@sensiblestats/widget-react 0.84.0 → 0.86.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +22 -0
- package/dist/index.cjs +1273 -392
- 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 +1236 -355
- package/dist/index.js.map +1 -1
- package/dist/styles.css +106 -4
- package/package.json +2 -2
package/dist/index.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
// src/StatsWidget.tsx
|
|
2
|
-
import { useCallback as
|
|
2
|
+
import { useCallback as useCallback23, useEffect as useEffect34, useMemo as useMemo6, useRef as useRef31, useState as useState55 } from "react";
|
|
3
3
|
import { StatsWidgetClient } from "@sensiblestats/widget-sdk";
|
|
4
4
|
|
|
5
5
|
// src/kickoff.ts
|
|
@@ -15,8 +15,13 @@ function formatBettingKickoff(kickoffUtc, ui, locale, now = /* @__PURE__ */ new
|
|
|
15
15
|
}
|
|
16
16
|
|
|
17
17
|
// src/i18n.ts
|
|
18
|
+
var GROUP_NOUN_EN = { G: "goalkeepers", D: "defenders", M: "midfielders", F: "forwards" };
|
|
19
|
+
var GROUP_NOUN_TR = { G: "kalecileri", D: "defans oyuncular\u0131", M: "orta saha oyuncular\u0131", F: "forvetleri" };
|
|
18
20
|
var formatPtsEn = (n) => new Intl.NumberFormat("en-GB").format(n);
|
|
19
21
|
var formatPtsTr = (n) => new Intl.NumberFormat("tr-TR").format(n);
|
|
22
|
+
var nbsp = (s) => s.replace(/\s/g, "\xA0");
|
|
23
|
+
var pdDateEn = (ms, opts) => nbsp(new Intl.DateTimeFormat("en-GB", opts).format(new Date(ms)).replace("Sept", "Sep"));
|
|
24
|
+
var pdDateTr = (ms, opts) => nbsp(new Intl.DateTimeFormat("tr-TR", opts).format(new Date(ms)));
|
|
20
25
|
var STRINGS = {
|
|
21
26
|
en: {
|
|
22
27
|
launcherLabel: "Chat with SensibleStats",
|
|
@@ -119,7 +124,93 @@ var STRINGS = {
|
|
|
119
124
|
clubFixturesEmpty: "No fixtures yet.",
|
|
120
125
|
clubStandingsEmpty: "Standings are not available yet.",
|
|
121
126
|
clubSquadEmpty: "Squad is not available yet.",
|
|
127
|
+
footRight: "Right",
|
|
128
|
+
footLeft: "Left",
|
|
129
|
+
footBoth: "Both",
|
|
130
|
+
positionGoalkeeper: "Goalkeeper",
|
|
131
|
+
positionDefender: "Defender",
|
|
132
|
+
positionMidfielder: "Midfielder",
|
|
133
|
+
positionAttacker: "Attacker",
|
|
134
|
+
tabRecords: "Records",
|
|
135
|
+
clubSquadStatsEmpty: "Squad stats are not available yet.",
|
|
136
|
+
clubPlayerDetailEmpty: "Player details are not available.",
|
|
137
|
+
clubRecordsEmpty: "Club records are not available yet.",
|
|
138
|
+
squadViewRoster: "Roster",
|
|
139
|
+
squadViewStats: "Stats",
|
|
140
|
+
statColApps: "Apps",
|
|
141
|
+
statColGoals: "Goals",
|
|
142
|
+
statColAssists: "Assists",
|
|
143
|
+
statColRating: "Rating",
|
|
144
|
+
statColMinutes: "Minutes",
|
|
145
|
+
statColYellow: "Yellow cards",
|
|
146
|
+
statColRed: "Red cards",
|
|
147
|
+
statColXg: "xG",
|
|
148
|
+
statColShots: "Shots",
|
|
149
|
+
detailNationality: "Nationality",
|
|
150
|
+
detailAge: "Age",
|
|
151
|
+
detailHeight: "Height",
|
|
152
|
+
detailFoot: "Foot",
|
|
153
|
+
detailSeason: "Season {season}",
|
|
154
|
+
clubPlayerBack: "Back",
|
|
155
|
+
recordsTopScorers: "Top scorers",
|
|
156
|
+
recordsMostAppearances: "Most appearances",
|
|
157
|
+
recordsMostAssists: "Most assists",
|
|
158
|
+
recordsSince: "Since {season}",
|
|
122
159
|
standingsColClub: "Club",
|
|
160
|
+
statHeadPos: "Pos",
|
|
161
|
+
statHeadMins: "Mins",
|
|
162
|
+
statHeadGoals: "G",
|
|
163
|
+
statHeadAssists: "A",
|
|
164
|
+
statHeadYellow: "Y",
|
|
165
|
+
statHeadRed: "R",
|
|
166
|
+
statHeadRating: "Rtg",
|
|
167
|
+
squadStatsEyebrow: (season, competition, n) => `${season} ${competition} \xB7 after ${n} game${n === 1 ? "" : "s"}`,
|
|
168
|
+
squadTopScorer: (name, n) => `Top scorer: ${name} (${n})`,
|
|
169
|
+
squadTopAssists: (name, n) => `Most assists: ${name} (${n})`,
|
|
170
|
+
detailStarted: "Started",
|
|
171
|
+
detailMatches: "Matches",
|
|
172
|
+
detailNatShort: "Nat.",
|
|
173
|
+
detailYellows: "Yellows",
|
|
174
|
+
detailReds: "Reds",
|
|
175
|
+
availabilityNext: (opponent, isHome, kickoffMs) => `Next: ${isHome ? "vs" : "at"} ${opponent} (${isHome ? "H" : "A"})` + (kickoffMs !== null && kickoffMs > 0 ? ` \xB7 ${pdDateEn(kickoffMs, { weekday: "short", day: "numeric", month: "short" })}` : ""),
|
|
176
|
+
availabilityAvailable: "Available",
|
|
177
|
+
availabilityInjured: "Injured",
|
|
178
|
+
availabilitySuspended: "Suspended",
|
|
179
|
+
availabilityUnavailable: "Unavailable",
|
|
180
|
+
availabilityNoConcerns: "No fitness concerns reported",
|
|
181
|
+
availabilityBack: (ms) => `Expected back ${pdDateEn(ms, { day: "numeric", month: "short" })}`,
|
|
182
|
+
perfTitle: "Season performance",
|
|
183
|
+
perfTotal: "Total",
|
|
184
|
+
perfPer90: "Per 90",
|
|
185
|
+
perfRankedAgainst: (competition, group) => `Ranked against ${competition} ${GROUP_NOUN_EN[group] ?? group}`,
|
|
186
|
+
perfUnranked: "Not enough minutes to rank",
|
|
187
|
+
perfUnrankedCohort: "Not enough players in this position to rank",
|
|
188
|
+
perfUnrankedNoLeague: "Not ranked \u2014 no league data",
|
|
189
|
+
perfGroupShooting: "Shooting",
|
|
190
|
+
perfGroupPassing: "Passing",
|
|
191
|
+
perfGroupPossession: "Possession",
|
|
192
|
+
perfGroupDefending: "Defending",
|
|
193
|
+
perfMetric: {
|
|
194
|
+
goals: "Goals",
|
|
195
|
+
xg: "Expected goals (xG)",
|
|
196
|
+
shots: "Shots",
|
|
197
|
+
shotsOnTarget: "Shots on target",
|
|
198
|
+
assists: "Assists",
|
|
199
|
+
successfulPasses: "Successful passes",
|
|
200
|
+
passAccuracy: "Pass accuracy",
|
|
201
|
+
chancesCreated: "Chances created",
|
|
202
|
+
successfulDribbles: "Successful dribbles",
|
|
203
|
+
dribbleSuccess: "Dribble success",
|
|
204
|
+
touches: "Touches",
|
|
205
|
+
tacklesWon: "Tackles won",
|
|
206
|
+
interceptions: "Interceptions",
|
|
207
|
+
duelsWon: "Duels won"
|
|
208
|
+
},
|
|
209
|
+
perfGroupNoun: GROUP_NOUN_EN,
|
|
210
|
+
matchLogTitle: "Match log",
|
|
211
|
+
matchLogOpponent: (name, isHome) => isHome ? `vs ${name}` : `at ${name}`,
|
|
212
|
+
resultLetter: { W: "W", D: "D", L: "L" },
|
|
213
|
+
logShortDate: (ms) => pdDateEn(ms, { day: "numeric", month: "short" }),
|
|
123
214
|
standingsColPlayed: "P",
|
|
124
215
|
standingsColWon: "W",
|
|
125
216
|
standingsColDrawn: "D",
|
|
@@ -500,7 +591,93 @@ var STRINGS = {
|
|
|
500
591
|
clubFixturesEmpty: "Hen\xFCz fikst\xFCr yok.",
|
|
501
592
|
clubStandingsEmpty: "Puan durumu hen\xFCz mevcut de\u011Fil.",
|
|
502
593
|
clubSquadEmpty: "Kadro hen\xFCz mevcut de\u011Fil.",
|
|
594
|
+
footRight: "Sa\u011F",
|
|
595
|
+
footLeft: "Sol",
|
|
596
|
+
footBoth: "\u0130ki ayak",
|
|
597
|
+
positionGoalkeeper: "Kaleci",
|
|
598
|
+
positionDefender: "Defans",
|
|
599
|
+
positionMidfielder: "Orta saha",
|
|
600
|
+
positionAttacker: "Forvet",
|
|
601
|
+
tabRecords: "Rekorlar",
|
|
602
|
+
clubSquadStatsEmpty: "Kadro istatistikleri hen\xFCz mevcut de\u011Fil.",
|
|
603
|
+
clubPlayerDetailEmpty: "Oyuncu bilgileri mevcut de\u011Fil.",
|
|
604
|
+
clubRecordsEmpty: "Kul\xFCp rekorlar\u0131 hen\xFCz mevcut de\u011Fil.",
|
|
605
|
+
squadViewRoster: "Kadro",
|
|
606
|
+
squadViewStats: "\u0130statistik",
|
|
607
|
+
statColApps: "Ma\xE7",
|
|
608
|
+
statColGoals: "Gol",
|
|
609
|
+
statColAssists: "Asist",
|
|
610
|
+
statColRating: "Puan",
|
|
611
|
+
statColMinutes: "Dakika",
|
|
612
|
+
statColYellow: "Sar\u0131 kart",
|
|
613
|
+
statColRed: "K\u0131rm\u0131z\u0131 kart",
|
|
614
|
+
statColXg: "xG",
|
|
615
|
+
statColShots: "\u015Eut",
|
|
616
|
+
detailNationality: "Uyruk",
|
|
617
|
+
detailAge: "Ya\u015F",
|
|
618
|
+
detailHeight: "Boy",
|
|
619
|
+
detailFoot: "Ayak",
|
|
620
|
+
detailSeason: "{season} sezonu",
|
|
621
|
+
clubPlayerBack: "Geri",
|
|
622
|
+
recordsTopScorers: "En \xE7ok gol atanlar",
|
|
623
|
+
recordsMostAppearances: "En \xE7ok ma\xE7 yapanlar",
|
|
624
|
+
recordsMostAssists: "En \xE7ok asist yapanlar",
|
|
625
|
+
recordsSince: "{season} sezonundan beri",
|
|
503
626
|
standingsColClub: "Tak\u0131m",
|
|
627
|
+
statHeadPos: "Mvk",
|
|
628
|
+
statHeadMins: "Dk",
|
|
629
|
+
statHeadGoals: "G",
|
|
630
|
+
statHeadAssists: "A",
|
|
631
|
+
statHeadYellow: "S",
|
|
632
|
+
statHeadRed: "K",
|
|
633
|
+
statHeadRating: "Puan",
|
|
634
|
+
squadStatsEyebrow: (season, competition, n) => `${season} ${competition} \xB7 ${n} ma\xE7 sonra`,
|
|
635
|
+
squadTopScorer: (name, n) => `Gol kral\u0131: ${name} (${n})`,
|
|
636
|
+
squadTopAssists: (name, n) => `Asist lideri: ${name} (${n})`,
|
|
637
|
+
detailStarted: "\u0130lk 11",
|
|
638
|
+
detailMatches: "Ma\xE7",
|
|
639
|
+
detailNatShort: "Uyruk",
|
|
640
|
+
detailYellows: "Sar\u0131",
|
|
641
|
+
detailReds: "K\u0131rm\u0131z\u0131",
|
|
642
|
+
availabilityNext: (opponent, isHome, kickoffMs) => `Sonraki: ${opponent} (${isHome ? "\u0130\xE7\xA0saha" : "Deplasman"})` + (kickoffMs !== null && kickoffMs > 0 ? ` \xB7 ${pdDateTr(kickoffMs, { day: "numeric", month: "short", weekday: "short" })}` : ""),
|
|
643
|
+
availabilityAvailable: "Haz\u0131r",
|
|
644
|
+
availabilityInjured: "Sakat",
|
|
645
|
+
availabilitySuspended: "Cezal\u0131",
|
|
646
|
+
availabilityUnavailable: "Haz\u0131r de\u011Fil",
|
|
647
|
+
availabilityNoConcerns: "Sakatl\u0131k bildirimi yok",
|
|
648
|
+
availabilityBack: (ms) => `D\xF6n\xFC\u015F: ${pdDateTr(ms, { day: "numeric", month: "short" })}`,
|
|
649
|
+
perfTitle: "Sezon performans\u0131",
|
|
650
|
+
perfTotal: "Toplam",
|
|
651
|
+
perfPer90: "90 dk",
|
|
652
|
+
perfRankedAgainst: (competition, group) => `${competition} ${GROUP_NOUN_TR[group] ?? group} aras\u0131nda`,
|
|
653
|
+
perfUnranked: "S\u0131ralama i\xE7in yeterli s\xFCre yok",
|
|
654
|
+
perfUnrankedCohort: "Bu mevkide s\u0131ralama i\xE7in yeterli oyuncu yok",
|
|
655
|
+
perfUnrankedNoLeague: "S\u0131ralanmad\u0131 \u2014 lig verisi yok",
|
|
656
|
+
perfGroupShooting: "\u015Eut",
|
|
657
|
+
perfGroupPassing: "Pas",
|
|
658
|
+
perfGroupPossession: "Top hakimiyeti",
|
|
659
|
+
perfGroupDefending: "Savunma",
|
|
660
|
+
perfMetric: {
|
|
661
|
+
goals: "Gol",
|
|
662
|
+
xg: "Gol beklentisi (xG)",
|
|
663
|
+
shots: "\u015Eut",
|
|
664
|
+
shotsOnTarget: "\u0130sabetli \u015Fut",
|
|
665
|
+
assists: "Asist",
|
|
666
|
+
successfulPasses: "Ba\u015Far\u0131l\u0131 pas",
|
|
667
|
+
passAccuracy: "Pas isabeti",
|
|
668
|
+
chancesCreated: "Yarat\u0131lan f\u0131rsat",
|
|
669
|
+
successfulDribbles: "Ba\u015Far\u0131l\u0131 \xE7al\u0131m",
|
|
670
|
+
dribbleSuccess: "\xC7al\u0131m ba\u015Far\u0131s\u0131",
|
|
671
|
+
touches: "Topla bulu\u015Fma",
|
|
672
|
+
tacklesWon: "Kazan\u0131lan m\xFCdahale",
|
|
673
|
+
interceptions: "Top kapma",
|
|
674
|
+
duelsWon: "Kazan\u0131lan ikili m\xFCcadele"
|
|
675
|
+
},
|
|
676
|
+
perfGroupNoun: GROUP_NOUN_TR,
|
|
677
|
+
matchLogTitle: "Ma\xE7 ge\xE7mi\u015Fi",
|
|
678
|
+
matchLogOpponent: (name, isHome) => isHome ? `${name} (\u0130)` : `${name} (D)`,
|
|
679
|
+
resultLetter: { W: "G", D: "B", L: "M" },
|
|
680
|
+
logShortDate: (ms) => pdDateTr(ms, { day: "numeric", month: "short" }),
|
|
504
681
|
standingsColPlayed: "O",
|
|
505
682
|
standingsColWon: "G",
|
|
506
683
|
standingsColDrawn: "B",
|
|
@@ -878,7 +1055,78 @@ function normalizeUi(cfg) {
|
|
|
878
1055
|
clubFixturesEmpty: strings.clubFixturesEmpty,
|
|
879
1056
|
clubStandingsEmpty: strings.clubStandingsEmpty,
|
|
880
1057
|
clubSquadEmpty: strings.clubSquadEmpty,
|
|
1058
|
+
footRight: strings.footRight,
|
|
1059
|
+
footLeft: strings.footLeft,
|
|
1060
|
+
footBoth: strings.footBoth,
|
|
1061
|
+
positionGoalkeeper: strings.positionGoalkeeper,
|
|
1062
|
+
positionDefender: strings.positionDefender,
|
|
1063
|
+
positionMidfielder: strings.positionMidfielder,
|
|
1064
|
+
positionAttacker: strings.positionAttacker,
|
|
1065
|
+
tabRecords: strings.tabRecords,
|
|
1066
|
+
clubSquadStatsEmpty: strings.clubSquadStatsEmpty,
|
|
1067
|
+
clubPlayerDetailEmpty: strings.clubPlayerDetailEmpty,
|
|
1068
|
+
clubRecordsEmpty: strings.clubRecordsEmpty,
|
|
1069
|
+
squadViewRoster: strings.squadViewRoster,
|
|
1070
|
+
squadViewStats: strings.squadViewStats,
|
|
1071
|
+
statColApps: strings.statColApps,
|
|
1072
|
+
statColGoals: strings.statColGoals,
|
|
1073
|
+
statColAssists: strings.statColAssists,
|
|
1074
|
+
statColRating: strings.statColRating,
|
|
1075
|
+
statColMinutes: strings.statColMinutes,
|
|
1076
|
+
statColYellow: strings.statColYellow,
|
|
1077
|
+
statColRed: strings.statColRed,
|
|
1078
|
+
statColXg: strings.statColXg,
|
|
1079
|
+
statColShots: strings.statColShots,
|
|
1080
|
+
detailNationality: strings.detailNationality,
|
|
1081
|
+
detailAge: strings.detailAge,
|
|
1082
|
+
detailHeight: strings.detailHeight,
|
|
1083
|
+
detailFoot: strings.detailFoot,
|
|
1084
|
+
detailSeason: strings.detailSeason,
|
|
1085
|
+
clubPlayerBack: strings.clubPlayerBack,
|
|
1086
|
+
recordsTopScorers: strings.recordsTopScorers,
|
|
1087
|
+
recordsMostAppearances: strings.recordsMostAppearances,
|
|
1088
|
+
recordsMostAssists: strings.recordsMostAssists,
|
|
1089
|
+
recordsSince: strings.recordsSince,
|
|
881
1090
|
standingsColClub: strings.standingsColClub,
|
|
1091
|
+
statHeadPos: strings.statHeadPos,
|
|
1092
|
+
statHeadMins: strings.statHeadMins,
|
|
1093
|
+
statHeadGoals: strings.statHeadGoals,
|
|
1094
|
+
statHeadAssists: strings.statHeadAssists,
|
|
1095
|
+
statHeadYellow: strings.statHeadYellow,
|
|
1096
|
+
statHeadRed: strings.statHeadRed,
|
|
1097
|
+
statHeadRating: strings.statHeadRating,
|
|
1098
|
+
squadStatsEyebrow: strings.squadStatsEyebrow,
|
|
1099
|
+
squadTopScorer: strings.squadTopScorer,
|
|
1100
|
+
squadTopAssists: strings.squadTopAssists,
|
|
1101
|
+
detailStarted: strings.detailStarted,
|
|
1102
|
+
detailMatches: strings.detailMatches,
|
|
1103
|
+
detailNatShort: strings.detailNatShort,
|
|
1104
|
+
detailYellows: strings.detailYellows,
|
|
1105
|
+
detailReds: strings.detailReds,
|
|
1106
|
+
availabilityNext: strings.availabilityNext,
|
|
1107
|
+
availabilityAvailable: strings.availabilityAvailable,
|
|
1108
|
+
availabilityInjured: strings.availabilityInjured,
|
|
1109
|
+
availabilitySuspended: strings.availabilitySuspended,
|
|
1110
|
+
availabilityUnavailable: strings.availabilityUnavailable,
|
|
1111
|
+
availabilityNoConcerns: strings.availabilityNoConcerns,
|
|
1112
|
+
availabilityBack: strings.availabilityBack,
|
|
1113
|
+
perfTitle: strings.perfTitle,
|
|
1114
|
+
perfTotal: strings.perfTotal,
|
|
1115
|
+
perfPer90: strings.perfPer90,
|
|
1116
|
+
perfRankedAgainst: strings.perfRankedAgainst,
|
|
1117
|
+
perfUnranked: strings.perfUnranked,
|
|
1118
|
+
perfUnrankedCohort: strings.perfUnrankedCohort,
|
|
1119
|
+
perfUnrankedNoLeague: strings.perfUnrankedNoLeague,
|
|
1120
|
+
perfGroupShooting: strings.perfGroupShooting,
|
|
1121
|
+
perfGroupPassing: strings.perfGroupPassing,
|
|
1122
|
+
perfGroupPossession: strings.perfGroupPossession,
|
|
1123
|
+
perfGroupDefending: strings.perfGroupDefending,
|
|
1124
|
+
perfMetric: strings.perfMetric,
|
|
1125
|
+
perfGroupNoun: strings.perfGroupNoun,
|
|
1126
|
+
matchLogTitle: strings.matchLogTitle,
|
|
1127
|
+
matchLogOpponent: strings.matchLogOpponent,
|
|
1128
|
+
resultLetter: strings.resultLetter,
|
|
1129
|
+
logShortDate: strings.logShortDate,
|
|
882
1130
|
standingsColPlayed: strings.standingsColPlayed,
|
|
883
1131
|
standingsColWon: strings.standingsColWon,
|
|
884
1132
|
standingsColDrawn: strings.standingsColDrawn,
|
|
@@ -3243,8 +3491,87 @@ function useClubSquad(conversation, { activeTab, enabled }) {
|
|
|
3243
3491
|
return { data, loading: effectiveLoading, refresh };
|
|
3244
3492
|
}
|
|
3245
3493
|
|
|
3494
|
+
// src/useClubSquadStats.ts
|
|
3495
|
+
import { useCallback as useCallback10, useEffect as useEffect11, useRef as useRef11, useState as useState10 } from "react";
|
|
3496
|
+
function useClubSquadStats(conversation, { activeTab, enabled }) {
|
|
3497
|
+
const [data, setData] = useState10(null);
|
|
3498
|
+
const [seasonName, setSeasonName] = useState10(null);
|
|
3499
|
+
const [competitionName, setCompetitionName] = useState10(null);
|
|
3500
|
+
const [matchesPlayed, setMatchesPlayed] = useState10(null);
|
|
3501
|
+
const [loading, setLoading] = useState10(false);
|
|
3502
|
+
const [refreshCount, setRefreshCount] = useState10(0);
|
|
3503
|
+
const inFlightRef = useRef11(false);
|
|
3504
|
+
const conversationRef = useRef11(conversation);
|
|
3505
|
+
conversationRef.current = conversation;
|
|
3506
|
+
useEffect11(() => {
|
|
3507
|
+
if (activeTab !== "squad" || !enabled) return;
|
|
3508
|
+
let active = true;
|
|
3509
|
+
const doFetch = async () => {
|
|
3510
|
+
const conv = conversationRef.current;
|
|
3511
|
+
if (!conv || inFlightRef.current) return;
|
|
3512
|
+
inFlightRef.current = true;
|
|
3513
|
+
setLoading(true);
|
|
3514
|
+
try {
|
|
3515
|
+
const result = await conv.getClubSquadStats();
|
|
3516
|
+
if (active) {
|
|
3517
|
+
setData(result?.players ?? null);
|
|
3518
|
+
setSeasonName(result?.seasonName ?? null);
|
|
3519
|
+
setCompetitionName(result?.competitionName ?? null);
|
|
3520
|
+
setMatchesPlayed(result?.clubMatchesPlayed ?? null);
|
|
3521
|
+
}
|
|
3522
|
+
} catch {
|
|
3523
|
+
} finally {
|
|
3524
|
+
inFlightRef.current = false;
|
|
3525
|
+
if (active) setLoading(false);
|
|
3526
|
+
}
|
|
3527
|
+
};
|
|
3528
|
+
void doFetch();
|
|
3529
|
+
return () => {
|
|
3530
|
+
active = false;
|
|
3531
|
+
inFlightRef.current = false;
|
|
3532
|
+
};
|
|
3533
|
+
}, [activeTab, enabled, refreshCount]);
|
|
3534
|
+
const refresh = useCallback10(() => {
|
|
3535
|
+
setRefreshCount((c) => c + 1);
|
|
3536
|
+
}, []);
|
|
3537
|
+
const effectiveLoading = loading || activeTab === "squad" && enabled && data === null;
|
|
3538
|
+
return { data, seasonName, competitionName, matchesPlayed, loading: effectiveLoading, refresh };
|
|
3539
|
+
}
|
|
3540
|
+
|
|
3541
|
+
// src/useClubPlayerDetail.ts
|
|
3542
|
+
import { useCallback as useCallback11, useRef as useRef12, useState as useState11 } from "react";
|
|
3543
|
+
function useClubPlayerDetail(conversation) {
|
|
3544
|
+
const [data, setData] = useState11(null);
|
|
3545
|
+
const [loading, setLoading] = useState11(false);
|
|
3546
|
+
const requestSeqRef = useRef12(0);
|
|
3547
|
+
const conversationRef = useRef12(conversation);
|
|
3548
|
+
conversationRef.current = conversation;
|
|
3549
|
+
const fetch = useCallback11((playerId) => {
|
|
3550
|
+
const conv = conversationRef.current;
|
|
3551
|
+
if (!conv) return;
|
|
3552
|
+
const seq = ++requestSeqRef.current;
|
|
3553
|
+
setData(null);
|
|
3554
|
+
setLoading(true);
|
|
3555
|
+
void (async () => {
|
|
3556
|
+
try {
|
|
3557
|
+
const result = await conv.getClubPlayerDetail(playerId);
|
|
3558
|
+
if (seq === requestSeqRef.current) setData(result);
|
|
3559
|
+
} catch {
|
|
3560
|
+
} finally {
|
|
3561
|
+
if (seq === requestSeqRef.current) setLoading(false);
|
|
3562
|
+
}
|
|
3563
|
+
})();
|
|
3564
|
+
}, []);
|
|
3565
|
+
const clear = useCallback11(() => {
|
|
3566
|
+
requestSeqRef.current++;
|
|
3567
|
+
setData(null);
|
|
3568
|
+
setLoading(false);
|
|
3569
|
+
}, []);
|
|
3570
|
+
return { data, loading, fetch, clear };
|
|
3571
|
+
}
|
|
3572
|
+
|
|
3246
3573
|
// src/usePresetGrid.ts
|
|
3247
|
-
import { useEffect as
|
|
3574
|
+
import { useEffect as useEffect12, useRef as useRef13, useState as useState12 } from "react";
|
|
3248
3575
|
|
|
3249
3576
|
// src/presetGrid.ts
|
|
3250
3577
|
var DEFAULT_SINGLES_LIMITS = [1.3, 1.5, 1.7, 2];
|
|
@@ -3387,22 +3714,22 @@ function marketDisplay(cell, s) {
|
|
|
3387
3714
|
// src/usePresetGrid.ts
|
|
3388
3715
|
var GRID_MAX_AGE_MS = 6e5;
|
|
3389
3716
|
function usePresetGrid({ getPricePresets, isOpen, locale, now = Date.now }) {
|
|
3390
|
-
const [grid, setGrid] =
|
|
3391
|
-
const keptRef =
|
|
3392
|
-
const localeRef =
|
|
3393
|
-
const inFlightRef =
|
|
3394
|
-
const mountedRef =
|
|
3395
|
-
const getRef =
|
|
3717
|
+
const [grid, setGrid] = useState12(null);
|
|
3718
|
+
const keptRef = useRef13(null);
|
|
3719
|
+
const localeRef = useRef13(locale);
|
|
3720
|
+
const inFlightRef = useRef13(false);
|
|
3721
|
+
const mountedRef = useRef13(true);
|
|
3722
|
+
const getRef = useRef13(getPricePresets);
|
|
3396
3723
|
getRef.current = getPricePresets;
|
|
3397
|
-
const nowRef =
|
|
3724
|
+
const nowRef = useRef13(now);
|
|
3398
3725
|
nowRef.current = now;
|
|
3399
|
-
|
|
3726
|
+
useEffect12(() => {
|
|
3400
3727
|
mountedRef.current = true;
|
|
3401
3728
|
return () => {
|
|
3402
3729
|
mountedRef.current = false;
|
|
3403
3730
|
};
|
|
3404
3731
|
}, []);
|
|
3405
|
-
|
|
3732
|
+
useEffect12(() => {
|
|
3406
3733
|
if (localeRef.current !== locale) {
|
|
3407
3734
|
localeRef.current = locale;
|
|
3408
3735
|
keptRef.current = null;
|
|
@@ -3452,11 +3779,11 @@ function useEventLog() {
|
|
|
3452
3779
|
}
|
|
3453
3780
|
|
|
3454
3781
|
// src/popupTelemetry.ts
|
|
3455
|
-
import { useCallback as
|
|
3782
|
+
import { useCallback as useCallback12, useEffect as useEffect13, useRef as useRef14 } from "react";
|
|
3456
3783
|
function usePopupTelemetry(log, isOpen, popupText, dismissPopup) {
|
|
3457
|
-
const shownRef =
|
|
3458
|
-
const closedTextRef =
|
|
3459
|
-
|
|
3784
|
+
const shownRef = useRef14(/* @__PURE__ */ new Set());
|
|
3785
|
+
const closedTextRef = useRef14(null);
|
|
3786
|
+
useEffect13(() => {
|
|
3460
3787
|
if (isOpen) {
|
|
3461
3788
|
if (closedTextRef.current) log?.log({ name: "popup_opened" });
|
|
3462
3789
|
closedTextRef.current = null;
|
|
@@ -3468,17 +3795,17 @@ function usePopupTelemetry(log, isOpen, popupText, dismissPopup) {
|
|
|
3468
3795
|
log?.log({ name: "popup_shown" });
|
|
3469
3796
|
}
|
|
3470
3797
|
}, [log, isOpen, popupText]);
|
|
3471
|
-
return
|
|
3798
|
+
return useCallback12(() => {
|
|
3472
3799
|
log?.log({ name: "popup_dismissed" });
|
|
3473
3800
|
dismissPopup();
|
|
3474
3801
|
}, [log, dismissPopup]);
|
|
3475
3802
|
}
|
|
3476
3803
|
|
|
3477
3804
|
// src/openTelemetry.ts
|
|
3478
|
-
import { useEffect as
|
|
3805
|
+
import { useEffect as useEffect14, useRef as useRef15 } from "react";
|
|
3479
3806
|
function useOpenTelemetry(log, isOpen) {
|
|
3480
|
-
const openLoggedRef =
|
|
3481
|
-
|
|
3807
|
+
const openLoggedRef = useRef15(false);
|
|
3808
|
+
useEffect14(() => {
|
|
3482
3809
|
if (!isOpen) {
|
|
3483
3810
|
openLoggedRef.current = false;
|
|
3484
3811
|
return;
|
|
@@ -3490,10 +3817,10 @@ function useOpenTelemetry(log, isOpen) {
|
|
|
3490
3817
|
}
|
|
3491
3818
|
|
|
3492
3819
|
// src/components/ChatFab.tsx
|
|
3493
|
-
import { useEffect as
|
|
3820
|
+
import { useEffect as useEffect15, useRef as useRef16, useState as useState14 } from "react";
|
|
3494
3821
|
|
|
3495
3822
|
// src/components/BrandMark.tsx
|
|
3496
|
-
import { useState as
|
|
3823
|
+
import { useState as useState13 } from "react";
|
|
3497
3824
|
|
|
3498
3825
|
// src/assets/logo.ts
|
|
3499
3826
|
var SS_LOGO_DATA_URI = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAjoAAAI6CAYAAAAuSOLAAAAAAXNSR0IArs4c6QAAAJplWElmTU0AKgAAAAgAAwESAAMAAAABAAEAAAExAAIAAAA9AAAAModpAAQAAAABAAAAcAAAAABBZG9iZSBQaG90b3Nob3AgMjYuMTAgKDIwMjUwNzMwLm0uMzE2NiAwN2IxMjM0KSAgKE1hY2ludG9zaCkAAAADoAEAAwAAAAEAAQAAoAIABAAAAAEAAAI6oAMABAAAAAEAAAI6AAAAACwGtVwAAAQwaVRYdFhNTDpjb20uYWRvYmUueG1wAAAAAAA8eDp4bXBtZXRhIHhtbG5zOng9ImFkb2JlOm5zOm1ldGEvIiB4OnhtcHRrPSJYTVAgQ29yZSA2LjAuMCI+CiAgIDxyZGY6UkRGIHhtbG5zOnJkZj0iaHR0cDovL3d3dy53My5vcmcvMTk5OS8wMi8yMi1yZGYtc3ludGF4LW5zIyI+CiAgICAgIDxyZGY6RGVzY3JpcHRpb24gcmRmOmFib3V0PSIiCiAgICAgICAgICAgIHhtbG5zOnhtcE1NPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvbW0vIgogICAgICAgICAgICB4bWxuczpzdFJlZj0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL3NUeXBlL1Jlc291cmNlUmVmIyIKICAgICAgICAgICAgeG1sbnM6eG1wPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvIgogICAgICAgICAgICB4bWxuczp0aWZmPSJodHRwOi8vbnMuYWRvYmUuY29tL3RpZmYvMS4wLyI+CiAgICAgICAgIDx4bXBNTTpEb2N1bWVudElEPnhtcC5kaWQ6QzBGRTM5NjM5NEJEMTFGMEJGNjZEMjUyN0U0MzU5RUM8L3htcE1NOkRvY3VtZW50SUQ+CiAgICAgICAgIDx4bXBNTTpJbnN0YW5jZUlEPnhtcC5paWQ6QzBGRTM5NjI5NEJEMTFGMEJGNjZEMjUyN0U0MzU5RUM8L3htcE1NOkluc3RhbmNlSUQ+CiAgICAgICAgIDx4bXBNTTpEZXJpdmVkRnJvbSByZGY6cGFyc2VUeXBlPSJSZXNvdXJjZSI+CiAgICAgICAgICAgIDxzdFJlZjppbnN0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";
|
|
@@ -3556,7 +3883,7 @@ function DashboardIcon({ name }) {
|
|
|
3556
3883
|
// src/components/BrandMark.tsx
|
|
3557
3884
|
import { jsx as jsx2 } from "react/jsx-runtime";
|
|
3558
3885
|
function BrandMark({ logoUrl, className }) {
|
|
3559
|
-
const [failed, setFailed] =
|
|
3886
|
+
const [failed, setFailed] = useState13(false);
|
|
3560
3887
|
if (!logoUrl || failed) return /* @__PURE__ */ jsx2(SsMark, { className });
|
|
3561
3888
|
return /* @__PURE__ */ jsx2("img", { className, src: logoUrl, alt: "", "aria-hidden": "true", onError: () => setFailed(true) });
|
|
3562
3889
|
}
|
|
@@ -3592,9 +3919,9 @@ function GreetingBubble({ text, onOpen, onDismiss, dismissLabel = "Dismiss", ask
|
|
|
3592
3919
|
import { jsx as jsx4, jsxs as jsxs3 } from "react/jsx-runtime";
|
|
3593
3920
|
function ChatFab({ label, greeting, popupText, logoUrl, onOpen, onDismissPopup, dismissLabel = "Dismiss", introAllowed = false, onIntroStart, asks }) {
|
|
3594
3921
|
const bubble = popupText ?? greeting;
|
|
3595
|
-
const [intro, setIntro] =
|
|
3596
|
-
const armedRef =
|
|
3597
|
-
|
|
3922
|
+
const [intro, setIntro] = useState14(false);
|
|
3923
|
+
const armedRef = useRef16(introAllowed);
|
|
3924
|
+
useEffect15(() => {
|
|
3598
3925
|
if (armedRef.current && bubble) {
|
|
3599
3926
|
armedRef.current = false;
|
|
3600
3927
|
setIntro(true);
|
|
@@ -3608,10 +3935,10 @@ function ChatFab({ label, greeting, popupText, logoUrl, onOpen, onDismissPopup,
|
|
|
3608
3935
|
}
|
|
3609
3936
|
|
|
3610
3937
|
// src/components/ChatPanel.tsx
|
|
3611
|
-
import { useCallback as
|
|
3938
|
+
import { useCallback as useCallback22, useEffect as useEffect33, useLayoutEffect, useMemo as useMemo5, useRef as useRef30, useState as useState54 } from "react";
|
|
3612
3939
|
|
|
3613
3940
|
// src/components/ChatHeader.tsx
|
|
3614
|
-
import { useEffect as
|
|
3941
|
+
import { useEffect as useEffect16, useRef as useRef17, useState as useState15 } from "react";
|
|
3615
3942
|
import { jsx as jsx5, jsxs as jsxs4 } from "react/jsx-runtime";
|
|
3616
3943
|
function ChatHeader({
|
|
3617
3944
|
onClose,
|
|
@@ -3623,15 +3950,15 @@ function ChatHeader({
|
|
|
3623
3950
|
newConversationLabel = "New conversation",
|
|
3624
3951
|
moreOptionsLabel = "More options"
|
|
3625
3952
|
}) {
|
|
3626
|
-
const [menuOpen, setMenuOpen] =
|
|
3627
|
-
const wrapRef =
|
|
3628
|
-
const kebabRef =
|
|
3629
|
-
const firstItemRef =
|
|
3953
|
+
const [menuOpen, setMenuOpen] = useState15(false);
|
|
3954
|
+
const wrapRef = useRef17(null);
|
|
3955
|
+
const kebabRef = useRef17(null);
|
|
3956
|
+
const firstItemRef = useRef17(null);
|
|
3630
3957
|
const hasMenu = !!(canReset && onNewConversation);
|
|
3631
|
-
|
|
3958
|
+
useEffect16(() => {
|
|
3632
3959
|
if (menuOpen) firstItemRef.current?.focus();
|
|
3633
3960
|
}, [menuOpen]);
|
|
3634
|
-
|
|
3961
|
+
useEffect16(() => {
|
|
3635
3962
|
if (!menuOpen) return;
|
|
3636
3963
|
const onPointer = (e) => {
|
|
3637
3964
|
if (!wrapRef.current?.contains(e.target)) setMenuOpen(false);
|
|
@@ -3687,7 +4014,7 @@ function ChatHeader({
|
|
|
3687
4014
|
}
|
|
3688
4015
|
|
|
3689
4016
|
// src/components/MessageList.tsx
|
|
3690
|
-
import { useEffect as
|
|
4017
|
+
import { useEffect as useEffect22, useRef as useRef20 } from "react";
|
|
3691
4018
|
|
|
3692
4019
|
// src/components/Markdown.tsx
|
|
3693
4020
|
import ReactMarkdown from "react-markdown";
|
|
@@ -3705,7 +4032,7 @@ function Markdown({ text }) {
|
|
|
3705
4032
|
}
|
|
3706
4033
|
|
|
3707
4034
|
// src/components/EntityCardList.tsx
|
|
3708
|
-
import { useState as
|
|
4035
|
+
import { useState as useState16 } from "react";
|
|
3709
4036
|
import { jsx as jsx7, jsxs as jsxs5 } from "react/jsx-runtime";
|
|
3710
4037
|
var MAX_VISIBLE = 3;
|
|
3711
4038
|
var RECORD_RE = /^(\d+)-(\d+)-(\d+)$/;
|
|
@@ -3789,7 +4116,7 @@ function ScopeTabs({ scopes, active, onSelect }) {
|
|
|
3789
4116
|
)) });
|
|
3790
4117
|
}
|
|
3791
4118
|
function EntityCardItem({ c }) {
|
|
3792
|
-
const [active, setActive] =
|
|
4119
|
+
const [active, setActive] = useState16(0);
|
|
3793
4120
|
const hasBody = c.scopes.length > 0;
|
|
3794
4121
|
if (!hasBody) {
|
|
3795
4122
|
return /* @__PURE__ */ jsx7("div", { className: "ss-w-ecard ss-w-ecard-bare", "data-kind": c.kind, children: /* @__PURE__ */ jsx7(CardHeader, { c, showScopeCrest: false }) });
|
|
@@ -3803,7 +4130,7 @@ function EntityCardItem({ c }) {
|
|
|
3803
4130
|
] });
|
|
3804
4131
|
}
|
|
3805
4132
|
function EntityCardList({ cards, disabled, showLessLabel = "Show less", showMoreLabel = (n) => `Show ${n} more` }) {
|
|
3806
|
-
const [expanded, setExpanded] =
|
|
4133
|
+
const [expanded, setExpanded] = useState16(false);
|
|
3807
4134
|
if (cards.length === 0) return null;
|
|
3808
4135
|
const visible = expanded ? cards : cards.slice(0, MAX_VISIBLE);
|
|
3809
4136
|
const overflow = cards.length - MAX_VISIBLE;
|
|
@@ -3814,10 +4141,10 @@ function EntityCardList({ cards, disabled, showLessLabel = "Show less", showMore
|
|
|
3814
4141
|
}
|
|
3815
4142
|
|
|
3816
4143
|
// src/components/AddToSlipButton.tsx
|
|
3817
|
-
import { useCallback as
|
|
4144
|
+
import { useCallback as useCallback14, useState as useState17 } from "react";
|
|
3818
4145
|
|
|
3819
4146
|
// src/slipAdd.ts
|
|
3820
|
-
import { useCallback as
|
|
4147
|
+
import { useCallback as useCallback13 } from "react";
|
|
3821
4148
|
import { isAddToSlipResult } from "@sensiblestats/widget-sdk";
|
|
3822
4149
|
|
|
3823
4150
|
// src/slipStateContext.ts
|
|
@@ -3839,7 +4166,7 @@ function useSlipAdd(slip, ui) {
|
|
|
3839
4166
|
const slipState = useSlipState();
|
|
3840
4167
|
const handler = slip.onAddToSlip;
|
|
3841
4168
|
const rawLabels = !!ui?.rawBettingLabels;
|
|
3842
|
-
return
|
|
4169
|
+
return useCallback13(async (selection, { marketDeveloperName, selectionLabel, line }) => {
|
|
3843
4170
|
if (!handler) return { kind: "failed" };
|
|
3844
4171
|
const pick = slipPickFields(selection, rawLabels ? selectionLabel : void 0, line);
|
|
3845
4172
|
if (marketDeveloperName !== void 0) {
|
|
@@ -3876,11 +4203,11 @@ function useSlipAdd(slip, ui) {
|
|
|
3876
4203
|
}
|
|
3877
4204
|
|
|
3878
4205
|
// src/components/Toast.tsx
|
|
3879
|
-
import { useEffect as
|
|
4206
|
+
import { useEffect as useEffect17 } from "react";
|
|
3880
4207
|
import { jsx as jsx8 } from "react/jsx-runtime";
|
|
3881
4208
|
var DISMISS_MS = 4e3;
|
|
3882
4209
|
function Toast({ toast, onDismiss }) {
|
|
3883
|
-
|
|
4210
|
+
useEffect17(() => {
|
|
3884
4211
|
if (!toast) return;
|
|
3885
4212
|
const timer = setTimeout(onDismiss, DISMISS_MS);
|
|
3886
4213
|
return () => clearTimeout(timer);
|
|
@@ -3892,10 +4219,10 @@ function Toast({ toast, onDismiss }) {
|
|
|
3892
4219
|
// src/components/AddToSlipButton.tsx
|
|
3893
4220
|
import { jsx as jsx9, jsxs as jsxs6 } from "react/jsx-runtime";
|
|
3894
4221
|
function SlipButton({ selection, shownOdds, marketDeveloperName, selectionLabel, line, slip, ui, price, ariaLabel }) {
|
|
3895
|
-
const [pending, setPending] =
|
|
3896
|
-
const [settledLocal, setSettledLocal] =
|
|
3897
|
-
const [toast, setToast] =
|
|
3898
|
-
const dismiss =
|
|
4222
|
+
const [pending, setPending] = useState17(false);
|
|
4223
|
+
const [settledLocal, setSettledLocal] = useState17(false);
|
|
4224
|
+
const [toast, setToast] = useState17(null);
|
|
4225
|
+
const dismiss = useCallback14(() => setToast(null), []);
|
|
3899
4226
|
const add = useSlipAdd(slip, ui);
|
|
3900
4227
|
const slipState = useSlipState();
|
|
3901
4228
|
const handler = slip.onAddToSlip;
|
|
@@ -3983,14 +4310,14 @@ function OddsMovementBadge({
|
|
|
3983
4310
|
}
|
|
3984
4311
|
|
|
3985
4312
|
// src/components/Crest.tsx
|
|
3986
|
-
import { useState as
|
|
4313
|
+
import { useState as useState18 } from "react";
|
|
3987
4314
|
import { jsx as jsx11 } from "react/jsx-runtime";
|
|
3988
4315
|
function initials2(name) {
|
|
3989
4316
|
return (name ?? "").trim().slice(0, 1).toUpperCase() || "?";
|
|
3990
4317
|
}
|
|
3991
4318
|
function Crest2({ url, name, kind }) {
|
|
3992
4319
|
const cls = kind === "comp" ? "ss-w-bi-comp-logo" : "ss-w-bi-crest";
|
|
3993
|
-
const [failed, setFailed] =
|
|
4320
|
+
const [failed, setFailed] = useState18(false);
|
|
3994
4321
|
if (url && !failed) {
|
|
3995
4322
|
return /* @__PURE__ */ jsx11("img", { className: cls, src: url, alt: "", "aria-hidden": "true", onError: () => setFailed(true) });
|
|
3996
4323
|
}
|
|
@@ -3998,7 +4325,7 @@ function Crest2({ url, name, kind }) {
|
|
|
3998
4325
|
}
|
|
3999
4326
|
|
|
4000
4327
|
// src/components/PinToggle.tsx
|
|
4001
|
-
import { useCallback as
|
|
4328
|
+
import { useCallback as useCallback15, useState as useState19 } from "react";
|
|
4002
4329
|
import { jsx as jsx12, jsxs as jsxs8 } from "react/jsx-runtime";
|
|
4003
4330
|
var PIN_GLYPHS = {
|
|
4004
4331
|
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" },
|
|
@@ -4006,8 +4333,8 @@ var PIN_GLYPHS = {
|
|
|
4006
4333
|
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" }
|
|
4007
4334
|
};
|
|
4008
4335
|
function PinToggle({ pin, monitor, ui, market }) {
|
|
4009
|
-
const [toast, setToast] =
|
|
4010
|
-
const dismiss =
|
|
4336
|
+
const [toast, setToast] = useState19(null);
|
|
4337
|
+
const dismiss = useCallback15(() => setToast(null), []);
|
|
4011
4338
|
const log = useEventLog();
|
|
4012
4339
|
if (!monitor || !monitor.enabled) return null;
|
|
4013
4340
|
const key = pinKey(pin);
|
|
@@ -4064,11 +4391,11 @@ function PinToggle({ pin, monitor, ui, market }) {
|
|
|
4064
4391
|
}
|
|
4065
4392
|
|
|
4066
4393
|
// src/components/PriceHistoryButton.tsx
|
|
4067
|
-
import { useCallback as
|
|
4394
|
+
import { useCallback as useCallback16, useState as useState20 } from "react";
|
|
4068
4395
|
import { jsx as jsx13, jsxs as jsxs9 } from "react/jsx-runtime";
|
|
4069
4396
|
function PriceHistoryButton({ selection, monitor, ui }) {
|
|
4070
|
-
const [toast, setToast] =
|
|
4071
|
-
const dismiss =
|
|
4397
|
+
const [toast, setToast] = useState20(null);
|
|
4398
|
+
const dismiss = useCallback16(() => setToast(null), []);
|
|
4072
4399
|
const log = useEventLog();
|
|
4073
4400
|
if (!monitor || !monitor.enabled) return null;
|
|
4074
4401
|
const name = joinSelection(selection.selectionLabel ?? void 0, selection.line ?? void 0);
|
|
@@ -4183,15 +4510,15 @@ function BettingInsightList({ insights, ui, slip, monitor }) {
|
|
|
4183
4510
|
}
|
|
4184
4511
|
|
|
4185
4512
|
// src/components/AddAllToSlipButton.tsx
|
|
4186
|
-
import { useCallback as
|
|
4513
|
+
import { useCallback as useCallback17, useState as useState21 } from "react";
|
|
4187
4514
|
import { jsx as jsx15, jsxs as jsxs11 } from "react/jsx-runtime";
|
|
4188
4515
|
function AddAllToSlipButton({ legs, slip, ui }) {
|
|
4189
4516
|
const add = useSlipAdd(slip, ui);
|
|
4190
4517
|
const slipState = useSlipState();
|
|
4191
|
-
const [pending, setPending] =
|
|
4192
|
-
const [settledLocal, setSettledLocal] =
|
|
4193
|
-
const [toast, setToast] =
|
|
4194
|
-
const dismiss =
|
|
4518
|
+
const [pending, setPending] = useState21(false);
|
|
4519
|
+
const [settledLocal, setSettledLocal] = useState21({});
|
|
4520
|
+
const [toast, setToast] = useState21(null);
|
|
4521
|
+
const dismiss = useCallback17(() => setToast(null), []);
|
|
4195
4522
|
if (!ui || !slip.onAddToSlip || legs.length < 2) return null;
|
|
4196
4523
|
const settled = slipState ? slipState.settled : settledLocal;
|
|
4197
4524
|
const open = legs.filter((leg) => !settled[leg.matchOddsId]);
|
|
@@ -4301,7 +4628,7 @@ function ComboCardList({ cards, ui, slip, monitor }) {
|
|
|
4301
4628
|
}
|
|
4302
4629
|
|
|
4303
4630
|
// src/components/MarketOddsCardList.tsx
|
|
4304
|
-
import { useEffect as
|
|
4631
|
+
import { useEffect as useEffect18, useState as useState22 } from "react";
|
|
4305
4632
|
|
|
4306
4633
|
// src/components/AllMarketsButton.tsx
|
|
4307
4634
|
import { jsx as jsx17, jsxs as jsxs13 } from "react/jsx-runtime";
|
|
@@ -4364,7 +4691,7 @@ function fmtHhMm(iso, locale) {
|
|
|
4364
4691
|
return new Date(iso).toLocaleTimeString(locale, { hour: "2-digit", minute: "2-digit", hour12: false });
|
|
4365
4692
|
}
|
|
4366
4693
|
function MarketOddsCard({ vm, ui, slip, monitor, inSlipIds, hideHeader, pinRef }) {
|
|
4367
|
-
const [open, setOpen] =
|
|
4694
|
+
const [open, setOpen] = useState22(false);
|
|
4368
4695
|
const kickoffFallback = vm.kickoffUtc && ui?.bettingKickoff ? ui.bettingKickoff(vm.kickoffUtc) : void 0;
|
|
4369
4696
|
const kickoff = vm.kickoffLabel ?? (kickoffFallback ? `${kickoffFallback.dayLabel} ${kickoffFallback.time}` : void 0);
|
|
4370
4697
|
const hasNamedTeams = !!vm.homeTeamName && !!vm.awayTeamName;
|
|
@@ -4374,9 +4701,9 @@ function MarketOddsCard({ vm, ui, slip, monitor, inSlipIds, hideHeader, pinRef }
|
|
|
4374
4701
|
const asOfMs = live ? new Date(live.asOfUtc).getTime() : NaN;
|
|
4375
4702
|
const isStale = live != null && !isClosed && (vm.awaitingLiveUpdate === true || Date.now() - asOfMs > STALE_AFTER_MS);
|
|
4376
4703
|
const staleTime = isStale && live ? fmtHhMm(live.asOfUtc, ui?.locale ?? "en") : null;
|
|
4377
|
-
const [, setStaleTick] =
|
|
4704
|
+
const [, setStaleTick] = useState22(0);
|
|
4378
4705
|
const watchStale = live != null && !isClosed && !isStale;
|
|
4379
|
-
|
|
4706
|
+
useEffect18(() => {
|
|
4380
4707
|
if (!watchStale) return;
|
|
4381
4708
|
const id = window.setTimeout(() => setStaleTick((n) => n + 1), Math.max(0, asOfMs + STALE_AFTER_MS - Date.now()) + 1);
|
|
4382
4709
|
return () => window.clearTimeout(id);
|
|
@@ -4455,7 +4782,7 @@ function MarketOddsCardList({ cards, ui, slip, monitor, inSlipIds, hideHeader, p
|
|
|
4455
4782
|
}
|
|
4456
4783
|
|
|
4457
4784
|
// src/components/CompactOddsList.tsx
|
|
4458
|
-
import { useEffect as
|
|
4785
|
+
import { useEffect as useEffect19, useRef as useRef18, useState as useState23 } from "react";
|
|
4459
4786
|
|
|
4460
4787
|
// src/compactList.ts
|
|
4461
4788
|
var COMPACT_MIN_CARDS = 3;
|
|
@@ -4569,11 +4896,11 @@ function Row({ row, columns, ui, slip, monitor, rowRef }) {
|
|
|
4569
4896
|
] });
|
|
4570
4897
|
}
|
|
4571
4898
|
function CompactOddsList({ list, ui, slip, monitor }) {
|
|
4572
|
-
const [shown, setShown] =
|
|
4899
|
+
const [shown, setShown] = useState23(COMPACT_PAGE);
|
|
4573
4900
|
const hidden = list.rowCount - shown;
|
|
4574
|
-
const [focusIndex, setFocusIndex] =
|
|
4575
|
-
const focusRef =
|
|
4576
|
-
|
|
4901
|
+
const [focusIndex, setFocusIndex] = useState23(null);
|
|
4902
|
+
const focusRef = useRef18(null);
|
|
4903
|
+
useEffect19(() => {
|
|
4577
4904
|
if (focusIndex !== null) focusRef.current?.focus();
|
|
4578
4905
|
}, [focusIndex]);
|
|
4579
4906
|
let left = shown;
|
|
@@ -4878,7 +5205,7 @@ function FixtureCard({ card }) {
|
|
|
4878
5205
|
}
|
|
4879
5206
|
|
|
4880
5207
|
// src/components/dashboard/CountdownCard.tsx
|
|
4881
|
-
import { Fragment as Fragment6, useEffect as
|
|
5208
|
+
import { Fragment as Fragment6, useEffect as useEffect20, useState as useState24 } from "react";
|
|
4882
5209
|
import { jsx as jsx25, jsxs as jsxs21 } from "react/jsx-runtime";
|
|
4883
5210
|
var DAY_MS = 864e5;
|
|
4884
5211
|
function remainingSegments(kickoffUnix, nowMs, withSeconds) {
|
|
@@ -4897,12 +5224,12 @@ function remainingSegments(kickoffUnix, nowMs, withSeconds) {
|
|
|
4897
5224
|
function CountdownCard({ card }) {
|
|
4898
5225
|
const { data } = card;
|
|
4899
5226
|
const unitLabel = { d: data.daysUnit, h: data.hoursUnit, m: data.minutesUnit, s: data.secondsUnit };
|
|
4900
|
-
const [nowMs, setNowMs] =
|
|
4901
|
-
const [reduced] =
|
|
5227
|
+
const [nowMs, setNowMs] = useState24(() => Date.now());
|
|
5228
|
+
const [reduced] = useState24(
|
|
4902
5229
|
() => typeof window !== "undefined" && window.matchMedia("(prefers-reduced-motion: reduce)").matches
|
|
4903
5230
|
);
|
|
4904
5231
|
const withinDay = data.kickoffUnix * 1e3 - nowMs < DAY_MS;
|
|
4905
|
-
|
|
5232
|
+
useEffect20(() => {
|
|
4906
5233
|
if (reduced) return;
|
|
4907
5234
|
const id = window.setInterval(() => setNowMs(Date.now()), withinDay ? 1e3 : 6e4);
|
|
4908
5235
|
return () => window.clearInterval(id);
|
|
@@ -4921,7 +5248,7 @@ function CountdownCard({ card }) {
|
|
|
4921
5248
|
}
|
|
4922
5249
|
|
|
4923
5250
|
// src/components/dashboard/InjuriesCard.tsx
|
|
4924
|
-
import { useState as
|
|
5251
|
+
import { useState as useState25 } from "react";
|
|
4925
5252
|
import { jsx as jsx26, jsxs as jsxs22 } from "react/jsx-runtime";
|
|
4926
5253
|
var SHOWN = 3;
|
|
4927
5254
|
function ColHead({ name, crestUrl }) {
|
|
@@ -4944,7 +5271,7 @@ function InjuryList({ rows, emptyLabel, limit }) {
|
|
|
4944
5271
|
}
|
|
4945
5272
|
function InjuriesCard({ card, ui }) {
|
|
4946
5273
|
const { data } = card;
|
|
4947
|
-
const [expanded, setExpanded] =
|
|
5274
|
+
const [expanded, setExpanded] = useState25(false);
|
|
4948
5275
|
const hidden = Math.max(0, data.ours.length - SHOWN) + Math.max(0, data.theirs.length - SHOWN);
|
|
4949
5276
|
const limit = expanded ? void 0 : SHOWN;
|
|
4950
5277
|
const showMore = ui?.showMore ?? ((n) => `Show ${n} more`);
|
|
@@ -5050,7 +5377,7 @@ function LinksCard({ card }) {
|
|
|
5050
5377
|
}
|
|
5051
5378
|
|
|
5052
5379
|
// src/components/dashboard/PostMatchResultCard.tsx
|
|
5053
|
-
import { useState as
|
|
5380
|
+
import { useState as useState26 } from "react";
|
|
5054
5381
|
import { jsx as jsx32, jsxs as jsxs28 } from "react/jsx-runtime";
|
|
5055
5382
|
function initials3(name) {
|
|
5056
5383
|
return name.trim().slice(0, 3).toUpperCase();
|
|
@@ -5060,7 +5387,7 @@ function PostMatchCrest({
|
|
|
5060
5387
|
name,
|
|
5061
5388
|
side
|
|
5062
5389
|
}) {
|
|
5063
|
-
const [failed, setFailed] =
|
|
5390
|
+
const [failed, setFailed] = useState26(false);
|
|
5064
5391
|
const cls = `ss-w-fandash-postmatch-crest ss-w-fandash-postmatch-crest--${side}`;
|
|
5065
5392
|
if (url && !failed) {
|
|
5066
5393
|
return /* @__PURE__ */ jsx32("img", { className: cls, src: url, alt: "", "aria-hidden": "true", onError: () => setFailed(true) });
|
|
@@ -5259,10 +5586,10 @@ function RestingFormCard({ card }) {
|
|
|
5259
5586
|
}
|
|
5260
5587
|
|
|
5261
5588
|
// src/components/dashboard/LiveScoreCard.tsx
|
|
5262
|
-
import { useRef as
|
|
5589
|
+
import { useRef as useRef19, useState as useState28 } from "react";
|
|
5263
5590
|
|
|
5264
5591
|
// src/useLiveClock.ts
|
|
5265
|
-
import { useEffect as
|
|
5592
|
+
import { useEffect as useEffect21, useState as useState27 } from "react";
|
|
5266
5593
|
var TICK_MS = 6e4;
|
|
5267
5594
|
var MAX_LIVE_TICK_MINUTES = 15;
|
|
5268
5595
|
function computeDisplayMinute(minute, clockRunning, receivedAtMs) {
|
|
@@ -5271,10 +5598,10 @@ function computeDisplayMinute(minute, clockRunning, receivedAtMs) {
|
|
|
5271
5598
|
return minute + Math.min(Math.max(0, elapsedMinutes), MAX_LIVE_TICK_MINUTES);
|
|
5272
5599
|
}
|
|
5273
5600
|
function useLiveClock(minute, clockRunning, receivedAtMs) {
|
|
5274
|
-
const [displayMinute, setDisplayMinute] =
|
|
5601
|
+
const [displayMinute, setDisplayMinute] = useState27(
|
|
5275
5602
|
() => computeDisplayMinute(minute, clockRunning, receivedAtMs)
|
|
5276
5603
|
);
|
|
5277
|
-
|
|
5604
|
+
useEffect21(() => {
|
|
5278
5605
|
setDisplayMinute(computeDisplayMinute(minute, clockRunning, receivedAtMs));
|
|
5279
5606
|
if (!clockRunning) return;
|
|
5280
5607
|
const id = window.setInterval(() => {
|
|
@@ -5291,7 +5618,7 @@ function initials5(name) {
|
|
|
5291
5618
|
return name.trim().slice(0, 3).toUpperCase();
|
|
5292
5619
|
}
|
|
5293
5620
|
function LiveCrest({ url, name, side }) {
|
|
5294
|
-
const [failed, setFailed] =
|
|
5621
|
+
const [failed, setFailed] = useState28(false);
|
|
5295
5622
|
const cls = `ss-w-fandash-live-crest ss-w-fandash-live-crest--${side}`;
|
|
5296
5623
|
if (url && !failed) {
|
|
5297
5624
|
return /* @__PURE__ */ jsx41("img", { className: cls, src: url, alt: "", "aria-hidden": "true", onError: () => setFailed(true) });
|
|
@@ -5310,7 +5637,7 @@ function LiveScoreCard({
|
|
|
5310
5637
|
}) {
|
|
5311
5638
|
const { data } = card;
|
|
5312
5639
|
const seedKey = `${data.minute}:${data.homeScore}:${data.awayScore}`;
|
|
5313
|
-
const seedRef =
|
|
5640
|
+
const seedRef = useRef19(null);
|
|
5314
5641
|
if (!seedRef.current || seedRef.current.key !== seedKey) {
|
|
5315
5642
|
seedRef.current = { key: seedKey, receivedAtMs: Date.now() };
|
|
5316
5643
|
}
|
|
@@ -5350,7 +5677,7 @@ function LiveScoreCard({
|
|
|
5350
5677
|
}
|
|
5351
5678
|
|
|
5352
5679
|
// src/components/dashboard/LiveTimelineCard.tsx
|
|
5353
|
-
import { useState as
|
|
5680
|
+
import { useState as useState29 } from "react";
|
|
5354
5681
|
import { jsx as jsx42, jsxs as jsxs38 } from "react/jsx-runtime";
|
|
5355
5682
|
var SHOWN2 = 3;
|
|
5356
5683
|
function EventIcon({ type }) {
|
|
@@ -5392,7 +5719,7 @@ function EventRow({ e }) {
|
|
|
5392
5719
|
] });
|
|
5393
5720
|
}
|
|
5394
5721
|
function LiveTimelineCard({ card, ui }) {
|
|
5395
|
-
const [expanded, setExpanded] =
|
|
5722
|
+
const [expanded, setExpanded] = useState29(false);
|
|
5396
5723
|
const events = card.data.events;
|
|
5397
5724
|
if (!events || events.length === 0) return null;
|
|
5398
5725
|
const sorted = [...events].sort((a, b) => b.minute - a.minute);
|
|
@@ -5634,11 +5961,11 @@ function turnAnchor(messages) {
|
|
|
5634
5961
|
}
|
|
5635
5962
|
function MessageList({ controller, ui, slip, onDashboardTap, monitor }) {
|
|
5636
5963
|
const { state, send } = controller;
|
|
5637
|
-
const listRef =
|
|
5638
|
-
const endRef =
|
|
5639
|
-
const pinnedRef =
|
|
5640
|
-
const anchoredTurnRef =
|
|
5641
|
-
|
|
5964
|
+
const listRef = useRef20(null);
|
|
5965
|
+
const endRef = useRef20(null);
|
|
5966
|
+
const pinnedRef = useRef20(true);
|
|
5967
|
+
const anchoredTurnRef = useRef20(null);
|
|
5968
|
+
useEffect22(() => {
|
|
5642
5969
|
const anchor = turnAnchor(state.messages);
|
|
5643
5970
|
const list = listRef.current;
|
|
5644
5971
|
if (anchor && anchor.turnId !== anchoredTurnRef.current) {
|
|
@@ -5695,13 +6022,13 @@ function MessageList({ controller, ui, slip, onDashboardTap, monitor }) {
|
|
|
5695
6022
|
}
|
|
5696
6023
|
|
|
5697
6024
|
// src/components/ChatInput.tsx
|
|
5698
|
-
import { forwardRef, useEffect as
|
|
6025
|
+
import { forwardRef, useEffect as useEffect23, useImperativeHandle, useRef as useRef21, useState as useState30 } from "react";
|
|
5699
6026
|
import { jsx as jsx49, jsxs as jsxs44 } from "react/jsx-runtime";
|
|
5700
6027
|
var ChatInput = forwardRef(function ChatInput2({ placeholder, streaming, onSend, onStop, stopLabel = "Stop response", sendLabel = "Send message", disabled = false, onType }, ref) {
|
|
5701
|
-
const [value, setValue] =
|
|
5702
|
-
const textareaRef =
|
|
5703
|
-
const stopRef =
|
|
5704
|
-
const textBoxWantsFocusRef =
|
|
6028
|
+
const [value, setValue] = useState30("");
|
|
6029
|
+
const textareaRef = useRef21(null);
|
|
6030
|
+
const stopRef = useRef21(null);
|
|
6031
|
+
const textBoxWantsFocusRef = useRef21(false);
|
|
5705
6032
|
const submit = () => {
|
|
5706
6033
|
if (disabled) return;
|
|
5707
6034
|
const t = value.trim();
|
|
@@ -5727,7 +6054,7 @@ var ChatInput = forwardRef(function ChatInput2({ placeholder, streaming, onSend,
|
|
|
5727
6054
|
stopRef.current?.focus();
|
|
5728
6055
|
}
|
|
5729
6056
|
}), []);
|
|
5730
|
-
|
|
6057
|
+
useEffect23(() => {
|
|
5731
6058
|
if (streaming || disabled || !textBoxWantsFocusRef.current) return;
|
|
5732
6059
|
textBoxWantsFocusRef.current = false;
|
|
5733
6060
|
const box = textareaRef.current;
|
|
@@ -5759,6 +6086,7 @@ var ChatInput = forwardRef(function ChatInput2({ placeholder, streaming, onSend,
|
|
|
5759
6086
|
});
|
|
5760
6087
|
|
|
5761
6088
|
// src/components/TabBar.tsx
|
|
6089
|
+
import { useEffect as useEffect24, useRef as useRef22 } from "react";
|
|
5762
6090
|
import { jsx as jsx50, jsxs as jsxs45 } from "react/jsx-runtime";
|
|
5763
6091
|
function TabBar({ monitor, ui, matchCount, oddsCount, todayCount, hasToday, gamesEnabled, clubEnabled }) {
|
|
5764
6092
|
const tabs = [
|
|
@@ -5774,8 +6102,16 @@ function TabBar({ monitor, ui, matchCount, oddsCount, todayCount, hasToday, game
|
|
|
5774
6102
|
],
|
|
5775
6103
|
...gamesEnabled ? [{ tab: "games", label: ui.tabGames, count: 0, dot: false }] : []
|
|
5776
6104
|
];
|
|
6105
|
+
const listRef = useRef22(null);
|
|
6106
|
+
const activeTab = monitor.activeTab;
|
|
6107
|
+
useEffect24(() => {
|
|
6108
|
+
const el = listRef.current?.querySelector("[data-on]");
|
|
6109
|
+
if (!el || typeof el.scrollIntoView !== "function") return;
|
|
6110
|
+
const reduce = typeof window.matchMedia === "function" && window.matchMedia("(prefers-reduced-motion: reduce)").matches;
|
|
6111
|
+
el.scrollIntoView({ block: "nearest", inline: "nearest", behavior: reduce ? "auto" : "smooth" });
|
|
6112
|
+
}, [activeTab]);
|
|
5777
6113
|
if (tabs.length < 2) return null;
|
|
5778
|
-
return /* @__PURE__ */ jsx50("div", { className: "ss-w-tabs", role: "tablist", children: tabs.map(({ tab, label, count, dot }) => {
|
|
6114
|
+
return /* @__PURE__ */ jsx50("div", { className: "ss-w-tabs", role: "tablist", ref: listRef, children: tabs.map(({ tab, label, count, dot }) => {
|
|
5779
6115
|
const active = monitor.activeTab === tab;
|
|
5780
6116
|
return /* @__PURE__ */ jsxs45(
|
|
5781
6117
|
"button",
|
|
@@ -5852,10 +6188,10 @@ function MarketAccordion({ match, monitor, ui, slip }) {
|
|
|
5852
6188
|
}
|
|
5853
6189
|
|
|
5854
6190
|
// src/components/LiveFactBlock.tsx
|
|
5855
|
-
import { useState as
|
|
6191
|
+
import { useState as useState31 } from "react";
|
|
5856
6192
|
import { jsx as jsx52, jsxs as jsxs47 } from "react/jsx-runtime";
|
|
5857
6193
|
function LiveFactBlock({ facts, matchId, ui, slip, onAsk }) {
|
|
5858
|
-
const [expanded, setExpanded] =
|
|
6194
|
+
const [expanded, setExpanded] = useState31(false);
|
|
5859
6195
|
const [current, ...earlier] = facts;
|
|
5860
6196
|
if (!current) return null;
|
|
5861
6197
|
const m = current.market;
|
|
@@ -6121,7 +6457,7 @@ function OddsPanel({ monitor, ui, slip }) {
|
|
|
6121
6457
|
}
|
|
6122
6458
|
|
|
6123
6459
|
// src/components/TodayPanel.tsx
|
|
6124
|
-
import { useEffect as
|
|
6460
|
+
import { useEffect as useEffect26, useId as useId2, useMemo as useMemo4, useState as useState34 } from "react";
|
|
6125
6461
|
|
|
6126
6462
|
// src/placement.ts
|
|
6127
6463
|
function placeLeagues(visible, pinnedMatchIds) {
|
|
@@ -6184,11 +6520,11 @@ function matchingFixtures(group, query) {
|
|
|
6184
6520
|
}
|
|
6185
6521
|
|
|
6186
6522
|
// src/useStarTap.ts
|
|
6187
|
-
import { useCallback as
|
|
6523
|
+
import { useCallback as useCallback18, useRef as useRef23, useState as useState32 } from "react";
|
|
6188
6524
|
function useStarTap(starLeague) {
|
|
6189
|
-
const [pendingId, setPendingId] =
|
|
6190
|
-
const pendingRef =
|
|
6191
|
-
const tap =
|
|
6525
|
+
const [pendingId, setPendingId] = useState32(null);
|
|
6526
|
+
const pendingRef = useRef23(null);
|
|
6527
|
+
const tap = useCallback18(async (competitionId, next) => {
|
|
6192
6528
|
if (pendingRef.current !== null) return false;
|
|
6193
6529
|
pendingRef.current = competitionId;
|
|
6194
6530
|
setPendingId(competitionId);
|
|
@@ -6247,7 +6583,7 @@ function LeagueTile({ group, starClickable: starClickable2, disambiguate, onOpen
|
|
|
6247
6583
|
}
|
|
6248
6584
|
|
|
6249
6585
|
// src/components/LeagueDetail.tsx
|
|
6250
|
-
import { useEffect as
|
|
6586
|
+
import { useEffect as useEffect25, useState as useState33 } from "react";
|
|
6251
6587
|
|
|
6252
6588
|
// src/components/FixtureRow.tsx
|
|
6253
6589
|
import { jsx as jsx56, jsxs as jsxs51 } from "react/jsx-runtime";
|
|
@@ -6282,11 +6618,11 @@ function FixtureRow({ match, state, stale, ui, monitor }) {
|
|
|
6282
6618
|
import { jsx as jsx57, jsxs as jsxs52 } from "react/jsx-runtime";
|
|
6283
6619
|
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";
|
|
6284
6620
|
function LeagueDetail({ group, position, states, stale, ui, monitor, starTap, onBack, onPrev, onNext }) {
|
|
6285
|
-
const [toast, setToast] =
|
|
6286
|
-
|
|
6621
|
+
const [toast, setToast] = useState33(null);
|
|
6622
|
+
useEffect25(() => {
|
|
6287
6623
|
setToast(null);
|
|
6288
6624
|
}, [group.competitionId]);
|
|
6289
|
-
|
|
6625
|
+
useEffect25(() => {
|
|
6290
6626
|
if (toast === null) return;
|
|
6291
6627
|
const id = setTimeout(() => setToast(null), 4e3);
|
|
6292
6628
|
return () => clearTimeout(id);
|
|
@@ -6418,7 +6754,7 @@ function LeagueRowGroup({ group, states, stale, cap, starClickable: starClickabl
|
|
|
6418
6754
|
}
|
|
6419
6755
|
|
|
6420
6756
|
// src/components/games/ui/SearchField.tsx
|
|
6421
|
-
import { useCallback as
|
|
6757
|
+
import { useCallback as useCallback19, useRef as useRef24 } from "react";
|
|
6422
6758
|
|
|
6423
6759
|
// src/components/games/ui/icons.tsx
|
|
6424
6760
|
import { jsx as jsx59 } from "react/jsx-runtime";
|
|
@@ -6457,8 +6793,8 @@ var IconFlame = ({ size = 16 }) => svg(size, /* @__PURE__ */ jsx59("path", { d:
|
|
|
6457
6793
|
// src/components/games/ui/SearchField.tsx
|
|
6458
6794
|
import { jsx as jsx60, jsxs as jsxs54 } from "react/jsx-runtime";
|
|
6459
6795
|
function SearchField({ id, label, labelHidden = false, placeholder, value, onChange, disabled, inputRef, onKeyDown, clearLabel }) {
|
|
6460
|
-
const localRef =
|
|
6461
|
-
const setInputRef =
|
|
6796
|
+
const localRef = useRef24(null);
|
|
6797
|
+
const setInputRef = useCallback19((node) => {
|
|
6462
6798
|
localRef.current = node;
|
|
6463
6799
|
if (typeof inputRef === "function") inputRef(node);
|
|
6464
6800
|
else if (inputRef) inputRef.current = node;
|
|
@@ -6503,10 +6839,10 @@ import { Fragment as Fragment7, jsx as jsx61, jsxs as jsxs55 } from "react/jsx-r
|
|
|
6503
6839
|
function TodayPanel({ discovery, ui, monitor }) {
|
|
6504
6840
|
const { groups, states, stale, starLeague } = discovery;
|
|
6505
6841
|
const searchId = useId2();
|
|
6506
|
-
const [query, setQuery] =
|
|
6507
|
-
const [selectedCompetitionId, setSelectedCompetitionId] =
|
|
6508
|
-
const [toast, setToast] =
|
|
6509
|
-
|
|
6842
|
+
const [query, setQuery] = useState34("");
|
|
6843
|
+
const [selectedCompetitionId, setSelectedCompetitionId] = useState34(null);
|
|
6844
|
+
const [toast, setToast] = useState34(null);
|
|
6845
|
+
useEffect26(() => {
|
|
6510
6846
|
if (toast === null) return;
|
|
6511
6847
|
const id = setTimeout(() => setToast(null), 4e3);
|
|
6512
6848
|
return () => clearTimeout(id);
|
|
@@ -6552,7 +6888,7 @@ function TodayPanel({ discovery, ui, monitor }) {
|
|
|
6552
6888
|
}
|
|
6553
6889
|
const openIndex = selectedCompetitionId === null ? -1 : placement.order.findIndex((g) => g.competitionId === selectedCompetitionId);
|
|
6554
6890
|
const openGroup = openIndex === -1 ? void 0 : placement.order[openIndex];
|
|
6555
|
-
|
|
6891
|
+
useEffect26(() => {
|
|
6556
6892
|
if (selectedCompetitionId !== null && openGroup === void 0) setSelectedCompetitionId(null);
|
|
6557
6893
|
}, [selectedCompetitionId, openGroup]);
|
|
6558
6894
|
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);
|
|
@@ -6699,7 +7035,7 @@ function TodayPanel({ discovery, ui, monitor }) {
|
|
|
6699
7035
|
}
|
|
6700
7036
|
|
|
6701
7037
|
// src/components/GamesPanel.tsx
|
|
6702
|
-
import { useEffect as
|
|
7038
|
+
import { useEffect as useEffect30, useState as useState49 } from "react";
|
|
6703
7039
|
|
|
6704
7040
|
// src/components/GamesLoginWall.tsx
|
|
6705
7041
|
import { jsx as jsx62 } from "react/jsx-runtime";
|
|
@@ -6708,7 +7044,7 @@ function GamesLoginWall({ ui }) {
|
|
|
6708
7044
|
}
|
|
6709
7045
|
|
|
6710
7046
|
// src/components/GamesHub.tsx
|
|
6711
|
-
import { useEffect as
|
|
7047
|
+
import { useEffect as useEffect27, useState as useState35 } from "react";
|
|
6712
7048
|
|
|
6713
7049
|
// src/components/games/ui/gameMeta.ts
|
|
6714
7050
|
function prettifyGameId(gameId) {
|
|
@@ -6859,8 +7195,8 @@ function pickHeroGame(games) {
|
|
|
6859
7195
|
}
|
|
6860
7196
|
var tileKey = (g) => `${g.gameId}-${g.gameDay}-${g.fixtureId}`;
|
|
6861
7197
|
function GamesHub({ games, myWeeklyRow, weeklyPrize, onOpen, ui }) {
|
|
6862
|
-
const [, setTick] =
|
|
6863
|
-
|
|
7198
|
+
const [, setTick] = useState35(0);
|
|
7199
|
+
useEffect27(() => {
|
|
6864
7200
|
const id = setInterval(() => setTick((t) => t + 1), 6e4);
|
|
6865
7201
|
return () => clearInterval(id);
|
|
6866
7202
|
}, []);
|
|
@@ -6920,10 +7256,10 @@ function GamesHub({ games, myWeeklyRow, weeklyPrize, onOpen, ui }) {
|
|
|
6920
7256
|
}
|
|
6921
7257
|
|
|
6922
7258
|
// src/components/GameScreenHost.tsx
|
|
6923
|
-
import { useEffect as
|
|
7259
|
+
import { useEffect as useEffect29, useRef as useRef27, useState as useState47 } from "react";
|
|
6924
7260
|
|
|
6925
7261
|
// src/useGamePlay.ts
|
|
6926
|
-
import { useCallback as
|
|
7262
|
+
import { useCallback as useCallback20, useRef as useRef25, useState as useState36 } from "react";
|
|
6927
7263
|
function toSubmitResult(payload) {
|
|
6928
7264
|
return {
|
|
6929
7265
|
// 'pending' means the play is recorded but awaiting resolution (fixture games)
|
|
@@ -6935,17 +7271,17 @@ function toSubmitResult(payload) {
|
|
|
6935
7271
|
};
|
|
6936
7272
|
}
|
|
6937
7273
|
function useGamePlay(conversation, { gameId, gameDay, fixtureId, locale, refresh }) {
|
|
6938
|
-
const [result, setResult] =
|
|
6939
|
-
const [submitting, setSubmitting] =
|
|
6940
|
-
const [rawStatus, setRawStatus] =
|
|
6941
|
-
const inFlightRef =
|
|
6942
|
-
const convRef =
|
|
7274
|
+
const [result, setResult] = useState36(null);
|
|
7275
|
+
const [submitting, setSubmitting] = useState36(false);
|
|
7276
|
+
const [rawStatus, setRawStatus] = useState36(null);
|
|
7277
|
+
const inFlightRef = useRef25(false);
|
|
7278
|
+
const convRef = useRef25(conversation);
|
|
6943
7279
|
convRef.current = conversation;
|
|
6944
|
-
const optsRef =
|
|
7280
|
+
const optsRef = useRef25({ gameId, gameDay, fixtureId, locale, refresh });
|
|
6945
7281
|
optsRef.current = { gameId, gameDay, fixtureId, locale, refresh };
|
|
6946
|
-
const resultRef =
|
|
7282
|
+
const resultRef = useRef25(null);
|
|
6947
7283
|
resultRef.current = result;
|
|
6948
|
-
const refetch =
|
|
7284
|
+
const refetch = useCallback20(async () => {
|
|
6949
7285
|
const conv = convRef.current;
|
|
6950
7286
|
if (!conv) return;
|
|
6951
7287
|
const opts = optsRef.current;
|
|
@@ -6961,7 +7297,7 @@ function useGamePlay(conversation, { gameId, gameDay, fixtureId, locale, refresh
|
|
|
6961
7297
|
} catch {
|
|
6962
7298
|
}
|
|
6963
7299
|
}, []);
|
|
6964
|
-
const submit =
|
|
7300
|
+
const submit = useCallback20(async (answerJson) => {
|
|
6965
7301
|
const conv = convRef.current;
|
|
6966
7302
|
if (!conv || inFlightRef.current) return;
|
|
6967
7303
|
inFlightRef.current = true;
|
|
@@ -6988,14 +7324,14 @@ function useGamePlay(conversation, { gameId, gameDay, fixtureId, locale, refresh
|
|
|
6988
7324
|
setSubmitting(false);
|
|
6989
7325
|
}
|
|
6990
7326
|
}, [refetch]);
|
|
6991
|
-
const hydrate =
|
|
7327
|
+
const hydrate = useCallback20(() => {
|
|
6992
7328
|
void refetch();
|
|
6993
7329
|
}, [refetch]);
|
|
6994
7330
|
return { result, submitting, submit, hydrate, rawStatus };
|
|
6995
7331
|
}
|
|
6996
7332
|
|
|
6997
7333
|
// src/components/games/MysteryTigerGame.tsx
|
|
6998
|
-
import { useState as
|
|
7334
|
+
import { useState as useState38, useId as useId3 } from "react";
|
|
6999
7335
|
|
|
7000
7336
|
// src/components/games/nationFlags.ts
|
|
7001
7337
|
var FLAGS = {
|
|
@@ -7206,7 +7542,7 @@ function isNationCode(flag) {
|
|
|
7206
7542
|
}
|
|
7207
7543
|
|
|
7208
7544
|
// src/components/games/PlayerAvatar.tsx
|
|
7209
|
-
import { useState as
|
|
7545
|
+
import { useState as useState37 } from "react";
|
|
7210
7546
|
import { jsx as jsx67 } from "react/jsx-runtime";
|
|
7211
7547
|
function initialsOf(name) {
|
|
7212
7548
|
const parts = name.trim().split(/\s+/).filter(Boolean);
|
|
@@ -7224,7 +7560,7 @@ function PlayerAvatar({
|
|
|
7224
7560
|
imagePath,
|
|
7225
7561
|
className
|
|
7226
7562
|
}) {
|
|
7227
|
-
const [failed, setFailed] =
|
|
7563
|
+
const [failed, setFailed] = useState37(false);
|
|
7228
7564
|
const showImage = Boolean(imagePath) && !isPlaceholderImage(imagePath) && !failed;
|
|
7229
7565
|
return /* @__PURE__ */ jsx67("div", { className, "aria-hidden": "true", children: showImage ? /* @__PURE__ */ jsx67("img", { src: imagePath, alt: "", loading: "lazy", onError: () => setFailed(true) }) : /* @__PURE__ */ jsx67("span", { className: "ss-w-av-initials", children: initialsOf(name) }) });
|
|
7230
7566
|
}
|
|
@@ -7465,7 +7801,7 @@ function MysteryTigerGame({
|
|
|
7465
7801
|
onBack
|
|
7466
7802
|
}) {
|
|
7467
7803
|
const t = ui.games.mysteryTiger;
|
|
7468
|
-
const [query, setQuery] =
|
|
7804
|
+
const [query, setQuery] = useState38("");
|
|
7469
7805
|
const inputId = useId3();
|
|
7470
7806
|
const clientState = parseClientState(result?.clientStateJson);
|
|
7471
7807
|
const guessResults = clientState?.guessResults ?? [];
|
|
@@ -7727,13 +8063,13 @@ function HigherOrLowerGame({
|
|
|
7727
8063
|
}
|
|
7728
8064
|
|
|
7729
8065
|
// src/components/games/CareerPathGame.tsx
|
|
7730
|
-
import { useState as
|
|
8066
|
+
import { useState as useState40, useId as useId4 } from "react";
|
|
7731
8067
|
|
|
7732
8068
|
// src/components/games/ui/CrestShield.tsx
|
|
7733
|
-
import { useState as
|
|
8069
|
+
import { useState as useState39 } from "react";
|
|
7734
8070
|
import { jsx as jsx78 } from "react/jsx-runtime";
|
|
7735
8071
|
function CrestShield({ src, name, size = 28 }) {
|
|
7736
|
-
const [failed, setFailed] =
|
|
8072
|
+
const [failed, setFailed] = useState39(false);
|
|
7737
8073
|
if (src && !isPlaceholderImage(src) && !failed) {
|
|
7738
8074
|
return /* @__PURE__ */ jsx78("img", { className: "ss-g-crest", src, alt: name, width: size, height: size, loading: "lazy", onError: () => setFailed(true) });
|
|
7739
8075
|
}
|
|
@@ -7765,7 +8101,7 @@ function CareerPathGame({
|
|
|
7765
8101
|
}) {
|
|
7766
8102
|
const s = ui.games.careerPath;
|
|
7767
8103
|
const title = gameTitle({ gameId: "career-path" }, ui.games.titles);
|
|
7768
|
-
const [query, setQuery] =
|
|
8104
|
+
const [query, setQuery] = useState40("");
|
|
7769
8105
|
const inputId = useId4();
|
|
7770
8106
|
const clientState = parseClientState3(result?.clientStateJson);
|
|
7771
8107
|
const alreadyGuessedIds = new Set(clientState?.guessResults.map((g) => g.playerId) ?? []);
|
|
@@ -7872,7 +8208,7 @@ function CareerPathGame({
|
|
|
7872
8208
|
}
|
|
7873
8209
|
|
|
7874
8210
|
// src/components/games/BeatTheGridGame.tsx
|
|
7875
|
-
import React, { useEffect as
|
|
8211
|
+
import React, { useEffect as useEffect28, useId as useId5, useRef as useRef26, useState as useState41 } from "react";
|
|
7876
8212
|
|
|
7877
8213
|
// src/components/games/ui/OptionList.tsx
|
|
7878
8214
|
import { jsx as jsx80 } from "react/jsx-runtime";
|
|
@@ -7961,10 +8297,10 @@ function SearchSheet({
|
|
|
7961
8297
|
ui
|
|
7962
8298
|
}) {
|
|
7963
8299
|
const s = ui.games.beatTheGrid;
|
|
7964
|
-
const [query, setQuery] =
|
|
8300
|
+
const [query, setQuery] = useState41("");
|
|
7965
8301
|
const inputId = useId5();
|
|
7966
|
-
const inputRef =
|
|
7967
|
-
|
|
8302
|
+
const inputRef = useRef26(null);
|
|
8303
|
+
useEffect28(() => {
|
|
7968
8304
|
inputRef.current?.focus();
|
|
7969
8305
|
}, [row, col]);
|
|
7970
8306
|
const filtered = playerPool.filter(
|
|
@@ -8029,7 +8365,7 @@ function BeatTheGridGame({
|
|
|
8029
8365
|
}) {
|
|
8030
8366
|
const s = ui.games.beatTheGrid;
|
|
8031
8367
|
const title = gameTitle({ gameId: "beat-the-grid" }, ui.games.titles);
|
|
8032
|
-
const [activeCell, setActiveCell] =
|
|
8368
|
+
const [activeCell, setActiveCell] = useState41(null);
|
|
8033
8369
|
const clientState = parseClientState4(result?.clientStateJson);
|
|
8034
8370
|
const filledCells = clientState?.cells ?? [];
|
|
8035
8371
|
const isLocked2 = result?.alreadyPlayed === true || clientState?.isComplete === true;
|
|
@@ -8184,7 +8520,7 @@ function BeatTheGridGame({
|
|
|
8184
8520
|
}
|
|
8185
8521
|
|
|
8186
8522
|
// src/components/games/GuessTheXiGame.tsx
|
|
8187
|
-
import { useState as
|
|
8523
|
+
import { useState as useState42, useId as useId6 } from "react";
|
|
8188
8524
|
|
|
8189
8525
|
// src/components/games/ui/PitchSvg.tsx
|
|
8190
8526
|
import { Fragment as Fragment16, jsx as jsx82, jsxs as jsxs70 } from "react/jsx-runtime";
|
|
@@ -8273,7 +8609,7 @@ function GuessTheXiGame({
|
|
|
8273
8609
|
onBack
|
|
8274
8610
|
}) {
|
|
8275
8611
|
const t = ui.games.guessTheXi;
|
|
8276
|
-
const [query, setQuery] =
|
|
8612
|
+
const [query, setQuery] = useState42("");
|
|
8277
8613
|
const inputId = useId6();
|
|
8278
8614
|
const clientState = parseClientState5(result?.clientStateJson);
|
|
8279
8615
|
const isOver = result?.alreadyPlayed === true || clientState?.status === "solved" || clientState?.status === "failed";
|
|
@@ -8416,7 +8752,7 @@ function GuessTheXiGame({
|
|
|
8416
8752
|
}
|
|
8417
8753
|
|
|
8418
8754
|
// src/components/games/DailyQuizGame.tsx
|
|
8419
|
-
import { useState as
|
|
8755
|
+
import { useState as useState43 } from "react";
|
|
8420
8756
|
import { Fragment as Fragment18, jsx as jsx84, jsxs as jsxs72 } from "react/jsx-runtime";
|
|
8421
8757
|
function parseClientState6(json) {
|
|
8422
8758
|
if (!json) return null;
|
|
@@ -8457,8 +8793,8 @@ function DailyQuizGame({
|
|
|
8457
8793
|
}) {
|
|
8458
8794
|
const s = ui.games.dailyQuiz;
|
|
8459
8795
|
const title = gameTitle({ gameId: "daily-quiz" }, ui.games.titles);
|
|
8460
|
-
const [selections, setSelections] =
|
|
8461
|
-
const [page, setPage] =
|
|
8796
|
+
const [selections, setSelections] = useState43(/* @__PURE__ */ new Map());
|
|
8797
|
+
const [page, setPage] = useState43(0);
|
|
8462
8798
|
const clientState = parseClientState6(result?.clientStateJson);
|
|
8463
8799
|
const results = clientState?.results ?? [];
|
|
8464
8800
|
const isRevealed = results.length > 0 || result?.alreadyPlayed === true;
|
|
@@ -8568,7 +8904,7 @@ function DailyQuizGame({
|
|
|
8568
8904
|
}
|
|
8569
8905
|
|
|
8570
8906
|
// src/components/games/MatchdayPredictorGame.tsx
|
|
8571
|
-
import { useId as useId7, useState as
|
|
8907
|
+
import { useId as useId7, useState as useState44 } from "react";
|
|
8572
8908
|
import { jsx as jsx85, jsxs as jsxs73 } from "react/jsx-runtime";
|
|
8573
8909
|
var SCORER_SEARCH_THRESHOLD = 9;
|
|
8574
8910
|
function parseClientState7(json) {
|
|
@@ -8664,11 +9000,11 @@ function MatchdayPredictorGame({
|
|
|
8664
9000
|
onBack
|
|
8665
9001
|
}) {
|
|
8666
9002
|
const t = ui.games.predictor;
|
|
8667
|
-
const [homeScore, setHomeScore] =
|
|
8668
|
-
const [awayScore, setAwayScore] =
|
|
8669
|
-
const [firstScorerPlayerId, setFirstScorerPlayerId] =
|
|
8670
|
-
const [lastEdited, setLastEdited] =
|
|
8671
|
-
const [query, setQuery] =
|
|
9003
|
+
const [homeScore, setHomeScore] = useState44(0);
|
|
9004
|
+
const [awayScore, setAwayScore] = useState44(0);
|
|
9005
|
+
const [firstScorerPlayerId, setFirstScorerPlayerId] = useState44(null);
|
|
9006
|
+
const [lastEdited, setLastEdited] = useState44("home");
|
|
9007
|
+
const [query, setQuery] = useState44("");
|
|
8672
9008
|
const searchId = useId7();
|
|
8673
9009
|
const clientState = parseClientState7(result?.clientStateJson);
|
|
8674
9010
|
const alreadyPlayed = result?.alreadyPlayed === true;
|
|
@@ -8836,7 +9172,7 @@ function MatchdayPredictorGame({
|
|
|
8836
9172
|
}
|
|
8837
9173
|
|
|
8838
9174
|
// src/components/games/StartingXiGame.tsx
|
|
8839
|
-
import { useId as useId8, useState as
|
|
9175
|
+
import { useId as useId8, useState as useState45 } from "react";
|
|
8840
9176
|
import { Fragment as Fragment19, jsx as jsx86, jsxs as jsxs74 } from "react/jsx-runtime";
|
|
8841
9177
|
var POINTS_PER_STARTER = 8;
|
|
8842
9178
|
var XI_SIZE = 11;
|
|
@@ -8880,9 +9216,9 @@ function StartingXiGame({
|
|
|
8880
9216
|
lockAtUtc
|
|
8881
9217
|
}) {
|
|
8882
9218
|
const t = ui.games.startingXi;
|
|
8883
|
-
const [slotPlayers, setSlotPlayers] =
|
|
8884
|
-
const [active, setActive] =
|
|
8885
|
-
const [query, setQuery] =
|
|
9219
|
+
const [slotPlayers, setSlotPlayers] = useState45(() => Array(XI_SIZE).fill(null));
|
|
9220
|
+
const [active, setActive] = useState45(0);
|
|
9221
|
+
const [query, setQuery] = useState45("");
|
|
8886
9222
|
const searchId = useId8();
|
|
8887
9223
|
const clientState = parseClientState8(result?.clientStateJson);
|
|
8888
9224
|
const alreadyPlayed = result?.alreadyPlayed === true;
|
|
@@ -9022,7 +9358,7 @@ function StartingXiGame({
|
|
|
9022
9358
|
}
|
|
9023
9359
|
|
|
9024
9360
|
// src/components/games/StatLadderGame.tsx
|
|
9025
|
-
import { useId as useId9, useState as
|
|
9361
|
+
import { useId as useId9, useState as useState46 } from "react";
|
|
9026
9362
|
import { jsx as jsx87, jsxs as jsxs75 } from "react/jsx-runtime";
|
|
9027
9363
|
function ladderClue(ladder) {
|
|
9028
9364
|
const mystery = ladder.find((r) => r.rank === 2);
|
|
@@ -9059,8 +9395,8 @@ function StatLadderGame({
|
|
|
9059
9395
|
onBack
|
|
9060
9396
|
}) {
|
|
9061
9397
|
const t = ui.games.statLadder;
|
|
9062
|
-
const [query, setQuery] =
|
|
9063
|
-
const [selectedId, setSelectedId] =
|
|
9398
|
+
const [query, setQuery] = useState46("");
|
|
9399
|
+
const [selectedId, setSelectedId] = useState46(null);
|
|
9064
9400
|
const searchId = useId9();
|
|
9065
9401
|
const clientState = parseClientState9(result?.clientStateJson);
|
|
9066
9402
|
const revealed = clientState != null;
|
|
@@ -9267,8 +9603,8 @@ function GameScreenHost({
|
|
|
9267
9603
|
ui
|
|
9268
9604
|
}) {
|
|
9269
9605
|
const { gameId, fixtureId, gameDay = "", lockAtUtc = null } = selected;
|
|
9270
|
-
const [configJson, setConfigJson] =
|
|
9271
|
-
|
|
9606
|
+
const [configJson, setConfigJson] = useState47(null);
|
|
9607
|
+
useEffect29(() => {
|
|
9272
9608
|
setConfigJson(null);
|
|
9273
9609
|
if (!conversation) return;
|
|
9274
9610
|
let cancelled = false;
|
|
@@ -9291,12 +9627,12 @@ function GameScreenHost({
|
|
|
9291
9627
|
fixtureId: fixtureId || void 0,
|
|
9292
9628
|
locale: ui.games.lang
|
|
9293
9629
|
});
|
|
9294
|
-
|
|
9630
|
+
useEffect29(() => {
|
|
9295
9631
|
if (conversation) hydrate();
|
|
9296
9632
|
}, [conversation, gameId]);
|
|
9297
|
-
const hydrateRef =
|
|
9633
|
+
const hydrateRef = useRef27(hydrate);
|
|
9298
9634
|
hydrateRef.current = hydrate;
|
|
9299
|
-
|
|
9635
|
+
useEffect29(() => {
|
|
9300
9636
|
if (!FIXTURE_GAME_IDS.has(gameId)) return;
|
|
9301
9637
|
if (rawStatus !== "pending") return;
|
|
9302
9638
|
const timerId = setInterval(() => {
|
|
@@ -9409,7 +9745,7 @@ function GameScreenHost({
|
|
|
9409
9745
|
}
|
|
9410
9746
|
|
|
9411
9747
|
// src/components/Leaderboard.tsx
|
|
9412
|
-
import { useState as
|
|
9748
|
+
import { useState as useState48 } from "react";
|
|
9413
9749
|
|
|
9414
9750
|
// src/components/LeaderboardRow.tsx
|
|
9415
9751
|
import { jsx as jsx90, jsxs as jsxs77 } from "react/jsx-runtime";
|
|
@@ -9494,7 +9830,7 @@ function Leaderboard({
|
|
|
9494
9830
|
ui,
|
|
9495
9831
|
onPlay
|
|
9496
9832
|
}) {
|
|
9497
|
-
const [segment, setSegment] =
|
|
9833
|
+
const [segment, setSegment] = useState48("weekly");
|
|
9498
9834
|
const myRow = segment === "weekly" ? data.myWeeklyRow : data.myAllTimeRow;
|
|
9499
9835
|
const offBoard = myRow !== null && myRow !== void 0 && myRow.rank === -1;
|
|
9500
9836
|
const isEmpty = segment === "weekly" ? data.weeklyTop.length === 0 : data.allTimeTop.length === 0;
|
|
@@ -9597,9 +9933,9 @@ function GamesPanel({
|
|
|
9597
9933
|
leaderboardLoading,
|
|
9598
9934
|
refreshHub
|
|
9599
9935
|
}) {
|
|
9600
|
-
const [selected, setSelected] =
|
|
9601
|
-
const [segment, setSegment] =
|
|
9602
|
-
|
|
9936
|
+
const [selected, setSelected] = useState49(null);
|
|
9937
|
+
const [segment, setSegment] = useState49("play");
|
|
9938
|
+
useEffect30(() => {
|
|
9603
9939
|
ensureGamesFonts();
|
|
9604
9940
|
}, []);
|
|
9605
9941
|
if (!loggedIn) return /* @__PURE__ */ jsx94(GamesLoginWall, { ui });
|
|
@@ -9747,8 +10083,7 @@ function Standings({ standings, loading, ui }) {
|
|
|
9747
10083
|
] }, `${gi}-${group.table ?? "none"}`)) });
|
|
9748
10084
|
}
|
|
9749
10085
|
|
|
9750
|
-
// src/components/
|
|
9751
|
-
import { jsx as jsx97, jsxs as jsxs83 } from "react/jsx-runtime";
|
|
10086
|
+
// src/components/groupByPosition.ts
|
|
9752
10087
|
function groupByPosition(players) {
|
|
9753
10088
|
const groups = [];
|
|
9754
10089
|
for (const p of players) {
|
|
@@ -9758,26 +10093,412 @@ function groupByPosition(players) {
|
|
|
9758
10093
|
}
|
|
9759
10094
|
return groups;
|
|
9760
10095
|
}
|
|
9761
|
-
|
|
9762
|
-
|
|
9763
|
-
|
|
9764
|
-
|
|
9765
|
-
|
|
9766
|
-
|
|
9767
|
-
|
|
9768
|
-
|
|
9769
|
-
|
|
9770
|
-
|
|
10096
|
+
|
|
10097
|
+
// src/components/labels.ts
|
|
10098
|
+
function positionLabel(ui, name) {
|
|
10099
|
+
switch (name) {
|
|
10100
|
+
case "Goalkeeper":
|
|
10101
|
+
return ui.positionGoalkeeper;
|
|
10102
|
+
case "Defender":
|
|
10103
|
+
return ui.positionDefender;
|
|
10104
|
+
case "Midfielder":
|
|
10105
|
+
return ui.positionMidfielder;
|
|
10106
|
+
case "Attacker":
|
|
10107
|
+
return ui.positionAttacker;
|
|
10108
|
+
default:
|
|
10109
|
+
return name;
|
|
10110
|
+
}
|
|
10111
|
+
}
|
|
10112
|
+
function footLabel(ui, foot) {
|
|
10113
|
+
const v = foot?.trim() ?? "";
|
|
10114
|
+
if (v === "" || v.toUpperCase() === "N/A") return null;
|
|
10115
|
+
switch (v.toLowerCase()) {
|
|
10116
|
+
case "right":
|
|
10117
|
+
return ui.footRight;
|
|
10118
|
+
case "left":
|
|
10119
|
+
return ui.footLeft;
|
|
10120
|
+
case "both":
|
|
10121
|
+
return ui.footBoth;
|
|
10122
|
+
default:
|
|
10123
|
+
return v;
|
|
10124
|
+
}
|
|
10125
|
+
}
|
|
10126
|
+
var GROUP_CODE = { Goalkeeper: "GK", Defender: "DF", Midfielder: "MF", Attacker: "FW" };
|
|
10127
|
+
function positionShort(code, positionName) {
|
|
10128
|
+
const c = code?.trim().toUpperCase() ?? "";
|
|
10129
|
+
if (c !== "") return c === "CF" || c === "SS" ? "ST" : c;
|
|
10130
|
+
return positionName !== null && GROUP_CODE[positionName] || "\u2013";
|
|
10131
|
+
}
|
|
10132
|
+
function statsEyebrow(ui, season, competition, matches) {
|
|
10133
|
+
if (season === null || competition === null || matches === null || matches <= 0) return null;
|
|
10134
|
+
return ui.squadStatsEyebrow(season, competition, matches);
|
|
10135
|
+
}
|
|
10136
|
+
|
|
10137
|
+
// src/components/SquadStats.tsx
|
|
10138
|
+
import { jsx as jsx97, jsxs as jsxs83 } from "react/jsx-runtime";
|
|
10139
|
+
function leader(stats, pick) {
|
|
10140
|
+
let best = null;
|
|
10141
|
+
for (const p of stats) {
|
|
10142
|
+
if (pick(p) <= 0) continue;
|
|
10143
|
+
if (best === null || pick(p) > pick(best) || pick(p) === pick(best) && p.minutesPlayed < best.minutesPlayed) best = p;
|
|
10144
|
+
}
|
|
10145
|
+
return best;
|
|
10146
|
+
}
|
|
10147
|
+
function ratingClass(rating) {
|
|
10148
|
+
if (rating === null) return "ss-w-sq-c36 ss-w-sq-rtg-none";
|
|
10149
|
+
return Number(rating.toFixed(1)) >= 7 ? "ss-w-sq-c36 ss-w-sq-rtg ss-w-pos-ink" : "ss-w-sq-c36 ss-w-sq-rtg";
|
|
10150
|
+
}
|
|
10151
|
+
function SquadStats({ stats, loading, ui, onSelectPlayer }) {
|
|
10152
|
+
if (stats === null && loading) return /* @__PURE__ */ jsx97("div", { className: "ss-w-mon-list" });
|
|
10153
|
+
if (stats === null || stats.length === 0) return /* @__PURE__ */ jsx97("div", { className: "ss-w-mon-empty", children: ui.clubSquadStatsEmpty });
|
|
10154
|
+
const scorer = leader(stats, (p) => p.goals);
|
|
10155
|
+
const assister = leader(stats, (p) => p.assists);
|
|
10156
|
+
const footer = [
|
|
10157
|
+
scorer && ui.squadTopScorer(scorer.playerName, scorer.goals),
|
|
10158
|
+
assister && ui.squadTopAssists(assister.playerName, assister.assists)
|
|
10159
|
+
].filter((part) => !!part).join(" \xB7 ");
|
|
10160
|
+
return /* @__PURE__ */ jsxs83("div", { className: "ss-w-mon-list ss-w-sq-stats", children: [
|
|
10161
|
+
/* @__PURE__ */ jsxs83("div", { className: "ss-w-sq-card", children: [
|
|
10162
|
+
/* @__PURE__ */ jsxs83("div", { className: "ss-w-sq-row ss-w-sq-head", "aria-hidden": "true", children: [
|
|
10163
|
+
/* @__PURE__ */ jsx97("span", { className: "ss-w-sq-name" }),
|
|
10164
|
+
/* @__PURE__ */ jsx97("span", { className: "ss-w-sq-pos", children: ui.statHeadPos }),
|
|
10165
|
+
/* @__PURE__ */ jsx97("span", { className: "ss-w-sq-c30", children: ui.statColApps }),
|
|
10166
|
+
/* @__PURE__ */ jsx97("span", { className: "ss-w-sq-c36", children: ui.statHeadMins }),
|
|
10167
|
+
/* @__PURE__ */ jsx97("span", { className: "ss-w-sq-c20", children: ui.statHeadGoals }),
|
|
10168
|
+
/* @__PURE__ */ jsx97("span", { className: "ss-w-sq-c20", children: ui.statHeadAssists }),
|
|
10169
|
+
/* @__PURE__ */ jsx97("span", { className: "ss-w-sq-c20 ss-w-sq-yr", children: ui.statHeadYellow }),
|
|
10170
|
+
/* @__PURE__ */ jsx97("span", { className: "ss-w-sq-c20 ss-w-sq-yr", children: ui.statHeadRed }),
|
|
10171
|
+
/* @__PURE__ */ jsx97("span", { className: "ss-w-sq-c36", children: ui.statHeadRating })
|
|
10172
|
+
] }),
|
|
10173
|
+
stats.map((p) => /* @__PURE__ */ jsxs83("button", { type: "button", className: "ss-w-sq-row ss-w-sq-tap", onClick: () => onSelectPlayer(p.playerId), children: [
|
|
10174
|
+
/* @__PURE__ */ jsxs83("span", { className: "ss-w-sq-player", children: [
|
|
10175
|
+
p.jerseyNumber !== null && /* @__PURE__ */ jsx97("span", { className: "ss-w-sq-badge", children: p.jerseyNumber }),
|
|
10176
|
+
/* @__PURE__ */ jsx97("span", { className: "ss-w-sq-name ss-w-sq-name-1", children: p.playerName })
|
|
10177
|
+
] }),
|
|
10178
|
+
/* @__PURE__ */ jsx97("span", { className: "ss-w-sq-pos", children: positionShort(p.positionCode, p.positionName) }),
|
|
10179
|
+
/* @__PURE__ */ jsx97("span", { className: "ss-w-sq-c30", children: p.appearances }),
|
|
10180
|
+
/* @__PURE__ */ jsx97("span", { className: "ss-w-sq-c36", children: p.minutesPlayed }),
|
|
10181
|
+
/* @__PURE__ */ jsx97("span", { className: "ss-w-sq-c20", children: p.goals }),
|
|
10182
|
+
/* @__PURE__ */ jsx97("span", { className: "ss-w-sq-c20", children: p.assists }),
|
|
10183
|
+
/* @__PURE__ */ jsx97("span", { className: "ss-w-sq-c20 ss-w-sq-yr", children: p.yellowCards }),
|
|
10184
|
+
/* @__PURE__ */ jsx97("span", { className: "ss-w-sq-c20 ss-w-sq-yr", children: p.redCards }),
|
|
10185
|
+
/* @__PURE__ */ jsx97("span", { className: ratingClass(p.averageRating), children: p.averageRating === null ? "\u2013" : p.averageRating.toFixed(1) })
|
|
10186
|
+
] }, p.playerId))
|
|
10187
|
+
] }),
|
|
10188
|
+
footer !== "" && /* @__PURE__ */ jsx97("div", { className: "ss-w-sq-foot", children: footer })
|
|
10189
|
+
] });
|
|
10190
|
+
}
|
|
10191
|
+
|
|
10192
|
+
// src/components/Squad.tsx
|
|
10193
|
+
import { Fragment as Fragment21, jsx as jsx98, jsxs as jsxs84 } from "react/jsx-runtime";
|
|
10194
|
+
function Squad({ squad, loading, ui, view, onToggleView, stats, statsLoading, seasonName = null, competitionName = null, matchesPlayed = null, onSelectPlayer }) {
|
|
10195
|
+
const eyebrow = view === "stats" ? statsEyebrow(ui, seasonName, competitionName, matchesPlayed) : null;
|
|
10196
|
+
const toggle = /* @__PURE__ */ jsxs84("div", { className: "ss-w-sq-bar", children: [
|
|
10197
|
+
eyebrow !== null && /* @__PURE__ */ jsx98("div", { className: "ss-w-sq-eyebrow", children: eyebrow }),
|
|
10198
|
+
/* @__PURE__ */ jsx98("div", { className: "ss-w-sq-seg", role: "group", children: ["roster", "stats"].map((v) => /* @__PURE__ */ jsx98(
|
|
10199
|
+
"button",
|
|
10200
|
+
{
|
|
10201
|
+
type: "button",
|
|
10202
|
+
className: "ss-w-sq-seg-btn",
|
|
10203
|
+
"aria-pressed": view === v,
|
|
10204
|
+
onClick: () => {
|
|
10205
|
+
if (view !== v) onToggleView();
|
|
10206
|
+
},
|
|
10207
|
+
children: v === "roster" ? ui.squadViewRoster : ui.squadViewStats
|
|
10208
|
+
},
|
|
10209
|
+
v
|
|
10210
|
+
)) })
|
|
10211
|
+
] });
|
|
10212
|
+
if (view === "stats") {
|
|
10213
|
+
return /* @__PURE__ */ jsxs84(Fragment21, { children: [
|
|
10214
|
+
toggle,
|
|
10215
|
+
/* @__PURE__ */ jsx98(SquadStats, { stats, loading: statsLoading, ui, onSelectPlayer })
|
|
10216
|
+
] });
|
|
10217
|
+
}
|
|
10218
|
+
if (squad === null && loading) return /* @__PURE__ */ jsxs84(Fragment21, { children: [
|
|
10219
|
+
toggle,
|
|
10220
|
+
/* @__PURE__ */ jsx98("div", { className: "ss-w-mon-list" })
|
|
10221
|
+
] });
|
|
10222
|
+
if (squad === null || squad.length === 0) return /* @__PURE__ */ jsxs84(Fragment21, { children: [
|
|
10223
|
+
toggle,
|
|
10224
|
+
/* @__PURE__ */ jsx98("div", { className: "ss-w-mon-empty", children: ui.clubSquadEmpty })
|
|
10225
|
+
] });
|
|
10226
|
+
return /* @__PURE__ */ jsxs84(Fragment21, { children: [
|
|
10227
|
+
toggle,
|
|
10228
|
+
/* @__PURE__ */ jsx98("div", { className: "ss-w-mon-list", children: groupByPosition(squad).map((group, gi) => /* @__PURE__ */ jsxs84("div", { children: [
|
|
10229
|
+
group.positionName && /* @__PURE__ */ jsx98("div", { className: "ss-w-club-eyebrow", children: positionLabel(ui, group.positionName) }),
|
|
10230
|
+
group.items.map((p) => /* @__PURE__ */ jsxs84("button", { type: "button", className: "ss-w-sq-row ss-w-sq-tap", onClick: () => onSelectPlayer(p.playerId), children: [
|
|
10231
|
+
/* @__PURE__ */ jsx98("span", { className: "ss-w-sq-num", children: p.jerseyNumber ?? "" }),
|
|
10232
|
+
/* @__PURE__ */ jsx98("span", { className: "ss-w-sq-name", children: p.playerName })
|
|
10233
|
+
] }, p.playerId))
|
|
10234
|
+
] }, `${gi}-${group.positionName ?? "none"}`)) })
|
|
10235
|
+
] });
|
|
10236
|
+
}
|
|
10237
|
+
|
|
10238
|
+
// src/components/PlayerPhoto.tsx
|
|
10239
|
+
import { useState as useState50 } from "react";
|
|
10240
|
+
import { jsx as jsx99 } from "react/jsx-runtime";
|
|
10241
|
+
function PlayerPhoto({ photoUrl, jerseyNumber, size }) {
|
|
10242
|
+
const [failed, setFailed] = useState50(false);
|
|
10243
|
+
const box = { width: size, height: size };
|
|
10244
|
+
if (photoUrl && !failed) {
|
|
10245
|
+
return /* @__PURE__ */ jsx99("img", { className: "ss-w-pd-photo", style: box, src: photoUrl, alt: "", "aria-hidden": "true", onError: () => setFailed(true) });
|
|
10246
|
+
}
|
|
10247
|
+
return /* @__PURE__ */ jsx99("span", { className: "ss-w-pd-photo ss-w-pd-avatar", style: { ...box, fontSize: Math.round(size * 0.35) }, "aria-hidden": "true", children: jerseyNumber ?? "" });
|
|
10248
|
+
}
|
|
10249
|
+
|
|
10250
|
+
// src/components/MiniPitch.tsx
|
|
10251
|
+
import { jsx as jsx100 } from "react/jsx-runtime";
|
|
10252
|
+
var SPOT = {
|
|
10253
|
+
GK: [50, 90],
|
|
10254
|
+
CB: [50, 75],
|
|
10255
|
+
LB: [18, 70],
|
|
10256
|
+
RB: [82, 70],
|
|
10257
|
+
LWB: [15, 58],
|
|
10258
|
+
RWB: [85, 58],
|
|
10259
|
+
DM: [50, 60],
|
|
10260
|
+
CM: [50, 48],
|
|
10261
|
+
LM: [18, 45],
|
|
10262
|
+
RM: [82, 45],
|
|
10263
|
+
AM: [50, 32],
|
|
10264
|
+
LW: [20, 25],
|
|
10265
|
+
RW: [80, 25],
|
|
10266
|
+
CF: [50, 14],
|
|
10267
|
+
SS: [50, 14],
|
|
10268
|
+
ST: [50, 14]
|
|
10269
|
+
};
|
|
10270
|
+
function MiniPitch({ positionCode }) {
|
|
10271
|
+
const spot = SPOT[positionCode?.trim().toUpperCase() ?? ""];
|
|
10272
|
+
if (spot === void 0) return null;
|
|
10273
|
+
return /* @__PURE__ */ jsx100("div", { className: "ss-w-pd-pitch", "aria-hidden": "true", children: /* @__PURE__ */ jsx100("div", { className: "ss-w-pd-pitch-dot", style: { left: `${spot[0]}%`, top: `${spot[1]}%` } }) });
|
|
10274
|
+
}
|
|
10275
|
+
|
|
10276
|
+
// src/components/PerformanceBars.tsx
|
|
10277
|
+
import { useState as useState51 } from "react";
|
|
10278
|
+
import { jsx as jsx101, jsxs as jsxs85 } from "react/jsx-runtime";
|
|
10279
|
+
var GROUPS = ["shooting", "passing", "possession", "defending"];
|
|
10280
|
+
function finite3(v) {
|
|
10281
|
+
return typeof v === "number" && Number.isFinite(v) ? v : null;
|
|
10282
|
+
}
|
|
10283
|
+
function valueOf(m, mode) {
|
|
10284
|
+
return finite3(mode === "total" ? m.total : m.per90);
|
|
10285
|
+
}
|
|
10286
|
+
function rankOf(m, mode) {
|
|
10287
|
+
const r = finite3(mode === "total" ? m.totalRank : m.per90Rank);
|
|
10288
|
+
return r === null ? null : Math.min(100, Math.max(0, Math.round(r)));
|
|
10289
|
+
}
|
|
10290
|
+
function format(m, v, mode) {
|
|
10291
|
+
if (m.isPercent) return `${v.toFixed(1)}%`;
|
|
10292
|
+
if (mode === "per90" || m.key === "xg") return v.toFixed(2);
|
|
10293
|
+
return String(Math.round(v));
|
|
10294
|
+
}
|
|
10295
|
+
function band(rank) {
|
|
10296
|
+
if (rank >= 67) return "pos";
|
|
10297
|
+
if (rank >= 34) return "warn";
|
|
10298
|
+
return "neg";
|
|
10299
|
+
}
|
|
10300
|
+
function groupTitle(ui, g) {
|
|
10301
|
+
switch (g) {
|
|
10302
|
+
case "shooting":
|
|
10303
|
+
return ui.perfGroupShooting;
|
|
10304
|
+
case "passing":
|
|
10305
|
+
return ui.perfGroupPassing;
|
|
10306
|
+
case "possession":
|
|
10307
|
+
return ui.perfGroupPossession;
|
|
10308
|
+
case "defending":
|
|
10309
|
+
return ui.perfGroupDefending;
|
|
10310
|
+
}
|
|
10311
|
+
}
|
|
10312
|
+
function unrankedLine(ui, reason) {
|
|
10313
|
+
switch (reason) {
|
|
10314
|
+
case "cohort":
|
|
10315
|
+
return ui.perfUnrankedCohort;
|
|
10316
|
+
case "noLeague":
|
|
10317
|
+
return ui.perfUnrankedNoLeague;
|
|
10318
|
+
default:
|
|
10319
|
+
return ui.perfUnranked;
|
|
10320
|
+
}
|
|
10321
|
+
}
|
|
10322
|
+
function PerformanceBars({ performance, competitionName, strings }) {
|
|
10323
|
+
const [mode, setMode] = useState51("total");
|
|
10324
|
+
const labelled = performance.metrics.filter((m) => Object.prototype.hasOwnProperty.call(strings.perfMetric, m.key));
|
|
10325
|
+
if (!labelled.some((m) => valueOf(m, "total") !== null || valueOf(m, "per90") !== null)) return null;
|
|
10326
|
+
const subtitle = !performance.ranked ? unrankedLine(strings, performance.unrankedReason) : competitionName ? strings.perfRankedAgainst(competitionName, performance.positionGroup) : null;
|
|
10327
|
+
const cards = GROUPS.map((g) => {
|
|
10328
|
+
const rows = labelled.filter((m) => m.group === g && valueOf(m, mode) !== null);
|
|
10329
|
+
if (rows.length === 0) return null;
|
|
10330
|
+
return /* @__PURE__ */ jsxs85("div", { className: "ss-w-pd-card ss-w-pd-perf-card", children: [
|
|
10331
|
+
/* @__PURE__ */ jsx101("div", { className: "ss-w-pd-perf-group", children: groupTitle(strings, g) }),
|
|
10332
|
+
rows.map((m) => {
|
|
10333
|
+
const v = valueOf(m, mode);
|
|
10334
|
+
const rank = performance.ranked ? rankOf(m, mode) : null;
|
|
10335
|
+
return /* @__PURE__ */ jsxs85("div", { className: "ss-w-pd-bar-row", children: [
|
|
10336
|
+
/* @__PURE__ */ jsxs85("div", { className: "ss-w-pd-bar-top", children: [
|
|
10337
|
+
/* @__PURE__ */ jsx101("span", { className: "ss-w-pd-bar-label", children: strings.perfMetric[m.key] }),
|
|
10338
|
+
/* @__PURE__ */ jsx101("span", { className: "ss-w-pd-bar-value", children: format(m, v, mode) })
|
|
10339
|
+
] }),
|
|
10340
|
+
rank !== null && /* @__PURE__ */ jsx101("div", { className: "ss-w-pd-track", children: /* @__PURE__ */ jsx101("div", { className: `ss-w-pd-fill ss-w-pd-fill--${band(rank)}`, style: { width: `${rank}%` } }) })
|
|
10341
|
+
] }, m.key);
|
|
10342
|
+
})
|
|
10343
|
+
] }, g);
|
|
10344
|
+
});
|
|
10345
|
+
return /* @__PURE__ */ jsxs85("div", { children: [
|
|
10346
|
+
/* @__PURE__ */ jsxs85("div", { className: "ss-w-pd-perf-head", children: [
|
|
10347
|
+
/* @__PURE__ */ jsx101("div", { className: "ss-w-pd-eyebrow", children: strings.perfTitle }),
|
|
10348
|
+
/* @__PURE__ */ jsx101("div", { className: "ss-w-pd-seg", role: "group", children: ["total", "per90"].map((m) => /* @__PURE__ */ jsx101("button", { type: "button", className: "ss-w-pd-seg-btn", "aria-pressed": mode === m, onClick: () => setMode(m), children: m === "total" ? strings.perfTotal : strings.perfPer90 }, m)) })
|
|
10349
|
+
] }),
|
|
10350
|
+
subtitle !== null && /* @__PURE__ */ jsx101("div", { className: "ss-w-pd-perf-sub", children: subtitle }),
|
|
10351
|
+
/* @__PURE__ */ jsx101("div", { className: "ss-w-pd-perf-cards", children: cards })
|
|
10352
|
+
] });
|
|
10353
|
+
}
|
|
10354
|
+
|
|
10355
|
+
// src/components/PlayerDetail.tsx
|
|
10356
|
+
import { Fragment as Fragment22, jsx as jsx102, jsxs as jsxs86 } from "react/jsx-runtime";
|
|
10357
|
+
var DASH = "\u2014";
|
|
10358
|
+
function ageFrom(dobMs) {
|
|
10359
|
+
if (dobMs === null) return DASH;
|
|
10360
|
+
const dob = new Date(dobMs);
|
|
10361
|
+
const now = /* @__PURE__ */ new Date();
|
|
10362
|
+
let age = now.getUTCFullYear() - dob.getUTCFullYear();
|
|
10363
|
+
const beforeBirthday = now.getUTCMonth() < dob.getUTCMonth() || now.getUTCMonth() === dob.getUTCMonth() && now.getUTCDate() < dob.getUTCDate();
|
|
10364
|
+
if (beforeBirthday) age--;
|
|
10365
|
+
return String(age);
|
|
10366
|
+
}
|
|
10367
|
+
function validMs(ms) {
|
|
10368
|
+
return typeof ms === "number" && Number.isFinite(ms) && ms > 0 ? ms : null;
|
|
10369
|
+
}
|
|
10370
|
+
function ratingTone(rounded) {
|
|
10371
|
+
if (rounded >= 7) return "pos";
|
|
10372
|
+
if (rounded >= 6) return "warn";
|
|
10373
|
+
return "neg";
|
|
10374
|
+
}
|
|
10375
|
+
function Bio({ label, value }) {
|
|
10376
|
+
return /* @__PURE__ */ jsxs86("div", { className: "ss-w-pd-bio-item", children: [
|
|
10377
|
+
/* @__PURE__ */ jsx102("span", { className: "ss-w-pd-faint", children: label }),
|
|
10378
|
+
" ",
|
|
10379
|
+
/* @__PURE__ */ jsx102("span", { children: value })
|
|
10380
|
+
] });
|
|
10381
|
+
}
|
|
10382
|
+
function Tile({ label, value, pos }) {
|
|
10383
|
+
return /* @__PURE__ */ jsxs86("div", { className: "ss-w-pd-tile", children: [
|
|
10384
|
+
/* @__PURE__ */ jsx102("div", { className: "ss-w-pd-tile-label", children: label }),
|
|
10385
|
+
/* @__PURE__ */ jsx102("div", { className: pos ? "ss-w-pd-tile-value ss-w-pd-pos-ink" : "ss-w-pd-tile-value", children: value })
|
|
10386
|
+
] });
|
|
10387
|
+
}
|
|
10388
|
+
function AvailabilityCard({ ui, next, availability }) {
|
|
10389
|
+
let note = null;
|
|
10390
|
+
let pill = null;
|
|
10391
|
+
if (availability !== null) {
|
|
10392
|
+
if (availability.status === "available") {
|
|
10393
|
+
note = ui.availabilityNoConcerns;
|
|
10394
|
+
pill = { text: ui.availabilityAvailable, tone: "pos" };
|
|
10395
|
+
} else {
|
|
10396
|
+
const back = validMs(availability.expectedReturnUnixMs);
|
|
10397
|
+
note = [availability.detail?.trim() || null, back === null ? null : ui.availabilityBack(back)].filter(Boolean).join(" \xB7 ") || null;
|
|
10398
|
+
pill = availability.status === "injured" ? { text: ui.availabilityInjured, tone: "neg" } : availability.status === "suspended" ? { text: ui.availabilitySuspended, tone: "warn" } : { text: ui.availabilityUnavailable, tone: "warn" };
|
|
10399
|
+
}
|
|
10400
|
+
}
|
|
10401
|
+
return /* @__PURE__ */ jsxs86("div", { className: "ss-w-pd-card ss-w-pd-avail", children: [
|
|
10402
|
+
/* @__PURE__ */ jsxs86("div", { className: "ss-w-pd-avail-text", children: [
|
|
10403
|
+
next !== null && /* @__PURE__ */ jsx102("div", { className: "ss-w-pd-avail-next", children: ui.availabilityNext(next.opponentName, next.isHome, validMs(next.kickoffUnixMs)) }),
|
|
10404
|
+
note !== null && /* @__PURE__ */ jsx102("div", { className: "ss-w-pd-avail-note", children: note })
|
|
10405
|
+
] }),
|
|
10406
|
+
pill !== null && /* @__PURE__ */ jsx102("div", { className: `ss-w-pd-pill ss-w-pd-pill--${pill.tone}`, children: pill.text })
|
|
10407
|
+
] });
|
|
10408
|
+
}
|
|
10409
|
+
function MatchRow({ ui, row }) {
|
|
10410
|
+
const date = validMs(row.kickoffUnixMs);
|
|
10411
|
+
const extras = [
|
|
10412
|
+
row.goals > 0 ? `${row.goals}${ui.statHeadGoals}` : null,
|
|
10413
|
+
row.assists > 0 ? `${row.assists}${ui.statHeadAssists}` : null,
|
|
10414
|
+
row.yellowCards > 0 ? `${row.yellowCards}${ui.statHeadYellow}` : null,
|
|
10415
|
+
row.sentOff ? ui.statHeadRed : null
|
|
10416
|
+
].filter((x) => x !== null);
|
|
10417
|
+
const sub = [`${ui.resultLetter[row.result]} ${row.goalsFor}\u2013${row.goalsAgainst}`, `${row.minutes}\u2032`, ...extras].join(" \xB7 ");
|
|
10418
|
+
const rating = typeof row.rating === "number" && Number.isFinite(row.rating) ? Math.round(row.rating * 10) / 10 : null;
|
|
10419
|
+
const pillTone = row.result === "W" ? "pos" : row.result === "L" ? "neg" : "draw";
|
|
10420
|
+
return /* @__PURE__ */ jsxs86("div", { className: "ss-w-pd-match", children: [
|
|
10421
|
+
/* @__PURE__ */ jsx102("div", { className: "ss-w-pd-match-date", children: date === null ? "" : ui.logShortDate(date) }),
|
|
10422
|
+
/* @__PURE__ */ jsxs86("div", { className: "ss-w-pd-match-main", children: [
|
|
10423
|
+
/* @__PURE__ */ jsx102("div", { className: "ss-w-pd-match-opp", children: ui.matchLogOpponent(row.opponentName, row.isHome) }),
|
|
10424
|
+
/* @__PURE__ */ jsx102("div", { className: "ss-w-pd-match-sub", children: sub })
|
|
10425
|
+
] }),
|
|
10426
|
+
/* @__PURE__ */ jsx102("div", { className: `ss-w-pd-pill ss-w-pd-pill--${pillTone}`, children: ui.resultLetter[row.result] }),
|
|
10427
|
+
rating === null ? /* @__PURE__ */ jsx102("div", { className: "ss-w-pd-chip-empty" }) : /* @__PURE__ */ jsx102("div", { className: `ss-w-pd-chip ss-w-pd-chip--${ratingTone(rating)}`, children: rating.toFixed(1) })
|
|
10428
|
+
] });
|
|
10429
|
+
}
|
|
10430
|
+
function PlayerDetail({ detail, loading, ui, seasonName, onClose }) {
|
|
10431
|
+
const back = /* @__PURE__ */ jsxs86("button", { type: "button", className: "ss-w-pd-back", onClick: onClose, children: [
|
|
10432
|
+
/* @__PURE__ */ jsx102("svg", { width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", "aria-hidden": "true", children: /* @__PURE__ */ jsx102("path", { d: "M15 18l-6-6 6-6" }) }),
|
|
10433
|
+
ui.clubPlayerBack
|
|
10434
|
+
] });
|
|
10435
|
+
if (detail === null) {
|
|
10436
|
+
return loading ? /* @__PURE__ */ jsxs86(Fragment22, { children: [
|
|
10437
|
+
/* @__PURE__ */ jsx102("div", { className: "ss-w-pd-bar", children: back }),
|
|
10438
|
+
/* @__PURE__ */ jsx102("div", { className: "ss-w-mon-list" })
|
|
10439
|
+
] }) : /* @__PURE__ */ jsxs86(Fragment22, { children: [
|
|
10440
|
+
/* @__PURE__ */ jsx102("div", { className: "ss-w-pd-bar", children: back }),
|
|
10441
|
+
/* @__PURE__ */ jsx102("div", { className: "ss-w-mon-empty", children: ui.clubPlayerDetailEmpty })
|
|
10442
|
+
] });
|
|
10443
|
+
}
|
|
10444
|
+
const s = detail.seasonStats;
|
|
10445
|
+
const foot = footLabel(ui, detail.foot);
|
|
10446
|
+
const position = positionLabel(ui, detail.positionName);
|
|
10447
|
+
const subLine = [detail.teamName?.trim() || null, position].filter(Boolean).join(" \xB7 ");
|
|
10448
|
+
const competition = detail.competitionName?.trim() || null;
|
|
10449
|
+
const eyebrow = seasonName === null ? null : competition === null ? ui.detailSeason.replace("{season}", seasonName) : `${seasonName} ${competition}`;
|
|
10450
|
+
const rating = typeof s.averageRating === "number" && Number.isFinite(s.averageRating) ? s.averageRating : null;
|
|
10451
|
+
const next = detail.nextFixture ?? null;
|
|
10452
|
+
const availability = detail.availability ?? null;
|
|
10453
|
+
const log = detail.matchLog ?? [];
|
|
10454
|
+
return /* @__PURE__ */ jsxs86(Fragment22, { children: [
|
|
10455
|
+
/* @__PURE__ */ jsx102("div", { className: "ss-w-pd-bar", children: back }),
|
|
10456
|
+
/* @__PURE__ */ jsxs86("div", { className: "ss-w-mon-list ss-w-pd-list", children: [
|
|
10457
|
+
/* @__PURE__ */ jsxs86("div", { className: "ss-w-pd-card ss-w-pd-profile", children: [
|
|
10458
|
+
/* @__PURE__ */ jsx102(PlayerPhoto, { photoUrl: detail.photoUrl, jerseyNumber: detail.jerseyNumber, size: 52 }, detail.photoUrl ?? ""),
|
|
10459
|
+
/* @__PURE__ */ jsxs86("div", { className: "ss-w-pd-profile-main", children: [
|
|
10460
|
+
/* @__PURE__ */ jsx102("div", { className: "ss-w-pd-name", children: detail.playerName }),
|
|
10461
|
+
subLine !== "" && /* @__PURE__ */ jsx102("div", { className: "ss-w-pd-sub", children: subLine }),
|
|
10462
|
+
/* @__PURE__ */ jsxs86("div", { className: "ss-w-pd-bio", children: [
|
|
10463
|
+
/* @__PURE__ */ jsx102(Bio, { label: ui.detailAge, value: ageFrom(detail.dateOfBirthUnixMs) }),
|
|
10464
|
+
/* @__PURE__ */ jsx102(Bio, { label: ui.detailHeight, value: detail.heightCm === null ? DASH : `${detail.heightCm} cm` }),
|
|
10465
|
+
foot !== null && /* @__PURE__ */ jsx102(Bio, { label: ui.detailFoot, value: foot }),
|
|
10466
|
+
/* @__PURE__ */ jsx102(Bio, { label: ui.detailNatShort, value: detail.nationality ?? DASH })
|
|
10467
|
+
] })
|
|
10468
|
+
] }),
|
|
10469
|
+
/* @__PURE__ */ jsx102(MiniPitch, { positionCode: detail.positionCode })
|
|
10470
|
+
] }),
|
|
10471
|
+
(next !== null || availability !== null) && /* @__PURE__ */ jsx102(AvailabilityCard, { ui, next, availability }),
|
|
10472
|
+
/* @__PURE__ */ jsxs86("div", { children: [
|
|
10473
|
+
eyebrow !== null && /* @__PURE__ */ jsx102("div", { className: "ss-w-pd-eyebrow ss-w-pd-eyebrow--block", children: eyebrow }),
|
|
10474
|
+
/* @__PURE__ */ jsxs86("div", { className: "ss-w-pd-tiles", children: [
|
|
10475
|
+
/* @__PURE__ */ jsx102(Tile, { label: ui.statColGoals, value: String(s.goals) }),
|
|
10476
|
+
/* @__PURE__ */ jsx102(Tile, { label: ui.statColAssists, value: String(s.assists) }),
|
|
10477
|
+
typeof s.starts === "number" && /* @__PURE__ */ jsx102(Tile, { label: ui.detailStarted, value: String(s.starts) }),
|
|
10478
|
+
/* @__PURE__ */ jsx102(Tile, { label: ui.detailMatches, value: String(s.appearances) }),
|
|
10479
|
+
/* @__PURE__ */ jsx102(Tile, { label: ui.statColMinutes, value: String(s.minutesPlayed) }),
|
|
10480
|
+
rating !== null && /* @__PURE__ */ jsx102(Tile, { label: ui.statColRating, value: rating.toFixed(2), pos: Math.round(rating * 100) / 100 >= 7 }),
|
|
10481
|
+
/* @__PURE__ */ jsx102(Tile, { label: ui.detailYellows, value: String(s.yellowCards) }),
|
|
10482
|
+
/* @__PURE__ */ jsx102(Tile, { label: ui.detailReds, value: String(s.redCards) })
|
|
10483
|
+
] })
|
|
10484
|
+
] }),
|
|
10485
|
+
detail.performance != null && /* @__PURE__ */ jsx102(PerformanceBars, { performance: detail.performance, competitionName: competition, strings: ui }),
|
|
10486
|
+
log.length > 0 && /* @__PURE__ */ jsxs86("div", { children: [
|
|
10487
|
+
/* @__PURE__ */ jsx102("div", { className: "ss-w-pd-eyebrow ss-w-pd-eyebrow--block", children: ui.matchLogTitle }),
|
|
10488
|
+
/* @__PURE__ */ jsx102("div", { className: "ss-w-pd-card ss-w-pd-log", children: log.map((row) => /* @__PURE__ */ jsx102(MatchRow, { ui, row }, row.matchId)) })
|
|
10489
|
+
] })
|
|
10490
|
+
] })
|
|
10491
|
+
] });
|
|
9771
10492
|
}
|
|
9772
10493
|
|
|
9773
10494
|
// src/components/PresetSpeedDial.tsx
|
|
9774
10495
|
import { useId as useId10 } from "react";
|
|
9775
|
-
import { jsx as
|
|
10496
|
+
import { jsx as jsx103, jsxs as jsxs87 } from "react/jsx-runtime";
|
|
9776
10497
|
function PresetSpeedDial({ expanded, showDot, strings, onToggle, onOpen, rootRef, buttonRef }) {
|
|
9777
10498
|
const pillsId = useId10();
|
|
9778
10499
|
const tabIndex = expanded ? 0 : -1;
|
|
9779
|
-
return /* @__PURE__ */
|
|
9780
|
-
/* @__PURE__ */
|
|
10500
|
+
return /* @__PURE__ */ jsxs87("div", { ref: rootRef, className: "ss-w-dial", children: [
|
|
10501
|
+
/* @__PURE__ */ jsxs87(
|
|
9781
10502
|
"button",
|
|
9782
10503
|
{
|
|
9783
10504
|
ref: buttonRef,
|
|
@@ -9788,36 +10509,36 @@ function PresetSpeedDial({ expanded, showDot, strings, onToggle, onOpen, rootRef
|
|
|
9788
10509
|
"aria-label": strings.dialName,
|
|
9789
10510
|
onClick: onToggle,
|
|
9790
10511
|
children: [
|
|
9791
|
-
/* @__PURE__ */
|
|
9792
|
-
/* @__PURE__ */
|
|
9793
|
-
showDot && !expanded ? /* @__PURE__ */
|
|
10512
|
+
/* @__PURE__ */ jsx103("span", { className: "ss-w-dial-icon ss-w-dial-icon--open", children: /* @__PURE__ */ jsx103(SlidersIcon, {}) }),
|
|
10513
|
+
/* @__PURE__ */ jsx103("span", { className: "ss-w-dial-icon ss-w-dial-icon--close", children: /* @__PURE__ */ jsx103(CloseIcon, {}) }),
|
|
10514
|
+
showDot && !expanded ? /* @__PURE__ */ jsx103("span", { className: "ss-w-dial-dot", "aria-hidden": "true" }) : null
|
|
9794
10515
|
]
|
|
9795
10516
|
}
|
|
9796
10517
|
),
|
|
9797
|
-
/* @__PURE__ */
|
|
9798
|
-
/* @__PURE__ */
|
|
9799
|
-
/* @__PURE__ */
|
|
9800
|
-
/* @__PURE__ */
|
|
10518
|
+
/* @__PURE__ */ jsxs87("div", { id: pillsId, className: "ss-w-dial-pills", "data-open": expanded ? "" : void 0, children: [
|
|
10519
|
+
/* @__PURE__ */ jsxs87("button", { type: "button", className: "ss-w-dial-pill", tabIndex, onClick: () => onOpen("numbers"), children: [
|
|
10520
|
+
/* @__PURE__ */ jsx103(SlidersIcon, {}),
|
|
10521
|
+
/* @__PURE__ */ jsx103("span", { className: "ss-w-dial-pill-label", children: strings.setNumbers })
|
|
9801
10522
|
] }),
|
|
9802
|
-
/* @__PURE__ */
|
|
9803
|
-
/* @__PURE__ */
|
|
9804
|
-
/* @__PURE__ */
|
|
10523
|
+
/* @__PURE__ */ jsxs87("button", { type: "button", className: "ss-w-dial-pill", tabIndex, onClick: () => onOpen("combo"), children: [
|
|
10524
|
+
/* @__PURE__ */ jsx103(ComboIcon, {}),
|
|
10525
|
+
/* @__PURE__ */ jsx103("span", { className: "ss-w-dial-pill-label", children: strings.buildCombo })
|
|
9805
10526
|
] })
|
|
9806
10527
|
] })
|
|
9807
10528
|
] });
|
|
9808
10529
|
}
|
|
9809
10530
|
|
|
9810
10531
|
// src/components/PresetTools.tsx
|
|
9811
|
-
import { Fragment as
|
|
9812
|
-
import { Fragment as
|
|
10532
|
+
import { Fragment as Fragment23, useEffect as useEffect31, useId as useId11, useRef as useRef28, useState as useState52 } from "react";
|
|
10533
|
+
import { Fragment as Fragment24, jsx as jsx104, jsxs as jsxs88 } from "react/jsx-runtime";
|
|
9813
10534
|
var FOCUSABLE = 'button:not([disabled]), [href], input:not([disabled]), textarea:not([disabled]), [tabindex]:not([tabindex="-1"])';
|
|
9814
10535
|
function PresetToolModal({ title, closeLabel, onClose, children, footer }) {
|
|
9815
|
-
const dialogRef =
|
|
10536
|
+
const dialogRef = useRef28(null);
|
|
9816
10537
|
const titleId = useId11();
|
|
9817
|
-
|
|
10538
|
+
useEffect31(() => {
|
|
9818
10539
|
dialogRef.current?.focus();
|
|
9819
10540
|
}, []);
|
|
9820
|
-
|
|
10541
|
+
useEffect31(() => {
|
|
9821
10542
|
const onKey = (e) => {
|
|
9822
10543
|
if (e.key !== "Escape") return;
|
|
9823
10544
|
e.stopPropagation();
|
|
@@ -9847,79 +10568,79 @@ function PresetToolModal({ title, closeLabel, onClose, children, footer }) {
|
|
|
9847
10568
|
first.focus();
|
|
9848
10569
|
}
|
|
9849
10570
|
};
|
|
9850
|
-
return /* @__PURE__ */
|
|
9851
|
-
/* @__PURE__ */
|
|
9852
|
-
/* @__PURE__ */
|
|
9853
|
-
/* @__PURE__ */
|
|
10571
|
+
return /* @__PURE__ */ jsx104("div", { className: "ss-w-tool-backdrop", children: /* @__PURE__ */ jsxs88("div", { ref: dialogRef, className: "ss-w-tool", role: "dialog", "aria-modal": "true", "aria-labelledby": titleId, tabIndex: -1, onKeyDown: trapTab, children: [
|
|
10572
|
+
/* @__PURE__ */ jsxs88("div", { className: "ss-w-tool-head", children: [
|
|
10573
|
+
/* @__PURE__ */ jsx104("h2", { id: titleId, className: "ss-w-tool-title", children: title }),
|
|
10574
|
+
/* @__PURE__ */ jsx104("button", { type: "button", className: "ss-w-tool-close", "aria-label": closeLabel, onClick: onClose, children: /* @__PURE__ */ jsx104(CloseIcon, {}) })
|
|
9854
10575
|
] }),
|
|
9855
|
-
/* @__PURE__ */
|
|
9856
|
-
footer ? /* @__PURE__ */
|
|
10576
|
+
/* @__PURE__ */ jsx104("div", { className: "ss-w-tool-body", children }),
|
|
10577
|
+
footer ? /* @__PURE__ */ jsx104("div", { className: "ss-w-tool-foot", children: footer }) : null
|
|
9857
10578
|
] }) });
|
|
9858
10579
|
}
|
|
9859
10580
|
function fillTemplate(template, slots) {
|
|
9860
10581
|
return template.split(/(\{[a-z]+\})/).filter((part) => part !== "").map((part, i) => {
|
|
9861
10582
|
const key = /^\{([a-z]+)\}$/.exec(part)?.[1];
|
|
9862
|
-
return /* @__PURE__ */
|
|
10583
|
+
return /* @__PURE__ */ jsx104(Fragment23, { children: key !== void 0 && key in slots ? slots[key] : part }, i);
|
|
9863
10584
|
});
|
|
9864
10585
|
}
|
|
9865
10586
|
function NumberSelect({ current, choices: choices2, label, notToday, lockEmpty = true, onChoose }) {
|
|
9866
10587
|
const selected = Math.max(0, choices2.findIndex((c) => c.text === current));
|
|
9867
|
-
return /* @__PURE__ */
|
|
9868
|
-
/* @__PURE__ */
|
|
9869
|
-
/* @__PURE__ */
|
|
10588
|
+
return /* @__PURE__ */ jsxs88("span", { className: "ss-w-tool-num", children: [
|
|
10589
|
+
/* @__PURE__ */ jsx104("span", { className: "ss-w-tool-num-size", "aria-hidden": "true", children: current }),
|
|
10590
|
+
/* @__PURE__ */ jsx104("select", { className: "ss-w-tool-num-select", "aria-label": label, value: String(selected), onChange: (e) => {
|
|
9870
10591
|
const c = choices2[Number(e.target.value)];
|
|
9871
10592
|
if (c) onChoose(c.value);
|
|
9872
|
-
}, children: choices2.map((c, i) => /* @__PURE__ */
|
|
10593
|
+
}, children: choices2.map((c, i) => /* @__PURE__ */ jsx104("option", { value: String(i), disabled: lockEmpty && !c.available && i !== selected, children: c.available ? c.text : `${c.text}${notToday}` }, i)) })
|
|
9873
10594
|
] });
|
|
9874
10595
|
}
|
|
9875
10596
|
function ChoiceSelect({ currentIdx, sizeLabels, optionLabels, label, onChoose }) {
|
|
9876
10597
|
const sizeText = sizeLabels[currentIdx] ?? "";
|
|
9877
|
-
return /* @__PURE__ */
|
|
9878
|
-
/* @__PURE__ */
|
|
9879
|
-
/* @__PURE__ */
|
|
10598
|
+
return /* @__PURE__ */ jsxs88("span", { className: "ss-w-tool-num", children: [
|
|
10599
|
+
/* @__PURE__ */ jsx104("span", { className: "ss-w-tool-num-size", "aria-hidden": "true", children: sizeText }),
|
|
10600
|
+
/* @__PURE__ */ jsx104("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__ */ jsx104("option", { value: String(i), children: opt }, i)) })
|
|
9880
10601
|
] });
|
|
9881
10602
|
}
|
|
9882
10603
|
function SendButton({ label, display, disabled, onClick }) {
|
|
9883
|
-
return /* @__PURE__ */
|
|
10604
|
+
return /* @__PURE__ */ jsx104("button", { type: "button", className: "ss-w-tool-send", "aria-label": `${label}: ${display}`, disabled, onClick, children: label });
|
|
9884
10605
|
}
|
|
9885
10606
|
function PickList({ picks, formatKickoff }) {
|
|
9886
|
-
return /* @__PURE__ */
|
|
9887
|
-
/* @__PURE__ */
|
|
10607
|
+
return /* @__PURE__ */ jsx104("ul", { className: "ss-w-tool-picks", role: "list", children: picks.map((p) => /* @__PURE__ */ jsxs88("li", { className: "ss-w-tool-pick", children: [
|
|
10608
|
+
/* @__PURE__ */ jsxs88("span", { className: "ss-w-tool-pick-match", children: [
|
|
9888
10609
|
p.homeTeamName,
|
|
9889
10610
|
" \u2013 ",
|
|
9890
10611
|
p.awayTeamName
|
|
9891
10612
|
] }),
|
|
9892
|
-
/* @__PURE__ */
|
|
10613
|
+
/* @__PURE__ */ jsxs88("span", { className: "ss-w-tool-pick-sel", children: [
|
|
9893
10614
|
p.marketLabel,
|
|
9894
10615
|
": ",
|
|
9895
10616
|
p.selectionLabel,
|
|
9896
10617
|
p.line ? ` ${p.line}` : ""
|
|
9897
10618
|
] }),
|
|
9898
|
-
/* @__PURE__ */
|
|
9899
|
-
/* @__PURE__ */
|
|
10619
|
+
/* @__PURE__ */ jsx104("span", { className: "ss-w-tool-pick-kick", children: formatKickoff(p.kickoffUtc) }),
|
|
10620
|
+
/* @__PURE__ */ jsx104("span", { className: "ss-w-tool-pick-price", children: p.price.toFixed(2) })
|
|
9900
10621
|
] }, p.matchOddsId)) });
|
|
9901
10622
|
}
|
|
9902
10623
|
function ComboPreview({ cell, formatKickoff }) {
|
|
9903
|
-
return /* @__PURE__ */
|
|
9904
|
-
/* @__PURE__ */
|
|
9905
|
-
/* @__PURE__ */
|
|
10624
|
+
return /* @__PURE__ */ jsxs88(Fragment24, { children: [
|
|
10625
|
+
/* @__PURE__ */ jsx104(PickList, { picks: cell.combo.legs, formatKickoff }),
|
|
10626
|
+
/* @__PURE__ */ jsx104("div", { className: "ss-w-tool-math", children: cell.combo.multiplication })
|
|
9906
10627
|
] });
|
|
9907
10628
|
}
|
|
9908
10629
|
function Unavailable({ text }) {
|
|
9909
|
-
return /* @__PURE__ */
|
|
10630
|
+
return /* @__PURE__ */ jsx104("p", { className: "ss-w-tool-unavailable", children: text });
|
|
9910
10631
|
}
|
|
9911
10632
|
function AskRow({ icon, ask, ready, send }) {
|
|
9912
|
-
return /* @__PURE__ */
|
|
9913
|
-
/* @__PURE__ */
|
|
9914
|
-
/* @__PURE__ */
|
|
9915
|
-
/* @__PURE__ */
|
|
9916
|
-
ready ? /* @__PURE__ */
|
|
10633
|
+
return /* @__PURE__ */ jsxs88("section", { className: "ss-w-tool-row ss-w-tool-row--ask", children: [
|
|
10634
|
+
/* @__PURE__ */ jsx104("span", { className: "ss-w-tool-icon", "aria-hidden": "true", children: icon }),
|
|
10635
|
+
/* @__PURE__ */ jsxs88("div", { className: "ss-w-tool-main", children: [
|
|
10636
|
+
/* @__PURE__ */ jsx104("p", { className: "ss-w-tool-ask", children: ask }),
|
|
10637
|
+
ready ? /* @__PURE__ */ jsx104("span", { className: "ss-w-tool-ready", children: ready }) : null
|
|
9917
10638
|
] }),
|
|
9918
10639
|
send
|
|
9919
10640
|
] });
|
|
9920
10641
|
}
|
|
9921
10642
|
function RoundSend({ label, display, disabled, onClick }) {
|
|
9922
|
-
return /* @__PURE__ */
|
|
10643
|
+
return /* @__PURE__ */ jsx104("button", { type: "button", className: "ss-w-tool-go", "aria-label": `${label}: ${display}`, disabled, onClick, children: /* @__PURE__ */ jsx104(SendIcon, {}) });
|
|
9923
10644
|
}
|
|
9924
10645
|
var BIG_COMBO = { total: 50, legs: 6 };
|
|
9925
10646
|
function SetNumbersTool({ grid, strings, streaming, onSend, onClose }) {
|
|
@@ -9928,15 +10649,15 @@ function SetNumbersTool({ grid, strings, streaming, onSend, onClose }) {
|
|
|
9928
10649
|
const totals = comboTotals(grid);
|
|
9929
10650
|
const legChoices = comboLegChoices(grid);
|
|
9930
10651
|
const count = FIXED_SINGLES_COUNT;
|
|
9931
|
-
const [maxPrice, setMaxPrice] =
|
|
9932
|
-
const [minPrice, setMinPrice] =
|
|
9933
|
-
const [start] =
|
|
9934
|
-
const [total, setTotal] =
|
|
9935
|
-
const [legs, setLegs] =
|
|
9936
|
-
const [bigStart] =
|
|
9937
|
-
const [bigTotal, setBigTotal] =
|
|
9938
|
-
const [bigLegs, setBigLegs] =
|
|
9939
|
-
const [announcement, setAnnouncement] =
|
|
10652
|
+
const [maxPrice, setMaxPrice] = useState52(() => startSingles(grid.singles, limits, START.maxPrice, count));
|
|
10653
|
+
const [minPrice, setMinPrice] = useState52(() => startSingles(grid.singlesFrom, floors, START.minPrice, count));
|
|
10654
|
+
const [start] = useState52(() => startCombo(grid, totals, legChoices, START.comboTotal, START.comboLegs));
|
|
10655
|
+
const [total, setTotal] = useState52(start.total);
|
|
10656
|
+
const [legs, setLegs] = useState52(start.legs);
|
|
10657
|
+
const [bigStart] = useState52(() => startCombo(grid, totals, legChoices, BIG_COMBO.total, BIG_COMBO.legs));
|
|
10658
|
+
const [bigTotal, setBigTotal] = useState52(bigStart.total);
|
|
10659
|
+
const [bigLegs, setBigLegs] = useState52(bigStart.legs);
|
|
10660
|
+
const [announcement, setAnnouncement] = useState52("");
|
|
9940
10661
|
const maxCell = findSingles(grid.singles, maxPrice, count);
|
|
9941
10662
|
const minCell = findSingles(grid.singlesFrom, minPrice, count);
|
|
9942
10663
|
const comboCell = findCombo(grid, total, legs);
|
|
@@ -9980,95 +10701,95 @@ function SetNumbersTool({ grid, strings, streaming, onSend, onClose }) {
|
|
|
9980
10701
|
const totalChoices = totals.map((v) => ({ value: v, text: v.toFixed(1), available: legChoices.some((n) => !!findCombo(grid, v, n)) }));
|
|
9981
10702
|
const legChoicesFor = (t) => legChoices.map((n) => ({ value: n, text: String(n), available: !!findCombo(grid, t, n) }));
|
|
9982
10703
|
const markets = grid.markets ?? [];
|
|
9983
|
-
const [marketIdx, setMarketIdx] =
|
|
10704
|
+
const [marketIdx, setMarketIdx] = useState52(0);
|
|
9984
10705
|
const marketCell = markets[marketIdx] ?? null;
|
|
9985
10706
|
const marketLabels = markets.map((c) => strings.marketShort(c.marketDeveloperName, c.marketLabel, c.selectionLabel ?? null));
|
|
9986
10707
|
const singlesReady = (cell) => cell ? strings.readyCount(cell.picks.length) : strings.unavailable;
|
|
9987
10708
|
const comboReady = (cell) => cell ? strings.readyAt(cell.combo.total) : strings.unavailable;
|
|
9988
|
-
return /* @__PURE__ */
|
|
9989
|
-
/* @__PURE__ */
|
|
10709
|
+
return /* @__PURE__ */ jsxs88(PresetToolModal, { title: strings.setNumbers, closeLabel: strings.close, onClose, children: [
|
|
10710
|
+
/* @__PURE__ */ jsx104(
|
|
9990
10711
|
AskRow,
|
|
9991
10712
|
{
|
|
9992
10713
|
icon: "\u{1F3AF}",
|
|
9993
10714
|
ask: fillTemplate(strings.maxPriceRow, {
|
|
9994
10715
|
count: String(count),
|
|
9995
|
-
price: /* @__PURE__ */
|
|
10716
|
+
price: /* @__PURE__ */ jsx104(NumberSelect, { current: maxPrice.toFixed(2), choices: maxChoices, label: strings.maxPriceName, notToday: strings.notToday, onChoose: chooseMax })
|
|
9996
10717
|
}),
|
|
9997
10718
|
ready: singlesReady(maxCell),
|
|
9998
|
-
send: /* @__PURE__ */
|
|
10719
|
+
send: /* @__PURE__ */ jsx104(RoundSend, { label: strings.send, display: strings.maxPriceDisplay(count, maxPrice), disabled: !maxCell || streaming, onClick: () => {
|
|
9999
10720
|
if (maxCell) onSend(maxPriceAsk(maxCell, strings));
|
|
10000
10721
|
} })
|
|
10001
10722
|
}
|
|
10002
10723
|
),
|
|
10003
|
-
/* @__PURE__ */
|
|
10724
|
+
/* @__PURE__ */ jsx104(
|
|
10004
10725
|
AskRow,
|
|
10005
10726
|
{
|
|
10006
10727
|
icon: "\u{1F4C8}",
|
|
10007
10728
|
ask: fillTemplate(strings.minPriceRow, {
|
|
10008
10729
|
count: String(count),
|
|
10009
|
-
price: /* @__PURE__ */
|
|
10730
|
+
price: /* @__PURE__ */ jsx104(NumberSelect, { current: minPrice.toFixed(2), choices: minChoices, label: strings.minPriceName, notToday: strings.notToday, onChoose: chooseMin })
|
|
10010
10731
|
}),
|
|
10011
10732
|
ready: singlesReady(minCell),
|
|
10012
|
-
send: /* @__PURE__ */
|
|
10733
|
+
send: /* @__PURE__ */ jsx104(RoundSend, { label: strings.send, display: strings.minPriceDisplay(count, minPrice), disabled: !minCell || streaming, onClick: () => {
|
|
10013
10734
|
if (minCell) onSend(minPriceAsk(minCell, strings));
|
|
10014
10735
|
} })
|
|
10015
10736
|
}
|
|
10016
10737
|
),
|
|
10017
|
-
/* @__PURE__ */
|
|
10738
|
+
/* @__PURE__ */ jsx104(
|
|
10018
10739
|
AskRow,
|
|
10019
10740
|
{
|
|
10020
10741
|
icon: "\u2728",
|
|
10021
10742
|
ask: fillTemplate(strings.comboRow, {
|
|
10022
|
-
legs: /* @__PURE__ */
|
|
10023
|
-
total: /* @__PURE__ */
|
|
10743
|
+
legs: /* @__PURE__ */ jsx104(NumberSelect, { current: String(legs), choices: legChoicesFor(total), label: strings.matchesLabel, notToday: strings.notToday, lockEmpty: false, onChoose: chooseLegs }),
|
|
10744
|
+
total: /* @__PURE__ */ jsx104(NumberSelect, { current: total.toFixed(1), choices: totalChoices, label: strings.totalLabel, notToday: strings.notToday, onChoose: chooseTotal })
|
|
10024
10745
|
}),
|
|
10025
10746
|
ready: comboReady(comboCell),
|
|
10026
|
-
send: /* @__PURE__ */
|
|
10747
|
+
send: /* @__PURE__ */ jsx104(RoundSend, { label: strings.send, display: strings.comboDisplay(legs, total), disabled: !comboCell || streaming, onClick: () => {
|
|
10027
10748
|
if (comboCell) onSend(comboAsk(comboCell, strings));
|
|
10028
10749
|
} })
|
|
10029
10750
|
}
|
|
10030
10751
|
),
|
|
10031
|
-
/* @__PURE__ */
|
|
10752
|
+
/* @__PURE__ */ jsx104(
|
|
10032
10753
|
AskRow,
|
|
10033
10754
|
{
|
|
10034
10755
|
icon: "\u{1F3C6}",
|
|
10035
10756
|
ask: fillTemplate(strings.bigComboRow, {
|
|
10036
|
-
legs: /* @__PURE__ */
|
|
10037
|
-
total: /* @__PURE__ */
|
|
10757
|
+
legs: /* @__PURE__ */ jsx104(NumberSelect, { current: String(bigLegs), choices: legChoicesFor(bigTotal), label: strings.matchesLabel, notToday: strings.notToday, lockEmpty: false, onChoose: chooseBigLegs }),
|
|
10758
|
+
total: /* @__PURE__ */ jsx104(NumberSelect, { current: bigTotal.toFixed(1), choices: totalChoices, label: strings.totalLabel, notToday: strings.notToday, onChoose: chooseBigTotal })
|
|
10038
10759
|
}),
|
|
10039
10760
|
ready: comboReady(bigCell),
|
|
10040
|
-
send: /* @__PURE__ */
|
|
10761
|
+
send: /* @__PURE__ */ jsx104(RoundSend, { label: strings.send, display: strings.comboDisplay(bigLegs, bigTotal), disabled: !bigCell || streaming, onClick: () => {
|
|
10041
10762
|
if (bigCell) onSend(comboAsk(bigCell, strings));
|
|
10042
10763
|
} })
|
|
10043
10764
|
}
|
|
10044
10765
|
),
|
|
10045
|
-
markets.length > 0 && /* @__PURE__ */
|
|
10766
|
+
markets.length > 0 && /* @__PURE__ */ jsx104(
|
|
10046
10767
|
AskRow,
|
|
10047
10768
|
{
|
|
10048
10769
|
icon: "\u26BD",
|
|
10049
10770
|
ask: fillTemplate(strings.marketRow, {
|
|
10050
|
-
market: /* @__PURE__ */
|
|
10771
|
+
market: /* @__PURE__ */ jsx104(ChoiceSelect, { currentIdx: marketIdx, sizeLabels: marketLabels, optionLabels: marketLabels, label: strings.marketName, onChoose: chooseMarket })
|
|
10051
10772
|
}),
|
|
10052
10773
|
ready: marketCell ? strings.readyCount(marketCell.count) : null,
|
|
10053
|
-
send: /* @__PURE__ */
|
|
10774
|
+
send: /* @__PURE__ */ jsx104(RoundSend, { label: strings.send, display: marketCell ? marketDisplay(marketCell, strings) : "", disabled: !marketCell || streaming, onClick: () => {
|
|
10054
10775
|
if (marketCell) onSend(marketAsk(marketCell, strings));
|
|
10055
10776
|
} })
|
|
10056
10777
|
}
|
|
10057
10778
|
),
|
|
10058
|
-
/* @__PURE__ */
|
|
10779
|
+
/* @__PURE__ */ jsx104("p", { className: "ss-w-vh", "aria-live": "polite", children: announcement })
|
|
10059
10780
|
] });
|
|
10060
10781
|
}
|
|
10061
10782
|
function BuildComboTool({ grid, strings, streaming, formatKickoff, initialTotal, initialLegs, onSend, onClose }) {
|
|
10062
10783
|
const totals = comboTotals(grid);
|
|
10063
10784
|
const legChoices = comboLegChoices(grid);
|
|
10064
|
-
const [start] =
|
|
10065
|
-
const [total, setTotal] =
|
|
10066
|
-
const [legs, setLegs] =
|
|
10785
|
+
const [start] = useState52(() => initialTotal === void 0 ? startCombo(grid, totals, legChoices, START.comboTotal, START.comboLegs) : null);
|
|
10786
|
+
const [total, setTotal] = useState52(() => initialTotal !== void 0 ? nearest(totals, initialTotal) : start.total);
|
|
10787
|
+
const [legs, setLegs] = useState52(() => {
|
|
10067
10788
|
if (initialTotal === void 0) return initialLegs !== void 0 ? clampLegs(legChoices, initialLegs) : start.legs;
|
|
10068
10789
|
const from = initialLegs !== void 0 ? clampLegs(legChoices, initialLegs) : startValue(legChoices, START.comboLegs);
|
|
10069
10790
|
return legsForTotal(grid, nearest(totals, initialTotal), from);
|
|
10070
10791
|
});
|
|
10071
|
-
const [announcement, setAnnouncement] =
|
|
10792
|
+
const [announcement, setAnnouncement] = useState52("");
|
|
10072
10793
|
const cell = findCombo(grid, total, legs);
|
|
10073
10794
|
const minLegs = legChoices[0] ?? legs;
|
|
10074
10795
|
const maxLegs = legChoices[legChoices.length - 1] ?? legs;
|
|
@@ -10079,29 +10800,29 @@ function BuildComboTool({ grid, strings, streaming, formatKickoff, initialTotal,
|
|
|
10079
10800
|
const d = strings.comboDisplay(nextLegs, nextTotal);
|
|
10080
10801
|
setAnnouncement(findCombo(grid, nextTotal, nextLegs) ? d : `${d}. ${strings.unavailable}`);
|
|
10081
10802
|
};
|
|
10082
|
-
const footer = /* @__PURE__ */
|
|
10803
|
+
const footer = /* @__PURE__ */ jsx104(SendButton, { label: strings.send, display, disabled: !cell || streaming, onClick: () => {
|
|
10083
10804
|
if (cell) onSend(comboAsk(cell, strings));
|
|
10084
10805
|
} });
|
|
10085
|
-
return /* @__PURE__ */
|
|
10086
|
-
/* @__PURE__ */
|
|
10087
|
-
/* @__PURE__ */
|
|
10088
|
-
/* @__PURE__ */
|
|
10806
|
+
return /* @__PURE__ */ jsxs88(PresetToolModal, { title: strings.buildCombo, closeLabel: strings.close, onClose, footer, children: [
|
|
10807
|
+
/* @__PURE__ */ jsxs88("div", { className: "ss-w-tool-section", role: "group", "aria-label": strings.totalLabel, children: [
|
|
10808
|
+
/* @__PURE__ */ jsx104("span", { className: "ss-w-tool-label", "aria-hidden": "true", children: strings.totalLabel }),
|
|
10809
|
+
/* @__PURE__ */ jsx104("div", { className: "ss-w-tool-chips", children: totals.map((t) => /* @__PURE__ */ jsx104("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)) })
|
|
10089
10810
|
] }),
|
|
10090
|
-
/* @__PURE__ */
|
|
10091
|
-
/* @__PURE__ */
|
|
10092
|
-
/* @__PURE__ */
|
|
10093
|
-
/* @__PURE__ */
|
|
10094
|
-
/* @__PURE__ */
|
|
10095
|
-
/* @__PURE__ */
|
|
10811
|
+
/* @__PURE__ */ jsxs88("div", { className: "ss-w-tool-section", role: "group", "aria-label": strings.matchesLabel, children: [
|
|
10812
|
+
/* @__PURE__ */ jsx104("span", { className: "ss-w-tool-label", "aria-hidden": "true", children: strings.matchesLabel }),
|
|
10813
|
+
/* @__PURE__ */ jsxs88("div", { className: "ss-w-tool-stepper", children: [
|
|
10814
|
+
/* @__PURE__ */ jsx104("button", { type: "button", className: "ss-w-tool-step", "aria-label": strings.fewerMatches, disabled: legs <= minLegs, onClick: () => choose(total, legs - 1), children: "\u2212" }),
|
|
10815
|
+
/* @__PURE__ */ jsx104("span", { className: "ss-w-tool-count", children: legs }),
|
|
10816
|
+
/* @__PURE__ */ jsx104("button", { type: "button", className: "ss-w-tool-step", "aria-label": strings.moreMatches, disabled: legs >= maxLegs, onClick: () => choose(total, legs + 1), children: "+" })
|
|
10096
10817
|
] })
|
|
10097
10818
|
] }),
|
|
10098
|
-
cell ? /* @__PURE__ */
|
|
10099
|
-
/* @__PURE__ */
|
|
10819
|
+
cell ? /* @__PURE__ */ jsx104(ComboPreview, { cell, formatKickoff }) : /* @__PURE__ */ jsx104(Unavailable, { text: strings.unavailable }),
|
|
10820
|
+
/* @__PURE__ */ jsx104("p", { className: "ss-w-vh", "aria-live": "polite", children: announcement })
|
|
10100
10821
|
] });
|
|
10101
10822
|
}
|
|
10102
10823
|
|
|
10103
10824
|
// src/usePresetDial.ts
|
|
10104
|
-
import { useCallback as
|
|
10825
|
+
import { useCallback as useCallback21, useEffect as useEffect32, useRef as useRef29, useState as useState53 } from "react";
|
|
10105
10826
|
function sendInFlight(messages, isStreaming) {
|
|
10106
10827
|
const last = messages[messages.length - 1];
|
|
10107
10828
|
return isStreaming && !!last && last.role === "assistant" && !last.done && !last.isGreeting;
|
|
@@ -10115,25 +10836,25 @@ function lastUserId(messages) {
|
|
|
10115
10836
|
}
|
|
10116
10837
|
var SCROLL_KEYS = /* @__PURE__ */ new Set(["ArrowUp", "ArrowDown", "PageUp", "PageDown", "Home", "End", " "]);
|
|
10117
10838
|
function usePresetDial({ layerRef, dialRef, dialButtonRef, messages, isStreaming, activeTab }) {
|
|
10118
|
-
const [expanded, setExpanded] =
|
|
10119
|
-
const fold =
|
|
10120
|
-
const toggle =
|
|
10839
|
+
const [expanded, setExpanded] = useState53(() => !sendInFlight(messages, isStreaming));
|
|
10840
|
+
const fold = useCallback21(() => setExpanded(false), []);
|
|
10841
|
+
const toggle = useCallback21(() => setExpanded((e) => !e), []);
|
|
10121
10842
|
const currentUserId = lastUserId(messages);
|
|
10122
|
-
const userIdRef =
|
|
10123
|
-
|
|
10843
|
+
const userIdRef = useRef29(currentUserId);
|
|
10844
|
+
useEffect32(() => {
|
|
10124
10845
|
if (currentUserId === userIdRef.current) return;
|
|
10125
10846
|
userIdRef.current = currentUserId;
|
|
10126
10847
|
setExpanded(false);
|
|
10127
10848
|
}, [currentUserId]);
|
|
10128
|
-
const tabRef =
|
|
10129
|
-
|
|
10849
|
+
const tabRef = useRef29(activeTab);
|
|
10850
|
+
useEffect32(() => {
|
|
10130
10851
|
if (activeTab === tabRef.current) return;
|
|
10131
10852
|
tabRef.current = activeTab;
|
|
10132
10853
|
setExpanded(false);
|
|
10133
10854
|
}, [activeTab]);
|
|
10134
|
-
const expandedRef =
|
|
10855
|
+
const expandedRef = useRef29(expanded);
|
|
10135
10856
|
expandedRef.current = expanded;
|
|
10136
|
-
|
|
10857
|
+
useEffect32(() => {
|
|
10137
10858
|
const onEscape = (e) => {
|
|
10138
10859
|
const dial = dialRef.current;
|
|
10139
10860
|
if (e.key !== "Escape" || !dial || !e.composedPath().includes(dial)) return;
|
|
@@ -10146,7 +10867,7 @@ function usePresetDial({ layerRef, dialRef, dialButtonRef, messages, isStreaming
|
|
|
10146
10867
|
window.addEventListener("keydown", onEscape, true);
|
|
10147
10868
|
return () => window.removeEventListener("keydown", onEscape, true);
|
|
10148
10869
|
}, [dialRef, dialButtonRef]);
|
|
10149
|
-
|
|
10870
|
+
useEffect32(() => {
|
|
10150
10871
|
if (!expanded) return;
|
|
10151
10872
|
const layer = layerRef.current;
|
|
10152
10873
|
const inDial = (e) => {
|
|
@@ -10198,11 +10919,11 @@ function markToolSeen() {
|
|
|
10198
10919
|
}
|
|
10199
10920
|
|
|
10200
10921
|
// src/components/ChatPanel.tsx
|
|
10201
|
-
import { Fragment as
|
|
10922
|
+
import { Fragment as Fragment25, jsx as jsx105, jsxs as jsxs89 } from "react/jsx-runtime";
|
|
10202
10923
|
var FULLSCREEN_QUERY = "(max-width: 639px)";
|
|
10203
10924
|
function useIsModal() {
|
|
10204
|
-
const [modal, setModal] =
|
|
10205
|
-
|
|
10925
|
+
const [modal, setModal] = useState54(false);
|
|
10926
|
+
useEffect33(() => {
|
|
10206
10927
|
if (typeof window === "undefined" || typeof window.matchMedia !== "function") return;
|
|
10207
10928
|
const mql = window.matchMedia(FULLSCREEN_QUERY);
|
|
10208
10929
|
const sync = () => setModal(mql.matches);
|
|
@@ -10213,10 +10934,38 @@ function useIsModal() {
|
|
|
10213
10934
|
return modal;
|
|
10214
10935
|
}
|
|
10215
10936
|
var HIDDEN_LAYER_STYLE = { position: "absolute", inset: 0, visibility: "hidden", display: "flex", flexDirection: "column" };
|
|
10216
|
-
|
|
10937
|
+
var SQUAD_LAYER_STYLE = { display: "flex", flexDirection: "column", flex: 1, minHeight: 0 };
|
|
10938
|
+
function ChatPanel({ controller, ui, slip, onDashboardTap, monitor, discovery, gamesResult, leaderboardResult, clubFixturesResult, clubStandingsResult, clubSquadResult, clubSquadStatsResult, clubPlayerDetailResult, loggedIn, conversation, presetGrid }) {
|
|
10217
10939
|
const { state, close, stop, send, reset } = controller;
|
|
10940
|
+
const [squadView, setSquadView] = useState54("roster");
|
|
10941
|
+
const [selectedPlayerId, setSelectedPlayerId] = useState54(null);
|
|
10942
|
+
const clearPlayerDetail = clubPlayerDetailResult?.clear;
|
|
10943
|
+
const fetchPlayerDetail = clubPlayerDetailResult?.fetch;
|
|
10944
|
+
const squadLayerRef = useRef30(null);
|
|
10945
|
+
const squadScrollRef = useRef30(null);
|
|
10946
|
+
const selectPlayer = (playerId) => {
|
|
10947
|
+
squadScrollRef.current = squadLayerRef.current?.querySelector(".ss-w-mon-list")?.scrollTop ?? null;
|
|
10948
|
+
setSelectedPlayerId(playerId);
|
|
10949
|
+
fetchPlayerDetail?.(playerId);
|
|
10950
|
+
};
|
|
10951
|
+
const closePlayer = () => {
|
|
10952
|
+
setSelectedPlayerId(null);
|
|
10953
|
+
clearPlayerDetail?.();
|
|
10954
|
+
};
|
|
10955
|
+
useLayoutEffect(() => {
|
|
10956
|
+
if (selectedPlayerId !== null || squadScrollRef.current === null) return;
|
|
10957
|
+
const list = squadLayerRef.current?.querySelector(".ss-w-mon-list");
|
|
10958
|
+
if (list) list.scrollTop = squadScrollRef.current;
|
|
10959
|
+
squadScrollRef.current = null;
|
|
10960
|
+
}, [selectedPlayerId]);
|
|
10961
|
+
const activeTab = monitor?.activeTab;
|
|
10962
|
+
useEffect33(() => {
|
|
10963
|
+
if (activeTab === "squad" || selectedPlayerId === null) return;
|
|
10964
|
+
setSelectedPlayerId(null);
|
|
10965
|
+
clearPlayerDetail?.();
|
|
10966
|
+
}, [activeTab, selectedPlayerId, clearPlayerDetail]);
|
|
10218
10967
|
const isModal = useIsModal();
|
|
10219
|
-
|
|
10968
|
+
useEffect33(() => {
|
|
10220
10969
|
const onKey = (e) => {
|
|
10221
10970
|
if (e.key === "Escape") close();
|
|
10222
10971
|
};
|
|
@@ -10232,19 +10981,19 @@ function ChatPanel({ controller, ui, slip, onDashboardTap, monitor, discovery, g
|
|
|
10232
10981
|
monitor?.setActiveTab("chat");
|
|
10233
10982
|
send(text, { grounding });
|
|
10234
10983
|
};
|
|
10235
|
-
|
|
10984
|
+
useEffect33(() => {
|
|
10236
10985
|
if (monitor && monitor.activeTab !== "chat" && state.isStreaming) monitor.markChatActivity();
|
|
10237
10986
|
}, [monitor, state.isStreaming, state.messages.length]);
|
|
10238
10987
|
const onChatTab = !monitor || monitor.activeTab === "chat";
|
|
10239
|
-
const layerRef =
|
|
10240
|
-
const dialRef =
|
|
10241
|
-
const dialButtonRef =
|
|
10242
|
-
const inputRef =
|
|
10243
|
-
const limitRef =
|
|
10244
|
-
const typedSendRef =
|
|
10245
|
-
const focusAfterCloseRef =
|
|
10246
|
-
const [tool, setTool] =
|
|
10247
|
-
const [toolSeen, setToolSeen] =
|
|
10988
|
+
const layerRef = useRef30(null);
|
|
10989
|
+
const dialRef = useRef30(null);
|
|
10990
|
+
const dialButtonRef = useRef30(null);
|
|
10991
|
+
const inputRef = useRef30(null);
|
|
10992
|
+
const limitRef = useRef30(null);
|
|
10993
|
+
const typedSendRef = useRef30(false);
|
|
10994
|
+
const focusAfterCloseRef = useRef30(null);
|
|
10995
|
+
const [tool, setTool] = useState54(null);
|
|
10996
|
+
const [toolSeen, setToolSeen] = useState54(readToolSeen);
|
|
10248
10997
|
const dial = usePresetDial({
|
|
10249
10998
|
layerRef,
|
|
10250
10999
|
dialRef,
|
|
@@ -10256,53 +11005,53 @@ function ChatPanel({ controller, ui, slip, onDashboardTap, monitor, discovery, g
|
|
|
10256
11005
|
const { fold } = dial;
|
|
10257
11006
|
const paused = isPaused(state.limit);
|
|
10258
11007
|
const showDial = !!presetGrid && onChatTab && !tool && !paused;
|
|
10259
|
-
|
|
11008
|
+
useEffect33(() => {
|
|
10260
11009
|
if (paused) setTool(null);
|
|
10261
11010
|
}, [paused]);
|
|
10262
|
-
|
|
11011
|
+
useEffect33(() => {
|
|
10263
11012
|
if (!paused) return;
|
|
10264
11013
|
if (typedSendRef.current) limitRef.current?.focus();
|
|
10265
11014
|
typedSendRef.current = false;
|
|
10266
11015
|
}, [paused]);
|
|
10267
|
-
const openTool =
|
|
11016
|
+
const openTool = useCallback22((next) => {
|
|
10268
11017
|
fold();
|
|
10269
11018
|
markToolSeen();
|
|
10270
11019
|
setToolSeen(true);
|
|
10271
11020
|
setTool(next);
|
|
10272
11021
|
}, [fold]);
|
|
10273
|
-
const onPill =
|
|
11022
|
+
const onPill = useCallback22((kind) => openTool(kind === "numbers" ? { kind: "numbers" } : { kind: "combo" }), [openTool]);
|
|
10274
11023
|
const toolsValue = useMemo5(
|
|
10275
11024
|
() => presetGrid && !paused ? { openBuilder: (total, legs) => openTool({ kind: "combo", total, legs }), changeLabel: ui.presets.changeCombo } : null,
|
|
10276
11025
|
[presetGrid, paused, openTool, ui.presets.changeCombo]
|
|
10277
11026
|
);
|
|
10278
|
-
const closeTool =
|
|
11027
|
+
const closeTool = useCallback22(() => {
|
|
10279
11028
|
focusAfterCloseRef.current = "dial";
|
|
10280
11029
|
setTool(null);
|
|
10281
11030
|
}, []);
|
|
10282
|
-
const sendAsk =
|
|
11031
|
+
const sendAsk = useCallback22((ask) => {
|
|
10283
11032
|
focusAfterCloseRef.current = "composer";
|
|
10284
11033
|
setTool(null);
|
|
10285
11034
|
monitor?.setActiveTab("chat");
|
|
10286
11035
|
send(ask.message, { displayText: ask.displayText, preset: ask.preset });
|
|
10287
11036
|
}, [monitor, send]);
|
|
10288
|
-
const formatKickoff =
|
|
11037
|
+
const formatKickoff = useCallback22((kickoffUtc) => {
|
|
10289
11038
|
const k = ui.bettingKickoff(kickoffUtc);
|
|
10290
11039
|
return `${k.dayLabel} ${k.time}`;
|
|
10291
11040
|
}, [ui]);
|
|
10292
|
-
|
|
11041
|
+
useEffect33(() => {
|
|
10293
11042
|
if (tool) return;
|
|
10294
11043
|
const target = focusAfterCloseRef.current;
|
|
10295
11044
|
focusAfterCloseRef.current = null;
|
|
10296
11045
|
if (target === "dial") dialButtonRef.current?.focus();
|
|
10297
11046
|
else if (target === "composer") inputRef.current?.focus();
|
|
10298
11047
|
}, [tool]);
|
|
10299
|
-
|
|
11048
|
+
useEffect33(() => {
|
|
10300
11049
|
if (!tool || onChatTab && presetGrid) return;
|
|
10301
11050
|
focusAfterCloseRef.current = "composer";
|
|
10302
11051
|
setTool(null);
|
|
10303
11052
|
}, [tool, onChatTab, presetGrid]);
|
|
10304
|
-
return /* @__PURE__ */
|
|
10305
|
-
/* @__PURE__ */
|
|
11053
|
+
return /* @__PURE__ */ jsxs89("div", { className: "ss-w-panel", role: "dialog", "aria-modal": isModal, "aria-label": ui.chatDialogLabel, children: [
|
|
11054
|
+
/* @__PURE__ */ jsx105(
|
|
10306
11055
|
ChatHeader,
|
|
10307
11056
|
{
|
|
10308
11057
|
onClose: close,
|
|
@@ -10315,7 +11064,7 @@ function ChatPanel({ controller, ui, slip, onDashboardTap, monitor, discovery, g
|
|
|
10315
11064
|
moreOptionsLabel: ui.moreOptions
|
|
10316
11065
|
}
|
|
10317
11066
|
),
|
|
10318
|
-
monitor && /* @__PURE__ */
|
|
11067
|
+
monitor && /* @__PURE__ */ jsx105(
|
|
10319
11068
|
TabBar,
|
|
10320
11069
|
{
|
|
10321
11070
|
monitor,
|
|
@@ -10328,9 +11077,9 @@ function ChatPanel({ controller, ui, slip, onDashboardTap, monitor, discovery, g
|
|
|
10328
11077
|
clubEnabled: clubFixturesResult?.enabled ?? false
|
|
10329
11078
|
}
|
|
10330
11079
|
),
|
|
10331
|
-
/* @__PURE__ */
|
|
10332
|
-
/* @__PURE__ */
|
|
10333
|
-
showDial ? /* @__PURE__ */
|
|
11080
|
+
/* @__PURE__ */ jsxs89("div", { ref: layerRef, className: "ss-w-chat-layer", "data-dial": presetGrid ? "" : void 0, style: onChatTab ? void 0 : HIDDEN_LAYER_STYLE, children: [
|
|
11081
|
+
/* @__PURE__ */ jsx105(PresetToolsContext.Provider, { value: toolsValue, children: /* @__PURE__ */ jsx105(MessageList, { controller, ui, slip, onDashboardTap, monitor }) }),
|
|
11082
|
+
showDial ? /* @__PURE__ */ jsx105(
|
|
10334
11083
|
PresetSpeedDial,
|
|
10335
11084
|
{
|
|
10336
11085
|
expanded: dial.expanded,
|
|
@@ -10342,15 +11091,41 @@ function ChatPanel({ controller, ui, slip, onDashboardTap, monitor, discovery, g
|
|
|
10342
11091
|
buttonRef: dialButtonRef
|
|
10343
11092
|
}
|
|
10344
11093
|
) : null,
|
|
10345
|
-
tool && presetGrid && onChatTab && !paused ? tool.kind === "numbers" ? /* @__PURE__ */
|
|
11094
|
+
tool && presetGrid && onChatTab && !paused ? tool.kind === "numbers" ? /* @__PURE__ */ jsx105(SetNumbersTool, { grid: presetGrid, strings: ui.presets, streaming: state.isStreaming, onSend: sendAsk, onClose: closeTool }) : /* @__PURE__ */ jsx105(BuildComboTool, { grid: presetGrid, strings: ui.presets, streaming: state.isStreaming, formatKickoff, initialTotal: tool.total, initialLegs: tool.legs, onSend: sendAsk, onClose: closeTool }) : null
|
|
10346
11095
|
] }),
|
|
10347
|
-
monitor && discovery && monitor.activeTab === "today" && /* @__PURE__ */
|
|
10348
|
-
monitor && monitor.activeTab === "following" && /* @__PURE__ */
|
|
10349
|
-
monitor && monitor.activeTab === "odds" && /* @__PURE__ */
|
|
10350
|
-
monitor && monitor.activeTab === "fixtures" && /* @__PURE__ */
|
|
10351
|
-
monitor && monitor.activeTab === "standings" && /* @__PURE__ */
|
|
10352
|
-
monitor && monitor.activeTab === "squad" && /* @__PURE__ */
|
|
10353
|
-
|
|
11096
|
+
monitor && discovery && monitor.activeTab === "today" && /* @__PURE__ */ jsx105(TodayPanel, { discovery, ui, monitor }),
|
|
11097
|
+
monitor && monitor.activeTab === "following" && /* @__PURE__ */ jsx105(MatchesPanel, { monitor, ui, slip, onAsk: paused ? void 0 : handleAsk }),
|
|
11098
|
+
monitor && monitor.activeTab === "odds" && /* @__PURE__ */ jsx105(OddsPanel, { monitor, ui, slip }),
|
|
11099
|
+
monitor && monitor.activeTab === "fixtures" && /* @__PURE__ */ jsx105(Fixtures, { fixtures: clubFixturesResult?.fixtures ?? [], loading: clubFixturesResult?.loading ?? false, ui }),
|
|
11100
|
+
monitor && monitor.activeTab === "standings" && /* @__PURE__ */ jsx105(Standings, { standings: clubStandingsResult?.data ?? null, loading: clubStandingsResult?.loading ?? false, ui }),
|
|
11101
|
+
monitor && monitor.activeTab === "squad" && /* @__PURE__ */ jsxs89(Fragment25, { children: [
|
|
11102
|
+
/* @__PURE__ */ jsx105(
|
|
11103
|
+
"div",
|
|
11104
|
+
{
|
|
11105
|
+
ref: squadLayerRef,
|
|
11106
|
+
style: selectedPlayerId === null ? SQUAD_LAYER_STYLE : HIDDEN_LAYER_STYLE,
|
|
11107
|
+
"aria-hidden": selectedPlayerId !== null ? true : void 0,
|
|
11108
|
+
children: /* @__PURE__ */ jsx105(
|
|
11109
|
+
Squad,
|
|
11110
|
+
{
|
|
11111
|
+
squad: clubSquadResult?.data ?? null,
|
|
11112
|
+
loading: clubSquadResult?.loading ?? false,
|
|
11113
|
+
ui,
|
|
11114
|
+
view: squadView,
|
|
11115
|
+
onToggleView: () => setSquadView((v) => v === "roster" ? "stats" : "roster"),
|
|
11116
|
+
stats: clubSquadStatsResult?.data ?? null,
|
|
11117
|
+
statsLoading: clubSquadStatsResult?.loading ?? false,
|
|
11118
|
+
seasonName: clubSquadStatsResult?.seasonName ?? null,
|
|
11119
|
+
competitionName: clubSquadStatsResult?.competitionName ?? null,
|
|
11120
|
+
matchesPlayed: clubSquadStatsResult?.matchesPlayed ?? null,
|
|
11121
|
+
onSelectPlayer: selectPlayer
|
|
11122
|
+
}
|
|
11123
|
+
)
|
|
11124
|
+
}
|
|
11125
|
+
),
|
|
11126
|
+
selectedPlayerId !== null && /* @__PURE__ */ jsx105(PlayerDetail, { detail: clubPlayerDetailResult?.data ?? null, loading: clubPlayerDetailResult?.loading ?? false, ui, seasonName: clubSquadStatsResult?.seasonName ?? null, onClose: closePlayer })
|
|
11127
|
+
] }),
|
|
11128
|
+
monitor && monitor.activeTab === "games" && gamesResult && /* @__PURE__ */ jsx105(
|
|
10354
11129
|
GamesPanel,
|
|
10355
11130
|
{
|
|
10356
11131
|
loggedIn: !!loggedIn,
|
|
@@ -10365,9 +11140,9 @@ function ChatPanel({ controller, ui, slip, onDashboardTap, monitor, discovery, g
|
|
|
10365
11140
|
}
|
|
10366
11141
|
}
|
|
10367
11142
|
),
|
|
10368
|
-
(!monitor || monitor.activeTab !== "games") && /* @__PURE__ */
|
|
10369
|
-
/* @__PURE__ */
|
|
10370
|
-
paused ? null : /* @__PURE__ */
|
|
11143
|
+
(!monitor || monitor.activeTab !== "games") && /* @__PURE__ */ jsxs89(Fragment25, { children: [
|
|
11144
|
+
/* @__PURE__ */ jsx105("div", { ref: limitRef, className: "ss-w-limit", role: "status", tabIndex: -1, children: state.limit ? limitText(state.limit, ui) : null }),
|
|
11145
|
+
paused ? null : /* @__PURE__ */ jsx105(
|
|
10371
11146
|
ChatInput,
|
|
10372
11147
|
{
|
|
10373
11148
|
ref: inputRef,
|
|
@@ -10386,9 +11161,9 @@ function ChatPanel({ controller, ui, slip, onDashboardTap, monitor, discovery, g
|
|
|
10386
11161
|
}
|
|
10387
11162
|
|
|
10388
11163
|
// src/components/HostEventsProvider.tsx
|
|
10389
|
-
import { jsx as
|
|
11164
|
+
import { jsx as jsx106 } from "react/jsx-runtime";
|
|
10390
11165
|
function HostEventsProvider({ value, children }) {
|
|
10391
|
-
return /* @__PURE__ */
|
|
11166
|
+
return /* @__PURE__ */ jsx106(SlipStateContext.Provider, { value: value.slipState, children });
|
|
10392
11167
|
}
|
|
10393
11168
|
|
|
10394
11169
|
// src/styles/css.generated.ts
|
|
@@ -10399,7 +11174,7 @@ var WIDGET_CSS = `.ss-w-root { all: revert; }
|
|
|
10399
11174
|
--ss-w-cta: #f5a623; --ss-w-cta-ink: #1b1300;
|
|
10400
11175
|
--ss-w-ink: #14181d; --ss-w-faint: #6b7580; --ss-w-line: #e4e8ec;
|
|
10401
11176
|
--ss-w-panel: #ffffff; --ss-w-bubble: #f3f5f7; --ss-w-nav: #0e1622;
|
|
10402
|
-
--ss-w-pos: #1aa563; --ss-w-neg: #e0524b;
|
|
11177
|
+
--ss-w-pos: #1aa563; --ss-w-neg: #e0524b; --ss-w-warn: #c07a00;
|
|
10403
11178
|
--ss-w-home: #3a63a8; --ss-w-away: #c8102e; --ss-w-track: #e9edf1;
|
|
10404
11179
|
--ss-w-correct: #1f9d55; --ss-w-wrong: #b9bbc2;
|
|
10405
11180
|
--ss-w-radius: 16px; --ss-w-offset-x: 20px; --ss-w-offset-y: 20px;
|
|
@@ -10411,7 +11186,7 @@ var WIDGET_CSS = `.ss-w-root { all: revert; }
|
|
|
10411
11186
|
--ss-w-accent: #37c891; --ss-w-cta: #ffb638; --ss-w-cta-ink: #1b1300;
|
|
10412
11187
|
--ss-w-ink: #e8edf2; --ss-w-faint: #8b95a1;
|
|
10413
11188
|
--ss-w-line: #2a3441; --ss-w-panel: #141b24; --ss-w-bubble: #1e2732; --ss-w-nav: #0a0f16;
|
|
10414
|
-
--ss-w-pos: #37c891; --ss-w-neg: #f0655d;
|
|
11189
|
+
--ss-w-pos: #37c891; --ss-w-neg: #f0655d; --ss-w-warn: #e0a030;
|
|
10415
11190
|
--ss-w-home: #5b83c8; --ss-w-away: #e8384f; --ss-w-track: #232d3a;
|
|
10416
11191
|
--ss-w-correct: #37c86b; --ss-w-wrong: #3a3a41;
|
|
10417
11192
|
}
|
|
@@ -10420,7 +11195,7 @@ var WIDGET_CSS = `.ss-w-root { all: revert; }
|
|
|
10420
11195
|
--ss-w-accent: #37c891; --ss-w-cta: #ffb638; --ss-w-cta-ink: #1b1300;
|
|
10421
11196
|
--ss-w-ink: #e8edf2; --ss-w-faint: #8b95a1;
|
|
10422
11197
|
--ss-w-line: #2a3441; --ss-w-panel: #141b24; --ss-w-bubble: #1e2732; --ss-w-nav: #0a0f16;
|
|
10423
|
-
--ss-w-pos: #37c891; --ss-w-neg: #f0655d;
|
|
11198
|
+
--ss-w-pos: #37c891; --ss-w-neg: #f0655d; --ss-w-warn: #e0a030;
|
|
10424
11199
|
--ss-w-home: #5b83c8; --ss-w-away: #e8384f; --ss-w-track: #232d3a;
|
|
10425
11200
|
--ss-w-correct: #37c86b; --ss-w-wrong: #3a3a41;
|
|
10426
11201
|
}
|
|
@@ -11467,7 +12242,7 @@ var WIDGET_CSS = `.ss-w-root { all: revert; }
|
|
|
11467
12242
|
/* live monitor tab bar: underline pattern mirrors .ss-w-ecard-scope; the unread dot uses --ss-w-neg */
|
|
11468
12243
|
.ss-w-tabs { display: flex; align-items: stretch; gap: 2px; border-bottom: 1px solid var(--ss-w-line); overflow-x: auto; scrollbar-width: none; }
|
|
11469
12244
|
.ss-w-tabs::-webkit-scrollbar { display: none; }
|
|
11470
|
-
.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
|
|
12245
|
+
.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; }
|
|
11471
12246
|
.ss-w-tab[data-on] { color: var(--ss-w-ink); border-bottom-color: var(--ss-w-accent); }
|
|
11472
12247
|
.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; }
|
|
11473
12248
|
.ss-w-tab[data-on] .ss-w-tab-count { color: var(--ss-w-accent); }
|
|
@@ -11549,6 +12324,108 @@ var WIDGET_CSS = `.ss-w-root { all: revert; }
|
|
|
11549
12324
|
.ss-w-sq-row { display: flex; align-items: center; gap: 10px; padding: 7px 2px; border-bottom: 1px solid var(--ss-w-line); }
|
|
11550
12325
|
.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); }
|
|
11551
12326
|
.ss-w-sq-name { font-size: 13px; font-weight: 600; color: var(--ss-w-ink); }
|
|
12327
|
+
.ss-w-sq-name { flex: 1; min-width: 0; }
|
|
12328
|
+
.ss-w-sq-name-1 { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
|
|
12329
|
+
.ss-w-sq-seg { display: flex; gap: 2px; padding: 2px; border-radius: var(--ss-w-radius); background: var(--ss-w-track); }
|
|
12330
|
+
.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; }
|
|
12331
|
+
.ss-w-sq-seg-btn[aria-pressed="true"] { background: var(--ss-w-panel); color: var(--ss-w-ink); }
|
|
12332
|
+
.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; }
|
|
12333
|
+
.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; }
|
|
12334
|
+
.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); }
|
|
12335
|
+
.ss-w-sq-head { border-bottom: 0; padding-bottom: 0; }
|
|
12336
|
+
.ss-w-sq-head .ss-w-sq-col { font-size: 10px; font-weight: 700; color: var(--ss-w-faint); }
|
|
12337
|
+
.ss-w-sq-stats { padding-top: 10px; gap: 10px; }
|
|
12338
|
+
.ss-w-sq-card { background: var(--ss-w-panel); border: 1px solid var(--ss-w-line); border-radius: 12px; overflow: hidden; }
|
|
12339
|
+
.ss-w-sq-stats .ss-w-sq-row { display: grid; grid-template-columns: 1fr 26px 30px 36px 20px 20px 20px 20px 36px; gap: 0; padding: 7px 10px; font-size: 11px; }
|
|
12340
|
+
.ss-w-sq-card > :last-child { border-bottom: 0; }
|
|
12341
|
+
.ss-w-sq-pos, .ss-w-sq-c20, .ss-w-sq-c30, .ss-w-sq-c36 { text-align: right; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; font-size: 11px; font-weight: 400; font-variant-numeric: tabular-nums; color: var(--ss-w-ink); }
|
|
12342
|
+
.ss-w-sq-stats .ss-w-sq-head { padding-bottom: 7px; border-bottom: 1px solid var(--ss-w-line); font-size: 9px; font-weight: 700; text-transform: uppercase; letter-spacing: .02em; color: var(--ss-w-faint); }
|
|
12343
|
+
.ss-w-sq-stats .ss-w-sq-head > span { font-size: 9px; font-weight: 700; color: var(--ss-w-faint); }
|
|
12344
|
+
.ss-w-sq-player { display: flex; align-items: center; gap: 6px; min-width: 0; }
|
|
12345
|
+
.ss-w-sq-badge { flex: none; width: 18px; height: 18px; border-radius: 6px; background: var(--ss-w-track); color: var(--ss-w-faint); font-size: 9px; font-weight: 700; display: flex; align-items: center; justify-content: center; }
|
|
12346
|
+
.ss-w-sq-stats .ss-w-sq-name { font-size: 11px; }
|
|
12347
|
+
.ss-w-sq-rtg { font-weight: 700; }
|
|
12348
|
+
.ss-w-sq-rtg-none { color: var(--ss-w-faint); font-weight: 400; }
|
|
12349
|
+
.ss-w-sq-stats .ss-w-pos-ink { color: var(--ss-w-pos); font-weight: 700; }
|
|
12350
|
+
.ss-w-sq-foot { padding: 0 2px; font-size: 10.5px; color: var(--ss-w-faint); }
|
|
12351
|
+
.ss-w-sq-bar { flex: none; display: flex; align-items: center; justify-content: space-between; gap: 8px; margin: 10px 14px 0; }
|
|
12352
|
+
.ss-w-sq-bar .ss-w-sq-seg { margin: 0; }
|
|
12353
|
+
.ss-w-sq-bar .ss-w-sq-seg:only-child { flex: 1; }
|
|
12354
|
+
.ss-w-sq-bar .ss-w-sq-seg:not(:only-child) { flex: none; }
|
|
12355
|
+
.ss-w-sq-eyebrow { flex: 1; min-width: 0; font-size: 10.5px; font-weight: 700; letter-spacing: .06em; text-transform: uppercase; color: var(--ss-w-faint); }
|
|
12356
|
+
@media (max-width: 429px) { .ss-w-sq-badge { display: none; } }
|
|
12357
|
+
@media (max-width: 359px) {
|
|
12358
|
+
.ss-w-sq-yr { display: none; }
|
|
12359
|
+
.ss-w-sq-stats .ss-w-sq-row { grid-template-columns: 1fr 26px 30px 36px 20px 20px 36px; }
|
|
12360
|
+
}
|
|
12361
|
+
.ss-w-pd-bar { flex: none; display: flex; align-items: center; padding: 12px 16px; border-bottom: 1px solid var(--ss-w-line); line-height: normal; }
|
|
12362
|
+
.ss-w-pd-back { display: flex; align-items: center; gap: 2px; min-height: 32px; padding: 8px 8px 8px 0; margin: -8px 0; border: 0; background: transparent; font: inherit; font-size: 12.5px; font-weight: 600; color: var(--ss-w-faint); cursor: pointer; }
|
|
12363
|
+
.ss-w-pd-back:hover { color: var(--ss-w-ink); }
|
|
12364
|
+
.ss-w-mon-list.ss-w-pd-list { padding: 16px; gap: 14px; line-height: normal; }
|
|
12365
|
+
.ss-w-pd-card { background: var(--ss-w-panel); border: 1px solid var(--ss-w-line); border-radius: 12px; }
|
|
12366
|
+
.ss-w-pd-faint { color: var(--ss-w-faint); }
|
|
12367
|
+
.ss-w-pd-profile { display: flex; gap: 12px; padding: 14px; }
|
|
12368
|
+
.ss-w-pd-photo { flex: none; border-radius: 50%; border: 1px solid var(--ss-w-line); background: var(--ss-w-bubble); object-fit: cover; }
|
|
12369
|
+
.ss-w-pd-avatar { display: flex; align-items: center; justify-content: center; font-weight: 700; color: var(--ss-w-ink); }
|
|
12370
|
+
.ss-w-pd-profile-main { flex: 1; min-width: 0; }
|
|
12371
|
+
.ss-w-pd-name { font-size: 16px; font-weight: 800; color: var(--ss-w-ink); overflow-wrap: break-word; }
|
|
12372
|
+
.ss-w-pd-sub { margin-top: 1px; font-size: 12px; color: var(--ss-w-faint); }
|
|
12373
|
+
/* Two columns as on the board, collapsing to one when a column would drop under 80px (narrow phones). */
|
|
12374
|
+
.ss-w-pd-bio { display: grid; grid-template-columns: repeat(auto-fill, minmax(max(80px, calc((100% - 10px) / 2)), 1fr)); gap: 4px 10px; margin-top: 10px; font-size: 11.5px; }
|
|
12375
|
+
.ss-w-pd-bio-item { min-width: 0; overflow-wrap: break-word; }
|
|
12376
|
+
.ss-w-pd-pitch { position: relative; flex: none; width: 56px; height: 76px; border: 1px solid var(--ss-w-line); border-radius: 6px; background: var(--ss-w-track); }
|
|
12377
|
+
.ss-w-pd-pitch-dot { position: absolute; width: 11px; height: 11px; border-radius: 50%; background: var(--ss-w-accent); border: 2px solid var(--ss-w-nav); transform: translate(-50%, -50%); }
|
|
12378
|
+
.ss-w-pd-avail { display: flex; align-items: center; justify-content: space-between; gap: 10px; padding: 10px 14px; }
|
|
12379
|
+
.ss-w-pd-avail-text { min-width: 0; }
|
|
12380
|
+
.ss-w-pd-avail-next { font-size: 12.5px; font-weight: 700; }
|
|
12381
|
+
.ss-w-pd-avail-note { margin-top: 1px; font-size: 11px; color: var(--ss-w-faint); }
|
|
12382
|
+
.ss-w-pd-pill { flex: none; padding: 4px 10px; border-radius: 999px; font-size: 11px; font-weight: 700; white-space: nowrap; }
|
|
12383
|
+
.ss-w-pd-pill--pos, .ss-w-pd-chip--pos { background: color-mix(in srgb, var(--ss-w-pos) 14%, transparent); color: var(--ss-w-pos); }
|
|
12384
|
+
.ss-w-pd-pill--warn, .ss-w-pd-chip--warn { background: color-mix(in srgb, var(--ss-w-warn) 14%, transparent); color: var(--ss-w-warn); }
|
|
12385
|
+
.ss-w-pd-pill--neg, .ss-w-pd-chip--neg { background: color-mix(in srgb, var(--ss-w-neg) 14%, transparent); color: var(--ss-w-neg); }
|
|
12386
|
+
.ss-w-pd-pill--draw { background: var(--ss-w-track); color: var(--ss-w-faint); }
|
|
12387
|
+
.ss-w-pd-eyebrow { font-size: 10.5px; font-weight: 700; letter-spacing: .06em; text-transform: uppercase; color: var(--ss-w-faint); padding: 0 2px; }
|
|
12388
|
+
.ss-w-pd-eyebrow--block { margin-bottom: 8px; }
|
|
12389
|
+
.ss-w-pd-tiles { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 8px; }
|
|
12390
|
+
.ss-w-pd-tile { min-width: 0; padding: 10px; background: var(--ss-w-panel); border: 1px solid var(--ss-w-line); border-radius: 12px; }
|
|
12391
|
+
.ss-w-pd-tile-label { font-size: 10.5px; color: var(--ss-w-faint); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
|
|
12392
|
+
.ss-w-pd-tile-value { margin-top: 2px; font-size: 18px; font-weight: 800; font-variant-numeric: tabular-nums; }
|
|
12393
|
+
.ss-w-pd-pos-ink { color: var(--ss-w-pos); }
|
|
12394
|
+
/* Below 360px the board's 10px tile padding clips "Matches"/"Minutes" (43px) in a ~34px label box. */
|
|
12395
|
+
@media (max-width: 359px) {
|
|
12396
|
+
.ss-w-pd-tiles { gap: 6px; }
|
|
12397
|
+
.ss-w-pd-tile { padding: 10px 6px; }
|
|
12398
|
+
}
|
|
12399
|
+
.ss-w-pd-perf-head { display: flex; align-items: center; justify-content: space-between; gap: 8px; margin-bottom: 2px; }
|
|
12400
|
+
.ss-w-pd-perf-head .ss-w-pd-eyebrow { flex: 1; min-width: 0; }
|
|
12401
|
+
.ss-w-pd-seg { flex: none; display: flex; gap: 2px; padding: 3px; border-radius: 999px; background: var(--ss-w-track); }
|
|
12402
|
+
.ss-w-pd-seg-btn { padding: 5px 12px; border: 0; border-radius: 999px; background: transparent; font: inherit; font-size: 11.5px; font-weight: 700; line-height: normal; white-space: nowrap; color: var(--ss-w-faint); cursor: pointer; }
|
|
12403
|
+
.ss-w-pd-seg-btn[aria-pressed="true"] { background: var(--ss-w-nav); color: #fff; }
|
|
12404
|
+
.ss-w-pd-seg-btn:focus-visible { outline: 2px solid var(--ss-w-accent); outline-offset: 1px; }
|
|
12405
|
+
.ss-w-pd-perf-sub { margin-bottom: 10px; font-size: 11px; color: var(--ss-w-faint); }
|
|
12406
|
+
.ss-w-pd-perf-head + .ss-w-pd-perf-cards { margin-top: 10px; }
|
|
12407
|
+
.ss-w-pd-perf-cards { display: flex; flex-direction: column; gap: 8px; }
|
|
12408
|
+
.ss-w-pd-perf-card { padding: 14px; }
|
|
12409
|
+
.ss-w-pd-perf-group { margin-bottom: 10px; font-size: 12.5px; font-weight: 700; }
|
|
12410
|
+
.ss-w-pd-bar-row + .ss-w-pd-bar-row { margin-top: 12px; }
|
|
12411
|
+
.ss-w-pd-bar-top { display: flex; align-items: baseline; justify-content: space-between; gap: 8px; margin-bottom: 5px; font-size: 12.5px; }
|
|
12412
|
+
.ss-w-pd-bar-label { min-width: 0; overflow-wrap: break-word; }
|
|
12413
|
+
.ss-w-pd-bar-value { flex: none; font-weight: 700; font-variant-numeric: tabular-nums; }
|
|
12414
|
+
.ss-w-pd-track { height: 6px; border-radius: 999px; background: var(--ss-w-track); overflow: hidden; }
|
|
12415
|
+
.ss-w-pd-fill { height: 100%; border-radius: 999px; }
|
|
12416
|
+
.ss-w-pd-fill--pos { background: var(--ss-w-pos); }
|
|
12417
|
+
.ss-w-pd-fill--warn { background: var(--ss-w-warn); }
|
|
12418
|
+
.ss-w-pd-fill--neg { background: var(--ss-w-neg); }
|
|
12419
|
+
.ss-w-pd-match { display: grid; grid-template-columns: 44px minmax(0, 1fr) auto auto; align-items: center; gap: 10px; padding: 9px 12px; border-bottom: 1px solid var(--ss-w-line); }
|
|
12420
|
+
.ss-w-pd-match:last-child { border-bottom: none; }
|
|
12421
|
+
.ss-w-pd-match-date { font-size: 10.5px; color: var(--ss-w-faint); }
|
|
12422
|
+
.ss-w-pd-match-opp { font-size: 12.5px; font-weight: 600; overflow-wrap: break-word; }
|
|
12423
|
+
.ss-w-pd-match-sub { margin-top: 1px; font-size: 10.5px; color: var(--ss-w-faint); }
|
|
12424
|
+
.ss-w-pd-chip-empty { min-width: 30px; }
|
|
12425
|
+
.ss-w-pd-chip { min-width: 30px; padding: 3px 0; border-radius: 6px; text-align: center; font-size: 11.5px; font-weight: 800; font-variant-numeric: tabular-nums; }
|
|
12426
|
+
.ss-w-rec-list { margin: 0; padding: 0; list-style: none; }
|
|
12427
|
+
.ss-w-rec-value { flex: none; font-size: 13px; font-weight: 700; font-variant-numeric: tabular-nums; color: var(--ss-w-ink); }
|
|
12428
|
+
.ss-w-rec-since { font-size: 12px; color: var(--ss-w-faint); }
|
|
11552
12429
|
/* Per-pin unavailable state: the pin's context line still rendered above (score, name, unpin), but
|
|
11553
12430
|
the pin has neither a card nor history (compose-time rescue failed) -- a small inline note beats
|
|
11554
12431
|
a bare context line with nothing under it. */
|
|
@@ -12152,7 +13029,7 @@ var WIDGET_CSS = `.ss-w-root { all: revert; }
|
|
|
12152
13029
|
`;
|
|
12153
13030
|
|
|
12154
13031
|
// src/StatsWidget.tsx
|
|
12155
|
-
import { jsx as
|
|
13032
|
+
import { jsx as jsx107 } from "react/jsx-runtime";
|
|
12156
13033
|
function buildClient(props) {
|
|
12157
13034
|
try {
|
|
12158
13035
|
if ("client" in props && props.client) {
|
|
@@ -12186,14 +13063,14 @@ function StatsWidget(props) {
|
|
|
12186
13063
|
[built?.client]
|
|
12187
13064
|
);
|
|
12188
13065
|
const ui = useMemo6(() => normalizeUi(props.config ?? { operatorId: "", publicKey: "" }), [props.config]);
|
|
12189
|
-
const rootRef =
|
|
12190
|
-
const introDoneRef =
|
|
12191
|
-
const markIntroDone =
|
|
13066
|
+
const rootRef = useRef31(null);
|
|
13067
|
+
const introDoneRef = useRef31(false);
|
|
13068
|
+
const markIntroDone = useCallback23(() => {
|
|
12192
13069
|
introDoneRef.current = true;
|
|
12193
13070
|
}, []);
|
|
12194
13071
|
const convStorageKey = `ss-w-conv:${cfg?.operatorId ?? ""}:${cfg?.userContext?.operatorUserId ?? "anon"}`;
|
|
12195
13072
|
const controller = useChatStream(built?.conversation ?? emptyConversation(), ui.starters, built ? ui.greetingMessage : void 0, convStorageKey);
|
|
12196
|
-
const [hasToday, setHasToday] =
|
|
13073
|
+
const [hasToday, setHasToday] = useState55(false);
|
|
12197
13074
|
const liveCardWatches = useMemo6(() => {
|
|
12198
13075
|
const seen = /* @__PURE__ */ new Set();
|
|
12199
13076
|
const out = [];
|
|
@@ -12220,15 +13097,15 @@ function StatsWidget(props) {
|
|
|
12220
13097
|
});
|
|
12221
13098
|
const operatorUserId = cfg?.userContext?.operatorUserId;
|
|
12222
13099
|
const anonymousUserId = cfg?.userContext?.anonymousUserId;
|
|
12223
|
-
const getSchedule =
|
|
13100
|
+
const getSchedule = useCallback23(
|
|
12224
13101
|
(localDate, utcOffsetMinutes) => built ? built.conversation.getSchedule(localDate, utcOffsetMinutes, operatorUserId, anonymousUserId) : Promise.resolve(null),
|
|
12225
13102
|
[built, operatorUserId, anonymousUserId]
|
|
12226
13103
|
);
|
|
12227
|
-
const postLeagueStar =
|
|
13104
|
+
const postLeagueStar = useCallback23(
|
|
12228
13105
|
(competitionId, starred) => built ? built.conversation.starLeague(competitionId, starred, operatorUserId, anonymousUserId) : Promise.resolve(null),
|
|
12229
13106
|
[built, operatorUserId, anonymousUserId]
|
|
12230
13107
|
);
|
|
12231
|
-
const getStates =
|
|
13108
|
+
const getStates = useCallback23(
|
|
12232
13109
|
(matchIds) => built ? built.conversation.getStates(matchIds) : Promise.resolve(null),
|
|
12233
13110
|
[built]
|
|
12234
13111
|
);
|
|
@@ -12247,11 +13124,11 @@ function StatsWidget(props) {
|
|
|
12247
13124
|
pinnedMatchIds
|
|
12248
13125
|
});
|
|
12249
13126
|
const todayHasContent = visibleGroupsOf(discovery.groups, discovery.states).length > 0;
|
|
12250
|
-
|
|
13127
|
+
useEffect34(() => {
|
|
12251
13128
|
setHasToday(todayHasContent);
|
|
12252
13129
|
}, [todayHasContent]);
|
|
12253
|
-
const prevLiveSnapshotRef =
|
|
12254
|
-
|
|
13130
|
+
const prevLiveSnapshotRef = useRef31(monitor.snapshot);
|
|
13131
|
+
useEffect34(() => {
|
|
12255
13132
|
const snap = monitor.snapshot;
|
|
12256
13133
|
if (!snap || snap === prevLiveSnapshotRef.current) return;
|
|
12257
13134
|
prevLiveSnapshotRef.current = snap;
|
|
@@ -12289,14 +13166,16 @@ function StatsWidget(props) {
|
|
|
12289
13166
|
const leaderboardResult = useLeaderboard(built?.conversation ?? null, { activeTab: monitor.activeTab });
|
|
12290
13167
|
const clubStandingsResult = useClubStandings(built?.conversation ?? null, { activeTab: monitor.activeTab, enabled: clubFixturesResult.enabled });
|
|
12291
13168
|
const clubSquadResult = useClubSquad(built?.conversation ?? null, { activeTab: monitor.activeTab, enabled: clubFixturesResult.enabled });
|
|
12292
|
-
const
|
|
13169
|
+
const clubSquadStatsResult = useClubSquadStats(built?.conversation ?? null, { activeTab: monitor.activeTab, enabled: clubFixturesResult.enabled });
|
|
13170
|
+
const clubPlayerDetailResult = useClubPlayerDetail(built?.conversation ?? null);
|
|
13171
|
+
const getPricePresets = useCallback23(
|
|
12293
13172
|
(locale2) => built ? built.conversation.getPricePresets(locale2, { pool: "open" }) : Promise.resolve(null),
|
|
12294
13173
|
[built]
|
|
12295
13174
|
);
|
|
12296
13175
|
const presetGrid = usePresetGrid({ getPricePresets, isOpen: controller.state.isOpen, locale: ui.presets.lang });
|
|
12297
13176
|
const markTodayActivity = monitor.markTodayActivity;
|
|
12298
|
-
const prevLiveCountRef =
|
|
12299
|
-
|
|
13177
|
+
const prevLiveCountRef = useRef31(0);
|
|
13178
|
+
useEffect34(() => {
|
|
12300
13179
|
const rose = prevLiveCountRef.current === 0 && discovery.liveCount > 0;
|
|
12301
13180
|
prevLiveCountRef.current = discovery.liveCount;
|
|
12302
13181
|
if (rose) markTodayActivity();
|
|
@@ -12346,11 +13225,11 @@ function StatsWidget(props) {
|
|
|
12346
13225
|
})
|
|
12347
13226
|
}));
|
|
12348
13227
|
const conversationId = controller.state.conversationId ?? void 0;
|
|
12349
|
-
|
|
13228
|
+
useEffect34(() => {
|
|
12350
13229
|
if (!logger) return;
|
|
12351
13230
|
logger.setIdentity({ operatorUserId, anonymousUserId, conversationId });
|
|
12352
13231
|
}, [logger, operatorUserId, anonymousUserId, conversationId]);
|
|
12353
|
-
|
|
13232
|
+
useEffect34(() => {
|
|
12354
13233
|
if (!logger) return;
|
|
12355
13234
|
logger.resume();
|
|
12356
13235
|
const onHide = () => {
|
|
@@ -12368,14 +13247,14 @@ function StatsWidget(props) {
|
|
|
12368
13247
|
logger.dispose();
|
|
12369
13248
|
};
|
|
12370
13249
|
}, [logger]);
|
|
12371
|
-
|
|
13250
|
+
useEffect34(() => {
|
|
12372
13251
|
if (!built || !ui.injectStyles) return;
|
|
12373
13252
|
const node = rootRef.current?.getRootNode();
|
|
12374
13253
|
if (node) injectStyles(node);
|
|
12375
13254
|
}, [built, ui.injectStyles]);
|
|
12376
13255
|
if (!built) return null;
|
|
12377
13256
|
const attrs = themeAttrs(ui);
|
|
12378
|
-
return /* @__PURE__ */
|
|
13257
|
+
return /* @__PURE__ */ jsx107(EventLogContext.Provider, { value: logger, children: /* @__PURE__ */ jsx107(HostEventsProvider, { value: hostEvents, children: /* @__PURE__ */ jsx107("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__ */ jsx107(
|
|
12379
13258
|
ChatPanel,
|
|
12380
13259
|
{
|
|
12381
13260
|
controller,
|
|
@@ -12389,11 +13268,13 @@ function StatsWidget(props) {
|
|
|
12389
13268
|
clubFixturesResult,
|
|
12390
13269
|
clubStandingsResult,
|
|
12391
13270
|
clubSquadResult,
|
|
13271
|
+
clubSquadStatsResult,
|
|
13272
|
+
clubPlayerDetailResult,
|
|
12392
13273
|
loggedIn: !!operatorUserId,
|
|
12393
13274
|
conversation: built?.conversation ?? null,
|
|
12394
13275
|
presetGrid
|
|
12395
13276
|
}
|
|
12396
|
-
) : /* @__PURE__ */
|
|
13277
|
+
) : /* @__PURE__ */ jsx107(
|
|
12397
13278
|
ChatFab,
|
|
12398
13279
|
{
|
|
12399
13280
|
label: ui.launcherLabel,
|