@hadoku/watchparty-ui 0.45.15 → 0.45.16

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