{"version":3,"file":"rationalCubic2d-CeHgpNht.mjs","names":["fromPolynomials","fromCoefficients","LinearPolynomial.make","fromEndpoints","isLinearCurve2d","derivative","Vector2.make","solve","LinearPolynomial.solve","solveAtX","Solution.match","LinearPolynomial.solveInverse","Solution.none","Solution.one","solveAtY","length","boundingBox","Interval2d.make","LinearPolynomial.unitRange","isMonotonic","LinearPolynomial.isMonotonic","isIncreasing","LinearPolynomial.isIncreasing","isDecreasing","LinearPolynomial.isDecreasing","fail","asMonotonic","asIncreasing","asDecreasing","fromPolynomials","internal.fromPolynomials","fromCoefficients","internal.fromCoefficients","internal.fromEndpoints","internal.isLinearCurve2d","derivative","internal.derivative","solve","internal.solve","length","internal.length","boundingBox","internal.boundingBox","solveAtX","internal.solveAtX","solveAtY","internal.solveAtY","isMonotonic","internal.isMonotonic","isIncreasing","internal.isIncreasing","isDecreasing","internal.isDecreasing","asMonotonic","internal.asMonotonic","asIncreasing","internal.asIncreasing","asDecreasing","internal.asDecreasing","fromPolynomials","fromCoefficients","QuadraticPolynomial.make","fromBezierPoints","isQuadraticCurve2d","solve","Vector2.make","QuadraticPolynomial.solve","solveAtX","Solution.clip","QuadraticPolynomial.solveInverse","Interval.unit","Solution.map","solveAtY","derivative","LinearCurve2d.fromPolynomials","QuadraticPolynomial.derivative","length","Interval.size","LinearCurve2d.length","LinearPolynomial.make","Interval.scaleShift","Interval.biunit","Vector2.magnitude","LinearCurve2d.solve","curvature","LinearCurve2d.derivative","Vector2.cross","boundingBox","Interval2d.make","QuadraticPolynomial.unitRange","isMonotonic","QuadraticPolynomial.isMonotonic","isIncreasing","QuadraticPolynomial.isIncreasing","isDecreasing","QuadraticPolynomial.isDecreasing","fail","asMonotonic","asIncreasing","asDecreasing","fromPolynomials","internal.fromPolynomials","fromCoefficients","internal.fromCoefficients","fromBezierPoints","internal.fromBezierPoints","internal.isQuadraticCurve2d","solve","internal.solve","length","internal.length","solveAtX","internal.solveAtX","solveAtY","internal.solveAtY","derivative","internal.derivative","curvature","internal.curvature","boundingBox","internal.boundingBox","isMonotonic","internal.isMonotonic","isIncreasing","internal.isIncreasing","isDecreasing","internal.isDecreasing","asMonotonic","internal.asMonotonic","asIncreasing","internal.asIncreasing","asDecreasing","internal.asDecreasing","fromPolynomials","fromCoefficients","CubicPolynomial.make","fromBezierPoints","Vector4.transpose","Characteristic.apply","Characteristic.cubicBezier","isCubicCurve2d","solve","Vector2.make","CubicPolynomial.solve","solveAtX","Solution.clip","CubicPolynomial.solveInverse","Interval.unit","Solution.map","solveAtY","QuadraticCurve2d.fromPolynomials","CubicPolynomial.derivative","length","Interval.size","QuadraticCurve2d.length","QuadraticPolynomial.make","Interval.scaleShift","Interval.biunit","Vector2.magnitude","QuadraticCurve2d.solve","curvature","LinearCurve2d.solve","QuadraticCurve2d.derivative","Vector2.cross","boundingBox","Interval2d.make","CubicPolynomial.unitRange","isMonotonic","CubicPolynomial.isMonotonic","isIncreasing","CubicPolynomial.isIncreasing","isDecreasing","CubicPolynomial.isDecreasing","fail","asMonotonic","asIncreasing","asDecreasing","fromPolynomials","internal.fromPolynomials","internal.fromCoefficients","fromBezierPoints","internal.fromBezierPoints","internal.isCubicCurve2d","solve","internal.solve","internal.length","solveAtX","internal.solveAtX","solveAtY","internal.solveAtY","internal.curvature","boundingBox","internal.boundingBox","isMonotonic","internal.isMonotonic","isIncreasing","internal.isIncreasing","isDecreasing","internal.isDecreasing","asMonotonic","internal.asMonotonic","asIncreasing","internal.asIncreasing","asDecreasing","internal.asDecreasing","isRationalCubicCurve2d","fromPolynomials","fromBezierPoints","Characteristic.apply","Characteristic.cubicBezier","Vector4.transpose","makeMonotonicEasing","CubicPolynomial.make","CubicPolynomial.roots","Solution.clip","Interval.unitOpen","CubicPolynomial.solve","solve","Vector2.make","solveAtX","Interval.unit","Solution.map","solveAtY","xMonotonicity","yMonotonicity","isMonotonicX","Monotonicity.isStrict","isIncreasingX","isDecreasingX","isMonotonicY","isIncreasingY","isDecreasingY","isMonotonic","isIncreasing","isDecreasing","asMonotonicX","asIncreasingX","asDecreasingX","asMonotonicY","asIncreasingY","asDecreasingY","asMonotonic","asIncreasing","asDecreasing","boundingBox","Interval2d.make","CubicPolynomial.unitRange","subdivide","Interval2d.union","CubicCurve2d.fromBezierPoints","CubicPolynomial.subdivide","Interval2d.fromVectors","CubicCurve2d.fromPolynomials","CubicCurve2d.boundingBox","Interval2d.maxDistance","approximateAsCubicCurves","internal.isRationalCubicCurve2d","internal.fromPolynomials","internal.fromBezierPoints","internal.makeMonotonicEasing","internal.solve","internal.solveAtX","internal.solveAtY","internal.subdivide","internal.boundingBox","internal.xMonotonicity","internal.yMonotonicity","internal.isMonotonicX","internal.isIncreasingX","internal.isDecreasingX","internal.isMonotonicY","internal.isIncreasingY","internal.isDecreasingY","internal.isMonotonic","internal.isIncreasing","internal.isDecreasing","internal.asMonotonicX","internal.asIncreasingX","internal.asDecreasingX","internal.asMonotonicY","internal.asIncreasingY","internal.asDecreasingY","internal.asMonotonic","internal.asIncreasing","internal.asDecreasing","internal.approximateAsCubicCurves"],"sources":["../../src/curve/linear2d.internal.ts","../../src/curve/linear2d.ts","../../src/curve/quadratic2d.internal.ts","../../src/curve/quadratic2d.ts","../../src/curve/cubic2d.internal.ts","../../src/curve/cubic2d.ts","../../src/curve/rationalCubic2d.internal.ts","../../src/curve/rationalCubic2d.ts"],"sourcesContent":["import * as Interval2d from '../interval/interval2d.ts'\nimport type * as Interval from '../interval/interval.ts'\nimport { dual, Pipeable } from '../utils.ts'\nimport * as LinearPolynomial from '../polynomial/linear.ts'\nimport type { Decreasing, Increasing, Monotonic } from '../polynomial/traits.ts'\nimport * as Solution from '../solution/solution.ts'\nimport * as Vector2 from '../vector/vector2.ts'\nimport type { LinearCurve2d } from './linear2d.ts'\n\nexport const LinearCurve2dTypeId: unique symbol = Symbol('curvy/curve/linear2d')\nexport type LinearCurve2dTypeId = typeof LinearCurve2dTypeId\n\n/** @internal */\nexport class LinearCurve2dImpl extends Pipeable implements LinearCurve2d<unknown, unknown> {\n  readonly [LinearCurve2dTypeId]: LinearCurve2dTypeId = LinearCurve2dTypeId\n\n  readonly x: LinearPolynomial.LinearPolynomial\n  readonly y: LinearPolynomial.LinearPolynomial\n\n  constructor(c0: LinearPolynomial.LinearPolynomial, c1: LinearPolynomial.LinearPolynomial) {\n    super()\n    this.x = c0\n    this.y = c1\n  }\n\n  get [0]() {\n    return this.x\n  }\n\n  get [1]() {\n    return this.y\n  }\n}\n\n/** @internal */\nexport const fromPolynomials: (\n  c0: LinearPolynomial.LinearPolynomial,\n  c1: LinearPolynomial.LinearPolynomial,\n) => LinearCurve2d = (c0, c1) => new LinearCurve2dImpl(c0, c1)\n\n/** @internal */\nexport const fromCoefficients: (c0: Vector2.Vector2, c1: Vector2.Vector2) => LinearCurve2d = (\n  c0,\n  c1,\n) => new LinearCurve2dImpl(LinearPolynomial.make(c0.x, c1.x), LinearPolynomial.make(c0.y, c1.y))\n\n// Linear Bernstein basis: B(t) = (1-t)·p0 + t·p1\n// Expanding to monomial form gives c0 = p0, c1 = p1 - p0.\n/** @internal */\nexport const fromEndpoints: (p0: Vector2.Vector2, p1: Vector2.Vector2) => LinearCurve2d = (\n  p0,\n  p1,\n) =>\n  new LinearCurve2dImpl(\n    LinearPolynomial.make(p0.x, p1.x - p0.x),\n    LinearPolynomial.make(p0.y, p1.y - p0.y),\n  )\n\n/** @internal */\nexport const isLinearCurve2d = (c: unknown): c is LinearCurve2d =>\n  typeof c === 'object' && c !== null && LinearCurve2dTypeId in c\n\n/** @internal */\nexport const derivative = (c: LinearCurve2d) => Vector2.make(c.x.c1, c.y.c1)\n\n/** @internal */\nexport const solve = dual<\n  (t: number) => (c: LinearCurve2d) => Vector2.Vector2,\n  (c: LinearCurve2d, t: number) => Vector2.Vector2\n>(2, (c: LinearCurve2d, t: number) =>\n  Vector2.make(LinearPolynomial.solve(c.x, t), LinearPolynomial.solve(c.y, t)),\n)\n\n// solveAtX: invert the x polynomial to find t, then evaluate y at t — only\n// returning the result when t lies in the curve's parameter domain [0, 1].\n// A linear curve crosses any vertical line at most once, so the result is\n// always 0 or 1 element.\n/** @internal */\nexport const solveAtX = dual(2, (c: LinearCurve2d, x: number) =>\n  Solution.match(LinearPolynomial.solveInverse(c.x, x), {\n    onNone: () => Solution.none,\n    onSome: ({ value: t }) =>\n      t < 0 || t > 1 ? Solution.none : Solution.one(LinearPolynomial.solve(c.y, t)),\n  }),\n)\n\n/** @internal */\nexport const solveAtY = dual(2, (c: LinearCurve2d, y: number) =>\n  Solution.match(LinearPolynomial.solveInverse(c.y, y), {\n    onNone: () => Solution.none,\n    onSome: ({ value: t }) =>\n      t < 0 || t > 1 ? Solution.none : Solution.one(LinearPolynomial.solve(c.x, t)),\n  }),\n)\n\n/** @internal */\nexport const length = dual(\n  2,\n  (c: LinearCurve2d, i: Interval.Interval) =>\n    Math.sqrt(c.x.c1 ** 2 + c.y.c1 ** 2) * Math.abs(i.end - i.start),\n)\n\n/** @internal */\nexport const boundingBox = (\n  c: LinearCurve2d,\n): Interval2d.Interval2d<Interval.Closed, Interval.Closed> =>\n  Interval2d.make(LinearPolynomial.unitRange(c.x), LinearPolynomial.unitRange(c.y))\n\n// Combined trait refiners — fan out the polynomial-level check across both\n// axes. For per-axis checks, users can call `LinearPolynomial.isMonotonic(c.x)`\n// directly.\n/** @internal */\nexport const isMonotonic = <XT, YT>(\n  c: LinearCurve2d<XT, YT>,\n): c is LinearCurve2d<XT & Monotonic, YT & Monotonic> =>\n  LinearPolynomial.isMonotonic(c.x) && LinearPolynomial.isMonotonic(c.y)\n\n/** @internal */\nexport const isIncreasing = <XT, YT>(\n  c: LinearCurve2d<XT, YT>,\n): c is LinearCurve2d<XT & Increasing, YT & Increasing> =>\n  LinearPolynomial.isIncreasing(c.x) && LinearPolynomial.isIncreasing(c.y)\n\n/** @internal */\nexport const isDecreasing = <XT, YT>(\n  c: LinearCurve2d<XT, YT>,\n): c is LinearCurve2d<XT & Decreasing, YT & Decreasing> =>\n  LinearPolynomial.isDecreasing(c.x) && LinearPolynomial.isDecreasing(c.y)\n\nconst fail = (m: string): never => {\n  throw new Error(m)\n}\n\n/** @internal */\nexport const asMonotonic = <XT, YT>(\n  c: LinearCurve2d<XT, YT>,\n): LinearCurve2d<XT & Monotonic, YT & Monotonic> =>\n  isMonotonic(c) ? c : fail('linear curve is not monotonic in both axes')\n\n/** @internal */\nexport const asIncreasing = <XT, YT>(\n  c: LinearCurve2d<XT, YT>,\n): LinearCurve2d<XT & Increasing, YT & Increasing> =>\n  isIncreasing(c) ? c : fail('linear curve is not increasing in both axes')\n\n/** @internal */\nexport const asDecreasing = <XT, YT>(\n  c: LinearCurve2d<XT, YT>,\n): LinearCurve2d<XT & Decreasing, YT & Decreasing> =>\n  isDecreasing(c) ? c : fail('linear curve is not decreasing in both axes')\n","import type { Interval2d } from '../interval/interval2d.ts'\nimport type { TwoDimensional } from '../dimensions.ts'\nimport type { Closed, Interval } from '../interval/interval.ts'\nimport type { Pipeable } from '../utils.ts'\nimport type { LinearPolynomial } from '../polynomial/linear.ts'\nimport type { Decreasing, Increasing, Monotonic } from '../polynomial/traits.ts'\nimport type * as Solution from '../solution/solution.ts'\nimport type { Vector2 } from '../vector/vector2.ts'\nimport type { LinearCurve2dTypeId } from './linear2d.internal.ts'\nimport * as internal from './linear2d.internal.ts'\n\nexport type { Monotonic, Increasing, Decreasing } from '../polynomial/traits.ts'\n\n/**\n * A linear curve in 2D space.\n *\n * All fields are readonly and immutable, and all operations create new instances.\n *\n * The two type parameters carry the trait sets of the curve's per-axis\n * polynomials. Refiners like `isMonotonic` lift each axis's monotonicity into\n * the curve's combined trait set.\n *\n * @since 1.0.0\n */\nexport interface LinearCurve2d<out XTraits = unknown, out YTraits = unknown>\n  extends Pipeable, TwoDimensional<LinearPolynomial<XTraits>, LinearPolynomial<YTraits>> {\n  readonly [LinearCurve2dTypeId]: LinearCurve2dTypeId\n}\n\n/**\n * Creates a new `LinearCurve2d` instance from polynomial parameters.\n *\n * @param x - The x polynomial.\n * @param y - The y polynomial.\n * @returns A new `LinearCurve2d` instance.\n * @since 1.0.0\n */\nexport const fromPolynomials: (x: LinearPolynomial, y: LinearPolynomial) => LinearCurve2d =\n  internal.fromPolynomials\n\n/**\n * Creates a new `LinearCurve2d` instance from monomial coefficient vectors.\n *\n * Each argument bundles the per-axis coefficient at the given power: `c0`\n * holds the x⁰ term, `c1` holds the x¹ term. The resulting curve evaluates to\n * `c0 + c1·t` per axis.\n *\n * @param c0 - The x⁰ coefficients (x and y).\n * @param c1 - The x¹ coefficients (x and y).\n * @returns A new `LinearCurve2d` instance.\n * @since 2.0.0\n */\nexport const fromCoefficients: (c0: Vector2, c1: Vector2) => LinearCurve2d =\n  internal.fromCoefficients\n\n/**\n * Creates a new `LinearCurve2d` instance from a pair of endpoints.\n *\n * `p0` is the curve at `t = 0`, `p1` is the curve at `t = 1`. The\n * implementation converts to the curve's internal monomial form (slope-form\n * polynomial in `t`) in closed form.\n *\n * @param p0 - The curve's start point.\n * @param p1 - The curve's end point.\n * @returns A new `LinearCurve2d` instance whose curve matches the line from `p0` to `p1`.\n * @since 2.0.0\n */\nexport const fromEndpoints: (p0: Vector2, p1: Vector2) => LinearCurve2d = internal.fromEndpoints\n\n/**\n * Checks if a value is a `LinearCurve2d`.\n *\n * @param c - The value to check.\n * @returns `true` if the value is a `LinearCurve2d`, `false` otherwise.\n * @since 1.0.0\n */\nexport const isLinearCurve2d: (c: unknown) => c is LinearCurve2d = internal.isLinearCurve2d\n\n/**\n * Gets the derivative of a linear curve as a vector\n *\n * @param c - The linear curve to get the derivative of.\n * @returns The derivative of the linear curve as a vector.\n * @since 1.0.0\n */\nexport const derivative: (c: LinearCurve2d) => Vector2 = internal.derivative\n\nexport const solve: {\n  /**\n   * Solves the linear curve for a given parameter t.\n   *\n   * @param t - The parameter value.\n   * @returns A function that takes a linear curve and returns the point on the curve at parameter t.\n   * @since 1.0.0\n   */\n  (t: number): (c: LinearCurve2d) => Vector2\n  /**\n   * Solves the linear curve for a given parameter t.\n   *\n   * @param c - The linear curve to solve.\n   * @param t - The parameter value.\n   * @returns The point on the curve at parameter t.\n   * @since 1.0.0\n   */\n  (c: LinearCurve2d, t: number): Vector2\n} = internal.solve\n\nexport const length: {\n  /**\n   * Calculates (approximates) the length of a linear curve.\n   *\n   * @param c - The linear curve to calculate the length of.\n   * @param i - The interval to calculate the length over.\n   * @returns The length of the linear curve over the given interval.\n   * @since 1.0.0\n   */\n  (c: LinearCurve2d, i: Interval): number\n  /**\n   * Calculates (approximates) the length of a linear curve.\n   *\n   * @param i - The interval to calculate the length over.\n   * @returns A function that takes a linear curve and returns the length of the linear curve over the given interval.\n   * @since 1.0.0\n   */\n  (i: Interval): (c: LinearCurve2d) => number\n} = internal.length\n\n/**\n * Computes the axis-aligned bounding box of the curve over its parameter\n * domain `[0, 1]`. For a linear curve this is the closed box enclosing the\n * two endpoints.\n *\n * @param c - The linear curve.\n * @returns A closed `Box2d` enclosing the curve.\n * @since 2.0.0\n */\nexport const boundingBox: (c: LinearCurve2d) => Interval2d<Closed, Closed> = internal.boundingBox\n\nexport const solveAtX: {\n  /**\n   * Evaluates the curve's y value at a given x. A linear curve crosses any\n   * vertical line at most once (within the curve's parameter domain `[0, 1]`),\n   * so the result is at most one y. Returns the empty tuple when x is outside\n   * the curve's range or when the curve's x polynomial is constant.\n   *\n   * @param c - The linear curve.\n   * @param x - The x coordinate.\n   * @returns The y value at x, or empty when x is undefined for this curve.\n   * @since 2.0.0\n   */\n  <XT, YT>(c: LinearCurve2d<XT, YT>, x: number): Solution.AtMostOne<number>\n  /** @since 2.0.0 */\n  (x: number): <XT, YT>(c: LinearCurve2d<XT, YT>) => Solution.AtMostOne<number>\n} = internal.solveAtX as never\n\nexport const solveAtY: {\n  /**\n   * Evaluates the curve's x value at a given y. A linear curve crosses any\n   * horizontal line at most once (within the curve's parameter domain\n   * `[0, 1]`), so the result is at most one x.\n   *\n   * @param c - The linear curve.\n   * @param y - The y coordinate.\n   * @returns The x value at y, or empty when y is undefined for this curve.\n   * @since 2.0.0\n   */\n  <XT, YT>(c: LinearCurve2d<XT, YT>, y: number): Solution.AtMostOne<number>\n  /** @since 2.0.0 */\n  (y: number): <XT, YT>(c: LinearCurve2d<XT, YT>) => Solution.AtMostOne<number>\n} = internal.solveAtY as never\n\n/**\n * Type-narrowing predicate: refines both axes' traits to include `Monotonic`\n * when both the x and y polynomials are strictly monotonic. When both axes\n * are monotonic, the curve is invertible in either direction.\n *\n * For checking only one axis, call the polynomial-level refiner directly:\n * `LinearPolynomial.isMonotonic(curve.x)`.\n *\n * @since 2.0.0\n */\nexport const isMonotonic: <XT, YT>(\n  c: LinearCurve2d<XT, YT>,\n) => c is LinearCurve2d<XT & Monotonic, YT & Monotonic> = internal.isMonotonic\n\n/**\n * Type-narrowing predicate: refines both axes' traits to include `Increasing`.\n *\n * @since 2.0.0\n */\nexport const isIncreasing: <XT, YT>(\n  c: LinearCurve2d<XT, YT>,\n) => c is LinearCurve2d<XT & Increasing, YT & Increasing> = internal.isIncreasing\n\n/**\n * Type-narrowing predicate: refines both axes' traits to include `Decreasing`.\n *\n * @since 2.0.0\n */\nexport const isDecreasing: <XT, YT>(\n  c: LinearCurve2d<XT, YT>,\n) => c is LinearCurve2d<XT & Decreasing, YT & Decreasing> = internal.isDecreasing\n\n/**\n * Asserts monotonicity in both axes, throwing on failure.\n *\n * @since 2.0.0\n */\nexport const asMonotonic: <XT, YT>(\n  c: LinearCurve2d<XT, YT>,\n) => LinearCurve2d<XT & Monotonic, YT & Monotonic> = internal.asMonotonic\n\n/**\n * Asserts that both axes are strictly increasing, throwing on failure.\n *\n * @since 2.0.0\n */\nexport const asIncreasing: <XT, YT>(\n  c: LinearCurve2d<XT, YT>,\n) => LinearCurve2d<XT & Increasing, YT & Increasing> = internal.asIncreasing\n\n/**\n * Asserts that both axes are strictly decreasing, throwing on failure.\n *\n * @since 2.0.0\n */\nexport const asDecreasing: <XT, YT>(\n  c: LinearCurve2d<XT, YT>,\n) => LinearCurve2d<XT & Decreasing, YT & Decreasing> = internal.asDecreasing\n","import * as Interval2d from '../interval/interval2d.ts'\nimport * as Interval from '../interval/interval.ts'\nimport type { Decreasing, Increasing, Monotonic } from '../polynomial/traits.ts'\nimport {\n  GL32_W0,\n  GL32_W1,\n  GL32_W2,\n  GL32_W3,\n  GL32_W4,\n  GL32_W5,\n  GL32_W6,\n  GL32_W7,\n  GL32_W8,\n  GL32_W9,\n  GL32_W10,\n  GL32_W11,\n  GL32_W12,\n  GL32_W13,\n  GL32_W14,\n  GL32_W15,\n  GL32_X0,\n  GL32_X1,\n  GL32_X2,\n  GL32_X3,\n  GL32_X4,\n  GL32_X5,\n  GL32_X6,\n  GL32_X7,\n  GL32_X8,\n  GL32_X9,\n  GL32_X10,\n  GL32_X11,\n  GL32_X12,\n  GL32_X13,\n  GL32_X14,\n  GL32_X15,\n} from '../length.ts'\nimport { dual, Pipeable } from '../utils.ts'\nimport * as LinearPolynomial from '../polynomial/linear.ts'\nimport * as QuadraticPolynomial from '../polynomial/quadratic.ts'\nimport * as Solution from '../solution/solution.ts'\nimport * as Vector2 from '../vector/vector2.ts'\nimport * as LinearCurve2d from './linear2d.ts'\nimport type { QuadraticCurve2d } from './quadratic2d.ts'\n\nexport const QuadraticCurve2dTypeId: unique symbol = Symbol('curvy/curve/quadratic2d')\nexport type QuadraticCurve2dTypeId = typeof QuadraticCurve2dTypeId\n\n/** @internal */\nexport class QuadraticCurve2dImpl extends Pipeable implements QuadraticCurve2d<unknown, unknown> {\n  readonly [QuadraticCurve2dTypeId]: QuadraticCurve2dTypeId = QuadraticCurve2dTypeId\n\n  readonly x: QuadraticPolynomial.QuadraticPolynomial\n  readonly y: QuadraticPolynomial.QuadraticPolynomial\n\n  constructor(\n    c0: QuadraticPolynomial.QuadraticPolynomial,\n    c1: QuadraticPolynomial.QuadraticPolynomial,\n  ) {\n    super()\n    this.x = c0\n    this.y = c1\n  }\n\n  get [0]() {\n    return this.x\n  }\n\n  get [1]() {\n    return this.y\n  }\n}\n\n/** @internal */\nexport const fromPolynomials: (\n  c0: QuadraticPolynomial.QuadraticPolynomial,\n  c1: QuadraticPolynomial.QuadraticPolynomial,\n) => QuadraticCurve2d = (c0, c1) => new QuadraticCurve2dImpl(c0, c1)\n\n/** @internal */\nexport const fromCoefficients: (\n  c0: Vector2.Vector2,\n  c1: Vector2.Vector2,\n  c2: Vector2.Vector2,\n) => QuadraticCurve2d = (c0, c1, c2) =>\n  new QuadraticCurve2dImpl(\n    QuadraticPolynomial.make(c0.x, c1.x, c2.x),\n    QuadraticPolynomial.make(c0.y, c1.y, c2.y),\n  )\n\n// Quadratic Bernstein basis: B(t) = (1-t)²·p0 + 2(1-t)t·p1 + t²·p2\n// Expanding to monomial form gives:\n//   c0 = p0\n//   c1 = -2p0 + 2p1\n//   c2 = p0 - 2p1 + p2\n/** @internal */\nexport const fromBezierPoints: (\n  p0: Vector2.Vector2,\n  p1: Vector2.Vector2,\n  p2: Vector2.Vector2,\n) => QuadraticCurve2d = (p0, p1, p2) =>\n  new QuadraticCurve2dImpl(\n    QuadraticPolynomial.make(p0.x, -2 * p0.x + 2 * p1.x, p0.x - 2 * p1.x + p2.x),\n    QuadraticPolynomial.make(p0.y, -2 * p0.y + 2 * p1.y, p0.y - 2 * p1.y + p2.y),\n  )\n\n/** @internal */\nexport const isQuadraticCurve2d = (c: unknown): c is QuadraticCurve2d =>\n  typeof c === 'object' && c !== null && QuadraticCurve2dTypeId in c\n\n/** @internal */\nexport const solve = dual<\n  (t: number) => (c: QuadraticCurve2d) => Vector2.Vector2,\n  (c: QuadraticCurve2d, t: number) => Vector2.Vector2\n>(2, (c: QuadraticCurve2d, t: number) =>\n  Vector2.make(QuadraticPolynomial.solve(c.x, t), QuadraticPolynomial.solve(c.y, t)),\n)\n\n// solveAtX: invert the x polynomial to find ts within the unit interval, then\n// evaluate y at each surviving t. Result order matches solveInverse order\n// (t-ascending).\n/** @internal */\nexport const solveAtX = dual(2, (c: QuadraticCurve2d, x: number) => {\n  const ts = Solution.clip(QuadraticPolynomial.solveInverse(c.x, x), Interval.unit)\n  return Solution.map(ts, (t) => QuadraticPolynomial.solve(c.y, t))\n})\n\n/** @internal */\nexport const solveAtY = dual(2, (c: QuadraticCurve2d, y: number) => {\n  const ts = Solution.clip(QuadraticPolynomial.solveInverse(c.y, y), Interval.unit)\n  return Solution.map(ts, (t) => QuadraticPolynomial.solve(c.x, t))\n})\n\n/** @internal */\nexport const derivative = (c: QuadraticCurve2d) =>\n  LinearCurve2d.fromPolynomials(\n    QuadraticPolynomial.derivative(c.x),\n    QuadraticPolynomial.derivative(c.y),\n  )\n\n/** @internal */\nexport const length = dual(2, (c: QuadraticCurve2d, i: Interval.Interval) => {\n  if (Interval.size(i) === 0) {\n    return 0\n  }\n\n  if (c.x.c2 === 0 && c.y.c2 === 0) {\n    return LinearCurve2d.length(\n      LinearCurve2d.fromPolynomials(\n        LinearPolynomial.make(c.x.c0, c.x.c1),\n        LinearPolynomial.make(c.y.c0, c.y.c1),\n      ),\n      i,\n    )\n  }\n\n  const d = derivative(c)\n\n  const { scale, shift } = Interval.scaleShift(Interval.biunit, i)\n\n  return (\n    (GL32_W0 * Vector2.magnitude(LinearCurve2d.solve(d, shift + scale * -GL32_X0)) +\n      GL32_W0 * Vector2.magnitude(LinearCurve2d.solve(d, shift + scale * GL32_X0)) +\n      GL32_W1 * Vector2.magnitude(LinearCurve2d.solve(d, shift + scale * -GL32_X1)) +\n      GL32_W1 * Vector2.magnitude(LinearCurve2d.solve(d, shift + scale * GL32_X1)) +\n      GL32_W2 * Vector2.magnitude(LinearCurve2d.solve(d, shift + scale * -GL32_X2)) +\n      GL32_W2 * Vector2.magnitude(LinearCurve2d.solve(d, shift + scale * GL32_X2)) +\n      GL32_W3 * Vector2.magnitude(LinearCurve2d.solve(d, shift + scale * -GL32_X3)) +\n      GL32_W3 * Vector2.magnitude(LinearCurve2d.solve(d, shift + scale * GL32_X3)) +\n      GL32_W4 * Vector2.magnitude(LinearCurve2d.solve(d, shift + scale * -GL32_X4)) +\n      GL32_W4 * Vector2.magnitude(LinearCurve2d.solve(d, shift + scale * GL32_X4)) +\n      GL32_W5 * Vector2.magnitude(LinearCurve2d.solve(d, shift + scale * -GL32_X5)) +\n      GL32_W5 * Vector2.magnitude(LinearCurve2d.solve(d, shift + scale * GL32_X5)) +\n      GL32_W6 * Vector2.magnitude(LinearCurve2d.solve(d, shift + scale * -GL32_X6)) +\n      GL32_W6 * Vector2.magnitude(LinearCurve2d.solve(d, shift + scale * GL32_X6)) +\n      GL32_W7 * Vector2.magnitude(LinearCurve2d.solve(d, shift + scale * -GL32_X7)) +\n      GL32_W7 * Vector2.magnitude(LinearCurve2d.solve(d, shift + scale * GL32_X7)) +\n      GL32_W8 * Vector2.magnitude(LinearCurve2d.solve(d, shift + scale * -GL32_X8)) +\n      GL32_W8 * Vector2.magnitude(LinearCurve2d.solve(d, shift + scale * GL32_X8)) +\n      GL32_W9 * Vector2.magnitude(LinearCurve2d.solve(d, shift + scale * -GL32_X9)) +\n      GL32_W9 * Vector2.magnitude(LinearCurve2d.solve(d, shift + scale * GL32_X9)) +\n      GL32_W10 * Vector2.magnitude(LinearCurve2d.solve(d, shift + scale * -GL32_X10)) +\n      GL32_W10 * Vector2.magnitude(LinearCurve2d.solve(d, shift + scale * GL32_X10)) +\n      GL32_W11 * Vector2.magnitude(LinearCurve2d.solve(d, shift + scale * -GL32_X11)) +\n      GL32_W11 * Vector2.magnitude(LinearCurve2d.solve(d, shift + scale * GL32_X11)) +\n      GL32_W12 * Vector2.magnitude(LinearCurve2d.solve(d, shift + scale * -GL32_X12)) +\n      GL32_W12 * Vector2.magnitude(LinearCurve2d.solve(d, shift + scale * GL32_X12)) +\n      GL32_W13 * Vector2.magnitude(LinearCurve2d.solve(d, shift + scale * -GL32_X13)) +\n      GL32_W13 * Vector2.magnitude(LinearCurve2d.solve(d, shift + scale * GL32_X13)) +\n      GL32_W14 * Vector2.magnitude(LinearCurve2d.solve(d, shift + scale * -GL32_X14)) +\n      GL32_W14 * Vector2.magnitude(LinearCurve2d.solve(d, shift + scale * GL32_X14)) +\n      GL32_W15 * Vector2.magnitude(LinearCurve2d.solve(d, shift + scale * -GL32_X15)) +\n      GL32_W15 * Vector2.magnitude(LinearCurve2d.solve(d, shift + scale * GL32_X15))) *\n    scale\n  )\n})\n\n/** @internal */\nexport const curvature = dual(2, (c: QuadraticCurve2d, t: number) => {\n  const d = derivative(c)\n  const v = LinearCurve2d.solve(d, t)\n  const a = LinearCurve2d.derivative(d)\n\n  const vMag = Vector2.magnitude(v)\n\n  if (vMag === 0) {\n    return 0\n  }\n\n  return Math.abs(Vector2.cross(v, a)) / vMag ** 3\n})\n\n/** @internal */\nexport const boundingBox = (\n  c: QuadraticCurve2d,\n): Interval2d.Interval2d<Interval.Closed, Interval.Closed> =>\n  Interval2d.make(QuadraticPolynomial.unitRange(c.x), QuadraticPolynomial.unitRange(c.y))\n\n// Combined trait refiners — fan out the polynomial-level check across both\n// axes, over the unit interval. For per-axis checks, users can call\n// `QuadraticPolynomial.isMonotonic(c.x, Interval.unit)` directly.\n/** @internal */\nexport const isMonotonic = <XT, YT>(\n  c: QuadraticCurve2d<XT, YT>,\n): c is QuadraticCurve2d<XT & Monotonic, YT & Monotonic> =>\n  QuadraticPolynomial.isMonotonic(c.x, Interval.unit) &&\n  QuadraticPolynomial.isMonotonic(c.y, Interval.unit)\n\n/** @internal */\nexport const isIncreasing = <XT, YT>(\n  c: QuadraticCurve2d<XT, YT>,\n): c is QuadraticCurve2d<XT & Increasing, YT & Increasing> =>\n  QuadraticPolynomial.isIncreasing(c.x, Interval.unit) &&\n  QuadraticPolynomial.isIncreasing(c.y, Interval.unit)\n\n/** @internal */\nexport const isDecreasing = <XT, YT>(\n  c: QuadraticCurve2d<XT, YT>,\n): c is QuadraticCurve2d<XT & Decreasing, YT & Decreasing> =>\n  QuadraticPolynomial.isDecreasing(c.x, Interval.unit) &&\n  QuadraticPolynomial.isDecreasing(c.y, Interval.unit)\n\nconst fail = (m: string): never => {\n  throw new Error(m)\n}\n\n/** @internal */\nexport const asMonotonic = <XT, YT>(\n  c: QuadraticCurve2d<XT, YT>,\n): QuadraticCurve2d<XT & Monotonic, YT & Monotonic> =>\n  isMonotonic(c) ? c : fail('quadratic curve is not monotonic in both axes')\n\n/** @internal */\nexport const asIncreasing = <XT, YT>(\n  c: QuadraticCurve2d<XT, YT>,\n): QuadraticCurve2d<XT & Increasing, YT & Increasing> =>\n  isIncreasing(c) ? c : fail('quadratic curve is not increasing in both axes')\n\n/** @internal */\nexport const asDecreasing = <XT, YT>(\n  c: QuadraticCurve2d<XT, YT>,\n): QuadraticCurve2d<XT & Decreasing, YT & Decreasing> =>\n  isDecreasing(c) ? c : fail('quadratic curve is not decreasing in both axes')\n","import type { Interval2d } from '../interval/interval2d.ts'\nimport type { TwoDimensional } from '../dimensions.ts'\nimport type { Closed, Interval } from '../interval/interval.ts'\nimport type { Pipeable } from '../utils.ts'\nimport type { QuadraticPolynomial } from '../polynomial/quadratic.ts'\nimport type { Decreasing, Increasing, Monotonic } from '../polynomial/traits.ts'\nimport type * as Solution from '../solution/solution.ts'\nimport type { Vector2 } from '../vector/vector2.ts'\nimport type { LinearCurve2d } from './linear2d.ts'\nimport type { QuadraticCurve2dTypeId } from './quadratic2d.internal.ts'\nimport * as internal from './quadratic2d.internal.ts'\n\nexport type { Monotonic, Increasing, Decreasing } from '../polynomial/traits.ts'\n\n/**\n * A quadratic curve in 2D space.\n *\n * All fields are readonly and immutable, and all operations create new instances.\n *\n * The two type parameters carry the trait sets of the curve's per-axis\n * polynomials. Refiners check monotonicity over the unit interval `[0, 1]` —\n * the curve's natural parameter domain.\n *\n * @since 1.0.0\n */\nexport interface QuadraticCurve2d<out XTraits = unknown, out YTraits = unknown>\n  extends Pipeable, TwoDimensional<QuadraticPolynomial<XTraits>, QuadraticPolynomial<YTraits>> {\n  readonly [QuadraticCurve2dTypeId]: QuadraticCurve2dTypeId\n}\n\n/**\n * Creates a new `QuadraticCurve2d` instance from polynomial parameters.\n *\n * @param c0 - The x polynomial.\n * @param c1 - The y polynomial.\n * @returns A new `QuadraticCurve2d` instance.\n * @since 1.0.0\n */\nexport const fromPolynomials: (\n  c0: QuadraticPolynomial,\n  c1: QuadraticPolynomial,\n) => QuadraticCurve2d = internal.fromPolynomials\n\n/**\n * Creates a new `QuadraticCurve2d` instance from monomial coefficient vectors.\n *\n * Each argument bundles the per-axis coefficient at the given power: `c0`\n * holds the x⁰ term, `c1` holds the x¹ term, and so on. The resulting curve\n * evaluates to `c0 + c1·t + c2·t²` per axis.\n *\n * @param c0 - The x⁰ coefficients (x and y).\n * @param c1 - The x¹ coefficients (x and y).\n * @param c2 - The x² coefficients (x and y).\n * @returns A new `QuadraticCurve2d` instance.\n * @since 2.0.0\n */\nexport const fromCoefficients: (c0: Vector2, c1: Vector2, c2: Vector2) => QuadraticCurve2d =\n  internal.fromCoefficients\n\n/**\n * Creates a new `QuadraticCurve2d` instance from quadratic Bézier control\n * points.\n *\n * The three arguments are the Bernstein-basis control points: `p0` and `p2`\n * are the curve's endpoints and `p1` is the off-curve control handle. The\n * implementation converts to the curve's internal monomial form in closed\n * form.\n *\n * @param p0 - The first control point (curve start).\n * @param p1 - The second control point (control handle).\n * @param p2 - The third control point (curve end).\n * @returns A new `QuadraticCurve2d` instance whose curve matches the given Bézier.\n * @since 2.0.0\n */\nexport const fromBezierPoints: (p0: Vector2, p1: Vector2, p2: Vector2) => QuadraticCurve2d =\n  internal.fromBezierPoints\n\n/**\n * Checks if a value is a `QuadraticCurve2d`.\n *\n * @param c - The value to check.\n * @returns `true` if the value is a `QuadraticCurve2d`, `false` otherwise.\n * @since 1.0.0\n */\nexport const isQuadraticCurve2d: (c: unknown) => c is QuadraticCurve2d = internal.isQuadraticCurve2d\n\nexport const solve: {\n  /**\n   * Solves the quadratic curve for a given parameter t.\n   *\n   * @param t - The parameter value.\n   * @returns A function that takes a quadratic curve and returns the point on the curve at parameter t.\n   * @since 1.0.0\n   */\n  (t: number): (c: QuadraticCurve2d) => Vector2\n  /**\n   * Solves the quadratic curve for a given parameter t.\n   *\n   * @param c - The quadratic curve to solve.\n   * @param t - The parameter value.\n   * @returns The point on the curve at parameter t.\n   * @since 1.0.0\n   */\n  (c: QuadraticCurve2d, t: number): Vector2\n} = internal.solve\n\nexport const length: {\n  /**\n   * Computes the length of the quadratic curve over a given interval.\n   *\n   * @param c - The quadratic curve to compute the length of.\n   * @param i - The interval over which to compute the length.\n   * @returns The length of the quadratic curve over the interval.\n   * @since 1.0.0\n   */\n  (c: QuadraticCurve2d, i: Interval): number\n  /**\n   * Computes the length of the quadratic curve over a given interval.\n   *\n   * @param i - The interval over which to compute the length.\n   * @returns A function that takes a quadratic curve and returns the length of the curve over the interval.\n   * @since 1.0.0\n   */\n  (i: Interval): (c: QuadraticCurve2d) => number\n} = internal.length\n\nexport const solveAtX: {\n  /**\n   * Evaluates the curve's y values at a given x. Because the x polynomial is\n   * `Monotonic`, the inverse has at most one solution — at most one y value.\n   *\n   * @param c - The quadratic curve.\n   * @param x - The x coordinate.\n   * @returns Zero or one y values, in t-ascending order.\n   * @since 2.0.0\n   */\n  <XT extends Monotonic, YT>(c: QuadraticCurve2d<XT, YT>, x: number): Solution.AtMostOne<number>\n  /**\n   * Evaluates the curve's y values at a given x. The result is the y values\n   * the curve passes through where x(t) = the given x — up to two solutions\n   * for a quadratic curve.\n   *\n   * @param c - The quadratic curve.\n   * @param x - The x coordinate.\n   * @returns The y values at x, in t-ascending order.\n   * @since 2.0.0\n   */\n  <XT, YT>(c: QuadraticCurve2d<XT, YT>, x: number): Solution.AtMostTwo<number>\n  /** @since 2.0.0 */\n  (x: number): {\n    <XT extends Monotonic, YT>(c: QuadraticCurve2d<XT, YT>): Solution.AtMostOne<number>\n    <XT, YT>(c: QuadraticCurve2d<XT, YT>): Solution.AtMostTwo<number>\n  }\n} = internal.solveAtX as never\n\nexport const solveAtY: {\n  /**\n   * Evaluates the curve's x values at a given y. Because the y polynomial is\n   * `Monotonic`, the inverse has at most one solution.\n   *\n   * @param c - The quadratic curve.\n   * @param y - The y coordinate.\n   * @returns Zero or one x values, in t-ascending order.\n   * @since 2.0.0\n   */\n  <XT, YT extends Monotonic>(c: QuadraticCurve2d<XT, YT>, y: number): Solution.AtMostOne<number>\n  /**\n   * Evaluates the curve's x values at a given y. The result is the x values\n   * the curve passes through where y(t) = the given y — up to two solutions\n   * for a quadratic curve.\n   *\n   * @param c - The quadratic curve.\n   * @param y - The y coordinate.\n   * @returns The x values at y, in t-ascending order.\n   * @since 2.0.0\n   */\n  <XT, YT>(c: QuadraticCurve2d<XT, YT>, y: number): Solution.AtMostTwo<number>\n  /** @since 2.0.0 */\n  (y: number): {\n    <XT, YT extends Monotonic>(c: QuadraticCurve2d<XT, YT>): Solution.AtMostOne<number>\n    <XT, YT>(c: QuadraticCurve2d<XT, YT>): Solution.AtMostTwo<number>\n  }\n} = internal.solveAtY as never\n\n/**\n * Computes the derivative of a quadratic curve.\n *\n * @param c - The quadratic curve to compute the derivative of.\n * @returns The derivative of the quadratic curve as a linear curve.\n * @since 1.0.0\n */\nexport const derivative: (c: QuadraticCurve2d) => LinearCurve2d = internal.derivative\n\nexport const curvature: {\n  /**\n   * Computes the curvature of the quadratic curve at a given parameter t.\n   *\n   * @param c - The quadratic curve to compute the curvature for.\n   * @param t - The parameter value.\n   * @returns The curvature of the quadratic curve at parameter t.\n   * @since 1.0.0\n   */\n  (c: QuadraticCurve2d, t: number): number\n  /**\n   * Computes the curvature of the quadratic curve at a given parameter t.\n   *\n   * @param t - The parameter value.\n   * @returns A function that takes a quadratic curve and returns the curvature of the curve at parameter t.\n   * @since 1.0.0\n   */\n  (t: number): (c: QuadraticCurve2d) => number\n} = internal.curvature\n\n/**\n * Computes the axis-aligned bounding box of the curve over its parameter\n * domain `[0, 1]`. Accounts for interior extrema, so the box is tight against\n * the curve and not just the control polygon.\n *\n * @param c - The quadratic curve.\n * @returns A closed `Box2d` enclosing the curve.\n * @since 2.0.0\n */\nexport const boundingBox: (c: QuadraticCurve2d) => Interval2d<Closed, Closed> = internal.boundingBox\n\n/**\n * Type-narrowing predicate: refines both axes' traits to include `Monotonic`\n * when both x and y polynomials are monotonic over the unit interval `[0, 1]`.\n *\n * For checking only one axis, call the polynomial-level refiner directly:\n * `QuadraticPolynomial.isMonotonic(curve.x, Interval.unit)`.\n *\n * @since 2.0.0\n */\nexport const isMonotonic: <XT, YT>(\n  c: QuadraticCurve2d<XT, YT>,\n) => c is QuadraticCurve2d<XT & Monotonic, YT & Monotonic> = internal.isMonotonic\n\n/** @since 2.0.0 */\nexport const isIncreasing: <XT, YT>(\n  c: QuadraticCurve2d<XT, YT>,\n) => c is QuadraticCurve2d<XT & Increasing, YT & Increasing> = internal.isIncreasing\n\n/** @since 2.0.0 */\nexport const isDecreasing: <XT, YT>(\n  c: QuadraticCurve2d<XT, YT>,\n) => c is QuadraticCurve2d<XT & Decreasing, YT & Decreasing> = internal.isDecreasing\n\n/** @since 2.0.0 */\nexport const asMonotonic: <XT, YT>(\n  c: QuadraticCurve2d<XT, YT>,\n) => QuadraticCurve2d<XT & Monotonic, YT & Monotonic> = internal.asMonotonic\n\n/** @since 2.0.0 */\nexport const asIncreasing: <XT, YT>(\n  c: QuadraticCurve2d<XT, YT>,\n) => QuadraticCurve2d<XT & Increasing, YT & Increasing> = internal.asIncreasing\n\n/** @since 2.0.0 */\nexport const asDecreasing: <XT, YT>(\n  c: QuadraticCurve2d<XT, YT>,\n) => QuadraticCurve2d<XT & Decreasing, YT & Decreasing> = internal.asDecreasing\n","import * as Interval2d from '../interval/interval2d.ts'\nimport * as Characteristic from '../characteristic/characteristic.ts'\nimport * as Interval from '../interval/interval.ts'\nimport {\n  GL32_W0,\n  GL32_W1,\n  GL32_W2,\n  GL32_W3,\n  GL32_W4,\n  GL32_W5,\n  GL32_W6,\n  GL32_W7,\n  GL32_W8,\n  GL32_W9,\n  GL32_W10,\n  GL32_W11,\n  GL32_W12,\n  GL32_W13,\n  GL32_W14,\n  GL32_W15,\n  GL32_X0,\n  GL32_X1,\n  GL32_X2,\n  GL32_X3,\n  GL32_X4,\n  GL32_X5,\n  GL32_X6,\n  GL32_X7,\n  GL32_X8,\n  GL32_X9,\n  GL32_X10,\n  GL32_X11,\n  GL32_X12,\n  GL32_X13,\n  GL32_X14,\n  GL32_X15,\n} from '../length.ts'\nimport { dual, Pipeable } from '../utils.ts'\nimport * as CubicPolynomial from '../polynomial/cubic.ts'\nimport * as QuadraticPolynomial from '../polynomial/quadratic.ts'\nimport type { Decreasing, Increasing, Monotonic } from '../polynomial/traits.ts'\nimport * as Solution from '../solution/solution.ts'\nimport * as Vector2 from '../vector/vector2.ts'\nimport * as Vector4 from '../vector/vector4.ts'\nimport type { CubicCurve2d } from './cubic2d.ts'\nimport * as LinearCurve2d from './linear2d.ts'\nimport * as QuadraticCurve2d from './quadratic2d.ts'\n\nexport const CubicCurve2dTypeId: unique symbol = Symbol('curvy/curve/cubic2d')\nexport type CubicCurve2dTypeId = typeof CubicCurve2dTypeId\n\n/** @internal */\nexport class CubicCurve2dImpl extends Pipeable implements CubicCurve2d<unknown, unknown> {\n  readonly [CubicCurve2dTypeId]: CubicCurve2dTypeId = CubicCurve2dTypeId\n\n  readonly x: CubicPolynomial.CubicPolynomial\n  readonly y: CubicPolynomial.CubicPolynomial\n\n  constructor(c0: CubicPolynomial.CubicPolynomial, c1: CubicPolynomial.CubicPolynomial) {\n    super()\n    this.x = c0\n    this.y = c1\n  }\n\n  get [0]() {\n    return this.x\n  }\n\n  get [1]() {\n    return this.y\n  }\n}\n\n/** @internal */\nexport const fromPolynomials: (\n  c0: CubicPolynomial.CubicPolynomial,\n  c1: CubicPolynomial.CubicPolynomial,\n) => CubicCurve2d = (c0, c1) => new CubicCurve2dImpl(c0, c1)\n\n/** @internal */\nexport const fromCoefficients: (\n  c0: Vector2.Vector2,\n  c1: Vector2.Vector2,\n  c2: Vector2.Vector2,\n  c3: Vector2.Vector2,\n) => CubicCurve2d = (c0, c1, c2, c3) =>\n  new CubicCurve2dImpl(\n    CubicPolynomial.make(c0.x, c1.x, c2.x, c3.x),\n    CubicPolynomial.make(c0.y, c1.y, c2.y, c3.y),\n  )\n\n// Applies the cubic Bézier characteristic matrix to the per-axis control\n// vectors, producing monomial polynomials. The matrix encodes the cubic\n// Bernstein → monomial expansion `(c₀, c₁, c₂, c₃) = M · (p₀, p₁, p₂, p₃)`\n// for each axis independently.\n/** @internal */\nexport const fromBezierPoints: (\n  p0: Vector2.Vector2,\n  p1: Vector2.Vector2,\n  p2: Vector2.Vector2,\n  p3: Vector2.Vector2,\n) => CubicCurve2d = (p0, p1, p2, p3) => {\n  const channels = Vector4.transpose([p0, p1, p2, p3], (p) => [p.x, p.y])\n  return new CubicCurve2dImpl(...Characteristic.apply(Characteristic.cubicBezier, ...channels))\n}\n\n/** @internal */\nexport const isCubicCurve2d = (c: unknown): c is CubicCurve2d =>\n  typeof c === 'object' && c !== null && CubicCurve2dTypeId in c\n\n/** @internal */\nexport const solve = dual<\n  (t: number) => (c: CubicCurve2d) => Vector2.Vector2,\n  (c: CubicCurve2d, t: number) => Vector2.Vector2\n>(2, (c: CubicCurve2d, t: number) =>\n  Vector2.make(CubicPolynomial.solve(c.x, t), CubicPolynomial.solve(c.y, t)),\n)\n\n// solveAtX: invert the x polynomial to find ts within the unit interval, then\n// evaluate y at each surviving t. Result order matches solveInverse order\n// (t-ascending).\n/** @internal */\nexport const solveAtX = dual(2, (c: CubicCurve2d, x: number) => {\n  const ts = Solution.clip(CubicPolynomial.solveInverse(c.x, x), Interval.unit)\n  return Solution.map(ts, (t) => CubicPolynomial.solve(c.y, t))\n})\n\n/** @internal */\nexport const solveAtY = dual(2, (c: CubicCurve2d, y: number) => {\n  const ts = Solution.clip(CubicPolynomial.solveInverse(c.y, y), Interval.unit)\n  return Solution.map(ts, (t) => CubicPolynomial.solve(c.x, t))\n})\n\n/** @internal */\nexport const derivative = (c: CubicCurve2d) =>\n  QuadraticCurve2d.fromPolynomials(CubicPolynomial.derivative(c.x), CubicPolynomial.derivative(c.y))\n\n/** @internal */\nexport const length = dual(2, (c: CubicCurve2d, i: Interval.Interval) => {\n  if (Interval.size(i) === 0) {\n    return 0\n  }\n\n  if (c.x.c3 === 0 && c.y.c3 === 0) {\n    return QuadraticCurve2d.length(\n      QuadraticCurve2d.fromPolynomials(\n        QuadraticPolynomial.make(c.x.c0, c.x.c1, c.x.c2),\n        QuadraticPolynomial.make(c.y.c0, c.y.c1, c.y.c2),\n      ),\n      i,\n    )\n  }\n\n  const d = derivative(c)\n\n  const { scale, shift } = Interval.scaleShift(Interval.biunit, i)\n\n  return (\n    (GL32_W0 * Vector2.magnitude(QuadraticCurve2d.solve(d, shift + scale * -GL32_X0)) +\n      GL32_W0 * Vector2.magnitude(QuadraticCurve2d.solve(d, shift + scale * GL32_X0)) +\n      GL32_W1 * Vector2.magnitude(QuadraticCurve2d.solve(d, shift + scale * -GL32_X1)) +\n      GL32_W1 * Vector2.magnitude(QuadraticCurve2d.solve(d, shift + scale * GL32_X1)) +\n      GL32_W2 * Vector2.magnitude(QuadraticCurve2d.solve(d, shift + scale * -GL32_X2)) +\n      GL32_W2 * Vector2.magnitude(QuadraticCurve2d.solve(d, shift + scale * GL32_X2)) +\n      GL32_W3 * Vector2.magnitude(QuadraticCurve2d.solve(d, shift + scale * -GL32_X3)) +\n      GL32_W3 * Vector2.magnitude(QuadraticCurve2d.solve(d, shift + scale * GL32_X3)) +\n      GL32_W4 * Vector2.magnitude(QuadraticCurve2d.solve(d, shift + scale * -GL32_X4)) +\n      GL32_W4 * Vector2.magnitude(QuadraticCurve2d.solve(d, shift + scale * GL32_X4)) +\n      GL32_W5 * Vector2.magnitude(QuadraticCurve2d.solve(d, shift + scale * -GL32_X5)) +\n      GL32_W5 * Vector2.magnitude(QuadraticCurve2d.solve(d, shift + scale * GL32_X5)) +\n      GL32_W6 * Vector2.magnitude(QuadraticCurve2d.solve(d, shift + scale * -GL32_X6)) +\n      GL32_W6 * Vector2.magnitude(QuadraticCurve2d.solve(d, shift + scale * GL32_X6)) +\n      GL32_W7 * Vector2.magnitude(QuadraticCurve2d.solve(d, shift + scale * -GL32_X7)) +\n      GL32_W7 * Vector2.magnitude(QuadraticCurve2d.solve(d, shift + scale * GL32_X7)) +\n      GL32_W8 * Vector2.magnitude(QuadraticCurve2d.solve(d, shift + scale * -GL32_X8)) +\n      GL32_W8 * Vector2.magnitude(QuadraticCurve2d.solve(d, shift + scale * GL32_X8)) +\n      GL32_W9 * Vector2.magnitude(QuadraticCurve2d.solve(d, shift + scale * -GL32_X9)) +\n      GL32_W9 * Vector2.magnitude(QuadraticCurve2d.solve(d, shift + scale * GL32_X9)) +\n      GL32_W10 * Vector2.magnitude(QuadraticCurve2d.solve(d, shift + scale * -GL32_X10)) +\n      GL32_W10 * Vector2.magnitude(QuadraticCurve2d.solve(d, shift + scale * GL32_X10)) +\n      GL32_W11 * Vector2.magnitude(QuadraticCurve2d.solve(d, shift + scale * -GL32_X11)) +\n      GL32_W11 * Vector2.magnitude(QuadraticCurve2d.solve(d, shift + scale * GL32_X11)) +\n      GL32_W12 * Vector2.magnitude(QuadraticCurve2d.solve(d, shift + scale * -GL32_X12)) +\n      GL32_W12 * Vector2.magnitude(QuadraticCurve2d.solve(d, shift + scale * GL32_X12)) +\n      GL32_W13 * Vector2.magnitude(QuadraticCurve2d.solve(d, shift + scale * -GL32_X13)) +\n      GL32_W13 * Vector2.magnitude(QuadraticCurve2d.solve(d, shift + scale * GL32_X13)) +\n      GL32_W14 * Vector2.magnitude(QuadraticCurve2d.solve(d, shift + scale * -GL32_X14)) +\n      GL32_W14 * Vector2.magnitude(QuadraticCurve2d.solve(d, shift + scale * GL32_X14)) +\n      GL32_W15 * Vector2.magnitude(QuadraticCurve2d.solve(d, shift + scale * -GL32_X15)) +\n      GL32_W15 * Vector2.magnitude(QuadraticCurve2d.solve(d, shift + scale * GL32_X15))) *\n    scale\n  )\n})\n\n/** @internal */\nexport const curvature = dual(2, (c: CubicCurve2d, t: number) => {\n  const d = derivative(c)\n\n  const v = QuadraticCurve2d.solve(d, t)\n  const a = LinearCurve2d.solve(QuadraticCurve2d.derivative(d), t)\n\n  const vMag = Vector2.magnitude(v)\n\n  if (vMag === 0) {\n    return 0\n  }\n\n  return Math.abs(Vector2.cross(v, a)) / vMag ** 3\n})\n\n/** @internal */\nexport const boundingBox = (\n  c: CubicCurve2d,\n): Interval2d.Interval2d<Interval.Closed, Interval.Closed> =>\n  Interval2d.make(CubicPolynomial.unitRange(c.x), CubicPolynomial.unitRange(c.y))\n\n// Combined trait refiners — fan out the polynomial-level check across both\n// axes, over the unit interval. For per-axis checks, users can call\n// `CubicPolynomial.isMonotonic(c.x, Interval.unit)` directly.\n/** @internal */\nexport const isMonotonic = <XT, YT>(\n  c: CubicCurve2d<XT, YT>,\n): c is CubicCurve2d<XT & Monotonic, YT & Monotonic> =>\n  CubicPolynomial.isMonotonic(c.x, Interval.unit) && CubicPolynomial.isMonotonic(c.y, Interval.unit)\n\n/** @internal */\nexport const isIncreasing = <XT, YT>(\n  c: CubicCurve2d<XT, YT>,\n): c is CubicCurve2d<XT & Increasing, YT & Increasing> =>\n  CubicPolynomial.isIncreasing(c.x, Interval.unit) &&\n  CubicPolynomial.isIncreasing(c.y, Interval.unit)\n\n/** @internal */\nexport const isDecreasing = <XT, YT>(\n  c: CubicCurve2d<XT, YT>,\n): c is CubicCurve2d<XT & Decreasing, YT & Decreasing> =>\n  CubicPolynomial.isDecreasing(c.x, Interval.unit) &&\n  CubicPolynomial.isDecreasing(c.y, Interval.unit)\n\nconst fail = (m: string): never => {\n  throw new Error(m)\n}\n\n/** @internal */\nexport const asMonotonic = <XT, YT>(\n  c: CubicCurve2d<XT, YT>,\n): CubicCurve2d<XT & Monotonic, YT & Monotonic> =>\n  isMonotonic(c) ? c : fail('cubic curve is not monotonic in both axes')\n\n/** @internal */\nexport const asIncreasing = <XT, YT>(\n  c: CubicCurve2d<XT, YT>,\n): CubicCurve2d<XT & Increasing, YT & Increasing> =>\n  isIncreasing(c) ? c : fail('cubic curve is not increasing in both axes')\n\n/** @internal */\nexport const asDecreasing = <XT, YT>(\n  c: CubicCurve2d<XT, YT>,\n): CubicCurve2d<XT & Decreasing, YT & Decreasing> =>\n  isDecreasing(c) ? c : fail('cubic curve is not decreasing in both axes')\n","import type { Interval2d } from '../interval/interval2d.ts'\nimport type { TwoDimensional } from '../dimensions.ts'\nimport type { Closed, Interval } from '../interval/interval.ts'\nimport type { Pipeable } from '../utils.ts'\nimport type { CubicPolynomial } from '../polynomial/cubic.ts'\nimport type { Decreasing, Increasing, Monotonic } from '../polynomial/traits.ts'\nimport type * as Solution from '../solution/solution.ts'\nimport type { Vector2 } from '../vector/vector2.ts'\nimport type { CubicCurve2dTypeId } from './cubic2d.internal.ts'\nimport * as internal from './cubic2d.internal.ts'\n\nexport type { Monotonic, Increasing, Decreasing } from '../polynomial/traits.ts'\n\n/**\n * A cubic curve in 2D space.\n *\n * All fields are readonly and immutable, and all operations create new instances.\n *\n * The two type parameters carry the trait sets of the curve's per-axis\n * polynomials. Refiners check monotonicity over the unit interval `[0, 1]` —\n * the curve's natural parameter domain.\n *\n * @since 1.0.0\n */\nexport interface CubicCurve2d<out XTraits = unknown, out YTraits = unknown>\n  extends Pipeable, TwoDimensional<CubicPolynomial<XTraits>, CubicPolynomial<YTraits>> {\n  readonly [CubicCurve2dTypeId]: CubicCurve2dTypeId\n}\n\n/**\n * Creates a new `CubicCurve2d` instance from polynomial parameters.\n *\n * @param x - The x polynomial.\n * @param y - The y polynomial.\n * @returns A new `CubicCurve2d` instance.\n * @since 1.0.0\n */\nexport const fromPolynomials: (x: CubicPolynomial, y: CubicPolynomial) => CubicCurve2d =\n  internal.fromPolynomials\n\n/**\n * Creates a new `CubicCurve2d` instance from monomial coefficient vectors.\n *\n * Each argument bundles the per-axis coefficient at the given power: `c0`\n * holds the x⁰ term, `c1` holds the x¹ term, and so on. The resulting curve\n * evaluates to `c0 + c1·t + c2·t² + c3·t³` per axis.\n *\n * @param c0 - The x⁰ coefficients (x and y).\n * @param c1 - The x¹ coefficients (x and y).\n * @param c2 - The x² coefficients (x and y).\n * @param c3 - The x³ coefficients (x and y).\n * @returns A new `CubicCurve2d` instance.\n * @since 2.0.0\n */\nexport const fromCoefficients: (\n  c0: Vector2,\n  c1: Vector2,\n  c2: Vector2,\n  c3: Vector2,\n) => CubicCurve2d = internal.fromCoefficients\n\n/**\n * Creates a new `CubicCurve2d` instance from cubic Bézier control points.\n *\n * The four arguments are the Bernstein-basis control points: `p0` and `p3` are\n * the curve's endpoints and `p1` and `p2` are the off-curve control handles.\n * The implementation converts to the curve's internal monomial form in closed\n * form.\n *\n * @param p0 - The first control point (curve start).\n * @param p1 - The second control point (start handle).\n * @param p2 - The third control point (end handle).\n * @param p3 - The fourth control point (curve end).\n * @returns A new `CubicCurve2d` instance whose curve matches the given Bézier.\n * @since 2.0.0\n */\nexport const fromBezierPoints: (\n  p0: Vector2,\n  p1: Vector2,\n  p2: Vector2,\n  p3: Vector2,\n) => CubicCurve2d = internal.fromBezierPoints\n\n/**\n * Checks if a value is a `CubicCurve2d`.\n *\n * @param c - The value to check.\n * @returns `true` if the value is a `CubicCurve2d`, `false` otherwise.\n * @since 1.0.0\n */\nexport const isCubicCurve2d: (c: unknown) => c is CubicCurve2d = internal.isCubicCurve2d\n\nexport const solve: {\n  /**\n   * Solves the cubic curve for a given parameter t.\n   *\n   * @param t - The parameter value.\n   * @returns A function that takes a cubic curve and returns the point on the curve at parameter t.\n   * @since 1.0.0\n   */\n  (t: number): (c: CubicCurve2d) => Vector2\n  /**\n   * Solves the cubic curve for a given parameter t.\n   *\n   * @param c - The cubic curve to solve.\n   * @param t - The parameter value.\n   * @returns The point on the curve at parameter t.\n   * @since 1.0.0\n   */\n  (c: CubicCurve2d, t: number): Vector2\n} = internal.solve\n\nexport const length: {\n  /**\n   * Calculates (approximates) the length of a cubic curve.\n   *\n   * @param c - The cubic curve to calculate the length of.\n   * @param i - The interval over which to calculate the length.\n   * @returns The length of the cubic curve.\n   * @since 1.0.0\n   */\n  (c: CubicCurve2d, i: Interval): number\n  /**\n   * Calculates (approximates) the length of a cubic curve.\n   *\n   * @param i - The interval over which to calculate the length.\n   * @returns A function that takes a cubic curve and returns the length of the cubic curve.\n   * @since 1.0.0\n   */\n  (i: Interval): (c: CubicCurve2d) => number\n} = internal.length\n\nexport const solveAtX: {\n  /**\n   * Evaluates the curve's y values at a given x. Because the x polynomial is\n   * `Monotonic`, the inverse has at most one solution — at most one y value.\n   *\n   * @param c - The cubic curve.\n   * @param x - The x coordinate.\n   * @returns Zero or one y values, in t-ascending order.\n   * @since 2.0.0\n   */\n  <XT extends Monotonic, YT>(c: CubicCurve2d<XT, YT>, x: number): Solution.AtMostOne<number>\n  /**\n   * Evaluates the curve's y values at a given x. The result is the y values\n   * the curve passes through where x(t) = the given x — up to three solutions\n   * for a cubic curve.\n   *\n   * @param c - The cubic curve.\n   * @param x - The x coordinate.\n   * @returns The y values at x, in t-ascending order.\n   * @since 2.0.0\n   */\n  <XT, YT>(c: CubicCurve2d<XT, YT>, x: number): Solution.AtMostThree<number>\n  /** @since 2.0.0 */\n  (x: number): {\n    <XT extends Monotonic, YT>(c: CubicCurve2d<XT, YT>): Solution.AtMostOne<number>\n    <XT, YT>(c: CubicCurve2d<XT, YT>): Solution.AtMostThree<number>\n  }\n} = internal.solveAtX as never\n\nexport const solveAtY: {\n  /**\n   * Evaluates the curve's x values at a given y. Because the y polynomial is\n   * `Monotonic`, the inverse has at most one solution.\n   *\n   * @param c - The cubic curve.\n   * @param y - The y coordinate.\n   * @returns Zero or one x values, in t-ascending order.\n   * @since 2.0.0\n   */\n  <XT, YT extends Monotonic>(c: CubicCurve2d<XT, YT>, y: number): Solution.AtMostOne<number>\n  /**\n   * Evaluates the curve's x values at a given y. The result is the x values\n   * the curve passes through where y(t) = the given y — up to three solutions\n   * for a cubic curve.\n   *\n   * @param c - The cubic curve.\n   * @param y - The y coordinate.\n   * @returns The x values at y, in t-ascending order.\n   * @since 2.0.0\n   */\n  <XT, YT>(c: CubicCurve2d<XT, YT>, y: number): Solution.AtMostThree<number>\n  /** @since 2.0.0 */\n  (y: number): {\n    <XT, YT extends Monotonic>(c: CubicCurve2d<XT, YT>): Solution.AtMostOne<number>\n    <XT, YT>(c: CubicCurve2d<XT, YT>): Solution.AtMostThree<number>\n  }\n} = internal.solveAtY as never\n\nexport const curvature: {\n  /**\n   * Calculates the curvature of a cubic curve at a given parameter.\n   *\n   * @param c - The cubic curve to calculate the curvature for.\n   * @param t - The parameter value.\n   * @returns The curvature of the cubic curve at parameter t.\n   * @since 1.0.0\n   */\n  (c: CubicCurve2d, t: number): number\n  /**\n   * Calculates the curvature of a cubic curve at a given parameter.\n   *\n   * @param t - The parameter value.\n   * @returns A function that takes a cubic curve and returns the curvature of the cubic curve at parameter t.\n   * @since 1.0.0\n   */\n  (t: number): (c: CubicCurve2d) => number\n} = internal.curvature\n\n/**\n * Computes the axis-aligned bounding box of the curve over its parameter\n * domain `[0, 1]`. Accounts for up to two interior extrema per axis, so the\n * box is tight against the curve and not just the control polygon.\n *\n * @param c - The cubic curve.\n * @returns A closed `Box2d` enclosing the curve.\n * @since 2.0.0\n */\nexport const boundingBox: (c: CubicCurve2d) => Interval2d<Closed, Closed> = internal.boundingBox\n\n/**\n * Type-narrowing predicate: refines both axes' traits to include `Monotonic`\n * when both x and y polynomials are monotonic over the unit interval `[0, 1]`.\n *\n * For checking only one axis, call the polynomial-level refiner directly:\n * `CubicPolynomial.isMonotonic(curve.x, Interval.unit)`.\n *\n * @since 2.0.0\n */\nexport const isMonotonic: <XT, YT>(\n  c: CubicCurve2d<XT, YT>,\n) => c is CubicCurve2d<XT & Monotonic, YT & Monotonic> = internal.isMonotonic\n\n/** @since 2.0.0 */\nexport const isIncreasing: <XT, YT>(\n  c: CubicCurve2d<XT, YT>,\n) => c is CubicCurve2d<XT & Increasing, YT & Increasing> = internal.isIncreasing\n\n/** @since 2.0.0 */\nexport const isDecreasing: <XT, YT>(\n  c: CubicCurve2d<XT, YT>,\n) => c is CubicCurve2d<XT & Decreasing, YT & Decreasing> = internal.isDecreasing\n\n/** @since 2.0.0 */\nexport const asMonotonic: <XT, YT>(\n  c: CubicCurve2d<XT, YT>,\n) => CubicCurve2d<XT & Monotonic, YT & Monotonic> = internal.asMonotonic\n\n/** @since 2.0.0 */\nexport const asIncreasing: <XT, YT>(\n  c: CubicCurve2d<XT, YT>,\n) => CubicCurve2d<XT & Increasing, YT & Increasing> = internal.asIncreasing\n\n/** @since 2.0.0 */\nexport const asDecreasing: <XT, YT>(\n  c: CubicCurve2d<XT, YT>,\n) => CubicCurve2d<XT & Decreasing, YT & Decreasing> = internal.asDecreasing\n","import * as Characteristic from '../characteristic/characteristic.ts'\nimport * as Interval from '../interval/interval.ts'\nimport * as Interval2d from '../interval/interval2d.ts'\nimport * as Monotonicity from '../monotonicity/monotonicity.ts'\nimport { dual, Pipeable } from '../utils.ts'\nimport * as CubicPolynomial from '../polynomial/cubic.ts'\nimport * as Solution from '../solution/solution.ts'\nimport type { Decreasing, Increasing, Monotonic } from '../polynomial/traits.ts'\nimport { invariant } from '../utils.ts'\nimport * as Vector2 from '../vector/vector2.ts'\nimport * as Vector4 from '../vector/vector4.ts'\nimport * as CubicCurve2d from './cubic2d.ts'\nimport type { RationalCubicCurve2d } from './rationalCubic2d.ts'\n\nexport const RationalCubicCurve2dTypeId: unique symbol = Symbol('curvy/curve/rationalCubic2d')\nexport type RationalCubicCurve2dTypeId = typeof RationalCubicCurve2dTypeId\n\n// Phantom property key carrying the per-axis trait tuple. Unlike `CubicCurve2d`\n// where traits flow through to the underlying polynomials, rational curve\n// traits are properties of the projected rational functions x(t)/w(t) and\n// y(t)/w(t) — not of any individual polynomial — so the brand lives on the\n// curve itself.\n/** @internal */\nexport const RationalCurveTraits: unique symbol = Symbol.for('curvy/curve/rationalCubic2d/traits')\n/** @internal */\nexport type RationalCurveTraits = typeof RationalCurveTraits\n\n/** @internal */\nexport class RationalCubicCurve2dImpl\n  extends Pipeable\n  implements RationalCubicCurve2d<unknown, unknown>\n{\n  readonly [RationalCubicCurve2dTypeId]: RationalCubicCurve2dTypeId = RationalCubicCurve2dTypeId\n  declare readonly [RationalCurveTraits]: [unknown, unknown]\n\n  readonly x: CubicPolynomial.CubicPolynomial\n  readonly y: CubicPolynomial.CubicPolynomial\n  readonly w: CubicPolynomial.CubicPolynomial\n\n  constructor(\n    x: CubicPolynomial.CubicPolynomial,\n    y: CubicPolynomial.CubicPolynomial,\n    w: CubicPolynomial.CubicPolynomial,\n  ) {\n    super()\n    this.x = x\n    this.y = y\n    this.w = w\n  }\n}\n\n/** @internal */\nexport const isRationalCubicCurve2d = (c: unknown): c is RationalCubicCurve2d =>\n  typeof c === 'object' && c !== null && RationalCubicCurve2dTypeId in c\n\n/** @internal */\nexport const fromPolynomials = (\n  x: CubicPolynomial.CubicPolynomial,\n  y: CubicPolynomial.CubicPolynomial,\n  w: CubicPolynomial.CubicPolynomial,\n): RationalCubicCurve2d => new RationalCubicCurve2dImpl(x, y, w)\n\n// Applies the cubic Bézier characteristic matrix in homogeneous space —\n// each control point is lifted to `(w·x, w·y, w)` and the same matrix that\n// drives `CubicCurve2d.fromBezierPoints` runs on each of the three channels\n// independently. The shared `w` polynomial is the projective denominator;\n// at solve time, x(t)/w(t) and y(t)/w(t) project the curve back to the plane.\n//\n// This is Freya Holmér's \"matrix IS the spline\" framing extended to rational:\n// same matrix, three channels instead of two, one projection at the end.\n/** @internal */\nexport const fromBezierPoints = (\n  p0: Vector2.Weighted,\n  p1: Vector2.Weighted,\n  p2: Vector2.Weighted,\n  p3: Vector2.Weighted,\n): RationalCubicCurve2d =>\n  new RationalCubicCurve2dImpl(\n    ...Characteristic.apply(\n      Characteristic.cubicBezier,\n      // Lift each control point to homogeneous (w·x, w·y, w), then transpose\n      // the four lifted CPs into three per-channel Vector4s for the matrix.\n      ...Vector4.transpose([p0, p1, p2, p3], (p) => [p.x * p.weight, p.y * p.weight, p.weight]),\n    ),\n  )\n\n// Gregory-Delbourgo style monotone rational cubic Hermite easing.\n//\n// Construction: rational cubic with *linear* denominator embedded in the 2D\n// pipeline by pinning x(t) = t exactly. With endpoint weights α at t=0 and\n// β at t=1, the Hermite conditions y(0)=0, y(1)=1, y'(0)=m₀, y'(1)=m₁\n// produce a closed-form cubic numerator. Monotonicity of y(t) is then a\n// degree-3 polynomial sign question — verified rigorously with the existing\n// cubic root-finder.\n//\n// The 2D embedding stores three polynomials in cubic form:\n//   X(t) = t · Q(t)        (quadratic, c3 = 0)        so x(t)/w(t) = t\n//   Y(t) = cubic numerator\n//   W(t) = Q(t) = α + (β-α)·t  (linear, c2 = c3 = 0)\n//\n// The α = m₀+1, β = m₁+1 choice is a serviceable heuristic — it makes\n// smoothstep (m₀=m₁=0) and linear (m₀=m₁=1) fall out for free, gives a\n// useful operating range for moderate slopes, and throws cleanly on inputs\n// it can't handle. Finding the optimal α, β formula for a wider input range\n// is a v2 problem.\n/** @internal */\nexport const makeMonotonicEasing = (startSlope: number, endSlope: number): RationalCubicCurve2d => {\n  invariant(\n    Number.isFinite(startSlope) && startSlope >= 0,\n    'makeMonotonicEasing: startSlope must be finite and ≥ 0',\n  )\n  invariant(\n    Number.isFinite(endSlope) && endSlope >= 0,\n    'makeMonotonicEasing: endSlope must be finite and ≥ 0',\n  )\n\n  const m0 = startSlope\n  const m1 = endSlope\n  const alpha = m0 + 1\n  const beta = m1 + 1\n\n  // Numerator P(t) cubic coefficients, derived from Hermite conditions\n  // y(0)=0, y(1)=1, y'(0)=m₀·α/α = m₀, y'(1)=(m₁·β + (β-α))/β = m₁:\n  //   c0 = 0\n  //   c1 = m₀·α\n  //   c2 = β·(2 - m₁) + α·(1 - 2m₀)\n  //   c3 = β·(m₁ - 1) + α·(m₀ - 1)\n  const pC0 = 0\n  const pC1 = m0 * alpha\n  const pC2 = beta * (2 - m1) + alpha * (1 - 2 * m0)\n  const pC3 = beta * (m1 - 1) + alpha * (m0 - 1)\n\n  // Denominator Q(t) = α + (β-α)·t — linear, stored as cubic with c2=c3=0.\n  const qC0 = alpha\n  const qC1 = beta - alpha\n\n  // X(t) = t · Q(t) = α·t + (β-α)·t² — quadratic, stored as cubic with c3=0.\n  const xC1 = alpha\n  const xC2 = beta - alpha\n\n  const xPoly = CubicPolynomial.make(0, xC1, xC2, 0)\n  const yPoly = CubicPolynomial.make(pC0, pC1, pC2, pC3)\n  const wPoly = CubicPolynomial.make(qC0, qC1, 0, 0)\n\n  // Verify monotonicity of y(t) = P(t)/Q(t) on (0, 1).\n  //\n  // sign(y'(t)) = sign(P'·Q - P·Q')  (since Q > 0 on [0,1])\n  //\n  // P' is degree 2, Q is degree 1, Q' is constant — so P'·Q - P·Q' is a\n  // degree-3 polynomial. We compute its coefficients and clip the roots to\n  // the strict interior (0, 1); any surviving root where the polynomial\n  // changes sign means y'(t) crosses zero inside the interval and the curve\n  // is not monotonic.\n  //\n  //   q(t) = m₀·α² + 2·α·a·t + (3·α·b + a·(β-α))·t² + 2·b·(β-α)·t³\n  // where a = β(2-m₁) + α(1-2m₀), b = β(m₁-1) + α(m₀-1) — i.e. c2 and c3.\n  const monoQ = CubicPolynomial.make(\n    m0 * alpha * alpha,\n    2 * alpha * pC2,\n    3 * alpha * pC3 + pC2 * (beta - alpha),\n    2 * pC3 * (beta - alpha),\n  )\n\n  const interiorRoots = monoQ.pipe(CubicPolynomial.roots, Solution.clip(Interval.unitOpen))\n  for (const t of interiorRoots) {\n    // Check sign on both sides of the root. If the polynomial changes sign\n    // across this point, monotonicity is violated.\n    const epsilon = 1e-6\n    const lo = Math.max(0, t - epsilon)\n    const hi = Math.min(1, t + epsilon)\n    const signLo = Math.sign(CubicPolynomial.solve(monoQ, lo))\n    const signHi = Math.sign(CubicPolynomial.solve(monoQ, hi))\n    invariant(\n      signLo * signHi >= 0,\n      `makeMonotonicEasing: slopes (${m0}, ${m1}) produce a non-monotonic curve with the default Gregory-Delbourgo construction. Try smaller slopes or use a different easing form.`,\n    )\n  }\n\n  return new RationalCubicCurve2dImpl(xPoly, yPoly, wPoly)\n}\n\n/** @internal */\nexport const solve = dual<\n  (t: number) => (c: RationalCubicCurve2d) => Vector2.Vector2,\n  (c: RationalCubicCurve2d, t: number) => Vector2.Vector2\n>(2, (c: RationalCubicCurve2d, t: number) => {\n  const w = CubicPolynomial.solve(c.w, t)\n  return Vector2.make(CubicPolynomial.solve(c.x, t) / w, CubicPolynomial.solve(c.y, t) / w)\n})\n\n// Inverse-solve x(t)/w(t) = X by finding roots of X(t) - X·w(t) = 0.\n// Both X(t) and w(t) are cubic in t, so their linear combination is also\n// cubic — solvable with the existing cubic root-finder. Solutions outside\n// the [0, 1] unit interval are discarded; for each surviving t, y(t)/w(t)\n// is evaluated. The brand-aware overload narrows to `AtMostOne` for curves\n// known to be x-monotonic.\n/** @internal */\nexport const solveAtX = dual(\n  2,\n  (c: RationalCubicCurve2d, x: number): Solution.Solution<number> =>\n    CubicPolynomial.make(\n      c.x.c0 - x * c.w.c0,\n      c.x.c1 - x * c.w.c1,\n      c.x.c2 - x * c.w.c2,\n      c.x.c3 - x * c.w.c3,\n    ).pipe(\n      CubicPolynomial.roots,\n      Solution.clip(Interval.unit),\n      Solution.map((t) => CubicPolynomial.solve(c.y, t) / CubicPolynomial.solve(c.w, t)),\n    ),\n)\n\n/** @internal */\nexport const solveAtY = dual(\n  2,\n  (c: RationalCubicCurve2d, y: number): Solution.Solution<number> =>\n    CubicPolynomial.make(\n      c.y.c0 - y * c.w.c0,\n      c.y.c1 - y * c.w.c1,\n      c.y.c2 - y * c.w.c2,\n      c.y.c3 - y * c.w.c3,\n    ).pipe(\n      CubicPolynomial.roots,\n      Solution.clip(Interval.unit),\n      Solution.map((t) => CubicPolynomial.solve(c.x, t) / CubicPolynomial.solve(c.w, t)),\n    ),\n)\n\n// Monomial coefficients of the quartic q(t) = N'(t)·D(t) − N(t)·D'(t).\n//\n// Since `r(t) = N(t)/D(t)` and `r'(t) = (N'·D − N·D')/D²`, with D² > 0 wherever\n// D ≠ 0, the sign of `r'` equals the sign of `q` on the unit interval (the\n// documented invariant assumes D is nonvanishing on `[0, 1]`). So per-axis\n// monotonicity of the rational reduces to sign analysis of `q`.\n//\n// `q` is the difference of two degree-5 products, but the leading t⁵ terms of\n// `N'·D` and `N·D'` both equal `3·n₃·d₃` and cancel — so `q` is actually\n// degree 4. (For equal-degree-n rationals, the derivative-numerator has degree\n// `2n − 2`.) Five monomial coefficients suffice.\nconst derivativeNumeratorQuartic = (\n  n: CubicPolynomial.CubicPolynomial,\n  d: CubicPolynomial.CubicPolynomial,\n): readonly [number, number, number, number, number] => [\n  n.c1 * d.c0 - n.c0 * d.c1,\n  2 * (n.c2 * d.c0 - n.c0 * d.c2),\n  n.c2 * d.c1 - n.c1 * d.c2 + 3 * (n.c3 * d.c0 - n.c0 * d.c3),\n  2 * (n.c3 * d.c1 - n.c1 * d.c3),\n  n.c3 * d.c2 - n.c2 * d.c3,\n]\n\n// Monomial → Bernstein basis conversion for degree 4 on [0, 1].\n//\n//   bⱼ = Σᵢ₌₀..ⱼ C(j, i)/C(4, i) · cᵢ\n//\n// Closed-form for n = 4 using C(4,·) = (1, 4, 6, 4, 1). Five outputs.\nconst bernsteinFromQuarticMonomial = (\n  c0: number,\n  c1: number,\n  c2: number,\n  c3: number,\n  c4: number,\n): readonly [number, number, number, number, number] => [\n  c0,\n  c0 + c1 / 4,\n  c0 + c1 / 2 + c2 / 6,\n  c0 + (3 * c1) / 4 + c2 / 2 + c3 / 4,\n  c0 + c1 + c2 + c3 + c4,\n]\n\n// At depth 32 the recursion has bracketed any sign change to an interval of\n// width 2⁻³² ≈ 2 × 10⁻¹⁰ — well below floating-point noise for typical\n// curve coefficients. Surviving ambiguity at this depth indicates a\n// tangential zero (touches but does not cross), which we report as\n// `Monotonicity.None`.\nconst BERNSTEIN_SIGN_MAX_DEPTH = 32\n\n// Bernstein sign convexity check on `[0, 1]`, returning the monotonicity\n// implied for a function whose derivative is the polynomial described by\n// these Bernstein coefficients. The encoding of `Monotonicity` is the same\n// 2-bit sign-coverage bitmask used internally here (bit 0 = \"polynomial\n// takes positive values\", bit 1 = \"takes negative values\"), so we can build\n// up the result and return it without translation.\n//\n// Single-level: by the convex-hull property of Bernstein form, a polynomial's\n// range on `[0, 1]` is contained in the convex hull of its Bernstein control\n// values — so the sign coverage of those values upper-bounds the sign\n// coverage of the polynomial. When the control values are sign-uniform we're\n// done; when not, the polynomial *might* still be sign-uniform (the hull is\n// only an outer bound), so we subdivide and check on tighter intervals.\n//\n// Recursive: split at t = 0.5 via de Casteljau (exact in Bernstein basis),\n// classify each half, then OR the coverages — `Increasing | Decreasing`\n// (subintervals of opposite sign) automatically degenerates to `None`,\n// matching the convex-union semantics of the sign sets. The depth cap turns\n// this into a decision procedure except at tangential zeros.\nconst certifyBernsteinSign = (\n  bs: readonly [number, number, number, number, number],\n  depth = 0,\n): Monotonicity.Monotonicity => {\n  let m: Monotonicity.Monotonicity = Monotonicity.Constant\n  for (let i = 0; i < 5; i++) {\n    const b = bs[i] as number\n    if (b > 0) {\n      m = (m | Monotonicity.Increasing) as Monotonicity.Monotonicity\n    } else if (b < 0) {\n      m = (m | Monotonicity.Decreasing) as Monotonicity.Monotonicity\n    }\n  }\n  if (m !== Monotonicity.None) {\n    return m\n  }\n  if (depth >= BERNSTEIN_SIGN_MAX_DEPTH) {\n    return Monotonicity.None\n  }\n\n  // de Casteljau at t = 0.5: each level averages adjacent values. Left half\n  // Bernstein coefficients are the first entry of each column; right half are\n  // the last entry of each column, read in reverse.\n  const [b0, b1, b2, b3, b4] = bs\n  const c0 = (b0 + b1) * 0.5\n  const c1 = (b1 + b2) * 0.5\n  const c2 = (b2 + b3) * 0.5\n  const c3 = (b3 + b4) * 0.5\n  const d0 = (c0 + c1) * 0.5\n  const d1 = (c1 + c2) * 0.5\n  const d2 = (c2 + c3) * 0.5\n  const e0 = (d0 + d1) * 0.5\n  const e1 = (d1 + d2) * 0.5\n  const f = (e0 + e1) * 0.5\n\n  return (certifyBernsteinSign([b0, c0, d0, e0, f], depth + 1) |\n    certifyBernsteinSign([f, e1, d2, c3, b4], depth + 1)) as Monotonicity.Monotonicity\n}\n\nconst axisMonotonicity = (\n  numerator: CubicPolynomial.CubicPolynomial,\n  denominator: CubicPolynomial.CubicPolynomial,\n): Monotonicity.Monotonicity => {\n  const [q0, q1, q2, q3, q4] = derivativeNumeratorQuartic(numerator, denominator)\n  return certifyBernsteinSign(bernsteinFromQuarticMonomial(q0, q1, q2, q3, q4))\n}\n\n/** @internal */\nexport const xMonotonicity = (c: RationalCubicCurve2d): Monotonicity.Monotonicity =>\n  axisMonotonicity(c.x, c.w)\n\n/** @internal */\nexport const yMonotonicity = (c: RationalCubicCurve2d): Monotonicity.Monotonicity =>\n  axisMonotonicity(c.y, c.w)\n\n/** @internal */\nexport const isMonotonicX = <XT, YT>(\n  c: RationalCubicCurve2d<XT, YT>,\n): c is RationalCubicCurve2d<XT & Monotonic, YT> => Monotonicity.isStrict(xMonotonicity(c))\n\n/** @internal */\nexport const isIncreasingX = <XT, YT>(\n  c: RationalCubicCurve2d<XT, YT>,\n): c is RationalCubicCurve2d<XT & Increasing, YT> => xMonotonicity(c) === Monotonicity.Increasing\n\n/** @internal */\nexport const isDecreasingX = <XT, YT>(\n  c: RationalCubicCurve2d<XT, YT>,\n): c is RationalCubicCurve2d<XT & Decreasing, YT> => xMonotonicity(c) === Monotonicity.Decreasing\n\n/** @internal */\nexport const isMonotonicY = <XT, YT>(\n  c: RationalCubicCurve2d<XT, YT>,\n): c is RationalCubicCurve2d<XT, YT & Monotonic> => Monotonicity.isStrict(yMonotonicity(c))\n\n/** @internal */\nexport const isIncreasingY = <XT, YT>(\n  c: RationalCubicCurve2d<XT, YT>,\n): c is RationalCubicCurve2d<XT, YT & Increasing> => yMonotonicity(c) === Monotonicity.Increasing\n\n/** @internal */\nexport const isDecreasingY = <XT, YT>(\n  c: RationalCubicCurve2d<XT, YT>,\n): c is RationalCubicCurve2d<XT, YT & Decreasing> => yMonotonicity(c) === Monotonicity.Decreasing\n\n// Combined refiners compose from per-axis ones via TypeScript's narrowing of\n// the && chain: each per-axis predicate attaches its brand to its own axis,\n// and the intersection accumulates as expected.\n/** @internal */\nexport const isMonotonic = <XT, YT>(\n  c: RationalCubicCurve2d<XT, YT>,\n): c is RationalCubicCurve2d<XT & Monotonic, YT & Monotonic> => isMonotonicX(c) && isMonotonicY(c)\n\n/** @internal */\nexport const isIncreasing = <XT, YT>(\n  c: RationalCubicCurve2d<XT, YT>,\n): c is RationalCubicCurve2d<XT & Increasing, YT & Increasing> =>\n  isIncreasingX(c) && isIncreasingY(c)\n\n/** @internal */\nexport const isDecreasing = <XT, YT>(\n  c: RationalCubicCurve2d<XT, YT>,\n): c is RationalCubicCurve2d<XT & Decreasing, YT & Decreasing> =>\n  isDecreasingX(c) && isDecreasingY(c)\n\nconst fail = (m: string): never => {\n  throw new Error(m)\n}\n\n/** @internal */\nexport const asMonotonicX = <XT, YT>(\n  c: RationalCubicCurve2d<XT, YT>,\n): RationalCubicCurve2d<XT & Monotonic, YT> =>\n  isMonotonicX(c) ? c : fail('rational cubic curve is not monotonic in x')\n\n/** @internal */\nexport const asIncreasingX = <XT, YT>(\n  c: RationalCubicCurve2d<XT, YT>,\n): RationalCubicCurve2d<XT & Increasing, YT> =>\n  isIncreasingX(c) ? c : fail('rational cubic curve is not increasing in x')\n\n/** @internal */\nexport const asDecreasingX = <XT, YT>(\n  c: RationalCubicCurve2d<XT, YT>,\n): RationalCubicCurve2d<XT & Decreasing, YT> =>\n  isDecreasingX(c) ? c : fail('rational cubic curve is not decreasing in x')\n\n/** @internal */\nexport const asMonotonicY = <XT, YT>(\n  c: RationalCubicCurve2d<XT, YT>,\n): RationalCubicCurve2d<XT, YT & Monotonic> =>\n  isMonotonicY(c) ? c : fail('rational cubic curve is not monotonic in y')\n\n/** @internal */\nexport const asIncreasingY = <XT, YT>(\n  c: RationalCubicCurve2d<XT, YT>,\n): RationalCubicCurve2d<XT, YT & Increasing> =>\n  isIncreasingY(c) ? c : fail('rational cubic curve is not increasing in y')\n\n/** @internal */\nexport const asDecreasingY = <XT, YT>(\n  c: RationalCubicCurve2d<XT, YT>,\n): RationalCubicCurve2d<XT, YT & Decreasing> =>\n  isDecreasingY(c) ? c : fail('rational cubic curve is not decreasing in y')\n\n/** @internal */\nexport const asMonotonic = <XT, YT>(\n  c: RationalCubicCurve2d<XT, YT>,\n): RationalCubicCurve2d<XT & Monotonic, YT & Monotonic> =>\n  isMonotonic(c) ? c : fail('rational cubic curve is not monotonic in both axes')\n\n/** @internal */\nexport const asIncreasing = <XT, YT>(\n  c: RationalCubicCurve2d<XT, YT>,\n): RationalCubicCurve2d<XT & Increasing, YT & Increasing> =>\n  isIncreasing(c) ? c : fail('rational cubic curve is not increasing in both axes')\n\n/** @internal */\nexport const asDecreasing = <XT, YT>(\n  c: RationalCubicCurve2d<XT, YT>,\n): RationalCubicCurve2d<XT & Decreasing, YT & Decreasing> =>\n  isDecreasing(c) ? c : fail('rational cubic curve is not decreasing in both axes')\n\n// Depth cap for tight bounding box recursion. 2²⁰ ≈ 1M leaves is well past\n// the point where any geometrically meaningful tolerance would still be\n// driving subdivision — the cap is here to guard against tolerances\n// approaching zero.\nconst MAX_BBOX_DEPTH = 20\n\n/** @internal */\nexport const boundingBox = dual<\n  (\n    tolerance: number,\n  ) => (c: RationalCubicCurve2d) => Interval2d.Interval2d<Interval.Closed, Interval.Closed>,\n  (\n    c: RationalCubicCurve2d,\n    tolerance: number,\n  ) => Interval2d.Interval2d<Interval.Closed, Interval.Closed>\n>(2, (c: RationalCubicCurve2d, tolerance: number) => {\n  invariant(\n    Number.isFinite(tolerance) && tolerance > 0,\n    'boundingBox: tolerance must be finite and > 0',\n  )\n\n  // Polynomial fast path: when W(t) is a constant (all weights equal at the\n  // source), the curve coincides with a polynomial cubic and its tight box\n  // is exact via the polynomial's per-axis range. No subdivision needed.\n  if (c.w.c1 === 0 && c.w.c2 === 0 && c.w.c3 === 0) {\n    const w = c.w.c0\n    return Interval2d.make(\n      CubicPolynomial.unitRange(\n        CubicPolynomial.make(c.x.c0 / w, c.x.c1 / w, c.x.c2 / w, c.x.c3 / w),\n      ),\n      CubicPolynomial.unitRange(\n        CubicPolynomial.make(c.y.c0 / w, c.y.c1 / w, c.y.c2 / w, c.y.c3 / w),\n      ),\n    )\n  }\n\n  // Per-segment recursion: union of leaf-segment hull AABBs, subdividing until\n  // each leaf's hull is within `tolerance` per side of an inner reference that\n  // is known to lie inside the curve's true range.\n  //\n  // The reference is the segment's endpoint AABB: `r(0)` and `r(1)` both lie\n  // on the curve and therefore inside its true bounding box. So\n  //   endpointBox ⊆ trueBox ⊆ hullBox\n  // and the gap `hullBox − endpointBox` (per side) upper-bounds the gap\n  // `hullBox − trueBox`. When that gap is ≤ tolerance on every side, the\n  // leaf's hull box is provably within tolerance of its true range; the\n  // union of all leaves is then within tolerance of the curve's tight box.\n  const recurse = (\n    curr: RationalCubicCurve2d,\n    depth: number,\n  ): Interval2d.Interval2d<Interval.Closed, Interval.Closed> => {\n    const hull = hullBoundingBox(curr)\n\n    const w0 = curr.w.c0\n    const x0 = curr.x.c0 / w0\n    const y0 = curr.y.c0 / w0\n    const w1 = curr.w.c0 + curr.w.c1 + curr.w.c2 + curr.w.c3\n    const x1 = (curr.x.c0 + curr.x.c1 + curr.x.c2 + curr.x.c3) / w1\n    const y1 = (curr.y.c0 + curr.y.c1 + curr.y.c2 + curr.y.c3) / w1\n\n    const lowX = Math.min(x0, x1)\n    const highX = Math.max(x0, x1)\n    const lowY = Math.min(y0, y1)\n    const highY = Math.max(y0, y1)\n\n    const excess = Math.max(\n      lowX - hull.x.start,\n      hull.x.end - highX,\n      lowY - hull.y.start,\n      hull.y.end - highY,\n    )\n\n    if (excess <= tolerance || depth >= MAX_BBOX_DEPTH) {\n      return hull\n    }\n\n    const [left, right] = subdivide(curr, 0.5)\n    return Interval2d.union(recurse(left, depth + 1), recurse(right, depth + 1))\n  }\n\n  return recurse(c, 0)\n})\n\n// Approximation cap. At depth 20 we'd emit up to 2²⁰ ≈ 1M segments for one\n// input curve — well past any sane target — so the cap is really just a guard\n// against pathological tolerances (e.g. tolerance approaching 0).\nconst MAX_APPROX_DEPTH = 20\n\n// Builds the polynomial-cubic candidate for one rational segment by:\n//   1. Inverting Bernstein → monomial on each of x, y, w to recover the four\n//      homogeneous Bézier control points (Xᵢ, Yᵢ, Wᵢ).\n//   2. Projecting each CP back to 2D as (Xᵢ/Wᵢ, Yᵢ/Wᵢ).\n//   3. Lifting those 2D CPs back to a polynomial cubic via fromBezierPoints.\n// The result matches the rational at t=0 and t=1 exactly and matches endpoint\n// tangent directions, but interior shape diverges whenever the weights are\n// not all equal.\nconst buildCubicCandidate = (c: RationalCubicCurve2d): CubicCurve2d.CubicCurve2d => {\n  const x0 = c.x.c0\n  const x1 = c.x.c0 + c.x.c1 / 3\n  const x2 = c.x.c0 + (2 * c.x.c1) / 3 + c.x.c2 / 3\n  const x3 = c.x.c0 + c.x.c1 + c.x.c2 + c.x.c3\n\n  const y0 = c.y.c0\n  const y1 = c.y.c0 + c.y.c1 / 3\n  const y2 = c.y.c0 + (2 * c.y.c1) / 3 + c.y.c2 / 3\n  const y3 = c.y.c0 + c.y.c1 + c.y.c2 + c.y.c3\n\n  const w0 = c.w.c0\n  const w1 = c.w.c0 + c.w.c1 / 3\n  const w2 = c.w.c0 + (2 * c.w.c1) / 3 + c.w.c2 / 3\n  const w3 = c.w.c0 + c.w.c1 + c.w.c2 + c.w.c3\n\n  return CubicCurve2d.fromBezierPoints(\n    Vector2.make(x0 / w0, y0 / w0),\n    Vector2.make(x1 / w1, y1 / w1),\n    Vector2.make(x2 / w2, y2 / w2),\n    Vector2.make(x3 / w3, y3 / w3),\n  )\n}\n\n// Splits a rational cubic at parameter `t ∈ (0, 1)` by applying\n// `CubicPolynomial.subdivide` independently to each of x, y, w. Equivalent to\n// de Casteljau on the homogeneous control polygon but stays in monomial form\n// throughout, so no Bernstein round-trip is required.\n/** @internal */\nexport const subdivide = dual<\n  (t: number) => (c: RationalCubicCurve2d) => [RationalCubicCurve2d, RationalCubicCurve2d],\n  (c: RationalCubicCurve2d, t: number) => [RationalCubicCurve2d, RationalCubicCurve2d]\n>(2, (c: RationalCubicCurve2d, t: number) => {\n  const [leftX, rightX] = CubicPolynomial.subdivide(c.x, t)\n  const [leftY, rightY] = CubicPolynomial.subdivide(c.y, t)\n  const [leftW, rightW] = CubicPolynomial.subdivide(c.w, t)\n\n  return [\n    new RationalCubicCurve2dImpl(leftX, leftY, leftW),\n    new RationalCubicCurve2dImpl(rightX, rightY, rightW),\n  ]\n})\n\n// Loose hull-based bounding box from the rational's projected Bézier control\n// polygon. Private leaf helper for the subdivision-based public `boundingBox`\n// and for the Hausdorff machinery in `approximateAsCubicCurves`.\n//\n// Rational Bézier curves with positive weights satisfy the projected\n// convex-hull property: the curve lies inside the convex hull of the four\n// projected 2D control points (Wᵢ⁻¹·Xᵢ, Wᵢ⁻¹·Yᵢ). Their AABB is a strict\n// superset of the hull, so it is a valid (and cheap) bound on the curve.\n//\n// Looser than the public tight box — for that we'd need the extrema of\n// x(t)/w(t) and y(t)/w(t), each a degree-5 root problem — but tight enough\n// for subdivision-based geometric queries, which compensate via depth.\nconst hullBoundingBox = (\n  c: RationalCubicCurve2d,\n): Interval2d.Interval2d<Interval.Closed, Interval.Closed> => {\n  // Bernstein control points recovered from monomial coefficients — same\n  // inversion as `buildCubicCandidate`.\n  const x0 = c.x.c0\n  const x1 = c.x.c0 + c.x.c1 / 3\n  const x2 = c.x.c0 + (2 * c.x.c1) / 3 + c.x.c2 / 3\n  const x3 = c.x.c0 + c.x.c1 + c.x.c2 + c.x.c3\n\n  const y0 = c.y.c0\n  const y1 = c.y.c0 + c.y.c1 / 3\n  const y2 = c.y.c0 + (2 * c.y.c1) / 3 + c.y.c2 / 3\n  const y3 = c.y.c0 + c.y.c1 + c.y.c2 + c.y.c3\n\n  const w0 = c.w.c0\n  const w1 = c.w.c0 + c.w.c1 / 3\n  const w2 = c.w.c0 + (2 * c.w.c1) / 3 + c.w.c2 / 3\n  const w3 = c.w.c0 + c.w.c1 + c.w.c2 + c.w.c3\n\n  return Interval2d.fromVectors(\n    Vector2.make(x0 / w0, y0 / w0),\n    Vector2.make(x1 / w1, y1 / w1),\n    Vector2.make(x2 / w2, y2 / w2),\n    Vector2.make(x3 / w3, y3 / w3),\n  )\n}\n\n// Certified Hausdorff-within-tolerance check between a rational and a\n// candidate polynomial cubic.\n//\n// `approximateAsCubicCurves` uses this as the stopping criterion: when it\n// returns `true`, every point on the rational is provably within `tolerance`\n// of the candidate, and every point on the candidate is within `tolerance` of\n// the rational. When `false`, the rational is subdivided and the procedure\n// recurses.\n//\n// Implementation: for each direction (rational → candidate, candidate →\n// rational), run a depth-first subdivision on the source side. At each\n// piece, compute\n//\n//   lower = dist(witness-on-piece, target)\n//   upper = min(\n//     lower + maxDist(witness, piece.box),     // triangle inequality bound\n//     maxDist(piece.box, target.box),          // box-pair bound\n//   )\n//\n// Both upper bounds are provable; their min is too. The triangle bound\n// shrinks proportionally to source box diameter, so it dominates when source\n// and target overlap (which they usually do here — the candidate matches the\n// rational at endpoints and tangents). Early-terminate on the first piece\n// whose `lower` exceeds `tolerance` (definitive miss) or accept whenever\n// every piece's `upper` ≤ tolerance.\n\nconst MAX_HAUSDORFF_DEPTH = 30\n\n// Coarse sample + bisection on the squared-distance derivative. Returns the\n// minimum squared distance from (qx, qy) to a parametric curve described by\n// `eval_`. Stationary points of (P(s) - q) · P'(s) are local extrema of\n// D²(s); 32 coarse samples reliably bracket the global min for cubic-degree\n// curves (which have at most ~5 critical points of squared distance).\nconst closestSquaredDistance = (\n  eval_: (s: number) => { px: number; py: number; tx: number; ty: number },\n  qx: number,\n  qy: number,\n): number => {\n  const coarseSamples = 32\n  let sBest = 0\n  let d2Best = Number.POSITIVE_INFINITY\n  for (let i = 0; i <= coarseSamples; i++) {\n    const s = i / coarseSamples\n    const { px, py } = eval_(s)\n    const dx = px - qx\n    const dy = py - qy\n    const d2 = dx * dx + dy * dy\n    if (d2 < d2Best) {\n      d2Best = d2\n      sBest = s\n    }\n  }\n  const step = 1 / coarseSamples\n  let lo = Math.max(0, sBest - step)\n  let hi = Math.min(1, sBest + step)\n  const gradient = (s: number): number => {\n    const { px, py, tx, ty } = eval_(s)\n    return (px - qx) * tx + (py - qy) * ty\n  }\n  if (gradient(lo) > 0 || gradient(hi) < 0) {\n    return d2Best\n  }\n  for (let i = 0; i < 40; i++) {\n    const m = 0.5 * (lo + hi)\n    if (gradient(m) > 0) {\n      hi = m\n    } else {\n      lo = m\n    }\n    if (hi - lo < 1e-12) {\n      break\n    }\n  }\n  const s = 0.5 * (lo + hi)\n  const { px, py } = eval_(s)\n  const dx = px - qx\n  const dy = py - qy\n  const d2 = dx * dx + dy * dy\n  return d2 < d2Best ? d2 : d2Best\n}\n\nconst polynomialEval = (c: CubicCurve2d.CubicCurve2d, s: number) => ({\n  px: c.x.c0 + s * (c.x.c1 + s * (c.x.c2 + s * c.x.c3)),\n  py: c.y.c0 + s * (c.y.c1 + s * (c.y.c2 + s * c.y.c3)),\n  tx: c.x.c1 + s * (2 * c.x.c2 + s * 3 * c.x.c3),\n  ty: c.y.c1 + s * (2 * c.y.c2 + s * 3 * c.y.c3),\n})\n\n// R(s) = (X(s)/W(s), Y(s)/W(s))  →  R'(s) = ((X'W - XW')/W², (Y'W - YW')/W²)\nconst rationalEval = (c: RationalCubicCurve2d, s: number) => {\n  const X = c.x.c0 + s * (c.x.c1 + s * (c.x.c2 + s * c.x.c3))\n  const Y = c.y.c0 + s * (c.y.c1 + s * (c.y.c2 + s * c.y.c3))\n  const W = c.w.c0 + s * (c.w.c1 + s * (c.w.c2 + s * c.w.c3))\n  const Xp = c.x.c1 + s * (2 * c.x.c2 + s * 3 * c.x.c3)\n  const Yp = c.y.c1 + s * (2 * c.y.c2 + s * 3 * c.y.c3)\n  const Wp = c.w.c1 + s * (2 * c.w.c2 + s * 3 * c.w.c3)\n  const w2 = W * W\n  return {\n    px: X / W,\n    py: Y / W,\n    tx: (Xp * W - X * Wp) / w2,\n    ty: (Yp * W - Y * Wp) / w2,\n  }\n}\n\nconst maxDistFromPointToBox = (px: number, py: number, box: Interval2d.Interval2d): number => {\n  const xLo = Math.min(box.x.start, box.x.end)\n  const xHi = Math.max(box.x.start, box.x.end)\n  const yLo = Math.min(box.y.start, box.y.end)\n  const yHi = Math.max(box.y.start, box.y.end)\n  const dx = Math.max(px - xLo, xHi - px)\n  const dy = Math.max(py - yLo, yHi - py)\n  return Math.hypot(dx, dy)\n}\n\n// Subdivide a polynomial cubic curve at parameter t by subdividing each\n// per-axis polynomial independently — the polynomial split is exact and in\n// monomial form.\nconst subdividePolynomial = (\n  c: CubicCurve2d.CubicCurve2d,\n  t: number,\n): [CubicCurve2d.CubicCurve2d, CubicCurve2d.CubicCurve2d] => {\n  const [leftX, rightX] = CubicPolynomial.subdivide(c.x, t)\n  const [leftY, rightY] = CubicPolynomial.subdivide(c.y, t)\n  return [CubicCurve2d.fromPolynomials(leftX, leftY), CubicCurve2d.fromPolynomials(rightX, rightY)]\n}\n\ninterface CertifiedPiece {\n  box: Interval2d.Interval2d\n  witnessX: number\n  witnessY: number\n  depth: number\n  subdivide(): [CertifiedPiece, CertifiedPiece]\n}\n\nconst rationalPiece = (c: RationalCubicCurve2d, depth = 0): CertifiedPiece => {\n  const wMid = CubicPolynomial.solve(c.w, 0.5)\n  const witnessX = CubicPolynomial.solve(c.x, 0.5) / wMid\n  const witnessY = CubicPolynomial.solve(c.y, 0.5) / wMid\n  return {\n    box: hullBoundingBox(c),\n    witnessX,\n    witnessY,\n    depth,\n    subdivide: () => {\n      const [left, right] = subdivide(c, 0.5)\n      return [rationalPiece(left, depth + 1), rationalPiece(right, depth + 1)]\n    },\n  }\n}\n\nconst polynomialPiece = (c: CubicCurve2d.CubicCurve2d, depth = 0): CertifiedPiece => {\n  const witnessX = CubicPolynomial.solve(c.x, 0.5)\n  const witnessY = CubicPolynomial.solve(c.y, 0.5)\n  return {\n    box: CubicCurve2d.boundingBox(c),\n    witnessX,\n    witnessY,\n    depth,\n    subdivide: () => {\n      const [left, right] = subdividePolynomial(c, 0.5)\n      return [polynomialPiece(left, depth + 1), polynomialPiece(right, depth + 1)]\n    },\n  }\n}\n\nconst oneSidedWithinTolerance = (\n  initialPiece: CertifiedPiece,\n  targetBox: Interval2d.Interval2d,\n  targetClosestSquared: (qx: number, qy: number) => number,\n  tolerance: number,\n): boolean => {\n  const tol2 = tolerance * tolerance\n  const stack: Array<CertifiedPiece> = [initialPiece]\n  while (stack.length > 0) {\n    const piece = stack.pop() as CertifiedPiece\n    const lower2 = targetClosestSquared(piece.witnessX, piece.witnessY)\n    if (lower2 > tol2) {\n      return false\n    }\n    const lower = Math.sqrt(lower2)\n    const triangleUpper = lower + maxDistFromPointToBox(piece.witnessX, piece.witnessY, piece.box)\n    const boxPairUpper = Interval2d.maxDistance(piece.box, targetBox)\n    const upper = triangleUpper < boxPairUpper ? triangleUpper : boxPairUpper\n    if (upper <= tolerance) {\n      continue\n    }\n    if (piece.depth >= MAX_HAUSDORFF_DEPTH) {\n      return false\n    }\n    const [left, right] = piece.subdivide()\n    stack.push(left, right)\n  }\n  return true\n}\n\nconst hausdorffWithinTolerance = (\n  rational: RationalCubicCurve2d,\n  candidate: CubicCurve2d.CubicCurve2d,\n  tolerance: number,\n): boolean => {\n  // Algebraic fast path: when the denominator polynomial is constant — every\n  // weighted Bézier control point shares the same weight, so the rational\n  // reduces to a polynomial cubic — `buildCubicCandidate` is exact. The\n  // Bernstein → monomial transform produces exact zero higher coefficients\n  // for a uniform input (integer cancellation), and `CubicPolynomial.subdivide`\n  // preserves constants, so this check holds at every recursion depth.\n  //\n  // Without this fast path the subdivision Hausdorff would take ~30 levels\n  // to certify the coincident-curve case at sub-pixel tolerances, even\n  // though the answer is exactly zero.\n  if (rational.w.c1 === 0 && rational.w.c2 === 0 && rational.w.c3 === 0) {\n    return true\n  }\n\n  const candidateBox = CubicCurve2d.boundingBox(candidate)\n  if (\n    !oneSidedWithinTolerance(\n      rationalPiece(rational),\n      candidateBox,\n      (qx, qy) => closestSquaredDistance((s) => polynomialEval(candidate, s), qx, qy),\n      tolerance,\n    )\n  ) {\n    return false\n  }\n  const rationalBox = hullBoundingBox(rational)\n  return oneSidedWithinTolerance(\n    polynomialPiece(candidate),\n    rationalBox,\n    (qx, qy) => closestSquaredDistance((s) => rationalEval(rational, s), qx, qy),\n    tolerance,\n  )\n}\n\n/** @internal */\nexport const approximateAsCubicCurves = dual<\n  (tolerance: number) => (c: RationalCubicCurve2d) => ReadonlyArray<CubicCurve2d.CubicCurve2d>,\n  (c: RationalCubicCurve2d, tolerance: number) => ReadonlyArray<CubicCurve2d.CubicCurve2d>\n>(2, (c: RationalCubicCurve2d, tolerance: number) => {\n  invariant(\n    Number.isFinite(tolerance) && tolerance > 0,\n    'approximateAsCubicCurves: tolerance must be finite and > 0',\n  )\n\n  const out: Array<CubicCurve2d.CubicCurve2d> = []\n  const recurse = (curr: RationalCubicCurve2d, depth: number): void => {\n    const candidate = buildCubicCandidate(curr)\n    if (depth >= MAX_APPROX_DEPTH || hausdorffWithinTolerance(curr, candidate, tolerance)) {\n      out.push(candidate)\n      return\n    }\n    const [left, right] = subdivide(curr, 0.5)\n    recurse(left, depth + 1)\n    recurse(right, depth + 1)\n  }\n  recurse(c, 0)\n  return out\n})\n","import type { Closed } from '../interval/interval.ts'\nimport type { Interval2d } from '../interval/interval2d.ts'\nimport type { Monotonicity } from '../monotonicity/monotonicity.ts'\nimport type { Pipeable } from '../utils.ts'\nimport type { CubicPolynomial } from '../polynomial/cubic.ts'\nimport type { Decreasing, Increasing, Monotonic } from '../polynomial/traits.ts'\nimport type * as Solution from '../solution/solution.ts'\nimport type { Vector2, Weighted } from '../vector/vector2.ts'\nimport type { CubicCurve2d } from './cubic2d.ts'\nimport type { RationalCubicCurve2dTypeId, RationalCurveTraits } from './rationalCubic2d.internal.ts'\nimport * as internal from './rationalCubic2d.internal.ts'\n\nexport type { Decreasing, Increasing, Monotonic } from '../polynomial/traits.ts'\nexport { RationalCurveTraits } from './rationalCubic2d.internal.ts'\n\n/**\n * A rational cubic curve in 2D space.\n *\n * Represented as three cubic polynomials in the parameter `t`: per-axis\n * numerators `x`, `y`, and a shared denominator `w`. Evaluation is\n * `(x(t)/w(t), y(t)/w(t))` — the projection from homogeneous coordinates\n * back to the plane. With all weights equal at the source (e.g. produced\n * from a non-rational Bézier with unit weights), `w` is constant and the\n * curve coincides with a polynomial cubic.\n *\n * The two type parameters carry per-axis monotonicity trait brands attached\n * to the rational functions `x(t)/w(t)` and `y(t)/w(t)`. Unlike\n * `CubicCurve2d`, traits do not flow through to the underlying polynomials —\n * monotonicity of a ratio of cubics is not the same property as monotonicity\n * of either cubic alone, so the brand lives on the curve itself. Constructors\n * with construction-time monotonicity guarantees (e.g. {@link makeMonotonicEasing})\n * return curves with `Increasing` brands attached, narrowing downstream\n * operations like {@link solveAtX} to single-solution returns.\n *\n * All fields are readonly and immutable, and all operations create new instances.\n *\n * @since 2.0.0\n */\nexport interface RationalCubicCurve2d<\n  out XTraits = unknown,\n  out YTraits = unknown,\n> extends Pipeable {\n  readonly [RationalCubicCurve2dTypeId]: RationalCubicCurve2dTypeId\n  readonly [RationalCurveTraits]: [XTraits, YTraits]\n  readonly x: CubicPolynomial\n  readonly y: CubicPolynomial\n  readonly w: CubicPolynomial\n}\n\n/**\n * Checks if a value is a `RationalCubicCurve2d`.\n *\n * @param c - The value to check.\n * @returns `true` if the value is a `RationalCubicCurve2d`, `false` otherwise.\n * @since 2.0.0\n */\nexport const isRationalCubicCurve2d: (c: unknown) => c is RationalCubicCurve2d =\n  internal.isRationalCubicCurve2d\n\n/**\n * Creates a new `RationalCubicCurve2d` from per-axis numerator polynomials\n * and a shared denominator polynomial.\n *\n * @param x - The x numerator polynomial.\n * @param y - The y numerator polynomial.\n * @param w - The shared denominator polynomial (must be non-zero on `[0, 1]`).\n * @returns A new `RationalCubicCurve2d` instance.\n * @since 2.0.0\n */\nexport const fromPolynomials: (\n  x: CubicPolynomial,\n  y: CubicPolynomial,\n  w: CubicPolynomial,\n) => RationalCubicCurve2d = internal.fromPolynomials\n\n/**\n * Creates a new `RationalCubicCurve2d` from four weighted cubic Bézier\n * control points. The four control points are lifted to homogeneous form\n * `(w·x, w·y, w)` and the cubic Bernstein basis is expanded into per-channel\n * monomial coefficients, yielding the curve's `x`, `y`, and `w` polynomials.\n *\n * @param p0 - The first weighted control point (curve start).\n * @param p1 - The second weighted control point (start handle).\n * @param p2 - The third weighted control point (end handle).\n * @param p3 - The fourth weighted control point (curve end).\n * @returns A new `RationalCubicCurve2d` instance.\n * @since 2.0.0\n */\nexport const fromBezierPoints: (\n  p0: Weighted,\n  p1: Weighted,\n  p2: Weighted,\n  p3: Weighted,\n) => RationalCubicCurve2d = internal.fromBezierPoints\n\n/**\n * Creates a guaranteed-monotonic rational cubic easing curve via Gregory-\n * Delbourgo style construction. The result interpolates `(0, 0)` and\n * `(1, 1)` with the given endpoint slopes, with `x(t) = t` pinned linearly\n * and a rational cubic numerator for `y(t)`. Monotonicity of `y(t)` is\n * verified rigorously at construction (degree-3 polynomial sign analysis);\n * the returned curve is branded `<Increasing, Increasing>` so that\n * {@link solveAtX} returns `Solution.AtMostOne<number>` without further\n * trait refinement.\n *\n * For input slope combinations that the default Gregory-Delbourgo\n * construction cannot accommodate (typically when one slope is large while\n * the other is small), construction throws. Useful operating range is\n * roughly `m₀, m₁ ∈ [0, 2]` with `m₀ + m₁ ≲ 3`; smoothstep (`0, 0`) and\n * linear (`1, 1`) fall out as special cases.\n *\n * @param startSlope - The easing function's slope at the start (`dy/dx` at `x = 0`); must be finite and non-negative.\n * @param endSlope - The easing function's slope at the end (`dy/dx` at `x = 1`); must be finite and non-negative.\n * @returns A monotone-by-construction rational cubic easing curve.\n * @throws When slopes are negative, non-finite, or produce a non-monotonic curve under the default construction.\n * @since 2.0.0\n */\nexport const makeMonotonicEasing: (\n  startSlope: number,\n  endSlope: number,\n) => RationalCubicCurve2d<Increasing, Increasing> = internal.makeMonotonicEasing as never\n\nexport const solve: {\n  /**\n   * Evaluates the rational cubic curve at parameter `t`. Returns\n   * `(x(t)/w(t), y(t)/w(t))` — three Horner evaluations and two divisions.\n   *\n   * @param c - The curve to evaluate.\n   * @param t - The parameter value.\n   * @returns The point on the curve at parameter `t`.\n   * @since 2.0.0\n   */\n  (c: RationalCubicCurve2d, t: number): Vector2\n  /**\n   * Evaluates the rational cubic curve at parameter `t`.\n   *\n   * @param t - The parameter value.\n   * @returns A function that takes a curve and returns the point at `t`.\n   * @since 2.0.0\n   */\n  (t: number): (c: RationalCubicCurve2d) => Vector2\n} = internal.solve\n\nexport const solveAtX: {\n  /**\n   * Evaluates the curve's y values at a given x. Because the curve's x axis\n   * carries the `Monotonic` brand, the inverse has at most one solution.\n   *\n   * @param c - The rational cubic curve with monotonic x.\n   * @param x - The x coordinate.\n   * @returns Zero or one y values.\n   * @since 2.0.0\n   */\n  <XT extends Monotonic, YT>(c: RationalCubicCurve2d<XT, YT>, x: number): Solution.AtMostOne<number>\n  /**\n   * Evaluates the curve's y values at a given x. Up to three solutions —\n   * `(X(t) - x·W(t))` is a cubic polynomial in `t`.\n   *\n   * @param c - The rational cubic curve.\n   * @param x - The x coordinate.\n   * @returns The y values at x, in t-ascending order.\n   * @since 2.0.0\n   */\n  <XT, YT>(c: RationalCubicCurve2d<XT, YT>, x: number): Solution.AtMostThree<number>\n  /** @since 2.0.0 */\n  (x: number): {\n    <XT extends Monotonic, YT>(c: RationalCubicCurve2d<XT, YT>): Solution.AtMostOne<number>\n    <XT, YT>(c: RationalCubicCurve2d<XT, YT>): Solution.AtMostThree<number>\n  }\n} = internal.solveAtX as never\n\nexport const solveAtY: {\n  /**\n   * Evaluates the curve's x values at a given y. Because the curve's y axis\n   * carries the `Monotonic` brand, the inverse has at most one solution.\n   *\n   * @param c - The rational cubic curve with monotonic y.\n   * @param y - The y coordinate.\n   * @returns Zero or one x values.\n   * @since 2.0.0\n   */\n  <XT, YT extends Monotonic>(c: RationalCubicCurve2d<XT, YT>, y: number): Solution.AtMostOne<number>\n  /**\n   * Evaluates the curve's x values at a given y. Up to three solutions.\n   *\n   * @param c - The rational cubic curve.\n   * @param y - The y coordinate.\n   * @returns The x values at y, in t-ascending order.\n   * @since 2.0.0\n   */\n  <XT, YT>(c: RationalCubicCurve2d<XT, YT>, y: number): Solution.AtMostThree<number>\n  /** @since 2.0.0 */\n  (y: number): {\n    <XT, YT extends Monotonic>(c: RationalCubicCurve2d<XT, YT>): Solution.AtMostOne<number>\n    <XT, YT>(c: RationalCubicCurve2d<XT, YT>): Solution.AtMostThree<number>\n  }\n} = internal.solveAtY as never\n\nexport const subdivide: {\n  /**\n   * Subdivides a rational cubic curve at parameter `t ∈ (0, 1)` into two new\n   * rational cubic curves. The first curve's evaluation on `[0, 1]` matches\n   * the original's on `[0, t]`; the second matches the original's on `[t, 1]`.\n   * Equivalent to de Casteljau subdivision on the homogeneous control polygon,\n   * but performed directly on the per-axis monomial polynomials.\n   *\n   * @param c - The rational cubic curve to subdivide.\n   * @param t - The split parameter; must be in the open interval `(0, 1)`.\n   * @returns A `[left, right]` tuple of rational cubic curves.\n   * @since 2.0.0\n   */\n  (c: RationalCubicCurve2d, t: number): [RationalCubicCurve2d, RationalCubicCurve2d]\n  /**\n   * Subdivides a rational cubic curve at parameter `t ∈ (0, 1)`.\n   *\n   * @param t - The split parameter; must be in the open interval `(0, 1)`.\n   * @returns A function that takes a curve and returns its `[left, right]` halves.\n   * @since 2.0.0\n   */\n  (t: number): (c: RationalCubicCurve2d) => [RationalCubicCurve2d, RationalCubicCurve2d]\n} = internal.subdivide\n\nexport const boundingBox: {\n  /**\n   * Computes a closed axis-aligned bounding box for a rational cubic curve,\n   * tight to within `tolerance` per side.\n   *\n   * Implemented as recursive subdivision: at each leaf the curve segment's\n   * loose hull AABB (cheap, always valid) is compared against the segment's\n   * endpoint AABB (which the curve provably visits). When the per-side gap\n   * between them is ≤ `tolerance`, the leaf returns its hull; otherwise the\n   * segment is split at `t = 0.5` and the procedure recurses, unioning the\n   * halves.\n   *\n   * The returned box is provably within `tolerance` of the true tight box on\n   * every side, and contains the curve since each leaf hull does. The\n   * polynomial cubic case (uniform weights) is handled by a fast path that\n   * computes the exact box from per-axis cubic extrema, with no subdivision.\n   *\n   * @param c - The rational cubic curve.\n   * @param tolerance - Maximum allowed slack per side; must be positive.\n   * @returns A closed `Interval2d` enclosing the curve, tight to within `tolerance`.\n   * @since 2.0.0\n   */\n  (c: RationalCubicCurve2d, tolerance: number): Interval2d<Closed, Closed>\n  /**\n   * Computes a closed axis-aligned bounding box for a rational cubic curve.\n   *\n   * @param tolerance - Maximum allowed slack per side; must be positive.\n   * @returns A function that takes a curve and returns its bounding box.\n   * @since 2.0.0\n   */\n  (tolerance: number): (c: RationalCubicCurve2d) => Interval2d<Closed, Closed>\n} = internal.boundingBox\n\n/**\n * Classifies the monotonicity of the curve's `x(t) = X(t)/W(t)` projection on\n * the unit interval `[0, 1]`.\n *\n * Decided via Bernstein sign convexity on the derivative-numerator polynomial\n * `q(t) = X'·W − X·W'`. Since `W² > 0` wherever the curve is well-defined,\n * the sign of `dx/dt` equals the sign of `q`. Although `q` is a difference of\n * degree-5 products, the leading terms cancel and `q` is in fact a quartic —\n * its 5 Bernstein coefficients on `[0, 1]` are evaluated for uniform sign,\n * with de Casteljau subdivision to resolve mixed-sign cases. The procedure is\n * exact except at tangential zeros, where it conservatively reports `None`.\n *\n * Returning `Increasing` or `Decreasing` is the trigger for\n * {@link asMonotonic} / {@link asIncreasing} / {@link asDecreasing}.\n *\n * @param c - The rational cubic curve.\n * @returns The monotonicity of the curve's x projection on `[0, 1]`.\n * @since 2.0.0\n */\nexport const xMonotonicity: (c: RationalCubicCurve2d) => Monotonicity = internal.xMonotonicity\n\n/**\n * Classifies the monotonicity of the curve's `y(t) = Y(t)/W(t)` projection on\n * the unit interval `[0, 1]`. See {@link xMonotonicity} for the method.\n *\n * @param c - The rational cubic curve.\n * @returns The monotonicity of the curve's y projection on `[0, 1]`.\n * @since 2.0.0\n */\nexport const yMonotonicity: (c: RationalCubicCurve2d) => Monotonicity = internal.yMonotonicity\n\n/**\n * Type-narrowing predicate: refines the curve's x-axis trait to include\n * `Monotonic` when `x(t)/w(t)` is strictly monotonic on `[0, 1]`. The y-axis\n * trait is unchanged.\n *\n * Use this when only x-axis monotonicity is required (e.g. to make {@link solveAtX}\n * narrow to `AtMostOne` without also asserting y-axis monotonicity).\n *\n * @param c - The rational cubic curve.\n * @returns `true` when the x projection is strictly monotonic on `[0, 1]`.\n * @since 2.0.0\n */\nexport const isMonotonicX: <XT, YT>(\n  c: RationalCubicCurve2d<XT, YT>,\n) => c is RationalCubicCurve2d<XT & Monotonic, YT> = internal.isMonotonicX\n\n/**\n * Type-narrowing predicate: refines the curve's x-axis trait to include\n * `Increasing`.\n *\n * @since 2.0.0\n */\nexport const isIncreasingX: <XT, YT>(\n  c: RationalCubicCurve2d<XT, YT>,\n) => c is RationalCubicCurve2d<XT & Increasing, YT> = internal.isIncreasingX\n\n/**\n * Type-narrowing predicate: refines the curve's x-axis trait to include\n * `Decreasing`.\n *\n * @since 2.0.0\n */\nexport const isDecreasingX: <XT, YT>(\n  c: RationalCubicCurve2d<XT, YT>,\n) => c is RationalCubicCurve2d<XT & Decreasing, YT> = internal.isDecreasingX\n\n/**\n * Type-narrowing predicate: refines the curve's y-axis trait to include\n * `Monotonic`. The x-axis trait is unchanged. y analog of {@link isMonotonicX}.\n *\n * @since 2.0.0\n */\nexport const isMonotonicY: <XT, YT>(\n  c: RationalCubicCurve2d<XT, YT>,\n) => c is RationalCubicCurve2d<XT, YT & Monotonic> = internal.isMonotonicY\n\n/**\n * Type-narrowing predicate: refines the curve's y-axis trait to include\n * `Increasing`.\n *\n * @since 2.0.0\n */\nexport const isIncreasingY: <XT, YT>(\n  c: RationalCubicCurve2d<XT, YT>,\n) => c is RationalCubicCurve2d<XT, YT & Increasing> = internal.isIncreasingY\n\n/**\n * Type-narrowing predicate: refines the curve's y-axis trait to include\n * `Decreasing`.\n *\n * @since 2.0.0\n */\nexport const isDecreasingY: <XT, YT>(\n  c: RationalCubicCurve2d<XT, YT>,\n) => c is RationalCubicCurve2d<XT, YT & Decreasing> = internal.isDecreasingY\n\n/**\n * Type-narrowing predicate: refines both axes' traits to include `Monotonic`\n * when both `x(t)/w(t)` and `y(t)/w(t)` are strictly monotonic on `[0, 1]`.\n *\n * The constant case is excluded — `Monotonic` is the *strict* brand.\n *\n * @param c - The rational cubic curve.\n * @returns `true` when both axes are strictly monotonic on `[0, 1]`.\n * @since 2.0.0\n */\nexport const isMonotonic: <XT, YT>(\n  c: RationalCubicCurve2d<XT, YT>,\n) => c is RationalCubicCurve2d<XT & Monotonic, YT & Monotonic> = internal.isMonotonic\n\n/**\n * Type-narrowing predicate: refines both axes' traits to include `Increasing`\n * when both `x(t)/w(t)` and `y(t)/w(t)` are strictly increasing on `[0, 1]`.\n *\n * @since 2.0.0\n */\nexport const isIncreasing: <XT, YT>(\n  c: RationalCubicCurve2d<XT, YT>,\n) => c is RationalCubicCurve2d<XT & Increasing, YT & Increasing> = internal.isIncreasing\n\n/**\n * Type-narrowing predicate: refines both axes' traits to include `Decreasing`\n * when both `x(t)/w(t)` and `y(t)/w(t)` are strictly decreasing on `[0, 1]`.\n *\n * @since 2.0.0\n */\nexport const isDecreasing: <XT, YT>(\n  c: RationalCubicCurve2d<XT, YT>,\n) => c is RationalCubicCurve2d<XT & Decreasing, YT & Decreasing> = internal.isDecreasing\n\n/**\n * Asserts that the curve is strictly monotonic in x on `[0, 1]`, returning\n * the same curve with the x-axis trait branded `Monotonic`.\n *\n * @param c - The rational cubic curve.\n * @returns The same curve, refined with the `Monotonic` brand on x.\n * @throws When the x projection is not strictly monotonic on `[0, 1]`.\n * @since 2.0.0\n */\nexport const asMonotonicX: <XT, YT>(\n  c: RationalCubicCurve2d<XT, YT>,\n) => RationalCubicCurve2d<XT & Monotonic, YT> = internal.asMonotonicX\n\n/**\n * Asserts that the curve is strictly increasing in x on `[0, 1]`.\n *\n * @since 2.0.0\n */\nexport const asIncreasingX: <XT, YT>(\n  c: RationalCubicCurve2d<XT, YT>,\n) => RationalCubicCurve2d<XT & Increasing, YT> = internal.asIncreasingX\n\n/**\n * Asserts that the curve is strictly decreasing in x on `[0, 1]`.\n *\n * @since 2.0.0\n */\nexport const asDecreasingX: <XT, YT>(\n  c: RationalCubicCurve2d<XT, YT>,\n) => RationalCubicCurve2d<XT & Decreasing, YT> = internal.asDecreasingX\n\n/**\n * Asserts that the curve is strictly monotonic in y on `[0, 1]`. y analog of\n * {@link asMonotonicX}.\n *\n * @since 2.0.0\n */\nexport const asMonotonicY: <XT, YT>(\n  c: RationalCubicCurve2d<XT, YT>,\n) => RationalCubicCurve2d<XT, YT & Monotonic> = internal.asMonotonicY\n\n/**\n * Asserts that the curve is strictly increasing in y on `[0, 1]`.\n *\n * @since 2.0.0\n */\nexport const asIncreasingY: <XT, YT>(\n  c: RationalCubicCurve2d<XT, YT>,\n) => RationalCubicCurve2d<XT, YT & Increasing> = internal.asIncreasingY\n\n/**\n * Asserts that the curve is strictly decreasing in y on `[0, 1]`.\n *\n * @since 2.0.0\n */\nexport const asDecreasingY: <XT, YT>(\n  c: RationalCubicCurve2d<XT, YT>,\n) => RationalCubicCurve2d<XT, YT & Decreasing> = internal.asDecreasingY\n\n/**\n * Asserts that the curve is strictly monotonic in both axes on `[0, 1]`,\n * returning the same curve with both axes branded `Monotonic`.\n *\n * @param c - The rational cubic curve.\n * @returns The same curve, refined with the `Monotonic` brand on both axes.\n * @throws When either axis is not strictly monotonic on `[0, 1]`.\n * @since 2.0.0\n */\nexport const asMonotonic: <XT, YT>(\n  c: RationalCubicCurve2d<XT, YT>,\n) => RationalCubicCurve2d<XT & Monotonic, YT & Monotonic> = internal.asMonotonic\n\n/**\n * Asserts that the curve is strictly increasing in both axes on `[0, 1]`,\n * returning the same curve with both axes branded `Increasing`.\n *\n * @since 2.0.0\n */\nexport const asIncreasing: <XT, YT>(\n  c: RationalCubicCurve2d<XT, YT>,\n) => RationalCubicCurve2d<XT & Increasing, YT & Increasing> = internal.asIncreasing\n\n/**\n * Asserts that the curve is strictly decreasing in both axes on `[0, 1]`,\n * returning the same curve with both axes branded `Decreasing`.\n *\n * @since 2.0.0\n */\nexport const asDecreasing: <XT, YT>(\n  c: RationalCubicCurve2d<XT, YT>,\n) => RationalCubicCurve2d<XT & Decreasing, YT & Decreasing> = internal.asDecreasing\n\nexport const approximateAsCubicCurves: {\n  /**\n   * Approximates the rational cubic as a sequence of polynomial cubic curves\n   * via recursive subdivision. At each level a candidate polynomial cubic is\n   * built by projecting the segment's homogeneous Bézier control points to\n   * 2D; if the symmetric Hausdorff distance between the rational segment and\n   * its candidate exceeds `tolerance` (verified via a certified subdivision\n   * bound, not a single-point sample), the segment is split at `t = 0.5` and\n   * the procedure recurses on each half. Returns a non-empty array; for a\n   * curve that is already polynomial (uniform weights) the result is a\n   * single exact segment.\n   *\n   * The Hausdorff guarantee means: every point on the rational lies within\n   * `tolerance` of some output segment, and every point on the output lies\n   * within `tolerance` of the rational — a true two-sided bound on geometric\n   * deviation, not just a parametric error at one sample.\n   *\n   * @param c - The rational cubic curve to approximate.\n   * @param tolerance - Maximum allowed Hausdorff distance; must be positive.\n   * @returns A sequence of polynomial cubic curves covering the input.\n   * @since 2.0.0\n   */\n  (c: RationalCubicCurve2d, tolerance: number): ReadonlyArray<CubicCurve2d>\n  /**\n   * Approximates the rational cubic as a sequence of polynomial cubic curves.\n   *\n   * @param tolerance - Maximum allowed Hausdorff distance; must be positive.\n   * @returns A function that takes a curve and returns its polynomial approximation.\n   * @since 2.0.0\n   */\n  (tolerance: number): (c: RationalCubicCurve2d) => ReadonlyArray<CubicCurve2d>\n} = internal.approximateAsCubicCurves\n"],"mappings":"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"}