@danielsimonjr/mathts-core 0.1.2 → 0.1.3

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/dist/index.js CHANGED
@@ -757,10 +757,7 @@ var Fraction = class _Fraction {
757
757
  */
758
758
  multiply(other) {
759
759
  if (other instanceof _Fraction) {
760
- return new _Fraction(
761
- this.numerator * other.numerator,
762
- this.denominator * other.denominator
763
- );
760
+ return new _Fraction(this.numerator * other.numerator, this.denominator * other.denominator);
764
761
  }
765
762
  return this.multiply(_Fraction.fromNumber(Number(other.valueOf())));
766
763
  }
@@ -772,10 +769,7 @@ var Fraction = class _Fraction {
772
769
  if (other.numerator === 0n) {
773
770
  throw new Error("Division by zero");
774
771
  }
775
- return new _Fraction(
776
- this.numerator * other.denominator,
777
- this.denominator * other.numerator
778
- );
772
+ return new _Fraction(this.numerator * other.denominator, this.denominator * other.numerator);
779
773
  }
780
774
  return this.divide(_Fraction.fromNumber(Number(other.valueOf())));
781
775
  }
@@ -789,10 +783,7 @@ var Fraction = class _Fraction {
789
783
  * Absolute value: |a/b|
790
784
  */
791
785
  abs() {
792
- return new _Fraction(
793
- this.numerator < 0n ? -this.numerator : this.numerator,
794
- this.denominator
795
- );
786
+ return new _Fraction(this.numerator < 0n ? -this.numerator : this.numerator, this.denominator);
796
787
  }
797
788
  /**
798
789
  * Reciprocal: b/a
@@ -1019,10 +1010,7 @@ var Fraction = class _Fraction {
1019
1010
  * Used in Stern-Brocot tree and Farey sequences
1020
1011
  */
1021
1012
  mediant(other) {
1022
- return new _Fraction(
1023
- this.numerator + other.numerator,
1024
- this.denominator + other.denominator
1025
- );
1013
+ return new _Fraction(this.numerator + other.numerator, this.denominator + other.denominator);
1026
1014
  }
1027
1015
  };
1028
1016
  var FRACTION_ZERO = new Fraction(0n, 1n);
@@ -1045,6 +1033,12 @@ var defaultConfig = {
1045
1033
  var globalConfig = { ...defaultConfig };
1046
1034
  var BigNumber = class _BigNumber {
1047
1035
  type = "BigNumber";
1036
+ /**
1037
+ * Duck-typing marker for Decimal.js / mathjs formatter compatibility.
1038
+ * Allows external code that checks `obj.isBigNumber === true` to identify
1039
+ * this class without an `instanceof` check.
1040
+ */
1041
+ isBigNumber = true;
1048
1042
  // Internal representation: sign * coefficient * 10^exponent
1049
1043
  _sign;
1050
1044
  _coefficient;
@@ -1218,6 +1212,14 @@ var BigNumber = class _BigNumber {
1218
1212
  const str = this.toString();
1219
1213
  return parseFloat(str);
1220
1214
  }
1215
+ /**
1216
+ * Convert to a JS number.
1217
+ * Alias for `valueOf()` — provided for Decimal.js / mathjs formatter
1218
+ * duck-typing compatibility.
1219
+ */
1220
+ toNumber() {
1221
+ return this.valueOf();
1222
+ }
1221
1223
  toString() {
1222
1224
  if (this._isNaN) return "NaN";
1223
1225
  if (this._isInfinite) return this._sign === 1 ? "Infinity" : "-Infinity";
@@ -1240,35 +1242,55 @@ var BigNumber = class _BigNumber {
1240
1242
  };
1241
1243
  }
1242
1244
  /**
1243
- * Convert to fixed-point notation
1245
+ * Convert to fixed-point notation.
1246
+ *
1247
+ * When called with no argument (or `undefined`) returns the full fixed-point
1248
+ * string representation without rounding — matching Decimal.js semantics where
1249
+ * `toFixed()` is equivalent to a lossless fixed-point stringify.
1250
+ * When called with a non-negative integer `decimalPlaces`, rounds and formats
1251
+ * to exactly that many digits after the decimal point.
1244
1252
  */
1245
- toFixed(decimalPlaces = 0) {
1253
+ toFixed(decimalPlaces) {
1254
+ if (decimalPlaces === void 0) {
1255
+ return this.toFixedInternal(void 0);
1256
+ }
1246
1257
  return this.round(decimalPlaces).toFixedInternal(decimalPlaces);
1247
1258
  }
1248
1259
  toFixedInternal(decimalPlaces) {
1249
1260
  if (this._isNaN) return "NaN";
1250
1261
  if (this._isInfinite) return this._sign === 1 ? "Infinity" : "-Infinity";
1251
- if (this._sign === 0) return decimalPlaces > 0 ? "0." + "0".repeat(decimalPlaces) : "0";
1262
+ const dp = decimalPlaces ?? -1;
1263
+ const allDigits = dp < 0;
1264
+ if (this._sign === 0) return allDigits ? "0" : dp > 0 ? "0." + "0".repeat(dp) : "0";
1252
1265
  const sign = this._sign === -1 ? "-" : "";
1253
1266
  const digits = this._coefficient.toString();
1254
1267
  if (this._exponent >= 0) {
1255
1268
  const intPart = digits + "0".repeat(this._exponent);
1256
- return sign + intPart + (decimalPlaces > 0 ? "." + "0".repeat(decimalPlaces) : "");
1269
+ if (allDigits) return sign + intPart;
1270
+ return sign + intPart + (dp > 0 ? "." + "0".repeat(dp) : "");
1257
1271
  } else if (-this._exponent <= digits.length) {
1258
1272
  const insertPos = digits.length + this._exponent;
1259
1273
  const intPart = digits.slice(0, insertPos) || "0";
1260
- let decPart = digits.slice(insertPos);
1261
- if (decPart.length < decimalPlaces) {
1262
- decPart += "0".repeat(decimalPlaces - decPart.length);
1274
+ const decPart = digits.slice(insertPos);
1275
+ if (allDigits) {
1276
+ return sign + intPart + (decPart.length > 0 ? "." + decPart : "");
1263
1277
  }
1264
- return sign + intPart + (decimalPlaces > 0 ? "." + decPart.slice(0, decimalPlaces) : "");
1278
+ let paddedDec = decPart;
1279
+ if (paddedDec.length < dp) {
1280
+ paddedDec += "0".repeat(dp - paddedDec.length);
1281
+ }
1282
+ return sign + intPart + (dp > 0 ? "." + paddedDec.slice(0, dp) : "");
1265
1283
  } else {
1266
1284
  const leadingZeros = -this._exponent - digits.length;
1267
- let decPart = "0".repeat(leadingZeros) + digits;
1268
- if (decPart.length < decimalPlaces) {
1269
- decPart += "0".repeat(decimalPlaces - decPart.length);
1285
+ const decPart = "0".repeat(leadingZeros) + digits;
1286
+ if (allDigits) {
1287
+ return sign + "0." + decPart;
1288
+ }
1289
+ let paddedDec = decPart;
1290
+ if (paddedDec.length < dp) {
1291
+ paddedDec += "0".repeat(dp - paddedDec.length);
1270
1292
  }
1271
- return sign + "0" + (decimalPlaces > 0 ? "." + decPart.slice(0, decimalPlaces) : "");
1293
+ return sign + "0" + (dp > 0 ? "." + paddedDec.slice(0, dp) : "");
1272
1294
  }
1273
1295
  }
1274
1296
  /**
@@ -1373,6 +1395,12 @@ var BigNumber = class _BigNumber {
1373
1395
  const b = this.ensureBigNumber(other);
1374
1396
  return this.add(b.negate());
1375
1397
  }
1398
+ /**
1399
+ * Alias for subtract — mathjs / Decimal.js compatibility.
1400
+ */
1401
+ sub(other) {
1402
+ return this.subtract(other);
1403
+ }
1376
1404
  /**
1377
1405
  * Multiplication
1378
1406
  */
@@ -1390,6 +1418,12 @@ var BigNumber = class _BigNumber {
1390
1418
  const exponent = this._exponent + b._exponent;
1391
1419
  return this.normalize(sign, coefficient, exponent);
1392
1420
  }
1421
+ /**
1422
+ * Alias for multiply — mathjs / Decimal.js compatibility.
1423
+ */
1424
+ mul(other) {
1425
+ return this.multiply(other);
1426
+ }
1393
1427
  /**
1394
1428
  * Division
1395
1429
  */
@@ -1501,6 +1535,14 @@ var BigNumber = class _BigNumber {
1501
1535
  compare(other) {
1502
1536
  return this.compareTo(other);
1503
1537
  }
1538
+ /**
1539
+ * Returns true iff this > other.
1540
+ * Accepts the same argument types as `add`/`multiply` (BigNumber, number, or string).
1541
+ * Named `gt` for Decimal.js / mathjs formatter compatibility.
1542
+ */
1543
+ gt(other) {
1544
+ return this.greaterThan(this.ensureBigNumber(other));
1545
+ }
1504
1546
  // ============================================================
1505
1547
  // Rounding Methods
1506
1548
  // ============================================================
@@ -1579,6 +1621,36 @@ var BigNumber = class _BigNumber {
1579
1621
  trunc() {
1580
1622
  return this.round(0, "down");
1581
1623
  }
1624
+ /**
1625
+ * Round to `n` significant decimal digits and return a new BigNumber.
1626
+ * Delegates to `roundToPrecision`, using the global rounding mode unless
1627
+ * an explicit `roundingMode` is supplied.
1628
+ *
1629
+ * Named `toSignificantDigits` for Decimal.js / mathjs formatter compatibility.
1630
+ * When `n` is undefined the value is returned unchanged (no rounding).
1631
+ */
1632
+ toSignificantDigits(n, roundingMode) {
1633
+ if (n === void 0) return this.clone();
1634
+ return this.roundToPrecision(n, roundingMode ?? globalConfig.rounding);
1635
+ }
1636
+ /**
1637
+ * The decimal exponent of this number: `floor(log10(|x|))`.
1638
+ *
1639
+ * Matches Decimal.js semantics:
1640
+ * - `12345` → `4` (5 digits → the most-significant place is 10^4)
1641
+ * - `0.0123` → `-2` (first significant digit is at 10^-2)
1642
+ * - `100` → `2`
1643
+ * - `0.01` → `-2`
1644
+ * - `0` → `0` (by convention; `isZero()` can be used to distinguish)
1645
+ *
1646
+ * For special values (NaN, ±Infinity) returns 0 — callers check
1647
+ * `isFinite()` / `isNaN()` before using `.e`.
1648
+ */
1649
+ get e() {
1650
+ if (this._isNaN || this._isInfinite || this._sign === 0) return 0;
1651
+ const d = this._coefficient.toString().length;
1652
+ return d - 1 + this._exponent;
1653
+ }
1582
1654
  // ============================================================
1583
1655
  // Modular Arithmetic
1584
1656
  // ============================================================
@@ -1795,7 +1867,7 @@ var BigNumber = class _BigNumber {
1795
1867
  if (val > 0.5) {
1796
1868
  k = Math.ceil(Math.log2(val * 2));
1797
1869
  }
1798
- const divisor = _BigNumber.fromNumber(2 ** k);
1870
+ const divisor = _BigNumber.fromNumber(2).pow(k);
1799
1871
  const reduced = this.divide(divisor);
1800
1872
  let sum = _BigNumber.fromNumber(1);
1801
1873
  let term = _BigNumber.fromNumber(1);
@@ -1883,9 +1955,7 @@ var BigNumber = class _BigNumber {
1883
1955
  for (let i = 0; i < 100; i++) {
1884
1956
  const guessSquared = guess.multiply(guess);
1885
1957
  const newGuess = guess.multiply(_BigNumber.fromNumber(2)).add(this.divide(guessSquared)).divide(three);
1886
- if (guess.subtract(newGuess).abs().compareTo(
1887
- guess.abs().multiply(_BigNumber.parse("1e-" + (precision + 5)))
1888
- ) <= 0) {
1958
+ if (guess.subtract(newGuess).abs().compareTo(guess.abs().multiply(_BigNumber.parse("1e-" + (precision + 5)))) <= 0) {
1889
1959
  return newGuess.roundToPrecision(precision);
1890
1960
  }
1891
1961
  guess = newGuess;
@@ -1963,9 +2033,7 @@ var BigNumber = class _BigNumber {
1963
2033
  const xSquared = this.multiply(this);
1964
2034
  const maxIter = precision + 20;
1965
2035
  for (let n = 1; n <= maxIter; n++) {
1966
- term = term.multiply(xSquared).divide(
1967
- _BigNumber.fromNumber(2 * n * (2 * n + 1))
1968
- ).negate();
2036
+ term = term.multiply(xSquared).divide(_BigNumber.fromNumber(2 * n * (2 * n + 1))).negate();
1969
2037
  const newSum = sum.add(term);
1970
2038
  if (sum.equals(newSum)) break;
1971
2039
  sum = newSum;
@@ -1980,9 +2048,7 @@ var BigNumber = class _BigNumber {
1980
2048
  const xSquared = this.multiply(this);
1981
2049
  const maxIter = precision + 20;
1982
2050
  for (let n = 1; n <= maxIter; n++) {
1983
- term = term.multiply(xSquared).divide(
1984
- _BigNumber.fromNumber((2 * n - 1) * (2 * n))
1985
- ).negate();
2051
+ term = term.multiply(xSquared).divide(_BigNumber.fromNumber((2 * n - 1) * (2 * n))).negate();
1986
2052
  const newSum = sum.add(term);
1987
2053
  if (sum.equals(newSum)) break;
1988
2054
  sum = newSum;
@@ -2034,7 +2100,13 @@ var BigNumber = class _BigNumber {
2034
2100
  return this._sign;
2035
2101
  }
2036
2102
  clone() {
2037
- return new _BigNumber(this._sign, this._coefficient, this._exponent, this._isNaN, this._isInfinite);
2103
+ return new _BigNumber(
2104
+ this._sign,
2105
+ this._coefficient,
2106
+ this._exponent,
2107
+ this._isNaN,
2108
+ this._isInfinite
2109
+ );
2038
2110
  }
2039
2111
  // ============================================================
2040
2112
  // Private Helper Methods
@@ -2072,8 +2144,683 @@ var BIGNUMBER_NEG_ONE = BigNumber.fromNumber(-1);
2072
2144
  var BIGNUMBER_TEN = BigNumber.fromNumber(10);
2073
2145
  var BIGNUMBER_PI = BigNumber.parse("3.14159265358979323846264338327950288419716939937510");
2074
2146
  var BIGNUMBER_E = BigNumber.parse("2.71828182845904523536028747135266249775724709369995");
2075
- var BIGNUMBER_LN2 = BigNumber.parse("0.69314718055994530941723212145817656807550013436026");
2076
- var BIGNUMBER_LN10 = BigNumber.parse("2.30258509299404568401799145468436420760110148862877");
2147
+ var BIGNUMBER_LN2 = BigNumber.parse(
2148
+ "0.69314718055994530941723212145817656807550013436026"
2149
+ );
2150
+ var BIGNUMBER_LN10 = BigNumber.parse(
2151
+ "2.30258509299404568401799145468436420760110148862877"
2152
+ );
2153
+
2154
+ // src/types/unit-definitions.ts
2155
+ var DIMENSIONLESS = Object.freeze({
2156
+ length: 0,
2157
+ mass: 0,
2158
+ time: 0,
2159
+ current: 0,
2160
+ temperature: 0,
2161
+ amount: 0,
2162
+ luminosity: 0
2163
+ });
2164
+ function dim(partial) {
2165
+ return {
2166
+ length: partial.length ?? 0,
2167
+ mass: partial.mass ?? 0,
2168
+ time: partial.time ?? 0,
2169
+ current: partial.current ?? 0,
2170
+ temperature: partial.temperature ?? 0,
2171
+ amount: partial.amount ?? 0,
2172
+ luminosity: partial.luminosity ?? 0
2173
+ };
2174
+ }
2175
+ var BASE_UNITS = {
2176
+ m: { multiplier: 1, dimensions: dim({ length: 1 }), prefixable: true },
2177
+ // The base unit of mass is *kilogram*, but the prefix-able symbol is "g".
2178
+ // Internally we treat 1 kg as the canonical value, so "g" -> 0.001 kg.
2179
+ kg: { multiplier: 1, dimensions: dim({ mass: 1 }) },
2180
+ s: { multiplier: 1, dimensions: dim({ time: 1 }), prefixable: true },
2181
+ A: { multiplier: 1, dimensions: dim({ current: 1 }), prefixable: true },
2182
+ K: { multiplier: 1, dimensions: dim({ temperature: 1 }), prefixable: true },
2183
+ mol: { multiplier: 1, dimensions: dim({ amount: 1 }), prefixable: true },
2184
+ cd: { multiplier: 1, dimensions: dim({ luminosity: 1 }), prefixable: true }
2185
+ };
2186
+ var DERIVED_UNITS = {
2187
+ // --- Length ---------------------------------------------------------------
2188
+ // Note: 'm' is a base unit (above), already prefixable.
2189
+ ft: { multiplier: 0.3048, dimensions: dim({ length: 1 }) },
2190
+ foot: { multiplier: 0.3048, dimensions: dim({ length: 1 }) },
2191
+ in: { multiplier: 0.0254, dimensions: dim({ length: 1 }) },
2192
+ inch: { multiplier: 0.0254, dimensions: dim({ length: 1 }) },
2193
+ yd: { multiplier: 0.9144, dimensions: dim({ length: 1 }) },
2194
+ yard: { multiplier: 0.9144, dimensions: dim({ length: 1 }) },
2195
+ mi: { multiplier: 1609.344, dimensions: dim({ length: 1 }) },
2196
+ mile: { multiplier: 1609.344, dimensions: dim({ length: 1 }) },
2197
+ // --- Mass -----------------------------------------------------------------
2198
+ // The "g" entry is gram (0.001 kg). It is prefixable, so kg/mg/µg work via
2199
+ // prefix application on this entry rather than the base "kg".
2200
+ g: { multiplier: 1e-3, dimensions: dim({ mass: 1 }), prefixable: true },
2201
+ lb: { multiplier: 0.45359237, dimensions: dim({ mass: 1 }) },
2202
+ lbm: { multiplier: 0.45359237, dimensions: dim({ mass: 1 }) },
2203
+ oz: { multiplier: 0.028349523125, dimensions: dim({ mass: 1 }) },
2204
+ ton: { multiplier: 907.18474, dimensions: dim({ mass: 1 }) },
2205
+ // US short ton
2206
+ tonne: { multiplier: 1e3, dimensions: dim({ mass: 1 }) },
2207
+ // metric ton
2208
+ // --- Time -----------------------------------------------------------------
2209
+ min: { multiplier: 60, dimensions: dim({ time: 1 }) },
2210
+ h: { multiplier: 3600, dimensions: dim({ time: 1 }) },
2211
+ hr: { multiplier: 3600, dimensions: dim({ time: 1 }) },
2212
+ day: { multiplier: 86400, dimensions: dim({ time: 1 }) },
2213
+ week: { multiplier: 604800, dimensions: dim({ time: 1 }) },
2214
+ year: { multiplier: 31557600, dimensions: dim({ time: 1 }) },
2215
+ // Julian year
2216
+ // --- Temperature ----------------------------------------------------------
2217
+ // K is the base.
2218
+ // °C → K is offset by 273.15 (no multiplicative factor change).
2219
+ // °F → K is more complex (offset & scale).
2220
+ degC: { multiplier: 1, offset: 273.15, dimensions: dim({ temperature: 1 }) },
2221
+ degF: { multiplier: 5 / 9, offset: 459.67 * (5 / 9), dimensions: dim({ temperature: 1 }) },
2222
+ degR: { multiplier: 5 / 9, dimensions: dim({ temperature: 1 }) },
2223
+ // Rankine
2224
+ // --- Plane angle (dimensionless, but often treated as units) --------------
2225
+ rad: { multiplier: 1, dimensions: dim({}), prefixable: true },
2226
+ deg: { multiplier: Math.PI / 180, dimensions: dim({}) },
2227
+ grad: { multiplier: Math.PI / 200, dimensions: dim({}) },
2228
+ // --- Force ----------------------------------------------------------------
2229
+ // N = kg·m·s^-2 = 1 kg·m·s^-2; in our base-units representation that's
2230
+ // value=1, dim {length: 1, mass: 1, time: -2}.
2231
+ N: { multiplier: 1, dimensions: dim({ length: 1, mass: 1, time: -2 }), prefixable: true },
2232
+ dyn: { multiplier: 1e-5, dimensions: dim({ length: 1, mass: 1, time: -2 }) },
2233
+ lbf: { multiplier: 4.4482216152605, dimensions: dim({ length: 1, mass: 1, time: -2 }) },
2234
+ // --- Energy ---------------------------------------------------------------
2235
+ J: { multiplier: 1, dimensions: dim({ length: 2, mass: 1, time: -2 }), prefixable: true },
2236
+ erg: { multiplier: 1e-7, dimensions: dim({ length: 2, mass: 1, time: -2 }) },
2237
+ cal: { multiplier: 4.184, dimensions: dim({ length: 2, mass: 1, time: -2 }) },
2238
+ eV: {
2239
+ multiplier: 1602176634e-28,
2240
+ dimensions: dim({ length: 2, mass: 1, time: -2 }),
2241
+ prefixable: true
2242
+ },
2243
+ BTU: { multiplier: 1055.05585262, dimensions: dim({ length: 2, mass: 1, time: -2 }) },
2244
+ // --- Power ----------------------------------------------------------------
2245
+ W: { multiplier: 1, dimensions: dim({ length: 2, mass: 1, time: -3 }), prefixable: true },
2246
+ hp: { multiplier: 745.6998715822702, dimensions: dim({ length: 2, mass: 1, time: -3 }) },
2247
+ // --- Pressure -------------------------------------------------------------
2248
+ Pa: { multiplier: 1, dimensions: dim({ length: -1, mass: 1, time: -2 }), prefixable: true },
2249
+ bar: { multiplier: 1e5, dimensions: dim({ length: -1, mass: 1, time: -2 }), prefixable: true },
2250
+ atm: { multiplier: 101325, dimensions: dim({ length: -1, mass: 1, time: -2 }) },
2251
+ psi: { multiplier: 6894.757293168361, dimensions: dim({ length: -1, mass: 1, time: -2 }) },
2252
+ torr: { multiplier: 133.322368421, dimensions: dim({ length: -1, mass: 1, time: -2 }) },
2253
+ mmHg: { multiplier: 133.322387415, dimensions: dim({ length: -1, mass: 1, time: -2 }) },
2254
+ // --- Electric -------------------------------------------------------------
2255
+ C: {
2256
+ multiplier: 1,
2257
+ dimensions: dim({ time: 1, current: 1 }),
2258
+ prefixable: true
2259
+ },
2260
+ V: {
2261
+ multiplier: 1,
2262
+ dimensions: dim({ length: 2, mass: 1, time: -3, current: -1 }),
2263
+ prefixable: true
2264
+ },
2265
+ ohm: {
2266
+ multiplier: 1,
2267
+ dimensions: dim({ length: 2, mass: 1, time: -3, current: -2 }),
2268
+ prefixable: true
2269
+ },
2270
+ \u03A9: {
2271
+ multiplier: 1,
2272
+ dimensions: dim({ length: 2, mass: 1, time: -3, current: -2 }),
2273
+ prefixable: true
2274
+ },
2275
+ F: {
2276
+ multiplier: 1,
2277
+ dimensions: dim({ length: -2, mass: -1, time: 4, current: 2 }),
2278
+ prefixable: true
2279
+ },
2280
+ H: {
2281
+ multiplier: 1,
2282
+ dimensions: dim({ length: 2, mass: 1, time: -2, current: -2 }),
2283
+ prefixable: true
2284
+ },
2285
+ // --- Frequency ------------------------------------------------------------
2286
+ Hz: { multiplier: 1, dimensions: dim({ time: -1 }), prefixable: true },
2287
+ // --- Volume ---------------------------------------------------------------
2288
+ L: { multiplier: 1e-3, dimensions: dim({ length: 3 }), prefixable: true },
2289
+ l: { multiplier: 1e-3, dimensions: dim({ length: 3 }), prefixable: true },
2290
+ gal: { multiplier: 0.003785411784, dimensions: dim({ length: 3 }) },
2291
+ // US gallon
2292
+ // --- Area -----------------------------------------------------------------
2293
+ ha: { multiplier: 1e4, dimensions: dim({ length: 2 }) },
2294
+ // hectare
2295
+ acre: { multiplier: 4046.8564224, dimensions: dim({ length: 2 }) }
2296
+ };
2297
+ var ALL_UNITS = { ...BASE_UNITS, ...DERIVED_UNITS };
2298
+ var UNIT_ALIASES = {
2299
+ "\xB0C": "degC",
2300
+ "\xB0F": "degF",
2301
+ "\xB0R": "degR",
2302
+ "\xB0": "deg"
2303
+ // The Unicode micro sign is handled in prefixes; °K is non-standard.
2304
+ };
2305
+ function getUnitDef(name) {
2306
+ return ALL_UNITS[name];
2307
+ }
2308
+
2309
+ // src/types/unit-prefixes.ts
2310
+ var SI_PREFIXES = {
2311
+ // Positive powers of ten
2312
+ Y: 1e24,
2313
+ // yotta
2314
+ Z: 1e21,
2315
+ // zetta
2316
+ E: 1e18,
2317
+ // exa
2318
+ P: 1e15,
2319
+ // peta
2320
+ T: 1e12,
2321
+ // tera
2322
+ G: 1e9,
2323
+ // giga
2324
+ M: 1e6,
2325
+ // mega
2326
+ k: 1e3,
2327
+ // kilo
2328
+ h: 100,
2329
+ // hecto
2330
+ da: 10,
2331
+ // deka (two-letter)
2332
+ // Negative powers of ten
2333
+ d: 0.1,
2334
+ // deci
2335
+ c: 0.01,
2336
+ // centi
2337
+ m: 1e-3,
2338
+ // milli
2339
+ u: 1e-6,
2340
+ // micro (ASCII fallback)
2341
+ \u00B5: 1e-6,
2342
+ // micro (Unicode)
2343
+ n: 1e-9,
2344
+ // nano
2345
+ p: 1e-12,
2346
+ // pico
2347
+ f: 1e-15,
2348
+ // femto
2349
+ a: 1e-18,
2350
+ // atto
2351
+ z: 1e-21,
2352
+ // zepto
2353
+ y: 1e-24
2354
+ // yocto
2355
+ };
2356
+ var SI_PREFIX_KEYS = Object.keys(SI_PREFIXES).sort(
2357
+ (a, b) => b.length - a.length
2358
+ );
2359
+ var BEST_PREFIXES = [
2360
+ "Y",
2361
+ "Z",
2362
+ "E",
2363
+ "P",
2364
+ "T",
2365
+ "G",
2366
+ "M",
2367
+ "k",
2368
+ "",
2369
+ "m",
2370
+ "u",
2371
+ "n",
2372
+ "p",
2373
+ "f",
2374
+ "a",
2375
+ "z",
2376
+ "y"
2377
+ ];
2378
+ function getPrefix(name) {
2379
+ return SI_PREFIXES[name];
2380
+ }
2381
+
2382
+ // src/types/unit.ts
2383
+ var DimensionMismatchError = class extends Error {
2384
+ constructor(left, right, op) {
2385
+ super(
2386
+ `Dimension mismatch in ${op}: ${formatDimensions(left)} vs ${formatDimensions(right)}`
2387
+ );
2388
+ this.left = left;
2389
+ this.right = right;
2390
+ }
2391
+ left;
2392
+ right;
2393
+ name = "DimensionMismatchError";
2394
+ };
2395
+ var UnitParseError = class extends Error {
2396
+ name = "UnitParseError";
2397
+ constructor(notation, reason) {
2398
+ super(`Cannot parse unit notation "${notation}": ${reason}`);
2399
+ }
2400
+ };
2401
+ var DIM_KEYS = [
2402
+ "length",
2403
+ "mass",
2404
+ "time",
2405
+ "current",
2406
+ "temperature",
2407
+ "amount",
2408
+ "luminosity"
2409
+ ];
2410
+ function dimsEqual(a, b) {
2411
+ for (const k of DIM_KEYS) {
2412
+ if (a[k] !== b[k]) return false;
2413
+ }
2414
+ return true;
2415
+ }
2416
+ function dimsAdd(a, b) {
2417
+ return {
2418
+ length: a.length + b.length,
2419
+ mass: a.mass + b.mass,
2420
+ time: a.time + b.time,
2421
+ current: a.current + b.current,
2422
+ temperature: a.temperature + b.temperature,
2423
+ amount: a.amount + b.amount,
2424
+ luminosity: a.luminosity + b.luminosity
2425
+ };
2426
+ }
2427
+ function dimsSub(a, b) {
2428
+ return {
2429
+ length: a.length - b.length,
2430
+ mass: a.mass - b.mass,
2431
+ time: a.time - b.time,
2432
+ current: a.current - b.current,
2433
+ temperature: a.temperature - b.temperature,
2434
+ amount: a.amount - b.amount,
2435
+ luminosity: a.luminosity - b.luminosity
2436
+ };
2437
+ }
2438
+ function dimsScale(a, n) {
2439
+ return {
2440
+ length: a.length * n,
2441
+ mass: a.mass * n,
2442
+ time: a.time * n,
2443
+ current: a.current * n,
2444
+ temperature: a.temperature * n,
2445
+ amount: a.amount * n,
2446
+ luminosity: a.luminosity * n
2447
+ };
2448
+ }
2449
+ function isDimensionless(d) {
2450
+ return dimsEqual(d, DIMENSIONLESS);
2451
+ }
2452
+ function formatDimensions(d) {
2453
+ const parts = [];
2454
+ for (const k of DIM_KEYS) {
2455
+ const e = d[k];
2456
+ if (e !== 0) parts.push(`${k}^${e}`);
2457
+ }
2458
+ return parts.length === 0 ? "dimensionless" : parts.join("\xB7");
2459
+ }
2460
+ function resolveAtom(token) {
2461
+ const aliased = UNIT_ALIASES[token] ?? token;
2462
+ const direct = getUnitDef(aliased);
2463
+ if (direct) {
2464
+ return {
2465
+ multiplier: direct.multiplier,
2466
+ offset: direct.offset ?? 0,
2467
+ dimensions: direct.dimensions,
2468
+ prefix: "",
2469
+ base: aliased
2470
+ };
2471
+ }
2472
+ for (const prefix of SI_PREFIX_KEYS) {
2473
+ if (!aliased.startsWith(prefix) || aliased.length === prefix.length) continue;
2474
+ const rest = aliased.slice(prefix.length);
2475
+ const baseDef = getUnitDef(rest);
2476
+ if (!baseDef) continue;
2477
+ if (!baseDef.prefixable) continue;
2478
+ return {
2479
+ multiplier: baseDef.multiplier * SI_PREFIXES[prefix],
2480
+ // Offset is in base units, so prefix the multiplier but not the offset
2481
+ // (we never apply prefixes to temperature units in practice anyway).
2482
+ offset: baseDef.offset ?? 0,
2483
+ dimensions: baseDef.dimensions,
2484
+ prefix,
2485
+ base: rest
2486
+ };
2487
+ }
2488
+ throw new UnitParseError(token, `unknown unit "${token}"`);
2489
+ }
2490
+ function splitScalar(input) {
2491
+ const m = input.match(/^\s*([+-]?\d+(?:\.\d+)?(?:[eE][+-]?\d+)?)\s+(.*)$/);
2492
+ if (m) {
2493
+ return { scalar: parseFloat(m[1]), rest: m[2].trim() };
2494
+ }
2495
+ const scalarOnly = input.match(/^\s*([+-]?\d+(?:\.\d+)?(?:[eE][+-]?\d+)?)\s*$/);
2496
+ if (scalarOnly) {
2497
+ return { scalar: parseFloat(scalarOnly[1]), rest: "" };
2498
+ }
2499
+ return { scalar: 1, rest: input.trim() };
2500
+ }
2501
+ function parseUnitExpr(expr) {
2502
+ if (expr === "" || expr === "1") return [];
2503
+ const normalized = expr.replace(/[·⋅]/g, "*");
2504
+ const atoms = [];
2505
+ let pos = 0;
2506
+ let nextSign = 1;
2507
+ while (pos < normalized.length) {
2508
+ while (pos < normalized.length && /\s/.test(normalized[pos])) pos++;
2509
+ if (pos >= normalized.length) break;
2510
+ const ch = normalized[pos];
2511
+ if (ch === "*") {
2512
+ pos++;
2513
+ continue;
2514
+ }
2515
+ if (ch === "/") {
2516
+ nextSign = -1;
2517
+ pos++;
2518
+ continue;
2519
+ }
2520
+ if (ch === "1") {
2521
+ const next = normalized[pos + 1];
2522
+ if (next === void 0 || next === " " || next === "/" || next === "*") {
2523
+ pos++;
2524
+ continue;
2525
+ }
2526
+ }
2527
+ if (!/[A-Za-z°µΩ]/.test(ch)) {
2528
+ throw new UnitParseError(expr, `unexpected character "${ch}" at position ${pos}`);
2529
+ }
2530
+ const idStart = pos;
2531
+ while (pos < normalized.length && /[A-Za-z°µΩ]/.test(normalized[pos])) pos++;
2532
+ const identifier = normalized.slice(idStart, pos);
2533
+ let exponent = 1;
2534
+ if (pos < normalized.length && normalized[pos] === "^") {
2535
+ pos++;
2536
+ const expMatch = normalized.slice(pos).match(/^([+-]?\d+(?:\.\d+)?)/);
2537
+ if (!expMatch) {
2538
+ throw new UnitParseError(expr, `expected exponent after "^" at position ${pos}`);
2539
+ }
2540
+ exponent = parseFloat(expMatch[1]);
2541
+ pos += expMatch[1].length;
2542
+ } else {
2543
+ const supMatch = normalized.slice(pos).match(/^([²³⁴⁵⁶⁷⁸⁹⁰¹]+)/);
2544
+ if (supMatch) {
2545
+ exponent = parseSuperscript(supMatch[1]);
2546
+ pos += supMatch[1].length;
2547
+ }
2548
+ }
2549
+ const resolved = resolveAtom(identifier);
2550
+ atoms.push({
2551
+ multiplier: resolved.multiplier,
2552
+ offset: resolved.offset,
2553
+ dimensions: resolved.dimensions,
2554
+ exponent: nextSign * exponent,
2555
+ source: identifier
2556
+ });
2557
+ nextSign = 1;
2558
+ }
2559
+ return atoms;
2560
+ }
2561
+ var SUPERSCRIPT_MAP = {
2562
+ "\u2070": "0",
2563
+ "\xB9": "1",
2564
+ "\xB2": "2",
2565
+ "\xB3": "3",
2566
+ "\u2074": "4",
2567
+ "\u2075": "5",
2568
+ "\u2076": "6",
2569
+ "\u2077": "7",
2570
+ "\u2078": "8",
2571
+ "\u2079": "9"
2572
+ };
2573
+ function parseSuperscript(s) {
2574
+ let out = "";
2575
+ for (const ch of s) out += SUPERSCRIPT_MAP[ch] ?? ch;
2576
+ return parseInt(out, 10);
2577
+ }
2578
+ function parse(input) {
2579
+ const { scalar, rest } = splitScalar(input);
2580
+ return { scalar, atoms: parseUnitExpr(rest) };
2581
+ }
2582
+ var Unit = class _Unit {
2583
+ /** Discriminator (matches the prototype-flag convention). */
2584
+ type = "Unit";
2585
+ /** Used by `isUnit()` and typed-function dispatch. */
2586
+ isUnit = true;
2587
+ /** Numeric magnitude in **SI base units**. */
2588
+ value;
2589
+ /** Dimensional signature. */
2590
+ dimensions;
2591
+ /** Original notation string, preserved for `toString()` round-trip. */
2592
+ notation;
2593
+ constructor(value, notationOrDims, notation) {
2594
+ if (typeof notationOrDims === "string") {
2595
+ const parsed = parse(notationOrDims);
2596
+ const composed = composeAtoms(parsed.atoms);
2597
+ const inputValue = parsed.scalar * value;
2598
+ let canonical;
2599
+ if (parsed.atoms.length === 1 && parsed.atoms[0].exponent === 1) {
2600
+ const a = parsed.atoms[0];
2601
+ canonical = inputValue * a.multiplier + a.offset;
2602
+ } else {
2603
+ canonical = inputValue * composed.multiplier;
2604
+ }
2605
+ this.value = canonical;
2606
+ this.dimensions = composed.dimensions;
2607
+ this.notation = notationOrDims;
2608
+ } else {
2609
+ this.value = value;
2610
+ this.dimensions = notationOrDims;
2611
+ this.notation = notation ?? "";
2612
+ }
2613
+ }
2614
+ // -------------------------------------------------------------------------
2615
+ // Arithmetic
2616
+ // -------------------------------------------------------------------------
2617
+ /**
2618
+ * Add two units. Requires identical dimensions.
2619
+ *
2620
+ * @throws {DimensionMismatchError} if dimensions differ.
2621
+ */
2622
+ add(other) {
2623
+ if (!dimsEqual(this.dimensions, other.dimensions)) {
2624
+ throw new DimensionMismatchError(this.dimensions, other.dimensions, "add");
2625
+ }
2626
+ return new _Unit(this.value + other.value, this.dimensions, this.notation);
2627
+ }
2628
+ /**
2629
+ * Subtract two units. Requires identical dimensions.
2630
+ *
2631
+ * @throws {DimensionMismatchError} if dimensions differ.
2632
+ */
2633
+ sub(other) {
2634
+ if (!dimsEqual(this.dimensions, other.dimensions)) {
2635
+ throw new DimensionMismatchError(this.dimensions, other.dimensions, "sub");
2636
+ }
2637
+ return new _Unit(this.value - other.value, this.dimensions, this.notation);
2638
+ }
2639
+ /**
2640
+ * Multiply by another unit or a scalar. Dimensions add when multiplying by
2641
+ * another unit; unchanged when multiplying by a scalar.
2642
+ */
2643
+ mul(other) {
2644
+ if (typeof other === "number") {
2645
+ return new _Unit(this.value * other, this.dimensions, this.notation);
2646
+ }
2647
+ return new _Unit(
2648
+ this.value * other.value,
2649
+ dimsAdd(this.dimensions, other.dimensions),
2650
+ composeNotation(this.notation, other.notation, "*")
2651
+ );
2652
+ }
2653
+ /**
2654
+ * Divide by another unit or a scalar. Dimensions subtract when dividing by
2655
+ * another unit; unchanged when dividing by a scalar.
2656
+ */
2657
+ div(other) {
2658
+ if (typeof other === "number") {
2659
+ return new _Unit(this.value / other, this.dimensions, this.notation);
2660
+ }
2661
+ return new _Unit(
2662
+ this.value / other.value,
2663
+ dimsSub(this.dimensions, other.dimensions),
2664
+ composeNotation(this.notation, other.notation, "/")
2665
+ );
2666
+ }
2667
+ /**
2668
+ * Raise to an integer or rational power. Dimensions scale by `n`.
2669
+ */
2670
+ pow(n) {
2671
+ return new _Unit(
2672
+ this.value ** n,
2673
+ dimsScale(this.dimensions, n),
2674
+ this.notation ? `(${this.notation})^${n}` : ""
2675
+ );
2676
+ }
2677
+ // -------------------------------------------------------------------------
2678
+ // Conversion
2679
+ // -------------------------------------------------------------------------
2680
+ /**
2681
+ * Convert to a target unit. Dimensions must match.
2682
+ *
2683
+ * @throws {DimensionMismatchError} if `targetNotation`'s dimensions differ
2684
+ * from this unit's.
2685
+ */
2686
+ to(targetNotation) {
2687
+ const parsed = parse(targetNotation);
2688
+ const composed = composeAtoms(parsed.atoms);
2689
+ if (!dimsEqual(this.dimensions, composed.dimensions)) {
2690
+ throw new DimensionMismatchError(
2691
+ this.dimensions,
2692
+ composed.dimensions,
2693
+ `to("${targetNotation}")`
2694
+ );
2695
+ }
2696
+ return new _Unit(this.value, composed.dimensions, targetNotation);
2697
+ }
2698
+ /**
2699
+ * Pick a unit (with SI prefix) that gives a magnitude closest to 1.
2700
+ *
2701
+ * Searches the unit registry for entries matching this unit's dimensions,
2702
+ * then applies each SI prefix in {@link BEST_PREFIXES} to find the
2703
+ * representation minimising `|log10(displayed value)|`.
2704
+ *
2705
+ * If no registered unit matches the dimensions, falls back to a synthetic
2706
+ * notation describing the dimensional vector.
2707
+ */
2708
+ toBest() {
2709
+ if (isDimensionless(this.dimensions)) {
2710
+ return new _Unit(this.value, this.dimensions, "");
2711
+ }
2712
+ let bestNotation;
2713
+ let bestScore = Infinity;
2714
+ for (const [name, def] of Object.entries(ALL_UNITS)) {
2715
+ if (name === "kg") continue;
2716
+ if (!dimsEqual(def.dimensions, this.dimensions)) continue;
2717
+ if (def.offset !== void 0) continue;
2718
+ const candidatePrefixes = def.prefixable ? BEST_PREFIXES : [""];
2719
+ for (const prefix of candidatePrefixes) {
2720
+ const factor = prefix === "" ? def.multiplier : def.multiplier * SI_PREFIXES[prefix];
2721
+ if (factor === 0) continue;
2722
+ const displayed = this.value / factor;
2723
+ if (displayed === 0) continue;
2724
+ const score = Math.abs(Math.log10(Math.abs(displayed)));
2725
+ if (score < bestScore) {
2726
+ bestScore = score;
2727
+ bestNotation = prefix + name;
2728
+ }
2729
+ }
2730
+ }
2731
+ if (bestNotation === void 0) {
2732
+ return new _Unit(
2733
+ this.value,
2734
+ this.dimensions,
2735
+ this.notation || formatDimensions(this.dimensions)
2736
+ );
2737
+ }
2738
+ return new _Unit(this.value, this.dimensions, bestNotation);
2739
+ }
2740
+ // -------------------------------------------------------------------------
2741
+ // Comparison
2742
+ // -------------------------------------------------------------------------
2743
+ /** True iff dimensions and canonical value are equal. */
2744
+ equals(other) {
2745
+ return dimsEqual(this.dimensions, other.dimensions) && this.value === other.value;
2746
+ }
2747
+ /** True iff dimensions match (values may differ). */
2748
+ dimensionsEqual(other) {
2749
+ return dimsEqual(this.dimensions, other.dimensions);
2750
+ }
2751
+ // -------------------------------------------------------------------------
2752
+ // Formatting
2753
+ // -------------------------------------------------------------------------
2754
+ /**
2755
+ * Pretty-print. If `notation` is set (the common case), display the value
2756
+ * in that notation — otherwise emit a dimensional signature.
2757
+ */
2758
+ toString() {
2759
+ if (this.notation === "") {
2760
+ if (isDimensionless(this.dimensions)) return String(this.value);
2761
+ return `${this.value} ${formatDimensions(this.dimensions)}`;
2762
+ }
2763
+ const displayed = displayedValue(this.value, this.notation);
2764
+ return `${formatNumber(displayed)} ${this.notation}`;
2765
+ }
2766
+ /** JSON-serialisable record. */
2767
+ toJSON() {
2768
+ return { mathts: "Unit", value: this.value, notation: this.notation };
2769
+ }
2770
+ /**
2771
+ * Rehydrate from a JSON record produced by {@link toJSON}.
2772
+ *
2773
+ * @throws {UnitParseError} if `json.notation` cannot be parsed.
2774
+ */
2775
+ static fromJSON(json) {
2776
+ const parsed = parse(json.notation);
2777
+ const composed = composeAtoms(parsed.atoms);
2778
+ return new _Unit(json.value, composed.dimensions, json.notation);
2779
+ }
2780
+ /**
2781
+ * Parse a full unit expression (with optional leading numeric coefficient).
2782
+ *
2783
+ * Example: `Unit.parse('5 km/h')`.
2784
+ */
2785
+ static parse(input) {
2786
+ const { scalar, rest } = splitScalar(input);
2787
+ return new _Unit(scalar, rest);
2788
+ }
2789
+ };
2790
+ Unit.prototype.isUnit = true;
2791
+ function composeAtoms(atoms) {
2792
+ let multiplier = 1;
2793
+ let dimensions = { ...DIMENSIONLESS };
2794
+ for (const a of atoms) {
2795
+ multiplier *= a.multiplier ** a.exponent;
2796
+ dimensions = dimsAdd(dimensions, dimsScale(a.dimensions, a.exponent));
2797
+ }
2798
+ return { multiplier, dimensions };
2799
+ }
2800
+ function displayedValue(canonical, notation) {
2801
+ const parsed = parse(notation);
2802
+ const composed = composeAtoms(parsed.atoms);
2803
+ if (parsed.atoms.length === 1 && parsed.atoms[0].exponent === 1) {
2804
+ const a = parsed.atoms[0];
2805
+ return (canonical - a.offset) / a.multiplier;
2806
+ }
2807
+ return canonical / composed.multiplier;
2808
+ }
2809
+ function formatNumber(n) {
2810
+ if (Number.isInteger(n)) return n.toString();
2811
+ const rounded = Number(n.toPrecision(12));
2812
+ return rounded.toString();
2813
+ }
2814
+ function composeNotation(a, b, op) {
2815
+ if (a === "" && b === "") return "";
2816
+ if (a === "") return op === "*" ? b : `1/${b}`;
2817
+ if (b === "") return a;
2818
+ const sep = op === "*" ? "*" : "/";
2819
+ return `${a}${sep}${b}`;
2820
+ }
2821
+ function isUnit(value) {
2822
+ return value instanceof Unit;
2823
+ }
2077
2824
 
2078
2825
  // src/typed/mathts-typed.ts
2079
2826
  import typed, { create } from "typed-function";
@@ -2115,7 +2862,14 @@ var isBigNumber2 = (x) => isBigNumber(x);
2115
2862
  var isMatrix = (x) => isObject(x) && "rows" in x && "cols" in x && "get" in x && typeof x.type === "string";
2116
2863
  var isDenseMatrix = (x) => isMatrix(x) && x.type === "DenseMatrix";
2117
2864
  var isSparseMatrix = (x) => isMatrix(x) && x.type === "SparseMatrix";
2118
- var isUnit = (x) => isObject(x) && "value" in x && "unit" in x && typeof x.type === "string";
2865
+ var isUnit2 = (x) => {
2866
+ if (!isObject(x)) return false;
2867
+ const o = x;
2868
+ if (typeof o.type !== "string") return false;
2869
+ if (o.type === "Unit" && "value" in o && "dimensions" in o) return true;
2870
+ if ("value" in o && "unit" in o) return true;
2871
+ return false;
2872
+ };
2119
2873
  var MATHTS_TYPES = [
2120
2874
  // bigint is not built into typed-function
2121
2875
  { name: "bigint", test: isBigInt },
@@ -2135,7 +2889,7 @@ var MATHTS_TYPES = [
2135
2889
  { name: "SparseMatrix", test: isSparseMatrix },
2136
2890
  { name: "Matrix", test: isMatrix },
2137
2891
  // Other types
2138
- { name: "Unit", test: isUnit }
2892
+ { name: "Unit", test: isUnit2 }
2139
2893
  ];
2140
2894
  var MATHTS_CONVERSIONS = [
2141
2895
  // -------------------------------------------------------------------------
@@ -2551,6 +3305,9 @@ var math = {
2551
3305
  // src/index.ts
2552
3306
  var VERSION = "0.1.0";
2553
3307
  export {
3308
+ ALL_UNITS,
3309
+ BASE_UNITS,
3310
+ BEST_PREFIXES,
2554
3311
  BIGNUMBER_E,
2555
3312
  BIGNUMBER_LN10,
2556
3313
  BIGNUMBER_LN2,
@@ -2565,6 +3322,9 @@ export {
2565
3322
  COMPLEX_ZERO,
2566
3323
  Complex,
2567
3324
  DEFAULT_CONFIG,
3325
+ DERIVED_UNITS,
3326
+ DIMENSIONLESS,
3327
+ DimensionMismatchError,
2568
3328
  FRACTION_HALF,
2569
3329
  FRACTION_NEG_ONE,
2570
3330
  FRACTION_ONE,
@@ -2576,12 +3336,19 @@ export {
2576
3336
  I,
2577
3337
  MATHTS_CONVERSIONS,
2578
3338
  MATHTS_TYPES,
3339
+ SI_PREFIXES,
2579
3340
  TypeRegistry,
3341
+ UNIT_ALIASES,
3342
+ Unit,
3343
+ UnitParseError,
2580
3344
  VERSION,
2581
3345
  create,
2582
3346
  createFactory,
2583
3347
  createMathTSTyped,
2584
3348
  createTypedFunction,
3349
+ dim,
3350
+ getPrefix,
3351
+ getUnitDef,
2585
3352
  initTypedWasm,
2586
3353
  isArray,
2587
3354
  isBigInt,
@@ -2599,7 +3366,8 @@ export {
2599
3366
  isString,
2600
3367
  isTypedWasmAvailable,
2601
3368
  isUndefined,
2602
- isUnit,
3369
+ isUnit2 as isUnit,
3370
+ isUnit as isUnitValue,
2603
3371
  math,
2604
3372
  mathTyped,
2605
3373
  registerNativeTypes,