@agg-build/ui 4.11.1 → 4.13.2

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.
@@ -1039,6 +1039,8 @@ import {
1039
1039
  } from "@agg-build/hooks";
1040
1040
  var PRICE_PRECISION = 1e6;
1041
1041
  var SIZE_PRECISION = 1e8;
1042
+ var DISPLAY_PRICE_BUCKETS_PER_UNIT = 1e3;
1043
+ var DISPLAY_ROUNDING_PRECISION = 1e9;
1042
1044
  var POSITIVE_OUTCOME_KEYS = /* @__PURE__ */ new Set(["yes", "y", "true", "up", "buy", "long"]);
1043
1045
  var NEGATIVE_OUTCOME_KEYS = /* @__PURE__ */ new Set(["no", "n", "false", "down", "sell", "short"]);
1044
1046
  var roundTo = (value, precision) => {
@@ -1053,6 +1055,10 @@ var fromScaled = (value, precision) => {
1053
1055
  var toPriceKey = (price) => {
1054
1056
  return String(toScaled(price, PRICE_PRECISION));
1055
1057
  };
1058
+ var toDisplayPrice = (price) => {
1059
+ const bucketSize = DISPLAY_ROUNDING_PRECISION / DISPLAY_PRICE_BUCKETS_PER_UNIT;
1060
+ return Math.round(toScaled(price, DISPLAY_ROUNDING_PRECISION) / bucketSize) / DISPLAY_PRICE_BUCKETS_PER_UNIT;
1061
+ };
1056
1062
  var normalizeOutcomeLabel = (value) => {
1057
1063
  if (typeof value !== "string") return "";
1058
1064
  return value.trim().toLowerCase().replace(/[_-]+/g, " ").replace(/[^\p{L}\p{N}\s]/gu, " ").replace(/\s+/g, " ");
@@ -1166,7 +1172,7 @@ var buildRowsFromAccumulator = ({
1166
1172
  venues,
1167
1173
  price: roundTo(level.price, PRICE_PRECISION),
1168
1174
  size,
1169
- total: roundTo(level.price * size, SIZE_PRECISION),
1175
+ total: roundTo(level.notional, SIZE_PRECISION),
1170
1176
  tone,
1171
1177
  barScale: 0,
1172
1178
  venueBreakdown,
@@ -1184,6 +1190,7 @@ var accumulateSideLevels = ({
1184
1190
  orderbooksByOutcomeId
1185
1191
  }) => {
1186
1192
  const levelsByPrice = /* @__PURE__ */ new Map();
1193
+ let bestPrice = null;
1187
1194
  const includedOutcomeIds = /* @__PURE__ */ new Set();
1188
1195
  const missingOutcomeIds = /* @__PURE__ */ new Set();
1189
1196
  eligibleOutcomes.forEach((eligibleOutcome) => {
@@ -1199,18 +1206,25 @@ var accumulateSideLevels = ({
1199
1206
  includedOutcomeIds.add(eligibleOutcome.outcomeId);
1200
1207
  venueLevels.forEach((level) => {
1201
1208
  var _a;
1202
- const priceKey = toPriceKey(level.price);
1209
+ if (bestPrice == null || (side === "asks" ? level.price < bestPrice : level.price > bestPrice)) {
1210
+ bestPrice = level.price;
1211
+ }
1212
+ const displayPrice = toDisplayPrice(level.price);
1213
+ const priceKey = toPriceKey(displayPrice);
1203
1214
  const scaledSize = toScaled(level.size, SIZE_PRECISION);
1215
+ const notional = level.price * level.size;
1204
1216
  const currentLevel = levelsByPrice.get(priceKey);
1205
1217
  if (currentLevel) {
1206
1218
  currentLevel.sizeScaled += scaledSize;
1219
+ currentLevel.notional += notional;
1207
1220
  currentLevel.venueBreakdownScaled[eligibleOutcome.venue] = ((_a = currentLevel.venueBreakdownScaled[eligibleOutcome.venue]) != null ? _a : 0) + scaledSize;
1208
1221
  currentLevel.sourceOutcomeIds.add(eligibleOutcome.outcomeId);
1209
1222
  return;
1210
1223
  }
1211
1224
  levelsByPrice.set(priceKey, {
1212
- price: level.price,
1225
+ price: displayPrice,
1213
1226
  sizeScaled: scaledSize,
1227
+ notional,
1214
1228
  venueBreakdownScaled: {
1215
1229
  [eligibleOutcome.venue]: scaledSize
1216
1230
  },
@@ -1220,6 +1234,7 @@ var accumulateSideLevels = ({
1220
1234
  });
1221
1235
  return {
1222
1236
  levelsByPrice,
1237
+ bestPrice,
1223
1238
  includedOutcomeIds,
1224
1239
  missingOutcomeIds
1225
1240
  };
@@ -1387,7 +1402,7 @@ var mergeVenueOutcomeOrderbooks = ({
1387
1402
  eligibleOutcomes,
1388
1403
  orderbooksByOutcomeId
1389
1404
  }) => {
1390
- var _a, _b, _c, _d, _e, _f;
1405
+ var _a, _b;
1391
1406
  const bidState = accumulateSideLevels({
1392
1407
  side: "bids",
1393
1408
  eligibleOutcomes,
@@ -1410,8 +1425,8 @@ var mergeVenueOutcomeOrderbooks = ({
1410
1425
  levelsByPrice: askState.levelsByPrice,
1411
1426
  fallbackVenue: (_b = eligibleOutcomes[0]) == null ? void 0 : _b.venue
1412
1427
  });
1413
- const bestBid = (_d = (_c = bidRows[0]) == null ? void 0 : _c.price) != null ? _d : null;
1414
- const bestAsk = (_f = (_e = askRows[0]) == null ? void 0 : _e.price) != null ? _f : null;
1428
+ const bestBid = bidState.bestPrice;
1429
+ const bestAsk = askState.bestPrice;
1415
1430
  return {
1416
1431
  askRows,
1417
1432
  bidRows,
@@ -3056,7 +3056,9 @@ var TRADING_ACCESS_VENUES = [
3056
3056
  "limitless",
3057
3057
  "predict",
3058
3058
  "myriad",
3059
- "hyperliquid"
3059
+ "hyperliquid",
3060
+ "novig",
3061
+ "prophetx"
3060
3062
  ];
3061
3063
  var TRADING_ACCESS_VENUE_ITEMS = TRADING_ACCESS_VENUES.map((id) => ({ id }));
3062
3064
  var SectionTitle2 = ({ children }) => /* @__PURE__ */ jsx22("h3", { className: "text-agg-sm font-agg-bold leading-agg-5 text-agg-foreground", children });
@@ -12,7 +12,7 @@ import {
12
12
  isErrorWithStatus,
13
13
  useEventListTabs,
14
14
  useEventListTabsHeaderOverflow
15
- } from "./chunk-EYJS45RP.mjs";
15
+ } from "./chunk-IS45S6R3.mjs";
16
16
  import {
17
17
  DEPOSIT_MODAL_OPEN_EVENT,
18
18
  PlaceOrder,
@@ -21,7 +21,7 @@ import {
21
21
  formatChainIdLabel,
22
22
  useClaimWinnings,
23
23
  useResolvedMarketClaim
24
- } from "./chunk-WWIVSROM.mjs";
24
+ } from "./chunk-VHKGW4DB.mjs";
25
25
  import {
26
26
  getDisplayOutcomePrice,
27
27
  resolveHeaderOutcomeItems,
@@ -1341,6 +1341,16 @@ var aggregateSportsLineStops = (markets, isSpread = false) => {
1341
1341
  (left, right) => left.lineValue !== right.lineValue ? left.lineValue - right.lineValue : left.value.localeCompare(right.value)
1342
1342
  );
1343
1343
  };
1344
+ var escapeRegExp = (value) => value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
1345
+ var resolveSportsLadderTitle = (group, selectedLineDisplay) => {
1346
+ var _a;
1347
+ const anchorLineValue = (_a = group.markets[0]) == null ? void 0 : _a.lineValue;
1348
+ if (anchorLineValue == null || !selectedLineDisplay) return group.title;
1349
+ const anchorDisplay = resolveSelectedSportsLineValue(anchorLineValue);
1350
+ if (anchorDisplay === selectedLineDisplay) return group.title;
1351
+ const pattern = new RegExp(`(^|[^\\d.])${escapeRegExp(anchorDisplay)}(?![\\d.])`);
1352
+ return pattern.test(group.title) ? group.title.replace(pattern, (_match, prefix) => `${prefix}${selectedLineDisplay}`) : group.title;
1353
+ };
1344
1354
  var buildSportsSlideFromGroup = (group) => {
1345
1355
  const lineStops = group.hasLineVariants ? aggregateSportsLineStops(group.markets, group.sportsMarketType === "spread") : [];
1346
1356
  const hasLadder = lineStops.length > 1;
@@ -1855,6 +1865,8 @@ var SportsMarketCard = ({
1855
1865
  });
1856
1866
  }, [slide.kind, activeMarket, group.markets, midpointsResult]);
1857
1867
  if (!activeMarket) return null;
1868
+ const selectedStop = slide.hasLadder ? slide.stops[selectedLineIndex] : void 0;
1869
+ const cardTitle = selectedStop ? resolveSportsLadderTitle(group, selectedStop.value) : group.title;
1858
1870
  const activeOutcome = (_h = activeMarket.venueMarketOutcomes.find(
1859
1871
  (outcome) => outcome.id === (tradingContext == null ? void 0 : tradingContext.selectedOutcomeId)
1860
1872
  )) != null ? _h : activeDefaultOutcome;
@@ -1915,7 +1927,7 @@ var SportsMarketCard = ({
1915
1927
  {
1916
1928
  marketId: activeMarket.id,
1917
1929
  venueMarkets,
1918
- title: group.title,
1930
+ title: cardTitle,
1919
1931
  compactHeader: true,
1920
1932
  subtitleOverride: compactSubtitle,
1921
1933
  headerOutcomeVariant,
@@ -1934,9 +1946,9 @@ var SportsMarketCard = ({
1934
1946
  })),
1935
1947
  selectedIndex: selectedLineIndex,
1936
1948
  onSelect: handleLineSelect,
1937
- ariaLabel: labels.eventMarketPage.sports.lineSelectorAria(group.title),
1938
- previousAriaLabel: labels.eventMarketPage.sports.previousLineAria(group.title),
1939
- nextAriaLabel: labels.eventMarketPage.sports.nextLineAria(group.title)
1949
+ ariaLabel: labels.eventMarketPage.sports.lineSelectorAria(cardTitle),
1950
+ previousAriaLabel: labels.eventMarketPage.sports.previousLineAria(cardTitle),
1951
+ nextAriaLabel: labels.eventMarketPage.sports.nextLineAria(cardTitle)
1940
1952
  }
1941
1953
  ) : void 0,
1942
1954
  classNames: { root: "agg-market-list-item agg-sports-market-card" },
@@ -1412,6 +1412,72 @@ var parseDecimalString = (value) => {
1412
1412
  if (!Number.isFinite(parsed) || parsed <= 0) return null;
1413
1413
  return parsed;
1414
1414
  };
1415
+ var getPlaceOrderBuyPayout = (quoteData) => {
1416
+ var _a;
1417
+ return (_a = quoteData.estimatedPayout) != null ? _a : quoteData.totalFilled;
1418
+ };
1419
+ var getPlaceOrderSellProceeds = (quoteData) => Math.max(
1420
+ 0,
1421
+ quoteData.rawExecCost - quoteData.fills.reduce((sum, fill) => {
1422
+ var _a, _b;
1423
+ return sum + ((_a = fill.venueFee) != null ? _a : 0) + ((_b = fill.builderFee) != null ? _b : 0);
1424
+ }, 0)
1425
+ );
1426
+ var getPlaceOrderQuoteValue = (quoteData, tradeSide) => tradeSide === "sell" ? getPlaceOrderSellProceeds(quoteData) : getPlaceOrderBuyPayout(quoteData);
1427
+ var resolvePlaceOrderNetResult = ({
1428
+ quoteData,
1429
+ tradeSide,
1430
+ shares,
1431
+ usd,
1432
+ terminalOrderEvents,
1433
+ submittedOrders
1434
+ }) => {
1435
+ if (!quoteData) return tradeSide === "sell" ? usd : shares;
1436
+ const actualEvents = (terminalOrderEvents != null ? terminalOrderEvents : []).filter(
1437
+ (event) => (event.event === "filled" || event.event === "partial_fill") && (tradeSide === "buy" ? event.filledAmountRaw != null : event.actualSharesRaw != null)
1438
+ );
1439
+ if (actualEvents.length) {
1440
+ return actualEvents.reduce((sum, event) => {
1441
+ var _a;
1442
+ const outcomeId = (_a = submittedOrders == null ? void 0 : submittedOrders.find(
1443
+ (order) => order.orderId === event.orderId
1444
+ )) == null ? void 0 : _a.outcomeId;
1445
+ const venueFills = quoteData.fills.filter((fill) => fill.venue === event.venue);
1446
+ const exactFill = venueFills.find((fill) => fill.venueMarketOutcomeId === outcomeId);
1447
+ const fills = exactFill ? [exactFill] : venueFills;
1448
+ const legQuote = fills.length ? __spreadProps(__spreadValues({}, quoteData), {
1449
+ fills,
1450
+ totalFilled: fills.reduce((total, fill) => total + fill.venueQty, 0),
1451
+ rawExecCost: fills.reduce((total, fill) => total + fill.avgPrice * fill.venueQty, 0),
1452
+ estimatedPayout: fills.reduce(
1453
+ (total, fill) => {
1454
+ var _a2;
1455
+ return total + fill.venueQty - ((_a2 = fill.settlementFee) != null ? _a2 : 0);
1456
+ },
1457
+ 0
1458
+ )
1459
+ }) : quoteData;
1460
+ const actual = resolveActualExecutionEconomics({
1461
+ quoteData: legQuote,
1462
+ tradeSide,
1463
+ terminalOrderEvents: [event],
1464
+ submittedOrders
1465
+ });
1466
+ return sum + resolvePlaceOrderNetResult({
1467
+ quoteData: legQuote,
1468
+ tradeSide,
1469
+ shares: actual.actualTotalFilled,
1470
+ usd: actual.actualRawExecCost
1471
+ });
1472
+ }, 0);
1473
+ }
1474
+ if (tradeSide === "sell") {
1475
+ const gross = quoteData.rawExecCost;
1476
+ return gross > 0 ? usd * (getPlaceOrderSellProceeds(quoteData) / gross) : usd;
1477
+ }
1478
+ const filled = quoteData.totalFilled;
1479
+ return filled > 0 ? shares * (getPlaceOrderBuyPayout(quoteData) / filled) : shares;
1480
+ };
1415
1481
  var resolvePlaceOrderQuoteResult = ({
1416
1482
  labels,
1417
1483
  quoteData,
@@ -1420,7 +1486,7 @@ var resolvePlaceOrderQuoteResult = ({
1420
1486
  if (!quoteData || quoteData.totalFilled <= 0) return null;
1421
1487
  const avgPrice = getPlaceOrderAverageExecutionPrice(quoteData);
1422
1488
  if (avgPrice == null) return null;
1423
- const quoteValue = tradeSide === "sell" ? quoteData.rawExecCost : quoteData.totalFilled;
1489
+ const quoteValue = getPlaceOrderQuoteValue(quoteData, tradeSide);
1424
1490
  return {
1425
1491
  hint: labels.averagePrice(avgPrice),
1426
1492
  value: getTradingValueLabel({
@@ -1538,7 +1604,7 @@ var buildLiveRouteCards = ({
1538
1604
  eventVenues = [],
1539
1605
  geoBlockedVenues: inheritedGeoBlockedVenues
1540
1606
  }) => {
1541
- var _a, _b, _c, _d;
1607
+ var _a, _b, _c, _d, _e;
1542
1608
  const geoBlockedVenues = extractGeoBlockedVenues(quoteData.warnings);
1543
1609
  for (const venue of inheritedGeoBlockedVenues != null ? inheritedGeoBlockedVenues : []) {
1544
1610
  geoBlockedVenues.add(venue);
@@ -1553,6 +1619,7 @@ var buildLiveRouteCards = ({
1553
1619
  );
1554
1620
  const averageExecutionPrice = (_b = getPlaceOrderAverageExecutionPrice(quoteData)) != null ? _b : void 0;
1555
1621
  const primaryWinnerVenue = quoteData.fills.length === 1 ? primaryVenue : void 0;
1622
+ const primaryWinnerOutcomeId = quoteData.fills.length === 1 ? (_c = quoteData.fills[0]) == null ? void 0 : _c.venueMarketOutcomeId : void 0;
1556
1623
  const isPrimaryRouteGeoBlocked = quoteData.fills.length > 0 && quoteData.fills.some((f) => geoBlockedVenues.has(f.venue));
1557
1624
  const primaryCard = primaryResult ? isPrimaryRouteGeoBlocked ? isSplit ? null : {
1558
1625
  id: "live-route",
@@ -1562,7 +1629,7 @@ var buildLiveRouteCards = ({
1562
1629
  parsedPrimaryVenue.success ? parsedPrimaryVenue.data : void 0
1563
1630
  ),
1564
1631
  executionPrice: averageExecutionPrice,
1565
- numericValue: tradeSide === "sell" ? quoteData.rawExecCost : quoteData.totalFilled,
1632
+ numericValue: getPlaceOrderQuoteValue(quoteData, tradeSide),
1566
1633
  quoteData,
1567
1634
  value: primaryResult.value,
1568
1635
  venue: parsedPrimaryVenue.success ? parsedPrimaryVenue.data : void 0,
@@ -1575,7 +1642,7 @@ var buildLiveRouteCards = ({
1575
1642
  label: isSplit ? labels.orderSplitting : getTradingVenueLabel(
1576
1643
  parsedPrimaryVenue.success ? parsedPrimaryVenue.data : void 0
1577
1644
  ),
1578
- numericValue: tradeSide === "sell" ? quoteData.rawExecCost : quoteData.totalFilled,
1645
+ numericValue: getPlaceOrderQuoteValue(quoteData, tradeSide),
1579
1646
  quoteData,
1580
1647
  rows: mapQuoteDataToRoutingRows(quoteData, tradeSide),
1581
1648
  description: labels.splitOrderDescription,
@@ -1585,7 +1652,7 @@ var buildLiveRouteCards = ({
1585
1652
  requiresSharedKyc: primaryRequiresSharedKyc
1586
1653
  } : null;
1587
1654
  const soloCardId = (prefix, sq) => `${prefix}-${sq.venue}${sq.venueMarketOutcomeId ? `-${sq.venueMarketOutcomeId}` : ""}`;
1588
- const soloCards = ((_c = quoteData.venueSoloQuotes) != null ? _c : []).filter(
1655
+ const soloCards = ((_d = quoteData.venueSoloQuotes) != null ? _d : []).filter(
1589
1656
  (sq) => sq.status === "ok" && sq.unavailableReason !== "venue_unavailable" && sq.avgPrice !== null && sq.filledQty > 0 && // No `sq.quoteId` requirement: a solo is preview-only whenever its own
1590
1657
  // funding lane is short (API nulls the quoteId), which is NOT always the
1591
1658
  // whole-quote `insufficient_balance` case — an off-chain winner (Kalshi
@@ -1593,9 +1660,9 @@ var buildLiveRouteCards = ({
1593
1660
  // stays unfunded. Gating on the quoteId silently hid that venue from the
1594
1661
  // comparison list entirely. The panel's Deposit CTA fires off the same
1595
1662
  // balance condition, and `handleExecuteQuote` rejects an empty quoteId.
1596
- sq.venue !== primaryWinnerVenue
1663
+ (primaryWinnerOutcomeId && sq.venueMarketOutcomeId ? sq.venueMarketOutcomeId !== primaryWinnerOutcomeId : sq.venue !== primaryWinnerVenue)
1597
1664
  ).map((sq) => {
1598
- var _a2, _b2;
1665
+ var _a2, _b2, _c2, _d2, _e2, _f;
1599
1666
  const parsedVenue = parseVenue(sq.venue);
1600
1667
  const venue = parsedVenue.success ? parsedVenue.data : void 0;
1601
1668
  if (geoBlockedVenues.has(sq.venue)) {
@@ -1605,10 +1672,10 @@ var buildLiveRouteCards = ({
1605
1672
  hint: labels.venueUnavailableInRegion,
1606
1673
  kind: "venue",
1607
1674
  label: getTradingVenueLabel(venue),
1608
- numericValue: sq.filledQty,
1675
+ numericValue: (_a2 = sq.estimatedPayout) != null ? _a2 : sq.filledQty,
1609
1676
  quoteData,
1610
1677
  value: getTradingValueLabel({
1611
- amount: sq.filledQty,
1678
+ amount: (_b2 = sq.estimatedPayout) != null ? _b2 : sq.filledQty,
1612
1679
  minimumFractionDigits: 2,
1613
1680
  maximumFractionDigits: 2
1614
1681
  }),
@@ -1622,7 +1689,7 @@ var buildLiveRouteCards = ({
1622
1689
  // Preview-only solos intentionally carry no executable quoteId; the card
1623
1690
  // should still render for comparison, while the CTA stays disabled until
1624
1691
  // the user is funded and requotes.
1625
- quoteId: (_a2 = sq.quoteId) != null ? _a2 : "",
1692
+ quoteId: (_c2 = sq.quoteId) != null ? _c2 : "",
1626
1693
  fills: sq.fills.map((f) => __spreadValues({}, f)),
1627
1694
  totalFilled: sq.filledQty,
1628
1695
  rawExecCost: sq.rawExecCost,
@@ -1635,7 +1702,7 @@ var buildLiveRouteCards = ({
1635
1702
  // primary route's breakdown in place, so selecting a bridge-free venue
1636
1703
  // still showed the primary's bridging charge. Falls back to the
1637
1704
  // primary only when the router omitted one (non-"ok" solos).
1638
- feeBreakdown: (_b2 = sq.feeBreakdown) != null ? _b2 : quoteData.feeBreakdown
1705
+ feeBreakdown: (_d2 = sq.feeBreakdown) != null ? _d2 : quoteData.feeBreakdown
1639
1706
  }), sq.quoteId ? { status: "ok", error: void 0 } : null);
1640
1707
  return {
1641
1708
  id: soloCardId("live-solo", sq),
@@ -1644,10 +1711,10 @@ var buildLiveRouteCards = ({
1644
1711
  kind: "venue",
1645
1712
  label: getTradingVenueLabel(venue),
1646
1713
  executionPrice: avgPrice,
1647
- numericValue: sq.filledQty,
1714
+ numericValue: (_e2 = sq.estimatedPayout) != null ? _e2 : sq.filledQty,
1648
1715
  quoteData: soloQuoteData,
1649
1716
  value: getTradingValueLabel({
1650
- amount: sq.filledQty,
1717
+ amount: (_f = sq.estimatedPayout) != null ? _f : sq.filledQty,
1651
1718
  minimumFractionDigits: 2,
1652
1719
  maximumFractionDigits: 2
1653
1720
  }),
@@ -1655,7 +1722,8 @@ var buildLiveRouteCards = ({
1655
1722
  requiresSharedKyc: venueRequiresSharedKyc({ venue: sq.venue })
1656
1723
  };
1657
1724
  });
1658
- const unavailableCards = ((_d = quoteData.venueSoloQuotes) != null ? _d : []).filter((sq) => sq.status === "unavailable" || sq.unavailableReason === "venue_unavailable").map((sq) => {
1725
+ const unavailableCards = ((_e = quoteData.venueSoloQuotes) != null ? _e : []).filter((sq) => sq.status === "unavailable" || sq.unavailableReason === "venue_unavailable").map((sq) => {
1726
+ var _a2, _b2;
1659
1727
  const parsedVenue = parseVenue(sq.venue);
1660
1728
  const venue = parsedVenue.success ? parsedVenue.data : void 0;
1661
1729
  const temporarilyUnavailable = sq.unavailableReason === "venue_unavailable";
@@ -1666,10 +1734,10 @@ var buildLiveRouteCards = ({
1666
1734
  hint: temporarilyUnavailable ? labels.venueTemporarilyUnavailable : labels.venueUnavailableInRegion,
1667
1735
  kind: "venue",
1668
1736
  label: getTradingVenueLabel(venue),
1669
- numericValue: hasPreview ? sq.filledQty : 0,
1737
+ numericValue: hasPreview ? (_a2 = sq.estimatedPayout) != null ? _a2 : sq.filledQty : 0,
1670
1738
  quoteData: __spreadProps(__spreadValues({}, quoteData), { quoteId: "" }),
1671
1739
  value: hasPreview ? getTradingValueLabel({
1672
- amount: sq.filledQty,
1740
+ amount: (_b2 = sq.estimatedPayout) != null ? _b2 : sq.filledQty,
1673
1741
  minimumFractionDigits: 2,
1674
1742
  maximumFractionDigits: 2
1675
1743
  }) : ""
@@ -1883,10 +1951,13 @@ var getPlaceOrderPotentialReturn = (quoteData) => {
1883
1951
  if (!((_a = quoteData == null ? void 0 : quoteData.fills) == null ? void 0 : _a.length) || quoteData.fills.length < 2) return 0;
1884
1952
  const bestSoloVenueFill = Math.max(
1885
1953
  0,
1886
- ...((_b = quoteData.venueSoloQuotes) != null ? _b : []).filter((quote) => quote.status === "ok" && quote.filledQty > 0).map((quote) => quote.filledQty)
1954
+ ...((_b = quoteData.venueSoloQuotes) != null ? _b : []).filter((quote) => quote.status === "ok" && quote.filledQty > 0).map((quote) => {
1955
+ var _a2;
1956
+ return (_a2 = quote.estimatedPayout) != null ? _a2 : quote.filledQty;
1957
+ })
1887
1958
  );
1888
1959
  if (bestSoloVenueFill <= 0) return 0;
1889
- return Math.max(0, quoteData.totalFilled - bestSoloVenueFill);
1960
+ return Math.max(0, getPlaceOrderBuyPayout(quoteData) - bestSoloVenueFill);
1890
1961
  };
1891
1962
  var resolvePrimarySubmittedOrderId = ({
1892
1963
  allowOrderIdFallback = true,
@@ -5072,7 +5143,16 @@ var PlaceOrder = ({
5072
5143
  });
5073
5144
  const payoutLabel = formatUsd(usdSide);
5074
5145
  const amountLabel = internalTab === "sell" ? sharesLabel : payoutLabel;
5075
- const toWinLabel = internalTab === "sell" ? payoutLabel : formatUsd(sharesSide);
5146
+ const toWinLabel = formatUsd(
5147
+ resolvePlaceOrderNetResult({
5148
+ quoteData,
5149
+ tradeSide: internalTab,
5150
+ shares: sharesSide,
5151
+ usd: usdSide,
5152
+ terminalOrderEvents: executionProgress.terminalOrderEvents,
5153
+ submittedOrders: executionProgress.submittedOrders
5154
+ })
5155
+ );
5076
5156
  const potentialReturnValue = getPlaceOrderPotentialReturn(quoteData);
5077
5157
  const potentialReturnLabel = potentialReturnValue > 0 ? formatUsd(potentialReturnValue) : void 0;
5078
5158
  const eventTitle = (_f2 = (_e2 = scopedSelectedEvent == null ? void 0 : scopedSelectedEvent.title) != null ? _e2 : scopedSelectedMarket == null ? void 0 : scopedSelectedMarket.question) != null ? _f2 : "";
@@ -5476,7 +5556,16 @@ var PlaceOrder = ({
5476
5556
  maximumFractionDigits: 2
5477
5557
  })
5478
5558
  ) : formatUsd(actualEconomics.actualRawExecCost);
5479
- const payoutLabel = isSell ? formatUsd(actualEconomics.actualRawExecCost) : formatUsd(actualEconomics.actualTotalFilled);
5559
+ const payoutLabel = formatUsd(
5560
+ resolvePlaceOrderNetResult({
5561
+ quoteData,
5562
+ tradeSide: internalTab,
5563
+ shares: actualEconomics.actualTotalFilled,
5564
+ usd: actualEconomics.actualRawExecCost,
5565
+ terminalOrderEvents: executionProgress.terminalOrderEvents,
5566
+ submittedOrders: executionProgress.submittedOrders
5567
+ })
5568
+ );
5480
5569
  return __spreadProps(__spreadValues({}, summaryWithGroups), {
5481
5570
  actions: summaryWithGroups.actions.map(
5482
5571
  (action) => action.variant === "retry" ? __spreadProps(__spreadValues({}, action), { label: tradingLabels.orderTryRemaining(remainingLabel) }) : action
package/dist/events.js CHANGED
@@ -9866,6 +9866,8 @@ var buildMarketDetailsModel = ({
9866
9866
  var import_hooks38 = require("@agg-build/hooks");
9867
9867
  var PRICE_PRECISION = 1e6;
9868
9868
  var SIZE_PRECISION = 1e8;
9869
+ var DISPLAY_PRICE_BUCKETS_PER_UNIT = 1e3;
9870
+ var DISPLAY_ROUNDING_PRECISION = 1e9;
9869
9871
  var POSITIVE_OUTCOME_KEYS = /* @__PURE__ */ new Set(["yes", "y", "true", "up", "buy", "long"]);
9870
9872
  var NEGATIVE_OUTCOME_KEYS = /* @__PURE__ */ new Set(["no", "n", "false", "down", "sell", "short"]);
9871
9873
  var roundTo = (value, precision) => {
@@ -9880,6 +9882,10 @@ var fromScaled = (value, precision) => {
9880
9882
  var toPriceKey = (price) => {
9881
9883
  return String(toScaled(price, PRICE_PRECISION));
9882
9884
  };
9885
+ var toDisplayPrice = (price) => {
9886
+ const bucketSize = DISPLAY_ROUNDING_PRECISION / DISPLAY_PRICE_BUCKETS_PER_UNIT;
9887
+ return Math.round(toScaled(price, DISPLAY_ROUNDING_PRECISION) / bucketSize) / DISPLAY_PRICE_BUCKETS_PER_UNIT;
9888
+ };
9883
9889
  var normalizeOutcomeLabel = (value) => {
9884
9890
  if (typeof value !== "string") return "";
9885
9891
  return value.trim().toLowerCase().replace(/[_-]+/g, " ").replace(/[^\p{L}\p{N}\s]/gu, " ").replace(/\s+/g, " ");
@@ -9993,7 +9999,7 @@ var buildRowsFromAccumulator = ({
9993
9999
  venues,
9994
10000
  price: roundTo(level.price, PRICE_PRECISION),
9995
10001
  size,
9996
- total: roundTo(level.price * size, SIZE_PRECISION),
10002
+ total: roundTo(level.notional, SIZE_PRECISION),
9997
10003
  tone,
9998
10004
  barScale: 0,
9999
10005
  venueBreakdown,
@@ -10011,6 +10017,7 @@ var accumulateSideLevels = ({
10011
10017
  orderbooksByOutcomeId
10012
10018
  }) => {
10013
10019
  const levelsByPrice = /* @__PURE__ */ new Map();
10020
+ let bestPrice = null;
10014
10021
  const includedOutcomeIds = /* @__PURE__ */ new Set();
10015
10022
  const missingOutcomeIds = /* @__PURE__ */ new Set();
10016
10023
  eligibleOutcomes.forEach((eligibleOutcome) => {
@@ -10026,18 +10033,25 @@ var accumulateSideLevels = ({
10026
10033
  includedOutcomeIds.add(eligibleOutcome.outcomeId);
10027
10034
  venueLevels.forEach((level) => {
10028
10035
  var _a;
10029
- const priceKey = toPriceKey(level.price);
10036
+ if (bestPrice == null || (side === "asks" ? level.price < bestPrice : level.price > bestPrice)) {
10037
+ bestPrice = level.price;
10038
+ }
10039
+ const displayPrice = toDisplayPrice(level.price);
10040
+ const priceKey = toPriceKey(displayPrice);
10030
10041
  const scaledSize = toScaled(level.size, SIZE_PRECISION);
10042
+ const notional = level.price * level.size;
10031
10043
  const currentLevel = levelsByPrice.get(priceKey);
10032
10044
  if (currentLevel) {
10033
10045
  currentLevel.sizeScaled += scaledSize;
10046
+ currentLevel.notional += notional;
10034
10047
  currentLevel.venueBreakdownScaled[eligibleOutcome.venue] = ((_a = currentLevel.venueBreakdownScaled[eligibleOutcome.venue]) != null ? _a : 0) + scaledSize;
10035
10048
  currentLevel.sourceOutcomeIds.add(eligibleOutcome.outcomeId);
10036
10049
  return;
10037
10050
  }
10038
10051
  levelsByPrice.set(priceKey, {
10039
- price: level.price,
10052
+ price: displayPrice,
10040
10053
  sizeScaled: scaledSize,
10054
+ notional,
10041
10055
  venueBreakdownScaled: {
10042
10056
  [eligibleOutcome.venue]: scaledSize
10043
10057
  },
@@ -10047,6 +10061,7 @@ var accumulateSideLevels = ({
10047
10061
  });
10048
10062
  return {
10049
10063
  levelsByPrice,
10064
+ bestPrice,
10050
10065
  includedOutcomeIds,
10051
10066
  missingOutcomeIds
10052
10067
  };
@@ -10214,7 +10229,7 @@ var mergeVenueOutcomeOrderbooks = ({
10214
10229
  eligibleOutcomes,
10215
10230
  orderbooksByOutcomeId
10216
10231
  }) => {
10217
- var _a, _b, _c, _d, _e, _f;
10232
+ var _a, _b;
10218
10233
  const bidState = accumulateSideLevels({
10219
10234
  side: "bids",
10220
10235
  eligibleOutcomes,
@@ -10237,8 +10252,8 @@ var mergeVenueOutcomeOrderbooks = ({
10237
10252
  levelsByPrice: askState.levelsByPrice,
10238
10253
  fallbackVenue: (_b = eligibleOutcomes[0]) == null ? void 0 : _b.venue
10239
10254
  });
10240
- const bestBid = (_d = (_c = bidRows[0]) == null ? void 0 : _c.price) != null ? _d : null;
10241
- const bestAsk = (_f = (_e = askRows[0]) == null ? void 0 : _e.price) != null ? _f : null;
10255
+ const bestBid = bidState.bestPrice;
10256
+ const bestAsk = askState.bestPrice;
10242
10257
  return {
10243
10258
  askRows,
10244
10259
  bidRows,
package/dist/events.mjs CHANGED
@@ -17,7 +17,7 @@ import {
17
17
  orderbookRowLimitDefault,
18
18
  resolveEventDetailsSyncKey,
19
19
  useCenterOrderbookSpread
20
- } from "./chunk-EYJS45RP.mjs";
20
+ } from "./chunk-IS45S6R3.mjs";
21
21
  import {
22
22
  formatProbabilityCents,
23
23
  resolveOrderBookRows,