@sensiblestats/widget-react 0.85.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 +11 -0
- package/dist/index.cjs +743 -273
- 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 +682 -212
- package/dist/index.js.map +1 -1
- package/dist/styles.css +93 -13
- package/package.json +2 -2
package/dist/index.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
// src/StatsWidget.tsx
|
|
2
|
-
import { useCallback as useCallback23, useEffect as useEffect34, useMemo as useMemo6, useRef as useRef31, useState 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",
|
|
@@ -152,6 +157,60 @@ var STRINGS = {
|
|
|
152
157
|
recordsMostAssists: "Most assists",
|
|
153
158
|
recordsSince: "Since {season}",
|
|
154
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" }),
|
|
155
214
|
standingsColPlayed: "P",
|
|
156
215
|
standingsColWon: "W",
|
|
157
216
|
standingsColDrawn: "D",
|
|
@@ -565,6 +624,60 @@ var STRINGS = {
|
|
|
565
624
|
recordsMostAssists: "En \xE7ok asist yapanlar",
|
|
566
625
|
recordsSince: "{season} sezonundan beri",
|
|
567
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" }),
|
|
568
681
|
standingsColPlayed: "O",
|
|
569
682
|
standingsColWon: "G",
|
|
570
683
|
standingsColDrawn: "B",
|
|
@@ -975,6 +1088,45 @@ function normalizeUi(cfg) {
|
|
|
975
1088
|
recordsMostAssists: strings.recordsMostAssists,
|
|
976
1089
|
recordsSince: strings.recordsSince,
|
|
977
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,
|
|
978
1130
|
standingsColPlayed: strings.standingsColPlayed,
|
|
979
1131
|
standingsColWon: strings.standingsColWon,
|
|
980
1132
|
standingsColDrawn: strings.standingsColDrawn,
|
|
@@ -3344,6 +3496,8 @@ import { useCallback as useCallback10, useEffect as useEffect11, useRef as useRe
|
|
|
3344
3496
|
function useClubSquadStats(conversation, { activeTab, enabled }) {
|
|
3345
3497
|
const [data, setData] = useState10(null);
|
|
3346
3498
|
const [seasonName, setSeasonName] = useState10(null);
|
|
3499
|
+
const [competitionName, setCompetitionName] = useState10(null);
|
|
3500
|
+
const [matchesPlayed, setMatchesPlayed] = useState10(null);
|
|
3347
3501
|
const [loading, setLoading] = useState10(false);
|
|
3348
3502
|
const [refreshCount, setRefreshCount] = useState10(0);
|
|
3349
3503
|
const inFlightRef = useRef11(false);
|
|
@@ -3362,6 +3516,8 @@ function useClubSquadStats(conversation, { activeTab, enabled }) {
|
|
|
3362
3516
|
if (active) {
|
|
3363
3517
|
setData(result?.players ?? null);
|
|
3364
3518
|
setSeasonName(result?.seasonName ?? null);
|
|
3519
|
+
setCompetitionName(result?.competitionName ?? null);
|
|
3520
|
+
setMatchesPlayed(result?.clubMatchesPlayed ?? null);
|
|
3365
3521
|
}
|
|
3366
3522
|
} catch {
|
|
3367
3523
|
} finally {
|
|
@@ -3379,7 +3535,7 @@ function useClubSquadStats(conversation, { activeTab, enabled }) {
|
|
|
3379
3535
|
setRefreshCount((c) => c + 1);
|
|
3380
3536
|
}, []);
|
|
3381
3537
|
const effectiveLoading = loading || activeTab === "squad" && enabled && data === null;
|
|
3382
|
-
return { data, seasonName, loading: effectiveLoading, refresh };
|
|
3538
|
+
return { data, seasonName, competitionName, matchesPlayed, loading: effectiveLoading, refresh };
|
|
3383
3539
|
}
|
|
3384
3540
|
|
|
3385
3541
|
// src/useClubPlayerDetail.ts
|
|
@@ -3779,7 +3935,7 @@ function ChatFab({ label, greeting, popupText, logoUrl, onOpen, onDismissPopup,
|
|
|
3779
3935
|
}
|
|
3780
3936
|
|
|
3781
3937
|
// src/components/ChatPanel.tsx
|
|
3782
|
-
import { useCallback as useCallback22, useEffect as useEffect33, useLayoutEffect, useMemo as useMemo5, useRef as useRef30, useState as
|
|
3938
|
+
import { useCallback as useCallback22, useEffect as useEffect33, useLayoutEffect, useMemo as useMemo5, useRef as useRef30, useState as useState54 } from "react";
|
|
3783
3939
|
|
|
3784
3940
|
// src/components/ChatHeader.tsx
|
|
3785
3941
|
import { useEffect as useEffect16, useRef as useRef17, useState as useState15 } from "react";
|
|
@@ -9967,51 +10123,92 @@ function footLabel(ui, foot) {
|
|
|
9967
10123
|
return v;
|
|
9968
10124
|
}
|
|
9969
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
|
+
}
|
|
9970
10136
|
|
|
9971
10137
|
// src/components/SquadStats.tsx
|
|
9972
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
|
+
}
|
|
9973
10151
|
function SquadStats({ stats, loading, ui, onSelectPlayer }) {
|
|
9974
10152
|
if (stats === null && loading) return /* @__PURE__ */ jsx97("div", { className: "ss-w-mon-list" });
|
|
9975
10153
|
if (stats === null || stats.length === 0) return /* @__PURE__ */ jsx97("div", { className: "ss-w-mon-empty", children: ui.clubSquadStatsEmpty });
|
|
9976
|
-
|
|
9977
|
-
|
|
9978
|
-
|
|
9979
|
-
|
|
9980
|
-
|
|
9981
|
-
|
|
9982
|
-
|
|
9983
|
-
|
|
9984
|
-
|
|
9985
|
-
|
|
9986
|
-
|
|
9987
|
-
|
|
9988
|
-
/* @__PURE__ */ jsx97("span", { className: "ss-w-sq-
|
|
9989
|
-
/* @__PURE__ */ jsx97("span", { className: "ss-w-sq-
|
|
9990
|
-
/* @__PURE__ */ jsx97("span", { className: "ss-w-sq-
|
|
9991
|
-
/* @__PURE__ */ jsx97("span", { className: "ss-w-sq-
|
|
9992
|
-
/* @__PURE__ */ jsx97("span", { className: "ss-w-sq-
|
|
9993
|
-
/* @__PURE__ */ jsx97("span", { className: "ss-w-sq-
|
|
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) })
|
|
9994
10186
|
] }, p.playerId))
|
|
9995
|
-
] },
|
|
10187
|
+
] }),
|
|
10188
|
+
footer !== "" && /* @__PURE__ */ jsx97("div", { className: "ss-w-sq-foot", children: footer })
|
|
9996
10189
|
] });
|
|
9997
10190
|
}
|
|
9998
10191
|
|
|
9999
10192
|
// src/components/Squad.tsx
|
|
10000
10193
|
import { Fragment as Fragment21, jsx as jsx98, jsxs as jsxs84 } from "react/jsx-runtime";
|
|
10001
|
-
function Squad({ squad, loading, ui, view, onToggleView, stats, statsLoading, onSelectPlayer }) {
|
|
10002
|
-
const
|
|
10003
|
-
|
|
10004
|
-
{
|
|
10005
|
-
|
|
10006
|
-
|
|
10007
|
-
|
|
10008
|
-
|
|
10009
|
-
|
|
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
|
|
10010
10208
|
},
|
|
10011
|
-
|
|
10012
|
-
}
|
|
10013
|
-
|
|
10014
|
-
)) });
|
|
10209
|
+
v
|
|
10210
|
+
)) })
|
|
10211
|
+
] });
|
|
10015
10212
|
if (view === "stats") {
|
|
10016
10213
|
return /* @__PURE__ */ jsxs84(Fragment21, { children: [
|
|
10017
10214
|
toggle,
|
|
@@ -10038,8 +10235,125 @@ function Squad({ squad, loading, ui, view, onToggleView, stats, statsLoading, on
|
|
|
10038
10235
|
] });
|
|
10039
10236
|
}
|
|
10040
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
|
+
|
|
10041
10355
|
// src/components/PlayerDetail.tsx
|
|
10042
|
-
import { Fragment as Fragment22, jsx as
|
|
10356
|
+
import { Fragment as Fragment22, jsx as jsx102, jsxs as jsxs86 } from "react/jsx-runtime";
|
|
10043
10357
|
var DASH = "\u2014";
|
|
10044
10358
|
function ageFrom(dobMs) {
|
|
10045
10359
|
if (dobMs === null) return DASH;
|
|
@@ -10050,55 +10364,128 @@ function ageFrom(dobMs) {
|
|
|
10050
10364
|
if (beforeBirthday) age--;
|
|
10051
10365
|
return String(age);
|
|
10052
10366
|
}
|
|
10053
|
-
function
|
|
10054
|
-
return
|
|
10055
|
-
|
|
10056
|
-
|
|
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) })
|
|
10057
10428
|
] });
|
|
10058
10429
|
}
|
|
10059
10430
|
function PlayerDetail({ detail, loading, ui, seasonName, onClose }) {
|
|
10060
|
-
const back = /* @__PURE__ */
|
|
10061
|
-
/* @__PURE__ */
|
|
10062
|
-
" ",
|
|
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" }) }),
|
|
10063
10433
|
ui.clubPlayerBack
|
|
10064
10434
|
] });
|
|
10065
10435
|
if (detail === null) {
|
|
10066
|
-
return loading ? /* @__PURE__ */
|
|
10067
|
-
/* @__PURE__ */
|
|
10068
|
-
/* @__PURE__ */
|
|
10069
|
-
] }) : /* @__PURE__ */
|
|
10070
|
-
/* @__PURE__ */
|
|
10071
|
-
/* @__PURE__ */
|
|
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 })
|
|
10072
10442
|
] });
|
|
10073
10443
|
}
|
|
10074
10444
|
const s = detail.seasonStats;
|
|
10075
|
-
const
|
|
10076
|
-
|
|
10077
|
-
|
|
10078
|
-
|
|
10079
|
-
|
|
10080
|
-
|
|
10081
|
-
|
|
10082
|
-
|
|
10083
|
-
|
|
10084
|
-
|
|
10085
|
-
|
|
10086
|
-
|
|
10087
|
-
|
|
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 })
|
|
10088
10470
|
] }),
|
|
10089
|
-
/* @__PURE__ */
|
|
10090
|
-
|
|
10091
|
-
/* @__PURE__ */
|
|
10092
|
-
|
|
10093
|
-
/* @__PURE__ */
|
|
10094
|
-
/* @__PURE__ */
|
|
10095
|
-
/* @__PURE__ */
|
|
10096
|
-
/* @__PURE__ */
|
|
10097
|
-
/* @__PURE__ */
|
|
10098
|
-
/* @__PURE__ */
|
|
10099
|
-
/* @__PURE__ */
|
|
10100
|
-
/* @__PURE__ */
|
|
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) })
|
|
10101
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)) })
|
|
10102
10489
|
] })
|
|
10103
10490
|
] })
|
|
10104
10491
|
] });
|
|
@@ -10106,12 +10493,12 @@ function PlayerDetail({ detail, loading, ui, seasonName, onClose }) {
|
|
|
10106
10493
|
|
|
10107
10494
|
// src/components/PresetSpeedDial.tsx
|
|
10108
10495
|
import { useId as useId10 } from "react";
|
|
10109
|
-
import { jsx as
|
|
10496
|
+
import { jsx as jsx103, jsxs as jsxs87 } from "react/jsx-runtime";
|
|
10110
10497
|
function PresetSpeedDial({ expanded, showDot, strings, onToggle, onOpen, rootRef, buttonRef }) {
|
|
10111
10498
|
const pillsId = useId10();
|
|
10112
10499
|
const tabIndex = expanded ? 0 : -1;
|
|
10113
|
-
return /* @__PURE__ */
|
|
10114
|
-
/* @__PURE__ */
|
|
10500
|
+
return /* @__PURE__ */ jsxs87("div", { ref: rootRef, className: "ss-w-dial", children: [
|
|
10501
|
+
/* @__PURE__ */ jsxs87(
|
|
10115
10502
|
"button",
|
|
10116
10503
|
{
|
|
10117
10504
|
ref: buttonRef,
|
|
@@ -10122,28 +10509,28 @@ function PresetSpeedDial({ expanded, showDot, strings, onToggle, onOpen, rootRef
|
|
|
10122
10509
|
"aria-label": strings.dialName,
|
|
10123
10510
|
onClick: onToggle,
|
|
10124
10511
|
children: [
|
|
10125
|
-
/* @__PURE__ */
|
|
10126
|
-
/* @__PURE__ */
|
|
10127
|
-
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
|
|
10128
10515
|
]
|
|
10129
10516
|
}
|
|
10130
10517
|
),
|
|
10131
|
-
/* @__PURE__ */
|
|
10132
|
-
/* @__PURE__ */
|
|
10133
|
-
/* @__PURE__ */
|
|
10134
|
-
/* @__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 })
|
|
10135
10522
|
] }),
|
|
10136
|
-
/* @__PURE__ */
|
|
10137
|
-
/* @__PURE__ */
|
|
10138
|
-
/* @__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 })
|
|
10139
10526
|
] })
|
|
10140
10527
|
] })
|
|
10141
10528
|
] });
|
|
10142
10529
|
}
|
|
10143
10530
|
|
|
10144
10531
|
// src/components/PresetTools.tsx
|
|
10145
|
-
import { Fragment as Fragment23, useEffect as useEffect31, useId as useId11, useRef as useRef28, useState as
|
|
10146
|
-
import { Fragment as Fragment24, jsx 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";
|
|
10147
10534
|
var FOCUSABLE = 'button:not([disabled]), [href], input:not([disabled]), textarea:not([disabled]), [tabindex]:not([tabindex="-1"])';
|
|
10148
10535
|
function PresetToolModal({ title, closeLabel, onClose, children, footer }) {
|
|
10149
10536
|
const dialogRef = useRef28(null);
|
|
@@ -10181,79 +10568,79 @@ function PresetToolModal({ title, closeLabel, onClose, children, footer }) {
|
|
|
10181
10568
|
first.focus();
|
|
10182
10569
|
}
|
|
10183
10570
|
};
|
|
10184
|
-
return /* @__PURE__ */
|
|
10185
|
-
/* @__PURE__ */
|
|
10186
|
-
/* @__PURE__ */
|
|
10187
|
-
/* @__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, {}) })
|
|
10188
10575
|
] }),
|
|
10189
|
-
/* @__PURE__ */
|
|
10190
|
-
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
|
|
10191
10578
|
] }) });
|
|
10192
10579
|
}
|
|
10193
10580
|
function fillTemplate(template, slots) {
|
|
10194
10581
|
return template.split(/(\{[a-z]+\})/).filter((part) => part !== "").map((part, i) => {
|
|
10195
10582
|
const key = /^\{([a-z]+)\}$/.exec(part)?.[1];
|
|
10196
|
-
return /* @__PURE__ */
|
|
10583
|
+
return /* @__PURE__ */ jsx104(Fragment23, { children: key !== void 0 && key in slots ? slots[key] : part }, i);
|
|
10197
10584
|
});
|
|
10198
10585
|
}
|
|
10199
10586
|
function NumberSelect({ current, choices: choices2, label, notToday, lockEmpty = true, onChoose }) {
|
|
10200
10587
|
const selected = Math.max(0, choices2.findIndex((c) => c.text === current));
|
|
10201
|
-
return /* @__PURE__ */
|
|
10202
|
-
/* @__PURE__ */
|
|
10203
|
-
/* @__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) => {
|
|
10204
10591
|
const c = choices2[Number(e.target.value)];
|
|
10205
10592
|
if (c) onChoose(c.value);
|
|
10206
|
-
}, 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)) })
|
|
10207
10594
|
] });
|
|
10208
10595
|
}
|
|
10209
10596
|
function ChoiceSelect({ currentIdx, sizeLabels, optionLabels, label, onChoose }) {
|
|
10210
10597
|
const sizeText = sizeLabels[currentIdx] ?? "";
|
|
10211
|
-
return /* @__PURE__ */
|
|
10212
|
-
/* @__PURE__ */
|
|
10213
|
-
/* @__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)) })
|
|
10214
10601
|
] });
|
|
10215
10602
|
}
|
|
10216
10603
|
function SendButton({ label, display, disabled, onClick }) {
|
|
10217
|
-
return /* @__PURE__ */
|
|
10604
|
+
return /* @__PURE__ */ jsx104("button", { type: "button", className: "ss-w-tool-send", "aria-label": `${label}: ${display}`, disabled, onClick, children: label });
|
|
10218
10605
|
}
|
|
10219
10606
|
function PickList({ picks, formatKickoff }) {
|
|
10220
|
-
return /* @__PURE__ */
|
|
10221
|
-
/* @__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: [
|
|
10222
10609
|
p.homeTeamName,
|
|
10223
10610
|
" \u2013 ",
|
|
10224
10611
|
p.awayTeamName
|
|
10225
10612
|
] }),
|
|
10226
|
-
/* @__PURE__ */
|
|
10613
|
+
/* @__PURE__ */ jsxs88("span", { className: "ss-w-tool-pick-sel", children: [
|
|
10227
10614
|
p.marketLabel,
|
|
10228
10615
|
": ",
|
|
10229
10616
|
p.selectionLabel,
|
|
10230
10617
|
p.line ? ` ${p.line}` : ""
|
|
10231
10618
|
] }),
|
|
10232
|
-
/* @__PURE__ */
|
|
10233
|
-
/* @__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) })
|
|
10234
10621
|
] }, p.matchOddsId)) });
|
|
10235
10622
|
}
|
|
10236
10623
|
function ComboPreview({ cell, formatKickoff }) {
|
|
10237
|
-
return /* @__PURE__ */
|
|
10238
|
-
/* @__PURE__ */
|
|
10239
|
-
/* @__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 })
|
|
10240
10627
|
] });
|
|
10241
10628
|
}
|
|
10242
10629
|
function Unavailable({ text }) {
|
|
10243
|
-
return /* @__PURE__ */
|
|
10630
|
+
return /* @__PURE__ */ jsx104("p", { className: "ss-w-tool-unavailable", children: text });
|
|
10244
10631
|
}
|
|
10245
10632
|
function AskRow({ icon, ask, ready, send }) {
|
|
10246
|
-
return /* @__PURE__ */
|
|
10247
|
-
/* @__PURE__ */
|
|
10248
|
-
/* @__PURE__ */
|
|
10249
|
-
/* @__PURE__ */
|
|
10250
|
-
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
|
|
10251
10638
|
] }),
|
|
10252
10639
|
send
|
|
10253
10640
|
] });
|
|
10254
10641
|
}
|
|
10255
10642
|
function RoundSend({ label, display, disabled, onClick }) {
|
|
10256
|
-
return /* @__PURE__ */
|
|
10643
|
+
return /* @__PURE__ */ jsx104("button", { type: "button", className: "ss-w-tool-go", "aria-label": `${label}: ${display}`, disabled, onClick, children: /* @__PURE__ */ jsx104(SendIcon, {}) });
|
|
10257
10644
|
}
|
|
10258
10645
|
var BIG_COMBO = { total: 50, legs: 6 };
|
|
10259
10646
|
function SetNumbersTool({ grid, strings, streaming, onSend, onClose }) {
|
|
@@ -10262,15 +10649,15 @@ function SetNumbersTool({ grid, strings, streaming, onSend, onClose }) {
|
|
|
10262
10649
|
const totals = comboTotals(grid);
|
|
10263
10650
|
const legChoices = comboLegChoices(grid);
|
|
10264
10651
|
const count = FIXED_SINGLES_COUNT;
|
|
10265
|
-
const [maxPrice, setMaxPrice] =
|
|
10266
|
-
const [minPrice, setMinPrice] =
|
|
10267
|
-
const [start] =
|
|
10268
|
-
const [total, setTotal] =
|
|
10269
|
-
const [legs, setLegs] =
|
|
10270
|
-
const [bigStart] =
|
|
10271
|
-
const [bigTotal, setBigTotal] =
|
|
10272
|
-
const [bigLegs, setBigLegs] =
|
|
10273
|
-
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("");
|
|
10274
10661
|
const maxCell = findSingles(grid.singles, maxPrice, count);
|
|
10275
10662
|
const minCell = findSingles(grid.singlesFrom, minPrice, count);
|
|
10276
10663
|
const comboCell = findCombo(grid, total, legs);
|
|
@@ -10314,95 +10701,95 @@ function SetNumbersTool({ grid, strings, streaming, onSend, onClose }) {
|
|
|
10314
10701
|
const totalChoices = totals.map((v) => ({ value: v, text: v.toFixed(1), available: legChoices.some((n) => !!findCombo(grid, v, n)) }));
|
|
10315
10702
|
const legChoicesFor = (t) => legChoices.map((n) => ({ value: n, text: String(n), available: !!findCombo(grid, t, n) }));
|
|
10316
10703
|
const markets = grid.markets ?? [];
|
|
10317
|
-
const [marketIdx, setMarketIdx] =
|
|
10704
|
+
const [marketIdx, setMarketIdx] = useState52(0);
|
|
10318
10705
|
const marketCell = markets[marketIdx] ?? null;
|
|
10319
10706
|
const marketLabels = markets.map((c) => strings.marketShort(c.marketDeveloperName, c.marketLabel, c.selectionLabel ?? null));
|
|
10320
10707
|
const singlesReady = (cell) => cell ? strings.readyCount(cell.picks.length) : strings.unavailable;
|
|
10321
10708
|
const comboReady = (cell) => cell ? strings.readyAt(cell.combo.total) : strings.unavailable;
|
|
10322
|
-
return /* @__PURE__ */
|
|
10323
|
-
/* @__PURE__ */
|
|
10709
|
+
return /* @__PURE__ */ jsxs88(PresetToolModal, { title: strings.setNumbers, closeLabel: strings.close, onClose, children: [
|
|
10710
|
+
/* @__PURE__ */ jsx104(
|
|
10324
10711
|
AskRow,
|
|
10325
10712
|
{
|
|
10326
10713
|
icon: "\u{1F3AF}",
|
|
10327
10714
|
ask: fillTemplate(strings.maxPriceRow, {
|
|
10328
10715
|
count: String(count),
|
|
10329
|
-
price: /* @__PURE__ */
|
|
10716
|
+
price: /* @__PURE__ */ jsx104(NumberSelect, { current: maxPrice.toFixed(2), choices: maxChoices, label: strings.maxPriceName, notToday: strings.notToday, onChoose: chooseMax })
|
|
10330
10717
|
}),
|
|
10331
10718
|
ready: singlesReady(maxCell),
|
|
10332
|
-
send: /* @__PURE__ */
|
|
10719
|
+
send: /* @__PURE__ */ jsx104(RoundSend, { label: strings.send, display: strings.maxPriceDisplay(count, maxPrice), disabled: !maxCell || streaming, onClick: () => {
|
|
10333
10720
|
if (maxCell) onSend(maxPriceAsk(maxCell, strings));
|
|
10334
10721
|
} })
|
|
10335
10722
|
}
|
|
10336
10723
|
),
|
|
10337
|
-
/* @__PURE__ */
|
|
10724
|
+
/* @__PURE__ */ jsx104(
|
|
10338
10725
|
AskRow,
|
|
10339
10726
|
{
|
|
10340
10727
|
icon: "\u{1F4C8}",
|
|
10341
10728
|
ask: fillTemplate(strings.minPriceRow, {
|
|
10342
10729
|
count: String(count),
|
|
10343
|
-
price: /* @__PURE__ */
|
|
10730
|
+
price: /* @__PURE__ */ jsx104(NumberSelect, { current: minPrice.toFixed(2), choices: minChoices, label: strings.minPriceName, notToday: strings.notToday, onChoose: chooseMin })
|
|
10344
10731
|
}),
|
|
10345
10732
|
ready: singlesReady(minCell),
|
|
10346
|
-
send: /* @__PURE__ */
|
|
10733
|
+
send: /* @__PURE__ */ jsx104(RoundSend, { label: strings.send, display: strings.minPriceDisplay(count, minPrice), disabled: !minCell || streaming, onClick: () => {
|
|
10347
10734
|
if (minCell) onSend(minPriceAsk(minCell, strings));
|
|
10348
10735
|
} })
|
|
10349
10736
|
}
|
|
10350
10737
|
),
|
|
10351
|
-
/* @__PURE__ */
|
|
10738
|
+
/* @__PURE__ */ jsx104(
|
|
10352
10739
|
AskRow,
|
|
10353
10740
|
{
|
|
10354
10741
|
icon: "\u2728",
|
|
10355
10742
|
ask: fillTemplate(strings.comboRow, {
|
|
10356
|
-
legs: /* @__PURE__ */
|
|
10357
|
-
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 })
|
|
10358
10745
|
}),
|
|
10359
10746
|
ready: comboReady(comboCell),
|
|
10360
|
-
send: /* @__PURE__ */
|
|
10747
|
+
send: /* @__PURE__ */ jsx104(RoundSend, { label: strings.send, display: strings.comboDisplay(legs, total), disabled: !comboCell || streaming, onClick: () => {
|
|
10361
10748
|
if (comboCell) onSend(comboAsk(comboCell, strings));
|
|
10362
10749
|
} })
|
|
10363
10750
|
}
|
|
10364
10751
|
),
|
|
10365
|
-
/* @__PURE__ */
|
|
10752
|
+
/* @__PURE__ */ jsx104(
|
|
10366
10753
|
AskRow,
|
|
10367
10754
|
{
|
|
10368
10755
|
icon: "\u{1F3C6}",
|
|
10369
10756
|
ask: fillTemplate(strings.bigComboRow, {
|
|
10370
|
-
legs: /* @__PURE__ */
|
|
10371
|
-
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 })
|
|
10372
10759
|
}),
|
|
10373
10760
|
ready: comboReady(bigCell),
|
|
10374
|
-
send: /* @__PURE__ */
|
|
10761
|
+
send: /* @__PURE__ */ jsx104(RoundSend, { label: strings.send, display: strings.comboDisplay(bigLegs, bigTotal), disabled: !bigCell || streaming, onClick: () => {
|
|
10375
10762
|
if (bigCell) onSend(comboAsk(bigCell, strings));
|
|
10376
10763
|
} })
|
|
10377
10764
|
}
|
|
10378
10765
|
),
|
|
10379
|
-
markets.length > 0 && /* @__PURE__ */
|
|
10766
|
+
markets.length > 0 && /* @__PURE__ */ jsx104(
|
|
10380
10767
|
AskRow,
|
|
10381
10768
|
{
|
|
10382
10769
|
icon: "\u26BD",
|
|
10383
10770
|
ask: fillTemplate(strings.marketRow, {
|
|
10384
|
-
market: /* @__PURE__ */
|
|
10771
|
+
market: /* @__PURE__ */ jsx104(ChoiceSelect, { currentIdx: marketIdx, sizeLabels: marketLabels, optionLabels: marketLabels, label: strings.marketName, onChoose: chooseMarket })
|
|
10385
10772
|
}),
|
|
10386
10773
|
ready: marketCell ? strings.readyCount(marketCell.count) : null,
|
|
10387
|
-
send: /* @__PURE__ */
|
|
10774
|
+
send: /* @__PURE__ */ jsx104(RoundSend, { label: strings.send, display: marketCell ? marketDisplay(marketCell, strings) : "", disabled: !marketCell || streaming, onClick: () => {
|
|
10388
10775
|
if (marketCell) onSend(marketAsk(marketCell, strings));
|
|
10389
10776
|
} })
|
|
10390
10777
|
}
|
|
10391
10778
|
),
|
|
10392
|
-
/* @__PURE__ */
|
|
10779
|
+
/* @__PURE__ */ jsx104("p", { className: "ss-w-vh", "aria-live": "polite", children: announcement })
|
|
10393
10780
|
] });
|
|
10394
10781
|
}
|
|
10395
10782
|
function BuildComboTool({ grid, strings, streaming, formatKickoff, initialTotal, initialLegs, onSend, onClose }) {
|
|
10396
10783
|
const totals = comboTotals(grid);
|
|
10397
10784
|
const legChoices = comboLegChoices(grid);
|
|
10398
|
-
const [start] =
|
|
10399
|
-
const [total, setTotal] =
|
|
10400
|
-
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(() => {
|
|
10401
10788
|
if (initialTotal === void 0) return initialLegs !== void 0 ? clampLegs(legChoices, initialLegs) : start.legs;
|
|
10402
10789
|
const from = initialLegs !== void 0 ? clampLegs(legChoices, initialLegs) : startValue(legChoices, START.comboLegs);
|
|
10403
10790
|
return legsForTotal(grid, nearest(totals, initialTotal), from);
|
|
10404
10791
|
});
|
|
10405
|
-
const [announcement, setAnnouncement] =
|
|
10792
|
+
const [announcement, setAnnouncement] = useState52("");
|
|
10406
10793
|
const cell = findCombo(grid, total, legs);
|
|
10407
10794
|
const minLegs = legChoices[0] ?? legs;
|
|
10408
10795
|
const maxLegs = legChoices[legChoices.length - 1] ?? legs;
|
|
@@ -10413,29 +10800,29 @@ function BuildComboTool({ grid, strings, streaming, formatKickoff, initialTotal,
|
|
|
10413
10800
|
const d = strings.comboDisplay(nextLegs, nextTotal);
|
|
10414
10801
|
setAnnouncement(findCombo(grid, nextTotal, nextLegs) ? d : `${d}. ${strings.unavailable}`);
|
|
10415
10802
|
};
|
|
10416
|
-
const footer = /* @__PURE__ */
|
|
10803
|
+
const footer = /* @__PURE__ */ jsx104(SendButton, { label: strings.send, display, disabled: !cell || streaming, onClick: () => {
|
|
10417
10804
|
if (cell) onSend(comboAsk(cell, strings));
|
|
10418
10805
|
} });
|
|
10419
|
-
return /* @__PURE__ */
|
|
10420
|
-
/* @__PURE__ */
|
|
10421
|
-
/* @__PURE__ */
|
|
10422
|
-
/* @__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)) })
|
|
10423
10810
|
] }),
|
|
10424
|
-
/* @__PURE__ */
|
|
10425
|
-
/* @__PURE__ */
|
|
10426
|
-
/* @__PURE__ */
|
|
10427
|
-
/* @__PURE__ */
|
|
10428
|
-
/* @__PURE__ */
|
|
10429
|
-
/* @__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: "+" })
|
|
10430
10817
|
] })
|
|
10431
10818
|
] }),
|
|
10432
|
-
cell ? /* @__PURE__ */
|
|
10433
|
-
/* @__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 })
|
|
10434
10821
|
] });
|
|
10435
10822
|
}
|
|
10436
10823
|
|
|
10437
10824
|
// src/usePresetDial.ts
|
|
10438
|
-
import { useCallback as useCallback21, useEffect as useEffect32, useRef as useRef29, useState as
|
|
10825
|
+
import { useCallback as useCallback21, useEffect as useEffect32, useRef as useRef29, useState as useState53 } from "react";
|
|
10439
10826
|
function sendInFlight(messages, isStreaming) {
|
|
10440
10827
|
const last = messages[messages.length - 1];
|
|
10441
10828
|
return isStreaming && !!last && last.role === "assistant" && !last.done && !last.isGreeting;
|
|
@@ -10449,7 +10836,7 @@ function lastUserId(messages) {
|
|
|
10449
10836
|
}
|
|
10450
10837
|
var SCROLL_KEYS = /* @__PURE__ */ new Set(["ArrowUp", "ArrowDown", "PageUp", "PageDown", "Home", "End", " "]);
|
|
10451
10838
|
function usePresetDial({ layerRef, dialRef, dialButtonRef, messages, isStreaming, activeTab }) {
|
|
10452
|
-
const [expanded, setExpanded] =
|
|
10839
|
+
const [expanded, setExpanded] = useState53(() => !sendInFlight(messages, isStreaming));
|
|
10453
10840
|
const fold = useCallback21(() => setExpanded(false), []);
|
|
10454
10841
|
const toggle = useCallback21(() => setExpanded((e) => !e), []);
|
|
10455
10842
|
const currentUserId = lastUserId(messages);
|
|
@@ -10532,10 +10919,10 @@ function markToolSeen() {
|
|
|
10532
10919
|
}
|
|
10533
10920
|
|
|
10534
10921
|
// src/components/ChatPanel.tsx
|
|
10535
|
-
import { Fragment as Fragment25, jsx as
|
|
10922
|
+
import { Fragment as Fragment25, jsx as jsx105, jsxs as jsxs89 } from "react/jsx-runtime";
|
|
10536
10923
|
var FULLSCREEN_QUERY = "(max-width: 639px)";
|
|
10537
10924
|
function useIsModal() {
|
|
10538
|
-
const [modal, setModal] =
|
|
10925
|
+
const [modal, setModal] = useState54(false);
|
|
10539
10926
|
useEffect33(() => {
|
|
10540
10927
|
if (typeof window === "undefined" || typeof window.matchMedia !== "function") return;
|
|
10541
10928
|
const mql = window.matchMedia(FULLSCREEN_QUERY);
|
|
@@ -10550,8 +10937,8 @@ var HIDDEN_LAYER_STYLE = { position: "absolute", inset: 0, visibility: "hidden",
|
|
|
10550
10937
|
var SQUAD_LAYER_STYLE = { display: "flex", flexDirection: "column", flex: 1, minHeight: 0 };
|
|
10551
10938
|
function ChatPanel({ controller, ui, slip, onDashboardTap, monitor, discovery, gamesResult, leaderboardResult, clubFixturesResult, clubStandingsResult, clubSquadResult, clubSquadStatsResult, clubPlayerDetailResult, loggedIn, conversation, presetGrid }) {
|
|
10552
10939
|
const { state, close, stop, send, reset } = controller;
|
|
10553
|
-
const [squadView, setSquadView] =
|
|
10554
|
-
const [selectedPlayerId, setSelectedPlayerId] =
|
|
10940
|
+
const [squadView, setSquadView] = useState54("roster");
|
|
10941
|
+
const [selectedPlayerId, setSelectedPlayerId] = useState54(null);
|
|
10555
10942
|
const clearPlayerDetail = clubPlayerDetailResult?.clear;
|
|
10556
10943
|
const fetchPlayerDetail = clubPlayerDetailResult?.fetch;
|
|
10557
10944
|
const squadLayerRef = useRef30(null);
|
|
@@ -10605,8 +10992,8 @@ function ChatPanel({ controller, ui, slip, onDashboardTap, monitor, discovery, g
|
|
|
10605
10992
|
const limitRef = useRef30(null);
|
|
10606
10993
|
const typedSendRef = useRef30(false);
|
|
10607
10994
|
const focusAfterCloseRef = useRef30(null);
|
|
10608
|
-
const [tool, setTool] =
|
|
10609
|
-
const [toolSeen, setToolSeen] =
|
|
10995
|
+
const [tool, setTool] = useState54(null);
|
|
10996
|
+
const [toolSeen, setToolSeen] = useState54(readToolSeen);
|
|
10610
10997
|
const dial = usePresetDial({
|
|
10611
10998
|
layerRef,
|
|
10612
10999
|
dialRef,
|
|
@@ -10663,8 +11050,8 @@ function ChatPanel({ controller, ui, slip, onDashboardTap, monitor, discovery, g
|
|
|
10663
11050
|
focusAfterCloseRef.current = "composer";
|
|
10664
11051
|
setTool(null);
|
|
10665
11052
|
}, [tool, onChatTab, presetGrid]);
|
|
10666
|
-
return /* @__PURE__ */
|
|
10667
|
-
/* @__PURE__ */
|
|
11053
|
+
return /* @__PURE__ */ jsxs89("div", { className: "ss-w-panel", role: "dialog", "aria-modal": isModal, "aria-label": ui.chatDialogLabel, children: [
|
|
11054
|
+
/* @__PURE__ */ jsx105(
|
|
10668
11055
|
ChatHeader,
|
|
10669
11056
|
{
|
|
10670
11057
|
onClose: close,
|
|
@@ -10677,7 +11064,7 @@ function ChatPanel({ controller, ui, slip, onDashboardTap, monitor, discovery, g
|
|
|
10677
11064
|
moreOptionsLabel: ui.moreOptions
|
|
10678
11065
|
}
|
|
10679
11066
|
),
|
|
10680
|
-
monitor && /* @__PURE__ */
|
|
11067
|
+
monitor && /* @__PURE__ */ jsx105(
|
|
10681
11068
|
TabBar,
|
|
10682
11069
|
{
|
|
10683
11070
|
monitor,
|
|
@@ -10690,9 +11077,9 @@ function ChatPanel({ controller, ui, slip, onDashboardTap, monitor, discovery, g
|
|
|
10690
11077
|
clubEnabled: clubFixturesResult?.enabled ?? false
|
|
10691
11078
|
}
|
|
10692
11079
|
),
|
|
10693
|
-
/* @__PURE__ */
|
|
10694
|
-
/* @__PURE__ */
|
|
10695
|
-
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(
|
|
10696
11083
|
PresetSpeedDial,
|
|
10697
11084
|
{
|
|
10698
11085
|
expanded: dial.expanded,
|
|
@@ -10704,21 +11091,21 @@ function ChatPanel({ controller, ui, slip, onDashboardTap, monitor, discovery, g
|
|
|
10704
11091
|
buttonRef: dialButtonRef
|
|
10705
11092
|
}
|
|
10706
11093
|
) : null,
|
|
10707
|
-
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
|
|
10708
11095
|
] }),
|
|
10709
|
-
monitor && discovery && monitor.activeTab === "today" && /* @__PURE__ */
|
|
10710
|
-
monitor && monitor.activeTab === "following" && /* @__PURE__ */
|
|
10711
|
-
monitor && monitor.activeTab === "odds" && /* @__PURE__ */
|
|
10712
|
-
monitor && monitor.activeTab === "fixtures" && /* @__PURE__ */
|
|
10713
|
-
monitor && monitor.activeTab === "standings" && /* @__PURE__ */
|
|
10714
|
-
monitor && monitor.activeTab === "squad" && /* @__PURE__ */
|
|
10715
|
-
/* @__PURE__ */
|
|
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(
|
|
10716
11103
|
"div",
|
|
10717
11104
|
{
|
|
10718
11105
|
ref: squadLayerRef,
|
|
10719
11106
|
style: selectedPlayerId === null ? SQUAD_LAYER_STYLE : HIDDEN_LAYER_STYLE,
|
|
10720
11107
|
"aria-hidden": selectedPlayerId !== null ? true : void 0,
|
|
10721
|
-
children: /* @__PURE__ */
|
|
11108
|
+
children: /* @__PURE__ */ jsx105(
|
|
10722
11109
|
Squad,
|
|
10723
11110
|
{
|
|
10724
11111
|
squad: clubSquadResult?.data ?? null,
|
|
@@ -10728,14 +11115,17 @@ function ChatPanel({ controller, ui, slip, onDashboardTap, monitor, discovery, g
|
|
|
10728
11115
|
onToggleView: () => setSquadView((v) => v === "roster" ? "stats" : "roster"),
|
|
10729
11116
|
stats: clubSquadStatsResult?.data ?? null,
|
|
10730
11117
|
statsLoading: clubSquadStatsResult?.loading ?? false,
|
|
11118
|
+
seasonName: clubSquadStatsResult?.seasonName ?? null,
|
|
11119
|
+
competitionName: clubSquadStatsResult?.competitionName ?? null,
|
|
11120
|
+
matchesPlayed: clubSquadStatsResult?.matchesPlayed ?? null,
|
|
10731
11121
|
onSelectPlayer: selectPlayer
|
|
10732
11122
|
}
|
|
10733
11123
|
)
|
|
10734
11124
|
}
|
|
10735
11125
|
),
|
|
10736
|
-
selectedPlayerId !== null && /* @__PURE__ */
|
|
11126
|
+
selectedPlayerId !== null && /* @__PURE__ */ jsx105(PlayerDetail, { detail: clubPlayerDetailResult?.data ?? null, loading: clubPlayerDetailResult?.loading ?? false, ui, seasonName: clubSquadStatsResult?.seasonName ?? null, onClose: closePlayer })
|
|
10737
11127
|
] }),
|
|
10738
|
-
monitor && monitor.activeTab === "games" && gamesResult && /* @__PURE__ */
|
|
11128
|
+
monitor && monitor.activeTab === "games" && gamesResult && /* @__PURE__ */ jsx105(
|
|
10739
11129
|
GamesPanel,
|
|
10740
11130
|
{
|
|
10741
11131
|
loggedIn: !!loggedIn,
|
|
@@ -10750,9 +11140,9 @@ function ChatPanel({ controller, ui, slip, onDashboardTap, monitor, discovery, g
|
|
|
10750
11140
|
}
|
|
10751
11141
|
}
|
|
10752
11142
|
),
|
|
10753
|
-
(!monitor || monitor.activeTab !== "games") && /* @__PURE__ */
|
|
10754
|
-
/* @__PURE__ */
|
|
10755
|
-
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(
|
|
10756
11146
|
ChatInput,
|
|
10757
11147
|
{
|
|
10758
11148
|
ref: inputRef,
|
|
@@ -10771,9 +11161,9 @@ function ChatPanel({ controller, ui, slip, onDashboardTap, monitor, discovery, g
|
|
|
10771
11161
|
}
|
|
10772
11162
|
|
|
10773
11163
|
// src/components/HostEventsProvider.tsx
|
|
10774
|
-
import { jsx as
|
|
11164
|
+
import { jsx as jsx106 } from "react/jsx-runtime";
|
|
10775
11165
|
function HostEventsProvider({ value, children }) {
|
|
10776
|
-
return /* @__PURE__ */
|
|
11166
|
+
return /* @__PURE__ */ jsx106(SlipStateContext.Provider, { value: value.slipState, children });
|
|
10777
11167
|
}
|
|
10778
11168
|
|
|
10779
11169
|
// src/styles/css.generated.ts
|
|
@@ -10784,7 +11174,7 @@ var WIDGET_CSS = `.ss-w-root { all: revert; }
|
|
|
10784
11174
|
--ss-w-cta: #f5a623; --ss-w-cta-ink: #1b1300;
|
|
10785
11175
|
--ss-w-ink: #14181d; --ss-w-faint: #6b7580; --ss-w-line: #e4e8ec;
|
|
10786
11176
|
--ss-w-panel: #ffffff; --ss-w-bubble: #f3f5f7; --ss-w-nav: #0e1622;
|
|
10787
|
-
--ss-w-pos: #1aa563; --ss-w-neg: #e0524b;
|
|
11177
|
+
--ss-w-pos: #1aa563; --ss-w-neg: #e0524b; --ss-w-warn: #c07a00;
|
|
10788
11178
|
--ss-w-home: #3a63a8; --ss-w-away: #c8102e; --ss-w-track: #e9edf1;
|
|
10789
11179
|
--ss-w-correct: #1f9d55; --ss-w-wrong: #b9bbc2;
|
|
10790
11180
|
--ss-w-radius: 16px; --ss-w-offset-x: 20px; --ss-w-offset-y: 20px;
|
|
@@ -10796,7 +11186,7 @@ var WIDGET_CSS = `.ss-w-root { all: revert; }
|
|
|
10796
11186
|
--ss-w-accent: #37c891; --ss-w-cta: #ffb638; --ss-w-cta-ink: #1b1300;
|
|
10797
11187
|
--ss-w-ink: #e8edf2; --ss-w-faint: #8b95a1;
|
|
10798
11188
|
--ss-w-line: #2a3441; --ss-w-panel: #141b24; --ss-w-bubble: #1e2732; --ss-w-nav: #0a0f16;
|
|
10799
|
-
--ss-w-pos: #37c891; --ss-w-neg: #f0655d;
|
|
11189
|
+
--ss-w-pos: #37c891; --ss-w-neg: #f0655d; --ss-w-warn: #e0a030;
|
|
10800
11190
|
--ss-w-home: #5b83c8; --ss-w-away: #e8384f; --ss-w-track: #232d3a;
|
|
10801
11191
|
--ss-w-correct: #37c86b; --ss-w-wrong: #3a3a41;
|
|
10802
11192
|
}
|
|
@@ -10805,7 +11195,7 @@ var WIDGET_CSS = `.ss-w-root { all: revert; }
|
|
|
10805
11195
|
--ss-w-accent: #37c891; --ss-w-cta: #ffb638; --ss-w-cta-ink: #1b1300;
|
|
10806
11196
|
--ss-w-ink: #e8edf2; --ss-w-faint: #8b95a1;
|
|
10807
11197
|
--ss-w-line: #2a3441; --ss-w-panel: #141b24; --ss-w-bubble: #1e2732; --ss-w-nav: #0a0f16;
|
|
10808
|
-
--ss-w-pos: #37c891; --ss-w-neg: #f0655d;
|
|
11198
|
+
--ss-w-pos: #37c891; --ss-w-neg: #f0655d; --ss-w-warn: #e0a030;
|
|
10809
11199
|
--ss-w-home: #5b83c8; --ss-w-away: #e8384f; --ss-w-track: #232d3a;
|
|
10810
11200
|
--ss-w-correct: #37c86b; --ss-w-wrong: #3a3a41;
|
|
10811
11201
|
}
|
|
@@ -11936,7 +12326,7 @@ var WIDGET_CSS = `.ss-w-root { all: revert; }
|
|
|
11936
12326
|
.ss-w-sq-name { font-size: 13px; font-weight: 600; color: var(--ss-w-ink); }
|
|
11937
12327
|
.ss-w-sq-name { flex: 1; min-width: 0; }
|
|
11938
12328
|
.ss-w-sq-name-1 { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
|
|
11939
|
-
.ss-w-sq-seg { display: flex;
|
|
12329
|
+
.ss-w-sq-seg { display: flex; gap: 2px; padding: 2px; border-radius: var(--ss-w-radius); background: var(--ss-w-track); }
|
|
11940
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; }
|
|
11941
12331
|
.ss-w-sq-seg-btn[aria-pressed="true"] { background: var(--ss-w-panel); color: var(--ss-w-ink); }
|
|
11942
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; }
|
|
@@ -11944,15 +12334,95 @@ var WIDGET_CSS = `.ss-w-root { all: revert; }
|
|
|
11944
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); }
|
|
11945
12335
|
.ss-w-sq-head { border-bottom: 0; padding-bottom: 0; }
|
|
11946
12336
|
.ss-w-sq-head .ss-w-sq-col { font-size: 10px; font-weight: 700; color: var(--ss-w-faint); }
|
|
11947
|
-
.ss-w-
|
|
11948
|
-
.ss-w-
|
|
11949
|
-
.ss-w-
|
|
11950
|
-
.ss-w-
|
|
11951
|
-
.ss-w-
|
|
11952
|
-
.ss-w-
|
|
11953
|
-
.ss-w-
|
|
11954
|
-
.ss-w-
|
|
11955
|
-
.ss-w-
|
|
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; }
|
|
11956
12426
|
.ss-w-rec-list { margin: 0; padding: 0; list-style: none; }
|
|
11957
12427
|
.ss-w-rec-value { flex: none; font-size: 13px; font-weight: 700; font-variant-numeric: tabular-nums; color: var(--ss-w-ink); }
|
|
11958
12428
|
.ss-w-rec-since { font-size: 12px; color: var(--ss-w-faint); }
|
|
@@ -12559,7 +13029,7 @@ var WIDGET_CSS = `.ss-w-root { all: revert; }
|
|
|
12559
13029
|
`;
|
|
12560
13030
|
|
|
12561
13031
|
// src/StatsWidget.tsx
|
|
12562
|
-
import { jsx as
|
|
13032
|
+
import { jsx as jsx107 } from "react/jsx-runtime";
|
|
12563
13033
|
function buildClient(props) {
|
|
12564
13034
|
try {
|
|
12565
13035
|
if ("client" in props && props.client) {
|
|
@@ -12600,7 +13070,7 @@ function StatsWidget(props) {
|
|
|
12600
13070
|
}, []);
|
|
12601
13071
|
const convStorageKey = `ss-w-conv:${cfg?.operatorId ?? ""}:${cfg?.userContext?.operatorUserId ?? "anon"}`;
|
|
12602
13072
|
const controller = useChatStream(built?.conversation ?? emptyConversation(), ui.starters, built ? ui.greetingMessage : void 0, convStorageKey);
|
|
12603
|
-
const [hasToday, setHasToday] =
|
|
13073
|
+
const [hasToday, setHasToday] = useState55(false);
|
|
12604
13074
|
const liveCardWatches = useMemo6(() => {
|
|
12605
13075
|
const seen = /* @__PURE__ */ new Set();
|
|
12606
13076
|
const out = [];
|
|
@@ -12784,7 +13254,7 @@ function StatsWidget(props) {
|
|
|
12784
13254
|
}, [built, ui.injectStyles]);
|
|
12785
13255
|
if (!built) return null;
|
|
12786
13256
|
const attrs = themeAttrs(ui);
|
|
12787
|
-
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(
|
|
12788
13258
|
ChatPanel,
|
|
12789
13259
|
{
|
|
12790
13260
|
controller,
|
|
@@ -12804,7 +13274,7 @@ function StatsWidget(props) {
|
|
|
12804
13274
|
conversation: built?.conversation ?? null,
|
|
12805
13275
|
presetGrid
|
|
12806
13276
|
}
|
|
12807
|
-
) : /* @__PURE__ */
|
|
13277
|
+
) : /* @__PURE__ */ jsx107(
|
|
12808
13278
|
ChatFab,
|
|
12809
13279
|
{
|
|
12810
13280
|
label: ui.launcherLabel,
|