@sensiblestats/widget-react 0.84.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 +11 -0
- package/dist/index.cjs +800 -389
- 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 +763 -352
- 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,
|
|
@@ -3281,8 +3377,83 @@ function useClubSquad(conversation, { activeTab, enabled }) {
|
|
|
3281
3377
|
return { data, loading: effectiveLoading, refresh };
|
|
3282
3378
|
}
|
|
3283
3379
|
|
|
3284
|
-
// src/
|
|
3380
|
+
// src/useClubSquadStats.ts
|
|
3285
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");
|
|
3286
3457
|
|
|
3287
3458
|
// src/presetGrid.ts
|
|
3288
3459
|
var DEFAULT_SINGLES_LIMITS = [1.3, 1.5, 1.7, 2];
|
|
@@ -3425,22 +3596,22 @@ function marketDisplay(cell, s) {
|
|
|
3425
3596
|
// src/usePresetGrid.ts
|
|
3426
3597
|
var GRID_MAX_AGE_MS = 6e5;
|
|
3427
3598
|
function usePresetGrid({ getPricePresets, isOpen, locale, now = Date.now }) {
|
|
3428
|
-
const [grid, setGrid] = (0,
|
|
3429
|
-
const keptRef = (0,
|
|
3430
|
-
const localeRef = (0,
|
|
3431
|
-
const inFlightRef = (0,
|
|
3432
|
-
const mountedRef = (0,
|
|
3433
|
-
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);
|
|
3434
3605
|
getRef.current = getPricePresets;
|
|
3435
|
-
const nowRef = (0,
|
|
3606
|
+
const nowRef = (0, import_react14.useRef)(now);
|
|
3436
3607
|
nowRef.current = now;
|
|
3437
|
-
(0,
|
|
3608
|
+
(0, import_react14.useEffect)(() => {
|
|
3438
3609
|
mountedRef.current = true;
|
|
3439
3610
|
return () => {
|
|
3440
3611
|
mountedRef.current = false;
|
|
3441
3612
|
};
|
|
3442
3613
|
}, []);
|
|
3443
|
-
(0,
|
|
3614
|
+
(0, import_react14.useEffect)(() => {
|
|
3444
3615
|
if (localeRef.current !== locale) {
|
|
3445
3616
|
localeRef.current = locale;
|
|
3446
3617
|
keptRef.current = null;
|
|
@@ -3483,18 +3654,18 @@ function visibleGroupsOf(groups, states) {
|
|
|
3483
3654
|
}
|
|
3484
3655
|
|
|
3485
3656
|
// src/eventLogContext.ts
|
|
3486
|
-
var
|
|
3487
|
-
var EventLogContext = (0,
|
|
3657
|
+
var import_react15 = require("react");
|
|
3658
|
+
var EventLogContext = (0, import_react15.createContext)(null);
|
|
3488
3659
|
function useEventLog() {
|
|
3489
|
-
return (0,
|
|
3660
|
+
return (0, import_react15.useContext)(EventLogContext);
|
|
3490
3661
|
}
|
|
3491
3662
|
|
|
3492
3663
|
// src/popupTelemetry.ts
|
|
3493
|
-
var
|
|
3664
|
+
var import_react16 = require("react");
|
|
3494
3665
|
function usePopupTelemetry(log, isOpen, popupText, dismissPopup) {
|
|
3495
|
-
const shownRef = (0,
|
|
3496
|
-
const closedTextRef = (0,
|
|
3497
|
-
(0,
|
|
3666
|
+
const shownRef = (0, import_react16.useRef)(/* @__PURE__ */ new Set());
|
|
3667
|
+
const closedTextRef = (0, import_react16.useRef)(null);
|
|
3668
|
+
(0, import_react16.useEffect)(() => {
|
|
3498
3669
|
if (isOpen) {
|
|
3499
3670
|
if (closedTextRef.current) log?.log({ name: "popup_opened" });
|
|
3500
3671
|
closedTextRef.current = null;
|
|
@@ -3506,17 +3677,17 @@ function usePopupTelemetry(log, isOpen, popupText, dismissPopup) {
|
|
|
3506
3677
|
log?.log({ name: "popup_shown" });
|
|
3507
3678
|
}
|
|
3508
3679
|
}, [log, isOpen, popupText]);
|
|
3509
|
-
return (0,
|
|
3680
|
+
return (0, import_react16.useCallback)(() => {
|
|
3510
3681
|
log?.log({ name: "popup_dismissed" });
|
|
3511
3682
|
dismissPopup();
|
|
3512
3683
|
}, [log, dismissPopup]);
|
|
3513
3684
|
}
|
|
3514
3685
|
|
|
3515
3686
|
// src/openTelemetry.ts
|
|
3516
|
-
var
|
|
3687
|
+
var import_react17 = require("react");
|
|
3517
3688
|
function useOpenTelemetry(log, isOpen) {
|
|
3518
|
-
const openLoggedRef = (0,
|
|
3519
|
-
(0,
|
|
3689
|
+
const openLoggedRef = (0, import_react17.useRef)(false);
|
|
3690
|
+
(0, import_react17.useEffect)(() => {
|
|
3520
3691
|
if (!isOpen) {
|
|
3521
3692
|
openLoggedRef.current = false;
|
|
3522
3693
|
return;
|
|
@@ -3528,10 +3699,10 @@ function useOpenTelemetry(log, isOpen) {
|
|
|
3528
3699
|
}
|
|
3529
3700
|
|
|
3530
3701
|
// src/components/ChatFab.tsx
|
|
3531
|
-
var
|
|
3702
|
+
var import_react19 = require("react");
|
|
3532
3703
|
|
|
3533
3704
|
// src/components/BrandMark.tsx
|
|
3534
|
-
var
|
|
3705
|
+
var import_react18 = require("react");
|
|
3535
3706
|
|
|
3536
3707
|
// src/assets/logo.ts
|
|
3537
3708
|
var SS_LOGO_DATA_URI = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAjoAAAI6CAYAAAAuSOLAAAAAAXNSR0IArs4c6QAAAJplWElmTU0AKgAAAAgAAwESAAMAAAABAAEAAAExAAIAAAA9AAAAModpAAQAAAABAAAAcAAAAABBZG9iZSBQaG90b3Nob3AgMjYuMTAgKDIwMjUwNzMwLm0uMzE2NiAwN2IxMjM0KSAgKE1hY2ludG9zaCkAAAADoAEAAwAAAAEAAQAAoAIABAAAAAEAAAI6oAMABAAAAAEAAAI6AAAAACwGtVwAAAQwaVRYdFhNTDpjb20uYWRvYmUueG1wAAAAAAA8eDp4bXBtZXRhIHhtbG5zOng9ImFkb2JlOm5zOm1ldGEvIiB4OnhtcHRrPSJYTVAgQ29yZSA2LjAuMCI+CiAgIDxyZGY6UkRGIHhtbG5zOnJkZj0iaHR0cDovL3d3dy53My5vcmcvMTk5OS8wMi8yMi1yZGYtc3ludGF4LW5zIyI+CiAgICAgIDxyZGY6RGVzY3JpcHRpb24gcmRmOmFib3V0PSIiCiAgICAgICAgICAgIHhtbG5zOnhtcE1NPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvbW0vIgogICAgICAgICAgICB4bWxuczpzdFJlZj0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL3NUeXBlL1Jlc291cmNlUmVmIyIKICAgICAgICAgICAgeG1sbnM6eG1wPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvIgogICAgICAgICAgICB4bWxuczp0aWZmPSJodHRwOi8vbnMuYWRvYmUuY29tL3RpZmYvMS4wLyI+CiAgICAgICAgIDx4bXBNTTpEb2N1bWVudElEPnhtcC5kaWQ6QzBGRTM5NjM5NEJEMTFGMEJGNjZEMjUyN0U0MzU5RUM8L3htcE1NOkRvY3VtZW50SUQ+CiAgICAgICAgIDx4bXBNTTpJbnN0YW5jZUlEPnhtcC5paWQ6QzBGRTM5NjI5NEJEMTFGMEJGNjZEMjUyN0U0MzU5RUM8L3htcE1NOkluc3RhbmNlSUQ+CiAgICAgICAgIDx4bXBNTTpEZXJpdmVkRnJvbSByZGY6cGFyc2VUeXBlPSJSZXNvdXJjZSI+CiAgICAgICAgICAgIDxzdFJlZjppbnN0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";
|
|
@@ -3594,7 +3765,7 @@ function DashboardIcon({ name }) {
|
|
|
3594
3765
|
// src/components/BrandMark.tsx
|
|
3595
3766
|
var import_jsx_runtime2 = require("react/jsx-runtime");
|
|
3596
3767
|
function BrandMark({ logoUrl, className }) {
|
|
3597
|
-
const [failed, setFailed] = (0,
|
|
3768
|
+
const [failed, setFailed] = (0, import_react18.useState)(false);
|
|
3598
3769
|
if (!logoUrl || failed) return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(SsMark, { className });
|
|
3599
3770
|
return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("img", { className, src: logoUrl, alt: "", "aria-hidden": "true", onError: () => setFailed(true) });
|
|
3600
3771
|
}
|
|
@@ -3630,9 +3801,9 @@ function GreetingBubble({ text, onOpen, onDismiss, dismissLabel = "Dismiss", ask
|
|
|
3630
3801
|
var import_jsx_runtime4 = require("react/jsx-runtime");
|
|
3631
3802
|
function ChatFab({ label, greeting, popupText, logoUrl, onOpen, onDismissPopup, dismissLabel = "Dismiss", introAllowed = false, onIntroStart, asks }) {
|
|
3632
3803
|
const bubble = popupText ?? greeting;
|
|
3633
|
-
const [intro, setIntro] = (0,
|
|
3634
|
-
const armedRef = (0,
|
|
3635
|
-
(0,
|
|
3804
|
+
const [intro, setIntro] = (0, import_react19.useState)(false);
|
|
3805
|
+
const armedRef = (0, import_react19.useRef)(introAllowed);
|
|
3806
|
+
(0, import_react19.useEffect)(() => {
|
|
3636
3807
|
if (armedRef.current && bubble) {
|
|
3637
3808
|
armedRef.current = false;
|
|
3638
3809
|
setIntro(true);
|
|
@@ -3646,10 +3817,10 @@ function ChatFab({ label, greeting, popupText, logoUrl, onOpen, onDismissPopup,
|
|
|
3646
3817
|
}
|
|
3647
3818
|
|
|
3648
3819
|
// src/components/ChatPanel.tsx
|
|
3649
|
-
var
|
|
3820
|
+
var import_react66 = require("react");
|
|
3650
3821
|
|
|
3651
3822
|
// src/components/ChatHeader.tsx
|
|
3652
|
-
var
|
|
3823
|
+
var import_react20 = require("react");
|
|
3653
3824
|
var import_jsx_runtime5 = require("react/jsx-runtime");
|
|
3654
3825
|
function ChatHeader({
|
|
3655
3826
|
onClose,
|
|
@@ -3661,15 +3832,15 @@ function ChatHeader({
|
|
|
3661
3832
|
newConversationLabel = "New conversation",
|
|
3662
3833
|
moreOptionsLabel = "More options"
|
|
3663
3834
|
}) {
|
|
3664
|
-
const [menuOpen, setMenuOpen] = (0,
|
|
3665
|
-
const wrapRef = (0,
|
|
3666
|
-
const kebabRef = (0,
|
|
3667
|
-
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);
|
|
3668
3839
|
const hasMenu = !!(canReset && onNewConversation);
|
|
3669
|
-
(0,
|
|
3840
|
+
(0, import_react20.useEffect)(() => {
|
|
3670
3841
|
if (menuOpen) firstItemRef.current?.focus();
|
|
3671
3842
|
}, [menuOpen]);
|
|
3672
|
-
(0,
|
|
3843
|
+
(0, import_react20.useEffect)(() => {
|
|
3673
3844
|
if (!menuOpen) return;
|
|
3674
3845
|
const onPointer = (e) => {
|
|
3675
3846
|
if (!wrapRef.current?.contains(e.target)) setMenuOpen(false);
|
|
@@ -3725,7 +3896,7 @@ function ChatHeader({
|
|
|
3725
3896
|
}
|
|
3726
3897
|
|
|
3727
3898
|
// src/components/MessageList.tsx
|
|
3728
|
-
var
|
|
3899
|
+
var import_react40 = require("react");
|
|
3729
3900
|
|
|
3730
3901
|
// src/components/Markdown.tsx
|
|
3731
3902
|
var import_react_markdown = __toESM(require("react-markdown"), 1);
|
|
@@ -3743,7 +3914,7 @@ function Markdown({ text }) {
|
|
|
3743
3914
|
}
|
|
3744
3915
|
|
|
3745
3916
|
// src/components/EntityCardList.tsx
|
|
3746
|
-
var
|
|
3917
|
+
var import_react21 = require("react");
|
|
3747
3918
|
var import_jsx_runtime7 = require("react/jsx-runtime");
|
|
3748
3919
|
var MAX_VISIBLE = 3;
|
|
3749
3920
|
var RECORD_RE = /^(\d+)-(\d+)-(\d+)$/;
|
|
@@ -3827,7 +3998,7 @@ function ScopeTabs({ scopes, active, onSelect }) {
|
|
|
3827
3998
|
)) });
|
|
3828
3999
|
}
|
|
3829
4000
|
function EntityCardItem({ c }) {
|
|
3830
|
-
const [active, setActive] = (0,
|
|
4001
|
+
const [active, setActive] = (0, import_react21.useState)(0);
|
|
3831
4002
|
const hasBody = c.scopes.length > 0;
|
|
3832
4003
|
if (!hasBody) {
|
|
3833
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 }) });
|
|
@@ -3841,7 +4012,7 @@ function EntityCardItem({ c }) {
|
|
|
3841
4012
|
] });
|
|
3842
4013
|
}
|
|
3843
4014
|
function EntityCardList({ cards, disabled, showLessLabel = "Show less", showMoreLabel = (n) => `Show ${n} more` }) {
|
|
3844
|
-
const [expanded, setExpanded] = (0,
|
|
4015
|
+
const [expanded, setExpanded] = (0, import_react21.useState)(false);
|
|
3845
4016
|
if (cards.length === 0) return null;
|
|
3846
4017
|
const visible = expanded ? cards : cards.slice(0, MAX_VISIBLE);
|
|
3847
4018
|
const overflow = cards.length - MAX_VISIBLE;
|
|
@@ -3852,17 +4023,17 @@ function EntityCardList({ cards, disabled, showLessLabel = "Show less", showMore
|
|
|
3852
4023
|
}
|
|
3853
4024
|
|
|
3854
4025
|
// src/components/AddToSlipButton.tsx
|
|
3855
|
-
var
|
|
4026
|
+
var import_react25 = require("react");
|
|
3856
4027
|
|
|
3857
4028
|
// src/slipAdd.ts
|
|
3858
|
-
var
|
|
4029
|
+
var import_react23 = require("react");
|
|
3859
4030
|
var import_widget_sdk5 = require("@sensiblestats/widget-sdk");
|
|
3860
4031
|
|
|
3861
4032
|
// src/slipStateContext.ts
|
|
3862
|
-
var
|
|
3863
|
-
var SlipStateContext = (0,
|
|
4033
|
+
var import_react22 = require("react");
|
|
4034
|
+
var SlipStateContext = (0, import_react22.createContext)(null);
|
|
3864
4035
|
function useSlipState() {
|
|
3865
|
-
return (0,
|
|
4036
|
+
return (0, import_react22.useContext)(SlipStateContext);
|
|
3866
4037
|
}
|
|
3867
4038
|
|
|
3868
4039
|
// src/slipAdd.ts
|
|
@@ -3877,7 +4048,7 @@ function useSlipAdd(slip, ui) {
|
|
|
3877
4048
|
const slipState = useSlipState();
|
|
3878
4049
|
const handler = slip.onAddToSlip;
|
|
3879
4050
|
const rawLabels = !!ui?.rawBettingLabels;
|
|
3880
|
-
return (0,
|
|
4051
|
+
return (0, import_react23.useCallback)(async (selection, { marketDeveloperName, selectionLabel, line }) => {
|
|
3881
4052
|
if (!handler) return { kind: "failed" };
|
|
3882
4053
|
const pick = slipPickFields(selection, rawLabels ? selectionLabel : void 0, line);
|
|
3883
4054
|
if (marketDeveloperName !== void 0) {
|
|
@@ -3914,11 +4085,11 @@ function useSlipAdd(slip, ui) {
|
|
|
3914
4085
|
}
|
|
3915
4086
|
|
|
3916
4087
|
// src/components/Toast.tsx
|
|
3917
|
-
var
|
|
4088
|
+
var import_react24 = require("react");
|
|
3918
4089
|
var import_jsx_runtime8 = require("react/jsx-runtime");
|
|
3919
4090
|
var DISMISS_MS = 4e3;
|
|
3920
4091
|
function Toast({ toast, onDismiss }) {
|
|
3921
|
-
(0,
|
|
4092
|
+
(0, import_react24.useEffect)(() => {
|
|
3922
4093
|
if (!toast) return;
|
|
3923
4094
|
const timer = setTimeout(onDismiss, DISMISS_MS);
|
|
3924
4095
|
return () => clearTimeout(timer);
|
|
@@ -3930,10 +4101,10 @@ function Toast({ toast, onDismiss }) {
|
|
|
3930
4101
|
// src/components/AddToSlipButton.tsx
|
|
3931
4102
|
var import_jsx_runtime9 = require("react/jsx-runtime");
|
|
3932
4103
|
function SlipButton({ selection, shownOdds, marketDeveloperName, selectionLabel, line, slip, ui, price, ariaLabel }) {
|
|
3933
|
-
const [pending, setPending] = (0,
|
|
3934
|
-
const [settledLocal, setSettledLocal] = (0,
|
|
3935
|
-
const [toast, setToast] = (0,
|
|
3936
|
-
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), []);
|
|
3937
4108
|
const add = useSlipAdd(slip, ui);
|
|
3938
4109
|
const slipState = useSlipState();
|
|
3939
4110
|
const handler = slip.onAddToSlip;
|
|
@@ -4021,14 +4192,14 @@ function OddsMovementBadge({
|
|
|
4021
4192
|
}
|
|
4022
4193
|
|
|
4023
4194
|
// src/components/Crest.tsx
|
|
4024
|
-
var
|
|
4195
|
+
var import_react26 = require("react");
|
|
4025
4196
|
var import_jsx_runtime11 = require("react/jsx-runtime");
|
|
4026
4197
|
function initials2(name) {
|
|
4027
4198
|
return (name ?? "").trim().slice(0, 1).toUpperCase() || "?";
|
|
4028
4199
|
}
|
|
4029
4200
|
function Crest2({ url, name, kind }) {
|
|
4030
4201
|
const cls = kind === "comp" ? "ss-w-bi-comp-logo" : "ss-w-bi-crest";
|
|
4031
|
-
const [failed, setFailed] = (0,
|
|
4202
|
+
const [failed, setFailed] = (0, import_react26.useState)(false);
|
|
4032
4203
|
if (url && !failed) {
|
|
4033
4204
|
return /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("img", { className: cls, src: url, alt: "", "aria-hidden": "true", onError: () => setFailed(true) });
|
|
4034
4205
|
}
|
|
@@ -4036,7 +4207,7 @@ function Crest2({ url, name, kind }) {
|
|
|
4036
4207
|
}
|
|
4037
4208
|
|
|
4038
4209
|
// src/components/PinToggle.tsx
|
|
4039
|
-
var
|
|
4210
|
+
var import_react27 = require("react");
|
|
4040
4211
|
var import_jsx_runtime12 = require("react/jsx-runtime");
|
|
4041
4212
|
var PIN_GLYPHS = {
|
|
4042
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" },
|
|
@@ -4044,8 +4215,8 @@ var PIN_GLYPHS = {
|
|
|
4044
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" }
|
|
4045
4216
|
};
|
|
4046
4217
|
function PinToggle({ pin, monitor, ui, market }) {
|
|
4047
|
-
const [toast, setToast] = (0,
|
|
4048
|
-
const dismiss = (0,
|
|
4218
|
+
const [toast, setToast] = (0, import_react27.useState)(null);
|
|
4219
|
+
const dismiss = (0, import_react27.useCallback)(() => setToast(null), []);
|
|
4049
4220
|
const log = useEventLog();
|
|
4050
4221
|
if (!monitor || !monitor.enabled) return null;
|
|
4051
4222
|
const key = pinKey(pin);
|
|
@@ -4102,11 +4273,11 @@ function PinToggle({ pin, monitor, ui, market }) {
|
|
|
4102
4273
|
}
|
|
4103
4274
|
|
|
4104
4275
|
// src/components/PriceHistoryButton.tsx
|
|
4105
|
-
var
|
|
4276
|
+
var import_react28 = require("react");
|
|
4106
4277
|
var import_jsx_runtime13 = require("react/jsx-runtime");
|
|
4107
4278
|
function PriceHistoryButton({ selection, monitor, ui }) {
|
|
4108
|
-
const [toast, setToast] = (0,
|
|
4109
|
-
const dismiss = (0,
|
|
4279
|
+
const [toast, setToast] = (0, import_react28.useState)(null);
|
|
4280
|
+
const dismiss = (0, import_react28.useCallback)(() => setToast(null), []);
|
|
4110
4281
|
const log = useEventLog();
|
|
4111
4282
|
if (!monitor || !monitor.enabled) return null;
|
|
4112
4283
|
const name = joinSelection(selection.selectionLabel ?? void 0, selection.line ?? void 0);
|
|
@@ -4221,15 +4392,15 @@ function BettingInsightList({ insights, ui, slip, monitor }) {
|
|
|
4221
4392
|
}
|
|
4222
4393
|
|
|
4223
4394
|
// src/components/AddAllToSlipButton.tsx
|
|
4224
|
-
var
|
|
4395
|
+
var import_react29 = require("react");
|
|
4225
4396
|
var import_jsx_runtime15 = require("react/jsx-runtime");
|
|
4226
4397
|
function AddAllToSlipButton({ legs, slip, ui }) {
|
|
4227
4398
|
const add = useSlipAdd(slip, ui);
|
|
4228
4399
|
const slipState = useSlipState();
|
|
4229
|
-
const [pending, setPending] = (0,
|
|
4230
|
-
const [settledLocal, setSettledLocal] = (0,
|
|
4231
|
-
const [toast, setToast] = (0,
|
|
4232
|
-
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), []);
|
|
4233
4404
|
if (!ui || !slip.onAddToSlip || legs.length < 2) return null;
|
|
4234
4405
|
const settled = slipState ? slipState.settled : settledLocal;
|
|
4235
4406
|
const open = legs.filter((leg) => !settled[leg.matchOddsId]);
|
|
@@ -4271,10 +4442,10 @@ function AddAllToSlipButton({ legs, slip, ui }) {
|
|
|
4271
4442
|
}
|
|
4272
4443
|
|
|
4273
4444
|
// src/presetToolsContext.ts
|
|
4274
|
-
var
|
|
4275
|
-
var PresetToolsContext = (0,
|
|
4445
|
+
var import_react30 = require("react");
|
|
4446
|
+
var PresetToolsContext = (0, import_react30.createContext)(null);
|
|
4276
4447
|
function usePresetTools() {
|
|
4277
|
-
return (0,
|
|
4448
|
+
return (0, import_react30.useContext)(PresetToolsContext);
|
|
4278
4449
|
}
|
|
4279
4450
|
|
|
4280
4451
|
// src/components/ComboCardList.tsx
|
|
@@ -4339,7 +4510,7 @@ function ComboCardList({ cards, ui, slip, monitor }) {
|
|
|
4339
4510
|
}
|
|
4340
4511
|
|
|
4341
4512
|
// src/components/MarketOddsCardList.tsx
|
|
4342
|
-
var
|
|
4513
|
+
var import_react31 = require("react");
|
|
4343
4514
|
|
|
4344
4515
|
// src/components/AllMarketsButton.tsx
|
|
4345
4516
|
var import_jsx_runtime17 = require("react/jsx-runtime");
|
|
@@ -4402,7 +4573,7 @@ function fmtHhMm(iso, locale) {
|
|
|
4402
4573
|
return new Date(iso).toLocaleTimeString(locale, { hour: "2-digit", minute: "2-digit", hour12: false });
|
|
4403
4574
|
}
|
|
4404
4575
|
function MarketOddsCard({ vm, ui, slip, monitor, inSlipIds, hideHeader, pinRef }) {
|
|
4405
|
-
const [open, setOpen] = (0,
|
|
4576
|
+
const [open, setOpen] = (0, import_react31.useState)(false);
|
|
4406
4577
|
const kickoffFallback = vm.kickoffUtc && ui?.bettingKickoff ? ui.bettingKickoff(vm.kickoffUtc) : void 0;
|
|
4407
4578
|
const kickoff = vm.kickoffLabel ?? (kickoffFallback ? `${kickoffFallback.dayLabel} ${kickoffFallback.time}` : void 0);
|
|
4408
4579
|
const hasNamedTeams = !!vm.homeTeamName && !!vm.awayTeamName;
|
|
@@ -4412,9 +4583,9 @@ function MarketOddsCard({ vm, ui, slip, monitor, inSlipIds, hideHeader, pinRef }
|
|
|
4412
4583
|
const asOfMs = live ? new Date(live.asOfUtc).getTime() : NaN;
|
|
4413
4584
|
const isStale = live != null && !isClosed && (vm.awaitingLiveUpdate === true || Date.now() - asOfMs > STALE_AFTER_MS);
|
|
4414
4585
|
const staleTime = isStale && live ? fmtHhMm(live.asOfUtc, ui?.locale ?? "en") : null;
|
|
4415
|
-
const [, setStaleTick] = (0,
|
|
4586
|
+
const [, setStaleTick] = (0, import_react31.useState)(0);
|
|
4416
4587
|
const watchStale = live != null && !isClosed && !isStale;
|
|
4417
|
-
(0,
|
|
4588
|
+
(0, import_react31.useEffect)(() => {
|
|
4418
4589
|
if (!watchStale) return;
|
|
4419
4590
|
const id = window.setTimeout(() => setStaleTick((n) => n + 1), Math.max(0, asOfMs + STALE_AFTER_MS - Date.now()) + 1);
|
|
4420
4591
|
return () => window.clearTimeout(id);
|
|
@@ -4493,7 +4664,7 @@ function MarketOddsCardList({ cards, ui, slip, monitor, inSlipIds, hideHeader, p
|
|
|
4493
4664
|
}
|
|
4494
4665
|
|
|
4495
4666
|
// src/components/CompactOddsList.tsx
|
|
4496
|
-
var
|
|
4667
|
+
var import_react32 = require("react");
|
|
4497
4668
|
|
|
4498
4669
|
// src/compactList.ts
|
|
4499
4670
|
var COMPACT_MIN_CARDS = 3;
|
|
@@ -4607,11 +4778,11 @@ function Row({ row, columns, ui, slip, monitor, rowRef }) {
|
|
|
4607
4778
|
] });
|
|
4608
4779
|
}
|
|
4609
4780
|
function CompactOddsList({ list, ui, slip, monitor }) {
|
|
4610
|
-
const [shown, setShown] = (0,
|
|
4781
|
+
const [shown, setShown] = (0, import_react32.useState)(COMPACT_PAGE);
|
|
4611
4782
|
const hidden = list.rowCount - shown;
|
|
4612
|
-
const [focusIndex, setFocusIndex] = (0,
|
|
4613
|
-
const focusRef = (0,
|
|
4614
|
-
(0,
|
|
4783
|
+
const [focusIndex, setFocusIndex] = (0, import_react32.useState)(null);
|
|
4784
|
+
const focusRef = (0, import_react32.useRef)(null);
|
|
4785
|
+
(0, import_react32.useEffect)(() => {
|
|
4615
4786
|
if (focusIndex !== null) focusRef.current?.focus();
|
|
4616
4787
|
}, [focusIndex]);
|
|
4617
4788
|
let left = shown;
|
|
@@ -4916,7 +5087,7 @@ function FixtureCard({ card }) {
|
|
|
4916
5087
|
}
|
|
4917
5088
|
|
|
4918
5089
|
// src/components/dashboard/CountdownCard.tsx
|
|
4919
|
-
var
|
|
5090
|
+
var import_react33 = require("react");
|
|
4920
5091
|
var import_jsx_runtime25 = require("react/jsx-runtime");
|
|
4921
5092
|
var DAY_MS = 864e5;
|
|
4922
5093
|
function remainingSegments(kickoffUnix, nowMs, withSeconds) {
|
|
@@ -4935,12 +5106,12 @@ function remainingSegments(kickoffUnix, nowMs, withSeconds) {
|
|
|
4935
5106
|
function CountdownCard({ card }) {
|
|
4936
5107
|
const { data } = card;
|
|
4937
5108
|
const unitLabel = { d: data.daysUnit, h: data.hoursUnit, m: data.minutesUnit, s: data.secondsUnit };
|
|
4938
|
-
const [nowMs, setNowMs] = (0,
|
|
4939
|
-
const [reduced] = (0,
|
|
5109
|
+
const [nowMs, setNowMs] = (0, import_react33.useState)(() => Date.now());
|
|
5110
|
+
const [reduced] = (0, import_react33.useState)(
|
|
4940
5111
|
() => typeof window !== "undefined" && window.matchMedia("(prefers-reduced-motion: reduce)").matches
|
|
4941
5112
|
);
|
|
4942
5113
|
const withinDay = data.kickoffUnix * 1e3 - nowMs < DAY_MS;
|
|
4943
|
-
(0,
|
|
5114
|
+
(0, import_react33.useEffect)(() => {
|
|
4944
5115
|
if (reduced) return;
|
|
4945
5116
|
const id = window.setInterval(() => setNowMs(Date.now()), withinDay ? 1e3 : 6e4);
|
|
4946
5117
|
return () => window.clearInterval(id);
|
|
@@ -4948,7 +5119,7 @@ function CountdownCard({ card }) {
|
|
|
4948
5119
|
const segments = remainingSegments(data.kickoffUnix, nowMs, withinDay && !reduced);
|
|
4949
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: [
|
|
4950
5121
|
/* @__PURE__ */ (0, import_jsx_runtime25.jsx)("span", { className: "ss-w-fandash-eyebrow", children: card.title ?? "Kick-off in" }),
|
|
4951
|
-
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: [
|
|
4952
5123
|
i > 0 ? /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("span", { className: "ss-w-fandash-countdown-colon", children: ":" }) : null,
|
|
4953
5124
|
/* @__PURE__ */ (0, import_jsx_runtime25.jsxs)("span", { className: "ss-w-fandash-countdown-seg", children: [
|
|
4954
5125
|
/* @__PURE__ */ (0, import_jsx_runtime25.jsx)("span", { className: "ss-w-fandash-countdown-value", children: s.value }),
|
|
@@ -4959,7 +5130,7 @@ function CountdownCard({ card }) {
|
|
|
4959
5130
|
}
|
|
4960
5131
|
|
|
4961
5132
|
// src/components/dashboard/InjuriesCard.tsx
|
|
4962
|
-
var
|
|
5133
|
+
var import_react34 = require("react");
|
|
4963
5134
|
var import_jsx_runtime26 = require("react/jsx-runtime");
|
|
4964
5135
|
var SHOWN = 3;
|
|
4965
5136
|
function ColHead({ name, crestUrl }) {
|
|
@@ -4982,7 +5153,7 @@ function InjuryList({ rows, emptyLabel, limit }) {
|
|
|
4982
5153
|
}
|
|
4983
5154
|
function InjuriesCard({ card, ui }) {
|
|
4984
5155
|
const { data } = card;
|
|
4985
|
-
const [expanded, setExpanded] = (0,
|
|
5156
|
+
const [expanded, setExpanded] = (0, import_react34.useState)(false);
|
|
4986
5157
|
const hidden = Math.max(0, data.ours.length - SHOWN) + Math.max(0, data.theirs.length - SHOWN);
|
|
4987
5158
|
const limit = expanded ? void 0 : SHOWN;
|
|
4988
5159
|
const showMore = ui?.showMore ?? ((n) => `Show ${n} more`);
|
|
@@ -5088,7 +5259,7 @@ function LinksCard({ card }) {
|
|
|
5088
5259
|
}
|
|
5089
5260
|
|
|
5090
5261
|
// src/components/dashboard/PostMatchResultCard.tsx
|
|
5091
|
-
var
|
|
5262
|
+
var import_react35 = require("react");
|
|
5092
5263
|
var import_jsx_runtime32 = require("react/jsx-runtime");
|
|
5093
5264
|
function initials3(name) {
|
|
5094
5265
|
return name.trim().slice(0, 3).toUpperCase();
|
|
@@ -5098,7 +5269,7 @@ function PostMatchCrest({
|
|
|
5098
5269
|
name,
|
|
5099
5270
|
side
|
|
5100
5271
|
}) {
|
|
5101
|
-
const [failed, setFailed] = (0,
|
|
5272
|
+
const [failed, setFailed] = (0, import_react35.useState)(false);
|
|
5102
5273
|
const cls = `ss-w-fandash-postmatch-crest ss-w-fandash-postmatch-crest--${side}`;
|
|
5103
5274
|
if (url && !failed) {
|
|
5104
5275
|
return /* @__PURE__ */ (0, import_jsx_runtime32.jsx)("img", { className: cls, src: url, alt: "", "aria-hidden": "true", onError: () => setFailed(true) });
|
|
@@ -5297,10 +5468,10 @@ function RestingFormCard({ card }) {
|
|
|
5297
5468
|
}
|
|
5298
5469
|
|
|
5299
5470
|
// src/components/dashboard/LiveScoreCard.tsx
|
|
5300
|
-
var
|
|
5471
|
+
var import_react37 = require("react");
|
|
5301
5472
|
|
|
5302
5473
|
// src/useLiveClock.ts
|
|
5303
|
-
var
|
|
5474
|
+
var import_react36 = require("react");
|
|
5304
5475
|
var TICK_MS = 6e4;
|
|
5305
5476
|
var MAX_LIVE_TICK_MINUTES = 15;
|
|
5306
5477
|
function computeDisplayMinute(minute, clockRunning, receivedAtMs) {
|
|
@@ -5309,10 +5480,10 @@ function computeDisplayMinute(minute, clockRunning, receivedAtMs) {
|
|
|
5309
5480
|
return minute + Math.min(Math.max(0, elapsedMinutes), MAX_LIVE_TICK_MINUTES);
|
|
5310
5481
|
}
|
|
5311
5482
|
function useLiveClock(minute, clockRunning, receivedAtMs) {
|
|
5312
|
-
const [displayMinute, setDisplayMinute] = (0,
|
|
5483
|
+
const [displayMinute, setDisplayMinute] = (0, import_react36.useState)(
|
|
5313
5484
|
() => computeDisplayMinute(minute, clockRunning, receivedAtMs)
|
|
5314
5485
|
);
|
|
5315
|
-
(0,
|
|
5486
|
+
(0, import_react36.useEffect)(() => {
|
|
5316
5487
|
setDisplayMinute(computeDisplayMinute(minute, clockRunning, receivedAtMs));
|
|
5317
5488
|
if (!clockRunning) return;
|
|
5318
5489
|
const id = window.setInterval(() => {
|
|
@@ -5329,7 +5500,7 @@ function initials5(name) {
|
|
|
5329
5500
|
return name.trim().slice(0, 3).toUpperCase();
|
|
5330
5501
|
}
|
|
5331
5502
|
function LiveCrest({ url, name, side }) {
|
|
5332
|
-
const [failed, setFailed] = (0,
|
|
5503
|
+
const [failed, setFailed] = (0, import_react37.useState)(false);
|
|
5333
5504
|
const cls = `ss-w-fandash-live-crest ss-w-fandash-live-crest--${side}`;
|
|
5334
5505
|
if (url && !failed) {
|
|
5335
5506
|
return /* @__PURE__ */ (0, import_jsx_runtime41.jsx)("img", { className: cls, src: url, alt: "", "aria-hidden": "true", onError: () => setFailed(true) });
|
|
@@ -5348,7 +5519,7 @@ function LiveScoreCard({
|
|
|
5348
5519
|
}) {
|
|
5349
5520
|
const { data } = card;
|
|
5350
5521
|
const seedKey = `${data.minute}:${data.homeScore}:${data.awayScore}`;
|
|
5351
|
-
const seedRef = (0,
|
|
5522
|
+
const seedRef = (0, import_react37.useRef)(null);
|
|
5352
5523
|
if (!seedRef.current || seedRef.current.key !== seedKey) {
|
|
5353
5524
|
seedRef.current = { key: seedKey, receivedAtMs: Date.now() };
|
|
5354
5525
|
}
|
|
@@ -5388,7 +5559,7 @@ function LiveScoreCard({
|
|
|
5388
5559
|
}
|
|
5389
5560
|
|
|
5390
5561
|
// src/components/dashboard/LiveTimelineCard.tsx
|
|
5391
|
-
var
|
|
5562
|
+
var import_react38 = require("react");
|
|
5392
5563
|
var import_jsx_runtime42 = require("react/jsx-runtime");
|
|
5393
5564
|
var SHOWN2 = 3;
|
|
5394
5565
|
function EventIcon({ type }) {
|
|
@@ -5430,7 +5601,7 @@ function EventRow({ e }) {
|
|
|
5430
5601
|
] });
|
|
5431
5602
|
}
|
|
5432
5603
|
function LiveTimelineCard({ card, ui }) {
|
|
5433
|
-
const [expanded, setExpanded] = (0,
|
|
5604
|
+
const [expanded, setExpanded] = (0, import_react38.useState)(false);
|
|
5434
5605
|
const events = card.data.events;
|
|
5435
5606
|
if (!events || events.length === 0) return null;
|
|
5436
5607
|
const sorted = [...events].sort((a, b) => b.minute - a.minute);
|
|
@@ -5455,7 +5626,7 @@ function LiveTimelineCard({ card, ui }) {
|
|
|
5455
5626
|
}
|
|
5456
5627
|
|
|
5457
5628
|
// src/components/dashboard/MomentumWave.tsx
|
|
5458
|
-
var
|
|
5629
|
+
var import_react39 = require("react");
|
|
5459
5630
|
var import_jsx_runtime43 = require("react/jsx-runtime");
|
|
5460
5631
|
var WIDTH = 270;
|
|
5461
5632
|
var HEIGHT = 56;
|
|
@@ -5479,7 +5650,7 @@ function MomentumWave({
|
|
|
5479
5650
|
}) {
|
|
5480
5651
|
if (points.length === 0) return null;
|
|
5481
5652
|
const { area, line, lastLeftPct, lastTopPx } = buildPaths(points);
|
|
5482
|
-
const clipId = (0,
|
|
5653
|
+
const clipId = (0, import_react39.useId)();
|
|
5483
5654
|
const topClipId = `${clipId}-top`;
|
|
5484
5655
|
const bottomClipId = `${clipId}-bottom`;
|
|
5485
5656
|
const topClass = clubIsHome ? "ss-w-fandash-live-mom-home" : "ss-w-fandash-live-mom-away";
|
|
@@ -5672,11 +5843,11 @@ function turnAnchor(messages) {
|
|
|
5672
5843
|
}
|
|
5673
5844
|
function MessageList({ controller, ui, slip, onDashboardTap, monitor }) {
|
|
5674
5845
|
const { state, send } = controller;
|
|
5675
|
-
const listRef = (0,
|
|
5676
|
-
const endRef = (0,
|
|
5677
|
-
const pinnedRef = (0,
|
|
5678
|
-
const anchoredTurnRef = (0,
|
|
5679
|
-
(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)(() => {
|
|
5680
5851
|
const anchor = turnAnchor(state.messages);
|
|
5681
5852
|
const list = listRef.current;
|
|
5682
5853
|
if (anchor && anchor.turnId !== anchoredTurnRef.current) {
|
|
@@ -5733,13 +5904,13 @@ function MessageList({ controller, ui, slip, onDashboardTap, monitor }) {
|
|
|
5733
5904
|
}
|
|
5734
5905
|
|
|
5735
5906
|
// src/components/ChatInput.tsx
|
|
5736
|
-
var
|
|
5907
|
+
var import_react41 = require("react");
|
|
5737
5908
|
var import_jsx_runtime49 = require("react/jsx-runtime");
|
|
5738
|
-
var ChatInput = (0,
|
|
5739
|
-
const [value, setValue] = (0,
|
|
5740
|
-
const textareaRef = (0,
|
|
5741
|
-
const stopRef = (0,
|
|
5742
|
-
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);
|
|
5743
5914
|
const submit = () => {
|
|
5744
5915
|
if (disabled) return;
|
|
5745
5916
|
const t = value.trim();
|
|
@@ -5753,7 +5924,7 @@ var ChatInput = (0, import_react39.forwardRef)(function ChatInput2({ placeholder
|
|
|
5753
5924
|
submit();
|
|
5754
5925
|
}
|
|
5755
5926
|
};
|
|
5756
|
-
(0,
|
|
5927
|
+
(0, import_react41.useImperativeHandle)(ref, () => ({
|
|
5757
5928
|
focus() {
|
|
5758
5929
|
const box = textareaRef.current;
|
|
5759
5930
|
if (box && !box.disabled) {
|
|
@@ -5765,7 +5936,7 @@ var ChatInput = (0, import_react39.forwardRef)(function ChatInput2({ placeholder
|
|
|
5765
5936
|
stopRef.current?.focus();
|
|
5766
5937
|
}
|
|
5767
5938
|
}), []);
|
|
5768
|
-
(0,
|
|
5939
|
+
(0, import_react41.useEffect)(() => {
|
|
5769
5940
|
if (streaming || disabled || !textBoxWantsFocusRef.current) return;
|
|
5770
5941
|
textBoxWantsFocusRef.current = false;
|
|
5771
5942
|
const box = textareaRef.current;
|
|
@@ -5797,6 +5968,7 @@ var ChatInput = (0, import_react39.forwardRef)(function ChatInput2({ placeholder
|
|
|
5797
5968
|
});
|
|
5798
5969
|
|
|
5799
5970
|
// src/components/TabBar.tsx
|
|
5971
|
+
var import_react42 = require("react");
|
|
5800
5972
|
var import_jsx_runtime50 = require("react/jsx-runtime");
|
|
5801
5973
|
function TabBar({ monitor, ui, matchCount, oddsCount, todayCount, hasToday, gamesEnabled, clubEnabled }) {
|
|
5802
5974
|
const tabs = [
|
|
@@ -5812,8 +5984,16 @@ function TabBar({ monitor, ui, matchCount, oddsCount, todayCount, hasToday, game
|
|
|
5812
5984
|
],
|
|
5813
5985
|
...gamesEnabled ? [{ tab: "games", label: ui.tabGames, count: 0, dot: false }] : []
|
|
5814
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]);
|
|
5815
5995
|
if (tabs.length < 2) return null;
|
|
5816
|
-
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 }) => {
|
|
5817
5997
|
const active = monitor.activeTab === tab;
|
|
5818
5998
|
return /* @__PURE__ */ (0, import_jsx_runtime50.jsxs)(
|
|
5819
5999
|
"button",
|
|
@@ -5890,10 +6070,10 @@ function MarketAccordion({ match, monitor, ui, slip }) {
|
|
|
5890
6070
|
}
|
|
5891
6071
|
|
|
5892
6072
|
// src/components/LiveFactBlock.tsx
|
|
5893
|
-
var
|
|
6073
|
+
var import_react43 = require("react");
|
|
5894
6074
|
var import_jsx_runtime52 = require("react/jsx-runtime");
|
|
5895
6075
|
function LiveFactBlock({ facts, matchId, ui, slip, onAsk }) {
|
|
5896
|
-
const [expanded, setExpanded] = (0,
|
|
6076
|
+
const [expanded, setExpanded] = (0, import_react43.useState)(false);
|
|
5897
6077
|
const [current, ...earlier] = facts;
|
|
5898
6078
|
if (!current) return null;
|
|
5899
6079
|
const m = current.market;
|
|
@@ -6159,7 +6339,7 @@ function OddsPanel({ monitor, ui, slip }) {
|
|
|
6159
6339
|
}
|
|
6160
6340
|
|
|
6161
6341
|
// src/components/TodayPanel.tsx
|
|
6162
|
-
var
|
|
6342
|
+
var import_react47 = require("react");
|
|
6163
6343
|
|
|
6164
6344
|
// src/placement.ts
|
|
6165
6345
|
function placeLeagues(visible, pinnedMatchIds) {
|
|
@@ -6222,11 +6402,11 @@ function matchingFixtures(group, query) {
|
|
|
6222
6402
|
}
|
|
6223
6403
|
|
|
6224
6404
|
// src/useStarTap.ts
|
|
6225
|
-
var
|
|
6405
|
+
var import_react44 = require("react");
|
|
6226
6406
|
function useStarTap(starLeague) {
|
|
6227
|
-
const [pendingId, setPendingId] = (0,
|
|
6228
|
-
const pendingRef = (0,
|
|
6229
|
-
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) => {
|
|
6230
6410
|
if (pendingRef.current !== null) return false;
|
|
6231
6411
|
pendingRef.current = competitionId;
|
|
6232
6412
|
setPendingId(competitionId);
|
|
@@ -6285,7 +6465,7 @@ function LeagueTile({ group, starClickable: starClickable2, disambiguate, onOpen
|
|
|
6285
6465
|
}
|
|
6286
6466
|
|
|
6287
6467
|
// src/components/LeagueDetail.tsx
|
|
6288
|
-
var
|
|
6468
|
+
var import_react45 = require("react");
|
|
6289
6469
|
|
|
6290
6470
|
// src/components/FixtureRow.tsx
|
|
6291
6471
|
var import_jsx_runtime56 = require("react/jsx-runtime");
|
|
@@ -6320,11 +6500,11 @@ function FixtureRow({ match, state, stale, ui, monitor }) {
|
|
|
6320
6500
|
var import_jsx_runtime57 = require("react/jsx-runtime");
|
|
6321
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";
|
|
6322
6502
|
function LeagueDetail({ group, position, states, stale, ui, monitor, starTap, onBack, onPrev, onNext }) {
|
|
6323
|
-
const [toast, setToast] = (0,
|
|
6324
|
-
(0,
|
|
6503
|
+
const [toast, setToast] = (0, import_react45.useState)(null);
|
|
6504
|
+
(0, import_react45.useEffect)(() => {
|
|
6325
6505
|
setToast(null);
|
|
6326
6506
|
}, [group.competitionId]);
|
|
6327
|
-
(0,
|
|
6507
|
+
(0, import_react45.useEffect)(() => {
|
|
6328
6508
|
if (toast === null) return;
|
|
6329
6509
|
const id = setTimeout(() => setToast(null), 4e3);
|
|
6330
6510
|
return () => clearTimeout(id);
|
|
@@ -6456,7 +6636,7 @@ function LeagueRowGroup({ group, states, stale, cap, starClickable: starClickabl
|
|
|
6456
6636
|
}
|
|
6457
6637
|
|
|
6458
6638
|
// src/components/games/ui/SearchField.tsx
|
|
6459
|
-
var
|
|
6639
|
+
var import_react46 = require("react");
|
|
6460
6640
|
|
|
6461
6641
|
// src/components/games/ui/icons.tsx
|
|
6462
6642
|
var import_jsx_runtime59 = require("react/jsx-runtime");
|
|
@@ -6495,8 +6675,8 @@ var IconFlame = ({ size = 16 }) => svg(size, /* @__PURE__ */ (0, import_jsx_runt
|
|
|
6495
6675
|
// src/components/games/ui/SearchField.tsx
|
|
6496
6676
|
var import_jsx_runtime60 = require("react/jsx-runtime");
|
|
6497
6677
|
function SearchField({ id, label, labelHidden = false, placeholder, value, onChange, disabled, inputRef, onKeyDown, clearLabel }) {
|
|
6498
|
-
const localRef = (0,
|
|
6499
|
-
const setInputRef = (0,
|
|
6678
|
+
const localRef = (0, import_react46.useRef)(null);
|
|
6679
|
+
const setInputRef = (0, import_react46.useCallback)((node) => {
|
|
6500
6680
|
localRef.current = node;
|
|
6501
6681
|
if (typeof inputRef === "function") inputRef(node);
|
|
6502
6682
|
else if (inputRef) inputRef.current = node;
|
|
@@ -6540,23 +6720,23 @@ function SearchField({ id, label, labelHidden = false, placeholder, value, onCha
|
|
|
6540
6720
|
var import_jsx_runtime61 = require("react/jsx-runtime");
|
|
6541
6721
|
function TodayPanel({ discovery, ui, monitor }) {
|
|
6542
6722
|
const { groups, states, stale, starLeague } = discovery;
|
|
6543
|
-
const searchId = (0,
|
|
6544
|
-
const [query, setQuery] = (0,
|
|
6545
|
-
const [selectedCompetitionId, setSelectedCompetitionId] = (0,
|
|
6546
|
-
const [toast, setToast] = (0,
|
|
6547
|
-
(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)(() => {
|
|
6548
6728
|
if (toast === null) return;
|
|
6549
6729
|
const id = setTimeout(() => setToast(null), 4e3);
|
|
6550
6730
|
return () => clearTimeout(id);
|
|
6551
6731
|
}, [toast]);
|
|
6552
6732
|
const visibleGroups = visibleGroupsOf(groups, states);
|
|
6553
|
-
const pinnedMatchIds = (0,
|
|
6733
|
+
const pinnedMatchIds = (0, import_react47.useMemo)(
|
|
6554
6734
|
() => monitor.pins.filter((p) => p.kind === "match").map((p) => p.matchId),
|
|
6555
6735
|
[monitor.pins]
|
|
6556
6736
|
);
|
|
6557
|
-
const placement = (0,
|
|
6737
|
+
const placement = (0, import_react47.useMemo)(() => placeLeagues(visibleGroups, pinnedMatchIds), [visibleGroups, pinnedMatchIds]);
|
|
6558
6738
|
const starTap = useStarTap(starLeague);
|
|
6559
|
-
const gridStarTap = (0,
|
|
6739
|
+
const gridStarTap = (0, import_react47.useMemo)(() => ({
|
|
6560
6740
|
pendingId: starTap.pendingId,
|
|
6561
6741
|
tap: async (competitionId, next) => {
|
|
6562
6742
|
const ok = await starTap.tap(competitionId, next);
|
|
@@ -6590,7 +6770,7 @@ function TodayPanel({ discovery, ui, monitor }) {
|
|
|
6590
6770
|
}
|
|
6591
6771
|
const openIndex = selectedCompetitionId === null ? -1 : placement.order.findIndex((g) => g.competitionId === selectedCompetitionId);
|
|
6592
6772
|
const openGroup = openIndex === -1 ? void 0 : placement.order[openIndex];
|
|
6593
|
-
(0,
|
|
6773
|
+
(0, import_react47.useEffect)(() => {
|
|
6594
6774
|
if (selectedCompetitionId !== null && openGroup === void 0) setSelectedCompetitionId(null);
|
|
6595
6775
|
}, [selectedCompetitionId, openGroup]);
|
|
6596
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);
|
|
@@ -6737,7 +6917,7 @@ function TodayPanel({ discovery, ui, monitor }) {
|
|
|
6737
6917
|
}
|
|
6738
6918
|
|
|
6739
6919
|
// src/components/GamesPanel.tsx
|
|
6740
|
-
var
|
|
6920
|
+
var import_react62 = require("react");
|
|
6741
6921
|
|
|
6742
6922
|
// src/components/GamesLoginWall.tsx
|
|
6743
6923
|
var import_jsx_runtime62 = require("react/jsx-runtime");
|
|
@@ -6746,7 +6926,7 @@ function GamesLoginWall({ ui }) {
|
|
|
6746
6926
|
}
|
|
6747
6927
|
|
|
6748
6928
|
// src/components/GamesHub.tsx
|
|
6749
|
-
var
|
|
6929
|
+
var import_react48 = require("react");
|
|
6750
6930
|
|
|
6751
6931
|
// src/components/games/ui/gameMeta.ts
|
|
6752
6932
|
function prettifyGameId(gameId) {
|
|
@@ -6897,8 +7077,8 @@ function pickHeroGame(games) {
|
|
|
6897
7077
|
}
|
|
6898
7078
|
var tileKey = (g) => `${g.gameId}-${g.gameDay}-${g.fixtureId}`;
|
|
6899
7079
|
function GamesHub({ games, myWeeklyRow, weeklyPrize, onOpen, ui }) {
|
|
6900
|
-
const [, setTick] = (0,
|
|
6901
|
-
(0,
|
|
7080
|
+
const [, setTick] = (0, import_react48.useState)(0);
|
|
7081
|
+
(0, import_react48.useEffect)(() => {
|
|
6902
7082
|
const id = setInterval(() => setTick((t) => t + 1), 6e4);
|
|
6903
7083
|
return () => clearInterval(id);
|
|
6904
7084
|
}, []);
|
|
@@ -6958,10 +7138,10 @@ function GamesHub({ games, myWeeklyRow, weeklyPrize, onOpen, ui }) {
|
|
|
6958
7138
|
}
|
|
6959
7139
|
|
|
6960
7140
|
// src/components/GameScreenHost.tsx
|
|
6961
|
-
var
|
|
7141
|
+
var import_react60 = require("react");
|
|
6962
7142
|
|
|
6963
7143
|
// src/useGamePlay.ts
|
|
6964
|
-
var
|
|
7144
|
+
var import_react49 = require("react");
|
|
6965
7145
|
function toSubmitResult(payload) {
|
|
6966
7146
|
return {
|
|
6967
7147
|
// 'pending' means the play is recorded but awaiting resolution (fixture games)
|
|
@@ -6973,17 +7153,17 @@ function toSubmitResult(payload) {
|
|
|
6973
7153
|
};
|
|
6974
7154
|
}
|
|
6975
7155
|
function useGamePlay(conversation, { gameId, gameDay, fixtureId, locale, refresh }) {
|
|
6976
|
-
const [result, setResult] = (0,
|
|
6977
|
-
const [submitting, setSubmitting] = (0,
|
|
6978
|
-
const [rawStatus, setRawStatus] = (0,
|
|
6979
|
-
const inFlightRef = (0,
|
|
6980
|
-
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);
|
|
6981
7161
|
convRef.current = conversation;
|
|
6982
|
-
const optsRef = (0,
|
|
7162
|
+
const optsRef = (0, import_react49.useRef)({ gameId, gameDay, fixtureId, locale, refresh });
|
|
6983
7163
|
optsRef.current = { gameId, gameDay, fixtureId, locale, refresh };
|
|
6984
|
-
const resultRef = (0,
|
|
7164
|
+
const resultRef = (0, import_react49.useRef)(null);
|
|
6985
7165
|
resultRef.current = result;
|
|
6986
|
-
const refetch = (0,
|
|
7166
|
+
const refetch = (0, import_react49.useCallback)(async () => {
|
|
6987
7167
|
const conv = convRef.current;
|
|
6988
7168
|
if (!conv) return;
|
|
6989
7169
|
const opts = optsRef.current;
|
|
@@ -6999,7 +7179,7 @@ function useGamePlay(conversation, { gameId, gameDay, fixtureId, locale, refresh
|
|
|
6999
7179
|
} catch {
|
|
7000
7180
|
}
|
|
7001
7181
|
}, []);
|
|
7002
|
-
const submit = (0,
|
|
7182
|
+
const submit = (0, import_react49.useCallback)(async (answerJson) => {
|
|
7003
7183
|
const conv = convRef.current;
|
|
7004
7184
|
if (!conv || inFlightRef.current) return;
|
|
7005
7185
|
inFlightRef.current = true;
|
|
@@ -7026,14 +7206,14 @@ function useGamePlay(conversation, { gameId, gameDay, fixtureId, locale, refresh
|
|
|
7026
7206
|
setSubmitting(false);
|
|
7027
7207
|
}
|
|
7028
7208
|
}, [refetch]);
|
|
7029
|
-
const hydrate = (0,
|
|
7209
|
+
const hydrate = (0, import_react49.useCallback)(() => {
|
|
7030
7210
|
void refetch();
|
|
7031
7211
|
}, [refetch]);
|
|
7032
7212
|
return { result, submitting, submit, hydrate, rawStatus };
|
|
7033
7213
|
}
|
|
7034
7214
|
|
|
7035
7215
|
// src/components/games/MysteryTigerGame.tsx
|
|
7036
|
-
var
|
|
7216
|
+
var import_react51 = require("react");
|
|
7037
7217
|
|
|
7038
7218
|
// src/components/games/nationFlags.ts
|
|
7039
7219
|
var FLAGS = {
|
|
@@ -7244,7 +7424,7 @@ function isNationCode(flag) {
|
|
|
7244
7424
|
}
|
|
7245
7425
|
|
|
7246
7426
|
// src/components/games/PlayerAvatar.tsx
|
|
7247
|
-
var
|
|
7427
|
+
var import_react50 = require("react");
|
|
7248
7428
|
var import_jsx_runtime67 = require("react/jsx-runtime");
|
|
7249
7429
|
function initialsOf(name) {
|
|
7250
7430
|
const parts = name.trim().split(/\s+/).filter(Boolean);
|
|
@@ -7262,7 +7442,7 @@ function PlayerAvatar({
|
|
|
7262
7442
|
imagePath,
|
|
7263
7443
|
className
|
|
7264
7444
|
}) {
|
|
7265
|
-
const [failed, setFailed] = (0,
|
|
7445
|
+
const [failed, setFailed] = (0, import_react50.useState)(false);
|
|
7266
7446
|
const showImage = Boolean(imagePath) && !isPlaceholderImage(imagePath) && !failed;
|
|
7267
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) }) });
|
|
7268
7448
|
}
|
|
@@ -7503,8 +7683,8 @@ function MysteryTigerGame({
|
|
|
7503
7683
|
onBack
|
|
7504
7684
|
}) {
|
|
7505
7685
|
const t = ui.games.mysteryTiger;
|
|
7506
|
-
const [query, setQuery] = (0,
|
|
7507
|
-
const inputId = (0,
|
|
7686
|
+
const [query, setQuery] = (0, import_react51.useState)("");
|
|
7687
|
+
const inputId = (0, import_react51.useId)();
|
|
7508
7688
|
const clientState = parseClientState(result?.clientStateJson);
|
|
7509
7689
|
const guessResults = clientState?.guessResults ?? [];
|
|
7510
7690
|
const alreadyGuessedIds = new Set(guessResults.map((g) => g.playerId));
|
|
@@ -7765,13 +7945,13 @@ function HigherOrLowerGame({
|
|
|
7765
7945
|
}
|
|
7766
7946
|
|
|
7767
7947
|
// src/components/games/CareerPathGame.tsx
|
|
7768
|
-
var
|
|
7948
|
+
var import_react53 = require("react");
|
|
7769
7949
|
|
|
7770
7950
|
// src/components/games/ui/CrestShield.tsx
|
|
7771
|
-
var
|
|
7951
|
+
var import_react52 = require("react");
|
|
7772
7952
|
var import_jsx_runtime78 = require("react/jsx-runtime");
|
|
7773
7953
|
function CrestShield({ src, name, size = 28 }) {
|
|
7774
|
-
const [failed, setFailed] = (0,
|
|
7954
|
+
const [failed, setFailed] = (0, import_react52.useState)(false);
|
|
7775
7955
|
if (src && !isPlaceholderImage(src) && !failed) {
|
|
7776
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) });
|
|
7777
7957
|
}
|
|
@@ -7803,8 +7983,8 @@ function CareerPathGame({
|
|
|
7803
7983
|
}) {
|
|
7804
7984
|
const s = ui.games.careerPath;
|
|
7805
7985
|
const title = gameTitle({ gameId: "career-path" }, ui.games.titles);
|
|
7806
|
-
const [query, setQuery] = (0,
|
|
7807
|
-
const inputId = (0,
|
|
7986
|
+
const [query, setQuery] = (0, import_react53.useState)("");
|
|
7987
|
+
const inputId = (0, import_react53.useId)();
|
|
7808
7988
|
const clientState = parseClientState3(result?.clientStateJson);
|
|
7809
7989
|
const alreadyGuessedIds = new Set(clientState?.guessResults.map((g) => g.playerId) ?? []);
|
|
7810
7990
|
const isOver = result?.alreadyPlayed === true || clientState?.solved === true || clientState?.failed === true;
|
|
@@ -7910,7 +8090,7 @@ function CareerPathGame({
|
|
|
7910
8090
|
}
|
|
7911
8091
|
|
|
7912
8092
|
// src/components/games/BeatTheGridGame.tsx
|
|
7913
|
-
var
|
|
8093
|
+
var import_react54 = __toESM(require("react"), 1);
|
|
7914
8094
|
|
|
7915
8095
|
// src/components/games/ui/OptionList.tsx
|
|
7916
8096
|
var import_jsx_runtime80 = require("react/jsx-runtime");
|
|
@@ -7999,10 +8179,10 @@ function SearchSheet({
|
|
|
7999
8179
|
ui
|
|
8000
8180
|
}) {
|
|
8001
8181
|
const s = ui.games.beatTheGrid;
|
|
8002
|
-
const [query, setQuery] = (0,
|
|
8003
|
-
const inputId = (0,
|
|
8004
|
-
const inputRef = (0,
|
|
8005
|
-
(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)(() => {
|
|
8006
8186
|
inputRef.current?.focus();
|
|
8007
8187
|
}, [row, col]);
|
|
8008
8188
|
const filtered = playerPool.filter(
|
|
@@ -8067,7 +8247,7 @@ function BeatTheGridGame({
|
|
|
8067
8247
|
}) {
|
|
8068
8248
|
const s = ui.games.beatTheGrid;
|
|
8069
8249
|
const title = gameTitle({ gameId: "beat-the-grid" }, ui.games.titles);
|
|
8070
|
-
const [activeCell, setActiveCell] = (0,
|
|
8250
|
+
const [activeCell, setActiveCell] = (0, import_react54.useState)(null);
|
|
8071
8251
|
const clientState = parseClientState4(result?.clientStateJson);
|
|
8072
8252
|
const filledCells = clientState?.cells ?? [];
|
|
8073
8253
|
const isLocked2 = result?.alreadyPlayed === true || clientState?.isComplete === true;
|
|
@@ -8141,7 +8321,7 @@ function BeatTheGridGame({
|
|
|
8141
8321
|
/* @__PURE__ */ (0, import_jsx_runtime81.jsx)("span", { "aria-hidden": "true", children: abbr }),
|
|
8142
8322
|
/* @__PURE__ */ (0, import_jsx_runtime81.jsx)("span", { className: "ss-g-sr", children: rowLabel })
|
|
8143
8323
|
] });
|
|
8144
|
-
return /* @__PURE__ */ (0, import_jsx_runtime81.jsxs)(
|
|
8324
|
+
return /* @__PURE__ */ (0, import_jsx_runtime81.jsxs)(import_react54.default.Fragment, { children: [
|
|
8145
8325
|
/* @__PURE__ */ (0, import_jsx_runtime81.jsx)("div", { className: "ss-g-btg-rowhdr", "data-meta": rowMeta ? "true" : void 0, children: rowHeaderContent }),
|
|
8146
8326
|
cols.map((colLabel, colIdx) => {
|
|
8147
8327
|
const filled = findCellResult(filledCells, rowIdx, colIdx);
|
|
@@ -8222,7 +8402,7 @@ function BeatTheGridGame({
|
|
|
8222
8402
|
}
|
|
8223
8403
|
|
|
8224
8404
|
// src/components/games/GuessTheXiGame.tsx
|
|
8225
|
-
var
|
|
8405
|
+
var import_react55 = require("react");
|
|
8226
8406
|
|
|
8227
8407
|
// src/components/games/ui/PitchSvg.tsx
|
|
8228
8408
|
var import_jsx_runtime82 = require("react/jsx-runtime");
|
|
@@ -8311,8 +8491,8 @@ function GuessTheXiGame({
|
|
|
8311
8491
|
onBack
|
|
8312
8492
|
}) {
|
|
8313
8493
|
const t = ui.games.guessTheXi;
|
|
8314
|
-
const [query, setQuery] = (0,
|
|
8315
|
-
const inputId = (0,
|
|
8494
|
+
const [query, setQuery] = (0, import_react55.useState)("");
|
|
8495
|
+
const inputId = (0, import_react55.useId)();
|
|
8316
8496
|
const clientState = parseClientState5(result?.clientStateJson);
|
|
8317
8497
|
const isOver = result?.alreadyPlayed === true || clientState?.status === "solved" || clientState?.status === "failed";
|
|
8318
8498
|
const solved = clientState?.status === "solved";
|
|
@@ -8454,7 +8634,7 @@ function GuessTheXiGame({
|
|
|
8454
8634
|
}
|
|
8455
8635
|
|
|
8456
8636
|
// src/components/games/DailyQuizGame.tsx
|
|
8457
|
-
var
|
|
8637
|
+
var import_react56 = require("react");
|
|
8458
8638
|
var import_jsx_runtime84 = require("react/jsx-runtime");
|
|
8459
8639
|
function parseClientState6(json) {
|
|
8460
8640
|
if (!json) return null;
|
|
@@ -8495,8 +8675,8 @@ function DailyQuizGame({
|
|
|
8495
8675
|
}) {
|
|
8496
8676
|
const s = ui.games.dailyQuiz;
|
|
8497
8677
|
const title = gameTitle({ gameId: "daily-quiz" }, ui.games.titles);
|
|
8498
|
-
const [selections, setSelections] = (0,
|
|
8499
|
-
const [page, setPage] = (0,
|
|
8678
|
+
const [selections, setSelections] = (0, import_react56.useState)(/* @__PURE__ */ new Map());
|
|
8679
|
+
const [page, setPage] = (0, import_react56.useState)(0);
|
|
8500
8680
|
const clientState = parseClientState6(result?.clientStateJson);
|
|
8501
8681
|
const results = clientState?.results ?? [];
|
|
8502
8682
|
const isRevealed = results.length > 0 || result?.alreadyPlayed === true;
|
|
@@ -8606,7 +8786,7 @@ function DailyQuizGame({
|
|
|
8606
8786
|
}
|
|
8607
8787
|
|
|
8608
8788
|
// src/components/games/MatchdayPredictorGame.tsx
|
|
8609
|
-
var
|
|
8789
|
+
var import_react57 = require("react");
|
|
8610
8790
|
var import_jsx_runtime85 = require("react/jsx-runtime");
|
|
8611
8791
|
var SCORER_SEARCH_THRESHOLD = 9;
|
|
8612
8792
|
function parseClientState7(json) {
|
|
@@ -8702,12 +8882,12 @@ function MatchdayPredictorGame({
|
|
|
8702
8882
|
onBack
|
|
8703
8883
|
}) {
|
|
8704
8884
|
const t = ui.games.predictor;
|
|
8705
|
-
const [homeScore, setHomeScore] = (0,
|
|
8706
|
-
const [awayScore, setAwayScore] = (0,
|
|
8707
|
-
const [firstScorerPlayerId, setFirstScorerPlayerId] = (0,
|
|
8708
|
-
const [lastEdited, setLastEdited] = (0,
|
|
8709
|
-
const [query, setQuery] = (0,
|
|
8710
|
-
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)();
|
|
8711
8891
|
const clientState = parseClientState7(result?.clientStateJson);
|
|
8712
8892
|
const alreadyPlayed = result?.alreadyPlayed === true;
|
|
8713
8893
|
const header = /* @__PURE__ */ (0, import_jsx_runtime85.jsx)(
|
|
@@ -8874,7 +9054,7 @@ function MatchdayPredictorGame({
|
|
|
8874
9054
|
}
|
|
8875
9055
|
|
|
8876
9056
|
// src/components/games/StartingXiGame.tsx
|
|
8877
|
-
var
|
|
9057
|
+
var import_react58 = require("react");
|
|
8878
9058
|
var import_jsx_runtime86 = require("react/jsx-runtime");
|
|
8879
9059
|
var POINTS_PER_STARTER = 8;
|
|
8880
9060
|
var XI_SIZE = 11;
|
|
@@ -8918,10 +9098,10 @@ function StartingXiGame({
|
|
|
8918
9098
|
lockAtUtc
|
|
8919
9099
|
}) {
|
|
8920
9100
|
const t = ui.games.startingXi;
|
|
8921
|
-
const [slotPlayers, setSlotPlayers] = (0,
|
|
8922
|
-
const [active, setActive] = (0,
|
|
8923
|
-
const [query, setQuery] = (0,
|
|
8924
|
-
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)();
|
|
8925
9105
|
const clientState = parseClientState8(result?.clientStateJson);
|
|
8926
9106
|
const alreadyPlayed = result?.alreadyPlayed === true;
|
|
8927
9107
|
const header = /* @__PURE__ */ (0, import_jsx_runtime86.jsx)(
|
|
@@ -9060,7 +9240,7 @@ function StartingXiGame({
|
|
|
9060
9240
|
}
|
|
9061
9241
|
|
|
9062
9242
|
// src/components/games/StatLadderGame.tsx
|
|
9063
|
-
var
|
|
9243
|
+
var import_react59 = require("react");
|
|
9064
9244
|
var import_jsx_runtime87 = require("react/jsx-runtime");
|
|
9065
9245
|
function ladderClue(ladder) {
|
|
9066
9246
|
const mystery = ladder.find((r) => r.rank === 2);
|
|
@@ -9097,9 +9277,9 @@ function StatLadderGame({
|
|
|
9097
9277
|
onBack
|
|
9098
9278
|
}) {
|
|
9099
9279
|
const t = ui.games.statLadder;
|
|
9100
|
-
const [query, setQuery] = (0,
|
|
9101
|
-
const [selectedId, setSelectedId] = (0,
|
|
9102
|
-
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)();
|
|
9103
9283
|
const clientState = parseClientState9(result?.clientStateJson);
|
|
9104
9284
|
const revealed = clientState != null;
|
|
9105
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 });
|
|
@@ -9305,8 +9485,8 @@ function GameScreenHost({
|
|
|
9305
9485
|
ui
|
|
9306
9486
|
}) {
|
|
9307
9487
|
const { gameId, fixtureId, gameDay = "", lockAtUtc = null } = selected;
|
|
9308
|
-
const [configJson, setConfigJson] = (0,
|
|
9309
|
-
(0,
|
|
9488
|
+
const [configJson, setConfigJson] = (0, import_react60.useState)(null);
|
|
9489
|
+
(0, import_react60.useEffect)(() => {
|
|
9310
9490
|
setConfigJson(null);
|
|
9311
9491
|
if (!conversation) return;
|
|
9312
9492
|
let cancelled = false;
|
|
@@ -9329,12 +9509,12 @@ function GameScreenHost({
|
|
|
9329
9509
|
fixtureId: fixtureId || void 0,
|
|
9330
9510
|
locale: ui.games.lang
|
|
9331
9511
|
});
|
|
9332
|
-
(0,
|
|
9512
|
+
(0, import_react60.useEffect)(() => {
|
|
9333
9513
|
if (conversation) hydrate();
|
|
9334
9514
|
}, [conversation, gameId]);
|
|
9335
|
-
const hydrateRef = (0,
|
|
9515
|
+
const hydrateRef = (0, import_react60.useRef)(hydrate);
|
|
9336
9516
|
hydrateRef.current = hydrate;
|
|
9337
|
-
(0,
|
|
9517
|
+
(0, import_react60.useEffect)(() => {
|
|
9338
9518
|
if (!FIXTURE_GAME_IDS.has(gameId)) return;
|
|
9339
9519
|
if (rawStatus !== "pending") return;
|
|
9340
9520
|
const timerId = setInterval(() => {
|
|
@@ -9447,7 +9627,7 @@ function GameScreenHost({
|
|
|
9447
9627
|
}
|
|
9448
9628
|
|
|
9449
9629
|
// src/components/Leaderboard.tsx
|
|
9450
|
-
var
|
|
9630
|
+
var import_react61 = require("react");
|
|
9451
9631
|
|
|
9452
9632
|
// src/components/LeaderboardRow.tsx
|
|
9453
9633
|
var import_jsx_runtime90 = require("react/jsx-runtime");
|
|
@@ -9532,7 +9712,7 @@ function Leaderboard({
|
|
|
9532
9712
|
ui,
|
|
9533
9713
|
onPlay
|
|
9534
9714
|
}) {
|
|
9535
|
-
const [segment, setSegment] = (0,
|
|
9715
|
+
const [segment, setSegment] = (0, import_react61.useState)("weekly");
|
|
9536
9716
|
const myRow = segment === "weekly" ? data.myWeeklyRow : data.myAllTimeRow;
|
|
9537
9717
|
const offBoard = myRow !== null && myRow !== void 0 && myRow.rank === -1;
|
|
9538
9718
|
const isEmpty = segment === "weekly" ? data.weeklyTop.length === 0 : data.allTimeTop.length === 0;
|
|
@@ -9635,9 +9815,9 @@ function GamesPanel({
|
|
|
9635
9815
|
leaderboardLoading,
|
|
9636
9816
|
refreshHub
|
|
9637
9817
|
}) {
|
|
9638
|
-
const [selected, setSelected] = (0,
|
|
9639
|
-
const [segment, setSegment] = (0,
|
|
9640
|
-
(0,
|
|
9818
|
+
const [selected, setSelected] = (0, import_react62.useState)(null);
|
|
9819
|
+
const [segment, setSegment] = (0, import_react62.useState)("play");
|
|
9820
|
+
(0, import_react62.useEffect)(() => {
|
|
9641
9821
|
ensureGamesFonts();
|
|
9642
9822
|
}, []);
|
|
9643
9823
|
if (!loggedIn) return /* @__PURE__ */ (0, import_jsx_runtime94.jsx)(GamesLoginWall, { ui });
|
|
@@ -9785,8 +9965,7 @@ function Standings({ standings, loading, ui }) {
|
|
|
9785
9965
|
] }, `${gi}-${group.table ?? "none"}`)) });
|
|
9786
9966
|
}
|
|
9787
9967
|
|
|
9788
|
-
// src/components/
|
|
9789
|
-
var import_jsx_runtime97 = require("react/jsx-runtime");
|
|
9968
|
+
// src/components/groupByPosition.ts
|
|
9790
9969
|
function groupByPosition(players) {
|
|
9791
9970
|
const groups = [];
|
|
9792
9971
|
for (const p of players) {
|
|
@@ -9796,26 +9975,181 @@ function groupByPosition(players) {
|
|
|
9796
9975
|
}
|
|
9797
9976
|
return groups;
|
|
9798
9977
|
}
|
|
9799
|
-
|
|
9800
|
-
|
|
9801
|
-
|
|
9802
|
-
|
|
9803
|
-
|
|
9804
|
-
|
|
9805
|
-
|
|
9806
|
-
|
|
9807
|
-
|
|
9808
|
-
|
|
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
|
+
}
|
|
9809
10007
|
}
|
|
9810
10008
|
|
|
9811
|
-
// src/components/
|
|
9812
|
-
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
|
|
9813
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");
|
|
9814
10148
|
function PresetSpeedDial({ expanded, showDot, strings, onToggle, onOpen, rootRef, buttonRef }) {
|
|
9815
|
-
const pillsId = (0,
|
|
10149
|
+
const pillsId = (0, import_react63.useId)();
|
|
9816
10150
|
const tabIndex = expanded ? 0 : -1;
|
|
9817
|
-
return /* @__PURE__ */ (0,
|
|
9818
|
-
/* @__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)(
|
|
9819
10153
|
"button",
|
|
9820
10154
|
{
|
|
9821
10155
|
ref: buttonRef,
|
|
@@ -9826,36 +10160,36 @@ function PresetSpeedDial({ expanded, showDot, strings, onToggle, onOpen, rootRef
|
|
|
9826
10160
|
"aria-label": strings.dialName,
|
|
9827
10161
|
onClick: onToggle,
|
|
9828
10162
|
children: [
|
|
9829
|
-
/* @__PURE__ */ (0,
|
|
9830
|
-
/* @__PURE__ */ (0,
|
|
9831
|
-
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
|
|
9832
10166
|
]
|
|
9833
10167
|
}
|
|
9834
10168
|
),
|
|
9835
|
-
/* @__PURE__ */ (0,
|
|
9836
|
-
/* @__PURE__ */ (0,
|
|
9837
|
-
/* @__PURE__ */ (0,
|
|
9838
|
-
/* @__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 })
|
|
9839
10173
|
] }),
|
|
9840
|
-
/* @__PURE__ */ (0,
|
|
9841
|
-
/* @__PURE__ */ (0,
|
|
9842
|
-
/* @__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 })
|
|
9843
10177
|
] })
|
|
9844
10178
|
] })
|
|
9845
10179
|
] });
|
|
9846
10180
|
}
|
|
9847
10181
|
|
|
9848
10182
|
// src/components/PresetTools.tsx
|
|
9849
|
-
var
|
|
9850
|
-
var
|
|
10183
|
+
var import_react64 = require("react");
|
|
10184
|
+
var import_jsx_runtime101 = require("react/jsx-runtime");
|
|
9851
10185
|
var FOCUSABLE = 'button:not([disabled]), [href], input:not([disabled]), textarea:not([disabled]), [tabindex]:not([tabindex="-1"])';
|
|
9852
10186
|
function PresetToolModal({ title, closeLabel, onClose, children, footer }) {
|
|
9853
|
-
const dialogRef = (0,
|
|
9854
|
-
const titleId = (0,
|
|
9855
|
-
(0,
|
|
10187
|
+
const dialogRef = (0, import_react64.useRef)(null);
|
|
10188
|
+
const titleId = (0, import_react64.useId)();
|
|
10189
|
+
(0, import_react64.useEffect)(() => {
|
|
9856
10190
|
dialogRef.current?.focus();
|
|
9857
10191
|
}, []);
|
|
9858
|
-
(0,
|
|
10192
|
+
(0, import_react64.useEffect)(() => {
|
|
9859
10193
|
const onKey = (e) => {
|
|
9860
10194
|
if (e.key !== "Escape") return;
|
|
9861
10195
|
e.stopPropagation();
|
|
@@ -9885,79 +10219,79 @@ function PresetToolModal({ title, closeLabel, onClose, children, footer }) {
|
|
|
9885
10219
|
first.focus();
|
|
9886
10220
|
}
|
|
9887
10221
|
};
|
|
9888
|
-
return /* @__PURE__ */ (0,
|
|
9889
|
-
/* @__PURE__ */ (0,
|
|
9890
|
-
/* @__PURE__ */ (0,
|
|
9891
|
-
/* @__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, {}) })
|
|
9892
10226
|
] }),
|
|
9893
|
-
/* @__PURE__ */ (0,
|
|
9894
|
-
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
|
|
9895
10229
|
] }) });
|
|
9896
10230
|
}
|
|
9897
10231
|
function fillTemplate(template, slots) {
|
|
9898
10232
|
return template.split(/(\{[a-z]+\})/).filter((part) => part !== "").map((part, i) => {
|
|
9899
10233
|
const key = /^\{([a-z]+)\}$/.exec(part)?.[1];
|
|
9900
|
-
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);
|
|
9901
10235
|
});
|
|
9902
10236
|
}
|
|
9903
10237
|
function NumberSelect({ current, choices: choices2, label, notToday, lockEmpty = true, onChoose }) {
|
|
9904
10238
|
const selected = Math.max(0, choices2.findIndex((c) => c.text === current));
|
|
9905
|
-
return /* @__PURE__ */ (0,
|
|
9906
|
-
/* @__PURE__ */ (0,
|
|
9907
|
-
/* @__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) => {
|
|
9908
10242
|
const c = choices2[Number(e.target.value)];
|
|
9909
10243
|
if (c) onChoose(c.value);
|
|
9910
|
-
}, 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)) })
|
|
9911
10245
|
] });
|
|
9912
10246
|
}
|
|
9913
10247
|
function ChoiceSelect({ currentIdx, sizeLabels, optionLabels, label, onChoose }) {
|
|
9914
10248
|
const sizeText = sizeLabels[currentIdx] ?? "";
|
|
9915
|
-
return /* @__PURE__ */ (0,
|
|
9916
|
-
/* @__PURE__ */ (0,
|
|
9917
|
-
/* @__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)) })
|
|
9918
10252
|
] });
|
|
9919
10253
|
}
|
|
9920
10254
|
function SendButton({ label, display, disabled, onClick }) {
|
|
9921
|
-
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 });
|
|
9922
10256
|
}
|
|
9923
10257
|
function PickList({ picks, formatKickoff }) {
|
|
9924
|
-
return /* @__PURE__ */ (0,
|
|
9925
|
-
/* @__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: [
|
|
9926
10260
|
p.homeTeamName,
|
|
9927
10261
|
" \u2013 ",
|
|
9928
10262
|
p.awayTeamName
|
|
9929
10263
|
] }),
|
|
9930
|
-
/* @__PURE__ */ (0,
|
|
10264
|
+
/* @__PURE__ */ (0, import_jsx_runtime101.jsxs)("span", { className: "ss-w-tool-pick-sel", children: [
|
|
9931
10265
|
p.marketLabel,
|
|
9932
10266
|
": ",
|
|
9933
10267
|
p.selectionLabel,
|
|
9934
10268
|
p.line ? ` ${p.line}` : ""
|
|
9935
10269
|
] }),
|
|
9936
|
-
/* @__PURE__ */ (0,
|
|
9937
|
-
/* @__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) })
|
|
9938
10272
|
] }, p.matchOddsId)) });
|
|
9939
10273
|
}
|
|
9940
10274
|
function ComboPreview({ cell, formatKickoff }) {
|
|
9941
|
-
return /* @__PURE__ */ (0,
|
|
9942
|
-
/* @__PURE__ */ (0,
|
|
9943
|
-
/* @__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 })
|
|
9944
10278
|
] });
|
|
9945
10279
|
}
|
|
9946
10280
|
function Unavailable({ text }) {
|
|
9947
|
-
return /* @__PURE__ */ (0,
|
|
10281
|
+
return /* @__PURE__ */ (0, import_jsx_runtime101.jsx)("p", { className: "ss-w-tool-unavailable", children: text });
|
|
9948
10282
|
}
|
|
9949
10283
|
function AskRow({ icon, ask, ready, send }) {
|
|
9950
|
-
return /* @__PURE__ */ (0,
|
|
9951
|
-
/* @__PURE__ */ (0,
|
|
9952
|
-
/* @__PURE__ */ (0,
|
|
9953
|
-
/* @__PURE__ */ (0,
|
|
9954
|
-
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
|
|
9955
10289
|
] }),
|
|
9956
10290
|
send
|
|
9957
10291
|
] });
|
|
9958
10292
|
}
|
|
9959
10293
|
function RoundSend({ label, display, disabled, onClick }) {
|
|
9960
|
-
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, {}) });
|
|
9961
10295
|
}
|
|
9962
10296
|
var BIG_COMBO = { total: 50, legs: 6 };
|
|
9963
10297
|
function SetNumbersTool({ grid, strings, streaming, onSend, onClose }) {
|
|
@@ -9966,15 +10300,15 @@ function SetNumbersTool({ grid, strings, streaming, onSend, onClose }) {
|
|
|
9966
10300
|
const totals = comboTotals(grid);
|
|
9967
10301
|
const legChoices = comboLegChoices(grid);
|
|
9968
10302
|
const count = FIXED_SINGLES_COUNT;
|
|
9969
|
-
const [maxPrice, setMaxPrice] = (0,
|
|
9970
|
-
const [minPrice, setMinPrice] = (0,
|
|
9971
|
-
const [start] = (0,
|
|
9972
|
-
const [total, setTotal] = (0,
|
|
9973
|
-
const [legs, setLegs] = (0,
|
|
9974
|
-
const [bigStart] = (0,
|
|
9975
|
-
const [bigTotal, setBigTotal] = (0,
|
|
9976
|
-
const [bigLegs, setBigLegs] = (0,
|
|
9977
|
-
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)("");
|
|
9978
10312
|
const maxCell = findSingles(grid.singles, maxPrice, count);
|
|
9979
10313
|
const minCell = findSingles(grid.singlesFrom, minPrice, count);
|
|
9980
10314
|
const comboCell = findCombo(grid, total, legs);
|
|
@@ -10018,95 +10352,95 @@ function SetNumbersTool({ grid, strings, streaming, onSend, onClose }) {
|
|
|
10018
10352
|
const totalChoices = totals.map((v) => ({ value: v, text: v.toFixed(1), available: legChoices.some((n) => !!findCombo(grid, v, n)) }));
|
|
10019
10353
|
const legChoicesFor = (t) => legChoices.map((n) => ({ value: n, text: String(n), available: !!findCombo(grid, t, n) }));
|
|
10020
10354
|
const markets = grid.markets ?? [];
|
|
10021
|
-
const [marketIdx, setMarketIdx] = (0,
|
|
10355
|
+
const [marketIdx, setMarketIdx] = (0, import_react64.useState)(0);
|
|
10022
10356
|
const marketCell = markets[marketIdx] ?? null;
|
|
10023
10357
|
const marketLabels = markets.map((c) => strings.marketShort(c.marketDeveloperName, c.marketLabel, c.selectionLabel ?? null));
|
|
10024
10358
|
const singlesReady = (cell) => cell ? strings.readyCount(cell.picks.length) : strings.unavailable;
|
|
10025
10359
|
const comboReady = (cell) => cell ? strings.readyAt(cell.combo.total) : strings.unavailable;
|
|
10026
|
-
return /* @__PURE__ */ (0,
|
|
10027
|
-
/* @__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)(
|
|
10028
10362
|
AskRow,
|
|
10029
10363
|
{
|
|
10030
10364
|
icon: "\u{1F3AF}",
|
|
10031
10365
|
ask: fillTemplate(strings.maxPriceRow, {
|
|
10032
10366
|
count: String(count),
|
|
10033
|
-
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 })
|
|
10034
10368
|
}),
|
|
10035
10369
|
ready: singlesReady(maxCell),
|
|
10036
|
-
send: /* @__PURE__ */ (0,
|
|
10370
|
+
send: /* @__PURE__ */ (0, import_jsx_runtime101.jsx)(RoundSend, { label: strings.send, display: strings.maxPriceDisplay(count, maxPrice), disabled: !maxCell || streaming, onClick: () => {
|
|
10037
10371
|
if (maxCell) onSend(maxPriceAsk(maxCell, strings));
|
|
10038
10372
|
} })
|
|
10039
10373
|
}
|
|
10040
10374
|
),
|
|
10041
|
-
/* @__PURE__ */ (0,
|
|
10375
|
+
/* @__PURE__ */ (0, import_jsx_runtime101.jsx)(
|
|
10042
10376
|
AskRow,
|
|
10043
10377
|
{
|
|
10044
10378
|
icon: "\u{1F4C8}",
|
|
10045
10379
|
ask: fillTemplate(strings.minPriceRow, {
|
|
10046
10380
|
count: String(count),
|
|
10047
|
-
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 })
|
|
10048
10382
|
}),
|
|
10049
10383
|
ready: singlesReady(minCell),
|
|
10050
|
-
send: /* @__PURE__ */ (0,
|
|
10384
|
+
send: /* @__PURE__ */ (0, import_jsx_runtime101.jsx)(RoundSend, { label: strings.send, display: strings.minPriceDisplay(count, minPrice), disabled: !minCell || streaming, onClick: () => {
|
|
10051
10385
|
if (minCell) onSend(minPriceAsk(minCell, strings));
|
|
10052
10386
|
} })
|
|
10053
10387
|
}
|
|
10054
10388
|
),
|
|
10055
|
-
/* @__PURE__ */ (0,
|
|
10389
|
+
/* @__PURE__ */ (0, import_jsx_runtime101.jsx)(
|
|
10056
10390
|
AskRow,
|
|
10057
10391
|
{
|
|
10058
10392
|
icon: "\u2728",
|
|
10059
10393
|
ask: fillTemplate(strings.comboRow, {
|
|
10060
|
-
legs: /* @__PURE__ */ (0,
|
|
10061
|
-
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 })
|
|
10062
10396
|
}),
|
|
10063
10397
|
ready: comboReady(comboCell),
|
|
10064
|
-
send: /* @__PURE__ */ (0,
|
|
10398
|
+
send: /* @__PURE__ */ (0, import_jsx_runtime101.jsx)(RoundSend, { label: strings.send, display: strings.comboDisplay(legs, total), disabled: !comboCell || streaming, onClick: () => {
|
|
10065
10399
|
if (comboCell) onSend(comboAsk(comboCell, strings));
|
|
10066
10400
|
} })
|
|
10067
10401
|
}
|
|
10068
10402
|
),
|
|
10069
|
-
/* @__PURE__ */ (0,
|
|
10403
|
+
/* @__PURE__ */ (0, import_jsx_runtime101.jsx)(
|
|
10070
10404
|
AskRow,
|
|
10071
10405
|
{
|
|
10072
10406
|
icon: "\u{1F3C6}",
|
|
10073
10407
|
ask: fillTemplate(strings.bigComboRow, {
|
|
10074
|
-
legs: /* @__PURE__ */ (0,
|
|
10075
|
-
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 })
|
|
10076
10410
|
}),
|
|
10077
10411
|
ready: comboReady(bigCell),
|
|
10078
|
-
send: /* @__PURE__ */ (0,
|
|
10412
|
+
send: /* @__PURE__ */ (0, import_jsx_runtime101.jsx)(RoundSend, { label: strings.send, display: strings.comboDisplay(bigLegs, bigTotal), disabled: !bigCell || streaming, onClick: () => {
|
|
10079
10413
|
if (bigCell) onSend(comboAsk(bigCell, strings));
|
|
10080
10414
|
} })
|
|
10081
10415
|
}
|
|
10082
10416
|
),
|
|
10083
|
-
markets.length > 0 && /* @__PURE__ */ (0,
|
|
10417
|
+
markets.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime101.jsx)(
|
|
10084
10418
|
AskRow,
|
|
10085
10419
|
{
|
|
10086
10420
|
icon: "\u26BD",
|
|
10087
10421
|
ask: fillTemplate(strings.marketRow, {
|
|
10088
|
-
market: /* @__PURE__ */ (0,
|
|
10422
|
+
market: /* @__PURE__ */ (0, import_jsx_runtime101.jsx)(ChoiceSelect, { currentIdx: marketIdx, sizeLabels: marketLabels, optionLabels: marketLabels, label: strings.marketName, onChoose: chooseMarket })
|
|
10089
10423
|
}),
|
|
10090
10424
|
ready: marketCell ? strings.readyCount(marketCell.count) : null,
|
|
10091
|
-
send: /* @__PURE__ */ (0,
|
|
10425
|
+
send: /* @__PURE__ */ (0, import_jsx_runtime101.jsx)(RoundSend, { label: strings.send, display: marketCell ? marketDisplay(marketCell, strings) : "", disabled: !marketCell || streaming, onClick: () => {
|
|
10092
10426
|
if (marketCell) onSend(marketAsk(marketCell, strings));
|
|
10093
10427
|
} })
|
|
10094
10428
|
}
|
|
10095
10429
|
),
|
|
10096
|
-
/* @__PURE__ */ (0,
|
|
10430
|
+
/* @__PURE__ */ (0, import_jsx_runtime101.jsx)("p", { className: "ss-w-vh", "aria-live": "polite", children: announcement })
|
|
10097
10431
|
] });
|
|
10098
10432
|
}
|
|
10099
10433
|
function BuildComboTool({ grid, strings, streaming, formatKickoff, initialTotal, initialLegs, onSend, onClose }) {
|
|
10100
10434
|
const totals = comboTotals(grid);
|
|
10101
10435
|
const legChoices = comboLegChoices(grid);
|
|
10102
|
-
const [start] = (0,
|
|
10103
|
-
const [total, setTotal] = (0,
|
|
10104
|
-
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)(() => {
|
|
10105
10439
|
if (initialTotal === void 0) return initialLegs !== void 0 ? clampLegs(legChoices, initialLegs) : start.legs;
|
|
10106
10440
|
const from = initialLegs !== void 0 ? clampLegs(legChoices, initialLegs) : startValue(legChoices, START.comboLegs);
|
|
10107
10441
|
return legsForTotal(grid, nearest(totals, initialTotal), from);
|
|
10108
10442
|
});
|
|
10109
|
-
const [announcement, setAnnouncement] = (0,
|
|
10443
|
+
const [announcement, setAnnouncement] = (0, import_react64.useState)("");
|
|
10110
10444
|
const cell = findCombo(grid, total, legs);
|
|
10111
10445
|
const minLegs = legChoices[0] ?? legs;
|
|
10112
10446
|
const maxLegs = legChoices[legChoices.length - 1] ?? legs;
|
|
@@ -10117,29 +10451,29 @@ function BuildComboTool({ grid, strings, streaming, formatKickoff, initialTotal,
|
|
|
10117
10451
|
const d = strings.comboDisplay(nextLegs, nextTotal);
|
|
10118
10452
|
setAnnouncement(findCombo(grid, nextTotal, nextLegs) ? d : `${d}. ${strings.unavailable}`);
|
|
10119
10453
|
};
|
|
10120
|
-
const footer = /* @__PURE__ */ (0,
|
|
10454
|
+
const footer = /* @__PURE__ */ (0, import_jsx_runtime101.jsx)(SendButton, { label: strings.send, display, disabled: !cell || streaming, onClick: () => {
|
|
10121
10455
|
if (cell) onSend(comboAsk(cell, strings));
|
|
10122
10456
|
} });
|
|
10123
|
-
return /* @__PURE__ */ (0,
|
|
10124
|
-
/* @__PURE__ */ (0,
|
|
10125
|
-
/* @__PURE__ */ (0,
|
|
10126
|
-
/* @__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)) })
|
|
10127
10461
|
] }),
|
|
10128
|
-
/* @__PURE__ */ (0,
|
|
10129
|
-
/* @__PURE__ */ (0,
|
|
10130
|
-
/* @__PURE__ */ (0,
|
|
10131
|
-
/* @__PURE__ */ (0,
|
|
10132
|
-
/* @__PURE__ */ (0,
|
|
10133
|
-
/* @__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: "+" })
|
|
10134
10468
|
] })
|
|
10135
10469
|
] }),
|
|
10136
|
-
cell ? /* @__PURE__ */ (0,
|
|
10137
|
-
/* @__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 })
|
|
10138
10472
|
] });
|
|
10139
10473
|
}
|
|
10140
10474
|
|
|
10141
10475
|
// src/usePresetDial.ts
|
|
10142
|
-
var
|
|
10476
|
+
var import_react65 = require("react");
|
|
10143
10477
|
function sendInFlight(messages, isStreaming) {
|
|
10144
10478
|
const last = messages[messages.length - 1];
|
|
10145
10479
|
return isStreaming && !!last && last.role === "assistant" && !last.done && !last.isGreeting;
|
|
@@ -10153,25 +10487,25 @@ function lastUserId(messages) {
|
|
|
10153
10487
|
}
|
|
10154
10488
|
var SCROLL_KEYS = /* @__PURE__ */ new Set(["ArrowUp", "ArrowDown", "PageUp", "PageDown", "Home", "End", " "]);
|
|
10155
10489
|
function usePresetDial({ layerRef, dialRef, dialButtonRef, messages, isStreaming, activeTab }) {
|
|
10156
|
-
const [expanded, setExpanded] = (0,
|
|
10157
|
-
const fold = (0,
|
|
10158
|
-
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), []);
|
|
10159
10493
|
const currentUserId = lastUserId(messages);
|
|
10160
|
-
const userIdRef = (0,
|
|
10161
|
-
(0,
|
|
10494
|
+
const userIdRef = (0, import_react65.useRef)(currentUserId);
|
|
10495
|
+
(0, import_react65.useEffect)(() => {
|
|
10162
10496
|
if (currentUserId === userIdRef.current) return;
|
|
10163
10497
|
userIdRef.current = currentUserId;
|
|
10164
10498
|
setExpanded(false);
|
|
10165
10499
|
}, [currentUserId]);
|
|
10166
|
-
const tabRef = (0,
|
|
10167
|
-
(0,
|
|
10500
|
+
const tabRef = (0, import_react65.useRef)(activeTab);
|
|
10501
|
+
(0, import_react65.useEffect)(() => {
|
|
10168
10502
|
if (activeTab === tabRef.current) return;
|
|
10169
10503
|
tabRef.current = activeTab;
|
|
10170
10504
|
setExpanded(false);
|
|
10171
10505
|
}, [activeTab]);
|
|
10172
|
-
const expandedRef = (0,
|
|
10506
|
+
const expandedRef = (0, import_react65.useRef)(expanded);
|
|
10173
10507
|
expandedRef.current = expanded;
|
|
10174
|
-
(0,
|
|
10508
|
+
(0, import_react65.useEffect)(() => {
|
|
10175
10509
|
const onEscape = (e) => {
|
|
10176
10510
|
const dial = dialRef.current;
|
|
10177
10511
|
if (e.key !== "Escape" || !dial || !e.composedPath().includes(dial)) return;
|
|
@@ -10184,7 +10518,7 @@ function usePresetDial({ layerRef, dialRef, dialButtonRef, messages, isStreaming
|
|
|
10184
10518
|
window.addEventListener("keydown", onEscape, true);
|
|
10185
10519
|
return () => window.removeEventListener("keydown", onEscape, true);
|
|
10186
10520
|
}, [dialRef, dialButtonRef]);
|
|
10187
|
-
(0,
|
|
10521
|
+
(0, import_react65.useEffect)(() => {
|
|
10188
10522
|
if (!expanded) return;
|
|
10189
10523
|
const layer = layerRef.current;
|
|
10190
10524
|
const inDial = (e) => {
|
|
@@ -10236,11 +10570,11 @@ function markToolSeen() {
|
|
|
10236
10570
|
}
|
|
10237
10571
|
|
|
10238
10572
|
// src/components/ChatPanel.tsx
|
|
10239
|
-
var
|
|
10573
|
+
var import_jsx_runtime102 = require("react/jsx-runtime");
|
|
10240
10574
|
var FULLSCREEN_QUERY = "(max-width: 639px)";
|
|
10241
10575
|
function useIsModal() {
|
|
10242
|
-
const [modal, setModal] = (0,
|
|
10243
|
-
(0,
|
|
10576
|
+
const [modal, setModal] = (0, import_react66.useState)(false);
|
|
10577
|
+
(0, import_react66.useEffect)(() => {
|
|
10244
10578
|
if (typeof window === "undefined" || typeof window.matchMedia !== "function") return;
|
|
10245
10579
|
const mql = window.matchMedia(FULLSCREEN_QUERY);
|
|
10246
10580
|
const sync = () => setModal(mql.matches);
|
|
@@ -10251,10 +10585,38 @@ function useIsModal() {
|
|
|
10251
10585
|
return modal;
|
|
10252
10586
|
}
|
|
10253
10587
|
var HIDDEN_LAYER_STYLE = { position: "absolute", inset: 0, visibility: "hidden", display: "flex", flexDirection: "column" };
|
|
10254
|
-
|
|
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 }) {
|
|
10255
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]);
|
|
10256
10618
|
const isModal = useIsModal();
|
|
10257
|
-
(0,
|
|
10619
|
+
(0, import_react66.useEffect)(() => {
|
|
10258
10620
|
const onKey = (e) => {
|
|
10259
10621
|
if (e.key === "Escape") close();
|
|
10260
10622
|
};
|
|
@@ -10270,19 +10632,19 @@ function ChatPanel({ controller, ui, slip, onDashboardTap, monitor, discovery, g
|
|
|
10270
10632
|
monitor?.setActiveTab("chat");
|
|
10271
10633
|
send(text, { grounding });
|
|
10272
10634
|
};
|
|
10273
|
-
(0,
|
|
10635
|
+
(0, import_react66.useEffect)(() => {
|
|
10274
10636
|
if (monitor && monitor.activeTab !== "chat" && state.isStreaming) monitor.markChatActivity();
|
|
10275
10637
|
}, [monitor, state.isStreaming, state.messages.length]);
|
|
10276
10638
|
const onChatTab = !monitor || monitor.activeTab === "chat";
|
|
10277
|
-
const layerRef = (0,
|
|
10278
|
-
const dialRef = (0,
|
|
10279
|
-
const dialButtonRef = (0,
|
|
10280
|
-
const inputRef = (0,
|
|
10281
|
-
const limitRef = (0,
|
|
10282
|
-
const typedSendRef = (0,
|
|
10283
|
-
const focusAfterCloseRef = (0,
|
|
10284
|
-
const [tool, setTool] = (0,
|
|
10285
|
-
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);
|
|
10286
10648
|
const dial = usePresetDial({
|
|
10287
10649
|
layerRef,
|
|
10288
10650
|
dialRef,
|
|
@@ -10294,53 +10656,53 @@ function ChatPanel({ controller, ui, slip, onDashboardTap, monitor, discovery, g
|
|
|
10294
10656
|
const { fold } = dial;
|
|
10295
10657
|
const paused = isPaused(state.limit);
|
|
10296
10658
|
const showDial = !!presetGrid && onChatTab && !tool && !paused;
|
|
10297
|
-
(0,
|
|
10659
|
+
(0, import_react66.useEffect)(() => {
|
|
10298
10660
|
if (paused) setTool(null);
|
|
10299
10661
|
}, [paused]);
|
|
10300
|
-
(0,
|
|
10662
|
+
(0, import_react66.useEffect)(() => {
|
|
10301
10663
|
if (!paused) return;
|
|
10302
10664
|
if (typedSendRef.current) limitRef.current?.focus();
|
|
10303
10665
|
typedSendRef.current = false;
|
|
10304
10666
|
}, [paused]);
|
|
10305
|
-
const openTool = (0,
|
|
10667
|
+
const openTool = (0, import_react66.useCallback)((next) => {
|
|
10306
10668
|
fold();
|
|
10307
10669
|
markToolSeen();
|
|
10308
10670
|
setToolSeen(true);
|
|
10309
10671
|
setTool(next);
|
|
10310
10672
|
}, [fold]);
|
|
10311
|
-
const onPill = (0,
|
|
10312
|
-
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)(
|
|
10313
10675
|
() => presetGrid && !paused ? { openBuilder: (total, legs) => openTool({ kind: "combo", total, legs }), changeLabel: ui.presets.changeCombo } : null,
|
|
10314
10676
|
[presetGrid, paused, openTool, ui.presets.changeCombo]
|
|
10315
10677
|
);
|
|
10316
|
-
const closeTool = (0,
|
|
10678
|
+
const closeTool = (0, import_react66.useCallback)(() => {
|
|
10317
10679
|
focusAfterCloseRef.current = "dial";
|
|
10318
10680
|
setTool(null);
|
|
10319
10681
|
}, []);
|
|
10320
|
-
const sendAsk = (0,
|
|
10682
|
+
const sendAsk = (0, import_react66.useCallback)((ask) => {
|
|
10321
10683
|
focusAfterCloseRef.current = "composer";
|
|
10322
10684
|
setTool(null);
|
|
10323
10685
|
monitor?.setActiveTab("chat");
|
|
10324
10686
|
send(ask.message, { displayText: ask.displayText, preset: ask.preset });
|
|
10325
10687
|
}, [monitor, send]);
|
|
10326
|
-
const formatKickoff = (0,
|
|
10688
|
+
const formatKickoff = (0, import_react66.useCallback)((kickoffUtc) => {
|
|
10327
10689
|
const k = ui.bettingKickoff(kickoffUtc);
|
|
10328
10690
|
return `${k.dayLabel} ${k.time}`;
|
|
10329
10691
|
}, [ui]);
|
|
10330
|
-
(0,
|
|
10692
|
+
(0, import_react66.useEffect)(() => {
|
|
10331
10693
|
if (tool) return;
|
|
10332
10694
|
const target = focusAfterCloseRef.current;
|
|
10333
10695
|
focusAfterCloseRef.current = null;
|
|
10334
10696
|
if (target === "dial") dialButtonRef.current?.focus();
|
|
10335
10697
|
else if (target === "composer") inputRef.current?.focus();
|
|
10336
10698
|
}, [tool]);
|
|
10337
|
-
(0,
|
|
10699
|
+
(0, import_react66.useEffect)(() => {
|
|
10338
10700
|
if (!tool || onChatTab && presetGrid) return;
|
|
10339
10701
|
focusAfterCloseRef.current = "composer";
|
|
10340
10702
|
setTool(null);
|
|
10341
10703
|
}, [tool, onChatTab, presetGrid]);
|
|
10342
|
-
return /* @__PURE__ */ (0,
|
|
10343
|
-
/* @__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)(
|
|
10344
10706
|
ChatHeader,
|
|
10345
10707
|
{
|
|
10346
10708
|
onClose: close,
|
|
@@ -10353,7 +10715,7 @@ function ChatPanel({ controller, ui, slip, onDashboardTap, monitor, discovery, g
|
|
|
10353
10715
|
moreOptionsLabel: ui.moreOptions
|
|
10354
10716
|
}
|
|
10355
10717
|
),
|
|
10356
|
-
monitor && /* @__PURE__ */ (0,
|
|
10718
|
+
monitor && /* @__PURE__ */ (0, import_jsx_runtime102.jsx)(
|
|
10357
10719
|
TabBar,
|
|
10358
10720
|
{
|
|
10359
10721
|
monitor,
|
|
@@ -10366,9 +10728,9 @@ function ChatPanel({ controller, ui, slip, onDashboardTap, monitor, discovery, g
|
|
|
10366
10728
|
clubEnabled: clubFixturesResult?.enabled ?? false
|
|
10367
10729
|
}
|
|
10368
10730
|
),
|
|
10369
|
-
/* @__PURE__ */ (0,
|
|
10370
|
-
/* @__PURE__ */ (0,
|
|
10371
|
-
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)(
|
|
10372
10734
|
PresetSpeedDial,
|
|
10373
10735
|
{
|
|
10374
10736
|
expanded: dial.expanded,
|
|
@@ -10380,15 +10742,38 @@ function ChatPanel({ controller, ui, slip, onDashboardTap, monitor, discovery, g
|
|
|
10380
10742
|
buttonRef: dialButtonRef
|
|
10381
10743
|
}
|
|
10382
10744
|
) : null,
|
|
10383
|
-
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
|
|
10384
10746
|
] }),
|
|
10385
|
-
monitor && discovery && monitor.activeTab === "today" && /* @__PURE__ */ (0,
|
|
10386
|
-
monitor && monitor.activeTab === "following" && /* @__PURE__ */ (0,
|
|
10387
|
-
monitor && monitor.activeTab === "odds" && /* @__PURE__ */ (0,
|
|
10388
|
-
monitor && monitor.activeTab === "fixtures" && /* @__PURE__ */ (0,
|
|
10389
|
-
monitor && monitor.activeTab === "standings" && /* @__PURE__ */ (0,
|
|
10390
|
-
monitor && monitor.activeTab === "squad" && /* @__PURE__ */ (0,
|
|
10391
|
-
|
|
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)(
|
|
10392
10777
|
GamesPanel,
|
|
10393
10778
|
{
|
|
10394
10779
|
loggedIn: !!loggedIn,
|
|
@@ -10403,9 +10788,9 @@ function ChatPanel({ controller, ui, slip, onDashboardTap, monitor, discovery, g
|
|
|
10403
10788
|
}
|
|
10404
10789
|
}
|
|
10405
10790
|
),
|
|
10406
|
-
(!monitor || monitor.activeTab !== "games") && /* @__PURE__ */ (0,
|
|
10407
|
-
/* @__PURE__ */ (0,
|
|
10408
|
-
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)(
|
|
10409
10794
|
ChatInput,
|
|
10410
10795
|
{
|
|
10411
10796
|
ref: inputRef,
|
|
@@ -10424,9 +10809,9 @@ function ChatPanel({ controller, ui, slip, onDashboardTap, monitor, discovery, g
|
|
|
10424
10809
|
}
|
|
10425
10810
|
|
|
10426
10811
|
// src/components/HostEventsProvider.tsx
|
|
10427
|
-
var
|
|
10812
|
+
var import_jsx_runtime103 = require("react/jsx-runtime");
|
|
10428
10813
|
function HostEventsProvider({ value, children }) {
|
|
10429
|
-
return /* @__PURE__ */ (0,
|
|
10814
|
+
return /* @__PURE__ */ (0, import_jsx_runtime103.jsx)(SlipStateContext.Provider, { value: value.slipState, children });
|
|
10430
10815
|
}
|
|
10431
10816
|
|
|
10432
10817
|
// src/styles/css.generated.ts
|
|
@@ -11505,7 +11890,7 @@ var WIDGET_CSS = `.ss-w-root { all: revert; }
|
|
|
11505
11890
|
/* live monitor tab bar: underline pattern mirrors .ss-w-ecard-scope; the unread dot uses --ss-w-neg */
|
|
11506
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; }
|
|
11507
11892
|
.ss-w-tabs::-webkit-scrollbar { display: none; }
|
|
11508
|
-
.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; }
|
|
11509
11894
|
.ss-w-tab[data-on] { color: var(--ss-w-ink); border-bottom-color: var(--ss-w-accent); }
|
|
11510
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; }
|
|
11511
11896
|
.ss-w-tab[data-on] .ss-w-tab-count { color: var(--ss-w-accent); }
|
|
@@ -11587,6 +11972,28 @@ var WIDGET_CSS = `.ss-w-root { all: revert; }
|
|
|
11587
11972
|
.ss-w-sq-row { display: flex; align-items: center; gap: 10px; padding: 7px 2px; border-bottom: 1px solid var(--ss-w-line); }
|
|
11588
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); }
|
|
11589
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); }
|
|
11590
11997
|
/* Per-pin unavailable state: the pin's context line still rendered above (score, name, unpin), but
|
|
11591
11998
|
the pin has neither a card nor history (compose-time rescue failed) -- a small inline note beats
|
|
11592
11999
|
a bare context line with nothing under it. */
|
|
@@ -12190,7 +12597,7 @@ var WIDGET_CSS = `.ss-w-root { all: revert; }
|
|
|
12190
12597
|
`;
|
|
12191
12598
|
|
|
12192
12599
|
// src/StatsWidget.tsx
|
|
12193
|
-
var
|
|
12600
|
+
var import_jsx_runtime104 = require("react/jsx-runtime");
|
|
12194
12601
|
function buildClient(props) {
|
|
12195
12602
|
try {
|
|
12196
12603
|
if ("client" in props && props.client) {
|
|
@@ -12215,24 +12622,24 @@ function injectStyles(root) {
|
|
|
12215
12622
|
function StatsWidget(props) {
|
|
12216
12623
|
const injectedClient = "client" in props ? props.client : void 0;
|
|
12217
12624
|
const cfg = props.config;
|
|
12218
|
-
const built = (0,
|
|
12219
|
-
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)(
|
|
12220
12627
|
() => built ? built.client.createEventLogger({
|
|
12221
12628
|
operatorUserId: cfg?.userContext?.operatorUserId,
|
|
12222
12629
|
anonymousUserId: cfg?.userContext?.anonymousUserId
|
|
12223
12630
|
}) : null,
|
|
12224
12631
|
[built?.client]
|
|
12225
12632
|
);
|
|
12226
|
-
const ui = (0,
|
|
12227
|
-
const rootRef = (0,
|
|
12228
|
-
const introDoneRef = (0,
|
|
12229
|
-
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)(() => {
|
|
12230
12637
|
introDoneRef.current = true;
|
|
12231
12638
|
}, []);
|
|
12232
12639
|
const convStorageKey = `ss-w-conv:${cfg?.operatorId ?? ""}:${cfg?.userContext?.operatorUserId ?? "anon"}`;
|
|
12233
12640
|
const controller = useChatStream(built?.conversation ?? emptyConversation(), ui.starters, built ? ui.greetingMessage : void 0, convStorageKey);
|
|
12234
|
-
const [hasToday, setHasToday] = (0,
|
|
12235
|
-
const liveCardWatches = (0,
|
|
12641
|
+
const [hasToday, setHasToday] = (0, import_react67.useState)(false);
|
|
12642
|
+
const liveCardWatches = (0, import_react67.useMemo)(() => {
|
|
12236
12643
|
const seen = /* @__PURE__ */ new Set();
|
|
12237
12644
|
const out = [];
|
|
12238
12645
|
for (const msg of controller.state.messages) {
|
|
@@ -12258,19 +12665,19 @@ function StatsWidget(props) {
|
|
|
12258
12665
|
});
|
|
12259
12666
|
const operatorUserId = cfg?.userContext?.operatorUserId;
|
|
12260
12667
|
const anonymousUserId = cfg?.userContext?.anonymousUserId;
|
|
12261
|
-
const getSchedule = (0,
|
|
12668
|
+
const getSchedule = (0, import_react67.useCallback)(
|
|
12262
12669
|
(localDate, utcOffsetMinutes) => built ? built.conversation.getSchedule(localDate, utcOffsetMinutes, operatorUserId, anonymousUserId) : Promise.resolve(null),
|
|
12263
12670
|
[built, operatorUserId, anonymousUserId]
|
|
12264
12671
|
);
|
|
12265
|
-
const postLeagueStar = (0,
|
|
12672
|
+
const postLeagueStar = (0, import_react67.useCallback)(
|
|
12266
12673
|
(competitionId, starred) => built ? built.conversation.starLeague(competitionId, starred, operatorUserId, anonymousUserId) : Promise.resolve(null),
|
|
12267
12674
|
[built, operatorUserId, anonymousUserId]
|
|
12268
12675
|
);
|
|
12269
|
-
const getStates = (0,
|
|
12676
|
+
const getStates = (0, import_react67.useCallback)(
|
|
12270
12677
|
(matchIds) => built ? built.conversation.getStates(matchIds) : Promise.resolve(null),
|
|
12271
12678
|
[built]
|
|
12272
12679
|
);
|
|
12273
|
-
const pinnedMatchIds = (0,
|
|
12680
|
+
const pinnedMatchIds = (0, import_react67.useMemo)(
|
|
12274
12681
|
() => monitor.pins.filter((p) => p.kind === "match").map((p) => p.matchId),
|
|
12275
12682
|
[monitor.pins]
|
|
12276
12683
|
);
|
|
@@ -12285,11 +12692,11 @@ function StatsWidget(props) {
|
|
|
12285
12692
|
pinnedMatchIds
|
|
12286
12693
|
});
|
|
12287
12694
|
const todayHasContent = visibleGroupsOf(discovery.groups, discovery.states).length > 0;
|
|
12288
|
-
(0,
|
|
12695
|
+
(0, import_react67.useEffect)(() => {
|
|
12289
12696
|
setHasToday(todayHasContent);
|
|
12290
12697
|
}, [todayHasContent]);
|
|
12291
|
-
const prevLiveSnapshotRef = (0,
|
|
12292
|
-
(0,
|
|
12698
|
+
const prevLiveSnapshotRef = (0, import_react67.useRef)(monitor.snapshot);
|
|
12699
|
+
(0, import_react67.useEffect)(() => {
|
|
12293
12700
|
const snap = monitor.snapshot;
|
|
12294
12701
|
if (!snap || snap === prevLiveSnapshotRef.current) return;
|
|
12295
12702
|
prevLiveSnapshotRef.current = snap;
|
|
@@ -12327,14 +12734,16 @@ function StatsWidget(props) {
|
|
|
12327
12734
|
const leaderboardResult = useLeaderboard(built?.conversation ?? null, { activeTab: monitor.activeTab });
|
|
12328
12735
|
const clubStandingsResult = useClubStandings(built?.conversation ?? null, { activeTab: monitor.activeTab, enabled: clubFixturesResult.enabled });
|
|
12329
12736
|
const clubSquadResult = useClubSquad(built?.conversation ?? null, { activeTab: monitor.activeTab, enabled: clubFixturesResult.enabled });
|
|
12330
|
-
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)(
|
|
12331
12740
|
(locale2) => built ? built.conversation.getPricePresets(locale2, { pool: "open" }) : Promise.resolve(null),
|
|
12332
12741
|
[built]
|
|
12333
12742
|
);
|
|
12334
12743
|
const presetGrid = usePresetGrid({ getPricePresets, isOpen: controller.state.isOpen, locale: ui.presets.lang });
|
|
12335
12744
|
const markTodayActivity = monitor.markTodayActivity;
|
|
12336
|
-
const prevLiveCountRef = (0,
|
|
12337
|
-
(0,
|
|
12745
|
+
const prevLiveCountRef = (0, import_react67.useRef)(0);
|
|
12746
|
+
(0, import_react67.useEffect)(() => {
|
|
12338
12747
|
const rose = prevLiveCountRef.current === 0 && discovery.liveCount > 0;
|
|
12339
12748
|
prevLiveCountRef.current = discovery.liveCount;
|
|
12340
12749
|
if (rose) markTodayActivity();
|
|
@@ -12348,7 +12757,7 @@ function StatsWidget(props) {
|
|
|
12348
12757
|
closePanel: controller.close
|
|
12349
12758
|
});
|
|
12350
12759
|
const markAdded = hostEvents.markAdded;
|
|
12351
|
-
const slip = (0,
|
|
12760
|
+
const slip = (0, import_react67.useMemo)(
|
|
12352
12761
|
() => {
|
|
12353
12762
|
const handler = props.config?.onAddToSlip;
|
|
12354
12763
|
return {
|
|
@@ -12367,7 +12776,7 @@ function StatsWidget(props) {
|
|
|
12367
12776
|
},
|
|
12368
12777
|
[props.config?.onAddToSlip, controller.state.conversationId, markAdded]
|
|
12369
12778
|
);
|
|
12370
|
-
const onDashboardTap = (0,
|
|
12779
|
+
const onDashboardTap = (0, import_react67.useMemo)(
|
|
12371
12780
|
() => built ? createDashboardTapSignal((input) => built.conversation.sendSignal(input), logger) : void 0,
|
|
12372
12781
|
[built, logger]
|
|
12373
12782
|
);
|
|
@@ -12384,11 +12793,11 @@ function StatsWidget(props) {
|
|
|
12384
12793
|
})
|
|
12385
12794
|
}));
|
|
12386
12795
|
const conversationId = controller.state.conversationId ?? void 0;
|
|
12387
|
-
(0,
|
|
12796
|
+
(0, import_react67.useEffect)(() => {
|
|
12388
12797
|
if (!logger) return;
|
|
12389
12798
|
logger.setIdentity({ operatorUserId, anonymousUserId, conversationId });
|
|
12390
12799
|
}, [logger, operatorUserId, anonymousUserId, conversationId]);
|
|
12391
|
-
(0,
|
|
12800
|
+
(0, import_react67.useEffect)(() => {
|
|
12392
12801
|
if (!logger) return;
|
|
12393
12802
|
logger.resume();
|
|
12394
12803
|
const onHide = () => {
|
|
@@ -12406,14 +12815,14 @@ function StatsWidget(props) {
|
|
|
12406
12815
|
logger.dispose();
|
|
12407
12816
|
};
|
|
12408
12817
|
}, [logger]);
|
|
12409
|
-
(0,
|
|
12818
|
+
(0, import_react67.useEffect)(() => {
|
|
12410
12819
|
if (!built || !ui.injectStyles) return;
|
|
12411
12820
|
const node = rootRef.current?.getRootNode();
|
|
12412
12821
|
if (node) injectStyles(node);
|
|
12413
12822
|
}, [built, ui.injectStyles]);
|
|
12414
12823
|
if (!built) return null;
|
|
12415
12824
|
const attrs = themeAttrs(ui);
|
|
12416
|
-
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)(
|
|
12417
12826
|
ChatPanel,
|
|
12418
12827
|
{
|
|
12419
12828
|
controller,
|
|
@@ -12427,11 +12836,13 @@ function StatsWidget(props) {
|
|
|
12427
12836
|
clubFixturesResult,
|
|
12428
12837
|
clubStandingsResult,
|
|
12429
12838
|
clubSquadResult,
|
|
12839
|
+
clubSquadStatsResult,
|
|
12840
|
+
clubPlayerDetailResult,
|
|
12430
12841
|
loggedIn: !!operatorUserId,
|
|
12431
12842
|
conversation: built?.conversation ?? null,
|
|
12432
12843
|
presetGrid
|
|
12433
12844
|
}
|
|
12434
|
-
) : /* @__PURE__ */ (0,
|
|
12845
|
+
) : /* @__PURE__ */ (0, import_jsx_runtime104.jsx)(
|
|
12435
12846
|
ChatFab,
|
|
12436
12847
|
{
|
|
12437
12848
|
label: ui.launcherLabel,
|