@sensiblestats/widget-react 0.83.0 → 0.85.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/CHANGELOG.md +22 -0
- package/dist/index.cjs +802 -390
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +765 -353
- package/dist/index.js.map +1 -1
- package/dist/styles.css +23 -1
- package/package.json +2 -2
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
|
|
40
|
+
var import_react67 = require("react");
|
|
41
41
|
var import_widget_sdk6 = require("@sensiblestats/widget-sdk");
|
|
42
42
|
|
|
43
43
|
// src/kickoff.ts
|
|
@@ -157,6 +157,38 @@ var STRINGS = {
|
|
|
157
157
|
clubFixturesEmpty: "No fixtures yet.",
|
|
158
158
|
clubStandingsEmpty: "Standings are not available yet.",
|
|
159
159
|
clubSquadEmpty: "Squad is not available yet.",
|
|
160
|
+
footRight: "Right",
|
|
161
|
+
footLeft: "Left",
|
|
162
|
+
footBoth: "Both",
|
|
163
|
+
positionGoalkeeper: "Goalkeeper",
|
|
164
|
+
positionDefender: "Defender",
|
|
165
|
+
positionMidfielder: "Midfielder",
|
|
166
|
+
positionAttacker: "Attacker",
|
|
167
|
+
tabRecords: "Records",
|
|
168
|
+
clubSquadStatsEmpty: "Squad stats are not available yet.",
|
|
169
|
+
clubPlayerDetailEmpty: "Player details are not available.",
|
|
170
|
+
clubRecordsEmpty: "Club records are not available yet.",
|
|
171
|
+
squadViewRoster: "Roster",
|
|
172
|
+
squadViewStats: "Stats",
|
|
173
|
+
statColApps: "Apps",
|
|
174
|
+
statColGoals: "Goals",
|
|
175
|
+
statColAssists: "Assists",
|
|
176
|
+
statColRating: "Rating",
|
|
177
|
+
statColMinutes: "Minutes",
|
|
178
|
+
statColYellow: "Yellow cards",
|
|
179
|
+
statColRed: "Red cards",
|
|
180
|
+
statColXg: "xG",
|
|
181
|
+
statColShots: "Shots",
|
|
182
|
+
detailNationality: "Nationality",
|
|
183
|
+
detailAge: "Age",
|
|
184
|
+
detailHeight: "Height",
|
|
185
|
+
detailFoot: "Foot",
|
|
186
|
+
detailSeason: "Season {season}",
|
|
187
|
+
clubPlayerBack: "Back",
|
|
188
|
+
recordsTopScorers: "Top scorers",
|
|
189
|
+
recordsMostAppearances: "Most appearances",
|
|
190
|
+
recordsMostAssists: "Most assists",
|
|
191
|
+
recordsSince: "Since {season}",
|
|
160
192
|
standingsColClub: "Club",
|
|
161
193
|
standingsColPlayed: "P",
|
|
162
194
|
standingsColWon: "W",
|
|
@@ -538,6 +570,38 @@ var STRINGS = {
|
|
|
538
570
|
clubFixturesEmpty: "Hen\xFCz fikst\xFCr yok.",
|
|
539
571
|
clubStandingsEmpty: "Puan durumu hen\xFCz mevcut de\u011Fil.",
|
|
540
572
|
clubSquadEmpty: "Kadro hen\xFCz mevcut de\u011Fil.",
|
|
573
|
+
footRight: "Sa\u011F",
|
|
574
|
+
footLeft: "Sol",
|
|
575
|
+
footBoth: "\u0130ki ayak",
|
|
576
|
+
positionGoalkeeper: "Kaleci",
|
|
577
|
+
positionDefender: "Defans",
|
|
578
|
+
positionMidfielder: "Orta saha",
|
|
579
|
+
positionAttacker: "Forvet",
|
|
580
|
+
tabRecords: "Rekorlar",
|
|
581
|
+
clubSquadStatsEmpty: "Kadro istatistikleri hen\xFCz mevcut de\u011Fil.",
|
|
582
|
+
clubPlayerDetailEmpty: "Oyuncu bilgileri mevcut de\u011Fil.",
|
|
583
|
+
clubRecordsEmpty: "Kul\xFCp rekorlar\u0131 hen\xFCz mevcut de\u011Fil.",
|
|
584
|
+
squadViewRoster: "Kadro",
|
|
585
|
+
squadViewStats: "\u0130statistik",
|
|
586
|
+
statColApps: "Ma\xE7",
|
|
587
|
+
statColGoals: "Gol",
|
|
588
|
+
statColAssists: "Asist",
|
|
589
|
+
statColRating: "Puan",
|
|
590
|
+
statColMinutes: "Dakika",
|
|
591
|
+
statColYellow: "Sar\u0131 kart",
|
|
592
|
+
statColRed: "K\u0131rm\u0131z\u0131 kart",
|
|
593
|
+
statColXg: "xG",
|
|
594
|
+
statColShots: "\u015Eut",
|
|
595
|
+
detailNationality: "Uyruk",
|
|
596
|
+
detailAge: "Ya\u015F",
|
|
597
|
+
detailHeight: "Boy",
|
|
598
|
+
detailFoot: "Ayak",
|
|
599
|
+
detailSeason: "{season} sezonu",
|
|
600
|
+
clubPlayerBack: "Geri",
|
|
601
|
+
recordsTopScorers: "En \xE7ok gol atanlar",
|
|
602
|
+
recordsMostAppearances: "En \xE7ok ma\xE7 yapanlar",
|
|
603
|
+
recordsMostAssists: "En \xE7ok asist yapanlar",
|
|
604
|
+
recordsSince: "{season} sezonundan beri",
|
|
541
605
|
standingsColClub: "Tak\u0131m",
|
|
542
606
|
standingsColPlayed: "O",
|
|
543
607
|
standingsColWon: "G",
|
|
@@ -916,6 +980,38 @@ function normalizeUi(cfg) {
|
|
|
916
980
|
clubFixturesEmpty: strings.clubFixturesEmpty,
|
|
917
981
|
clubStandingsEmpty: strings.clubStandingsEmpty,
|
|
918
982
|
clubSquadEmpty: strings.clubSquadEmpty,
|
|
983
|
+
footRight: strings.footRight,
|
|
984
|
+
footLeft: strings.footLeft,
|
|
985
|
+
footBoth: strings.footBoth,
|
|
986
|
+
positionGoalkeeper: strings.positionGoalkeeper,
|
|
987
|
+
positionDefender: strings.positionDefender,
|
|
988
|
+
positionMidfielder: strings.positionMidfielder,
|
|
989
|
+
positionAttacker: strings.positionAttacker,
|
|
990
|
+
tabRecords: strings.tabRecords,
|
|
991
|
+
clubSquadStatsEmpty: strings.clubSquadStatsEmpty,
|
|
992
|
+
clubPlayerDetailEmpty: strings.clubPlayerDetailEmpty,
|
|
993
|
+
clubRecordsEmpty: strings.clubRecordsEmpty,
|
|
994
|
+
squadViewRoster: strings.squadViewRoster,
|
|
995
|
+
squadViewStats: strings.squadViewStats,
|
|
996
|
+
statColApps: strings.statColApps,
|
|
997
|
+
statColGoals: strings.statColGoals,
|
|
998
|
+
statColAssists: strings.statColAssists,
|
|
999
|
+
statColRating: strings.statColRating,
|
|
1000
|
+
statColMinutes: strings.statColMinutes,
|
|
1001
|
+
statColYellow: strings.statColYellow,
|
|
1002
|
+
statColRed: strings.statColRed,
|
|
1003
|
+
statColXg: strings.statColXg,
|
|
1004
|
+
statColShots: strings.statColShots,
|
|
1005
|
+
detailNationality: strings.detailNationality,
|
|
1006
|
+
detailAge: strings.detailAge,
|
|
1007
|
+
detailHeight: strings.detailHeight,
|
|
1008
|
+
detailFoot: strings.detailFoot,
|
|
1009
|
+
detailSeason: strings.detailSeason,
|
|
1010
|
+
clubPlayerBack: strings.clubPlayerBack,
|
|
1011
|
+
recordsTopScorers: strings.recordsTopScorers,
|
|
1012
|
+
recordsMostAppearances: strings.recordsMostAppearances,
|
|
1013
|
+
recordsMostAssists: strings.recordsMostAssists,
|
|
1014
|
+
recordsSince: strings.recordsSince,
|
|
919
1015
|
standingsColClub: strings.standingsColClub,
|
|
920
1016
|
standingsColPlayed: strings.standingsColPlayed,
|
|
921
1017
|
standingsColWon: strings.standingsColWon,
|
|
@@ -1215,6 +1311,7 @@ function toMarketOddsVM(card) {
|
|
|
1215
1311
|
mainLine: str(card.mainLine),
|
|
1216
1312
|
pinEnabled: card.pinEnabled === true,
|
|
1217
1313
|
statText: card.insight && typeof card.insight === "object" ? str(card.insight.text) : void 0,
|
|
1314
|
+
statTexts: Array.isArray(card.insights) ? card.insights.map((i) => str(i?.text)).filter((t) => !!t) : void 0,
|
|
1218
1315
|
tag: card.tag === "your_market" ? "your_market" : void 0,
|
|
1219
1316
|
live: card.live ?? null,
|
|
1220
1317
|
marketCount: typeof card.marketCount === "number" && Number.isFinite(card.marketCount) ? card.marketCount : void 0
|
|
@@ -3280,8 +3377,83 @@ function useClubSquad(conversation, { activeTab, enabled }) {
|
|
|
3280
3377
|
return { data, loading: effectiveLoading, refresh };
|
|
3281
3378
|
}
|
|
3282
3379
|
|
|
3283
|
-
// src/
|
|
3380
|
+
// src/useClubSquadStats.ts
|
|
3284
3381
|
var import_react12 = require("react");
|
|
3382
|
+
function useClubSquadStats(conversation, { activeTab, enabled }) {
|
|
3383
|
+
const [data, setData] = (0, import_react12.useState)(null);
|
|
3384
|
+
const [seasonName, setSeasonName] = (0, import_react12.useState)(null);
|
|
3385
|
+
const [loading, setLoading] = (0, import_react12.useState)(false);
|
|
3386
|
+
const [refreshCount, setRefreshCount] = (0, import_react12.useState)(0);
|
|
3387
|
+
const inFlightRef = (0, import_react12.useRef)(false);
|
|
3388
|
+
const conversationRef = (0, import_react12.useRef)(conversation);
|
|
3389
|
+
conversationRef.current = conversation;
|
|
3390
|
+
(0, import_react12.useEffect)(() => {
|
|
3391
|
+
if (activeTab !== "squad" || !enabled) return;
|
|
3392
|
+
let active = true;
|
|
3393
|
+
const doFetch = async () => {
|
|
3394
|
+
const conv = conversationRef.current;
|
|
3395
|
+
if (!conv || inFlightRef.current) return;
|
|
3396
|
+
inFlightRef.current = true;
|
|
3397
|
+
setLoading(true);
|
|
3398
|
+
try {
|
|
3399
|
+
const result = await conv.getClubSquadStats();
|
|
3400
|
+
if (active) {
|
|
3401
|
+
setData(result?.players ?? null);
|
|
3402
|
+
setSeasonName(result?.seasonName ?? null);
|
|
3403
|
+
}
|
|
3404
|
+
} catch {
|
|
3405
|
+
} finally {
|
|
3406
|
+
inFlightRef.current = false;
|
|
3407
|
+
if (active) setLoading(false);
|
|
3408
|
+
}
|
|
3409
|
+
};
|
|
3410
|
+
void doFetch();
|
|
3411
|
+
return () => {
|
|
3412
|
+
active = false;
|
|
3413
|
+
inFlightRef.current = false;
|
|
3414
|
+
};
|
|
3415
|
+
}, [activeTab, enabled, refreshCount]);
|
|
3416
|
+
const refresh = (0, import_react12.useCallback)(() => {
|
|
3417
|
+
setRefreshCount((c) => c + 1);
|
|
3418
|
+
}, []);
|
|
3419
|
+
const effectiveLoading = loading || activeTab === "squad" && enabled && data === null;
|
|
3420
|
+
return { data, seasonName, loading: effectiveLoading, refresh };
|
|
3421
|
+
}
|
|
3422
|
+
|
|
3423
|
+
// src/useClubPlayerDetail.ts
|
|
3424
|
+
var import_react13 = require("react");
|
|
3425
|
+
function useClubPlayerDetail(conversation) {
|
|
3426
|
+
const [data, setData] = (0, import_react13.useState)(null);
|
|
3427
|
+
const [loading, setLoading] = (0, import_react13.useState)(false);
|
|
3428
|
+
const requestSeqRef = (0, import_react13.useRef)(0);
|
|
3429
|
+
const conversationRef = (0, import_react13.useRef)(conversation);
|
|
3430
|
+
conversationRef.current = conversation;
|
|
3431
|
+
const fetch = (0, import_react13.useCallback)((playerId) => {
|
|
3432
|
+
const conv = conversationRef.current;
|
|
3433
|
+
if (!conv) return;
|
|
3434
|
+
const seq = ++requestSeqRef.current;
|
|
3435
|
+
setData(null);
|
|
3436
|
+
setLoading(true);
|
|
3437
|
+
void (async () => {
|
|
3438
|
+
try {
|
|
3439
|
+
const result = await conv.getClubPlayerDetail(playerId);
|
|
3440
|
+
if (seq === requestSeqRef.current) setData(result);
|
|
3441
|
+
} catch {
|
|
3442
|
+
} finally {
|
|
3443
|
+
if (seq === requestSeqRef.current) setLoading(false);
|
|
3444
|
+
}
|
|
3445
|
+
})();
|
|
3446
|
+
}, []);
|
|
3447
|
+
const clear = (0, import_react13.useCallback)(() => {
|
|
3448
|
+
requestSeqRef.current++;
|
|
3449
|
+
setData(null);
|
|
3450
|
+
setLoading(false);
|
|
3451
|
+
}, []);
|
|
3452
|
+
return { data, loading, fetch, clear };
|
|
3453
|
+
}
|
|
3454
|
+
|
|
3455
|
+
// src/usePresetGrid.ts
|
|
3456
|
+
var import_react14 = require("react");
|
|
3285
3457
|
|
|
3286
3458
|
// src/presetGrid.ts
|
|
3287
3459
|
var DEFAULT_SINGLES_LIMITS = [1.3, 1.5, 1.7, 2];
|
|
@@ -3424,22 +3596,22 @@ function marketDisplay(cell, s) {
|
|
|
3424
3596
|
// src/usePresetGrid.ts
|
|
3425
3597
|
var GRID_MAX_AGE_MS = 6e5;
|
|
3426
3598
|
function usePresetGrid({ getPricePresets, isOpen, locale, now = Date.now }) {
|
|
3427
|
-
const [grid, setGrid] = (0,
|
|
3428
|
-
const keptRef = (0,
|
|
3429
|
-
const localeRef = (0,
|
|
3430
|
-
const inFlightRef = (0,
|
|
3431
|
-
const mountedRef = (0,
|
|
3432
|
-
const getRef = (0,
|
|
3599
|
+
const [grid, setGrid] = (0, import_react14.useState)(null);
|
|
3600
|
+
const keptRef = (0, import_react14.useRef)(null);
|
|
3601
|
+
const localeRef = (0, import_react14.useRef)(locale);
|
|
3602
|
+
const inFlightRef = (0, import_react14.useRef)(false);
|
|
3603
|
+
const mountedRef = (0, import_react14.useRef)(true);
|
|
3604
|
+
const getRef = (0, import_react14.useRef)(getPricePresets);
|
|
3433
3605
|
getRef.current = getPricePresets;
|
|
3434
|
-
const nowRef = (0,
|
|
3606
|
+
const nowRef = (0, import_react14.useRef)(now);
|
|
3435
3607
|
nowRef.current = now;
|
|
3436
|
-
(0,
|
|
3608
|
+
(0, import_react14.useEffect)(() => {
|
|
3437
3609
|
mountedRef.current = true;
|
|
3438
3610
|
return () => {
|
|
3439
3611
|
mountedRef.current = false;
|
|
3440
3612
|
};
|
|
3441
3613
|
}, []);
|
|
3442
|
-
(0,
|
|
3614
|
+
(0, import_react14.useEffect)(() => {
|
|
3443
3615
|
if (localeRef.current !== locale) {
|
|
3444
3616
|
localeRef.current = locale;
|
|
3445
3617
|
keptRef.current = null;
|
|
@@ -3482,18 +3654,18 @@ function visibleGroupsOf(groups, states) {
|
|
|
3482
3654
|
}
|
|
3483
3655
|
|
|
3484
3656
|
// src/eventLogContext.ts
|
|
3485
|
-
var
|
|
3486
|
-
var EventLogContext = (0,
|
|
3657
|
+
var import_react15 = require("react");
|
|
3658
|
+
var EventLogContext = (0, import_react15.createContext)(null);
|
|
3487
3659
|
function useEventLog() {
|
|
3488
|
-
return (0,
|
|
3660
|
+
return (0, import_react15.useContext)(EventLogContext);
|
|
3489
3661
|
}
|
|
3490
3662
|
|
|
3491
3663
|
// src/popupTelemetry.ts
|
|
3492
|
-
var
|
|
3664
|
+
var import_react16 = require("react");
|
|
3493
3665
|
function usePopupTelemetry(log, isOpen, popupText, dismissPopup) {
|
|
3494
|
-
const shownRef = (0,
|
|
3495
|
-
const closedTextRef = (0,
|
|
3496
|
-
(0,
|
|
3666
|
+
const shownRef = (0, import_react16.useRef)(/* @__PURE__ */ new Set());
|
|
3667
|
+
const closedTextRef = (0, import_react16.useRef)(null);
|
|
3668
|
+
(0, import_react16.useEffect)(() => {
|
|
3497
3669
|
if (isOpen) {
|
|
3498
3670
|
if (closedTextRef.current) log?.log({ name: "popup_opened" });
|
|
3499
3671
|
closedTextRef.current = null;
|
|
@@ -3505,17 +3677,17 @@ function usePopupTelemetry(log, isOpen, popupText, dismissPopup) {
|
|
|
3505
3677
|
log?.log({ name: "popup_shown" });
|
|
3506
3678
|
}
|
|
3507
3679
|
}, [log, isOpen, popupText]);
|
|
3508
|
-
return (0,
|
|
3680
|
+
return (0, import_react16.useCallback)(() => {
|
|
3509
3681
|
log?.log({ name: "popup_dismissed" });
|
|
3510
3682
|
dismissPopup();
|
|
3511
3683
|
}, [log, dismissPopup]);
|
|
3512
3684
|
}
|
|
3513
3685
|
|
|
3514
3686
|
// src/openTelemetry.ts
|
|
3515
|
-
var
|
|
3687
|
+
var import_react17 = require("react");
|
|
3516
3688
|
function useOpenTelemetry(log, isOpen) {
|
|
3517
|
-
const openLoggedRef = (0,
|
|
3518
|
-
(0,
|
|
3689
|
+
const openLoggedRef = (0, import_react17.useRef)(false);
|
|
3690
|
+
(0, import_react17.useEffect)(() => {
|
|
3519
3691
|
if (!isOpen) {
|
|
3520
3692
|
openLoggedRef.current = false;
|
|
3521
3693
|
return;
|
|
@@ -3527,10 +3699,10 @@ function useOpenTelemetry(log, isOpen) {
|
|
|
3527
3699
|
}
|
|
3528
3700
|
|
|
3529
3701
|
// src/components/ChatFab.tsx
|
|
3530
|
-
var
|
|
3702
|
+
var import_react19 = require("react");
|
|
3531
3703
|
|
|
3532
3704
|
// src/components/BrandMark.tsx
|
|
3533
|
-
var
|
|
3705
|
+
var import_react18 = require("react");
|
|
3534
3706
|
|
|
3535
3707
|
// src/assets/logo.ts
|
|
3536
3708
|
var SS_LOGO_DATA_URI = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAjoAAAI6CAYAAAAuSOLAAAAAAXNSR0IArs4c6QAAAJplWElmTU0AKgAAAAgAAwESAAMAAAABAAEAAAExAAIAAAA9AAAAModpAAQAAAABAAAAcAAAAABBZG9iZSBQaG90b3Nob3AgMjYuMTAgKDIwMjUwNzMwLm0uMzE2NiAwN2IxMjM0KSAgKE1hY2ludG9zaCkAAAADoAEAAwAAAAEAAQAAoAIABAAAAAEAAAI6oAMABAAAAAEAAAI6AAAAACwGtVwAAAQwaVRYdFhNTDpjb20uYWRvYmUueG1wAAAAAAA8eDp4bXBtZXRhIHhtbG5zOng9ImFkb2JlOm5zOm1ldGEvIiB4OnhtcHRrPSJYTVAgQ29yZSA2LjAuMCI+CiAgIDxyZGY6UkRGIHhtbG5zOnJkZj0iaHR0cDovL3d3dy53My5vcmcvMTk5OS8wMi8yMi1yZGYtc3ludGF4LW5zIyI+CiAgICAgIDxyZGY6RGVzY3JpcHRpb24gcmRmOmFib3V0PSIiCiAgICAgICAgICAgIHhtbG5zOnhtcE1NPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvbW0vIgogICAgICAgICAgICB4bWxuczpzdFJlZj0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL3NUeXBlL1Jlc291cmNlUmVmIyIKICAgICAgICAgICAgeG1sbnM6eG1wPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvIgogICAgICAgICAgICB4bWxuczp0aWZmPSJodHRwOi8vbnMuYWRvYmUuY29tL3RpZmYvMS4wLyI+CiAgICAgICAgIDx4bXBNTTpEb2N1bWVudElEPnhtcC5kaWQ6QzBGRTM5NjM5NEJEMTFGMEJGNjZEMjUyN0U0MzU5RUM8L3htcE1NOkRvY3VtZW50SUQ+CiAgICAgICAgIDx4bXBNTTpJbnN0YW5jZUlEPnhtcC5paWQ6QzBGRTM5NjI5NEJEMTFGMEJGNjZEMjUyN0U0MzU5RUM8L3htcE1NOkluc3RhbmNlSUQ+CiAgICAgICAgIDx4bXBNTTpEZXJpdmVkRnJvbSByZGY6cGFyc2VUeXBlPSJSZXNvdXJjZSI+CiAgICAgICAgICAgIDxzdFJlZjppbnN0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";
|
|
@@ -3593,7 +3765,7 @@ function DashboardIcon({ name }) {
|
|
|
3593
3765
|
// src/components/BrandMark.tsx
|
|
3594
3766
|
var import_jsx_runtime2 = require("react/jsx-runtime");
|
|
3595
3767
|
function BrandMark({ logoUrl, className }) {
|
|
3596
|
-
const [failed, setFailed] = (0,
|
|
3768
|
+
const [failed, setFailed] = (0, import_react18.useState)(false);
|
|
3597
3769
|
if (!logoUrl || failed) return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(SsMark, { className });
|
|
3598
3770
|
return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("img", { className, src: logoUrl, alt: "", "aria-hidden": "true", onError: () => setFailed(true) });
|
|
3599
3771
|
}
|
|
@@ -3629,9 +3801,9 @@ function GreetingBubble({ text, onOpen, onDismiss, dismissLabel = "Dismiss", ask
|
|
|
3629
3801
|
var import_jsx_runtime4 = require("react/jsx-runtime");
|
|
3630
3802
|
function ChatFab({ label, greeting, popupText, logoUrl, onOpen, onDismissPopup, dismissLabel = "Dismiss", introAllowed = false, onIntroStart, asks }) {
|
|
3631
3803
|
const bubble = popupText ?? greeting;
|
|
3632
|
-
const [intro, setIntro] = (0,
|
|
3633
|
-
const armedRef = (0,
|
|
3634
|
-
(0,
|
|
3804
|
+
const [intro, setIntro] = (0, import_react19.useState)(false);
|
|
3805
|
+
const armedRef = (0, import_react19.useRef)(introAllowed);
|
|
3806
|
+
(0, import_react19.useEffect)(() => {
|
|
3635
3807
|
if (armedRef.current && bubble) {
|
|
3636
3808
|
armedRef.current = false;
|
|
3637
3809
|
setIntro(true);
|
|
@@ -3645,10 +3817,10 @@ function ChatFab({ label, greeting, popupText, logoUrl, onOpen, onDismissPopup,
|
|
|
3645
3817
|
}
|
|
3646
3818
|
|
|
3647
3819
|
// src/components/ChatPanel.tsx
|
|
3648
|
-
var
|
|
3820
|
+
var import_react66 = require("react");
|
|
3649
3821
|
|
|
3650
3822
|
// src/components/ChatHeader.tsx
|
|
3651
|
-
var
|
|
3823
|
+
var import_react20 = require("react");
|
|
3652
3824
|
var import_jsx_runtime5 = require("react/jsx-runtime");
|
|
3653
3825
|
function ChatHeader({
|
|
3654
3826
|
onClose,
|
|
@@ -3660,15 +3832,15 @@ function ChatHeader({
|
|
|
3660
3832
|
newConversationLabel = "New conversation",
|
|
3661
3833
|
moreOptionsLabel = "More options"
|
|
3662
3834
|
}) {
|
|
3663
|
-
const [menuOpen, setMenuOpen] = (0,
|
|
3664
|
-
const wrapRef = (0,
|
|
3665
|
-
const kebabRef = (0,
|
|
3666
|
-
const firstItemRef = (0,
|
|
3835
|
+
const [menuOpen, setMenuOpen] = (0, import_react20.useState)(false);
|
|
3836
|
+
const wrapRef = (0, import_react20.useRef)(null);
|
|
3837
|
+
const kebabRef = (0, import_react20.useRef)(null);
|
|
3838
|
+
const firstItemRef = (0, import_react20.useRef)(null);
|
|
3667
3839
|
const hasMenu = !!(canReset && onNewConversation);
|
|
3668
|
-
(0,
|
|
3840
|
+
(0, import_react20.useEffect)(() => {
|
|
3669
3841
|
if (menuOpen) firstItemRef.current?.focus();
|
|
3670
3842
|
}, [menuOpen]);
|
|
3671
|
-
(0,
|
|
3843
|
+
(0, import_react20.useEffect)(() => {
|
|
3672
3844
|
if (!menuOpen) return;
|
|
3673
3845
|
const onPointer = (e) => {
|
|
3674
3846
|
if (!wrapRef.current?.contains(e.target)) setMenuOpen(false);
|
|
@@ -3724,7 +3896,7 @@ function ChatHeader({
|
|
|
3724
3896
|
}
|
|
3725
3897
|
|
|
3726
3898
|
// src/components/MessageList.tsx
|
|
3727
|
-
var
|
|
3899
|
+
var import_react40 = require("react");
|
|
3728
3900
|
|
|
3729
3901
|
// src/components/Markdown.tsx
|
|
3730
3902
|
var import_react_markdown = __toESM(require("react-markdown"), 1);
|
|
@@ -3742,7 +3914,7 @@ function Markdown({ text }) {
|
|
|
3742
3914
|
}
|
|
3743
3915
|
|
|
3744
3916
|
// src/components/EntityCardList.tsx
|
|
3745
|
-
var
|
|
3917
|
+
var import_react21 = require("react");
|
|
3746
3918
|
var import_jsx_runtime7 = require("react/jsx-runtime");
|
|
3747
3919
|
var MAX_VISIBLE = 3;
|
|
3748
3920
|
var RECORD_RE = /^(\d+)-(\d+)-(\d+)$/;
|
|
@@ -3826,7 +3998,7 @@ function ScopeTabs({ scopes, active, onSelect }) {
|
|
|
3826
3998
|
)) });
|
|
3827
3999
|
}
|
|
3828
4000
|
function EntityCardItem({ c }) {
|
|
3829
|
-
const [active, setActive] = (0,
|
|
4001
|
+
const [active, setActive] = (0, import_react21.useState)(0);
|
|
3830
4002
|
const hasBody = c.scopes.length > 0;
|
|
3831
4003
|
if (!hasBody) {
|
|
3832
4004
|
return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { className: "ss-w-ecard ss-w-ecard-bare", "data-kind": c.kind, children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(CardHeader, { c, showScopeCrest: false }) });
|
|
@@ -3840,7 +4012,7 @@ function EntityCardItem({ c }) {
|
|
|
3840
4012
|
] });
|
|
3841
4013
|
}
|
|
3842
4014
|
function EntityCardList({ cards, disabled, showLessLabel = "Show less", showMoreLabel = (n) => `Show ${n} more` }) {
|
|
3843
|
-
const [expanded, setExpanded] = (0,
|
|
4015
|
+
const [expanded, setExpanded] = (0, import_react21.useState)(false);
|
|
3844
4016
|
if (cards.length === 0) return null;
|
|
3845
4017
|
const visible = expanded ? cards : cards.slice(0, MAX_VISIBLE);
|
|
3846
4018
|
const overflow = cards.length - MAX_VISIBLE;
|
|
@@ -3851,17 +4023,17 @@ function EntityCardList({ cards, disabled, showLessLabel = "Show less", showMore
|
|
|
3851
4023
|
}
|
|
3852
4024
|
|
|
3853
4025
|
// src/components/AddToSlipButton.tsx
|
|
3854
|
-
var
|
|
4026
|
+
var import_react25 = require("react");
|
|
3855
4027
|
|
|
3856
4028
|
// src/slipAdd.ts
|
|
3857
|
-
var
|
|
4029
|
+
var import_react23 = require("react");
|
|
3858
4030
|
var import_widget_sdk5 = require("@sensiblestats/widget-sdk");
|
|
3859
4031
|
|
|
3860
4032
|
// src/slipStateContext.ts
|
|
3861
|
-
var
|
|
3862
|
-
var SlipStateContext = (0,
|
|
4033
|
+
var import_react22 = require("react");
|
|
4034
|
+
var SlipStateContext = (0, import_react22.createContext)(null);
|
|
3863
4035
|
function useSlipState() {
|
|
3864
|
-
return (0,
|
|
4036
|
+
return (0, import_react22.useContext)(SlipStateContext);
|
|
3865
4037
|
}
|
|
3866
4038
|
|
|
3867
4039
|
// src/slipAdd.ts
|
|
@@ -3876,7 +4048,7 @@ function useSlipAdd(slip, ui) {
|
|
|
3876
4048
|
const slipState = useSlipState();
|
|
3877
4049
|
const handler = slip.onAddToSlip;
|
|
3878
4050
|
const rawLabels = !!ui?.rawBettingLabels;
|
|
3879
|
-
return (0,
|
|
4051
|
+
return (0, import_react23.useCallback)(async (selection, { marketDeveloperName, selectionLabel, line }) => {
|
|
3880
4052
|
if (!handler) return { kind: "failed" };
|
|
3881
4053
|
const pick = slipPickFields(selection, rawLabels ? selectionLabel : void 0, line);
|
|
3882
4054
|
if (marketDeveloperName !== void 0) {
|
|
@@ -3913,11 +4085,11 @@ function useSlipAdd(slip, ui) {
|
|
|
3913
4085
|
}
|
|
3914
4086
|
|
|
3915
4087
|
// src/components/Toast.tsx
|
|
3916
|
-
var
|
|
4088
|
+
var import_react24 = require("react");
|
|
3917
4089
|
var import_jsx_runtime8 = require("react/jsx-runtime");
|
|
3918
4090
|
var DISMISS_MS = 4e3;
|
|
3919
4091
|
function Toast({ toast, onDismiss }) {
|
|
3920
|
-
(0,
|
|
4092
|
+
(0, import_react24.useEffect)(() => {
|
|
3921
4093
|
if (!toast) return;
|
|
3922
4094
|
const timer = setTimeout(onDismiss, DISMISS_MS);
|
|
3923
4095
|
return () => clearTimeout(timer);
|
|
@@ -3929,10 +4101,10 @@ function Toast({ toast, onDismiss }) {
|
|
|
3929
4101
|
// src/components/AddToSlipButton.tsx
|
|
3930
4102
|
var import_jsx_runtime9 = require("react/jsx-runtime");
|
|
3931
4103
|
function SlipButton({ selection, shownOdds, marketDeveloperName, selectionLabel, line, slip, ui, price, ariaLabel }) {
|
|
3932
|
-
const [pending, setPending] = (0,
|
|
3933
|
-
const [settledLocal, setSettledLocal] = (0,
|
|
3934
|
-
const [toast, setToast] = (0,
|
|
3935
|
-
const dismiss = (0,
|
|
4104
|
+
const [pending, setPending] = (0, import_react25.useState)(false);
|
|
4105
|
+
const [settledLocal, setSettledLocal] = (0, import_react25.useState)(false);
|
|
4106
|
+
const [toast, setToast] = (0, import_react25.useState)(null);
|
|
4107
|
+
const dismiss = (0, import_react25.useCallback)(() => setToast(null), []);
|
|
3936
4108
|
const add = useSlipAdd(slip, ui);
|
|
3937
4109
|
const slipState = useSlipState();
|
|
3938
4110
|
const handler = slip.onAddToSlip;
|
|
@@ -4020,14 +4192,14 @@ function OddsMovementBadge({
|
|
|
4020
4192
|
}
|
|
4021
4193
|
|
|
4022
4194
|
// src/components/Crest.tsx
|
|
4023
|
-
var
|
|
4195
|
+
var import_react26 = require("react");
|
|
4024
4196
|
var import_jsx_runtime11 = require("react/jsx-runtime");
|
|
4025
4197
|
function initials2(name) {
|
|
4026
4198
|
return (name ?? "").trim().slice(0, 1).toUpperCase() || "?";
|
|
4027
4199
|
}
|
|
4028
4200
|
function Crest2({ url, name, kind }) {
|
|
4029
4201
|
const cls = kind === "comp" ? "ss-w-bi-comp-logo" : "ss-w-bi-crest";
|
|
4030
|
-
const [failed, setFailed] = (0,
|
|
4202
|
+
const [failed, setFailed] = (0, import_react26.useState)(false);
|
|
4031
4203
|
if (url && !failed) {
|
|
4032
4204
|
return /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("img", { className: cls, src: url, alt: "", "aria-hidden": "true", onError: () => setFailed(true) });
|
|
4033
4205
|
}
|
|
@@ -4035,7 +4207,7 @@ function Crest2({ url, name, kind }) {
|
|
|
4035
4207
|
}
|
|
4036
4208
|
|
|
4037
4209
|
// src/components/PinToggle.tsx
|
|
4038
|
-
var
|
|
4210
|
+
var import_react27 = require("react");
|
|
4039
4211
|
var import_jsx_runtime12 = require("react/jsx-runtime");
|
|
4040
4212
|
var PIN_GLYPHS = {
|
|
4041
4213
|
pin: { viewBox: "0 0 24 24", strokeWidth: 1.4, transform: "scale(1.5)", d: "M9.5 1.5 14.5 6.5 13 8l-.5-.5-3 3 .3 2.2-1.4 1.4L5.6 11.3l-3.3 3.3-1-1 3.3-3.3L1.9 7.5l1.4-1.4 2.2.3 3-3L8 2.9z" },
|
|
@@ -4043,8 +4215,8 @@ var PIN_GLYPHS = {
|
|
|
4043
4215
|
bookmark: { viewBox: "0 0 24 24", strokeWidth: 2, d: "M7 3h10a1.5 1.5 0 0 1 1.5 1.5V21l-6.5-3.6L5.5 21V4.5A1.5 1.5 0 0 1 7 3z" }
|
|
4044
4216
|
};
|
|
4045
4217
|
function PinToggle({ pin, monitor, ui, market }) {
|
|
4046
|
-
const [toast, setToast] = (0,
|
|
4047
|
-
const dismiss = (0,
|
|
4218
|
+
const [toast, setToast] = (0, import_react27.useState)(null);
|
|
4219
|
+
const dismiss = (0, import_react27.useCallback)(() => setToast(null), []);
|
|
4048
4220
|
const log = useEventLog();
|
|
4049
4221
|
if (!monitor || !monitor.enabled) return null;
|
|
4050
4222
|
const key = pinKey(pin);
|
|
@@ -4101,11 +4273,11 @@ function PinToggle({ pin, monitor, ui, market }) {
|
|
|
4101
4273
|
}
|
|
4102
4274
|
|
|
4103
4275
|
// src/components/PriceHistoryButton.tsx
|
|
4104
|
-
var
|
|
4276
|
+
var import_react28 = require("react");
|
|
4105
4277
|
var import_jsx_runtime13 = require("react/jsx-runtime");
|
|
4106
4278
|
function PriceHistoryButton({ selection, monitor, ui }) {
|
|
4107
|
-
const [toast, setToast] = (0,
|
|
4108
|
-
const dismiss = (0,
|
|
4279
|
+
const [toast, setToast] = (0, import_react28.useState)(null);
|
|
4280
|
+
const dismiss = (0, import_react28.useCallback)(() => setToast(null), []);
|
|
4109
4281
|
const log = useEventLog();
|
|
4110
4282
|
if (!monitor || !monitor.enabled) return null;
|
|
4111
4283
|
const name = joinSelection(selection.selectionLabel ?? void 0, selection.line ?? void 0);
|
|
@@ -4220,15 +4392,15 @@ function BettingInsightList({ insights, ui, slip, monitor }) {
|
|
|
4220
4392
|
}
|
|
4221
4393
|
|
|
4222
4394
|
// src/components/AddAllToSlipButton.tsx
|
|
4223
|
-
var
|
|
4395
|
+
var import_react29 = require("react");
|
|
4224
4396
|
var import_jsx_runtime15 = require("react/jsx-runtime");
|
|
4225
4397
|
function AddAllToSlipButton({ legs, slip, ui }) {
|
|
4226
4398
|
const add = useSlipAdd(slip, ui);
|
|
4227
4399
|
const slipState = useSlipState();
|
|
4228
|
-
const [pending, setPending] = (0,
|
|
4229
|
-
const [settledLocal, setSettledLocal] = (0,
|
|
4230
|
-
const [toast, setToast] = (0,
|
|
4231
|
-
const dismiss = (0,
|
|
4400
|
+
const [pending, setPending] = (0, import_react29.useState)(false);
|
|
4401
|
+
const [settledLocal, setSettledLocal] = (0, import_react29.useState)({});
|
|
4402
|
+
const [toast, setToast] = (0, import_react29.useState)(null);
|
|
4403
|
+
const dismiss = (0, import_react29.useCallback)(() => setToast(null), []);
|
|
4232
4404
|
if (!ui || !slip.onAddToSlip || legs.length < 2) return null;
|
|
4233
4405
|
const settled = slipState ? slipState.settled : settledLocal;
|
|
4234
4406
|
const open = legs.filter((leg) => !settled[leg.matchOddsId]);
|
|
@@ -4270,10 +4442,10 @@ function AddAllToSlipButton({ legs, slip, ui }) {
|
|
|
4270
4442
|
}
|
|
4271
4443
|
|
|
4272
4444
|
// src/presetToolsContext.ts
|
|
4273
|
-
var
|
|
4274
|
-
var PresetToolsContext = (0,
|
|
4445
|
+
var import_react30 = require("react");
|
|
4446
|
+
var PresetToolsContext = (0, import_react30.createContext)(null);
|
|
4275
4447
|
function usePresetTools() {
|
|
4276
|
-
return (0,
|
|
4448
|
+
return (0, import_react30.useContext)(PresetToolsContext);
|
|
4277
4449
|
}
|
|
4278
4450
|
|
|
4279
4451
|
// src/components/ComboCardList.tsx
|
|
@@ -4338,7 +4510,7 @@ function ComboCardList({ cards, ui, slip, monitor }) {
|
|
|
4338
4510
|
}
|
|
4339
4511
|
|
|
4340
4512
|
// src/components/MarketOddsCardList.tsx
|
|
4341
|
-
var
|
|
4513
|
+
var import_react31 = require("react");
|
|
4342
4514
|
|
|
4343
4515
|
// src/components/AllMarketsButton.tsx
|
|
4344
4516
|
var import_jsx_runtime17 = require("react/jsx-runtime");
|
|
@@ -4401,7 +4573,7 @@ function fmtHhMm(iso, locale) {
|
|
|
4401
4573
|
return new Date(iso).toLocaleTimeString(locale, { hour: "2-digit", minute: "2-digit", hour12: false });
|
|
4402
4574
|
}
|
|
4403
4575
|
function MarketOddsCard({ vm, ui, slip, monitor, inSlipIds, hideHeader, pinRef }) {
|
|
4404
|
-
const [open, setOpen] = (0,
|
|
4576
|
+
const [open, setOpen] = (0, import_react31.useState)(false);
|
|
4405
4577
|
const kickoffFallback = vm.kickoffUtc && ui?.bettingKickoff ? ui.bettingKickoff(vm.kickoffUtc) : void 0;
|
|
4406
4578
|
const kickoff = vm.kickoffLabel ?? (kickoffFallback ? `${kickoffFallback.dayLabel} ${kickoffFallback.time}` : void 0);
|
|
4407
4579
|
const hasNamedTeams = !!vm.homeTeamName && !!vm.awayTeamName;
|
|
@@ -4411,9 +4583,9 @@ function MarketOddsCard({ vm, ui, slip, monitor, inSlipIds, hideHeader, pinRef }
|
|
|
4411
4583
|
const asOfMs = live ? new Date(live.asOfUtc).getTime() : NaN;
|
|
4412
4584
|
const isStale = live != null && !isClosed && (vm.awaitingLiveUpdate === true || Date.now() - asOfMs > STALE_AFTER_MS);
|
|
4413
4585
|
const staleTime = isStale && live ? fmtHhMm(live.asOfUtc, ui?.locale ?? "en") : null;
|
|
4414
|
-
const [, setStaleTick] = (0,
|
|
4586
|
+
const [, setStaleTick] = (0, import_react31.useState)(0);
|
|
4415
4587
|
const watchStale = live != null && !isClosed && !isStale;
|
|
4416
|
-
(0,
|
|
4588
|
+
(0, import_react31.useEffect)(() => {
|
|
4417
4589
|
if (!watchStale) return;
|
|
4418
4590
|
const id = window.setTimeout(() => setStaleTick((n) => n + 1), Math.max(0, asOfMs + STALE_AFTER_MS - Date.now()) + 1);
|
|
4419
4591
|
return () => window.clearTimeout(id);
|
|
@@ -4467,7 +4639,7 @@ function MarketOddsCard({ vm, ui, slip, monitor, inSlipIds, hideHeader, pinRef }
|
|
|
4467
4639
|
] }) : null
|
|
4468
4640
|
] }) : null
|
|
4469
4641
|
] }),
|
|
4470
|
-
|
|
4642
|
+
!hideHeader && !pinRef ? (vm.statTexts && vm.statTexts.length > 0 ? vm.statTexts : vm.statText ? [vm.statText] : []).map((text, i) => /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("div", { className: "ss-w-mo-stat", children: text }, i)) : null,
|
|
4471
4643
|
isClosed ? /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("div", { className: "ss-w-mo-closed", children: closedReason === "suspended" ? /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("span", { children: ui?.liveCard.suspended ?? "Market suspended" }) : closedReason === "no_live_price" ? /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("span", { children: ui?.liveCard.noPrice ?? "No live price available" }) : closedReason === "full_time" ? /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("span", { children: ui?.liveCard.fullTime ?? "Full time" }) : null }) : /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)(import_jsx_runtime18.Fragment, { children: [
|
|
4472
4644
|
/* @__PURE__ */ (0, import_jsx_runtime18.jsxs)("div", { className: "ss-w-mo-rows", children: [
|
|
4473
4645
|
vm.mainRows.map((row) => /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(OddsRow, { vm, row, ui, slip, inSlipIds, history, suppressSlip: isStale }, row.key)),
|
|
@@ -4492,7 +4664,7 @@ function MarketOddsCardList({ cards, ui, slip, monitor, inSlipIds, hideHeader, p
|
|
|
4492
4664
|
}
|
|
4493
4665
|
|
|
4494
4666
|
// src/components/CompactOddsList.tsx
|
|
4495
|
-
var
|
|
4667
|
+
var import_react32 = require("react");
|
|
4496
4668
|
|
|
4497
4669
|
// src/compactList.ts
|
|
4498
4670
|
var COMPACT_MIN_CARDS = 3;
|
|
@@ -4606,11 +4778,11 @@ function Row({ row, columns, ui, slip, monitor, rowRef }) {
|
|
|
4606
4778
|
] });
|
|
4607
4779
|
}
|
|
4608
4780
|
function CompactOddsList({ list, ui, slip, monitor }) {
|
|
4609
|
-
const [shown, setShown] = (0,
|
|
4781
|
+
const [shown, setShown] = (0, import_react32.useState)(COMPACT_PAGE);
|
|
4610
4782
|
const hidden = list.rowCount - shown;
|
|
4611
|
-
const [focusIndex, setFocusIndex] = (0,
|
|
4612
|
-
const focusRef = (0,
|
|
4613
|
-
(0,
|
|
4783
|
+
const [focusIndex, setFocusIndex] = (0, import_react32.useState)(null);
|
|
4784
|
+
const focusRef = (0, import_react32.useRef)(null);
|
|
4785
|
+
(0, import_react32.useEffect)(() => {
|
|
4614
4786
|
if (focusIndex !== null) focusRef.current?.focus();
|
|
4615
4787
|
}, [focusIndex]);
|
|
4616
4788
|
let left = shown;
|
|
@@ -4915,7 +5087,7 @@ function FixtureCard({ card }) {
|
|
|
4915
5087
|
}
|
|
4916
5088
|
|
|
4917
5089
|
// src/components/dashboard/CountdownCard.tsx
|
|
4918
|
-
var
|
|
5090
|
+
var import_react33 = require("react");
|
|
4919
5091
|
var import_jsx_runtime25 = require("react/jsx-runtime");
|
|
4920
5092
|
var DAY_MS = 864e5;
|
|
4921
5093
|
function remainingSegments(kickoffUnix, nowMs, withSeconds) {
|
|
@@ -4934,12 +5106,12 @@ function remainingSegments(kickoffUnix, nowMs, withSeconds) {
|
|
|
4934
5106
|
function CountdownCard({ card }) {
|
|
4935
5107
|
const { data } = card;
|
|
4936
5108
|
const unitLabel = { d: data.daysUnit, h: data.hoursUnit, m: data.minutesUnit, s: data.secondsUnit };
|
|
4937
|
-
const [nowMs, setNowMs] = (0,
|
|
4938
|
-
const [reduced] = (0,
|
|
5109
|
+
const [nowMs, setNowMs] = (0, import_react33.useState)(() => Date.now());
|
|
5110
|
+
const [reduced] = (0, import_react33.useState)(
|
|
4939
5111
|
() => typeof window !== "undefined" && window.matchMedia("(prefers-reduced-motion: reduce)").matches
|
|
4940
5112
|
);
|
|
4941
5113
|
const withinDay = data.kickoffUnix * 1e3 - nowMs < DAY_MS;
|
|
4942
|
-
(0,
|
|
5114
|
+
(0, import_react33.useEffect)(() => {
|
|
4943
5115
|
if (reduced) return;
|
|
4944
5116
|
const id = window.setInterval(() => setNowMs(Date.now()), withinDay ? 1e3 : 6e4);
|
|
4945
5117
|
return () => window.clearInterval(id);
|
|
@@ -4947,7 +5119,7 @@ function CountdownCard({ card }) {
|
|
|
4947
5119
|
const segments = remainingSegments(data.kickoffUnix, nowMs, withinDay && !reduced);
|
|
4948
5120
|
return /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("div", { className: "ss-w-fandash-card ss-w-fandash-countdown", children: /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)("div", { className: "ss-w-fandash-countdown-top", children: [
|
|
4949
5121
|
/* @__PURE__ */ (0, import_jsx_runtime25.jsx)("span", { className: "ss-w-fandash-eyebrow", children: card.title ?? "Kick-off in" }),
|
|
4950
|
-
segments ? /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("span", { className: "ss-w-fandash-countdown-clock", children: segments.map((s, i) => /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)(
|
|
5122
|
+
segments ? /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("span", { className: "ss-w-fandash-countdown-clock", children: segments.map((s, i) => /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)(import_react33.Fragment, { children: [
|
|
4951
5123
|
i > 0 ? /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("span", { className: "ss-w-fandash-countdown-colon", children: ":" }) : null,
|
|
4952
5124
|
/* @__PURE__ */ (0, import_jsx_runtime25.jsxs)("span", { className: "ss-w-fandash-countdown-seg", children: [
|
|
4953
5125
|
/* @__PURE__ */ (0, import_jsx_runtime25.jsx)("span", { className: "ss-w-fandash-countdown-value", children: s.value }),
|
|
@@ -4958,7 +5130,7 @@ function CountdownCard({ card }) {
|
|
|
4958
5130
|
}
|
|
4959
5131
|
|
|
4960
5132
|
// src/components/dashboard/InjuriesCard.tsx
|
|
4961
|
-
var
|
|
5133
|
+
var import_react34 = require("react");
|
|
4962
5134
|
var import_jsx_runtime26 = require("react/jsx-runtime");
|
|
4963
5135
|
var SHOWN = 3;
|
|
4964
5136
|
function ColHead({ name, crestUrl }) {
|
|
@@ -4981,7 +5153,7 @@ function InjuryList({ rows, emptyLabel, limit }) {
|
|
|
4981
5153
|
}
|
|
4982
5154
|
function InjuriesCard({ card, ui }) {
|
|
4983
5155
|
const { data } = card;
|
|
4984
|
-
const [expanded, setExpanded] = (0,
|
|
5156
|
+
const [expanded, setExpanded] = (0, import_react34.useState)(false);
|
|
4985
5157
|
const hidden = Math.max(0, data.ours.length - SHOWN) + Math.max(0, data.theirs.length - SHOWN);
|
|
4986
5158
|
const limit = expanded ? void 0 : SHOWN;
|
|
4987
5159
|
const showMore = ui?.showMore ?? ((n) => `Show ${n} more`);
|
|
@@ -5087,7 +5259,7 @@ function LinksCard({ card }) {
|
|
|
5087
5259
|
}
|
|
5088
5260
|
|
|
5089
5261
|
// src/components/dashboard/PostMatchResultCard.tsx
|
|
5090
|
-
var
|
|
5262
|
+
var import_react35 = require("react");
|
|
5091
5263
|
var import_jsx_runtime32 = require("react/jsx-runtime");
|
|
5092
5264
|
function initials3(name) {
|
|
5093
5265
|
return name.trim().slice(0, 3).toUpperCase();
|
|
@@ -5097,7 +5269,7 @@ function PostMatchCrest({
|
|
|
5097
5269
|
name,
|
|
5098
5270
|
side
|
|
5099
5271
|
}) {
|
|
5100
|
-
const [failed, setFailed] = (0,
|
|
5272
|
+
const [failed, setFailed] = (0, import_react35.useState)(false);
|
|
5101
5273
|
const cls = `ss-w-fandash-postmatch-crest ss-w-fandash-postmatch-crest--${side}`;
|
|
5102
5274
|
if (url && !failed) {
|
|
5103
5275
|
return /* @__PURE__ */ (0, import_jsx_runtime32.jsx)("img", { className: cls, src: url, alt: "", "aria-hidden": "true", onError: () => setFailed(true) });
|
|
@@ -5296,10 +5468,10 @@ function RestingFormCard({ card }) {
|
|
|
5296
5468
|
}
|
|
5297
5469
|
|
|
5298
5470
|
// src/components/dashboard/LiveScoreCard.tsx
|
|
5299
|
-
var
|
|
5471
|
+
var import_react37 = require("react");
|
|
5300
5472
|
|
|
5301
5473
|
// src/useLiveClock.ts
|
|
5302
|
-
var
|
|
5474
|
+
var import_react36 = require("react");
|
|
5303
5475
|
var TICK_MS = 6e4;
|
|
5304
5476
|
var MAX_LIVE_TICK_MINUTES = 15;
|
|
5305
5477
|
function computeDisplayMinute(minute, clockRunning, receivedAtMs) {
|
|
@@ -5308,10 +5480,10 @@ function computeDisplayMinute(minute, clockRunning, receivedAtMs) {
|
|
|
5308
5480
|
return minute + Math.min(Math.max(0, elapsedMinutes), MAX_LIVE_TICK_MINUTES);
|
|
5309
5481
|
}
|
|
5310
5482
|
function useLiveClock(minute, clockRunning, receivedAtMs) {
|
|
5311
|
-
const [displayMinute, setDisplayMinute] = (0,
|
|
5483
|
+
const [displayMinute, setDisplayMinute] = (0, import_react36.useState)(
|
|
5312
5484
|
() => computeDisplayMinute(minute, clockRunning, receivedAtMs)
|
|
5313
5485
|
);
|
|
5314
|
-
(0,
|
|
5486
|
+
(0, import_react36.useEffect)(() => {
|
|
5315
5487
|
setDisplayMinute(computeDisplayMinute(minute, clockRunning, receivedAtMs));
|
|
5316
5488
|
if (!clockRunning) return;
|
|
5317
5489
|
const id = window.setInterval(() => {
|
|
@@ -5328,7 +5500,7 @@ function initials5(name) {
|
|
|
5328
5500
|
return name.trim().slice(0, 3).toUpperCase();
|
|
5329
5501
|
}
|
|
5330
5502
|
function LiveCrest({ url, name, side }) {
|
|
5331
|
-
const [failed, setFailed] = (0,
|
|
5503
|
+
const [failed, setFailed] = (0, import_react37.useState)(false);
|
|
5332
5504
|
const cls = `ss-w-fandash-live-crest ss-w-fandash-live-crest--${side}`;
|
|
5333
5505
|
if (url && !failed) {
|
|
5334
5506
|
return /* @__PURE__ */ (0, import_jsx_runtime41.jsx)("img", { className: cls, src: url, alt: "", "aria-hidden": "true", onError: () => setFailed(true) });
|
|
@@ -5347,7 +5519,7 @@ function LiveScoreCard({
|
|
|
5347
5519
|
}) {
|
|
5348
5520
|
const { data } = card;
|
|
5349
5521
|
const seedKey = `${data.minute}:${data.homeScore}:${data.awayScore}`;
|
|
5350
|
-
const seedRef = (0,
|
|
5522
|
+
const seedRef = (0, import_react37.useRef)(null);
|
|
5351
5523
|
if (!seedRef.current || seedRef.current.key !== seedKey) {
|
|
5352
5524
|
seedRef.current = { key: seedKey, receivedAtMs: Date.now() };
|
|
5353
5525
|
}
|
|
@@ -5387,7 +5559,7 @@ function LiveScoreCard({
|
|
|
5387
5559
|
}
|
|
5388
5560
|
|
|
5389
5561
|
// src/components/dashboard/LiveTimelineCard.tsx
|
|
5390
|
-
var
|
|
5562
|
+
var import_react38 = require("react");
|
|
5391
5563
|
var import_jsx_runtime42 = require("react/jsx-runtime");
|
|
5392
5564
|
var SHOWN2 = 3;
|
|
5393
5565
|
function EventIcon({ type }) {
|
|
@@ -5429,7 +5601,7 @@ function EventRow({ e }) {
|
|
|
5429
5601
|
] });
|
|
5430
5602
|
}
|
|
5431
5603
|
function LiveTimelineCard({ card, ui }) {
|
|
5432
|
-
const [expanded, setExpanded] = (0,
|
|
5604
|
+
const [expanded, setExpanded] = (0, import_react38.useState)(false);
|
|
5433
5605
|
const events = card.data.events;
|
|
5434
5606
|
if (!events || events.length === 0) return null;
|
|
5435
5607
|
const sorted = [...events].sort((a, b) => b.minute - a.minute);
|
|
@@ -5454,7 +5626,7 @@ function LiveTimelineCard({ card, ui }) {
|
|
|
5454
5626
|
}
|
|
5455
5627
|
|
|
5456
5628
|
// src/components/dashboard/MomentumWave.tsx
|
|
5457
|
-
var
|
|
5629
|
+
var import_react39 = require("react");
|
|
5458
5630
|
var import_jsx_runtime43 = require("react/jsx-runtime");
|
|
5459
5631
|
var WIDTH = 270;
|
|
5460
5632
|
var HEIGHT = 56;
|
|
@@ -5478,7 +5650,7 @@ function MomentumWave({
|
|
|
5478
5650
|
}) {
|
|
5479
5651
|
if (points.length === 0) return null;
|
|
5480
5652
|
const { area, line, lastLeftPct, lastTopPx } = buildPaths(points);
|
|
5481
|
-
const clipId = (0,
|
|
5653
|
+
const clipId = (0, import_react39.useId)();
|
|
5482
5654
|
const topClipId = `${clipId}-top`;
|
|
5483
5655
|
const bottomClipId = `${clipId}-bottom`;
|
|
5484
5656
|
const topClass = clubIsHome ? "ss-w-fandash-live-mom-home" : "ss-w-fandash-live-mom-away";
|
|
@@ -5671,11 +5843,11 @@ function turnAnchor(messages) {
|
|
|
5671
5843
|
}
|
|
5672
5844
|
function MessageList({ controller, ui, slip, onDashboardTap, monitor }) {
|
|
5673
5845
|
const { state, send } = controller;
|
|
5674
|
-
const listRef = (0,
|
|
5675
|
-
const endRef = (0,
|
|
5676
|
-
const pinnedRef = (0,
|
|
5677
|
-
const anchoredTurnRef = (0,
|
|
5678
|
-
(0,
|
|
5846
|
+
const listRef = (0, import_react40.useRef)(null);
|
|
5847
|
+
const endRef = (0, import_react40.useRef)(null);
|
|
5848
|
+
const pinnedRef = (0, import_react40.useRef)(true);
|
|
5849
|
+
const anchoredTurnRef = (0, import_react40.useRef)(null);
|
|
5850
|
+
(0, import_react40.useEffect)(() => {
|
|
5679
5851
|
const anchor = turnAnchor(state.messages);
|
|
5680
5852
|
const list = listRef.current;
|
|
5681
5853
|
if (anchor && anchor.turnId !== anchoredTurnRef.current) {
|
|
@@ -5732,13 +5904,13 @@ function MessageList({ controller, ui, slip, onDashboardTap, monitor }) {
|
|
|
5732
5904
|
}
|
|
5733
5905
|
|
|
5734
5906
|
// src/components/ChatInput.tsx
|
|
5735
|
-
var
|
|
5907
|
+
var import_react41 = require("react");
|
|
5736
5908
|
var import_jsx_runtime49 = require("react/jsx-runtime");
|
|
5737
|
-
var ChatInput = (0,
|
|
5738
|
-
const [value, setValue] = (0,
|
|
5739
|
-
const textareaRef = (0,
|
|
5740
|
-
const stopRef = (0,
|
|
5741
|
-
const textBoxWantsFocusRef = (0,
|
|
5909
|
+
var ChatInput = (0, import_react41.forwardRef)(function ChatInput2({ placeholder, streaming, onSend, onStop, stopLabel = "Stop response", sendLabel = "Send message", disabled = false, onType }, ref) {
|
|
5910
|
+
const [value, setValue] = (0, import_react41.useState)("");
|
|
5911
|
+
const textareaRef = (0, import_react41.useRef)(null);
|
|
5912
|
+
const stopRef = (0, import_react41.useRef)(null);
|
|
5913
|
+
const textBoxWantsFocusRef = (0, import_react41.useRef)(false);
|
|
5742
5914
|
const submit = () => {
|
|
5743
5915
|
if (disabled) return;
|
|
5744
5916
|
const t = value.trim();
|
|
@@ -5752,7 +5924,7 @@ var ChatInput = (0, import_react39.forwardRef)(function ChatInput2({ placeholder
|
|
|
5752
5924
|
submit();
|
|
5753
5925
|
}
|
|
5754
5926
|
};
|
|
5755
|
-
(0,
|
|
5927
|
+
(0, import_react41.useImperativeHandle)(ref, () => ({
|
|
5756
5928
|
focus() {
|
|
5757
5929
|
const box = textareaRef.current;
|
|
5758
5930
|
if (box && !box.disabled) {
|
|
@@ -5764,7 +5936,7 @@ var ChatInput = (0, import_react39.forwardRef)(function ChatInput2({ placeholder
|
|
|
5764
5936
|
stopRef.current?.focus();
|
|
5765
5937
|
}
|
|
5766
5938
|
}), []);
|
|
5767
|
-
(0,
|
|
5939
|
+
(0, import_react41.useEffect)(() => {
|
|
5768
5940
|
if (streaming || disabled || !textBoxWantsFocusRef.current) return;
|
|
5769
5941
|
textBoxWantsFocusRef.current = false;
|
|
5770
5942
|
const box = textareaRef.current;
|
|
@@ -5796,6 +5968,7 @@ var ChatInput = (0, import_react39.forwardRef)(function ChatInput2({ placeholder
|
|
|
5796
5968
|
});
|
|
5797
5969
|
|
|
5798
5970
|
// src/components/TabBar.tsx
|
|
5971
|
+
var import_react42 = require("react");
|
|
5799
5972
|
var import_jsx_runtime50 = require("react/jsx-runtime");
|
|
5800
5973
|
function TabBar({ monitor, ui, matchCount, oddsCount, todayCount, hasToday, gamesEnabled, clubEnabled }) {
|
|
5801
5974
|
const tabs = [
|
|
@@ -5811,8 +5984,16 @@ function TabBar({ monitor, ui, matchCount, oddsCount, todayCount, hasToday, game
|
|
|
5811
5984
|
],
|
|
5812
5985
|
...gamesEnabled ? [{ tab: "games", label: ui.tabGames, count: 0, dot: false }] : []
|
|
5813
5986
|
];
|
|
5987
|
+
const listRef = (0, import_react42.useRef)(null);
|
|
5988
|
+
const activeTab = monitor.activeTab;
|
|
5989
|
+
(0, import_react42.useEffect)(() => {
|
|
5990
|
+
const el = listRef.current?.querySelector("[data-on]");
|
|
5991
|
+
if (!el || typeof el.scrollIntoView !== "function") return;
|
|
5992
|
+
const reduce = typeof window.matchMedia === "function" && window.matchMedia("(prefers-reduced-motion: reduce)").matches;
|
|
5993
|
+
el.scrollIntoView({ block: "nearest", inline: "nearest", behavior: reduce ? "auto" : "smooth" });
|
|
5994
|
+
}, [activeTab]);
|
|
5814
5995
|
if (tabs.length < 2) return null;
|
|
5815
|
-
return /* @__PURE__ */ (0, import_jsx_runtime50.jsx)("div", { className: "ss-w-tabs", role: "tablist", children: tabs.map(({ tab, label, count, dot }) => {
|
|
5996
|
+
return /* @__PURE__ */ (0, import_jsx_runtime50.jsx)("div", { className: "ss-w-tabs", role: "tablist", ref: listRef, children: tabs.map(({ tab, label, count, dot }) => {
|
|
5816
5997
|
const active = monitor.activeTab === tab;
|
|
5817
5998
|
return /* @__PURE__ */ (0, import_jsx_runtime50.jsxs)(
|
|
5818
5999
|
"button",
|
|
@@ -5889,10 +6070,10 @@ function MarketAccordion({ match, monitor, ui, slip }) {
|
|
|
5889
6070
|
}
|
|
5890
6071
|
|
|
5891
6072
|
// src/components/LiveFactBlock.tsx
|
|
5892
|
-
var
|
|
6073
|
+
var import_react43 = require("react");
|
|
5893
6074
|
var import_jsx_runtime52 = require("react/jsx-runtime");
|
|
5894
6075
|
function LiveFactBlock({ facts, matchId, ui, slip, onAsk }) {
|
|
5895
|
-
const [expanded, setExpanded] = (0,
|
|
6076
|
+
const [expanded, setExpanded] = (0, import_react43.useState)(false);
|
|
5896
6077
|
const [current, ...earlier] = facts;
|
|
5897
6078
|
if (!current) return null;
|
|
5898
6079
|
const m = current.market;
|
|
@@ -6158,7 +6339,7 @@ function OddsPanel({ monitor, ui, slip }) {
|
|
|
6158
6339
|
}
|
|
6159
6340
|
|
|
6160
6341
|
// src/components/TodayPanel.tsx
|
|
6161
|
-
var
|
|
6342
|
+
var import_react47 = require("react");
|
|
6162
6343
|
|
|
6163
6344
|
// src/placement.ts
|
|
6164
6345
|
function placeLeagues(visible, pinnedMatchIds) {
|
|
@@ -6221,11 +6402,11 @@ function matchingFixtures(group, query) {
|
|
|
6221
6402
|
}
|
|
6222
6403
|
|
|
6223
6404
|
// src/useStarTap.ts
|
|
6224
|
-
var
|
|
6405
|
+
var import_react44 = require("react");
|
|
6225
6406
|
function useStarTap(starLeague) {
|
|
6226
|
-
const [pendingId, setPendingId] = (0,
|
|
6227
|
-
const pendingRef = (0,
|
|
6228
|
-
const tap = (0,
|
|
6407
|
+
const [pendingId, setPendingId] = (0, import_react44.useState)(null);
|
|
6408
|
+
const pendingRef = (0, import_react44.useRef)(null);
|
|
6409
|
+
const tap = (0, import_react44.useCallback)(async (competitionId, next) => {
|
|
6229
6410
|
if (pendingRef.current !== null) return false;
|
|
6230
6411
|
pendingRef.current = competitionId;
|
|
6231
6412
|
setPendingId(competitionId);
|
|
@@ -6284,7 +6465,7 @@ function LeagueTile({ group, starClickable: starClickable2, disambiguate, onOpen
|
|
|
6284
6465
|
}
|
|
6285
6466
|
|
|
6286
6467
|
// src/components/LeagueDetail.tsx
|
|
6287
|
-
var
|
|
6468
|
+
var import_react45 = require("react");
|
|
6288
6469
|
|
|
6289
6470
|
// src/components/FixtureRow.tsx
|
|
6290
6471
|
var import_jsx_runtime56 = require("react/jsx-runtime");
|
|
@@ -6319,11 +6500,11 @@ function FixtureRow({ match, state, stale, ui, monitor }) {
|
|
|
6319
6500
|
var import_jsx_runtime57 = require("react/jsx-runtime");
|
|
6320
6501
|
var STAR_PATH2 = "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";
|
|
6321
6502
|
function LeagueDetail({ group, position, states, stale, ui, monitor, starTap, onBack, onPrev, onNext }) {
|
|
6322
|
-
const [toast, setToast] = (0,
|
|
6323
|
-
(0,
|
|
6503
|
+
const [toast, setToast] = (0, import_react45.useState)(null);
|
|
6504
|
+
(0, import_react45.useEffect)(() => {
|
|
6324
6505
|
setToast(null);
|
|
6325
6506
|
}, [group.competitionId]);
|
|
6326
|
-
(0,
|
|
6507
|
+
(0, import_react45.useEffect)(() => {
|
|
6327
6508
|
if (toast === null) return;
|
|
6328
6509
|
const id = setTimeout(() => setToast(null), 4e3);
|
|
6329
6510
|
return () => clearTimeout(id);
|
|
@@ -6455,7 +6636,7 @@ function LeagueRowGroup({ group, states, stale, cap, starClickable: starClickabl
|
|
|
6455
6636
|
}
|
|
6456
6637
|
|
|
6457
6638
|
// src/components/games/ui/SearchField.tsx
|
|
6458
|
-
var
|
|
6639
|
+
var import_react46 = require("react");
|
|
6459
6640
|
|
|
6460
6641
|
// src/components/games/ui/icons.tsx
|
|
6461
6642
|
var import_jsx_runtime59 = require("react/jsx-runtime");
|
|
@@ -6494,8 +6675,8 @@ var IconFlame = ({ size = 16 }) => svg(size, /* @__PURE__ */ (0, import_jsx_runt
|
|
|
6494
6675
|
// src/components/games/ui/SearchField.tsx
|
|
6495
6676
|
var import_jsx_runtime60 = require("react/jsx-runtime");
|
|
6496
6677
|
function SearchField({ id, label, labelHidden = false, placeholder, value, onChange, disabled, inputRef, onKeyDown, clearLabel }) {
|
|
6497
|
-
const localRef = (0,
|
|
6498
|
-
const setInputRef = (0,
|
|
6678
|
+
const localRef = (0, import_react46.useRef)(null);
|
|
6679
|
+
const setInputRef = (0, import_react46.useCallback)((node) => {
|
|
6499
6680
|
localRef.current = node;
|
|
6500
6681
|
if (typeof inputRef === "function") inputRef(node);
|
|
6501
6682
|
else if (inputRef) inputRef.current = node;
|
|
@@ -6539,23 +6720,23 @@ function SearchField({ id, label, labelHidden = false, placeholder, value, onCha
|
|
|
6539
6720
|
var import_jsx_runtime61 = require("react/jsx-runtime");
|
|
6540
6721
|
function TodayPanel({ discovery, ui, monitor }) {
|
|
6541
6722
|
const { groups, states, stale, starLeague } = discovery;
|
|
6542
|
-
const searchId = (0,
|
|
6543
|
-
const [query, setQuery] = (0,
|
|
6544
|
-
const [selectedCompetitionId, setSelectedCompetitionId] = (0,
|
|
6545
|
-
const [toast, setToast] = (0,
|
|
6546
|
-
(0,
|
|
6723
|
+
const searchId = (0, import_react47.useId)();
|
|
6724
|
+
const [query, setQuery] = (0, import_react47.useState)("");
|
|
6725
|
+
const [selectedCompetitionId, setSelectedCompetitionId] = (0, import_react47.useState)(null);
|
|
6726
|
+
const [toast, setToast] = (0, import_react47.useState)(null);
|
|
6727
|
+
(0, import_react47.useEffect)(() => {
|
|
6547
6728
|
if (toast === null) return;
|
|
6548
6729
|
const id = setTimeout(() => setToast(null), 4e3);
|
|
6549
6730
|
return () => clearTimeout(id);
|
|
6550
6731
|
}, [toast]);
|
|
6551
6732
|
const visibleGroups = visibleGroupsOf(groups, states);
|
|
6552
|
-
const pinnedMatchIds = (0,
|
|
6733
|
+
const pinnedMatchIds = (0, import_react47.useMemo)(
|
|
6553
6734
|
() => monitor.pins.filter((p) => p.kind === "match").map((p) => p.matchId),
|
|
6554
6735
|
[monitor.pins]
|
|
6555
6736
|
);
|
|
6556
|
-
const placement = (0,
|
|
6737
|
+
const placement = (0, import_react47.useMemo)(() => placeLeagues(visibleGroups, pinnedMatchIds), [visibleGroups, pinnedMatchIds]);
|
|
6557
6738
|
const starTap = useStarTap(starLeague);
|
|
6558
|
-
const gridStarTap = (0,
|
|
6739
|
+
const gridStarTap = (0, import_react47.useMemo)(() => ({
|
|
6559
6740
|
pendingId: starTap.pendingId,
|
|
6560
6741
|
tap: async (competitionId, next) => {
|
|
6561
6742
|
const ok = await starTap.tap(competitionId, next);
|
|
@@ -6589,7 +6770,7 @@ function TodayPanel({ discovery, ui, monitor }) {
|
|
|
6589
6770
|
}
|
|
6590
6771
|
const openIndex = selectedCompetitionId === null ? -1 : placement.order.findIndex((g) => g.competitionId === selectedCompetitionId);
|
|
6591
6772
|
const openGroup = openIndex === -1 ? void 0 : placement.order[openIndex];
|
|
6592
|
-
(0,
|
|
6773
|
+
(0, import_react47.useEffect)(() => {
|
|
6593
6774
|
if (selectedCompetitionId !== null && openGroup === void 0) setSelectedCompetitionId(null);
|
|
6594
6775
|
}, [selectedCompetitionId, openGroup]);
|
|
6595
6776
|
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);
|
|
@@ -6736,7 +6917,7 @@ function TodayPanel({ discovery, ui, monitor }) {
|
|
|
6736
6917
|
}
|
|
6737
6918
|
|
|
6738
6919
|
// src/components/GamesPanel.tsx
|
|
6739
|
-
var
|
|
6920
|
+
var import_react62 = require("react");
|
|
6740
6921
|
|
|
6741
6922
|
// src/components/GamesLoginWall.tsx
|
|
6742
6923
|
var import_jsx_runtime62 = require("react/jsx-runtime");
|
|
@@ -6745,7 +6926,7 @@ function GamesLoginWall({ ui }) {
|
|
|
6745
6926
|
}
|
|
6746
6927
|
|
|
6747
6928
|
// src/components/GamesHub.tsx
|
|
6748
|
-
var
|
|
6929
|
+
var import_react48 = require("react");
|
|
6749
6930
|
|
|
6750
6931
|
// src/components/games/ui/gameMeta.ts
|
|
6751
6932
|
function prettifyGameId(gameId) {
|
|
@@ -6896,8 +7077,8 @@ function pickHeroGame(games) {
|
|
|
6896
7077
|
}
|
|
6897
7078
|
var tileKey = (g) => `${g.gameId}-${g.gameDay}-${g.fixtureId}`;
|
|
6898
7079
|
function GamesHub({ games, myWeeklyRow, weeklyPrize, onOpen, ui }) {
|
|
6899
|
-
const [, setTick] = (0,
|
|
6900
|
-
(0,
|
|
7080
|
+
const [, setTick] = (0, import_react48.useState)(0);
|
|
7081
|
+
(0, import_react48.useEffect)(() => {
|
|
6901
7082
|
const id = setInterval(() => setTick((t) => t + 1), 6e4);
|
|
6902
7083
|
return () => clearInterval(id);
|
|
6903
7084
|
}, []);
|
|
@@ -6957,10 +7138,10 @@ function GamesHub({ games, myWeeklyRow, weeklyPrize, onOpen, ui }) {
|
|
|
6957
7138
|
}
|
|
6958
7139
|
|
|
6959
7140
|
// src/components/GameScreenHost.tsx
|
|
6960
|
-
var
|
|
7141
|
+
var import_react60 = require("react");
|
|
6961
7142
|
|
|
6962
7143
|
// src/useGamePlay.ts
|
|
6963
|
-
var
|
|
7144
|
+
var import_react49 = require("react");
|
|
6964
7145
|
function toSubmitResult(payload) {
|
|
6965
7146
|
return {
|
|
6966
7147
|
// 'pending' means the play is recorded but awaiting resolution (fixture games)
|
|
@@ -6972,17 +7153,17 @@ function toSubmitResult(payload) {
|
|
|
6972
7153
|
};
|
|
6973
7154
|
}
|
|
6974
7155
|
function useGamePlay(conversation, { gameId, gameDay, fixtureId, locale, refresh }) {
|
|
6975
|
-
const [result, setResult] = (0,
|
|
6976
|
-
const [submitting, setSubmitting] = (0,
|
|
6977
|
-
const [rawStatus, setRawStatus] = (0,
|
|
6978
|
-
const inFlightRef = (0,
|
|
6979
|
-
const convRef = (0,
|
|
7156
|
+
const [result, setResult] = (0, import_react49.useState)(null);
|
|
7157
|
+
const [submitting, setSubmitting] = (0, import_react49.useState)(false);
|
|
7158
|
+
const [rawStatus, setRawStatus] = (0, import_react49.useState)(null);
|
|
7159
|
+
const inFlightRef = (0, import_react49.useRef)(false);
|
|
7160
|
+
const convRef = (0, import_react49.useRef)(conversation);
|
|
6980
7161
|
convRef.current = conversation;
|
|
6981
|
-
const optsRef = (0,
|
|
7162
|
+
const optsRef = (0, import_react49.useRef)({ gameId, gameDay, fixtureId, locale, refresh });
|
|
6982
7163
|
optsRef.current = { gameId, gameDay, fixtureId, locale, refresh };
|
|
6983
|
-
const resultRef = (0,
|
|
7164
|
+
const resultRef = (0, import_react49.useRef)(null);
|
|
6984
7165
|
resultRef.current = result;
|
|
6985
|
-
const refetch = (0,
|
|
7166
|
+
const refetch = (0, import_react49.useCallback)(async () => {
|
|
6986
7167
|
const conv = convRef.current;
|
|
6987
7168
|
if (!conv) return;
|
|
6988
7169
|
const opts = optsRef.current;
|
|
@@ -6998,7 +7179,7 @@ function useGamePlay(conversation, { gameId, gameDay, fixtureId, locale, refresh
|
|
|
6998
7179
|
} catch {
|
|
6999
7180
|
}
|
|
7000
7181
|
}, []);
|
|
7001
|
-
const submit = (0,
|
|
7182
|
+
const submit = (0, import_react49.useCallback)(async (answerJson) => {
|
|
7002
7183
|
const conv = convRef.current;
|
|
7003
7184
|
if (!conv || inFlightRef.current) return;
|
|
7004
7185
|
inFlightRef.current = true;
|
|
@@ -7025,14 +7206,14 @@ function useGamePlay(conversation, { gameId, gameDay, fixtureId, locale, refresh
|
|
|
7025
7206
|
setSubmitting(false);
|
|
7026
7207
|
}
|
|
7027
7208
|
}, [refetch]);
|
|
7028
|
-
const hydrate = (0,
|
|
7209
|
+
const hydrate = (0, import_react49.useCallback)(() => {
|
|
7029
7210
|
void refetch();
|
|
7030
7211
|
}, [refetch]);
|
|
7031
7212
|
return { result, submitting, submit, hydrate, rawStatus };
|
|
7032
7213
|
}
|
|
7033
7214
|
|
|
7034
7215
|
// src/components/games/MysteryTigerGame.tsx
|
|
7035
|
-
var
|
|
7216
|
+
var import_react51 = require("react");
|
|
7036
7217
|
|
|
7037
7218
|
// src/components/games/nationFlags.ts
|
|
7038
7219
|
var FLAGS = {
|
|
@@ -7243,7 +7424,7 @@ function isNationCode(flag) {
|
|
|
7243
7424
|
}
|
|
7244
7425
|
|
|
7245
7426
|
// src/components/games/PlayerAvatar.tsx
|
|
7246
|
-
var
|
|
7427
|
+
var import_react50 = require("react");
|
|
7247
7428
|
var import_jsx_runtime67 = require("react/jsx-runtime");
|
|
7248
7429
|
function initialsOf(name) {
|
|
7249
7430
|
const parts = name.trim().split(/\s+/).filter(Boolean);
|
|
@@ -7261,7 +7442,7 @@ function PlayerAvatar({
|
|
|
7261
7442
|
imagePath,
|
|
7262
7443
|
className
|
|
7263
7444
|
}) {
|
|
7264
|
-
const [failed, setFailed] = (0,
|
|
7445
|
+
const [failed, setFailed] = (0, import_react50.useState)(false);
|
|
7265
7446
|
const showImage = Boolean(imagePath) && !isPlaceholderImage(imagePath) && !failed;
|
|
7266
7447
|
return /* @__PURE__ */ (0, import_jsx_runtime67.jsx)("div", { className, "aria-hidden": "true", children: showImage ? /* @__PURE__ */ (0, import_jsx_runtime67.jsx)("img", { src: imagePath, alt: "", loading: "lazy", onError: () => setFailed(true) }) : /* @__PURE__ */ (0, import_jsx_runtime67.jsx)("span", { className: "ss-w-av-initials", children: initialsOf(name) }) });
|
|
7267
7448
|
}
|
|
@@ -7502,8 +7683,8 @@ function MysteryTigerGame({
|
|
|
7502
7683
|
onBack
|
|
7503
7684
|
}) {
|
|
7504
7685
|
const t = ui.games.mysteryTiger;
|
|
7505
|
-
const [query, setQuery] = (0,
|
|
7506
|
-
const inputId = (0,
|
|
7686
|
+
const [query, setQuery] = (0, import_react51.useState)("");
|
|
7687
|
+
const inputId = (0, import_react51.useId)();
|
|
7507
7688
|
const clientState = parseClientState(result?.clientStateJson);
|
|
7508
7689
|
const guessResults = clientState?.guessResults ?? [];
|
|
7509
7690
|
const alreadyGuessedIds = new Set(guessResults.map((g) => g.playerId));
|
|
@@ -7764,13 +7945,13 @@ function HigherOrLowerGame({
|
|
|
7764
7945
|
}
|
|
7765
7946
|
|
|
7766
7947
|
// src/components/games/CareerPathGame.tsx
|
|
7767
|
-
var
|
|
7948
|
+
var import_react53 = require("react");
|
|
7768
7949
|
|
|
7769
7950
|
// src/components/games/ui/CrestShield.tsx
|
|
7770
|
-
var
|
|
7951
|
+
var import_react52 = require("react");
|
|
7771
7952
|
var import_jsx_runtime78 = require("react/jsx-runtime");
|
|
7772
7953
|
function CrestShield({ src, name, size = 28 }) {
|
|
7773
|
-
const [failed, setFailed] = (0,
|
|
7954
|
+
const [failed, setFailed] = (0, import_react52.useState)(false);
|
|
7774
7955
|
if (src && !isPlaceholderImage(src) && !failed) {
|
|
7775
7956
|
return /* @__PURE__ */ (0, import_jsx_runtime78.jsx)("img", { className: "ss-g-crest", src, alt: name, width: size, height: size, loading: "lazy", onError: () => setFailed(true) });
|
|
7776
7957
|
}
|
|
@@ -7802,8 +7983,8 @@ function CareerPathGame({
|
|
|
7802
7983
|
}) {
|
|
7803
7984
|
const s = ui.games.careerPath;
|
|
7804
7985
|
const title = gameTitle({ gameId: "career-path" }, ui.games.titles);
|
|
7805
|
-
const [query, setQuery] = (0,
|
|
7806
|
-
const inputId = (0,
|
|
7986
|
+
const [query, setQuery] = (0, import_react53.useState)("");
|
|
7987
|
+
const inputId = (0, import_react53.useId)();
|
|
7807
7988
|
const clientState = parseClientState3(result?.clientStateJson);
|
|
7808
7989
|
const alreadyGuessedIds = new Set(clientState?.guessResults.map((g) => g.playerId) ?? []);
|
|
7809
7990
|
const isOver = result?.alreadyPlayed === true || clientState?.solved === true || clientState?.failed === true;
|
|
@@ -7909,7 +8090,7 @@ function CareerPathGame({
|
|
|
7909
8090
|
}
|
|
7910
8091
|
|
|
7911
8092
|
// src/components/games/BeatTheGridGame.tsx
|
|
7912
|
-
var
|
|
8093
|
+
var import_react54 = __toESM(require("react"), 1);
|
|
7913
8094
|
|
|
7914
8095
|
// src/components/games/ui/OptionList.tsx
|
|
7915
8096
|
var import_jsx_runtime80 = require("react/jsx-runtime");
|
|
@@ -7998,10 +8179,10 @@ function SearchSheet({
|
|
|
7998
8179
|
ui
|
|
7999
8180
|
}) {
|
|
8000
8181
|
const s = ui.games.beatTheGrid;
|
|
8001
|
-
const [query, setQuery] = (0,
|
|
8002
|
-
const inputId = (0,
|
|
8003
|
-
const inputRef = (0,
|
|
8004
|
-
(0,
|
|
8182
|
+
const [query, setQuery] = (0, import_react54.useState)("");
|
|
8183
|
+
const inputId = (0, import_react54.useId)();
|
|
8184
|
+
const inputRef = (0, import_react54.useRef)(null);
|
|
8185
|
+
(0, import_react54.useEffect)(() => {
|
|
8005
8186
|
inputRef.current?.focus();
|
|
8006
8187
|
}, [row, col]);
|
|
8007
8188
|
const filtered = playerPool.filter(
|
|
@@ -8066,7 +8247,7 @@ function BeatTheGridGame({
|
|
|
8066
8247
|
}) {
|
|
8067
8248
|
const s = ui.games.beatTheGrid;
|
|
8068
8249
|
const title = gameTitle({ gameId: "beat-the-grid" }, ui.games.titles);
|
|
8069
|
-
const [activeCell, setActiveCell] = (0,
|
|
8250
|
+
const [activeCell, setActiveCell] = (0, import_react54.useState)(null);
|
|
8070
8251
|
const clientState = parseClientState4(result?.clientStateJson);
|
|
8071
8252
|
const filledCells = clientState?.cells ?? [];
|
|
8072
8253
|
const isLocked2 = result?.alreadyPlayed === true || clientState?.isComplete === true;
|
|
@@ -8140,7 +8321,7 @@ function BeatTheGridGame({
|
|
|
8140
8321
|
/* @__PURE__ */ (0, import_jsx_runtime81.jsx)("span", { "aria-hidden": "true", children: abbr }),
|
|
8141
8322
|
/* @__PURE__ */ (0, import_jsx_runtime81.jsx)("span", { className: "ss-g-sr", children: rowLabel })
|
|
8142
8323
|
] });
|
|
8143
|
-
return /* @__PURE__ */ (0, import_jsx_runtime81.jsxs)(
|
|
8324
|
+
return /* @__PURE__ */ (0, import_jsx_runtime81.jsxs)(import_react54.default.Fragment, { children: [
|
|
8144
8325
|
/* @__PURE__ */ (0, import_jsx_runtime81.jsx)("div", { className: "ss-g-btg-rowhdr", "data-meta": rowMeta ? "true" : void 0, children: rowHeaderContent }),
|
|
8145
8326
|
cols.map((colLabel, colIdx) => {
|
|
8146
8327
|
const filled = findCellResult(filledCells, rowIdx, colIdx);
|
|
@@ -8221,7 +8402,7 @@ function BeatTheGridGame({
|
|
|
8221
8402
|
}
|
|
8222
8403
|
|
|
8223
8404
|
// src/components/games/GuessTheXiGame.tsx
|
|
8224
|
-
var
|
|
8405
|
+
var import_react55 = require("react");
|
|
8225
8406
|
|
|
8226
8407
|
// src/components/games/ui/PitchSvg.tsx
|
|
8227
8408
|
var import_jsx_runtime82 = require("react/jsx-runtime");
|
|
@@ -8310,8 +8491,8 @@ function GuessTheXiGame({
|
|
|
8310
8491
|
onBack
|
|
8311
8492
|
}) {
|
|
8312
8493
|
const t = ui.games.guessTheXi;
|
|
8313
|
-
const [query, setQuery] = (0,
|
|
8314
|
-
const inputId = (0,
|
|
8494
|
+
const [query, setQuery] = (0, import_react55.useState)("");
|
|
8495
|
+
const inputId = (0, import_react55.useId)();
|
|
8315
8496
|
const clientState = parseClientState5(result?.clientStateJson);
|
|
8316
8497
|
const isOver = result?.alreadyPlayed === true || clientState?.status === "solved" || clientState?.status === "failed";
|
|
8317
8498
|
const solved = clientState?.status === "solved";
|
|
@@ -8453,7 +8634,7 @@ function GuessTheXiGame({
|
|
|
8453
8634
|
}
|
|
8454
8635
|
|
|
8455
8636
|
// src/components/games/DailyQuizGame.tsx
|
|
8456
|
-
var
|
|
8637
|
+
var import_react56 = require("react");
|
|
8457
8638
|
var import_jsx_runtime84 = require("react/jsx-runtime");
|
|
8458
8639
|
function parseClientState6(json) {
|
|
8459
8640
|
if (!json) return null;
|
|
@@ -8494,8 +8675,8 @@ function DailyQuizGame({
|
|
|
8494
8675
|
}) {
|
|
8495
8676
|
const s = ui.games.dailyQuiz;
|
|
8496
8677
|
const title = gameTitle({ gameId: "daily-quiz" }, ui.games.titles);
|
|
8497
|
-
const [selections, setSelections] = (0,
|
|
8498
|
-
const [page, setPage] = (0,
|
|
8678
|
+
const [selections, setSelections] = (0, import_react56.useState)(/* @__PURE__ */ new Map());
|
|
8679
|
+
const [page, setPage] = (0, import_react56.useState)(0);
|
|
8499
8680
|
const clientState = parseClientState6(result?.clientStateJson);
|
|
8500
8681
|
const results = clientState?.results ?? [];
|
|
8501
8682
|
const isRevealed = results.length > 0 || result?.alreadyPlayed === true;
|
|
@@ -8605,7 +8786,7 @@ function DailyQuizGame({
|
|
|
8605
8786
|
}
|
|
8606
8787
|
|
|
8607
8788
|
// src/components/games/MatchdayPredictorGame.tsx
|
|
8608
|
-
var
|
|
8789
|
+
var import_react57 = require("react");
|
|
8609
8790
|
var import_jsx_runtime85 = require("react/jsx-runtime");
|
|
8610
8791
|
var SCORER_SEARCH_THRESHOLD = 9;
|
|
8611
8792
|
function parseClientState7(json) {
|
|
@@ -8701,12 +8882,12 @@ function MatchdayPredictorGame({
|
|
|
8701
8882
|
onBack
|
|
8702
8883
|
}) {
|
|
8703
8884
|
const t = ui.games.predictor;
|
|
8704
|
-
const [homeScore, setHomeScore] = (0,
|
|
8705
|
-
const [awayScore, setAwayScore] = (0,
|
|
8706
|
-
const [firstScorerPlayerId, setFirstScorerPlayerId] = (0,
|
|
8707
|
-
const [lastEdited, setLastEdited] = (0,
|
|
8708
|
-
const [query, setQuery] = (0,
|
|
8709
|
-
const searchId = (0,
|
|
8885
|
+
const [homeScore, setHomeScore] = (0, import_react57.useState)(0);
|
|
8886
|
+
const [awayScore, setAwayScore] = (0, import_react57.useState)(0);
|
|
8887
|
+
const [firstScorerPlayerId, setFirstScorerPlayerId] = (0, import_react57.useState)(null);
|
|
8888
|
+
const [lastEdited, setLastEdited] = (0, import_react57.useState)("home");
|
|
8889
|
+
const [query, setQuery] = (0, import_react57.useState)("");
|
|
8890
|
+
const searchId = (0, import_react57.useId)();
|
|
8710
8891
|
const clientState = parseClientState7(result?.clientStateJson);
|
|
8711
8892
|
const alreadyPlayed = result?.alreadyPlayed === true;
|
|
8712
8893
|
const header = /* @__PURE__ */ (0, import_jsx_runtime85.jsx)(
|
|
@@ -8873,7 +9054,7 @@ function MatchdayPredictorGame({
|
|
|
8873
9054
|
}
|
|
8874
9055
|
|
|
8875
9056
|
// src/components/games/StartingXiGame.tsx
|
|
8876
|
-
var
|
|
9057
|
+
var import_react58 = require("react");
|
|
8877
9058
|
var import_jsx_runtime86 = require("react/jsx-runtime");
|
|
8878
9059
|
var POINTS_PER_STARTER = 8;
|
|
8879
9060
|
var XI_SIZE = 11;
|
|
@@ -8917,10 +9098,10 @@ function StartingXiGame({
|
|
|
8917
9098
|
lockAtUtc
|
|
8918
9099
|
}) {
|
|
8919
9100
|
const t = ui.games.startingXi;
|
|
8920
|
-
const [slotPlayers, setSlotPlayers] = (0,
|
|
8921
|
-
const [active, setActive] = (0,
|
|
8922
|
-
const [query, setQuery] = (0,
|
|
8923
|
-
const searchId = (0,
|
|
9101
|
+
const [slotPlayers, setSlotPlayers] = (0, import_react58.useState)(() => Array(XI_SIZE).fill(null));
|
|
9102
|
+
const [active, setActive] = (0, import_react58.useState)(0);
|
|
9103
|
+
const [query, setQuery] = (0, import_react58.useState)("");
|
|
9104
|
+
const searchId = (0, import_react58.useId)();
|
|
8924
9105
|
const clientState = parseClientState8(result?.clientStateJson);
|
|
8925
9106
|
const alreadyPlayed = result?.alreadyPlayed === true;
|
|
8926
9107
|
const header = /* @__PURE__ */ (0, import_jsx_runtime86.jsx)(
|
|
@@ -9059,7 +9240,7 @@ function StartingXiGame({
|
|
|
9059
9240
|
}
|
|
9060
9241
|
|
|
9061
9242
|
// src/components/games/StatLadderGame.tsx
|
|
9062
|
-
var
|
|
9243
|
+
var import_react59 = require("react");
|
|
9063
9244
|
var import_jsx_runtime87 = require("react/jsx-runtime");
|
|
9064
9245
|
function ladderClue(ladder) {
|
|
9065
9246
|
const mystery = ladder.find((r) => r.rank === 2);
|
|
@@ -9096,9 +9277,9 @@ function StatLadderGame({
|
|
|
9096
9277
|
onBack
|
|
9097
9278
|
}) {
|
|
9098
9279
|
const t = ui.games.statLadder;
|
|
9099
|
-
const [query, setQuery] = (0,
|
|
9100
|
-
const [selectedId, setSelectedId] = (0,
|
|
9101
|
-
const searchId = (0,
|
|
9280
|
+
const [query, setQuery] = (0, import_react59.useState)("");
|
|
9281
|
+
const [selectedId, setSelectedId] = (0, import_react59.useState)(null);
|
|
9282
|
+
const searchId = (0, import_react59.useId)();
|
|
9102
9283
|
const clientState = parseClientState9(result?.clientStateJson);
|
|
9103
9284
|
const revealed = clientState != null;
|
|
9104
9285
|
const header = /* @__PURE__ */ (0, import_jsx_runtime87.jsx)(GameHeader, { title: gameTitle({ gameId: "stat-ladder" }, ui.games.titles), eyebrow: t.eyebrow, onBack, backLabel: ui.back });
|
|
@@ -9304,8 +9485,8 @@ function GameScreenHost({
|
|
|
9304
9485
|
ui
|
|
9305
9486
|
}) {
|
|
9306
9487
|
const { gameId, fixtureId, gameDay = "", lockAtUtc = null } = selected;
|
|
9307
|
-
const [configJson, setConfigJson] = (0,
|
|
9308
|
-
(0,
|
|
9488
|
+
const [configJson, setConfigJson] = (0, import_react60.useState)(null);
|
|
9489
|
+
(0, import_react60.useEffect)(() => {
|
|
9309
9490
|
setConfigJson(null);
|
|
9310
9491
|
if (!conversation) return;
|
|
9311
9492
|
let cancelled = false;
|
|
@@ -9328,12 +9509,12 @@ function GameScreenHost({
|
|
|
9328
9509
|
fixtureId: fixtureId || void 0,
|
|
9329
9510
|
locale: ui.games.lang
|
|
9330
9511
|
});
|
|
9331
|
-
(0,
|
|
9512
|
+
(0, import_react60.useEffect)(() => {
|
|
9332
9513
|
if (conversation) hydrate();
|
|
9333
9514
|
}, [conversation, gameId]);
|
|
9334
|
-
const hydrateRef = (0,
|
|
9515
|
+
const hydrateRef = (0, import_react60.useRef)(hydrate);
|
|
9335
9516
|
hydrateRef.current = hydrate;
|
|
9336
|
-
(0,
|
|
9517
|
+
(0, import_react60.useEffect)(() => {
|
|
9337
9518
|
if (!FIXTURE_GAME_IDS.has(gameId)) return;
|
|
9338
9519
|
if (rawStatus !== "pending") return;
|
|
9339
9520
|
const timerId = setInterval(() => {
|
|
@@ -9446,7 +9627,7 @@ function GameScreenHost({
|
|
|
9446
9627
|
}
|
|
9447
9628
|
|
|
9448
9629
|
// src/components/Leaderboard.tsx
|
|
9449
|
-
var
|
|
9630
|
+
var import_react61 = require("react");
|
|
9450
9631
|
|
|
9451
9632
|
// src/components/LeaderboardRow.tsx
|
|
9452
9633
|
var import_jsx_runtime90 = require("react/jsx-runtime");
|
|
@@ -9531,7 +9712,7 @@ function Leaderboard({
|
|
|
9531
9712
|
ui,
|
|
9532
9713
|
onPlay
|
|
9533
9714
|
}) {
|
|
9534
|
-
const [segment, setSegment] = (0,
|
|
9715
|
+
const [segment, setSegment] = (0, import_react61.useState)("weekly");
|
|
9535
9716
|
const myRow = segment === "weekly" ? data.myWeeklyRow : data.myAllTimeRow;
|
|
9536
9717
|
const offBoard = myRow !== null && myRow !== void 0 && myRow.rank === -1;
|
|
9537
9718
|
const isEmpty = segment === "weekly" ? data.weeklyTop.length === 0 : data.allTimeTop.length === 0;
|
|
@@ -9634,9 +9815,9 @@ function GamesPanel({
|
|
|
9634
9815
|
leaderboardLoading,
|
|
9635
9816
|
refreshHub
|
|
9636
9817
|
}) {
|
|
9637
|
-
const [selected, setSelected] = (0,
|
|
9638
|
-
const [segment, setSegment] = (0,
|
|
9639
|
-
(0,
|
|
9818
|
+
const [selected, setSelected] = (0, import_react62.useState)(null);
|
|
9819
|
+
const [segment, setSegment] = (0, import_react62.useState)("play");
|
|
9820
|
+
(0, import_react62.useEffect)(() => {
|
|
9640
9821
|
ensureGamesFonts();
|
|
9641
9822
|
}, []);
|
|
9642
9823
|
if (!loggedIn) return /* @__PURE__ */ (0, import_jsx_runtime94.jsx)(GamesLoginWall, { ui });
|
|
@@ -9784,8 +9965,7 @@ function Standings({ standings, loading, ui }) {
|
|
|
9784
9965
|
] }, `${gi}-${group.table ?? "none"}`)) });
|
|
9785
9966
|
}
|
|
9786
9967
|
|
|
9787
|
-
// src/components/
|
|
9788
|
-
var import_jsx_runtime97 = require("react/jsx-runtime");
|
|
9968
|
+
// src/components/groupByPosition.ts
|
|
9789
9969
|
function groupByPosition(players) {
|
|
9790
9970
|
const groups = [];
|
|
9791
9971
|
for (const p of players) {
|
|
@@ -9795,26 +9975,181 @@ function groupByPosition(players) {
|
|
|
9795
9975
|
}
|
|
9796
9976
|
return groups;
|
|
9797
9977
|
}
|
|
9798
|
-
|
|
9799
|
-
|
|
9800
|
-
|
|
9801
|
-
|
|
9802
|
-
|
|
9803
|
-
|
|
9804
|
-
|
|
9805
|
-
|
|
9806
|
-
|
|
9807
|
-
|
|
9978
|
+
|
|
9979
|
+
// src/components/labels.ts
|
|
9980
|
+
function positionLabel(ui, name) {
|
|
9981
|
+
switch (name) {
|
|
9982
|
+
case "Goalkeeper":
|
|
9983
|
+
return ui.positionGoalkeeper;
|
|
9984
|
+
case "Defender":
|
|
9985
|
+
return ui.positionDefender;
|
|
9986
|
+
case "Midfielder":
|
|
9987
|
+
return ui.positionMidfielder;
|
|
9988
|
+
case "Attacker":
|
|
9989
|
+
return ui.positionAttacker;
|
|
9990
|
+
default:
|
|
9991
|
+
return name;
|
|
9992
|
+
}
|
|
9993
|
+
}
|
|
9994
|
+
function footLabel(ui, foot) {
|
|
9995
|
+
const v = foot?.trim() ?? "";
|
|
9996
|
+
if (v === "" || v.toUpperCase() === "N/A") return null;
|
|
9997
|
+
switch (v.toLowerCase()) {
|
|
9998
|
+
case "right":
|
|
9999
|
+
return ui.footRight;
|
|
10000
|
+
case "left":
|
|
10001
|
+
return ui.footLeft;
|
|
10002
|
+
case "both":
|
|
10003
|
+
return ui.footBoth;
|
|
10004
|
+
default:
|
|
10005
|
+
return v;
|
|
10006
|
+
}
|
|
9808
10007
|
}
|
|
9809
10008
|
|
|
9810
|
-
// src/components/
|
|
9811
|
-
var
|
|
10009
|
+
// src/components/SquadStats.tsx
|
|
10010
|
+
var import_jsx_runtime97 = require("react/jsx-runtime");
|
|
10011
|
+
function SquadStats({ stats, loading, ui, onSelectPlayer }) {
|
|
10012
|
+
if (stats === null && loading) return /* @__PURE__ */ (0, import_jsx_runtime97.jsx)("div", { className: "ss-w-mon-list" });
|
|
10013
|
+
if (stats === null || stats.length === 0) return /* @__PURE__ */ (0, import_jsx_runtime97.jsx)("div", { className: "ss-w-mon-empty", children: ui.clubSquadStatsEmpty });
|
|
10014
|
+
return /* @__PURE__ */ (0, import_jsx_runtime97.jsxs)("div", { className: "ss-w-mon-list", children: [
|
|
10015
|
+
/* @__PURE__ */ (0, import_jsx_runtime97.jsxs)("div", { className: "ss-w-sq-row ss-w-sq-head", "aria-hidden": "true", children: [
|
|
10016
|
+
/* @__PURE__ */ (0, import_jsx_runtime97.jsx)("span", { className: "ss-w-sq-num" }),
|
|
10017
|
+
/* @__PURE__ */ (0, import_jsx_runtime97.jsx)("span", { className: "ss-w-sq-name" }),
|
|
10018
|
+
/* @__PURE__ */ (0, import_jsx_runtime97.jsx)("span", { className: "ss-w-sq-col", children: ui.statColApps }),
|
|
10019
|
+
/* @__PURE__ */ (0, import_jsx_runtime97.jsx)("span", { className: "ss-w-sq-col", children: ui.statColGoals }),
|
|
10020
|
+
/* @__PURE__ */ (0, import_jsx_runtime97.jsx)("span", { className: "ss-w-sq-col", children: ui.statColAssists }),
|
|
10021
|
+
/* @__PURE__ */ (0, import_jsx_runtime97.jsx)("span", { className: "ss-w-sq-col", children: ui.statColRating })
|
|
10022
|
+
] }),
|
|
10023
|
+
groupByPosition(stats).map((group, gi) => /* @__PURE__ */ (0, import_jsx_runtime97.jsxs)("div", { children: [
|
|
10024
|
+
group.positionName && /* @__PURE__ */ (0, import_jsx_runtime97.jsx)("div", { className: "ss-w-club-eyebrow", children: positionLabel(ui, group.positionName) }),
|
|
10025
|
+
group.items.map((p) => /* @__PURE__ */ (0, import_jsx_runtime97.jsxs)("button", { type: "button", className: "ss-w-sq-row ss-w-sq-tap", onClick: () => onSelectPlayer(p.playerId), children: [
|
|
10026
|
+
/* @__PURE__ */ (0, import_jsx_runtime97.jsx)("span", { className: "ss-w-sq-num", children: p.jerseyNumber ?? "" }),
|
|
10027
|
+
/* @__PURE__ */ (0, import_jsx_runtime97.jsx)("span", { className: "ss-w-sq-name ss-w-sq-name-1", children: p.playerName }),
|
|
10028
|
+
/* @__PURE__ */ (0, import_jsx_runtime97.jsx)("span", { className: "ss-w-sq-col", children: p.appearances }),
|
|
10029
|
+
/* @__PURE__ */ (0, import_jsx_runtime97.jsx)("span", { className: "ss-w-sq-col", children: p.goals }),
|
|
10030
|
+
/* @__PURE__ */ (0, import_jsx_runtime97.jsx)("span", { className: "ss-w-sq-col", children: p.assists }),
|
|
10031
|
+
/* @__PURE__ */ (0, import_jsx_runtime97.jsx)("span", { className: "ss-w-sq-col", children: p.averageRating === null ? "\u2014" : p.averageRating.toFixed(1) })
|
|
10032
|
+
] }, p.playerId))
|
|
10033
|
+
] }, `${gi}-${group.positionName ?? "none"}`))
|
|
10034
|
+
] });
|
|
10035
|
+
}
|
|
10036
|
+
|
|
10037
|
+
// src/components/Squad.tsx
|
|
9812
10038
|
var import_jsx_runtime98 = require("react/jsx-runtime");
|
|
10039
|
+
function Squad({ squad, loading, ui, view, onToggleView, stats, statsLoading, onSelectPlayer }) {
|
|
10040
|
+
const toggle = /* @__PURE__ */ (0, import_jsx_runtime98.jsx)("div", { className: "ss-w-sq-seg", role: "group", children: ["roster", "stats"].map((v) => /* @__PURE__ */ (0, import_jsx_runtime98.jsx)(
|
|
10041
|
+
"button",
|
|
10042
|
+
{
|
|
10043
|
+
type: "button",
|
|
10044
|
+
className: "ss-w-sq-seg-btn",
|
|
10045
|
+
"aria-pressed": view === v,
|
|
10046
|
+
onClick: () => {
|
|
10047
|
+
if (view !== v) onToggleView();
|
|
10048
|
+
},
|
|
10049
|
+
children: v === "roster" ? ui.squadViewRoster : ui.squadViewStats
|
|
10050
|
+
},
|
|
10051
|
+
v
|
|
10052
|
+
)) });
|
|
10053
|
+
if (view === "stats") {
|
|
10054
|
+
return /* @__PURE__ */ (0, import_jsx_runtime98.jsxs)(import_jsx_runtime98.Fragment, { children: [
|
|
10055
|
+
toggle,
|
|
10056
|
+
/* @__PURE__ */ (0, import_jsx_runtime98.jsx)(SquadStats, { stats, loading: statsLoading, ui, onSelectPlayer })
|
|
10057
|
+
] });
|
|
10058
|
+
}
|
|
10059
|
+
if (squad === null && loading) return /* @__PURE__ */ (0, import_jsx_runtime98.jsxs)(import_jsx_runtime98.Fragment, { children: [
|
|
10060
|
+
toggle,
|
|
10061
|
+
/* @__PURE__ */ (0, import_jsx_runtime98.jsx)("div", { className: "ss-w-mon-list" })
|
|
10062
|
+
] });
|
|
10063
|
+
if (squad === null || squad.length === 0) return /* @__PURE__ */ (0, import_jsx_runtime98.jsxs)(import_jsx_runtime98.Fragment, { children: [
|
|
10064
|
+
toggle,
|
|
10065
|
+
/* @__PURE__ */ (0, import_jsx_runtime98.jsx)("div", { className: "ss-w-mon-empty", children: ui.clubSquadEmpty })
|
|
10066
|
+
] });
|
|
10067
|
+
return /* @__PURE__ */ (0, import_jsx_runtime98.jsxs)(import_jsx_runtime98.Fragment, { children: [
|
|
10068
|
+
toggle,
|
|
10069
|
+
/* @__PURE__ */ (0, import_jsx_runtime98.jsx)("div", { className: "ss-w-mon-list", children: groupByPosition(squad).map((group, gi) => /* @__PURE__ */ (0, import_jsx_runtime98.jsxs)("div", { children: [
|
|
10070
|
+
group.positionName && /* @__PURE__ */ (0, import_jsx_runtime98.jsx)("div", { className: "ss-w-club-eyebrow", children: positionLabel(ui, group.positionName) }),
|
|
10071
|
+
group.items.map((p) => /* @__PURE__ */ (0, import_jsx_runtime98.jsxs)("button", { type: "button", className: "ss-w-sq-row ss-w-sq-tap", onClick: () => onSelectPlayer(p.playerId), children: [
|
|
10072
|
+
/* @__PURE__ */ (0, import_jsx_runtime98.jsx)("span", { className: "ss-w-sq-num", children: p.jerseyNumber ?? "" }),
|
|
10073
|
+
/* @__PURE__ */ (0, import_jsx_runtime98.jsx)("span", { className: "ss-w-sq-name", children: p.playerName })
|
|
10074
|
+
] }, p.playerId))
|
|
10075
|
+
] }, `${gi}-${group.positionName ?? "none"}`)) })
|
|
10076
|
+
] });
|
|
10077
|
+
}
|
|
10078
|
+
|
|
10079
|
+
// src/components/PlayerDetail.tsx
|
|
10080
|
+
var import_jsx_runtime99 = require("react/jsx-runtime");
|
|
10081
|
+
var DASH = "\u2014";
|
|
10082
|
+
function ageFrom(dobMs) {
|
|
10083
|
+
if (dobMs === null) return DASH;
|
|
10084
|
+
const dob = new Date(dobMs);
|
|
10085
|
+
const now = /* @__PURE__ */ new Date();
|
|
10086
|
+
let age = now.getUTCFullYear() - dob.getUTCFullYear();
|
|
10087
|
+
const beforeBirthday = now.getUTCMonth() < dob.getUTCMonth() || now.getUTCMonth() === dob.getUTCMonth() && now.getUTCDate() < dob.getUTCDate();
|
|
10088
|
+
if (beforeBirthday) age--;
|
|
10089
|
+
return String(age);
|
|
10090
|
+
}
|
|
10091
|
+
function Field({ label, value }) {
|
|
10092
|
+
return /* @__PURE__ */ (0, import_jsx_runtime99.jsxs)("div", { className: "ss-w-pd-field", children: [
|
|
10093
|
+
/* @__PURE__ */ (0, import_jsx_runtime99.jsx)("span", { className: "ss-w-pd-label", children: label }),
|
|
10094
|
+
/* @__PURE__ */ (0, import_jsx_runtime99.jsx)("span", { className: "ss-w-pd-value", children: value })
|
|
10095
|
+
] });
|
|
10096
|
+
}
|
|
10097
|
+
function PlayerDetail({ detail, loading, ui, seasonName, onClose }) {
|
|
10098
|
+
const back = /* @__PURE__ */ (0, import_jsx_runtime99.jsxs)("button", { type: "button", className: "ss-w-pd-back", onClick: onClose, children: [
|
|
10099
|
+
/* @__PURE__ */ (0, import_jsx_runtime99.jsx)("span", { "aria-hidden": "true", children: "\u2039" }),
|
|
10100
|
+
" ",
|
|
10101
|
+
ui.clubPlayerBack
|
|
10102
|
+
] });
|
|
10103
|
+
if (detail === null) {
|
|
10104
|
+
return loading ? /* @__PURE__ */ (0, import_jsx_runtime99.jsxs)(import_jsx_runtime99.Fragment, { children: [
|
|
10105
|
+
/* @__PURE__ */ (0, import_jsx_runtime99.jsx)("div", { className: "ss-w-pd-bar", children: back }),
|
|
10106
|
+
/* @__PURE__ */ (0, import_jsx_runtime99.jsx)("div", { className: "ss-w-mon-list" })
|
|
10107
|
+
] }) : /* @__PURE__ */ (0, import_jsx_runtime99.jsxs)(import_jsx_runtime99.Fragment, { children: [
|
|
10108
|
+
/* @__PURE__ */ (0, import_jsx_runtime99.jsx)("div", { className: "ss-w-pd-bar", children: back }),
|
|
10109
|
+
/* @__PURE__ */ (0, import_jsx_runtime99.jsx)("div", { className: "ss-w-mon-empty", children: ui.clubPlayerDetailEmpty })
|
|
10110
|
+
] });
|
|
10111
|
+
}
|
|
10112
|
+
const s = detail.seasonStats;
|
|
10113
|
+
const opt = (v, digits) => v === null ? DASH : digits === void 0 ? String(v) : v.toFixed(digits);
|
|
10114
|
+
return /* @__PURE__ */ (0, import_jsx_runtime99.jsxs)(import_jsx_runtime99.Fragment, { children: [
|
|
10115
|
+
/* @__PURE__ */ (0, import_jsx_runtime99.jsx)("div", { className: "ss-w-pd-bar", children: back }),
|
|
10116
|
+
/* @__PURE__ */ (0, import_jsx_runtime99.jsxs)("div", { className: "ss-w-mon-list", children: [
|
|
10117
|
+
/* @__PURE__ */ (0, import_jsx_runtime99.jsxs)("div", { children: [
|
|
10118
|
+
/* @__PURE__ */ (0, import_jsx_runtime99.jsx)("div", { className: "ss-w-pd-name", children: detail.playerName }),
|
|
10119
|
+
/* @__PURE__ */ (0, import_jsx_runtime99.jsx)("div", { className: "ss-w-pd-sub", children: [detail.jerseyNumber === null ? null : `#${detail.jerseyNumber}`, positionLabel(ui, detail.positionName)].filter(Boolean).join(" \xB7 ") })
|
|
10120
|
+
] }),
|
|
10121
|
+
/* @__PURE__ */ (0, import_jsx_runtime99.jsxs)("div", { className: "ss-w-pd-grid ss-w-pd-bio", children: [
|
|
10122
|
+
/* @__PURE__ */ (0, import_jsx_runtime99.jsx)(Field, { label: ui.detailNationality, value: detail.nationality ?? DASH }),
|
|
10123
|
+
/* @__PURE__ */ (0, import_jsx_runtime99.jsx)(Field, { label: ui.detailAge, value: ageFrom(detail.dateOfBirthUnixMs) }),
|
|
10124
|
+
/* @__PURE__ */ (0, import_jsx_runtime99.jsx)(Field, { label: ui.detailHeight, value: detail.heightCm === null ? DASH : `${detail.heightCm} cm` }),
|
|
10125
|
+
/* @__PURE__ */ (0, import_jsx_runtime99.jsx)(Field, { label: ui.detailFoot, value: footLabel(ui, detail.foot) ?? DASH })
|
|
10126
|
+
] }),
|
|
10127
|
+
/* @__PURE__ */ (0, import_jsx_runtime99.jsxs)("div", { children: [
|
|
10128
|
+
seasonName !== null && /* @__PURE__ */ (0, import_jsx_runtime99.jsx)("div", { className: "ss-w-club-eyebrow", children: ui.detailSeason.replace("{season}", seasonName) }),
|
|
10129
|
+
/* @__PURE__ */ (0, import_jsx_runtime99.jsxs)("div", { className: "ss-w-pd-grid", children: [
|
|
10130
|
+
/* @__PURE__ */ (0, import_jsx_runtime99.jsx)(Field, { label: ui.statColApps, value: String(s.appearances) }),
|
|
10131
|
+
/* @__PURE__ */ (0, import_jsx_runtime99.jsx)(Field, { label: ui.statColMinutes, value: String(s.minutesPlayed) }),
|
|
10132
|
+
/* @__PURE__ */ (0, import_jsx_runtime99.jsx)(Field, { label: ui.statColGoals, value: String(s.goals) }),
|
|
10133
|
+
/* @__PURE__ */ (0, import_jsx_runtime99.jsx)(Field, { label: ui.statColAssists, value: String(s.assists) }),
|
|
10134
|
+
/* @__PURE__ */ (0, import_jsx_runtime99.jsx)(Field, { label: ui.statColYellow, value: String(s.yellowCards) }),
|
|
10135
|
+
/* @__PURE__ */ (0, import_jsx_runtime99.jsx)(Field, { label: ui.statColRed, value: String(s.redCards) }),
|
|
10136
|
+
/* @__PURE__ */ (0, import_jsx_runtime99.jsx)(Field, { label: ui.statColRating, value: opt(s.averageRating, 1) }),
|
|
10137
|
+
/* @__PURE__ */ (0, import_jsx_runtime99.jsx)(Field, { label: ui.statColXg, value: opt(s.expectedGoals, 2) }),
|
|
10138
|
+
/* @__PURE__ */ (0, import_jsx_runtime99.jsx)(Field, { label: ui.statColShots, value: opt(s.totalShots) })
|
|
10139
|
+
] })
|
|
10140
|
+
] })
|
|
10141
|
+
] })
|
|
10142
|
+
] });
|
|
10143
|
+
}
|
|
10144
|
+
|
|
10145
|
+
// src/components/PresetSpeedDial.tsx
|
|
10146
|
+
var import_react63 = require("react");
|
|
10147
|
+
var import_jsx_runtime100 = require("react/jsx-runtime");
|
|
9813
10148
|
function PresetSpeedDial({ expanded, showDot, strings, onToggle, onOpen, rootRef, buttonRef }) {
|
|
9814
|
-
const pillsId = (0,
|
|
10149
|
+
const pillsId = (0, import_react63.useId)();
|
|
9815
10150
|
const tabIndex = expanded ? 0 : -1;
|
|
9816
|
-
return /* @__PURE__ */ (0,
|
|
9817
|
-
/* @__PURE__ */ (0,
|
|
10151
|
+
return /* @__PURE__ */ (0, import_jsx_runtime100.jsxs)("div", { ref: rootRef, className: "ss-w-dial", children: [
|
|
10152
|
+
/* @__PURE__ */ (0, import_jsx_runtime100.jsxs)(
|
|
9818
10153
|
"button",
|
|
9819
10154
|
{
|
|
9820
10155
|
ref: buttonRef,
|
|
@@ -9825,36 +10160,36 @@ function PresetSpeedDial({ expanded, showDot, strings, onToggle, onOpen, rootRef
|
|
|
9825
10160
|
"aria-label": strings.dialName,
|
|
9826
10161
|
onClick: onToggle,
|
|
9827
10162
|
children: [
|
|
9828
|
-
/* @__PURE__ */ (0,
|
|
9829
|
-
/* @__PURE__ */ (0,
|
|
9830
|
-
showDot && !expanded ? /* @__PURE__ */ (0,
|
|
10163
|
+
/* @__PURE__ */ (0, import_jsx_runtime100.jsx)("span", { className: "ss-w-dial-icon ss-w-dial-icon--open", children: /* @__PURE__ */ (0, import_jsx_runtime100.jsx)(SlidersIcon, {}) }),
|
|
10164
|
+
/* @__PURE__ */ (0, import_jsx_runtime100.jsx)("span", { className: "ss-w-dial-icon ss-w-dial-icon--close", children: /* @__PURE__ */ (0, import_jsx_runtime100.jsx)(CloseIcon, {}) }),
|
|
10165
|
+
showDot && !expanded ? /* @__PURE__ */ (0, import_jsx_runtime100.jsx)("span", { className: "ss-w-dial-dot", "aria-hidden": "true" }) : null
|
|
9831
10166
|
]
|
|
9832
10167
|
}
|
|
9833
10168
|
),
|
|
9834
|
-
/* @__PURE__ */ (0,
|
|
9835
|
-
/* @__PURE__ */ (0,
|
|
9836
|
-
/* @__PURE__ */ (0,
|
|
9837
|
-
/* @__PURE__ */ (0,
|
|
10169
|
+
/* @__PURE__ */ (0, import_jsx_runtime100.jsxs)("div", { id: pillsId, className: "ss-w-dial-pills", "data-open": expanded ? "" : void 0, children: [
|
|
10170
|
+
/* @__PURE__ */ (0, import_jsx_runtime100.jsxs)("button", { type: "button", className: "ss-w-dial-pill", tabIndex, onClick: () => onOpen("numbers"), children: [
|
|
10171
|
+
/* @__PURE__ */ (0, import_jsx_runtime100.jsx)(SlidersIcon, {}),
|
|
10172
|
+
/* @__PURE__ */ (0, import_jsx_runtime100.jsx)("span", { className: "ss-w-dial-pill-label", children: strings.setNumbers })
|
|
9838
10173
|
] }),
|
|
9839
|
-
/* @__PURE__ */ (0,
|
|
9840
|
-
/* @__PURE__ */ (0,
|
|
9841
|
-
/* @__PURE__ */ (0,
|
|
10174
|
+
/* @__PURE__ */ (0, import_jsx_runtime100.jsxs)("button", { type: "button", className: "ss-w-dial-pill", tabIndex, onClick: () => onOpen("combo"), children: [
|
|
10175
|
+
/* @__PURE__ */ (0, import_jsx_runtime100.jsx)(ComboIcon, {}),
|
|
10176
|
+
/* @__PURE__ */ (0, import_jsx_runtime100.jsx)("span", { className: "ss-w-dial-pill-label", children: strings.buildCombo })
|
|
9842
10177
|
] })
|
|
9843
10178
|
] })
|
|
9844
10179
|
] });
|
|
9845
10180
|
}
|
|
9846
10181
|
|
|
9847
10182
|
// src/components/PresetTools.tsx
|
|
9848
|
-
var
|
|
9849
|
-
var
|
|
10183
|
+
var import_react64 = require("react");
|
|
10184
|
+
var import_jsx_runtime101 = require("react/jsx-runtime");
|
|
9850
10185
|
var FOCUSABLE = 'button:not([disabled]), [href], input:not([disabled]), textarea:not([disabled]), [tabindex]:not([tabindex="-1"])';
|
|
9851
10186
|
function PresetToolModal({ title, closeLabel, onClose, children, footer }) {
|
|
9852
|
-
const dialogRef = (0,
|
|
9853
|
-
const titleId = (0,
|
|
9854
|
-
(0,
|
|
10187
|
+
const dialogRef = (0, import_react64.useRef)(null);
|
|
10188
|
+
const titleId = (0, import_react64.useId)();
|
|
10189
|
+
(0, import_react64.useEffect)(() => {
|
|
9855
10190
|
dialogRef.current?.focus();
|
|
9856
10191
|
}, []);
|
|
9857
|
-
(0,
|
|
10192
|
+
(0, import_react64.useEffect)(() => {
|
|
9858
10193
|
const onKey = (e) => {
|
|
9859
10194
|
if (e.key !== "Escape") return;
|
|
9860
10195
|
e.stopPropagation();
|
|
@@ -9884,79 +10219,79 @@ function PresetToolModal({ title, closeLabel, onClose, children, footer }) {
|
|
|
9884
10219
|
first.focus();
|
|
9885
10220
|
}
|
|
9886
10221
|
};
|
|
9887
|
-
return /* @__PURE__ */ (0,
|
|
9888
|
-
/* @__PURE__ */ (0,
|
|
9889
|
-
/* @__PURE__ */ (0,
|
|
9890
|
-
/* @__PURE__ */ (0,
|
|
10222
|
+
return /* @__PURE__ */ (0, import_jsx_runtime101.jsx)("div", { className: "ss-w-tool-backdrop", children: /* @__PURE__ */ (0, import_jsx_runtime101.jsxs)("div", { ref: dialogRef, className: "ss-w-tool", role: "dialog", "aria-modal": "true", "aria-labelledby": titleId, tabIndex: -1, onKeyDown: trapTab, children: [
|
|
10223
|
+
/* @__PURE__ */ (0, import_jsx_runtime101.jsxs)("div", { className: "ss-w-tool-head", children: [
|
|
10224
|
+
/* @__PURE__ */ (0, import_jsx_runtime101.jsx)("h2", { id: titleId, className: "ss-w-tool-title", children: title }),
|
|
10225
|
+
/* @__PURE__ */ (0, import_jsx_runtime101.jsx)("button", { type: "button", className: "ss-w-tool-close", "aria-label": closeLabel, onClick: onClose, children: /* @__PURE__ */ (0, import_jsx_runtime101.jsx)(CloseIcon, {}) })
|
|
9891
10226
|
] }),
|
|
9892
|
-
/* @__PURE__ */ (0,
|
|
9893
|
-
footer ? /* @__PURE__ */ (0,
|
|
10227
|
+
/* @__PURE__ */ (0, import_jsx_runtime101.jsx)("div", { className: "ss-w-tool-body", children }),
|
|
10228
|
+
footer ? /* @__PURE__ */ (0, import_jsx_runtime101.jsx)("div", { className: "ss-w-tool-foot", children: footer }) : null
|
|
9894
10229
|
] }) });
|
|
9895
10230
|
}
|
|
9896
10231
|
function fillTemplate(template, slots) {
|
|
9897
10232
|
return template.split(/(\{[a-z]+\})/).filter((part) => part !== "").map((part, i) => {
|
|
9898
10233
|
const key = /^\{([a-z]+)\}$/.exec(part)?.[1];
|
|
9899
|
-
return /* @__PURE__ */ (0,
|
|
10234
|
+
return /* @__PURE__ */ (0, import_jsx_runtime101.jsx)(import_react64.Fragment, { children: key !== void 0 && key in slots ? slots[key] : part }, i);
|
|
9900
10235
|
});
|
|
9901
10236
|
}
|
|
9902
10237
|
function NumberSelect({ current, choices: choices2, label, notToday, lockEmpty = true, onChoose }) {
|
|
9903
10238
|
const selected = Math.max(0, choices2.findIndex((c) => c.text === current));
|
|
9904
|
-
return /* @__PURE__ */ (0,
|
|
9905
|
-
/* @__PURE__ */ (0,
|
|
9906
|
-
/* @__PURE__ */ (0,
|
|
10239
|
+
return /* @__PURE__ */ (0, import_jsx_runtime101.jsxs)("span", { className: "ss-w-tool-num", children: [
|
|
10240
|
+
/* @__PURE__ */ (0, import_jsx_runtime101.jsx)("span", { className: "ss-w-tool-num-size", "aria-hidden": "true", children: current }),
|
|
10241
|
+
/* @__PURE__ */ (0, import_jsx_runtime101.jsx)("select", { className: "ss-w-tool-num-select", "aria-label": label, value: String(selected), onChange: (e) => {
|
|
9907
10242
|
const c = choices2[Number(e.target.value)];
|
|
9908
10243
|
if (c) onChoose(c.value);
|
|
9909
|
-
}, children: choices2.map((c, i) => /* @__PURE__ */ (0,
|
|
10244
|
+
}, children: choices2.map((c, i) => /* @__PURE__ */ (0, import_jsx_runtime101.jsx)("option", { value: String(i), disabled: lockEmpty && !c.available && i !== selected, children: c.available ? c.text : `${c.text}${notToday}` }, i)) })
|
|
9910
10245
|
] });
|
|
9911
10246
|
}
|
|
9912
10247
|
function ChoiceSelect({ currentIdx, sizeLabels, optionLabels, label, onChoose }) {
|
|
9913
10248
|
const sizeText = sizeLabels[currentIdx] ?? "";
|
|
9914
|
-
return /* @__PURE__ */ (0,
|
|
9915
|
-
/* @__PURE__ */ (0,
|
|
9916
|
-
/* @__PURE__ */ (0,
|
|
10249
|
+
return /* @__PURE__ */ (0, import_jsx_runtime101.jsxs)("span", { className: "ss-w-tool-num", children: [
|
|
10250
|
+
/* @__PURE__ */ (0, import_jsx_runtime101.jsx)("span", { className: "ss-w-tool-num-size", "aria-hidden": "true", children: sizeText }),
|
|
10251
|
+
/* @__PURE__ */ (0, import_jsx_runtime101.jsx)("select", { className: "ss-w-tool-num-select", "aria-label": label, value: String(currentIdx), onChange: (e) => onChoose(Number(e.target.value)), children: optionLabels.map((opt, i) => /* @__PURE__ */ (0, import_jsx_runtime101.jsx)("option", { value: String(i), children: opt }, i)) })
|
|
9917
10252
|
] });
|
|
9918
10253
|
}
|
|
9919
10254
|
function SendButton({ label, display, disabled, onClick }) {
|
|
9920
|
-
return /* @__PURE__ */ (0,
|
|
10255
|
+
return /* @__PURE__ */ (0, import_jsx_runtime101.jsx)("button", { type: "button", className: "ss-w-tool-send", "aria-label": `${label}: ${display}`, disabled, onClick, children: label });
|
|
9921
10256
|
}
|
|
9922
10257
|
function PickList({ picks, formatKickoff }) {
|
|
9923
|
-
return /* @__PURE__ */ (0,
|
|
9924
|
-
/* @__PURE__ */ (0,
|
|
10258
|
+
return /* @__PURE__ */ (0, import_jsx_runtime101.jsx)("ul", { className: "ss-w-tool-picks", role: "list", children: picks.map((p) => /* @__PURE__ */ (0, import_jsx_runtime101.jsxs)("li", { className: "ss-w-tool-pick", children: [
|
|
10259
|
+
/* @__PURE__ */ (0, import_jsx_runtime101.jsxs)("span", { className: "ss-w-tool-pick-match", children: [
|
|
9925
10260
|
p.homeTeamName,
|
|
9926
10261
|
" \u2013 ",
|
|
9927
10262
|
p.awayTeamName
|
|
9928
10263
|
] }),
|
|
9929
|
-
/* @__PURE__ */ (0,
|
|
10264
|
+
/* @__PURE__ */ (0, import_jsx_runtime101.jsxs)("span", { className: "ss-w-tool-pick-sel", children: [
|
|
9930
10265
|
p.marketLabel,
|
|
9931
10266
|
": ",
|
|
9932
10267
|
p.selectionLabel,
|
|
9933
10268
|
p.line ? ` ${p.line}` : ""
|
|
9934
10269
|
] }),
|
|
9935
|
-
/* @__PURE__ */ (0,
|
|
9936
|
-
/* @__PURE__ */ (0,
|
|
10270
|
+
/* @__PURE__ */ (0, import_jsx_runtime101.jsx)("span", { className: "ss-w-tool-pick-kick", children: formatKickoff(p.kickoffUtc) }),
|
|
10271
|
+
/* @__PURE__ */ (0, import_jsx_runtime101.jsx)("span", { className: "ss-w-tool-pick-price", children: p.price.toFixed(2) })
|
|
9937
10272
|
] }, p.matchOddsId)) });
|
|
9938
10273
|
}
|
|
9939
10274
|
function ComboPreview({ cell, formatKickoff }) {
|
|
9940
|
-
return /* @__PURE__ */ (0,
|
|
9941
|
-
/* @__PURE__ */ (0,
|
|
9942
|
-
/* @__PURE__ */ (0,
|
|
10275
|
+
return /* @__PURE__ */ (0, import_jsx_runtime101.jsxs)(import_jsx_runtime101.Fragment, { children: [
|
|
10276
|
+
/* @__PURE__ */ (0, import_jsx_runtime101.jsx)(PickList, { picks: cell.combo.legs, formatKickoff }),
|
|
10277
|
+
/* @__PURE__ */ (0, import_jsx_runtime101.jsx)("div", { className: "ss-w-tool-math", children: cell.combo.multiplication })
|
|
9943
10278
|
] });
|
|
9944
10279
|
}
|
|
9945
10280
|
function Unavailable({ text }) {
|
|
9946
|
-
return /* @__PURE__ */ (0,
|
|
10281
|
+
return /* @__PURE__ */ (0, import_jsx_runtime101.jsx)("p", { className: "ss-w-tool-unavailable", children: text });
|
|
9947
10282
|
}
|
|
9948
10283
|
function AskRow({ icon, ask, ready, send }) {
|
|
9949
|
-
return /* @__PURE__ */ (0,
|
|
9950
|
-
/* @__PURE__ */ (0,
|
|
9951
|
-
/* @__PURE__ */ (0,
|
|
9952
|
-
/* @__PURE__ */ (0,
|
|
9953
|
-
ready ? /* @__PURE__ */ (0,
|
|
10284
|
+
return /* @__PURE__ */ (0, import_jsx_runtime101.jsxs)("section", { className: "ss-w-tool-row ss-w-tool-row--ask", children: [
|
|
10285
|
+
/* @__PURE__ */ (0, import_jsx_runtime101.jsx)("span", { className: "ss-w-tool-icon", "aria-hidden": "true", children: icon }),
|
|
10286
|
+
/* @__PURE__ */ (0, import_jsx_runtime101.jsxs)("div", { className: "ss-w-tool-main", children: [
|
|
10287
|
+
/* @__PURE__ */ (0, import_jsx_runtime101.jsx)("p", { className: "ss-w-tool-ask", children: ask }),
|
|
10288
|
+
ready ? /* @__PURE__ */ (0, import_jsx_runtime101.jsx)("span", { className: "ss-w-tool-ready", children: ready }) : null
|
|
9954
10289
|
] }),
|
|
9955
10290
|
send
|
|
9956
10291
|
] });
|
|
9957
10292
|
}
|
|
9958
10293
|
function RoundSend({ label, display, disabled, onClick }) {
|
|
9959
|
-
return /* @__PURE__ */ (0,
|
|
10294
|
+
return /* @__PURE__ */ (0, import_jsx_runtime101.jsx)("button", { type: "button", className: "ss-w-tool-go", "aria-label": `${label}: ${display}`, disabled, onClick, children: /* @__PURE__ */ (0, import_jsx_runtime101.jsx)(SendIcon, {}) });
|
|
9960
10295
|
}
|
|
9961
10296
|
var BIG_COMBO = { total: 50, legs: 6 };
|
|
9962
10297
|
function SetNumbersTool({ grid, strings, streaming, onSend, onClose }) {
|
|
@@ -9965,15 +10300,15 @@ function SetNumbersTool({ grid, strings, streaming, onSend, onClose }) {
|
|
|
9965
10300
|
const totals = comboTotals(grid);
|
|
9966
10301
|
const legChoices = comboLegChoices(grid);
|
|
9967
10302
|
const count = FIXED_SINGLES_COUNT;
|
|
9968
|
-
const [maxPrice, setMaxPrice] = (0,
|
|
9969
|
-
const [minPrice, setMinPrice] = (0,
|
|
9970
|
-
const [start] = (0,
|
|
9971
|
-
const [total, setTotal] = (0,
|
|
9972
|
-
const [legs, setLegs] = (0,
|
|
9973
|
-
const [bigStart] = (0,
|
|
9974
|
-
const [bigTotal, setBigTotal] = (0,
|
|
9975
|
-
const [bigLegs, setBigLegs] = (0,
|
|
9976
|
-
const [announcement, setAnnouncement] = (0,
|
|
10303
|
+
const [maxPrice, setMaxPrice] = (0, import_react64.useState)(() => startSingles(grid.singles, limits, START.maxPrice, count));
|
|
10304
|
+
const [minPrice, setMinPrice] = (0, import_react64.useState)(() => startSingles(grid.singlesFrom, floors, START.minPrice, count));
|
|
10305
|
+
const [start] = (0, import_react64.useState)(() => startCombo(grid, totals, legChoices, START.comboTotal, START.comboLegs));
|
|
10306
|
+
const [total, setTotal] = (0, import_react64.useState)(start.total);
|
|
10307
|
+
const [legs, setLegs] = (0, import_react64.useState)(start.legs);
|
|
10308
|
+
const [bigStart] = (0, import_react64.useState)(() => startCombo(grid, totals, legChoices, BIG_COMBO.total, BIG_COMBO.legs));
|
|
10309
|
+
const [bigTotal, setBigTotal] = (0, import_react64.useState)(bigStart.total);
|
|
10310
|
+
const [bigLegs, setBigLegs] = (0, import_react64.useState)(bigStart.legs);
|
|
10311
|
+
const [announcement, setAnnouncement] = (0, import_react64.useState)("");
|
|
9977
10312
|
const maxCell = findSingles(grid.singles, maxPrice, count);
|
|
9978
10313
|
const minCell = findSingles(grid.singlesFrom, minPrice, count);
|
|
9979
10314
|
const comboCell = findCombo(grid, total, legs);
|
|
@@ -10017,95 +10352,95 @@ function SetNumbersTool({ grid, strings, streaming, onSend, onClose }) {
|
|
|
10017
10352
|
const totalChoices = totals.map((v) => ({ value: v, text: v.toFixed(1), available: legChoices.some((n) => !!findCombo(grid, v, n)) }));
|
|
10018
10353
|
const legChoicesFor = (t) => legChoices.map((n) => ({ value: n, text: String(n), available: !!findCombo(grid, t, n) }));
|
|
10019
10354
|
const markets = grid.markets ?? [];
|
|
10020
|
-
const [marketIdx, setMarketIdx] = (0,
|
|
10355
|
+
const [marketIdx, setMarketIdx] = (0, import_react64.useState)(0);
|
|
10021
10356
|
const marketCell = markets[marketIdx] ?? null;
|
|
10022
10357
|
const marketLabels = markets.map((c) => strings.marketShort(c.marketDeveloperName, c.marketLabel, c.selectionLabel ?? null));
|
|
10023
10358
|
const singlesReady = (cell) => cell ? strings.readyCount(cell.picks.length) : strings.unavailable;
|
|
10024
10359
|
const comboReady = (cell) => cell ? strings.readyAt(cell.combo.total) : strings.unavailable;
|
|
10025
|
-
return /* @__PURE__ */ (0,
|
|
10026
|
-
/* @__PURE__ */ (0,
|
|
10360
|
+
return /* @__PURE__ */ (0, import_jsx_runtime101.jsxs)(PresetToolModal, { title: strings.setNumbers, closeLabel: strings.close, onClose, children: [
|
|
10361
|
+
/* @__PURE__ */ (0, import_jsx_runtime101.jsx)(
|
|
10027
10362
|
AskRow,
|
|
10028
10363
|
{
|
|
10029
10364
|
icon: "\u{1F3AF}",
|
|
10030
10365
|
ask: fillTemplate(strings.maxPriceRow, {
|
|
10031
10366
|
count: String(count),
|
|
10032
|
-
price: /* @__PURE__ */ (0,
|
|
10367
|
+
price: /* @__PURE__ */ (0, import_jsx_runtime101.jsx)(NumberSelect, { current: maxPrice.toFixed(2), choices: maxChoices, label: strings.maxPriceName, notToday: strings.notToday, onChoose: chooseMax })
|
|
10033
10368
|
}),
|
|
10034
10369
|
ready: singlesReady(maxCell),
|
|
10035
|
-
send: /* @__PURE__ */ (0,
|
|
10370
|
+
send: /* @__PURE__ */ (0, import_jsx_runtime101.jsx)(RoundSend, { label: strings.send, display: strings.maxPriceDisplay(count, maxPrice), disabled: !maxCell || streaming, onClick: () => {
|
|
10036
10371
|
if (maxCell) onSend(maxPriceAsk(maxCell, strings));
|
|
10037
10372
|
} })
|
|
10038
10373
|
}
|
|
10039
10374
|
),
|
|
10040
|
-
/* @__PURE__ */ (0,
|
|
10375
|
+
/* @__PURE__ */ (0, import_jsx_runtime101.jsx)(
|
|
10041
10376
|
AskRow,
|
|
10042
10377
|
{
|
|
10043
10378
|
icon: "\u{1F4C8}",
|
|
10044
10379
|
ask: fillTemplate(strings.minPriceRow, {
|
|
10045
10380
|
count: String(count),
|
|
10046
|
-
price: /* @__PURE__ */ (0,
|
|
10381
|
+
price: /* @__PURE__ */ (0, import_jsx_runtime101.jsx)(NumberSelect, { current: minPrice.toFixed(2), choices: minChoices, label: strings.minPriceName, notToday: strings.notToday, onChoose: chooseMin })
|
|
10047
10382
|
}),
|
|
10048
10383
|
ready: singlesReady(minCell),
|
|
10049
|
-
send: /* @__PURE__ */ (0,
|
|
10384
|
+
send: /* @__PURE__ */ (0, import_jsx_runtime101.jsx)(RoundSend, { label: strings.send, display: strings.minPriceDisplay(count, minPrice), disabled: !minCell || streaming, onClick: () => {
|
|
10050
10385
|
if (minCell) onSend(minPriceAsk(minCell, strings));
|
|
10051
10386
|
} })
|
|
10052
10387
|
}
|
|
10053
10388
|
),
|
|
10054
|
-
/* @__PURE__ */ (0,
|
|
10389
|
+
/* @__PURE__ */ (0, import_jsx_runtime101.jsx)(
|
|
10055
10390
|
AskRow,
|
|
10056
10391
|
{
|
|
10057
10392
|
icon: "\u2728",
|
|
10058
10393
|
ask: fillTemplate(strings.comboRow, {
|
|
10059
|
-
legs: /* @__PURE__ */ (0,
|
|
10060
|
-
total: /* @__PURE__ */ (0,
|
|
10394
|
+
legs: /* @__PURE__ */ (0, import_jsx_runtime101.jsx)(NumberSelect, { current: String(legs), choices: legChoicesFor(total), label: strings.matchesLabel, notToday: strings.notToday, lockEmpty: false, onChoose: chooseLegs }),
|
|
10395
|
+
total: /* @__PURE__ */ (0, import_jsx_runtime101.jsx)(NumberSelect, { current: total.toFixed(1), choices: totalChoices, label: strings.totalLabel, notToday: strings.notToday, onChoose: chooseTotal })
|
|
10061
10396
|
}),
|
|
10062
10397
|
ready: comboReady(comboCell),
|
|
10063
|
-
send: /* @__PURE__ */ (0,
|
|
10398
|
+
send: /* @__PURE__ */ (0, import_jsx_runtime101.jsx)(RoundSend, { label: strings.send, display: strings.comboDisplay(legs, total), disabled: !comboCell || streaming, onClick: () => {
|
|
10064
10399
|
if (comboCell) onSend(comboAsk(comboCell, strings));
|
|
10065
10400
|
} })
|
|
10066
10401
|
}
|
|
10067
10402
|
),
|
|
10068
|
-
/* @__PURE__ */ (0,
|
|
10403
|
+
/* @__PURE__ */ (0, import_jsx_runtime101.jsx)(
|
|
10069
10404
|
AskRow,
|
|
10070
10405
|
{
|
|
10071
10406
|
icon: "\u{1F3C6}",
|
|
10072
10407
|
ask: fillTemplate(strings.bigComboRow, {
|
|
10073
|
-
legs: /* @__PURE__ */ (0,
|
|
10074
|
-
total: /* @__PURE__ */ (0,
|
|
10408
|
+
legs: /* @__PURE__ */ (0, import_jsx_runtime101.jsx)(NumberSelect, { current: String(bigLegs), choices: legChoicesFor(bigTotal), label: strings.matchesLabel, notToday: strings.notToday, lockEmpty: false, onChoose: chooseBigLegs }),
|
|
10409
|
+
total: /* @__PURE__ */ (0, import_jsx_runtime101.jsx)(NumberSelect, { current: bigTotal.toFixed(1), choices: totalChoices, label: strings.totalLabel, notToday: strings.notToday, onChoose: chooseBigTotal })
|
|
10075
10410
|
}),
|
|
10076
10411
|
ready: comboReady(bigCell),
|
|
10077
|
-
send: /* @__PURE__ */ (0,
|
|
10412
|
+
send: /* @__PURE__ */ (0, import_jsx_runtime101.jsx)(RoundSend, { label: strings.send, display: strings.comboDisplay(bigLegs, bigTotal), disabled: !bigCell || streaming, onClick: () => {
|
|
10078
10413
|
if (bigCell) onSend(comboAsk(bigCell, strings));
|
|
10079
10414
|
} })
|
|
10080
10415
|
}
|
|
10081
10416
|
),
|
|
10082
|
-
markets.length > 0 && /* @__PURE__ */ (0,
|
|
10417
|
+
markets.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime101.jsx)(
|
|
10083
10418
|
AskRow,
|
|
10084
10419
|
{
|
|
10085
10420
|
icon: "\u26BD",
|
|
10086
10421
|
ask: fillTemplate(strings.marketRow, {
|
|
10087
|
-
market: /* @__PURE__ */ (0,
|
|
10422
|
+
market: /* @__PURE__ */ (0, import_jsx_runtime101.jsx)(ChoiceSelect, { currentIdx: marketIdx, sizeLabels: marketLabels, optionLabels: marketLabels, label: strings.marketName, onChoose: chooseMarket })
|
|
10088
10423
|
}),
|
|
10089
10424
|
ready: marketCell ? strings.readyCount(marketCell.count) : null,
|
|
10090
|
-
send: /* @__PURE__ */ (0,
|
|
10425
|
+
send: /* @__PURE__ */ (0, import_jsx_runtime101.jsx)(RoundSend, { label: strings.send, display: marketCell ? marketDisplay(marketCell, strings) : "", disabled: !marketCell || streaming, onClick: () => {
|
|
10091
10426
|
if (marketCell) onSend(marketAsk(marketCell, strings));
|
|
10092
10427
|
} })
|
|
10093
10428
|
}
|
|
10094
10429
|
),
|
|
10095
|
-
/* @__PURE__ */ (0,
|
|
10430
|
+
/* @__PURE__ */ (0, import_jsx_runtime101.jsx)("p", { className: "ss-w-vh", "aria-live": "polite", children: announcement })
|
|
10096
10431
|
] });
|
|
10097
10432
|
}
|
|
10098
10433
|
function BuildComboTool({ grid, strings, streaming, formatKickoff, initialTotal, initialLegs, onSend, onClose }) {
|
|
10099
10434
|
const totals = comboTotals(grid);
|
|
10100
10435
|
const legChoices = comboLegChoices(grid);
|
|
10101
|
-
const [start] = (0,
|
|
10102
|
-
const [total, setTotal] = (0,
|
|
10103
|
-
const [legs, setLegs] = (0,
|
|
10436
|
+
const [start] = (0, import_react64.useState)(() => initialTotal === void 0 ? startCombo(grid, totals, legChoices, START.comboTotal, START.comboLegs) : null);
|
|
10437
|
+
const [total, setTotal] = (0, import_react64.useState)(() => initialTotal !== void 0 ? nearest(totals, initialTotal) : start.total);
|
|
10438
|
+
const [legs, setLegs] = (0, import_react64.useState)(() => {
|
|
10104
10439
|
if (initialTotal === void 0) return initialLegs !== void 0 ? clampLegs(legChoices, initialLegs) : start.legs;
|
|
10105
10440
|
const from = initialLegs !== void 0 ? clampLegs(legChoices, initialLegs) : startValue(legChoices, START.comboLegs);
|
|
10106
10441
|
return legsForTotal(grid, nearest(totals, initialTotal), from);
|
|
10107
10442
|
});
|
|
10108
|
-
const [announcement, setAnnouncement] = (0,
|
|
10443
|
+
const [announcement, setAnnouncement] = (0, import_react64.useState)("");
|
|
10109
10444
|
const cell = findCombo(grid, total, legs);
|
|
10110
10445
|
const minLegs = legChoices[0] ?? legs;
|
|
10111
10446
|
const maxLegs = legChoices[legChoices.length - 1] ?? legs;
|
|
@@ -10116,29 +10451,29 @@ function BuildComboTool({ grid, strings, streaming, formatKickoff, initialTotal,
|
|
|
10116
10451
|
const d = strings.comboDisplay(nextLegs, nextTotal);
|
|
10117
10452
|
setAnnouncement(findCombo(grid, nextTotal, nextLegs) ? d : `${d}. ${strings.unavailable}`);
|
|
10118
10453
|
};
|
|
10119
|
-
const footer = /* @__PURE__ */ (0,
|
|
10454
|
+
const footer = /* @__PURE__ */ (0, import_jsx_runtime101.jsx)(SendButton, { label: strings.send, display, disabled: !cell || streaming, onClick: () => {
|
|
10120
10455
|
if (cell) onSend(comboAsk(cell, strings));
|
|
10121
10456
|
} });
|
|
10122
|
-
return /* @__PURE__ */ (0,
|
|
10123
|
-
/* @__PURE__ */ (0,
|
|
10124
|
-
/* @__PURE__ */ (0,
|
|
10125
|
-
/* @__PURE__ */ (0,
|
|
10457
|
+
return /* @__PURE__ */ (0, import_jsx_runtime101.jsxs)(PresetToolModal, { title: strings.buildCombo, closeLabel: strings.close, onClose, footer, children: [
|
|
10458
|
+
/* @__PURE__ */ (0, import_jsx_runtime101.jsxs)("div", { className: "ss-w-tool-section", role: "group", "aria-label": strings.totalLabel, children: [
|
|
10459
|
+
/* @__PURE__ */ (0, import_jsx_runtime101.jsx)("span", { className: "ss-w-tool-label", "aria-hidden": "true", children: strings.totalLabel }),
|
|
10460
|
+
/* @__PURE__ */ (0, import_jsx_runtime101.jsx)("div", { className: "ss-w-tool-chips", children: totals.map((t) => /* @__PURE__ */ (0, import_jsx_runtime101.jsx)("button", { type: "button", className: "ss-w-tool-chip", "aria-pressed": samePrice(t, total), onClick: () => choose(t, samePrice(t, total) ? legs : legsForTotal(grid, t, legs)), children: t.toFixed(1) }, t)) })
|
|
10126
10461
|
] }),
|
|
10127
|
-
/* @__PURE__ */ (0,
|
|
10128
|
-
/* @__PURE__ */ (0,
|
|
10129
|
-
/* @__PURE__ */ (0,
|
|
10130
|
-
/* @__PURE__ */ (0,
|
|
10131
|
-
/* @__PURE__ */ (0,
|
|
10132
|
-
/* @__PURE__ */ (0,
|
|
10462
|
+
/* @__PURE__ */ (0, import_jsx_runtime101.jsxs)("div", { className: "ss-w-tool-section", role: "group", "aria-label": strings.matchesLabel, children: [
|
|
10463
|
+
/* @__PURE__ */ (0, import_jsx_runtime101.jsx)("span", { className: "ss-w-tool-label", "aria-hidden": "true", children: strings.matchesLabel }),
|
|
10464
|
+
/* @__PURE__ */ (0, import_jsx_runtime101.jsxs)("div", { className: "ss-w-tool-stepper", children: [
|
|
10465
|
+
/* @__PURE__ */ (0, import_jsx_runtime101.jsx)("button", { type: "button", className: "ss-w-tool-step", "aria-label": strings.fewerMatches, disabled: legs <= minLegs, onClick: () => choose(total, legs - 1), children: "\u2212" }),
|
|
10466
|
+
/* @__PURE__ */ (0, import_jsx_runtime101.jsx)("span", { className: "ss-w-tool-count", children: legs }),
|
|
10467
|
+
/* @__PURE__ */ (0, import_jsx_runtime101.jsx)("button", { type: "button", className: "ss-w-tool-step", "aria-label": strings.moreMatches, disabled: legs >= maxLegs, onClick: () => choose(total, legs + 1), children: "+" })
|
|
10133
10468
|
] })
|
|
10134
10469
|
] }),
|
|
10135
|
-
cell ? /* @__PURE__ */ (0,
|
|
10136
|
-
/* @__PURE__ */ (0,
|
|
10470
|
+
cell ? /* @__PURE__ */ (0, import_jsx_runtime101.jsx)(ComboPreview, { cell, formatKickoff }) : /* @__PURE__ */ (0, import_jsx_runtime101.jsx)(Unavailable, { text: strings.unavailable }),
|
|
10471
|
+
/* @__PURE__ */ (0, import_jsx_runtime101.jsx)("p", { className: "ss-w-vh", "aria-live": "polite", children: announcement })
|
|
10137
10472
|
] });
|
|
10138
10473
|
}
|
|
10139
10474
|
|
|
10140
10475
|
// src/usePresetDial.ts
|
|
10141
|
-
var
|
|
10476
|
+
var import_react65 = require("react");
|
|
10142
10477
|
function sendInFlight(messages, isStreaming) {
|
|
10143
10478
|
const last = messages[messages.length - 1];
|
|
10144
10479
|
return isStreaming && !!last && last.role === "assistant" && !last.done && !last.isGreeting;
|
|
@@ -10152,25 +10487,25 @@ function lastUserId(messages) {
|
|
|
10152
10487
|
}
|
|
10153
10488
|
var SCROLL_KEYS = /* @__PURE__ */ new Set(["ArrowUp", "ArrowDown", "PageUp", "PageDown", "Home", "End", " "]);
|
|
10154
10489
|
function usePresetDial({ layerRef, dialRef, dialButtonRef, messages, isStreaming, activeTab }) {
|
|
10155
|
-
const [expanded, setExpanded] = (0,
|
|
10156
|
-
const fold = (0,
|
|
10157
|
-
const toggle = (0,
|
|
10490
|
+
const [expanded, setExpanded] = (0, import_react65.useState)(() => !sendInFlight(messages, isStreaming));
|
|
10491
|
+
const fold = (0, import_react65.useCallback)(() => setExpanded(false), []);
|
|
10492
|
+
const toggle = (0, import_react65.useCallback)(() => setExpanded((e) => !e), []);
|
|
10158
10493
|
const currentUserId = lastUserId(messages);
|
|
10159
|
-
const userIdRef = (0,
|
|
10160
|
-
(0,
|
|
10494
|
+
const userIdRef = (0, import_react65.useRef)(currentUserId);
|
|
10495
|
+
(0, import_react65.useEffect)(() => {
|
|
10161
10496
|
if (currentUserId === userIdRef.current) return;
|
|
10162
10497
|
userIdRef.current = currentUserId;
|
|
10163
10498
|
setExpanded(false);
|
|
10164
10499
|
}, [currentUserId]);
|
|
10165
|
-
const tabRef = (0,
|
|
10166
|
-
(0,
|
|
10500
|
+
const tabRef = (0, import_react65.useRef)(activeTab);
|
|
10501
|
+
(0, import_react65.useEffect)(() => {
|
|
10167
10502
|
if (activeTab === tabRef.current) return;
|
|
10168
10503
|
tabRef.current = activeTab;
|
|
10169
10504
|
setExpanded(false);
|
|
10170
10505
|
}, [activeTab]);
|
|
10171
|
-
const expandedRef = (0,
|
|
10506
|
+
const expandedRef = (0, import_react65.useRef)(expanded);
|
|
10172
10507
|
expandedRef.current = expanded;
|
|
10173
|
-
(0,
|
|
10508
|
+
(0, import_react65.useEffect)(() => {
|
|
10174
10509
|
const onEscape = (e) => {
|
|
10175
10510
|
const dial = dialRef.current;
|
|
10176
10511
|
if (e.key !== "Escape" || !dial || !e.composedPath().includes(dial)) return;
|
|
@@ -10183,7 +10518,7 @@ function usePresetDial({ layerRef, dialRef, dialButtonRef, messages, isStreaming
|
|
|
10183
10518
|
window.addEventListener("keydown", onEscape, true);
|
|
10184
10519
|
return () => window.removeEventListener("keydown", onEscape, true);
|
|
10185
10520
|
}, [dialRef, dialButtonRef]);
|
|
10186
|
-
(0,
|
|
10521
|
+
(0, import_react65.useEffect)(() => {
|
|
10187
10522
|
if (!expanded) return;
|
|
10188
10523
|
const layer = layerRef.current;
|
|
10189
10524
|
const inDial = (e) => {
|
|
@@ -10235,11 +10570,11 @@ function markToolSeen() {
|
|
|
10235
10570
|
}
|
|
10236
10571
|
|
|
10237
10572
|
// src/components/ChatPanel.tsx
|
|
10238
|
-
var
|
|
10573
|
+
var import_jsx_runtime102 = require("react/jsx-runtime");
|
|
10239
10574
|
var FULLSCREEN_QUERY = "(max-width: 639px)";
|
|
10240
10575
|
function useIsModal() {
|
|
10241
|
-
const [modal, setModal] = (0,
|
|
10242
|
-
(0,
|
|
10576
|
+
const [modal, setModal] = (0, import_react66.useState)(false);
|
|
10577
|
+
(0, import_react66.useEffect)(() => {
|
|
10243
10578
|
if (typeof window === "undefined" || typeof window.matchMedia !== "function") return;
|
|
10244
10579
|
const mql = window.matchMedia(FULLSCREEN_QUERY);
|
|
10245
10580
|
const sync = () => setModal(mql.matches);
|
|
@@ -10250,10 +10585,38 @@ function useIsModal() {
|
|
|
10250
10585
|
return modal;
|
|
10251
10586
|
}
|
|
10252
10587
|
var HIDDEN_LAYER_STYLE = { position: "absolute", inset: 0, visibility: "hidden", display: "flex", flexDirection: "column" };
|
|
10253
|
-
|
|
10588
|
+
var SQUAD_LAYER_STYLE = { display: "flex", flexDirection: "column", flex: 1, minHeight: 0 };
|
|
10589
|
+
function ChatPanel({ controller, ui, slip, onDashboardTap, monitor, discovery, gamesResult, leaderboardResult, clubFixturesResult, clubStandingsResult, clubSquadResult, clubSquadStatsResult, clubPlayerDetailResult, loggedIn, conversation, presetGrid }) {
|
|
10254
10590
|
const { state, close, stop, send, reset } = controller;
|
|
10591
|
+
const [squadView, setSquadView] = (0, import_react66.useState)("roster");
|
|
10592
|
+
const [selectedPlayerId, setSelectedPlayerId] = (0, import_react66.useState)(null);
|
|
10593
|
+
const clearPlayerDetail = clubPlayerDetailResult?.clear;
|
|
10594
|
+
const fetchPlayerDetail = clubPlayerDetailResult?.fetch;
|
|
10595
|
+
const squadLayerRef = (0, import_react66.useRef)(null);
|
|
10596
|
+
const squadScrollRef = (0, import_react66.useRef)(null);
|
|
10597
|
+
const selectPlayer = (playerId) => {
|
|
10598
|
+
squadScrollRef.current = squadLayerRef.current?.querySelector(".ss-w-mon-list")?.scrollTop ?? null;
|
|
10599
|
+
setSelectedPlayerId(playerId);
|
|
10600
|
+
fetchPlayerDetail?.(playerId);
|
|
10601
|
+
};
|
|
10602
|
+
const closePlayer = () => {
|
|
10603
|
+
setSelectedPlayerId(null);
|
|
10604
|
+
clearPlayerDetail?.();
|
|
10605
|
+
};
|
|
10606
|
+
(0, import_react66.useLayoutEffect)(() => {
|
|
10607
|
+
if (selectedPlayerId !== null || squadScrollRef.current === null) return;
|
|
10608
|
+
const list = squadLayerRef.current?.querySelector(".ss-w-mon-list");
|
|
10609
|
+
if (list) list.scrollTop = squadScrollRef.current;
|
|
10610
|
+
squadScrollRef.current = null;
|
|
10611
|
+
}, [selectedPlayerId]);
|
|
10612
|
+
const activeTab = monitor?.activeTab;
|
|
10613
|
+
(0, import_react66.useEffect)(() => {
|
|
10614
|
+
if (activeTab === "squad" || selectedPlayerId === null) return;
|
|
10615
|
+
setSelectedPlayerId(null);
|
|
10616
|
+
clearPlayerDetail?.();
|
|
10617
|
+
}, [activeTab, selectedPlayerId, clearPlayerDetail]);
|
|
10255
10618
|
const isModal = useIsModal();
|
|
10256
|
-
(0,
|
|
10619
|
+
(0, import_react66.useEffect)(() => {
|
|
10257
10620
|
const onKey = (e) => {
|
|
10258
10621
|
if (e.key === "Escape") close();
|
|
10259
10622
|
};
|
|
@@ -10269,19 +10632,19 @@ function ChatPanel({ controller, ui, slip, onDashboardTap, monitor, discovery, g
|
|
|
10269
10632
|
monitor?.setActiveTab("chat");
|
|
10270
10633
|
send(text, { grounding });
|
|
10271
10634
|
};
|
|
10272
|
-
(0,
|
|
10635
|
+
(0, import_react66.useEffect)(() => {
|
|
10273
10636
|
if (monitor && monitor.activeTab !== "chat" && state.isStreaming) monitor.markChatActivity();
|
|
10274
10637
|
}, [monitor, state.isStreaming, state.messages.length]);
|
|
10275
10638
|
const onChatTab = !monitor || monitor.activeTab === "chat";
|
|
10276
|
-
const layerRef = (0,
|
|
10277
|
-
const dialRef = (0,
|
|
10278
|
-
const dialButtonRef = (0,
|
|
10279
|
-
const inputRef = (0,
|
|
10280
|
-
const limitRef = (0,
|
|
10281
|
-
const typedSendRef = (0,
|
|
10282
|
-
const focusAfterCloseRef = (0,
|
|
10283
|
-
const [tool, setTool] = (0,
|
|
10284
|
-
const [toolSeen, setToolSeen] = (0,
|
|
10639
|
+
const layerRef = (0, import_react66.useRef)(null);
|
|
10640
|
+
const dialRef = (0, import_react66.useRef)(null);
|
|
10641
|
+
const dialButtonRef = (0, import_react66.useRef)(null);
|
|
10642
|
+
const inputRef = (0, import_react66.useRef)(null);
|
|
10643
|
+
const limitRef = (0, import_react66.useRef)(null);
|
|
10644
|
+
const typedSendRef = (0, import_react66.useRef)(false);
|
|
10645
|
+
const focusAfterCloseRef = (0, import_react66.useRef)(null);
|
|
10646
|
+
const [tool, setTool] = (0, import_react66.useState)(null);
|
|
10647
|
+
const [toolSeen, setToolSeen] = (0, import_react66.useState)(readToolSeen);
|
|
10285
10648
|
const dial = usePresetDial({
|
|
10286
10649
|
layerRef,
|
|
10287
10650
|
dialRef,
|
|
@@ -10293,53 +10656,53 @@ function ChatPanel({ controller, ui, slip, onDashboardTap, monitor, discovery, g
|
|
|
10293
10656
|
const { fold } = dial;
|
|
10294
10657
|
const paused = isPaused(state.limit);
|
|
10295
10658
|
const showDial = !!presetGrid && onChatTab && !tool && !paused;
|
|
10296
|
-
(0,
|
|
10659
|
+
(0, import_react66.useEffect)(() => {
|
|
10297
10660
|
if (paused) setTool(null);
|
|
10298
10661
|
}, [paused]);
|
|
10299
|
-
(0,
|
|
10662
|
+
(0, import_react66.useEffect)(() => {
|
|
10300
10663
|
if (!paused) return;
|
|
10301
10664
|
if (typedSendRef.current) limitRef.current?.focus();
|
|
10302
10665
|
typedSendRef.current = false;
|
|
10303
10666
|
}, [paused]);
|
|
10304
|
-
const openTool = (0,
|
|
10667
|
+
const openTool = (0, import_react66.useCallback)((next) => {
|
|
10305
10668
|
fold();
|
|
10306
10669
|
markToolSeen();
|
|
10307
10670
|
setToolSeen(true);
|
|
10308
10671
|
setTool(next);
|
|
10309
10672
|
}, [fold]);
|
|
10310
|
-
const onPill = (0,
|
|
10311
|
-
const toolsValue = (0,
|
|
10673
|
+
const onPill = (0, import_react66.useCallback)((kind) => openTool(kind === "numbers" ? { kind: "numbers" } : { kind: "combo" }), [openTool]);
|
|
10674
|
+
const toolsValue = (0, import_react66.useMemo)(
|
|
10312
10675
|
() => presetGrid && !paused ? { openBuilder: (total, legs) => openTool({ kind: "combo", total, legs }), changeLabel: ui.presets.changeCombo } : null,
|
|
10313
10676
|
[presetGrid, paused, openTool, ui.presets.changeCombo]
|
|
10314
10677
|
);
|
|
10315
|
-
const closeTool = (0,
|
|
10678
|
+
const closeTool = (0, import_react66.useCallback)(() => {
|
|
10316
10679
|
focusAfterCloseRef.current = "dial";
|
|
10317
10680
|
setTool(null);
|
|
10318
10681
|
}, []);
|
|
10319
|
-
const sendAsk = (0,
|
|
10682
|
+
const sendAsk = (0, import_react66.useCallback)((ask) => {
|
|
10320
10683
|
focusAfterCloseRef.current = "composer";
|
|
10321
10684
|
setTool(null);
|
|
10322
10685
|
monitor?.setActiveTab("chat");
|
|
10323
10686
|
send(ask.message, { displayText: ask.displayText, preset: ask.preset });
|
|
10324
10687
|
}, [monitor, send]);
|
|
10325
|
-
const formatKickoff = (0,
|
|
10688
|
+
const formatKickoff = (0, import_react66.useCallback)((kickoffUtc) => {
|
|
10326
10689
|
const k = ui.bettingKickoff(kickoffUtc);
|
|
10327
10690
|
return `${k.dayLabel} ${k.time}`;
|
|
10328
10691
|
}, [ui]);
|
|
10329
|
-
(0,
|
|
10692
|
+
(0, import_react66.useEffect)(() => {
|
|
10330
10693
|
if (tool) return;
|
|
10331
10694
|
const target = focusAfterCloseRef.current;
|
|
10332
10695
|
focusAfterCloseRef.current = null;
|
|
10333
10696
|
if (target === "dial") dialButtonRef.current?.focus();
|
|
10334
10697
|
else if (target === "composer") inputRef.current?.focus();
|
|
10335
10698
|
}, [tool]);
|
|
10336
|
-
(0,
|
|
10699
|
+
(0, import_react66.useEffect)(() => {
|
|
10337
10700
|
if (!tool || onChatTab && presetGrid) return;
|
|
10338
10701
|
focusAfterCloseRef.current = "composer";
|
|
10339
10702
|
setTool(null);
|
|
10340
10703
|
}, [tool, onChatTab, presetGrid]);
|
|
10341
|
-
return /* @__PURE__ */ (0,
|
|
10342
|
-
/* @__PURE__ */ (0,
|
|
10704
|
+
return /* @__PURE__ */ (0, import_jsx_runtime102.jsxs)("div", { className: "ss-w-panel", role: "dialog", "aria-modal": isModal, "aria-label": ui.chatDialogLabel, children: [
|
|
10705
|
+
/* @__PURE__ */ (0, import_jsx_runtime102.jsx)(
|
|
10343
10706
|
ChatHeader,
|
|
10344
10707
|
{
|
|
10345
10708
|
onClose: close,
|
|
@@ -10352,7 +10715,7 @@ function ChatPanel({ controller, ui, slip, onDashboardTap, monitor, discovery, g
|
|
|
10352
10715
|
moreOptionsLabel: ui.moreOptions
|
|
10353
10716
|
}
|
|
10354
10717
|
),
|
|
10355
|
-
monitor && /* @__PURE__ */ (0,
|
|
10718
|
+
monitor && /* @__PURE__ */ (0, import_jsx_runtime102.jsx)(
|
|
10356
10719
|
TabBar,
|
|
10357
10720
|
{
|
|
10358
10721
|
monitor,
|
|
@@ -10365,9 +10728,9 @@ function ChatPanel({ controller, ui, slip, onDashboardTap, monitor, discovery, g
|
|
|
10365
10728
|
clubEnabled: clubFixturesResult?.enabled ?? false
|
|
10366
10729
|
}
|
|
10367
10730
|
),
|
|
10368
|
-
/* @__PURE__ */ (0,
|
|
10369
|
-
/* @__PURE__ */ (0,
|
|
10370
|
-
showDial ? /* @__PURE__ */ (0,
|
|
10731
|
+
/* @__PURE__ */ (0, import_jsx_runtime102.jsxs)("div", { ref: layerRef, className: "ss-w-chat-layer", "data-dial": presetGrid ? "" : void 0, style: onChatTab ? void 0 : HIDDEN_LAYER_STYLE, children: [
|
|
10732
|
+
/* @__PURE__ */ (0, import_jsx_runtime102.jsx)(PresetToolsContext.Provider, { value: toolsValue, children: /* @__PURE__ */ (0, import_jsx_runtime102.jsx)(MessageList, { controller, ui, slip, onDashboardTap, monitor }) }),
|
|
10733
|
+
showDial ? /* @__PURE__ */ (0, import_jsx_runtime102.jsx)(
|
|
10371
10734
|
PresetSpeedDial,
|
|
10372
10735
|
{
|
|
10373
10736
|
expanded: dial.expanded,
|
|
@@ -10379,15 +10742,38 @@ function ChatPanel({ controller, ui, slip, onDashboardTap, monitor, discovery, g
|
|
|
10379
10742
|
buttonRef: dialButtonRef
|
|
10380
10743
|
}
|
|
10381
10744
|
) : null,
|
|
10382
|
-
tool && presetGrid && onChatTab && !paused ? tool.kind === "numbers" ? /* @__PURE__ */ (0,
|
|
10745
|
+
tool && presetGrid && onChatTab && !paused ? tool.kind === "numbers" ? /* @__PURE__ */ (0, import_jsx_runtime102.jsx)(SetNumbersTool, { grid: presetGrid, strings: ui.presets, streaming: state.isStreaming, onSend: sendAsk, onClose: closeTool }) : /* @__PURE__ */ (0, import_jsx_runtime102.jsx)(BuildComboTool, { grid: presetGrid, strings: ui.presets, streaming: state.isStreaming, formatKickoff, initialTotal: tool.total, initialLegs: tool.legs, onSend: sendAsk, onClose: closeTool }) : null
|
|
10383
10746
|
] }),
|
|
10384
|
-
monitor && discovery && monitor.activeTab === "today" && /* @__PURE__ */ (0,
|
|
10385
|
-
monitor && monitor.activeTab === "following" && /* @__PURE__ */ (0,
|
|
10386
|
-
monitor && monitor.activeTab === "odds" && /* @__PURE__ */ (0,
|
|
10387
|
-
monitor && monitor.activeTab === "fixtures" && /* @__PURE__ */ (0,
|
|
10388
|
-
monitor && monitor.activeTab === "standings" && /* @__PURE__ */ (0,
|
|
10389
|
-
monitor && monitor.activeTab === "squad" && /* @__PURE__ */ (0,
|
|
10390
|
-
|
|
10747
|
+
monitor && discovery && monitor.activeTab === "today" && /* @__PURE__ */ (0, import_jsx_runtime102.jsx)(TodayPanel, { discovery, ui, monitor }),
|
|
10748
|
+
monitor && monitor.activeTab === "following" && /* @__PURE__ */ (0, import_jsx_runtime102.jsx)(MatchesPanel, { monitor, ui, slip, onAsk: paused ? void 0 : handleAsk }),
|
|
10749
|
+
monitor && monitor.activeTab === "odds" && /* @__PURE__ */ (0, import_jsx_runtime102.jsx)(OddsPanel, { monitor, ui, slip }),
|
|
10750
|
+
monitor && monitor.activeTab === "fixtures" && /* @__PURE__ */ (0, import_jsx_runtime102.jsx)(Fixtures, { fixtures: clubFixturesResult?.fixtures ?? [], loading: clubFixturesResult?.loading ?? false, ui }),
|
|
10751
|
+
monitor && monitor.activeTab === "standings" && /* @__PURE__ */ (0, import_jsx_runtime102.jsx)(Standings, { standings: clubStandingsResult?.data ?? null, loading: clubStandingsResult?.loading ?? false, ui }),
|
|
10752
|
+
monitor && monitor.activeTab === "squad" && /* @__PURE__ */ (0, import_jsx_runtime102.jsxs)(import_jsx_runtime102.Fragment, { children: [
|
|
10753
|
+
/* @__PURE__ */ (0, import_jsx_runtime102.jsx)(
|
|
10754
|
+
"div",
|
|
10755
|
+
{
|
|
10756
|
+
ref: squadLayerRef,
|
|
10757
|
+
style: selectedPlayerId === null ? SQUAD_LAYER_STYLE : HIDDEN_LAYER_STYLE,
|
|
10758
|
+
"aria-hidden": selectedPlayerId !== null ? true : void 0,
|
|
10759
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime102.jsx)(
|
|
10760
|
+
Squad,
|
|
10761
|
+
{
|
|
10762
|
+
squad: clubSquadResult?.data ?? null,
|
|
10763
|
+
loading: clubSquadResult?.loading ?? false,
|
|
10764
|
+
ui,
|
|
10765
|
+
view: squadView,
|
|
10766
|
+
onToggleView: () => setSquadView((v) => v === "roster" ? "stats" : "roster"),
|
|
10767
|
+
stats: clubSquadStatsResult?.data ?? null,
|
|
10768
|
+
statsLoading: clubSquadStatsResult?.loading ?? false,
|
|
10769
|
+
onSelectPlayer: selectPlayer
|
|
10770
|
+
}
|
|
10771
|
+
)
|
|
10772
|
+
}
|
|
10773
|
+
),
|
|
10774
|
+
selectedPlayerId !== null && /* @__PURE__ */ (0, import_jsx_runtime102.jsx)(PlayerDetail, { detail: clubPlayerDetailResult?.data ?? null, loading: clubPlayerDetailResult?.loading ?? false, ui, seasonName: clubSquadStatsResult?.seasonName ?? null, onClose: closePlayer })
|
|
10775
|
+
] }),
|
|
10776
|
+
monitor && monitor.activeTab === "games" && gamesResult && /* @__PURE__ */ (0, import_jsx_runtime102.jsx)(
|
|
10391
10777
|
GamesPanel,
|
|
10392
10778
|
{
|
|
10393
10779
|
loggedIn: !!loggedIn,
|
|
@@ -10402,9 +10788,9 @@ function ChatPanel({ controller, ui, slip, onDashboardTap, monitor, discovery, g
|
|
|
10402
10788
|
}
|
|
10403
10789
|
}
|
|
10404
10790
|
),
|
|
10405
|
-
(!monitor || monitor.activeTab !== "games") && /* @__PURE__ */ (0,
|
|
10406
|
-
/* @__PURE__ */ (0,
|
|
10407
|
-
paused ? null : /* @__PURE__ */ (0,
|
|
10791
|
+
(!monitor || monitor.activeTab !== "games") && /* @__PURE__ */ (0, import_jsx_runtime102.jsxs)(import_jsx_runtime102.Fragment, { children: [
|
|
10792
|
+
/* @__PURE__ */ (0, import_jsx_runtime102.jsx)("div", { ref: limitRef, className: "ss-w-limit", role: "status", tabIndex: -1, children: state.limit ? limitText(state.limit, ui) : null }),
|
|
10793
|
+
paused ? null : /* @__PURE__ */ (0, import_jsx_runtime102.jsx)(
|
|
10408
10794
|
ChatInput,
|
|
10409
10795
|
{
|
|
10410
10796
|
ref: inputRef,
|
|
@@ -10423,9 +10809,9 @@ function ChatPanel({ controller, ui, slip, onDashboardTap, monitor, discovery, g
|
|
|
10423
10809
|
}
|
|
10424
10810
|
|
|
10425
10811
|
// src/components/HostEventsProvider.tsx
|
|
10426
|
-
var
|
|
10812
|
+
var import_jsx_runtime103 = require("react/jsx-runtime");
|
|
10427
10813
|
function HostEventsProvider({ value, children }) {
|
|
10428
|
-
return /* @__PURE__ */ (0,
|
|
10814
|
+
return /* @__PURE__ */ (0, import_jsx_runtime103.jsx)(SlipStateContext.Provider, { value: value.slipState, children });
|
|
10429
10815
|
}
|
|
10430
10816
|
|
|
10431
10817
|
// src/styles/css.generated.ts
|
|
@@ -11504,7 +11890,7 @@ var WIDGET_CSS = `.ss-w-root { all: revert; }
|
|
|
11504
11890
|
/* live monitor tab bar: underline pattern mirrors .ss-w-ecard-scope; the unread dot uses --ss-w-neg */
|
|
11505
11891
|
.ss-w-tabs { display: flex; align-items: stretch; gap: 2px; border-bottom: 1px solid var(--ss-w-line); overflow-x: auto; scrollbar-width: none; }
|
|
11506
11892
|
.ss-w-tabs::-webkit-scrollbar { display: none; }
|
|
11507
|
-
.ss-w-tab { display: inline-flex; align-items: center; gap: 6px; font-size: 12.5px; font-weight: 620; color: var(--ss-w-faint); background: none; border: none; cursor: pointer; padding: 9px
|
|
11893
|
+
.ss-w-tab { display: inline-flex; align-items: center; gap: 6px; font-size: 12.5px; font-weight: 620; color: var(--ss-w-faint); background: none; border: none; cursor: pointer; padding: 9px 8px; margin-bottom: -1px; border-bottom: 2px solid transparent; flex: none; white-space: nowrap; }
|
|
11508
11894
|
.ss-w-tab[data-on] { color: var(--ss-w-ink); border-bottom-color: var(--ss-w-accent); }
|
|
11509
11895
|
.ss-w-tab-count { font-size: 10.5px; font-weight: 700; color: var(--ss-w-faint); background: var(--ss-w-bubble); border-radius: 999px; padding: 1px 6px; }
|
|
11510
11896
|
.ss-w-tab[data-on] .ss-w-tab-count { color: var(--ss-w-accent); }
|
|
@@ -11586,6 +11972,28 @@ var WIDGET_CSS = `.ss-w-root { all: revert; }
|
|
|
11586
11972
|
.ss-w-sq-row { display: flex; align-items: center; gap: 10px; padding: 7px 2px; border-bottom: 1px solid var(--ss-w-line); }
|
|
11587
11973
|
.ss-w-sq-num { flex: none; width: 20px; text-align: right; font-size: 12px; font-weight: 700; font-variant-numeric: tabular-nums; color: var(--ss-w-faint); }
|
|
11588
11974
|
.ss-w-sq-name { font-size: 13px; font-weight: 600; color: var(--ss-w-ink); }
|
|
11975
|
+
.ss-w-sq-name { flex: 1; min-width: 0; }
|
|
11976
|
+
.ss-w-sq-name-1 { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
|
|
11977
|
+
.ss-w-sq-seg { display: flex; flex: none; gap: 2px; margin: 10px 14px 0; padding: 2px; border-radius: var(--ss-w-radius); background: var(--ss-w-track); }
|
|
11978
|
+
.ss-w-sq-seg-btn { flex: 1; padding: 5px 8px; border: 0; border-radius: calc(var(--ss-w-radius) - 2px); background: transparent; font: inherit; font-size: 12px; font-weight: 600; color: var(--ss-w-faint); cursor: pointer; }
|
|
11979
|
+
.ss-w-sq-seg-btn[aria-pressed="true"] { background: var(--ss-w-panel); color: var(--ss-w-ink); }
|
|
11980
|
+
.ss-w-sq-seg-btn:focus-visible, .ss-w-sq-tap:focus-visible, .ss-w-pd-back:focus-visible { outline: 2px solid var(--ss-w-accent); outline-offset: 1px; }
|
|
11981
|
+
.ss-w-sq-tap { width: 100%; border: 0; border-bottom: 1px solid var(--ss-w-line); background: transparent; font: inherit; text-align: left; cursor: pointer; }
|
|
11982
|
+
.ss-w-sq-col { flex: none; width: 40px; text-align: center; font-size: 12px; font-weight: 600; font-variant-numeric: tabular-nums; color: var(--ss-w-ink); }
|
|
11983
|
+
.ss-w-sq-head { border-bottom: 0; padding-bottom: 0; }
|
|
11984
|
+
.ss-w-sq-head .ss-w-sq-col { font-size: 10px; font-weight: 700; color: var(--ss-w-faint); }
|
|
11985
|
+
.ss-w-pd-bar { flex: none; padding: 8px 14px 0; }
|
|
11986
|
+
.ss-w-pd-back { padding: 4px 0; border: 0; background: transparent; font: inherit; font-size: 12px; font-weight: 600; color: var(--ss-w-accent); cursor: pointer; }
|
|
11987
|
+
.ss-w-pd-name { font-size: 16px; font-weight: 700; color: var(--ss-w-ink); }
|
|
11988
|
+
.ss-w-pd-sub { margin-top: 2px; font-size: 12px; color: var(--ss-w-faint); }
|
|
11989
|
+
.ss-w-pd-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 8px; }
|
|
11990
|
+
.ss-w-pd-bio { grid-template-columns: repeat(2, 1fr); }
|
|
11991
|
+
.ss-w-pd-field { display: flex; flex-direction: column; gap: 2px; padding: 8px 10px; border: 1px solid var(--ss-w-line); border-radius: var(--ss-w-radius); }
|
|
11992
|
+
.ss-w-pd-label { font-size: 10px; font-weight: 700; letter-spacing: .04em; color: var(--ss-w-faint); }
|
|
11993
|
+
.ss-w-pd-value { font-size: 14px; font-weight: 700; font-variant-numeric: tabular-nums; color: var(--ss-w-ink); }
|
|
11994
|
+
.ss-w-rec-list { margin: 0; padding: 0; list-style: none; }
|
|
11995
|
+
.ss-w-rec-value { flex: none; font-size: 13px; font-weight: 700; font-variant-numeric: tabular-nums; color: var(--ss-w-ink); }
|
|
11996
|
+
.ss-w-rec-since { font-size: 12px; color: var(--ss-w-faint); }
|
|
11589
11997
|
/* Per-pin unavailable state: the pin's context line still rendered above (score, name, unpin), but
|
|
11590
11998
|
the pin has neither a card nor history (compose-time rescue failed) -- a small inline note beats
|
|
11591
11999
|
a bare context line with nothing under it. */
|
|
@@ -12189,7 +12597,7 @@ var WIDGET_CSS = `.ss-w-root { all: revert; }
|
|
|
12189
12597
|
`;
|
|
12190
12598
|
|
|
12191
12599
|
// src/StatsWidget.tsx
|
|
12192
|
-
var
|
|
12600
|
+
var import_jsx_runtime104 = require("react/jsx-runtime");
|
|
12193
12601
|
function buildClient(props) {
|
|
12194
12602
|
try {
|
|
12195
12603
|
if ("client" in props && props.client) {
|
|
@@ -12214,24 +12622,24 @@ function injectStyles(root) {
|
|
|
12214
12622
|
function StatsWidget(props) {
|
|
12215
12623
|
const injectedClient = "client" in props ? props.client : void 0;
|
|
12216
12624
|
const cfg = props.config;
|
|
12217
|
-
const built = (0,
|
|
12218
|
-
const logger = (0,
|
|
12625
|
+
const built = (0, import_react67.useMemo)(() => buildClient(props), [injectedClient, cfg?.operatorId, cfg?.publicKey, cfg?.baseUrl]);
|
|
12626
|
+
const logger = (0, import_react67.useMemo)(
|
|
12219
12627
|
() => built ? built.client.createEventLogger({
|
|
12220
12628
|
operatorUserId: cfg?.userContext?.operatorUserId,
|
|
12221
12629
|
anonymousUserId: cfg?.userContext?.anonymousUserId
|
|
12222
12630
|
}) : null,
|
|
12223
12631
|
[built?.client]
|
|
12224
12632
|
);
|
|
12225
|
-
const ui = (0,
|
|
12226
|
-
const rootRef = (0,
|
|
12227
|
-
const introDoneRef = (0,
|
|
12228
|
-
const markIntroDone = (0,
|
|
12633
|
+
const ui = (0, import_react67.useMemo)(() => normalizeUi(props.config ?? { operatorId: "", publicKey: "" }), [props.config]);
|
|
12634
|
+
const rootRef = (0, import_react67.useRef)(null);
|
|
12635
|
+
const introDoneRef = (0, import_react67.useRef)(false);
|
|
12636
|
+
const markIntroDone = (0, import_react67.useCallback)(() => {
|
|
12229
12637
|
introDoneRef.current = true;
|
|
12230
12638
|
}, []);
|
|
12231
12639
|
const convStorageKey = `ss-w-conv:${cfg?.operatorId ?? ""}:${cfg?.userContext?.operatorUserId ?? "anon"}`;
|
|
12232
12640
|
const controller = useChatStream(built?.conversation ?? emptyConversation(), ui.starters, built ? ui.greetingMessage : void 0, convStorageKey);
|
|
12233
|
-
const [hasToday, setHasToday] = (0,
|
|
12234
|
-
const liveCardWatches = (0,
|
|
12641
|
+
const [hasToday, setHasToday] = (0, import_react67.useState)(false);
|
|
12642
|
+
const liveCardWatches = (0, import_react67.useMemo)(() => {
|
|
12235
12643
|
const seen = /* @__PURE__ */ new Set();
|
|
12236
12644
|
const out = [];
|
|
12237
12645
|
for (const msg of controller.state.messages) {
|
|
@@ -12257,19 +12665,19 @@ function StatsWidget(props) {
|
|
|
12257
12665
|
});
|
|
12258
12666
|
const operatorUserId = cfg?.userContext?.operatorUserId;
|
|
12259
12667
|
const anonymousUserId = cfg?.userContext?.anonymousUserId;
|
|
12260
|
-
const getSchedule = (0,
|
|
12668
|
+
const getSchedule = (0, import_react67.useCallback)(
|
|
12261
12669
|
(localDate, utcOffsetMinutes) => built ? built.conversation.getSchedule(localDate, utcOffsetMinutes, operatorUserId, anonymousUserId) : Promise.resolve(null),
|
|
12262
12670
|
[built, operatorUserId, anonymousUserId]
|
|
12263
12671
|
);
|
|
12264
|
-
const postLeagueStar = (0,
|
|
12672
|
+
const postLeagueStar = (0, import_react67.useCallback)(
|
|
12265
12673
|
(competitionId, starred) => built ? built.conversation.starLeague(competitionId, starred, operatorUserId, anonymousUserId) : Promise.resolve(null),
|
|
12266
12674
|
[built, operatorUserId, anonymousUserId]
|
|
12267
12675
|
);
|
|
12268
|
-
const getStates = (0,
|
|
12676
|
+
const getStates = (0, import_react67.useCallback)(
|
|
12269
12677
|
(matchIds) => built ? built.conversation.getStates(matchIds) : Promise.resolve(null),
|
|
12270
12678
|
[built]
|
|
12271
12679
|
);
|
|
12272
|
-
const pinnedMatchIds = (0,
|
|
12680
|
+
const pinnedMatchIds = (0, import_react67.useMemo)(
|
|
12273
12681
|
() => monitor.pins.filter((p) => p.kind === "match").map((p) => p.matchId),
|
|
12274
12682
|
[monitor.pins]
|
|
12275
12683
|
);
|
|
@@ -12284,11 +12692,11 @@ function StatsWidget(props) {
|
|
|
12284
12692
|
pinnedMatchIds
|
|
12285
12693
|
});
|
|
12286
12694
|
const todayHasContent = visibleGroupsOf(discovery.groups, discovery.states).length > 0;
|
|
12287
|
-
(0,
|
|
12695
|
+
(0, import_react67.useEffect)(() => {
|
|
12288
12696
|
setHasToday(todayHasContent);
|
|
12289
12697
|
}, [todayHasContent]);
|
|
12290
|
-
const prevLiveSnapshotRef = (0,
|
|
12291
|
-
(0,
|
|
12698
|
+
const prevLiveSnapshotRef = (0, import_react67.useRef)(monitor.snapshot);
|
|
12699
|
+
(0, import_react67.useEffect)(() => {
|
|
12292
12700
|
const snap = monitor.snapshot;
|
|
12293
12701
|
if (!snap || snap === prevLiveSnapshotRef.current) return;
|
|
12294
12702
|
prevLiveSnapshotRef.current = snap;
|
|
@@ -12326,14 +12734,16 @@ function StatsWidget(props) {
|
|
|
12326
12734
|
const leaderboardResult = useLeaderboard(built?.conversation ?? null, { activeTab: monitor.activeTab });
|
|
12327
12735
|
const clubStandingsResult = useClubStandings(built?.conversation ?? null, { activeTab: monitor.activeTab, enabled: clubFixturesResult.enabled });
|
|
12328
12736
|
const clubSquadResult = useClubSquad(built?.conversation ?? null, { activeTab: monitor.activeTab, enabled: clubFixturesResult.enabled });
|
|
12329
|
-
const
|
|
12737
|
+
const clubSquadStatsResult = useClubSquadStats(built?.conversation ?? null, { activeTab: monitor.activeTab, enabled: clubFixturesResult.enabled });
|
|
12738
|
+
const clubPlayerDetailResult = useClubPlayerDetail(built?.conversation ?? null);
|
|
12739
|
+
const getPricePresets = (0, import_react67.useCallback)(
|
|
12330
12740
|
(locale2) => built ? built.conversation.getPricePresets(locale2, { pool: "open" }) : Promise.resolve(null),
|
|
12331
12741
|
[built]
|
|
12332
12742
|
);
|
|
12333
12743
|
const presetGrid = usePresetGrid({ getPricePresets, isOpen: controller.state.isOpen, locale: ui.presets.lang });
|
|
12334
12744
|
const markTodayActivity = monitor.markTodayActivity;
|
|
12335
|
-
const prevLiveCountRef = (0,
|
|
12336
|
-
(0,
|
|
12745
|
+
const prevLiveCountRef = (0, import_react67.useRef)(0);
|
|
12746
|
+
(0, import_react67.useEffect)(() => {
|
|
12337
12747
|
const rose = prevLiveCountRef.current === 0 && discovery.liveCount > 0;
|
|
12338
12748
|
prevLiveCountRef.current = discovery.liveCount;
|
|
12339
12749
|
if (rose) markTodayActivity();
|
|
@@ -12347,7 +12757,7 @@ function StatsWidget(props) {
|
|
|
12347
12757
|
closePanel: controller.close
|
|
12348
12758
|
});
|
|
12349
12759
|
const markAdded = hostEvents.markAdded;
|
|
12350
|
-
const slip = (0,
|
|
12760
|
+
const slip = (0, import_react67.useMemo)(
|
|
12351
12761
|
() => {
|
|
12352
12762
|
const handler = props.config?.onAddToSlip;
|
|
12353
12763
|
return {
|
|
@@ -12366,7 +12776,7 @@ function StatsWidget(props) {
|
|
|
12366
12776
|
},
|
|
12367
12777
|
[props.config?.onAddToSlip, controller.state.conversationId, markAdded]
|
|
12368
12778
|
);
|
|
12369
|
-
const onDashboardTap = (0,
|
|
12779
|
+
const onDashboardTap = (0, import_react67.useMemo)(
|
|
12370
12780
|
() => built ? createDashboardTapSignal((input) => built.conversation.sendSignal(input), logger) : void 0,
|
|
12371
12781
|
[built, logger]
|
|
12372
12782
|
);
|
|
@@ -12383,11 +12793,11 @@ function StatsWidget(props) {
|
|
|
12383
12793
|
})
|
|
12384
12794
|
}));
|
|
12385
12795
|
const conversationId = controller.state.conversationId ?? void 0;
|
|
12386
|
-
(0,
|
|
12796
|
+
(0, import_react67.useEffect)(() => {
|
|
12387
12797
|
if (!logger) return;
|
|
12388
12798
|
logger.setIdentity({ operatorUserId, anonymousUserId, conversationId });
|
|
12389
12799
|
}, [logger, operatorUserId, anonymousUserId, conversationId]);
|
|
12390
|
-
(0,
|
|
12800
|
+
(0, import_react67.useEffect)(() => {
|
|
12391
12801
|
if (!logger) return;
|
|
12392
12802
|
logger.resume();
|
|
12393
12803
|
const onHide = () => {
|
|
@@ -12405,14 +12815,14 @@ function StatsWidget(props) {
|
|
|
12405
12815
|
logger.dispose();
|
|
12406
12816
|
};
|
|
12407
12817
|
}, [logger]);
|
|
12408
|
-
(0,
|
|
12818
|
+
(0, import_react67.useEffect)(() => {
|
|
12409
12819
|
if (!built || !ui.injectStyles) return;
|
|
12410
12820
|
const node = rootRef.current?.getRootNode();
|
|
12411
12821
|
if (node) injectStyles(node);
|
|
12412
12822
|
}, [built, ui.injectStyles]);
|
|
12413
12823
|
if (!built) return null;
|
|
12414
12824
|
const attrs = themeAttrs(ui);
|
|
12415
|
-
return /* @__PURE__ */ (0,
|
|
12825
|
+
return /* @__PURE__ */ (0, import_jsx_runtime104.jsx)(EventLogContext.Provider, { value: logger, children: /* @__PURE__ */ (0, import_jsx_runtime104.jsx)(HostEventsProvider, { value: hostEvents, children: /* @__PURE__ */ (0, import_jsx_runtime104.jsx)("div", { ref: rootRef, className: "ss-w-root", "data-ss-w-theme": attrs["data-ss-w-theme"], "data-ss-w-pos": attrs["data-ss-w-pos"], style: attrs.style, children: controller.state.isOpen ? /* @__PURE__ */ (0, import_jsx_runtime104.jsx)(
|
|
12416
12826
|
ChatPanel,
|
|
12417
12827
|
{
|
|
12418
12828
|
controller,
|
|
@@ -12426,11 +12836,13 @@ function StatsWidget(props) {
|
|
|
12426
12836
|
clubFixturesResult,
|
|
12427
12837
|
clubStandingsResult,
|
|
12428
12838
|
clubSquadResult,
|
|
12839
|
+
clubSquadStatsResult,
|
|
12840
|
+
clubPlayerDetailResult,
|
|
12429
12841
|
loggedIn: !!operatorUserId,
|
|
12430
12842
|
conversation: built?.conversation ?? null,
|
|
12431
12843
|
presetGrid
|
|
12432
12844
|
}
|
|
12433
|
-
) : /* @__PURE__ */ (0,
|
|
12845
|
+
) : /* @__PURE__ */ (0, import_jsx_runtime104.jsx)(
|
|
12434
12846
|
ChatFab,
|
|
12435
12847
|
{
|
|
12436
12848
|
label: ui.launcherLabel,
|