fashionable 0.0.0 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE.md +21 -0
- package/README.md +276 -0
- package/dist/calc/index.d.mts +2 -0
- package/dist/calc/index.mjs +2 -0
- package/dist/data/index.d.mts +208 -0
- package/dist/data/index.mjs +696 -0
- package/dist/data/index.mjs.map +1 -0
- package/dist/declaration/index.d.mts +2 -0
- package/dist/declaration/index.mjs +74 -0
- package/dist/declaration/index.mjs.map +1 -0
- package/dist/fontFace/index.d.mts +2 -0
- package/dist/fontFace/index.mjs +102 -0
- package/dist/fontFace/index.mjs.map +1 -0
- package/dist/property/index.d.mts +2 -0
- package/dist/property/index.mjs +293 -0
- package/dist/property/index.mjs.map +1 -0
- package/dist/query/index.d.mts +2 -0
- package/dist/query/index.mjs +62 -0
- package/dist/query/index.mjs.map +1 -0
- package/dist/rule/index.d.mts +2 -0
- package/dist/rule/index.mjs +234 -0
- package/dist/rule/index.mjs.map +1 -0
- package/dist/selector/index.d.mts +2 -0
- package/dist/selector/index.mjs +178 -0
- package/dist/selector/index.mjs.map +1 -0
- package/dist/shared/calc-Cih4o2r7.mjs +1145 -0
- package/dist/shared/calc-Cih4o2r7.mjs.map +1 -0
- package/dist/shared/color-BvNJ2YqL.d.mts +590 -0
- package/dist/shared/color.internal-Dts5ycTm.mjs +450 -0
- package/dist/shared/color.internal-Dts5ycTm.mjs.map +1 -0
- package/dist/shared/declaration-1DlO_ltT.d.mts +166 -0
- package/dist/shared/declaration.internal-wLB4ssxC.mjs +73 -0
- package/dist/shared/declaration.internal-wLB4ssxC.mjs.map +1 -0
- package/dist/shared/equal-U9G5LhtL.mjs +71 -0
- package/dist/shared/equal-U9G5LhtL.mjs.map +1 -0
- package/dist/shared/fontFaceRule-C7nYgH6X.d.mts +294 -0
- package/dist/shared/fontFaceRule.internal-D5u48TUO.mjs +214 -0
- package/dist/shared/fontFaceRule.internal-D5u48TUO.mjs.map +1 -0
- package/dist/shared/format-B9jsmCER.mjs +53 -0
- package/dist/shared/format-B9jsmCER.mjs.map +1 -0
- package/dist/shared/index-BvtwY4FQ.d.mts +841 -0
- package/dist/shared/mediaQuery-BYR1z-iD.d.mts +145 -0
- package/dist/shared/mediaQuery.internal-B6iuMd75.mjs +100 -0
- package/dist/shared/mediaQuery.internal-B6iuMd75.mjs.map +1 -0
- package/dist/shared/mediaRule-BDB4WCYy.d.mts +558 -0
- package/dist/shared/precision.internal-0lv1nEpF.mjs +40 -0
- package/dist/shared/precision.internal-0lv1nEpF.mjs.map +1 -0
- package/dist/shared/propertyRule-BbkFh9b9.d.mts +466 -0
- package/dist/shared/propertyRule.internal-Bc_HrfcL.mjs +246 -0
- package/dist/shared/propertyRule.internal-Bc_HrfcL.mjs.map +1 -0
- package/dist/shared/render-BqcFH9Vr.mjs +9 -0
- package/dist/shared/render-BqcFH9Vr.mjs.map +1 -0
- package/dist/shared/rolldown-runtime-D7D4PA-g.mjs +13 -0
- package/dist/shared/ruleSet.internal-DodzVMUU.mjs +218 -0
- package/dist/shared/ruleSet.internal-DodzVMUU.mjs.map +1 -0
- package/dist/shared/selector-HZY-W6l6.d.mts +346 -0
- package/dist/shared/selector.internal-ESe9s0IH.mjs +290 -0
- package/dist/shared/selector.internal-ESe9s0IH.mjs.map +1 -0
- package/dist/shared/utils-BKm298I-.d.mts +179 -0
- package/dist/stylesheet/index.d.mts +316 -0
- package/dist/stylesheet/index.mjs +296 -0
- package/dist/stylesheet/index.mjs.map +1 -0
- package/dist/utils.d.mts +2 -0
- package/dist/utils.mjs +131 -0
- package/dist/utils.mjs.map +1 -0
- package/package.json +96 -8
- package/index.js +0 -1
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"calc-Cih4o2r7.mjs","names":["Equal.hashString","Equal.combine","Equal.hashNumber","Equal.EqualTypeId","isCalc","Equal.HashTypeId","#hash","of","ref","add","min","max","subtract","multiply","mod","divide","pow","signedPow","abs","sign","sin","cos","tan","acos","atan2","clamp","lerp","bind","solve","serialize","refs","channels","equals","Equal.equals","internal.isCalc","internal.of","internal.ref","internal.add","internal.subtract","internal.mod","internal.multiply","internal.divide","internal.pow","internal.signedPow","internal.min","internal.max","internal.clamp","internal.lerp","internal.abs","internal.sign","internal.sin","internal.cos","internal.tan","internal.acos","internal.atan2","internal.bind","internal.solve","internal.serialize","internal.refs","internal.channels","internal.equals","internal.isPrecision","internal.decimals","internal.significant"],"sources":["../../src/internal/refs.ts","../../src/calc/calc.internal.ts","../../src/calc/calc.ts","../../src/calc/precision.ts"],"sourcesContent":["/**\n * Runtime helpers for the unbound-reference sets carried by expression\n * values. The matching type-level machinery (the phantom `Refs` parameter\n * and `ApplyBindings`) lives with the public types in calc/calc.ts;\n * container modules extract refs from heterogeneous members with\n * conditionals over their member unions (`RuleSet.MemberRefs`).\n */\n\n/** @internal */\nexport const unionRefs = (...sets: ReadonlyArray<ReadonlySet<string>>): Set<string> => {\n const merged = new Set<string>()\n for (const set of sets) {\n for (const ref of set) {\n merged.add(ref)\n }\n }\n return merged\n}\n\n/** @internal */\nexport const EMPTY_REFS: ReadonlySet<never> = new Set()\n","import * as Equal from '#internal/equal'\nimport {\n DEFAULT_FORMAT,\n type FormatSpec,\n formatWith,\n specEquals,\n specFidelity,\n} from '#internal/format'\nimport { EMPTY_REFS } from '#internal/refs'\nimport { dual, invariant, Pipeable } from '#util'\nimport type { ApplyBindings, Bindings, Calc, Input, Kind, SerializeOptions } from './calc.ts'\nimport { toSpec } from './precision.internal.ts'\nimport type { Precision } from './precision.ts'\n\nexport const CalcTypeId = Symbol.for('fashionable/calc')\nexport type CalcTypeId = typeof CalcTypeId\n\n// ---------------------------------------------------------------------------\n// node ADT\n// ---------------------------------------------------------------------------\n\n/** @internal */\nexport interface ConstantNode {\n readonly _tag: 'Constant'\n readonly value: number\n readonly precision: FormatSpec | undefined\n /** The CSS unit token (`'px'`, `'rad'`), or `undefined` for a plain number. */\n readonly unit: string | undefined\n /** The CSS dimension, supplied by the constructing data module. */\n readonly kind: Kind\n}\n\n/** @internal */\nexport interface RefNode {\n readonly _tag: 'Ref'\n readonly name: string\n}\n\n/**\n * A bare CSS identifier leaf — an unquoted token resolved from its surrounding\n * context, not the custom-property channel. Serializes as its name (`l`, not\n * `var(--l)`) and contributes no references; `bind` passes it through untouched.\n * It carries a leaf brand (`Unit.ChannelLeaf`), so `solve` demands a value for\n * it by name through the context, the way a viewport unit demands a ratio.\n * Today the relative-color channel keywords (`Channel.L`, `Channel.C`, ...) are\n * its only source.\n *\n * @internal\n */\nexport interface IdentNode {\n readonly _tag: 'Ident'\n readonly name: string\n}\n\n/** @internal */\nexport type CalcNode =\n | ConstantNode\n | RefNode\n | IdentNode\n | { readonly _tag: 'Add'; readonly terms: ReadonlyArray<CalcNode> }\n | { readonly _tag: 'Subtract'; readonly left: CalcNode; readonly right: CalcNode }\n | { readonly _tag: 'Multiply'; readonly left: CalcNode; readonly right: CalcNode }\n | { readonly _tag: 'Divide'; readonly left: CalcNode; readonly right: CalcNode }\n | { readonly _tag: 'Mod'; readonly left: CalcNode; readonly right: CalcNode }\n | { readonly _tag: 'Pow'; readonly base: CalcNode; readonly exponent: CalcNode }\n | { readonly _tag: 'SignedPow'; readonly base: CalcNode; readonly exponent: CalcNode }\n | { readonly _tag: 'Min'; readonly args: ReadonlyArray<CalcNode> }\n | { readonly _tag: 'Max'; readonly args: ReadonlyArray<CalcNode> }\n | {\n readonly _tag: 'Clamp'\n readonly minimum: CalcNode\n readonly value: CalcNode\n readonly maximum: CalcNode\n }\n | { readonly _tag: 'Abs'; readonly argument: CalcNode }\n | { readonly _tag: 'Sign'; readonly argument: CalcNode }\n | { readonly _tag: 'Sin'; readonly argument: CalcNode }\n | { readonly _tag: 'Cos'; readonly argument: CalcNode }\n | { readonly _tag: 'Tan'; readonly argument: CalcNode }\n | { readonly _tag: 'Acos'; readonly argument: CalcNode }\n | { readonly _tag: 'Atan2'; readonly y: CalcNode; readonly x: CalcNode }\n\nconst isConstant = (node: CalcNode): node is ConstantNode => node._tag === 'Constant'\n\n// ---------------------------------------------------------------------------\n// smart node constructors: eager constant folding + precision propagation\n// ---------------------------------------------------------------------------\n\nconst constantNode = (\n value: number,\n precision: FormatSpec | undefined,\n unit: string | undefined = undefined,\n kind: Kind = 'number',\n): ConstantNode => {\n invariant(Number.isFinite(value), `Constant value must be a finite number, got ${value}`)\n return { _tag: 'Constant', value, precision, unit, kind }\n}\n\n/**\n * The shared (unit, kind) of a run of constants, or `undefined` when they mix\n * units and so cannot fold to a single constant (`10px + 5vw` stays symbolic).\n */\nconst commonDimension = (\n nodes: ReadonlyArray<ConstantNode>,\n): { readonly unit: string | undefined; readonly kind: Kind } | undefined => {\n const first = nodes[0]\n if (first === undefined) {\n return { unit: undefined, kind: 'number' }\n }\n for (const node of nodes) {\n if (node.unit !== first.unit) {\n return undefined\n }\n }\n return { unit: first.unit, kind: first.kind }\n}\n\nconst bestPrecision = (nodes: ReadonlyArray<ConstantNode>): FormatSpec | undefined => {\n let best: FormatSpec | undefined\n for (const node of nodes) {\n if (specFidelity(node.precision) > specFidelity(best)) {\n best = node.precision\n }\n }\n return best\n}\n\nconst addNode = (terms: ReadonlyArray<CalcNode>): CalcNode => {\n if (terms.every(isConstant)) {\n const dim = commonDimension(terms)\n if (dim !== undefined) {\n return constantNode(\n terms.reduce((total, term) => total + term.value, 0),\n bestPrecision(terms),\n dim.unit,\n dim.kind,\n )\n }\n }\n return { _tag: 'Add', terms }\n}\n\nconst subtractNode = (left: CalcNode, right: CalcNode): CalcNode => {\n if (isConstant(left) && isConstant(right) && left.unit === right.unit) {\n return constantNode(\n left.value - right.value,\n bestPrecision([left, right]),\n left.unit,\n left.kind,\n )\n }\n return { _tag: 'Subtract', left, right }\n}\n\nconst multiplyNode = (left: CalcNode, right: CalcNode): CalcNode => {\n if (isConstant(left) && isConstant(right)) {\n // A dimensioned factor rides through a number factor; two dimensioned\n // factors are invalid CSS (rejected at the type level) and stay symbolic.\n if (left.unit === undefined) {\n return constantNode(\n left.value * right.value,\n bestPrecision([left, right]),\n right.unit,\n right.kind,\n )\n }\n if (right.unit === undefined) {\n return constantNode(\n left.value * right.value,\n bestPrecision([left, right]),\n left.unit,\n left.kind,\n )\n }\n }\n return { _tag: 'Multiply', left, right }\n}\n\nconst divideNode = (left: CalcNode, right: CalcNode): CalcNode => {\n if (isConstant(left) && isConstant(right)) {\n if (left.unit === right.unit) {\n // same unit (or both unit-free) -> the ratio is a unit-free number\n return constantNode(left.value / right.value, bestPrecision([left, right]))\n }\n if (right.unit === undefined) {\n return constantNode(\n left.value / right.value,\n bestPrecision([left, right]),\n left.unit,\n left.kind,\n )\n }\n // number / dimensioned, or two differing dimensioned units: no context-free\n // value, so stay symbolic (the browser resolves the units)\n }\n return { _tag: 'Divide', left, right }\n}\n\n// CSS mod(): the result takes the sign of the divisor, so it is the floored\n// modulo. Folds only when both operands share a unit (or are unit-free).\nconst modNode = (left: CalcNode, right: CalcNode): CalcNode => {\n if (isConstant(left) && isConstant(right) && left.unit === right.unit) {\n return constantNode(\n left.value - right.value * Math.floor(left.value / right.value),\n bestPrecision([left, right]),\n left.unit,\n left.kind,\n )\n }\n return { _tag: 'Mod', left, right }\n}\n\nconst powNode = (base: CalcNode, exponent: CalcNode): CalcNode => {\n if (isConstant(base) && isConstant(exponent)) {\n return constantNode(base.value ** exponent.value, bestPrecision([base, exponent]))\n }\n return { _tag: 'Pow', base, exponent }\n}\n\nconst signedPowNode = (base: CalcNode, exponent: CalcNode): CalcNode => {\n if (isConstant(base) && isConstant(exponent)) {\n return constantNode(\n Math.abs(base.value) ** exponent.value * Math.sign(base.value),\n bestPrecision([base, exponent]),\n )\n }\n return { _tag: 'SignedPow', base, exponent }\n}\n\nconst naryNode =\n (tag: 'Min' | 'Max', compute: (values: ReadonlyArray<number>) => number) =>\n (args: ReadonlyArray<CalcNode>): CalcNode => {\n if (args.every(isConstant)) {\n const dim = commonDimension(args)\n if (dim !== undefined) {\n return constantNode(\n compute(args.map((arg) => arg.value)),\n bestPrecision(args),\n dim.unit,\n dim.kind,\n )\n }\n }\n return { _tag: tag, args }\n }\n\nconst minNode = naryNode('Min', (values) => Math.min(...values))\nconst maxNode = naryNode('Max', (values) => Math.max(...values))\n\nconst clampNode = (minimum: CalcNode, value: CalcNode, maximum: CalcNode): CalcNode => {\n if (isConstant(minimum) && isConstant(value) && isConstant(maximum)) {\n const dim = commonDimension([minimum, value, maximum])\n if (dim !== undefined) {\n return constantNode(\n Math.max(minimum.value, Math.min(value.value, maximum.value)),\n bestPrecision([minimum, value, maximum]),\n dim.unit,\n dim.kind,\n )\n }\n }\n return { _tag: 'Clamp', minimum, value, maximum }\n}\n\ntype UnaryTag = 'Abs' | 'Sign' | 'Sin' | 'Cos' | 'Tan' | 'Acos'\n\n/**\n * Per-function data for the unary math nodes — the single source of truth the\n * fold constructor, the evaluator, and the serializer all read:\n *\n * - `fn` both folds a constant operand and lowers the node under `solve`, so the\n * construction-time and solve-time numerics can never drift.\n * - `css` is the math-function name serialization emits.\n * - `result` is the folded constant's dimension: `sign`/`sin`/`cos`/`tan`\n * produce a plain `number`; `abs` preserves the operand's; `acos` returns\n * radians, so its constant composes with `Angle.rad` terms and stays valid CSS\n * with no plain-number-beside-angle hack.\n */\nconst UNARY: Record<\n UnaryTag,\n {\n readonly fn: (x: number) => number\n readonly css: string\n readonly result: 'number' | 'preserve' | 'rad'\n }\n> = {\n Abs: { fn: Math.abs, css: 'abs', result: 'preserve' },\n Sign: { fn: Math.sign, css: 'sign', result: 'number' },\n Sin: { fn: Math.sin, css: 'sin', result: 'number' },\n Cos: { fn: Math.cos, css: 'cos', result: 'number' },\n Tan: { fn: Math.tan, css: 'tan', result: 'number' },\n Acos: { fn: Math.acos, css: 'acos', result: 'rad' },\n}\n\nconst foldUnary = (tag: UnaryTag, argument: CalcNode): CalcNode => {\n if (!isConstant(argument)) {\n return { _tag: tag, argument }\n }\n const { fn, result } = UNARY[tag]\n const value = fn(argument.value)\n // No `default`: a new `result` variant becomes a missing-return type error here,\n // the same exhaustiveness the node walkers rely on.\n switch (result) {\n case 'number':\n return constantNode(value, argument.precision)\n case 'preserve':\n return constantNode(value, argument.precision, argument.unit, argument.kind)\n case 'rad':\n return constantNode(value, argument.precision, 'rad', 'angle')\n }\n}\n\n// atan2(y, x) returns an <angle>. It also divides same-kind dimensions to a\n// number via tan(atan2(a, b)): a length ratio that works where `a / b` does not\n// (Firefox does not yet support <length> / <length> in calc). Folds only when\n// both operands share a unit, so the ratio is unit-free (like divide).\nconst atan2Node = (y: CalcNode, x: CalcNode): CalcNode => {\n if (isConstant(y) && isConstant(x) && y.unit === x.unit) {\n return constantNode(Math.atan2(y.value, x.value), bestPrecision([y, x]), 'rad', 'angle')\n }\n return { _tag: 'Atan2', y, x }\n}\n\n// ---------------------------------------------------------------------------\n// walkers\n// ---------------------------------------------------------------------------\n\n/** @internal */\nexport const substituteNode = (node: CalcNode, bindings: Record<string, CalcNode>): CalcNode => {\n switch (node._tag) {\n case 'Constant':\n return node\n case 'Ref':\n return bindings[node.name] ?? node\n case 'Ident':\n return node\n case 'Add':\n return addNode(node.terms.map((term) => substituteNode(term, bindings)))\n case 'Subtract':\n return subtractNode(substituteNode(node.left, bindings), substituteNode(node.right, bindings))\n case 'Multiply':\n return multiplyNode(substituteNode(node.left, bindings), substituteNode(node.right, bindings))\n case 'Divide':\n return divideNode(substituteNode(node.left, bindings), substituteNode(node.right, bindings))\n case 'Mod':\n return modNode(substituteNode(node.left, bindings), substituteNode(node.right, bindings))\n case 'Pow':\n return powNode(substituteNode(node.base, bindings), substituteNode(node.exponent, bindings))\n case 'SignedPow':\n return signedPowNode(\n substituteNode(node.base, bindings),\n substituteNode(node.exponent, bindings),\n )\n case 'Min':\n return minNode(node.args.map((arg) => substituteNode(arg, bindings)))\n case 'Max':\n return maxNode(node.args.map((arg) => substituteNode(arg, bindings)))\n case 'Clamp':\n return clampNode(\n substituteNode(node.minimum, bindings),\n substituteNode(node.value, bindings),\n substituteNode(node.maximum, bindings),\n )\n case 'Abs':\n case 'Sign':\n case 'Sin':\n case 'Cos':\n case 'Tan':\n case 'Acos':\n return foldUnary(node._tag, substituteNode(node.argument, bindings))\n case 'Atan2':\n return atan2Node(substituteNode(node.y, bindings), substituteNode(node.x, bindings))\n }\n}\n\n/**\n * The units that lower with no caller-supplied ratio: `px` is the pixel base\n * (`1`), a radian is already the numeric measure of its angle (`1`), and a\n * degree is a fixed `pi / 180` of one. Every other unit is context-dependent\n * and must appear in the solve context.\n *\n * @internal\n */\nexport const DEFAULT_RATIOS: Record<string, number> = { px: 1, rad: 1, deg: Math.PI / 180 }\n\n/** @internal */\nexport const evaluateNode = (node: CalcNode, context: Record<string, number>): number => {\n switch (node._tag) {\n case 'Constant': {\n if (node.unit === undefined) {\n return node.value\n }\n const ratio = context[node.unit] ?? DEFAULT_RATIOS[node.unit]\n invariant(\n ratio !== undefined,\n `Cannot evaluate ${node.value}${node.unit}: no ratio for '${node.unit}' in the unit context`,\n )\n return node.value * ratio\n }\n case 'Ref':\n throw new Error(`Cannot evaluate non-constant reference: ${node.name}`)\n case 'Ident': {\n const value = context[node.name]\n invariant(\n value !== undefined,\n `Cannot evaluate '${node.name}': no value for it in the solve context`,\n )\n return value\n }\n case 'Add':\n return node.terms.reduce((total, term) => total + evaluateNode(term, context), 0)\n case 'Subtract':\n return evaluateNode(node.left, context) - evaluateNode(node.right, context)\n case 'Multiply':\n return evaluateNode(node.left, context) * evaluateNode(node.right, context)\n case 'Divide':\n return evaluateNode(node.left, context) / evaluateNode(node.right, context)\n case 'Mod': {\n const dividend = evaluateNode(node.left, context)\n const divisor = evaluateNode(node.right, context)\n return dividend - divisor * Math.floor(dividend / divisor)\n }\n case 'Pow':\n return evaluateNode(node.base, context) ** evaluateNode(node.exponent, context)\n case 'SignedPow': {\n const base = evaluateNode(node.base, context)\n return Math.abs(base) ** evaluateNode(node.exponent, context) * Math.sign(base)\n }\n case 'Min':\n return Math.min(...node.args.map((arg) => evaluateNode(arg, context)))\n case 'Max':\n return Math.max(...node.args.map((arg) => evaluateNode(arg, context)))\n case 'Clamp':\n return Math.max(\n evaluateNode(node.minimum, context),\n Math.min(evaluateNode(node.value, context), evaluateNode(node.maximum, context)),\n )\n case 'Abs':\n case 'Sign':\n case 'Sin':\n case 'Cos':\n case 'Tan':\n case 'Acos':\n return UNARY[node._tag].fn(evaluateNode(node.argument, context))\n case 'Atan2':\n return Math.atan2(evaluateNode(node.y, context), evaluateNode(node.x, context))\n }\n}\n\n/**\n * True for the arithmetic forms that need a `calc()` wrapper when they\n * stand alone; function forms and leaves never do.\n *\n * @internal\n */\nexport const needsCalcWrap = (node: CalcNode): boolean =>\n node._tag === 'Add' ||\n node._tag === 'Subtract' ||\n node._tag === 'Multiply' ||\n node._tag === 'Divide' ||\n node._tag === 'SignedPow'\n\n// ---------------------------------------------------------------------------\n// serialization\n// ---------------------------------------------------------------------------\n\ninterface SerializeContext {\n readonly precision: FormatSpec\n}\n\nconst PI_TOLERANCE = 1e-10\n\nconst formatConstant = (\n node: ConstantNode,\n insideMath: boolean,\n context: SerializeContext,\n): string => {\n if (node.unit === undefined && insideMath && Math.abs(node.value - Math.PI) < PI_TOLERANCE) {\n return 'pi'\n }\n const text = formatWith(node.value, node.precision ?? context.precision)\n return node.unit !== undefined ? `${text}${node.unit}` : text\n}\n\nconst wrapOperand = (node: CalcNode, serialized: string): string =>\n node._tag === 'Add' || node._tag === 'Subtract' ? `(${serialized})` : serialized\n\nconst hasNegativeCoefficient = (node: CalcNode): boolean => {\n if (isConstant(node)) {\n return node.value < 0\n }\n if (node._tag === 'Multiply' || node._tag === 'Divide') {\n return isConstant(node.left) && node.left.value < 0\n }\n return false\n}\n\n/**\n * Serializes the negation of a term whose leading coefficient is a\n * negative constant, so `a + (-k * x)` renders as `a - k * x`.\n */\nconst serializeNegated = (\n node: CalcNode,\n insideMath: boolean,\n context: SerializeContext,\n): string => {\n if (isConstant(node)) {\n return formatConstant(\n constantNode(-node.value, node.precision, node.unit, node.kind),\n insideMath,\n context,\n )\n }\n const binary = node as Extract<CalcNode, { _tag: 'Multiply' | 'Divide' }>\n const left = binary.left as ConstantNode\n const negated: CalcNode = {\n _tag: binary._tag,\n left: constantNode(-left.value, left.precision, left.unit, left.kind),\n right: binary.right,\n }\n return serializeNode(negated, insideMath, context)\n}\n\n/** @internal */\nexport const serializeNode = (\n node: CalcNode,\n insideMath: boolean,\n context: SerializeContext,\n): string => {\n switch (node._tag) {\n case 'Constant':\n return formatConstant(node, insideMath, context)\n case 'Ref':\n return `var(--${node.name})`\n case 'Ident':\n return node.name\n case 'Add': {\n let out = ''\n for (const [index, term] of node.terms.entries()) {\n if (index === 0) {\n out = serializeNode(term, insideMath, context)\n } else if (hasNegativeCoefficient(term)) {\n out += ` - ${serializeNegated(term, insideMath, context)}`\n } else {\n out += ` + ${serializeNode(term, insideMath, context)}`\n }\n }\n return out\n }\n case 'Subtract': {\n const left = serializeNode(node.left, insideMath, context)\n if (hasNegativeCoefficient(node.right)) {\n return `${left} + ${serializeNegated(node.right, insideMath, context)}`\n }\n return `${left} - ${serializeNode(node.right, insideMath, context)}`\n }\n case 'Multiply': {\n const left = wrapOperand(node.left, serializeNode(node.left, insideMath, context))\n const right = wrapOperand(node.right, serializeNode(node.right, insideMath, context))\n return `${left} * ${right}`\n }\n case 'Divide': {\n const left = wrapOperand(node.left, serializeNode(node.left, insideMath, context))\n const right = wrapOperand(node.right, serializeNode(node.right, insideMath, context))\n return `${left} / ${right}`\n }\n case 'Mod':\n return `mod(${serializeNode(node.left, true, context)}, ${serializeNode(node.right, true, context)})`\n case 'Pow':\n return `pow(${serializeNode(node.base, true, context)}, ${serializeNode(node.exponent, true, context)})`\n case 'SignedPow': {\n const base = serializeNode(node.base, true, context)\n const exponent = serializeNode(node.exponent, true, context)\n return `pow(abs(${base}), ${exponent}) * sign(${base})`\n }\n case 'Min':\n return `min(${node.args.map((arg) => serializeNode(arg, true, context)).join(', ')})`\n case 'Max':\n return `max(${node.args.map((arg) => serializeNode(arg, true, context)).join(', ')})`\n case 'Clamp':\n return `clamp(${serializeNode(node.minimum, true, context)}, ${serializeNode(node.value, true, context)}, ${serializeNode(node.maximum, true, context)})`\n case 'Abs':\n case 'Sign':\n case 'Sin':\n case 'Cos':\n case 'Tan':\n case 'Acos':\n return `${UNARY[node._tag].css}(${serializeNode(node.argument, true, context)})`\n case 'Atan2':\n return `atan2(${serializeNode(node.y, true, context)}, ${serializeNode(node.x, true, context)})`\n }\n}\n\n/** @internal */\nexport const serializeTop = (node: CalcNode, precision: FormatSpec): string => {\n const wrap = needsCalcWrap(node)\n const body = serializeNode(node, wrap, { precision })\n return wrap ? `calc(${body})` : body\n}\n\n// ---------------------------------------------------------------------------\n// structural equality\n// ---------------------------------------------------------------------------\n\nconst nodeArrayEquals = (a: ReadonlyArray<CalcNode>, b: ReadonlyArray<CalcNode>): boolean =>\n a.length === b.length && a.every((node, index) => nodeEquals(node, b[index] as CalcNode))\n\n/** @internal */\nexport const nodeEquals = (a: CalcNode, b: CalcNode): boolean => {\n if (a === b) {\n return true\n }\n if (a._tag !== b._tag) {\n return false\n }\n switch (a._tag) {\n case 'Constant': {\n const other = b as ConstantNode\n return (\n a.value === other.value && a.unit === other.unit && specEquals(a.precision, other.precision)\n )\n }\n case 'Ref':\n return a.name === (b as RefNode).name\n case 'Ident':\n return a.name === (b as IdentNode).name\n case 'Add':\n return nodeArrayEquals(a.terms, (b as typeof a).terms)\n case 'Subtract':\n case 'Multiply':\n case 'Divide':\n case 'Mod': {\n const other = b as typeof a\n return nodeEquals(a.left, other.left) && nodeEquals(a.right, other.right)\n }\n case 'Pow':\n case 'SignedPow': {\n const other = b as typeof a\n return nodeEquals(a.base, other.base) && nodeEquals(a.exponent, other.exponent)\n }\n case 'Min':\n case 'Max':\n return nodeArrayEquals(a.args, (b as typeof a).args)\n case 'Clamp': {\n const other = b as typeof a\n return (\n nodeEquals(a.minimum, other.minimum) &&\n nodeEquals(a.value, other.value) &&\n nodeEquals(a.maximum, other.maximum)\n )\n }\n case 'Abs':\n case 'Sign':\n case 'Sin':\n case 'Cos':\n case 'Tan':\n case 'Acos':\n return nodeEquals(a.argument, (b as typeof a).argument)\n case 'Atan2': {\n const other = b as typeof a\n return nodeEquals(a.y, other.y) && nodeEquals(a.x, other.x)\n }\n }\n}\n\nconst hashNodeArray = (tag: string, nodes: ReadonlyArray<CalcNode>): number => {\n let h = Equal.hashString(tag)\n for (const node of nodes) {\n h = Equal.combine(h, nodeHash(node))\n }\n return h\n}\n\n/** @internal */\nexport const nodeHash = (node: CalcNode): number => {\n switch (node._tag) {\n case 'Constant': {\n const precision =\n node.precision === undefined\n ? 0\n : Equal.combine(Equal.hashString(node.precision.mode), node.precision.digits | 0)\n const unit = node.unit === undefined ? 0 : Equal.hashString(node.unit)\n return Equal.combine(\n Equal.hashString('Constant'),\n Equal.combine(Equal.combine(Equal.hashNumber(node.value), precision), unit),\n )\n }\n case 'Ref':\n return Equal.combine(Equal.hashString('Ref'), Equal.hashString(node.name))\n case 'Ident':\n return Equal.combine(Equal.hashString('Ident'), Equal.hashString(node.name))\n case 'Add':\n return hashNodeArray('Add', node.terms)\n case 'Subtract':\n case 'Multiply':\n case 'Divide':\n case 'Mod':\n return hashNodeArray(node._tag, [node.left, node.right])\n case 'Pow':\n case 'SignedPow':\n return hashNodeArray(node._tag, [node.base, node.exponent])\n case 'Min':\n case 'Max':\n return hashNodeArray(node._tag, node.args)\n case 'Clamp':\n return hashNodeArray('Clamp', [node.minimum, node.value, node.maximum])\n case 'Abs':\n case 'Sign':\n case 'Sin':\n case 'Cos':\n case 'Tan':\n case 'Acos':\n return hashNodeArray(node._tag, [node.argument])\n case 'Atan2':\n return hashNodeArray('Atan2', [node.y, node.x])\n }\n}\n\n// ---------------------------------------------------------------------------\n// the public value\n// ---------------------------------------------------------------------------\n\nclass CalcImpl extends Pipeable implements Calc<string>, Equal.Equal {\n readonly [CalcTypeId]: CalcTypeId = CalcTypeId\n\n readonly node: CalcNode\n readonly refSet: ReadonlySet<string>\n #hash: number | undefined\n\n constructor(node: CalcNode, refSet: ReadonlySet<string>) {\n super()\n this.node = node\n this.refSet = refSet\n }\n\n [Equal.EqualTypeId](that: unknown): boolean {\n return isCalc(that) && nodeEquals(this.node, nodeOf(that))\n }\n\n [Equal.HashTypeId](): number {\n this.#hash ??= Equal.combine(Equal.hashString('fashionable/calc'), nodeHash(this.node))\n return this.#hash\n }\n\n get [Symbol.toStringTag]() {\n return `Calc(${serializeTop(this.node, DEFAULT_FORMAT)})`\n }\n\n get [Symbol.for('nodejs.util.inspect.custom')]() {\n return this[Symbol.toStringTag]\n }\n}\n\n/** @internal */\nexport const isCalc = (u: unknown): u is Calc<string, Kind, unknown> =>\n typeof u === 'object' && u !== null && CalcTypeId in u\n\n/** @internal */\nexport const nodeOf = (expr: Calc<string, Kind, unknown>): CalcNode => (expr as CalcImpl).node\n\n/** @internal */\nexport const refsOf = <R extends string>(expr: Calc<R, Kind, unknown>): ReadonlySet<R> =>\n (expr as unknown as CalcImpl).refSet as ReadonlySet<R>\n\n// Bare identifiers aren't tracked in the ref set (they are not custom\n// properties), so their names are gathered by walking the tree on demand —\n// the runtime counterpart to the `Leaves`-level channel typing.\nconst collectIdents = (node: CalcNode, into: Set<string>): void => {\n switch (node._tag) {\n case 'Ident':\n into.add(node.name)\n return\n case 'Constant':\n case 'Ref':\n return\n case 'Add':\n for (const term of node.terms) {\n collectIdents(term, into)\n }\n return\n case 'Min':\n case 'Max':\n for (const arg of node.args) {\n collectIdents(arg, into)\n }\n return\n case 'Subtract':\n case 'Multiply':\n case 'Divide':\n case 'Mod':\n collectIdents(node.left, into)\n collectIdents(node.right, into)\n return\n case 'Pow':\n case 'SignedPow':\n collectIdents(node.base, into)\n collectIdents(node.exponent, into)\n return\n case 'Clamp':\n collectIdents(node.minimum, into)\n collectIdents(node.value, into)\n collectIdents(node.maximum, into)\n return\n case 'Abs':\n case 'Sign':\n case 'Sin':\n case 'Cos':\n case 'Tan':\n case 'Acos':\n collectIdents(node.argument, into)\n return\n case 'Atan2':\n collectIdents(node.y, into)\n collectIdents(node.x, into)\n return\n }\n}\n\n/** @internal */\nexport const identsOf = (node: CalcNode): ReadonlySet<string> => {\n const set = new Set<string>()\n collectIdents(node, set)\n return set\n}\n\nconst makeCalc = (node: CalcNode, refSet: ReadonlySet<string>): Calc<string> =>\n new CalcImpl(node, refSet)\n\n/**\n * Any operand the runtime combinators accept: an expression of any kind, or a\n * bare number. The precise per-combinator kind/leaf types live in `calc.ts`;\n * the runtime works on the erased tree.\n *\n * @internal\n */\nexport type AnyInput = Calc<string, Kind, unknown> | number\n\n/**\n * The bottom `Calc` — assignable to every precise combinator return in\n * `calc.ts`. The loosely-typed runtime impls return this; the public signatures\n * carry the real kind/leaf types.\n *\n * @internal\n */\nexport type Bottom = Calc<never, never, never>\n\n/** @internal */\nexport const toCalc = (input: AnyInput): Calc<string> =>\n typeof input === 'number' ? of(input) : (input as Calc<string>)\n\nconst mergeRefs = (exprs: ReadonlyArray<Calc<string>>): ReadonlySet<string> => {\n const merged = new Set<string>()\n for (const expr of exprs) {\n for (const name of refsOf(expr)) {\n merged.add(name)\n }\n }\n return merged\n}\n\n// ---------------------------------------------------------------------------\n// constructors\n// ---------------------------------------------------------------------------\n\n/** @internal */\nexport function of(value: number, precision?: Precision): Calc<never> {\n return makeCalc(\n constantNode(value, precision === undefined ? undefined : toSpec(precision)),\n EMPTY_REFS,\n ) as Calc<never>\n}\n\n/**\n * Builds a dimensioned constant. The `data` module's `Length`/`Angle`\n * constructors call this and cast the result to the precise leaf-branded type;\n * the calc core stays unit-agnostic, carrying `unit` and `kind` as given.\n *\n * @internal\n */\nexport function dimension(value: number, unit: string, kind: Kind, precision?: Precision): Bottom {\n return makeCalc(\n constantNode(value, precision === undefined ? undefined : toSpec(precision), unit, kind),\n EMPTY_REFS,\n ) as Bottom\n}\n\nconst refCache = new Map<string, Calc<string>>()\n\n/** @internal */\nexport function ref<Name extends string>(name: Name): Calc<Name> {\n const cached = refCache.get(name)\n if (cached) {\n return cached as Calc<Name>\n }\n invariant(name.length > 0, 'Reference name must be a non-empty string')\n const expr = makeCalc({ _tag: 'Ref', name }, new Set([name]))\n refCache.set(name, expr)\n return expr as Calc<Name>\n}\n\n/**\n * Builds a bare-identifier constant — a leaf serializing as `name`, carrying no\n * references. The `data` module's `Channel` keywords call this; the identifier\n * text is opaque to the calc core, resolved by whatever CSS context surrounds\n * it (a relative-color function today).\n *\n * @internal\n */\nexport function ident(name: string): Calc<never> {\n invariant(name.length > 0, 'Identifier name must be a non-empty string')\n return makeCalc({ _tag: 'Ident', name }, EMPTY_REFS) as Calc<never>\n}\n\n// ---------------------------------------------------------------------------\n// combinators\n// ---------------------------------------------------------------------------\n\nconst liftNary =\n (construct: (nodes: ReadonlyArray<CalcNode>) => CalcNode) =>\n (args: ReadonlyArray<Input<string>>): Calc<string> => {\n const exprs = args.map(toCalc)\n return makeCalc(construct(exprs.map(nodeOf)), mergeRefs(exprs))\n }\n\nconst addImpl = liftNary(addNode)\nconst minImpl = liftNary(minNode)\nconst maxImpl = liftNary(maxNode)\n\n/**\n * The shared shape of the variadic same-kind combinators (`add`, `min`, `max`):\n * fixed 2/3/4-ary overloads that union the operands' references, then a variadic\n * tail. The precise kind/leaf algebra rides on the public re-exports in\n * `calc.ts`; these internal arms track only references.\n */\ninterface NaryCombinator {\n <A extends string = never, B extends string = never>(a: Input<A>, b: Input<B>): Calc<A | B>\n <A extends string = never, B extends string = never, C extends string = never>(\n a: Input<A>,\n b: Input<B>,\n c: Input<C>,\n ): Calc<A | B | C>\n <\n A extends string = never,\n B extends string = never,\n C extends string = never,\n D extends string = never,\n >(\n a: Input<A>,\n b: Input<B>,\n c: Input<C>,\n d: Input<D>,\n ): Calc<A | B | C | D>\n (...args: readonly [Input<string>, Input<string>, ...ReadonlyArray<Input<string>>]): Calc<string>\n}\n\n// The precise arms widen the loose runtime impl (every arity returns\n// `Calc<string>`); the function-overload form these three replace hid the same\n// widening behind lenient overload checking, so the cast loses no safety.\nconst naryCombinator = (\n impl: (args: ReadonlyArray<Input<string>>) => Calc<string>,\n): NaryCombinator => ((...args: ReadonlyArray<Input<string>>) => impl(args)) as NaryCombinator\n\n/** @internal */\nexport const add: NaryCombinator = naryCombinator(addImpl)\n\n/** @internal */\nexport const min: NaryCombinator = naryCombinator(minImpl)\n\n/** @internal */\nexport const max: NaryCombinator = naryCombinator(maxImpl)\n\nconst liftBinary =\n (construct: (left: CalcNode, right: CalcNode) => CalcNode) =>\n (left: AnyInput, right: AnyInput): Calc<string> => {\n const l = toCalc(left)\n const r = toCalc(right)\n return makeCalc(construct(nodeOf(l), nodeOf(r)), mergeRefs([l, r]))\n }\n\nconst subtractImpl = liftBinary(subtractNode)\nconst multiplyImpl = liftBinary(multiplyNode)\nconst divideImpl = liftBinary(divideNode)\nconst modImpl = liftBinary(modNode)\nconst powImpl = liftBinary(powNode)\nconst signedPowImpl = liftBinary(signedPowNode)\nconst atan2Impl = liftBinary(atan2Node)\n\n/** @internal */\nexport function subtract(left: AnyInput, right: AnyInput): Bottom {\n return subtractImpl(left, right) as Bottom\n}\n\n/** @internal */\nexport function multiply(left: AnyInput, right: AnyInput): Bottom {\n return multiplyImpl(left, right) as Bottom\n}\n\n/** @internal */\nexport function mod(left: AnyInput, right: AnyInput): Bottom {\n return modImpl(left, right) as Bottom\n}\n\n/** @internal */\nexport function divide<A extends string = never, B extends string = never>(\n left: Input<A>,\n right: Input<B>,\n): Calc<A | B> {\n return divideImpl(left, right) as Calc<A | B>\n}\n\n/** @internal */\nexport function pow<A extends string = never, B extends string = never>(\n base: Input<A>,\n exponent: Input<B>,\n): Calc<A | B> {\n return powImpl(base, exponent) as Calc<A | B>\n}\n\n/** @internal */\nexport function signedPow<A extends string = never, B extends string = never>(\n base: Input<A>,\n exponent: Input<B>,\n): Calc<A | B> {\n return signedPowImpl(base, exponent) as Calc<A | B>\n}\n\nconst liftUnary =\n (construct: (argument: CalcNode) => CalcNode) =>\n (argument: AnyInput): Calc<string> => {\n const arg = toCalc(argument)\n return makeCalc(construct(nodeOf(arg)), refsOf(arg))\n }\n\nconst absImpl = liftUnary((argument) => foldUnary('Abs', argument))\nconst signImpl = liftUnary((argument) => foldUnary('Sign', argument))\nconst sinImpl = liftUnary((argument) => foldUnary('Sin', argument))\nconst cosImpl = liftUnary((argument) => foldUnary('Cos', argument))\nconst tanImpl = liftUnary((argument) => foldUnary('Tan', argument))\nconst acosImpl = liftUnary((argument) => foldUnary('Acos', argument))\n\n/** @internal */\nexport function abs(argument: AnyInput): Bottom {\n return absImpl(argument) as Bottom\n}\n\n/** @internal */\nexport function sign<A extends string = never>(argument: Input<A>): Calc<A> {\n return signImpl(argument) as Calc<A>\n}\n\n/** @internal */\nexport function sin(argument: AnyInput): Bottom {\n return sinImpl(argument) as Bottom\n}\n\n/** @internal */\nexport function cos(argument: AnyInput): Bottom {\n return cosImpl(argument) as Bottom\n}\n\n/** @internal */\nexport function tan(argument: AnyInput): Bottom {\n return tanImpl(argument) as Bottom\n}\n\n/** @internal */\nexport function acos(argument: AnyInput): Bottom {\n return acosImpl(argument) as Bottom\n}\n\n/** @internal */\nexport function atan2(y: AnyInput, x: AnyInput): Bottom {\n return atan2Impl(y, x) as Bottom\n}\n\n/** @internal */\nexport function clamp(minimum: AnyInput, value: AnyInput, maximum: AnyInput): Bottom {\n const lo = toCalc(minimum)\n const mid = toCalc(value)\n const hi = toCalc(maximum)\n return makeCalc(\n clampNode(nodeOf(lo), nodeOf(mid), nodeOf(hi)),\n mergeRefs([lo, mid, hi]),\n ) as Bottom\n}\n\n/** @internal */\nexport function lerp(a: AnyInput, b: AnyInput, t: AnyInput): Bottom {\n return add(multiply(subtract(1, t), a), multiply(t, b)) as Bottom\n}\n\n// ---------------------------------------------------------------------------\n// binding and projections\n// ---------------------------------------------------------------------------\n\n/** @internal */\nexport const collectBindings = (\n refSet: ReadonlySet<string>,\n bindings: Record<string, Input<string> | undefined>,\n): { readonly nodeBindings: Record<string, CalcNode>; readonly refSet: Set<string> } => {\n const nodeBindings: Record<string, CalcNode> = {}\n const newRefs = new Set<string>(refSet)\n for (const [key, value] of Object.entries(bindings)) {\n if (value === undefined || !refSet.has(key)) {\n continue\n }\n const expr = toCalc(value)\n nodeBindings[key] = nodeOf(expr)\n newRefs.delete(key)\n for (const name of refsOf(expr)) {\n newRefs.add(name)\n }\n }\n return { nodeBindings, refSet: newRefs }\n}\n\n/** @internal */\nexport const bind: {\n <const B extends Bindings>(\n bindings: B,\n ): <Refs extends string>(expr: Calc<Refs, Kind, unknown>) => Calc<ApplyBindings<Refs, B>>\n <Refs extends string, const B extends Bindings>(\n expr: Calc<Refs, Kind, unknown>,\n bindings: B,\n ): Calc<ApplyBindings<Refs, B>>\n} = dual(\n 2,\n (expr: Calc<string, Kind, unknown>, bindings: Record<string, Input<string>>): Calc<string> => {\n const collected = collectBindings(refsOf(expr), bindings)\n return makeCalc(substituteNode(nodeOf(expr), collected.nodeBindings), collected.refSet)\n },\n)\n\n/** @internal */\nexport function solve(\n expr: Calc<string, Kind, unknown>,\n bindings?: Record<string, Input<string>>,\n context?: Record<string, number>,\n): number {\n let node = nodeOf(expr)\n let remaining: ReadonlySet<string> = refsOf(expr)\n if (bindings !== undefined) {\n const collected = collectBindings(remaining, bindings)\n node = substituteNode(node, collected.nodeBindings)\n remaining = collected.refSet\n }\n invariant(remaining.size === 0, 'Cannot convert expression to number: unbound references remain')\n return evaluateNode(node, context ?? {})\n}\n\n/** @internal */\nexport function serialize<Refs extends string>(\n expr: Calc<Refs, Kind, unknown>,\n options?: SerializeOptions<Refs>,\n): string {\n let node = nodeOf(expr)\n if (options?.bindings !== undefined) {\n const collected = collectBindings(\n refsOf(expr),\n options.bindings as Record<string, Input<string> | undefined>,\n )\n node = substituteNode(node, collected.nodeBindings)\n }\n const precision = options?.precision === undefined ? DEFAULT_FORMAT : toSpec(options.precision)\n return serializeTop(node, precision)\n}\n\n/** @internal */\nexport function refs<Refs extends string>(expr: Calc<Refs, Kind, unknown>): ReadonlySet<Refs> {\n return refsOf(expr)\n}\n\n/** @internal */\nexport function channels(expr: Calc<string, Kind, unknown>): ReadonlySet<string> {\n return identsOf(nodeOf(expr))\n}\n\n/** @internal */\nexport const equals = dual<\n (that: Calc<string, Kind, unknown>) => (self: Calc<string, Kind, unknown>) => boolean,\n (self: Calc<string, Kind, unknown>, that: Calc<string, Kind, unknown>) => boolean\n>(2, (self: Calc<string, Kind, unknown>, that: Calc<string, Kind, unknown>): boolean =>\n Equal.equals(self, that),\n)\n","import type { ContextFree, UnitContext } from '#data/units'\nimport type { Pipeable } from '#util'\nimport type { CalcTypeId } from './calc.internal.ts'\nimport * as internal from './calc.internal.ts'\nimport type { Precision } from './precision.ts'\n\ndeclare const CalcVariance: unique symbol\n\n/**\n * The CSS dimension an expression carries: `<number>`, `<length>`, `<angle>`,\n * or `<percentage>`. It is the `Kind` parameter of `Calc`, and the algebra\n * enforces it — same-kind addition, kind-merging multiplication, same-kind\n * division yielding a number. A `<percentage>` is its own kind, not a\n * length: it adds only to another percentage, and `<length-percentage>`\n * mixing stays out of the model (see `docs/design.md`).\n *\n * @since 0.2.0\n */\nexport type Kind = 'number' | 'length' | 'angle' | 'percentage'\n\n/**\n * A CSS value expression: a tree of constants, unbound references, and math\n * operations that can be solved to a number, serialized to CSS `calc()`\n * text, or partially bound and passed along.\n *\n * Three type parameters track the expression structurally:\n *\n * - `Refs` — the unbound reference names. `ref('u')` is a `Calc<'u'>`;\n * combining expressions unions their parameters; `bind` subtracts the\n * names it binds. A fully bound (or constant) expression is a\n * `Calc<never>`.\n * - `Kind` — the CSS dimension (`'number'` by default, or `'length'` /\n * `'angle'`). `add`/`subtract` require a shared kind; `multiply` and\n * `divide` combine kinds (a `<length>` over a `<length>` is a\n * `<number>`); an invalid pairing (a `<length>` plus a `<number>`) is a\n * type error.\n * - `Leaves` — the units the tree contains, as a set of `Unit` brands\n * (`never` when the tree is unit-free). It types the context `solve`\n * needs to lower the tree to a number.\n *\n * Values are immutable and structurally comparable via `equals`.\n * Construction folds constant subtrees eagerly: `add(1, 2)` is the\n * constant `3`, and binding every reference of a tree collapses it to a\n * constant.\n *\n * An unbound reference serializes as `var(--name)` — the reference channel\n * is the custom-property channel.\n *\n * Construct via `of`, `ref`, the `Length`/`Angle` constructors in\n * `fashionable/data`, and the math combinators.\n *\n * @since 0.1.0\n */\nexport interface Calc<\n out Refs extends string = string,\n out K extends Kind = 'number',\n out Leaves = never,\n> extends Pipeable {\n readonly [CalcTypeId]: CalcTypeId\n readonly [CalcVariance]?: { readonly refs: Refs; readonly kind: K; readonly leaves: Leaves }\n}\n\n/**\n * The widest `Calc` — the supertype every expression extends, used to\n * constrain a combinator operand before its facets are extracted.\n *\n * @since 0.2.0\n */\nexport type Top = Calc<string, Kind, unknown>\n\n// ---------------------------------------------------------------------------\n// dimensioned-combinator type machinery (internal): facet extractors and the\n// kind/leaf algebra the combinator signatures below are built from. Validated\n// by the spike in docs/dimensioned-calc.md.\n// ---------------------------------------------------------------------------\n\n/** Any operand a combinator accepts: an expression of any kind, or a bare number. */\ntype In = Top | number\n\ntype RefsOf<A> = A extends Calc<infer R, Kind, unknown> ? R : never\ntype KindOf<A> = A extends Calc<string, infer K, unknown> ? K : 'number'\ntype LeavesOf<A> = A extends Calc<string, Kind, infer L> ? L : never\n\n/** An operand constrained to number-kind (or a bare number). */\ntype NumberIn = number | Calc<string, 'number', unknown>\n\n/** An operand accepted by `sin`/`cos`: a plain number (radians) or an angle. */\ntype NumberOrAngleIn = number | Calc<string, 'number' | 'angle', unknown>\n\n/**\n * An operand constrained to `A`'s kind — a bare number only when `A` is\n * number-kind, so `add(length, 1)` is rejected while `add(length, length)`\n * holds.\n */\ntype SameKindIn<A> =\n | Calc<string, KindOf<A> & Kind, unknown>\n | (KindOf<A> extends 'number' ? number : never)\n\ntype RefsOfAll<T extends ReadonlyArray<unknown>> = { [K in keyof T]: RefsOf<T[K]> }[number]\ntype LeavesOfAll<T extends ReadonlyArray<unknown>> = { [K in keyof T]: LeavesOf<T[K]> }[number]\n\n// same-single-unit division cancels to a unit-free number; anything else keeps\n// both operands' units (conservative, but sound)\ntype IsUnion<T, U = T> = [T] extends [never]\n ? false\n : T extends T\n ? [U] extends [T]\n ? false\n : true\n : never\ntype Singleton<T> = [T] extends [never] ? false : IsUnion<T> extends true ? false : true\ntype LeafFn<X> = <T>() => T extends X ? 1 : 2\ntype LeafEqual<A, B> = LeafFn<A> extends LeafFn<B> ? true : false\ntype SameSingleton<A, B> = LeafEqual<A, B> extends true ? Singleton<A> : false\ntype DivLeaves<A, B> =\n KindOf<B> extends 'number'\n ? LeavesOf<A>\n : SameSingleton<LeavesOf<A>, LeavesOf<B>> extends true\n ? never\n : LeavesOf<A> | LeavesOf<B>\n\n/**\n * A value accepted where an expression is expected: an existing `Calc` or\n * a bare number, which is coerced to an unannotated constant.\n *\n * @since 0.1.0\n */\nexport type Input<Refs extends string = string> = Calc<Refs> | number\n\n/**\n * A bindings record: reference names to the values that replace them. A\n * value may itself be an expression, whose own references join the result.\n *\n * @since 0.1.0\n */\nexport type Bindings<Refs extends string = string> = Record<Refs, Input>\n\ntype ValueRefs<V> = V extends Calc<infer R> ? R : never\n\ntype BindingRefs<T> = T extends Record<string, infer V> ? ValueRefs<V> : never\n\n/**\n * The reference names remaining after applying the bindings `B` to an\n * expression with references `Refs`: bound names are removed, and the\n * references of any expression-valued bindings are added.\n *\n * @since 0.1.0\n */\nexport type ApplyBindings<Refs extends string, B> =\n | Exclude<Refs, keyof B & string>\n | BindingRefs<Pick<B, Extract<keyof B, Refs>>>\n\n/**\n * Options for `serialize`.\n *\n * @since 0.1.0\n */\nexport interface SerializeOptions<Refs extends string = string> {\n /**\n * Bindings applied before rendering. May be partial: references left\n * unbound render as `var(--name)`.\n */\n readonly bindings?: Partial<Bindings<Refs>>\n /**\n * The precision for constants that carry no annotation of their own.\n * Defaults to `Precision.decimals(5)`.\n */\n readonly precision?: Precision\n}\n\n/**\n * Checks if a value is a `Calc`.\n *\n * True only for values built by this module's constructors, which carry\n * the brand.\n *\n * @param u - The value to check.\n * @returns `true` if the value is a `Calc`, `false` otherwise.\n * @since 0.1.0\n */\nexport const isCalc: (u: unknown) => u is Calc<string, Kind, unknown> = internal.isCalc\n\n/**\n * Creates a constant expression, optionally annotated with a serialization\n * precision that overrides the context default wherever the constant lands\n * — including in constants produced by folding it with others (the\n * highest-fidelity operand annotation wins).\n *\n * Bare numbers passed to combinators become unannotated constants; `of`\n * exists to name a value or pin its precision.\n *\n * @param value - The constant value. Must be finite.\n * @param precision - Optional precision annotation.\n * @returns A constant `Calc<never>`.\n * @throws `Error` when `value` is not finite.\n * @example\n * ```ts\n * const k = Calc.of(0.8377580409572781, Precision.significant(10))\n * Calc.serialize(Calc.multiply(k, Calc.ref('t'))) // 'calc(0.837758041 * var(--t))'\n * ```\n * @since 0.1.0\n */\nexport const of: (value: number, precision?: Precision) => Calc<never> = internal.of\n\n/**\n * Creates a reference to an unbound name. References serialize as\n * `var(--name)` and are the channel through which expressions read CSS\n * custom properties; `bind` replaces them with values or other\n * expressions.\n *\n * Repeated calls with the same name return the same instance.\n *\n * @param name - The reference name, without the `--` prefix. Must be non-empty.\n * @returns A `Calc` with `name` as its one unbound reference.\n * @throws `Error` when `name` is empty.\n * @example\n * ```ts\n * Calc.serialize(Calc.ref('width')) // 'var(--width)'\n * ```\n * @since 0.1.0\n */\nexport const ref: <Name extends string>(name: Name) => Calc<Name> = internal.ref\n\n/**\n * Adds expressions. Constant operands fold at construction.\n *\n * Serializes as `a + b + ...` inside a `calc()` wrapper; negative constant\n * terms (and products led by a negative constant) render subtractively:\n * `a + (-2)` serializes as `a - 2`.\n *\n * @param a - The first operand.\n * @param b - The second operand.\n * @returns The sum, with the operands' references unioned.\n * @example\n * ```ts\n * Calc.serialize(Calc.add(Calc.ref('x'), 10)) // 'calc(var(--x) + 10)'\n * ```\n * @since 0.1.0\n */\nexport const add: <\n A extends In,\n B extends SameKindIn<A>,\n Rest extends ReadonlyArray<SameKindIn<A>>,\n>(\n a: A,\n b: B,\n ...rest: Rest\n) => Calc<\n RefsOf<A> | RefsOf<B> | RefsOfAll<Rest>,\n KindOf<A> & Kind,\n LeavesOf<A> | LeavesOf<B> | LeavesOfAll<Rest>\n> = internal.add\n\n/**\n * Subtracts `right` from `left`. Constant operands fold at construction.\n *\n * @param left - The minuend.\n * @param right - The subtrahend.\n * @returns The difference, with the operands' references unioned.\n * @since 0.1.0\n */\nexport const subtract: <A extends In, B extends SameKindIn<A>>(\n left: A,\n right: B,\n) => Calc<RefsOf<A> | RefsOf<B>, KindOf<A> & Kind, LeavesOf<A> | LeavesOf<B>> = internal.subtract\n\n/**\n * The CSS `mod()` of `dividend` and `divisor` — the remainder that takes the\n * sign of the divisor (the floored modulo), so `mod(x, 360)` lands in\n * `[0, 360)` for a positive divisor. Same-kind operands, as `subtract`;\n * constant operands fold at construction.\n *\n * @param dividend - The value to reduce.\n * @param divisor - The modulus, sharing `dividend`'s kind.\n * @returns The modulo, with the operands' references unioned.\n * @example\n * ```ts\n * Calc.serialize(Calc.mod(Calc.ref('h'), 360)) // 'mod(var(--h), 360)'\n * ```\n * @since 0.2.0\n */\nexport const mod: <A extends In, B extends SameKindIn<A>>(\n dividend: A,\n divisor: B,\n) => Calc<RefsOf<A> | RefsOf<B>, KindOf<A> & Kind, LeavesOf<A> | LeavesOf<B>> = internal.mod\n\n/**\n * Multiplies expressions. Constant operands fold at construction.\n *\n * Addition and subtraction operands are parenthesized when serialized\n * under a product: `(a + b) * c`.\n *\n * @param left - The first factor.\n * @param right - The second factor.\n * @returns The product, with the operands' references unioned.\n * @since 0.1.0\n */\nexport const multiply: {\n <A extends NumberIn, B extends In>(\n left: A,\n right: B,\n ): Calc<RefsOf<A> | RefsOf<B>, KindOf<B> & Kind, LeavesOf<A> | LeavesOf<B>>\n <A extends In, B extends NumberIn>(\n left: A,\n right: B,\n ): Calc<RefsOf<A> | RefsOf<B>, KindOf<A> & Kind, LeavesOf<A> | LeavesOf<B>>\n} = internal.multiply\n\n/**\n * Divides `left` by `right`. Constant operands fold at construction.\n *\n * @param left - The dividend.\n * @param right - The divisor.\n * @returns The quotient, with the operands' references unioned.\n * @since 0.1.0\n */\nexport const divide: {\n <A extends In, B extends NumberIn>(\n left: A,\n right: B,\n ): Calc<RefsOf<A> | RefsOf<B>, KindOf<A> & Kind, DivLeaves<A, B>>\n <A extends In, B extends SameKindIn<A>>(\n left: A,\n right: B,\n ): Calc<RefsOf<A> | RefsOf<B>, 'number', DivLeaves<A, B>>\n} = internal.divide\n\n/**\n * Raises `base` to `exponent`. Serializes as the CSS `pow()` function.\n *\n * @param base - The base.\n * @param exponent - The exponent.\n * @returns The power, with the operands' references unioned.\n * @since 0.1.0\n */\nexport const pow: <A extends string = never, B extends string = never>(\n base: Input<A>,\n exponent: Input<B>,\n) => Calc<A | B> = internal.pow\n\n/**\n * Sign-preserving power: `abs(base) ^ exponent * sign(base)`. Unlike\n * `pow`, well-defined for negative bases with fractional exponents.\n * Serializes as `pow(abs(base), exponent) * sign(base)`.\n *\n * @param base - The base.\n * @param exponent - The exponent.\n * @returns The signed power, with the operands' references unioned.\n * @since 0.1.0\n */\nexport const signedPow: <A extends string = never, B extends string = never>(\n base: Input<A>,\n exponent: Input<B>,\n) => Calc<A | B> = internal.signedPow\n\n/**\n * The minimum of the operands. Serializes as the CSS `min()` function.\n *\n * @param a - The first operand.\n * @param b - The second operand.\n * @returns The minimum, with the operands' references unioned.\n * @since 0.1.0\n */\nexport const min: <\n A extends In,\n B extends SameKindIn<A>,\n Rest extends ReadonlyArray<SameKindIn<A>>,\n>(\n a: A,\n b: B,\n ...rest: Rest\n) => Calc<\n RefsOf<A> | RefsOf<B> | RefsOfAll<Rest>,\n KindOf<A> & Kind,\n LeavesOf<A> | LeavesOf<B> | LeavesOfAll<Rest>\n> = internal.min\n\n/**\n * The maximum of the operands. Serializes as the CSS `max()` function.\n *\n * @param a - The first operand.\n * @param b - The second operand.\n * @returns The maximum, with the operands' references unioned.\n * @since 0.1.0\n */\nexport const max: <\n A extends In,\n B extends SameKindIn<A>,\n Rest extends ReadonlyArray<SameKindIn<A>>,\n>(\n a: A,\n b: B,\n ...rest: Rest\n) => Calc<\n RefsOf<A> | RefsOf<B> | RefsOfAll<Rest>,\n KindOf<A> & Kind,\n LeavesOf<A> | LeavesOf<B> | LeavesOfAll<Rest>\n> = internal.max\n\n/**\n * Clamps `value` between `minimum` and `maximum`. Serializes as the CSS\n * `clamp()` function, with the CSS argument order `(min, value, max)`.\n *\n * @param minimum - The lower bound.\n * @param value - The value to clamp.\n * @param maximum - The upper bound.\n * @returns The clamped expression, with the operands' references unioned.\n * @example\n * ```ts\n * Calc.serialize(Calc.clamp(-1, Calc.ref('u'), 1)) // 'clamp(-1, var(--u), 1)'\n * ```\n * @since 0.1.0\n */\nexport const clamp: <A extends In, B extends SameKindIn<A>, C extends SameKindIn<A>>(\n minimum: A,\n value: B,\n maximum: C,\n) => Calc<\n RefsOf<A> | RefsOf<B> | RefsOf<C>,\n KindOf<A> & Kind,\n LeavesOf<A> | LeavesOf<B> | LeavesOf<C>\n> = internal.clamp\n\n/**\n * Linear interpolation from `a` to `b` by `t`. This is sugar, not a node:\n * it desugars to `(1 - t) * a + t * b`, and serializes as that expanded\n * form.\n *\n * @param a - The value at `t = 0`.\n * @param b - The value at `t = 1`.\n * @param t - The interpolation parameter.\n * @returns The interpolated expression, with the operands' references unioned.\n * @since 0.1.0\n */\nexport const lerp: {\n <A extends In, B extends SameKindIn<A>, T extends NumberIn>(\n a: A,\n b: B,\n t: T,\n ): Calc<\n RefsOf<A> | RefsOf<B> | RefsOf<T>,\n KindOf<A> & Kind,\n LeavesOf<A> | LeavesOf<B> | LeavesOf<T>\n >\n} = internal.lerp\n\n/**\n * The absolute value. Serializes as the CSS `abs()` function.\n *\n * @param argument - The operand.\n * @returns The absolute value expression.\n * @since 0.1.0\n */\nexport const abs: {\n <A extends In>(argument: A): Calc<RefsOf<A>, KindOf<A> & Kind, LeavesOf<A>>\n} = internal.abs\n\n/**\n * The sign (`-1`, `0`, or `1`). Serializes as the CSS `sign()` function.\n *\n * @param argument - The operand.\n * @returns The sign expression.\n * @since 0.1.0\n */\nexport const sign: <A extends string = never>(argument: Input<A>) => Calc<A> = internal.sign\n\n/**\n * The sine of its argument. Serializes as the CSS `sin()` function, which\n * accepts an `<angle>` or a plain number treated as radians — so this takes\n * either an angle-kind expression or a number, and returns a number.\n *\n * @param argument - An angle, or a plain number in radians.\n * @returns The sine, a `<number>`, carrying the argument's units.\n * @since 0.1.0\n */\nexport const sin: {\n <A extends NumberOrAngleIn>(argument: A): Calc<RefsOf<A>, 'number', LeavesOf<A>>\n} = internal.sin\n\n/**\n * The cosine of its argument. Serializes as the CSS `cos()` function, which\n * accepts an `<angle>` or a plain number treated as radians — so this takes\n * either an angle-kind expression or a number, and returns a number.\n *\n * @param argument - An angle, or a plain number in radians.\n * @returns The cosine, a `<number>`, carrying the argument's units.\n * @since 0.1.0\n */\nexport const cos: {\n <A extends NumberOrAngleIn>(argument: A): Calc<RefsOf<A>, 'number', LeavesOf<A>>\n} = internal.cos\n\n/**\n * The tangent of its argument. Serializes as the CSS `tan()` function, which\n * accepts an `<angle>` or a plain number treated as radians. Paired with\n * `atan2`, `tan(atan2(a, b))` divides two same-kind dimensions to a `<number>` —\n * the length ratio that works where `a / b` does not, since Firefox does not\n * yet support `<length> / <length>` in `calc()`.\n *\n * @param argument - An angle, or a plain number in radians.\n * @returns The tangent, a `<number>`, carrying the argument's units.\n * @since 0.2.0\n */\nexport const tan: {\n <A extends NumberOrAngleIn>(argument: A): Calc<RefsOf<A>, 'number', LeavesOf<A>>\n} = internal.tan\n\n/**\n * The arccosine of a value in `[-1, 1]`, an `<angle>` in radians (CSS's\n * `acos()` returns an `<angle>`). Solving evaluates `Math.acos`, in radians.\n *\n * Because the result is angle-kind, it composes only with other angles: divide\n * or scale it by a number, and add or subtract an `Angle.rad(...)` phase. A\n * plain number added to it is a type error — supply the phase as an angle.\n *\n * @param argument - The cosine value, in `[-1, 1]`.\n * @returns The arccosine, an `<angle>`, carrying the argument's units.\n * @example\n * ```ts\n * const phase = Angle.rad(2.0943951)\n * Calc.serialize(Calc.cos(Calc.subtract(Calc.divide(Calc.acos(Calc.ref('u')), 3), phase)))\n * // 'cos(acos(var(--u)) / 3 - 2.0944rad)'\n * ```\n * @since 0.1.0\n */\nexport const acos: {\n <A extends NumberIn>(argument: A): Calc<RefsOf<A>, 'angle', LeavesOf<A>>\n} = internal.acos\n\n/**\n * The angle, in radians, of the vector from the origin to `(x, y)` — CSS's\n * `atan2()`, which returns an `<angle>`. The operands must share a kind (two\n * numbers, two lengths, two angles); their units cancel in the ratio, so\n * `tan(atan2(a, b))` recovers `a / b` as a `<number>` and is the portable way to\n * divide two `<length>`s.\n *\n * @param y - The vertical component.\n * @param x - The horizontal component, sharing `y`'s kind.\n * @returns The angle, an `<angle>`, with the operands' units unioned.\n * @example\n * ```ts\n * const ratio = Calc.tan(Calc.atan2(Calc.subtract(Length.vw(100), Length.px(320)), Length.px(160)))\n * Calc.serialize(ratio) // 'tan(atan2(100vw - 320px, 160px))'\n * ```\n * @since 0.2.0\n */\nexport const atan2: {\n <A extends In, B extends SameKindIn<A>>(\n y: A,\n x: B,\n ): Calc<RefsOf<A> | RefsOf<B>, 'angle', LeavesOf<A> | LeavesOf<B>>\n} = internal.atan2\n\nexport const bind: {\n /**\n * Returns a function that binds the given names in an expression.\n *\n * @param bindings - Reference names to values or expressions. Names the expression does not reference are ignored, as are `undefined` values.\n * @returns A function replacing bound references in its argument.\n * @since 0.1.0\n */\n <const B extends Bindings>(\n bindings: B,\n ): <Refs extends string>(expr: Calc<Refs>) => Calc<ApplyBindings<Refs, B>>\n /**\n * Replaces references with values or other expressions. Binding is\n * partial evaluation: substituted subtrees re-fold, so binding every\n * reference collapses the tree to a constant.\n *\n * Names the expression does not reference are ignored (spreading a wider\n * bindings object is fine), as are `undefined` values. Binding a\n * reference to another expression composes trees; the bound expression's\n * own references join the result, tracked in the return type by\n * `ApplyBindings`.\n *\n * @param expr - The expression to bind.\n * @param bindings - Reference names to values or expressions.\n * @returns The bound expression.\n * @example\n * ```ts\n * const half = Calc.bind(Calc.divide(Calc.ref('x'), 2), { x: Calc.ref('width') })\n * Calc.serialize(half) // 'calc(var(--width) / 2)'\n * Calc.solve(Calc.bind(half, { width: 100 })) // 50\n * ```\n * @since 0.1.0\n */\n <Refs extends string, const B extends Bindings>(\n expr: Calc<Refs>,\n bindings: B,\n ): Calc<ApplyBindings<Refs, B>>\n} = internal.bind\n\nexport const solve: {\n /**\n * Evaluates a closed expression to a number. Absolute lengths (`px`) and\n * angles (radians) lower with no context; a viewport- or font-relative unit\n * needs the context overload, and an unbound reference needs the bindings\n * overload.\n *\n * @param expr - The expression. No unbound references, only context-free units.\n * @returns The numeric value.\n * @throws `Error` when unbound references or unresolvable units remain at runtime.\n * @since 0.1.0\n */\n (expr: Calc<never, Kind, ContextFree>): number\n /**\n * Applies bindings, then evaluates to a number. For expressions whose units,\n * if any, are all context-free.\n *\n * @param expr - The expression to evaluate.\n * @param bindings - Values for every unbound reference.\n * @returns The numeric value.\n * @throws `Error` when unbound references remain after binding.\n * @example\n * ```ts\n * Calc.solve(Calc.lerp(Calc.ref('a'), Calc.ref('b'), 0.5), { a: 0, b: 10 }) // 5\n * ```\n * @since 0.1.0\n */\n <Refs extends string, B extends Bindings<Refs>>(\n expr: Calc<Refs, Kind, ContextFree>,\n bindings: B,\n ): number\n /**\n * Applies bindings, lowers each context-dependent unit through the context,\n * then evaluates to a number. The context supplies a pixels-per-unit ratio\n * for every relative unit the expression carries (`vw` is `sampleWidth / 100`);\n * absolute lengths default (`px` is `1`) unless overridden.\n *\n * @param expr - The expression to evaluate.\n * @param bindings - Values for every unbound reference.\n * @param context - Ratios for the expression's context-dependent units.\n * @returns The numeric value.\n * @example\n * ```ts\n * const position = Calc.divide(Calc.subtract(Length.vw(100), Length.px(320)), Length.px(160))\n * Calc.solve(position, {}, { vw: 1280 / 100 }) // 6\n * ```\n * @since 0.2.0\n */\n <Refs extends string, B extends Bindings<Refs>, L>(\n expr: Calc<Refs, Kind, L>,\n bindings: B,\n context: UnitContext<L>,\n ): number\n} = internal.solve\n\n/**\n * Renders an expression as CSS text. Arithmetic gets a `calc()` wrapper;\n * function forms (`min`, `clamp`, `sin`, ...) and leaves stand alone.\n * References render as `var(--name)`.\n *\n * Bindings in `options` are applied first and may be partial — this is\n * the serialize half of the solve/serialize duality, and unbound\n * references are the values left for the browser. Constants render with\n * their annotated precision, or the context `precision` option (default\n * `Precision.decimals(5)`). Constants equal to pi render as the CSS\n * constant `pi` where a math function surrounds them.\n *\n * @param expr - The expression to render.\n * @param options - Optional bindings and precision context.\n * @returns Deterministic CSS text.\n * @example\n * ```ts\n * const fluid = Calc.add(10, Calc.ref('runtime'))\n * Calc.serialize(fluid) // 'calc(10 + var(--runtime))'\n * Calc.serialize(fluid, { bindings: { runtime: 4 } }) // '14'\n * ```\n * @since 0.1.0\n */\nexport const serialize: <Refs extends string>(\n expr: Calc<Refs, Kind, unknown>,\n options?: SerializeOptions<Refs>,\n) => string = internal.serialize\n\n/**\n * The expression's unbound reference names.\n *\n * @param expr - The expression to inspect.\n * @returns The set of unbound reference names.\n * @since 0.1.0\n */\nexport const refs: <Refs extends string>(expr: Calc<Refs, Kind, unknown>) => ReadonlySet<Refs> =\n internal.refs\n\n/**\n * The channel-keyword tokens the expression reads — the `Channel` keywords a\n * relative color introduces (`l`, `c`, `h`, ...). Empty for an expression with\n * no channel keywords.\n *\n * This is the runtime companion to the `Leaves`-level scoping that `solve`'s\n * context requires: `channels` reports which values a context must supply,\n * exactly as `refs` reports the custom properties a binding must, and — unlike\n * a `Calc`'s `Kind`/`Leaves` type — survives on a `Calc<Refs, Kind, unknown>`\n * whose leaves have been erased. Channel keywords are not references, so `refs`\n * never lists them and they never reach a `Stylesheet`'s dependency report.\n *\n * @param expr - The expression to inspect.\n * @returns The set of channel-keyword tokens the expression reads.\n * @example\n * ```ts\n * Calc.channels(Calc.multiply(Channel.L, 0.8)) // Set { 'l' }\n * Calc.channels(Calc.ref('x')) // Set {}\n * ```\n * @since 0.2.0\n */\nexport const channels: (expr: Calc<string, Kind, unknown>) => ReadonlySet<string> =\n internal.channels\n\nexport const equals: {\n /**\n * Returns a function that checks structural equality against `that`.\n *\n * @param that - The expression to compare against.\n * @returns A function testing its argument for structural equality with `that`.\n * @since 0.1.0\n */\n (that: Calc<string, Kind, unknown>): (self: Calc<string, Kind, unknown>) => boolean\n /**\n * Structural equality over expression trees. Two expressions are equal\n * when their trees match node for node — including constant units and\n * precision annotations, which affect serialization. Expression trees are\n * ordered syntax: `add(a, b)` and `add(b, a)` are not equal.\n *\n * @param self - The first expression.\n * @param that - The second expression.\n * @returns `true` if the expressions are structurally equal.\n * @since 0.1.0\n */\n (self: Calc<string, Kind, unknown>, that: Calc<string, Kind, unknown>): boolean\n} = internal.equals\n","import type { Pipeable } from '#util'\nimport type { PrecisionTypeId } from './precision.internal.ts'\nimport * as internal from './precision.internal.ts'\n\n/**\n * A number-formatting precision, attached to constants at construction\n * (`Calc.of`) or supplied as a serialization context default\n * (`Calc.serialize`'s `precision` option).\n *\n * Two modes exist. `decimals` fixes the count of digits after the decimal\n * point (`toFixed` semantics); `significant` fixes the count of significant\n * digits (`toPrecision` semantics). Both render plain decimal text with\n * trailing zeros trimmed — CSS never accepts exponent notation.\n *\n * A precision annotated on a constant overrides the serialization context.\n * When constant folding combines annotated constants, the result carries\n * the highest-fidelity annotation among the operands: any `significant`\n * outranks any `decimals`, and more digits outrank fewer.\n *\n * @since 0.1.0\n */\nexport interface Precision extends Pipeable {\n readonly [PrecisionTypeId]: PrecisionTypeId\n /**\n * The formatting mode: digits after the decimal point (`decimals`) or\n * significant digits (`significant`).\n */\n readonly mode: 'decimals' | 'significant'\n /**\n * The digit count the mode fixes.\n */\n readonly digits: number\n}\n\n/**\n * Checks if a value is a `Precision`.\n *\n * True only for values built by `decimals` or `significant`, which carry\n * the brand.\n *\n * @param u - The value to check.\n * @returns `true` if the value is a `Precision`, `false` otherwise.\n * @since 0.1.0\n */\nexport const isPrecision: (u: unknown) => u is Precision = internal.isPrecision\n\n/**\n * Creates a `Precision` fixing the count of digits after the decimal\n * point. The library default for unannotated constants is `decimals(5)`.\n *\n * @param digits - Digits after the decimal point. Must be an integer in `[0, 100]`.\n * @returns A `Precision` in `decimals` mode.\n * @throws `Error` when `digits` is not an integer in `[0, 100]`.\n * @example\n * ```ts\n * Calc.serialize(Calc.of(1 / 3), { precision: Precision.decimals(2) }) // '0.33'\n * ```\n * @since 0.1.0\n */\nexport const decimals: (digits: number) => Precision = internal.decimals\n\n/**\n * Creates a `Precision` fixing the count of significant digits. Use it for\n * unit-free constants whose error is amplified downstream — solved curve\n * coefficients, for example — where fixed decimal places would truncate.\n *\n * @param digits - Significant digits. Must be an integer in `[1, 100]`.\n * @returns A `Precision` in `significant` mode.\n * @throws `Error` when `digits` is not an integer in `[1, 100]`.\n * @example\n * ```ts\n * const k = Calc.of(0.8377580409572781, Precision.significant(10))\n * Calc.serialize(k) // '0.837758041'\n * ```\n * @since 0.1.0\n */\nexport const significant: (digits: number) => Precision = internal.significant\n"],"mappings":"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"}
|