exprify 1.0.6 → 1.0.7
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/README.md +52 -45
- package/dist/exprify.js +1 -1
- package/dist/exprify.min.js +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,3 +1,9 @@
|
|
|
1
|
+
[](https://github.com/code-hemu/Exprify)
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
**Exprify** (Math **Expr**ession + Simp**lify**) is a fast, lightweight JavaScript expression parser and evaluator. It is designed for math applications, scientific computing, data visualization tools, calculators, and other complex workflows that run in the browser and in Node.js. It supports basic arithmetic, variables, user-defined functions, and built-in operators for comparison, logic, and string manipulation.
|
|
5
|
+
|
|
6
|
+
|
|
1
7
|
[](https://www.npmjs.com/package/exprify)
|
|
2
8
|
[](https://www.npmjs.com/package/exprify)
|
|
3
9
|
[](https://github.com/code-hemu/exprify/blob/master/LICENSE)
|
|
@@ -6,27 +12,22 @@
|
|
|
6
12
|
[](https://github.com/code-hemu/exprify/issues)
|
|
7
13
|
[](https://github.com/code-hemu/exprify/graphs/contributors)
|
|
8
14
|
[](https://github.com/sponsors/code-hemu)
|
|
9
|
-
|
|
10
|
-
[](https://github.com/code-hemu/Exprify)
|
|
11
|
-
|
|
12
|
-
**Exprify** (**Math Expr**ession + Simp**lify**) parses a string into an expression tree, evaluates it with a given set of variables, and lets you chain or compose operations together - in the browser and in Node.js.
|
|
15
|
+
[](https://github.com/code-hemu/exprify)
|
|
13
16
|
|
|
14
17
|
## Features
|
|
15
18
|
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
| **State serialization** | `expr.exportState()` / `expr.importState(state)` | [core/serialization.md](docs/core/serialization.md) |
|
|
29
|
-
| **Degree-mode trig** | `expr.evaluate("sind(90)")` | [reference/functions.md](docs/reference/functions.md) |
|
|
19
|
+
- **Arithmetic & Variables** - `expr.evaluate("5 + 7 * 2")` · [docs](docs/datatypes/numbers.md)
|
|
20
|
+
- **Unit conversion** - `expr.evaluate("2 inch to cm")` · [docs](docs/datatypes/units.md)
|
|
21
|
+
- **Matrix operations** - `expr.evaluate("det([-1,2;3,1])")` · [docs](docs/datatypes/matrices.md)
|
|
22
|
+
- **Complex numbers** - `expr.evaluate("9/3 + 2i")` · [docs](docs/datatypes/complex_numbers.md)
|
|
23
|
+
- **Symbolic math** - `expr.evaluate('expand("(x+1)^2")')` · [docs](docs/expressions/algebra.md)
|
|
24
|
+
- **Arbitrary precision** - `expr.evaluate('bignumber("0.1") + bignumber("0.2")')` · [docs](docs/datatypes/bignumbers.md)
|
|
25
|
+
- **Exact fractions** - `expr.evaluate("fraction(1,3) + fraction(1,6)")` · [docs](docs/datatypes/fractions.md)
|
|
26
|
+
- **Calculus & statistics** - `expr.evaluate('integral("x^2", 0, 1)')` · [docs](docs/reference/functions.md)
|
|
27
|
+
- **Lambda expressions** - `expr.evaluate('map([1,2,3], x -> x^2)')` · [docs](docs/expressions/customization.md)
|
|
28
|
+
- **Expression chaining** - `c.evaluate("sqrt(x)").evaluate("ans * 2").done()` · [docs](docs/core/chaining.md)
|
|
29
|
+
- **State serialization** - `expr.exportState()` / `expr.importState(state)` · [docs](docs/core/serialization.md)
|
|
30
|
+
- **Degree-mode trig** - `expr.evaluate("sind(90)")` · [docs](docs/reference/functions.md)
|
|
30
31
|
|
|
31
32
|
## Installation
|
|
32
33
|
|
|
@@ -68,47 +69,39 @@ expr.evaluate("5 + 7 * 2"); // 19
|
|
|
68
69
|
</script>
|
|
69
70
|
```
|
|
70
71
|
|
|
71
|
-
##
|
|
72
|
-
|
|
73
|
-
`package.json`'s `exports` field routes each import style to the correct build automatically.
|
|
74
|
-
|
|
75
|
-
| Consumer | Resolved file | Notes |
|
|
76
|
-
|---|---|---|
|
|
77
|
-
| `import Exprify from "exprify"` | `dist/exprify.esm.js` | Default export is the `Exprify` class |
|
|
78
|
-
| `require("exprify")` | `dist/exprify.cjs.cjs` | `module.exports` is the `Exprify` class |
|
|
79
|
-
| `<script src="https://unpkg.com/exprify">` | `dist/exprify.min.js` | UMD build; exposes `Exprify` as a global |
|
|
80
|
-
| `import "exprify/dist/exprify.js"` | `dist/exprify.js` | Unminified UMD for bundlers that prefer it |
|
|
81
|
-
|
|
82
|
-
> The `.cjs` extension keeps the CommonJS bundle loadable via `require()` even though the package uses `"type": "module"`.
|
|
83
|
-
|
|
84
|
-
## API
|
|
72
|
+
## API Reference
|
|
85
73
|
|
|
86
74
|
### `new Exprify()`
|
|
87
75
|
|
|
88
|
-
Creates a new evaluator instance with isolated state
|
|
76
|
+
Creates a new evaluator instance with fully isolated state. Each instance maintains its own independent registry of variables, custom functions, unit definitions, and a compiled-expression cache - so multiple instances never interfere with each other.
|
|
77
|
+
|
|
78
|
+
```js
|
|
79
|
+
const expr = new Exprify();
|
|
80
|
+
```
|
|
89
81
|
|
|
90
82
|
### `expr.evaluate(expression, scope?)`
|
|
91
83
|
|
|
92
|
-
Parses and evaluates an expression string. An optional `scope` object
|
|
84
|
+
Parses and evaluates an expression string, returning the computed result. An optional `scope` object lets you pass temporary variable values that apply only to that single call - they do not modify the instance's stored state.
|
|
93
85
|
|
|
94
86
|
```js
|
|
95
87
|
expr.evaluate("10 + 5 * 2"); // 20
|
|
96
88
|
|
|
97
89
|
expr.setVariable("x", 100);
|
|
98
|
-
expr.evaluate("x + 1", { x: 5 }); // 6
|
|
90
|
+
expr.evaluate("x + 1", { x: 5 }); // 6 (x = 100 is unchanged)
|
|
99
91
|
```
|
|
100
92
|
|
|
101
93
|
### `expr.parse(expression)`
|
|
102
94
|
|
|
103
|
-
Returns `{ tokens, ast }`
|
|
95
|
+
Parses an expression without evaluating it. Returns a `{ tokens, ast }` object containing the raw token list and the abstract syntax tree - useful for debugging, introspection, or building custom tooling on top of the parser.
|
|
104
96
|
|
|
105
97
|
```js
|
|
106
98
|
const { tokens, ast } = expr.parse("2 inch to cm");
|
|
99
|
+
// tokens: [...], ast: { type: "UnitConversion", ... }
|
|
107
100
|
```
|
|
108
101
|
|
|
109
102
|
### `expr.compile(expression)`
|
|
110
103
|
|
|
111
|
-
Compiles an expression once and returns a reusable function
|
|
104
|
+
Compiles an expression once and returns a reusable callable function. The compiled form skips parsing on every subsequent invocation, making this the right choice for hot paths or any expression evaluated repeatedly with different inputs.
|
|
112
105
|
|
|
113
106
|
```js
|
|
114
107
|
const area = expr.compile("width * height");
|
|
@@ -118,56 +111,69 @@ area({ width: 3, height: 9 }); // 27
|
|
|
118
111
|
|
|
119
112
|
### `expr.setVariable(name, value)` / `expr.getVariable(name)`
|
|
120
113
|
|
|
121
|
-
Stores
|
|
114
|
+
Stores a named value that persists across all future evaluations on this instance. `getVariable` retrieves a previously stored value by name.
|
|
122
115
|
|
|
123
116
|
```js
|
|
124
117
|
expr.setVariable("x", 10);
|
|
125
118
|
expr.setVariable("y", 5);
|
|
126
119
|
expr.evaluate("x + y * 2"); // 20
|
|
120
|
+
|
|
121
|
+
expr.getVariable("x"); // 10
|
|
127
122
|
```
|
|
128
123
|
|
|
129
124
|
### `expr.addFunction(name, fn)`
|
|
130
125
|
|
|
131
|
-
Registers a
|
|
126
|
+
Registers a plain JavaScript function under a given name, making it available to call inside any expression evaluated on this instance. The function receives its arguments as individual parameters, exactly as written in the expression.
|
|
132
127
|
|
|
133
128
|
```js
|
|
134
129
|
expr.addFunction("double", (n) => n * 2);
|
|
135
130
|
expr.evaluate("double(5) + 3"); // 13
|
|
131
|
+
|
|
132
|
+
expr.addFunction("clamp", (val, lo, hi) => Math.min(Math.max(val, lo), hi));
|
|
133
|
+
expr.evaluate("clamp(150, 0, 100)"); // 100
|
|
136
134
|
```
|
|
137
135
|
|
|
138
136
|
### `expr.chain()`
|
|
139
137
|
|
|
140
|
-
Returns a fluent `Chain` object. Each
|
|
138
|
+
Returns a fluent `Chain` object for building multi-step calculations. Each call to `.evaluate()` on the chain stores its result in the special variable `ans`, which the next expression can reference directly. Call `.done()` at the end to extract the final value.
|
|
141
139
|
|
|
142
140
|
```js
|
|
143
141
|
const c = expr.chain();
|
|
144
142
|
c.setVariable("x", 25);
|
|
145
|
-
c.evaluate("sqrt(x) + 3"); //
|
|
146
|
-
c.evaluate("ans * 2"); //
|
|
143
|
+
c.evaluate("sqrt(x) + 3"); // computes 8, stored as ans
|
|
144
|
+
c.evaluate("ans * 2"); // computes 16, stored as ans
|
|
147
145
|
c.done(); // 16
|
|
148
146
|
```
|
|
149
147
|
|
|
150
148
|
### `expr.exportState()` / `expr.importState(state)`
|
|
151
149
|
|
|
152
|
-
Serializes
|
|
150
|
+
Serializes the complete engine state - all variables, registered functions, and unit definitions - into a plain object that can be stored, transmitted, or restored later. `importState` loads a previously exported snapshot into a fresh instance, fully reconstructing that environment.
|
|
153
151
|
|
|
154
152
|
```js
|
|
155
153
|
const state = expr.exportState();
|
|
156
|
-
// {
|
|
154
|
+
// {
|
|
155
|
+
// variables: { x: 10, y: 5 },
|
|
156
|
+
// functions: ["double", "clamp"],
|
|
157
|
+
// units: {...}
|
|
158
|
+
// }
|
|
157
159
|
|
|
158
160
|
const expr2 = new Exprify();
|
|
159
161
|
expr2.importState(state);
|
|
162
|
+
expr2.evaluate("x + y"); // 15
|
|
160
163
|
```
|
|
161
164
|
|
|
162
165
|
### Inline Function Definitions
|
|
163
166
|
|
|
164
|
-
Functions can be defined directly inside
|
|
167
|
+
Functions can be defined directly inside an expression using the `name(params) = body` syntax. Once defined, they behave exactly like functions registered via `addFunction` and remain available for the lifetime of the instance.
|
|
165
168
|
|
|
166
169
|
```js
|
|
167
170
|
expr.evaluate("hyp(a, b) = sqrt(a^2 + b^2)");
|
|
168
171
|
expr.evaluate("hyp(3, 4)"); // 5
|
|
172
|
+
expr.evaluate("hyp(5, 12)"); // 13
|
|
169
173
|
```
|
|
170
174
|
|
|
175
|
+
This is particularly convenient for one-off helpers that do not warrant a full `addFunction` call, or for expressions that define and immediately use a function in a single evaluation step.
|
|
176
|
+
|
|
171
177
|
## Built-in Functions (Selected)
|
|
172
178
|
|
|
173
179
|
| Function | Description | Example | Result |
|
|
@@ -192,6 +198,7 @@ expr.evaluate("hyp(3, 4)"); // 5
|
|
|
192
198
|
| Function | `x -> x^2` | Native JS function |
|
|
193
199
|
| Array | `1:5` | `[1,2,3,4,5]` |
|
|
194
200
|
|
|
201
|
+
|
|
195
202
|
## Manual Build
|
|
196
203
|
|
|
197
204
|
```bash
|
package/dist/exprify.js
CHANGED
package/dist/exprify.min.js
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
/*! exprify v1.0.
|
|
1
|
+
/*! exprify v1.0.7 | * (c) 2026 Nirmal Paul and contributors | GPL-3.0 License*/
|
|
2
2
|
!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?module.exports=t():"function"==typeof define&&define.amd?define(t):(e="undefined"!=typeof globalThis?globalThis:e||self).Exprify=t()}(this,function(){"use strict";const e=e=>e&&"object"==typeof e&&"DenseMatrix"===e.exprify&&"data"in e&&"size"in e,t=e=>Array.isArray(e)?e.map(t):e,r=e=>{if(Array.isArray(e)&&e.every(Array.isArray))return[e.length,e[0]?.length||0];if(Array.isArray(e))return[e.length];throw new Error("Matrix data must be an array")},n=e=>({exprify:"DenseMatrix",data:t(e),size:r(e)}),o=r=>e(r)?t(r.data):r,i=t=>e(t)?JSON.stringify(t):Array.isArray(t)||t&&"object"==typeof t?JSON.stringify(t,(t,r)=>(e(r),r)):t;function a(e,t=1){if("number"!=typeof e||"number"!=typeof t)throw new Error("Fraction requires numeric arguments");if(!Number.isInteger(e)||!Number.isInteger(t))throw new Error("Fraction requires integer arguments");if(0===t)throw new Error("Fraction denominator cannot be zero");t<0&&(e=-e,t=-t);const r=((e,t)=>{for(e=Math.abs(e),t=Math.abs(t);t;)[e,t]=[t,e%t];return e})(e,t);return{n:e/r,d:t/r}}function s(e){return e&&"object"==typeof e&&"n"in e&&"d"in e&&!("re"in e)&&!("unit"in e)}class u{static DP=20;#e;#t;#r;constructor(e){if(e instanceof u)return this.#e=e.#e,this.#t=e.#t,void(this.#r=e.#r);if("bigint"==typeof e)return this.#e=e>=0n?1:-1,this.#t=e>=0n?e:-e,void(this.#r=0);if("number"==typeof e){if(!Number.isFinite(e))throw new Error(`Cannot create ExprDecimal from ${e}`);e=String(e)}if("string"!=typeof e)throw new Error("ExprDecimal expects a number, string, bigint, or ExprDecimal");let t=e.trim();if(""===t)throw new Error("Cannot create ExprDecimal from empty string");this.#e=1,"-"===t[0]?(this.#e=-1,t=t.slice(1)):"+"===t[0]&&(t=t.slice(1));let r=0;const n=t.search(/[eE]/);-1!==n&&(r=parseInt(t.slice(n+1),10),t=t.slice(0,n));const o=t.indexOf(".");if(-1===o)this.#t=BigInt(t||"0"),this.#r=0;else{const e=t.slice(0,o)||"0",r=t.slice(o+1),n=e+r;this.#t=BigInt(n||"0"),this.#r=r.length}this.#r-=r,this.#r<0&&(this.#t*=10n**BigInt(-this.#r),this.#r=0),this.#n()}#n(){for(;this.#r>0&&this.#t%10n==0n;)this.#t/=10n,this.#r--;0n===this.#t&&(this.#e=1,this.#r=0)}#o(e){if(this.#r===e.#r)return[this.#t*BigInt(this.#e),e.#t*BigInt(e.#e),this.#r];if(this.#r<e.#r){const t=10n**BigInt(e.#r-this.#r);return[this.#t*t*BigInt(this.#e),e.#t*BigInt(e.#e),e.#r]}const t=10n**BigInt(this.#r-e.#r);return[this.#t*BigInt(this.#e),e.#t*t*BigInt(e.#e),this.#r]}#i(e,t,r){const n=new u(0);return n.#e=e,n.#t=t<0n?-t:t,t<0n&&(n.#e=-e),n.#r=r,n.#n(),n}plus(e){e=e instanceof u?e:new u(e);const[t,r,n]=this.#o(e);return this.#i(1,t+r,n)}minus(e){e=e instanceof u?e:new u(e);const[t,r,n]=this.#o(e);return this.#i(1,t-r,n)}times(e){e=e instanceof u?e:new u(e);const t=this.#t*e.#t,r=this.#r+e.#r;return this.#i(this.#e*e.#e,t,r)}div(e){if(0n===(e=e instanceof u?e:new u(e)).#t)throw new Error("Division by zero");const t=Math.min(u.DP,100),r=10n**BigInt(t+e.#r),n=this.#t*r/e.#t,o=this.#e*e.#e;return 0n===n?new u(0):this.#i(o,n,t)}mod(e){e=e instanceof u?e:new u(e);const t=this.div(e),r=t.#i(t.#e,t.#t-t.#t%10n**BigInt(t.#r>0?1:0),0);return this.minus(r.times(e))}pow(e){if((e=e instanceof u?e:new u(e)).#r>0||1!==e.#e)throw new Error("ExprDecimal pow() supports non-negative integer exponents only");const t=Number(e.#t);if(t>100)throw new Error("ExprDecimal pow() exponent too large");let r=new u(1);for(let e=0;e<t;e++)r=r.times(this);return r}negated(){const e=new u(this);return e.#e=-e.#e,0n===e.#t&&(e.#e=1),e}eq(e){e=e instanceof u?e:new u(e);const[t,r]=this.#o(e);return t===r}gt(e){e=e instanceof u?e:new u(e);const[t,r]=this.#o(e);return t>r}lt(e){e=e instanceof u?e:new u(e);const[t,r]=this.#o(e);return t<r}gte(e){return this.gt(e)||this.eq(e)}lte(e){return this.lt(e)||this.eq(e)}toString(){let e=this.#t.toString();const t=this.#r,r=(e,t)=>{const r=e[0],n=e.slice(1).replace(/0+$/,"");let o=r;return n&&(o+=`.${n}`),o+="e",o+=t>=0?"+":"",o+=t,-1===this.#e?`-${o}`:o};if(0===t)return e.length>15?r(e,e.length-1):-1===this.#e?`-${e}`:e;for(;e.length<=t;)e=`0${e}`;const n=e.length-t,o=e.slice(0,n),i=o.replace(/^0+/,"")||"0",a=e.slice(n);if(i.length>15||"0"===i&&a.replace(/0+$/,"").length>15){const t=e.replace(/^0+/,"")||"0";return r(t,n-(e.length-t.length)-1)}const s=o||"0",u=a.replace(/0+$/,"");return""===u?-1===this.#e?`-${s}`:s:`${-1===this.#e?"-":""}${s}.${u}`}toNumber(){return Number(this.toString())}static isDecimal(e){return e instanceof u}}function l(e){if(u.isDecimal(e))return e;if("number"==typeof e||"string"==typeof e||"bigint"==typeof e)return new u(e);throw new Error("bignumber() expects a number, string, or bigint")}function c(e){return u.isDecimal(e)}function p(e){return u.isDecimal(e)?e.toString():String(e)}function h(t,r={}){const i=r.variables,u=r.functions,p=r.units,f=e=>e&&"object"==typeof e&&"value"in e&&"unit"in e,m=e=>e&&"object"==typeof e&&"re"in e&&"im"in e,g=e=>Array.isArray(e)&&e.length>0&&e.every(Array.isArray),y=t=>g(t)||e(t),d=e=>{if(e=o(e),g(e))return e.map(e=>[...e]);if(Array.isArray(e))return[e];throw new Error("Expected matrix-compatible value")},w=e=>{const r=t&&void 0!==t.pos?` at position ${t.pos}`:"";return new Error(`${e}${r}`)},b=e=>{if("number"!=typeof e||!Number.isInteger(e)||e<1)throw new Error("Matrix indices must be positive integers");return e-1},v=(e,t)=>{if((n=e)&&"object"==typeof n&&"SliceExpression"===n.type){const n=null===e.start||void 0===e.start?1:h(e.start,r),o=null===e.end||void 0===e.end?t:h(e.end,r),i=b(n),a=b(o);if(a<i)return[];const s=[];for(let e=i;e<=a;e++)s.push(e);return s}var n;return[b(h(e,r))]},E=e=>"number"==typeof e||"bigint"==typeof e,x=(e,t)=>{if(E(e)){return d(t).map(t=>t.map(t=>Number(e)*t))}if(E(t)){return d(e).map(e=>e.map(e=>e*Number(t)))}const r=d(e),n=d(t);if(r[0].length!==n.length)throw new Error("Matrix dimensions do not allow multiplication");return r.map(e=>n[0].map((t,r)=>e.reduce((e,t,o)=>e+t*n[o][r],0)))},M=(e,t)=>{const r=d(e);if(r.length!==r[0].length)throw new Error("Matrix power requires a square matrix");if(!Number.isInteger(t)||t<0)throw new Error("Matrix power requires a non-negative integer exponent");if(0===t)return n=r.length,Array.from({length:n},(e,t)=>Array.from({length:n},(e,r)=>t===r?1:0));var n;let o=r;for(let e=1;e<t;e++)o=x(o,r);return o},A=e=>{if(m(e))return e;if("number"==typeof e)return{re:e,im:0};throw new Error("Complex arithmetic only supports numbers")},$=e=>0===e.im?e.re:e,I=(e,t)=>{const r={};return e.forEach((e,n)=>{r[e]=t[n]}),r};switch(t.type){case"Literal":return t.value;case"ImaginaryLiteral":return{re:0,im:t.value};case"UnitLiteral":return{value:t.value,unit:t.unit};case"Identifier":return i.get(t.name);case"AssignmentExpression":{let e;if("="!==t.operator){const n=i.get(t.left.name),o=h(t.right,r);switch(t.operator.slice(0,-1)){case"+":e=n+o;break;case"-":e=n-o;break;case"*":e=n*o;break;case"/":e=n/o;break;case"%":e=n%o;break;default:throw w(`Unknown compound operator ${t.operator}`)}}else e=h(t.right,r);if("Identifier"===t.left.type)return i.set(t.left.name,e),"ArrayExpression"===t.right.type?n(o(e)):e;if("IndexExpression"===t.left.type&&"Identifier"===t.left.object.type){const r=((e,t,r)=>{const n=g(e)?e.map(e=>[...e]):Array.isArray(e)?[e.slice()]:[],o=t[0],i=t[1];if(!o)throw new Error("Matrix assignment requires at least one index");const a=Math.max(n.length,1),s=v(o,a);if(1===t.length){const e=g(r)?r:d(r);if(e.length!==s.length)throw new Error("Assigned row count does not match slice");return s.forEach((t,r)=>{n[t]=[...e[r]]}),{updatedMatrix:n,selectionResult:1===s.length?[n[s[0]]]:s.map(e=>[n[e]])}}const u=Math.max(...n.map(e=>e.length),0,1),l=v(i,u),c=d(r);if(c.length!==s.length)throw new Error("Assigned row count does not match matrix slice");return c.forEach((e,t)=>{if(e.length!==l.length)throw new Error("Assigned column count does not match matrix slice")}),s.forEach((e,t)=>{n[e]||(n[e]=[]),l.forEach((r,o)=>{n[e][r]=c[t][o]})}),{updatedMatrix:n,selectionResult:1===s.length?[l.map(e=>n[s[0]][e])]:s.map(e=>l.map(t=>n[e][t]))}})(i.get(t.left.object.name),t.left.selectors,e);return i.set(t.left.object.name,r.updatedMatrix),r.selectionResult}throw w("Invalid assignment target")}case"FunctionAssignmentExpression":{if("="!==t.operator)throw w(`Operator ${t.operator} is not supported for function definitions`);const e=(...e)=>{const n=r.withScope(I(t.params,e));return h(t.right,n)};return u.register(t.left.name,e),e}case"UnaryExpression":{const e=h(t.argument,r);switch(t.operator){case"-":return c(e)?e.negated():m(e)?$({re:-e.re,im:-e.im}):-e;case"!":return!e}throw w(`Unknown unary operator ${t.operator}`)}case"BinaryExpression":{const e=h(t.left,r),n=h(t.right,r);if(f(e)||f(n)){if(!p)throw new Error("Unit system not available");return p.compute(t.operator,e,n)}if(y(e)||y(n)||"*"===t.operator&&(Array.isArray(e)||Array.isArray(n)))switch(t.operator){case"+":return((e,t)=>{const r=d(e),n=d(t);if(r.length!==n.length||r[0].length!==n[0].length)throw new Error("Matrix dimensions must match for addition");return r.map((e,t)=>e.map((e,r)=>e+n[t][r]))})(e,n);case"-":return((e,t)=>{const r=d(e),n=d(t);if(r.length!==n.length||r[0].length!==n[0].length)throw new Error("Matrix dimensions must match for subtraction");return r.map((e,t)=>e.map((e,r)=>e-n[t][r]))})(e,n);case"*":return x(e,n);case"^":return M(e,n);default:throw w(`Operator ${t.operator} not supported for matrices`)}if(s(e)||s(n)){const r=s(e)?e:a(e,1),o=s(n)?n:a(n,1);switch(t.operator){case"+":return function(e,t){return a(e.n*t.d+t.n*e.d,e.d*t.d)}(r,o);case"-":return function(e,t){return a(e.n*t.d-t.n*e.d,e.d*t.d)}(r,o);case"*":return function(e,t){return a(e.n*t.n,e.d*t.d)}(r,o);case"/":return function(e,t){return a(e.n*t.d,e.d*t.n)}(r,o);case"^":{const e=function(e,t){return!Number.isInteger(t)||t<0?null:a(e.n**t,e.d**t)}(r,n);if(e)return e;throw w("Fraction power requires non-negative integer exponent")}default:throw w(`Operator ${t.operator} not supported for fractions`)}}if(c(e)||c(n)){const r=c(e)?e:l(e),o=c(n)?n:l(n);switch(t.operator){case"+":return r.plus(o);case"-":return r.minus(o);case"*":return r.times(o);case"/":return r.div(o);case"%":return r.mod(o);case"^":return r.pow(o);case">":return r.gt(o);case"<":return r.lt(o);case">=":return r.gte(o);case"<=":return r.lte(o);case"==":return r.eq(o);default:throw w(`Operator ${t.operator} not supported for BigNumber`)}}if(m(e)||m(n))return((e,t,r)=>{const n=A(t),o=A(r);switch(e){case"+":return $({re:n.re+o.re,im:n.im+o.im});case"-":return $({re:n.re-o.re,im:n.im-o.im});case"*":return $({re:n.re*o.re-n.im*o.im,im:n.re*o.im+n.im*o.re});case"/":{const e=o.re**2+o.im**2;if(0===e)throw new Error("Division by zero");return $({re:(n.re*o.re+n.im*o.im)/e,im:(n.im*o.re-n.re*o.im)/e})}default:throw new Error(`Operator ${e} is not supported for complex numbers`)}})(t.operator,e,n);switch(t.operator){case"+":return e+n;case"-":return e-n;case"*":return e*n;case"/":return e/n;case"%":return e%n;case"^":return e**n;case">":return e>n;case"<":return e<n;case">=":return e>=n;case"<=":return e<=n;case"==":return e===n}throw w(`Unknown operator ${t.operator}`)}case"LogicalExpression":{const e=h(t.left,r);if("&&"===t.operator)return e&&h(t.right,r);if("||"===t.operator)return e||h(t.right,r);if("??"===t.operator)return e??h(t.right,r);throw w(`Unknown logical operator ${t.operator}`)}case"RangeExpression":{const e=h(t.start,r),n=h(t.end,r);if("number"!=typeof e||"number"!=typeof n)throw w("Range requires numeric bounds");const o=[];for(let t=Math.floor(e);t<=Math.floor(n);t++)o.push(t);return o}case"ArrowFunctionExpression":return(...e)=>{const n=r.withScope(I(t.params,e));return h(t.body,n)};case"CallExpression":{const e=t.callee.name,n=u.get(e),o=t.arguments.map(e=>{if("SpreadElement"===e.type){const t=h(e.argument,r);if(!Array.isArray(t))throw new Error("Spread operator requires an array");return{spread:!0,values:t}}return{spread:!1,value:h(e,r)}}),i=[];for(const e of o)e.spread?i.push(...e.values):i.push(e.value);return n(...i)}case"PipelineExpression":{const e=h(t.left,r);if("CallExpression"===t.right.type){const n=t.right.callee.name;return u.get(n)(...[e,...t.right.arguments.map(e=>h(e,r))])}if("Identifier"===t.right.type){return u.get(t.right.name)(e)}throw w("Invalid pipeline target")}case"UnitConversion":{const e=h(t.from,r);if(!f(e))throw w("Left side must be a unit value");if(!p)throw w("Unit system not available");return p.convert(e.value,e.unit,t.to)}case"ArrayExpression":return t.elements.map(e=>h(e,r));case"IndexExpression":return((e,t)=>{const r=d(e);if(1===t.length){const e=v(t[0],r.length).map(e=>{if(e>=r.length)throw new Error("Row index out of range");return[...r[e]]});return 1===e.length?e[0]:e}const n=v(t[0],r.length),o=v(t[1],r[0]?.length||0),i=n.map(e=>{if(e>=r.length)throw new Error("Row index out of range");return o.map(t=>{if(t>=r[e].length)throw new Error("Column index out of range");return r[e][t]})});return 1===n.length&&1===o.length?i[0][0]:1===n.length?i[0]:1===o.length?i.map(e=>[e[0]]):i})(h(t.object,r),t.selectors);case"ObjectExpression":{const e={};for(const n of t.properties)e[n.key]=h(n.value,r);return e}case"MemberExpression":{const e=h(t.object,r);if(t.optional&&null==e)return;return e[t.property.name]}default:throw w(`Unknown AST node type: ${t.type}`)}}function f({variables:e,functions:t,units:r,evaluate:n}){if(!e)throw new Error("Variable store missing");if(!t)throw new Error("Function registry missing");if(!r)throw new Error("Units list missing");if(!n)throw new Error("evaluate function missing");return{variables:e,functions:t,units:r,evaluate:n,withScope(o={}){const i={...e.all?.(),...o};return f({functions:t,evaluate:n,units:r,variables:{get:e=>i[e],set:(e,t)=>i[e]=t,all:()=>i}})}}}const m=(e,t)=>typeof e==typeof t&&("number"==typeof e||"bigint"==typeof e),g=Object.freeze({power:function(e,t){if(m(e,t))return e**t;throw new Error("Invalid types for ^")},multiply:function(e,t){if(m(e,t))return e*t;throw new Error("Invalid types for *")},divide:function(e,t){if(m(e,t)){if(0===t)throw new Error("Division by zero");return e/t}throw new Error("Invalid types for /")},add:function(e,t){if(m(e,t))return e+t;if("string"==typeof e&&"string"==typeof t)return e+t;throw new Error("Invalid types for +")},subtract:function(e,t){if(m(e,t))return e-t;throw new Error("Invalid types for -")},modulus:function(e,t){if(m(e,t))return e%t;throw new Error("Invalid types for %")}});const y={length:{m:{value:1,unit:"meter",symbol:"m"},cm:{value:.01,unit:"centimeter",symbol:"cm"},mm:{value:.001,unit:"millimeter",symbol:"mm"},km:{value:1e3,unit:"kilometer",symbol:"km"},um:{value:1e-6,unit:"micrometer",symbol:"um",note:"also called micron"},nm:{value:1e-9,unit:"nanometer",symbol:"nm"},px:{value:264583e-9,unit:"pixel",symbol:"px",note:"96dpi standard"},em:{value:.004233328,unit:"em",symbol:"em",note:"1em = 16px by default"},rem:{value:.004233328,unit:"rem",symbol:"rem",note:"root em = 16px by default"},pt:{value:352778e-9,unit:"point",symbol:"pt",note:"1pt = 1/72 inch"},pica:{value:.00423333,unit:"pica",symbol:"pc",note:"1pc = 12pt"},inch:{value:.0254,unit:"inch",symbol:"in"},ft:{value:.3048,unit:"foot",symbol:"ft"},yd:{value:.9144,unit:"yard",symbol:"yd"},mi:{value:1609.344,unit:"mile",symbol:"mi"},thou:{value:254e-7,unit:"mil",symbol:"thou",note:"thousandth of an inch"},furlong:{value:201.168,unit:"furlong",symbol:"fur",note:"220 yards"},nmi:{value:1852,unit:"nautical mile",symbol:"nmi"},fathom:{value:1.8288,unit:"fathom",symbol:"fathom"},au:{value:1496e8,unit:"astronomical unit",symbol:"AU"},ly:{value:94607e11,unit:"light year",symbol:"ly"},pc:{value:30857e12,unit:"parsec",symbol:"pc"}},weight:{mg:{value:1e-6,unit:"milligram",symbol:"mg"},g:{value:.001,unit:"gram",symbol:"g"},kg:{value:1,unit:"kilogram",symbol:"kg"},t:{value:1e3,unit:"tonne",symbol:"t",note:"metric ton"},lb:{value:.453592,unit:"pound",symbol:"lb"},oz:{value:.0283495,unit:"ounce",symbol:"oz"},stone:{value:6.35029,unit:"stone",symbol:"st",note:"1 stone = 14 lb"}},time:{s:{value:1,unit:"second",symbol:"s"},min:{value:60,unit:"minute",symbol:"min"},h:{value:3600,unit:"hour",symbol:"h"},day:{value:86400,unit:"day",symbol:"d"},week:{value:604800,unit:"week",symbol:"wk"},month:{value:2629800,unit:"month",symbol:"mo",note:"average month = 30.44 days"},year:{value:31557600,unit:"year",symbol:"yr",note:"average year = 365.25 days"}},voltage:{V:{value:1,unit:"volt",symbol:"V"},mV:{value:.001,unit:"millivolt",symbol:"mV"},kV:{value:1e3,unit:"kilovolt",symbol:"kV"},MV:{value:1e6,unit:"megavolt",symbol:"MV"},GV:{value:1e9,unit:"gigavolt",symbol:"GV"},statV:{value:299.792458,unit:"statvolt",symbol:"statV",note:"CGS unit"},abV:{value:1e-8,unit:"abvolt",symbol:"abV",note:"CGS electromagnetic unit"}},frequency:{Hz:{value:1,unit:"hertz",symbol:"Hz",note:"1 cycle per second"},kHz:{value:1e3,unit:"kilohertz",symbol:"kHz"},MHz:{value:1e6,unit:"megahertz",symbol:"MHz"},GHz:{value:1e9,unit:"gigahertz",symbol:"GHz"},THz:{value:1e12,unit:"terahertz",symbol:"THz"}},power:{W:{value:1,unit:"watt",symbol:"W",note:"1 joule per second"},mW:{value:.001,unit:"milliwatt",symbol:"mW"},kW:{value:1e3,unit:"kilowatt",symbol:"kW"},MW:{value:1e6,unit:"megawatt",symbol:"MW"},GW:{value:1e9,unit:"gigawatt",symbol:"GW"},HP:{value:745.7,unit:"horsepower",symbol:"HP",note:"mechanical HP = 745.7 W"},"kcal/h":{value:1.163,unit:"kilocalorie per hour",symbol:"kcal/h",note:"= 1.163 W"},"BTU/h":{value:.29307107,unit:"BTU per hour",symbol:"BTU/h",note:"= 0.293 W"}},sound:{dB:{value:1,unit:"decibel",symbol:"dB",note:"logarithmic unit of sound intensity"},dBA:{value:1,unit:"A-weighted decibel",symbol:"dBA",note:"Adjusted for human hearing"},dBC:{value:1,unit:"C-weighted decibel",symbol:"dBC",note:"Flat weighting for high-level sounds"}},temperature:{K:{value:1,unit:"kelvin",symbol:"K"},C:{value:1,unit:"Celsius",symbol:"°C",note:"°C → K: add 273.15"},F:{value:1,unit:"Fahrenheit",symbol:"°F",note:"°F → K: (°F - 32) * 5/9 + 273.15"}},pressure:{Pa:{value:1,unit:"pascal",symbol:"Pa"},kPa:{value:1e3,unit:"kilopascal",symbol:"kPa"},MPa:{value:1e6,unit:"megapascal",symbol:"MPa"},bar:{value:1e5,unit:"bar",symbol:"bar"},atm:{value:101325,unit:"atmosphere",symbol:"atm"},psi:{value:6894.757,unit:"pound per square inch",symbol:"psi"},mmHg:{value:133.322,unit:"millimeter of mercury",symbol:"mmHg"}},energy:{J:{value:1,unit:"joule",symbol:"J"},kJ:{value:1e3,unit:"kilojoule",symbol:"kJ"},cal:{value:4.184,unit:"calorie",symbol:"cal"},kcal:{value:4184,unit:"kilocalorie",symbol:"kcal"},eV:{value:160218e-24,unit:"electronvolt",symbol:"eV"},BTU:{value:1055.06,unit:"BTU",symbol:"BTU"}},force:{N:{value:1,unit:"newton",symbol:"N"},kN:{value:1e3,unit:"kilonewton",symbol:"kN"},lbf:{value:4.44822,unit:"pound-force",symbol:"lbf"},kgf:{value:9.80665,unit:"kilogram-force",symbol:"kgf"},dyne:{value:1e-5,unit:"dyne",symbol:"dyn"}},area:{m2:{value:1,unit:"square meter",symbol:"m²"},cm2:{value:1e-4,unit:"square centimeter",symbol:"cm²"},km2:{value:1e6,unit:"square kilometer",symbol:"km²"},acre:{value:4046.856,unit:"acre",symbol:"acre"},hectare:{value:1e4,unit:"hectare",symbol:"ha"},ft2:{value:.092903,unit:"square foot",symbol:"ft²"},yd2:{value:.836127,unit:"square yard",symbol:"yd²"}},volume:{m3:{value:1,unit:"cubic meter",symbol:"m³"},L:{value:.001,unit:"liter",symbol:"L"},mL:{value:1e-6,unit:"milliliter",symbol:"mL"},gallon:{value:.00378541,unit:"US gallon",symbol:"gal"},pint:{value:473176e-9,unit:"US pint",symbol:"pt"},floz:{value:29574e-9,unit:"US fluid ounce",symbol:"fl oz"}},current:{A:{value:1,unit:"ampere",symbol:"A"},mA:{value:.001,unit:"milliampere",symbol:"mA"},uA:{value:1e-6,unit:"microampere",symbol:"uA"},kA:{value:1e3,unit:"kiloampere",symbol:"kA"}},resistance:{ohm:{value:1,unit:"ohm"},kohm:{value:1e3,unit:"kiloohm"},megaohm:{value:1e6,unit:"megaohm"},S:{value:1,unit:"siemens",symbol:"S",note:"conductance"}},capacitance:{F:{value:1,unit:"farad",symbol:"F"},mF:{value:.001,unit:"millifarad"},uF:{value:1e-6,unit:"microfarad"}},inductance:{H:{value:1,unit:"henry",symbol:"H"},mH:{value:.001,unit:"millihenry",symbol:"mH"},uH:{value:1e-6,unit:"microhenry",symbol:"uH"}},light:{cd:{value:1,unit:"candela",symbol:"cd"},lm:{value:1,unit:"lumen",symbol:"lm"},lx:{value:1,unit:"lux",symbol:"lx"}},data:{bit:{value:1,unit:"bit",symbol:"bit"},B:{value:8,unit:"byte",symbol:"B"},KB:{value:8e3,unit:"kilobyte",symbol:"KB"},MB:{value:8e6,unit:"megabyte",symbol:"MB"},GB:{value:8e9,unit:"gigabyte",symbol:"GB"},TB:{value:8e12,unit:"terabyte",symbol:"TB"}},angle:{deg:{value:1,unit:"degree",symbol:"°"},rad:{value:57.2958,unit:"radian",symbol:"rad",note:"1 rad = 57.2958°"},grad:{value:.9,unit:"grad",symbol:"grad",note:"1 grad = 0.9°"}},radiation:{Gy:{value:1,unit:"gray",symbol:"Gy",note:"Absorbed dose: 1 Gy = 1 J/kg"},mGy:{value:.001,unit:"milligray",symbol:"mGy"},rad:{value:.01,unit:"rad",symbol:"rad",note:"1 rad = 0.01 Gy"},Sv:{value:1,unit:"sievert",symbol:"Sv",note:"Biological effect dose equivalent"},mSv:{value:.001,unit:"millisievert",symbol:"mSv"},rem:{value:.01,unit:"rem",symbol:"rem",note:"1 rem = 0.01 Sv"},Bq:{value:1,unit:"becquerel",symbol:"Bq",note:"1 decay per second"},kBq:{value:1e3,unit:"kilobecquerel",symbol:"kBq"},MBq:{value:1e6,unit:"megabecquerel",symbol:"MBq"},GBq:{value:1e9,unit:"gigabecquerel",symbol:"GBq"},Ci:{value:37e9,unit:"curie",symbol:"Ci",note:"1 Ci = 3.7 x 10¹⁰ decays per second"},mCi:{value:37e6,unit:"millicurie",symbol:"mCi"}}},d=/^[a-zA-Z_$][a-zA-Z0-9_$]*$/;function w(e={}){let t=Object.create(null);for(const r in e)t[r]=e[r];return{set(e,r,{override:n=!0}={}){if("string"!=typeof e||!e)throw new Error("Variable name must be a non-empty string");if(!d.test(e))throw new Error(`Variable Name Error: '${e}' is not a valid variable name`);if(void 0===r)throw new Error(`Variable Value Error: '${e}' cannot be undefined`);if(!n&&e in t)throw new Error(`Variable '${e}' already exists`);t[e]=r},get:e=>t[e],has:e=>Object.prototype.hasOwnProperty.call(t,e),remove(e){delete t[e]},all:()=>({...t}),clear(){t=Object.create(null)},merge(e={}){for(const r in e)t[r]=e[r]},clone:()=>w(t)}}function b(e={}){const t=Object.create(null);for(const r in e)"function"==typeof e[r]&&(t[r]=e[r]);return{getAllFunctionsName:()=>Object.keys(t),register(e,r){if("string"!=typeof e||!e)throw new Error("Formula name must be a non-empty string");if("function"!=typeof r)throw new Error(`Formula "${e}" must be callable`);t[e]=r},get:e=>t[e],has:e=>Object.prototype.hasOwnProperty.call(t,e),remove(e){delete t[e]},all:()=>({...t}),clear(){for(const e in t)delete t[e]},extend(e={}){for(const r in e)"function"==typeof e[r]&&(t[r]=e[r])},clone:()=>b(t)}}function v(e){if(e=o(e),!Array.isArray(e)||0===e.length)throw new Error("det() expects a non-empty matrix");if(!e.every(Array.isArray))throw new Error("det() expects a 2D matrix");const t=e.length;if(!e.every(e=>e.length===t))throw new Error("det() expects a square matrix");for(const t of e)for(const e of t)if("number"!=typeof e&&"bigint"!=typeof e)throw new Error("det() matrix values must be numeric")}function E(e){return v(e=o(e)),1===e.length?e[0][0]:2===e.length?e[0][0]*e[1][1]-e[0][1]*e[1][0]:e[0].reduce((t,r,n)=>{const o=e.slice(1).map(e=>e.filter((e,t)=>t!==n));return t+(n%2==0?r:-r)*E(o)},0)}function x(e){const t=o(e);if(!Array.isArray(t))throw new Error("Expected matrix data");return t}function M(e){const t=x(e).map(e=>[...e]);v(t);const r=t.length,o=Array.from({length:r},(e,t)=>t);for(let e=0;e<r;e++){let n=e,i=Math.abs(t[e][e]);for(let o=e+1;o<r;o++){const r=Math.abs(t[o][e]);r>i&&(i=r,n=o)}if(0===i)throw new Error("Matrix is singular");n!==e&&([t[e],t[n]]=[t[n],t[e]],[o[e],o[n]]=[o[n],o[e]]);for(let n=e+1;n<r;n++){t[n][e]/=t[e][e];for(let o=e+1;o<r;o++)t[n][o]-=t[n][e]*t[e][o]}}const i=t.map((e,t)=>e.map((e,r)=>t===r?1:t>r?e:0)),a=t.map((e,t)=>e.map((e,r)=>t<=r?e:0));return{L:n(i),U:n(a),p:o}}function A(e,t){const{L:r,U:o,p:i}=M(e),a=x(e),s=x(t),u=Array.isArray(s[0])?s.map(e=>e[0]):s;if(a.length!==u.length)throw new Error("Right-hand side dimension mismatch");const l=i.map(e=>u[e]),c=new Array(a.length).fill(0);for(let e=0;e<a.length;e++){c[e]=l[e];for(let t=0;t<e;t++)c[e]-=r.data[e][t]*c[t]}const p=new Array(a.length).fill(0);for(let e=a.length-1;e>=0;e--){p[e]=c[e];for(let t=e+1;t<a.length;t++)p[e]-=o.data[e][t]*p[t];p[e]/=o.data[e][e]}return n(p.map(e=>[e]))}function $(e,t){const r=x(e).map(e=>[...e]),o=x(t).map(e=>[...e]);v(r),v(o);const i=r.length;if(o.length!==i)throw new Error("A and Q must have the same dimensions");const a=[],s=[];for(let e=0;e<i;e++)for(let t=0;t<i;t++){const n=new Array(i*i).fill(0);for(let o=0;o<i;o++)n[o*i+t]+=r[e][o],n[e*i+o]+=r[t][o];a.push(n),s.push(-o[e][t])}const u=function(e,t){const r=e.length,n=e.map((e,r)=>[...e,t[r]]);for(let e=0;e<r;e++){let t=e,o=Math.abs(n[e][e]);for(let i=e+1;i<r;i++){const r=Math.abs(n[i][e]);r>o&&(o=r,t=i)}if(0===o)throw new Error("Linear system is singular");t!==e&&([n[e],n[t]]=[n[t],n[e]]);const i=n[e][e];for(let t=e;t<=r;t++)n[e][t]/=i;for(let t=0;t<r;t++){if(t===e)continue;const o=n[t][e];for(let i=e;i<=r;i++)n[t][i]-=o*n[e][i]}}return n.map(e=>e[r])}(a,s),l=[];for(let e=0;e<i;e++)l.push(u.slice(e*i,(e+1)*i));return n(l)}function I(e,t){return e.reduce((e,r,n)=>e+r*t**n,0)}function k(e,t){const r=[...e].reverse(),n=[r[0]];for(let e=1;e<r.length-1;e++)n.push(r[e]+n[e-1]*t);const o=r[r.length-1]+n[n.length-1]*t;return{quotient:n.reverse(),remainder:o}}function q(e){const[t,r,n]=e,o=r**2-4*n*t;if(o<0)throw new Error("Only real roots are supported");const i=Math.sqrt(o);return[(-r+i)/(2*n),(-r-i)/(2*n)]}function N(e,t){return e.reduce((e,r,n)=>e+r*t[n],0)}function O(e){return Math.sqrt(N(e,e))}function z(e,t){return e.map(e=>e*t)}function B(e,t){return e.map((e,r)=>e-t[r])}function C(e){return e[0].map((t,r)=>e.map(e=>e[r]))}function U(e,t){const r=function(e){const t=e.replace(/\s+/g,"");return t?t.replace(/-/g,"+-").split("+").filter(Boolean):[]}(e),n=new Map;for(const e of r)if(e.includes(t)){const[r,o]=e.split(t);let i;if(""===r||"+"===r)i=1;else if("-"===r)i=-1;else{const e=r.endsWith("*")?r.slice(0,-1):r;i=Number(e)}if(!Number.isFinite(i))throw new Error("Unsupported algebra term");let a=1;if(o){if(!o.startsWith("^"))throw new Error("Unsupported algebra term");a=Number(o.slice(1))}if(!Number.isInteger(a)||a<0)throw new Error("Only non-negative integer powers are supported");n.set(a,(n.get(a)||0)+i)}else{const t=Number(e);if(!Number.isFinite(t))throw new Error("Unsupported algebra term");n.set(0,(n.get(0)||0)+t)}return n}function j(e,t){const r=[...e.entries()].filter(([,e])=>0!==e).sort((e,t)=>t[0]-e[0]);return r.length?r.map(([e,r],n)=>{const o=r<0,i=Math.abs(r);let a;return a=0===e?`${i}`:1===e?1===i?t:`${i} * ${t}`:1===i?`${t}^${e}`:`${i} * ${t}^${e}`,0===n?o?`-${a}`:a:o?`- ${a}`:`+ ${a}`}).join(" "):"0"}function S(e,t){for(e=Math.abs(e),t=Math.abs(t);t;)[e,t]=[t,e%t];return e}function F(e){if(0===e)throw new Error("gamma(0) is undefined");if(Number.isInteger(e)&&e<0)throw new Error("gamma() undefined for negative integers");if(Number.isInteger(e)&&e>0){let t=1;for(let r=2;r<e;r++)t*=r;return t}const t=[.9999999999998099,676.5203681218851,-1259.1392167224028,771.3234287776531,-176.6150291621406,12.507343278686905,-.13857109526572012,9984369578019572e-21,1.5056327351493116e-7];if(e<.5)return Math.PI/(Math.sin(Math.PI*e)*F(1-e));e-=1;let r=t[0];for(let n=1;n<9;n++)r+=t[n]/(e+n);const n=e+7+.5;return Math.sqrt(2*Math.PI)*n**(e+.5)*Math.exp(-n)*r}function P(e){return Array.from({length:e},(t,r)=>Array.from({length:e},(e,t)=>r===t?1:0))}function _(e){const t=o(e).map(e=>[...e]);let r=0;const i=t.length,a=t[0].length;for(let e=0;e<i&&!(r>=a);e++){let n=e;for(;Math.abs(t[n][r])<1e-12&&(n++,!(n===i&&(n=e,r++,r>=a))););if(r>=a)break;[t[e],t[n]]=[t[n],t[e]];const o=t[e][r];for(let r=0;r<a;r++)t[e][r]/=o;for(let n=0;n<i;n++)if(n!==e){const o=t[n][r];for(let r=0;r<a;r++)t[n][r]-=o*t[e][r]}r++}return n(t)}function L(e){const t=o(e);v(e);const[[r,i],[a,s]]=t,u=r+s,l=u*u-4*(r*s-i*a);if(l<0)throw new Error("Complex eigenvalues not supported");const c=Math.sqrt(l),p=(u+c)/2,h=(u-c)/2,f=e=>Math.abs(i)>1e-12?[1,(e-r)/i]:Math.abs(a)>1e-12?[(e-s)/a,1]:[1,0],m=f(p),g=Math.sqrt(m[0]*m[0]+m[1]*m[1]),y=f(h),d=Math.sqrt(y[0]*y[0]+y[1]*y[1]);return{values:[p,h],vectors:n([[m[0]/g,y[0]/d],[m[1]/g,y[1]/d]])}}const V={fraction:(e,t)=>a(e,t),numer:e=>function(e){if(!s(e))throw new Error("numer() expects a fraction");return e.n}(e),denom:e=>function(e){if(!s(e))throw new Error("denom() expects a fraction");return e.d}(e),isFraction:e=>s(e),bignumber:e=>l(e),isBigNumber:e=>c(e),max:(...e)=>{if(!e.length)throw new Error("max() requires arguments");return Math.max(...e)},min:(...e)=>{if(!e.length)throw new Error("min() requires arguments");return Math.min(...e)},abs:e=>Math.abs(e),round:e=>Math.round(e),floor:e=>Math.floor(e),ceil:e=>Math.ceil(e),sqrt:e=>{if(e<0)throw new Error("sqrt() domain error");return Math.sqrt(e)},pow:(e,t)=>e**t,det:e=>E(e),polynomialRoot:(...e)=>function(...e){for(;e.length>1&&0===e[e.length-1];)e.pop();const t=e.length-1;if(t<1)throw new Error("polynomialRoot() expects at least a linear polynomial");if(1===t){const[t,r]=e;return[-t/r]}if(2===t)return q(e);if(3===t){const t=e[0],r=[],n=Math.abs(t);for(let e=1;e<=Math.max(1,n);e++)n%e===0&&r.push(e,-e);for(const t of r)if(0===I(e,t))return[t,...q(k(e,t).quotient)]}throw new Error("polynomialRoot() currently supports degree up to 3")}(...e),lsolve:(e,t)=>A(e,t),lup:e=>M(e),lyap:(e,t)=>$(e,t),qr:e=>function(e){const t=x(e).map(e=>[...e]);if(!t.length||!t.every(e=>e.length===t[0].length))throw new Error("qr() expects a rectangular matrix");const r=t.length,o=t[0].length,i=C(t),a=[];for(let e=0;e<o;e++){let t=[...i[e]];for(let r=0;r<a.length;r++){const n=N(a[r],i[e]);t=B(t,z(a[r],n))}const r=O(t);if(0===r)throw new Error("qr() requires linearly independent columns");a.push(z(t,1/r))}for(let e=0;a.length<r&&e<r;e++){let t=Array.from({length:r},(t,r)=>r===e?1:0);for(const e of a)t=B(t,z(e,N(e,t)));const n=O(t);n>1e-10&&a.push(z(t,1/n))}const s=Array.from({length:r},(e,t)=>a.map(e=>e[t])),u=Array.from({length:r},()=>Array(o).fill(0));for(let e=0;e<r;e++)for(let t=0;t<o;t++)u[e][t]=N(a[e],i[t]);return{Q:n(s),R:n(u)}}(e),transpose:e=>n(C(o(e))),inverse:e=>function(e){const t=o(e);v(e);const r=t.length;if(2===r){const e=t[0][0]*t[1][1]-t[0][1]*t[1][0];if(0===e)throw new Error("Matrix is singular");return n([[t[1][1]/e,-t[0][1]/e],[-t[1][0]/e,t[0][0]/e]])}const i=Array.from({length:r},()=>Array(r).fill(0));for(let e=0;e<r;e++){const a=Array.from({length:r},(t,r)=>r===e?1:0),s=A(t,n(a.map(e=>[e]))),u=o(s);for(let t=0;t<r;t++)i[t][e]=u[t][0]}return n(i)}(e),trace:e=>{const t=o(e);return v(e),t.reduce((e,t,r)=>e+t[r],0)},rank:e=>o(_(e)).filter(e=>e.some(e=>Math.abs(e)>1e-10)).length,rref:e=>_(e),minor:(e,t,r)=>{const n=o(e);v(e);return E(n.filter((e,r)=>r!==t).map(e=>e.filter((e,t)=>t!==r)))},cofactor:(e,t,r)=>{const n=o(e).filter((e,r)=>r!==t).map(e=>e.filter((e,t)=>t!==r));return((t+r)%2==0?1:-1)*E(n)},cross:(e,t)=>{const r=o(e),n=o(t);if(!Array.isArray(r)||!Array.isArray(n)||3!==r.length||3!==n.length)throw new Error("cross() requires two 3D vectors");return function(e,t){return[e[1]*t[2]-e[2]*t[1],e[2]*t[0]-e[0]*t[2],e[0]*t[1]-e[1]*t[0]]}(r,n)},normalize:e=>{const t=o(e);if(!Array.isArray(t))throw new Error("normalize() expects a vector");const r=O(t);if(0===r)throw new Error("Cannot normalize zero vector");return z(t,1/r)},angle:(e,t)=>{const r=o(e),n=o(t);if(!Array.isArray(r)||!Array.isArray(n))throw new Error("angle() expects vectors");const i=N(r,n),a=O(r)*O(n);if(0===a)throw new Error("Zero vector angle is undefined");return Math.acos(Math.max(-1,Math.min(1,i/a)))},projection:(e,t)=>{const r=o(e),n=o(t);if(!Array.isArray(r)||!Array.isArray(n))throw new Error("projection() expects vectors");const i=N(r,n),a=O(n);if(0===a)throw new Error("Zero vector projection undefined");return i/a},identity:e=>n(P(e)),eye:e=>n(P(e)),zeros:(e,t)=>(void 0===t&&(t=e),n(Array.from({length:e},()=>Array(t).fill(0)))),ones:(e,t)=>(void 0===t&&(t=e),n(Array.from({length:e},()=>Array(t).fill(1)))),diag:e=>{const t=o(e);if(!Array.isArray(t))throw new Error("diag() expects an array");return n(Array.from({length:t.length},(e,r)=>Array.from({length:t.length},(e,n)=>r===n?t[r]:0)))},cholesky:e=>function(e){const t=o(e);v(e);const r=t.length,i=Array.from({length:r},()=>Array(r).fill(0));for(let e=0;e<r;e++){let n=0;for(let t=0;t<e;t++)n+=i[e][t]*i[e][t];const o=t[e][e]-n;if(o<=0)throw new Error("Matrix is not positive definite");i[e][e]=Math.sqrt(o);for(let o=e+1;o<r;o++){n=0;for(let t=0;t<e;t++)n+=i[o][t]*i[e][t];i[o][e]=(t[o][e]-n)/i[e][e]}}return n(i)}(e),eig:e=>L(e),svd:e=>function(e){const t=o(e),r=t.length,i=t[0].length;if(2!==r||2!==i)throw new Error("svd() currently supports 2x2 matrices only");const a=[[t[0][0]*t[0][0]+t[1][0]*t[1][0],t[0][0]*t[0][1]+t[1][0]*t[1][1]],[t[0][1]*t[0][0]+t[1][1]*t[1][0],t[0][1]*t[0][1]+t[1][1]*t[1][1]]],s=L(n(a)),u=[Math.sqrt(Math.max(0,s.values[0])),Math.sqrt(Math.max(0,s.values[1]))],l=o(s.vectors),c=[[(t[0][0]*l[0][0]+t[0][1]*l[1][0])/(u[0]||1),(t[0][0]*l[0][1]+t[0][1]*l[1][1])/(u[1]||1)],[(t[1][0]*l[0][0]+t[1][1]*l[1][0])/(u[0]||1),(t[1][0]*l[0][1]+t[1][1]*l[1][1])/(u[1]||1)]];return{U:n(c),S:n([[u[0],0],[0,u[1]]]),V:n(l)}}(e),simplify:e=>{if("string"!=typeof e)throw new Error("simplify() expects an expression string");return function(e){const t=e.replace(/\s+/g,"").match(/[a-zA-Z]+/),r=t?.[0]||"x";return j(U(e,r),r)}(e)},derivative:(e,t="x")=>{if("string"!=typeof e||"string"!=typeof t)throw new Error("derivative() expects expression and variable strings");return function(e,t){const r=U(e,t),n=new Map;for(const[e,t]of r.entries())0!==e&&n.set(e-1,(n.get(e-1)||0)+t*e);return j(n,t)}(e,t)},sin:e=>Math.sin(e),cos:e=>Math.cos(e),tan:e=>Math.tan(e),sind:e=>Math.sin(e*Math.PI/180),cosd:e=>Math.cos(e*Math.PI/180),tand:e=>Math.tan(e*Math.PI/180),asind:e=>180*Math.asin(e)/Math.PI,acosd:e=>180*Math.acos(e)/Math.PI,atand:e=>180*Math.atan(e)/Math.PI,atand2:(e,t)=>180*Math.atan2(e,t)/Math.PI,asin:e=>Math.asin(e),acos:e=>Math.acos(e),atan:e=>Math.atan(e),log:e=>{if(e<=0)throw new Error("log() domain error");return Math.log(e)},log10:e=>{if(e<=0)throw new Error("log10() domain error");return Math.log10(e)},exp:e=>Math.exp(e),random:()=>Math.random(),and:(e,t)=>Boolean(e&&t),or:(e,t)=>Boolean(e||t),not:e=>!e,"!":e=>!e,eq:(e,t)=>e===t,neq:(e,t)=>e!==t,notEqual:(e,t)=>e!==t,gt:(e,t)=>e>t,greaterThan:(e,t)=>e>t,lt:(e,t)=>e<t,lessThan:(e,t)=>e<t,gte:(e,t)=>e>=t,greaterThanOrEqual:(e,t)=>e>=t,lte:(e,t)=>e<=t,lessThanOrEqual:(e,t)=>e<=t,clamp:(e,t,r)=>{if(t>r)throw new Error("clamp(): min > max");return Math.min(Math.max(e,t),r)},if:(e,t,r)=>e?t:r,typeof:e=>typeof e,length:e=>{if("string"==typeof e||Array.isArray(e))return e.length;throw new Error("length() expects string or array")},sum:(...e)=>{if(!e.length)throw new Error("sum() requires at least one argument");return e.reduce((e,t)=>e+t,0)},prod:(...e)=>{if(!e.length)throw new Error("prod() requires at least one argument");return e.reduce((e,t)=>e*t,1)},mean:(...e)=>{if(!e.length)throw new Error("mean() requires at least one argument");return e.reduce((e,t)=>e+t,0)/e.length},median:(...e)=>{if(!e.length)throw new Error("median() requires at least one argument");const t=[...e].sort((e,t)=>e-t),r=Math.floor(t.length/2);return t.length%2?t[r]:(t[r-1]+t[r])/2},mode:(...e)=>{if(!e.length)throw new Error("mode() requires at least one argument");const t=new Map;e.forEach(e=>t.set(e,(t.get(e)||0)+1));let r=0,n=e[0];for(const[e,o]of t)o>r&&(r=o,n=e);return n},std:(...e)=>{if(e.length<2)throw new Error("std() requires at least two values");const t=e.reduce((e,t)=>e+t,0)/e.length;return Math.sqrt(e.reduce((e,r)=>e+(r-t)**2,0)/(e.length-1))},variance:(...e)=>{if(e.length<2)throw new Error("variance() requires at least two values");const t=e.reduce((e,t)=>e+t,0)/e.length;return e.reduce((e,r)=>e+(r-t)**2,0)/(e.length-1)},range:(...e)=>{if(!e.length)throw new Error("range() requires at least one argument");return Math.max(...e)-Math.min(...e)},gcd:(e,t)=>S(e,t),lcm:(e,t)=>0===e||0===t?0:Math.abs(e/S(e,t)*t),factorial:e=>{if(!Number.isInteger(e)||e<0)throw new Error("factorial() requires a non-negative integer");if(0===e||1===e)return 1;let t=1;for(let r=2;r<=e;r++)t*=r;return t},isPrime:e=>{if(!Number.isInteger(e)||e<2)return!1;if(2===e)return!0;if(e%2==0)return!1;for(let t=3;t*t<=e;t+=2)if(e%t===0)return!1;return!0},primeFactors:e=>{if(!Number.isInteger(e)||e<2)throw new Error("primeFactors() requires an integer >= 2");const t=[];let r=e;for(let e=2;e*e<=r;e++)for(;r%e===0;)t.push(e),r/=e;return r>1&&t.push(r),t},fibonacci:e=>{if(!Number.isInteger(e)||e<0)throw new Error("fibonacci() requires a non-negative integer");if(e<=1)return e;let t=0,r=1;for(let n=2;n<=e;n++){const e=t+r;t=r,r=e}return r},nCr:(e,t)=>{if(!Number.isInteger(e)||!Number.isInteger(t)||e<0||t<0)throw new Error("nCr() requires non-negative integers");if(t>e)return 0;if(0===t||t===e)return 1;t=Math.min(t,e-t);let r=1;for(let n=1;n<=t;n++)r=r*(e-t+n)/n;return r},nPr:(e,t)=>{if(!Number.isInteger(e)||!Number.isInteger(t)||e<0||t<0)throw new Error("nPr() requires non-negative integers");if(t>e)return 0;let r=1;for(let n=0;n<t;n++)r*=e-n;return r},gamma:e=>F(e),sinh:e=>Math.sinh(e),cosh:e=>Math.cosh(e),tanh:e=>Math.tanh(e),asinh:e=>Math.asinh(e),acosh:e=>Math.acosh(e),atanh:e=>Math.atanh(e),sec:e=>{const t=Math.cos(e);if(Math.abs(t)<1e-15)throw new Error("sec() undefined for this input");return 1/t},csc:e=>{const t=Math.sin(e);if(Math.abs(t)<1e-15)throw new Error("csc() undefined for this input");return 1/t},cot:e=>{const t=Math.sin(e);if(Math.abs(t)<1e-15)throw new Error("cot() undefined for this input");return Math.cos(e)/t},trunc:e=>Math.trunc(e),sign:e=>Math.sign(e),frac:e=>e-Math.trunc(e),split:(e,t)=>{if("string"!=typeof e)throw new Error("split() expects a string");return e.split(t)},join:(e,t)=>{if(!Array.isArray(e))throw new Error("join() expects an array");return e.join(t)},upper:e=>{if("string"!=typeof e)throw new Error("upper() expects a string");return e.toUpperCase()},lower:e=>{if("string"!=typeof e)throw new Error("lower() expects a string");return e.toLowerCase()},trim:e=>{if("string"!=typeof e)throw new Error("trim() expects a string");return e.trim()},replace:(e,t,r)=>{if("string"!=typeof e)throw new Error("replace() expects a string");return e.replace(t,r)},substring:(e,t,r)=>{if("string"!=typeof e)throw new Error("substring() expects a string");return e.substring(t,r)},acot:e=>0===e?Math.PI/2:Math.atan(1/e),asec:e=>{if(e<1&&e>-1)throw new Error("asec() domain error");return Math.acos(1/e)},acsc:e=>{if(e<1&&e>-1)throw new Error("acsc() domain error");return Math.asin(1/e)},acoth:e=>{if(Math.abs(e)<=1)throw new Error("acoth() domain error");return Math.atanh(1/e)},asech:e=>{if(e<=0||e>1)throw new Error("asech() domain error");return Math.acosh(1/e)},acsch:e=>{if(0===e)throw new Error("acsch() domain error");return Math.asinh(1/e)},quantile:(e,t)=>{if(!Array.isArray(e)||0===e.length)throw new Error("quantile() expects a non-empty array");if(t<0||t>1)throw new Error("quantile() p must be between 0 and 1");const r=[...e].sort((e,t)=>e-t),n=t*(r.length-1),o=Math.floor(n),i=Math.ceil(n);return o===i?r[o]:r[o]+(n-o)*(r[i]-r[o])},percentile:(e,t)=>{if(t<0||t>100)throw new Error("percentile() p must be between 0 and 100");return V.quantile(e,t/100)},covariance:(e,t)=>{if(!Array.isArray(e)||!Array.isArray(t)||e.length<2||e.length!==t.length)throw new Error("covariance() expects two arrays of equal length >= 2");const r=e.reduce((e,t)=>e+t,0)/e.length,n=t.reduce((e,t)=>e+t,0)/t.length;return e.reduce((e,o,i)=>e+(o-r)*(t[i]-n),0)/(e.length-1)},corr:(e,t)=>{const r=V.covariance(e,t),n=Math.sqrt(V.covariance(e,e)),o=Math.sqrt(V.covariance(t,t));if(0===n||0===o)throw new Error("corr() zero variance");return r/(n*o)},randomInt:(e,t)=>{if(!Number.isInteger(e)||!Number.isInteger(t))throw new Error("randomInt() expects integers");return Math.floor(Math.random()*(t-e+1))+e},randomNormal:(e,t)=>{if(t<=0)throw new Error("randomNormal() std must be > 0");let r=0,n=0;for(;0===r;)r=Math.random();for(;0===n;)n=Math.random();return e+t*Math.sqrt(-2*Math.log(r))*Math.cos(2*Math.PI*n)},erf:e=>{if(0===e)return 0;const t=1/(1+.3275911*Math.abs(e)),r=[.254829592,-.284496736,1.421413741,-1.453152027,1.061405429];let n=r[4]*t+r[3];n=n*t+r[2],n=n*t+r[1],n=n*t+r[0],n*=t;const o=1-n*Math.exp(-e*e);return e>=0?o:-o},lgamma:e=>{if(e<=0)throw new Error("lgamma() domain error (x > 0 required)");if(e<12){let t=e,r=0;for(;t<12;)r-=Math.log(t),t+=1;return r+V.lgamma(t)}const t=1/e,r=(1/12-t*t/360+t*t*t*t/1260)*t;return(e-.5)*Math.log(e)-e+.9189385332046727+r},beta:(e,t)=>{if(e<=0||t<=0)throw new Error("beta() domain error");return Math.exp(V.lgamma(e)+V.lgamma(t)-V.lgamma(e+t))},hypot:(...e)=>Math.hypot(...e),cbrt:e=>Math.cbrt(e),log2:e=>{if(e<=0)throw new Error("log2() domain error");return Math.log2(e)},log1p:e=>{if(e<=-1)throw new Error("log1p() domain error");return Math.log1p(e)},expm1:e=>Math.expm1(e),bitAnd:(e,t)=>{if(!Number.isInteger(e)||!Number.isInteger(t))throw new Error("bitAnd() expects integers");return e&t},bitOr:(e,t)=>{if(!Number.isInteger(e)||!Number.isInteger(t))throw new Error("bitOr() expects integers");return e|t},bitXor:(e,t)=>{if(!Number.isInteger(e)||!Number.isInteger(t))throw new Error("bitXor() expects integers");return e^t},bitNot:e=>{if(!Number.isInteger(e))throw new Error("bitNot() expects an integer");return~e}};function T(e){let t=0;const r=()=>e[t],n=()=>e[t++],o=()=>{const r=t>0?e[t-1]:null;return r&&void 0!==r.pos?r.pos:-1},i=()=>{const e=r();return e&&void 0!==e.pos?e.pos:-1},a=e=>{const t=o();return t>=0&&(e.pos=t),e},s=e=>{const t=i()>=0?i():o();throw new Error(`${e}${t>=0?` at position ${t}`:""}`)},u=(e,n)=>{const o=r();return!!o&&(o.type===e&&((void 0===n||o.value===n)&&(t++,!0)))},l=()=>{let e=null;if("Colon"!==r()?.type&&"Comma"!==r()?.type&&"ArrayEnd"!==r()?.type&&(e=E()),u("Colon",void 0)){let t=null;return"Comma"!==r()?.type&&"ArrayEnd"!==r()?.type&&(t=E()),{type:"SliceExpression",start:e,end:t}}return e};function c(){let e=function(){const e=n();e||s("Unexpected end of input");const t=t=>(void 0!==e.pos&&(t.pos=e.pos),t);switch(e.type){case"Number":case"BigInt":case"Boolean":case"String":return t({type:"Literal",value:e.value});case"ImaginaryLiteral":return t({type:"ImaginaryLiteral",value:e.value});case"NumberWithUnit":return t({type:"UnitLiteral",value:e.value,unit:e.unit});case"Identifier":case"Function":return t({type:"Identifier",name:e.name});case"Parenthesis":if("("===e.value){const e=E();return u("Parenthesis",")")||s("Expected ')'"),e}case"ArrayStart":{const e=[];let r=[];if(!u("ArrayEnd",void 0))for(;;)if(r.push(E()),!u("Comma",void 0))if(u("Semicolon",void 0))e.push(r),r=[];else{if(u("ArrayEnd",void 0)){e.push(r);break}s("Expected ',', ';', or ']'")}return e.length?1===e.length?t({type:"ArrayExpression",elements:e[0]}):t({type:"ArrayExpression",elements:e.map(e=>({type:"ArrayExpression",elements:e}))}):t({type:"ArrayExpression",elements:[]})}case"BlockStart":{const e=[];if(!u("BlockEnd",void 0)){do{const t=n();"Identifier"!==t.type&&"String"!==t.type&&s("Invalid object key"),u("Colon",void 0)||s("Expected ':' after key");const r=E();e.push({key:t.value,value:r})}while(u("Comma",void 0));u("BlockEnd",void 0)||s("Expected '}'")}return t({type:"ObjectExpression",properties:e})}}s(`Unexpected token: ${JSON.stringify(e.value||e.name||e.type)}`)}();for(;;){if(u("ArrayStart",void 0)){const t=[];if(!u("ArrayEnd",void 0)){do{t.push(l())}while(u("Comma",void 0));u("ArrayEnd",void 0)||s("Expected ']'")}e=a({type:"IndexExpression",object:e,selectors:t});continue}if(u("Dot",void 0)){const t=n();"Identifier"!==t.type&&s("Expected property after '.'"),e=a({type:"MemberExpression",object:e,property:{type:"Identifier",name:t.value},optional:!1});continue}if(u("Operator","?.")){const t=n();e=a({type:"MemberExpression",object:e,property:{type:"Identifier",name:t.value},optional:!0});continue}break}return e}function p(){if(u("UnaryOperator",void 0)){const r=e[t-1].value;return a({type:"UnaryExpression",operator:r,argument:p()})}return function(){let e=c();for(;"Parenthesis"===r()?.type&&"("===r()?.value;){n();const t=[];if("Parenthesis"!==r()?.type||")"!==r()?.value)do{if(u("Spread",void 0)){const e=E();t.push({type:"SpreadElement",argument:e})}else t.push(E())}while(u("Comma",void 0));u("Parenthesis",")")||s("Expected ')'"),e=a({type:"CallExpression",callee:e,arguments:t})}return e}()}function h(){const e=p();if(u("Operator","^")){const t=h();return a({type:"BinaryExpression",operator:"^",left:e,right:t})}return e}function f(){let r=h();for(;u("Operator","*")||u("Operator","/")||u("Operator","%");){const n=e[t-1].value,o=h();r=a({type:"BinaryExpression",operator:n,left:r,right:o})}return r}function m(){const o=function(){let r=f();for(;u("Operator","+")||u("Operator","-");){const n=e[t-1].value,o=f();r=a({type:"BinaryExpression",operator:n,left:r,right:o})}return r}(),i=r();if("Keyword"===i?.type&&["to","in"].includes(i.value)){n();const e=n();return e&&"Unit"===e.type||s(`Expected unit after '${i.value}'`),a({type:"UnitConversion",from:o,to:e.value})}return o}function g(){let r=m();for(;u("Operator",">")||u("Operator","<")||u("Operator",">=")||u("Operator","<=")||u("Operator","==");){const n=e[t-1].value,o=m();r=a({type:"BinaryExpression",operator:n,left:r,right:o})}return r}function y(){let r=g();for(;u("Operator","&&")||u("Operator","||");){const n=e[t-1].value,o=g();r=a({type:"LogicalExpression",operator:n,left:r,right:o})}return r}function d(){let e=y();for(;u("Operator","??");){const t=y();e=a({type:"LogicalExpression",operator:"??",left:e,right:t})}return e}function w(){const e=d();if(u("Ternary","?")){const t=E();u("Ternary",":")||s("Expected ':' in ternary");const r=E();return a({type:"ConditionalExpression",test:e,consequent:t,alternate:r})}if(u("Colon",void 0)){const t=d();return a({type:"RangeExpression",start:e,end:t})}return e}function b(){const e=function(){let e=w();for(;u("Operator","|>");){const t=w();e=a({type:"PipelineExpression",left:e,right:t})}return e}();if(u("Operator","->")){let t;"Identifier"===e.type?t=[e.name]:"ArrayExpression"===e.type?t=e.elements.map(e=>("Identifier"!==e.type&&s("Lambda parameter must be an identifier"),e.name)):s("Invalid lambda parameter");const r=b();return a({type:"ArrowFunctionExpression",params:t,body:r})}return e}function v(){const r=b();if(u("Operator","=")||u("Operator","+=")||u("Operator","-=")||u("Operator","*=")||u("Operator","/=")){const n=e[t-1].value;if("CallExpression"===r.type){"Identifier"===r.callee?.type&&r.arguments.every(e=>"Identifier"===e.type)||s("Invalid function definition");const e=v();return a({type:"FunctionAssignmentExpression",operator:n,left:{type:"Identifier",name:r.callee.name},params:r.arguments.map(e=>e.name),right:e})}"Identifier"!==r.type&&"MemberExpression"!==r.type&&"IndexExpression"!==r.type&&s("Invalid assignment target");const o=v();return a({type:"AssignmentExpression",operator:n,left:r,right:o})}return r}function E(){return v()}const x=E();if(t<e.length){const e=r(),t=e&&void 0!==e.pos?` at position ${e.pos}`:"";throw new Error(`Unexpected token "${e?JSON.stringify(e.value||e.name||e.type):"?"}"${t}`)}return x}const Z=e=>e&&"object"==typeof e&&"re"in e&&"im"in e,H=e=>c(e)?p(e):"number"!=typeof e||Number.isInteger(e)?String(e):Number(e.toFixed(14)).toString(),R=t=>{return s(t)?s(r=t)?1===r.d?String(r.n):`${r.n}/${r.d}`:String(r):c(t)?p(t):Z(t)?(e=>{if(!Z(e))return e;const t=e.re,r=Math.abs(e.im),n=e.im<0?"-":"+";return 0===t?1===e.im?"i":-1===e.im?"-i":`${e.im}i`:`${t} ${n} ${1===r?"i":`${r}i`}`})(t):(e=>e&&"object"==typeof e&&"value"in e&&"unit"in e)(t)?`${t.value} ${t.unit}`:e(t)?i(t):(e=>Array.isArray(e)&&e.length>0&&e.every(Array.isArray))(t)?t.map(e=>e.map(H).join("\t")).join("\n"):Array.isArray(t)?JSON.stringify(t):t&&"object"==typeof t?i(t):t;var r};class W{constructor(e){this._expr=e,this._rawResult=void 0}evaluate(e,t={}){return this._rawResult=this._expr._evaluateRaw(e,{...t,ans:this._rawResult}),this}setVariable(e,t){return this._expr.setVariable(e,t),this}compile(e){return this._expr.compile(e)}done(){return R(this._rawResult)}}return class{constructor(){this.math=g,this.units=function(e={}){let t={...e};function r(e){e=e.toLowerCase();for(const r in t)for(const n in t[r]){const o=t[r][n];if(n.toLowerCase()===e||o.unit?.toLowerCase()===e||o.symbol?.toLowerCase()===e)return{type:r,key:n,data:o}}return null}return{getUnits:()=>t,setUnits:e=>{t={...e}},updateType:(e,r)=>{t[e]={...t[e],...r}},addUnit:(e,r,n)=>{t[e]||(t[e]={}),t[e][r]=n},compute(e,t,r){const n=e=>e&&"object"==typeof e&&"value"in e&&"unit"in e,o=(t,r)=>{switch(e){case"+":return t+r;case"-":return t-r;case"*":return t*r;case"/":return t/r;case"%":return t%r;case"^":return Math.pow(t,r)}};if(n(t)&&n(r)){const e=this.findUnit(r.unit),n=this.findUnit(t.unit);if(!e||!n||e.type!==n.type)throw new Error("Cannot operate on different unit types");const i=r.value*(e.data.value/n.data.value);return{value:o(t.value,i),unit:t.unit}}if(n(t)&&!n(r))return{value:o(t.value,r),unit:t.unit};if(!n(t)&&n(r)){return{value:o(t,r.value),unit:r.unit}}return o(t,r)},convert:function(e,n,o){const i=r(n),a=r(o);if(!i)throw new Error(`Unknown unit: ${n}`);if(!a)throw new Error(`Unknown unit: ${o}`);if(i.type!==a.type)throw new Error(`Cannot convert ${n} to ${o} (${a.data.unit||a.key}). ${i.data.unit||i.key} conversion units like ${Object.keys(t[i.type]).join(", ")}`);return{value:e*(i.data.value/a.data.value),unit:a.key}},getAllUnitsFlat:function(){const e=new Set;for(const r in t)for(const n in t[r]){const o=t[r][n],i=n.toLowerCase();if(e.add(i),o.unit){const t=o.unit.toLowerCase();t!==i&&1===t.split(/\s+/).length&&e.add(t)}if(o.symbol){const t=o.symbol.toLowerCase();o.unit&&t===o.unit.toLowerCase()||e.add(t)}}return Array.from(e)},findUnit:r}}(y),this.functions=b(V),this.variables=w(),this._cache=new Map,this.variables.set("pi",Math.PI),this.variables.set("e",Math.E),this.variables.set("PHI",(1+Math.sqrt(5))/2),this.variables.set("TAU",2*Math.PI),this.variables.set("INFINITY",1/0),this.variables.set("NaN",NaN),this.addFunction("parse",e=>{if("string"!=typeof e)throw new Error("parse() expects an expression string");return e}),this.addFunction("leafCount",e=>{let t=e;if("string"==typeof e)try{t=this.parse(e).ast}catch{return(e=>{const t=e.replace(/(^|[{,]\s*)[a-zA-Z_][a-zA-Z0-9_]*\s*:/g,"$1").match(/\d+(\.\d+)?(e[+-]?\d+)?n?|[a-zA-Z_][a-zA-Z0-9_]*/gi);return t?t.length:0})(e)}const r=e=>{if(!e||"object"!=typeof e)return 0;switch(e.type){case"Literal":case"ImaginaryLiteral":case"UnitLiteral":case"Identifier":return 1;default:return Object.values(e).reduce((e,t)=>Array.isArray(t)?e+t.reduce((e,t)=>e+r(t),0):e+r(t),0)}};return r(t)}),this.addFunction("matrix",e=>n(e)),this.addFunction("sparse",e=>n(e)),this.addFunction("rationalize",(e,t=!1)=>{if("string"!=typeof e)throw new Error("rationalize() expects an expression string");const r=e.replace(/\s+/g,"").replace(/(\d)([a-zA-Z(])/g,"$1*$2").replace(/([a-zA-Z)])(\d)/g,"$1*$2"),n=e=>JSON.stringify(Object.entries(e).sort(([e],[t])=>e.localeCompare(t))),o=e=>Object.fromEntries(JSON.parse(e)),i=e=>new Map([[n({}),e]]),a=e=>new Map([...e.entries()].filter(([,e])=>0!==e)),s=(e,t,r=1)=>{const n=new Map(e);for(const[e,o]of t.entries())n.set(e,(n.get(e)||0)+r*o);return a(n)},u=(e,t)=>{const r=new Map;for(const[i,a]of e.entries()){const e=o(i);for(const[i,s]of t.entries()){const t=o(i),u={...e};for(const[e,r]of Object.entries(t))u[e]=(u[e]||0)+r;const l=n(u);r.set(l,(r.get(l)||0)+a*s)}}return a(r)},l=(e,t)=>{let r=i(1);for(let n=0;n<t;n++)r=u(r,e);return r},c=(e,t=i(1))=>({num:e,den:t}),p=(e,t,r=1)=>c(s(u(e.num,t.den),u(t.num,e.den),r),u(e.den,t.den)),h=e=>{switch(e.type){case"Literal":return c(i(e.value));case"Identifier":return c((a=e.name,new Map([[n({[a]:1}),1]])));case"UnaryExpression":if("-"===e.operator)return o=h(e.argument),c(s(new Map,o.num,-1),o.den);throw new Error("Unsupported unary operator");case"BinaryExpression":{const n=h(e.left),o=h(e.right);switch(e.operator){case"+":return p(n,o);case"-":return p(n,o,-1);case"*":return r=o,c(u((t=n).num,r.num),u(t.den,r.den));case"/":return((e,t)=>c(u(e.num,t.den),u(e.den,t.num)))(n,o);case"^":if("Literal"!==e.right.type||!Number.isInteger(e.right.value)||e.right.value<0)throw new Error("Unsupported exponent");return c(l(n.num,e.right.value),l(n.den,e.right.value));default:throw new Error("Unsupported operator in rationalize()")}}default:throw new Error("Unsupported expression in rationalize()")}var t,r,o,a},f=e=>{const t=[...e.entries()].filter(([,e])=>0!==e).sort(([e],[t])=>{const r=o(e),n=o(t),i=Object.keys(r).sort()[0]||"",a=Object.keys(n).sort()[0]||"";if(i!==a)return i.localeCompare(a);const s=Object.values(r).reduce((e,t)=>e+t,0);return Object.values(n).reduce((e,t)=>e+t,0)-s});return t.length?t.map(([e,t],r)=>{const n=o(e),i=Math.abs(t);let a=Object.entries(n).map(([e,t])=>1===t?e:`${e} ^ ${t}`).join(" * ");return a?1!==i&&(a=`${i} * ${a}`):a=`${i}`,0===r?t<0?`- ${a}`.replace("- ","-"):a:t<0?`- ${a}`:`+ ${a}`}).join(" "):"0"},m=this.parse(r).ast,g=h(m),y=f(g.num),d=f(g.den),w=new Set;for(const e of[g.num,g.den])for(const t of e.keys())for(const e of Object.keys(o(t)))w.add(e);return t?{numerator:y,denominator:d,coefficients:[],variables:[...w].sort(),expression:`(${y}) / (${d})`}:`(${y}) / (${d})`}),this.addFunction("map",(e,t)=>{if(!Array.isArray(e))throw new Error("map() expects an array");const r="string"==typeof t?this.functions.get(t):t;if("function"!=typeof r)throw new Error("map() requires a function or function name");return e.map(e=>r(e))}),this.addFunction("filter",(e,t)=>{if(!Array.isArray(e))throw new Error("filter() expects an array");const r="string"==typeof t?this.functions.get(t):t;if("function"!=typeof r)throw new Error("filter() requires a function or function name");return e.filter(e=>r(e))}),this.addFunction("integral",(e,t,r)=>{if("string"!=typeof e)throw new Error("integral() expects an expression string");const n=this.compile(e),o=(r-t)/100;let i=n({x:t})+n({x:r});for(let e=1;e<100;e++){const r=n({x:t+e*o});i+=e%2==0?2*r:4*r}return o/3*i}),this.addFunction("sigma",(e,t,r,n)=>{if("string"!=typeof n)throw new Error("sigma() expects an expression string");const o=this.compile(n);let i=0;for(let n=t;n<=r;n++)i+=o({[e]:n});return i}),this.addFunction("pi",(e,t,r,n)=>{if("string"!=typeof n)throw new Error("pi() expects an expression string");const o=this.compile(n);let i=1;for(let n=t;n<=r;n++)i*=o({[e]:n});return i}),this.addFunction("substitute",(e,t,r)=>{if("string"!=typeof e)throw new Error("substitute() expects an expression string");return this.compile(e)({[t]:r})}),this.addFunction("limit",(e,t,r,n)=>{if("string"!=typeof e)throw new Error("limit() expects an expression string");const o=this.compile(e),i=[.1,.01,.001,1e-4,1e-5,1e-6,1e-7,1e-8,1e-9,1e-10];let a=NaN;for(const e of i){let i;i="right"===n?r+e:"left"===n?r-e:r+e;const s=o({[t]:i});isFinite(s)&&(a=s)}return a}),this.addFunction("expand",e=>{if("string"!=typeof e)throw new Error("expand() expects an expression string");const t=e.match(/[a-zA-Z_][a-zA-Z0-9_]*/);if(!t)throw new Error("expand() could not identify variable");const r=t[0],n=e.replace(/\s+/g,"").replace(/\\/g,"\\\\").replace(/"/g,'\\"'),o=e=>{return this.evaluate(`substitute("${t=n,t.replace(/(\d)([a-zA-Z_])/g,"$1*$2")}", "${r}", ${e})`);var t},i=[];for(let e=0;e<=10;e++)i.push(o(e));let a=0,s=[...i];for(let e=0;e<=10;e++){Math.abs(s[0])>1e-10&&(a=e);const t=[];for(let e=0;e<s.length-1;e++)t.push(s[e+1]-s[e]);if(s=t,s.every(e=>Math.abs(e)<1e-10))break}const u=a+1,l=Array.from({length:u},(e,t)=>{const r=Array.from({length:u},(e,r)=>t**r);return r.push(i[t]),r});for(let e=0;e<u;e++){let t=e;for(;t<u&&Math.abs(l[t][e])<1e-12;)t++;if(t===u)continue;[l[e],l[t]]=[l[t],l[e]];const r=l[e][e];for(let t=e;t<=u;t++)l[e][t]/=r;for(let t=0;t<u;t++)if(t!==e){const r=l[t][e];for(let n=e;n<=u;n++)l[t][n]-=r*l[e][n]}}const c=l.map(e=>Math.abs(e[u])<1e-10?0:e[u]),p=[];for(let e=a;e>=0;e--){const t=c[e];if(Math.abs(t)<1e-10)continue;const n=0===p.length?t<0?"-":"":t<0?" - ":" + ",o=Math.abs(t),i=0===e?`${o}`:1===o?"":`${o}`,a=0===e?"":1===e?r:`${r}^${e}`;p.push(`${n}${i}${a}`)}return p.join("")||"0"}),this.addFunction("factor",e=>{if("string"!=typeof e)throw new Error("factor() expects an expression string");const t=e.replace(/\s+/g,""),r=t.match(/[a-zA-Z_][a-zA-Z0-9_]*/);if(!r)throw new Error("factor() could not identify variable");const n=r[0],o=t.replace(/\\/g,"\\\\").replace(/"/g,'\\"').replace(/(\d)([a-zA-Z_])/g,"$1*$2");const i=[];for(let e=0;e<=6;e++)i.push(this.evaluate(`substitute("${o}", "${n}", ${e})`));let a=i.slice(),s=0;for(let e=0;e<=6;e++){if(a.every(e=>Math.abs(e)<1e-10)){s=Math.max(0,e-1);break}if(e<6){const e=[];for(let t=0;t<a.length-1;t++)e.push(a[t+1]-a[t]);a=e}}if(0===s)return`(${e})`;const u=s+1,l=Array.from({length:u},(e,t)=>{const r=Array.from({length:u},(e,r)=>t**r);return r.push(i[t]),r});for(let e=0;e<u;e++){let t=e;for(;t<u&&Math.abs(l[t][e])<1e-12;)t++;if(t===u)continue;[l[e],l[t]]=[l[t],l[e]];const r=l[e][e];for(let t=e;t<=u;t++)l[e][t]/=r;for(let t=0;t<u;t++)if(t!==e){const r=l[t][e];for(let n=e;n<=u;n++)l[t][n]-=r*l[e][n]}}const c=l.map(e=>Math.abs(e[u])<1e-10?0:e[u]);if(s>=1&&s<=3){const e=this.functions.get("polynomialRoot")(...c),t=Array.isArray(e)?e:[e],r=[...new Set(t.map(e=>Number.isInteger(e)?e:Math.round(1e10*e)/1e10))].sort((e,t)=>e-t);if(r.length===s){const e=c[s];return`${Math.abs(e-1)>1e-10?Math.abs(e+1)<1e-10?"-":`${e}`:""}${r.map(e=>Math.abs(e)<1e-10?n:e>0?`(${n} - ${e})`:`(${n} + ${Math.abs(e)})`).join("")}`}}return`(${e})`}),this.addFunction("solve",(e,t)=>{if("string"!=typeof e)throw new Error("solve() expects an equation string");const r=e.split("=");if(2!==r.length)throw new Error("solve() expects an equation with =");const n=`(${r[0].trim()}) - (${r[1].trim()})`.replace(/\s+/g,""),o=n.match(/[a-zA-Z_][a-zA-Z0-9_]*/),i=t||(o?o[0]:"x"),a=n.replace(/\\/g,"\\\\").replace(/"/g,'\\"').replace(/(\d)([a-zA-Z_])/g,"$1*$2");const s=[];for(let e=0;e<=6;e++)s.push(this.evaluate(`substitute("${a}", "${i}", ${e})`));let u=s.slice(),l=0;for(let e=0;e<=6;e++){if(u.every(e=>Math.abs(e)<1e-10)){l=Math.max(0,e-1);break}if(e<6){const e=[];for(let t=0;t<u.length-1;t++)e.push(u[t+1]-u[t]);u=e}}if(0===l)throw new Error("No solution found");const c=l+1,p=Array.from({length:c},(e,t)=>{const r=Array.from({length:c},(e,r)=>t**r);return r.push(s[t]),r});for(let e=0;e<c;e++){let t=e;for(;t<c&&Math.abs(p[t][e])<1e-12;)t++;if(t===c)continue;[p[e],p[t]]=[p[t],p[e]];const r=p[e][e];for(let t=e;t<=c;t++)p[e][t]/=r;for(let t=0;t<c;t++)if(t!==e){const r=p[t][e];for(let n=e;n<=c;n++)p[t][n]-=r*p[e][n]}}const h=p.map(e=>Math.abs(e[c])<1e-10?0:e[c]);if(l>=1&&l<=3){const e=this.functions.get("polynomialRoot")(...h);return(Array.isArray(e)?e:[e]).sort((e,t)=>e-t)}throw new Error("solve() currently supports degree up to 3")})}setVariable(e,t){this.variables.set(e,t)}getVariable(e){return this.variables.get(e)}addFunction(e,t){this.functions.register(e,t)}_createContext(){return f({functions:this.functions,variables:this.variables,units:this.units,evaluate:this.evaluate.bind(this)})}tokenize(e){if("string"!=typeof e)throw new Error("Expression must be a string");return function(e,t={}){const r=[];let n="",o="";const i=["+","-","*","/","%","^","=",">","<","!","&","|"],a=["==",">=","<=","&&","||","+=","-=","*=","/=","%=","?.","??","|>","->"],s=["to","in"],u=t.units?.getAllUnitsFlat?.()||[],l=e=>!e||"Operator"===e.type||"UnaryOperator"===e.type||"Parenthesis"===e.type&&")"!==e.value||"ArrayStart"===e.type||"Semicolon"===e.type||"Comma"===e.type||"Ternary"===e.type,c=(t,o)=>{if(!n)return;if(/^(true|false)$/i.test(n))return r.push({type:"Boolean",value:"true"===n.toLowerCase()}),void(n="");if(s.includes(n))return r.push({type:"Keyword",value:n,pos:o}),void(n="");if(/^\d+n$/.test(n))return r.push({type:"BigInt",value:BigInt(n.slice(0,-1)),pos:o}),void(n="");if(/^0x[0-9a-fA-F]+$/.test(n))return r.push({type:"Number",value:parseInt(n,16),pos:o}),void(n="");if(/^0b[01]+$/.test(n))return r.push({type:"Number",value:parseInt(n,2),pos:o}),void(n="");if(/^[+-]?(\d+(\.\d+)?|\.\d+)(e[+-]?\d+)?$/i.test(n))return r.push({type:"Number",value:parseFloat(n),pos:o}),void(n="");if(/^[+-]?(\d+(\.\d+)?|\.\d+)(e[+-]?\d+)?i$/i.test(n))return r.push({type:"ImaginaryLiteral",value:parseFloat(n.slice(0,-1)),pos:o}),void(n="");if(/^[+-]?i$/i.test(n)){const e="-"===n[0]?-1:1;return r.push({type:"ImaginaryLiteral",value:e,pos:o}),void(n="")}const i=n.match(/^([+-]?\d+(\.\d+)?)([a-zA-Z]+)$/);if(i){const e=parseFloat(i[1]),t=i[3];return r.push({type:u.includes(t)?"NumberWithUnit":"UnknownUnit",value:e,unit:t,pos:o}),void(n="")}if(u.includes(n)){const{prevWord:i}=function(e,t){const r=e.match(/[a-z0-9]+/gi)||[],n=e[t]||null,o=t>0?e[t-1]:null;let i=t;for(;i>0&&/[a-z0-9]/i.test(e[i-1]);)i--;let a=t;for(;a<e.length&&/[a-z0-9]/i.test(e[a]);)a++;const s=e.substring(i,a),u=r.indexOf(s);return{prevWord:u>0?r[u-1]:null,prevChar:o,currentWord:s,currentChar:n,nextWord:-1!==u&&u<r.length-1?r[u+1]:null}}(e,o);if("("!==t&&i&&(!isNaN(parseFloat(i))||"to"===i||"in"===i))return r.push({type:"Unit",value:n,pos:o}),void(n="")}if(/^[a-zA-Z_][a-zA-Z0-9_]*$/.test(n))return"("===t?r.push({type:"Function",name:n,pos:o}):r.push({type:"Identifier",name:n,pos:o}),void(n="");throw new Error(`Invalid token "${n}" at index ${o}`)};for(let t=0;t<e.length;t++){const s=e[t],u=e[t+1];if("/"===s&&"/"===u){for(;t<e.length&&"\n"!==e[t];)t++;continue}if("/"===s&&"*"===u){for(t+=2;t<e.length&&("*"!==e[t]||"/"!==e[t+1]);)t++;t++;continue}if("\"'".includes(s)){o?o===s?(n+=s,r.push({type:"String",value:n.slice(1,-1),pos:t}),n="",o=""):n+=s:(o=s,n+=s);continue}if(o){n+="\\"===s?s+e[++t]:s;continue}const p=s+u;if(a.includes(p))c(s,t),r.push({type:"Operator",value:p,pos:t}),t++;else if("?"!==s){if(":"===s){c(s,t);const e=r[r.length-1];e&&"Ternary"===e.type?r.push({type:"Ternary",value:":"}):r.push({type:"Colon"});continue}if("."!==s||"."!==u||"."!==e[t+2])if("."===s&&/\d/.test(n)&&/\d/.test(u))n+=s;else if("."!==s){if(i.includes(s)){c(s,t);const e=r[r.length-1];"-"!==s&&"!"!==s||!l(e)?r.push({type:"Operator",value:s,pos:t}):r.push({type:"UnaryOperator",value:s,pos:t});continue}"()".includes(s)?(c(s,t),r.push({type:"Parenthesis",value:s,pos:t})):"["!==s?"]"!==s?"{"!==s?"}"!==s?","!==s?";"!==s?" "!==s?(n+=s,t===e.length-1&&c(null,t)):c(u,t):(c(s,t),r.push({type:"Semicolon",pos:t})):(c(s,t),r.push({type:"Comma",pos:t})):(c(s,t),r.push({type:"BlockEnd",pos:t})):(c(s,t),r.push({type:"BlockStart",pos:t})):(c(s,t),r.push({type:"ArrayEnd",pos:t})):(c(s,t),r.push({type:"ArrayStart",pos:t}))}else c(s,t),r.push({type:"Dot",pos:t});else c(s,t),r.push({type:"Spread",pos:t}),t+=2}else r.push({type:"Ternary",value:"?"})}if(o)throw new Error("Unclosed string literal");const p=[];for(let e=0;e<r.length;e++){const t=r[e],n=r[e+1];"Number"!==t?.type||"Unit"!==n?.type?p.push(t):(p.push({type:"NumberWithUnit",value:t.value,unit:n.value,pos:t.pos}),e++)}const h=[];for(let e=0;e<p.length;e++){const t=p[e],r=p[e+1];h.push(t),t&&r&&(["Number","Identifier"].includes(t.type)||"Parenthesis"===t.type&&")"===t.value||"ArrayEnd"===t.type)&&(["Identifier","Function"].includes(r.type)||"Parenthesis"===r.type&&"("===r.value)&&h.push({type:"Operator",value:"*",implicit:!0})}return h}(e,this._createContext())}parse(e){const t=this.tokenize(e);return{tokens:t,ast:T(t)}}evaluate(e,t={}){return R(this._evaluateRaw(e,t))}_evaluateRaw(e,t={}){const{ast:r}=this.parse(e),n=this._createContext();return h(r,Object.keys(t).length>0?n.withScope(t):n)}compile(e){if(this._cache.has(e))return this._cache.get(e);const{ast:t}=this.parse(e),r=(e={})=>{const r=this._createContext().withScope(e);return R(h(t,r))};return this._cache.set(e,r),r}clearCache(){this._cache.clear()}exportState(){return{variables:this.variables.all(),functions:this.functions.getAllFunctionsName(),units:this.units.getUnits()}}importState(e){if(e.variables&&this.variables.merge(e.variables),e.units&&this.units.setUnits(e.units),e.functions)for(const t of e.functions)this.functions.has(t);return this}chain(){return new W(this)}}});
|
|
3
3
|
|