@devalok/shilp-sutra 0.36.0 → 0.36.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","names":[],"sources":["../../../src/ui/charts/_internal/types.ts","../../../src/ui/charts/chart-container.tsx","../../../src/ui/charts/_internal/axes.tsx","../../../src/ui/charts/_internal/grid-lines.tsx","../../../src/ui/charts/_internal/legend.tsx","../../../src/ui/charts/_internal/tooltip.tsx","../../../src/ui/charts/_internal/colors.ts","../../../src/ui/charts/_internal/animation.ts","../../../src/ui/charts/bar-chart.tsx","../../../src/ui/charts/line-chart.tsx","../../../src/ui/charts/area-chart.tsx","../../../src/ui/charts/pie-chart.tsx","../../../src/ui/charts/sparkline.tsx","../../../src/ui/charts/gauge-chart.tsx","../../../src/ui/charts/radar-chart.tsx"],"sourcesContent":["export interface ChartMargin {\n top: number\n right: number\n bottom: number\n left: number\n}\n\nexport const DEFAULT_MARGIN: ChartMargin = {\n top: 20,\n right: 20,\n bottom: 40,\n left: 50,\n}\n\nexport interface DataPoint {\n [key: string]: string | number | Date\n}\n\nexport interface Series {\n key: string\n label: string\n color?: string\n}\n\nexport type ChartColor =\n | 'chart-1'\n | 'chart-2'\n | 'chart-3'\n | 'chart-4'\n | 'chart-5'\n | 'chart-6'\n | 'chart-7'\n | 'chart-8'\n","'use client'\n\nimport * as React from 'react'\nimport { useState, useRef, useEffect } from 'react'\nimport { cn } from '../lib/utils'\nimport type { ChartMargin } from './_internal/types'\nimport { DEFAULT_MARGIN } from './_internal/types'\n\nexport interface ChartContainerProps extends Omit<React.HTMLAttributes<HTMLDivElement>, 'children'> {\n /** Fixed height in pixels */\n height?: number\n /** Chart margins */\n margin?: Partial<ChartMargin>\n className?: string\n /** Accessible label for the chart SVG */\n ariaLabel?: string\n /** Accessible description for screen readers — summarize key data points */\n ariaDescription?: string\n /** Render function receiving inner dimensions (width/height minus margins) */\n children: (dimensions: {\n width: number\n height: number\n margin: ChartMargin\n }) => React.ReactNode\n}\n\nexport const ChartContainer = React.forwardRef<HTMLDivElement, ChartContainerProps>(\n (\n {\n height = 300,\n margin: marginOverride,\n className,\n ariaLabel = 'Chart',\n ariaDescription,\n children,\n ...props\n },\n ref,\n ) => {\n const containerRef = useRef<HTMLDivElement>(null)\n const [width, setWidth] = useState(0)\n\n const margin = { ...DEFAULT_MARGIN, ...marginOverride }\n\n useEffect(() => {\n if (!containerRef.current) return\n const observer = new ResizeObserver((entries) => {\n const entry = entries[0]\n if (entry) setWidth(entry.contentRect.width)\n })\n observer.observe(containerRef.current)\n return () => observer.disconnect()\n }, [])\n\n const innerWidth = Math.max(0, width - margin.left - margin.right)\n const innerHeight = Math.max(0, height - margin.top - margin.bottom)\n\n return (\n <div\n ref={(node) => {\n (containerRef as React.MutableRefObject<HTMLDivElement | null>).current = node\n if (typeof ref === 'function') ref(node)\n else if (ref) (ref as React.MutableRefObject<HTMLDivElement | null>).current = node\n }}\n className={cn('relative w-full', className)}\n {...props}\n >\n {width > 0 && (\n <svg width={width} height={height} role=\"img\" aria-label={ariaLabel}>\n {ariaDescription && <desc>{ariaDescription}</desc>}\n <g transform={`translate(${margin.left},${margin.top})`}>\n {children({ width: innerWidth, height: innerHeight, margin })}\n </g>\n </svg>\n )}\n </div>\n )\n },\n)\nChartContainer.displayName = 'ChartContainer'\n","'use client'\n\nimport * as React from 'react'\nimport { useRef, useEffect } from 'react'\nimport { axisBottom, axisLeft, axisRight, axisTop } from 'd3-axis'\nimport { select } from 'd3-selection'\nimport type { ScaleLinear, ScaleBand, ScalePoint, ScaleTime } from 'd3-scale'\n\nexport type AnyScale =\n | ScaleLinear<number, number>\n | ScaleBand<string>\n | ScalePoint<string>\n | ScaleTime<number, number>\n\ninterface AxisProps {\n scale: AnyScale\n orientation: 'top' | 'right' | 'bottom' | 'left'\n transform?: string\n tickCount?: number\n tickFormat?: (value: unknown) => string\n label?: string\n className?: string\n}\n\nexport function Axis({\n scale,\n orientation,\n transform,\n tickCount,\n tickFormat,\n label,\n className,\n}: AxisProps) {\n const ref = useRef<SVGGElement>(null)\n\n useEffect(() => {\n if (!ref.current) return\n\n const axisFn = {\n top: axisTop,\n right: axisRight,\n bottom: axisBottom,\n left: axisLeft,\n }[orientation]\n\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n let axis = axisFn(scale as any)\n if (tickCount) axis = axis.ticks(tickCount)\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n if (tickFormat) axis = axis.tickFormat(tickFormat as any)\n\n const g = select(ref.current)\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n g.call(axis as any)\n\n // Style using design tokens\n g.selectAll('.tick line').attr('stroke', 'var(--color-surface-border)')\n g.selectAll('.tick text')\n .attr('fill', 'var(--color-surface-fg-muted)')\n .attr('font-size', 'var(--font-size-xs)')\n g.selectAll('.domain').attr('stroke', 'var(--color-surface-border-strong)')\n }, [scale, orientation, tickCount, tickFormat])\n\n const labelProps =\n orientation === 'bottom'\n ? { x: '50%', dy: 35 }\n : orientation === 'left'\n ? { transform: 'rotate(-90)', y: -40, x: 0 }\n : {}\n\n return (\n <g ref={ref} transform={transform} className={className}>\n {label && (\n <text\n textAnchor=\"middle\"\n fill=\"var(--color-surface-fg-muted)\"\n fontSize=\"var(--font-size-sm)\"\n {...labelProps}\n >\n {label}\n </text>\n )}\n </g>\n )\n}\nAxis.displayName = 'Axis'\n","import * as React from 'react'\nimport type { ScaleLinear, ScaleTime } from 'd3-scale'\n\ntype TickableScale = ScaleLinear<number, number> | ScaleTime<number, number>\n\ninterface GridLinesProps {\n width: number\n height: number\n xScale?: TickableScale\n yScale?: TickableScale\n horizontal?: boolean\n vertical?: boolean\n}\n\nexport function GridLines({\n width,\n height,\n xScale,\n yScale,\n horizontal = true,\n vertical = false,\n}: GridLinesProps) {\n return (\n <g className=\"grid-lines\">\n {horizontal &&\n yScale?.ticks &&\n yScale.ticks().map((tick: number | Date, i: number) => (\n <line\n key={`h-${i}`}\n x1={0}\n x2={width}\n y1={yScale(tick as number)}\n y2={yScale(tick as number)}\n stroke=\"var(--color-surface-border)\"\n strokeDasharray=\"3,3\"\n opacity={0.6}\n />\n ))}\n {vertical &&\n xScale?.ticks &&\n xScale.ticks().map((tick: number | Date, i: number) => (\n <line\n key={`v-${i}`}\n x1={xScale(tick as number)}\n x2={xScale(tick as number)}\n y1={0}\n y2={height}\n stroke=\"var(--color-surface-border)\"\n strokeDasharray=\"3,3\"\n opacity={0.6}\n />\n ))}\n </g>\n )\n}\nGridLines.displayName = 'GridLines'\n","import * as React from 'react'\nimport { cn } from '../../lib/utils'\n\ninterface LegendItem {\n label: string\n color: string // CSS color value or var() reference\n}\n\ninterface LegendProps {\n items: LegendItem[]\n position?: 'top' | 'bottom' | 'left' | 'right'\n className?: string\n}\n\nexport function Legend({ items, position = 'bottom', className }: LegendProps) {\n const isVertical = position === 'left' || position === 'right'\n\n return (\n <div\n className={cn(\n 'flex gap-ds-04 text-ds-sm text-surface-fg-muted',\n isVertical ? 'flex-col' : 'flex-row flex-wrap justify-center',\n className,\n )}\n >\n {items.map((item) => (\n <div key={item.label} className=\"flex items-center gap-ds-02\">\n <span\n className=\"inline-block h-3 w-3 shrink-0 rounded-ds-sm\"\n style={{ backgroundColor: item.color }}\n />\n <span>{item.label}</span>\n </div>\n ))}\n </div>\n )\n}\nLegend.displayName = 'Legend'\n\nexport type { LegendItem, LegendProps }\n","'use client'\n\nimport * as React from 'react'\nimport { useState, useCallback } from 'react'\nimport { cn } from '../../lib/utils'\n\ninterface TooltipState {\n visible: boolean\n x: number\n y: number\n content: React.ReactNode\n}\n\ninterface ChartTooltipProps {\n state: TooltipState\n className?: string\n}\n\nexport function ChartTooltip({ state, className }: ChartTooltipProps) {\n if (!state.visible) return null\n\n return (\n <div\n className={cn(\n 'pointer-events-none absolute z-tooltip',\n 'rounded-ds-md border border-surface-border-strong',\n 'bg-surface-overlay px-ds-03 py-ds-02',\n 'shadow-raised-hover',\n 'text-ds-sm text-surface-fg',\n className,\n )}\n style={{ left: state.x + 12, top: state.y - 12 }}\n >\n {state.content}\n </div>\n )\n}\nChartTooltip.displayName = 'ChartTooltip'\n\n/** Hook to manage chart tooltip state */\nexport function useChartTooltip() {\n const [tooltip, setTooltip] = useState<TooltipState>({\n visible: false,\n x: 0,\n y: 0,\n content: null,\n })\n\n const show = useCallback((x: number, y: number, content: React.ReactNode) => {\n setTooltip({ visible: true, x, y, content })\n }, [])\n\n const hide = useCallback(() => {\n setTooltip((prev) => ({ ...prev, visible: false }))\n }, [])\n\n return { tooltip, show, hide }\n}\n\nexport type { TooltipState, ChartTooltipProps }\n","import type { ChartColor } from './types'\n\nconst CHART_COLORS: ChartColor[] = [\n 'chart-1',\n 'chart-2',\n 'chart-3',\n 'chart-4',\n 'chart-5',\n 'chart-6',\n 'chart-7',\n 'chart-8',\n]\n\n/** Get CSS variable reference for a chart color token */\nexport function getChartColor(color: ChartColor): string {\n return `var(--${color})`\n}\n\n/** Get an array of chart color CSS variable references, cycling if needed */\nexport function getChartColors(count: number): string[] {\n return Array.from({ length: count }, (_, i) =>\n getChartColor(CHART_COLORS[i % CHART_COLORS.length]),\n )\n}\n\n/** Resolve a color prop — if it's a ChartColor token name, convert to var(); otherwise pass through */\nexport function resolveColor(color: string | ChartColor | undefined, index: number = 0): string {\n if (!color) return getChartColor(CHART_COLORS[index % CHART_COLORS.length])\n if ((CHART_COLORS as string[]).includes(color)) return getChartColor(color as ChartColor)\n return color // pass through raw CSS color\n}\n","'use client'\n\nimport { useMotion } from '../../../motion/motion-provider'\n\n/** Hook to detect reduced-motion preference via MotionProvider context */\nexport function useReducedMotion(): boolean {\n const { reducedMotion } = useMotion()\n return reducedMotion\n}\n\n/** Get transition duration respecting reduced motion preference */\nexport function getTransitionDuration(reducedMotion: boolean, duration = 300): number {\n return reducedMotion ? 0 : duration\n}\n","'use client'\n\nimport * as React from 'react'\nimport { motion } from 'framer-motion'\nimport { scaleBand, scaleLinear } from 'd3-scale'\nimport { cn } from '../lib/utils'\nimport { tweens, motionProps } from '../lib/motion'\nimport { ChartContainer } from './chart-container'\nimport { Axis } from './_internal/axes'\nimport { GridLines } from './_internal/grid-lines'\nimport { Legend } from './_internal/legend'\nimport { ChartTooltip, useChartTooltip } from './_internal/tooltip'\nimport { resolveColor } from './_internal/colors'\nimport { useReducedMotion } from './_internal/animation'\nimport type { DataPoint, ChartColor } from './_internal/types'\n\nexport interface BarChartProps extends Omit<React.HTMLAttributes<HTMLDivElement>, 'children' | 'color'> {\n /** Data array */\n data: DataPoint[]\n /** Key for x-axis categories */\n xKey: string\n /** Key(s) for y-axis values. String for single series, array for multi-series */\n yKey: string | string[]\n /** Bar orientation */\n orientation?: 'vertical' | 'horizontal'\n /** Stack multiple series */\n stacked?: boolean\n /** Group multiple series side by side */\n grouped?: boolean\n /** Color(s) for bars */\n color?: ChartColor | ChartColor[] | string | string[]\n /** Chart height in pixels */\n height?: number\n /** Show background grid lines */\n showGrid?: boolean\n /** Show tooltip on hover */\n showTooltip?: boolean\n /** Show legend (only for multi-series) */\n showLegend?: boolean\n /** Animate bars on mount */\n animate?: boolean\n /** Bar corner radius */\n barRadius?: number\n /** X-axis label */\n xLabel?: string\n /** Y-axis label */\n yLabel?: string\n /** Series labels (for legend) */\n seriesLabels?: string[]\n /** Accessible label for the chart */\n ariaLabel?: string\n className?: string\n}\n\nexport const BarChart = React.forwardRef<HTMLDivElement, BarChartProps>(\n (\n {\n data,\n xKey,\n yKey,\n orientation = 'vertical',\n stacked = false,\n grouped = false,\n color,\n height = 300,\n showGrid = true,\n showTooltip = true,\n showLegend = false,\n animate = true,\n barRadius = 4,\n xLabel,\n yLabel,\n seriesLabels,\n ariaLabel,\n className,\n ...props\n },\n ref,\n ) => {\n const { tooltip, show, hide } = useChartTooltip()\n const reducedMotion = useReducedMotion()\n const isVertical = orientation === 'vertical'\n const shouldAnimate = animate && !reducedMotion\n\n // Normalize yKey to array\n const yKeys = Array.isArray(yKey) ? yKey : [yKey]\n const isMultiSeries = yKeys.length > 1\n\n // Resolve colors\n const colors = isMultiSeries\n ? yKeys.map((_, i) =>\n resolveColor(\n Array.isArray(color) ? color[i] : typeof color === 'string' ? color : undefined,\n i,\n ),\n )\n : [\n resolveColor(\n typeof color === 'string'\n ? color\n : Array.isArray(color)\n ? color[0]\n : undefined,\n 0,\n ),\n ]\n\n return (\n <motion.div\n ref={ref}\n className={cn('relative', className)}\n {...(shouldAnimate\n ? { initial: { opacity: 0, scale: 0.96 }, animate: { opacity: 1, scale: 1 }, transition: tweens.fade }\n : {})}\n {...motionProps(props)}\n >\n <ChartContainer height={height} ariaLabel={ariaLabel ?? 'Bar chart'}>\n {({ width, height: innerHeight, margin }) => {\n // Suppress unused-var lint for margin (available for extensions)\n void margin\n\n // Category labels\n const categories = data.map((d) => String(d[xKey]))\n\n // Build data summary for screen readers\n const dataSummary = data.map((d) => {\n const cat = String(d[xKey])\n const vals = yKeys.map((k, i) => {\n const lbl = seriesLabels?.[i] ?? k\n return `${lbl}: ${Number(d[k]).toLocaleString()}`\n }).join(', ')\n return `${cat} — ${vals}`\n }).join('. ')\n\n // Calculate max value\n let maxValue: number\n if (stacked) {\n maxValue = Math.max(\n ...data.map((d) =>\n yKeys.reduce((sum, k) => sum + (Number(d[k]) || 0), 0),\n ),\n )\n } else {\n maxValue = Math.max(\n ...data.flatMap((d) => yKeys.map((k) => Number(d[k]) || 0)),\n )\n }\n\n // Build scales\n const categoryScale = scaleBand()\n .domain(categories)\n .range(isVertical ? [0, width] : [0, innerHeight])\n .padding(0.2)\n\n const valueScale = scaleLinear()\n .domain([0, maxValue * 1.1])\n .range(isVertical ? [innerHeight, 0] : [0, width])\n .nice()\n\n const barBandwidth = categoryScale.bandwidth()\n const barWidth =\n isMultiSeries && grouped\n ? barBandwidth / yKeys.length\n : barBandwidth\n\n return (\n <>\n {/* Screen-reader data summary */}\n <desc>{dataSummary}</desc>\n\n {/* Grid */}\n {showGrid && (\n <GridLines\n width={width}\n height={innerHeight}\n yScale={isVertical ? valueScale : undefined}\n xScale={!isVertical ? valueScale : undefined}\n horizontal={isVertical}\n vertical={!isVertical}\n />\n )}\n\n {/* Bars */}\n {data.map((d) => {\n const category = String(d[xKey])\n let stackOffset = 0\n\n return yKeys.map((key, seriesIdx) => {\n const value = Number(d[key]) || 0\n const barColor = colors[seriesIdx] || colors[0]\n\n let x: number, y: number, w: number, h: number\n\n if (isVertical) {\n x =\n (categoryScale(category) ?? 0) +\n (grouped && isMultiSeries ? seriesIdx * barWidth : 0)\n y = stacked\n ? valueScale(stackOffset + value)\n : valueScale(value)\n w = barWidth\n h = stacked\n ? valueScale(stackOffset) - valueScale(stackOffset + value)\n : innerHeight - valueScale(value)\n } else {\n x = stacked ? valueScale(stackOffset) : 0\n y =\n (categoryScale(category) ?? 0) +\n (grouped && isMultiSeries ? seriesIdx * barWidth : 0)\n w = stacked\n ? valueScale(stackOffset + value) - valueScale(stackOffset)\n : valueScale(value)\n h = barWidth\n }\n\n if (stacked) stackOffset += value\n\n const seriesLabel = seriesLabels?.[seriesIdx] ?? key\n const barAriaLabel = isMultiSeries\n ? `${category}, ${seriesLabel}: ${value.toLocaleString()}`\n : `${category}: ${value.toLocaleString()}`\n\n const tooltipContent = (\n <div>\n <div className=\"font-medium\">{category}</div>\n {isMultiSeries && (\n <div className=\"text-surface-fg-muted\">\n {seriesLabel}\n </div>\n )}\n <div>{value.toLocaleString()}</div>\n </div>\n )\n\n return (\n <rect\n key={`${category}-${key}`}\n x={x}\n y={y}\n width={Math.max(0, w)}\n height={Math.max(0, h)}\n rx={barRadius}\n fill={barColor}\n className=\"transition-opacity hover:opacity-80 focus-visible:outline-none focus-visible:opacity-80\"\n tabIndex={showTooltip ? 0 : undefined}\n role={showTooltip ? 'graphics-symbol' : undefined}\n aria-label={barAriaLabel}\n onMouseMove={(e) => {\n if (showTooltip) {\n const rect = e.currentTarget\n .closest('div')\n ?.getBoundingClientRect()\n show(\n e.clientX - (rect?.left ?? 0),\n e.clientY - (rect?.top ?? 0),\n tooltipContent,\n )\n }\n }}\n onMouseLeave={hide}\n onFocus={(e) => {\n if (showTooltip) {\n const svgRect = e.currentTarget\n .closest('div')\n ?.getBoundingClientRect()\n const barRect = e.currentTarget.getBoundingClientRect()\n show(\n barRect.left + barRect.width / 2 - (svgRect?.left ?? 0),\n barRect.top - (svgRect?.top ?? 0),\n tooltipContent,\n )\n }\n }}\n onBlur={hide}\n />\n )\n })\n })}\n\n {/* Axes */}\n {isVertical ? (\n <>\n <Axis\n scale={categoryScale}\n orientation=\"bottom\"\n transform={`translate(0,${innerHeight})`}\n label={xLabel}\n />\n <Axis scale={valueScale} orientation=\"left\" label={yLabel} />\n </>\n ) : (\n <>\n <Axis\n scale={valueScale}\n orientation=\"bottom\"\n transform={`translate(0,${innerHeight})`}\n label={xLabel}\n />\n <Axis\n scale={categoryScale}\n orientation=\"left\"\n label={yLabel}\n />\n </>\n )}\n </>\n )\n }}\n </ChartContainer>\n\n {/* Tooltip overlay */}\n {showTooltip && <ChartTooltip state={tooltip} />}\n\n {/* Legend */}\n {showLegend && isMultiSeries && (\n <Legend\n items={yKeys.map((key, i) => ({\n label: seriesLabels?.[i] ?? key,\n color: colors[i],\n }))}\n className=\"mt-ds-04\"\n />\n )}\n </motion.div>\n )\n },\n)\nBarChart.displayName = 'BarChart'\n","'use client'\n\nimport * as React from 'react'\nimport { motion } from 'framer-motion'\nimport { line, curveMonotoneX, curveLinear } from 'd3-shape'\nimport { scaleLinear, scalePoint } from 'd3-scale'\nimport type { ScaleLinear, ScalePoint } from 'd3-scale'\nimport { cn } from '../lib/utils'\nimport { tweens, motionProps } from '../lib/motion'\nimport { ChartContainer } from './chart-container'\nimport { Axis, type AnyScale } from './_internal/axes'\nimport { GridLines } from './_internal/grid-lines'\nimport { Legend } from './_internal/legend'\nimport { ChartTooltip, useChartTooltip } from './_internal/tooltip'\nimport { resolveColor } from './_internal/colors'\nimport { useReducedMotion } from './_internal/animation'\nimport type { DataPoint, Series } from './_internal/types'\n\nexport interface LineChartProps extends Omit<React.HTMLAttributes<HTMLDivElement>, 'children'> {\n /** Data array */\n data: DataPoint[]\n /** Key for x-axis */\n xKey: string\n /** Series definitions — each becomes a line */\n series: Series[]\n /** Use curved (monotone) interpolation */\n curved?: boolean\n /** Show dots at data points */\n showDots?: boolean\n /** Dot radius */\n dotSize?: number\n /** Line stroke width */\n strokeWidth?: number\n /** Chart height */\n height?: number\n /** Show grid lines */\n showGrid?: boolean\n /** Show tooltip on hover */\n showTooltip?: boolean\n /** Show legend */\n showLegend?: boolean\n /** Animate on mount */\n animate?: boolean\n /** X-axis label */\n xLabel?: string\n /** Y-axis label */\n yLabel?: string\n /** Accessible label for the chart */\n ariaLabel?: string\n className?: string\n}\n\nexport const LineChart = React.forwardRef<HTMLDivElement, LineChartProps>(\n (\n {\n data,\n xKey,\n series,\n curved = false,\n showDots = false,\n dotSize = 4,\n strokeWidth = 2,\n height = 300,\n showGrid = true,\n showTooltip = true,\n showLegend = false,\n animate = true,\n xLabel,\n yLabel,\n ariaLabel,\n className,\n ...props\n },\n ref,\n ) => {\n const { tooltip, show, hide } = useChartTooltip()\n const reducedMotion = useReducedMotion()\n const shouldAnimate = animate && !reducedMotion\n\n // Resolve colors for each series\n const colors = series.map((s, i) => resolveColor(s.color, i))\n\n return (\n <motion.div\n ref={ref}\n className={cn('relative', className)}\n {...(shouldAnimate\n ? { initial: { opacity: 0, scale: 0.96 }, animate: { opacity: 1, scale: 1 }, transition: tweens.fade }\n : {})}\n {...motionProps(props)}\n >\n <ChartContainer height={height} ariaLabel={ariaLabel ?? 'Line chart'}>\n {({ width, height: innerHeight, margin }) => {\n void margin\n\n // Determine if x-axis data is numeric or categorical\n const xValues = data.map((d) => d[xKey])\n const isNumericX = xValues.every((v) => typeof v === 'number')\n\n // Build x scale and accessor\n let xAxisScale: ScaleLinear<number, number> | ScalePoint<string>\n let getX: (d: DataPoint) => number\n\n if (isNumericX) {\n const numericValues = xValues as number[]\n const xMin = Math.min(...numericValues)\n const xMax = Math.max(...numericValues)\n const linearX = scaleLinear<number, number>()\n .domain([xMin, xMax])\n .range([0, width])\n xAxisScale = linearX\n getX = (d: DataPoint) => linearX(Number(d[xKey]))\n } else {\n const categories = xValues.map(String)\n const pointX = scalePoint<string>()\n .domain(categories)\n .range([0, width])\n .padding(0.5)\n xAxisScale = pointX\n getX = (d: DataPoint) => pointX(String(d[xKey])) ?? 0\n }\n\n // Build y scale across all series\n const allValues = data.flatMap((d) =>\n series.map((s) => Number(d[s.key]) || 0),\n )\n const yMax = Math.max(...allValues)\n const yScale = scaleLinear<number, number>()\n .domain([0, yMax * 1.1])\n .range([innerHeight, 0])\n .nice()\n\n // Line generator\n const curveType = curved ? curveMonotoneX : curveLinear\n const lineGen = line<DataPoint>()\n .curve(curveType)\n .defined((d) => d !== undefined && d !== null)\n\n // Build data summary for screen readers\n const dataSummary = data.map((d) => {\n const xVal = String(d[xKey])\n const vals = series.map((s) =>\n `${s.label}: ${Number(d[s.key]).toLocaleString()}`\n ).join(', ')\n return `${xVal} — ${vals}`\n }).join('. ')\n\n return (\n <>\n {/* Screen-reader data summary */}\n <desc>{dataSummary}</desc>\n\n {/* Grid */}\n {showGrid && (\n <GridLines\n width={width}\n height={innerHeight}\n yScale={yScale}\n horizontal\n />\n )}\n\n {/* Lines */}\n {series.map((s, seriesIdx) => {\n const pathGen = lineGen\n .x((d) => getX(d))\n .y((d) => yScale(Number(d[s.key]) || 0))\n\n const pathD = pathGen(data) ?? ''\n\n return (\n <g key={s.key}>\n {/* Line path */}\n <path\n d={pathD}\n fill=\"none\"\n stroke={colors[seriesIdx]}\n strokeWidth={strokeWidth}\n strokeLinejoin=\"round\"\n strokeLinecap=\"round\"\n />\n\n {/* Data point dots */}\n {showDots &&\n data.map((d, i) => {\n const cx = getX(d)\n const cy = yScale(Number(d[s.key]) || 0)\n return (\n <circle\n key={`${s.key}-dot-${i}`}\n cx={cx}\n cy={cy}\n r={dotSize}\n fill={colors[seriesIdx]}\n className=\"transition-opacity hover:opacity-80\"\n />\n )\n })}\n </g>\n )\n })}\n\n {/* Invisible hover/focus rectangles for tooltip */}\n {showTooltip &&\n data.map((d, i) => {\n const cx = getX(d)\n const sliceWidth = width / Math.max(data.length - 1, 1)\n const xVal = String(d[xKey])\n const pointAriaLabel = `${xVal}: ${series.map((s) => `${s.label} ${Number(d[s.key]).toLocaleString()}`).join(', ')}`\n\n const tooltipContent = (\n <div>\n <div className=\"font-medium\">{xVal}</div>\n {series.map((s, sIdx) => (\n <div\n key={s.key}\n className=\"flex items-center gap-ds-02\"\n >\n <span\n className=\"inline-block h-2 w-2 rounded-ds-full\"\n style={{ backgroundColor: colors[sIdx] }}\n />\n <span className=\"text-surface-fg-muted\">\n {s.label}:\n </span>{' '}\n {Number(d[s.key]).toLocaleString()}\n </div>\n ))}\n </div>\n )\n\n return (\n <rect\n key={`hover-${i}`}\n x={cx - sliceWidth / 2}\n y={0}\n width={sliceWidth}\n height={innerHeight}\n fill=\"transparent\"\n tabIndex={0}\n role=\"graphics-symbol\"\n aria-label={pointAriaLabel}\n className=\"focus-visible:outline-none\"\n onMouseMove={(e) => {\n const rect = e.currentTarget\n .closest('div')\n ?.getBoundingClientRect()\n show(\n e.clientX - (rect?.left ?? 0),\n e.clientY - (rect?.top ?? 0),\n tooltipContent,\n )\n }}\n onMouseLeave={hide}\n onFocus={(e) => {\n const svgRect = e.currentTarget\n .closest('div')\n ?.getBoundingClientRect()\n const sliceRect = e.currentTarget.getBoundingClientRect()\n show(\n sliceRect.left + sliceRect.width / 2 - (svgRect?.left ?? 0),\n sliceRect.top + sliceRect.height / 2 - (svgRect?.top ?? 0),\n tooltipContent,\n )\n }}\n onBlur={hide}\n />\n )\n })}\n\n {/* Axes */}\n <Axis\n scale={xAxisScale as AnyScale}\n orientation=\"bottom\"\n transform={`translate(0,${innerHeight})`}\n label={xLabel}\n />\n <Axis scale={yScale} orientation=\"left\" label={yLabel} />\n </>\n )\n }}\n </ChartContainer>\n\n {/* Tooltip overlay */}\n {showTooltip && <ChartTooltip state={tooltip} />}\n\n {/* Legend */}\n {showLegend && series.length > 1 && (\n <Legend\n items={series.map((s, i) => ({\n label: s.label,\n color: colors[i],\n }))}\n className=\"mt-ds-04\"\n />\n )}\n </motion.div>\n )\n },\n)\nLineChart.displayName = 'LineChart'\n","'use client'\n\nimport * as React from 'react'\nimport { motion } from 'framer-motion'\nimport {\n area,\n line,\n stack,\n stackOrderNone,\n stackOffsetNone,\n curveMonotoneX,\n curveLinear,\n} from 'd3-shape'\nimport { scaleLinear, scalePoint } from 'd3-scale'\nimport type { ScaleLinear, ScalePoint } from 'd3-scale'\nimport { cn } from '../lib/utils'\nimport { tweens, motionProps } from '../lib/motion'\nimport { ChartContainer } from './chart-container'\nimport { Axis, type AnyScale } from './_internal/axes'\nimport { GridLines } from './_internal/grid-lines'\nimport { Legend } from './_internal/legend'\nimport { ChartTooltip, useChartTooltip } from './_internal/tooltip'\nimport { resolveColor } from './_internal/colors'\nimport { useReducedMotion } from './_internal/animation'\nimport type { DataPoint, Series } from './_internal/types'\n\nexport interface AreaChartProps extends Omit<React.HTMLAttributes<HTMLDivElement>, 'children'> {\n /** Data array */\n data: DataPoint[]\n /** Key for x-axis */\n xKey: string\n /** Series definitions — each becomes an area */\n series: Series[]\n /** Use curved (monotone) interpolation */\n curved?: boolean\n /** Stack areas on top of each other */\n stacked?: boolean\n /** Fill opacity for area shapes */\n fillOpacity?: number\n /** Use vertical gradient fill */\n gradient?: boolean\n /** Stroke width for area outline */\n strokeWidth?: number\n /** Chart height */\n height?: number\n /** Show grid lines */\n showGrid?: boolean\n /** Show tooltip on hover */\n showTooltip?: boolean\n /** Show legend */\n showLegend?: boolean\n /** Animate on mount */\n animate?: boolean\n /** X-axis label */\n xLabel?: string\n /** Y-axis label */\n yLabel?: string\n /** Accessible label for the chart */\n ariaLabel?: string\n className?: string\n}\n\n/** Type for rows fed to d3 stack — all numeric except the xKey */\ninterface StackableRow {\n [key: string]: number | string\n}\n\nexport const AreaChart = React.forwardRef<HTMLDivElement, AreaChartProps>(\n (\n {\n data,\n xKey,\n series,\n curved = false,\n stacked = false,\n fillOpacity = 0.3,\n gradient = false,\n strokeWidth = 2,\n height = 300,\n showGrid = true,\n showTooltip = true,\n showLegend = false,\n animate = true,\n xLabel,\n yLabel,\n ariaLabel,\n className,\n ...props\n },\n ref,\n ) => {\n const { tooltip, show, hide } = useChartTooltip()\n const reducedMotion = useReducedMotion()\n const shouldAnimate = animate && !reducedMotion\n\n // Resolve colors for each series\n const colors = series.map((s, i) => resolveColor(s.color, i))\n\n // Stable unique ID for gradient definitions\n const chartId = React.useId()\n\n return (\n <motion.div\n ref={ref}\n className={cn('relative', className)}\n {...(shouldAnimate\n ? { initial: { opacity: 0, scale: 0.96 }, animate: { opacity: 1, scale: 1 }, transition: tweens.fade }\n : {})}\n {...motionProps(props)}\n >\n <ChartContainer height={height} ariaLabel={ariaLabel ?? 'Area chart'}>\n {({ width, height: innerHeight, margin }) => {\n void margin\n\n // Determine if x-axis data is numeric or categorical\n const xValues = data.map((d) => d[xKey])\n const isNumericX = xValues.every((v) => typeof v === 'number')\n\n // Build x scale and accessor\n let xAxisScale: ScaleLinear<number, number> | ScalePoint<string>\n let getX: (d: DataPoint) => number\n let getXByIndex: (i: number) => number\n\n if (isNumericX) {\n const numericValues = xValues as number[]\n const xMin = Math.min(...numericValues)\n const xMax = Math.max(...numericValues)\n const linearX = scaleLinear<number, number>()\n .domain([xMin, xMax])\n .range([0, width])\n xAxisScale = linearX\n getX = (d: DataPoint) => linearX(Number(d[xKey]))\n getXByIndex = (i: number) => linearX(Number(data[i][xKey]))\n } else {\n const categories = xValues.map(String)\n const pointX = scalePoint<string>()\n .domain(categories)\n .range([0, width])\n .padding(0.5)\n xAxisScale = pointX\n getX = (d: DataPoint) => pointX(String(d[xKey])) ?? 0\n getXByIndex = (i: number) => pointX(String(data[i][xKey])) ?? 0\n }\n\n // Build y scale\n let yMax: number\n if (stacked) {\n yMax = Math.max(\n ...data.map((d) =>\n series.reduce((sum, s) => sum + (Number(d[s.key]) || 0), 0),\n ),\n )\n } else {\n yMax = Math.max(\n ...data.flatMap((d) =>\n series.map((s) => Number(d[s.key]) || 0),\n ),\n )\n }\n\n const yScale = scaleLinear<number, number>()\n .domain([0, yMax * 1.1])\n .range([innerHeight, 0])\n .nice()\n\n const curveType = curved ? curveMonotoneX : curveLinear\n\n // Shared tooltip render function\n const renderTooltipZones = () =>\n data.map((d, i) => {\n const cx = getX(d)\n const sliceWidth = width / Math.max(data.length - 1, 1)\n return (\n <rect\n key={`hover-${i}`}\n x={cx - sliceWidth / 2}\n y={0}\n width={sliceWidth}\n height={innerHeight}\n fill=\"transparent\"\n onMouseMove={(e) => {\n const rect = e.currentTarget\n .closest('div')\n ?.getBoundingClientRect()\n show(\n e.clientX - (rect?.left ?? 0),\n e.clientY - (rect?.top ?? 0),\n <div>\n <div className=\"font-medium\">\n {String(d[xKey])}\n </div>\n {series.map((s, sIdx) => (\n <div\n key={s.key}\n className=\"flex items-center gap-ds-02\"\n >\n <span\n className=\"inline-block h-2 w-2 rounded-ds-full\"\n style={{ backgroundColor: colors[sIdx] }}\n />\n <span className=\"text-surface-fg-muted\">\n {s.label}:\n </span>{' '}\n {Number(d[s.key]).toLocaleString()}\n </div>\n ))}\n </div>,\n )\n }}\n onMouseLeave={hide}\n />\n )\n })\n\n // Shared gradient definitions\n const renderGradientDefs = () =>\n gradient ? (\n <defs>\n {series.map((_, sIdx) => (\n <linearGradient\n key={`grad-${sIdx}`}\n id={`${chartId}-gradient-${sIdx}`}\n x1=\"0\"\n y1=\"0\"\n x2=\"0\"\n y2=\"1\"\n >\n <stop\n offset=\"0%\"\n stopColor={colors[sIdx]}\n stopOpacity={fillOpacity}\n />\n <stop\n offset=\"100%\"\n stopColor={colors[sIdx]}\n stopOpacity={0.05}\n />\n </linearGradient>\n ))}\n </defs>\n ) : null\n\n // Shared axes\n const renderAxes = () => (\n <>\n <Axis\n scale={xAxisScale as AnyScale}\n orientation=\"bottom\"\n transform={`translate(0,${innerHeight})`}\n label={xLabel}\n />\n <Axis scale={yScale} orientation=\"left\" label={yLabel} />\n </>\n )\n\n // Stacked layout\n if (stacked) {\n const seriesKeys = series.map((s) => s.key)\n const stackGen = stack<StackableRow>()\n .keys(seriesKeys)\n .order(stackOrderNone)\n .offset(stackOffsetNone)\n\n // Coerce data to StackableRow (numeric values for series keys)\n const numericData: StackableRow[] = data.map((d) => {\n const row: StackableRow = { [xKey]: String(d[xKey]) }\n for (const s of series) {\n row[s.key] = Number(d[s.key]) || 0\n }\n return row\n })\n\n const stackedData = stackGen(numericData)\n\n const areaGen = area<[number, number]>()\n .curve(curveType)\n .x((_, i) => getXByIndex(i))\n .y0((d) => yScale(d[0]))\n .y1((d) => yScale(d[1]))\n\n const lineGen = line<[number, number]>()\n .curve(curveType)\n .x((_, i) => getXByIndex(i))\n .y((d) => yScale(d[1]))\n\n return (\n <>\n {renderGradientDefs()}\n\n {/* Grid */}\n {showGrid && (\n <GridLines\n width={width}\n height={innerHeight}\n yScale={yScale}\n horizontal\n />\n )}\n\n {/* Stacked areas (render in reverse so first series is on top) */}\n {[...stackedData].reverse().map((layer, reversedIdx) => {\n const seriesIdx = stackedData.length - 1 - reversedIdx\n const layerData = layer as unknown as [number, number][]\n const areaD = areaGen(layerData) ?? ''\n const lineD = lineGen(layerData) ?? ''\n const fillColor = gradient\n ? `url(#${chartId}-gradient-${seriesIdx})`\n : colors[seriesIdx]\n\n return (\n <g key={series[seriesIdx].key}>\n <path\n d={areaD}\n fill={fillColor}\n opacity={gradient ? 1 : fillOpacity}\n />\n <path\n d={lineD}\n fill=\"none\"\n stroke={colors[seriesIdx]}\n strokeWidth={strokeWidth}\n strokeLinejoin=\"round\"\n strokeLinecap=\"round\"\n />\n </g>\n )\n })}\n\n {/* Tooltip hover zones */}\n {showTooltip && renderTooltipZones()}\n\n {renderAxes()}\n </>\n )\n }\n\n // Non-stacked areas\n const areaGen = area<DataPoint>()\n .curve(curveType)\n .defined((d) => d !== undefined && d !== null)\n\n const lineGen = line<DataPoint>()\n .curve(curveType)\n .defined((d) => d !== undefined && d !== null)\n\n return (\n <>\n {renderGradientDefs()}\n\n {/* Grid */}\n {showGrid && (\n <GridLines\n width={width}\n height={innerHeight}\n yScale={yScale}\n horizontal\n />\n )}\n\n {/* Areas (render in reverse so first series is visually on top) */}\n {[...series].reverse().map((s, reversedIdx) => {\n const seriesIdx = series.length - 1 - reversedIdx\n\n const areaPath = areaGen\n .x((d) => getX(d))\n .y0(innerHeight)\n .y1((d) => yScale(Number(d[s.key]) || 0))\n\n const linePath = lineGen\n .x((d) => getX(d))\n .y((d) => yScale(Number(d[s.key]) || 0))\n\n const areaD = areaPath(data) ?? ''\n const lineD = linePath(data) ?? ''\n\n const fillColor = gradient\n ? `url(#${chartId}-gradient-${seriesIdx})`\n : colors[seriesIdx]\n\n return (\n <g key={s.key}>\n <path\n d={areaD}\n fill={fillColor}\n opacity={gradient ? 1 : fillOpacity}\n />\n <path\n d={lineD}\n fill=\"none\"\n stroke={colors[seriesIdx]}\n strokeWidth={strokeWidth}\n strokeLinejoin=\"round\"\n strokeLinecap=\"round\"\n />\n </g>\n )\n })}\n\n {/* Tooltip hover zones */}\n {showTooltip && renderTooltipZones()}\n\n {renderAxes()}\n </>\n )\n }}\n </ChartContainer>\n\n {/* Tooltip overlay */}\n {showTooltip && <ChartTooltip state={tooltip} />}\n\n {/* Legend */}\n {showLegend && series.length > 1 && (\n <Legend\n items={series.map((s, i) => ({\n label: s.label,\n color: colors[i],\n }))}\n className=\"mt-ds-04\"\n />\n )}\n </motion.div>\n )\n },\n)\nAreaChart.displayName = 'AreaChart'\n","'use client'\n\nimport * as React from 'react'\nimport { useState, useRef, useEffect } from 'react'\nimport { motion } from 'framer-motion'\nimport { pie as d3Pie, arc as d3Arc } from 'd3-shape'\nimport type { PieArcDatum } from 'd3-shape'\nimport { cn } from '../lib/utils'\nimport { tweens, motionProps } from '../lib/motion'\nimport { Legend } from './_internal/legend'\nimport { ChartTooltip, useChartTooltip } from './_internal/tooltip'\nimport { resolveColor } from './_internal/colors'\nimport { useReducedMotion } from './_internal/animation'\n\ninterface PieSlice {\n label: string\n value: number\n color?: string\n}\n\nexport interface PieChartProps extends Omit<React.HTMLAttributes<HTMLDivElement>, 'children'> {\n /** Data with label and value */\n data: PieSlice[]\n /** Pie or donut variant */\n variant?: 'pie' | 'donut'\n /** Inner radius ratio for donut (0-1, default 0.6) */\n innerRadius?: number\n /** Gap angle between slices in radians */\n padAngle?: number\n /** Corner radius for slice edges */\n cornerRadius?: number\n /** Chart height (and width, since pie is square) */\n height?: number\n /** Show tooltip on hover */\n showTooltip?: boolean\n /** Show legend */\n showLegend?: boolean\n /** Show percentage labels on/near slices */\n showLabels?: boolean\n /** Animate slices */\n animate?: boolean\n className?: string\n /** Content to show in center of donut */\n centerLabel?: React.ReactNode\n /** Accessible label for the chart */\n ariaLabel?: string\n}\n\nexport const PieChart = React.forwardRef<HTMLDivElement, PieChartProps>(\n (\n {\n data,\n variant = 'pie',\n innerRadius: innerRadiusRatio = 0.6,\n padAngle = 0,\n cornerRadius = 0,\n height = 300,\n showTooltip = true,\n showLegend = false,\n showLabels = false,\n animate = true,\n className,\n centerLabel,\n ariaLabel,\n ...props\n },\n ref,\n ) => {\n const containerRef = useRef<HTMLDivElement>(null)\n const [containerWidth, setContainerWidth] = useState(0)\n const [hoveredIndex, setHoveredIndex] = useState<number | null>(null)\n const { tooltip, show, hide } = useChartTooltip()\n const reducedMotion = useReducedMotion()\n const shouldAnimate = animate && !reducedMotion\n\n useEffect(() => {\n if (!containerRef.current) return\n const observer = new ResizeObserver((entries) => {\n const entry = entries[0]\n if (entry) setContainerWidth(entry.contentRect.width)\n })\n observer.observe(containerRef.current)\n return () => observer.disconnect()\n }, [])\n\n // Pie chart is square — use the smaller of width/height\n const size = containerWidth > 0 ? Math.min(containerWidth, height) : height\n const outerRadius = size / 2\n const innerR = variant === 'donut' ? outerRadius * innerRadiusRatio : 0\n\n // Resolve colors for each slice\n const colors = data.map((d, i) => resolveColor(d.color, i))\n\n // Compute total for percentages\n const total = data.reduce((sum, d) => sum + d.value, 0)\n\n // D3 pie layout\n const pieLayout = d3Pie<PieSlice>()\n .value((d) => d.value)\n .padAngle(padAngle)\n .sort(null)\n\n const arcs = pieLayout(data)\n\n // D3 arc generator\n const arcGenerator = d3Arc<PieArcDatum<PieSlice>>()\n .innerRadius(innerR)\n .outerRadius(outerRadius - 2) // slight inset so hover offset doesn't clip\n .cornerRadius(cornerRadius)\n\n // Label arc — position labels at 70% of the way from inner to outer radius\n const labelRadius = innerR + (outerRadius - 2 - innerR) * 0.7\n const labelArc = d3Arc<PieArcDatum<PieSlice>>()\n .innerRadius(labelRadius)\n .outerRadius(labelRadius)\n\n return (\n <motion.div\n ref={(node) => {\n (containerRef as React.MutableRefObject<HTMLDivElement | null>).current = node\n if (typeof ref === 'function') ref(node)\n else if (ref) (ref as React.MutableRefObject<HTMLDivElement | null>).current = node\n }}\n className={cn('relative w-full', className)}\n {...(shouldAnimate\n ? { initial: { opacity: 0, scale: 0.96 }, animate: { opacity: 1, scale: 1 }, transition: tweens.fade }\n : {})}\n {...motionProps(props)}\n >\n {containerWidth > 0 && (\n <>\n <svg\n width={containerWidth}\n height={height}\n role=\"img\"\n aria-label={ariaLabel ?? 'Pie chart'}\n >\n <g transform={`translate(${containerWidth / 2},${height / 2})`}>\n {arcs.map((d, i) => {\n const path = arcGenerator(d)\n if (!path) return null\n\n // Hover offset: push slice outward along its centroid angle\n const [cx, cy] = arcGenerator.centroid(d)\n const angle = Math.atan2(cy, cx)\n const offsetX = Math.cos(angle) * 4\n const offsetY = Math.sin(angle) * 4\n const isHovered = hoveredIndex === i\n\n return (\n <path\n key={`slice-${d.data.label}-${i}`}\n d={path}\n fill={colors[i]}\n className=\"cursor-pointer transition-transform\"\n style={{\n transform: isHovered\n ? `translate(${offsetX}px, ${offsetY}px)`\n : undefined,\n }}\n onMouseEnter={() => setHoveredIndex(i)}\n onMouseMove={(e) => {\n if (showTooltip) {\n const rect = e.currentTarget\n .closest('div')\n ?.getBoundingClientRect()\n const pct =\n total > 0\n ? ((d.data.value / total) * 100).toFixed(1)\n : '0'\n show(\n e.clientX - (rect?.left ?? 0),\n e.clientY - (rect?.top ?? 0),\n <div>\n <div className=\"font-medium\">{d.data.label}</div>\n <div>\n {d.data.value.toLocaleString()} ({pct}%)\n </div>\n </div>,\n )\n }\n }}\n onMouseLeave={() => {\n setHoveredIndex(null)\n hide()\n }}\n />\n )\n })}\n\n {/* Percentage labels */}\n {showLabels &&\n arcs.map((d, i) => {\n const [lx, ly] = labelArc.centroid(d)\n const pct =\n total > 0\n ? ((d.data.value / total) * 100).toFixed(0)\n : '0'\n\n // Skip tiny slices (< 3%) to avoid label overlap\n if (total > 0 && d.data.value / total < 0.03) return null\n\n return (\n <text\n key={`label-${d.data.label}-${i}`}\n x={lx}\n y={ly}\n textAnchor=\"middle\"\n dominantBaseline=\"central\"\n className=\"pointer-events-none fill-accent-fg text-ds-xs font-medium\"\n >\n {pct}%\n </text>\n )\n })}\n\n {/* Center label for donut variant */}\n {variant === 'donut' && centerLabel && innerR > 0 && (\n <foreignObject\n x={-innerR * 0.7}\n y={-innerR * 0.7}\n width={innerR * 1.4}\n height={innerR * 1.4}\n >\n <div className=\"flex h-full w-full items-center justify-center text-center text-surface-fg\">\n {centerLabel}\n </div>\n </foreignObject>\n )}\n </g>\n </svg>\n\n {/* Tooltip overlay */}\n {showTooltip && <ChartTooltip state={tooltip} />}\n </>\n )}\n\n {/* Legend */}\n {showLegend && (\n <Legend\n items={data.map((d, i) => ({\n label: d.label,\n color: colors[i],\n }))}\n className=\"mt-ds-04\"\n />\n )}\n </motion.div>\n )\n },\n)\nPieChart.displayName = 'PieChart'\n","'use client'\n\nimport * as React from 'react'\nimport { motion } from 'framer-motion'\nimport { line, area, curveMonotoneX } from 'd3-shape'\nimport { scaleLinear } from 'd3-scale'\nimport { cn } from '../lib/utils'\nimport { resolveColor } from './_internal/colors'\nimport { useReducedMotion } from './_internal/animation'\n\nexport interface SparklineProps extends Omit<React.SVGAttributes<SVGSVGElement>, 'children'> {\n /** Numeric data points */\n data: number[]\n /** Visual variant */\n variant?: 'line' | 'bar' | 'area'\n /** Width (default: 120) */\n width?: number\n /** Height (default: 32) */\n height?: number\n /** Color token or CSS color */\n color?: string\n /** Show a dot on the last data point (line/area only) */\n showLastDot?: boolean\n /** Line stroke width (line/area only, default: 1.5) */\n strokeWidth?: number\n /** Animate on mount (default: true) */\n animate?: boolean\n className?: string\n}\n\nconst pathDrawTransition = { duration: 1, ease: 'easeOut' as const }\n\nexport const Sparkline = React.forwardRef<SVGSVGElement, SparklineProps>(\n (\n {\n data,\n variant = 'line',\n width = 120,\n height = 32,\n color,\n showLastDot = false,\n strokeWidth = 1.5,\n animate = true,\n className,\n ...props\n },\n ref,\n ) => {\n const resolvedColor = resolveColor(color, 0)\n const reducedMotion = useReducedMotion()\n const shouldAnimate = animate && !reducedMotion\n\n if (!data.length) return null\n\n const padding = variant === 'bar' ? 1 : strokeWidth\n const innerWidth = width - padding * 2\n const innerHeight = height - padding * 2\n\n const xScale = scaleLinear()\n .domain([0, Math.max(data.length - 1, 1)])\n .range([padding, padding + innerWidth])\n\n const yMin = Math.min(...data)\n const yMax = Math.max(...data)\n const yDomain = yMin === yMax ? [yMin - 1, yMax + 1] : [yMin, yMax]\n\n const yScale = scaleLinear()\n .domain(yDomain)\n .range([padding + innerHeight, padding])\n\n if (variant === 'bar') {\n const barGap = 1\n const barWidth = Math.max(\n 1,\n (innerWidth - barGap * (data.length - 1)) / data.length,\n )\n // For bars, baseline is the bottom of the chart\n const baselineY = padding + innerHeight\n\n return (\n <svg\n ref={ref}\n width={width}\n height={height}\n role=\"img\"\n aria-label=\"Sparkline bar chart\"\n className={cn('inline-block align-middle', className)}\n {...props}\n >\n {data.map((value, i) => {\n const x = padding + i * (barWidth + barGap)\n const y = yScale(value)\n const barHeight = Math.max(1, baselineY - y)\n return (\n <rect\n key={i}\n x={x}\n y={y}\n width={barWidth}\n height={barHeight}\n rx={Math.min(1, barWidth / 2)}\n fill={resolvedColor}\n />\n )\n })}\n </svg>\n )\n }\n\n if (variant === 'area') {\n const areaGen = area<number>()\n .curve(curveMonotoneX)\n .x((_, i) => xScale(i))\n .y0(padding + innerHeight)\n .y1((d) => yScale(d))\n\n const lineGen = line<number>()\n .curve(curveMonotoneX)\n .x((_, i) => xScale(i))\n .y((d) => yScale(d))\n\n const areaD = areaGen(data) ?? ''\n const lineD = lineGen(data) ?? ''\n\n const lastX = xScale(data.length - 1)\n const lastY = yScale(data[data.length - 1])\n\n return (\n <svg\n ref={ref}\n width={width}\n height={height}\n role=\"img\"\n aria-label=\"Sparkline area chart\"\n className={cn('inline-block align-middle', className)}\n {...props}\n >\n <path d={areaD} fill={resolvedColor} opacity={0.2} />\n {shouldAnimate ? (\n <motion.path\n d={lineD}\n fill=\"none\"\n stroke={resolvedColor}\n strokeWidth={strokeWidth}\n strokeLinejoin=\"round\"\n strokeLinecap=\"round\"\n initial={{ pathLength: 0 }}\n animate={{ pathLength: 1 }}\n transition={pathDrawTransition}\n />\n ) : (\n <path\n d={lineD}\n fill=\"none\"\n stroke={resolvedColor}\n strokeWidth={strokeWidth}\n strokeLinejoin=\"round\"\n strokeLinecap=\"round\"\n />\n )}\n {showLastDot && (\n <circle\n cx={lastX}\n cy={lastY}\n r={strokeWidth + 1}\n fill={resolvedColor}\n />\n )}\n </svg>\n )\n }\n\n // Default: line variant\n const lineGen = line<number>()\n .curve(curveMonotoneX)\n .x((_, i) => xScale(i))\n .y((d) => yScale(d))\n\n const pathD = lineGen(data) ?? ''\n\n const lastX = xScale(data.length - 1)\n const lastY = yScale(data[data.length - 1])\n\n return (\n <svg\n ref={ref}\n width={width}\n height={height}\n role=\"img\"\n aria-label=\"Sparkline chart\"\n className={cn('inline-block align-middle', className)}\n {...props}\n >\n {shouldAnimate ? (\n <motion.path\n d={pathD}\n fill=\"none\"\n stroke={resolvedColor}\n strokeWidth={strokeWidth}\n strokeLinejoin=\"round\"\n strokeLinecap=\"round\"\n initial={{ pathLength: 0 }}\n animate={{ pathLength: 1 }}\n transition={pathDrawTransition}\n />\n ) : (\n <path\n d={pathD}\n fill=\"none\"\n stroke={resolvedColor}\n strokeWidth={strokeWidth}\n strokeLinejoin=\"round\"\n strokeLinecap=\"round\"\n />\n )}\n {showLastDot && (\n <circle\n cx={lastX}\n cy={lastY}\n r={strokeWidth + 1}\n fill={resolvedColor}\n />\n )}\n </svg>\n )\n },\n)\nSparkline.displayName = 'Sparkline'\n","'use client'\n\nimport * as React from 'react'\nimport { motion } from 'framer-motion'\nimport { arc } from 'd3-shape'\nimport { cn } from '../lib/utils'\nimport { tweens, motionProps } from '../lib/motion'\nimport { resolveColor } from './_internal/colors'\nimport { useReducedMotion, getTransitionDuration } from './_internal/animation'\n\nexport interface GaugeChartProps extends Omit<React.HTMLAttributes<HTMLDivElement>, 'children' | 'color'> {\n /** Current value */\n value: number\n /** Maximum value (default: 100) */\n max?: number\n /** Minimum value (default: 0) */\n min?: number\n /** Label below the value */\n label?: string\n /** Custom value display */\n valueLabel?: string | ((value: number) => string)\n /** Arc color */\n color?: string\n /** Track (background) color */\n trackColor?: string\n /** Chart height/width (default: 200) */\n height?: number\n /** Start angle in degrees (default: -120) */\n startAngle?: number\n /** End angle in degrees (default: 120) */\n endAngle?: number\n /** Arc thickness in pixels (default: 16) */\n thickness?: number\n /** Animate the value arc */\n animate?: boolean\n className?: string\n}\n\nconst toRad = (deg: number) => (deg * Math.PI) / 180\n\nexport const GaugeChart = React.forwardRef<HTMLDivElement, GaugeChartProps>(\n (\n {\n value,\n max = 100,\n min = 0,\n label,\n valueLabel,\n color,\n trackColor = 'var(--color-surface-border)',\n height = 200,\n startAngle = -120,\n endAngle = 120,\n thickness = 16,\n animate = true,\n className,\n ...props\n },\n ref,\n ) => {\n const reducedMotion = useReducedMotion()\n const duration = getTransitionDuration(reducedMotion, animate ? 600 : 0)\n const shouldAnimate = animate && !reducedMotion\n\n const resolvedColor = resolveColor(color, 0)\n const size = height\n const radius = size / 2\n\n // Clamp value to [min, max]\n const clampedValue = Math.min(Math.max(value, min), max)\n const valueFraction = max === min ? 0 : (clampedValue - min) / (max - min)\n const valueEndAngle = startAngle + (endAngle - startAngle) * valueFraction\n\n // Display text\n const displayValue =\n typeof valueLabel === 'function'\n ? valueLabel(clampedValue)\n : typeof valueLabel === 'string'\n ? valueLabel\n : String(clampedValue)\n\n // Track arc generator\n const trackGenerator = arc<unknown>()\n .innerRadius(radius - thickness)\n .outerRadius(radius)\n .startAngle(toRad(startAngle))\n .endAngle(toRad(endAngle))\n .cornerRadius(thickness / 2)\n\n // Value arc generator\n const valueGenerator = arc<unknown>()\n .innerRadius(radius - thickness)\n .outerRadius(radius)\n .startAngle(toRad(startAngle))\n .endAngle(toRad(valueEndAngle))\n .cornerRadius(thickness / 2)\n\n const trackPath = trackGenerator(null as unknown as Record<string, never>) ?? ''\n const valuePath = valueGenerator(null as unknown as Record<string, never>) ?? ''\n\n return (\n <motion.div\n ref={ref}\n className={cn('inline-flex flex-col items-center', className)}\n {...(shouldAnimate\n ? { initial: { opacity: 0, scale: 0.96 }, animate: { opacity: 1, scale: 1 }, transition: tweens.fade }\n : {})}\n {...motionProps(props)}\n role=\"meter\"\n aria-valuenow={clampedValue}\n aria-valuemin={min}\n aria-valuemax={max}\n aria-label={label ?? 'Gauge chart'}\n >\n <svg width={size} height={size} role=\"img\" aria-hidden=\"true\">\n <g transform={`translate(${radius},${radius})`}>\n {/* Background track */}\n <path d={trackPath} fill={trackColor} />\n\n {/* Value arc */}\n <path\n d={valuePath}\n fill={resolvedColor}\n style={\n duration > 0\n ? { transition: `d ${duration}ms ease-out` }\n : undefined\n }\n />\n\n {/* Center value text */}\n <text\n x={0}\n y={label ? -4 : 0}\n textAnchor=\"middle\"\n dominantBaseline=\"central\"\n className=\"fill-surface-fg text-ds-2xl font-semibold\"\n >\n {displayValue}\n </text>\n\n {/* Label below value */}\n {label && (\n <text\n x={0}\n y={20}\n textAnchor=\"middle\"\n dominantBaseline=\"central\"\n className=\"fill-surface-fg-muted text-ds-xs\"\n >\n {label}\n </text>\n )}\n </g>\n </svg>\n </motion.div>\n )\n },\n)\nGaugeChart.displayName = 'GaugeChart'\n","'use client'\n\nimport * as React from 'react'\nimport { useState, useRef, useEffect } from 'react'\nimport { motion } from 'framer-motion'\nimport { lineRadial, curveLinearClosed } from 'd3-shape'\nimport { cn } from '../lib/utils'\nimport { tweens, motionProps } from '../lib/motion'\nimport { Legend } from './_internal/legend'\nimport { ChartTooltip, useChartTooltip } from './_internal/tooltip'\nimport { resolveColor } from './_internal/colors'\nimport { useReducedMotion } from './_internal/animation'\n\nexport interface RadarChartProps extends Omit<React.HTMLAttributes<HTMLDivElement>, 'children'> {\n /** Data array (one entry per data point / axis) */\n data: Record<string, string | number>[]\n /** Axis labels (3-8 axes) */\n axes: string[]\n /** Series to plot */\n series: { key: string; label: string; color?: string }[]\n /** Max value (auto-detect if not set) */\n maxValue?: number\n /** Number of concentric grid rings (default: 5) */\n levels?: number\n /** Fill opacity for the data polygon (default: 0.25) */\n fillOpacity?: number\n /** Show dots at vertices */\n showDots?: boolean\n /** Chart height (default: 300) */\n height?: number\n /** Show tooltip on hover */\n showTooltip?: boolean\n /** Show legend */\n showLegend?: boolean\n /** Animate on mount */\n animate?: boolean\n /** Accessible label for the chart */\n ariaLabel?: string\n className?: string\n}\n\nexport const RadarChart = React.forwardRef<HTMLDivElement, RadarChartProps>(\n (\n {\n data,\n axes,\n series,\n maxValue: maxValueProp,\n levels = 5,\n fillOpacity = 0.25,\n showDots = false,\n height = 300,\n showTooltip = true,\n showLegend = false,\n animate = true,\n ariaLabel,\n className,\n ...props\n },\n ref,\n ) => {\n const containerRef = useRef<HTMLDivElement>(null)\n const [containerWidth, setContainerWidth] = useState(0)\n const { tooltip, show, hide } = useChartTooltip()\n const reducedMotion = useReducedMotion()\n const shouldAnimate = animate && !reducedMotion\n\n useEffect(() => {\n if (!containerRef.current) return\n const observer = new ResizeObserver((entries) => {\n const entry = entries[0]\n if (entry) setContainerWidth(entry.contentRect.width)\n })\n observer.observe(containerRef.current)\n return () => observer.disconnect()\n }, [])\n\n // Radar chart is square — use the smaller of width/height\n const svgSize = containerWidth > 0 ? Math.min(containerWidth, height) : height\n const radius = svgSize / 2 - 40 // leave room for labels\n\n // Resolve colors for each series\n const colors = series.map((s, i) => resolveColor(s.color, i))\n\n // Auto-detect maxValue if not provided\n const maxValue =\n maxValueProp ??\n Math.max(\n ...data.flatMap((d) => series.map((s) => Number(d[s.key]) || 0)),\n 1,\n )\n\n // Angle per axis slice\n const angleSlice = (2 * Math.PI) / axes.length\n\n // D3 radial line generator for the data polygon\n const radarLine = lineRadial<number>()\n .radius((d) => (radius * d) / maxValue)\n .angle((_, i) => i * angleSlice)\n .curve(curveLinearClosed)\n\n // Convert a data row into an array of values aligned with axes\n const getSeriesValues = (seriesKey: string): number[] =>\n axes.map((_, i) => Number(data[i]?.[seriesKey]) || 0)\n\n // Convert polar to cartesian for a given axis index and value\n const polarToXY = (axisIndex: number, value: number) => {\n const angle = angleSlice * axisIndex - Math.PI / 2\n const r = (radius * value) / maxValue\n return {\n x: r * Math.cos(angle),\n y: r * Math.sin(angle),\n }\n }\n\n return (\n <motion.div\n ref={(node) => {\n (containerRef as React.MutableRefObject<HTMLDivElement | null>).current = node\n if (typeof ref === 'function') ref(node)\n else if (ref) (ref as React.MutableRefObject<HTMLDivElement | null>).current = node\n }}\n className={cn('relative w-full', className)}\n {...(shouldAnimate\n ? { initial: { opacity: 0, scale: 0.96 }, animate: { opacity: 1, scale: 1 }, transition: tweens.fade }\n : {})}\n {...motionProps(props)}\n >\n {containerWidth > 0 && (\n <>\n <svg\n width={containerWidth}\n height={height}\n role=\"img\"\n aria-label={ariaLabel ?? 'Radar chart'}\n >\n <g transform={`translate(${containerWidth / 2},${height / 2})`}>\n {/* Concentric grid polygons */}\n {Array.from({ length: levels }, (_, i) => {\n const levelRadius = (radius / levels) * (i + 1)\n const points = axes\n .map((_, j) => {\n const angle = angleSlice * j - Math.PI / 2\n return `${levelRadius * Math.cos(angle)},${levelRadius * Math.sin(angle)}`\n })\n .join(' ')\n return (\n <polygon\n key={`grid-${i}`}\n points={points}\n fill=\"none\"\n stroke=\"var(--color-surface-border)\"\n strokeDasharray=\"3,3\"\n strokeWidth={1}\n />\n )\n })}\n\n {/* Axis lines from center to outer edge */}\n {axes.map((_, i) => {\n const angle = angleSlice * i - Math.PI / 2\n const x = radius * Math.cos(angle)\n const y = radius * Math.sin(angle)\n return (\n <line\n key={`axis-${i}`}\n x1={0}\n y1={0}\n x2={x}\n y2={y}\n stroke=\"var(--color-surface-border)\"\n strokeWidth={1}\n />\n )\n })}\n\n {/* Axis labels */}\n {axes.map((label, i) => {\n const angle = angleSlice * i - Math.PI / 2\n const labelRadius = radius + 18\n const x = labelRadius * Math.cos(angle)\n const y = labelRadius * Math.sin(angle)\n\n // Determine text-anchor based on position\n let textAnchor: 'start' | 'middle' | 'end' = 'middle'\n if (Math.abs(Math.cos(angle)) > 0.1) {\n textAnchor = Math.cos(angle) > 0 ? 'start' : 'end'\n }\n\n return (\n <text\n key={`label-${i}`}\n x={x}\n y={y}\n textAnchor={textAnchor}\n dominantBaseline=\"central\"\n className=\"fill-surface-fg-muted text-ds-xs\"\n >\n {label}\n </text>\n )\n })}\n\n {/* Level value labels on the first axis */}\n {Array.from({ length: levels }, (_, i) => {\n const levelValue = Math.round((maxValue / levels) * (i + 1))\n const levelRadius = (radius / levels) * (i + 1)\n const angle = -Math.PI / 2 // first axis is at top\n const x = levelRadius * Math.cos(angle) + 4\n const y = levelRadius * Math.sin(angle)\n return (\n <text\n key={`level-label-${i}`}\n x={x}\n y={y}\n textAnchor=\"start\"\n dominantBaseline=\"auto\"\n className=\"fill-surface-fg-subtle text-ds-xs\"\n >\n {levelValue}\n </text>\n )\n })}\n\n {/* Data polygons — one per series */}\n {series.map((s, seriesIdx) => {\n const values = getSeriesValues(s.key)\n const pathD = radarLine(values)\n if (!pathD) return null\n\n return (\n <g key={s.key}>\n <path\n d={pathD}\n fill={colors[seriesIdx]}\n fillOpacity={fillOpacity}\n stroke={colors[seriesIdx]}\n strokeWidth={2}\n strokeLinejoin=\"round\"\n />\n\n {/* Vertex dots */}\n {showDots &&\n values.map((v, i) => {\n const { x, y } = polarToXY(i, v)\n return (\n <circle\n key={`dot-${s.key}-${i}`}\n cx={x}\n cy={y}\n r={4}\n fill={colors[seriesIdx]}\n stroke=\"var(--color-surface-base)\"\n strokeWidth={2}\n className=\"transition-opacity\"\n />\n )\n })}\n </g>\n )\n })}\n\n {/* Invisible hover areas at each vertex for tooltips */}\n {showTooltip &&\n axes.map((axisLabel, i) => {\n // Place a transparent circle at the outermost series point\n // for hit detection. Use the max value point for the axis.\n const angle = angleSlice * i - Math.PI / 2\n const hitX = radius * Math.cos(angle)\n const hitY = radius * Math.sin(angle)\n\n return (\n <circle\n key={`hover-${i}`}\n cx={hitX}\n cy={hitY}\n r={16}\n fill=\"transparent\"\n className=\"cursor-pointer\"\n onMouseMove={(e) => {\n const rect = e.currentTarget\n .closest('div')\n ?.getBoundingClientRect()\n show(\n e.clientX - (rect?.left ?? 0),\n e.clientY - (rect?.top ?? 0),\n <div>\n <div className=\"font-medium\">{axisLabel}</div>\n {series.map((s, sIdx) => {\n const val = Number(data[i]?.[s.key]) || 0\n return (\n <div\n key={s.key}\n className=\"flex items-center gap-ds-02\"\n >\n <span\n className=\"inline-block h-2 w-2 rounded-ds-full\"\n style={{ backgroundColor: colors[sIdx] }}\n />\n <span className=\"text-surface-fg-muted\">\n {s.label}:\n </span>{' '}\n {val.toLocaleString()}\n </div>\n )\n })}\n </div>,\n )\n }}\n onMouseLeave={hide}\n />\n )\n })}\n </g>\n </svg>\n\n {/* Tooltip overlay */}\n {showTooltip && <ChartTooltip state={tooltip} />}\n </>\n )}\n\n {/* Legend */}\n {showLegend && (\n <Legend\n items={series.map((s, i) => ({\n label: s.label,\n color: colors[i],\n }))}\n className=\"mt-ds-04\"\n />\n )}\n </motion.div>\n )\n },\n)\nRadarChart.displayName = 'RadarChart'\n"],"mappings":"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"}
1
+ {"version":3,"file":"index.js","names":[],"sources":["../../../src/ui/charts/_internal/types.ts","../../../src/ui/charts/chart-container.tsx","../../../src/ui/charts/_internal/axes.tsx","../../../src/ui/charts/_internal/grid-lines.tsx","../../../src/ui/charts/_internal/legend.tsx","../../../src/ui/charts/_internal/tooltip.tsx","../../../src/ui/charts/_internal/colors.ts","../../../src/ui/charts/_internal/animation.ts","../../../src/ui/charts/bar-chart.tsx","../../../src/ui/charts/line-chart.tsx","../../../src/ui/charts/area-chart.tsx","../../../src/ui/charts/pie-chart.tsx","../../../src/ui/charts/sparkline.tsx","../../../src/ui/charts/gauge-chart.tsx","../../../src/ui/charts/radar-chart.tsx"],"sourcesContent":["export interface ChartMargin {\n top: number\n right: number\n bottom: number\n left: number\n}\n\nexport const DEFAULT_MARGIN: ChartMargin = {\n top: 20,\n right: 20,\n bottom: 40,\n left: 50,\n}\n\nexport interface DataPoint {\n [key: string]: string | number | Date\n}\n\nexport interface Series {\n key: string\n label: string\n color?: string\n}\n\nexport type ChartColor =\n | 'chart-1'\n | 'chart-2'\n | 'chart-3'\n | 'chart-4'\n | 'chart-5'\n | 'chart-6'\n | 'chart-7'\n | 'chart-8'\n","'use client'\n\nimport * as React from 'react'\nimport { useState, useRef, useEffect } from 'react'\nimport { cn } from '../lib/utils'\nimport type { ChartMargin } from './_internal/types'\nimport { DEFAULT_MARGIN } from './_internal/types'\n\nexport interface ChartContainerProps extends Omit<React.HTMLAttributes<HTMLDivElement>, 'children'> {\n /** Fixed height in pixels */\n height?: number\n /** Chart margins */\n margin?: Partial<ChartMargin>\n className?: string\n /** Accessible label for the chart SVG */\n ariaLabel?: string\n /** Accessible description for screen readers — summarize key data points */\n ariaDescription?: string\n /** Render function receiving inner dimensions (width/height minus margins) */\n children: (dimensions: {\n width: number\n height: number\n margin: ChartMargin\n }) => React.ReactNode\n}\n\nexport const ChartContainer = React.forwardRef<HTMLDivElement, ChartContainerProps>(\n (\n {\n height = 300,\n margin: marginOverride,\n className,\n ariaLabel = 'Chart',\n ariaDescription,\n children,\n ...props\n },\n ref,\n ) => {\n const containerRef = useRef<HTMLDivElement>(null)\n const [width, setWidth] = useState(0)\n\n const margin = { ...DEFAULT_MARGIN, ...marginOverride }\n\n useEffect(() => {\n if (!containerRef.current) return\n const observer = new ResizeObserver((entries) => {\n const entry = entries[0]\n if (entry) setWidth(entry.contentRect.width)\n })\n observer.observe(containerRef.current)\n return () => observer.disconnect()\n }, [])\n\n const innerWidth = Math.max(0, width - margin.left - margin.right)\n const innerHeight = Math.max(0, height - margin.top - margin.bottom)\n\n return (\n <div\n ref={(node) => {\n (containerRef as React.MutableRefObject<HTMLDivElement | null>).current = node\n if (typeof ref === 'function') ref(node)\n else if (ref) (ref as React.MutableRefObject<HTMLDivElement | null>).current = node\n }}\n className={cn('relative w-full', className)}\n {...props}\n >\n {width > 0 && (\n <svg width={width} height={height} role=\"img\" aria-label={ariaLabel}>\n {ariaDescription && <desc>{ariaDescription}</desc>}\n <g transform={`translate(${margin.left},${margin.top})`}>\n {children({ width: innerWidth, height: innerHeight, margin })}\n </g>\n </svg>\n )}\n </div>\n )\n },\n)\nChartContainer.displayName = 'ChartContainer'\n","'use client'\n\nimport * as React from 'react'\nimport { useRef, useEffect } from 'react'\nimport { axisBottom, axisLeft, axisRight, axisTop } from 'd3-axis'\nimport { select } from 'd3-selection'\nimport type { ScaleLinear, ScaleBand, ScalePoint, ScaleTime } from 'd3-scale'\n\nexport type AnyScale =\n | ScaleLinear<number, number>\n | ScaleBand<string>\n | ScalePoint<string>\n | ScaleTime<number, number>\n\ninterface AxisProps {\n scale: AnyScale\n orientation: 'top' | 'right' | 'bottom' | 'left'\n transform?: string\n tickCount?: number\n tickFormat?: (value: unknown) => string\n label?: string\n className?: string\n}\n\nexport function Axis({\n scale,\n orientation,\n transform,\n tickCount,\n tickFormat,\n label,\n className,\n}: AxisProps) {\n const ref = useRef<SVGGElement>(null)\n\n useEffect(() => {\n if (!ref.current) return\n\n const axisFn = {\n top: axisTop,\n right: axisRight,\n bottom: axisBottom,\n left: axisLeft,\n }[orientation]\n\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n let axis = axisFn(scale as any)\n if (tickCount) axis = axis.ticks(tickCount)\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n if (tickFormat) axis = axis.tickFormat(tickFormat as any)\n\n const g = select(ref.current)\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n g.call(axis as any)\n\n // Style using design tokens\n g.selectAll('.tick line').attr('stroke', 'var(--color-surface-border)')\n g.selectAll('.tick text')\n .attr('fill', 'var(--color-surface-fg-muted)')\n .attr('font-size', 'var(--font-size-xs)')\n g.selectAll('.domain').attr('stroke', 'var(--color-surface-border-strong)')\n }, [scale, orientation, tickCount, tickFormat])\n\n const labelProps =\n orientation === 'bottom'\n ? { x: '50%', dy: 35 }\n : orientation === 'left'\n ? { transform: 'rotate(-90)', y: -40, x: 0 }\n : {}\n\n return (\n <g ref={ref} transform={transform} className={className}>\n {label && (\n <text\n textAnchor=\"middle\"\n fill=\"var(--color-surface-fg-muted)\"\n fontSize=\"var(--font-size-sm)\"\n {...labelProps}\n >\n {label}\n </text>\n )}\n </g>\n )\n}\nAxis.displayName = 'Axis'\n","import * as React from 'react'\nimport type { ScaleLinear, ScaleTime } from 'd3-scale'\n\ntype TickableScale = ScaleLinear<number, number> | ScaleTime<number, number>\n\ninterface GridLinesProps {\n width: number\n height: number\n xScale?: TickableScale\n yScale?: TickableScale\n horizontal?: boolean\n vertical?: boolean\n}\n\nexport function GridLines({\n width,\n height,\n xScale,\n yScale,\n horizontal = true,\n vertical = false,\n}: GridLinesProps) {\n return (\n <g className=\"grid-lines\">\n {horizontal &&\n yScale?.ticks &&\n yScale.ticks().map((tick: number | Date, i: number) => (\n <line\n key={`h-${i}`}\n x1={0}\n x2={width}\n y1={yScale(tick as number)}\n y2={yScale(tick as number)}\n stroke=\"var(--color-surface-border)\"\n strokeDasharray=\"3,3\"\n opacity={0.6}\n />\n ))}\n {vertical &&\n xScale?.ticks &&\n xScale.ticks().map((tick: number | Date, i: number) => (\n <line\n key={`v-${i}`}\n x1={xScale(tick as number)}\n x2={xScale(tick as number)}\n y1={0}\n y2={height}\n stroke=\"var(--color-surface-border)\"\n strokeDasharray=\"3,3\"\n opacity={0.6}\n />\n ))}\n </g>\n )\n}\nGridLines.displayName = 'GridLines'\n","import * as React from 'react'\nimport { cn } from '../../lib/utils'\n\ninterface LegendItem {\n label: string\n color: string // CSS color value or var() reference\n}\n\ninterface LegendProps {\n items: LegendItem[]\n position?: 'top' | 'bottom' | 'left' | 'right'\n className?: string\n}\n\nexport function Legend({ items, position = 'bottom', className }: LegendProps) {\n const isVertical = position === 'left' || position === 'right'\n\n return (\n <div\n className={cn(\n 'flex gap-ds-04 text-ds-sm text-surface-fg-muted',\n isVertical ? 'flex-col' : 'flex-row flex-wrap justify-center',\n className,\n )}\n >\n {items.map((item) => (\n <div key={item.label} className=\"flex items-center gap-ds-02\">\n <span\n className=\"inline-block h-3 w-3 shrink-0 rounded-ds-sm\"\n style={{ backgroundColor: item.color }}\n />\n <span>{item.label}</span>\n </div>\n ))}\n </div>\n )\n}\nLegend.displayName = 'Legend'\n\nexport type { LegendItem, LegendProps }\n","'use client'\n\nimport * as React from 'react'\nimport { useState, useCallback } from 'react'\nimport { cn } from '../../lib/utils'\n\ninterface TooltipState {\n visible: boolean\n x: number\n y: number\n content: React.ReactNode\n}\n\ninterface ChartTooltipProps {\n state: TooltipState\n className?: string\n}\n\nexport function ChartTooltip({ state, className }: ChartTooltipProps) {\n if (!state.visible) return null\n\n return (\n <div\n className={cn(\n 'pointer-events-none absolute z-tooltip',\n 'rounded-ds-md border border-surface-border-strong',\n 'bg-surface-overlay px-ds-03 py-ds-02',\n 'shadow-raised-hover',\n 'text-ds-sm text-surface-fg',\n className,\n )}\n style={{ left: state.x + 12, top: state.y - 12 }}\n >\n {state.content}\n </div>\n )\n}\nChartTooltip.displayName = 'ChartTooltip'\n\n/** Hook to manage chart tooltip state */\nexport function useChartTooltip() {\n const [tooltip, setTooltip] = useState<TooltipState>({\n visible: false,\n x: 0,\n y: 0,\n content: null,\n })\n\n const show = useCallback((x: number, y: number, content: React.ReactNode) => {\n setTooltip({ visible: true, x, y, content })\n }, [])\n\n const hide = useCallback(() => {\n setTooltip((prev) => ({ ...prev, visible: false }))\n }, [])\n\n return { tooltip, show, hide }\n}\n\nexport type { TooltipState, ChartTooltipProps }\n","import type { ChartColor } from './types'\n\nconst CHART_COLORS: ChartColor[] = [\n 'chart-1',\n 'chart-2',\n 'chart-3',\n 'chart-4',\n 'chart-5',\n 'chart-6',\n 'chart-7',\n 'chart-8',\n]\n\n/** Get CSS variable reference for a chart color token */\nexport function getChartColor(color: ChartColor): string {\n return `var(--${color})`\n}\n\n/** Get an array of chart color CSS variable references, cycling if needed */\nexport function getChartColors(count: number): string[] {\n return Array.from({ length: count }, (_, i) =>\n getChartColor(CHART_COLORS[i % CHART_COLORS.length]),\n )\n}\n\n/** Resolve a color prop — if it's a ChartColor token name, convert to var(); otherwise pass through */\nexport function resolveColor(color: string | ChartColor | undefined, index: number = 0): string {\n if (!color) return getChartColor(CHART_COLORS[index % CHART_COLORS.length])\n if ((CHART_COLORS as string[]).includes(color)) return getChartColor(color as ChartColor)\n return color // pass through raw CSS color\n}\n","'use client'\n\nimport { useMotion } from '../../../motion/motion-provider'\n\n/** Hook to detect reduced-motion preference via MotionProvider context */\nexport function useReducedMotion(): boolean {\n const { reducedMotion } = useMotion()\n return reducedMotion\n}\n\n/** Get transition duration respecting reduced motion preference */\nexport function getTransitionDuration(reducedMotion: boolean, duration = 300): number {\n return reducedMotion ? 0 : duration\n}\n","'use client'\n\nimport * as React from 'react'\nimport { motion } from 'framer-motion'\nimport { scaleBand, scaleLinear } from 'd3-scale'\nimport { cn } from '../lib/utils'\nimport { tweens, motionProps } from '../lib/motion'\nimport { ChartContainer } from './chart-container'\nimport { Axis } from './_internal/axes'\nimport { GridLines } from './_internal/grid-lines'\nimport { Legend } from './_internal/legend'\nimport { ChartTooltip, useChartTooltip } from './_internal/tooltip'\nimport { resolveColor } from './_internal/colors'\nimport { useReducedMotion } from './_internal/animation'\nimport type { DataPoint, ChartColor } from './_internal/types'\n\nexport interface BarChartProps extends Omit<React.HTMLAttributes<HTMLDivElement>, 'children' | 'color'> {\n /** Data array */\n data: DataPoint[]\n /** Key for x-axis categories */\n xKey: string\n /** Key(s) for y-axis values. String for single series, array for multi-series */\n yKey: string | string[]\n /** Bar orientation */\n orientation?: 'vertical' | 'horizontal'\n /** Stack multiple series */\n stacked?: boolean\n /** Group multiple series side by side */\n grouped?: boolean\n /** Color(s) for bars */\n color?: ChartColor | ChartColor[] | string | string[]\n /** Chart height in pixels */\n height?: number\n /** Show background grid lines */\n showGrid?: boolean\n /** Show tooltip on hover */\n showTooltip?: boolean\n /** Show legend (only for multi-series) */\n showLegend?: boolean\n /** Animate bars on mount */\n animate?: boolean\n /** Bar corner radius */\n barRadius?: number\n /** X-axis label */\n xLabel?: string\n /** Y-axis label */\n yLabel?: string\n /** Series labels (for legend) */\n seriesLabels?: string[]\n /** Accessible label for the chart */\n ariaLabel?: string\n className?: string\n}\n\nexport const BarChart = React.forwardRef<HTMLDivElement, BarChartProps>(\n (\n {\n data,\n xKey,\n yKey,\n orientation = 'vertical',\n stacked = false,\n grouped = false,\n color,\n height = 300,\n showGrid = true,\n showTooltip = true,\n showLegend = false,\n animate = true,\n barRadius = 4,\n xLabel,\n yLabel,\n seriesLabels,\n ariaLabel,\n className,\n ...props\n },\n ref,\n ) => {\n const { tooltip, show, hide } = useChartTooltip()\n const reducedMotion = useReducedMotion()\n const isVertical = orientation === 'vertical'\n const shouldAnimate = animate && !reducedMotion\n\n // Normalize yKey to array\n const yKeys = Array.isArray(yKey) ? yKey : [yKey]\n const isMultiSeries = yKeys.length > 1\n\n // Resolve colors\n const colors = isMultiSeries\n ? yKeys.map((_, i) =>\n resolveColor(\n Array.isArray(color) ? color[i] : typeof color === 'string' ? color : undefined,\n i,\n ),\n )\n : [\n resolveColor(\n typeof color === 'string'\n ? color\n : Array.isArray(color)\n ? color[0]\n : undefined,\n 0,\n ),\n ]\n\n return (\n <motion.div\n ref={ref}\n className={cn('relative', className)}\n {...(shouldAnimate\n ? { initial: { opacity: 0, scale: 0.96 }, animate: { opacity: 1, scale: 1 }, transition: tweens.fade }\n : {})}\n {...motionProps(props)}\n >\n <ChartContainer height={height} ariaLabel={ariaLabel ?? 'Bar chart'}>\n {({ width, height: innerHeight, margin }) => {\n // Suppress unused-var lint for margin (available for extensions)\n void margin\n\n // Category labels\n const categories = data.map((d) => String(d[xKey]))\n\n // Build data summary for screen readers\n const dataSummary = data.map((d) => {\n const cat = String(d[xKey])\n const vals = yKeys.map((k, i) => {\n const lbl = seriesLabels?.[i] ?? k\n return `${lbl}: ${Number(d[k]).toLocaleString()}`\n }).join(', ')\n return `${cat} — ${vals}`\n }).join('. ')\n\n // Calculate max value\n let maxValue: number\n if (stacked) {\n maxValue = Math.max(\n ...data.map((d) =>\n yKeys.reduce((sum, k) => sum + (Number(d[k]) || 0), 0),\n ),\n )\n } else {\n maxValue = Math.max(\n ...data.flatMap((d) => yKeys.map((k) => Number(d[k]) || 0)),\n )\n }\n\n // Build scales\n const categoryScale = scaleBand()\n .domain(categories)\n .range(isVertical ? [0, width] : [0, innerHeight])\n .padding(0.2)\n\n const valueScale = scaleLinear()\n .domain([0, maxValue * 1.1])\n .range(isVertical ? [innerHeight, 0] : [0, width])\n .nice()\n\n const barBandwidth = categoryScale.bandwidth()\n const barWidth =\n isMultiSeries && grouped\n ? barBandwidth / yKeys.length\n : barBandwidth\n\n return (\n <>\n {/* Screen-reader data summary */}\n <desc>{dataSummary}</desc>\n\n {/* Grid */}\n {showGrid && (\n <GridLines\n width={width}\n height={innerHeight}\n yScale={isVertical ? valueScale : undefined}\n xScale={!isVertical ? valueScale : undefined}\n horizontal={isVertical}\n vertical={!isVertical}\n />\n )}\n\n {/* Bars */}\n {data.map((d) => {\n const category = String(d[xKey])\n let stackOffset = 0\n\n return yKeys.map((key, seriesIdx) => {\n const value = Number(d[key]) || 0\n const barColor = colors[seriesIdx] || colors[0]\n\n let x: number, y: number, w: number, h: number\n\n if (isVertical) {\n x =\n (categoryScale(category) ?? 0) +\n (grouped && isMultiSeries ? seriesIdx * barWidth : 0)\n y = stacked\n ? valueScale(stackOffset + value)\n : valueScale(value)\n w = barWidth\n h = stacked\n ? valueScale(stackOffset) - valueScale(stackOffset + value)\n : innerHeight - valueScale(value)\n } else {\n x = stacked ? valueScale(stackOffset) : 0\n y =\n (categoryScale(category) ?? 0) +\n (grouped && isMultiSeries ? seriesIdx * barWidth : 0)\n w = stacked\n ? valueScale(stackOffset + value) - valueScale(stackOffset)\n : valueScale(value)\n h = barWidth\n }\n\n if (stacked) stackOffset += value\n\n const seriesLabel = seriesLabels?.[seriesIdx] ?? key\n const barAriaLabel = isMultiSeries\n ? `${category}, ${seriesLabel}: ${value.toLocaleString()}`\n : `${category}: ${value.toLocaleString()}`\n\n const tooltipContent = (\n <div>\n <div className=\"font-medium\">{category}</div>\n {isMultiSeries && (\n <div className=\"text-surface-fg-muted\">\n {seriesLabel}\n </div>\n )}\n <div>{value.toLocaleString()}</div>\n </div>\n )\n\n return (\n <rect\n key={`${category}-${key}`}\n x={x}\n y={y}\n width={Math.max(0, w)}\n height={Math.max(0, h)}\n rx={barRadius}\n fill={barColor}\n className=\"transition-opacity hover:opacity-80 focus-visible:outline-hidden focus-visible:opacity-80\"\n tabIndex={showTooltip ? 0 : undefined}\n role={showTooltip ? 'graphics-symbol' : undefined}\n aria-label={barAriaLabel}\n onMouseMove={(e) => {\n if (showTooltip) {\n const rect = e.currentTarget\n .closest('div')\n ?.getBoundingClientRect()\n show(\n e.clientX - (rect?.left ?? 0),\n e.clientY - (rect?.top ?? 0),\n tooltipContent,\n )\n }\n }}\n onMouseLeave={hide}\n onFocus={(e) => {\n if (showTooltip) {\n const svgRect = e.currentTarget\n .closest('div')\n ?.getBoundingClientRect()\n const barRect = e.currentTarget.getBoundingClientRect()\n show(\n barRect.left + barRect.width / 2 - (svgRect?.left ?? 0),\n barRect.top - (svgRect?.top ?? 0),\n tooltipContent,\n )\n }\n }}\n onBlur={hide}\n />\n )\n })\n })}\n\n {/* Axes */}\n {isVertical ? (\n <>\n <Axis\n scale={categoryScale}\n orientation=\"bottom\"\n transform={`translate(0,${innerHeight})`}\n label={xLabel}\n />\n <Axis scale={valueScale} orientation=\"left\" label={yLabel} />\n </>\n ) : (\n <>\n <Axis\n scale={valueScale}\n orientation=\"bottom\"\n transform={`translate(0,${innerHeight})`}\n label={xLabel}\n />\n <Axis\n scale={categoryScale}\n orientation=\"left\"\n label={yLabel}\n />\n </>\n )}\n </>\n )\n }}\n </ChartContainer>\n\n {/* Tooltip overlay */}\n {showTooltip && <ChartTooltip state={tooltip} />}\n\n {/* Legend */}\n {showLegend && isMultiSeries && (\n <Legend\n items={yKeys.map((key, i) => ({\n label: seriesLabels?.[i] ?? key,\n color: colors[i],\n }))}\n className=\"mt-ds-04\"\n />\n )}\n </motion.div>\n )\n },\n)\nBarChart.displayName = 'BarChart'\n","'use client'\n\nimport * as React from 'react'\nimport { motion } from 'framer-motion'\nimport { line, curveMonotoneX, curveLinear } from 'd3-shape'\nimport { scaleLinear, scalePoint } from 'd3-scale'\nimport type { ScaleLinear, ScalePoint } from 'd3-scale'\nimport { cn } from '../lib/utils'\nimport { tweens, motionProps } from '../lib/motion'\nimport { ChartContainer } from './chart-container'\nimport { Axis, type AnyScale } from './_internal/axes'\nimport { GridLines } from './_internal/grid-lines'\nimport { Legend } from './_internal/legend'\nimport { ChartTooltip, useChartTooltip } from './_internal/tooltip'\nimport { resolveColor } from './_internal/colors'\nimport { useReducedMotion } from './_internal/animation'\nimport type { DataPoint, Series } from './_internal/types'\n\nexport interface LineChartProps extends Omit<React.HTMLAttributes<HTMLDivElement>, 'children'> {\n /** Data array */\n data: DataPoint[]\n /** Key for x-axis */\n xKey: string\n /** Series definitions — each becomes a line */\n series: Series[]\n /** Use curved (monotone) interpolation */\n curved?: boolean\n /** Show dots at data points */\n showDots?: boolean\n /** Dot radius */\n dotSize?: number\n /** Line stroke width */\n strokeWidth?: number\n /** Chart height */\n height?: number\n /** Show grid lines */\n showGrid?: boolean\n /** Show tooltip on hover */\n showTooltip?: boolean\n /** Show legend */\n showLegend?: boolean\n /** Animate on mount */\n animate?: boolean\n /** X-axis label */\n xLabel?: string\n /** Y-axis label */\n yLabel?: string\n /** Accessible label for the chart */\n ariaLabel?: string\n className?: string\n}\n\nexport const LineChart = React.forwardRef<HTMLDivElement, LineChartProps>(\n (\n {\n data,\n xKey,\n series,\n curved = false,\n showDots = false,\n dotSize = 4,\n strokeWidth = 2,\n height = 300,\n showGrid = true,\n showTooltip = true,\n showLegend = false,\n animate = true,\n xLabel,\n yLabel,\n ariaLabel,\n className,\n ...props\n },\n ref,\n ) => {\n const { tooltip, show, hide } = useChartTooltip()\n const reducedMotion = useReducedMotion()\n const shouldAnimate = animate && !reducedMotion\n\n // Resolve colors for each series\n const colors = series.map((s, i) => resolveColor(s.color, i))\n\n return (\n <motion.div\n ref={ref}\n className={cn('relative', className)}\n {...(shouldAnimate\n ? { initial: { opacity: 0, scale: 0.96 }, animate: { opacity: 1, scale: 1 }, transition: tweens.fade }\n : {})}\n {...motionProps(props)}\n >\n <ChartContainer height={height} ariaLabel={ariaLabel ?? 'Line chart'}>\n {({ width, height: innerHeight, margin }) => {\n void margin\n\n // Determine if x-axis data is numeric or categorical\n const xValues = data.map((d) => d[xKey])\n const isNumericX = xValues.every((v) => typeof v === 'number')\n\n // Build x scale and accessor\n let xAxisScale: ScaleLinear<number, number> | ScalePoint<string>\n let getX: (d: DataPoint) => number\n\n if (isNumericX) {\n const numericValues = xValues as number[]\n const xMin = Math.min(...numericValues)\n const xMax = Math.max(...numericValues)\n const linearX = scaleLinear<number, number>()\n .domain([xMin, xMax])\n .range([0, width])\n xAxisScale = linearX\n getX = (d: DataPoint) => linearX(Number(d[xKey]))\n } else {\n const categories = xValues.map(String)\n const pointX = scalePoint<string>()\n .domain(categories)\n .range([0, width])\n .padding(0.5)\n xAxisScale = pointX\n getX = (d: DataPoint) => pointX(String(d[xKey])) ?? 0\n }\n\n // Build y scale across all series\n const allValues = data.flatMap((d) =>\n series.map((s) => Number(d[s.key]) || 0),\n )\n const yMax = Math.max(...allValues)\n const yScale = scaleLinear<number, number>()\n .domain([0, yMax * 1.1])\n .range([innerHeight, 0])\n .nice()\n\n // Line generator\n const curveType = curved ? curveMonotoneX : curveLinear\n const lineGen = line<DataPoint>()\n .curve(curveType)\n .defined((d) => d !== undefined && d !== null)\n\n // Build data summary for screen readers\n const dataSummary = data.map((d) => {\n const xVal = String(d[xKey])\n const vals = series.map((s) =>\n `${s.label}: ${Number(d[s.key]).toLocaleString()}`\n ).join(', ')\n return `${xVal} — ${vals}`\n }).join('. ')\n\n return (\n <>\n {/* Screen-reader data summary */}\n <desc>{dataSummary}</desc>\n\n {/* Grid */}\n {showGrid && (\n <GridLines\n width={width}\n height={innerHeight}\n yScale={yScale}\n horizontal\n />\n )}\n\n {/* Lines */}\n {series.map((s, seriesIdx) => {\n const pathGen = lineGen\n .x((d) => getX(d))\n .y((d) => yScale(Number(d[s.key]) || 0))\n\n const pathD = pathGen(data) ?? ''\n\n return (\n <g key={s.key}>\n {/* Line path */}\n <path\n d={pathD}\n fill=\"none\"\n stroke={colors[seriesIdx]}\n strokeWidth={strokeWidth}\n strokeLinejoin=\"round\"\n strokeLinecap=\"round\"\n />\n\n {/* Data point dots */}\n {showDots &&\n data.map((d, i) => {\n const cx = getX(d)\n const cy = yScale(Number(d[s.key]) || 0)\n return (\n <circle\n key={`${s.key}-dot-${i}`}\n cx={cx}\n cy={cy}\n r={dotSize}\n fill={colors[seriesIdx]}\n className=\"transition-opacity hover:opacity-80\"\n />\n )\n })}\n </g>\n )\n })}\n\n {/* Invisible hover/focus rectangles for tooltip */}\n {showTooltip &&\n data.map((d, i) => {\n const cx = getX(d)\n const sliceWidth = width / Math.max(data.length - 1, 1)\n const xVal = String(d[xKey])\n const pointAriaLabel = `${xVal}: ${series.map((s) => `${s.label} ${Number(d[s.key]).toLocaleString()}`).join(', ')}`\n\n const tooltipContent = (\n <div>\n <div className=\"font-medium\">{xVal}</div>\n {series.map((s, sIdx) => (\n <div\n key={s.key}\n className=\"flex items-center gap-ds-02\"\n >\n <span\n className=\"inline-block h-2 w-2 rounded-ds-full\"\n style={{ backgroundColor: colors[sIdx] }}\n />\n <span className=\"text-surface-fg-muted\">\n {s.label}:\n </span>{' '}\n {Number(d[s.key]).toLocaleString()}\n </div>\n ))}\n </div>\n )\n\n return (\n <rect\n key={`hover-${i}`}\n x={cx - sliceWidth / 2}\n y={0}\n width={sliceWidth}\n height={innerHeight}\n fill=\"transparent\"\n tabIndex={0}\n role=\"graphics-symbol\"\n aria-label={pointAriaLabel}\n className=\"focus-visible:outline-hidden\"\n onMouseMove={(e) => {\n const rect = e.currentTarget\n .closest('div')\n ?.getBoundingClientRect()\n show(\n e.clientX - (rect?.left ?? 0),\n e.clientY - (rect?.top ?? 0),\n tooltipContent,\n )\n }}\n onMouseLeave={hide}\n onFocus={(e) => {\n const svgRect = e.currentTarget\n .closest('div')\n ?.getBoundingClientRect()\n const sliceRect = e.currentTarget.getBoundingClientRect()\n show(\n sliceRect.left + sliceRect.width / 2 - (svgRect?.left ?? 0),\n sliceRect.top + sliceRect.height / 2 - (svgRect?.top ?? 0),\n tooltipContent,\n )\n }}\n onBlur={hide}\n />\n )\n })}\n\n {/* Axes */}\n <Axis\n scale={xAxisScale as AnyScale}\n orientation=\"bottom\"\n transform={`translate(0,${innerHeight})`}\n label={xLabel}\n />\n <Axis scale={yScale} orientation=\"left\" label={yLabel} />\n </>\n )\n }}\n </ChartContainer>\n\n {/* Tooltip overlay */}\n {showTooltip && <ChartTooltip state={tooltip} />}\n\n {/* Legend */}\n {showLegend && series.length > 1 && (\n <Legend\n items={series.map((s, i) => ({\n label: s.label,\n color: colors[i],\n }))}\n className=\"mt-ds-04\"\n />\n )}\n </motion.div>\n )\n },\n)\nLineChart.displayName = 'LineChart'\n","'use client'\n\nimport * as React from 'react'\nimport { motion } from 'framer-motion'\nimport {\n area,\n line,\n stack,\n stackOrderNone,\n stackOffsetNone,\n curveMonotoneX,\n curveLinear,\n} from 'd3-shape'\nimport { scaleLinear, scalePoint } from 'd3-scale'\nimport type { ScaleLinear, ScalePoint } from 'd3-scale'\nimport { cn } from '../lib/utils'\nimport { tweens, motionProps } from '../lib/motion'\nimport { ChartContainer } from './chart-container'\nimport { Axis, type AnyScale } from './_internal/axes'\nimport { GridLines } from './_internal/grid-lines'\nimport { Legend } from './_internal/legend'\nimport { ChartTooltip, useChartTooltip } from './_internal/tooltip'\nimport { resolveColor } from './_internal/colors'\nimport { useReducedMotion } from './_internal/animation'\nimport type { DataPoint, Series } from './_internal/types'\n\nexport interface AreaChartProps extends Omit<React.HTMLAttributes<HTMLDivElement>, 'children'> {\n /** Data array */\n data: DataPoint[]\n /** Key for x-axis */\n xKey: string\n /** Series definitions — each becomes an area */\n series: Series[]\n /** Use curved (monotone) interpolation */\n curved?: boolean\n /** Stack areas on top of each other */\n stacked?: boolean\n /** Fill opacity for area shapes */\n fillOpacity?: number\n /** Use vertical gradient fill */\n gradient?: boolean\n /** Stroke width for area outline */\n strokeWidth?: number\n /** Chart height */\n height?: number\n /** Show grid lines */\n showGrid?: boolean\n /** Show tooltip on hover */\n showTooltip?: boolean\n /** Show legend */\n showLegend?: boolean\n /** Animate on mount */\n animate?: boolean\n /** X-axis label */\n xLabel?: string\n /** Y-axis label */\n yLabel?: string\n /** Accessible label for the chart */\n ariaLabel?: string\n className?: string\n}\n\n/** Type for rows fed to d3 stack — all numeric except the xKey */\ninterface StackableRow {\n [key: string]: number | string\n}\n\nexport const AreaChart = React.forwardRef<HTMLDivElement, AreaChartProps>(\n (\n {\n data,\n xKey,\n series,\n curved = false,\n stacked = false,\n fillOpacity = 0.3,\n gradient = false,\n strokeWidth = 2,\n height = 300,\n showGrid = true,\n showTooltip = true,\n showLegend = false,\n animate = true,\n xLabel,\n yLabel,\n ariaLabel,\n className,\n ...props\n },\n ref,\n ) => {\n const { tooltip, show, hide } = useChartTooltip()\n const reducedMotion = useReducedMotion()\n const shouldAnimate = animate && !reducedMotion\n\n // Resolve colors for each series\n const colors = series.map((s, i) => resolveColor(s.color, i))\n\n // Stable unique ID for gradient definitions\n const chartId = React.useId()\n\n return (\n <motion.div\n ref={ref}\n className={cn('relative', className)}\n {...(shouldAnimate\n ? { initial: { opacity: 0, scale: 0.96 }, animate: { opacity: 1, scale: 1 }, transition: tweens.fade }\n : {})}\n {...motionProps(props)}\n >\n <ChartContainer height={height} ariaLabel={ariaLabel ?? 'Area chart'}>\n {({ width, height: innerHeight, margin }) => {\n void margin\n\n // Determine if x-axis data is numeric or categorical\n const xValues = data.map((d) => d[xKey])\n const isNumericX = xValues.every((v) => typeof v === 'number')\n\n // Build x scale and accessor\n let xAxisScale: ScaleLinear<number, number> | ScalePoint<string>\n let getX: (d: DataPoint) => number\n let getXByIndex: (i: number) => number\n\n if (isNumericX) {\n const numericValues = xValues as number[]\n const xMin = Math.min(...numericValues)\n const xMax = Math.max(...numericValues)\n const linearX = scaleLinear<number, number>()\n .domain([xMin, xMax])\n .range([0, width])\n xAxisScale = linearX\n getX = (d: DataPoint) => linearX(Number(d[xKey]))\n getXByIndex = (i: number) => linearX(Number(data[i][xKey]))\n } else {\n const categories = xValues.map(String)\n const pointX = scalePoint<string>()\n .domain(categories)\n .range([0, width])\n .padding(0.5)\n xAxisScale = pointX\n getX = (d: DataPoint) => pointX(String(d[xKey])) ?? 0\n getXByIndex = (i: number) => pointX(String(data[i][xKey])) ?? 0\n }\n\n // Build y scale\n let yMax: number\n if (stacked) {\n yMax = Math.max(\n ...data.map((d) =>\n series.reduce((sum, s) => sum + (Number(d[s.key]) || 0), 0),\n ),\n )\n } else {\n yMax = Math.max(\n ...data.flatMap((d) =>\n series.map((s) => Number(d[s.key]) || 0),\n ),\n )\n }\n\n const yScale = scaleLinear<number, number>()\n .domain([0, yMax * 1.1])\n .range([innerHeight, 0])\n .nice()\n\n const curveType = curved ? curveMonotoneX : curveLinear\n\n // Shared tooltip render function\n const renderTooltipZones = () =>\n data.map((d, i) => {\n const cx = getX(d)\n const sliceWidth = width / Math.max(data.length - 1, 1)\n return (\n <rect\n key={`hover-${i}`}\n x={cx - sliceWidth / 2}\n y={0}\n width={sliceWidth}\n height={innerHeight}\n fill=\"transparent\"\n onMouseMove={(e) => {\n const rect = e.currentTarget\n .closest('div')\n ?.getBoundingClientRect()\n show(\n e.clientX - (rect?.left ?? 0),\n e.clientY - (rect?.top ?? 0),\n <div>\n <div className=\"font-medium\">\n {String(d[xKey])}\n </div>\n {series.map((s, sIdx) => (\n <div\n key={s.key}\n className=\"flex items-center gap-ds-02\"\n >\n <span\n className=\"inline-block h-2 w-2 rounded-ds-full\"\n style={{ backgroundColor: colors[sIdx] }}\n />\n <span className=\"text-surface-fg-muted\">\n {s.label}:\n </span>{' '}\n {Number(d[s.key]).toLocaleString()}\n </div>\n ))}\n </div>,\n )\n }}\n onMouseLeave={hide}\n />\n )\n })\n\n // Shared gradient definitions\n const renderGradientDefs = () =>\n gradient ? (\n <defs>\n {series.map((_, sIdx) => (\n <linearGradient\n key={`grad-${sIdx}`}\n id={`${chartId}-gradient-${sIdx}`}\n x1=\"0\"\n y1=\"0\"\n x2=\"0\"\n y2=\"1\"\n >\n <stop\n offset=\"0%\"\n stopColor={colors[sIdx]}\n stopOpacity={fillOpacity}\n />\n <stop\n offset=\"100%\"\n stopColor={colors[sIdx]}\n stopOpacity={0.05}\n />\n </linearGradient>\n ))}\n </defs>\n ) : null\n\n // Shared axes\n const renderAxes = () => (\n <>\n <Axis\n scale={xAxisScale as AnyScale}\n orientation=\"bottom\"\n transform={`translate(0,${innerHeight})`}\n label={xLabel}\n />\n <Axis scale={yScale} orientation=\"left\" label={yLabel} />\n </>\n )\n\n // Stacked layout\n if (stacked) {\n const seriesKeys = series.map((s) => s.key)\n const stackGen = stack<StackableRow>()\n .keys(seriesKeys)\n .order(stackOrderNone)\n .offset(stackOffsetNone)\n\n // Coerce data to StackableRow (numeric values for series keys)\n const numericData: StackableRow[] = data.map((d) => {\n const row: StackableRow = { [xKey]: String(d[xKey]) }\n for (const s of series) {\n row[s.key] = Number(d[s.key]) || 0\n }\n return row\n })\n\n const stackedData = stackGen(numericData)\n\n const areaGen = area<[number, number]>()\n .curve(curveType)\n .x((_, i) => getXByIndex(i))\n .y0((d) => yScale(d[0]))\n .y1((d) => yScale(d[1]))\n\n const lineGen = line<[number, number]>()\n .curve(curveType)\n .x((_, i) => getXByIndex(i))\n .y((d) => yScale(d[1]))\n\n return (\n <>\n {renderGradientDefs()}\n\n {/* Grid */}\n {showGrid && (\n <GridLines\n width={width}\n height={innerHeight}\n yScale={yScale}\n horizontal\n />\n )}\n\n {/* Stacked areas (render in reverse so first series is on top) */}\n {[...stackedData].reverse().map((layer, reversedIdx) => {\n const seriesIdx = stackedData.length - 1 - reversedIdx\n const layerData = layer as unknown as [number, number][]\n const areaD = areaGen(layerData) ?? ''\n const lineD = lineGen(layerData) ?? ''\n const fillColor = gradient\n ? `url(#${chartId}-gradient-${seriesIdx})`\n : colors[seriesIdx]\n\n return (\n <g key={series[seriesIdx].key}>\n <path\n d={areaD}\n fill={fillColor}\n opacity={gradient ? 1 : fillOpacity}\n />\n <path\n d={lineD}\n fill=\"none\"\n stroke={colors[seriesIdx]}\n strokeWidth={strokeWidth}\n strokeLinejoin=\"round\"\n strokeLinecap=\"round\"\n />\n </g>\n )\n })}\n\n {/* Tooltip hover zones */}\n {showTooltip && renderTooltipZones()}\n\n {renderAxes()}\n </>\n )\n }\n\n // Non-stacked areas\n const areaGen = area<DataPoint>()\n .curve(curveType)\n .defined((d) => d !== undefined && d !== null)\n\n const lineGen = line<DataPoint>()\n .curve(curveType)\n .defined((d) => d !== undefined && d !== null)\n\n return (\n <>\n {renderGradientDefs()}\n\n {/* Grid */}\n {showGrid && (\n <GridLines\n width={width}\n height={innerHeight}\n yScale={yScale}\n horizontal\n />\n )}\n\n {/* Areas (render in reverse so first series is visually on top) */}\n {[...series].reverse().map((s, reversedIdx) => {\n const seriesIdx = series.length - 1 - reversedIdx\n\n const areaPath = areaGen\n .x((d) => getX(d))\n .y0(innerHeight)\n .y1((d) => yScale(Number(d[s.key]) || 0))\n\n const linePath = lineGen\n .x((d) => getX(d))\n .y((d) => yScale(Number(d[s.key]) || 0))\n\n const areaD = areaPath(data) ?? ''\n const lineD = linePath(data) ?? ''\n\n const fillColor = gradient\n ? `url(#${chartId}-gradient-${seriesIdx})`\n : colors[seriesIdx]\n\n return (\n <g key={s.key}>\n <path\n d={areaD}\n fill={fillColor}\n opacity={gradient ? 1 : fillOpacity}\n />\n <path\n d={lineD}\n fill=\"none\"\n stroke={colors[seriesIdx]}\n strokeWidth={strokeWidth}\n strokeLinejoin=\"round\"\n strokeLinecap=\"round\"\n />\n </g>\n )\n })}\n\n {/* Tooltip hover zones */}\n {showTooltip && renderTooltipZones()}\n\n {renderAxes()}\n </>\n )\n }}\n </ChartContainer>\n\n {/* Tooltip overlay */}\n {showTooltip && <ChartTooltip state={tooltip} />}\n\n {/* Legend */}\n {showLegend && series.length > 1 && (\n <Legend\n items={series.map((s, i) => ({\n label: s.label,\n color: colors[i],\n }))}\n className=\"mt-ds-04\"\n />\n )}\n </motion.div>\n )\n },\n)\nAreaChart.displayName = 'AreaChart'\n","'use client'\n\nimport * as React from 'react'\nimport { useState, useRef, useEffect } from 'react'\nimport { motion } from 'framer-motion'\nimport { pie as d3Pie, arc as d3Arc } from 'd3-shape'\nimport type { PieArcDatum } from 'd3-shape'\nimport { cn } from '../lib/utils'\nimport { tweens, motionProps } from '../lib/motion'\nimport { Legend } from './_internal/legend'\nimport { ChartTooltip, useChartTooltip } from './_internal/tooltip'\nimport { resolveColor } from './_internal/colors'\nimport { useReducedMotion } from './_internal/animation'\n\ninterface PieSlice {\n label: string\n value: number\n color?: string\n}\n\nexport interface PieChartProps extends Omit<React.HTMLAttributes<HTMLDivElement>, 'children'> {\n /** Data with label and value */\n data: PieSlice[]\n /** Pie or donut variant */\n variant?: 'pie' | 'donut'\n /** Inner radius ratio for donut (0-1, default 0.6) */\n innerRadius?: number\n /** Gap angle between slices in radians */\n padAngle?: number\n /** Corner radius for slice edges */\n cornerRadius?: number\n /** Chart height (and width, since pie is square) */\n height?: number\n /** Show tooltip on hover */\n showTooltip?: boolean\n /** Show legend */\n showLegend?: boolean\n /** Show percentage labels on/near slices */\n showLabels?: boolean\n /** Animate slices */\n animate?: boolean\n className?: string\n /** Content to show in center of donut */\n centerLabel?: React.ReactNode\n /** Accessible label for the chart */\n ariaLabel?: string\n}\n\nexport const PieChart = React.forwardRef<HTMLDivElement, PieChartProps>(\n (\n {\n data,\n variant = 'pie',\n innerRadius: innerRadiusRatio = 0.6,\n padAngle = 0,\n cornerRadius = 0,\n height = 300,\n showTooltip = true,\n showLegend = false,\n showLabels = false,\n animate = true,\n className,\n centerLabel,\n ariaLabel,\n ...props\n },\n ref,\n ) => {\n const containerRef = useRef<HTMLDivElement>(null)\n const [containerWidth, setContainerWidth] = useState(0)\n const [hoveredIndex, setHoveredIndex] = useState<number | null>(null)\n const { tooltip, show, hide } = useChartTooltip()\n const reducedMotion = useReducedMotion()\n const shouldAnimate = animate && !reducedMotion\n\n useEffect(() => {\n if (!containerRef.current) return\n const observer = new ResizeObserver((entries) => {\n const entry = entries[0]\n if (entry) setContainerWidth(entry.contentRect.width)\n })\n observer.observe(containerRef.current)\n return () => observer.disconnect()\n }, [])\n\n // Pie chart is square — use the smaller of width/height\n const size = containerWidth > 0 ? Math.min(containerWidth, height) : height\n const outerRadius = size / 2\n const innerR = variant === 'donut' ? outerRadius * innerRadiusRatio : 0\n\n // Resolve colors for each slice\n const colors = data.map((d, i) => resolveColor(d.color, i))\n\n // Compute total for percentages\n const total = data.reduce((sum, d) => sum + d.value, 0)\n\n // D3 pie layout\n const pieLayout = d3Pie<PieSlice>()\n .value((d) => d.value)\n .padAngle(padAngle)\n .sort(null)\n\n const arcs = pieLayout(data)\n\n // D3 arc generator\n const arcGenerator = d3Arc<PieArcDatum<PieSlice>>()\n .innerRadius(innerR)\n .outerRadius(outerRadius - 2) // slight inset so hover offset doesn't clip\n .cornerRadius(cornerRadius)\n\n // Label arc — position labels at 70% of the way from inner to outer radius\n const labelRadius = innerR + (outerRadius - 2 - innerR) * 0.7\n const labelArc = d3Arc<PieArcDatum<PieSlice>>()\n .innerRadius(labelRadius)\n .outerRadius(labelRadius)\n\n return (\n <motion.div\n ref={(node) => {\n (containerRef as React.MutableRefObject<HTMLDivElement | null>).current = node\n if (typeof ref === 'function') ref(node)\n else if (ref) (ref as React.MutableRefObject<HTMLDivElement | null>).current = node\n }}\n className={cn('relative w-full', className)}\n {...(shouldAnimate\n ? { initial: { opacity: 0, scale: 0.96 }, animate: { opacity: 1, scale: 1 }, transition: tweens.fade }\n : {})}\n {...motionProps(props)}\n >\n {containerWidth > 0 && (\n <>\n <svg\n width={containerWidth}\n height={height}\n role=\"img\"\n aria-label={ariaLabel ?? 'Pie chart'}\n >\n <g transform={`translate(${containerWidth / 2},${height / 2})`}>\n {arcs.map((d, i) => {\n const path = arcGenerator(d)\n if (!path) return null\n\n // Hover offset: push slice outward along its centroid angle\n const [cx, cy] = arcGenerator.centroid(d)\n const angle = Math.atan2(cy, cx)\n const offsetX = Math.cos(angle) * 4\n const offsetY = Math.sin(angle) * 4\n const isHovered = hoveredIndex === i\n\n return (\n <path\n key={`slice-${d.data.label}-${i}`}\n d={path}\n fill={colors[i]}\n className=\"cursor-pointer transition-transform\"\n style={{\n transform: isHovered\n ? `translate(${offsetX}px, ${offsetY}px)`\n : undefined,\n }}\n onMouseEnter={() => setHoveredIndex(i)}\n onMouseMove={(e) => {\n if (showTooltip) {\n const rect = e.currentTarget\n .closest('div')\n ?.getBoundingClientRect()\n const pct =\n total > 0\n ? ((d.data.value / total) * 100).toFixed(1)\n : '0'\n show(\n e.clientX - (rect?.left ?? 0),\n e.clientY - (rect?.top ?? 0),\n <div>\n <div className=\"font-medium\">{d.data.label}</div>\n <div>\n {d.data.value.toLocaleString()} ({pct}%)\n </div>\n </div>,\n )\n }\n }}\n onMouseLeave={() => {\n setHoveredIndex(null)\n hide()\n }}\n />\n )\n })}\n\n {/* Percentage labels */}\n {showLabels &&\n arcs.map((d, i) => {\n const [lx, ly] = labelArc.centroid(d)\n const pct =\n total > 0\n ? ((d.data.value / total) * 100).toFixed(0)\n : '0'\n\n // Skip tiny slices (< 3%) to avoid label overlap\n if (total > 0 && d.data.value / total < 0.03) return null\n\n return (\n <text\n key={`label-${d.data.label}-${i}`}\n x={lx}\n y={ly}\n textAnchor=\"middle\"\n dominantBaseline=\"central\"\n className=\"pointer-events-none fill-accent-fg text-ds-xs font-medium\"\n >\n {pct}%\n </text>\n )\n })}\n\n {/* Center label for donut variant */}\n {variant === 'donut' && centerLabel && innerR > 0 && (\n <foreignObject\n x={-innerR * 0.7}\n y={-innerR * 0.7}\n width={innerR * 1.4}\n height={innerR * 1.4}\n >\n <div className=\"flex h-full w-full items-center justify-center text-center text-surface-fg\">\n {centerLabel}\n </div>\n </foreignObject>\n )}\n </g>\n </svg>\n\n {/* Tooltip overlay */}\n {showTooltip && <ChartTooltip state={tooltip} />}\n </>\n )}\n\n {/* Legend */}\n {showLegend && (\n <Legend\n items={data.map((d, i) => ({\n label: d.label,\n color: colors[i],\n }))}\n className=\"mt-ds-04\"\n />\n )}\n </motion.div>\n )\n },\n)\nPieChart.displayName = 'PieChart'\n","'use client'\n\nimport * as React from 'react'\nimport { motion } from 'framer-motion'\nimport { line, area, curveMonotoneX } from 'd3-shape'\nimport { scaleLinear } from 'd3-scale'\nimport { cn } from '../lib/utils'\nimport { resolveColor } from './_internal/colors'\nimport { useReducedMotion } from './_internal/animation'\n\nexport interface SparklineProps extends Omit<React.SVGAttributes<SVGSVGElement>, 'children'> {\n /** Numeric data points */\n data: number[]\n /** Visual variant */\n variant?: 'line' | 'bar' | 'area'\n /** Width (default: 120) */\n width?: number\n /** Height (default: 32) */\n height?: number\n /** Color token or CSS color */\n color?: string\n /** Show a dot on the last data point (line/area only) */\n showLastDot?: boolean\n /** Line stroke width (line/area only, default: 1.5) */\n strokeWidth?: number\n /** Animate on mount (default: true) */\n animate?: boolean\n className?: string\n}\n\nconst pathDrawTransition = { duration: 1, ease: 'easeOut' as const }\n\nexport const Sparkline = React.forwardRef<SVGSVGElement, SparklineProps>(\n (\n {\n data,\n variant = 'line',\n width = 120,\n height = 32,\n color,\n showLastDot = false,\n strokeWidth = 1.5,\n animate = true,\n className,\n ...props\n },\n ref,\n ) => {\n const resolvedColor = resolveColor(color, 0)\n const reducedMotion = useReducedMotion()\n const shouldAnimate = animate && !reducedMotion\n\n if (!data.length) return null\n\n const padding = variant === 'bar' ? 1 : strokeWidth\n const innerWidth = width - padding * 2\n const innerHeight = height - padding * 2\n\n const xScale = scaleLinear()\n .domain([0, Math.max(data.length - 1, 1)])\n .range([padding, padding + innerWidth])\n\n const yMin = Math.min(...data)\n const yMax = Math.max(...data)\n const yDomain = yMin === yMax ? [yMin - 1, yMax + 1] : [yMin, yMax]\n\n const yScale = scaleLinear()\n .domain(yDomain)\n .range([padding + innerHeight, padding])\n\n if (variant === 'bar') {\n const barGap = 1\n const barWidth = Math.max(\n 1,\n (innerWidth - barGap * (data.length - 1)) / data.length,\n )\n // For bars, baseline is the bottom of the chart\n const baselineY = padding + innerHeight\n\n return (\n <svg\n ref={ref}\n width={width}\n height={height}\n role=\"img\"\n aria-label=\"Sparkline bar chart\"\n className={cn('inline-block align-middle', className)}\n {...props}\n >\n {data.map((value, i) => {\n const x = padding + i * (barWidth + barGap)\n const y = yScale(value)\n const barHeight = Math.max(1, baselineY - y)\n return (\n <rect\n key={i}\n x={x}\n y={y}\n width={barWidth}\n height={barHeight}\n rx={Math.min(1, barWidth / 2)}\n fill={resolvedColor}\n />\n )\n })}\n </svg>\n )\n }\n\n if (variant === 'area') {\n const areaGen = area<number>()\n .curve(curveMonotoneX)\n .x((_, i) => xScale(i))\n .y0(padding + innerHeight)\n .y1((d) => yScale(d))\n\n const lineGen = line<number>()\n .curve(curveMonotoneX)\n .x((_, i) => xScale(i))\n .y((d) => yScale(d))\n\n const areaD = areaGen(data) ?? ''\n const lineD = lineGen(data) ?? ''\n\n const lastX = xScale(data.length - 1)\n const lastY = yScale(data[data.length - 1])\n\n return (\n <svg\n ref={ref}\n width={width}\n height={height}\n role=\"img\"\n aria-label=\"Sparkline area chart\"\n className={cn('inline-block align-middle', className)}\n {...props}\n >\n <path d={areaD} fill={resolvedColor} opacity={0.2} />\n {shouldAnimate ? (\n <motion.path\n d={lineD}\n fill=\"none\"\n stroke={resolvedColor}\n strokeWidth={strokeWidth}\n strokeLinejoin=\"round\"\n strokeLinecap=\"round\"\n initial={{ pathLength: 0 }}\n animate={{ pathLength: 1 }}\n transition={pathDrawTransition}\n />\n ) : (\n <path\n d={lineD}\n fill=\"none\"\n stroke={resolvedColor}\n strokeWidth={strokeWidth}\n strokeLinejoin=\"round\"\n strokeLinecap=\"round\"\n />\n )}\n {showLastDot && (\n <circle\n cx={lastX}\n cy={lastY}\n r={strokeWidth + 1}\n fill={resolvedColor}\n />\n )}\n </svg>\n )\n }\n\n // Default: line variant\n const lineGen = line<number>()\n .curve(curveMonotoneX)\n .x((_, i) => xScale(i))\n .y((d) => yScale(d))\n\n const pathD = lineGen(data) ?? ''\n\n const lastX = xScale(data.length - 1)\n const lastY = yScale(data[data.length - 1])\n\n return (\n <svg\n ref={ref}\n width={width}\n height={height}\n role=\"img\"\n aria-label=\"Sparkline chart\"\n className={cn('inline-block align-middle', className)}\n {...props}\n >\n {shouldAnimate ? (\n <motion.path\n d={pathD}\n fill=\"none\"\n stroke={resolvedColor}\n strokeWidth={strokeWidth}\n strokeLinejoin=\"round\"\n strokeLinecap=\"round\"\n initial={{ pathLength: 0 }}\n animate={{ pathLength: 1 }}\n transition={pathDrawTransition}\n />\n ) : (\n <path\n d={pathD}\n fill=\"none\"\n stroke={resolvedColor}\n strokeWidth={strokeWidth}\n strokeLinejoin=\"round\"\n strokeLinecap=\"round\"\n />\n )}\n {showLastDot && (\n <circle\n cx={lastX}\n cy={lastY}\n r={strokeWidth + 1}\n fill={resolvedColor}\n />\n )}\n </svg>\n )\n },\n)\nSparkline.displayName = 'Sparkline'\n","'use client'\n\nimport * as React from 'react'\nimport { motion } from 'framer-motion'\nimport { arc } from 'd3-shape'\nimport { cn } from '../lib/utils'\nimport { tweens, motionProps } from '../lib/motion'\nimport { resolveColor } from './_internal/colors'\nimport { useReducedMotion, getTransitionDuration } from './_internal/animation'\n\nexport interface GaugeChartProps extends Omit<React.HTMLAttributes<HTMLDivElement>, 'children' | 'color'> {\n /** Current value */\n value: number\n /** Maximum value (default: 100) */\n max?: number\n /** Minimum value (default: 0) */\n min?: number\n /** Label below the value */\n label?: string\n /** Custom value display */\n valueLabel?: string | ((value: number) => string)\n /** Arc color */\n color?: string\n /** Track (background) color */\n trackColor?: string\n /** Chart height/width (default: 200) */\n height?: number\n /** Start angle in degrees (default: -120) */\n startAngle?: number\n /** End angle in degrees (default: 120) */\n endAngle?: number\n /** Arc thickness in pixels (default: 16) */\n thickness?: number\n /** Animate the value arc */\n animate?: boolean\n className?: string\n}\n\nconst toRad = (deg: number) => (deg * Math.PI) / 180\n\nexport const GaugeChart = React.forwardRef<HTMLDivElement, GaugeChartProps>(\n (\n {\n value,\n max = 100,\n min = 0,\n label,\n valueLabel,\n color,\n trackColor = 'var(--color-surface-border)',\n height = 200,\n startAngle = -120,\n endAngle = 120,\n thickness = 16,\n animate = true,\n className,\n ...props\n },\n ref,\n ) => {\n const reducedMotion = useReducedMotion()\n const duration = getTransitionDuration(reducedMotion, animate ? 600 : 0)\n const shouldAnimate = animate && !reducedMotion\n\n const resolvedColor = resolveColor(color, 0)\n const size = height\n const radius = size / 2\n\n // Clamp value to [min, max]\n const clampedValue = Math.min(Math.max(value, min), max)\n const valueFraction = max === min ? 0 : (clampedValue - min) / (max - min)\n const valueEndAngle = startAngle + (endAngle - startAngle) * valueFraction\n\n // Display text\n const displayValue =\n typeof valueLabel === 'function'\n ? valueLabel(clampedValue)\n : typeof valueLabel === 'string'\n ? valueLabel\n : String(clampedValue)\n\n // Track arc generator\n const trackGenerator = arc<unknown>()\n .innerRadius(radius - thickness)\n .outerRadius(radius)\n .startAngle(toRad(startAngle))\n .endAngle(toRad(endAngle))\n .cornerRadius(thickness / 2)\n\n // Value arc generator\n const valueGenerator = arc<unknown>()\n .innerRadius(radius - thickness)\n .outerRadius(radius)\n .startAngle(toRad(startAngle))\n .endAngle(toRad(valueEndAngle))\n .cornerRadius(thickness / 2)\n\n const trackPath = trackGenerator(null as unknown as Record<string, never>) ?? ''\n const valuePath = valueGenerator(null as unknown as Record<string, never>) ?? ''\n\n return (\n <motion.div\n ref={ref}\n className={cn('inline-flex flex-col items-center', className)}\n {...(shouldAnimate\n ? { initial: { opacity: 0, scale: 0.96 }, animate: { opacity: 1, scale: 1 }, transition: tweens.fade }\n : {})}\n {...motionProps(props)}\n role=\"meter\"\n aria-valuenow={clampedValue}\n aria-valuemin={min}\n aria-valuemax={max}\n aria-label={label ?? 'Gauge chart'}\n >\n <svg width={size} height={size} role=\"img\" aria-hidden=\"true\">\n <g transform={`translate(${radius},${radius})`}>\n {/* Background track */}\n <path d={trackPath} fill={trackColor} />\n\n {/* Value arc */}\n <path\n d={valuePath}\n fill={resolvedColor}\n style={\n duration > 0\n ? { transition: `d ${duration}ms ease-out` }\n : undefined\n }\n />\n\n {/* Center value text */}\n <text\n x={0}\n y={label ? -4 : 0}\n textAnchor=\"middle\"\n dominantBaseline=\"central\"\n className=\"fill-surface-fg text-ds-2xl font-semibold\"\n >\n {displayValue}\n </text>\n\n {/* Label below value */}\n {label && (\n <text\n x={0}\n y={20}\n textAnchor=\"middle\"\n dominantBaseline=\"central\"\n className=\"fill-surface-fg-muted text-ds-xs\"\n >\n {label}\n </text>\n )}\n </g>\n </svg>\n </motion.div>\n )\n },\n)\nGaugeChart.displayName = 'GaugeChart'\n","'use client'\n\nimport * as React from 'react'\nimport { useState, useRef, useEffect } from 'react'\nimport { motion } from 'framer-motion'\nimport { lineRadial, curveLinearClosed } from 'd3-shape'\nimport { cn } from '../lib/utils'\nimport { tweens, motionProps } from '../lib/motion'\nimport { Legend } from './_internal/legend'\nimport { ChartTooltip, useChartTooltip } from './_internal/tooltip'\nimport { resolveColor } from './_internal/colors'\nimport { useReducedMotion } from './_internal/animation'\n\nexport interface RadarChartProps extends Omit<React.HTMLAttributes<HTMLDivElement>, 'children'> {\n /** Data array (one entry per data point / axis) */\n data: Record<string, string | number>[]\n /** Axis labels (3-8 axes) */\n axes: string[]\n /** Series to plot */\n series: { key: string; label: string; color?: string }[]\n /** Max value (auto-detect if not set) */\n maxValue?: number\n /** Number of concentric grid rings (default: 5) */\n levels?: number\n /** Fill opacity for the data polygon (default: 0.25) */\n fillOpacity?: number\n /** Show dots at vertices */\n showDots?: boolean\n /** Chart height (default: 300) */\n height?: number\n /** Show tooltip on hover */\n showTooltip?: boolean\n /** Show legend */\n showLegend?: boolean\n /** Animate on mount */\n animate?: boolean\n /** Accessible label for the chart */\n ariaLabel?: string\n className?: string\n}\n\nexport const RadarChart = React.forwardRef<HTMLDivElement, RadarChartProps>(\n (\n {\n data,\n axes,\n series,\n maxValue: maxValueProp,\n levels = 5,\n fillOpacity = 0.25,\n showDots = false,\n height = 300,\n showTooltip = true,\n showLegend = false,\n animate = true,\n ariaLabel,\n className,\n ...props\n },\n ref,\n ) => {\n const containerRef = useRef<HTMLDivElement>(null)\n const [containerWidth, setContainerWidth] = useState(0)\n const { tooltip, show, hide } = useChartTooltip()\n const reducedMotion = useReducedMotion()\n const shouldAnimate = animate && !reducedMotion\n\n useEffect(() => {\n if (!containerRef.current) return\n const observer = new ResizeObserver((entries) => {\n const entry = entries[0]\n if (entry) setContainerWidth(entry.contentRect.width)\n })\n observer.observe(containerRef.current)\n return () => observer.disconnect()\n }, [])\n\n // Radar chart is square — use the smaller of width/height\n const svgSize = containerWidth > 0 ? Math.min(containerWidth, height) : height\n const radius = svgSize / 2 - 40 // leave room for labels\n\n // Resolve colors for each series\n const colors = series.map((s, i) => resolveColor(s.color, i))\n\n // Auto-detect maxValue if not provided\n const maxValue =\n maxValueProp ??\n Math.max(\n ...data.flatMap((d) => series.map((s) => Number(d[s.key]) || 0)),\n 1,\n )\n\n // Angle per axis slice\n const angleSlice = (2 * Math.PI) / axes.length\n\n // D3 radial line generator for the data polygon\n const radarLine = lineRadial<number>()\n .radius((d) => (radius * d) / maxValue)\n .angle((_, i) => i * angleSlice)\n .curve(curveLinearClosed)\n\n // Convert a data row into an array of values aligned with axes\n const getSeriesValues = (seriesKey: string): number[] =>\n axes.map((_, i) => Number(data[i]?.[seriesKey]) || 0)\n\n // Convert polar to cartesian for a given axis index and value\n const polarToXY = (axisIndex: number, value: number) => {\n const angle = angleSlice * axisIndex - Math.PI / 2\n const r = (radius * value) / maxValue\n return {\n x: r * Math.cos(angle),\n y: r * Math.sin(angle),\n }\n }\n\n return (\n <motion.div\n ref={(node) => {\n (containerRef as React.MutableRefObject<HTMLDivElement | null>).current = node\n if (typeof ref === 'function') ref(node)\n else if (ref) (ref as React.MutableRefObject<HTMLDivElement | null>).current = node\n }}\n className={cn('relative w-full', className)}\n {...(shouldAnimate\n ? { initial: { opacity: 0, scale: 0.96 }, animate: { opacity: 1, scale: 1 }, transition: tweens.fade }\n : {})}\n {...motionProps(props)}\n >\n {containerWidth > 0 && (\n <>\n <svg\n width={containerWidth}\n height={height}\n role=\"img\"\n aria-label={ariaLabel ?? 'Radar chart'}\n >\n <g transform={`translate(${containerWidth / 2},${height / 2})`}>\n {/* Concentric grid polygons */}\n {Array.from({ length: levels }, (_, i) => {\n const levelRadius = (radius / levels) * (i + 1)\n const points = axes\n .map((_, j) => {\n const angle = angleSlice * j - Math.PI / 2\n return `${levelRadius * Math.cos(angle)},${levelRadius * Math.sin(angle)}`\n })\n .join(' ')\n return (\n <polygon\n key={`grid-${i}`}\n points={points}\n fill=\"none\"\n stroke=\"var(--color-surface-border)\"\n strokeDasharray=\"3,3\"\n strokeWidth={1}\n />\n )\n })}\n\n {/* Axis lines from center to outer edge */}\n {axes.map((_, i) => {\n const angle = angleSlice * i - Math.PI / 2\n const x = radius * Math.cos(angle)\n const y = radius * Math.sin(angle)\n return (\n <line\n key={`axis-${i}`}\n x1={0}\n y1={0}\n x2={x}\n y2={y}\n stroke=\"var(--color-surface-border)\"\n strokeWidth={1}\n />\n )\n })}\n\n {/* Axis labels */}\n {axes.map((label, i) => {\n const angle = angleSlice * i - Math.PI / 2\n const labelRadius = radius + 18\n const x = labelRadius * Math.cos(angle)\n const y = labelRadius * Math.sin(angle)\n\n // Determine text-anchor based on position\n let textAnchor: 'start' | 'middle' | 'end' = 'middle'\n if (Math.abs(Math.cos(angle)) > 0.1) {\n textAnchor = Math.cos(angle) > 0 ? 'start' : 'end'\n }\n\n return (\n <text\n key={`label-${i}`}\n x={x}\n y={y}\n textAnchor={textAnchor}\n dominantBaseline=\"central\"\n className=\"fill-surface-fg-muted text-ds-xs\"\n >\n {label}\n </text>\n )\n })}\n\n {/* Level value labels on the first axis */}\n {Array.from({ length: levels }, (_, i) => {\n const levelValue = Math.round((maxValue / levels) * (i + 1))\n const levelRadius = (radius / levels) * (i + 1)\n const angle = -Math.PI / 2 // first axis is at top\n const x = levelRadius * Math.cos(angle) + 4\n const y = levelRadius * Math.sin(angle)\n return (\n <text\n key={`level-label-${i}`}\n x={x}\n y={y}\n textAnchor=\"start\"\n dominantBaseline=\"auto\"\n className=\"fill-surface-fg-subtle text-ds-xs\"\n >\n {levelValue}\n </text>\n )\n })}\n\n {/* Data polygons — one per series */}\n {series.map((s, seriesIdx) => {\n const values = getSeriesValues(s.key)\n const pathD = radarLine(values)\n if (!pathD) return null\n\n return (\n <g key={s.key}>\n <path\n d={pathD}\n fill={colors[seriesIdx]}\n fillOpacity={fillOpacity}\n stroke={colors[seriesIdx]}\n strokeWidth={2}\n strokeLinejoin=\"round\"\n />\n\n {/* Vertex dots */}\n {showDots &&\n values.map((v, i) => {\n const { x, y } = polarToXY(i, v)\n return (\n <circle\n key={`dot-${s.key}-${i}`}\n cx={x}\n cy={y}\n r={4}\n fill={colors[seriesIdx]}\n stroke=\"var(--color-surface-base)\"\n strokeWidth={2}\n className=\"transition-opacity\"\n />\n )\n })}\n </g>\n )\n })}\n\n {/* Invisible hover areas at each vertex for tooltips */}\n {showTooltip &&\n axes.map((axisLabel, i) => {\n // Place a transparent circle at the outermost series point\n // for hit detection. Use the max value point for the axis.\n const angle = angleSlice * i - Math.PI / 2\n const hitX = radius * Math.cos(angle)\n const hitY = radius * Math.sin(angle)\n\n return (\n <circle\n key={`hover-${i}`}\n cx={hitX}\n cy={hitY}\n r={16}\n fill=\"transparent\"\n className=\"cursor-pointer\"\n onMouseMove={(e) => {\n const rect = e.currentTarget\n .closest('div')\n ?.getBoundingClientRect()\n show(\n e.clientX - (rect?.left ?? 0),\n e.clientY - (rect?.top ?? 0),\n <div>\n <div className=\"font-medium\">{axisLabel}</div>\n {series.map((s, sIdx) => {\n const val = Number(data[i]?.[s.key]) || 0\n return (\n <div\n key={s.key}\n className=\"flex items-center gap-ds-02\"\n >\n <span\n className=\"inline-block h-2 w-2 rounded-ds-full\"\n style={{ backgroundColor: colors[sIdx] }}\n />\n <span className=\"text-surface-fg-muted\">\n {s.label}:\n </span>{' '}\n {val.toLocaleString()}\n </div>\n )\n })}\n </div>,\n )\n }}\n onMouseLeave={hide}\n />\n )\n })}\n </g>\n </svg>\n\n {/* Tooltip overlay */}\n {showTooltip && <ChartTooltip state={tooltip} />}\n </>\n )}\n\n {/* Legend */}\n {showLegend && (\n <Legend\n items={series.map((s, i) => ({\n label: s.label,\n color: colors[i],\n }))}\n className=\"mt-ds-04\"\n />\n )}\n </motion.div>\n )\n },\n)\nRadarChart.displayName = 'RadarChart'\n"],"mappings":";;;;;;;;;;;;AAOA,IAAa,IAA8B;CACzC,KAAK;CACL,OAAO;CACP,QAAQ;CACR,MAAM;CACP,ECcY,IAAiB,EAAM,YAEhC,EACE,YAAS,KACT,QAAQ,GACR,cACA,eAAY,SACZ,oBACA,aACA,GAAG,KAEL,MACG;CACL,IAAM,IAAe,EAAuB,KAAK,EAC3C,CAAC,GAAO,KAAY,EAAS,EAAE,EAE/B,IAAS;EAAE,GAAG;EAAgB,GAAG;EAAgB;AAEvD,SAAgB;AACd,MAAI,CAAC,EAAa,QAAS;EAC3B,IAAM,IAAW,IAAI,gBAAgB,MAAY;GAC/C,IAAM,IAAQ,EAAQ;AACtB,GAAI,KAAO,EAAS,EAAM,YAAY,MAAM;IAC5C;AAEF,SADA,EAAS,QAAQ,EAAa,QAAQ,QACzB,EAAS,YAAY;IACjC,EAAE,CAAC;CAEN,IAAM,IAAa,KAAK,IAAI,GAAG,IAAQ,EAAO,OAAO,EAAO,MAAM,EAC5D,IAAc,KAAK,IAAI,GAAG,IAAS,EAAO,MAAM,EAAO,OAAO;AAEpE,QACE,kBAAC,OAAD;EACE,MAAM,MAAS;AAEb,GADC,EAA+D,UAAU,GACtE,OAAO,KAAQ,aAAY,EAAI,EAAK,GAC/B,MAAM,EAAsD,UAAU;;EAEjF,WAAW,EAAG,mBAAmB,EAAU;EAC3C,GAAI;YAEH,IAAQ,KACP,kBAAC,OAAD;GAAY;GAAe;GAAQ,MAAK;GAAM,cAAY;aAA1D,CACG,KAAmB,kBAAC,QAAD,EAAA,UAAO,GAAuB,CAAA,EAClD,kBAAC,KAAD;IAAG,WAAW,aAAa,EAAO,KAAK,GAAG,EAAO,IAAI;cAClD,EAAS;KAAE,OAAO;KAAY,QAAQ;KAAa;KAAQ,CAAC;IAC3D,CAAA,CACA;;EAEJ,CAAA;EAGT;AACD,EAAe,cAAc;;;ACvD7B,SAAgB,EAAK,EACnB,UACA,gBACA,cACA,cACA,eACA,UACA,gBACY;CACZ,IAAM,IAAM,EAAoB,KAAK;AAqCrC,QAnCA,QAAgB;AACd,MAAI,CAAC,EAAI,QAAS;EAElB,IAAM,IAAS;GACb,KAAK;GACL,OAAO;GACP,QAAQ;GACR,MAAM;GACP,CAAC,IAGE,IAAO,EAAO,EAAa;AAG/B,EAFI,MAAW,IAAO,EAAK,MAAM,EAAU,GAEvC,MAAY,IAAO,EAAK,WAAW,EAAkB;EAEzD,IAAM,IAAI,EAAO,EAAI,QAAQ;AAS7B,EAPA,EAAE,KAAK,EAAY,EAGnB,EAAE,UAAU,aAAa,CAAC,KAAK,UAAU,8BAA8B,EACvE,EAAE,UAAU,aAAa,CACtB,KAAK,QAAQ,gCAAgC,CAC7C,KAAK,aAAa,sBAAsB,EAC3C,EAAE,UAAU,UAAU,CAAC,KAAK,UAAU,qCAAqC;IAC1E;EAAC;EAAO;EAAa;EAAW;EAAW,CAAC,EAU7C,kBAAC,KAAD;EAAQ;EAAgB;EAAsB;YAC3C,KACC,kBAAC,QAAD;GACE,YAAW;GACX,MAAK;GACL,UAAS;GACT,GAbN,MAAgB,WACZ;IAAE,GAAG;IAAO,IAAI;IAAI,GACpB,MAAgB,SACd;IAAE,WAAW;IAAe,GAAG;IAAK,GAAG;IAAG,GAC1C,EAAE;aAWD;GACI,CAAA;EAEP,CAAA;;AAGR,EAAK,cAAc;;;ACvEnB,SAAgB,EAAU,EACxB,UACA,WACA,WACA,WACA,gBAAa,IACb,cAAW,MACM;AACjB,QACE,kBAAC,KAAD;EAAG,WAAU;YAAb,CACG,KACC,GAAQ,SACR,EAAO,OAAO,CAAC,KAAK,GAAqB,MACvC,kBAAC,QAAD;GAEE,IAAI;GACJ,IAAI;GACJ,IAAI,EAAO,EAAe;GAC1B,IAAI,EAAO,EAAe;GAC1B,QAAO;GACP,iBAAgB;GAChB,SAAS;GACT,EARK,KAAK,IAQV,CACF,EACH,KACC,GAAQ,SACR,EAAO,OAAO,CAAC,KAAK,GAAqB,MACvC,kBAAC,QAAD;GAEE,IAAI,EAAO,EAAe;GAC1B,IAAI,EAAO,EAAe;GAC1B,IAAI;GACJ,IAAI;GACJ,QAAO;GACP,iBAAgB;GAChB,SAAS;GACT,EARK,KAAK,IAQV,CACF,CACF;;;AAGR,EAAU,cAAc;;;ACzCxB,SAAgB,EAAO,EAAE,UAAO,cAAW,UAAU,gBAA0B;AAG7E,QACE,kBAAC,OAAD;EACE,WAAW,EACT,mDALa,MAAa,UAAU,MAAa,UAMpC,aAAa,qCAC1B,EACD;YAEA,EAAM,KAAK,MACV,kBAAC,OAAD;GAAsB,WAAU;aAAhC,CACE,kBAAC,QAAD;IACE,WAAU;IACV,OAAO,EAAE,iBAAiB,EAAK,OAAO;IACtC,CAAA,EACF,kBAAC,QAAD,EAAA,UAAO,EAAK,OAAa,CAAA,CACrB;KANI,EAAK,MAMT,CACN;EACE,CAAA;;AAGV,EAAO,cAAc;;;ACnBrB,SAAgB,EAAa,EAAE,UAAO,gBAAgC;AAGpE,QAFK,EAAM,UAGT,kBAAC,OAAD;EACE,WAAW,EACT,0CACA,qDACA,wCACA,uBACA,8BACA,EACD;EACD,OAAO;GAAE,MAAM,EAAM,IAAI;GAAI,KAAK,EAAM,IAAI;GAAI;YAE/C,EAAM;EACH,CAAA,GAfmB;;AAkB7B,EAAa,cAAc;AAG3B,SAAgB,IAAkB;CAChC,IAAM,CAAC,GAAS,KAAc,EAAuB;EACnD,SAAS;EACT,GAAG;EACH,GAAG;EACH,SAAS;EACV,CAAC;AAUF,QAAO;EAAE;EAAS,MARL,GAAa,GAAW,GAAW,MAA6B;AAC3E,KAAW;IAAE,SAAS;IAAM;IAAG;IAAG;IAAS,CAAC;KAC3C,EAAE,CAAC;EAMkB,MAJX,QAAkB;AAC7B,MAAY,OAAU;IAAE,GAAG;IAAM,SAAS;IAAO,EAAE;KAClD,EAAE,CAAC;EAEwB;;;;ACtDhC,IAAM,IAA6B;CACjC;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACD;AAGD,SAAgB,EAAc,GAA2B;AACvD,QAAO,SAAS,EAAM;;AAWxB,SAAgB,EAAa,GAAwC,IAAgB,GAAW;AAG9F,QAFK,IACA,EAA0B,SAAS,EAAM,GAAS,EAAc,EAAoB,GAClF,IAFY,EAAc,EAAa,IAAQ,EAAa,QAAQ;;;;ACtB7E,SAAgB,IAA4B;CAC1C,IAAM,EAAE,qBAAkB,GAAW;AACrC,QAAO;;AAIT,SAAgB,EAAsB,GAAwB,IAAW,KAAa;AACpF,QAAO,IAAgB,IAAI;;;;AC0C7B,IAAa,IAAW,EAAM,YAE1B,EACE,SACA,SACA,SACA,iBAAc,YACd,aAAU,IACV,aAAU,IACV,UACA,YAAS,KACT,cAAW,IACX,iBAAc,IACd,gBAAa,IACb,aAAU,IACV,eAAY,GACZ,WACA,WACA,iBACA,cACA,cACA,GAAG,KAEL,MACG;CACL,IAAM,EAAE,YAAS,SAAM,YAAS,GAAiB,EAC3C,IAAgB,GAAkB,EAClC,IAAa,MAAgB,YAC7B,IAAgB,KAAW,CAAC,GAG5B,IAAQ,MAAM,QAAQ,EAAK,GAAG,IAAO,CAAC,EAAK,EAC3C,IAAgB,EAAM,SAAS,GAG/B,IAAS,IACX,EAAM,KAAK,GAAG,MACZ,EACE,MAAM,QAAQ,EAAM,GAAG,EAAM,KAAK,OAAO,KAAU,WAAW,IAAQ,KAAA,GACtE,EACD,CACF,GACD,CACE,EACE,OAAO,KAAU,WACb,IACA,MAAM,QAAQ,EAAM,GAClB,EAAM,KACN,KAAA,GACN,EACD,CACF;AAEL,QACE,kBAAC,EAAO,KAAR;EACO;EACL,WAAW,EAAG,YAAY,EAAU;EACpC,GAAK,IACD;GAAE,SAAS;IAAE,SAAS;IAAG,OAAO;IAAM;GAAE,SAAS;IAAE,SAAS;IAAG,OAAO;IAAG;GAAE,YAAY,EAAO;GAAM,GACpG,EAAE;EACN,GAAI,EAAY,EAAM;YANxB;GAQE,kBAAC,GAAD;IAAwB;IAAQ,WAAW,KAAa;eACpD,EAAE,UAAO,QAAQ,GAAa,gBAAa;KAK3C,IAAM,IAAa,EAAK,KAAK,MAAM,OAAO,EAAE,GAAM,CAAC,EAG7C,IAAc,EAAK,KAAK,MAMrB,GALK,OAAO,EAAE,GAAM,CAKb,KAJD,EAAM,KAAK,GAAG,MAElB,GADK,IAAe,MAAM,EACnB,IAAI,OAAO,EAAE,GAAG,CAAC,gBAAgB,GAC/C,CAAC,KAAK,KAAK,GAEb,CAAC,KAAK,KAAK,EAGT;AACJ,KAOE,IANW,KAAK,IADlB,GAAI,IAEG,EAAK,KAAK,MACX,EAAM,QAAQ,GAAK,MAAM,KAAO,OAAO,EAAE,GAAG,IAAI,IAAI,EAAE,CACvD,GAIE,EAAK,SAAS,MAAM,EAAM,KAAK,MAAM,OAAO,EAAE,GAAG,IAAI,EAAE,CAAC,CAC5D;KAIH,IAAM,IAAgB,GAAW,CAC9B,OAAO,EAAW,CAClB,MAAM,IAAa,CAAC,GAAG,EAAM,GAAG,CAAC,GAAG,EAAY,CAAC,CACjD,QAAQ,GAAI,EAET,IAAa,GAAa,CAC7B,OAAO,CAAC,GAAG,IAAW,IAAI,CAAC,CAC3B,MAAM,IAAa,CAAC,GAAa,EAAE,GAAG,CAAC,GAAG,EAAM,CAAC,CACjD,MAAM,EAEH,IAAe,EAAc,WAAW,EACxC,IACJ,KAAiB,IACb,IAAe,EAAM,SACrB;AAEN,YACE,kBAAA,GAAA,EAAA,UAAA;MAEE,kBAAC,QAAD,EAAA,UAAO,GAAmB,CAAA;MAGzB,KACC,kBAAC,GAAD;OACS;OACP,QAAQ;OACR,QAAQ,IAAa,IAAa,KAAA;OAClC,QAAS,IAA0B,KAAA,IAAb;OACtB,YAAY;OACZ,UAAU,CAAC;OACX,CAAA;MAIH,EAAK,KAAK,MAAM;OACf,IAAM,IAAW,OAAO,EAAE,GAAM,EAC5B,IAAc;AAElB,cAAO,EAAM,KAAK,GAAK,MAAc;QACnC,IAAM,IAAQ,OAAO,EAAE,GAAK,IAAI,GAC1B,IAAW,EAAO,MAAc,EAAO,IAEzC,GAAW,GAAW,GAAW;AAwBrC,QAtBI,KACF,KACG,EAAc,EAAS,IAAI,MAC3B,KAAW,IAAgB,IAAY,IAAW,IACrD,IACI,EADA,IACW,IAAc,IACd,EAAM,EACrB,IAAI,GACJ,IAAI,IACA,EAAW,EAAY,GAAG,EAAW,IAAc,EAAM,GACzD,IAAc,EAAW,EAAM,KAEnC,IAAI,IAAU,EAAW,EAAY,GAAG,GACxC,KACG,EAAc,EAAS,IAAI,MAC3B,KAAW,IAAgB,IAAY,IAAW,IACrD,IAAI,IACA,EAAW,IAAc,EAAM,GAAG,EAAW,EAAY,GACzD,EAAW,EAAM,EACrB,IAAI,IAGF,MAAS,KAAe;QAE5B,IAAM,IAAc,IAAe,MAAc,GAC3C,IAAe,IACjB,GAAG,EAAS,IAAI,EAAY,IAAI,EAAM,gBAAgB,KACtD,GAAG,EAAS,IAAI,EAAM,gBAAgB,IAEpC,IACJ,kBAAC,OAAD,EAAA,UAAA;SACE,kBAAC,OAAD;UAAK,WAAU;oBAAe;UAAe,CAAA;SAC5C,KACC,kBAAC,OAAD;UAAK,WAAU;oBACZ;UACG,CAAA;SAER,kBAAC,OAAD,EAAA,UAAM,EAAM,gBAAgB,EAAO,CAAA;SAC/B,EAAA,CAAA;AAGR,eACE,kBAAC,QAAD;SAEK;SACA;SACH,OAAO,KAAK,IAAI,GAAG,EAAE;SACrB,QAAQ,KAAK,IAAI,GAAG,EAAE;SACtB,IAAI;SACJ,MAAM;SACN,WAAU;SACV,UAAU,IAAc,IAAI,KAAA;SAC5B,MAAM,IAAc,oBAAoB,KAAA;SACxC,cAAY;SACZ,cAAc,MAAM;AAClB,cAAI,GAAa;WACf,IAAM,IAAO,EAAE,cACZ,QAAQ,MAAM,EACb,uBAAuB;AAC3B,aACE,EAAE,WAAW,GAAM,QAAQ,IAC3B,EAAE,WAAW,GAAM,OAAO,IAC1B,EACD;;;SAGL,cAAc;SACd,UAAU,MAAM;AACd,cAAI,GAAa;WACf,IAAM,IAAU,EAAE,cACf,QAAQ,MAAM,EACb,uBAAuB,EACrB,IAAU,EAAE,cAAc,uBAAuB;AACvD,aACE,EAAQ,OAAO,EAAQ,QAAQ,KAAK,GAAS,QAAQ,IACrD,EAAQ,OAAO,GAAS,OAAO,IAC/B,EACD;;;SAGL,QAAQ;SACR,EAtCK,GAAG,EAAS,GAAG,IAsCpB;SAEJ;QACF;MAGD,IACC,kBAAA,GAAA,EAAA,UAAA,CACE,kBAAC,GAAD;OACE,OAAO;OACP,aAAY;OACZ,WAAW,eAAe,EAAY;OACtC,OAAO;OACP,CAAA,EACF,kBAAC,GAAD;OAAM,OAAO;OAAY,aAAY;OAAO,OAAO;OAAU,CAAA,CAC5D,EAAA,CAAA,GAEH,kBAAA,GAAA,EAAA,UAAA,CACE,kBAAC,GAAD;OACE,OAAO;OACP,aAAY;OACZ,WAAW,eAAe,EAAY;OACtC,OAAO;OACP,CAAA,EACF,kBAAC,GAAD;OACE,OAAO;OACP,aAAY;OACZ,OAAO;OACP,CAAA,CACD,EAAA,CAAA;MAEJ,EAAA,CAAA;;IAGQ,CAAA;GAGhB,KAAe,kBAAC,GAAD,EAAc,OAAO,GAAW,CAAA;GAG/C,KAAc,KACb,kBAAC,GAAD;IACE,OAAO,EAAM,KAAK,GAAK,OAAO;KAC5B,OAAO,IAAe,MAAM;KAC5B,OAAO,EAAO;KACf,EAAE;IACH,WAAU;IACV,CAAA;GAEO;;EAGhB;AACD,EAAS,cAAc;;;ACnRvB,IAAa,IAAY,EAAM,YAE3B,EACE,SACA,SACA,WACA,YAAS,IACT,cAAW,IACX,aAAU,GACV,iBAAc,GACd,YAAS,KACT,cAAW,IACX,iBAAc,IACd,gBAAa,IACb,aAAU,IACV,WACA,WACA,cACA,cACA,GAAG,KAEL,MACG;CACL,IAAM,EAAE,YAAS,SAAM,YAAS,GAAiB,EAC3C,IAAgB,GAAkB,EAClC,IAAgB,KAAW,CAAC,GAG5B,IAAS,EAAO,KAAK,GAAG,MAAM,EAAa,EAAE,OAAO,EAAE,CAAC;AAE7D,QACE,kBAAC,EAAO,KAAR;EACO;EACL,WAAW,EAAG,YAAY,EAAU;EACpC,GAAK,IACD;GAAE,SAAS;IAAE,SAAS;IAAG,OAAO;IAAM;GAAE,SAAS;IAAE,SAAS;IAAG,OAAO;IAAG;GAAE,YAAY,EAAO;GAAM,GACpG,EAAE;EACN,GAAI,EAAY,EAAM;YANxB;GAQE,kBAAC,GAAD;IAAwB;IAAQ,WAAW,KAAa;eACpD,EAAE,UAAO,QAAQ,GAAa,gBAAa;KAI3C,IAAM,IAAU,EAAK,KAAK,MAAM,EAAE,GAAM,EAClC,IAAa,EAAQ,OAAO,MAAM,OAAO,KAAM,SAAS,EAG1D,GACA;AAEJ,SAAI,GAAY;MACd,IAAM,IAAgB,GAChB,IAAO,KAAK,IAAI,GAAG,EAAc,EACjC,IAAO,KAAK,IAAI,GAAG,EAAc,EACjC,IAAU,GAA6B,CAC1C,OAAO,CAAC,GAAM,EAAK,CAAC,CACpB,MAAM,CAAC,GAAG,EAAM,CAAC;AAEpB,MADA,IAAa,GACb,KAAQ,MAAiB,EAAQ,OAAO,EAAE,GAAM,CAAC;YAC5C;MACL,IAAM,IAAa,EAAQ,IAAI,OAAO,EAChC,IAAS,GAAoB,CAChC,OAAO,EAAW,CAClB,MAAM,CAAC,GAAG,EAAM,CAAC,CACjB,QAAQ,GAAI;AAEf,MADA,IAAa,GACb,KAAQ,MAAiB,EAAO,OAAO,EAAE,GAAM,CAAC,IAAI;;KAItD,IAAM,IAAY,EAAK,SAAS,MAC9B,EAAO,KAAK,MAAM,OAAO,EAAE,EAAE,KAAK,IAAI,EAAE,CACzC,EACK,IAAO,KAAK,IAAI,GAAG,EAAU,EAC7B,IAAS,GAA6B,CACzC,OAAO,CAAC,GAAG,IAAO,IAAI,CAAC,CACvB,MAAM,CAAC,GAAa,EAAE,CAAC,CACvB,MAAM,EAGH,IAAY,IAAS,IAAiB,GACtC,IAAU,GAAiB,CAC9B,MAAM,EAAU,CAChB,SAAS,MAAM,KAAyB,KAAK;AAWhD,YACE,kBAAA,GAAA,EAAA,UAAA;MAEE,kBAAC,QAAD,EAAA,UAXgB,EAAK,KAAK,MAKrB,GAJM,OAAO,EAAE,GAAM,CAIb,KAHF,EAAO,KAAK,MACvB,GAAG,EAAE,MAAM,IAAI,OAAO,EAAE,EAAE,KAAK,CAAC,gBAAgB,GACjD,CAAC,KAAK,KAAK,GAEZ,CAAC,KAAK,KAAK,EAKiB,CAAA;MAGzB,KACC,kBAAC,GAAD;OACS;OACP,QAAQ;OACA;OACR,YAAA;OACA,CAAA;MAIH,EAAO,KAAK,GAAG,MAQZ,kBAAC,KAAD,EAAA,UAAA,CAEE,kBAAC,QAAD;OACE,GAVU,EACb,GAAG,MAAM,EAAK,EAAE,CAAC,CACjB,GAAG,MAAM,EAAO,OAAO,EAAE,EAAE,KAAK,IAAI,EAAE,CAAC,CAEpB,EAAK,IAAI;OAOzB,MAAK;OACL,QAAQ,EAAO;OACF;OACb,gBAAe;OACf,eAAc;OACd,CAAA,EAGD,KACC,EAAK,KAAK,GAAG,MAIT,kBAAC,UAAD;OAEM,IALG,EAAK,EAAE;OAMV,IALG,EAAO,OAAO,EAAE,EAAE,KAAK,IAAI,EAAE;OAMpC,GAAG;OACH,MAAM,EAAO;OACb,WAAU;OACV,EANK,GAAG,EAAE,IAAI,OAAO,IAMrB,CAEJ,CACF,EAAA,EA3BI,EAAE,IA2BN,CAEN;MAGD,KACC,EAAK,KAAK,GAAG,MAAM;OACjB,IAAM,IAAK,EAAK,EAAE,EACZ,IAAa,IAAQ,KAAK,IAAI,EAAK,SAAS,GAAG,EAAE,EACjD,IAAO,OAAO,EAAE,GAAM,EACtB,IAAiB,GAAG,EAAK,IAAI,EAAO,KAAK,MAAM,GAAG,EAAE,MAAM,GAAG,OAAO,EAAE,EAAE,KAAK,CAAC,gBAAgB,GAAG,CAAC,KAAK,KAAK,IAE5G,IACJ,kBAAC,OAAD,EAAA,UAAA,CACE,kBAAC,OAAD;QAAK,WAAU;kBAAe;QAAW,CAAA,EACxC,EAAO,KAAK,GAAG,MACd,kBAAC,OAAD;QAEE,WAAU;kBAFZ;SAIE,kBAAC,QAAD;UACE,WAAU;UACV,OAAO,EAAE,iBAAiB,EAAO,IAAO;UACxC,CAAA;SACF,kBAAC,QAAD;UAAM,WAAU;oBAAhB,CACG,EAAE,OAAM,IACJ;;SAAC;SACP,OAAO,EAAE,EAAE,KAAK,CAAC,gBAAgB;SAC9B;UAXC,EAAE,IAWH,CACN,CACE,EAAA,CAAA;AAGR,cACE,kBAAC,QAAD;QAEE,GAAG,IAAK,IAAa;QACrB,GAAG;QACH,OAAO;QACP,QAAQ;QACR,MAAK;QACL,UAAU;QACV,MAAK;QACL,cAAY;QACZ,WAAU;QACV,cAAc,MAAM;SAClB,IAAM,IAAO,EAAE,cACZ,QAAQ,MAAM,EACb,uBAAuB;AAC3B,WACE,EAAE,WAAW,GAAM,QAAQ,IAC3B,EAAE,WAAW,GAAM,OAAO,IAC1B,EACD;;QAEH,cAAc;QACd,UAAU,MAAM;SACd,IAAM,IAAU,EAAE,cACf,QAAQ,MAAM,EACb,uBAAuB,EACrB,IAAY,EAAE,cAAc,uBAAuB;AACzD,WACE,EAAU,OAAO,EAAU,QAAQ,KAAK,GAAS,QAAQ,IACzD,EAAU,MAAM,EAAU,SAAS,KAAK,GAAS,OAAO,IACxD,EACD;;QAEH,QAAQ;QACR,EAjCK,SAAS,IAiCd;QAEJ;MAGJ,kBAAC,GAAD;OACE,OAAO;OACP,aAAY;OACZ,WAAW,eAAe,EAAY;OACtC,OAAO;OACP,CAAA;MACF,kBAAC,GAAD;OAAM,OAAO;OAAQ,aAAY;OAAO,OAAO;OAAU,CAAA;MACxD,EAAA,CAAA;;IAGQ,CAAA;GAGhB,KAAe,kBAAC,GAAD,EAAc,OAAO,GAAW,CAAA;GAG/C,KAAc,EAAO,SAAS,KAC7B,kBAAC,GAAD;IACE,OAAO,EAAO,KAAK,GAAG,OAAO;KAC3B,OAAO,EAAE;KACT,OAAO,EAAO;KACf,EAAE;IACH,WAAU;IACV,CAAA;GAEO;;EAGhB;AACD,EAAU,cAAc;;;ACzOxB,IAAa,IAAY,EAAM,YAE3B,EACE,SACA,SACA,WACA,YAAS,IACT,aAAU,IACV,iBAAc,IACd,cAAW,IACX,iBAAc,GACd,YAAS,KACT,cAAW,IACX,iBAAc,IACd,gBAAa,IACb,aAAU,IACV,WACA,WACA,cACA,cACA,GAAG,KAEL,MACG;CACL,IAAM,EAAE,YAAS,SAAM,YAAS,GAAiB,EAC3C,IAAgB,GAAkB,EAClC,IAAgB,KAAW,CAAC,GAG5B,IAAS,EAAO,KAAK,GAAG,MAAM,EAAa,EAAE,OAAO,EAAE,CAAC,EAGvD,IAAU,EAAM,OAAO;AAE7B,QACE,kBAAC,EAAO,KAAR;EACO;EACL,WAAW,EAAG,YAAY,EAAU;EACpC,GAAK,IACD;GAAE,SAAS;IAAE,SAAS;IAAG,OAAO;IAAM;GAAE,SAAS;IAAE,SAAS;IAAG,OAAO;IAAG;GAAE,YAAY,EAAO;GAAM,GACpG,EAAE;EACN,GAAI,EAAY,EAAM;YANxB;GAQE,kBAAC,GAAD;IAAwB;IAAQ,WAAW,KAAa;eACpD,EAAE,UAAO,QAAQ,GAAa,gBAAa;KAI3C,IAAM,IAAU,EAAK,KAAK,MAAM,EAAE,GAAM,EAClC,IAAa,EAAQ,OAAO,MAAM,OAAO,KAAM,SAAS,EAG1D,GACA,GACA;AAEJ,SAAI,GAAY;MACd,IAAM,IAAgB,GAChB,IAAO,KAAK,IAAI,GAAG,EAAc,EACjC,IAAO,KAAK,IAAI,GAAG,EAAc,EACjC,IAAU,GAA6B,CAC1C,OAAO,CAAC,GAAM,EAAK,CAAC,CACpB,MAAM,CAAC,GAAG,EAAM,CAAC;AAGpB,MAFA,IAAa,GACb,KAAQ,MAAiB,EAAQ,OAAO,EAAE,GAAM,CAAC,EACjD,KAAe,MAAc,EAAQ,OAAO,EAAK,GAAG,GAAM,CAAC;YACtD;MACL,IAAM,IAAa,EAAQ,IAAI,OAAO,EAChC,IAAS,GAAoB,CAChC,OAAO,EAAW,CAClB,MAAM,CAAC,GAAG,EAAM,CAAC,CACjB,QAAQ,GAAI;AAGf,MAFA,IAAa,GACb,KAAQ,MAAiB,EAAO,OAAO,EAAE,GAAM,CAAC,IAAI,GACpD,KAAe,MAAc,EAAO,OAAO,EAAK,GAAG,GAAM,CAAC,IAAI;;KAIhE,IAAI;AACJ,KAOE,IANO,KAAK,IADd,GAAI,IAEG,EAAK,KAAK,MACX,EAAO,QAAQ,GAAK,MAAM,KAAO,OAAO,EAAE,EAAE,KAAK,IAAI,IAAI,EAAE,CAC5D,GAIE,EAAK,SAAS,MACf,EAAO,KAAK,MAAM,OAAO,EAAE,EAAE,KAAK,IAAI,EAAE,CACzC,CACF;KAGH,IAAM,IAAS,GAA6B,CACzC,OAAO,CAAC,GAAG,IAAO,IAAI,CAAC,CACvB,MAAM,CAAC,GAAa,EAAE,CAAC,CACvB,MAAM,EAEH,IAAY,IAAS,IAAiB,GAGtC,UACJ,EAAK,KAAK,GAAG,MAAM;MACjB,IAAM,IAAK,EAAK,EAAE,EACZ,IAAa,IAAQ,KAAK,IAAI,EAAK,SAAS,GAAG,EAAE;AACvD,aACE,kBAAC,QAAD;OAEE,GAAG,IAAK,IAAa;OACrB,GAAG;OACH,OAAO;OACP,QAAQ;OACR,MAAK;OACL,cAAc,MAAM;QAClB,IAAM,IAAO,EAAE,cACZ,QAAQ,MAAM,EACb,uBAAuB;AAC3B,UACE,EAAE,WAAW,GAAM,QAAQ,IAC3B,EAAE,WAAW,GAAM,OAAO,IAC1B,kBAAC,OAAD,EAAA,UAAA,CACE,kBAAC,OAAD;SAAK,WAAU;mBACZ,OAAO,EAAE,GAAM;SACZ,CAAA,EACL,EAAO,KAAK,GAAG,MACd,kBAAC,OAAD;SAEE,WAAU;mBAFZ;UAIE,kBAAC,QAAD;WACE,WAAU;WACV,OAAO,EAAE,iBAAiB,EAAO,IAAO;WACxC,CAAA;UACF,kBAAC,QAAD;WAAM,WAAU;qBAAhB,CACG,EAAE,OAAM,IACJ;;UAAC;UACP,OAAO,EAAE,EAAE,KAAK,CAAC,gBAAgB;UAC9B;WAXC,EAAE,IAWH,CACN,CACE,EAAA,CAAA,CACP;;OAEH,cAAc;OACd,EApCK,SAAS,IAoCd;OAEJ,EAGE,UACJ,IACE,kBAAC,QAAD,EAAA,UACG,EAAO,KAAK,GAAG,MACd,kBAAC,kBAAD;MAEE,IAAI,GAAG,EAAQ,YAAY;MAC3B,IAAG;MACH,IAAG;MACH,IAAG;MACH,IAAG;gBANL,CAQE,kBAAC,QAAD;OACE,QAAO;OACP,WAAW,EAAO;OAClB,aAAa;OACb,CAAA,EACF,kBAAC,QAAD;OACE,QAAO;OACP,WAAW,EAAO;OAClB,aAAa;OACb,CAAA,CACa;QAjBV,QAAQ,IAiBE,CACjB,EACG,CAAA,GACL,MAGA,UACJ,kBAAA,GAAA,EAAA,UAAA,CACE,kBAAC,GAAD;MACE,OAAO;MACP,aAAY;MACZ,WAAW,eAAe,EAAY;MACtC,OAAO;MACP,CAAA,EACF,kBAAC,GAAD;MAAM,OAAO;MAAQ,aAAY;MAAO,OAAO;MAAU,CAAA,CACxD,EAAA,CAAA;AAIL,SAAI,GAAS;MACX,IAAM,IAAa,EAAO,KAAK,MAAM,EAAE,IAAI,EAerC,IAdW,GAAqB,CACnC,KAAK,EAAW,CAChB,MAAM,EAAe,CACrB,OAAO,EAAgB,CAGU,EAAK,KAAK,MAAM;OAClD,IAAM,IAAoB,GAAG,IAAO,OAAO,EAAE,GAAM,EAAE;AACrD,YAAK,IAAM,KAAK,EACd,GAAI,EAAE,OAAO,OAAO,EAAE,EAAE,KAAK,IAAI;AAEnC,cAAO;QACP,CAEuC,EAEnC,IAAU,GAAwB,CACrC,MAAM,EAAU,CAChB,GAAG,GAAG,MAAM,EAAY,EAAE,CAAC,CAC3B,IAAI,MAAM,EAAO,EAAE,GAAG,CAAC,CACvB,IAAI,MAAM,EAAO,EAAE,GAAG,CAAC,EAEpB,IAAU,GAAwB,CACrC,MAAM,EAAU,CAChB,GAAG,GAAG,MAAM,EAAY,EAAE,CAAC,CAC3B,GAAG,MAAM,EAAO,EAAE,GAAG,CAAC;AAEzB,aACE,kBAAA,GAAA,EAAA,UAAA;OACG,GAAoB;OAGpB,KACC,kBAAC,GAAD;QACS;QACP,QAAQ;QACA;QACR,YAAA;QACA,CAAA;OAIH,CAAC,GAAG,EAAY,CAAC,SAAS,CAAC,KAAK,GAAO,MAAgB;QACtD,IAAM,IAAY,EAAY,SAAS,IAAI,GACrC,IAAY,GACZ,IAAQ,EAAQ,EAAU,IAAI,IAC9B,IAAQ,EAAQ,EAAU,IAAI;AAKpC,eACE,kBAAC,KAAD,EAAA,UAAA,CACE,kBAAC,QAAD;SACE,GAAG;SACH,MARY,IACd,QAAQ,EAAQ,YAAY,EAAU,KACtC,EAAO;SAOL,SAAS,IAAW,IAAI;SACxB,CAAA,EACF,kBAAC,QAAD;SACE,GAAG;SACH,MAAK;SACL,QAAQ,EAAO;SACF;SACb,gBAAe;SACf,eAAc;SACd,CAAA,CACA,EAAA,EAdI,EAAO,GAAW,IActB;SAEN;OAGD,KAAe,GAAoB;OAEnC,GAAY;OACZ,EAAA,CAAA;;KAKP,IAAM,IAAU,GAAiB,CAC9B,MAAM,EAAU,CAChB,SAAS,MAAM,KAAyB,KAAK,EAE1C,IAAU,GAAiB,CAC9B,MAAM,EAAU,CAChB,SAAS,MAAM,KAAyB,KAAK;AAEhD,YACE,kBAAA,GAAA,EAAA,UAAA;MACG,GAAoB;MAGpB,KACC,kBAAC,GAAD;OACS;OACP,QAAQ;OACA;OACR,YAAA;OACA,CAAA;MAIH,CAAC,GAAG,EAAO,CAAC,SAAS,CAAC,KAAK,GAAG,MAAgB;OAC7C,IAAM,IAAY,EAAO,SAAS,IAAI,GAEhC,IAAW,EACd,GAAG,MAAM,EAAK,EAAE,CAAC,CACjB,GAAG,EAAY,CACf,IAAI,MAAM,EAAO,OAAO,EAAE,EAAE,KAAK,IAAI,EAAE,CAAC,EAErC,IAAW,EACd,GAAG,MAAM,EAAK,EAAE,CAAC,CACjB,GAAG,MAAM,EAAO,OAAO,EAAE,EAAE,KAAK,IAAI,EAAE,CAAC,EAEpC,IAAQ,EAAS,EAAK,IAAI,IAC1B,IAAQ,EAAS,EAAK,IAAI;AAMhC,cACE,kBAAC,KAAD,EAAA,UAAA,CACE,kBAAC,QAAD;QACE,GAAG;QACH,MARY,IACd,QAAQ,EAAQ,YAAY,EAAU,KACtC,EAAO;QAOL,SAAS,IAAW,IAAI;QACxB,CAAA,EACF,kBAAC,QAAD;QACE,GAAG;QACH,MAAK;QACL,QAAQ,EAAO;QACF;QACb,gBAAe;QACf,eAAc;QACd,CAAA,CACA,EAAA,EAdI,EAAE,IAcN;QAEN;MAGD,KAAe,GAAoB;MAEnC,GAAY;MACZ,EAAA,CAAA;;IAGQ,CAAA;GAGhB,KAAe,kBAAC,GAAD,EAAc,OAAO,GAAW,CAAA;GAG/C,KAAc,EAAO,SAAS,KAC7B,kBAAC,GAAD;IACE,OAAO,EAAO,KAAK,GAAG,OAAO;KAC3B,OAAO,EAAE;KACT,OAAO,EAAO;KACf,EAAE;IACH,WAAU;IACV,CAAA;GAEO;;EAGhB;AACD,EAAU,cAAc;;;ACxXxB,IAAa,IAAW,EAAM,YAE1B,EACE,SACA,aAAU,OACV,aAAa,IAAmB,IAChC,cAAW,GACX,kBAAe,GACf,YAAS,KACT,iBAAc,IACd,gBAAa,IACb,gBAAa,IACb,aAAU,IACV,cACA,gBACA,cACA,GAAG,KAEL,MACG;CACL,IAAM,IAAe,EAAuB,KAAK,EAC3C,CAAC,GAAgB,KAAqB,EAAS,EAAE,EACjD,CAAC,GAAc,KAAmB,EAAwB,KAAK,EAC/D,EAAE,YAAS,SAAM,YAAS,GAAiB,EAC3C,IAAgB,GAAkB,EAClC,IAAgB,KAAW,CAAC;AAElC,SAAgB;AACd,MAAI,CAAC,EAAa,QAAS;EAC3B,IAAM,IAAW,IAAI,gBAAgB,MAAY;GAC/C,IAAM,IAAQ,EAAQ;AACtB,GAAI,KAAO,EAAkB,EAAM,YAAY,MAAM;IACrD;AAEF,SADA,EAAS,QAAQ,EAAa,QAAQ,QACzB,EAAS,YAAY;IACjC,EAAE,CAAC;CAIN,IAAM,KADO,IAAiB,IAAI,KAAK,IAAI,GAAgB,EAAO,GAAG,KAC1C,GACrB,IAAS,MAAY,UAAU,IAAc,IAAmB,GAGhE,IAAS,EAAK,KAAK,GAAG,MAAM,EAAa,EAAE,OAAO,EAAE,CAAC,EAGrD,IAAQ,EAAK,QAAQ,GAAK,MAAM,IAAM,EAAE,OAAO,EAAE,EAQjD,IALY,GAAiB,CAChC,OAAO,MAAM,EAAE,MAAM,CACrB,SAAS,EAAS,CAClB,KAAK,KAAK,CAEU,EAAK,EAGtB,IAAe,GAA8B,CAChD,YAAY,EAAO,CACnB,YAAY,IAAc,EAAE,CAC5B,aAAa,EAAa,EAGvB,IAAc,KAAU,IAAc,IAAI,KAAU,IACpD,IAAW,GAA8B,CAC5C,YAAY,EAAY,CACxB,YAAY,EAAY;AAE3B,QACE,kBAAC,EAAO,KAAR;EACE,MAAM,MAAS;AAEb,GADC,EAA+D,UAAU,GACtE,OAAO,KAAQ,aAAY,EAAI,EAAK,GAC/B,MAAM,EAAsD,UAAU;;EAEjF,WAAW,EAAG,mBAAmB,EAAU;EAC3C,GAAK,IACD;GAAE,SAAS;IAAE,SAAS;IAAG,OAAO;IAAM;GAAE,SAAS;IAAE,SAAS;IAAG,OAAO;IAAG;GAAE,YAAY,EAAO;GAAM,GACpG,EAAE;EACN,GAAI,EAAY,EAAM;YAVxB,CAYG,IAAiB,KAChB,kBAAA,GAAA,EAAA,UAAA,CACE,kBAAC,OAAD;GACE,OAAO;GACC;GACR,MAAK;GACL,cAAY,KAAa;aAEzB,kBAAC,KAAD;IAAG,WAAW,aAAa,IAAiB,EAAE,GAAG,IAAS,EAAE;cAA5D;KACG,EAAK,KAAK,GAAG,MAAM;MAClB,IAAM,IAAO,EAAa,EAAE;AAC5B,UAAI,CAAC,EAAM,QAAO;MAGlB,IAAM,CAAC,GAAI,KAAM,EAAa,SAAS,EAAE,EACnC,IAAQ,KAAK,MAAM,GAAI,EAAG,EAC1B,IAAU,KAAK,IAAI,EAAM,GAAG,GAC5B,IAAU,KAAK,IAAI,EAAM,GAAG,GAC5B,IAAY,MAAiB;AAEnC,aACE,kBAAC,QAAD;OAEE,GAAG;OACH,MAAM,EAAO;OACb,WAAU;OACV,OAAO,EACL,WAAW,IACP,aAAa,EAAQ,MAAM,EAAQ,OACnC,KAAA,GACL;OACD,oBAAoB,EAAgB,EAAE;OACtC,cAAc,MAAM;AAClB,YAAI,GAAa;SACf,IAAM,IAAO,EAAE,cACZ,QAAQ,MAAM,EACb,uBAAuB,EACrB,IACJ,IAAQ,KACF,EAAE,KAAK,QAAQ,IAAS,KAAK,QAAQ,EAAE,GACzC;AACN,WACE,EAAE,WAAW,GAAM,QAAQ,IAC3B,EAAE,WAAW,GAAM,OAAO,IAC1B,kBAAC,OAAD,EAAA,UAAA,CACE,kBAAC,OAAD;UAAK,WAAU;oBAAe,EAAE,KAAK;UAAY,CAAA,EACjD,kBAAC,OAAD,EAAA,UAAA;UACG,EAAE,KAAK,MAAM,gBAAgB;UAAC;UAAG;UAAI;UAClC,EAAA,CAAA,CACF,EAAA,CAAA,CACP;;;OAGL,oBAAoB;AAElB,QADA,EAAgB,KAAK,EACrB,GAAM;;OAER,EAnCK,SAAS,EAAE,KAAK,MAAM,GAAG,IAmC9B;OAEJ;KAGD,KACC,EAAK,KAAK,GAAG,MAAM;MACjB,IAAM,CAAC,GAAI,KAAM,EAAS,SAAS,EAAE,EAC/B,IACJ,IAAQ,KACF,EAAE,KAAK,QAAQ,IAAS,KAAK,QAAQ,EAAE,GACzC;AAKN,aAFI,IAAQ,KAAK,EAAE,KAAK,QAAQ,IAAQ,MAAa,OAGnD,kBAAC,QAAD;OAEE,GAAG;OACH,GAAG;OACH,YAAW;OACX,kBAAiB;OACjB,WAAU;iBANZ,CAQG,GAAI,IACA;SARA,SAAS,EAAE,KAAK,MAAM,GAAG,IAQzB;OAET;KAGH,MAAY,WAAW,KAAe,IAAS,KAC9C,kBAAC,iBAAD;MACE,GAAG,CAAC,IAAS;MACb,GAAG,CAAC,IAAS;MACb,OAAO,IAAS;MAChB,QAAQ,IAAS;gBAEjB,kBAAC,OAAD;OAAK,WAAU;iBACZ;OACG,CAAA;MACQ,CAAA;KAEhB;;GACA,CAAA,EAGL,KAAe,kBAAC,GAAD,EAAc,OAAO,GAAW,CAAA,CAC/C,EAAA,CAAA,EAIJ,KACC,kBAAC,GAAD;GACE,OAAO,EAAK,KAAK,GAAG,OAAO;IACzB,OAAO,EAAE;IACT,OAAO,EAAO;IACf,EAAE;GACH,WAAU;GACV,CAAA,CAEO;;EAGhB;AACD,EAAS,cAAc;;;AC7NvB,IAAM,IAAqB;CAAE,UAAU;CAAG,MAAM;CAAoB,EAEvD,IAAY,EAAM,YAE3B,EACE,SACA,aAAU,QACV,WAAQ,KACR,YAAS,IACT,UACA,iBAAc,IACd,iBAAc,KACd,aAAU,IACV,cACA,GAAG,KAEL,MACG;CACL,IAAM,IAAgB,EAAa,GAAO,EAAE,EACtC,IAAgB,GAAkB,EAClC,IAAgB,KAAW,CAAC;AAElC,KAAI,CAAC,EAAK,OAAQ,QAAO;CAEzB,IAAM,IAAU,MAAY,QAAQ,IAAI,GAClC,IAAa,IAAQ,IAAU,GAC/B,IAAc,IAAS,IAAU,GAEjC,IAAS,GAAa,CACzB,OAAO,CAAC,GAAG,KAAK,IAAI,EAAK,SAAS,GAAG,EAAE,CAAC,CAAC,CACzC,MAAM,CAAC,GAAS,IAAU,EAAW,CAAC,EAEnC,IAAO,KAAK,IAAI,GAAG,EAAK,EACxB,IAAO,KAAK,IAAI,GAAG,EAAK,EACxB,IAAU,MAAS,IAAO,CAAC,IAAO,GAAG,IAAO,EAAE,GAAG,CAAC,GAAM,EAAK,EAE7D,IAAS,GAAa,CACzB,OAAO,EAAQ,CACf,MAAM,CAAC,IAAU,GAAa,EAAQ,CAAC;AAE1C,KAAI,MAAY,OAAO;EACrB,IACM,IAAW,KAAK,IACpB,IACC,IAAa,KAAU,EAAK,SAAS,MAAM,EAAK,OAClD,EAEK,IAAY,IAAU;AAE5B,SACE,kBAAC,OAAD;GACO;GACE;GACC;GACR,MAAK;GACL,cAAW;GACX,WAAW,EAAG,6BAA6B,EAAU;GACrD,GAAI;aAEH,EAAK,KAAK,GAAO,MAAM;IACtB,IAAM,IAAI,IAAU,KAAK,IAAW,IAC9B,IAAI,EAAO,EAAM;AAEvB,WACE,kBAAC,QAAD;KAEK;KACA;KACH,OAAO;KACP,QAPc,KAAK,IAAI,GAAG,IAAY,EAAE;KAQxC,IAAI,KAAK,IAAI,GAAG,IAAW,EAAE;KAC7B,MAAM;KACN,EAPK,EAOL;KAEJ;GACE,CAAA;;AAIV,KAAI,MAAY,QAAQ;EACtB,IAAM,IAAU,GAAc,CAC3B,MAAM,EAAe,CACrB,GAAG,GAAG,MAAM,EAAO,EAAE,CAAC,CACtB,GAAG,IAAU,EAAY,CACzB,IAAI,MAAM,EAAO,EAAE,CAAC,EAEjB,IAAU,GAAc,CAC3B,MAAM,EAAe,CACrB,GAAG,GAAG,MAAM,EAAO,EAAE,CAAC,CACtB,GAAG,MAAM,EAAO,EAAE,CAAC,EAEhB,IAAQ,EAAQ,EAAK,IAAI,IACzB,IAAQ,EAAQ,EAAK,IAAI,IAEzB,IAAQ,EAAO,EAAK,SAAS,EAAE,EAC/B,IAAQ,EAAO,EAAK,EAAK,SAAS,GAAG;AAE3C,SACE,kBAAC,OAAD;GACO;GACE;GACC;GACR,MAAK;GACL,cAAW;GACX,WAAW,EAAG,6BAA6B,EAAU;GACrD,GAAI;aAPN;IASE,kBAAC,QAAD;KAAM,GAAG;KAAO,MAAM;KAAe,SAAS;KAAO,CAAA;IACpD,IACC,kBAAC,EAAO,MAAR;KACE,GAAG;KACH,MAAK;KACL,QAAQ;KACK;KACb,gBAAe;KACf,eAAc;KACd,SAAS,EAAE,YAAY,GAAG;KAC1B,SAAS,EAAE,YAAY,GAAG;KAC1B,YAAY;KACZ,CAAA,GAEF,kBAAC,QAAD;KACE,GAAG;KACH,MAAK;KACL,QAAQ;KACK;KACb,gBAAe;KACf,eAAc;KACd,CAAA;IAEH,KACC,kBAAC,UAAD;KACE,IAAI;KACJ,IAAI;KACJ,GAAG,IAAc;KACjB,MAAM;KACN,CAAA;IAEA;;;CAUV,IAAM,IALU,GAAc,CAC3B,MAAM,EAAe,CACrB,GAAG,GAAG,MAAM,EAAO,EAAE,CAAC,CACtB,GAAG,MAAM,EAAO,EAAE,CAAC,CAEA,EAAK,IAAI,IAEzB,IAAQ,EAAO,EAAK,SAAS,EAAE,EAC/B,IAAQ,EAAO,EAAK,EAAK,SAAS,GAAG;AAE3C,QACE,kBAAC,OAAD;EACO;EACE;EACC;EACR,MAAK;EACL,cAAW;EACX,WAAW,EAAG,6BAA6B,EAAU;EACrD,GAAI;YAPN,CASG,IACC,kBAAC,EAAO,MAAR;GACE,GAAG;GACH,MAAK;GACL,QAAQ;GACK;GACb,gBAAe;GACf,eAAc;GACd,SAAS,EAAE,YAAY,GAAG;GAC1B,SAAS,EAAE,YAAY,GAAG;GAC1B,YAAY;GACZ,CAAA,GAEF,kBAAC,QAAD;GACE,GAAG;GACH,MAAK;GACL,QAAQ;GACK;GACb,gBAAe;GACf,eAAc;GACd,CAAA,EAEH,KACC,kBAAC,UAAD;GACE,IAAI;GACJ,IAAI;GACJ,GAAG,IAAc;GACjB,MAAM;GACN,CAAA,CAEA;;EAGT;AACD,EAAU,cAAc;;;AC7LxB,IAAM,KAAS,MAAiB,IAAM,KAAK,KAAM,KAEpC,IAAa,EAAM,YAE5B,EACE,UACA,SAAM,KACN,SAAM,GACN,UACA,eACA,UACA,gBAAa,+BACb,YAAS,KACT,gBAAa,MACb,cAAW,KACX,eAAY,IACZ,aAAU,IACV,cACA,GAAG,KAEL,MACG;CACL,IAAM,IAAgB,GAAkB,EAClC,IAAW,EAAsB,GAAe,IAAU,MAAM,EAAE,EAClE,IAAgB,KAAW,CAAC,GAE5B,IAAgB,EAAa,GAAO,EAAE,EACtC,IAAO,GACP,IAAS,IAAO,GAGhB,IAAe,KAAK,IAAI,KAAK,IAAI,GAAO,EAAI,EAAE,EAAI,EAClD,IAAgB,MAAQ,IAAM,KAAK,IAAe,MAAQ,IAAM,IAChE,IAAgB,KAAc,IAAW,KAAc,GAGvD,IACJ,OAAO,KAAe,aAClB,EAAW,EAAa,GACxB,OAAO,KAAe,WACpB,IACA,OAAO,EAAa,EAGtB,IAAiB,GAAc,CAClC,YAAY,IAAS,EAAU,CAC/B,YAAY,EAAO,CACnB,WAAW,EAAM,EAAW,CAAC,CAC7B,SAAS,EAAM,EAAS,CAAC,CACzB,aAAa,IAAY,EAAE,EAGxB,IAAiB,GAAc,CAClC,YAAY,IAAS,EAAU,CAC/B,YAAY,EAAO,CACnB,WAAW,EAAM,EAAW,CAAC,CAC7B,SAAS,EAAM,EAAc,CAAC,CAC9B,aAAa,IAAY,EAAE,EAExB,IAAY,EAAe,KAAyC,IAAI,IACxE,IAAY,EAAe,KAAyC,IAAI;AAE9E,QACE,kBAAC,EAAO,KAAR;EACO;EACL,WAAW,EAAG,qCAAqC,EAAU;EAC7D,GAAK,IACD;GAAE,SAAS;IAAE,SAAS;IAAG,OAAO;IAAM;GAAE,SAAS;IAAE,SAAS;IAAG,OAAO;IAAG;GAAE,YAAY,EAAO;GAAM,GACpG,EAAE;EACN,GAAI,EAAY,EAAM;EACtB,MAAK;EACL,iBAAe;EACf,iBAAe;EACf,iBAAe;EACf,cAAY,KAAS;YAErB,kBAAC,OAAD;GAAK,OAAO;GAAM,QAAQ;GAAM,MAAK;GAAM,eAAY;aACrD,kBAAC,KAAD;IAAG,WAAW,aAAa,EAAO,GAAG,EAAO;cAA5C;KAEE,kBAAC,QAAD;MAAM,GAAG;MAAW,MAAM;MAAc,CAAA;KAGxC,kBAAC,QAAD;MACE,GAAG;MACH,MAAM;MACN,OACE,IAAW,IACP,EAAE,YAAY,KAAK,EAAS,cAAc,GAC1C,KAAA;MAEN,CAAA;KAGF,kBAAC,QAAD;MACE,GAAG;MACH,GAAG,IAAQ,KAAK;MAChB,YAAW;MACX,kBAAiB;MACjB,WAAU;gBAET;MACI,CAAA;KAGN,KACC,kBAAC,QAAD;MACE,GAAG;MACH,GAAG;MACH,YAAW;MACX,kBAAiB;MACjB,WAAU;gBAET;MACI,CAAA;KAEP;;GACA,CAAA;EACK,CAAA;EAGhB;AACD,EAAW,cAAc;;;ACtHzB,IAAa,IAAa,EAAM,YAE5B,EACE,SACA,SACA,WACA,UAAU,GACV,YAAS,GACT,iBAAc,KACd,cAAW,IACX,YAAS,KACT,iBAAc,IACd,gBAAa,IACb,aAAU,IACV,cACA,cACA,GAAG,KAEL,MACG;CACL,IAAM,IAAe,EAAuB,KAAK,EAC3C,CAAC,GAAgB,KAAqB,EAAS,EAAE,EACjD,EAAE,YAAS,SAAM,YAAS,GAAiB,EAC3C,IAAgB,GAAkB,EAClC,IAAgB,KAAW,CAAC;AAElC,SAAgB;AACd,MAAI,CAAC,EAAa,QAAS;EAC3B,IAAM,IAAW,IAAI,gBAAgB,MAAY;GAC/C,IAAM,IAAQ,EAAQ;AACtB,GAAI,KAAO,EAAkB,EAAM,YAAY,MAAM;IACrD;AAEF,SADA,EAAS,QAAQ,EAAa,QAAQ,QACzB,EAAS,YAAY;IACjC,EAAE,CAAC;CAIN,IAAM,KADU,IAAiB,IAAI,KAAK,IAAI,GAAgB,EAAO,GAAG,KAC/C,IAAI,IAGvB,IAAS,EAAO,KAAK,GAAG,MAAM,EAAa,EAAE,OAAO,EAAE,CAAC,EAGvD,IACJ,KACA,KAAK,IACH,GAAG,EAAK,SAAS,MAAM,EAAO,KAAK,MAAM,OAAO,EAAE,EAAE,KAAK,IAAI,EAAE,CAAC,EAChE,EACD,EAGG,IAAc,IAAI,KAAK,KAAM,EAAK,QAGlC,IAAY,GAAoB,CACnC,QAAQ,MAAO,IAAS,IAAK,EAAS,CACtC,OAAO,GAAG,MAAM,IAAI,EAAW,CAC/B,MAAM,EAAkB,EAGrB,KAAmB,MACvB,EAAK,KAAK,GAAG,MAAM,OAAO,EAAK,KAAK,GAAW,IAAI,EAAE,EAGjD,KAAa,GAAmB,MAAkB;EACtD,IAAM,IAAQ,IAAa,IAAY,KAAK,KAAK,GAC3C,IAAK,IAAS,IAAS;AAC7B,SAAO;GACL,GAAG,IAAI,KAAK,IAAI,EAAM;GACtB,GAAG,IAAI,KAAK,IAAI,EAAM;GACvB;;AAGH,QACE,kBAAC,EAAO,KAAR;EACE,MAAM,MAAS;AAEb,GADC,EAA+D,UAAU,GACtE,OAAO,KAAQ,aAAY,EAAI,EAAK,GAC/B,MAAM,EAAsD,UAAU;;EAEjF,WAAW,EAAG,mBAAmB,EAAU;EAC3C,GAAK,IACD;GAAE,SAAS;IAAE,SAAS;IAAG,OAAO;IAAM;GAAE,SAAS;IAAE,SAAS;IAAG,OAAO;IAAG;GAAE,YAAY,EAAO;GAAM,GACpG,EAAE;EACN,GAAI,EAAY,EAAM;YAVxB,CAYG,IAAiB,KAChB,kBAAA,GAAA,EAAA,UAAA,CACE,kBAAC,OAAD;GACE,OAAO;GACC;GACR,MAAK;GACL,cAAY,KAAa;aAEzB,kBAAC,KAAD;IAAG,WAAW,aAAa,IAAiB,EAAE,GAAG,IAAS,EAAE;cAA5D;KAEG,MAAM,KAAK,EAAE,QAAQ,GAAQ,GAAG,GAAG,MAAM;MACxC,IAAM,IAAe,IAAS,KAAW,IAAI;AAO7C,aACE,kBAAC,WAAD;OAEU,QATG,EACZ,KAAK,GAAG,MAAM;QACb,IAAM,IAAQ,IAAa,IAAI,KAAK,KAAK;AACzC,eAAO,GAAG,IAAc,KAAK,IAAI,EAAM,CAAC,GAAG,IAAc,KAAK,IAAI,EAAM;SACxE,CACD,KAAK,IAAI;OAKR,MAAK;OACL,QAAO;OACP,iBAAgB;OAChB,aAAa;OACb,EANK,QAAQ,IAMb;OAEJ;KAGD,EAAK,KAAK,GAAG,MAAM;MAClB,IAAM,IAAQ,IAAa,IAAI,KAAK,KAAK;AAGzC,aACE,kBAAC,QAAD;OAEE,IAAI;OACJ,IAAI;OACJ,IAPM,IAAS,KAAK,IAAI,EAAM;OAQ9B,IAPM,IAAS,KAAK,IAAI,EAAM;OAQ9B,QAAO;OACP,aAAa;OACb,EAPK,QAAQ,IAOb;OAEJ;KAGD,EAAK,KAAK,GAAO,MAAM;MACtB,IAAM,IAAQ,IAAa,IAAI,KAAK,KAAK,GACnC,IAAc,IAAS,IACvB,IAAI,IAAc,KAAK,IAAI,EAAM,EACjC,IAAI,IAAc,KAAK,IAAI,EAAM,EAGnC,IAAyC;AAK7C,aAJI,KAAK,IAAI,KAAK,IAAI,EAAM,CAAC,GAAG,OAC9B,IAAa,KAAK,IAAI,EAAM,GAAG,IAAI,UAAU,QAI7C,kBAAC,QAAD;OAEK;OACA;OACS;OACZ,kBAAiB;OACjB,WAAU;iBAET;OACI,EARA,SAAS,IAQT;OAET;KAGD,MAAM,KAAK,EAAE,QAAQ,GAAQ,GAAG,GAAG,MAAM;MACxC,IAAM,IAAa,KAAK,MAAO,IAAW,KAAW,IAAI,GAAG,EACtD,IAAe,IAAS,KAAW,IAAI,IACvC,IAAQ,CAAC,KAAK,KAAK;AAGzB,aACE,kBAAC,QAAD;OAEK,GALG,IAAc,KAAK,IAAI,EAAM,GAAG;OAMnC,GALG,IAAc,KAAK,IAAI,EAAM;OAMnC,YAAW;OACX,kBAAiB;OACjB,WAAU;iBAET;OACI,EARA,eAAe,IAQf;OAET;KAGD,EAAO,KAAK,GAAG,MAAc;MAC5B,IAAM,IAAS,EAAgB,EAAE,IAAI,EAC/B,IAAQ,EAAU,EAAO;AAG/B,aAFK,IAGH,kBAAC,KAAD,EAAA,UAAA,CACE,kBAAC,QAAD;OACE,GAAG;OACH,MAAM,EAAO;OACA;OACb,QAAQ,EAAO;OACf,aAAa;OACb,gBAAe;OACf,CAAA,EAGD,KACC,EAAO,KAAK,GAAG,MAAM;OACnB,IAAM,EAAE,MAAG,SAAM,EAAU,GAAG,EAAE;AAChC,cACE,kBAAC,UAAD;QAEE,IAAI;QACJ,IAAI;QACJ,GAAG;QACH,MAAM,EAAO;QACb,QAAO;QACP,aAAa;QACb,WAAU;QACV,EARK,OAAO,EAAE,IAAI,GAAG,IAQrB;QAEJ,CACF,EAAA,EA3BI,EAAE,IA2BN,GA9Ba;OAgCnB;KAGD,KACC,EAAK,KAAK,GAAW,MAAM;MAGzB,IAAM,IAAQ,IAAa,IAAI,KAAK,KAAK;AAIzC,aACE,kBAAC,UAAD;OAEE,IANS,IAAS,KAAK,IAAI,EAAM;OAOjC,IANS,IAAS,KAAK,IAAI,EAAM;OAOjC,GAAG;OACH,MAAK;OACL,WAAU;OACV,cAAc,MAAM;QAClB,IAAM,IAAO,EAAE,cACZ,QAAQ,MAAM,EACb,uBAAuB;AAC3B,UACE,EAAE,WAAW,GAAM,QAAQ,IAC3B,EAAE,WAAW,GAAM,OAAO,IAC1B,kBAAC,OAAD,EAAA,UAAA,CACE,kBAAC,OAAD;SAAK,WAAU;mBAAe;SAAgB,CAAA,EAC7C,EAAO,KAAK,GAAG,MAAS;SACvB,IAAM,IAAM,OAAO,EAAK,KAAK,EAAE,KAAK,IAAI;AACxC,gBACE,kBAAC,OAAD;UAEE,WAAU;oBAFZ;WAIE,kBAAC,QAAD;YACE,WAAU;YACV,OAAO,EAAE,iBAAiB,EAAO,IAAO;YACxC,CAAA;WACF,kBAAC,QAAD;YAAM,WAAU;sBAAhB,CACG,EAAE,OAAM,IACJ;;WAAC;WACP,EAAI,gBAAgB;WACjB;YAXC,EAAE,IAWH;UAER,CACE,EAAA,CAAA,CACP;;OAEH,cAAc;OACd,EArCK,SAAS,IAqCd;OAEJ;KACF;;GACA,CAAA,EAGL,KAAe,kBAAC,GAAD,EAAc,OAAO,GAAW,CAAA,CAC/C,EAAA,CAAA,EAIJ,KACC,kBAAC,GAAD;GACE,OAAO,EAAO,KAAK,GAAG,OAAO;IAC3B,OAAO,EAAE;IACT,OAAO,EAAO;IACf,EAAE;GACH,WAAU;GACV,CAAA,CAEO;;EAGhB;AACD,EAAW,cAAc"}
@@ -18,7 +18,7 @@ var o = {
18
18
  icon: "h-4 w-4"
19
19
  }
20
20
  }, s = {
21
- default: "bg-surface-overlay shadow-sm",
21
+ default: "bg-surface-overlay shadow-raised",
22
22
  solid: "bg-accent-9",
23
23
  accent: "bg-accent-9"
24
24
  }, c = {
@@ -1 +1 @@
1
- {"version":3,"file":"segmented-control.js","names":[],"sources":["../../src/ui/segmented-control.tsx"],"sourcesContent":["'use client'\n\nimport * as React from 'react'\nimport { motion, LayoutGroup } from 'framer-motion'\nimport { cn } from './lib/utils'\n\n/* ── Types ─────────────────────────────────────────────────── */\n\nexport type SegmentedControlSize = 'sm' | 'md' | 'lg'\nexport type SegmentedControlVariant = 'default' | 'solid' | /** @deprecated Use `'solid'` instead. */ 'accent'\n\nexport interface SegmentedControlOption {\n id: string\n text: string\n /** Optional icon component rendered before the text label. */\n icon?: React.ComponentType<{ className?: string }>\n}\n\nexport interface SegmentedControlProps extends Omit<React.HTMLAttributes<HTMLDivElement>, 'onSelect'> {\n size?: SegmentedControlSize\n variant?: SegmentedControlVariant\n options: SegmentedControlOption[]\n selectedId: string\n onSelect: (id: string) => void\n disabled?: boolean\n}\n\n/* ── Size config ───────────────────────────────────────────── */\n\nconst sizeConfig = {\n sm: { button: 'h-7 px-ds-04 text-ds-sm', icon: 'h-3.5 w-3.5' },\n md: { button: 'h-8 px-ds-05 text-ds-md', icon: 'h-4 w-4' },\n lg: { button: 'h-10 px-ds-06 text-ds-md', icon: 'h-4 w-4' },\n} as const\n\n/* ── Pill styles per variant ───────────────────────────────── */\n\nconst pillStyles = {\n default: 'bg-surface-overlay shadow-sm',\n solid: 'bg-accent-9',\n /** @deprecated Use `solid` instead. */\n accent: 'bg-accent-9',\n} as const\n\nconst selectedTextStyles = {\n default: 'text-surface-fg',\n solid: 'text-accent-fg',\n /** @deprecated Use `solid` instead. */\n accent: 'text-accent-fg',\n} as const\n\n/* ── Spring config (snappy, minimal overshoot) ─────────────── */\n/* Intentionally softer than springs.snappy (500/30/0.5) for pill slide feel */\n\nconst pillSpring = { type: 'spring' as const, stiffness: 400, damping: 30 }\n\n/* ── SegmentedControl ──────────────────────────────────────── */\n\nconst SegmentedControl = React.forwardRef<HTMLDivElement, SegmentedControlProps>(\n function SegmentedControl(\n {\n size = 'md',\n variant = 'default',\n options,\n selectedId,\n onSelect,\n disabled = false,\n className,\n ...props\n },\n ref,\n ) {\n const instanceId = React.useId()\n const tablistRef = React.useRef<HTMLDivElement | null>(null)\n\n // Compose refs\n const mergedRef = React.useCallback(\n (node: HTMLDivElement | null) => {\n tablistRef.current = node\n if (typeof ref === 'function') ref(node)\n else if (ref) (ref as React.MutableRefObject<HTMLDivElement | null>).current = node\n },\n [ref],\n )\n\n // Keyboard navigation\n const handleKeyDown = (e: React.KeyboardEvent<HTMLDivElement>) => {\n if (disabled) return\n\n const currentIndex = options.findIndex((o) => o.id === selectedId)\n let nextIndex = currentIndex\n\n switch (e.key) {\n case 'ArrowLeft':\n e.preventDefault()\n nextIndex = currentIndex > 0 ? currentIndex - 1 : options.length - 1\n break\n case 'ArrowRight':\n e.preventDefault()\n nextIndex = currentIndex < options.length - 1 ? currentIndex + 1 : 0\n break\n case 'Home':\n e.preventDefault()\n nextIndex = 0\n break\n case 'End':\n e.preventDefault()\n nextIndex = options.length - 1\n break\n default:\n return\n }\n\n onSelect(options[nextIndex].id)\n requestAnimationFrame(() => {\n const buttons = tablistRef.current?.querySelectorAll<HTMLButtonElement>('[role=\"tab\"]')\n buttons?.[nextIndex]?.focus()\n })\n }\n\n const { button: buttonSize, icon: iconSize } = sizeConfig[size]\n\n return (\n <div\n ref={mergedRef}\n role=\"tablist\"\n tabIndex={-1}\n aria-label={props['aria-label'] ?? 'Segmented control'}\n onKeyDown={handleKeyDown}\n className={cn(\n 'inline-flex p-[3px] rounded-ds-lg',\n 'bg-surface-raised-hover border border-surface-border-subtle shadow-inset',\n disabled && 'opacity-action-disabled pointer-events-none',\n className,\n )}\n {...props}\n >\n <LayoutGroup id={instanceId}>\n {options.map((option) => {\n const isSelected = option.id === selectedId\n const OptionIcon = option.icon\n\n return (\n <button\n key={option.id}\n type=\"button\"\n role=\"tab\"\n aria-selected={isSelected}\n tabIndex={isSelected ? 0 : -1}\n disabled={disabled}\n onClick={() => onSelect(option.id)}\n className={cn(\n 'relative inline-flex items-center justify-center gap-ds-02 rounded-ds-md',\n 'font-medium transition-colors duration-fast-02 ease-productive-standard',\n 'outline-hidden focus-visible:ring-2 focus-visible:ring-accent-9 focus-visible:ring-offset-2',\n buttonSize,\n isSelected\n ? selectedTextStyles[variant]\n : 'text-surface-fg-muted hover:text-surface-fg',\n )}\n >\n {/* Sliding pill indicator */}\n {isSelected && (\n <motion.span\n layoutId=\"segment-pill\"\n className={cn(\n 'absolute inset-0 rounded-ds-md pointer-events-none',\n pillStyles[variant],\n )}\n transition={pillSpring}\n />\n )}\n\n {/* Content (above pill via z-index) */}\n {OptionIcon && (\n <OptionIcon className={cn('relative z-[1] shrink-0', iconSize)} />\n )}\n <span className=\"relative z-[1]\">{option.text}</span>\n </button>\n )\n })}\n </LayoutGroup>\n </div>\n )\n },\n)\nSegmentedControl.displayName = 'SegmentedControl'\n\n/* ── Exports ───────────────────────────────────────────────── */\n\nexport { SegmentedControl }\n"],"mappings":";;;;;;AA6BA,IAAM,IAAa;CACjB,IAAI;EAAE,QAAQ;EAA2B,MAAM;EAAe;CAC9D,IAAI;EAAE,QAAQ;EAA2B,MAAM;EAAW;CAC1D,IAAI;EAAE,QAAQ;EAA4B,MAAM;EAAW;CAC5D,EAIK,IAAa;CACjB,SAAS;CACT,OAAO;CAEP,QAAQ;CACT,EAEK,IAAqB;CACzB,SAAS;CACT,OAAO;CAEP,QAAQ;CACT,EAKK,IAAa;CAAE,MAAM;CAAmB,WAAW;CAAK,SAAS;CAAI,EAIrE,IAAmB,EAAM,WAC7B,SACE,EACE,UAAO,MACP,aAAU,WACV,YACA,eACA,aACA,cAAW,IACX,cACA,GAAG,KAEL,GACA;CACA,IAAM,IAAa,EAAM,OAAO,EAC1B,IAAa,EAAM,OAA8B,KAAK,EAGtD,IAAY,EAAM,aACrB,MAAgC;AAE/B,EADA,EAAW,UAAU,GACjB,OAAO,KAAQ,aAAY,EAAI,EAAK,GAC/B,MAAM,EAAsD,UAAU;IAEjF,CAAC,EAAI,CACN,EAGK,KAAiB,MAA2C;AAChE,MAAI,EAAU;EAEd,IAAM,IAAe,EAAQ,WAAW,MAAM,EAAE,OAAO,EAAW,EAC9D,IAAY;AAEhB,UAAQ,EAAE,KAAV;GACE,KAAK;AAEH,IADA,EAAE,gBAAgB,EAClB,IAAY,IAAe,IAAI,IAAe,IAAI,EAAQ,SAAS;AACnE;GACF,KAAK;AAEH,IADA,EAAE,gBAAgB,EAClB,IAAY,IAAe,EAAQ,SAAS,IAAI,IAAe,IAAI;AACnE;GACF,KAAK;AAEH,IADA,EAAE,gBAAgB,EAClB,IAAY;AACZ;GACF,KAAK;AAEH,IADA,EAAE,gBAAgB,EAClB,IAAY,EAAQ,SAAS;AAC7B;GACF,QACE;;AAIJ,EADA,EAAS,EAAQ,GAAW,GAAG,EAC/B,4BAA4B;AAE1B,IADgB,EAAW,SAAS,iBAAoC,iBAAe,IAC7E,IAAY,OAAO;IAC7B;IAGE,EAAE,QAAQ,GAAY,MAAM,MAAa,EAAW;AAE1D,QACE,kBAAC,OAAD;EACE,KAAK;EACL,MAAK;EACL,UAAU;EACV,cAAY,EAAM,iBAAiB;EACnC,WAAW;EACX,WAAW,EACT,qCACA,4EACA,KAAY,+CACZ,EACD;EACD,GAAI;YAEJ,kBAAC,GAAD;GAAa,IAAI;aACd,EAAQ,KAAK,MAAW;IACvB,IAAM,IAAa,EAAO,OAAO,GAC3B,IAAa,EAAO;AAE1B,WACE,kBAAC,UAAD;KAEE,MAAK;KACL,MAAK;KACL,iBAAe;KACf,UAAU,IAAa,IAAI;KACjB;KACV,eAAe,EAAS,EAAO,GAAG;KAClC,WAAW,EACT,4EACA,2EACA,+FACA,GACA,IACI,EAAmB,KACnB,8CACL;eAhBH;MAmBG,KACC,kBAAC,EAAO,MAAR;OACE,UAAS;OACT,WAAW,EACT,sDACA,EAAW,GACZ;OACD,YAAY;OACZ,CAAA;MAIH,KACC,kBAAC,GAAD,EAAY,WAAW,EAAG,2BAA2B,EAAS,EAAI,CAAA;MAEpE,kBAAC,QAAD;OAAM,WAAU;iBAAkB,EAAO;OAAY,CAAA;MAC9C;OAlCF,EAAO,GAkCL;KAEX;GACU,CAAA;EACV,CAAA;EAGX;AACD,EAAiB,cAAc"}
1
+ {"version":3,"file":"segmented-control.js","names":[],"sources":["../../src/ui/segmented-control.tsx"],"sourcesContent":["'use client'\n\nimport * as React from 'react'\nimport { motion, LayoutGroup } from 'framer-motion'\nimport { cn } from './lib/utils'\n\n/* ── Types ─────────────────────────────────────────────────── */\n\nexport type SegmentedControlSize = 'sm' | 'md' | 'lg'\nexport type SegmentedControlVariant = 'default' | 'solid' | /** @deprecated Use `'solid'` instead. */ 'accent'\n\nexport interface SegmentedControlOption {\n id: string\n text: string\n /** Optional icon component rendered before the text label. */\n icon?: React.ComponentType<{ className?: string }>\n}\n\nexport interface SegmentedControlProps extends Omit<React.HTMLAttributes<HTMLDivElement>, 'onSelect'> {\n size?: SegmentedControlSize\n variant?: SegmentedControlVariant\n options: SegmentedControlOption[]\n selectedId: string\n onSelect: (id: string) => void\n disabled?: boolean\n}\n\n/* ── Size config ───────────────────────────────────────────── */\n\nconst sizeConfig = {\n sm: { button: 'h-7 px-ds-04 text-ds-sm', icon: 'h-3.5 w-3.5' },\n md: { button: 'h-8 px-ds-05 text-ds-md', icon: 'h-4 w-4' },\n lg: { button: 'h-10 px-ds-06 text-ds-md', icon: 'h-4 w-4' },\n} as const\n\n/* ── Pill styles per variant ───────────────────────────────── */\n\nconst pillStyles = {\n default: 'bg-surface-overlay shadow-raised',\n solid: 'bg-accent-9',\n /** @deprecated Use `solid` instead. */\n accent: 'bg-accent-9',\n} as const\n\nconst selectedTextStyles = {\n default: 'text-surface-fg',\n solid: 'text-accent-fg',\n /** @deprecated Use `solid` instead. */\n accent: 'text-accent-fg',\n} as const\n\n/* ── Spring config (snappy, minimal overshoot) ─────────────── */\n/* Intentionally softer than springs.snappy (500/30/0.5) for pill slide feel */\n\nconst pillSpring = { type: 'spring' as const, stiffness: 400, damping: 30 }\n\n/* ── SegmentedControl ──────────────────────────────────────── */\n\nconst SegmentedControl = React.forwardRef<HTMLDivElement, SegmentedControlProps>(\n function SegmentedControl(\n {\n size = 'md',\n variant = 'default',\n options,\n selectedId,\n onSelect,\n disabled = false,\n className,\n ...props\n },\n ref,\n ) {\n const instanceId = React.useId()\n const tablistRef = React.useRef<HTMLDivElement | null>(null)\n\n // Compose refs\n const mergedRef = React.useCallback(\n (node: HTMLDivElement | null) => {\n tablistRef.current = node\n if (typeof ref === 'function') ref(node)\n else if (ref) (ref as React.MutableRefObject<HTMLDivElement | null>).current = node\n },\n [ref],\n )\n\n // Keyboard navigation\n const handleKeyDown = (e: React.KeyboardEvent<HTMLDivElement>) => {\n if (disabled) return\n\n const currentIndex = options.findIndex((o) => o.id === selectedId)\n let nextIndex = currentIndex\n\n switch (e.key) {\n case 'ArrowLeft':\n e.preventDefault()\n nextIndex = currentIndex > 0 ? currentIndex - 1 : options.length - 1\n break\n case 'ArrowRight':\n e.preventDefault()\n nextIndex = currentIndex < options.length - 1 ? currentIndex + 1 : 0\n break\n case 'Home':\n e.preventDefault()\n nextIndex = 0\n break\n case 'End':\n e.preventDefault()\n nextIndex = options.length - 1\n break\n default:\n return\n }\n\n onSelect(options[nextIndex].id)\n requestAnimationFrame(() => {\n const buttons = tablistRef.current?.querySelectorAll<HTMLButtonElement>('[role=\"tab\"]')\n buttons?.[nextIndex]?.focus()\n })\n }\n\n const { button: buttonSize, icon: iconSize } = sizeConfig[size]\n\n return (\n <div\n ref={mergedRef}\n role=\"tablist\"\n tabIndex={-1}\n aria-label={props['aria-label'] ?? 'Segmented control'}\n onKeyDown={handleKeyDown}\n className={cn(\n 'inline-flex p-[3px] rounded-ds-lg',\n 'bg-surface-raised-hover border border-surface-border-subtle shadow-inset',\n disabled && 'opacity-action-disabled pointer-events-none',\n className,\n )}\n {...props}\n >\n <LayoutGroup id={instanceId}>\n {options.map((option) => {\n const isSelected = option.id === selectedId\n const OptionIcon = option.icon\n\n return (\n <button\n key={option.id}\n type=\"button\"\n role=\"tab\"\n aria-selected={isSelected}\n tabIndex={isSelected ? 0 : -1}\n disabled={disabled}\n onClick={() => onSelect(option.id)}\n className={cn(\n 'relative inline-flex items-center justify-center gap-ds-02 rounded-ds-md',\n 'font-medium transition-colors duration-fast-02 ease-productive-standard',\n 'outline-hidden focus-visible:ring-2 focus-visible:ring-accent-9 focus-visible:ring-offset-2',\n buttonSize,\n isSelected\n ? selectedTextStyles[variant]\n : 'text-surface-fg-muted hover:text-surface-fg',\n )}\n >\n {/* Sliding pill indicator */}\n {isSelected && (\n <motion.span\n layoutId=\"segment-pill\"\n className={cn(\n 'absolute inset-0 rounded-ds-md pointer-events-none',\n pillStyles[variant],\n )}\n transition={pillSpring}\n />\n )}\n\n {/* Content (above pill via z-index) */}\n {OptionIcon && (\n <OptionIcon className={cn('relative z-[1] shrink-0', iconSize)} />\n )}\n <span className=\"relative z-[1]\">{option.text}</span>\n </button>\n )\n })}\n </LayoutGroup>\n </div>\n )\n },\n)\nSegmentedControl.displayName = 'SegmentedControl'\n\n/* ── Exports ───────────────────────────────────────────────── */\n\nexport { SegmentedControl }\n"],"mappings":";;;;;;AA6BA,IAAM,IAAa;CACjB,IAAI;EAAE,QAAQ;EAA2B,MAAM;EAAe;CAC9D,IAAI;EAAE,QAAQ;EAA2B,MAAM;EAAW;CAC1D,IAAI;EAAE,QAAQ;EAA4B,MAAM;EAAW;CAC5D,EAIK,IAAa;CACjB,SAAS;CACT,OAAO;CAEP,QAAQ;CACT,EAEK,IAAqB;CACzB,SAAS;CACT,OAAO;CAEP,QAAQ;CACT,EAKK,IAAa;CAAE,MAAM;CAAmB,WAAW;CAAK,SAAS;CAAI,EAIrE,IAAmB,EAAM,WAC7B,SACE,EACE,UAAO,MACP,aAAU,WACV,YACA,eACA,aACA,cAAW,IACX,cACA,GAAG,KAEL,GACA;CACA,IAAM,IAAa,EAAM,OAAO,EAC1B,IAAa,EAAM,OAA8B,KAAK,EAGtD,IAAY,EAAM,aACrB,MAAgC;AAE/B,EADA,EAAW,UAAU,GACjB,OAAO,KAAQ,aAAY,EAAI,EAAK,GAC/B,MAAM,EAAsD,UAAU;IAEjF,CAAC,EAAI,CACN,EAGK,KAAiB,MAA2C;AAChE,MAAI,EAAU;EAEd,IAAM,IAAe,EAAQ,WAAW,MAAM,EAAE,OAAO,EAAW,EAC9D,IAAY;AAEhB,UAAQ,EAAE,KAAV;GACE,KAAK;AAEH,IADA,EAAE,gBAAgB,EAClB,IAAY,IAAe,IAAI,IAAe,IAAI,EAAQ,SAAS;AACnE;GACF,KAAK;AAEH,IADA,EAAE,gBAAgB,EAClB,IAAY,IAAe,EAAQ,SAAS,IAAI,IAAe,IAAI;AACnE;GACF,KAAK;AAEH,IADA,EAAE,gBAAgB,EAClB,IAAY;AACZ;GACF,KAAK;AAEH,IADA,EAAE,gBAAgB,EAClB,IAAY,EAAQ,SAAS;AAC7B;GACF,QACE;;AAIJ,EADA,EAAS,EAAQ,GAAW,GAAG,EAC/B,4BAA4B;AAE1B,IADgB,EAAW,SAAS,iBAAoC,iBAAe,IAC7E,IAAY,OAAO;IAC7B;IAGE,EAAE,QAAQ,GAAY,MAAM,MAAa,EAAW;AAE1D,QACE,kBAAC,OAAD;EACE,KAAK;EACL,MAAK;EACL,UAAU;EACV,cAAY,EAAM,iBAAiB;EACnC,WAAW;EACX,WAAW,EACT,qCACA,4EACA,KAAY,+CACZ,EACD;EACD,GAAI;YAEJ,kBAAC,GAAD;GAAa,IAAI;aACd,EAAQ,KAAK,MAAW;IACvB,IAAM,IAAa,EAAO,OAAO,GAC3B,IAAa,EAAO;AAE1B,WACE,kBAAC,UAAD;KAEE,MAAK;KACL,MAAK;KACL,iBAAe;KACf,UAAU,IAAa,IAAI;KACjB;KACV,eAAe,EAAS,EAAO,GAAG;KAClC,WAAW,EACT,4EACA,2EACA,+FACA,GACA,IACI,EAAmB,KACnB,8CACL;eAhBH;MAmBG,KACC,kBAAC,EAAO,MAAR;OACE,UAAS;OACT,WAAW,EACT,sDACA,EAAW,GACZ;OACD,YAAY;OACZ,CAAA;MAIH,KACC,kBAAC,GAAD,EAAY,WAAW,EAAG,2BAA2B,EAAS,EAAI,CAAA;MAEpE,kBAAC,QAAD;OAAM,WAAU;iBAAkB,EAAO;OAAY,CAAA;MAC9C;OAlCF,EAAO,GAkCL;KAEX;GACU,CAAA;EACV,CAAA;EAGX;AACD,EAAiB,cAAc"}