@sensiblestats/widget-react 0.79.0 → 0.81.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 +23 -0
- package/dist/index.cjs +1501 -1033
- 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 +1494 -1026
- package/dist/index.js.map +1 -1
- package/dist/styles.css +58 -8
- package/package.json +2 -2
package/dist/index.cjs
CHANGED
|
@@ -37,8 +37,8 @@ __export(index_exports, {
|
|
|
37
37
|
module.exports = __toCommonJS(index_exports);
|
|
38
38
|
|
|
39
39
|
// src/StatsWidget.tsx
|
|
40
|
-
var
|
|
41
|
-
var
|
|
40
|
+
var import_react60 = require("react");
|
|
41
|
+
var import_widget_sdk6 = require("@sensiblestats/widget-sdk");
|
|
42
42
|
|
|
43
43
|
// src/kickoff.ts
|
|
44
44
|
function formatBettingKickoff(kickoffUtc, ui, locale, now = /* @__PURE__ */ new Date()) {
|
|
@@ -68,6 +68,9 @@ var STRINGS = {
|
|
|
68
68
|
dismissGreeting: "Dismiss",
|
|
69
69
|
somethingWentWrong: "Something went wrong.",
|
|
70
70
|
retry: "Retry",
|
|
71
|
+
limitDailyCap: "You've asked all your questions for today. You can ask again tomorrow.",
|
|
72
|
+
limitQuotaExhausted: "The assistant can't take new questions right now. Please try again later.",
|
|
73
|
+
limitAssistantPaused: "The assistant isn't available right now. Please try again later.",
|
|
71
74
|
showLess: "Show less",
|
|
72
75
|
showMore: (n) => `Show ${n} more`,
|
|
73
76
|
allMarkets: (n) => `All markets (${n})`,
|
|
@@ -149,6 +152,19 @@ var STRINGS = {
|
|
|
149
152
|
accordionSuspended: "Suspended",
|
|
150
153
|
tabToday: "Today",
|
|
151
154
|
sectionLive: "Live",
|
|
155
|
+
yourLeagues: "Your leagues",
|
|
156
|
+
topLeagues: "Top leagues",
|
|
157
|
+
topLeaguesSub: "Popular today.",
|
|
158
|
+
allLeagues: "All leagues",
|
|
159
|
+
searchLeaguesPlaceholder: "Search leagues or teams",
|
|
160
|
+
noLeagueResults: "No league or team matches that search.",
|
|
161
|
+
starOnLabel: "Add to Your leagues",
|
|
162
|
+
starOffLabel: "Remove from Your leagues",
|
|
163
|
+
starredToast: "Added to Your leagues.",
|
|
164
|
+
unstarredToast: "Removed from Your leagues.",
|
|
165
|
+
leagueDetailPosition: (index, total) => `${index} of ${total}`,
|
|
166
|
+
prevLeagueLabel: "Previous league",
|
|
167
|
+
nextLeagueLabel: "Next league",
|
|
152
168
|
halfTime: "HT",
|
|
153
169
|
staleStates: "Live scores can't be updated \u2014 showing the last known state.",
|
|
154
170
|
tabGames: "Games",
|
|
@@ -417,6 +433,9 @@ var STRINGS = {
|
|
|
417
433
|
dismissGreeting: "Kapat",
|
|
418
434
|
somethingWentWrong: "Bir \u015Feyler ters gitti.",
|
|
419
435
|
retry: "Tekrar dene",
|
|
436
|
+
limitDailyCap: "Bug\xFCnl\xFCk sorular\u0131n\u0131 tamamlad\u0131n. Yar\u0131n yeniden sorabilirsin.",
|
|
437
|
+
limitQuotaExhausted: "Asistan \u015Fu an yeni soru alam\u0131yor. L\xFCtfen daha sonra tekrar dene.",
|
|
438
|
+
limitAssistantPaused: "Asistan \u015Fu an kullan\u0131lam\u0131yor. L\xFCtfen daha sonra tekrar dene.",
|
|
420
439
|
showLess: "Daha az g\xF6ster",
|
|
421
440
|
showMore: (n) => `${n} tane daha g\xF6ster`,
|
|
422
441
|
allMarkets: (n) => `T\xFCm bahisler (${n})`,
|
|
@@ -498,6 +517,19 @@ var STRINGS = {
|
|
|
498
517
|
accordionSuspended: "Ask\u0131da",
|
|
499
518
|
tabToday: "Bug\xFCn",
|
|
500
519
|
sectionLive: "Canl\u0131",
|
|
520
|
+
yourLeagues: "Liglerin",
|
|
521
|
+
topLeagues: "\xD6ne \xE7\u0131kan ligler",
|
|
522
|
+
topLeaguesSub: "Bug\xFCn pop\xFCler.",
|
|
523
|
+
allLeagues: "T\xFCm ligler",
|
|
524
|
+
searchLeaguesPlaceholder: "Lig veya tak\u0131m ara",
|
|
525
|
+
noLeagueResults: "Aramana uyan lig veya tak\u0131m yok.",
|
|
526
|
+
starOnLabel: "Liglerine ekle",
|
|
527
|
+
starOffLabel: "Liglerinden \xE7\u0131kar",
|
|
528
|
+
starredToast: "Liglerin b\xF6l\xFCm\xFCne eklendi.",
|
|
529
|
+
unstarredToast: "Liglerin b\xF6l\xFCm\xFCnden \xE7\u0131kar\u0131ld\u0131.",
|
|
530
|
+
leagueDetailPosition: (index, total) => `${index} / ${total}`,
|
|
531
|
+
prevLeagueLabel: "\xD6nceki lig",
|
|
532
|
+
nextLeagueLabel: "Sonraki lig",
|
|
501
533
|
halfTime: "\u0130Y",
|
|
502
534
|
staleStates: "Canl\u0131 skorlar g\xFCncellenemiyor \u2014 son bilinen durum g\xF6steriliyor.",
|
|
503
535
|
tabGames: "Oyunlar",
|
|
@@ -795,6 +827,9 @@ function normalizeUi(cfg) {
|
|
|
795
827
|
dismissGreeting: strings.dismissGreeting,
|
|
796
828
|
somethingWentWrong: strings.somethingWentWrong,
|
|
797
829
|
retry: strings.retry,
|
|
830
|
+
limitDailyCap: strings.limitDailyCap,
|
|
831
|
+
limitQuotaExhausted: strings.limitQuotaExhausted,
|
|
832
|
+
limitAssistantPaused: strings.limitAssistantPaused,
|
|
798
833
|
showLess: strings.showLess,
|
|
799
834
|
showMore: strings.showMore,
|
|
800
835
|
allMarkets: strings.allMarkets,
|
|
@@ -844,6 +879,19 @@ function normalizeUi(cfg) {
|
|
|
844
879
|
tabOdds: strings.tabOdds,
|
|
845
880
|
tabToday: strings.tabToday,
|
|
846
881
|
sectionLive: strings.sectionLive,
|
|
882
|
+
yourLeagues: strings.yourLeagues,
|
|
883
|
+
topLeagues: strings.topLeagues,
|
|
884
|
+
topLeaguesSub: strings.topLeaguesSub,
|
|
885
|
+
allLeagues: strings.allLeagues,
|
|
886
|
+
searchLeaguesPlaceholder: strings.searchLeaguesPlaceholder,
|
|
887
|
+
noLeagueResults: strings.noLeagueResults,
|
|
888
|
+
starOnLabel: strings.starOnLabel,
|
|
889
|
+
starOffLabel: strings.starOffLabel,
|
|
890
|
+
starredToast: strings.starredToast,
|
|
891
|
+
unstarredToast: strings.unstarredToast,
|
|
892
|
+
leagueDetailPosition: strings.leagueDetailPosition,
|
|
893
|
+
prevLeagueLabel: strings.prevLeagueLabel,
|
|
894
|
+
nextLeagueLabel: strings.nextLeagueLabel,
|
|
847
895
|
halfTime: strings.halfTime,
|
|
848
896
|
staleStates: strings.staleStates,
|
|
849
897
|
pinLabel: strings.pinLabel,
|
|
@@ -1738,10 +1786,55 @@ function themeAttrs(ui) {
|
|
|
1738
1786
|
|
|
1739
1787
|
// src/useChatStream.ts
|
|
1740
1788
|
var import_react3 = require("react");
|
|
1741
|
-
var
|
|
1789
|
+
var import_widget_sdk4 = require("@sensiblestats/widget-sdk");
|
|
1742
1790
|
|
|
1743
1791
|
// src/reducer.ts
|
|
1792
|
+
var import_widget_sdk3 = require("@sensiblestats/widget-sdk");
|
|
1793
|
+
|
|
1794
|
+
// src/limit.ts
|
|
1744
1795
|
var import_widget_sdk2 = require("@sensiblestats/widget-sdk");
|
|
1796
|
+
var LIMIT_TIMER_MAX_MS = 60 * 60 * 1e3;
|
|
1797
|
+
var ZONED = /(?:Z|[+-]\d{2}:?\d{2})$/i;
|
|
1798
|
+
function build(code, message, resetsAt, retryAfterSeconds) {
|
|
1799
|
+
return {
|
|
1800
|
+
code,
|
|
1801
|
+
paused: code === "assistant_paused",
|
|
1802
|
+
message: message?.trim() || null,
|
|
1803
|
+
resetsAt: resetsAt ?? null,
|
|
1804
|
+
retryAfterSeconds: typeof retryAfterSeconds === "number" && Number.isFinite(retryAfterSeconds) ? retryAfterSeconds : null
|
|
1805
|
+
};
|
|
1806
|
+
}
|
|
1807
|
+
function limitFromEvent(data) {
|
|
1808
|
+
return (0, import_widget_sdk2.isLimitCode)(data.code) ? build(data.code, data.message, data.resetsAt, data.retryAfterSeconds) : null;
|
|
1809
|
+
}
|
|
1810
|
+
function limitFromError(error) {
|
|
1811
|
+
return error instanceof import_widget_sdk2.LimitError ? build(error.limitCode, error.limitMessage, error.resetsAt, error.retryAfter) : null;
|
|
1812
|
+
}
|
|
1813
|
+
function isLimitNotice(data) {
|
|
1814
|
+
return data.terminal === false && (0, import_widget_sdk2.isLimitCode)(data.code);
|
|
1815
|
+
}
|
|
1816
|
+
function isPaused(limit) {
|
|
1817
|
+
return limit?.paused === true;
|
|
1818
|
+
}
|
|
1819
|
+
function limitText(limit, ui) {
|
|
1820
|
+
if (limit.message) return limit.message;
|
|
1821
|
+
switch (limit.code) {
|
|
1822
|
+
case "daily_cap":
|
|
1823
|
+
return ui.limitDailyCap;
|
|
1824
|
+
case "quota_exhausted":
|
|
1825
|
+
return ui.limitQuotaExhausted;
|
|
1826
|
+
case "assistant_paused":
|
|
1827
|
+
return ui.limitAssistantPaused;
|
|
1828
|
+
}
|
|
1829
|
+
}
|
|
1830
|
+
function limitDelayMs(limit, nowMs) {
|
|
1831
|
+
const retry = limit.retryAfterSeconds;
|
|
1832
|
+
if (retry != null && Number.isFinite(retry) && retry >= 0) return Math.min(retry * 1e3, LIMIT_TIMER_MAX_MS);
|
|
1833
|
+
const at = limit.resetsAt ? Date.parse(ZONED.test(limit.resetsAt) ? limit.resetsAt : `${limit.resetsAt}Z`) : Number.NaN;
|
|
1834
|
+
return Number.isNaN(at) ? null : Math.min(Math.max(at - nowMs, 0), LIMIT_TIMER_MAX_MS);
|
|
1835
|
+
}
|
|
1836
|
+
|
|
1837
|
+
// src/reducer.ts
|
|
1745
1838
|
var POPUP_MAX = 160;
|
|
1746
1839
|
function markAwaitingLiveUpdate(messages, held = []) {
|
|
1747
1840
|
if (!messages.some((m) => m.role === "assistant" && m.marketOdds.some((vm) => vm.live != null))) return messages;
|
|
@@ -1759,12 +1852,18 @@ function markAwaitingLiveUpdate(messages, held = []) {
|
|
|
1759
1852
|
});
|
|
1760
1853
|
}
|
|
1761
1854
|
function initialState(starters) {
|
|
1762
|
-
return { isOpen: false, messages: [], isStreaming: false, status: null, actionsLoading: false, starters, configuredStarters: starters, error: null, lastUserInput: null, lastDisplayText: null, popupText: null, conversationId: null };
|
|
1855
|
+
return { isOpen: false, messages: [], isStreaming: false, status: null, actionsLoading: false, starters, configuredStarters: starters, error: null, lastUserInput: null, lastDisplayText: null, popupText: null, conversationId: null, limit: null };
|
|
1763
1856
|
}
|
|
1764
1857
|
function activeTurn(state) {
|
|
1765
1858
|
const last = state.messages[state.messages.length - 1];
|
|
1766
1859
|
return last && last.role === "assistant" && !last.done ? last : null;
|
|
1767
1860
|
}
|
|
1861
|
+
function settleRefused(state, limit) {
|
|
1862
|
+
return { ...state, limit, error: null, isStreaming: false, status: null, actionsLoading: false, messages: mapActive(state, (t) => ({ ...t, done: true })) };
|
|
1863
|
+
}
|
|
1864
|
+
function isPlainInput(input) {
|
|
1865
|
+
return !!input && !input.actionRef && !input.actionId && !input.grounding && !input.preset;
|
|
1866
|
+
}
|
|
1768
1867
|
function mapActive(state, fn) {
|
|
1769
1868
|
const last = state.messages[state.messages.length - 1];
|
|
1770
1869
|
if (!last || last.role !== "assistant" || last.done) return state.messages;
|
|
@@ -1804,6 +1903,7 @@ function applyEvent(state, event) {
|
|
|
1804
1903
|
case "turn_complete": {
|
|
1805
1904
|
const active = activeTurn(state);
|
|
1806
1905
|
const greetingLine = event.data.clubFanDashboard?.greeting?.trim() || (active?.text.trim() ?? "");
|
|
1906
|
+
const clearsLimit = !active?.isGreeting && isPlainInput(state.lastUserInput);
|
|
1807
1907
|
const popupText = active?.isGreeting && !state.isOpen && greetingLine ? greetingLine.slice(0, POPUP_MAX) : state.popupText;
|
|
1808
1908
|
return {
|
|
1809
1909
|
...state,
|
|
@@ -1811,6 +1911,7 @@ function applyEvent(state, event) {
|
|
|
1811
1911
|
status: null,
|
|
1812
1912
|
actionsLoading: false,
|
|
1813
1913
|
popupText,
|
|
1914
|
+
limit: clearsLimit ? null : state.limit,
|
|
1814
1915
|
conversationId: event.data.conversationId ?? state.conversationId,
|
|
1815
1916
|
messages: mapActive(state, (t) => ({
|
|
1816
1917
|
...t,
|
|
@@ -1821,6 +1922,9 @@ function applyEvent(state, event) {
|
|
|
1821
1922
|
};
|
|
1822
1923
|
}
|
|
1823
1924
|
case "error": {
|
|
1925
|
+
const limit = limitFromEvent(event.data);
|
|
1926
|
+
if (limit && event.data.terminal === false) return { ...state, limit };
|
|
1927
|
+
if (limit) return settleRefused(state, limit);
|
|
1824
1928
|
const suppress = activeTurn(state)?.isGreeting === true;
|
|
1825
1929
|
return { ...state, error: suppress ? state.error : event.data, isStreaming: false, status: null, actionsLoading: false, messages: mapActive(state, (t) => ({ ...t, done: true })) };
|
|
1826
1930
|
}
|
|
@@ -1845,7 +1949,7 @@ function reducer(state, action) {
|
|
|
1845
1949
|
case "DISMISS_POPUP":
|
|
1846
1950
|
return { ...state, popupText: null };
|
|
1847
1951
|
case "RESET":
|
|
1848
|
-
return { ...initialState(state.configuredStarters), isOpen: state.isOpen };
|
|
1952
|
+
return { ...initialState(state.configuredStarters), isOpen: state.isOpen, limit: state.limit };
|
|
1849
1953
|
case "RESTORE":
|
|
1850
1954
|
return {
|
|
1851
1955
|
...state,
|
|
@@ -1859,8 +1963,13 @@ function reducer(state, action) {
|
|
|
1859
1963
|
};
|
|
1860
1964
|
case "EVENT":
|
|
1861
1965
|
return applyEvent(state, action.event);
|
|
1862
|
-
case "STREAM_ERROR":
|
|
1966
|
+
case "STREAM_ERROR": {
|
|
1967
|
+
const limit = limitFromError(action.error);
|
|
1968
|
+
if (limit) return settleRefused(state, limit);
|
|
1863
1969
|
return { ...state, error: action.error, isStreaming: false, status: null, actionsLoading: false, messages: mapActive(state, (t) => ({ ...t, done: true })) };
|
|
1970
|
+
}
|
|
1971
|
+
case "LIMIT_EXPIRED":
|
|
1972
|
+
return { ...state, limit: null };
|
|
1864
1973
|
case "STOP":
|
|
1865
1974
|
return { ...state, isStreaming: false, status: null, actionsLoading: false, messages: mapActive(state, (t) => ({ ...t, done: true })) };
|
|
1866
1975
|
case "UPDATE_LIVE_CARD": {
|
|
@@ -2033,7 +2142,7 @@ function clearConversation(storageKey) {
|
|
|
2033
2142
|
}
|
|
2034
2143
|
|
|
2035
2144
|
// src/presets.ts
|
|
2036
|
-
var CLIENT_CAPABILITIES = ["price_presets", "price_presets_open"];
|
|
2145
|
+
var CLIENT_CAPABILITIES = ["price_presets", "price_presets_open", "limit_notice"];
|
|
2037
2146
|
var PRICE_TILE_PREFIX = "goal-preset-";
|
|
2038
2147
|
function isPriceTile(tile) {
|
|
2039
2148
|
const id = tile.signal?.entityId;
|
|
@@ -2131,11 +2240,11 @@ function useChatStream(conversation, starterTexts, greetingMessage, storageKey)
|
|
|
2131
2240
|
try {
|
|
2132
2241
|
for await (const event of handle) {
|
|
2133
2242
|
dispatch({ kind: "EVENT", event });
|
|
2134
|
-
if (event.type === "turn_complete" || event.type === "error") clearFallbackTimer();
|
|
2243
|
+
if (event.type === "turn_complete" || event.type === "error" && !isLimitNotice(event.data)) clearFallbackTimer();
|
|
2135
2244
|
}
|
|
2136
2245
|
} catch (err) {
|
|
2137
2246
|
if (handleRef.current === handle) clearFallbackTimer();
|
|
2138
|
-
if (err instanceof
|
|
2247
|
+
if (err instanceof import_widget_sdk4.WidgetSdkError) onError(err);
|
|
2139
2248
|
else if (err?.name === "AbortError") {
|
|
2140
2249
|
} else throw err;
|
|
2141
2250
|
} finally {
|
|
@@ -2144,6 +2253,7 @@ function useChatStream(conversation, starterTexts, greetingMessage, storageKey)
|
|
|
2144
2253
|
})();
|
|
2145
2254
|
}, [clearFallbackTimer]);
|
|
2146
2255
|
const run = (0, import_react3.useCallback)((input, displayText) => {
|
|
2256
|
+
if (isPaused(stateRef.current.limit)) return;
|
|
2147
2257
|
handleRef.current?.cancel();
|
|
2148
2258
|
clearFallbackTimer();
|
|
2149
2259
|
dispatch({ kind: "USER_SENT", input, userId: nextId(), assistantId: nextId(), displayText });
|
|
@@ -2151,7 +2261,7 @@ function useChatStream(conversation, starterTexts, greetingMessage, storageKey)
|
|
|
2151
2261
|
handleRef.current = handle;
|
|
2152
2262
|
armFallbackTimer(() => {
|
|
2153
2263
|
dispatch({ kind: "STOP" });
|
|
2154
|
-
dispatch({ kind: "STREAM_ERROR", error: new
|
|
2264
|
+
dispatch({ kind: "STREAM_ERROR", error: new import_widget_sdk4.WidgetSdkError("No response received in time", "timeout") });
|
|
2155
2265
|
});
|
|
2156
2266
|
consume(handle, (err) => dispatch({ kind: "STREAM_ERROR", error: err }));
|
|
2157
2267
|
}, [conversation, consume, clearFallbackTimer, armFallbackTimer]);
|
|
@@ -2191,6 +2301,13 @@ function useChatStream(conversation, starterTexts, greetingMessage, storageKey)
|
|
|
2191
2301
|
greetedRef.current = true;
|
|
2192
2302
|
fireGreeting();
|
|
2193
2303
|
}, [fireGreeting]);
|
|
2304
|
+
(0, import_react3.useEffect)(() => {
|
|
2305
|
+
if (!state.limit) return;
|
|
2306
|
+
const delay = limitDelayMs(state.limit, Date.now());
|
|
2307
|
+
if (delay === null) return;
|
|
2308
|
+
const timer = setTimeout(() => dispatch({ kind: "LIMIT_EXPIRED" }), delay);
|
|
2309
|
+
return () => clearTimeout(timer);
|
|
2310
|
+
}, [state.limit]);
|
|
2194
2311
|
(0, import_react3.useEffect)(() => {
|
|
2195
2312
|
if (boot.stale && storageKey) clearConversation(storageKey);
|
|
2196
2313
|
}, []);
|
|
@@ -2676,14 +2793,14 @@ var import_react6 = require("react");
|
|
|
2676
2793
|
|
|
2677
2794
|
// src/scheduleCache.ts
|
|
2678
2795
|
var PREFIX = "ss-w-schedule:";
|
|
2679
|
-
var SCHEMA_VERSION =
|
|
2796
|
+
var SCHEMA_VERSION = 2;
|
|
2680
2797
|
var TTL_MS2 = 6 * 36e5;
|
|
2681
|
-
function scheduleCacheKey(operatorId, localDate) {
|
|
2682
|
-
return `${PREFIX}${operatorId}:${localDate}`;
|
|
2798
|
+
function scheduleCacheKey(operatorId, encodedUserKey2, localDate) {
|
|
2799
|
+
return `${PREFIX}${operatorId}:${encodedUserKey2}:${localDate}`;
|
|
2683
2800
|
}
|
|
2684
|
-
function read(operatorId, localDate) {
|
|
2801
|
+
function read(operatorId, encodedUserKey2, localDate) {
|
|
2685
2802
|
try {
|
|
2686
|
-
const raw = localStorage.getItem(scheduleCacheKey(operatorId, localDate));
|
|
2803
|
+
const raw = localStorage.getItem(scheduleCacheKey(operatorId, encodedUserKey2, localDate));
|
|
2687
2804
|
if (!raw) return null;
|
|
2688
2805
|
const entry = JSON.parse(raw);
|
|
2689
2806
|
if (entry.v !== SCHEMA_VERSION || !entry.payload) return null;
|
|
@@ -2692,13 +2809,13 @@ function read(operatorId, localDate) {
|
|
|
2692
2809
|
return null;
|
|
2693
2810
|
}
|
|
2694
2811
|
}
|
|
2695
|
-
function readSchedule(operatorId, localDate, nowMs) {
|
|
2696
|
-
const entry = read(operatorId, localDate);
|
|
2812
|
+
function readSchedule(operatorId, encodedUserKey2, localDate, nowMs) {
|
|
2813
|
+
const entry = read(operatorId, encodedUserKey2, localDate);
|
|
2697
2814
|
if (!entry) return null;
|
|
2698
2815
|
return nowMs - entry.at > TTL_MS2 ? null : entry.payload;
|
|
2699
2816
|
}
|
|
2700
|
-
function readScheduleIgnoringTtl(operatorId, localDate) {
|
|
2701
|
-
return read(operatorId, localDate)?.payload ?? null;
|
|
2817
|
+
function readScheduleIgnoringTtl(operatorId, encodedUserKey2, localDate) {
|
|
2818
|
+
return read(operatorId, encodedUserKey2, localDate)?.payload ?? null;
|
|
2702
2819
|
}
|
|
2703
2820
|
function skeletonOnly(payload) {
|
|
2704
2821
|
return {
|
|
@@ -2706,9 +2823,13 @@ function skeletonOnly(payload) {
|
|
|
2706
2823
|
groups: payload.groups.map((g) => ({
|
|
2707
2824
|
competitionId: g.competitionId,
|
|
2708
2825
|
competitionName: g.competitionName,
|
|
2826
|
+
competitionCountry: g.competitionCountry ?? null,
|
|
2709
2827
|
competitionImagePath: g.competitionImagePath ?? null,
|
|
2710
2828
|
rank: g.rank,
|
|
2711
2829
|
expandedByDefault: g.expandedByDefault,
|
|
2830
|
+
isStarred: g.isStarred,
|
|
2831
|
+
isLearned: g.isLearned,
|
|
2832
|
+
learnedRank: g.learnedRank,
|
|
2712
2833
|
matches: g.matches.map((m) => ({
|
|
2713
2834
|
matchId: m.matchId,
|
|
2714
2835
|
homeTeamName: m.homeTeamName,
|
|
@@ -2720,9 +2841,9 @@ function skeletonOnly(payload) {
|
|
|
2720
2841
|
}))
|
|
2721
2842
|
};
|
|
2722
2843
|
}
|
|
2723
|
-
function writeSchedule(operatorId, localDate, payload, nowMs) {
|
|
2724
|
-
const keep = scheduleCacheKey(operatorId, localDate);
|
|
2725
|
-
const mine = `${PREFIX}${operatorId}:`;
|
|
2844
|
+
function writeSchedule(operatorId, encodedUserKey2, localDate, payload, nowMs) {
|
|
2845
|
+
const keep = scheduleCacheKey(operatorId, encodedUserKey2, localDate);
|
|
2846
|
+
const mine = `${PREFIX}${operatorId}:${encodedUserKey2}:`;
|
|
2726
2847
|
try {
|
|
2727
2848
|
for (let i = localStorage.length - 1; i >= 0; i--) {
|
|
2728
2849
|
const key = localStorage.key(i);
|
|
@@ -2733,6 +2854,12 @@ function writeSchedule(operatorId, localDate, payload, nowMs) {
|
|
|
2733
2854
|
} catch {
|
|
2734
2855
|
}
|
|
2735
2856
|
}
|
|
2857
|
+
function patchScheduleStar(operatorId, encodedUserKey2, localDate, competitionId, star) {
|
|
2858
|
+
const entry = read(operatorId, encodedUserKey2, localDate);
|
|
2859
|
+
if (!entry) return;
|
|
2860
|
+
const groups = entry.payload.groups.map((g) => g.competitionId === competitionId ? { ...g, ...star } : g);
|
|
2861
|
+
writeSchedule(operatorId, encodedUserKey2, localDate, { ...entry.payload, groups }, entry.at);
|
|
2862
|
+
}
|
|
2736
2863
|
|
|
2737
2864
|
// src/dueSet.ts
|
|
2738
2865
|
var TERMINAL_PHASES = /* @__PURE__ */ new Set(["fullTime", "postponed"]);
|
|
@@ -2753,6 +2880,9 @@ function dueMatchIds(groups, states, nowMs) {
|
|
|
2753
2880
|
var POLL_MS = 6e4;
|
|
2754
2881
|
var ROLLOVER_CHECK_MS = 6e4;
|
|
2755
2882
|
var STALE_AFTER_FAILURES = 2;
|
|
2883
|
+
function encodedUserKey(operatorUserId, anonymousUserId) {
|
|
2884
|
+
return encodeURIComponent(operatorUserId || anonymousUserId || "none");
|
|
2885
|
+
}
|
|
2756
2886
|
function localDateOf(now) {
|
|
2757
2887
|
const y = now.getFullYear();
|
|
2758
2888
|
const m = `${now.getMonth() + 1}`.padStart(2, "0");
|
|
@@ -2763,15 +2893,12 @@ function useMatchDiscovery(opts) {
|
|
|
2763
2893
|
const [groups, setGroups] = (0, import_react6.useState)([]);
|
|
2764
2894
|
const [states, setStates] = (0, import_react6.useState)({});
|
|
2765
2895
|
const [failures, setFailures] = (0, import_react6.useState)(0);
|
|
2766
|
-
const [expanded, setExpanded] = (0, import_react6.useState)({});
|
|
2767
|
-
const [touched, setTouched] = (0, import_react6.useState)({});
|
|
2768
2896
|
const groupsRef = (0, import_react6.useRef)(groups);
|
|
2769
2897
|
groupsRef.current = groups;
|
|
2770
2898
|
const statesRef = (0, import_react6.useRef)(states);
|
|
2771
2899
|
statesRef.current = states;
|
|
2772
2900
|
const getStatesRef = (0, import_react6.useRef)(opts.getStates);
|
|
2773
2901
|
getStatesRef.current = opts.getStates;
|
|
2774
|
-
const pinnedKey = opts.pinnedMatchIds.join(",");
|
|
2775
2902
|
const [localDate, setLocalDate] = (0, import_react6.useState)(() => localDateOf(/* @__PURE__ */ new Date()));
|
|
2776
2903
|
(0, import_react6.useEffect)(() => {
|
|
2777
2904
|
const id = setInterval(() => {
|
|
@@ -2783,7 +2910,8 @@ function useMatchDiscovery(opts) {
|
|
|
2783
2910
|
(0, import_react6.useEffect)(() => {
|
|
2784
2911
|
let cancelled = false;
|
|
2785
2912
|
const utcOffsetMinutes = -(/* @__PURE__ */ new Date()).getTimezoneOffset();
|
|
2786
|
-
const
|
|
2913
|
+
const key = encodedUserKey(opts.operatorUserId, opts.anonymousUserId);
|
|
2914
|
+
const cached = readSchedule(opts.operatorId, key, localDate, Date.now());
|
|
2787
2915
|
if (cached) {
|
|
2788
2916
|
if (!cancelled) setGroups(cached.groups);
|
|
2789
2917
|
return () => {
|
|
@@ -2794,28 +2922,17 @@ function useMatchDiscovery(opts) {
|
|
|
2794
2922
|
try {
|
|
2795
2923
|
const payload = await opts.getSchedule(localDate, utcOffsetMinutes);
|
|
2796
2924
|
if (cancelled || !payload) return;
|
|
2797
|
-
writeSchedule(opts.operatorId, localDate, payload, Date.now());
|
|
2925
|
+
writeSchedule(opts.operatorId, key, localDate, payload, Date.now());
|
|
2798
2926
|
setGroups(payload.groups);
|
|
2799
2927
|
} catch {
|
|
2800
|
-
const fallback = readScheduleIgnoringTtl(opts.operatorId, localDate);
|
|
2928
|
+
const fallback = readScheduleIgnoringTtl(opts.operatorId, key, localDate);
|
|
2801
2929
|
if (!cancelled && fallback) setGroups(fallback.groups);
|
|
2802
2930
|
}
|
|
2803
2931
|
})();
|
|
2804
2932
|
return () => {
|
|
2805
2933
|
cancelled = true;
|
|
2806
2934
|
};
|
|
2807
|
-
}, [opts.operatorId, localDate]);
|
|
2808
|
-
(0, import_react6.useEffect)(() => {
|
|
2809
|
-
setExpanded((prev) => {
|
|
2810
|
-
const next = {};
|
|
2811
|
-
for (const group of groups) {
|
|
2812
|
-
const hasPin = group.matches.some((m) => opts.pinnedMatchIds.includes(m.matchId));
|
|
2813
|
-
const seeded = group.expandedByDefault || hasPin;
|
|
2814
|
-
next[group.competitionId] = touched[group.competitionId] ? prev[group.competitionId] ?? seeded : seeded;
|
|
2815
|
-
}
|
|
2816
|
-
return next;
|
|
2817
|
-
});
|
|
2818
|
-
}, [groups, pinnedKey, touched]);
|
|
2935
|
+
}, [opts.operatorId, opts.operatorUserId, opts.anonymousUserId, localDate]);
|
|
2819
2936
|
const tick = (0, import_react6.useCallback)(async () => {
|
|
2820
2937
|
const ids = dueMatchIds(groupsRef.current, statesRef.current, Date.now());
|
|
2821
2938
|
if (ids.length === 0) return;
|
|
@@ -2845,11 +2962,20 @@ function useMatchDiscovery(opts) {
|
|
|
2845
2962
|
() => stale ? 0 : Object.values(states).filter((s) => s.phase === "live").length,
|
|
2846
2963
|
[states, stale]
|
|
2847
2964
|
);
|
|
2848
|
-
const
|
|
2849
|
-
|
|
2850
|
-
|
|
2851
|
-
|
|
2852
|
-
|
|
2965
|
+
const starLeague = (0, import_react6.useCallback)(async (competitionId, starred) => {
|
|
2966
|
+
let result;
|
|
2967
|
+
try {
|
|
2968
|
+
result = await opts.postLeagueStar(competitionId, starred);
|
|
2969
|
+
} catch {
|
|
2970
|
+
return false;
|
|
2971
|
+
}
|
|
2972
|
+
if (!result) return false;
|
|
2973
|
+
const patch = { isStarred: result.starred, isLearned: false, learnedRank: null };
|
|
2974
|
+
setGroups((prev) => prev.map((g) => g.competitionId === competitionId ? { ...g, ...patch } : g));
|
|
2975
|
+
patchScheduleStar(opts.operatorId, encodedUserKey(opts.operatorUserId, opts.anonymousUserId), localDate, competitionId, patch);
|
|
2976
|
+
return true;
|
|
2977
|
+
}, [opts.postLeagueStar, opts.operatorId, opts.operatorUserId, opts.anonymousUserId, localDate]);
|
|
2978
|
+
return { groups, states, liveCount, stale, starLeague, _tick: tick };
|
|
2853
2979
|
}
|
|
2854
2980
|
|
|
2855
2981
|
// src/useGames.ts
|
|
@@ -3323,7 +3449,7 @@ function ChatFab({ label, greeting, popupText, logoUrl, onOpen, onDismissPopup,
|
|
|
3323
3449
|
}
|
|
3324
3450
|
|
|
3325
3451
|
// src/components/ChatPanel.tsx
|
|
3326
|
-
var
|
|
3452
|
+
var import_react59 = require("react");
|
|
3327
3453
|
|
|
3328
3454
|
// src/components/ChatHeader.tsx
|
|
3329
3455
|
var import_react15 = require("react");
|
|
@@ -3533,7 +3659,7 @@ var import_react20 = require("react");
|
|
|
3533
3659
|
|
|
3534
3660
|
// src/slipAdd.ts
|
|
3535
3661
|
var import_react18 = require("react");
|
|
3536
|
-
var
|
|
3662
|
+
var import_widget_sdk5 = require("@sensiblestats/widget-sdk");
|
|
3537
3663
|
|
|
3538
3664
|
// src/slipStateContext.ts
|
|
3539
3665
|
var import_react17 = require("react");
|
|
@@ -3562,7 +3688,7 @@ function useSlipAdd(slip, ui) {
|
|
|
3562
3688
|
}
|
|
3563
3689
|
try {
|
|
3564
3690
|
const raw = await withTimeout(Promise.resolve(handler(selection)));
|
|
3565
|
-
if (raw != null && !(0,
|
|
3691
|
+
if (raw != null && !(0, import_widget_sdk5.isAddToSlipResult)(raw)) throw new Error("malformed add-to-slip result");
|
|
3566
3692
|
const result = raw ?? void 0;
|
|
3567
3693
|
if (marketDeveloperName !== void 0) {
|
|
3568
3694
|
log?.log({
|
|
@@ -5381,7 +5507,7 @@ function MessageList({ controller, ui, slip, onDashboardTap, monitor }) {
|
|
|
5381
5507
|
ChatMessage,
|
|
5382
5508
|
{
|
|
5383
5509
|
message: m,
|
|
5384
|
-
disabled: state.isStreaming,
|
|
5510
|
+
disabled: state.isStreaming || isPaused(state.limit),
|
|
5385
5511
|
onAct: (a) => send(a.message, { actionId: a.actionId, actionRef: a.actionRef, displayText: a.label }),
|
|
5386
5512
|
onTap: (tile, index) => {
|
|
5387
5513
|
const displayText = tileDisplayText(tile);
|
|
@@ -5401,7 +5527,7 @@ function MessageList({ controller, ui, slip, onDashboardTap, monitor }) {
|
|
|
5401
5527
|
/* @__PURE__ */ (0, import_jsx_runtime48.jsx)("span", { children: "message" in state.error ? state.error.message : ui.somethingWentWrong }),
|
|
5402
5528
|
/* @__PURE__ */ (0, import_jsx_runtime48.jsx)("button", { type: "button", className: "ss-w-retry", onClick: () => controller.retry(), children: ui.retry })
|
|
5403
5529
|
] }) : null,
|
|
5404
|
-
!hasUserMessage && !hasDashboard ? /* @__PURE__ */ (0, import_jsx_runtime48.jsx)(IntentChips, { chips: state.starters, onPick: (t) => send(t) }) : null,
|
|
5530
|
+
!hasUserMessage && !hasDashboard && !isPaused(state.limit) ? /* @__PURE__ */ (0, import_jsx_runtime48.jsx)(IntentChips, { chips: state.starters, onPick: (t) => send(t) }) : null,
|
|
5405
5531
|
/* @__PURE__ */ (0, import_jsx_runtime48.jsx)("div", { ref: endRef, className: "ss-w-turn-spacer", "aria-hidden": "true" })
|
|
5406
5532
|
]
|
|
5407
5533
|
}
|
|
@@ -5831,16 +5957,135 @@ function OddsPanel({ monitor, ui, slip }) {
|
|
|
5831
5957
|
}) });
|
|
5832
5958
|
}
|
|
5833
5959
|
|
|
5834
|
-
// src/components/
|
|
5960
|
+
// src/components/TodayPanel.tsx
|
|
5961
|
+
var import_react40 = require("react");
|
|
5962
|
+
|
|
5963
|
+
// src/placement.ts
|
|
5964
|
+
function placeLeagues(visible, pinnedMatchIds) {
|
|
5965
|
+
const candidates = [];
|
|
5966
|
+
const candidateIds = /* @__PURE__ */ new Set();
|
|
5967
|
+
for (const g of visible) {
|
|
5968
|
+
if (g.isStarred) {
|
|
5969
|
+
candidates.push(g);
|
|
5970
|
+
candidateIds.add(g.competitionId);
|
|
5971
|
+
}
|
|
5972
|
+
}
|
|
5973
|
+
let budget = 4;
|
|
5974
|
+
const pinned = visible.find(
|
|
5975
|
+
(g) => !candidateIds.has(g.competitionId) && g.matches.some((m) => pinnedMatchIds.includes(m.matchId))
|
|
5976
|
+
) ?? null;
|
|
5977
|
+
if (pinned && budget > 0) {
|
|
5978
|
+
candidates.push(pinned);
|
|
5979
|
+
candidateIds.add(pinned.competitionId);
|
|
5980
|
+
budget -= 1;
|
|
5981
|
+
}
|
|
5982
|
+
const learned = visible.filter((g) => g.isLearned && !candidateIds.has(g.competitionId)).sort((a, b) => (a.learnedRank ?? Number.MAX_SAFE_INTEGER) - (b.learnedRank ?? Number.MAX_SAFE_INTEGER));
|
|
5983
|
+
for (const g of learned) {
|
|
5984
|
+
if (budget <= 0) break;
|
|
5985
|
+
candidates.push(g);
|
|
5986
|
+
candidateIds.add(g.competitionId);
|
|
5987
|
+
budget -= 1;
|
|
5988
|
+
}
|
|
5989
|
+
const personal = candidates.length > 0;
|
|
5990
|
+
const pool = personal ? candidates : visible.slice(0, 4);
|
|
5991
|
+
const poolIds = personal ? candidateIds : new Set(pool.map((g) => g.competitionId));
|
|
5992
|
+
const others = visible.filter((g) => !poolIds.has(g.competitionId));
|
|
5993
|
+
return { personal, candidates: pool, others, order: [...pool, ...others], pinnedCompetitionId: pinned?.competitionId ?? null };
|
|
5994
|
+
}
|
|
5995
|
+
function starClickable(group, pinnedCompetitionId) {
|
|
5996
|
+
return group.isStarred || group.competitionId !== pinnedCompetitionId;
|
|
5997
|
+
}
|
|
5998
|
+
|
|
5999
|
+
// src/search.ts
|
|
6000
|
+
function foldSearchText(s) {
|
|
6001
|
+
return s.replace(/İ/g, "I").replace(/ı/g, "i").normalize("NFD").replace(/[̀-ͯ]/g, "").toLowerCase();
|
|
6002
|
+
}
|
|
6003
|
+
function matchesQuery(group, query) {
|
|
6004
|
+
const q = foldSearchText(query.trim());
|
|
6005
|
+
if (!q) return true;
|
|
6006
|
+
if (foldSearchText(group.competitionName).includes(q)) return true;
|
|
6007
|
+
if (group.competitionCountry && foldSearchText(group.competitionCountry).includes(q)) return true;
|
|
6008
|
+
return group.matches.some(
|
|
6009
|
+
(m) => foldSearchText(m.homeTeamName).includes(q) || foldSearchText(m.awayTeamName).includes(q)
|
|
6010
|
+
);
|
|
6011
|
+
}
|
|
6012
|
+
|
|
6013
|
+
// src/useStarTap.ts
|
|
6014
|
+
var import_react38 = require("react");
|
|
6015
|
+
function useStarTap(starLeague) {
|
|
6016
|
+
const [pendingId, setPendingId] = (0, import_react38.useState)(null);
|
|
6017
|
+
const pendingRef = (0, import_react38.useRef)(null);
|
|
6018
|
+
const tap = (0, import_react38.useCallback)(async (competitionId, next) => {
|
|
6019
|
+
if (pendingRef.current !== null) return false;
|
|
6020
|
+
pendingRef.current = competitionId;
|
|
6021
|
+
setPendingId(competitionId);
|
|
6022
|
+
try {
|
|
6023
|
+
return await starLeague(competitionId, next);
|
|
6024
|
+
} finally {
|
|
6025
|
+
pendingRef.current = null;
|
|
6026
|
+
setPendingId(null);
|
|
6027
|
+
}
|
|
6028
|
+
}, [starLeague]);
|
|
6029
|
+
return { pendingId, tap };
|
|
6030
|
+
}
|
|
6031
|
+
|
|
6032
|
+
// src/components/LeagueTile.tsx
|
|
5835
6033
|
var import_jsx_runtime55 = require("react/jsx-runtime");
|
|
6034
|
+
var STAR_PATH = "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";
|
|
6035
|
+
function LeagueTile({ group, starClickable: starClickable2, disambiguate, onOpen, starTap, ui }) {
|
|
6036
|
+
const onStarClick = () => {
|
|
6037
|
+
void starTap.tap(group.competitionId, !group.isStarred);
|
|
6038
|
+
};
|
|
6039
|
+
return /* @__PURE__ */ (0, import_jsx_runtime55.jsxs)("div", { className: "ss-w-today-tile", children: [
|
|
6040
|
+
/* @__PURE__ */ (0, import_jsx_runtime55.jsxs)("button", { type: "button", className: "ss-w-today-tile-body", onClick: onOpen, children: [
|
|
6041
|
+
/* @__PURE__ */ (0, import_jsx_runtime55.jsx)(Crest2, { url: group.competitionImagePath ?? void 0, name: group.competitionName, kind: "comp" }),
|
|
6042
|
+
/* @__PURE__ */ (0, import_jsx_runtime55.jsxs)("span", { className: "ss-w-today-tile-name", children: [
|
|
6043
|
+
group.competitionName,
|
|
6044
|
+
disambiguate && group.competitionCountry ? /* @__PURE__ */ (0, import_jsx_runtime55.jsxs)("span", { className: "ss-w-today-tile-country", children: [
|
|
6045
|
+
" (",
|
|
6046
|
+
group.competitionCountry,
|
|
6047
|
+
")"
|
|
6048
|
+
] }) : null
|
|
6049
|
+
] })
|
|
6050
|
+
] }),
|
|
6051
|
+
/* @__PURE__ */ (0, import_jsx_runtime55.jsx)(
|
|
6052
|
+
"button",
|
|
6053
|
+
{
|
|
6054
|
+
type: "button",
|
|
6055
|
+
className: "ss-w-today-tile-star",
|
|
6056
|
+
"aria-pressed": group.isStarred,
|
|
6057
|
+
"aria-label": group.isStarred ? ui.starOffLabel : ui.starOnLabel,
|
|
6058
|
+
disabled: !starClickable2 || starTap.pendingId !== null,
|
|
6059
|
+
onClick: onStarClick,
|
|
6060
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime55.jsx)("svg", { viewBox: "0 0 24 24", "aria-hidden": "true", children: /* @__PURE__ */ (0, import_jsx_runtime55.jsx)(
|
|
6061
|
+
"path",
|
|
6062
|
+
{
|
|
6063
|
+
d: STAR_PATH,
|
|
6064
|
+
fill: group.isStarred ? "currentColor" : "none",
|
|
6065
|
+
stroke: group.isStarred ? "none" : "currentColor",
|
|
6066
|
+
strokeWidth: 2,
|
|
6067
|
+
strokeLinejoin: "round",
|
|
6068
|
+
strokeLinecap: "round"
|
|
6069
|
+
}
|
|
6070
|
+
) })
|
|
6071
|
+
}
|
|
6072
|
+
)
|
|
6073
|
+
] });
|
|
6074
|
+
}
|
|
6075
|
+
|
|
6076
|
+
// src/components/LeagueDetail.tsx
|
|
6077
|
+
var import_react39 = require("react");
|
|
6078
|
+
|
|
6079
|
+
// src/components/FixtureRow.tsx
|
|
6080
|
+
var import_jsx_runtime56 = require("react/jsx-runtime");
|
|
5836
6081
|
function kickoffLabel(kickoffUnix) {
|
|
5837
6082
|
const d = new Date(kickoffUnix * 1e3);
|
|
5838
6083
|
return `${`${d.getHours()}`.padStart(2, "0")}:${`${d.getMinutes()}`.padStart(2, "0")}`;
|
|
5839
6084
|
}
|
|
5840
6085
|
function Side({ name, crest, away = false }) {
|
|
5841
|
-
return /* @__PURE__ */ (0,
|
|
5842
|
-
crest ? /* @__PURE__ */ (0,
|
|
5843
|
-
/* @__PURE__ */ (0,
|
|
6086
|
+
return /* @__PURE__ */ (0, import_jsx_runtime56.jsxs)("span", { className: away ? "ss-w-drow-side ss-w-drow-side--away" : "ss-w-drow-side", children: [
|
|
6087
|
+
crest ? /* @__PURE__ */ (0, import_jsx_runtime56.jsx)("img", { className: "ss-w-drow-crest", src: crest, alt: "" }) : null,
|
|
6088
|
+
/* @__PURE__ */ (0, import_jsx_runtime56.jsx)("span", { className: "ss-w-drow-nm", children: name })
|
|
5844
6089
|
] });
|
|
5845
6090
|
}
|
|
5846
6091
|
function FixtureRow({ match, state, stale, ui, monitor }) {
|
|
@@ -5849,100 +6094,310 @@ function FixtureRow({ match, state, stale, ui, monitor }) {
|
|
|
5849
6094
|
const score = hasScore ? `${state.homeScore}\u2013${state.awayScore}` : void 0;
|
|
5850
6095
|
const ticked = state?.phase === "live" ? state.minuteLabel ?? null : null;
|
|
5851
6096
|
const when = state?.isHalfTime && !stale ? ui.halfTime : isLive ? ticked ?? "\u2014" : state?.phase === "live" ? "\u2014" : kickoffLabel(match.kickoffUnix);
|
|
5852
|
-
return /* @__PURE__ */ (0,
|
|
5853
|
-
/* @__PURE__ */ (0,
|
|
5854
|
-
/* @__PURE__ */ (0,
|
|
5855
|
-
/* @__PURE__ */ (0,
|
|
5856
|
-
/* @__PURE__ */ (0,
|
|
5857
|
-
/* @__PURE__ */ (0,
|
|
6097
|
+
return /* @__PURE__ */ (0, import_jsx_runtime56.jsxs)("div", { className: isLive || state?.isHalfTime ? "ss-w-drow ss-w-drow--live" : "ss-w-drow", children: [
|
|
6098
|
+
/* @__PURE__ */ (0, import_jsx_runtime56.jsx)("span", { className: isLive || state?.isHalfTime ? "ss-w-drow-when ss-w-drow-when--live" : "ss-w-drow-when", children: when }),
|
|
6099
|
+
/* @__PURE__ */ (0, import_jsx_runtime56.jsxs)("span", { className: "ss-w-drow-fx", children: [
|
|
6100
|
+
/* @__PURE__ */ (0, import_jsx_runtime56.jsx)(Side, { name: match.homeTeamName, crest: match.homeTeamImagePath }),
|
|
6101
|
+
/* @__PURE__ */ (0, import_jsx_runtime56.jsx)("span", { className: hasScore ? "ss-w-drow-sc" : "ss-w-drow-sc ss-w-drow-sc--idle", children: score ?? "\u2013" }),
|
|
6102
|
+
/* @__PURE__ */ (0, import_jsx_runtime56.jsx)(Side, { name: match.awayTeamName, crest: match.awayTeamImagePath, away: true })
|
|
5858
6103
|
] }),
|
|
5859
|
-
/* @__PURE__ */ (0,
|
|
6104
|
+
/* @__PURE__ */ (0, import_jsx_runtime56.jsx)(PinToggle, { ui, monitor, pin: { kind: "match", matchId: match.matchId } })
|
|
5860
6105
|
] });
|
|
5861
6106
|
}
|
|
5862
6107
|
|
|
5863
|
-
// src/components/
|
|
5864
|
-
var
|
|
5865
|
-
|
|
6108
|
+
// src/components/LeagueDetail.tsx
|
|
6109
|
+
var import_jsx_runtime57 = require("react/jsx-runtime");
|
|
6110
|
+
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";
|
|
6111
|
+
function LeagueDetail({ group, position, states, stale, ui, monitor, starTap, onBack, onPrev, onNext }) {
|
|
6112
|
+
const [toast, setToast] = (0, import_react39.useState)(null);
|
|
6113
|
+
(0, import_react39.useEffect)(() => {
|
|
6114
|
+
setToast(null);
|
|
6115
|
+
}, [group.competitionId]);
|
|
6116
|
+
(0, import_react39.useEffect)(() => {
|
|
6117
|
+
if (toast === null) return;
|
|
6118
|
+
const id = setTimeout(() => setToast(null), 4e3);
|
|
6119
|
+
return () => clearTimeout(id);
|
|
6120
|
+
}, [toast]);
|
|
5866
6121
|
const own = group.matches.filter((m) => !isTreatedLive(states[m.matchId], stale));
|
|
5867
|
-
const
|
|
5868
|
-
|
|
5869
|
-
|
|
5870
|
-
|
|
5871
|
-
|
|
5872
|
-
|
|
5873
|
-
|
|
5874
|
-
|
|
5875
|
-
/* @__PURE__ */ (0,
|
|
5876
|
-
|
|
5877
|
-
|
|
5878
|
-
|
|
5879
|
-
|
|
5880
|
-
|
|
5881
|
-
|
|
5882
|
-
|
|
5883
|
-
|
|
6122
|
+
const onStarClick = () => {
|
|
6123
|
+
const next = !group.isStarred;
|
|
6124
|
+
void starTap.tap(group.competitionId, next).then((ok) => {
|
|
6125
|
+
if (ok) setToast(next ? ui.starredToast : ui.unstarredToast);
|
|
6126
|
+
});
|
|
6127
|
+
};
|
|
6128
|
+
return /* @__PURE__ */ (0, import_jsx_runtime57.jsxs)("div", { className: "ss-w-today-detail", children: [
|
|
6129
|
+
/* @__PURE__ */ (0, import_jsx_runtime57.jsxs)("div", { className: "ss-w-today-detail-head", children: [
|
|
6130
|
+
/* @__PURE__ */ (0, import_jsx_runtime57.jsx)("button", { type: "button", className: "ss-w-today-detail-back", "aria-label": ui.back, onClick: onBack, children: /* @__PURE__ */ (0, import_jsx_runtime57.jsx)(ChevronIcon, {}) }),
|
|
6131
|
+
/* @__PURE__ */ (0, import_jsx_runtime57.jsx)(Crest2, { url: group.competitionImagePath ?? void 0, name: group.competitionName, kind: "comp" }),
|
|
6132
|
+
/* @__PURE__ */ (0, import_jsx_runtime57.jsx)("span", { className: "ss-w-today-detail-name", children: group.competitionName }),
|
|
6133
|
+
/* @__PURE__ */ (0, import_jsx_runtime57.jsx)(
|
|
6134
|
+
"button",
|
|
6135
|
+
{
|
|
6136
|
+
type: "button",
|
|
6137
|
+
className: "ss-w-today-detail-star",
|
|
6138
|
+
"aria-pressed": group.isStarred,
|
|
6139
|
+
"aria-label": group.isStarred ? ui.starOffLabel : ui.starOnLabel,
|
|
6140
|
+
disabled: starTap.pendingId !== null,
|
|
6141
|
+
onClick: onStarClick,
|
|
6142
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime57.jsx)("svg", { viewBox: "0 0 24 24", "aria-hidden": "true", children: /* @__PURE__ */ (0, import_jsx_runtime57.jsx)(
|
|
6143
|
+
"path",
|
|
6144
|
+
{
|
|
6145
|
+
d: STAR_PATH2,
|
|
6146
|
+
fill: group.isStarred ? "currentColor" : "none",
|
|
6147
|
+
stroke: group.isStarred ? "none" : "currentColor",
|
|
6148
|
+
strokeWidth: 2,
|
|
6149
|
+
strokeLinejoin: "round",
|
|
6150
|
+
strokeLinecap: "round"
|
|
6151
|
+
}
|
|
6152
|
+
) })
|
|
6153
|
+
}
|
|
6154
|
+
)
|
|
6155
|
+
] }),
|
|
6156
|
+
/* @__PURE__ */ (0, import_jsx_runtime57.jsxs)("div", { className: "ss-w-today-detail-nav", children: [
|
|
6157
|
+
/* @__PURE__ */ (0, import_jsx_runtime57.jsx)(
|
|
6158
|
+
"button",
|
|
6159
|
+
{
|
|
6160
|
+
type: "button",
|
|
6161
|
+
className: "ss-w-today-detail-prev",
|
|
6162
|
+
"aria-label": ui.prevLeagueLabel,
|
|
6163
|
+
disabled: position.index <= 1,
|
|
6164
|
+
onClick: onPrev,
|
|
6165
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime57.jsx)(ChevronIcon, {})
|
|
6166
|
+
}
|
|
6167
|
+
),
|
|
6168
|
+
/* @__PURE__ */ (0, import_jsx_runtime57.jsx)("span", { className: "ss-w-today-detail-pos", children: ui.leagueDetailPosition(position.index, position.total) }),
|
|
6169
|
+
/* @__PURE__ */ (0, import_jsx_runtime57.jsx)(
|
|
6170
|
+
"button",
|
|
6171
|
+
{
|
|
6172
|
+
type: "button",
|
|
6173
|
+
className: "ss-w-today-detail-next",
|
|
6174
|
+
"aria-label": ui.nextLeagueLabel,
|
|
6175
|
+
disabled: position.index >= position.total,
|
|
6176
|
+
onClick: onNext,
|
|
6177
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime57.jsx)(ChevronIcon, {})
|
|
6178
|
+
}
|
|
6179
|
+
)
|
|
6180
|
+
] }),
|
|
6181
|
+
/* @__PURE__ */ (0, import_jsx_runtime57.jsxs)("div", { className: "ss-w-today-detail-body", children: [
|
|
6182
|
+
/* @__PURE__ */ (0, import_jsx_runtime57.jsx)("span", { className: "ss-w-today-detail-count", children: own.length }),
|
|
6183
|
+
own.map((m) => /* @__PURE__ */ (0, import_jsx_runtime57.jsx)(FixtureRow, { match: m, state: states[m.matchId], stale, ui, monitor }, m.matchId))
|
|
5884
6184
|
] }),
|
|
5885
|
-
|
|
6185
|
+
toast !== null && /* @__PURE__ */ (0, import_jsx_runtime57.jsx)("p", { className: "ss-w-today-toast", role: "status", "aria-live": "polite", children: toast })
|
|
6186
|
+
] });
|
|
6187
|
+
}
|
|
6188
|
+
|
|
6189
|
+
// src/components/games/ui/icons.tsx
|
|
6190
|
+
var import_jsx_runtime58 = require("react/jsx-runtime");
|
|
6191
|
+
var svg = (size, children, fill = false) => /* @__PURE__ */ (0, import_jsx_runtime58.jsx)(
|
|
6192
|
+
"svg",
|
|
6193
|
+
{
|
|
6194
|
+
width: size,
|
|
6195
|
+
height: size,
|
|
6196
|
+
viewBox: "0 0 24 24",
|
|
6197
|
+
fill: fill ? "currentColor" : "none",
|
|
6198
|
+
stroke: fill ? "none" : "currentColor",
|
|
6199
|
+
strokeWidth: 2.2,
|
|
6200
|
+
strokeLinecap: "round",
|
|
6201
|
+
strokeLinejoin: "round",
|
|
6202
|
+
"aria-hidden": "true",
|
|
6203
|
+
children
|
|
6204
|
+
}
|
|
6205
|
+
);
|
|
6206
|
+
var IconChevronLeft = ({ size = 20 }) => svg(size, /* @__PURE__ */ (0, import_jsx_runtime58.jsx)("path", { d: "M15 18l-6-6 6-6" }));
|
|
6207
|
+
var IconLock = ({ size = 14 }) => svg(size, [/* @__PURE__ */ (0, import_jsx_runtime58.jsx)("rect", { x: "5", y: "11", width: "14", height: "10", rx: "2" }, "a"), /* @__PURE__ */ (0, import_jsx_runtime58.jsx)("path", { d: "M8 11V7a4 4 0 0 1 8 0v4" }, "b")]);
|
|
6208
|
+
var IconCheck = ({ size = 14 }) => svg(size, /* @__PURE__ */ (0, import_jsx_runtime58.jsx)("path", { d: "M5 12l5 5 9-10" }));
|
|
6209
|
+
var IconClose = ({ size = 16 }) => svg(size, /* @__PURE__ */ (0, import_jsx_runtime58.jsx)("path", { d: "M6 6l12 12M18 6L6 18" }));
|
|
6210
|
+
var IconSearch = ({ size = 18 }) => svg(size, [/* @__PURE__ */ (0, import_jsx_runtime58.jsx)("circle", { cx: "11", cy: "11", r: "7" }, "a"), /* @__PURE__ */ (0, import_jsx_runtime58.jsx)("path", { d: "M20 20l-3.5-3.5" }, "b")]);
|
|
6211
|
+
var IconPlus = ({ size = 20 }) => svg(size, /* @__PURE__ */ (0, import_jsx_runtime58.jsx)("path", { d: "M12 5v14M5 12h14" }));
|
|
6212
|
+
var IconBulb = ({ size = 16 }) => svg(size, [/* @__PURE__ */ (0, import_jsx_runtime58.jsx)("path", { d: "M9 18h6M10 21h4" }, "a"), /* @__PURE__ */ (0, import_jsx_runtime58.jsx)("path", { d: "M12 3a6 6 0 0 0-3.5 10.9V16h7v-2.1A6 6 0 0 0 12 3z" }, "b")]);
|
|
6213
|
+
var IconArrowUp = ({ size = 12 }) => svg(size, /* @__PURE__ */ (0, import_jsx_runtime58.jsx)("path", { d: "M12 19V5M5 12l7-7 7 7" }));
|
|
6214
|
+
var IconArrowDown = ({ size = 12 }) => svg(size, /* @__PURE__ */ (0, import_jsx_runtime58.jsx)("path", { d: "M12 5v14M19 12l-7 7-7-7" }));
|
|
6215
|
+
var IconCalendar = ({ size = 18 }) => svg(size, [/* @__PURE__ */ (0, import_jsx_runtime58.jsx)("rect", { x: "4", y: "5", width: "16", height: "15", rx: "2" }, "a"), /* @__PURE__ */ (0, import_jsx_runtime58.jsx)("path", { d: "M4 10h16M9 3v4M15 3v4" }, "b")]);
|
|
6216
|
+
var IconShield = ({ size = 18 }) => svg(size, /* @__PURE__ */ (0, import_jsx_runtime58.jsx)("path", { d: "M12 3l7 3v6c0 5-3 8-7 9-4-1-7-4-7-9V6z" }));
|
|
6217
|
+
var IconFlag = ({ size = 18 }) => svg(size, /* @__PURE__ */ (0, import_jsx_runtime58.jsx)("path", { d: "M5 21V4M5 4h12l-2 4 2 4H5" }));
|
|
6218
|
+
var IconBall = ({ size = 18 }) => svg(size, [/* @__PURE__ */ (0, import_jsx_runtime58.jsx)("circle", { cx: "12", cy: "12", r: "9" }, "a"), /* @__PURE__ */ (0, import_jsx_runtime58.jsx)("path", { d: "M12 7l4 3-1.5 4.5h-5L8 10z" }, "b")]);
|
|
6219
|
+
var IconBoot = ({ size = 18 }) => svg(size, /* @__PURE__ */ (0, import_jsx_runtime58.jsx)("path", { d: "M4 6h6l1 6 8 3v3H4z" }));
|
|
6220
|
+
var IconGloves = ({ size = 18 }) => svg(size, /* @__PURE__ */ (0, import_jsx_runtime58.jsx)("path", { d: "M7 21v-8l-2-3V6a1.5 1.5 0 0 1 3 0v3V4a1.5 1.5 0 0 1 3 0v5V3.5a1.5 1.5 0 0 1 3 0V9V5a1.5 1.5 0 0 1 3 0v9l-2 3v4z" }));
|
|
6221
|
+
var IconFlame = ({ size = 16 }) => svg(size, /* @__PURE__ */ (0, import_jsx_runtime58.jsx)("path", { d: "M12 3c1 4 5 5 5 10a5 5 0 0 1-10 0c0-3 2-4 2-7 1.5 1 2 2 2 3 1-2 1-4 1-6z" }), true);
|
|
6222
|
+
|
|
6223
|
+
// src/components/games/ui/SearchField.tsx
|
|
6224
|
+
var import_jsx_runtime59 = require("react/jsx-runtime");
|
|
6225
|
+
function SearchField({ id, label, labelHidden = false, placeholder, value, onChange, disabled, inputRef, onKeyDown }) {
|
|
6226
|
+
return /* @__PURE__ */ (0, import_jsx_runtime59.jsxs)("div", { className: "ss-g-search", children: [
|
|
6227
|
+
/* @__PURE__ */ (0, import_jsx_runtime59.jsx)("label", { htmlFor: id, className: labelHidden ? "ss-g-sr" : "ss-g-search-label", children: label }),
|
|
6228
|
+
/* @__PURE__ */ (0, import_jsx_runtime59.jsxs)("div", { className: "ss-g-search-box", children: [
|
|
6229
|
+
/* @__PURE__ */ (0, import_jsx_runtime59.jsx)(IconSearch, {}),
|
|
6230
|
+
/* @__PURE__ */ (0, import_jsx_runtime59.jsx)(
|
|
6231
|
+
"input",
|
|
6232
|
+
{
|
|
6233
|
+
id,
|
|
6234
|
+
ref: inputRef,
|
|
6235
|
+
type: "text",
|
|
6236
|
+
autoComplete: "off",
|
|
6237
|
+
placeholder,
|
|
6238
|
+
value,
|
|
6239
|
+
disabled,
|
|
6240
|
+
onKeyDown,
|
|
6241
|
+
onChange: (e) => onChange(e.target.value)
|
|
6242
|
+
}
|
|
6243
|
+
)
|
|
6244
|
+
] })
|
|
5886
6245
|
] });
|
|
5887
6246
|
}
|
|
5888
6247
|
|
|
5889
6248
|
// src/components/TodayPanel.tsx
|
|
5890
|
-
var
|
|
6249
|
+
var import_jsx_runtime60 = require("react/jsx-runtime");
|
|
5891
6250
|
function TodayPanel({ discovery, ui, monitor }) {
|
|
5892
|
-
const { groups, states, stale,
|
|
6251
|
+
const { groups, states, stale, starLeague } = discovery;
|
|
6252
|
+
const searchId = (0, import_react40.useId)();
|
|
6253
|
+
const [query, setQuery] = (0, import_react40.useState)("");
|
|
6254
|
+
const [selectedCompetitionId, setSelectedCompetitionId] = (0, import_react40.useState)(null);
|
|
6255
|
+
const [toast, setToast] = (0, import_react40.useState)(null);
|
|
6256
|
+
(0, import_react40.useEffect)(() => {
|
|
6257
|
+
if (toast === null) return;
|
|
6258
|
+
const id = setTimeout(() => setToast(null), 4e3);
|
|
6259
|
+
return () => clearTimeout(id);
|
|
6260
|
+
}, [toast]);
|
|
5893
6261
|
const visibleGroups = visibleGroupsOf(groups, states);
|
|
5894
|
-
const
|
|
6262
|
+
const pinnedMatchIds = (0, import_react40.useMemo)(
|
|
6263
|
+
() => monitor.pins.filter((p) => p.kind === "match").map((p) => p.matchId),
|
|
6264
|
+
[monitor.pins]
|
|
6265
|
+
);
|
|
6266
|
+
const placement = (0, import_react40.useMemo)(() => placeLeagues(visibleGroups, pinnedMatchIds), [visibleGroups, pinnedMatchIds]);
|
|
6267
|
+
const starTap = useStarTap(starLeague);
|
|
6268
|
+
const gridStarTap = (0, import_react40.useMemo)(() => ({
|
|
6269
|
+
pendingId: starTap.pendingId,
|
|
6270
|
+
tap: async (competitionId, next) => {
|
|
6271
|
+
const ok = await starTap.tap(competitionId, next);
|
|
6272
|
+
if (ok) setToast(next ? "starred" : "unstarred");
|
|
6273
|
+
return ok;
|
|
6274
|
+
}
|
|
6275
|
+
}), [starTap, starTap.pendingId]);
|
|
5895
6276
|
const nameCounts = visibleGroups.reduce((acc, g) => {
|
|
5896
6277
|
acc[g.competitionName] = (acc[g.competitionName] ?? 0) + 1;
|
|
5897
6278
|
return acc;
|
|
5898
6279
|
}, {});
|
|
5899
|
-
|
|
5900
|
-
|
|
5901
|
-
|
|
5902
|
-
|
|
5903
|
-
|
|
5904
|
-
|
|
5905
|
-
|
|
5906
|
-
|
|
5907
|
-
|
|
5908
|
-
|
|
5909
|
-
match,
|
|
5910
|
-
state: states[match.matchId],
|
|
5911
|
-
stale,
|
|
5912
|
-
ui,
|
|
5913
|
-
monitor
|
|
5914
|
-
},
|
|
5915
|
-
match.matchId
|
|
5916
|
-
)) })
|
|
6280
|
+
const openIndex = selectedCompetitionId === null ? -1 : placement.order.findIndex((g) => g.competitionId === selectedCompetitionId);
|
|
6281
|
+
const openGroup = openIndex === -1 ? void 0 : placement.order[openIndex];
|
|
6282
|
+
(0, import_react40.useEffect)(() => {
|
|
6283
|
+
if (selectedCompetitionId !== null && openGroup === void 0) setSelectedCompetitionId(null);
|
|
6284
|
+
}, [selectedCompetitionId, openGroup]);
|
|
6285
|
+
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);
|
|
6286
|
+
const liveBand = liveRows.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime60.jsxs)(import_jsx_runtime60.Fragment, { children: [
|
|
6287
|
+
/* @__PURE__ */ (0, import_jsx_runtime60.jsxs)("div", { className: "ss-w-sec-head", children: [
|
|
6288
|
+
/* @__PURE__ */ (0, import_jsx_runtime60.jsx)("span", { className: "ss-w-sec-dot", "aria-hidden": "true" }),
|
|
6289
|
+
ui.sectionLive
|
|
5917
6290
|
] }),
|
|
5918
|
-
|
|
5919
|
-
|
|
6291
|
+
/* @__PURE__ */ (0, import_jsx_runtime60.jsx)("div", { className: "ss-w-today-live", children: liveRows.map(({ match }) => /* @__PURE__ */ (0, import_jsx_runtime60.jsx)(
|
|
6292
|
+
FixtureRow,
|
|
5920
6293
|
{
|
|
5921
|
-
|
|
5922
|
-
|
|
5923
|
-
onToggle: () => toggleGroup(group.competitionId),
|
|
5924
|
-
disambiguate: (nameCounts[group.competitionName] ?? 0) > 1,
|
|
5925
|
-
states,
|
|
6294
|
+
match,
|
|
6295
|
+
state: states[match.matchId],
|
|
5926
6296
|
stale,
|
|
5927
6297
|
ui,
|
|
5928
6298
|
monitor
|
|
5929
6299
|
},
|
|
5930
|
-
|
|
5931
|
-
))
|
|
6300
|
+
match.matchId
|
|
6301
|
+
)) })
|
|
6302
|
+
] });
|
|
6303
|
+
if (openGroup !== void 0) {
|
|
6304
|
+
return /* @__PURE__ */ (0, import_jsx_runtime60.jsx)("div", { className: "ss-w-today-root", children: /* @__PURE__ */ (0, import_jsx_runtime60.jsxs)("div", { className: "ss-w-mon-list", children: [
|
|
6305
|
+
stale && /* @__PURE__ */ (0, import_jsx_runtime60.jsx)("div", { className: "ss-w-stale", children: ui.staleStates }),
|
|
6306
|
+
liveBand,
|
|
6307
|
+
/* @__PURE__ */ (0, import_jsx_runtime60.jsx)(
|
|
6308
|
+
LeagueDetail,
|
|
6309
|
+
{
|
|
6310
|
+
group: openGroup,
|
|
6311
|
+
position: { index: openIndex + 1, total: placement.order.length },
|
|
6312
|
+
states,
|
|
6313
|
+
stale,
|
|
6314
|
+
ui,
|
|
6315
|
+
monitor,
|
|
6316
|
+
starTap,
|
|
6317
|
+
onBack: () => setSelectedCompetitionId(null),
|
|
6318
|
+
onPrev: () => setSelectedCompetitionId(placement.order[Math.max(0, openIndex - 1)].competitionId),
|
|
6319
|
+
onNext: () => setSelectedCompetitionId(
|
|
6320
|
+
placement.order[Math.min(placement.order.length - 1, openIndex + 1)].competitionId
|
|
6321
|
+
)
|
|
6322
|
+
}
|
|
6323
|
+
)
|
|
6324
|
+
] }) });
|
|
6325
|
+
}
|
|
6326
|
+
const searching = query.trim().length > 0;
|
|
6327
|
+
const searchResults = searching ? visibleGroups.filter((g) => matchesQuery(g, query)) : [];
|
|
6328
|
+
return /* @__PURE__ */ (0, import_jsx_runtime60.jsxs)("div", { className: "ss-w-today-root", children: [
|
|
6329
|
+
/* @__PURE__ */ (0, import_jsx_runtime60.jsxs)("div", { className: "ss-w-mon-list", children: [
|
|
6330
|
+
stale && /* @__PURE__ */ (0, import_jsx_runtime60.jsx)("div", { className: "ss-w-stale", children: ui.staleStates }),
|
|
6331
|
+
!searching && liveBand,
|
|
6332
|
+
/* @__PURE__ */ (0, import_jsx_runtime60.jsx)(
|
|
6333
|
+
SearchField,
|
|
6334
|
+
{
|
|
6335
|
+
id: searchId,
|
|
6336
|
+
label: ui.searchLeaguesPlaceholder,
|
|
6337
|
+
labelHidden: true,
|
|
6338
|
+
placeholder: ui.searchLeaguesPlaceholder,
|
|
6339
|
+
value: query,
|
|
6340
|
+
onChange: setQuery
|
|
6341
|
+
}
|
|
6342
|
+
),
|
|
6343
|
+
searching ? searchResults.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime60.jsx)("div", { className: "ss-w-today-empty", children: ui.noLeagueResults }) : /* @__PURE__ */ (0, import_jsx_runtime60.jsx)("div", { className: "ss-w-today-tiles", children: searchResults.map((group) => /* @__PURE__ */ (0, import_jsx_runtime60.jsx)(
|
|
6344
|
+
LeagueTile,
|
|
6345
|
+
{
|
|
6346
|
+
group,
|
|
6347
|
+
starClickable: starClickable(group, placement.pinnedCompetitionId),
|
|
6348
|
+
disambiguate: (nameCounts[group.competitionName] ?? 0) > 1,
|
|
6349
|
+
onOpen: () => setSelectedCompetitionId(group.competitionId),
|
|
6350
|
+
starTap: gridStarTap,
|
|
6351
|
+
ui
|
|
6352
|
+
},
|
|
6353
|
+
group.competitionId
|
|
6354
|
+
)) }) : /* @__PURE__ */ (0, import_jsx_runtime60.jsxs)(import_jsx_runtime60.Fragment, { children: [
|
|
6355
|
+
/* @__PURE__ */ (0, import_jsx_runtime60.jsxs)("div", { className: "ss-w-today-sec", children: [
|
|
6356
|
+
placement.personal ? ui.yourLeagues : ui.topLeagues,
|
|
6357
|
+
!placement.personal && /* @__PURE__ */ (0, import_jsx_runtime60.jsx)("span", { className: "ss-w-today-sec-sub", children: ui.topLeaguesSub })
|
|
6358
|
+
] }),
|
|
6359
|
+
/* @__PURE__ */ (0, import_jsx_runtime60.jsx)("div", { className: "ss-w-today-tiles", children: placement.candidates.map((group) => /* @__PURE__ */ (0, import_jsx_runtime60.jsx)(
|
|
6360
|
+
LeagueTile,
|
|
6361
|
+
{
|
|
6362
|
+
group,
|
|
6363
|
+
starClickable: starClickable(group, placement.pinnedCompetitionId),
|
|
6364
|
+
disambiguate: (nameCounts[group.competitionName] ?? 0) > 1,
|
|
6365
|
+
onOpen: () => setSelectedCompetitionId(group.competitionId),
|
|
6366
|
+
starTap: gridStarTap,
|
|
6367
|
+
ui
|
|
6368
|
+
},
|
|
6369
|
+
group.competitionId
|
|
6370
|
+
)) }),
|
|
6371
|
+
/* @__PURE__ */ (0, import_jsx_runtime60.jsx)("div", { className: "ss-w-today-sec", children: ui.allLeagues }),
|
|
6372
|
+
/* @__PURE__ */ (0, import_jsx_runtime60.jsx)("div", { className: "ss-w-today-tiles", children: placement.others.map((group) => /* @__PURE__ */ (0, import_jsx_runtime60.jsx)(
|
|
6373
|
+
LeagueTile,
|
|
6374
|
+
{
|
|
6375
|
+
group,
|
|
6376
|
+
starClickable: starClickable(group, placement.pinnedCompetitionId),
|
|
6377
|
+
disambiguate: (nameCounts[group.competitionName] ?? 0) > 1,
|
|
6378
|
+
onOpen: () => setSelectedCompetitionId(group.competitionId),
|
|
6379
|
+
starTap: gridStarTap,
|
|
6380
|
+
ui
|
|
6381
|
+
},
|
|
6382
|
+
group.competitionId
|
|
6383
|
+
)) })
|
|
6384
|
+
] })
|
|
6385
|
+
] }),
|
|
6386
|
+
toast !== null && /* @__PURE__ */ (0, import_jsx_runtime60.jsx)("p", { className: "ss-w-today-toast", role: "status", "aria-live": "polite", children: toast === "starred" ? ui.starredToast : ui.unstarredToast })
|
|
5932
6387
|
] });
|
|
5933
6388
|
}
|
|
5934
6389
|
|
|
5935
6390
|
// src/components/GamesPanel.tsx
|
|
5936
|
-
var
|
|
6391
|
+
var import_react54 = require("react");
|
|
5937
6392
|
|
|
5938
6393
|
// src/components/GamesLoginWall.tsx
|
|
5939
|
-
var
|
|
6394
|
+
var import_jsx_runtime61 = require("react/jsx-runtime");
|
|
5940
6395
|
function GamesLoginWall({ ui }) {
|
|
5941
|
-
return /* @__PURE__ */ (0,
|
|
6396
|
+
return /* @__PURE__ */ (0, import_jsx_runtime61.jsx)("div", { className: "ss-w-mon-list", children: /* @__PURE__ */ (0, import_jsx_runtime61.jsx)("div", { className: "ss-w-games-wall", children: /* @__PURE__ */ (0, import_jsx_runtime61.jsx)("p", { children: ui.gamesLoginRequired }) }) });
|
|
5942
6397
|
}
|
|
5943
6398
|
|
|
5944
6399
|
// src/components/GamesHub.tsx
|
|
5945
|
-
var
|
|
6400
|
+
var import_react41 = require("react");
|
|
5946
6401
|
|
|
5947
6402
|
// src/components/games/ui/gameMeta.ts
|
|
5948
6403
|
function prettifyGameId(gameId) {
|
|
@@ -5958,108 +6413,74 @@ function splitName(full) {
|
|
|
5958
6413
|
}
|
|
5959
6414
|
|
|
5960
6415
|
// src/components/GameTileArt.tsx
|
|
5961
|
-
var
|
|
6416
|
+
var import_jsx_runtime62 = require("react/jsx-runtime");
|
|
5962
6417
|
function GameTileArt({ gameId }) {
|
|
5963
|
-
return /* @__PURE__ */ (0,
|
|
6418
|
+
return /* @__PURE__ */ (0, import_jsx_runtime62.jsx)("svg", { className: "ss-g-art", viewBox: "0 0 120 74", "aria-hidden": "true", children: ART[gameId] ?? ART.default });
|
|
5964
6419
|
}
|
|
5965
|
-
var head = (cx, cy, r, cls = "ss-g-art-fg") => /* @__PURE__ */ (0,
|
|
5966
|
-
/* @__PURE__ */ (0,
|
|
5967
|
-
/* @__PURE__ */ (0,
|
|
6420
|
+
var head = (cx, cy, r, cls = "ss-g-art-fg") => /* @__PURE__ */ (0, import_jsx_runtime62.jsxs)("g", { className: cls, children: [
|
|
6421
|
+
/* @__PURE__ */ (0, import_jsx_runtime62.jsx)("circle", { cx, cy: cy - r * 0.3, r: r * 0.45 }),
|
|
6422
|
+
/* @__PURE__ */ (0, import_jsx_runtime62.jsx)("path", { d: `M${cx - r} ${cy + r}c0-${r * 0.8} ${r * 0.45}-${r * 1.1} ${r}-${r * 1.1}s${r} ${r * 0.3} ${r} ${r * 1.1}z` })
|
|
5968
6423
|
] });
|
|
5969
6424
|
var ART = {
|
|
5970
|
-
"mystery-tiger": /* @__PURE__ */ (0,
|
|
6425
|
+
"mystery-tiger": /* @__PURE__ */ (0, import_jsx_runtime62.jsxs)(import_jsx_runtime62.Fragment, { children: [
|
|
5971
6426
|
head(60, 38, 26, "ss-g-art-fg"),
|
|
5972
|
-
/* @__PURE__ */ (0,
|
|
6427
|
+
/* @__PURE__ */ (0, import_jsx_runtime62.jsx)("text", { x: "60", y: "36", className: "ss-g-art-q", textAnchor: "middle", children: "?" })
|
|
5973
6428
|
] }),
|
|
5974
|
-
"higher-or-lower": /* @__PURE__ */ (0,
|
|
6429
|
+
"higher-or-lower": /* @__PURE__ */ (0, import_jsx_runtime62.jsxs)(import_jsx_runtime62.Fragment, { children: [
|
|
5975
6430
|
head(32, 38, 20),
|
|
5976
6431
|
head(88, 38, 20),
|
|
5977
|
-
/* @__PURE__ */ (0,
|
|
5978
|
-
/* @__PURE__ */ (0,
|
|
6432
|
+
/* @__PURE__ */ (0, import_jsx_runtime62.jsx)("circle", { cx: "60", cy: "37", r: "11", className: "ss-g-art-accent" }),
|
|
6433
|
+
/* @__PURE__ */ (0, import_jsx_runtime62.jsx)("path", { d: "M57 33l3-3 3 3M57 41l3 3 3-3", className: "ss-g-art-ink" })
|
|
5979
6434
|
] }),
|
|
5980
|
-
"guess-the-xi": /* @__PURE__ */ (0,
|
|
5981
|
-
/* @__PURE__ */ (0,
|
|
5982
|
-
[[60, 60, "a"], [24, 46], [48, 46], [72, 46], [96, 46], [36, 30], [60, 30], [84, 30], [40, 14], [60, 14], [80, 14]].map(([x, y, a], i) => /* @__PURE__ */ (0,
|
|
6435
|
+
"guess-the-xi": /* @__PURE__ */ (0, import_jsx_runtime62.jsxs)(import_jsx_runtime62.Fragment, { children: [
|
|
6436
|
+
/* @__PURE__ */ (0, import_jsx_runtime62.jsx)("rect", { x: "8", y: "4", width: "104", height: "66", rx: "6", className: "ss-g-art-pitch" }),
|
|
6437
|
+
[[60, 60, "a"], [24, 46], [48, 46], [72, 46], [96, 46], [36, 30], [60, 30], [84, 30], [40, 14], [60, 14], [80, 14]].map(([x, y, a], i) => /* @__PURE__ */ (0, import_jsx_runtime62.jsx)("circle", { cx: x, cy: y, r: "4", className: a ? "ss-g-art-accent" : "ss-g-art-dot" }, i))
|
|
5983
6438
|
] }),
|
|
5984
|
-
"daily-quiz": /* @__PURE__ */ (0,
|
|
5985
|
-
"career-path": /* @__PURE__ */ (0,
|
|
5986
|
-
/* @__PURE__ */ (0,
|
|
5987
|
-
/* @__PURE__ */ (0,
|
|
5988
|
-
/* @__PURE__ */ (0,
|
|
5989
|
-
/* @__PURE__ */ (0,
|
|
5990
|
-
/* @__PURE__ */ (0,
|
|
6439
|
+
"daily-quiz": /* @__PURE__ */ (0, import_jsx_runtime62.jsx)(import_jsx_runtime62.Fragment, { children: [[14, 8], [62, 8], [14, 40], [62, 40]].map(([x, y], i) => /* @__PURE__ */ (0, import_jsx_runtime62.jsx)("rect", { x, y, width: "44", height: "26", rx: "5", className: i === 1 ? "ss-g-art-correct" : "ss-g-art-block" }, i)) }),
|
|
6440
|
+
"career-path": /* @__PURE__ */ (0, import_jsx_runtime62.jsxs)(import_jsx_runtime62.Fragment, { children: [
|
|
6441
|
+
/* @__PURE__ */ (0, import_jsx_runtime62.jsx)("path", { d: "M18 22h24v10c0 7-5 11-12 13-7-2-12-6-12-13z", className: "ss-g-art-fg" }),
|
|
6442
|
+
/* @__PURE__ */ (0, import_jsx_runtime62.jsx)("path", { d: "M48 37h8M84 37h8", className: "ss-g-art-line" }),
|
|
6443
|
+
/* @__PURE__ */ (0, import_jsx_runtime62.jsx)("path", { d: "M60 22h24v10c0 7-5 11-12 13-7-2-12-6-12-13z", className: "ss-g-art-fg" }),
|
|
6444
|
+
/* @__PURE__ */ (0, import_jsx_runtime62.jsx)("rect", { x: "96", y: "22", width: "18", height: "26", rx: "4", className: "ss-g-art-dash" }),
|
|
6445
|
+
/* @__PURE__ */ (0, import_jsx_runtime62.jsx)("text", { x: "105", y: "40", className: "ss-g-art-q", textAnchor: "middle", children: "?" })
|
|
5991
6446
|
] }),
|
|
5992
|
-
"beat-the-grid": /* @__PURE__ */ (0,
|
|
5993
|
-
"matchday-predictor": /* @__PURE__ */ (0,
|
|
5994
|
-
/* @__PURE__ */ (0,
|
|
5995
|
-
/* @__PURE__ */ (0,
|
|
5996
|
-
/* @__PURE__ */ (0,
|
|
5997
|
-
/* @__PURE__ */ (0,
|
|
6447
|
+
"beat-the-grid": /* @__PURE__ */ (0, import_jsx_runtime62.jsx)(import_jsx_runtime62.Fragment, { children: [0, 1, 2].flatMap((r) => [0, 1, 2].map((c) => /* @__PURE__ */ (0, import_jsx_runtime62.jsx)("rect", { x: 33 + c * 19, y: 10 + r * 19, width: "16", height: "16", rx: "3", className: (r + c) % 3 === 0 ? "ss-g-art-accent" : "ss-g-art-block" }, `${r}${c}`))) }),
|
|
6448
|
+
"matchday-predictor": /* @__PURE__ */ (0, import_jsx_runtime62.jsxs)(import_jsx_runtime62.Fragment, { children: [
|
|
6449
|
+
/* @__PURE__ */ (0, import_jsx_runtime62.jsx)("path", { d: "M10 20h20v9c0 6-4 9-10 11-6-2-10-5-10-11z", className: "ss-g-art-fg" }),
|
|
6450
|
+
/* @__PURE__ */ (0, import_jsx_runtime62.jsx)("rect", { x: "38", y: "22", width: "18", height: "24", rx: "4", className: "ss-g-art-accent-stroke" }),
|
|
6451
|
+
/* @__PURE__ */ (0, import_jsx_runtime62.jsx)("rect", { x: "64", y: "22", width: "18", height: "24", rx: "4", className: "ss-g-art-dash" }),
|
|
6452
|
+
/* @__PURE__ */ (0, import_jsx_runtime62.jsx)("path", { d: "M90 20h20v9c0 6-4 9-10 11-6-2-10-5-10-11z", className: "ss-g-art-fg" })
|
|
5998
6453
|
] }),
|
|
5999
|
-
"starting-xi": /* @__PURE__ */ (0,
|
|
6000
|
-
/* @__PURE__ */ (0,
|
|
6001
|
-
[[60, 60], [30, 46], [50, 46], [70, 46], [90, 46], [45, 30], [75, 30], [30, 16], [60, 16], [90, 16]].map(([x, y], i) => /* @__PURE__ */ (0,
|
|
6454
|
+
"starting-xi": /* @__PURE__ */ (0, import_jsx_runtime62.jsxs)(import_jsx_runtime62.Fragment, { children: [
|
|
6455
|
+
/* @__PURE__ */ (0, import_jsx_runtime62.jsx)("rect", { x: "8", y: "4", width: "104", height: "66", rx: "6", className: "ss-g-art-pitch" }),
|
|
6456
|
+
[[60, 60], [30, 46], [50, 46], [70, 46], [90, 46], [45, 30], [75, 30], [30, 16], [60, 16], [90, 16]].map(([x, y], i) => /* @__PURE__ */ (0, import_jsx_runtime62.jsx)("circle", { cx: x, cy: y, r: "5", className: i < 7 ? "ss-g-art-accent" : "ss-g-art-dash" }, i))
|
|
6002
6457
|
] }),
|
|
6003
|
-
"stat-ladder": /* @__PURE__ */ (0,
|
|
6004
|
-
"fan-motm": /* @__PURE__ */ (0,
|
|
6005
|
-
/* @__PURE__ */ (0,
|
|
6458
|
+
"stat-ladder": /* @__PURE__ */ (0, import_jsx_runtime62.jsx)(import_jsx_runtime62.Fragment, { children: [[20, 70], [34, 52], [48, 34]].map(([y, w], i) => /* @__PURE__ */ (0, import_jsx_runtime62.jsx)("rect", { x: "24", y, width: w, height: "12", rx: "3", className: i === 1 ? "ss-g-art-accent" : "ss-g-art-block" }, i)) }),
|
|
6459
|
+
"fan-motm": /* @__PURE__ */ (0, import_jsx_runtime62.jsxs)(import_jsx_runtime62.Fragment, { children: [
|
|
6460
|
+
/* @__PURE__ */ (0, import_jsx_runtime62.jsx)("circle", { cx: "60", cy: "37", r: "26", className: "ss-g-art-accent-stroke" }),
|
|
6006
6461
|
head(60, 40, 18),
|
|
6007
|
-
/* @__PURE__ */ (0,
|
|
6462
|
+
/* @__PURE__ */ (0, import_jsx_runtime62.jsx)("path", { d: "M84 8l2.4 5 5.4.6-4 3.7 1.1 5.4-4.9-2.7-4.9 2.7 1.1-5.4-4-3.7 5.4-.6z", className: "ss-g-art-accent" })
|
|
6008
6463
|
] }),
|
|
6009
|
-
default: /* @__PURE__ */ (0,
|
|
6464
|
+
default: /* @__PURE__ */ (0, import_jsx_runtime62.jsx)("circle", { cx: "60", cy: "37", r: "22", className: "ss-g-art-fg" })
|
|
6010
6465
|
};
|
|
6011
6466
|
|
|
6012
6467
|
// src/components/games/ui/Chip.tsx
|
|
6013
|
-
var
|
|
6468
|
+
var import_jsx_runtime63 = require("react/jsx-runtime");
|
|
6014
6469
|
function Chip({ variant = "neutral", icon, children, className }) {
|
|
6015
|
-
return /* @__PURE__ */ (0,
|
|
6470
|
+
return /* @__PURE__ */ (0, import_jsx_runtime63.jsxs)("span", { className: `ss-g-chip ss-g-chip--${variant}${className ? ` ${className}` : ""}`, children: [
|
|
6016
6471
|
icon,
|
|
6017
6472
|
children
|
|
6018
6473
|
] });
|
|
6019
6474
|
}
|
|
6020
6475
|
function StatStack({ value, label }) {
|
|
6021
|
-
return /* @__PURE__ */ (0,
|
|
6022
|
-
/* @__PURE__ */ (0,
|
|
6023
|
-
/* @__PURE__ */ (0,
|
|
6476
|
+
return /* @__PURE__ */ (0, import_jsx_runtime63.jsxs)("span", { className: "ss-g-statstack", children: [
|
|
6477
|
+
/* @__PURE__ */ (0, import_jsx_runtime63.jsx)("span", { className: "ss-g-statstack-v", children: value }),
|
|
6478
|
+
/* @__PURE__ */ (0, import_jsx_runtime63.jsx)("span", { className: "ss-g-statstack-l", children: label })
|
|
6024
6479
|
] });
|
|
6025
6480
|
}
|
|
6026
6481
|
|
|
6027
|
-
// src/components/games/ui/icons.tsx
|
|
6028
|
-
var import_jsx_runtime61 = require("react/jsx-runtime");
|
|
6029
|
-
var svg = (size, children, fill = false) => /* @__PURE__ */ (0, import_jsx_runtime61.jsx)(
|
|
6030
|
-
"svg",
|
|
6031
|
-
{
|
|
6032
|
-
width: size,
|
|
6033
|
-
height: size,
|
|
6034
|
-
viewBox: "0 0 24 24",
|
|
6035
|
-
fill: fill ? "currentColor" : "none",
|
|
6036
|
-
stroke: fill ? "none" : "currentColor",
|
|
6037
|
-
strokeWidth: 2.2,
|
|
6038
|
-
strokeLinecap: "round",
|
|
6039
|
-
strokeLinejoin: "round",
|
|
6040
|
-
"aria-hidden": "true",
|
|
6041
|
-
children
|
|
6042
|
-
}
|
|
6043
|
-
);
|
|
6044
|
-
var IconChevronLeft = ({ size = 20 }) => svg(size, /* @__PURE__ */ (0, import_jsx_runtime61.jsx)("path", { d: "M15 18l-6-6 6-6" }));
|
|
6045
|
-
var IconLock = ({ size = 14 }) => svg(size, [/* @__PURE__ */ (0, import_jsx_runtime61.jsx)("rect", { x: "5", y: "11", width: "14", height: "10", rx: "2" }, "a"), /* @__PURE__ */ (0, import_jsx_runtime61.jsx)("path", { d: "M8 11V7a4 4 0 0 1 8 0v4" }, "b")]);
|
|
6046
|
-
var IconCheck = ({ size = 14 }) => svg(size, /* @__PURE__ */ (0, import_jsx_runtime61.jsx)("path", { d: "M5 12l5 5 9-10" }));
|
|
6047
|
-
var IconClose = ({ size = 16 }) => svg(size, /* @__PURE__ */ (0, import_jsx_runtime61.jsx)("path", { d: "M6 6l12 12M18 6L6 18" }));
|
|
6048
|
-
var IconSearch = ({ size = 18 }) => svg(size, [/* @__PURE__ */ (0, import_jsx_runtime61.jsx)("circle", { cx: "11", cy: "11", r: "7" }, "a"), /* @__PURE__ */ (0, import_jsx_runtime61.jsx)("path", { d: "M20 20l-3.5-3.5" }, "b")]);
|
|
6049
|
-
var IconPlus = ({ size = 20 }) => svg(size, /* @__PURE__ */ (0, import_jsx_runtime61.jsx)("path", { d: "M12 5v14M5 12h14" }));
|
|
6050
|
-
var IconBulb = ({ size = 16 }) => svg(size, [/* @__PURE__ */ (0, import_jsx_runtime61.jsx)("path", { d: "M9 18h6M10 21h4" }, "a"), /* @__PURE__ */ (0, import_jsx_runtime61.jsx)("path", { d: "M12 3a6 6 0 0 0-3.5 10.9V16h7v-2.1A6 6 0 0 0 12 3z" }, "b")]);
|
|
6051
|
-
var IconArrowUp = ({ size = 12 }) => svg(size, /* @__PURE__ */ (0, import_jsx_runtime61.jsx)("path", { d: "M12 19V5M5 12l7-7 7 7" }));
|
|
6052
|
-
var IconArrowDown = ({ size = 12 }) => svg(size, /* @__PURE__ */ (0, import_jsx_runtime61.jsx)("path", { d: "M12 5v14M19 12l-7 7-7-7" }));
|
|
6053
|
-
var IconCalendar = ({ size = 18 }) => svg(size, [/* @__PURE__ */ (0, import_jsx_runtime61.jsx)("rect", { x: "4", y: "5", width: "16", height: "15", rx: "2" }, "a"), /* @__PURE__ */ (0, import_jsx_runtime61.jsx)("path", { d: "M4 10h16M9 3v4M15 3v4" }, "b")]);
|
|
6054
|
-
var IconShield = ({ size = 18 }) => svg(size, /* @__PURE__ */ (0, import_jsx_runtime61.jsx)("path", { d: "M12 3l7 3v6c0 5-3 8-7 9-4-1-7-4-7-9V6z" }));
|
|
6055
|
-
var IconFlag = ({ size = 18 }) => svg(size, /* @__PURE__ */ (0, import_jsx_runtime61.jsx)("path", { d: "M5 21V4M5 4h12l-2 4 2 4H5" }));
|
|
6056
|
-
var IconBall = ({ size = 18 }) => svg(size, [/* @__PURE__ */ (0, import_jsx_runtime61.jsx)("circle", { cx: "12", cy: "12", r: "9" }, "a"), /* @__PURE__ */ (0, import_jsx_runtime61.jsx)("path", { d: "M12 7l4 3-1.5 4.5h-5L8 10z" }, "b")]);
|
|
6057
|
-
var IconBoot = ({ size = 18 }) => svg(size, /* @__PURE__ */ (0, import_jsx_runtime61.jsx)("path", { d: "M4 6h6l1 6 8 3v3H4z" }));
|
|
6058
|
-
var IconGloves = ({ size = 18 }) => svg(size, /* @__PURE__ */ (0, import_jsx_runtime61.jsx)("path", { d: "M7 21v-8l-2-3V6a1.5 1.5 0 0 1 3 0v3V4a1.5 1.5 0 0 1 3 0v5V3.5a1.5 1.5 0 0 1 3 0V9V5a1.5 1.5 0 0 1 3 0v9l-2 3v4z" }));
|
|
6059
|
-
var IconFlame = ({ size = 16 }) => svg(size, /* @__PURE__ */ (0, import_jsx_runtime61.jsx)("path", { d: "M12 3c1 4 5 5 5 10a5 5 0 0 1-10 0c0-3 2-4 2-7 1.5 1 2 2 2 3 1-2 1-4 1-6z" }), true);
|
|
6060
|
-
|
|
6061
6482
|
// src/components/GameTile.tsx
|
|
6062
|
-
var
|
|
6483
|
+
var import_jsx_runtime64 = require("react/jsx-runtime");
|
|
6063
6484
|
function tileStatus(game, ui) {
|
|
6064
6485
|
switch (game.status) {
|
|
6065
6486
|
case "locked":
|
|
@@ -6083,38 +6504,38 @@ function GameTile({ game, onOpen, ui, variant = "tile" }) {
|
|
|
6083
6504
|
const status = tileStatus(game, ui);
|
|
6084
6505
|
const disabled = DISABLED.has(game.status);
|
|
6085
6506
|
const title = gameTitle(game, ui.games.titles);
|
|
6086
|
-
const body = variant === "hero" ? /* @__PURE__ */ (0,
|
|
6087
|
-
/* @__PURE__ */ (0,
|
|
6088
|
-
/* @__PURE__ */ (0,
|
|
6089
|
-
status.tone === "new" && /* @__PURE__ */ (0,
|
|
6090
|
-
/* @__PURE__ */ (0,
|
|
6091
|
-
/* @__PURE__ */ (0,
|
|
6092
|
-
status.tone === "success" ? /* @__PURE__ */ (0,
|
|
6507
|
+
const body = variant === "hero" ? /* @__PURE__ */ (0, import_jsx_runtime64.jsxs)(import_jsx_runtime64.Fragment, { children: [
|
|
6508
|
+
/* @__PURE__ */ (0, import_jsx_runtime64.jsxs)("span", { className: "ss-g-hero-text", children: [
|
|
6509
|
+
/* @__PURE__ */ (0, import_jsx_runtime64.jsx)("span", { className: "ss-g-hero-eyebrow", children: ui.games.dailyChallenge }),
|
|
6510
|
+
status.tone === "new" && /* @__PURE__ */ (0, import_jsx_runtime64.jsx)(Chip, { variant: "badge", children: ui.games.newToday }),
|
|
6511
|
+
/* @__PURE__ */ (0, import_jsx_runtime64.jsx)("span", { className: "ss-g-hero-title", children: title }),
|
|
6512
|
+
/* @__PURE__ */ (0, import_jsx_runtime64.jsx)("span", { className: "ss-g-hero-sub", children: ui.games.taglines[game.gameId] ?? "" }),
|
|
6513
|
+
status.tone === "success" ? /* @__PURE__ */ (0, import_jsx_runtime64.jsx)("span", { className: "ss-g-tile-status", "data-tone": "success", children: status.text }) : /* @__PURE__ */ (0, import_jsx_runtime64.jsxs)("span", { className: "ss-g-hero-cta", children: [
|
|
6093
6514
|
status.tone === "accent" ? ui.games.resume : ui.games.playNow,
|
|
6094
6515
|
" \u2192"
|
|
6095
6516
|
] })
|
|
6096
6517
|
] }),
|
|
6097
|
-
/* @__PURE__ */ (0,
|
|
6098
|
-
] }) : variant === "wide" ? /* @__PURE__ */ (0,
|
|
6099
|
-
/* @__PURE__ */ (0,
|
|
6100
|
-
/* @__PURE__ */ (0,
|
|
6101
|
-
/* @__PURE__ */ (0,
|
|
6102
|
-
/* @__PURE__ */ (0,
|
|
6103
|
-
status.tone === "new" && /* @__PURE__ */ (0,
|
|
6518
|
+
/* @__PURE__ */ (0, import_jsx_runtime64.jsx)("span", { className: "ss-g-hero-art", children: /* @__PURE__ */ (0, import_jsx_runtime64.jsx)(GameTileArt, { gameId: game.gameId }) })
|
|
6519
|
+
] }) : variant === "wide" ? /* @__PURE__ */ (0, import_jsx_runtime64.jsxs)(import_jsx_runtime64.Fragment, { children: [
|
|
6520
|
+
/* @__PURE__ */ (0, import_jsx_runtime64.jsx)("span", { className: "ss-g-wide-art", children: /* @__PURE__ */ (0, import_jsx_runtime64.jsx)(GameTileArt, { gameId: game.gameId }) }),
|
|
6521
|
+
/* @__PURE__ */ (0, import_jsx_runtime64.jsxs)("span", { className: "ss-g-wide-text", children: [
|
|
6522
|
+
/* @__PURE__ */ (0, import_jsx_runtime64.jsx)("span", { className: "ss-g-tile-title", children: title }),
|
|
6523
|
+
/* @__PURE__ */ (0, import_jsx_runtime64.jsx)("span", { className: "ss-g-tile-status", "data-tone": status.tone, children: status.text }),
|
|
6524
|
+
status.tone === "new" && /* @__PURE__ */ (0, import_jsx_runtime64.jsx)(Chip, { variant: "badge", children: ui.games.newToday })
|
|
6104
6525
|
] }),
|
|
6105
|
-
/* @__PURE__ */ (0,
|
|
6106
|
-
] }) : /* @__PURE__ */ (0,
|
|
6107
|
-
/* @__PURE__ */ (0,
|
|
6108
|
-
/* @__PURE__ */ (0,
|
|
6109
|
-
/* @__PURE__ */ (0,
|
|
6526
|
+
/* @__PURE__ */ (0, import_jsx_runtime64.jsx)("span", { className: "ss-g-wide-chev", children: /* @__PURE__ */ (0, import_jsx_runtime64.jsx)(IconChevronLeft, { size: 18 }) })
|
|
6527
|
+
] }) : /* @__PURE__ */ (0, import_jsx_runtime64.jsxs)(import_jsx_runtime64.Fragment, { children: [
|
|
6528
|
+
/* @__PURE__ */ (0, import_jsx_runtime64.jsx)("span", { className: "ss-g-tile-art", children: /* @__PURE__ */ (0, import_jsx_runtime64.jsx)(GameTileArt, { gameId: game.gameId }) }),
|
|
6529
|
+
/* @__PURE__ */ (0, import_jsx_runtime64.jsx)("span", { className: "ss-g-tile-title", children: title }),
|
|
6530
|
+
/* @__PURE__ */ (0, import_jsx_runtime64.jsx)("span", { className: "ss-g-tile-status", "data-tone": status.tone, children: status.text })
|
|
6110
6531
|
] });
|
|
6111
6532
|
const cls = `ss-g-tile ss-g-tile--${variant}`;
|
|
6112
|
-
if (disabled) return /* @__PURE__ */ (0,
|
|
6113
|
-
return /* @__PURE__ */ (0,
|
|
6533
|
+
if (disabled) return /* @__PURE__ */ (0, import_jsx_runtime64.jsx)("div", { className: cls, "data-disabled": true, "aria-disabled": "true", children: body });
|
|
6534
|
+
return /* @__PURE__ */ (0, import_jsx_runtime64.jsx)("button", { type: "button", className: cls, "aria-label": `${title} \u2014 ${status.text}`, onClick: () => onOpen(game), children: body });
|
|
6114
6535
|
}
|
|
6115
6536
|
|
|
6116
6537
|
// src/components/GamesHub.tsx
|
|
6117
|
-
var
|
|
6538
|
+
var import_jsx_runtime65 = require("react/jsx-runtime");
|
|
6118
6539
|
var PLAYABLE = /* @__PURE__ */ new Set(["available", "in_progress"]);
|
|
6119
6540
|
var DONE = /* @__PURE__ */ new Set(["played", "graded"]);
|
|
6120
6541
|
function pickHeroGame(games) {
|
|
@@ -6127,8 +6548,8 @@ function pickHeroGame(games) {
|
|
|
6127
6548
|
}
|
|
6128
6549
|
var tileKey = (g) => `${g.gameId}-${g.gameDay}-${g.fixtureId}`;
|
|
6129
6550
|
function GamesHub({ games, myWeeklyRow, weeklyPrize, onOpen, ui }) {
|
|
6130
|
-
const [, setTick] = (0,
|
|
6131
|
-
(0,
|
|
6551
|
+
const [, setTick] = (0, import_react41.useState)(0);
|
|
6552
|
+
(0, import_react41.useEffect)(() => {
|
|
6132
6553
|
const id = setInterval(() => setTick((t) => t + 1), 6e4);
|
|
6133
6554
|
return () => clearInterval(id);
|
|
6134
6555
|
}, []);
|
|
@@ -6140,58 +6561,58 @@ function GamesHub({ games, myWeeklyRow, weeklyPrize, onOpen, ui }) {
|
|
|
6140
6561
|
const kickoffs = fixtures.map((g) => g.kickoffUtc).filter((k) => !!k).sort();
|
|
6141
6562
|
const todayPts = games.filter((g) => DONE.has(g.status)).reduce((s, g) => s + (g.score ?? 0), 0);
|
|
6142
6563
|
const dash = "\u2014";
|
|
6143
|
-
return /* @__PURE__ */ (0,
|
|
6144
|
-
/* @__PURE__ */ (0,
|
|
6145
|
-
/* @__PURE__ */ (0,
|
|
6146
|
-
/* @__PURE__ */ (0,
|
|
6147
|
-
/* @__PURE__ */ (0,
|
|
6148
|
-
myWeeklyRow ? /* @__PURE__ */ (0,
|
|
6149
|
-
/* @__PURE__ */ (0,
|
|
6564
|
+
return /* @__PURE__ */ (0, import_jsx_runtime65.jsxs)("div", { className: "ss-g-hub", children: [
|
|
6565
|
+
/* @__PURE__ */ (0, import_jsx_runtime65.jsxs)("div", { className: "ss-g-stats", children: [
|
|
6566
|
+
/* @__PURE__ */ (0, import_jsx_runtime65.jsxs)("div", { className: "ss-g-stat", children: [
|
|
6567
|
+
/* @__PURE__ */ (0, import_jsx_runtime65.jsx)("span", { className: "ss-g-stat-l", children: ui.games.statStreak }),
|
|
6568
|
+
/* @__PURE__ */ (0, import_jsx_runtime65.jsxs)("span", { className: "ss-g-stat-v", "data-testid": "stat-streak", children: [
|
|
6569
|
+
myWeeklyRow ? /* @__PURE__ */ (0, import_jsx_runtime65.jsxs)(import_jsx_runtime65.Fragment, { children: [
|
|
6570
|
+
/* @__PURE__ */ (0, import_jsx_runtime65.jsx)(IconFlame, {}),
|
|
6150
6571
|
myWeeklyRow.currentStreak
|
|
6151
6572
|
] }) : dash,
|
|
6152
|
-
myWeeklyRow && /* @__PURE__ */ (0,
|
|
6573
|
+
myWeeklyRow && /* @__PURE__ */ (0, import_jsx_runtime65.jsx)("small", { children: ui.games.unitDays })
|
|
6153
6574
|
] })
|
|
6154
6575
|
] }),
|
|
6155
|
-
/* @__PURE__ */ (0,
|
|
6156
|
-
/* @__PURE__ */ (0,
|
|
6157
|
-
/* @__PURE__ */ (0,
|
|
6576
|
+
/* @__PURE__ */ (0, import_jsx_runtime65.jsxs)("div", { className: "ss-g-stat", children: [
|
|
6577
|
+
/* @__PURE__ */ (0, import_jsx_runtime65.jsx)("span", { className: "ss-g-stat-l", children: ui.games.statToday }),
|
|
6578
|
+
/* @__PURE__ */ (0, import_jsx_runtime65.jsxs)("span", { className: "ss-g-stat-v ss-g-stat-v--accent", "data-testid": "stat-today", children: [
|
|
6158
6579
|
ui.games.formatPts(todayPts),
|
|
6159
|
-
/* @__PURE__ */ (0,
|
|
6580
|
+
/* @__PURE__ */ (0, import_jsx_runtime65.jsx)("small", { children: ui.games.unitPts })
|
|
6160
6581
|
] })
|
|
6161
6582
|
] }),
|
|
6162
|
-
/* @__PURE__ */ (0,
|
|
6163
|
-
/* @__PURE__ */ (0,
|
|
6164
|
-
/* @__PURE__ */ (0,
|
|
6583
|
+
/* @__PURE__ */ (0, import_jsx_runtime65.jsxs)("div", { className: "ss-g-stat", children: [
|
|
6584
|
+
/* @__PURE__ */ (0, import_jsx_runtime65.jsx)("span", { className: "ss-g-stat-l", children: ui.games.statRank }),
|
|
6585
|
+
/* @__PURE__ */ (0, import_jsx_runtime65.jsxs)("span", { className: "ss-g-stat-v", "data-testid": "stat-rank", children: [
|
|
6165
6586
|
myWeeklyRow ? `#${myWeeklyRow.rank}` : dash,
|
|
6166
|
-
myWeeklyRow && /* @__PURE__ */ (0,
|
|
6587
|
+
myWeeklyRow && /* @__PURE__ */ (0, import_jsx_runtime65.jsx)("small", { children: ui.games.thisWeek })
|
|
6167
6588
|
] })
|
|
6168
6589
|
] })
|
|
6169
6590
|
] }),
|
|
6170
|
-
weeklyPrize && /* @__PURE__ */ (0,
|
|
6171
|
-
hero && /* @__PURE__ */ (0,
|
|
6172
|
-
(grid.length > 0 || wide) && /* @__PURE__ */ (0,
|
|
6173
|
-
/* @__PURE__ */ (0,
|
|
6174
|
-
/* @__PURE__ */ (0,
|
|
6175
|
-
/* @__PURE__ */ (0,
|
|
6591
|
+
weeklyPrize && /* @__PURE__ */ (0, import_jsx_runtime65.jsx)(Chip, { variant: "accent", className: "ss-g-prize", children: weeklyPrize }),
|
|
6592
|
+
hero && /* @__PURE__ */ (0, import_jsx_runtime65.jsx)(GameTile, { game: hero, onOpen, ui, variant: "hero" }),
|
|
6593
|
+
(grid.length > 0 || wide) && /* @__PURE__ */ (0, import_jsx_runtime65.jsxs)("section", { className: "ss-g-sec", children: [
|
|
6594
|
+
/* @__PURE__ */ (0, import_jsx_runtime65.jsxs)("div", { className: "ss-g-sec-head", children: [
|
|
6595
|
+
/* @__PURE__ */ (0, import_jsx_runtime65.jsx)("h3", { children: ui.games.dailyGames }),
|
|
6596
|
+
/* @__PURE__ */ (0, import_jsx_runtime65.jsx)("span", { children: ui.games.newSetAtMidnight })
|
|
6176
6597
|
] }),
|
|
6177
|
-
grid.length > 0 && /* @__PURE__ */ (0,
|
|
6178
|
-
wide && /* @__PURE__ */ (0,
|
|
6598
|
+
grid.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime65.jsx)("div", { className: "ss-g-grid", children: grid.map((g) => /* @__PURE__ */ (0, import_jsx_runtime65.jsx)(GameTile, { game: g, onOpen, ui }, tileKey(g))) }),
|
|
6599
|
+
wide && /* @__PURE__ */ (0, import_jsx_runtime65.jsx)(GameTile, { game: wide, onOpen, ui, variant: "wide" })
|
|
6179
6600
|
] }),
|
|
6180
|
-
fixtures.length > 0 && /* @__PURE__ */ (0,
|
|
6181
|
-
/* @__PURE__ */ (0,
|
|
6182
|
-
/* @__PURE__ */ (0,
|
|
6183
|
-
kickoffs[0] && /* @__PURE__ */ (0,
|
|
6601
|
+
fixtures.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime65.jsxs)("section", { className: "ss-g-sec", children: [
|
|
6602
|
+
/* @__PURE__ */ (0, import_jsx_runtime65.jsxs)("div", { className: "ss-g-sec-head", children: [
|
|
6603
|
+
/* @__PURE__ */ (0, import_jsx_runtime65.jsx)("h3", { children: ui.games.matchdayGames }),
|
|
6604
|
+
kickoffs[0] && /* @__PURE__ */ (0, import_jsx_runtime65.jsx)("span", { children: ui.games.kickoffAt(ui.games.formatDayTime(kickoffs[0])) })
|
|
6184
6605
|
] }),
|
|
6185
|
-
/* @__PURE__ */ (0,
|
|
6606
|
+
/* @__PURE__ */ (0, import_jsx_runtime65.jsx)("div", { className: "ss-g-grid", children: fixtures.map((g) => /* @__PURE__ */ (0, import_jsx_runtime65.jsx)(GameTile, { game: g, onOpen, ui }, tileKey(g))) })
|
|
6186
6607
|
] })
|
|
6187
6608
|
] });
|
|
6188
6609
|
}
|
|
6189
6610
|
|
|
6190
6611
|
// src/components/GameScreenHost.tsx
|
|
6191
|
-
var
|
|
6612
|
+
var import_react53 = require("react");
|
|
6192
6613
|
|
|
6193
6614
|
// src/useGamePlay.ts
|
|
6194
|
-
var
|
|
6615
|
+
var import_react42 = require("react");
|
|
6195
6616
|
function toSubmitResult(payload) {
|
|
6196
6617
|
return {
|
|
6197
6618
|
// 'pending' means the play is recorded but awaiting resolution (fixture games)
|
|
@@ -6203,17 +6624,17 @@ function toSubmitResult(payload) {
|
|
|
6203
6624
|
};
|
|
6204
6625
|
}
|
|
6205
6626
|
function useGamePlay(conversation, { gameId, gameDay, fixtureId, locale, refresh }) {
|
|
6206
|
-
const [result, setResult] = (0,
|
|
6207
|
-
const [submitting, setSubmitting] = (0,
|
|
6208
|
-
const [rawStatus, setRawStatus] = (0,
|
|
6209
|
-
const inFlightRef = (0,
|
|
6210
|
-
const convRef = (0,
|
|
6627
|
+
const [result, setResult] = (0, import_react42.useState)(null);
|
|
6628
|
+
const [submitting, setSubmitting] = (0, import_react42.useState)(false);
|
|
6629
|
+
const [rawStatus, setRawStatus] = (0, import_react42.useState)(null);
|
|
6630
|
+
const inFlightRef = (0, import_react42.useRef)(false);
|
|
6631
|
+
const convRef = (0, import_react42.useRef)(conversation);
|
|
6211
6632
|
convRef.current = conversation;
|
|
6212
|
-
const optsRef = (0,
|
|
6633
|
+
const optsRef = (0, import_react42.useRef)({ gameId, gameDay, fixtureId, locale, refresh });
|
|
6213
6634
|
optsRef.current = { gameId, gameDay, fixtureId, locale, refresh };
|
|
6214
|
-
const resultRef = (0,
|
|
6635
|
+
const resultRef = (0, import_react42.useRef)(null);
|
|
6215
6636
|
resultRef.current = result;
|
|
6216
|
-
const refetch = (0,
|
|
6637
|
+
const refetch = (0, import_react42.useCallback)(async () => {
|
|
6217
6638
|
const conv = convRef.current;
|
|
6218
6639
|
if (!conv) return;
|
|
6219
6640
|
const opts = optsRef.current;
|
|
@@ -6229,7 +6650,7 @@ function useGamePlay(conversation, { gameId, gameDay, fixtureId, locale, refresh
|
|
|
6229
6650
|
} catch {
|
|
6230
6651
|
}
|
|
6231
6652
|
}, []);
|
|
6232
|
-
const submit = (0,
|
|
6653
|
+
const submit = (0, import_react42.useCallback)(async (answerJson) => {
|
|
6233
6654
|
const conv = convRef.current;
|
|
6234
6655
|
if (!conv || inFlightRef.current) return;
|
|
6235
6656
|
inFlightRef.current = true;
|
|
@@ -6256,14 +6677,14 @@ function useGamePlay(conversation, { gameId, gameDay, fixtureId, locale, refresh
|
|
|
6256
6677
|
setSubmitting(false);
|
|
6257
6678
|
}
|
|
6258
6679
|
}, [refetch]);
|
|
6259
|
-
const hydrate = (0,
|
|
6680
|
+
const hydrate = (0, import_react42.useCallback)(() => {
|
|
6260
6681
|
void refetch();
|
|
6261
6682
|
}, [refetch]);
|
|
6262
6683
|
return { result, submitting, submit, hydrate, rawStatus };
|
|
6263
6684
|
}
|
|
6264
6685
|
|
|
6265
6686
|
// src/components/games/MysteryTigerGame.tsx
|
|
6266
|
-
var
|
|
6687
|
+
var import_react44 = require("react");
|
|
6267
6688
|
|
|
6268
6689
|
// src/components/games/nationFlags.ts
|
|
6269
6690
|
var FLAGS = {
|
|
@@ -6474,8 +6895,8 @@ function isNationCode(flag) {
|
|
|
6474
6895
|
}
|
|
6475
6896
|
|
|
6476
6897
|
// src/components/games/PlayerAvatar.tsx
|
|
6477
|
-
var
|
|
6478
|
-
var
|
|
6898
|
+
var import_react43 = require("react");
|
|
6899
|
+
var import_jsx_runtime66 = require("react/jsx-runtime");
|
|
6479
6900
|
function initialsOf(name) {
|
|
6480
6901
|
const parts = name.trim().split(/\s+/).filter(Boolean);
|
|
6481
6902
|
const first = parts[0];
|
|
@@ -6492,41 +6913,41 @@ function PlayerAvatar({
|
|
|
6492
6913
|
imagePath,
|
|
6493
6914
|
className
|
|
6494
6915
|
}) {
|
|
6495
|
-
const [failed, setFailed] = (0,
|
|
6916
|
+
const [failed, setFailed] = (0, import_react43.useState)(false);
|
|
6496
6917
|
const showImage = Boolean(imagePath) && !isPlaceholderImage(imagePath) && !failed;
|
|
6497
|
-
return /* @__PURE__ */ (0,
|
|
6918
|
+
return /* @__PURE__ */ (0, import_jsx_runtime66.jsx)("div", { className, "aria-hidden": "true", children: showImage ? /* @__PURE__ */ (0, import_jsx_runtime66.jsx)("img", { src: imagePath, alt: "", loading: "lazy", onError: () => setFailed(true) }) : /* @__PURE__ */ (0, import_jsx_runtime66.jsx)("span", { className: "ss-w-av-initials", children: initialsOf(name) }) });
|
|
6498
6919
|
}
|
|
6499
6920
|
|
|
6500
6921
|
// src/components/games/ui/GameHeader.tsx
|
|
6501
|
-
var
|
|
6922
|
+
var import_jsx_runtime67 = require("react/jsx-runtime");
|
|
6502
6923
|
function GameHeader({ title, eyebrow, right, onBack, backLabel }) {
|
|
6503
|
-
return /* @__PURE__ */ (0,
|
|
6504
|
-
onBack && /* @__PURE__ */ (0,
|
|
6505
|
-
/* @__PURE__ */ (0,
|
|
6506
|
-
eyebrow && /* @__PURE__ */ (0,
|
|
6507
|
-
/* @__PURE__ */ (0,
|
|
6924
|
+
return /* @__PURE__ */ (0, import_jsx_runtime67.jsxs)("div", { className: "ss-g-head", children: [
|
|
6925
|
+
onBack && /* @__PURE__ */ (0, import_jsx_runtime67.jsx)("button", { type: "button", className: "ss-g-back", "aria-label": backLabel, onClick: onBack, children: /* @__PURE__ */ (0, import_jsx_runtime67.jsx)(IconChevronLeft, {}) }),
|
|
6926
|
+
/* @__PURE__ */ (0, import_jsx_runtime67.jsxs)("div", { className: "ss-g-head-text", children: [
|
|
6927
|
+
eyebrow && /* @__PURE__ */ (0, import_jsx_runtime67.jsx)("span", { className: "ss-g-eyebrow", children: eyebrow }),
|
|
6928
|
+
/* @__PURE__ */ (0, import_jsx_runtime67.jsx)("h2", { className: "ss-g-title", children: title })
|
|
6508
6929
|
] }),
|
|
6509
|
-
right && /* @__PURE__ */ (0,
|
|
6930
|
+
right && /* @__PURE__ */ (0, import_jsx_runtime67.jsx)("div", { className: "ss-g-head-right", children: right })
|
|
6510
6931
|
] });
|
|
6511
6932
|
}
|
|
6512
6933
|
|
|
6513
6934
|
// src/components/games/ui/SegmentProgress.tsx
|
|
6514
|
-
var
|
|
6935
|
+
var import_jsx_runtime68 = require("react/jsx-runtime");
|
|
6515
6936
|
function SegmentProgress({ segments, ariaLabel, leftLabel, rightLabel, right }) {
|
|
6516
|
-
return /* @__PURE__ */ (0,
|
|
6517
|
-
/* @__PURE__ */ (0,
|
|
6518
|
-
(leftLabel || rightLabel) && /* @__PURE__ */ (0,
|
|
6519
|
-
/* @__PURE__ */ (0,
|
|
6520
|
-
/* @__PURE__ */ (0,
|
|
6937
|
+
return /* @__PURE__ */ (0, import_jsx_runtime68.jsxs)("div", { className: "ss-g-progress", children: [
|
|
6938
|
+
/* @__PURE__ */ (0, import_jsx_runtime68.jsxs)("div", { className: "ss-g-progress-main", children: [
|
|
6939
|
+
(leftLabel || rightLabel) && /* @__PURE__ */ (0, import_jsx_runtime68.jsxs)("div", { className: "ss-g-progress-labels", children: [
|
|
6940
|
+
/* @__PURE__ */ (0, import_jsx_runtime68.jsx)("span", { children: leftLabel }),
|
|
6941
|
+
/* @__PURE__ */ (0, import_jsx_runtime68.jsx)("span", { className: "ss-g-progress-rl", children: rightLabel })
|
|
6521
6942
|
] }),
|
|
6522
|
-
/* @__PURE__ */ (0,
|
|
6943
|
+
/* @__PURE__ */ (0, import_jsx_runtime68.jsx)(
|
|
6523
6944
|
"div",
|
|
6524
6945
|
{
|
|
6525
6946
|
className: "ss-g-segs",
|
|
6526
6947
|
role: "img",
|
|
6527
6948
|
"aria-label": ariaLabel,
|
|
6528
6949
|
style: { gridTemplateColumns: `repeat(${segments.length}, minmax(0, 1fr))` },
|
|
6529
|
-
children: segments.map((s, i) => /* @__PURE__ */ (0,
|
|
6950
|
+
children: segments.map((s, i) => /* @__PURE__ */ (0, import_jsx_runtime68.jsx)("span", { className: "ss-g-seg", "data-state": s }, i))
|
|
6530
6951
|
}
|
|
6531
6952
|
)
|
|
6532
6953
|
] }),
|
|
@@ -6534,38 +6955,13 @@ function SegmentProgress({ segments, ariaLabel, leftLabel, rightLabel, right })
|
|
|
6534
6955
|
] });
|
|
6535
6956
|
}
|
|
6536
6957
|
|
|
6537
|
-
// src/components/games/ui/SearchField.tsx
|
|
6538
|
-
var import_jsx_runtime67 = require("react/jsx-runtime");
|
|
6539
|
-
function SearchField({ id, label, labelHidden = false, placeholder, value, onChange, disabled, inputRef, onKeyDown }) {
|
|
6540
|
-
return /* @__PURE__ */ (0, import_jsx_runtime67.jsxs)("div", { className: "ss-g-search", children: [
|
|
6541
|
-
/* @__PURE__ */ (0, import_jsx_runtime67.jsx)("label", { htmlFor: id, className: labelHidden ? "ss-g-sr" : "ss-g-search-label", children: label }),
|
|
6542
|
-
/* @__PURE__ */ (0, import_jsx_runtime67.jsxs)("div", { className: "ss-g-search-box", children: [
|
|
6543
|
-
/* @__PURE__ */ (0, import_jsx_runtime67.jsx)(IconSearch, {}),
|
|
6544
|
-
/* @__PURE__ */ (0, import_jsx_runtime67.jsx)(
|
|
6545
|
-
"input",
|
|
6546
|
-
{
|
|
6547
|
-
id,
|
|
6548
|
-
ref: inputRef,
|
|
6549
|
-
type: "text",
|
|
6550
|
-
autoComplete: "off",
|
|
6551
|
-
placeholder,
|
|
6552
|
-
value,
|
|
6553
|
-
disabled,
|
|
6554
|
-
onKeyDown,
|
|
6555
|
-
onChange: (e) => onChange(e.target.value)
|
|
6556
|
-
}
|
|
6557
|
-
)
|
|
6558
|
-
] })
|
|
6559
|
-
] });
|
|
6560
|
-
}
|
|
6561
|
-
|
|
6562
6958
|
// src/components/games/ui/AnswerTray.tsx
|
|
6563
|
-
var
|
|
6959
|
+
var import_jsx_runtime69 = require("react/jsx-runtime");
|
|
6564
6960
|
function AnswerTray({ id, label, placeholder, optionsLabel, options, query, onQuery, onPick, disabled, minQuery = 0 }) {
|
|
6565
6961
|
const needle = query.trim().toLowerCase();
|
|
6566
6962
|
const shown = needle.length < minQuery ? [] : needle ? options.filter((o) => o.name.toLowerCase().includes(needle)) : options;
|
|
6567
|
-
return /* @__PURE__ */ (0,
|
|
6568
|
-
/* @__PURE__ */ (0,
|
|
6963
|
+
return /* @__PURE__ */ (0, import_jsx_runtime69.jsxs)(import_jsx_runtime69.Fragment, { children: [
|
|
6964
|
+
/* @__PURE__ */ (0, import_jsx_runtime69.jsx)(
|
|
6569
6965
|
SearchField,
|
|
6570
6966
|
{
|
|
6571
6967
|
id,
|
|
@@ -6577,9 +6973,9 @@ function AnswerTray({ id, label, placeholder, optionsLabel, options, query, onQu
|
|
|
6577
6973
|
disabled
|
|
6578
6974
|
}
|
|
6579
6975
|
),
|
|
6580
|
-
shown.length > 0 && /* @__PURE__ */ (0,
|
|
6976
|
+
shown.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime69.jsx)("div", { className: "ss-g-tray", role: "listbox", "aria-label": optionsLabel, children: shown.map((o) => {
|
|
6581
6977
|
const { first, last } = splitName(o.name);
|
|
6582
|
-
return /* @__PURE__ */ (0,
|
|
6978
|
+
return /* @__PURE__ */ (0, import_jsx_runtime69.jsxs)(
|
|
6583
6979
|
"button",
|
|
6584
6980
|
{
|
|
6585
6981
|
type: "button",
|
|
@@ -6590,10 +6986,10 @@ function AnswerTray({ id, label, placeholder, optionsLabel, options, query, onQu
|
|
|
6590
6986
|
disabled,
|
|
6591
6987
|
onClick: () => onPick(o.id),
|
|
6592
6988
|
children: [
|
|
6593
|
-
/* @__PURE__ */ (0,
|
|
6594
|
-
/* @__PURE__ */ (0,
|
|
6595
|
-
first && /* @__PURE__ */ (0,
|
|
6596
|
-
/* @__PURE__ */ (0,
|
|
6989
|
+
/* @__PURE__ */ (0, import_jsx_runtime69.jsx)(PlayerAvatar, { className: "ss-g-tray-av", name: o.name, imagePath: o.imagePath }),
|
|
6990
|
+
/* @__PURE__ */ (0, import_jsx_runtime69.jsxs)("span", { className: "ss-g-tray-name", "aria-hidden": "true", children: [
|
|
6991
|
+
first && /* @__PURE__ */ (0, import_jsx_runtime69.jsx)("span", { className: "ss-g-tray-first", children: first }),
|
|
6992
|
+
/* @__PURE__ */ (0, import_jsx_runtime69.jsx)("span", { className: "ss-g-tray-last", children: last })
|
|
6597
6993
|
] })
|
|
6598
6994
|
]
|
|
6599
6995
|
},
|
|
@@ -6604,59 +7000,59 @@ function AnswerTray({ id, label, placeholder, optionsLabel, options, query, onQu
|
|
|
6604
7000
|
}
|
|
6605
7001
|
|
|
6606
7002
|
// src/components/games/ui/FooterBar.tsx
|
|
6607
|
-
var
|
|
7003
|
+
var import_jsx_runtime70 = require("react/jsx-runtime");
|
|
6608
7004
|
function FooterBar({ children }) {
|
|
6609
|
-
return /* @__PURE__ */ (0,
|
|
7005
|
+
return /* @__PURE__ */ (0, import_jsx_runtime70.jsx)("div", { className: "ss-g-footer", children });
|
|
6610
7006
|
}
|
|
6611
7007
|
|
|
6612
7008
|
// src/components/games/ui/Silhouette.tsx
|
|
6613
|
-
var
|
|
7009
|
+
var import_jsx_runtime71 = require("react/jsx-runtime");
|
|
6614
7010
|
function Silhouette({ size, variant = "default" }) {
|
|
6615
|
-
return /* @__PURE__ */ (0,
|
|
6616
|
-
/* @__PURE__ */ (0,
|
|
6617
|
-
/* @__PURE__ */ (0,
|
|
6618
|
-
/* @__PURE__ */ (0,
|
|
7011
|
+
return /* @__PURE__ */ (0, import_jsx_runtime71.jsxs)("span", { className: `ss-g-sil ss-g-sil--${variant}`, style: { width: size, height: size }, "aria-hidden": "true", children: [
|
|
7012
|
+
/* @__PURE__ */ (0, import_jsx_runtime71.jsxs)("svg", { width: size * 0.86, height: size * 0.86, viewBox: "0 0 100 100", children: [
|
|
7013
|
+
/* @__PURE__ */ (0, import_jsx_runtime71.jsx)("circle", { cx: "50", cy: "40", r: "19", fill: "currentColor" }),
|
|
7014
|
+
/* @__PURE__ */ (0, import_jsx_runtime71.jsx)("path", { d: "M12 100c0-23 17-38 38-38s38 15 38 38z", fill: "currentColor" })
|
|
6619
7015
|
] }),
|
|
6620
|
-
variant === "mystery" && /* @__PURE__ */ (0,
|
|
7016
|
+
variant === "mystery" && /* @__PURE__ */ (0, import_jsx_runtime71.jsx)("span", { className: "ss-g-sil-q", children: "?" })
|
|
6621
7017
|
] });
|
|
6622
7018
|
}
|
|
6623
7019
|
|
|
6624
7020
|
// src/components/games/ui/GameButton.tsx
|
|
6625
|
-
var
|
|
7021
|
+
var import_jsx_runtime72 = require("react/jsx-runtime");
|
|
6626
7022
|
function GameButton({ variant = "primary", block = false, className, type = "button", ...rest }) {
|
|
6627
7023
|
const cls = `ss-g-btn ss-g-btn--${variant}${block ? " ss-g-btn--block" : ""}${className ? ` ${className}` : ""}`;
|
|
6628
|
-
return /* @__PURE__ */ (0,
|
|
7024
|
+
return /* @__PURE__ */ (0, import_jsx_runtime72.jsx)("button", { type, className: cls, ...rest });
|
|
6629
7025
|
}
|
|
6630
7026
|
|
|
6631
7027
|
// src/components/games/ui/ResultCard.tsx
|
|
6632
|
-
var
|
|
7028
|
+
var import_jsx_runtime73 = require("react/jsx-runtime");
|
|
6633
7029
|
function ResultCard({ tone, title, score, detail, onBack, ui }) {
|
|
6634
|
-
return /* @__PURE__ */ (0,
|
|
6635
|
-
/* @__PURE__ */ (0,
|
|
6636
|
-
score !== void 0 && /* @__PURE__ */ (0,
|
|
6637
|
-
/* @__PURE__ */ (0,
|
|
7030
|
+
return /* @__PURE__ */ (0, import_jsx_runtime73.jsxs)("div", { className: "ss-g-result", "data-tone": tone, role: "status", children: [
|
|
7031
|
+
/* @__PURE__ */ (0, import_jsx_runtime73.jsx)("span", { className: "ss-g-result-title", children: title }),
|
|
7032
|
+
score !== void 0 && /* @__PURE__ */ (0, import_jsx_runtime73.jsxs)("span", { className: "ss-g-result-score", children: [
|
|
7033
|
+
/* @__PURE__ */ (0, import_jsx_runtime73.jsx)("span", { className: "ss-g-result-num", children: score }),
|
|
6638
7034
|
ui.games.unitPts
|
|
6639
7035
|
] }),
|
|
6640
|
-
detail && /* @__PURE__ */ (0,
|
|
6641
|
-
onBack && /* @__PURE__ */ (0,
|
|
7036
|
+
detail && /* @__PURE__ */ (0, import_jsx_runtime73.jsx)("span", { className: "ss-g-result-detail", children: detail }),
|
|
7037
|
+
onBack && /* @__PURE__ */ (0, import_jsx_runtime73.jsx)(GameButton, { variant: "outline", onClick: onBack, children: ui.games.backToGames })
|
|
6642
7038
|
] });
|
|
6643
7039
|
}
|
|
6644
7040
|
|
|
6645
7041
|
// src/components/games/ui/PointsLadderRow.tsx
|
|
6646
|
-
var
|
|
7042
|
+
var import_jsx_runtime74 = require("react/jsx-runtime");
|
|
6647
7043
|
function PointsLadderRow({ ladder, guessesUsed, ui }) {
|
|
6648
7044
|
if (!ladder || ladder.length === 0) return null;
|
|
6649
7045
|
const now = ladder[Math.min(guessesUsed, ladder.length - 1)];
|
|
6650
7046
|
const next = ladder[guessesUsed + 1];
|
|
6651
7047
|
if (now === void 0) return null;
|
|
6652
|
-
return /* @__PURE__ */ (0,
|
|
6653
|
-
/* @__PURE__ */ (0,
|
|
6654
|
-
next !== void 0 && next !== now && /* @__PURE__ */ (0,
|
|
7048
|
+
return /* @__PURE__ */ (0, import_jsx_runtime74.jsxs)("div", { className: "ss-g-worth", "data-testid": "points-ladder", children: [
|
|
7049
|
+
/* @__PURE__ */ (0, import_jsx_runtime74.jsx)("span", { className: "ss-g-worth-now", children: ui.games.worthNow(now) }),
|
|
7050
|
+
next !== void 0 && next !== now && /* @__PURE__ */ (0, import_jsx_runtime74.jsx)("span", { className: "ss-g-worth-next", children: ui.games.worthAfterMiss(next) })
|
|
6655
7051
|
] });
|
|
6656
7052
|
}
|
|
6657
7053
|
|
|
6658
7054
|
// src/components/games/MysteryTigerGame.tsx
|
|
6659
|
-
var
|
|
7055
|
+
var import_jsx_runtime75 = require("react/jsx-runtime");
|
|
6660
7056
|
function parseClientState(json) {
|
|
6661
7057
|
if (!json) return null;
|
|
6662
7058
|
try {
|
|
@@ -6758,8 +7154,8 @@ function MysteryTigerGame({
|
|
|
6758
7154
|
onBack
|
|
6759
7155
|
}) {
|
|
6760
7156
|
const t = ui.games.mysteryTiger;
|
|
6761
|
-
const [query, setQuery] = (0,
|
|
6762
|
-
const inputId = (0,
|
|
7157
|
+
const [query, setQuery] = (0, import_react44.useState)("");
|
|
7158
|
+
const inputId = (0, import_react44.useId)();
|
|
6763
7159
|
const clientState = parseClientState(result?.clientStateJson);
|
|
6764
7160
|
const guessResults = clientState?.guessResults ?? [];
|
|
6765
7161
|
const alreadyGuessedIds = new Set(guessResults.map((g) => g.playerId));
|
|
@@ -6778,22 +7174,22 @@ function MysteryTigerGame({
|
|
|
6778
7174
|
setQuery("");
|
|
6779
7175
|
onSubmit(JSON.stringify({ guesses: newGuesses }));
|
|
6780
7176
|
}
|
|
6781
|
-
const headerRight = !config ? void 0 : isOver ? /* @__PURE__ */ (0,
|
|
7177
|
+
const headerRight = !config ? void 0 : isOver ? /* @__PURE__ */ (0, import_jsx_runtime75.jsxs)(Chip, { variant: "accent", children: [
|
|
6782
7178
|
score,
|
|
6783
7179
|
" ",
|
|
6784
7180
|
ui.games.unitPts
|
|
6785
|
-
] }) : /* @__PURE__ */ (0,
|
|
7181
|
+
] }) : /* @__PURE__ */ (0, import_jsx_runtime75.jsx)("span", { "data-testid": "mt-chip", children: /* @__PURE__ */ (0, import_jsx_runtime75.jsxs)(Chip, { children: [
|
|
6786
7182
|
ui.games.guess,
|
|
6787
7183
|
" ",
|
|
6788
|
-
/* @__PURE__ */ (0,
|
|
7184
|
+
/* @__PURE__ */ (0, import_jsx_runtime75.jsx)("span", { className: "ss-g-num", children: guessesUsed + 1 }),
|
|
6789
7185
|
" / ",
|
|
6790
7186
|
totalGuesses
|
|
6791
7187
|
] }) });
|
|
6792
7188
|
const segments = Array.from({ length: totalGuesses }, (_, i) => i < guessesUsed ? "done" : i === guessesUsed ? "current" : "todo");
|
|
6793
7189
|
const cols = { gridTemplateColumns: `minmax(0, 1fr) repeat(${keys.length}, 42px)` };
|
|
6794
7190
|
const known = deriveKnownAttributes(guessResults, keys);
|
|
6795
|
-
return /* @__PURE__ */ (0,
|
|
6796
|
-
/* @__PURE__ */ (0,
|
|
7191
|
+
return /* @__PURE__ */ (0, import_jsx_runtime75.jsxs)("div", { className: "ss-g-screen ss-g-mt", "data-game": "mystery-tiger", "data-testid": "game-screen-mystery-tiger", children: [
|
|
7192
|
+
/* @__PURE__ */ (0, import_jsx_runtime75.jsx)(
|
|
6797
7193
|
GameHeader,
|
|
6798
7194
|
{
|
|
6799
7195
|
title: gameTitle({ gameId: "mystery-tiger" }, ui.games.titles),
|
|
@@ -6803,41 +7199,41 @@ function MysteryTigerGame({
|
|
|
6803
7199
|
backLabel: ui.back
|
|
6804
7200
|
}
|
|
6805
7201
|
),
|
|
6806
|
-
!config && /* @__PURE__ */ (0,
|
|
6807
|
-
config && /* @__PURE__ */ (0,
|
|
6808
|
-
/* @__PURE__ */ (0,
|
|
6809
|
-
!isOver && /* @__PURE__ */ (0,
|
|
6810
|
-
/* @__PURE__ */ (0,
|
|
6811
|
-
/* @__PURE__ */ (0,
|
|
6812
|
-
revealName ? /* @__PURE__ */ (0,
|
|
6813
|
-
revealName && /* @__PURE__ */ (0,
|
|
7202
|
+
!config && /* @__PURE__ */ (0, import_jsx_runtime75.jsx)("div", { className: "ss-g-body ss-g-loading", children: ui.games.loading }),
|
|
7203
|
+
config && /* @__PURE__ */ (0, import_jsx_runtime75.jsxs)(import_jsx_runtime75.Fragment, { children: [
|
|
7204
|
+
/* @__PURE__ */ (0, import_jsx_runtime75.jsxs)("div", { className: "ss-g-body", children: [
|
|
7205
|
+
!isOver && /* @__PURE__ */ (0, import_jsx_runtime75.jsx)(PointsLadderRow, { ladder: config.pointsLadder, guessesUsed, ui }),
|
|
7206
|
+
/* @__PURE__ */ (0, import_jsx_runtime75.jsxs)("div", { className: `ss-g-mt-card${isOver ? " ss-g-mt-card--reveal" : ""}`, children: [
|
|
7207
|
+
/* @__PURE__ */ (0, import_jsx_runtime75.jsxs)("div", { className: "ss-g-mt-portrait", children: [
|
|
7208
|
+
revealName ? /* @__PURE__ */ (0, import_jsx_runtime75.jsx)(PlayerAvatar, { className: "ss-g-mt-photo", name: revealName, imagePath: clientState?.revealedPlayerImagePath }) : /* @__PURE__ */ (0, import_jsx_runtime75.jsx)(Silhouette, { size: 150, variant: "mystery" }),
|
|
7209
|
+
revealName && /* @__PURE__ */ (0, import_jsx_runtime75.jsx)("span", { className: "ss-g-mt-reveal-name", children: revealName })
|
|
6814
7210
|
] }),
|
|
6815
|
-
/* @__PURE__ */ (0,
|
|
6816
|
-
/* @__PURE__ */ (0,
|
|
6817
|
-
/* @__PURE__ */ (0,
|
|
7211
|
+
/* @__PURE__ */ (0, import_jsx_runtime75.jsx)("div", { className: "ss-g-mt-known", style: { gridTemplateColumns: `repeat(${keys.length}, minmax(0, 1fr))` }, children: known.map((k) => /* @__PURE__ */ (0, import_jsx_runtime75.jsxs)("div", { className: "ss-g-mt-known-cell", children: [
|
|
7212
|
+
/* @__PURE__ */ (0, import_jsx_runtime75.jsx)("span", { className: "ss-g-mt-lab", children: t.labels[k.key] }),
|
|
7213
|
+
/* @__PURE__ */ (0, import_jsx_runtime75.jsx)("span", { className: "ss-g-mt-known-v", "data-state": k.state, "data-testid": `known-${k.key}`, children: k.text })
|
|
6818
7214
|
] }, k.key)) })
|
|
6819
7215
|
] }),
|
|
6820
|
-
!isOver && /* @__PURE__ */ (0,
|
|
6821
|
-
guessResults.length > 0 && /* @__PURE__ */ (0,
|
|
6822
|
-
/* @__PURE__ */ (0,
|
|
6823
|
-
/* @__PURE__ */ (0,
|
|
6824
|
-
keys.map((k) => /* @__PURE__ */ (0,
|
|
7216
|
+
!isOver && /* @__PURE__ */ (0, import_jsx_runtime75.jsx)(SegmentProgress, { segments, ariaLabel: t.progress(guessesUsed, totalGuesses) }),
|
|
7217
|
+
guessResults.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime75.jsxs)("div", { className: "ss-g-mt-table", children: [
|
|
7218
|
+
/* @__PURE__ */ (0, import_jsx_runtime75.jsxs)("div", { className: "ss-g-mt-thead", style: cols, children: [
|
|
7219
|
+
/* @__PURE__ */ (0, import_jsx_runtime75.jsx)("span", { children: t.yourGuesses }),
|
|
7220
|
+
keys.map((k) => /* @__PURE__ */ (0, import_jsx_runtime75.jsx)("span", { children: t.labels[k] }, k))
|
|
6825
7221
|
] }),
|
|
6826
7222
|
guessResults.map((gr, i) => {
|
|
6827
7223
|
const name = config.squadPlayers.find((p) => p.id === gr.playerId)?.name ?? `#${gr.playerId}`;
|
|
6828
7224
|
const { first, last } = splitName(name);
|
|
6829
|
-
return /* @__PURE__ */ (0,
|
|
6830
|
-
/* @__PURE__ */ (0,
|
|
6831
|
-
/* @__PURE__ */ (0,
|
|
6832
|
-
/* @__PURE__ */ (0,
|
|
6833
|
-
first && /* @__PURE__ */ (0,
|
|
6834
|
-
/* @__PURE__ */ (0,
|
|
7225
|
+
return /* @__PURE__ */ (0, import_jsx_runtime75.jsxs)("div", { className: "ss-g-mt-row", style: cols, children: [
|
|
7226
|
+
/* @__PURE__ */ (0, import_jsx_runtime75.jsxs)("div", { className: "ss-g-mt-who", children: [
|
|
7227
|
+
/* @__PURE__ */ (0, import_jsx_runtime75.jsx)(PlayerAvatar, { className: "ss-g-mt-av", name }),
|
|
7228
|
+
/* @__PURE__ */ (0, import_jsx_runtime75.jsxs)("span", { className: "ss-g-mt-names", children: [
|
|
7229
|
+
first && /* @__PURE__ */ (0, import_jsx_runtime75.jsx)("span", { className: "ss-g-mt-first", children: first }),
|
|
7230
|
+
/* @__PURE__ */ (0, import_jsx_runtime75.jsx)("span", { className: "ss-g-mt-last", children: last })
|
|
6835
7231
|
] })
|
|
6836
7232
|
] }),
|
|
6837
7233
|
keys.map((key) => {
|
|
6838
7234
|
const v = gr[key];
|
|
6839
7235
|
const arrow = directionArrow(v);
|
|
6840
|
-
return /* @__PURE__ */ (0,
|
|
7236
|
+
return /* @__PURE__ */ (0, import_jsx_runtime75.jsxs)(
|
|
6841
7237
|
"div",
|
|
6842
7238
|
{
|
|
6843
7239
|
className: "ss-g-mt-cell",
|
|
@@ -6845,8 +7241,8 @@ function MysteryTigerGame({
|
|
|
6845
7241
|
"data-verdict": v.verdict,
|
|
6846
7242
|
"aria-label": `${t.labels[key]}: ${v.value ?? v.verdict}${v.direction ? ` ${v.direction}` : ""}`,
|
|
6847
7243
|
children: [
|
|
6848
|
-
/* @__PURE__ */ (0,
|
|
6849
|
-
arrow && /* @__PURE__ */ (0,
|
|
7244
|
+
/* @__PURE__ */ (0, import_jsx_runtime75.jsx)("span", { className: "ss-g-mt-cell-v", "aria-hidden": "true", children: tileFace(key, v) }),
|
|
7245
|
+
arrow && /* @__PURE__ */ (0, import_jsx_runtime75.jsx)("span", { className: "ss-g-mt-cell-dir", "aria-hidden": "true", children: arrow })
|
|
6850
7246
|
]
|
|
6851
7247
|
},
|
|
6852
7248
|
key
|
|
@@ -6855,25 +7251,25 @@ function MysteryTigerGame({
|
|
|
6855
7251
|
] }, gr.playerId);
|
|
6856
7252
|
})
|
|
6857
7253
|
] }),
|
|
6858
|
-
!isOver && /* @__PURE__ */ (0,
|
|
6859
|
-
/* @__PURE__ */ (0,
|
|
6860
|
-
/* @__PURE__ */ (0,
|
|
7254
|
+
!isOver && /* @__PURE__ */ (0, import_jsx_runtime75.jsxs)("div", { className: "ss-g-mt-legend", children: [
|
|
7255
|
+
/* @__PURE__ */ (0, import_jsx_runtime75.jsxs)("span", { children: [
|
|
7256
|
+
/* @__PURE__ */ (0, import_jsx_runtime75.jsx)("i", { className: "ss-g-mt-sw", "data-verdict": "exact" }),
|
|
6861
7257
|
t.legendMatch
|
|
6862
7258
|
] }),
|
|
6863
|
-
/* @__PURE__ */ (0,
|
|
6864
|
-
/* @__PURE__ */ (0,
|
|
7259
|
+
/* @__PURE__ */ (0, import_jsx_runtime75.jsxs)("span", { children: [
|
|
7260
|
+
/* @__PURE__ */ (0, import_jsx_runtime75.jsx)("i", { className: "ss-g-mt-sw", "data-verdict": "near" }),
|
|
6865
7261
|
t.legendClose
|
|
6866
7262
|
] }),
|
|
6867
|
-
/* @__PURE__ */ (0,
|
|
7263
|
+
/* @__PURE__ */ (0, import_jsx_runtime75.jsxs)("span", { children: [
|
|
6868
7264
|
"\u25B2 ",
|
|
6869
7265
|
t.legendHigher
|
|
6870
7266
|
] })
|
|
6871
7267
|
] }),
|
|
6872
|
-
clientState?.hintLine && !isOver && /* @__PURE__ */ (0,
|
|
6873
|
-
/* @__PURE__ */ (0,
|
|
6874
|
-
/* @__PURE__ */ (0,
|
|
7268
|
+
clientState?.hintLine && !isOver && /* @__PURE__ */ (0, import_jsx_runtime75.jsxs)("div", { className: "ss-g-mt-hint", children: [
|
|
7269
|
+
/* @__PURE__ */ (0, import_jsx_runtime75.jsx)(IconBulb, {}),
|
|
7270
|
+
/* @__PURE__ */ (0, import_jsx_runtime75.jsx)("span", { children: clientState.hintLine })
|
|
6875
7271
|
] }),
|
|
6876
|
-
isOver && /* @__PURE__ */ (0,
|
|
7272
|
+
isOver && /* @__PURE__ */ (0, import_jsx_runtime75.jsx)(
|
|
6877
7273
|
ResultCard,
|
|
6878
7274
|
{
|
|
6879
7275
|
tone: clientState?.solved ? "win" : clientState?.failed ? "lose" : "neutral",
|
|
@@ -6885,7 +7281,7 @@ function MysteryTigerGame({
|
|
|
6885
7281
|
}
|
|
6886
7282
|
)
|
|
6887
7283
|
] }),
|
|
6888
|
-
!isOver && /* @__PURE__ */ (0,
|
|
7284
|
+
!isOver && /* @__PURE__ */ (0, import_jsx_runtime75.jsx)(FooterBar, { children: /* @__PURE__ */ (0, import_jsx_runtime75.jsx)(
|
|
6889
7285
|
AnswerTray,
|
|
6890
7286
|
{
|
|
6891
7287
|
id: inputId,
|
|
@@ -6904,7 +7300,7 @@ function MysteryTigerGame({
|
|
|
6904
7300
|
}
|
|
6905
7301
|
|
|
6906
7302
|
// src/components/games/HigherOrLowerGame.tsx
|
|
6907
|
-
var
|
|
7303
|
+
var import_jsx_runtime76 = require("react/jsx-runtime");
|
|
6908
7304
|
var POINTS_PER_CORRECT = 10;
|
|
6909
7305
|
function parseClientState2(json) {
|
|
6910
7306
|
if (!json) return null;
|
|
@@ -6916,11 +7312,11 @@ function parseClientState2(json) {
|
|
|
6916
7312
|
}
|
|
6917
7313
|
function PlayerCard({ name, imagePath, highlight, children }) {
|
|
6918
7314
|
const { first, last } = splitName(name);
|
|
6919
|
-
return /* @__PURE__ */ (0,
|
|
6920
|
-
/* @__PURE__ */ (0,
|
|
6921
|
-
/* @__PURE__ */ (0,
|
|
6922
|
-
first && /* @__PURE__ */ (0,
|
|
6923
|
-
/* @__PURE__ */ (0,
|
|
7315
|
+
return /* @__PURE__ */ (0, import_jsx_runtime76.jsxs)("div", { className: `ss-g-hl-card${highlight ? " ss-g-hl-card--b" : ""}`, children: [
|
|
7316
|
+
/* @__PURE__ */ (0, import_jsx_runtime76.jsx)("div", { className: "ss-g-hl-photo-wrap", children: imagePath ? /* @__PURE__ */ (0, import_jsx_runtime76.jsx)(PlayerAvatar, { className: "ss-g-hl-photo", name, imagePath }) : /* @__PURE__ */ (0, import_jsx_runtime76.jsx)(Silhouette, { size: 150 }) }),
|
|
7317
|
+
/* @__PURE__ */ (0, import_jsx_runtime76.jsxs)("div", { className: "ss-g-hl-info", children: [
|
|
7318
|
+
first && /* @__PURE__ */ (0, import_jsx_runtime76.jsx)("span", { className: "ss-g-hl-first", children: first }),
|
|
7319
|
+
/* @__PURE__ */ (0, import_jsx_runtime76.jsx)("span", { className: "ss-g-hl-surname", children: last }),
|
|
6924
7320
|
children
|
|
6925
7321
|
] })
|
|
6926
7322
|
] });
|
|
@@ -6952,47 +7348,47 @@ function HigherOrLowerGame({
|
|
|
6952
7348
|
const newAnswers = [...prevAnswers, { pairIndex: currentPair.pairIndex, pick }];
|
|
6953
7349
|
onSubmit(JSON.stringify({ answers: newAnswers }));
|
|
6954
7350
|
}
|
|
6955
|
-
return /* @__PURE__ */ (0,
|
|
6956
|
-
/* @__PURE__ */ (0,
|
|
7351
|
+
return /* @__PURE__ */ (0, import_jsx_runtime76.jsxs)("div", { className: "ss-g-screen ss-g-hl", "data-game": "higher-or-lower", "data-testid": "game-screen-higher-or-lower", children: [
|
|
7352
|
+
/* @__PURE__ */ (0, import_jsx_runtime76.jsx)(
|
|
6957
7353
|
GameHeader,
|
|
6958
7354
|
{
|
|
6959
7355
|
title: gameTitle({ gameId: "higher-or-lower" }, ui.games.titles),
|
|
6960
7356
|
eyebrow: t.eyebrow(POINTS_PER_CORRECT),
|
|
6961
|
-
right: config ? /* @__PURE__ */ (0,
|
|
7357
|
+
right: config ? /* @__PURE__ */ (0, import_jsx_runtime76.jsx)(StatStack, { value: runLength, label: t.streak }) : void 0,
|
|
6962
7358
|
onBack,
|
|
6963
7359
|
backLabel: ui.back
|
|
6964
7360
|
}
|
|
6965
7361
|
),
|
|
6966
|
-
!config && /* @__PURE__ */ (0,
|
|
6967
|
-
config && /* @__PURE__ */ (0,
|
|
6968
|
-
/* @__PURE__ */ (0,
|
|
6969
|
-
/* @__PURE__ */ (0,
|
|
6970
|
-
/* @__PURE__ */ (0,
|
|
6971
|
-
/* @__PURE__ */ (0,
|
|
6972
|
-
/* @__PURE__ */ (0,
|
|
7362
|
+
!config && /* @__PURE__ */ (0, import_jsx_runtime76.jsx)("div", { className: "ss-g-body ss-g-loading", children: ui.games.loading }),
|
|
7363
|
+
config && /* @__PURE__ */ (0, import_jsx_runtime76.jsxs)(import_jsx_runtime76.Fragment, { children: [
|
|
7364
|
+
/* @__PURE__ */ (0, import_jsx_runtime76.jsxs)("div", { className: "ss-g-body", children: [
|
|
7365
|
+
/* @__PURE__ */ (0, import_jsx_runtime76.jsxs)("div", { className: "ss-g-hl-prompt", "data-testid": "hol-prompt", children: [
|
|
7366
|
+
/* @__PURE__ */ (0, import_jsx_runtime76.jsx)("span", { className: "ss-g-hl-prompt-q", children: t.whoHadMore }),
|
|
7367
|
+
/* @__PURE__ */ (0, import_jsx_runtime76.jsx)("span", { className: "ss-g-hl-prompt-stat", children: config.statLabel }),
|
|
7368
|
+
/* @__PURE__ */ (0, import_jsx_runtime76.jsx)("span", { className: "ss-g-hl-prompt-season", children: t.season(config.seasonLabel) })
|
|
6973
7369
|
] }),
|
|
6974
|
-
currentPair && /* @__PURE__ */ (0,
|
|
6975
|
-
/* @__PURE__ */ (0,
|
|
6976
|
-
/* @__PURE__ */ (0,
|
|
6977
|
-
/* @__PURE__ */ (0,
|
|
7370
|
+
currentPair && /* @__PURE__ */ (0, import_jsx_runtime76.jsxs)("div", { className: "ss-g-hl-pair", children: [
|
|
7371
|
+
/* @__PURE__ */ (0, import_jsx_runtime76.jsxs)(PlayerCard, { name: currentPair.playerAName, imagePath: currentPair.playerAImagePath, children: [
|
|
7372
|
+
/* @__PURE__ */ (0, import_jsx_runtime76.jsx)("span", { className: "ss-g-hl-value", children: currentPair.playerAValue }),
|
|
7373
|
+
/* @__PURE__ */ (0, import_jsx_runtime76.jsx)("span", { className: "ss-g-hl-stat", children: config.statLabel })
|
|
6978
7374
|
] }),
|
|
6979
|
-
/* @__PURE__ */ (0,
|
|
6980
|
-
/* @__PURE__ */ (0,
|
|
6981
|
-
/* @__PURE__ */ (0,
|
|
6982
|
-
/* @__PURE__ */ (0,
|
|
7375
|
+
/* @__PURE__ */ (0, import_jsx_runtime76.jsx)("span", { className: "ss-g-hl-vs", "aria-hidden": "true", children: t.vs }),
|
|
7376
|
+
/* @__PURE__ */ (0, import_jsx_runtime76.jsx)(PlayerCard, { name: currentPair.playerBName, imagePath: currentPair.playerBImagePath, highlight: true, children: /* @__PURE__ */ (0, import_jsx_runtime76.jsxs)("div", { className: "ss-g-hl-btns", children: [
|
|
7377
|
+
/* @__PURE__ */ (0, import_jsx_runtime76.jsxs)(GameButton, { variant: "primary", disabled: submitting, onClick: () => handlePick("higher"), children: [
|
|
7378
|
+
/* @__PURE__ */ (0, import_jsx_runtime76.jsx)(IconArrowUp, { size: 16 }),
|
|
6983
7379
|
t.higher
|
|
6984
7380
|
] }),
|
|
6985
|
-
/* @__PURE__ */ (0,
|
|
6986
|
-
/* @__PURE__ */ (0,
|
|
7381
|
+
/* @__PURE__ */ (0, import_jsx_runtime76.jsxs)(GameButton, { variant: "outline", disabled: submitting, onClick: () => handlePick("lower"), children: [
|
|
7382
|
+
/* @__PURE__ */ (0, import_jsx_runtime76.jsx)(IconArrowDown, { size: 16 }),
|
|
6987
7383
|
t.lower
|
|
6988
7384
|
] })
|
|
6989
7385
|
] }) })
|
|
6990
7386
|
] }),
|
|
6991
|
-
lastAnswer && lastAnswerPair && /* @__PURE__ */ (0,
|
|
6992
|
-
lastAnswer.wasCorrect ? /* @__PURE__ */ (0,
|
|
7387
|
+
lastAnswer && lastAnswerPair && /* @__PURE__ */ (0, import_jsx_runtime76.jsxs)("p", { className: "ss-g-hl-feedback", "data-testid": "hol-last", "data-correct": lastAnswer.wasCorrect ? "true" : "false", children: [
|
|
7388
|
+
lastAnswer.wasCorrect ? /* @__PURE__ */ (0, import_jsx_runtime76.jsx)(IconCheck, {}) : /* @__PURE__ */ (0, import_jsx_runtime76.jsx)(IconClose, {}),
|
|
6993
7389
|
t.lastAnswer(splitName(lastAnswerPair.playerBName).last, lastAnswer.playerBValue)
|
|
6994
7390
|
] }),
|
|
6995
|
-
isOver && /* @__PURE__ */ (0,
|
|
7391
|
+
isOver && /* @__PURE__ */ (0, import_jsx_runtime76.jsx)(
|
|
6996
7392
|
ResultCard,
|
|
6997
7393
|
{
|
|
6998
7394
|
tone: runEndedWrong ? "lose" : allPairsAnswered ? "win" : "neutral",
|
|
@@ -7004,15 +7400,15 @@ function HigherOrLowerGame({
|
|
|
7004
7400
|
}
|
|
7005
7401
|
)
|
|
7006
7402
|
] }),
|
|
7007
|
-
!isOver && /* @__PURE__ */ (0,
|
|
7008
|
-
/* @__PURE__ */ (0,
|
|
7403
|
+
!isOver && /* @__PURE__ */ (0, import_jsx_runtime76.jsx)(FooterBar, { children: /* @__PURE__ */ (0, import_jsx_runtime76.jsxs)("div", { className: "ss-g-hl-foot", children: [
|
|
7404
|
+
/* @__PURE__ */ (0, import_jsx_runtime76.jsx)("div", { className: "ss-g-hl-dots", role: "img", "aria-label": t.answersSoFar(answeredCount, config.pairs.length), children: config.pairs.map((p, i) => {
|
|
7009
7405
|
const a = answeredPairs[i];
|
|
7010
|
-
return /* @__PURE__ */ (0,
|
|
7406
|
+
return /* @__PURE__ */ (0, import_jsx_runtime76.jsx)("span", { className: "ss-g-hl-dot", "data-state": a ? a.wasCorrect ? "correct" : "wrong" : "todo" }, p.pairIndex);
|
|
7011
7407
|
}) }),
|
|
7012
|
-
/* @__PURE__ */ (0,
|
|
7013
|
-
/* @__PURE__ */ (0,
|
|
7408
|
+
/* @__PURE__ */ (0, import_jsx_runtime76.jsxs)("span", { className: "ss-g-hl-pts", children: [
|
|
7409
|
+
/* @__PURE__ */ (0, import_jsx_runtime76.jsx)("span", { "data-testid": "hol-score", children: score }),
|
|
7014
7410
|
" ",
|
|
7015
|
-
/* @__PURE__ */ (0,
|
|
7411
|
+
/* @__PURE__ */ (0, import_jsx_runtime76.jsx)("span", { className: "ss-g-hl-pts-unit", children: ui.games.unitPts })
|
|
7016
7412
|
] })
|
|
7017
7413
|
] }) })
|
|
7018
7414
|
] })
|
|
@@ -7020,21 +7416,21 @@ function HigherOrLowerGame({
|
|
|
7020
7416
|
}
|
|
7021
7417
|
|
|
7022
7418
|
// src/components/games/CareerPathGame.tsx
|
|
7023
|
-
var
|
|
7419
|
+
var import_react46 = require("react");
|
|
7024
7420
|
|
|
7025
7421
|
// src/components/games/ui/CrestShield.tsx
|
|
7026
|
-
var
|
|
7027
|
-
var
|
|
7422
|
+
var import_react45 = require("react");
|
|
7423
|
+
var import_jsx_runtime77 = require("react/jsx-runtime");
|
|
7028
7424
|
function CrestShield({ src, name, size = 28 }) {
|
|
7029
|
-
const [failed, setFailed] = (0,
|
|
7425
|
+
const [failed, setFailed] = (0, import_react45.useState)(false);
|
|
7030
7426
|
if (src && !isPlaceholderImage(src) && !failed) {
|
|
7031
|
-
return /* @__PURE__ */ (0,
|
|
7427
|
+
return /* @__PURE__ */ (0, import_jsx_runtime77.jsx)("img", { className: "ss-g-crest", src, alt: name, width: size, height: size, loading: "lazy", onError: () => setFailed(true) });
|
|
7032
7428
|
}
|
|
7033
|
-
return /* @__PURE__ */ (0,
|
|
7429
|
+
return /* @__PURE__ */ (0, import_jsx_runtime77.jsx)("svg", { className: "ss-g-crest ss-g-crest--ph", width: size, height: size * 32 / 28, viewBox: "0 0 28 32", role: "img", "aria-label": name, children: /* @__PURE__ */ (0, import_jsx_runtime77.jsx)("path", { d: "M2 3h24v12c0 9-6 14-12 17C8 29 2 24 2 15z", fill: "currentColor" }) });
|
|
7034
7430
|
}
|
|
7035
7431
|
|
|
7036
7432
|
// src/components/games/CareerPathGame.tsx
|
|
7037
|
-
var
|
|
7433
|
+
var import_jsx_runtime78 = require("react/jsx-runtime");
|
|
7038
7434
|
function parseClientState3(json) {
|
|
7039
7435
|
if (!json) return null;
|
|
7040
7436
|
try {
|
|
@@ -7058,15 +7454,15 @@ function CareerPathGame({
|
|
|
7058
7454
|
}) {
|
|
7059
7455
|
const s = ui.games.careerPath;
|
|
7060
7456
|
const title = gameTitle({ gameId: "career-path" }, ui.games.titles);
|
|
7061
|
-
const [query, setQuery] = (0,
|
|
7062
|
-
const inputId = (0,
|
|
7457
|
+
const [query, setQuery] = (0, import_react46.useState)("");
|
|
7458
|
+
const inputId = (0, import_react46.useId)();
|
|
7063
7459
|
const clientState = parseClientState3(result?.clientStateJson);
|
|
7064
7460
|
const alreadyGuessedIds = new Set(clientState?.guessResults.map((g) => g.playerId) ?? []);
|
|
7065
7461
|
const isOver = result?.alreadyPlayed === true || clientState?.solved === true || clientState?.failed === true;
|
|
7066
7462
|
if (!config) {
|
|
7067
|
-
return /* @__PURE__ */ (0,
|
|
7068
|
-
/* @__PURE__ */ (0,
|
|
7069
|
-
/* @__PURE__ */ (0,
|
|
7463
|
+
return /* @__PURE__ */ (0, import_jsx_runtime78.jsxs)("div", { className: "ss-g-screen", "data-game": "career-path", "data-testid": "game-screen-career-path", children: [
|
|
7464
|
+
/* @__PURE__ */ (0, import_jsx_runtime78.jsx)(GameHeader, { title, eyebrow: s.eyebrow, onBack, backLabel: ui.back }),
|
|
7465
|
+
/* @__PURE__ */ (0, import_jsx_runtime78.jsx)("div", { className: "ss-g-body ss-g-loading", children: ui.games.loading })
|
|
7070
7466
|
] });
|
|
7071
7467
|
}
|
|
7072
7468
|
const visiblePath = clientState?.visiblePath ?? config.initialPath;
|
|
@@ -7080,61 +7476,61 @@ function CareerPathGame({
|
|
|
7080
7476
|
setQuery("");
|
|
7081
7477
|
onSubmit(JSON.stringify({ guesses: newGuesses }));
|
|
7082
7478
|
}
|
|
7083
|
-
const right = !isOver && clientState ? /* @__PURE__ */ (0,
|
|
7479
|
+
const right = !isOver && clientState ? /* @__PURE__ */ (0, import_jsx_runtime78.jsx)("span", { "data-testid": "cp-guess-chip", children: /* @__PURE__ */ (0, import_jsx_runtime78.jsxs)(Chip, { variant: "neutral", children: [
|
|
7084
7480
|
ui.games.guess,
|
|
7085
7481
|
" ",
|
|
7086
|
-
/* @__PURE__ */ (0,
|
|
7482
|
+
/* @__PURE__ */ (0, import_jsx_runtime78.jsx)("span", { className: "ss-g-num", children: clientState.guessesUsed + 1 }),
|
|
7087
7483
|
" / ",
|
|
7088
7484
|
clientState.guessesUsed + clientState.guessesRemaining
|
|
7089
7485
|
] }) }) : void 0;
|
|
7090
7486
|
const outcome = clientState?.solved ? s.solved : clientState?.failed ? s.failed : ui.games.done;
|
|
7091
|
-
return /* @__PURE__ */ (0,
|
|
7092
|
-
/* @__PURE__ */ (0,
|
|
7093
|
-
/* @__PURE__ */ (0,
|
|
7094
|
-
!isOver && /* @__PURE__ */ (0,
|
|
7095
|
-
/* @__PURE__ */ (0,
|
|
7096
|
-
isOver && clientState?.revealedPlayerName ? /* @__PURE__ */ (0,
|
|
7097
|
-
/* @__PURE__ */ (0,
|
|
7098
|
-
/* @__PURE__ */ (0,
|
|
7099
|
-
clientState?.hintLine ? /* @__PURE__ */ (0,
|
|
7100
|
-
/* @__PURE__ */ (0,
|
|
7101
|
-
/* @__PURE__ */ (0,
|
|
7487
|
+
return /* @__PURE__ */ (0, import_jsx_runtime78.jsxs)("div", { className: "ss-g-screen", "data-game": "career-path", "data-testid": "game-screen-career-path", children: [
|
|
7488
|
+
/* @__PURE__ */ (0, import_jsx_runtime78.jsx)(GameHeader, { title, eyebrow: s.eyebrow, right, onBack, backLabel: ui.back }),
|
|
7489
|
+
/* @__PURE__ */ (0, import_jsx_runtime78.jsxs)("div", { className: "ss-g-body", children: [
|
|
7490
|
+
!isOver && /* @__PURE__ */ (0, import_jsx_runtime78.jsx)(PointsLadderRow, { ladder: config.pointsLadder, guessesUsed: clientState?.guessesUsed ?? 0, ui }),
|
|
7491
|
+
/* @__PURE__ */ (0, import_jsx_runtime78.jsxs)("div", { className: "ss-g-cp-card", children: [
|
|
7492
|
+
isOver && clientState?.revealedPlayerName ? /* @__PURE__ */ (0, import_jsx_runtime78.jsx)(PlayerAvatar, { className: "ss-g-cp-photo", name: clientState.revealedPlayerName, imagePath: clientState.revealedPlayerImagePath }) : /* @__PURE__ */ (0, import_jsx_runtime78.jsx)(Silhouette, { size: 64, variant: isOver ? "default" : "mystery" }),
|
|
7493
|
+
/* @__PURE__ */ (0, import_jsx_runtime78.jsxs)("div", { className: "ss-g-cp-card-text", children: [
|
|
7494
|
+
/* @__PURE__ */ (0, import_jsx_runtime78.jsx)("span", { className: "ss-g-cp-card-title", children: isOver && clientState?.revealedPlayerName ? clientState.revealedPlayerName : s.mysteryPlayer }),
|
|
7495
|
+
clientState?.hintLine ? /* @__PURE__ */ (0, import_jsx_runtime78.jsx)("span", { className: "ss-g-cp-hint", children: clientState.hintLine }) : !isOver ? /* @__PURE__ */ (0, import_jsx_runtime78.jsxs)("span", { className: "ss-g-cp-locks", children: [
|
|
7496
|
+
/* @__PURE__ */ (0, import_jsx_runtime78.jsx)(Chip, { variant: "lock", icon: /* @__PURE__ */ (0, import_jsx_runtime78.jsx)(IconLock, { size: 11 }), children: s.lockPosition }),
|
|
7497
|
+
/* @__PURE__ */ (0, import_jsx_runtime78.jsx)(Chip, { variant: "lock", icon: /* @__PURE__ */ (0, import_jsx_runtime78.jsx)(IconLock, { size: 11 }), children: s.lockNationality })
|
|
7102
7498
|
] }) : null
|
|
7103
7499
|
] })
|
|
7104
7500
|
] }),
|
|
7105
|
-
/* @__PURE__ */ (0,
|
|
7501
|
+
/* @__PURE__ */ (0, import_jsx_runtime78.jsxs)("ol", { className: "ss-g-cp-line", children: [
|
|
7106
7502
|
visiblePath.map((spell, i) => {
|
|
7107
7503
|
const years = i === 0 ? s.firstClub : spellYears(spell);
|
|
7108
|
-
return /* @__PURE__ */ (0,
|
|
7109
|
-
/* @__PURE__ */ (0,
|
|
7110
|
-
/* @__PURE__ */ (0,
|
|
7111
|
-
/* @__PURE__ */ (0,
|
|
7504
|
+
return /* @__PURE__ */ (0, import_jsx_runtime78.jsxs)("li", { className: "ss-g-cp-step", children: [
|
|
7505
|
+
/* @__PURE__ */ (0, import_jsx_runtime78.jsxs)("span", { className: "ss-g-cp-rail", children: [
|
|
7506
|
+
/* @__PURE__ */ (0, import_jsx_runtime78.jsx)("span", { className: "ss-g-cp-tile", children: /* @__PURE__ */ (0, import_jsx_runtime78.jsx)(CrestShield, { src: spell.crestUrl, name: spell.clubName, size: 30 }) }),
|
|
7507
|
+
/* @__PURE__ */ (0, import_jsx_runtime78.jsx)("span", { className: "ss-g-cp-conn", "aria-hidden": "true" })
|
|
7112
7508
|
] }),
|
|
7113
|
-
/* @__PURE__ */ (0,
|
|
7114
|
-
/* @__PURE__ */ (0,
|
|
7115
|
-
/* @__PURE__ */ (0,
|
|
7116
|
-
/* @__PURE__ */ (0,
|
|
7117
|
-
spell.isLoan && /* @__PURE__ */ (0,
|
|
7509
|
+
/* @__PURE__ */ (0, import_jsx_runtime78.jsxs)("span", { className: "ss-g-cp-step-text", children: [
|
|
7510
|
+
/* @__PURE__ */ (0, import_jsx_runtime78.jsx)("span", { className: "ss-g-cp-club", children: spell.clubName }),
|
|
7511
|
+
/* @__PURE__ */ (0, import_jsx_runtime78.jsxs)("span", { className: "ss-g-cp-sub", children: [
|
|
7512
|
+
/* @__PURE__ */ (0, import_jsx_runtime78.jsx)("span", { className: "ss-g-cp-years", children: years }),
|
|
7513
|
+
spell.isLoan && /* @__PURE__ */ (0, import_jsx_runtime78.jsxs)(import_jsx_runtime78.Fragment, { children: [
|
|
7118
7514
|
years ? " \xB7 " : "",
|
|
7119
|
-
/* @__PURE__ */ (0,
|
|
7515
|
+
/* @__PURE__ */ (0, import_jsx_runtime78.jsx)("span", { className: "ss-g-cp-loan", children: s.loan })
|
|
7120
7516
|
] })
|
|
7121
7517
|
] })
|
|
7122
7518
|
] })
|
|
7123
7519
|
] }, `${spell.clubName}-${i}`);
|
|
7124
7520
|
}),
|
|
7125
|
-
hidden > 0 && /* @__PURE__ */ (0,
|
|
7126
|
-
/* @__PURE__ */ (0,
|
|
7127
|
-
/* @__PURE__ */ (0,
|
|
7128
|
-
hidden > 1 && /* @__PURE__ */ (0,
|
|
7521
|
+
hidden > 0 && /* @__PURE__ */ (0, import_jsx_runtime78.jsxs)("li", { className: "ss-g-cp-step ss-g-cp-step--hidden", children: [
|
|
7522
|
+
/* @__PURE__ */ (0, import_jsx_runtime78.jsxs)("span", { className: "ss-g-cp-rail", children: [
|
|
7523
|
+
/* @__PURE__ */ (0, import_jsx_runtime78.jsx)("span", { className: "ss-g-cp-tile ss-g-cp-tile--locked", children: /* @__PURE__ */ (0, import_jsx_runtime78.jsx)(IconLock, { size: 18 }) }),
|
|
7524
|
+
hidden > 1 && /* @__PURE__ */ (0, import_jsx_runtime78.jsx)("span", { className: "ss-g-cp-conn ss-g-cp-conn--faint", "aria-hidden": "true" })
|
|
7129
7525
|
] }),
|
|
7130
|
-
/* @__PURE__ */ (0,
|
|
7526
|
+
/* @__PURE__ */ (0, import_jsx_runtime78.jsx)("span", { className: "ss-g-cp-step-text", children: /* @__PURE__ */ (0, import_jsx_runtime78.jsx)("span", { className: "ss-g-cp-sub", children: s.nextClubHidden }) })
|
|
7131
7527
|
] }),
|
|
7132
|
-
hidden > 1 && /* @__PURE__ */ (0,
|
|
7133
|
-
/* @__PURE__ */ (0,
|
|
7134
|
-
/* @__PURE__ */ (0,
|
|
7528
|
+
hidden > 1 && /* @__PURE__ */ (0, import_jsx_runtime78.jsxs)("li", { className: "ss-g-cp-step ss-g-cp-step--more", children: [
|
|
7529
|
+
/* @__PURE__ */ (0, import_jsx_runtime78.jsx)("span", { className: "ss-g-cp-rail", children: /* @__PURE__ */ (0, import_jsx_runtime78.jsx)("span", { className: "ss-g-cp-tile ss-g-cp-tile--faint", children: /* @__PURE__ */ (0, import_jsx_runtime78.jsx)(IconLock, { size: 18 }) }) }),
|
|
7530
|
+
/* @__PURE__ */ (0, import_jsx_runtime78.jsx)("span", { className: "ss-g-cp-step-text", children: /* @__PURE__ */ (0, import_jsx_runtime78.jsx)("span", { className: "ss-g-cp-sub", children: s.moreClubs(hidden - 1) }) })
|
|
7135
7531
|
] })
|
|
7136
7532
|
] }),
|
|
7137
|
-
isOver && /* @__PURE__ */ (0,
|
|
7533
|
+
isOver && /* @__PURE__ */ (0, import_jsx_runtime78.jsx)(
|
|
7138
7534
|
ResultCard,
|
|
7139
7535
|
{
|
|
7140
7536
|
tone: clientState?.solved ? "win" : clientState?.failed ? "lose" : "neutral",
|
|
@@ -7146,7 +7542,7 @@ function CareerPathGame({
|
|
|
7146
7542
|
}
|
|
7147
7543
|
)
|
|
7148
7544
|
] }),
|
|
7149
|
-
!isOver && /* @__PURE__ */ (0,
|
|
7545
|
+
!isOver && /* @__PURE__ */ (0, import_jsx_runtime78.jsx)(FooterBar, { children: /* @__PURE__ */ (0, import_jsx_runtime78.jsx)(
|
|
7150
7546
|
AnswerTray,
|
|
7151
7547
|
{
|
|
7152
7548
|
id: inputId,
|
|
@@ -7165,16 +7561,16 @@ function CareerPathGame({
|
|
|
7165
7561
|
}
|
|
7166
7562
|
|
|
7167
7563
|
// src/components/games/BeatTheGridGame.tsx
|
|
7168
|
-
var
|
|
7564
|
+
var import_react47 = __toESM(require("react"), 1);
|
|
7169
7565
|
|
|
7170
7566
|
// src/components/games/ui/OptionList.tsx
|
|
7171
|
-
var
|
|
7567
|
+
var import_jsx_runtime79 = require("react/jsx-runtime");
|
|
7172
7568
|
function OptionList({ label, options, onPick }) {
|
|
7173
|
-
return /* @__PURE__ */ (0,
|
|
7569
|
+
return /* @__PURE__ */ (0, import_jsx_runtime79.jsx)("div", { className: "ss-g-opts", role: "listbox", "aria-label": label, children: options.map((o) => /* @__PURE__ */ (0, import_jsx_runtime79.jsx)("button", { type: "button", role: "option", "aria-selected": false, className: "ss-g-opt", onClick: () => onPick(o.key), children: o.content }, o.key)) });
|
|
7174
7570
|
}
|
|
7175
7571
|
|
|
7176
7572
|
// src/components/games/BeatTheGridGame.tsx
|
|
7177
|
-
var
|
|
7573
|
+
var import_jsx_runtime80 = require("react/jsx-runtime");
|
|
7178
7574
|
function criterionIconKind(label, key) {
|
|
7179
7575
|
const l = (key ?? label).toLowerCase();
|
|
7180
7576
|
if (l.includes("app")) return "calendar";
|
|
@@ -7192,34 +7588,34 @@ function rowAbbrev(label, map, key) {
|
|
|
7192
7588
|
function CriterionIcon({ kind }) {
|
|
7193
7589
|
switch (kind) {
|
|
7194
7590
|
case "calendar":
|
|
7195
|
-
return /* @__PURE__ */ (0,
|
|
7591
|
+
return /* @__PURE__ */ (0, import_jsx_runtime80.jsx)(IconCalendar, {});
|
|
7196
7592
|
case "ball":
|
|
7197
|
-
return /* @__PURE__ */ (0,
|
|
7593
|
+
return /* @__PURE__ */ (0, import_jsx_runtime80.jsx)(IconBall, {});
|
|
7198
7594
|
case "boot":
|
|
7199
|
-
return /* @__PURE__ */ (0,
|
|
7595
|
+
return /* @__PURE__ */ (0, import_jsx_runtime80.jsx)(IconBoot, {});
|
|
7200
7596
|
case "gloves":
|
|
7201
|
-
return /* @__PURE__ */ (0,
|
|
7597
|
+
return /* @__PURE__ */ (0, import_jsx_runtime80.jsx)(IconGloves, {});
|
|
7202
7598
|
case "shield":
|
|
7203
|
-
return /* @__PURE__ */ (0,
|
|
7599
|
+
return /* @__PURE__ */ (0, import_jsx_runtime80.jsx)(IconShield, {});
|
|
7204
7600
|
default:
|
|
7205
|
-
return /* @__PURE__ */ (0,
|
|
7601
|
+
return /* @__PURE__ */ (0, import_jsx_runtime80.jsx)(IconFlag, {});
|
|
7206
7602
|
}
|
|
7207
7603
|
}
|
|
7208
7604
|
function HeaderVisual({ label, textKey: iKey, meta }) {
|
|
7209
7605
|
if (!meta) {
|
|
7210
|
-
return /* @__PURE__ */ (0,
|
|
7606
|
+
return /* @__PURE__ */ (0, import_jsx_runtime80.jsx)(CriterionIcon, { kind: criterionIconKind(label, iKey) });
|
|
7211
7607
|
}
|
|
7212
7608
|
switch (meta.kind) {
|
|
7213
7609
|
case "club":
|
|
7214
|
-
return /* @__PURE__ */ (0,
|
|
7610
|
+
return /* @__PURE__ */ (0, import_jsx_runtime80.jsx)(CrestShield, { src: meta.imageUrl, name: label, size: 24 });
|
|
7215
7611
|
case "coach":
|
|
7216
|
-
return /* @__PURE__ */ (0,
|
|
7612
|
+
return /* @__PURE__ */ (0, import_jsx_runtime80.jsx)(PlayerAvatar, { name: label, imagePath: meta.imageUrl, className: "ss-g-btg-coach-av" });
|
|
7217
7613
|
case "country":
|
|
7218
|
-
return /* @__PURE__ */ (0,
|
|
7614
|
+
return /* @__PURE__ */ (0, import_jsx_runtime80.jsx)("span", { className: "ss-g-btg-hdr-flag", "aria-hidden": "true", children: nationalityFlag(meta.country ?? label) });
|
|
7219
7615
|
case "position":
|
|
7220
|
-
return /* @__PURE__ */ (0,
|
|
7616
|
+
return /* @__PURE__ */ (0, import_jsx_runtime80.jsx)(import_jsx_runtime80.Fragment, {});
|
|
7221
7617
|
default:
|
|
7222
|
-
return /* @__PURE__ */ (0,
|
|
7618
|
+
return /* @__PURE__ */ (0, import_jsx_runtime80.jsx)(CriterionIcon, { kind: criterionIconKind(label, iKey) });
|
|
7223
7619
|
}
|
|
7224
7620
|
}
|
|
7225
7621
|
function parseClientState4(json) {
|
|
@@ -7254,21 +7650,21 @@ function SearchSheet({
|
|
|
7254
7650
|
ui
|
|
7255
7651
|
}) {
|
|
7256
7652
|
const s = ui.games.beatTheGrid;
|
|
7257
|
-
const [query, setQuery] = (0,
|
|
7258
|
-
const inputId = (0,
|
|
7259
|
-
const inputRef = (0,
|
|
7260
|
-
(0,
|
|
7653
|
+
const [query, setQuery] = (0, import_react47.useState)("");
|
|
7654
|
+
const inputId = (0, import_react47.useId)();
|
|
7655
|
+
const inputRef = (0, import_react47.useRef)(null);
|
|
7656
|
+
(0, import_react47.useEffect)(() => {
|
|
7261
7657
|
inputRef.current?.focus();
|
|
7262
7658
|
}, [row, col]);
|
|
7263
7659
|
const filtered = playerPool.filter(
|
|
7264
7660
|
(p) => !alreadyFilledIds.has(p.id) && p.name.toLowerCase().includes(query.toLowerCase())
|
|
7265
7661
|
);
|
|
7266
|
-
return /* @__PURE__ */ (0,
|
|
7267
|
-
/* @__PURE__ */ (0,
|
|
7268
|
-
/* @__PURE__ */ (0,
|
|
7269
|
-
/* @__PURE__ */ (0,
|
|
7270
|
-
/* @__PURE__ */ (0,
|
|
7271
|
-
/* @__PURE__ */ (0,
|
|
7662
|
+
return /* @__PURE__ */ (0, import_jsx_runtime80.jsxs)("div", { className: "ss-g-btg-sheet", "data-testid": "btg-search-sheet", children: [
|
|
7663
|
+
/* @__PURE__ */ (0, import_jsx_runtime80.jsxs)("div", { className: "ss-g-btg-sheet-hdr", children: [
|
|
7664
|
+
/* @__PURE__ */ (0, import_jsx_runtime80.jsx)(Chip, { variant: "neutral", children: rowLabel }),
|
|
7665
|
+
/* @__PURE__ */ (0, import_jsx_runtime80.jsx)("span", { className: "ss-g-btg-sheet-x", "aria-hidden": "true", children: /* @__PURE__ */ (0, import_jsx_runtime80.jsx)(IconClose, { size: 12 }) }),
|
|
7666
|
+
/* @__PURE__ */ (0, import_jsx_runtime80.jsx)(Chip, { variant: "accent", children: colLabel }),
|
|
7667
|
+
/* @__PURE__ */ (0, import_jsx_runtime80.jsx)(
|
|
7272
7668
|
"button",
|
|
7273
7669
|
{
|
|
7274
7670
|
type: "button",
|
|
@@ -7276,12 +7672,12 @@ function SearchSheet({
|
|
|
7276
7672
|
"data-testid": "btg-sheet-dismiss",
|
|
7277
7673
|
"aria-label": s.closeSearch,
|
|
7278
7674
|
onClick: onDismiss,
|
|
7279
|
-
children: /* @__PURE__ */ (0,
|
|
7675
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime80.jsx)(IconClose, {})
|
|
7280
7676
|
}
|
|
7281
7677
|
)
|
|
7282
7678
|
] }),
|
|
7283
|
-
playerPool.length === 0 ? /* @__PURE__ */ (0,
|
|
7284
|
-
/* @__PURE__ */ (0,
|
|
7679
|
+
playerPool.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime80.jsx)("div", { className: "ss-g-btg-sheet-empty", children: s.emptyPool }) : /* @__PURE__ */ (0, import_jsx_runtime80.jsxs)(import_jsx_runtime80.Fragment, { children: [
|
|
7680
|
+
/* @__PURE__ */ (0, import_jsx_runtime80.jsx)(
|
|
7285
7681
|
SearchField,
|
|
7286
7682
|
{
|
|
7287
7683
|
id: inputId,
|
|
@@ -7293,16 +7689,16 @@ function SearchSheet({
|
|
|
7293
7689
|
inputRef
|
|
7294
7690
|
}
|
|
7295
7691
|
),
|
|
7296
|
-
query.length > 0 && filtered.length > 0 && /* @__PURE__ */ (0,
|
|
7692
|
+
query.length > 0 && filtered.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime80.jsx)(
|
|
7297
7693
|
OptionList,
|
|
7298
7694
|
{
|
|
7299
7695
|
label: s.searchLabel(rowLabel, colLabel),
|
|
7300
7696
|
options: filtered.map((p) => ({
|
|
7301
7697
|
key: p.id,
|
|
7302
|
-
content: /* @__PURE__ */ (0,
|
|
7303
|
-
/* @__PURE__ */ (0,
|
|
7304
|
-
/* @__PURE__ */ (0,
|
|
7305
|
-
/* @__PURE__ */ (0,
|
|
7698
|
+
content: /* @__PURE__ */ (0, import_jsx_runtime80.jsxs)(import_jsx_runtime80.Fragment, { children: [
|
|
7699
|
+
/* @__PURE__ */ (0, import_jsx_runtime80.jsx)(PlayerAvatar, { name: p.name, imagePath: p.imagePath, className: "ss-g-opt-av" }),
|
|
7700
|
+
/* @__PURE__ */ (0, import_jsx_runtime80.jsx)("span", { className: "ss-g-btg-result-name", children: p.name }),
|
|
7701
|
+
/* @__PURE__ */ (0, import_jsx_runtime80.jsx)("span", { className: "ss-g-btg-result-plus", "aria-hidden": "true", children: /* @__PURE__ */ (0, import_jsx_runtime80.jsx)(IconPlus, { size: 18 }) })
|
|
7306
7702
|
] })
|
|
7307
7703
|
})),
|
|
7308
7704
|
onPick: (k) => onPick(row, col, Number(k))
|
|
@@ -7322,7 +7718,7 @@ function BeatTheGridGame({
|
|
|
7322
7718
|
}) {
|
|
7323
7719
|
const s = ui.games.beatTheGrid;
|
|
7324
7720
|
const title = gameTitle({ gameId: "beat-the-grid" }, ui.games.titles);
|
|
7325
|
-
const [activeCell, setActiveCell] = (0,
|
|
7721
|
+
const [activeCell, setActiveCell] = (0, import_react47.useState)(null);
|
|
7326
7722
|
const clientState = parseClientState4(result?.clientStateJson);
|
|
7327
7723
|
const filledCells = clientState?.cells ?? [];
|
|
7328
7724
|
const isLocked2 = result?.alreadyPlayed === true || clientState?.isComplete === true;
|
|
@@ -7340,9 +7736,9 @@ function BeatTheGridGame({
|
|
|
7340
7736
|
onSubmit(JSON.stringify({ cells: newCells }));
|
|
7341
7737
|
}
|
|
7342
7738
|
if (!config) {
|
|
7343
|
-
return /* @__PURE__ */ (0,
|
|
7344
|
-
/* @__PURE__ */ (0,
|
|
7345
|
-
/* @__PURE__ */ (0,
|
|
7739
|
+
return /* @__PURE__ */ (0, import_jsx_runtime80.jsxs)("div", { className: "ss-g-screen", "data-game": "beat-the-grid", "data-testid": "game-screen-beat-the-grid", children: [
|
|
7740
|
+
/* @__PURE__ */ (0, import_jsx_runtime80.jsx)(GameHeader, { title, eyebrow: s.eyebrow, onBack, backLabel: ui.back }),
|
|
7741
|
+
/* @__PURE__ */ (0, import_jsx_runtime80.jsx)("div", { className: "ss-g-body ss-g-loading", children: ui.games.loading })
|
|
7346
7742
|
] });
|
|
7347
7743
|
}
|
|
7348
7744
|
const rows = config.rows;
|
|
@@ -7355,20 +7751,20 @@ function BeatTheGridGame({
|
|
|
7355
7751
|
(_, i) => i < correctCount ? "correct" : i < correctCount + wrongCount ? "wrong" : "todo"
|
|
7356
7752
|
);
|
|
7357
7753
|
const totalScore = clientState?.totalScore ?? result?.score ?? 0;
|
|
7358
|
-
return /* @__PURE__ */ (0,
|
|
7359
|
-
/* @__PURE__ */ (0,
|
|
7360
|
-
/* @__PURE__ */ (0,
|
|
7754
|
+
return /* @__PURE__ */ (0, import_jsx_runtime80.jsxs)("div", { className: "ss-g-screen", "data-game": "beat-the-grid", "data-testid": "game-screen-beat-the-grid", children: [
|
|
7755
|
+
/* @__PURE__ */ (0, import_jsx_runtime80.jsx)(GameHeader, { title, eyebrow: s.eyebrow, onBack, backLabel: ui.back }),
|
|
7756
|
+
/* @__PURE__ */ (0, import_jsx_runtime80.jsx)(
|
|
7361
7757
|
SegmentProgress,
|
|
7362
7758
|
{
|
|
7363
7759
|
segments,
|
|
7364
7760
|
ariaLabel: s.progressAria(filledCells.length, total),
|
|
7365
7761
|
leftLabel: s.filled(filledCells.length, total),
|
|
7366
7762
|
rightLabel: s.toGo(Math.max(0, total - filledCells.length)),
|
|
7367
|
-
right: /* @__PURE__ */ (0,
|
|
7763
|
+
right: /* @__PURE__ */ (0, import_jsx_runtime80.jsx)(Chip, { variant: "accent", children: `${totalScore} ${ui.games.unitPts}` })
|
|
7368
7764
|
}
|
|
7369
7765
|
),
|
|
7370
|
-
/* @__PURE__ */ (0,
|
|
7371
|
-
/* @__PURE__ */ (0,
|
|
7766
|
+
/* @__PURE__ */ (0, import_jsx_runtime80.jsxs)("div", { className: "ss-g-body", children: [
|
|
7767
|
+
/* @__PURE__ */ (0, import_jsx_runtime80.jsxs)(
|
|
7372
7768
|
"div",
|
|
7373
7769
|
{
|
|
7374
7770
|
className: activeCell !== null ? "ss-g-btg-grid ss-g-btg-grid--fit" : "ss-g-btg-grid",
|
|
@@ -7378,31 +7774,31 @@ function BeatTheGridGame({
|
|
|
7378
7774
|
},
|
|
7379
7775
|
role: "grid",
|
|
7380
7776
|
children: [
|
|
7381
|
-
/* @__PURE__ */ (0,
|
|
7777
|
+
/* @__PURE__ */ (0, import_jsx_runtime80.jsx)("div", { className: "ss-g-btg-corner" }),
|
|
7382
7778
|
cols.map((col, colIdx) => {
|
|
7383
7779
|
const colMeta = config.colsMeta?.[colIdx];
|
|
7384
|
-
return /* @__PURE__ */ (0,
|
|
7385
|
-
/* @__PURE__ */ (0,
|
|
7386
|
-
/* @__PURE__ */ (0,
|
|
7780
|
+
return /* @__PURE__ */ (0, import_jsx_runtime80.jsxs)("div", { className: "ss-g-btg-colhdr", "data-meta": colMeta ? "true" : void 0, children: [
|
|
7781
|
+
/* @__PURE__ */ (0, import_jsx_runtime80.jsx)(HeaderVisual, { label: col, textKey: config.colsI18n?.[colIdx]?.key, meta: colMeta }),
|
|
7782
|
+
/* @__PURE__ */ (0, import_jsx_runtime80.jsx)("span", { children: col })
|
|
7387
7783
|
] }, col);
|
|
7388
7784
|
}),
|
|
7389
7785
|
rows.map((rowLabel, rowIdx) => {
|
|
7390
7786
|
const rowMeta = config.rowsMeta?.[rowIdx];
|
|
7391
7787
|
const abbr = rowAbbrev(rowLabel, s.rowAbbrev, config.rowsI18n?.[rowIdx]?.key);
|
|
7392
|
-
const rowHeaderContent = rowMeta ? /* @__PURE__ */ (0,
|
|
7393
|
-
/* @__PURE__ */ (0,
|
|
7394
|
-
/* @__PURE__ */ (0,
|
|
7395
|
-
] }) : abbr === rowLabel ? /* @__PURE__ */ (0,
|
|
7396
|
-
/* @__PURE__ */ (0,
|
|
7397
|
-
/* @__PURE__ */ (0,
|
|
7788
|
+
const rowHeaderContent = rowMeta ? /* @__PURE__ */ (0, import_jsx_runtime80.jsxs)(import_jsx_runtime80.Fragment, { children: [
|
|
7789
|
+
/* @__PURE__ */ (0, import_jsx_runtime80.jsx)(HeaderVisual, { label: rowLabel, textKey: config.rowsI18n?.[rowIdx]?.key, meta: rowMeta }),
|
|
7790
|
+
/* @__PURE__ */ (0, import_jsx_runtime80.jsx)("span", { children: rowLabel })
|
|
7791
|
+
] }) : abbr === rowLabel ? /* @__PURE__ */ (0, import_jsx_runtime80.jsx)("span", { children: rowLabel }) : /* @__PURE__ */ (0, import_jsx_runtime80.jsxs)(import_jsx_runtime80.Fragment, { children: [
|
|
7792
|
+
/* @__PURE__ */ (0, import_jsx_runtime80.jsx)("span", { "aria-hidden": "true", children: abbr }),
|
|
7793
|
+
/* @__PURE__ */ (0, import_jsx_runtime80.jsx)("span", { className: "ss-g-sr", children: rowLabel })
|
|
7398
7794
|
] });
|
|
7399
|
-
return /* @__PURE__ */ (0,
|
|
7400
|
-
/* @__PURE__ */ (0,
|
|
7795
|
+
return /* @__PURE__ */ (0, import_jsx_runtime80.jsxs)(import_react47.default.Fragment, { children: [
|
|
7796
|
+
/* @__PURE__ */ (0, import_jsx_runtime80.jsx)("div", { className: "ss-g-btg-rowhdr", "data-meta": rowMeta ? "true" : void 0, children: rowHeaderContent }),
|
|
7401
7797
|
cols.map((colLabel, colIdx) => {
|
|
7402
7798
|
const filled = findCellResult(filledCells, rowIdx, colIdx);
|
|
7403
7799
|
const isActive = activeCell?.row === rowIdx && activeCell?.col === colIdx;
|
|
7404
7800
|
const state = filled ? filled.isCorrect ? "correct" : "wrong" : isActive ? "active" : "empty";
|
|
7405
|
-
return /* @__PURE__ */ (0,
|
|
7801
|
+
return /* @__PURE__ */ (0, import_jsx_runtime80.jsx)(
|
|
7406
7802
|
"button",
|
|
7407
7803
|
{
|
|
7408
7804
|
type: "button",
|
|
@@ -7413,20 +7809,20 @@ function BeatTheGridGame({
|
|
|
7413
7809
|
className: "ss-g-btg-cell",
|
|
7414
7810
|
disabled: isLocked2 || submitting,
|
|
7415
7811
|
onClick: () => handleCellClick(rowIdx, colIdx),
|
|
7416
|
-
children: filled ? /* @__PURE__ */ (0,
|
|
7417
|
-
/* @__PURE__ */ (0,
|
|
7812
|
+
children: filled ? /* @__PURE__ */ (0, import_jsx_runtime80.jsxs)(import_jsx_runtime80.Fragment, { children: [
|
|
7813
|
+
/* @__PURE__ */ (0, import_jsx_runtime80.jsx)(
|
|
7418
7814
|
"span",
|
|
7419
7815
|
{
|
|
7420
7816
|
className: `ss-g-btg-badge ss-g-btg-badge--${filled.isCorrect ? "correct" : "wrong"}`,
|
|
7421
7817
|
role: "img",
|
|
7422
7818
|
"aria-label": filled.isCorrect ? s.correct : s.wrong,
|
|
7423
|
-
children: filled.isCorrect ? /* @__PURE__ */ (0,
|
|
7819
|
+
children: filled.isCorrect ? /* @__PURE__ */ (0, import_jsx_runtime80.jsx)(IconCheck, { size: 11 }) : /* @__PURE__ */ (0, import_jsx_runtime80.jsx)(IconClose, { size: 11 })
|
|
7424
7820
|
}
|
|
7425
7821
|
),
|
|
7426
|
-
/* @__PURE__ */ (0,
|
|
7822
|
+
/* @__PURE__ */ (0, import_jsx_runtime80.jsx)("span", { className: "ss-g-btg-rarity", children: filled.rarityScore }),
|
|
7427
7823
|
(() => {
|
|
7428
7824
|
const entry = playerPool.find((p) => p.id === filled.playerId);
|
|
7429
|
-
return /* @__PURE__ */ (0,
|
|
7825
|
+
return /* @__PURE__ */ (0, import_jsx_runtime80.jsx)(
|
|
7430
7826
|
PlayerAvatar,
|
|
7431
7827
|
{
|
|
7432
7828
|
name: entry?.name ?? "",
|
|
@@ -7435,8 +7831,8 @@ function BeatTheGridGame({
|
|
|
7435
7831
|
}
|
|
7436
7832
|
);
|
|
7437
7833
|
})(),
|
|
7438
|
-
/* @__PURE__ */ (0,
|
|
7439
|
-
] }) : /* @__PURE__ */ (0,
|
|
7834
|
+
/* @__PURE__ */ (0, import_jsx_runtime80.jsx)("span", { className: "ss-g-btg-name", children: shortName(playerPool.find((p) => p.id === filled.playerId)?.name) })
|
|
7835
|
+
] }) : /* @__PURE__ */ (0, import_jsx_runtime80.jsx)("span", { className: "ss-g-btg-plus", "aria-hidden": "true", children: /* @__PURE__ */ (0, import_jsx_runtime80.jsx)(IconPlus, { size: 22 }) })
|
|
7440
7836
|
},
|
|
7441
7837
|
`cell-${rowIdx}-${colIdx}`
|
|
7442
7838
|
);
|
|
@@ -7446,7 +7842,7 @@ function BeatTheGridGame({
|
|
|
7446
7842
|
]
|
|
7447
7843
|
}
|
|
7448
7844
|
),
|
|
7449
|
-
isLocked2 && /* @__PURE__ */ (0,
|
|
7845
|
+
isLocked2 && /* @__PURE__ */ (0, import_jsx_runtime80.jsx)(
|
|
7450
7846
|
ResultCard,
|
|
7451
7847
|
{
|
|
7452
7848
|
tone: "neutral",
|
|
@@ -7458,7 +7854,7 @@ function BeatTheGridGame({
|
|
|
7458
7854
|
}
|
|
7459
7855
|
)
|
|
7460
7856
|
] }),
|
|
7461
|
-
activeCell !== null && /* @__PURE__ */ (0,
|
|
7857
|
+
activeCell !== null && /* @__PURE__ */ (0, import_jsx_runtime80.jsx)("div", { className: "ss-g-btg-pin", children: /* @__PURE__ */ (0, import_jsx_runtime80.jsx)(
|
|
7462
7858
|
SearchSheet,
|
|
7463
7859
|
{
|
|
7464
7860
|
row: activeCell.row,
|
|
@@ -7477,21 +7873,21 @@ function BeatTheGridGame({
|
|
|
7477
7873
|
}
|
|
7478
7874
|
|
|
7479
7875
|
// src/components/games/GuessTheXiGame.tsx
|
|
7480
|
-
var
|
|
7876
|
+
var import_react48 = require("react");
|
|
7481
7877
|
|
|
7482
7878
|
// src/components/games/ui/PitchSvg.tsx
|
|
7483
|
-
var
|
|
7879
|
+
var import_jsx_runtime81 = require("react/jsx-runtime");
|
|
7484
7880
|
function PitchSvg({ variant }) {
|
|
7485
|
-
return /* @__PURE__ */ (0,
|
|
7486
|
-
/* @__PURE__ */ (0,
|
|
7487
|
-
variant === "full" ? /* @__PURE__ */ (0,
|
|
7488
|
-
/* @__PURE__ */ (0,
|
|
7489
|
-
/* @__PURE__ */ (0,
|
|
7490
|
-
/* @__PURE__ */ (0,
|
|
7491
|
-
/* @__PURE__ */ (0,
|
|
7492
|
-
] }) : /* @__PURE__ */ (0,
|
|
7493
|
-
/* @__PURE__ */ (0,
|
|
7494
|
-
/* @__PURE__ */ (0,
|
|
7881
|
+
return /* @__PURE__ */ (0, import_jsx_runtime81.jsxs)("svg", { className: "ss-g-pitch-svg", viewBox: variant === "full" ? "0 0 100 150" : "0 0 100 100", preserveAspectRatio: "none", "aria-hidden": "true", children: [
|
|
7882
|
+
/* @__PURE__ */ (0, import_jsx_runtime81.jsx)("rect", { x: "4", y: "4", width: "92", height: variant === "full" ? 142 : 92, fill: "none" }),
|
|
7883
|
+
variant === "full" ? /* @__PURE__ */ (0, import_jsx_runtime81.jsxs)(import_jsx_runtime81.Fragment, { children: [
|
|
7884
|
+
/* @__PURE__ */ (0, import_jsx_runtime81.jsx)("line", { x1: "4", y1: "75", x2: "96", y2: "75" }),
|
|
7885
|
+
/* @__PURE__ */ (0, import_jsx_runtime81.jsx)("circle", { cx: "50", cy: "75", r: "12", fill: "none" }),
|
|
7886
|
+
/* @__PURE__ */ (0, import_jsx_runtime81.jsx)("rect", { x: "26", y: "4", width: "48", height: "20", fill: "none" }),
|
|
7887
|
+
/* @__PURE__ */ (0, import_jsx_runtime81.jsx)("rect", { x: "26", y: "126", width: "48", height: "20", fill: "none" })
|
|
7888
|
+
] }) : /* @__PURE__ */ (0, import_jsx_runtime81.jsxs)(import_jsx_runtime81.Fragment, { children: [
|
|
7889
|
+
/* @__PURE__ */ (0, import_jsx_runtime81.jsx)("path", { d: "M38 4a12 12 0 0 0 24 0", fill: "none" }),
|
|
7890
|
+
/* @__PURE__ */ (0, import_jsx_runtime81.jsx)("rect", { x: "26", y: "76", width: "48", height: "20", fill: "none" })
|
|
7495
7891
|
] })
|
|
7496
7892
|
] });
|
|
7497
7893
|
}
|
|
@@ -7547,7 +7943,7 @@ function positionsBySlot(formation, rowsAttackFirst) {
|
|
|
7547
7943
|
}
|
|
7548
7944
|
|
|
7549
7945
|
// src/components/games/GuessTheXiGame.tsx
|
|
7550
|
-
var
|
|
7946
|
+
var import_jsx_runtime82 = require("react/jsx-runtime");
|
|
7551
7947
|
var MAX_GUESSES2 = 3;
|
|
7552
7948
|
function parseClientState5(json) {
|
|
7553
7949
|
if (!json) return null;
|
|
@@ -7566,8 +7962,8 @@ function GuessTheXiGame({
|
|
|
7566
7962
|
onBack
|
|
7567
7963
|
}) {
|
|
7568
7964
|
const t = ui.games.guessTheXi;
|
|
7569
|
-
const [query, setQuery] = (0,
|
|
7570
|
-
const inputId = (0,
|
|
7965
|
+
const [query, setQuery] = (0, import_react48.useState)("");
|
|
7966
|
+
const inputId = (0, import_react48.useId)();
|
|
7571
7967
|
const clientState = parseClientState5(result?.clientStateJson);
|
|
7572
7968
|
const isOver = result?.alreadyPlayed === true || clientState?.status === "solved" || clientState?.status === "failed";
|
|
7573
7969
|
const solved = clientState?.status === "solved";
|
|
@@ -7597,31 +7993,31 @@ function GuessTheXiGame({
|
|
|
7597
7993
|
const wrongGuesses = (clientState?.guessHistory ?? []).filter((g) => !g.wasCorrect);
|
|
7598
7994
|
const guessesLeft = Math.max(0, MAX_GUESSES2 - (clientState?.guessesUsed ?? 0));
|
|
7599
7995
|
const teamName = (id) => config?.teamPool.find((tm) => tm.teamId === id)?.teamName ?? `#${id}`;
|
|
7600
|
-
return /* @__PURE__ */ (0,
|
|
7601
|
-
/* @__PURE__ */ (0,
|
|
7996
|
+
return /* @__PURE__ */ (0, import_jsx_runtime82.jsxs)("div", { className: "ss-g-screen ss-g-gxi", "data-game": "guess-the-xi", "data-testid": "game-screen-guess-the-xi", children: [
|
|
7997
|
+
/* @__PURE__ */ (0, import_jsx_runtime82.jsx)(
|
|
7602
7998
|
GameHeader,
|
|
7603
7999
|
{
|
|
7604
8000
|
title: gameTitle({ gameId: "guess-the-xi" }, ui.games.titles),
|
|
7605
8001
|
eyebrow: config?.poolLabel,
|
|
7606
|
-
right: formation ? /* @__PURE__ */ (0,
|
|
8002
|
+
right: formation ? /* @__PURE__ */ (0, import_jsx_runtime82.jsx)(Chip, { variant: "accent", children: formation }) : void 0,
|
|
7607
8003
|
onBack,
|
|
7608
8004
|
backLabel: ui.back
|
|
7609
8005
|
}
|
|
7610
8006
|
),
|
|
7611
|
-
!config && /* @__PURE__ */ (0,
|
|
7612
|
-
config && /* @__PURE__ */ (0,
|
|
7613
|
-
/* @__PURE__ */ (0,
|
|
7614
|
-
!isOver && /* @__PURE__ */ (0,
|
|
7615
|
-
rows.length > 0 && /* @__PURE__ */ (0,
|
|
7616
|
-
/* @__PURE__ */ (0,
|
|
7617
|
-
/* @__PURE__ */ (0,
|
|
8007
|
+
!config && /* @__PURE__ */ (0, import_jsx_runtime82.jsx)("div", { className: "ss-g-body ss-g-loading", children: ui.games.loading }),
|
|
8008
|
+
config && /* @__PURE__ */ (0, import_jsx_runtime82.jsxs)(import_jsx_runtime82.Fragment, { children: [
|
|
8009
|
+
/* @__PURE__ */ (0, import_jsx_runtime82.jsxs)("div", { className: "ss-g-body", children: [
|
|
8010
|
+
!isOver && /* @__PURE__ */ (0, import_jsx_runtime82.jsx)(PointsLadderRow, { ladder: config.pointsLadder, guessesUsed: clientState?.guessHistory.length ?? 0, ui }),
|
|
8011
|
+
rows.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime82.jsxs)("div", { className: "ss-g-gxi-pitch", role: "group", "aria-label": t.pitchLabel, children: [
|
|
8012
|
+
/* @__PURE__ */ (0, import_jsx_runtime82.jsx)(PitchSvg, { variant: "full" }),
|
|
8013
|
+
/* @__PURE__ */ (0, import_jsx_runtime82.jsx)("div", { className: "ss-g-gxi-rows", children: rows.map((row, r) => /* @__PURE__ */ (0, import_jsx_runtime82.jsx)("div", { className: "ss-g-gxi-row", children: row.map((pos, c) => {
|
|
7618
8014
|
const posLabel = pos.slot ? posBySlot.get(pos.slot) ?? "" : "";
|
|
7619
8015
|
const name = pos.slot ? nameBySlot.get(pos.slot) : void 0;
|
|
7620
8016
|
const lineupEntry = pos.slot ? lineupBySlot.get(pos.slot) : void 0;
|
|
7621
8017
|
const flag = nationalityFlag(pos.nationality);
|
|
7622
8018
|
if (lineupEntry) {
|
|
7623
|
-
return /* @__PURE__ */ (0,
|
|
7624
|
-
/* @__PURE__ */ (0,
|
|
8019
|
+
return /* @__PURE__ */ (0, import_jsx_runtime82.jsxs)("div", { className: "ss-g-gxi-node", "data-revealed": "true", children: [
|
|
8020
|
+
/* @__PURE__ */ (0, import_jsx_runtime82.jsx)(
|
|
7625
8021
|
PlayerAvatar,
|
|
7626
8022
|
{
|
|
7627
8023
|
name: lineupEntry.name,
|
|
@@ -7629,11 +8025,11 @@ function GuessTheXiGame({
|
|
|
7629
8025
|
className: "ss-g-gxi-disc ss-g-gxi-disc--photo"
|
|
7630
8026
|
}
|
|
7631
8027
|
),
|
|
7632
|
-
/* @__PURE__ */ (0,
|
|
8028
|
+
/* @__PURE__ */ (0, import_jsx_runtime82.jsx)("span", { className: "ss-g-gxi-pos ss-g-gxi-pos--name", children: splitName(lineupEntry.name).last })
|
|
7633
8029
|
] }, `${pos.slot}-${c}`);
|
|
7634
8030
|
}
|
|
7635
|
-
return /* @__PURE__ */ (0,
|
|
7636
|
-
/* @__PURE__ */ (0,
|
|
8031
|
+
return /* @__PURE__ */ (0, import_jsx_runtime82.jsxs)("div", { className: "ss-g-gxi-node", "data-revealed": name ? "true" : void 0, children: [
|
|
8032
|
+
/* @__PURE__ */ (0, import_jsx_runtime82.jsx)(
|
|
7637
8033
|
"span",
|
|
7638
8034
|
{
|
|
7639
8035
|
className: "ss-g-gxi-disc",
|
|
@@ -7644,22 +8040,22 @@ function GuessTheXiGame({
|
|
|
7644
8040
|
children: flag
|
|
7645
8041
|
}
|
|
7646
8042
|
),
|
|
7647
|
-
name ? /* @__PURE__ */ (0,
|
|
8043
|
+
name ? /* @__PURE__ */ (0, import_jsx_runtime82.jsx)("span", { className: "ss-g-gxi-pos ss-g-gxi-pos--name", children: splitName(name).last }) : posLabel && /* @__PURE__ */ (0, import_jsx_runtime82.jsx)("span", { className: "ss-g-gxi-pos", children: posLabel })
|
|
7648
8044
|
] }, `${pos.slot}-${c}`);
|
|
7649
8045
|
}) }, r)) })
|
|
7650
8046
|
] }),
|
|
7651
|
-
!isOver && wrongGuesses.length > 0 && /* @__PURE__ */ (0,
|
|
7652
|
-
/* @__PURE__ */ (0,
|
|
8047
|
+
!isOver && wrongGuesses.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime82.jsxs)("div", { className: "ss-g-gxi-wrong", children: [
|
|
8048
|
+
/* @__PURE__ */ (0, import_jsx_runtime82.jsx)("span", { className: "ss-g-gxi-wrong-l", children: t.notThem }),
|
|
7653
8049
|
wrongGuesses.map((g) => {
|
|
7654
8050
|
const crestUrl = config?.teamPool.find((tm) => tm.teamId === g.teamId)?.crestUrl;
|
|
7655
|
-
return /* @__PURE__ */ (0,
|
|
7656
|
-
/* @__PURE__ */ (0,
|
|
7657
|
-
/* @__PURE__ */ (0,
|
|
8051
|
+
return /* @__PURE__ */ (0, import_jsx_runtime82.jsxs)("span", { className: "ss-g-gxi-wrong-chip", children: [
|
|
8052
|
+
/* @__PURE__ */ (0, import_jsx_runtime82.jsx)(CrestShield, { src: crestUrl, name: teamName(g.teamId), size: 18 }),
|
|
8053
|
+
/* @__PURE__ */ (0, import_jsx_runtime82.jsx)("s", { children: teamName(g.teamId) })
|
|
7658
8054
|
] }, g.teamId);
|
|
7659
8055
|
})
|
|
7660
8056
|
] }),
|
|
7661
|
-
isOver && /* @__PURE__ */ (0,
|
|
7662
|
-
/* @__PURE__ */ (0,
|
|
8057
|
+
isOver && /* @__PURE__ */ (0, import_jsx_runtime82.jsxs)(import_jsx_runtime82.Fragment, { children: [
|
|
8058
|
+
/* @__PURE__ */ (0, import_jsx_runtime82.jsx)(
|
|
7663
8059
|
ResultCard,
|
|
7664
8060
|
{
|
|
7665
8061
|
tone: solved ? "win" : failed ? "lose" : "neutral",
|
|
@@ -7670,29 +8066,29 @@ function GuessTheXiGame({
|
|
|
7670
8066
|
ui
|
|
7671
8067
|
}
|
|
7672
8068
|
),
|
|
7673
|
-
(solved || failed) && clientState?.answer && /* @__PURE__ */ (0,
|
|
7674
|
-
/* @__PURE__ */ (0,
|
|
7675
|
-
/* @__PURE__ */ (0,
|
|
7676
|
-
/* @__PURE__ */ (0,
|
|
8069
|
+
(solved || failed) && clientState?.answer && /* @__PURE__ */ (0, import_jsx_runtime82.jsxs)("div", { className: "ss-g-gxi-answer", "data-testid": "gxi-answer-reveal", children: [
|
|
8070
|
+
/* @__PURE__ */ (0, import_jsx_runtime82.jsx)("span", { className: "ss-g-gxi-answer-label", children: t.theAnswer }),
|
|
8071
|
+
/* @__PURE__ */ (0, import_jsx_runtime82.jsx)(CrestShield, { src: clientState.answer.crestUrl, name: clientState.answer.teamName, size: 32 }),
|
|
8072
|
+
/* @__PURE__ */ (0, import_jsx_runtime82.jsx)("span", { className: "ss-g-gxi-answer-name", children: clientState.answer.teamName })
|
|
7677
8073
|
] })
|
|
7678
8074
|
] })
|
|
7679
8075
|
] }),
|
|
7680
|
-
!isOver && /* @__PURE__ */ (0,
|
|
7681
|
-
query.length > 0 && filtered.length > 0 && /* @__PURE__ */ (0,
|
|
8076
|
+
!isOver && /* @__PURE__ */ (0, import_jsx_runtime82.jsxs)(FooterBar, { children: [
|
|
8077
|
+
query.length > 0 && filtered.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime82.jsx)(
|
|
7682
8078
|
OptionList,
|
|
7683
8079
|
{
|
|
7684
8080
|
label: t.optionsLabel,
|
|
7685
8081
|
options: filtered.map((tm) => ({
|
|
7686
8082
|
key: tm.teamId,
|
|
7687
|
-
content: /* @__PURE__ */ (0,
|
|
7688
|
-
/* @__PURE__ */ (0,
|
|
7689
|
-
/* @__PURE__ */ (0,
|
|
8083
|
+
content: /* @__PURE__ */ (0, import_jsx_runtime82.jsxs)(import_jsx_runtime82.Fragment, { children: [
|
|
8084
|
+
/* @__PURE__ */ (0, import_jsx_runtime82.jsx)(CrestShield, { src: tm.crestUrl, name: tm.teamName, size: 28 }),
|
|
8085
|
+
/* @__PURE__ */ (0, import_jsx_runtime82.jsx)("span", { children: tm.teamName })
|
|
7690
8086
|
] })
|
|
7691
8087
|
})),
|
|
7692
8088
|
onPick: (k) => handlePick(Number(k))
|
|
7693
8089
|
}
|
|
7694
8090
|
),
|
|
7695
|
-
/* @__PURE__ */ (0,
|
|
8091
|
+
/* @__PURE__ */ (0, import_jsx_runtime82.jsx)(
|
|
7696
8092
|
SearchField,
|
|
7697
8093
|
{
|
|
7698
8094
|
id: inputId,
|
|
@@ -7709,8 +8105,8 @@ function GuessTheXiGame({
|
|
|
7709
8105
|
}
|
|
7710
8106
|
|
|
7711
8107
|
// src/components/games/DailyQuizGame.tsx
|
|
7712
|
-
var
|
|
7713
|
-
var
|
|
8108
|
+
var import_react49 = require("react");
|
|
8109
|
+
var import_jsx_runtime83 = require("react/jsx-runtime");
|
|
7714
8110
|
function parseClientState6(json) {
|
|
7715
8111
|
if (!json) return null;
|
|
7716
8112
|
try {
|
|
@@ -7731,13 +8127,13 @@ function OptionName({ text }) {
|
|
|
7731
8127
|
const tokens = base.split(/\s+/).filter(Boolean);
|
|
7732
8128
|
const isPlainName = tokens.length >= 1 && tokens.length <= 4 && tokens.every((t) => NAME_TOKEN.test(t));
|
|
7733
8129
|
if (!isPlainName || base === "") {
|
|
7734
|
-
return /* @__PURE__ */ (0,
|
|
8130
|
+
return /* @__PURE__ */ (0, import_jsx_runtime83.jsx)("span", { className: "ss-g-dq-opt-name", children: /* @__PURE__ */ (0, import_jsx_runtime83.jsx)("span", { className: "ss-g-dq-opt-full", children: text }) });
|
|
7735
8131
|
}
|
|
7736
8132
|
const { first, last } = splitName(base);
|
|
7737
|
-
return /* @__PURE__ */ (0,
|
|
7738
|
-
first && /* @__PURE__ */ (0,
|
|
7739
|
-
/* @__PURE__ */ (0,
|
|
7740
|
-
suffix && /* @__PURE__ */ (0,
|
|
8133
|
+
return /* @__PURE__ */ (0, import_jsx_runtime83.jsxs)("span", { className: "ss-g-dq-opt-name", children: [
|
|
8134
|
+
first && /* @__PURE__ */ (0, import_jsx_runtime83.jsx)("span", { className: "ss-g-dq-opt-first", children: first }),
|
|
8135
|
+
/* @__PURE__ */ (0, import_jsx_runtime83.jsx)("span", { className: "ss-g-dq-opt-last", children: last }),
|
|
8136
|
+
suffix && /* @__PURE__ */ (0, import_jsx_runtime83.jsx)("span", { className: "ss-g-dq-opt-suffix", children: suffix })
|
|
7741
8137
|
] });
|
|
7742
8138
|
}
|
|
7743
8139
|
function DailyQuizGame({
|
|
@@ -7750,15 +8146,15 @@ function DailyQuizGame({
|
|
|
7750
8146
|
}) {
|
|
7751
8147
|
const s = ui.games.dailyQuiz;
|
|
7752
8148
|
const title = gameTitle({ gameId: "daily-quiz" }, ui.games.titles);
|
|
7753
|
-
const [selections, setSelections] = (0,
|
|
7754
|
-
const [page, setPage] = (0,
|
|
8149
|
+
const [selections, setSelections] = (0, import_react49.useState)(/* @__PURE__ */ new Map());
|
|
8150
|
+
const [page, setPage] = (0, import_react49.useState)(0);
|
|
7755
8151
|
const clientState = parseClientState6(result?.clientStateJson);
|
|
7756
8152
|
const results = clientState?.results ?? [];
|
|
7757
8153
|
const isRevealed = results.length > 0 || result?.alreadyPlayed === true;
|
|
7758
8154
|
if (!config) {
|
|
7759
|
-
return /* @__PURE__ */ (0,
|
|
7760
|
-
/* @__PURE__ */ (0,
|
|
7761
|
-
/* @__PURE__ */ (0,
|
|
8155
|
+
return /* @__PURE__ */ (0, import_jsx_runtime83.jsxs)("div", { className: "ss-g-screen", "data-game": "daily-quiz", "data-testid": "game-screen-daily-quiz", children: [
|
|
8156
|
+
/* @__PURE__ */ (0, import_jsx_runtime83.jsx)(GameHeader, { title, onBack, backLabel: ui.back }),
|
|
8157
|
+
/* @__PURE__ */ (0, import_jsx_runtime83.jsx)("div", { className: "ss-g-body ss-g-loading", children: ui.games.loading })
|
|
7762
8158
|
] });
|
|
7763
8159
|
}
|
|
7764
8160
|
const questions = config.questions;
|
|
@@ -7793,11 +8189,11 @@ function DailyQuizGame({
|
|
|
7793
8189
|
return r.isCorrect ? "correct" : "wrong";
|
|
7794
8190
|
});
|
|
7795
8191
|
const correctCount = results.filter((r) => r.isCorrect).length;
|
|
7796
|
-
return /* @__PURE__ */ (0,
|
|
7797
|
-
/* @__PURE__ */ (0,
|
|
7798
|
-
/* @__PURE__ */ (0,
|
|
7799
|
-
/* @__PURE__ */ (0,
|
|
7800
|
-
/* @__PURE__ */ (0,
|
|
8192
|
+
return /* @__PURE__ */ (0, import_jsx_runtime83.jsxs)("div", { className: "ss-g-screen", "data-game": "daily-quiz", "data-testid": "game-screen-daily-quiz", children: [
|
|
8193
|
+
/* @__PURE__ */ (0, import_jsx_runtime83.jsx)(GameHeader, { title, eyebrow: s.results, onBack, backLabel: ui.back }),
|
|
8194
|
+
/* @__PURE__ */ (0, import_jsx_runtime83.jsx)(SegmentProgress, { segments: segments2, ariaLabel: s.results }),
|
|
8195
|
+
/* @__PURE__ */ (0, import_jsx_runtime83.jsxs)("div", { className: "ss-g-body", children: [
|
|
8196
|
+
/* @__PURE__ */ (0, import_jsx_runtime83.jsx)(
|
|
7801
8197
|
ResultCard,
|
|
7802
8198
|
{
|
|
7803
8199
|
tone: "neutral",
|
|
@@ -7810,15 +8206,15 @@ function DailyQuizGame({
|
|
|
7810
8206
|
questions.map((q) => {
|
|
7811
8207
|
const r = findResult(results, q.index);
|
|
7812
8208
|
const picked = selections.get(q.index);
|
|
7813
|
-
return /* @__PURE__ */ (0,
|
|
7814
|
-
/* @__PURE__ */ (0,
|
|
7815
|
-
r && /* @__PURE__ */ (0,
|
|
8209
|
+
return /* @__PURE__ */ (0, import_jsx_runtime83.jsxs)("div", { className: "ss-g-dq-rq", children: [
|
|
8210
|
+
/* @__PURE__ */ (0, import_jsx_runtime83.jsx)("div", { className: "ss-g-dq-rq-stem", children: q.stem }),
|
|
8211
|
+
r && /* @__PURE__ */ (0, import_jsx_runtime83.jsx)("div", { className: "ss-g-dq-rq-opts", children: q.options.map((opt, optIdx) => {
|
|
7816
8212
|
let cls = "ss-g-dq-rq-opt";
|
|
7817
8213
|
if (optIdx === r.correctOptionIndex) cls += " ss-g-dq-rq-opt--correct";
|
|
7818
8214
|
else if (optIdx === picked && !r.isCorrect) cls += " ss-g-dq-rq-opt--wrong";
|
|
7819
|
-
return /* @__PURE__ */ (0,
|
|
8215
|
+
return /* @__PURE__ */ (0, import_jsx_runtime83.jsx)("span", { className: cls, children: opt }, optIdx);
|
|
7820
8216
|
}) }),
|
|
7821
|
-
r?.revealText && /* @__PURE__ */ (0,
|
|
8217
|
+
r?.revealText && /* @__PURE__ */ (0, import_jsx_runtime83.jsx)("div", { className: "ss-g-dq-why", children: r.revealText })
|
|
7822
8218
|
] }, q.index);
|
|
7823
8219
|
})
|
|
7824
8220
|
] })
|
|
@@ -7826,16 +8222,16 @@ function DailyQuizGame({
|
|
|
7826
8222
|
}
|
|
7827
8223
|
const segments = questions.map((_, i) => i < page ? "done" : i === page ? "current" : "todo");
|
|
7828
8224
|
const selectedIdx = current ? selections.get(current.index) : void 0;
|
|
7829
|
-
return /* @__PURE__ */ (0,
|
|
7830
|
-
/* @__PURE__ */ (0,
|
|
7831
|
-
/* @__PURE__ */ (0,
|
|
7832
|
-
/* @__PURE__ */ (0,
|
|
7833
|
-
/* @__PURE__ */ (0,
|
|
7834
|
-
/* @__PURE__ */ (0,
|
|
8225
|
+
return /* @__PURE__ */ (0, import_jsx_runtime83.jsxs)("div", { className: "ss-g-screen", "data-game": "daily-quiz", "data-testid": "game-screen-daily-quiz", children: [
|
|
8226
|
+
/* @__PURE__ */ (0, import_jsx_runtime83.jsx)(GameHeader, { title, eyebrow: s.questionOf(page + 1, total), onBack, backLabel: ui.back }),
|
|
8227
|
+
/* @__PURE__ */ (0, import_jsx_runtime83.jsx)(SegmentProgress, { segments, ariaLabel: s.progressAria(page + 1, total) }),
|
|
8228
|
+
/* @__PURE__ */ (0, import_jsx_runtime83.jsx)("div", { className: "ss-g-body", children: current && /* @__PURE__ */ (0, import_jsx_runtime83.jsxs)(import_jsx_runtime83.Fragment, { children: [
|
|
8229
|
+
/* @__PURE__ */ (0, import_jsx_runtime83.jsx)("h3", { className: "ss-g-dq-stem", children: current.stem }),
|
|
8230
|
+
/* @__PURE__ */ (0, import_jsx_runtime83.jsx)("div", { className: "ss-g-dq-opts", children: current.options.map((opt, optIdx) => {
|
|
7835
8231
|
const selected = optIdx === selectedIdx;
|
|
7836
8232
|
const imagePath = current.optionImagePaths?.[optIdx] ?? void 0;
|
|
7837
8233
|
const playerName = opt;
|
|
7838
|
-
return /* @__PURE__ */ (0,
|
|
8234
|
+
return /* @__PURE__ */ (0, import_jsx_runtime83.jsxs)(
|
|
7839
8235
|
"button",
|
|
7840
8236
|
{
|
|
7841
8237
|
type: "button",
|
|
@@ -7844,25 +8240,25 @@ function DailyQuizGame({
|
|
|
7844
8240
|
disabled: submitting,
|
|
7845
8241
|
onClick: () => handleSelect(current.index, optIdx),
|
|
7846
8242
|
children: [
|
|
7847
|
-
current.optionImagePaths && /* @__PURE__ */ (0,
|
|
7848
|
-
/* @__PURE__ */ (0,
|
|
7849
|
-
/* @__PURE__ */ (0,
|
|
8243
|
+
current.optionImagePaths && /* @__PURE__ */ (0, import_jsx_runtime83.jsx)(PlayerAvatar, { name: playerName, imagePath, className: "ss-g-dq-opt-av" }),
|
|
8244
|
+
/* @__PURE__ */ (0, import_jsx_runtime83.jsx)("span", { className: "ss-g-dq-badge", "aria-hidden": "true", children: selected ? /* @__PURE__ */ (0, import_jsx_runtime83.jsx)(IconCheck, {}) : String.fromCharCode(65 + optIdx) }),
|
|
8245
|
+
/* @__PURE__ */ (0, import_jsx_runtime83.jsx)(OptionName, { text: opt })
|
|
7850
8246
|
]
|
|
7851
8247
|
},
|
|
7852
8248
|
optIdx
|
|
7853
8249
|
);
|
|
7854
8250
|
}) })
|
|
7855
8251
|
] }) }),
|
|
7856
|
-
/* @__PURE__ */ (0,
|
|
7857
|
-
page > 0 && /* @__PURE__ */ (0,
|
|
7858
|
-
isLast ? /* @__PURE__ */ (0,
|
|
8252
|
+
/* @__PURE__ */ (0, import_jsx_runtime83.jsx)(FooterBar, { children: /* @__PURE__ */ (0, import_jsx_runtime83.jsxs)("div", { className: "ss-g-dq-nav", children: [
|
|
8253
|
+
page > 0 && /* @__PURE__ */ (0, import_jsx_runtime83.jsx)(GameButton, { variant: "outline", onClick: goPrev, disabled: submitting, children: s.previous }),
|
|
8254
|
+
isLast ? /* @__PURE__ */ (0, import_jsx_runtime83.jsx)(GameButton, { variant: "primary", block: true, onClick: handleSubmit, disabled: !currentAnswered || !allAnswered || submitting, children: submitting ? s.submitting : s.submit }) : /* @__PURE__ */ (0, import_jsx_runtime83.jsx)(GameButton, { variant: "primary", block: true, onClick: goNext, disabled: !currentAnswered || submitting, children: s.next })
|
|
7859
8255
|
] }) })
|
|
7860
8256
|
] });
|
|
7861
8257
|
}
|
|
7862
8258
|
|
|
7863
8259
|
// src/components/games/MatchdayPredictorGame.tsx
|
|
7864
|
-
var
|
|
7865
|
-
var
|
|
8260
|
+
var import_react50 = require("react");
|
|
8261
|
+
var import_jsx_runtime84 = require("react/jsx-runtime");
|
|
7866
8262
|
var SCORER_SEARCH_THRESHOLD = 9;
|
|
7867
8263
|
function parseClientState7(json) {
|
|
7868
8264
|
if (!json) return null;
|
|
@@ -7880,7 +8276,7 @@ function isLocked(kickoffUtc) {
|
|
|
7880
8276
|
}
|
|
7881
8277
|
}
|
|
7882
8278
|
function IconMinus() {
|
|
7883
|
-
return /* @__PURE__ */ (0,
|
|
8279
|
+
return /* @__PURE__ */ (0, import_jsx_runtime84.jsx)(
|
|
7884
8280
|
"svg",
|
|
7885
8281
|
{
|
|
7886
8282
|
width: 18,
|
|
@@ -7891,20 +8287,20 @@ function IconMinus() {
|
|
|
7891
8287
|
strokeWidth: 2.2,
|
|
7892
8288
|
strokeLinecap: "round",
|
|
7893
8289
|
"aria-hidden": "true",
|
|
7894
|
-
children: /* @__PURE__ */ (0,
|
|
8290
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime84.jsx)("path", { d: "M5 12h14" })
|
|
7895
8291
|
}
|
|
7896
8292
|
);
|
|
7897
8293
|
}
|
|
7898
8294
|
function TeamBadge({ team, label }) {
|
|
7899
|
-
return /* @__PURE__ */ (0,
|
|
7900
|
-
/* @__PURE__ */ (0,
|
|
7901
|
-
/* @__PURE__ */ (0,
|
|
7902
|
-
/* @__PURE__ */ (0,
|
|
8295
|
+
return /* @__PURE__ */ (0, import_jsx_runtime84.jsxs)("div", { className: "ss-g-mp-team", children: [
|
|
8296
|
+
/* @__PURE__ */ (0, import_jsx_runtime84.jsx)(CrestShield, { name: team.name, size: 44 }),
|
|
8297
|
+
/* @__PURE__ */ (0, import_jsx_runtime84.jsx)("span", { className: "ss-g-mp-team-name", children: team.name }),
|
|
8298
|
+
/* @__PURE__ */ (0, import_jsx_runtime84.jsx)("span", { className: "ss-g-mp-team-side", children: label })
|
|
7903
8299
|
] });
|
|
7904
8300
|
}
|
|
7905
8301
|
function ScoreCard({ home, away, h, a, t, edit }) {
|
|
7906
|
-
const col = (side, team, value) => /* @__PURE__ */ (0,
|
|
7907
|
-
edit && /* @__PURE__ */ (0,
|
|
8302
|
+
const col = (side, team, value) => /* @__PURE__ */ (0, import_jsx_runtime84.jsxs)("div", { className: "ss-g-mp-col", children: [
|
|
8303
|
+
edit && /* @__PURE__ */ (0, import_jsx_runtime84.jsx)(
|
|
7908
8304
|
"button",
|
|
7909
8305
|
{
|
|
7910
8306
|
type: "button",
|
|
@@ -7912,11 +8308,11 @@ function ScoreCard({ home, away, h, a, t, edit }) {
|
|
|
7912
8308
|
"aria-label": t.goalsUp(team.name),
|
|
7913
8309
|
disabled: edit.disabled,
|
|
7914
8310
|
onClick: () => edit.onStep(side, 1),
|
|
7915
|
-
children: /* @__PURE__ */ (0,
|
|
8311
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime84.jsx)(IconPlus, { size: 18 })
|
|
7916
8312
|
}
|
|
7917
8313
|
),
|
|
7918
|
-
/* @__PURE__ */ (0,
|
|
7919
|
-
edit && /* @__PURE__ */ (0,
|
|
8314
|
+
/* @__PURE__ */ (0, import_jsx_runtime84.jsx)("span", { className: "ss-g-mp-digit", "data-testid": "mp-digit", "data-active": edit ? String(edit.active === side) : "false", children: value }),
|
|
8315
|
+
edit && /* @__PURE__ */ (0, import_jsx_runtime84.jsx)(
|
|
7920
8316
|
"button",
|
|
7921
8317
|
{
|
|
7922
8318
|
type: "button",
|
|
@@ -7924,27 +8320,27 @@ function ScoreCard({ home, away, h, a, t, edit }) {
|
|
|
7924
8320
|
"aria-label": t.goalsDown(team.name),
|
|
7925
8321
|
disabled: edit.disabled || value <= 0,
|
|
7926
8322
|
onClick: () => edit.onStep(side, -1),
|
|
7927
|
-
children: /* @__PURE__ */ (0,
|
|
8323
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime84.jsx)(IconMinus, {})
|
|
7928
8324
|
}
|
|
7929
8325
|
)
|
|
7930
8326
|
] });
|
|
7931
|
-
return /* @__PURE__ */ (0,
|
|
7932
|
-
/* @__PURE__ */ (0,
|
|
7933
|
-
/* @__PURE__ */ (0,
|
|
8327
|
+
return /* @__PURE__ */ (0, import_jsx_runtime84.jsxs)("div", { className: "ss-g-mp-card", children: [
|
|
8328
|
+
/* @__PURE__ */ (0, import_jsx_runtime84.jsx)(TeamBadge, { team: home, label: t.home }),
|
|
8329
|
+
/* @__PURE__ */ (0, import_jsx_runtime84.jsxs)("div", { className: "ss-g-mp-scores", children: [
|
|
7934
8330
|
col("home", home, h),
|
|
7935
|
-
/* @__PURE__ */ (0,
|
|
8331
|
+
/* @__PURE__ */ (0, import_jsx_runtime84.jsx)("span", { className: "ss-g-mp-dash", "aria-hidden": "true", children: "\u2013" }),
|
|
7936
8332
|
col("away", away, a)
|
|
7937
8333
|
] }),
|
|
7938
|
-
/* @__PURE__ */ (0,
|
|
8334
|
+
/* @__PURE__ */ (0, import_jsx_runtime84.jsx)(TeamBadge, { team: away, label: t.away })
|
|
7939
8335
|
] });
|
|
7940
8336
|
}
|
|
7941
8337
|
function OutcomeRow({ label, ok, detail, t }) {
|
|
7942
|
-
return /* @__PURE__ */ (0,
|
|
7943
|
-
/* @__PURE__ */ (0,
|
|
7944
|
-
/* @__PURE__ */ (0,
|
|
7945
|
-
ok ? /* @__PURE__ */ (0,
|
|
7946
|
-
/* @__PURE__ */ (0,
|
|
7947
|
-
detail ? /* @__PURE__ */ (0,
|
|
8338
|
+
return /* @__PURE__ */ (0, import_jsx_runtime84.jsxs)("li", { className: "ss-g-mp-row", "data-testid": "mp-row", "data-ok": String(ok), children: [
|
|
8339
|
+
/* @__PURE__ */ (0, import_jsx_runtime84.jsx)("span", { className: "ss-g-mp-row-k", children: label }),
|
|
8340
|
+
/* @__PURE__ */ (0, import_jsx_runtime84.jsxs)("span", { className: "ss-g-mp-row-v", children: [
|
|
8341
|
+
ok ? /* @__PURE__ */ (0, import_jsx_runtime84.jsx)(IconCheck, {}) : /* @__PURE__ */ (0, import_jsx_runtime84.jsx)(IconClose, { size: 14 }),
|
|
8342
|
+
/* @__PURE__ */ (0, import_jsx_runtime84.jsx)("span", { className: "ss-g-sr", children: ok ? t.correct : t.incorrect }),
|
|
8343
|
+
detail ? /* @__PURE__ */ (0, import_jsx_runtime84.jsx)("span", { className: "ss-g-mp-row-d", children: detail }) : null
|
|
7948
8344
|
] })
|
|
7949
8345
|
] });
|
|
7950
8346
|
}
|
|
@@ -7957,20 +8353,20 @@ function MatchdayPredictorGame({
|
|
|
7957
8353
|
onBack
|
|
7958
8354
|
}) {
|
|
7959
8355
|
const t = ui.games.predictor;
|
|
7960
|
-
const [homeScore, setHomeScore] = (0,
|
|
7961
|
-
const [awayScore, setAwayScore] = (0,
|
|
7962
|
-
const [firstScorerPlayerId, setFirstScorerPlayerId] = (0,
|
|
7963
|
-
const [lastEdited, setLastEdited] = (0,
|
|
7964
|
-
const [query, setQuery] = (0,
|
|
7965
|
-
const searchId = (0,
|
|
8356
|
+
const [homeScore, setHomeScore] = (0, import_react50.useState)(0);
|
|
8357
|
+
const [awayScore, setAwayScore] = (0, import_react50.useState)(0);
|
|
8358
|
+
const [firstScorerPlayerId, setFirstScorerPlayerId] = (0, import_react50.useState)(null);
|
|
8359
|
+
const [lastEdited, setLastEdited] = (0, import_react50.useState)("home");
|
|
8360
|
+
const [query, setQuery] = (0, import_react50.useState)("");
|
|
8361
|
+
const searchId = (0, import_react50.useId)();
|
|
7966
8362
|
const clientState = parseClientState7(result?.clientStateJson);
|
|
7967
8363
|
const alreadyPlayed = result?.alreadyPlayed === true;
|
|
7968
|
-
const header = /* @__PURE__ */ (0,
|
|
8364
|
+
const header = /* @__PURE__ */ (0, import_jsx_runtime84.jsx)(
|
|
7969
8365
|
GameHeader,
|
|
7970
8366
|
{
|
|
7971
8367
|
title: gameTitle({ gameId: "matchday-predictor" }, ui.games.titles),
|
|
7972
8368
|
eyebrow: config ? t.eyebrow(config.homeTeam.name, config.awayTeam.name) : void 0,
|
|
7973
|
-
right: config ? /* @__PURE__ */ (0,
|
|
8369
|
+
right: config ? /* @__PURE__ */ (0, import_jsx_runtime84.jsx)(Chip, { icon: /* @__PURE__ */ (0, import_jsx_runtime84.jsx)(IconLock, {}), children: ui.games.formatDayTime(config.kickoffUtc) }) : void 0,
|
|
7974
8370
|
onBack,
|
|
7975
8371
|
backLabel: ui.back
|
|
7976
8372
|
}
|
|
@@ -7978,10 +8374,10 @@ function MatchdayPredictorGame({
|
|
|
7978
8374
|
if (alreadyPlayed && clientState) {
|
|
7979
8375
|
if (!clientState.graded) {
|
|
7980
8376
|
const scorer = config?.scorerPool.find((p) => p.playerId === clientState.predictedFirstScorerPlayerId) ?? null;
|
|
7981
|
-
return /* @__PURE__ */ (0,
|
|
8377
|
+
return /* @__PURE__ */ (0, import_jsx_runtime84.jsxs)("div", { className: "ss-g-screen", "data-game": "matchday-predictor", "data-testid": "game-screen-matchday-predictor", children: [
|
|
7982
8378
|
header,
|
|
7983
|
-
/* @__PURE__ */ (0,
|
|
7984
|
-
config && /* @__PURE__ */ (0,
|
|
8379
|
+
/* @__PURE__ */ (0, import_jsx_runtime84.jsxs)("div", { className: "ss-g-body", children: [
|
|
8380
|
+
config && /* @__PURE__ */ (0, import_jsx_runtime84.jsx)(
|
|
7985
8381
|
ScoreCard,
|
|
7986
8382
|
{
|
|
7987
8383
|
home: config.homeTeam,
|
|
@@ -7991,7 +8387,7 @@ function MatchdayPredictorGame({
|
|
|
7991
8387
|
t
|
|
7992
8388
|
}
|
|
7993
8389
|
),
|
|
7994
|
-
/* @__PURE__ */ (0,
|
|
8390
|
+
/* @__PURE__ */ (0, import_jsx_runtime84.jsx)(
|
|
7995
8391
|
ResultCard,
|
|
7996
8392
|
{
|
|
7997
8393
|
tone: "neutral",
|
|
@@ -8008,28 +8404,28 @@ function MatchdayPredictorGame({
|
|
|
8008
8404
|
}
|
|
8009
8405
|
)
|
|
8010
8406
|
] }),
|
|
8011
|
-
/* @__PURE__ */ (0,
|
|
8407
|
+
/* @__PURE__ */ (0, import_jsx_runtime84.jsx)(FooterBar, { children: /* @__PURE__ */ (0, import_jsx_runtime84.jsx)("p", { className: "ss-g-mp-fun", children: t.forFun }) })
|
|
8012
8408
|
] });
|
|
8013
8409
|
}
|
|
8014
8410
|
const r = clientState.result;
|
|
8015
|
-
return /* @__PURE__ */ (0,
|
|
8411
|
+
return /* @__PURE__ */ (0, import_jsx_runtime84.jsxs)("div", { className: "ss-g-screen", "data-game": "matchday-predictor", "data-testid": "game-screen-matchday-predictor", children: [
|
|
8016
8412
|
header,
|
|
8017
|
-
/* @__PURE__ */ (0,
|
|
8018
|
-
config && /* @__PURE__ */ (0,
|
|
8019
|
-
/* @__PURE__ */ (0,
|
|
8020
|
-
/* @__PURE__ */ (0,
|
|
8021
|
-
/* @__PURE__ */ (0,
|
|
8022
|
-
/* @__PURE__ */ (0,
|
|
8023
|
-
!clientState.firstScorerVoid && /* @__PURE__ */ (0,
|
|
8413
|
+
/* @__PURE__ */ (0, import_jsx_runtime84.jsxs)("div", { className: "ss-g-body", children: [
|
|
8414
|
+
config && /* @__PURE__ */ (0, import_jsx_runtime84.jsx)(ScoreCard, { home: config.homeTeam, away: config.awayTeam, h: r.homeScore, a: r.awayScore, t }),
|
|
8415
|
+
/* @__PURE__ */ (0, import_jsx_runtime84.jsx)(ResultCard, { tone: "neutral", title: t.fullTime(r.homeScore, r.awayScore), onBack, ui }),
|
|
8416
|
+
/* @__PURE__ */ (0, import_jsx_runtime84.jsxs)("ul", { className: "ss-g-mp-rows", children: [
|
|
8417
|
+
/* @__PURE__ */ (0, import_jsx_runtime84.jsx)(OutcomeRow, { label: t.exactScore, ok: clientState.exactScoreCorrect, t }),
|
|
8418
|
+
/* @__PURE__ */ (0, import_jsx_runtime84.jsx)(OutcomeRow, { label: t.outcome, ok: clientState.outcomeCorrect, t }),
|
|
8419
|
+
!clientState.firstScorerVoid && /* @__PURE__ */ (0, import_jsx_runtime84.jsx)(OutcomeRow, { label: t.firstScorerRow, ok: clientState.firstScorerCorrect, detail: r.firstScorerName, t })
|
|
8024
8420
|
] })
|
|
8025
8421
|
] }),
|
|
8026
|
-
/* @__PURE__ */ (0,
|
|
8422
|
+
/* @__PURE__ */ (0, import_jsx_runtime84.jsx)(FooterBar, { children: /* @__PURE__ */ (0, import_jsx_runtime84.jsx)("p", { className: "ss-g-mp-fun", children: t.forFun }) })
|
|
8027
8423
|
] });
|
|
8028
8424
|
}
|
|
8029
8425
|
if (!config) {
|
|
8030
|
-
return /* @__PURE__ */ (0,
|
|
8426
|
+
return /* @__PURE__ */ (0, import_jsx_runtime84.jsxs)("div", { className: "ss-g-screen", "data-game": "matchday-predictor", "data-testid": "game-screen-matchday-predictor", children: [
|
|
8031
8427
|
header,
|
|
8032
|
-
/* @__PURE__ */ (0,
|
|
8428
|
+
/* @__PURE__ */ (0, import_jsx_runtime84.jsx)("div", { className: "ss-g-body ss-g-loading", children: ui.games.loading })
|
|
8033
8429
|
] });
|
|
8034
8430
|
}
|
|
8035
8431
|
const locked = isLocked(config.kickoffUtc);
|
|
@@ -8053,10 +8449,10 @@ function MatchdayPredictorGame({
|
|
|
8053
8449
|
const showSearch = pool.length > SCORER_SEARCH_THRESHOLD;
|
|
8054
8450
|
const q = query.trim().toLowerCase();
|
|
8055
8451
|
const visible = showSearch && q ? pool.filter((p) => p.playerName.toLowerCase().includes(q)) : pool;
|
|
8056
|
-
return /* @__PURE__ */ (0,
|
|
8452
|
+
return /* @__PURE__ */ (0, import_jsx_runtime84.jsxs)("div", { className: "ss-g-screen", "data-game": "matchday-predictor", "data-testid": "game-screen-matchday-predictor", children: [
|
|
8057
8453
|
header,
|
|
8058
|
-
/* @__PURE__ */ (0,
|
|
8059
|
-
/* @__PURE__ */ (0,
|
|
8454
|
+
/* @__PURE__ */ (0, import_jsx_runtime84.jsxs)("div", { className: "ss-g-body", children: [
|
|
8455
|
+
/* @__PURE__ */ (0, import_jsx_runtime84.jsx)(
|
|
8060
8456
|
ScoreCard,
|
|
8061
8457
|
{
|
|
8062
8458
|
home: config.homeTeam,
|
|
@@ -8067,12 +8463,12 @@ function MatchdayPredictorGame({
|
|
|
8067
8463
|
edit: { disabled, active: lastEdited, onStep: step }
|
|
8068
8464
|
}
|
|
8069
8465
|
),
|
|
8070
|
-
pool.length > 0 && /* @__PURE__ */ (0,
|
|
8071
|
-
/* @__PURE__ */ (0,
|
|
8072
|
-
/* @__PURE__ */ (0,
|
|
8073
|
-
/* @__PURE__ */ (0,
|
|
8466
|
+
pool.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime84.jsxs)("section", { className: "ss-g-mp-scorer", children: [
|
|
8467
|
+
/* @__PURE__ */ (0, import_jsx_runtime84.jsxs)("div", { className: "ss-g-mp-sec-head", children: [
|
|
8468
|
+
/* @__PURE__ */ (0, import_jsx_runtime84.jsx)("h3", { children: t.firstScorer }),
|
|
8469
|
+
/* @__PURE__ */ (0, import_jsx_runtime84.jsx)("span", { children: t.optional })
|
|
8074
8470
|
] }),
|
|
8075
|
-
showSearch && /* @__PURE__ */ (0,
|
|
8471
|
+
showSearch && /* @__PURE__ */ (0, import_jsx_runtime84.jsx)(
|
|
8076
8472
|
SearchField,
|
|
8077
8473
|
{
|
|
8078
8474
|
id: searchId,
|
|
@@ -8084,9 +8480,9 @@ function MatchdayPredictorGame({
|
|
|
8084
8480
|
disabled
|
|
8085
8481
|
}
|
|
8086
8482
|
),
|
|
8087
|
-
/* @__PURE__ */ (0,
|
|
8483
|
+
/* @__PURE__ */ (0, import_jsx_runtime84.jsx)("div", { className: "ss-g-mp-grid", children: visible.map((p) => {
|
|
8088
8484
|
const selected = firstScorerPlayerId === p.playerId;
|
|
8089
|
-
return /* @__PURE__ */ (0,
|
|
8485
|
+
return /* @__PURE__ */ (0, import_jsx_runtime84.jsxs)(
|
|
8090
8486
|
"button",
|
|
8091
8487
|
{
|
|
8092
8488
|
type: "button",
|
|
@@ -8096,15 +8492,15 @@ function MatchdayPredictorGame({
|
|
|
8096
8492
|
disabled,
|
|
8097
8493
|
onClick: () => setFirstScorerPlayerId((id) => id === p.playerId ? null : p.playerId),
|
|
8098
8494
|
children: [
|
|
8099
|
-
selected && /* @__PURE__ */ (0,
|
|
8100
|
-
/* @__PURE__ */ (0,
|
|
8101
|
-
/* @__PURE__ */ (0,
|
|
8495
|
+
selected && /* @__PURE__ */ (0, import_jsx_runtime84.jsx)("span", { className: "ss-g-mp-pcheck", children: /* @__PURE__ */ (0, import_jsx_runtime84.jsx)(IconCheck, { size: 12 }) }),
|
|
8496
|
+
/* @__PURE__ */ (0, import_jsx_runtime84.jsx)(Silhouette, { size: 52, variant: selected ? "selected" : "default" }),
|
|
8497
|
+
/* @__PURE__ */ (0, import_jsx_runtime84.jsx)("span", { className: "ss-g-mp-pname", children: splitName(p.playerName).last })
|
|
8102
8498
|
]
|
|
8103
8499
|
},
|
|
8104
8500
|
p.playerId
|
|
8105
8501
|
);
|
|
8106
8502
|
}) }),
|
|
8107
|
-
/* @__PURE__ */ (0,
|
|
8503
|
+
/* @__PURE__ */ (0, import_jsx_runtime84.jsxs)(
|
|
8108
8504
|
"button",
|
|
8109
8505
|
{
|
|
8110
8506
|
type: "button",
|
|
@@ -8113,24 +8509,24 @@ function MatchdayPredictorGame({
|
|
|
8113
8509
|
disabled,
|
|
8114
8510
|
onClick: () => setFirstScorerPlayerId(null),
|
|
8115
8511
|
children: [
|
|
8116
|
-
/* @__PURE__ */ (0,
|
|
8512
|
+
/* @__PURE__ */ (0, import_jsx_runtime84.jsx)("span", { className: "ss-g-mp-radio", "aria-hidden": "true" }),
|
|
8117
8513
|
t.noScorer
|
|
8118
8514
|
]
|
|
8119
8515
|
}
|
|
8120
8516
|
)
|
|
8121
8517
|
] }),
|
|
8122
|
-
locked && /* @__PURE__ */ (0,
|
|
8518
|
+
locked && /* @__PURE__ */ (0, import_jsx_runtime84.jsx)("p", { className: "ss-g-mp-closed", children: t.closed })
|
|
8123
8519
|
] }),
|
|
8124
|
-
/* @__PURE__ */ (0,
|
|
8125
|
-
/* @__PURE__ */ (0,
|
|
8126
|
-
/* @__PURE__ */ (0,
|
|
8520
|
+
/* @__PURE__ */ (0, import_jsx_runtime84.jsxs)(FooterBar, { children: [
|
|
8521
|
+
/* @__PURE__ */ (0, import_jsx_runtime84.jsx)(GameButton, { variant: "primary", block: true, disabled, onClick: handleSubmit, children: submitting ? t.saving : t.save }),
|
|
8522
|
+
/* @__PURE__ */ (0, import_jsx_runtime84.jsx)("p", { className: "ss-g-mp-fun", children: t.forFun })
|
|
8127
8523
|
] })
|
|
8128
8524
|
] });
|
|
8129
8525
|
}
|
|
8130
8526
|
|
|
8131
8527
|
// src/components/games/StartingXiGame.tsx
|
|
8132
|
-
var
|
|
8133
|
-
var
|
|
8528
|
+
var import_react51 = require("react");
|
|
8529
|
+
var import_jsx_runtime85 = require("react/jsx-runtime");
|
|
8134
8530
|
var POINTS_PER_STARTER = 8;
|
|
8135
8531
|
var XI_SIZE = 11;
|
|
8136
8532
|
var DEFAULT_FORMATION = "4-3-3";
|
|
@@ -8173,26 +8569,26 @@ function StartingXiGame({
|
|
|
8173
8569
|
lockAtUtc
|
|
8174
8570
|
}) {
|
|
8175
8571
|
const t = ui.games.startingXi;
|
|
8176
|
-
const [slotPlayers, setSlotPlayers] = (0,
|
|
8177
|
-
const [active, setActive] = (0,
|
|
8178
|
-
const [query, setQuery] = (0,
|
|
8179
|
-
const searchId = (0,
|
|
8572
|
+
const [slotPlayers, setSlotPlayers] = (0, import_react51.useState)(() => Array(XI_SIZE).fill(null));
|
|
8573
|
+
const [active, setActive] = (0, import_react51.useState)(0);
|
|
8574
|
+
const [query, setQuery] = (0, import_react51.useState)("");
|
|
8575
|
+
const searchId = (0, import_react51.useId)();
|
|
8180
8576
|
const clientState = parseClientState8(result?.clientStateJson);
|
|
8181
8577
|
const alreadyPlayed = result?.alreadyPlayed === true;
|
|
8182
|
-
const header = /* @__PURE__ */ (0,
|
|
8578
|
+
const header = /* @__PURE__ */ (0, import_jsx_runtime85.jsx)(
|
|
8183
8579
|
GameHeader,
|
|
8184
8580
|
{
|
|
8185
8581
|
title: gameTitle({ gameId: "starting-xi" }, ui.games.titles),
|
|
8186
8582
|
eyebrow: t.eyebrow,
|
|
8187
|
-
right: /* @__PURE__ */ (0,
|
|
8583
|
+
right: /* @__PURE__ */ (0, import_jsx_runtime85.jsx)(Chip, { variant: "accent", children: t.perStarter(POINTS_PER_STARTER) }),
|
|
8188
8584
|
onBack,
|
|
8189
8585
|
backLabel: ui.back
|
|
8190
8586
|
}
|
|
8191
8587
|
);
|
|
8192
8588
|
function statusScreen(title, score) {
|
|
8193
|
-
return /* @__PURE__ */ (0,
|
|
8589
|
+
return /* @__PURE__ */ (0, import_jsx_runtime85.jsxs)("div", { className: "ss-g-screen", "data-game": "starting-xi", "data-testid": "game-screen-starting-xi", children: [
|
|
8194
8590
|
header,
|
|
8195
|
-
/* @__PURE__ */ (0,
|
|
8591
|
+
/* @__PURE__ */ (0, import_jsx_runtime85.jsx)("div", { className: "ss-g-body", children: /* @__PURE__ */ (0, import_jsx_runtime85.jsx)(ResultCard, { tone: "neutral", title, score, onBack, ui }) })
|
|
8196
8592
|
] });
|
|
8197
8593
|
}
|
|
8198
8594
|
if (alreadyPlayed) {
|
|
@@ -8201,9 +8597,9 @@ function StartingXiGame({
|
|
|
8201
8597
|
if (clientState.status === "graded") return statusScreen(t.gradedLine(clientState.correctCount), clientState.score);
|
|
8202
8598
|
}
|
|
8203
8599
|
if (!config) {
|
|
8204
|
-
return /* @__PURE__ */ (0,
|
|
8600
|
+
return /* @__PURE__ */ (0, import_jsx_runtime85.jsxs)("div", { className: "ss-g-screen", "data-game": "starting-xi", "data-testid": "game-screen-starting-xi", children: [
|
|
8205
8601
|
header,
|
|
8206
|
-
/* @__PURE__ */ (0,
|
|
8602
|
+
/* @__PURE__ */ (0, import_jsx_runtime85.jsx)("div", { className: "ss-g-body ss-g-loading", children: ui.games.loading })
|
|
8207
8603
|
] });
|
|
8208
8604
|
}
|
|
8209
8605
|
const { formation, slots } = formationSlots(config.formation);
|
|
@@ -8238,27 +8634,27 @@ function StartingXiGame({
|
|
|
8238
8634
|
onSubmit(JSON.stringify({ predictedPlayerIds: slotPlayers }));
|
|
8239
8635
|
}
|
|
8240
8636
|
const segments = slotPlayers.map((p) => p !== null ? "current" : "todo");
|
|
8241
|
-
return /* @__PURE__ */ (0,
|
|
8637
|
+
return /* @__PURE__ */ (0, import_jsx_runtime85.jsxs)("div", { className: "ss-g-screen", "data-game": "starting-xi", "data-testid": "game-screen-starting-xi", children: [
|
|
8242
8638
|
header,
|
|
8243
|
-
/* @__PURE__ */ (0,
|
|
8639
|
+
/* @__PURE__ */ (0, import_jsx_runtime85.jsx)(
|
|
8244
8640
|
SegmentProgress,
|
|
8245
8641
|
{
|
|
8246
8642
|
segments,
|
|
8247
8643
|
ariaLabel: t.picked(pickedCount),
|
|
8248
8644
|
leftLabel: t.picked(pickedCount),
|
|
8249
8645
|
rightLabel: t.toGo(XI_SIZE - pickedCount),
|
|
8250
|
-
right: /* @__PURE__ */ (0,
|
|
8646
|
+
right: /* @__PURE__ */ (0, import_jsx_runtime85.jsx)(Chip, { children: formation })
|
|
8251
8647
|
}
|
|
8252
8648
|
),
|
|
8253
|
-
/* @__PURE__ */ (0,
|
|
8254
|
-
/* @__PURE__ */ (0,
|
|
8255
|
-
/* @__PURE__ */ (0,
|
|
8649
|
+
/* @__PURE__ */ (0, import_jsx_runtime85.jsxs)("div", { className: "ss-g-body", children: [
|
|
8650
|
+
/* @__PURE__ */ (0, import_jsx_runtime85.jsxs)("div", { className: "ss-g-xi-pitch", children: [
|
|
8651
|
+
/* @__PURE__ */ (0, import_jsx_runtime85.jsx)(PitchSvg, { variant: "half" }),
|
|
8256
8652
|
slots.map((s) => {
|
|
8257
8653
|
const playerId = slotPlayers[s.index] ?? null;
|
|
8258
8654
|
const player = playerId !== null ? byId.get(playerId) ?? null : null;
|
|
8259
8655
|
const name = player?.playerName ?? "";
|
|
8260
8656
|
const state = player ? "filled" : active === s.index ? "active" : "empty";
|
|
8261
|
-
return /* @__PURE__ */ (0,
|
|
8657
|
+
return /* @__PURE__ */ (0, import_jsx_runtime85.jsxs)(
|
|
8262
8658
|
"button",
|
|
8263
8659
|
{
|
|
8264
8660
|
type: "button",
|
|
@@ -8270,21 +8666,21 @@ function StartingXiGame({
|
|
|
8270
8666
|
disabled: submitting,
|
|
8271
8667
|
onClick: () => tapSlot(s.index),
|
|
8272
8668
|
children: [
|
|
8273
|
-
/* @__PURE__ */ (0,
|
|
8274
|
-
/* @__PURE__ */ (0,
|
|
8669
|
+
/* @__PURE__ */ (0, import_jsx_runtime85.jsx)("span", { className: "ss-g-xi-ring", "aria-hidden": "true", children: player ? player.jerseyNumber ?? "" : /* @__PURE__ */ (0, import_jsx_runtime85.jsx)(IconPlus, { size: 18 }) }),
|
|
8670
|
+
/* @__PURE__ */ (0, import_jsx_runtime85.jsx)("span", { className: "ss-g-xi-tag", "aria-hidden": "true", children: player ? splitName(name).last : s.label })
|
|
8275
8671
|
]
|
|
8276
8672
|
},
|
|
8277
8673
|
s.index
|
|
8278
8674
|
);
|
|
8279
8675
|
})
|
|
8280
8676
|
] }),
|
|
8281
|
-
/* @__PURE__ */ (0,
|
|
8282
|
-
/* @__PURE__ */ (0,
|
|
8283
|
-
/* @__PURE__ */ (0,
|
|
8284
|
-
/* @__PURE__ */ (0,
|
|
8285
|
-
] }) : /* @__PURE__ */ (0,
|
|
8286
|
-
activeSlot && /* @__PURE__ */ (0,
|
|
8287
|
-
/* @__PURE__ */ (0,
|
|
8677
|
+
/* @__PURE__ */ (0, import_jsx_runtime85.jsxs)("div", { className: "ss-g-xi-picker", children: [
|
|
8678
|
+
/* @__PURE__ */ (0, import_jsx_runtime85.jsx)("div", { className: "ss-g-xi-picker-head", children: activeSlot ? /* @__PURE__ */ (0, import_jsx_runtime85.jsxs)(import_jsx_runtime85.Fragment, { children: [
|
|
8679
|
+
/* @__PURE__ */ (0, import_jsx_runtime85.jsx)(Chip, { variant: "badge", children: activeSlot.label }),
|
|
8680
|
+
/* @__PURE__ */ (0, import_jsx_runtime85.jsx)("strong", { children: t.pickFor(activeSlot.label) })
|
|
8681
|
+
] }) : /* @__PURE__ */ (0, import_jsx_runtime85.jsx)("strong", { children: t.allPicked }) }),
|
|
8682
|
+
activeSlot && /* @__PURE__ */ (0, import_jsx_runtime85.jsxs)(import_jsx_runtime85.Fragment, { children: [
|
|
8683
|
+
/* @__PURE__ */ (0, import_jsx_runtime85.jsx)(
|
|
8288
8684
|
SearchField,
|
|
8289
8685
|
{
|
|
8290
8686
|
id: searchId,
|
|
@@ -8296,18 +8692,18 @@ function StartingXiGame({
|
|
|
8296
8692
|
disabled: submitting
|
|
8297
8693
|
}
|
|
8298
8694
|
),
|
|
8299
|
-
/* @__PURE__ */ (0,
|
|
8300
|
-
/* @__PURE__ */ (0,
|
|
8301
|
-
/* @__PURE__ */ (0,
|
|
8302
|
-
/* @__PURE__ */ (0,
|
|
8695
|
+
/* @__PURE__ */ (0, import_jsx_runtime85.jsx)("ul", { className: "ss-g-xi-list", children: available.map((p) => /* @__PURE__ */ (0, import_jsx_runtime85.jsx)("li", { children: /* @__PURE__ */ (0, import_jsx_runtime85.jsxs)("button", { type: "button", className: "ss-g-xi-opt", disabled: submitting, onClick: () => pick(p.playerId), children: [
|
|
8696
|
+
/* @__PURE__ */ (0, import_jsx_runtime85.jsx)("span", { className: "ss-g-xi-opt-no", "aria-hidden": "true", children: p.jerseyNumber ?? "" }),
|
|
8697
|
+
/* @__PURE__ */ (0, import_jsx_runtime85.jsx)("span", { className: "ss-g-xi-opt-name", children: p.playerName }),
|
|
8698
|
+
/* @__PURE__ */ (0, import_jsx_runtime85.jsx)("span", { className: "ss-g-xi-opt-pos", children: p.positionName })
|
|
8303
8699
|
] }) }, p.playerId)) })
|
|
8304
8700
|
] })
|
|
8305
8701
|
] })
|
|
8306
8702
|
] }),
|
|
8307
|
-
/* @__PURE__ */ (0,
|
|
8308
|
-
/* @__PURE__ */ (0,
|
|
8309
|
-
/* @__PURE__ */ (0,
|
|
8310
|
-
/* @__PURE__ */ (0,
|
|
8703
|
+
/* @__PURE__ */ (0, import_jsx_runtime85.jsxs)(FooterBar, { children: [
|
|
8704
|
+
/* @__PURE__ */ (0, import_jsx_runtime85.jsx)(GameButton, { variant: "primary", block: true, disabled: !canSubmit, onClick: handleSubmit, children: submitting ? t.submitting : t.submit }),
|
|
8705
|
+
/* @__PURE__ */ (0, import_jsx_runtime85.jsxs)("p", { className: "ss-g-xi-lock", children: [
|
|
8706
|
+
/* @__PURE__ */ (0, import_jsx_runtime85.jsx)(IconLock, {}),
|
|
8311
8707
|
lockAtUtc ? t.locksAt(ui.games.formatDayTime(lockAtUtc)) : t.locksSoon
|
|
8312
8708
|
] })
|
|
8313
8709
|
] })
|
|
@@ -8315,8 +8711,8 @@ function StartingXiGame({
|
|
|
8315
8711
|
}
|
|
8316
8712
|
|
|
8317
8713
|
// src/components/games/StatLadderGame.tsx
|
|
8318
|
-
var
|
|
8319
|
-
var
|
|
8714
|
+
var import_react52 = require("react");
|
|
8715
|
+
var import_jsx_runtime86 = require("react/jsx-runtime");
|
|
8320
8716
|
function ladderClue(ladder) {
|
|
8321
8717
|
const mystery = ladder.find((r) => r.rank === 2);
|
|
8322
8718
|
if (!mystery) return null;
|
|
@@ -8338,9 +8734,9 @@ function parseClientState9(json) {
|
|
|
8338
8734
|
}
|
|
8339
8735
|
function NameStack({ name }) {
|
|
8340
8736
|
const { first, last } = splitName(name);
|
|
8341
|
-
return /* @__PURE__ */ (0,
|
|
8342
|
-
first && /* @__PURE__ */ (0,
|
|
8343
|
-
/* @__PURE__ */ (0,
|
|
8737
|
+
return /* @__PURE__ */ (0, import_jsx_runtime86.jsxs)("span", { className: "ss-g-sl-name", children: [
|
|
8738
|
+
first && /* @__PURE__ */ (0, import_jsx_runtime86.jsx)("small", { children: `${first[0]}.` }),
|
|
8739
|
+
/* @__PURE__ */ (0, import_jsx_runtime86.jsx)("b", { children: last })
|
|
8344
8740
|
] });
|
|
8345
8741
|
}
|
|
8346
8742
|
function StatLadderGame({
|
|
@@ -8352,16 +8748,16 @@ function StatLadderGame({
|
|
|
8352
8748
|
onBack
|
|
8353
8749
|
}) {
|
|
8354
8750
|
const t = ui.games.statLadder;
|
|
8355
|
-
const [query, setQuery] = (0,
|
|
8356
|
-
const [selectedId, setSelectedId] = (0,
|
|
8357
|
-
const searchId = (0,
|
|
8751
|
+
const [query, setQuery] = (0, import_react52.useState)("");
|
|
8752
|
+
const [selectedId, setSelectedId] = (0, import_react52.useState)(null);
|
|
8753
|
+
const searchId = (0, import_react52.useId)();
|
|
8358
8754
|
const clientState = parseClientState9(result?.clientStateJson);
|
|
8359
8755
|
const revealed = clientState != null;
|
|
8360
|
-
const header = /* @__PURE__ */ (0,
|
|
8756
|
+
const header = /* @__PURE__ */ (0, import_jsx_runtime86.jsx)(GameHeader, { title: gameTitle({ gameId: "stat-ladder" }, ui.games.titles), eyebrow: t.eyebrow, onBack, backLabel: ui.back });
|
|
8361
8757
|
if (!config) {
|
|
8362
|
-
return /* @__PURE__ */ (0,
|
|
8758
|
+
return /* @__PURE__ */ (0, import_jsx_runtime86.jsxs)("div", { className: "ss-g-screen", "data-game": "stat-ladder", "data-testid": "game-screen-stat-ladder", children: [
|
|
8363
8759
|
header,
|
|
8364
|
-
/* @__PURE__ */ (0,
|
|
8760
|
+
/* @__PURE__ */ (0, import_jsx_runtime86.jsx)("div", { className: "ss-g-body ss-g-loading", children: ui.games.loading })
|
|
8365
8761
|
] });
|
|
8366
8762
|
}
|
|
8367
8763
|
const question = t.question(config.statLabel);
|
|
@@ -8373,45 +8769,45 @@ function StatLadderGame({
|
|
|
8373
8769
|
if (selectedId === null || submitting || revealed) return;
|
|
8374
8770
|
onSubmit(JSON.stringify({ guessedPlayerId: selectedId }));
|
|
8375
8771
|
}
|
|
8376
|
-
return /* @__PURE__ */ (0,
|
|
8772
|
+
return /* @__PURE__ */ (0, import_jsx_runtime86.jsxs)("div", { className: "ss-g-screen", "data-game": "stat-ladder", "data-testid": "game-screen-stat-ladder", children: [
|
|
8377
8773
|
header,
|
|
8378
|
-
/* @__PURE__ */ (0,
|
|
8379
|
-
!revealed && /* @__PURE__ */ (0,
|
|
8380
|
-
/* @__PURE__ */ (0,
|
|
8381
|
-
/* @__PURE__ */ (0,
|
|
8382
|
-
/* @__PURE__ */ (0,
|
|
8774
|
+
/* @__PURE__ */ (0, import_jsx_runtime86.jsxs)("div", { className: "ss-g-body", children: [
|
|
8775
|
+
!revealed && /* @__PURE__ */ (0, import_jsx_runtime86.jsx)(PointsLadderRow, { ladder: config.pointsLadder, guessesUsed: 0, ui }),
|
|
8776
|
+
/* @__PURE__ */ (0, import_jsx_runtime86.jsxs)("div", { className: "ss-g-sl-prompt", children: [
|
|
8777
|
+
/* @__PURE__ */ (0, import_jsx_runtime86.jsx)(Chip, { variant: "accent", icon: /* @__PURE__ */ (0, import_jsx_runtime86.jsx)(IconShield, { size: 14 }), className: "ss-g-sl-stat", children: config.statLabel }),
|
|
8778
|
+
/* @__PURE__ */ (0, import_jsx_runtime86.jsxs)("h3", { className: "ss-g-sl-q", children: [
|
|
8383
8779
|
question.pre,
|
|
8384
|
-
/* @__PURE__ */ (0,
|
|
8780
|
+
/* @__PURE__ */ (0, import_jsx_runtime86.jsx)("em", { children: question.emph }),
|
|
8385
8781
|
question.post
|
|
8386
8782
|
] })
|
|
8387
8783
|
] }),
|
|
8388
|
-
/* @__PURE__ */ (0,
|
|
8389
|
-
(rung) => rung.rank === 2 ? /* @__PURE__ */ (0,
|
|
8784
|
+
/* @__PURE__ */ (0, import_jsx_runtime86.jsx)("ol", { className: "ss-g-sl-rungs", children: rungs.map(
|
|
8785
|
+
(rung) => rung.rank === 2 ? /* @__PURE__ */ (0, import_jsx_runtime86.jsxs)(
|
|
8390
8786
|
"li",
|
|
8391
8787
|
{
|
|
8392
8788
|
className: "ss-g-sl-rung ss-g-sl-rung--mystery",
|
|
8393
8789
|
"data-testid": "sl-mystery-rung",
|
|
8394
8790
|
"data-result": revealed ? clientState.isCorrect ? "correct" : "wrong" : void 0,
|
|
8395
8791
|
children: [
|
|
8396
|
-
/* @__PURE__ */ (0,
|
|
8397
|
-
revealed ? /* @__PURE__ */ (0,
|
|
8398
|
-
revealed ? /* @__PURE__ */ (0,
|
|
8399
|
-
/* @__PURE__ */ (0,
|
|
8792
|
+
/* @__PURE__ */ (0, import_jsx_runtime86.jsx)("span", { className: "ss-g-sl-rank", children: "2" }),
|
|
8793
|
+
revealed ? /* @__PURE__ */ (0, import_jsx_runtime86.jsx)(PlayerAvatar, { name: clientState.revealedRank2.playerName, className: "ss-g-sl-av" }) : /* @__PURE__ */ (0, import_jsx_runtime86.jsx)(Silhouette, { size: 52, variant: "mystery" }),
|
|
8794
|
+
revealed ? /* @__PURE__ */ (0, import_jsx_runtime86.jsx)(NameStack, { name: clientState.revealedRank2.playerName }) : /* @__PURE__ */ (0, import_jsx_runtime86.jsx)("span", { className: "ss-g-sl-who", children: t.whoSecond }),
|
|
8795
|
+
/* @__PURE__ */ (0, import_jsx_runtime86.jsx)("span", { className: "ss-g-sl-val ss-g-sl-val--mystery", children: rung.statValue })
|
|
8400
8796
|
]
|
|
8401
8797
|
},
|
|
8402
8798
|
rung.rank
|
|
8403
|
-
) : /* @__PURE__ */ (0,
|
|
8404
|
-
/* @__PURE__ */ (0,
|
|
8405
|
-
/* @__PURE__ */ (0,
|
|
8406
|
-
/* @__PURE__ */ (0,
|
|
8407
|
-
/* @__PURE__ */ (0,
|
|
8799
|
+
) : /* @__PURE__ */ (0, import_jsx_runtime86.jsxs)("li", { className: "ss-g-sl-rung", children: [
|
|
8800
|
+
/* @__PURE__ */ (0, import_jsx_runtime86.jsx)("span", { className: "ss-g-sl-rank", children: rung.rank }),
|
|
8801
|
+
/* @__PURE__ */ (0, import_jsx_runtime86.jsx)(PlayerAvatar, { name: rung.playerName ?? "?", className: "ss-g-sl-av" }),
|
|
8802
|
+
/* @__PURE__ */ (0, import_jsx_runtime86.jsx)(NameStack, { name: rung.playerName ?? "?" }),
|
|
8803
|
+
/* @__PURE__ */ (0, import_jsx_runtime86.jsx)("span", { className: "ss-g-sl-val", children: rung.statValue })
|
|
8408
8804
|
] }, rung.rank)
|
|
8409
8805
|
) }),
|
|
8410
|
-
clue && /* @__PURE__ */ (0,
|
|
8411
|
-
/* @__PURE__ */ (0,
|
|
8412
|
-
/* @__PURE__ */ (0,
|
|
8806
|
+
clue && /* @__PURE__ */ (0, import_jsx_runtime86.jsxs)("p", { className: "ss-g-sl-clue", children: [
|
|
8807
|
+
/* @__PURE__ */ (0, import_jsx_runtime86.jsx)(IconBulb, {}),
|
|
8808
|
+
/* @__PURE__ */ (0, import_jsx_runtime86.jsx)("span", { children: t.clue(clue, config.statLabel) })
|
|
8413
8809
|
] }),
|
|
8414
|
-
!revealed && /* @__PURE__ */ (0,
|
|
8810
|
+
!revealed && /* @__PURE__ */ (0, import_jsx_runtime86.jsx)("ul", { className: "ss-g-sl-pool", children: pool.map((p) => /* @__PURE__ */ (0, import_jsx_runtime86.jsx)("li", { children: /* @__PURE__ */ (0, import_jsx_runtime86.jsxs)(
|
|
8415
8811
|
"button",
|
|
8416
8812
|
{
|
|
8417
8813
|
type: "button",
|
|
@@ -8424,13 +8820,13 @@ function StatLadderGame({
|
|
|
8424
8820
|
setQuery(p.playerName);
|
|
8425
8821
|
},
|
|
8426
8822
|
children: [
|
|
8427
|
-
/* @__PURE__ */ (0,
|
|
8428
|
-
/* @__PURE__ */ (0,
|
|
8429
|
-
selectedId === p.playerId && /* @__PURE__ */ (0,
|
|
8823
|
+
/* @__PURE__ */ (0, import_jsx_runtime86.jsx)(PlayerAvatar, { name: p.playerName, className: "ss-g-sl-opt-av" }),
|
|
8824
|
+
/* @__PURE__ */ (0, import_jsx_runtime86.jsx)("span", { className: "ss-g-sl-opt-name", children: p.playerName }),
|
|
8825
|
+
selectedId === p.playerId && /* @__PURE__ */ (0, import_jsx_runtime86.jsx)(IconCheck, {})
|
|
8430
8826
|
]
|
|
8431
8827
|
}
|
|
8432
8828
|
) }, p.playerId)) }),
|
|
8433
|
-
revealed && /* @__PURE__ */ (0,
|
|
8829
|
+
revealed && /* @__PURE__ */ (0, import_jsx_runtime86.jsx)(
|
|
8434
8830
|
ResultCard,
|
|
8435
8831
|
{
|
|
8436
8832
|
tone: clientState.isCorrect ? "win" : "lose",
|
|
@@ -8441,8 +8837,8 @@ function StatLadderGame({
|
|
|
8441
8837
|
}
|
|
8442
8838
|
)
|
|
8443
8839
|
] }),
|
|
8444
|
-
!revealed && /* @__PURE__ */ (0,
|
|
8445
|
-
/* @__PURE__ */ (0,
|
|
8840
|
+
!revealed && /* @__PURE__ */ (0, import_jsx_runtime86.jsx)(FooterBar, { children: /* @__PURE__ */ (0, import_jsx_runtime86.jsxs)("div", { className: "ss-g-sl-guess", children: [
|
|
8841
|
+
/* @__PURE__ */ (0, import_jsx_runtime86.jsx)(
|
|
8446
8842
|
SearchField,
|
|
8447
8843
|
{
|
|
8448
8844
|
id: searchId,
|
|
@@ -8457,13 +8853,13 @@ function StatLadderGame({
|
|
|
8457
8853
|
disabled: submitting
|
|
8458
8854
|
}
|
|
8459
8855
|
),
|
|
8460
|
-
/* @__PURE__ */ (0,
|
|
8856
|
+
/* @__PURE__ */ (0, import_jsx_runtime86.jsx)(GameButton, { variant: "primary", disabled: selectedId === null || submitting, onClick: guess, children: t.guess })
|
|
8461
8857
|
] }) })
|
|
8462
8858
|
] });
|
|
8463
8859
|
}
|
|
8464
8860
|
|
|
8465
8861
|
// src/components/games/FanMotmGame.tsx
|
|
8466
|
-
var
|
|
8862
|
+
var import_jsx_runtime87 = require("react/jsx-runtime");
|
|
8467
8863
|
function parseClientState10(json) {
|
|
8468
8864
|
if (!json) return null;
|
|
8469
8865
|
try {
|
|
@@ -8484,20 +8880,20 @@ function FanMotmGame({
|
|
|
8484
8880
|
const clientState = parseClientState10(result?.clientStateJson);
|
|
8485
8881
|
const alreadyVoted = result?.alreadyPlayed === true;
|
|
8486
8882
|
const pickedId = clientState?.pickedPlayerId ?? null;
|
|
8487
|
-
const header = /* @__PURE__ */ (0,
|
|
8883
|
+
const header = /* @__PURE__ */ (0, import_jsx_runtime87.jsx)(
|
|
8488
8884
|
GameHeader,
|
|
8489
8885
|
{
|
|
8490
8886
|
title: t.title,
|
|
8491
8887
|
eyebrow: t.eyebrow,
|
|
8492
|
-
right: alreadyVoted ? /* @__PURE__ */ (0,
|
|
8888
|
+
right: alreadyVoted ? /* @__PURE__ */ (0, import_jsx_runtime87.jsx)(Chip, { variant: "success", icon: /* @__PURE__ */ (0, import_jsx_runtime87.jsx)(IconCheck, {}), children: t.voted }) : void 0,
|
|
8493
8889
|
onBack,
|
|
8494
8890
|
backLabel: ui.back
|
|
8495
8891
|
}
|
|
8496
8892
|
);
|
|
8497
8893
|
if (!config) {
|
|
8498
|
-
return /* @__PURE__ */ (0,
|
|
8894
|
+
return /* @__PURE__ */ (0, import_jsx_runtime87.jsxs)("div", { className: "ss-g-screen", "data-game": "fan-motm", "data-testid": "game-screen-fan-motm", children: [
|
|
8499
8895
|
header,
|
|
8500
|
-
/* @__PURE__ */ (0,
|
|
8896
|
+
/* @__PURE__ */ (0, import_jsx_runtime87.jsx)("div", { className: "ss-g-body ss-g-loading", children: ui.games.loading })
|
|
8501
8897
|
] });
|
|
8502
8898
|
}
|
|
8503
8899
|
const picked = config.candidates.find((c) => c.playerId === pickedId) ?? null;
|
|
@@ -8505,12 +8901,12 @@ function FanMotmGame({
|
|
|
8505
8901
|
if (alreadyVoted || submitting) return;
|
|
8506
8902
|
onSubmit(JSON.stringify({ pickedPlayerId: candidateId }));
|
|
8507
8903
|
}
|
|
8508
|
-
return /* @__PURE__ */ (0,
|
|
8904
|
+
return /* @__PURE__ */ (0, import_jsx_runtime87.jsxs)("div", { className: "ss-g-screen", "data-game": "fan-motm", "data-testid": "game-screen-fan-motm", children: [
|
|
8509
8905
|
header,
|
|
8510
|
-
/* @__PURE__ */ (0,
|
|
8511
|
-
/* @__PURE__ */ (0,
|
|
8906
|
+
/* @__PURE__ */ (0, import_jsx_runtime87.jsxs)("div", { className: "ss-g-body", children: [
|
|
8907
|
+
/* @__PURE__ */ (0, import_jsx_runtime87.jsx)("ul", { className: "ss-g-motm-list", children: config.candidates.map((c) => {
|
|
8512
8908
|
const isVoted = alreadyVoted && pickedId === c.playerId;
|
|
8513
|
-
return /* @__PURE__ */ (0,
|
|
8909
|
+
return /* @__PURE__ */ (0, import_jsx_runtime87.jsx)("li", { children: /* @__PURE__ */ (0, import_jsx_runtime87.jsxs)(
|
|
8514
8910
|
"button",
|
|
8515
8911
|
{
|
|
8516
8912
|
type: "button",
|
|
@@ -8519,24 +8915,24 @@ function FanMotmGame({
|
|
|
8519
8915
|
disabled: alreadyVoted || submitting,
|
|
8520
8916
|
onClick: () => handleVote(c.playerId),
|
|
8521
8917
|
children: [
|
|
8522
|
-
/* @__PURE__ */ (0,
|
|
8523
|
-
/* @__PURE__ */ (0,
|
|
8524
|
-
isVoted && /* @__PURE__ */ (0,
|
|
8918
|
+
/* @__PURE__ */ (0, import_jsx_runtime87.jsx)(PlayerAvatar, { name: c.playerName, className: "ss-g-motm-av" }),
|
|
8919
|
+
/* @__PURE__ */ (0, import_jsx_runtime87.jsx)("span", { className: "ss-g-motm-name", children: c.playerName }),
|
|
8920
|
+
isVoted && /* @__PURE__ */ (0, import_jsx_runtime87.jsx)(Chip, { variant: "accent", className: "ss-g-motm-pill", children: t.yourVote })
|
|
8525
8921
|
]
|
|
8526
8922
|
}
|
|
8527
8923
|
) }, c.playerId);
|
|
8528
8924
|
}) }),
|
|
8529
|
-
alreadyVoted && picked && /* @__PURE__ */ (0,
|
|
8925
|
+
alreadyVoted && picked && /* @__PURE__ */ (0, import_jsx_runtime87.jsx)(ResultCard, { tone: "neutral", title: t.youVoted(picked.playerName), detail: t.thanks, onBack, ui })
|
|
8530
8926
|
] }),
|
|
8531
|
-
/* @__PURE__ */ (0,
|
|
8532
|
-
!alreadyVoted && /* @__PURE__ */ (0,
|
|
8533
|
-
/* @__PURE__ */ (0,
|
|
8927
|
+
/* @__PURE__ */ (0, import_jsx_runtime87.jsxs)(FooterBar, { children: [
|
|
8928
|
+
!alreadyVoted && /* @__PURE__ */ (0, import_jsx_runtime87.jsx)("p", { className: "ss-g-motm-foot", children: t.tapToVote }),
|
|
8929
|
+
/* @__PURE__ */ (0, import_jsx_runtime87.jsx)("p", { className: "ss-g-motm-fun", children: t.forFun })
|
|
8534
8930
|
] })
|
|
8535
8931
|
] });
|
|
8536
8932
|
}
|
|
8537
8933
|
|
|
8538
8934
|
// src/components/GameScreenHost.tsx
|
|
8539
|
-
var
|
|
8935
|
+
var import_jsx_runtime88 = require("react/jsx-runtime");
|
|
8540
8936
|
var FIXTURE_GAME_IDS = /* @__PURE__ */ new Set([
|
|
8541
8937
|
"matchday-predictor",
|
|
8542
8938
|
"starting-xi",
|
|
@@ -8560,8 +8956,8 @@ function GameScreenHost({
|
|
|
8560
8956
|
ui
|
|
8561
8957
|
}) {
|
|
8562
8958
|
const { gameId, fixtureId, gameDay = "", lockAtUtc = null } = selected;
|
|
8563
|
-
const [configJson, setConfigJson] = (0,
|
|
8564
|
-
(0,
|
|
8959
|
+
const [configJson, setConfigJson] = (0, import_react53.useState)(null);
|
|
8960
|
+
(0, import_react53.useEffect)(() => {
|
|
8565
8961
|
setConfigJson(null);
|
|
8566
8962
|
if (!conversation) return;
|
|
8567
8963
|
let cancelled = false;
|
|
@@ -8584,12 +8980,12 @@ function GameScreenHost({
|
|
|
8584
8980
|
fixtureId: fixtureId || void 0,
|
|
8585
8981
|
locale: ui.games.lang
|
|
8586
8982
|
});
|
|
8587
|
-
(0,
|
|
8983
|
+
(0, import_react53.useEffect)(() => {
|
|
8588
8984
|
if (conversation) hydrate();
|
|
8589
8985
|
}, [conversation, gameId]);
|
|
8590
|
-
const hydrateRef = (0,
|
|
8986
|
+
const hydrateRef = (0, import_react53.useRef)(hydrate);
|
|
8591
8987
|
hydrateRef.current = hydrate;
|
|
8592
|
-
(0,
|
|
8988
|
+
(0, import_react53.useEffect)(() => {
|
|
8593
8989
|
if (!FIXTURE_GAME_IDS.has(gameId)) return;
|
|
8594
8990
|
if (rawStatus !== "pending") return;
|
|
8595
8991
|
const timerId = setInterval(() => {
|
|
@@ -8612,7 +9008,7 @@ function GameScreenHost({
|
|
|
8612
9008
|
function renderScreen() {
|
|
8613
9009
|
switch (gameId) {
|
|
8614
9010
|
case "mystery-tiger":
|
|
8615
|
-
return /* @__PURE__ */ (0,
|
|
9011
|
+
return /* @__PURE__ */ (0, import_jsx_runtime88.jsx)(
|
|
8616
9012
|
MysteryTigerGame,
|
|
8617
9013
|
{
|
|
8618
9014
|
...sharedProps,
|
|
@@ -8620,7 +9016,7 @@ function GameScreenHost({
|
|
|
8620
9016
|
}
|
|
8621
9017
|
);
|
|
8622
9018
|
case "higher-or-lower":
|
|
8623
|
-
return /* @__PURE__ */ (0,
|
|
9019
|
+
return /* @__PURE__ */ (0, import_jsx_runtime88.jsx)(
|
|
8624
9020
|
HigherOrLowerGame,
|
|
8625
9021
|
{
|
|
8626
9022
|
...sharedProps,
|
|
@@ -8628,7 +9024,7 @@ function GameScreenHost({
|
|
|
8628
9024
|
}
|
|
8629
9025
|
);
|
|
8630
9026
|
case "career-path":
|
|
8631
|
-
return /* @__PURE__ */ (0,
|
|
9027
|
+
return /* @__PURE__ */ (0, import_jsx_runtime88.jsx)(
|
|
8632
9028
|
CareerPathGame,
|
|
8633
9029
|
{
|
|
8634
9030
|
...sharedProps,
|
|
@@ -8637,7 +9033,7 @@ function GameScreenHost({
|
|
|
8637
9033
|
);
|
|
8638
9034
|
case "beat-the-grid": {
|
|
8639
9035
|
const btgConfig = safeParseConfig(configJson);
|
|
8640
|
-
return /* @__PURE__ */ (0,
|
|
9036
|
+
return /* @__PURE__ */ (0, import_jsx_runtime88.jsx)(
|
|
8641
9037
|
BeatTheGridGame,
|
|
8642
9038
|
{
|
|
8643
9039
|
...sharedProps,
|
|
@@ -8647,7 +9043,7 @@ function GameScreenHost({
|
|
|
8647
9043
|
);
|
|
8648
9044
|
}
|
|
8649
9045
|
case "guess-the-xi":
|
|
8650
|
-
return /* @__PURE__ */ (0,
|
|
9046
|
+
return /* @__PURE__ */ (0, import_jsx_runtime88.jsx)(
|
|
8651
9047
|
GuessTheXiGame,
|
|
8652
9048
|
{
|
|
8653
9049
|
...sharedProps,
|
|
@@ -8655,7 +9051,7 @@ function GameScreenHost({
|
|
|
8655
9051
|
}
|
|
8656
9052
|
);
|
|
8657
9053
|
case "daily-quiz":
|
|
8658
|
-
return /* @__PURE__ */ (0,
|
|
9054
|
+
return /* @__PURE__ */ (0, import_jsx_runtime88.jsx)(
|
|
8659
9055
|
DailyQuizGame,
|
|
8660
9056
|
{
|
|
8661
9057
|
...sharedProps,
|
|
@@ -8663,7 +9059,7 @@ function GameScreenHost({
|
|
|
8663
9059
|
}
|
|
8664
9060
|
);
|
|
8665
9061
|
case "matchday-predictor":
|
|
8666
|
-
return /* @__PURE__ */ (0,
|
|
9062
|
+
return /* @__PURE__ */ (0, import_jsx_runtime88.jsx)(
|
|
8667
9063
|
MatchdayPredictorGame,
|
|
8668
9064
|
{
|
|
8669
9065
|
...sharedProps,
|
|
@@ -8671,7 +9067,7 @@ function GameScreenHost({
|
|
|
8671
9067
|
}
|
|
8672
9068
|
);
|
|
8673
9069
|
case "starting-xi":
|
|
8674
|
-
return /* @__PURE__ */ (0,
|
|
9070
|
+
return /* @__PURE__ */ (0, import_jsx_runtime88.jsx)(
|
|
8675
9071
|
StartingXiGame,
|
|
8676
9072
|
{
|
|
8677
9073
|
...sharedProps,
|
|
@@ -8679,7 +9075,7 @@ function GameScreenHost({
|
|
|
8679
9075
|
}
|
|
8680
9076
|
);
|
|
8681
9077
|
case "stat-ladder":
|
|
8682
|
-
return /* @__PURE__ */ (0,
|
|
9078
|
+
return /* @__PURE__ */ (0, import_jsx_runtime88.jsx)(
|
|
8683
9079
|
StatLadderGame,
|
|
8684
9080
|
{
|
|
8685
9081
|
...sharedProps,
|
|
@@ -8687,7 +9083,7 @@ function GameScreenHost({
|
|
|
8687
9083
|
}
|
|
8688
9084
|
);
|
|
8689
9085
|
case "fan-motm":
|
|
8690
|
-
return /* @__PURE__ */ (0,
|
|
9086
|
+
return /* @__PURE__ */ (0, import_jsx_runtime88.jsx)(
|
|
8691
9087
|
FanMotmGame,
|
|
8692
9088
|
{
|
|
8693
9089
|
...sharedProps,
|
|
@@ -8695,10 +9091,10 @@ function GameScreenHost({
|
|
|
8695
9091
|
}
|
|
8696
9092
|
);
|
|
8697
9093
|
default:
|
|
8698
|
-
return /* @__PURE__ */ (0,
|
|
9094
|
+
return /* @__PURE__ */ (0, import_jsx_runtime88.jsx)("div", { className: "ss-g-screen", "data-testid": `game-screen-${gameId}`, children: /* @__PURE__ */ (0, import_jsx_runtime88.jsx)(GameHeader, { title: gameTitle({ gameId }, ui.games.titles), onBack, backLabel: ui.back }) });
|
|
8699
9095
|
}
|
|
8700
9096
|
}
|
|
8701
|
-
return /* @__PURE__ */ (0,
|
|
9097
|
+
return /* @__PURE__ */ (0, import_jsx_runtime88.jsx)("div", { className: "ss-w-gscreen", "data-testid": "gscreen", "data-lock-at": lockAtUtc ?? void 0, children: renderScreen() });
|
|
8702
9098
|
}
|
|
8703
9099
|
|
|
8704
9100
|
// src/components/games/ui/fonts.ts
|
|
@@ -8715,7 +9111,7 @@ function ensureGamesFonts(doc = document) {
|
|
|
8715
9111
|
}
|
|
8716
9112
|
|
|
8717
9113
|
// src/components/GamesPanel.tsx
|
|
8718
|
-
var
|
|
9114
|
+
var import_jsx_runtime89 = require("react/jsx-runtime");
|
|
8719
9115
|
function GamesPanel({
|
|
8720
9116
|
loggedIn,
|
|
8721
9117
|
games,
|
|
@@ -8724,13 +9120,13 @@ function GamesPanel({
|
|
|
8724
9120
|
leaderboard,
|
|
8725
9121
|
refreshHub
|
|
8726
9122
|
}) {
|
|
8727
|
-
const [selected, setSelected] = (0,
|
|
8728
|
-
(0,
|
|
9123
|
+
const [selected, setSelected] = (0, import_react54.useState)(null);
|
|
9124
|
+
(0, import_react54.useEffect)(() => {
|
|
8729
9125
|
ensureGamesFonts();
|
|
8730
9126
|
}, []);
|
|
8731
|
-
if (!loggedIn) return /* @__PURE__ */ (0,
|
|
9127
|
+
if (!loggedIn) return /* @__PURE__ */ (0, import_jsx_runtime89.jsx)(GamesLoginWall, { ui });
|
|
8732
9128
|
if (selected !== null) {
|
|
8733
|
-
return /* @__PURE__ */ (0,
|
|
9129
|
+
return /* @__PURE__ */ (0, import_jsx_runtime89.jsx)("div", { className: "ss-w-gscreen-wrap", lang: ui.games.lang, children: /* @__PURE__ */ (0, import_jsx_runtime89.jsx)(
|
|
8734
9130
|
GameScreenHost,
|
|
8735
9131
|
{
|
|
8736
9132
|
selected,
|
|
@@ -8744,7 +9140,7 @@ function GamesPanel({
|
|
|
8744
9140
|
}
|
|
8745
9141
|
) });
|
|
8746
9142
|
}
|
|
8747
|
-
return /* @__PURE__ */ (0,
|
|
9143
|
+
return /* @__PURE__ */ (0, import_jsx_runtime89.jsx)("div", { className: "ss-g-hub-wrap", "data-testid": "games-hub", lang: ui.games.lang, children: /* @__PURE__ */ (0, import_jsx_runtime89.jsx)(
|
|
8748
9144
|
GamesHub,
|
|
8749
9145
|
{
|
|
8750
9146
|
games,
|
|
@@ -8756,10 +9152,10 @@ function GamesPanel({
|
|
|
8756
9152
|
}
|
|
8757
9153
|
|
|
8758
9154
|
// src/components/Leaderboard.tsx
|
|
8759
|
-
var
|
|
9155
|
+
var import_react55 = require("react");
|
|
8760
9156
|
|
|
8761
9157
|
// src/components/LeaderboardRow.tsx
|
|
8762
|
-
var
|
|
9158
|
+
var import_jsx_runtime90 = require("react/jsx-runtime");
|
|
8763
9159
|
function formatPoints(n) {
|
|
8764
9160
|
return n.toLocaleString("en");
|
|
8765
9161
|
}
|
|
@@ -8768,14 +9164,14 @@ function LeaderboardWeeklyRow({
|
|
|
8768
9164
|
isMe
|
|
8769
9165
|
}) {
|
|
8770
9166
|
const rankClass = `ss-w-lb2-rank${row.rank <= 3 ? " ss-w-lb2-rank--top3" : ""}`;
|
|
8771
|
-
return /* @__PURE__ */ (0,
|
|
8772
|
-
/* @__PURE__ */ (0,
|
|
9167
|
+
return /* @__PURE__ */ (0, import_jsx_runtime90.jsxs)("div", { className: `ss-w-lb2-row${isMe ? " ss-w-lb2-row--you" : ""}`, children: [
|
|
9168
|
+
/* @__PURE__ */ (0, import_jsx_runtime90.jsxs)("span", { className: rankClass, children: [
|
|
8773
9169
|
"#",
|
|
8774
9170
|
row.rank
|
|
8775
9171
|
] }),
|
|
8776
|
-
/* @__PURE__ */ (0,
|
|
8777
|
-
/* @__PURE__ */ (0,
|
|
8778
|
-
row.currentStreak > 0 && /* @__PURE__ */ (0,
|
|
9172
|
+
/* @__PURE__ */ (0, import_jsx_runtime90.jsx)("span", { className: "ss-w-lb2-handle", children: row.handle }),
|
|
9173
|
+
/* @__PURE__ */ (0, import_jsx_runtime90.jsx)("span", { className: "ss-w-lb2-points", children: formatPoints(row.points) }),
|
|
9174
|
+
row.currentStreak > 0 && /* @__PURE__ */ (0, import_jsx_runtime90.jsxs)("span", { className: "ss-w-lb2-streak", children: [
|
|
8779
9175
|
"\u{1F525} ",
|
|
8780
9176
|
row.currentStreak
|
|
8781
9177
|
] })
|
|
@@ -8786,18 +9182,18 @@ function LeaderboardAllTimeRow({
|
|
|
8786
9182
|
isMe
|
|
8787
9183
|
}) {
|
|
8788
9184
|
const rankClass = `ss-w-lb2-rank${row.rank <= 3 ? " ss-w-lb2-rank--top3" : ""}`;
|
|
8789
|
-
return /* @__PURE__ */ (0,
|
|
8790
|
-
/* @__PURE__ */ (0,
|
|
9185
|
+
return /* @__PURE__ */ (0, import_jsx_runtime90.jsxs)("div", { className: `ss-w-lb2-row${isMe ? " ss-w-lb2-row--you" : ""}`, children: [
|
|
9186
|
+
/* @__PURE__ */ (0, import_jsx_runtime90.jsxs)("span", { className: rankClass, children: [
|
|
8791
9187
|
"#",
|
|
8792
9188
|
row.rank
|
|
8793
9189
|
] }),
|
|
8794
|
-
/* @__PURE__ */ (0,
|
|
8795
|
-
/* @__PURE__ */ (0,
|
|
9190
|
+
/* @__PURE__ */ (0, import_jsx_runtime90.jsx)("span", { className: "ss-w-lb2-handle", children: row.handle }),
|
|
9191
|
+
/* @__PURE__ */ (0, import_jsx_runtime90.jsx)("span", { className: "ss-w-lb2-points", children: formatPoints(row.allTimePoints) })
|
|
8796
9192
|
] });
|
|
8797
9193
|
}
|
|
8798
9194
|
|
|
8799
9195
|
// src/components/LeaderboardEmpty.tsx
|
|
8800
|
-
var
|
|
9196
|
+
var import_jsx_runtime91 = require("react/jsx-runtime");
|
|
8801
9197
|
function LeaderboardEmpty({
|
|
8802
9198
|
segment,
|
|
8803
9199
|
lastWeek,
|
|
@@ -8806,48 +9202,48 @@ function LeaderboardEmpty({
|
|
|
8806
9202
|
ui
|
|
8807
9203
|
}) {
|
|
8808
9204
|
if (segment === "alltime") {
|
|
8809
|
-
return /* @__PURE__ */ (0,
|
|
8810
|
-
/* @__PURE__ */ (0,
|
|
8811
|
-
/* @__PURE__ */ (0,
|
|
9205
|
+
return /* @__PURE__ */ (0, import_jsx_runtime91.jsxs)("div", { className: "ss-w-lb-empty ss-w-lb-empty--alltime", children: [
|
|
9206
|
+
/* @__PURE__ */ (0, import_jsx_runtime91.jsx)("div", { className: "ss-w-lb-empty-icon", "aria-hidden": "true", children: "\u{1F4CA}" }),
|
|
9207
|
+
/* @__PURE__ */ (0, import_jsx_runtime91.jsx)("p", { className: "ss-w-lb-empty-body", children: ui.leaderboardAllTimeEmpty })
|
|
8812
9208
|
] });
|
|
8813
9209
|
}
|
|
8814
9210
|
const fresh = lastWeek != null;
|
|
8815
9211
|
const title = fresh ? ui.leaderboardEmptyFreshTitle : ui.leaderboardEmptyColdTitle;
|
|
8816
9212
|
const body = fresh ? ui.leaderboardEmptyFreshBody : ui.leaderboardEmptyColdBody;
|
|
8817
|
-
return /* @__PURE__ */ (0,
|
|
8818
|
-
weeklyPrize && /* @__PURE__ */ (0,
|
|
8819
|
-
/* @__PURE__ */ (0,
|
|
8820
|
-
/* @__PURE__ */ (0,
|
|
9213
|
+
return /* @__PURE__ */ (0, import_jsx_runtime91.jsxs)("div", { className: "ss-w-lb-empty", children: [
|
|
9214
|
+
weeklyPrize && /* @__PURE__ */ (0, import_jsx_runtime91.jsxs)("div", { className: "ss-w-prize", children: [
|
|
9215
|
+
/* @__PURE__ */ (0, import_jsx_runtime91.jsx)("span", { className: "ss-w-prize-icon", "aria-hidden": "true", children: "\u{1F3C6}" }),
|
|
9216
|
+
/* @__PURE__ */ (0, import_jsx_runtime91.jsx)("div", { className: "ss-w-prize-body", children: /* @__PURE__ */ (0, import_jsx_runtime91.jsx)("span", { className: "ss-w-prize-text", children: weeklyPrize }) })
|
|
8821
9217
|
] }),
|
|
8822
|
-
/* @__PURE__ */ (0,
|
|
8823
|
-
/* @__PURE__ */ (0,
|
|
8824
|
-
/* @__PURE__ */ (0,
|
|
8825
|
-
/* @__PURE__ */ (0,
|
|
8826
|
-
onPlay && /* @__PURE__ */ (0,
|
|
9218
|
+
/* @__PURE__ */ (0, import_jsx_runtime91.jsxs)("div", { className: "ss-w-lb-empty-hero", children: [
|
|
9219
|
+
/* @__PURE__ */ (0, import_jsx_runtime91.jsx)("div", { className: "ss-w-lb-empty-icon", "aria-hidden": "true", children: fresh ? "\u{1F3C6}" : "\u{1F3AE}" }),
|
|
9220
|
+
/* @__PURE__ */ (0, import_jsx_runtime91.jsx)("h4", { className: "ss-w-lb-empty-title", children: title }),
|
|
9221
|
+
/* @__PURE__ */ (0, import_jsx_runtime91.jsx)("p", { className: "ss-w-lb-empty-body", children: body }),
|
|
9222
|
+
onPlay && /* @__PURE__ */ (0, import_jsx_runtime91.jsx)("button", { type: "button", className: "ss-w-lb-empty-cta", onClick: onPlay, children: ui.leaderboardEmptyCta })
|
|
8827
9223
|
] }),
|
|
8828
|
-
fresh && lastWeek && /* @__PURE__ */ (0,
|
|
8829
|
-
/* @__PURE__ */ (0,
|
|
8830
|
-
/* @__PURE__ */ (0,
|
|
8831
|
-
/* @__PURE__ */ (0,
|
|
8832
|
-
/* @__PURE__ */ (0,
|
|
9224
|
+
fresh && lastWeek && /* @__PURE__ */ (0, import_jsx_runtime91.jsxs)("div", { className: "ss-w-lb-last", children: [
|
|
9225
|
+
/* @__PURE__ */ (0, import_jsx_runtime91.jsx)("span", { className: "ss-w-lb-last-label", children: ui.leaderboardLastWeekLabel }),
|
|
9226
|
+
/* @__PURE__ */ (0, import_jsx_runtime91.jsx)("span", { className: "ss-w-lb-last-champ", "aria-hidden": "true", children: "\u{1F947}" }),
|
|
9227
|
+
/* @__PURE__ */ (0, import_jsx_runtime91.jsx)("span", { className: "ss-w-lb-last-handle", children: lastWeek.handle }),
|
|
9228
|
+
/* @__PURE__ */ (0, import_jsx_runtime91.jsx)("span", { className: "ss-w-lb-last-points", children: formatPoints(lastWeek.points) })
|
|
8833
9229
|
] })
|
|
8834
9230
|
] });
|
|
8835
9231
|
}
|
|
8836
9232
|
|
|
8837
9233
|
// src/components/Leaderboard.tsx
|
|
8838
|
-
var
|
|
9234
|
+
var import_jsx_runtime92 = require("react/jsx-runtime");
|
|
8839
9235
|
function Leaderboard({
|
|
8840
9236
|
data,
|
|
8841
9237
|
ui,
|
|
8842
9238
|
onPlay
|
|
8843
9239
|
}) {
|
|
8844
|
-
const [segment, setSegment] = (0,
|
|
9240
|
+
const [segment, setSegment] = (0, import_react55.useState)("weekly");
|
|
8845
9241
|
const myRow = segment === "weekly" ? data.myWeeklyRow : data.myAllTimeRow;
|
|
8846
9242
|
const offBoard = myRow !== null && myRow !== void 0 && myRow.rank === -1;
|
|
8847
9243
|
const isEmpty = segment === "weekly" ? data.weeklyTop.length === 0 : data.allTimeTop.length === 0;
|
|
8848
|
-
return /* @__PURE__ */ (0,
|
|
8849
|
-
/* @__PURE__ */ (0,
|
|
8850
|
-
/* @__PURE__ */ (0,
|
|
9244
|
+
return /* @__PURE__ */ (0, import_jsx_runtime92.jsxs)("div", { className: "ss-w-lb2", children: [
|
|
9245
|
+
/* @__PURE__ */ (0, import_jsx_runtime92.jsxs)("div", { className: "ss-w-seg", children: [
|
|
9246
|
+
/* @__PURE__ */ (0, import_jsx_runtime92.jsx)(
|
|
8851
9247
|
"button",
|
|
8852
9248
|
{
|
|
8853
9249
|
type: "button",
|
|
@@ -8857,7 +9253,7 @@ function Leaderboard({
|
|
|
8857
9253
|
children: ui.leaderboardThisWeek
|
|
8858
9254
|
}
|
|
8859
9255
|
),
|
|
8860
|
-
/* @__PURE__ */ (0,
|
|
9256
|
+
/* @__PURE__ */ (0, import_jsx_runtime92.jsx)(
|
|
8861
9257
|
"button",
|
|
8862
9258
|
{
|
|
8863
9259
|
type: "button",
|
|
@@ -8868,7 +9264,7 @@ function Leaderboard({
|
|
|
8868
9264
|
}
|
|
8869
9265
|
)
|
|
8870
9266
|
] }),
|
|
8871
|
-
isEmpty ? /* @__PURE__ */ (0,
|
|
9267
|
+
isEmpty ? /* @__PURE__ */ (0, import_jsx_runtime92.jsx)(
|
|
8872
9268
|
LeaderboardEmpty,
|
|
8873
9269
|
{
|
|
8874
9270
|
segment,
|
|
@@ -8877,15 +9273,15 @@ function Leaderboard({
|
|
|
8877
9273
|
onPlay,
|
|
8878
9274
|
ui
|
|
8879
9275
|
}
|
|
8880
|
-
) : /* @__PURE__ */ (0,
|
|
8881
|
-
/* @__PURE__ */ (0,
|
|
9276
|
+
) : /* @__PURE__ */ (0, import_jsx_runtime92.jsxs)(import_jsx_runtime92.Fragment, { children: [
|
|
9277
|
+
/* @__PURE__ */ (0, import_jsx_runtime92.jsx)("div", { className: "ss-w-lb2-rows", children: segment === "weekly" ? data.weeklyTop.map((row) => /* @__PURE__ */ (0, import_jsx_runtime92.jsx)(
|
|
8882
9278
|
LeaderboardWeeklyRow,
|
|
8883
9279
|
{
|
|
8884
9280
|
row,
|
|
8885
9281
|
isMe: row.operatorUserId === data.myWeeklyRow?.operatorUserId
|
|
8886
9282
|
},
|
|
8887
9283
|
row.operatorUserId
|
|
8888
|
-
)) : data.allTimeTop.map((row) => /* @__PURE__ */ (0,
|
|
9284
|
+
)) : data.allTimeTop.map((row) => /* @__PURE__ */ (0, import_jsx_runtime92.jsx)(
|
|
8889
9285
|
LeaderboardAllTimeRow,
|
|
8890
9286
|
{
|
|
8891
9287
|
row,
|
|
@@ -8893,18 +9289,18 @@ function Leaderboard({
|
|
|
8893
9289
|
},
|
|
8894
9290
|
row.operatorUserId
|
|
8895
9291
|
)) }),
|
|
8896
|
-
/* @__PURE__ */ (0,
|
|
8897
|
-
myRow != null && (offBoard ? /* @__PURE__ */ (0,
|
|
8898
|
-
segment === "weekly" && data.myWeeklyRow && /* @__PURE__ */ (0,
|
|
8899
|
-
segment === "alltime" && data.myAllTimeRow && /* @__PURE__ */ (0,
|
|
9292
|
+
/* @__PURE__ */ (0, import_jsx_runtime92.jsx)("div", { className: "ss-w-kitline", children: "\u{1F3BD}" }),
|
|
9293
|
+
myRow != null && (offBoard ? /* @__PURE__ */ (0, import_jsx_runtime92.jsx)("div", { className: "ss-w-lbgap", children: ui.leaderboardOffBoard }) : /* @__PURE__ */ (0, import_jsx_runtime92.jsxs)("div", { className: "ss-w-lb2-rows", children: [
|
|
9294
|
+
segment === "weekly" && data.myWeeklyRow && /* @__PURE__ */ (0, import_jsx_runtime92.jsx)(LeaderboardWeeklyRow, { row: data.myWeeklyRow, isMe: true }),
|
|
9295
|
+
segment === "alltime" && data.myAllTimeRow && /* @__PURE__ */ (0, import_jsx_runtime92.jsx)(LeaderboardAllTimeRow, { row: data.myAllTimeRow, isMe: true })
|
|
8900
9296
|
] })),
|
|
8901
|
-
segment === "alltime" && data.myAllTimeRow && !offBoard && /* @__PURE__ */ (0,
|
|
9297
|
+
segment === "alltime" && data.myAllTimeRow && !offBoard && /* @__PURE__ */ (0, import_jsx_runtime92.jsx)("div", { className: "ss-w-lb2-rows", children: /* @__PURE__ */ (0, import_jsx_runtime92.jsx)("div", { className: "ss-w-lb2-row", children: /* @__PURE__ */ (0, import_jsx_runtime92.jsx)("span", { className: "ss-w-lb2-handle", children: formatPoints(data.allTimeTop.reduce((s, r) => s + r.allTimePoints, 0)) }) }) })
|
|
8902
9298
|
] })
|
|
8903
9299
|
] });
|
|
8904
9300
|
}
|
|
8905
9301
|
|
|
8906
9302
|
// src/components/LeaderboardPanel.tsx
|
|
8907
|
-
var
|
|
9303
|
+
var import_jsx_runtime93 = require("react/jsx-runtime");
|
|
8908
9304
|
var EMPTY_PAYLOAD = {
|
|
8909
9305
|
week: "",
|
|
8910
9306
|
weeklyTop: [],
|
|
@@ -8915,19 +9311,19 @@ var EMPTY_PAYLOAD = {
|
|
|
8915
9311
|
lastWeek: null
|
|
8916
9312
|
};
|
|
8917
9313
|
function LeaderboardPanel({ loggedIn, data, loading, onPlay, ui }) {
|
|
8918
|
-
if (!loggedIn) return /* @__PURE__ */ (0,
|
|
8919
|
-
if (data === null && loading) return /* @__PURE__ */ (0,
|
|
8920
|
-
return /* @__PURE__ */ (0,
|
|
9314
|
+
if (!loggedIn) return /* @__PURE__ */ (0, import_jsx_runtime93.jsx)(GamesLoginWall, { ui });
|
|
9315
|
+
if (data === null && loading) return /* @__PURE__ */ (0, import_jsx_runtime93.jsx)("div", { className: "ss-w-mon-list" });
|
|
9316
|
+
return /* @__PURE__ */ (0, import_jsx_runtime93.jsx)("div", { className: "ss-w-mon-list", children: /* @__PURE__ */ (0, import_jsx_runtime93.jsx)(Leaderboard, { data: data ?? EMPTY_PAYLOAD, ui, onPlay }) });
|
|
8921
9317
|
}
|
|
8922
9318
|
|
|
8923
9319
|
// src/components/PresetSpeedDial.tsx
|
|
8924
|
-
var
|
|
8925
|
-
var
|
|
9320
|
+
var import_react56 = require("react");
|
|
9321
|
+
var import_jsx_runtime94 = require("react/jsx-runtime");
|
|
8926
9322
|
function PresetSpeedDial({ expanded, showDot, strings, onToggle, onOpen, rootRef, buttonRef }) {
|
|
8927
|
-
const pillsId = (0,
|
|
9323
|
+
const pillsId = (0, import_react56.useId)();
|
|
8928
9324
|
const tabIndex = expanded ? 0 : -1;
|
|
8929
|
-
return /* @__PURE__ */ (0,
|
|
8930
|
-
/* @__PURE__ */ (0,
|
|
9325
|
+
return /* @__PURE__ */ (0, import_jsx_runtime94.jsxs)("div", { ref: rootRef, className: "ss-w-dial", children: [
|
|
9326
|
+
/* @__PURE__ */ (0, import_jsx_runtime94.jsxs)(
|
|
8931
9327
|
"button",
|
|
8932
9328
|
{
|
|
8933
9329
|
ref: buttonRef,
|
|
@@ -8938,36 +9334,36 @@ function PresetSpeedDial({ expanded, showDot, strings, onToggle, onOpen, rootRef
|
|
|
8938
9334
|
"aria-label": strings.dialName,
|
|
8939
9335
|
onClick: onToggle,
|
|
8940
9336
|
children: [
|
|
8941
|
-
/* @__PURE__ */ (0,
|
|
8942
|
-
/* @__PURE__ */ (0,
|
|
8943
|
-
showDot && !expanded ? /* @__PURE__ */ (0,
|
|
9337
|
+
/* @__PURE__ */ (0, import_jsx_runtime94.jsx)("span", { className: "ss-w-dial-icon ss-w-dial-icon--open", children: /* @__PURE__ */ (0, import_jsx_runtime94.jsx)(SlidersIcon, {}) }),
|
|
9338
|
+
/* @__PURE__ */ (0, import_jsx_runtime94.jsx)("span", { className: "ss-w-dial-icon ss-w-dial-icon--close", children: /* @__PURE__ */ (0, import_jsx_runtime94.jsx)(CloseIcon, {}) }),
|
|
9339
|
+
showDot && !expanded ? /* @__PURE__ */ (0, import_jsx_runtime94.jsx)("span", { className: "ss-w-dial-dot", "aria-hidden": "true" }) : null
|
|
8944
9340
|
]
|
|
8945
9341
|
}
|
|
8946
9342
|
),
|
|
8947
|
-
/* @__PURE__ */ (0,
|
|
8948
|
-
/* @__PURE__ */ (0,
|
|
8949
|
-
/* @__PURE__ */ (0,
|
|
8950
|
-
/* @__PURE__ */ (0,
|
|
9343
|
+
/* @__PURE__ */ (0, import_jsx_runtime94.jsxs)("div", { id: pillsId, className: "ss-w-dial-pills", "data-open": expanded ? "" : void 0, children: [
|
|
9344
|
+
/* @__PURE__ */ (0, import_jsx_runtime94.jsxs)("button", { type: "button", className: "ss-w-dial-pill", tabIndex, onClick: () => onOpen("numbers"), children: [
|
|
9345
|
+
/* @__PURE__ */ (0, import_jsx_runtime94.jsx)(SlidersIcon, {}),
|
|
9346
|
+
/* @__PURE__ */ (0, import_jsx_runtime94.jsx)("span", { className: "ss-w-dial-pill-label", children: strings.setNumbers })
|
|
8951
9347
|
] }),
|
|
8952
|
-
/* @__PURE__ */ (0,
|
|
8953
|
-
/* @__PURE__ */ (0,
|
|
8954
|
-
/* @__PURE__ */ (0,
|
|
9348
|
+
/* @__PURE__ */ (0, import_jsx_runtime94.jsxs)("button", { type: "button", className: "ss-w-dial-pill", tabIndex, onClick: () => onOpen("combo"), children: [
|
|
9349
|
+
/* @__PURE__ */ (0, import_jsx_runtime94.jsx)(ComboIcon, {}),
|
|
9350
|
+
/* @__PURE__ */ (0, import_jsx_runtime94.jsx)("span", { className: "ss-w-dial-pill-label", children: strings.buildCombo })
|
|
8955
9351
|
] })
|
|
8956
9352
|
] })
|
|
8957
9353
|
] });
|
|
8958
9354
|
}
|
|
8959
9355
|
|
|
8960
9356
|
// src/components/PresetTools.tsx
|
|
8961
|
-
var
|
|
8962
|
-
var
|
|
9357
|
+
var import_react57 = require("react");
|
|
9358
|
+
var import_jsx_runtime95 = require("react/jsx-runtime");
|
|
8963
9359
|
var FOCUSABLE = 'button:not([disabled]), [href], input:not([disabled]), textarea:not([disabled]), [tabindex]:not([tabindex="-1"])';
|
|
8964
9360
|
function PresetToolModal({ title, closeLabel, onClose, children, footer }) {
|
|
8965
|
-
const dialogRef = (0,
|
|
8966
|
-
const titleId = (0,
|
|
8967
|
-
(0,
|
|
9361
|
+
const dialogRef = (0, import_react57.useRef)(null);
|
|
9362
|
+
const titleId = (0, import_react57.useId)();
|
|
9363
|
+
(0, import_react57.useEffect)(() => {
|
|
8968
9364
|
dialogRef.current?.focus();
|
|
8969
9365
|
}, []);
|
|
8970
|
-
(0,
|
|
9366
|
+
(0, import_react57.useEffect)(() => {
|
|
8971
9367
|
const onKey = (e) => {
|
|
8972
9368
|
if (e.key !== "Escape") return;
|
|
8973
9369
|
e.stopPropagation();
|
|
@@ -8997,79 +9393,79 @@ function PresetToolModal({ title, closeLabel, onClose, children, footer }) {
|
|
|
8997
9393
|
first.focus();
|
|
8998
9394
|
}
|
|
8999
9395
|
};
|
|
9000
|
-
return /* @__PURE__ */ (0,
|
|
9001
|
-
/* @__PURE__ */ (0,
|
|
9002
|
-
/* @__PURE__ */ (0,
|
|
9003
|
-
/* @__PURE__ */ (0,
|
|
9396
|
+
return /* @__PURE__ */ (0, import_jsx_runtime95.jsx)("div", { className: "ss-w-tool-backdrop", children: /* @__PURE__ */ (0, import_jsx_runtime95.jsxs)("div", { ref: dialogRef, className: "ss-w-tool", role: "dialog", "aria-modal": "true", "aria-labelledby": titleId, tabIndex: -1, onKeyDown: trapTab, children: [
|
|
9397
|
+
/* @__PURE__ */ (0, import_jsx_runtime95.jsxs)("div", { className: "ss-w-tool-head", children: [
|
|
9398
|
+
/* @__PURE__ */ (0, import_jsx_runtime95.jsx)("h2", { id: titleId, className: "ss-w-tool-title", children: title }),
|
|
9399
|
+
/* @__PURE__ */ (0, import_jsx_runtime95.jsx)("button", { type: "button", className: "ss-w-tool-close", "aria-label": closeLabel, onClick: onClose, children: /* @__PURE__ */ (0, import_jsx_runtime95.jsx)(CloseIcon, {}) })
|
|
9004
9400
|
] }),
|
|
9005
|
-
/* @__PURE__ */ (0,
|
|
9006
|
-
footer ? /* @__PURE__ */ (0,
|
|
9401
|
+
/* @__PURE__ */ (0, import_jsx_runtime95.jsx)("div", { className: "ss-w-tool-body", children }),
|
|
9402
|
+
footer ? /* @__PURE__ */ (0, import_jsx_runtime95.jsx)("div", { className: "ss-w-tool-foot", children: footer }) : null
|
|
9007
9403
|
] }) });
|
|
9008
9404
|
}
|
|
9009
9405
|
function fillTemplate(template, slots) {
|
|
9010
9406
|
return template.split(/(\{[a-z]+\})/).filter((part) => part !== "").map((part, i) => {
|
|
9011
9407
|
const key = /^\{([a-z]+)\}$/.exec(part)?.[1];
|
|
9012
|
-
return /* @__PURE__ */ (0,
|
|
9408
|
+
return /* @__PURE__ */ (0, import_jsx_runtime95.jsx)(import_react57.Fragment, { children: key !== void 0 && key in slots ? slots[key] : part }, i);
|
|
9013
9409
|
});
|
|
9014
9410
|
}
|
|
9015
9411
|
function NumberSelect({ current, choices: choices2, label, notToday, lockEmpty = true, onChoose }) {
|
|
9016
9412
|
const selected = Math.max(0, choices2.findIndex((c) => c.text === current));
|
|
9017
|
-
return /* @__PURE__ */ (0,
|
|
9018
|
-
/* @__PURE__ */ (0,
|
|
9019
|
-
/* @__PURE__ */ (0,
|
|
9413
|
+
return /* @__PURE__ */ (0, import_jsx_runtime95.jsxs)("span", { className: "ss-w-tool-num", children: [
|
|
9414
|
+
/* @__PURE__ */ (0, import_jsx_runtime95.jsx)("span", { className: "ss-w-tool-num-size", "aria-hidden": "true", children: current }),
|
|
9415
|
+
/* @__PURE__ */ (0, import_jsx_runtime95.jsx)("select", { className: "ss-w-tool-num-select", "aria-label": label, value: String(selected), onChange: (e) => {
|
|
9020
9416
|
const c = choices2[Number(e.target.value)];
|
|
9021
9417
|
if (c) onChoose(c.value);
|
|
9022
|
-
}, children: choices2.map((c, i) => /* @__PURE__ */ (0,
|
|
9418
|
+
}, children: choices2.map((c, i) => /* @__PURE__ */ (0, import_jsx_runtime95.jsx)("option", { value: String(i), disabled: lockEmpty && !c.available && i !== selected, children: c.available ? c.text : `${c.text}${notToday}` }, i)) })
|
|
9023
9419
|
] });
|
|
9024
9420
|
}
|
|
9025
9421
|
function ChoiceSelect({ currentIdx, sizeLabels, optionLabels, label, onChoose }) {
|
|
9026
9422
|
const sizeText = sizeLabels[currentIdx] ?? "";
|
|
9027
|
-
return /* @__PURE__ */ (0,
|
|
9028
|
-
/* @__PURE__ */ (0,
|
|
9029
|
-
/* @__PURE__ */ (0,
|
|
9423
|
+
return /* @__PURE__ */ (0, import_jsx_runtime95.jsxs)("span", { className: "ss-w-tool-num", children: [
|
|
9424
|
+
/* @__PURE__ */ (0, import_jsx_runtime95.jsx)("span", { className: "ss-w-tool-num-size", "aria-hidden": "true", children: sizeText }),
|
|
9425
|
+
/* @__PURE__ */ (0, import_jsx_runtime95.jsx)("select", { className: "ss-w-tool-num-select", "aria-label": label, value: String(currentIdx), onChange: (e) => onChoose(Number(e.target.value)), children: optionLabels.map((opt, i) => /* @__PURE__ */ (0, import_jsx_runtime95.jsx)("option", { value: String(i), children: opt }, i)) })
|
|
9030
9426
|
] });
|
|
9031
9427
|
}
|
|
9032
9428
|
function SendButton({ label, display, disabled, onClick }) {
|
|
9033
|
-
return /* @__PURE__ */ (0,
|
|
9429
|
+
return /* @__PURE__ */ (0, import_jsx_runtime95.jsx)("button", { type: "button", className: "ss-w-tool-send", "aria-label": `${label}: ${display}`, disabled, onClick, children: label });
|
|
9034
9430
|
}
|
|
9035
9431
|
function PickList({ picks, formatKickoff }) {
|
|
9036
|
-
return /* @__PURE__ */ (0,
|
|
9037
|
-
/* @__PURE__ */ (0,
|
|
9432
|
+
return /* @__PURE__ */ (0, import_jsx_runtime95.jsx)("ul", { className: "ss-w-tool-picks", role: "list", children: picks.map((p) => /* @__PURE__ */ (0, import_jsx_runtime95.jsxs)("li", { className: "ss-w-tool-pick", children: [
|
|
9433
|
+
/* @__PURE__ */ (0, import_jsx_runtime95.jsxs)("span", { className: "ss-w-tool-pick-match", children: [
|
|
9038
9434
|
p.homeTeamName,
|
|
9039
9435
|
" \u2013 ",
|
|
9040
9436
|
p.awayTeamName
|
|
9041
9437
|
] }),
|
|
9042
|
-
/* @__PURE__ */ (0,
|
|
9438
|
+
/* @__PURE__ */ (0, import_jsx_runtime95.jsxs)("span", { className: "ss-w-tool-pick-sel", children: [
|
|
9043
9439
|
p.marketLabel,
|
|
9044
9440
|
": ",
|
|
9045
9441
|
p.selectionLabel,
|
|
9046
9442
|
p.line ? ` ${p.line}` : ""
|
|
9047
9443
|
] }),
|
|
9048
|
-
/* @__PURE__ */ (0,
|
|
9049
|
-
/* @__PURE__ */ (0,
|
|
9444
|
+
/* @__PURE__ */ (0, import_jsx_runtime95.jsx)("span", { className: "ss-w-tool-pick-kick", children: formatKickoff(p.kickoffUtc) }),
|
|
9445
|
+
/* @__PURE__ */ (0, import_jsx_runtime95.jsx)("span", { className: "ss-w-tool-pick-price", children: p.price.toFixed(2) })
|
|
9050
9446
|
] }, p.matchOddsId)) });
|
|
9051
9447
|
}
|
|
9052
9448
|
function ComboPreview({ cell, formatKickoff }) {
|
|
9053
|
-
return /* @__PURE__ */ (0,
|
|
9054
|
-
/* @__PURE__ */ (0,
|
|
9055
|
-
/* @__PURE__ */ (0,
|
|
9449
|
+
return /* @__PURE__ */ (0, import_jsx_runtime95.jsxs)(import_jsx_runtime95.Fragment, { children: [
|
|
9450
|
+
/* @__PURE__ */ (0, import_jsx_runtime95.jsx)(PickList, { picks: cell.combo.legs, formatKickoff }),
|
|
9451
|
+
/* @__PURE__ */ (0, import_jsx_runtime95.jsx)("div", { className: "ss-w-tool-math", children: cell.combo.multiplication })
|
|
9056
9452
|
] });
|
|
9057
9453
|
}
|
|
9058
9454
|
function Unavailable({ text }) {
|
|
9059
|
-
return /* @__PURE__ */ (0,
|
|
9455
|
+
return /* @__PURE__ */ (0, import_jsx_runtime95.jsx)("p", { className: "ss-w-tool-unavailable", children: text });
|
|
9060
9456
|
}
|
|
9061
9457
|
function AskRow({ icon, ask, ready, send }) {
|
|
9062
|
-
return /* @__PURE__ */ (0,
|
|
9063
|
-
/* @__PURE__ */ (0,
|
|
9064
|
-
/* @__PURE__ */ (0,
|
|
9065
|
-
/* @__PURE__ */ (0,
|
|
9066
|
-
ready ? /* @__PURE__ */ (0,
|
|
9458
|
+
return /* @__PURE__ */ (0, import_jsx_runtime95.jsxs)("section", { className: "ss-w-tool-row ss-w-tool-row--ask", children: [
|
|
9459
|
+
/* @__PURE__ */ (0, import_jsx_runtime95.jsx)("span", { className: "ss-w-tool-icon", "aria-hidden": "true", children: icon }),
|
|
9460
|
+
/* @__PURE__ */ (0, import_jsx_runtime95.jsxs)("div", { className: "ss-w-tool-main", children: [
|
|
9461
|
+
/* @__PURE__ */ (0, import_jsx_runtime95.jsx)("p", { className: "ss-w-tool-ask", children: ask }),
|
|
9462
|
+
ready ? /* @__PURE__ */ (0, import_jsx_runtime95.jsx)("span", { className: "ss-w-tool-ready", children: ready }) : null
|
|
9067
9463
|
] }),
|
|
9068
9464
|
send
|
|
9069
9465
|
] });
|
|
9070
9466
|
}
|
|
9071
9467
|
function RoundSend({ label, display, disabled, onClick }) {
|
|
9072
|
-
return /* @__PURE__ */ (0,
|
|
9468
|
+
return /* @__PURE__ */ (0, import_jsx_runtime95.jsx)("button", { type: "button", className: "ss-w-tool-go", "aria-label": `${label}: ${display}`, disabled, onClick, children: /* @__PURE__ */ (0, import_jsx_runtime95.jsx)(SendIcon, {}) });
|
|
9073
9469
|
}
|
|
9074
9470
|
var BIG_COMBO = { total: 50, legs: 6 };
|
|
9075
9471
|
function SetNumbersTool({ grid, strings, streaming, onSend, onClose }) {
|
|
@@ -9078,15 +9474,15 @@ function SetNumbersTool({ grid, strings, streaming, onSend, onClose }) {
|
|
|
9078
9474
|
const totals = comboTotals(grid);
|
|
9079
9475
|
const legChoices = comboLegChoices(grid);
|
|
9080
9476
|
const count = FIXED_SINGLES_COUNT;
|
|
9081
|
-
const [maxPrice, setMaxPrice] = (0,
|
|
9082
|
-
const [minPrice, setMinPrice] = (0,
|
|
9083
|
-
const [start] = (0,
|
|
9084
|
-
const [total, setTotal] = (0,
|
|
9085
|
-
const [legs, setLegs] = (0,
|
|
9086
|
-
const [bigStart] = (0,
|
|
9087
|
-
const [bigTotal, setBigTotal] = (0,
|
|
9088
|
-
const [bigLegs, setBigLegs] = (0,
|
|
9089
|
-
const [announcement, setAnnouncement] = (0,
|
|
9477
|
+
const [maxPrice, setMaxPrice] = (0, import_react57.useState)(() => startSingles(grid.singles, limits, START.maxPrice, count));
|
|
9478
|
+
const [minPrice, setMinPrice] = (0, import_react57.useState)(() => startSingles(grid.singlesFrom, floors, START.minPrice, count));
|
|
9479
|
+
const [start] = (0, import_react57.useState)(() => startCombo(grid, totals, legChoices, START.comboTotal, START.comboLegs));
|
|
9480
|
+
const [total, setTotal] = (0, import_react57.useState)(start.total);
|
|
9481
|
+
const [legs, setLegs] = (0, import_react57.useState)(start.legs);
|
|
9482
|
+
const [bigStart] = (0, import_react57.useState)(() => startCombo(grid, totals, legChoices, BIG_COMBO.total, BIG_COMBO.legs));
|
|
9483
|
+
const [bigTotal, setBigTotal] = (0, import_react57.useState)(bigStart.total);
|
|
9484
|
+
const [bigLegs, setBigLegs] = (0, import_react57.useState)(bigStart.legs);
|
|
9485
|
+
const [announcement, setAnnouncement] = (0, import_react57.useState)("");
|
|
9090
9486
|
const maxCell = findSingles(grid.singles, maxPrice, count);
|
|
9091
9487
|
const minCell = findSingles(grid.singlesFrom, minPrice, count);
|
|
9092
9488
|
const comboCell = findCombo(grid, total, legs);
|
|
@@ -9130,95 +9526,95 @@ function SetNumbersTool({ grid, strings, streaming, onSend, onClose }) {
|
|
|
9130
9526
|
const totalChoices = totals.map((v) => ({ value: v, text: v.toFixed(1), available: legChoices.some((n) => !!findCombo(grid, v, n)) }));
|
|
9131
9527
|
const legChoicesFor = (t) => legChoices.map((n) => ({ value: n, text: String(n), available: !!findCombo(grid, t, n) }));
|
|
9132
9528
|
const markets = grid.markets ?? [];
|
|
9133
|
-
const [marketIdx, setMarketIdx] = (0,
|
|
9529
|
+
const [marketIdx, setMarketIdx] = (0, import_react57.useState)(0);
|
|
9134
9530
|
const marketCell = markets[marketIdx] ?? null;
|
|
9135
9531
|
const marketLabels = markets.map((c) => strings.marketShort(c.marketDeveloperName, c.marketLabel, c.selectionLabel ?? null));
|
|
9136
9532
|
const singlesReady = (cell) => cell ? strings.readyCount(cell.picks.length) : strings.unavailable;
|
|
9137
9533
|
const comboReady = (cell) => cell ? strings.readyAt(cell.combo.total) : strings.unavailable;
|
|
9138
|
-
return /* @__PURE__ */ (0,
|
|
9139
|
-
/* @__PURE__ */ (0,
|
|
9534
|
+
return /* @__PURE__ */ (0, import_jsx_runtime95.jsxs)(PresetToolModal, { title: strings.setNumbers, closeLabel: strings.close, onClose, children: [
|
|
9535
|
+
/* @__PURE__ */ (0, import_jsx_runtime95.jsx)(
|
|
9140
9536
|
AskRow,
|
|
9141
9537
|
{
|
|
9142
9538
|
icon: "\u{1F3AF}",
|
|
9143
9539
|
ask: fillTemplate(strings.maxPriceRow, {
|
|
9144
9540
|
count: String(count),
|
|
9145
|
-
price: /* @__PURE__ */ (0,
|
|
9541
|
+
price: /* @__PURE__ */ (0, import_jsx_runtime95.jsx)(NumberSelect, { current: maxPrice.toFixed(2), choices: maxChoices, label: strings.maxPriceName, notToday: strings.notToday, onChoose: chooseMax })
|
|
9146
9542
|
}),
|
|
9147
9543
|
ready: singlesReady(maxCell),
|
|
9148
|
-
send: /* @__PURE__ */ (0,
|
|
9544
|
+
send: /* @__PURE__ */ (0, import_jsx_runtime95.jsx)(RoundSend, { label: strings.send, display: strings.maxPriceDisplay(count, maxPrice), disabled: !maxCell || streaming, onClick: () => {
|
|
9149
9545
|
if (maxCell) onSend(maxPriceAsk(maxCell, strings));
|
|
9150
9546
|
} })
|
|
9151
9547
|
}
|
|
9152
9548
|
),
|
|
9153
|
-
/* @__PURE__ */ (0,
|
|
9549
|
+
/* @__PURE__ */ (0, import_jsx_runtime95.jsx)(
|
|
9154
9550
|
AskRow,
|
|
9155
9551
|
{
|
|
9156
9552
|
icon: "\u{1F4C8}",
|
|
9157
9553
|
ask: fillTemplate(strings.minPriceRow, {
|
|
9158
9554
|
count: String(count),
|
|
9159
|
-
price: /* @__PURE__ */ (0,
|
|
9555
|
+
price: /* @__PURE__ */ (0, import_jsx_runtime95.jsx)(NumberSelect, { current: minPrice.toFixed(2), choices: minChoices, label: strings.minPriceName, notToday: strings.notToday, onChoose: chooseMin })
|
|
9160
9556
|
}),
|
|
9161
9557
|
ready: singlesReady(minCell),
|
|
9162
|
-
send: /* @__PURE__ */ (0,
|
|
9558
|
+
send: /* @__PURE__ */ (0, import_jsx_runtime95.jsx)(RoundSend, { label: strings.send, display: strings.minPriceDisplay(count, minPrice), disabled: !minCell || streaming, onClick: () => {
|
|
9163
9559
|
if (minCell) onSend(minPriceAsk(minCell, strings));
|
|
9164
9560
|
} })
|
|
9165
9561
|
}
|
|
9166
9562
|
),
|
|
9167
|
-
/* @__PURE__ */ (0,
|
|
9563
|
+
/* @__PURE__ */ (0, import_jsx_runtime95.jsx)(
|
|
9168
9564
|
AskRow,
|
|
9169
9565
|
{
|
|
9170
9566
|
icon: "\u2728",
|
|
9171
9567
|
ask: fillTemplate(strings.comboRow, {
|
|
9172
|
-
legs: /* @__PURE__ */ (0,
|
|
9173
|
-
total: /* @__PURE__ */ (0,
|
|
9568
|
+
legs: /* @__PURE__ */ (0, import_jsx_runtime95.jsx)(NumberSelect, { current: String(legs), choices: legChoicesFor(total), label: strings.matchesLabel, notToday: strings.notToday, lockEmpty: false, onChoose: chooseLegs }),
|
|
9569
|
+
total: /* @__PURE__ */ (0, import_jsx_runtime95.jsx)(NumberSelect, { current: total.toFixed(1), choices: totalChoices, label: strings.totalLabel, notToday: strings.notToday, onChoose: chooseTotal })
|
|
9174
9570
|
}),
|
|
9175
9571
|
ready: comboReady(comboCell),
|
|
9176
|
-
send: /* @__PURE__ */ (0,
|
|
9572
|
+
send: /* @__PURE__ */ (0, import_jsx_runtime95.jsx)(RoundSend, { label: strings.send, display: strings.comboDisplay(legs, total), disabled: !comboCell || streaming, onClick: () => {
|
|
9177
9573
|
if (comboCell) onSend(comboAsk(comboCell, strings));
|
|
9178
9574
|
} })
|
|
9179
9575
|
}
|
|
9180
9576
|
),
|
|
9181
|
-
/* @__PURE__ */ (0,
|
|
9577
|
+
/* @__PURE__ */ (0, import_jsx_runtime95.jsx)(
|
|
9182
9578
|
AskRow,
|
|
9183
9579
|
{
|
|
9184
9580
|
icon: "\u{1F3C6}",
|
|
9185
9581
|
ask: fillTemplate(strings.bigComboRow, {
|
|
9186
|
-
legs: /* @__PURE__ */ (0,
|
|
9187
|
-
total: /* @__PURE__ */ (0,
|
|
9582
|
+
legs: /* @__PURE__ */ (0, import_jsx_runtime95.jsx)(NumberSelect, { current: String(bigLegs), choices: legChoicesFor(bigTotal), label: strings.matchesLabel, notToday: strings.notToday, lockEmpty: false, onChoose: chooseBigLegs }),
|
|
9583
|
+
total: /* @__PURE__ */ (0, import_jsx_runtime95.jsx)(NumberSelect, { current: bigTotal.toFixed(1), choices: totalChoices, label: strings.totalLabel, notToday: strings.notToday, onChoose: chooseBigTotal })
|
|
9188
9584
|
}),
|
|
9189
9585
|
ready: comboReady(bigCell),
|
|
9190
|
-
send: /* @__PURE__ */ (0,
|
|
9586
|
+
send: /* @__PURE__ */ (0, import_jsx_runtime95.jsx)(RoundSend, { label: strings.send, display: strings.comboDisplay(bigLegs, bigTotal), disabled: !bigCell || streaming, onClick: () => {
|
|
9191
9587
|
if (bigCell) onSend(comboAsk(bigCell, strings));
|
|
9192
9588
|
} })
|
|
9193
9589
|
}
|
|
9194
9590
|
),
|
|
9195
|
-
markets.length > 0 && /* @__PURE__ */ (0,
|
|
9591
|
+
markets.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime95.jsx)(
|
|
9196
9592
|
AskRow,
|
|
9197
9593
|
{
|
|
9198
9594
|
icon: "\u26BD",
|
|
9199
9595
|
ask: fillTemplate(strings.marketRow, {
|
|
9200
|
-
market: /* @__PURE__ */ (0,
|
|
9596
|
+
market: /* @__PURE__ */ (0, import_jsx_runtime95.jsx)(ChoiceSelect, { currentIdx: marketIdx, sizeLabels: marketLabels, optionLabels: marketLabels, label: strings.marketName, onChoose: chooseMarket })
|
|
9201
9597
|
}),
|
|
9202
9598
|
ready: marketCell ? strings.readyCount(marketCell.count) : null,
|
|
9203
|
-
send: /* @__PURE__ */ (0,
|
|
9599
|
+
send: /* @__PURE__ */ (0, import_jsx_runtime95.jsx)(RoundSend, { label: strings.send, display: marketCell ? marketDisplay(marketCell, strings) : "", disabled: !marketCell || streaming, onClick: () => {
|
|
9204
9600
|
if (marketCell) onSend(marketAsk(marketCell, strings));
|
|
9205
9601
|
} })
|
|
9206
9602
|
}
|
|
9207
9603
|
),
|
|
9208
|
-
/* @__PURE__ */ (0,
|
|
9604
|
+
/* @__PURE__ */ (0, import_jsx_runtime95.jsx)("p", { className: "ss-w-vh", "aria-live": "polite", children: announcement })
|
|
9209
9605
|
] });
|
|
9210
9606
|
}
|
|
9211
9607
|
function BuildComboTool({ grid, strings, streaming, formatKickoff, initialTotal, initialLegs, onSend, onClose }) {
|
|
9212
9608
|
const totals = comboTotals(grid);
|
|
9213
9609
|
const legChoices = comboLegChoices(grid);
|
|
9214
|
-
const [start] = (0,
|
|
9215
|
-
const [total, setTotal] = (0,
|
|
9216
|
-
const [legs, setLegs] = (0,
|
|
9610
|
+
const [start] = (0, import_react57.useState)(() => initialTotal === void 0 ? startCombo(grid, totals, legChoices, START.comboTotal, START.comboLegs) : null);
|
|
9611
|
+
const [total, setTotal] = (0, import_react57.useState)(() => initialTotal !== void 0 ? nearest(totals, initialTotal) : start.total);
|
|
9612
|
+
const [legs, setLegs] = (0, import_react57.useState)(() => {
|
|
9217
9613
|
if (initialTotal === void 0) return initialLegs !== void 0 ? clampLegs(legChoices, initialLegs) : start.legs;
|
|
9218
9614
|
const from = initialLegs !== void 0 ? clampLegs(legChoices, initialLegs) : startValue(legChoices, START.comboLegs);
|
|
9219
9615
|
return legsForTotal(grid, nearest(totals, initialTotal), from);
|
|
9220
9616
|
});
|
|
9221
|
-
const [announcement, setAnnouncement] = (0,
|
|
9617
|
+
const [announcement, setAnnouncement] = (0, import_react57.useState)("");
|
|
9222
9618
|
const cell = findCombo(grid, total, legs);
|
|
9223
9619
|
const minLegs = legChoices[0] ?? legs;
|
|
9224
9620
|
const maxLegs = legChoices[legChoices.length - 1] ?? legs;
|
|
@@ -9229,29 +9625,29 @@ function BuildComboTool({ grid, strings, streaming, formatKickoff, initialTotal,
|
|
|
9229
9625
|
const d = strings.comboDisplay(nextLegs, nextTotal);
|
|
9230
9626
|
setAnnouncement(findCombo(grid, nextTotal, nextLegs) ? d : `${d}. ${strings.unavailable}`);
|
|
9231
9627
|
};
|
|
9232
|
-
const footer = /* @__PURE__ */ (0,
|
|
9628
|
+
const footer = /* @__PURE__ */ (0, import_jsx_runtime95.jsx)(SendButton, { label: strings.send, display, disabled: !cell || streaming, onClick: () => {
|
|
9233
9629
|
if (cell) onSend(comboAsk(cell, strings));
|
|
9234
9630
|
} });
|
|
9235
|
-
return /* @__PURE__ */ (0,
|
|
9236
|
-
/* @__PURE__ */ (0,
|
|
9237
|
-
/* @__PURE__ */ (0,
|
|
9238
|
-
/* @__PURE__ */ (0,
|
|
9631
|
+
return /* @__PURE__ */ (0, import_jsx_runtime95.jsxs)(PresetToolModal, { title: strings.buildCombo, closeLabel: strings.close, onClose, footer, children: [
|
|
9632
|
+
/* @__PURE__ */ (0, import_jsx_runtime95.jsxs)("div", { className: "ss-w-tool-section", role: "group", "aria-label": strings.totalLabel, children: [
|
|
9633
|
+
/* @__PURE__ */ (0, import_jsx_runtime95.jsx)("span", { className: "ss-w-tool-label", "aria-hidden": "true", children: strings.totalLabel }),
|
|
9634
|
+
/* @__PURE__ */ (0, import_jsx_runtime95.jsx)("div", { className: "ss-w-tool-chips", children: totals.map((t) => /* @__PURE__ */ (0, import_jsx_runtime95.jsx)("button", { type: "button", className: "ss-w-tool-chip", "aria-pressed": samePrice(t, total), onClick: () => choose(t, samePrice(t, total) ? legs : legsForTotal(grid, t, legs)), children: t.toFixed(1) }, t)) })
|
|
9239
9635
|
] }),
|
|
9240
|
-
/* @__PURE__ */ (0,
|
|
9241
|
-
/* @__PURE__ */ (0,
|
|
9242
|
-
/* @__PURE__ */ (0,
|
|
9243
|
-
/* @__PURE__ */ (0,
|
|
9244
|
-
/* @__PURE__ */ (0,
|
|
9245
|
-
/* @__PURE__ */ (0,
|
|
9636
|
+
/* @__PURE__ */ (0, import_jsx_runtime95.jsxs)("div", { className: "ss-w-tool-section", role: "group", "aria-label": strings.matchesLabel, children: [
|
|
9637
|
+
/* @__PURE__ */ (0, import_jsx_runtime95.jsx)("span", { className: "ss-w-tool-label", "aria-hidden": "true", children: strings.matchesLabel }),
|
|
9638
|
+
/* @__PURE__ */ (0, import_jsx_runtime95.jsxs)("div", { className: "ss-w-tool-stepper", children: [
|
|
9639
|
+
/* @__PURE__ */ (0, import_jsx_runtime95.jsx)("button", { type: "button", className: "ss-w-tool-step", "aria-label": strings.fewerMatches, disabled: legs <= minLegs, onClick: () => choose(total, legs - 1), children: "\u2212" }),
|
|
9640
|
+
/* @__PURE__ */ (0, import_jsx_runtime95.jsx)("span", { className: "ss-w-tool-count", children: legs }),
|
|
9641
|
+
/* @__PURE__ */ (0, import_jsx_runtime95.jsx)("button", { type: "button", className: "ss-w-tool-step", "aria-label": strings.moreMatches, disabled: legs >= maxLegs, onClick: () => choose(total, legs + 1), children: "+" })
|
|
9246
9642
|
] })
|
|
9247
9643
|
] }),
|
|
9248
|
-
cell ? /* @__PURE__ */ (0,
|
|
9249
|
-
/* @__PURE__ */ (0,
|
|
9644
|
+
cell ? /* @__PURE__ */ (0, import_jsx_runtime95.jsx)(ComboPreview, { cell, formatKickoff }) : /* @__PURE__ */ (0, import_jsx_runtime95.jsx)(Unavailable, { text: strings.unavailable }),
|
|
9645
|
+
/* @__PURE__ */ (0, import_jsx_runtime95.jsx)("p", { className: "ss-w-vh", "aria-live": "polite", children: announcement })
|
|
9250
9646
|
] });
|
|
9251
9647
|
}
|
|
9252
9648
|
|
|
9253
9649
|
// src/usePresetDial.ts
|
|
9254
|
-
var
|
|
9650
|
+
var import_react58 = require("react");
|
|
9255
9651
|
function sendInFlight(messages, isStreaming) {
|
|
9256
9652
|
const last = messages[messages.length - 1];
|
|
9257
9653
|
return isStreaming && !!last && last.role === "assistant" && !last.done && !last.isGreeting;
|
|
@@ -9265,25 +9661,25 @@ function lastUserId(messages) {
|
|
|
9265
9661
|
}
|
|
9266
9662
|
var SCROLL_KEYS = /* @__PURE__ */ new Set(["ArrowUp", "ArrowDown", "PageUp", "PageDown", "Home", "End", " "]);
|
|
9267
9663
|
function usePresetDial({ layerRef, dialRef, dialButtonRef, messages, isStreaming, activeTab }) {
|
|
9268
|
-
const [expanded, setExpanded] = (0,
|
|
9269
|
-
const fold = (0,
|
|
9270
|
-
const toggle = (0,
|
|
9664
|
+
const [expanded, setExpanded] = (0, import_react58.useState)(() => !sendInFlight(messages, isStreaming));
|
|
9665
|
+
const fold = (0, import_react58.useCallback)(() => setExpanded(false), []);
|
|
9666
|
+
const toggle = (0, import_react58.useCallback)(() => setExpanded((e) => !e), []);
|
|
9271
9667
|
const currentUserId = lastUserId(messages);
|
|
9272
|
-
const userIdRef = (0,
|
|
9273
|
-
(0,
|
|
9668
|
+
const userIdRef = (0, import_react58.useRef)(currentUserId);
|
|
9669
|
+
(0, import_react58.useEffect)(() => {
|
|
9274
9670
|
if (currentUserId === userIdRef.current) return;
|
|
9275
9671
|
userIdRef.current = currentUserId;
|
|
9276
9672
|
setExpanded(false);
|
|
9277
9673
|
}, [currentUserId]);
|
|
9278
|
-
const tabRef = (0,
|
|
9279
|
-
(0,
|
|
9674
|
+
const tabRef = (0, import_react58.useRef)(activeTab);
|
|
9675
|
+
(0, import_react58.useEffect)(() => {
|
|
9280
9676
|
if (activeTab === tabRef.current) return;
|
|
9281
9677
|
tabRef.current = activeTab;
|
|
9282
9678
|
setExpanded(false);
|
|
9283
9679
|
}, [activeTab]);
|
|
9284
|
-
const expandedRef = (0,
|
|
9680
|
+
const expandedRef = (0, import_react58.useRef)(expanded);
|
|
9285
9681
|
expandedRef.current = expanded;
|
|
9286
|
-
(0,
|
|
9682
|
+
(0, import_react58.useEffect)(() => {
|
|
9287
9683
|
const onEscape = (e) => {
|
|
9288
9684
|
const dial = dialRef.current;
|
|
9289
9685
|
if (e.key !== "Escape" || !dial || !e.composedPath().includes(dial)) return;
|
|
@@ -9296,7 +9692,7 @@ function usePresetDial({ layerRef, dialRef, dialButtonRef, messages, isStreaming
|
|
|
9296
9692
|
window.addEventListener("keydown", onEscape, true);
|
|
9297
9693
|
return () => window.removeEventListener("keydown", onEscape, true);
|
|
9298
9694
|
}, [dialRef, dialButtonRef]);
|
|
9299
|
-
(0,
|
|
9695
|
+
(0, import_react58.useEffect)(() => {
|
|
9300
9696
|
if (!expanded) return;
|
|
9301
9697
|
const layer = layerRef.current;
|
|
9302
9698
|
const inDial = (e) => {
|
|
@@ -9348,11 +9744,11 @@ function markToolSeen() {
|
|
|
9348
9744
|
}
|
|
9349
9745
|
|
|
9350
9746
|
// src/components/ChatPanel.tsx
|
|
9351
|
-
var
|
|
9747
|
+
var import_jsx_runtime96 = require("react/jsx-runtime");
|
|
9352
9748
|
var FULLSCREEN_QUERY = "(max-width: 639px)";
|
|
9353
9749
|
function useIsModal() {
|
|
9354
|
-
const [modal, setModal] = (0,
|
|
9355
|
-
(0,
|
|
9750
|
+
const [modal, setModal] = (0, import_react59.useState)(false);
|
|
9751
|
+
(0, import_react59.useEffect)(() => {
|
|
9356
9752
|
if (typeof window === "undefined" || typeof window.matchMedia !== "function") return;
|
|
9357
9753
|
const mql = window.matchMedia(FULLSCREEN_QUERY);
|
|
9358
9754
|
const sync = () => setModal(mql.matches);
|
|
@@ -9366,7 +9762,7 @@ var HIDDEN_LAYER_STYLE = { position: "absolute", inset: 0, visibility: "hidden",
|
|
|
9366
9762
|
function ChatPanel({ controller, ui, slip, onDashboardTap, monitor, discovery, gamesResult, leaderboardResult, loggedIn, conversation, presetGrid }) {
|
|
9367
9763
|
const { state, close, stop, send, reset } = controller;
|
|
9368
9764
|
const isModal = useIsModal();
|
|
9369
|
-
(0,
|
|
9765
|
+
(0, import_react59.useEffect)(() => {
|
|
9370
9766
|
const onKey = (e) => {
|
|
9371
9767
|
if (e.key === "Escape") close();
|
|
9372
9768
|
};
|
|
@@ -9374,6 +9770,7 @@ function ChatPanel({ controller, ui, slip, onDashboardTap, monitor, discovery, g
|
|
|
9374
9770
|
return () => window.removeEventListener("keydown", onKey);
|
|
9375
9771
|
}, [close]);
|
|
9376
9772
|
const handleSend = (text) => {
|
|
9773
|
+
typedSendRef.current = true;
|
|
9377
9774
|
monitor?.setActiveTab("chat");
|
|
9378
9775
|
send(text);
|
|
9379
9776
|
};
|
|
@@ -9381,17 +9778,19 @@ function ChatPanel({ controller, ui, slip, onDashboardTap, monitor, discovery, g
|
|
|
9381
9778
|
monitor?.setActiveTab("chat");
|
|
9382
9779
|
send(text, { grounding });
|
|
9383
9780
|
};
|
|
9384
|
-
(0,
|
|
9781
|
+
(0, import_react59.useEffect)(() => {
|
|
9385
9782
|
if (monitor && monitor.activeTab !== "chat" && state.isStreaming) monitor.markChatActivity();
|
|
9386
9783
|
}, [monitor, state.isStreaming, state.messages.length]);
|
|
9387
9784
|
const onChatTab = !monitor || monitor.activeTab === "chat";
|
|
9388
|
-
const layerRef = (0,
|
|
9389
|
-
const dialRef = (0,
|
|
9390
|
-
const dialButtonRef = (0,
|
|
9391
|
-
const inputRef = (0,
|
|
9392
|
-
const
|
|
9393
|
-
const
|
|
9394
|
-
const
|
|
9785
|
+
const layerRef = (0, import_react59.useRef)(null);
|
|
9786
|
+
const dialRef = (0, import_react59.useRef)(null);
|
|
9787
|
+
const dialButtonRef = (0, import_react59.useRef)(null);
|
|
9788
|
+
const inputRef = (0, import_react59.useRef)(null);
|
|
9789
|
+
const limitRef = (0, import_react59.useRef)(null);
|
|
9790
|
+
const typedSendRef = (0, import_react59.useRef)(false);
|
|
9791
|
+
const focusAfterCloseRef = (0, import_react59.useRef)(null);
|
|
9792
|
+
const [tool, setTool] = (0, import_react59.useState)(null);
|
|
9793
|
+
const [toolSeen, setToolSeen] = (0, import_react59.useState)(readToolSeen);
|
|
9395
9794
|
const dial = usePresetDial({
|
|
9396
9795
|
layerRef,
|
|
9397
9796
|
dialRef,
|
|
@@ -9401,46 +9800,55 @@ function ChatPanel({ controller, ui, slip, onDashboardTap, monitor, discovery, g
|
|
|
9401
9800
|
activeTab: monitor?.activeTab ?? "chat"
|
|
9402
9801
|
});
|
|
9403
9802
|
const { fold } = dial;
|
|
9404
|
-
const
|
|
9405
|
-
const
|
|
9803
|
+
const paused = isPaused(state.limit);
|
|
9804
|
+
const showDial = !!presetGrid && onChatTab && !tool && !paused;
|
|
9805
|
+
(0, import_react59.useEffect)(() => {
|
|
9806
|
+
if (paused) setTool(null);
|
|
9807
|
+
}, [paused]);
|
|
9808
|
+
(0, import_react59.useEffect)(() => {
|
|
9809
|
+
if (!paused) return;
|
|
9810
|
+
if (typedSendRef.current) limitRef.current?.focus();
|
|
9811
|
+
typedSendRef.current = false;
|
|
9812
|
+
}, [paused]);
|
|
9813
|
+
const openTool = (0, import_react59.useCallback)((next) => {
|
|
9406
9814
|
fold();
|
|
9407
9815
|
markToolSeen();
|
|
9408
9816
|
setToolSeen(true);
|
|
9409
9817
|
setTool(next);
|
|
9410
9818
|
}, [fold]);
|
|
9411
|
-
const onPill = (0,
|
|
9412
|
-
const toolsValue = (0,
|
|
9413
|
-
() => presetGrid ? { openBuilder: (total, legs) => openTool({ kind: "combo", total, legs }), changeLabel: ui.presets.changeCombo } : null,
|
|
9414
|
-
[presetGrid, openTool, ui.presets.changeCombo]
|
|
9819
|
+
const onPill = (0, import_react59.useCallback)((kind) => openTool(kind === "numbers" ? { kind: "numbers" } : { kind: "combo" }), [openTool]);
|
|
9820
|
+
const toolsValue = (0, import_react59.useMemo)(
|
|
9821
|
+
() => presetGrid && !paused ? { openBuilder: (total, legs) => openTool({ kind: "combo", total, legs }), changeLabel: ui.presets.changeCombo } : null,
|
|
9822
|
+
[presetGrid, paused, openTool, ui.presets.changeCombo]
|
|
9415
9823
|
);
|
|
9416
|
-
const closeTool = (0,
|
|
9824
|
+
const closeTool = (0, import_react59.useCallback)(() => {
|
|
9417
9825
|
focusAfterCloseRef.current = "dial";
|
|
9418
9826
|
setTool(null);
|
|
9419
9827
|
}, []);
|
|
9420
|
-
const sendAsk = (0,
|
|
9828
|
+
const sendAsk = (0, import_react59.useCallback)((ask) => {
|
|
9421
9829
|
focusAfterCloseRef.current = "composer";
|
|
9422
9830
|
setTool(null);
|
|
9423
9831
|
monitor?.setActiveTab("chat");
|
|
9424
9832
|
send(ask.message, { displayText: ask.displayText, preset: ask.preset });
|
|
9425
9833
|
}, [monitor, send]);
|
|
9426
|
-
const formatKickoff = (0,
|
|
9834
|
+
const formatKickoff = (0, import_react59.useCallback)((kickoffUtc) => {
|
|
9427
9835
|
const k = ui.bettingKickoff(kickoffUtc);
|
|
9428
9836
|
return `${k.dayLabel} ${k.time}`;
|
|
9429
9837
|
}, [ui]);
|
|
9430
|
-
(0,
|
|
9838
|
+
(0, import_react59.useEffect)(() => {
|
|
9431
9839
|
if (tool) return;
|
|
9432
9840
|
const target = focusAfterCloseRef.current;
|
|
9433
9841
|
focusAfterCloseRef.current = null;
|
|
9434
9842
|
if (target === "dial") dialButtonRef.current?.focus();
|
|
9435
9843
|
else if (target === "composer") inputRef.current?.focus();
|
|
9436
9844
|
}, [tool]);
|
|
9437
|
-
(0,
|
|
9845
|
+
(0, import_react59.useEffect)(() => {
|
|
9438
9846
|
if (!tool || onChatTab && presetGrid) return;
|
|
9439
9847
|
focusAfterCloseRef.current = "composer";
|
|
9440
9848
|
setTool(null);
|
|
9441
9849
|
}, [tool, onChatTab, presetGrid]);
|
|
9442
|
-
return /* @__PURE__ */ (0,
|
|
9443
|
-
/* @__PURE__ */ (0,
|
|
9850
|
+
return /* @__PURE__ */ (0, import_jsx_runtime96.jsxs)("div", { className: "ss-w-panel", role: "dialog", "aria-modal": isModal, "aria-label": ui.chatDialogLabel, children: [
|
|
9851
|
+
/* @__PURE__ */ (0, import_jsx_runtime96.jsx)(
|
|
9444
9852
|
ChatHeader,
|
|
9445
9853
|
{
|
|
9446
9854
|
onClose: close,
|
|
@@ -9453,7 +9861,7 @@ function ChatPanel({ controller, ui, slip, onDashboardTap, monitor, discovery, g
|
|
|
9453
9861
|
moreOptionsLabel: ui.moreOptions
|
|
9454
9862
|
}
|
|
9455
9863
|
),
|
|
9456
|
-
monitor && /* @__PURE__ */ (0,
|
|
9864
|
+
monitor && /* @__PURE__ */ (0, import_jsx_runtime96.jsx)(
|
|
9457
9865
|
TabBar,
|
|
9458
9866
|
{
|
|
9459
9867
|
monitor,
|
|
@@ -9465,9 +9873,9 @@ function ChatPanel({ controller, ui, slip, onDashboardTap, monitor, discovery, g
|
|
|
9465
9873
|
gamesEnabled: gamesResult?.enabled ?? false
|
|
9466
9874
|
}
|
|
9467
9875
|
),
|
|
9468
|
-
/* @__PURE__ */ (0,
|
|
9469
|
-
/* @__PURE__ */ (0,
|
|
9470
|
-
showDial ? /* @__PURE__ */ (0,
|
|
9876
|
+
/* @__PURE__ */ (0, import_jsx_runtime96.jsxs)("div", { ref: layerRef, className: "ss-w-chat-layer", "data-dial": presetGrid ? "" : void 0, style: onChatTab ? void 0 : HIDDEN_LAYER_STYLE, children: [
|
|
9877
|
+
/* @__PURE__ */ (0, import_jsx_runtime96.jsx)(PresetToolsContext.Provider, { value: toolsValue, children: /* @__PURE__ */ (0, import_jsx_runtime96.jsx)(MessageList, { controller, ui, slip, onDashboardTap, monitor }) }),
|
|
9878
|
+
showDial ? /* @__PURE__ */ (0, import_jsx_runtime96.jsx)(
|
|
9471
9879
|
PresetSpeedDial,
|
|
9472
9880
|
{
|
|
9473
9881
|
expanded: dial.expanded,
|
|
@@ -9479,12 +9887,12 @@ function ChatPanel({ controller, ui, slip, onDashboardTap, monitor, discovery, g
|
|
|
9479
9887
|
buttonRef: dialButtonRef
|
|
9480
9888
|
}
|
|
9481
9889
|
) : null,
|
|
9482
|
-
tool && presetGrid && onChatTab ? tool.kind === "numbers" ? /* @__PURE__ */ (0,
|
|
9890
|
+
tool && presetGrid && onChatTab && !paused ? tool.kind === "numbers" ? /* @__PURE__ */ (0, import_jsx_runtime96.jsx)(SetNumbersTool, { grid: presetGrid, strings: ui.presets, streaming: state.isStreaming, onSend: sendAsk, onClose: closeTool }) : /* @__PURE__ */ (0, import_jsx_runtime96.jsx)(BuildComboTool, { grid: presetGrid, strings: ui.presets, streaming: state.isStreaming, formatKickoff, initialTotal: tool.total, initialLegs: tool.legs, onSend: sendAsk, onClose: closeTool }) : null
|
|
9483
9891
|
] }),
|
|
9484
|
-
monitor && discovery && monitor.activeTab === "today" && /* @__PURE__ */ (0,
|
|
9485
|
-
monitor && monitor.activeTab === "following" && /* @__PURE__ */ (0,
|
|
9486
|
-
monitor && monitor.activeTab === "odds" && /* @__PURE__ */ (0,
|
|
9487
|
-
monitor && monitor.activeTab === "games" && gamesResult && /* @__PURE__ */ (0,
|
|
9892
|
+
monitor && discovery && monitor.activeTab === "today" && /* @__PURE__ */ (0, import_jsx_runtime96.jsx)(TodayPanel, { discovery, ui, monitor }),
|
|
9893
|
+
monitor && monitor.activeTab === "following" && /* @__PURE__ */ (0, import_jsx_runtime96.jsx)(MatchesPanel, { monitor, ui, slip, onAsk: paused ? void 0 : handleAsk }),
|
|
9894
|
+
monitor && monitor.activeTab === "odds" && /* @__PURE__ */ (0, import_jsx_runtime96.jsx)(OddsPanel, { monitor, ui, slip }),
|
|
9895
|
+
monitor && monitor.activeTab === "games" && gamesResult && /* @__PURE__ */ (0, import_jsx_runtime96.jsx)(
|
|
9488
9896
|
GamesPanel,
|
|
9489
9897
|
{
|
|
9490
9898
|
loggedIn: !!loggedIn,
|
|
@@ -9498,7 +9906,7 @@ function ChatPanel({ controller, ui, slip, onDashboardTap, monitor, discovery, g
|
|
|
9498
9906
|
}
|
|
9499
9907
|
}
|
|
9500
9908
|
),
|
|
9501
|
-
monitor && monitor.activeTab === "leaderboard" && leaderboardResult && /* @__PURE__ */ (0,
|
|
9909
|
+
monitor && monitor.activeTab === "leaderboard" && leaderboardResult && /* @__PURE__ */ (0, import_jsx_runtime96.jsx)(
|
|
9502
9910
|
LeaderboardPanel,
|
|
9503
9911
|
{
|
|
9504
9912
|
loggedIn: !!loggedIn,
|
|
@@ -9508,27 +9916,30 @@ function ChatPanel({ controller, ui, slip, onDashboardTap, monitor, discovery, g
|
|
|
9508
9916
|
ui
|
|
9509
9917
|
}
|
|
9510
9918
|
),
|
|
9511
|
-
(!monitor || monitor.activeTab !== "games" && monitor.activeTab !== "leaderboard") && /* @__PURE__ */ (0,
|
|
9512
|
-
|
|
9513
|
-
|
|
9514
|
-
|
|
9515
|
-
|
|
9516
|
-
|
|
9517
|
-
|
|
9518
|
-
|
|
9519
|
-
|
|
9520
|
-
|
|
9521
|
-
|
|
9522
|
-
|
|
9523
|
-
|
|
9524
|
-
|
|
9919
|
+
(!monitor || monitor.activeTab !== "games" && monitor.activeTab !== "leaderboard") && /* @__PURE__ */ (0, import_jsx_runtime96.jsxs)(import_jsx_runtime96.Fragment, { children: [
|
|
9920
|
+
/* @__PURE__ */ (0, import_jsx_runtime96.jsx)("div", { ref: limitRef, className: "ss-w-limit", role: "status", tabIndex: -1, children: state.limit ? limitText(state.limit, ui) : null }),
|
|
9921
|
+
paused ? null : /* @__PURE__ */ (0, import_jsx_runtime96.jsx)(
|
|
9922
|
+
ChatInput,
|
|
9923
|
+
{
|
|
9924
|
+
ref: inputRef,
|
|
9925
|
+
placeholder: ui.placeholder,
|
|
9926
|
+
streaming: state.isStreaming,
|
|
9927
|
+
onSend: handleSend,
|
|
9928
|
+
onStop: stop,
|
|
9929
|
+
stopLabel: ui.stopResponse,
|
|
9930
|
+
sendLabel: ui.sendMessage,
|
|
9931
|
+
disabled: !!tool,
|
|
9932
|
+
onType: fold
|
|
9933
|
+
}
|
|
9934
|
+
)
|
|
9935
|
+
] })
|
|
9525
9936
|
] });
|
|
9526
9937
|
}
|
|
9527
9938
|
|
|
9528
9939
|
// src/components/HostEventsProvider.tsx
|
|
9529
|
-
var
|
|
9940
|
+
var import_jsx_runtime97 = require("react/jsx-runtime");
|
|
9530
9941
|
function HostEventsProvider({ value, children }) {
|
|
9531
|
-
return /* @__PURE__ */ (0,
|
|
9942
|
+
return /* @__PURE__ */ (0, import_jsx_runtime97.jsx)(SlipStateContext.Provider, { value: value.slipState, children });
|
|
9532
9943
|
}
|
|
9533
9944
|
|
|
9534
9945
|
// src/styles/css.generated.ts
|
|
@@ -10119,6 +10530,10 @@ var WIDGET_CSS = `.ss-w-root { all: revert; }
|
|
|
10119
10530
|
|
|
10120
10531
|
/* input */
|
|
10121
10532
|
.ss-w-input { display: flex; align-items: flex-end; gap: 8px; padding: 10px 12px; border-top: 1px solid var(--ss-w-line); }
|
|
10533
|
+
.ss-w-limit { padding: 10px 12px; border-top: 1px solid var(--ss-w-line); font-size: 13px; line-height: 1.4; color: var(--ss-w-ink); overflow-wrap: anywhere; }
|
|
10534
|
+
.ss-w-limit:empty { padding: 0; border-top: 0; }
|
|
10535
|
+
.ss-w-limit:focus { outline: none; }
|
|
10536
|
+
.ss-w-limit:not(:empty) + .ss-w-input { border-top: none; }
|
|
10122
10537
|
.ss-w-textarea { flex: 1; resize: none; border: 1px solid var(--ss-w-line); border-radius: 12px; padding: 8px 10px; font: inherit; color: inherit; background: var(--ss-w-panel); max-height: 96px; }
|
|
10123
10538
|
.ss-w-textarea:disabled { opacity: .55; cursor: not-allowed; }
|
|
10124
10539
|
/* iOS Safari zooms the page when a focused field's font-size is < 16px. Bump it
|
|
@@ -10717,14 +11132,60 @@ var WIDGET_CSS = `.ss-w-root { all: revert; }
|
|
|
10717
11132
|
.ss-w-sec-dot { width: 6px; height: 6px; border-radius: 50%; background: var(--ss-w-neg); flex: none; }
|
|
10718
11133
|
.ss-w-today-live { display: flex; flex-direction: column; gap: 2px; }
|
|
10719
11134
|
|
|
10720
|
-
|
|
10721
|
-
|
|
10722
|
-
.ss-w-
|
|
10723
|
-
|
|
10724
|
-
|
|
10725
|
-
|
|
10726
|
-
|
|
10727
|
-
.ss-w-
|
|
11135
|
+
/* Today tab root (Task 7): position: relative so the grid's own star/unstar toast (absolute,
|
|
11136
|
+
top-centre) anchors here rather than to some unrelated positioned ancestor. */
|
|
11137
|
+
/* Non-scrolling anchor for .ss-w-today-toast (position: absolute; top: 0): .ss-w-mon-list below is
|
|
11138
|
+
the overflow-y: auto scroller, so a toast parented to IT would scroll out of view with the
|
|
11139
|
+
content that moved it. This wrapper sits outside that scroller, inside .ss-w-panel's fixed-size
|
|
11140
|
+
flex column, so top: 0 always lands at the visible top of the Today tab. min-height: 0 is
|
|
11141
|
+
required: without it this flex item defaults to min-height: auto (its content height), .ss-w-panel's
|
|
11142
|
+
overflow: hidden then clips it, and .ss-w-mon-list inside never gets a bounded height to scroll within. */
|
|
11143
|
+
.ss-w-today-root { position: relative; flex: 1; min-height: 0; display: flex; flex-direction: column; }
|
|
11144
|
+
|
|
11145
|
+
/* Section header for "Your leagues"/"Top leagues"/"All leagues" (Task 7) -- same visual
|
|
11146
|
+
treatment as .ss-w-sec-head (the live-band header), kept as a separate class so a kept test
|
|
11147
|
+
asserting .ss-w-sec-head is absent when nothing is live cannot see this header too. */
|
|
11148
|
+
.ss-w-today-sec { display: flex; align-items: center; gap: 7px; padding: 2px 2px 0; font-size: 10px; font-weight: 800; letter-spacing: .09em; text-transform: uppercase; color: var(--ss-w-faint); }
|
|
11149
|
+
.ss-w-today-sec::after { content: ""; flex: 1; height: 1px; background: var(--ss-w-line); }
|
|
11150
|
+
.ss-w-today-sec-sub { text-transform: none; letter-spacing: normal; font-weight: 600; }
|
|
11151
|
+
.ss-w-today-tiles { display: grid; grid-template-columns: 1fr 1fr; gap: 8px; }
|
|
11152
|
+
.ss-w-today-empty { font-size: 12px; color: var(--ss-w-faint); padding: 10px 2px; }
|
|
11153
|
+
|
|
11154
|
+
/* League tile (Task 5): a flat row (crest + name as the open target, star as a separate sibling
|
|
11155
|
+
button) rather than a disclosure header -- opening is Task 6's LeagueDetail, not an inline
|
|
11156
|
+
expansion. Same border/radius language .ss-w-grp used to carry, before Task 7 deleted it. */
|
|
11157
|
+
.ss-w-today-tile { display: flex; align-items: center; gap: 6px; border: 1px solid var(--ss-w-line); border-radius: 12px; overflow: hidden; background: var(--ss-w-bubble); }
|
|
11158
|
+
.ss-w-today-tile-body { flex: 1; min-width: 0; display: flex; align-items: center; gap: 8px; padding: 8px 9px; background: none; border: none; font: inherit; color: var(--ss-w-ink); cursor: pointer; text-align: left; }
|
|
11159
|
+
.ss-w-today-tile-body:focus-visible { outline: 2px solid var(--ss-w-accent); outline-offset: -2px; }
|
|
11160
|
+
.ss-w-today-tile-name { font-size: 12px; font-weight: 700; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
|
|
11161
|
+
.ss-w-today-tile-country { font-weight: 600; color: var(--ss-w-faint); }
|
|
11162
|
+
.ss-w-today-tile-star { flex: none; display: flex; align-items: center; justify-content: center; width: 32px; height: 32px; margin: 0 6px; background: none; border: none; border-radius: 8px; color: var(--ss-w-faint); cursor: pointer; }
|
|
11163
|
+
.ss-w-today-tile-star:focus-visible { outline: 2px solid var(--ss-w-accent); outline-offset: -2px; }
|
|
11164
|
+
.ss-w-today-tile-star[aria-pressed="true"] { color: var(--ss-w-accent); }
|
|
11165
|
+
.ss-w-today-tile-star:disabled { cursor: default; opacity: .4; }
|
|
11166
|
+
.ss-w-today-tile-star svg { width: 18px; height: 18px; }
|
|
11167
|
+
|
|
11168
|
+
/* League detail (Task 6): the drill-in view opened from a tile. Its header star is always
|
|
11169
|
+
enabled (spec \xA73/\xA77's one exception to the tile rule), so it carries no :disabled styling. */
|
|
11170
|
+
.ss-w-today-detail { position: relative; display: flex; flex-direction: column; gap: 10px; }
|
|
11171
|
+
.ss-w-today-detail-head { display: flex; align-items: center; gap: 8px; }
|
|
11172
|
+
.ss-w-today-detail-back { flex: none; display: flex; align-items: center; justify-content: center; width: 28px; height: 28px; background: none; border: none; border-radius: 8px; color: var(--ss-w-ink); cursor: pointer; transform: scaleX(-1); }
|
|
11173
|
+
.ss-w-today-detail-back:focus-visible { outline: 2px solid var(--ss-w-accent); outline-offset: -2px; }
|
|
11174
|
+
.ss-w-today-detail-name { flex: 1; min-width: 0; font-size: 13px; font-weight: 700; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
|
|
11175
|
+
.ss-w-today-detail-star { flex: none; display: flex; align-items: center; justify-content: center; width: 32px; height: 32px; background: none; border: none; border-radius: 8px; color: var(--ss-w-faint); cursor: pointer; }
|
|
11176
|
+
.ss-w-today-detail-star:focus-visible { outline: 2px solid var(--ss-w-accent); outline-offset: -2px; }
|
|
11177
|
+
.ss-w-today-detail-star[aria-pressed="true"] { color: var(--ss-w-accent); }
|
|
11178
|
+
.ss-w-today-detail-star svg { width: 18px; height: 18px; }
|
|
11179
|
+
.ss-w-today-detail-nav { display: flex; align-items: center; justify-content: center; gap: 10px; }
|
|
11180
|
+
.ss-w-today-detail-prev, .ss-w-today-detail-next { flex: none; display: flex; align-items: center; justify-content: center; width: 26px; height: 26px; background: none; border: none; border-radius: 8px; color: var(--ss-w-faint); cursor: pointer; }
|
|
11181
|
+
.ss-w-today-detail-prev:focus-visible, .ss-w-today-detail-next:focus-visible { outline: 2px solid var(--ss-w-accent); outline-offset: -2px; }
|
|
11182
|
+
.ss-w-today-detail-prev { transform: scaleX(-1); }
|
|
11183
|
+
.ss-w-today-detail-pos { font-size: 10.5px; font-weight: 700; color: var(--ss-w-faint); font-variant-numeric: tabular-nums; }
|
|
11184
|
+
.ss-w-today-detail-body { display: flex; flex-direction: column; }
|
|
11185
|
+
.ss-w-today-detail-count { align-self: flex-end; flex: none; font-size: 10.5px; font-weight: 700; color: var(--ss-w-faint); background: var(--ss-w-panel); border: 1px solid var(--ss-w-line); border-radius: 999px; padding: 1px 7px; font-variant-numeric: tabular-nums; margin-bottom: 4px; }
|
|
11186
|
+
/* aria-live status region, not a modal -- pointer-events: none so the header/nav above stay
|
|
11187
|
+
clickable while it is showing. */
|
|
11188
|
+
.ss-w-today-toast { position: absolute; top: 0; left: 50%; transform: translateX(-50%); z-index: 1; pointer-events: none; width: max-content; max-width: 220px; font-size: 11px; font-weight: 560; color: var(--ss-w-accent); background: color-mix(in srgb, var(--ss-w-accent) 14%, var(--ss-w-panel)); border: 1px solid color-mix(in srgb, var(--ss-w-accent) 30%, var(--ss-w-line)); border-radius: 10px; padding: 5px 10px; box-shadow: 0 4px 14px rgba(0,0,0,.14); }
|
|
10728
11189
|
|
|
10729
11190
|
.ss-w-drow { display: grid; grid-template-columns: 42px minmax(0,1fr) 22px; align-items: center; gap: 9px; padding: 7px 0; border-bottom: 1px solid var(--ss-w-line); }
|
|
10730
11191
|
.ss-w-drow:last-child { border-bottom: none; }
|
|
@@ -11210,14 +11671,14 @@ var WIDGET_CSS = `.ss-w-root { all: revert; }
|
|
|
11210
11671
|
`;
|
|
11211
11672
|
|
|
11212
11673
|
// src/StatsWidget.tsx
|
|
11213
|
-
var
|
|
11674
|
+
var import_jsx_runtime98 = require("react/jsx-runtime");
|
|
11214
11675
|
function buildClient(props) {
|
|
11215
11676
|
try {
|
|
11216
11677
|
if ("client" in props && props.client) {
|
|
11217
11678
|
return { client: props.client, conversation: props.client.conversation() };
|
|
11218
11679
|
}
|
|
11219
11680
|
const cfg = props.config;
|
|
11220
|
-
const client = new
|
|
11681
|
+
const client = new import_widget_sdk6.StatsWidgetClient(toClientOptions(cfg));
|
|
11221
11682
|
return { client, conversation: client.conversation(toUserContext(cfg)) };
|
|
11222
11683
|
} catch (err) {
|
|
11223
11684
|
console.error("[StatsWidget] failed to initialize:", err instanceof Error ? err.message : err);
|
|
@@ -11235,24 +11696,24 @@ function injectStyles(root) {
|
|
|
11235
11696
|
function StatsWidget(props) {
|
|
11236
11697
|
const injectedClient = "client" in props ? props.client : void 0;
|
|
11237
11698
|
const cfg = props.config;
|
|
11238
|
-
const built = (0,
|
|
11239
|
-
const logger = (0,
|
|
11699
|
+
const built = (0, import_react60.useMemo)(() => buildClient(props), [injectedClient, cfg?.operatorId, cfg?.publicKey, cfg?.baseUrl]);
|
|
11700
|
+
const logger = (0, import_react60.useMemo)(
|
|
11240
11701
|
() => built ? built.client.createEventLogger({
|
|
11241
11702
|
operatorUserId: cfg?.userContext?.operatorUserId,
|
|
11242
11703
|
anonymousUserId: cfg?.userContext?.anonymousUserId
|
|
11243
11704
|
}) : null,
|
|
11244
11705
|
[built?.client]
|
|
11245
11706
|
);
|
|
11246
|
-
const ui = (0,
|
|
11247
|
-
const rootRef = (0,
|
|
11248
|
-
const introDoneRef = (0,
|
|
11249
|
-
const markIntroDone = (0,
|
|
11707
|
+
const ui = (0, import_react60.useMemo)(() => normalizeUi(props.config ?? { operatorId: "", publicKey: "" }), [props.config]);
|
|
11708
|
+
const rootRef = (0, import_react60.useRef)(null);
|
|
11709
|
+
const introDoneRef = (0, import_react60.useRef)(false);
|
|
11710
|
+
const markIntroDone = (0, import_react60.useCallback)(() => {
|
|
11250
11711
|
introDoneRef.current = true;
|
|
11251
11712
|
}, []);
|
|
11252
11713
|
const convStorageKey = `ss-w-conv:${cfg?.operatorId ?? ""}:${cfg?.userContext?.operatorUserId ?? "anon"}`;
|
|
11253
11714
|
const controller = useChatStream(built?.conversation ?? emptyConversation(), ui.starters, built ? ui.greetingMessage : void 0, convStorageKey);
|
|
11254
|
-
const [hasToday, setHasToday] = (0,
|
|
11255
|
-
const liveCardWatches = (0,
|
|
11715
|
+
const [hasToday, setHasToday] = (0, import_react60.useState)(false);
|
|
11716
|
+
const liveCardWatches = (0, import_react60.useMemo)(() => {
|
|
11256
11717
|
const seen = /* @__PURE__ */ new Set();
|
|
11257
11718
|
const out = [];
|
|
11258
11719
|
for (const msg of controller.state.messages) {
|
|
@@ -11274,31 +11735,40 @@ function StatsWidget(props) {
|
|
|
11274
11735
|
hasToday,
|
|
11275
11736
|
watches: liveCardWatches
|
|
11276
11737
|
});
|
|
11277
|
-
const
|
|
11278
|
-
|
|
11279
|
-
|
|
11738
|
+
const operatorUserId = cfg?.userContext?.operatorUserId;
|
|
11739
|
+
const anonymousUserId = cfg?.userContext?.anonymousUserId;
|
|
11740
|
+
const getSchedule = (0, import_react60.useCallback)(
|
|
11741
|
+
(localDate, utcOffsetMinutes) => built ? built.conversation.getSchedule(localDate, utcOffsetMinutes, operatorUserId, anonymousUserId) : Promise.resolve(null),
|
|
11742
|
+
[built, operatorUserId, anonymousUserId]
|
|
11280
11743
|
);
|
|
11281
|
-
const
|
|
11744
|
+
const postLeagueStar = (0, import_react60.useCallback)(
|
|
11745
|
+
(competitionId, starred) => built ? built.conversation.starLeague(competitionId, starred, operatorUserId, anonymousUserId) : Promise.resolve(null),
|
|
11746
|
+
[built, operatorUserId, anonymousUserId]
|
|
11747
|
+
);
|
|
11748
|
+
const getStates = (0, import_react60.useCallback)(
|
|
11282
11749
|
(matchIds) => built ? built.conversation.getStates(matchIds) : Promise.resolve(null),
|
|
11283
11750
|
[built]
|
|
11284
11751
|
);
|
|
11285
|
-
const pinnedMatchIds = (0,
|
|
11752
|
+
const pinnedMatchIds = (0, import_react60.useMemo)(
|
|
11286
11753
|
() => monitor.pins.filter((p) => p.kind === "match").map((p) => p.matchId),
|
|
11287
11754
|
[monitor.pins]
|
|
11288
11755
|
);
|
|
11289
11756
|
const discovery = useMatchDiscovery({
|
|
11290
11757
|
getSchedule,
|
|
11291
11758
|
getStates,
|
|
11759
|
+
postLeagueStar,
|
|
11292
11760
|
operatorId: cfg?.operatorId ?? "",
|
|
11761
|
+
operatorUserId,
|
|
11762
|
+
anonymousUserId,
|
|
11293
11763
|
isOpen: controller.state.isOpen,
|
|
11294
11764
|
pinnedMatchIds
|
|
11295
11765
|
});
|
|
11296
11766
|
const todayHasContent = visibleGroupsOf(discovery.groups, discovery.states).length > 0;
|
|
11297
|
-
(0,
|
|
11767
|
+
(0, import_react60.useEffect)(() => {
|
|
11298
11768
|
setHasToday(todayHasContent);
|
|
11299
11769
|
}, [todayHasContent]);
|
|
11300
|
-
const prevLiveSnapshotRef = (0,
|
|
11301
|
-
(0,
|
|
11770
|
+
const prevLiveSnapshotRef = (0, import_react60.useRef)(monitor.snapshot);
|
|
11771
|
+
(0, import_react60.useEffect)(() => {
|
|
11302
11772
|
const snap = monitor.snapshot;
|
|
11303
11773
|
if (!snap || snap === prevLiveSnapshotRef.current) return;
|
|
11304
11774
|
prevLiveSnapshotRef.current = snap;
|
|
@@ -11334,14 +11804,14 @@ function StatsWidget(props) {
|
|
|
11334
11804
|
}, [monitor.snapshot]);
|
|
11335
11805
|
const gamesResult = useGames(built?.conversation ?? null, { activeTab: monitor.activeTab });
|
|
11336
11806
|
const leaderboardResult = useLeaderboard(built?.conversation ?? null, { activeTab: monitor.activeTab });
|
|
11337
|
-
const getPricePresets = (0,
|
|
11807
|
+
const getPricePresets = (0, import_react60.useCallback)(
|
|
11338
11808
|
(locale2) => built ? built.conversation.getPricePresets(locale2, { pool: "open" }) : Promise.resolve(null),
|
|
11339
11809
|
[built]
|
|
11340
11810
|
);
|
|
11341
11811
|
const presetGrid = usePresetGrid({ getPricePresets, isOpen: controller.state.isOpen, locale: ui.presets.lang });
|
|
11342
11812
|
const markTodayActivity = monitor.markTodayActivity;
|
|
11343
|
-
const prevLiveCountRef = (0,
|
|
11344
|
-
(0,
|
|
11813
|
+
const prevLiveCountRef = (0, import_react60.useRef)(0);
|
|
11814
|
+
(0, import_react60.useEffect)(() => {
|
|
11345
11815
|
const rose = prevLiveCountRef.current === 0 && discovery.liveCount > 0;
|
|
11346
11816
|
prevLiveCountRef.current = discovery.liveCount;
|
|
11347
11817
|
if (rose) markTodayActivity();
|
|
@@ -11355,7 +11825,7 @@ function StatsWidget(props) {
|
|
|
11355
11825
|
closePanel: controller.close
|
|
11356
11826
|
});
|
|
11357
11827
|
const markAdded = hostEvents.markAdded;
|
|
11358
|
-
const slip = (0,
|
|
11828
|
+
const slip = (0, import_react60.useMemo)(
|
|
11359
11829
|
() => {
|
|
11360
11830
|
const handler = props.config?.onAddToSlip;
|
|
11361
11831
|
return {
|
|
@@ -11374,7 +11844,7 @@ function StatsWidget(props) {
|
|
|
11374
11844
|
},
|
|
11375
11845
|
[props.config?.onAddToSlip, controller.state.conversationId, markAdded]
|
|
11376
11846
|
);
|
|
11377
|
-
const onDashboardTap = (0,
|
|
11847
|
+
const onDashboardTap = (0, import_react60.useMemo)(
|
|
11378
11848
|
() => built ? createDashboardTapSignal((input) => built.conversation.sendSignal(input), logger) : void 0,
|
|
11379
11849
|
[built, logger]
|
|
11380
11850
|
);
|
|
@@ -11390,14 +11860,12 @@ function StatsWidget(props) {
|
|
|
11390
11860
|
log: logger
|
|
11391
11861
|
})
|
|
11392
11862
|
}));
|
|
11393
|
-
const operatorUserId = cfg?.userContext?.operatorUserId;
|
|
11394
|
-
const anonymousUserId = cfg?.userContext?.anonymousUserId;
|
|
11395
11863
|
const conversationId = controller.state.conversationId ?? void 0;
|
|
11396
|
-
(0,
|
|
11864
|
+
(0, import_react60.useEffect)(() => {
|
|
11397
11865
|
if (!logger) return;
|
|
11398
11866
|
logger.setIdentity({ operatorUserId, anonymousUserId, conversationId });
|
|
11399
11867
|
}, [logger, operatorUserId, anonymousUserId, conversationId]);
|
|
11400
|
-
(0,
|
|
11868
|
+
(0, import_react60.useEffect)(() => {
|
|
11401
11869
|
if (!logger) return;
|
|
11402
11870
|
logger.resume();
|
|
11403
11871
|
const onHide = () => {
|
|
@@ -11415,14 +11883,14 @@ function StatsWidget(props) {
|
|
|
11415
11883
|
logger.dispose();
|
|
11416
11884
|
};
|
|
11417
11885
|
}, [logger]);
|
|
11418
|
-
(0,
|
|
11886
|
+
(0, import_react60.useEffect)(() => {
|
|
11419
11887
|
if (!built || !ui.injectStyles) return;
|
|
11420
11888
|
const node = rootRef.current?.getRootNode();
|
|
11421
11889
|
if (node) injectStyles(node);
|
|
11422
11890
|
}, [built, ui.injectStyles]);
|
|
11423
11891
|
if (!built) return null;
|
|
11424
11892
|
const attrs = themeAttrs(ui);
|
|
11425
|
-
return /* @__PURE__ */ (0,
|
|
11893
|
+
return /* @__PURE__ */ (0, import_jsx_runtime98.jsx)(EventLogContext.Provider, { value: logger, children: /* @__PURE__ */ (0, import_jsx_runtime98.jsx)(HostEventsProvider, { value: hostEvents, children: /* @__PURE__ */ (0, import_jsx_runtime98.jsx)("div", { ref: rootRef, className: "ss-w-root", "data-ss-w-theme": attrs["data-ss-w-theme"], "data-ss-w-pos": attrs["data-ss-w-pos"], style: attrs.style, children: controller.state.isOpen ? /* @__PURE__ */ (0, import_jsx_runtime98.jsx)(
|
|
11426
11894
|
ChatPanel,
|
|
11427
11895
|
{
|
|
11428
11896
|
controller,
|
|
@@ -11437,7 +11905,7 @@ function StatsWidget(props) {
|
|
|
11437
11905
|
conversation: built?.conversation ?? null,
|
|
11438
11906
|
presetGrid
|
|
11439
11907
|
}
|
|
11440
|
-
) : /* @__PURE__ */ (0,
|
|
11908
|
+
) : /* @__PURE__ */ (0, import_jsx_runtime98.jsx)(
|
|
11441
11909
|
ChatFab,
|
|
11442
11910
|
{
|
|
11443
11911
|
label: ui.launcherLabel,
|