@agg-market/ui 9.0.0 → 11.0.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.
Files changed (76) hide show
  1. package/dist/{chunk-6CRY27SQ.mjs → chunk-2KGE5AJQ.mjs} +670 -659
  2. package/dist/{chunk-N7U7QCSB.mjs → chunk-5FSWOXEG.mjs} +807 -358
  3. package/dist/{chunk-HJ4UPYM7.mjs → chunk-HMUMJUIL.mjs} +539 -405
  4. package/dist/{chunk-3G7C6WEC.mjs → chunk-IUJXJEDQ.mjs} +1340 -664
  5. package/dist/{chunk-3U4VHAP6.mjs → chunk-UONHGMFI.mjs} +12 -4
  6. package/dist/events.js +1267 -1035
  7. package/dist/events.mjs +6 -4
  8. package/dist/index.js +4443 -3205
  9. package/dist/index.mjs +18 -7
  10. package/dist/modals.js +1207 -379
  11. package/dist/modals.mjs +4 -2
  12. package/dist/pages.js +2942 -1689
  13. package/dist/pages.mjs +4 -4
  14. package/dist/primitives.js +1317 -657
  15. package/dist/primitives.mjs +5 -1
  16. package/dist/styles.css +1 -1
  17. package/dist/tailwind.css +1 -1
  18. package/dist/trading.js +274 -190
  19. package/dist/trading.mjs +2 -2
  20. package/dist/types/events/item/event-list-item.types.d.mts +1 -2
  21. package/dist/types/events/item/event-list-item.types.d.ts +1 -2
  22. package/dist/types/events/item-details/event-list-item-details.types.d.mts +1 -4
  23. package/dist/types/events/item-details/event-list-item-details.types.d.ts +1 -4
  24. package/dist/types/events/item-details/event-list-item-details.utils.d.mts +42 -3
  25. package/dist/types/events/item-details/event-list-item-details.utils.d.ts +42 -3
  26. package/dist/types/events/list/event-list.types.d.mts +3 -2
  27. package/dist/types/events/list/event-list.types.d.ts +3 -2
  28. package/dist/types/events/list/index.d.mts +1 -1
  29. package/dist/types/events/list/index.d.ts +1 -1
  30. package/dist/types/events/market-details/index.d.mts +7 -3
  31. package/dist/types/events/market-details/index.d.ts +7 -3
  32. package/dist/types/events/market-details/market-details.types.d.mts +30 -10
  33. package/dist/types/events/market-details/market-details.types.d.ts +30 -10
  34. package/dist/types/events/market-details/market-details.utils.d.mts +15 -10
  35. package/dist/types/events/market-details/market-details.utils.d.ts +15 -10
  36. package/dist/types/modals/index.d.mts +1 -0
  37. package/dist/types/modals/index.d.ts +1 -0
  38. package/dist/types/pages/event-market/event-market.types.d.mts +2 -0
  39. package/dist/types/pages/event-market/event-market.types.d.ts +2 -0
  40. package/dist/types/pages/home/home.constants.d.mts +1 -3
  41. package/dist/types/pages/home/home.constants.d.ts +1 -3
  42. package/dist/types/pages/home/home.types.d.mts +0 -2
  43. package/dist/types/pages/home/home.types.d.ts +0 -2
  44. package/dist/types/pages/home/home.utils.d.mts +4 -0
  45. package/dist/types/pages/home/home.utils.d.ts +4 -0
  46. package/dist/types/pages/home/index.d.mts +1 -1
  47. package/dist/types/pages/home/index.d.ts +1 -1
  48. package/dist/types/primitives/agg-logo/index.d.mts +6 -0
  49. package/dist/types/primitives/agg-logo/index.d.ts +6 -0
  50. package/dist/types/primitives/chart/index.d.mts +9 -1
  51. package/dist/types/primitives/chart/index.d.ts +9 -1
  52. package/dist/types/primitives/header/agg-logo.d.mts +2 -0
  53. package/dist/types/primitives/header/agg-logo.d.ts +2 -0
  54. package/dist/types/primitives/header/header.constants.d.mts +3 -0
  55. package/dist/types/primitives/header/header.constants.d.ts +3 -0
  56. package/dist/types/primitives/header/header.types.d.mts +28 -0
  57. package/dist/types/primitives/header/header.types.d.ts +28 -0
  58. package/dist/types/primitives/header/index.d.mts +7 -0
  59. package/dist/types/primitives/header/index.d.ts +7 -0
  60. package/dist/types/primitives/index.d.mts +2 -0
  61. package/dist/types/primitives/index.d.ts +2 -0
  62. package/dist/types/primitives/search/index.d.mts +1 -1
  63. package/dist/types/primitives/search/index.d.ts +1 -1
  64. package/dist/types/primitives/search/search.types.d.mts +9 -59
  65. package/dist/types/primitives/search/search.types.d.ts +9 -59
  66. package/dist/types/primitives/search/search.utils.d.mts +4 -0
  67. package/dist/types/primitives/search/search.utils.d.ts +4 -0
  68. package/dist/types/primitives/skeleton/skeleton.types.d.mts +1 -0
  69. package/dist/types/primitives/skeleton/skeleton.types.d.ts +1 -0
  70. package/dist/types/primitives/skeleton/views/search-skeleton-view.d.mts +5 -0
  71. package/dist/types/primitives/skeleton/views/search-skeleton-view.d.ts +5 -0
  72. package/dist/types/primitives/venue-logo/index.d.mts +1 -1
  73. package/dist/types/primitives/venue-logo/index.d.ts +1 -1
  74. package/dist/types/trading/types.d.mts +2 -2
  75. package/dist/types/trading/types.d.ts +2 -2
  76. package/package.json +4 -4
@@ -20,14 +20,24 @@ import {
20
20
  detailsBaseCardClassName,
21
21
  eventListItemDetailsTimeRanges,
22
22
  fallbackLineColors,
23
+ formatCountLabel,
23
24
  getMarketDetailsTabs,
24
25
  getMotionClassName,
26
+ getVenueSummary,
25
27
  lineColorByVenue,
26
28
  marketDetailsBaseCardClassName,
27
29
  marketDetailsDefaultIsOpened,
30
+ normalizeProbability,
28
31
  orderBookRowLimitDefault,
29
- toDate
30
- } from "./chunk-3G7C6WEC.mjs";
32
+ resolveEventListItemEvent,
33
+ resolveOutcomeTitle,
34
+ resolveTileImage,
35
+ resolveTileTitle,
36
+ resolveVenueLabel,
37
+ resolveVisibleOutcomes,
38
+ selectPrimaryVenueMarket,
39
+ sortOutcomes
40
+ } from "./chunk-IUJXJEDQ.mjs";
31
41
 
32
42
  // src/events/item/index.tsx
33
43
  import dayjs from "dayjs";
@@ -49,142 +59,6 @@ var isErrorWithStatus = (error, status) => {
49
59
  return getErrorStatus(error) === status;
50
60
  };
51
61
 
52
- // src/events/item/event-list-item.utils.ts
53
- var resolveEventListItemEvent = (fetchedEvent) => {
54
- if (!fetchedEvent)
55
- return void 0;
56
- if (!fetchedEvent.venueMarkets || fetchedEvent.venueMarkets.length === 0)
57
- return void 0;
58
- return fetchedEvent;
59
- };
60
- var normalizeProbability = (value) => {
61
- if (typeof value !== "number" || !Number.isFinite(value))
62
- return void 0;
63
- if (value < 0)
64
- return 0;
65
- if (value > 1)
66
- return 1;
67
- return value;
68
- };
69
- var hasDateLabel = (outcome) => {
70
- return !!toDate(outcome.label);
71
- };
72
- var sortOutcomes = (outcomes) => {
73
- if (outcomes.length <= 1)
74
- return outcomes;
75
- const now = Date.now();
76
- if (outcomes.some(hasDateLabel)) {
77
- return [...outcomes].sort((a, b) => {
78
- var _a, _b, _c, _d;
79
- const aDate = (_b = (_a = toDate(a.label)) == null ? void 0 : _a.getTime()) != null ? _b : 0;
80
- const bDate = (_d = (_c = toDate(b.label)) == null ? void 0 : _c.getTime()) != null ? _d : 0;
81
- return Math.abs(aDate - now) - Math.abs(bDate - now);
82
- });
83
- }
84
- return [...outcomes].sort((a, b) => {
85
- var _a, _b;
86
- const aPrice = (_a = normalizeProbability(a.price)) != null ? _a : 0;
87
- const bPrice = (_b = normalizeProbability(b.price)) != null ? _b : 0;
88
- return bPrice - aPrice;
89
- });
90
- };
91
- var compareVisibleOutcomeRows = (left, right) => {
92
- var _a, _b;
93
- const leftDate = toDate(resolveOutcomeTitle(left.outcome));
94
- const rightDate = toDate(resolveOutcomeTitle(right.outcome));
95
- if (leftDate && rightDate) {
96
- return leftDate.getTime() - rightDate.getTime();
97
- }
98
- const leftProbability = (_a = normalizeProbability(left.outcome.price)) != null ? _a : -1;
99
- const rightProbability = (_b = normalizeProbability(right.outcome.price)) != null ? _b : -1;
100
- return rightProbability - leftProbability;
101
- };
102
- var shouldReplaceVisibleOutcome = (current, next) => {
103
- var _a, _b;
104
- const currentVolume = typeof current.market.volume === "number" ? current.market.volume : -1;
105
- const nextVolume = typeof next.market.volume === "number" ? next.market.volume : -1;
106
- if (currentVolume !== nextVolume) {
107
- return nextVolume > currentVolume;
108
- }
109
- const currentProbability = (_a = normalizeProbability(current.outcome.price)) != null ? _a : -1;
110
- const nextProbability = (_b = normalizeProbability(next.outcome.price)) != null ? _b : -1;
111
- return nextProbability > currentProbability;
112
- };
113
- var resolveVisibleOutcomes = (venueMarkets, maxOutcomes) => {
114
- const visibleOutcomesByLabel = /* @__PURE__ */ new Map();
115
- venueMarkets.forEach((market) => {
116
- sortOutcomes(market.venueMarketOutcomes).forEach((outcome) => {
117
- const title = resolveOutcomeTitle(outcome);
118
- const normalizedTitle = title.trim().toLowerCase();
119
- const nextVisibleOutcome = {
120
- venue: market.venue,
121
- market,
122
- outcome,
123
- title
124
- };
125
- const currentVisibleOutcome = visibleOutcomesByLabel.get(normalizedTitle);
126
- if (!currentVisibleOutcome || shouldReplaceVisibleOutcome(currentVisibleOutcome, nextVisibleOutcome)) {
127
- visibleOutcomesByLabel.set(normalizedTitle, nextVisibleOutcome);
128
- }
129
- });
130
- });
131
- return [...visibleOutcomesByLabel.values()].sort(compareVisibleOutcomeRows).slice(0, Math.max(1, maxOutcomes));
132
- };
133
- var resolveOutcomeTitle = (outcome) => {
134
- if (outcome.title && outcome.title.trim())
135
- return outcome.title;
136
- return outcome.label;
137
- };
138
- var selectPrimaryVenueMarket = (venueMarkets) => {
139
- if (venueMarkets.length === 0)
140
- return void 0;
141
- if (venueMarkets.length === 1)
142
- return venueMarkets[0];
143
- return [...venueMarkets].sort((a, b) => {
144
- const aVolume = typeof a.volume === "number" ? a.volume : -1;
145
- const bVolume = typeof b.volume === "number" ? b.volume : -1;
146
- return bVolume - aVolume;
147
- })[0];
148
- };
149
- var resolveTileTitle = (event, primaryVenueMarket, titleOverride) => {
150
- if (typeof titleOverride === "string" && titleOverride.trim()) {
151
- return titleOverride;
152
- }
153
- if (typeof (primaryVenueMarket == null ? void 0 : primaryVenueMarket.question) === "string" && primaryVenueMarket.question.trim()) {
154
- return primaryVenueMarket.question;
155
- }
156
- return event.title;
157
- };
158
- var resolveTileImage = (event, primaryVenueMarket, imageOverride) => {
159
- if (typeof imageOverride === "string" && imageOverride.trim()) {
160
- return imageOverride;
161
- }
162
- if (typeof (primaryVenueMarket == null ? void 0 : primaryVenueMarket.image) === "string" && primaryVenueMarket.image.trim()) {
163
- return primaryVenueMarket.image;
164
- }
165
- if (typeof event.image === "string" && event.image.trim()) {
166
- return event.image;
167
- }
168
- return void 0;
169
- };
170
- var formatCountLabel = (count, singular, plural) => {
171
- return `${count} ${count === 1 ? singular : plural}`;
172
- };
173
- var getVenueSummary = (venueMarkets) => {
174
- const uniqueVenues = Array.from(new Set(venueMarkets.map((market) => market.venue)));
175
- return {
176
- marketCount: venueMarkets.length,
177
- venueCount: uniqueVenues.length,
178
- singleVenue: uniqueVenues.length === 1 ? uniqueVenues[0] : void 0
179
- };
180
- };
181
- var resolveVenueLabel = (venue, venueInfo, labels) => {
182
- var _a, _b;
183
- if (!venue)
184
- return labels.eventItem.venueSingular;
185
- return (_b = (_a = venueInfo == null ? void 0 : venueInfo[venue]) == null ? void 0 : _a.label) != null ? _b : labels.venues[venue];
186
- };
187
-
188
62
  // src/events/item/index.tsx
189
63
  import { jsx, jsxs } from "react/jsx-runtime";
190
64
  var EventListItemLoadingState = ({
@@ -238,7 +112,6 @@ var EventListItemContent = ({
238
112
  event,
239
113
  title,
240
114
  image,
241
- showVenueLogo = true,
242
115
  maxOutcomes = 2,
243
116
  classNames,
244
117
  venueInfo,
@@ -268,22 +141,22 @@ var EventListItemContent = ({
268
141
  return Array.from(new Set(allVenueMarkets.map((market) => market.venue))).slice(0, 4);
269
142
  }, [allVenueMarkets]);
270
143
  const resolvedVolume = typeof event.volume === "number" ? event.volume : (_a = primaryVenueMarket == null ? void 0 : primaryVenueMarket.volume) != null ? _a : void 0;
271
- const volumeLabel = typeof resolvedVolume === "number" ? `${config.formatCompactCurrency(resolvedVolume)} ${labels.eventItem.volumeSuffix}` : "";
144
+ const volumeLabel = typeof resolvedVolume === "number" ? `${config.formatting.formatCompactCurrency(resolvedVolume)} ${labels.eventItem.volumeSuffix}` : "";
272
145
  const handleKeyDown = (eventToHandle) => {
273
146
  if (!onClick)
274
147
  return;
275
148
  if ((eventToHandle == null ? void 0 : eventToHandle.key) === "Enter" || (eventToHandle == null ? void 0 : eventToHandle.key) === " ") {
276
149
  eventToHandle == null ? void 0 : eventToHandle.preventDefault();
277
- onClick();
150
+ onClick == null ? void 0 : onClick(event);
278
151
  }
279
152
  };
280
153
  const renderArbitrage = (value) => {
281
154
  if (value == null)
282
155
  return null;
283
- if (Math.abs(value) < config.arbitrageThreshold)
156
+ if (Math.abs(value) < config.market.arbitrageThreshold)
284
157
  return null;
285
158
  return /* @__PURE__ */ jsxs("div", { className: cn("flex items-center gap-1", "text-agg-success"), children: [
286
- /* @__PURE__ */ jsx(Typography, { variant: "label-strong", className: "text-agg-success", children: config.formatPercent(value) }),
159
+ /* @__PURE__ */ jsx(Typography, { variant: "label-strong", className: "text-agg-success", children: config.formatting.formatPercent(value) }),
287
160
  /* @__PURE__ */ jsx(
288
161
  Icon,
289
162
  {
@@ -301,7 +174,7 @@ var EventListItemContent = ({
301
174
  className: cn(baseCardClassName, onClick && "cursor-pointer", classNames == null ? void 0 : classNames.root),
302
175
  role: onClick ? "button" : void 0,
303
176
  tabIndex: onClick ? 0 : void 0,
304
- onClick,
177
+ onClick: () => onClick == null ? void 0 : onClick(event),
305
178
  onKeyDown: handleKeyDown,
306
179
  "aria-label": ariaLabel != null ? ariaLabel : resolvedTitle,
307
180
  children: [
@@ -354,8 +227,8 @@ var EventListItemContent = ({
354
227
  showBadge ? /* @__PURE__ */ jsx(
355
228
  Badge,
356
229
  {
357
- text: config.formatPercent(probability),
358
- prefix: showVenueLogo ? /* @__PURE__ */ jsx(VenueLogo, { venue: visibleOutcome.venue, size: "small" }) : void 0,
230
+ text: config.formatting.formatPercent(probability),
231
+ prefix: /* @__PURE__ */ jsx(VenueLogo, { venue: visibleOutcome.venue, size: "small" }),
359
232
  size: "large",
360
233
  classNames: {
361
234
  root: cn(
@@ -388,7 +261,7 @@ var EventListItemContent = ({
388
261
  ) }),
389
262
  /* @__PURE__ */ jsx("span", { className: "text-agg-muted-foreground", children: "\xD7" }),
390
263
  singleVenue ? /* @__PURE__ */ jsxs("span", { className: "flex items-center gap-1 truncate text-agg-muted-foreground", children: [
391
- showVenueLogo ? /* @__PURE__ */ jsx(
264
+ /* @__PURE__ */ jsx(
392
265
  VenueLogo,
393
266
  {
394
267
  venue: singleVenue,
@@ -396,14 +269,14 @@ var EventListItemContent = ({
396
269
  isMonochromatic: true,
397
270
  className: "text-agg-muted-foreground!"
398
271
  }
399
- ) : null,
272
+ ),
400
273
  /* @__PURE__ */ jsx("span", { children: venueLabel })
401
274
  ] }) : /* @__PURE__ */ jsx("span", { className: "truncate text-agg-muted-foreground", children: formatCountLabel(
402
275
  venueCount,
403
276
  labels.eventItem.venueSingular,
404
277
  labels.eventItem.venuePlural
405
278
  ) }),
406
- showVenueLogo && !singleVenue && visibleVenueLogos.length > 0 ? /* @__PURE__ */ jsx("span", { className: "flex items-center gap-1 overflow-hidden", children: visibleVenueLogos.map((venue) => /* @__PURE__ */ jsx(
279
+ !singleVenue && visibleVenueLogos.length > 0 ? /* @__PURE__ */ jsx("span", { className: "flex items-center gap-1 overflow-hidden", children: visibleVenueLogos.map((venue) => /* @__PURE__ */ jsx(
407
280
  VenueLogo,
408
281
  {
409
282
  venue,
@@ -471,7 +344,13 @@ EventListItem.displayName = "EventListItem";
471
344
 
472
345
  // src/events/item-details/index.tsx
473
346
  import { useEffect, useMemo as useMemo3, useState } from "react";
474
- import { useLabels as useLabels3, usePriceHistory, useSdkUiConfig as useSdkUiConfig2, useVenueEvent as useVenueEvent2 } from "@agg-market/hooks";
347
+ import {
348
+ useLabels as useLabels3,
349
+ useMarketChart,
350
+ useSdkUiConfig as useSdkUiConfig2,
351
+ useVenueEvent as useVenueEvent2,
352
+ timeRangeToInterval
353
+ } from "@agg-market/hooks";
475
354
 
476
355
  // src/primitives/chart/chart-type-switch.tsx
477
356
  import { useLabels as useLabels2 } from "@agg-market/hooks";
@@ -534,7 +413,9 @@ var ChartTypeSwitch = ({
534
413
  "transition-colors duration-200 ease-in-out",
535
414
  isActive ? "text-agg-foreground" : "text-agg-muted-foreground"
536
415
  ),
537
- onClick: () => {
416
+ onClick: (e) => {
417
+ e.stopPropagation();
418
+ e.preventDefault();
538
419
  if (isActive) {
539
420
  return;
540
421
  }
@@ -563,14 +444,9 @@ var isDateLikeLabel = (value) => {
563
444
  return false;
564
445
  return dayjs2(value).isValid();
565
446
  };
566
- var formatDateLabel = (value) => {
567
- if (!isDateLikeLabel(value))
568
- return value;
569
- return dayjs2(value).format("MMM D, YYYY");
570
- };
571
- var getDefaultSelectedTimeRange = (value) => {
447
+ var getDefaultSelectedTimeRange = (value, fallback = "1D") => {
572
448
  if (!value)
573
- return "1M";
449
+ return fallback;
574
450
  return value;
575
451
  };
576
452
  var getTimeWindowByRange = (range) => {
@@ -652,24 +528,6 @@ var resolveOutcomesByVenue = (venueMarkets, selectedOutcomeLabel) => {
652
528
  };
653
529
  }).filter((item) => item != null);
654
530
  };
655
- var buildPriceHistoryGroups = (selectedOutcomes, fallbackMarketId) => {
656
- const marketIdByVenue = /* @__PURE__ */ new Map();
657
- selectedOutcomes.forEach(({ venue, market }) => {
658
- var _a, _b;
659
- const marketWithCanonicalId = market;
660
- const canonicalMarketId = (_a = marketWithCanonicalId.marketId) != null ? _a : fallbackMarketId;
661
- if (!canonicalMarketId)
662
- return;
663
- if (!marketIdByVenue.has(venue)) {
664
- marketIdByVenue.set(venue, /* @__PURE__ */ new Set());
665
- }
666
- (_b = marketIdByVenue.get(venue)) == null ? void 0 : _b.add(canonicalMarketId);
667
- });
668
- return [...marketIdByVenue.entries()].map(([venue, marketIds]) => ({
669
- venue,
670
- venueMarketOutcomeIds: [...marketIds]
671
- })).filter((group) => group.venueMarketOutcomeIds.length > 0);
672
- };
673
531
  var resolveSeriesColor = (venue, index) => {
674
532
  var _a;
675
533
  const colorFromVenue = lineColorByVenue[venue];
@@ -677,6 +535,98 @@ var resolveSeriesColor = (venue, index) => {
677
535
  return colorFromVenue;
678
536
  return (_a = fallbackLineColors[index % fallbackLineColors.length]) != null ? _a : "#2e5cff";
679
537
  };
538
+ var toNonEmptyString = (value) => {
539
+ if (typeof value !== "string")
540
+ return void 0;
541
+ const trimmedValue = value.trim();
542
+ return trimmedValue ? trimmedValue : void 0;
543
+ };
544
+ var resolveCanonicalMarketId = (venueMarkets, fallbackMarketId) => {
545
+ var _a;
546
+ const uniqueMarketIds = Array.from(
547
+ new Set(venueMarkets.map((market) => toNonEmptyString(market.marketId)).filter(Boolean))
548
+ );
549
+ if (uniqueMarketIds.length === 1) {
550
+ return uniqueMarketIds[0];
551
+ }
552
+ return (_a = toNonEmptyString(fallbackMarketId)) != null ? _a : uniqueMarketIds[0];
553
+ };
554
+ var toChartDisplayValue = (value, transformProbability) => {
555
+ if (value == null || !Number.isFinite(value))
556
+ return void 0;
557
+ return transformProbability(value) * 100;
558
+ };
559
+ var marketChartCandleToLineChartPoint = (candle, transformProbability) => {
560
+ var _a, _b, _c, _d;
561
+ const open = (_a = toChartDisplayValue(candle.open, transformProbability)) != null ? _a : 0;
562
+ const high = (_b = toChartDisplayValue(candle.high, transformProbability)) != null ? _b : open;
563
+ const low = (_c = toChartDisplayValue(candle.low, transformProbability)) != null ? _c : open;
564
+ const close = (_d = toChartDisplayValue(candle.close, transformProbability)) != null ? _d : open;
565
+ return {
566
+ time: candle.time,
567
+ value: close,
568
+ open,
569
+ high,
570
+ low,
571
+ close
572
+ };
573
+ };
574
+ var marketChartCandleToScaledCandlePoint = (candle, transformProbability) => {
575
+ var _a, _b, _c, _d;
576
+ const point = marketChartCandleToLineChartPoint(candle, transformProbability);
577
+ return {
578
+ time: point.time,
579
+ open: (_a = point.open) != null ? _a : point.value,
580
+ high: (_b = point.high) != null ? _b : point.value,
581
+ low: (_c = point.low) != null ? _c : point.value,
582
+ close: (_d = point.close) != null ? _d : point.value,
583
+ v: candle.volume
584
+ };
585
+ };
586
+ var resolveMarketChartVenueSeries = ({
587
+ chartData,
588
+ transformProbability
589
+ }) => {
590
+ if (!chartData)
591
+ return [];
592
+ return Object.entries(chartData.venues).map(([venue, venueData]) => ({
593
+ venue,
594
+ points: venueData.candles.map(
595
+ (candle) => marketChartCandleToLineChartPoint(candle, transformProbability)
596
+ )
597
+ })).filter((item) => item.points.length > 0);
598
+ };
599
+ var resolveMarketChartLiveState = ({
600
+ chartData,
601
+ selectedVenue,
602
+ transformProbability
603
+ }) => {
604
+ var _a, _b;
605
+ if (!chartData) {
606
+ return {
607
+ liveCandle: null,
608
+ lineValue: void 0,
609
+ live: false
610
+ };
611
+ }
612
+ const venueEntries = selectedVenue ? Object.entries(chartData.venues).filter(([venue]) => venue === selectedVenue) : Object.entries(chartData.venues);
613
+ if (venueEntries.length === 0) {
614
+ return {
615
+ liveCandle: null,
616
+ lineValue: void 0,
617
+ live: false
618
+ };
619
+ }
620
+ const singleVenueView = selectedVenue != null || venueEntries.length === 1;
621
+ const liveCandleEntry = singleVenueView ? venueEntries.find(([, venueData]) => venueData.liveCandle != null) : null;
622
+ const primaryLineValue = (_b = (_a = venueEntries[0]) == null ? void 0 : _a[1]) == null ? void 0 : _b.lineValue;
623
+ const lineValue = primaryLineValue != null ? toChartDisplayValue(primaryLineValue, transformProbability) : void 0;
624
+ return {
625
+ liveCandle: (liveCandleEntry == null ? void 0 : liveCandleEntry[1].liveCandle) ? marketChartCandleToScaledCandlePoint(liveCandleEntry[1].liveCandle, transformProbability) : null,
626
+ lineValue,
627
+ live: liveCandleEntry != null
628
+ };
629
+ };
680
630
 
681
631
  // src/events/item-details/index.tsx
682
632
  import { jsx as jsx3, jsxs as jsxs2 } from "react/jsx-runtime";
@@ -741,31 +691,25 @@ var resolveAverageProbability = (values) => {
741
691
  return void 0;
742
692
  return validValues.reduce((sum, value) => sum + value, 0) / validValues.length;
743
693
  };
744
- var resolveOutcomeCandidateIds = (market, outcome) => {
745
- var _a, _b;
746
- const marketWithCanonicalId = market;
747
- return [
748
- outcome.id,
749
- (_a = outcome.externalIdentifier) != null ? _a : void 0,
750
- market.externalIdentifier,
751
- (_b = marketWithCanonicalId.marketId) != null ? _b : void 0
752
- ].filter((value) => typeof value === "string" && value.trim().length > 0);
753
- };
754
694
  var EventListItemDetailsGraphSection = ({
755
695
  venueMarkets,
756
- canonicalMarketId,
757
696
  selectedOutcomeLabel,
758
697
  onSelectedOutcomeLabelChange,
759
698
  switchLabels,
760
699
  isDateOutcomeMarket,
761
700
  classNames,
762
- showVenueLogo,
763
701
  venueInfo,
764
702
  formatPercent,
765
703
  selectedTimeRange,
766
- selectedChartType
704
+ selectedChartType,
705
+ selectedOutcome: _selectedOutcome,
706
+ selectedMarket
767
707
  }) => {
708
+ var _a, _b;
768
709
  const labels = useLabels3();
710
+ const {
711
+ features: { enableLiveUpdates }
712
+ } = useSdkUiConfig2();
769
713
  const [selectedVenue, setSelectedVenue] = useState(null);
770
714
  const [activeProbabilityMode, setActiveProbabilityMode] = useState("yes");
771
715
  const probabilityModeConfigs = useMemo3(() => {
@@ -834,105 +778,71 @@ var EventListItemDetailsGraphSection = ({
834
778
  no: buildModeData("no")
835
779
  };
836
780
  }, [labels, probabilityModeConfigs, selectedOutcomesByMode, venueInfo]);
837
- const allOutcomesForHistory = useMemo3(() => {
838
- const outcomeByModeAndId = /* @__PURE__ */ new Map();
839
- probabilityModeOrder.forEach((mode) => {
840
- selectedOutcomesByMode[mode].forEach((outcomeByVenue) => {
841
- outcomeByModeAndId.set(
842
- `${outcomeByVenue.venue}:${outcomeByVenue.outcome.id}`,
843
- outcomeByVenue
844
- );
845
- });
846
- });
847
- return [...outcomeByModeAndId.values()];
848
- }, [selectedOutcomesByMode]);
849
- const priceHistoryGroups = useMemo3(() => {
850
- return buildPriceHistoryGroups(allOutcomesForHistory, canonicalMarketId);
851
- }, [allOutcomesForHistory, canonicalMarketId]);
852
781
  const timeWindow = useMemo3(() => {
853
782
  return getTimeWindowByRange(selectedTimeRange);
854
783
  }, [selectedTimeRange]);
784
+ const activeOutcomes = selectedOutcomesByMode[activeProbabilityMode];
785
+ const activeCanonicalMarketId = useMemo3(() => {
786
+ return resolveCanonicalMarketId(activeOutcomes.map((item) => item.market));
787
+ }, [activeOutcomes]);
788
+ const venueMarketIds = useMemo3(() => {
789
+ return activeOutcomes.map((item) => item.market.id);
790
+ }, [activeOutcomes]);
855
791
  const {
856
- data: priceHistoryData,
857
- isLoading: isPriceHistoryLoading,
858
- error: priceHistoryError,
859
- results: priceHistoryResults
860
- } = usePriceHistory(__spreadProps(__spreadValues({
861
- groups: priceHistoryGroups
862
- }, timeWindow), {
863
- enabled: priceHistoryGroups.length > 0
864
- }));
865
- const priceHistoryByVenue = useMemo3(() => {
866
- const historyByVenue = /* @__PURE__ */ new Map();
867
- if (!(priceHistoryData == null ? void 0 : priceHistoryData.length)) {
868
- return historyByVenue;
869
- }
870
- priceHistoryData.forEach((historyItem) => {
871
- const venue = historyItem.venue;
872
- const venueHistory = historyByVenue.get(venue);
873
- if (venueHistory) {
874
- venueHistory.push(historyItem);
875
- return;
876
- }
877
- historyByVenue.set(venue, [historyItem]);
878
- });
879
- return historyByVenue;
880
- }, [priceHistoryData]);
881
- const chartSeriesByMode = useMemo3(() => {
882
- const buildSeries = (mode) => {
883
- const modeConfig = probabilityModeConfigs[mode];
884
- const chartSeries = [];
885
- normalizedVenueDataByMode[mode].forEach((venueData) => {
886
- var _a;
887
- const venueHistory = priceHistoryByVenue.get(venueData.venue);
888
- if (!(venueHistory == null ? void 0 : venueHistory.length))
889
- return;
890
- const candidateIds = resolveOutcomeCandidateIds(venueData.market, venueData.outcome);
891
- const matchingHistory = (_a = venueHistory.find((historyItem) => candidateIds.includes(historyItem.marketId))) != null ? _a : venueHistory.length === 1 ? venueHistory[0] : void 0;
892
- if (!matchingHistory)
893
- return;
894
- const points = matchingHistory.points.map((point) => {
895
- const probability = normalizeProbability(point.price);
896
- if (probability == null || !Number.isFinite(point.timestamp))
897
- return null;
898
- const open = normalizeProbability(point.open);
899
- const high = normalizeProbability(point.high);
900
- const low = normalizeProbability(point.low);
901
- const close = normalizeProbability(point.close);
902
- const transformedPoint = {
903
- time: point.timestamp,
904
- value: clampProbability(modeConfig.transformProbability(probability)) * 100,
905
- open: open == null ? void 0 : clampProbability(modeConfig.transformProbability(open)) * 100,
906
- high: high == null ? void 0 : clampProbability(modeConfig.transformProbability(high)) * 100,
907
- low: low == null ? void 0 : clampProbability(modeConfig.transformProbability(low)) * 100,
908
- close: close == null ? void 0 : clampProbability(modeConfig.transformProbability(close)) * 100
909
- };
910
- return transformedPoint;
911
- }).filter((point) => point != null);
912
- if (points.length === 0)
913
- return;
914
- chartSeries.push({
915
- id: `${mode}-${venueData.venue}-${matchingHistory.marketId}`,
916
- venue: venueData.venue,
917
- color: venueData.color,
918
- points,
919
- lineWidth: 2,
920
- lineStyle: "solid"
921
- });
922
- });
923
- return chartSeries;
924
- };
925
- return {
926
- yes: buildSeries("yes"),
927
- no: buildSeries("no")
928
- };
929
- }, [normalizedVenueDataByMode, priceHistoryByVenue, probabilityModeConfigs]);
792
+ data: marketChartData,
793
+ isLoading: isMarketChartLoading,
794
+ error: marketChartError,
795
+ refetch: refetchMarketChart
796
+ } = useMarketChart({
797
+ marketId: (_a = selectedMarket == null ? void 0 : selectedMarket.id) != null ? _a : null,
798
+ venueMarketIds,
799
+ interval: timeRangeToInterval(selectedTimeRange),
800
+ startTs: timeWindow.startTs * 1e3,
801
+ endTs: timeWindow.endTs * 1e3,
802
+ enabled: !!(selectedMarket == null ? void 0 : selectedMarket.id),
803
+ live: enableLiveUpdates
804
+ });
930
805
  const visibleChartSeries = useMemo3(() => {
931
- const modeSeries = chartSeriesByMode[activeProbabilityMode];
806
+ const transformProbability = probabilityModeConfigs[activeProbabilityMode].transformProbability;
807
+ const colorByVenue = new Map(
808
+ normalizedVenueDataByMode[activeProbabilityMode].map((venueData) => [
809
+ venueData.venue,
810
+ venueData.color
811
+ ])
812
+ );
813
+ const series = resolveMarketChartVenueSeries({
814
+ chartData: marketChartData,
815
+ transformProbability
816
+ }).map((seriesItem) => {
817
+ var _a2;
818
+ const resolvedVenue = seriesItem.venue;
819
+ return {
820
+ id: `${activeProbabilityMode}-${resolvedVenue}-${activeCanonicalMarketId != null ? activeCanonicalMarketId : "chart"}`,
821
+ venue: resolvedVenue,
822
+ color: (_a2 = colorByVenue.get(resolvedVenue)) != null ? _a2 : resolveSeriesColor(resolvedVenue, 0),
823
+ points: seriesItem.points,
824
+ lineWidth: 2,
825
+ lineStyle: "solid"
826
+ };
827
+ });
932
828
  if (!selectedVenue)
933
- return modeSeries;
934
- return modeSeries.filter((seriesItem) => seriesItem.venue === selectedVenue);
935
- }, [activeProbabilityMode, chartSeriesByMode, selectedVenue]);
829
+ return series;
830
+ return series.filter((seriesItem) => seriesItem.venue === selectedVenue);
831
+ }, [
832
+ activeCanonicalMarketId,
833
+ activeProbabilityMode,
834
+ marketChartData,
835
+ normalizedVenueDataByMode,
836
+ probabilityModeConfigs,
837
+ selectedVenue
838
+ ]);
839
+ const chartLiveState = useMemo3(() => {
840
+ return resolveMarketChartLiveState({
841
+ chartData: marketChartData,
842
+ selectedVenue,
843
+ transformProbability: probabilityModeConfigs[activeProbabilityMode].transformProbability
844
+ });
845
+ }, [activeProbabilityMode, marketChartData, probabilityModeConfigs, selectedVenue]);
936
846
  const segmentedDisplayItems = useMemo3(() => {
937
847
  return probabilityModeOrder.map((mode) => {
938
848
  const averageProbability = resolveAverageProbability(
@@ -970,31 +880,22 @@ var EventListItemDetailsGraphSection = ({
970
880
  return venue;
971
881
  });
972
882
  };
973
- const handleRetryPriceHistory = () => {
974
- void Promise.all(priceHistoryResults.map((result) => result.refetch()));
883
+ const handleRetryMarketChart = () => {
884
+ void refetchMarketChart();
975
885
  };
976
- if (priceHistoryError) {
977
- return /* @__PURE__ */ jsx3(
978
- "div",
886
+ if (marketChartError) {
887
+ return /* @__PURE__ */ jsx3("div", { className: cn("w-full", classNames == null ? void 0 : classNames.chart), children: /* @__PURE__ */ jsx3(
888
+ StateMessage,
979
889
  {
980
- className: cn(
981
- "w-full rounded-agg-xl border border-agg-separator bg-agg-secondary",
982
- classNames == null ? void 0 : classNames.chart
983
- ),
984
- children: /* @__PURE__ */ jsx3(
985
- StateMessage,
986
- {
987
- ariaLabel: labels.eventItemDetails.chartUnavailableAria,
988
- tone: "warning",
989
- title: labels.eventItemDetails.chartUnavailableTitle,
990
- description: labels.eventItemDetails.chartUnavailableDescription,
991
- actionLabel: labels.common.retry,
992
- onAction: handleRetryPriceHistory,
993
- className: "min-h-[300px] px-5 py-10 md:px-10"
994
- }
995
- )
890
+ tone: "warning",
891
+ ariaLabel: labels.eventItemDetails.chartUnavailableAria,
892
+ title: labels.eventItemDetails.chartUnavailableTitle,
893
+ description: labels.eventItemDetails.chartUnavailableDescription,
894
+ actionLabel: labels.common.retry,
895
+ onAction: handleRetryMarketChart,
896
+ className: "min-h-[300px] px-5 py-10 md:px-10"
996
897
  }
997
- );
898
+ ) });
998
899
  }
999
900
  return /* @__PURE__ */ jsx3(
1000
901
  LineChart,
@@ -1002,8 +903,10 @@ var EventListItemDetailsGraphSection = ({
1002
903
  classNames: { root: classNames == null ? void 0 : classNames.chart },
1003
904
  series: visibleChartSeries,
1004
905
  height: 300,
1005
- isLoading: isPriceHistoryLoading,
906
+ isLoading: isMarketChartLoading,
1006
907
  chartType: selectedChartType,
908
+ liveCandle: selectedChartType === "candlestick" ? (_b = chartLiveState.liveCandle) != null ? _b : void 0 : void 0,
909
+ lineValue: chartLiveState.lineValue,
1007
910
  showSeriesControls: activeModeVenueData.length > 0 || segmentedDisplayItems.length > 0,
1008
911
  renderSeriesControls: () => {
1009
912
  return /* @__PURE__ */ jsxs2(
@@ -1019,7 +922,7 @@ var EventListItemDetailsGraphSection = ({
1019
922
  classNames == null ? void 0 : classNames.outcomeBadges
1020
923
  ),
1021
924
  children: activeModeVenueData.map((venueData) => {
1022
- var _a;
925
+ var _a2;
1023
926
  const text = venueData.probability == null ? "-" : formatPercent(venueData.probability);
1024
927
  const isActiveVenue = selectedVenue === venueData.venue;
1025
928
  return /* @__PURE__ */ jsx3(
@@ -1036,14 +939,14 @@ var EventListItemDetailsGraphSection = ({
1036
939
  {
1037
940
  text,
1038
941
  size: "large",
1039
- prefix: showVenueLogo ? /* @__PURE__ */ jsx3(
942
+ prefix: /* @__PURE__ */ jsx3(
1040
943
  VenueLogo,
1041
944
  {
1042
945
  venue: venueData.venue,
1043
946
  size: "small",
1044
- title: (_a = venueInfo == null ? void 0 : venueInfo[venueData.venue]) == null ? void 0 : _a.label
947
+ title: (_a2 = venueInfo == null ? void 0 : venueInfo[venueData.venue]) == null ? void 0 : _a2.label
1045
948
  }
1046
- ) : void 0,
949
+ ),
1047
950
  classNames: {
1048
951
  root: cn("h-9 shrink-0 border-2 px-4 text-agg-base leading-agg-6")
1049
952
  },
@@ -1084,45 +987,55 @@ var EventListItemDetailsGraphSection = ({
1084
987
  };
1085
988
  var EventListItemDetailsContent = ({
1086
989
  event,
1087
- title,
1088
- image,
1089
- showVenueLogo = true,
1090
990
  classNames,
1091
991
  venueInfo,
1092
992
  detailsStats,
1093
993
  ariaLabel,
1094
- defaultTimeRange
994
+ defaultTimeRange,
995
+ onClick
1095
996
  }) => {
997
+ var _a;
1096
998
  const config = useSdkUiConfig2();
1097
999
  const labels = useLabels3();
1098
1000
  const venueMarkets = useMemo3(() => {
1099
- var _a;
1100
- return (_a = event.venueMarkets) != null ? _a : [];
1001
+ var _a2;
1002
+ return (_a2 = event.venueMarkets) != null ? _a2 : [];
1101
1003
  }, [event.venueMarkets]);
1004
+ const [selectedMarket, setSelectedMarket] = useState(venueMarkets[0]);
1005
+ const [selectedOutcome] = useState(
1006
+ (_a = selectedMarket == null ? void 0 : selectedMarket.venueMarketOutcomes.find(
1007
+ (outcome) => outcome.winner
1008
+ )) != null ? _a : selectedMarket == null ? void 0 : selectedMarket.venueMarketOutcomes[0]
1009
+ );
1102
1010
  const primaryVenueMarket = useMemo3(() => {
1103
1011
  return selectPrimaryVenueMarket(venueMarkets);
1104
1012
  }, [venueMarkets]);
1013
+ const filteredVenueMarkets = useMemo3(() => {
1014
+ if (!selectedMarket)
1015
+ return venueMarkets;
1016
+ return venueMarkets.filter(
1017
+ (vm) => vm.question === (selectedMarket == null ? void 0 : selectedMarket.question)
1018
+ );
1019
+ }, [venueMarkets, selectedMarket]);
1105
1020
  const outcomeLabels = useMemo3(() => {
1106
- return resolveOutcomeLabels(venueMarkets);
1107
- }, [venueMarkets]);
1021
+ return resolveOutcomeLabels(filteredVenueMarkets);
1022
+ }, [filteredVenueMarkets]);
1108
1023
  const [selectedOutcomeLabel, setSelectedOutcomeLabel] = useState(() => {
1109
1024
  return resolveDefaultOutcomeLabel(outcomeLabels);
1110
1025
  });
1026
+ const configTimeRange = config.chart.defaultChartTimeRange;
1111
1027
  const [selectedTimeRange, setSelectedTimeRange] = useState(() => {
1112
- return getDefaultSelectedTimeRange(defaultTimeRange);
1028
+ return getDefaultSelectedTimeRange(defaultTimeRange, configTimeRange);
1113
1029
  });
1114
1030
  const [selectedChartType, setSelectedChartType] = useState("line");
1115
1031
  useEffect(() => {
1116
- setSelectedTimeRange(getDefaultSelectedTimeRange(defaultTimeRange));
1117
- }, [defaultTimeRange]);
1118
- const resolvedTitle = resolveTileTitle(event, primaryVenueMarket, title);
1119
- const resolvedImage = resolveTileImage(event, primaryVenueMarket, image);
1032
+ setSelectedTimeRange(getDefaultSelectedTimeRange(defaultTimeRange, configTimeRange));
1033
+ }, [defaultTimeRange, configTimeRange]);
1120
1034
  const isDateOutcomeMarket = outcomeLabels.length > 2 && outcomeLabels.every(isDateLikeLabel);
1121
- const outcomeSelectorLabels = outcomeLabels;
1122
1035
  const probabilityByLabel = useMemo3(() => {
1123
1036
  return new Map(
1124
1037
  outcomeLabels.map((label) => {
1125
- const outcomesByVenue = resolveOutcomesByVenue(venueMarkets, label);
1038
+ const outcomesByVenue = resolveOutcomesByVenue(filteredVenueMarkets, label);
1126
1039
  const probabilities = outcomesByVenue.map((item) => normalizeProbability(item.outcome.price)).filter((value) => value != null);
1127
1040
  if (probabilities.length === 0) {
1128
1041
  return [label, void 0];
@@ -1131,13 +1044,13 @@ var EventListItemDetailsContent = ({
1131
1044
  return [label, averageProbability];
1132
1045
  })
1133
1046
  );
1134
- }, [outcomeLabels, venueMarkets]);
1047
+ }, [outcomeLabels, filteredVenueMarkets]);
1135
1048
  const mainOutcomeLabel = useMemo3(() => {
1136
1049
  if (outcomeLabels.length === 0)
1137
1050
  return void 0;
1138
1051
  return [...outcomeLabels].sort((left, right) => {
1139
- var _a, _b;
1140
- const leftProbability = (_a = probabilityByLabel.get(left)) != null ? _a : -1;
1052
+ var _a2, _b;
1053
+ const leftProbability = (_a2 = probabilityByLabel.get(left)) != null ? _a2 : -1;
1141
1054
  const rightProbability = (_b = probabilityByLabel.get(right)) != null ? _b : -1;
1142
1055
  return rightProbability - leftProbability;
1143
1056
  })[0];
@@ -1154,17 +1067,17 @@ var EventListItemDetailsContent = ({
1154
1067
  setSelectedOutcomeLabel(fallbackOutcomeLabel);
1155
1068
  }, [isDateOutcomeMarket, mainOutcomeLabel, outcomeLabels, selectedOutcomeLabel]);
1156
1069
  const switchLabels = useMemo3(() => {
1157
- var _a, _b;
1070
+ var _a2, _b;
1158
1071
  if (isDateOutcomeMarket) {
1159
1072
  return [labels.eventItemDetails.yes, labels.eventItemDetails.no];
1160
1073
  }
1161
1074
  const sortedOutcomeLabels = [...outcomeLabels].sort((left, right) => {
1162
- var _a2, _b2;
1163
- const leftProbability = (_a2 = probabilityByLabel.get(left)) != null ? _a2 : -1;
1075
+ var _a3, _b2;
1076
+ const leftProbability = (_a3 = probabilityByLabel.get(left)) != null ? _a3 : -1;
1164
1077
  const rightProbability = (_b2 = probabilityByLabel.get(right)) != null ? _b2 : -1;
1165
1078
  return rightProbability - leftProbability;
1166
1079
  });
1167
- const firstLabel = (_a = sortedOutcomeLabels[0]) != null ? _a : labels.eventItemDetails.yes;
1080
+ const firstLabel = (_a2 = sortedOutcomeLabels[0]) != null ? _a2 : labels.eventItemDetails.yes;
1168
1081
  const secondLabel = (_b = sortedOutcomeLabels.find((label) => label !== firstLabel)) != null ? _b : firstLabel;
1169
1082
  return [firstLabel, secondLabel];
1170
1083
  }, [
@@ -1175,34 +1088,44 @@ var EventListItemDetailsContent = ({
1175
1088
  probabilityByLabel
1176
1089
  ]);
1177
1090
  const volumeLabel = useMemo3(() => {
1178
- var _a;
1179
- const resolvedVolume = typeof event.volume === "number" ? event.volume : (_a = primaryVenueMarket == null ? void 0 : primaryVenueMarket.volume) != null ? _a : void 0;
1091
+ var _a2;
1092
+ const resolvedVolume = typeof event.volume === "number" ? event.volume : (_a2 = primaryVenueMarket == null ? void 0 : primaryVenueMarket.volume) != null ? _a2 : void 0;
1180
1093
  if (typeof resolvedVolume !== "number")
1181
1094
  return "";
1182
- return `${config.formatCompactCurrency(resolvedVolume)} ${labels.eventItemDetails.volumeSuffix}`;
1095
+ return `${config.formatting.formatCompactCurrency(resolvedVolume)} ${labels.eventItemDetails.volumeSuffix}`;
1183
1096
  }, [config, event.volume, labels.eventItemDetails.volumeSuffix, primaryVenueMarket == null ? void 0 : primaryVenueMarket.volume]);
1184
1097
  if (!primaryVenueMarket || !selectedOutcomeLabel) {
1185
- return /* @__PURE__ */ jsx3(EventListItemDetailsUnavailableState, { classNames, ariaLabel });
1098
+ return /* @__PURE__ */ jsx3(
1099
+ EventListItemDetailsUnavailableState,
1100
+ {
1101
+ classNames,
1102
+ ariaLabel: ariaLabel != null ? ariaLabel : event.title
1103
+ }
1104
+ );
1186
1105
  }
1187
1106
  return /* @__PURE__ */ jsxs2(
1188
1107
  Card,
1189
1108
  {
1190
1109
  className: cn(detailsBaseCardClassName, classNames == null ? void 0 : classNames.root),
1191
- "aria-label": ariaLabel != null ? ariaLabel : resolvedTitle,
1110
+ "aria-label": ariaLabel != null ? ariaLabel : event.title,
1111
+ onClick: () => {
1112
+ onClick == null ? void 0 : onClick(event);
1113
+ },
1192
1114
  children: [
1193
1115
  /* @__PURE__ */ jsxs2(
1194
1116
  "div",
1195
1117
  {
1196
1118
  className: cn(
1197
1119
  "flex flex-row gap-3 md:gap-4",
1198
- "items-center justify-start",
1120
+ venueMarkets.length > 1 ? "items-start" : "items-center",
1121
+ "justify-start",
1199
1122
  classNames == null ? void 0 : classNames.header
1200
1123
  ),
1201
1124
  children: [
1202
- resolvedImage ? /* @__PURE__ */ jsx3(
1125
+ event.image ? /* @__PURE__ */ jsx3(
1203
1126
  RemoteImage,
1204
1127
  {
1205
- src: resolvedImage,
1128
+ src: event.image,
1206
1129
  alt: "",
1207
1130
  className: "size-10 rounded-agg-lg object-cover md:size-[60px]"
1208
1131
  }
@@ -1217,19 +1140,18 @@ var EventListItemDetailsContent = ({
1217
1140
  "truncate text-wrap wrap-break-word line-clamp-2",
1218
1141
  classNames == null ? void 0 : classNames.title
1219
1142
  ),
1220
- children: resolvedTitle
1143
+ children: event.title
1221
1144
  }
1222
1145
  ),
1223
- outcomeSelectorLabels.length > 2 ? /* @__PURE__ */ jsx3(
1146
+ venueMarkets.length > 1 ? /* @__PURE__ */ jsx3(
1224
1147
  "div",
1225
1148
  {
1226
1149
  className: cn(
1227
- "flex items-center gap-2 overflow-x-auto pb-1 md:flex-wrap md:overflow-visible md:pb-0",
1150
+ "flex flex-row flex-nowrap items-center gap-2 overflow-x-auto pb-1 md:pb-0",
1228
1151
  classNames == null ? void 0 : classNames.headerPills
1229
1152
  ),
1230
- children: outcomeSelectorLabels.map((outcomeSelectorLabel) => {
1231
- const isActive = outcomeSelectorLabel === selectedOutcomeLabel;
1232
- const displayLabel = isDateLikeLabel(outcomeSelectorLabel) ? formatDateLabel(outcomeSelectorLabel) : outcomeSelectorLabel;
1153
+ children: venueMarkets.map((venueMarket) => {
1154
+ const isActive = (selectedMarket == null ? void 0 : selectedMarket.id) === venueMarket.id;
1233
1155
  return /* @__PURE__ */ jsx3(
1234
1156
  Button,
1235
1157
  {
@@ -1241,10 +1163,14 @@ var EventListItemDetailsContent = ({
1241
1163
  "border-2",
1242
1164
  isActive ? "border-agg-primary bg-agg-secondary text-agg-foreground font-agg-bold" : "border-transparent bg-agg-secondary-hover text-agg-foreground font-agg-normal"
1243
1165
  ),
1244
- onClick: () => setSelectedOutcomeLabel(outcomeSelectorLabel),
1245
- children: displayLabel
1166
+ onClick: (e) => {
1167
+ e.stopPropagation();
1168
+ e.preventDefault();
1169
+ setSelectedMarket(venueMarket);
1170
+ },
1171
+ children: venueMarket.question
1246
1172
  },
1247
- outcomeSelectorLabel
1173
+ venueMarket.id
1248
1174
  );
1249
1175
  })
1250
1176
  }
@@ -1273,16 +1199,16 @@ var EventListItemDetailsContent = ({
1273
1199
  /* @__PURE__ */ jsx3(
1274
1200
  EventListItemDetailsGraphSection,
1275
1201
  {
1276
- venueMarkets,
1277
- canonicalMarketId: event.id,
1202
+ selectedOutcome,
1203
+ selectedMarket,
1204
+ venueMarkets: filteredVenueMarkets,
1278
1205
  selectedOutcomeLabel,
1279
1206
  onSelectedOutcomeLabelChange: setSelectedOutcomeLabel,
1280
1207
  switchLabels,
1281
1208
  isDateOutcomeMarket,
1282
1209
  classNames,
1283
- showVenueLogo,
1284
1210
  venueInfo,
1285
- formatPercent: config.formatPercent,
1211
+ formatPercent: config.formatting.formatPercent,
1286
1212
  selectedTimeRange,
1287
1213
  selectedChartType
1288
1214
  }
@@ -1306,7 +1232,11 @@ var EventListItemDetailsContent = ({
1306
1232
  isActive ? "font-agg-bold! text-agg-foreground!" : "font-agg-normal! text-agg-muted-foreground!"
1307
1233
  ),
1308
1234
  "aria-pressed": isActive,
1309
- onClick: () => setSelectedTimeRange(timeRange),
1235
+ onClick: (e) => {
1236
+ e.stopPropagation();
1237
+ e.preventDefault();
1238
+ setSelectedTimeRange(timeRange);
1239
+ },
1310
1240
  children: timeRange === "ALL" ? labels.eventItemDetails.allTimeRange : timeRange
1311
1241
  },
1312
1242
  timeRange
@@ -1324,19 +1254,20 @@ var EventListItemDetailsByEventId = (_a) => {
1324
1254
  } = _b, rest = __objRest(_b, [
1325
1255
  "eventId"
1326
1256
  ]);
1257
+ const resolvedEventId = eventId != null ? eventId : "";
1327
1258
  const {
1328
1259
  event: fetchedEvent,
1329
1260
  error,
1330
1261
  isError,
1331
1262
  isLoading
1332
1263
  } = useVenueEvent2({
1333
- eventId: eventId != null ? eventId : "",
1334
- enabled: !!eventId
1264
+ eventId: resolvedEventId,
1265
+ enabled: !!resolvedEventId
1335
1266
  });
1336
1267
  const resolvedEvent = useMemo3(() => {
1337
1268
  return resolveEventListItemEvent(fetchedEvent);
1338
1269
  }, [fetchedEvent]);
1339
- if (!eventId) {
1270
+ if (!resolvedEventId) {
1340
1271
  return /* @__PURE__ */ jsx3(
1341
1272
  EventListItemDetailsUnavailableState,
1342
1273
  {
@@ -1375,26 +1306,22 @@ var EventListItemDetails = (props) => {
1375
1306
  }
1376
1307
  if ("eventId" in props && typeof props.eventId === "string") {
1377
1308
  const {
1378
- title: titleOverride,
1379
- image: imageOverride,
1380
- showVenueLogo: showVenueLogoOverride,
1381
1309
  classNames,
1382
1310
  venueInfo,
1383
1311
  detailsStats,
1384
1312
  ariaLabel: ariaLabelOverride,
1385
- defaultTimeRange: defaultTimeRangeOverride
1313
+ defaultTimeRange: defaultTimeRangeOverride,
1314
+ onClick
1386
1315
  } = props;
1387
1316
  const byEventIdProps = {
1388
1317
  eventId: props.eventId,
1389
1318
  isLoading: false,
1390
- title: titleOverride,
1391
- image: imageOverride,
1392
- showVenueLogo: showVenueLogoOverride,
1393
1319
  classNames,
1394
1320
  venueInfo,
1395
1321
  detailsStats,
1396
1322
  ariaLabel: ariaLabelOverride,
1397
- defaultTimeRange: defaultTimeRangeOverride
1323
+ defaultTimeRange: defaultTimeRangeOverride,
1324
+ onClick
1398
1325
  };
1399
1326
  return /* @__PURE__ */ jsx3(EventListItemDetailsByEventId, __spreadValues({}, byEventIdProps));
1400
1327
  }
@@ -1412,10 +1339,11 @@ EventListItemDetails.displayName = "EventListItemDetails";
1412
1339
  import { useEffect as useEffect2, useId, useMemo as useMemo4, useState as useState2 } from "react";
1413
1340
  import {
1414
1341
  useLabels as useLabels4,
1415
- useOrderBook,
1416
- usePriceHistory as usePriceHistory2,
1342
+ useMarketChart as useMarketChart2,
1343
+ useMarketOrderbook,
1344
+ useVenueMarkets,
1417
1345
  useSdkUiConfig as useSdkUiConfig3,
1418
- useVenueEvent as useVenueEvent3
1346
+ timeRangeToInterval as timeRangeToInterval2
1419
1347
  } from "@agg-market/hooks";
1420
1348
 
1421
1349
  // src/events/market-details/market-details.utils.ts
@@ -1447,24 +1375,29 @@ var resolveInitialTab = (defaultTab) => {
1447
1375
  return parsedTab.data;
1448
1376
  return "order-book";
1449
1377
  };
1450
- var resolveMarket = (event, marketId) => {
1451
- var _a, _b, _c, _d, _e;
1452
- if (!event.venueMarkets || event.venueMarkets.length === 0)
1378
+ var resolveMarketFromVenueMarkets = (venueMarkets, marketId) => {
1379
+ var _a, _b;
1380
+ if (!venueMarkets || venueMarkets.length === 0)
1453
1381
  return void 0;
1454
1382
  if (!marketId) {
1383
+ const primary = selectPrimaryVenueMarket(venueMarkets);
1384
+ const totalVolume2 = venueMarkets.reduce((sum, vm) => {
1385
+ return sum + (typeof vm.volume === "number" ? vm.volume : 0);
1386
+ }, 0);
1455
1387
  return {
1456
- id: event.id,
1457
- venueMarkets: event.venueMarkets,
1458
- volume: event.volume,
1459
- status: event.status,
1460
- startDate: event.startDate,
1461
- endDate: event.endDate,
1462
- creationDate: event.creationDate,
1463
- question: event.title
1388
+ id: (_a = primary == null ? void 0 : primary.id) != null ? _a : venueMarkets[0].id,
1389
+ venueMarkets,
1390
+ volume: totalVolume2 || (primary == null ? void 0 : primary.volume),
1391
+ status: primary == null ? void 0 : primary.status,
1392
+ startDate: primary == null ? void 0 : primary.startDate,
1393
+ endDate: primary == null ? void 0 : primary.endDate,
1394
+ creationDate: primary == null ? void 0 : primary.creationDate,
1395
+ question: (_b = primary == null ? void 0 : primary.question) != null ? _b : venueMarkets[0].question
1464
1396
  };
1465
1397
  }
1466
- const venueMarkets = event.venueMarkets;
1467
- const matchedVenueMarket = venueMarkets.find((vm) => vm.id === marketId);
1398
+ const matchedVenueMarket = venueMarkets.find(
1399
+ (vm) => vm.id === marketId || vm.externalIdentifier === marketId
1400
+ );
1468
1401
  if (!matchedVenueMarket)
1469
1402
  return void 0;
1470
1403
  const siblingVenueMarkets = venueMarkets.filter(
@@ -1477,11 +1410,11 @@ var resolveMarket = (event, marketId) => {
1477
1410
  id: matchedVenueMarket.id,
1478
1411
  venueMarkets: siblingVenueMarkets,
1479
1412
  volume: totalVolume || matchedVenueMarket.volume,
1480
- status: (_a = matchedVenueMarket.status) != null ? _a : event.status,
1481
- startDate: (_b = matchedVenueMarket.startDate) != null ? _b : event.startDate,
1482
- endDate: (_c = matchedVenueMarket.endDate) != null ? _c : event.endDate,
1483
- creationDate: (_d = matchedVenueMarket.creationDate) != null ? _d : event.creationDate,
1484
- question: (_e = matchedVenueMarket.question) != null ? _e : event.title
1413
+ status: matchedVenueMarket.status,
1414
+ startDate: matchedVenueMarket.startDate,
1415
+ endDate: matchedVenueMarket.endDate,
1416
+ creationDate: matchedVenueMarket.creationDate,
1417
+ question: matchedVenueMarket.question
1485
1418
  };
1486
1419
  };
1487
1420
  var resolveDisplayOutcomeLabels = (labels) => {
@@ -1491,6 +1424,21 @@ var resolveDisplayOutcomeLabels = (labels) => {
1491
1424
  (label) => labels.some((value) => normalizeLabel2(value) === normalizeLabel2(label))
1492
1425
  );
1493
1426
  };
1427
+ var resolveMarketDetailsOutcomeLabels = (venueMarkets) => {
1428
+ var _a;
1429
+ const primaryMarket = selectPrimaryVenueMarket(venueMarkets);
1430
+ const initialLabels = ((_a = primaryMarket == null ? void 0 : primaryMarket.venueMarketOutcomes) != null ? _a : []).map((outcome) => outcome.label.trim()).filter(Boolean);
1431
+ const labels = new Set(initialLabels);
1432
+ venueMarkets.forEach((market) => {
1433
+ sortOutcomes(market.venueMarketOutcomes).forEach((outcome) => {
1434
+ const label = outcome.label.trim();
1435
+ if (!label)
1436
+ return;
1437
+ labels.add(label);
1438
+ });
1439
+ });
1440
+ return [...labels];
1441
+ };
1494
1442
  var resolveInitialOutcomeLabel = (labels, defaultOutcomeLabel) => {
1495
1443
  var _a;
1496
1444
  if (labels.length === 0)
@@ -1542,7 +1490,7 @@ var resolveOutcomeTone = (label, index) => {
1542
1490
  return index === 0 ? "positive" : "negative";
1543
1491
  };
1544
1492
  var resolveHeaderOutcomeItems = (venueMarkets, defaultOutcomeLabel) => {
1545
- const labels = resolveDisplayOutcomeLabels(resolveOutcomeLabels(venueMarkets));
1493
+ const labels = resolveDisplayOutcomeLabels(resolveMarketDetailsOutcomeLabels(venueMarkets));
1546
1494
  const probabilityByLabel = resolveAverageProbabilityByLabel(venueMarkets, labels);
1547
1495
  return labels.slice(0, 2).map((label, index) => {
1548
1496
  var _a;
@@ -1550,7 +1498,8 @@ var resolveHeaderOutcomeItems = (venueMarkets, defaultOutcomeLabel) => {
1550
1498
  label,
1551
1499
  probability: probabilityByLabel.get(label),
1552
1500
  tone: resolveOutcomeTone(label, index),
1553
- isDefault: normalizeLabel2(label) === normalizeLabel2((_a = defaultOutcomeLabel != null ? defaultOutcomeLabel : labels[0]) != null ? _a : "")
1501
+ isDefault: normalizeLabel2(label) === normalizeLabel2((_a = defaultOutcomeLabel != null ? defaultOutcomeLabel : labels[0]) != null ? _a : ""),
1502
+ venue: venueMarkets[0].venue
1554
1503
  };
1555
1504
  });
1556
1505
  };
@@ -1641,30 +1590,32 @@ var resolveOtherTabRows = (market, labels) => {
1641
1590
  return rows;
1642
1591
  };
1643
1592
  var buildMarketDetailsModel = ({
1644
- event,
1593
+ venueMarkets,
1645
1594
  marketId,
1646
1595
  title,
1647
1596
  image,
1648
1597
  formatCompactCurrency,
1649
1598
  labels
1650
1599
  }) => {
1651
- var _a;
1652
- const market = resolveMarket(event, marketId);
1600
+ var _a, _b;
1601
+ const market = resolveMarketFromVenueMarkets(venueMarkets, marketId);
1653
1602
  if (!market)
1654
1603
  return void 0;
1655
1604
  const primaryVenueMarket = selectPrimaryVenueMarket(market.venueMarkets);
1656
1605
  if (!primaryVenueMarket)
1657
1606
  return void 0;
1658
- const resolvedTitle = resolveTileTitle(event, primaryVenueMarket, title);
1659
- const resolvedImage = resolveTileImage(event, primaryVenueMarket, image);
1660
- const resolvedVolume = typeof market.volume === "number" ? market.volume : (_a = primaryVenueMarket.volume) != null ? _a : void 0;
1607
+ const resolvedTitle = (title == null ? void 0 : title.trim()) || primaryVenueMarket.question || market.question;
1608
+ const resolvedImage = (_a = typeof image === "string" && image.trim() ? image : void 0) != null ? _a : typeof primaryVenueMarket.image === "string" && primaryVenueMarket.image.trim() ? primaryVenueMarket.image : void 0;
1609
+ const resolvedVolume = typeof market.volume === "number" ? market.volume : (_b = primaryVenueMarket.volume) != null ? _b : void 0;
1661
1610
  const subtitle = resolveSubtitle({
1662
1611
  venueMarkets: market.venueMarkets,
1663
1612
  volume: resolvedVolume,
1664
1613
  formatCompactCurrency,
1665
1614
  labels
1666
1615
  });
1667
- const outcomeLabels = resolveDisplayOutcomeLabels(resolveOutcomeLabels(market.venueMarkets));
1616
+ const outcomeLabels = resolveDisplayOutcomeLabels(
1617
+ resolveMarketDetailsOutcomeLabels(market.venueMarkets)
1618
+ );
1668
1619
  const probabilityByLabel = resolveAverageProbabilityByLabel(market.venueMarkets, outcomeLabels);
1669
1620
  return {
1670
1621
  market,
@@ -1794,7 +1745,7 @@ var getOutcomeButtonClassName = ({
1794
1745
  const defaultStateClassName = isPositive ? "border-[#18c15c]/50 bg-[#18c15c]/5 text-agg-foreground hover:bg-[#18c15c]/10" : "border-[#e5455f]/50 bg-[#e5455f]/5 text-agg-foreground hover:bg-[#e5455f]/10";
1795
1746
  const activeStateClassName = isPositive ? "border-transparent bg-[#18c15c] text-agg-on-primary" : "border-transparent bg-[#e5455f] text-agg-on-primary";
1796
1747
  return cn(
1797
- "h-auto min-h-10 flex-1 rounded-agg-full border px-4 py-1.5 text-agg-base leading-agg-6 shadow-none md:flex-none md:min-w-[168px]",
1748
+ "h-auto flex-1 rounded-agg-full border px-4 py-1.5 text-agg-base leading-agg-6 shadow-none md:flex-none md:min-w-[168px]",
1798
1749
  getMotionClassName(enableAnimations, "transition-all duration-300 ease-in-out"),
1799
1750
  isActive ? activeStateClassName : defaultStateClassName,
1800
1751
  "focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-agg-primary focus-visible:ring-offset-2 focus-visible:ring-offset-agg-secondary-hover",
@@ -1803,63 +1754,67 @@ var getOutcomeButtonClassName = ({
1803
1754
  );
1804
1755
  };
1805
1756
  var MarketDetailsContent = ({
1806
- event,
1757
+ venueMarkets,
1807
1758
  marketId,
1808
1759
  title,
1809
1760
  image,
1810
- isOpened: defaultIsOpened = marketDetailsDefaultIsOpened,
1761
+ isOpened: controlledIsOpened = marketDetailsDefaultIsOpened,
1811
1762
  onOpenChange,
1812
1763
  defaultTab,
1813
1764
  defaultOutcomeLabel,
1814
- defaultTimeRange = "1M",
1765
+ defaultTimeRange,
1815
1766
  orderBookDepth = orderBookRowLimitDefault,
1816
1767
  ariaLabel,
1817
1768
  classNames,
1818
- otherContent,
1819
- liveUpdate = false
1769
+ otherContent
1820
1770
  }) => {
1771
+ var _a, _b, _c, _d;
1821
1772
  const config = useSdkUiConfig3();
1822
1773
  const labels = useLabels4();
1823
1774
  const detailsContentId = useId();
1824
1775
  const model = useMemo4(() => {
1825
1776
  return buildMarketDetailsModel({
1826
- event,
1777
+ venueMarkets,
1827
1778
  marketId,
1828
1779
  title,
1829
1780
  image,
1830
- formatCompactCurrency: config.formatCompactCurrency,
1781
+ formatCompactCurrency: config.formatting.formatCompactCurrency,
1831
1782
  labels
1832
1783
  });
1833
- }, [config.formatCompactCurrency, event, image, labels, marketId, title]);
1784
+ }, [config.formatting.formatCompactCurrency, venueMarkets, image, labels, marketId, title]);
1834
1785
  const resolvedMarket = useMemo4(() => {
1835
- return resolveMarket(event, marketId);
1836
- }, [event, marketId]);
1786
+ return resolveMarketFromVenueMarkets(venueMarkets, marketId);
1787
+ }, [venueMarkets, marketId]);
1837
1788
  const marketDetailsTabs = useMemo4(() => {
1838
1789
  return getMarketDetailsTabs(labels);
1839
1790
  }, [labels]);
1840
1791
  const [selectedTab, setSelectedTab] = useState2(
1841
1792
  () => resolveInitialTab(defaultTab)
1842
1793
  );
1843
- const [isOpened, setIsOpened] = useState2(defaultIsOpened);
1794
+ const [isOpened, setIsOpened] = useState2(controlledIsOpened);
1844
1795
  useEffect2(() => {
1845
1796
  setSelectedTab(resolveInitialTab(defaultTab));
1846
1797
  }, [defaultTab]);
1847
- const [selectedTimeRange, setSelectedTimeRange] = useState2(defaultTimeRange);
1798
+ useEffect2(() => {
1799
+ setIsOpened(controlledIsOpened);
1800
+ }, [controlledIsOpened]);
1801
+ const resolvedDefaultTimeRange = (_a = defaultTimeRange != null ? defaultTimeRange : config.chart.defaultChartTimeRange) != null ? _a : "1D";
1802
+ const [selectedTimeRange, setSelectedTimeRange] = useState2(resolvedDefaultTimeRange);
1848
1803
  const [selectedChartType, setSelectedChartType] = useState2("line");
1849
1804
  useEffect2(() => {
1850
- setSelectedTimeRange(defaultTimeRange);
1851
- }, [defaultTimeRange]);
1805
+ setSelectedTimeRange(resolvedDefaultTimeRange);
1806
+ }, [resolvedDefaultTimeRange]);
1852
1807
  const [selectedOutcomeLabel, setSelectedOutcomeLabel] = useState2(
1853
1808
  () => {
1854
- var _a;
1855
- return resolveInitialOutcomeLabel((_a = model == null ? void 0 : model.outcomeLabels) != null ? _a : [], defaultOutcomeLabel);
1809
+ var _a2;
1810
+ return resolveInitialOutcomeLabel((_a2 = model == null ? void 0 : model.outcomeLabels) != null ? _a2 : [], defaultOutcomeLabel);
1856
1811
  }
1857
1812
  );
1858
1813
  const [selectedGraphVenue, setSelectedGraphVenue] = useState2(null);
1859
1814
  useEffect2(() => {
1860
- var _a;
1815
+ var _a2;
1861
1816
  setSelectedOutcomeLabel(
1862
- resolveInitialOutcomeLabel((_a = model == null ? void 0 : model.outcomeLabels) != null ? _a : [], defaultOutcomeLabel)
1817
+ resolveInitialOutcomeLabel((_a2 = model == null ? void 0 : model.outcomeLabels) != null ? _a2 : [], defaultOutcomeLabel)
1863
1818
  );
1864
1819
  }, [defaultOutcomeLabel, model == null ? void 0 : model.outcomeLabels]);
1865
1820
  const headerOutcomeItems = useMemo4(() => {
@@ -1886,52 +1841,66 @@ var MarketDetailsContent = ({
1886
1841
  return outcomesByLabelMap;
1887
1842
  }, [headerOutcomeItems, model]);
1888
1843
  const selectedOutcomesByVenue = useMemo4(() => {
1889
- var _a;
1844
+ var _a2;
1890
1845
  if (!selectedOutcomeLabel)
1891
1846
  return [];
1892
- return (_a = outcomesByLabel.get(selectedOutcomeLabel)) != null ? _a : [];
1847
+ return (_a2 = outcomesByLabel.get(selectedOutcomeLabel)) != null ? _a2 : [];
1893
1848
  }, [outcomesByLabel, selectedOutcomeLabel]);
1849
+ const chartEnabled = isOpened && selectedTab === "graph";
1850
+ const orderBookEnabled = isOpened && selectedTab === "order-book";
1894
1851
  const timeWindow = useMemo4(() => {
1895
1852
  return getTimeWindowByRange(selectedTimeRange);
1896
1853
  }, [selectedTimeRange]);
1897
- const graphOutcomes = useMemo4(() => {
1898
- const uniqueOutcomesByVenueAndId = /* @__PURE__ */ new Map();
1899
- outcomesByLabel.forEach((outcomes) => {
1900
- outcomes.forEach((outcomeByVenue) => {
1901
- uniqueOutcomesByVenueAndId.set(
1902
- `${outcomeByVenue.venue}:${outcomeByVenue.outcome.id}`,
1903
- outcomeByVenue
1904
- );
1905
- });
1906
- });
1907
- return [...uniqueOutcomesByVenueAndId.values()];
1908
- }, [outcomesByLabel]);
1909
- const canonicalMarketIdForHistory = model == null ? void 0 : model.market.id;
1910
- const priceHistoryGroups = useMemo4(() => {
1911
- return buildPriceHistoryGroups(graphOutcomes, canonicalMarketIdForHistory);
1912
- }, [canonicalMarketIdForHistory, graphOutcomes]);
1913
- const { data: priceHistoryData, isLoading: isPriceHistoryLoading } = usePriceHistory2(__spreadProps(__spreadValues({
1914
- groups: priceHistoryGroups
1915
- }, timeWindow), {
1916
- enabled: isOpened && selectedTab === "graph" && priceHistoryGroups.length > 0
1917
- }));
1918
- const orderBookInputs = useMemo4(() => {
1919
- return selectedOutcomesByVenue.map(({ market, outcome }) => ({
1920
- market,
1921
- outcome,
1922
- liveUpdate
1923
- }));
1924
- }, [selectedOutcomesByVenue, liveUpdate]);
1854
+ const primaryVenueMarketId = (_c = (_b = selectedOutcomesByVenue[0]) == null ? void 0 : _b.market.id) != null ? _c : null;
1855
+ const venueMarketIds = useMemo4(() => {
1856
+ return selectedOutcomesByVenue.map((item) => item.market.id);
1857
+ }, [selectedOutcomesByVenue]);
1858
+ const {
1859
+ data: marketChartData,
1860
+ isLoading: isMarketChartLoading,
1861
+ error: marketChartError,
1862
+ refetch: refetchMarketChart
1863
+ } = useMarketChart2({
1864
+ marketId: primaryVenueMarketId,
1865
+ venueMarketIds,
1866
+ interval: timeRangeToInterval2(selectedTimeRange),
1867
+ startTs: timeWindow.startTs * 1e3,
1868
+ endTs: timeWindow.endTs * 1e3,
1869
+ enabled: chartEnabled && !!primaryVenueMarketId
1870
+ });
1925
1871
  const {
1926
- data: orderBookData,
1872
+ data: marketOrderbookData,
1927
1873
  isLoading: isOrderBookLoading,
1928
1874
  error: orderBookError,
1929
- results: orderBookResults
1930
- } = useOrderBook({
1931
- orderbooks: orderBookInputs,
1932
- enabled: isOpened && selectedTab === "order-book" && orderBookInputs.length > 0,
1933
- canonicalMarketId: liveUpdate ? canonicalMarketIdForHistory : void 0
1875
+ refetch: refetchOrderBook
1876
+ } = useMarketOrderbook({
1877
+ marketId: primaryVenueMarketId,
1878
+ enabled: orderBookEnabled && !!primaryVenueMarketId,
1879
+ venueOutcomes: selectedOutcomesByVenue.map((item) => ({
1880
+ venue: item.market.venue,
1881
+ venueMarketOutcomeId: item.outcome.id
1882
+ }))
1934
1883
  });
1884
+ const orderBookData = useMemo4(() => {
1885
+ if (!marketOrderbookData)
1886
+ return void 0;
1887
+ const results = selectedOutcomesByVenue.flatMap(({ market, outcome }) => {
1888
+ const venueOrderbook = marketOrderbookData.venueOrderbooks[market.venue];
1889
+ if (!venueOrderbook)
1890
+ return [];
1891
+ return [
1892
+ {
1893
+ market,
1894
+ outcome,
1895
+ orderbook: {
1896
+ bids: venueOrderbook.bids,
1897
+ asks: venueOrderbook.asks
1898
+ }
1899
+ }
1900
+ ];
1901
+ });
1902
+ return results.length === selectedOutcomesByVenue.length ? results : void 0;
1903
+ }, [marketOrderbookData, selectedOutcomesByVenue]);
1935
1904
  const askRows = useMemo4(() => {
1936
1905
  return resolveOrderBookRows({
1937
1906
  data: orderBookData,
@@ -1944,78 +1913,43 @@ var MarketDetailsContent = ({
1944
1913
  side: "bids"
1945
1914
  });
1946
1915
  }, [orderBookData]);
1947
- const priceHistoryByVenue = useMemo4(() => {
1948
- const historyByVenue = /* @__PURE__ */ new Map();
1949
- if (!(priceHistoryData == null ? void 0 : priceHistoryData.length)) {
1950
- return historyByVenue;
1951
- }
1952
- priceHistoryData.forEach((historyItem) => {
1953
- const venue = historyItem.venue;
1954
- const venueHistory = historyByVenue.get(venue);
1955
- if (venueHistory) {
1956
- venueHistory.push(historyItem);
1957
- return;
1958
- }
1959
- historyByVenue.set(venue, [historyItem]);
1960
- });
1961
- return historyByVenue;
1962
- }, [priceHistoryData]);
1963
- const graphSeriesByOutcomeLabel = useMemo4(() => {
1964
- const seriesByOutcomeLabel = /* @__PURE__ */ new Map();
1965
- const resolveOutcomeCandidateIds2 = (outcomeByVenue) => {
1966
- var _a, _b;
1967
- const marketWithCanonicalId = outcomeByVenue.market;
1968
- return [
1969
- outcomeByVenue.outcome.id,
1970
- (_a = outcomeByVenue.outcome.externalIdentifier) != null ? _a : void 0,
1971
- outcomeByVenue.market.externalIdentifier,
1972
- (_b = marketWithCanonicalId.marketId) != null ? _b : void 0,
1973
- canonicalMarketIdForHistory
1974
- ].filter((value) => typeof value === "string" && value.trim().length > 0);
1975
- };
1976
- headerOutcomeItems.forEach((headerOutcomeItem) => {
1977
- var _a;
1978
- const outcomes = (_a = outcomesByLabel.get(headerOutcomeItem.label)) != null ? _a : [];
1979
- const graphSeries2 = [];
1980
- outcomes.forEach((outcomeByVenue, index) => {
1981
- var _a2;
1982
- const venueHistory = priceHistoryByVenue.get(outcomeByVenue.venue);
1983
- if (!(venueHistory == null ? void 0 : venueHistory.length))
1984
- return;
1985
- const candidateIds = resolveOutcomeCandidateIds2(outcomeByVenue);
1986
- const matchingHistory = (_a2 = venueHistory.find((historyItem) => candidateIds.includes(historyItem.marketId))) != null ? _a2 : venueHistory.length === 1 ? venueHistory[0] : void 0;
1987
- if (!matchingHistory)
1988
- return;
1989
- const points = matchingHistory.points.map((point) => ({
1990
- time: point.timestamp,
1991
- value: point.price * 100,
1992
- open: point.open == null ? void 0 : point.open * 100,
1993
- high: point.high == null ? void 0 : point.high * 100,
1994
- low: point.low == null ? void 0 : point.low * 100,
1995
- close: point.close == null ? void 0 : point.close * 100
1996
- })).filter((point) => Number.isFinite(point.time) && Number.isFinite(point.value));
1997
- if (points.length === 0)
1998
- return;
1999
- graphSeries2.push({
2000
- id: `${headerOutcomeItem.label}-${outcomeByVenue.venue}-${matchingHistory.marketId}`,
2001
- venue: outcomeByVenue.venue,
2002
- color: resolveSeriesColor(outcomeByVenue.venue, index),
2003
- points
2004
- });
2005
- });
2006
- seriesByOutcomeLabel.set(headerOutcomeItem.label, graphSeries2);
2007
- });
2008
- return seriesByOutcomeLabel;
2009
- }, [canonicalMarketIdForHistory, headerOutcomeItems, outcomesByLabel, priceHistoryByVenue]);
2010
1916
  const graphSeries = useMemo4(() => {
2011
- var _a;
2012
- if (!selectedOutcomeLabel)
2013
- return [];
2014
- const seriesForOutcomeLabel = (_a = graphSeriesByOutcomeLabel.get(selectedOutcomeLabel)) != null ? _a : [];
1917
+ const colorByVenue = new Map(
1918
+ selectedOutcomesByVenue.map((item, index) => [
1919
+ item.venue,
1920
+ resolveSeriesColor(item.venue, index)
1921
+ ])
1922
+ );
1923
+ const seriesForOutcomeLabel = resolveMarketChartVenueSeries({
1924
+ chartData: marketChartData,
1925
+ transformProbability: (value) => value
1926
+ }).map((seriesItem) => {
1927
+ var _a2;
1928
+ const resolvedVenue = seriesItem.venue;
1929
+ return {
1930
+ id: `${selectedOutcomeLabel != null ? selectedOutcomeLabel : "graph"}-${resolvedVenue}-${primaryVenueMarketId != null ? primaryVenueMarketId : "chart"}`,
1931
+ venue: resolvedVenue,
1932
+ color: (_a2 = colorByVenue.get(resolvedVenue)) != null ? _a2 : resolveSeriesColor(resolvedVenue, 0),
1933
+ points: seriesItem.points
1934
+ };
1935
+ });
2015
1936
  if (!selectedGraphVenue)
2016
1937
  return seriesForOutcomeLabel;
2017
1938
  return seriesForOutcomeLabel.filter((seriesItem) => seriesItem.venue === selectedGraphVenue);
2018
- }, [graphSeriesByOutcomeLabel, selectedGraphVenue, selectedOutcomeLabel]);
1939
+ }, [
1940
+ primaryVenueMarketId,
1941
+ marketChartData,
1942
+ selectedGraphVenue,
1943
+ selectedOutcomeLabel,
1944
+ selectedOutcomesByVenue
1945
+ ]);
1946
+ const graphLiveState = useMemo4(() => {
1947
+ return resolveMarketChartLiveState({
1948
+ chartData: marketChartData,
1949
+ selectedVenue: selectedGraphVenue,
1950
+ transformProbability: (value) => value
1951
+ });
1952
+ }, [marketChartData, selectedGraphVenue]);
2019
1953
  const otherRows = useMemo4(() => {
2020
1954
  if (!model)
2021
1955
  return [];
@@ -2023,9 +1957,10 @@ var MarketDetailsContent = ({
2023
1957
  }, [labels, model]);
2024
1958
  const isOrderBookNotFound = orderBookError && typeof orderBookError === "object" && "status" in orderBookError && orderBookError.status === 404;
2025
1959
  const hasOrderBookError = !!orderBookError && !isOrderBookNotFound;
2026
- const hasNoOrderBook = isOrderBookNotFound || !isOrderBookLoading && !hasOrderBookError && (orderBookInputs.length === 0 || askRows.length === 0 && bidRows.length === 0);
1960
+ const hasNoOrderBook = isOrderBookNotFound || !isOrderBookLoading && !hasOrderBookError && (selectedOutcomesByVenue.length === 0 || askRows.length === 0 && bidRows.length === 0);
1961
+ const hasChartError = !!marketChartError;
2027
1962
  const handleOutcomeKeyDown = (eventToHandle) => {
2028
- var _a;
1963
+ var _a2;
2029
1964
  if ((eventToHandle == null ? void 0 : eventToHandle.key) !== "ArrowLeft" && (eventToHandle == null ? void 0 : eventToHandle.key) !== "ArrowRight") {
2030
1965
  return;
2031
1966
  }
@@ -2036,19 +1971,17 @@ var MarketDetailsContent = ({
2036
1971
  });
2037
1972
  const direction = eventToHandle.key === "ArrowRight" ? 1 : -1;
2038
1973
  const nextIndex = activeIndex < 0 ? 0 : (activeIndex + direction + headerOutcomeItems.length) % headerOutcomeItems.length;
2039
- setSelectedOutcomeLabel((_a = headerOutcomeItems[nextIndex]) == null ? void 0 : _a.label);
1974
+ setSelectedOutcomeLabel((_a2 = headerOutcomeItems[nextIndex]) == null ? void 0 : _a2.label);
2040
1975
  };
2041
- const handleToggleExpanded = (event2) => {
2042
- if (event2 && "key" in event2 && (event2 == null ? void 0 : event2.key) !== "Enter" && (event2 == null ? void 0 : event2.key) !== " ") {
1976
+ const handleToggleExpanded = (event) => {
1977
+ if (!marketId)
1978
+ return;
1979
+ if (event && "key" in event && (event == null ? void 0 : event.key) !== "Enter" && (event == null ? void 0 : event.key) !== " ") {
2043
1980
  return;
2044
1981
  }
2045
- event2 == null ? void 0 : event2.preventDefault();
2046
- event2 == null ? void 0 : event2.stopPropagation();
2047
- setIsOpened((prev) => {
2048
- const next = !prev;
2049
- onOpenChange == null ? void 0 : onOpenChange(next);
2050
- return next;
2051
- });
1982
+ event == null ? void 0 : event.preventDefault();
1983
+ event == null ? void 0 : event.stopPropagation();
1984
+ onOpenChange == null ? void 0 : onOpenChange(marketId);
2052
1985
  };
2053
1986
  const handleGraphVenueToggle = (venue) => {
2054
1987
  setSelectedGraphVenue((currentVenue) => {
@@ -2058,7 +1991,10 @@ var MarketDetailsContent = ({
2058
1991
  });
2059
1992
  };
2060
1993
  const handleRetryOrderBook = () => {
2061
- void Promise.all(orderBookResults.map((result) => result.refetch()));
1994
+ void refetchOrderBook();
1995
+ };
1996
+ const handleRetryMarketChart = () => {
1997
+ void refetchMarketChart();
2062
1998
  };
2063
1999
  useEffect2(() => {
2064
2000
  if (!selectedGraphVenue) {
@@ -2089,7 +2025,7 @@ var MarketDetailsContent = ({
2089
2025
  {
2090
2026
  className: cn(
2091
2027
  "cursor-pointer disabled:cursor-default",
2092
- "flex flex-wrap flex-row items-center justify-between gap-3 px-5 py-4",
2028
+ "flex flex-nowrap flex-row items-center justify-between gap-3 px-5 py-4",
2093
2029
  isOpened && "pb-3",
2094
2030
  classNames == null ? void 0 : classNames.header
2095
2031
  ),
@@ -2101,7 +2037,7 @@ var MarketDetailsContent = ({
2101
2037
  onClick: handleToggleExpanded,
2102
2038
  onKeyDown: handleToggleExpanded,
2103
2039
  children: [
2104
- /* @__PURE__ */ jsxs3("div", { className: "flex min-w-52 items-center gap-3 md:gap-4", children: [
2040
+ /* @__PURE__ */ jsxs3("div", { className: "flex min-w-0 flex-1 items-center gap-3 md:gap-4", children: [
2105
2041
  model.image ? /* @__PURE__ */ jsx4(
2106
2042
  RemoteImage,
2107
2043
  {
@@ -2115,62 +2051,64 @@ var MarketDetailsContent = ({
2115
2051
  /* @__PURE__ */ jsx4("div", { className: "flex items-center gap-3", children: /* @__PURE__ */ jsx4(Typography, { variant: "label", className: "truncate text-agg-muted-foreground", children: model.subtitle }) })
2116
2052
  ] })
2117
2053
  ] }),
2118
- /* @__PURE__ */ jsx4(Typography, { as: "div", variant: "heading", className: "shrink-0", children: formatProbabilityPercent(headlineProbability) }),
2119
- /* @__PURE__ */ jsx4(
2120
- "div",
2121
- {
2122
- className: "flex gap-2",
2123
- role: "tablist",
2124
- "aria-label": labels.marketDetails.marketOutcomesAria,
2125
- tabIndex: 0,
2126
- onKeyDown: (e) => handleOutcomeKeyDown(e),
2127
- children: headerOutcomeItems.map((item) => {
2128
- const isPositive = item.tone === "positive";
2129
- const isActiveOutcome = item.label === selectedOutcomeLabel;
2130
- return /* @__PURE__ */ jsx4(
2131
- "button",
2132
- {
2133
- type: "button",
2134
- role: "tab",
2135
- "aria-selected": isActiveOutcome,
2136
- tabIndex: isActiveOutcome ? 0 : -1,
2137
- className: getOutcomeButtonClassName({
2138
- enableAnimations: config.enableAnimations,
2139
- isPositive,
2140
- isActive: isActiveOutcome
2141
- }),
2142
- onClick: (e) => {
2143
- e.preventDefault();
2144
- e.stopPropagation();
2145
- setSelectedOutcomeLabel(item.label);
2054
+ /* @__PURE__ */ jsxs3("div", { className: "flex shrink-0 items-center gap-3", children: [
2055
+ /* @__PURE__ */ jsx4(Typography, { as: "div", variant: "heading", className: "shrink-0", children: formatProbabilityPercent(headlineProbability) }),
2056
+ /* @__PURE__ */ jsx4(
2057
+ "div",
2058
+ {
2059
+ className: "flex shrink-0 gap-2",
2060
+ role: "tablist",
2061
+ "aria-label": labels.marketDetails.marketOutcomesAria,
2062
+ tabIndex: 0,
2063
+ onKeyDown: (e) => handleOutcomeKeyDown(e),
2064
+ children: headerOutcomeItems.map((item) => {
2065
+ const isPositive = item.tone === "positive";
2066
+ const isActiveOutcome = item.label === selectedOutcomeLabel;
2067
+ return /* @__PURE__ */ jsx4(
2068
+ "button",
2069
+ {
2070
+ type: "button",
2071
+ role: "tab",
2072
+ "aria-selected": isActiveOutcome,
2073
+ tabIndex: isActiveOutcome ? 0 : -1,
2074
+ className: getOutcomeButtonClassName({
2075
+ enableAnimations: config.features.enableAnimations,
2076
+ isPositive,
2077
+ isActive: isActiveOutcome
2078
+ }),
2079
+ onClick: (e) => {
2080
+ e.preventDefault();
2081
+ e.stopPropagation();
2082
+ setSelectedOutcomeLabel(item.label);
2083
+ },
2084
+ children: /* @__PURE__ */ jsxs3("span", { className: "inline-flex items-center gap-2", children: [
2085
+ /* @__PURE__ */ jsx4(
2086
+ VenueLogo,
2087
+ {
2088
+ venue: item.venue,
2089
+ size: "small",
2090
+ color: isActiveOutcome ? "var(--agg-color-on-primary)" : void 0
2091
+ }
2092
+ ),
2093
+ /* @__PURE__ */ jsx4(
2094
+ Typography,
2095
+ {
2096
+ variant: isActiveOutcome ? "body-strong" : "body",
2097
+ className: cn(
2098
+ "text-agg-base leading-agg-6",
2099
+ isActiveOutcome ? "text-agg-on-primary" : "text-agg-foreground"
2100
+ ),
2101
+ children: `${item.label} ${formatProbabilityCents(item.probability)}`
2102
+ }
2103
+ )
2104
+ ] })
2146
2105
  },
2147
- children: /* @__PURE__ */ jsxs3("span", { className: "inline-flex items-center gap-2", children: [
2148
- /* @__PURE__ */ jsx4(
2149
- VenueLogo,
2150
- {
2151
- venue: isPositive ? "polymarket" : "probable",
2152
- size: "small",
2153
- color: isActiveOutcome ? "var(--agg-color-on-primary)" : void 0
2154
- }
2155
- ),
2156
- /* @__PURE__ */ jsx4(
2157
- Typography,
2158
- {
2159
- variant: isActiveOutcome ? "body-strong" : "body",
2160
- className: cn(
2161
- "text-agg-base leading-agg-6",
2162
- isActiveOutcome ? "text-agg-on-primary" : "text-agg-foreground"
2163
- ),
2164
- children: `${item.label} ${formatProbabilityCents(item.probability)}`
2165
- }
2166
- )
2167
- ] })
2168
- },
2169
- item.label
2170
- );
2171
- })
2172
- }
2173
- )
2106
+ item.label
2107
+ );
2108
+ })
2109
+ }
2110
+ )
2111
+ ] })
2174
2112
  ]
2175
2113
  }
2176
2114
  ),
@@ -2180,7 +2118,10 @@ var MarketDetailsContent = ({
2180
2118
  id: detailsContentId,
2181
2119
  className: cn(
2182
2120
  "grid overflow-hidden",
2183
- getMotionClassName(config.enableAnimations, "transition-all duration-500 ease-in-out"),
2121
+ getMotionClassName(
2122
+ config.features.enableAnimations,
2123
+ "transition-all duration-500 ease-in-out"
2124
+ ),
2184
2125
  isOpened ? "grid-rows-[1fr] opacity-100" : "pointer-events-none grid-rows-[0fr] opacity-0"
2185
2126
  ),
2186
2127
  "aria-hidden": !isOpened,
@@ -2191,12 +2132,12 @@ var MarketDetailsContent = ({
2191
2132
  {
2192
2133
  className: cn(
2193
2134
  getMotionClassName(
2194
- config.enableAnimations,
2135
+ config.features.enableAnimations,
2195
2136
  "transition-all duration-500 ease-in-out"
2196
2137
  ),
2197
2138
  isOpened ? cn(
2198
2139
  "translate-y-0 opacity-100",
2199
- getMotionClassName(config.enableAnimations, "delay-100")
2140
+ getMotionClassName(config.features.enableAnimations, "delay-100")
2200
2141
  ) : "translate-y-5 opacity-0"
2201
2142
  ),
2202
2143
  children: [
@@ -2238,8 +2179,8 @@ var MarketDetailsContent = ({
2238
2179
  {
2239
2180
  rows: askRows,
2240
2181
  title: labels.marketDetails.asks,
2241
- formatNumber: config.formatNumber,
2242
- formatCurrency: config.formatCurrency,
2182
+ formatNumber: config.formatting.formatNumber,
2183
+ formatCurrency: config.formatting.formatCurrency,
2243
2184
  visibleRows: orderBookDepth
2244
2185
  }
2245
2186
  ),
@@ -2248,20 +2189,33 @@ var MarketDetailsContent = ({
2248
2189
  {
2249
2190
  rows: bidRows,
2250
2191
  title: labels.marketDetails.bids,
2251
- formatNumber: config.formatNumber,
2252
- formatCurrency: config.formatCurrency,
2192
+ formatNumber: config.formatting.formatNumber,
2193
+ formatCurrency: config.formatting.formatCurrency,
2253
2194
  visibleRows: orderBookDepth
2254
2195
  }
2255
2196
  )
2256
2197
  ] }) }) : null,
2257
2198
  selectedTab === "graph" ? /* @__PURE__ */ jsxs3("div", { className: cn("flex flex-col gap-5", classNames == null ? void 0 : classNames.graph), children: [
2258
- /* @__PURE__ */ jsx4(
2199
+ hasChartError ? /* @__PURE__ */ jsx4(
2200
+ StateMessage,
2201
+ {
2202
+ ariaLabel: labels.marketDetails.chartUnavailableAria,
2203
+ tone: "warning",
2204
+ title: labels.marketDetails.chartUnavailableTitle,
2205
+ description: labels.marketDetails.chartUnavailableDescription,
2206
+ actionLabel: labels.common.retry,
2207
+ onAction: handleRetryMarketChart,
2208
+ className: "min-h-[248px] px-5 py-10 md:min-h-[272px]"
2209
+ }
2210
+ ) : /* @__PURE__ */ jsx4(
2259
2211
  LineChart,
2260
2212
  {
2261
2213
  series: graphSeries,
2262
2214
  height: 260,
2263
- isLoading: isPriceHistoryLoading,
2215
+ isLoading: isMarketChartLoading,
2264
2216
  chartType: selectedChartType,
2217
+ liveCandle: selectedChartType === "candlestick" ? (_d = graphLiveState.liveCandle) != null ? _d : void 0 : void 0,
2218
+ lineValue: graphLiveState.lineValue,
2265
2219
  classNames: { root: "w-full" },
2266
2220
  showSeriesControls: selectedOutcomesByVenue.length > 0 || headerOutcomeItems.length > 0,
2267
2221
  renderSeriesControls: () => {
@@ -2319,7 +2273,7 @@ var MarketDetailsContent = ({
2319
2273
  classNames == null ? void 0 : classNames.footer
2320
2274
  ),
2321
2275
  children: [
2322
- /* @__PURE__ */ jsx4("span", { children: typeof model.market.volume === "number" ? `${config.formatCompactCurrency(model.market.volume)} ${labels.marketDetails.meta.volumeSuffix}` : labels.marketDetails.volumeUnavailable }),
2276
+ /* @__PURE__ */ jsx4("span", { children: typeof model.market.volume === "number" ? `${config.formatting.formatCompactCurrency(model.market.volume)} ${labels.marketDetails.meta.volumeSuffix}` : labels.marketDetails.volumeUnavailable }),
2323
2277
  /* @__PURE__ */ jsxs3("div", { className: "flex flex-wrap items-center gap-3 md:gap-4", children: [
2324
2278
  /* @__PURE__ */ jsx4(
2325
2279
  ChartTypeSwitch,
@@ -2384,79 +2338,117 @@ var MarketDetailsContent = ({
2384
2338
  }
2385
2339
  );
2386
2340
  };
2387
- var MarketDetails = (props) => {
2388
- var _a, _b;
2389
- const [uncontrolledIsOpened, setUncontrolledIsOpened] = useState2(
2390
- (_a = props.defaultIsOpened) != null ? _a : marketDetailsDefaultIsOpened
2391
- );
2392
- useEffect2(() => {
2393
- if (typeof props.isOpened !== "boolean")
2394
- return;
2395
- setUncontrolledIsOpened(props.isOpened);
2396
- }, [props.isOpened]);
2397
- const resolvedIsOpened = typeof props.isOpened === "boolean" ? props.isOpened : uncontrolledIsOpened;
2398
- const handleOpenChange = (nextIsOpened) => {
2399
- var _a2;
2400
- if (typeof props.isOpened !== "boolean") {
2401
- setUncontrolledIsOpened(nextIsOpened);
2402
- }
2403
- (_a2 = props.onOpenChange) == null ? void 0 : _a2.call(props, nextIsOpened);
2404
- };
2405
- const hasEventProp = "event" in props && !!props.event;
2406
- const {
2407
- event: fetchedEvent,
2408
- error: eventError,
2409
- isLoading: isFetchingEvent
2410
- } = useVenueEvent3({
2411
- eventId: hasEventProp ? "" : (_b = props.eventId) != null ? _b : "",
2412
- enabled: !props.isLoading && !hasEventProp && !!props.eventId
2413
- });
2341
+ var MarketDetails = (_a) => {
2342
+ var _b = _a, { isOpened } = _b, props = __objRest(_b, ["isOpened"]);
2414
2343
  if (props.isLoading) {
2415
2344
  return /* @__PURE__ */ jsx4(
2416
2345
  MarketDetailsLoadingState,
2417
2346
  {
2418
- isOpened: resolvedIsOpened,
2347
+ isOpened,
2419
2348
  ariaLabel: props.ariaLabel,
2420
2349
  classNames: props.classNames
2421
2350
  }
2422
2351
  );
2423
2352
  }
2424
- if ("event" in props && props.event) {
2353
+ if ("venueMarkets" in props && props.venueMarkets) {
2425
2354
  return /* @__PURE__ */ jsx4(
2426
2355
  MarketDetailsContent,
2427
2356
  __spreadProps(__spreadValues({}, props), {
2428
- isOpened: resolvedIsOpened,
2429
- onOpenChange: handleOpenChange,
2430
- event: props.event
2357
+ isOpened,
2358
+ onOpenChange: props.onOpenChange,
2359
+ venueMarkets: props.venueMarkets
2431
2360
  })
2432
2361
  );
2433
2362
  }
2434
- if (isFetchingEvent) {
2435
- return /* @__PURE__ */ jsx4(
2436
- MarketDetailsLoadingState,
2363
+ const { ariaLabel: fallbackAriaLabel, classNames: fallbackClassNames } = props;
2364
+ return /* @__PURE__ */ jsx4(MarketDetailsUnavailableState, { ariaLabel: fallbackAriaLabel, classNames: fallbackClassNames });
2365
+ };
2366
+ MarketDetails.displayName = "MarketDetails";
2367
+ var resolveInitialExpandedId = (markets) => {
2368
+ var _a, _b;
2369
+ if (!markets.length)
2370
+ return null;
2371
+ return (_b = (_a = markets[0]) == null ? void 0 : _a.id) != null ? _b : null;
2372
+ };
2373
+ var MarketDetailsList = ({
2374
+ eventId,
2375
+ onExpandedMarketChange,
2376
+ defaultTab,
2377
+ defaultTimeRange,
2378
+ classNames,
2379
+ ariaLabel
2380
+ }) => {
2381
+ const labels = useLabels4();
2382
+ const resolvedEventId = eventId || "";
2383
+ const { markets, isLoading, error } = useVenueMarkets({
2384
+ venueEventId: resolvedEventId,
2385
+ enabled: !!resolvedEventId
2386
+ });
2387
+ const [expandedMarketId, setExpandedMarketId] = useState2(
2388
+ () => resolveInitialExpandedId(markets)
2389
+ );
2390
+ useEffect2(() => {
2391
+ setExpandedMarketId((current) => {
2392
+ if (current && markets.some((m) => m.id === current))
2393
+ return current;
2394
+ return resolveInitialExpandedId(markets);
2395
+ });
2396
+ }, [markets]);
2397
+ const handleToggle = (marketId) => {
2398
+ if (marketId === expandedMarketId) {
2399
+ onExpandedMarketChange == null ? void 0 : onExpandedMarketChange(null);
2400
+ setExpandedMarketId(null);
2401
+ return;
2402
+ }
2403
+ onExpandedMarketChange == null ? void 0 : onExpandedMarketChange(marketId);
2404
+ setExpandedMarketId(marketId);
2405
+ };
2406
+ if (isLoading) {
2407
+ return /* @__PURE__ */ jsxs3("div", { className: cn("flex flex-col gap-3", classNames == null ? void 0 : classNames.root), "aria-label": ariaLabel, children: [
2408
+ /* @__PURE__ */ jsx4(MarketDetailsLoadingState, { isOpened: true, classNames: { root: classNames == null ? void 0 : classNames.item } }),
2409
+ /* @__PURE__ */ jsx4(MarketDetailsLoadingState, { isOpened: false, classNames: { root: classNames == null ? void 0 : classNames.item } })
2410
+ ] });
2411
+ }
2412
+ if (error) {
2413
+ return /* @__PURE__ */ jsx4(Card, { className: cn(marketDetailsBaseCardClassName, "p-0", classNames == null ? void 0 : classNames.root), children: /* @__PURE__ */ jsx4(
2414
+ StateMessage,
2437
2415
  {
2438
- isOpened: resolvedIsOpened,
2439
- ariaLabel: props.ariaLabel,
2440
- classNames: props.classNames
2416
+ ariaLabel: ariaLabel != null ? ariaLabel : labels.marketDetails.unavailableAria,
2417
+ title: labels.marketDetails.unavailableTitle,
2418
+ description: labels.marketDetails.unavailableDescription,
2419
+ className: "min-h-[280px] md:min-h-[320px]"
2441
2420
  }
2442
- );
2421
+ ) });
2443
2422
  }
2444
- if (!fetchedEvent) {
2445
- if (isErrorWithStatus(eventError, 404)) {
2446
- return /* @__PURE__ */ jsx4(MarketDetailsNotFoundState, { ariaLabel: props.ariaLabel, classNames: props.classNames });
2447
- }
2448
- return /* @__PURE__ */ jsx4(MarketDetailsUnavailableState, { ariaLabel: props.ariaLabel, classNames: props.classNames });
2423
+ if (markets.length === 0) {
2424
+ return /* @__PURE__ */ jsx4(Card, { className: cn(marketDetailsBaseCardClassName, "p-0", classNames == null ? void 0 : classNames.root), children: /* @__PURE__ */ jsx4(
2425
+ StateMessage,
2426
+ {
2427
+ ariaLabel: ariaLabel != null ? ariaLabel : labels.marketDetails.notFoundAria,
2428
+ title: labels.marketDetails.notFoundTitle,
2429
+ description: labels.marketDetails.notFoundDescription,
2430
+ className: "min-h-[280px] md:min-h-[320px]"
2431
+ }
2432
+ ) });
2449
2433
  }
2450
- return /* @__PURE__ */ jsx4(
2451
- MarketDetailsContent,
2452
- __spreadProps(__spreadValues({}, props), {
2453
- isOpened: resolvedIsOpened,
2454
- onOpenChange: handleOpenChange,
2455
- event: fetchedEvent
2456
- })
2457
- );
2434
+ return /* @__PURE__ */ jsx4("div", { className: cn("flex flex-col gap-3", classNames == null ? void 0 : classNames.root), "aria-label": ariaLabel, children: markets.map((market) => /* @__PURE__ */ jsx4(
2435
+ MarketDetails,
2436
+ {
2437
+ marketId: market.id,
2438
+ venueMarkets: [market],
2439
+ isOpened: expandedMarketId === market.id,
2440
+ onOpenChange: (marketId) => {
2441
+ handleToggle(marketId);
2442
+ },
2443
+ defaultTab,
2444
+ defaultTimeRange,
2445
+ ariaLabel: market.question,
2446
+ classNames: { root: classNames == null ? void 0 : classNames.item }
2447
+ },
2448
+ market.id
2449
+ )) });
2458
2450
  };
2459
- MarketDetails.displayName = "MarketDetails";
2451
+ MarketDetailsList.displayName = "MarketDetailsList";
2460
2452
 
2461
2453
  // src/events/list/index.tsx
2462
2454
  import { useCallback, useEffect as useEffect3, useMemo as useMemo5, useRef, useState as useState3 } from "react";
@@ -2465,8 +2457,12 @@ import { useVenueEvents, useLabels as useLabels5 } from "@agg-market/hooks";
2465
2457
  // src/events/list/event-list.constants.ts
2466
2458
  var POLYMARKET_VENUE = "polymarket";
2467
2459
  var KALSHI_VENUE = "kalshi";
2460
+ var OPINION_VENUE = "opinion";
2461
+ var PROBABLE_VENUE = "probable";
2468
2462
  var POLYMARKET_VENUE_LOGO = "polymarket";
2469
2463
  var KALSHI_VENUE_LOGO = "kalshi";
2464
+ var OPINION_VENUE_LOGO = "opinion";
2465
+ var PROBABLE_VENUE_LOGO = "probable";
2470
2466
  var getDefaultEventListTabs = (labels) => {
2471
2467
  return [
2472
2468
  {
@@ -2485,6 +2481,18 @@ var getDefaultEventListTabs = (labels) => {
2485
2481
  label: labels.venues.kalshi,
2486
2482
  venueLogo: KALSHI_VENUE_LOGO,
2487
2483
  venues: [KALSHI_VENUE]
2484
+ },
2485
+ {
2486
+ value: "opinion",
2487
+ label: labels.venues.opinion,
2488
+ venueLogo: OPINION_VENUE_LOGO,
2489
+ venues: [OPINION_VENUE]
2490
+ },
2491
+ {
2492
+ value: "probable",
2493
+ label: labels.venues.probable,
2494
+ venueLogo: PROBABLE_VENUE_LOGO,
2495
+ venues: [PROBABLE_VENUE]
2488
2496
  }
2489
2497
  ];
2490
2498
  };
@@ -2503,7 +2511,7 @@ var resolveTabVenus = (tab) => {
2503
2511
  return void 0;
2504
2512
  if (tab.venues && tab.venues.length > 0)
2505
2513
  return tab.venues;
2506
- if (tab.value === "polymarket" || tab.value === "kalshi") {
2514
+ if (tab.value === "polymarket" || tab.value === "kalshi" || tab.value === "opinion" || tab.value === "probable") {
2507
2515
  return [tab.value];
2508
2516
  }
2509
2517
  return void 0;
@@ -2555,11 +2563,11 @@ var estimateTabsWidth = (items) => {
2555
2563
  var EventList = ({
2556
2564
  title,
2557
2565
  maxItemsPerRow = 3,
2558
- limit = 3,
2566
+ limit = 9,
2559
2567
  maxVisibleItems,
2560
- showVenueLogo = true,
2561
2568
  search,
2562
- categoryIds
2569
+ categoryIds,
2570
+ onClick
2563
2571
  }) => {
2564
2572
  var _a, _b;
2565
2573
  const labels = useLabels5();
@@ -2584,6 +2592,7 @@ var EventList = ({
2584
2592
  const requestLimit = resolvedMaxVisibleItems != null ? resolvedMaxVisibleItems : limit;
2585
2593
  const shouldPaginate = resolvedMaxVisibleItems == null;
2586
2594
  const { events, isLoading, isError, fetchNextPage, hasNextPage, isFetchingNextPage } = useVenueEvents({
2595
+ queryKeyScope: "event-list",
2587
2596
  venues,
2588
2597
  search,
2589
2598
  categoryIds,
@@ -2714,10 +2723,10 @@ var EventList = ({
2714
2723
  EventListItem,
2715
2724
  {
2716
2725
  event,
2717
- showVenueLogo,
2718
2726
  classNames: {
2719
2727
  root: "w-full min-w-0 max-w-none"
2720
- }
2728
+ },
2729
+ onClick
2721
2730
  },
2722
2731
  event.id
2723
2732
  )),
@@ -2731,13 +2740,12 @@ var EventList = ({
2731
2740
  },
2732
2741
  `loading-${index}`
2733
2742
  )),
2734
- !isLoading && !isError && (tileEvents == null ? void 0 : tileEvents.length) === 0 ? /* @__PURE__ */ jsx5(Card, { className: "col-span-full overflow-hidden shadow-none hover:shadow-none", children: /* @__PURE__ */ jsx5(
2743
+ !isLoading && !isError && (tileEvents == null ? void 0 : tileEvents.length) === 0 ? /* @__PURE__ */ jsx5(Card, { className: "col-span-full overflow-hidden shadow-none hover:shadow-none p-0! border-none! bg-transparent!", children: /* @__PURE__ */ jsx5(
2735
2744
  StateMessage,
2736
2745
  {
2737
2746
  ariaLabel: labels.eventList.emptyAria,
2738
2747
  title: labels.eventList.emptyTitle,
2739
- description: labels.eventList.emptyDescription,
2740
- className: "min-h-[320px]"
2748
+ description: labels.eventList.emptyDescription
2741
2749
  }
2742
2750
  ) }) : null,
2743
2751
  isError ? /* @__PURE__ */ jsx5(
@@ -2759,5 +2767,8 @@ export {
2759
2767
  EventListItem,
2760
2768
  EventListItemDetails,
2761
2769
  MarketDetails,
2770
+ MarketDetailsList,
2771
+ getDefaultEventListTabs,
2772
+ resolveTabVenus,
2762
2773
  EventList
2763
2774
  };