p2p-lockstep-kit-ui 0.1.0 → 0.1.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.
package/dist/index.js CHANGED
@@ -112,7 +112,7 @@ var e = Object.create, t = Object.defineProperty, n = Object.getOwnPropertyDescr
112
112
  }
113
113
  render() {
114
114
  let { open: e } = this.#e;
115
- this.className = e ? "fixed inset-0 z-50 block" : "hidden", this.innerHTML = "\n <div data-overlay class=\"absolute inset-0 bg-[rgba(7,6,4,0.76)] backdrop-blur-sm\"></div>\n <div class=\"relative flex min-h-full items-end justify-center p-4 sm:items-center\">\n <section class=\"lock-panel w-full max-w-md rounded-[2rem] p-6\">\n <div class=\"space-y-3\">\n <p class=\"text-[0.72rem] uppercase tracking-[0.28em] text-[var(--lock-bronze-bright)]\">Action Required</p>\n <h3 data-title class=\"lock-title text-2xl font-semibold text-[var(--lock-paper)]\"></h3>\n <p data-description class=\"text-sm leading-6 text-[var(--lock-muted)]\"></p>\n </div>\n\n <div class=\"mt-6 grid gap-3 sm:grid-cols-2\">\n <button\n type=\"button\"\n data-action=\"confirm\"\n class=\"lock-primary inline-flex items-center justify-center rounded-full px-4 py-3 text-sm font-semibold transition\"\n >\n <span data-confirm-label></span>\n </button>\n <button\n type=\"button\"\n data-action=\"cancel\"\n class=\"lock-secondary inline-flex items-center justify-center rounded-full px-4 py-3 text-sm font-semibold transition\"\n >\n <span data-cancel-label></span>\n </button>\n </div>\n </section>\n </div>\n ", p(this, "[data-title]", this.#e.title), p(this, "[data-description]", this.#e.description), p(this, "[data-confirm-label]", this.#e.confirmLabel), p(this, "[data-cancel-label]", this.#e.cancelLabel);
115
+ this.className = e ? "fixed inset-0 z-50 block" : "hidden", this.innerHTML = "\n <div data-overlay class=\"absolute inset-0 bg-[var(--lock-overlay)] backdrop-blur-sm\"></div>\n <div class=\"relative flex min-h-full items-end justify-center p-4 sm:items-center\">\n <section class=\"lock-panel w-full max-w-md rounded-[2rem] p-6\">\n <div class=\"space-y-3\">\n <p class=\"text-[0.72rem] uppercase tracking-[0.28em] text-[var(--lock-bronze-bright)]\">Action Required</p>\n <h3 data-title class=\"lock-title text-2xl font-semibold text-[var(--lock-paper)]\"></h3>\n <p data-description class=\"text-sm leading-6 text-[var(--lock-muted)]\"></p>\n </div>\n\n <div class=\"mt-6 grid gap-3 sm:grid-cols-2\">\n <button\n type=\"button\"\n data-action=\"confirm\"\n class=\"lock-primary inline-flex items-center justify-center rounded-full px-4 py-3 text-sm font-semibold transition\"\n >\n <span data-confirm-label></span>\n </button>\n <button\n type=\"button\"\n data-action=\"cancel\"\n class=\"lock-secondary inline-flex items-center justify-center rounded-full px-4 py-3 text-sm font-semibold transition\"\n >\n <span data-cancel-label></span>\n </button>\n </div>\n </section>\n </div>\n ", p(this, "[data-title]", this.#e.title), p(this, "[data-description]", this.#e.description), p(this, "[data-confirm-label]", this.#e.confirmLabel), p(this, "[data-cancel-label]", this.#e.cancelLabel);
116
116
  }
117
117
  #n = (e) => {
118
118
  let t = e.target;
@@ -349,7 +349,7 @@ var e = Object.create, t = Object.defineProperty, n = Object.getOwnPropertyDescr
349
349
  }
350
350
  return i;
351
351
  };
352
- })), w = /* @__PURE__ */ o(((e) => {
352
+ })), te = /* @__PURE__ */ o(((e) => {
353
353
  var t = y(), n = [
354
354
  1,
355
355
  1,
@@ -690,7 +690,7 @@ var e = Object.create, t = Object.defineProperty, n = Object.getOwnPropertyDescr
690
690
  default: return;
691
691
  }
692
692
  };
693
- })), T = /* @__PURE__ */ o(((e) => {
693
+ })), w = /* @__PURE__ */ o(((e) => {
694
694
  var t = new Uint8Array(512), n = new Uint8Array(256);
695
695
  (function() {
696
696
  let e = 1;
@@ -704,8 +704,8 @@ var e = Object.create, t = Object.defineProperty, n = Object.getOwnPropertyDescr
704
704
  }, e.mul = function(e, r) {
705
705
  return e === 0 || r === 0 ? 0 : t[n[e] + n[r]];
706
706
  };
707
- })), te = /* @__PURE__ */ o(((e) => {
708
- var t = T();
707
+ })), ne = /* @__PURE__ */ o(((e) => {
708
+ var t = w();
709
709
  e.mul = function(e, n) {
710
710
  let r = new Uint8Array(e.length + n.length - 1);
711
711
  for (let i = 0; i < e.length; i++) for (let a = 0; a < n.length; a++) r[i + a] ^= t.mul(e[i], n[a]);
@@ -725,8 +725,8 @@ var e = Object.create, t = Object.defineProperty, n = Object.getOwnPropertyDescr
725
725
  for (let i = 0; i < n; i++) r = e.mul(r, new Uint8Array([1, t.exp(i)]));
726
726
  return r;
727
727
  };
728
- })), ne = /* @__PURE__ */ o(((e, t) => {
729
- var n = te();
728
+ })), re = /* @__PURE__ */ o(((e, t) => {
729
+ var n = ne();
730
730
  function r(e) {
731
731
  this.genPoly = void 0, this.degree = e, this.degree && this.initialize(this.degree);
732
732
  }
@@ -743,11 +743,11 @@ var e = Object.create, t = Object.defineProperty, n = Object.getOwnPropertyDescr
743
743
  }
744
744
  return r;
745
745
  }, t.exports = r;
746
- })), E = /* @__PURE__ */ o(((e) => {
746
+ })), T = /* @__PURE__ */ o(((e) => {
747
747
  e.isValid = function(e) {
748
748
  return !isNaN(e) && e >= 1 && e <= 40;
749
749
  };
750
- })), D = /* @__PURE__ */ o(((e) => {
750
+ })), E = /* @__PURE__ */ o(((e) => {
751
751
  var t = "[0-9]+", n = "[A-Z $%*+\\-./:]+", r = "(?:[u3000-u303F]|[u3040-u309F]|[u30A0-u30FF]|[uFF00-uFFEF]|[u4E00-u9FAF]|[u2605-u2606]|[u2190-u2195]|u203B|[u2010u2015u2018u2019u2025u2026u201Cu201Du2225u2260]|[u0391-u0451]|[u00A7u00A8u00B1u00B4u00D7u00F7])+";
752
752
  r = r.replace(/u/g, "\\u");
753
753
  var i = "(?:(?![A-Z0-9 $%*+\\-./:]|" + r + ")(?:.|[\r\n]))+";
@@ -760,8 +760,8 @@ var e = Object.create, t = Object.defineProperty, n = Object.getOwnPropertyDescr
760
760
  }, e.testAlphanumeric = function(e) {
761
761
  return s.test(e);
762
762
  };
763
- })), O = /* @__PURE__ */ o(((e) => {
764
- var t = E(), n = D();
763
+ })), D = /* @__PURE__ */ o(((e) => {
764
+ var t = T(), n = E();
765
765
  e.NUMERIC = {
766
766
  id: "Numeric",
767
767
  bit: 1,
@@ -824,8 +824,8 @@ var e = Object.create, t = Object.defineProperty, n = Object.getOwnPropertyDescr
824
824
  return n;
825
825
  }
826
826
  };
827
- })), re = /* @__PURE__ */ o(((e) => {
828
- var t = v(), n = w(), r = y(), i = O(), a = E(), o = 7973, s = t.getBCHDigit(o);
827
+ })), ie = /* @__PURE__ */ o(((e) => {
828
+ var t = v(), n = te(), r = y(), i = D(), a = T(), o = 7973, s = t.getBCHDigit(o);
829
829
  function c(t, n, r) {
830
830
  for (let i = 1; i <= 40; i++) if (n <= e.getCapacity(i, r, t)) return i;
831
831
  }
@@ -871,15 +871,15 @@ var e = Object.create, t = Object.defineProperty, n = Object.getOwnPropertyDescr
871
871
  for (; t.getBCHDigit(n) - s >= 0;) n ^= o << t.getBCHDigit(n) - s;
872
872
  return e << 12 | n;
873
873
  };
874
- })), ie = /* @__PURE__ */ o(((e) => {
874
+ })), ae = /* @__PURE__ */ o(((e) => {
875
875
  var t = v(), n = 1335, r = 21522, i = t.getBCHDigit(n);
876
876
  e.getEncodedBits = function(e, a) {
877
877
  let o = e.bit << 3 | a, s = o << 10;
878
878
  for (; t.getBCHDigit(s) - i >= 0;) s ^= n << t.getBCHDigit(s) - i;
879
879
  return (o << 10 | s) ^ r;
880
880
  };
881
- })), ae = /* @__PURE__ */ o(((e, t) => {
882
- var n = O();
881
+ })), oe = /* @__PURE__ */ o(((e, t) => {
882
+ var n = D();
883
883
  function r(e) {
884
884
  this.mode = n.NUMERIC, this.data = e.toString();
885
885
  }
@@ -895,8 +895,8 @@ var e = Object.create, t = Object.defineProperty, n = Object.getOwnPropertyDescr
895
895
  let i = this.data.length - t;
896
896
  i > 0 && (n = this.data.substr(t), r = parseInt(n, 10), e.put(r, i * 3 + 1));
897
897
  }, t.exports = r;
898
- })), oe = /* @__PURE__ */ o(((e, t) => {
899
- var n = O(), r = /* @__PURE__ */ "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ $%*+-./:".split("");
898
+ })), se = /* @__PURE__ */ o(((e, t) => {
899
+ var n = D(), r = /* @__PURE__ */ "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ $%*+-./:".split("");
900
900
  function i(e) {
901
901
  this.mode = n.ALPHANUMERIC, this.data = e;
902
902
  }
@@ -914,8 +914,8 @@ var e = Object.create, t = Object.defineProperty, n = Object.getOwnPropertyDescr
914
914
  }
915
915
  this.data.length % 2 && e.put(r.indexOf(this.data[t]), 6);
916
916
  }, t.exports = i;
917
- })), se = /* @__PURE__ */ o(((e, t) => {
918
- var n = O();
917
+ })), ce = /* @__PURE__ */ o(((e, t) => {
918
+ var n = D();
919
919
  function r(e) {
920
920
  this.mode = n.BYTE, typeof e == "string" ? this.data = new TextEncoder().encode(e) : this.data = new Uint8Array(e);
921
921
  }
@@ -928,8 +928,8 @@ var e = Object.create, t = Object.defineProperty, n = Object.getOwnPropertyDescr
928
928
  }, r.prototype.write = function(e) {
929
929
  for (let t = 0, n = this.data.length; t < n; t++) e.put(this.data[t], 8);
930
930
  }, t.exports = r;
931
- })), ce = /* @__PURE__ */ o(((e, t) => {
932
- var n = O(), r = v();
931
+ })), le = /* @__PURE__ */ o(((e, t) => {
932
+ var n = D(), r = v();
933
933
  function i(e) {
934
934
  this.mode = n.KANJI, this.data = e;
935
935
  }
@@ -949,7 +949,7 @@ var e = Object.create, t = Object.defineProperty, n = Object.getOwnPropertyDescr
949
949
  n = (n >>> 8 & 255) * 192 + (n & 255), e.put(n, 13);
950
950
  }
951
951
  }, t.exports = i;
952
- })), le = /* @__PURE__ */ o(((e, t) => {
952
+ })), ue = /* @__PURE__ */ o(((e, t) => {
953
953
  var n = {
954
954
  single_source_shortest_paths: function(e, t, r) {
955
955
  var i = {}, a = {};
@@ -1002,8 +1002,8 @@ var e = Object.create, t = Object.defineProperty, n = Object.getOwnPropertyDescr
1002
1002
  }
1003
1003
  };
1004
1004
  t !== void 0 && (t.exports = n);
1005
- })), ue = /* @__PURE__ */ o(((e) => {
1006
- var t = O(), n = ae(), r = oe(), i = se(), a = ce(), o = D(), s = v(), c = le();
1005
+ })), de = /* @__PURE__ */ o(((e) => {
1006
+ var t = D(), n = oe(), r = se(), i = ce(), a = le(), o = E(), s = v(), c = ue();
1007
1007
  function l(e) {
1008
1008
  return unescape(encodeURIComponent(e)).length;
1009
1009
  }
@@ -1130,8 +1130,8 @@ var e = Object.create, t = Object.defineProperty, n = Object.getOwnPropertyDescr
1130
1130
  }, e.rawSplit = function(t) {
1131
1131
  return e.fromArray(d(t, s.isKanjiModeEnabled()));
1132
1132
  };
1133
- })), de = /* @__PURE__ */ o(((e) => {
1134
- var t = v(), n = y(), r = b(), i = x(), a = S(), o = C(), s = ee(), c = w(), l = ne(), u = re(), d = ie(), f = O(), p = ue();
1133
+ })), fe = /* @__PURE__ */ o(((e) => {
1134
+ var t = v(), n = y(), r = b(), i = x(), a = S(), o = C(), s = ee(), c = te(), l = re(), u = ie(), d = ae(), f = D(), p = de();
1135
1135
  function m(e, t) {
1136
1136
  let n = e.size, r = o.getPositions(t);
1137
1137
  for (let t = 0; t < r.length; t++) {
@@ -1157,12 +1157,12 @@ var e = Object.create, t = Object.defineProperty, n = Object.getOwnPropertyDescr
1157
1157
  let n = e.size, r = u.getEncodedBits(t), i, a, o;
1158
1158
  for (let t = 0; t < 18; t++) i = Math.floor(t / 3), a = t % 3 + n - 8 - 3, o = (r >> t & 1) == 1, e.set(i, a, o, !0), e.set(a, i, o, !0);
1159
1159
  }
1160
- function T(e, t, n) {
1160
+ function w(e, t, n) {
1161
1161
  let r = e.size, i = d.getEncodedBits(t, n), a, o;
1162
1162
  for (a = 0; a < 15; a++) o = (i >> a & 1) == 1, a < 6 ? e.set(a, 8, o, !0) : a < 8 ? e.set(a + 1, 8, o, !0) : e.set(r - 15 + a, 8, o, !0), a < 8 ? e.set(8, r - a - 1, o, !0) : a < 9 ? e.set(8, 15 - a - 1 + 1, o, !0) : e.set(8, 15 - a - 1, o, !0);
1163
1163
  e.set(r - 8, 8, 1, !0);
1164
1164
  }
1165
- function te(e, t) {
1165
+ function ne(e, t) {
1166
1166
  let n = e.size, r = -1, i = n - 1, a = 7, o = 0;
1167
1167
  for (let s = n - 1; s > 0; s -= 2) for (s === 6 && s--;;) {
1168
1168
  for (let n = 0; n < 2; n++) if (!e.isReserved(i, s - n)) {
@@ -1175,7 +1175,7 @@ var e = Object.create, t = Object.defineProperty, n = Object.getOwnPropertyDescr
1175
1175
  }
1176
1176
  }
1177
1177
  }
1178
- function E(e, n, i) {
1178
+ function T(e, n, i) {
1179
1179
  let a = new r();
1180
1180
  i.forEach(function(t) {
1181
1181
  a.put(t.mode.bit, 4), a.put(t.getLength(), f.getCharCountIndicator(t.mode, e)), t.write(a);
@@ -1184,9 +1184,9 @@ var e = Object.create, t = Object.defineProperty, n = Object.getOwnPropertyDescr
1184
1184
  for (a.getLengthInBits() + 4 <= o && a.put(0, 4); a.getLengthInBits() % 8 != 0;) a.putBit(0);
1185
1185
  let s = (o - a.getLengthInBits()) / 8;
1186
1186
  for (let e = 0; e < s; e++) a.put(e % 2 ? 17 : 236, 8);
1187
- return D(a, e, n);
1187
+ return E(a, e, n);
1188
1188
  }
1189
- function D(e, n, r) {
1189
+ function E(e, n, r) {
1190
1190
  let i = t.getSymbolTotalCodewords(n), a = i - c.getTotalCodewordsCount(n, r), o = c.getBlocksCount(n, r), s = o - i % o, u = Math.floor(i / o), d = Math.floor(a / o), f = d + 1, p = u - d, m = new l(p), h = 0, g = Array(o), _ = Array(o), v = 0, y = new Uint8Array(e.buffer);
1191
1191
  for (let e = 0; e < o; e++) {
1192
1192
  let t = e < s ? d : f;
@@ -1197,7 +1197,7 @@ var e = Object.create, t = Object.defineProperty, n = Object.getOwnPropertyDescr
1197
1197
  for (S = 0; S < p; S++) for (C = 0; C < o; C++) b[x++] = _[C][S];
1198
1198
  return b;
1199
1199
  }
1200
- function ae(e, n, r, a) {
1200
+ function oe(e, n, r, a) {
1201
1201
  let o;
1202
1202
  if (Array.isArray(e)) o = p.fromArray(e);
1203
1203
  else if (typeof e == "string") {
@@ -1212,8 +1212,8 @@ var e = Object.create, t = Object.defineProperty, n = Object.getOwnPropertyDescr
1212
1212
  if (!c) throw Error("The amount of data is too big to be stored in a QR Code");
1213
1213
  if (!n) n = c;
1214
1214
  else if (n < c) throw Error("\nThe chosen QR Code version cannot contain this amount of data.\nMinimum version required to store current data is: " + c + ".\n");
1215
- let l = E(n, r, o), d = new i(t.getSymbolSize(n));
1216
- return m(d, n), h(d), g(d, n), T(d, r, 0), n >= 7 && _(d, n), te(d, l), isNaN(a) && (a = s.getBestMask(d, T.bind(null, d, r))), s.applyMask(a, d), T(d, r, a), {
1215
+ let l = T(n, r, o), d = new i(t.getSymbolSize(n));
1216
+ return m(d, n), h(d), g(d, n), w(d, r, 0), n >= 7 && _(d, n), ne(d, l), isNaN(a) && (a = s.getBestMask(d, w.bind(null, d, r))), s.applyMask(a, d), w(d, r, a), {
1217
1217
  modules: d,
1218
1218
  version: n,
1219
1219
  errorCorrectionLevel: r,
@@ -1224,9 +1224,9 @@ var e = Object.create, t = Object.defineProperty, n = Object.getOwnPropertyDescr
1224
1224
  e.create = function(e, r) {
1225
1225
  if (e === void 0 || e === "") throw Error("No input text");
1226
1226
  let i = n.M, a, o;
1227
- return r !== void 0 && (i = n.from(r.errorCorrectionLevel, n.M), a = u.from(r.version), o = s.from(r.maskPattern), r.toSJISFunc && t.setToSJISFunction(r.toSJISFunc)), ae(e, a, i, o);
1227
+ return r !== void 0 && (i = n.from(r.errorCorrectionLevel, n.M), a = u.from(r.version), o = s.from(r.maskPattern), r.toSJISFunc && t.setToSJISFunction(r.toSJISFunc)), oe(e, a, i, o);
1228
1228
  };
1229
- })), fe = /* @__PURE__ */ o(((e) => {
1229
+ })), pe = /* @__PURE__ */ o(((e) => {
1230
1230
  function t(e) {
1231
1231
  if (typeof e == "number" && (e = e.toString()), typeof e != "string") throw Error("Color should be defined as hex string");
1232
1232
  let t = e.slice().replace("#", "").split("");
@@ -1273,8 +1273,8 @@ var e = Object.create, t = Object.defineProperty, n = Object.getOwnPropertyDescr
1273
1273
  t[u++] = d.r, t[u++] = d.g, t[u++] = d.b, t[u] = d.a;
1274
1274
  }
1275
1275
  };
1276
- })), pe = /* @__PURE__ */ o(((e) => {
1277
- var t = fe();
1276
+ })), me = /* @__PURE__ */ o(((e) => {
1277
+ var t = pe();
1278
1278
  function n(e, t, n) {
1279
1279
  e.clearRect(0, 0, t.width, t.height), t.style ||= {}, t.height = n, t.width = n, t.style.height = n + "px", t.style.width = n + "px";
1280
1280
  }
@@ -1296,8 +1296,8 @@ var e = Object.create, t = Object.defineProperty, n = Object.getOwnPropertyDescr
1296
1296
  let a = e.render(t, n, i), o = i.type || "image/png", s = i.rendererOpts || {};
1297
1297
  return a.toDataURL(o, s.quality);
1298
1298
  };
1299
- })), me = /* @__PURE__ */ o(((e) => {
1300
- var t = fe();
1299
+ })), he = /* @__PURE__ */ o(((e) => {
1300
+ var t = pe();
1301
1301
  function n(e, t) {
1302
1302
  let n = e.a / 255, r = t + "=\"" + e.hex + "\"";
1303
1303
  return n < 1 ? r + " " + t + "-opacity=\"" + n.toFixed(2).slice(1) + "\"" : r;
@@ -1318,8 +1318,8 @@ var e = Object.create, t = Object.defineProperty, n = Object.getOwnPropertyDescr
1318
1318
  let o = t.getOptions(r), s = e.modules.size, c = e.modules.data, l = s + o.margin * 2, u = o.color.light.a ? "<path " + n(o.color.light, "fill") + " d=\"M0 0h" + l + "v" + l + "H0z\"/>" : "", d = "<path " + n(o.color.dark, "stroke") + " d=\"" + i(c, s, o.margin) + "\"/>", f = "viewBox=\"0 0 " + l + " " + l + "\"", p = "<svg xmlns=\"http://www.w3.org/2000/svg\" " + (o.width ? "width=\"" + o.width + "\" height=\"" + o.width + "\" " : "") + f + " shape-rendering=\"crispEdges\">" + u + d + "</svg>\n";
1319
1319
  return typeof a == "function" && a(null, p), p;
1320
1320
  };
1321
- })), he = /* @__PURE__ */ c((/* @__PURE__ */ o(((e) => {
1322
- var t = _(), n = de(), r = pe(), i = me();
1321
+ })), ge = /* @__PURE__ */ c((/* @__PURE__ */ o(((e) => {
1322
+ var t = _(), n = fe(), r = me(), i = he();
1323
1323
  function a(e, r, i, a, o) {
1324
1324
  let s = [].slice.call(arguments, 1), c = s.length, l = typeof s[c - 1] == "function";
1325
1325
  if (!l && !t()) throw Error("Callback required as last argument");
@@ -1346,12 +1346,12 @@ var e = Object.create, t = Object.defineProperty, n = Object.getOwnPropertyDescr
1346
1346
  e.create = n.create, e.toCanvas = a.bind(null, r.render), e.toDataURL = a.bind(null, r.renderToDataURL), e.toString = a.bind(null, function(e, t, n) {
1347
1347
  return i.render(e, n);
1348
1348
  });
1349
- })))(), 1), ge = {
1349
+ })))(), 1), _e = {
1350
1350
  peerId: "",
1351
1351
  signalUrl: "",
1352
1352
  shareUrl: ""
1353
- }, k = class extends HTMLElement {
1354
- #e = ge;
1353
+ }, ve = class extends HTMLElement {
1354
+ #e = _e;
1355
1355
  #t = !1;
1356
1356
  connectedCallback() {
1357
1357
  this.#t || (this.#t = !0, this.addEventListener("click", this.#n), this.render());
@@ -1371,7 +1371,7 @@ var e = Object.create, t = Object.defineProperty, n = Object.getOwnPropertyDescr
1371
1371
  <section class="lock-panel flex h-full flex-col justify-between gap-3 rounded-[1.4rem] p-3.5 sm:gap-4 sm:rounded-[2rem] sm:p-5">
1372
1372
  <div class="flex items-center justify-between gap-3">
1373
1373
  <p class="text-[0.62rem] font-semibold uppercase tracking-[0.18em] text-[var(--lock-dim)] sm:text-[0.7rem]">Share</p>
1374
- <span data-share-state class="rounded-full border border-[var(--lock-border)] bg-[rgba(255,255,252,0.62)] px-2.5 py-0.5 text-[0.65rem] uppercase tracking-[0.12em] text-[var(--lock-muted)] sm:px-3 sm:py-1 sm:text-xs"></span>
1374
+ <span data-share-state class="lock-card rounded-full border border-[var(--lock-border)] px-2.5 py-0.5 text-[0.65rem] uppercase tracking-[0.12em] text-[var(--lock-muted)] sm:px-3 sm:py-1 sm:text-xs"></span>
1375
1375
  </div>
1376
1376
 
1377
1377
  <div class="flex flex-1 items-center justify-center">
@@ -1398,7 +1398,7 @@ var e = Object.create, t = Object.defineProperty, n = Object.getOwnPropertyDescr
1398
1398
  return;
1399
1399
  }
1400
1400
  try {
1401
- await he.toCanvas(t, e, {
1401
+ await ge.toCanvas(t, e, {
1402
1402
  width: 208,
1403
1403
  margin: 1,
1404
1404
  color: {
@@ -1413,7 +1413,8 @@ var e = Object.create, t = Object.defineProperty, n = Object.getOwnPropertyDescr
1413
1413
  #n = (e) => {
1414
1414
  e.target?.closest("[data-action='copy-share']") && l(this, "lockstep-copy-share", { value: this.#e.shareUrl });
1415
1415
  };
1416
- }, _e = {
1416
+ }, ye = {
1417
+ theme: "light",
1417
1418
  gameTitle: "P2P Lockstep",
1418
1419
  peerId: "",
1419
1420
  remotePeerId: "",
@@ -1426,11 +1427,14 @@ var e = Object.create, t = Object.defineProperty, n = Object.getOwnPropertyDescr
1426
1427
  readySelf: !1,
1427
1428
  readyPeer: !1,
1428
1429
  pendingAction: null,
1429
- sessionId: "default-session"
1430
- }, A = (e) => e === "me" ? "Your turn" : e === "peer" ? "Peer turn" : "Waiting", ve = (e, t) => t === "ready" ? `${e} ready` : t === "could_start" ? e === "Me" ? "You can start" : "Peer can start" : `${e} idle`, j = (e, t) => {
1430
+ sessionId: "default-session",
1431
+ historyLength: 0,
1432
+ lastStart: null,
1433
+ lastError: ""
1434
+ }, O = (e) => e === "me" ? "Your turn" : e === "peer" ? "Peer turn" : "Waiting", k = (e, t) => t === "ready" ? `${e} ready` : t === "could_start" ? e === "Me" ? "You can start" : "Peer can start" : `${e} idle`, A = (e, t) => {
1431
1435
  let n = e === "Local" ? "You" : "Peer";
1432
1436
  return t === "idle" ? `${n} idle` : t === "ready" ? `${n} ready` : t === "could_start" ? `${n} can start` : `${n} ${t.replaceAll("_", " ")}`;
1433
- }, ye = (e, t) => e || t === "connected" ? {
1437
+ }, be = (e, t) => e || t === "connected" ? {
1434
1438
  label: "Live",
1435
1439
  detail: "connected",
1436
1440
  tone: "bg-[var(--lock-teal)]"
@@ -1458,11 +1462,14 @@ var e = Object.create, t = Object.defineProperty, n = Object.getOwnPropertyDescr
1458
1462
  label: "Standby",
1459
1463
  detail: "not registered",
1460
1464
  tone: "bg-[var(--lock-dim)]"
1461
- }, M = class extends HTMLElement {
1462
- #e = _e;
1465
+ }, j = class extends HTMLElement {
1466
+ #e = ye;
1463
1467
  #t = !1;
1464
1468
  connectedCallback() {
1465
- this.#t || (this.#t = !0, this.render());
1469
+ this.#t || (this.#t = !0, this.addEventListener("click", this.#n), this.render());
1470
+ }
1471
+ disconnectedCallback() {
1472
+ this.removeEventListener("click", this.#n);
1466
1473
  }
1467
1474
  set state(e) {
1468
1475
  this.#e = e, this.#t && this.render();
@@ -1471,7 +1478,7 @@ var e = Object.create, t = Object.defineProperty, n = Object.getOwnPropertyDescr
1471
1478
  return this.#e;
1472
1479
  }
1473
1480
  render() {
1474
- let { connected: e, pendingAction: t } = this.#e, n = ye(e, this.#e.connectionState), r = ve("Me", this.#e.localState), i = ve("Peer", this.#e.remoteState), a = j("Local", this.#e.localState), o = j("Remote", this.#e.remoteState), s = `${r} / ${i}`;
1481
+ let { connected: e, pendingAction: t } = this.#e, n = be(e, this.#e.connectionState), r = k("Me", this.#e.localState), i = k("Peer", this.#e.remoteState), a = A("Local", this.#e.localState), o = A("Remote", this.#e.remoteState), s = `${r} / ${i}`, c = this.#e.lastStart === "local" ? "You" : this.#e.lastStart === "remote" ? "Peer" : "Not started", l = `${this.#e.historyLength} move${this.#e.historyLength === 1 ? "" : "s"} / ${c}`;
1475
1482
  this.className = "block", this.innerHTML = `
1476
1483
  <section class="lock-panel relative rounded-[1.25rem] p-2.5 text-sm text-[var(--lock-muted)] sm:rounded-[1.5rem] sm:p-3 lg:rounded-[1.75rem] lg:p-2.5">
1477
1484
  <div class="flex items-center gap-2 lg:hidden">
@@ -1492,66 +1499,93 @@ var e = Object.create, t = Object.defineProperty, n = Object.getOwnPropertyDescr
1492
1499
  <details class="group shrink-0">
1493
1500
  <summary
1494
1501
  aria-label="Match details"
1495
- class="flex h-9 w-9 cursor-pointer list-none items-center justify-center rounded-full border border-[var(--lock-border)] bg-[rgba(255,255,252,0.7)] text-base font-semibold leading-none text-[var(--lock-muted)] transition hover:border-[var(--lock-border-strong)] hover:bg-white [&::-webkit-details-marker]:hidden"
1502
+ class="lock-control flex h-9 w-9 cursor-pointer list-none items-center justify-center rounded-full border border-[var(--lock-border)] text-base font-semibold leading-none text-[var(--lock-muted)] transition hover:border-[var(--lock-border-strong)] [&::-webkit-details-marker]:hidden"
1496
1503
  >
1497
1504
  ...
1498
1505
  </summary>
1499
- <div class="absolute inset-x-0 top-full z-50 mt-2 max-h-[calc(100svh-6rem)] overflow-auto rounded-[1.35rem] border border-[var(--lock-border-strong)] bg-[rgba(255,255,252,0.96)] p-3.5 shadow-2xl shadow-black/15 backdrop-blur-xl lg:inset-auto lg:right-0 lg:w-[min(22rem,calc(100vw-1.5rem))]">
1506
+ <div class="lock-surface-strong absolute inset-x-0 top-full z-50 mt-2 max-h-[calc(100svh-6rem)] overflow-auto rounded-[1.35rem] border border-[var(--lock-border-strong)] p-3.5 shadow-2xl shadow-black/15 backdrop-blur-xl lg:inset-auto lg:right-0 lg:w-[min(22rem,calc(100vw-1.5rem))]">
1500
1507
  <div class="grid grid-cols-2 gap-2">
1501
- <article class="rounded-[1rem] border border-[var(--lock-border)] bg-[rgba(255,255,252,0.54)] p-3">
1508
+ <article class="lock-card rounded-[1rem] border border-[var(--lock-border)] p-3">
1502
1509
  <p class="text-[0.6rem] uppercase tracking-[0.18em] text-[var(--lock-dim)]">Connection</p>
1503
1510
  <p data-detail-connection class="mt-1.5 text-sm font-semibold text-[var(--lock-paper)]"></p>
1504
1511
  </article>
1505
- <article class="rounded-[1rem] border border-[var(--lock-border)] bg-[rgba(255,255,252,0.54)] p-3">
1512
+ <article class="lock-card rounded-[1rem] border border-[var(--lock-border)] p-3">
1506
1513
  <p class="text-[0.6rem] uppercase tracking-[0.18em] text-[var(--lock-dim)]">Turn</p>
1507
1514
  <p data-detail-turn class="mt-1.5 text-sm font-semibold text-[var(--lock-paper)]"></p>
1508
1515
  </article>
1509
1516
  </div>
1510
1517
 
1511
- <div class="mt-2 rounded-[1rem] border border-[var(--lock-border)] bg-[rgba(255,255,252,0.54)] p-3">
1518
+ <div class="lock-card mt-2 rounded-[1rem] border border-[var(--lock-border)] p-3">
1512
1519
  <p class="text-[0.6rem] uppercase tracking-[0.18em] text-[var(--lock-dim)]">Identity</p>
1513
1520
  <p class="lock-mono mt-1.5 break-all text-xs text-[var(--lock-muted)]">Session: <span data-detail-session class="text-[var(--lock-paper)]"></span></p>
1514
1521
  <p class="lock-mono mt-1.5 break-all text-xs text-[var(--lock-muted)]">Me: <span data-detail-peer class="text-[var(--lock-paper)]"></span></p>
1515
1522
  <p class="lock-mono mt-1.5 break-all text-xs text-[var(--lock-muted)]">Peer: <span data-detail-remote class="text-[var(--lock-paper)]"></span></p>
1516
1523
  </div>
1517
1524
 
1525
+ <div class="lock-card mt-2 rounded-[1rem] border border-[var(--lock-border)] p-3">
1526
+ <p class="text-[0.6rem] uppercase tracking-[0.18em] text-[var(--lock-dim)]">Timeline</p>
1527
+ <p data-detail-timeline class="mt-1.5 text-sm font-semibold text-[var(--lock-paper)]"></p>
1528
+ ${this.#e.lastError ? "<p data-detail-error class=\"mt-1.5 break-words text-xs text-[var(--lock-rose)]\"></p>" : ""}
1529
+ </div>
1530
+
1531
+ <div class="lock-card mt-2 rounded-[1rem] border border-[var(--lock-border)] p-3">
1532
+ <p class="text-[0.6rem] uppercase tracking-[0.18em] text-[var(--lock-dim)]">Appearance</p>
1533
+ <div class="mt-2 grid grid-cols-2 gap-2" role="group" aria-label="Color mode">
1534
+ <button type="button" data-theme-mode="light" class="lock-theme-option rounded-xl px-3 py-2 text-xs font-semibold" aria-label="Use day mode" aria-pressed="${this.#e.theme === "light"}">Day</button>
1535
+ <button type="button" data-theme-mode="dark" class="lock-theme-option rounded-xl px-3 py-2 text-xs font-semibold" aria-label="Use night mode" aria-pressed="${this.#e.theme === "dark"}">Night</button>
1536
+ </div>
1537
+ </div>
1538
+
1518
1539
  <div class="mt-2 flex flex-wrap gap-1.5">
1519
1540
  <span data-detail-ready-self class="rounded-full border border-[var(--lock-border)] px-2.5 py-1 text-[0.68rem] text-[var(--lock-muted)]"></span>
1520
1541
  <span data-detail-ready-peer class="rounded-full border border-[var(--lock-border)] px-2.5 py-1 text-[0.68rem] text-[var(--lock-muted)]"></span>
1521
1542
  <span data-detail-local-state class="rounded-full border border-[var(--lock-border)] px-2.5 py-1 text-[0.68rem] text-[var(--lock-muted)]"></span>
1522
1543
  <span data-detail-remote-state class="rounded-full border border-[var(--lock-border)] px-2.5 py-1 text-[0.68rem] text-[var(--lock-muted)]"></span>
1523
- ${t ? `<span class="rounded-full border border-[var(--lock-border-strong)] bg-[rgba(201,149,67,0.14)] px-2.5 py-1 text-[0.68rem] text-[var(--lock-bronze-bright)]">Pending ${t}</span>` : ""}
1544
+ ${t ? `<span class="rounded-full border border-[var(--lock-border-strong)] bg-[var(--lock-pending-bg)] px-2.5 py-1 text-[0.68rem] text-[var(--lock-bronze-bright)]">Pending ${t}</span>` : ""}
1524
1545
  </div>
1525
1546
  </div>
1526
1547
  </details>
1527
1548
  </div>
1528
1549
 
1529
1550
  <div class="hidden gap-2 lg:grid">
1530
- <article class="rounded-[1.15rem] border border-[var(--lock-border)] bg-[rgba(255,255,252,0.52)] p-2.5">
1551
+ <article class="lock-card rounded-[1.15rem] border border-[var(--lock-border)] p-2.5">
1531
1552
  <div class="flex items-start justify-between gap-3">
1532
1553
  <div class="min-w-0">
1533
1554
  <p class="text-[0.62rem] uppercase tracking-[0.2em] text-[var(--lock-dim)]">Match</p>
1534
1555
  <p data-title class="mt-1.5 truncate text-xl font-semibold leading-none tracking-[-0.035em] text-[var(--lock-paper)]"></p>
1556
+ <p data-match-meta class="mt-1.5 text-xs text-[var(--lock-muted)]"></p>
1557
+ </div>
1558
+ <div class="flex shrink-0 items-center gap-2">
1559
+ <span class="h-2.5 w-2.5 rounded-full ${n.tone}"></span>
1560
+ <details class="group relative">
1561
+ <summary aria-label="Appearance settings" class="lock-control flex h-7 w-7 cursor-pointer list-none items-center justify-center rounded-full border border-[var(--lock-border)] text-xs font-semibold leading-none text-[var(--lock-muted)] [&::-webkit-details-marker]:hidden">...</summary>
1562
+ <div class="lock-surface-strong absolute right-0 z-50 mt-2 w-52 rounded-2xl border border-[var(--lock-border-strong)] p-3 shadow-xl shadow-black/15">
1563
+ <p class="text-[0.6rem] uppercase tracking-[0.18em] text-[var(--lock-dim)]">Appearance</p>
1564
+ <div class="mt-2 grid grid-cols-2 gap-2" role="group" aria-label="Color mode">
1565
+ <button type="button" data-theme-mode="light" class="lock-theme-option rounded-xl px-3 py-2 text-xs font-semibold" aria-label="Use day mode" aria-pressed="${this.#e.theme === "light"}">Day</button>
1566
+ <button type="button" data-theme-mode="dark" class="lock-theme-option rounded-xl px-3 py-2 text-xs font-semibold" aria-label="Use night mode" aria-pressed="${this.#e.theme === "dark"}">Night</button>
1567
+ </div>
1568
+ </div>
1569
+ </details>
1535
1570
  </div>
1536
- <span class="mt-0.5 h-2.5 w-2.5 shrink-0 rounded-full ${n.tone}"></span>
1537
1571
  </div>
1538
1572
  </article>
1539
1573
 
1540
1574
  <div class="grid grid-cols-2 gap-2">
1541
- <article class="rounded-[1rem] border border-[var(--lock-border)] bg-[rgba(255,255,252,0.52)] p-2.5">
1575
+ <article class="lock-card rounded-[1rem] border border-[var(--lock-border)] p-2.5">
1542
1576
  <p class="text-[0.58rem] uppercase tracking-[0.2em] text-[var(--lock-dim)]">Connection</p>
1543
1577
  <p class="mt-1.5 text-sm font-semibold text-[var(--lock-paper)]">${n.label}</p>
1544
1578
  <p data-connection-state class="mt-0.5 truncate text-xs text-[var(--lock-muted)]"></p>
1545
1579
  </article>
1546
1580
 
1547
- <article class="rounded-[1rem] border border-[var(--lock-border)] bg-[rgba(255,255,252,0.52)] p-2.5">
1581
+ <article class="lock-card rounded-[1rem] border border-[var(--lock-border)] p-2.5">
1548
1582
  <p class="text-[0.58rem] uppercase tracking-[0.2em] text-[var(--lock-dim)]">Turn</p>
1549
1583
  <p data-current-turn class="mt-1.5 text-sm font-semibold text-[var(--lock-paper)]"></p>
1550
1584
  <p data-turn-owner class="mt-0.5 truncate text-xs text-[var(--lock-muted)]"></p>
1551
1585
  </article>
1552
1586
  </div>
1553
1587
 
1554
- <article class="min-w-0 overflow-hidden rounded-[1.15rem] border border-[var(--lock-border)] bg-[rgba(255,255,252,0.52)] p-2.5">
1588
+ <article class="lock-card min-w-0 overflow-hidden rounded-[1.15rem] border border-[var(--lock-border)] p-2.5">
1555
1589
  <p class="text-[0.62rem] uppercase tracking-[0.2em] text-[var(--lock-dim)]">Identity</p>
1556
1590
  <div class="mt-2 grid gap-1.5 text-xs">
1557
1591
  <p class="grid min-w-0 grid-cols-[3.25rem_minmax(0,1fr)] items-center gap-2 text-[var(--lock-muted)]">
@@ -1569,25 +1603,31 @@ var e = Object.create, t = Object.defineProperty, n = Object.getOwnPropertyDescr
1569
1603
  </div>
1570
1604
  </article>
1571
1605
 
1572
- <article class="rounded-[1.15rem] border border-[var(--lock-border)] bg-[rgba(255,255,252,0.52)] p-2.5">
1606
+ ${this.#e.lastError ? "<article class=\"rounded-[1.15rem] border border-[var(--lock-border)] bg-[var(--lock-error-bg)] p-2.5\">\n <p class=\"text-[0.62rem] uppercase tracking-[0.2em] text-[var(--lock-rose)]\">Last error</p>\n <p data-error-message class=\"mt-1.5 break-words text-xs leading-5 text-[var(--lock-paper)]\"></p>\n </article>" : ""}
1607
+
1608
+ <article class="lock-card rounded-[1.15rem] border border-[var(--lock-border)] p-2.5">
1573
1609
  <p class="text-[0.62rem] uppercase tracking-[0.2em] text-[var(--lock-dim)]">State</p>
1574
1610
  <div class="mt-2 flex flex-wrap gap-1.5">
1575
1611
  <span data-ready-self class="rounded-full border border-[var(--lock-border)] px-2 py-0.5 text-[0.64rem] text-[var(--lock-muted)]"></span>
1576
1612
  <span data-ready-peer class="rounded-full border border-[var(--lock-border)] px-2 py-0.5 text-[0.64rem] text-[var(--lock-muted)]"></span>
1577
1613
  <span data-local-state class="rounded-full border border-[var(--lock-border)] px-2 py-0.5 text-[0.64rem] text-[var(--lock-muted)]"></span>
1578
1614
  <span data-remote-state class="rounded-full border border-[var(--lock-border)] px-2 py-0.5 text-[0.64rem] text-[var(--lock-muted)]"></span>
1579
- ${t ? `<span class="rounded-full border border-[var(--lock-border-strong)] bg-[rgba(201,149,67,0.14)] px-2 py-0.5 text-[0.64rem] text-[var(--lock-bronze-bright)]">Pending ${t}</span>` : ""}
1615
+ ${t ? `<span class="rounded-full border border-[var(--lock-border-strong)] bg-[var(--lock-pending-bg)] px-2 py-0.5 text-[0.64rem] text-[var(--lock-bronze-bright)]">Pending ${t}</span>` : ""}
1580
1616
  </div>
1581
1617
  </article>
1582
1618
  </div>
1583
1619
  </section>
1584
- `, p(this, "[data-mobile-title]", this.#e.gameTitle), p(this, "[data-mobile-connection]", n.label), p(this, "[data-mobile-turn]", `#${this.#e.currentTurn} ${A(this.#e.turnOwner)}`), p(this, "[data-mobile-ready]", s), p(this, "[data-detail-connection]", n.label), p(this, "[data-detail-turn]", `#${this.#e.currentTurn} / ${A(this.#e.turnOwner)}`), p(this, "[data-detail-session]", this.#e.sessionId), p(this, "[data-detail-peer]", this.#e.peerId || "not set"), p(this, "[data-detail-remote]", this.#e.remotePeerId || "not set"), p(this, "[data-detail-ready-self]", r), p(this, "[data-detail-ready-peer]", i), p(this, "[data-detail-local-state]", a), p(this, "[data-detail-remote-state]", o), p(this, "[data-title]", this.#e.gameTitle), p(this, "[data-connection-state]", n.detail), p(this, "[data-current-turn]", `#${this.#e.currentTurn}`), p(this, "[data-turn-owner]", A(this.#e.turnOwner)), p(this, "[data-session-id]", this.#e.sessionId), p(this, "[data-peer-id]", this.#e.peerId || "Local peer ID will appear after register.")?.setAttribute("title", this.#e.peerId), p(this, "[data-remote-peer-id]", this.#e.remotePeerId || "Remote peer not connected yet.")?.setAttribute("title", this.#e.remotePeerId), p(this, "[data-ready-self]", r), p(this, "[data-ready-peer]", i), p(this, "[data-local-state]", a), p(this, "[data-remote-state]", o);
1620
+ `, p(this, "[data-mobile-title]", this.#e.gameTitle), p(this, "[data-mobile-connection]", n.label), p(this, "[data-mobile-turn]", `#${this.#e.currentTurn} ${O(this.#e.turnOwner)}`), p(this, "[data-mobile-ready]", s), p(this, "[data-detail-connection]", n.label), p(this, "[data-detail-turn]", `#${this.#e.currentTurn} / ${O(this.#e.turnOwner)}`), p(this, "[data-detail-session]", this.#e.sessionId), p(this, "[data-detail-timeline]", l), p(this, "[data-detail-error]", this.#e.lastError), p(this, "[data-detail-peer]", this.#e.peerId || "not set"), p(this, "[data-detail-remote]", this.#e.remotePeerId || "not set"), p(this, "[data-detail-ready-self]", r), p(this, "[data-detail-ready-peer]", i), p(this, "[data-detail-local-state]", a), p(this, "[data-detail-remote-state]", o), p(this, "[data-title]", this.#e.gameTitle), p(this, "[data-match-meta]", l), p(this, "[data-error-message]", this.#e.lastError), p(this, "[data-connection-state]", n.detail), p(this, "[data-current-turn]", `#${this.#e.currentTurn}`), p(this, "[data-turn-owner]", O(this.#e.turnOwner)), p(this, "[data-session-id]", this.#e.sessionId), p(this, "[data-peer-id]", this.#e.peerId || "Local peer ID will appear after register.")?.setAttribute("title", this.#e.peerId), p(this, "[data-remote-peer-id]", this.#e.remotePeerId || "Remote peer not connected yet.")?.setAttribute("title", this.#e.remotePeerId), p(this, "[data-ready-self]", r), p(this, "[data-ready-peer]", i), p(this, "[data-local-state]", a), p(this, "[data-remote-state]", o);
1585
1621
  }
1586
- }, be = {
1622
+ #n = (e) => {
1623
+ let t = e.target?.closest("button[data-theme-mode]");
1624
+ (t?.dataset.themeMode === "light" || t?.dataset.themeMode === "dark") && l(this, "lockstep-theme-change", { theme: t.dataset.themeMode });
1625
+ };
1626
+ }, xe = {
1587
1627
  open: !1,
1588
1628
  message: ""
1589
- }, N = class extends HTMLElement {
1590
- #e = be;
1629
+ }, M = class extends HTMLElement {
1630
+ #e = xe;
1591
1631
  #t = !1;
1592
1632
  connectedCallback() {
1593
1633
  this.#t || (this.#t = !0, this.render());
@@ -1602,13 +1642,13 @@ var e = Object.create, t = Object.defineProperty, n = Object.getOwnPropertyDescr
1602
1642
  let { open: e } = this.#e;
1603
1643
  this.className = "pointer-events-none fixed inset-x-4 bottom-4 z-50 flex justify-center sm:justify-end", this.innerHTML = `
1604
1644
  <div
1605
- class="max-w-sm rounded-full border border-[var(--lock-border-strong)] bg-[rgba(255,255,252,0.96)] px-4 py-3 text-sm font-medium text-[var(--lock-paper)] shadow-lg shadow-black/15 backdrop-blur-xl transition duration-200 ${e ? "translate-y-0 opacity-100" : "translate-y-2 opacity-0"}"
1645
+ class="lock-surface-strong max-w-sm rounded-full border border-[var(--lock-border-strong)] px-4 py-3 text-sm font-medium text-[var(--lock-paper)] shadow-lg shadow-black/15 backdrop-blur-xl transition duration-200 ${e ? "translate-y-0 opacity-100" : "translate-y-2 opacity-0"}"
1606
1646
  >
1607
1647
  <span data-message></span>
1608
1648
  </div>
1609
1649
  `, p(this, "[data-message]", this.#e.message);
1610
1650
  }
1611
- }, P = class extends HTMLElement {
1651
+ }, N = class extends HTMLElement {
1612
1652
  #e = !1;
1613
1653
  #t = null;
1614
1654
  #n = null;
@@ -1631,18 +1671,18 @@ var e = Object.create, t = Object.defineProperty, n = Object.getOwnPropertyDescr
1631
1671
  render() {
1632
1672
  this.className = "block h-full", this.innerHTML = "\n <section class=\"relative h-full min-h-[15rem] overflow-visible rounded-[1.4rem] bg-transparent sm:min-h-[22rem] sm:rounded-[2.2rem] lg:min-h-[32rem] lg:rounded-[2rem]\">\n <div data-board-mount class=\"relative z-10 h-full\"></div>\n <div\n data-placeholder\n class=\"pointer-events-none absolute inset-0 z-20 flex items-center justify-center px-6 text-center text-sm leading-6 text-[var(--lock-muted)]\"\n >\n Board host ready\n </div>\n </section>\n ", this.#n = this.querySelector("[data-board-mount]");
1633
1673
  }
1634
- }, F = (e) => {
1674
+ }, P = (e) => {
1635
1675
  let t = e.hash.replace(/^#/, "");
1636
1676
  return new URLSearchParams(t || e.search);
1637
- }, xe = (e, t, n) => {
1677
+ }, Se = (e, t, n) => {
1638
1678
  if (!e) return "";
1639
1679
  let r = new URL(n ?? window.location.href), i = new URLSearchParams();
1640
1680
  return i.set("id", e), t && i.set("url", t), r.hash = i.toString(), r.toString();
1641
- }, Se = (e) => {
1681
+ }, Ce = (e) => {
1642
1682
  let t = e.trim();
1643
1683
  if (!t || !t.includes("://")) return null;
1644
1684
  try {
1645
- let e = F(new URL(t)), n = e.get("id");
1685
+ let e = P(new URL(t)), n = e.get("id");
1646
1686
  return n ? {
1647
1687
  peerId: n,
1648
1688
  signalUrl: e.get("url") ?? ""
@@ -1650,13 +1690,14 @@ var e = Object.create, t = Object.defineProperty, n = Object.getOwnPropertyDescr
1650
1690
  } catch {
1651
1691
  return null;
1652
1692
  }
1653
- }, Ce = () => {
1654
- let e = F(new URL(window.location.href));
1693
+ }, we = () => {
1694
+ let e = P(new URL(window.location.href));
1655
1695
  return {
1656
1696
  peerId: e.get("id") ?? "",
1657
1697
  signalUrl: e.get("url") ?? ""
1658
1698
  };
1659
- }, we = {
1699
+ }, Te = {
1700
+ theme: "light",
1660
1701
  gameTitle: "P2P Lockstep",
1661
1702
  signalUrl: "",
1662
1703
  targetId: "",
@@ -1665,8 +1706,8 @@ var e = Object.create, t = Object.defineProperty, n = Object.getOwnPropertyDescr
1665
1706
  connectionState: "idle",
1666
1707
  registering: !1,
1667
1708
  connecting: !1
1668
- }, I = class extends HTMLElement {
1669
- #e = we;
1709
+ }, F = class extends HTMLElement {
1710
+ #e = Te;
1670
1711
  #t = !1;
1671
1712
  #n = !1;
1672
1713
  connectedCallback() {
@@ -1683,26 +1724,30 @@ var e = Object.create, t = Object.defineProperty, n = Object.getOwnPropertyDescr
1683
1724
  return this.#e;
1684
1725
  }
1685
1726
  render() {
1686
- this.className = "block", this.innerHTML = "\n <section class=\"mx-auto grid min-h-full max-w-5xl gap-3 sm:gap-5 lg:grid-cols-[minmax(0,1fr)_22rem]\">\n <div class=\"lock-panel rounded-[1.4rem] p-3.5 sm:rounded-[2rem] sm:p-6 lg:p-7\">\n <div class=\"flex items-start justify-between gap-4\">\n <div class=\"min-w-0\">\n <p class=\"text-[0.62rem] font-semibold uppercase tracking-[0.18em] text-[var(--lock-dim)] sm:text-[0.68rem]\">Lobby</p>\n <h1 data-game-title class=\"mt-1.5 break-words text-3xl font-semibold leading-none tracking-[-0.04em] text-[var(--lock-paper)] sm:mt-3 sm:text-5xl lg:text-6xl\"></h1>\n </div>\n\n <details class=\"group relative shrink-0\">\n <summary\n aria-label=\"Server settings\"\n class=\"flex h-9 w-9 cursor-pointer list-none items-center justify-center rounded-full border border-[var(--lock-border)] bg-[rgba(255,255,252,0.7)] text-base font-semibold leading-none text-[var(--lock-muted)] transition hover:border-[var(--lock-border-strong)] hover:bg-white sm:h-10 sm:w-10 sm:text-lg [&::-webkit-details-marker]:hidden\"\n >\n ...\n </summary>\n <div class=\"absolute right-0 z-20 mt-2 w-[min(21rem,calc(100vw-2rem))] rounded-[1.2rem] border border-[var(--lock-border-strong)] bg-[var(--lock-surface-strong)] p-3.5 shadow-xl shadow-black/10 backdrop-blur-xl sm:mt-3 sm:rounded-[1.6rem] sm:p-4\">\n <label class=\"block\">\n <span class=\"mb-2 block text-xs uppercase tracking-[0.22em] text-[var(--lock-dim)]\">Signaling server</span>\n <input\n data-field=\"signal-url\"\n placeholder=\"wss://host\"\n class=\"lock-input lock-mono w-full rounded-2xl px-4 py-3 text-sm transition\"\n />\n </label>\n\n <button\n type=\"button\"\n data-action=\"register\"\n class=\"lock-primary lock-disabled mt-3 inline-flex w-full items-center justify-center rounded-full px-4 py-3 text-sm font-semibold transition\"\n >\n <span data-register-label></span>\n </button>\n </div>\n </details>\n </div>\n\n <div class=\"mt-4 grid grid-cols-2 gap-2 sm:mt-7 sm:gap-4\">\n <section class=\"rounded-[1rem] border border-[var(--lock-border)] bg-[rgba(255,255,252,0.58)] p-3 sm:rounded-[1.4rem] sm:p-4\">\n <p class=\"text-[0.58rem] uppercase tracking-[0.2em] text-[var(--lock-dim)] sm:text-[0.68rem]\">Server</p>\n <div class=\"mt-2 flex items-center gap-2 sm:mt-3 sm:gap-3\">\n <span data-status-dot class=\"h-2.5 w-2.5 rounded-full bg-slate-600\"></span>\n <span data-connection-state class=\"text-xs font-semibold uppercase tracking-[0.14em] text-[var(--lock-paper)] sm:text-sm\"></span>\n </div>\n </section>\n\n <section class=\"rounded-[1rem] border border-[var(--lock-border)] bg-[rgba(255,255,252,0.58)] p-3 sm:rounded-[1.4rem] sm:p-4\">\n <p class=\"text-[0.58rem] uppercase tracking-[0.2em] text-[var(--lock-dim)] sm:text-[0.68rem]\">Your ID</p>\n <p data-peer-id class=\"lock-mono mt-2 max-h-9 min-h-4 overflow-hidden break-all text-[0.68rem] leading-[1.35] text-[var(--lock-paper)] sm:mt-3 sm:max-h-none sm:text-sm\"></p>\n </section>\n </div>\n\n <section class=\"mt-3 rounded-[1.1rem] border border-[var(--lock-border)] bg-[rgba(255,255,252,0.58)] p-3 sm:mt-5 sm:rounded-[1.8rem] sm:p-5\">\n <label class=\"block\">\n <span class=\"mb-1.5 block text-xs font-semibold text-[var(--lock-muted)] sm:mb-2 sm:text-sm\">Peer ID or share link</span>\n <input\n data-field=\"target-id\"\n placeholder=\"Paste peer id\"\n class=\"lock-input lock-mono w-full rounded-xl px-3 py-3 text-sm transition sm:rounded-2xl sm:px-4 sm:py-4 sm:text-base\"\n />\n </label>\n\n <button\n type=\"button\"\n data-action=\"connect\"\n class=\"lock-primary lock-disabled mt-3 inline-flex w-full items-center justify-center rounded-full px-4 py-3 text-sm font-semibold transition sm:mt-4 sm:py-4\"\n >\n <span data-connect-label></span>\n </button>\n </section>\n </div>\n\n <p2p-lockstep-share-panel></p2p-lockstep-share-panel>\n </section>\n ", this.#n = !0, this.#r();
1727
+ this.className = "block", this.innerHTML = "\n <section class=\"mx-auto grid min-h-full max-w-5xl gap-3 sm:gap-5 lg:grid-cols-[minmax(0,1fr)_22rem]\">\n <div class=\"lock-panel rounded-[1.4rem] p-3.5 sm:rounded-[2rem] sm:p-6 lg:p-7\">\n <div class=\"flex items-start justify-between gap-4\">\n <div class=\"min-w-0\">\n <p class=\"text-[0.62rem] font-semibold uppercase tracking-[0.18em] text-[var(--lock-dim)] sm:text-[0.68rem]\">Peer connection</p>\n <h1 data-game-title class=\"mt-1.5 break-words text-3xl font-semibold leading-none tracking-[-0.04em] text-[var(--lock-paper)] sm:mt-3 sm:text-5xl lg:text-6xl\"></h1>\n </div>\n\n <details class=\"group relative shrink-0\">\n <summary\n aria-label=\"Server settings\"\n class=\"lock-control flex h-9 w-9 cursor-pointer list-none items-center justify-center rounded-full border border-[var(--lock-border)] text-base font-semibold leading-none text-[var(--lock-muted)] transition hover:border-[var(--lock-border-strong)] sm:h-10 sm:w-10 sm:text-lg [&::-webkit-details-marker]:hidden\"\n >\n ...\n </summary>\n <div class=\"lock-surface-strong absolute right-0 z-20 mt-2 w-[min(21rem,calc(100vw-2rem))] rounded-[1.2rem] border border-[var(--lock-border-strong)] p-3.5 shadow-xl shadow-black/10 backdrop-blur-xl sm:mt-3 sm:rounded-[1.6rem] sm:p-4\">\n <div class=\"lock-card mb-3 rounded-2xl border border-[var(--lock-border)] p-3\">\n <p class=\"text-[0.62rem] uppercase tracking-[0.2em] text-[var(--lock-dim)]\">Appearance</p>\n <div class=\"mt-2 grid grid-cols-2 gap-2\" role=\"group\" aria-label=\"Color mode\">\n <button type=\"button\" data-action=\"theme\" data-theme-mode=\"light\" class=\"lock-theme-option rounded-xl px-3 py-2 text-xs font-semibold\" aria-label=\"Use day mode\">Day</button>\n <button type=\"button\" data-action=\"theme\" data-theme-mode=\"dark\" class=\"lock-theme-option rounded-xl px-3 py-2 text-xs font-semibold\" aria-label=\"Use night mode\">Night</button>\n </div>\n </div>\n\n <label class=\"block\">\n <span class=\"mb-2 block text-xs uppercase tracking-[0.22em] text-[var(--lock-dim)]\">Signaling server</span>\n <input\n data-field=\"signal-url\"\n placeholder=\"wss://host\"\n class=\"lock-input lock-mono w-full rounded-2xl px-4 py-3 text-sm transition\"\n />\n </label>\n\n <button\n type=\"button\"\n data-action=\"register\"\n class=\"lock-primary lock-disabled mt-3 inline-flex w-full items-center justify-center rounded-full px-4 py-3 text-sm font-semibold transition\"\n >\n <span data-register-label></span>\n </button>\n </div>\n </details>\n </div>\n\n <div class=\"mt-4 grid grid-cols-2 gap-2 sm:mt-7 sm:gap-4\">\n <section class=\"lock-card rounded-[1rem] border border-[var(--lock-border)] p-3 sm:rounded-[1.4rem] sm:p-4\">\n <p class=\"text-[0.58rem] uppercase tracking-[0.2em] text-[var(--lock-dim)] sm:text-[0.68rem]\">Server</p>\n <div class=\"mt-2 flex items-center gap-2 sm:mt-3 sm:gap-3\">\n <span data-status-dot class=\"h-2.5 w-2.5 rounded-full bg-slate-600\"></span>\n <span data-connection-state class=\"text-xs font-semibold uppercase tracking-[0.14em] text-[var(--lock-paper)] sm:text-sm\"></span>\n </div>\n </section>\n\n <section class=\"lock-card rounded-[1rem] border border-[var(--lock-border)] p-3 sm:rounded-[1.4rem] sm:p-4\">\n <div class=\"flex items-center justify-between gap-2\">\n <p class=\"text-[0.58rem] uppercase tracking-[0.2em] text-[var(--lock-dim)] sm:text-[0.68rem]\">Your ID</p>\n <button type=\"button\" data-action=\"copy-peer\" class=\"lock-secondary lock-disabled rounded-full px-2.5 py-1 text-[0.62rem] font-semibold\" aria-label=\"Copy your peer ID\">Copy</button>\n </div>\n <p data-peer-id class=\"lock-mono mt-2 max-h-9 min-h-4 overflow-hidden break-all text-[0.68rem] leading-[1.35] text-[var(--lock-paper)] sm:mt-3 sm:max-h-none sm:text-sm\"></p>\n </section>\n </div>\n\n <section class=\"lock-card mt-3 rounded-[1.1rem] border border-[var(--lock-border)] p-3 sm:mt-5 sm:rounded-[1.8rem] sm:p-5\">\n <label class=\"block\">\n <span class=\"mb-1.5 block text-xs font-semibold text-[var(--lock-muted)] sm:mb-2 sm:text-sm\">Peer ID or share link</span>\n <input\n data-field=\"target-id\"\n placeholder=\"Paste peer id\"\n class=\"lock-input lock-mono w-full rounded-xl px-3 py-3 text-sm transition sm:rounded-2xl sm:px-4 sm:py-4 sm:text-base\"\n />\n </label>\n\n <button\n type=\"button\"\n data-action=\"connect\"\n class=\"lock-primary lock-disabled mt-3 inline-flex w-full items-center justify-center rounded-full px-4 py-3 text-sm font-semibold transition sm:mt-4 sm:py-4\"\n >\n <span data-connect-label></span>\n </button>\n </section>\n </div>\n\n <p2p-lockstep-share-panel></p2p-lockstep-share-panel>\n </section>\n ", this.#n = !0, this.#r();
1687
1728
  }
1688
1729
  #r() {
1689
1730
  p(this, "[data-game-title]", this.#e.gameTitle), p(this, "[data-connection-state]", this.#e.connectionState), p(this, "[data-register-label]", this.#e.registering ? "Registering..." : "Register peer"), p(this, "[data-connect-label]", this.#e.connecting ? "Connecting..." : "Connect"), p(this, "[data-peer-id]", this.#e.peerId || "Register first to get your peer ID."), m(this, "[data-field='signal-url']", this.#e.signalUrl), m(this, "[data-field='target-id']", this.#e.targetId);
1690
1731
  let e = this.querySelector("[data-action='register']");
1691
- e && (e.disabled = this.#e.registering || !this.#e.signalUrl.trim());
1732
+ e && (e.disabled = this.#e.registering || !this.#e.signalUrl.trim()), this.querySelectorAll("[data-theme-mode]").forEach((e) => {
1733
+ e.setAttribute("aria-pressed", String(e.dataset.themeMode === this.#e.theme));
1734
+ });
1692
1735
  let t = this.querySelector("[data-status-dot]");
1693
1736
  t && (t.className = `h-3 w-3 rounded-full ${this.#e.connectionState === "registered" || this.#e.connectionState === "connected" ? "bg-[var(--lock-teal)]" : this.#e.connectionState === "registering" || this.#e.connectionState === "connecting" ? "bg-[#c08a25]" : this.#e.connectionState === "error" || this.#e.connectionState === "offline" ? "bg-[var(--lock-rose)]" : "bg-[var(--lock-dim)]"}`);
1694
1737
  let n = this.querySelector("[data-action='connect']");
1695
1738
  n && (n.disabled = this.#e.connecting || !this.#e.targetId.trim());
1696
- let r = this.querySelector("p2p-lockstep-share-panel");
1697
- r && (r.state = {
1739
+ let r = this.querySelector("[data-action='copy-peer']");
1740
+ r && (r.disabled = !this.#e.peerId);
1741
+ let i = this.querySelector("p2p-lockstep-share-panel");
1742
+ i && (i.state = {
1698
1743
  peerId: this.#e.peerId,
1699
1744
  signalUrl: this.#e.signalUrl,
1700
- shareUrl: xe(this.#e.peerId, this.#e.signalUrl)
1745
+ shareUrl: Se(this.#e.peerId, this.#e.signalUrl)
1701
1746
  });
1702
1747
  }
1703
1748
  #i = (e) => {
1704
1749
  let t = e.target?.closest("button[data-action]");
1705
- !t || t.disabled || (t.dataset.action === "register" && l(this, "lockstep-register", { signalUrl: this.#e.signalUrl.trim() }), t.dataset.action === "connect" && l(this, "lockstep-connect", { targetId: this.#e.targetId.trim() }));
1750
+ !t || t.disabled || (t.dataset.action === "register" && l(this, "lockstep-register", { signalUrl: this.#e.signalUrl.trim() }), t.dataset.action === "connect" && l(this, "lockstep-connect", { targetId: this.#e.targetId.trim() }), t.dataset.action === "copy-peer" && l(this, "lockstep-copy-share", { value: this.#e.peerId }), t.dataset.action === "theme" && (t.dataset.themeMode === "light" || t.dataset.themeMode === "dark") && l(this, "lockstep-theme-change", { theme: t.dataset.themeMode }));
1706
1751
  };
1707
1752
  #a = (e) => {
1708
1753
  let t = e.target;
@@ -1712,7 +1757,7 @@ var e = Object.create, t = Object.defineProperty, n = Object.getOwnPropertyDescr
1712
1757
  return;
1713
1758
  }
1714
1759
  if (t.dataset.field === "target-id") {
1715
- let e = Se(t.value);
1760
+ let e = Ce(t.value);
1716
1761
  if (e) {
1717
1762
  l(this, "lockstep-share-detected", e);
1718
1763
  return;
@@ -1721,7 +1766,8 @@ var e = Object.create, t = Object.defineProperty, n = Object.getOwnPropertyDescr
1721
1766
  }
1722
1767
  }
1723
1768
  };
1724
- }, Te = {
1769
+ }, Ee = {
1770
+ theme: "light",
1725
1771
  gameTitle: "P2P Lockstep",
1726
1772
  peerId: "",
1727
1773
  remotePeerId: "",
@@ -1739,9 +1785,12 @@ var e = Object.create, t = Object.defineProperty, n = Object.getOwnPropertyDescr
1739
1785
  localState: "idle",
1740
1786
  remoteState: "idle",
1741
1787
  pendingAction: null,
1742
- sessionId: "default-session"
1743
- }, L = class extends HTMLElement {
1744
- #e = Te;
1788
+ sessionId: "default-session",
1789
+ historyLength: 0,
1790
+ lastStart: null,
1791
+ lastError: ""
1792
+ }, De = class extends HTMLElement {
1793
+ #e = Ee;
1745
1794
  #t = !1;
1746
1795
  #n = null;
1747
1796
  #r = null;
@@ -1763,6 +1812,7 @@ var e = Object.create, t = Object.defineProperty, n = Object.getOwnPropertyDescr
1763
1812
  }
1764
1813
  #a() {
1765
1814
  !this.#n || !this.#r || (this.#n.state = {
1815
+ theme: this.#e.theme,
1766
1816
  gameTitle: this.#e.gameTitle,
1767
1817
  peerId: this.#e.peerId,
1768
1818
  remotePeerId: this.#e.remotePeerId,
@@ -1775,7 +1825,10 @@ var e = Object.create, t = Object.defineProperty, n = Object.getOwnPropertyDescr
1775
1825
  readySelf: this.#e.readySelf,
1776
1826
  readyPeer: this.#e.readyPeer,
1777
1827
  pendingAction: this.#e.pendingAction,
1778
- sessionId: this.#e.sessionId
1828
+ sessionId: this.#e.sessionId,
1829
+ historyLength: this.#e.historyLength,
1830
+ lastStart: this.#e.lastStart,
1831
+ lastError: this.#e.lastError
1779
1832
  }, this.#r.state = {
1780
1833
  connected: this.#e.connected,
1781
1834
  readySelf: this.#e.readySelf,
@@ -1787,10 +1840,10 @@ var e = Object.create, t = Object.defineProperty, n = Object.getOwnPropertyDescr
1787
1840
  connectionState: this.#e.connectionState
1788
1841
  });
1789
1842
  }
1790
- }, R = (e) => JSON.stringify(e), Ee = (e) => {
1843
+ }, I = (e) => JSON.stringify(e), Oe = (e) => {
1791
1844
  if (typeof e != "string") throw TypeError("decode expects a serialized string");
1792
1845
  return JSON.parse(e);
1793
- }, De = (e) => {
1846
+ }, ke = (e) => {
1794
1847
  if (typeof e != "string") return {
1795
1848
  ok: !1,
1796
1849
  error: /* @__PURE__ */ TypeError("decodeSafe expects a serialized string")
@@ -1806,7 +1859,7 @@ var e = Object.create, t = Object.defineProperty, n = Object.getOwnPropertyDescr
1806
1859
  error: e
1807
1860
  };
1808
1861
  }
1809
- }, z = (e, t) => {
1862
+ }, L = (e, t) => {
1810
1863
  t === void 0 ? console.log(e) : console.log(e, t);
1811
1864
  let n = globalThis.__p2p_debug;
1812
1865
  if (typeof n == "function") try {
@@ -1814,39 +1867,39 @@ var e = Object.create, t = Object.defineProperty, n = Object.getOwnPropertyDescr
1814
1867
  } catch {
1815
1868
  n(e);
1816
1869
  }
1817
- }, Oe = class {
1870
+ }, Ae = class {
1818
1871
  constructor() {
1819
1872
  this.ws = null, this.peerId = null, this.ready = !1, this.signalHandlers = /* @__PURE__ */ new Set(), this.pendingRegistration = null, this.connect = (e) => new Promise((t, n) => {
1820
- this.ws?.close(), z("[signaling] ws connect", e), this.ws = new WebSocket(e);
1873
+ this.ws?.close(), L("[signaling] ws connect", e), this.ws = new WebSocket(e);
1821
1874
  let r = window.setTimeout(() => {
1822
1875
  try {
1823
1876
  this.ws?.close();
1824
1877
  } catch {}
1825
- z("[signaling] ws open timeout"), n(/* @__PURE__ */ Error("ws open timeout"));
1878
+ L("[signaling] ws open timeout"), n(/* @__PURE__ */ Error("ws open timeout"));
1826
1879
  }, 5e3);
1827
1880
  this.ws.addEventListener("open", () => {
1828
- this.ready = !0, this.registeredPayload = void 0, window.clearTimeout(r), z("[signaling] ws open"), t();
1881
+ this.ready = !0, this.registeredPayload = void 0, window.clearTimeout(r), L("[signaling] ws open"), t();
1829
1882
  }), this.ws.addEventListener("error", (e) => {
1830
- window.clearTimeout(r), z("[signaling] ws error", e), n(/* @__PURE__ */ Error("ws error"));
1883
+ window.clearTimeout(r), L("[signaling] ws error", e), n(/* @__PURE__ */ Error("ws error"));
1831
1884
  }), this.ws.addEventListener("close", (e) => {
1832
- this.ready = !1, this.peerId = null, this.registeredPayload = void 0, this.rejectPendingRegistration(/* @__PURE__ */ Error("ws closed")), window.clearTimeout(r), z("[signaling] ws close", {
1885
+ this.ready = !1, this.peerId = null, this.registeredPayload = void 0, this.rejectPendingRegistration(/* @__PURE__ */ Error("ws closed")), window.clearTimeout(r), L("[signaling] ws close", {
1833
1886
  code: e.code,
1834
1887
  reason: e.reason
1835
1888
  });
1836
1889
  }), this.ws.addEventListener("message", (e) => {
1837
- let t = String(e.data), n = De(t);
1890
+ let t = String(e.data), n = ke(t);
1838
1891
  if (!n.ok) {
1839
- z("[signaling] ws message decode error", t), this.rejectPendingRegistration(/* @__PURE__ */ Error("signaling decode error"));
1892
+ L("[signaling] ws message decode error", t), this.rejectPendingRegistration(/* @__PURE__ */ Error("signaling decode error"));
1840
1893
  return;
1841
1894
  }
1842
1895
  let r = n.value;
1843
- if (z("[signaling] ws message", r), r.type === "ERROR") {
1844
- z("[signaling] error", r), this.rejectPendingRegistration(/* @__PURE__ */ Error("signaling error"));
1896
+ if (L("[signaling] ws message", r), r.type === "ERROR") {
1897
+ L("[signaling] error", r), this.rejectPendingRegistration(/* @__PURE__ */ Error("signaling error"));
1845
1898
  return;
1846
1899
  }
1847
1900
  if ((r.type === "REGISTERED" || r.type === "RESUMED") && (this.peerId = r.to ?? null, this.registeredPayload = r.payload, this.peerId)) {
1848
1901
  let e = this.resolveRegisteredPayload();
1849
- z("[signaling] registered", {
1902
+ L("[signaling] registered", {
1850
1903
  peerId: this.peerId,
1851
1904
  resumeToken: e.resumeToken
1852
1905
  }), this.resolvePendingRegistration({
@@ -1868,14 +1921,14 @@ var e = Object.create, t = Object.defineProperty, n = Object.getOwnPropertyDescr
1868
1921
  }), this.register = async () => {
1869
1922
  this.assertConnected();
1870
1923
  let e = { type: "REGISTER" };
1871
- z("[signaling] send REGISTER");
1924
+ L("[signaling] send REGISTER");
1872
1925
  let t = this.awaitRegistration("register");
1873
- this.ws?.send(R(e));
1926
+ this.ws?.send(I(e));
1874
1927
  try {
1875
1928
  let e = await t;
1876
- return z("[signaling] register ok", e.peerId), e;
1929
+ return L("[signaling] register ok", e.peerId), e;
1877
1930
  } catch (e) {
1878
- throw z("[signaling] register error", e), e;
1931
+ throw L("[signaling] register error", e), e;
1879
1932
  }
1880
1933
  }, this.resume = async (e) => {
1881
1934
  this.assertConnected();
@@ -1886,14 +1939,14 @@ var e = Object.create, t = Object.defineProperty, n = Object.getOwnPropertyDescr
1886
1939
  data: e
1887
1940
  }
1888
1941
  };
1889
- z("[signaling] send RESUME", e.peerId);
1942
+ L("[signaling] send RESUME", e.peerId);
1890
1943
  let n = this.awaitRegistration("resume");
1891
- this.ws?.send(R(t));
1944
+ this.ws?.send(I(t));
1892
1945
  try {
1893
1946
  let e = await n;
1894
- return z("[signaling] resume ok", e.peerId), e;
1947
+ return L("[signaling] resume ok", e.peerId), e;
1895
1948
  } catch (e) {
1896
- throw z("[signaling] resume error", e), e;
1949
+ throw L("[signaling] resume error", e), e;
1897
1950
  }
1898
1951
  }, this.relay = (e) => {
1899
1952
  if (!this.ws || !this.ready) return;
@@ -1906,7 +1959,7 @@ var e = Object.create, t = Object.defineProperty, n = Object.getOwnPropertyDescr
1906
1959
  to: e.to,
1907
1960
  payload: t
1908
1961
  };
1909
- this.ws.send(R(n));
1962
+ this.ws.send(I(n));
1910
1963
  };
1911
1964
  }
1912
1965
  onSignal(e) {
@@ -1935,7 +1988,7 @@ var e = Object.create, t = Object.defineProperty, n = Object.getOwnPropertyDescr
1935
1988
  resolve: t,
1936
1989
  reject: n,
1937
1990
  timeoutId: window.setTimeout(() => {
1938
- this.pendingRegistration = null, z(`[signaling] ${e} timeout`), n(/* @__PURE__ */ Error(`${e} timeout`));
1991
+ this.pendingRegistration = null, L(`[signaling] ${e} timeout`), n(/* @__PURE__ */ Error(`${e} timeout`));
1939
1992
  }, 5e3)
1940
1993
  };
1941
1994
  });
@@ -1951,7 +2004,7 @@ var e = Object.create, t = Object.defineProperty, n = Object.getOwnPropertyDescr
1951
2004
  emitSignal(e) {
1952
2005
  for (let t of [...this.signalHandlers]) t(e);
1953
2006
  }
1954
- }, ke = [
2007
+ }, je = [
1955
2008
  {
1956
2009
  from: "passive",
1957
2010
  event: "CONNECT",
@@ -1982,10 +2035,10 @@ var e = Object.create, t = Object.defineProperty, n = Object.getOwnPropertyDescr
1982
2035
  event: "CONNECT",
1983
2036
  to: "requesting"
1984
2037
  }
1985
- ], Ae = (e, t) => {
1986
- let n = ke.find((n) => n.from === e && n.event === t);
2038
+ ], Me = (e, t) => {
2039
+ let n = je.find((n) => n.from === e && n.event === t);
1987
2040
  return n ? n.to : e;
1988
- }, je = [
2041
+ }, Ne = [
1989
2042
  {
1990
2043
  from: "idle",
1991
2044
  event: "REQUEST",
@@ -2031,10 +2084,10 @@ var e = Object.create, t = Object.defineProperty, n = Object.getOwnPropertyDescr
2031
2084
  event: "STOP",
2032
2085
  to: "idle"
2033
2086
  }
2034
- ], Me = (e, t) => {
2035
- let n = je.find((n) => n.from === e && n.event === t);
2087
+ ], Pe = (e, t) => {
2088
+ let n = Ne.find((n) => n.from === e && n.event === t);
2036
2089
  return n ? n.to : e;
2037
- }, Ne = class {
2090
+ }, Fe = class {
2038
2091
  constructor(e, t, n, r, i, a, o) {
2039
2092
  this.dc = null, this.pendingSends = [], this.remoteId = null, this.requestedId = null, this.state = "passive", this.localStream = null, this.remoteStream = null, this.onRemoteStreamHandler = null, this.senders = [], this.mediaState = "idle", this.negotiating = !1, this.renegotiateQueued = !1, this.onStateChangeHandler = null, this.onMediaChangeHandler = null, this.handleConnectionStateChange = () => {
2040
2093
  if (this.pc.connectionState === "connected") {
@@ -2116,7 +2169,7 @@ var e = Object.create, t = Object.defineProperty, n = Object.getOwnPropertyDescr
2116
2169
  }
2117
2170
  }[e.type]();
2118
2171
  }, this.dispatch = (e) => {
2119
- let t = Ae(this.state, e);
2172
+ let t = Me(this.state, e);
2120
2173
  if (this.setPeerState(t)) {
2121
2174
  if (t === "requesting" && e === "CONNECT") {
2122
2175
  this.requestedId &&= (this.remoteId = this.requestedId, null), this.runTask(this.startOffer(), "startOffer");
@@ -2166,7 +2219,7 @@ var e = Object.create, t = Object.defineProperty, n = Object.getOwnPropertyDescr
2166
2219
  this.remoteStream = null, this.onRemoteStreamHandler?.(null);
2167
2220
  }
2168
2221
  }, this.isMediaReady = () => this.dc?.readyState === "open", this.dispatchMedia = (e) => {
2169
- let t = Me(this.mediaState, e);
2222
+ let t = Pe(this.mediaState, e);
2170
2223
  if (!this.setMediaState(t)) {
2171
2224
  e === "REQUEST" && t === "starting" && this.attemptActivateMedia();
2172
2225
  return;
@@ -2214,17 +2267,17 @@ var e = Object.create, t = Object.defineProperty, n = Object.getOwnPropertyDescr
2214
2267
  console.error(`[rtc-peer] ${t} failed`, e), this.dispatchMedia("DISCONNECT"), this.dispatch("DISCONNECT");
2215
2268
  });
2216
2269
  }
2217
- }, B = "p2p-lockstep-kit:signal-session", Pe = () => {
2270
+ }, R = "p2p-lockstep-kit:signal-session", Ie = 600 * 1e3, Le = () => {
2218
2271
  if (typeof window > "u") return null;
2219
2272
  try {
2220
2273
  return window.localStorage;
2221
2274
  } catch {
2222
2275
  return null;
2223
2276
  }
2224
- }, Fe = () => {
2225
- let e = Pe();
2277
+ }, Re = () => {
2278
+ let e = Le();
2226
2279
  if (!e) return null;
2227
- let t = e.getItem(B);
2280
+ let t = e.getItem(R);
2228
2281
  if (!t) return null;
2229
2282
  try {
2230
2283
  let e = JSON.parse(t);
@@ -2232,41 +2285,42 @@ var e = Object.create, t = Object.defineProperty, n = Object.getOwnPropertyDescr
2232
2285
  } catch {
2233
2286
  return null;
2234
2287
  }
2235
- }, Ie = (e) => {
2236
- let t = Pe();
2288
+ }, ze = (e) => {
2289
+ let t = Le();
2237
2290
  if (t) {
2238
2291
  if (!e) {
2239
- t.removeItem(B);
2292
+ t.removeItem(R);
2240
2293
  return;
2241
2294
  }
2242
- t.setItem(B, JSON.stringify(e));
2295
+ t.setItem(R, JSON.stringify(e));
2243
2296
  }
2244
- }, Le = () => {
2245
- Ie(null);
2246
- }, Re = class {
2247
- constructor(e = new Oe()) {
2297
+ }, Be = () => {
2298
+ ze(null);
2299
+ }, Ve = (e, t = Ie) => Date.now() - e.updatedAt > t, He = class {
2300
+ constructor(e = new Ae()) {
2248
2301
  this.peer = null, this.onMessageHandler = null, this.onRemoteStreamHandler = null, this.pendingMediaStream = null, this.onStateChangeHandler = null, this.onMediaChangeHandler = null, this.getLocalPeerId = () => this.peer?.getPeerId() ?? null, this.getRemotePeerId = () => this.peer?.getRemoteId() ?? null, this.peerState = () => this.peer?.getPeerState() ?? "passive", this.mediaState = () => this.peer?.getMediaState() ?? "idle", this.signaling = e;
2249
2302
  }
2250
2303
  async register(e) {
2251
2304
  this.peer?.dispose(), this.peer = null, await this.signaling.connect(e);
2252
- let t = Fe(), n = null;
2253
- if (t) try {
2305
+ let t = Re(), n = null;
2306
+ if (t && Ve(t)) Be();
2307
+ else if (t) try {
2254
2308
  n = await this.signaling.resume({
2255
2309
  peerId: t.peerId,
2256
2310
  resumeToken: t.resumeToken
2257
2311
  });
2258
2312
  } catch {
2259
- Le();
2313
+ Be();
2260
2314
  }
2261
- n ||= await this.signaling.register(), n.resumeToken && Ie({
2315
+ n ||= await this.signaling.register(), n.resumeToken && ze({
2262
2316
  peerId: n.peerId,
2263
2317
  resumeToken: n.resumeToken,
2264
2318
  updatedAt: Date.now()
2265
2319
  });
2266
2320
  let r = new RTCPeerConnection({ iceServers: n.iceServers });
2267
- return this.peer = new Ne(n.peerId, r, this.signaling, (e) => {
2321
+ return this.peer = new Fe(n.peerId, r, this.signaling, (e) => {
2268
2322
  try {
2269
- let t = Ee(String(e));
2323
+ let t = Oe(String(e));
2270
2324
  this.onMessageHandler?.(t);
2271
2325
  } catch {
2272
2326
  this.onMessageHandler?.(e);
@@ -2283,7 +2337,7 @@ var e = Object.create, t = Object.defineProperty, n = Object.getOwnPropertyDescr
2283
2337
  this.peer && await this.peer.connect(e);
2284
2338
  }
2285
2339
  send(e) {
2286
- let t = R(e);
2340
+ let t = I(e);
2287
2341
  this.peer?.send(t);
2288
2342
  }
2289
2343
  disconnect() {
@@ -2307,19 +2361,19 @@ var e = Object.create, t = Object.defineProperty, n = Object.getOwnPropertyDescr
2307
2361
  onMediaChange(e) {
2308
2362
  this.onMediaChangeHandler = e, e(this.peer?.getMediaState() ?? "idle");
2309
2363
  }
2310
- }, V = (e) => (t, n) => {
2364
+ }, z = (e) => (t, n) => {
2311
2365
  let r = e === "debug" ? console.info : console[e];
2312
2366
  if (n !== void 0) {
2313
2367
  r(t, n);
2314
2368
  return;
2315
2369
  }
2316
2370
  r(t);
2317
- }, H = {
2318
- debug: V("debug"),
2319
- info: V("info"),
2320
- warn: V("warn"),
2321
- error: V("error")
2322
- }, ze = (e) => {
2371
+ }, B = {
2372
+ debug: z("debug"),
2373
+ info: z("info"),
2374
+ warn: z("warn"),
2375
+ error: z("error")
2376
+ }, Ue = (e) => {
2323
2377
  if (typeof e != "string") return {
2324
2378
  ok: !1,
2325
2379
  error: /* @__PURE__ */ TypeError("decodeSafe expects a serialized string")
@@ -2335,11 +2389,11 @@ var e = Object.create, t = Object.defineProperty, n = Object.getOwnPropertyDescr
2335
2389
  error: e
2336
2390
  };
2337
2391
  }
2338
- }, Be = (e) => {
2392
+ }, We = (e) => {
2339
2393
  if (typeof e != "string") return !e || typeof e != "object" ? null : e;
2340
- let t = ze(e);
2394
+ let t = Ue(e);
2341
2395
  return !t.ok || !t.value || typeof t.value != "object" ? null : t.value;
2342
- }, Ve = class {
2396
+ }, Ge = class {
2343
2397
  handlers = {};
2344
2398
  processingQueue = Promise.resolve();
2345
2399
  emit(e, t, n = "local") {
@@ -2350,11 +2404,11 @@ var e = Object.create, t = Object.defineProperty, n = Object.getOwnPropertyDescr
2350
2404
  });
2351
2405
  }
2352
2406
  register(e, t) {
2353
- this.handlers[e] = t, H.debug(`[session:bus] registered ${e}`);
2407
+ this.handlers[e] = t, B.debug(`[session:bus] registered ${e}`);
2354
2408
  }
2355
2409
  dispatch(e) {
2356
2410
  this.processingQueue = this.processingQueue.then(async () => {
2357
- H.debug(`[session:bus] dispatch ${e.type}`, {
2411
+ B.debug(`[session:bus] dispatch ${e.type}`, {
2358
2412
  from: e.from,
2359
2413
  payload: e.payload,
2360
2414
  turn: e.turn,
@@ -2363,16 +2417,16 @@ var e = Object.create, t = Object.defineProperty, n = Object.getOwnPropertyDescr
2363
2417
  let t = this.handlers[e.type];
2364
2418
  if (t) {
2365
2419
  try {
2366
- await t(e), H.debug(`[session:bus] handled ${e.type}`, { from: e.from });
2420
+ await t(e), B.debug(`[session:bus] handled ${e.type}`, { from: e.from });
2367
2421
  } catch (t) {
2368
2422
  console.error(`[CommandBus] Error in ${e.type}:`, t);
2369
2423
  }
2370
2424
  return;
2371
2425
  }
2372
- H.debug(`[session:bus] no handler for ${e.type}`, { from: e.from });
2426
+ B.debug(`[session:bus] no handler for ${e.type}`, { from: e.from });
2373
2427
  });
2374
2428
  }
2375
- }, U = [
2429
+ }, V = [
2376
2430
  {
2377
2431
  from: "idle",
2378
2432
  event: "READY",
@@ -2613,13 +2667,13 @@ var e = Object.create, t = Object.defineProperty, n = Object.getOwnPropertyDescr
2613
2667
  event: "ONLINE",
2614
2668
  to: "syncing"
2615
2669
  }
2616
- ], He = (e, t, n) => {
2617
- if (n) return U.find((r) => r.from === e && r.event === t && r.to === n) ? n : e;
2670
+ ], Ke = (e, t, n) => {
2671
+ if (n) return V.find((r) => r.from === e && r.event === t && r.to === n) ? n : e;
2618
2672
  {
2619
- let n = U.find((n) => n.from === e && n.event === t);
2673
+ let n = V.find((n) => n.from === e && n.event === t);
2620
2674
  return n ? n.to : e;
2621
2675
  }
2622
- }, Ue = (e, t, n) => n ? !!U.find((r) => r.from === e && r.event === t && r.to === n) : !!U.find((n) => n.from === e && n.event === t), W = class {
2676
+ }, qe = (e, t, n) => n ? !!V.find((r) => r.from === e && r.event === t && r.to === n) : !!V.find((n) => n.from === e && n.event === t), H = class {
2623
2677
  state;
2624
2678
  constructor(e = "idle") {
2625
2679
  this.state = e;
@@ -2628,19 +2682,19 @@ var e = Object.create, t = Object.defineProperty, n = Object.getOwnPropertyDescr
2628
2682
  return this.state;
2629
2683
  }
2630
2684
  hasNextState(e, t) {
2631
- return Ue(this.state, e, t);
2685
+ return qe(this.state, e, t);
2632
2686
  }
2633
2687
  dispatch(e, t) {
2634
- this.state = He(this.state, e, t);
2688
+ this.state = Ke(this.state, e, t);
2635
2689
  }
2636
- }, We = class {
2690
+ }, Je = class {
2637
2691
  validateMove() {
2638
2692
  return { valid: !0 };
2639
2693
  }
2640
2694
  checkWin() {
2641
2695
  return null;
2642
2696
  }
2643
- }, Ge = class {
2697
+ }, Ye = class {
2644
2698
  observers = /* @__PURE__ */ new Set();
2645
2699
  subscribe(e) {
2646
2700
  this.observers.add(e);
@@ -2669,7 +2723,7 @@ var e = Object.create, t = Object.defineProperty, n = Object.getOwnPropertyDescr
2669
2723
  console.error("[StateObserver]", e);
2670
2724
  }
2671
2725
  }
2672
- }, Ke = class {
2726
+ }, Xe = class {
2673
2727
  observers = /* @__PURE__ */ new Set();
2674
2728
  currentSnapshot = null;
2675
2729
  subscribe(e) {
@@ -2717,7 +2771,7 @@ var e = Object.create, t = Object.defineProperty, n = Object.getOwnPropertyDescr
2717
2771
  return this.observers.size;
2718
2772
  }
2719
2773
  };
2720
- function qe(e, t = !1) {
2774
+ function Ze(e, t = !1) {
2721
2775
  return {
2722
2776
  localState: e.getState("local"),
2723
2777
  remoteState: e.getState("remote"),
@@ -2728,7 +2782,7 @@ function qe(e, t = !1) {
2728
2782
  connected: t
2729
2783
  };
2730
2784
  }
2731
- var Je = class {
2785
+ var Qe = class {
2732
2786
  lastNotificationTime = 0;
2733
2787
  notificationThrottleMs = 0;
2734
2788
  constructor(e, t, n = () => !1) {
@@ -2738,8 +2792,8 @@ var Je = class {
2738
2792
  let e = Date.now();
2739
2793
  if (this.lastNotificationTime + this.notificationThrottleMs > e) return;
2740
2794
  this.lastNotificationTime = e;
2741
- let t = qe(this.stateRef, this.getConnected());
2742
- H.debug("[session:observer] state snapshot", {
2795
+ let t = Ze(this.stateRef, this.getConnected());
2796
+ B.debug("[session:observer] state snapshot", {
2743
2797
  local: t.localState,
2744
2798
  remote: t.remoteState,
2745
2799
  turn: t.turn,
@@ -2757,9 +2811,9 @@ var Je = class {
2757
2811
  emitEvent(e) {
2758
2812
  this.uiObserver.notifyGameEvent(e);
2759
2813
  }
2760
- }, Ye = class {
2761
- local = new W("idle");
2762
- remote = new W("idle");
2814
+ }, $e = class {
2815
+ local = new H("idle");
2816
+ remote = new H("idle");
2763
2817
  localId = null;
2764
2818
  remoteId = null;
2765
2819
  history = [];
@@ -2767,10 +2821,10 @@ var Je = class {
2767
2821
  pendingUndoCount = null;
2768
2822
  resumeTurn = null;
2769
2823
  lastStart = null;
2770
- gamePlugin = new We();
2771
- stateObserverManager = new Ge();
2824
+ gamePlugin = new Je();
2825
+ stateObserverManager = new Ye();
2772
2826
  constructor(e, t) {
2773
- e && (this.localId = e), t && (this.remoteId = t), H.debug("[session:state] created", {
2827
+ e && (this.localId = e), t && (this.remoteId = t), B.debug("[session:state] created", {
2774
2828
  localId: e,
2775
2829
  remoteId: t
2776
2830
  });
@@ -2785,7 +2839,7 @@ var Je = class {
2785
2839
  return this.remoteId;
2786
2840
  }
2787
2841
  setremoteId(e) {
2788
- this.remoteId = e, H.debug("[session:state] remote id set", { remoteId: e });
2842
+ this.remoteId = e, B.debug("[session:state] remote id set", { remoteId: e });
2789
2843
  }
2790
2844
  getState(e) {
2791
2845
  return this.getPlayerFsm(e).getState();
@@ -2797,7 +2851,7 @@ var Je = class {
2797
2851
  return this.history.slice();
2798
2852
  }
2799
2853
  replaceHistory(e) {
2800
- H.debug("[session:history] replace", { count: e.length }), this.clearHistory(), e.forEach((e) => {
2854
+ B.debug("[session:history] replace", { count: e.length }), this.clearHistory(), e.forEach((e) => {
2801
2855
  this.pushHistory({
2802
2856
  turn: e.turn,
2803
2857
  player: e.player,
@@ -2807,10 +2861,10 @@ var Je = class {
2807
2861
  }
2808
2862
  clearHistory() {
2809
2863
  let e = this.history.length;
2810
- this.history.splice(0, this.history.length), H.debug("[session:history] clear", { count: e }), this.notifyHistoryChanged();
2864
+ this.history.splice(0, this.history.length), B.debug("[session:history] clear", { count: e }), this.notifyHistoryChanged();
2811
2865
  }
2812
2866
  pushHistory(e) {
2813
- this.history.push(e), H.debug("[session:history] push", {
2867
+ this.history.push(e), B.debug("[session:history] push", {
2814
2868
  turn: e.turn,
2815
2869
  player: e.player,
2816
2870
  move: e.move,
@@ -2819,7 +2873,7 @@ var Je = class {
2819
2873
  }
2820
2874
  popHistory() {
2821
2875
  let e = this.history.pop() ?? null;
2822
- return e && (H.debug("[session:history] pop", {
2876
+ return e && (B.debug("[session:history] pop", {
2823
2877
  turn: e.turn,
2824
2878
  player: e.player,
2825
2879
  move: e.move,
@@ -2833,7 +2887,7 @@ var Je = class {
2833
2887
  let r = this.getState(e);
2834
2888
  this.getPlayerFsm(e).dispatch(t, n);
2835
2889
  let i = this.getState(e);
2836
- H.debug(`[session:fsm] ${e} ${t}`, {
2890
+ B.debug(`[session:fsm] ${e} ${t}`, {
2837
2891
  from: r,
2838
2892
  to: i,
2839
2893
  requested: n,
@@ -2845,7 +2899,7 @@ var Je = class {
2845
2899
  }), this.notifyStateChanged();
2846
2900
  }
2847
2901
  setPendingAction(e) {
2848
- H.debug("[session:state] pending action set", {
2902
+ B.debug("[session:state] pending action set", {
2849
2903
  from: this.pendingAction,
2850
2904
  to: e
2851
2905
  }), this.pendingAction = e;
@@ -2854,7 +2908,7 @@ var Je = class {
2854
2908
  return this.pendingAction;
2855
2909
  }
2856
2910
  setPendingUndoCount(e) {
2857
- H.debug("[session:state] pending undo count set", {
2911
+ B.debug("[session:state] pending undo count set", {
2858
2912
  from: this.pendingUndoCount,
2859
2913
  to: e
2860
2914
  }), this.pendingUndoCount = e;
@@ -2863,7 +2917,7 @@ var Je = class {
2863
2917
  return this.pendingUndoCount;
2864
2918
  }
2865
2919
  setLastStart(e) {
2866
- H.debug("[session:state] last start set", {
2920
+ B.debug("[session:state] last start set", {
2867
2921
  from: this.lastStart,
2868
2922
  to: e
2869
2923
  }), this.lastStart = e;
@@ -2872,7 +2926,7 @@ var Je = class {
2872
2926
  return this.lastStart;
2873
2927
  }
2874
2928
  setResumeTurn(e) {
2875
- H.debug("[session:state] resume turn set", {
2929
+ B.debug("[session:state] resume turn set", {
2876
2930
  from: this.resumeTurn,
2877
2931
  to: e
2878
2932
  }), this.resumeTurn = e;
@@ -2884,7 +2938,7 @@ var Je = class {
2884
2938
  return e === "local" ? this.local : this.remote;
2885
2939
  }
2886
2940
  notifyStateChanged() {
2887
- H.debug("[session:state] notify state changed", {
2941
+ B.debug("[session:state] notify state changed", {
2888
2942
  local: this.getState("local"),
2889
2943
  remote: this.getState("remote"),
2890
2944
  turn: this.getTurnCount(),
@@ -2893,21 +2947,21 @@ var Je = class {
2893
2947
  }), this.stateObserverManager.notifyStateChanged();
2894
2948
  }
2895
2949
  notifyHistoryChanged() {
2896
- H.debug("[session:state] notify history changed", {
2950
+ B.debug("[session:state] notify history changed", {
2897
2951
  turn: this.getTurnCount(),
2898
2952
  history: this.history.length,
2899
2953
  pending: this.pendingAction
2900
2954
  }), this.stateObserverManager.notifyHistoryChanged();
2901
2955
  }
2902
2956
  notifyGameReset() {
2903
- H.debug("[session:state] notify game reset"), this.stateObserverManager.notifyGameReset();
2957
+ B.debug("[session:state] notify game reset"), this.stateObserverManager.notifyGameReset();
2904
2958
  }
2905
2959
  dispatchPair(e, t, n, r) {
2906
2960
  let i = {
2907
2961
  local: this.local.getState(),
2908
2962
  remote: this.remote.getState()
2909
2963
  };
2910
- this.local.dispatch(e, t), this.remote.dispatch(n, r), H.debug("[session:fsm] pair dispatch", {
2964
+ this.local.dispatch(e, t), this.remote.dispatch(n, r), B.debug("[session:fsm] pair dispatch", {
2911
2965
  before: i,
2912
2966
  after: {
2913
2967
  local: this.local.getState(),
@@ -2924,32 +2978,32 @@ var Je = class {
2924
2978
  }
2925
2979
  gameSnapshot = null;
2926
2980
  saveGameSnapshot(e) {
2927
- this.gameSnapshot = e, H.debug("[session:state] game snapshot saved", { snapshot: e });
2981
+ this.gameSnapshot = e, B.debug("[session:state] game snapshot saved", { snapshot: e });
2928
2982
  }
2929
2983
  getGameSnapshot() {
2930
2984
  return this.gameSnapshot;
2931
2985
  }
2932
2986
  clearGameSnapshot() {
2933
- this.gameSnapshot = null, H.debug("[session:state] game snapshot cleared");
2987
+ this.gameSnapshot = null, B.debug("[session:state] game snapshot cleared");
2934
2988
  }
2935
2989
  hasPendingAction() {
2936
2990
  return this.pendingAction !== null;
2937
2991
  }
2938
2992
  clearPendingStates() {
2939
- H.debug("[session:state] pending states cleared", {
2993
+ B.debug("[session:state] pending states cleared", {
2940
2994
  pending: this.pendingAction,
2941
2995
  pendingUndoCount: this.pendingUndoCount,
2942
2996
  resumeTurn: this.resumeTurn
2943
2997
  }), this.pendingAction = null, this.pendingUndoCount = null, this.resumeTurn = null, this.notifyStateChanged();
2944
2998
  }
2945
2999
  initializeUndoRequest(e, t) {
2946
- this.pendingAction = "undo", this.pendingUndoCount = e, this.resumeTurn = t, H.debug("[session:state] undo request initialized", {
3000
+ this.pendingAction = "undo", this.pendingUndoCount = e, this.resumeTurn = t, B.debug("[session:state] undo request initialized", {
2947
3001
  undoCount: e,
2948
3002
  resumeTurn: t
2949
3003
  });
2950
3004
  }
2951
3005
  initializeRestartRequest(e) {
2952
- this.pendingAction = "restart", this.resumeTurn = e, H.debug("[session:state] restart request initialized", { resumeTurn: e });
3006
+ this.pendingAction = "restart", this.resumeTurn = e, B.debug("[session:state] restart request initialized", { resumeTurn: e });
2953
3007
  }
2954
3008
  isPendingUndo() {
2955
3009
  return this.pendingAction === "undo";
@@ -2958,20 +3012,20 @@ var Je = class {
2958
3012
  return this.pendingAction === "restart";
2959
3013
  }
2960
3014
  applyUndo(e = 1) {
2961
- H.debug("[session:history] apply undo", { count: e });
3015
+ B.debug("[session:history] apply undo", { count: e });
2962
3016
  for (let t = 0; t < e; t++) this.popHistory();
2963
3017
  }
2964
3018
  resetGame() {
2965
- H.debug("[session:state] reset game", {
3019
+ B.debug("[session:state] reset game", {
2966
3020
  local: this.getState("local"),
2967
3021
  remote: this.getState("remote"),
2968
3022
  history: this.history.length,
2969
3023
  lastStart: this.lastStart,
2970
3024
  pending: this.pendingAction
2971
- }), this.clearHistory(), this.local = new W("idle"), this.remote = new W("idle"), this.lastStart = null, this.pendingAction = null, this.pendingUndoCount = null, this.resumeTurn = null, this.notifyGameReset(), this.notifyStateChanged();
3025
+ }), this.clearHistory(), this.local = new H("idle"), this.remote = new H("idle"), this.lastStart = null, this.pendingAction = null, this.pendingUndoCount = null, this.resumeTurn = null, this.notifyGameReset(), this.notifyStateChanged();
2972
3026
  }
2973
3027
  recordStartPlayer(e) {
2974
- this.lastStart = e, H.debug("[session:state] start player recorded", { player: e });
3028
+ this.lastStart = e, B.debug("[session:state] start player recorded", { player: e });
2975
3029
  }
2976
3030
  getLastMove() {
2977
3031
  return this.history.length > 0 ? this.history[this.history.length - 1] : null;
@@ -2993,7 +3047,7 @@ var Je = class {
2993
3047
  remote: this.remote.getState(),
2994
3048
  lastStart: this.lastStart
2995
3049
  };
2996
- e === "local" ? (this.local.dispatch("START", "turn"), this.remote.dispatch("START", "remote_turn"), this.lastStart = "local") : (this.local.dispatch("START", "remote_turn"), this.remote.dispatch("START", "turn"), this.lastStart = "remote"), H.debug("[session:fsm] start dispatch", {
3050
+ e === "local" ? (this.local.dispatch("START", "turn"), this.remote.dispatch("START", "remote_turn"), this.lastStart = "local") : (this.local.dispatch("START", "remote_turn"), this.remote.dispatch("START", "turn"), this.lastStart = "remote"), B.debug("[session:fsm] start dispatch", {
2997
3051
  before: t,
2998
3052
  firstPlayer: e,
2999
3053
  after: {
@@ -3007,7 +3061,7 @@ var Je = class {
3007
3061
  e === "local" ? this.dispatchPair("SYNC_COMPLETE", "turn", "SYNC_COMPLETE", "remote_turn") : this.dispatchPair("SYNC_COMPLETE", "remote_turn", "SYNC_COMPLETE", "turn"), this.resumeTurn = null;
3008
3062
  }
3009
3063
  setGamePlugin(e) {
3010
- this.gamePlugin = e, H.debug("[session:plugin] game plugin set", {
3064
+ this.gamePlugin = e, B.debug("[session:plugin] game plugin set", {
3011
3065
  hasInitialize: !!e.initialize,
3012
3066
  hasCleanup: !!e.cleanup
3013
3067
  }), e.initialize && e.initialize();
@@ -3017,7 +3071,7 @@ var Je = class {
3017
3071
  }
3018
3072
  validateMove(e) {
3019
3073
  let t = this.buildGameState(), n = this.gamePlugin.validateMove(e, t);
3020
- return H.debug("[session:plugin] validate move", {
3074
+ return B.debug("[session:plugin] validate move", {
3021
3075
  move: e,
3022
3076
  result: n,
3023
3077
  local: t.localState,
@@ -3028,14 +3082,14 @@ var Je = class {
3028
3082
  }
3029
3083
  checkWin() {
3030
3084
  let e = this.buildGameState(), t = this.gamePlugin.checkWin(e, this.getHistory());
3031
- return H.debug("[session:plugin] check win", {
3085
+ return B.debug("[session:plugin] check win", {
3032
3086
  winner: t,
3033
3087
  turn: e.turn,
3034
3088
  history: e.history.length
3035
3089
  }), t;
3036
3090
  }
3037
3091
  cleanupGame() {
3038
- this.gamePlugin.cleanup && this.gamePlugin.cleanup(), H.debug("[session:plugin] cleanup game");
3092
+ this.gamePlugin.cleanup && this.gamePlugin.cleanup(), B.debug("[session:plugin] cleanup game");
3039
3093
  }
3040
3094
  buildGameState() {
3041
3095
  return {
@@ -3046,7 +3100,7 @@ var Je = class {
3046
3100
  lastStart: this.getLastStart()
3047
3101
  };
3048
3102
  }
3049
- }, Xe = class {
3103
+ }, et = class {
3050
3104
  localPeerId;
3051
3105
  remotePeerId;
3052
3106
  isConnected = !1;
@@ -3054,7 +3108,7 @@ var Je = class {
3054
3108
  mediaStateListener = () => {};
3055
3109
  constructor(e, t, n) {
3056
3110
  this.client = e, this.bus = t, this.localPeerId = n ?? null, this.remotePeerId = null, this.client.onMessage((e) => {
3057
- let t = Be(e);
3111
+ let t = We(e);
3058
3112
  !t || typeof t != "object" || !t.type || this.bus.dispatch({
3059
3113
  ...t,
3060
3114
  type: t.type,
@@ -3097,7 +3151,7 @@ var Je = class {
3097
3151
  onMediaStateChange(e) {
3098
3152
  this.mediaStateListener = e;
3099
3153
  }
3100
- }, Ze = (e, t, n) => new Xe(e, t, n), Qe = class {
3154
+ }, tt = (e, t, n) => new et(e, t, n), nt = class {
3101
3155
  state;
3102
3156
  bus;
3103
3157
  net;
@@ -3117,14 +3171,14 @@ var Je = class {
3117
3171
  getSid() {
3118
3172
  return this.sid;
3119
3173
  }
3120
- }, G = null, $e = (e, t, n, r) => {
3121
- G = new Qe(e, t, n, r);
3122
- }, K = () => {
3123
- if (!G) throw Error("[SessionContext] Not initialized. Call initializeContext() first.");
3124
- return G;
3125
- }, q = () => K().getState(), J = () => K().getBus(), et = () => K().getSid(), Y = (e) => K().getNet().send(e), tt = (e) => {
3126
- let t = q(), n = J(), r = et();
3127
- if (H.debug("[session:ready] received", {
3174
+ }, U = null, rt = (e, t, n, r) => {
3175
+ U = new nt(e, t, n, r);
3176
+ }, W = () => {
3177
+ if (!U) throw Error("[SessionContext] Not initialized. Call initializeContext() first.");
3178
+ return U;
3179
+ }, G = () => W().getState(), K = () => W().getBus(), it = () => W().getSid(), q = (e) => W().getNet().send(e), at = (e) => {
3180
+ let t = G(), n = K(), r = it();
3181
+ if (B.debug("[session:ready] received", {
3128
3182
  from: e.from,
3129
3183
  sid: e.sid,
3130
3184
  localSid: r,
@@ -3135,10 +3189,10 @@ var Je = class {
3135
3189
  console.warn("[Ready] Cannot dispatch READY from current state", { state: t.getState("local") });
3136
3190
  return;
3137
3191
  }
3138
- t.dispatch("local", "READY"), t.dispatch("remote", "REMOTE_READY"), Y({
3192
+ t.dispatch("local", "READY"), t.dispatch("remote", "REMOTE_READY"), q({
3139
3193
  type: "READY",
3140
3194
  sid: r
3141
- }), H.debug("[session:ready] local toggled", {
3195
+ }), B.debug("[session:ready] local toggled", {
3142
3196
  local: t.getState("local"),
3143
3197
  remote: t.getState("remote")
3144
3198
  });
@@ -3156,13 +3210,13 @@ var Je = class {
3156
3210
  console.warn("[Ready] Cannot dispatch READY for remote peer", { state: t.getState("remote") });
3157
3211
  return;
3158
3212
  }
3159
- t.dispatch("remote", "READY"), t.dispatch("local", "REMOTE_READY"), H.debug("[session:ready] remote toggled", {
3213
+ t.dispatch("remote", "READY"), t.dispatch("local", "REMOTE_READY"), B.debug("[session:ready] remote toggled", {
3160
3214
  local: t.getState("local"),
3161
3215
  remote: t.getState("remote")
3162
3216
  });
3163
- }, nt = (e) => e ? e === "local" ? "remote" : "local" : Math.random() < .5 ? "local" : "remote", rt = (e) => {
3164
- let t = q();
3165
- if (H.debug("[session:start] received", {
3217
+ }, ot = (e) => e ? e === "local" ? "remote" : "local" : Math.random() < .5 ? "local" : "remote", st = (e) => {
3218
+ let t = G();
3219
+ if (B.debug("[session:start] received", {
3166
3220
  from: e.from,
3167
3221
  payload: e.payload,
3168
3222
  local: t.getState("local"),
@@ -3176,11 +3230,11 @@ var Je = class {
3176
3230
  });
3177
3231
  return;
3178
3232
  }
3179
- let e = nt(t.getLastStart()), n = e === "local" ? "turn" : "remote_turn", r = e === "local" ? "remote_turn" : "turn";
3180
- t.getHistory().length > 0 && (t.clearHistory(), H.debug("[session:start] cleared previous match history")), t.setLastStart(e), t.dispatch("local", "START", n), t.dispatch("remote", "REMOTE_START", r), Y({
3233
+ let e = ot(t.getLastStart()), n = e === "local" ? "turn" : "remote_turn", r = e === "local" ? "remote_turn" : "turn";
3234
+ t.getHistory().length > 0 && (t.clearHistory(), B.debug("[session:start] cleared previous match history")), t.setLastStart(e), t.dispatch("local", "START", n), t.dispatch("remote", "REMOTE_START", r), q({
3181
3235
  type: "START",
3182
3236
  payload: { starter: e === "local" ? "sender" : "receiver" }
3183
- }), H.debug("[session:start] local started", { nextStarter: e });
3237
+ }), B.debug("[session:start] local started", { nextStarter: e });
3184
3238
  return;
3185
3239
  }
3186
3240
  let n = e.payload?.starter;
@@ -3196,10 +3250,10 @@ var Je = class {
3196
3250
  return;
3197
3251
  }
3198
3252
  let r = n === "sender" ? "remote" : "local", i = r === "local" ? "turn" : "remote_turn", a = r === "local" ? "remote_turn" : "turn";
3199
- t.getHistory().length > 0 && (t.clearHistory(), H.debug("[session:start] cleared previous match history")), t.setLastStart(r), t.dispatch("local", "REMOTE_START", i), t.dispatch("remote", "START", a), H.debug("[session:start] remote started", { starter: r });
3200
- }, it = (e) => {
3201
- let t = q(), n = e.payload;
3202
- if (H.debug("[session:move] received", {
3253
+ t.getHistory().length > 0 && (t.clearHistory(), B.debug("[session:start] cleared previous match history")), t.setLastStart(r), t.dispatch("local", "REMOTE_START", i), t.dispatch("remote", "START", a), B.debug("[session:start] remote started", { starter: r });
3254
+ }, ct = (e) => {
3255
+ let t = G(), n = e.payload;
3256
+ if (B.debug("[session:move] received", {
3203
3257
  from: e.from,
3204
3258
  payload: n,
3205
3259
  local: t.getState("local"),
@@ -3225,20 +3279,20 @@ var Je = class {
3225
3279
  turn: r,
3226
3280
  player: "local",
3227
3281
  move: n
3228
- }), Y({
3282
+ }), q({
3229
3283
  type: "MOVE",
3230
3284
  turn: r,
3231
3285
  payload: n
3232
- }), H.debug("[session:move] local move sent", {
3286
+ }), B.debug("[session:move] local move sent", {
3233
3287
  turn: r,
3234
3288
  payload: n
3235
3289
  });
3236
3290
  let i = t.checkWin();
3237
3291
  if (i) {
3238
- H.debug("[session:move] game over detected", {
3292
+ B.debug("[session:move] game over detected", {
3239
3293
  winner: i,
3240
3294
  turn: r
3241
- }), t.dispatch("local", "GAME_OVER"), t.dispatch("remote", "GAME_OVER"), t.cleanupGame(), H.debug("[session:move] local game over applied", {
3295
+ }), t.dispatch("local", "GAME_OVER"), t.dispatch("remote", "GAME_OVER"), t.cleanupGame(), B.debug("[session:move] local game over applied", {
3242
3296
  winner: i,
3243
3297
  turn: r
3244
3298
  });
@@ -3267,23 +3321,23 @@ var Je = class {
3267
3321
  });
3268
3322
  let a = t.checkWin();
3269
3323
  if (a) {
3270
- H.debug("[session:move] game over detected", {
3324
+ B.debug("[session:move] game over detected", {
3271
3325
  winner: a,
3272
3326
  turn: i
3273
- }), t.dispatch("local", "GAME_OVER"), t.dispatch("remote", "GAME_OVER"), t.cleanupGame(), H.debug("[session:move] remote game over applied", {
3327
+ }), t.dispatch("local", "GAME_OVER"), t.dispatch("remote", "GAME_OVER"), t.cleanupGame(), B.debug("[session:move] remote game over applied", {
3274
3328
  winner: a,
3275
3329
  turn: i
3276
3330
  });
3277
3331
  return;
3278
3332
  }
3279
- H.debug("[session:move] remote move applied", {
3333
+ B.debug("[session:move] remote move applied", {
3280
3334
  turn: i,
3281
3335
  payload: n
3282
3336
  });
3283
- }, at = (e) => e === "undo" || e === "restart", ot = (e) => {
3337
+ }, lt = (e) => e === "undo" || e === "restart", ut = (e) => {
3284
3338
  if (e.type !== "APPROVE" && e.type !== "REJECT") return;
3285
- let t = q(), n = e.payload, r = t.getPendingAction(), i = r ?? (e.from === "local" && e.type === "REJECT" && at(n?.action) ? n.action : null);
3286
- if (H.debug("[session:request] received", {
3339
+ let t = G(), n = e.payload, r = t.getPendingAction(), i = r ?? (e.from === "local" && e.type === "REJECT" && lt(n?.action) ? n.action : null);
3340
+ if (B.debug("[session:request] received", {
3287
3341
  type: e.type,
3288
3342
  from: e.from,
3289
3343
  action: i,
@@ -3303,13 +3357,13 @@ var Je = class {
3303
3357
  }
3304
3358
  if (e.from === "local") {
3305
3359
  if (!r && e.type === "REJECT") {
3306
- Y({
3360
+ q({
3307
3361
  type: "REJECT",
3308
3362
  payload: {
3309
3363
  action: i,
3310
3364
  reason: n?.reason ?? "rejected"
3311
3365
  }
3312
- }), H.debug("[session:request] local auto rejected", {
3366
+ }), B.debug("[session:request] local auto rejected", {
3313
3367
  action: i,
3314
3368
  reason: n?.reason
3315
3369
  });
@@ -3320,23 +3374,23 @@ var Je = class {
3320
3374
  console.warn("[Request] Cannot APPROVE from current state");
3321
3375
  return;
3322
3376
  }
3323
- t.dispatchApprove(), i === "undo" ? t.applyUndo(t.getPendingUndoCount() ?? 1) : i === "restart" && t.resetGame(), Y({
3377
+ t.dispatchApprove(), i === "undo" ? t.applyUndo(t.getPendingUndoCount() ?? 1) : i === "restart" && t.resetGame(), q({
3324
3378
  type: "APPROVE",
3325
3379
  payload: { action: i }
3326
- }), t.clearPendingStates(), H.debug("[session:request] local approved", { action: i });
3380
+ }), t.clearPendingStates(), B.debug("[session:request] local approved", { action: i });
3327
3381
  return;
3328
3382
  }
3329
3383
  if (!t.canAction("local", "REJECT")) {
3330
3384
  console.warn("[Request] Cannot REJECT from current state");
3331
3385
  return;
3332
3386
  }
3333
- t.dispatchReject(), Y({
3387
+ t.dispatchReject(), q({
3334
3388
  type: "REJECT",
3335
3389
  payload: {
3336
3390
  action: i,
3337
3391
  reason: n?.reason ?? "rejected"
3338
3392
  }
3339
- }), t.clearPendingStates(), H.debug("[session:request] local rejected", { action: i });
3393
+ }), t.clearPendingStates(), B.debug("[session:request] local rejected", { action: i });
3340
3394
  return;
3341
3395
  }
3342
3396
  if (e.type === "APPROVE") {
@@ -3344,58 +3398,58 @@ var Je = class {
3344
3398
  console.warn("[Request] Cannot APPROVE from current state (remote approved)");
3345
3399
  return;
3346
3400
  }
3347
- t.dispatchApprove(), i === "undo" ? t.applyUndo(t.getPendingUndoCount() ?? 1) : i === "restart" && t.resetGame(), t.clearPendingStates(), H.debug("[session:request] remote approved", { action: i });
3401
+ t.dispatchApprove(), i === "undo" ? t.applyUndo(t.getPendingUndoCount() ?? 1) : i === "restart" && t.resetGame(), t.clearPendingStates(), B.debug("[session:request] remote approved", { action: i });
3348
3402
  return;
3349
3403
  }
3350
3404
  if (!t.canAction("local", "REJECT")) {
3351
3405
  console.warn("[Request] Cannot REJECT from current state (remote rejected)"), t.clearPendingStates();
3352
3406
  return;
3353
3407
  }
3354
- t.dispatchReject(), t.clearPendingStates(), H.debug("[session:request] remote rejected", { action: i });
3355
- }, st = (e) => e === "local" ? "remote" : "local", ct = () => {
3356
- let e = q();
3408
+ t.dispatchReject(), t.clearPendingStates(), B.debug("[session:request] remote rejected", { action: i });
3409
+ }, dt = (e) => e === "local" ? "remote" : "local", ft = () => {
3410
+ let e = G();
3357
3411
  return e.getResumeTurn() ?? (e.getState("local") === "turn" ? "local" : "remote");
3358
- }, lt = () => {
3359
- let e = q(), t = ct();
3412
+ }, pt = () => {
3413
+ let e = G(), t = ft();
3360
3414
  return {
3361
3415
  history: e.getHistory(),
3362
3416
  lastStart: e.getLastStart(),
3363
3417
  turn: t,
3364
3418
  resumeTurn: e.getResumeTurn()
3365
3419
  };
3366
- }, ut = () => {
3367
- let e = q();
3420
+ }, mt = () => {
3421
+ let e = G();
3368
3422
  return e.getState("local") === "syncing" || e.getState("remote") === "syncing" || e.getState("remote") === "offline" || e.getResumeTurn() !== null;
3369
- }, dt = () => {
3370
- let e = q();
3423
+ }, ht = () => {
3424
+ let e = G();
3371
3425
  if (e.getState("local") !== "syncing") {
3372
- if (!e.canAction("local", "SYNC")) return H.debug("[session:sync] local cannot enter sync", { local: e.getState("local") }), !1;
3426
+ if (!e.canAction("local", "SYNC")) return B.debug("[session:sync] local cannot enter sync", { local: e.getState("local") }), !1;
3373
3427
  e.dispatch("local", "SYNC", "syncing");
3374
3428
  }
3375
3429
  if (e.getState("remote") === "offline") {
3376
- if (!e.canAction("remote", "ONLINE")) return H.debug("[session:sync] offline remote cannot enter sync", { remote: e.getState("remote") }), !1;
3430
+ if (!e.canAction("remote", "ONLINE")) return B.debug("[session:sync] offline remote cannot enter sync", { remote: e.getState("remote") }), !1;
3377
3431
  e.dispatch("remote", "ONLINE", "syncing");
3378
3432
  } else if (e.getState("remote") !== "syncing") {
3379
- if (!e.canAction("remote", "SYNC")) return H.debug("[session:sync] remote cannot enter sync", { remote: e.getState("remote") }), !1;
3433
+ if (!e.canAction("remote", "SYNC")) return B.debug("[session:sync] remote cannot enter sync", { remote: e.getState("remote") }), !1;
3380
3434
  e.dispatch("remote", "SYNC", "syncing");
3381
3435
  }
3382
3436
  return e.getState("local") === "syncing" && e.getState("remote") === "syncing";
3383
- }, X = (e, t) => {
3384
- let n = q(), r = t ? st : (e) => e;
3437
+ }, J = (e, t) => {
3438
+ let n = G(), r = t ? dt : (e) => e;
3385
3439
  e.history && e.history.length > 0 ? n.replaceHistory(e.history.map((e) => ({
3386
3440
  ...e,
3387
3441
  player: r(e.player)
3388
3442
  }))) : n.clearHistory(), e.lastStart ? n.setLastStart(r(e.lastStart)) : n.setLastStart(null);
3389
- let i = e.resumeTurn ? r(e.resumeTurn) : e.turn ? r(e.turn) : ct();
3390
- H.debug("[session:sync] state restored", {
3443
+ let i = e.resumeTurn ? r(e.resumeTurn) : e.turn ? r(e.turn) : ft();
3444
+ B.debug("[session:sync] state restored", {
3391
3445
  historyLength: n.getHistory().length,
3392
3446
  lastStart: n.getLastStart(),
3393
3447
  nextTurnPlayer: i,
3394
3448
  mapped: t
3395
- }), dt() && n.dispatchSyncComplete(i);
3396
- }, ft = (e) => {
3397
- let t = q();
3398
- if (H.debug("[session:sync] received", {
3449
+ }), ht() && n.dispatchSyncComplete(i);
3450
+ }, gt = (e) => {
3451
+ let t = G();
3452
+ if (B.debug("[session:sync] received", {
3399
3453
  type: e.type,
3400
3454
  from: e.from,
3401
3455
  payload: e.payload,
@@ -3409,37 +3463,37 @@ var Je = class {
3409
3463
  console.warn("[Sync] Cannot SYNC from current state");
3410
3464
  return;
3411
3465
  }
3412
- t.getState("local") !== "syncing" && t.dispatch("local", "SYNC", "syncing"), t.getState("remote") !== "syncing" && t.dispatch("remote", "SYNC", "syncing"), Y({
3466
+ t.getState("local") !== "syncing" && t.dispatch("local", "SYNC", "syncing"), t.getState("remote") !== "syncing" && t.dispatch("remote", "SYNC", "syncing"), q({
3413
3467
  type: "SYNC_REQUEST",
3414
3468
  from: "",
3415
3469
  payload: e.payload
3416
- }), H.debug("[session:sync] request sent");
3470
+ }), B.debug("[session:sync] request sent");
3417
3471
  return;
3418
3472
  }
3419
- let n = lt();
3420
- Y({
3473
+ let n = pt();
3474
+ q({
3421
3475
  type: "SYNC_STATE",
3422
3476
  from: "",
3423
3477
  payload: n
3424
- }), H.debug("[session:sync] state sent", n), ut() && X(n, !1);
3478
+ }), B.debug("[session:sync] state sent", n), mt() && J(n, !1);
3425
3479
  return;
3426
3480
  }
3427
3481
  if (e.type === "SYNC_STATE") {
3428
3482
  if (e.from === "local") {
3429
- let e = lt();
3430
- Y({
3483
+ let e = pt();
3484
+ q({
3431
3485
  type: "SYNC_STATE",
3432
3486
  from: "",
3433
3487
  payload: e
3434
- }), H.debug("[session:sync] state pushed", e), ut() && X(e, !1);
3488
+ }), B.debug("[session:sync] state pushed", e), mt() && J(e, !1);
3435
3489
  return;
3436
3490
  }
3437
- X(e.payload || {}, !0);
3491
+ J(e.payload || {}, !0);
3438
3492
  }
3439
- }, pt = (e) => {
3493
+ }, _t = (e) => {
3440
3494
  if (e.type !== "UNDO") return;
3441
- let t = q(), n = J();
3442
- if (H.debug("[session:undo] received", {
3495
+ let t = G(), n = K();
3496
+ if (B.debug("[session:undo] received", {
3443
3497
  from: e.from,
3444
3498
  local: t.getState("local"),
3445
3499
  remote: t.getState("remote"),
@@ -3456,10 +3510,10 @@ var Je = class {
3456
3510
  console.warn("[Undo] Not enough history to undo", { count: n });
3457
3511
  return;
3458
3512
  }
3459
- t.initializeUndoRequest(n, r), t.dispatch("local", "UNDO"), t.dispatch("remote", "REMOTE_UNDO"), Y({
3513
+ t.initializeUndoRequest(n, r), t.dispatch("local", "UNDO"), t.dispatch("remote", "REMOTE_UNDO"), q({
3460
3514
  type: "UNDO",
3461
3515
  payload: { count: n }
3462
- }), H.debug("[session:undo] local requested", { undoCount: n });
3516
+ }), B.debug("[session:undo] local requested", { undoCount: n });
3463
3517
  return;
3464
3518
  }
3465
3519
  if (t.hasPendingAction()) {
@@ -3492,14 +3546,14 @@ var Je = class {
3492
3546
  return;
3493
3547
  }
3494
3548
  let a = t.getState("local") === "turn" ? "local" : "remote";
3495
- t.initializeUndoRequest(i, a), t.dispatch("local", "REMOTE_UNDO"), t.dispatch("remote", "UNDO"), H.debug("[session:undo] remote requested", {
3549
+ t.initializeUndoRequest(i, a), t.dispatch("local", "REMOTE_UNDO"), t.dispatch("remote", "UNDO"), B.debug("[session:undo] remote requested", {
3496
3550
  count: i,
3497
3551
  resumePlayer: a
3498
3552
  });
3499
- }, mt = (e) => {
3553
+ }, vt = (e) => {
3500
3554
  if (e.type !== "RESTART") return;
3501
- let t = q(), n = J();
3502
- if (H.debug("[session:restart] received", {
3555
+ let t = G(), n = K();
3556
+ if (B.debug("[session:restart] received", {
3503
3557
  from: e.from,
3504
3558
  local: t.getState("local"),
3505
3559
  remote: t.getState("remote"),
@@ -3512,7 +3566,7 @@ var Je = class {
3512
3566
  return;
3513
3567
  }
3514
3568
  let e = t.getState("local") === "turn" ? "local" : "remote";
3515
- t.initializeRestartRequest(e), t.dispatch("local", "RESTART"), t.dispatch("remote", "REMOTE_RESTART"), Y({ type: "RESTART" }), H.debug("[session:restart] local requested", { resumePlayer: e });
3569
+ t.initializeRestartRequest(e), t.dispatch("local", "RESTART"), t.dispatch("remote", "REMOTE_RESTART"), q({ type: "RESTART" }), B.debug("[session:restart] local requested", { resumePlayer: e });
3516
3570
  return;
3517
3571
  }
3518
3572
  if (t.hasPendingAction()) {
@@ -3530,11 +3584,11 @@ var Je = class {
3530
3584
  return;
3531
3585
  }
3532
3586
  let r = t.getState("local") === "turn" ? "local" : "remote";
3533
- t.initializeRestartRequest(r), t.dispatch("local", "REMOTE_RESTART"), t.dispatch("remote", "RESTART"), H.debug("[session:restart] remote requested", { resumePlayer: r });
3534
- }, Z = (e) => {
3587
+ t.initializeRestartRequest(r), t.dispatch("local", "REMOTE_RESTART"), t.dispatch("remote", "RESTART"), B.debug("[session:restart] remote requested", { resumePlayer: r });
3588
+ }, yt = (e) => {
3535
3589
  if (e.type !== "OFFLINE" && e.type !== "ONLINE") return;
3536
- let t = q(), n = J();
3537
- if (H.debug("[session:connection] received", {
3590
+ let t = G(), n = K();
3591
+ if (B.debug("[session:connection] received", {
3538
3592
  type: e.type,
3539
3593
  from: e.from,
3540
3594
  local: t.getState("local"),
@@ -3551,21 +3605,21 @@ var Je = class {
3551
3605
  return;
3552
3606
  }
3553
3607
  let e = t.getResumeTurn() ?? (t.getState("local") === "turn" ? "local" : "remote");
3554
- t.setResumeTurn(e), t.dispatch("remote", "OFFLINE", "offline"), H.debug("[session:connection] remote offline", { currentTurn: e });
3608
+ t.setResumeTurn(e), t.dispatch("remote", "OFFLINE", "offline"), B.debug("[session:connection] remote offline", { currentTurn: e });
3555
3609
  return;
3556
3610
  }
3557
3611
  if (t.getState("remote") !== "offline") {
3558
- H.debug("[session:connection] ignored online while remote is not offline", { remote: t.getState("remote") });
3612
+ B.debug("[session:connection] ignored online while remote is not offline", { remote: t.getState("remote") });
3559
3613
  return;
3560
3614
  }
3561
3615
  if (!t.canAction("remote", "ONLINE")) {
3562
3616
  console.warn("[Offline] Cannot transition to ONLINE from current state");
3563
3617
  return;
3564
3618
  }
3565
- t.dispatch("remote", "ONLINE", "syncing"), n.emit("SYNC_STATE", void 0, "local"), H.debug("[session:connection] remote online, sync state pushed");
3566
- }, ht = (e) => {
3567
- e.register("READY", tt), e.register("START", rt), e.register("MOVE", it), e.register("UNDO", pt), e.register("RESTART", mt), e.register("SYNC_REQUEST", ft), e.register("SYNC_STATE", ft), e.register("OFFLINE", Z), e.register("ONLINE", Z), e.register("APPROVE", ot), e.register("REJECT", ot);
3568
- }, gt = class {
3619
+ t.dispatch("remote", "ONLINE", "syncing"), n.emit("SYNC_STATE", void 0, "local"), B.debug("[session:connection] remote online, sync state pushed");
3620
+ }, bt = (e) => {
3621
+ e.register("READY", at), e.register("START", st), e.register("MOVE", ct), e.register("UNDO", _t), e.register("RESTART", vt), e.register("SYNC_REQUEST", gt), e.register("SYNC_STATE", gt), e.register("OFFLINE", yt), e.register("ONLINE", yt), e.register("APPROVE", ut), e.register("REJECT", ut);
3622
+ }, xt = class {
3569
3623
  constructor(e) {
3570
3624
  this.bus = e;
3571
3625
  }
@@ -3590,15 +3644,12 @@ var Je = class {
3590
3644
  reject() {
3591
3645
  this.bus.emit("REJECT");
3592
3646
  }
3593
- rejoin(e) {
3594
- this.bus.emit("REJOIN", { sid: e });
3595
- }
3596
- }, _t = (e, t) => {
3597
- let n = new Ve(), r = new Ye(null, null), i = new Ke(), a = Ze(e, n, null), o = new Je(r, i, () => a.getIsConnected());
3598
- r.subscribeStateObserver(o), $e(r, n, a, t), ht(n);
3599
- let s = new gt(n);
3647
+ }, St = (e, t) => {
3648
+ let n = new Ge(), r = new $e(null, null), i = new Xe(), a = tt(e, n, null), o = new Qe(r, i, () => a.getIsConnected());
3649
+ r.subscribeStateObserver(o), rt(r, n, a, t), bt(n);
3650
+ let s = new xt(n);
3600
3651
  return a.onConnectionChange((e) => {
3601
- i.notifyConnectionChange(e), i.notifyStateChange(qe(r, e));
3652
+ i.notifyConnectionChange(e), i.notifyStateChange(Ze(r, e));
3602
3653
  }), {
3603
3654
  bus: n,
3604
3655
  state: r,
@@ -3607,8 +3658,9 @@ var Je = class {
3607
3658
  actions: s,
3608
3659
  send: a.send.bind(a)
3609
3660
  };
3610
- }, vt = "wss://signal.jiahengli.xyz", yt = (e) => ({
3611
- screen: "lobby",
3661
+ }, Ct = "wss://signal.jiahengli.xyz", Y = (e) => ({
3662
+ screen: "pairing",
3663
+ theme: e?.theme || "light",
3612
3664
  gameTitle: e?.gameTitle || "P2P Lockstep",
3613
3665
  sessionId: e?.sessionId || "default-session",
3614
3666
  signalUrl: e?.signalUrl || "wss://signal.jiahengli.xyz",
@@ -3634,54 +3686,70 @@ var Je = class {
3634
3686
  historyLength: 0,
3635
3687
  lastStart: null,
3636
3688
  lastError: ""
3637
- }), Q = {
3689
+ }), wt = "p2p-lockstep-theme", X = (e) => e === "light" || e === "dark", Tt = () => {
3690
+ try {
3691
+ let e = window.localStorage.getItem(wt);
3692
+ return X(e) ? e : null;
3693
+ } catch {
3694
+ return null;
3695
+ }
3696
+ }, Et = (e) => {
3697
+ try {
3698
+ window.localStorage.setItem(wt, e);
3699
+ } catch {}
3700
+ }, Z = {
3638
3701
  open: !1,
3639
3702
  title: "",
3640
3703
  description: "",
3641
3704
  confirmLabel: "Approve",
3642
3705
  cancelLabel: "Reject"
3643
- }, bt = {
3706
+ }, Dt = {
3644
3707
  open: !1,
3645
3708
  message: ""
3646
- }, xt = [
3709
+ }, Ot = [
3647
3710
  "turn",
3648
3711
  "remote_turn",
3649
3712
  "approving",
3650
3713
  "waiting_approval",
3651
3714
  "syncing"
3652
- ], St = class extends HTMLElement {
3715
+ ], kt = class extends HTMLElement {
3653
3716
  static get observedAttributes() {
3654
3717
  return [
3655
3718
  "game-title",
3656
3719
  "session-id",
3657
- "signal-url"
3720
+ "signal-url",
3721
+ "theme"
3658
3722
  ];
3659
3723
  }
3660
3724
  #e = !1;
3661
- #t = yt();
3662
- #n = Q;
3663
- #r = bt;
3725
+ #t = Y();
3726
+ #n = Z;
3727
+ #r = Dt;
3664
3728
  #i = null;
3665
3729
  #a = null;
3666
3730
  #o = null;
3667
3731
  #s = null;
3668
- #c = new Re();
3732
+ #c = new He();
3669
3733
  #l = null;
3670
3734
  #u = null;
3671
3735
  #d = null;
3672
3736
  #f = null;
3673
3737
  connectedCallback() {
3674
- this.#e || (this.#e = !0, this.#t = yt({
3738
+ if (this.#e) return;
3739
+ this.#e = !0;
3740
+ let e = X(this.getAttribute("theme")) ? this.getAttribute("theme") : "light", t = Tt() ?? e;
3741
+ this.#t = Y({
3675
3742
  gameTitle: this.getAttribute("game-title") ?? void 0,
3676
3743
  sessionId: this.getAttribute("session-id") ?? void 0,
3677
- signalUrl: this.getAttribute("signal-url") ?? void 0
3678
- }), this.render(), this.addEventListener("lockstep-register", this.#C), this.addEventListener("lockstep-connect", this.#w), this.addEventListener("lockstep-signal-change", this.#T), this.addEventListener("lockstep-target-change", this.#E), this.addEventListener("lockstep-share-detected", this.#D), this.addEventListener("lockstep-copy-share", this.#O), this.addEventListener("lockstep-ready", this.#k), this.addEventListener("lockstep-start", this.#A), this.addEventListener("lockstep-undo", this.#j), this.addEventListener("lockstep-restart", this.#M), this.addEventListener("lockstep-dialog-confirm", this.#N), this.addEventListener("lockstep-dialog-cancel", this.#P), this.#p(), this.#m());
3744
+ signalUrl: this.getAttribute("signal-url") ?? void 0,
3745
+ theme: t
3746
+ }), this.getAttribute("theme") !== t && this.setAttribute("theme", t), this.render(), this.addEventListener("lockstep-register", this.#C), this.addEventListener("lockstep-connect", this.#w), this.addEventListener("lockstep-signal-change", this.#T), this.addEventListener("lockstep-target-change", this.#E), this.addEventListener("lockstep-share-detected", this.#D), this.addEventListener("lockstep-copy-share", this.#O), this.addEventListener("lockstep-theme-change", this.#k), this.addEventListener("lockstep-ready", this.#A), this.addEventListener("lockstep-start", this.#j), this.addEventListener("lockstep-undo", this.#M), this.addEventListener("lockstep-restart", this.#N), this.addEventListener("lockstep-dialog-confirm", this.#P), this.addEventListener("lockstep-dialog-cancel", this.#F), this.#p(), this.#m();
3679
3747
  }
3680
3748
  disconnectedCallback() {
3681
- this.removeEventListener("lockstep-register", this.#C), this.removeEventListener("lockstep-connect", this.#w), this.removeEventListener("lockstep-signal-change", this.#T), this.removeEventListener("lockstep-target-change", this.#E), this.removeEventListener("lockstep-share-detected", this.#D), this.removeEventListener("lockstep-copy-share", this.#O), this.removeEventListener("lockstep-ready", this.#k), this.removeEventListener("lockstep-start", this.#A), this.removeEventListener("lockstep-undo", this.#j), this.removeEventListener("lockstep-restart", this.#M), this.removeEventListener("lockstep-dialog-confirm", this.#N), this.removeEventListener("lockstep-dialog-cancel", this.#P), this.#d &&= (window.clearTimeout(this.#d), null), this.#c.disconnect();
3749
+ this.removeEventListener("lockstep-register", this.#C), this.removeEventListener("lockstep-connect", this.#w), this.removeEventListener("lockstep-signal-change", this.#T), this.removeEventListener("lockstep-target-change", this.#E), this.removeEventListener("lockstep-share-detected", this.#D), this.removeEventListener("lockstep-copy-share", this.#O), this.removeEventListener("lockstep-theme-change", this.#k), this.removeEventListener("lockstep-ready", this.#A), this.removeEventListener("lockstep-start", this.#j), this.removeEventListener("lockstep-undo", this.#M), this.removeEventListener("lockstep-restart", this.#N), this.removeEventListener("lockstep-dialog-confirm", this.#P), this.removeEventListener("lockstep-dialog-cancel", this.#F), this.#d &&= (window.clearTimeout(this.#d), null), this.#c.disconnect();
3682
3750
  }
3683
3751
  attributeChangedCallback(e, t, n) {
3684
- this.#e && (e === "game-title" && n && this.#y({ gameTitle: n }), e === "session-id" && n && this.#y({ sessionId: n }), e === "signal-url" && n && this.#y({ signalUrl: n }));
3752
+ this.#e && (e === "game-title" && n && this.#y({ gameTitle: n }), e === "session-id" && n && this.#y({ sessionId: n }), e === "signal-url" && n && this.#y({ signalUrl: n }), e === "theme" && X(n) && this.#y({ theme: n }));
3685
3753
  }
3686
3754
  getRuntime() {
3687
3755
  return this.#u;
@@ -3691,24 +3759,24 @@ var Je = class {
3691
3759
  }
3692
3760
  render() {
3693
3761
  this.className = "block min-h-svh bg-[var(--lock-bg-deep)] text-[var(--lock-paper)]", this.innerHTML = `
3694
- <div class="relative min-h-svh overflow-hidden bg-[radial-gradient(circle_at_18%_8%,rgba(255,255,255,0.85),transparent_28%),linear-gradient(145deg,var(--lock-bg),var(--lock-bg-deep))]">
3695
- <div class="pointer-events-none absolute inset-0 hidden opacity-[0.45] sm:block bg-[linear-gradient(rgba(28,28,26,0.035)_1px,transparent_1px),linear-gradient(90deg,rgba(28,28,26,0.03)_1px,transparent_1px)] bg-[size:3.25rem_3.25rem]"></div>
3762
+ <div class="lock-app-bg relative min-h-svh overflow-hidden">
3763
+ <div class="lock-grid-bg pointer-events-none absolute inset-0 hidden opacity-[0.45] sm:block"></div>
3696
3764
 
3697
3765
  <main class="relative mx-auto flex min-h-svh max-w-7xl flex-col px-3 py-3 sm:px-6 sm:py-6 lg:px-8 lg:py-8">
3698
- <header class="lock-enter mb-5 hidden flex-wrap items-center justify-between gap-4 rounded-[1.25rem] border border-[var(--lock-border)] bg-[rgba(255,255,252,0.72)] px-4 py-3 shadow-sm backdrop-blur-xl sm:flex">
3766
+ <header class="lock-panel lock-enter mb-5 hidden flex-wrap items-center justify-between gap-4 rounded-[1.25rem] px-4 py-3 sm:flex">
3699
3767
  <div class="flex items-center gap-3">
3700
3768
  <div>
3701
- <p class="text-sm font-semibold text-[var(--lock-paper)]">P2P Lockstep</p>
3702
- <p class="text-xs text-[var(--lock-muted)]">private match console</p>
3769
+ <p class="text-sm font-semibold text-[var(--lock-paper)]">${this.#t.gameTitle}</p>
3770
+ <p class="text-xs text-[var(--lock-muted)]">direct peer match</p>
3703
3771
  </div>
3704
3772
  </div>
3705
- <div data-shell-connection-state class="rounded-full border border-[var(--lock-border)] bg-[rgba(255,255,252,0.78)] px-3 py-1 text-xs uppercase tracking-[0.16em] text-[var(--lock-muted)]">
3773
+ <div data-shell-connection-state class="lock-control rounded-full border px-3 py-1 text-xs uppercase tracking-[0.16em] text-[var(--lock-muted)]">
3706
3774
  ${this.#t.connectionState}
3707
3775
  </div>
3708
3776
  </header>
3709
3777
 
3710
3778
  <div class="flex-1 lock-enter">
3711
- <p2p-lockstep-lobby-page ${this.#t.screen === "lobby" ? "" : "hidden"}></p2p-lockstep-lobby-page>
3779
+ <p2p-lockstep-pairing-page ${this.#t.screen === "pairing" ? "" : "hidden"}></p2p-lockstep-pairing-page>
3712
3780
  <p2p-lockstep-game-page ${this.#t.screen === "game" ? "" : "hidden"}></p2p-lockstep-game-page>
3713
3781
  </div>
3714
3782
  </main>
@@ -3716,10 +3784,10 @@ var Je = class {
3716
3784
  <p2p-lockstep-confirm-dialog></p2p-lockstep-confirm-dialog>
3717
3785
  <p2p-lockstep-toast-message></p2p-lockstep-toast-message>
3718
3786
  </div>
3719
- `, this.#i = this.querySelector("p2p-lockstep-lobby-page"), this.#a = this.querySelector("p2p-lockstep-game-page"), this.#o = this.querySelector("p2p-lockstep-confirm-dialog"), this.#s = this.querySelector("p2p-lockstep-toast-message"), this.#b();
3787
+ `, this.#i = this.querySelector("p2p-lockstep-pairing-page"), this.#a = this.querySelector("p2p-lockstep-game-page"), this.#o = this.querySelector("p2p-lockstep-confirm-dialog"), this.#s = this.querySelector("p2p-lockstep-toast-message"), this.#b();
3720
3788
  }
3721
3789
  #p() {
3722
- this.#l = _t(this.#c, this.#t.sessionId), this.#u = {
3790
+ this.#l = St(this.#c, this.#t.sessionId), this.#u = {
3723
3791
  setGamePlugin: (e) => this.#l?.state.setGamePlugin(e),
3724
3792
  actions: { move: (e) => this.#l?.actions.move(e) },
3725
3793
  observer: {
@@ -3748,7 +3816,7 @@ var Je = class {
3748
3816
  });
3749
3817
  }
3750
3818
  async #m() {
3751
- let e = Ce();
3819
+ let e = we();
3752
3820
  e.signalUrl && this.#y({ signalUrl: e.signalUrl }), e.peerId && this.#y({ targetId: e.peerId }), this.#t.signalUrl && (await this.#h(this.#t.signalUrl, !0), e.peerId && await this.#g(e.peerId, !0));
3753
3821
  }
3754
3822
  async #h(e, t = !1) {
@@ -3787,7 +3855,8 @@ var Je = class {
3787
3855
  remotePeerId: n,
3788
3856
  connecting: !0,
3789
3857
  connectionState: "connecting",
3790
- screen: "game"
3858
+ screen: "game",
3859
+ lastError: ""
3791
3860
  }), this.#l?.net.setPeerIds({
3792
3861
  local: this.#t.peerId || null,
3793
3862
  remote: n
@@ -3804,7 +3873,7 @@ var Je = class {
3804
3873
  }
3805
3874
  }
3806
3875
  #_(e) {
3807
- let t = e.connected, n = e.localState === "ready", r = e.remoteState === "ready", i = t && e.localState === "idle", a = t && e.localState === "could_start", o = t && (e.localState === "turn" || e.localState === "remote_turn") && !e.pendingAction && e.history.length > 0, s = t && (e.localState === "turn" || e.localState === "remote_turn") && !e.pendingAction, c = xt.includes(e.localState) || e.localState === "offline" && e.lastStart !== null, l = e.localState === "turn" ? "me" : e.localState === "remote_turn" ? "peer" : null;
3876
+ let t = e.connected, n = e.localState === "ready", r = e.remoteState === "ready", i = t && e.localState === "idle", a = t && e.localState === "could_start", o = t && (e.localState === "turn" || e.localState === "remote_turn") && !e.pendingAction && e.history.length > 0, s = t && (e.localState === "turn" || e.localState === "remote_turn") && !e.pendingAction, c = Ot.includes(e.localState) || e.localState === "offline" && e.lastStart !== null, l = e.localState === "turn" ? "me" : e.localState === "remote_turn" ? "peer" : null;
3808
3877
  this.#y({
3809
3878
  readySelf: n,
3810
3879
  readyPeer: r,
@@ -3829,7 +3898,7 @@ var Je = class {
3829
3898
  description: e.pendingAction === "undo" ? "Your peer wants to roll the match back. Approve the undo or reject it and keep the current board." : "Your peer wants to restart the match. Approve to reset the board shell or reject to continue.",
3830
3899
  confirmLabel: "Approve",
3831
3900
  cancelLabel: "Reject"
3832
- } : this.#n.open && (this.#n = Q), this.#b();
3901
+ } : this.#n.open && (this.#n = Z), this.#b();
3833
3902
  }
3834
3903
  #v(e) {
3835
3904
  let t = this.#t.screen === "game", n = this.#c.peerState(), r = this.#c.getRemotePeerId() ?? this.#t.remotePeerId, i = this.#c.getLocalPeerId() ?? this.#t.peerId, a = e || n === "requesting" || t, o = n === "connected" ? "connected" : n === "requesting" ? "connecting" : t ? "offline" : i ? "registered" : "idle";
@@ -3839,7 +3908,7 @@ var Je = class {
3839
3908
  connected: e,
3840
3909
  connecting: n === "requesting",
3841
3910
  connectionState: o,
3842
- screen: a ? "game" : "lobby"
3911
+ screen: a ? "game" : "pairing"
3843
3912
  }), e ? this.#x("Peer connected. Game page is live.") : n === "requesting" && !t ? this.#x("Peer connection request received.") : t && i && this.#x("Peer disconnected. Waiting for reconnect.");
3844
3913
  }
3845
3914
  #y(e) {
@@ -3851,9 +3920,10 @@ var Je = class {
3851
3920
  #b() {
3852
3921
  let e = this.#i, t = this.#a, n = this.#o, r = this.#s;
3853
3922
  if (!e || !t || !n || !r) return;
3854
- e.toggleAttribute("hidden", this.#t.screen !== "lobby"), t.toggleAttribute("hidden", this.#t.screen !== "game");
3923
+ e.toggleAttribute("hidden", this.#t.screen !== "pairing"), t.toggleAttribute("hidden", this.#t.screen !== "game");
3855
3924
  let i = this.querySelector("[data-shell-connection-state]");
3856
3925
  i && (i.textContent = this.#t.connectionState), e.state = {
3926
+ theme: this.#t.theme,
3857
3927
  gameTitle: this.#t.gameTitle,
3858
3928
  signalUrl: this.#t.signalUrl,
3859
3929
  targetId: this.#t.targetId,
@@ -3863,6 +3933,7 @@ var Je = class {
3863
3933
  registering: this.#t.registering,
3864
3934
  connecting: this.#t.connecting
3865
3935
  }, t.state = {
3936
+ theme: this.#t.theme,
3866
3937
  gameTitle: this.#t.gameTitle,
3867
3938
  peerId: this.#t.peerId,
3868
3939
  remotePeerId: this.#t.remotePeerId,
@@ -3880,7 +3951,10 @@ var Je = class {
3880
3951
  localState: this.#t.localState,
3881
3952
  remoteState: this.#t.remoteState,
3882
3953
  pendingAction: this.#t.pendingAction,
3883
- sessionId: this.#t.sessionId
3954
+ sessionId: this.#t.sessionId,
3955
+ historyLength: this.#t.historyLength,
3956
+ lastStart: this.#t.lastStart,
3957
+ lastError: this.#t.lastError
3884
3958
  }, n.state = this.#n, r.state = this.#r;
3885
3959
  }
3886
3960
  #x(e) {
@@ -3888,18 +3962,18 @@ var Je = class {
3888
3962
  open: !0,
3889
3963
  message: e
3890
3964
  }, this.#b(), this.#d = window.setTimeout(() => {
3891
- this.#r = bt, this.#b(), this.#d = null;
3965
+ this.#r = Dt, this.#b(), this.#d = null;
3892
3966
  }, 2200));
3893
3967
  }
3894
3968
  async #S(e) {
3895
3969
  if (e) {
3896
3970
  try {
3897
3971
  if (navigator.clipboard?.writeText) {
3898
- await navigator.clipboard.writeText(e), this.#x("Share link copied.");
3972
+ await navigator.clipboard.writeText(e), this.#x("Copied to clipboard.");
3899
3973
  return;
3900
3974
  }
3901
3975
  } catch {}
3902
- window.prompt("Copy share link", e);
3976
+ window.prompt("Copy value", e);
3903
3977
  }
3904
3978
  }
3905
3979
  #C = (e) => {
@@ -3923,31 +3997,36 @@ var Je = class {
3923
3997
  #O = (e) => {
3924
3998
  this.#S(e.detail.value);
3925
3999
  };
3926
- #k = () => {
3927
- this.#l?.actions.ready(), this.#x(this.#t.readySelf ? "Ready state cleared." : "Ready state sent.");
4000
+ #k = (e) => {
4001
+ if (!X(e.detail.theme) || e.detail.theme === this.#t.theme) return;
4002
+ let t = e.detail.theme;
4003
+ Et(t), this.setAttribute("theme", t), this.#x(`${t === "dark" ? "Night" : "Day"} mode enabled.`);
3928
4004
  };
3929
4005
  #A = () => {
3930
- this.#l?.actions.start(), this.#x("Start request sent.");
4006
+ this.#l?.actions.ready(), this.#x(this.#t.readySelf ? "Ready state cleared." : "Ready state sent.");
3931
4007
  };
3932
4008
  #j = () => {
3933
- this.#l?.actions.undo(), this.#x("Undo request sent.");
4009
+ this.#l?.actions.start(), this.#x("Start request sent.");
3934
4010
  };
3935
4011
  #M = () => {
3936
- this.#l?.actions.restart(), this.#x("Restart request sent.");
4012
+ this.#l?.actions.undo(), this.#x("Undo request sent.");
3937
4013
  };
3938
4014
  #N = () => {
3939
- this.#l?.actions.approve(), this.#n = Q, this.#b(), this.#x("Request approved.");
4015
+ this.#l?.actions.restart(), this.#x("Restart request sent.");
3940
4016
  };
3941
4017
  #P = () => {
3942
- this.#l?.actions.reject(), this.#n = Q, this.#b(), this.#x("Request rejected.");
4018
+ this.#l?.actions.approve(), this.#n = Z, this.#b(), this.#x("Request approved.");
4019
+ };
4020
+ #F = () => {
4021
+ this.#l?.actions.reject(), this.#n = Z, this.#b(), this.#x("Request rejected.");
3943
4022
  };
3944
- }, $ = (e, t) => {
4023
+ }, Q = (e, t) => {
3945
4024
  customElements.get(e) || customElements.define(e, t);
3946
- }, Ct = () => {
3947
- $("p2p-lockstep-share-panel", k), $("p2p-lockstep-status-panel", M), $("p2p-lockstep-action-bar", d), $("p2p-lockstep-confirm-dialog", g), $("p2p-lockstep-toast-message", N), $("p2p-lockstep-board-host", P), $("p2p-lockstep-lobby-page", I), $("p2p-lockstep-game-page", L), $("p2p-lockstep-app", St);
4025
+ }, $ = () => {
4026
+ Q("p2p-lockstep-share-panel", ve), Q("p2p-lockstep-status-panel", j), Q("p2p-lockstep-action-bar", d), Q("p2p-lockstep-confirm-dialog", g), Q("p2p-lockstep-toast-message", M), Q("p2p-lockstep-board-host", N), Q("p2p-lockstep-pairing-page", F), Q("p2p-lockstep-game-page", De), Q("p2p-lockstep-app", kt);
3948
4027
  };
3949
- Ct();
4028
+ $();
3950
4029
  //#endregion
3951
- export { vt as DEFAULT_SIGNAL_URL, d as P2PLockstepActionBarElement, St as P2PLockstepAppElement, P as P2PLockstepBoardHostElement, g as P2PLockstepConfirmDialogElement, L as P2PLockstepGamePageElement, I as P2PLockstepLobbyPageElement, k as P2PLockstepSharePanelElement, M as P2PLockstepStatusPanelElement, N as P2PLockstepToastMessageElement, Ct as defineP2PLockstepUi };
4030
+ export { Ct as DEFAULT_SIGNAL_URL, d as P2PLockstepActionBarElement, kt as P2PLockstepAppElement, N as P2PLockstepBoardHostElement, g as P2PLockstepConfirmDialogElement, De as P2PLockstepGamePageElement, F as P2PLockstepPairingPageElement, ve as P2PLockstepSharePanelElement, j as P2PLockstepStatusPanelElement, M as P2PLockstepToastMessageElement, $ as defineP2PLockstepUi };
3952
4031
 
3953
4032
  //# sourceMappingURL=index.js.map