import { a as MarkMeta } from './interaction-C9KDmZ7k.js';
export { M as MarkKind } from './interaction-C9KDmZ7k.js';
import * as react_jsx_runtime from 'react/jsx-runtime';
import * as react from 'react';
import { ReactNode, ReactElement } from 'react';
import { a as VibeConfig } from './vibe-lqnEjG15.js';

/**
 * Parse the nearest `data-gc-*` tagged ancestor (or self) into MarkMeta.
 * Client-only: call it on a pointer/focus event target. Returns null when the
 * element is not part of a tagged mark.
 */
declare function readMark(el: Element): MarkMeta | null;

interface TooltipContent {
    title?: string;
    rows: [string, string][];
}
/** Default MarkMeta -> tooltip content: label as the title, value(s) as rows. */
declare function defaultTooltipFormat(mark: MarkMeta): TooltipContent;
/** A flat accessible label for a mark, e.g. "Q1, value 12" or "s1, x 1, y 3". */
declare function markAriaLabel(mark: MarkMeta): string;

type TooltipRenderer = (mark: MarkMeta) => ReactNode;
interface TooltipProps {
    mark: MarkMeta;
    /** Mark anchor in svg/viewBox coordinates. */
    anchor: {
        x: number;
        y: number;
    };
    /** Plot bounds (viewBox width/height) for edge-flipping + clamping. */
    bounds: {
        width: number;
        height: number;
    };
    format?: (mark: MarkMeta) => TooltipContent;
}
/**
 * A sketched, vibe-aware tooltip: a solid page-coloured backing (for legibility
 * over the chart) under a sketched frame, placed beside the mark via
 * `placeTooltip` so it never sits on the mark or runs off the canvas.
 */
declare function Tooltip({ mark, anchor, bounds, format }: TooltipProps): react_jsx_runtime.JSX.Element;

interface InteractiveChartProps {
    children: ReactElement;
    /** `true` (default) draws the built-in sketched tooltip; a function renders a custom one. */
    tooltip?: boolean | TooltipRenderer;
    /** Dim non-hovered marks while hovering (render-free). Default `true`. */
    highlight?: boolean;
    onHover?: (mark: MarkMeta | null) => void;
    /** Enable click/keyboard selection of marks. Default `false`. */
    selectable?: boolean;
    /** Controlled selection (mark keys). When set, internal state is ignored. */
    selected?: string | string[] | null;
    defaultSelected?: string | string[] | null;
    multiSelect?: boolean;
    onSelect?: (mark: MarkMeta, selectedKeys: string[]) => void;
    /** Make the chart's legend toggle series visibility. Default `true`. */
    legendToggle?: boolean;
    /** Draw a sketched vertical focus line snapped to the hovered mark. Default `false`. */
    crosshair?: boolean;
    /** Wheel-zoom the continuous x-axis (line/area/scatter), re-sketching at the new domain. */
    zoom?: boolean;
    /** Drag to pan the zoomed x-axis. Implies a zoomable chart. Default `false`. */
    pan?: boolean;
    /** Drag a sketched x-range selection; emits the brushed marks. Takes precedence over pan. */
    brush?: boolean;
    onBrush?: (marks: MarkMeta[]) => void;
    /** Animate the chart's data prop when it changes (snaps under reduced-motion). */
    transition?: boolean | {
        durationMs?: number;
    };
    /** This chart's source id within a surrounding `<LinkedCharts>` group (crossfilter). */
    linkGroup?: string;
    /** Mirrors the wrapped chart's vibe so the tooltip is sketched to match. */
    vibe?: VibeConfig;
}
interface HoverState {
    mark: MarkMeta;
    x: number;
    y: number;
}
/** Resolve a pointer/focus target into the hovered mark + its anchor in svg
 *  coordinates. Anchors at the mark's own cx/cy so it is stable regardless of
 *  cursor jitter (and testable without layout). */
declare function markFromEvent(_svg: SVGSVGElement, target: Element, _clientX: number, _clientY: number): HoverState | null;
/** Make every tagged mark keyboard-focusable with an accessible label, so the
 *  hover/selection path is reachable without a pointer. Idempotent. */
declare function enhanceMarks(svg: SVGSVGElement): void;
/**
 * Client-only boundary that makes a wrapped GoldenChart interactive via event
 * delegation on its `<svg>`: hover tooltips + emphasis (Phase 1), click/keyboard
 * selection, and a legend that toggles series visibility (Phase 2). Hover and
 * selection are render-free (imperative attributes); legend toggles re-render the
 * wrapped chart through the SeriesVisibility context.
 */
declare function InteractiveChart({ children, tooltip, highlight, onHover, selectable, selected, defaultSelected, multiSelect, onSelect, legendToggle, crosshair, zoom, pan, brush, onBrush, transition, linkGroup, vibe, }: InteractiveChartProps): react_jsx_runtime.JSX.Element;

interface Point {
    x: number;
    y: number;
}
interface Size {
    width: number;
    height: number;
}
/** Position a tooltip box near `anchor`, offset by `gap`, flipping at the right/
 *  bottom edges of `bounds` and clamping so it never leaves the near edges. */
declare function placeTooltip(anchor: Point, size: Size, bounds: Size, gap?: number): Point;

/** Root attribute present only while something is hovered. */
declare const HOVER_ATTR = "data-gc-hover";
/** Marks the currently-hovered mark group so the dim rule can exclude it. */
declare const CURRENT_ATTR = "data-gc-current";
/** Render-free hover emphasis: dim every mark except the current one, but only
 *  while a hover is active. The opacity transition is gated behind reduced-motion
 *  so it stays instant for users who prefer that. */
declare function hoverCss(dimOpacity?: number): string;

/** Stable per-mark key: `${series ?? ''}:${index}` (series disambiguates multi-series). */
declare function markKey(mark: Pick<MarkMeta, 'series' | 'index'>): string;
/** Pure selection toggle. Single-select replaces (or clears on re-click of the
 *  sole selection); multi-select toggles membership. */
declare function toggleSelection(current: ReadonlySet<string>, key: string, multi: boolean): Set<string>;

/** Root attribute present while a selection exists. */
declare const SELECTED_ATTR = "data-gc-selected";
/** Marks a chosen mark group. */
declare const CHOSEN_ATTR = "data-gc-chosen";
/** Persistent selection emphasis: chosen marks stay full-opacity; once any mark
 *  is chosen, the rest recede so the selection reads clearly. */
declare function selectCss(dimOpacity?: number): string;

interface PixelMark$1 {
    cx: number;
    cy: number;
}
/** Nearest mark to (x, y) by pixel distance — used to snap a crosshair/selection
 *  to the closest datum without needing the chart's scales. Returns null when
 *  there are no marks. */
declare function nearestMark<T extends PixelMark$1>(marks: readonly T[], x: number, y: number): T | null;
interface CrosshairProps {
    /** Snapped x position (svg space). */
    x: number;
    /** Plot height to span. */
    height: number;
}
/** A sketched vertical focus line at the snapped x. */
declare function Crosshair({ x, height }: CrosshairProps): react_jsx_runtime.JSX.Element;

interface SeriesVisibility {
    hidden: ReadonlySet<string>;
    toggle: (series: string) => void;
    /** When true, the Legend renders focusable toggle controls. Off by default so
     *  the static/SSR/MCP render emits no extra interactive attributes. */
    interactive: boolean;
}
/** No-op default: hides nothing, toggles nothing, not interactive. Keeps the
 *  static/SSR/MCP render byte-identical until an interactive provider mounts. */
declare const defaultSeriesVisibility: SeriesVisibility;
declare const SeriesVisibilityProvider: react.Provider<SeriesVisibility>;
/** Read by charts and `Legend` in their own body (descendants of the provider
 *  that `InteractiveChart` mounts around the chart). */
declare function useSeriesVisibility(): SeriesVisibility;

/** Domain math for semantic zoom/pan. Pure: no DOM, no scales. */
type Domain = [number, number];
/**
 * Zoom around `focus`, a 0..1 fraction of the current domain (0 = low edge,
 * 1 = high edge). `factor < 1` zooms in, `factor > 1` zooms out. The focus point
 * stays stationary in data space.
 */
declare function zoomDomain([lo, hi]: Domain, focus: number, factor: number): Domain;
/** Shift the whole domain by a data-space delta. */
declare function panDomain([lo, hi]: Domain, deltaData: number): Domain;
/**
 * Clamp a domain inside `bounds`, capping the span to the bounds' span and
 * enforcing `minSpan`, then sliding it back inside if it ran past an edge.
 */
declare function clampDomain([lo, hi]: Domain, [bLo, bHi]: Domain, minSpan: number): Domain;
/** One wheel notch -> zoom factor. Scroll up (deltaY < 0) zooms in; reciprocals
 *  so a zoom-in then zoom-out returns to the original domain. */
declare function wheelFactor(deltaY: number): number;
/** Apply a wheel event to a domain: zoom around `focus` (0..1) then clamp. */
declare function wheelZoom(domain: Domain, focus: number, deltaY: number, bounds: Domain, minSpan: number): Domain;
/** Pointer position -> 0..1 fraction across an element, clamped to the edges. */
declare function focusFraction(clientPos: number, edgeStart: number, length: number): number;

/** Brush range math. Pure: no DOM, no scales. */
/** Linearly invert a pixel position to a domain value (range edges may be reversed). */
declare function pixelToValue(px: number, [p0, p1]: [number, number], [v0, v1]: [number, number]): number;
/** Map a client (screen) coordinate into the chart's viewBox coordinate space. */
declare function clientToViewBox(client: number, rectStart: number, rectLength: number, vbStart: number, vbLength: number): number;
/** Normalize two endpoints into a rect origin + length (handles backwards drag). */
declare function brushRect(a: number, b: number): {
    start: number;
    length: number;
};
interface PixelMark {
    key: string;
    cx: number;
    cy: number;
}
/**
 * Filter marks whose pixel anchor falls within a brushed range on the given axis.
 * The range is normalized, so a backwards drag still selects correctly.
 */
declare function marksInPixelRange<M extends PixelMark>(marks: M[], range: [number, number], axis: 'x' | 'y'): M[];

/** Interpolation helpers for animated data transitions. Pure: no DOM, no rAF. */
/** Linear blend between `a` and `b` at fraction `t` (0..1). */
declare function lerp(a: number, b: number, t: number): number;
/**
 * Blend two numeric maps key-by-key. Keys missing from `from` snap to the `to`
 * value (an entering mark has no prior position to ease from).
 */
declare function interpolateNumberMap(from: Record<string, number>, to: Record<string, number>, t: number): Record<string, number>;
/** Standard ease-in-out cubic; pins 0->0 and 1->1. */
declare function easeInOutCubic(t: number): number;
/**
 * Interpolate a chart's data prop between two snapshots at fraction `t`.
 * Handles `{label,value}[]` (bar/pie, matched by label) and `{id,points}[]`
 * (line/area, matched by id then point index). Other shapes pass through as
 * `to`. Entering items (absent in `from`) snap to their target.
 */
declare function interpolateChartData(from: unknown, to: unknown, t: number): unknown;

/**
 * Pure reducer for cross-chart linked selection. Each source chart contributes a
 * set of selected mark keys; the active filter is their union. No DOM, no React.
 */
interface LinkState {
    /** Selected keys keyed by source chart id. */
    bySource: Record<string, string[]>;
}
declare function emptyLink(): LinkState;
/** Record (or, with an empty list, clear) a source chart's selected keys. */
declare function setFilter(state: LinkState, source: string, keys: string[]): LinkState;
/** Drop a source chart's contribution. */
declare function clearFilter(state: LinkState, source: string): LinkState;
/** The merged active filter: union of every source's keys, deduped and sorted. */
declare function activeFilter(state: LinkState): string[];

/**
 * Pure: derive the continuous x data-extent from a wrapped chart's props.
 * Handles point series (`series[].points[].x`) and `{ x }` datum arrays
 * (scatter). Returns null for charts without a continuous x (e.g. categorical
 * bars), which disables zoom for them.
 */
declare function chartXExtent(props: Record<string, unknown>): Domain | null;
interface UseZoomPan {
    /** Current view domain, or null when not zoomed (chart uses its default extent). */
    domain: Domain | null;
    onWheel: (e: WheelEvent) => void;
    onPointerDown: (e: PointerEvent) => void;
    onPointerMove: (e: PointerEvent) => void;
    onPointerUp: () => void;
    reset: () => void;
}
/**
 * Track a view domain driven by wheel-zoom and (optionally) drag-pan, both
 * clamped to `bounds`. All domain math is delegated to the pure `core/zoom`
 * helpers; this hook only wires pointer state. No-op when `bounds` is null.
 */
declare function useZoomPan(bounds: Domain | null, opts?: {
    pan?: boolean;
    minSpan?: number;
}): UseZoomPan;

interface BrushOverlayProps {
    /** Rect origin in viewBox x. */
    start: number;
    /** Rect width in viewBox units. */
    length: number;
    /** Plot height to span. */
    height: number;
}
/** A sketched translucent selection rectangle for an x-axis brush. */
declare function Brush({ start, length, height }: BrushOverlayProps): react_jsx_runtime.JSX.Element | null;

/** True when the user has requested reduced motion (SSR-safe). */
declare function prefersReducedMotion(): boolean;
/**
 * Tween a chart's data prop whenever its identity changes, over `durationMs`,
 * easing the interpolation (via the pure `interpolateChartData`). Snaps
 * instantly when disabled or under `prefers-reduced-motion`. Returns the data to
 * feed the chart this frame.
 */
declare function useDataTransition<T>(data: T, durationMs?: number, enabled?: boolean): T;

interface LinkGroupValue {
    /** Merged active filter (union of every member chart's published keys). */
    filter: string[];
    /** Publish this chart's selected/brushed keys under its source id. */
    publish: (source: string, keys: string[]) => void;
}
/**
 * Wrap a set of `<InteractiveChart linkGroup="...">`s so a brush/selection in one
 * filters the others. Holds the shared selection state via the pure
 * `core/linkSelection` reducer; the active filter is the union across members.
 */
declare function LinkedCharts({ children }: {
    children: ReactNode;
}): react_jsx_runtime.JSX.Element;
/** Read the surrounding link group, or null when not inside `<LinkedCharts>`. */
declare function useLinkGroup(): LinkGroupValue | null;

interface InteractiveEmbedOptions {
    /** Include the hover-tooltip hydrator. Default `true`. */
    tooltip?: boolean;
    /** Document `<title>`. Default `'GoldenChart'`. */
    title?: string;
}
/**
 * Wrap a static (already `data-gc-*` tagged) GoldenChart SVG into a
 * self-contained HTML document with a tiny vanilla hover-tooltip hydrator — no
 * React or runtime bundling. Renders identically offline (the SVG carries its
 * own embedded fonts when produced by the headless/server renderer).
 */
declare function interactiveEmbed(svg: string, opts?: InteractiveEmbedOptions): string;

export { Brush, type BrushOverlayProps, CHOSEN_ATTR, CURRENT_ATTR, Crosshair, type CrosshairProps, type Domain, HOVER_ATTR, type HoverState, InteractiveChart, type InteractiveChartProps, type InteractiveEmbedOptions, type LinkGroupValue, type LinkState, LinkedCharts, MarkMeta, type PixelMark$1 as PixelMark, SELECTED_ATTR, type SeriesVisibility, SeriesVisibilityProvider, Tooltip, type TooltipContent, type TooltipProps, type TooltipRenderer, activeFilter, brushRect, chartXExtent, clampDomain, clearFilter, clientToViewBox, defaultSeriesVisibility, defaultTooltipFormat, easeInOutCubic, emptyLink, enhanceMarks, focusFraction, hoverCss, interactiveEmbed, interpolateChartData, interpolateNumberMap, lerp, markAriaLabel, markFromEvent, markKey, marksInPixelRange, nearestMark, panDomain, pixelToValue, placeTooltip, prefersReducedMotion, readMark, selectCss, setFilter, toggleSelection, useDataTransition, useLinkGroup, useSeriesVisibility, useZoomPan, wheelFactor, wheelZoom, zoomDomain };
