@agg-build/ui 4.7.1 → 4.7.3

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.
@@ -12,7 +12,7 @@ import {
12
12
  isErrorWithStatus,
13
13
  useEventListTabs,
14
14
  useEventListTabsHeaderOverflow
15
- } from "./chunk-C4GFVJ62.mjs";
15
+ } from "./chunk-3X5ICUUC.mjs";
16
16
  import {
17
17
  DEPOSIT_MODAL_OPEN_EVENT,
18
18
  PlaceOrder,
@@ -21,12 +21,12 @@ import {
21
21
  formatChainIdLabel,
22
22
  useClaimWinnings,
23
23
  useResolvedMarketClaim
24
- } from "./chunk-3RQCBGIK.mjs";
24
+ } from "./chunk-SQ4BA3CC.mjs";
25
25
  import {
26
26
  getDisplayOutcomePrice,
27
27
  resolveHeaderOutcomeItems,
28
28
  resolveMarketFromVenueMarkets
29
- } from "./chunk-WYCSTAN7.mjs";
29
+ } from "./chunk-MAQ52KM5.mjs";
30
30
  import {
31
31
  AggErrorBoundary,
32
32
  Button,
@@ -62,7 +62,7 @@ import {
62
62
  skeletonViews,
63
63
  sortCategoriesForNavigation,
64
64
  useOptionalToast
65
- } from "./chunk-RDBMHBR2.mjs";
65
+ } from "./chunk-UQ7XJIAZ.mjs";
66
66
 
67
67
  // src/pages/home/index.tsx
68
68
  import {
@@ -769,13 +769,24 @@ var isDecomposedLeg = (market) => {
769
769
  );
770
770
  return labels.length === 2 && labels.every((label) => YES_NO_LABELS.has(label)) && !hasTeamTitledOutcomes(market);
771
771
  };
772
+ var singleEnumeratesLegs = (single, legs) => {
773
+ var _a;
774
+ const titles = new Set(
775
+ ((_a = single.venueMarketOutcomes) != null ? _a : []).map((outcome) => toTrimmedString(outcome.title).toLowerCase()).filter(Boolean)
776
+ );
777
+ if (titles.size === 0) return false;
778
+ return legs.every((leg) => {
779
+ const label = resolveCombinedMoneylineLegLabel(leg).toLowerCase();
780
+ return label.length > 0 && titles.has(label);
781
+ });
782
+ };
772
783
  var dropDecomposedLegsMergedIntoSingle = (markets) => {
773
784
  const legs = markets.filter((market) => isDecomposedLeg(market));
774
785
  if (legs.length === 0) return markets;
775
786
  const hasMergedSingle = markets.some(
776
787
  (market) => {
777
788
  var _a, _b;
778
- return hasTeamTitledOutcomes(market) && ((_b = (_a = market.venueMarketOutcomes) == null ? void 0 : _a.length) != null ? _b : 0) >= legs.length && markets.some((other) => other !== market && isClusterRelation(market, other));
789
+ return hasTeamTitledOutcomes(market) && ((_b = (_a = market.venueMarketOutcomes) == null ? void 0 : _a.length) != null ? _b : 0) >= legs.length && (markets.some((other) => other !== market && isClusterRelation(market, other)) || singleEnumeratesLegs(market, legs));
779
790
  }
780
791
  );
781
792
  return hasMergedSingle ? markets.filter((market) => !isDecomposedLeg(market)) : markets;
@@ -863,7 +874,7 @@ var isBinarySportsMoneylineMarket = (market) => {
863
874
  const aggKey = resolveSportsMarketAggKey(market);
864
875
  return sportsMarketType === "moneyline" && marketGroup === "game_lines" && normalizeSportsPeriod(market.period) === "full" && normalizedOutcomeLabels.length === 2 && normalizedOutcomeLabels.every((label) => YES_NO_LABELS.has(label)) && (marketSubtype === "moneyline" || REG_TIME_TITLE_PATTERN.test(question) || aggKey.includes("_ml_"));
865
876
  };
866
- var AGGKEY_LINE_TOKEN_PATTERN = /_\d+p\d+/g;
877
+ var AGGKEY_LINE_TOKEN_PATTERN = /_\d{1,3}(?:p\d+)?(?=_|$)/g;
867
878
  var resolveSportsLineFamilyKey = (market) => {
868
879
  const aggKey = resolveSportsMarketAggKey(market);
869
880
  return aggKey ? aggKey.replace(AGGKEY_LINE_TOKEN_PATTERN, "") : "";
@@ -872,18 +883,28 @@ var resolveSpreadFamilyKey = (market) => {
872
883
  const aggKey = resolveSportsMarketAggKey(market);
873
884
  return aggKey ? aggKey.replace(/_sp_.+$/i, "_sp") : "";
874
885
  };
875
- var resolveSpreadFavoredToken = (market) => {
876
- var _a, _b, _c;
877
- const aggKey = resolveSportsMarketAggKey(market);
878
- return (_c = (_b = (_a = aggKey.match(/_sp_([a-z0-9]+?)_\d+p\d+/i)) == null ? void 0 : _a[1]) == null ? void 0 : _b.toLowerCase()) != null ? _c : null;
886
+ var SPREAD_KEY_LEG_PATTERN = /_sp_([a-z0-9]+?)_([mp]?)(\d{1,3})(?:p(\d+))?(?:_|$)/i;
887
+ var resolveSpreadKeyLeg = (market) => {
888
+ const match = SPREAD_KEY_LEG_PATTERN.exec(resolveSportsMarketAggKey(market));
889
+ if (!match) return null;
890
+ const [, team, leg, whole, fraction] = match;
891
+ return {
892
+ team: team.toLowerCase(),
893
+ isFavorite: (leg == null ? void 0 : leg.toLowerCase()) !== "p",
894
+ line: Number(fraction ? `${whole}.${fraction}` : whole)
895
+ };
879
896
  };
880
- var resolveSpreadHomeToken = (markets) => {
897
+ var isSpreadUnderdogLeg = (market) => {
898
+ var _a;
899
+ return ((_a = resolveSpreadKeyLeg(market)) == null ? void 0 : _a.isFavorite) === false;
900
+ };
901
+ var resolveSpreadAnchorToken = (markets) => {
881
902
  var _a;
882
903
  const tokens = /* @__PURE__ */ new Set();
883
904
  let prefix = "";
884
905
  for (const market of markets) {
885
- const token = resolveSpreadFavoredToken(market);
886
- if (token) tokens.add(token);
906
+ const leg = resolveSpreadKeyLeg(market);
907
+ if (leg) tokens.add(leg.team);
887
908
  if (!prefix) prefix = (_a = resolveSportsMarketAggKey(market).split("_sp_")[0]) != null ? _a : "";
888
909
  }
889
910
  if (tokens.size === 0 || !prefix) return null;
@@ -910,17 +931,27 @@ var resolveSpreadOutcomeTeamNames = (activeMarket, groupMarkets) => {
910
931
  (longest, title) => title.length > longest.length ? title : longest
911
932
  );
912
933
  };
913
- return { favored: pickName(0), dog: pickName(1) };
934
+ const named = pickName(0);
935
+ const opponent = pickName(1);
936
+ return isSpreadUnderdogLeg(activeMarket) ? { favored: opponent, dog: named } : { favored: named, dog: opponent };
914
937
  };
915
938
  var resolveCombinedMoneylineLegLabel = (market) => {
916
939
  const typedMarket = market;
917
940
  return toTrimmedString(typedMarket.shortTitle) || toTrimmedString(market.question);
918
941
  };
919
- var areCombinedMoneylineLegsDistinct = (markets) => {
920
- const labels = markets.map((market) => resolveCombinedMoneylineLegLabel(market).toLowerCase());
921
- return labels.every((label) => label.length > 0) && new Set(labels).size === labels.length;
942
+ var normalizeSportsSubtypeToken = (subtype, sport) => {
943
+ const token = toTrimmedString(subtype).toLowerCase().replace(/^sports_/, "");
944
+ const sportToken = toTrimmedString(sport).toLowerCase();
945
+ return sportToken && token.startsWith(`${sportToken}_`) ? token.slice(sportToken.length + 1) : token;
922
946
  };
923
- var resolveDisplayGroupFamilyKey = (market) => {
947
+ var SPORTS_LEG_GROUPABLE_GROUPS = /* @__PURE__ */ new Set([
948
+ "game_lines",
949
+ "period_lines",
950
+ "team_props",
951
+ "specials",
952
+ "completion"
953
+ ]);
954
+ var resolveDisplayGroupFamilyKey = (market, sport) => {
924
955
  var _a, _b, _c;
925
956
  const normalizedQuestion = sanitizeFamilyValue(toTrimmedString(market.question));
926
957
  const outcomeKey = ((_a = market.venueMarketOutcomes) != null ? _a : []).map(
@@ -943,8 +974,24 @@ var resolveDisplayGroupFamilyKey = (market) => {
943
974
  if (market.lineValue != null || LINE_MARKET_TYPES.has(sportsMarketType)) {
944
975
  return lineFamily ? `${period}|${sportsMarketType}|${lineFamily}` : `${period}|${sportsMarketType}|${marketCategory}|${normalizedQuestion}|${outcomeKey}`;
945
976
  }
977
+ const marketGroup = normalizeSportsMarketGroup(market.marketGroup);
978
+ const legToken = marketGroup && SPORTS_LEG_GROUPABLE_GROUPS.has(marketGroup) && isDecomposedLeg(market) ? normalizeSportsSubtypeToken(market.marketSubtype, sport) : "";
979
+ if (legToken) {
980
+ return `${period}|leg|${marketGroup}|${legToken}`;
981
+ }
982
+ return resolveMarketOwnCardKey(market);
983
+ };
984
+ var resolveMarketOwnCardKey = (market) => {
985
+ var _a, _b, _c;
986
+ const outcomeKey = ((_a = market.venueMarketOutcomes) != null ? _a : []).map(
987
+ (outcome) => sanitizeFamilyValue(toTrimmedString(outcome.title) || toTrimmedString(outcome.label))
988
+ ).filter(Boolean).sort((left, right) => left.localeCompare(right)).join("|");
989
+ const sportsMarketType = (_b = normalizeSportsMarketType(market.sportsMarketType)) != null ? _b : "other";
990
+ const period = normalizeSportsPeriod(market.period);
991
+ const marketCategory = (_c = normalizeSportsMarketCategory(market.marketCategory)) != null ? _c : "other";
946
992
  return `${period}|${sportsMarketType}|${marketCategory}|${toTrimmedString(market.question)}|${outcomeKey}|${market.id}`;
947
993
  };
994
+ var LEG_GROUP_KEY_MARKER = "|leg|";
948
995
  var TOTAL_STAT_UNITS = [
949
996
  [/\bcorners?\b/i, "Corners"],
950
997
  [/\bcards?\b|\bbookings?\b/i, "Cards"],
@@ -966,12 +1013,24 @@ var resolveTotalStatUnit = (markets, marketCategory) => {
966
1013
  }
967
1014
  return null;
968
1015
  };
969
- var resolveDisplayGroupTitle = (market, groupMarkets = [market]) => {
1016
+ var SPORTS_LEG_TITLE_OVERRIDES = { nrfi: "NRFI" };
1017
+ var SPORTS_LEG_TITLE_SMALL_WORDS = /* @__PURE__ */ new Set(["to", "the", "of", "in", "at", "a", "and", "or"]);
1018
+ var formatSportsLegTitle = (token) => {
1019
+ var _a;
1020
+ return (_a = SPORTS_LEG_TITLE_OVERRIDES[token]) != null ? _a : token.split("_").filter(Boolean).map(
1021
+ (word, index) => index > 0 && SPORTS_LEG_TITLE_SMALL_WORDS.has(word) ? word : word.charAt(0).toUpperCase() + word.slice(1)
1022
+ ).join(" ");
1023
+ };
1024
+ var resolveDisplayGroupTitle = (market, groupMarkets = [market], sport, isCombinedLegGroup = false) => {
970
1025
  const sportsMarketType = normalizeSportsMarketType(market.sportsMarketType);
971
1026
  const question = toTrimmedString(market.question);
972
1027
  if (isBinarySportsMoneylineMarket(market)) return "Moneyline";
973
1028
  if (sportsMarketType === "to_advance") return "Team to Advance";
974
1029
  if (sportsMarketType === "spread") return "Spreads";
1030
+ if (isCombinedLegGroup) {
1031
+ const legToken = normalizeSportsSubtypeToken(market.marketSubtype, sport);
1032
+ if (legToken) return formatSportsLegTitle(legToken);
1033
+ }
975
1034
  if (!question) {
976
1035
  return sportsMarketType != null ? sportsMarketType : market.id;
977
1036
  }
@@ -1002,26 +1061,65 @@ var sortMarketsByLineValue = (markets) => {
1002
1061
  return leftMarket.question.localeCompare(rightMarket.question);
1003
1062
  });
1004
1063
  };
1005
- var buildSportsMarketDisplayGroups = (markets) => {
1006
- var _a;
1064
+ var buildSportsMarketDisplayGroups = (markets, sport) => {
1065
+ var _a, _b, _c, _d, _e;
1007
1066
  const groupsByKey = /* @__PURE__ */ new Map();
1008
1067
  for (const market of markets) {
1009
- const groupKey = resolveDisplayGroupFamilyKey(market);
1068
+ const groupKey = resolveDisplayGroupFamilyKey(market, sport);
1010
1069
  const currentMarkets = (_a = groupsByKey.get(groupKey)) != null ? _a : [];
1011
1070
  currentMarkets.push(market);
1012
1071
  groupsByKey.set(groupKey, currentMarkets);
1013
1072
  }
1073
+ const VENUE_SPLIT_MARKER = "|venue:";
1074
+ const pending = Array.from(groupsByKey.keys());
1075
+ while (pending.length > 0) {
1076
+ const groupKey = pending.pop();
1077
+ if (groupKey == null) continue;
1078
+ const groupMarkets = groupsByKey.get(groupKey);
1079
+ if (!groupMarkets || groupMarkets.length === 0) continue;
1080
+ const isLegBucket = groupKey.includes(LEG_GROUP_KEY_MARKER);
1081
+ const combinable = groupMarkets.length > 1 ? resolveSportsCombinedLegs({
1082
+ markets: groupMarkets,
1083
+ sportsMarketType: normalizeSportsMarketType((_b = groupMarkets[0]) == null ? void 0 : _b.sportsMarketType)
1084
+ }) : null;
1085
+ if (groupMarkets.length > 1) {
1086
+ if (groupMarkets.some((market) => market.lineValue != null)) continue;
1087
+ if (!combinable && groupMarkets.some((market) => hasTeamTitledOutcomes(market))) continue;
1088
+ const marketsPerVenue = /* @__PURE__ */ new Map();
1089
+ for (const market of groupMarkets) {
1090
+ marketsPerVenue.set(market.venue, [...(_c = marketsPerVenue.get(market.venue)) != null ? _c : [], market]);
1091
+ }
1092
+ const mostFromOneVenue = Math.max(...Array.from(marketsPerVenue.values(), (m) => m.length));
1093
+ if (combinable && combinable.length <= mostFromOneVenue) continue;
1094
+ if (marketsPerVenue.size > 1) {
1095
+ groupsByKey.delete(groupKey);
1096
+ for (const [venue, venueMarkets] of marketsPerVenue) {
1097
+ const venueKey = `${groupKey}${VENUE_SPLIT_MARKER}${venue}`;
1098
+ groupsByKey.set(venueKey, [...(_d = groupsByKey.get(venueKey)) != null ? _d : [], ...venueMarkets]);
1099
+ pending.push(venueKey);
1100
+ }
1101
+ continue;
1102
+ }
1103
+ }
1104
+ if (isLegBucket && !combinable) {
1105
+ groupsByKey.delete(groupKey);
1106
+ for (const market of groupMarkets) {
1107
+ const ownKey = resolveMarketOwnCardKey(market);
1108
+ groupsByKey.set(ownKey, [...(_e = groupsByKey.get(ownKey)) != null ? _e : [], market]);
1109
+ }
1110
+ }
1111
+ }
1014
1112
  const groups = Array.from(groupsByKey.entries()).map(([id, groupMarkets]) => {
1015
1113
  var _a2;
1016
1114
  const isToAdvanceGroup = groupMarkets.some(
1017
1115
  (market) => normalizeSportsMarketType(market.sportsMarketType) === "to_advance"
1018
1116
  );
1019
1117
  const orderedMarkets = isToAdvanceGroup ? [...groupMarkets].sort((left, right) => {
1020
- var _a3, _b;
1118
+ var _a3, _b2;
1021
1119
  const leftSingle = resolveSportsMarketAggKey(left).endsWith("_adv") ? 0 : 1;
1022
1120
  const rightSingle = resolveSportsMarketAggKey(right).endsWith("_adv") ? 0 : 1;
1023
1121
  if (leftSingle !== rightSingle) return leftSingle - rightSingle;
1024
- return ((_a3 = right.volume) != null ? _a3 : 0) - ((_b = left.volume) != null ? _b : 0);
1122
+ return ((_a3 = right.volume) != null ? _a3 : 0) - ((_b2 = left.volume) != null ? _b2 : 0);
1025
1123
  }) : sortMarketsByLineValue(groupMarkets);
1026
1124
  const firstMarket = orderedMarkets[0];
1027
1125
  const sportsMarketType = normalizeSportsMarketType(firstMarket == null ? void 0 : firstMarket.sportsMarketType);
@@ -1030,7 +1128,12 @@ var buildSportsMarketDisplayGroups = (markets) => {
1030
1128
  const sectionRank = (_a2 = firstMarket == null ? void 0 : firstMarket.sectionRank) != null ? _a2 : Number.MAX_SAFE_INTEGER;
1031
1129
  return {
1032
1130
  id,
1033
- title: resolveDisplayGroupTitle(firstMarket, orderedMarkets),
1131
+ title: resolveDisplayGroupTitle(
1132
+ firstMarket,
1133
+ orderedMarkets,
1134
+ id.includes(LEG_GROUP_KEY_MARKER) ? sport : void 0,
1135
+ id.includes(LEG_GROUP_KEY_MARKER)
1136
+ ),
1034
1137
  questionKey: sanitizeFamilyValue(toTrimmedString(firstMarket == null ? void 0 : firstMarket.question)),
1035
1138
  sportsMarketType,
1036
1139
  marketCategory,
@@ -1041,7 +1144,7 @@ var buildSportsMarketDisplayGroups = (markets) => {
1041
1144
  };
1042
1145
  });
1043
1146
  return groups.sort((leftGroup, rightGroup) => {
1044
- var _a2, _b, _c, _d;
1147
+ var _a2, _b2, _c2, _d2;
1045
1148
  if (leftGroup.sectionRank !== rightGroup.sectionRank) {
1046
1149
  return leftGroup.sectionRank - rightGroup.sectionRank;
1047
1150
  }
@@ -1050,15 +1153,15 @@ var buildSportsMarketDisplayGroups = (markets) => {
1050
1153
  if (leftMarketTypeOrder !== rightMarketTypeOrder) {
1051
1154
  return leftMarketTypeOrder - rightMarketTypeOrder;
1052
1155
  }
1053
- const leftLineValue = (_b = (_a2 = leftGroup.markets[0]) == null ? void 0 : _a2.lineValue) != null ? _b : Number.NEGATIVE_INFINITY;
1054
- const rightLineValue = (_d = (_c = rightGroup.markets[0]) == null ? void 0 : _c.lineValue) != null ? _d : Number.NEGATIVE_INFINITY;
1156
+ const leftLineValue = (_b2 = (_a2 = leftGroup.markets[0]) == null ? void 0 : _a2.lineValue) != null ? _b2 : Number.NEGATIVE_INFINITY;
1157
+ const rightLineValue = (_d2 = (_c2 = rightGroup.markets[0]) == null ? void 0 : _c2.lineValue) != null ? _d2 : Number.NEGATIVE_INFINITY;
1055
1158
  if (leftLineValue !== rightLineValue) {
1056
1159
  return leftLineValue - rightLineValue;
1057
1160
  }
1058
1161
  return leftGroup.title.localeCompare(rightGroup.title);
1059
1162
  });
1060
1163
  };
1061
- var groupSportsMarketsByPeriod = (markets) => {
1164
+ var groupSportsMarketsByPeriod = (markets, sport) => {
1062
1165
  var _a;
1063
1166
  const periodGroups = /* @__PURE__ */ new Map();
1064
1167
  for (const market of markets) {
@@ -1070,7 +1173,7 @@ var groupSportsMarketsByPeriod = (markets) => {
1070
1173
  return Array.from(periodGroups.entries()).map(([key, groupedMarkets]) => ({
1071
1174
  key,
1072
1175
  markets: groupedMarkets,
1073
- groups: buildSportsMarketDisplayGroups(groupedMarkets)
1176
+ groups: buildSportsMarketDisplayGroups(groupedMarkets, sport)
1074
1177
  })).sort((leftGroup, rightGroup) => {
1075
1178
  return getSportsPeriodOrderIndex(leftGroup.key) - getSportsPeriodOrderIndex(rightGroup.key);
1076
1179
  });
@@ -1129,6 +1232,57 @@ var resolveHighestVolumeIndex = (markets) => {
1129
1232
  });
1130
1233
  return bestIndex;
1131
1234
  };
1235
+ var resolveSportsCombinedLegs = (group) => {
1236
+ var _a;
1237
+ if (group.markets.some((market) => market.lineValue != null)) return null;
1238
+ const isMoneylineGroup = group.sportsMarketType === "moneyline" && group.markets.every((market) => isBinarySportsMoneylineMarket(market));
1239
+ const legs = group.markets.filter(
1240
+ (market) => isMoneylineGroup ? isBinarySportsMoneylineMarket(market) : isDecomposedLeg(market)
1241
+ );
1242
+ if (legs.length < 2 || legs.length !== group.markets.length) return null;
1243
+ if (!isMoneylineGroup) {
1244
+ const legsPerVenue = /* @__PURE__ */ new Map();
1245
+ for (const leg of legs) {
1246
+ legsPerVenue.set(leg.venue, ((_a = legsPerVenue.get(leg.venue)) != null ? _a : 0) + 1);
1247
+ }
1248
+ const isDecomposition = Array.from(legsPerVenue.values()).some((count) => count > 1);
1249
+ if (!isDecomposition) return null;
1250
+ }
1251
+ const twinSets = [];
1252
+ for (const leg of legs) {
1253
+ const legQuestion = sanitizeFamilyValue(toTrimmedString(leg.question));
1254
+ const twins = twinSets.find(
1255
+ (candidates) => candidates.some(
1256
+ (candidate) => (
1257
+ // CROSS-VENUE only. A venue never lists one leg twice, so two legs
1258
+ // from the SAME venue are always different bets — and they routinely
1259
+ // reference each other through their absent merged anchor, so the
1260
+ // cluster test alone would fold a 2-way decomposition down to one
1261
+ // pill and drop a team off the card.
1262
+ candidate.venue !== leg.venue && (isClusterRelation(candidate, leg) || legQuestion.length > 0 && sanitizeFamilyValue(toTrimmedString(candidate.question)) === legQuestion)
1263
+ )
1264
+ )
1265
+ );
1266
+ if (twins) twins.push(leg);
1267
+ else twinSets.push([leg]);
1268
+ }
1269
+ const pills = twinSets.map((twins) => {
1270
+ var _a2;
1271
+ const market = (_a2 = twins[resolveHighestVolumeIndex(twins)]) != null ? _a2 : twins[0];
1272
+ const label = twins.map((twin) => resolveCombinedMoneylineLegLabel(twin)).reduce(
1273
+ (longest, candidate) => candidate.length > longest.length ? candidate : longest,
1274
+ ""
1275
+ );
1276
+ const venues = /* @__PURE__ */ new Set();
1277
+ for (const twin of twins) {
1278
+ for (const venue of collectVenueNames(twin)) venues.add(venue);
1279
+ }
1280
+ return { label, market, venues: Array.from(venues) };
1281
+ });
1282
+ const labels = pills.map((pill) => pill.label.toLowerCase());
1283
+ if (pills.length < 2 || labels.some((label) => !label)) return null;
1284
+ return new Set(labels).size === labels.length ? pills : null;
1285
+ };
1132
1286
  var resolveSlideKind = (group) => {
1133
1287
  if (group.sportsMarketType === "to_advance") return "to_advance";
1134
1288
  if (group.sportsMarketType === "moneyline") return "moneyline";
@@ -1138,21 +1292,23 @@ var resolveSlideKind = (group) => {
1138
1292
  };
1139
1293
  var aggregateSportsLineStops = (markets, isSpread = false) => {
1140
1294
  var _a;
1141
- const homeToken = isSpread ? resolveSpreadHomeToken(markets) : null;
1295
+ const anchorToken = isSpread ? resolveSpreadAnchorToken(markets) : null;
1142
1296
  const axisOf = (market) => {
1143
- var _a2, _b;
1144
- if (homeToken) {
1145
- const favored = resolveSpreadFavoredToken(market);
1146
- if (favored) {
1147
- const magnitude = Math.abs((_a2 = market.lineValue) != null ? _a2 : 0);
1148
- return favored === homeToken ? -magnitude : magnitude;
1297
+ var _a2;
1298
+ if (anchorToken) {
1299
+ const leg = resolveSpreadKeyLeg(market);
1300
+ if (leg) {
1301
+ const anchorGivesPoints = leg.team === anchorToken ? leg.isFavorite : !leg.isFavorite;
1302
+ return anchorGivesPoints ? -leg.line : leg.line;
1149
1303
  }
1150
1304
  }
1151
- return (_b = market.lineValue) != null ? _b : Number.NEGATIVE_INFINITY;
1305
+ return (_a2 = market.lineValue) != null ? _a2 : Number.NEGATIVE_INFINITY;
1152
1306
  };
1153
1307
  const displayOf = (market) => {
1154
1308
  var _a2;
1155
- return homeToken ? resolveSelectedSportsLineValue(Math.abs((_a2 = market.lineValue) != null ? _a2 : 0)) : resolveSelectedSportsLineValue(market.lineValue);
1309
+ if (!anchorToken) return resolveSelectedSportsLineValue(market.lineValue);
1310
+ const leg = resolveSpreadKeyLeg(market);
1311
+ return resolveSelectedSportsLineValue(leg ? leg.line : Math.abs((_a2 = market.lineValue) != null ? _a2 : 0));
1156
1312
  };
1157
1313
  const marketsByAxis = /* @__PURE__ */ new Map();
1158
1314
  for (const market of markets) {
@@ -1530,10 +1686,11 @@ var resolveSpreadHeaderOutcomeItems = ({
1530
1686
  if (!favored && !dog) return void 0;
1531
1687
  const magnitude = Math.abs(lineValue);
1532
1688
  const formatLine = (value) => `${value > 0 ? "+" : "\u2212"}${Number.isInteger(magnitude) ? String(magnitude) : magnitude.toFixed(1)}`;
1689
+ const isDogLeg = isSpreadUnderdogLeg(market);
1533
1690
  return [
1534
- { index: 0, name: favored, signedLine: -magnitude },
1535
- { index: 1, name: dog, signedLine: magnitude }
1536
- ].flatMap(({ index, name, signedLine }) => {
1691
+ { index: isDogLeg ? 1 : 0, name: favored, signedLine: -magnitude, tone: "positive" },
1692
+ { index: isDogLeg ? 0 : 1, name: dog, signedLine: magnitude, tone: "negative" }
1693
+ ].flatMap(({ index, name, signedLine, tone }) => {
1537
1694
  var _a2;
1538
1695
  const outcome = outcomes[index];
1539
1696
  if (!outcome) return [];
@@ -1551,7 +1708,7 @@ var resolveSpreadHeaderOutcomeItems = ({
1551
1708
  lineLabel: formatLine(signedLine),
1552
1709
  probability,
1553
1710
  isPriceLoading: (midpointsResult == null ? void 0 : midpointsResult.isLoading) === true && probability == null,
1554
- tone: index === 0 ? "positive" : "negative",
1711
+ tone,
1555
1712
  variant: "line",
1556
1713
  venue: market.venue
1557
1714
  }
@@ -1603,7 +1760,7 @@ var SportsMarketCard = ({
1603
1760
  midpointsFallbackVenues,
1604
1761
  midpointsResult
1605
1762
  }) => {
1606
- var _a, _b, _c, _d, _e, _f, _g;
1763
+ var _a, _b, _c, _d, _e, _f, _g, _h;
1607
1764
  const labels = useLabels2();
1608
1765
  const {
1609
1766
  formatting: { formatCompactCurrency }
@@ -1611,27 +1768,27 @@ var SportsMarketCard = ({
1611
1768
  const tradingContext = useEventTradingContext();
1612
1769
  const slide = useMemo(() => buildSportsSlideFromGroup(group), [group]);
1613
1770
  const [selectedLineIndex, setSelectedLineIndex] = useState3(slide.defaultStopIndex);
1614
- const combinedMoneylineMarkets = useMemo(
1615
- () => group.markets.filter((market) => isBinarySportsMoneylineMarket(market)),
1616
- [group.markets]
1771
+ const combinedLegs = useMemo(() => resolveSportsCombinedLegs(group), [group]);
1772
+ const isCombinedLegGroup = combinedLegs != null;
1773
+ const combinedLegMarkets = useMemo(
1774
+ () => {
1775
+ var _a2;
1776
+ return (_a2 = combinedLegs == null ? void 0 : combinedLegs.map((leg) => leg.market)) != null ? _a2 : [];
1777
+ },
1778
+ [combinedLegs]
1617
1779
  );
1618
- const isCombinedMoneylineGroup = group.sportsMarketType === "moneyline" && combinedMoneylineMarkets.length > 1 && combinedMoneylineMarkets.length === group.markets.length && // Per-leg pills need distinct labels — unmerged cross-venue duplicates of
1619
- // one 2-way single ("Match Winner" ×2) would render the same Yes price
1620
- // twice as two options; fall back to the standard team-pill card instead.
1621
- areCombinedMoneylineLegsDistinct(combinedMoneylineMarkets);
1622
- const preferredResolvedMoneylineMarket = useMemo(() => {
1780
+ const preferredResolvedLegMarket = useMemo(() => {
1623
1781
  var _a2, _b2;
1624
- if (!isCombinedMoneylineGroup) return null;
1625
- const resolvedYesWinnerMarket = (_a2 = combinedMoneylineMarkets.find(
1782
+ const resolvedYesWinnerMarket = (_a2 = combinedLegMarkets.find(
1626
1783
  (market) => market.venueMarketOutcomes.some(
1627
1784
  (outcome) => outcome.winner === true && outcome.label.trim().toLowerCase() === "yes"
1628
1785
  )
1629
1786
  )) != null ? _a2 : null;
1630
1787
  if (resolvedYesWinnerMarket) return resolvedYesWinnerMarket;
1631
- return (_b2 = combinedMoneylineMarkets.find(
1788
+ return (_b2 = combinedLegMarkets.find(
1632
1789
  (market) => market.venueMarketOutcomes.some((outcome) => outcome.winner === true)
1633
1790
  )) != null ? _b2 : null;
1634
- }, [combinedMoneylineMarkets, isCombinedMoneylineGroup]);
1791
+ }, [combinedLegMarkets]);
1635
1792
  useEffect3(() => {
1636
1793
  if (!slide.hasLadder) return;
1637
1794
  const tradingMarketId = tradingContext == null ? void 0 : tradingContext.selectedMarketId;
@@ -1639,11 +1796,11 @@ var SportsMarketCard = ({
1639
1796
  const matchedIndex = slide.stops.findIndex((stop) => stop.market.id === tradingMarketId);
1640
1797
  if (matchedIndex >= 0) setSelectedLineIndex(matchedIndex);
1641
1798
  }, [slide.hasLadder, slide.stops, tradingContext == null ? void 0 : tradingContext.selectedMarketId]);
1642
- const activeMoneylineMarket = isCombinedMoneylineGroup ? preferredResolvedMoneylineMarket != null ? preferredResolvedMoneylineMarket : (tradingContext == null ? void 0 : tradingContext.selectedMarketId) ? (_a = group.markets.find((market) => market.id === tradingContext.selectedMarketId)) != null ? _a : null : null : null;
1643
- const activeMarket = slide.hasLadder ? (_d = (_c = (_b = slide.stops[selectedLineIndex]) == null ? void 0 : _b.market) != null ? _c : group.markets[0]) != null ? _d : null : (_e = activeMoneylineMarket != null ? activeMoneylineMarket : group.markets[0]) != null ? _e : null;
1644
- const activeDefaultOutcome = isCombinedMoneylineGroup && activeMarket ? (_f = activeMarket.venueMarketOutcomes.find(
1799
+ const activeLegMarket = isCombinedLegGroup ? preferredResolvedLegMarket != null ? preferredResolvedLegMarket : (tradingContext == null ? void 0 : tradingContext.selectedMarketId) ? (_a = group.markets.find((market) => market.id === tradingContext.selectedMarketId)) != null ? _a : null : null : null;
1800
+ const activeMarket = slide.hasLadder ? (_d = (_c = (_b = slide.stops[selectedLineIndex]) == null ? void 0 : _b.market) != null ? _c : group.markets[0]) != null ? _d : null : (_f = (_e = activeLegMarket != null ? activeLegMarket : combinedLegMarkets[0]) != null ? _e : group.markets[0]) != null ? _f : null;
1801
+ const activeDefaultOutcome = isCombinedLegGroup && activeMarket ? (_g = activeMarket.venueMarketOutcomes.find(
1645
1802
  (outcome) => outcome.label.trim().toLowerCase() === "yes"
1646
- )) != null ? _f : activeMarket.venueMarketOutcomes[0] : activeMarket == null ? void 0 : activeMarket.venueMarketOutcomes[0];
1803
+ )) != null ? _g : activeMarket.venueMarketOutcomes[0] : activeMarket == null ? void 0 : activeMarket.venueMarketOutcomes[0];
1647
1804
  const wasExpandedRef = useRef2(isExpanded);
1648
1805
  useEffect3(() => {
1649
1806
  const justOpened = isExpanded && !wasExpandedRef.current;
@@ -1658,16 +1815,14 @@ var SportsMarketCard = ({
1658
1815
  tradingContext == null ? void 0 : tradingContext.selectMarketAndOutcome(activeMarket.id, firstOutcome.id);
1659
1816
  }
1660
1817
  }, [activeDefaultOutcome, isExpanded, activeMarket, tradingContext]);
1661
- const combinedMoneylineHeaderOutcomeItems = useMemo(() => {
1662
- if (!isCombinedMoneylineGroup) return void 0;
1663
- return combinedMoneylineMarkets.flatMap((market, index) => {
1818
+ const combinedLegHeaderOutcomeItems = useMemo(() => {
1819
+ if (!combinedLegs) return void 0;
1820
+ return combinedLegs.flatMap(({ label, market }, index) => {
1664
1821
  var _a2;
1665
1822
  const yesOutcome = market.venueMarketOutcomes.find(
1666
1823
  (outcome) => outcome.label.trim().toLowerCase() === "yes"
1667
1824
  );
1668
1825
  if (!yesOutcome) return [];
1669
- const label = resolveCombinedMoneylineLegLabel(market);
1670
- if (!label) return [];
1671
1826
  const probability = midpointsResult == null ? void 0 : getDisplayOutcomePrice({
1672
1827
  outcomeId: yesOutcome.id,
1673
1828
  outcomeLabel: yesOutcome.label,
@@ -1686,7 +1841,7 @@ var SportsMarketCard = ({
1686
1841
  }
1687
1842
  ];
1688
1843
  });
1689
- }, [combinedMoneylineMarkets, isCombinedMoneylineGroup, midpointsResult]);
1844
+ }, [combinedLegs, midpointsResult]);
1690
1845
  const spreadHeaderOutcomeItems = useMemo(() => {
1691
1846
  if (slide.kind !== "spread" || !activeMarket) return void 0;
1692
1847
  return resolveSpreadHeaderOutcomeItems({
@@ -1696,9 +1851,9 @@ var SportsMarketCard = ({
1696
1851
  });
1697
1852
  }, [slide.kind, activeMarket, group.markets, midpointsResult]);
1698
1853
  if (!activeMarket) return null;
1699
- const activeOutcome = (_g = activeMarket.venueMarketOutcomes.find(
1854
+ const activeOutcome = (_h = activeMarket.venueMarketOutcomes.find(
1700
1855
  (outcome) => outcome.id === (tradingContext == null ? void 0 : tradingContext.selectedOutcomeId)
1701
- )) != null ? _g : activeDefaultOutcome;
1856
+ )) != null ? _h : activeDefaultOutcome;
1702
1857
  const activeOutcomeVenueCount = (() => {
1703
1858
  var _a2, _b2;
1704
1859
  if (!activeOutcome) return collectVenueNames(activeMarket).length;
@@ -1716,8 +1871,8 @@ var SportsMarketCard = ({
1716
1871
  const activeMarketVolume = resolveSportsExpandedMarketsVolume([activeMarket]);
1717
1872
  const totalGroupVolume = resolveSportsExpandedMarketsVolume(group.markets);
1718
1873
  const compactSubtitle = `${activeOutcomeVenueCount} ${activeOutcomeVenueCount === 1 ? labels.marketDetails.meta.venueSingular : labels.marketDetails.meta.venuePlural} \xB7 ${formatCompactCurrency(activeMarketVolume || resolveTotalGroupVolume([activeMarket]))} ${labels.eventMarketPage.sports.volumeShort} \xB7 ${formatCompactCurrency(totalGroupVolume || resolveTotalGroupVolume(group.markets))} ${labels.eventMarketPage.sports.totalVolumeShort}`;
1719
- const headerOutcomeItemsOverride = combinedMoneylineHeaderOutcomeItems != null ? combinedMoneylineHeaderOutcomeItems : spreadHeaderOutcomeItems;
1720
- const headerOutcomeVariant = isCombinedMoneylineGroup ? "outcome" : resolveSportsMarketCardVariant(activeMarket);
1874
+ const headerOutcomeItemsOverride = combinedLegHeaderOutcomeItems != null ? combinedLegHeaderOutcomeItems : spreadHeaderOutcomeItems;
1875
+ const headerOutcomeVariant = isCombinedLegGroup ? "outcome" : resolveSportsMarketCardVariant(activeMarket);
1721
1876
  const handleLineSelect = (index) => {
1722
1877
  var _a2, _b2, _c2;
1723
1878
  const targetMarket = (_a2 = slide.stops[index]) == null ? void 0 : _a2.market;
@@ -1807,6 +1962,23 @@ var LEGACY_STAT_LABEL_KEYS = {
1807
1962
  assists: "assistsTab",
1808
1963
  shots: "shotsTab"
1809
1964
  };
1965
+ var SPORTS_PERIOD_LABEL_KEYS = {
1966
+ full: "fullPeriod",
1967
+ "1h": "firstHalfPeriod",
1968
+ "2h": "secondHalfPeriod",
1969
+ q1: "quarterOnePeriod",
1970
+ q2: "quarterTwoPeriod",
1971
+ q3: "quarterThreePeriod",
1972
+ q4: "quarterFourPeriod",
1973
+ ot: "overtimePeriod"
1974
+ };
1975
+ var resolveSportsPeriodLabel = (labels, period) => {
1976
+ var _a;
1977
+ const sports = labels.eventMarketPage.sports;
1978
+ const labelKey = SPORTS_PERIOD_LABEL_KEYS[period];
1979
+ if (labelKey && typeof sports[labelKey] === "string") return sports[labelKey];
1980
+ return (_a = formatSportsPeriodGrammarLabel(period)) != null ? _a : formatStatLabel(period);
1981
+ };
1810
1982
  var resolveSportsSectionLabel = (labels, tab) => {
1811
1983
  var _a, _b, _c, _d, _e;
1812
1984
  const sports = labels.eventMarketPage.sports;
@@ -1974,8 +2146,8 @@ var SportsMarkets = ({
1974
2146
  [stableSectionMarkets, isSectionSettled, resolvedSectionMarkets]
1975
2147
  );
1976
2148
  const periodGroups = useMemo2(
1977
- () => groupSportsMarketsByPeriod(displayedSectionMarkets),
1978
- [displayedSectionMarkets]
2149
+ () => groupSportsMarketsByPeriod(displayedSectionMarkets, event.sport),
2150
+ [displayedSectionMarkets, event.sport]
1979
2151
  );
1980
2152
  const allGroups = useMemo2(
1981
2153
  () => periodGroups.flatMap((periodGroup) => periodGroup.groups),
@@ -2084,24 +2256,34 @@ var SportsMarkets = ({
2084
2256
  }
2085
2257
  ) : null,
2086
2258
  periodGroups.map((periodGroup) => {
2087
- return /* @__PURE__ */ jsx4(
2259
+ return /* @__PURE__ */ jsxs3(
2088
2260
  "section",
2089
2261
  {
2090
2262
  className: "flex flex-col gap-3",
2091
2263
  "data-period-key": periodGroup.key,
2092
- children: periodGroup.groups.map((group) => /* @__PURE__ */ jsx4(
2093
- SportsMarketCard,
2094
- {
2095
- group,
2096
- venueMarkets: displayedSectionMarkets,
2097
- isExpanded: expandedGroupId === group.id,
2098
- onToggle: handleToggleGroup,
2099
- onOutcomeSelect: (_groupId, _selection) => handleGroupOutcomeSelect(group.id),
2100
- live,
2101
- midpointsResult
2102
- },
2103
- group.id
2104
- ))
2264
+ children: [
2265
+ periodGroups.length > 1 ? /* @__PURE__ */ jsx4(
2266
+ "h3",
2267
+ {
2268
+ "data-testid": "sports-period-heading",
2269
+ className: "text-agg-sm font-agg-bold leading-agg-5 text-agg-muted-foreground",
2270
+ children: resolveSportsPeriodLabel(labels, periodGroup.key)
2271
+ }
2272
+ ) : null,
2273
+ periodGroup.groups.map((group) => /* @__PURE__ */ jsx4(
2274
+ SportsMarketCard,
2275
+ {
2276
+ group,
2277
+ venueMarkets: displayedSectionMarkets,
2278
+ isExpanded: expandedGroupId === group.id,
2279
+ onToggle: handleToggleGroup,
2280
+ onOutcomeSelect: (_groupId, _selection) => handleGroupOutcomeSelect(group.id),
2281
+ live,
2282
+ midpointsResult
2283
+ },
2284
+ group.id
2285
+ ))
2286
+ ]
2105
2287
  },
2106
2288
  `${activeTabKey}-${periodGroup.key}`
2107
2289
  );
@@ -3817,7 +3999,8 @@ var CLAIM_VENUE_LABELS = {
3817
3999
  [Venue.probable]: "Probable",
3818
4000
  [Venue.myriad]: "Myriad",
3819
4001
  [Venue.hyperliquid]: "Hyperliquid",
3820
- [Venue.novig]: "Novig"
4002
+ [Venue.novig]: "Novig",
4003
+ [Venue.prophetx]: "ProphetX"
3821
4004
  };
3822
4005
  var ClaimActivityBreakdownModal = ({
3823
4006
  activity,
@@ -3971,7 +4154,8 @@ var VENUE_LABELS = {
3971
4154
  [Venue2.probable]: "Probable",
3972
4155
  [Venue2.myriad]: "Myriad",
3973
4156
  [Venue2.hyperliquid]: "Hyperliquid",
3974
- [Venue2.novig]: "Novig"
4157
+ [Venue2.novig]: "Novig",
4158
+ [Venue2.prophetx]: "ProphetX"
3975
4159
  };
3976
4160
  var amountSchema = z2.string().min(1).regex(FINAL_AMOUNT_PATTERN);
3977
4161
  var decimalToRaw = (value, decimals = USDC_DECIMALS) => {
@@ -19,7 +19,7 @@ import {
19
19
  selectPrimaryVenueMarket,
20
20
  skeletonViews,
21
21
  sortOutcomes
22
- } from "./chunk-RDBMHBR2.mjs";
22
+ } from "./chunk-UQ7XJIAZ.mjs";
23
23
 
24
24
  // src/trading/trading-context/index.tsx
25
25
  import { useEventTradingContext } from "@agg-build/hooks";