@sensiblestats/widget-react 0.66.0 → 0.66.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -1,5 +1,5 @@
1
1
  // src/StatsWidget.tsx
2
- import { useCallback as useCallback12, useEffect as useEffect20, useMemo as useMemo4, useRef as useRef16, useState as useState41 } from "react";
2
+ import { useCallback as useCallback12, useEffect as useEffect21, useMemo as useMemo4, useRef as useRef17, useState as useState41 } from "react";
3
3
  import { StatsWidgetClient } from "@sensiblestats/widget-sdk";
4
4
 
5
5
  // src/kickoff.ts
@@ -809,10 +809,10 @@ function resultToToast(result, shownOdds, ui) {
809
809
  }
810
810
 
811
811
  // src/useHostEvents.ts
812
- import { useCallback as useCallback5, useEffect as useEffect11, useMemo, useRef as useRef7, useState as useState34 } from "react";
812
+ import { useCallback as useCallback5, useEffect as useEffect12, useMemo, useRef as useRef8, useState as useState34 } from "react";
813
813
 
814
814
  // src/components/ChatPanel.tsx
815
- import { useEffect as useEffect10, useState as useState33 } from "react";
815
+ import { useEffect as useEffect11, useState as useState33 } from "react";
816
816
 
817
817
  // src/components/ChatHeader.tsx
818
818
  import { useEffect, useRef, useState as useState2 } from "react";
@@ -946,7 +946,7 @@ function ChatHeader({
946
946
  }
947
947
 
948
948
  // src/components/MessageList.tsx
949
- import { useEffect as useEffect5, useRef as useRef3 } from "react";
949
+ import { useEffect as useEffect6, useRef as useRef4 } from "react";
950
950
 
951
951
  // src/components/Markdown.tsx
952
952
  import ReactMarkdown from "react-markdown";
@@ -1442,8 +1442,9 @@ function SlipButton({ selection, shownOdds, marketDeveloperName, selectionLabel,
1442
1442
  disabled: pending || settled,
1443
1443
  onClick,
1444
1444
  children: [
1445
+ settled ? /* @__PURE__ */ jsx7("span", { className: "ss-w-mol-tick", "aria-hidden": "true", children: "\u2713" }) : null,
1445
1446
  price.label ? /* @__PURE__ */ jsx7("span", { className: "ss-w-mol-lab", children: price.label }) : null,
1446
- shownOdds
1447
+ /* @__PURE__ */ jsx7("span", { children: shownOdds })
1447
1448
  ]
1448
1449
  }
1449
1450
  ) : /* @__PURE__ */ jsx7(
@@ -1913,7 +1914,7 @@ function MarketOddsCard({ vm, ui, slip, monitor, inSlipIds, hideHeader, pinRef }
1913
1914
  vm.market ? /* @__PURE__ */ jsx14("div", { className: "ss-w-mo-market-row", children: /* @__PURE__ */ jsx14("span", { className: "ss-w-mo-market", children: vm.market }) }) : null
1914
1915
  ] }) : null
1915
1916
  ] }),
1916
- vm.statText && !hideHeader ? /* @__PURE__ */ jsx14("div", { className: "ss-w-mo-stat", children: vm.statText }) : null,
1917
+ vm.statText && !hideHeader && !pinRef ? /* @__PURE__ */ jsx14("div", { className: "ss-w-mo-stat", children: vm.statText }) : null,
1917
1918
  /* @__PURE__ */ jsxs9("div", { className: "ss-w-mo-rows", children: [
1918
1919
  vm.mainRows.map((row) => /* @__PURE__ */ jsx14(OddsRow, { vm, row, ui, slip, inSlipIds, history }, row.key)),
1919
1920
  open ? vm.moreRows.map((row) => /* @__PURE__ */ jsx14(OddsRow, { vm, row, ui, slip, inSlipIds, history }, row.key)) : null
@@ -1932,7 +1933,7 @@ function MarketOddsCardList({ cards, ui, slip, monitor, inSlipIds, hideHeader, p
1932
1933
  }
1933
1934
 
1934
1935
  // src/components/CompactOddsList.tsx
1935
- import { useState as useState9 } from "react";
1936
+ import { useEffect as useEffect3, useRef as useRef2, useState as useState9 } from "react";
1936
1937
 
1937
1938
  // src/compactList.ts
1938
1939
  var COMPACT_MIN_CARDS = 3;
@@ -1994,6 +1995,7 @@ import { jsx as jsx15, jsxs as jsxs10 } from "react/jsx-runtime";
1994
1995
  function Cell({ row, cell, ui, slip }) {
1995
1996
  const vm = row.card;
1996
1997
  const selection = vm.addToSlipEnabled ? marketOddsRowToSlipSelection(vm, cell.row, slip.conversationId) : null;
1998
+ const name = `${vm.homeTeamName ?? ""} ${vm.awayTeamName ?? ""}, ${cell.row.selection} ${cell.row.odds}`;
1997
1999
  const button = /* @__PURE__ */ jsx15(
1998
2000
  SlipButton,
1999
2001
  {
@@ -2004,7 +2006,7 @@ function Cell({ row, cell, ui, slip }) {
2004
2006
  line: cell.row.line,
2005
2007
  slip,
2006
2008
  ui,
2007
- price: { label: cell.label, ariaLabel: `${vm.homeTeamName ?? ""} ${vm.awayTeamName ?? ""}, ${cell.row.selection} ${cell.row.odds}` }
2009
+ price: { label: cell.label, ariaLabel: name }
2008
2010
  }
2009
2011
  );
2010
2012
  return (
@@ -2012,18 +2014,19 @@ function Cell({ row, cell, ui, slip }) {
2012
2014
  // and 101.00 two.
2013
2015
  /* @__PURE__ */ jsxs10("span", { className: ["ss-w-mol-cell", cell.row.odds.length >= 5 && "ss-w-mol-cell--wide", cell.row.odds.length >= 6 && "ss-w-mol-cell--wider"].filter(Boolean).join(" "), children: [
2014
2016
  selection && slip.onAddToSlip && ui ? button : /* @__PURE__ */ jsxs10("span", { className: "ss-w-mol-price", children: [
2015
- cell.label ? /* @__PURE__ */ jsx15("span", { className: "ss-w-mol-lab", children: cell.label }) : null,
2016
- cell.row.odds
2017
+ cell.label ? /* @__PURE__ */ jsx15("span", { className: "ss-w-mol-lab", "aria-hidden": "true", children: cell.label }) : null,
2018
+ /* @__PURE__ */ jsx15("span", { "aria-hidden": "true", children: cell.row.odds }),
2019
+ /* @__PURE__ */ jsx15("span", { className: "ss-w-vh", children: name })
2017
2020
  ] }),
2018
2021
  /* @__PURE__ */ jsx15(OddsMovementBadge, { previous: cell.row.previousOdds, current: cell.row.odds, direction: cell.row.movementDirection, ui })
2019
2022
  ] })
2020
2023
  );
2021
2024
  }
2022
- function Row({ row, columns, ui, slip, monitor }) {
2025
+ function Row({ row, columns, ui, slip, monitor, rowRef }) {
2023
2026
  const vm = row.card;
2024
2027
  const kickoffFallback = vm.kickoffUtc && ui?.bettingKickoff ? ui.bettingKickoff(vm.kickoffUtc) : void 0;
2025
2028
  const when = vm.isLive ? ui?.liveLabel ?? "Live" : vm.kickoffLabel ?? (kickoffFallback ? `${kickoffFallback.dayLabel} ${kickoffFallback.time}` : void 0);
2026
- return /* @__PURE__ */ jsxs10("div", { className: "ss-w-mol-row", children: [
2029
+ return /* @__PURE__ */ jsxs10("div", { className: "ss-w-mol-row", ref: rowRef, tabIndex: rowRef ? -1 : void 0, children: [
2027
2030
  /* @__PURE__ */ jsxs10(MatchLink, { as: "div", matchId: vm.matchId, home: vm.homeTeamName, away: vm.awayTeamName, className: "ss-w-mol-fx", children: [
2028
2031
  /* @__PURE__ */ jsxs10("span", { className: "ss-w-mol-team", children: [
2029
2032
  /* @__PURE__ */ jsx15(Crest2, { kind: "team", url: vm.homeCrest, name: vm.homeTeamName ?? "" }),
@@ -2045,11 +2048,17 @@ function Row({ row, columns, ui, slip, monitor }) {
2045
2048
  function CompactOddsList({ list, ui, slip, monitor }) {
2046
2049
  const [shown, setShown] = useState9(COMPACT_PAGE);
2047
2050
  const hidden = list.rowCount - shown;
2051
+ const [focusIndex, setFocusIndex] = useState9(null);
2052
+ const focusRef = useRef2(null);
2053
+ useEffect3(() => {
2054
+ if (focusIndex !== null) focusRef.current?.focus();
2055
+ }, [focusIndex]);
2048
2056
  let left = shown;
2057
+ let index = 0;
2049
2058
  return /* @__PURE__ */ jsxs10("div", { className: "ss-w-mol", children: [
2050
2059
  /* @__PURE__ */ jsxs10("div", { className: "ss-w-mol-head", children: [
2051
2060
  /* @__PURE__ */ jsx15("span", { className: "ss-w-mol-market", children: list.market }),
2052
- /* @__PURE__ */ jsx15("span", { className: "ss-w-mol-cols", style: { gridTemplateColumns: `repeat(${list.columns.length}, minmax(0, 1fr))` }, children: list.columns.map((c, i) => /* @__PURE__ */ jsx15("span", { className: "ss-w-mol-col", children: c }, `${c}:${i}`)) }),
2061
+ /* @__PURE__ */ jsx15("span", { className: "ss-w-mol-cols", "aria-hidden": "true", style: { gridTemplateColumns: `repeat(${list.columns.length}, minmax(0, 1fr))` }, children: list.columns.map((c, i) => /* @__PURE__ */ jsx15("span", { className: "ss-w-mol-col", children: c }, `${c}:${i}`)) }),
2053
2062
  /* @__PURE__ */ jsx15("span", { className: "ss-w-mol-side", "aria-hidden": "true" })
2054
2063
  ] }),
2055
2064
  list.groups.map((group, gi) => {
@@ -2061,10 +2070,16 @@ function CompactOddsList({ list, ui, slip, monitor }) {
2061
2070
  /* @__PURE__ */ jsx15(Crest2, { kind: "comp", url: group.competitionCrest, name: group.competition }),
2062
2071
  /* @__PURE__ */ jsx15("span", { children: group.competition })
2063
2072
  ] }) : null,
2064
- rows.map((row) => /* @__PURE__ */ jsx15(Row, { row, columns: list.columns.length, ui, slip, monitor }, row.card.id))
2073
+ rows.map((row) => {
2074
+ const at = index++;
2075
+ return /* @__PURE__ */ jsx15(Row, { row, columns: list.columns.length, ui, slip, monitor, rowRef: at === focusIndex ? focusRef : void 0 }, row.card.id);
2076
+ })
2065
2077
  ] }, `${group.competition ?? ""}:${gi}`);
2066
2078
  }),
2067
- hidden > 0 ? /* @__PURE__ */ jsxs10("button", { type: "button", className: "ss-w-mo-more", onClick: () => setShown((n) => n + COMPACT_PAGE), children: [
2079
+ hidden > 0 ? /* @__PURE__ */ jsxs10("button", { type: "button", className: "ss-w-mo-more", onClick: () => {
2080
+ setFocusIndex(shown);
2081
+ setShown((n) => n + COMPACT_PAGE);
2082
+ }, children: [
2068
2083
  /* @__PURE__ */ jsx15("span", { children: ui?.showMore ? ui.showMore(Math.min(COMPACT_PAGE, hidden)) : `Show ${Math.min(COMPACT_PAGE, hidden)} more` }),
2069
2084
  /* @__PURE__ */ jsx15("span", { className: "ss-w-mo-more-chev", "aria-hidden": "true" })
2070
2085
  ] }) : null,
@@ -2336,7 +2351,7 @@ function FixtureCard({ card }) {
2336
2351
  }
2337
2352
 
2338
2353
  // src/components/dashboard/CountdownCard.tsx
2339
- import { Fragment as Fragment6, useEffect as useEffect3, useState as useState10 } from "react";
2354
+ import { Fragment as Fragment6, useEffect as useEffect4, useState as useState10 } from "react";
2340
2355
  import { jsx as jsx21, jsxs as jsxs16 } from "react/jsx-runtime";
2341
2356
  var DAY_MS = 864e5;
2342
2357
  function remainingSegments(kickoffUnix, nowMs, withSeconds) {
@@ -2360,7 +2375,7 @@ function CountdownCard({ card }) {
2360
2375
  () => typeof window !== "undefined" && window.matchMedia("(prefers-reduced-motion: reduce)").matches
2361
2376
  );
2362
2377
  const withinDay = data.kickoffUnix * 1e3 - nowMs < DAY_MS;
2363
- useEffect3(() => {
2378
+ useEffect4(() => {
2364
2379
  if (reduced) return;
2365
2380
  const id = window.setInterval(() => setNowMs(Date.now()), withinDay ? 1e3 : 6e4);
2366
2381
  return () => window.clearInterval(id);
@@ -2717,10 +2732,10 @@ function RestingFormCard({ card }) {
2717
2732
  }
2718
2733
 
2719
2734
  // src/components/dashboard/LiveScoreCard.tsx
2720
- import { useRef as useRef2, useState as useState14 } from "react";
2735
+ import { useRef as useRef3, useState as useState14 } from "react";
2721
2736
 
2722
2737
  // src/useLiveClock.ts
2723
- import { useEffect as useEffect4, useState as useState13 } from "react";
2738
+ import { useEffect as useEffect5, useState as useState13 } from "react";
2724
2739
  var TICK_MS = 6e4;
2725
2740
  var MAX_LIVE_TICK_MINUTES = 15;
2726
2741
  function computeDisplayMinute(minute, clockRunning, receivedAtMs) {
@@ -2732,7 +2747,7 @@ function useLiveClock(minute, clockRunning, receivedAtMs) {
2732
2747
  const [displayMinute, setDisplayMinute] = useState13(
2733
2748
  () => computeDisplayMinute(minute, clockRunning, receivedAtMs)
2734
2749
  );
2735
- useEffect4(() => {
2750
+ useEffect5(() => {
2736
2751
  setDisplayMinute(computeDisplayMinute(minute, clockRunning, receivedAtMs));
2737
2752
  if (!clockRunning) return;
2738
2753
  const id = window.setInterval(() => {
@@ -2768,7 +2783,7 @@ function LiveScoreCard({
2768
2783
  }) {
2769
2784
  const { data } = card;
2770
2785
  const seedKey = `${data.minute}:${data.homeScore}:${data.awayScore}`;
2771
- const seedRef = useRef2(null);
2786
+ const seedRef = useRef3(null);
2772
2787
  if (!seedRef.current || seedRef.current.key !== seedKey) {
2773
2788
  seedRef.current = { key: seedKey, receivedAtMs: Date.now() };
2774
2789
  }
@@ -3091,11 +3106,11 @@ function turnAnchor(messages) {
3091
3106
  }
3092
3107
  function MessageList({ controller, ui, slip, onDashboardTap, monitor }) {
3093
3108
  const { state, send } = controller;
3094
- const listRef = useRef3(null);
3095
- const endRef = useRef3(null);
3096
- const pinnedRef = useRef3(true);
3097
- const anchoredTurnRef = useRef3(null);
3098
- useEffect5(() => {
3109
+ const listRef = useRef4(null);
3110
+ const endRef = useRef4(null);
3111
+ const pinnedRef = useRef4(true);
3112
+ const anchoredTurnRef = useRef4(null);
3113
+ useEffect6(() => {
3099
3114
  const anchor = turnAnchor(state.messages);
3100
3115
  const list = listRef.current;
3101
3116
  if (anchor && anchor.turnId !== anchoredTurnRef.current) {
@@ -3654,7 +3669,7 @@ function TodayPanel({ discovery, ui, monitor }) {
3654
3669
  }
3655
3670
 
3656
3671
  // src/components/GamesPanel.tsx
3657
- import { useEffect as useEffect9, useState as useState31 } from "react";
3672
+ import { useEffect as useEffect10, useState as useState31 } from "react";
3658
3673
 
3659
3674
  // src/components/GamesLoginWall.tsx
3660
3675
  import { jsx as jsx54 } from "react/jsx-runtime";
@@ -3663,7 +3678,7 @@ function GamesLoginWall({ ui }) {
3663
3678
  }
3664
3679
 
3665
3680
  // src/components/GamesHub.tsx
3666
- import { useEffect as useEffect6, useState as useState18 } from "react";
3681
+ import { useEffect as useEffect7, useState as useState18 } from "react";
3667
3682
 
3668
3683
  // src/components/games/ui/gameMeta.ts
3669
3684
  function prettifyGameId(gameId) {
@@ -3849,7 +3864,7 @@ function pickHeroGame(games) {
3849
3864
  var tileKey = (g) => `${g.gameId}-${g.gameDay}-${g.fixtureId}`;
3850
3865
  function GamesHub({ games, myWeeklyRow, weeklyPrize, onOpen, ui }) {
3851
3866
  const [, setTick] = useState18(0);
3852
- useEffect6(() => {
3867
+ useEffect7(() => {
3853
3868
  const id = setInterval(() => setTick((t) => t + 1), 6e4);
3854
3869
  return () => clearInterval(id);
3855
3870
  }, []);
@@ -3909,10 +3924,10 @@ function GamesHub({ games, myWeeklyRow, weeklyPrize, onOpen, ui }) {
3909
3924
  }
3910
3925
 
3911
3926
  // src/components/GameScreenHost.tsx
3912
- import { useEffect as useEffect8, useRef as useRef6, useState as useState30 } from "react";
3927
+ import { useEffect as useEffect9, useRef as useRef7, useState as useState30 } from "react";
3913
3928
 
3914
3929
  // src/useGamePlay.ts
3915
- import { useCallback as useCallback4, useRef as useRef4, useState as useState19 } from "react";
3930
+ import { useCallback as useCallback4, useRef as useRef5, useState as useState19 } from "react";
3916
3931
  function toSubmitResult(payload) {
3917
3932
  return {
3918
3933
  // 'pending' means the play is recorded but awaiting resolution (fixture games)
@@ -3927,12 +3942,12 @@ function useGamePlay(conversation, { gameId, gameDay, fixtureId, locale, refresh
3927
3942
  const [result, setResult] = useState19(null);
3928
3943
  const [submitting, setSubmitting] = useState19(false);
3929
3944
  const [rawStatus, setRawStatus] = useState19(null);
3930
- const inFlightRef = useRef4(false);
3931
- const convRef = useRef4(conversation);
3945
+ const inFlightRef = useRef5(false);
3946
+ const convRef = useRef5(conversation);
3932
3947
  convRef.current = conversation;
3933
- const optsRef = useRef4({ gameId, gameDay, fixtureId, locale, refresh });
3948
+ const optsRef = useRef5({ gameId, gameDay, fixtureId, locale, refresh });
3934
3949
  optsRef.current = { gameId, gameDay, fixtureId, locale, refresh };
3935
- const resultRef = useRef4(null);
3950
+ const resultRef = useRef5(null);
3936
3951
  resultRef.current = result;
3937
3952
  const refetch = useCallback4(async () => {
3938
3953
  const conv = convRef.current;
@@ -4862,7 +4877,7 @@ function CareerPathGame({
4862
4877
  }
4863
4878
 
4864
4879
  // src/components/games/BeatTheGridGame.tsx
4865
- import React, { useEffect as useEffect7, useId as useId4, useRef as useRef5, useState as useState24 } from "react";
4880
+ import React, { useEffect as useEffect8, useId as useId4, useRef as useRef6, useState as useState24 } from "react";
4866
4881
  import { Fragment as Fragment14, jsx as jsx73, jsxs as jsxs60 } from "react/jsx-runtime";
4867
4882
  function criterionIconKind(label, key) {
4868
4883
  const l = (key ?? label).toLowerCase();
@@ -4945,8 +4960,8 @@ function SearchSheet({
4945
4960
  const s = ui.games.beatTheGrid;
4946
4961
  const [query, setQuery] = useState24("");
4947
4962
  const inputId = useId4();
4948
- const inputRef = useRef5(null);
4949
- useEffect7(() => {
4963
+ const inputRef = useRef6(null);
4964
+ useEffect8(() => {
4950
4965
  inputRef.current?.focus();
4951
4966
  }, [row, col]);
4952
4967
  const filtered = playerPool.filter(
@@ -6248,7 +6263,7 @@ function GameScreenHost({
6248
6263
  }) {
6249
6264
  const { gameId, fixtureId, gameDay = "", lockAtUtc = null } = selected;
6250
6265
  const [configJson, setConfigJson] = useState30(null);
6251
- useEffect8(() => {
6266
+ useEffect9(() => {
6252
6267
  setConfigJson(null);
6253
6268
  if (!conversation) return;
6254
6269
  let cancelled = false;
@@ -6271,12 +6286,12 @@ function GameScreenHost({
6271
6286
  fixtureId: fixtureId || void 0,
6272
6287
  locale: ui.games.lang
6273
6288
  });
6274
- useEffect8(() => {
6289
+ useEffect9(() => {
6275
6290
  if (conversation) hydrate();
6276
6291
  }, [conversation, gameId]);
6277
- const hydrateRef = useRef6(hydrate);
6292
+ const hydrateRef = useRef7(hydrate);
6278
6293
  hydrateRef.current = hydrate;
6279
- useEffect8(() => {
6294
+ useEffect9(() => {
6280
6295
  if (!FIXTURE_GAME_IDS.has(gameId)) return;
6281
6296
  if (rawStatus !== "pending") return;
6282
6297
  const timerId = setInterval(() => {
@@ -6412,7 +6427,7 @@ function GamesPanel({
6412
6427
  refreshHub
6413
6428
  }) {
6414
6429
  const [selected, setSelected] = useState31(null);
6415
- useEffect9(() => {
6430
+ useEffect10(() => {
6416
6431
  ensureGamesFonts();
6417
6432
  }, []);
6418
6433
  if (!loggedIn) return /* @__PURE__ */ jsx82(GamesLoginWall, { ui });
@@ -6612,7 +6627,7 @@ import { jsx as jsx87, jsxs as jsxs71 } from "react/jsx-runtime";
6612
6627
  var FULLSCREEN_QUERY = "(max-width: 639px)";
6613
6628
  function useIsModal() {
6614
6629
  const [modal, setModal] = useState33(false);
6615
- useEffect10(() => {
6630
+ useEffect11(() => {
6616
6631
  if (typeof window === "undefined" || typeof window.matchMedia !== "function") return;
6617
6632
  const mql = window.matchMedia(FULLSCREEN_QUERY);
6618
6633
  const sync = () => setModal(mql.matches);
@@ -6625,7 +6640,7 @@ function useIsModal() {
6625
6640
  function ChatPanel({ controller, ui, slip, onDashboardTap, monitor, discovery, gamesResult, leaderboardResult, loggedIn, conversation }) {
6626
6641
  const { state, close, stop, send, reset } = controller;
6627
6642
  const isModal = useIsModal();
6628
- useEffect10(() => {
6643
+ useEffect11(() => {
6629
6644
  const onKey = (e) => {
6630
6645
  if (e.key === "Escape") close();
6631
6646
  };
@@ -6640,7 +6655,7 @@ function ChatPanel({ controller, ui, slip, onDashboardTap, monitor, discovery, g
6640
6655
  monitor?.setActiveTab("chat");
6641
6656
  send(text, { grounding });
6642
6657
  };
6643
- useEffect10(() => {
6658
+ useEffect11(() => {
6644
6659
  if (monitor && monitor.activeTab !== "chat" && state.isStreaming) monitor.markChatActivity();
6645
6660
  }, [monitor, state.isStreaming, state.messages.length]);
6646
6661
  return /* @__PURE__ */ jsxs71("div", { className: "ss-w-panel", role: "dialog", "aria-modal": isModal, "aria-label": ui.chatDialogLabel, children: [
@@ -6935,7 +6950,7 @@ function useHostEvents(opts) {
6935
6950
  () => hasHost ? createSlipLedger(`ss-w-slip:${operatorId}`) : null,
6936
6951
  [hasHost, operatorId]
6937
6952
  );
6938
- const currentUserRef = useRef7(currentUser);
6953
+ const currentUserRef = useRef8(currentUser);
6939
6954
  currentUserRef.current = currentUser;
6940
6955
  const recordAdd = useCallback5((add) => {
6941
6956
  ledger?.record({ id: add.selection.matchOddsId, market: add.market, ...add.pick, user: currentUserRef.current });
@@ -6950,7 +6965,7 @@ function useHostEvents(opts) {
6950
6965
  () => tracksViews ? createMatchViews(`ss-w-views:${operatorId}`, { user: currentUser }) : null,
6951
6966
  [tracksViews, operatorId, currentUser]
6952
6967
  );
6953
- const sinkRef = useRef7(() => {
6968
+ const sinkRef = useRef8(() => {
6954
6969
  });
6955
6970
  sinkRef.current = (command) => {
6956
6971
  if (command.kind === "matchOpened") {
@@ -6971,11 +6986,11 @@ function useHostEvents(opts) {
6971
6986
  logger?.log(toSlipEvent(name, entry));
6972
6987
  }
6973
6988
  };
6974
- useEffect11(() => {
6989
+ useEffect12(() => {
6975
6990
  if (!host) return;
6976
6991
  return attachHost(host, (command) => sinkRef.current(command));
6977
6992
  }, [host]);
6978
- useEffect11(() => {
6993
+ useEffect12(() => {
6979
6994
  if (!isOpen || !views) return;
6980
6995
  const held = views.markOpened();
6981
6996
  if (held.length === 0) return;
@@ -6984,7 +6999,7 @@ function useHostEvents(opts) {
6984
6999
  }
6985
7000
  void logger?.flushNow();
6986
7001
  }, [isOpen, views, logger]);
6987
- const openMatchRef = useRef7(() => {
7002
+ const openMatchRef = useRef8(() => {
6988
7003
  });
6989
7004
  openMatchRef.current = (matchId) => {
6990
7005
  if (views?.view(matchId) === "log") {
@@ -7066,7 +7081,7 @@ function themeAttrs(ui) {
7066
7081
  }
7067
7082
 
7068
7083
  // src/useChatStream.ts
7069
- import { useCallback as useCallback6, useEffect as useEffect13, useMemo as useMemo2, useReducer as useReducer2, useRef as useRef9 } from "react";
7084
+ import { useCallback as useCallback6, useEffect as useEffect14, useMemo as useMemo2, useReducer as useReducer2, useRef as useRef10 } from "react";
7070
7085
  import { WidgetSdkError as WidgetSdkError2 } from "@sensiblestats/widget-sdk";
7071
7086
 
7072
7087
  // src/reducer.ts
@@ -7190,7 +7205,7 @@ function reducer(state, action) {
7190
7205
  }
7191
7206
 
7192
7207
  // src/useLiveDashboardPoll.ts
7193
- import { useEffect as useEffect12, useReducer, useRef as useRef8 } from "react";
7208
+ import { useEffect as useEffect13, useReducer, useRef as useRef9 } from "react";
7194
7209
  var POLL_INTERVAL_MS = 6e4;
7195
7210
  var LEAD_MS = 12e4;
7196
7211
  var GIVE_UP_MS = 30 * 6e4;
@@ -7234,11 +7249,11 @@ function findEarliestWakeupMs(messages) {
7234
7249
  function useLiveDashboardPoll({ messages, dispatch, getLiveDashboard }) {
7235
7250
  const [, forceUpdate] = useReducer((x) => x + 1, 0);
7236
7251
  const anchor = findAnchor(messages);
7237
- const anchorRef = useRef8(anchor);
7252
+ const anchorRef = useRef9(anchor);
7238
7253
  anchorRef.current = anchor;
7239
- const inFlightRef = useRef8(false);
7254
+ const inFlightRef = useRef9(false);
7240
7255
  const anchorKey = anchor ? `${anchor.messageId}:${anchor.kind}` : null;
7241
- useEffect12(() => {
7256
+ useEffect13(() => {
7242
7257
  if (!anchorKey || !anchorRef.current) return;
7243
7258
  const tick = async () => {
7244
7259
  if (inFlightRef.current) return;
@@ -7274,7 +7289,7 @@ function useLiveDashboardPoll({ messages, dispatch, getLiveDashboard }) {
7274
7289
  }, POLL_INTERVAL_MS);
7275
7290
  return () => window.clearInterval(id);
7276
7291
  }, [anchorKey, dispatch, getLiveDashboard]);
7277
- useEffect12(() => {
7292
+ useEffect13(() => {
7278
7293
  if (anchorKey !== null) return;
7279
7294
  const wakeAt = findEarliestWakeupMs(messages);
7280
7295
  if (wakeAt === null) return;
@@ -7349,14 +7364,14 @@ function useChatStream(conversation, starterTexts, greetingMessage, storageKey)
7349
7364
  return { state: base, restored: false, stale: payload === "expired" || payload === "corrupt" };
7350
7365
  }, []);
7351
7366
  const [state, dispatch] = useReducer2(reducer, boot.state);
7352
- const idRef = useRef9(seedIdCounter(boot.state.messages));
7353
- const handleRef = useRef9(null);
7354
- const fallbackTimerRef = useRef9(null);
7355
- const stateRef = useRef9(state);
7367
+ const idRef = useRef10(seedIdCounter(boot.state.messages));
7368
+ const handleRef = useRef10(null);
7369
+ const fallbackTimerRef = useRef10(null);
7370
+ const stateRef = useRef10(state);
7356
7371
  stateRef.current = state;
7357
- const greetedRef = useRef9(boot.restored);
7358
- const hydratedRef = useRef9(false);
7359
- const restoreSeededRef = useRef9(false);
7372
+ const greetedRef = useRef10(boot.restored);
7373
+ const hydratedRef = useRef10(false);
7374
+ const restoreSeededRef = useRef10(false);
7360
7375
  if (!restoreSeededRef.current) {
7361
7376
  restoreSeededRef.current = true;
7362
7377
  if (boot.restored && boot.state.conversationId) conversation.conversationId = boot.state.conversationId;
@@ -7431,15 +7446,15 @@ function useChatStream(conversation, starterTexts, greetingMessage, storageKey)
7431
7446
  dispatch({ kind: "STOP" });
7432
7447
  }
7433
7448
  }, [greetingMessage, conversation, consume, clearFallbackTimer, armFallbackTimer]);
7434
- useEffect13(() => {
7449
+ useEffect14(() => {
7435
7450
  if (greetedRef.current) return;
7436
7451
  greetedRef.current = true;
7437
7452
  fireGreeting();
7438
7453
  }, [fireGreeting]);
7439
- useEffect13(() => {
7454
+ useEffect14(() => {
7440
7455
  if (boot.stale && storageKey) clearConversation(storageKey);
7441
7456
  }, []);
7442
- useEffect13(() => {
7457
+ useEffect14(() => {
7443
7458
  if (!storageKey || state.isStreaming) return;
7444
7459
  if (hydratedRef.current) {
7445
7460
  hydratedRef.current = false;
@@ -7456,7 +7471,7 @@ function useChatStream(conversation, starterTexts, greetingMessage, storageKey)
7456
7471
  if (persistable.length === 0) return;
7457
7472
  writeConversation(storageKey, state.conversationId, persistable, Date.now());
7458
7473
  }, [storageKey, state.isStreaming, state.messages, state.conversationId]);
7459
- useEffect13(() => {
7474
+ useEffect14(() => {
7460
7475
  if (!storageKey) return;
7461
7476
  const onStorage = (e) => {
7462
7477
  if (e.key !== storageKey || e.storageArea !== window.localStorage) return;
@@ -7515,7 +7530,7 @@ function useChatStream(conversation, starterTexts, greetingMessage, storageKey)
7515
7530
  }
7516
7531
 
7517
7532
  // src/useLiveMonitor.ts
7518
- import { useCallback as useCallback7, useEffect as useEffect14, useRef as useRef10, useState as useState36 } from "react";
7533
+ import { useCallback as useCallback7, useEffect as useEffect15, useRef as useRef11, useState as useState36 } from "react";
7519
7534
 
7520
7535
  // src/useTabs.ts
7521
7536
  import { useState as useState35 } from "react";
@@ -7544,7 +7559,7 @@ function phaseForPin(snapshot, pin) {
7544
7559
  return snapshot.markets.find((mk) => mk.key === pin.key)?.phase;
7545
7560
  }
7546
7561
  function useLiveMonitor(opts) {
7547
- const sessionIdRef = useRef10(crypto.randomUUID());
7562
+ const sessionIdRef = useRef11(crypto.randomUUID());
7548
7563
  const [pins, setPins] = useState36([]);
7549
7564
  const [store] = useState36(() => createPinStore(opts.storageKey, sessionIdRef.current, setPins));
7550
7565
  const [enabled, setEnabled] = useState36(true);
@@ -7557,21 +7572,21 @@ function useLiveMonitor(opts) {
7557
7572
  const [lastViewedPrices, setLastViewedPrices] = useState36({});
7558
7573
  const [openMarket, setOpenMarket] = useState36({});
7559
7574
  const [marketOdds, setMarketOdds] = useState36({});
7560
- const pinsRef = useRef10(pins);
7575
+ const pinsRef = useRef11(pins);
7561
7576
  pinsRef.current = pins;
7562
- const activeTabRef = useRef10(activeTab);
7577
+ const activeTabRef = useRef11(activeTab);
7563
7578
  activeTabRef.current = activeTab;
7564
- const snapshotRef = useRef10(snapshot);
7579
+ const snapshotRef = useRef11(snapshot);
7565
7580
  snapshotRef.current = snapshot;
7566
- const lastViewedPricesRef = useRef10(lastViewedPrices);
7581
+ const lastViewedPricesRef = useRef11(lastViewedPrices);
7567
7582
  lastViewedPricesRef.current = lastViewedPrices;
7568
- const openMarketRef = useRef10(openMarket);
7583
+ const openMarketRef = useRef11(openMarket);
7569
7584
  openMarketRef.current = openMarket;
7570
- const marketOddsRef = useRef10(marketOdds);
7585
+ const marketOddsRef = useRef11(marketOdds);
7571
7586
  marketOddsRef.current = marketOdds;
7572
7587
  const hasToday = opts.hasToday ?? false;
7573
7588
  const marketKey = (matchId, dev) => `${matchId}:${dev}`;
7574
- const getMarketOddsRef = useRef10(opts.getMarketOdds);
7589
+ const getMarketOddsRef = useRef11(opts.getMarketOdds);
7575
7590
  getMarketOddsRef.current = opts.getMarketOdds;
7576
7591
  const fetchMarket = useCallback7((matchId, dev) => {
7577
7592
  const key = marketKey(matchId, dev);
@@ -7669,11 +7684,11 @@ function useLiveMonitor(opts) {
7669
7684
  snapshotRef.current = next;
7670
7685
  setSnapshotState(next);
7671
7686
  }, [store]);
7672
- const inFlightRef = useRef10(false);
7673
- const timerRef = useRef10(void 0);
7674
- const disabledRef = useRef10(false);
7675
- const mountedRef = useRef10(false);
7676
- const getLiveMonitorRef = useRef10(opts.getLiveMonitor);
7687
+ const inFlightRef = useRef11(false);
7688
+ const timerRef = useRef11(void 0);
7689
+ const disabledRef = useRef11(false);
7690
+ const mountedRef = useRef11(false);
7691
+ const getLiveMonitorRef = useRef11(opts.getLiveMonitor);
7677
7692
  getLiveMonitorRef.current = opts.getLiveMonitor;
7678
7693
  const tick = useCallback7(async () => {
7679
7694
  if (inFlightRef.current || disabledRef.current || pinsRef.current.length === 0) return;
@@ -7698,7 +7713,7 @@ function useLiveMonitor(opts) {
7698
7713
  scheduleRef.current();
7699
7714
  }
7700
7715
  }, [applySnapshot, fetchMarket]);
7701
- const scheduleRef = useRef10(() => {
7716
+ const scheduleRef = useRef11(() => {
7702
7717
  });
7703
7718
  scheduleRef.current = () => {
7704
7719
  window.clearTimeout(timerRef.current);
@@ -7706,14 +7721,14 @@ function useLiveMonitor(opts) {
7706
7721
  const hinted = (snapshotRef.current?.nextPollSeconds ?? DEFAULT_POLL_MS / 1e3) * 1e3;
7707
7722
  timerRef.current = window.setTimeout(() => void tick(), Math.max(MIN_POLL_MS, hinted));
7708
7723
  };
7709
- useEffect14(() => {
7724
+ useEffect15(() => {
7710
7725
  mountedRef.current = true;
7711
7726
  return () => {
7712
7727
  mountedRef.current = false;
7713
7728
  };
7714
7729
  }, []);
7715
- const prevPinsLengthRef = useRef10(0);
7716
- useEffect14(() => {
7730
+ const prevPinsLengthRef = useRef11(0);
7731
+ useEffect15(() => {
7717
7732
  const wasEmpty = prevPinsLengthRef.current === 0;
7718
7733
  prevPinsLengthRef.current = pins.length;
7719
7734
  if (pins.length === 0) {
@@ -7722,20 +7737,20 @@ function useLiveMonitor(opts) {
7722
7737
  }
7723
7738
  if (wasEmpty) void tick();
7724
7739
  }, [pins.length, tick]);
7725
- useEffect14(() => {
7740
+ useEffect15(() => {
7726
7741
  const matchPins = pins.filter((p) => p.kind === "match").length;
7727
7742
  const marketPins = pins.length - matchPins;
7728
7743
  if (activeTab === "following" && matchPins === 0) setActiveTabState(hasToday ? "today" : "chat");
7729
7744
  if (activeTab === "odds" && marketPins === 0) setActiveTabState(hasToday ? "today" : "chat");
7730
7745
  if (activeTab === "today" && !hasToday) setActiveTabState("chat");
7731
7746
  }, [pins, activeTab, hasToday]);
7732
- const prevIsOpenRef = useRef10(false);
7733
- useEffect14(() => {
7747
+ const prevIsOpenRef = useRef11(false);
7748
+ useEffect15(() => {
7734
7749
  const wasClosed = !prevIsOpenRef.current;
7735
7750
  prevIsOpenRef.current = opts.isOpen;
7736
7751
  if (wasClosed && opts.isOpen) void tick();
7737
7752
  }, [opts.isOpen, tick]);
7738
- useEffect14(() => {
7753
+ useEffect15(() => {
7739
7754
  const onVisibility = () => {
7740
7755
  if (document.visibilityState === "hidden") window.clearTimeout(timerRef.current);
7741
7756
  else void tick();
@@ -7801,7 +7816,7 @@ function useLiveMonitor(opts) {
7801
7816
  }
7802
7817
 
7803
7818
  // src/useMatchDiscovery.ts
7804
- import { useCallback as useCallback8, useEffect as useEffect15, useMemo as useMemo3, useRef as useRef11, useState as useState37 } from "react";
7819
+ import { useCallback as useCallback8, useEffect as useEffect16, useMemo as useMemo3, useRef as useRef12, useState as useState37 } from "react";
7805
7820
 
7806
7821
  // src/scheduleCache.ts
7807
7822
  var PREFIX = "ss-w-schedule:";
@@ -7894,22 +7909,22 @@ function useMatchDiscovery(opts) {
7894
7909
  const [failures, setFailures] = useState37(0);
7895
7910
  const [expanded, setExpanded] = useState37({});
7896
7911
  const [touched, setTouched] = useState37({});
7897
- const groupsRef = useRef11(groups);
7912
+ const groupsRef = useRef12(groups);
7898
7913
  groupsRef.current = groups;
7899
- const statesRef = useRef11(states);
7914
+ const statesRef = useRef12(states);
7900
7915
  statesRef.current = states;
7901
- const getStatesRef = useRef11(opts.getStates);
7916
+ const getStatesRef = useRef12(opts.getStates);
7902
7917
  getStatesRef.current = opts.getStates;
7903
7918
  const pinnedKey = opts.pinnedMatchIds.join(",");
7904
7919
  const [localDate, setLocalDate] = useState37(() => localDateOf(/* @__PURE__ */ new Date()));
7905
- useEffect15(() => {
7920
+ useEffect16(() => {
7906
7921
  const id = setInterval(() => {
7907
7922
  const next = localDateOf(/* @__PURE__ */ new Date());
7908
7923
  setLocalDate((prev) => prev === next ? prev : next);
7909
7924
  }, ROLLOVER_CHECK_MS);
7910
7925
  return () => clearInterval(id);
7911
7926
  }, []);
7912
- useEffect15(() => {
7927
+ useEffect16(() => {
7913
7928
  let cancelled = false;
7914
7929
  const utcOffsetMinutes = -(/* @__PURE__ */ new Date()).getTimezoneOffset();
7915
7930
  const cached = readSchedule(opts.operatorId, localDate, Date.now());
@@ -7934,7 +7949,7 @@ function useMatchDiscovery(opts) {
7934
7949
  cancelled = true;
7935
7950
  };
7936
7951
  }, [opts.operatorId, localDate]);
7937
- useEffect15(() => {
7952
+ useEffect16(() => {
7938
7953
  setExpanded((prev) => {
7939
7954
  const next = {};
7940
7955
  for (const group of groups) {
@@ -7961,7 +7976,7 @@ function useMatchDiscovery(opts) {
7961
7976
  setFailures((n) => n + 1);
7962
7977
  }
7963
7978
  }, []);
7964
- useEffect15(() => {
7979
+ useEffect16(() => {
7965
7980
  if (!opts.isOpen) return;
7966
7981
  void tick();
7967
7982
  const id = setInterval(() => {
@@ -7982,7 +7997,7 @@ function useMatchDiscovery(opts) {
7982
7997
  }
7983
7998
 
7984
7999
  // src/useGames.ts
7985
- import { useCallback as useCallback9, useEffect as useEffect16, useRef as useRef12, useState as useState38 } from "react";
8000
+ import { useCallback as useCallback9, useEffect as useEffect17, useRef as useRef13, useState as useState38 } from "react";
7986
8001
  var GAMES_POLL_MS = 6e4;
7987
8002
  var DEFAULT_TZ = "Europe/London";
7988
8003
  function computeGameDay(timezone) {
@@ -7993,14 +8008,14 @@ function useGames(conversation, { activeTab, operatorTimezone }) {
7993
8008
  const [games, setGames] = useState38([]);
7994
8009
  const [loading, setLoading] = useState38(false);
7995
8010
  const [refreshCount, setRefreshCount] = useState38(0);
7996
- const inFlightRef = useRef12(false);
7997
- const hardOffRef = useRef12(false);
7998
- const conversationRef = useRef12(conversation);
8011
+ const inFlightRef = useRef13(false);
8012
+ const hardOffRef = useRef13(false);
8013
+ const conversationRef = useRef13(conversation);
7999
8014
  conversationRef.current = conversation;
8000
- const tzRef = useRef12(operatorTimezone ?? DEFAULT_TZ);
8015
+ const tzRef = useRef13(operatorTimezone ?? DEFAULT_TZ);
8001
8016
  tzRef.current = operatorTimezone ?? DEFAULT_TZ;
8002
8017
  const ready = conversation != null;
8003
- useEffect16(() => {
8018
+ useEffect17(() => {
8004
8019
  if (hardOffRef.current) return;
8005
8020
  let active = true;
8006
8021
  const doFetch = async () => {
@@ -8050,15 +8065,15 @@ function useGames(conversation, { activeTab, operatorTimezone }) {
8050
8065
  }
8051
8066
 
8052
8067
  // src/useLeaderboard.ts
8053
- import { useCallback as useCallback10, useEffect as useEffect17, useRef as useRef13, useState as useState39 } from "react";
8068
+ import { useCallback as useCallback10, useEffect as useEffect18, useRef as useRef14, useState as useState39 } from "react";
8054
8069
  function useLeaderboard(conversation, { activeTab }) {
8055
8070
  const [data, setData] = useState39(null);
8056
8071
  const [loading, setLoading] = useState39(false);
8057
8072
  const [refreshCount, setRefreshCount] = useState39(0);
8058
- const inFlightRef = useRef13(false);
8059
- const conversationRef = useRef13(conversation);
8073
+ const inFlightRef = useRef14(false);
8074
+ const conversationRef = useRef14(conversation);
8060
8075
  conversationRef.current = conversation;
8061
- useEffect17(() => {
8076
+ useEffect18(() => {
8062
8077
  if (activeTab !== "leaderboard" && activeTab !== "games") return;
8063
8078
  let active = true;
8064
8079
  const doFetch = async () => {
@@ -8088,11 +8103,11 @@ function useLeaderboard(conversation, { activeTab }) {
8088
8103
  }
8089
8104
 
8090
8105
  // src/popupTelemetry.ts
8091
- import { useCallback as useCallback11, useEffect as useEffect18, useRef as useRef14 } from "react";
8106
+ import { useCallback as useCallback11, useEffect as useEffect19, useRef as useRef15 } from "react";
8092
8107
  function usePopupTelemetry(log, isOpen, popupText, dismissPopup) {
8093
- const shownRef = useRef14(/* @__PURE__ */ new Set());
8094
- const closedTextRef = useRef14(null);
8095
- useEffect18(() => {
8108
+ const shownRef = useRef15(/* @__PURE__ */ new Set());
8109
+ const closedTextRef = useRef15(null);
8110
+ useEffect19(() => {
8096
8111
  if (isOpen) {
8097
8112
  if (closedTextRef.current) log?.log({ name: "popup_opened" });
8098
8113
  closedTextRef.current = null;
@@ -8111,7 +8126,7 @@ function usePopupTelemetry(log, isOpen, popupText, dismissPopup) {
8111
8126
  }
8112
8127
 
8113
8128
  // src/components/ChatFab.tsx
8114
- import { useEffect as useEffect19, useRef as useRef15, useState as useState40 } from "react";
8129
+ import { useEffect as useEffect20, useRef as useRef16, useState as useState40 } from "react";
8115
8130
 
8116
8131
  // src/components/GreetingBubble.tsx
8117
8132
  import { jsx as jsx88, jsxs as jsxs72 } from "react/jsx-runtime";
@@ -8134,8 +8149,8 @@ import { jsx as jsx89, jsxs as jsxs73 } from "react/jsx-runtime";
8134
8149
  function ChatFab({ label, greeting, popupText, logoUrl, onOpen, onDismissPopup, dismissLabel = "Dismiss", introAllowed = false, onIntroStart }) {
8135
8150
  const bubble = popupText ?? greeting;
8136
8151
  const [intro, setIntro] = useState40(false);
8137
- const armedRef = useRef15(introAllowed);
8138
- useEffect19(() => {
8152
+ const armedRef = useRef16(introAllowed);
8153
+ useEffect20(() => {
8139
8154
  if (armedRef.current && bubble) {
8140
8155
  armedRef.current = false;
8141
8156
  setIntro(true);
@@ -8563,6 +8578,10 @@ var WIDGET_CSS = `.ss-w-root { all: revert; }
8563
8578
  .ss-w-mol-col { font-size: 10px; font-weight: 700; color: var(--ss-w-faint); text-align: center; overflow-wrap: break-word; min-width: 0; }
8564
8579
  .ss-w-mol-comp { display: flex; align-items: center; gap: 6px; font-size: 10px; font-weight: 800; letter-spacing: .06em; text-transform: uppercase; color: var(--ss-w-faint); padding-top: 4px; }
8565
8580
  .ss-w-mol-row { padding: 6px 0; border-bottom: 1px dashed var(--ss-w-line); min-height: 48px; box-sizing: border-box; }
8581
+ .ss-w-mol-row:focus { outline: none; }
8582
+ .ss-w-mol-row:focus-visible { outline: 2px solid var(--ss-w-accent); outline-offset: 2px; border-radius: 6px; }
8583
+ .ss-w-mol-tick { font-family: inherit; font-size: 9.5px; font-weight: 700; line-height: 1.1; }
8584
+ .ss-w-vh { position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0; }
8566
8585
  .ss-w-mol-group .ss-w-mol-row:last-child { border-bottom: none; }
8567
8586
  .ss-w-mol-fx { display: flex; flex-direction: column; gap: 3px; min-width: 0; background: none; border: none; padding: 0; text-align: left; font: inherit; color: inherit; }
8568
8587
  .ss-w-mol-team { display: flex; align-items: center; gap: 5px; min-width: 0; }
@@ -9708,8 +9727,8 @@ function StatsWidget(props) {
9708
9727
  [built?.client]
9709
9728
  );
9710
9729
  const ui = useMemo4(() => normalizeUi(props.config ?? { operatorId: "", publicKey: "" }), [props.config]);
9711
- const rootRef = useRef16(null);
9712
- const introDoneRef = useRef16(false);
9730
+ const rootRef = useRef17(null);
9731
+ const introDoneRef = useRef17(false);
9713
9732
  const markIntroDone = useCallback12(() => {
9714
9733
  introDoneRef.current = true;
9715
9734
  }, []);
@@ -9743,14 +9762,14 @@ function StatsWidget(props) {
9743
9762
  pinnedMatchIds
9744
9763
  });
9745
9764
  const todayHasContent = visibleGroupsOf(discovery.groups, discovery.states).length > 0;
9746
- useEffect20(() => {
9765
+ useEffect21(() => {
9747
9766
  setHasToday(todayHasContent);
9748
9767
  }, [todayHasContent]);
9749
9768
  const gamesResult = useGames(built?.conversation ?? null, { activeTab: monitor.activeTab });
9750
9769
  const leaderboardResult = useLeaderboard(built?.conversation ?? null, { activeTab: monitor.activeTab });
9751
9770
  const markTodayActivity = monitor.markTodayActivity;
9752
- const prevLiveCountRef = useRef16(0);
9753
- useEffect20(() => {
9771
+ const prevLiveCountRef = useRef17(0);
9772
+ useEffect21(() => {
9754
9773
  const rose = prevLiveCountRef.current === 0 && discovery.liveCount > 0;
9755
9774
  prevLiveCountRef.current = discovery.liveCount;
9756
9775
  if (rose) markTodayActivity();
@@ -9793,11 +9812,11 @@ function StatsWidget(props) {
9793
9812
  const operatorUserId = cfg?.userContext?.operatorUserId;
9794
9813
  const anonymousUserId = cfg?.userContext?.anonymousUserId;
9795
9814
  const conversationId = controller.state.conversationId ?? void 0;
9796
- useEffect20(() => {
9815
+ useEffect21(() => {
9797
9816
  if (!logger) return;
9798
9817
  logger.setIdentity({ operatorUserId, anonymousUserId, conversationId });
9799
9818
  }, [logger, operatorUserId, anonymousUserId, conversationId]);
9800
- useEffect20(() => {
9819
+ useEffect21(() => {
9801
9820
  if (!logger) return;
9802
9821
  logger.resume();
9803
9822
  const onHide = () => {
@@ -9815,7 +9834,7 @@ function StatsWidget(props) {
9815
9834
  logger.dispose();
9816
9835
  };
9817
9836
  }, [logger]);
9818
- useEffect20(() => {
9837
+ useEffect21(() => {
9819
9838
  if (!built || !ui.injectStyles) return;
9820
9839
  const node = rootRef.current?.getRootNode();
9821
9840
  if (node) injectStyles(node);