"use client";
import {
  Card,
  DEFAULT_VENUE_COLOR,
  Skeleton,
  __spreadProps,
  __spreadValues,
  cn,
  fallbackLineColors,
  formatMarketProbabilityPercent,
  formatUsd,
  getVenueSummary,
  normalizeProbability,
  normalizeVenueMarketCluster,
  resolveOutcomeTitle,
  resolveVenueLineColor,
  selectPrimaryVenueMarket,
  skeletonViews,
  sortOutcomes
} from "./chunk-34L7ZKJW.mjs";

// src/trading/trading-context/index.tsx
import { useEventTradingContext } from "@agg-build/hooks";

// src/events/orderbook/orderbook.utils.ts
import { safeParse, hasShape } from "@agg-build/sdk";
var isOrderBookLevel = (v) => hasShape(v, {
  price: (p) => typeof p === "number" && p >= 0 && p <= 1,
  size: (s) => typeof s === "number" && s >= 0
});
var isOrderBookRow = (v) => hasShape(v, {
  id: (x) => typeof x === "string",
  venue: (x) => typeof x === "string" && x.length > 0,
  price: (p) => typeof p === "number" && p >= 0 && p <= 1,
  size: (s) => typeof s === "number" && s >= 0,
  total: (t) => typeof t === "number" && t >= 0,
  tone: (x) => x === "positive" || x === "negative"
});
var formatProbabilityCents = (value) => {
  if (value == null) return "-";
  const cents = (value * 100).toFixed(1).replace(/\.0$/, "");
  return `${cents}\xA2`;
};
var resolveOrderBookRows = ({
  data,
  side
}) => {
  if (!(data == null ? void 0 : data.length)) return [];
  const tone = side === "asks" ? "negative" : "positive";
  const rows = data.flatMap((result) => {
    var _a;
    return ((_a = result.orderbook[side]) != null ? _a : []).flatMap(
      (level, index) => {
        const parsedLevel = safeParse(level, isOrderBookLevel);
        if (!parsedLevel.success) return [];
        const parsedRow = safeParse(
          {
            id: `${result.market.id}-${side}-${index}-${parsedLevel.data.price}`,
            venue: result.market.venue,
            price: parsedLevel.data.price,
            size: parsedLevel.data.size,
            total: parsedLevel.data.price * parsedLevel.data.size,
            tone
          },
          isOrderBookRow
        );
        if (!parsedRow.success) return [];
        return [parsedRow.data];
      }
    );
  });
  const sortedRows = [...rows].sort((left, right) => {
    if (side === "asks") return left.price - right.price;
    return right.price - left.price;
  });
  const maxTotal = sortedRows.reduce((currentMax, row) => Math.max(currentMax, row.total), 0) || 1;
  return sortedRows.map((row) => __spreadProps(__spreadValues({}, row), {
    barScale: row.total / maxTotal
  }));
};
var resolveUnifiedOrderBookEntries = ({
  askRows,
  bidRows,
  midPrice,
  spread
}) => {
  const asksDescending = [...askRows].reverse();
  const askCumulativeDepths = new Array(asksDescending.length);
  let cumulative = 0;
  for (let i = asksDescending.length - 1; i >= 0; i--) {
    cumulative += asksDescending[i].total;
    askCumulativeDepths[i] = cumulative;
  }
  const bidCumulativeDepths = new Array(bidRows.length);
  cumulative = 0;
  for (let i = 0; i < bidRows.length; i++) {
    cumulative += bidRows[i].total;
    bidCumulativeDepths[i] = cumulative;
  }
  const maxAskCumulative = askCumulativeDepths.length > 0 ? askCumulativeDepths[0] : 0;
  const maxBidCumulative = bidCumulativeDepths.length > 0 ? bidCumulativeDepths[bidCumulativeDepths.length - 1] : 0;
  const askMax = maxAskCumulative || 1;
  const bidMax = maxBidCumulative || 1;
  const askEntries = asksDescending.map((row, index) => ({
    kind: "ask",
    row,
    cumulativeDepth: askCumulativeDepths[index],
    unifiedBarScale: askCumulativeDepths[index] / askMax
  }));
  const bidEntries = bidRows.map((row, index) => ({
    kind: "bid",
    row,
    cumulativeDepth: bidCumulativeDepths[index],
    unifiedBarScale: bidCumulativeDepths[index] / bidMax
  }));
  const spreadEntry = { kind: "spread", midPrice, spread };
  return [...askEntries, spreadEntry, ...bidEntries];
};

// src/trading/utils.ts
import { resolveAggUiLabels } from "@agg-build/hooks";
import dayjs from "dayjs";
var defaultLabels = resolveAggUiLabels("en-US");
var defaultSettlementSectionLabel = defaultLabels.trading.settlementSection;
var defaultTradingDisclaimer = defaultLabels.trading.disclaimer;
var getTradingDateLabel = (value) => {
  const parsedValue = dayjs(value);
  if (!parsedValue.isValid()) {
    return typeof value === "string" ? value : "";
  }
  return parsedValue.format("MMM D, YYYY");
};
var getTradingVenueLabel = (venue, label) => {
  var _a;
  if (label) return label;
  if (!venue) return "Unknown";
  return (_a = defaultLabels.venues[venue]) != null ? _a : venue;
};
var getTradingValueLabel = ({
  amount,
  minimumFractionDigits = 0,
  maximumFractionDigits = 2
}) => {
  return amount.toLocaleString("en-US", {
    style: "currency",
    currency: "USD",
    minimumFractionDigits,
    maximumFractionDigits
  });
};
var getTradingPriceLabel = (value) => {
  return `${Math.round(value * 100)}\xA2`;
};
var getTradingAveragePriceLabel = (value) => {
  return defaultLabels.trading.averagePrice(value);
};
var getTradingBalanceLabel = (value) => {
  return defaultLabels.trading.balance(formatUsd(value));
};
var getTradingSharesLabel = (value) => {
  return defaultLabels.trading.shares(value);
};
var getTradingSlippageLabel = (value) => {
  return defaultLabels.trading.slippage(value);
};

// src/trading/settlement/index.tsx
import { useLabels } from "@agg-build/hooks";
import { useMemo } from "react";

// src/trading/settlement/settlement-text-renderer.tsx
import { Fragment } from "react";

// src/trading/settlement/settlement-text.utils.ts
var stripHtmlFragments = (text) => {
  return text.replace(/<\s*p\s*>/gi, "").replace(/<\s*\/\s*p\s*>/gi, "\n\n").replace(/<\s*br\s*\/?\s*>/gi, "\n").replace(/\r\n/g, "\n");
};
var isListLine = (line) => /^\s*[-*]\s+/.test(line);
var stripBullet = (line) => line.replace(/^\s*[-*]\s+/, "").trim();
var parseSettlementBlocks = (input) => {
  const normalized = stripHtmlFragments(input).trim();
  if (!normalized) return [];
  const paragraphs = normalized.split(/\n{2,}/);
  const blocks = [];
  for (const rawParagraph of paragraphs) {
    const lines = rawParagraph.split("\n").map((line) => line.replace(/\s+$/, "")).filter((line) => line.trim().length > 0);
    if (lines.length === 0) continue;
    if (lines.every(isListLine)) {
      blocks.push({ kind: "list", items: lines.map(stripBullet) });
      continue;
    }
    blocks.push({ kind: "paragraph", lines: lines.map((line) => line.trim()) });
  }
  return blocks;
};
var getFirstSettlementParagraph = (input) => {
  if (!input) return "";
  const blocks = parseSettlementBlocks(input);
  const firstParagraph = blocks.find((block) => block.kind === "paragraph");
  if (!firstParagraph || firstParagraph.kind !== "paragraph") return "";
  return firstParagraph.lines.join(" ").trim();
};
var normalizeSettlementForCompare = (input) => {
  return stripHtmlFragments(input).replace(/\s+/g, " ").trim().toLowerCase();
};
var dedupeSettlementSources = (sources) => {
  const order = ["eventDescription", "marketDescription", "primaryRules"];
  const seen = /* @__PURE__ */ new Set();
  const result = [];
  for (const key of order) {
    const value = sources[key];
    if (typeof value !== "string") continue;
    const trimmed = value.trim();
    if (!trimmed) continue;
    const fingerprint = normalizeSettlementForCompare(trimmed);
    if (!fingerprint) continue;
    if (seen.has(fingerprint)) continue;
    seen.add(fingerprint);
    result.push({ key, content: trimmed });
  }
  return result;
};

// src/trading/settlement/settlement-text-renderer.tsx
import { jsx, jsxs } from "react/jsx-runtime";
var inlineTokenRegex = new RegExp(
  [
    /\[([^\]\n]+)\]\(([^)\s]+)\)/.source,
    // 1=link text, 2=link href
    /\*\*([^*\n]+?)\*\*/.source,
    // 3=bold inner
    /`([^`\n]+?)`/.source,
    // 4=code inner
    /(https?:\/\/[^\s<>"'`]+)/.source
    // 5=bare url
  ].join("|"),
  "g"
);
var trailingUrlPunctuationRegex = /[.,;:!?)\]]+$/;
var isLinkMatch = (match) => match[1] !== void 0 && match[2] !== void 0;
var linkClassName = "agg-settlement-text-link text-agg-primary underline hover:opacity-80";
var renderInlineSegment = (text, baseKey) => {
  const nodes = [];
  let lastIndex = 0;
  let segmentIndex = 0;
  inlineTokenRegex.lastIndex = 0;
  let match;
  while ((match = inlineTokenRegex.exec(text)) !== null) {
    let matchEnd = match.index + match[0].length;
    let bareUrl = match[5];
    if (bareUrl !== void 0) {
      const trailing = trailingUrlPunctuationRegex.exec(bareUrl);
      if (trailing) {
        const trimmed = bareUrl.slice(0, bareUrl.length - trailing[0].length);
        if (trimmed.length > "https://".length) {
          bareUrl = trimmed;
          matchEnd -= trailing[0].length;
          inlineTokenRegex.lastIndex = matchEnd;
        }
      }
    }
    if (match.index > lastIndex) {
      nodes.push(
        /* @__PURE__ */ jsx(Fragment, { children: text.slice(lastIndex, match.index) }, `${baseKey}-text-${segmentIndex++}`)
      );
    }
    if (isLinkMatch(match)) {
      nodes.push(
        /* @__PURE__ */ jsx(
          "a",
          {
            href: match[2],
            target: "_blank",
            rel: "noopener noreferrer",
            className: linkClassName,
            children: match[1]
          },
          `${baseKey}-link-${segmentIndex++}`
        )
      );
    } else if (match[3] !== void 0) {
      nodes.push(
        /* @__PURE__ */ jsx(
          "strong",
          {
            className: "agg-settlement-text-bold font-agg-bold",
            children: match[3]
          },
          `${baseKey}-bold-${segmentIndex++}`
        )
      );
    } else if (match[4] !== void 0) {
      nodes.push(
        /* @__PURE__ */ jsx(
          "code",
          {
            className: "agg-settlement-text-code rounded-agg-sm bg-agg-secondary-hover px-1 py-0.5 font-mono text-[0.875em]",
            children: match[4]
          },
          `${baseKey}-code-${segmentIndex++}`
        )
      );
    } else if (bareUrl !== void 0) {
      nodes.push(
        /* @__PURE__ */ jsx(
          "a",
          {
            href: bareUrl,
            target: "_blank",
            rel: "noopener noreferrer",
            className: linkClassName,
            children: bareUrl
          },
          `${baseKey}-url-${segmentIndex++}`
        )
      );
    }
    lastIndex = matchEnd;
  }
  if (lastIndex < text.length) {
    nodes.push(
      /* @__PURE__ */ jsx(Fragment, { children: text.slice(lastIndex) }, `${baseKey}-text-${segmentIndex++}`)
    );
  }
  return nodes;
};
var renderBlock = (block, blockIndex) => {
  if (block.kind === "list") {
    return /* @__PURE__ */ jsx(
      "ul",
      {
        className: "agg-settlement-text-list list-disc pl-5 text-agg-sm leading-agg-5 text-agg-foreground",
        children: block.items.map((item, itemIndex) => /* @__PURE__ */ jsx(
          "li",
          {
            className: "agg-settlement-text-list-item",
            children: renderInlineSegment(item, `block-${blockIndex}-item-${itemIndex}`)
          },
          `block-${blockIndex}-item-${itemIndex}`
        ))
      },
      `block-${blockIndex}`
    );
  }
  return /* @__PURE__ */ jsx(
    "p",
    {
      className: "agg-settlement-text-paragraph text-agg-sm leading-agg-5 text-agg-foreground break-words [overflow-wrap:anywhere]",
      children: block.lines.map((line, lineIndex) => /* @__PURE__ */ jsxs(Fragment, { children: [
        lineIndex > 0 ? /* @__PURE__ */ jsx("br", {}) : null,
        renderInlineSegment(line, `block-${blockIndex}-line-${lineIndex}`)
      ] }, `block-${blockIndex}-line-${lineIndex}`))
    },
    `block-${blockIndex}`
  );
};
var SettlementTextRenderer = ({
  content,
  className
}) => {
  const blocks = parseSettlementBlocks(content);
  if (blocks.length === 0) return null;
  return /* @__PURE__ */ jsx("div", { className: cn("agg-settlement-text flex flex-col gap-2", className), children: blocks.map((block, blockIndex) => renderBlock(block, blockIndex)) });
};
SettlementTextRenderer.displayName = "SettlementTextRenderer";

// src/trading/settlement/index.tsx
import { jsx as jsx2, jsxs as jsxs2 } from "react/jsx-runtime";
var SETTLEMENT_SECTION_ID = "agg-settlement-section";
var getSettlementHeaderClassName = () => {
  return "flex items-center justify-between gap-4";
};
var Settlement = ({
  className,
  id = SETTLEMENT_SECTION_ID,
  sectionLabel = defaultSettlementSectionLabel,
  question,
  eventDescription,
  marketDescription,
  primaryRules,
  isLoading = false
}) => {
  var _a, _b, _c;
  const labels = useLabels();
  const blocks = useMemo(
    () => dedupeSettlementSources({
      eventDescription,
      marketDescription,
      primaryRules
    }),
    [eventDescription, marketDescription, primaryRules]
  );
  const eventBlock = (_a = blocks.find((block) => block.key === "eventDescription")) != null ? _a : null;
  const marketBlock = (_b = blocks.find((block) => block.key === "marketDescription")) != null ? _b : null;
  const primaryRulesBlock = (_c = blocks.find((block) => block.key === "primaryRules")) != null ? _c : null;
  if (isLoading) {
    return /* @__PURE__ */ jsx2(
      Skeleton,
      {
        ariaLabel: labels.trading.settlementLoading,
        className,
        view: skeletonViews.settlement
      }
    );
  }
  const resolvedSectionLabel = sectionLabel === defaultSettlementSectionLabel ? labels.trading.settlementSection : sectionLabel;
  return /* @__PURE__ */ jsxs2(
    Card,
    {
      id,
      className: cn(
        "group/agg-settlement-card",
        "flex flex-col w-full gap-5 rounded-agg-xl border border-agg-separator bg-agg-secondary p-5 shadow-none hover:shadow-none",
        className
      ),
      children: [
        /* @__PURE__ */ jsxs2("div", { className: cn("agg-settlement-header", getSettlementHeaderClassName()), children: [
          /* @__PURE__ */ jsx2("p", { className: "text-agg-xs font-agg-bold leading-agg-4 uppercase text-agg-muted-foreground", children: resolvedSectionLabel }),
          question ? /* @__PURE__ */ jsx2("p", { className: "agg-settlement-question text-agg-sm font-agg-bold leading-agg-5 text-agg-foreground", children: question }) : null
        ] }),
        blocks.length === 0 ? /* @__PURE__ */ jsx2("p", { className: "agg-settlement-empty text-agg-sm leading-agg-5 text-agg-muted-foreground", children: labels.trading.settlementEmpty }) : /* @__PURE__ */ jsxs2("div", { className: "agg-settlement-sections flex flex-col gap-4", children: [
          eventBlock || marketBlock ? /* @__PURE__ */ jsxs2(
            "div",
            {
              className: "agg-settlement-section agg-settlement-section-description",
              "data-source": "description",
              children: [
                eventBlock ? /* @__PURE__ */ jsx2("div", { "data-source": "eventDescription", children: /* @__PURE__ */ jsx2(SettlementTextRenderer, { content: eventBlock.content }) }) : null,
                eventBlock && marketBlock ? /* @__PURE__ */ jsx2("hr", { className: "agg-settlement-divider my-4 border-0 border-t border-agg-separator" }) : null,
                marketBlock ? /* @__PURE__ */ jsx2("div", { "data-source": "marketDescription", children: /* @__PURE__ */ jsx2(SettlementTextRenderer, { content: marketBlock.content }) }) : null
              ]
            }
          ) : null,
          primaryRulesBlock ? /* @__PURE__ */ jsxs2(
            "div",
            {
              className: "agg-settlement-section agg-settlement-section-primaryRules",
              "data-source": "primaryRules",
              children: [
                /* @__PURE__ */ jsx2("p", { className: "agg-settlement-section-label text-agg-xs font-agg-bold leading-agg-4 uppercase text-agg-muted-foreground mb-2", children: labels.trading.settlementPrimaryRulesLabel }),
                /* @__PURE__ */ jsx2(SettlementTextRenderer, { content: primaryRulesBlock.content })
              ]
            }
          ) : null
        ] })
      ]
    }
  );
};
Settlement.displayName = "Settlement";

// src/events/item-details/event-list-item-details.utils.ts
import dayjs2 from "dayjs";
var compareOutcomeSelectorLabels = (leftLabel, rightLabel) => {
  const leftSemanticLabel = toSemanticLabel(leftLabel);
  const rightSemanticLabel = toSemanticLabel(rightLabel);
  const binaryOrderByLabel = /* @__PURE__ */ new Map([
    ["yes", 0],
    ["no", 1]
  ]);
  const leftBinaryOrder = binaryOrderByLabel.get(leftSemanticLabel);
  const rightBinaryOrder = binaryOrderByLabel.get(rightSemanticLabel);
  if (leftBinaryOrder != null && rightBinaryOrder != null) {
    return leftBinaryOrder - rightBinaryOrder;
  }
  const leftDate = isDateLikeLabel(leftLabel) ? dayjs2(leftLabel).valueOf() : null;
  const rightDate = isDateLikeLabel(rightLabel) ? dayjs2(rightLabel).valueOf() : null;
  if (leftDate != null && rightDate != null && leftDate !== rightDate) {
    return leftDate - rightDate;
  }
  const parseNumericLabelValue = (value) => {
    const matchedValue = value.replace(/,/g, "").match(/-?\d+(\.\d+)?/);
    if (!matchedValue) return null;
    const parsedValue = Number(matchedValue[0]);
    return Number.isFinite(parsedValue) ? parsedValue : null;
  };
  const leftNumericValue = parseNumericLabelValue(leftLabel);
  const rightNumericValue = parseNumericLabelValue(rightLabel);
  if (leftNumericValue != null && rightNumericValue != null && leftNumericValue !== rightNumericValue) {
    return leftNumericValue - rightNumericValue;
  }
  return leftLabel.localeCompare(rightLabel, void 0, {
    numeric: true,
    sensitivity: "base"
  });
};
var sortOutcomeSelectorOutcomes = (outcomes) => {
  return [...outcomes].sort(
    (leftOutcome, rightOutcome) => compareOutcomeSelectorLabels(
      resolveOutcomeTitle(leftOutcome),
      resolveOutcomeTitle(rightOutcome)
    )
  );
};
var normalizeLabel = (value) => {
  return value.trim().toLowerCase().replace(/[_-]+/g, " ").replace(/[^\p{L}\p{N}\s]/gu, " ").replace(/\s+/g, " ");
};
var positiveOutcomeKeys = /* @__PURE__ */ new Set(["yes", "y", "true", "up", "buy", "long"]);
var negativeOutcomeKeys = /* @__PURE__ */ new Set(["no", "n", "false", "down", "sell", "short"]);
var toSemanticLabel = (value) => {
  const normalizedValue = normalizeLabel(value);
  if (positiveOutcomeKeys.has(normalizedValue)) return "yes";
  if (negativeOutcomeKeys.has(normalizedValue)) return "no";
  return normalizedValue;
};
var isDateLikeLabel = (value) => {
  if (!value.trim()) return false;
  return dayjs2(value).isValid();
};
var getTimeWindowByRange = (range) => {
  const endTs = dayjs2().unix();
  if (range === "1H") {
    return {
      startTs: dayjs2.unix(endTs).subtract(1, "hour").unix(),
      endTs,
      intervalMinutes: 5
    };
  }
  if (range === "6H") {
    return {
      startTs: dayjs2.unix(endTs).subtract(6, "hour").unix(),
      endTs,
      intervalMinutes: 15
    };
  }
  if (range === "1D") {
    return {
      startTs: dayjs2.unix(endTs).subtract(1, "day").unix(),
      endTs,
      intervalMinutes: 30
    };
  }
  if (range === "1W") {
    return {
      startTs: dayjs2.unix(endTs).subtract(7, "day").unix(),
      endTs,
      intervalMinutes: 60
    };
  }
  if (range === "1M") {
    return {
      startTs: dayjs2.unix(endTs).subtract(1, "month").unix(),
      endTs,
      intervalMinutes: 240
    };
  }
  return {
    startTs: dayjs2.unix(endTs).subtract(6, "month").unix(),
    endTs,
    intervalMinutes: 720
  };
};
var matchOutcomeByLabel = (outcome, selectedOutcomeLabel) => {
  const normalizedSelectedLabel = normalizeLabel(selectedOutcomeLabel);
  const semanticSelectedLabel = toSemanticLabel(selectedOutcomeLabel);
  const candidates = [resolveOutcomeTitle(outcome), outcome.label, outcome.title].filter(
    (candidate) => typeof candidate === "string" && Boolean(candidate.trim())
  ).map(normalizeLabel);
  return candidates.some((candidate) => {
    return candidate === normalizedSelectedLabel || toSemanticLabel(candidate) === semanticSelectedLabel;
  });
};
var resolveOutcomesByVenue = (venueMarkets, selectedOutcomeLabel) => {
  return venueMarkets.map((market) => {
    const matchedOutcome = sortOutcomes(market.venueMarketOutcomes).find((outcome) => {
      return matchOutcomeByLabel(outcome, selectedOutcomeLabel);
    });
    if (!matchedOutcome) return null;
    return {
      venue: market.venue,
      market,
      outcome: matchedOutcome
    };
  }).filter((item) => item != null);
};
var resolveSeriesColor = (venue, index, isDarkTheme = false) => {
  var _a;
  const colorFromVenue = resolveVenueLineColor(venue, isDarkTheme);
  if (colorFromVenue) return colorFromVenue;
  return (_a = fallbackLineColors[index % fallbackLineColors.length]) != null ? _a : DEFAULT_VENUE_COLOR;
};
var toChartDisplayValue = (value, transformProbability) => {
  if (value == null || !Number.isFinite(value)) return void 0;
  return transformProbability(value) * 100;
};
var marketChartCandleToLineChartPoint = (candle, transformProbability) => {
  var _a, _b, _c, _d;
  const open = (_a = toChartDisplayValue(candle.open, transformProbability)) != null ? _a : 0;
  const high = (_b = toChartDisplayValue(candle.high, transformProbability)) != null ? _b : open;
  const low = (_c = toChartDisplayValue(candle.low, transformProbability)) != null ? _c : open;
  const close = (_d = toChartDisplayValue(candle.close, transformProbability)) != null ? _d : open;
  return {
    time: candle.time,
    value: close,
    open,
    high,
    low,
    close
  };
};
var marketChartCandleToScaledCandlePoint = (candle, transformProbability) => {
  var _a, _b, _c, _d;
  const point = marketChartCandleToLineChartPoint(candle, transformProbability);
  return {
    time: point.time,
    open: (_a = point.open) != null ? _a : point.value,
    high: (_b = point.high) != null ? _b : point.value,
    low: (_c = point.low) != null ? _c : point.value,
    close: (_d = point.close) != null ? _d : point.value,
    v: candle.volume
  };
};
var resolveMarketChartVenueSeries = ({
  chartData,
  transformProbability
}) => {
  if (!chartData) return [];
  return Object.entries(chartData.venues).map(([venue, venueData]) => ({
    venue,
    points: venueData.candles.map(
      (candle) => marketChartCandleToLineChartPoint(candle, transformProbability)
    )
  })).filter((item) => item.points.length > 0);
};
var resolveAggregatedCandleSource = (candles) => {
  if (candles.some((candle) => candle.source === "trade")) return "trade";
  if (candles.some((candle) => candle.source === "ws")) return "ws";
  return "rest";
};
var aggregateMarketChartCandles = (candles) => {
  const candlesByTime = /* @__PURE__ */ new Map();
  candles.forEach((candle) => {
    var _a;
    const existingCandles = (_a = candlesByTime.get(candle.time)) != null ? _a : [];
    existingCandles.push(candle);
    candlesByTime.set(candle.time, existingCandles);
  });
  return [...candlesByTime.entries()].sort((left, right) => left[0] - right[0]).map(([time, timeCandles]) => {
    var _a, _b, _c, _d;
    const open = (_a = resolveAverageProbability(timeCandles.map((candle) => candle.open))) != null ? _a : 0;
    const high = (_b = resolveAverageProbability(timeCandles.map((candle) => candle.high))) != null ? _b : open;
    const low = (_c = resolveAverageProbability(timeCandles.map((candle) => candle.low))) != null ? _c : open;
    const close = (_d = resolveAverageProbability(timeCandles.map((candle) => candle.close))) != null ? _d : open;
    const volumeValues = timeCandles.map((candle) => candle.volume).filter((value) => value != null);
    return {
      time,
      open,
      high,
      low,
      close,
      volume: volumeValues.length > 0 ? volumeValues.reduce((sum, value) => sum + value, 0) : null,
      source: resolveAggregatedCandleSource(timeCandles)
    };
  });
};
var resolveChartVenueEntries = ({
  chartData,
  selectedVenue
}) => {
  if (!chartData) return [];
  const venueEntries = Object.entries(chartData.venues);
  if (!selectedVenue) return venueEntries;
  return venueEntries.filter(([venue]) => venue === selectedVenue);
};
var resolveMarketChartDisplaySeries = ({
  chartData,
  selectedVenue,
  transformProbability
}) => {
  const venueEntries = resolveChartVenueEntries({ chartData, selectedVenue });
  if (venueEntries.length === 0) return [];
  if (selectedVenue) {
    return venueEntries.map(([venue, venueData]) => ({
      venue,
      points: venueData.candles.map(
        (candle) => marketChartCandleToLineChartPoint(candle, transformProbability)
      )
    })).filter((item) => item.points.length > 0);
  }
  const aggregatedCandles = aggregateMarketChartCandles(
    venueEntries.flatMap(([, venueData]) => venueData.candles)
  );
  if (aggregatedCandles.length === 0) return [];
  return [
    {
      venue: "aggregate",
      points: aggregatedCandles.map(
        (candle) => marketChartCandleToLineChartPoint(candle, transformProbability)
      )
    }
  ];
};
var resolveAverageProbability = (values) => {
  const validValues = values.filter((value) => value != null);
  if (validValues.length === 0) return void 0;
  return validValues.reduce((sum, value) => sum + value, 0) / validValues.length;
};
var resolveMarketChartLiveState = ({
  chartData,
  selectedVenue,
  transformProbability
}) => {
  var _a, _b;
  if (!chartData) {
    return {
      liveCandle: null,
      lineValue: void 0,
      live: false
    };
  }
  const venueEntries = selectedVenue ? Object.entries(chartData.venues).filter(([venue]) => venue === selectedVenue) : Object.entries(chartData.venues);
  if (venueEntries.length === 0) {
    return {
      liveCandle: null,
      lineValue: void 0,
      live: false
    };
  }
  if (selectedVenue) {
    const selectedVenueData = (_a = venueEntries[0]) == null ? void 0 : _a[1];
    const lineValue2 = (selectedVenueData == null ? void 0 : selectedVenueData.lineValue) != null ? toChartDisplayValue(selectedVenueData.lineValue, transformProbability) : void 0;
    return {
      liveCandle: (selectedVenueData == null ? void 0 : selectedVenueData.liveCandle) ? marketChartCandleToScaledCandlePoint(selectedVenueData.liveCandle, transformProbability) : null,
      lineValue: lineValue2,
      live: (selectedVenueData == null ? void 0 : selectedVenueData.liveCandle) != null
    };
  }
  const liveCandles = aggregateMarketChartCandles(
    venueEntries.flatMap(([, venueData]) => venueData.liveCandle ? [venueData.liveCandle] : [])
  );
  const aggregatedLiveCandle = (_b = liveCandles[liveCandles.length - 1]) != null ? _b : null;
  const primaryLineValue = resolveAverageProbability(
    venueEntries.map(([, venueData]) => venueData.lineValue)
  );
  const lineValue = primaryLineValue != null ? toChartDisplayValue(primaryLineValue, transformProbability) : void 0;
  return {
    liveCandle: aggregatedLiveCandle ? marketChartCandleToScaledCandlePoint(aggregatedLiveCandle, transformProbability) : null,
    lineValue,
    live: aggregatedLiveCandle != null
  };
};

// src/events/market-details/market-details.utils.ts
import { safeParse as safeParse2 } from "@agg-build/sdk";
import dayjs3 from "dayjs";
var VALID_TABS = /* @__PURE__ */ new Set(["order-book", "graph", "other"]);
var isMarketDetailsTab = (v) => typeof v === "string" && VALID_TABS.has(v);
var normalizeLabel2 = (value) => {
  return value.trim().toLowerCase();
};
var hasBinaryLabels = (labels) => {
  const normalizedLabels = labels.map(normalizeLabel2);
  return normalizedLabels.includes("yes") && normalizedLabels.includes("no");
};
var resolveInitialTab = (defaultTab) => {
  const parsedTab = safeParse2(defaultTab, isMarketDetailsTab);
  if (parsedTab.success) return parsedTab.data;
  return "order-book";
};
var resolveMarketFromVenueMarkets = (venueMarkets, marketId) => {
  var _a, _b, _c, _d, _e, _f;
  if (!venueMarkets || venueMarkets.length === 0) return void 0;
  if (!marketId) {
    const normalizedVenueMarkets = normalizeVenueMarketCluster(venueMarkets);
    const primary = selectPrimaryVenueMarket(normalizedVenueMarkets);
    const totalVolume2 = normalizedVenueMarkets.reduce((sum, vm) => {
      return sum + (typeof vm.volume === "number" ? vm.volume : 0);
    }, 0);
    return {
      id: (_c = (_b = primary == null ? void 0 : primary.id) != null ? _b : (_a = normalizedVenueMarkets[0]) == null ? void 0 : _a.id) != null ? _c : venueMarkets[0].id,
      venueMarkets: normalizedVenueMarkets,
      volume: totalVolume2 || (primary == null ? void 0 : primary.volume),
      status: primary == null ? void 0 : primary.status,
      startDate: primary == null ? void 0 : primary.startDate,
      endDate: primary == null ? void 0 : primary.endDate,
      creationDate: primary == null ? void 0 : primary.creationDate,
      question: (_f = (_e = primary == null ? void 0 : primary.question) != null ? _e : (_d = normalizedVenueMarkets[0]) == null ? void 0 : _d.question) != null ? _f : venueMarkets[0].question
    };
  }
  const matchedVenueMarket = normalizeVenueMarketCluster(venueMarkets).find(
    (vm) => vm.id === marketId || vm.externalIdentifier === marketId
  );
  if (!matchedVenueMarket) return void 0;
  const siblingVenueMarkets = normalizeVenueMarketCluster(venueMarkets, matchedVenueMarket.id);
  const totalVolume = siblingVenueMarkets.reduce((sum, vm) => {
    return sum + (typeof vm.volume === "number" ? vm.volume : 0);
  }, 0);
  return {
    id: matchedVenueMarket.id,
    venueMarkets: siblingVenueMarkets,
    volume: totalVolume || matchedVenueMarket.volume,
    status: matchedVenueMarket.status,
    startDate: matchedVenueMarket.startDate,
    endDate: matchedVenueMarket.endDate,
    creationDate: matchedVenueMarket.creationDate,
    question: matchedVenueMarket.question
  };
};
var resolveDisplayOutcomeLabels = (labels) => {
  if (!hasBinaryLabels(labels)) return labels;
  return ["Yes", "No"].filter(
    (label) => labels.some((value) => normalizeLabel2(value) === normalizeLabel2(label))
  );
};
var resolveMarketDetailsOutcomeLabels = (venueMarkets) => {
  var _a;
  const primaryMarket = selectPrimaryVenueMarket(venueMarkets);
  const labels = /* @__PURE__ */ new Map();
  const upsertOutcome = (outcome) => {
    var _a2;
    const label = outcome.label.trim();
    if (!label) return;
    const key = normalizeLabel2(label);
    const title = ((_a2 = outcome.title) != null ? _a2 : "").trim() || label;
    const existing = labels.get(key);
    if (!existing) {
      labels.set(key, { label, title });
      return;
    }
    if (existing.title === existing.label && title !== label) {
      labels.set(key, __spreadProps(__spreadValues({}, existing), { title }));
    }
  };
  ((_a = primaryMarket == null ? void 0 : primaryMarket.venueMarketOutcomes) != null ? _a : []).forEach(upsertOutcome);
  venueMarkets.forEach((market) => sortOutcomes(market.venueMarketOutcomes).forEach(upsertOutcome));
  return [...labels.values()];
};
var resolveInitialOutcomeLabel = (labels, defaultOutcomeLabel) => {
  var _a;
  if (labels.length === 0) return void 0;
  if (defaultOutcomeLabel) {
    const matchedLabel = labels.find(
      (label) => normalizeLabel2(label) === normalizeLabel2(defaultOutcomeLabel)
    );
    if (matchedLabel) return matchedLabel;
  }
  if (hasBinaryLabels(labels)) {
    return (_a = labels.find((label) => normalizeLabel2(label) === "yes")) != null ? _a : labels[0];
  }
  return labels[0];
};
var resolveAverageProbabilityByLabel = (venueMarkets, labels) => {
  return new Map(
    labels.map((label) => {
      const matchingOutcomes = resolveOutcomesByVenue(venueMarkets, label);
      const probabilities = matchingOutcomes.map((item) => normalizeProbability(item.outcome.price)).filter((value) => value != null);
      if (!probabilities.length) {
        return [label, void 0];
      }
      const averageProbability = probabilities.reduce((sum, value) => sum + value, 0) / probabilities.length;
      return [label, averageProbability];
    })
  );
};
var formatProbabilityPercent = (value, formatPercent) => {
  return formatMarketProbabilityPercent(value, formatPercent);
};
var resolveOutcomeTone = (label, index) => {
  const normalizedLabel = normalizeLabel2(label);
  if (normalizedLabel === "yes" || normalizedLabel === "up" || normalizedLabel === "buy") {
    return "positive";
  }
  if (normalizedLabel === "no" || normalizedLabel === "down" || normalizedLabel === "sell") {
    return "negative";
  }
  return index === 0 ? "positive" : "negative";
};
var resolveHeaderOutcomeItems = (venueMarkets) => {
  const outcomes = resolveMarketDetailsOutcomeLabels(venueMarkets);
  const labels = resolveDisplayOutcomeLabels(outcomes.map((outcome) => outcome.label));
  const probabilityByLabel = resolveAverageProbabilityByLabel(venueMarkets, labels);
  return labels.slice(0, 2).map((label, index) => {
    var _a, _b, _c, _d, _e, _f, _g, _h;
    return {
      title: (_b = (_a = outcomes.find((outcome) => normalizeLabel2(outcome.label) === normalizeLabel2(label))) == null ? void 0 : _a.title) != null ? _b : label,
      id: (_d = (_c = resolveOutcomesByVenue(venueMarkets, label)[0]) == null ? void 0 : _c.outcome.id) != null ? _d : "",
      venue: (_h = (_g = (_e = resolveOutcomesByVenue(venueMarkets, label)[0]) == null ? void 0 : _e.venue) != null ? _g : (_f = venueMarkets[0]) == null ? void 0 : _f.venue) != null ? _h : "polymarket",
      label,
      probability: probabilityByLabel.get(label),
      tone: resolveOutcomeTone(label, index)
    };
  });
};
var resolveSubtitle = ({
  venueMarkets,
  volume,
  formatCompactCurrency,
  labels
}) => {
  const { venueCount } = getVenueSummary(venueMarkets);
  const parts = [
    `${venueCount} ${venueCount === 1 ? labels.marketDetails.meta.venueSingular : labels.marketDetails.meta.venuePlural}`
  ];
  if (typeof volume === "number" && volume > 0) {
    parts.push(`${formatCompactCurrency(volume)} ${labels.marketDetails.meta.volumeSuffix}`);
  }
  return parts.join(" \xB7 ");
};
var resolveOtherTabRows = (market, labels) => {
  var _a;
  const rows = [];
  rows.push({
    label: labels.marketDetails.meta.status,
    value: (_a = market.status) != null ? _a : labels.marketDetails.meta.unknown
  });
  if (market.creationDate) {
    rows.push({
      label: labels.marketDetails.meta.created,
      value: dayjs3(market.creationDate).format("MMM D, YYYY")
    });
  }
  if (market.startDate) {
    rows.push({
      label: labels.marketDetails.meta.opens,
      value: dayjs3(market.startDate).format("MMM D, YYYY")
    });
  }
  if (market.endDate) {
    rows.push({
      label: labels.marketDetails.meta.closes,
      value: dayjs3(market.endDate).format("MMM D, YYYY")
    });
  }
  if (rows.length === 1) {
    rows.push({
      label: labels.marketDetails.meta.markets,
      value: `${market.venueMarkets.length}`
    });
  }
  return rows;
};
var buildMarketDetailsModel = ({
  venueMarkets,
  marketId,
  title,
  image,
  formatCompactCurrency,
  labels
}) => {
  var _a, _b;
  const market = resolveMarketFromVenueMarkets(venueMarkets, marketId);
  if (!market) return void 0;
  const primaryVenueMarket = selectPrimaryVenueMarket(market.venueMarkets);
  if (!primaryVenueMarket) return void 0;
  const resolvedTitle = (title == null ? void 0 : title.trim()) || primaryVenueMarket.question || market.question;
  const resolvedImage = (_a = typeof image === "string" && image.trim() ? image : void 0) != null ? _a : typeof primaryVenueMarket.image === "string" && primaryVenueMarket.image.trim() ? primaryVenueMarket.image : void 0;
  const resolvedVolume = typeof market.volume === "number" ? market.volume : (_b = primaryVenueMarket.volume) != null ? _b : void 0;
  const subtitle = resolveSubtitle({
    venueMarkets: market.venueMarkets,
    volume: resolvedVolume,
    formatCompactCurrency,
    labels
  });
  const outcomeLabels = resolveDisplayOutcomeLabels(
    resolveMarketDetailsOutcomeLabels(market.venueMarkets).map((outcome) => outcome.label)
  );
  const probabilityByLabel = resolveAverageProbabilityByLabel(market.venueMarkets, outcomeLabels);
  return {
    market,
    primaryVenueMarket,
    title: resolvedTitle,
    image: resolvedImage,
    subtitle,
    outcomeLabels,
    probabilityByLabel
  };
};

// src/events/shared/event-trading-state.utils.ts
import dayjs4 from "dayjs";
var formatTradingStateDate = (value) => {
  if (!dayjs4(value).isValid()) return value;
  return dayjs4(value).format("MMM D, YYYY");
};
var resolveTradingStateTimestampLabel = (labels, state) => {
  if (state.kind === "resolved" && state.resolvesAt) {
    return labels.eventMarketPage.resolvedAt(formatTradingStateDate(state.resolvesAt));
  }
  if (state.kind === "closed" && state.endsAt) {
    return labels.eventMarketPage.closedAt(formatTradingStateDate(state.endsAt));
  }
  if (state.kind === "unopened" && state.startsAt) {
    return labels.eventMarketPage.opensAt(formatTradingStateDate(state.startsAt));
  }
  return null;
};
var resolveTradingStatePresentation = (labels, state) => {
  const timestampLabel = resolveTradingStateTimestampLabel(labels, state);
  const winningOutcomeLabel = state.winningOutcome ? labels.eventMarketPage.winningOutcome(state.winningOutcome.label) : null;
  if (state.kind === "resolved") {
    return {
      badgeLabel: labels.eventMarketPage.tradingResolvedBadge,
      title: labels.eventMarketPage.tradingResolvedTitle,
      description: labels.eventMarketPage.tradingResolvedDescription,
      iconName: "check-circle",
      timestampLabel,
      winningOutcomeLabel
    };
  }
  if (state.kind === "paused") {
    return {
      badgeLabel: labels.eventMarketPage.tradingPausedBadge,
      title: labels.eventMarketPage.tradingPausedTitle,
      description: labels.eventMarketPage.tradingPausedDescription,
      iconName: "warning-filled",
      timestampLabel,
      winningOutcomeLabel
    };
  }
  if (state.kind === "unopened") {
    return {
      badgeLabel: labels.eventMarketPage.tradingUnopenedBadge,
      title: labels.eventMarketPage.tradingUnopenedTitle,
      description: labels.eventMarketPage.tradingUnopenedDescription,
      iconName: "info",
      timestampLabel,
      winningOutcomeLabel
    };
  }
  if (state.kind === "closed") {
    return {
      badgeLabel: labels.eventMarketPage.tradingClosedBadge,
      title: labels.eventMarketPage.tradingClosedTitle,
      description: labels.eventMarketPage.tradingClosedDescription,
      iconName: "warning-filled",
      timestampLabel,
      winningOutcomeLabel
    };
  }
  return {
    badgeLabel: labels.eventMarketPage.tradingUnavailableBadge,
    title: labels.eventMarketPage.tradingUnavailableTitle,
    description: labels.eventMarketPage.tradingUnavailableDescription,
    iconName: "info",
    timestampLabel,
    winningOutcomeLabel
  };
};
var resolveTradingStateBadgeClassName = (kind) => {
  if (kind === "resolved") {
    return "border-agg-success/20 bg-agg-success/10 text-agg-success";
  }
  if (kind === "unopened") {
    return "border-agg-primary/15 bg-agg-primary/5 text-agg-primary";
  }
  if (kind === "paused") {
    return "border-agg-warning/20 bg-agg-warning/10 text-agg-warning";
  }
  if (kind === "closed") {
    return "border-agg-warning/20 bg-agg-warning/10 text-agg-warning";
  }
  return "border-agg-separator bg-agg-secondary text-agg-muted-foreground";
};
var ORDER_ELIGIBILITY_LABEL_MAP = {
  no_event_selected: (labels) => labels.trading.orderDisabledNoEvent,
  no_market_selected: (labels) => labels.trading.orderDisabledNoMarket,
  no_outcome_selected: (labels) => labels.trading.orderDisabledNoOutcome,
  event_resolved: (labels) => labels.trading.orderDisabledEventResolved,
  event_closed: (labels) => labels.trading.orderDisabledEventClosed,
  event_paused: (labels) => labels.trading.orderDisabledEventPaused,
  event_unopened: (labels) => labels.trading.orderDisabledEventUnopened,
  event_unavailable: (labels) => labels.trading.orderDisabledEventUnavailable,
  market_resolved: (labels) => labels.trading.orderDisabledMarketResolved,
  market_closed: (labels) => labels.trading.orderDisabledMarketClosed,
  market_paused: (labels) => labels.trading.orderDisabledMarketPaused,
  market_unopened: (labels) => labels.trading.orderDisabledMarketUnopened,
  market_unavailable: (labels) => labels.trading.orderDisabledMarketUnavailable
};
var resolveOrderEligibilityMessage = (labels, reason) => {
  if (reason === "eligible") return null;
  return ORDER_ELIGIBILITY_LABEL_MAP[reason](labels);
};

export {
  useEventTradingContext,
  sortOutcomeSelectorOutcomes,
  getTimeWindowByRange,
  resolveOutcomesByVenue,
  resolveSeriesColor,
  resolveMarketChartVenueSeries,
  resolveMarketChartDisplaySeries,
  resolveMarketChartLiveState,
  formatProbabilityCents,
  resolveOrderBookRows,
  resolveUnifiedOrderBookEntries,
  resolveInitialTab,
  resolveMarketFromVenueMarkets,
  resolveInitialOutcomeLabel,
  formatProbabilityPercent,
  resolveHeaderOutcomeItems,
  resolveOtherTabRows,
  buildMarketDetailsModel,
  defaultSettlementSectionLabel,
  defaultTradingDisclaimer,
  getTradingDateLabel,
  getTradingVenueLabel,
  getTradingValueLabel,
  getTradingPriceLabel,
  getTradingAveragePriceLabel,
  getTradingBalanceLabel,
  getTradingSharesLabel,
  getTradingSlippageLabel,
  getFirstSettlementParagraph,
  SETTLEMENT_SECTION_ID,
  Settlement,
  resolveTradingStatePresentation,
  resolveTradingStateBadgeClassName,
  resolveOrderEligibilityMessage
};
