@agg-build/ui 4.7.2 → 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.
package/dist/trading.mjs CHANGED
@@ -12,7 +12,7 @@ import {
12
12
  parseVenue,
13
13
  useClaimWinnings,
14
14
  useResolvedMarketClaim
15
- } from "./chunk-KDBKKJ7W.mjs";
15
+ } from "./chunk-SQ4BA3CC.mjs";
16
16
  import {
17
17
  SETTLEMENT_SECTION_ID,
18
18
  Settlement,
@@ -30,9 +30,9 @@ import {
30
30
  prepareSettlementDifferences,
31
31
  resolveDifferenceIconClassName,
32
32
  useEventTradingContext
33
- } from "./chunk-WYCSTAN7.mjs";
34
- import "./chunk-XN2NB2NP.mjs";
35
- import "./chunk-RDBMHBR2.mjs";
33
+ } from "./chunk-MAQ52KM5.mjs";
34
+ import "./chunk-XR6C3MZX.mjs";
35
+ import "./chunk-UQ7XJIAZ.mjs";
36
36
  export {
37
37
  FundKalshiModal,
38
38
  PlaceOrder,
@@ -97,6 +97,16 @@ export declare const resolveSportsSectionMarkets: ({ tab, eventMarkets, sectionM
97
97
  }) => VenueMarket[];
98
98
  export declare const resolveSportsMarketCardVariant: (market: VenueMarket) => SportsMarketCardVariant;
99
99
  export declare const isBinarySportsMoneylineMarket: (market: VenueMarket) => boolean;
100
+ /**
101
+ * True when this spread row's outcome 0 is the side RECEIVING points.
102
+ *
103
+ * `_sp_{team}_m{line}` puts the favourite at outcome 0 ("Yes = {team} covers
104
+ * −line"); `_sp_{team}_p{line}` puts the underdog there (novig 2026-09-01:
105
+ * `…_sp_tb_p1p5` outcomes read `Yes/TB +1.5 | No/NYM −1.5`). Callers that label
106
+ * pills "favourite −X / dog +X" must swap the two indices for these rows or the
107
+ * card shows the underdog priced as the favourite.
108
+ */
109
+ export declare const isSpreadUnderdogLeg: (market: VenueMarket) => boolean;
100
110
  export declare const isSpreadTeamTitle: (title: string | null | undefined) => boolean;
101
111
  /**
102
112
  * Resolve favored/dog team display names for a spread market's two outcomes,
@@ -105,9 +115,9 @@ export declare const isSpreadTeamTitle: (title: string | null | undefined) => bo
105
115
  * A kalshi/limitless anchor stores `Yes`/`No` labels with no clean team title,
106
116
  * so the pill would read "Yes +1.5". But the same signed line has cross-venue
107
117
  * twins (identical `_sp_{fav}_{line}` aggKey) from poly/predict that DO carry the
108
- * team name as the outcome title. Outcome index 0 is the favored side (covers
109
- * the spread) on every venue keyed `_sp_{fav}`. So borrow the fullest clean
110
- * title at each index. Returns `null` for a side when no twin has a team title
118
+ * team name as the outcome title. Outcome index 0 is the team the KEY names, so
119
+ * borrow the fullest clean title at each index, then assign the favoured/dog
120
+ * ROLES from the key's leg token (see `isSpreadUnderdogLeg`). Returns `null` for a side when no twin has a team title
111
121
  * (→ caller falls back to the raw `Yes`/`No` label). Null-aggKey spreads can't
112
122
  * be matched to twins, so only the market's own titles are considered.
113
123
  */
@@ -117,17 +127,8 @@ export declare const resolveSpreadOutcomeTeamNames: (activeMarket: VenueMarket,
117
127
  };
118
128
  /** The per-leg pill label for a combined (decomposed) moneyline group. */
119
129
  export declare const resolveCombinedMoneylineLegLabel: (market: VenueMarket) => string;
120
- /**
121
- * Combined per-leg moneyline pills are only meaningful when every leg carries a
122
- * DISTINCT label. Cross-venue duplicates of the SAME 2-way single that never
123
- * merged (e.g. poly + predict "… (BO5) - Match Winner") collapse to identical
124
- * labels — rendering them as separate pills shows the same Yes price twice as
125
- * if it were two different options. Non-distinct → the card falls back to the
126
- * standard single-market rendering (team-title pills).
127
- */
128
- export declare const areCombinedMoneylineLegsDistinct: (markets: VenueMarket[]) => boolean;
129
- export declare const buildSportsMarketDisplayGroups: (markets: VenueMarket[]) => SportsMarketDisplayGroup[];
130
- export declare const groupSportsMarketsByPeriod: (markets: VenueMarket[]) => SportsPeriodGroup[];
130
+ export declare const buildSportsMarketDisplayGroups: (markets: VenueMarket[], sport?: string | null) => SportsMarketDisplayGroup[];
131
+ export declare const groupSportsMarketsByPeriod: (markets: VenueMarket[], sport?: string | null) => SportsPeriodGroup[];
131
132
  export type SportsGameLineSlideKind = "to_advance" | "moneyline" | "spread" | "total" | "other";
132
133
  export type SportsGameLineSlideStop = {
133
134
  /** Display value for the ladder chip, e.g. "1.5", "216.5". */
@@ -151,6 +152,38 @@ export declare const collectVenueNames: (market: VenueMarket) => string[];
151
152
  export declare const resolveTotalGroupVolume: (markets: VenueMarket[]) => number;
152
153
  export declare const resolveSportsExpandedMarkets: (markets: VenueMarket[]) => VenueMarket[];
153
154
  export declare const resolveSportsExpandedMarketsVolume: (markets: VenueMarket[]) => number;
155
+ export type SportsCombinedLeg = {
156
+ /** Pill label — the fullest clean leg name across the venues offering it. */
157
+ label: string;
158
+ /** Highest-volume market at this leg; drives the order book and order ticket. */
159
+ market: VenueMarket;
160
+ /** Every venue offering this leg, including the representative's own. */
161
+ venues: string[];
162
+ };
163
+ /**
164
+ * The per-leg pills for a group a venue published as a DECOMPOSITION — one bare
165
+ * Yes/No market per outcome of a single N-way question — or `null` when the
166
+ * group is not one and should render as an ordinary card.
167
+ *
168
+ * Two shapes share the same subtype and must NOT render the same way:
169
+ *
170
+ * • a real decomposition (poly's three `soccer_halftime_result` legs), which
171
+ * belongs in one card with a pill per leg, and
172
+ * • a plain binary that several venues each list once (poly + novig "Both
173
+ * Teams to Score"), which is ONE Yes/No market with cross-venue twins.
174
+ *
175
+ * "Some venue published more than one leg" separates them structurally, with no
176
+ * guessing from prose. The moneyline path is deliberately exempt: it is gated on
177
+ * `isBinarySportsMoneylineMarket` and has shipped this way.
178
+ *
179
+ * Cross-venue twins are folded by QUESTION, not by label — poly and predict
180
+ * phrase a leg identically ("Real Betis Balompié leading at halftime?") while
181
+ * labelling it "Real Betis Balompié" vs "BET" — and the fullest label wins, the
182
+ * same preference `resolveSpreadOutcomeTeamNames` applies to spread pills.
183
+ *
184
+ * ponytail: O(n) map build over one group's markets (a handful of rows).
185
+ */
186
+ export declare const resolveSportsCombinedLegs: (group: Pick<SportsMarketDisplayGroup, "markets" | "sportsMarketType">) => SportsCombinedLeg[] | null;
154
187
  export declare const buildSportsSlideFromGroup: (group: SportsMarketDisplayGroup) => SportsGameLineSlide;
155
188
  /**
156
189
  * Derive the Moneyline / Spreads / Total game-line slides (in that order) from a
@@ -97,6 +97,16 @@ export declare const resolveSportsSectionMarkets: ({ tab, eventMarkets, sectionM
97
97
  }) => VenueMarket[];
98
98
  export declare const resolveSportsMarketCardVariant: (market: VenueMarket) => SportsMarketCardVariant;
99
99
  export declare const isBinarySportsMoneylineMarket: (market: VenueMarket) => boolean;
100
+ /**
101
+ * True when this spread row's outcome 0 is the side RECEIVING points.
102
+ *
103
+ * `_sp_{team}_m{line}` puts the favourite at outcome 0 ("Yes = {team} covers
104
+ * −line"); `_sp_{team}_p{line}` puts the underdog there (novig 2026-09-01:
105
+ * `…_sp_tb_p1p5` outcomes read `Yes/TB +1.5 | No/NYM −1.5`). Callers that label
106
+ * pills "favourite −X / dog +X" must swap the two indices for these rows or the
107
+ * card shows the underdog priced as the favourite.
108
+ */
109
+ export declare const isSpreadUnderdogLeg: (market: VenueMarket) => boolean;
100
110
  export declare const isSpreadTeamTitle: (title: string | null | undefined) => boolean;
101
111
  /**
102
112
  * Resolve favored/dog team display names for a spread market's two outcomes,
@@ -105,9 +115,9 @@ export declare const isSpreadTeamTitle: (title: string | null | undefined) => bo
105
115
  * A kalshi/limitless anchor stores `Yes`/`No` labels with no clean team title,
106
116
  * so the pill would read "Yes +1.5". But the same signed line has cross-venue
107
117
  * twins (identical `_sp_{fav}_{line}` aggKey) from poly/predict that DO carry the
108
- * team name as the outcome title. Outcome index 0 is the favored side (covers
109
- * the spread) on every venue keyed `_sp_{fav}`. So borrow the fullest clean
110
- * title at each index. Returns `null` for a side when no twin has a team title
118
+ * team name as the outcome title. Outcome index 0 is the team the KEY names, so
119
+ * borrow the fullest clean title at each index, then assign the favoured/dog
120
+ * ROLES from the key's leg token (see `isSpreadUnderdogLeg`). Returns `null` for a side when no twin has a team title
111
121
  * (→ caller falls back to the raw `Yes`/`No` label). Null-aggKey spreads can't
112
122
  * be matched to twins, so only the market's own titles are considered.
113
123
  */
@@ -117,17 +127,8 @@ export declare const resolveSpreadOutcomeTeamNames: (activeMarket: VenueMarket,
117
127
  };
118
128
  /** The per-leg pill label for a combined (decomposed) moneyline group. */
119
129
  export declare const resolveCombinedMoneylineLegLabel: (market: VenueMarket) => string;
120
- /**
121
- * Combined per-leg moneyline pills are only meaningful when every leg carries a
122
- * DISTINCT label. Cross-venue duplicates of the SAME 2-way single that never
123
- * merged (e.g. poly + predict "… (BO5) - Match Winner") collapse to identical
124
- * labels — rendering them as separate pills shows the same Yes price twice as
125
- * if it were two different options. Non-distinct → the card falls back to the
126
- * standard single-market rendering (team-title pills).
127
- */
128
- export declare const areCombinedMoneylineLegsDistinct: (markets: VenueMarket[]) => boolean;
129
- export declare const buildSportsMarketDisplayGroups: (markets: VenueMarket[]) => SportsMarketDisplayGroup[];
130
- export declare const groupSportsMarketsByPeriod: (markets: VenueMarket[]) => SportsPeriodGroup[];
130
+ export declare const buildSportsMarketDisplayGroups: (markets: VenueMarket[], sport?: string | null) => SportsMarketDisplayGroup[];
131
+ export declare const groupSportsMarketsByPeriod: (markets: VenueMarket[], sport?: string | null) => SportsPeriodGroup[];
131
132
  export type SportsGameLineSlideKind = "to_advance" | "moneyline" | "spread" | "total" | "other";
132
133
  export type SportsGameLineSlideStop = {
133
134
  /** Display value for the ladder chip, e.g. "1.5", "216.5". */
@@ -151,6 +152,38 @@ export declare const collectVenueNames: (market: VenueMarket) => string[];
151
152
  export declare const resolveTotalGroupVolume: (markets: VenueMarket[]) => number;
152
153
  export declare const resolveSportsExpandedMarkets: (markets: VenueMarket[]) => VenueMarket[];
153
154
  export declare const resolveSportsExpandedMarketsVolume: (markets: VenueMarket[]) => number;
155
+ export type SportsCombinedLeg = {
156
+ /** Pill label — the fullest clean leg name across the venues offering it. */
157
+ label: string;
158
+ /** Highest-volume market at this leg; drives the order book and order ticket. */
159
+ market: VenueMarket;
160
+ /** Every venue offering this leg, including the representative's own. */
161
+ venues: string[];
162
+ };
163
+ /**
164
+ * The per-leg pills for a group a venue published as a DECOMPOSITION — one bare
165
+ * Yes/No market per outcome of a single N-way question — or `null` when the
166
+ * group is not one and should render as an ordinary card.
167
+ *
168
+ * Two shapes share the same subtype and must NOT render the same way:
169
+ *
170
+ * • a real decomposition (poly's three `soccer_halftime_result` legs), which
171
+ * belongs in one card with a pill per leg, and
172
+ * • a plain binary that several venues each list once (poly + novig "Both
173
+ * Teams to Score"), which is ONE Yes/No market with cross-venue twins.
174
+ *
175
+ * "Some venue published more than one leg" separates them structurally, with no
176
+ * guessing from prose. The moneyline path is deliberately exempt: it is gated on
177
+ * `isBinarySportsMoneylineMarket` and has shipped this way.
178
+ *
179
+ * Cross-venue twins are folded by QUESTION, not by label — poly and predict
180
+ * phrase a leg identically ("Real Betis Balompié leading at halftime?") while
181
+ * labelling it "Real Betis Balompié" vs "BET" — and the fullest label wins, the
182
+ * same preference `resolveSpreadOutcomeTeamNames` applies to spread pills.
183
+ *
184
+ * ponytail: O(n) map build over one group's markets (a handful of rows).
185
+ */
186
+ export declare const resolveSportsCombinedLegs: (group: Pick<SportsMarketDisplayGroup, "markets" | "sportsMarketType">) => SportsCombinedLeg[] | null;
154
187
  export declare const buildSportsSlideFromGroup: (group: SportsMarketDisplayGroup) => SportsGameLineSlide;
155
188
  /**
156
189
  * Derive the Moneyline / Spreads / Total game-line slides (in that order) from a
@@ -0,0 +1,27 @@
1
+ import type { LogoIconProps } from "../logo-props";
2
+ /**
3
+ * ProphetX's mark: two arrows crossing into an X — one running bottom-left to
4
+ * top-right, the other top-left to bottom-right — drawn as three filled paths.
5
+ *
6
+ * Paths, viewBox and gradient stops are taken VERBATIM from the official asset;
7
+ * nothing here is redrawn or approximated. All three gradients run the same
8
+ * #1DC29A green to #00A7AF teal, differing only in direction and intermediate
9
+ * stops, which is what gives the crossing strokes their depth.
10
+ *
11
+ * FIRST gradient logo in this registry — every other venue mark is a single
12
+ * flat colour. Two consequences worth knowing:
13
+ *
14
+ * 1. The gradient ids MUST be per-instance. SVG resolves `url(#id)` against the
15
+ * whole document, so two of these on one page with hardcoded ids would both
16
+ * paint from whichever mounted first — and since these three gradients carry
17
+ * different `gradientTransform`s, the wrong one is visibly wrong, not merely
18
+ * duplicated. `useId` gives each instance its own namespace.
19
+ * 2. The monochrome contract still holds. `isColor={false}` or an explicit
20
+ * `color` collapses all three paths to one flat fill, so callers that need a
21
+ * single-colour mark (see `logo-probable.tsx`) get exactly that; the gradient
22
+ * is the default-brand path only.
23
+ */
24
+ export declare const LogoProphetXIcon: {
25
+ ({ title, className, isColor, color, ...props }: LogoIconProps): JSX.Element;
26
+ displayName: string;
27
+ };
@@ -0,0 +1,27 @@
1
+ import type { LogoIconProps } from "../logo-props";
2
+ /**
3
+ * ProphetX's mark: two arrows crossing into an X — one running bottom-left to
4
+ * top-right, the other top-left to bottom-right — drawn as three filled paths.
5
+ *
6
+ * Paths, viewBox and gradient stops are taken VERBATIM from the official asset;
7
+ * nothing here is redrawn or approximated. All three gradients run the same
8
+ * #1DC29A green to #00A7AF teal, differing only in direction and intermediate
9
+ * stops, which is what gives the crossing strokes their depth.
10
+ *
11
+ * FIRST gradient logo in this registry — every other venue mark is a single
12
+ * flat colour. Two consequences worth knowing:
13
+ *
14
+ * 1. The gradient ids MUST be per-instance. SVG resolves `url(#id)` against the
15
+ * whole document, so two of these on one page with hardcoded ids would both
16
+ * paint from whichever mounted first — and since these three gradients carry
17
+ * different `gradientTransform`s, the wrong one is visibly wrong, not merely
18
+ * duplicated. `useId` gives each instance its own namespace.
19
+ * 2. The monochrome contract still holds. `isColor={false}` or an explicit
20
+ * `color` collapses all three paths to one flat fill, so callers that need a
21
+ * single-colour mark (see `logo-probable.tsx`) get exactly that; the gradient
22
+ * is the default-brand path only.
23
+ */
24
+ export declare const LogoProphetXIcon: {
25
+ ({ title, className, isColor, color, ...props }: LogoIconProps): JSX.Element;
26
+ displayName: string;
27
+ };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@agg-build/ui",
3
- "version": "4.7.2",
3
+ "version": "4.7.3",
4
4
  "description": "Pre-built React component library for the AGG prediction market aggregator. Tailwind-based, themeable, with primitives, event surfaces, trading flows, full pages, and modals.",
5
5
  "sideEffects": false,
6
6
  "license": "MIT",
@@ -100,7 +100,7 @@
100
100
  "liveline": "^0.0.7",
101
101
  "react": "^18.0.0 || ^19.0.0",
102
102
  "react-dom": "^18.0.0 || ^19.0.0",
103
- "@agg-build/hooks": "^4.7.0",
103
+ "@agg-build/hooks": "^4.7.3",
104
104
  "@agg-build/sdk": "^4.7.0"
105
105
  },
106
106
  "dependencies": {