exprify 1.0.4 → 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/HISTORY.md +49 -0
- package/README.md +109 -182
- package/SECURITY.md +18 -0
- package/bin/cli.mjs +234 -0
- package/dist/exprify.cjs.cjs +3558 -1220
- package/dist/exprify.cjs.cjs.map +1 -1
- package/dist/exprify.esm.js +3558 -1220
- package/dist/exprify.esm.js.map +1 -1
- package/dist/exprify.js +3560 -1222
- package/dist/exprify.js.map +1 -1
- package/dist/exprify.min.js +2 -2
- package/dist/exprify.min.js.map +1 -1
- package/package.json +44 -17
- package/src/core/context.js +35 -27
- package/src/core/exprify.js +880 -0
- package/src/function/executor.js +29 -20
- package/src/function/internal.js +1150 -153
- package/src/function/registry.js +23 -16
- package/src/index.js +1 -1
- package/src/math/bignumber.js +31 -0
- package/src/math/fraction.js +112 -0
- package/src/math/operations.js +38 -24
- package/src/parser/astBuild.js +276 -214
- package/src/parser/evaluator.js +431 -171
- package/src/parser/tokenizer.js +179 -146
- package/src/utils/decimal.js +264 -0
- package/src/utils/globalUnits.js +43 -35
- package/src/utils/matrix.js +14 -14
- package/src/utils/store.js +69 -47
- package/src/variables/store.js +18 -15
- package/src/core/Exprify.js +0 -369
|
@@ -0,0 +1,264 @@
|
|
|
1
|
+
const MAX_SAFE_DP = 100;
|
|
2
|
+
|
|
3
|
+
export class ExprDecimal {
|
|
4
|
+
static DP = 20;
|
|
5
|
+
|
|
6
|
+
#sign;
|
|
7
|
+
#int;
|
|
8
|
+
#dp;
|
|
9
|
+
|
|
10
|
+
constructor(value) {
|
|
11
|
+
if (value instanceof ExprDecimal) {
|
|
12
|
+
this.#sign = value.#sign;
|
|
13
|
+
this.#int = value.#int;
|
|
14
|
+
this.#dp = value.#dp;
|
|
15
|
+
return;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
if (typeof value === 'bigint') {
|
|
19
|
+
this.#sign = value >= 0n ? 1 : -1;
|
|
20
|
+
this.#int = value >= 0n ? value : -value;
|
|
21
|
+
this.#dp = 0;
|
|
22
|
+
return;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
if (typeof value === 'number') {
|
|
26
|
+
if (!Number.isFinite(value)) {
|
|
27
|
+
throw new Error(`Cannot create ExprDecimal from ${value}`);
|
|
28
|
+
}
|
|
29
|
+
value = String(value);
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
if (typeof value !== 'string') {
|
|
33
|
+
throw new Error('ExprDecimal expects a number, string, bigint, or ExprDecimal');
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
let s = value.trim();
|
|
37
|
+
if (s === '') {
|
|
38
|
+
throw new Error('Cannot create ExprDecimal from empty string');
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
this.#sign = 1;
|
|
42
|
+
if (s[0] === '-') {
|
|
43
|
+
this.#sign = -1;
|
|
44
|
+
s = s.slice(1);
|
|
45
|
+
} else if (s[0] === '+') {
|
|
46
|
+
s = s.slice(1);
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
let exp = 0;
|
|
50
|
+
const eIdx = s.search(/[eE]/);
|
|
51
|
+
if (eIdx !== -1) {
|
|
52
|
+
exp = parseInt(s.slice(eIdx + 1), 10);
|
|
53
|
+
s = s.slice(0, eIdx);
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
const dotIdx = s.indexOf('.');
|
|
57
|
+
if (dotIdx === -1) {
|
|
58
|
+
this.#int = BigInt(s || '0');
|
|
59
|
+
this.#dp = 0;
|
|
60
|
+
} else {
|
|
61
|
+
const intPart = s.slice(0, dotIdx) || '0';
|
|
62
|
+
const fracPart = s.slice(dotIdx + 1);
|
|
63
|
+
const combined = intPart + fracPart;
|
|
64
|
+
this.#int = BigInt(combined || '0');
|
|
65
|
+
this.#dp = fracPart.length;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
this.#dp -= exp;
|
|
69
|
+
if (this.#dp < 0) {
|
|
70
|
+
this.#int *= 10n ** BigInt(-this.#dp);
|
|
71
|
+
this.#dp = 0;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
this.#normalize();
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
#normalize() {
|
|
78
|
+
while (this.#dp > 0 && this.#int % 10n === 0n) {
|
|
79
|
+
this.#int /= 10n;
|
|
80
|
+
this.#dp--;
|
|
81
|
+
}
|
|
82
|
+
if (this.#int === 0n) {
|
|
83
|
+
this.#sign = 1;
|
|
84
|
+
this.#dp = 0;
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
#align(other) {
|
|
89
|
+
if (this.#dp === other.#dp) {
|
|
90
|
+
return [this.#int * BigInt(this.#sign), other.#int * BigInt(other.#sign), this.#dp];
|
|
91
|
+
}
|
|
92
|
+
if (this.#dp < other.#dp) {
|
|
93
|
+
const factor = 10n ** BigInt(other.#dp - this.#dp);
|
|
94
|
+
return [this.#int * factor * BigInt(this.#sign), other.#int * BigInt(other.#sign), other.#dp];
|
|
95
|
+
}
|
|
96
|
+
const factor = 10n ** BigInt(this.#dp - other.#dp);
|
|
97
|
+
return [this.#int * BigInt(this.#sign), other.#int * factor * BigInt(other.#sign), this.#dp];
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
#fromParts(sign, int, dp) {
|
|
101
|
+
const d = new ExprDecimal(0);
|
|
102
|
+
d.#sign = sign;
|
|
103
|
+
d.#int = int < 0n ? -int : int;
|
|
104
|
+
if (int < 0n) {
|
|
105
|
+
d.#sign = -sign;
|
|
106
|
+
}
|
|
107
|
+
d.#dp = dp;
|
|
108
|
+
d.#normalize();
|
|
109
|
+
return d;
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
plus(other) {
|
|
113
|
+
other = other instanceof ExprDecimal ? other : new ExprDecimal(other);
|
|
114
|
+
const [a, b, dp] = this.#align(other);
|
|
115
|
+
return this.#fromParts(1, a + b, dp);
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
minus(other) {
|
|
119
|
+
other = other instanceof ExprDecimal ? other : new ExprDecimal(other);
|
|
120
|
+
const [a, b, dp] = this.#align(other);
|
|
121
|
+
return this.#fromParts(1, a - b, dp);
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
times(other) {
|
|
125
|
+
other = other instanceof ExprDecimal ? other : new ExprDecimal(other);
|
|
126
|
+
const int = this.#int * other.#int;
|
|
127
|
+
const dp = this.#dp + other.#dp;
|
|
128
|
+
return this.#fromParts(this.#sign * other.#sign, int, dp);
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
div(other) {
|
|
132
|
+
other = other instanceof ExprDecimal ? other : new ExprDecimal(other);
|
|
133
|
+
if (other.#int === 0n) {
|
|
134
|
+
throw new Error('Division by zero');
|
|
135
|
+
}
|
|
136
|
+
const targetDp = Math.min(ExprDecimal.DP, MAX_SAFE_DP);
|
|
137
|
+
const scale = 10n ** BigInt(targetDp + other.#dp);
|
|
138
|
+
const dividend = this.#int * scale;
|
|
139
|
+
const quotient = dividend / other.#int;
|
|
140
|
+
const sign = this.#sign * other.#sign;
|
|
141
|
+
if (quotient === 0n) {
|
|
142
|
+
return new ExprDecimal(0);
|
|
143
|
+
}
|
|
144
|
+
return this.#fromParts(sign, quotient, targetDp);
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
mod(other) {
|
|
148
|
+
other = other instanceof ExprDecimal ? other : new ExprDecimal(other);
|
|
149
|
+
const quotient = this.div(other);
|
|
150
|
+
const truncated = quotient.#fromParts(
|
|
151
|
+
quotient.#sign,
|
|
152
|
+
quotient.#int - (quotient.#int % 10n ** BigInt(quotient.#dp > 0 ? 1 : 0)),
|
|
153
|
+
0
|
|
154
|
+
);
|
|
155
|
+
return this.minus(truncated.times(other));
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
pow(other) {
|
|
159
|
+
other = other instanceof ExprDecimal ? other : new ExprDecimal(other);
|
|
160
|
+
if (other.#dp > 0 || other.#sign !== 1) {
|
|
161
|
+
throw new Error('ExprDecimal pow() supports non-negative integer exponents only');
|
|
162
|
+
}
|
|
163
|
+
const exp = Number(other.#int);
|
|
164
|
+
if (exp > 100) {
|
|
165
|
+
throw new Error('ExprDecimal pow() exponent too large');
|
|
166
|
+
}
|
|
167
|
+
let result = new ExprDecimal(1);
|
|
168
|
+
for (let i = 0; i < exp; i++) {
|
|
169
|
+
result = result.times(this);
|
|
170
|
+
}
|
|
171
|
+
return result;
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
negated() {
|
|
175
|
+
const d = new ExprDecimal(this);
|
|
176
|
+
d.#sign = -d.#sign;
|
|
177
|
+
if (d.#int === 0n) {
|
|
178
|
+
d.#sign = 1;
|
|
179
|
+
}
|
|
180
|
+
return d;
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
eq(other) {
|
|
184
|
+
other = other instanceof ExprDecimal ? other : new ExprDecimal(other);
|
|
185
|
+
const [a, b] = this.#align(other);
|
|
186
|
+
return a === b;
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
gt(other) {
|
|
190
|
+
other = other instanceof ExprDecimal ? other : new ExprDecimal(other);
|
|
191
|
+
const [a, b] = this.#align(other);
|
|
192
|
+
return a > b;
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
lt(other) {
|
|
196
|
+
other = other instanceof ExprDecimal ? other : new ExprDecimal(other);
|
|
197
|
+
const [a, b] = this.#align(other);
|
|
198
|
+
return a < b;
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
gte(other) {
|
|
202
|
+
return this.gt(other) || this.eq(other);
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
lte(other) {
|
|
206
|
+
return this.lt(other) || this.eq(other);
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
toString() {
|
|
210
|
+
let s = this.#int.toString();
|
|
211
|
+
const edp = this.#dp;
|
|
212
|
+
|
|
213
|
+
const toScientific = (intStr, exponent) => {
|
|
214
|
+
const coeffInt = intStr[0];
|
|
215
|
+
const coeffFrac = intStr.slice(1).replace(/0+$/, '');
|
|
216
|
+
let r = coeffInt;
|
|
217
|
+
if (coeffFrac) {
|
|
218
|
+
r += `.${coeffFrac}`;
|
|
219
|
+
}
|
|
220
|
+
r += 'e';
|
|
221
|
+
r += exponent >= 0 ? '+' : '';
|
|
222
|
+
r += exponent;
|
|
223
|
+
return this.#sign === -1 ? `-${r}` : r;
|
|
224
|
+
};
|
|
225
|
+
|
|
226
|
+
if (edp === 0) {
|
|
227
|
+
if (s.length > 15) {
|
|
228
|
+
return toScientific(s, s.length - 1);
|
|
229
|
+
}
|
|
230
|
+
return this.#sign === -1 ? `-${s}` : s;
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
while (s.length <= edp) {
|
|
234
|
+
s = `0${s}`;
|
|
235
|
+
}
|
|
236
|
+
const dotPos = s.length - edp;
|
|
237
|
+
const intPartRaw = s.slice(0, dotPos);
|
|
238
|
+
const intTrimmed = intPartRaw.replace(/^0+/, '') || '0';
|
|
239
|
+
const fracRaw = s.slice(dotPos);
|
|
240
|
+
|
|
241
|
+
if (intTrimmed.length > 15 || (intTrimmed === '0' && fracRaw.replace(/0+$/, '').length > 15)) {
|
|
242
|
+
const normalized = s.replace(/^0+/, '') || '0';
|
|
243
|
+
const leadZeros = s.length - normalized.length;
|
|
244
|
+
return toScientific(normalized, dotPos - leadZeros - 1);
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
const intPart = intPartRaw || '0';
|
|
248
|
+
const fracPart = fracRaw.replace(/0+$/, '');
|
|
249
|
+
if (fracPart === '') {
|
|
250
|
+
return this.#sign === -1 ? `-${intPart}` : intPart;
|
|
251
|
+
}
|
|
252
|
+
return `${this.#sign === -1 ? '-' : ''}${intPart}.${fracPart}`;
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
toNumber() {
|
|
256
|
+
return Number(this.toString());
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
static isDecimal(value) {
|
|
260
|
+
return value instanceof ExprDecimal;
|
|
261
|
+
}
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
export default ExprDecimal;
|
package/src/utils/globalUnits.js
CHANGED
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
export const globalUnits = {
|
|
2
|
-
// Length
|
|
3
2
|
length: {
|
|
4
3
|
m: { value: 1, unit: 'meter', symbol: 'm' },
|
|
5
4
|
cm: { value: 0.01, unit: 'centimeter', symbol: 'cm' },
|
|
@@ -11,7 +10,7 @@ export const globalUnits = {
|
|
|
11
10
|
em: { value: 0.000264583 * 16, unit: 'em', symbol: 'em', note: '1em = 16px by default' },
|
|
12
11
|
rem: { value: 0.000264583 * 16, unit: 'rem', symbol: 'rem', note: 'root em = 16px by default' },
|
|
13
12
|
pt: { value: 0.000352778, unit: 'point', symbol: 'pt', note: '1pt = 1/72 inch' },
|
|
14
|
-
|
|
13
|
+
pica: { value: 0.00423333, unit: 'pica', symbol: 'pc', note: '1pc = 12pt' },
|
|
15
14
|
inch: { value: 0.0254, unit: 'inch', symbol: 'in' },
|
|
16
15
|
ft: { value: 0.3048, unit: 'foot', symbol: 'ft' },
|
|
17
16
|
yd: { value: 0.9144, unit: 'yard', symbol: 'yd' },
|
|
@@ -22,7 +21,7 @@ export const globalUnits = {
|
|
|
22
21
|
fathom: { value: 1.8288, unit: 'fathom', symbol: 'fathom' },
|
|
23
22
|
au: { value: 1.496e11, unit: 'astronomical unit', symbol: 'AU' },
|
|
24
23
|
ly: { value: 9.4607e15, unit: 'light year', symbol: 'ly' },
|
|
25
|
-
pc: { value: 3.0857e16, unit: 'parsec', symbol: 'pc' }
|
|
24
|
+
pc: { value: 3.0857e16, unit: 'parsec', symbol: 'pc' },
|
|
26
25
|
},
|
|
27
26
|
|
|
28
27
|
// Weight / Mass
|
|
@@ -33,7 +32,7 @@ export const globalUnits = {
|
|
|
33
32
|
t: { value: 1000, unit: 'tonne', symbol: 't', note: 'metric ton' },
|
|
34
33
|
lb: { value: 0.453592, unit: 'pound', symbol: 'lb' },
|
|
35
34
|
oz: { value: 0.0283495, unit: 'ounce', symbol: 'oz' },
|
|
36
|
-
stone: { value: 6.35029, unit: 'stone', symbol: 'st', note: '1 stone = 14 lb' }
|
|
35
|
+
stone: { value: 6.35029, unit: 'stone', symbol: 'st', note: '1 stone = 14 lb' },
|
|
37
36
|
},
|
|
38
37
|
|
|
39
38
|
// Time
|
|
@@ -44,18 +43,18 @@ export const globalUnits = {
|
|
|
44
43
|
day: { value: 86400, unit: 'day', symbol: 'd' },
|
|
45
44
|
week: { value: 604800, unit: 'week', symbol: 'wk' },
|
|
46
45
|
month: { value: 2629800, unit: 'month', symbol: 'mo', note: 'average month = 30.44 days' },
|
|
47
|
-
year: { value: 31557600, unit: 'year', symbol: 'yr', note: 'average year = 365.25 days' }
|
|
46
|
+
year: { value: 31557600, unit: 'year', symbol: 'yr', note: 'average year = 365.25 days' },
|
|
48
47
|
},
|
|
49
48
|
|
|
50
49
|
// Voltage
|
|
51
50
|
voltage: {
|
|
52
|
-
V:
|
|
51
|
+
V: { value: 1, unit: 'volt', symbol: 'V' },
|
|
53
52
|
mV: { value: 0.001, unit: 'millivolt', symbol: 'mV' },
|
|
54
53
|
kV: { value: 1000, unit: 'kilovolt', symbol: 'kV' },
|
|
55
54
|
MV: { value: 1e6, unit: 'megavolt', symbol: 'MV' },
|
|
56
55
|
GV: { value: 1e9, unit: 'gigavolt', symbol: 'GV' },
|
|
57
56
|
statV: { value: 299.792458, unit: 'statvolt', symbol: 'statV', note: 'CGS unit' },
|
|
58
|
-
abV: { value: 1e-8, unit: 'abvolt', symbol: 'abV', note: 'CGS electromagnetic unit' }
|
|
57
|
+
abV: { value: 1e-8, unit: 'abvolt', symbol: 'abV', note: 'CGS electromagnetic unit' },
|
|
59
58
|
},
|
|
60
59
|
|
|
61
60
|
// Frequency
|
|
@@ -64,7 +63,7 @@ export const globalUnits = {
|
|
|
64
63
|
kHz: { value: 1e3, unit: 'kilohertz', symbol: 'kHz' },
|
|
65
64
|
MHz: { value: 1e6, unit: 'megahertz', symbol: 'MHz' },
|
|
66
65
|
GHz: { value: 1e9, unit: 'gigahertz', symbol: 'GHz' },
|
|
67
|
-
THz: { value: 1e12, unit: 'terahertz', symbol: 'THz' }
|
|
66
|
+
THz: { value: 1e12, unit: 'terahertz', symbol: 'THz' },
|
|
68
67
|
},
|
|
69
68
|
|
|
70
69
|
// Power
|
|
@@ -75,22 +74,32 @@ export const globalUnits = {
|
|
|
75
74
|
MW: { value: 1e6, unit: 'megawatt', symbol: 'MW' },
|
|
76
75
|
GW: { value: 1e9, unit: 'gigawatt', symbol: 'GW' },
|
|
77
76
|
HP: { value: 745.7, unit: 'horsepower', symbol: 'HP', note: 'mechanical HP = 745.7 W' },
|
|
78
|
-
|
|
79
|
-
|
|
77
|
+
'kcal/h': { value: 1.163, unit: 'kilocalorie per hour', symbol: 'kcal/h', note: '= 1.163 W' },
|
|
78
|
+
'BTU/h': { value: 0.29307107, unit: 'BTU per hour', symbol: 'BTU/h', note: '= 0.293 W' },
|
|
80
79
|
},
|
|
81
80
|
|
|
82
81
|
// Sound
|
|
83
82
|
sound: {
|
|
84
83
|
dB: { value: 1, unit: 'decibel', symbol: 'dB', note: 'logarithmic unit of sound intensity' },
|
|
85
|
-
dBA: {
|
|
86
|
-
|
|
84
|
+
dBA: {
|
|
85
|
+
value: 1,
|
|
86
|
+
unit: 'A-weighted decibel',
|
|
87
|
+
symbol: 'dBA',
|
|
88
|
+
note: 'Adjusted for human hearing',
|
|
89
|
+
},
|
|
90
|
+
dBC: {
|
|
91
|
+
value: 1,
|
|
92
|
+
unit: 'C-weighted decibel',
|
|
93
|
+
symbol: 'dBC',
|
|
94
|
+
note: 'Flat weighting for high-level sounds',
|
|
95
|
+
},
|
|
87
96
|
},
|
|
88
97
|
|
|
89
98
|
// Temperature
|
|
90
99
|
temperature: {
|
|
91
100
|
K: { value: 1, unit: 'kelvin', symbol: 'K' },
|
|
92
101
|
C: { value: 1, unit: 'Celsius', symbol: '°C', note: '°C → K: add 273.15' },
|
|
93
|
-
F: { value: 1, unit: 'Fahrenheit', symbol: '°F', note: '°F → K: (°F - 32) * 5/9 + 273.15' }
|
|
102
|
+
F: { value: 1, unit: 'Fahrenheit', symbol: '°F', note: '°F → K: (°F - 32) * 5/9 + 273.15' },
|
|
94
103
|
},
|
|
95
104
|
|
|
96
105
|
// Pressure
|
|
@@ -101,7 +110,7 @@ export const globalUnits = {
|
|
|
101
110
|
bar: { value: 1e5, unit: 'bar', symbol: 'bar' },
|
|
102
111
|
atm: { value: 101325, unit: 'atmosphere', symbol: 'atm' },
|
|
103
112
|
psi: { value: 6894.757, unit: 'pound per square inch', symbol: 'psi' },
|
|
104
|
-
mmHg:{ value: 133.322, unit: 'millimeter of mercury', symbol: 'mmHg' }
|
|
113
|
+
mmHg: { value: 133.322, unit: 'millimeter of mercury', symbol: 'mmHg' },
|
|
105
114
|
},
|
|
106
115
|
|
|
107
116
|
// Energy
|
|
@@ -109,9 +118,9 @@ export const globalUnits = {
|
|
|
109
118
|
J: { value: 1, unit: 'joule', symbol: 'J' },
|
|
110
119
|
kJ: { value: 1000, unit: 'kilojoule', symbol: 'kJ' },
|
|
111
120
|
cal: { value: 4.184, unit: 'calorie', symbol: 'cal' },
|
|
112
|
-
kcal:{ value: 4184, unit: 'kilocalorie', symbol: 'kcal' },
|
|
121
|
+
kcal: { value: 4184, unit: 'kilocalorie', symbol: 'kcal' },
|
|
113
122
|
eV: { value: 1.60218e-19, unit: 'electronvolt', symbol: 'eV' },
|
|
114
|
-
BTU: { value: 1055.06, unit: 'BTU', symbol: 'BTU' }
|
|
123
|
+
BTU: { value: 1055.06, unit: 'BTU', symbol: 'BTU' },
|
|
115
124
|
},
|
|
116
125
|
|
|
117
126
|
// Force
|
|
@@ -120,7 +129,7 @@ export const globalUnits = {
|
|
|
120
129
|
kN: { value: 1000, unit: 'kilonewton', symbol: 'kN' },
|
|
121
130
|
lbf: { value: 4.44822, unit: 'pound-force', symbol: 'lbf' },
|
|
122
131
|
kgf: { value: 9.80665, unit: 'kilogram-force', symbol: 'kgf' },
|
|
123
|
-
dyne:{ value: 1e-5, unit: 'dyne', symbol: 'dyn' }
|
|
132
|
+
dyne: { value: 1e-5, unit: 'dyne', symbol: 'dyn' },
|
|
124
133
|
},
|
|
125
134
|
|
|
126
135
|
// Area
|
|
@@ -129,9 +138,9 @@ export const globalUnits = {
|
|
|
129
138
|
cm2: { value: 0.0001, unit: 'square centimeter', symbol: 'cm²' },
|
|
130
139
|
km2: { value: 1e6, unit: 'square kilometer', symbol: 'km²' },
|
|
131
140
|
acre: { value: 4046.856, unit: 'acre', symbol: 'acre' },
|
|
132
|
-
hectare:{ value: 10000, unit: 'hectare', symbol: 'ha' },
|
|
141
|
+
hectare: { value: 10000, unit: 'hectare', symbol: 'ha' },
|
|
133
142
|
ft2: { value: 0.092903, unit: 'square foot', symbol: 'ft²' },
|
|
134
|
-
yd2: { value: 0.836127, unit: 'square yard', symbol: 'yd²' }
|
|
143
|
+
yd2: { value: 0.836127, unit: 'square yard', symbol: 'yd²' },
|
|
135
144
|
},
|
|
136
145
|
|
|
137
146
|
// Volume
|
|
@@ -139,9 +148,9 @@ export const globalUnits = {
|
|
|
139
148
|
m3: { value: 1, unit: 'cubic meter', symbol: 'm³' },
|
|
140
149
|
L: { value: 0.001, unit: 'liter', symbol: 'L' },
|
|
141
150
|
mL: { value: 1e-6, unit: 'milliliter', symbol: 'mL' },
|
|
142
|
-
gallon:{ value: 0.00378541, unit: 'US gallon', symbol: 'gal' },
|
|
151
|
+
gallon: { value: 0.00378541, unit: 'US gallon', symbol: 'gal' },
|
|
143
152
|
pint: { value: 0.000473176, unit: 'US pint', symbol: 'pt' },
|
|
144
|
-
floz: { value: 2.9574e-5, unit: 'US fluid ounce', symbol: 'fl oz' }
|
|
153
|
+
floz: { value: 2.9574e-5, unit: 'US fluid ounce', symbol: 'fl oz' },
|
|
145
154
|
},
|
|
146
155
|
|
|
147
156
|
// Electrical Current
|
|
@@ -149,34 +158,34 @@ export const globalUnits = {
|
|
|
149
158
|
A: { value: 1, unit: 'ampere', symbol: 'A' },
|
|
150
159
|
mA: { value: 0.001, unit: 'milliampere', symbol: 'mA' },
|
|
151
160
|
uA: { value: 0.000001, unit: 'microampere', symbol: 'uA' },
|
|
152
|
-
kA: { value: 1000, unit: 'kiloampere', symbol: 'kA' }
|
|
161
|
+
kA: { value: 1000, unit: 'kiloampere', symbol: 'kA' },
|
|
153
162
|
},
|
|
154
163
|
|
|
155
164
|
// Resistance / Conductance
|
|
156
165
|
resistance: {
|
|
157
166
|
ohm: { value: 1, unit: 'ohm' },
|
|
158
|
-
kohm: { value: 1000, unit: 'kiloohm'},
|
|
159
|
-
megaohm: { value: 1e6, unit: 'megaohm'},
|
|
160
|
-
S: { value: 1, unit: 'siemens', symbol: 'S', note: 'conductance' }
|
|
167
|
+
kohm: { value: 1000, unit: 'kiloohm' },
|
|
168
|
+
megaohm: { value: 1e6, unit: 'megaohm' },
|
|
169
|
+
S: { value: 1, unit: 'siemens', symbol: 'S', note: 'conductance' },
|
|
161
170
|
},
|
|
162
171
|
|
|
163
172
|
// Capacitance / Inductance
|
|
164
173
|
capacitance: {
|
|
165
174
|
F: { value: 1, unit: 'farad', symbol: 'F' },
|
|
166
|
-
mF: { value: 0.001, unit: 'millifarad'},
|
|
167
|
-
uF: { value: 0.000001, unit: 'microfarad' }
|
|
175
|
+
mF: { value: 0.001, unit: 'millifarad' },
|
|
176
|
+
uF: { value: 0.000001, unit: 'microfarad' },
|
|
168
177
|
},
|
|
169
178
|
inductance: {
|
|
170
179
|
H: { value: 1, unit: 'henry', symbol: 'H' },
|
|
171
180
|
mH: { value: 0.001, unit: 'millihenry', symbol: 'mH' },
|
|
172
|
-
uH: { value: 0.000001, unit: 'microhenry', symbol: 'uH' }
|
|
181
|
+
uH: { value: 0.000001, unit: 'microhenry', symbol: 'uH' },
|
|
173
182
|
},
|
|
174
183
|
|
|
175
184
|
// Luminous Intensity / Illuminance
|
|
176
185
|
light: {
|
|
177
186
|
cd: { value: 1, unit: 'candela', symbol: 'cd' },
|
|
178
187
|
lm: { value: 1, unit: 'lumen', symbol: 'lm' },
|
|
179
|
-
lx: { value: 1, unit: 'lux', symbol: 'lx' }
|
|
188
|
+
lx: { value: 1, unit: 'lux', symbol: 'lx' },
|
|
180
189
|
},
|
|
181
190
|
|
|
182
191
|
// Data / Digital Storage
|
|
@@ -186,17 +195,16 @@ export const globalUnits = {
|
|
|
186
195
|
KB: { value: 8e3, unit: 'kilobyte', symbol: 'KB' },
|
|
187
196
|
MB: { value: 8e6, unit: 'megabyte', symbol: 'MB' },
|
|
188
197
|
GB: { value: 8e9, unit: 'gigabyte', symbol: 'GB' },
|
|
189
|
-
TB: { value: 8e12, unit: 'terabyte', symbol: 'TB' }
|
|
198
|
+
TB: { value: 8e12, unit: 'terabyte', symbol: 'TB' },
|
|
190
199
|
},
|
|
191
200
|
|
|
192
201
|
// Angle
|
|
193
202
|
angle: {
|
|
194
203
|
deg: { value: 1, unit: 'degree', symbol: '°' },
|
|
195
204
|
rad: { value: 57.2958, unit: 'radian', symbol: 'rad', note: '1 rad = 57.2958°' },
|
|
196
|
-
grad:{ value: 0.9, unit: 'grad', symbol: 'grad', note: '1 grad = 0.9°' }
|
|
205
|
+
grad: { value: 0.9, unit: 'grad', symbol: 'grad', note: '1 grad = 0.9°' },
|
|
197
206
|
},
|
|
198
207
|
radiation: {
|
|
199
|
-
// Absorbed Dose
|
|
200
208
|
Gy: { value: 1, unit: 'gray', symbol: 'Gy', note: 'Absorbed dose: 1 Gy = 1 J/kg' },
|
|
201
209
|
mGy: { value: 0.001, unit: 'milligray', symbol: 'mGy' },
|
|
202
210
|
rad: { value: 0.01, unit: 'rad', symbol: 'rad', note: '1 rad = 0.01 Gy' },
|
|
@@ -212,6 +220,6 @@ export const globalUnits = {
|
|
|
212
220
|
MBq: { value: 1e6, unit: 'megabecquerel', symbol: 'MBq' },
|
|
213
221
|
GBq: { value: 1e9, unit: 'gigabecquerel', symbol: 'GBq' },
|
|
214
222
|
Ci: { value: 3.7e10, unit: 'curie', symbol: 'Ci', note: '1 Ci = 3.7 x 10¹⁰ decays per second' },
|
|
215
|
-
mCi: { value: 3.7e7, unit: 'millicurie', symbol: 'mCi' }
|
|
216
|
-
}
|
|
217
|
-
};
|
|
223
|
+
mCi: { value: 3.7e7, unit: 'millicurie', symbol: 'mCi' },
|
|
224
|
+
},
|
|
225
|
+
};
|
package/src/utils/matrix.js
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
export const isDenseMatrixWrapper = (value) =>
|
|
1
|
+
export const isDenseMatrixWrapper = (/** @type {any} */ value) =>
|
|
2
2
|
value &&
|
|
3
|
-
typeof value ===
|
|
4
|
-
value.exprify ===
|
|
5
|
-
|
|
6
|
-
|
|
3
|
+
typeof value === 'object' &&
|
|
4
|
+
value.exprify === 'DenseMatrix' &&
|
|
5
|
+
'data' in value &&
|
|
6
|
+
'size' in value;
|
|
7
7
|
|
|
8
|
-
export const cloneMatrixData = (value) => {
|
|
8
|
+
export const cloneMatrixData = (/** @type {any[]} */ value) => {
|
|
9
9
|
if (Array.isArray(value)) {
|
|
10
10
|
return value.map(cloneMatrixData);
|
|
11
11
|
}
|
|
@@ -13,7 +13,7 @@ export const cloneMatrixData = (value) => {
|
|
|
13
13
|
return value;
|
|
14
14
|
};
|
|
15
15
|
|
|
16
|
-
export const getMatrixSize = (data) => {
|
|
16
|
+
export const getMatrixSize = (/** @type {any[]} */ data) => {
|
|
17
17
|
if (Array.isArray(data) && data.every(Array.isArray)) {
|
|
18
18
|
return [data.length, data[0]?.length || 0];
|
|
19
19
|
}
|
|
@@ -22,24 +22,24 @@ export const getMatrixSize = (data) => {
|
|
|
22
22
|
return [data.length];
|
|
23
23
|
}
|
|
24
24
|
|
|
25
|
-
throw new Error(
|
|
25
|
+
throw new Error('Matrix data must be an array');
|
|
26
26
|
};
|
|
27
27
|
|
|
28
|
-
export const wrapDenseMatrix = (data) => ({
|
|
29
|
-
exprify:
|
|
28
|
+
export const wrapDenseMatrix = (/** @type {any[][]} */ data) => ({
|
|
29
|
+
exprify: 'DenseMatrix',
|
|
30
30
|
data: cloneMatrixData(data),
|
|
31
|
-
size: getMatrixSize(data)
|
|
31
|
+
size: getMatrixSize(data),
|
|
32
32
|
});
|
|
33
33
|
|
|
34
|
-
export const unwrapDenseMatrix = (value) =>
|
|
34
|
+
export const unwrapDenseMatrix = (/** @type {any} */ value) =>
|
|
35
35
|
isDenseMatrixWrapper(value) ? cloneMatrixData(value.data) : value;
|
|
36
36
|
|
|
37
|
-
export const serializeExprifyValue = (value) => {
|
|
37
|
+
export const serializeExprifyValue = (/** @type {any} */ value) => {
|
|
38
38
|
if (isDenseMatrixWrapper(value)) {
|
|
39
39
|
return JSON.stringify(value);
|
|
40
40
|
}
|
|
41
41
|
|
|
42
|
-
if (Array.isArray(value) || (value && typeof value ===
|
|
42
|
+
if (Array.isArray(value) || (value && typeof value === 'object')) {
|
|
43
43
|
return JSON.stringify(value, (_, current) => {
|
|
44
44
|
if (isDenseMatrixWrapper(current)) {
|
|
45
45
|
return current;
|