@sensiblestats/widget-react 0.81.0 → 0.81.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.cjs CHANGED
@@ -37,7 +37,7 @@ __export(index_exports, {
37
37
  module.exports = __toCommonJS(index_exports);
38
38
 
39
39
  // src/StatsWidget.tsx
40
- var import_react60 = require("react");
40
+ var import_react61 = require("react");
41
41
  var import_widget_sdk6 = require("@sensiblestats/widget-sdk");
42
42
 
43
43
  // src/kickoff.ts
@@ -158,6 +158,7 @@ var STRINGS = {
158
158
  allLeagues: "All leagues",
159
159
  searchLeaguesPlaceholder: "Search leagues or teams",
160
160
  noLeagueResults: "No league or team matches that search.",
161
+ clearSearchLabel: "Clear search",
161
162
  starOnLabel: "Add to Your leagues",
162
163
  starOffLabel: "Remove from Your leagues",
163
164
  starredToast: "Added to Your leagues.",
@@ -523,6 +524,7 @@ var STRINGS = {
523
524
  allLeagues: "T\xFCm ligler",
524
525
  searchLeaguesPlaceholder: "Lig veya tak\u0131m ara",
525
526
  noLeagueResults: "Aramana uyan lig veya tak\u0131m yok.",
527
+ clearSearchLabel: "Aramay\u0131 temizle",
526
528
  starOnLabel: "Liglerine ekle",
527
529
  starOffLabel: "Liglerinden \xE7\u0131kar",
528
530
  starredToast: "Liglerin b\xF6l\xFCm\xFCne eklendi.",
@@ -885,6 +887,7 @@ function normalizeUi(cfg) {
885
887
  allLeagues: strings.allLeagues,
886
888
  searchLeaguesPlaceholder: strings.searchLeaguesPlaceholder,
887
889
  noLeagueResults: strings.noLeagueResults,
890
+ clearSearchLabel: strings.clearSearchLabel,
888
891
  starOnLabel: strings.starOnLabel,
889
892
  starOffLabel: strings.starOffLabel,
890
893
  starredToast: strings.starredToast,
@@ -3449,7 +3452,7 @@ function ChatFab({ label, greeting, popupText, logoUrl, onOpen, onDismissPopup,
3449
3452
  }
3450
3453
 
3451
3454
  // src/components/ChatPanel.tsx
3452
- var import_react59 = require("react");
3455
+ var import_react60 = require("react");
3453
3456
 
3454
3457
  // src/components/ChatHeader.tsx
3455
3458
  var import_react15 = require("react");
@@ -3854,7 +3857,8 @@ function PinToggle({ pin, monitor, ui, market }) {
3854
3857
  const key = pinKey(pin);
3855
3858
  const pinned = monitor.isPinned(key);
3856
3859
  const labels = pin.kind === "match" ? { pin: ui.matchPinLabel, unpin: ui.matchUnpinLabel } : { pin: ui.pinLabel, unpin: ui.unpinLabel };
3857
- const onClick = () => {
3860
+ const onClick = (e) => {
3861
+ e.stopPropagation();
3858
3862
  if (pin.kind === "match" && !monitor.isPinned(key)) {
3859
3863
  if (monitor.pinMatch({ matchId: pin.matchId, marketDeveloperName: market }) === "added") {
3860
3864
  log?.log({ name: "pin_add", entityType: "match", entityId: String(pin.matchId), marketDeveloperName: pin.marketDeveloperName });
@@ -5958,7 +5962,7 @@ function OddsPanel({ monitor, ui, slip }) {
5958
5962
  }
5959
5963
 
5960
5964
  // src/components/TodayPanel.tsx
5961
- var import_react40 = require("react");
5965
+ var import_react41 = require("react");
5962
5966
 
5963
5967
  // src/placement.ts
5964
5968
  function placeLeagues(visible, pinnedMatchIds) {
@@ -6186,6 +6190,9 @@ function LeagueDetail({ group, position, states, stale, ui, monitor, starTap, on
6186
6190
  ] });
6187
6191
  }
6188
6192
 
6193
+ // src/components/games/ui/SearchField.tsx
6194
+ var import_react40 = require("react");
6195
+
6189
6196
  // src/components/games/ui/icons.tsx
6190
6197
  var import_jsx_runtime58 = require("react/jsx-runtime");
6191
6198
  var svg = (size, children, fill = false) => /* @__PURE__ */ (0, import_jsx_runtime58.jsx)(
@@ -6222,7 +6229,13 @@ var IconFlame = ({ size = 16 }) => svg(size, /* @__PURE__ */ (0, import_jsx_runt
6222
6229
 
6223
6230
  // src/components/games/ui/SearchField.tsx
6224
6231
  var import_jsx_runtime59 = require("react/jsx-runtime");
6225
- function SearchField({ id, label, labelHidden = false, placeholder, value, onChange, disabled, inputRef, onKeyDown }) {
6232
+ function SearchField({ id, label, labelHidden = false, placeholder, value, onChange, disabled, inputRef, onKeyDown, clearLabel }) {
6233
+ const localRef = (0, import_react40.useRef)(null);
6234
+ const setInputRef = (0, import_react40.useCallback)((node) => {
6235
+ localRef.current = node;
6236
+ if (typeof inputRef === "function") inputRef(node);
6237
+ else if (inputRef) inputRef.current = node;
6238
+ }, [inputRef]);
6226
6239
  return /* @__PURE__ */ (0, import_jsx_runtime59.jsxs)("div", { className: "ss-g-search", children: [
6227
6240
  /* @__PURE__ */ (0, import_jsx_runtime59.jsx)("label", { htmlFor: id, className: labelHidden ? "ss-g-sr" : "ss-g-search-label", children: label }),
6228
6241
  /* @__PURE__ */ (0, import_jsx_runtime59.jsxs)("div", { className: "ss-g-search-box", children: [
@@ -6231,7 +6244,7 @@ function SearchField({ id, label, labelHidden = false, placeholder, value, onCha
6231
6244
  "input",
6232
6245
  {
6233
6246
  id,
6234
- ref: inputRef,
6247
+ ref: setInputRef,
6235
6248
  type: "text",
6236
6249
  autoComplete: "off",
6237
6250
  placeholder,
@@ -6240,7 +6253,20 @@ function SearchField({ id, label, labelHidden = false, placeholder, value, onCha
6240
6253
  onKeyDown,
6241
6254
  onChange: (e) => onChange(e.target.value)
6242
6255
  }
6243
- )
6256
+ ),
6257
+ clearLabel && value.length > 0 ? /* @__PURE__ */ (0, import_jsx_runtime59.jsx)(
6258
+ "button",
6259
+ {
6260
+ type: "button",
6261
+ className: "ss-g-search-clear",
6262
+ "aria-label": clearLabel,
6263
+ onClick: () => {
6264
+ onChange("");
6265
+ localRef.current?.focus();
6266
+ },
6267
+ children: /* @__PURE__ */ (0, import_jsx_runtime59.jsx)(IconClose, { size: 11 })
6268
+ }
6269
+ ) : null
6244
6270
  ] })
6245
6271
  ] });
6246
6272
  }
@@ -6249,23 +6275,23 @@ function SearchField({ id, label, labelHidden = false, placeholder, value, onCha
6249
6275
  var import_jsx_runtime60 = require("react/jsx-runtime");
6250
6276
  function TodayPanel({ discovery, ui, monitor }) {
6251
6277
  const { groups, states, stale, starLeague } = discovery;
6252
- const searchId = (0, import_react40.useId)();
6253
- const [query, setQuery] = (0, import_react40.useState)("");
6254
- const [selectedCompetitionId, setSelectedCompetitionId] = (0, import_react40.useState)(null);
6255
- const [toast, setToast] = (0, import_react40.useState)(null);
6256
- (0, import_react40.useEffect)(() => {
6278
+ const searchId = (0, import_react41.useId)();
6279
+ const [query, setQuery] = (0, import_react41.useState)("");
6280
+ const [selectedCompetitionId, setSelectedCompetitionId] = (0, import_react41.useState)(null);
6281
+ const [toast, setToast] = (0, import_react41.useState)(null);
6282
+ (0, import_react41.useEffect)(() => {
6257
6283
  if (toast === null) return;
6258
6284
  const id = setTimeout(() => setToast(null), 4e3);
6259
6285
  return () => clearTimeout(id);
6260
6286
  }, [toast]);
6261
6287
  const visibleGroups = visibleGroupsOf(groups, states);
6262
- const pinnedMatchIds = (0, import_react40.useMemo)(
6288
+ const pinnedMatchIds = (0, import_react41.useMemo)(
6263
6289
  () => monitor.pins.filter((p) => p.kind === "match").map((p) => p.matchId),
6264
6290
  [monitor.pins]
6265
6291
  );
6266
- const placement = (0, import_react40.useMemo)(() => placeLeagues(visibleGroups, pinnedMatchIds), [visibleGroups, pinnedMatchIds]);
6292
+ const placement = (0, import_react41.useMemo)(() => placeLeagues(visibleGroups, pinnedMatchIds), [visibleGroups, pinnedMatchIds]);
6267
6293
  const starTap = useStarTap(starLeague);
6268
- const gridStarTap = (0, import_react40.useMemo)(() => ({
6294
+ const gridStarTap = (0, import_react41.useMemo)(() => ({
6269
6295
  pendingId: starTap.pendingId,
6270
6296
  tap: async (competitionId, next) => {
6271
6297
  const ok = await starTap.tap(competitionId, next);
@@ -6279,7 +6305,7 @@ function TodayPanel({ discovery, ui, monitor }) {
6279
6305
  }, {});
6280
6306
  const openIndex = selectedCompetitionId === null ? -1 : placement.order.findIndex((g) => g.competitionId === selectedCompetitionId);
6281
6307
  const openGroup = openIndex === -1 ? void 0 : placement.order[openIndex];
6282
- (0, import_react40.useEffect)(() => {
6308
+ (0, import_react41.useEffect)(() => {
6283
6309
  if (selectedCompetitionId !== null && openGroup === void 0) setSelectedCompetitionId(null);
6284
6310
  }, [selectedCompetitionId, openGroup]);
6285
6311
  const liveRows = stale ? [] : visibleGroups.flatMap((group) => group.matches.filter((m) => isTreatedLive(states[m.matchId], stale)).map((match) => ({ match, rank: group.rank }))).sort((a, b) => a.rank - b.rank);
@@ -6324,7 +6350,7 @@ function TodayPanel({ discovery, ui, monitor }) {
6324
6350
  ] }) });
6325
6351
  }
6326
6352
  const searching = query.trim().length > 0;
6327
- const searchResults = searching ? visibleGroups.filter((g) => matchesQuery(g, query)) : [];
6353
+ const searchResults = searching ? placement.order.filter((g) => matchesQuery(g, query)) : [];
6328
6354
  return /* @__PURE__ */ (0, import_jsx_runtime60.jsxs)("div", { className: "ss-w-today-root", children: [
6329
6355
  /* @__PURE__ */ (0, import_jsx_runtime60.jsxs)("div", { className: "ss-w-mon-list", children: [
6330
6356
  stale && /* @__PURE__ */ (0, import_jsx_runtime60.jsx)("div", { className: "ss-w-stale", children: ui.staleStates }),
@@ -6337,21 +6363,41 @@ function TodayPanel({ discovery, ui, monitor }) {
6337
6363
  labelHidden: true,
6338
6364
  placeholder: ui.searchLeaguesPlaceholder,
6339
6365
  value: query,
6340
- onChange: setQuery
6366
+ onChange: setQuery,
6367
+ clearLabel: ui.clearSearchLabel
6341
6368
  }
6342
6369
  ),
6343
- searching ? searchResults.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime60.jsx)("div", { className: "ss-w-today-empty", children: ui.noLeagueResults }) : /* @__PURE__ */ (0, import_jsx_runtime60.jsx)("div", { className: "ss-w-today-tiles", children: searchResults.map((group) => /* @__PURE__ */ (0, import_jsx_runtime60.jsx)(
6344
- LeagueTile,
6345
- {
6346
- group,
6347
- starClickable: starClickable(group, placement.pinnedCompetitionId),
6348
- disambiguate: (nameCounts[group.competitionName] ?? 0) > 1,
6349
- onOpen: () => setSelectedCompetitionId(group.competitionId),
6350
- starTap: gridStarTap,
6351
- ui
6352
- },
6353
- group.competitionId
6354
- )) }) : /* @__PURE__ */ (0, import_jsx_runtime60.jsxs)(import_jsx_runtime60.Fragment, { children: [
6370
+ searching ? searchResults.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime60.jsx)("div", { className: "ss-w-today-empty", children: ui.noLeagueResults }) : /* @__PURE__ */ (0, import_jsx_runtime60.jsx)(import_jsx_runtime60.Fragment, { children: searchResults.map((group) => /* @__PURE__ */ (0, import_jsx_runtime60.jsxs)("div", { className: "ss-w-today-search-block", children: [
6371
+ /* @__PURE__ */ (0, import_jsx_runtime60.jsxs)("div", { className: "ss-w-today-search-group", children: [
6372
+ /* @__PURE__ */ (0, import_jsx_runtime60.jsx)(Crest2, { url: group.competitionImagePath ?? void 0, name: group.competitionName, kind: "comp" }),
6373
+ /* @__PURE__ */ (0, import_jsx_runtime60.jsxs)("span", { className: "ss-w-today-search-group-name", children: [
6374
+ group.competitionName,
6375
+ (nameCounts[group.competitionName] ?? 0) > 1 && group.competitionCountry ? /* @__PURE__ */ (0, import_jsx_runtime60.jsxs)("span", { className: "ss-w-today-tile-country", children: [
6376
+ " (",
6377
+ group.competitionCountry,
6378
+ ")"
6379
+ ] }) : null
6380
+ ] })
6381
+ ] }),
6382
+ group.matches.map((match) => /* @__PURE__ */ (0, import_jsx_runtime60.jsx)(
6383
+ "div",
6384
+ {
6385
+ role: "button",
6386
+ tabIndex: 0,
6387
+ className: "ss-w-today-search-row",
6388
+ onClick: () => setSelectedCompetitionId(group.competitionId),
6389
+ onKeyDown: (e) => {
6390
+ if (e.target !== e.currentTarget) return;
6391
+ if (e.key === "Enter" || e.key === " ") {
6392
+ e.preventDefault();
6393
+ setSelectedCompetitionId(group.competitionId);
6394
+ }
6395
+ },
6396
+ children: /* @__PURE__ */ (0, import_jsx_runtime60.jsx)(FixtureRow, { match, state: states[match.matchId], stale, ui, monitor })
6397
+ },
6398
+ match.matchId
6399
+ ))
6400
+ ] }, group.competitionId)) }) : /* @__PURE__ */ (0, import_jsx_runtime60.jsxs)(import_jsx_runtime60.Fragment, { children: [
6355
6401
  /* @__PURE__ */ (0, import_jsx_runtime60.jsxs)("div", { className: "ss-w-today-sec", children: [
6356
6402
  placement.personal ? ui.yourLeagues : ui.topLeagues,
6357
6403
  !placement.personal && /* @__PURE__ */ (0, import_jsx_runtime60.jsx)("span", { className: "ss-w-today-sec-sub", children: ui.topLeaguesSub })
@@ -6388,7 +6434,7 @@ function TodayPanel({ discovery, ui, monitor }) {
6388
6434
  }
6389
6435
 
6390
6436
  // src/components/GamesPanel.tsx
6391
- var import_react54 = require("react");
6437
+ var import_react55 = require("react");
6392
6438
 
6393
6439
  // src/components/GamesLoginWall.tsx
6394
6440
  var import_jsx_runtime61 = require("react/jsx-runtime");
@@ -6397,7 +6443,7 @@ function GamesLoginWall({ ui }) {
6397
6443
  }
6398
6444
 
6399
6445
  // src/components/GamesHub.tsx
6400
- var import_react41 = require("react");
6446
+ var import_react42 = require("react");
6401
6447
 
6402
6448
  // src/components/games/ui/gameMeta.ts
6403
6449
  function prettifyGameId(gameId) {
@@ -6548,8 +6594,8 @@ function pickHeroGame(games) {
6548
6594
  }
6549
6595
  var tileKey = (g) => `${g.gameId}-${g.gameDay}-${g.fixtureId}`;
6550
6596
  function GamesHub({ games, myWeeklyRow, weeklyPrize, onOpen, ui }) {
6551
- const [, setTick] = (0, import_react41.useState)(0);
6552
- (0, import_react41.useEffect)(() => {
6597
+ const [, setTick] = (0, import_react42.useState)(0);
6598
+ (0, import_react42.useEffect)(() => {
6553
6599
  const id = setInterval(() => setTick((t) => t + 1), 6e4);
6554
6600
  return () => clearInterval(id);
6555
6601
  }, []);
@@ -6609,10 +6655,10 @@ function GamesHub({ games, myWeeklyRow, weeklyPrize, onOpen, ui }) {
6609
6655
  }
6610
6656
 
6611
6657
  // src/components/GameScreenHost.tsx
6612
- var import_react53 = require("react");
6658
+ var import_react54 = require("react");
6613
6659
 
6614
6660
  // src/useGamePlay.ts
6615
- var import_react42 = require("react");
6661
+ var import_react43 = require("react");
6616
6662
  function toSubmitResult(payload) {
6617
6663
  return {
6618
6664
  // 'pending' means the play is recorded but awaiting resolution (fixture games)
@@ -6624,17 +6670,17 @@ function toSubmitResult(payload) {
6624
6670
  };
6625
6671
  }
6626
6672
  function useGamePlay(conversation, { gameId, gameDay, fixtureId, locale, refresh }) {
6627
- const [result, setResult] = (0, import_react42.useState)(null);
6628
- const [submitting, setSubmitting] = (0, import_react42.useState)(false);
6629
- const [rawStatus, setRawStatus] = (0, import_react42.useState)(null);
6630
- const inFlightRef = (0, import_react42.useRef)(false);
6631
- const convRef = (0, import_react42.useRef)(conversation);
6673
+ const [result, setResult] = (0, import_react43.useState)(null);
6674
+ const [submitting, setSubmitting] = (0, import_react43.useState)(false);
6675
+ const [rawStatus, setRawStatus] = (0, import_react43.useState)(null);
6676
+ const inFlightRef = (0, import_react43.useRef)(false);
6677
+ const convRef = (0, import_react43.useRef)(conversation);
6632
6678
  convRef.current = conversation;
6633
- const optsRef = (0, import_react42.useRef)({ gameId, gameDay, fixtureId, locale, refresh });
6679
+ const optsRef = (0, import_react43.useRef)({ gameId, gameDay, fixtureId, locale, refresh });
6634
6680
  optsRef.current = { gameId, gameDay, fixtureId, locale, refresh };
6635
- const resultRef = (0, import_react42.useRef)(null);
6681
+ const resultRef = (0, import_react43.useRef)(null);
6636
6682
  resultRef.current = result;
6637
- const refetch = (0, import_react42.useCallback)(async () => {
6683
+ const refetch = (0, import_react43.useCallback)(async () => {
6638
6684
  const conv = convRef.current;
6639
6685
  if (!conv) return;
6640
6686
  const opts = optsRef.current;
@@ -6650,7 +6696,7 @@ function useGamePlay(conversation, { gameId, gameDay, fixtureId, locale, refresh
6650
6696
  } catch {
6651
6697
  }
6652
6698
  }, []);
6653
- const submit = (0, import_react42.useCallback)(async (answerJson) => {
6699
+ const submit = (0, import_react43.useCallback)(async (answerJson) => {
6654
6700
  const conv = convRef.current;
6655
6701
  if (!conv || inFlightRef.current) return;
6656
6702
  inFlightRef.current = true;
@@ -6677,14 +6723,14 @@ function useGamePlay(conversation, { gameId, gameDay, fixtureId, locale, refresh
6677
6723
  setSubmitting(false);
6678
6724
  }
6679
6725
  }, [refetch]);
6680
- const hydrate = (0, import_react42.useCallback)(() => {
6726
+ const hydrate = (0, import_react43.useCallback)(() => {
6681
6727
  void refetch();
6682
6728
  }, [refetch]);
6683
6729
  return { result, submitting, submit, hydrate, rawStatus };
6684
6730
  }
6685
6731
 
6686
6732
  // src/components/games/MysteryTigerGame.tsx
6687
- var import_react44 = require("react");
6733
+ var import_react45 = require("react");
6688
6734
 
6689
6735
  // src/components/games/nationFlags.ts
6690
6736
  var FLAGS = {
@@ -6895,7 +6941,7 @@ function isNationCode(flag) {
6895
6941
  }
6896
6942
 
6897
6943
  // src/components/games/PlayerAvatar.tsx
6898
- var import_react43 = require("react");
6944
+ var import_react44 = require("react");
6899
6945
  var import_jsx_runtime66 = require("react/jsx-runtime");
6900
6946
  function initialsOf(name) {
6901
6947
  const parts = name.trim().split(/\s+/).filter(Boolean);
@@ -6913,7 +6959,7 @@ function PlayerAvatar({
6913
6959
  imagePath,
6914
6960
  className
6915
6961
  }) {
6916
- const [failed, setFailed] = (0, import_react43.useState)(false);
6962
+ const [failed, setFailed] = (0, import_react44.useState)(false);
6917
6963
  const showImage = Boolean(imagePath) && !isPlaceholderImage(imagePath) && !failed;
6918
6964
  return /* @__PURE__ */ (0, import_jsx_runtime66.jsx)("div", { className, "aria-hidden": "true", children: showImage ? /* @__PURE__ */ (0, import_jsx_runtime66.jsx)("img", { src: imagePath, alt: "", loading: "lazy", onError: () => setFailed(true) }) : /* @__PURE__ */ (0, import_jsx_runtime66.jsx)("span", { className: "ss-w-av-initials", children: initialsOf(name) }) });
6919
6965
  }
@@ -7154,8 +7200,8 @@ function MysteryTigerGame({
7154
7200
  onBack
7155
7201
  }) {
7156
7202
  const t = ui.games.mysteryTiger;
7157
- const [query, setQuery] = (0, import_react44.useState)("");
7158
- const inputId = (0, import_react44.useId)();
7203
+ const [query, setQuery] = (0, import_react45.useState)("");
7204
+ const inputId = (0, import_react45.useId)();
7159
7205
  const clientState = parseClientState(result?.clientStateJson);
7160
7206
  const guessResults = clientState?.guessResults ?? [];
7161
7207
  const alreadyGuessedIds = new Set(guessResults.map((g) => g.playerId));
@@ -7416,13 +7462,13 @@ function HigherOrLowerGame({
7416
7462
  }
7417
7463
 
7418
7464
  // src/components/games/CareerPathGame.tsx
7419
- var import_react46 = require("react");
7465
+ var import_react47 = require("react");
7420
7466
 
7421
7467
  // src/components/games/ui/CrestShield.tsx
7422
- var import_react45 = require("react");
7468
+ var import_react46 = require("react");
7423
7469
  var import_jsx_runtime77 = require("react/jsx-runtime");
7424
7470
  function CrestShield({ src, name, size = 28 }) {
7425
- const [failed, setFailed] = (0, import_react45.useState)(false);
7471
+ const [failed, setFailed] = (0, import_react46.useState)(false);
7426
7472
  if (src && !isPlaceholderImage(src) && !failed) {
7427
7473
  return /* @__PURE__ */ (0, import_jsx_runtime77.jsx)("img", { className: "ss-g-crest", src, alt: name, width: size, height: size, loading: "lazy", onError: () => setFailed(true) });
7428
7474
  }
@@ -7454,8 +7500,8 @@ function CareerPathGame({
7454
7500
  }) {
7455
7501
  const s = ui.games.careerPath;
7456
7502
  const title = gameTitle({ gameId: "career-path" }, ui.games.titles);
7457
- const [query, setQuery] = (0, import_react46.useState)("");
7458
- const inputId = (0, import_react46.useId)();
7503
+ const [query, setQuery] = (0, import_react47.useState)("");
7504
+ const inputId = (0, import_react47.useId)();
7459
7505
  const clientState = parseClientState3(result?.clientStateJson);
7460
7506
  const alreadyGuessedIds = new Set(clientState?.guessResults.map((g) => g.playerId) ?? []);
7461
7507
  const isOver = result?.alreadyPlayed === true || clientState?.solved === true || clientState?.failed === true;
@@ -7561,7 +7607,7 @@ function CareerPathGame({
7561
7607
  }
7562
7608
 
7563
7609
  // src/components/games/BeatTheGridGame.tsx
7564
- var import_react47 = __toESM(require("react"), 1);
7610
+ var import_react48 = __toESM(require("react"), 1);
7565
7611
 
7566
7612
  // src/components/games/ui/OptionList.tsx
7567
7613
  var import_jsx_runtime79 = require("react/jsx-runtime");
@@ -7650,10 +7696,10 @@ function SearchSheet({
7650
7696
  ui
7651
7697
  }) {
7652
7698
  const s = ui.games.beatTheGrid;
7653
- const [query, setQuery] = (0, import_react47.useState)("");
7654
- const inputId = (0, import_react47.useId)();
7655
- const inputRef = (0, import_react47.useRef)(null);
7656
- (0, import_react47.useEffect)(() => {
7699
+ const [query, setQuery] = (0, import_react48.useState)("");
7700
+ const inputId = (0, import_react48.useId)();
7701
+ const inputRef = (0, import_react48.useRef)(null);
7702
+ (0, import_react48.useEffect)(() => {
7657
7703
  inputRef.current?.focus();
7658
7704
  }, [row, col]);
7659
7705
  const filtered = playerPool.filter(
@@ -7718,7 +7764,7 @@ function BeatTheGridGame({
7718
7764
  }) {
7719
7765
  const s = ui.games.beatTheGrid;
7720
7766
  const title = gameTitle({ gameId: "beat-the-grid" }, ui.games.titles);
7721
- const [activeCell, setActiveCell] = (0, import_react47.useState)(null);
7767
+ const [activeCell, setActiveCell] = (0, import_react48.useState)(null);
7722
7768
  const clientState = parseClientState4(result?.clientStateJson);
7723
7769
  const filledCells = clientState?.cells ?? [];
7724
7770
  const isLocked2 = result?.alreadyPlayed === true || clientState?.isComplete === true;
@@ -7792,7 +7838,7 @@ function BeatTheGridGame({
7792
7838
  /* @__PURE__ */ (0, import_jsx_runtime80.jsx)("span", { "aria-hidden": "true", children: abbr }),
7793
7839
  /* @__PURE__ */ (0, import_jsx_runtime80.jsx)("span", { className: "ss-g-sr", children: rowLabel })
7794
7840
  ] });
7795
- return /* @__PURE__ */ (0, import_jsx_runtime80.jsxs)(import_react47.default.Fragment, { children: [
7841
+ return /* @__PURE__ */ (0, import_jsx_runtime80.jsxs)(import_react48.default.Fragment, { children: [
7796
7842
  /* @__PURE__ */ (0, import_jsx_runtime80.jsx)("div", { className: "ss-g-btg-rowhdr", "data-meta": rowMeta ? "true" : void 0, children: rowHeaderContent }),
7797
7843
  cols.map((colLabel, colIdx) => {
7798
7844
  const filled = findCellResult(filledCells, rowIdx, colIdx);
@@ -7873,7 +7919,7 @@ function BeatTheGridGame({
7873
7919
  }
7874
7920
 
7875
7921
  // src/components/games/GuessTheXiGame.tsx
7876
- var import_react48 = require("react");
7922
+ var import_react49 = require("react");
7877
7923
 
7878
7924
  // src/components/games/ui/PitchSvg.tsx
7879
7925
  var import_jsx_runtime81 = require("react/jsx-runtime");
@@ -7962,8 +8008,8 @@ function GuessTheXiGame({
7962
8008
  onBack
7963
8009
  }) {
7964
8010
  const t = ui.games.guessTheXi;
7965
- const [query, setQuery] = (0, import_react48.useState)("");
7966
- const inputId = (0, import_react48.useId)();
8011
+ const [query, setQuery] = (0, import_react49.useState)("");
8012
+ const inputId = (0, import_react49.useId)();
7967
8013
  const clientState = parseClientState5(result?.clientStateJson);
7968
8014
  const isOver = result?.alreadyPlayed === true || clientState?.status === "solved" || clientState?.status === "failed";
7969
8015
  const solved = clientState?.status === "solved";
@@ -8105,7 +8151,7 @@ function GuessTheXiGame({
8105
8151
  }
8106
8152
 
8107
8153
  // src/components/games/DailyQuizGame.tsx
8108
- var import_react49 = require("react");
8154
+ var import_react50 = require("react");
8109
8155
  var import_jsx_runtime83 = require("react/jsx-runtime");
8110
8156
  function parseClientState6(json) {
8111
8157
  if (!json) return null;
@@ -8146,8 +8192,8 @@ function DailyQuizGame({
8146
8192
  }) {
8147
8193
  const s = ui.games.dailyQuiz;
8148
8194
  const title = gameTitle({ gameId: "daily-quiz" }, ui.games.titles);
8149
- const [selections, setSelections] = (0, import_react49.useState)(/* @__PURE__ */ new Map());
8150
- const [page, setPage] = (0, import_react49.useState)(0);
8195
+ const [selections, setSelections] = (0, import_react50.useState)(/* @__PURE__ */ new Map());
8196
+ const [page, setPage] = (0, import_react50.useState)(0);
8151
8197
  const clientState = parseClientState6(result?.clientStateJson);
8152
8198
  const results = clientState?.results ?? [];
8153
8199
  const isRevealed = results.length > 0 || result?.alreadyPlayed === true;
@@ -8257,7 +8303,7 @@ function DailyQuizGame({
8257
8303
  }
8258
8304
 
8259
8305
  // src/components/games/MatchdayPredictorGame.tsx
8260
- var import_react50 = require("react");
8306
+ var import_react51 = require("react");
8261
8307
  var import_jsx_runtime84 = require("react/jsx-runtime");
8262
8308
  var SCORER_SEARCH_THRESHOLD = 9;
8263
8309
  function parseClientState7(json) {
@@ -8353,12 +8399,12 @@ function MatchdayPredictorGame({
8353
8399
  onBack
8354
8400
  }) {
8355
8401
  const t = ui.games.predictor;
8356
- const [homeScore, setHomeScore] = (0, import_react50.useState)(0);
8357
- const [awayScore, setAwayScore] = (0, import_react50.useState)(0);
8358
- const [firstScorerPlayerId, setFirstScorerPlayerId] = (0, import_react50.useState)(null);
8359
- const [lastEdited, setLastEdited] = (0, import_react50.useState)("home");
8360
- const [query, setQuery] = (0, import_react50.useState)("");
8361
- const searchId = (0, import_react50.useId)();
8402
+ const [homeScore, setHomeScore] = (0, import_react51.useState)(0);
8403
+ const [awayScore, setAwayScore] = (0, import_react51.useState)(0);
8404
+ const [firstScorerPlayerId, setFirstScorerPlayerId] = (0, import_react51.useState)(null);
8405
+ const [lastEdited, setLastEdited] = (0, import_react51.useState)("home");
8406
+ const [query, setQuery] = (0, import_react51.useState)("");
8407
+ const searchId = (0, import_react51.useId)();
8362
8408
  const clientState = parseClientState7(result?.clientStateJson);
8363
8409
  const alreadyPlayed = result?.alreadyPlayed === true;
8364
8410
  const header = /* @__PURE__ */ (0, import_jsx_runtime84.jsx)(
@@ -8525,7 +8571,7 @@ function MatchdayPredictorGame({
8525
8571
  }
8526
8572
 
8527
8573
  // src/components/games/StartingXiGame.tsx
8528
- var import_react51 = require("react");
8574
+ var import_react52 = require("react");
8529
8575
  var import_jsx_runtime85 = require("react/jsx-runtime");
8530
8576
  var POINTS_PER_STARTER = 8;
8531
8577
  var XI_SIZE = 11;
@@ -8569,10 +8615,10 @@ function StartingXiGame({
8569
8615
  lockAtUtc
8570
8616
  }) {
8571
8617
  const t = ui.games.startingXi;
8572
- const [slotPlayers, setSlotPlayers] = (0, import_react51.useState)(() => Array(XI_SIZE).fill(null));
8573
- const [active, setActive] = (0, import_react51.useState)(0);
8574
- const [query, setQuery] = (0, import_react51.useState)("");
8575
- const searchId = (0, import_react51.useId)();
8618
+ const [slotPlayers, setSlotPlayers] = (0, import_react52.useState)(() => Array(XI_SIZE).fill(null));
8619
+ const [active, setActive] = (0, import_react52.useState)(0);
8620
+ const [query, setQuery] = (0, import_react52.useState)("");
8621
+ const searchId = (0, import_react52.useId)();
8576
8622
  const clientState = parseClientState8(result?.clientStateJson);
8577
8623
  const alreadyPlayed = result?.alreadyPlayed === true;
8578
8624
  const header = /* @__PURE__ */ (0, import_jsx_runtime85.jsx)(
@@ -8711,7 +8757,7 @@ function StartingXiGame({
8711
8757
  }
8712
8758
 
8713
8759
  // src/components/games/StatLadderGame.tsx
8714
- var import_react52 = require("react");
8760
+ var import_react53 = require("react");
8715
8761
  var import_jsx_runtime86 = require("react/jsx-runtime");
8716
8762
  function ladderClue(ladder) {
8717
8763
  const mystery = ladder.find((r) => r.rank === 2);
@@ -8748,9 +8794,9 @@ function StatLadderGame({
8748
8794
  onBack
8749
8795
  }) {
8750
8796
  const t = ui.games.statLadder;
8751
- const [query, setQuery] = (0, import_react52.useState)("");
8752
- const [selectedId, setSelectedId] = (0, import_react52.useState)(null);
8753
- const searchId = (0, import_react52.useId)();
8797
+ const [query, setQuery] = (0, import_react53.useState)("");
8798
+ const [selectedId, setSelectedId] = (0, import_react53.useState)(null);
8799
+ const searchId = (0, import_react53.useId)();
8754
8800
  const clientState = parseClientState9(result?.clientStateJson);
8755
8801
  const revealed = clientState != null;
8756
8802
  const header = /* @__PURE__ */ (0, import_jsx_runtime86.jsx)(GameHeader, { title: gameTitle({ gameId: "stat-ladder" }, ui.games.titles), eyebrow: t.eyebrow, onBack, backLabel: ui.back });
@@ -8956,8 +9002,8 @@ function GameScreenHost({
8956
9002
  ui
8957
9003
  }) {
8958
9004
  const { gameId, fixtureId, gameDay = "", lockAtUtc = null } = selected;
8959
- const [configJson, setConfigJson] = (0, import_react53.useState)(null);
8960
- (0, import_react53.useEffect)(() => {
9005
+ const [configJson, setConfigJson] = (0, import_react54.useState)(null);
9006
+ (0, import_react54.useEffect)(() => {
8961
9007
  setConfigJson(null);
8962
9008
  if (!conversation) return;
8963
9009
  let cancelled = false;
@@ -8980,12 +9026,12 @@ function GameScreenHost({
8980
9026
  fixtureId: fixtureId || void 0,
8981
9027
  locale: ui.games.lang
8982
9028
  });
8983
- (0, import_react53.useEffect)(() => {
9029
+ (0, import_react54.useEffect)(() => {
8984
9030
  if (conversation) hydrate();
8985
9031
  }, [conversation, gameId]);
8986
- const hydrateRef = (0, import_react53.useRef)(hydrate);
9032
+ const hydrateRef = (0, import_react54.useRef)(hydrate);
8987
9033
  hydrateRef.current = hydrate;
8988
- (0, import_react53.useEffect)(() => {
9034
+ (0, import_react54.useEffect)(() => {
8989
9035
  if (!FIXTURE_GAME_IDS.has(gameId)) return;
8990
9036
  if (rawStatus !== "pending") return;
8991
9037
  const timerId = setInterval(() => {
@@ -9120,8 +9166,8 @@ function GamesPanel({
9120
9166
  leaderboard,
9121
9167
  refreshHub
9122
9168
  }) {
9123
- const [selected, setSelected] = (0, import_react54.useState)(null);
9124
- (0, import_react54.useEffect)(() => {
9169
+ const [selected, setSelected] = (0, import_react55.useState)(null);
9170
+ (0, import_react55.useEffect)(() => {
9125
9171
  ensureGamesFonts();
9126
9172
  }, []);
9127
9173
  if (!loggedIn) return /* @__PURE__ */ (0, import_jsx_runtime89.jsx)(GamesLoginWall, { ui });
@@ -9152,7 +9198,7 @@ function GamesPanel({
9152
9198
  }
9153
9199
 
9154
9200
  // src/components/Leaderboard.tsx
9155
- var import_react55 = require("react");
9201
+ var import_react56 = require("react");
9156
9202
 
9157
9203
  // src/components/LeaderboardRow.tsx
9158
9204
  var import_jsx_runtime90 = require("react/jsx-runtime");
@@ -9237,7 +9283,7 @@ function Leaderboard({
9237
9283
  ui,
9238
9284
  onPlay
9239
9285
  }) {
9240
- const [segment, setSegment] = (0, import_react55.useState)("weekly");
9286
+ const [segment, setSegment] = (0, import_react56.useState)("weekly");
9241
9287
  const myRow = segment === "weekly" ? data.myWeeklyRow : data.myAllTimeRow;
9242
9288
  const offBoard = myRow !== null && myRow !== void 0 && myRow.rank === -1;
9243
9289
  const isEmpty = segment === "weekly" ? data.weeklyTop.length === 0 : data.allTimeTop.length === 0;
@@ -9317,10 +9363,10 @@ function LeaderboardPanel({ loggedIn, data, loading, onPlay, ui }) {
9317
9363
  }
9318
9364
 
9319
9365
  // src/components/PresetSpeedDial.tsx
9320
- var import_react56 = require("react");
9366
+ var import_react57 = require("react");
9321
9367
  var import_jsx_runtime94 = require("react/jsx-runtime");
9322
9368
  function PresetSpeedDial({ expanded, showDot, strings, onToggle, onOpen, rootRef, buttonRef }) {
9323
- const pillsId = (0, import_react56.useId)();
9369
+ const pillsId = (0, import_react57.useId)();
9324
9370
  const tabIndex = expanded ? 0 : -1;
9325
9371
  return /* @__PURE__ */ (0, import_jsx_runtime94.jsxs)("div", { ref: rootRef, className: "ss-w-dial", children: [
9326
9372
  /* @__PURE__ */ (0, import_jsx_runtime94.jsxs)(
@@ -9354,16 +9400,16 @@ function PresetSpeedDial({ expanded, showDot, strings, onToggle, onOpen, rootRef
9354
9400
  }
9355
9401
 
9356
9402
  // src/components/PresetTools.tsx
9357
- var import_react57 = require("react");
9403
+ var import_react58 = require("react");
9358
9404
  var import_jsx_runtime95 = require("react/jsx-runtime");
9359
9405
  var FOCUSABLE = 'button:not([disabled]), [href], input:not([disabled]), textarea:not([disabled]), [tabindex]:not([tabindex="-1"])';
9360
9406
  function PresetToolModal({ title, closeLabel, onClose, children, footer }) {
9361
- const dialogRef = (0, import_react57.useRef)(null);
9362
- const titleId = (0, import_react57.useId)();
9363
- (0, import_react57.useEffect)(() => {
9407
+ const dialogRef = (0, import_react58.useRef)(null);
9408
+ const titleId = (0, import_react58.useId)();
9409
+ (0, import_react58.useEffect)(() => {
9364
9410
  dialogRef.current?.focus();
9365
9411
  }, []);
9366
- (0, import_react57.useEffect)(() => {
9412
+ (0, import_react58.useEffect)(() => {
9367
9413
  const onKey = (e) => {
9368
9414
  if (e.key !== "Escape") return;
9369
9415
  e.stopPropagation();
@@ -9405,7 +9451,7 @@ function PresetToolModal({ title, closeLabel, onClose, children, footer }) {
9405
9451
  function fillTemplate(template, slots) {
9406
9452
  return template.split(/(\{[a-z]+\})/).filter((part) => part !== "").map((part, i) => {
9407
9453
  const key = /^\{([a-z]+)\}$/.exec(part)?.[1];
9408
- return /* @__PURE__ */ (0, import_jsx_runtime95.jsx)(import_react57.Fragment, { children: key !== void 0 && key in slots ? slots[key] : part }, i);
9454
+ return /* @__PURE__ */ (0, import_jsx_runtime95.jsx)(import_react58.Fragment, { children: key !== void 0 && key in slots ? slots[key] : part }, i);
9409
9455
  });
9410
9456
  }
9411
9457
  function NumberSelect({ current, choices: choices2, label, notToday, lockEmpty = true, onChoose }) {
@@ -9474,15 +9520,15 @@ function SetNumbersTool({ grid, strings, streaming, onSend, onClose }) {
9474
9520
  const totals = comboTotals(grid);
9475
9521
  const legChoices = comboLegChoices(grid);
9476
9522
  const count = FIXED_SINGLES_COUNT;
9477
- const [maxPrice, setMaxPrice] = (0, import_react57.useState)(() => startSingles(grid.singles, limits, START.maxPrice, count));
9478
- const [minPrice, setMinPrice] = (0, import_react57.useState)(() => startSingles(grid.singlesFrom, floors, START.minPrice, count));
9479
- const [start] = (0, import_react57.useState)(() => startCombo(grid, totals, legChoices, START.comboTotal, START.comboLegs));
9480
- const [total, setTotal] = (0, import_react57.useState)(start.total);
9481
- const [legs, setLegs] = (0, import_react57.useState)(start.legs);
9482
- const [bigStart] = (0, import_react57.useState)(() => startCombo(grid, totals, legChoices, BIG_COMBO.total, BIG_COMBO.legs));
9483
- const [bigTotal, setBigTotal] = (0, import_react57.useState)(bigStart.total);
9484
- const [bigLegs, setBigLegs] = (0, import_react57.useState)(bigStart.legs);
9485
- const [announcement, setAnnouncement] = (0, import_react57.useState)("");
9523
+ const [maxPrice, setMaxPrice] = (0, import_react58.useState)(() => startSingles(grid.singles, limits, START.maxPrice, count));
9524
+ const [minPrice, setMinPrice] = (0, import_react58.useState)(() => startSingles(grid.singlesFrom, floors, START.minPrice, count));
9525
+ const [start] = (0, import_react58.useState)(() => startCombo(grid, totals, legChoices, START.comboTotal, START.comboLegs));
9526
+ const [total, setTotal] = (0, import_react58.useState)(start.total);
9527
+ const [legs, setLegs] = (0, import_react58.useState)(start.legs);
9528
+ const [bigStart] = (0, import_react58.useState)(() => startCombo(grid, totals, legChoices, BIG_COMBO.total, BIG_COMBO.legs));
9529
+ const [bigTotal, setBigTotal] = (0, import_react58.useState)(bigStart.total);
9530
+ const [bigLegs, setBigLegs] = (0, import_react58.useState)(bigStart.legs);
9531
+ const [announcement, setAnnouncement] = (0, import_react58.useState)("");
9486
9532
  const maxCell = findSingles(grid.singles, maxPrice, count);
9487
9533
  const minCell = findSingles(grid.singlesFrom, minPrice, count);
9488
9534
  const comboCell = findCombo(grid, total, legs);
@@ -9526,7 +9572,7 @@ function SetNumbersTool({ grid, strings, streaming, onSend, onClose }) {
9526
9572
  const totalChoices = totals.map((v) => ({ value: v, text: v.toFixed(1), available: legChoices.some((n) => !!findCombo(grid, v, n)) }));
9527
9573
  const legChoicesFor = (t) => legChoices.map((n) => ({ value: n, text: String(n), available: !!findCombo(grid, t, n) }));
9528
9574
  const markets = grid.markets ?? [];
9529
- const [marketIdx, setMarketIdx] = (0, import_react57.useState)(0);
9575
+ const [marketIdx, setMarketIdx] = (0, import_react58.useState)(0);
9530
9576
  const marketCell = markets[marketIdx] ?? null;
9531
9577
  const marketLabels = markets.map((c) => strings.marketShort(c.marketDeveloperName, c.marketLabel, c.selectionLabel ?? null));
9532
9578
  const singlesReady = (cell) => cell ? strings.readyCount(cell.picks.length) : strings.unavailable;
@@ -9607,14 +9653,14 @@ function SetNumbersTool({ grid, strings, streaming, onSend, onClose }) {
9607
9653
  function BuildComboTool({ grid, strings, streaming, formatKickoff, initialTotal, initialLegs, onSend, onClose }) {
9608
9654
  const totals = comboTotals(grid);
9609
9655
  const legChoices = comboLegChoices(grid);
9610
- const [start] = (0, import_react57.useState)(() => initialTotal === void 0 ? startCombo(grid, totals, legChoices, START.comboTotal, START.comboLegs) : null);
9611
- const [total, setTotal] = (0, import_react57.useState)(() => initialTotal !== void 0 ? nearest(totals, initialTotal) : start.total);
9612
- const [legs, setLegs] = (0, import_react57.useState)(() => {
9656
+ const [start] = (0, import_react58.useState)(() => initialTotal === void 0 ? startCombo(grid, totals, legChoices, START.comboTotal, START.comboLegs) : null);
9657
+ const [total, setTotal] = (0, import_react58.useState)(() => initialTotal !== void 0 ? nearest(totals, initialTotal) : start.total);
9658
+ const [legs, setLegs] = (0, import_react58.useState)(() => {
9613
9659
  if (initialTotal === void 0) return initialLegs !== void 0 ? clampLegs(legChoices, initialLegs) : start.legs;
9614
9660
  const from = initialLegs !== void 0 ? clampLegs(legChoices, initialLegs) : startValue(legChoices, START.comboLegs);
9615
9661
  return legsForTotal(grid, nearest(totals, initialTotal), from);
9616
9662
  });
9617
- const [announcement, setAnnouncement] = (0, import_react57.useState)("");
9663
+ const [announcement, setAnnouncement] = (0, import_react58.useState)("");
9618
9664
  const cell = findCombo(grid, total, legs);
9619
9665
  const minLegs = legChoices[0] ?? legs;
9620
9666
  const maxLegs = legChoices[legChoices.length - 1] ?? legs;
@@ -9647,7 +9693,7 @@ function BuildComboTool({ grid, strings, streaming, formatKickoff, initialTotal,
9647
9693
  }
9648
9694
 
9649
9695
  // src/usePresetDial.ts
9650
- var import_react58 = require("react");
9696
+ var import_react59 = require("react");
9651
9697
  function sendInFlight(messages, isStreaming) {
9652
9698
  const last = messages[messages.length - 1];
9653
9699
  return isStreaming && !!last && last.role === "assistant" && !last.done && !last.isGreeting;
@@ -9661,25 +9707,25 @@ function lastUserId(messages) {
9661
9707
  }
9662
9708
  var SCROLL_KEYS = /* @__PURE__ */ new Set(["ArrowUp", "ArrowDown", "PageUp", "PageDown", "Home", "End", " "]);
9663
9709
  function usePresetDial({ layerRef, dialRef, dialButtonRef, messages, isStreaming, activeTab }) {
9664
- const [expanded, setExpanded] = (0, import_react58.useState)(() => !sendInFlight(messages, isStreaming));
9665
- const fold = (0, import_react58.useCallback)(() => setExpanded(false), []);
9666
- const toggle = (0, import_react58.useCallback)(() => setExpanded((e) => !e), []);
9710
+ const [expanded, setExpanded] = (0, import_react59.useState)(() => !sendInFlight(messages, isStreaming));
9711
+ const fold = (0, import_react59.useCallback)(() => setExpanded(false), []);
9712
+ const toggle = (0, import_react59.useCallback)(() => setExpanded((e) => !e), []);
9667
9713
  const currentUserId = lastUserId(messages);
9668
- const userIdRef = (0, import_react58.useRef)(currentUserId);
9669
- (0, import_react58.useEffect)(() => {
9714
+ const userIdRef = (0, import_react59.useRef)(currentUserId);
9715
+ (0, import_react59.useEffect)(() => {
9670
9716
  if (currentUserId === userIdRef.current) return;
9671
9717
  userIdRef.current = currentUserId;
9672
9718
  setExpanded(false);
9673
9719
  }, [currentUserId]);
9674
- const tabRef = (0, import_react58.useRef)(activeTab);
9675
- (0, import_react58.useEffect)(() => {
9720
+ const tabRef = (0, import_react59.useRef)(activeTab);
9721
+ (0, import_react59.useEffect)(() => {
9676
9722
  if (activeTab === tabRef.current) return;
9677
9723
  tabRef.current = activeTab;
9678
9724
  setExpanded(false);
9679
9725
  }, [activeTab]);
9680
- const expandedRef = (0, import_react58.useRef)(expanded);
9726
+ const expandedRef = (0, import_react59.useRef)(expanded);
9681
9727
  expandedRef.current = expanded;
9682
- (0, import_react58.useEffect)(() => {
9728
+ (0, import_react59.useEffect)(() => {
9683
9729
  const onEscape = (e) => {
9684
9730
  const dial = dialRef.current;
9685
9731
  if (e.key !== "Escape" || !dial || !e.composedPath().includes(dial)) return;
@@ -9692,7 +9738,7 @@ function usePresetDial({ layerRef, dialRef, dialButtonRef, messages, isStreaming
9692
9738
  window.addEventListener("keydown", onEscape, true);
9693
9739
  return () => window.removeEventListener("keydown", onEscape, true);
9694
9740
  }, [dialRef, dialButtonRef]);
9695
- (0, import_react58.useEffect)(() => {
9741
+ (0, import_react59.useEffect)(() => {
9696
9742
  if (!expanded) return;
9697
9743
  const layer = layerRef.current;
9698
9744
  const inDial = (e) => {
@@ -9747,8 +9793,8 @@ function markToolSeen() {
9747
9793
  var import_jsx_runtime96 = require("react/jsx-runtime");
9748
9794
  var FULLSCREEN_QUERY = "(max-width: 639px)";
9749
9795
  function useIsModal() {
9750
- const [modal, setModal] = (0, import_react59.useState)(false);
9751
- (0, import_react59.useEffect)(() => {
9796
+ const [modal, setModal] = (0, import_react60.useState)(false);
9797
+ (0, import_react60.useEffect)(() => {
9752
9798
  if (typeof window === "undefined" || typeof window.matchMedia !== "function") return;
9753
9799
  const mql = window.matchMedia(FULLSCREEN_QUERY);
9754
9800
  const sync = () => setModal(mql.matches);
@@ -9762,7 +9808,7 @@ var HIDDEN_LAYER_STYLE = { position: "absolute", inset: 0, visibility: "hidden",
9762
9808
  function ChatPanel({ controller, ui, slip, onDashboardTap, monitor, discovery, gamesResult, leaderboardResult, loggedIn, conversation, presetGrid }) {
9763
9809
  const { state, close, stop, send, reset } = controller;
9764
9810
  const isModal = useIsModal();
9765
- (0, import_react59.useEffect)(() => {
9811
+ (0, import_react60.useEffect)(() => {
9766
9812
  const onKey = (e) => {
9767
9813
  if (e.key === "Escape") close();
9768
9814
  };
@@ -9778,19 +9824,19 @@ function ChatPanel({ controller, ui, slip, onDashboardTap, monitor, discovery, g
9778
9824
  monitor?.setActiveTab("chat");
9779
9825
  send(text, { grounding });
9780
9826
  };
9781
- (0, import_react59.useEffect)(() => {
9827
+ (0, import_react60.useEffect)(() => {
9782
9828
  if (monitor && monitor.activeTab !== "chat" && state.isStreaming) monitor.markChatActivity();
9783
9829
  }, [monitor, state.isStreaming, state.messages.length]);
9784
9830
  const onChatTab = !monitor || monitor.activeTab === "chat";
9785
- const layerRef = (0, import_react59.useRef)(null);
9786
- const dialRef = (0, import_react59.useRef)(null);
9787
- const dialButtonRef = (0, import_react59.useRef)(null);
9788
- const inputRef = (0, import_react59.useRef)(null);
9789
- const limitRef = (0, import_react59.useRef)(null);
9790
- const typedSendRef = (0, import_react59.useRef)(false);
9791
- const focusAfterCloseRef = (0, import_react59.useRef)(null);
9792
- const [tool, setTool] = (0, import_react59.useState)(null);
9793
- const [toolSeen, setToolSeen] = (0, import_react59.useState)(readToolSeen);
9831
+ const layerRef = (0, import_react60.useRef)(null);
9832
+ const dialRef = (0, import_react60.useRef)(null);
9833
+ const dialButtonRef = (0, import_react60.useRef)(null);
9834
+ const inputRef = (0, import_react60.useRef)(null);
9835
+ const limitRef = (0, import_react60.useRef)(null);
9836
+ const typedSendRef = (0, import_react60.useRef)(false);
9837
+ const focusAfterCloseRef = (0, import_react60.useRef)(null);
9838
+ const [tool, setTool] = (0, import_react60.useState)(null);
9839
+ const [toolSeen, setToolSeen] = (0, import_react60.useState)(readToolSeen);
9794
9840
  const dial = usePresetDial({
9795
9841
  layerRef,
9796
9842
  dialRef,
@@ -9802,47 +9848,47 @@ function ChatPanel({ controller, ui, slip, onDashboardTap, monitor, discovery, g
9802
9848
  const { fold } = dial;
9803
9849
  const paused = isPaused(state.limit);
9804
9850
  const showDial = !!presetGrid && onChatTab && !tool && !paused;
9805
- (0, import_react59.useEffect)(() => {
9851
+ (0, import_react60.useEffect)(() => {
9806
9852
  if (paused) setTool(null);
9807
9853
  }, [paused]);
9808
- (0, import_react59.useEffect)(() => {
9854
+ (0, import_react60.useEffect)(() => {
9809
9855
  if (!paused) return;
9810
9856
  if (typedSendRef.current) limitRef.current?.focus();
9811
9857
  typedSendRef.current = false;
9812
9858
  }, [paused]);
9813
- const openTool = (0, import_react59.useCallback)((next) => {
9859
+ const openTool = (0, import_react60.useCallback)((next) => {
9814
9860
  fold();
9815
9861
  markToolSeen();
9816
9862
  setToolSeen(true);
9817
9863
  setTool(next);
9818
9864
  }, [fold]);
9819
- const onPill = (0, import_react59.useCallback)((kind) => openTool(kind === "numbers" ? { kind: "numbers" } : { kind: "combo" }), [openTool]);
9820
- const toolsValue = (0, import_react59.useMemo)(
9865
+ const onPill = (0, import_react60.useCallback)((kind) => openTool(kind === "numbers" ? { kind: "numbers" } : { kind: "combo" }), [openTool]);
9866
+ const toolsValue = (0, import_react60.useMemo)(
9821
9867
  () => presetGrid && !paused ? { openBuilder: (total, legs) => openTool({ kind: "combo", total, legs }), changeLabel: ui.presets.changeCombo } : null,
9822
9868
  [presetGrid, paused, openTool, ui.presets.changeCombo]
9823
9869
  );
9824
- const closeTool = (0, import_react59.useCallback)(() => {
9870
+ const closeTool = (0, import_react60.useCallback)(() => {
9825
9871
  focusAfterCloseRef.current = "dial";
9826
9872
  setTool(null);
9827
9873
  }, []);
9828
- const sendAsk = (0, import_react59.useCallback)((ask) => {
9874
+ const sendAsk = (0, import_react60.useCallback)((ask) => {
9829
9875
  focusAfterCloseRef.current = "composer";
9830
9876
  setTool(null);
9831
9877
  monitor?.setActiveTab("chat");
9832
9878
  send(ask.message, { displayText: ask.displayText, preset: ask.preset });
9833
9879
  }, [monitor, send]);
9834
- const formatKickoff = (0, import_react59.useCallback)((kickoffUtc) => {
9880
+ const formatKickoff = (0, import_react60.useCallback)((kickoffUtc) => {
9835
9881
  const k = ui.bettingKickoff(kickoffUtc);
9836
9882
  return `${k.dayLabel} ${k.time}`;
9837
9883
  }, [ui]);
9838
- (0, import_react59.useEffect)(() => {
9884
+ (0, import_react60.useEffect)(() => {
9839
9885
  if (tool) return;
9840
9886
  const target = focusAfterCloseRef.current;
9841
9887
  focusAfterCloseRef.current = null;
9842
9888
  if (target === "dial") dialButtonRef.current?.focus();
9843
9889
  else if (target === "composer") inputRef.current?.focus();
9844
9890
  }, [tool]);
9845
- (0, import_react59.useEffect)(() => {
9891
+ (0, import_react60.useEffect)(() => {
9846
9892
  if (!tool || onChatTab && presetGrid) return;
9847
9893
  focusAfterCloseRef.current = "composer";
9848
9894
  setTool(null);
@@ -10061,6 +10107,8 @@ var WIDGET_CSS = `.ss-w-root { all: revert; }
10061
10107
  .ss-g-search-box { display: flex; align-items: center; gap: 10px; height: 50px; padding: 0 14px; border-radius: 14px; background: var(--ss-g-surface); border: 1.5px solid var(--ss-g-line); color: var(--ss-g-muted); }
10062
10108
  .ss-g-search-box:focus-within { border-color: var(--ss-w-accent); }
10063
10109
  .ss-g-search-box input { flex: 1; min-width: 0; border: 0; outline: none; background: transparent; color: var(--ss-g-ink); font: 500 15px var(--ss-g-font-body); }
10110
+ .ss-g-search-clear { flex: none; width: 20px; height: 20px; padding: 0; border: none; border-radius: 50%; background: var(--ss-g-line); color: var(--ss-g-muted); display: flex; align-items: center; justify-content: center; cursor: pointer; }
10111
+ .ss-g-search-clear:focus-visible { outline: 2px solid var(--ss-w-accent); outline-offset: -2px; }
10064
10112
  .ss-g-footer { flex: none; padding: 12px 16px 16px; border-top: 1px solid var(--ss-g-line); display: flex; flex-direction: column; gap: 10px; background: var(--ss-g-ground); }
10065
10113
  .ss-g-sil { position: relative; flex: none; display: inline-flex; align-items: flex-end; justify-content: center; overflow: hidden; border-radius: 50%; background: var(--ss-g-raised); color: var(--ss-g-strong-line); }
10066
10114
  .ss-g-sil--selected { background: var(--ss-g-accent-tint); color: color-mix(in srgb, var(--ss-w-accent) 40%, var(--ss-g-raised)); }
@@ -11150,6 +11198,13 @@ var WIDGET_CSS = `.ss-w-root { all: revert; }
11150
11198
  .ss-w-today-sec-sub { text-transform: none; letter-spacing: normal; font-weight: 600; }
11151
11199
  .ss-w-today-tiles { display: grid; grid-template-columns: 1fr 1fr; gap: 8px; }
11152
11200
  .ss-w-today-empty { font-size: 12px; color: var(--ss-w-faint); padding: 10px 2px; }
11201
+ .ss-w-today-search-block { display: flex; flex-direction: column; }
11202
+ .ss-w-today-search-group { display: flex; align-items: center; gap: 7px; padding: 2px 2px 6px; }
11203
+ .ss-w-today-search-group::after { content: ""; flex: 1; height: 1px; background: var(--ss-w-line); }
11204
+ .ss-w-today-search-group .ss-w-bi-comp-logo { width: 16px; height: 16px; }
11205
+ .ss-w-today-search-group-name { font-size: 10px; font-weight: 800; letter-spacing: .09em; text-transform: uppercase; color: var(--ss-w-faint); min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
11206
+ .ss-w-today-search-row { cursor: pointer; border-radius: 10px; }
11207
+ .ss-w-today-search-row:focus-visible { outline: 2px solid var(--ss-w-accent); outline-offset: -2px; }
11153
11208
 
11154
11209
  /* League tile (Task 5): a flat row (crest + name as the open target, star as a separate sibling
11155
11210
  button) rather than a disclosure header -- opening is Task 6's LeagueDetail, not an inline
@@ -11696,24 +11751,24 @@ function injectStyles(root) {
11696
11751
  function StatsWidget(props) {
11697
11752
  const injectedClient = "client" in props ? props.client : void 0;
11698
11753
  const cfg = props.config;
11699
- const built = (0, import_react60.useMemo)(() => buildClient(props), [injectedClient, cfg?.operatorId, cfg?.publicKey, cfg?.baseUrl]);
11700
- const logger = (0, import_react60.useMemo)(
11754
+ const built = (0, import_react61.useMemo)(() => buildClient(props), [injectedClient, cfg?.operatorId, cfg?.publicKey, cfg?.baseUrl]);
11755
+ const logger = (0, import_react61.useMemo)(
11701
11756
  () => built ? built.client.createEventLogger({
11702
11757
  operatorUserId: cfg?.userContext?.operatorUserId,
11703
11758
  anonymousUserId: cfg?.userContext?.anonymousUserId
11704
11759
  }) : null,
11705
11760
  [built?.client]
11706
11761
  );
11707
- const ui = (0, import_react60.useMemo)(() => normalizeUi(props.config ?? { operatorId: "", publicKey: "" }), [props.config]);
11708
- const rootRef = (0, import_react60.useRef)(null);
11709
- const introDoneRef = (0, import_react60.useRef)(false);
11710
- const markIntroDone = (0, import_react60.useCallback)(() => {
11762
+ const ui = (0, import_react61.useMemo)(() => normalizeUi(props.config ?? { operatorId: "", publicKey: "" }), [props.config]);
11763
+ const rootRef = (0, import_react61.useRef)(null);
11764
+ const introDoneRef = (0, import_react61.useRef)(false);
11765
+ const markIntroDone = (0, import_react61.useCallback)(() => {
11711
11766
  introDoneRef.current = true;
11712
11767
  }, []);
11713
11768
  const convStorageKey = `ss-w-conv:${cfg?.operatorId ?? ""}:${cfg?.userContext?.operatorUserId ?? "anon"}`;
11714
11769
  const controller = useChatStream(built?.conversation ?? emptyConversation(), ui.starters, built ? ui.greetingMessage : void 0, convStorageKey);
11715
- const [hasToday, setHasToday] = (0, import_react60.useState)(false);
11716
- const liveCardWatches = (0, import_react60.useMemo)(() => {
11770
+ const [hasToday, setHasToday] = (0, import_react61.useState)(false);
11771
+ const liveCardWatches = (0, import_react61.useMemo)(() => {
11717
11772
  const seen = /* @__PURE__ */ new Set();
11718
11773
  const out = [];
11719
11774
  for (const msg of controller.state.messages) {
@@ -11737,19 +11792,19 @@ function StatsWidget(props) {
11737
11792
  });
11738
11793
  const operatorUserId = cfg?.userContext?.operatorUserId;
11739
11794
  const anonymousUserId = cfg?.userContext?.anonymousUserId;
11740
- const getSchedule = (0, import_react60.useCallback)(
11795
+ const getSchedule = (0, import_react61.useCallback)(
11741
11796
  (localDate, utcOffsetMinutes) => built ? built.conversation.getSchedule(localDate, utcOffsetMinutes, operatorUserId, anonymousUserId) : Promise.resolve(null),
11742
11797
  [built, operatorUserId, anonymousUserId]
11743
11798
  );
11744
- const postLeagueStar = (0, import_react60.useCallback)(
11799
+ const postLeagueStar = (0, import_react61.useCallback)(
11745
11800
  (competitionId, starred) => built ? built.conversation.starLeague(competitionId, starred, operatorUserId, anonymousUserId) : Promise.resolve(null),
11746
11801
  [built, operatorUserId, anonymousUserId]
11747
11802
  );
11748
- const getStates = (0, import_react60.useCallback)(
11803
+ const getStates = (0, import_react61.useCallback)(
11749
11804
  (matchIds) => built ? built.conversation.getStates(matchIds) : Promise.resolve(null),
11750
11805
  [built]
11751
11806
  );
11752
- const pinnedMatchIds = (0, import_react60.useMemo)(
11807
+ const pinnedMatchIds = (0, import_react61.useMemo)(
11753
11808
  () => monitor.pins.filter((p) => p.kind === "match").map((p) => p.matchId),
11754
11809
  [monitor.pins]
11755
11810
  );
@@ -11764,11 +11819,11 @@ function StatsWidget(props) {
11764
11819
  pinnedMatchIds
11765
11820
  });
11766
11821
  const todayHasContent = visibleGroupsOf(discovery.groups, discovery.states).length > 0;
11767
- (0, import_react60.useEffect)(() => {
11822
+ (0, import_react61.useEffect)(() => {
11768
11823
  setHasToday(todayHasContent);
11769
11824
  }, [todayHasContent]);
11770
- const prevLiveSnapshotRef = (0, import_react60.useRef)(monitor.snapshot);
11771
- (0, import_react60.useEffect)(() => {
11825
+ const prevLiveSnapshotRef = (0, import_react61.useRef)(monitor.snapshot);
11826
+ (0, import_react61.useEffect)(() => {
11772
11827
  const snap = monitor.snapshot;
11773
11828
  if (!snap || snap === prevLiveSnapshotRef.current) return;
11774
11829
  prevLiveSnapshotRef.current = snap;
@@ -11804,14 +11859,14 @@ function StatsWidget(props) {
11804
11859
  }, [monitor.snapshot]);
11805
11860
  const gamesResult = useGames(built?.conversation ?? null, { activeTab: monitor.activeTab });
11806
11861
  const leaderboardResult = useLeaderboard(built?.conversation ?? null, { activeTab: monitor.activeTab });
11807
- const getPricePresets = (0, import_react60.useCallback)(
11862
+ const getPricePresets = (0, import_react61.useCallback)(
11808
11863
  (locale2) => built ? built.conversation.getPricePresets(locale2, { pool: "open" }) : Promise.resolve(null),
11809
11864
  [built]
11810
11865
  );
11811
11866
  const presetGrid = usePresetGrid({ getPricePresets, isOpen: controller.state.isOpen, locale: ui.presets.lang });
11812
11867
  const markTodayActivity = monitor.markTodayActivity;
11813
- const prevLiveCountRef = (0, import_react60.useRef)(0);
11814
- (0, import_react60.useEffect)(() => {
11868
+ const prevLiveCountRef = (0, import_react61.useRef)(0);
11869
+ (0, import_react61.useEffect)(() => {
11815
11870
  const rose = prevLiveCountRef.current === 0 && discovery.liveCount > 0;
11816
11871
  prevLiveCountRef.current = discovery.liveCount;
11817
11872
  if (rose) markTodayActivity();
@@ -11825,7 +11880,7 @@ function StatsWidget(props) {
11825
11880
  closePanel: controller.close
11826
11881
  });
11827
11882
  const markAdded = hostEvents.markAdded;
11828
- const slip = (0, import_react60.useMemo)(
11883
+ const slip = (0, import_react61.useMemo)(
11829
11884
  () => {
11830
11885
  const handler = props.config?.onAddToSlip;
11831
11886
  return {
@@ -11844,7 +11899,7 @@ function StatsWidget(props) {
11844
11899
  },
11845
11900
  [props.config?.onAddToSlip, controller.state.conversationId, markAdded]
11846
11901
  );
11847
- const onDashboardTap = (0, import_react60.useMemo)(
11902
+ const onDashboardTap = (0, import_react61.useMemo)(
11848
11903
  () => built ? createDashboardTapSignal((input) => built.conversation.sendSignal(input), logger) : void 0,
11849
11904
  [built, logger]
11850
11905
  );
@@ -11861,11 +11916,11 @@ function StatsWidget(props) {
11861
11916
  })
11862
11917
  }));
11863
11918
  const conversationId = controller.state.conversationId ?? void 0;
11864
- (0, import_react60.useEffect)(() => {
11919
+ (0, import_react61.useEffect)(() => {
11865
11920
  if (!logger) return;
11866
11921
  logger.setIdentity({ operatorUserId, anonymousUserId, conversationId });
11867
11922
  }, [logger, operatorUserId, anonymousUserId, conversationId]);
11868
- (0, import_react60.useEffect)(() => {
11923
+ (0, import_react61.useEffect)(() => {
11869
11924
  if (!logger) return;
11870
11925
  logger.resume();
11871
11926
  const onHide = () => {
@@ -11883,7 +11938,7 @@ function StatsWidget(props) {
11883
11938
  logger.dispose();
11884
11939
  };
11885
11940
  }, [logger]);
11886
- (0, import_react60.useEffect)(() => {
11941
+ (0, import_react61.useEffect)(() => {
11887
11942
  if (!built || !ui.injectStyles) return;
11888
11943
  const node = rootRef.current?.getRootNode();
11889
11944
  if (node) injectStyles(node);