{"version":3,"file":"d3.mjs","sources":["../src/type/grammar.ts","../src/adapters/d3/util.ts","../src/adapters/d3/selectors.ts","../src/adapters/d3/binders/bar.ts","../src/adapters/d3/binders/box.ts","../src/adapters/d3/binders/candlestick.ts","../src/adapters/d3/binders/heatmap.ts","../src/adapters/d3/binders/histogram.ts","../src/adapters/d3/binders/line.ts","../src/adapters/d3/binders/scatter.ts","../src/adapters/d3/binders/segmented.ts","../src/adapters/d3/binders/smooth.ts"],"sourcesContent":["/**\n * Represents the trend direction for candlestick data points.\n * Used across the application for audio palette selection and data representation.\n */\nexport type CandlestickTrend = 'Bull' | 'Bear' | 'Neutral';\n\n/**\n * Format function signature for axis values.\n * Takes a value (number or string) and returns a formatted string.\n *\n * @example\n * // Currency formatting\n * const currencyFormat: FormatFunction = (v) => `$${Number(v).toFixed(2)}`;\n *\n * @example\n * // Date formatting\n * const dateFormat: FormatFunction = (v) => new Date(v).toLocaleDateString();\n */\nexport type FormatFunction = (value: number | string) => string;\n\n/**\n * Supported format type specifiers for JSON/HTML API.\n */\nexport type FormatType = 'currency' | 'percent' | 'fixed' | 'number' | 'date' | 'scientific';\n\n/**\n * Configuration for formatting values on an axis.\n *\n * Two ways to specify formatting:\n * 1. `function` - Function body string (for custom logic)\n * 2. `type` - Format type specifier (for common patterns)\n *\n * @example\n * // Using function string\n * { \"function\": \"return `$${Number(value).toFixed(2)}`\" }\n *\n * @example\n * // Using type specifier\n * { \"type\": \"currency\", \"decimals\": 2 }\n */\nexport interface AxisFormat {\n  /**\n   * Function body string for custom formatting.\n   * The function receives `value` as parameter and must return a string.\n   *\n   * @example\n   * // Currency formatting\n   * { \"function\": \"return `$${Number(value).toFixed(2)}`\" }\n   *\n   * @example\n   * // Date formatting\n   * { \"function\": \"return new Date(value).toLocaleDateString('en-US')\" }\n   */\n  function?: string;\n\n  /**\n   * Format type specifier for common formatting patterns.\n   * Use with `decimals`, `currency`, `locale`, `dateOptions` for customization.\n   *\n   * @example\n   * { \"type\": \"currency\", \"currency\": \"USD\", \"decimals\": 2 }\n   * { \"type\": \"percent\", \"decimals\": 1 }\n   * { \"type\": \"date\", \"dateOptions\": { \"month\": \"short\", \"day\": \"numeric\" } }\n   */\n  type?: FormatType;\n\n  /**\n   * Number of decimal places for numeric formatters.\n   * Used with: currency, percent, fixed, number, scientific\n   * @default varies by type\n   */\n  decimals?: number;\n\n  /**\n   * ISO 4217 currency code for currency formatter.\n   * @default 'USD'\n   */\n  currency?: string;\n\n  /**\n   * BCP 47 locale string for locale-aware formatters.\n   * Used with: currency, number, date\n   * @default 'en-US'\n   */\n  locale?: string;\n\n  /**\n   * Options for Intl.DateTimeFormat when using date type.\n   *\n   * @example\n   * { \"month\": \"short\", \"day\": \"numeric\" } // \"Jan 15\"\n   * { \"year\": \"numeric\", \"month\": \"long\" } // \"January 2024\"\n   */\n  dateOptions?: Intl.DateTimeFormatOptions;\n}\n\n/**\n * Configuration options for violin plot display.\n * Controls which summary statistics are shown in the violin box overlay.\n * Sent from the Python backend alongside violin_kde and violin_box layers.\n */\nexport interface ViolinOptions {\n  /** Show median line marker. Default: true */\n  showMedian?: boolean;\n  /** Show mean value marker. Default: false */\n  showMean?: boolean;\n  /** Show extrema (min/max) markers. Default: true */\n  showExtrema?: boolean;\n}\n\n/**\n * Data point for violin KDE (kernel density estimation) curves.\n * Library-agnostic — no SVG coordinates embedded in data.\n * The density field falls back to width if absent.\n */\nexport interface ViolinKdePoint {\n  /** Categorical label for the violin (e.g., \"setosa\") */\n  x: string | number;\n  /** Position along the density axis */\n  y: number;\n  /** KDE density value at this point. Falls back to `width` if absent. */\n  density?: number;\n  /** Half-width of the violin at this Y level (used as density fallback) */\n  width?: number;\n  /** SVG viewport x-coordinate for highlight positioning (provided by backend) */\n  svg_x?: number;\n  /** SVG viewport y-coordinate for highlight positioning (provided by backend) */\n  svg_y?: number;\n}\n\n/**\n * Root MAIDR data structure containing figure metadata and subplot grid.\n * This is the type for the `data` prop passed to the `<Maidr>` React component.\n *\n * @example\n * ```typescript\n * const data: Maidr = {\n *   id: 'my-chart',\n *   title: 'Sales by Quarter',\n *   subplots: [[{\n *     layers: [{\n *       id: '0',\n *       type: 'bar',\n *       axes: { x: 'Quarter', y: 'Revenue' },\n *       data: [{ x: 'Q1', y: 120 }, { x: 'Q2', y: 200 }],\n *     }],\n *   }]],\n * };\n * ```\n */\nexport interface Maidr {\n  /** Unique identifier for the chart. Used for DOM element IDs. */\n  id: string;\n  /** Chart title displayed in text descriptions. */\n  title?: string;\n  /** Chart subtitle. */\n  subtitle?: string;\n  /** Chart caption. */\n  caption?: string;\n  /**\n   * 2D grid of subplots. Each row is an array of subplots.\n   * For a single chart, use `[[{ layers: [...] }]]`.\n   */\n  subplots: MaidrSubplot[][];\n}\n\n/**\n * Subplot data structure containing optional legend and trace layers.\n * A subplot groups one or more layers (traces) that share the same coordinate space.\n *\n * @example\n * ```typescript\n * const subplot: MaidrSubplot = {\n *   layers: [\n *     { id: '0', type: 'bar', axes: { x: 'X', y: 'Y' }, data: [...] },\n *     { id: '1', type: 'line', axes: { x: 'X', y: 'Y' }, data: [...] },\n *   ],\n * };\n * ```\n */\nexport interface MaidrSubplot {\n  /** Legend labels for multi-series plots. */\n  legend?: string[];\n  /** CSS selector for the subplot container element. */\n  selector?: string;\n  /** Array of trace layers in this subplot. */\n  layers: MaidrLayer[];\n}\n\n/**\n * Data point for bar charts with x and y coordinates.\n */\nexport interface BarPoint {\n  x: string | number;\n  y: number | string;\n}\n\n/**\n * Data point for boxplots containing quartiles, min/max, and outliers.\n */\nexport interface BoxPoint {\n  z: string;\n  lowerOutliers: number[];\n  min: number;\n  q1: number;\n  q2: number;\n  q3: number;\n  max: number;\n  upperOutliers: number[];\n  /** Mean value for violin plots when mean display is enabled. */\n  mean?: number;\n}\n\n/**\n * DOM selectors for boxplot visual elements.\n */\nexport interface BoxSelector {\n  lowerOutliers: string[];\n  min: string;\n  iq: string;\n  q2: string;\n  max: string;\n  upperOutliers: string[];\n  /** CSS selector for mean marker element in violin plots. */\n  mean?: string;\n  /** Optional direct CSS selector for Q1 element (bypasses iq edge derivation). */\n  q1?: string;\n  /** Optional direct CSS selector for Q3 element (bypasses iq edge derivation). */\n  q3?: string;\n}\n\n/**\n * Data point for candlestick charts with OHLC values, volume, and trend information.\n */\nexport interface CandlestickPoint {\n  value: string;\n  open: number;\n  high: number;\n  low: number;\n  close: number;\n  /** Optional volume data. May be undefined when source (e.g., Google Charts) doesn't provide it. */\n  volume?: number;\n  trend: CandlestickTrend;\n  volatility: number;\n}\n\n/**\n * Data structure for heatmap charts with x/y labels and 2D point values.\n */\nexport interface HeatmapData {\n  x: string[];\n  y: string[];\n  points: number[][];\n}\n\n/**\n * Data point for histograms extending bar points with bin ranges.\n */\nexport interface HistogramPoint extends BarPoint {\n  xMin: number;\n  xMax: number;\n  yMin: number;\n  yMax: number;\n}\n\n/**\n * Data point for line charts with optional fill color for multi-series plots.\n */\nexport interface LinePoint {\n  x: number | string;\n  y: number;\n  z?: string;\n}\n\n/**\n * Data point for scatter plots with x and y coordinates.\n */\nexport interface ScatterPoint {\n  x: number;\n  y: number;\n}\n\n/**\n * Data point for segmented/grouped bar charts with fill color identifier.\n */\nexport interface SegmentedPoint extends BarPoint {\n  z: string;\n}\n\n/**\n * Data point for smooth/regression plots with data and SVG coordinate pairs.\n */\nexport interface SmoothPoint {\n  x: number;\n  y: number;\n  svg_x: number;\n  svg_y: number;\n}\n\n/**\n * Canonical axis configuration. Every axis (x, y, z) must be specified as an\n * object of this shape. The `label` is optional and falls back to built-in\n * defaults ('X', 'Y', 'Level') when omitted.\n *\n * Grid navigation properties (`min`, `max`, `tickStep`) are currently consumed\n * by scatter-plot traces only; they are silently ignored by other trace types.\n *\n * Formatting configuration lives inline as `format` on each axis, allowing\n * different formatters per axis without a separate top-level block.\n *\n * @example\n * // Simple label\n * axes: { x: { label: \"Date\" }, y: { label: \"Price\" } }\n *\n * @example\n * // With grid navigation (scatter)\n * axes: {\n *   x: { label: \"Sepal Length\", min: 4.3, max: 7.9, tickStep: 0.7 },\n *   y: { label: \"Sepal Width\",  min: 2,   max: 4.4, tickStep: 0.5 }\n * }\n *\n * @example\n * // With formatting\n * axes: {\n *   x: { label: \"Date\" },\n *   y: { label: \"Price\", format: { type: \"currency\", decimals: 2 } }\n * }\n */\nexport interface AxisConfig {\n  /** Axis label displayed in text descriptions. Defaults applied when absent. */\n  label?: string;\n  /** Minimum value for grid navigation (scatter only). */\n  min?: number;\n  /** Maximum value for grid navigation (scatter only). */\n  max?: number;\n  /** Step size for grid navigation (scatter only). */\n  tickStep?: number;\n  /** Optional per-axis value formatting applied in text descriptions. */\n  format?: AxisFormat;\n}\n\n/**\n * Chart orientation for bar and box plots.\n */\nexport enum Orientation {\n  VERTICAL = 'vert',\n  HORIZONTAL = 'horz',\n}\n\n/**\n * DOM selectors for candlestick chart visual elements.\n */\nexport interface CandlestickSelector {\n  body: string | string[];\n  wickHigh?: string | string[];\n  wickLow?: string | string[];\n  wick?: string | string[]; // single combined wick (high-to-low) line\n  open?: string | string[];\n  close?: string | string[];\n}\n\n/**\n * Layer/trace definition containing plot type, data, and rendering configuration.\n */\nexport interface MaidrLayer {\n  id: string;\n  type: TraceType;\n  title?: string;\n  selectors?: string | string[] | BoxSelector[] | CandlestickSelector;\n  orientation?: Orientation;\n  /**\n   * Optional DOM mapping hints. When provided, individual traces can opt-in\n   * to use these hints to map DOM elements to the internal row-major data grid\n   * without changing default behavior when omitted.\n   */\n  domMapping?: {\n    /**\n     * Specify DOM flattening order for grid-like traces.\n     * 'row' => row-major, 'column' => column-major.\n     */\n    order?: 'row' | 'column';\n    /**\n     * For segmented/dodged bars, control the per-column group/level iteration.\n     * 'forward' => iterate groups top-to-bottom (as previously domOrder='forward').\n     * 'reverse' => iterate bottom-to-top (default).\n     */\n    groupDirection?: 'forward' | 'reverse';\n    /**\n     * For boxplots, control the Q1/Q3 edge mapping for IQR box.\n     * 'forward' => Q1=bottom, Q3=top (default for vertical)\n     * 'reverse' => Q1=top, Q3=bottom (for Base R vertical boxplots)\n     */\n    iqrDirection?: 'forward' | 'reverse';\n  };\n  /**\n   * Axis configuration. Every axis (x, y, z) is specified as an {@link AxisConfig}\n   * object with an optional `label`, optional grid navigation properties\n   * (`min`, `max`, `tickStep`), and optional per-axis `format`.\n   *\n   * @example\n   * // Basic labels\n   * axes: { x: { label: \"Date\" }, y: { label: \"Price\" } }\n   *\n   * @example\n   * // With per-axis formatting\n   * axes: {\n   *   x: { label: \"Date\" },\n   *   y: { label: \"Price\", format: { type: \"currency\", decimals: 2 } }\n   * }\n   *\n   * @example\n   * // With grid navigation (scatter)\n   * axes: {\n   *   x: { label: \"Sepal Length\", min: 4.3, max: 7.9, tickStep: 0.7 },\n   *   y: { label: \"Sepal Width\",  min: 2,   max: 4.4, tickStep: 0.5 }\n   * }\n   */\n  axes?: {\n    x?: AxisConfig;\n    y?: AxisConfig;\n    z?: AxisConfig;\n  };\n  /**\n   * Optional display configuration for violin plot layers (VIOLIN_KDE and VIOLIN_BOX).\n   * Controls which summary statistics are shown in the violin box overlay.\n   */\n  violinOptions?: ViolinOptions;\n  data:\n    | BarPoint[]\n    | BoxPoint[]\n    | CandlestickPoint[]\n    | HeatmapData\n    | HistogramPoint[]\n    | LinePoint[][]\n    | ScatterPoint[]\n    | SegmentedPoint[][]\n    | SmoothPoint[][]\n    | ViolinKdePoint[][];\n}\n\n/**\n * Enumeration of supported plot trace types.\n * Use these values for the `type` field in {@link MaidrLayer}.\n *\n * @example\n * ```typescript\n * import { TraceType } from 'maidr/react';\n * const layer = { id: '0', type: TraceType.BAR, ... };\n * // Or use the string value directly:\n * const layer2 = { id: '0', type: 'bar', ... };\n * ```\n */\nexport enum TraceType {\n  BAR = 'bar',\n  BOX = 'box',\n  CANDLESTICK = 'candlestick',\n  DODGED = 'dodged_bar',\n  HEATMAP = 'heat',\n  HISTOGRAM = 'hist',\n  LINE = 'line',\n  NORMALIZED = 'stacked_normalized_bar',\n  SCATTER = 'point',\n  SMOOTH = 'smooth',\n  STACKED = 'stacked_bar',\n  VIOLIN_BOX = 'violin_box',\n  VIOLIN_KDE = 'violin_kde',\n}\n","/**\n * Utility functions for the D3 adapter.\n * Handles extracting data from D3.js-bound DOM elements,\n * generating identifiers, and normalizing axis configuration.\n *\n * Selector-specific helpers (cssEscape, ensureContainerId, scopeSelector)\n * live in ./selectors.ts.\n */\n\nimport type { AxisConfig, AxisFormat, Maidr, MaidrLayer } from '../../type/grammar';\nimport type { D3AxisInput, D3BinderConfig, DataAccessor } from './types';\n\n/**\n * Interface for DOM elements with D3's `__data__` property.\n * D3.js binds data to elements via this property during `.data()` joins.\n */\ninterface D3BoundElement extends Element {\n  __data__?: unknown;\n}\n\n/**\n * Extracts the D3-bound datum from a DOM element.\n * D3.js stores bound data on the `__data__` property of DOM elements\n * after a `.data()` join.\n *\n * @param element - The DOM element to extract data from.\n * @returns The bound datum, or `undefined` if no data is bound.\n */\nexport function getD3Datum(element: Element): unknown {\n  return (element as D3BoundElement).__data__;\n}\n\n/**\n * Resolves a {@link DataAccessor} to extract a value from a datum.\n *\n * Two accessor shapes are supported:\n *\n * 1. **Function accessor** — invoked with `(datum, index)` and the return\n *    value is used verbatim. The function may return any value, including\n *    falsy values (`0`, `''`, `false`, `null`); these are preserved and\n *    returned unchanged. Function accessors are NOT validated — if they\n *    throw, the error propagates to the binder.\n *\n * 2. **String accessor** — treated as a property key on `datum`. Presence is\n *    checked with the `in` operator (NOT a truthiness/`!= null` check), so\n *    properties whose value is `0`, `''`, `false`, or `null` are still\n *    considered \"found\" and returned as-is. Only an actually-missing\n *    property triggers the helpful \"Available properties: …\" error.\n *\n * The returned value is asserted to be of type `T` without runtime\n * verification — callers that expect a specific shape (e.g. number) should\n * either pass a typed function accessor or validate the result themselves.\n *\n * Use {@link resolveAccessorOptional} when an absent property should resolve\n * to `undefined` instead of throwing (e.g. optional `fill`, outlier arrays).\n *\n * @param datum    - The data object bound to a D3 element. Must be an\n *                   object when `accessor` is a string; passing `null` or\n *                   `undefined` will produce a non-actionable runtime error\n *                   from the property lookup. Validate beforehand with the\n *                   `=== undefined || === null` guard used by the binders.\n * @param accessor - Property key or function to extract the value.\n * @param index    - The index of the element in its selection. Forwarded to\n *                   function accessors and surfaced in the missing-property\n *                   error to help locate the offending datum.\n * @returns The extracted value of type `T`.\n * @throws Error if the string accessor references a property not present on\n *         the datum (using `in`-operator semantics, NOT truthiness).\n */\nexport function resolveAccessor<T>(\n  datum: unknown,\n  accessor: DataAccessor<T>,\n  index: number,\n): T {\n  if (typeof accessor === 'function') {\n    return accessor(datum, index);\n  }\n  // String accessor: use as property key. The `in` operator preserves\n  // falsy values (0, '', false, null) — only missing keys throw.\n  const record = datum as Record<string, unknown>;\n  if (!(accessor in record)) {\n    throw new Error(\n      `Property \"${accessor}\" not found on datum at index ${index}. `\n      + `Available properties: ${Object.keys(record).join(', ')}`,\n    );\n  }\n  return record[accessor] as T;\n}\n\n/**\n * Resolves a string accessor with optional fallback-key inference.\n *\n * Call AFTER {@link queryD3Elements} returns so the first datum can be\n * sampled. When the user did NOT provide an explicit accessor\n * (`config[configKey]` is `undefined`), and the canonical `defaultKey` is\n * missing from the first datum, each name in `alternatives` is tried in\n * order. The first alternative present on the datum is returned. If nothing\n * matches, `defaultKey` is returned — which will trigger the helpful\n * \"Available properties: …\" error inside {@link resolveAccessor}.\n *\n * When the user DID provide an accessor (string or function), it is\n * returned verbatim — explicit user intent always wins.\n *\n * The `config` parameter is typed as `object` so each binder's typed\n * config (e.g. `D3BarConfig`) can be passed directly without the\n * `as unknown as Record<string, unknown>` double-cast at the call site.\n * The narrowing to a string-keyed record is performed once, internally.\n *\n * @param config       - The user's config object, looked up by `configKey`.\n * @param configKey    - The property name on `config` to check.\n * @param defaultKey   - Canonical key used when user is silent.\n * @param alternatives - Alternative keys to try if `defaultKey` is missing.\n * @param firstDatum   - First D3-bound datum; used only when the user was\n *                       silent and the default key is missing.\n * @returns A {@link DataAccessor} ready to pass to {@link resolveAccessor}.\n */\nexport function inferAccessor<T>(\n  config: object,\n  configKey: string,\n  defaultKey: string,\n  alternatives: string[],\n  firstDatum: unknown,\n): DataAccessor<T> {\n  const configRecord = config as Record<string, unknown>;\n  const userProvided = configRecord[configKey];\n  if (userProvided !== undefined) {\n    return userProvided as DataAccessor<T>;\n  }\n  if (firstDatum && typeof firstDatum === 'object') {\n    const record = firstDatum as Record<string, unknown>;\n    if (defaultKey in record) {\n      return defaultKey as DataAccessor<T>;\n    }\n    for (const alt of alternatives) {\n      if (alt in record) {\n        return alt as DataAccessor<T>;\n      }\n    }\n  }\n  return defaultKey as DataAccessor<T>;\n}\n\n/**\n * Resolves a {@link DataAccessor} like {@link resolveAccessor}, but returns\n * `undefined` instead of throwing when a string accessor references a\n * property that is NOT present on the datum (`in`-operator semantics).\n *\n * Like {@link resolveAccessor}, falsy property values (`0`, `''`, `false`,\n * `null`) are preserved — only an actually-missing key resolves to\n * `undefined`. This matters because `null` and `0` are valid data values\n * (e.g. an explicitly-null `fill`), distinct from \"the property is absent\".\n *\n * Function accessors are invoked unconditionally and their return value is\n * passed through verbatim, including any `undefined` they return.\n *\n * Use this for optional fields such as `fill`, outlier arrays, or any datum\n * shape variation where the binder should keep working when the property is\n * absent. For required fields, prefer {@link resolveAccessor} so the missing\n * property surfaces as an actionable \"Available properties: …\" error.\n */\nexport function resolveAccessorOptional<T>(\n  datum: unknown,\n  accessor: DataAccessor<T>,\n  index: number,\n): T | undefined {\n  if (typeof accessor === 'function') {\n    return accessor(datum, index);\n  }\n  const record = datum as Record<string, unknown>;\n  if (!(accessor in record)) {\n    return undefined;\n  }\n  return record[accessor] as T;\n}\n\n/**\n * Queries all matching elements within a container and returns them with\n * their D3-bound data.\n *\n * @param container - The root element (typically an SVG) to query within.\n * @param selector - CSS selector for the target elements.\n * @returns Array of `{ element, datum, index }` tuples.\n * @throws Error if the selector is empty.\n */\nexport function queryD3Elements(\n  container: Element,\n  selector: string,\n): { element: Element; datum: unknown; index: number }[] {\n  if (!selector) {\n    throw new Error('CSS selector must not be empty.');\n  }\n  const elements = Array.from(container.querySelectorAll(selector));\n  return elements.map((element, index) => ({\n    element,\n    datum: getD3Datum(element),\n    index,\n  }));\n}\n\n/**\n * Builds a richer \"no elements matched\" error that distinguishes between\n * three common failure modes so users can fix them quickly:\n *\n * 1. Nothing at all was drawn (no SVG children) — likely the binder ran\n *    before D3 rendered.\n * 2. Something was drawn but nothing matches the given selector — likely\n *    a typo, wrong class, or wrong element name.\n * 3. The selector matches elements but none carry a `__data__` binding —\n *    the DOM was drawn by hand (or by a non-D3 library), so the binder\n *    has no data to extract.\n *\n * @param container  - The root element the selector was run against.\n * @param selector   - The CSS selector the user provided.\n * @param elementKind - Human-friendly name for the target elements\n *                     (e.g. \"bar\", \"box group\", \"cell\") used in the\n *                     suggestion text.\n */\nexport function buildNoElementsError(\n  container: Element,\n  selector: string,\n  elementKind: string,\n): Error {\n  const hasAnyChildren = container.children && container.children.length > 0;\n  if (!hasAnyChildren) {\n    return new Error(\n      `No elements found for selector \"${selector}\" and the SVG appears empty. `\n      + `This usually means the binder ran before D3 finished rendering. `\n      + `Call the binder right after your \\`.data(...).join(...)\\` chain, or `\n      + `inside a React \\`useEffect\\` (not during render).`,\n    );\n  }\n\n  // Try to give a hint about what IS present so users can adjust the selector.\n  const sampleTagNames = new Set<string>();\n  for (let i = 0; i < container.children.length && sampleTagNames.size < 5; i++) {\n    sampleTagNames.add(container.children[i].tagName.toLowerCase());\n  }\n  const hint = sampleTagNames.size > 0\n    ? ` Top-level child tags present: ${Array.from(sampleTagNames).join(', ')}.`\n    : '';\n\n  return new Error(\n    `No elements found for selector \"${selector}\".${hint} `\n    + `Check that the selector matches the ${elementKind} elements you drew with D3.`,\n  );\n}\n\n/**\n * Builds a richer \"element has no D3 data bound\" error. Called when\n * `queryD3Elements` returned elements but `__data__` is missing, which\n * almost always means the SVG was built with `.append(...)` alone,\n * without a `.data(...).join(...)` chain.\n *\n * @param selector - The CSS selector that matched the element.\n * @param index    - Position of the offending element in the selection.\n */\nexport function buildNoDatumError(selector: string, index: number): Error {\n  return new Error(\n    `Element at index ${index} (matched by \"${selector}\") has no D3-bound `\n    + `\\`__data__\\` property. The binder relies on D3's data join: ensure you `\n    + `built these elements with \\`.data(yourData).join(...)\\` (or `\n    + `\\`.data(...).enter().append(...)\\`) rather than plain \\`.append(...)\\`. `\n    + `If you are using a non-D3 library, pass the data to the MAIDR schema directly.`,\n  );\n}\n\n/**\n * Generates a unique ID string for use in MAIDR data structures.\n * Uses `crypto.randomUUID()` when available, with a fallback for\n * environments that lack crypto support.\n */\nexport function generateId(): string {\n  if (typeof crypto !== 'undefined' && typeof crypto.randomUUID === 'function') {\n    return `d3-${crypto.randomUUID()}`;\n  }\n  // Fallback: combine timestamp with multiple random segments\n  const timestamp = Date.now().toString(36);\n  const a = Math.random().toString(36).slice(2, 8);\n  const b = Math.random().toString(36).slice(2, 8);\n  return `d3-${timestamp}-${a}${b}`;\n}\n\n/**\n * Normalizes a single axis input (string shorthand or AxisConfig object)\n * into a canonical AxisConfig. When the user passes a string, it becomes\n * the axis label. A shared `format` is applied only if the axis does not\n * already specify its own.\n */\nfunction normalizeAxis(\n  input: D3AxisInput | undefined,\n  sharedFormat?: AxisFormat,\n): AxisConfig | undefined {\n  if (input === undefined)\n    return undefined;\n\n  const base: AxisConfig = typeof input === 'string'\n    ? { label: input }\n    : { ...input };\n\n  if (sharedFormat && base.format === undefined) {\n    base.format = sharedFormat;\n  }\n  return base;\n}\n\n/**\n * Builds the axes configuration for a MAIDR layer per the canonical schema:\n * `{ x?: AxisConfig, y?: AxisConfig, z?: AxisConfig }`.\n *\n * Accepts the D3 adapter's user-friendly input (string labels or full\n * {@link AxisConfig} objects) and maps the D3-specific `fill` axis to the\n * canonical `z` axis used internally.\n *\n * @param axes - D3 adapter axis configuration.\n * @param format - Optional shared format applied to axes without own `format`.\n * @returns Canonical layer axes, or `undefined` if no axes provided.\n */\nexport function buildAxes(\n  axes?: D3BinderConfig['axes'],\n  format?: AxisFormat,\n): MaidrLayer['axes'] | undefined {\n  if (!axes)\n    return undefined;\n\n  const result: NonNullable<MaidrLayer['axes']> = {};\n  const x = normalizeAxis(axes.x, format);\n  const y = normalizeAxis(axes.y, format);\n  const z = normalizeAxis(axes.fill, format);\n\n  if (x)\n    result.x = x;\n  if (y)\n    result.y = y;\n  if (z)\n    result.z = z;\n\n  return Object.keys(result).length > 0 ? result : undefined;\n}\n\n/**\n * Applies the generated MAIDR schema to the SVG as a `maidr-data` attribute,\n * unless opted out via `autoApply: false`. This removes the boilerplate\n * `svg.setAttribute('maidr-data', JSON.stringify(result.maidr))` call for\n * vanilla-JS users, while staying out of the way of the React adapter\n * (which passes `autoApply: false` and hands the schema straight to\n * `<Maidr>` / `<MaidrD3>`).\n *\n * @param svg       - The target SVG element (or container).\n * @param maidr     - The MAIDR schema produced by a binder.\n * @param autoApply - When `false`, no attribute is set. When `undefined`\n *                    or any other value, the attribute is set.\n */\nexport function applyMaidrData(\n  svg: Element,\n  maidr: Maidr,\n  autoApply: boolean | undefined,\n): void {\n  if (autoApply === false)\n    return;\n  if (typeof svg.setAttribute !== 'function')\n    return;\n  svg.setAttribute('maidr-data', JSON.stringify(maidr));\n}\n","/**\n * CSS selector helpers for the D3 adapter.\n *\n * Unlike Recharts or Google Charts (which have well-defined SVG class\n * conventions), D3 gives the user complete control over the output DOM.\n * These helpers therefore do not assume any particular class structure —\n * they take user-provided selectors and derive per-element CSS paths\n * that MAIDR can use for visual highlighting.\n */\n\nimport { generateId } from './util';\n\n/**\n * Escapes a string for use in CSS selectors.\n * Uses the native `CSS.escape` when available (browsers), and falls\n * back to a basic escape for Node.js / SSR environments.\n */\nexport function cssEscape(value: string): string {\n  if (typeof CSS !== 'undefined' && typeof CSS.escape === 'function') {\n    return CSS.escape(value);\n  }\n  // Fallback: escape characters that are special in CSS identifiers\n  return value.replace(/([^\\w-])/g, '\\\\$1');\n}\n\n/**\n * Ensures a container element has an `id` attribute, generating one when\n * missing. Returns the (possibly newly assigned) id.\n *\n * MAIDR resolves layer selectors via `document.querySelector`, which is\n * page-global — a bare selector like `\"rect.bar\"` would collide with any\n * other chart on the page. By stamping the container with a stable id and\n * prefixing all emitted selectors with `#<id>`, we guarantee page-wide\n * uniqueness without requiring users to set the id themselves.\n *\n * Idempotent: re-calling on a container that already has an id is a no-op.\n *\n * @param container - The root SVG container (or any element).\n * @returns The container's id (existing or newly generated).\n */\nexport function ensureContainerId(container: Element): string {\n  if (!container.id) {\n    container.id = generateId();\n  }\n  return container.id;\n}\n\n/**\n * Scopes a user-provided selector to a container, prefixing the result with\n * the container's id so it resolves uniquely under page-global lookups\n * (`document.querySelectorAll`). When the container lacks an id, one is\n * auto-assigned via {@link ensureContainerId} so every binder emits an\n * absolutely-scoped selector without per-binder boilerplate.\n *\n * @param container - The root SVG container.\n * @param selector - The user-provided CSS selector.\n * @returns The id-scoped selector string, e.g. `#<svgId> <selector>`.\n */\nexport function scopeSelector(container: Element, selector: string): string {\n  const id = ensureContainerId(container);\n  return `#${cssEscape(id)} ${selector}`;\n}\n","/**\n * D3 binder for bar charts.\n *\n * Extracts data from D3.js-rendered bar chart SVG elements and generates\n * the MAIDR JSON schema for accessible bar chart interaction.\n */\n\nimport type { BarPoint, Maidr, MaidrLayer } from '../../../type/grammar';\nimport type { D3BarConfig, D3BinderResult } from '../types';\nimport { Orientation, TraceType } from '../../../type/grammar';\nimport { scopeSelector } from '../selectors';\nimport { applyMaidrData, buildAxes, buildNoDatumError, buildNoElementsError, generateId, inferAccessor, queryD3Elements, resolveAccessor } from '../util';\n\n/**\n * Binds a D3.js bar chart to MAIDR, generating the accessible data representation.\n *\n * Extracts data from D3-bound SVG elements (`<rect>`, `<path>`, etc.) and\n * produces a complete {@link Maidr} data structure for sonification, text\n * descriptions, braille output, and keyboard navigation.\n *\n * @remarks\n * **Timing — call after D3 has rendered.** This function reads each matched\n * element's D3-bound `__data__`: the x (category) and y (numeric) properties\n * you name via the `x` / `y` accessors. Calling it before `.data().join()`\n * has run (or before the SVG is mounted) throws \"No elements found for\n * selector …\" or \"Property '…' not found on datum\".\n *\n * Typical call sites:\n * - **Vanilla JS:** right after your `selectAll(...).data(...).join(...)` chain.\n * - **React:** inside `useEffect`, never during render. Prefer\n *   {@link MaidrD3} / {@link useD3Adapter} from `maidr/react`, which\n *   handle the post-render timing for you.\n * - **Async data:** inside the `.then(...)` of your fetch, after drawing.\n *\n * @see {@link MaidrD3}\n * @see {@link useD3Adapter}\n *\n * @param svg - The SVG element (or container) containing the D3 bar chart.\n * @param config - Configuration specifying the selector and data accessors.\n * @returns A {@link D3BinderResult} with the MAIDR data and generated layer.\n *\n * @example\n * ```ts\n * // D3 bar chart with data bound to <rect> elements\n * const result = bindD3Bar(svgElement, {\n *   selector: 'rect.bar',\n *   title: 'Sales by Quarter',\n *   axes: { x: 'Quarter', y: 'Revenue' },\n *   x: 'quarter',     // property name on the bound datum\n *   y: 'revenue',     // property name on the bound datum\n * });\n *\n * // Use with maidr-data attribute\n * svgElement.setAttribute('maidr-data', JSON.stringify(result.maidr));\n *\n * // Or use with React\n * <Maidr data={result.maidr}><svg>...</svg></Maidr>\n * ```\n */\nexport function bindD3Bar(svg: Element, config: D3BarConfig): D3BinderResult {\n  const {\n    id = generateId(),\n    title,\n    subtitle,\n    caption,\n    axes,\n    format,\n    selector,\n    orientation = Orientation.VERTICAL,\n    autoApply,\n  } = config;\n\n  const elements = queryD3Elements(svg, selector);\n  if (elements.length === 0) {\n    throw buildNoElementsError(svg, selector, 'bar');\n  }\n\n  // Infer accessors from the first datum's keys when the user did not specify.\n  const firstDatum = elements[0].datum;\n  const xAccessor = inferAccessor<string | number>(\n    config,\n    'x',\n    'x',\n    ['category', 'label', 'name', 'key', 'date'],\n    firstDatum,\n  );\n  const yAccessor = inferAccessor<number | string>(\n    config,\n    'y',\n    'y',\n    ['value', 'count', 'amount', 'total'],\n    firstDatum,\n  );\n\n  const data: BarPoint[] = elements.map(({ datum, index }) => {\n    if (datum === undefined || datum === null) {\n      throw buildNoDatumError(selector, index);\n    }\n    return {\n      x: resolveAccessor<string | number>(datum, xAccessor, index),\n      y: resolveAccessor<number | string>(datum, yAccessor, index),\n    };\n  });\n\n  const layerId = generateId();\n  const layer: MaidrLayer = {\n    id: layerId,\n    type: TraceType.BAR,\n    title,\n    selectors: scopeSelector(svg, selector),\n    orientation,\n    axes: buildAxes(axes, format),\n    data,\n  };\n\n  const maidr: Maidr = {\n    id,\n    title,\n    subtitle,\n    caption,\n    subplots: [[{ layers: [layer] }]],\n  };\n\n  applyMaidrData(svg, maidr, autoApply);\n  return { maidr, layer };\n}\n","/**\n * D3 binder for box plots.\n *\n * Extracts data from D3.js-rendered box plot SVG elements and generates\n * the MAIDR JSON schema for accessible box plot interaction.\n */\n\nimport type { BoxPoint, BoxSelector, Maidr, MaidrLayer } from '../../../type/grammar';\nimport type { D3BinderResult, D3BoxConfig } from '../types';\nimport { Orientation, TraceType } from '../../../type/grammar';\nimport { cssEscape, ensureContainerId } from '../selectors';\nimport { applyMaidrData, buildAxes, buildNoDatumError, buildNoElementsError, generateId, getD3Datum, queryD3Elements, resolveAccessor, resolveAccessorOptional } from '../util';\n\n/**\n * Binds a D3.js box plot to MAIDR, generating the accessible data representation.\n *\n * Box plots in D3 are typically constructed from multiple SVG elements per box\n * (a rect for the IQR, lines for whiskers, a line for the median, and circles\n * for outliers). This binder extracts statistical summary data from D3-bound\n * data on the box group elements.\n *\n * @remarks\n * **Timing — call after D3 has rendered.** This function reads each matched\n * box-group element's D3-bound `__data__`: the 5-number summary\n * (`min`/`q1`/`q2`/`q3`/`max`) plus optional outlier arrays. Calling it\n * before `.data().join()` has run (or before the SVG is mounted) throws\n * \"No elements found for selector …\" or \"Property '…' not found on datum\".\n *\n * Typical call sites:\n * - **Vanilla JS:** right after your `selectAll(...).data(...).join(...)` chain.\n * - **React:** inside `useEffect`, never during render. Prefer\n *   {@link MaidrD3} / {@link useD3Adapter} from `maidr/react`, which\n *   handle the post-render timing for you.\n * - **Async data:** inside the `.then(...)` of your fetch, after drawing.\n *\n * @see {@link MaidrD3}\n * @see {@link useD3Adapter}\n *\n * @param svg - The SVG element containing the D3 box plot.\n * @param config - Configuration specifying selectors and data accessors.\n * @returns A {@link D3BinderResult} with the MAIDR data and generated layer.\n *\n * @example\n * ```ts\n * const result = bindD3Box(svgElement, {\n *   selector: 'g.box',\n *   title: 'Distribution by Category',\n *   axes: { x: 'Category', y: 'Value' },\n *   fill: 'category',\n *   min: 'whiskerLow',\n *   q1: 'q1',\n *   q2: 'median',\n *   q3: 'q3',\n *   max: 'whiskerHigh',\n *   lowerOutliers: 'lowOutliers',\n *   upperOutliers: 'highOutliers',\n * });\n * ```\n */\nexport function bindD3Box(svg: Element, config: D3BoxConfig): D3BinderResult {\n  const {\n    id = generateId(),\n    title,\n    subtitle,\n    caption,\n    axes,\n    format,\n    selector,\n    fill: fillAccessor = 'fill',\n    min: minAccessor = 'min',\n    q1: q1Accessor = 'q1',\n    q2: q2Accessor = 'q2',\n    q3: q3Accessor = 'q3',\n    max: maxAccessor = 'max',\n    lowerOutliers: lowerOutliersAccessor = 'lowerOutliers',\n    upperOutliers: upperOutliersAccessor = 'upperOutliers',\n    orientation = Orientation.VERTICAL,\n    autoApply,\n  } = config;\n\n  const boxGroups = queryD3Elements(svg, selector);\n  if (boxGroups.length === 0) {\n    throw buildNoElementsError(svg, selector, 'box group');\n  }\n\n  const data: BoxPoint[] = boxGroups.map(({ element, datum, index }) => {\n    // Try to get data from the group element's D3 binding first\n    let effectiveDatum = datum;\n\n    // If no data on the group, try to find it on child elements\n    if (effectiveDatum === undefined || effectiveDatum === null) {\n      const firstChild = element.querySelector('rect, line, path');\n      if (firstChild) {\n        effectiveDatum = getD3Datum(firstChild);\n      }\n    }\n\n    if (effectiveDatum === undefined || effectiveDatum === null) {\n      throw buildNoDatumError(selector, index);\n    }\n\n    // Outlier arrays are optional - use resolveAccessorOptional\n    const lowerOutliers = resolveAccessorOptional<number[]>(effectiveDatum, lowerOutliersAccessor, index) ?? [];\n    const upperOutliers = resolveAccessorOptional<number[]>(effectiveDatum, upperOutliersAccessor, index) ?? [];\n\n    return {\n      z: resolveAccessor<string>(effectiveDatum, fillAccessor, index),\n      lowerOutliers,\n      min: resolveAccessor<number>(effectiveDatum, minAccessor, index),\n      q1: resolveAccessor<number>(effectiveDatum, q1Accessor, index),\n      q2: resolveAccessor<number>(effectiveDatum, q2Accessor, index),\n      q3: resolveAccessor<number>(effectiveDatum, q3Accessor, index),\n      max: resolveAccessor<number>(effectiveDatum, maxAccessor, index),\n      upperOutliers,\n    };\n  });\n\n  const layerId = generateId();\n\n  // Ensure the SVG has a stable id so selectors can be absolutely scoped\n  // (consumers resolve selectors via global `document.querySelector`, so they\n  // must be unique page-wide). `ensureContainerId` auto-assigns an id when\n  // the user-supplied SVG lacks one, mirroring `scopeSelector`'s behaviour.\n  const svgId = ensureContainerId(svg);\n\n  // BoxTrace.mapToSvgElements (src/model/box.ts) requires one BoxSelector\n  // object per box (it bails when `selectors.length !== points.length`). A\n  // bare `scopeSelector(svg, selector)` yields a single string, whose `.length`\n  // is the character count — the model fails silently and no highlight renders.\n  //\n  // Stamp each box group + its sub-parts with MAIDR-owned data attributes so\n  // we can emit absolutely-scoped, structurally-stable selectors. This mirrors\n  // the line-path stamping in `binders/line.ts` and the Google Charts adapter's\n  // `data-maidr-*` convention. `removeAttribute` before `setAttribute` keeps\n  // rebinding idempotent when D3 re-runs a data join.\n  const isHorizontal = orientation === Orientation.HORIZONTAL;\n\n  const boxSelectors: BoxSelector[] = boxGroups.map(({ element }, boxIndex) => {\n    element.removeAttribute('data-maidr-box-index');\n    element.setAttribute('data-maidr-box-index', String(boxIndex));\n\n    // Direct children only: D3 box groups pack rect/lines/circles as siblings.\n    // Using descendant queries would pick up decoration nested deeper (legend\n    // swatches, title text, etc.) which happen to share tag names.\n    const children = Array.from(element.children);\n    const rect = children.find(c => c.localName === 'rect') as SVGRectElement | undefined;\n    if (!rect) {\n      throw new Error(\n        `D3 box binder: no <rect> found inside \"${selector}\"[${boxIndex}]. `\n        + `Each box group must contain a <rect> representing the IQR body.`,\n      );\n    }\n    rect.removeAttribute('data-maidr-box-part');\n    rect.setAttribute('data-maidr-box-part', 'iq');\n\n    // Rect bounds define the coordinate system for classifying sibling\n    // lines/outliers relative to the IQR body.\n    const rectX = Number(rect.getAttribute('x') ?? 0);\n    const rectY = Number(rect.getAttribute('y') ?? 0);\n    const rectW = Number(rect.getAttribute('width') ?? 0);\n    const rectH = Number(rect.getAttribute('height') ?? 0);\n    const rectCx = rectX + rectW / 2;\n    const rectCy = rectY + rectH / 2;\n\n    // Classify each <line>. Role swaps by orientation:\n    //   Vertical boxplot:   median = horizontal line (|dx| > |dy|)\n    //                       whiskers = vertical lines (above/below rect center)\n    //   Horizontal boxplot: median = vertical line   (|dy| > |dx|)\n    //                       whiskers = horizontal lines (left/right of rect center)\n    const lines = children.filter(c => c.localName === 'line') as SVGLineElement[];\n    for (const line of lines) {\n      const x1 = Number(line.getAttribute('x1') ?? 0);\n      const y1 = Number(line.getAttribute('y1') ?? 0);\n      const x2 = Number(line.getAttribute('x2') ?? 0);\n      const y2 = Number(line.getAttribute('y2') ?? 0);\n      const dx = Math.abs(x2 - x1);\n      const dy = Math.abs(y2 - y1);\n      const midX = (x1 + x2) / 2;\n      const midY = (y1 + y2) / 2;\n\n      line.removeAttribute('data-maidr-box-part');\n\n      let part: 'q2' | 'lower-whisker' | 'upper-whisker';\n      if (isHorizontal) {\n        if (dy > dx) {\n          part = 'q2';\n        } else {\n          part = midX < rectCx ? 'lower-whisker' : 'upper-whisker';\n        }\n      } else {\n        if (dx > dy) {\n          part = 'q2';\n        } else {\n          // SVG y grows downward, so a larger midpoint y is visually below\n          // the rect center ⇒ lower whisker.\n          part = midY > rectCy ? 'lower-whisker' : 'upper-whisker';\n        }\n      }\n      line.setAttribute('data-maidr-box-part', part);\n    }\n\n    // Classify outlier markers. D3 boxplots commonly use <circle>; a D3\n    // chart may omit outliers entirely, in which case we emit empty arrays\n    // (BoxTrace tolerates this per the type contract).\n    const outlierEls = children.filter(c => c.localName === 'circle') as SVGCircleElement[];\n    const lowerOutlierIndices: number[] = [];\n    const upperOutlierIndices: number[] = [];\n\n    outlierEls.forEach((outlier, outlierIndex) => {\n      const cx = Number(outlier.getAttribute('cx') ?? 0);\n      const cy = Number(outlier.getAttribute('cy') ?? 0);\n      const isLower = isHorizontal ? cx < rectCx : cy > rectCy;\n      outlier.removeAttribute('data-maidr-box-part');\n      outlier.removeAttribute('data-maidr-outlier-index');\n      outlier.setAttribute(\n        'data-maidr-box-part',\n        isLower ? 'lower-outlier' : 'upper-outlier',\n      );\n      outlier.setAttribute('data-maidr-outlier-index', String(outlierIndex));\n      (isLower ? lowerOutlierIndices : upperOutlierIndices).push(outlierIndex);\n    });\n\n    const base = `#${cssEscape(svgId)} ${selector}[data-maidr-box-index=\"${boxIndex}\"]`;\n    return {\n      lowerOutliers: lowerOutlierIndices.map(\n        i => `${base} [data-maidr-box-part=\"lower-outlier\"][data-maidr-outlier-index=\"${i}\"]`,\n      ),\n      min: `${base} [data-maidr-box-part=\"lower-whisker\"]`,\n      iq: `${base} [data-maidr-box-part=\"iq\"]`,\n      q2: `${base} [data-maidr-box-part=\"q2\"]`,\n      max: `${base} [data-maidr-box-part=\"upper-whisker\"]`,\n      upperOutliers: upperOutlierIndices.map(\n        i => `${base} [data-maidr-box-part=\"upper-outlier\"][data-maidr-outlier-index=\"${i}\"]`,\n      ),\n    };\n  });\n\n  const layer: MaidrLayer = {\n    id: layerId,\n    type: TraceType.BOX,\n    title,\n    selectors: boxSelectors,\n    orientation,\n    axes: buildAxes(axes, format),\n    data,\n  };\n\n  const maidr: Maidr = {\n    id,\n    title,\n    subtitle,\n    caption,\n    subplots: [[{ layers: [layer] }]],\n  };\n\n  applyMaidrData(svg, maidr, autoApply);\n  return { maidr, layer };\n}\n","/**\n * D3 binder for candlestick charts.\n *\n * Extracts data from D3.js-rendered candlestick chart SVG elements and generates\n * the MAIDR JSON schema for accessible candlestick chart interaction.\n */\n\nimport type { CandlestickPoint, CandlestickTrend, Maidr, MaidrLayer } from '../../../type/grammar';\nimport type { D3BinderResult, D3CandlestickConfig } from '../types';\nimport { TraceType } from '../../../type/grammar';\nimport { scopeSelector } from '../selectors';\nimport { applyMaidrData, buildAxes, buildNoDatumError, buildNoElementsError, generateId, queryD3Elements, resolveAccessor, resolveAccessorOptional } from '../util';\n\n/**\n * Binds a D3.js candlestick chart to MAIDR.\n *\n * Candlestick charts show OHLC (Open, High, Low, Close) data for financial\n * time series. This binder extracts data from D3-bound SVG elements\n * representing candlestick bodies (typically `<rect>`) and optional wicks.\n *\n * @remarks\n * **Timing — call after D3 has rendered.** This function reads each matched\n * element's D3-bound `__data__`: the OHLC + volume bound to each candlestick\n * body. Calling it before `.data().join()` has run (or before the SVG is\n * mounted) throws \"No elements found for selector …\" or \"Property '…' not\n * found on datum\".\n *\n * Typical call sites:\n * - **Vanilla JS:** right after your `selectAll(...).data(...).join(...)` chain.\n * - **React:** inside `useEffect`, never during render. Prefer\n *   {@link MaidrD3} / {@link useD3Adapter} from `maidr/react`, which\n *   handle the post-render timing for you.\n * - **Async data:** inside the `.then(...)` of your fetch, after drawing.\n *\n * @see {@link MaidrD3}\n * @see {@link useD3Adapter}\n *\n * @param svg - The SVG element containing the D3 candlestick chart.\n * @param config - Configuration specifying the selector and data accessors.\n * @returns A {@link D3BinderResult} with the MAIDR data and generated layer.\n *\n * @example\n * ```ts\n * const result = bindD3Candlestick(svgElement, {\n *   selector: 'rect.candle',\n *   title: 'Stock Price',\n *   axes: { x: 'Date', y: 'Price ($)' },\n *   value: 'date',\n *   open: 'open',\n *   high: 'high',\n *   low: 'low',\n *   close: 'close',\n *   volume: 'volume',\n * });\n * ```\n */\nexport function bindD3Candlestick(svg: Element, config: D3CandlestickConfig): D3BinderResult {\n  const {\n    id = generateId(),\n    title,\n    subtitle,\n    caption,\n    axes,\n    format,\n    selector,\n    value: valueAccessor = 'value',\n    open: openAccessor = 'open',\n    high: highAccessor = 'high',\n    low: lowAccessor = 'low',\n    close: closeAccessor = 'close',\n    volume: volumeAccessor = 'volume',\n    trend: trendAccessor,\n    autoApply,\n  } = config;\n\n  const elements = queryD3Elements(svg, selector);\n  if (elements.length === 0) {\n    throw buildNoElementsError(svg, selector, 'candlestick');\n  }\n\n  const data: CandlestickPoint[] = elements.map(({ datum, index }) => {\n    if (datum === undefined || datum === null) {\n      throw buildNoDatumError(selector, index);\n    }\n\n    const openVal = resolveAccessor<number>(datum, openAccessor, index);\n    const closeVal = resolveAccessor<number>(datum, closeAccessor, index);\n    const highVal = resolveAccessor<number>(datum, highAccessor, index);\n    const lowVal = resolveAccessor<number>(datum, lowAccessor, index);\n\n    // Compute trend if not provided\n    let trend: CandlestickTrend;\n    if (trendAccessor) {\n      trend = resolveAccessor<CandlestickTrend>(datum, trendAccessor, index);\n    } else if (closeVal > openVal) {\n      trend = 'Bull';\n    } else if (closeVal < openVal) {\n      trend = 'Bear';\n    } else {\n      trend = 'Neutral';\n    }\n\n    const volumeVal = resolveAccessorOptional<number>(datum, volumeAccessor, index) ?? 0;\n\n    return {\n      value: resolveAccessor<string>(datum, valueAccessor, index),\n      open: openVal,\n      high: highVal,\n      low: lowVal,\n      close: closeVal,\n      volume: volumeVal,\n      trend,\n      volatility: highVal - lowVal,\n    };\n  });\n\n  const layerId = generateId();\n  const layer: MaidrLayer = {\n    id: layerId,\n    type: TraceType.CANDLESTICK,\n    title,\n    selectors: scopeSelector(svg, selector),\n    axes: buildAxes(axes, format),\n    data,\n  };\n\n  const maidr: Maidr = {\n    id,\n    title,\n    subtitle,\n    caption,\n    subplots: [[{ layers: [layer] }]],\n  };\n\n  applyMaidrData(svg, maidr, autoApply);\n  return { maidr, layer };\n}\n","/**\n * D3 binder for heatmaps.\n *\n * Extracts data from D3.js-rendered heatmap SVG elements and generates\n * the MAIDR JSON schema for accessible heatmap interaction.\n */\n\nimport type { HeatmapData, Maidr, MaidrLayer } from '../../../type/grammar';\nimport type { D3BinderResult, D3HeatmapConfig } from '../types';\nimport { TraceType } from '../../../type/grammar';\nimport { scopeSelector } from '../selectors';\nimport { applyMaidrData, buildAxes, buildNoDatumError, buildNoElementsError, generateId, inferAccessor, queryD3Elements, resolveAccessor } from '../util';\n\n/**\n * Binds a D3.js heatmap to MAIDR, generating the accessible data representation.\n *\n * Extracts cell data from D3-bound SVG elements (`<rect>`) organized in a grid\n * and produces a complete {@link Maidr} data structure. The cells are grouped\n * by their x and y category values to form the 2D points grid.\n *\n * @remarks\n * **Timing — call after D3 has rendered.** This function reads each matched\n * element's D3-bound `__data__`: the x/y category pair and cell value bound\n * to each heatmap cell. Calling it before `.data().join()` has run (or\n * before the SVG is mounted) throws \"No elements found for selector …\" or\n * \"Property '…' not found on datum\".\n *\n * Typical call sites:\n * - **Vanilla JS:** right after your `selectAll(...).data(...).join(...)` chain.\n * - **React:** inside `useEffect`, never during render. Prefer\n *   {@link MaidrD3} / {@link useD3Adapter} from `maidr/react`, which\n *   handle the post-render timing for you.\n * - **Async data:** inside the `.then(...)` of your fetch, after drawing.\n *\n * @see {@link MaidrD3}\n * @see {@link useD3Adapter}\n *\n * @param svg - The SVG element containing the D3 heatmap.\n * @param config - Configuration specifying the selector and data accessors.\n * @returns A {@link D3BinderResult} with the MAIDR data and generated layer.\n * @throws Error if any cell coordinate pair is missing from the extracted data.\n *\n * @example\n * ```ts\n * const result = bindD3Heatmap(svgElement, {\n *   selector: 'rect.cell',\n *   title: 'Correlation Matrix',\n *   axes: { x: 'Variable', y: 'Variable', fill: 'Correlation' },\n *   x: 'xVar',\n *   y: 'yVar',\n *   value: 'correlation',\n * });\n * ```\n */\nexport function bindD3Heatmap(svg: Element, config: D3HeatmapConfig): D3BinderResult {\n  const {\n    id = generateId(),\n    title,\n    subtitle,\n    caption,\n    axes,\n    format,\n    selector,\n    autoApply,\n  } = config;\n\n  const elements = queryD3Elements(svg, selector);\n  if (elements.length === 0) {\n    throw buildNoElementsError(svg, selector, 'heatmap cell');\n  }\n\n  // Infer accessors from the first datum's keys when the user did not specify.\n  const firstDatum = elements[0].datum;\n  const xAccessor = inferAccessor<string>(\n    config,\n    'x',\n    'x',\n    ['xLabel', 'xVar', 'category', 'col', 'column'],\n    firstDatum,\n  );\n  const yAccessor = inferAccessor<string>(\n    config,\n    'y',\n    'y',\n    ['yLabel', 'yVar', 'group', 'row'],\n    firstDatum,\n  );\n  const valueAccessor = inferAccessor<number>(\n    config,\n    'value',\n    'value',\n    ['count', 'amount', 'v', 'z', 'correlation'],\n    firstDatum,\n  );\n\n  // Extract raw cell data\n  const cells: { x: string; y: string; value: number }[] = elements.map(({ datum, index }) => {\n    if (datum === undefined || datum === null) {\n      throw buildNoDatumError(selector, index);\n    }\n    return {\n      x: String(resolveAccessor<string>(datum, xAccessor, index)),\n      y: String(resolveAccessor<string>(datum, yAccessor, index)),\n      value: resolveAccessor<number>(datum, valueAccessor, index),\n    };\n  });\n\n  // Build unique x and y labels (preserving order of appearance)\n  const xLabels: string[] = [];\n  const yLabels: string[] = [];\n  const seenX = new Set<string>();\n  const seenY = new Set<string>();\n\n  for (const cell of cells) {\n    if (!seenX.has(cell.x)) {\n      seenX.add(cell.x);\n      xLabels.push(cell.x);\n    }\n    if (!seenY.has(cell.y)) {\n      seenY.add(cell.y);\n      yLabels.push(cell.y);\n    }\n  }\n\n  // Build the 2D points grid using nested Maps to avoid key collisions\n  const cellMap = new Map<string, Map<string, number>>();\n  for (const cell of cells) {\n    let row = cellMap.get(cell.y);\n    if (!row) {\n      row = new Map();\n      cellMap.set(cell.y, row);\n    }\n    row.set(cell.x, cell.value);\n  }\n\n  const points: number[][] = [];\n  for (const yLabel of yLabels) {\n    const row: number[] = [];\n    const rowMap = cellMap.get(yLabel);\n    for (const xLabel of xLabels) {\n      const value = rowMap?.get(xLabel);\n      if (value === undefined) {\n        throw new Error(\n          `Missing heatmap cell for y=\"${yLabel}\", x=\"${xLabel}\". `\n          + `Expected a complete grid of ${yLabels.length} x ${xLabels.length} cells `\n          + `but found ${cells.length} elements.`,\n        );\n      }\n      row.push(value);\n    }\n    points.push(row);\n  }\n\n  const data: HeatmapData = {\n    x: xLabels,\n    y: yLabels,\n    points,\n  };\n\n  const layerId = generateId();\n  const layer: MaidrLayer = {\n    id: layerId,\n    type: TraceType.HEATMAP,\n    title,\n    selectors: scopeSelector(svg, selector),\n    axes: buildAxes(axes, format),\n    data,\n    // D3 heatmaps typically join rects in row-major order (outer loop over\n    // rows, inner over columns), which matches how we build `points` here.\n    // The HeatmapTrace model otherwise defaults to column-major DOM mapping\n    // (matplotlib path-element convention), which would transpose the\n    // highlight grid relative to the data. Emit the hint explicitly.\n    domMapping: { order: 'row' },\n  };\n\n  const maidr: Maidr = {\n    id,\n    title,\n    subtitle,\n    caption,\n    subplots: [[{ layers: [layer] }]],\n  };\n\n  applyMaidrData(svg, maidr, autoApply);\n  return { maidr, layer };\n}\n","/**\n * D3 binder for histograms.\n *\n * Extracts data from D3.js-rendered histogram SVG elements and generates\n * the MAIDR JSON schema for accessible histogram interaction.\n */\n\nimport type { HistogramPoint, Maidr, MaidrLayer } from '../../../type/grammar';\nimport type { D3BinderResult, D3HistogramConfig } from '../types';\nimport { TraceType } from '../../../type/grammar';\nimport { scopeSelector } from '../selectors';\nimport { applyMaidrData, buildAxes, buildNoDatumError, buildNoElementsError, generateId, queryD3Elements, resolveAccessor, resolveAccessorOptional } from '../util';\n\n/**\n * Binds a D3.js histogram to MAIDR, generating the accessible data representation.\n *\n * D3 histograms are typically created with `d3.bin()` (or `d3.histogram()` in v5),\n * which produces arrays with `x0` and `x1` properties for bin boundaries. This\n * binder extracts bin data from D3-bound rect elements.\n *\n * @remarks\n * **Timing — call after D3 has rendered.** This function reads each matched\n * element's D3-bound `__data__`: the bin boundaries (`x0`/`x1`) and count\n * bound to each bar — typically produced by `d3.bin()`. Calling it before\n * `.data().join()` has run (or before the SVG is mounted) throws \"No\n * elements found for selector …\" or \"Property '…' not found on datum\".\n *\n * Typical call sites:\n * - **Vanilla JS:** right after your `selectAll(...).data(...).join(...)` chain.\n * - **React:** inside `useEffect`, never during render. Prefer\n *   {@link MaidrD3} / {@link useD3Adapter} from `maidr/react`, which\n *   handle the post-render timing for you.\n * - **Async data:** inside the `.then(...)` of your fetch, after drawing.\n *\n * @see {@link MaidrD3}\n * @see {@link useD3Adapter}\n *\n * @param svg - The SVG element containing the D3 histogram.\n * @param config - Configuration specifying the selector and data accessors.\n * @returns A {@link D3BinderResult} with the MAIDR data and generated layer.\n *\n * @example\n * ```ts\n * // D3 histogram using d3.bin()\n * const result = bindD3Histogram(svgElement, {\n *   selector: 'rect.bar',\n *   title: 'Age Distribution',\n *   axes: { x: 'Age', y: 'Count' },\n *   x: (d) => `${d.x0}-${d.x1}`,\n *   y: (d) => d.length,\n *   xMin: 'x0',\n *   xMax: 'x1',\n *   yMin: () => 0,\n *   yMax: (d) => d.length,\n * });\n * ```\n */\nexport function bindD3Histogram(svg: Element, config: D3HistogramConfig): D3BinderResult {\n  const {\n    id = generateId(),\n    title,\n    subtitle,\n    caption,\n    axes,\n    format,\n    selector,\n    x: xAccessor = 'x',\n    y: yAccessor = 'y',\n    xMin: xMinAccessor = 'x0',\n    xMax: xMaxAccessor = 'x1',\n    yMin: yMinAccessor = (_d: unknown, _i: number) => 0,\n    yMax: yMaxAccessor,\n    autoApply,\n  } = config;\n\n  const elements = queryD3Elements(svg, selector);\n  if (elements.length === 0) {\n    throw buildNoElementsError(svg, selector, 'histogram bar');\n  }\n\n  // Fallback: when the user did NOT specify xMin/xMax accessors AND the\n  // datum lacks `x0`/`x1` (i.e. the data is not raw d3.bin() output but\n  // pre-aggregated bar-like data), treat the bin as a zero-width point at\n  // `xValue`. This lets the binder work with `[ { x, count } ]`-shaped data.\n  const userSetXMin = (config as unknown as Record<string, unknown>).xMin !== undefined;\n  const userSetXMax = (config as unknown as Record<string, unknown>).xMax !== undefined;\n\n  const data: HistogramPoint[] = elements.map(({ datum, index }) => {\n    if (datum === undefined || datum === null) {\n      throw buildNoDatumError(selector, index);\n    }\n\n    // For D3 bin data, the datum is typically an array with x0/x1 properties.\n    // The \"y\" value is usually the array length (count of items in the bin).\n    const xValue = resolveAccessor<string | number>(datum, xAccessor, index);\n    const yValue = resolveAccessor<number | string>(datum, yAccessor, index);\n\n    const xMin = userSetXMin\n      ? resolveAccessor<number>(datum, xMinAccessor, index)\n      : (resolveAccessorOptional<number>(datum, xMinAccessor, index) ?? Number(xValue));\n    const xMax = userSetXMax\n      ? resolveAccessor<number>(datum, xMaxAccessor, index)\n      : (resolveAccessorOptional<number>(datum, xMaxAccessor, index) ?? Number(xValue));\n\n    const yMin = resolveAccessor<number>(datum, yMinAccessor, index);\n    const yMax = yMaxAccessor\n      ? resolveAccessor<number>(datum, yMaxAccessor, index)\n      : Number(yValue);\n\n    return {\n      x: xValue,\n      y: yValue,\n      xMin,\n      xMax,\n      yMin,\n      yMax,\n    };\n  });\n\n  const layerId = generateId();\n  const layer: MaidrLayer = {\n    id: layerId,\n    type: TraceType.HISTOGRAM,\n    title,\n    selectors: scopeSelector(svg, selector),\n    axes: buildAxes(axes, format),\n    data,\n  };\n\n  const maidr: Maidr = {\n    id,\n    title,\n    subtitle,\n    caption,\n    subplots: [[{ layers: [layer] }]],\n  };\n\n  applyMaidrData(svg, maidr, autoApply);\n  return { maidr, layer };\n}\n","/**\n * D3 binder for line charts.\n *\n * Extracts data from D3.js-rendered line chart SVG elements and generates\n * the MAIDR JSON schema for accessible line chart interaction.\n */\n\nimport type { LinePoint, Maidr, MaidrLayer } from '../../../type/grammar';\nimport type { D3BinderResult, D3LineConfig, DataAccessor } from '../types';\nimport { TraceType } from '../../../type/grammar';\nimport { cssEscape, ensureContainerId, scopeSelector } from '../selectors';\nimport { applyMaidrData, buildAxes, buildNoDatumError, buildNoElementsError, generateId, getD3Datum, inferAccessor, queryD3Elements, resolveAccessor, resolveAccessorOptional } from '../util';\n\n/**\n * Binds a D3.js line chart to MAIDR, generating the accessible data representation.\n *\n * Supports both single-line and multi-line charts. Data can be extracted from:\n * 1. D3-bound data on point elements (circles, etc.) via `pointSelector`.\n *    When using `pointSelector`, each line path and its associated points\n *    must share the same parent `<g>` group element for correct scoping.\n * 2. D3-bound data on the path elements themselves (array of points per path).\n *\n * @remarks\n * **Timing — call after D3 has rendered.** This function reads each matched\n * element's D3-bound `__data__`: an array of points per line path, or\n * individual point data when `pointSelector` is set. Calling it before\n * `.data().join()` has run (or before the SVG is mounted) throws \"No\n * elements found for selector …\" or \"Property '…' not found on datum\".\n *\n * Typical call sites:\n * - **Vanilla JS:** right after your `selectAll(...).data(...).join(...)` chain.\n * - **React:** inside `useEffect`, never during render. Prefer\n *   {@link MaidrD3} / {@link useD3Adapter} from `maidr/react`, which\n *   handle the post-render timing for you.\n * - **Async data:** inside the `.then(...)` of your fetch, after drawing.\n *\n * @see {@link MaidrD3}\n * @see {@link useD3Adapter}\n *\n * @param svg - The SVG element containing the D3 line chart.\n * @param config - Configuration specifying selectors and data accessors.\n * @returns A {@link D3BinderResult} with the MAIDR data and generated layer.\n *\n * @example\n * ```ts\n * // Multi-line chart with paths and point circles\n * const result = bindD3Line(svgElement, {\n *   selector: 'path.line',\n *   pointSelector: 'circle.data-point',\n *   title: 'Temperature Over Time',\n *   axes: { x: 'Month', y: 'Temperature (F)' },\n *   x: 'month',\n *   y: 'temp',\n *   fill: 'city',\n * });\n * ```\n */\nexport function bindD3Line(svg: Element, config: D3LineConfig): D3BinderResult {\n  const {\n    id = generateId(),\n    title,\n    subtitle,\n    caption,\n    axes,\n    format,\n    selector,\n    pointSelector,\n    autoApply,\n  } = config;\n\n  const lineElements = queryD3Elements(svg, selector);\n  if (lineElements.length === 0) {\n    throw buildNoElementsError(svg, selector, 'line path');\n  }\n\n  // Infer accessors from a sample point-level datum when the user was silent.\n  // When pointSelector is set, sample the first matching point; otherwise\n  // the path's datum is typically an array of points — take its first item.\n  let sampleDatum: unknown;\n  if (pointSelector) {\n    const samplePointEl = svg.querySelector(pointSelector);\n    sampleDatum = samplePointEl ? getD3Datum(samplePointEl) : undefined;\n  } else {\n    const pathDatum = lineElements[0].datum;\n    sampleDatum = Array.isArray(pathDatum) ? pathDatum[0] : pathDatum;\n  }\n  const xAccessor = inferAccessor<number | string>(\n    config,\n    'x',\n    'x',\n    ['category', 'label', 'name', 'date', 'time'],\n    sampleDatum,\n  );\n  const yAccessor = inferAccessor<number>(\n    config,\n    'y',\n    'y',\n    ['value', 'count', 'amount', 'total'],\n    sampleDatum,\n  );\n  const fillAccessor = inferAccessor<string>(\n    config,\n    'fill',\n    'fill',\n    ['group', 'series', 'category', 'z', 'color'],\n    sampleDatum,\n  );\n\n  const data: LinePoint[][] = [];\n\n  if (pointSelector) {\n    // Determine whether line paths have distinct parent elements.\n    // Pattern A: Each <path> lives in its own <g> with its <circle> points.\n    // Pattern B: All <path>s and <circle>s share a single parent <g>.\n    const parents = new Set(\n      lineElements.map(({ element }) => element.parentElement ?? svg),\n    );\n\n    if (parents.size >= lineElements.length) {\n      // Pattern A: distinct parents – scope point queries per parent\n      for (const { element } of lineElements) {\n        const parent = element.parentElement ?? svg;\n        const points = queryD3Elements(parent, pointSelector);\n        const lineData = extractPointsFromElements(\n          points,\n          xAccessor,\n          yAccessor,\n          fillAccessor,\n          pointSelector,\n        );\n        if (lineData.length > 0) {\n          data.push(lineData);\n        }\n      }\n    } else {\n      // Pattern B: shared parent – query all points once and group by fill\n      const allPoints = queryD3Elements(svg, pointSelector);\n      if (allPoints.length === 0) {\n        throw new Error(\n          `No point elements found for selector \"${pointSelector}\" within the SVG.`,\n        );\n      }\n\n      const lineMap = new Map<string, LinePoint[]>();\n      const lineOrder: string[] = [];\n\n      for (const { datum, index } of allPoints) {\n        if (datum === undefined || datum === null) {\n          throw buildNoDatumError(pointSelector, index);\n        }\n        const point: LinePoint = {\n          x: resolveAccessor<number | string>(datum, xAccessor, index),\n          y: resolveAccessor<number>(datum, yAccessor, index),\n        };\n        const fill = resolveAccessorOptional<string>(datum, fillAccessor, index);\n        if (fill !== undefined) {\n          point.z = fill;\n        }\n\n        const key = fill ?? '__default__';\n        if (!lineMap.has(key)) {\n          lineOrder.push(key);\n          lineMap.set(key, []);\n        }\n        lineMap.get(key)!.push(point);\n      }\n\n      for (const key of lineOrder) {\n        data.push(lineMap.get(key)!);\n      }\n    }\n  } else {\n    // Extract data from the path element's bound data directly\n    // D3 line charts typically bind an array of points to each path\n    for (const { datum } of lineElements) {\n      if (datum === undefined || datum === null) {\n        throw new Error(\n          `No D3 data bound to line path element. `\n          + `Ensure D3's .data() join has been applied to the \"${selector}\" elements, `\n          + `or provide a pointSelector.`,\n        );\n      }\n\n      const pointArray = Array.isArray(datum) ? datum : [datum];\n      const lineData: LinePoint[] = pointArray.map((d: unknown, index: number) => {\n        const point: LinePoint = {\n          x: resolveAccessor<number | string>(d, xAccessor, index),\n          y: resolveAccessor<number>(d, yAccessor, index),\n        };\n        const fill = resolveAccessorOptional<string>(d, fillAccessor, index);\n        if (fill !== undefined) {\n          point.z = fill;\n        }\n        return point;\n      });\n\n      if (lineData.length > 0) {\n        data.push(lineData);\n      }\n    }\n  }\n\n  // Extract legend labels from fill values (stored as `z` on each LinePoint)\n  const legend: string[] = [];\n  for (const lineData of data) {\n    const fill = lineData[0]?.z;\n    if (fill) {\n      legend.push(fill);\n    }\n  }\n\n  const layerId = generateId();\n\n  // Ensure the SVG has a stable id so we can emit absolutely-scoped selectors\n  // (the model resolves selectors via global `document.querySelector`, so they\n  // MUST be unique page-wide). `ensureContainerId` auto-assigns an id when\n  // the user-supplied SVG lacks one, mirroring `scopeSelector`'s behaviour.\n  const svgId = ensureContainerId(svg);\n\n  // LineTrace's `mapToSvgElements` requires one selector per line (it uses\n  // `Svg.selectElement(selectors[r])` to grab a single <path> per series for\n  // path-parsing, or `selectAllElements(selectors[r])` for per-point markers).\n  // A bare `selector` like `\"path.line\"` matches ALL line paths at once, so\n  // `selectors.length (1) !== lineValues.length (N)` → the model bails out\n  // and no highlight renders.\n  //\n  // Structural selectors (e.g. `:nth-child(N)`) are fragile to DOM reordering\n  // (legend/axis insertions, React re-renders, non-path siblings shifting\n  // nth-child indices). Instead, stamp a MAIDR-owned `data-maidr-line-index`\n  // attribute on each line path at bind time and emit selectors that pin\n  // that attribute, absolutely scoped by the SVG's id. This matches the\n  // Google Charts adapter's `data-maidr-line-series` / `data-maidr-point`\n  // convention and survives any DOM reordering that leaves the path itself\n  // intact.\n  const selectorValue: string | string[] = data.length > 1\n    ? lineElements.map(({ element }, lineIndex) => {\n        // Clear any prior stamp so rebinding after a D3 data update produces\n        // a clean, deterministic state.\n        element.removeAttribute('data-maidr-line-index');\n        element.setAttribute('data-maidr-line-index', String(lineIndex));\n        return `#${cssEscape(svgId)} ${selector}[data-maidr-line-index=\"${lineIndex}\"]`;\n      })\n    : scopeSelector(svg, selector);\n  const layer: MaidrLayer = {\n    id: layerId,\n    type: TraceType.LINE,\n    title,\n    selectors: selectorValue,\n    axes: buildAxes(axes, format),\n    data,\n  };\n\n  const maidr: Maidr = {\n    id,\n    title,\n    subtitle,\n    caption,\n    subplots: [[{\n      ...(legend.length > 0 ? { legend } : {}),\n      layers: [layer],\n    }]],\n  };\n\n  applyMaidrData(svg, maidr, autoApply);\n  return { maidr, layer };\n}\n\n/**\n * Extracts LinePoint data from a set of queried D3 elements.\n */\nfunction extractPointsFromElements(\n  points: { element: Element; datum: unknown; index: number }[],\n  xAccessor: DataAccessor<number | string>,\n  yAccessor: DataAccessor<number>,\n  fillAccessor: DataAccessor<string>,\n  pointSelector: string,\n): LinePoint[] {\n  const lineData: LinePoint[] = [];\n  for (const { datum, index } of points) {\n    if (datum === undefined || datum === null) {\n      throw buildNoDatumError(pointSelector, index);\n    }\n    const point: LinePoint = {\n      x: resolveAccessor<number | string>(datum, xAccessor, index),\n      y: resolveAccessor<number>(datum, yAccessor, index),\n    };\n    const fill = resolveAccessorOptional<string>(datum, fillAccessor, index);\n    if (fill !== undefined) {\n      point.z = fill;\n    }\n    lineData.push(point);\n  }\n  return lineData;\n}\n","/**\n * D3 binder for scatter plots.\n *\n * Extracts data from D3.js-rendered scatter plot SVG elements and generates\n * the MAIDR JSON schema for accessible scatter plot interaction.\n */\n\nimport type { Maidr, MaidrLayer, ScatterPoint } from '../../../type/grammar';\nimport type { D3BinderResult, D3ScatterConfig } from '../types';\nimport { TraceType } from '../../../type/grammar';\nimport { scopeSelector } from '../selectors';\nimport { applyMaidrData, buildAxes, buildNoDatumError, buildNoElementsError, generateId, inferAccessor, queryD3Elements, resolveAccessor } from '../util';\n\n/**\n * Binds a D3.js scatter plot to MAIDR, generating the accessible data representation.\n *\n * Extracts x/y data from D3-bound SVG point elements (`<circle>`, `<use>`, etc.)\n * and produces a complete {@link Maidr} data structure.\n *\n * @remarks\n * **Timing — call after D3 has rendered.** This function reads each matched\n * element's D3-bound `__data__`: the numeric x/y bound to each point element.\n * Calling it before `.data().join()` has run (or before the SVG is mounted)\n * throws \"No elements found for selector …\" or \"Property '…' not found on\n * datum\".\n *\n * Typical call sites:\n * - **Vanilla JS:** right after your `selectAll(...).data(...).join(...)` chain.\n * - **React:** inside `useEffect`, never during render. Prefer\n *   {@link MaidrD3} / {@link useD3Adapter} from `maidr/react`, which\n *   handle the post-render timing for you.\n * - **Async data:** inside the `.then(...)` of your fetch, after drawing.\n *\n * @see {@link MaidrD3}\n * @see {@link useD3Adapter}\n *\n * @param svg - The SVG element containing the D3 scatter plot.\n * @param config - Configuration specifying the selector and data accessors.\n * @returns A {@link D3BinderResult} with the MAIDR data and generated layer.\n *\n * @example\n * ```ts\n * const result = bindD3Scatter(svgElement, {\n *   selector: 'circle.dot',\n *   title: 'Height vs Weight',\n *   axes: { x: 'Height (cm)', y: 'Weight (kg)' },\n *   x: 'height',\n *   y: 'weight',\n * });\n * ```\n */\nexport function bindD3Scatter(svg: Element, config: D3ScatterConfig): D3BinderResult {\n  const {\n    id = generateId(),\n    title,\n    subtitle,\n    caption,\n    axes,\n    format,\n    selector,\n    autoApply,\n  } = config;\n\n  const elements = queryD3Elements(svg, selector);\n  if (elements.length === 0) {\n    throw buildNoElementsError(svg, selector, 'scatter point');\n  }\n\n  // Infer accessors from the first datum's keys when the user did not specify.\n  const firstDatum = elements[0].datum;\n  const xAccessor = inferAccessor<number>(\n    config,\n    'x',\n    'x',\n    ['xVal', 'xValue', 'x_val', 'xCoord'],\n    firstDatum,\n  );\n  const yAccessor = inferAccessor<number>(\n    config,\n    'y',\n    'y',\n    ['yVal', 'yValue', 'y_val', 'yCoord', 'value'],\n    firstDatum,\n  );\n\n  const data: ScatterPoint[] = elements.map(({ datum, index }) => {\n    if (datum === undefined || datum === null) {\n      throw buildNoDatumError(selector, index);\n    }\n    return {\n      x: resolveAccessor<number>(datum, xAccessor, index),\n      y: resolveAccessor<number>(datum, yAccessor, index),\n    };\n  });\n\n  const layerId = generateId();\n  const layer: MaidrLayer = {\n    id: layerId,\n    type: TraceType.SCATTER,\n    title,\n    selectors: scopeSelector(svg, selector),\n    axes: buildAxes(axes, format),\n    data,\n  };\n\n  const maidr: Maidr = {\n    id,\n    title,\n    subtitle,\n    caption,\n    subplots: [[{ layers: [layer] }]],\n  };\n\n  applyMaidrData(svg, maidr, autoApply);\n  return { maidr, layer };\n}\n","/**\n * D3 binder for segmented bar charts (stacked, dodged, and normalized).\n *\n * Extracts data from D3.js-rendered grouped/stacked bar chart SVG elements\n * and generates the MAIDR JSON schema for accessible interaction.\n */\n\nimport type { Maidr, MaidrLayer, SegmentedPoint } from '../../../type/grammar';\nimport type { D3BinderResult, D3SegmentedConfig } from '../types';\nimport { TraceType } from '../../../type/grammar';\nimport { scopeSelector } from '../selectors';\nimport { applyMaidrData, buildAxes, buildNoDatumError, buildNoElementsError, generateId, inferAccessor, queryD3Elements, resolveAccessor } from '../util';\n\n/**\n * Binds a D3.js segmented bar chart (stacked, dodged, or normalized) to MAIDR.\n *\n * Segmented bar charts extend regular bar charts with a `fill` dimension that\n * identifies the segment/group within each bar. The data is organized as a\n * 2D array where each inner array represents a series/group.\n *\n * @remarks\n * **Timing — call after D3 has rendered.** This function reads each matched\n * element's D3-bound `__data__`: the x/y/fill bound to each bar segment —\n * or, with `groupSelector`, the `d3.stack()` tuple plus the parent group's\n * `.key`. Calling it before `.data().join()` has run (or before the SVG is\n * mounted) throws \"No elements found for selector …\" or \"Property '…' not\n * found on datum\".\n *\n * Typical call sites:\n * - **Vanilla JS:** right after your `selectAll(...).data(...).join(...)` chain.\n * - **React:** inside `useEffect`, never during render. Prefer\n *   {@link MaidrD3} / {@link useD3Adapter} from `maidr/react`, which\n *   handle the post-render timing for you.\n * - **Async data:** inside the `.then(...)` of your fetch, after drawing.\n *\n * @see {@link MaidrD3}\n * @see {@link useD3Adapter}\n *\n * @param svg - The SVG element containing the D3 segmented bar chart.\n * @param config - Configuration specifying the selector and data accessors.\n * @returns A {@link D3BinderResult} with the MAIDR data and generated layer.\n *\n * @example\n * ```ts\n * // Flat structure: each rect has { x, y, fill } data\n * const result = bindD3Segmented(svgElement, {\n *   selector: 'rect.bar',\n *   type: 'stacked_bar',\n *   title: 'Revenue by Region and Quarter',\n *   axes: { x: 'Quarter', y: 'Revenue', fill: 'Region' },\n *   x: 'quarter',\n *   y: 'revenue',\n *   fill: 'region',\n * });\n *\n * // d3.stack() structure: groups contain segments\n * const result = bindD3Segmented(svgElement, {\n *   groupSelector: 'g.series',\n *   selector: 'rect',\n *   type: 'stacked_bar',\n *   title: 'Revenue by Region and Quarter',\n *   x: (d) => d.data.category,\n *   y: (d) => d[1] - d[0],\n * });\n * ```\n */\nexport function bindD3Segmented(svg: Element, config: D3SegmentedConfig): D3BinderResult {\n  const {\n    id = generateId(),\n    title,\n    subtitle,\n    caption,\n    axes,\n    format,\n    selector,\n    groupSelector,\n    type = TraceType.STACKED,\n    domOrder: domOrderOverride,\n    autoApply,\n  } = config;\n\n  const groupOrder: string[] = [];\n  const data: SegmentedPoint[][] = [];\n\n  // Track the DOM ordering so we can emit an accurate `domMapping` hint on the\n  // layer below. Without this, the model falls back to column-major +\n  // `groupDirection='reverse'`, which yields wrong highlights for both of the\n  // typical D3 patterns (flat dodged ⇒ subject-major; nested/`d3.stack()` ⇒\n  // series-major).\n  let detectedDomOrder: 'subject-major' | 'series-major' | undefined;\n\n  if (groupSelector) {\n    // d3.stack() pattern: each group <g> contains segment <rect>s.\n    // The group's datum typically has a .key property (d3.stack output).\n    // Rects are rendered one full series at a time (all categories of group 0,\n    // then all of group 1, …) ⇒ series-major DOM order.\n    detectedDomOrder = 'series-major';\n\n    const groupElements = queryD3Elements(svg, groupSelector);\n    if (groupElements.length === 0) {\n      throw buildNoElementsError(svg, groupSelector, 'segmented-bar group');\n    }\n\n    // Sample the first group's first segment for accessor inference.\n    const firstGroupSegments = queryD3Elements(groupElements[0].element, selector);\n    const sampleDatum = firstGroupSegments[0]?.datum;\n    const xAccessor = inferAccessor<string | number>(\n      config,\n      'x',\n      'x',\n      ['category', 'label', 'name', 'key', 'date'],\n      sampleDatum,\n    );\n    const yAccessor = inferAccessor<number | string>(\n      config,\n      'y',\n      'y',\n      ['value', 'count', 'amount', 'total'],\n      sampleDatum,\n    );\n    const fillAccessor = inferAccessor<string>(\n      config,\n      'fill',\n      'fill',\n      ['group', 'series', 'category', 'z', 'color'],\n      sampleDatum,\n    );\n\n    for (const { element: groupEl, datum: groupDatum } of groupElements) {\n      const segments = queryD3Elements(groupEl, selector);\n      if (segments.length === 0)\n        continue;\n\n      // Derive fill from group datum's .key (d3.stack) or first segment\n      const groupKey = (groupDatum as Record<string, unknown> | null)?.key as string | undefined;\n\n      const groupPoints: SegmentedPoint[] = segments.map(({ datum, index }) => {\n        if (datum === undefined || datum === null) {\n          throw buildNoDatumError(selector, index);\n        }\n        const fillValue = groupKey ?? resolveAccessor<string>(datum, fillAccessor, index);\n        return {\n          x: resolveAccessor<string | number>(datum, xAccessor, index),\n          y: resolveAccessor<number | string>(datum, yAccessor, index),\n          z: fillValue,\n        };\n      });\n\n      if (groupPoints.length > 0) {\n        groupOrder.push(groupPoints[0].z);\n        data.push(groupPoints);\n      }\n    }\n  } else {\n    // Flat structure: all segments in one container, grouped by fill value\n    const elements = queryD3Elements(svg, selector);\n    if (elements.length === 0) {\n      throw buildNoElementsError(svg, selector, 'segmented bar');\n    }\n\n    // Pattern detection: if the datum looks like a d3.stack() tuple\n    // ([y0, y1] array with a back-reference to the row via `.data`), the\n    // user almost certainly wanted the grouped path. Tell them so before\n    // `resolveAccessor` throws a cryptic \"Property 'x' not found\" error.\n    const firstDatum = elements[0].datum;\n    if (\n      Array.isArray(firstDatum)\n      && firstDatum.length === 2\n      && typeof firstDatum[0] === 'number'\n      && typeof firstDatum[1] === 'number'\n      && 'data' in (firstDatum as unknown as Record<string, unknown>)\n    ) {\n      throw new Error(\n        `The datum bound to \"${selector}\" looks like d3.stack() output `\n        + `(a [y0, y1] tuple with a .data back-reference), but no `\n        + `\\`groupSelector\\` was provided. Pass \\`groupSelector\\` (typically `\n        + `the series container, e.g. \"g.series\") so the binder can walk `\n        + `each group and read the series key from its datum. Alternatively, `\n        + `pre-flatten your data to \\`{ x, y, fill }\\` before joining.`,\n      );\n    }\n\n    // Pattern detection: if elements share a single parent whose datum\n    // has a `.key` string, that parent is the d3.stack series group.\n    // Suggest lifting it to `groupSelector`.\n    const parents = new Set(elements.map(({ element }) => element.parentElement));\n    if (parents.size === 1) {\n      const parent = elements[0].element.parentElement;\n      const parentDatum = parent ? (parent as { __data__?: unknown }).__data__ : undefined;\n      if (\n        parentDatum\n        && typeof parentDatum === 'object'\n        && 'key' in (parentDatum as Record<string, unknown>)\n      ) {\n        throw new Error(\n          `All \"${selector}\" elements share a parent whose D3 datum has a `\n          + `\\`.key\\` property — this is the d3.stack() shape. Pass a `\n          + `\\`groupSelector\\` that matches the parent (e.g. \"g.series\") so `\n          + `the binder can read each series key from the parent's datum.`,\n        );\n      }\n    }\n\n    // Infer accessors from the first segment's datum.\n    const sampleDatum = elements[0].datum;\n    const xAccessor = inferAccessor<string | number>(\n      config,\n      'x',\n      'x',\n      ['category', 'label', 'name', 'key', 'date'],\n      sampleDatum,\n    );\n    const yAccessor = inferAccessor<number | string>(\n      config,\n      'y',\n      'y',\n      ['value', 'count', 'amount', 'total'],\n      sampleDatum,\n    );\n    const fillAccessor = inferAccessor<string>(\n      config,\n      'fill',\n      'fill',\n      ['group', 'series', 'category', 'z', 'color'],\n      sampleDatum,\n    );\n\n    const groups = new Map<string, SegmentedPoint[]>();\n    for (const { datum, index } of elements) {\n      if (datum === undefined || datum === null) {\n        throw buildNoDatumError(selector, index);\n      }\n      const point: SegmentedPoint = {\n        x: resolveAccessor<string | number>(datum, xAccessor, index),\n        y: resolveAccessor<number | string>(datum, yAccessor, index),\n        z: resolveAccessor<string>(datum, fillAccessor, index),\n      };\n      if (!groups.has(point.z)) {\n        groupOrder.push(point.z);\n        groups.set(point.z, []);\n      }\n      groups.get(point.z)!.push(point);\n    }\n    for (const fill of groupOrder) {\n      data.push(groups.get(fill)!);\n    }\n\n    // Detect DOM order from the first two rendered rects' fill values.\n    // - Flat dodged join (`selectAll('rect.bar').data(flatArr)`): fills\n    //   alternate by series each row ⇒ `[A, B, C, A, B, C, …]` (subject-major).\n    // - Flat stacked-by-series join (`for (s of series) selectAll(`rect.${s.key}`)…`):\n    //   all of series 0 first ⇒ `[E, E, …, W, W, …]` (series-major).\n    // This catches both common patterns without requiring user config.\n    if (elements.length >= 2) {\n      const fill0 = String(resolveAccessor<string>(elements[0].datum, fillAccessor, 0));\n      const fill1 = String(resolveAccessor<string>(elements[1].datum, fillAccessor, 1));\n      detectedDomOrder = fill0 === fill1 ? 'series-major' : 'subject-major';\n    }\n  }\n\n  const layerId = generateId();\n  const selectorValue = groupSelector\n    ? scopeSelector(svg, `${groupSelector} ${selector}`)\n    : scopeSelector(svg, selector);\n\n  // Resolve final DOM order: explicit user override wins; else detected value;\n  // else fall back to the chart type (stacked/normalized render series-major,\n  // dodged renders subject-major in the typical D3 patterns).\n  const finalDomOrder: 'subject-major' | 'series-major' = domOrderOverride\n    ?? detectedDomOrder\n    ?? (type === TraceType.DODGED ? 'subject-major' : 'series-major');\n\n  // Translate the semantic DOM order into the `domMapping` shape the model\n  // consumes:\n  // - series-major DOM ⇒ row-major iteration over `barValues` matches the DOM.\n  // - subject-major DOM ⇒ column-major iteration, walking series top-to-bottom\n  //   (`groupDirection: 'forward'`) matches the DOM.\n  const domMapping = finalDomOrder === 'series-major'\n    ? { order: 'row' as const }\n    : { order: 'column' as const, groupDirection: 'forward' as const };\n\n  const layer: MaidrLayer = {\n    id: layerId,\n    type,\n    title,\n    selectors: selectorValue,\n    axes: buildAxes(axes, format),\n    data,\n    domMapping,\n  };\n\n  const maidr: Maidr = {\n    id,\n    title,\n    subtitle,\n    caption,\n    subplots: [[{\n      legend: groupOrder,\n      layers: [layer],\n    }]],\n  };\n\n  applyMaidrData(svg, maidr, autoApply);\n  return { maidr, layer };\n}\n","/**\n * D3 binder for smooth/regression curves.\n *\n * Extracts data from D3.js-rendered smooth curve SVG elements and generates\n * the MAIDR JSON schema for accessible smooth plot interaction.\n */\n\nimport type { Maidr, MaidrLayer, SmoothPoint } from '../../../type/grammar';\nimport type { D3BinderResult, D3SmoothConfig } from '../types';\nimport { TraceType } from '../../../type/grammar';\nimport { scopeSelector } from '../selectors';\nimport { applyMaidrData, buildAxes, buildNoDatumError, buildNoElementsError, generateId, queryD3Elements, resolveAccessor } from '../util';\n\n/**\n * Binds a D3.js smooth/regression curve to MAIDR.\n *\n * Smooth plots represent fitted curves (e.g., LOESS, regression lines).\n * The data includes both the data-space coordinates (x, y) and SVG-space\n * coordinates (svg_x, svg_y) for each point along the curve.\n *\n * @remarks\n * **Timing — call after D3 has rendered.** This function reads each matched\n * element's D3-bound `__data__`: both the data-space (`x`/`y`) and SVG-space\n * (`svg_x`/`svg_y`) coords bound to each curve point. Calling it before\n * `.data().join()` has run (or before the SVG is mounted) throws \"No\n * elements found for selector …\" or \"Property '…' not found on datum\".\n *\n * Typical call sites:\n * - **Vanilla JS:** right after your `selectAll(...).data(...).join(...)` chain.\n * - **React:** inside `useEffect`, never during render. Prefer\n *   {@link MaidrD3} / {@link useD3Adapter} from `maidr/react`, which\n *   handle the post-render timing for you.\n * - **Async data:** inside the `.then(...)` of your fetch, after drawing.\n *\n * @see {@link MaidrD3}\n * @see {@link useD3Adapter}\n *\n * @param svg - The SVG element containing the D3 smooth curve.\n * @param config - Configuration specifying the selector and data accessors.\n * @returns A {@link D3BinderResult} with the MAIDR data and generated layer.\n *\n * @example\n * ```ts\n * const result = bindD3Smooth(svgElement, {\n *   selector: 'circle.smooth-point',\n *   title: 'LOESS Regression',\n *   axes: { x: 'X', y: 'Y (predicted)' },\n *   x: 'x',\n *   y: 'yPredicted',\n *   svgX: 'screenX',\n *   svgY: 'screenY',\n * });\n * ```\n */\nexport function bindD3Smooth(svg: Element, config: D3SmoothConfig): D3BinderResult {\n  const {\n    id = generateId(),\n    title,\n    subtitle,\n    caption,\n    axes,\n    format,\n    selector,\n    x: xAccessor = 'x',\n    y: yAccessor = 'y',\n    svgX: svgXAccessor = 'svg_x',\n    svgY: svgYAccessor = 'svg_y',\n    autoApply,\n  } = config;\n\n  const elements = queryD3Elements(svg, selector);\n  if (elements.length === 0) {\n    throw buildNoElementsError(svg, selector, 'smooth curve point');\n  }\n\n  // Guard: smooth curves need SVG-space coords so MAIDR can highlight points\n  // on-screen. If neither the user nor the datum provides them, throw an\n  // actionable error instead of the generic \"Property 'svg_x' not found\".\n  const firstDatum = elements[0].datum;\n  const configRecord = config as unknown as Record<string, unknown>;\n  const userSetSvgX = configRecord.svgX !== undefined;\n  const userSetSvgY = configRecord.svgY !== undefined;\n  if (\n    firstDatum\n    && typeof firstDatum === 'object'\n    && !userSetSvgX\n    && !userSetSvgY\n  ) {\n    const record = firstDatum as Record<string, unknown>;\n    if (!('svg_x' in record) || !('svg_y' in record)) {\n      throw new Error(\n        `Smooth curve datum at \"${selector}\" lacks \\`svg_x\\` / \\`svg_y\\` `\n        + `SVG-space coordinates, which MAIDR uses to position highlights `\n        + `on the curve. Either bind data with \\`svg_x\\` / \\`svg_y\\` keys, `\n        + `or pass \\`svgX\\` / \\`svgY\\` accessor functions that compute the `\n        + `SVG-space coords from your D3 scales, e.g. `\n        + `\\`svgX: d => xScale(d.x), svgY: d => yScale(d.yHat)\\`. `\n        + `Available keys on the datum: ${Object.keys(record).join(', ') || '(none)'}.`,\n      );\n    }\n  }\n\n  // Extract points - group into a single series (2D array with one row)\n  const points: SmoothPoint[] = elements.map(({ datum, index }) => {\n    if (datum === undefined || datum === null) {\n      throw buildNoDatumError(selector, index);\n    }\n    return {\n      x: resolveAccessor<number>(datum, xAccessor, index),\n      y: resolveAccessor<number>(datum, yAccessor, index),\n      svg_x: resolveAccessor<number>(datum, svgXAccessor, index),\n      svg_y: resolveAccessor<number>(datum, svgYAccessor, index),\n    };\n  });\n\n  const data: SmoothPoint[][] = [points];\n\n  const layerId = generateId();\n  const layer: MaidrLayer = {\n    id: layerId,\n    type: TraceType.SMOOTH,\n    title,\n    // Wrap in an array so the per-line length check inside\n    // `mapToSvgElements` compares array length to line count (1). A bare\n    // string would compare character count to 1 and always fail.\n    selectors: [scopeSelector(svg, selector)],\n    axes: buildAxes(axes, format),\n    data,\n  };\n\n  const maidr: Maidr = {\n    id,\n    title,\n    subtitle,\n    caption,\n    subplots: [[{ layers: [layer] }]],\n  };\n\n  applyMaidrData(svg, maidr, autoApply);\n  return { maidr, layer };\n}\n"],"names":["Orientation","TraceType","getD3Datum","element","resolveAccessor","datum","accessor","index","record","inferAccessor","config","configKey","defaultKey","alternatives","firstDatum","userProvided","alt","resolveAccessorOptional","queryD3Elements","container","selector","buildNoElementsError","elementKind","sampleTagNames","i","hint","buildNoDatumError","generateId","timestamp","a","b","normalizeAxis","input","sharedFormat","base","buildAxes","axes","format","result","x","z","applyMaidrData","svg","maidr","autoApply","cssEscape","value","ensureContainerId","scopeSelector","id","bindD3Bar","title","subtitle","caption","orientation","elements","xAccessor","yAccessor","data","layer","bindD3Box","fillAccessor","minAccessor","q1Accessor","q2Accessor","q3Accessor","maxAccessor","lowerOutliersAccessor","upperOutliersAccessor","boxGroups","effectiveDatum","firstChild","lowerOutliers","upperOutliers","layerId","svgId","isHorizontal","boxSelectors","boxIndex","children","rect","c","rectX","rectY","rectW","rectH","rectCx","rectCy","lines","line","x1","y1","x2","y2","dx","dy","midX","midY","part","outlierEls","lowerOutlierIndices","upperOutlierIndices","outlier","outlierIndex","cx","cy","isLower","bindD3Candlestick","valueAccessor","openAccessor","highAccessor","lowAccessor","closeAccessor","volumeAccessor","trendAccessor","openVal","closeVal","highVal","lowVal","trend","volumeVal","bindD3Heatmap","cells","xLabels","yLabels","seenX","seenY","cell","cellMap","row","points","yLabel","rowMap","xLabel","bindD3Histogram","xMinAccessor","xMaxAccessor","yMinAccessor","_d","_i","yMaxAccessor","userSetXMin","userSetXMax","xValue","yValue","xMin","xMax","yMin","yMax","bindD3Line","_a","pointSelector","lineElements","sampleDatum","samplePointEl","pathDatum","parent","lineData","extractPointsFromElements","allPoints","lineMap","lineOrder","point","fill","key","legend","selectorValue","lineIndex","bindD3Scatter","bindD3Segmented","groupSelector","type","domOrderOverride","groupOrder","detectedDomOrder","groupElements","groupEl","groupDatum","segments","groupKey","groupPoints","fillValue","parentDatum","groups","fill0","fill1","domMapping","bindD3Smooth","svgXAccessor","svgYAccessor","configRecord","userSetSvgX","userSetSvgY"],"mappings":"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"}