@devmm/puredocs-excel-formula 1.0.9 → 1.1.1
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.cjs +70 -21
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +70 -21
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
package/dist/index.cjs
CHANGED
|
@@ -31,6 +31,13 @@ var FormulaError = /* @__PURE__ */ ((FormulaError2) => {
|
|
|
31
31
|
FormulaError2[FormulaError2["Spill"] = 9] = "Spill";
|
|
32
32
|
return FormulaError2;
|
|
33
33
|
})(FormulaError || {});
|
|
34
|
+
var DECIMAL = /^[+-]?(?:\d+\.?\d*|\.\d+)(?:[eE][+-]?\d+)?$/;
|
|
35
|
+
function numericText(text) {
|
|
36
|
+
const trimmed = text.trim();
|
|
37
|
+
if (!DECIMAL.test(trimmed)) return null;
|
|
38
|
+
const n = Number(trimmed);
|
|
39
|
+
return Number.isFinite(n) ? n : null;
|
|
40
|
+
}
|
|
34
41
|
var TailCall = class {
|
|
35
42
|
constructor(lambda, args) {
|
|
36
43
|
this.lambda = lambda;
|
|
@@ -275,7 +282,7 @@ var _FormulaValue = class _FormulaValue {
|
|
|
275
282
|
if (value2 === null || value2 === void 0) return _FormulaValue.blank;
|
|
276
283
|
if (typeof value2 === "number") return isNaN(value2) ? _FormulaValue.errorValue : _FormulaValue.number(value2);
|
|
277
284
|
if (typeof value2 === "boolean") return _FormulaValue.boolean(value2);
|
|
278
|
-
if (typeof value2 === "string") return
|
|
285
|
+
if (typeof value2 === "string") return _FormulaValue.text(value2);
|
|
279
286
|
if (value2 instanceof Date) {
|
|
280
287
|
return _FormulaValue.number(puredocsExcel.toOADate(value2));
|
|
281
288
|
}
|
|
@@ -1443,6 +1450,7 @@ var indexes = /* @__PURE__ */ new WeakMap();
|
|
|
1443
1450
|
function build(arr) {
|
|
1444
1451
|
const byText = /* @__PURE__ */ new Map();
|
|
1445
1452
|
const byNumber = /* @__PURE__ */ new Map();
|
|
1453
|
+
const byTextNumber = /* @__PURE__ */ new Map();
|
|
1446
1454
|
const classes = /* @__PURE__ */ new Map();
|
|
1447
1455
|
const addToClass = (kind, v, i2) => {
|
|
1448
1456
|
const group = classes.get(kind);
|
|
@@ -1462,6 +1470,14 @@ function build(arr) {
|
|
|
1462
1470
|
else byNumber.set(n, [i]);
|
|
1463
1471
|
} else {
|
|
1464
1472
|
addToClass(v.kind, v, i);
|
|
1473
|
+
if (v.isText) {
|
|
1474
|
+
const n = numericText(v.textValue);
|
|
1475
|
+
if (n !== null) {
|
|
1476
|
+
const atText2 = byTextNumber.get(n);
|
|
1477
|
+
if (atText2) atText2.push(i);
|
|
1478
|
+
else byTextNumber.set(n, [i]);
|
|
1479
|
+
}
|
|
1480
|
+
}
|
|
1465
1481
|
}
|
|
1466
1482
|
i++;
|
|
1467
1483
|
}
|
|
@@ -1470,7 +1486,15 @@ function build(arr) {
|
|
|
1470
1486
|
for (let k = 0; k < sortedNumbers.length; k++) {
|
|
1471
1487
|
cumulative[k + 1] = cumulative[k] + byNumber.get(sortedNumbers[k]).length;
|
|
1472
1488
|
}
|
|
1473
|
-
return {
|
|
1489
|
+
return {
|
|
1490
|
+
byText,
|
|
1491
|
+
byNumber,
|
|
1492
|
+
sortedNumbers,
|
|
1493
|
+
cumulative,
|
|
1494
|
+
byTextNumber,
|
|
1495
|
+
sortedTextNumbers: Float64Array.from(byTextNumber.keys()).sort(),
|
|
1496
|
+
classes: [...classes.values()]
|
|
1497
|
+
};
|
|
1474
1498
|
}
|
|
1475
1499
|
function indexOf(arr) {
|
|
1476
1500
|
let idx = indexes.get(arr);
|
|
@@ -1508,19 +1532,25 @@ function matchingPositions(criteriaRange, criteria, minSize) {
|
|
|
1508
1532
|
if (criteria.kind === "equalsNumber") {
|
|
1509
1533
|
const target = criteria.number;
|
|
1510
1534
|
const idx = indexOf(arr);
|
|
1511
|
-
const
|
|
1512
|
-
|
|
1513
|
-
|
|
1514
|
-
|
|
1515
|
-
|
|
1516
|
-
|
|
1517
|
-
|
|
1518
|
-
|
|
1519
|
-
|
|
1520
|
-
|
|
1535
|
+
const groups = [];
|
|
1536
|
+
const collect = (byValue, sorted) => {
|
|
1537
|
+
const exact2 = byValue.get(target);
|
|
1538
|
+
if (exact2) groups.push(exact2);
|
|
1539
|
+
for (let k = lowerBound(sorted, target - EPSILON); k < sorted.length; k++) {
|
|
1540
|
+
const value2 = sorted[k];
|
|
1541
|
+
if (value2 > target + EPSILON) break;
|
|
1542
|
+
if (value2 === target) continue;
|
|
1543
|
+
if (!criteria.test(FormulaValue.number(value2))) continue;
|
|
1544
|
+
groups.push(byValue.get(value2));
|
|
1545
|
+
}
|
|
1546
|
+
};
|
|
1547
|
+
collect(idx.byNumber, idx.sortedNumbers);
|
|
1548
|
+
collect(idx.byTextNumber, idx.sortedTextNumbers);
|
|
1521
1549
|
const blanks = criteria.test(FormulaValue.blank) ? blankPositions(idx) : void 0;
|
|
1522
|
-
if (
|
|
1523
|
-
|
|
1550
|
+
if (blanks?.length) groups.push(blanks);
|
|
1551
|
+
if (groups.length === 0) return EMPTY;
|
|
1552
|
+
if (groups.length === 1) return groups[0];
|
|
1553
|
+
const merged = groups.flat();
|
|
1524
1554
|
merged.sort((a, b) => a - b);
|
|
1525
1555
|
return merged;
|
|
1526
1556
|
}
|
|
@@ -1790,11 +1820,14 @@ function count(a, c) {
|
|
|
1790
1820
|
function countA(a, c) {
|
|
1791
1821
|
return FormulaValue.number(exports.FormulaHelper.flattenArgs(a, c).filter((v) => !v.isBlank).length);
|
|
1792
1822
|
}
|
|
1823
|
+
function isCountBlank(v) {
|
|
1824
|
+
return v.isBlank || v.isText && v.textValue === "";
|
|
1825
|
+
}
|
|
1793
1826
|
function countBlank(a, c) {
|
|
1794
1827
|
const v = a[0].evaluate(c);
|
|
1795
|
-
if (!v.isArray) return FormulaValue.number(v
|
|
1828
|
+
if (!v.isArray) return FormulaValue.number(isCountBlank(v) ? 1 : 0);
|
|
1796
1829
|
let n = 0;
|
|
1797
|
-
for (const item of v.arrayVal.values()) if (item
|
|
1830
|
+
for (const item of v.arrayVal.values()) if (isCountBlank(item)) n++;
|
|
1798
1831
|
return FormulaValue.number(n);
|
|
1799
1832
|
}
|
|
1800
1833
|
function countIf(a, c) {
|
|
@@ -1802,11 +1835,12 @@ function countIf(a, c) {
|
|
|
1802
1835
|
if (range.isError) return range;
|
|
1803
1836
|
const crit = a[1].evaluate(c);
|
|
1804
1837
|
if (crit.isError) return crit;
|
|
1805
|
-
const
|
|
1806
|
-
if (!range.isArray) return FormulaValue.number(
|
|
1838
|
+
const compiled = exports.FormulaHelper.compileCriteria(crit.asText());
|
|
1839
|
+
if (!range.isArray) return FormulaValue.number(compiled.test(range) ? 1 : 0);
|
|
1840
|
+
const countBlanks = compiled.kind === "blankness";
|
|
1807
1841
|
let n = 0;
|
|
1808
1842
|
for (const item of range.arrayVal.values()) {
|
|
1809
|
-
if (!item.isBlank &&
|
|
1843
|
+
if ((countBlanks || !item.isBlank) && compiled.test(item)) n++;
|
|
1810
1844
|
}
|
|
1811
1845
|
return FormulaValue.number(n);
|
|
1812
1846
|
}
|
|
@@ -4698,11 +4732,14 @@ exports.FormulaHelper = void 0;
|
|
|
4698
4732
|
const rhsVal = parseFloat(rhs);
|
|
4699
4733
|
const rhsNum = isNaN(rhsVal) ? null : rhsVal;
|
|
4700
4734
|
const rhsValue = rhsNum !== null ? FormulaValue.number(rhsNum) : FormulaValue.text(rhs);
|
|
4735
|
+
if (rhs === "" && op === "=") return { kind: "blankness", test: (v) => v.isBlank };
|
|
4736
|
+
if (rhs === "" && op === "<>") return { kind: "other", test: (v) => !v.isBlank };
|
|
4701
4737
|
if (op === "=") {
|
|
4702
4738
|
return rhsNum !== null ? numberEquality(rhsNum) : textEquality(rhs);
|
|
4703
4739
|
}
|
|
4704
4740
|
if (op === "<>") {
|
|
4705
|
-
|
|
4741
|
+
const equals = rhsNum !== null ? numberEquality(rhsNum) : textEquality(rhs);
|
|
4742
|
+
return { kind: "other", test: (v) => !equals.test(v) };
|
|
4706
4743
|
}
|
|
4707
4744
|
const wanted = op === ">" ? (c) => c > 0 : op === ">=" ? (c) => c >= 0 : op === "<" ? (c) => c < 0 : (c) => c <= 0;
|
|
4708
4745
|
const test = (v) => wanted(FormulaValue.compare(v, rhsValue));
|
|
@@ -4712,13 +4749,25 @@ exports.FormulaHelper = void 0;
|
|
|
4712
4749
|
const pattern = wildcardToRegex(trimmed);
|
|
4713
4750
|
return { kind: "other", test: (v) => pattern.test(v.asText()) };
|
|
4714
4751
|
}
|
|
4752
|
+
if (trimmed === "") {
|
|
4753
|
+
return { kind: "blankness", test: (v) => v.isBlank || v.isText && v.textValue === "" };
|
|
4754
|
+
}
|
|
4715
4755
|
const num5 = parseFloat(trimmed);
|
|
4716
4756
|
return isNaN(num5) ? textEquality(trimmed) : numberEquality(num5);
|
|
4717
4757
|
}
|
|
4718
4758
|
FormulaHelper2.compileCriteria = compileCriteria;
|
|
4719
4759
|
function numberEquality(n) {
|
|
4720
4760
|
const target = FormulaValue.number(n);
|
|
4721
|
-
return {
|
|
4761
|
+
return {
|
|
4762
|
+
kind: "equalsNumber",
|
|
4763
|
+
number: n,
|
|
4764
|
+
test: (v) => {
|
|
4765
|
+
if (FormulaValue.areEqual(v, target)) return true;
|
|
4766
|
+
if (!v.isText) return false;
|
|
4767
|
+
const asNumber = numericText(v.textValue);
|
|
4768
|
+
return asNumber !== null && Math.abs(asNumber - n) < 1e-10;
|
|
4769
|
+
}
|
|
4770
|
+
};
|
|
4722
4771
|
}
|
|
4723
4772
|
function textEquality(s) {
|
|
4724
4773
|
const upper2 = s.toUpperCase();
|