@agg-build/ui 2.4.1 → 2.4.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.
package/dist/pages.js CHANGED
@@ -5322,17 +5322,10 @@ var SettlementSkeletonView = ({
5322
5322
  children: [
5323
5323
  /* @__PURE__ */ (0, import_jsx_runtime102.jsxs)("div", { className: "flex w-full items-center justify-between gap-4", children: [
5324
5324
  /* @__PURE__ */ (0, import_jsx_runtime102.jsx)(SkeletonBlock, { className: "h-4 w-[81px] rounded-agg-sm" }),
5325
- /* @__PURE__ */ (0, import_jsx_runtime102.jsx)(SkeletonBlock, { className: "h-5 w-full max-w-[240px] rounded-agg-sm" })
5325
+ /* @__PURE__ */ (0, import_jsx_runtime102.jsx)(SkeletonBlock, { className: "h-5 w-[240px] max-w-[60%] rounded-agg-sm" })
5326
5326
  ] }),
5327
- /* @__PURE__ */ (0, import_jsx_runtime102.jsxs)("div", { className: "flex w-full flex-col gap-3", children: [
5328
- /* @__PURE__ */ (0, import_jsx_runtime102.jsx)(SkeletonBlock, { className: "h-5 w-[200px] rounded-agg-sm" }),
5329
- /* @__PURE__ */ (0, import_jsx_runtime102.jsxs)("div", { className: "flex flex-col gap-2", children: [
5330
- /* @__PURE__ */ (0, import_jsx_runtime102.jsx)(SkeletonBlock, { className: "h-4 w-full max-w-[320px] rounded-agg-sm" }),
5331
- /* @__PURE__ */ (0, import_jsx_runtime102.jsx)(SkeletonBlock, { className: "h-4 w-full max-w-[280px] rounded-agg-sm" })
5332
- ] })
5333
- ] }),
5334
- /* @__PURE__ */ (0, import_jsx_runtime102.jsx)("div", { className: "h-px w-full bg-agg-separator" }),
5335
- /* @__PURE__ */ (0, import_jsx_runtime102.jsxs)("div", { className: "flex w-full flex-col gap-3", children: [
5327
+ /* @__PURE__ */ (0, import_jsx_runtime102.jsx)(SkeletonBlock, { className: "h-5 w-[200px] rounded-agg-sm" }),
5328
+ /* @__PURE__ */ (0, import_jsx_runtime102.jsxs)("div", { className: "flex w-full flex-col gap-4", children: [
5336
5329
  /* @__PURE__ */ (0, import_jsx_runtime102.jsxs)("div", { className: "flex items-center gap-2", children: [
5337
5330
  /* @__PURE__ */ (0, import_jsx_runtime102.jsx)(SkeletonBlock, { className: "size-4 rounded-agg-sm" }),
5338
5331
  /* @__PURE__ */ (0, import_jsx_runtime102.jsx)(SkeletonBlock, { className: "h-5 w-[100px] rounded-agg-sm" })
@@ -12664,6 +12657,137 @@ SettlementTextRenderer.displayName = "SettlementTextRenderer";
12664
12657
  // src/trading/settlement/index.tsx
12665
12658
  var import_jsx_runtime134 = require("react/jsx-runtime");
12666
12659
  var SETTLEMENT_SECTION_ID = "agg-settlement-section";
12660
+ var getSettlementDifferenceId = (sectionId, canonicalKey) => {
12661
+ return `${sectionId}-difference-${canonicalKey}`;
12662
+ };
12663
+ var dateOnlyRegex = /^(\d{4})-(\d{2})-(\d{2})$/;
12664
+ var isoTimestampWithTimezoneRegex = /^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}(?::\d{2}(?:\.\d{1,9})?)?(?:Z|[+-]\d{2}:?\d{2})$/i;
12665
+ var normalizeDifferenceText = (value) => {
12666
+ return value.trim().toLowerCase().replace(/[^a-z0-9]+/g, "_").replace(/^_+|_+$/g, "");
12667
+ };
12668
+ var resolveCanonicalDifferenceKey = (difference) => {
12669
+ const normalizedType = normalizeDifferenceText(difference.type);
12670
+ const combined = normalizeDifferenceText(`${difference.type} ${difference.title}`);
12671
+ if (combined.includes("start_date") || combined.includes("open_date")) return "start_date";
12672
+ if (combined.includes("end_date") || combined.includes("close_date") || combined.includes("closing_date") || combined.includes("expiration_date") || combined.includes("expiry_date")) {
12673
+ return "end_date";
12674
+ }
12675
+ if (combined.includes("resolution_timing") || combined.includes("resolution_date") || combined.includes("resolution_deadline") || combined.includes("settlement_date") || combined.includes("settlement_deadline") || combined.includes("settlement_timing")) {
12676
+ return "resolution_timing";
12677
+ }
12678
+ return normalizedType || "other";
12679
+ };
12680
+ var parseSettlementDateMs = (value) => {
12681
+ const trimmed = value.trim();
12682
+ const dateOnlyMatch = dateOnlyRegex.exec(trimmed);
12683
+ if (dateOnlyMatch) {
12684
+ const [, year, month, day] = dateOnlyMatch;
12685
+ return Date.UTC(Number(year), Number(month) - 1, Number(day));
12686
+ }
12687
+ if (!isoTimestampWithTimezoneRegex.test(trimmed)) return null;
12688
+ const ms = Date.parse(trimmed);
12689
+ return Number.isNaN(ms) ? null : ms;
12690
+ };
12691
+ var isDateLikeDifference = (canonicalKey) => {
12692
+ return canonicalKey === "resolution_timing" || canonicalKey === "start_date" || canonicalKey === "end_date";
12693
+ };
12694
+ var hasEqualNormalizedDateValues = (difference, canonicalKey) => {
12695
+ if (!isDateLikeDifference(canonicalKey)) return false;
12696
+ const values = Object.values(difference.perVenue);
12697
+ if (values.length < 2) return false;
12698
+ const timestamps = values.map(parseSettlementDateMs);
12699
+ if (timestamps.some((timestamp) => timestamp === null)) return false;
12700
+ return new Set(timestamps).size === 1;
12701
+ };
12702
+ var resolveDifferenceSeverity = (difference, canonicalKey) => {
12703
+ var _a;
12704
+ const combined = normalizeDifferenceText(
12705
+ `${difference.type} ${difference.title} ${(_a = difference.summary) != null ? _a : ""}`
12706
+ );
12707
+ if (isDateLikeDifference(canonicalKey)) return "critical";
12708
+ if (canonicalKey === "scope" || canonicalKey === "threshold" || canonicalKey === "edge_cases") {
12709
+ return "critical";
12710
+ }
12711
+ if (combined.includes("conflict") || combined.includes("void") || combined.includes("cancel") || combined.includes("postpone") || combined.includes("recount") || combined.includes("overtime") || combined.includes("extra_time")) {
12712
+ return "critical";
12713
+ }
12714
+ return "informational";
12715
+ };
12716
+ var mergePerVenueValues = (current, next) => {
12717
+ return Object.entries(next).reduce(
12718
+ (merged, [venue, value]) => {
12719
+ if (merged[venue] === void 0) merged[venue] = value;
12720
+ return merged;
12721
+ },
12722
+ __spreadValues({}, current)
12723
+ );
12724
+ };
12725
+ var prepareSettlementDifferences = (differences) => {
12726
+ const byCanonicalKey = /* @__PURE__ */ new Map();
12727
+ for (const [originalIndex, difference] of (differences != null ? differences : []).entries()) {
12728
+ const canonicalKey = resolveCanonicalDifferenceKey(difference);
12729
+ if (hasEqualNormalizedDateValues(difference, canonicalKey)) continue;
12730
+ const existing = byCanonicalKey.get(canonicalKey);
12731
+ if (existing) {
12732
+ byCanonicalKey.set(canonicalKey, __spreadProps(__spreadValues({}, existing), {
12733
+ perVenue: mergePerVenueValues(existing.perVenue, difference.perVenue)
12734
+ }));
12735
+ continue;
12736
+ }
12737
+ byCanonicalKey.set(canonicalKey, __spreadProps(__spreadValues({}, difference), {
12738
+ canonicalKey,
12739
+ severity: resolveDifferenceSeverity(difference, canonicalKey),
12740
+ originalIndex
12741
+ }));
12742
+ }
12743
+ return Array.from(byCanonicalKey.values()).sort((left, right) => {
12744
+ const severityDelta = Number(right.severity === "critical") - Number(left.severity === "critical");
12745
+ if (severityDelta !== 0) return severityDelta;
12746
+ return left.originalIndex - right.originalIndex;
12747
+ });
12748
+ };
12749
+ var formatVenueFallbackLabel = (venue) => {
12750
+ return venue.split(/[-_\s]+/).filter(Boolean).map((part) => `${part.slice(0, 1).toUpperCase()}${part.slice(1)}`).join(" ");
12751
+ };
12752
+ var resolveSettlementVenueLabel = (venue, labels) => {
12753
+ var _a;
12754
+ return (_a = labels.venues[venue]) != null ? _a : formatVenueFallbackLabel(venue);
12755
+ };
12756
+ var resolveDifferenceVenueKeys = (difference, settlementVenues) => {
12757
+ const explicitVenues = Object.keys(difference.perVenue);
12758
+ if (!isDateLikeDifference(difference.canonicalKey)) return explicitVenues;
12759
+ const allVenues = [...settlementVenues != null ? settlementVenues : [], ...explicitVenues];
12760
+ return Array.from(new Set(allVenues.filter((venue) => venue.trim().length > 0)));
12761
+ };
12762
+ var resolveDifferenceIconClassName = (canonicalKey) => {
12763
+ if (canonicalKey.includes("source") || canonicalKey.includes("url")) return "fi-rr-world";
12764
+ if (canonicalKey === "resolution_timing" || canonicalKey.includes("timing")) {
12765
+ return "fi-rr-clock";
12766
+ }
12767
+ if (canonicalKey === "start_date" || canonicalKey.includes("start"))
12768
+ return "fi-rr-calendar-clock";
12769
+ if (canonicalKey === "end_date" || canonicalKey.includes("end")) return "fi-rr-calendar-clock";
12770
+ if (canonicalKey.includes("cancel") || canonicalKey.includes("void") || canonicalKey.includes("postpone")) {
12771
+ return "fi-rr-ban";
12772
+ }
12773
+ if (canonicalKey === "edge_cases" || canonicalKey.includes("edge")) {
12774
+ return "fi-rr-triangle-warning";
12775
+ }
12776
+ if (canonicalKey === "scope") return "fi-rr-layers";
12777
+ if (canonicalKey === "threshold") return "fi-rr-tachometer-alt-fastest";
12778
+ if (canonicalKey.includes("wording")) return "fi-rr-document";
12779
+ return "fi-rr-info";
12780
+ };
12781
+ var buildSettlementVenueRules = ({
12782
+ eventBlock,
12783
+ marketBlock,
12784
+ primaryRulesBlock,
12785
+ settlementVenueRules
12786
+ }) => {
12787
+ if (settlementVenueRules) return settlementVenueRules;
12788
+ const content = [marketBlock == null ? void 0 : marketBlock.content, primaryRulesBlock == null ? void 0 : primaryRulesBlock.content, eventBlock == null ? void 0 : eventBlock.content].filter((value) => typeof value === "string" && value.trim().length > 0).join("\n\n");
12789
+ return content ? [{ venue: "polymarket", content }] : [];
12790
+ };
12667
12791
  var getSettlementHeaderClassName = () => {
12668
12792
  return "flex items-center justify-between gap-4";
12669
12793
  };
@@ -12675,9 +12799,12 @@ var Settlement = ({
12675
12799
  eventDescription,
12676
12800
  marketDescription,
12677
12801
  primaryRules,
12802
+ settlementDiff,
12803
+ settlementVenues,
12804
+ settlementVenueRules,
12678
12805
  isLoading = false
12679
12806
  }) => {
12680
- var _a, _b, _c;
12807
+ var _a, _b, _c, _d, _e;
12681
12808
  const labels = (0, import_hooks44.useLabels)();
12682
12809
  const blocks = (0, import_react21.useMemo)(
12683
12810
  () => dedupeSettlementSources({
@@ -12687,9 +12814,34 @@ var Settlement = ({
12687
12814
  }),
12688
12815
  [eventDescription, marketDescription, primaryRules]
12689
12816
  );
12817
+ const settlementDifferences = (0, import_react21.useMemo)(
12818
+ () => prepareSettlementDifferences(settlementDiff == null ? void 0 : settlementDiff.differences),
12819
+ [settlementDiff == null ? void 0 : settlementDiff.differences]
12820
+ );
12690
12821
  const eventBlock = (_a = blocks.find((block) => block.key === "eventDescription")) != null ? _a : null;
12691
12822
  const marketBlock = (_b = blocks.find((block) => block.key === "marketDescription")) != null ? _b : null;
12692
12823
  const primaryRulesBlock = (_c = blocks.find((block) => block.key === "primaryRules")) != null ? _c : null;
12824
+ const venueRuleBlocks = (0, import_react21.useMemo)(
12825
+ () => buildSettlementVenueRules({
12826
+ eventBlock,
12827
+ marketBlock,
12828
+ primaryRulesBlock,
12829
+ settlementVenueRules
12830
+ }),
12831
+ [eventBlock, marketBlock, primaryRulesBlock, settlementVenueRules]
12832
+ );
12833
+ const defaultOpenDifferenceKey = (_e = (_d = settlementDifferences[0]) == null ? void 0 : _d.canonicalKey) != null ? _e : null;
12834
+ const [openDifferenceKeys, setOpenDifferenceKeys] = (0, import_react21.useState)(
12835
+ () => defaultOpenDifferenceKey ? [defaultOpenDifferenceKey] : []
12836
+ );
12837
+ (0, import_react21.useEffect)(() => {
12838
+ setOpenDifferenceKeys(defaultOpenDifferenceKey ? [defaultOpenDifferenceKey] : []);
12839
+ }, [defaultOpenDifferenceKey]);
12840
+ const handleToggleDifference = (canonicalKey) => {
12841
+ setOpenDifferenceKeys(
12842
+ (currentKeys) => currentKeys.includes(canonicalKey) ? currentKeys.filter((currentKey) => currentKey !== canonicalKey) : [...currentKeys, canonicalKey]
12843
+ );
12844
+ };
12693
12845
  if (isLoading) {
12694
12846
  return /* @__PURE__ */ (0, import_jsx_runtime134.jsx)(
12695
12847
  Skeleton,
@@ -12701,6 +12853,124 @@ var Settlement = ({
12701
12853
  );
12702
12854
  }
12703
12855
  const resolvedSectionLabel = sectionLabel === defaultSettlementSectionLabel ? labels.trading.settlementSection : sectionLabel;
12856
+ if (settlementDifferences.length > 0) {
12857
+ return /* @__PURE__ */ (0, import_jsx_runtime134.jsxs)(
12858
+ Card,
12859
+ {
12860
+ id,
12861
+ className: cn(
12862
+ "group/agg-settlement-card",
12863
+ "flex w-full flex-col items-start gap-4 rounded-agg-xl border border-agg-separator bg-agg-secondary p-5 shadow-none hover:shadow-none sm:gap-5",
12864
+ className
12865
+ ),
12866
+ children: [
12867
+ /* @__PURE__ */ (0, import_jsx_runtime134.jsxs)("div", { className: "agg-settlement-header flex w-full flex-col items-start gap-1 text-agg-muted-foreground sm:flex-row sm:items-center sm:justify-between sm:gap-4", children: [
12868
+ /* @__PURE__ */ (0, import_jsx_runtime134.jsx)("p", { className: "shrink-0 text-agg-xs font-agg-bold leading-agg-4 uppercase", children: resolvedSectionLabel }),
12869
+ question ? /* @__PURE__ */ (0, import_jsx_runtime134.jsx)("p", { className: "agg-settlement-question min-w-0 text-agg-sm font-agg-normal leading-agg-5 sm:max-w-[314px] sm:truncate", children: question }) : null
12870
+ ] }),
12871
+ /* @__PURE__ */ (0, import_jsx_runtime134.jsxs)("div", { className: "agg-settlement-differences flex w-full flex-col items-start gap-5", children: [
12872
+ /* @__PURE__ */ (0, import_jsx_runtime134.jsxs)("div", { className: "flex items-center gap-2", children: [
12873
+ /* @__PURE__ */ (0, import_jsx_runtime134.jsx)("p", { className: "text-agg-sm font-agg-bold leading-agg-5 text-agg-foreground", children: "Key differences" }),
12874
+ /* @__PURE__ */ (0, import_jsx_runtime134.jsx)("span", { className: "flex size-4 shrink-0 items-center justify-center rounded-agg-full bg-agg-primary text-[10px] font-agg-bold leading-[14px] text-agg-on-primary", children: settlementDifferences.length })
12875
+ ] }),
12876
+ /* @__PURE__ */ (0, import_jsx_runtime134.jsx)("div", { className: "flex w-full flex-col items-start gap-5", children: settlementDifferences.map((difference) => {
12877
+ const venueKeys = resolveDifferenceVenueKeys(difference, settlementVenues);
12878
+ const isExpanded = openDifferenceKeys.includes(difference.canonicalKey) && venueKeys.length > 0;
12879
+ return /* @__PURE__ */ (0, import_jsx_runtime134.jsxs)(
12880
+ "div",
12881
+ {
12882
+ id: getSettlementDifferenceId(id, difference.canonicalKey),
12883
+ className: "agg-settlement-difference flex w-full flex-col items-start gap-2 rounded-agg-lg",
12884
+ children: [
12885
+ /* @__PURE__ */ (0, import_jsx_runtime134.jsxs)(
12886
+ "button",
12887
+ {
12888
+ type: "button",
12889
+ className: "flex w-full cursor-pointer items-start gap-2 text-left",
12890
+ "aria-expanded": isExpanded,
12891
+ onClick: () => handleToggleDifference(difference.canonicalKey),
12892
+ children: [
12893
+ /* @__PURE__ */ (0, import_jsx_runtime134.jsx)(
12894
+ "i",
12895
+ {
12896
+ className: cn(
12897
+ "fi",
12898
+ resolveDifferenceIconClassName(difference.canonicalKey),
12899
+ "inline-flex size-4! shrink-0 items-center justify-center text-[16px] leading-none text-agg-muted-foreground"
12900
+ ),
12901
+ "aria-hidden": "true"
12902
+ }
12903
+ ),
12904
+ /* @__PURE__ */ (0, import_jsx_runtime134.jsx)("p", { className: "min-w-0 text-agg-sm font-agg-normal leading-agg-5 text-agg-foreground break-words [overflow-wrap:anywhere]", children: difference.title }),
12905
+ /* @__PURE__ */ (0, import_jsx_runtime134.jsx)(
12906
+ Icon,
12907
+ {
12908
+ name: isExpanded ? "chevron-up" : "chevron-down",
12909
+ className: "size-4! mt-0.5 shrink-0 text-agg-foreground",
12910
+ "aria-hidden": "true"
12911
+ }
12912
+ )
12913
+ ]
12914
+ }
12915
+ ),
12916
+ isExpanded ? /* @__PURE__ */ (0, import_jsx_runtime134.jsx)("dl", { className: "flex w-full flex-col items-start gap-1 px-6", children: venueKeys.map((venue) => {
12917
+ var _a2;
12918
+ const venueValue = (_a2 = difference.perVenue[venue]) != null ? _a2 : labels.trading.settlementValueUnavailable;
12919
+ const venueLabel = resolveSettlementVenueLabel(venue, labels);
12920
+ return /* @__PURE__ */ (0, import_jsx_runtime134.jsxs)("div", { className: "flex w-full items-start gap-2", children: [
12921
+ /* @__PURE__ */ (0, import_jsx_runtime134.jsx)(
12922
+ VenueLogo,
12923
+ {
12924
+ venue,
12925
+ size: "small",
12926
+ className: "mt-0.5 size-4",
12927
+ ariaLabel: venueLabel
12928
+ }
12929
+ ),
12930
+ /* @__PURE__ */ (0, import_jsx_runtime134.jsx)("dt", { className: "w-[88px] shrink-0 text-agg-sm font-agg-normal leading-agg-5 text-agg-foreground", children: venueLabel }),
12931
+ /* @__PURE__ */ (0, import_jsx_runtime134.jsx)("dd", { className: "min-w-0 flex-1 text-agg-sm font-agg-normal leading-agg-5 text-agg-muted-foreground break-words [overflow-wrap:anywhere]", children: venueValue })
12932
+ ] }, venue);
12933
+ }) }) : null
12934
+ ]
12935
+ },
12936
+ difference.canonicalKey
12937
+ );
12938
+ }) }),
12939
+ venueRuleBlocks.length > 0 ? /* @__PURE__ */ (0, import_jsx_runtime134.jsxs)(import_jsx_runtime134.Fragment, { children: [
12940
+ /* @__PURE__ */ (0, import_jsx_runtime134.jsx)("div", { className: "h-px w-full bg-agg-separator" }),
12941
+ /* @__PURE__ */ (0, import_jsx_runtime134.jsx)("p", { className: "text-agg-sm font-agg-bold leading-agg-5 text-agg-foreground", children: "Full rules by venue" }),
12942
+ /* @__PURE__ */ (0, import_jsx_runtime134.jsx)("div", { className: "flex w-full flex-col items-start gap-4", children: venueRuleBlocks.map((rule) => {
12943
+ const venueLabel = resolveSettlementVenueLabel(rule.venue, labels);
12944
+ return /* @__PURE__ */ (0, import_jsx_runtime134.jsxs)("details", { className: "group/agg-settlement-rule w-full", children: [
12945
+ /* @__PURE__ */ (0, import_jsx_runtime134.jsxs)("summary", { className: "flex cursor-pointer list-none items-center gap-2 text-agg-sm font-agg-normal leading-agg-5 text-agg-foreground marker:hidden", children: [
12946
+ /* @__PURE__ */ (0, import_jsx_runtime134.jsx)(
12947
+ VenueLogo,
12948
+ {
12949
+ venue: rule.venue,
12950
+ size: "small",
12951
+ className: "size-4",
12952
+ ariaLabel: venueLabel
12953
+ }
12954
+ ),
12955
+ /* @__PURE__ */ (0, import_jsx_runtime134.jsx)("span", { children: venueLabel }),
12956
+ /* @__PURE__ */ (0, import_jsx_runtime134.jsx)(
12957
+ Icon,
12958
+ {
12959
+ name: "chevron-down",
12960
+ className: "size-4! shrink-0 text-agg-foreground transition-transform group-open/agg-settlement-rule:rotate-180",
12961
+ "aria-hidden": "true"
12962
+ }
12963
+ )
12964
+ ] }),
12965
+ /* @__PURE__ */ (0, import_jsx_runtime134.jsx)("div", { className: "mt-3 pl-6", children: /* @__PURE__ */ (0, import_jsx_runtime134.jsx)(SettlementTextRenderer, { content: rule.content }) })
12966
+ ] }, rule.venue);
12967
+ }) })
12968
+ ] }) : null
12969
+ ] })
12970
+ ]
12971
+ }
12972
+ );
12973
+ }
12704
12974
  return /* @__PURE__ */ (0, import_jsx_runtime134.jsxs)(
12705
12975
  Card,
12706
12976
  {
@@ -12715,7 +12985,7 @@ var Settlement = ({
12715
12985
  /* @__PURE__ */ (0, import_jsx_runtime134.jsx)("p", { className: "text-agg-xs font-agg-bold leading-agg-4 uppercase text-agg-muted-foreground", children: resolvedSectionLabel }),
12716
12986
  question ? /* @__PURE__ */ (0, import_jsx_runtime134.jsx)("p", { className: "agg-settlement-question text-agg-sm font-agg-bold leading-agg-5 text-agg-foreground", children: question }) : null
12717
12987
  ] }),
12718
- blocks.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime134.jsx)("p", { className: "agg-settlement-empty text-agg-sm leading-agg-5 text-agg-muted-foreground", children: labels.trading.settlementEmpty }) : /* @__PURE__ */ (0, import_jsx_runtime134.jsxs)("div", { className: "agg-settlement-sections flex flex-col gap-4", children: [
12988
+ blocks.length === 0 && settlementDifferences.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime134.jsx)("p", { className: "agg-settlement-empty text-agg-sm leading-agg-5 text-agg-muted-foreground", children: labels.trading.settlementEmpty }) : /* @__PURE__ */ (0, import_jsx_runtime134.jsxs)("div", { className: "agg-settlement-sections flex flex-col gap-4", children: [
12719
12989
  eventBlock || marketBlock ? /* @__PURE__ */ (0, import_jsx_runtime134.jsxs)(
12720
12990
  "div",
12721
12991
  {
@@ -12750,12 +13020,17 @@ Settlement.displayName = "Settlement";
12750
13020
  var import_jsx_runtime135 = require("react/jsx-runtime");
12751
13021
  var SettlementSummary = ({
12752
13022
  content,
13023
+ settlementDiff,
12753
13024
  settlementSectionId = SETTLEMENT_SECTION_ID,
12754
13025
  className
12755
13026
  }) => {
12756
13027
  const labels = (0, import_hooks45.useLabels)();
12757
13028
  const firstParagraph = (0, import_react22.useMemo)(() => getFirstSettlementParagraph(content), [content]);
12758
- if (!firstParagraph) return null;
13029
+ const settlementDifferences = (0, import_react22.useMemo)(
13030
+ () => prepareSettlementDifferences(settlementDiff == null ? void 0 : settlementDiff.differences),
13031
+ [settlementDiff == null ? void 0 : settlementDiff.differences]
13032
+ );
13033
+ if (!firstParagraph && settlementDifferences.length === 0) return null;
12759
13034
  const handleReadFullDetails = (event) => {
12760
13035
  event.preventDefault();
12761
13036
  event.stopPropagation();
@@ -12764,43 +13039,118 @@ var SettlementSummary = ({
12764
13039
  if (!target) return;
12765
13040
  target.scrollIntoView({ behavior: "smooth", block: "start" });
12766
13041
  };
12767
- return /* @__PURE__ */ (0, import_jsx_runtime135.jsxs)("div", { className: cn("agg-settlement-summary flex w-full flex-col gap-2", className), children: [
12768
- /* @__PURE__ */ (0, import_jsx_runtime135.jsx)(
12769
- Typography,
13042
+ const handleDifferencePillClick = (event, canonicalKey) => {
13043
+ event.preventDefault();
13044
+ event.stopPropagation();
13045
+ if (typeof document === "undefined") return;
13046
+ const target = document.getElementById(
13047
+ getSettlementDifferenceId(settlementSectionId, canonicalKey)
13048
+ );
13049
+ if (!target) return;
13050
+ const trigger = target.querySelector("button[aria-expanded]");
13051
+ if ((trigger == null ? void 0 : trigger.getAttribute("aria-expanded")) === "false") {
13052
+ trigger.click();
13053
+ }
13054
+ target.scrollIntoView({ behavior: "smooth", block: "start" });
13055
+ };
13056
+ const actionButton = /* @__PURE__ */ (0, import_jsx_runtime135.jsxs)(
13057
+ "button",
13058
+ {
13059
+ type: "button",
13060
+ className: cn(
13061
+ "agg-settlement-summary-toggle",
13062
+ "inline-flex shrink-0 cursor-pointer items-center gap-1 whitespace-nowrap text-agg-sm font-agg-bold leading-agg-5 text-agg-primary",
13063
+ "hover:opacity-80",
13064
+ "focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-agg-primary focus-visible:ring-offset-0 focus-visible:ring-offset-agg-secondary"
13065
+ ),
13066
+ "aria-controls": settlementSectionId,
13067
+ onClick: handleReadFullDetails,
13068
+ children: [
13069
+ /* @__PURE__ */ (0, import_jsx_runtime135.jsx)("span", { children: labels.settlementSummary.readFullDetails }),
13070
+ /* @__PURE__ */ (0, import_jsx_runtime135.jsx)(Icon, { name: "chevron-down", className: "size-[14px]", "aria-hidden": "true" })
13071
+ ]
13072
+ }
13073
+ );
13074
+ if (settlementDifferences.length > 0) {
13075
+ const visibleDifferences = settlementDifferences.slice(0, 2);
13076
+ const hiddenDifferenceCount = settlementDifferences.length - visibleDifferences.length;
13077
+ return /* @__PURE__ */ (0, import_jsx_runtime135.jsxs)(
13078
+ "div",
12770
13079
  {
12771
- variant: "caption-caps",
12772
- className: "agg-settlement-summary-label text-agg-muted-foreground",
12773
- children: labels.settlementSummary.title
13080
+ className: cn(
13081
+ "agg-settlement-summary flex w-full flex-wrap items-start justify-between gap-x-4 gap-y-2",
13082
+ className
13083
+ ),
13084
+ children: [
13085
+ /* @__PURE__ */ (0, import_jsx_runtime135.jsxs)("div", { className: "flex min-w-[240px] flex-1 flex-wrap items-center gap-x-5 gap-y-3", children: [
13086
+ /* @__PURE__ */ (0, import_jsx_runtime135.jsxs)("div", { className: "agg-settlement-summary-heading flex shrink-0 items-center gap-2", children: [
13087
+ /* @__PURE__ */ (0, import_jsx_runtime135.jsx)("p", { className: "text-agg-sm font-agg-normal leading-agg-5 text-agg-foreground", children: labels.settlementSummary.title }),
13088
+ /* @__PURE__ */ (0, import_jsx_runtime135.jsx)("span", { className: "flex size-4 shrink-0 items-center justify-center rounded-agg-full bg-agg-primary text-[10px] font-agg-bold leading-[14px] text-agg-on-primary", children: settlementDifferences.length })
13089
+ ] }),
13090
+ /* @__PURE__ */ (0, import_jsx_runtime135.jsxs)("div", { className: "agg-settlement-summary-pills flex min-w-[240px] flex-1 flex-wrap items-center gap-2", children: [
13091
+ visibleDifferences.map((difference) => /* @__PURE__ */ (0, import_jsx_runtime135.jsxs)(
13092
+ "button",
13093
+ {
13094
+ type: "button",
13095
+ className: cn(
13096
+ "flex h-6 max-w-full shrink-0 cursor-pointer items-center gap-2 rounded-agg-full bg-agg-secondary-hover px-3 py-1 text-agg-xs font-agg-normal leading-agg-4 text-agg-foreground sm:max-w-[220px]",
13097
+ "hover:opacity-80",
13098
+ "focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-agg-primary focus-visible:ring-offset-0 focus-visible:ring-offset-agg-secondary"
13099
+ ),
13100
+ onClick: (event) => handleDifferencePillClick(event, difference.canonicalKey),
13101
+ children: [
13102
+ /* @__PURE__ */ (0, import_jsx_runtime135.jsx)(
13103
+ "i",
13104
+ {
13105
+ className: cn(
13106
+ "fi",
13107
+ resolveDifferenceIconClassName(difference.canonicalKey),
13108
+ "inline-flex size-3 shrink-0 items-center justify-center text-[12px] leading-none text-agg-muted-foreground"
13109
+ ),
13110
+ "aria-hidden": "true"
13111
+ }
13112
+ ),
13113
+ /* @__PURE__ */ (0, import_jsx_runtime135.jsx)("span", { className: "min-w-0 truncate", children: difference.title })
13114
+ ]
13115
+ },
13116
+ difference.canonicalKey
13117
+ )),
13118
+ hiddenDifferenceCount > 0 ? /* @__PURE__ */ (0, import_jsx_runtime135.jsxs)("span", { className: "flex h-6 shrink-0 items-center rounded-agg-full bg-agg-secondary-hover px-3 py-1 text-agg-xs font-agg-normal leading-agg-4 text-agg-foreground", children: [
13119
+ "+",
13120
+ hiddenDifferenceCount
13121
+ ] }) : null
13122
+ ] })
13123
+ ] }),
13124
+ actionButton
13125
+ ]
12774
13126
  }
12775
- ),
12776
- /* @__PURE__ */ (0, import_jsx_runtime135.jsxs)("div", { className: "agg-settlement-summary-row flex w-full items-center gap-3", children: [
12777
- /* @__PURE__ */ (0, import_jsx_runtime135.jsx)(
12778
- "p",
12779
- {
12780
- className: cn(
12781
- "agg-settlement-summary-text",
12782
- "min-w-0 flex-1 truncate text-agg-sm leading-agg-5 text-agg-foreground"
12783
- ),
12784
- children: firstParagraph
12785
- }
13127
+ );
13128
+ }
13129
+ return /* @__PURE__ */ (0, import_jsx_runtime135.jsxs)(
13130
+ "div",
13131
+ {
13132
+ className: cn(
13133
+ "agg-settlement-summary flex w-full items-center justify-between gap-4",
13134
+ className
12786
13135
  ),
12787
- /* @__PURE__ */ (0, import_jsx_runtime135.jsx)(
12788
- "button",
12789
- {
12790
- type: "button",
12791
- className: cn(
12792
- "agg-settlement-summary-toggle",
12793
- "shrink-0 cursor-pointer whitespace-nowrap text-agg-sm font-agg-bold leading-agg-5 text-agg-primary",
12794
- "hover:opacity-80",
12795
- "focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-agg-primary focus-visible:ring-offset-0 focus-visible:ring-offset-agg-secondary"
12796
- ),
12797
- "aria-controls": settlementSectionId,
12798
- onClick: handleReadFullDetails,
12799
- children: labels.settlementSummary.readFullDetails
12800
- }
12801
- )
12802
- ] })
12803
- ] });
13136
+ children: [
13137
+ /* @__PURE__ */ (0, import_jsx_runtime135.jsxs)("div", { className: "agg-settlement-summary-row flex min-w-0 flex-1 items-center gap-5", children: [
13138
+ /* @__PURE__ */ (0, import_jsx_runtime135.jsx)("div", { className: "agg-settlement-summary-heading flex shrink-0 items-center gap-2", children: /* @__PURE__ */ (0, import_jsx_runtime135.jsx)("p", { className: "text-agg-sm font-agg-normal leading-agg-5 text-agg-foreground", children: labels.settlementSummary.title }) }),
13139
+ /* @__PURE__ */ (0, import_jsx_runtime135.jsx)(
13140
+ "p",
13141
+ {
13142
+ className: cn(
13143
+ "agg-settlement-summary-text",
13144
+ "min-w-0 flex-1 truncate text-agg-sm leading-agg-5 text-agg-foreground"
13145
+ ),
13146
+ children: firstParagraph
13147
+ }
13148
+ )
13149
+ ] }),
13150
+ actionButton
13151
+ ]
13152
+ }
13153
+ );
12804
13154
  };
12805
13155
  SettlementSummary.displayName = "SettlementSummary";
12806
13156
 
@@ -13535,7 +13885,7 @@ var EventListItemDetailsContent = ({
13535
13885
  }
13536
13886
  )
13537
13887
  ] }),
13538
- event.description ? /* @__PURE__ */ (0, import_jsx_runtime136.jsx)(SettlementSummary, { content: event.description }) : null
13888
+ event.description || event.settlementDiff ? /* @__PURE__ */ (0, import_jsx_runtime136.jsx)(SettlementSummary, { content: event.description, settlementDiff: event.settlementDiff }) : null
13539
13889
  ]
13540
13890
  }
13541
13891
  );
@@ -15821,7 +16171,7 @@ var hasContent = (value) => {
15821
16171
  return typeof value === "string" && value.trim().length > 0;
15822
16172
  };
15823
16173
  var SettlementDetails = ({ className }) => {
15824
- var _a, _b, _c, _d, _e, _f;
16174
+ var _a, _b, _c, _d, _e, _f, _g, _h;
15825
16175
  const tradingContext = (0, import_hooks50.useEventTradingContext)();
15826
16176
  const selectedEvent = (_a = tradingContext == null ? void 0 : tradingContext.selectedEvent) != null ? _a : null;
15827
16177
  const selectedMarket = (_b = tradingContext == null ? void 0 : tradingContext.selectedMarket) != null ? _b : null;
@@ -15830,16 +16180,29 @@ var SettlementDetails = ({ className }) => {
15830
16180
  const eventDescription = (_c = selectedEvent.description) != null ? _c : null;
15831
16181
  const marketDescription = (_d = selectedMarket.description) != null ? _d : null;
15832
16182
  const primaryRules = (_e = selectedMarket.rulesPrimary) != null ? _e : null;
15833
- if (!hasContent(eventDescription) && !hasContent(marketDescription) && !hasContent(primaryRules)) {
16183
+ const settlementDiff = (_f = selectedEvent.settlementDiff) != null ? _f : null;
16184
+ const settlementVenues = Array.from(
16185
+ new Set(selectedEvent.venueMarkets.map((market) => market.venue))
16186
+ );
16187
+ const selectedMarketRuleContent = [
16188
+ selectedMarket.description,
16189
+ selectedMarket.rulesPrimary,
16190
+ selectedMarket.rulesSecondary
16191
+ ].filter(hasContent).join("\n\n");
16192
+ const settlementVenueRules = selectedMarketRuleContent ? [{ venue: selectedMarket.venue, content: selectedMarketRuleContent }] : [];
16193
+ if (!hasContent(eventDescription) && !hasContent(marketDescription) && !hasContent(primaryRules) && ((_g = settlementDiff == null ? void 0 : settlementDiff.differences.length) != null ? _g : 0) === 0) {
15834
16194
  return null;
15835
16195
  }
15836
16196
  return /* @__PURE__ */ (0, import_jsx_runtime142.jsx)("div", { className: "agg-settlement-list flex flex-col gap-6", children: /* @__PURE__ */ (0, import_jsx_runtime142.jsx)("div", { className: "agg-settlement-list-item", children: /* @__PURE__ */ (0, import_jsx_runtime142.jsx)(
15837
16197
  Settlement,
15838
16198
  {
15839
- question: (_f = selectedMarket.question) != null ? _f : selectedEvent.title,
16199
+ question: (_h = selectedMarket.question) != null ? _h : selectedEvent.title,
15840
16200
  eventDescription,
15841
16201
  marketDescription,
15842
16202
  primaryRules,
16203
+ settlementDiff,
16204
+ settlementVenues,
16205
+ settlementVenueRules,
15843
16206
  className
15844
16207
  }
15845
16208
  ) }) });
@@ -20972,7 +21335,14 @@ var EventMarketPageLoadingState = ({
20972
21335
  /* @__PURE__ */ (0, import_jsx_runtime148.jsx)(MarketDetails, { isLoading: true, isOpened: true, classNames: { root: "w-full" } }),
20973
21336
  /* @__PURE__ */ (0, import_jsx_runtime148.jsx)(MarketDetails, { isLoading: true, isOpened: false, classNames: { root: "w-full" } }),
20974
21337
  /* @__PURE__ */ (0, import_jsx_runtime148.jsx)(MarketDetails, { isLoading: true, isOpened: false, classNames: { root: "w-full" } })
20975
- ] })
21338
+ ] }),
21339
+ /* @__PURE__ */ (0, import_jsx_runtime148.jsx)(
21340
+ Skeleton,
21341
+ {
21342
+ view: skeletonViews.settlement,
21343
+ className: cn("agg-settlement-list-item", classNames == null ? void 0 : classNames.settlement)
21344
+ }
21345
+ )
20976
21346
  ]
20977
21347
  }
20978
21348
  ),
@@ -21402,6 +21772,16 @@ var resolveSpreadOutcomeTeamNames = (activeMarket, groupMarkets) => {
21402
21772
  };
21403
21773
  return { favored: pickName(0), dog: pickName(1) };
21404
21774
  };
21775
+ var resolveCombinedMoneylineLegLabel = (market) => {
21776
+ const typedMarket = market;
21777
+ return toTrimmedString(typedMarket.shortTitle) || toTrimmedString(market.question);
21778
+ };
21779
+ var areCombinedMoneylineLegsDistinct = (markets) => {
21780
+ const labels = markets.map(
21781
+ (market) => resolveCombinedMoneylineLegLabel(market).toLowerCase()
21782
+ );
21783
+ return labels.every((label2) => label2.length > 0) && new Set(labels).size === labels.length;
21784
+ };
21405
21785
  var resolveDisplayGroupFamilyKey = (market) => {
21406
21786
  var _a, _b, _c;
21407
21787
  const normalizedQuestion = sanitizeFamilyValue(toTrimmedString(market.question));
@@ -22012,7 +22392,10 @@ var SportsMarketCard = ({
22012
22392
  () => group.markets.filter((market) => isBinarySportsMoneylineMarket(market)),
22013
22393
  [group.markets]
22014
22394
  );
22015
- const isCombinedMoneylineGroup = group.sportsMarketType === "moneyline" && combinedMoneylineMarkets.length > 1 && combinedMoneylineMarkets.length === group.markets.length;
22395
+ const isCombinedMoneylineGroup = group.sportsMarketType === "moneyline" && combinedMoneylineMarkets.length > 1 && combinedMoneylineMarkets.length === group.markets.length && // Per-leg pills need distinct labels — unmerged cross-venue duplicates of
22396
+ // one 2-way single ("Match Winner" ×2) would render the same Yes price
22397
+ // twice as two options; fall back to the standard team-pill card instead.
22398
+ areCombinedMoneylineLegsDistinct(combinedMoneylineMarkets);
22016
22399
  const preferredResolvedMoneylineMarket = (0, import_react36.useMemo)(() => {
22017
22400
  var _a2, _b2;
22018
22401
  if (!isCombinedMoneylineGroup) return null;
@@ -22076,18 +22459,17 @@ var SportsMarketCard = ({
22076
22459
  const combinedMoneylineHeaderOutcomeItems = (0, import_react36.useMemo)(() => {
22077
22460
  if (!isCombinedMoneylineGroup) return void 0;
22078
22461
  return combinedMoneylineMarkets.flatMap((market, index) => {
22079
- var _a2, _b2;
22080
- const typedMarket = market;
22462
+ var _a2;
22081
22463
  const yesOutcome = market.venueMarketOutcomes.find(
22082
22464
  (outcome) => outcome.label.trim().toLowerCase() === "yes"
22083
22465
  );
22084
22466
  if (!yesOutcome) return [];
22085
- const label2 = ((_a2 = typedMarket.shortTitle) == null ? void 0 : _a2.trim()) || market.question.trim();
22467
+ const label2 = resolveCombinedMoneylineLegLabel(market);
22086
22468
  if (!label2) return [];
22087
22469
  const probability = midpointsResult == null ? void 0 : getDisplayOutcomePrice({
22088
22470
  outcomeId: yesOutcome.id,
22089
22471
  outcomeLabel: yesOutcome.label,
22090
- bestMidpointsByOutcomeId: (_b2 = midpointsResult.bestMidpointsByOutcomeId) != null ? _b2 : midpointsResult.prices
22472
+ bestMidpointsByOutcomeId: (_a2 = midpointsResult.bestMidpointsByOutcomeId) != null ? _a2 : midpointsResult.prices
22091
22473
  });
22092
22474
  return [
22093
22475
  {
package/dist/pages.mjs CHANGED
@@ -8,17 +8,17 @@ import {
8
8
  UserProfilePage,
9
9
  buildAggTxExplorerHref,
10
10
  useHomePageModals
11
- } from "./chunk-FIN55CXA.mjs";
12
- import "./chunk-MDO3NMXP.mjs";
11
+ } from "./chunk-GLVLCXIM.mjs";
12
+ import "./chunk-PHRYWSNV.mjs";
13
13
  import {
14
14
  DEPOSIT_MODAL_OPEN_EVENT,
15
15
  WITHDRAW_MODAL_OPEN_EVENT,
16
16
  requestAggDepositModalOpen,
17
17
  requestAggWithdrawModalOpen
18
- } from "./chunk-3FLLEJFM.mjs";
19
- import "./chunk-G5Y45GIA.mjs";
20
- import "./chunk-G5BXCT5Y.mjs";
21
- import "./chunk-2ET5CXOU.mjs";
18
+ } from "./chunk-PHAEFHBM.mjs";
19
+ import "./chunk-STL4ZHLP.mjs";
20
+ import "./chunk-3PSIO77N.mjs";
21
+ import "./chunk-WZ55ERDO.mjs";
22
22
  export {
23
23
  DEPOSIT_MODAL_OPEN_EVENT,
24
24
  EventMarketPage,