postcss-calc 11.2.0 → 11.2.2

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.
Files changed (40) hide show
  1. package/LICENSE +0 -0
  2. package/README.md +44 -16
  3. package/package.json +13 -13
  4. package/src/index.js +2 -1
  5. package/src/lib/analyze.js +81 -43
  6. package/src/lib/compile.js +1 -1
  7. package/src/lib/functions.js +40 -10
  8. package/src/lib/node.js +62 -5
  9. package/src/lib/parser/opaque.js +151 -0
  10. package/src/lib/parser/tokens.js +242 -0
  11. package/src/lib/parser.js +27 -382
  12. package/src/lib/serialize/expression.js +376 -0
  13. package/src/lib/serialize/precision.js +244 -0
  14. package/src/lib/serialize.js +24 -517
  15. package/src/lib/simplify/bucket.js +22 -5
  16. package/src/lib/simplify/cancel.js +35 -11
  17. package/src/lib/simplify/clamp.js +2 -2
  18. package/src/lib/simplify/exact.js +18 -0
  19. package/src/lib/simplify/fold.js +15 -1
  20. package/src/lib/simplify/min-max.js +2 -2
  21. package/src/lib/simplify/product.js +263 -48
  22. package/src/lib/simplify/sum.js +6 -2
  23. package/src/lib/simplify.js +22 -5
  24. package/src/reduce.js +2 -1
  25. package/types/lib/analyze.d.ts +27 -0
  26. package/types/lib/functions.d.ts +19 -1
  27. package/types/lib/node.d.ts +17 -2
  28. package/types/lib/parser/opaque.d.ts +12 -0
  29. package/types/lib/parser/tokens.d.ts +83 -0
  30. package/types/lib/parser.d.ts +4 -44
  31. package/types/lib/serialize/expression.d.ts +95 -0
  32. package/types/lib/serialize/precision.d.ts +101 -0
  33. package/types/lib/simplify/bucket.d.ts +4 -1
  34. package/types/lib/simplify/cancel.d.ts +11 -7
  35. package/types/lib/simplify/exact.d.ts +9 -0
  36. package/types/lib/simplify/fold.d.ts +14 -1
  37. package/types/lib/simplify/product.d.ts +3 -7
  38. package/types/lib/simplify/sum.d.ts +2 -1
  39. package/types/lib/simplify.d.ts +3 -8
  40. package/src/lib/calculation-type.js +0 -25
@@ -0,0 +1,83 @@
1
+ export type CSSToken = import('@csstools/css-tokenizer').CSSToken;
2
+ export type BlockIndex = ReturnType<typeof import('../block-index.js').indexBlocks>;
3
+ export type TokenBase = {
4
+ raw: string;
5
+ pos: number;
6
+ ws: boolean;
7
+ index: number;
8
+ };
9
+ export type NumberToken = TokenBase & {
10
+ type: 'number';
11
+ value: number;
12
+ signCharacter?: '+' | '-';
13
+ };
14
+ export type DimensionToken = TokenBase & {
15
+ type: 'dimension';
16
+ value: number;
17
+ unit: string;
18
+ rawUnit: string;
19
+ signCharacter?: '+' | '-';
20
+ };
21
+ export type IdentToken = TokenBase & {
22
+ type: 'ident';
23
+ value: string;
24
+ };
25
+ export type FunctionToken = TokenBase & {
26
+ type: 'function';
27
+ value: string;
28
+ };
29
+ export type Punctuator = '(' | ')' | ',' | '+' | '-' | '*' | '/';
30
+ export type PunctToken = TokenBase & {
31
+ type: 'punct';
32
+ value: Punctuator;
33
+ };
34
+ export type EofToken = TokenBase & {
35
+ type: 'eof';
36
+ value: '';
37
+ raw: '';
38
+ };
39
+ export type Token = NumberToken | DimensionToken | IdentToken | FunctionToken | PunctToken | EofToken;
40
+ export type ParseInput = Readonly<{
41
+ tokens: CSSToken[];
42
+ end: number;
43
+ index: BlockIndex;
44
+ }>;
45
+ /** @param {string} raw @param {string} decoded */
46
+ declare function sourceSpelling(raw: string, decoded: string): string | undefined;
47
+ /**
48
+ * Mutable navigation state only. `index` is always the next native token
49
+ * position; trivia is intentionally left visible to `scanToken`.
50
+ */
51
+ declare class Cursor {
52
+ /** @type {number} */
53
+ index: number;
54
+ /** @type {boolean} */
55
+ firstToken: boolean;
56
+ /** @type {Token | null} */
57
+ lookahead: Token | null;
58
+ /** @type {number} */
59
+ lookaheadNextIndex: number;
60
+ /** @param {number} start */
61
+ constructor(start: number);
62
+ /** @param {number} index @return {void} */
63
+ skipTo(index: number): void;
64
+ }
65
+ /** @param {ParseInput} input @param {number} index @return {number} */
66
+ declare function eofPositionAt(input: ParseInput, index: number): number;
67
+ /** @param {ParseInput} input @param {Cursor} cursor @return {Token} */
68
+ declare function peekToken(input: ParseInput, cursor: Cursor): Token;
69
+ /**
70
+ * Consume the cached token and advance to its native next index. This is one
71
+ * of the only two operations allowed to advance `cursor.index`.
72
+ * @param {ParseInput} input
73
+ * @param {Cursor} cursor
74
+ * @return {Token}
75
+ */
76
+ declare function takeToken(input: ParseInput, cursor: Cursor): Token;
77
+ /** @param {ParseInput} input @param {Cursor} cursor @param {Punctuator} value @param {Punctuator} [value2] @return {boolean} */
78
+ declare function isPunct(input: ParseInput, cursor: Cursor, value: Punctuator, value2?: Punctuator): boolean;
79
+ /** @param {ParseInput} input @param {Cursor} cursor @param {Punctuator} value @return {boolean} */
80
+ declare function matchPunct(input: ParseInput, cursor: Cursor, value: Punctuator): boolean;
81
+ /** @param {ParseInput} input @param {Cursor} cursor @param {Punctuator} value @return {PunctToken} */
82
+ declare function expectPunct(input: ParseInput, cursor: Cursor, value: Punctuator): PunctToken;
83
+ export { Cursor, eofPositionAt, expectPunct, isPunct, matchPunct, peekToken, sourceSpelling, takeToken, };
@@ -1,49 +1,9 @@
1
1
  export type CSSToken = import('@csstools/css-tokenizer').CSSToken;
2
2
  export type Node = import('./node.js').Node;
3
- export type OpaqueComponent = import('./node.js').OpaqueComponent;
4
- export type BlockIndex = ReturnType<typeof import('./block-index.js').indexBlocks>;
5
- export type TokenBase = {
6
- raw: string;
7
- pos: number;
8
- ws: boolean;
9
- index: number;
10
- };
11
- export type NumberToken = TokenBase & {
12
- type: 'number';
13
- value: number;
14
- signCharacter?: '+' | '-';
15
- };
16
- export type DimensionToken = TokenBase & {
17
- type: 'dimension';
18
- value: number;
19
- unit: string;
20
- rawUnit: string;
21
- signCharacter?: '+' | '-';
22
- };
23
- export type IdentToken = TokenBase & {
24
- type: 'ident';
25
- value: string;
26
- };
27
- export type FunctionToken = TokenBase & {
28
- type: 'function';
29
- value: string;
30
- };
31
- export type Punctuator = '(' | ')' | ',' | '+' | '-' | '*' | '/';
32
- export type PunctToken = TokenBase & {
33
- type: 'punct';
34
- value: Punctuator;
35
- };
36
- export type EofToken = TokenBase & {
37
- type: 'eof';
38
- value: '';
39
- raw: '';
40
- };
41
- export type Token = NumberToken | DimensionToken | IdentToken | FunctionToken | PunctToken | EofToken;
42
- export type ParseInput = Readonly<{
43
- tokens: CSSToken[];
44
- end: number;
45
- index: BlockIndex;
46
- }>;
3
+ export type BlockIndex = import('./parser/tokens.js').BlockIndex;
4
+ export type ParseInput = import('./parser/tokens.js').ParseInput;
5
+ export type Token = import('./parser/tokens.js').Token;
6
+ export type FunctionToken = import('./parser/tokens.js').FunctionToken;
47
7
  /** @param {CSSToken[]} tokens @param {number} start @param {number} end @param {BlockIndex} index @return {Node} */
48
8
  declare function parse(tokens: CSSToken[], start: number, end: number, index: BlockIndex): Node;
49
9
  export { parse };
@@ -0,0 +1,95 @@
1
+ export type Node = import('../node.js').Node;
2
+ export type Sum = import('../node.js').Sum;
3
+ export type Product = import('../node.js').Product;
4
+ export type ProductFactor = import('../node.js').ProductFactor;
5
+ export type SerializeSession = import('./precision.js').SerializeSession;
6
+ /**
7
+ * @typedef {import('../node.js').Node} Node
8
+ * @typedef {import('../node.js').Sum} Sum
9
+ * @typedef {import('../node.js').Product} Product
10
+ * @typedef {import('../node.js').ProductFactor} ProductFactor
11
+ * @typedef {import('./precision.js').SerializeSession} SerializeSession
12
+ */
13
+ declare const SUM_PRECEDENCE = 1;
14
+ declare const PRODUCT_PRECEDENCE = 2;
15
+ declare const ATOMIC_PRECEDENCE = 3;
16
+ declare const UNARY_PRECEDENCE = 3;
17
+ /** @param {Node} node @return {number} */
18
+ declare function precedence(node: Node): number;
19
+ /**
20
+ * @param {Node} node
21
+ * @param {number} parentPrecedence
22
+ * @param {boolean} groupedRequired
23
+ * @return {boolean}
24
+ */
25
+ declare function needsParentheses(node: Node, parentPrecedence: number, groupedRequired: boolean): boolean;
26
+ /**
27
+ * @param {Node} node
28
+ * @param {SerializeSession} session
29
+ * @param {number} [parentPrecedence]
30
+ * @param {boolean} [groupedRequired]
31
+ * @return {void}
32
+ */
33
+ declare function emitNode(node: Node, session: SerializeSession, parentPrecedence?: number, groupedRequired?: boolean): void;
34
+ /**
35
+ * @param {import('../node.js').Call} node
36
+ * @param {SerializeSession} session
37
+ * @param {string} [callNameOverride]
38
+ * @return {void}
39
+ */
40
+ declare function emitCall(node: import('../node.js').Call, session: SerializeSession, callNameOverride?: string): void;
41
+ /**
42
+ * @param {import('../node.js').OpaqueCall} node
43
+ * @param {SerializeSession} session
44
+ * @param {string} [callNameOverride]
45
+ * @return {void}
46
+ */
47
+ declare function emitOpaqueCall(node: import('../node.js').OpaqueCall, session: SerializeSession, callNameOverride?: string): void;
48
+ /**
49
+ * @param {import('../node.js').SumTerm} term
50
+ * @param {1 | -1} multiplier
51
+ * @param {number | false} precision
52
+ * @return {1 | -1}
53
+ */
54
+ declare function termSign(term: import('../node.js').SumTerm, multiplier: 1 | -1, precision: number | false): 1 | -1;
55
+ /**
56
+ * @param {import('../node.js').SumTerm[]} terms
57
+ * @param {SerializeSession} session
58
+ * @param {1 | -1} [multiplier]
59
+ * @return {void}
60
+ */
61
+ declare function emitSumTerms(terms: import('../node.js').SumTerm[], session: SerializeSession, multiplier?: 1 | -1): void;
62
+ /** @param {Sum} sum @param {SerializeSession} session @return {void} */
63
+ declare function emitSum(sum: Sum, session: SerializeSession): void;
64
+ /**
65
+ * @param {Node} node
66
+ * @param {SerializeSession} session
67
+ * @return {void}
68
+ */
69
+ declare function emitLeadingNeg(node: Node, session: SerializeSession): void;
70
+ /**
71
+ * @param {ProductFactor[]} factors
72
+ * @param {SerializeSession} session
73
+ * @param {number} [start]
74
+ * @param {number} [coefficientValue]
75
+ * @param {import('../node.js').Num} [coefficientNode]
76
+ * @return {void}
77
+ */
78
+ declare function emitProductFactors(factors: ProductFactor[], session: SerializeSession, start?: number, coefficientValue?: number, coefficientNode?: import('../node.js').Num): void;
79
+ /** @param {Product} product @param {SerializeSession} session @return {void} */
80
+ declare function emitProduct(product: Product, session: SerializeSession): void;
81
+ /**
82
+ * @param {Node} node
83
+ * @param {SerializeSession} session
84
+ * @param {string} wrapper
85
+ * @return {void}
86
+ */
87
+ declare function emitMathResult(node: Node, session: SerializeSession, wrapper: string): void;
88
+ /**
89
+ * @param {Node} node
90
+ * @param {SerializeSession} session
91
+ * @param {string[]} [buffer]
92
+ * @return {void}
93
+ */
94
+ declare function emitNestedMathResult(node: Node, session: SerializeSession, buffer?: string[]): void;
95
+ export { SUM_PRECEDENCE, PRODUCT_PRECEDENCE, ATOMIC_PRECEDENCE, UNARY_PRECEDENCE, precedence, needsParentheses, emitNode, emitCall, emitOpaqueCall, termSign, emitSumTerms, emitSum, emitLeadingNeg, emitProductFactors, emitProduct, emitMathResult, emitNestedMathResult, };
@@ -0,0 +1,101 @@
1
+ export type Node = import('../node.js').Node;
2
+ export type Num = import('../node.js').Num;
3
+ export type Dim = import('../node.js').Dim;
4
+ export type SerializeSession = {
5
+ buffer: string[];
6
+ precision: number | false;
7
+ scalarPolicy: 'standard' | 'unwrap-all';
8
+ };
9
+ /**
10
+ * @typedef {import('../node.js').Node} Node
11
+ * @typedef {import('../node.js').Num} Num
12
+ * @typedef {import('../node.js').Dim} Dim
13
+ * @typedef {object} SerializeSession
14
+ * @property {string[]} buffer
15
+ * @property {number | false} precision
16
+ * @property {'standard' | 'unwrap-all'} scalarPolicy
17
+ */
18
+ declare const NOISE_FLOOR = 1e-12;
19
+ /**
20
+ * Divide a decimal digit string by 10^k, rounding half away from zero, and
21
+ * return the resulting integer digit string. `digits` has no leading zeros.
22
+ * @param {string} digits
23
+ * @param {number} k
24
+ * @return {string}
25
+ */
26
+ declare function divideByPowerOfTen(digits: string, k: number): string;
27
+ /**
28
+ * Round the shortest decimal representation of a non-negative double to `p`
29
+ * fractional digits, half away from zero.
30
+ *
31
+ * `Number(text + 'e' + p)` reads the exact intended decimal (so `1.005` at
32
+ * precision 2 becomes `1.01`), but it is only exact while the shifted value
33
+ * fits in `Number.MAX_SAFE_INTEGER`; beyond that the intermediate double
34
+ * rounds and can move the rounding boundary (e.g. `312834450754803.44` at
35
+ * precision 1 or 6 drifted to `312834450754803.5`). Round the decimal digits
36
+ * directly instead.
37
+ *
38
+ * @param {number} abs
39
+ * @param {number} p
40
+ * @return {number}
41
+ */
42
+ declare function roundDecimal(abs: number, p: number): number;
43
+ /**
44
+ * @param {number} v
45
+ * @param {number | false} prec
46
+ * @return {number}
47
+ */
48
+ declare function round(v: number, prec: number | false): number;
49
+ /** @param {number} v @return {boolean} */
50
+ declare function isDegenerate(v: number): boolean;
51
+ /** @param {number} v @return {string} */
52
+ declare function degenerateKeyword(v: number): string;
53
+ /** @param {number} v @return {string} */
54
+ declare function serializeNumber(v: number): string;
55
+ /**
56
+ * @param {import('../node.js').Num | import('../node.js').Dim} node
57
+ * @param {number | false} precision
58
+ * @param {number} [value]
59
+ * @return {number}
60
+ */
61
+ declare function roundedScalarValue(node: import('../node.js').Num | import('../node.js').Dim, precision: number | false, value?: number): number;
62
+ /**
63
+ * @param {import('../node.js').Num | import('../node.js').Dim} node
64
+ * @param {string[]} buffer
65
+ * @param {number} value
66
+ * @return {void}
67
+ */
68
+ declare function emitRoundedScalar(node: import('../node.js').Num | import('../node.js').Dim, buffer: string[], value: number): void;
69
+ /**
70
+ * @param {import('../node.js').Num | import('../node.js').Dim} node
71
+ * @param {SerializeSession} session
72
+ * @param {number} [value]
73
+ * @return {number}
74
+ */
75
+ declare function emitFiniteScalar(node: import('../node.js').Num | import('../node.js').Dim, session: SerializeSession, value?: number): number;
76
+ /**
77
+ * @param {import('../node.js').Num | import('../node.js').Dim} node
78
+ * @param {SerializeSession} session
79
+ * @param {number} [value]
80
+ * @return {void}
81
+ */
82
+ declare function emitScalar(node: import('../node.js').Num | import('../node.js').Dim, session: SerializeSession, value?: number): void;
83
+ /**
84
+ * @param {string[]} buffer
85
+ * @param {import('../node.js').Num | import('../node.js').Dim} node
86
+ * @return {void}
87
+ */
88
+ declare function emitSignedZero(buffer: string[], node: import('../node.js').Num | import('../node.js').Dim): void;
89
+ /** @param {Node} node @return {node is import('../node.js').Num | import('../node.js').Dim} */
90
+ declare function isScalar(node: Node): node is import('../node.js').Num | import('../node.js').Dim;
91
+ /** @param {Node} node @return {node is import('../node.js').Num | import('../node.js').Dim} */
92
+ declare function isSignedZero(node: Node): node is import('../node.js').Num | import('../node.js').Dim;
93
+ /**
94
+ * Whether a scalar node is strictly negative after precision rounding
95
+ * (excluding signed zero and sub-precision values that round to zero).
96
+ * @param {Node} node
97
+ * @param {number | false} precision
98
+ * @return {node is import('../node.js').Num | import('../node.js').Dim}
99
+ */
100
+ declare function isEffectivelyNegative(node: Node, precision: number | false): node is import('../node.js').Num | import('../node.js').Dim;
101
+ export { NOISE_FLOOR, divideByPowerOfTen, roundDecimal, round, isDegenerate, degenerateKeyword, serializeNumber, roundedScalarValue, emitRoundedScalar, emitFiniteScalar, emitScalar, emitSignedZero, isScalar, isSignedZero, isEffectivelyNegative, };
@@ -19,7 +19,10 @@ export type UnitBucket = {
19
19
  /** Mutates `buckets` in place — totals of survivor buckets accumulate the
20
20
  * converted values of merged neighbors. Caller must not reuse the input.
21
21
  * @param {UnitBucket[]} buckets
22
+ * @param {number | false} [precision] A conversion that is not exact at this
23
+ * precision is not merged. When only the reverse direction is exact, the
24
+ * survivor switches to the other bucket's unit.
22
25
  * @return {UnitBucket[]}
23
26
  */
24
- declare function mergeConvertibleBuckets(buckets: UnitBucket[]): UnitBucket[];
27
+ declare function mergeConvertibleBuckets(buckets: UnitBucket[], precision?: number | false): UnitBucket[];
25
28
  export { mergeConvertibleBuckets };
@@ -1,20 +1,24 @@
1
1
  /**
2
2
  * If `dims` contain exactly one numerator / one denominator pair with the
3
- * same base type and convertible units, return the numeric factor produced
4
- * by cancelling them and the list of remaining (uncancelled) dims.
5
- * Otherwise return null. Used by `simplifyProduct` for typed division
6
- * (§10.2). More complex cancellation (e.g. `px^2 / px`) is left
3
+ * same base type and convertible units, return the two sides expressed in a
4
+ * common unit, so the caller can fold them into its own numerator and
5
+ * denominator. Otherwise return null. Used by `simplifyProduct` for typed
6
+ * division (§10.2). More complex cancellation (e.g. `px^2 / px`) is left
7
7
  * unreduced — consumers rarely rely on it and the spec doesn't require it.
8
8
  * @template {{ exponent: 1 | -1, value: number, unit: string }} D
9
9
  * @param {D[]} dims
10
- * @return {{ factor: number, remaining: D[] } | null}
10
+ * @param {number | false} [precision] The denominator is converted into the
11
+ * numerator's unit when that is exact at this precision (`1px / 1in` →
12
+ * `1 / 96`); otherwise the numerator is converted (`1in / 1px` → `96 / 1`).
13
+ * @return {{ numerator: number, denominator: number, remaining: D[] } | null}
11
14
  */
12
15
  declare function tryCancelPair<D extends {
13
16
  exponent: 1 | -1;
14
17
  value: number;
15
18
  unit: string;
16
- }>(dims: D[]): {
17
- factor: number;
19
+ }>(dims: D[], precision?: number | false): {
20
+ numerator: number;
21
+ denominator: number;
18
22
  remaining: D[];
19
23
  } | null;
20
24
  export { tryCancelPair };
@@ -0,0 +1,9 @@
1
+ /**
2
+ * A value is exact at `precision` when rounding it for output loses nothing
3
+ * beyond float noise.
4
+ * @param {number} value
5
+ * @param {number | false} precision
6
+ * @return {boolean}
7
+ */
8
+ declare function isExact(value: number, precision: number | false): boolean;
9
+ export { isExact };
@@ -15,6 +15,19 @@ export type BaseType = import('../convertUnits.js').BaseType;
15
15
  declare function foldResult(fold: {
16
16
  unit: string;
17
17
  }, value: number): Num | Dim;
18
+ /**
19
+ * Return the argument that produced a folded min/max/clamp value, so the
20
+ * result keeps its own unit, spelling and zero sign. Falls back to a fresh
21
+ * node when no argument matches (NaN).
22
+ * @param {Node[]} args
23
+ * @param {{ values: number[], unit: string }} fold
24
+ * @param {number} value
25
+ * @return {Node}
26
+ */
27
+ declare function chosenArg(args: Node[], fold: {
28
+ values: number[];
29
+ unit: string;
30
+ }, value: number): Node;
18
31
  /**
19
32
  * @param {Node[]} args
20
33
  * @return {{ values: number[], unit: string } | null}
@@ -23,4 +36,4 @@ declare function foldConstArgs(args: Node[]): {
23
36
  values: number[];
24
37
  unit: string;
25
38
  } | null;
26
- export { foldConstArgs, foldResult };
39
+ export { foldConstArgs, foldResult, chosenArg };
@@ -2,16 +2,12 @@ export type Node = import('../node.js').Node;
2
2
  export type Product = import('../node.js').Product;
3
3
  export type ProductFactor = import('../node.js').ProductFactor;
4
4
  export type SimplifyFn = import('../simplify.js').SimplifyFn;
5
- /**
6
- * @typedef {import('../node.js').Node} Node
7
- * @typedef {import('../node.js').Product} Product
8
- * @typedef {import('../node.js').ProductFactor} ProductFactor
9
- * @typedef {import('../simplify.js').SimplifyFn} SimplifyFn
10
- */
11
5
  /**
12
6
  * @param {Product} product
13
7
  * @param {SimplifyFn} simplify
8
+ * @param {number | false} [precision] A quotient that is not exact at this
9
+ * precision stays symbolic (`100% / 3`) instead of being rounded.
14
10
  * @return {Node}
15
11
  */
16
- declare function simplifyProduct(product: Product, simplify: SimplifyFn): Node;
12
+ declare function simplifyProduct(product: Product, simplify: SimplifyFn, precision?: number | false): Node;
17
13
  export { simplifyProduct };
@@ -6,7 +6,8 @@ export type UnitBucket = import('./bucket.js').UnitBucket;
6
6
  /**
7
7
  * @param {Sum} sum
8
8
  * @param {SimplifyFn} simplify
9
+ * @param {number | false} [precision]
9
10
  * @return {Node}
10
11
  */
11
- declare function simplifySum(sum: Sum, simplify: SimplifyFn): Node;
12
+ declare function simplifySum(sum: Sum, simplify: SimplifyFn, precision?: number | false): Node;
12
13
  export { simplifySum };
@@ -1,18 +1,13 @@
1
1
  export type Node = import('./node.js').Node;
2
2
  export type SimplifyFn = (node: Node) => Node;
3
- /**
4
- * @typedef {import('./node.js').Node} Node
5
- *
6
- * Recursive simplifier reference, threaded into Sum/Product/Call/OpaqueCall. Lets
7
- * leaf fold modules avoid circular imports of the entry function.
8
- * @typedef {(node: Node) => Node} SimplifyFn
9
- */
10
3
  /**
11
4
  * Simplify is an independent, composable AST transformation. It may
12
5
  * synthesize canonical nodes while preserving the Node -> Node contract.
13
6
  * @param {Node} node
7
+ * @param {number | false} [precision] When set, divisions and unit
8
+ * conversions that are not exact at this precision stay symbolic.
14
9
  * @param {number} [depth]
15
10
  * @return {Node}
16
11
  */
17
- declare function simplify(node: Node, depth?: number): Node;
12
+ declare function simplify(node: Node, precision?: number | false, depth?: number): Node;
18
13
  export { simplify };
@@ -1,25 +0,0 @@
1
- // Compatibility facade for the former calculation-type module. New code uses
2
- // analyze() for the complete result and limits.js for depth policy.
3
-
4
- import { analyze } from './analyze.js';
5
- import { MAX_CALCULATION_DEPTH, checkCalculationDepth } from './limits.js';
6
-
7
- /** @typedef {import('./node.js').Node} Node */
8
-
9
- /** @typedef {{kind: 'number'} | {kind: 'dimension', base: string | null} | {kind: 'unknown'} | {kind: 'failure'}} CalculationType */
10
-
11
- /** @param {Node} node @return {CalculationType} */
12
- function checkCalculationType(node) {
13
- const result = analyze(node);
14
- if (!result.valid) return { kind: 'failure' };
15
- if (result.type === 'number') return { kind: 'number' };
16
- if (result.type === 'unknown') return { kind: 'unknown' };
17
- return { kind: 'dimension', base: result.type.dimension };
18
- }
19
-
20
- export {
21
- MAX_CALCULATION_DEPTH,
22
- checkCalculationDepth,
23
- checkCalculationType,
24
- analyze,
25
- };