@sensiblestats/widget-react 0.90.0 → 0.91.0

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
@@ -1041,7 +1041,7 @@ function isEnglishLocale(locale) {
1041
1041
  }
1042
1042
 
1043
1043
  // src/version.generated.ts
1044
- var WIDGET_REACT_VERSION = "0.90.0";
1044
+ var WIDGET_REACT_VERSION = "0.91.0";
1045
1045
 
1046
1046
  // src/config.ts
1047
1047
  function normalizeUi(cfg) {
@@ -3240,10 +3240,11 @@ function useLiveMonitor(opts) {
3240
3240
 
3241
3241
  // src/useMatchDiscovery.ts
3242
3242
  import { useCallback as useCallback4, useEffect as useEffect5, useMemo as useMemo3, useRef as useRef5, useState as useState4 } from "react";
3243
+ import { matchKey as matchKey2 } from "@sensiblestats/widget-sdk";
3243
3244
 
3244
3245
  // src/scheduleCache.ts
3245
3246
  var PREFIX = "ss-w-schedule:";
3246
- var SCHEMA_VERSION = 2;
3247
+ var SCHEMA_VERSION = 3;
3247
3248
  var TTL_MS2 = 6 * 36e5;
3248
3249
  function scheduleCacheKey(operatorId, encodedUserKey2, localDate) {
3249
3250
  return `${PREFIX}${operatorId}:${encodedUserKey2}:${localDate}`;
@@ -3271,6 +3272,7 @@ function skeletonOnly(payload) {
3271
3272
  return {
3272
3273
  localDate: payload.localDate,
3273
3274
  groups: payload.groups.map((g) => ({
3275
+ sport: g.sport,
3274
3276
  competitionId: g.competitionId,
3275
3277
  competitionName: g.competitionName,
3276
3278
  competitionCountry: g.competitionCountry ?? null,
@@ -3282,10 +3284,13 @@ function skeletonOnly(payload) {
3282
3284
  learnedRank: g.learnedRank,
3283
3285
  matches: g.matches.map((m) => ({
3284
3286
  matchId: m.matchId,
3287
+ sport: m.sport,
3285
3288
  homeTeamName: m.homeTeamName,
3286
3289
  awayTeamName: m.awayTeamName,
3287
3290
  homeTeamImagePath: m.homeTeamImagePath ?? null,
3288
3291
  awayTeamImagePath: m.awayTeamImagePath ?? null,
3292
+ homeTeamAbbr: m.homeTeamAbbr,
3293
+ awayTeamAbbr: m.awayTeamAbbr,
3289
3294
  kickoffUnix: m.kickoffUnix
3290
3295
  }))
3291
3296
  }))
@@ -3312,18 +3317,21 @@ function patchScheduleStar(operatorId, encodedUserKey2, localDate, competitionId
3312
3317
  }
3313
3318
 
3314
3319
  // src/dueSet.ts
3320
+ import { matchKey } from "@sensiblestats/widget-sdk";
3315
3321
  var TERMINAL_PHASES = /* @__PURE__ */ new Set(["fullTime", "postponed"]);
3316
3322
  function dueMatchIds(groups, states, nowMs) {
3317
- const due = /* @__PURE__ */ new Set();
3323
+ const football = /* @__PURE__ */ new Set();
3324
+ const nba = /* @__PURE__ */ new Set();
3318
3325
  for (const group of groups) {
3319
3326
  for (const match of group.matches) {
3320
3327
  if (nowMs - match.kickoffUnix * 1e3 < 0) continue;
3321
- const phase = states[match.matchId]?.phase;
3328
+ const phase = states.get(matchKey(match.sport, match.matchId))?.phase;
3322
3329
  if (phase !== void 0 && TERMINAL_PHASES.has(phase)) continue;
3323
- due.add(match.matchId);
3330
+ const bucket = match.sport === "basketball" ? nba : football;
3331
+ bucket.add(match.matchId);
3324
3332
  }
3325
3333
  }
3326
- return [...due];
3334
+ return { football: [...football], nba: [...nba] };
3327
3335
  }
3328
3336
 
3329
3337
  // src/useMatchDiscovery.ts
@@ -3341,7 +3349,7 @@ function localDateOf(now) {
3341
3349
  }
3342
3350
  function useMatchDiscovery(opts) {
3343
3351
  const [groups, setGroups] = useState4([]);
3344
- const [states, setStates] = useState4({});
3352
+ const [states, setStates] = useState4(() => /* @__PURE__ */ new Map());
3345
3353
  const [failures, setFailures] = useState4(0);
3346
3354
  const groupsRef = useRef5(groups);
3347
3355
  groupsRef.current = groups;
@@ -3385,13 +3393,13 @@ function useMatchDiscovery(opts) {
3385
3393
  }, [opts.operatorId, opts.operatorUserId, opts.anonymousUserId, localDate]);
3386
3394
  const tick = useCallback4(async () => {
3387
3395
  const ids = dueMatchIds(groupsRef.current, statesRef.current, Date.now());
3388
- if (ids.length === 0) return;
3396
+ if (ids.football.length === 0 && ids.nba.length === 0) return;
3389
3397
  try {
3390
- const payload = await getStatesRef.current(ids);
3398
+ const payload = await getStatesRef.current(ids.football, ids.nba);
3391
3399
  if (!payload) return;
3392
3400
  setStates((prev) => {
3393
- const next = { ...prev };
3394
- for (const state of payload.states) next[state.matchId] = state;
3401
+ const next = new Map(prev);
3402
+ for (const state of payload.states) next.set(matchKey2(state.sport, state.matchId), state);
3395
3403
  return next;
3396
3404
  });
3397
3405
  setFailures(0);
@@ -3409,7 +3417,7 @@ function useMatchDiscovery(opts) {
3409
3417
  }, [opts.isOpen, tick, groups]);
3410
3418
  const stale = failures >= STALE_AFTER_FAILURES;
3411
3419
  const liveCount = useMemo3(
3412
- () => stale ? 0 : Object.values(states).filter((s) => s.phase === "live").length,
3420
+ () => stale ? 0 : [...states.values()].filter((s) => s.phase === "live").length,
3413
3421
  [states, stale]
3414
3422
  );
3415
3423
  const starLeague = useCallback4(async (competitionId, starred) => {
@@ -3947,6 +3955,7 @@ function hasAnyCell(grid) {
3947
3955
  }
3948
3956
 
3949
3957
  // src/liveClock.ts
3958
+ import { matchKey as matchKey3 } from "@sensiblestats/widget-sdk";
3950
3959
  function isTreatedLive(state, pollStale) {
3951
3960
  return state?.phase === "live" && !pollStale;
3952
3961
  }
@@ -3954,7 +3963,7 @@ function isFinished(state) {
3954
3963
  return state?.phase === "fullTime";
3955
3964
  }
3956
3965
  function visibleGroupsOf(groups, states) {
3957
- return groups.map((group) => ({ ...group, matches: group.matches.filter((m) => !isFinished(states[m.matchId])) })).filter((group) => group.matches.length > 0);
3966
+ return groups.map((group) => ({ ...group, matches: group.matches.filter((m) => !isFinished(states.get(matchKey3(m.sport, m.matchId)))) })).filter((group) => group.matches.length > 0);
3958
3967
  }
3959
3968
 
3960
3969
  // src/eventLogContext.ts
@@ -7120,6 +7129,7 @@ function OddsPanel({ monitor, ui, slip }) {
7120
7129
 
7121
7130
  // src/components/TodayPanel.tsx
7122
7131
  import { useEffect as useEffect26, useId as useId2, useMemo as useMemo4, useState as useState35 } from "react";
7132
+ import { matchKey as matchKey6 } from "@sensiblestats/widget-sdk";
7123
7133
 
7124
7134
  // src/placement.ts
7125
7135
  function placeLeagues(visible, pinnedMatchIds) {
@@ -7133,7 +7143,7 @@ function placeLeagues(visible, pinnedMatchIds) {
7133
7143
  }
7134
7144
  let budget = 4;
7135
7145
  const pinned = visible.find(
7136
- (g) => !candidateIds.has(g.competitionId) && g.matches.some((m) => pinnedMatchIds.includes(m.matchId))
7146
+ (g) => !candidateIds.has(g.competitionId) && g.matches.some((m) => m.sport !== "basketball" && pinnedMatchIds.includes(m.matchId))
7137
7147
  ) ?? null;
7138
7148
  if (pinned && budget > 0) {
7139
7149
  candidates.push(pinned);
@@ -7154,6 +7164,7 @@ function placeLeagues(visible, pinnedMatchIds) {
7154
7164
  return { personal, candidates: pool, others, order: [...pool, ...others], pinnedCompetitionId: pinned?.competitionId ?? null };
7155
7165
  }
7156
7166
  function starClickable(group, pinnedCompetitionId) {
7167
+ if (group.sport === "basketball") return false;
7157
7168
  return group.isStarred || group.competitionId !== pinnedCompetitionId;
7158
7169
  }
7159
7170
 
@@ -7219,7 +7230,7 @@ function LeagueTile({ group, starClickable: starClickable2, disambiguate, onOpen
7219
7230
  ] }) : null
7220
7231
  ] })
7221
7232
  ] }),
7222
- /* @__PURE__ */ jsx57(
7233
+ group.sport !== "basketball" && /* @__PURE__ */ jsx57(
7223
7234
  "button",
7224
7235
  {
7225
7236
  type: "button",
@@ -7246,16 +7257,25 @@ function LeagueTile({ group, starClickable: starClickable2, disambiguate, onOpen
7246
7257
 
7247
7258
  // src/components/LeagueDetail.tsx
7248
7259
  import { useEffect as useEffect25, useState as useState34 } from "react";
7260
+ import { matchKey as matchKey4 } from "@sensiblestats/widget-sdk";
7249
7261
 
7250
7262
  // src/components/FixtureRow.tsx
7251
7263
  import { jsx as jsx58, jsxs as jsxs53 } from "react/jsx-runtime";
7264
+ function splitAtFirstSpace(label) {
7265
+ const i = label.indexOf(" ");
7266
+ return i > 0 && i < label.length - 1 ? [label.slice(0, i), label.slice(i + 1)] : null;
7267
+ }
7268
+ function isOtherLocalDay(kickoffUnix, now) {
7269
+ const at = new Date(kickoffUnix * 1e3);
7270
+ return at.getFullYear() !== now.getFullYear() || at.getMonth() !== now.getMonth() || at.getDate() !== now.getDate();
7271
+ }
7252
7272
  function kickoffLabel(kickoffUnix) {
7253
7273
  const d = new Date(kickoffUnix * 1e3);
7254
7274
  return `${`${d.getHours()}`.padStart(2, "0")}:${`${d.getMinutes()}`.padStart(2, "0")}`;
7255
7275
  }
7256
- function Side({ name, crest, away = false }) {
7276
+ function Side({ name, crest, abbr, away = false }) {
7257
7277
  return /* @__PURE__ */ jsxs53("span", { className: away ? "ss-w-drow-side ss-w-drow-side--away" : "ss-w-drow-side", children: [
7258
- crest ? /* @__PURE__ */ jsx58("img", { className: "ss-w-drow-crest", src: crest, alt: "" }) : null,
7278
+ abbr ? /* @__PURE__ */ jsx58("span", { className: "ss-w-drow-crest ss-w-drow-crest--abbr", children: abbr }) : crest ? /* @__PURE__ */ jsx58("img", { className: "ss-w-drow-crest", src: crest, alt: "" }) : null,
7259
7279
  /* @__PURE__ */ jsx58("span", { className: "ss-w-drow-nm", children: name })
7260
7280
  ] });
7261
7281
  }
@@ -7265,14 +7285,24 @@ function FixtureRow({ match, state, stale, ui, monitor }) {
7265
7285
  const score = hasScore ? `${state.homeScore}\u2013${state.awayScore}` : void 0;
7266
7286
  const ticked = state?.phase === "live" ? state.minuteLabel ?? null : null;
7267
7287
  const when = state?.isHalfTime && !stale ? ui.halfTime : isLive ? ticked ?? "\u2014" : state?.phase === "live" ? "\u2014" : kickoffLabel(match.kickoffUnix);
7268
- return /* @__PURE__ */ jsxs53("div", { className: isLive || state?.isHalfTime ? "ss-w-drow ss-w-drow--live" : "ss-w-drow", children: [
7269
- /* @__PURE__ */ jsx58("span", { className: isLive || state?.isHalfTime ? "ss-w-drow-when ss-w-drow-when--live" : "ss-w-drow-when", children: when }),
7288
+ const isNba = match.sport === "basketball";
7289
+ const liveTone = isLive || state?.isHalfTime;
7290
+ const clockParts = isNba && isLive && ticked !== null && !state?.isHalfTime ? splitAtFirstSpace(ticked) : null;
7291
+ const dayMarker = isNba && !liveTone && state?.phase !== "live" && isOtherLocalDay(match.kickoffUnix, /* @__PURE__ */ new Date()) ? new Intl.DateTimeFormat(ui.locale === "tr" ? "tr-TR" : "en-GB", { weekday: "short" }).format(new Date(match.kickoffUnix * 1e3)) : null;
7292
+ const twoLines = clockParts ?? (dayMarker !== null ? [when, dayMarker] : null);
7293
+ const whenClass = [
7294
+ "ss-w-drow-when",
7295
+ liveTone ? "ss-w-drow-when--live" : null,
7296
+ twoLines ? "ss-w-drow-when--two" : null
7297
+ ].filter(Boolean).join(" ");
7298
+ return /* @__PURE__ */ jsxs53("div", { className: liveTone ? "ss-w-drow ss-w-drow--live" : "ss-w-drow", children: [
7299
+ /* @__PURE__ */ jsx58("span", { className: whenClass, children: twoLines ? twoLines.map((line, i) => /* @__PURE__ */ jsx58("span", { children: line }, i)) : when }),
7270
7300
  /* @__PURE__ */ jsxs53("span", { className: "ss-w-drow-fx", children: [
7271
- /* @__PURE__ */ jsx58(Side, { name: match.homeTeamName, crest: match.homeTeamImagePath }),
7301
+ /* @__PURE__ */ jsx58(Side, { name: match.homeTeamName, crest: match.homeTeamImagePath, abbr: isNba ? match.homeTeamAbbr ?? void 0 : void 0 }),
7272
7302
  /* @__PURE__ */ jsx58("span", { className: hasScore ? "ss-w-drow-sc" : "ss-w-drow-sc ss-w-drow-sc--idle", children: score ?? "\u2013" }),
7273
- /* @__PURE__ */ jsx58(Side, { name: match.awayTeamName, crest: match.awayTeamImagePath, away: true })
7303
+ /* @__PURE__ */ jsx58(Side, { name: match.awayTeamName, crest: match.awayTeamImagePath, abbr: isNba ? match.awayTeamAbbr ?? void 0 : void 0, away: true })
7274
7304
  ] }),
7275
- /* @__PURE__ */ jsx58(PinToggle, { ui, monitor, pin: { kind: "match", matchId: match.matchId } })
7305
+ !isNba && /* @__PURE__ */ jsx58(PinToggle, { ui, monitor, pin: { kind: "match", matchId: match.matchId } })
7276
7306
  ] });
7277
7307
  }
7278
7308
 
@@ -7289,7 +7319,7 @@ function LeagueDetail({ group, position, states, stale, ui, monitor, starTap, on
7289
7319
  const id = setTimeout(() => setToast(null), 4e3);
7290
7320
  return () => clearTimeout(id);
7291
7321
  }, [toast]);
7292
- const own = group.matches.filter((m) => !isTreatedLive(states[m.matchId], stale));
7322
+ const own = group.matches.filter((m) => !isTreatedLive(states.get(matchKey4(m.sport, m.matchId)), stale));
7293
7323
  const onStarClick = () => {
7294
7324
  const next = !group.isStarred;
7295
7325
  void starTap.tap(group.competitionId, next).then((ok) => {
@@ -7301,7 +7331,7 @@ function LeagueDetail({ group, position, states, stale, ui, monitor, starTap, on
7301
7331
  /* @__PURE__ */ jsx59("button", { type: "button", className: "ss-w-today-detail-back", "aria-label": ui.back, onClick: onBack, children: /* @__PURE__ */ jsx59(ChevronIcon, {}) }),
7302
7332
  /* @__PURE__ */ jsx59(Crest2, { url: group.competitionImagePath ?? void 0, name: group.competitionName, kind: "comp" }),
7303
7333
  /* @__PURE__ */ jsx59("span", { className: "ss-w-today-detail-name", children: group.competitionName }),
7304
- /* @__PURE__ */ jsx59(
7334
+ group.sport !== "basketball" && /* @__PURE__ */ jsx59(
7305
7335
  "button",
7306
7336
  {
7307
7337
  type: "button",
@@ -7351,23 +7381,34 @@ function LeagueDetail({ group, position, states, stale, ui, monitor, starTap, on
7351
7381
  ] }),
7352
7382
  /* @__PURE__ */ jsxs54("div", { className: "ss-w-today-detail-body", children: [
7353
7383
  /* @__PURE__ */ jsx59("span", { className: "ss-w-today-detail-count", children: own.length }),
7354
- own.map((m) => /* @__PURE__ */ jsx59(FixtureRow, { match: m, state: states[m.matchId], stale, ui, monitor }, m.matchId))
7384
+ own.map((m) => /* @__PURE__ */ jsx59(
7385
+ FixtureRow,
7386
+ {
7387
+ match: m,
7388
+ state: states.get(matchKey4(m.sport, m.matchId)),
7389
+ stale,
7390
+ ui,
7391
+ monitor
7392
+ },
7393
+ matchKey4(m.sport, m.matchId)
7394
+ ))
7355
7395
  ] }),
7356
7396
  toast !== null && /* @__PURE__ */ jsx59("p", { className: "ss-w-today-toast", role: "status", "aria-live": "polite", children: toast })
7357
7397
  ] });
7358
7398
  }
7359
7399
 
7360
7400
  // src/components/LeagueRowGroup.tsx
7401
+ import { matchKey as matchKey5 } from "@sensiblestats/widget-sdk";
7361
7402
  import { jsx as jsx60, jsxs as jsxs55 } from "react/jsx-runtime";
7362
7403
  var ROW_CAP_PER_LEAGUE = 3;
7363
7404
  var SECTION_ROW_BUDGET = 12;
7364
7405
  function rowsFor(group, states, stale) {
7365
- const nonLive = group.matches.filter((m) => !isTreatedLive(states[m.matchId], stale)).length;
7406
+ const nonLive = group.matches.filter((m) => !isTreatedLive(states.get(matchKey5(m.sport, m.matchId)), stale)).length;
7366
7407
  return Math.min(nonLive, ROW_CAP_PER_LEAGUE);
7367
7408
  }
7368
7409
  var STAR_PATH3 = "M12 2.5l2.9 5.9 6.5.95-4.7 4.58 1.1 6.47L12 17.35 6.1 20.4l1.1-6.47L2.5 9.35l6.5-.95z";
7369
7410
  function LeagueRowGroup({ group, states, stale, cap, starClickable: starClickable2, disambiguate, onOpen, starTap, ui, monitor }) {
7370
- const sorted = group.matches.filter((m) => !isTreatedLive(states[m.matchId], stale)).sort((a, b) => a.kickoffUnix - b.kickoffUnix);
7411
+ const sorted = group.matches.filter((m) => !isTreatedLive(states.get(matchKey5(m.sport, m.matchId)), stale)).sort((a, b) => a.kickoffUnix - b.kickoffUnix);
7371
7412
  if (sorted.length === 0) return null;
7372
7413
  const shown = sorted.slice(0, cap);
7373
7414
  const overflow = sorted.length - shown.length;
@@ -7387,7 +7428,7 @@ function LeagueRowGroup({ group, states, stale, cap, starClickable: starClickabl
7387
7428
  ] }) : null
7388
7429
  ] })
7389
7430
  ] }),
7390
- /* @__PURE__ */ jsx60(
7431
+ group.sport !== "basketball" && /* @__PURE__ */ jsx60(
7391
7432
  "button",
7392
7433
  {
7393
7434
  type: "button",
@@ -7410,7 +7451,17 @@ function LeagueRowGroup({ group, states, stale, cap, starClickable: starClickabl
7410
7451
  }
7411
7452
  )
7412
7453
  ] }),
7413
- /* @__PURE__ */ jsx60("div", { className: "ss-w-today-rowgroup-rows", children: shown.map((m) => /* @__PURE__ */ jsx60(FixtureRow, { match: m, state: states[m.matchId], stale, ui, monitor }, m.matchId)) }),
7454
+ /* @__PURE__ */ jsx60("div", { className: "ss-w-today-rowgroup-rows", children: shown.map((m) => /* @__PURE__ */ jsx60(
7455
+ FixtureRow,
7456
+ {
7457
+ match: m,
7458
+ state: states.get(matchKey5(m.sport, m.matchId)),
7459
+ stale,
7460
+ ui,
7461
+ monitor
7462
+ },
7463
+ matchKey5(m.sport, m.matchId)
7464
+ )) }),
7414
7465
  overflow > 0 && /* @__PURE__ */ jsx60("button", { type: "button", className: "ss-w-today-rowgroup-seeall", onClick: onOpen, children: ui.seeAllFixturesLabel(sorted.length) })
7415
7466
  ] });
7416
7467
  }
@@ -7553,7 +7604,7 @@ function TodayPanel({ discovery, ui, monitor }) {
7553
7604
  useEffect26(() => {
7554
7605
  if (selectedCompetitionId !== null && openGroup === void 0) setSelectedCompetitionId(null);
7555
7606
  }, [selectedCompetitionId, openGroup]);
7556
- 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);
7607
+ const liveRows = stale ? [] : visibleGroups.flatMap((group) => group.matches.filter((m) => isTreatedLive(states.get(matchKey6(m.sport, m.matchId)), stale)).map((match) => ({ match, rank: group.rank }))).sort((a, b) => a.rank - b.rank);
7557
7608
  const liveBand = liveRows.length > 0 && /* @__PURE__ */ jsxs57(Fragment10, { children: [
7558
7609
  /* @__PURE__ */ jsxs57("div", { className: "ss-w-sec-head", children: [
7559
7610
  /* @__PURE__ */ jsx63("span", { className: "ss-w-sec-dot", "aria-hidden": "true" }),
@@ -7563,12 +7614,12 @@ function TodayPanel({ discovery, ui, monitor }) {
7563
7614
  FixtureRow,
7564
7615
  {
7565
7616
  match,
7566
- state: states[match.matchId],
7617
+ state: states.get(matchKey6(match.sport, match.matchId)),
7567
7618
  stale,
7568
7619
  ui,
7569
7620
  monitor
7570
7621
  },
7571
- match.matchId
7622
+ matchKey6(match.sport, match.matchId)
7572
7623
  )) })
7573
7624
  ] });
7574
7625
  if (openGroup !== void 0) {
@@ -7638,9 +7689,18 @@ function TodayPanel({ discovery, ui, monitor }) {
7638
7689
  setSelectedCompetitionId(group.competitionId);
7639
7690
  }
7640
7691
  },
7641
- children: /* @__PURE__ */ jsx63(FixtureRow, { match, state: states[match.matchId], stale, ui, monitor })
7692
+ children: /* @__PURE__ */ jsx63(
7693
+ FixtureRow,
7694
+ {
7695
+ match,
7696
+ state: states.get(matchKey6(match.sport, match.matchId)),
7697
+ stale,
7698
+ ui,
7699
+ monitor
7700
+ }
7701
+ )
7642
7702
  },
7643
- match.matchId
7703
+ matchKey6(match.sport, match.matchId)
7644
7704
  ))
7645
7705
  ] }, group.competitionId)) }) : /* @__PURE__ */ jsxs57(Fragment10, { children: [
7646
7706
  /* @__PURE__ */ jsxs57("div", { className: "ss-w-today-sec", children: [
@@ -13334,6 +13394,8 @@ var WIDGET_CSS = `.ss-w-root { all: revert; }
13334
13394
  .ss-w-drow:last-child { border-bottom: none; }
13335
13395
  .ss-w-drow-when { font-size: 11px; font-weight: 700; color: var(--ss-w-faint); font-variant-numeric: tabular-nums; }
13336
13396
  .ss-w-drow-when--live { color: var(--ss-w-neg); }
13397
+ .ss-w-drow-when--two { display: flex; flex-direction: column; align-items: flex-start; line-height: 1.15; }
13398
+ .ss-w-drow-when--two > span:last-child { font-size: 10px; font-weight: 600; }
13337
13399
  /* Each side ellipsises independently: a single joined string truncates the away team off the end,
13338
13400
  which is the u350 betting-card truncation one layer down. */
13339
13401
  .ss-w-drow-fx { display: flex; align-items: center; gap: 6px; min-width: 0; }
@@ -13349,6 +13411,7 @@ var WIDGET_CSS = `.ss-w-root { all: revert; }
13349
13411
  .ss-w-drow-sc--idle { color: var(--ss-w-faint); font-weight: 600; }
13350
13412
  .ss-w-drow--live { background: color-mix(in srgb, var(--ss-w-neg) 5%, transparent); border-radius: 8px; padding: 7px 6px; margin: 0 -6px; border-bottom: none; }
13351
13413
  .ss-w-drow-crest { width: 16px; height: 16px; flex: none; border-radius: 50%; object-fit: contain; background: var(--ss-w-bubble); }
13414
+ .ss-w-drow-crest--abbr { width: 26px; height: 16px; border-radius: 4px; display: inline-flex; align-items: center; justify-content: center; font-size: 8px; font-weight: 800; letter-spacing: .02em; line-height: 1; color: var(--ss-w-faint); background: var(--ss-w-bubble); border: 1px solid var(--ss-w-line); box-sizing: border-box; }
13352
13415
 
13353
13416
  .ss-w-stale { font-size: 11px; font-weight: 600; color: var(--ss-w-cta); background: color-mix(in srgb, var(--ss-w-cta) 12%, var(--ss-w-panel)); border-radius: 8px; padding: 6px 9px; }
13354
13417
 
@@ -13891,7 +13954,7 @@ function StatsWidget(props) {
13891
13954
  [built, operatorUserId, anonymousUserId]
13892
13955
  );
13893
13956
  const getStates = useCallback23(
13894
- (matchIds) => built ? built.conversation.getStates(matchIds) : Promise.resolve(null),
13957
+ (matchIds, nbaGameIds) => built ? built.conversation.getStates(matchIds, nbaGameIds) : Promise.resolve(null),
13895
13958
  [built]
13896
13959
  );
13897
13960
  const pinnedMatchIds = useMemo6(