@hadoku/watchparty-ui 0.45.30 → 0.45.31

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,24 +1,24 @@
1
- import { jsx as c, jsxs as v, Fragment as ce } from "react/jsx-runtime";
2
- import Pe, { useState as R, useRef as K, useMemo as J, useCallback as k, useEffect as N, createContext as rt, useContext as Kt, useSyncExternalStore as Ln, useId as jn, useEffectEvent as Wt } from "react";
3
- import { themePrefs as ie, Icon as Un, THEMES as Fn, useHadokuThemeOptional as Hn } from "@wolffm/themes";
1
+ import { jsx as c, jsxs as v, Fragment as le } from "react/jsx-runtime";
2
+ import Ne, { useState as R, useRef as K, useMemo as J, useCallback as E, useEffect as N, createContext as Ze, useContext as Bt, useSyncExternalStore as Rn, useId as On, useEffectEvent as Gt } from "react";
3
+ import { themePrefs as ae, Icon as Dn, THEMES as Mn, useHadokuThemeOptional as Ln } from "@wolffm/themes";
4
4
  import { z as o } from "zod";
5
- import { createCdnClient as $n, kindOfType as Bn, MAX_BYTES as Gn, measureImage as qn, filesFromClipboard as Vn, filesFromDrop as Kn, CdnError as ze } from "@wolffm/cdn-client";
6
- import { ensureCosmeticsStyles as Wn, cleanWorn as Yn, decorHtml as zn, messageHtml as Xn, nameHtml as Jn, finishReveal as Zn } from "@wolffm/prefs-client/cosmetics";
5
+ import { createCdnClient as jn, kindOfType as Un, MAX_BYTES as Fn, measureImage as Hn, filesFromClipboard as $n, filesFromDrop as Bn, CdnError as We } from "@wolffm/cdn-client";
6
+ import { ensureCosmeticsStyles as Gn, cleanWorn as qn, readPictureColour as Vn, onPictureColour as Kn, pictureColour as Wn, decorHtml as Yn, messageHtml as zn, nameHtml as Xn, finishReveal as Jn } from "@wolffm/prefs-client/cosmetics";
7
7
  import { create as Qn } from "zustand";
8
- import { createPrefsClient as er, getDeviceId as tr, DEVICE_ID_KEY as nr } from "@wolffm/prefs-client";
9
- import { io as rr } from "socket.io-client";
10
- import { createAvatarClient as or, AvatarError as _t } from "@wolffm/prefs-client/avatar";
11
- import { resolveIdentityReassert as ar } from "@wolffm/rooms-protocol";
12
- import { createPortal as ir } from "react-dom";
13
- import { useCatalogueSearch as sr } from "@wolffm/cdn-client/react";
14
- const Yt = "https://cdn.hadoku.me", zt = /^[0-9a-f]{64}\.(?:png|jpe?g|gif|webp|avif)$/;
15
- function ot(e) {
16
- return typeof e == "string" && zt.test(e);
17
- }
18
- const at = 8080, Xt = 5173, lr = "/watchparty/ws", Jt = 500, cr = 1e3, Y = 4, Zt = typeof process < "u" && process.env ? process.env : {};
19
- Zt.PRODUCTION_UI_URL;
20
- Zt.PRODUCTION_SERVER_URL;
21
- const Ie = o.enum(["S", "A", "B", "C", "D", "F"]), xt = 2e4, dr = 300;
8
+ import { createPrefsClient as Zn, getDeviceId as er, DEVICE_ID_KEY as tr } from "@wolffm/prefs-client";
9
+ import { io as nr } from "socket.io-client";
10
+ import { createAvatarClient as rr, AvatarError as bt } from "@wolffm/prefs-client/avatar";
11
+ import { resolveIdentityReassert as or } from "@wolffm/rooms-protocol";
12
+ import { createPortal as ar } from "react-dom";
13
+ import { useCatalogueSearch as ir } from "@wolffm/cdn-client/react";
14
+ const qt = "https://cdn.hadoku.me", Vt = /^[0-9a-f]{64}\.(?:png|jpe?g|gif|webp|avif)$/;
15
+ function et(e) {
16
+ return typeof e == "string" && Vt.test(e);
17
+ }
18
+ const tt = 8080, Kt = 5173, sr = "/watchparty/ws", Wt = 500, lr = 1e3, Y = 4, Yt = typeof process < "u" && process.env ? process.env : {};
19
+ Yt.PRODUCTION_UI_URL;
20
+ Yt.PRODUCTION_SERVER_URL;
21
+ const xe = o.enum(["S", "A", "B", "C", "D", "F"]), vt = 2e4, cr = 300;
22
22
  o.object({
23
23
  name: o.string().min(1).max(32).optional(),
24
24
  sprite: o.string().min(1).max(32).optional(),
@@ -27,7 +27,7 @@ o.object({
27
27
  * resolves it from prefs-api by registry userId, never from the client. */
28
28
  avatar: o.literal(!0).optional()
29
29
  });
30
- const _ = {
30
+ const w = {
31
31
  JOIN: "join",
32
32
  SNAPSHOT: "snapshot",
33
33
  CONTROL_ACK: "control_ack",
@@ -45,7 +45,7 @@ const _ = {
45
45
  // 'ready_state' here = playback-readiness gate (distinct from READY_EVENTS.STATE = "ready check" UX feature)
46
46
  READY_STATE: "ready_state",
47
47
  ERROR: "error"
48
- }, ur = o.enum(["play", "pause", "seek", "load", "home"]), mr = o.object({
48
+ }, dr = o.enum(["play", "pause", "seek", "load", "home"]), ur = o.object({
49
49
  framed: o.boolean(),
50
50
  depth: o.number().int().nonnegative().max(10)
51
51
  });
@@ -53,7 +53,7 @@ o.object({
53
53
  room_key: o.string(),
54
54
  name: o.string().min(1).max(32).optional(),
55
55
  sprite: o.string().min(1).max(32).optional(),
56
- embed: mr.optional(),
56
+ embed: ur.optional(),
57
57
  /** Which media-delivery path this client resolved to ('range' | 'fragment').
58
58
  * Optional so older clients still validate. Reported so a party's logs can be split by
59
59
  * arm — without it an A/B rollout is unmeasurable, exactly as entry path was before
@@ -101,13 +101,13 @@ o.object({
101
101
  });
102
102
  o.object({
103
103
  client_seq: o.number().int().positive(),
104
- kind: ur,
104
+ kind: dr,
105
105
  to_ms: o.number().int().nonnegative().optional(),
106
106
  media_id: o.string().optional()
107
107
  // leader_id removed - not needed since set_leader control was removed
108
108
  });
109
- const Qt = o.object({
110
- key: o.string().regex(zt, "not a CDN image key"),
109
+ const zt = o.object({
110
+ key: o.string().regex(Vt, "not a CDN image key"),
111
111
  /**
112
112
  * Intrinsic pixels, or **0 meaning "unknown"**.
113
113
  *
@@ -120,8 +120,8 @@ const Qt = o.object({
120
120
  * text went with it, with nothing said. Widening is backward compatible —
121
121
  * every message already in history carries positive dimensions.
122
122
  */
123
- w: o.number().int().nonnegative().max(xt),
124
- h: o.number().int().nonnegative().max(xt),
123
+ w: o.number().int().nonnegative().max(vt),
124
+ h: o.number().int().nonnegative().max(vt),
125
125
  /**
126
126
  * Human-readable description, rendered as the `alt` text.
127
127
  *
@@ -135,14 +135,14 @@ const Qt = o.object({
135
135
  * value only, never as markup. Bounded so one message cannot carry a
136
136
  * paragraph; the library's own titles run well under this.
137
137
  */
138
- title: o.string().max(dr).optional()
138
+ title: o.string().max(cr).optional()
139
139
  });
140
140
  o.object({
141
- text: o.string().max(Jt),
141
+ text: o.string().max(Wt),
142
142
  style: o.string().max(64).optional(),
143
- images: o.array(Qt).max(Y).optional()
143
+ images: o.array(zt).max(Y).optional()
144
144
  }).refine((e) => e.text.length > 0 || (e.images?.length ?? 0) > 0, { message: "message must carry text or at least one image" });
145
- const fr = o.enum(["join", "leave", "media_change", "identity_change", "recap"]);
145
+ const mr = o.enum(["join", "leave", "media_change", "identity_change", "recap"]);
146
146
  o.object({
147
147
  id: o.string(),
148
148
  client_id: o.string(),
@@ -155,11 +155,11 @@ o.object({
155
155
  ts: o.number(),
156
156
  // Optional so a client on an older bundle still validates a message that
157
157
  // has none, and so system messages (which never carry images) stay unchanged.
158
- images: o.array(Qt).max(Y).optional(),
158
+ images: o.array(zt).max(Y).optional(),
159
159
  isSystem: o.boolean().optional(),
160
- systemType: fr.optional()
160
+ systemType: mr.optional()
161
161
  });
162
- const pr = o.object({
162
+ const fr = o.object({
163
163
  avg_download_rate_bps: o.number().nonnegative(),
164
164
  buffered_ahead_ms: o.number().nonnegative(),
165
165
  rtt_ms: o.number().nonnegative(),
@@ -201,7 +201,7 @@ const pr = o.object({
201
201
  * socket shows here as a growing number while everything else looks fine. */
202
202
  pong_age_ms: o.number().int().nonnegative().optional(),
203
203
  reported_at: o.number().int().nonnegative()
204
- }), hr = pr.extend({
204
+ }), pr = fr.extend({
205
205
  client_id: o.string(),
206
206
  name: o.string(),
207
207
  sprite_id: o.string().nullable(),
@@ -212,10 +212,10 @@ const pr = o.object({
212
212
  stale_ms: o.number().int().nonnegative().optional()
213
213
  });
214
214
  o.object({
215
- clients: o.array(hr),
215
+ clients: o.array(pr),
216
216
  server_ts: o.number().int().nonnegative()
217
217
  });
218
- const gr = o.object({
218
+ const hr = o.object({
219
219
  client_id: o.string(),
220
220
  sprite_id: o.string().nullable(),
221
221
  name: o.string(),
@@ -233,13 +233,13 @@ const gr = o.object({
233
233
  video_ready_state: o.number().int().default(-1)
234
234
  });
235
235
  o.object({
236
- clients: o.array(gr),
236
+ clients: o.array(hr),
237
237
  server_ts: o.number().int().nonnegative()
238
238
  });
239
239
  o.object({
240
240
  media_id: o.string()
241
241
  });
242
- const it = o.enum(["super_upvote", "upvote", "mid", "downvote"]), yr = o.object({
242
+ const nt = o.enum(["super_upvote", "upvote", "mid", "downvote"]), gr = o.object({
243
243
  mediaId: o.string(),
244
244
  displayName: o.string(),
245
245
  // Enrichment fields — present for flat-playlist ingest output, absent for
@@ -250,11 +250,11 @@ const it = o.enum(["super_upvote", "upvote", "mid", "downvote"]), yr = o.object(
250
250
  durationMs: o.number().optional(),
251
251
  uploadDate: o.string().optional()
252
252
  // YouTube upload date 'YYYY-MM-DD'; drives playlist order
253
- }), br = o.enum(["basic", "vote"]), en = o.object({
253
+ }), yr = o.enum(["basic", "vote"]), Xt = o.object({
254
254
  id: o.string(),
255
255
  name: o.string(),
256
- type: br.default("vote"),
257
- videos: o.array(yr),
256
+ type: yr.default("vote"),
257
+ videos: o.array(gr),
258
258
  cover: o.string().optional()
259
259
  // media-relative path to the playlist cover image
260
260
  });
@@ -263,28 +263,28 @@ o.object({ index: o.number().int().min(0) });
263
263
  o.object({
264
264
  playlistId: o.string(),
265
265
  mediaId: o.string(),
266
- vote: it
266
+ vote: nt
267
267
  });
268
268
  o.object({ voterKey: o.string().min(1).max(128) });
269
269
  o.object({ playlistId: o.string(), mediaIds: o.array(o.string()) });
270
270
  o.object({
271
- playlist: en.nullable(),
271
+ playlist: Xt.nullable(),
272
272
  activeIndex: o.number().int().nullable(),
273
- myVotes: o.record(o.string(), it)
273
+ myVotes: o.record(o.string(), nt)
274
274
  // mediaId -> VoteValue
275
275
  });
276
- const vr = o.object({
276
+ const br = o.object({
277
277
  clientId: o.string(),
278
278
  name: o.string(),
279
279
  votedCount: o.number().int().nonnegative(),
280
280
  totalVideos: o.number().int().nonnegative()
281
281
  });
282
282
  o.object({
283
- progress: o.array(vr)
283
+ progress: o.array(br)
284
284
  });
285
285
  o.object({
286
- playlist: en,
287
- votes: o.record(o.string(), o.record(o.string(), it)),
286
+ playlist: Xt,
287
+ votes: o.record(o.string(), o.record(o.string(), nt)),
288
288
  // votes[clientId][mediaId]
289
289
  names: o.record(o.string(), o.string()),
290
290
  // clientId -> display name
@@ -299,37 +299,37 @@ o.object({
299
299
  * reveal is closed ignores it, rather than having the popup reappear. */
300
300
  update: o.boolean().optional()
301
301
  });
302
- const be = {
302
+ const ye = {
303
303
  STATE: "playlist_state",
304
304
  VOTE_PROGRESS: "playlist_vote_progress",
305
305
  RESULTS: "playlist_results",
306
306
  /** Server -> the removed voter: forget the ballot you hold in localStorage. */
307
307
  VOTES_CLEARED: "playlist_votes_cleared"
308
- }, tn = o.object({
308
+ }, Jt = o.object({
309
309
  id: o.string(),
310
310
  displayName: o.string(),
311
311
  thumbnail: o.string().optional()
312
312
  });
313
313
  o.object({
314
- items: o.array(tn)
314
+ items: o.array(Jt)
315
315
  });
316
- const nn = o.partialRecord(Ie, o.array(o.string()));
317
- o.object({ board: nn });
318
- const Sr = o.object({
316
+ const Qt = o.partialRecord(xe, o.array(o.string()));
317
+ o.object({ board: Qt });
318
+ const vr = o.object({
319
319
  mediaId: o.string(),
320
- tier: Ie,
321
- absoluteTier: Ie,
320
+ tier: xe,
321
+ absoluteTier: xe,
322
322
  /** Tier level + within-row position. Integer part is the tier. */
323
323
  score: o.number(),
324
324
  /** The consensus mean that decided the tier. Never the displayed number. */
325
325
  placementScore: o.number(),
326
326
  subRankOffset: o.number(),
327
- votes: o.record(o.string(), Ie)
327
+ votes: o.record(o.string(), xe)
328
328
  // opaque voterId -> the letter they gave
329
329
  });
330
330
  o.object({
331
- items: o.array(tn),
332
- placed: o.array(Sr),
331
+ items: o.array(Jt),
332
+ placed: o.array(vr),
333
333
  unrated: o.array(o.string()),
334
334
  spread: o.number(),
335
335
  nudged: o.boolean(),
@@ -339,9 +339,9 @@ o.object({
339
339
  * browser on a newer bundle still reads an older server's board. */
340
340
  pictures: o.record(o.string(), o.string()).optional(),
341
341
  voterCount: o.number().int().nonnegative(),
342
- myBoard: nn
342
+ myBoard: Qt
343
343
  });
344
- const wr = {
344
+ const Sr = {
345
345
  /** Broadcast to EVERY connected socket when anyone saves. Carries no board —
346
346
  * it is a "re-fetch" ping, because the shared result is identical for all
347
347
  * viewers but `myBoard` is not, and one payload cannot serve both. */
@@ -357,7 +357,7 @@ o.object({
357
357
  const _r = {
358
358
  STATE: "ready_check_state"
359
359
  // distinct from buffer-readiness 'ready_state'
360
- }, rn = {
360
+ }, Zt = {
361
361
  ACTIVE: "game_active",
362
362
  // server -> room (the open game id; null = none)
363
363
  SYNC: "game_sync"
@@ -369,7 +369,7 @@ o.object({
369
369
  o.object({
370
370
  gameId: o.string().nullable()
371
371
  });
372
- const xr = [
372
+ const wr = [
373
373
  {
374
374
  id: "fantasy",
375
375
  characters: [
@@ -413,37 +413,37 @@ const xr = [
413
413
  { id: "mentor", color: "#e1e0dc" }
414
414
  ]
415
415
  }
416
- ], st = xr.flatMap((e) => e.characters), je = st.map((e) => e.id), Ir = Object.fromEntries(st.map((e) => [e.id, e.color])), Cr = Object.fromEntries(st.map((e) => [e.id, "rev" in e ? e.rev : 1]));
417
- function Tr(e) {
416
+ ], rt = wr.flatMap((e) => e.characters), Le = rt.map((e) => e.id), xr = Object.fromEntries(rt.map((e) => [e.id, e.color])), Cr = Object.fromEntries(rt.map((e) => [e.id, "rev" in e ? e.rev : 1]));
417
+ function Ir(e) {
418
418
  const t = Cr[e];
419
419
  return `/media/sprites/square_${e}.png${t > 1 ? `?v=${t}` : ""}`;
420
420
  }
421
- function lt(e) {
422
- return !!e && je.includes(e);
421
+ function ot(e) {
422
+ return !!e && Le.includes(e);
423
423
  }
424
- const Ar = 5e3, on = { mode: "off", percent: 0 }, Er = ["off", "on", "ab"];
424
+ const Tr = 5e3, en = { mode: "off", percent: 0 }, Ar = ["off", "on", "ab"];
425
425
  function kr(e) {
426
- return typeof e == "string" && Er.includes(e);
426
+ return typeof e == "string" && Ar.includes(e);
427
427
  }
428
- function Nr(e) {
429
- const t = e && typeof e == "object" ? e : {}, n = kr(t.mode) ? t.mode : on.mode, r = Number(t.percent), a = Number.isFinite(r) ? Math.min(100, Math.max(0, Math.round(r))) : 0;
428
+ function Er(e) {
429
+ const t = e && typeof e == "object" ? e : {}, n = kr(t.mode) ? t.mode : en.mode, r = Number(t.percent), a = Number.isFinite(r) ? Math.min(100, Math.max(0, Math.round(r))) : 0;
430
430
  return { mode: n, percent: a };
431
431
  }
432
- function Pr(e) {
432
+ function Nr(e) {
433
433
  let t = 2166136261;
434
434
  for (let n = 0; n < e.length; n++)
435
435
  t ^= e.charCodeAt(n), t = Math.imul(t, 16777619) >>> 0;
436
436
  return t >>> 0;
437
437
  }
438
- function Rr(e, t, n) {
438
+ function Pr(e, t, n) {
439
439
  if (n === !0)
440
440
  return "fragment";
441
441
  if (n === !1)
442
442
  return "range";
443
- const r = Nr(e);
444
- return r.mode === "on" ? "fragment" : r.mode === "off" || r.percent <= 0 ? "range" : r.percent >= 100 || t && Pr(t) % 100 < r.percent ? "fragment" : "range";
443
+ const r = Er(e);
444
+ return r.mode === "on" ? "fragment" : r.mode === "off" || r.percent <= 0 ? "range" : r.percent >= 100 || t && Nr(t) % 100 < r.percent ? "fragment" : "range";
445
445
  }
446
- const an = o.enum(["url", "magnet", "upload"]), Or = o.enum([
446
+ const tn = o.enum(["url", "magnet", "upload"]), Rr = o.enum([
447
447
  "pending",
448
448
  "approved",
449
449
  "fetching",
@@ -451,7 +451,7 @@ const an = o.enum(["url", "magnet", "upload"]), Or = o.enum([
451
451
  "ready",
452
452
  "rejected",
453
453
  "failed"
454
- ]), It = {
454
+ ]), St = {
455
455
  pending: ["approved", "rejected"],
456
456
  approved: ["fetching", "rejected", "failed"],
457
457
  fetching: ["ingesting", "failed"],
@@ -460,12 +460,12 @@ const an = o.enum(["url", "magnet", "upload"]), Or = o.enum([
460
460
  rejected: [],
461
461
  failed: ["approved"]
462
462
  };
463
- Object.keys(It).filter((e) => It[e].length === 0);
464
- const Dr = o.object({
463
+ Object.keys(St).filter((e) => St[e].length === 0);
464
+ const Or = o.object({
465
465
  id: o.string().min(1),
466
466
  /** Stable userId from whoami. Never the raw `X-User-Key`. */
467
467
  ownerUserId: o.string().min(1),
468
- kind: an,
468
+ kind: tn,
469
469
  /** The magnet URI, the https URL, or the filetransfer binding id. */
470
470
  source: o.string().min(1),
471
471
  title: o.string().optional(),
@@ -480,7 +480,7 @@ const Dr = o.object({
480
480
  * misroute the copy.
481
481
  */
482
482
  series: o.string().optional(),
483
- state: Or,
483
+ state: Rr,
484
484
  createdAt: o.number().int().nonnegative(),
485
485
  updatedAt: o.number().int().nonnegative(),
486
486
  /** Why it failed, or why an operator rejected it. */
@@ -488,19 +488,19 @@ const Dr = o.object({
488
488
  /** Size once known. 0 means "known to be empty"; absent means "not yet known" —
489
489
  * the same distinction `chatImages` draws for image dimensions. */
490
490
  bytes: o.number().int().nonnegative().optional()
491
- }), Mr = 4096, sn = 300, Lr = 100;
491
+ }), Dr = 4096, nn = 300, Mr = 100;
492
492
  o.object({
493
- kind: an,
494
- source: o.string().min(1).max(Mr),
495
- title: o.string().min(1).max(sn).optional(),
493
+ kind: tn,
494
+ source: o.string().min(1).max(Dr),
495
+ title: o.string().min(1).max(nn).optional(),
496
496
  /** Required for `kind: 'magnet'` by `checkSource`; ignored for `url`/`upload`. */
497
- series: o.string().min(1).max(Lr).optional()
497
+ series: o.string().min(1).max(Mr).optional()
498
498
  });
499
499
  o.object({
500
- reason: o.string().min(1).max(sn).optional()
500
+ reason: o.string().min(1).max(nn).optional()
501
501
  });
502
502
  o.object({
503
- submissions: o.array(Dr)
503
+ submissions: o.array(Or)
504
504
  });
505
505
  o.object({
506
506
  error: o.literal("submissions/quota_exceeded"),
@@ -509,26 +509,26 @@ o.object({
509
509
  /** The cap that was applied, from the server's config. */
510
510
  capBytes: o.number().int().nonnegative()
511
511
  });
512
- const jr = /^[a-z0-9][a-z0-9-]{0,31}$/, Ct = "https://game-catalog.invalid";
513
- function Ur(e) {
512
+ const Lr = /^[a-z0-9][a-z0-9-]{0,31}$/, _t = "https://game-catalog.invalid";
513
+ function jr(e) {
514
514
  if (!e.startsWith("/") || e.startsWith("//") || /[\\\s]/.test(e) || [...e].some((t) => t.charCodeAt(0) < 32 || t.charCodeAt(0) === 127))
515
515
  return !1;
516
516
  try {
517
- return new URL(e, Ct).origin === Ct;
517
+ return new URL(e, _t).origin === _t;
518
518
  } catch {
519
519
  return !1;
520
520
  }
521
521
  }
522
- const ln = o.string().min(2).max(512).refine(Ur, {
522
+ const rn = o.string().min(2).max(512).refine(jr, {
523
523
  message: "must be a root-relative path on the page origin (e.g. /cardtable/embed/x.js)"
524
- }), Fr = {
525
- id: o.string().regex(jr),
524
+ }), Ur = {
525
+ id: o.string().regex(Lr),
526
526
  name: o.string().min(1).max(64),
527
- cover: ln.optional()
528
- }, Hr = o.object({ ...Fr, kind: o.literal("module"), url: ln }).strict();
529
- o.array(Hr).max(32).refine((e) => new Set(e.map((t) => t.id)).size === e.length, { message: "game ids must be unique" });
530
- const ct = o.enum(["anilist", "tmdb"]), $r = o.object({
531
- source: ct,
527
+ cover: rn.optional()
528
+ }, Fr = o.object({ ...Ur, kind: o.literal("module"), url: rn }).strict();
529
+ o.array(Fr).max(32).refine((e) => new Set(e.map((t) => t.id)).size === e.length, { message: "game ids must be unique" });
530
+ const at = o.enum(["anilist", "tmdb"]), Hr = o.object({
531
+ source: at,
532
532
  /** The provider's own id, as a string (AniList and TMDB both use integers). */
533
533
  id: o.string(),
534
534
  title: o.string(),
@@ -549,11 +549,11 @@ const ct = o.enum(["anilist", "tmdb"]), $r = o.object({
549
549
  addable: o.boolean()
550
550
  });
551
551
  o.object({
552
- results: o.array($r),
552
+ results: o.array(Hr),
553
553
  /** Providers that answered. TMDB is absent when no token is configured. */
554
- sources: o.array(ct)
554
+ sources: o.array(at)
555
555
  });
556
- const Br = o.object({
556
+ const $r = o.object({
557
557
  id: o.string(),
558
558
  url: o.string(),
559
559
  title: o.string(),
@@ -561,30 +561,30 @@ const Br = o.object({
561
561
  durationS: o.number().nullable(),
562
562
  thumb: o.string().nullable()
563
563
  });
564
- o.object({ results: o.array(Br) });
564
+ o.object({ results: o.array($r) });
565
565
  o.object({
566
- source: ct,
566
+ source: at,
567
567
  id: o.string().regex(/^\d{1,12}$/)
568
568
  });
569
569
  o.object({ series: o.string(), title: o.string() });
570
- let ve = null, cn = Yt;
571
- function Gr(e) {
572
- e.cdnBase && (cn = e.cdnBase);
570
+ let be = null, on = qt;
571
+ function Br(e) {
572
+ e.cdnBase && (on = e.cdnBase);
573
573
  }
574
- function dn() {
575
- return cn.replace(/\/+$/, "");
574
+ function an() {
575
+ return on.replace(/\/+$/, "");
576
576
  }
577
- function Ue() {
578
- const e = dn();
579
- return (!ve || ve.base !== e) && (ve = { base: e, client: $n({ cdnBase: e }) }), ve.client;
577
+ function je() {
578
+ const e = an();
579
+ return (!be || be.base !== e) && (be = { base: e, client: jn({ cdnBase: e }) }), be.client;
580
580
  }
581
- function Re(e) {
582
- return !ot(e) || !dn() ? null : Ue().urlFor(e);
581
+ function Pe(e) {
582
+ return !et(e) || !an() ? null : je().urlFor(e);
583
583
  }
584
- function qr(e) {
584
+ function Gr(e) {
585
585
  return e.kind === "file";
586
586
  }
587
- class un extends Error {
587
+ class sn extends Error {
588
588
  constructor(t) {
589
589
  super(t), this.name = "ChatImageUploadError";
590
590
  }
@@ -609,88 +609,88 @@ function Ce(e) {
609
609
  return "Image upload failed";
610
610
  }
611
611
  }
612
+ function qr(e) {
613
+ return e instanceof We ? Ce(e.reason) : e instanceof sn ? e.message : "Image upload failed";
614
+ }
612
615
  function Vr(e) {
613
- return e instanceof ze ? Ce(e.reason) : e instanceof un ? e.message : "Image upload failed";
616
+ const t = e.type.toLowerCase().split(";")[0].trim();
617
+ return t && Un(t) !== "image" ? Ce("unsupported-type") : e.size > Fn.image ? Ce("too-large") : e.size === 0 ? Ce("invalid") : null;
614
618
  }
615
619
  function Kr(e) {
616
- const t = e.type.toLowerCase().split(";")[0].trim();
617
- return t && Bn(t) !== "image" ? Ce("unsupported-type") : e.size > Gn.image ? Ce("too-large") : e.size === 0 ? Ce("invalid") : null;
620
+ return $n(e);
618
621
  }
619
622
  function Wr(e) {
620
- return Vn(e);
623
+ return Bn(e);
621
624
  }
622
- function Yr(e) {
623
- return Kn(e);
624
- }
625
- async function zr(e) {
626
- const t = await qn(e);
625
+ async function Yr(e) {
626
+ const t = await Hn(e);
627
627
  return { w: t?.width ?? 0, h: t?.height ?? 0 };
628
628
  }
629
- async function Xr(e, t = {}) {
630
- const n = await Ue().upload(e, { signal: t.signal });
631
- if (!ot(n.key))
632
- throw new un("Image upload returned an unusable key");
629
+ async function zr(e, t = {}) {
630
+ const n = await je().upload(e, { signal: t.signal });
631
+ if (!et(n.key))
632
+ throw new sn("Image upload returned an unusable key");
633
633
  return { key: n.key, deduplicated: n.deduplicated === !0 };
634
634
  }
635
- async function Jr(e, t = {}) {
635
+ async function Xr(e, t = {}) {
636
636
  const n = [];
637
637
  for (const r of e) {
638
638
  if (r.kind === "remote") {
639
639
  n.push({ key: r.key, w: r.w, h: r.h, ...r.title ? { title: r.title } : {} });
640
640
  continue;
641
641
  }
642
- const { key: a } = await Xr(r.file, t);
642
+ const { key: a } = await zr(r.file, t);
643
643
  n.push({ key: a, w: r.w, h: r.h });
644
644
  }
645
645
  return n;
646
646
  }
647
- function Zr(e) {
647
+ function Jr(e) {
648
648
  return {
649
649
  error: e instanceof Error ? e.message : String(e),
650
650
  name: e instanceof Error ? e.name : typeof e,
651
- reason: e instanceof ze ? e.reason : void 0,
652
- status: e instanceof ze ? e.status : void 0
651
+ reason: e instanceof We ? e.reason : void 0,
652
+ status: e instanceof We ? e.status : void 0
653
653
  };
654
654
  }
655
- const Xe = 240, X = 8, Qr = 28, mn = 240;
656
- function eo(e, t, n) {
657
- let r = t.left - Xe - X;
658
- r < X && (r = t.right + X), r = Math.min(r, n.width - Xe - X), r = Math.max(X, r);
659
- const a = mn + Qr;
655
+ const Ye = 240, X = 8, Qr = 28, ln = 240;
656
+ function Zr(e, t, n) {
657
+ let r = t.left - Ye - X;
658
+ r < X && (r = t.right + X), r = Math.min(r, n.width - Ye - X), r = Math.max(X, r);
659
+ const a = ln + Qr;
660
660
  let i = e.top + e.height / 2 - a / 2;
661
661
  return i = Math.min(i, n.height - a - X), i = Math.max(X, i), { left: r, top: i };
662
662
  }
663
- const fn = "/dataplatform/api/memes", to = 120;
664
- function no({ onClose: e, onPick: t, onUnavailable: n }) {
665
- const [r, a] = R(""), i = K(null), s = K(null), l = Ue(), { items: m, loading: h, error: u, hasMore: D, loadMore: M } = sr(
663
+ const cn = "/dataplatform/api/memes", eo = 120;
664
+ function to({ onClose: e, onPick: t, onUnavailable: n }) {
665
+ const [r, a] = R(""), i = K(null), s = K(null), l = je(), { items: f, loading: h, error: u, hasMore: j, loadMore: D } = ir(
666
666
  l,
667
- fn,
667
+ cn,
668
668
  r.trim()
669
- ), L = u?.reason ?? null, C = J(() => {
669
+ ), M = u?.reason ?? null, I = J(() => {
670
670
  const x = /* @__PURE__ */ new Set();
671
- return m.filter((P) => x.has(P.key) ? !1 : (x.add(P.key), !0));
672
- }, [m]), [p, S] = R(null), b = K(null), I = k(() => {
671
+ return f.filter((P) => x.has(P.key) ? !1 : (x.add(P.key), !0));
672
+ }, [f]), [p, S] = R(null), b = K(null), C = E(() => {
673
673
  b.current !== null && (window.clearTimeout(b.current), b.current = null);
674
- }, []), g = k(() => {
675
- I(), S(null);
676
- }, [I]), E = typeof window < "u" && typeof window.matchMedia == "function" && window.matchMedia("(hover: hover)").matches, O = k(
674
+ }, []), g = E(() => {
675
+ C(), S(null);
676
+ }, [C]), k = typeof window < "u" && typeof window.matchMedia == "function" && window.matchMedia("(hover: hover)").matches, O = E(
677
677
  (x, P, T = !1) => {
678
- const he = i.current;
679
- if (!he) return;
680
- const ge = () => S({
678
+ const pe = i.current;
679
+ if (!pe) return;
680
+ const he = () => S({
681
681
  item: x,
682
- ...eo(P.getBoundingClientRect(), he.getBoundingClientRect(), {
682
+ ...Zr(P.getBoundingClientRect(), pe.getBoundingClientRect(), {
683
683
  width: window.innerWidth,
684
684
  height: window.innerHeight
685
685
  })
686
686
  });
687
- I(), T ? ge() : b.current = window.setTimeout(ge, to);
687
+ C(), T ? he() : b.current = window.setTimeout(he, eo);
688
688
  },
689
- [I]
689
+ [C]
690
690
  );
691
- N(() => () => I(), [I]), N(() => {
692
- L === "unavailable" && n?.();
693
- }, [L, n]), N(() => {
691
+ N(() => () => C(), [C]), N(() => {
692
+ M === "unavailable" && n?.();
693
+ }, [M, n]), N(() => {
694
694
  s.current?.focus();
695
695
  }, []), N(() => {
696
696
  const x = (T) => {
@@ -702,9 +702,9 @@ function no({ onClose: e, onPick: t, onUnavailable: n }) {
702
702
  document.removeEventListener("keydown", x), document.removeEventListener("mousedown", P);
703
703
  };
704
704
  }, [e]);
705
- const j = k((x) => {
705
+ const L = E((x) => {
706
706
  t(x), e();
707
- }, [t, e]), F = !h && !u && C.length === 0;
707
+ }, [t, e]), F = !h && !u && I.length === 0;
708
708
  return /* @__PURE__ */ v(
709
709
  "div",
710
710
  {
@@ -739,22 +739,22 @@ function no({ onClose: e, onPick: t, onUnavailable: n }) {
739
739
  {
740
740
  className: "m-2 p-2 text-center text-sm bg-danger-bg text-on-danger-bg rounded",
741
741
  role: "alert",
742
- "data-reason": L,
743
- children: L === "unauthenticated" ? "Sign in to browse memes" : L === "forbidden" ? "Your account can't browse the meme library" : "Meme library is unavailable"
742
+ "data-reason": M,
743
+ children: M === "unauthenticated" ? "Sign in to browse memes" : M === "forbidden" ? "Your account can't browse the meme library" : "Meme library is unavailable"
744
744
  }
745
745
  ),
746
746
  F && /* @__PURE__ */ c("p", { className: "p-4 text-center text-sm text-text-secondary", children: r.trim() ? `No memes match "${r.trim()}"` : "The meme library is empty" }),
747
- C.length > 0 && /* @__PURE__ */ c("div", { className: "grid grid-cols-3 gap-1.5 sm:grid-cols-4", children: C.map((x) => {
748
- const P = Re(x.key);
747
+ I.length > 0 && /* @__PURE__ */ c("div", { className: "grid grid-cols-3 gap-1.5 sm:grid-cols-4", children: I.map((x) => {
748
+ const P = Pe(x.key);
749
749
  return P ? /* @__PURE__ */ c(
750
750
  "button",
751
751
  {
752
752
  type: "button",
753
- onClick: () => j(x),
753
+ onClick: () => L(x),
754
754
  title: x.title,
755
755
  "data-testid": "meme-result",
756
756
  onMouseEnter: (T) => {
757
- E && O(x, T.currentTarget);
757
+ k && O(x, T.currentTarget);
758
758
  },
759
759
  onMouseLeave: g,
760
760
  onFocus: (T) => O(x, T.currentTarget, !0),
@@ -775,11 +775,11 @@ function no({ onClose: e, onPick: t, onUnavailable: n }) {
775
775
  ) : null;
776
776
  }) }),
777
777
  h && /* @__PURE__ */ c("p", { className: "p-2 text-center text-xs text-text-secondary", children: "Loading…" }),
778
- D && !h && /* @__PURE__ */ c(
778
+ j && !h && /* @__PURE__ */ c(
779
779
  "button",
780
780
  {
781
781
  type: "button",
782
- onClick: M,
782
+ onClick: D,
783
783
  "data-testid": "meme-load-more",
784
784
  className: "mt-2 w-full rounded border border-border-light py-1 text-xs text-text-secondary hover:text-text hover:border-primary",
785
785
  children: "Load more"
@@ -796,7 +796,7 @@ function no({ onClose: e, onPick: t, onUnavailable: n }) {
796
796
  style: {
797
797
  left: p.left,
798
798
  top: p.top,
799
- width: Xe,
799
+ width: Ye,
800
800
  /* The placement maths reserves exactly PREVIEW_PX of width.
801
801
  Without border-box the padding and border sit OUTSIDE that
802
802
  number and the box laps over the panel it is meant to sit
@@ -810,10 +810,10 @@ function no({ onClose: e, onPick: t, onUnavailable: n }) {
810
810
  /* @__PURE__ */ c(
811
811
  "img",
812
812
  {
813
- src: Re(p.item.key) ?? void 0,
813
+ src: Pe(p.item.key) ?? void 0,
814
814
  alt: "",
815
815
  className: "block w-full rounded bg-bg object-contain",
816
- style: { height: "auto", maxHeight: mn }
816
+ style: { height: "auto", maxHeight: ln }
817
817
  }
818
818
  ),
819
819
  p.item.title && /* One line. A long title must not change the box height, because
@@ -826,42 +826,42 @@ function no({ onClose: e, onPick: t, onUnavailable: n }) {
826
826
  }
827
827
  );
828
828
  }
829
- function ro({ open: e, ...t }) {
830
- return e ? /* @__PURE__ */ c(no, { ...t }) : null;
829
+ function no({ open: e, ...t }) {
830
+ return e ? /* @__PURE__ */ c(to, { ...t }) : null;
831
831
  }
832
- const dt = {
833
- serverOrigin: `http://localhost:${at}`,
832
+ const it = {
833
+ serverOrigin: `http://localhost:${tt}`,
834
834
  defaultRoomKey: "dev-room",
835
- cdnBase: Yt
835
+ cdnBase: qt
836
836
  };
837
- let Te = { ...dt };
838
- function oo(e) {
837
+ let Ie = { ...it };
838
+ function ro(e) {
839
839
  const t = Object.fromEntries(
840
840
  Object.entries(e).filter(([n, r]) => r !== void 0)
841
841
  );
842
- Te = { ...Te, ...t }, Gr({ cdnBase: Te.cdnBase });
842
+ Ie = { ...Ie, ...t }, Br({ cdnBase: Ie.cdnBase });
843
843
  }
844
- function fe() {
845
- return Te;
844
+ function me() {
845
+ return Ie;
846
846
  }
847
- const ao = rt(dt);
848
- function io(e) {
847
+ const oo = Ze(it);
848
+ function ao(e) {
849
849
  return e.serverOrigin?.replace(/\/$/, "") || "";
850
850
  }
851
- function pn() {
852
- return io(fe());
851
+ function dn() {
852
+ return ao(me());
853
853
  }
854
- const hn = rt(null);
855
- function so() {
856
- return Kt(hn);
854
+ const un = Ze(null);
855
+ function io() {
856
+ return Bt(un);
857
857
  }
858
- const ne = {
858
+ const te = {
859
859
  ANON_KEY: "watchparty_preferences",
860
860
  DEBUG_FLAG: "wp:debug",
861
861
  REPORT_LOGS_FLAG: "wp:reportLogs",
862
862
  voteKey: (e, t, n) => `watchparty_vote:${e}:${t}:${n}`
863
863
  };
864
- function Fe() {
864
+ function Ue() {
865
865
  try {
866
866
  return globalThis.localStorage ?? null;
867
867
  } catch {
@@ -870,22 +870,22 @@ function Fe() {
870
870
  }
871
871
  function B(e) {
872
872
  try {
873
- return Fe()?.getItem(e) ?? null;
873
+ return Ue()?.getItem(e) ?? null;
874
874
  } catch {
875
875
  return null;
876
876
  }
877
877
  }
878
- function ut(e, t) {
878
+ function st(e, t) {
879
879
  try {
880
- const n = Fe();
880
+ const n = Ue();
881
881
  return n ? (n.setItem(e, t), !0) : !1;
882
882
  } catch {
883
883
  return !1;
884
884
  }
885
885
  }
886
- function lo() {
886
+ function so() {
887
887
  try {
888
- const e = Fe();
888
+ const e = Ue();
889
889
  if (!e) return [];
890
890
  const t = [];
891
891
  for (let n = 0; n < e.length; n++) {
@@ -897,51 +897,51 @@ function lo() {
897
897
  return [];
898
898
  }
899
899
  }
900
- function Oe(e) {
900
+ function Re(e) {
901
901
  try {
902
- Fe()?.removeItem(e);
902
+ Ue()?.removeItem(e);
903
903
  } catch {
904
904
  }
905
905
  }
906
- function co(e) {
906
+ function lo(e) {
907
907
  const t = B(e);
908
908
  return t === null ? null : t === "true" ? !0 : t === "false" ? !1 : null;
909
909
  }
910
- const gn = /* @__PURE__ */ new Map();
911
- let yn = !1;
912
- function He(e, t) {
913
- gn.set(e, t), yn && bn(e, t);
910
+ const mn = /* @__PURE__ */ new Map();
911
+ let fn = !1;
912
+ function Fe(e, t) {
913
+ mn.set(e, t), fn && pn(e, t);
914
914
  }
915
- function uo() {
916
- yn = !0;
917
- for (const [e, t] of gn) bn(e, t);
915
+ function co() {
916
+ fn = !0;
917
+ for (const [e, t] of mn) pn(e, t);
918
918
  }
919
- function bn(e, t) {
919
+ function pn(e, t) {
920
920
  typeof window > "u" || (window[e] = t);
921
921
  }
922
- const se = [], mo = 500;
923
- let Ae = [], Je = null;
924
- const fo = 1e3, po = 200;
925
- let Ze = null;
926
- function vn(e) {
927
- Ze = e;
922
+ const ie = [], uo = 500;
923
+ let Te = [], ze = null;
924
+ const mo = 1e3, fo = 200;
925
+ let Xe = null;
926
+ function hn(e) {
927
+ Xe = e;
928
928
  }
929
- function Sn() {
930
- return B(ne.REPORT_LOGS_FLAG) === "true";
929
+ function gn() {
930
+ return B(te.REPORT_LOGS_FLAG) === "true";
931
931
  }
932
- function ho() {
932
+ function po() {
933
933
  if (typeof window > "u") return !1;
934
934
  if (window.__WP_DEBUG__ || new URLSearchParams(window.location.search).get("debug") === "true") return !0;
935
- const t = B(ne.DEBUG_FLAG);
935
+ const t = B(te.DEBUG_FLAG);
936
936
  return t !== null && t !== "false";
937
937
  }
938
- function go() {
939
- const e = B(ne.DEBUG_FLAG);
938
+ function ho() {
939
+ const e = B(te.DEBUG_FLAG);
940
940
  if (!e || e === "true") return null;
941
941
  const t = e.split(",").map((n) => n.trim().toLowerCase()).filter(Boolean);
942
942
  return t.length > 0 ? new Set(t) : null;
943
943
  }
944
- function yo() {
944
+ function go() {
945
945
  return (/* @__PURE__ */ new Date()).toLocaleTimeString("en-US", {
946
946
  hour12: !1,
947
947
  hour: "2-digit",
@@ -950,24 +950,24 @@ function yo() {
950
950
  fractionalSecondDigits: 3
951
951
  });
952
952
  }
953
- function bo(e) {
954
- se.push(e), se.length > mo && se.shift();
953
+ function yo(e) {
954
+ ie.push(e), ie.length > uo && ie.shift();
955
955
  }
956
- const $e = {
956
+ const He = {
957
957
  debug: "color: #64748b; font-weight: normal;",
958
958
  warn: "color: #f59e0b; font-weight: bold;",
959
959
  error: "color: #ef4444; font-weight: bold;",
960
960
  category: "color: #3b82f6; font-weight: bold;",
961
961
  time: "color: #6b7280; font-weight: normal;"
962
962
  };
963
- function vo(e) {
963
+ function bo(e) {
964
964
  try {
965
965
  return JSON.stringify(e);
966
966
  } catch {
967
967
  return "[unserializable]";
968
968
  }
969
969
  }
970
- function mt(e, t, n, r, a, i, s) {
970
+ function lt(e, t, n, r, a, i, s) {
971
971
  const l = {
972
972
  level: e,
973
973
  category: a,
@@ -975,47 +975,47 @@ function mt(e, t, n, r, a, i, s) {
975
975
  data: s,
976
976
  timestamp: Date.now()
977
977
  };
978
- if (bo(l), (n || Sn()) && Tt(l), !r) {
979
- if (!ho()) return;
980
- const u = go();
978
+ if (yo(l), (n || gn()) && wt(l), !r) {
979
+ if (!po()) return;
980
+ const u = ho();
981
981
  if (u && !u.has(a.toLowerCase())) return;
982
982
  }
983
- const m = yo(), h = s !== void 0 ? " " + vo(s) : "";
983
+ const f = go(), h = s !== void 0 ? " " + bo(s) : "";
984
984
  t(
985
- `%c[${m}]%c [${a}]%c ${i}${h}`,
986
- $e.time,
987
- $e.category,
988
- $e[e]
985
+ `%c[${f}]%c [${a}]%c ${i}${h}`,
986
+ He.time,
987
+ He.category,
988
+ He[e]
989
989
  );
990
990
  }
991
991
  function d(e, t, n) {
992
- mt("debug", console.log, !1, !1, e, t, n);
992
+ lt("debug", console.log, !1, !1, e, t, n);
993
993
  }
994
994
  function A(e, t, n) {
995
- mt("warn", console.warn, !0, !1, e, t, n);
995
+ lt("warn", console.warn, !0, !1, e, t, n);
996
996
  }
997
- function Ee(e, t, n) {
998
- mt("error", console.error, !0, !0, e, t, n);
997
+ function Ae(e, t, n) {
998
+ lt("error", console.error, !0, !0, e, t, n);
999
999
  }
1000
- function So() {
1001
- return [...se];
1000
+ function vo() {
1001
+ return [...ie];
1002
1002
  }
1003
- function wo() {
1004
- se.length = 0;
1003
+ function So() {
1004
+ ie.length = 0;
1005
1005
  }
1006
1006
  function _o(e) {
1007
1007
  const t = e && e.length > 0 ? e.join(",") : "true";
1008
- ut(ne.DEBUG_FLAG, t), console.log("[wp] Debug mode enabled");
1008
+ st(te.DEBUG_FLAG, t), console.log("[wp] Debug mode enabled");
1009
1009
  }
1010
- function xo() {
1011
- Oe(ne.DEBUG_FLAG), console.log("[wp] Debug mode disabled");
1010
+ function wo() {
1011
+ Re(te.DEBUG_FLAG), console.log("[wp] Debug mode disabled");
1012
1012
  }
1013
- const Io = 1024, Co = 5e4;
1014
- function To(e) {
1013
+ const xo = 1024, Co = 5e4;
1014
+ function Io(e) {
1015
1015
  if (e == null) return e;
1016
1016
  try {
1017
1017
  const t = JSON.stringify(e);
1018
- if (t.length <= Io) return e;
1018
+ if (t.length <= xo) return e;
1019
1019
  if (typeof e == "object" && !Array.isArray(e)) {
1020
1020
  const n = {};
1021
1021
  for (const [r, a] of Object.entries(e)) {
@@ -1029,35 +1029,35 @@ function To(e) {
1029
1029
  return "[unserializable]";
1030
1030
  }
1031
1031
  }
1032
- async function Ao() {
1033
- if (Ae.length === 0) return;
1034
- const e = Ae;
1035
- Ae = [], Je = null;
1032
+ async function To() {
1033
+ if (Te.length === 0) return;
1034
+ const e = Te;
1035
+ Te = [], ze = null;
1036
1036
  try {
1037
- let n = fe().serverOrigin || "";
1037
+ let n = me().serverOrigin || "";
1038
1038
  if ((n === "/" || !n) && typeof window < "u") {
1039
1039
  const l = window.location;
1040
- (l.hostname === "localhost" || l.hostname === "127.0.0.1") && l.port === String(Xt) ? n = `${l.protocol}//${l.hostname}:${at}` : n = l.origin;
1040
+ (l.hostname === "localhost" || l.hostname === "127.0.0.1") && l.port === String(Kt) ? n = `${l.protocol}//${l.hostname}:${tt}` : n = l.origin;
1041
1041
  }
1042
1042
  const r = `${n.replace(/\/$/, "")}/api/client-log`, a = e.map((l) => ({
1043
1043
  level: l.level,
1044
1044
  category: l.category,
1045
1045
  message: l.message,
1046
- data: To(l.data),
1046
+ data: Io(l.data),
1047
1047
  timestamp: l.timestamp,
1048
1048
  url: typeof window < "u" ? window.location.href : void 0,
1049
1049
  userAgent: typeof navigator < "u" ? navigator.userAgent : void 0,
1050
- room_key: Ze?.room_key,
1051
- client_id: Ze?.client_id
1050
+ room_key: Xe?.room_key,
1051
+ client_id: Xe?.client_id
1052
1052
  }));
1053
1053
  let i = [], s = 0;
1054
1054
  for (const l of a) {
1055
- const m = JSON.stringify(l).length + 1;
1056
- s + m > Co && i.length > 0 && (await fetch(r, {
1055
+ const f = JSON.stringify(l).length + 1;
1056
+ s + f > Co && i.length > 0 && (await fetch(r, {
1057
1057
  method: "POST",
1058
1058
  headers: { "Content-Type": "application/json" },
1059
1059
  body: JSON.stringify({ logs: i })
1060
- }), i = [], s = 0), i.push(l), s += m;
1060
+ }), i = [], s = 0), i.push(l), s += f;
1061
1061
  }
1062
1062
  i.length > 0 && await fetch(r, {
1063
1063
  method: "POST",
@@ -1065,70 +1065,70 @@ async function Ao() {
1065
1065
  body: JSON.stringify({ logs: i })
1066
1066
  });
1067
1067
  } catch (t) {
1068
- console.warn("[wp] log flush failed (client logs may be lost):", pe(t).error);
1068
+ console.warn("[wp] log flush failed (client logs may be lost):", fe(t).error);
1069
1069
  }
1070
1070
  }
1071
- function Tt(e) {
1072
- if (Ae.push(e), !Je) {
1073
- const t = Sn() ? po : fo;
1074
- Je = setTimeout(() => {
1075
- Ao();
1071
+ function wt(e) {
1072
+ if (Te.push(e), !ze) {
1073
+ const t = gn() ? fo : mo;
1074
+ ze = setTimeout(() => {
1075
+ To();
1076
1076
  }, t);
1077
1077
  }
1078
1078
  }
1079
- function pe(e) {
1079
+ function fe(e) {
1080
1080
  return e instanceof Error ? { error: e.message, name: e.name } : { error: String(e), name: typeof e };
1081
1081
  }
1082
- He("__wpDebug", {
1082
+ Fe("__wpDebug", {
1083
1083
  enable: _o,
1084
- disable: xo,
1085
- history: So,
1086
- clear: wo
1084
+ disable: wo,
1085
+ history: vo,
1086
+ clear: So
1087
1087
  });
1088
- function wn(e) {
1089
- return lt(e) ? Ir[e] : "var(--color-neutral-bg)";
1088
+ function yn(e) {
1089
+ return ot(e) ? xr[e] : "var(--color-neutral-bg)";
1090
1090
  }
1091
- function Eo(e) {
1092
- return lt(e) ? `${fe().serverOrigin.replace(/\/$/, "")}${Tr(e)}` : void 0;
1091
+ function Ao(e) {
1092
+ return ot(e) ? `${me().serverOrigin.replace(/\/$/, "")}${Ir(e)}` : void 0;
1093
1093
  }
1094
- let de = null, Se = null;
1094
+ let ce = null, ve = null;
1095
1095
  function ko() {
1096
- return de ? Promise.resolve() : Se || (Se = (async () => {
1096
+ return ce ? Promise.resolve() : ve || (ve = (async () => {
1097
1097
  try {
1098
- const e = fe().serverOrigin.replace(/\/$/, ""), t = await fetch(`${e}/media/sprites/names.json`, { cache: "no-cache" });
1098
+ const e = me().serverOrigin.replace(/\/$/, ""), t = await fetch(`${e}/media/sprites/names.json`, { cache: "no-cache" });
1099
1099
  if (!t.ok) return;
1100
1100
  const n = await t.json();
1101
- de = n, He("__DISPLAY_NAMES__", n), d("characters", "Loaded display names", n);
1101
+ ce = n, Fe("__DISPLAY_NAMES__", n), d("characters", "Loaded display names", n);
1102
1102
  } catch (e) {
1103
- d("characters", "display names fetch failed (degrading to sprite IDs)", pe(e));
1103
+ d("characters", "display names fetch failed (degrading to sprite IDs)", fe(e));
1104
1104
  }
1105
- })(), Se);
1105
+ })(), ve);
1106
1106
  }
1107
- function ue(e) {
1108
- return de?.[e] || e.charAt(0).toUpperCase() + e.slice(1);
1107
+ function de(e) {
1108
+ return ce?.[e] || e.charAt(0).toUpperCase() + e.slice(1);
1109
1109
  }
1110
- function Z(e) {
1110
+ function Q(e) {
1111
1111
  const t = e.toLowerCase();
1112
- return je.some((n) => n === t) ? !0 : de ? Object.values(de).some((n) => n.toLowerCase() === t) : !1;
1112
+ return Le.some((n) => n === t) ? !0 : ce ? Object.values(ce).some((n) => n.toLowerCase() === t) : !1;
1113
1113
  }
1114
1114
  const z = {
1115
1115
  resolved: !1,
1116
1116
  userType: "public",
1117
1117
  accountId: null
1118
1118
  };
1119
- function ft() {
1119
+ function ct() {
1120
1120
  return z.accountId ? z.accountId : z.resolved && z.userType === "public" ? "anon" : null;
1121
1121
  }
1122
- function No(e) {
1122
+ function Eo(e) {
1123
1123
  z.resolved = !0, e.userType && (z.userType = e.userType), e.userId !== void 0 && (z.accountId = e.userId && e.userId !== "public" ? e.userId : null);
1124
1124
  }
1125
- function pt() {
1125
+ function dt() {
1126
1126
  return z.accountId ?? "public";
1127
1127
  }
1128
- function Po() {
1129
- return ft() ?? "unscoped";
1128
+ function No() {
1129
+ return ct() ?? "unscoped";
1130
1130
  }
1131
- const Ro = o.object({
1131
+ const Po = o.object({
1132
1132
  // Identity. There is deliberately NO `name`: a person's name is their
1133
1133
  // hadoku key-registry name, resolved by the server from whoami and renamed
1134
1134
  // through hadoku_site's POST /session/name (operator decision 2026-10-08).
@@ -1153,19 +1153,19 @@ const Ro = o.object({
1153
1153
  preferredAudioLang: o.string().optional(),
1154
1154
  subtitlesEnabled: o.boolean().optional(),
1155
1155
  subtitleStyle: o.string().optional()
1156
- }), le = er({
1156
+ }), se = Zn({
1157
1157
  appId: "watchparty",
1158
- schema: Ro
1159
- }), Oo = /* @__PURE__ */ new Set(["theme", "themeMode"]);
1160
- function De(e) {
1161
- const t = ft();
1158
+ schema: Po
1159
+ }), Ro = /* @__PURE__ */ new Set(["theme", "themeMode"]);
1160
+ function Oe(e) {
1161
+ const t = ct();
1162
1162
  return t ? `prefs-cache:${t}:${e}` : null;
1163
1163
  }
1164
- function Do() {
1165
- return ft() === null;
1164
+ function Oo() {
1165
+ return ct() === null;
1166
1166
  }
1167
- function At(e) {
1168
- const t = De(e);
1167
+ function xt(e) {
1168
+ const t = Oe(e);
1169
1169
  if (!t) return {};
1170
1170
  const n = B(t);
1171
1171
  if (!n) return {};
@@ -1175,10 +1175,10 @@ function At(e) {
1175
1175
  return {};
1176
1176
  }
1177
1177
  }
1178
- function Mo() {
1178
+ function Do() {
1179
1179
  let e = 0;
1180
- for (const t of lo()) {
1181
- const n = t.startsWith("prefs-cache:") && t.endsWith(":watchparty"), r = t === Me || t.startsWith(`${Me}:`) && !t.endsWith(":_serverSynced_v1");
1180
+ for (const t of so()) {
1181
+ const n = t.startsWith("prefs-cache:") && t.endsWith(":watchparty"), r = t === De || t.startsWith(`${De}:`) && !t.endsWith(":_serverSynced_v1");
1182
1182
  if (!n && !r) continue;
1183
1183
  const a = B(t);
1184
1184
  if (!a) continue;
@@ -1190,18 +1190,18 @@ function Mo() {
1190
1190
  }
1191
1191
  const s = n ? i?.blob : i;
1192
1192
  if (!s || typeof s != "object" || !("name" in s)) continue;
1193
- const { name: l, ...m } = s, h = n ? { ...i, blob: m } : m;
1194
- ut(t, JSON.stringify(h)) && e++;
1193
+ const { name: l, ...f } = s, h = n ? { ...i, blob: f } : f;
1194
+ st(t, JSON.stringify(h)) && e++;
1195
1195
  }
1196
1196
  return e > 0 && d("preferences", "Stripped retired name from cached prefs rows", { rewritten: e }), e;
1197
1197
  }
1198
- let _n = null, xn = null;
1199
- const Et = /* @__PURE__ */ new Set();
1200
- function ht() {
1201
- if (Do())
1198
+ let bn = null, vn = null;
1199
+ const Ct = /* @__PURE__ */ new Set();
1200
+ function ut() {
1201
+ if (Oo())
1202
1202
  return d("preferences", "Boot read deferred — session pending, identity unresolved"), {};
1203
- const e = At("portfolio"), t = At("watchparty"), n = Object.keys(e).length > 0 ? e : _n ?? {}, r = Object.keys(t).length > 0 ? t : xn ?? {}, a = pt() || "public";
1204
- if (Et.has(a))
1203
+ const e = xt("portfolio"), t = xt("watchparty"), n = Object.keys(e).length > 0 ? e : bn ?? {}, r = Object.keys(t).length > 0 ? t : vn ?? {}, a = dt() || "public";
1204
+ if (Ct.has(a))
1205
1205
  return d("preferences", "Loaded (sync, SDK-only after first read)", {
1206
1206
  uid: a,
1207
1207
  sdkThemeKeys: Object.keys(n).length,
@@ -1211,8 +1211,8 @@ function ht() {
1211
1211
  themeSource: Object.keys(e).length > 0 ? "cache" : "mem",
1212
1212
  appSource: Object.keys(t).length > 0 ? "cache" : "mem"
1213
1213
  }), { ...r, ...n };
1214
- Et.add(a);
1215
- const i = Cn() ?? {}, s = { ...i, ...r, ...n };
1214
+ Ct.add(a);
1215
+ const i = _n() ?? {}, s = { ...i, ...r, ...n };
1216
1216
  return d("preferences", "Loaded (sync, first read — legacy + SDK)", {
1217
1217
  uid: a,
1218
1218
  sdkThemeKeys: Object.keys(n).length,
@@ -1222,60 +1222,60 @@ function ht() {
1222
1222
  appSource: Object.keys(t).length > 0 ? "cache" : "mem"
1223
1223
  }), s;
1224
1224
  }
1225
- let In = !1;
1226
- function Lo() {
1227
- const e = pt();
1225
+ let Sn = !1;
1226
+ function Mo() {
1227
+ const e = dt();
1228
1228
  return !e || e === "public";
1229
1229
  }
1230
1230
  function G(e, t) {
1231
- Lo() && (In = !0), Oo.has(e) ? ie.save({ [e]: t }, { scope: "device" }).catch((n) => A("preferences", "themePrefs.save failed", { key: e, err: n?.message })) : le.save({ [e]: t }).catch((n) => A("preferences", "watchpartyPrefs.save failed", { key: e, err: n?.message })), d("preferences", "Saved (via SDK)", { key: e, value: t });
1231
+ Mo() && (Sn = !0), Ro.has(e) ? ae.save({ [e]: t }, { scope: "device" }).catch((n) => A("preferences", "themePrefs.save failed", { key: e, err: n?.message })) : se.save({ [e]: t }).catch((n) => A("preferences", "watchpartyPrefs.save failed", { key: e, err: n?.message })), d("preferences", "Saved (via SDK)", { key: e, value: t });
1232
1232
  }
1233
- let we = null, kt = !1;
1234
- function jo() {
1235
- return we || (we = (async () => {
1233
+ let Se = null, It = !1;
1234
+ function Lo() {
1235
+ return Se || (Se = (async () => {
1236
1236
  if (typeof window > "u") return !1;
1237
1237
  try {
1238
- kt || (kt = !0, ie.subscribe((s) => {
1239
- _n = s, Rt("portfolio", s), Ot("theme");
1240
- }), le.subscribe((s) => {
1241
- xn = s, Rt("watchparty", s), Ot("watchparty");
1238
+ It || (It = !0, ae.subscribe((s) => {
1239
+ bn = s, kt("portfolio", s), Et("theme");
1240
+ }), se.subscribe((s) => {
1241
+ vn = s, kt("watchparty", s), Et("watchparty");
1242
1242
  }));
1243
1243
  const [e, t] = await Promise.all([
1244
- ie.read(),
1245
- le.read()
1244
+ ae.read(),
1245
+ se.read()
1246
1246
  ]);
1247
1247
  try {
1248
- const { useAppStore: s } = await Promise.resolve().then(() => An);
1248
+ const { useAppStore: s } = await Promise.resolve().then(() => xn);
1249
1249
  s.getState().rehydrateFromPrefs();
1250
1250
  } catch (s) {
1251
1251
  A("preferences", "inline rehydrate after SDK read failed", { err: s?.message });
1252
1252
  }
1253
- const n = De("portfolio"), r = De("watchparty"), a = n ? B(n) : null, i = r ? B(r) : null;
1253
+ const n = Oe("portfolio"), r = Oe("watchparty"), a = n ? B(n) : null, i = r ? B(r) : null;
1254
1254
  return d("preferences", "sdk.read", {
1255
1255
  themeKeys: Object.keys(e ?? {}),
1256
1256
  appKeys: Object.keys(t ?? {}),
1257
1257
  // Post-fetch cache state: should be non-zero if SDK wrote it.
1258
1258
  sdkThemeBytesPost: a?.length ?? 0,
1259
1259
  sdkAppBytesPost: i?.length ?? 0
1260
- }), await Uo(e, t), In ? (d("preferences", "Promoting this load's pre-auth picks to the signed-in user"), await Promise.all([
1261
- ie.promoteAnonPrefsToUser().catch(() => {
1260
+ }), await jo(e, t), Sn ? (d("preferences", "Promoting this load's pre-auth picks to the signed-in user"), await Promise.all([
1261
+ ae.promoteAnonPrefsToUser().catch(() => {
1262
1262
  }),
1263
- le.promoteAnonPrefsToUser().catch(() => {
1263
+ se.promoteAnonPrefsToUser().catch(() => {
1264
1264
  })
1265
1265
  ])) : d("preferences", "Skipping anon promotion — no pre-auth writes this load"), d("preferences", "First-load SDK sync complete"), !0;
1266
1266
  } catch (e) {
1267
1267
  return A("preferences", "First-load SDK sync failed (non-fatal)", { err: e?.message }), !1;
1268
1268
  }
1269
- })(), we);
1269
+ })(), Se);
1270
1270
  }
1271
- const Me = "watchparty_preferences";
1272
- Mo();
1273
- function Qe() {
1274
- const e = pt();
1275
- return !e || e === "public" ? Me : `${Me}:${e}`;
1271
+ const De = "watchparty_preferences";
1272
+ Do();
1273
+ function Je() {
1274
+ const e = dt();
1275
+ return !e || e === "public" ? De : `${De}:${e}`;
1276
1276
  }
1277
- function Cn() {
1278
- const e = B(Qe());
1277
+ function _n() {
1278
+ const e = B(Je());
1279
1279
  if (!e) return null;
1280
1280
  try {
1281
1281
  const t = JSON.parse(e);
@@ -1284,40 +1284,40 @@ function Cn() {
1284
1284
  return null;
1285
1285
  }
1286
1286
  }
1287
- function Nt() {
1288
- Oe(Qe()), Oe(`${Qe()}:_serverSynced_v1`);
1287
+ function Tt() {
1288
+ Re(Je()), Re(`${Je()}:_serverSynced_v1`);
1289
1289
  }
1290
- async function Uo(e, t) {
1291
- const n = Cn();
1290
+ async function jo(e, t) {
1291
+ const n = _n();
1292
1292
  if (!n || Object.keys(n).length === 0) return;
1293
1293
  const r = Object.keys(e ?? {}).length > 0, a = Object.keys(t ?? {}).length > 0, i = {}, s = {};
1294
1294
  for (const [h, u] of Object.entries(n))
1295
1295
  r || (h === "theme" && typeof u == "string" ? i.theme = u : h === "themeMode" && (u === "simple" || u === "advanced") && (i.themeMode = u)), a || (h === "chatCollapsed" && typeof u == "boolean" ? s.chatCollapsed = u : h === "floatingChatEnabled" && typeof u == "boolean" ? s.floatingChatEnabled = u : h === "volume" && typeof u == "number" && u >= 0 && u <= 1 ? s.volume = u : h === "muted" && typeof u == "boolean" ? s.muted = u : h === "preferredAudioLang" && typeof u == "string" ? s.preferredAudioLang = u : h === "subtitlesEnabled" && typeof u == "boolean" ? s.subtitlesEnabled = u : h === "subtitleStyle" && typeof u == "string" && (s.subtitleStyle = u));
1296
- const l = Object.keys(i), m = Object.keys(s);
1297
- if (l.length === 0 && m.length === 0) {
1298
- Nt();
1296
+ const l = Object.keys(i), f = Object.keys(s);
1297
+ if (l.length === 0 && f.length === 0) {
1298
+ Tt();
1299
1299
  return;
1300
1300
  }
1301
1301
  d("preferences", "Migrating legacy localStorage prefs to SDK", {
1302
1302
  themeKeys: l,
1303
- appKeys: m,
1303
+ appKeys: f,
1304
1304
  sdkHasTheme: r,
1305
1305
  sdkHasApp: a
1306
1306
  });
1307
1307
  try {
1308
1308
  await Promise.all([
1309
- l.length > 0 ? ie.save(i, { scope: "device" }) : Promise.resolve(),
1310
- m.length > 0 ? le.save(s) : Promise.resolve()
1311
- ]), Nt(), d("preferences", "Legacy migration complete");
1309
+ l.length > 0 ? ae.save(i, { scope: "device" }) : Promise.resolve(),
1310
+ f.length > 0 ? se.save(s) : Promise.resolve()
1311
+ ]), Tt(), d("preferences", "Legacy migration complete");
1312
1312
  } catch (h) {
1313
1313
  A("preferences", "Legacy migration save failed — will retry next load", {
1314
1314
  err: h?.message
1315
1315
  });
1316
1316
  }
1317
1317
  }
1318
- let Pt = !1;
1319
- function Rt(e, t) {
1320
- const n = De(e);
1318
+ let At = !1;
1319
+ function kt(e, t) {
1320
+ const n = Oe(e);
1321
1321
  if (n)
1322
1322
  try {
1323
1323
  const r = {
@@ -1328,15 +1328,15 @@ function Rt(e, t) {
1328
1328
  };
1329
1329
  localStorage.setItem(n, JSON.stringify(r));
1330
1330
  } catch (r) {
1331
- Pt || (Pt = !0, A("preferences", "writeThrough localStorage failed (in-memory backstop only)", {
1331
+ At || (At = !0, A("preferences", "writeThrough localStorage failed (in-memory backstop only)", {
1332
1332
  appId: e,
1333
1333
  err: r?.message,
1334
1334
  name: r?.name
1335
1335
  }));
1336
1336
  }
1337
1337
  }
1338
- function Ot(e) {
1339
- Promise.resolve().then(() => An).then(({ useAppStore: t }) => {
1338
+ function Et(e) {
1339
+ Promise.resolve().then(() => xn).then(({ useAppStore: t }) => {
1340
1340
  try {
1341
1341
  t.getState().rehydrateFromPrefs();
1342
1342
  } catch (n) {
@@ -1344,33 +1344,33 @@ function Ot(e) {
1344
1344
  }
1345
1345
  }).catch((t) => A("preferences", "store import failed", { reason: e, err: t?.message }));
1346
1346
  }
1347
- const Tn = 320, Le = 240, gt = 640, Fo = 320, Ho = 36, Dt = 16;
1347
+ const wn = 320, Me = 240, mt = 640, Uo = 320, Fo = 36, Nt = 16;
1348
1348
  function V(e, t) {
1349
- if (!Number.isFinite(e)) return Tn;
1350
- let n = gt;
1351
- return t !== void 0 && Number.isFinite(t) && t > 0 && (n = Math.min(n, t - Fo)), n = Math.max(n, Le), Math.round(Math.min(n, Math.max(Le, e)));
1349
+ if (!Number.isFinite(e)) return wn;
1350
+ let n = mt;
1351
+ return t !== void 0 && Number.isFinite(t) && t > 0 && (n = Math.min(n, t - Uo)), n = Math.max(n, Me), Math.round(Math.min(n, Math.max(Me, e)));
1352
1352
  }
1353
- function Mt(e, t, n, r) {
1353
+ function Pt(e, t, n, r) {
1354
1354
  return V(e + (t - n), r);
1355
1355
  }
1356
- function $o(e, t, n) {
1356
+ function Ho(e, t, n) {
1357
1357
  switch (t) {
1358
1358
  case "ArrowLeft":
1359
- return V(e + Dt, n);
1359
+ return V(e + Nt, n);
1360
1360
  case "ArrowRight":
1361
- return V(e - Dt, n);
1361
+ return V(e - Nt, n);
1362
1362
  case "Home":
1363
- return V(Le, n);
1363
+ return V(Me, n);
1364
1364
  case "End":
1365
- return V(gt, n);
1365
+ return V(mt, n);
1366
1366
  default:
1367
1367
  return null;
1368
1368
  }
1369
1369
  }
1370
- function Bo(e, t) {
1371
- return { collapsed: e, width: e ? Ho : t };
1370
+ function $o(e, t) {
1371
+ return { collapsed: e, width: e ? Fo : t };
1372
1372
  }
1373
- const q = ht(), f = Qn((e, t) => ({
1373
+ const q = ut(), m = Qn((e, t) => ({
1374
1374
  ready: !1,
1375
1375
  name: "",
1376
1376
  sprite: null,
@@ -1380,7 +1380,7 @@ const q = ht(), f = Qn((e, t) => ({
1380
1380
  chat: [],
1381
1381
  chatCollapsed: q.chatCollapsed ?? !1,
1382
1382
  chromeChatCollapsed: q.chromeChatCollapsed ?? !1,
1383
- chromeChatWidth: V(q.chromeChatWidth ?? Tn),
1383
+ chromeChatWidth: V(q.chromeChatWidth ?? wn),
1384
1384
  // Hardcoded on for everyone — the per-user toggle was removed from the
1385
1385
  // control bar; FloatingChat + toggleFloatingChat code is kept for future
1386
1386
  // re-enablement but the value is no longer user-controllable.
@@ -1424,7 +1424,7 @@ const q = ht(), f = Qn((e, t) => ({
1424
1424
  ensureAutoIdentity: () => e((n) => {
1425
1425
  if (n.name) return {};
1426
1426
  if (n.sprite) {
1427
- const a = ue(n.sprite);
1427
+ const a = de(n.sprite);
1428
1428
  return d("store", "Auto-identity: deriving name from the requested sprite", { name: a, sprite: n.sprite }), { name: a };
1429
1429
  }
1430
1430
  const r = new Set(Object.values(n.roster).map((a) => a.sprite).filter(Boolean));
@@ -1432,9 +1432,9 @@ const q = ht(), f = Qn((e, t) => ({
1432
1432
  rosterSize: Object.keys(n.roster).length,
1433
1433
  usedSprites: Array.from(r)
1434
1434
  });
1435
- for (const a of je)
1435
+ for (const a of Le)
1436
1436
  if (!r.has(a)) {
1437
- const i = ue(a);
1437
+ const i = de(a);
1438
1438
  return d("store", "Auto-identity assigned", { name: i, sprite: a }), { name: i, sprite: a };
1439
1439
  }
1440
1440
  return A("store", "All characters taken, leaving identity unset"), {};
@@ -1445,7 +1445,7 @@ const q = ht(), f = Qn((e, t) => ({
1445
1445
  applySnapshot: (n) => e((r) => {
1446
1446
  const a = { ...r.roster };
1447
1447
  if (n.users)
1448
- for (const m of n.users) a[m.clientId] = m;
1448
+ for (const f of n.users) a[f.clientId] = f;
1449
1449
  const i = n.mediaId !== void 0 ? n.mediaId : r.snapshot.mediaId, s = n.leaderId !== void 0 ? n.leaderId : r.snapshot.leaderId;
1450
1450
  d("store", "Snapshot applied", {
1451
1451
  mediaId: i,
@@ -1520,8 +1520,8 @@ const q = ht(), f = Qn((e, t) => ({
1520
1520
  const s = [...i.drift.rtts, n].slice(-5);
1521
1521
  let l = i.drift.offsetMs;
1522
1522
  if (r && a) {
1523
- const m = a + n / 2;
1524
- l = r - m;
1523
+ const f = a + n / 2;
1524
+ l = r - f;
1525
1525
  }
1526
1526
  return { drift: { rtts: s, offsetMs: l } };
1527
1527
  }),
@@ -1575,13 +1575,13 @@ const q = ht(), f = Qn((e, t) => ({
1575
1575
  */
1576
1576
  moveTierlistItem: (n, r, a) => e((i) => {
1577
1577
  const s = {};
1578
- for (const [l, m] of Object.entries(i.tierlistDraft)) {
1579
- const h = (m ?? []).filter((u) => u !== n);
1578
+ for (const [l, f] of Object.entries(i.tierlistDraft)) {
1579
+ const h = (f ?? []).filter((u) => u !== n);
1580
1580
  h.length > 0 && (s[l] = h);
1581
1581
  }
1582
1582
  if (r !== null) {
1583
- const l = s[r] ?? [], m = Math.max(0, Math.min(a ?? l.length, l.length));
1584
- l.splice(m, 0, n), s[r] = l;
1583
+ const l = s[r] ?? [], f = Math.max(0, Math.min(a ?? l.length, l.length));
1584
+ l.splice(f, 0, n), s[r] = l;
1585
1585
  }
1586
1586
  return { tierlistDraft: s };
1587
1587
  }),
@@ -1590,7 +1590,7 @@ const q = ht(), f = Qn((e, t) => ({
1590
1590
  setGameSettings: (n) => e({ gameSettings: n }),
1591
1591
  setRoomKeyType: (n) => e({ roomKeyType: n }),
1592
1592
  rehydrateFromPrefs: () => e((n) => {
1593
- const r = ht(), a = {};
1593
+ const r = ut(), a = {};
1594
1594
  if (r.chatCollapsed !== void 0 && (a.chatCollapsed = r.chatCollapsed), r.chromeChatCollapsed !== void 0 && (a.chromeChatCollapsed = r.chromeChatCollapsed), r.chromeChatWidth !== void 0 && (a.chromeChatWidth = V(r.chromeChatWidth)), ["volume", "muted", "preferredAudioLang", "subtitlesEnabled", "subtitleStyle"].some((l) => r[l] !== void 0)) {
1595
1595
  const l = { ...n.mediaPrefs };
1596
1596
  r.volume !== void 0 && (l.volume = r.volume), r.muted !== void 0 && (l.muted = r.muted), r.preferredAudioLang !== void 0 && (l.preferredAudioLang = r.preferredAudioLang), r.subtitlesEnabled !== void 0 && (l.subtitlesEnabled = r.subtitlesEnabled), r.subtitleStyle !== void 0 && ["classic", "cinema", "minimal", "contrast"].includes(r.subtitleStyle) && (l.subtitleStyle = r.subtitleStyle), a.mediaPrefs = l;
@@ -1599,37 +1599,37 @@ const q = ht(), f = Qn((e, t) => ({
1599
1599
  }),
1600
1600
  setSidebarTab: (n) => e((r) => r.sidebarTab === n && n !== "chat" ? { sidebarTab: "chat" } : { sidebarTab: n, chatCollapsed: !1 })
1601
1601
  }));
1602
- He("__ZUSTAND_STORE__", f);
1603
- const An = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
1602
+ Fe("__ZUSTAND_STORE__", m);
1603
+ const xn = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
1604
1604
  __proto__: null,
1605
- useAppStore: f
1606
- }, Symbol.toStringTag, { value: "Module" })), En = rt(!0);
1607
- function Go() {
1608
- const e = Kt(En);
1605
+ useAppStore: m
1606
+ }, Symbol.toStringTag, { value: "Module" })), Cn = Ze(!0);
1607
+ function Bo() {
1608
+ const e = Bt(Cn);
1609
1609
  N(() => {
1610
- e && Wn();
1610
+ e && Gn();
1611
1611
  }, [e]);
1612
1612
  }
1613
- function qo(e, t) {
1613
+ function Go(e, t) {
1614
1614
  if (!t) return "";
1615
1615
  for (const n of Object.values(e))
1616
1616
  if (n.author === t && n.cosmetics) return JSON.stringify(n.cosmetics);
1617
1617
  return "";
1618
1618
  }
1619
- function Vo(e) {
1620
- const t = f((n) => qo(n.roster, e));
1619
+ function qo(e) {
1620
+ const t = m((n) => Go(n.roster, e));
1621
1621
  return J(() => t ? JSON.parse(t) : void 0, [t]);
1622
1622
  }
1623
- function Ko(e) {
1623
+ function Vo(e) {
1624
1624
  return e ? { "--hc-base": e } : {};
1625
1625
  }
1626
- const et = Pe.memo(
1626
+ const Qe = Ne.memo(
1627
1627
  function({ html: t, as: n = "span", className: r, style: a }) {
1628
- return Pe.createElement(n, { className: r, style: a, dangerouslySetInnerHTML: { __html: t } });
1628
+ return Ne.createElement(n, { className: r, style: a, dangerouslySetInnerHTML: { __html: t } });
1629
1629
  },
1630
1630
  (e, t) => e.html === t.html && e.as === t.as && e.className === t.className && JSON.stringify(e.style) === JSON.stringify(t.style)
1631
1631
  );
1632
- function Wo(e, t) {
1632
+ function Ko(e, t) {
1633
1633
  N(() => {
1634
1634
  const n = e.current;
1635
1635
  if (!n || !t || typeof IntersectionObserver > "u") return;
@@ -1641,102 +1641,102 @@ function Wo(e, t) {
1641
1641
  };
1642
1642
  }, [e, t]);
1643
1643
  }
1644
- function Yo(e) {
1645
- return `${pn()}/media/${e}`.replace(/\\/g, "/");
1644
+ function Wo(e) {
1645
+ return `${dn()}/media/${e}`.replace(/\\/g, "/");
1646
1646
  }
1647
- function zo(e, t) {
1648
- return Yo(t ?? `${e}/poster.jpg`);
1647
+ function Yo(e, t) {
1648
+ return Wo(t ?? `${e}/poster.jpg`);
1649
1649
  }
1650
- function Xo(e) {
1651
- return `${pn()}${e}`.replace(/\\/g, "/");
1650
+ function zo(e) {
1651
+ return `${dn()}${e}`.replace(/\\/g, "/");
1652
1652
  }
1653
- async function Jo(e) {
1653
+ async function Xo(e) {
1654
1654
  try {
1655
- const t = await fetch(Xo("/api/tierlist"));
1655
+ const t = await fetch(zo("/api/tierlist"));
1656
1656
  if (!t.ok)
1657
1657
  return A("tierlist", "Board fetch failed", { status: t.status }), null;
1658
1658
  const n = await t.json();
1659
- return f.getState().setTierlistSnapshot(n, e), d("tierlist", "Board loaded", {
1659
+ return m.getState().setTierlistSnapshot(n, e), d("tierlist", "Board loaded", {
1660
1660
  items: n.items.length,
1661
1661
  voters: n.voterCount,
1662
1662
  placed: n.placed.length
1663
1663
  }), n;
1664
1664
  } catch (t) {
1665
- return A("tierlist", "Board fetch threw", pe(t)), null;
1665
+ return A("tierlist", "Board fetch threw", fe(t)), null;
1666
1666
  }
1667
1667
  }
1668
- let Lt = !1;
1669
- function Zo() {
1670
- if (Lt || typeof Image > "u") return;
1671
- const e = f.getState().tierlist;
1668
+ let Rt = !1;
1669
+ function Jo() {
1670
+ if (Rt || typeof Image > "u") return;
1671
+ const e = m.getState().tierlist;
1672
1672
  if (!(!e || e.items.length === 0)) {
1673
- Lt = !0;
1673
+ Rt = !0;
1674
1674
  for (const t of e.items) {
1675
1675
  const n = new Image();
1676
- n.decoding = "async", n.src = zo(t.id, t.thumbnail);
1676
+ n.decoding = "async", n.src = Yo(t.id, t.thumbnail);
1677
1677
  }
1678
1678
  d("tierlist", "Warming posters", { count: e.items.length });
1679
1679
  }
1680
1680
  }
1681
1681
  function Qo() {
1682
- const e = f.getState(), t = new Set(Object.values(e.roster).map((i) => i.sprite).filter(Boolean)), n = je.find((i) => !t.has(i));
1682
+ const e = m.getState(), t = new Set(Object.values(e.roster).map((i) => i.sprite).filter(Boolean)), n = Le.find((i) => !t.has(i));
1683
1683
  if (!n)
1684
1684
  return A("socket", "sprite_taken: no available sprites to retry with"), null;
1685
- const r = !!e.name && !Z(e.name), a = r ? e.name : ue(n);
1685
+ const r = !!e.name && !Q(e.name), a = r ? e.name : de(n);
1686
1686
  return d("socket", "sprite_taken: retrying with next available", { from: e.sprite, to: n, name: a, keptCustomName: r }), e.setSessionIdentity(a, n), { name: a, sprite: n };
1687
1687
  }
1688
- function ea(e) {
1689
- const t = f.getState(), n = e ? t.roster[e] : void 0;
1688
+ function Zo(e) {
1689
+ const t = m.getState(), n = e ? t.roster[e] : void 0;
1690
1690
  return !n || !!n.sprite && n.sprite === t.sprite;
1691
1691
  }
1692
- const jt = "hadoku:avatar";
1693
- function kn(e) {
1692
+ const Ot = "hadoku:avatar";
1693
+ function In(e) {
1694
1694
  const t = e?.sprite ?? e?.avatar?.sprite ?? null;
1695
- return lt(t) ? t : null;
1695
+ return ot(t) ? t : null;
1696
1696
  }
1697
- async function ta(e = {}) {
1697
+ async function ea(e = {}) {
1698
1698
  const t = e.fetch ?? (typeof fetch > "u" ? void 0 : fetch), n = typeof window > "u" ? void 0 : window.location?.origin, r = e.baseUrl ?? (n ? `${n}/prefs` : void 0);
1699
1699
  if (!t || !r) return null;
1700
1700
  try {
1701
- const a = await or({ baseUrl: r, fetch: t }).get(), i = kn(a);
1701
+ const a = await rr({ baseUrl: r, fetch: t }).get(), i = In(a);
1702
1702
  return d("avatar", "Requested character from prefs-api", { sprite: i }), i;
1703
1703
  } catch (a) {
1704
- return a instanceof _t && (a.status === 401 || a.status === 403 || a.status === 404) ? d("avatar", "No avatar settings here (signed out, or no prefs-api on this origin)", { status: a.status }) : A("avatar", "Avatar settings read failed — keeping the auto-assigned character", {
1705
- status: a instanceof _t ? a.status : void 0,
1706
- ...pe(a)
1704
+ return a instanceof bt && (a.status === 401 || a.status === 403 || a.status === 404) ? d("avatar", "No avatar settings here (signed out, or no prefs-api on this origin)", { status: a.status }) : A("avatar", "Avatar settings read failed — keeping the auto-assigned character", {
1705
+ status: a instanceof bt ? a.status : void 0,
1706
+ ...fe(a)
1707
1707
  }), null;
1708
1708
  }
1709
1709
  }
1710
- function Ut(e) {
1710
+ function Dt(e) {
1711
1711
  if (!e) return !1;
1712
- const t = f.getState();
1712
+ const t = m.getState();
1713
1713
  if (t.sprite === e) return !1;
1714
- const r = !!(t.me.clientId && t.roster[t.me.clientId]?.registryName) || !t.name || !Z(t.name) ? t.name : ue(e);
1714
+ const r = !!(t.me.clientId && t.roster[t.me.clientId]?.registryName) || !t.name || !Q(t.name) ? t.name : de(e);
1715
1715
  return t.setSessionIdentity(r, e), !0;
1716
1716
  }
1717
- function na(e, t = typeof window > "u" ? void 0 : window) {
1717
+ function ta(e, t = typeof window > "u" ? void 0 : window) {
1718
1718
  if (!t) return () => {
1719
1719
  };
1720
1720
  const n = (r) => {
1721
1721
  const a = r.detail;
1722
1722
  !a || typeof a != "object" || e(a);
1723
1723
  };
1724
- return t.addEventListener(jt, n), () => t.removeEventListener(jt, n);
1724
+ return t.addEventListener(Ot, n), () => t.removeEventListener(Ot, n);
1725
1725
  }
1726
- const ra = 10;
1727
- function oa(e = typeof window < "u" ? window : void 0) {
1726
+ const na = 10;
1727
+ function ra(e = typeof window < "u" ? window : void 0) {
1728
1728
  if (!e) return { framed: !1, depth: 0 };
1729
1729
  try {
1730
1730
  let t = 0, n = e;
1731
- for (; n !== n.parent && t < ra; )
1731
+ for (; n !== n.parent && t < na; )
1732
1732
  t++, n = n.parent;
1733
1733
  return { framed: e.top ? e.top !== e.self : t > 0, depth: t };
1734
1734
  } catch {
1735
1735
  return { framed: !1, depth: 0 };
1736
1736
  }
1737
1737
  }
1738
- const aa = "watchparty_fragment_delivery";
1739
- function ia() {
1738
+ const oa = "watchparty_fragment_delivery";
1739
+ function aa() {
1740
1740
  if (typeof window > "u") return null;
1741
1741
  try {
1742
1742
  const e = new URLSearchParams(window.location.search).get("fragmentDelivery");
@@ -1744,74 +1744,74 @@ function ia() {
1744
1744
  if (e === "0" || e === "false") return !1;
1745
1745
  } catch {
1746
1746
  }
1747
- return co(aa);
1747
+ return lo(oa);
1748
1748
  }
1749
- let sa = { ...on }, Be = null;
1750
- const Ft = "watchparty_delivery_client_id";
1751
- function la() {
1752
- const e = B(Ft);
1749
+ let ia = { ...en }, $e = null;
1750
+ const Mt = "watchparty_delivery_client_id";
1751
+ function sa() {
1752
+ const e = B(Mt);
1753
1753
  if (e) return e;
1754
1754
  const t = globalThis.crypto?.randomUUID?.() ?? `d${Math.random().toString(36).slice(2)}`;
1755
- return ut(Ft, t) ? t : "";
1755
+ return st(Mt, t) ? t : "";
1756
1756
  }
1757
- function ca() {
1758
- return Be === null && (Be = Rr(sa, la(), ia())), Be;
1757
+ function la() {
1758
+ return $e === null && ($e = Pr(ia, sa(), aa())), $e;
1759
1759
  }
1760
- function da() {
1761
- return ca();
1760
+ function ca() {
1761
+ return la();
1762
1762
  }
1763
1763
  let ke;
1764
- function Nn() {
1765
- return B(nr) || void 0;
1764
+ function Tn() {
1765
+ return B(tr) || void 0;
1766
1766
  }
1767
- function ua() {
1767
+ function da() {
1768
1768
  if (ke) return;
1769
- const e = Nn();
1769
+ const e = Tn();
1770
1770
  if (e) {
1771
1771
  ke = e;
1772
1772
  return;
1773
1773
  }
1774
- tr().then((t) => {
1774
+ er().then((t) => {
1775
1775
  t && (ke = t);
1776
1776
  }).catch(() => {
1777
1777
  d("identity", "device id unavailable — joining without one");
1778
1778
  });
1779
1779
  }
1780
- function ma() {
1781
- return ke ??= Nn();
1780
+ function ua() {
1781
+ return ke ??= Tn();
1782
1782
  }
1783
- function fa(e, t) {
1783
+ function ma(e, t) {
1784
1784
  let n = 0;
1785
1785
  for (const r of e.videos) {
1786
- const a = ne.voteKey(t, e.id, r.mediaId);
1787
- globalThis.localStorage?.getItem(a) != null && n++, Oe(a);
1786
+ const a = te.voteKey(t, e.id, r.mediaId);
1787
+ globalThis.localStorage?.getItem(a) != null && n++, Re(a);
1788
1788
  }
1789
1789
  return n;
1790
1790
  }
1791
- const pa = 2e4, ha = 1e4;
1792
- function ga() {
1791
+ const fa = 2e4, pa = 1e4;
1792
+ function ha() {
1793
1793
  return { unansweredSince: null, lastPongAt: null, lastTickAt: null };
1794
1794
  }
1795
- function ya(e, t) {
1795
+ function ga(e, t) {
1796
1796
  e.lastPongAt = t, e.unansweredSince = null;
1797
1797
  }
1798
- function ba(e, t, n) {
1799
- const r = e.lastTickAt !== null && t - e.lastTickAt > ha;
1800
- return e.lastTickAt = t, n ? r || e.unansweredSince === null ? (e.unansweredSince = t, !1) : t - e.unansweredSince > pa : (e.unansweredSince = null, !1);
1798
+ function ya(e, t, n) {
1799
+ const r = e.lastTickAt !== null && t - e.lastTickAt > pa;
1800
+ return e.lastTickAt = t, n ? r || e.unansweredSince === null ? (e.unansweredSince = t, !1) : t - e.unansweredSince > fa : (e.unansweredSince = null, !1);
1801
1801
  }
1802
- function va(e, t) {
1802
+ function ba(e, t) {
1803
1803
  return e.lastPongAt === null ? void 0 : Math.max(0, t - e.lastPongAt);
1804
1804
  }
1805
- let w = null, H = null, Ne = null, $ = null, W = null;
1806
- const Sa = xa(), ee = ga();
1807
- let _e = null, Ge = null, Ht = 0, yt = null, me = !1, bt = !1, ae = !1, Pn = null;
1808
- function wa(e) {
1809
- const t = re(), n = f.getState();
1805
+ let _ = null, H = null, Ee = null, $ = null, W = null;
1806
+ const va = wa(), Z = ha();
1807
+ let _e = null, Be = null, Lt = 0, ft = null, ue = !1, pt = !1, oe = !1, An = null;
1808
+ function Sa(e) {
1809
+ const t = ne(), n = m.getState();
1810
1810
  if (n.me.clientId && n.roster[n.me.clientId])
1811
- return (e.name || e.sprite) && (d("socket", "Identity update (already joined)", { name: e.name, sprite: e.sprite }), t.emit(_.IDENTITY_UPDATE, { name: e.name, sprite: e.sprite })), t;
1811
+ return (e.name || e.sprite) && (d("socket", "Identity update (already joined)", { name: e.name, sprite: e.sprite }), t.emit(w.IDENTITY_UPDATE, { name: e.name, sprite: e.sprite })), t;
1812
1812
  const r = _a(e);
1813
- return W = r, yt = { name: r.name, sprite: r.sprite }, t.connected ? (d("socket", "Emitting join", r), t.emit(_.JOIN, r)) : t.once("connect", () => {
1814
- d("socket", "Emitting join", r), t.emit(_.JOIN, r);
1813
+ return W = r, ft = { name: r.name, sprite: r.sprite }, t.connected ? (d("socket", "Emitting join", r), t.emit(w.JOIN, r)) : t.once("connect", () => {
1814
+ d("socket", "Emitting join", r), t.emit(w.JOIN, r);
1815
1815
  }), t;
1816
1816
  }
1817
1817
  function _a(e) {
@@ -1821,16 +1821,16 @@ function _a(e) {
1821
1821
  sprite: e.sprite,
1822
1822
  // Entry-path telemetry — see lib/embedContext.ts. Sent on every join AND
1823
1823
  // rejoin (lastJoinPayload carries it), so a reconnect keeps the attribution.
1824
- embed: oa(),
1825
- delivery_arm: da(),
1824
+ embed: ra(),
1825
+ delivery_arm: ca(),
1826
1826
  // Identity tier input — see lib/deviceId.ts. Sent on every join AND rejoin
1827
1827
  // (lastJoinPayload carries it) so a reconnect lands on the same
1828
1828
  // ParticipantId rather than minting a new person.
1829
- device_id: ma(),
1830
- tab_id: Sa
1829
+ device_id: ua(),
1830
+ tab_id: va
1831
1831
  };
1832
1832
  }
1833
- function xa() {
1833
+ function wa() {
1834
1834
  const e = globalThis.crypto;
1835
1835
  if (e && typeof e.randomUUID == "function") return e.randomUUID();
1836
1836
  const t = new Uint8Array(16);
@@ -1838,67 +1838,67 @@ function xa() {
1838
1838
  else for (let n = 0; n < t.length; n++) t[n] = Math.floor(Math.random() * 256);
1839
1839
  return Array.from(t, (n) => n.toString(16).padStart(2, "0")).join("");
1840
1840
  }
1841
- function re() {
1842
- if (!w) {
1843
- let t = fe().serverOrigin || "/";
1841
+ function ne() {
1842
+ if (!_) {
1843
+ let t = me().serverOrigin || "/";
1844
1844
  if (t === "/" && typeof window < "u") {
1845
1845
  const r = window.location;
1846
- (r.hostname === "localhost" || r.hostname === "127.0.0.1") && r.port === String(Xt) && (t = `${r.protocol}//${r.hostname}:${at}`, d("socket", "Using dev fallback origin", { origin: t }));
1846
+ (r.hostname === "localhost" || r.hostname === "127.0.0.1") && r.port === String(Kt) && (t = `${r.protocol}//${r.hostname}:${tt}`, d("socket", "Using dev fallback origin", { origin: t }));
1847
1847
  }
1848
1848
  const n = new URL(t.startsWith("http") ? t : `${window.location.origin}${t}`).origin;
1849
- w = rr(n, { path: lr, transports: ["websocket", "polling"] }), d("socket", "Socket initialized", { origin: t }), He("__SOCKET__", w), $ && (clearTimeout($), $ = null), H = null, Ne = setInterval(() => {
1850
- if (ba(ee, Date.now(), !!w?.connected)) {
1849
+ _ = nr(n, { path: sr, transports: ["websocket", "polling"] }), d("socket", "Socket initialized", { origin: t }), Fe("__SOCKET__", _), $ && (clearTimeout($), $ = null), H = null, Ee = setInterval(() => {
1850
+ if (ya(Z, Date.now(), !!_?.connected)) {
1851
1851
  A("socket", "PONG-WATCHDOG no time_pong for 20s — replacing the connection", {
1852
- sid: w?.id,
1853
- lastPongAgeMs: va(ee, Date.now()) ?? null
1854
- }), Ge = "pong-watchdog", ee.unansweredSince = null, w?.io.engine?.close();
1852
+ sid: _?.id,
1853
+ lastPongAgeMs: ba(Z, Date.now()) ?? null
1854
+ }), Be = "pong-watchdog", Z.unansweredSince = null, _?.io.engine?.close();
1855
1855
  return;
1856
1856
  }
1857
- Ma();
1858
- }, Ar), w.on("connect", () => {
1859
- bt = !1;
1860
- const r = w?.id;
1861
- if (d("socket", "Connected", { id: r, isReconnect: ae }), r)
1857
+ Da();
1858
+ }, Tr), _.on("connect", () => {
1859
+ pt = !1;
1860
+ const r = _?.id;
1861
+ if (d("socket", "Connected", { id: r, isReconnect: oe }), r)
1862
1862
  try {
1863
- f.getState().ensureMe(r), f.setState((a) => ({ me: { ...a.me, nextClientSeq: 1 } })), d("socket", "Reset client sequence for new connection");
1863
+ m.getState().ensureMe(r), m.setState((a) => ({ me: { ...a.me, nextClientSeq: 1 } })), d("socket", "Reset client sequence for new connection");
1864
1864
  } catch (a) {
1865
- Ee("socket", "Failed to initialize store on connect", { error: a.message, sid: r });
1865
+ Ae("socket", "Failed to initialize store on connect", { error: a.message, sid: r });
1866
1866
  }
1867
- if (ae && W) {
1868
- const a = f.getState();
1869
- Ht += 1;
1867
+ if (oe && W) {
1868
+ const a = m.getState();
1869
+ Lt += 1;
1870
1870
  const i = {
1871
1871
  ...W,
1872
1872
  name: a.name,
1873
1873
  sprite: a.sprite,
1874
1874
  reconnect: {
1875
- count: Ht,
1875
+ count: Lt,
1876
1876
  reason: (_e?.reason ?? "unknown").slice(0, 64),
1877
1877
  offline_ms: _e ? Math.max(0, Date.now() - _e.at) : 0
1878
1878
  }
1879
- }, s = Pn;
1879
+ }, s = An;
1880
1880
  if (d("socket", "Re-emitting join after reconnect", { room_key: i.room_key, name: i.name, sprite: i.sprite }), s) {
1881
1881
  let l = !1;
1882
- const m = () => {
1883
- l || (l = !0, w.off(_.SNAPSHOT, m), w.emit(_.CLIENT_READY, { media_id: s }), d("socket", "Re-emitted client_ready after reconnect snapshot", { mediaId: s }));
1882
+ const f = () => {
1883
+ l || (l = !0, _.off(w.SNAPSHOT, f), _.emit(w.CLIENT_READY, { media_id: s }), d("socket", "Re-emitted client_ready after reconnect snapshot", { mediaId: s }));
1884
1884
  };
1885
- w.on(_.SNAPSHOT, m), setTimeout(() => {
1886
- l || (l = !0, w.off(_.SNAPSHOT, m), A("socket", "client_ready re-emit timed out waiting for snapshot", { mediaId: s }));
1885
+ _.on(w.SNAPSHOT, f), setTimeout(() => {
1886
+ l || (l = !0, _.off(w.SNAPSHOT, f), A("socket", "client_ready re-emit timed out waiting for snapshot", { mediaId: s }));
1887
1887
  }, 1e4);
1888
1888
  }
1889
- yt = { name: i.name, sprite: i.sprite }, w.emit(_.JOIN, i), window.dispatchEvent(new CustomEvent("watchparty:socket-reconnect"));
1890
- } else ae && A("socket", "Reconnected — no join payload, not re-joining any room");
1891
- ae = !0;
1892
- }), w.on("disconnect", (r) => {
1893
- vn(null), _e = { reason: Ge ?? r, at: Date.now() }, Ge = null, d("socket", "Disconnected", { reason: r });
1894
- }), w.on("connect_error", (r) => Ee("socket", "Connection error", { message: r?.message })), w.on("reconnect_attempt", (r) => A("socket", "Reconnect attempt", { attempt: r })), w.on("reconnect_failed", () => Ee("socket", "Reconnect failed")), Oa(w);
1889
+ ft = { name: i.name, sprite: i.sprite }, _.emit(w.JOIN, i), window.dispatchEvent(new CustomEvent("watchparty:socket-reconnect"));
1890
+ } else oe && A("socket", "Reconnected — no join payload, not re-joining any room");
1891
+ oe = !0;
1892
+ }), _.on("disconnect", (r) => {
1893
+ hn(null), _e = { reason: Be ?? r, at: Date.now() }, Be = null, d("socket", "Disconnected", { reason: r });
1894
+ }), _.on("connect_error", (r) => Ae("socket", "Connection error", { message: r?.message })), _.on("reconnect_attempt", (r) => A("socket", "Reconnect attempt", { attempt: r })), _.on("reconnect_failed", () => Ae("socket", "Reconnect failed")), Ra(_);
1895
1895
  }
1896
- return w;
1896
+ return _;
1897
1897
  }
1898
- function qe(e) {
1898
+ function Ge(e) {
1899
1899
  return e.play_state === "playing" || e.playing === !0;
1900
1900
  }
1901
- function $t(e, t) {
1901
+ function jt(e, t) {
1902
1902
  return {
1903
1903
  id: String(e.id ?? e.server_seq ?? t ?? `${Date.now()}-${Math.random().toString(36).slice(2, 8)}`),
1904
1904
  clientId: e.client_id,
@@ -1910,52 +1910,52 @@ function $t(e, t) {
1910
1910
  // Attachments arrive from other clients, so the key shape is re-checked
1911
1911
  // here at the boundary rather than trusted at render time. A malformed
1912
1912
  // entry is dropped, not rendered and not allowed near an <img src>.
1913
- images: Array.isArray(e.images) ? e.images.filter((n) => !!n && ot(n.key)).slice(0, Y) : void 0,
1913
+ images: Array.isArray(e.images) ? e.images.filter((n) => !!n && et(n.key)).slice(0, Y) : void 0,
1914
1914
  isSystem: e.isSystem || !1,
1915
1915
  systemType: e.systemType
1916
1916
  };
1917
1917
  }
1918
- function Ia(e) {
1919
- e.on(_.SNAPSHOT, (t) => {
1920
- e.emit(rn.SYNC), f.getState().applySnapshot({
1918
+ function xa(e) {
1919
+ e.on(w.SNAPSHOT, (t) => {
1920
+ e.emit(Zt.SYNC), m.getState().applySnapshot({
1921
1921
  roomId: t.room_id ?? null,
1922
1922
  mediaId: t.media_id ?? null,
1923
1923
  playheadMs: t.playhead_ms || 0,
1924
- playing: qe(t),
1924
+ playing: Ge(t),
1925
1925
  serverSeq: t.server_seq || 0,
1926
1926
  leaderId: t.leader_id || null
1927
- }), f.getState().name || d("socket", "Deferring identity to presence event (snapshot carries no roster)");
1928
- const n = f.getState(), r = w?.id, i = (r ? n.roster[r] : void 0) ?? yt, s = ar(
1927
+ }), m.getState().name || d("socket", "Deferring identity to presence event (snapshot carries no roster)");
1928
+ const n = m.getState(), r = _?.id, i = (r ? n.roster[r] : void 0) ?? ft, s = or(
1929
1929
  { name: n.name, avatarId: n.sprite },
1930
1930
  i ? { name: i.name, avatarId: i.sprite ?? null } : void 0,
1931
1931
  // A join that carried no name counts as a default one, so a name that
1932
1932
  // landed after the join (prefs) is still asserted.
1933
- (l) => l === "" || Z(l)
1933
+ (l) => l === "" || Q(l)
1934
1934
  );
1935
1935
  if (s) {
1936
1936
  const l = {
1937
1937
  ...s.name !== void 0 ? { name: s.name } : {},
1938
- ...s.avatarId !== void 0 && !bt ? { sprite: s.avatarId } : {}
1938
+ ...s.avatarId !== void 0 && !pt ? { sprite: s.avatarId } : {}
1939
1939
  };
1940
- Object.keys(l).length > 0 && (d("socket", "Identity update on snapshot", l), e.emit(_.IDENTITY_UPDATE, l));
1940
+ Object.keys(l).length > 0 && (d("socket", "Identity update on snapshot", l), e.emit(w.IDENTITY_UPDATE, l));
1941
1941
  }
1942
1942
  d("socket", "Received snapshot", {
1943
1943
  mediaId: t.media_id ?? null,
1944
1944
  playheadMs: t.playhead_ms || 0,
1945
- playing: qe(t),
1945
+ playing: Ge(t),
1946
1946
  leaderId: t.leader_id || null,
1947
1947
  serverSeq: t.server_seq || 0,
1948
1948
  rosterSize: Object.keys(n.roster).length
1949
- }), W?.room_key && w?.id && vn({ room_key: W.room_key, client_id: w.id });
1950
- }), e.on(_.CONTROL_BROADCAST, (t) => {
1951
- const n = f.getState();
1949
+ }), W?.room_key && _?.id && hn({ room_key: W.room_key, client_id: _.id });
1950
+ }), e.on(w.CONTROL_BROADCAST, (t) => {
1951
+ const n = m.getState();
1952
1952
  if (Object.prototype.hasOwnProperty.call(t, "media_id")) {
1953
1953
  const r = t.media_id ?? null;
1954
1954
  n.snapshot.mediaId !== r && (n.applySnapshot({ mediaId: r }), r && n.setReadiness({ mediaId: r, ready: !1, readyCount: 0, total: 0 }), n.bumpLoadGeneration());
1955
1955
  }
1956
1956
  n.updateControlState({
1957
1957
  playheadMs: t.playhead_ms,
1958
- playing: qe(t),
1958
+ playing: Ge(t),
1959
1959
  serverSeq: t.server_seq,
1960
1960
  leaderId: t.leader_id ?? n.snapshot.leaderId
1961
1961
  }), d("socket", "Control broadcast received", {
@@ -1965,25 +1965,25 @@ function Ia(e) {
1965
1965
  playState: t.play_state,
1966
1966
  mediaId: t.media_id
1967
1967
  });
1968
- }), e.on(_.CONTROL_ACK, (t) => {
1968
+ }), e.on(w.CONTROL_ACK, (t) => {
1969
1969
  typeof t?.client_seq == "number" && typeof t?.server_seq == "number" && d("socket", "Control ack received", t);
1970
- }), e.on(_.TIME_PONG, (t) => {
1971
- if (ya(ee, Date.now()), H && H.ts) {
1970
+ }), e.on(w.TIME_PONG, (t) => {
1971
+ if (ga(Z, Date.now()), H && H.ts) {
1972
1972
  const n = Date.now() - H.ts;
1973
- f.getState().addRttSample(n, t?.server_ts, H.ts), H = null, $ && (clearTimeout($), $ = null), d("socket", "Time sync RTT", { rtt: n, offset: f.getState().drift.offsetMs });
1973
+ m.getState().addRttSample(n, t?.server_ts, H.ts), H = null, $ && (clearTimeout($), $ = null), d("socket", "Time sync RTT", { rtt: n, offset: m.getState().drift.offsetMs });
1974
1974
  }
1975
- }), e.on(_.READY_STATE, (t) => {
1975
+ }), e.on(w.READY_STATE, (t) => {
1976
1976
  if (!t) return;
1977
1977
  const n = t.media_id ?? null, r = typeof t.ready_count == "number" ? t.ready_count : 0, a = typeof t.total == "number" ? t.total : 0, i = t.ready === !0;
1978
- f.getState().setReadiness({ mediaId: n, ready: i, readyCount: r, total: a }), d("socket", "Ready state received", { mediaId: n, readyCount: r, total: a, ready: i });
1978
+ m.getState().setReadiness({ mediaId: n, ready: i, readyCount: r, total: a }), d("socket", "Ready state received", { mediaId: n, readyCount: r, total: a, ready: i });
1979
1979
  });
1980
1980
  }
1981
1981
  function Ca(e) {
1982
- const t = Yn(e);
1982
+ const t = qn(e);
1983
1983
  return t ? { cosmetics: t } : {};
1984
1984
  }
1985
- function Ta(e) {
1986
- e.on(_.PRESENCE, (t) => {
1985
+ function Ia(e) {
1986
+ e.on(w.PRESENCE, (t) => {
1987
1987
  if (!t) return;
1988
1988
  if (Array.isArray(t.users)) {
1989
1989
  const r = {};
@@ -1998,101 +1998,101 @@ function Ta(e) {
1998
1998
  ...l.avatar_url ? { avatarUrl: l.avatar_url } : {},
1999
1999
  ...Ca(l.cosmetics)
2000
2000
  };
2001
- const a = f.getState(), i = w?.id, s = i ? r[i] : void 0;
2001
+ const a = m.getState(), i = _?.id, s = i ? r[i] : void 0;
2002
2002
  if (s?.registryName)
2003
- f.setState({ roster: r }), (s.name !== a.name || s.sprite && s.sprite !== a.sprite) && (d("socket", "Adopting registry name", { from: a.name, to: s.name }), f.getState().setSessionIdentity(s.name, s.sprite ?? a.sprite));
2003
+ m.setState({ roster: r }), (s.name !== a.name || s.sprite && s.sprite !== a.sprite) && (d("socket", "Adopting registry name", { from: a.name, to: s.name }), m.getState().setSessionIdentity(s.name, s.sprite ?? a.sprite));
2004
2004
  else if (i && r[i]) {
2005
- const l = r[i].name, m = r[i].sprite;
2006
- if (a.name && !Z(a.name) && (r[i].name = a.name), f.setState({ roster: r }), m && m !== a.sprite) {
2007
- const h = a.name && !Z(a.name), u = h ? a.name : ue(m);
2008
- d("socket", "Server reassigned sprite", { from: a.sprite, to: m, newName: u, preservingCustomName: h }), f.getState().setSessionIdentity(u, m), u !== l && e.emit(_.IDENTITY_UPDATE, { name: u });
2005
+ const l = r[i].name, f = r[i].sprite;
2006
+ if (a.name && !Q(a.name) && (r[i].name = a.name), m.setState({ roster: r }), f && f !== a.sprite) {
2007
+ const h = a.name && !Q(a.name), u = h ? a.name : de(f);
2008
+ d("socket", "Server reassigned sprite", { from: a.sprite, to: f, newName: u, preservingCustomName: h }), m.getState().setSessionIdentity(u, f), u !== l && e.emit(w.IDENTITY_UPDATE, { name: u });
2009
2009
  }
2010
2010
  }
2011
2011
  }
2012
2012
  d("socket", "Received presence update", t);
2013
- const n = f.getState();
2013
+ const n = m.getState();
2014
2014
  if (!n.name) {
2015
2015
  n.ensureAutoIdentity?.();
2016
- const r = f.getState();
2017
- r.name && (d("socket", "Auto-assigned identity on presence", { name: r.name, sprite: r.sprite }), e.emit(_.IDENTITY_UPDATE, { name: r.name, sprite: r.sprite || void 0 }));
2016
+ const r = m.getState();
2017
+ r.name && (d("socket", "Auto-assigned identity on presence", { name: r.name, sprite: r.sprite }), e.emit(w.IDENTITY_UPDATE, { name: r.name, sprite: r.sprite || void 0 }));
2018
2018
  }
2019
2019
  });
2020
2020
  }
2021
- function Aa(e) {
2022
- e.on(_.CHAT_BROADCAST, (t) => {
2023
- const n = { ...$t(t, t.server_seq), live: !0 };
2024
- f.getState().appendChat(n), d("chat", "Message received", n);
2025
- }), e.on(_.CHAT_HISTORY, (t) => {
2021
+ function Ta(e) {
2022
+ e.on(w.CHAT_BROADCAST, (t) => {
2023
+ const n = { ...jt(t, t.server_seq), live: !0 };
2024
+ m.getState().appendChat(n), d("chat", "Message received", n);
2025
+ }), e.on(w.CHAT_HISTORY, (t) => {
2026
2026
  if (!t?.messages || !Array.isArray(t.messages)) return;
2027
- const n = t.messages.map((r) => $t(r));
2028
- f.getState().setChat(n), d("chat", "History loaded", { count: n.length });
2027
+ const n = t.messages.map((r) => jt(r));
2028
+ m.getState().setChat(n), d("chat", "History loaded", { count: n.length });
2029
2029
  });
2030
2030
  }
2031
- function Ea(e) {
2032
- e.on(be.STATE, (t) => {
2033
- f.getState().applyPlaylistState({
2031
+ function Aa(e) {
2032
+ e.on(ye.STATE, (t) => {
2033
+ m.getState().applyPlaylistState({
2034
2034
  playlist: t?.playlist ?? null,
2035
2035
  activeIndex: t?.activeIndex ?? null,
2036
2036
  myVotes: t?.myVotes ?? {}
2037
2037
  }), d("playlist", "Playlist state received", { playlistId: t?.playlist?.id ?? null, activeIndex: t?.activeIndex, myVoteCount: Object.keys(t?.myVotes || {}).length });
2038
- }), e.on(be.VOTE_PROGRESS, (t) => {
2039
- f.getState().setVoteProgress(t?.progress ?? []), d("playlist", "Vote progress", { progressCount: t?.progress?.length });
2040
- }), e.on(be.RESULTS, (t) => {
2041
- f.getState().setPlaylistResults(t ?? null), d("playlist", "Results received", { playlistId: t?.playlist?.id, update: t?.update === !0 });
2042
- }), e.on(be.VOTES_CLEARED, (t) => {
2038
+ }), e.on(ye.VOTE_PROGRESS, (t) => {
2039
+ m.getState().setVoteProgress(t?.progress ?? []), d("playlist", "Vote progress", { progressCount: t?.progress?.length });
2040
+ }), e.on(ye.RESULTS, (t) => {
2041
+ m.getState().setPlaylistResults(t ?? null), d("playlist", "Results received", { playlistId: t?.playlist?.id, update: t?.update === !0 });
2042
+ }), e.on(ye.VOTES_CLEARED, (t) => {
2043
2043
  if (!t?.playlistId || !Array.isArray(t.mediaIds)) return;
2044
- const n = fa(
2044
+ const n = ma(
2045
2045
  { id: t.playlistId, videos: t.mediaIds.map((a) => ({ mediaId: a })) },
2046
- Po()
2047
- ), r = f.getState();
2046
+ No()
2047
+ ), r = m.getState();
2048
2048
  r.playlist?.id === t.playlistId && r.applyPlaylistState({ playlist: r.playlist, activeIndex: r.activePlaylistIndex, myVotes: {} }), d("playlist", "Votes cleared by leader", { playlistId: t.playlistId, removed: n });
2049
2049
  });
2050
2050
  }
2051
2051
  function ka(e) {
2052
- e.on(wr.UPDATED, () => {
2053
- d("tierlist", "Someone saved — refreshing the board"), Jo(!1);
2052
+ e.on(Sr.UPDATED, () => {
2053
+ d("tierlist", "Someone saved — refreshing the board"), Xo(!1);
2054
2054
  });
2055
2055
  }
2056
- function Na(e) {
2056
+ function Ea(e) {
2057
2057
  e.on(_r.STATE, (t) => {
2058
2058
  if (!t || typeof t.active != "boolean") return;
2059
2059
  const n = Array.isArray(t.ready) ? t.ready.filter((r) => typeof r == "string") : [];
2060
- f.getState().setReadyCheckState({ active: t.active, ready: n }), d("ready-check", "State received", { active: t.active, readyCount: n.length });
2060
+ m.getState().setReadyCheckState({ active: t.active, ready: n }), d("ready-check", "State received", { active: t.active, readyCount: n.length });
2061
2061
  });
2062
2062
  }
2063
- function Pa(e) {
2064
- e.on(rn.ACTIVE, (t) => {
2063
+ function Na(e) {
2064
+ e.on(Zt.ACTIVE, (t) => {
2065
2065
  const n = typeof t?.gameId == "string" ? t.gameId : null;
2066
- f.getState().setActiveGameId(n), d("game", "game_active", { gameId: n });
2066
+ m.getState().setActiveGameId(n), d("game", "game_active", { gameId: n });
2067
2067
  });
2068
2068
  }
2069
- function Ra(e) {
2070
- e.on(_.HEALTH_SNAPSHOT, (t) => {
2071
- f.getState().setHealthSnapshot(t);
2072
- }), e.on(_.BUFFER_STATUS, (t) => {
2073
- f.getState().setBufferStatus(t);
2069
+ function Pa(e) {
2070
+ e.on(w.HEALTH_SNAPSHOT, (t) => {
2071
+ m.getState().setHealthSnapshot(t);
2072
+ }), e.on(w.BUFFER_STATUS, (t) => {
2073
+ m.getState().setBufferStatus(t);
2074
2074
  });
2075
2075
  }
2076
- function Oa(e) {
2077
- Ia(e), Ta(e), Aa(e), Ra(e), Ea(e), ka(e), Na(e), Pa(e), e.on(_.ERROR, (t) => {
2076
+ function Ra(e) {
2077
+ xa(e), Ia(e), Ta(e), Pa(e), Aa(e), ka(e), Ea(e), Na(e), e.on(w.ERROR, (t) => {
2078
2078
  const n = t?.code || "error/unknown";
2079
2079
  if (n === "conflict" && t?.message === "sprite_held_by_you") {
2080
- bt = !0, d("socket", "sprite held by this account's other connection: keeping the server-assigned sprite");
2080
+ pt = !0, d("socket", "sprite held by this account's other connection: keeping the server-assigned sprite");
2081
2081
  return;
2082
2082
  }
2083
2083
  if (n === "conflict" && t?.message === "sprite_taken") {
2084
- if (ea(w?.id)) {
2084
+ if (Zo(_?.id)) {
2085
2085
  d("socket", "sprite_taken: stale, the server already has our sprite");
2086
2086
  return;
2087
2087
  }
2088
- me = !0;
2088
+ ue = !0;
2089
2089
  let s;
2090
2090
  try {
2091
2091
  s = Qo();
2092
2092
  } finally {
2093
- me = !1;
2093
+ ue = !1;
2094
2094
  }
2095
- s && e.emit(_.IDENTITY_UPDATE, s);
2095
+ s && e.emit(w.IDENTITY_UPDATE, s);
2096
2096
  return;
2097
2097
  }
2098
2098
  const a = {
@@ -2113,55 +2113,55 @@ function Oa(e) {
2113
2113
  "recap/not_found": "No recap available for the previous episode."
2114
2114
  }[n] || n;
2115
2115
  if (n.startsWith("recap/")) {
2116
- d("socket", `recap unavailable: ${a}`, { code: n }), f.getState().pushToast("info", a);
2116
+ d("socket", `recap unavailable: ${a}`, { code: n }), m.getState().pushToast("info", a);
2117
2117
  return;
2118
2118
  }
2119
- (n.startsWith("auth/") ? A : Ee)("socket", `Server error: ${a}`, { code: n, raw: t }), f.getState().pushToast("error", a);
2119
+ (n.startsWith("auth/") ? A : Ae)("socket", `Server error: ${a}`, { code: n, raw: t }), m.getState().pushToast("error", a);
2120
2120
  });
2121
2121
  }
2122
- function Da(e, t) {
2123
- re().emit(_.CHAT_SEND, t?.length ? { text: e, images: t } : { text: e });
2122
+ function Oa(e, t) {
2123
+ ne().emit(w.CHAT_SEND, t?.length ? { text: e, images: t } : { text: e });
2124
2124
  }
2125
- function Ma() {
2126
- H || (H = { ts: Date.now() }, re().emit(_.TIME_PING, {}), $ = setTimeout(() => {
2125
+ function Da() {
2126
+ H || (H = { ts: Date.now() }, ne().emit(w.TIME_PING, {}), $ = setTimeout(() => {
2127
2127
  H && (d("socket", "Time ping timed out after 10s, clearing inflight"), H = null), $ = null;
2128
2128
  }, 1e4));
2129
2129
  }
2130
- function Rn(e) {
2131
- const t = f.getState(), n = t.me.clientId;
2130
+ function kn(e) {
2131
+ const t = m.getState(), n = t.me.clientId;
2132
2132
  if (!n || !t.roster[n]) {
2133
- Ut(e), d("socket", "Avatar change before join: the join will carry it", { sprite: e });
2133
+ Dt(e), d("socket", "Avatar change before join: the join will carry it", { sprite: e });
2134
2134
  return;
2135
2135
  }
2136
- me = !0;
2136
+ ue = !0;
2137
2137
  try {
2138
- Ut(e);
2138
+ Dt(e);
2139
2139
  } finally {
2140
- me = !1;
2140
+ ue = !1;
2141
2141
  }
2142
- const r = f.getState(), a = { avatar: !0 };
2143
- r.sprite && r.sprite !== t.sprite && (a.sprite = r.sprite), r.name && r.name !== t.name && (a.name = r.name), d("socket", "Sending avatar change", a), re().emit(_.IDENTITY_UPDATE, a);
2142
+ const r = m.getState(), a = { avatar: !0 };
2143
+ r.sprite && r.sprite !== t.sprite && (a.sprite = r.sprite), r.name && r.name !== t.name && (a.name = r.name), d("socket", "Sending avatar change", a), ne().emit(w.IDENTITY_UPDATE, a);
2144
2144
  }
2145
- let xe = { name: "", sprite: "" };
2146
- f.subscribe((e, t) => {
2147
- if (e.name === t.name && e.sprite === t.sprite || me) return;
2145
+ let we = { name: "", sprite: "" };
2146
+ m.subscribe((e, t) => {
2147
+ if (e.name === t.name && e.sprite === t.sprite || ue) return;
2148
2148
  const n = e.me.clientId;
2149
2149
  if (!n) return;
2150
2150
  const r = e.roster[n];
2151
2151
  if (!r) return;
2152
- const a = !!e.name && !Z(e.name) && e.name !== xe.name && (Z(r.name || "") || r.name !== e.name), i = !!e.sprite && e.sprite !== xe.sprite && r.sprite !== e.sprite;
2152
+ const a = !!e.name && !Q(e.name) && e.name !== we.name && (Q(r.name || "") || r.name !== e.name), i = !!e.sprite && e.sprite !== we.sprite && r.sprite !== e.sprite;
2153
2153
  if (!a && !i) return;
2154
2154
  const s = {};
2155
- a && (s.name = e.name, xe.name = e.name), i && (s.sprite = e.sprite, xe.sprite = e.sprite), d("socket", "Identity reassert (store change)", s), w?.connected ? w.emit(_.IDENTITY_UPDATE, s) : re().emit(_.IDENTITY_UPDATE, s);
2155
+ a && (s.name = e.name, we.name = e.name), i && (s.sprite = e.sprite, we.sprite = e.sprite), d("socket", "Identity reassert (store change)", s), _?.connected ? _.emit(w.IDENTITY_UPDATE, s) : ne().emit(w.IDENTITY_UPDATE, s);
2156
2156
  });
2157
- function La() {
2158
- Ne && (clearInterval(Ne), Ne = null), $ && (clearTimeout($), $ = null), H = null, ee.unansweredSince = null, ee.lastTickAt = null;
2157
+ function Ma() {
2158
+ Ee && (clearInterval(Ee), Ee = null), $ && (clearTimeout($), $ = null), H = null, Z.unansweredSince = null, Z.lastTickAt = null;
2159
2159
  }
2160
- function ja() {
2161
- d("socket", "clearJoinState called", { hadPayload: W !== null, room_key: W?.room_key }), W = null, ae = !1, Pn = null;
2160
+ function La() {
2161
+ d("socket", "clearJoinState called", { hadPayload: W !== null, room_key: W?.room_key }), W = null, oe = !1, An = null;
2162
2162
  }
2163
- function Bt() {
2164
- d("socket", "leaveRoom called", { room_key: W?.room_key }), ja(), La(), w && (w.disconnect(), w = null), f.setState({
2163
+ function Ut() {
2164
+ d("socket", "leaveRoom called", { room_key: W?.room_key }), La(), Ma(), _ && (_.disconnect(), _ = null), m.setState({
2165
2165
  me: { clientId: null, nextClientSeq: 1 },
2166
2166
  roster: {},
2167
2167
  snapshot: { roomId: null, mediaId: null, playheadMs: 0, playing: !1, serverSeq: 0, leaderId: null },
@@ -2176,89 +2176,30 @@ function Bt() {
2176
2176
  activeGameId: null
2177
2177
  });
2178
2178
  }
2179
- function Ua() {
2180
- d("chat", "Emitting recap_request"), re().emit("recap_request");
2179
+ function ja() {
2180
+ d("chat", "Emitting recap_request"), ne().emit("recap_request");
2181
2181
  }
2182
- function Fa() {
2183
- N(() => na((e) => {
2184
- const t = kn(e);
2185
- d("avatar", "Avatar changed in the settings popout", { sprite: t, source: e.avatar?.source }), Rn(t);
2182
+ function Ua() {
2183
+ N(() => ta((e) => {
2184
+ const t = In(e);
2185
+ d("avatar", "Avatar changed in the settings popout", { sprite: t, source: e.avatar?.source }), kn(t);
2186
2186
  }), []);
2187
2187
  }
2188
- const Ha = 0.3, $a = 0.82, Q = 24, Ba = 32;
2189
- function Ga(e) {
2190
- let t = 0, n = 0, r = 0, a = 0;
2191
- for (let i = 0; i + 3 < e.length; i += 4) {
2192
- const s = e[i + 3];
2193
- s < Ba || (t += e[i] * s, n += e[i + 1] * s, r += e[i + 2] * s, a += s);
2194
- }
2195
- return a === 0 ? null : qa(t / a, n / a, r / a);
2196
- }
2197
- function qa(e, t, n) {
2198
- const [r, a, i] = Va(e / 255, t / 255, n / 255), s = Math.min($a, Math.max(Ha, i)), [l, m, h] = Ka(r, a, s), u = (D) => Math.round(D * 255).toString(16).padStart(2, "0");
2199
- return `#${u(l)}${u(m)}${u(h)}`;
2200
- }
2201
- function Va(e, t, n) {
2202
- const r = Math.max(e, t, n), a = Math.min(e, t, n), i = (r + a) / 2;
2203
- if (r === a) return [0, 0, i];
2204
- const s = r - a, l = i > 0.5 ? s / (2 - r - a) : s / (r + a);
2205
- let m;
2206
- return r === e ? m = (t - n) / s + (t < n ? 6 : 0) : r === t ? m = (n - e) / s + 2 : m = (e - t) / s + 4, [m / 6, l, i];
2207
- }
2208
- function Ka(e, t, n) {
2209
- if (t === 0) return [n, n, n];
2210
- const r = n < 0.5 ? n * (1 + t) : n + t - n * t, a = 2 * n - r, i = (s) => (s < 0 && (s += 1), s > 1 && (s -= 1), s < 1 / 6 ? a + (r - a) * 6 * s : s < 1 / 2 ? r : s < 2 / 3 ? a + (r - a) * (2 / 3 - s) * 6 : a);
2211
- return [i(e + 1 / 3), i(e), i(e - 1 / 3)];
2212
- }
2213
- const tt = /* @__PURE__ */ new Map(), Ve = /* @__PURE__ */ new Set(), nt = /* @__PURE__ */ new Set();
2214
- function Wa() {
2215
- for (const e of nt) e();
2216
- }
2217
- function Ya(e) {
2218
- if (tt.has(e) || Ve.has(e) || typeof Image > "u" || typeof document > "u") return;
2219
- Ve.add(e);
2220
- const t = new Image();
2221
- t.crossOrigin = "anonymous", t.referrerPolicy = "no-referrer";
2222
- const n = (r) => {
2223
- Ve.delete(e), tt.set(e, r), Wa();
2224
- };
2225
- t.onload = () => {
2226
- try {
2227
- const r = document.createElement("canvas");
2228
- r.width = Q, r.height = Q;
2229
- const a = r.getContext("2d", { willReadFrequently: !0 });
2230
- if (!a) {
2231
- n(null);
2232
- return;
2233
- }
2234
- a.drawImage(t, 0, 0, Q, Q), n(Ga(a.getImageData(0, 0, Q, Q).data));
2235
- } catch (r) {
2236
- d("avatar", "picture colour unreadable", { url: e, error: r instanceof Error ? r.message : String(r) }), n(null);
2237
- }
2238
- }, t.onerror = () => n(null), t.src = e;
2239
- }
2240
- function za(e) {
2241
- return nt.add(e), () => nt.delete(e);
2242
- }
2243
- function Xa(e, t) {
2244
- if (t) {
2245
- const n = tt.get(t);
2246
- if (n) return n;
2247
- }
2248
- return wn(e);
2188
+ function Fa(e, t) {
2189
+ return (t ? Wn(t) : null) ?? yn(e);
2249
2190
  }
2250
- function On(e, t) {
2191
+ function En(e, t) {
2251
2192
  return N(() => {
2252
- t && Ya(t);
2253
- }, [t]), Ln(za, () => Xa(e, t), () => wn(e));
2193
+ t && Vn(t);
2194
+ }, [t]), Rn(Kn, () => Fa(e, t), () => yn(e));
2254
2195
  }
2255
- function Ja(e, t) {
2196
+ function Ha(e, t) {
2256
2197
  if (t) {
2257
2198
  for (const n of Object.values(e))
2258
2199
  if (n.author === t && n.avatarUrl) return n.avatarUrl;
2259
2200
  }
2260
2201
  }
2261
- function Dn({ sprite: e, url: t, alt: n = "", className: r, style: a, fallback: i }) {
2202
+ function Nn({ sprite: e, url: t, alt: n = "", className: r, style: a, fallback: i }) {
2262
2203
  const [s, l] = R(null);
2263
2204
  if (t && t !== s)
2264
2205
  return /* @__PURE__ */ c(
@@ -2273,13 +2214,13 @@ function Dn({ sprite: e, url: t, alt: n = "", className: r, style: a, fallback:
2273
2214
  onError: () => l(t)
2274
2215
  }
2275
2216
  );
2276
- const m = Eo(e);
2277
- return m ? /* @__PURE__ */ c("img", { src: m, alt: n, crossOrigin: "anonymous", className: r, style: a, draggable: !1 }) : /* @__PURE__ */ c(ce, { children: i });
2217
+ const f = Ao(e);
2218
+ return f ? /* @__PURE__ */ c("img", { src: f, alt: n, crossOrigin: "anonymous", className: r, style: a, draggable: !1 }) : /* @__PURE__ */ c(le, { children: i });
2278
2219
  }
2279
- function Za({ sprite: e, url: t, alt: n, worn: r }) {
2220
+ function $a({ sprite: e, url: t, alt: n, worn: r }) {
2280
2221
  return /* @__PURE__ */ v("span", { className: "hc-av", style: { "--hc-sz": "32px" }, children: [
2281
2222
  /* @__PURE__ */ c("span", { className: "hc-pic", children: /* @__PURE__ */ c(
2282
- Dn,
2223
+ Nn,
2283
2224
  {
2284
2225
  sprite: e,
2285
2226
  url: t,
@@ -2288,21 +2229,21 @@ function Za({ sprite: e, url: t, alt: n, worn: r }) {
2288
2229
  fallback: /* @__PURE__ */ c("span", { className: "inline-block w-8 h-8 bg-bg-alt/50 rounded-full flex-shrink-0" })
2289
2230
  }
2290
2231
  ) }),
2291
- r?.overlay && /* @__PURE__ */ c(et, { html: zn(r), style: { display: "contents" } })
2232
+ r?.overlay && /* @__PURE__ */ c(Qe, { html: Yn(r), style: { display: "contents" } })
2292
2233
  ] });
2293
2234
  }
2294
- function Qa(e) {
2235
+ function Ba(e) {
2295
2236
  return !(e.button !== 0 || e.ctrlKey || e.metaKey || e.shiftKey || e.altKey);
2296
2237
  }
2297
- function ei({ src: e, title: t, onClose: n }) {
2238
+ function Ga({ src: e, title: t, onClose: n }) {
2298
2239
  N(() => {
2299
2240
  const i = (s) => {
2300
2241
  s.key === "Escape" && (s.stopPropagation(), n());
2301
2242
  };
2302
2243
  return document.addEventListener("keydown", i, !0), () => document.removeEventListener("keydown", i, !0);
2303
2244
  }, [n]);
2304
- const r = so(), a = typeof document > "u" ? null : document.fullscreenElement ?? r ?? document.body;
2305
- return a ? ir(
2245
+ const r = io(), a = typeof document > "u" ? null : document.fullscreenElement ?? r ?? document.body;
2246
+ return a ? ar(
2306
2247
  /* @__PURE__ */ v(
2307
2248
  "div",
2308
2249
  {
@@ -2340,12 +2281,12 @@ function ei({ src: e, title: t, onClose: n }) {
2340
2281
  a
2341
2282
  ) : null;
2342
2283
  }
2343
- const Ke = 240, ti = 320;
2344
- function ni({ image: e }) {
2345
- const [t, n] = R(!1), r = Re(e.key);
2284
+ const qe = 240, qa = 320;
2285
+ function Va({ image: e }) {
2286
+ const [t, n] = R(!1), r = Pe(e.key);
2346
2287
  if (!r) return null;
2347
- const a = e.w > 0 && e.h > 0, i = a ? Math.min(1, ti / e.w, Ke / e.h) : 1;
2348
- return /* @__PURE__ */ v(ce, { children: [
2288
+ const a = e.w > 0 && e.h > 0, i = a ? Math.min(1, qa / e.w, qe / e.h) : 1;
2289
+ return /* @__PURE__ */ v(le, { children: [
2349
2290
  /* @__PURE__ */ c(
2350
2291
  "a",
2351
2292
  {
@@ -2355,7 +2296,7 @@ function ni({ image: e }) {
2355
2296
  className: "block max-w-full cursor-zoom-in",
2356
2297
  "data-testid": "chat-image",
2357
2298
  onClick: (s) => {
2358
- Qa(s) && (s.preventDefault(), n(!0));
2299
+ Ba(s) && (s.preventDefault(), n(!0));
2359
2300
  },
2360
2301
  children: /* @__PURE__ */ c(
2361
2302
  "img",
@@ -2367,13 +2308,13 @@ function ni({ image: e }) {
2367
2308
  width: a ? Math.round(e.w * i) : void 0,
2368
2309
  height: a ? Math.round(e.h * i) : void 0,
2369
2310
  className: "rounded border border-border-light object-contain bg-bg-alt/30",
2370
- style: a ? { aspectRatio: `${e.w} / ${e.h}`, maxWidth: "100%", maxHeight: Ke } : { maxWidth: "100%", maxHeight: Ke }
2311
+ style: a ? { aspectRatio: `${e.w} / ${e.h}`, maxWidth: "100%", maxHeight: qe } : { maxWidth: "100%", maxHeight: qe }
2371
2312
  }
2372
2313
  )
2373
2314
  }
2374
2315
  ),
2375
2316
  t && /* @__PURE__ */ c(
2376
- ei,
2317
+ Ga,
2377
2318
  {
2378
2319
  src: r,
2379
2320
  title: e.title,
@@ -2382,47 +2323,47 @@ function ni({ image: e }) {
2382
2323
  )
2383
2324
  ] });
2384
2325
  }
2385
- function ri({ images: e }) {
2386
- return e?.length ? /* @__PURE__ */ c("div", { className: "flex flex-wrap gap-1 mt-1", "data-testid": "chat-images", children: e.map((t, n) => /* @__PURE__ */ c(ni, { image: t }, `${t.key}-${n}`)) }) : null;
2326
+ function Ka({ images: e }) {
2327
+ return e?.length ? /* @__PURE__ */ c("div", { className: "flex flex-wrap gap-1 mt-1", "data-testid": "chat-images", children: e.map((t, n) => /* @__PURE__ */ c(Va, { image: t }, `${t.key}-${n}`)) }) : null;
2387
2328
  }
2388
- function oi(e, t) {
2329
+ function Wa(e, t) {
2389
2330
  return e.author && t.author ? e.author === t.author : !!t.clientId && e.clientId === t.clientId;
2390
2331
  }
2391
- function We(e) {
2332
+ function Ve(e) {
2392
2333
  return new Date(e).toLocaleTimeString([], { hour: "2-digit", minute: "2-digit" });
2393
2334
  }
2394
- const ai = Pe.memo(function({ message: t }) {
2395
- const n = f((u) => u.me.clientId), r = f((u) => u.me.clientId ? u.roster[u.me.clientId]?.author : void 0), a = oi(t, { clientId: n, author: r }), i = f((u) => Ja(u.roster, t.author)), s = On(t.sprite, i), l = Vo(t.isSystem ? void 0 : t.author), m = K(null);
2396
- Wo(m, !!l);
2335
+ const Ya = Ne.memo(function({ message: t }) {
2336
+ const n = m((u) => u.me.clientId), r = m((u) => u.me.clientId ? u.roster[u.me.clientId]?.author : void 0), a = Wa(t, { clientId: n, author: r }), i = m((u) => Ha(u.roster, t.author)), s = En(t.sprite, i), l = qo(t.isSystem ? void 0 : t.author), f = K(null);
2337
+ Ko(f, !!l);
2397
2338
  const [h] = R(
2398
- () => t.live && t.text ? Xn(t.text, l) : null
2339
+ () => t.live && t.text ? zn(t.text, l) : null
2399
2340
  );
2400
2341
  return t.isSystem && t.systemType === "recap" ? /* @__PURE__ */ c("div", { className: "px-2 py-1.5", children: /* @__PURE__ */ v("div", { className: "border-l-2 border-border-light pl-2.5 py-0.5", children: [
2401
2342
  /* @__PURE__ */ v("div", { className: "text-[10px] uppercase tracking-wide text-text-muted mb-0.5", children: [
2402
2343
  "Recap",
2403
- /* @__PURE__ */ c("span", { className: "ml-1.5 normal-case tracking-normal opacity-60", children: We(t.ts) })
2344
+ /* @__PURE__ */ c("span", { className: "ml-1.5 normal-case tracking-normal opacity-60", children: Ve(t.ts) })
2404
2345
  ] }),
2405
2346
  /* @__PURE__ */ c("p", { className: "text-[13px] text-text-secondary leading-relaxed whitespace-pre-wrap break-words", children: t.text })
2406
2347
  ] }) }) : t.isSystem ? /* @__PURE__ */ v("div", { className: "px-2 py-0.5 text-[11px] text-text-muted italic text-center leading-tight", children: [
2407
2348
  t.text,
2408
- /* @__PURE__ */ c("span", { className: "ml-1 text-[10px] opacity-50", children: We(t.ts) })
2409
- ] }) : /* @__PURE__ */ v("div", { ref: m, style: Ko(s), className: `flex items-start gap-2 px-2 py-1 hover:bg-bg-card/20 ${a ? "bg-bg-card/30" : ""}`, children: [
2410
- /* @__PURE__ */ c(Za, { sprite: t.sprite, url: i, alt: t.name, worn: l }),
2349
+ /* @__PURE__ */ c("span", { className: "ml-1 text-[10px] opacity-50", children: Ve(t.ts) })
2350
+ ] }) : /* @__PURE__ */ v("div", { ref: f, style: Vo(s), className: `flex items-start gap-2 px-2 py-1 hover:bg-bg-card/20 ${a ? "bg-bg-card/30" : ""}`, children: [
2351
+ /* @__PURE__ */ c($a, { sprite: t.sprite, url: i, alt: t.name, worn: l }),
2411
2352
  /* @__PURE__ */ v("div", { className: "flex-1 min-w-0 -mt-0.5", children: [
2412
- l ? /* @__PURE__ */ c(et, { html: Jn(t.name, l), className: "text-[13px]", style: { color: s } }) : /* @__PURE__ */ c("span", { className: "font-medium text-[13px]", style: { color: s }, children: t.name }),
2413
- /* @__PURE__ */ c("span", { className: "text-[10px] text-text-muted opacity-60 ml-1.5", children: We(t.ts) }),
2414
- t.text && (h ? /* @__PURE__ */ c(et, { as: "p", html: h, className: "text-[13px] text-text break-words leading-snug m-0" }) : /* @__PURE__ */ c("p", { className: "text-[13px] text-text break-words leading-snug m-0", children: t.text })),
2415
- /* @__PURE__ */ c(ri, { images: t.images })
2353
+ l ? /* @__PURE__ */ c(Qe, { html: Xn(t.name, l), className: "text-[13px]", style: { color: s } }) : /* @__PURE__ */ c("span", { className: "font-medium text-[13px]", style: { color: s }, children: t.name }),
2354
+ /* @__PURE__ */ c("span", { className: "text-[10px] text-text-muted opacity-60 ml-1.5", children: Ve(t.ts) }),
2355
+ t.text && (h ? /* @__PURE__ */ c(Qe, { as: "p", html: h, className: "text-[13px] text-text break-words leading-snug m-0" }) : /* @__PURE__ */ c("p", { className: "text-[13px] text-text break-words leading-snug m-0", children: t.text })),
2356
+ /* @__PURE__ */ c(Ka, { images: t.images })
2416
2357
  ] })
2417
2358
  ] });
2418
2359
  });
2419
- function ii() {
2420
- Go();
2421
- const e = f((a) => a.chat), t = K(null), n = K(!1), r = k(() => {
2360
+ function za() {
2361
+ Bo();
2362
+ const e = m((a) => a.chat), t = K(null), n = K(!1), r = E(() => {
2422
2363
  const a = t.current;
2423
2364
  if (!a) return;
2424
- const { scrollHeight: i, scrollTop: s, clientHeight: l } = a, m = i - s - l;
2425
- n.current = m > 40;
2365
+ const { scrollHeight: i, scrollTop: s, clientHeight: l } = a, f = i - s - l;
2366
+ n.current = f > 40;
2426
2367
  }, []);
2427
2368
  return N(() => {
2428
2369
  const a = t.current;
@@ -2433,21 +2374,21 @@ function ii() {
2433
2374
  ref: t,
2434
2375
  onScroll: r,
2435
2376
  className: "flex-1 overflow-y-auto overflow-x-hidden chat-messages",
2436
- children: e.length === 0 ? /* @__PURE__ */ c("div", { className: "p-4 text-xs text-text-muted text-center", children: "No messages yet. Be the first to say something!" }) : /* @__PURE__ */ c(ce, { children: e.map((a, i) => {
2377
+ children: e.length === 0 ? /* @__PURE__ */ c("div", { className: "p-4 text-xs text-text-muted text-center", children: "No messages yet. Be the first to say something!" }) : /* @__PURE__ */ c(le, { children: e.map((a, i) => {
2437
2378
  const s = i > 0 ? e[i - 1] : null, l = s && a.ts - s.ts > 1440 * 60 * 1e3;
2438
- return /* @__PURE__ */ v(Pe.Fragment, { children: [
2379
+ return /* @__PURE__ */ v(Ne.Fragment, { children: [
2439
2380
  l && /* @__PURE__ */ v("div", { className: "flex items-center gap-2 px-4 py-2 my-1", children: [
2440
2381
  /* @__PURE__ */ c("div", { className: "flex-1 h-px bg-border" }),
2441
2382
  /* @__PURE__ */ c("span", { className: "text-[10px] text-text-muted whitespace-nowrap", children: new Date(a.ts).toLocaleDateString([], { weekday: "short", month: "short", day: "numeric" }) }),
2442
2383
  /* @__PURE__ */ c("div", { className: "flex-1 h-px bg-border" })
2443
2384
  ] }),
2444
- /* @__PURE__ */ c(ai, { message: a })
2385
+ /* @__PURE__ */ c(Ya, { message: a })
2445
2386
  ] }, a.id);
2446
2387
  }) })
2447
2388
  }
2448
2389
  );
2449
2390
  }
2450
- const vt = [
2391
+ const ht = [
2451
2392
  {
2452
2393
  name: "recap",
2453
2394
  description: "Summarise the previous episode of what is loaded",
@@ -2467,13 +2408,13 @@ const vt = [
2467
2408
  usage: "/help",
2468
2409
  scope: "local"
2469
2410
  }
2470
- ], te = "/";
2471
- function si(e) {
2472
- if (!e.startsWith(te)) return null;
2473
- const t = e.slice(te.length);
2411
+ ], ee = "/";
2412
+ function Xa(e) {
2413
+ if (!e.startsWith(ee)) return null;
2414
+ const t = e.slice(ee.length);
2474
2415
  return /\s/.test(t) ? null : t.toLowerCase();
2475
2416
  }
2476
- function li(e, t = vt) {
2417
+ function Ja(e, t = ht) {
2477
2418
  const n = e.toLowerCase();
2478
2419
  if (!n) return [...t].sort((a, i) => a.name.localeCompare(i.name));
2479
2420
  const r = [];
@@ -2483,23 +2424,23 @@ function li(e, t = vt) {
2483
2424
  }
2484
2425
  return r.sort((a, i) => a.rank - i.rank || a.cmd.name.localeCompare(i.cmd.name)).map((a) => a.cmd);
2485
2426
  }
2486
- function ci(e) {
2487
- return `${te}${e.name} `;
2427
+ function Qa(e) {
2428
+ return `${ee}${e.name} `;
2488
2429
  }
2489
- function Ye(e, t) {
2430
+ function Ke(e, t) {
2490
2431
  return t <= 0 ? 0 : (e % t + t) % t;
2491
2432
  }
2492
- function di(e, t = vt) {
2433
+ function Za(e, t = ht) {
2493
2434
  const n = e.trim();
2494
2435
  if (!n) return null;
2495
- if (!n.startsWith(te)) return { kind: "chat", text: n };
2496
- const r = n.slice(te.length), a = r.search(/\s/), i = (a === -1 ? r : r.slice(0, a)).toLowerCase(), s = a === -1 ? "" : r.slice(a).trim(), l = t.find((m) => m.name.toLowerCase() === i);
2436
+ if (!n.startsWith(ee)) return { kind: "chat", text: n };
2437
+ const r = n.slice(ee.length), a = r.search(/\s/), i = (a === -1 ? r : r.slice(0, a)).toLowerCase(), s = a === -1 ? "" : r.slice(a).trim(), l = t.find((f) => f.name.toLowerCase() === i);
2497
2438
  return l ? { kind: "command", command: l, args: s } : { kind: "chat", text: n };
2498
2439
  }
2499
- function ui(e, t) {
2500
- return e.requiresMedia && !t.hasMedia ? `${te}${e.name} needs an episode loaded.` : null;
2440
+ function ei(e, t) {
2441
+ return e.requiresMedia && !t.hasMedia ? `${ee}${e.name} needs an episode loaded.` : null;
2501
2442
  }
2502
- function mi({
2443
+ function ti({
2503
2444
  commands: e,
2504
2445
  activeIndex: t,
2505
2446
  hasMedia: n,
@@ -2517,22 +2458,22 @@ function mi({
2517
2458
  bg-bg-card border border-border-light rounded shadow-lg
2518
2459
  list-none m-0 p-0 py-1 mb-1`,
2519
2460
  children: e.map((s, l) => {
2520
- const m = !!s.requiresMedia && !n, h = l === t;
2461
+ const f = !!s.requiresMedia && !n, h = l === t;
2521
2462
  return /* @__PURE__ */ v(
2522
2463
  "li",
2523
2464
  {
2524
2465
  id: `${i}-opt-${s.name}`,
2525
2466
  role: "option",
2526
2467
  "aria-selected": h,
2527
- "aria-disabled": m,
2468
+ "aria-disabled": f,
2528
2469
  onMouseDown: (u) => {
2529
2470
  u.preventDefault(), r(s);
2530
2471
  },
2531
2472
  onMouseEnter: () => a(l),
2532
- className: `px-3 py-1.5 cursor-pointer flex items-baseline gap-2 ${h ? "bg-bg-alt" : ""} ${m ? "opacity-50" : ""}`,
2473
+ className: `px-3 py-1.5 cursor-pointer flex items-baseline gap-2 ${h ? "bg-bg-alt" : ""} ${f ? "opacity-50" : ""}`,
2533
2474
  children: [
2534
2475
  /* @__PURE__ */ c("span", { className: "text-sm font-semibold text-text shrink-0", children: s.usage }),
2535
- /* @__PURE__ */ c("span", { className: "text-xs text-text-secondary truncate", children: m ? "needs an episode loaded" : s.description })
2476
+ /* @__PURE__ */ c("span", { className: "text-xs text-text-secondary truncate", children: f ? "needs an episode loaded" : s.description })
2536
2477
  ]
2537
2478
  },
2538
2479
  s.name
@@ -2541,7 +2482,7 @@ function mi({
2541
2482
  }
2542
2483
  );
2543
2484
  }
2544
- function fi({
2485
+ function ni({
2545
2486
  pending: e,
2546
2487
  uploading: t,
2547
2488
  onRemove: n
@@ -2568,48 +2509,48 @@ function fi({
2568
2509
  )
2569
2510
  ] }, r.id)) }) : null;
2570
2511
  }
2571
- function pi() {
2572
- const [e, t] = R([]), [n, r] = R(!1), a = f((p) => p.pushToast), i = K(/* @__PURE__ */ new Set());
2512
+ function ri() {
2513
+ const [e, t] = R([]), [n, r] = R(!1), a = m((p) => p.pushToast), i = K(/* @__PURE__ */ new Set());
2573
2514
  N(() => () => {
2574
2515
  for (const p of i.current) URL.revokeObjectURL(p);
2575
2516
  i.current.clear();
2576
2517
  }, []);
2577
- const s = k((p) => {
2578
- qr(p) && (URL.revokeObjectURL(p.previewUrl), i.current.delete(p.previewUrl));
2579
- }, []), l = k(async (p) => {
2518
+ const s = E((p) => {
2519
+ Gr(p) && (URL.revokeObjectURL(p.previewUrl), i.current.delete(p.previewUrl));
2520
+ }, []), l = E(async (p) => {
2580
2521
  if (!p.length) return;
2581
2522
  const S = [];
2582
2523
  for (const b of p) {
2583
- const I = Kr(b);
2584
- if (I) {
2585
- a("error", I);
2524
+ const C = Vr(b);
2525
+ if (C) {
2526
+ a("error", C);
2586
2527
  continue;
2587
2528
  }
2588
- const { w: g, h: E } = await zr(b), O = URL.createObjectURL(b);
2529
+ const { w: g, h: k } = await Yr(b), O = URL.createObjectURL(b);
2589
2530
  i.current.add(O), S.push({
2590
2531
  kind: "file",
2591
2532
  id: `${Date.now()}-${Math.random().toString(36).slice(2, 8)}`,
2592
2533
  file: b,
2593
2534
  previewUrl: O,
2594
2535
  w: g,
2595
- h: E
2536
+ h: k
2596
2537
  });
2597
2538
  }
2598
2539
  S.length && t((b) => {
2599
- const I = Y - b.length;
2600
- if (I <= 0) {
2540
+ const C = Y - b.length;
2541
+ if (C <= 0) {
2601
2542
  a("info", `Up to ${Y} images per message`);
2602
2543
  for (const g of S) s(g);
2603
2544
  return b;
2604
2545
  }
2605
- if (S.length > I) {
2546
+ if (S.length > C) {
2606
2547
  a("info", `Up to ${Y} images per message`);
2607
- for (const g of S.slice(I)) s(g);
2548
+ for (const g of S.slice(C)) s(g);
2608
2549
  }
2609
- return [...b, ...S.slice(0, I)];
2550
+ return [...b, ...S.slice(0, C)];
2610
2551
  });
2611
- }, [a, s]), m = k((p) => {
2612
- const S = Re(p.key);
2552
+ }, [a, s]), f = E((p) => {
2553
+ const S = Pe(p.key);
2613
2554
  S && (t((b) => b.length >= Y ? (a("info", `Up to ${Y} images per message`), b) : [...b, {
2614
2555
  kind: "remote",
2615
2556
  id: `${Date.now()}-${Math.random().toString(36).slice(2, 8)}`,
@@ -2620,32 +2561,32 @@ function pi() {
2620
2561
  w: p.width ?? 0,
2621
2562
  h: p.height ?? 0,
2622
2563
  title: p.title || void 0
2623
- }]), Ue().catalogue(fn).recordUse(p.key));
2624
- }, [a]), h = k((p) => {
2564
+ }]), je().catalogue(cn).recordUse(p.key));
2565
+ }, [a]), h = E((p) => {
2625
2566
  t((S) => {
2626
- const b = S.find((I) => I.id === p);
2627
- return b && s(b), S.filter((I) => I.id !== p);
2567
+ const b = S.find((C) => C.id === p);
2568
+ return b && s(b), S.filter((C) => C.id !== p);
2628
2569
  });
2629
- }, [s]), u = k(() => {
2570
+ }, [s]), u = E(() => {
2630
2571
  t((p) => {
2631
2572
  for (const S of p) s(S);
2632
2573
  return [];
2633
2574
  });
2634
- }, [s]), D = k((p) => {
2635
- const S = Wr(p.clipboardData);
2575
+ }, [s]), j = E((p) => {
2576
+ const S = Kr(p.clipboardData);
2636
2577
  S.length && (p.preventDefault(), l(S));
2637
- }, [l]), M = k((p) => {
2638
- const S = Yr(p.dataTransfer);
2578
+ }, [l]), D = E((p) => {
2579
+ const S = Wr(p.dataTransfer);
2639
2580
  S.length && (p.preventDefault(), l(S));
2640
- }, [l]), L = k((p) => {
2581
+ }, [l]), M = E((p) => {
2641
2582
  p.dataTransfer?.types?.includes("Files") && p.preventDefault();
2642
- }, []), C = k(async () => {
2583
+ }, []), I = E(async () => {
2643
2584
  if (!e.length) return [];
2644
2585
  r(!0);
2645
2586
  try {
2646
- return await Jr(e);
2587
+ return await Xr(e);
2647
2588
  } catch (p) {
2648
- return A("chat", "Image upload failed", Zr(p)), a("error", Vr(p)), null;
2589
+ return A("chat", "Image upload failed", Jr(p)), a("error", qr(p)), null;
2649
2590
  } finally {
2650
2591
  r(!1);
2651
2592
  }
@@ -2654,47 +2595,47 @@ function pi() {
2654
2595
  pending: e,
2655
2596
  uploading: n,
2656
2597
  addFiles: l,
2657
- addMeme: m,
2598
+ addMeme: f,
2658
2599
  remove: h,
2659
2600
  clear: u,
2660
- uploadPending: C,
2661
- onPaste: D,
2662
- onDrop: M,
2663
- onDragOver: L
2601
+ uploadPending: I,
2602
+ onPaste: j,
2603
+ onDrop: D,
2604
+ onDragOver: M
2664
2605
  };
2665
2606
  }
2666
- const Gt = Jt, hi = cr;
2667
- function gi({ commands: e = vt }) {
2668
- const [t, n] = R(""), [r, a] = R(!1), [i, s] = R({ q: null, i: 0 }), [l, m] = R(!1), h = K(null), u = jn(), [D, M] = R(!1), [L, C] = R(!1), p = pi(), S = f((y) => y.snapshot.mediaId), b = f((y) => y.pushToast), I = f((y) => y.setTierlistOpen), g = !!S, E = si(t), O = J(
2669
- () => E === null ? [] : li(E, e),
2670
- [E, e]
2671
- ), j = E !== null && !l && O.length > 0, F = i.q === E ? Ye(i.i, O.length) : 0, x = k(
2672
- (y) => s({ q: E, i: y }),
2673
- [E]
2674
- ), P = k((y, U) => {
2675
- const oe = ui(y, { hasMedia: g });
2676
- if (oe) {
2677
- b("info", oe);
2607
+ const Ft = Wt, oi = lr;
2608
+ function ai({ commands: e = ht }) {
2609
+ const [t, n] = R(""), [r, a] = R(!1), [i, s] = R({ q: null, i: 0 }), [l, f] = R(!1), h = K(null), u = On(), [j, D] = R(!1), [M, I] = R(!1), p = ri(), S = m((y) => y.snapshot.mediaId), b = m((y) => y.pushToast), C = m((y) => y.setTierlistOpen), g = !!S, k = Xa(t), O = J(
2610
+ () => k === null ? [] : Ja(k, e),
2611
+ [k, e]
2612
+ ), L = k !== null && !l && O.length > 0, F = i.q === k ? Ke(i.i, O.length) : 0, x = E(
2613
+ (y) => s({ q: k, i: y }),
2614
+ [k]
2615
+ ), P = E((y, U) => {
2616
+ const re = ei(y, { hasMedia: g });
2617
+ if (re) {
2618
+ b("info", re);
2678
2619
  return;
2679
2620
  }
2680
2621
  switch (y.name) {
2681
2622
  case "help":
2682
- b("info", e.map((Mn) => Mn.usage).join(" "));
2623
+ b("info", e.map((Pn) => Pn.usage).join(" "));
2683
2624
  break;
2684
2625
  case "recap":
2685
- Ua();
2626
+ ja();
2686
2627
  break;
2687
2628
  case "tierlist":
2688
- Zo(), I(!0);
2629
+ Jo(), C(!0);
2689
2630
  break;
2690
2631
  default:
2691
2632
  b("info", `${y.usage} is not implemented yet.`);
2692
2633
  }
2693
- }, [g, b, e, I]), T = k((y) => {
2694
- n(ci(y)), m(!1), h.current?.focus();
2695
- }, []), he = k(async (y) => {
2634
+ }, [g, b, e, C]), T = E((y) => {
2635
+ n(Qa(y)), f(!1), h.current?.focus();
2636
+ }, []), pe = E(async (y) => {
2696
2637
  if (y.preventDefault(), r || p.uploading) return;
2697
- const U = di(t, e);
2638
+ const U = Za(t, e);
2698
2639
  if (!U && !p.pending.length) return;
2699
2640
  if (U?.kind === "command" && p.pending.length) {
2700
2641
  b("info", "Send images on their own, not with a command.");
@@ -2704,18 +2645,18 @@ function gi({ commands: e = vt }) {
2704
2645
  P(U.command, U.args), n(""), !document.hidden && document.hasFocus() && h.current?.focus();
2705
2646
  return;
2706
2647
  }
2707
- const oe = await p.uploadPending();
2708
- oe !== null && (Da(U?.text ?? "", oe), n(""), p.clear(), a(!0), setTimeout(() => a(!1), hi), !document.hidden && document.hasFocus() && h.current?.focus());
2709
- }, [t, r, P, p, b, e]), ge = k((y) => {
2710
- if (y.key === "Escape" && j) {
2711
- y.preventDefault(), m(!0);
2648
+ const re = await p.uploadPending();
2649
+ re !== null && (Oa(U?.text ?? "", re), n(""), p.clear(), a(!0), setTimeout(() => a(!1), oi), !document.hidden && document.hasFocus() && h.current?.focus());
2650
+ }, [t, r, P, p, b, e]), he = E((y) => {
2651
+ if (y.key === "Escape" && L) {
2652
+ y.preventDefault(), f(!0);
2712
2653
  return;
2713
2654
  }
2714
- if (j) {
2655
+ if (L) {
2715
2656
  if (y.key === "ArrowDown")
2716
- y.preventDefault(), x(Ye(F + 1, O.length));
2657
+ y.preventDefault(), x(Ke(F + 1, O.length));
2717
2658
  else if (y.key === "ArrowUp")
2718
- y.preventDefault(), x(Ye(F - 1, O.length));
2659
+ y.preventDefault(), x(Ke(F - 1, O.length));
2719
2660
  else if (y.key === "Tab") {
2720
2661
  y.preventDefault();
2721
2662
  const U = O[F];
@@ -2726,29 +2667,29 @@ function gi({ commands: e = vt }) {
2726
2667
  U && T(U);
2727
2668
  }
2728
2669
  }
2729
- }, [j, O, F, T, x]);
2670
+ }, [L, O, F, T, x]);
2730
2671
  N(() => {
2731
2672
  const y = () => {
2732
2673
  document.hidden || !document.hasFocus() || (h.current?.focus(), h.current?.scrollIntoView({ block: "nearest" }));
2733
2674
  };
2734
2675
  return window.addEventListener("watchparty:focus-chat-input", y), () => window.removeEventListener("watchparty:focus-chat-input", y);
2735
2676
  }, []);
2736
- const ye = Gt - t.length, St = ye <= 100, wt = j ? O[F] : void 0;
2677
+ const ge = Ft - t.length, gt = ge <= 100, yt = L ? O[F] : void 0;
2737
2678
  return /* @__PURE__ */ v(
2738
2679
  "form",
2739
2680
  {
2740
2681
  onSubmit: (y) => {
2741
- he(y);
2682
+ pe(y);
2742
2683
  },
2743
2684
  onPaste: p.onPaste,
2744
2685
  onDrop: p.onDrop,
2745
2686
  onDragOver: p.onDragOver,
2746
2687
  className: "p-2 border-t border-border",
2747
2688
  children: [
2748
- /* @__PURE__ */ c(fi, { pending: p.pending, uploading: p.uploading, onRemove: p.remove }),
2689
+ /* @__PURE__ */ c(ni, { pending: p.pending, uploading: p.uploading, onRemove: p.remove }),
2749
2690
  /* @__PURE__ */ v("div", { className: "relative", children: [
2750
- j && /* @__PURE__ */ c(
2751
- mi,
2691
+ L && /* @__PURE__ */ c(
2692
+ ti,
2752
2693
  {
2753
2694
  commands: O,
2754
2695
  activeIndex: F,
@@ -2759,13 +2700,13 @@ function gi({ commands: e = vt }) {
2759
2700
  }
2760
2701
  ),
2761
2702
  /* @__PURE__ */ c(
2762
- ro,
2703
+ no,
2763
2704
  {
2764
- open: D,
2765
- onClose: () => M(!1),
2705
+ open: j,
2706
+ onClose: () => D(!1),
2766
2707
  onPick: p.addMeme,
2767
2708
  onUnavailable: () => {
2768
- C(!0), M(!1);
2709
+ I(!0), D(!1);
2769
2710
  }
2770
2711
  }
2771
2712
  ),
@@ -2778,32 +2719,32 @@ function gi({ commands: e = vt }) {
2778
2719
  type: "text",
2779
2720
  value: t,
2780
2721
  onChange: (y) => {
2781
- n(y.target.value), m(!1);
2722
+ n(y.target.value), f(!1);
2782
2723
  },
2783
- onKeyDown: ge,
2784
- maxLength: Gt,
2724
+ onKeyDown: he,
2725
+ maxLength: Ft,
2785
2726
  placeholder: "Send a message",
2786
2727
  role: "combobox",
2787
- "aria-expanded": j,
2788
- "aria-controls": j ? u : void 0,
2789
- "aria-activedescendant": wt ? `${u}-opt-${wt.name}` : void 0,
2728
+ "aria-expanded": L,
2729
+ "aria-controls": L ? u : void 0,
2730
+ "aria-activedescendant": yt ? `${u}-opt-${yt.name}` : void 0,
2790
2731
  "aria-autocomplete": "list",
2791
- className: `w-full bg-bg-card border border-border-light rounded px-3 py-1.5 text-sm focus:outline-none focus:border-text-muted ${St ? "pr-12" : ""}`
2732
+ className: `w-full bg-bg-card border border-border-light rounded px-3 py-1.5 text-sm focus:outline-none focus:border-text-muted ${gt ? "pr-12" : ""}`
2792
2733
  }
2793
2734
  ),
2794
- /* @__PURE__ */ c("span", { className: `absolute right-2 top-1/2 -translate-y-1/2 text-[10px] ${ye <= 50 ? ye <= 0 ? "bg-danger-bg text-on-danger-bg px-1 rounded" : "bg-primary-bg text-on-primary-bg px-1 rounded" : "text-text-muted"}`, children: St && ye })
2735
+ /* @__PURE__ */ c("span", { className: `absolute right-2 top-1/2 -translate-y-1/2 text-[10px] ${ge <= 50 ? ge <= 0 ? "bg-danger-bg text-on-danger-bg px-1 rounded" : "bg-primary-bg text-on-primary-bg px-1 rounded" : "text-text-muted"}`, children: gt && ge })
2795
2736
  ] }),
2796
- !L && /* @__PURE__ */ c(
2737
+ !M && /* @__PURE__ */ c(
2797
2738
  "button",
2798
2739
  {
2799
2740
  type: "button",
2800
- onClick: () => M((y) => !y),
2741
+ onClick: () => D((y) => !y),
2801
2742
  "aria-label": "Add a meme",
2802
- "aria-expanded": D,
2743
+ "aria-expanded": j,
2803
2744
  title: "Add a meme",
2804
2745
  "data-testid": "meme-button",
2805
- className: `shrink-0 rounded border border-border-light px-2 py-1.5 text-sm hover:border-primary ${D ? "text-text border-primary" : "text-text-secondary"}`,
2806
- children: /* @__PURE__ */ c(Un, { name: "image" })
2746
+ className: `shrink-0 rounded border border-border-light px-2 py-1.5 text-sm hover:border-primary ${j ? "text-text border-primary" : "text-text-secondary"}`,
2747
+ children: /* @__PURE__ */ c(Dn, { name: "image" })
2807
2748
  }
2808
2749
  )
2809
2750
  ] })
@@ -2812,15 +2753,15 @@ function gi({ commands: e = vt }) {
2812
2753
  }
2813
2754
  );
2814
2755
  }
2815
- function yi() {
2816
- const e = f((n) => n.roster), t = Object.values(e);
2817
- return t.length ? /* @__PURE__ */ c("div", { className: "flex flex-col gap-1", children: t.map((n) => /* @__PURE__ */ c(bi, { u: n }, n.clientId)) }) : /* @__PURE__ */ c("div", { className: "text-xs text-text-muted", children: "No users online" });
2756
+ function ii() {
2757
+ const e = m((n) => n.roster), t = Object.values(e);
2758
+ return t.length ? /* @__PURE__ */ c("div", { className: "flex flex-col gap-1", children: t.map((n) => /* @__PURE__ */ c(si, { u: n }, n.clientId)) }) : /* @__PURE__ */ c("div", { className: "text-xs text-text-muted", children: "No users online" });
2818
2759
  }
2819
- function bi({ u: e }) {
2820
- const t = On(e.sprite, e.avatarUrl);
2760
+ function si({ u: e }) {
2761
+ const t = En(e.sprite, e.avatarUrl);
2821
2762
  return /* @__PURE__ */ v("div", { className: "flex items-center gap-2 py-0.5", children: [
2822
2763
  /* @__PURE__ */ c(
2823
- Dn,
2764
+ Nn,
2824
2765
  {
2825
2766
  sprite: e.sprite,
2826
2767
  url: e.avatarUrl,
@@ -2833,8 +2774,8 @@ function bi({ u: e }) {
2833
2774
  e.isLeader && /* @__PURE__ */ c("span", { className: "ml-auto px-1.5 py-0.5 rounded text-[9px] font-medium bg-success/20 text-success", children: "Leader" })
2834
2775
  ] });
2835
2776
  }
2836
- function vi() {
2837
- const e = f((a) => Object.keys(a.roster).length), [t, n] = R(!1), r = K(null);
2777
+ function li() {
2778
+ const e = m((a) => Object.keys(a.roster).length), [t, n] = R(!1), r = K(null);
2838
2779
  return N(() => {
2839
2780
  if (!t) return;
2840
2781
  function a(i) {
@@ -2861,12 +2802,12 @@ function vi() {
2861
2802
  e,
2862
2803
  " online"
2863
2804
  ] }),
2864
- /* @__PURE__ */ c(yi, {})
2805
+ /* @__PURE__ */ c(ii, {})
2865
2806
  ] })
2866
2807
  ] });
2867
2808
  }
2868
- function qt({ className: e = "fixed bottom-4 left-1/2 -translate-x-1/2" }) {
2869
- const t = f((r) => r.toasts), n = f((r) => r.popToast);
2809
+ function Ht({ className: e = "fixed bottom-4 left-1/2 -translate-x-1/2" }) {
2810
+ const t = m((r) => r.toasts), n = m((r) => r.popToast);
2870
2811
  return N(() => {
2871
2812
  const r = t.map((a) => setTimeout(() => n(a.id), 4e3));
2872
2813
  return () => {
@@ -2874,39 +2815,39 @@ function qt({ className: e = "fixed bottom-4 left-1/2 -translate-x-1/2" }) {
2874
2815
  };
2875
2816
  }, [t, n]), /* @__PURE__ */ c("div", { className: `${e} flex flex-col gap-2 z-50`, children: t.map((r) => /* @__PURE__ */ c("div", { className: `px-3 py-2 rounded text-sm shadow font-medium border ${r.kind === "error" ? "bg-danger-bg text-on-danger-bg border-danger" : "bg-bg-card border-border-light text-text"}`, children: r.msg }, r.id)) });
2876
2817
  }
2877
- const Vt = (e) => typeof e == "string" && Fn.includes(e);
2878
- function Si(e, t, n) {
2879
- return e || (Vt(t) ? t : Vt(n) ? n : "dark");
2818
+ const $t = (e) => typeof e == "string" && Mn.includes(e);
2819
+ function ci(e, t, n) {
2820
+ return e || ($t(t) ? t : $t(n) ? n : "dark");
2880
2821
  }
2881
- function wi(e, t) {
2822
+ function di(e, t) {
2882
2823
  if (t(e.clientWidth), typeof ResizeObserver > "u") return () => {
2883
2824
  };
2884
2825
  const n = new ResizeObserver(() => t(e.clientWidth));
2885
2826
  return n.observe(e), () => n.disconnect();
2886
2827
  }
2887
- function _i(e) {
2828
+ function ui(e) {
2888
2829
  const t = e?.trim() ?? "";
2889
2830
  return t ? { source: "host", name: t } : { source: "auto" };
2890
2831
  }
2891
- function xi(e) {
2832
+ function mi(e) {
2892
2833
  if (e.source !== "host") return;
2893
- const { setSessionIdentity: t, sprite: n } = f.getState();
2834
+ const { setSessionIdentity: t, sprite: n } = m.getState();
2894
2835
  t(e.name, n);
2895
2836
  }
2896
- function Ii({ className: e = "w-4 h-4" }) {
2837
+ function fi({ className: e = "w-4 h-4" }) {
2897
2838
  return /* @__PURE__ */ v("svg", { className: e, viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: 2, children: [
2898
2839
  /* @__PURE__ */ c("path", { strokeLinecap: "round", strokeLinejoin: "round", d: "M4 4v16" }),
2899
2840
  /* @__PURE__ */ c("path", { strokeLinecap: "round", strokeLinejoin: "round", d: "M15 12l-5 4v-8l5 4z" })
2900
2841
  ] });
2901
2842
  }
2902
- function Ci({ className: e = "w-4 h-4" }) {
2843
+ function pi({ className: e = "w-4 h-4" }) {
2903
2844
  return /* @__PURE__ */ v("svg", { className: e, viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: 2, children: [
2904
2845
  /* @__PURE__ */ c("path", { strokeLinecap: "round", strokeLinejoin: "round", d: "M20 4v16" }),
2905
2846
  /* @__PURE__ */ c("path", { strokeLinecap: "round", strokeLinejoin: "round", d: "M9 12l5 4v-8l-5 4z" })
2906
2847
  ] });
2907
2848
  }
2908
- const Ti = 1500;
2909
- function $i({
2849
+ const hi = 1500;
2850
+ function Ni({
2910
2851
  roomKey: e,
2911
2852
  serverOrigin: t,
2912
2853
  userType: n,
@@ -2915,102 +2856,102 @@ function $i({
2915
2856
  name: i,
2916
2857
  onLeave: s,
2917
2858
  onLayoutChange: l,
2918
- collapsible: m = !0,
2859
+ collapsible: f = !0,
2919
2860
  debug: h,
2920
2861
  children: u
2921
2862
  }) {
2922
- const [D, M] = R(null), { setFrame: L, ...C } = Ai(l, m), p = Wt(() => i), S = J(() => (No({ userType: n, userId: r ?? null }), ht().theme), [n, r]), b = Hn(), I = b?.theme, g = J(
2923
- () => Si(a, I, S),
2924
- [a, I, S]
2863
+ const [j, D] = R(null), { setFrame: M, ...I } = gi(l, f), p = Gt(() => i), S = J(() => (Eo({ userType: n, userId: r ?? null }), ut().theme), [n, r]), b = Ln(), C = b?.theme, g = J(
2864
+ () => ci(a, C, S),
2865
+ [a, C, S]
2925
2866
  );
2926
2867
  N(() => {
2927
2868
  }, [a, b !== null]);
2928
2869
  const O = J(
2929
- () => ({ ...dt, serverOrigin: t, defaultRoomKey: e }),
2870
+ () => ({ ...it, serverOrigin: t, defaultRoomKey: e }),
2930
2871
  [t, e]
2931
2872
  );
2932
2873
  return N(() => {
2933
- h && uo();
2934
- }, [h]), Fa(), N(() => {
2935
- oo({ serverOrigin: t, defaultRoomKey: e }), f.getState().rehydrateFromPrefs(), ua();
2936
- let j = !1;
2874
+ h && co();
2875
+ }, [h]), Ua(), N(() => {
2876
+ ro({ serverOrigin: t, defaultRoomKey: e }), m.getState().rehydrateFromPrefs(), da();
2877
+ let L = !1;
2937
2878
  const F = ko();
2938
2879
  return (async () => {
2939
2880
  try {
2940
2881
  await Promise.race([
2941
2882
  Promise.all([
2942
2883
  F,
2943
- jo().then((T) => {
2944
- T && f.getState().rehydrateFromPrefs();
2884
+ Lo().then((T) => {
2885
+ T && m.getState().rehydrateFromPrefs();
2945
2886
  }),
2946
2887
  // The character chosen in the settings popout (lib/avatar.ts).
2947
- ta().then(Rn)
2888
+ ea().then(kn)
2948
2889
  ]),
2949
- new Promise((T) => setTimeout(T, Ti))
2890
+ new Promise((T) => setTimeout(T, hi))
2950
2891
  ]);
2951
2892
  } catch (T) {
2952
- A("room-chrome", "pre-join wait threw, proceeding anyway", pe(T));
2893
+ A("room-chrome", "pre-join wait threw, proceeding anyway", fe(T));
2953
2894
  }
2954
- if (j) return;
2955
- const x = _i(p());
2956
- f.getState().ensureAutoIdentity(), xi(x);
2957
- const P = f.getState();
2958
- d("room-chrome", "Joining room", { roomKey: e, name: P.name, sprite: P.sprite }), wa({ room_key: e, name: P.name || void 0, sprite: P.sprite || void 0 });
2895
+ if (L) return;
2896
+ const x = ui(p());
2897
+ m.getState().ensureAutoIdentity(), mi(x);
2898
+ const P = m.getState();
2899
+ d("room-chrome", "Joining room", { roomKey: e, name: P.name, sprite: P.sprite }), Sa({ room_key: e, name: P.name || void 0, sprite: P.sprite || void 0 });
2959
2900
  })(), () => {
2960
- j = !0, Bt();
2901
+ L = !0, Ut();
2961
2902
  };
2962
- }, [e, t, n, r]), /* @__PURE__ */ c(ao.Provider, { value: O, children: /* @__PURE__ */ c(En.Provider, { value: !1, children: /* @__PURE__ */ c(hn.Provider, { value: D, children: /* @__PURE__ */ v("div", { ref: L, className: "wp-room-chrome-frame", children: [
2903
+ }, [e, t, n, r]), /* @__PURE__ */ c(oo.Provider, { value: O, children: /* @__PURE__ */ c(Cn.Provider, { value: !1, children: /* @__PURE__ */ c(un.Provider, { value: j, children: /* @__PURE__ */ v("div", { ref: M, className: "wp-room-chrome-frame", children: [
2963
2904
  /* @__PURE__ */ c("div", { className: "wp-room-chrome-frame__content", children: u }),
2964
2905
  /* @__PURE__ */ c(
2965
2906
  "aside",
2966
2907
  {
2967
- ref: M,
2908
+ ref: D,
2968
2909
  className: "wp-room-chrome",
2969
2910
  "data-theme": g,
2970
- "data-collapsed": C.collapsed ? "1" : "0",
2971
- style: { "--wp-room-chrome-width": `${C.state.width}px` },
2972
- onAnimationEnd: (j) => Zn(j.nativeEvent),
2973
- children: C.collapsed ? /* @__PURE__ */ v(ce, { children: [
2911
+ "data-collapsed": I.collapsed ? "1" : "0",
2912
+ style: { "--wp-room-chrome-width": `${I.state.width}px` },
2913
+ onAnimationEnd: (L) => Jn(L.nativeEvent),
2914
+ children: I.collapsed ? /* @__PURE__ */ v(le, { children: [
2974
2915
  /* @__PURE__ */ c(
2975
2916
  "button",
2976
2917
  {
2977
- onClick: C.toggleCollapsed,
2918
+ onClick: I.toggleCollapsed,
2978
2919
  className: "wp-room-chrome__icon-btn",
2979
2920
  title: "Show chat",
2980
2921
  "aria-label": "Show chat",
2981
2922
  "aria-expanded": !1,
2982
- children: /* @__PURE__ */ c(Ci, {})
2923
+ children: /* @__PURE__ */ c(pi, {})
2983
2924
  }
2984
2925
  ),
2985
- /* @__PURE__ */ c(qt, { className: "absolute bottom-2 right-full mr-2 w-72" })
2986
- ] }) : /* @__PURE__ */ v(ce, { children: [
2926
+ /* @__PURE__ */ c(Ht, { className: "absolute bottom-2 right-full mr-2 w-72" })
2927
+ ] }) : /* @__PURE__ */ v(le, { children: [
2987
2928
  /* @__PURE__ */ c(
2988
2929
  "div",
2989
2930
  {
2990
2931
  role: "separator",
2991
2932
  "aria-orientation": "vertical",
2992
2933
  "aria-label": "Resize chat",
2993
- "aria-valuemin": Le,
2994
- "aria-valuemax": gt,
2995
- "aria-valuenow": C.state.width,
2934
+ "aria-valuemin": Me,
2935
+ "aria-valuemax": mt,
2936
+ "aria-valuenow": I.state.width,
2996
2937
  tabIndex: 0,
2997
2938
  className: "wp-room-chrome__resize",
2998
- "data-dragging": C.dragging ? "1" : "0",
2999
- onPointerDown: C.onPointerDown,
3000
- onPointerMove: C.onPointerMove,
3001
- onPointerUp: C.onPointerEnd,
3002
- onPointerCancel: C.onPointerEnd,
3003
- onKeyDown: C.onKeyDown
2939
+ "data-dragging": I.dragging ? "1" : "0",
2940
+ onPointerDown: I.onPointerDown,
2941
+ onPointerMove: I.onPointerMove,
2942
+ onPointerUp: I.onPointerEnd,
2943
+ onPointerCancel: I.onPointerEnd,
2944
+ onKeyDown: I.onKeyDown
3004
2945
  }
3005
2946
  ),
3006
2947
  /* @__PURE__ */ v("div", { className: "flex items-center gap-1 px-2 py-1.5 border-b border-border", children: [
3007
- /* @__PURE__ */ c(vi, {}),
2948
+ /* @__PURE__ */ c(li, {}),
3008
2949
  /* @__PURE__ */ c("div", { className: "flex-1" }),
3009
2950
  s && /* @__PURE__ */ c(
3010
2951
  "button",
3011
2952
  {
3012
2953
  onClick: () => {
3013
- Bt(), s();
2954
+ Ut(), s();
3014
2955
  },
3015
2956
  className: "wp-room-chrome__leave",
3016
2957
  title: "Leave room",
@@ -3018,59 +2959,59 @@ function $i({
3018
2959
  children: "Leave"
3019
2960
  }
3020
2961
  ),
3021
- m && /* @__PURE__ */ c(
2962
+ f && /* @__PURE__ */ c(
3022
2963
  "button",
3023
2964
  {
3024
- onClick: C.toggleCollapsed,
2965
+ onClick: I.toggleCollapsed,
3025
2966
  className: "wp-room-chrome__icon-btn",
3026
2967
  title: "Hide chat",
3027
2968
  "aria-label": "Hide chat",
3028
2969
  "aria-expanded": !0,
3029
- children: /* @__PURE__ */ c(Ii, {})
2970
+ children: /* @__PURE__ */ c(fi, {})
3030
2971
  }
3031
2972
  )
3032
2973
  ] }),
3033
- /* @__PURE__ */ c(ii, {}),
3034
- /* @__PURE__ */ c(gi, { commands: [] }),
3035
- /* @__PURE__ */ c(qt, { className: "absolute bottom-14 left-2 right-2" })
2974
+ /* @__PURE__ */ c(za, {}),
2975
+ /* @__PURE__ */ c(ai, { commands: [] }),
2976
+ /* @__PURE__ */ c(Ht, { className: "absolute bottom-14 left-2 right-2" })
3036
2977
  ] })
3037
2978
  }
3038
2979
  )
3039
2980
  ] }) }) }) });
3040
2981
  }
3041
- function Ai(e, t) {
3042
- const n = f((g) => g.chromeChatCollapsed) && t, r = f((g) => g.chromeChatWidth), a = f((g) => g.toggleChromeChatCollapsed), i = f((g) => g.setChromeChatWidth), [s, l] = R(null), [m, h] = R(void 0), [u, D] = R(null);
2982
+ function gi(e, t) {
2983
+ const n = m((g) => g.chromeChatCollapsed) && t, r = m((g) => g.chromeChatWidth), a = m((g) => g.toggleChromeChatCollapsed), i = m((g) => g.setChromeChatWidth), [s, l] = R(null), [f, h] = R(void 0), [u, j] = R(null);
3043
2984
  N(() => {
3044
2985
  if (s)
3045
- return wi(s, h);
2986
+ return di(s, h);
3046
2987
  }, [s]);
3047
- const M = V(u?.current ?? r, m), L = J(() => Bo(n, M), [n, M]), C = Wt((g) => e?.(g));
2988
+ const D = V(u?.current ?? r, f), M = J(() => $o(n, D), [n, D]), I = Gt((g) => e?.(g));
3048
2989
  return N(() => {
3049
- C(L);
3050
- }, [L]), {
2990
+ I(M);
2991
+ }, [M]), {
3051
2992
  setFrame: l,
3052
2993
  collapsed: n,
3053
- state: L,
2994
+ state: M,
3054
2995
  dragging: u !== null,
3055
2996
  toggleCollapsed: a,
3056
2997
  onPointerDown: (g) => {
3057
- g.button === 0 && (g.preventDefault(), g.currentTarget.setPointerCapture(g.pointerId), D({ pointerId: g.pointerId, startX: g.clientX, startWidth: M, current: M }));
2998
+ g.button === 0 && (g.preventDefault(), g.currentTarget.setPointerCapture(g.pointerId), j({ pointerId: g.pointerId, startX: g.clientX, startWidth: D, current: D }));
3058
2999
  },
3059
3000
  onPointerMove: (g) => {
3060
- !u || u.pointerId !== g.pointerId || D({ ...u, current: Mt(u.startWidth, u.startX, g.clientX, m) });
3001
+ !u || u.pointerId !== g.pointerId || j({ ...u, current: Pt(u.startWidth, u.startX, g.clientX, f) });
3061
3002
  },
3062
3003
  onPointerEnd: (g) => {
3063
3004
  if (!u || u.pointerId !== g.pointerId) return;
3064
- const E = Mt(u.startWidth, u.startX, g.clientX, m);
3065
- D(null), E !== r && i(E);
3005
+ const k = Pt(u.startWidth, u.startX, g.clientX, f);
3006
+ j(null), k !== r && i(k);
3066
3007
  },
3067
3008
  onKeyDown: (g) => {
3068
- const E = $o(M, g.key, m);
3069
- E !== null && (g.preventDefault(), E !== r && i(E));
3009
+ const k = Ho(D, g.key, f);
3010
+ k !== null && (g.preventDefault(), k !== r && i(k));
3070
3011
  }
3071
3012
  };
3072
3013
  }
3073
3014
  export {
3074
- $i as RoomChrome
3015
+ Ni as RoomChrome
3075
3016
  };
3076
3017
  //# sourceMappingURL=room-chrome.js.map