{"version":3,"file":"index.cjs","sources":["../src/geometry.ts","../src/handle.ts","../src/motion-path.ts","../src/draw.ts","../src/morph.ts","../src/path-commands.ts","../src/morph-commands.ts"],"sourcesContent":["/**\n * A subset of SVGGeometryElement: anything that can report its length and sample\n * a point at a given arc distance. Real `<path>`/`<line>`/`<polyline>` elements\n * satisfy it natively; tests pass a plain object.\n */\nexport interface PathGeometry {\n  getTotalLength(): number\n  getPointAtLength(distance: number): { x: number; y: number }\n}\n\n/** A path source: a CSS selector or any geometry element/object. */\nexport type PathInput = string | PathGeometry\n\n/** A sampled point on a path: position plus the tangent direction (degrees). */\nexport interface PathPoint {\n  x: number\n  y: number\n  /** tangent direction in degrees, fed to autoRotate */\n  angle: number\n}\n\nexport interface SamplePathOptions {\n  /**\n   * Distance, as a fraction of total length, used to estimate the tangent angle\n   * from two neighbouring samples. Smaller is sharper but noisier. Default 0.001.\n   */\n  tangentEpsilon?: number\n}\n\nexport interface PathSampler {\n  /** Total path length, in the path's user units. */\n  readonly length: number\n  /** Point at progress t (clamped to 0..1), with the tangent angle. */\n  at(t: number): PathPoint\n}\n\nconst clamp01 = (t: number): number => (t < 0 ? 0 : t > 1 ? 1 : t)\n\n/** Resolve a {@link PathInput} to a geometry source (querySelector for strings). */\nexport function resolvePathGeometry(path: PathInput): PathGeometry {\n  if (typeof path !== 'string') return path\n  if (typeof document === 'undefined') {\n    throw new Error('@underlying/svg: a selector needs a DOM; pass an element on the server')\n  }\n  const element = document.querySelector(path)\n  if (element === null) throw new Error(`@underlying/svg: no element matches \"${path}\"`)\n  return element as unknown as PathGeometry\n}\n\n/**\n * Wrap a path in a length-normalized sampler: feed it t in 0..1 and read back the\n * point plus tangent angle. Total length is measured once; each `at()` is two\n * getPointAtLength() reads (the point, and a neighbour for the tangent).\n */\nexport function samplePath(path: PathInput, options: SamplePathOptions = {}): PathSampler {\n  const geometry = resolvePathGeometry(path)\n  const length = geometry.getTotalLength()\n  const eps = (options.tangentEpsilon ?? 0.001) * length || 0.0001\n\n  return {\n    length,\n    at(t) {\n      const distance = clamp01(t) * length\n      const point = geometry.getPointAtLength(distance)\n      const behind = geometry.getPointAtLength(Math.max(0, distance - eps))\n      const ahead = geometry.getPointAtLength(Math.min(length, distance + eps))\n      const angle = (Math.atan2(ahead.y - behind.y, ahead.x - behind.x) * 180) / Math.PI\n      return { x: point.x, y: point.y, angle }\n    },\n  }\n}\n","import type { Animatable, AnimationHandle, DecayOptions, SpringOptions, ToOptions } from '@underlying/core'\n\n/**\n * The physics verbs every @underlying/svg handle shares. They delegate straight\n * to the live driver Animatable, so a motionPath or a draw is interruptible and\n * retargetable at any moment - the same engine as the rest of core.\n */\nexport interface ScalarControls {\n  /** Spring the driver toward a target (0..1), interruptible, velocity conserved. */\n  spring(target: number, options?: SpringOptions): AnimationHandle\n  /** Glide on inertia from the current velocity, clamped to 0..1. */\n  decay(options?: DecayOptions): AnimationHandle\n  /** Duration/easing escape hatch - still interruptible. */\n  to(target: number, options?: ToOptions): AnimationHandle\n  /** Teleport the driver (no animation). */\n  set(value: number): void\n  /** Flick: seed a velocity (0..1 units/s) and let it decay to a stop on the path. */\n  flick(velocity: number, options?: Omit<DecayOptions, 'velocity'>): AnimationHandle\n  /** Freeze in place; position and velocity stay readable. */\n  stop(): void\n  /** Read the driver, 0..1. */\n  progress(): number\n  /** Stop, unbind, and restore the element to its pre-bind state. */\n  revert(): void\n}\n\n/** Build the shared verb surface around a driver value, plus a revert. */\nexport function scalarControls(value: Animatable, revert: () => void): ScalarControls {\n  return {\n    spring: (target, options) => value.spring(target, options),\n    decay: (options) => value.decay(options),\n    to: (target, options) => value.to(target, options),\n    set: (next) => value.set(next),\n    flick: (velocity, options) => value.decay({ min: 0, max: 1, ...options, velocity }),\n    stop: () => value.stop(),\n    progress: () => value.get(),\n    revert,\n  }\n}\n","import { animatable, getSharedScheduler, type Animatable, type Scheduler } from '@underlying/core'\nimport { samplePath, type PathInput, type SamplePathOptions } from './geometry'\nimport { scalarControls, type ScalarControls } from './handle'\n\nexport interface PathBindOptions extends SamplePathOptions {\n  /**\n   * Turn the element to face along the path. `true` aligns to the tangent;\n   * a number adds that many degrees of offset (e.g. `90` for a north-up icon).\n   */\n  autoRotate?: boolean | number\n  /** Scheduler driving the value and the style flush. Defaults to the shared one. */\n  scheduler?: Scheduler\n}\n\nexport interface MotionPathOptions extends PathBindOptions {\n  /** Initial progress, 0..1. Default 0. */\n  from?: number\n  /** Spring to this progress on creation - a familiar one-call form. */\n  to?: number\n}\n\n/**\n * Low-level binder: map a driver Animatable (0..1) onto an element's transform\n * along a path. You own the driver - spring, decay, or scrub it from scroll or a\n * timeline. Writes the current point synchronously at bind; returns an unbind fn.\n */\nexport function bindPath(\n  element: HTMLElement | SVGElement,\n  path: PathInput,\n  source: Animatable,\n  options: PathBindOptions = {},\n): () => void {\n  const scheduler = options.scheduler ?? getSharedScheduler()\n  const sampler = samplePath(path, options)\n  const autoRotate = options.autoRotate ?? false\n  const rotates = autoRotate !== false\n  const offset = typeof autoRotate === 'number' ? autoRotate : 0\n\n  let dirty = false\n  let cancelFlush: (() => void) | null = null\n\n  const write = (): void => {\n    const point = sampler.at(source.get())\n    const move = `translate3d(${point.x}px, ${point.y}px, 0)`\n    element.style.transform = rotates ? `${move} rotate(${point.angle + offset}deg)` : move\n  }\n\n  // One-shot render subscription per change burst: flush once on the next frame,\n  // then let the scheduler sleep - same pattern as core's bindStyle.\n  const scheduleFlush = (): void => {\n    if (cancelFlush !== null) return\n    cancelFlush = scheduler.subscribe(() => {\n      cancelFlush?.()\n      cancelFlush = null\n      if (dirty) {\n        dirty = false\n        write()\n      }\n    }, 'render')\n  }\n\n  const unsubscribe = source.on('change', () => {\n    dirty = true\n    scheduleFlush()\n  })\n  write()\n\n  return () => {\n    unsubscribe()\n    cancelFlush?.()\n    cancelFlush = null\n  }\n}\n\nexport interface MotionPath extends ScalarControls {\n  /** The live 0..1 driver. Compose it: scroll.scrub(mp.t), a timeline, a sequence. */\n  readonly t: Animatable\n}\n\n/**\n * Ride an element along an SVG path, physics-first. Progress `t` is a live\n * Animatable, so you can spring it, flick it down the path and let it settle,\n * retarget it mid-flight (velocity conserved), or hand `t` to scroll/timeline.\n * `autoRotate` turns the element to face along the path.\n */\nexport function motionPath(\n  element: HTMLElement | SVGElement,\n  path: PathInput,\n  options: MotionPathOptions = {},\n): MotionPath {\n  const t = animatable(\n    options.from ?? 0,\n    options.scheduler !== undefined ? { scheduler: options.scheduler } : undefined,\n  )\n  const previousTransform = element.style.transform\n  const unbind = bindPath(element, path, t, options)\n\n  const revert = (): void => {\n    t.stop()\n    unbind()\n    t.dispose()\n    element.style.transform = previousTransform\n  }\n\n  if (options.to !== undefined) t.spring(options.to)\n\n  return { t, ...scalarControls(t, revert) }\n}\n","import { animatable, getSharedScheduler, type Animatable, type Scheduler } from '@underlying/core'\nimport { scalarControls, type ScalarControls } from './handle'\n\n/** An element that can be stroke-drawn: reports its length and has a writable style. */\nexport interface DrawElement {\n  getTotalLength(): number\n  style: { strokeDasharray: string; strokeDashoffset: string }\n}\n\n/** A draw source: a CSS selector or a stroked geometry element. */\nexport type DrawInput = string | DrawElement\n\nexport interface DrawOptions {\n  /** Scheduler driving the value and the style flush. Defaults to the shared one. */\n  scheduler?: Scheduler\n  /** Initial draw fraction, 0..1 (0 hidden, 1 drawn). Default 0. */\n  from?: number\n  /** Spring to this fraction on creation - a familiar one-call form. */\n  to?: number\n}\n\nconst clamp01 = (v: number): number => (v < 0 ? 0 : v > 1 ? 1 : v)\n\nfunction resolveDrawElement(path: DrawInput): DrawElement {\n  if (typeof path !== 'string') return path\n  if (typeof document === 'undefined') {\n    throw new Error('@underlying/svg: a selector needs a DOM; pass an element on the server')\n  }\n  const element = document.querySelector(path)\n  if (element === null) throw new Error(`@underlying/svg: no element matches \"${path}\"`)\n  return element as unknown as DrawElement\n}\n\n/**\n * Low-level binder: map a driver Animatable (0..1) onto an element's stroke\n * draw-on (0 = hidden, 1 = fully drawn) via stroke-dasharray/offset. You own the\n * driver. Returns an unbind fn that restores the original dash properties.\n */\nexport function bindDraw(path: DrawInput, source: Animatable, options: DrawOptions = {}): () => void {\n  const scheduler = options.scheduler ?? getSharedScheduler()\n  const element = resolveDrawElement(path)\n  const length = element.getTotalLength()\n  const previousDasharray = element.style.strokeDasharray\n  const previousDashoffset = element.style.strokeDashoffset\n  element.style.strokeDasharray = String(length)\n\n  let dirty = false\n  let cancelFlush: (() => void) | null = null\n\n  const write = (): void => {\n    element.style.strokeDashoffset = String(length * (1 - clamp01(source.get())))\n  }\n  const scheduleFlush = (): void => {\n    if (cancelFlush !== null) return\n    cancelFlush = scheduler.subscribe(() => {\n      cancelFlush?.()\n      cancelFlush = null\n      if (dirty) {\n        dirty = false\n        write()\n      }\n    }, 'render')\n  }\n\n  const unsubscribe = source.on('change', () => {\n    dirty = true\n    scheduleFlush()\n  })\n  write()\n\n  return () => {\n    unsubscribe()\n    cancelFlush?.()\n    cancelFlush = null\n    element.style.strokeDasharray = previousDasharray\n    element.style.strokeDashoffset = previousDashoffset\n  }\n}\n\nexport interface Draw extends ScalarControls {\n  /** The live 0..1 draw fraction (0 hidden, 1 drawn). Compose it anywhere. */\n  readonly fraction: Animatable\n}\n\n/**\n * Draw a stroke on, physics-first. The fraction is a live Animatable - spring it\n * in (it can overshoot), interrupt it mid-draw, flick it, or scrub it from\n * scroll. Restores the original stroke-dash properties on revert().\n */\nexport function draw(path: DrawInput, options: DrawOptions = {}): Draw {\n  const fraction = animatable(\n    options.from ?? 0,\n    options.scheduler !== undefined ? { scheduler: options.scheduler } : undefined,\n  )\n  const unbind = bindDraw(path, fraction, options)\n\n  const revert = (): void => {\n    fraction.stop()\n    unbind()\n    fraction.dispose()\n  }\n\n  if (options.to !== undefined) fraction.spring(options.to)\n\n  return { fraction, ...scalarControls(fraction, revert) }\n}\n","import { animatable, getSharedScheduler, type Animatable, type Scheduler } from '@underlying/core'\nimport type { PathGeometry } from './geometry'\nimport { scalarControls, type ScalarControls } from './handle'\n\n/** A path element whose shape this package rewrites: geometry plus the `d` attribute. */\nexport interface MorphElement extends PathGeometry {\n  getAttribute(name: string): string | null\n  setAttribute(name: string, value: string): void\n}\n\n/** The shape to morph toward: raw path data (`\"M ...\"`) or any geometry/element. */\nexport type MorphTarget = string | PathGeometry\n\nexport interface MorphOptions {\n  scheduler?: Scheduler\n  /** Points sampled along each outline; more is smoother (and heavier). Default 64. */\n  samples?: number\n  /** Close the interpolated outline - for closed shapes (a star, a blob). */\n  closed?: boolean\n  /** Initial morph fraction, 0..1 (0 = original shape, 1 = target). Default 0. */\n  from?: number\n  /** Spring to this fraction on creation. */\n  to?: number\n}\n\ninterface Point {\n  x: number\n  y: number\n}\n\nconst round = (n: number): number => Math.round(n * 100) / 100\n\n// Resample an outline into `count` points evenly spaced by arc length. This is\n// what lets ANY two shapes morph: both become the same-length point list, no\n// matching of bezier commands required.\nconst samplePoints = (geometry: PathGeometry, count: number): Point[] => {\n  const length = geometry.getTotalLength()\n  const divisor = count > 1 ? count - 1 : 1\n  const points: Point[] = []\n  for (let i = 0; i < count; i += 1) {\n    const p = geometry.getPointAtLength((i / divisor) * length)\n    points.push({ x: p.x, y: p.y })\n  }\n  return points\n}\n\nconst toPathData = (points: Point[], closed: boolean): string => {\n  const first = points[0]\n  if (first === undefined) return ''\n  let d = `M ${round(first.x)} ${round(first.y)}`\n  for (let i = 1; i < points.length; i += 1) {\n    const p = points[i]\n    if (p !== undefined) d += ` L ${round(p.x)} ${round(p.y)}`\n  }\n  return closed ? `${d} Z` : d\n}\n\nconst targetGeometry = (target: MorphTarget): PathGeometry => {\n  if (typeof target !== 'string') return target\n  if (typeof document === 'undefined') {\n    throw new Error('@underlying/svg: morph target path data needs a DOM')\n  }\n  const path = document.createElementNS('http://www.w3.org/2000/svg', 'path')\n  path.setAttribute('d', target)\n  return path as unknown as PathGeometry\n}\n\nexport interface Morph extends ScalarControls {\n  /** The live 0..1 morph fraction (0 original, 1 target). Compose it anywhere. */\n  readonly fraction: Animatable\n}\n\n/**\n * Morph one path into another, physics-first. Both outlines are resampled into\n * `samples` points along their length and interpolated, so any two shapes morph\n * (no matching command structure needed). The fraction is a live Animatable -\n * spring it, scrub it, or grab it mid-morph. `revert()` restores the original `d`.\n */\nexport function morph(element: MorphElement, target: MorphTarget, options: MorphOptions = {}): Morph {\n  const count = Math.max(2, options.samples ?? 64)\n  const closed = options.closed ?? false\n  const fromPoints = samplePoints(element, count)\n  const toPoints = samplePoints(targetGeometry(target), count)\n  const originalD = element.getAttribute('d')\n\n  const scheduler = options.scheduler ?? getSharedScheduler()\n  const fraction = animatable(\n    options.from ?? 0,\n    options.scheduler !== undefined ? { scheduler: options.scheduler } : undefined,\n  )\n\n  let dirty = false\n  let cancelFlush: (() => void) | null = null\n\n  const write = (): void => {\n    const f = fraction.get()\n    const blended: Point[] = []\n    for (let i = 0; i < count; i += 1) {\n      const a = fromPoints[i]\n      const b = toPoints[i]\n      if (a === undefined || b === undefined) continue\n      blended.push({ x: a.x + (b.x - a.x) * f, y: a.y + (b.y - a.y) * f })\n    }\n    element.setAttribute('d', toPathData(blended, closed))\n  }\n  const scheduleFlush = (): void => {\n    if (cancelFlush !== null) return\n    cancelFlush = scheduler.subscribe(() => {\n      cancelFlush?.()\n      cancelFlush = null\n      if (dirty) {\n        dirty = false\n        write()\n      }\n    }, 'render')\n  }\n\n  const unsubscribe = fraction.on('change', () => {\n    dirty = true\n    scheduleFlush()\n  })\n  write()\n\n  const revert = (): void => {\n    fraction.stop()\n    unsubscribe()\n    cancelFlush?.()\n    cancelFlush = null\n    if (originalD !== null) element.setAttribute('d', originalD)\n    fraction.dispose()\n  }\n\n  if (options.to !== undefined) fraction.spring(options.to)\n\n  return { fraction, ...scalarControls(fraction, revert) }\n}\n","// Command-preserving morph geometry: parse a `d` string into absolute cubic\n// segments, reconcile two shapes to the same segment count by de Casteljau\n// subdivision (so original anchors - sharp corners - stay anchors), and\n// interpolate per anchor/control. No getPointAtLength: the curves and corners\n// survive instead of being resampled into a polyline.\n\nexport interface Pt {\n  readonly x: number\n  readonly y: number\n}\n\n/** One cubic bezier from the previous anchor: two controls and the end anchor. */\nexport interface Cubic {\n  readonly c1: Pt\n  readonly c2: Pt\n  readonly end: Pt\n}\n\n/** A subpath: a start anchor, a chain of cubics, and whether it closes. */\nexport interface Subpath {\n  readonly start: Pt\n  readonly segments: Cubic[]\n  readonly closed: boolean\n}\n\nconst round = (n: number): number => Math.round(n * 1000) / 1000\nconst lerp = (a: number, b: number, f: number): number => a + (b - a) * f\nconst lerpPt = (a: Pt, b: Pt, f: number): Pt => ({ x: lerp(a.x, b.x, f), y: lerp(a.y, b.y, f) })\n\n// A straight line as a cubic: controls at the third points, so it stays exactly\n// straight and a corner (anchor) remains an anchor.\nconst lineCubic = (from: Pt, to: Pt): Cubic => ({\n  c1: { x: from.x + (to.x - from.x) / 3, y: from.y + (to.y - from.y) / 3 },\n  c2: { x: from.x + (2 * (to.x - from.x)) / 3, y: from.y + (2 * (to.y - from.y)) / 3 },\n  end: to,\n})\n\n// Quadratic -> cubic (degree elevation): exact, no shape change.\nconst quadCubic = (from: Pt, control: Pt, to: Pt): Cubic => ({\n  c1: { x: from.x + (2 * (control.x - from.x)) / 3, y: from.y + (2 * (control.y - from.y)) / 3 },\n  c2: { x: to.x + (2 * (control.x - to.x)) / 3, y: to.y + (2 * (control.y - to.y)) / 3 },\n  end: to,\n})\n\nconst reflect = (point: Pt, about: Pt): Pt => ({ x: 2 * about.x - point.x, y: 2 * about.y - point.y })\n\nconst NUMBER = /[-+]?(?:\\d*\\.\\d+|\\d+\\.?)(?:[eE][-+]?\\d+)?/g\nconst COMMAND = /([astvzqmhlcASTVZQMHLC])([^astvzqmhlcASTVZQMHLC]*)/g\n\n// One arc arg group: rx ry x-rotation, then two single-digit flags (which may be\n// glued to their neighbours, e.g. \"0 0110 10\"), then the end point. The [01]\n// slots consume exactly one digit each, so packed flags parse correctly.\nconst N = String.raw`[-+]?(?:\\d*\\.\\d+|\\d+\\.?)(?:[eE][-+]?\\d+)?`\nconst ARC_ARGS = new RegExp(\n  `(${N})[\\\\s,]*(${N})[\\\\s,]*(${N})[\\\\s,]*([01])[\\\\s,]*([01])[\\\\s,]*(${N})[\\\\s,]*(${N})`,\n  'g',\n)\n\n/**\n * Convert one elliptical arc (endpoint parameterization) to a chain of cubic\n * beziers. Endpoint -> center per the SVG spec, then split into <=90 degree\n * sweeps each approximated by a cubic (the standard 4/3 tan(dθ/4) control offset).\n * Degenerate radii or a zero-length arc fall back to a straight line.\n */\nconst arcToCubics = (\n  from: Pt,\n  rxIn: number,\n  ryIn: number,\n  phiDeg: number,\n  largeArc: boolean,\n  sweep: boolean,\n  to: Pt,\n): Cubic[] => {\n  if (rxIn === 0 || ryIn === 0 || (from.x === to.x && from.y === to.y)) return [lineCubic(from, to)]\n  let rx = Math.abs(rxIn)\n  let ry = Math.abs(ryIn)\n  const phi = (phiDeg * Math.PI) / 180\n  const cosP = Math.cos(phi)\n  const sinP = Math.sin(phi)\n\n  // Step 1: transform to the ellipse's coordinate frame (endpoint delta halved).\n  const dx = (from.x - to.x) / 2\n  const dy = (from.y - to.y) / 2\n  const x1p = cosP * dx + sinP * dy\n  const y1p = -sinP * dx + cosP * dy\n\n  // Step 2: correct out-of-range radii so the ellipse can span the endpoints.\n  const lambda = (x1p * x1p) / (rx * rx) + (y1p * y1p) / (ry * ry)\n  if (lambda > 1) {\n    const s = Math.sqrt(lambda)\n    rx *= s\n    ry *= s\n  }\n\n  // Step 3: the center in the ellipse frame.\n  const rx2 = rx * rx\n  const ry2 = ry * ry\n  const num = rx2 * ry2 - rx2 * y1p * y1p - ry2 * x1p * x1p\n  const den = rx2 * y1p * y1p + ry2 * x1p * x1p\n  const co = (largeArc !== sweep ? 1 : -1) * Math.sqrt(Math.max(0, num / den))\n  const cxp = (co * rx * y1p) / ry\n  const cyp = (-co * ry * x1p) / rx\n\n  // Step 4: back to the user frame, and the start/sweep angles.\n  const cx = cosP * cxp - sinP * cyp + (from.x + to.x) / 2\n  const cy = sinP * cxp + cosP * cyp + (from.y + to.y) / 2\n  const angle = (ux: number, uy: number, vx: number, vy: number): number => {\n    const dot = ux * vx + uy * vy\n    const len = Math.sqrt((ux * ux + uy * uy) * (vx * vx + vy * vy))\n    let a = Math.acos(Math.min(1, Math.max(-1, dot / (len || 1))))\n    if (ux * vy - uy * vx < 0) a = -a\n    return a\n  }\n  const theta1 = angle(1, 0, (x1p - cxp) / rx, (y1p - cyp) / ry)\n  let dtheta = angle((x1p - cxp) / rx, (y1p - cyp) / ry, (-x1p - cxp) / rx, (-y1p - cyp) / ry)\n  if (!sweep && dtheta > 0) dtheta -= 2 * Math.PI\n  if (sweep && dtheta < 0) dtheta += 2 * Math.PI\n\n  // Step 5: one cubic per <=90 degree segment.\n  const count = Math.max(1, Math.ceil(Math.abs(dtheta) / (Math.PI / 2)))\n  const delta = dtheta / count\n  const alpha = (4 / 3) * Math.tan(delta / 4)\n  const cubics: Cubic[] = []\n  let t = theta1\n  let px = from.x\n  let py = from.y\n  for (let i = 0; i < count; i += 1) {\n    const t2 = t + delta\n    const cosT = Math.cos(t)\n    const sinT = Math.sin(t)\n    const cosT2 = Math.cos(t2)\n    const sinT2 = Math.sin(t2)\n    // Ellipse point at t2 (in the user frame).\n    const ex = cx + rx * cosP * cosT2 - ry * sinP * sinT2\n    const ey = cy + rx * sinP * cosT2 + ry * cosP * sinT2\n    // Tangent-scaled control points via alpha.\n    const d1x = -rx * cosP * sinT - ry * sinP * cosT\n    const d1y = -rx * sinP * sinT + ry * cosP * cosT\n    const d2x = -rx * cosP * sinT2 - ry * sinP * cosT2\n    const d2y = -rx * sinP * sinT2 + ry * cosP * cosT2\n    cubics.push({\n      c1: { x: px + alpha * d1x, y: py + alpha * d1y },\n      c2: { x: ex - alpha * d2x, y: ey - alpha * d2y },\n      end: { x: ex, y: ey },\n    })\n    t = t2\n    px = ex\n    py = ey\n  }\n  return cubics\n}\n\n/**\n * Parse a `d` string into subpaths of absolute cubic segments. Handles M, L, H,\n * V, C, S, Q, T, A, Z (and their relative forms). Elliptical arcs (A/a) are\n * converted to cubic beziers (<=90 degrees per segment).\n */\nexport function parsePath(d: string): Subpath[] {\n  const subpaths: Subpath[] = []\n  let segments: Cubic[] = []\n  let start: Pt = { x: 0, y: 0 }\n  let cur: Pt = { x: 0, y: 0 }\n  let prevCubicCtrl: Pt | null = null // last C/S second control, for S reflection\n  let prevQuadCtrl: Pt | null = null // last Q/T control, for T reflection\n  let open = false\n\n  const flush = (closed: boolean): void => {\n    if (open && segments.length > 0) subpaths.push({ start, segments, closed }) // drop empty moveto-only legs\n    segments = []\n    open = false\n  }\n  // A drawing command after Z (with no explicit M) starts a new subpath at the\n  // just-closed start point, which Z left in `cur`.\n  const ensureOpen = (): void => {\n    if (!open) {\n      open = true\n      start = cur\n    }\n  }\n\n  let match: RegExpExecArray | null\n  COMMAND.lastIndex = 0\n  while ((match = COMMAND.exec(d)) !== null) {\n    const code = match[1] as string\n    const nums = (match[2]?.match(NUMBER) ?? []).map(Number)\n    const rel = code === code.toLowerCase()\n    const upper = code.toUpperCase()\n    const ax = (v: number): number => (rel ? cur.x + v : v)\n    const ay = (v: number): number => (rel ? cur.y + v : v)\n    let i = 0\n    if (upper !== 'M' && upper !== 'Z') ensureOpen() // continue a new subpath after Z\n\n    if (upper === 'M') {\n      flush(false)\n      start = cur = { x: ax(nums[0] ?? 0), y: ay(nums[1] ?? 0) }\n      open = true\n      prevCubicCtrl = prevQuadCtrl = null\n      i = 2\n      // extra coordinate pairs after an M are implicit L\n      for (; i + 1 < nums.length; i += 2) {\n        const to = { x: ax(nums[i] ?? 0), y: ay(nums[i + 1] ?? 0) }\n        segments.push(lineCubic(cur, to))\n        cur = to\n      }\n      prevCubicCtrl = prevQuadCtrl = null\n    } else if (upper === 'Z') {\n      if (open) segments.push(lineCubic(cur, start)) // close with a straight segment if needed\n      flush(true)\n      cur = start\n      prevCubicCtrl = prevQuadCtrl = null\n    } else if (upper === 'L') {\n      for (; i + 1 < nums.length; i += 2) {\n        const to = { x: ax(nums[i] ?? 0), y: ay(nums[i + 1] ?? 0) }\n        segments.push(lineCubic(cur, to))\n        cur = to\n      }\n      prevCubicCtrl = prevQuadCtrl = null\n    } else if (upper === 'H') {\n      for (; i < nums.length; i += 1) {\n        const to = { x: ax(nums[i] ?? 0), y: cur.y }\n        segments.push(lineCubic(cur, to))\n        cur = to\n      }\n      prevCubicCtrl = prevQuadCtrl = null\n    } else if (upper === 'V') {\n      for (; i < nums.length; i += 1) {\n        const to = { x: cur.x, y: ay(nums[i] ?? 0) }\n        segments.push(lineCubic(cur, to))\n        cur = to\n      }\n      prevCubicCtrl = prevQuadCtrl = null\n    } else if (upper === 'C') {\n      for (; i + 5 < nums.length; i += 6) {\n        const c1 = { x: ax(nums[i] ?? 0), y: ay(nums[i + 1] ?? 0) }\n        const c2 = { x: ax(nums[i + 2] ?? 0), y: ay(nums[i + 3] ?? 0) }\n        const end = { x: ax(nums[i + 4] ?? 0), y: ay(nums[i + 5] ?? 0) }\n        segments.push({ c1, c2, end })\n        cur = end\n        prevCubicCtrl = c2\n      }\n      prevQuadCtrl = null\n    } else if (upper === 'S') {\n      for (; i + 3 < nums.length; i += 4) {\n        const c1 = prevCubicCtrl !== null ? reflect(prevCubicCtrl, cur) : cur\n        const c2 = { x: ax(nums[i] ?? 0), y: ay(nums[i + 1] ?? 0) }\n        const end = { x: ax(nums[i + 2] ?? 0), y: ay(nums[i + 3] ?? 0) }\n        segments.push({ c1, c2, end })\n        cur = end\n        prevCubicCtrl = c2\n      }\n      prevQuadCtrl = null\n    } else if (upper === 'Q') {\n      for (; i + 3 < nums.length; i += 4) {\n        const ctrl = { x: ax(nums[i] ?? 0), y: ay(nums[i + 1] ?? 0) }\n        const end = { x: ax(nums[i + 2] ?? 0), y: ay(nums[i + 3] ?? 0) }\n        segments.push(quadCubic(cur, ctrl, end))\n        cur = end\n        prevQuadCtrl = ctrl\n      }\n      prevCubicCtrl = null\n    } else if (upper === 'T') {\n      for (; i + 1 < nums.length; i += 2) {\n        const ctrl: Pt = prevQuadCtrl !== null ? reflect(prevQuadCtrl, cur) : cur\n        const end = { x: ax(nums[i] ?? 0), y: ay(nums[i + 1] ?? 0) }\n        segments.push(quadCubic(cur, ctrl, end))\n        cur = end\n        prevQuadCtrl = ctrl\n      }\n      prevCubicCtrl = null\n    } else if (upper === 'A') {\n      // Arc args need a flag-aware tokenizer (flags may be glued to neighbours),\n      // so re-scan the raw arg substring rather than the generic NUMBER split.\n      const rawArgs = match[2] ?? ''\n      ARC_ARGS.lastIndex = 0\n      let arc: RegExpExecArray | null\n      while ((arc = ARC_ARGS.exec(rawArgs)) !== null) {\n        const rx = Number(arc[1])\n        const ry = Number(arc[2])\n        const rot = Number(arc[3])\n        const largeArc = arc[4] === '1'\n        const sweep = arc[5] === '1'\n        const end = { x: ax(Number(arc[6])), y: ay(Number(arc[7])) }\n        for (const cubic of arcToCubics(cur, rx, ry, rot, largeArc, sweep, end)) segments.push(cubic)\n        cur = end\n      }\n      prevCubicCtrl = prevQuadCtrl = null\n    }\n  }\n  flush(false)\n  return subpaths\n}\n\n// Point on a cubic at t (de Casteljau) - used to measure arc length.\nconst cubicPointAt = (p0: Pt, cubic: Cubic, t: number): Pt => {\n  const a = lerpPt(p0, cubic.c1, t)\n  const b = lerpPt(cubic.c1, cubic.c2, t)\n  const c = lerpPt(cubic.c2, cubic.end, t)\n  const d = lerpPt(a, b, t)\n  const e = lerpPt(b, c, t)\n  return lerpPt(d, e, t)\n}\n\nconst dist = (a: Pt, b: Pt): number => Math.hypot(a.x - b.x, a.y - b.y)\n\nconst ARC_SAMPLES = 24\n\n// Approximate arc length by flattening into samples (chord sum). A curve that\n// folds back has a long arc but a short chord - measuring the arc divides it fairly.\nconst cubicArcLength = (from: Pt, cubic: Cubic): number => {\n  let len = 0\n  let prev = from\n  for (let i = 1; i <= ARC_SAMPLES; i += 1) {\n    const p = cubicPointAt(from, cubic, i / ARC_SAMPLES)\n    len += dist(prev, p)\n    prev = p\n  }\n  return len\n}\n\n// The t that bisects a cubic by ARC LENGTH (not the parametric midpoint), so a new\n// anchor lands at the geometric middle of the curve.\nconst tAtHalfArcLength = (from: Pt, cubic: Cubic): number => {\n  const cum: number[] = [0]\n  let len = 0\n  let prev = from\n  for (let i = 1; i <= ARC_SAMPLES; i += 1) {\n    const p = cubicPointAt(from, cubic, i / ARC_SAMPLES)\n    len += dist(prev, p)\n    cum.push(len)\n    prev = p\n  }\n  const half = len / 2\n  for (let i = 1; i <= ARC_SAMPLES; i += 1) {\n    if ((cum[i] as number) >= half) {\n      const seg = (cum[i] as number) - (cum[i - 1] as number)\n      const frac = seg > 0 ? (half - (cum[i - 1] as number)) / seg : 0\n      return (i - 1 + frac) / ARC_SAMPLES\n    }\n  }\n  return 0.5\n}\n\n// Split one cubic at t into two cubics that trace the same curve (de Casteljau).\nconst splitCubic = (from: Pt, cubic: Cubic, t: number): [Cubic, Cubic] => {\n  const p0 = from\n  const p1 = cubic.c1\n  const p2 = cubic.c2\n  const p3 = cubic.end\n  const a = lerpPt(p0, p1, t)\n  const b = lerpPt(p1, p2, t)\n  const c = lerpPt(p2, p3, t)\n  const d = lerpPt(a, b, t)\n  const e = lerpPt(b, c, t)\n  const mid = lerpPt(d, e, t)\n  return [\n    { c1: a, c2: d, end: mid },\n    { c1: e, c2: c, end: p3 },\n  ]\n}\n\n// Bring a subpath up to `count` segments by repeatedly splitting its longest\n// (by ARC LENGTH) segment at its arc-length midpoint. Original anchors are kept;\n// new anchors land ON the curves at their geometric middle, so a curvy segment is\n// divided fairly (a chord metric under-divides folds) while corners stay corners.\nconst subdivideTo = (subpath: Subpath, count: number): Subpath => {\n  if (subpath.segments.length >= count) return subpath\n  const segments = subpath.segments.slice()\n  const anchorsBefore: Pt[] = [subpath.start]\n  for (const seg of segments) anchorsBefore.push(seg.end)\n\n  while (segments.length < count) {\n    let longest = 0\n    let best = -1\n    for (let s = 0; s < segments.length; s += 1) {\n      const arc = cubicArcLength(anchorsBefore[s] as Pt, segments[s] as Cubic)\n      if (arc > longest) {\n        longest = arc\n        best = s\n      }\n    }\n    // Every segment is zero-length (a point-like subpath grown to `count`): keep\n    // splitting index 0 at the parametric midpoint so the count still reaches\n    // `count` and the loop terminates.\n    if (best < 0) best = 0\n    const from = anchorsBefore[best] as Pt\n    const seg = segments[best] as Cubic\n    const t = longest > 0 ? tAtHalfArcLength(from, seg) : 0.5\n    const [left, right] = splitCubic(from, seg, t)\n    segments.splice(best, 1, left, right)\n    anchorsBefore.splice(best + 1, 0, left.end)\n  }\n  return { start: subpath.start, segments, closed: subpath.closed }\n}\n\n/** Reconcile two subpaths to the same segment count (subdivide the smaller). */\nexport function reconcile(a: Subpath, b: Subpath): [Subpath, Subpath] {\n  const count = Math.max(a.segments.length, b.segments.length)\n  return [subdivideTo(a, count), subdivideTo(b, count)]\n}\n\n// The N ring anchors of a subpath (start + each segment end but the closing one).\nconst ringAnchors = (sp: Subpath): Pt[] => {\n  const anchors: Pt[] = [sp.start]\n  const upto = sp.closed ? sp.segments.length - 1 : sp.segments.length\n  for (let i = 0; i < upto; i += 1) anchors.push((sp.segments[i] as Cubic).end)\n  return anchors\n}\n\n/** The centroid of a point set (mean position). */\nconst centroid = (pts: Pt[]): Pt => {\n  let x = 0\n  let y = 0\n  for (const p of pts) {\n    x += p.x\n    y += p.y\n  }\n  const n = pts.length || 1\n  return { x: x / n, y: y / n }\n}\n\n// Center at the centroid and scale to unit RMS radius, so a correspondence cost\n// measures rotational/winding match independent of the shapes' size and position.\nconst normalizeAnchors = (pts: Pt[]): Pt[] => {\n  const c = centroid(pts)\n  let sum = 0\n  for (const p of pts) sum += (p.x - c.x) ** 2 + (p.y - c.y) ** 2\n  const scale = Math.sqrt(sum / (pts.length || 1)) || 1\n  return pts.map((p) => ({ x: (p.x - c.x) / scale, y: (p.y - c.y) / scale }))\n}\n\n// Reverse traversal: each cubic flips (controls swapped, direction reversed) and\n// the segment order reverses. Used to match opposite winding.\nconst reverseSubpath = (sp: Subpath): Subpath => {\n  const segs = sp.segments\n  const anchorsBefore: Pt[] = [sp.start]\n  for (const s of segs) anchorsBefore.push(s.end)\n  const reversed: Cubic[] = []\n  for (let i = segs.length - 1; i >= 0; i -= 1) {\n    const seg = segs[i] as Cubic\n    reversed.push({ c1: seg.c2, c2: seg.c1, end: anchorsBefore[i] as Pt })\n  }\n  return { start: anchorsBefore[segs.length] as Pt, segments: reversed, closed: sp.closed }\n}\n\n// Shift which anchor of a closed ring is the start (segments reorder cyclically).\nconst rotateSubpath = (sp: Subpath, offset: number): Subpath => {\n  const n = sp.segments.length\n  const k = ((offset % n) + n) % n\n  if (k === 0 || !sp.closed) return sp\n  const anchorsBefore: Pt[] = [sp.start]\n  for (const s of sp.segments) anchorsBefore.push(s.end)\n  const segments: Cubic[] = []\n  for (let i = 0; i < n; i += 1) segments.push(sp.segments[(k + i) % n] as Cubic)\n  return { start: anchorsBefore[k] as Pt, segments, closed: true }\n}\n\n/**\n * Pick the rotation and winding of `to` (a closed ring) that puts its anchors\n * closest to `from`'s - so the shape settles into place instead of spinning or\n * turning inside out. Both must already be reconciled to the same count. Open\n * subpaths have a fixed start/end, so they pass through unchanged.\n */\nexport function align(from: Subpath, to: Subpath): Subpath {\n  const n = from.segments.length\n  if (!from.closed || !to.closed || to.segments.length !== n) return to\n  // Match on centroid/scale-normalized anchors so a size or position difference\n  // between the two shapes doesn't swamp the rotational cost; the winning rotation\n  // and winding are then applied to the REAL `to` for interpolation.\n  const fromAnchors = normalizeAnchors(ringAnchors(from))\n  let best = to\n  let bestCost = Number.POSITIVE_INFINITY\n  for (const candidate of [to, reverseSubpath(to)]) {\n    const anchors = normalizeAnchors(ringAnchors(candidate))\n    for (let off = 0; off < n; off += 1) {\n      let cost = 0\n      for (let i = 0; i < n; i += 1) {\n        const a = fromAnchors[i] as Pt\n        const b = anchors[(i + off) % n] as Pt\n        cost += (a.x - b.x) ** 2 + (a.y - b.y) ** 2\n      }\n      if (cost < bestCost) {\n        bestCost = cost\n        best = rotateSubpath(candidate, off)\n      }\n    }\n  }\n  return best\n}\n\n/** Interpolate two reconciled subpaths (same segment count) at fraction f. */\nexport function lerpSubpath(a: Subpath, b: Subpath, f: number): Subpath {\n  const segments: Cubic[] = []\n  // reconcile() makes the counts equal; min() is a defensive guard so a\n  // mismatch can never dereference an undefined segment.\n  const n = Math.min(a.segments.length, b.segments.length)\n  for (let i = 0; i < n; i += 1) {\n    const sa = a.segments[i] as Cubic\n    const sb = b.segments[i] as Cubic\n    segments.push({ c1: lerpPt(sa.c1, sb.c1, f), c2: lerpPt(sa.c2, sb.c2, f), end: lerpPt(sa.end, sb.end, f) })\n  }\n  return { start: lerpPt(a.start, b.start, f), segments, closed: a.closed }\n}\n\n/** The centroid of a subpath's ring anchors - its rough position, for matching. */\nexport function subpathCentroid(sp: Subpath): Pt {\n  return centroid(ringAnchors(sp))\n}\n\n/** The (unsigned) enclosed area of a subpath's ring anchors - its rough size, for matching. */\nexport function subpathArea(sp: Subpath): number {\n  const a = ringAnchors(sp)\n  let area = 0\n  for (let i = 0; i < a.length; i += 1) {\n    const p = a[i] as Pt\n    const q = a[(i + 1) % a.length] as Pt\n    area += p.x * q.y - q.x * p.y\n  }\n  return Math.abs(area) / 2\n}\n\n/**\n * A degenerate copy of `sp` with every anchor and control collapsed onto `pt` -\n * so a surplus subpath can shrink to a point (or grow from one) rather than\n * being padded with an unrelated shape. Keeps the segment count for reconciliation.\n */\nexport function collapseToPoint(sp: Subpath, pt: Pt): Subpath {\n  return { start: pt, segments: sp.segments.map(() => ({ c1: pt, c2: pt, end: pt })), closed: sp.closed }\n}\n\n/**\n * True if a subpath has collapsed to a single point (every anchor and control\n * within `eps` of the start) - a not-yet-grown or fully-shrunk piece, which\n * should emit nothing so it never paints a dot on a stroked path.\n */\nexport function isPointSubpath(sp: Subpath, eps = 0.01): boolean {\n  const near = (p: Pt): boolean => Math.abs(p.x - sp.start.x) <= eps && Math.abs(p.y - sp.start.y) <= eps\n  for (const seg of sp.segments) {\n    if (!near(seg.c1) || !near(seg.c2) || !near(seg.end)) return false\n  }\n  return true\n}\n\n/** Emit a subpath as a cubic `d` string. */\nexport function subpathToD(subpath: Subpath): string {\n  let d = `M ${round(subpath.start.x)} ${round(subpath.start.y)}`\n  for (const seg of subpath.segments) {\n    d += ` C ${round(seg.c1.x)} ${round(seg.c1.y)} ${round(seg.c2.x)} ${round(seg.c2.y)} ${round(seg.end.x)} ${round(seg.end.y)}`\n  }\n  return subpath.closed ? `${d} Z` : d\n}\n","import { animatable, getSharedScheduler, type Scheduler } from '@underlying/core'\nimport { scalarControls } from './handle'\nimport type { Morph, MorphElement } from './morph'\nimport {\n  align,\n  collapseToPoint,\n  isPointSubpath,\n  lerpSubpath,\n  parsePath,\n  reconcile,\n  subpathArea,\n  subpathCentroid,\n  subpathToD,\n  type Subpath,\n} from './path-commands'\n\n/** The shape to morph toward: raw path data (`\"M ...\"`) or an element with a `d`. */\nexport type MorphCommandsTarget = string | { getAttribute(name: string): string | null }\n\nexport interface MorphCommandsOptions {\n  scheduler?: Scheduler\n  /** Initial morph fraction, 0..1 (0 = original shape, 1 = target). Default 0. */\n  from?: number\n  /** Spring to this fraction on creation. */\n  to?: number\n}\n\nconst dataOf = (target: MorphCommandsTarget): string =>\n  typeof target === 'string' ? target : (target.getAttribute('d') ?? '')\n\n/**\n * Pair from/to subpaths by SIMILARITY (centroid position + enclosed area) rather\n * than by index, so the parts of a multi-piece shape map to their nearest\n * counterpart. A greedy assignment over the normalized cost matrix; whichever side\n * has surplus subpaths, each unmatched one is paired with a collapsed point (its\n * own centroid) so it shrinks away (a surplus source) or grows in (a surplus target).\n */\nconst pairSubpaths = (fromSubs: Subpath[], toSubs: Subpath[]): Array<{ a: Subpath; b: Subpath }> => {\n  // Extent of all anchors, to make centroid distance comparable to area ratio.\n  const all = [...fromSubs, ...toSubs]\n  const cents = new Map<Subpath, ReturnType<typeof subpathCentroid>>()\n  const areas = new Map<Subpath, number>()\n  let minX = Infinity\n  let minY = Infinity\n  let maxX = -Infinity\n  let maxY = -Infinity\n  for (const sp of all) {\n    const c = subpathCentroid(sp)\n    cents.set(sp, c)\n    areas.set(sp, subpathArea(sp))\n    minX = Math.min(minX, c.x)\n    minY = Math.min(minY, c.y)\n    maxX = Math.max(maxX, c.x)\n    maxY = Math.max(maxY, c.y)\n  }\n  const diag = Math.hypot(maxX - minX, maxY - minY) || 1\n\n  const cost = (a: Subpath, b: Subpath): number => {\n    const ca = cents.get(a) as { x: number; y: number }\n    const cb = cents.get(b) as { x: number; y: number }\n    const posCost = Math.hypot(ca.x - cb.x, ca.y - cb.y) / diag\n    const areaA = areas.get(a) as number\n    const areaB = areas.get(b) as number\n    const areaCost = Math.abs(areaA - areaB) / (Math.max(areaA, areaB) || 1)\n    return posCost + 0.5 * areaCost\n  }\n\n  // Greedy: take the cheapest available pair until one side is exhausted.\n  const candidates: Array<{ i: number; j: number; c: number }> = []\n  for (let i = 0; i < fromSubs.length; i += 1) {\n    for (let j = 0; j < toSubs.length; j += 1) {\n      candidates.push({ i, j, c: cost(fromSubs[i] as Subpath, toSubs[j] as Subpath) })\n    }\n  }\n  candidates.sort((p, q) => p.c - q.c)\n  const usedFrom = new Set<number>()\n  const usedTo = new Set<number>()\n  const pairs: Array<{ a: Subpath; b: Subpath }> = []\n  for (const { i, j } of candidates) {\n    if (usedFrom.has(i) || usedTo.has(j)) continue\n    usedFrom.add(i)\n    usedTo.add(j)\n    const [a, b] = reconcile(fromSubs[i] as Subpath, toSubs[j] as Subpath)\n    pairs.push({ a, b: align(a, b) })\n  }\n  // Surplus source subpaths collapse to their own point (shrink away at f=1).\n  for (let i = 0; i < fromSubs.length; i += 1) {\n    if (usedFrom.has(i)) continue\n    const sp = fromSubs[i] as Subpath\n    pairs.push({ a: sp, b: collapseToPoint(sp, subpathCentroid(sp)) })\n  }\n  // Surplus target subpaths grow from their own point (appear by f=1).\n  for (let j = 0; j < toSubs.length; j += 1) {\n    if (usedTo.has(j)) continue\n    const sp = toSubs[j] as Subpath\n    pairs.push({ a: collapseToPoint(sp, subpathCentroid(sp)), b: sp })\n  }\n  return pairs\n}\n\n/**\n * Command-preserving morph. Unlike `morph()` (which resamples both outlines into\n * a polyline), this parses both `d` strings into cubic segments, subdivides the\n * sparser shape so the two match anchor-for-anchor (de Casteljau, so original\n * corners stay sharp), aligns closed rings by rotation and winding, and\n * interpolates each anchor and control. The result is real curves with crisp\n * corners. Elliptical arcs (A) are converted to cubics; segments are divided by\n * arc length, correspondence is matched on centroid/scale-normalized anchors, and\n * subpaths pair by similarity (surplus pieces shrink to / grow from a point). The\n * fraction is a live Animatable - spring it, scrub it, grab it mid-morph.\n * `revert()` restores the original `d`. For arbitrary blobby shapes where corner\n * preservation does not matter, `morph()` (resampling) is the simpler fallback.\n */\nexport function morphCommands(element: MorphElement, target: MorphCommandsTarget, options: MorphCommandsOptions = {}): Morph {\n  const originalD = element.getAttribute('d')\n  const fromSubs = parsePath(originalD ?? '')\n  const toSubs = parsePath(dataOf(target))\n\n  // If one side is empty, hold the other in place so fraction 0 still reproduces\n  // the original instead of blanking the element. Otherwise pair by similarity.\n  let pairs: Array<{ a: Subpath; b: Subpath }>\n  if (fromSubs.length === 0 || toSubs.length === 0) {\n    const held = fromSubs.length === 0 ? toSubs : fromSubs\n    pairs = held.map((sp) => reconcile(sp, sp)).map(([a, b]) => ({ a, b: align(a, b) }))\n  } else {\n    pairs = pairSubpaths(fromSubs, toSubs)\n  }\n\n  const scheduler = options.scheduler ?? getSharedScheduler()\n  const fraction = animatable(\n    options.from ?? 0,\n    options.scheduler !== undefined ? { scheduler: options.scheduler } : undefined,\n  )\n\n  let dirty = false\n  let cancelFlush: (() => void) | null = null\n\n  const write = (): void => {\n    const f = fraction.get()\n    // A piece that has fully shrunk (or not yet grown) emits nothing, so a\n    // collapsed subpath never paints a stroked dot and f=0 reproduces the source.\n    const parts: string[] = []\n    for (const { a, b } of pairs) {\n      const sp = lerpSubpath(a, b, f)\n      if (!isPointSubpath(sp)) parts.push(subpathToD(sp))\n    }\n    element.setAttribute('d', parts.join(' '))\n  }\n  const scheduleFlush = (): void => {\n    if (cancelFlush !== null) return\n    cancelFlush = scheduler.subscribe(() => {\n      cancelFlush?.()\n      cancelFlush = null\n      if (dirty) {\n        dirty = false\n        write()\n      }\n    }, 'render')\n  }\n\n  const unsubscribe = fraction.on('change', () => {\n    dirty = true\n    scheduleFlush()\n  })\n  write()\n\n  const revert = (): void => {\n    fraction.stop()\n    unsubscribe()\n    cancelFlush?.()\n    cancelFlush = null\n    if (originalD !== null) element.setAttribute('d', originalD)\n    fraction.dispose()\n  }\n\n  if (options.to !== undefined) fraction.spring(options.to)\n\n  return { fraction, ...scalarControls(fraction, revert) }\n}\n"],"names":["clamp01","resolvePathGeometry","path","element","samplePath","options","geometry","length","eps","t","distance","point","behind","ahead","angle","scalarControls","value","revert","target","next","velocity","bindPath","source","scheduler","getSharedScheduler","sampler","autoRotate","rotates","offset","dirty","cancelFlush","write","move","scheduleFlush","unsubscribe","motionPath","animatable","previousTransform","unbind","v","resolveDrawElement","bindDraw","previousDasharray","previousDashoffset","draw","fraction","round","n","samplePoints","count","divisor","points","i","p","toPathData","closed","first","d","targetGeometry","morph","fromPoints","toPoints","originalD","f","blended","a","b","lerp","lerpPt","lineCubic","from","to","quadCubic","control","reflect","about","NUMBER","COMMAND","N","ARC_ARGS","arcToCubics","rxIn","ryIn","phiDeg","largeArc","sweep","rx","ry","phi","cosP","sinP","dx","dy","x1p","y1p","lambda","s","rx2","ry2","num","den","co","cxp","cyp","cx","cy","ux","uy","vx","vy","dot","len","theta1","dtheta","delta","alpha","cubics","px","py","t2","cosT","sinT","cosT2","sinT2","ex","ey","d1x","d1y","d2x","d2y","parsePath","subpaths","segments","start","cur","prevCubicCtrl","prevQuadCtrl","open","flush","ensureOpen","match","code","nums","_a","rel","upper","ax","ay","c1","c2","end","ctrl","rawArgs","arc","rot","cubic","cubicPointAt","p0","e","dist","ARC_SAMPLES","cubicArcLength","prev","tAtHalfArcLength","cum","half","seg","frac","splitCubic","p1","p2","p3","c","mid","subdivideTo","subpath","anchorsBefore","longest","best","left","right","reconcile","ringAnchors","sp","anchors","upto","centroid","pts","x","y","normalizeAnchors","sum","scale","reverseSubpath","segs","reversed","rotateSubpath","k","align","fromAnchors","bestCost","candidate","off","cost","lerpSubpath","sa","sb","subpathCentroid","subpathArea","area","q","collapseToPoint","pt","isPointSubpath","near","subpathToD","dataOf","pairSubpaths","fromSubs","toSubs","all","cents","areas","minX","minY","maxX","maxY","diag","ca","cb","posCost","areaA","areaB","areaCost","candidates","j","usedFrom","usedTo","pairs","morphCommands","parts"],"mappings":"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"}