solve-engine 1.0.1 → 1.1.0
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/{BytecodeBuilder-B0xskcv5.d.cts → BytecodeBuilder-Bp9xeTmX.d.cts} +4 -0
- package/dist/{BytecodeBuilder-B0xskcv5.d.ts → BytecodeBuilder-Bp9xeTmX.d.ts} +4 -0
- package/dist/{Configuration-B-G5gTRn.d.cts → Configuration-C9W8tJv_.d.cts} +53 -1
- package/dist/{Configuration-B-G5gTRn.d.ts → Configuration-C9W8tJv_.d.ts} +53 -1
- package/dist/{EngineError-LU7W7AgI.d.cts → EngineError-B61GS1jp.d.cts} +14 -0
- package/dist/{EngineError-LU7W7AgI.d.ts → EngineError-B61GS1jp.d.ts} +14 -0
- package/dist/FormattingSettings-CJHyxcYu.d.cts +27 -0
- package/dist/FormattingSettings-CJHyxcYu.d.ts +27 -0
- package/dist/{Lexer-D78E2yDW.d.cts → Lexer-BOs7euZe.d.cts} +58 -1
- package/dist/{Lexer-BN5mt30n.d.ts → Lexer-CSI_lwbW.d.ts} +58 -1
- package/dist/PackageCompatibility-B-7rK1TD.d.cts +76 -0
- package/dist/PackageCompatibility-Dh59eF-X.d.ts +76 -0
- package/dist/{PackageRegistry-B37mRvvz.d.cts → PackageRegistry-BHWJP83F.d.cts} +449 -11
- package/dist/{PackageRegistry-DCUEzbQt.d.ts → PackageRegistry-_8rDlvxI.d.ts} +449 -11
- package/dist/{Parselet-BaySkMV3.d.ts → Parselet-BBT8riYh.d.ts} +12 -3
- package/dist/{Parselet-DuI1Pjiq.d.cts → Parselet-BHcgK9S7.d.cts} +12 -3
- package/dist/{ScopeManager-B6GzdhVG.d.cts → ScopeManager-8vf02dwj.d.cts} +56 -5
- package/dist/{ScopeManager-udv4Twwq.d.ts → ScopeManager-CxA24W5n.d.ts} +56 -5
- package/dist/{Token-BzG5G4ja.d.cts → Token-B1hdkedD.d.cts} +9 -0
- package/dist/{Token-BzG5G4ja.d.ts → Token-B1hdkedD.d.ts} +9 -0
- package/dist/{TokenNormalizer-t_GotBxr.d.ts → TokenNormalizer-C6VzZgHa.d.ts} +1 -1
- package/dist/{TokenNormalizer-DGVa24Q-.d.cts → TokenNormalizer-DRc1Js1V.d.cts} +1 -1
- package/dist/{VMCheckpoints-DwLjivM7.d.cts → VMCheckpoints-ELYqITdF.d.cts} +3 -3
- package/dist/{VMCheckpoints-BiaIlOOY.d.ts → VMCheckpoints-MK--EBH2.d.ts} +3 -3
- package/dist/{Value-CXJqDH9J.d.cts → Value-BUi1RA3S.d.cts} +124 -5
- package/dist/{Value-CXJqDH9J.d.ts → Value-BUi1RA3S.d.ts} +124 -5
- package/dist/WorkerError-_-RkoQ5P.d.ts +75 -0
- package/dist/WorkerError-gzmaopj2.d.cts +75 -0
- package/dist/{chunk-GQCOSXMG.js → chunk-267JPOTF.js} +43 -5
- package/dist/chunk-267JPOTF.js.map +1 -0
- package/dist/{chunk-JMXUNXQS.cjs → chunk-2TZKENDH.cjs} +51 -8
- package/dist/chunk-2TZKENDH.cjs.map +1 -0
- package/dist/chunk-3OWCDIPN.js +215 -0
- package/dist/chunk-3OWCDIPN.js.map +1 -0
- package/dist/{chunk-VB37OC6I.js → chunk-4D6NIHE2.js} +40 -3
- package/dist/chunk-4D6NIHE2.js.map +1 -0
- package/dist/{chunk-TY3TLZAW.cjs → chunk-536WPM2V.cjs} +18 -2
- package/dist/chunk-536WPM2V.cjs.map +1 -0
- package/dist/chunk-5HRB36DK.js +405 -0
- package/dist/chunk-5HRB36DK.js.map +1 -0
- package/dist/chunk-5ON7PUAZ.js +12 -0
- package/dist/chunk-5ON7PUAZ.js.map +1 -0
- package/dist/{chunk-KV7UW6T6.js → chunk-7KYSUDQO.js} +12 -5
- package/dist/chunk-7KYSUDQO.js.map +1 -0
- package/dist/{chunk-6WFMPTGB.cjs → chunk-7ZX6B7SY.cjs} +774 -528
- package/dist/chunk-7ZX6B7SY.cjs.map +1 -0
- package/dist/chunk-ALYRJ72W.cjs +434 -0
- package/dist/chunk-ALYRJ72W.cjs.map +1 -0
- package/dist/{chunk-5KMIY374.cjs → chunk-B4HBEFTB.cjs} +17 -2
- package/dist/chunk-B4HBEFTB.cjs.map +1 -0
- package/dist/chunk-B7NLZMQ3.cjs +74 -0
- package/dist/chunk-B7NLZMQ3.cjs.map +1 -0
- package/dist/{chunk-UQ3UIZJC.js → chunk-BLI4NIQY.js} +6 -2
- package/dist/chunk-BLI4NIQY.js.map +1 -0
- package/dist/{chunk-BHTNFEGZ.cjs → chunk-C75AFGVD.cjs} +11 -11
- package/dist/{chunk-BHTNFEGZ.cjs.map → chunk-C75AFGVD.cjs.map} +1 -1
- package/dist/{chunk-G535KJEG.js → chunk-CCBZZQAE.js} +2 -2
- package/dist/{chunk-G535KJEG.js.map → chunk-CCBZZQAE.js.map} +1 -1
- package/dist/chunk-CKQMXMHR.cjs +219 -0
- package/dist/chunk-CKQMXMHR.cjs.map +1 -0
- package/dist/{chunk-PFUESQTW.cjs → chunk-EJ3ILXX6.cjs} +48 -2
- package/dist/chunk-EJ3ILXX6.cjs.map +1 -0
- package/dist/{chunk-526PMQOA.js → chunk-ENKKJYD3.js} +10 -4
- package/dist/chunk-ENKKJYD3.js.map +1 -0
- package/dist/{chunk-5X2PTP6F.cjs → chunk-ENRIK36Q.cjs} +2 -12
- package/dist/chunk-ENRIK36Q.cjs.map +1 -0
- package/dist/{chunk-3D7V24DG.js → chunk-ERCOHGXD.js} +17 -2
- package/dist/chunk-ERCOHGXD.js.map +1 -0
- package/dist/{chunk-IF532O7C.js → chunk-FD5ZZHEU.js} +3 -12
- package/dist/chunk-FD5ZZHEU.js.map +1 -0
- package/dist/{chunk-TBN7DEHO.js → chunk-G7Z4HJQA.js} +11 -5
- package/dist/chunk-G7Z4HJQA.js.map +1 -0
- package/dist/{chunk-QY25VWBF.js → chunk-GQMUHVE3.js} +142 -6
- package/dist/chunk-GQMUHVE3.js.map +1 -0
- package/dist/chunk-GUG7SNSV.js +1764 -0
- package/dist/chunk-GUG7SNSV.js.map +1 -0
- package/dist/{chunk-UM6BVY2S.cjs → chunk-HIQ5HSZL.cjs} +175 -43
- package/dist/chunk-HIQ5HSZL.cjs.map +1 -0
- package/dist/{chunk-HVQFNJKE.cjs → chunk-HVRVSI2Z.cjs} +104 -86
- package/dist/chunk-HVRVSI2Z.cjs.map +1 -0
- package/dist/{chunk-3LAEG75D.js → chunk-I4GAWIPW.js} +24 -6
- package/dist/chunk-I4GAWIPW.js.map +1 -0
- package/dist/{chunk-PA4VC73I.cjs → chunk-J45BCEZ4.cjs} +33 -27
- package/dist/chunk-J45BCEZ4.cjs.map +1 -0
- package/dist/{chunk-V5PYO44Y.js → chunk-JIPATHVY.js} +1853 -2638
- package/dist/chunk-JIPATHVY.js.map +1 -0
- package/dist/{chunk-YPPPYLSR.js → chunk-JJIXHXFQ.js} +5 -5
- package/dist/{chunk-YPPPYLSR.js.map → chunk-JJIXHXFQ.js.map} +1 -1
- package/dist/chunk-L2TE7PMO.cjs +14 -0
- package/dist/chunk-L2TE7PMO.cjs.map +1 -0
- package/dist/{chunk-B7TLZABL.cjs → chunk-MG6Q3DUO.cjs} +1962 -2746
- package/dist/chunk-MG6Q3DUO.cjs.map +1 -0
- package/dist/{chunk-R3PY4G7J.js → chunk-MVTOCRV2.js} +48 -3
- package/dist/chunk-MVTOCRV2.js.map +1 -0
- package/dist/{chunk-Y7FT4IQT.js → chunk-NKW7LKYU.js} +266 -28
- package/dist/chunk-NKW7LKYU.js.map +1 -0
- package/dist/{chunk-O3ANBHSA.js → chunk-NNQ2TYDF.js} +123 -5
- package/dist/chunk-NNQ2TYDF.js.map +1 -0
- package/dist/{chunk-5F4C26RU.js → chunk-OADDUPT3.js} +4 -4
- package/dist/{chunk-5F4C26RU.js.map → chunk-OADDUPT3.js.map} +1 -1
- package/dist/{chunk-3AFRJYP4.cjs → chunk-OTN6SZOD.cjs} +1868 -393
- package/dist/chunk-OTN6SZOD.cjs.map +1 -0
- package/dist/{chunk-5LI5EPGJ.cjs → chunk-QFTDTX6K.cjs} +40 -3
- package/dist/chunk-QFTDTX6K.cjs.map +1 -0
- package/dist/{chunk-HMOISHXR.js → chunk-RRLHC37V.js} +1530 -57
- package/dist/chunk-RRLHC37V.js.map +1 -0
- package/dist/chunk-SNHVVOJK.cjs +1768 -0
- package/dist/chunk-SNHVVOJK.cjs.map +1 -0
- package/dist/{chunk-HDP7VK3C.cjs → chunk-SRGQ72IR.cjs} +649 -349
- package/dist/chunk-SRGQ72IR.cjs.map +1 -0
- package/dist/{chunk-4B2CNWQU.cjs → chunk-SSV46KFA.cjs} +14 -7
- package/dist/chunk-SSV46KFA.cjs.map +1 -0
- package/dist/{chunk-AJA6LUI7.js → chunk-UO6BUV6K.js} +18 -2
- package/dist/chunk-UO6BUV6K.js.map +1 -0
- package/dist/chunk-WWQEY7BV.js +67 -0
- package/dist/chunk-WWQEY7BV.js.map +1 -0
- package/dist/{chunk-5WVP4YHP.js → chunk-WXEHD6TT.js} +333 -33
- package/dist/chunk-WXEHD6TT.js.map +1 -0
- package/dist/{chunk-47LRVGOT.cjs → chunk-XA4CKRML.cjs} +2 -2
- package/dist/{chunk-47LRVGOT.cjs.map → chunk-XA4CKRML.cjs.map} +1 -1
- package/dist/{chunk-6KFYJ6TD.cjs → chunk-XIYYHA65.cjs} +6 -2
- package/dist/chunk-XIYYHA65.cjs.map +1 -0
- package/dist/{chunk-KBSXGXPM.cjs → chunk-XJGJCF2R.cjs} +6 -6
- package/dist/{chunk-KBSXGXPM.cjs.map → chunk-XJGJCF2R.cjs.map} +1 -1
- package/dist/{chunk-YWQ6V4ZN.cjs → chunk-YTIYVHL7.cjs} +211 -75
- package/dist/chunk-YTIYVHL7.cjs.map +1 -0
- package/dist/{chunk-TMA4RCEN.js → chunk-Z7XGGLI2.js} +3 -3
- package/dist/{chunk-TMA4RCEN.js.map → chunk-Z7XGGLI2.js.map} +1 -1
- package/dist/{chunk-A2N2GFCG.cjs → chunk-ZVTWQLK4.cjs} +10 -10
- package/dist/{chunk-A2N2GFCG.cjs.map → chunk-ZVTWQLK4.cjs.map} +1 -1
- package/dist/{chunk-2XLQPQKI.cjs → chunk-ZXCESUJS.cjs} +15 -9
- package/dist/chunk-ZXCESUJS.cjs.map +1 -0
- package/dist/constants.cjs +5 -5
- package/dist/constants.d.cts +1 -1
- package/dist/constants.d.ts +1 -1
- package/dist/constants.js +2 -2
- package/dist/engine.cjs +52 -35
- package/dist/engine.d.cts +13 -13
- package/dist/engine.d.ts +13 -13
- package/dist/engine.js +26 -21
- package/dist/errors.cjs +44 -19
- package/dist/errors.d.cts +3 -2
- package/dist/errors.d.ts +3 -2
- package/dist/errors.js +2 -1
- package/dist/format.cjs +19 -169
- package/dist/format.cjs.map +1 -1
- package/dist/format.d.cts +18 -26
- package/dist/format.d.ts +18 -26
- package/dist/format.js +7 -171
- package/dist/format.js.map +1 -1
- package/dist/index.cjs +250 -31
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +110 -74
- package/dist/index.d.ts +110 -74
- package/dist/index.js +228 -23
- package/dist/index.js.map +1 -1
- package/dist/language.cjs +9 -9
- package/dist/language.d.cts +12 -12
- package/dist/language.d.ts +12 -12
- package/dist/language.js +3 -3
- package/dist/lexer.cjs +16 -16
- package/dist/lexer.d.cts +3 -3
- package/dist/lexer.d.ts +3 -3
- package/dist/lexer.js +5 -5
- package/dist/normalizer.cjs +10 -10
- package/dist/normalizer.d.cts +3 -3
- package/dist/normalizer.d.ts +3 -3
- package/dist/normalizer.js +4 -4
- package/dist/packages.cjs +45 -36
- package/dist/packages.d.cts +135 -31
- package/dist/packages.d.ts +135 -31
- package/dist/packages.js +14 -13
- package/dist/parser.cjs +16 -16
- package/dist/parser.d.cts +6 -5
- package/dist/parser.d.ts +6 -5
- package/dist/parser.js +6 -6
- package/dist/{pipeline-BEb3hujr.d.cts → pipeline-CtfJtPQc.d.cts} +3 -3
- package/dist/{pipeline-B6k5lCB7.d.ts → pipeline-DCd5M6Gk.d.ts} +3 -3
- package/dist/resolvers.d.cts +3 -3
- package/dist/resolvers.d.ts +3 -3
- package/dist/testing.cjs +478 -0
- package/dist/testing.cjs.map +1 -0
- package/dist/testing.d.cts +271 -0
- package/dist/testing.d.ts +271 -0
- package/dist/testing.js +470 -0
- package/dist/testing.js.map +1 -0
- package/dist/uom.cjs +16 -16
- package/dist/uom.d.cts +3 -3
- package/dist/uom.d.ts +3 -3
- package/dist/uom.js +6 -6
- package/dist/utilities.cjs +6 -5
- package/dist/utilities.js +2 -1
- package/dist/vm.cjs +34 -34
- package/dist/vm.d.cts +8 -8
- package/dist/vm.d.ts +8 -8
- package/dist/vm.js +9 -9
- package/dist/worker.cjs +493 -0
- package/dist/worker.cjs.map +1 -0
- package/dist/worker.d.cts +509 -0
- package/dist/worker.d.ts +509 -0
- package/dist/worker.js +484 -0
- package/dist/worker.js.map +1 -0
- package/package.json +21 -1
- package/dist/chunk-2XLQPQKI.cjs.map +0 -1
- package/dist/chunk-3AFRJYP4.cjs.map +0 -1
- package/dist/chunk-3D7V24DG.js.map +0 -1
- package/dist/chunk-3LAEG75D.js.map +0 -1
- package/dist/chunk-4B2CNWQU.cjs.map +0 -1
- package/dist/chunk-526PMQOA.js.map +0 -1
- package/dist/chunk-5KMIY374.cjs.map +0 -1
- package/dist/chunk-5LI5EPGJ.cjs.map +0 -1
- package/dist/chunk-5WVP4YHP.js.map +0 -1
- package/dist/chunk-5X2PTP6F.cjs.map +0 -1
- package/dist/chunk-6KFYJ6TD.cjs.map +0 -1
- package/dist/chunk-6WFMPTGB.cjs.map +0 -1
- package/dist/chunk-AJA6LUI7.js.map +0 -1
- package/dist/chunk-B7TLZABL.cjs.map +0 -1
- package/dist/chunk-GQCOSXMG.js.map +0 -1
- package/dist/chunk-HDP7VK3C.cjs.map +0 -1
- package/dist/chunk-HMOISHXR.js.map +0 -1
- package/dist/chunk-HVQFNJKE.cjs.map +0 -1
- package/dist/chunk-IF532O7C.js.map +0 -1
- package/dist/chunk-JMXUNXQS.cjs.map +0 -1
- package/dist/chunk-KV7UW6T6.js.map +0 -1
- package/dist/chunk-O3ANBHSA.js.map +0 -1
- package/dist/chunk-PA4VC73I.cjs.map +0 -1
- package/dist/chunk-PFUESQTW.cjs.map +0 -1
- package/dist/chunk-QY25VWBF.js.map +0 -1
- package/dist/chunk-R3PY4G7J.js.map +0 -1
- package/dist/chunk-TBN7DEHO.js.map +0 -1
- package/dist/chunk-TY3TLZAW.cjs.map +0 -1
- package/dist/chunk-UM6BVY2S.cjs.map +0 -1
- package/dist/chunk-UQ3UIZJC.js.map +0 -1
- package/dist/chunk-V5PYO44Y.js.map +0 -1
- package/dist/chunk-VB37OC6I.js.map +0 -1
- package/dist/chunk-Y7FT4IQT.js.map +0 -1
- package/dist/chunk-YWQ6V4ZN.cjs.map +0 -1
|
@@ -1,45 +1,49 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
var
|
|
4
|
-
var
|
|
3
|
+
var chunkJ45BCEZ4_cjs = require('./chunk-J45BCEZ4.cjs');
|
|
4
|
+
var chunkC75AFGVD_cjs = require('./chunk-C75AFGVD.cjs');
|
|
5
5
|
var chunkADBA3XBE_cjs = require('./chunk-ADBA3XBE.cjs');
|
|
6
|
-
var
|
|
6
|
+
var chunkSSV46KFA_cjs = require('./chunk-SSV46KFA.cjs');
|
|
7
7
|
var chunkZ2XP767T_cjs = require('./chunk-Z2XP767T.cjs');
|
|
8
|
-
var
|
|
8
|
+
var chunk7ZX6B7SY_cjs = require('./chunk-7ZX6B7SY.cjs');
|
|
9
|
+
var chunkZVTWQLK4_cjs = require('./chunk-ZVTWQLK4.cjs');
|
|
9
10
|
var chunkVEKIWQ3F_cjs = require('./chunk-VEKIWQ3F.cjs');
|
|
10
|
-
var
|
|
11
|
-
var
|
|
12
|
-
var
|
|
13
|
-
var
|
|
14
|
-
var
|
|
11
|
+
var chunkALYRJ72W_cjs = require('./chunk-ALYRJ72W.cjs');
|
|
12
|
+
var chunkHIQ5HSZL_cjs = require('./chunk-HIQ5HSZL.cjs');
|
|
13
|
+
var chunk2TZKENDH_cjs = require('./chunk-2TZKENDH.cjs');
|
|
14
|
+
var chunkEJ3ILXX6_cjs = require('./chunk-EJ3ILXX6.cjs');
|
|
15
|
+
var chunkYTIYVHL7_cjs = require('./chunk-YTIYVHL7.cjs');
|
|
16
|
+
var chunkQFTDTX6K_cjs = require('./chunk-QFTDTX6K.cjs');
|
|
15
17
|
var chunkOUHT5Z36_cjs = require('./chunk-OUHT5Z36.cjs');
|
|
16
18
|
var chunkAQNHHJMJ_cjs = require('./chunk-AQNHHJMJ.cjs');
|
|
17
19
|
var chunkAMOJYLG2_cjs = require('./chunk-AMOJYLG2.cjs');
|
|
18
|
-
var
|
|
20
|
+
var chunkB4HBEFTB_cjs = require('./chunk-B4HBEFTB.cjs');
|
|
19
21
|
|
|
20
22
|
// src/packages/arithmetic/parselets/NumberParselet.ts
|
|
21
23
|
var CHAINED_DOT_THOUSANDS_GROUPS = /^\d{1,3}(\.\d{3}){2,}$/;
|
|
24
|
+
var PLAIN_DECIMAL = /^\d*\.\d*$/;
|
|
22
25
|
var NumberParselet = class {
|
|
23
26
|
constructor() {
|
|
24
27
|
this.category = "Arithmetic";
|
|
25
28
|
}
|
|
26
29
|
parse(parser, token, builder) {
|
|
27
30
|
let v;
|
|
31
|
+
let decimalText = null;
|
|
28
32
|
const raw = token.value;
|
|
29
33
|
if (raw.startsWith("0x") || raw.startsWith("0X")) {
|
|
30
34
|
v = parseInt(raw, 16);
|
|
31
35
|
if (Number.isNaN(v)) {
|
|
32
|
-
throw
|
|
36
|
+
throw chunkB4HBEFTB_cjs.ErrorFactory.parsing("INVALID_NUMBER_LITERAL", `Invalid hex literal: "${raw}"`, { raw });
|
|
33
37
|
}
|
|
34
38
|
} else if (raw.startsWith("0b") || raw.startsWith("0B")) {
|
|
35
39
|
v = parseInt(raw.slice(2), 2);
|
|
36
40
|
if (Number.isNaN(v)) {
|
|
37
|
-
throw
|
|
41
|
+
throw chunkB4HBEFTB_cjs.ErrorFactory.parsing("INVALID_NUMBER_LITERAL", `Invalid binary literal: "${raw}"`, { raw });
|
|
38
42
|
}
|
|
39
43
|
} else if (raw.startsWith("0o") || raw.startsWith("0O")) {
|
|
40
44
|
v = parseInt(raw.slice(2), 8);
|
|
41
45
|
if (Number.isNaN(v)) {
|
|
42
|
-
throw
|
|
46
|
+
throw chunkB4HBEFTB_cjs.ErrorFactory.parsing("INVALID_NUMBER_LITERAL", `Invalid octal literal: "${raw}"`, { raw });
|
|
43
47
|
}
|
|
44
48
|
} else if (CHAINED_DOT_THOUSANDS_GROUPS.test(raw)) {
|
|
45
49
|
v = parseFloat(raw.split(".").join(""));
|
|
@@ -55,6 +59,12 @@ var NumberParselet = class {
|
|
|
55
59
|
normalized = normalized.replace(decimalSep, ".");
|
|
56
60
|
}
|
|
57
61
|
v = parseFloat(normalized);
|
|
62
|
+
if (PLAIN_DECIMAL.test(normalized)) decimalText = normalized;
|
|
63
|
+
}
|
|
64
|
+
if (decimalText !== null) {
|
|
65
|
+
builder.emitOpcode(16 /* PUSH_DECIMAL */);
|
|
66
|
+
builder.emitString(decimalText);
|
|
67
|
+
return;
|
|
58
68
|
}
|
|
59
69
|
builder.emitOpcode(10 /* PUSH_NUMBER */);
|
|
60
70
|
builder.emitNumber(v);
|
|
@@ -141,7 +151,7 @@ var WORD_MAGNITUDE = {
|
|
|
141
151
|
trillions: 12,
|
|
142
152
|
tn: 12
|
|
143
153
|
};
|
|
144
|
-
var
|
|
154
|
+
var PLAIN_DECIMAL2 = /^\d+(\.\d+)?$/;
|
|
145
155
|
function scaleDecimalString(raw, magnitude) {
|
|
146
156
|
const dotIdx = raw.indexOf(".");
|
|
147
157
|
const intPart = dotIdx === -1 ? raw : raw.slice(0, dotIdx);
|
|
@@ -160,7 +170,7 @@ function largeNumberSuffixNormalizerRule(priority = 65) {
|
|
|
160
170
|
match(tokens, pos) {
|
|
161
171
|
const numberToken = tokens[pos];
|
|
162
172
|
if (numberToken.type !== "NUMBER") return null;
|
|
163
|
-
if (!
|
|
173
|
+
if (!PLAIN_DECIMAL2.test(numberToken.text)) return null;
|
|
164
174
|
const suffixToken = tokens[pos + 1];
|
|
165
175
|
if (!suffixToken) return null;
|
|
166
176
|
if (suffixToken.type !== "IDENT" && suffixToken.type !== "UNIT") return null;
|
|
@@ -171,7 +181,7 @@ function largeNumberSuffixNormalizerRule(priority = 65) {
|
|
|
171
181
|
const scaled = scaleDecimalString(numberToken.text, magnitude);
|
|
172
182
|
return {
|
|
173
183
|
consumed: 2,
|
|
174
|
-
replacement: [
|
|
184
|
+
replacement: [chunkC75AFGVD_cjs.createFusedToken("NUMBER", scaled, tokens.slice(pos, pos + 2))],
|
|
175
185
|
ruleName: "arithmetic:large-number-suffix"
|
|
176
186
|
};
|
|
177
187
|
}
|
|
@@ -194,35 +204,35 @@ var ARITHMETIC_PACKAGE = {
|
|
|
194
204
|
{ tokenType: "BIT_NOT", parselet: new PrefixOpParselet(36 /* BIT_NOT */) }
|
|
195
205
|
],
|
|
196
206
|
infixParselets: [
|
|
197
|
-
{ tokenType: "PLUS", parselet: new BinaryOpParselet(
|
|
207
|
+
{ tokenType: "PLUS", parselet: new BinaryOpParselet(chunkJ45BCEZ4_cjs.BindingPower.Sum, 20 /* ADD */) },
|
|
198
208
|
// The word "and", which adds exactly like "+" but at a looser binding
|
|
199
209
|
// power so a phrase parselet can use it as a list separator. See
|
|
200
210
|
// Token.ts's AND_CONJ comment for why it is not simply mapped to PLUS.
|
|
201
|
-
{ tokenType: "AND_CONJ", parselet: new BinaryOpParselet(
|
|
202
|
-
{ tokenType: "MINUS", parselet: new BinaryOpParselet(
|
|
203
|
-
{ tokenType: "STAR", parselet: new BinaryOpParselet(
|
|
204
|
-
{ tokenType: "SLASH", parselet: new BinaryOpParselet(
|
|
205
|
-
{ tokenType: "MOD", parselet: new BinaryOpParselet(
|
|
211
|
+
{ tokenType: "AND_CONJ", parselet: new BinaryOpParselet(chunkJ45BCEZ4_cjs.BindingPower.Conjunction, 20 /* ADD */) },
|
|
212
|
+
{ tokenType: "MINUS", parselet: new BinaryOpParselet(chunkJ45BCEZ4_cjs.BindingPower.Sum, 21 /* SUB */) },
|
|
213
|
+
{ tokenType: "STAR", parselet: new BinaryOpParselet(chunkJ45BCEZ4_cjs.BindingPower.Product, 22 /* MUL */) },
|
|
214
|
+
{ tokenType: "SLASH", parselet: new BinaryOpParselet(chunkJ45BCEZ4_cjs.BindingPower.Product, 23 /* DIV */) },
|
|
215
|
+
{ tokenType: "MOD", parselet: new BinaryOpParselet(chunkJ45BCEZ4_cjs.BindingPower.Product, 24 /* MOD */) },
|
|
206
216
|
// `^` is right-associative, so "2 ^ 3 ^ 2" is 2^(3^2) = 512. The Tier 1
|
|
207
217
|
// fast path in PrecedenceParser is what actually runs for `^`; this
|
|
208
218
|
// registration has to agree with it or the two tiers describe different
|
|
209
219
|
// languages.
|
|
210
|
-
{ tokenType: "CARET", parselet: new BinaryOpParselet(
|
|
211
|
-
{ tokenType: "TIMES_BY", parselet: new BinaryOpParselet(
|
|
212
|
-
{ tokenType: "MULTIPLY_BY", parselet: new BinaryOpParselet(
|
|
213
|
-
{ tokenType: "DIVIDE_BY", parselet: new BinaryOpParselet(
|
|
220
|
+
{ tokenType: "CARET", parselet: new BinaryOpParselet(chunkJ45BCEZ4_cjs.BindingPower.Exponent, 25 /* EXP */, true) },
|
|
221
|
+
{ tokenType: "TIMES_BY", parselet: new BinaryOpParselet(chunkJ45BCEZ4_cjs.BindingPower.Product, 22 /* MUL */) },
|
|
222
|
+
{ tokenType: "MULTIPLY_BY", parselet: new BinaryOpParselet(chunkJ45BCEZ4_cjs.BindingPower.Product, 22 /* MUL */) },
|
|
223
|
+
{ tokenType: "DIVIDE_BY", parselet: new BinaryOpParselet(chunkJ45BCEZ4_cjs.BindingPower.Product, 23 /* DIV */) },
|
|
214
224
|
// The shifts and the bitwise trio, at the levels BindingPower gives them
|
|
215
225
|
// and therefore at C and JavaScript precedence. These six are declared
|
|
216
226
|
// twice, here and in BUILTIN_INFIX_BP, and only the Tier 1 numbers are
|
|
217
227
|
// ever read, so the levels must be the SAME names in both places. When
|
|
218
228
|
// they were not, the four that had a fast-path entry ran at one level
|
|
219
229
|
// while `>>>`, which had none, ran at another.
|
|
220
|
-
{ tokenType: "LSHIFT", parselet: new BinaryOpParselet(
|
|
221
|
-
{ tokenType: "RSHIFT", parselet: new BinaryOpParselet(
|
|
222
|
-
{ tokenType: "URSHIFT", parselet: new BinaryOpParselet(
|
|
223
|
-
{ tokenType: "BIT_AND", parselet: new BinaryOpParselet(
|
|
224
|
-
{ tokenType: "BIT_OR", parselet: new BinaryOpParselet(
|
|
225
|
-
{ tokenType: "BIT_XOR", parselet: new BinaryOpParselet(
|
|
230
|
+
{ tokenType: "LSHIFT", parselet: new BinaryOpParselet(chunkJ45BCEZ4_cjs.BindingPower.Shift, 30 /* LSHIFT */) },
|
|
231
|
+
{ tokenType: "RSHIFT", parselet: new BinaryOpParselet(chunkJ45BCEZ4_cjs.BindingPower.Shift, 31 /* RSHIFT */) },
|
|
232
|
+
{ tokenType: "URSHIFT", parselet: new BinaryOpParselet(chunkJ45BCEZ4_cjs.BindingPower.Shift, 32 /* URSHIFT */) },
|
|
233
|
+
{ tokenType: "BIT_AND", parselet: new BinaryOpParselet(chunkJ45BCEZ4_cjs.BindingPower.BitwiseAnd, 33 /* BIT_AND */) },
|
|
234
|
+
{ tokenType: "BIT_OR", parselet: new BinaryOpParselet(chunkJ45BCEZ4_cjs.BindingPower.BitwiseOr, 34 /* BIT_OR */) },
|
|
235
|
+
{ tokenType: "BIT_XOR", parselet: new BinaryOpParselet(chunkJ45BCEZ4_cjs.BindingPower.BitwiseXor, 35 /* BIT_XOR */) }
|
|
226
236
|
],
|
|
227
237
|
normalizerRules: [largeNumberSuffixNormalizerRule()]
|
|
228
238
|
};
|
|
@@ -231,7 +241,7 @@ var ARITHMETIC_PACKAGE = {
|
|
|
231
241
|
var PercentParselet = class {
|
|
232
242
|
constructor() {
|
|
233
243
|
this.category = "Percentage";
|
|
234
|
-
this.bindingPower =
|
|
244
|
+
this.bindingPower = chunkJ45BCEZ4_cjs.BindingPower.Prefix;
|
|
235
245
|
}
|
|
236
246
|
parse(parser, left, token, builder) {
|
|
237
247
|
builder.emitOpcode(10 /* PUSH_NUMBER */);
|
|
@@ -247,7 +257,7 @@ var IsWhatParselet = class {
|
|
|
247
257
|
this.category = "Percentage";
|
|
248
258
|
// Below arithmetic, so the whole expression to the left is the value being
|
|
249
259
|
// asked about: `10 + 10 is what % of 200` asks about 20.
|
|
250
|
-
this.bindingPower =
|
|
260
|
+
this.bindingPower = chunkJ45BCEZ4_cjs.BindingPower.Conditional;
|
|
251
261
|
}
|
|
252
262
|
parse(parser, _left, _token, builder) {
|
|
253
263
|
if (nextWordIs(parser, "what")) {
|
|
@@ -262,7 +272,7 @@ var IsWhatParselet = class {
|
|
|
262
272
|
*/
|
|
263
273
|
parseWhatRate(parser, builder) {
|
|
264
274
|
if (!parser.match("PERCENT")) {
|
|
265
|
-
throw
|
|
275
|
+
throw chunkB4HBEFTB_cjs.ErrorFactory.parsing(
|
|
266
276
|
"IS_WHAT_EXPECTED_PERCENT",
|
|
267
277
|
'Expected "%" after "is what", as in "20 is what % of 200"'
|
|
268
278
|
);
|
|
@@ -272,7 +282,7 @@ var IsWhatParselet = class {
|
|
|
272
282
|
builder.emitOpcode(74 /* TO_PERCENTAGE */);
|
|
273
283
|
return;
|
|
274
284
|
}
|
|
275
|
-
parser.parseExpression(
|
|
285
|
+
parser.parseExpression(chunkJ45BCEZ4_cjs.BindingPower.Conditional, builder);
|
|
276
286
|
builder.emitOpcode(23 /* DIV */);
|
|
277
287
|
if (preposition === "off") {
|
|
278
288
|
builder.emitOpcode(10 /* PUSH_NUMBER */);
|
|
@@ -290,7 +300,7 @@ var IsWhatParselet = class {
|
|
|
290
300
|
* `<part> is <rate> of|off|on what`, solving for the base.
|
|
291
301
|
*/
|
|
292
302
|
parseWhatBase(parser, builder) {
|
|
293
|
-
parser.parseExpression(
|
|
303
|
+
parser.parseExpression(chunkJ45BCEZ4_cjs.BindingPower.Conditional, builder);
|
|
294
304
|
if (parser.match("TO")) {
|
|
295
305
|
expectWord(parser, "what", '"81 is 9 to what power"');
|
|
296
306
|
expectWord(parser, "power", '"81 is 9 to what power"');
|
|
@@ -307,7 +317,7 @@ var IsWhatParselet = class {
|
|
|
307
317
|
}
|
|
308
318
|
const preposition = parser.match("OF_WHAT") ? "of" : parser.match("OFF_WHAT") ? "off" : parser.match("ON_WHAT") ? "on" : null;
|
|
309
319
|
if (preposition === null) {
|
|
310
|
-
throw
|
|
320
|
+
throw chunkB4HBEFTB_cjs.ErrorFactory.parsing(
|
|
311
321
|
"IS_WHAT_EXPECTED_PREPOSITION",
|
|
312
322
|
'Expected "of what", "off what" or "on what", as in "20 is 10% of what"'
|
|
313
323
|
);
|
|
@@ -333,7 +343,7 @@ function nextWordIs(parser, word) {
|
|
|
333
343
|
}
|
|
334
344
|
function expectWord(parser, word, example) {
|
|
335
345
|
if (!nextWordIs(parser, word)) {
|
|
336
|
-
throw
|
|
346
|
+
throw chunkB4HBEFTB_cjs.ErrorFactory.parsing(
|
|
337
347
|
"IS_WHAT_EXPECTED_WORD",
|
|
338
348
|
`Expected "${word}" here, as in ${example}`
|
|
339
349
|
);
|
|
@@ -356,10 +366,10 @@ var OnOffBaseParselet = class {
|
|
|
356
366
|
constructor(sign) {
|
|
357
367
|
this.sign = sign;
|
|
358
368
|
this.category = "Percentage";
|
|
359
|
-
this.bindingPower =
|
|
369
|
+
this.bindingPower = chunkJ45BCEZ4_cjs.BindingPower.Conditional;
|
|
360
370
|
}
|
|
361
371
|
parse(parser, _left, _token, builder) {
|
|
362
|
-
parser.parseExpression(
|
|
372
|
+
parser.parseExpression(chunkJ45BCEZ4_cjs.BindingPower.Conditional, builder);
|
|
363
373
|
builder.emitOpcode(2 /* SWAP */);
|
|
364
374
|
builder.emitOpcode(10 /* PUSH_NUMBER */);
|
|
365
375
|
builder.emitNumber(1);
|
|
@@ -390,7 +400,7 @@ function percentOnOffNormalizerRule(priority = 68) {
|
|
|
390
400
|
consumed: 2,
|
|
391
401
|
replacement: [
|
|
392
402
|
tokens[pos],
|
|
393
|
-
|
|
403
|
+
chunkC75AFGVD_cjs.createFusedToken(text === "on" ? "PCT_ON" : "PCT_OFF", text, [word])
|
|
394
404
|
],
|
|
395
405
|
ruleName: "percentage:on-off"
|
|
396
406
|
};
|
|
@@ -402,7 +412,7 @@ function percentOnOffNormalizerRule(priority = 68) {
|
|
|
402
412
|
var OfParselet = class {
|
|
403
413
|
constructor() {
|
|
404
414
|
this.category = "Percentage";
|
|
405
|
-
this.bindingPower =
|
|
415
|
+
this.bindingPower = chunkJ45BCEZ4_cjs.BindingPower.Product;
|
|
406
416
|
}
|
|
407
417
|
parse(parser, left, token, builder) {
|
|
408
418
|
parser.parseExpression(this.bindingPower, builder);
|
|
@@ -414,7 +424,7 @@ var OfParselet = class {
|
|
|
414
424
|
var OfWhatIsParselet = class {
|
|
415
425
|
constructor() {
|
|
416
426
|
this.category = "Percentage";
|
|
417
|
-
this.bindingPower =
|
|
427
|
+
this.bindingPower = chunkJ45BCEZ4_cjs.BindingPower.Product;
|
|
418
428
|
}
|
|
419
429
|
parse(parser, left, token, builder) {
|
|
420
430
|
parser.parseExpression(this.bindingPower, builder);
|
|
@@ -428,7 +438,7 @@ var OnOffWhatIsParselet = class {
|
|
|
428
438
|
constructor(sign) {
|
|
429
439
|
this.sign = sign;
|
|
430
440
|
this.category = "Percentage";
|
|
431
|
-
this.bindingPower =
|
|
441
|
+
this.bindingPower = chunkJ45BCEZ4_cjs.BindingPower.Product;
|
|
432
442
|
}
|
|
433
443
|
parse(parser, left, token, builder) {
|
|
434
444
|
builder.emitOpcode(10 /* PUSH_NUMBER */);
|
|
@@ -471,7 +481,7 @@ var IncreaseByParselet = class {
|
|
|
471
481
|
constructor(multiplier) {
|
|
472
482
|
this.multiplier = multiplier;
|
|
473
483
|
this.category = "Percentage";
|
|
474
|
-
this.bindingPower =
|
|
484
|
+
this.bindingPower = chunkJ45BCEZ4_cjs.BindingPower.Conditional;
|
|
475
485
|
}
|
|
476
486
|
parse(parser, left, token, builder) {
|
|
477
487
|
parser.parseExpression(this.bindingPower, builder);
|
|
@@ -487,7 +497,7 @@ var IncreaseByParselet = class {
|
|
|
487
497
|
var PercentageChangeParselet = class {
|
|
488
498
|
constructor() {
|
|
489
499
|
this.category = "Percentage";
|
|
490
|
-
this.bindingPower =
|
|
500
|
+
this.bindingPower = chunkJ45BCEZ4_cjs.BindingPower.Conditional;
|
|
491
501
|
}
|
|
492
502
|
parse(parser, left, token, builder) {
|
|
493
503
|
if (left.type === "UNIT") {
|
|
@@ -511,6 +521,119 @@ var PercentageChangeParselet = class {
|
|
|
511
521
|
}
|
|
512
522
|
};
|
|
513
523
|
|
|
524
|
+
// src/packages/percentage/parselets/UpDownParselet.ts
|
|
525
|
+
var COUNT_WORDS = {
|
|
526
|
+
one: 1,
|
|
527
|
+
two: 2,
|
|
528
|
+
three: 3,
|
|
529
|
+
four: 4,
|
|
530
|
+
five: 5,
|
|
531
|
+
six: 6,
|
|
532
|
+
seven: 7,
|
|
533
|
+
eight: 8,
|
|
534
|
+
nine: 9,
|
|
535
|
+
ten: 10,
|
|
536
|
+
eleven: 11,
|
|
537
|
+
twelve: 12
|
|
538
|
+
};
|
|
539
|
+
function resolveCount(token) {
|
|
540
|
+
if (token.type === "NUMBER") {
|
|
541
|
+
const n = Number(token.value);
|
|
542
|
+
return Number.isInteger(n) && n >= 0 ? n : null;
|
|
543
|
+
}
|
|
544
|
+
if (token.type === "IDENT") {
|
|
545
|
+
return COUNT_WORDS[token.value.toLowerCase()] ?? null;
|
|
546
|
+
}
|
|
547
|
+
return null;
|
|
548
|
+
}
|
|
549
|
+
var UpDownParselet = class {
|
|
550
|
+
/** @param sign `1` for `up` (grow), `-1` for `down` (shrink). */
|
|
551
|
+
constructor(sign) {
|
|
552
|
+
this.sign = sign;
|
|
553
|
+
this.category = "Percentage";
|
|
554
|
+
this.bindingPower = chunkJ45BCEZ4_cjs.BindingPower.Conditional;
|
|
555
|
+
}
|
|
556
|
+
parse(parser, _left, _token, builder) {
|
|
557
|
+
parser.parseExpression(this.bindingPower, builder);
|
|
558
|
+
builder.emitOpcode(10 /* PUSH_NUMBER */);
|
|
559
|
+
builder.emitNumber(1);
|
|
560
|
+
builder.emitOpcode(2 /* SWAP */);
|
|
561
|
+
builder.emitOpcode(this.sign > 0 ? 20 /* ADD */ : 21 /* SUB */);
|
|
562
|
+
const repeat = this.tryConsumeRepeat(parser);
|
|
563
|
+
if (repeat !== null) {
|
|
564
|
+
builder.emitOpcode(10 /* PUSH_NUMBER */);
|
|
565
|
+
builder.emitNumber(repeat);
|
|
566
|
+
builder.emitOpcode(25 /* EXP */);
|
|
567
|
+
}
|
|
568
|
+
builder.emitOpcode(22 /* MUL */);
|
|
569
|
+
this.consumeChainThen(parser);
|
|
570
|
+
}
|
|
571
|
+
/**
|
|
572
|
+
* Consume a trailing `N times` (`3 times`, `three times`) if present,
|
|
573
|
+
* returning the count, or `null` when there is no repeat here. The word
|
|
574
|
+
* "times" lexes as the multiply token but keeps its source text, which is
|
|
575
|
+
* what tells it apart from a literal `*`.
|
|
576
|
+
*/
|
|
577
|
+
tryConsumeRepeat(parser) {
|
|
578
|
+
const countTok = parser.peek();
|
|
579
|
+
const timesTok = parser.peekAt(1);
|
|
580
|
+
if (!countTok || !timesTok) return null;
|
|
581
|
+
if (timesTok.type !== "STAR" || timesTok.value.toLowerCase() !== "times") return null;
|
|
582
|
+
const count = resolveCount(countTok);
|
|
583
|
+
if (count === null) return null;
|
|
584
|
+
parser.consume();
|
|
585
|
+
parser.consume();
|
|
586
|
+
return count;
|
|
587
|
+
}
|
|
588
|
+
/** Drop a connective `then` that sits directly before the next step. */
|
|
589
|
+
consumeChainThen(parser) {
|
|
590
|
+
if (parser.peek()?.type !== "THEN") return;
|
|
591
|
+
const next = parser.peekAt(1)?.type;
|
|
592
|
+
if (next === "PCT_UP" || next === "PCT_DOWN") {
|
|
593
|
+
parser.consume();
|
|
594
|
+
}
|
|
595
|
+
}
|
|
596
|
+
};
|
|
597
|
+
|
|
598
|
+
// src/packages/percentage/normalizer/PercentUpDownNormalizerRule.ts
|
|
599
|
+
function stepTokenAt(tokens, i) {
|
|
600
|
+
const word = tokens[i];
|
|
601
|
+
if (word?.type !== "IDENT") return null;
|
|
602
|
+
const text = (word.text ?? word.value ?? "").toLowerCase();
|
|
603
|
+
if (text !== "up" && text !== "down") return null;
|
|
604
|
+
if (tokens[i + 1]?.type !== "NUMBER") return null;
|
|
605
|
+
if (tokens[i + 2]?.type !== "PERCENT") return null;
|
|
606
|
+
return chunkC75AFGVD_cjs.createFusedToken(text === "up" ? "PCT_UP" : "PCT_DOWN", text, [word]);
|
|
607
|
+
}
|
|
608
|
+
function percentUpDownNormalizerRule(priority = 68) {
|
|
609
|
+
return {
|
|
610
|
+
name: "percentage:up-down",
|
|
611
|
+
priority,
|
|
612
|
+
match(tokens, pos) {
|
|
613
|
+
const here = tokens[pos];
|
|
614
|
+
if (here && (here.type === "NUMBER" || here.type === "RPAREN")) {
|
|
615
|
+
const step2 = stepTokenAt(tokens, pos + 1);
|
|
616
|
+
if (step2) {
|
|
617
|
+
return {
|
|
618
|
+
consumed: 2,
|
|
619
|
+
replacement: [here, step2],
|
|
620
|
+
ruleName: "percentage:up-down"
|
|
621
|
+
};
|
|
622
|
+
}
|
|
623
|
+
}
|
|
624
|
+
const step = stepTokenAt(tokens, pos);
|
|
625
|
+
if (step) {
|
|
626
|
+
return {
|
|
627
|
+
consumed: 1,
|
|
628
|
+
replacement: [step],
|
|
629
|
+
ruleName: "percentage:up-down"
|
|
630
|
+
};
|
|
631
|
+
}
|
|
632
|
+
return null;
|
|
633
|
+
}
|
|
634
|
+
};
|
|
635
|
+
}
|
|
636
|
+
|
|
514
637
|
// src/packages/percentage/PercentagePackage.ts
|
|
515
638
|
var PERCENTAGE_PACKAGE = {
|
|
516
639
|
name: "solve-percentage",
|
|
@@ -538,14 +661,18 @@ var PERCENTAGE_PACKAGE = {
|
|
|
538
661
|
{ tokenType: "OFF_WHAT_IS", parselet: new OnOffWhatIsParselet(-1) },
|
|
539
662
|
{ tokenType: "TO", parselet: new PercentageChangeParselet() },
|
|
540
663
|
{ tokenType: "INCREASE_BY", parselet: new IncreaseByParselet(1) },
|
|
541
|
-
{ tokenType: "DECREASE_BY", parselet: new IncreaseByParselet(-1) }
|
|
664
|
+
{ tokenType: "DECREASE_BY", parselet: new IncreaseByParselet(-1) },
|
|
665
|
+
// Successive change: "120 up 10% then down 10%" is 118.80, not 120.
|
|
666
|
+
{ tokenType: "PCT_UP", parselet: new UpDownParselet(1) },
|
|
667
|
+
{ tokenType: "PCT_DOWN", parselet: new UpDownParselet(-1) }
|
|
542
668
|
],
|
|
543
669
|
prefixParselets: [
|
|
544
670
|
{ tokenType: "INCREASE", parselet: new IncreaseDecreaseParselet(1) },
|
|
545
671
|
{ tokenType: "DECREASE", parselet: new IncreaseDecreaseParselet(-1) }
|
|
546
672
|
],
|
|
547
673
|
normalizerRules: [
|
|
548
|
-
percentOnOffNormalizerRule()
|
|
674
|
+
percentOnOffNormalizerRule(),
|
|
675
|
+
percentUpDownNormalizerRule()
|
|
549
676
|
]
|
|
550
677
|
};
|
|
551
678
|
|
|
@@ -656,7 +783,7 @@ var FunctionCallParselet = class {
|
|
|
656
783
|
const fnName = token.value.toLowerCase();
|
|
657
784
|
const fnIdx = builtinNameToIndex[fnName];
|
|
658
785
|
if (fnIdx === void 0) {
|
|
659
|
-
throw
|
|
786
|
+
throw chunkB4HBEFTB_cjs.ErrorFactory.execution(
|
|
660
787
|
"UNKNOWN_FUNCTION",
|
|
661
788
|
`Unknown function: ${fnName}`,
|
|
662
789
|
{ functionName: fnName }
|
|
@@ -665,10 +792,10 @@ var FunctionCallParselet = class {
|
|
|
665
792
|
parser.consume("LPAREN");
|
|
666
793
|
let argCount = 0;
|
|
667
794
|
if (parser.peek()?.type !== "RPAREN") {
|
|
668
|
-
parser.parseExpression(
|
|
795
|
+
parser.parseExpression(chunkJ45BCEZ4_cjs.BindingPower.Lowest, builder);
|
|
669
796
|
argCount++;
|
|
670
797
|
while (parser.match("COMMA")) {
|
|
671
|
-
parser.parseExpression(
|
|
798
|
+
parser.parseExpression(chunkJ45BCEZ4_cjs.BindingPower.Lowest, builder);
|
|
672
799
|
argCount++;
|
|
673
800
|
}
|
|
674
801
|
}
|
|
@@ -725,7 +852,7 @@ var NextLastParselet = class {
|
|
|
725
852
|
const dayToken = parser.peek();
|
|
726
853
|
const targetDay = dayToken ? WEEKDAY_TOKEN_INDEX[dayToken.type] : void 0;
|
|
727
854
|
if (targetDay === void 0) {
|
|
728
|
-
throw
|
|
855
|
+
throw chunkB4HBEFTB_cjs.ErrorFactory.parsing(
|
|
729
856
|
"MISSING_WEEKDAY",
|
|
730
857
|
`"${token.value}" must be followed by a day of the week (e.g. "${token.value} Saturday")`,
|
|
731
858
|
{ keyword: token.value, actualType: dayToken?.type, actualValue: dayToken?.value }
|
|
@@ -794,27 +921,27 @@ function unixTimestampToEpochMs(n) {
|
|
|
794
921
|
}
|
|
795
922
|
|
|
796
923
|
// src/packages/datetime/parselets/DatetimeTimestampPluginFunctions.ts
|
|
797
|
-
var WORKDAYS_IN_FN_IDX =
|
|
798
|
-
var WEEKDAY_ON_FN_IDX =
|
|
799
|
-
var TO_DATE_FN_IDX =
|
|
800
|
-
var TO_TIMESTAMP_FN_IDX =
|
|
801
|
-
var MONTH_ON_FN_IDX =
|
|
802
|
-
var WEEK_ON_FN_IDX =
|
|
803
|
-
var IS_WEEKEND_FN_IDX =
|
|
804
|
-
var IS_WORKDAY_FN_IDX =
|
|
805
|
-
var SPAN_BETWEEN_FN_IDX =
|
|
924
|
+
var WORKDAYS_IN_FN_IDX = chunk7ZX6B7SY_cjs.allocatePluginFunctionIndex();
|
|
925
|
+
var WEEKDAY_ON_FN_IDX = chunk7ZX6B7SY_cjs.allocatePluginFunctionIndex();
|
|
926
|
+
var TO_DATE_FN_IDX = chunk7ZX6B7SY_cjs.allocatePluginFunctionIndex();
|
|
927
|
+
var TO_TIMESTAMP_FN_IDX = chunk7ZX6B7SY_cjs.allocatePluginFunctionIndex();
|
|
928
|
+
var MONTH_ON_FN_IDX = chunk7ZX6B7SY_cjs.allocatePluginFunctionIndex();
|
|
929
|
+
var WEEK_ON_FN_IDX = chunk7ZX6B7SY_cjs.allocatePluginFunctionIndex();
|
|
930
|
+
var IS_WEEKEND_FN_IDX = chunk7ZX6B7SY_cjs.allocatePluginFunctionIndex();
|
|
931
|
+
var IS_WORKDAY_FN_IDX = chunk7ZX6B7SY_cjs.allocatePluginFunctionIndex();
|
|
932
|
+
var SPAN_BETWEEN_FN_IDX = chunk7ZX6B7SY_cjs.allocatePluginFunctionIndex();
|
|
806
933
|
function workdaysInDurationHandler(args) {
|
|
807
934
|
const v = args[0];
|
|
808
935
|
let totalDays;
|
|
809
936
|
if (v.type === 6 /* Uom */ && v.unit) {
|
|
810
|
-
const measure =
|
|
937
|
+
const measure = chunkEJ3ILXX6_cjs.getMeasure(v.unit);
|
|
811
938
|
if (measure !== "time") {
|
|
812
|
-
return
|
|
939
|
+
return chunk2TZKENDH_cjs.errorValue(
|
|
813
940
|
"WORKDAYS_IN_EXPECTED_DURATION",
|
|
814
941
|
`"workdays in" expects a time duration, got unit "${v.unit}"`
|
|
815
942
|
);
|
|
816
943
|
}
|
|
817
|
-
totalDays =
|
|
944
|
+
totalDays = chunkEJ3ILXX6_cjs.convertUnit(v.toNumber(), v.unit, "day");
|
|
818
945
|
} else {
|
|
819
946
|
totalDays = v.toNumber();
|
|
820
947
|
}
|
|
@@ -823,7 +950,7 @@ function workdaysInDurationHandler(args) {
|
|
|
823
950
|
const fullWeeks = Math.floor(magnitudeDays / 7);
|
|
824
951
|
const remainderDays = magnitudeDays - fullWeeks * 7;
|
|
825
952
|
const workdays = sign * (fullWeeks * 5 + Math.min(remainderDays, 5));
|
|
826
|
-
return
|
|
953
|
+
return chunk2TZKENDH_cjs.numberValue(workdays);
|
|
827
954
|
}
|
|
828
955
|
var WEEKDAY_NAMES = [
|
|
829
956
|
"Sunday",
|
|
@@ -836,15 +963,15 @@ var WEEKDAY_NAMES = [
|
|
|
836
963
|
];
|
|
837
964
|
function asEpochMs(value, fieldName) {
|
|
838
965
|
if (value.type === 4 /* Datetime */) return value.toNumber();
|
|
839
|
-
return
|
|
966
|
+
return chunk2TZKENDH_cjs.errorValue(
|
|
840
967
|
"DATE_FIELD_EXPECTED_DATE",
|
|
841
|
-
`"${fieldName}" expects a date, got ${
|
|
968
|
+
`"${fieldName}" expects a date, got ${chunk2TZKENDH_cjs.ValueType[value.type] ?? "an unsupported value"}`
|
|
842
969
|
);
|
|
843
970
|
}
|
|
844
971
|
function weekdayOnDateHandler(args) {
|
|
845
972
|
const epochMs = asEpochMs(args[0], "weekday");
|
|
846
973
|
if (typeof epochMs !== "number") return epochMs;
|
|
847
|
-
return
|
|
974
|
+
return chunk2TZKENDH_cjs.stringValue(WEEKDAY_NAMES[new Date(epochMs).getDay()]);
|
|
848
975
|
}
|
|
849
976
|
var MONTH_NAMES = [
|
|
850
977
|
"January",
|
|
@@ -863,7 +990,7 @@ var MONTH_NAMES = [
|
|
|
863
990
|
function monthOnDateHandler(args) {
|
|
864
991
|
const epochMs = asEpochMs(args[0], "month");
|
|
865
992
|
if (typeof epochMs !== "number") return epochMs;
|
|
866
|
-
return
|
|
993
|
+
return chunk2TZKENDH_cjs.stringValue(MONTH_NAMES[new Date(epochMs).getMonth()]);
|
|
867
994
|
}
|
|
868
995
|
function weekOnDateHandler(args) {
|
|
869
996
|
const epochMs = asEpochMs(args[0], "week");
|
|
@@ -874,7 +1001,7 @@ function weekOnDateHandler(args) {
|
|
|
874
1001
|
target.setUTCDate(target.getUTCDate() + 4 - isoDay);
|
|
875
1002
|
const yearStart = Date.UTC(target.getUTCFullYear(), 0, 1);
|
|
876
1003
|
const days = Math.floor((target.getTime() - yearStart) / 864e5);
|
|
877
|
-
return
|
|
1004
|
+
return chunk2TZKENDH_cjs.numberValue(Math.floor(days / 7) + 1);
|
|
878
1005
|
}
|
|
879
1006
|
function isWeekendDate(epochMs) {
|
|
880
1007
|
const day = new Date(epochMs).getDay();
|
|
@@ -883,15 +1010,15 @@ function isWeekendDate(epochMs) {
|
|
|
883
1010
|
function isWeekendOnDateHandler(args) {
|
|
884
1011
|
const epochMs = asEpochMs(args[0], "is a weekend");
|
|
885
1012
|
if (typeof epochMs !== "number") return epochMs;
|
|
886
|
-
return
|
|
1013
|
+
return chunk2TZKENDH_cjs.boolValue(isWeekendDate(epochMs));
|
|
887
1014
|
}
|
|
888
1015
|
function isWorkdayOnDateHandler(args) {
|
|
889
1016
|
const epochMs = asEpochMs(args[0], "is a workday");
|
|
890
1017
|
if (typeof epochMs !== "number") return epochMs;
|
|
891
|
-
return
|
|
1018
|
+
return chunk2TZKENDH_cjs.boolValue(!isWeekendDate(epochMs));
|
|
892
1019
|
}
|
|
893
1020
|
function spanBetweenDatesHandler(args) {
|
|
894
|
-
return
|
|
1021
|
+
return chunk2TZKENDH_cjs.uomValue(Math.abs(args[0].toNumber() - args[1].toNumber()), "ms");
|
|
895
1022
|
}
|
|
896
1023
|
function toDateFromAnyHandler(args) {
|
|
897
1024
|
const v = args[0];
|
|
@@ -901,28 +1028,28 @@ function toDateFromAnyHandler(args) {
|
|
|
901
1028
|
if (v.type === 3 /* String */) {
|
|
902
1029
|
const ms = parseIso8601(v.value);
|
|
903
1030
|
if (ms === null) {
|
|
904
|
-
return
|
|
1031
|
+
return chunk2TZKENDH_cjs.errorValue(
|
|
905
1032
|
"INVALID_ISO8601_STRING",
|
|
906
1033
|
`"${v.value}" is not a recognizable ISO8601 date/time string`
|
|
907
1034
|
);
|
|
908
1035
|
}
|
|
909
|
-
return
|
|
1036
|
+
return chunk2TZKENDH_cjs.datetimeValue(ms);
|
|
910
1037
|
}
|
|
911
|
-
return
|
|
1038
|
+
return chunk2TZKENDH_cjs.datetimeValue(unixTimestampToEpochMs(v.toNumber()));
|
|
912
1039
|
}
|
|
913
1040
|
function toTimestampFromAnyHandler(args) {
|
|
914
1041
|
const v = args[0];
|
|
915
1042
|
if (v.type === 3 /* String */) {
|
|
916
1043
|
const ms = parseIso8601(v.value);
|
|
917
1044
|
if (ms === null) {
|
|
918
|
-
return
|
|
1045
|
+
return chunk2TZKENDH_cjs.errorValue(
|
|
919
1046
|
"INVALID_ISO8601_STRING",
|
|
920
1047
|
`"${v.value}" is not a recognizable ISO8601 date/time string`
|
|
921
1048
|
);
|
|
922
1049
|
}
|
|
923
|
-
return
|
|
1050
|
+
return chunk2TZKENDH_cjs.numberValue(Math.floor(ms / 1e3));
|
|
924
1051
|
}
|
|
925
|
-
return
|
|
1052
|
+
return chunk2TZKENDH_cjs.numberValue(Math.floor(v.toNumber() / 1e3));
|
|
926
1053
|
}
|
|
927
1054
|
var workdaysInDuration = workdaysInDurationHandler;
|
|
928
1055
|
var weekdayOnDate = weekdayOnDateHandler;
|
|
@@ -947,6 +1074,34 @@ var WorkdaysInParselet = class {
|
|
|
947
1074
|
}
|
|
948
1075
|
};
|
|
949
1076
|
|
|
1077
|
+
// src/packages/datetime/parselets/WorkdayOffsetParselet.ts
|
|
1078
|
+
var WorkdayOffsetParselet = class {
|
|
1079
|
+
/** @param direction "forward" for after/from, "backward" for before. */
|
|
1080
|
+
constructor(direction) {
|
|
1081
|
+
this.direction = direction;
|
|
1082
|
+
this.category = "Date/Time";
|
|
1083
|
+
this.bindingPower = chunkJ45BCEZ4_cjs.BindingPower.Conditional;
|
|
1084
|
+
}
|
|
1085
|
+
parse(parser, _left, _token, builder) {
|
|
1086
|
+
parser.parseExpression(chunkJ45BCEZ4_cjs.BindingPower.Sum, builder);
|
|
1087
|
+
builder.emitOpcode(96 /* DATE_WORKDAY_OFFSET */);
|
|
1088
|
+
builder.emitByte(this.direction === "backward" ? 1 : 0);
|
|
1089
|
+
}
|
|
1090
|
+
};
|
|
1091
|
+
|
|
1092
|
+
// src/packages/datetime/parselets/WorkdaysBetweenParselet.ts
|
|
1093
|
+
var WorkdaysBetweenParselet = class {
|
|
1094
|
+
constructor() {
|
|
1095
|
+
this.category = "Date/Time";
|
|
1096
|
+
}
|
|
1097
|
+
parse(parser, _token, builder) {
|
|
1098
|
+
parser.parseExpression(chunkJ45BCEZ4_cjs.BindingPower.Product, builder);
|
|
1099
|
+
parser.consume("AND_CONJ");
|
|
1100
|
+
parser.parseExpression(chunkJ45BCEZ4_cjs.BindingPower.Lowest, builder);
|
|
1101
|
+
builder.emitOpcode(97 /* DATE_WORKDAYS_BETWEEN */);
|
|
1102
|
+
}
|
|
1103
|
+
};
|
|
1104
|
+
|
|
950
1105
|
// src/packages/datetime/parselets/DateFieldQueryParselet.ts
|
|
951
1106
|
var DateFieldQueryParselet = class {
|
|
952
1107
|
constructor(functionIndex, mode) {
|
|
@@ -977,9 +1132,9 @@ var DurationBetweenParselet = class {
|
|
|
977
1132
|
}
|
|
978
1133
|
parse(parser, token, builder) {
|
|
979
1134
|
const unit = token.value;
|
|
980
|
-
parser.parseExpression(
|
|
1135
|
+
parser.parseExpression(chunkJ45BCEZ4_cjs.BindingPower.Product, builder);
|
|
981
1136
|
parser.consume("AND_CONJ");
|
|
982
|
-
parser.parseExpression(
|
|
1137
|
+
parser.parseExpression(chunkJ45BCEZ4_cjs.BindingPower.Lowest, builder);
|
|
983
1138
|
builder.emitOpcode(50 /* CALL_PLUGIN */);
|
|
984
1139
|
builder.emitIndex(SPAN_BETWEEN_FN_IDX);
|
|
985
1140
|
builder.emitIndex(2);
|
|
@@ -994,7 +1149,7 @@ var DayTypePredicateParselet = class {
|
|
|
994
1149
|
constructor(functionIndex) {
|
|
995
1150
|
this.functionIndex = functionIndex;
|
|
996
1151
|
this.category = "Date/Time";
|
|
997
|
-
this.bindingPower =
|
|
1152
|
+
this.bindingPower = chunkJ45BCEZ4_cjs.BindingPower.Conditional;
|
|
998
1153
|
}
|
|
999
1154
|
parse(parser, left, token, builder) {
|
|
1000
1155
|
builder.emitOpcode(50 /* CALL_PLUGIN */);
|
|
@@ -1020,7 +1175,7 @@ var CurrentTimestampParselet = class {
|
|
|
1020
1175
|
var ToDateParselet = class {
|
|
1021
1176
|
constructor() {
|
|
1022
1177
|
this.category = "Date/Time";
|
|
1023
|
-
this.bindingPower =
|
|
1178
|
+
this.bindingPower = chunkJ45BCEZ4_cjs.BindingPower.Conditional;
|
|
1024
1179
|
}
|
|
1025
1180
|
parse(parser, left, token, builder) {
|
|
1026
1181
|
builder.emitOpcode(50 /* CALL_PLUGIN */);
|
|
@@ -1033,7 +1188,7 @@ var ToDateParselet = class {
|
|
|
1033
1188
|
var ToTimestampParselet = class {
|
|
1034
1189
|
constructor() {
|
|
1035
1190
|
this.category = "Date/Time";
|
|
1036
|
-
this.bindingPower =
|
|
1191
|
+
this.bindingPower = chunkJ45BCEZ4_cjs.BindingPower.Conditional;
|
|
1037
1192
|
}
|
|
1038
1193
|
parse(parser, left, token, builder) {
|
|
1039
1194
|
builder.emitOpcode(50 /* CALL_PLUGIN */);
|
|
@@ -1067,7 +1222,7 @@ function untilSinceNormalizerRule(priority = 60) {
|
|
|
1067
1222
|
const fusedType = keywordToken.type === "UNTIL" ? "UNTIL_UNIT" : "SINCE_UNIT";
|
|
1068
1223
|
return {
|
|
1069
1224
|
consumed: 2,
|
|
1070
|
-
replacement: [
|
|
1225
|
+
replacement: [chunkC75AFGVD_cjs.createFusedToken(fusedType, unitToken.value, [unitToken, keywordToken])],
|
|
1071
1226
|
ruleName: `datetime:${keywordToken.type.toLowerCase()}`
|
|
1072
1227
|
};
|
|
1073
1228
|
}
|
|
@@ -1104,7 +1259,7 @@ function betweenUnitNormalizerRule(priority = 60) {
|
|
|
1104
1259
|
}
|
|
1105
1260
|
return {
|
|
1106
1261
|
consumed: howManyLength + 2,
|
|
1107
|
-
replacement: [
|
|
1262
|
+
replacement: [chunkC75AFGVD_cjs.createFusedToken("BETWEEN_UNIT", unitToken.value, sources)],
|
|
1108
1263
|
ruleName: "datetime:between"
|
|
1109
1264
|
};
|
|
1110
1265
|
}
|
|
@@ -1125,7 +1280,7 @@ function workdayRateDenominatorNormalizerRule(priority = 70) {
|
|
|
1125
1280
|
const syntheticOne = {
|
|
1126
1281
|
...unit,
|
|
1127
1282
|
type: "NUMBER",
|
|
1128
|
-
typeId:
|
|
1283
|
+
typeId: chunkQFTDTX6K_cjs.tokenTypeId("NUMBER"),
|
|
1129
1284
|
value: "1",
|
|
1130
1285
|
text: "1"
|
|
1131
1286
|
};
|
|
@@ -1140,7 +1295,7 @@ function workdayRateDenominatorNormalizerRule(priority = 70) {
|
|
|
1140
1295
|
|
|
1141
1296
|
// src/packages/datetime/normalizer/DateLiteralNormalizerRule.ts
|
|
1142
1297
|
var DATETIME_LITERAL_TYPE = "DATETIME_LITERAL";
|
|
1143
|
-
var DATETIME_LITERAL_TYPE_ID =
|
|
1298
|
+
var DATETIME_LITERAL_TYPE_ID = chunkQFTDTX6K_cjs.tokenTypeId(DATETIME_LITERAL_TYPE);
|
|
1144
1299
|
var PLAIN_INTEGER = /^\d+$/;
|
|
1145
1300
|
var DOT_DAY_MONTH = /^\d{1,2}\.\d{1,2}$/;
|
|
1146
1301
|
var DOT_LEADING_YEAR = /^\.(\d{2}|\d{4})$/;
|
|
@@ -1169,7 +1324,7 @@ function buildDateToken(day, month, year, sourceTokens, ruleName) {
|
|
|
1169
1324
|
}
|
|
1170
1325
|
const first = sourceTokens[0];
|
|
1171
1326
|
const text = sourceTokens.map((t) => t.value).join("");
|
|
1172
|
-
const fusedToken = new
|
|
1327
|
+
const fusedToken = new chunkYTIYVHL7_cjs.LexerToken(
|
|
1173
1328
|
DATETIME_LITERAL_TYPE,
|
|
1174
1329
|
DATETIME_LITERAL_TYPE_ID,
|
|
1175
1330
|
String(date.getTime()),
|
|
@@ -1210,7 +1365,7 @@ function fuseIsoTimestamp(tokens, pos, ruleName) {
|
|
|
1210
1365
|
if (covered !== matched[0].length) return null;
|
|
1211
1366
|
const epochMs = parseIso8601(matched[0]);
|
|
1212
1367
|
if (epochMs === null) return null;
|
|
1213
|
-
const fusedToken = new
|
|
1368
|
+
const fusedToken = new chunkYTIYVHL7_cjs.LexerToken(
|
|
1214
1369
|
DATETIME_LITERAL_TYPE,
|
|
1215
1370
|
DATETIME_LITERAL_TYPE_ID,
|
|
1216
1371
|
String(epochMs),
|
|
@@ -1403,7 +1558,7 @@ var DaysInPeriodParselet = class {
|
|
|
1403
1558
|
}
|
|
1404
1559
|
const year = this.readOptionalYear(parser);
|
|
1405
1560
|
if (year !== null) return daysInYear(year);
|
|
1406
|
-
throw
|
|
1561
|
+
throw chunkB4HBEFTB_cjs.ErrorFactory.parsing(
|
|
1407
1562
|
"DAYS_IN_EXPECTED_PERIOD",
|
|
1408
1563
|
'Expected a month, quarter or year, as in "days in February 2020" or "days in Q3"'
|
|
1409
1564
|
);
|
|
@@ -1469,7 +1624,7 @@ function daysInPeriodNormalizerRule(priority = 60) {
|
|
|
1469
1624
|
if (!startsPeriod(tokens[pos + 2])) return null;
|
|
1470
1625
|
return {
|
|
1471
1626
|
consumed: 2,
|
|
1472
|
-
replacement: [
|
|
1627
|
+
replacement: [chunkC75AFGVD_cjs.createFusedToken("DAYS_IN_PERIOD", "days in", [days, tokens[pos + 1]])],
|
|
1473
1628
|
ruleName: "datetime:days-in-period"
|
|
1474
1629
|
};
|
|
1475
1630
|
}
|
|
@@ -1501,6 +1656,26 @@ var DATETIME_PACKAGE = {
|
|
|
1501
1656
|
name: "solve-datetime",
|
|
1502
1657
|
phrases: {
|
|
1503
1658
|
"workdays in": "WORKDAYS_IN",
|
|
1659
|
+
// Business-day arithmetic in words. "after"/"from" count forward, "before"
|
|
1660
|
+
// back; the count is the left operand, so these fuse as INFIX tokens (see
|
|
1661
|
+
// WorkdayOffsetParselet). Both "working" and "business" days, singular and
|
|
1662
|
+
// plural, so "1 working day after" and "5 business days from" both read.
|
|
1663
|
+
"working days after": "WORKDAYS_AFTER",
|
|
1664
|
+
"business days after": "WORKDAYS_AFTER",
|
|
1665
|
+
"working day after": "WORKDAYS_AFTER",
|
|
1666
|
+
"business day after": "WORKDAYS_AFTER",
|
|
1667
|
+
"working days from": "WORKDAYS_AFTER",
|
|
1668
|
+
"business days from": "WORKDAYS_AFTER",
|
|
1669
|
+
"working day from": "WORKDAYS_AFTER",
|
|
1670
|
+
"business day from": "WORKDAYS_AFTER",
|
|
1671
|
+
"working days before": "WORKDAYS_BEFORE",
|
|
1672
|
+
"business days before": "WORKDAYS_BEFORE",
|
|
1673
|
+
"working day before": "WORKDAYS_BEFORE",
|
|
1674
|
+
"business day before": "WORKDAYS_BEFORE",
|
|
1675
|
+
// The count form (prefix). Fusing the whole "working days between" keeps
|
|
1676
|
+
// the bare `days between` rule from claiming the "days" first.
|
|
1677
|
+
"working days between": "WORKDAYS_BETWEEN",
|
|
1678
|
+
"business days between": "WORKDAYS_BETWEEN",
|
|
1504
1679
|
"day of the week on": "WEEKDAY_ON",
|
|
1505
1680
|
"weekday on": "WEEKDAY_ON",
|
|
1506
1681
|
"current timestamp": "CURRENT_TIMESTAMP",
|
|
@@ -1548,6 +1723,7 @@ var DATETIME_PACKAGE = {
|
|
|
1548
1723
|
{ tokenType: "UNTIL_UNIT", parselet: new UntilSinceParselet("until") },
|
|
1549
1724
|
{ tokenType: "SINCE_UNIT", parselet: new UntilSinceParselet("since") },
|
|
1550
1725
|
{ tokenType: "WORKDAYS_IN", parselet: new WorkdaysInParselet() },
|
|
1726
|
+
{ tokenType: "WORKDAYS_BETWEEN", parselet: new WorkdaysBetweenParselet() },
|
|
1551
1727
|
{ tokenType: "WEEKDAY_ON", parselet: new DateFieldQueryParselet(WEEKDAY_ON_FN_IDX, "on") },
|
|
1552
1728
|
{ tokenType: "WEEKDAY_IN", parselet: new DateFieldQueryParselet(WEEKDAY_ON_FN_IDX, "in") },
|
|
1553
1729
|
{ tokenType: "MONTH_ON", parselet: new DateFieldQueryParselet(MONTH_ON_FN_IDX, "on") },
|
|
@@ -1559,6 +1735,8 @@ var DATETIME_PACKAGE = {
|
|
|
1559
1735
|
{ tokenType: "DATETIME_LITERAL", parselet: new DateLiteralParselet() }
|
|
1560
1736
|
],
|
|
1561
1737
|
infixParselets: [
|
|
1738
|
+
{ tokenType: "WORKDAYS_AFTER", parselet: new WorkdayOffsetParselet("forward") },
|
|
1739
|
+
{ tokenType: "WORKDAYS_BEFORE", parselet: new WorkdayOffsetParselet("backward") },
|
|
1562
1740
|
{ tokenType: "TO_DATE", parselet: new ToDateParselet() },
|
|
1563
1741
|
{ tokenType: "TO_TIMESTAMP", parselet: new ToTimestampParselet() },
|
|
1564
1742
|
{ tokenType: "IS_WEEKEND", parselet: new DayTypePredicateParselet(IS_WEEKEND_FN_IDX) },
|
|
@@ -1588,7 +1766,7 @@ var DATETIME_PACKAGE = {
|
|
|
1588
1766
|
{ index: SPAN_BETWEEN_FN_IDX, handler: spanBetweenDates }
|
|
1589
1767
|
],
|
|
1590
1768
|
asConverters: {
|
|
1591
|
-
iso8601: (value) =>
|
|
1769
|
+
iso8601: (value) => chunk2TZKENDH_cjs.stringValue(formatIso8601Local(value.toNumber())),
|
|
1592
1770
|
// The same three fields the "what X is it" questions answer, in the
|
|
1593
1771
|
// composable form: `next friday + 2 weeks as weekday`. Question phrases
|
|
1594
1772
|
// only ever take a bare date expression, whereas `as` binds after a
|
|
@@ -1912,10 +2090,10 @@ function tryConsumeZoneReference(parser) {
|
|
|
1912
2090
|
}
|
|
1913
2091
|
|
|
1914
2092
|
// src/packages/time/parselets/TimezonePluginFunctions.ts
|
|
1915
|
-
var ZONE_CONVERT_FN_IDX =
|
|
1916
|
-
var TIME_IN_ZONE_FN_IDX =
|
|
1917
|
-
var DATE_IN_ZONE_FN_IDX =
|
|
1918
|
-
var TIME_DIFFERENCE_FN_IDX =
|
|
2093
|
+
var ZONE_CONVERT_FN_IDX = chunk7ZX6B7SY_cjs.allocatePluginFunctionIndex();
|
|
2094
|
+
var TIME_IN_ZONE_FN_IDX = chunk7ZX6B7SY_cjs.allocatePluginFunctionIndex();
|
|
2095
|
+
var DATE_IN_ZONE_FN_IDX = chunk7ZX6B7SY_cjs.allocatePluginFunctionIndex();
|
|
2096
|
+
var TIME_DIFFERENCE_FN_IDX = chunk7ZX6B7SY_cjs.allocatePluginFunctionIndex();
|
|
1919
2097
|
function zoneConvertHandler(args) {
|
|
1920
2098
|
const totalMinutes = args[0].toNumber();
|
|
1921
2099
|
const sourceZoneRef = args[1].value;
|
|
@@ -1931,17 +2109,17 @@ function zoneConvertHandler(args) {
|
|
|
1931
2109
|
);
|
|
1932
2110
|
const time = formatTimeInZone(utcMs, targetZoneRef);
|
|
1933
2111
|
const dayShift = dayShiftBetweenZones(utcMs, targetZoneRef, sourceZoneRef);
|
|
1934
|
-
if (dayShift === 0) return
|
|
2112
|
+
if (dayShift === 0) return chunk2TZKENDH_cjs.stringValue(time);
|
|
1935
2113
|
const sign = dayShift > 0 ? "+" : "";
|
|
1936
|
-
return
|
|
2114
|
+
return chunk2TZKENDH_cjs.stringValue(`${time} (${sign}${dayShift} day${Math.abs(dayShift) === 1 ? "" : "s"})`);
|
|
1937
2115
|
}
|
|
1938
2116
|
function timeInZoneHandler(args) {
|
|
1939
2117
|
const zoneRef = args[0].value;
|
|
1940
|
-
return
|
|
2118
|
+
return chunk2TZKENDH_cjs.stringValue(formatTimeInZone(Date.now(), zoneRef));
|
|
1941
2119
|
}
|
|
1942
2120
|
function dateInZoneHandler(args) {
|
|
1943
2121
|
const zoneRef = args[0].value;
|
|
1944
|
-
return
|
|
2122
|
+
return chunk2TZKENDH_cjs.stringValue(formatDateInZone(Date.now(), zoneRef));
|
|
1945
2123
|
}
|
|
1946
2124
|
function timeDifferenceHandler(args) {
|
|
1947
2125
|
const zoneRef1 = args[0].value;
|
|
@@ -1953,7 +2131,7 @@ function timeDifferenceHandler(args) {
|
|
|
1953
2131
|
const offset2 = resolveOffsetMinutes(zoneRef2, now);
|
|
1954
2132
|
const diff = offset2 - offset1;
|
|
1955
2133
|
if (diff === 0) {
|
|
1956
|
-
return
|
|
2134
|
+
return chunk2TZKENDH_cjs.stringValue(`${label2} and ${label1} currently share the same UTC offset`);
|
|
1957
2135
|
}
|
|
1958
2136
|
const ahead = diff > 0 ? label2 : label1;
|
|
1959
2137
|
const behind = diff > 0 ? label1 : label2;
|
|
@@ -1963,7 +2141,7 @@ function timeDifferenceHandler(args) {
|
|
|
1963
2141
|
const parts = [];
|
|
1964
2142
|
if (hours > 0) parts.push(`${hours} hour${hours === 1 ? "" : "s"}`);
|
|
1965
2143
|
if (minutes > 0) parts.push(`${minutes} minute${minutes === 1 ? "" : "s"}`);
|
|
1966
|
-
return
|
|
2144
|
+
return chunk2TZKENDH_cjs.stringValue(`${ahead} is ${parts.join(" ")} ahead of ${behind}`);
|
|
1967
2145
|
}
|
|
1968
2146
|
|
|
1969
2147
|
// src/packages/time/parselets/ClockTimeParselet.ts
|
|
@@ -1976,7 +2154,7 @@ var ClockTimeParselet = class {
|
|
|
1976
2154
|
const sourceZoneRef = tryConsumeZoneReference(parser);
|
|
1977
2155
|
if (sourceZoneRef !== null) {
|
|
1978
2156
|
if (parser.peek()?.type !== "IN") {
|
|
1979
|
-
throw
|
|
2157
|
+
throw chunkB4HBEFTB_cjs.ErrorFactory.parsing(
|
|
1980
2158
|
"TIME_ZONE_EXPECTED_IN",
|
|
1981
2159
|
`Expected "in <city>" after the zone name (e.g. "6pm Sydney in Chicago") but got ${parser.peek() ? `"${parser.peek().value}"` : "end of input"}`
|
|
1982
2160
|
);
|
|
@@ -1984,7 +2162,7 @@ var ClockTimeParselet = class {
|
|
|
1984
2162
|
parser.consume();
|
|
1985
2163
|
const target = tryConsumeZoneReference(parser);
|
|
1986
2164
|
if (target === null) {
|
|
1987
|
-
throw
|
|
2165
|
+
throw chunkB4HBEFTB_cjs.ErrorFactory.parsing(
|
|
1988
2166
|
"TIME_ZONE_EXPECTED_TARGET",
|
|
1989
2167
|
`Expected a city or zone name after "in" (e.g. "6pm Sydney in Chicago")`
|
|
1990
2168
|
);
|
|
@@ -2059,7 +2237,7 @@ function timeOrDateInZoneParselet(pluginFnIdx) {
|
|
|
2059
2237
|
parse(parser, token, builder) {
|
|
2060
2238
|
const zone = tryConsumeZoneReference(parser);
|
|
2061
2239
|
if (zone === null) {
|
|
2062
|
-
throw
|
|
2240
|
+
throw chunkB4HBEFTB_cjs.ErrorFactory.parsing(
|
|
2063
2241
|
"TIME_ZONE_EXPECTED_CITY",
|
|
2064
2242
|
`Expected a city or zone name after "${token.value}" (e.g. "time in Paris")`
|
|
2065
2243
|
);
|
|
@@ -2081,7 +2259,7 @@ var TimeDifferenceParselet = class {
|
|
|
2081
2259
|
parse(parser, token, builder) {
|
|
2082
2260
|
const zone1 = tryConsumeZoneReference(parser);
|
|
2083
2261
|
if (zone1 === null) {
|
|
2084
|
-
throw
|
|
2262
|
+
throw chunkB4HBEFTB_cjs.ErrorFactory.parsing(
|
|
2085
2263
|
"TIME_DIFFERENCE_EXPECTED_CITY",
|
|
2086
2264
|
`Expected a city or zone name after "time difference between" (e.g. "time difference between Seattle and Moscow")`
|
|
2087
2265
|
);
|
|
@@ -2089,7 +2267,7 @@ var TimeDifferenceParselet = class {
|
|
|
2089
2267
|
parser.consume("AND_CONJ");
|
|
2090
2268
|
const zone2 = tryConsumeZoneReference(parser);
|
|
2091
2269
|
if (zone2 === null) {
|
|
2092
|
-
throw
|
|
2270
|
+
throw chunkB4HBEFTB_cjs.ErrorFactory.parsing(
|
|
2093
2271
|
"TIME_DIFFERENCE_EXPECTED_SECOND_CITY",
|
|
2094
2272
|
`Expected a second city or zone name after "and" (e.g. "time difference between Seattle and Moscow")`
|
|
2095
2273
|
);
|
|
@@ -2117,7 +2295,7 @@ var VideoTimecodeParselet = class {
|
|
|
2117
2295
|
const [hours, minutes, seconds, frames] = token.value.split(",").map(Number);
|
|
2118
2296
|
const separator = parser.peek();
|
|
2119
2297
|
if (!separator || separator.type !== "RATE_AT" && separator.type !== "AT") {
|
|
2120
|
-
throw
|
|
2298
|
+
throw chunkB4HBEFTB_cjs.ErrorFactory.parsing(
|
|
2121
2299
|
"TIMECODE_EXPECTED_FPS",
|
|
2122
2300
|
`A video timecode must specify a frame rate, e.g. "${token.value.split(",").join(":")} at 30 fps" or "... @ 30 fps"`
|
|
2123
2301
|
);
|
|
@@ -2125,7 +2303,7 @@ var VideoTimecodeParselet = class {
|
|
|
2125
2303
|
parser.consume();
|
|
2126
2304
|
const fpsToken = parser.peek();
|
|
2127
2305
|
if (!fpsToken || fpsToken.type !== "FPS_RATE") {
|
|
2128
|
-
throw
|
|
2306
|
+
throw chunkB4HBEFTB_cjs.ErrorFactory.parsing(
|
|
2129
2307
|
"TIMECODE_EXPECTED_FPS",
|
|
2130
2308
|
`Expected "<number> fps" after "${separator.value}" (e.g. "at 30 fps")`
|
|
2131
2309
|
);
|
|
@@ -2134,18 +2312,18 @@ var VideoTimecodeParselet = class {
|
|
|
2134
2312
|
const fps = parseFloat(fpsToken.value);
|
|
2135
2313
|
const fpsWhole = Math.round(fps);
|
|
2136
2314
|
if (frames >= fpsWhole) {
|
|
2137
|
-
throw
|
|
2315
|
+
throw chunkB4HBEFTB_cjs.ErrorFactory.parsing(
|
|
2138
2316
|
"TIMECODE_FRAME_OUT_OF_RANGE",
|
|
2139
2317
|
`Frame number ${frames} is out of range for ${fps} fps (must be 0-${fpsWhole - 1})`
|
|
2140
2318
|
);
|
|
2141
2319
|
}
|
|
2142
2320
|
const totalFrames = (hours * 3600 + minutes * 60 + seconds) * fpsWhole + frames;
|
|
2143
|
-
let unit =
|
|
2321
|
+
let unit = chunk2TZKENDH_cjs.timecodeUnit(fps);
|
|
2144
2322
|
if (parser.peek()?.type === "IN") {
|
|
2145
2323
|
parser.consume();
|
|
2146
2324
|
const framesWord = parser.peek();
|
|
2147
2325
|
if (!framesWord || framesWord.type !== "IDENT" || framesWord.value.toLowerCase() !== "frames") {
|
|
2148
|
-
throw
|
|
2326
|
+
throw chunkB4HBEFTB_cjs.ErrorFactory.parsing(
|
|
2149
2327
|
"TIMECODE_EXPECTED_FRAMES",
|
|
2150
2328
|
`Expected "frames" after "in" (e.g. "... in frames") but got ${framesWord ? `"${framesWord.value}"` : "end of input"}`
|
|
2151
2329
|
);
|
|
@@ -2186,7 +2364,7 @@ var FrameCountParselet = class {
|
|
|
2186
2364
|
parser.consume();
|
|
2187
2365
|
const fpsToken = parser.peek();
|
|
2188
2366
|
if (!fpsToken || fpsToken.type !== "FPS_RATE") {
|
|
2189
|
-
throw
|
|
2367
|
+
throw chunkB4HBEFTB_cjs.ErrorFactory.parsing(
|
|
2190
2368
|
"TIMECODE_EXPECTED_FPS",
|
|
2191
2369
|
`Expected "<number> fps" after "${separator.value}" (e.g. "@ 30 fps")`
|
|
2192
2370
|
);
|
|
@@ -2225,7 +2403,7 @@ function clockTimeNormalizerRule(priority = 65) {
|
|
|
2225
2403
|
name: "time:clock-time",
|
|
2226
2404
|
priority,
|
|
2227
2405
|
match(tokens, pos) {
|
|
2228
|
-
if (
|
|
2406
|
+
if (chunkC75AFGVD_cjs.isInsideRangeContext(tokens, pos)) return null;
|
|
2229
2407
|
const hourToken = tokens[pos];
|
|
2230
2408
|
if (hourToken.type !== "NUMBER") return null;
|
|
2231
2409
|
const hour = parseInt(hourToken.value, 10);
|
|
@@ -2241,7 +2419,7 @@ function clockTimeNormalizerRule(priority = 65) {
|
|
|
2241
2419
|
const consumed = hasAmPm ? 4 : 3;
|
|
2242
2420
|
return {
|
|
2243
2421
|
consumed,
|
|
2244
|
-
replacement: [
|
|
2422
|
+
replacement: [chunkC75AFGVD_cjs.createFusedToken("CLOCK_TIME", String(totalMinutes), tokens.slice(pos, pos + consumed))],
|
|
2245
2423
|
ruleName: "time:clock-time"
|
|
2246
2424
|
};
|
|
2247
2425
|
}
|
|
@@ -2251,7 +2429,7 @@ function clockTimeNormalizerRule(priority = 65) {
|
|
|
2251
2429
|
if (totalMinutes === null) return null;
|
|
2252
2430
|
return {
|
|
2253
2431
|
consumed: 2,
|
|
2254
|
-
replacement: [
|
|
2432
|
+
replacement: [chunkC75AFGVD_cjs.createFusedToken("CLOCK_TIME", String(totalMinutes), tokens.slice(pos, pos + 2))],
|
|
2255
2433
|
ruleName: "time:clock-time"
|
|
2256
2434
|
};
|
|
2257
2435
|
}
|
|
@@ -2274,7 +2452,7 @@ function clockTimeIntervalNormalizerRule(priority = 66) {
|
|
|
2274
2452
|
if (end?.type !== "CLOCK_TIME") return null;
|
|
2275
2453
|
return {
|
|
2276
2454
|
consumed: 3,
|
|
2277
|
-
replacement: [
|
|
2455
|
+
replacement: [chunkC75AFGVD_cjs.createFusedToken("CLOCK_TIME_INTERVAL", `${start.value}:${end.value}`, tokens.slice(pos, pos + 3))],
|
|
2278
2456
|
ruleName: "time:clock-time-interval"
|
|
2279
2457
|
};
|
|
2280
2458
|
}
|
|
@@ -2293,7 +2471,7 @@ function fpsRateNormalizerRule(priority = 65) {
|
|
|
2293
2471
|
if (fpsToken?.type !== "IDENT" || fpsToken.value.toLowerCase() !== "fps") return null;
|
|
2294
2472
|
return {
|
|
2295
2473
|
consumed: 2,
|
|
2296
|
-
replacement: [
|
|
2474
|
+
replacement: [chunkC75AFGVD_cjs.createFusedToken("FPS_RATE", numberToken.value, tokens.slice(pos, pos + 2))],
|
|
2297
2475
|
ruleName: "time:fps-rate"
|
|
2298
2476
|
};
|
|
2299
2477
|
}
|
|
@@ -2306,7 +2484,7 @@ function laptimeNormalizerRule(priority = 70) {
|
|
|
2306
2484
|
name: "time:laptime",
|
|
2307
2485
|
priority,
|
|
2308
2486
|
match(tokens, pos) {
|
|
2309
|
-
if (
|
|
2487
|
+
if (chunkC75AFGVD_cjs.isInsideRangeContext(tokens, pos)) return null;
|
|
2310
2488
|
const h = tokens[pos];
|
|
2311
2489
|
const c1 = tokens[pos + 1];
|
|
2312
2490
|
const m = tokens[pos + 2];
|
|
@@ -2325,7 +2503,7 @@ function laptimeNormalizerRule(priority = 70) {
|
|
|
2325
2503
|
const totalSeconds = hours * 3600 + minutes * 60 + seconds;
|
|
2326
2504
|
return {
|
|
2327
2505
|
consumed: 5,
|
|
2328
|
-
replacement: [
|
|
2506
|
+
replacement: [chunkC75AFGVD_cjs.createFusedToken("LAPTIME", String(totalSeconds), tokens.slice(pos, pos + 5))],
|
|
2329
2507
|
ruleName: "time:laptime"
|
|
2330
2508
|
};
|
|
2331
2509
|
}
|
|
@@ -2338,7 +2516,7 @@ function videoTimecodeNormalizerRule(priority = 75) {
|
|
|
2338
2516
|
name: "time:video-timecode",
|
|
2339
2517
|
priority,
|
|
2340
2518
|
match(tokens, pos) {
|
|
2341
|
-
if (
|
|
2519
|
+
if (chunkC75AFGVD_cjs.isInsideRangeContext(tokens, pos)) return null;
|
|
2342
2520
|
const h = tokens[pos];
|
|
2343
2521
|
const c1 = tokens[pos + 1];
|
|
2344
2522
|
const m = tokens[pos + 2];
|
|
@@ -2364,7 +2542,7 @@ function videoTimecodeNormalizerRule(priority = 75) {
|
|
|
2364
2542
|
return {
|
|
2365
2543
|
consumed: 7,
|
|
2366
2544
|
replacement: [
|
|
2367
|
-
|
|
2545
|
+
chunkC75AFGVD_cjs.createFusedToken("VIDEO_TIMECODE", `${hours},${minutes},${seconds},${frames}`, tokens.slice(pos, pos + 7))
|
|
2368
2546
|
],
|
|
2369
2547
|
ruleName: "time:video-timecode"
|
|
2370
2548
|
};
|
|
@@ -2384,7 +2562,7 @@ function frameCountNormalizerRule(priority = 65) {
|
|
|
2384
2562
|
if (framesToken?.type !== "IDENT" || framesToken.value.toLowerCase() !== "frames") return null;
|
|
2385
2563
|
return {
|
|
2386
2564
|
consumed: 2,
|
|
2387
|
-
replacement: [
|
|
2565
|
+
replacement: [chunkC75AFGVD_cjs.createFusedToken("FRAME_COUNT", numberToken.value, tokens.slice(pos, pos + 2))],
|
|
2388
2566
|
ruleName: "time:frame-count"
|
|
2389
2567
|
};
|
|
2390
2568
|
}
|
|
@@ -2410,7 +2588,7 @@ function durationSeconds(value) {
|
|
|
2410
2588
|
function toTimespanString(value) {
|
|
2411
2589
|
const total = durationSeconds(value);
|
|
2412
2590
|
if (total === null) {
|
|
2413
|
-
return
|
|
2591
|
+
return chunk2TZKENDH_cjs.stringValue(`"as timespan" needs a duration, got ${value.unit ?? "a non-duration"}`);
|
|
2414
2592
|
}
|
|
2415
2593
|
const negative = total < 0;
|
|
2416
2594
|
let remaining = Math.abs(total);
|
|
@@ -2427,12 +2605,12 @@ function toTimespanString(value) {
|
|
|
2427
2605
|
if (secondsLeft > 0 || parts.length === 0) {
|
|
2428
2606
|
parts.push(`${secondsLeft} ${secondsLeft === 1 ? "second" : "seconds"}`);
|
|
2429
2607
|
}
|
|
2430
|
-
return
|
|
2608
|
+
return chunk2TZKENDH_cjs.stringValue((negative ? "-" : "") + parts.join(" "));
|
|
2431
2609
|
}
|
|
2432
2610
|
function toLaptimeString(value) {
|
|
2433
2611
|
const total = durationSeconds(value);
|
|
2434
2612
|
if (total === null) {
|
|
2435
|
-
return
|
|
2613
|
+
return chunk2TZKENDH_cjs.stringValue(`"as laptime" needs a duration, got ${value.unit ?? "a non-duration"}`);
|
|
2436
2614
|
}
|
|
2437
2615
|
const negative = total < 0;
|
|
2438
2616
|
const rounded = Math.round(Math.abs(total) * 1e3) / 1e3;
|
|
@@ -2442,7 +2620,7 @@ function toLaptimeString(value) {
|
|
|
2442
2620
|
const whole = Math.floor(seconds);
|
|
2443
2621
|
const fraction = Math.round((seconds - whole) * 1e3);
|
|
2444
2622
|
const base = `${pad(hours)}:${pad(minutes)}:${pad(whole)}`;
|
|
2445
|
-
return
|
|
2623
|
+
return chunk2TZKENDH_cjs.stringValue((negative ? "-" : "") + (fraction > 0 ? `${base}.${String(fraction).padStart(3, "0")}` : base));
|
|
2446
2624
|
}
|
|
2447
2625
|
function pad(n) {
|
|
2448
2626
|
return n < 10 ? `0${n}` : String(n);
|
|
@@ -2495,7 +2673,7 @@ function definePhrasePattern(opts) {
|
|
|
2495
2673
|
for (const alt of opts.alternatives) {
|
|
2496
2674
|
const first = alt.slots[0];
|
|
2497
2675
|
if (!first || first.kind !== "keyword") {
|
|
2498
|
-
throw
|
|
2676
|
+
throw chunkB4HBEFTB_cjs.ErrorFactory.config(
|
|
2499
2677
|
"INVALID_PHRASE_PATTERN",
|
|
2500
2678
|
"Every PhraseAlternative's first slot must be a `keyword` slot \u2014 alternatives are chosen by peeking the next token, which only works if the choice is decidable from one leading keyword.",
|
|
2501
2679
|
{ category: opts.category }
|
|
@@ -2512,7 +2690,7 @@ function definePhrasePattern(opts) {
|
|
|
2512
2690
|
});
|
|
2513
2691
|
if (!alternative) {
|
|
2514
2692
|
const expected = opts.alternatives.map((alt) => alt.slots[0].tokenTypes.join("|")).join(", ");
|
|
2515
|
-
throw
|
|
2693
|
+
throw chunkB4HBEFTB_cjs.ErrorFactory.parsing(
|
|
2516
2694
|
"NO_MATCHING_PHRASE_ALTERNATIVE",
|
|
2517
2695
|
`Expected one of [${expected}] but got "${next?.type ?? "end of input"}" ("${next?.value ?? ""}")`,
|
|
2518
2696
|
{ category: opts.category, expected, actualType: next?.type, actualValue: next?.value }
|
|
@@ -2523,7 +2701,7 @@ function definePhrasePattern(opts) {
|
|
|
2523
2701
|
if (slot.kind === "keyword") {
|
|
2524
2702
|
const token = parser.peek();
|
|
2525
2703
|
if (!token || !slot.tokenTypes.includes(token.type)) {
|
|
2526
|
-
throw
|
|
2704
|
+
throw chunkB4HBEFTB_cjs.ErrorFactory.parsing(
|
|
2527
2705
|
"PHRASE_KEYWORD_MISMATCH",
|
|
2528
2706
|
`Expected one of [${slot.tokenTypes.join("|")}] but got "${token?.type ?? "end of input"}" ("${token?.value ?? ""}")`,
|
|
2529
2707
|
{ category: opts.category, expected: slot.tokenTypes, actualType: token?.type, actualValue: token?.value }
|
|
@@ -2553,7 +2731,7 @@ var keywordLedRollPattern = definePhrasePattern({
|
|
|
2553
2731
|
{
|
|
2554
2732
|
slots: [
|
|
2555
2733
|
{ kind: "keyword", tokenTypes: ["BETWEEN"] },
|
|
2556
|
-
{ kind: "expr", bindingPower:
|
|
2734
|
+
{ kind: "expr", bindingPower: chunkJ45BCEZ4_cjs.BindingPower.Product },
|
|
2557
2735
|
// The word "and" lexes as PLUS, not a dedicated AND token, en.ts's
|
|
2558
2736
|
// keywordMap maps `and: "PLUS"` (a synonym for arithmetic "+").
|
|
2559
2737
|
// The original hand-written parselet never actually checked the
|
|
@@ -2568,7 +2746,7 @@ var keywordLedRollPattern = definePhrasePattern({
|
|
|
2568
2746
|
{
|
|
2569
2747
|
slots: [
|
|
2570
2748
|
{ kind: "keyword", tokenTypes: ["FROM"] },
|
|
2571
|
-
{ kind: "expr", bindingPower:
|
|
2749
|
+
{ kind: "expr", bindingPower: chunkJ45BCEZ4_cjs.BindingPower.Product },
|
|
2572
2750
|
{ kind: "keyword", tokenTypes: ["TO"] },
|
|
2573
2751
|
{ kind: "expr" }
|
|
2574
2752
|
],
|
|
@@ -2623,7 +2801,7 @@ var VariableParselet = class {
|
|
|
2623
2801
|
parse(parser, _token, builder) {
|
|
2624
2802
|
const nameToken = parser.consume();
|
|
2625
2803
|
if (nameToken.type !== "IDENT" && nameToken.type !== "UNIT") {
|
|
2626
|
-
throw
|
|
2804
|
+
throw chunkB4HBEFTB_cjs.ErrorFactory.parsing(
|
|
2627
2805
|
"EXPECTED_IDENTIFIER",
|
|
2628
2806
|
`Expected identifier or unit after colon, got ${nameToken.type}`,
|
|
2629
2807
|
{ tokenType: nameToken.type }
|
|
@@ -2662,7 +2840,7 @@ var GlobalVariableParselet = class {
|
|
|
2662
2840
|
parser.consume("COLON");
|
|
2663
2841
|
const nameToken = parser.consume();
|
|
2664
2842
|
if (nameToken.type !== "IDENT" && nameToken.type !== "UNIT") {
|
|
2665
|
-
throw
|
|
2843
|
+
throw chunkB4HBEFTB_cjs.ErrorFactory.parsing(
|
|
2666
2844
|
"EXPECTED_IDENTIFIER",
|
|
2667
2845
|
`Expected identifier after 'global :', got ${nameToken.type}`,
|
|
2668
2846
|
{ tokenType: nameToken.type }
|
|
@@ -2712,11 +2890,11 @@ var GlobalVariableAsyncResolver = class {
|
|
|
2712
2890
|
const op = opcodes[i];
|
|
2713
2891
|
if (op === 62 /* LOAD_GLOBAL_VAR */) {
|
|
2714
2892
|
const varName = strings[opcodes[i + 1]];
|
|
2715
|
-
if (!
|
|
2893
|
+
if (!chunk7ZX6B7SY_cjs.sharedGlobalVariableStore.has(varName)) {
|
|
2716
2894
|
return this.pendingResultFor(varName, packageId, signal);
|
|
2717
2895
|
}
|
|
2718
2896
|
}
|
|
2719
|
-
i =
|
|
2897
|
+
i = chunkSSV46KFA_cjs.nextInstruction(opcodes, i);
|
|
2720
2898
|
}
|
|
2721
2899
|
return null;
|
|
2722
2900
|
}
|
|
@@ -2724,7 +2902,7 @@ var GlobalVariableAsyncResolver = class {
|
|
|
2724
2902
|
let resolver = this.pending.get(varName);
|
|
2725
2903
|
if (!resolver) {
|
|
2726
2904
|
resolver = new Promise((resolve) => {
|
|
2727
|
-
const unsubscribe =
|
|
2905
|
+
const unsubscribe = chunk7ZX6B7SY_cjs.sharedGlobalVariableStore.subscribe((name, value) => {
|
|
2728
2906
|
if (name !== varName) return;
|
|
2729
2907
|
unsubscribe();
|
|
2730
2908
|
this.pending.delete(varName);
|
|
@@ -2769,26 +2947,193 @@ var VARIABLES_PACKAGE = {
|
|
|
2769
2947
|
]
|
|
2770
2948
|
};
|
|
2771
2949
|
|
|
2950
|
+
// src/uom/HistoricalCurrency.ts
|
|
2951
|
+
var HISTORICAL_CURRENCY_NS = "currency-historical";
|
|
2952
|
+
var HISTORICAL_CURRENCY_FN_IDX = chunk7ZX6B7SY_cjs.allocatePluginFunctionIndex();
|
|
2953
|
+
var HistoricalCurrencyErrorCodes = {
|
|
2954
|
+
/** No {@link HistoricalRateProvider} was supplied, so `on <date>` conversions cannot be answered. NOT a fall back to today's rate. */
|
|
2955
|
+
NOT_CONFIGURED: "HISTORICAL_RATES_NOT_CONFIGURED",
|
|
2956
|
+
/** The host provider threw or timed out for one pair/date. Transient, evicted after a cooldown so a retry can happen. */
|
|
2957
|
+
QUERY_FAILED: "HISTORICAL_RATE_QUERY_FAILED",
|
|
2958
|
+
/** The VM reached the conversion before preflight cached its rate, a "shouldn't happen" invariant break, not a user error. */
|
|
2959
|
+
NOT_PREFLIGHTED: "HISTORICAL_RATE_NOT_PREFLIGHTED",
|
|
2960
|
+
/** The amount being converted was not a currency Value (bad bytecode, or a non-currency left operand). */
|
|
2961
|
+
INVALID_OPERAND: "HISTORICAL_CURRENCY_INVALID_OPERAND"
|
|
2962
|
+
};
|
|
2963
|
+
var FAILURE_COOLDOWN_MS = 3e4;
|
|
2964
|
+
var HISTORICAL_RATE_STALE_TIME_MS = Infinity;
|
|
2965
|
+
var FETCH_TIMEOUT_MS = 1e4;
|
|
2966
|
+
function historicalRateQueryKey(from, to, isoDate) {
|
|
2967
|
+
return [HISTORICAL_CURRENCY_NS, `${from.toUpperCase()}:${to.toUpperCase()}:${isoDate}`];
|
|
2968
|
+
}
|
|
2969
|
+
function pad2(n) {
|
|
2970
|
+
return n < 10 ? `0${n}` : String(n);
|
|
2971
|
+
}
|
|
2972
|
+
function tryConsumeCurrencyOnDate(parser, to, from) {
|
|
2973
|
+
if (!chunkZVTWQLK4_cjs.sharedCurrencyExchange.isCurrency(to)) return null;
|
|
2974
|
+
if (from !== void 0 && !chunkZVTWQLK4_cjs.sharedCurrencyExchange.isCurrency(from)) return null;
|
|
2975
|
+
const onToken = parser.peek();
|
|
2976
|
+
if (!onToken || onToken.type !== "IDENT" || onToken.value.toLowerCase() !== "on") return null;
|
|
2977
|
+
const dateToken = parser.peekAt(1);
|
|
2978
|
+
if (!dateToken || dateToken.type !== "DATETIME_LITERAL") return null;
|
|
2979
|
+
parser.consume();
|
|
2980
|
+
parser.consume();
|
|
2981
|
+
const date = new Date(Number(dateToken.value));
|
|
2982
|
+
return `${date.getFullYear()}-${pad2(date.getMonth() + 1)}-${pad2(date.getDate())}`;
|
|
2983
|
+
}
|
|
2984
|
+
async function fetchHistoricalRate(provider, from, to, isoDate, signal, queryClient) {
|
|
2985
|
+
const fromUpper = from.toUpperCase();
|
|
2986
|
+
const toUpper = to.toUpperCase();
|
|
2987
|
+
if (!provider) {
|
|
2988
|
+
return chunk2TZKENDH_cjs.errorValue(
|
|
2989
|
+
HistoricalCurrencyErrorCodes.NOT_CONFIGURED,
|
|
2990
|
+
`Historical exchange rates are not configured. Supply historicalRateProvider via createCurrencyPackage({ ... }) to convert ${fromUpper} to ${toUpper} on ${isoDate}.`
|
|
2991
|
+
);
|
|
2992
|
+
}
|
|
2993
|
+
const { signal: fetchSignal, cleanup } = chunkVEKIWQ3F_cjs.createTimeoutSignal(signal, FETCH_TIMEOUT_MS, "Historical currency rate fetch");
|
|
2994
|
+
try {
|
|
2995
|
+
const rate = await provider(fromUpper, toUpper, isoDate, fetchSignal);
|
|
2996
|
+
return chunk2TZKENDH_cjs.numberValue(rate);
|
|
2997
|
+
} catch (error) {
|
|
2998
|
+
const failedValue = chunk2TZKENDH_cjs.errorValue(
|
|
2999
|
+
HistoricalCurrencyErrorCodes.QUERY_FAILED,
|
|
3000
|
+
`Failed to resolve the historical rate for ${fromUpper} to ${toUpper} on ${isoDate}: ${error instanceof Error ? error.message : String(error)}`
|
|
3001
|
+
);
|
|
3002
|
+
const key = historicalRateQueryKey(from, to, isoDate);
|
|
3003
|
+
const cooldownTimer = setTimeout(() => {
|
|
3004
|
+
if (queryClient.getQueryData(key) === failedValue) {
|
|
3005
|
+
queryClient.removeQueries({ queryKey: key, exact: true });
|
|
3006
|
+
}
|
|
3007
|
+
}, FAILURE_COOLDOWN_MS);
|
|
3008
|
+
cooldownTimer.unref?.();
|
|
3009
|
+
return failedValue;
|
|
3010
|
+
} finally {
|
|
3011
|
+
cleanup();
|
|
3012
|
+
}
|
|
3013
|
+
}
|
|
3014
|
+
function createHistoricalCurrencyPluginFunction(provider) {
|
|
3015
|
+
return (args) => {
|
|
3016
|
+
const amount = args[0];
|
|
3017
|
+
const toArg = args[1];
|
|
3018
|
+
const dateArg = args[2];
|
|
3019
|
+
const fault = chunk2TZKENDH_cjs.faultedOperand(amount);
|
|
3020
|
+
if (fault) return fault;
|
|
3021
|
+
if (amount.type !== 6 /* Uom */ || amount.unit === void 0 || !chunkZVTWQLK4_cjs.sharedCurrencyExchange.isCurrency(amount.unit)) {
|
|
3022
|
+
return chunk2TZKENDH_cjs.errorValue(
|
|
3023
|
+
HistoricalCurrencyErrorCodes.INVALID_OPERAND,
|
|
3024
|
+
`Historical conversion needs an amount in a currency, for example "100 USD in GBP on 2024-01-15".`
|
|
3025
|
+
);
|
|
3026
|
+
}
|
|
3027
|
+
const from = amount.unit;
|
|
3028
|
+
const to = String(toArg.value);
|
|
3029
|
+
const isoDate = String(dateArg.value);
|
|
3030
|
+
if (from.toUpperCase() === to.toUpperCase()) {
|
|
3031
|
+
return chunk2TZKENDH_cjs.uomValue(amount.toNumber(), to);
|
|
3032
|
+
}
|
|
3033
|
+
const queryClient = chunkZ2XP767T_cjs.getActiveQueryClient();
|
|
3034
|
+
const key = historicalRateQueryKey(from, to, isoDate);
|
|
3035
|
+
const cached = queryClient?.getQueryData(key);
|
|
3036
|
+
if (cached === void 0) {
|
|
3037
|
+
if (!queryClient) {
|
|
3038
|
+
return chunk2TZKENDH_cjs.errorValue(
|
|
3039
|
+
HistoricalCurrencyErrorCodes.NOT_PREFLIGHTED,
|
|
3040
|
+
`No historical rate resolved for ${from.toUpperCase()} to ${to.toUpperCase()} on ${isoDate}.`
|
|
3041
|
+
);
|
|
3042
|
+
}
|
|
3043
|
+
return queryClient.fetchQuery({
|
|
3044
|
+
queryKey: key,
|
|
3045
|
+
queryFn: ({ signal }) => fetchHistoricalRate(provider, from, to, isoDate, signal, queryClient),
|
|
3046
|
+
staleTime: HISTORICAL_RATE_STALE_TIME_MS
|
|
3047
|
+
});
|
|
3048
|
+
}
|
|
3049
|
+
if (cached.type === 13 /* Error */) return cached;
|
|
3050
|
+
const rate = cached.value;
|
|
3051
|
+
return chunk2TZKENDH_cjs.uomValue(amount.toNumber() * rate, to);
|
|
3052
|
+
};
|
|
3053
|
+
}
|
|
3054
|
+
function createHistoricalCurrencyResolver(provider) {
|
|
3055
|
+
return {
|
|
3056
|
+
namespace: HISTORICAL_CURRENCY_NS,
|
|
3057
|
+
preflight(_tokens, bytecode, packageId, signal, queryClient) {
|
|
3058
|
+
const { opcodes, strings } = bytecode;
|
|
3059
|
+
const len = opcodes.length;
|
|
3060
|
+
let i = 0;
|
|
3061
|
+
let stringIdxs = [];
|
|
3062
|
+
while (i < len) {
|
|
3063
|
+
const op = opcodes[i];
|
|
3064
|
+
if (op === 13 /* PUSH_STRING */) {
|
|
3065
|
+
stringIdxs.push(opcodes[i + 1]);
|
|
3066
|
+
} else if (op === 50 /* CALL_PLUGIN */) {
|
|
3067
|
+
const fnIdx = opcodes[i + 1];
|
|
3068
|
+
const argCount = opcodes[i + 2];
|
|
3069
|
+
if (fnIdx === HISTORICAL_CURRENCY_FN_IDX && argCount === 3 && stringIdxs.length >= 3) {
|
|
3070
|
+
const isoDate = strings[stringIdxs[stringIdxs.length - 1]];
|
|
3071
|
+
const to = strings[stringIdxs[stringIdxs.length - 2]];
|
|
3072
|
+
const sources = /* @__PURE__ */ new Set();
|
|
3073
|
+
for (let k = 0; k < stringIdxs.length - 2; k++) {
|
|
3074
|
+
const s = strings[stringIdxs[k]];
|
|
3075
|
+
if (chunkZVTWQLK4_cjs.sharedCurrencyExchange.isCurrency(s)) sources.add(s.toUpperCase());
|
|
3076
|
+
}
|
|
3077
|
+
if (sources.size === 1) {
|
|
3078
|
+
const from = sources.values().next().value;
|
|
3079
|
+
if (from !== to.toUpperCase()) {
|
|
3080
|
+
const key = historicalRateQueryKey(from, to, isoDate);
|
|
3081
|
+
if (queryClient.getQueryData(key) === void 0) {
|
|
3082
|
+
const resolver = queryClient.fetchQuery({
|
|
3083
|
+
queryKey: key,
|
|
3084
|
+
queryFn: ({ signal: qSignal }) => fetchHistoricalRate(provider, from, to, isoDate, qSignal, queryClient),
|
|
3085
|
+
staleTime: HISTORICAL_RATE_STALE_TIME_MS
|
|
3086
|
+
});
|
|
3087
|
+
return { queryKey: key.join(":"), resolver, packageId, signal, metadata: { from, to, isoDate } };
|
|
3088
|
+
}
|
|
3089
|
+
}
|
|
3090
|
+
}
|
|
3091
|
+
}
|
|
3092
|
+
stringIdxs = [];
|
|
3093
|
+
}
|
|
3094
|
+
i = chunkSSV46KFA_cjs.nextInstruction(opcodes, i);
|
|
3095
|
+
}
|
|
3096
|
+
return null;
|
|
3097
|
+
},
|
|
3098
|
+
destroy() {
|
|
3099
|
+
}
|
|
3100
|
+
};
|
|
3101
|
+
}
|
|
3102
|
+
|
|
2772
3103
|
// src/packages/uom/parselets/UomLiteralParselet.ts
|
|
2773
3104
|
function resolveUnitAlias(rawUnit) {
|
|
2774
|
-
return
|
|
3105
|
+
return chunkHIQ5HSZL_cjs.resolveCurrencyAlias(rawUnit) ?? rawUnit;
|
|
2775
3106
|
}
|
|
2776
3107
|
var UomLiteralParselet = class {
|
|
2777
3108
|
constructor() {
|
|
2778
3109
|
this.category = "UoM";
|
|
2779
|
-
this.bindingPower =
|
|
3110
|
+
this.bindingPower = chunkJ45BCEZ4_cjs.BindingPower.Postfix;
|
|
2780
3111
|
}
|
|
2781
3112
|
parse(parser, left, token, builder) {
|
|
2782
3113
|
const unit = resolveUnitAlias(token.value);
|
|
2783
3114
|
builder.emitOpcode(13 /* PUSH_STRING */);
|
|
2784
3115
|
builder.emitString(unit);
|
|
2785
|
-
|
|
3116
|
+
const boundInsideProduct = parser.infixMinBindingPower >= chunkJ45BCEZ4_cjs.BindingPower.Product;
|
|
3117
|
+
if (!boundInsideProduct && (parser.peek()?.type === "TO" || parser.peek()?.type === "IN")) {
|
|
2786
3118
|
parser.consume();
|
|
2787
3119
|
const targetToken = parser.peek();
|
|
2788
3120
|
if (targetToken?.type === "UNIT" || targetToken?.type === "IN") {
|
|
2789
3121
|
parser.consume();
|
|
3122
|
+
const targetUnit = resolveUnitAlias(targetToken.value);
|
|
3123
|
+
const isoDate = tryConsumeCurrencyOnDate(parser, targetUnit, unit);
|
|
3124
|
+
if (isoDate !== null) {
|
|
3125
|
+
builder.emitOpcode(80 /* UOM_CONVERT */);
|
|
3126
|
+
builder.emitOpcode(13 /* PUSH_STRING */);
|
|
3127
|
+
builder.emitString(targetUnit);
|
|
3128
|
+
builder.emitOpcode(13 /* PUSH_STRING */);
|
|
3129
|
+
builder.emitString(isoDate);
|
|
3130
|
+
builder.emitOpcode(50 /* CALL_PLUGIN */);
|
|
3131
|
+
builder.emitIndex(HISTORICAL_CURRENCY_FN_IDX);
|
|
3132
|
+
builder.emitIndex(3);
|
|
3133
|
+
return;
|
|
3134
|
+
}
|
|
2790
3135
|
builder.emitOpcode(13 /* PUSH_STRING */);
|
|
2791
|
-
builder.emitString(
|
|
3136
|
+
builder.emitString(targetUnit);
|
|
2792
3137
|
builder.emitOpcode(81 /* UOM_CONVERT_TO */);
|
|
2793
3138
|
return;
|
|
2794
3139
|
}
|
|
@@ -2809,14 +3154,14 @@ var UomLiteralParselet = class {
|
|
|
2809
3154
|
|
|
2810
3155
|
// src/packages/uom/parselets/ConvertParselet.ts
|
|
2811
3156
|
function resolveUnitAlias2(rawUnit) {
|
|
2812
|
-
return
|
|
3157
|
+
return chunkHIQ5HSZL_cjs.resolveCurrencyAlias(rawUnit) ?? rawUnit;
|
|
2813
3158
|
}
|
|
2814
3159
|
var ConvertParselet = class {
|
|
2815
3160
|
constructor() {
|
|
2816
3161
|
this.category = "UoM";
|
|
2817
3162
|
}
|
|
2818
3163
|
parse(parser, token, builder) {
|
|
2819
|
-
parser.parseExpression(
|
|
3164
|
+
parser.parseExpression(chunkJ45BCEZ4_cjs.BindingPower.Postfix, builder);
|
|
2820
3165
|
const nextToken = parser.peek();
|
|
2821
3166
|
if (nextToken && nextToken.type === "UNIT") {
|
|
2822
3167
|
parser.consume();
|
|
@@ -2881,7 +3226,7 @@ function uomPossibilitiesNormalizerRule(priority = 60) {
|
|
|
2881
3226
|
if (questionToken.type !== "QUESTION") return null;
|
|
2882
3227
|
return {
|
|
2883
3228
|
consumed: 3,
|
|
2884
|
-
replacement: [
|
|
3229
|
+
replacement: [chunkC75AFGVD_cjs.createFusedToken("UOM_POSSIBILITIES_QUERY", unitToken.value, [unitToken, toToken, questionToken])],
|
|
2885
3230
|
ruleName: "uom:possibilities"
|
|
2886
3231
|
};
|
|
2887
3232
|
}
|
|
@@ -2933,8 +3278,8 @@ function compoundQuantityNormalizerRule(priority = 63) {
|
|
|
2933
3278
|
return {
|
|
2934
3279
|
consumed,
|
|
2935
3280
|
replacement: [
|
|
2936
|
-
|
|
2937
|
-
|
|
3281
|
+
chunkC75AFGVD_cjs.createFusedToken("NUMBER", String(scaled), source),
|
|
3282
|
+
chunkC75AFGVD_cjs.createFusedToken("UNIT", smallestUnit, [smallestUnitToken])
|
|
2938
3283
|
],
|
|
2939
3284
|
ruleName: "uom:compound-quantity"
|
|
2940
3285
|
};
|
|
@@ -2962,7 +3307,7 @@ function twoUnitConversionNormalizerRule(priority = 59) {
|
|
|
2962
3307
|
return {
|
|
2963
3308
|
consumed: 4,
|
|
2964
3309
|
replacement: [
|
|
2965
|
-
|
|
3310
|
+
chunkC75AFGVD_cjs.createFusedToken("IN_TWO_UNITS", `${major} ${minor}`, tokens.slice(pos, pos + 4))
|
|
2966
3311
|
],
|
|
2967
3312
|
ruleName: "uom:two-unit-conversion"
|
|
2968
3313
|
};
|
|
@@ -2983,7 +3328,7 @@ function degreeSymbolNormalizerRule(priority = 74) {
|
|
|
2983
3328
|
if ((symbol.text ?? symbol.value ?? "") !== "\xB0") return null;
|
|
2984
3329
|
return {
|
|
2985
3330
|
consumed: 2,
|
|
2986
|
-
replacement: [number,
|
|
3331
|
+
replacement: [number, chunkC75AFGVD_cjs.createFusedToken("UNIT", "degrees", [symbol])],
|
|
2987
3332
|
ruleName: "uom:degree-symbol"
|
|
2988
3333
|
};
|
|
2989
3334
|
}
|
|
@@ -2995,7 +3340,7 @@ var TwoUnitConversionParselet = class {
|
|
|
2995
3340
|
constructor(builtinIndex) {
|
|
2996
3341
|
this.builtinIndex = builtinIndex;
|
|
2997
3342
|
this.category = "Uom";
|
|
2998
|
-
this.bindingPower =
|
|
3343
|
+
this.bindingPower = chunkJ45BCEZ4_cjs.BindingPower.Conditional;
|
|
2999
3344
|
}
|
|
3000
3345
|
parse(_parser, _left, token, builder) {
|
|
3001
3346
|
const [major, minor] = String(token.value).split(" ");
|
|
@@ -3035,7 +3380,7 @@ function bareRateDenominatorNormalizerRule(priority = 75) {
|
|
|
3035
3380
|
if (introduces && isUnit2(tokens[pos + 3])) {
|
|
3036
3381
|
return {
|
|
3037
3382
|
consumed: 2,
|
|
3038
|
-
replacement: [head,
|
|
3383
|
+
replacement: [head, chunkC75AFGVD_cjs.createFusedToken("UNIT", label.value, [label])],
|
|
3039
3384
|
ruleName: "uom:bare-rate-denominator"
|
|
3040
3385
|
};
|
|
3041
3386
|
}
|
|
@@ -3049,7 +3394,7 @@ function bareRateDenominatorNormalizerRule(priority = 75) {
|
|
|
3049
3394
|
return {
|
|
3050
3395
|
consumed: 2,
|
|
3051
3396
|
replacement: [
|
|
3052
|
-
|
|
3397
|
+
chunkC75AFGVD_cjs.createFusedToken("PER_UNIT", unitToken.value, [head, unitToken])
|
|
3053
3398
|
],
|
|
3054
3399
|
ruleName: "uom:bare-rate-denominator"
|
|
3055
3400
|
};
|
|
@@ -3062,7 +3407,7 @@ var PerUnitParselet = class {
|
|
|
3062
3407
|
constructor(builtinIndex) {
|
|
3063
3408
|
this.builtinIndex = builtinIndex;
|
|
3064
3409
|
this.category = "Uom";
|
|
3065
|
-
this.bindingPower =
|
|
3410
|
+
this.bindingPower = chunkJ45BCEZ4_cjs.BindingPower.Product;
|
|
3066
3411
|
}
|
|
3067
3412
|
parse(_parser, _left, token, builder) {
|
|
3068
3413
|
builder.emitOpcode(13 /* PUSH_STRING */);
|
|
@@ -3078,10 +3423,10 @@ var AtRateParselet = class {
|
|
|
3078
3423
|
constructor(builtinIndex) {
|
|
3079
3424
|
this.builtinIndex = builtinIndex;
|
|
3080
3425
|
this.category = "Uom";
|
|
3081
|
-
this.bindingPower =
|
|
3426
|
+
this.bindingPower = chunkJ45BCEZ4_cjs.BindingPower.Product;
|
|
3082
3427
|
}
|
|
3083
3428
|
parse(parser, _left, _token, builder) {
|
|
3084
|
-
parser.parseExpression(
|
|
3429
|
+
parser.parseExpression(chunkJ45BCEZ4_cjs.BindingPower.Conditional, builder);
|
|
3085
3430
|
builder.emitOpcode(51 /* CALL_BUILTIN */);
|
|
3086
3431
|
builder.emitIndex(this.builtinIndex);
|
|
3087
3432
|
builder.emitIndex(2);
|
|
@@ -3114,7 +3459,7 @@ function atRateNormalizerRule(priority = 73) {
|
|
|
3114
3459
|
if (!hasRateAhead(tokens, pos + 1)) return null;
|
|
3115
3460
|
return {
|
|
3116
3461
|
consumed: 1,
|
|
3117
|
-
replacement: [
|
|
3462
|
+
replacement: [chunkC75AFGVD_cjs.createFusedToken("AT_RATE", "at", [tokens[pos]])],
|
|
3118
3463
|
ruleName: "uom:at-rate"
|
|
3119
3464
|
};
|
|
3120
3465
|
}
|
|
@@ -3141,8 +3486,8 @@ function forDurationNormalizerRule(priority = 76) {
|
|
|
3141
3486
|
return {
|
|
3142
3487
|
consumed: 3,
|
|
3143
3488
|
replacement: [
|
|
3144
|
-
|
|
3145
|
-
|
|
3489
|
+
chunkC75AFGVD_cjs.createFusedToken("STAR", "*", [head]),
|
|
3490
|
+
chunkC75AFGVD_cjs.createFusedToken("NUMBER", "1", [article]),
|
|
3146
3491
|
tokens[pos + 2]
|
|
3147
3492
|
],
|
|
3148
3493
|
ruleName: "uom:for-duration"
|
|
@@ -3179,7 +3524,7 @@ function reversedConversionNormalizerRule(priority = 61) {
|
|
|
3179
3524
|
return {
|
|
3180
3525
|
consumed: 4,
|
|
3181
3526
|
replacement: [
|
|
3182
|
-
|
|
3527
|
+
chunkC75AFGVD_cjs.createFusedToken("NUMBER", "1", [third]),
|
|
3183
3528
|
tokens[pos + 3],
|
|
3184
3529
|
tokens[pos + 1],
|
|
3185
3530
|
target
|
|
@@ -3288,54 +3633,54 @@ function getIngredientDensity(name) {
|
|
|
3288
3633
|
}
|
|
3289
3634
|
|
|
3290
3635
|
// src/packages/uom/parselets/CookingPluginFunctions.ts
|
|
3291
|
-
var COOKING_CONVERT_IDX =
|
|
3636
|
+
var COOKING_CONVERT_IDX = chunk7ZX6B7SY_cjs.allocatePluginFunctionIndex();
|
|
3292
3637
|
function cookingConvertHandler(args) {
|
|
3293
3638
|
const amountValue = args[0];
|
|
3294
3639
|
const ingredientName = args[1].value;
|
|
3295
3640
|
const targetUnitText = args[2].value;
|
|
3296
3641
|
if (amountValue.type !== 6 /* Uom */ || !amountValue.unit) {
|
|
3297
|
-
return
|
|
3642
|
+
return chunk2TZKENDH_cjs.errorValue(
|
|
3298
3643
|
"COOKING_CONVERSION_REQUIRES_UNIT",
|
|
3299
3644
|
`Expected a value with a mass or volume unit (e.g. "300g", "10 cups"), got a plain number`
|
|
3300
3645
|
);
|
|
3301
3646
|
}
|
|
3302
3647
|
const sourceUnit = amountValue.unit;
|
|
3303
3648
|
const amount = amountValue.toNumber();
|
|
3304
|
-
const sourceMeasure =
|
|
3305
|
-
const targetMeasure =
|
|
3649
|
+
const sourceMeasure = chunkEJ3ILXX6_cjs.getMeasure(sourceUnit);
|
|
3650
|
+
const targetMeasure = chunkEJ3ILXX6_cjs.getMeasure(targetUnitText);
|
|
3306
3651
|
const isMassOrVolume = (m) => m === "mass" || m === "volume";
|
|
3307
3652
|
if (!isMassOrVolume(sourceMeasure)) {
|
|
3308
|
-
return
|
|
3653
|
+
return chunk2TZKENDH_cjs.errorValue(
|
|
3309
3654
|
"COOKING_CONVERSION_UNSUPPORTED_UNIT",
|
|
3310
3655
|
`"${sourceUnit}" is not a recognized mass or volume unit`
|
|
3311
3656
|
);
|
|
3312
3657
|
}
|
|
3313
3658
|
if (!isMassOrVolume(targetMeasure)) {
|
|
3314
|
-
return
|
|
3659
|
+
return chunk2TZKENDH_cjs.errorValue(
|
|
3315
3660
|
"COOKING_CONVERSION_UNSUPPORTED_UNIT",
|
|
3316
3661
|
`"${targetUnitText}" is not a recognized mass or volume unit`
|
|
3317
3662
|
);
|
|
3318
3663
|
}
|
|
3319
3664
|
if (sourceMeasure === targetMeasure) {
|
|
3320
|
-
return
|
|
3665
|
+
return chunk2TZKENDH_cjs.uomValue(chunkEJ3ILXX6_cjs.convertUnit(amount, sourceUnit, targetUnitText), targetUnitText);
|
|
3321
3666
|
}
|
|
3322
3667
|
const density = getIngredientDensity(ingredientName);
|
|
3323
3668
|
if (density === void 0) {
|
|
3324
|
-
return
|
|
3669
|
+
return chunk2TZKENDH_cjs.errorValue(
|
|
3325
3670
|
"COOKING_UNKNOWN_INGREDIENT",
|
|
3326
3671
|
`No density data for "${ingredientName}" \u2014 cannot convert between mass and volume for this ingredient`
|
|
3327
3672
|
);
|
|
3328
3673
|
}
|
|
3329
3674
|
if (sourceMeasure === "mass") {
|
|
3330
|
-
const grams2 =
|
|
3675
|
+
const grams2 = chunkEJ3ILXX6_cjs.convertUnit(amount, sourceUnit, "g");
|
|
3331
3676
|
const mL2 = grams2 / density;
|
|
3332
|
-
const result2 =
|
|
3333
|
-
return
|
|
3677
|
+
const result2 = chunkEJ3ILXX6_cjs.convertUnit(mL2, "ml", targetUnitText);
|
|
3678
|
+
return chunk2TZKENDH_cjs.uomValue(result2, targetUnitText);
|
|
3334
3679
|
}
|
|
3335
|
-
const mL =
|
|
3680
|
+
const mL = chunkEJ3ILXX6_cjs.convertUnit(amount, sourceUnit, "ml");
|
|
3336
3681
|
const grams = mL * density;
|
|
3337
|
-
const result =
|
|
3338
|
-
return
|
|
3682
|
+
const result = chunkEJ3ILXX6_cjs.convertUnit(grams, "g", targetUnitText);
|
|
3683
|
+
return chunk2TZKENDH_cjs.uomValue(result, targetUnitText);
|
|
3339
3684
|
}
|
|
3340
3685
|
|
|
3341
3686
|
// src/packages/uom/parselets/CookingConversionParselet.ts
|
|
@@ -3378,7 +3723,7 @@ function ingredientNameNormalizerRule(priority = 68) {
|
|
|
3378
3723
|
const candidate = candidateTokens.map((t) => t.value.toLowerCase()).join(" ");
|
|
3379
3724
|
return {
|
|
3380
3725
|
consumed: wordCount,
|
|
3381
|
-
replacement: [
|
|
3726
|
+
replacement: [chunkC75AFGVD_cjs.createFusedToken("INGREDIENT_NAME", candidate, candidateTokens)],
|
|
3382
3727
|
ruleName: "uom-cooking:ingredient-name"
|
|
3383
3728
|
};
|
|
3384
3729
|
}
|
|
@@ -3401,13 +3746,35 @@ function multiWordUnitNormalizerRule(priority = 78) {
|
|
|
3401
3746
|
if (chunkAMOJYLG2_cjs.UNIT_TABLE[spelling] === void 0) return null;
|
|
3402
3747
|
return {
|
|
3403
3748
|
consumed: 2,
|
|
3404
|
-
replacement: [
|
|
3749
|
+
replacement: [chunkC75AFGVD_cjs.createFusedToken("UNIT", spelling, tokens.slice(pos, pos + 2))],
|
|
3405
3750
|
ruleName: "uom:multi-word-unit"
|
|
3406
3751
|
};
|
|
3407
3752
|
}
|
|
3408
3753
|
};
|
|
3409
3754
|
}
|
|
3410
3755
|
|
|
3756
|
+
// src/packages/uom/normalizer/CompoundUnitNormalizerRule.ts
|
|
3757
|
+
function compoundUnitNormalizerRule(priority = 77) {
|
|
3758
|
+
return {
|
|
3759
|
+
name: "uom:compound-unit",
|
|
3760
|
+
priority,
|
|
3761
|
+
match(tokens, pos) {
|
|
3762
|
+
const numerator = tokens[pos];
|
|
3763
|
+
const slash = tokens[pos + 1];
|
|
3764
|
+
const denominator = tokens[pos + 2];
|
|
3765
|
+
if (numerator?.type !== "UNIT") return null;
|
|
3766
|
+
if (slash?.type !== "SLASH") return null;
|
|
3767
|
+
if (denominator?.type !== "UNIT") return null;
|
|
3768
|
+
const spelling = `${numerator.value}/${denominator.value}`;
|
|
3769
|
+
return {
|
|
3770
|
+
consumed: 3,
|
|
3771
|
+
replacement: [chunkC75AFGVD_cjs.createFusedToken("UNIT", spelling, [numerator, slash, denominator])],
|
|
3772
|
+
ruleName: "uom:compound-unit"
|
|
3773
|
+
};
|
|
3774
|
+
}
|
|
3775
|
+
};
|
|
3776
|
+
}
|
|
3777
|
+
|
|
3411
3778
|
// src/packages/uom/UomPackage.ts
|
|
3412
3779
|
var UOM_PACKAGE = {
|
|
3413
3780
|
name: "solve-uom",
|
|
@@ -3426,6 +3793,9 @@ var UOM_PACKAGE = {
|
|
|
3426
3793
|
// Highest priority of the unit rules: a two-word spelling has to become one
|
|
3427
3794
|
// token before anything else reads the first word as a unit on its own.
|
|
3428
3795
|
multiWordUnitNormalizerRule(),
|
|
3796
|
+
// Above the bare-denominator rule (75): a slash-notation compound unit like
|
|
3797
|
+
// `km/h` is claimed whole before the slash is read as a bare denominator.
|
|
3798
|
+
compoundUnitNormalizerRule(),
|
|
3429
3799
|
uomPossibilitiesNormalizerRule(),
|
|
3430
3800
|
compoundQuantityNormalizerRule(),
|
|
3431
3801
|
twoUnitConversionNormalizerRule(),
|
|
@@ -3447,8 +3817,8 @@ var CurrencySymbolParselet = class {
|
|
|
3447
3817
|
this.category = "UoM";
|
|
3448
3818
|
}
|
|
3449
3819
|
parse(parser, token, builder) {
|
|
3450
|
-
const currency =
|
|
3451
|
-
parser.parseExpression(
|
|
3820
|
+
const currency = chunkHIQ5HSZL_cjs.resolveCurrencyAlias(token.value) ?? token.value.toUpperCase();
|
|
3821
|
+
parser.parseExpression(chunkJ45BCEZ4_cjs.BindingPower.Prefix, builder);
|
|
3452
3822
|
if (parser.peek()?.type === "UNIT") {
|
|
3453
3823
|
parser.consume();
|
|
3454
3824
|
}
|
|
@@ -3468,32 +3838,59 @@ var InParselet = class {
|
|
|
3468
3838
|
const targetToken = parser.peek();
|
|
3469
3839
|
if (targetToken && (targetToken.type === "UNIT" || targetToken.type === "DOLLAR" || targetToken.type === "POUND" || targetToken.type === "EURO" || targetToken.type === "YEN" || targetToken.type === "RUBLE" || targetToken.type === "WON" || targetToken.type === "CURRENCY_SYMBOL" || targetToken.type === "IDENT" || targetToken.type === "IN")) {
|
|
3470
3840
|
parser.consume();
|
|
3841
|
+
const targetUnit = chunkHIQ5HSZL_cjs.resolveCurrencyAlias(targetToken.value) ?? targetToken.value;
|
|
3842
|
+
const isoDate = tryConsumeCurrencyOnDate(parser, targetUnit);
|
|
3843
|
+
if (isoDate !== null) {
|
|
3844
|
+
builder.emitOpcode(13 /* PUSH_STRING */);
|
|
3845
|
+
builder.emitString(targetUnit);
|
|
3846
|
+
builder.emitOpcode(13 /* PUSH_STRING */);
|
|
3847
|
+
builder.emitString(isoDate);
|
|
3848
|
+
builder.emitOpcode(50 /* CALL_PLUGIN */);
|
|
3849
|
+
builder.emitIndex(HISTORICAL_CURRENCY_FN_IDX);
|
|
3850
|
+
builder.emitIndex(3);
|
|
3851
|
+
return;
|
|
3852
|
+
}
|
|
3471
3853
|
builder.emitOpcode(13 /* PUSH_STRING */);
|
|
3472
|
-
builder.emitString(
|
|
3854
|
+
builder.emitString(targetUnit);
|
|
3473
3855
|
builder.emitOpcode(84 /* UOM_CONVERT_IN */);
|
|
3474
3856
|
}
|
|
3475
3857
|
}
|
|
3476
3858
|
};
|
|
3477
3859
|
|
|
3478
3860
|
// src/packages/currency/CurrencyPackage.ts
|
|
3479
|
-
|
|
3480
|
-
|
|
3481
|
-
|
|
3482
|
-
|
|
3483
|
-
|
|
3484
|
-
|
|
3485
|
-
|
|
3486
|
-
|
|
3487
|
-
|
|
3488
|
-
|
|
3489
|
-
|
|
3490
|
-
|
|
3491
|
-
|
|
3492
|
-
|
|
3493
|
-
|
|
3494
|
-
|
|
3495
|
-
|
|
3496
|
-
|
|
3861
|
+
function createCurrencyPackage(config = {}) {
|
|
3862
|
+
return {
|
|
3863
|
+
name: "solve-currency",
|
|
3864
|
+
asyncResolvers: [
|
|
3865
|
+
new chunkSSV46KFA_cjs.CurrencyAsyncResolver(),
|
|
3866
|
+
createHistoricalCurrencyResolver(config.historicalRateProvider)
|
|
3867
|
+
],
|
|
3868
|
+
prefixParselets: [
|
|
3869
|
+
{ tokenType: "DOLLAR", parselet: new CurrencySymbolParselet() },
|
|
3870
|
+
{ tokenType: "POUND", parselet: new CurrencySymbolParselet() },
|
|
3871
|
+
{ tokenType: "EURO", parselet: new CurrencySymbolParselet() },
|
|
3872
|
+
{ tokenType: "YEN", parselet: new CurrencySymbolParselet() },
|
|
3873
|
+
{ tokenType: "RUBLE", parselet: new CurrencySymbolParselet() },
|
|
3874
|
+
{ tokenType: "WON", parselet: new CurrencySymbolParselet() },
|
|
3875
|
+
// Every currency symbol added after the original six above shares this
|
|
3876
|
+
// one generic token type. See Token.ts's CURRENCY_SYMBOL doc comment.
|
|
3877
|
+
{ tokenType: "CURRENCY_SYMBOL", parselet: new CurrencySymbolParselet() }
|
|
3878
|
+
],
|
|
3879
|
+
infixParselets: [
|
|
3880
|
+
{ tokenType: "IN", parselet: new InParselet() }
|
|
3881
|
+
],
|
|
3882
|
+
pluginFunctions: [
|
|
3883
|
+
// Historical conversions (`<money> in <currency> on <date>`) compile to a
|
|
3884
|
+
// CALL_PLUGIN at this shared index (see uom/HistoricalCurrency.ts). One
|
|
3885
|
+
// index serves every pair and date, the query is the amount plus the
|
|
3886
|
+
// target and date strings. The handler carries the same provider as the
|
|
3887
|
+
// resolver, so a source currency known only at runtime (`x in GBP on
|
|
3888
|
+
// <date>`) can fetch the rate the bytecode scan could not preflight.
|
|
3889
|
+
{ index: HISTORICAL_CURRENCY_FN_IDX, handler: createHistoricalCurrencyPluginFunction(config.historicalRateProvider) }
|
|
3890
|
+
]
|
|
3891
|
+
};
|
|
3892
|
+
}
|
|
3893
|
+
var CURRENCY_PACKAGE = createCurrencyPackage();
|
|
3497
3894
|
|
|
3498
3895
|
// src/packages/vector/parselets/VectorParselet.ts
|
|
3499
3896
|
var VectorParselet = class {
|
|
@@ -3554,7 +3951,7 @@ var MatrixLiteralParselet = class {
|
|
|
3554
3951
|
let rows = 0;
|
|
3555
3952
|
let cols = -1;
|
|
3556
3953
|
if (parser.peek()?.type === "RBRACKET") {
|
|
3557
|
-
throw
|
|
3954
|
+
throw chunkB4HBEFTB_cjs.ErrorFactory.parsing(
|
|
3558
3955
|
"EMPTY_MATRIX_LITERAL",
|
|
3559
3956
|
"A matrix literal cannot be empty \u2014 `[]` has no valid shape.",
|
|
3560
3957
|
{}
|
|
@@ -3571,7 +3968,7 @@ var MatrixLiteralParselet = class {
|
|
|
3571
3968
|
if (cols === -1) {
|
|
3572
3969
|
cols = rowCols;
|
|
3573
3970
|
} else if (rowCols !== cols) {
|
|
3574
|
-
throw
|
|
3971
|
+
throw chunkB4HBEFTB_cjs.ErrorFactory.parsing(
|
|
3575
3972
|
"RAGGED_MATRIX_LITERAL",
|
|
3576
3973
|
`Matrix literal rows must all have the same number of columns \u2014 row ${rows + 1} has ${rowCols}, but a previous row has ${cols}.`,
|
|
3577
3974
|
{ expectedCols: cols, actualCols: rowCols, row: rows + 1 }
|
|
@@ -3591,7 +3988,7 @@ var MatrixLiteralParselet = class {
|
|
|
3591
3988
|
var MatrixIndexParselet = class {
|
|
3592
3989
|
constructor() {
|
|
3593
3990
|
this.category = "Matrix";
|
|
3594
|
-
this.bindingPower =
|
|
3991
|
+
this.bindingPower = chunkJ45BCEZ4_cjs.BindingPower.Postfix;
|
|
3595
3992
|
}
|
|
3596
3993
|
parse(parser, _left, _token, builder) {
|
|
3597
3994
|
const isSlice = this.hasTopLevelColon(parser);
|
|
@@ -3611,7 +4008,7 @@ var MatrixIndexParselet = class {
|
|
|
3611
4008
|
return;
|
|
3612
4009
|
}
|
|
3613
4010
|
if (argCount !== 2) {
|
|
3614
|
-
throw
|
|
4011
|
+
throw chunkB4HBEFTB_cjs.ErrorFactory.parsing(
|
|
3615
4012
|
"INVALID_MATRIX_SLICE_ARITY",
|
|
3616
4013
|
`Range-based matrix slicing needs exactly 2 arguments ("a[rowRange, colRange]"), got ${argCount}.`,
|
|
3617
4014
|
{ argCount }
|
|
@@ -3694,12 +4091,12 @@ function parseTransform(parser, builder) {
|
|
|
3694
4091
|
}
|
|
3695
4092
|
return { kind: 2, name };
|
|
3696
4093
|
}
|
|
3697
|
-
const transformBuilder = new
|
|
3698
|
-
parser.parseExpression(
|
|
4094
|
+
const transformBuilder = new chunkJ45BCEZ4_cjs.BytecodeBuilder();
|
|
4095
|
+
parser.parseExpression(chunkJ45BCEZ4_cjs.BindingPower.Lowest, transformBuilder);
|
|
3699
4096
|
parser.setBuilder(builder);
|
|
3700
4097
|
const program = transformBuilder.build();
|
|
3701
4098
|
if (program.hasAsync) {
|
|
3702
|
-
throw
|
|
4099
|
+
throw chunkB4HBEFTB_cjs.ErrorFactory.parsing(
|
|
3703
4100
|
"MAP_REDUCE_TRANSFORM_MUST_BE_SYNCHRONOUS",
|
|
3704
4101
|
`map/reduce transform expressions must be synchronous (no weather/stocks/currency calls).`
|
|
3705
4102
|
);
|
|
@@ -3717,7 +4114,7 @@ function consumeCollectionName(parser) {
|
|
|
3717
4114
|
parser.consume();
|
|
3718
4115
|
return token.value;
|
|
3719
4116
|
}
|
|
3720
|
-
throw
|
|
4117
|
+
throw chunkB4HBEFTB_cjs.ErrorFactory.parsing(
|
|
3721
4118
|
"MAP_REDUCE_EXPECTED_COLLECTION_NAME",
|
|
3722
4119
|
`Expected a collection name (e.g. "x" in "x=[1,2,3]") but got ${token ? `"${token.value}"` : "end of input"}.`
|
|
3723
4120
|
);
|
|
@@ -3781,7 +4178,7 @@ var ReduceParselet = class {
|
|
|
3781
4178
|
parseCollectionExpr(parser, builder);
|
|
3782
4179
|
let hasInitial = 0;
|
|
3783
4180
|
if (parser.match("COMMA")) {
|
|
3784
|
-
parser.parseExpression(
|
|
4181
|
+
parser.parseExpression(chunkJ45BCEZ4_cjs.BindingPower.Lowest, builder);
|
|
3785
4182
|
hasInitial = 1;
|
|
3786
4183
|
}
|
|
3787
4184
|
parser.consume("RPAREN");
|
|
@@ -3796,15 +4193,15 @@ var SumParselet = class {
|
|
|
3796
4193
|
}
|
|
3797
4194
|
parse(parser, _token, builder) {
|
|
3798
4195
|
parser.consume("LPAREN");
|
|
3799
|
-
const bodyBuilder = new
|
|
4196
|
+
const bodyBuilder = new chunkJ45BCEZ4_cjs.BytecodeBuilder();
|
|
3800
4197
|
bodyBuilder.emitOpcode(60 /* LOAD_VAR */);
|
|
3801
4198
|
bodyBuilder.emitString("acc");
|
|
3802
|
-
parser.parseExpression(
|
|
4199
|
+
parser.parseExpression(chunkJ45BCEZ4_cjs.BindingPower.Lowest, bodyBuilder);
|
|
3803
4200
|
parser.setBuilder(builder);
|
|
3804
4201
|
bodyBuilder.emitOpcode(20 /* ADD */);
|
|
3805
4202
|
const bodyProgram = bodyBuilder.build();
|
|
3806
4203
|
if (bodyProgram.hasAsync) {
|
|
3807
|
-
throw
|
|
4204
|
+
throw chunkB4HBEFTB_cjs.ErrorFactory.parsing(
|
|
3808
4205
|
"MAP_REDUCE_TRANSFORM_MUST_BE_SYNCHRONOUS",
|
|
3809
4206
|
`sum's element expression must be synchronous (no weather/stocks/currency calls).`
|
|
3810
4207
|
);
|
|
@@ -3825,15 +4222,15 @@ var ProdParselet = class {
|
|
|
3825
4222
|
}
|
|
3826
4223
|
parse(parser, _token, builder) {
|
|
3827
4224
|
parser.consume("LPAREN");
|
|
3828
|
-
const bodyBuilder = new
|
|
4225
|
+
const bodyBuilder = new chunkJ45BCEZ4_cjs.BytecodeBuilder();
|
|
3829
4226
|
bodyBuilder.emitOpcode(60 /* LOAD_VAR */);
|
|
3830
4227
|
bodyBuilder.emitString("acc");
|
|
3831
|
-
parser.parseExpression(
|
|
4228
|
+
parser.parseExpression(chunkJ45BCEZ4_cjs.BindingPower.Lowest, bodyBuilder);
|
|
3832
4229
|
parser.setBuilder(builder);
|
|
3833
4230
|
bodyBuilder.emitOpcode(22 /* MUL */);
|
|
3834
4231
|
const bodyProgram = bodyBuilder.build();
|
|
3835
4232
|
if (bodyProgram.hasAsync) {
|
|
3836
|
-
throw
|
|
4233
|
+
throw chunkB4HBEFTB_cjs.ErrorFactory.parsing(
|
|
3837
4234
|
"MAP_REDUCE_TRANSFORM_MUST_BE_SYNCHRONOUS",
|
|
3838
4235
|
`prod's element expression must be synchronous (no weather/stocks/currency calls).`
|
|
3839
4236
|
);
|
|
@@ -3878,7 +4275,7 @@ function mapReduceCallNormalizerRule(priority = 80) {
|
|
|
3878
4275
|
return {
|
|
3879
4276
|
consumed: 1,
|
|
3880
4277
|
replacement: [
|
|
3881
|
-
new
|
|
4278
|
+
new chunkYTIYVHL7_cjs.LexerToken(tokenType, chunkQFTDTX6K_cjs.tokenTypeId(tokenType), token.value, token.value, token.offset, 0, token.line, token.col)
|
|
3882
4279
|
],
|
|
3883
4280
|
ruleName: "mapreduce:call"
|
|
3884
4281
|
};
|
|
@@ -3920,7 +4317,7 @@ var ExpandParselet = class {
|
|
|
3920
4317
|
}
|
|
3921
4318
|
parse(parser, _token, builder) {
|
|
3922
4319
|
parser.consume("LPAREN");
|
|
3923
|
-
parser.parseExpression(
|
|
4320
|
+
parser.parseExpression(chunkJ45BCEZ4_cjs.BindingPower.Lowest, builder);
|
|
3924
4321
|
parser.consume("RPAREN");
|
|
3925
4322
|
builder.emitOpcode(51 /* CALL_BUILTIN */);
|
|
3926
4323
|
builder.emitIndex(SYMBOLIC_BUILTIN_EXPAND);
|
|
@@ -3935,7 +4332,7 @@ var FactorParselet = class {
|
|
|
3935
4332
|
}
|
|
3936
4333
|
parse(parser, _token, builder) {
|
|
3937
4334
|
parser.consume("LPAREN");
|
|
3938
|
-
parser.parseExpression(
|
|
4335
|
+
parser.parseExpression(chunkJ45BCEZ4_cjs.BindingPower.Lowest, builder);
|
|
3939
4336
|
parser.consume("RPAREN");
|
|
3940
4337
|
builder.emitOpcode(51 /* CALL_BUILTIN */);
|
|
3941
4338
|
builder.emitIndex(SYMBOLIC_BUILTIN_FACTOR);
|
|
@@ -3947,7 +4344,7 @@ var FactorParselet = class {
|
|
|
3947
4344
|
function readVariableName(parser, verb) {
|
|
3948
4345
|
const token = parser.peek();
|
|
3949
4346
|
if (!token || token.type !== "IDENT" && token.type !== "UNIT") {
|
|
3950
|
-
throw
|
|
4347
|
+
throw chunkB4HBEFTB_cjs.ErrorFactory.parsing(
|
|
3951
4348
|
"SYMBOLIC_REQUIRES_VARIABLE_NAME",
|
|
3952
4349
|
`${verb} needs the name of an unknown here, as in ${verb}(x^2, x).`,
|
|
3953
4350
|
{ found: token?.type ?? "end of input" }
|
|
@@ -3961,12 +4358,12 @@ function emitVariableName(builder, name) {
|
|
|
3961
4358
|
builder.emitString(name);
|
|
3962
4359
|
}
|
|
3963
4360
|
function parseBoundExpression(parser, builder, verb) {
|
|
3964
|
-
const inner = new
|
|
3965
|
-
parser.parseExpression(
|
|
4361
|
+
const inner = new chunkJ45BCEZ4_cjs.BytecodeBuilder();
|
|
4362
|
+
parser.parseExpression(chunkJ45BCEZ4_cjs.BindingPower.Lowest, inner);
|
|
3966
4363
|
parser.setBuilder(builder);
|
|
3967
4364
|
const program = inner.build();
|
|
3968
4365
|
if (program.hasAsync) {
|
|
3969
|
-
throw
|
|
4366
|
+
throw chunkB4HBEFTB_cjs.ErrorFactory.parsing(
|
|
3970
4367
|
"SYMBOLIC_ARGUMENT_MUST_BE_SYNCHRONOUS",
|
|
3971
4368
|
`${verb}'s expression must be synchronous (no weather/stocks/currency calls).`
|
|
3972
4369
|
);
|
|
@@ -3991,7 +4388,7 @@ var SolveParselet = class {
|
|
|
3991
4388
|
parser.consume("COMMA");
|
|
3992
4389
|
const variable = parser.peek();
|
|
3993
4390
|
if (!variable || variable.type !== "IDENT" && variable.type !== "UNIT") {
|
|
3994
|
-
throw
|
|
4391
|
+
throw chunkB4HBEFTB_cjs.ErrorFactory.parsing(
|
|
3995
4392
|
"SOLVE_REQUIRES_VARIABLE_NAME",
|
|
3996
4393
|
`solve's second argument must be the name of the unknown to solve for, as in solve(x^2-4=0, x).`,
|
|
3997
4394
|
{ found: variable?.type ?? "end of input" }
|
|
@@ -4026,7 +4423,7 @@ var DerParselet = class {
|
|
|
4026
4423
|
emitBoundExpression(builder, expression, variable);
|
|
4027
4424
|
emitVariableName(builder, variable);
|
|
4028
4425
|
if (parser.match("COMMA")) {
|
|
4029
|
-
parser.parseExpression(
|
|
4426
|
+
parser.parseExpression(chunkJ45BCEZ4_cjs.BindingPower.Lowest, builder);
|
|
4030
4427
|
} else {
|
|
4031
4428
|
builder.emitOpcode(10 /* PUSH_NUMBER */);
|
|
4032
4429
|
builder.emitNumber(1);
|
|
@@ -4070,9 +4467,9 @@ var TaylorParselet = class {
|
|
|
4070
4467
|
emitBoundExpression(builder, expression, variable);
|
|
4071
4468
|
emitVariableName(builder, variable);
|
|
4072
4469
|
parser.consume("EQUALS");
|
|
4073
|
-
parser.parseExpression(
|
|
4470
|
+
parser.parseExpression(chunkJ45BCEZ4_cjs.BindingPower.Lowest, builder);
|
|
4074
4471
|
parser.consume("COMMA");
|
|
4075
|
-
parser.parseExpression(
|
|
4472
|
+
parser.parseExpression(chunkJ45BCEZ4_cjs.BindingPower.Lowest, builder);
|
|
4076
4473
|
parser.consume("RPAREN");
|
|
4077
4474
|
builder.emitOpcode(51 /* CALL_BUILTIN */);
|
|
4078
4475
|
builder.emitIndex(SYMBOLIC_BUILTIN_TAYLOR);
|
|
@@ -4089,7 +4486,7 @@ var JacobianParselet = class {
|
|
|
4089
4486
|
parser.consume("LPAREN");
|
|
4090
4487
|
let count = 0;
|
|
4091
4488
|
do {
|
|
4092
|
-
parser.parseExpression(
|
|
4489
|
+
parser.parseExpression(chunkJ45BCEZ4_cjs.BindingPower.Lowest, builder);
|
|
4093
4490
|
count++;
|
|
4094
4491
|
} while (parser.match("COMMA"));
|
|
4095
4492
|
parser.consume("RPAREN");
|
|
@@ -4120,7 +4517,7 @@ var ConjParselet = class {
|
|
|
4120
4517
|
}
|
|
4121
4518
|
parse(parser, _token, builder) {
|
|
4122
4519
|
parser.consume("LPAREN");
|
|
4123
|
-
parser.parseExpression(
|
|
4520
|
+
parser.parseExpression(chunkJ45BCEZ4_cjs.BindingPower.Lowest, builder);
|
|
4124
4521
|
parser.consume("RPAREN");
|
|
4125
4522
|
builder.emitOpcode(51 /* CALL_BUILTIN */);
|
|
4126
4523
|
builder.emitIndex(SYMBOLIC_BUILTIN_CONJ);
|
|
@@ -4135,7 +4532,7 @@ var ReParselet = class {
|
|
|
4135
4532
|
}
|
|
4136
4533
|
parse(parser, _token, builder) {
|
|
4137
4534
|
parser.consume("LPAREN");
|
|
4138
|
-
parser.parseExpression(
|
|
4535
|
+
parser.parseExpression(chunkJ45BCEZ4_cjs.BindingPower.Lowest, builder);
|
|
4139
4536
|
parser.consume("RPAREN");
|
|
4140
4537
|
builder.emitOpcode(51 /* CALL_BUILTIN */);
|
|
4141
4538
|
builder.emitIndex(SYMBOLIC_BUILTIN_RE);
|
|
@@ -4150,7 +4547,7 @@ var ImParselet = class {
|
|
|
4150
4547
|
}
|
|
4151
4548
|
parse(parser, _token, builder) {
|
|
4152
4549
|
parser.consume("LPAREN");
|
|
4153
|
-
parser.parseExpression(
|
|
4550
|
+
parser.parseExpression(chunkJ45BCEZ4_cjs.BindingPower.Lowest, builder);
|
|
4154
4551
|
parser.consume("RPAREN");
|
|
4155
4552
|
builder.emitOpcode(51 /* CALL_BUILTIN */);
|
|
4156
4553
|
builder.emitIndex(SYMBOLIC_BUILTIN_IM);
|
|
@@ -4165,7 +4562,7 @@ var CancelParselet = class {
|
|
|
4165
4562
|
}
|
|
4166
4563
|
parse(parser, _token, builder) {
|
|
4167
4564
|
parser.consume("LPAREN");
|
|
4168
|
-
parser.parseExpression(
|
|
4565
|
+
parser.parseExpression(chunkJ45BCEZ4_cjs.BindingPower.Lowest, builder);
|
|
4169
4566
|
parser.consume("RPAREN");
|
|
4170
4567
|
builder.emitOpcode(51 /* CALL_BUILTIN */);
|
|
4171
4568
|
builder.emitIndex(SYMBOLIC_BUILTIN_CANCEL);
|
|
@@ -4180,7 +4577,7 @@ var ApartParselet = class {
|
|
|
4180
4577
|
}
|
|
4181
4578
|
parse(parser, _token, builder) {
|
|
4182
4579
|
parser.consume("LPAREN");
|
|
4183
|
-
parser.parseExpression(
|
|
4580
|
+
parser.parseExpression(chunkJ45BCEZ4_cjs.BindingPower.Lowest, builder);
|
|
4184
4581
|
parser.consume("RPAREN");
|
|
4185
4582
|
builder.emitOpcode(51 /* CALL_BUILTIN */);
|
|
4186
4583
|
builder.emitIndex(SYMBOLIC_BUILTIN_APART);
|
|
@@ -4203,9 +4600,9 @@ function imaginaryLiteralNormalizerRule(priority = 75) {
|
|
|
4203
4600
|
return {
|
|
4204
4601
|
consumed: 2,
|
|
4205
4602
|
replacement: [
|
|
4206
|
-
new
|
|
4603
|
+
new chunkYTIYVHL7_cjs.LexerToken(
|
|
4207
4604
|
"IMAGINARY",
|
|
4208
|
-
|
|
4605
|
+
chunkQFTDTX6K_cjs.tokenTypeId("IMAGINARY"),
|
|
4209
4606
|
number.value,
|
|
4210
4607
|
number.value,
|
|
4211
4608
|
number.offset,
|
|
@@ -4249,7 +4646,7 @@ function symbolicCallNormalizerRule(priority = 80) {
|
|
|
4249
4646
|
return {
|
|
4250
4647
|
consumed: 1,
|
|
4251
4648
|
replacement: [
|
|
4252
|
-
new
|
|
4649
|
+
new chunkYTIYVHL7_cjs.LexerToken(tokenType, chunkQFTDTX6K_cjs.tokenTypeId(tokenType), token.value, token.value, token.offset, 0, token.line, token.col)
|
|
4253
4650
|
],
|
|
4254
4651
|
ruleName: "symbolic:call"
|
|
4255
4652
|
};
|
|
@@ -4402,7 +4799,7 @@ var BigIntNumberParselet = class {
|
|
|
4402
4799
|
}
|
|
4403
4800
|
parse(parser, token, builder) {
|
|
4404
4801
|
builder.emitOpcode(11 /* PUSH_BIGINT */);
|
|
4405
|
-
builder.emitString(
|
|
4802
|
+
builder.emitString(chunkJ45BCEZ4_cjs.bigIntLiteralDigits(token.value, parser.getLocaleCode()));
|
|
4406
4803
|
}
|
|
4407
4804
|
};
|
|
4408
4805
|
|
|
@@ -4419,7 +4816,7 @@ var ComparisonParselet = class {
|
|
|
4419
4816
|
constructor(opcode) {
|
|
4420
4817
|
this.opcode = opcode;
|
|
4421
4818
|
this.category = "Conditionals";
|
|
4422
|
-
this.bindingPower =
|
|
4819
|
+
this.bindingPower = chunkJ45BCEZ4_cjs.BindingPower.Conditional;
|
|
4423
4820
|
}
|
|
4424
4821
|
parse(parser, left, token, builder) {
|
|
4425
4822
|
parser.parseExpression(this.bindingPower, builder);
|
|
@@ -4482,9 +4879,9 @@ var CONDITIONALS_PACKAGE = {
|
|
|
4482
4879
|
{ tokenType: "GT", parselet: new ComparisonParselet(44 /* GT */) },
|
|
4483
4880
|
{ tokenType: "LTE", parselet: new ComparisonParselet(43 /* LTE */) },
|
|
4484
4881
|
{ tokenType: "GTE", parselet: new ComparisonParselet(45 /* GTE */) },
|
|
4485
|
-
{ tokenType: "OR", parselet: new LogicalParselet(131 /* LOGICAL_OR */,
|
|
4486
|
-
{ tokenType: "LOGICAL_AND", parselet: new LogicalParselet(130 /* LOGICAL_AND */,
|
|
4487
|
-
{ tokenType: "LOGICAL_OR", parselet: new LogicalParselet(131 /* LOGICAL_OR */,
|
|
4882
|
+
{ tokenType: "OR", parselet: new LogicalParselet(131 /* LOGICAL_OR */, chunkJ45BCEZ4_cjs.BindingPower.LogicalOr) },
|
|
4883
|
+
{ tokenType: "LOGICAL_AND", parselet: new LogicalParselet(130 /* LOGICAL_AND */, chunkJ45BCEZ4_cjs.BindingPower.LogicalAnd) },
|
|
4884
|
+
{ tokenType: "LOGICAL_OR", parselet: new LogicalParselet(131 /* LOGICAL_OR */, chunkJ45BCEZ4_cjs.BindingPower.LogicalOr) }
|
|
4488
4885
|
]
|
|
4489
4886
|
};
|
|
4490
4887
|
|
|
@@ -4516,7 +4913,7 @@ var BASE_CONVERTERS = {
|
|
|
4516
4913
|
var AsConverterParselet = class {
|
|
4517
4914
|
constructor() {
|
|
4518
4915
|
this.category = "Converters";
|
|
4519
|
-
this.bindingPower =
|
|
4916
|
+
this.bindingPower = chunkJ45BCEZ4_cjs.BindingPower.Conditional;
|
|
4520
4917
|
}
|
|
4521
4918
|
parse(parser, left, token, builder) {
|
|
4522
4919
|
const nextToken = parser.peek();
|
|
@@ -4526,7 +4923,7 @@ var AsConverterParselet = class {
|
|
|
4526
4923
|
return;
|
|
4527
4924
|
}
|
|
4528
4925
|
if (!nextToken || nextToken.type !== "CONVERTER_NAME" && nextToken.type !== "IDENT" && nextToken.type !== "FUNC" && nextToken.type !== "UNIT") {
|
|
4529
|
-
throw
|
|
4926
|
+
throw chunkB4HBEFTB_cjs.ErrorFactory.parsing(
|
|
4530
4927
|
"AS_CONVERTER_EXPECTED_NAME",
|
|
4531
4928
|
`Expected a converter name after "as" (e.g. "as hex", "as decimal") but got ${nextToken ? `"${nextToken.value}"` : "end of input"}`
|
|
4532
4929
|
);
|
|
@@ -4538,7 +4935,7 @@ var AsConverterParselet = class {
|
|
|
4538
4935
|
const radix = radixToken?.type === "NUMBER" ? Number(radixToken.value) : NaN;
|
|
4539
4936
|
const opcode = BASE_CONVERTERS[radix];
|
|
4540
4937
|
if (opcode === void 0) {
|
|
4541
|
-
throw
|
|
4938
|
+
throw chunkB4HBEFTB_cjs.ErrorFactory.parsing(
|
|
4542
4939
|
"AS_CONVERTER_UNSUPPORTED_BASE",
|
|
4543
4940
|
`"as base ${radixToken?.value ?? "?"}": only bases ${Object.keys(BASE_CONVERTERS).join(", ")} can be written out`
|
|
4544
4941
|
);
|
|
@@ -4550,7 +4947,7 @@ var AsConverterParselet = class {
|
|
|
4550
4947
|
const builtinOp = BUILTIN_CONVERTERS[name];
|
|
4551
4948
|
if (builtinOp !== void 0) {
|
|
4552
4949
|
if (builtinOp === 141 /* TO_MULTIPLIER */ && parser.match("OF")) {
|
|
4553
|
-
parser.parseExpression(
|
|
4950
|
+
parser.parseExpression(chunkJ45BCEZ4_cjs.BindingPower.Conditional, builder);
|
|
4554
4951
|
builder.emitOpcode(23 /* DIV */);
|
|
4555
4952
|
}
|
|
4556
4953
|
builder.emitOpcode(builtinOp);
|
|
@@ -4605,7 +5002,7 @@ function readDirection(parser) {
|
|
|
4605
5002
|
var RoundedParselet = class {
|
|
4606
5003
|
constructor() {
|
|
4607
5004
|
this.category = "Converters";
|
|
4608
|
-
this.bindingPower =
|
|
5005
|
+
this.bindingPower = chunkJ45BCEZ4_cjs.BindingPower.Conditional;
|
|
4609
5006
|
}
|
|
4610
5007
|
parse(parser, _left, _token, builder) {
|
|
4611
5008
|
const direction = readDirection(parser);
|
|
@@ -4619,7 +5016,7 @@ var RoundedParselet = class {
|
|
|
4619
5016
|
var ToNearestParselet = class {
|
|
4620
5017
|
constructor() {
|
|
4621
5018
|
this.category = "Converters";
|
|
4622
|
-
this.bindingPower =
|
|
5019
|
+
this.bindingPower = chunkJ45BCEZ4_cjs.BindingPower.Conditional;
|
|
4623
5020
|
}
|
|
4624
5021
|
parse(parser, _left, _token, builder) {
|
|
4625
5022
|
emitRoundToIncrement(builder, readIncrement(parser), "nearest");
|
|
@@ -4638,7 +5035,7 @@ function readIncrement(parser) {
|
|
|
4638
5035
|
const value = Number(next.value);
|
|
4639
5036
|
if (Number.isFinite(value) && value > 0) return value;
|
|
4640
5037
|
}
|
|
4641
|
-
throw
|
|
5038
|
+
throw chunkB4HBEFTB_cjs.ErrorFactory.parsing(
|
|
4642
5039
|
"INVALID_ROUNDING_INCREMENT",
|
|
4643
5040
|
`"to nearest ${next?.value ?? "?"}": expected a positive number or one of ${Object.keys(INCREMENT_WORDS).join(", ")}`
|
|
4644
5041
|
);
|
|
@@ -4646,12 +5043,12 @@ function readIncrement(parser) {
|
|
|
4646
5043
|
var DecimalPlacesParselet = class {
|
|
4647
5044
|
constructor() {
|
|
4648
5045
|
this.category = "Converters";
|
|
4649
|
-
this.bindingPower =
|
|
5046
|
+
this.bindingPower = chunkJ45BCEZ4_cjs.BindingPower.Conditional;
|
|
4650
5047
|
}
|
|
4651
5048
|
parse(_parser, _left, token, builder) {
|
|
4652
5049
|
const places = Number(token.value);
|
|
4653
5050
|
if (!Number.isFinite(places) || places < 0 || places > 100) {
|
|
4654
|
-
throw
|
|
5051
|
+
throw chunkB4HBEFTB_cjs.ErrorFactory.parsing(
|
|
4655
5052
|
"INVALID_DECIMAL_PLACES",
|
|
4656
5053
|
`"to ${token.value} dp": expected a place count between 0 and 100`
|
|
4657
5054
|
);
|
|
@@ -4690,7 +5087,7 @@ function decimalPlacesNormalizerRule(priority = 66) {
|
|
|
4690
5087
|
return {
|
|
4691
5088
|
consumed,
|
|
4692
5089
|
replacement: [
|
|
4693
|
-
|
|
5090
|
+
chunkC75AFGVD_cjs.createFusedToken("DECIMAL_PLACES", count.value, tokens.slice(pos, pos + consumed))
|
|
4694
5091
|
],
|
|
4695
5092
|
ruleName: "converters:decimal-places"
|
|
4696
5093
|
};
|
|
@@ -4712,7 +5109,7 @@ function converterPrepositionNormalizerRule(priority = 67) {
|
|
|
4712
5109
|
if (!isConverterTarget) return null;
|
|
4713
5110
|
return {
|
|
4714
5111
|
consumed: 1,
|
|
4715
|
-
replacement: [
|
|
5112
|
+
replacement: [chunkC75AFGVD_cjs.createFusedToken("AS", "as", [preposition])],
|
|
4716
5113
|
ruleName: "converters:preposition"
|
|
4717
5114
|
};
|
|
4718
5115
|
}
|
|
@@ -4749,10 +5146,10 @@ var VariadicAggregateParselet = class {
|
|
|
4749
5146
|
}
|
|
4750
5147
|
parse(parser, token, builder) {
|
|
4751
5148
|
let argCount = 0;
|
|
4752
|
-
parser.parseExpression(
|
|
5149
|
+
parser.parseExpression(chunkJ45BCEZ4_cjs.BindingPower.Conjunction, builder);
|
|
4753
5150
|
argCount++;
|
|
4754
5151
|
while (parser.match("COMMA") || parser.match("AND_CONJ")) {
|
|
4755
|
-
parser.parseExpression(
|
|
5152
|
+
parser.parseExpression(chunkJ45BCEZ4_cjs.BindingPower.Conjunction, builder);
|
|
4756
5153
|
argCount++;
|
|
4757
5154
|
}
|
|
4758
5155
|
builder.emitOpcode(51 /* CALL_BUILTIN */);
|
|
@@ -4766,7 +5163,7 @@ function unaryPhraseParselet(builtinIndex) {
|
|
|
4766
5163
|
return {
|
|
4767
5164
|
category: "MathPhrases",
|
|
4768
5165
|
parse(parser, _token, builder) {
|
|
4769
|
-
parser.parseExpression(
|
|
5166
|
+
parser.parseExpression(chunkJ45BCEZ4_cjs.BindingPower.Lowest, builder);
|
|
4770
5167
|
builder.emitOpcode(51 /* CALL_BUILTIN */);
|
|
4771
5168
|
builder.emitIndex(builtinIndex);
|
|
4772
5169
|
builder.emitIndex(1);
|
|
@@ -4778,28 +5175,28 @@ function unaryPhraseParselet(builtinIndex) {
|
|
|
4778
5175
|
var remainderOfParselet = {
|
|
4779
5176
|
category: "MathPhrases",
|
|
4780
5177
|
parse(parser, _token, builder) {
|
|
4781
|
-
parser.parseExpression(
|
|
5178
|
+
parser.parseExpression(chunkJ45BCEZ4_cjs.BindingPower.Product, builder);
|
|
4782
5179
|
if (!parser.match("DIVIDE_BY") && !parser.match("SLASH")) {
|
|
4783
|
-
throw
|
|
5180
|
+
throw chunkB4HBEFTB_cjs.ErrorFactory.parsing(
|
|
4784
5181
|
"REMAINDER_EXPECTED_DIVIDED_BY",
|
|
4785
5182
|
'Expected "divided by" or "/", as in "remainder of 21 divided by 5"'
|
|
4786
5183
|
);
|
|
4787
5184
|
}
|
|
4788
|
-
parser.parseExpression(
|
|
5185
|
+
parser.parseExpression(chunkJ45BCEZ4_cjs.BindingPower.Product, builder);
|
|
4789
5186
|
builder.emitOpcode(24 /* MOD */);
|
|
4790
5187
|
}
|
|
4791
5188
|
};
|
|
4792
5189
|
var nthRootParselet = {
|
|
4793
5190
|
category: "MathPhrases",
|
|
4794
5191
|
parse(parser, _token, builder) {
|
|
4795
|
-
parser.parseExpression(
|
|
5192
|
+
parser.parseExpression(chunkJ45BCEZ4_cjs.BindingPower.Product, builder);
|
|
4796
5193
|
if (!parser.match("OF")) {
|
|
4797
|
-
throw
|
|
5194
|
+
throw chunkB4HBEFTB_cjs.ErrorFactory.parsing(
|
|
4798
5195
|
"ROOT_EXPECTED_OF",
|
|
4799
5196
|
'Expected "of", as in "root 5 of 100"'
|
|
4800
5197
|
);
|
|
4801
5198
|
}
|
|
4802
|
-
parser.parseExpression(
|
|
5199
|
+
parser.parseExpression(chunkJ45BCEZ4_cjs.BindingPower.Conditional, builder);
|
|
4803
5200
|
builder.emitOpcode(2 /* SWAP */);
|
|
4804
5201
|
builder.emitOpcode(10 /* PUSH_NUMBER */);
|
|
4805
5202
|
builder.emitNumber(1);
|
|
@@ -4811,15 +5208,15 @@ var nthRootParselet = {
|
|
|
4811
5208
|
var logBaseParselet = {
|
|
4812
5209
|
category: "MathPhrases",
|
|
4813
5210
|
parse(parser, _token, builder) {
|
|
4814
|
-
parser.parseExpression(
|
|
5211
|
+
parser.parseExpression(chunkJ45BCEZ4_cjs.BindingPower.Conditional, builder);
|
|
4815
5212
|
emitNaturalLog(builder);
|
|
4816
5213
|
if (!parser.match("LOG_BASE")) {
|
|
4817
|
-
throw
|
|
5214
|
+
throw chunkB4HBEFTB_cjs.ErrorFactory.parsing(
|
|
4818
5215
|
"LOG_EXPECTED_BASE",
|
|
4819
5216
|
'Expected "base", as in "log 20 base 4"'
|
|
4820
5217
|
);
|
|
4821
5218
|
}
|
|
4822
|
-
parser.parseExpression(
|
|
5219
|
+
parser.parseExpression(chunkJ45BCEZ4_cjs.BindingPower.Conditional, builder);
|
|
4823
5220
|
emitNaturalLog(builder);
|
|
4824
5221
|
builder.emitOpcode(23 /* DIV */);
|
|
4825
5222
|
}
|
|
@@ -4845,15 +5242,15 @@ function functionPhraseNormalizerRule(priority = 69) {
|
|
|
4845
5242
|
if (word === "root") {
|
|
4846
5243
|
return {
|
|
4847
5244
|
consumed: 1,
|
|
4848
|
-
replacement: [
|
|
5245
|
+
replacement: [chunkC75AFGVD_cjs.createFusedToken("NTH_ROOT", "root", [head])],
|
|
4849
5246
|
ruleName: "mathphrases:function-phrase"
|
|
4850
5247
|
};
|
|
4851
5248
|
}
|
|
4852
5249
|
const baseAt = findBase(tokens, pos + 1);
|
|
4853
5250
|
if (baseAt === -1) return null;
|
|
4854
5251
|
const replacement = tokens.slice(pos, baseAt + 1).map((token, index) => {
|
|
4855
|
-
if (index === 0) return
|
|
4856
|
-
if (index === baseAt - pos) return
|
|
5252
|
+
if (index === 0) return chunkC75AFGVD_cjs.createFusedToken("LOG_PHRASE", "log", [token]);
|
|
5253
|
+
if (index === baseAt - pos) return chunkC75AFGVD_cjs.createFusedToken("LOG_BASE", "base", [token]);
|
|
4857
5254
|
return token;
|
|
4858
5255
|
});
|
|
4859
5256
|
return {
|
|
@@ -4878,9 +5275,9 @@ function largerSmallerParselet(builtinIndex) {
|
|
|
4878
5275
|
return {
|
|
4879
5276
|
category: "MathPhrases",
|
|
4880
5277
|
parse(parser, token, builder) {
|
|
4881
|
-
parser.parseExpression(
|
|
5278
|
+
parser.parseExpression(chunkJ45BCEZ4_cjs.BindingPower.Conjunction, builder);
|
|
4882
5279
|
parser.consume("AND_CONJ");
|
|
4883
|
-
parser.parseExpression(
|
|
5280
|
+
parser.parseExpression(chunkJ45BCEZ4_cjs.BindingPower.Lowest, builder);
|
|
4884
5281
|
builder.emitOpcode(51 /* CALL_BUILTIN */);
|
|
4885
5282
|
builder.emitIndex(builtinIndex);
|
|
4886
5283
|
builder.emitIndex(2);
|
|
@@ -4892,7 +5289,7 @@ function largerSmallerParselet(builtinIndex) {
|
|
|
4892
5289
|
var halfParselet = {
|
|
4893
5290
|
category: "MathPhrases",
|
|
4894
5291
|
parse(parser, token, builder) {
|
|
4895
|
-
parser.parseExpression(
|
|
5292
|
+
parser.parseExpression(chunkJ45BCEZ4_cjs.BindingPower.Lowest, builder);
|
|
4896
5293
|
builder.emitOpcode(10 /* PUSH_NUMBER */);
|
|
4897
5294
|
builder.emitNumber(2);
|
|
4898
5295
|
builder.emitOpcode(23 /* DIV */);
|
|
@@ -4903,9 +5300,9 @@ var halfParselet = {
|
|
|
4903
5300
|
var midpointParselet = {
|
|
4904
5301
|
category: "MathPhrases",
|
|
4905
5302
|
parse(parser, token, builder) {
|
|
4906
|
-
parser.parseExpression(
|
|
5303
|
+
parser.parseExpression(chunkJ45BCEZ4_cjs.BindingPower.Conjunction, builder);
|
|
4907
5304
|
parser.consume("AND_CONJ");
|
|
4908
|
-
parser.parseExpression(
|
|
5305
|
+
parser.parseExpression(chunkJ45BCEZ4_cjs.BindingPower.Lowest, builder);
|
|
4909
5306
|
builder.emitOpcode(20 /* ADD */);
|
|
4910
5307
|
builder.emitOpcode(10 /* PUSH_NUMBER */);
|
|
4911
5308
|
builder.emitNumber(2);
|
|
@@ -4920,7 +5317,7 @@ var randomNumberParselet = definePhrasePattern({
|
|
|
4920
5317
|
{
|
|
4921
5318
|
slots: [
|
|
4922
5319
|
{ kind: "keyword", tokenTypes: ["BETWEEN"] },
|
|
4923
|
-
{ kind: "expr", bindingPower:
|
|
5320
|
+
{ kind: "expr", bindingPower: chunkJ45BCEZ4_cjs.BindingPower.Product },
|
|
4924
5321
|
{ kind: "keyword", tokenTypes: ["AND_CONJ"] },
|
|
4925
5322
|
{ kind: "expr" }
|
|
4926
5323
|
],
|
|
@@ -4940,20 +5337,20 @@ var ClampParselet = class {
|
|
|
4940
5337
|
this.category = "MathPhrases";
|
|
4941
5338
|
}
|
|
4942
5339
|
parse(parser, token, builder) {
|
|
4943
|
-
parser.parseExpression(
|
|
5340
|
+
parser.parseExpression(chunkJ45BCEZ4_cjs.BindingPower.Lowest, builder);
|
|
4944
5341
|
const mid = parser.peek();
|
|
4945
5342
|
if (mid?.type === "BETWEEN") {
|
|
4946
5343
|
parser.consume();
|
|
4947
|
-
parser.parseExpression(
|
|
5344
|
+
parser.parseExpression(chunkJ45BCEZ4_cjs.BindingPower.Product, builder);
|
|
4948
5345
|
parser.consume("AND_CONJ");
|
|
4949
|
-
parser.parseExpression(
|
|
5346
|
+
parser.parseExpression(chunkJ45BCEZ4_cjs.BindingPower.Lowest, builder);
|
|
4950
5347
|
} else if (mid?.type === "FROM") {
|
|
4951
5348
|
parser.consume();
|
|
4952
|
-
parser.parseExpression(
|
|
5349
|
+
parser.parseExpression(chunkJ45BCEZ4_cjs.BindingPower.Lowest, builder);
|
|
4953
5350
|
parser.consume("TO");
|
|
4954
|
-
parser.parseExpression(
|
|
5351
|
+
parser.parseExpression(chunkJ45BCEZ4_cjs.BindingPower.Lowest, builder);
|
|
4955
5352
|
} else {
|
|
4956
|
-
throw
|
|
5353
|
+
throw chunkB4HBEFTB_cjs.ErrorFactory.parsing(
|
|
4957
5354
|
"CLAMP_EXPECTED_BETWEEN_OR_FROM",
|
|
4958
5355
|
`Expected "between" or "from" after "clamp <value>" but got ${mid ? `"${mid.value}"` : "end of input"}`
|
|
4959
5356
|
);
|
|
@@ -4969,7 +5366,7 @@ var PROPORTION_BUILTIN_INDEX = 46;
|
|
|
4969
5366
|
var ProportionParselet = class {
|
|
4970
5367
|
constructor() {
|
|
4971
5368
|
this.category = "MathPhrases";
|
|
4972
|
-
this.bindingPower =
|
|
5369
|
+
this.bindingPower = chunkJ45BCEZ4_cjs.BindingPower.Conditional;
|
|
4973
5370
|
}
|
|
4974
5371
|
parse(parser, left, token, builder) {
|
|
4975
5372
|
parser.parseExpression(this.bindingPower, builder);
|
|
@@ -4978,7 +5375,7 @@ var ProportionParselet = class {
|
|
|
4978
5375
|
parser.consume("IS_TO");
|
|
4979
5376
|
const whatToken = parser.consume();
|
|
4980
5377
|
if (!whatToken || whatToken.value.toLowerCase() !== "what") {
|
|
4981
|
-
throw
|
|
5378
|
+
throw chunkB4HBEFTB_cjs.ErrorFactory.parsing(
|
|
4982
5379
|
"PROPORTION_EXPECTED_WHAT",
|
|
4983
5380
|
`Expected "what" but got ${whatToken ? `"${whatToken.value}"` : "end of input"}`
|
|
4984
5381
|
);
|
|
@@ -5070,7 +5467,7 @@ function readCompoundingInterval(parser) {
|
|
|
5070
5467
|
const name = (token?.text ?? token?.value ?? "").toLowerCase();
|
|
5071
5468
|
const periods = PERIODS_PER_YEAR[name];
|
|
5072
5469
|
if (periods === void 0) {
|
|
5073
|
-
throw
|
|
5470
|
+
throw chunkB4HBEFTB_cjs.ErrorFactory.parsing(
|
|
5074
5471
|
"UNKNOWN_COMPOUNDING_INTERVAL",
|
|
5075
5472
|
`compounding ${name || "?"}: expected one of ${Object.keys(PERIODS_PER_YEAR).join(", ")}`
|
|
5076
5473
|
);
|
|
@@ -5088,12 +5485,12 @@ var InvestmentGrowthParselet = class {
|
|
|
5088
5485
|
this.annualIndex = annualIndex;
|
|
5089
5486
|
this.intervalIndex = intervalIndex;
|
|
5090
5487
|
this.category = "Finance";
|
|
5091
|
-
this.bindingPower =
|
|
5488
|
+
this.bindingPower = chunkJ45BCEZ4_cjs.BindingPower.Conditional;
|
|
5092
5489
|
}
|
|
5093
5490
|
parse(parser, _left, _token, builder) {
|
|
5094
|
-
parser.parseExpression(
|
|
5491
|
+
parser.parseExpression(chunkJ45BCEZ4_cjs.BindingPower.Conditional, builder);
|
|
5095
5492
|
if (!parser.match("RATE_AT")) parser.consume("AT");
|
|
5096
|
-
parser.parseExpression(
|
|
5493
|
+
parser.parseExpression(chunkJ45BCEZ4_cjs.BindingPower.Conditional, builder);
|
|
5097
5494
|
const periods = readCompoundingInterval(parser);
|
|
5098
5495
|
builder.emitOpcode(2 /* SWAP */);
|
|
5099
5496
|
if (periods === 1) {
|
|
@@ -5115,13 +5512,13 @@ var PresentValueParselet = class {
|
|
|
5115
5512
|
this.category = "Finance";
|
|
5116
5513
|
}
|
|
5117
5514
|
parse(parser, _token, builder) {
|
|
5118
|
-
parser.parseExpression(
|
|
5515
|
+
parser.parseExpression(chunkJ45BCEZ4_cjs.BindingPower.Conditional, builder);
|
|
5119
5516
|
if (!parser.match("AFTER") && !parser.match("OVER") && !parser.match("IN")) {
|
|
5120
5517
|
parser.consume("AFTER");
|
|
5121
5518
|
}
|
|
5122
|
-
parser.parseExpression(
|
|
5519
|
+
parser.parseExpression(chunkJ45BCEZ4_cjs.BindingPower.Conditional, builder);
|
|
5123
5520
|
if (!parser.match("RATE_AT")) parser.consume("AT");
|
|
5124
|
-
parser.parseExpression(
|
|
5521
|
+
parser.parseExpression(chunkJ45BCEZ4_cjs.BindingPower.Conditional, builder);
|
|
5125
5522
|
builder.emitOpcode(2 /* SWAP */);
|
|
5126
5523
|
builder.emitOpcode(51 /* CALL_BUILTIN */);
|
|
5127
5524
|
builder.emitIndex(this.builtinIndex);
|
|
@@ -5132,10 +5529,10 @@ var ReturnOnInvestmentParselet = class {
|
|
|
5132
5529
|
constructor(builtinIndex) {
|
|
5133
5530
|
this.builtinIndex = builtinIndex;
|
|
5134
5531
|
this.category = "Finance";
|
|
5135
|
-
this.bindingPower =
|
|
5532
|
+
this.bindingPower = chunkJ45BCEZ4_cjs.BindingPower.Conditional;
|
|
5136
5533
|
}
|
|
5137
5534
|
parse(parser, _left, _token, builder) {
|
|
5138
|
-
parser.parseExpression(
|
|
5535
|
+
parser.parseExpression(chunkJ45BCEZ4_cjs.BindingPower.Conditional, builder);
|
|
5139
5536
|
parser.consume("RETURNED");
|
|
5140
5537
|
builder.emitOpcode(51 /* CALL_BUILTIN */);
|
|
5141
5538
|
builder.emitIndex(this.builtinIndex);
|
|
@@ -5148,20 +5545,48 @@ var AnnualReturnParselet = class {
|
|
|
5148
5545
|
this.category = "Finance";
|
|
5149
5546
|
}
|
|
5150
5547
|
parse(parser, _token, builder) {
|
|
5151
|
-
parser.parseExpression(
|
|
5548
|
+
parser.parseExpression(chunkJ45BCEZ4_cjs.BindingPower.Conditional, builder);
|
|
5152
5549
|
parser.consume("INVESTED");
|
|
5153
|
-
parser.parseExpression(
|
|
5550
|
+
parser.parseExpression(chunkJ45BCEZ4_cjs.BindingPower.Conditional, builder);
|
|
5154
5551
|
parser.consume("RETURNED");
|
|
5155
5552
|
if (!parser.match("AFTER") && !parser.match("OVER") && !parser.match("IN")) {
|
|
5156
5553
|
parser.consume("AFTER");
|
|
5157
5554
|
}
|
|
5158
|
-
parser.parseExpression(
|
|
5555
|
+
parser.parseExpression(chunkJ45BCEZ4_cjs.BindingPower.Conditional, builder);
|
|
5159
5556
|
builder.emitOpcode(51 /* CALL_BUILTIN */);
|
|
5160
5557
|
builder.emitIndex(this.builtinIndex);
|
|
5161
5558
|
builder.emitIndex(3);
|
|
5162
5559
|
}
|
|
5163
5560
|
};
|
|
5164
5561
|
|
|
5562
|
+
// src/packages/finance/parselets/TermRateClauses.ts
|
|
5563
|
+
function parseTermAndRate(parser, builder, termWords) {
|
|
5564
|
+
if (matchTerm(parser, termWords)) {
|
|
5565
|
+
parser.parseExpression(chunkJ45BCEZ4_cjs.BindingPower.Lowest, builder);
|
|
5566
|
+
consumeRate(parser);
|
|
5567
|
+
parser.parseExpression(chunkJ45BCEZ4_cjs.BindingPower.Lowest, builder);
|
|
5568
|
+
return { swap: true };
|
|
5569
|
+
}
|
|
5570
|
+
consumeRate(parser);
|
|
5571
|
+
parser.parseExpression(chunkJ45BCEZ4_cjs.BindingPower.Lowest, builder);
|
|
5572
|
+
consumeTerm(parser, termWords);
|
|
5573
|
+
parser.parseExpression(chunkJ45BCEZ4_cjs.BindingPower.Lowest, builder);
|
|
5574
|
+
return { swap: false };
|
|
5575
|
+
}
|
|
5576
|
+
function matchTerm(parser, termWords) {
|
|
5577
|
+
for (const word of termWords) {
|
|
5578
|
+
if (parser.match(word)) return true;
|
|
5579
|
+
}
|
|
5580
|
+
return false;
|
|
5581
|
+
}
|
|
5582
|
+
function consumeTerm(parser, termWords) {
|
|
5583
|
+
if (matchTerm(parser, termWords)) return;
|
|
5584
|
+
parser.consume(termWords[0]);
|
|
5585
|
+
}
|
|
5586
|
+
function consumeRate(parser) {
|
|
5587
|
+
if (!parser.match("RATE_AT")) parser.consume("AT");
|
|
5588
|
+
}
|
|
5589
|
+
|
|
5165
5590
|
// src/packages/finance/parselets/CompoundInterestParselet.ts
|
|
5166
5591
|
var CompoundInterestParselet = class {
|
|
5167
5592
|
/**
|
|
@@ -5175,15 +5600,10 @@ var CompoundInterestParselet = class {
|
|
|
5175
5600
|
this.category = "Finance";
|
|
5176
5601
|
}
|
|
5177
5602
|
parse(parser, _token, builder) {
|
|
5178
|
-
parser.parseExpression(
|
|
5179
|
-
|
|
5180
|
-
parser.consume("OVER");
|
|
5181
|
-
}
|
|
5182
|
-
parser.parseExpression(chunkPA4VC73I_cjs.BindingPower.Lowest, builder);
|
|
5183
|
-
if (!parser.match("RATE_AT")) parser.consume("AT");
|
|
5184
|
-
parser.parseExpression(chunkPA4VC73I_cjs.BindingPower.Lowest, builder);
|
|
5603
|
+
parser.parseExpression(chunkJ45BCEZ4_cjs.BindingPower.Conditional, builder);
|
|
5604
|
+
const { swap } = parseTermAndRate(parser, builder, ["AFTER", "FOR_DURATION", "OVER"]);
|
|
5185
5605
|
const periods = readCompoundingInterval(parser);
|
|
5186
|
-
builder.emitOpcode(2 /* SWAP */);
|
|
5606
|
+
if (swap) builder.emitOpcode(2 /* SWAP */);
|
|
5187
5607
|
if (periods === 1) {
|
|
5188
5608
|
builder.emitOpcode(51 /* CALL_BUILTIN */);
|
|
5189
5609
|
builder.emitIndex(this.builtinIndex);
|
|
@@ -5206,12 +5626,9 @@ var LoanRepaymentParselet = class {
|
|
|
5206
5626
|
this.category = "Finance";
|
|
5207
5627
|
}
|
|
5208
5628
|
parse(parser, _token, builder) {
|
|
5209
|
-
parser.parseExpression(
|
|
5210
|
-
parser
|
|
5211
|
-
|
|
5212
|
-
if (!parser.match("RATE_AT")) parser.consume("AT");
|
|
5213
|
-
parser.parseExpression(chunkPA4VC73I_cjs.BindingPower.Lowest, builder);
|
|
5214
|
-
builder.emitOpcode(2 /* SWAP */);
|
|
5629
|
+
parser.parseExpression(chunkJ45BCEZ4_cjs.BindingPower.Lowest, builder);
|
|
5630
|
+
const { swap } = parseTermAndRate(parser, builder, ["OVER"]);
|
|
5631
|
+
if (swap) builder.emitOpcode(2 /* SWAP */);
|
|
5215
5632
|
builder.emitOpcode(10 /* PUSH_NUMBER */);
|
|
5216
5633
|
builder.emitNumber(this.periodsPerYear);
|
|
5217
5634
|
builder.emitOpcode(51 /* CALL_BUILTIN */);
|
|
@@ -5227,9 +5644,9 @@ var SalesTaxParselet = class {
|
|
|
5227
5644
|
this.category = "Finance";
|
|
5228
5645
|
}
|
|
5229
5646
|
parse(parser, _token, builder) {
|
|
5230
|
-
parser.parseExpression(
|
|
5647
|
+
parser.parseExpression(chunkJ45BCEZ4_cjs.BindingPower.Lowest, builder);
|
|
5231
5648
|
parser.consume("RATE_AT");
|
|
5232
|
-
parser.parseExpression(
|
|
5649
|
+
parser.parseExpression(chunkJ45BCEZ4_cjs.BindingPower.Lowest, builder);
|
|
5233
5650
|
builder.emitOpcode(51 /* CALL_BUILTIN */);
|
|
5234
5651
|
builder.emitIndex(this.builtinIndex);
|
|
5235
5652
|
builder.emitIndex(2);
|
|
@@ -5237,30 +5654,30 @@ var SalesTaxParselet = class {
|
|
|
5237
5654
|
};
|
|
5238
5655
|
|
|
5239
5656
|
// src/packages/finance/parselets/InflationPluginFunctions.ts
|
|
5240
|
-
var INFLATION_FROM_YEAR_TO_PRESENT_IDX =
|
|
5241
|
-
var INFLATION_TO_YEAR_FROM_PRESENT_IDX =
|
|
5242
|
-
var INFLATION_FUTURE_VALUE_IDX =
|
|
5657
|
+
var INFLATION_FROM_YEAR_TO_PRESENT_IDX = chunk7ZX6B7SY_cjs.allocatePluginFunctionIndex();
|
|
5658
|
+
var INFLATION_TO_YEAR_FROM_PRESENT_IDX = chunk7ZX6B7SY_cjs.allocatePluginFunctionIndex();
|
|
5659
|
+
var INFLATION_FUTURE_VALUE_IDX = chunk7ZX6B7SY_cjs.allocatePluginFunctionIndex();
|
|
5243
5660
|
function yearRangeError(code, badYear) {
|
|
5244
|
-
return
|
|
5661
|
+
return chunk2TZKENDH_cjs.errorValue(
|
|
5245
5662
|
code,
|
|
5246
|
-
`Year ${badYear} is outside the bundled CPI table's range (${
|
|
5663
|
+
`Year ${badYear} is outside the bundled CPI table's range (${chunk7ZX6B7SY_cjs.CPI_MIN_YEAR}-${chunk7ZX6B7SY_cjs.CPI_MAX_YEAR})`
|
|
5247
5664
|
);
|
|
5248
5665
|
}
|
|
5249
5666
|
function inflationFromYearToPresentHandler(args) {
|
|
5250
5667
|
const amountValue = args[0];
|
|
5251
5668
|
const fromYear = args[1].toNumber();
|
|
5252
5669
|
const toYear = (/* @__PURE__ */ new Date()).getFullYear();
|
|
5253
|
-
const result =
|
|
5670
|
+
const result = chunk7ZX6B7SY_cjs.adjustForInflation(amountValue.toNumber(), fromYear, toYear);
|
|
5254
5671
|
if (result === void 0) return yearRangeError("INFLATION_YEAR_OUT_OF_RANGE", fromYear);
|
|
5255
|
-
return amountValue.type === 6 /* Uom */ ?
|
|
5672
|
+
return amountValue.type === 6 /* Uom */ ? chunk2TZKENDH_cjs.uomValue(result, amountValue.unit) : chunk2TZKENDH_cjs.numberValue(result);
|
|
5256
5673
|
}
|
|
5257
5674
|
function inflationToYearFromPresentHandler(args) {
|
|
5258
5675
|
const amountValue = args[0];
|
|
5259
5676
|
const fromYear = (/* @__PURE__ */ new Date()).getFullYear();
|
|
5260
5677
|
const toYear = args[1].toNumber();
|
|
5261
|
-
const result =
|
|
5678
|
+
const result = chunk7ZX6B7SY_cjs.adjustForInflation(amountValue.toNumber(), fromYear, toYear);
|
|
5262
5679
|
if (result === void 0) return yearRangeError("INFLATION_YEAR_OUT_OF_RANGE", toYear);
|
|
5263
|
-
return amountValue.type === 6 /* Uom */ ?
|
|
5680
|
+
return amountValue.type === 6 /* Uom */ ? chunk2TZKENDH_cjs.uomValue(result, amountValue.unit) : chunk2TZKENDH_cjs.numberValue(result);
|
|
5264
5681
|
}
|
|
5265
5682
|
function inflationFutureValueHandler(args) {
|
|
5266
5683
|
const amountValue = args[0];
|
|
@@ -5268,11 +5685,11 @@ function inflationFutureValueHandler(args) {
|
|
|
5268
5685
|
const rate = args[2].toNumber();
|
|
5269
5686
|
const years = futureYear - (/* @__PURE__ */ new Date()).getFullYear();
|
|
5270
5687
|
if (1 + rate <= 0) {
|
|
5271
|
-
return
|
|
5688
|
+
return chunk2TZKENDH_cjs.errorValue("INVALID_RATE", `inflationFutureValue: rate ${rate} makes (1 + rate) non-positive`);
|
|
5272
5689
|
}
|
|
5273
5690
|
const amount = amountValue.toNumber();
|
|
5274
5691
|
const worth = amount / Math.pow(1 + rate, years);
|
|
5275
|
-
return amountValue.type === 6 /* Uom */ ?
|
|
5692
|
+
return amountValue.type === 6 /* Uom */ ? chunk2TZKENDH_cjs.uomValue(worth, amountValue.unit) : chunk2TZKENDH_cjs.numberValue(worth);
|
|
5276
5693
|
}
|
|
5277
5694
|
|
|
5278
5695
|
// src/packages/finance/parselets/InflationQueryParselet.ts
|
|
@@ -5291,13 +5708,13 @@ var InflationQueryParselet = class {
|
|
|
5291
5708
|
}
|
|
5292
5709
|
parse(parser, _token, builder) {
|
|
5293
5710
|
if (!hasInflationKeyword(parser)) {
|
|
5294
|
-
parser.parseExpression(
|
|
5711
|
+
parser.parseExpression(chunkJ45BCEZ4_cjs.BindingPower.Lowest, builder);
|
|
5295
5712
|
return;
|
|
5296
5713
|
}
|
|
5297
|
-
parser.parseExpression(
|
|
5714
|
+
parser.parseExpression(chunkJ45BCEZ4_cjs.BindingPower.Product, builder);
|
|
5298
5715
|
if (this.variant === "what-was") {
|
|
5299
5716
|
parser.consume("WORTH_IN");
|
|
5300
|
-
parser.parseExpression(
|
|
5717
|
+
parser.parseExpression(chunkJ45BCEZ4_cjs.BindingPower.Lowest, builder);
|
|
5301
5718
|
builder.emitOpcode(50 /* CALL_PLUGIN */);
|
|
5302
5719
|
builder.emitIndex(INFLATION_TO_YEAR_FROM_PRESENT_IDX);
|
|
5303
5720
|
builder.emitIndex(2);
|
|
@@ -5306,7 +5723,7 @@ var InflationQueryParselet = class {
|
|
|
5306
5723
|
const next = parser.peek();
|
|
5307
5724
|
if (next?.type === "FROM") {
|
|
5308
5725
|
parser.consume();
|
|
5309
|
-
parser.parseExpression(
|
|
5726
|
+
parser.parseExpression(chunkJ45BCEZ4_cjs.BindingPower.Lowest, builder);
|
|
5310
5727
|
builder.emitOpcode(50 /* CALL_PLUGIN */);
|
|
5311
5728
|
builder.emitIndex(INFLATION_FROM_YEAR_TO_PRESENT_IDX);
|
|
5312
5729
|
builder.emitIndex(2);
|
|
@@ -5314,16 +5731,16 @@ var InflationQueryParselet = class {
|
|
|
5314
5731
|
}
|
|
5315
5732
|
if (next?.type === "IN") {
|
|
5316
5733
|
parser.consume();
|
|
5317
|
-
parser.parseExpression(
|
|
5734
|
+
parser.parseExpression(chunkJ45BCEZ4_cjs.BindingPower.Lowest, builder);
|
|
5318
5735
|
parser.consume("WORTH_IN");
|
|
5319
|
-
parser.parseExpression(
|
|
5736
|
+
parser.parseExpression(chunkJ45BCEZ4_cjs.BindingPower.Lowest, builder);
|
|
5320
5737
|
builder.emitOpcode(51 /* CALL_BUILTIN */);
|
|
5321
5738
|
builder.emitIndex(INFLATION_ADJUST_BUILTIN_IDX);
|
|
5322
5739
|
builder.emitIndex(3);
|
|
5323
5740
|
return;
|
|
5324
5741
|
}
|
|
5325
5742
|
const gotType = next ? next.type : "end of input";
|
|
5326
|
-
throw
|
|
5743
|
+
throw chunkB4HBEFTB_cjs.ErrorFactory.parsing(
|
|
5327
5744
|
"INFLATION_EXPECTED_FROM_OR_IN",
|
|
5328
5745
|
`Expected "from <year>" or "in <year> worth in <year>" after "what is <amount>", got ${gotType}`
|
|
5329
5746
|
);
|
|
@@ -5336,16 +5753,16 @@ var InflationFutureValueParselet = class {
|
|
|
5336
5753
|
this.category = "Finance";
|
|
5337
5754
|
}
|
|
5338
5755
|
parse(parser, _token, builder) {
|
|
5339
|
-
parser.parseExpression(
|
|
5756
|
+
parser.parseExpression(chunkJ45BCEZ4_cjs.BindingPower.Product, builder);
|
|
5340
5757
|
parser.consume("IN");
|
|
5341
|
-
parser.parseExpression(
|
|
5758
|
+
parser.parseExpression(chunkJ45BCEZ4_cjs.BindingPower.Lowest, builder);
|
|
5342
5759
|
parser.consume("ASSUMING");
|
|
5343
|
-
parser.parseExpression(
|
|
5760
|
+
parser.parseExpression(chunkJ45BCEZ4_cjs.BindingPower.Lowest, builder);
|
|
5344
5761
|
const inflationToken = parser.peek();
|
|
5345
5762
|
const inflationWord = inflationToken && inflationToken.type === "IDENT" ? inflationToken.value.toLowerCase() : void 0;
|
|
5346
5763
|
if (inflationWord !== "inflation") {
|
|
5347
5764
|
const got = inflationToken ? inflationToken.value : "end of input";
|
|
5348
|
-
throw
|
|
5765
|
+
throw chunkB4HBEFTB_cjs.ErrorFactory.parsing(
|
|
5349
5766
|
"INFLATION_EXPECTED_INFLATION_WORD",
|
|
5350
5767
|
`Expected the word "inflation" after "assuming <rate>%", got "${got}"`
|
|
5351
5768
|
);
|
|
@@ -5389,13 +5806,138 @@ function inYearDollarsNormalizerRule(priority = 70) {
|
|
|
5389
5806
|
if (word !== "dollars" && word !== "dollar") return null;
|
|
5390
5807
|
return {
|
|
5391
5808
|
consumed: 3,
|
|
5392
|
-
replacement: [
|
|
5809
|
+
replacement: [chunkC75AFGVD_cjs.createFusedToken("IN_YEAR_DOLLARS", yearToken.value, tokens.slice(pos, pos + 3))],
|
|
5393
5810
|
ruleName: "finance:in-year-dollars"
|
|
5394
5811
|
};
|
|
5395
5812
|
}
|
|
5396
5813
|
};
|
|
5397
5814
|
}
|
|
5398
5815
|
|
|
5816
|
+
// src/packages/finance/normalizer/RecurringScheduleNormalizerRule.ts
|
|
5817
|
+
var RecurringScheduleErrorCodes = {
|
|
5818
|
+
/** `every 0 weeks` and the like: the interval a payment repeats on has to be a positive count, or the number of payments is undefined. */
|
|
5819
|
+
RECURRING_INTERVAL_NOT_POSITIVE: "RECURRING_INTERVAL_NOT_POSITIVE"
|
|
5820
|
+
};
|
|
5821
|
+
var PERIODS_PER_YEAR2 = {
|
|
5822
|
+
daily: 365,
|
|
5823
|
+
weekly: 52,
|
|
5824
|
+
monthly: 12,
|
|
5825
|
+
yearly: 1,
|
|
5826
|
+
// "annually" reads better than "yearly" before a duration and means the
|
|
5827
|
+
// same, so it is accepted as a spelling rather than a separate period.
|
|
5828
|
+
annually: 1
|
|
5829
|
+
};
|
|
5830
|
+
var UNIT_PER_YEAR = {
|
|
5831
|
+
day: 365,
|
|
5832
|
+
days: 365,
|
|
5833
|
+
week: 52,
|
|
5834
|
+
weeks: 52,
|
|
5835
|
+
month: 12,
|
|
5836
|
+
months: 12,
|
|
5837
|
+
year: 1,
|
|
5838
|
+
years: 1
|
|
5839
|
+
};
|
|
5840
|
+
var ARTICLES3 = /* @__PURE__ */ new Set(["a", "an"]);
|
|
5841
|
+
var VALUE_ENDERS = /* @__PURE__ */ new Set([
|
|
5842
|
+
"NUMBER",
|
|
5843
|
+
"FLOAT",
|
|
5844
|
+
"HEX",
|
|
5845
|
+
"BIGINT",
|
|
5846
|
+
"RPAREN",
|
|
5847
|
+
"RBRACKET",
|
|
5848
|
+
"IDENT",
|
|
5849
|
+
"PERCENT",
|
|
5850
|
+
"STRING"
|
|
5851
|
+
]);
|
|
5852
|
+
function wordOf(token) {
|
|
5853
|
+
if (token === void 0) return "";
|
|
5854
|
+
return (token.text ?? token.value ?? "").toLowerCase();
|
|
5855
|
+
}
|
|
5856
|
+
function unitPerYear(token) {
|
|
5857
|
+
if (token === void 0 || token.type !== "UNIT") return void 0;
|
|
5858
|
+
return UNIT_PER_YEAR[wordOf(token)];
|
|
5859
|
+
}
|
|
5860
|
+
function readPeriod(tokens, i) {
|
|
5861
|
+
const head = tokens[i];
|
|
5862
|
+
if (head === void 0) return null;
|
|
5863
|
+
if (head.type === "IDENT") {
|
|
5864
|
+
const simple = PERIODS_PER_YEAR2[wordOf(head)];
|
|
5865
|
+
if (simple !== void 0) return { perYear: simple, consumed: 1 };
|
|
5866
|
+
if (wordOf(head) === "every") {
|
|
5867
|
+
const countToken = tokens[i + 1];
|
|
5868
|
+
if (countToken?.type !== "NUMBER") return null;
|
|
5869
|
+
const per = unitPerYear(tokens[i + 2]);
|
|
5870
|
+
if (per === void 0) return null;
|
|
5871
|
+
const n = Number((countToken.value ?? "").replace(/,/g, ""));
|
|
5872
|
+
if (!(n > 0)) {
|
|
5873
|
+
throw chunkB4HBEFTB_cjs.ErrorFactory.parsing({
|
|
5874
|
+
code: RecurringScheduleErrorCodes.RECURRING_INTERVAL_NOT_POSITIVE,
|
|
5875
|
+
message: `A recurring interval must be a positive number, not "${countToken.value}".`,
|
|
5876
|
+
expected: "a positive interval, e.g. every 2 weeks",
|
|
5877
|
+
found: `every ${countToken.value} ${wordOf(tokens[i + 2])}`
|
|
5878
|
+
});
|
|
5879
|
+
}
|
|
5880
|
+
return { perYear: per / n, consumed: 3 };
|
|
5881
|
+
}
|
|
5882
|
+
}
|
|
5883
|
+
return null;
|
|
5884
|
+
}
|
|
5885
|
+
function readDuration(tokens, i) {
|
|
5886
|
+
const first = tokens[i];
|
|
5887
|
+
if (first === void 0) return null;
|
|
5888
|
+
let count;
|
|
5889
|
+
let unitIndex;
|
|
5890
|
+
if (first.type === "NUMBER") {
|
|
5891
|
+
count = Number((first.value ?? "").replace(/,/g, ""));
|
|
5892
|
+
unitIndex = i + 1;
|
|
5893
|
+
} else if (first.type === "IDENT" && ARTICLES3.has(wordOf(first))) {
|
|
5894
|
+
count = 1;
|
|
5895
|
+
unitIndex = i + 1;
|
|
5896
|
+
} else {
|
|
5897
|
+
return null;
|
|
5898
|
+
}
|
|
5899
|
+
const per = unitPerYear(tokens[unitIndex]);
|
|
5900
|
+
if (per === void 0) return null;
|
|
5901
|
+
if (!Number.isFinite(count) || count < 0) return null;
|
|
5902
|
+
return { years: count / per, consumed: unitIndex - i + 1 };
|
|
5903
|
+
}
|
|
5904
|
+
function wholePayments(perYear, durationYears) {
|
|
5905
|
+
const raw = perYear * durationYears;
|
|
5906
|
+
const nearest = Math.round(raw);
|
|
5907
|
+
return Math.abs(raw - nearest) < 1e-9 ? nearest : Math.floor(raw);
|
|
5908
|
+
}
|
|
5909
|
+
function recurringScheduleNormalizerRule(priority = 78) {
|
|
5910
|
+
return {
|
|
5911
|
+
name: "finance:recurring-schedule",
|
|
5912
|
+
priority,
|
|
5913
|
+
match(tokens, pos) {
|
|
5914
|
+
const amount = tokens[pos];
|
|
5915
|
+
if (amount === void 0 || !VALUE_ENDERS.has(amount.type)) return null;
|
|
5916
|
+
const period = readPeriod(tokens, pos + 1);
|
|
5917
|
+
if (period === null) return null;
|
|
5918
|
+
const forIndex = pos + 1 + period.consumed;
|
|
5919
|
+
if (tokens[forIndex]?.type !== "FOR_DURATION") return null;
|
|
5920
|
+
const duration = readDuration(tokens, forIndex + 1);
|
|
5921
|
+
if (duration === null) return null;
|
|
5922
|
+
const count = wholePayments(period.perYear, duration.years);
|
|
5923
|
+
const consumed = forIndex + 1 + duration.consumed - pos;
|
|
5924
|
+
const source = tokens.slice(pos, pos + consumed);
|
|
5925
|
+
return {
|
|
5926
|
+
// The amount is re-emitted unchanged, then `* <count>`. The amount may
|
|
5927
|
+
// be the tail of a longer expression, whose earlier tokens are before
|
|
5928
|
+
// `pos` and pass through on their own.
|
|
5929
|
+
replacement: [
|
|
5930
|
+
amount,
|
|
5931
|
+
chunkC75AFGVD_cjs.createFusedToken("STAR", "*", source),
|
|
5932
|
+
chunkC75AFGVD_cjs.createFusedToken("NUMBER", String(count), source)
|
|
5933
|
+
],
|
|
5934
|
+
consumed,
|
|
5935
|
+
ruleName: "finance:recurring-schedule"
|
|
5936
|
+
};
|
|
5937
|
+
}
|
|
5938
|
+
};
|
|
5939
|
+
}
|
|
5940
|
+
|
|
5399
5941
|
// src/packages/finance/FinancePackage.ts
|
|
5400
5942
|
var COMPOUND_FV = 51;
|
|
5401
5943
|
var COMPOUND_INTEREST = 52;
|
|
@@ -5472,7 +6014,11 @@ var FINANCE_PACKAGE = {
|
|
|
5472
6014
|
{ tokenType: "IN_YEAR_DOLLARS", parselet: new InYearDollarsParselet() }
|
|
5473
6015
|
],
|
|
5474
6016
|
normalizerRules: [
|
|
5475
|
-
inYearDollarsNormalizerRule()
|
|
6017
|
+
inYearDollarsNormalizerRule(),
|
|
6018
|
+
// `450 monthly for 18 months` -> `450 * 18`. A recurring schedule totalled
|
|
6019
|
+
// as a plain multiplication, so a currency amount stays currency and an
|
|
6020
|
+
// exact one stays exact. See RecurringScheduleNormalizerRule.ts.
|
|
6021
|
+
recurringScheduleNormalizerRule()
|
|
5476
6022
|
],
|
|
5477
6023
|
pluginFunctions: [
|
|
5478
6024
|
{ index: INFLATION_FROM_YEAR_TO_PRESENT_IDX, handler: inflationFromYearToPresentHandler },
|
|
@@ -5483,7 +6029,7 @@ var FINANCE_PACKAGE = {
|
|
|
5483
6029
|
|
|
5484
6030
|
// src/resolvers/QueryResolver.ts
|
|
5485
6031
|
function defaultOnError(namespace) {
|
|
5486
|
-
return (query, error) =>
|
|
6032
|
+
return (query, error) => chunk2TZKENDH_cjs.errorValue(
|
|
5487
6033
|
`${namespace.toUpperCase()}_QUERY_FAILED`,
|
|
5488
6034
|
`Failed to resolve "${query}": ${error instanceof Error ? error.message : String(error)}`
|
|
5489
6035
|
);
|
|
@@ -5538,7 +6084,7 @@ function createQueryResolver(opts) {
|
|
|
5538
6084
|
i += 3;
|
|
5539
6085
|
continue;
|
|
5540
6086
|
}
|
|
5541
|
-
i =
|
|
6087
|
+
i = chunkSSV46KFA_cjs.nextInstruction(opcodes, i);
|
|
5542
6088
|
}
|
|
5543
6089
|
return null;
|
|
5544
6090
|
},
|
|
@@ -5549,7 +6095,7 @@ function createQueryResolver(opts) {
|
|
|
5549
6095
|
const query = args[0]?.value;
|
|
5550
6096
|
const cached = chunkZ2XP767T_cjs.getActiveQueryClient()?.getQueryData(queryKeyFor(query));
|
|
5551
6097
|
if (cached !== void 0) return cached;
|
|
5552
|
-
return
|
|
6098
|
+
return chunk2TZKENDH_cjs.errorValue(`${opts.namespace.toUpperCase()}_NOT_PREFLIGHTED`, `No cached result for "${query}"`);
|
|
5553
6099
|
};
|
|
5554
6100
|
return { resolver, pluginFunction };
|
|
5555
6101
|
}
|
|
@@ -5561,7 +6107,7 @@ function consumeCityName(parser, triggerText) {
|
|
|
5561
6107
|
words.push(parser.consume().value);
|
|
5562
6108
|
}
|
|
5563
6109
|
if (words.length === 0) {
|
|
5564
|
-
throw
|
|
6110
|
+
throw chunkB4HBEFTB_cjs.ErrorFactory.parsing(
|
|
5565
6111
|
"WEATHER_EXPECTED_CITY",
|
|
5566
6112
|
`Expected a city name after "${triggerText}" (e.g. "${triggerText} London")`
|
|
5567
6113
|
);
|
|
@@ -5632,12 +6178,12 @@ var WeatherErrorCodes = {
|
|
|
5632
6178
|
};
|
|
5633
6179
|
var GEOCODING_API_URL = "https://geocoding-api.open-meteo.com/v1/search";
|
|
5634
6180
|
var FORECAST_API_URL = "https://api.open-meteo.com/v1/forecast";
|
|
5635
|
-
var
|
|
6181
|
+
var FETCH_TIMEOUT_MS2 = 1e4;
|
|
5636
6182
|
async function geocodeCity(city, signal) {
|
|
5637
6183
|
const url = `${GEOCODING_API_URL}?name=${encodeURIComponent(city)}&count=1&language=en&format=json`;
|
|
5638
6184
|
const response = await fetch(url, { signal });
|
|
5639
6185
|
if (!response.ok) {
|
|
5640
|
-
throw
|
|
6186
|
+
throw chunkB4HBEFTB_cjs.ErrorFactory.external(
|
|
5641
6187
|
WeatherErrorCodes.GEOCODING_API_ERROR,
|
|
5642
6188
|
`Open-Meteo geocoding API returned ${response.status} for "${city}"`,
|
|
5643
6189
|
{ city, status: response.status }
|
|
@@ -5646,7 +6192,7 @@ async function geocodeCity(city, signal) {
|
|
|
5646
6192
|
const json = await response.json();
|
|
5647
6193
|
const first = json?.results?.[0];
|
|
5648
6194
|
if (!first) {
|
|
5649
|
-
throw
|
|
6195
|
+
throw chunkB4HBEFTB_cjs.ErrorFactory.validation(
|
|
5650
6196
|
WeatherErrorCodes.CITY_NOT_FOUND,
|
|
5651
6197
|
`No location found for "${city}"`,
|
|
5652
6198
|
{ city }
|
|
@@ -5665,7 +6211,7 @@ async function fetchForecast(lat, lon, signal) {
|
|
|
5665
6211
|
});
|
|
5666
6212
|
const response = await fetch(`${FORECAST_API_URL}?${params.toString()}`, { signal });
|
|
5667
6213
|
if (!response.ok) {
|
|
5668
|
-
throw
|
|
6214
|
+
throw chunkB4HBEFTB_cjs.ErrorFactory.external(
|
|
5669
6215
|
WeatherErrorCodes.FORECAST_API_ERROR,
|
|
5670
6216
|
`Open-Meteo forecast API returned ${response.status}`,
|
|
5671
6217
|
{ status: response.status }
|
|
@@ -5675,7 +6221,7 @@ async function fetchForecast(lat, lon, signal) {
|
|
|
5675
6221
|
const current = json?.current;
|
|
5676
6222
|
const daily = json?.daily;
|
|
5677
6223
|
if (!current || !daily) {
|
|
5678
|
-
throw
|
|
6224
|
+
throw chunkB4HBEFTB_cjs.ErrorFactory.external(
|
|
5679
6225
|
WeatherErrorCodes.FORECAST_RESPONSE_MALFORMED,
|
|
5680
6226
|
"Open-Meteo forecast response missing current/daily blocks"
|
|
5681
6227
|
);
|
|
@@ -5697,7 +6243,7 @@ function fetchCityWeather(city, signal) {
|
|
|
5697
6243
|
if (cached && cached.expiresAt > now) {
|
|
5698
6244
|
return cached.promise;
|
|
5699
6245
|
}
|
|
5700
|
-
const { signal: fetchSignal, cleanup } = chunkVEKIWQ3F_cjs.createTimeoutSignal(signal,
|
|
6246
|
+
const { signal: fetchSignal, cleanup } = chunkVEKIWQ3F_cjs.createTimeoutSignal(signal, FETCH_TIMEOUT_MS2, "Open-Meteo weather query");
|
|
5701
6247
|
const promise = (async () => {
|
|
5702
6248
|
try {
|
|
5703
6249
|
const geo = await geocodeCity(city, fetchSignal);
|
|
@@ -5726,7 +6272,7 @@ function fetchCityWeather(city, signal) {
|
|
|
5726
6272
|
}
|
|
5727
6273
|
|
|
5728
6274
|
// src/packages/weather/WeatherPackage.ts
|
|
5729
|
-
var WEATHER_FN_IDX =
|
|
6275
|
+
var WEATHER_FN_IDX = chunk7ZX6B7SY_cjs.allocatePluginFunctionIndex();
|
|
5730
6276
|
var { resolver: weatherResolver, pluginFunction: weatherPluginFunction } = createQueryResolver({
|
|
5731
6277
|
namespace: "weather",
|
|
5732
6278
|
pluginFunctionIndex: WEATHER_FN_IDX,
|
|
@@ -5739,17 +6285,17 @@ var { resolver: weatherResolver, pluginFunction: weatherPluginFunction } = creat
|
|
|
5739
6285
|
const data = await fetchCityWeather(city, signal);
|
|
5740
6286
|
switch (kind) {
|
|
5741
6287
|
case "current":
|
|
5742
|
-
return
|
|
6288
|
+
return chunk2TZKENDH_cjs.stringValue(`${Math.round(data.temperature)}\xB0C, ${data.description}`);
|
|
5743
6289
|
case "temperature":
|
|
5744
|
-
return
|
|
6290
|
+
return chunk2TZKENDH_cjs.uomValue(data.temperature, "C");
|
|
5745
6291
|
case "feelslike":
|
|
5746
|
-
return
|
|
6292
|
+
return chunk2TZKENDH_cjs.uomValue(data.apparentTemperature, "C");
|
|
5747
6293
|
case "high":
|
|
5748
|
-
return
|
|
6294
|
+
return chunk2TZKENDH_cjs.uomValue(data.high, "C");
|
|
5749
6295
|
case "low":
|
|
5750
|
-
return
|
|
6296
|
+
return chunk2TZKENDH_cjs.uomValue(data.low, "C");
|
|
5751
6297
|
default:
|
|
5752
|
-
throw
|
|
6298
|
+
throw chunkB4HBEFTB_cjs.ErrorFactory.internal(
|
|
5753
6299
|
WeatherErrorCodes.UNKNOWN_QUERY_KIND,
|
|
5754
6300
|
`Unknown weather query kind "${kind}"`,
|
|
5755
6301
|
{ kind }
|
|
@@ -5806,22 +6352,22 @@ var MONTH_NAMES2 = {
|
|
|
5806
6352
|
dec: 11,
|
|
5807
6353
|
december: 11
|
|
5808
6354
|
};
|
|
5809
|
-
function
|
|
6355
|
+
function pad22(n) {
|
|
5810
6356
|
return n < 10 ? `0${n}` : String(n);
|
|
5811
6357
|
}
|
|
5812
6358
|
function validateAndFormat(year, monthIndex, day, raw) {
|
|
5813
6359
|
const d = new Date(year, monthIndex, day);
|
|
5814
6360
|
if (d.getFullYear() !== year || d.getMonth() !== monthIndex || d.getDate() !== day) {
|
|
5815
|
-
throw
|
|
6361
|
+
throw chunkB4HBEFTB_cjs.ErrorFactory.parsing(
|
|
5816
6362
|
"STOCKS_INVALID_DATE",
|
|
5817
6363
|
`"${raw}" is not a valid calendar date`
|
|
5818
6364
|
);
|
|
5819
6365
|
}
|
|
5820
|
-
return { isoDate: `${year}-${
|
|
6366
|
+
return { isoDate: `${year}-${pad22(monthIndex + 1)}-${pad22(day)}`, raw };
|
|
5821
6367
|
}
|
|
5822
6368
|
function requireYear(text, raw) {
|
|
5823
6369
|
if (!/^\d{4}$/.test(text)) {
|
|
5824
|
-
throw
|
|
6370
|
+
throw chunkB4HBEFTB_cjs.ErrorFactory.parsing(
|
|
5825
6371
|
"STOCKS_INVALID_DATE",
|
|
5826
6372
|
`Expected a 4-digit year in "${raw}", got "${text}"`
|
|
5827
6373
|
);
|
|
@@ -5836,7 +6382,7 @@ function tryParseDatePhrase(parser) {
|
|
|
5836
6382
|
const date = new Date(Number(first.value));
|
|
5837
6383
|
if (Number.isNaN(date.getTime())) return null;
|
|
5838
6384
|
return {
|
|
5839
|
-
isoDate: `${date.getFullYear()}-${
|
|
6385
|
+
isoDate: `${date.getFullYear()}-${pad22(date.getMonth() + 1)}-${pad22(date.getDate())}`,
|
|
5840
6386
|
raw: first.text ?? first.value
|
|
5841
6387
|
};
|
|
5842
6388
|
}
|
|
@@ -5878,7 +6424,7 @@ function tryParseDatePhrase(parser) {
|
|
|
5878
6424
|
const year = requireYear(yearTok.value, raw);
|
|
5879
6425
|
return validateAndFormat(year, monthIndex, parseInt(g1.value, 10), raw);
|
|
5880
6426
|
}
|
|
5881
|
-
throw
|
|
6427
|
+
throw chunkB4HBEFTB_cjs.ErrorFactory.parsing(
|
|
5882
6428
|
"STOCKS_INVALID_DATE",
|
|
5883
6429
|
`Expected a date after "on" (e.g. "April 12, 2005" or "4/12/2005"), got "${g1.value}"`
|
|
5884
6430
|
);
|
|
@@ -5965,7 +6511,7 @@ var MAJOR_TICKERS = /* @__PURE__ */ new Set([
|
|
|
5965
6511
|
|
|
5966
6512
|
// src/packages/stocks/normalizer/StockTickerNormalizerRule.ts
|
|
5967
6513
|
var STOCK_TICKER_TYPE = "STOCK_TICKER";
|
|
5968
|
-
var STOCK_TICKER_TYPE_ID =
|
|
6514
|
+
var STOCK_TICKER_TYPE_ID = chunkQFTDTX6K_cjs.tokenTypeId(STOCK_TICKER_TYPE);
|
|
5969
6515
|
function stockTickerNormalizerRule() {
|
|
5970
6516
|
return {
|
|
5971
6517
|
name: "stocks:bare-ticker",
|
|
@@ -5975,7 +6521,7 @@ function stockTickerNormalizerRule() {
|
|
|
5975
6521
|
if (!token || token.type !== "IDENT") return null;
|
|
5976
6522
|
if (!MAJOR_TICKERS.has(token.value)) return null;
|
|
5977
6523
|
if (pos > 0 && tokens[pos - 1].type === "COLON") return null;
|
|
5978
|
-
const fusedToken = new
|
|
6524
|
+
const fusedToken = new chunkYTIYVHL7_cjs.LexerToken(
|
|
5979
6525
|
STOCK_TICKER_TYPE,
|
|
5980
6526
|
STOCK_TICKER_TYPE_ID,
|
|
5981
6527
|
token.value,
|
|
@@ -6001,7 +6547,7 @@ function tryParseDateSuffix(parser) {
|
|
|
6001
6547
|
parser.consume();
|
|
6002
6548
|
const onTok = parser.peek();
|
|
6003
6549
|
if (!onTok || onTok.type !== "IDENT" || onTok.value.toLowerCase() !== "on") {
|
|
6004
|
-
throw
|
|
6550
|
+
throw chunkB4HBEFTB_cjs.ErrorFactory.parsing(
|
|
6005
6551
|
"STOCKS_EXPECTED_ON",
|
|
6006
6552
|
`Expected "on <date>" after "${lower}" (e.g. "AAPL ${lower} on April 12, 2005")`
|
|
6007
6553
|
);
|
|
@@ -6014,7 +6560,7 @@ function tryParseDateSuffix(parser) {
|
|
|
6014
6560
|
}
|
|
6015
6561
|
const date = tryParseDatePhrase(parser);
|
|
6016
6562
|
if (!date) {
|
|
6017
|
-
throw
|
|
6563
|
+
throw chunkB4HBEFTB_cjs.ErrorFactory.parsing(
|
|
6018
6564
|
"STOCKS_EXPECTED_DATE",
|
|
6019
6565
|
`Expected a date after "on" (e.g. "April 12, 2005" or "4/12/2005")`
|
|
6020
6566
|
);
|
|
@@ -6044,7 +6590,7 @@ function finishStockExpression(parser, builder, ticker, currentFnIdx, historical
|
|
|
6044
6590
|
const suffix = tryParseDateSuffix(parser);
|
|
6045
6591
|
if (sawStar && !suffix) {
|
|
6046
6592
|
emitStockQuery(builder, ticker, null, currentFnIdx, historicalFnIdx);
|
|
6047
|
-
parser.parseExpression(
|
|
6593
|
+
parser.parseExpression(chunkJ45BCEZ4_cjs.BindingPower.Product, builder);
|
|
6048
6594
|
builder.emitOpcode(22 /* MUL */);
|
|
6049
6595
|
return;
|
|
6050
6596
|
}
|
|
@@ -6062,7 +6608,7 @@ function stockFnParselet(currentFnIdx, historicalFnIdx) {
|
|
|
6062
6608
|
} else if (tickerToken.type === "IDENT" || tickerToken.type === STOCK_TICKER_TYPE) {
|
|
6063
6609
|
ticker = tickerToken.value.toUpperCase();
|
|
6064
6610
|
} else {
|
|
6065
|
-
throw
|
|
6611
|
+
throw chunkB4HBEFTB_cjs.ErrorFactory.parsing(
|
|
6066
6612
|
"STOCKS_INVALID_TICKER",
|
|
6067
6613
|
`Expected a ticker symbol inside stock(...), got "${tickerToken.value}" (${tickerToken.type})`
|
|
6068
6614
|
);
|
|
@@ -6084,10 +6630,10 @@ function bareStockTickerParselet(currentFnIdx, historicalFnIdx) {
|
|
|
6084
6630
|
|
|
6085
6631
|
// src/packages/stocks/StocksPackage.ts
|
|
6086
6632
|
function createStocksPackage(config = {}) {
|
|
6087
|
-
const currentFnIdx =
|
|
6088
|
-
const historicalFnIdx =
|
|
6633
|
+
const currentFnIdx = chunk7ZX6B7SY_cjs.allocatePluginFunctionIndex();
|
|
6634
|
+
const historicalFnIdx = chunk7ZX6B7SY_cjs.allocatePluginFunctionIndex();
|
|
6089
6635
|
function notConfigured(what) {
|
|
6090
|
-
return
|
|
6636
|
+
return chunk2TZKENDH_cjs.errorValue(
|
|
6091
6637
|
"STOCKS_NOT_CONFIGURED",
|
|
6092
6638
|
`Stock data provider not configured. Supply ${what} via createStocksPackage({ ... }); see the StocksPackage doc comment.`
|
|
6093
6639
|
);
|
|
@@ -6100,7 +6646,7 @@ function createStocksPackage(config = {}) {
|
|
|
6100
6646
|
fetchQuery: async (ticker, signal) => {
|
|
6101
6647
|
if (!config.fetchQuote) return notConfigured("fetchQuote");
|
|
6102
6648
|
const quote = await config.fetchQuote(ticker, signal);
|
|
6103
|
-
return
|
|
6649
|
+
return chunk2TZKENDH_cjs.uomValue(quote.price, quote.currency ?? "USD");
|
|
6104
6650
|
}
|
|
6105
6651
|
});
|
|
6106
6652
|
const { resolver: historicalResolver, pluginFunction: historicalPluginFunction } = createQueryResolver({
|
|
@@ -6112,8 +6658,8 @@ function createStocksPackage(config = {}) {
|
|
|
6112
6658
|
const [field, ticker, isoDate] = query.split(":");
|
|
6113
6659
|
if (!config.fetchHistoricalQuote) return notConfigured("fetchHistoricalQuote");
|
|
6114
6660
|
const quote = await config.fetchHistoricalQuote(ticker, isoDate, signal);
|
|
6115
|
-
if (field === "volume") return
|
|
6116
|
-
return
|
|
6661
|
+
if (field === "volume") return chunk2TZKENDH_cjs.numberValue(quote.volume ?? 0);
|
|
6662
|
+
return chunk2TZKENDH_cjs.uomValue(quote.close, quote.currency ?? "USD");
|
|
6117
6663
|
}
|
|
6118
6664
|
});
|
|
6119
6665
|
const pkg = {
|
|
@@ -6160,20 +6706,20 @@ function knowledgeQueryParselet(pluginFnIdx) {
|
|
|
6160
6706
|
|
|
6161
6707
|
// src/packages/knowledge/KnowledgePackage.ts
|
|
6162
6708
|
function createKnowledgePackage(config = {}) {
|
|
6163
|
-
const fnIdx =
|
|
6709
|
+
const fnIdx = chunk7ZX6B7SY_cjs.allocatePluginFunctionIndex();
|
|
6164
6710
|
const { resolver, pluginFunction } = createQueryResolver({
|
|
6165
6711
|
namespace: "knowledge",
|
|
6166
6712
|
pluginFunctionIndex: fnIdx,
|
|
6167
6713
|
staleTimeMs: config.staleTimeMs ?? 5 * 60 * 1e3,
|
|
6168
6714
|
fetchQuery: async (query, signal) => {
|
|
6169
6715
|
if (!config.answerQuery) {
|
|
6170
|
-
return
|
|
6716
|
+
return chunk2TZKENDH_cjs.errorValue(
|
|
6171
6717
|
"KNOWLEDGE_NOT_CONFIGURED",
|
|
6172
6718
|
`Knowledge answer provider not configured. Supply answerQuery via createKnowledgePackage({ ... }); see the KnowledgePackage doc comment.`
|
|
6173
6719
|
);
|
|
6174
6720
|
}
|
|
6175
6721
|
const answer = await config.answerQuery(query, signal);
|
|
6176
|
-
return
|
|
6722
|
+
return chunk2TZKENDH_cjs.stringValue(answer);
|
|
6177
6723
|
}
|
|
6178
6724
|
});
|
|
6179
6725
|
return {
|
|
@@ -6200,23 +6746,23 @@ function createKnowledgePackage(config = {}) {
|
|
|
6200
6746
|
// src/packages/lines/LinesPluginFunctions.ts
|
|
6201
6747
|
function checkLineValue(v, lineNumber) {
|
|
6202
6748
|
if (v === void 0) {
|
|
6203
|
-
return
|
|
6749
|
+
return chunk2TZKENDH_cjs.errorValue("LINE_NOT_YET_EVALUATED", `Line ${lineNumber} has not been evaluated yet (forward reference, or out of range)`);
|
|
6204
6750
|
}
|
|
6205
6751
|
if (v.type === 12 /* Pending */) {
|
|
6206
|
-
return
|
|
6752
|
+
return chunk2TZKENDH_cjs.errorValue("LINE_RESULT_PENDING", `Line ${lineNumber}'s result is still resolving`);
|
|
6207
6753
|
}
|
|
6208
6754
|
if (v.type === 13 /* Error */) {
|
|
6209
|
-
return
|
|
6755
|
+
return chunk2TZKENDH_cjs.errorValue("LINE_RESULT_ERROR", `Line ${lineNumber} has an error`);
|
|
6210
6756
|
}
|
|
6211
6757
|
return null;
|
|
6212
6758
|
}
|
|
6213
6759
|
function requireContext(context) {
|
|
6214
6760
|
if (!context?.getLineResult) {
|
|
6215
|
-
return
|
|
6761
|
+
return chunk2TZKENDH_cjs.errorValue("LINE_REF_NO_DOCUMENT", "Cross-line references require a real document \u2014 not available outside one (e.g. evaluateExpression()'s single-expression path)");
|
|
6216
6762
|
}
|
|
6217
6763
|
return null;
|
|
6218
6764
|
}
|
|
6219
|
-
var PREV_FN_IDX =
|
|
6765
|
+
var PREV_FN_IDX = chunk7ZX6B7SY_cjs.allocatePluginFunctionIndex();
|
|
6220
6766
|
function prevHandler(_args, context) {
|
|
6221
6767
|
const ctxError = requireContext(context);
|
|
6222
6768
|
if (ctxError) return ctxError;
|
|
@@ -6225,7 +6771,7 @@ function prevHandler(_args, context) {
|
|
|
6225
6771
|
const err = checkLineValue(v, targetLine);
|
|
6226
6772
|
return err ?? v;
|
|
6227
6773
|
}
|
|
6228
|
-
var LINE_REF_FN_IDX =
|
|
6774
|
+
var LINE_REF_FN_IDX = chunk7ZX6B7SY_cjs.allocatePluginFunctionIndex();
|
|
6229
6775
|
function lineRefHandler(args, context) {
|
|
6230
6776
|
const ctxError = requireContext(context);
|
|
6231
6777
|
if (ctxError) return ctxError;
|
|
@@ -6245,28 +6791,28 @@ function aggregateRange(from, to, context, isAverage) {
|
|
|
6245
6791
|
const err = checkLineValue(v, n);
|
|
6246
6792
|
if (err) return err;
|
|
6247
6793
|
if (v.type !== 0 /* Number */ && v.type !== 6 /* Uom */) {
|
|
6248
|
-
return
|
|
6794
|
+
return chunk2TZKENDH_cjs.errorValue("LINE_RANGE_NON_NUMERIC", `Line ${n} is not a plain number or unit value \u2014 cannot include it in a sum/total/average range`);
|
|
6249
6795
|
}
|
|
6250
6796
|
if (v.type === 6 /* Uom */) {
|
|
6251
6797
|
sawUom = true;
|
|
6252
6798
|
if (commonUnit === void 0) commonUnit = v.unit;
|
|
6253
6799
|
else if (v.unit !== commonUnit) {
|
|
6254
|
-
return
|
|
6800
|
+
return chunk2TZKENDH_cjs.errorValue("LINE_RANGE_MIXED_UNITS", `Line ${n}'s unit (${v.unit}) doesn't match the range's first unit (${commonUnit}) \u2014 aggregating mixed units would silently misrepresent the result`);
|
|
6255
6801
|
}
|
|
6256
6802
|
}
|
|
6257
6803
|
total += v.toNumber();
|
|
6258
6804
|
count++;
|
|
6259
6805
|
}
|
|
6260
6806
|
const result = isAverage ? total / count : total;
|
|
6261
|
-
return sawUom ?
|
|
6807
|
+
return sawUom ? chunk2TZKENDH_cjs.uomValue(result, commonUnit) : chunk2TZKENDH_cjs.numberValue(result);
|
|
6262
6808
|
}
|
|
6263
|
-
var SUM_RANGE_FN_IDX =
|
|
6809
|
+
var SUM_RANGE_FN_IDX = chunk7ZX6B7SY_cjs.allocatePluginFunctionIndex();
|
|
6264
6810
|
function sumRangeHandler(args, context) {
|
|
6265
6811
|
const ctxError = requireContext(context);
|
|
6266
6812
|
if (ctxError) return ctxError;
|
|
6267
6813
|
return aggregateRange(args[0].toNumber(), args[1].toNumber(), context, false);
|
|
6268
6814
|
}
|
|
6269
|
-
var AVERAGE_RANGE_FN_IDX =
|
|
6815
|
+
var AVERAGE_RANGE_FN_IDX = chunk7ZX6B7SY_cjs.allocatePluginFunctionIndex();
|
|
6270
6816
|
function averageRangeHandler(args, context) {
|
|
6271
6817
|
const ctxError = requireContext(context);
|
|
6272
6818
|
if (ctxError) return ctxError;
|
|
@@ -6275,7 +6821,7 @@ function averageRangeHandler(args, context) {
|
|
|
6275
6821
|
function aggregateAbove(context, isAverage) {
|
|
6276
6822
|
const boundaryCheck = context.isLineBoundary;
|
|
6277
6823
|
if (!boundaryCheck) {
|
|
6278
|
-
return
|
|
6824
|
+
return chunk2TZKENDH_cjs.errorValue("LINE_REF_NO_DOCUMENT", '"above" aggregation requires a real document');
|
|
6279
6825
|
}
|
|
6280
6826
|
let total = 0;
|
|
6281
6827
|
let count = 0;
|
|
@@ -6287,29 +6833,29 @@ function aggregateAbove(context, isAverage) {
|
|
|
6287
6833
|
const err = checkLineValue(v, n);
|
|
6288
6834
|
if (err) return err;
|
|
6289
6835
|
if (v.type !== 0 /* Number */ && v.type !== 6 /* Uom */) {
|
|
6290
|
-
return
|
|
6836
|
+
return chunk2TZKENDH_cjs.errorValue("LINE_RANGE_NON_NUMERIC", `Line ${n} is not a plain number or unit value \u2014 cannot include it in "above" aggregation`);
|
|
6291
6837
|
}
|
|
6292
6838
|
if (v.type === 6 /* Uom */) {
|
|
6293
6839
|
sawUom = true;
|
|
6294
6840
|
if (commonUnit === void 0) commonUnit = v.unit;
|
|
6295
6841
|
else if (v.unit !== commonUnit) {
|
|
6296
|
-
return
|
|
6842
|
+
return chunk2TZKENDH_cjs.errorValue("LINE_RANGE_MIXED_UNITS", `Line ${n}'s unit (${v.unit}) doesn't match the range's unit (${commonUnit})`);
|
|
6297
6843
|
}
|
|
6298
6844
|
}
|
|
6299
6845
|
total += v.toNumber();
|
|
6300
6846
|
count++;
|
|
6301
6847
|
}
|
|
6302
|
-
if (count === 0) return
|
|
6848
|
+
if (count === 0) return chunk2TZKENDH_cjs.errorValue("LINE_RANGE_EMPTY", "No lines above to aggregate (hit the top of the document, a blank line, or a heading immediately)");
|
|
6303
6849
|
const result = isAverage ? total / count : total;
|
|
6304
|
-
return sawUom ?
|
|
6850
|
+
return sawUom ? chunk2TZKENDH_cjs.uomValue(result, commonUnit) : chunk2TZKENDH_cjs.numberValue(result);
|
|
6305
6851
|
}
|
|
6306
|
-
var TOTAL_ABOVE_FN_IDX =
|
|
6852
|
+
var TOTAL_ABOVE_FN_IDX = chunk7ZX6B7SY_cjs.allocatePluginFunctionIndex();
|
|
6307
6853
|
function totalAboveHandler(_args, context) {
|
|
6308
6854
|
const ctxError = requireContext(context);
|
|
6309
6855
|
if (ctxError) return ctxError;
|
|
6310
6856
|
return aggregateAbove(context, false);
|
|
6311
6857
|
}
|
|
6312
|
-
var AVERAGE_ABOVE_FN_IDX =
|
|
6858
|
+
var AVERAGE_ABOVE_FN_IDX = chunk7ZX6B7SY_cjs.allocatePluginFunctionIndex();
|
|
6313
6859
|
function averageAboveHandler(_args, context) {
|
|
6314
6860
|
const ctxError = requireContext(context);
|
|
6315
6861
|
if (ctxError) return ctxError;
|
|
@@ -6381,9 +6927,9 @@ var AboveAggregateParselet = class {
|
|
|
6381
6927
|
};
|
|
6382
6928
|
|
|
6383
6929
|
// src/packages/lines/normalizer/LineRefNormalizerRule.ts
|
|
6384
|
-
var LINE_REF_TYPE_ID =
|
|
6385
|
-
var SUM_RANGE_CALL_TYPE_ID =
|
|
6386
|
-
var AVERAGE_RANGE_CALL_TYPE_ID =
|
|
6930
|
+
var LINE_REF_TYPE_ID = chunkQFTDTX6K_cjs.tokenTypeId("LINE_REF");
|
|
6931
|
+
var SUM_RANGE_CALL_TYPE_ID = chunkQFTDTX6K_cjs.tokenTypeId("SUM_RANGE_CALL");
|
|
6932
|
+
var AVERAGE_RANGE_CALL_TYPE_ID = chunkQFTDTX6K_cjs.tokenTypeId("AVERAGE_RANGE_CALL");
|
|
6387
6933
|
function lineRefNormalizerRule() {
|
|
6388
6934
|
return {
|
|
6389
6935
|
name: "lines:line-ref",
|
|
@@ -6420,7 +6966,7 @@ function lineRefNormalizerRule() {
|
|
|
6420
6966
|
};
|
|
6421
6967
|
}
|
|
6422
6968
|
function makeLineRefToken(lineNumberText, sourceToken) {
|
|
6423
|
-
return new
|
|
6969
|
+
return new chunkYTIYVHL7_cjs.LexerToken(
|
|
6424
6970
|
"LINE_REF",
|
|
6425
6971
|
LINE_REF_TYPE_ID,
|
|
6426
6972
|
lineNumberText,
|
|
@@ -6446,7 +6992,7 @@ function rangeCallNormalizerRule() {
|
|
|
6446
6992
|
return {
|
|
6447
6993
|
consumed: 1,
|
|
6448
6994
|
replacement: [
|
|
6449
|
-
new
|
|
6995
|
+
new chunkYTIYVHL7_cjs.LexerToken(tokenType, typeId, token.value, token.value, token.offset, 0, token.line, token.col)
|
|
6450
6996
|
],
|
|
6451
6997
|
ruleName: "lines:range-call"
|
|
6452
6998
|
};
|
|
@@ -6485,6 +7031,927 @@ var LINES_PACKAGE = {
|
|
|
6485
7031
|
]
|
|
6486
7032
|
};
|
|
6487
7033
|
|
|
7034
|
+
// src/packages/tables/parselets/ColumnAggregateParselet.ts
|
|
7035
|
+
var ColumnAggregateParselet = class {
|
|
7036
|
+
constructor(pluginFnIndex) {
|
|
7037
|
+
this.pluginFnIndex = pluginFnIndex;
|
|
7038
|
+
this.category = "Tables";
|
|
7039
|
+
}
|
|
7040
|
+
parse(parser, _token, builder) {
|
|
7041
|
+
const next = parser.peek();
|
|
7042
|
+
if (!next || next.type !== "STRING") {
|
|
7043
|
+
throw chunkB4HBEFTB_cjs.ErrorFactory.parsing(
|
|
7044
|
+
"TABLE_COLUMN_NAME_EXPECTED",
|
|
7045
|
+
`Expected a quoted column name after "... of column" but got ${next ? `"${next.value}"` : "end of input"}`
|
|
7046
|
+
);
|
|
7047
|
+
}
|
|
7048
|
+
const nameToken = parser.consume("STRING");
|
|
7049
|
+
while (true) {
|
|
7050
|
+
const t = parser.peek();
|
|
7051
|
+
if (!t) break;
|
|
7052
|
+
if (t.type === "IN") {
|
|
7053
|
+
parser.consume();
|
|
7054
|
+
continue;
|
|
7055
|
+
}
|
|
7056
|
+
if (t.type === "IDENT" && ADDRESS_WORDS.has(t.value.toLowerCase())) {
|
|
7057
|
+
parser.consume();
|
|
7058
|
+
continue;
|
|
7059
|
+
}
|
|
7060
|
+
break;
|
|
7061
|
+
}
|
|
7062
|
+
builder.emitOpcode(13 /* PUSH_STRING */);
|
|
7063
|
+
builder.emitString(nameToken.value);
|
|
7064
|
+
builder.emitOpcode(50 /* CALL_PLUGIN */);
|
|
7065
|
+
builder.emitIndex(this.pluginFnIndex);
|
|
7066
|
+
builder.emitIndex(1);
|
|
7067
|
+
}
|
|
7068
|
+
};
|
|
7069
|
+
var ADDRESS_WORDS = /* @__PURE__ */ new Set(["the", "table", "above"]);
|
|
7070
|
+
|
|
7071
|
+
// src/packages/tables/TableReader.ts
|
|
7072
|
+
function isTableRow(line) {
|
|
7073
|
+
return line.trimStart().startsWith("|");
|
|
7074
|
+
}
|
|
7075
|
+
function isSeparatorRow(line) {
|
|
7076
|
+
const s = line.trim();
|
|
7077
|
+
if (s.length === 0) return false;
|
|
7078
|
+
if (!s.includes("-") || !s.includes("|")) return false;
|
|
7079
|
+
return /^[|\s:-]+$/.test(s);
|
|
7080
|
+
}
|
|
7081
|
+
function splitTableRow(line) {
|
|
7082
|
+
let s = line.trim();
|
|
7083
|
+
if (s.startsWith("|")) s = s.slice(1);
|
|
7084
|
+
if (s.endsWith("|") && !s.endsWith("\\|")) s = s.slice(0, -1);
|
|
7085
|
+
const cells = [];
|
|
7086
|
+
let cell = "";
|
|
7087
|
+
for (let i = 0; i < s.length; i++) {
|
|
7088
|
+
const ch = s[i];
|
|
7089
|
+
if (ch === "\\" && i + 1 < s.length && s[i + 1] === "|") {
|
|
7090
|
+
cell += "|";
|
|
7091
|
+
i++;
|
|
7092
|
+
continue;
|
|
7093
|
+
}
|
|
7094
|
+
if (ch === "|") {
|
|
7095
|
+
cells.push(cell.trim());
|
|
7096
|
+
cell = "";
|
|
7097
|
+
continue;
|
|
7098
|
+
}
|
|
7099
|
+
cell += ch;
|
|
7100
|
+
}
|
|
7101
|
+
cells.push(cell.trim());
|
|
7102
|
+
return cells;
|
|
7103
|
+
}
|
|
7104
|
+
function parseNumericCell(cell) {
|
|
7105
|
+
if (cell === void 0) return null;
|
|
7106
|
+
const trimmed = cell.trim();
|
|
7107
|
+
if (trimmed.length === 0) return null;
|
|
7108
|
+
const cleaned = trimmed.replace(/,/g, "");
|
|
7109
|
+
if (!/^[+-]?(\d+(\.\d+)?|\.\d+)$/.test(cleaned)) return null;
|
|
7110
|
+
const n = Number.parseFloat(cleaned);
|
|
7111
|
+
return Number.isFinite(n) ? n : null;
|
|
7112
|
+
}
|
|
7113
|
+
function findTableAbove(getLineText, fromLine) {
|
|
7114
|
+
let bottom = -1;
|
|
7115
|
+
for (let n = fromLine - 1; n >= 1; n--) {
|
|
7116
|
+
const text = getLineText(n);
|
|
7117
|
+
if (text === void 0) break;
|
|
7118
|
+
if (isTableRow(text)) {
|
|
7119
|
+
bottom = n;
|
|
7120
|
+
break;
|
|
7121
|
+
}
|
|
7122
|
+
}
|
|
7123
|
+
if (bottom === -1) return null;
|
|
7124
|
+
let top = bottom;
|
|
7125
|
+
while (top - 1 >= 1) {
|
|
7126
|
+
const text = getLineText(top - 1);
|
|
7127
|
+
if (text === void 0 || !isTableRow(text)) break;
|
|
7128
|
+
top--;
|
|
7129
|
+
}
|
|
7130
|
+
let separator = -1;
|
|
7131
|
+
for (let n = top; n <= bottom; n++) {
|
|
7132
|
+
if (isSeparatorRow(getLineText(n))) {
|
|
7133
|
+
separator = n;
|
|
7134
|
+
break;
|
|
7135
|
+
}
|
|
7136
|
+
}
|
|
7137
|
+
if (separator === -1 || separator === top) return null;
|
|
7138
|
+
const header = splitTableRow(getLineText(separator - 1));
|
|
7139
|
+
const rows = [];
|
|
7140
|
+
for (let n = separator + 1; n <= bottom; n++) {
|
|
7141
|
+
rows.push(splitTableRow(getLineText(n)));
|
|
7142
|
+
}
|
|
7143
|
+
return { header, rows };
|
|
7144
|
+
}
|
|
7145
|
+
function columnIndex(header, name) {
|
|
7146
|
+
const target = name.trim().toLowerCase();
|
|
7147
|
+
for (let i = 0; i < header.length; i++) {
|
|
7148
|
+
if (header[i].trim().toLowerCase() === target) return i;
|
|
7149
|
+
}
|
|
7150
|
+
return -1;
|
|
7151
|
+
}
|
|
7152
|
+
function numericColumn(table, colIndex) {
|
|
7153
|
+
const out = [];
|
|
7154
|
+
for (const row of table.rows) {
|
|
7155
|
+
const value = parseNumericCell(row[colIndex]);
|
|
7156
|
+
if (value !== null) out.push(value);
|
|
7157
|
+
}
|
|
7158
|
+
return out;
|
|
7159
|
+
}
|
|
7160
|
+
|
|
7161
|
+
// src/packages/tables/TablesPluginFunctions.ts
|
|
7162
|
+
var TablesErrorCodes = {
|
|
7163
|
+
/** Cross-line table reads need a real document, absent on the single-expression path. */
|
|
7164
|
+
TABLE_NO_DOCUMENT: "TABLE_NO_DOCUMENT",
|
|
7165
|
+
/** No markdown table was found above the query line. */
|
|
7166
|
+
TABLE_NOT_FOUND: "TABLE_NOT_FOUND",
|
|
7167
|
+
/** The named column is not one of the table's headers. */
|
|
7168
|
+
TABLE_COLUMN_NOT_FOUND: "TABLE_COLUMN_NOT_FOUND",
|
|
7169
|
+
/** The column held no plain-number cells to aggregate. */
|
|
7170
|
+
TABLE_COLUMN_NO_NUMERIC_CELLS: "TABLE_COLUMN_NO_NUMERIC_CELLS"
|
|
7171
|
+
};
|
|
7172
|
+
function reduce(op, cells) {
|
|
7173
|
+
switch (op) {
|
|
7174
|
+
case "sum":
|
|
7175
|
+
return cells.reduce((acc, n) => acc + n, 0);
|
|
7176
|
+
case "average":
|
|
7177
|
+
return cells.reduce((acc, n) => acc + n, 0) / cells.length;
|
|
7178
|
+
case "min":
|
|
7179
|
+
return Math.min(...cells);
|
|
7180
|
+
case "max":
|
|
7181
|
+
return Math.max(...cells);
|
|
7182
|
+
case "count":
|
|
7183
|
+
return cells.length;
|
|
7184
|
+
case "median": {
|
|
7185
|
+
const sorted = [...cells].sort((a, b) => a - b);
|
|
7186
|
+
const mid = Math.floor(sorted.length / 2);
|
|
7187
|
+
return sorted.length % 2 === 0 ? (sorted[mid - 1] + sorted[mid]) / 2 : sorted[mid];
|
|
7188
|
+
}
|
|
7189
|
+
}
|
|
7190
|
+
}
|
|
7191
|
+
function aggregateColumn(op, columnName2, context) {
|
|
7192
|
+
const getLineText = context?.getLineText;
|
|
7193
|
+
if (!getLineText || context.lineIndex < 1) {
|
|
7194
|
+
return chunk2TZKENDH_cjs.errorValue(
|
|
7195
|
+
TablesErrorCodes.TABLE_NO_DOCUMENT,
|
|
7196
|
+
"Reading a table column needs a real document, which the single-expression path (evaluateExpression) does not have"
|
|
7197
|
+
);
|
|
7198
|
+
}
|
|
7199
|
+
const table = findTableAbove(getLineText, context.lineIndex);
|
|
7200
|
+
if (!table) {
|
|
7201
|
+
return chunk2TZKENDH_cjs.errorValue(
|
|
7202
|
+
TablesErrorCodes.TABLE_NOT_FOUND,
|
|
7203
|
+
'No markdown table found above this line (a table row starts with "|", and needs a "|---|" separator under its header)'
|
|
7204
|
+
);
|
|
7205
|
+
}
|
|
7206
|
+
const index = columnIndex(table.header, columnName2);
|
|
7207
|
+
if (index === -1) {
|
|
7208
|
+
const names = table.header.map((h) => `"${h}"`).join(", ");
|
|
7209
|
+
return chunk2TZKENDH_cjs.errorValue(
|
|
7210
|
+
TablesErrorCodes.TABLE_COLUMN_NOT_FOUND,
|
|
7211
|
+
`The table above has no column named "${columnName2}". Its columns are: ${names}`
|
|
7212
|
+
);
|
|
7213
|
+
}
|
|
7214
|
+
const cells = numericColumn(table, index);
|
|
7215
|
+
if (op === "count") return chunk2TZKENDH_cjs.numberValue(cells.length);
|
|
7216
|
+
if (cells.length === 0) {
|
|
7217
|
+
return chunk2TZKENDH_cjs.errorValue(
|
|
7218
|
+
TablesErrorCodes.TABLE_COLUMN_NO_NUMERIC_CELLS,
|
|
7219
|
+
`Column "${columnName2}" has no plain-number cells to aggregate (currency and unit cells are not read yet)`
|
|
7220
|
+
);
|
|
7221
|
+
}
|
|
7222
|
+
return chunk2TZKENDH_cjs.numberValue(reduce(op, cells));
|
|
7223
|
+
}
|
|
7224
|
+
function columnName(args) {
|
|
7225
|
+
const value = args[0];
|
|
7226
|
+
if (value && value.type === 3 /* String */ && typeof value.value === "string") {
|
|
7227
|
+
return value.value;
|
|
7228
|
+
}
|
|
7229
|
+
return String(value?.value ?? "");
|
|
7230
|
+
}
|
|
7231
|
+
var TABLE_COLUMN_SUM_FN_IDX = chunk7ZX6B7SY_cjs.allocatePluginFunctionIndex();
|
|
7232
|
+
function tableColumnSumHandler(args, context) {
|
|
7233
|
+
return aggregateColumn("sum", columnName(args), context);
|
|
7234
|
+
}
|
|
7235
|
+
var TABLE_COLUMN_AVERAGE_FN_IDX = chunk7ZX6B7SY_cjs.allocatePluginFunctionIndex();
|
|
7236
|
+
function tableColumnAverageHandler(args, context) {
|
|
7237
|
+
return aggregateColumn("average", columnName(args), context);
|
|
7238
|
+
}
|
|
7239
|
+
var TABLE_COLUMN_MIN_FN_IDX = chunk7ZX6B7SY_cjs.allocatePluginFunctionIndex();
|
|
7240
|
+
function tableColumnMinHandler(args, context) {
|
|
7241
|
+
return aggregateColumn("min", columnName(args), context);
|
|
7242
|
+
}
|
|
7243
|
+
var TABLE_COLUMN_MAX_FN_IDX = chunk7ZX6B7SY_cjs.allocatePluginFunctionIndex();
|
|
7244
|
+
function tableColumnMaxHandler(args, context) {
|
|
7245
|
+
return aggregateColumn("max", columnName(args), context);
|
|
7246
|
+
}
|
|
7247
|
+
var TABLE_COLUMN_COUNT_FN_IDX = chunk7ZX6B7SY_cjs.allocatePluginFunctionIndex();
|
|
7248
|
+
function tableColumnCountHandler(args, context) {
|
|
7249
|
+
return aggregateColumn("count", columnName(args), context);
|
|
7250
|
+
}
|
|
7251
|
+
var TABLE_COLUMN_MEDIAN_FN_IDX = chunk7ZX6B7SY_cjs.allocatePluginFunctionIndex();
|
|
7252
|
+
function tableColumnMedianHandler(args, context) {
|
|
7253
|
+
return aggregateColumn("median", columnName(args), context);
|
|
7254
|
+
}
|
|
7255
|
+
|
|
7256
|
+
// src/packages/tables/TablesPackage.ts
|
|
7257
|
+
var TABLES_PACKAGE = {
|
|
7258
|
+
name: "solve-tables",
|
|
7259
|
+
phrases: {
|
|
7260
|
+
"sum of column": "TABLE_COLUMN_SUM",
|
|
7261
|
+
"total of column": "TABLE_COLUMN_SUM",
|
|
7262
|
+
"average of column": "TABLE_COLUMN_AVERAGE",
|
|
7263
|
+
"mean of column": "TABLE_COLUMN_AVERAGE",
|
|
7264
|
+
"min of column": "TABLE_COLUMN_MIN",
|
|
7265
|
+
"minimum of column": "TABLE_COLUMN_MIN",
|
|
7266
|
+
"max of column": "TABLE_COLUMN_MAX",
|
|
7267
|
+
"maximum of column": "TABLE_COLUMN_MAX",
|
|
7268
|
+
"count of column": "TABLE_COLUMN_COUNT",
|
|
7269
|
+
"median of column": "TABLE_COLUMN_MEDIAN"
|
|
7270
|
+
},
|
|
7271
|
+
prefixParselets: [
|
|
7272
|
+
{ tokenType: "TABLE_COLUMN_SUM", parselet: new ColumnAggregateParselet(TABLE_COLUMN_SUM_FN_IDX) },
|
|
7273
|
+
{ tokenType: "TABLE_COLUMN_AVERAGE", parselet: new ColumnAggregateParselet(TABLE_COLUMN_AVERAGE_FN_IDX) },
|
|
7274
|
+
{ tokenType: "TABLE_COLUMN_MIN", parselet: new ColumnAggregateParselet(TABLE_COLUMN_MIN_FN_IDX) },
|
|
7275
|
+
{ tokenType: "TABLE_COLUMN_MAX", parselet: new ColumnAggregateParselet(TABLE_COLUMN_MAX_FN_IDX) },
|
|
7276
|
+
{ tokenType: "TABLE_COLUMN_COUNT", parselet: new ColumnAggregateParselet(TABLE_COLUMN_COUNT_FN_IDX) },
|
|
7277
|
+
{ tokenType: "TABLE_COLUMN_MEDIAN", parselet: new ColumnAggregateParselet(TABLE_COLUMN_MEDIAN_FN_IDX) }
|
|
7278
|
+
],
|
|
7279
|
+
pluginFunctions: [
|
|
7280
|
+
{ index: TABLE_COLUMN_SUM_FN_IDX, handler: tableColumnSumHandler },
|
|
7281
|
+
{ index: TABLE_COLUMN_AVERAGE_FN_IDX, handler: tableColumnAverageHandler },
|
|
7282
|
+
{ index: TABLE_COLUMN_MIN_FN_IDX, handler: tableColumnMinHandler },
|
|
7283
|
+
{ index: TABLE_COLUMN_MAX_FN_IDX, handler: tableColumnMaxHandler },
|
|
7284
|
+
{ index: TABLE_COLUMN_COUNT_FN_IDX, handler: tableColumnCountHandler },
|
|
7285
|
+
{ index: TABLE_COLUMN_MEDIAN_FN_IDX, handler: tableColumnMedianHandler }
|
|
7286
|
+
]
|
|
7287
|
+
};
|
|
7288
|
+
|
|
7289
|
+
// src/packages/uncertainty/parselets/UncertaintyParselet.ts
|
|
7290
|
+
var UncertaintyParselet = class {
|
|
7291
|
+
constructor() {
|
|
7292
|
+
this.category = "operator";
|
|
7293
|
+
this.bindingPower = chunkJ45BCEZ4_cjs.BindingPower.Uncertainty;
|
|
7294
|
+
}
|
|
7295
|
+
parse(parser, _left, _token, builder) {
|
|
7296
|
+
parser.parseExpression(this.bindingPower, builder);
|
|
7297
|
+
builder.emitOpcode(28 /* MAKE_UNCERTAIN */);
|
|
7298
|
+
}
|
|
7299
|
+
};
|
|
7300
|
+
|
|
7301
|
+
// src/packages/uncertainty/normalizer/AsciiPlusMinusNormalizerRule.ts
|
|
7302
|
+
function asciiPlusMinusNormalizerRule(priority = 90) {
|
|
7303
|
+
return {
|
|
7304
|
+
name: "uncertainty:ascii-plus-minus",
|
|
7305
|
+
priority,
|
|
7306
|
+
match(tokens, pos) {
|
|
7307
|
+
const plus = tokens[pos];
|
|
7308
|
+
if (plus?.type !== "PLUS") return null;
|
|
7309
|
+
const slash = tokens[pos + 1];
|
|
7310
|
+
if (slash?.type !== "SLASH") return null;
|
|
7311
|
+
const minus = tokens[pos + 2];
|
|
7312
|
+
if (minus?.type !== "MINUS") return null;
|
|
7313
|
+
return {
|
|
7314
|
+
consumed: 3,
|
|
7315
|
+
replacement: [chunkC75AFGVD_cjs.createFusedToken("PLUS_MINUS", "\xB1", [plus, slash, minus])],
|
|
7316
|
+
ruleName: "uncertainty:ascii-plus-minus"
|
|
7317
|
+
};
|
|
7318
|
+
}
|
|
7319
|
+
};
|
|
7320
|
+
}
|
|
7321
|
+
|
|
7322
|
+
// src/packages/uncertainty/UncertaintyPackage.ts
|
|
7323
|
+
var UNCERTAINTY_PACKAGE = {
|
|
7324
|
+
name: "solve-uncertainty",
|
|
7325
|
+
infixParselets: [
|
|
7326
|
+
{ tokenType: "PLUS_MINUS", parselet: new UncertaintyParselet() }
|
|
7327
|
+
],
|
|
7328
|
+
normalizerRules: [asciiPlusMinusNormalizerRule()]
|
|
7329
|
+
// PLUS_MINUS is a core lexer token, so its highlight category lives in the
|
|
7330
|
+
// built-in language/TokenCategoryMap.ts rather than being contributed here.
|
|
7331
|
+
};
|
|
7332
|
+
|
|
7333
|
+
// src/packages/goalseek/GoalSeekPluginFunctions.ts
|
|
7334
|
+
var SEARCH_LOWER_BOUND = 1e-9;
|
|
7335
|
+
var SEARCH_UPPER_BOUND = 1e9;
|
|
7336
|
+
var FALLBACK_MAX_ITERATIONS = 100;
|
|
7337
|
+
var ABSOLUTE_VALUE_TOLERANCE = 1e-9;
|
|
7338
|
+
var RELATIVE_VALUE_TOLERANCE = 1e-9;
|
|
7339
|
+
var INTERVAL_COLLAPSE_WIDTH = 1e-12;
|
|
7340
|
+
var REAL_ROOT_IMAGINARY_TOLERANCE = 1e-9;
|
|
7341
|
+
var GOAL_SEEK_FN_IDX = chunk7ZX6B7SY_cjs.allocatePluginFunctionIndex();
|
|
7342
|
+
function goalSeekHandler(args, context) {
|
|
7343
|
+
const probe = context?.evaluateLineWithBinding;
|
|
7344
|
+
const getLineReads = context?.getLineReads;
|
|
7345
|
+
if (!probe || !getLineReads) {
|
|
7346
|
+
return chunk2TZKENDH_cjs.errorValue(
|
|
7347
|
+
"GOAL_SEEK_NO_DOCUMENT",
|
|
7348
|
+
"Goal seek only works inside a document, since it re-runs another line. The single-expression entry point has no document to solve against."
|
|
7349
|
+
);
|
|
7350
|
+
}
|
|
7351
|
+
const targetLine = args[0].toNumber();
|
|
7352
|
+
const varName = typeof args[1].value === "string" ? args[1].value : String(args[1].value);
|
|
7353
|
+
const targetArg = args[2];
|
|
7354
|
+
if (targetArg.type !== 0 /* Number */ && targetArg.type !== 6 /* Uom */) {
|
|
7355
|
+
return chunk2TZKENDH_cjs.errorValue("GOAL_SEEK_TARGET_NOT_NUMERIC", `Goal seek's target must be a number, as in "solve line ${targetLine} for ${varName} = 900".`);
|
|
7356
|
+
}
|
|
7357
|
+
const target = targetArg.toNumber();
|
|
7358
|
+
if (!Number.isFinite(target)) {
|
|
7359
|
+
return chunk2TZKENDH_cjs.errorValue("GOAL_SEEK_TARGET_NOT_NUMERIC", "Goal seek's target is not a finite number.");
|
|
7360
|
+
}
|
|
7361
|
+
const reads = getLineReads(targetLine);
|
|
7362
|
+
if (reads === void 0) {
|
|
7363
|
+
return chunk2TZKENDH_cjs.errorValue("GOAL_SEEK_LINE_NOT_READY", `Line ${targetLine} has no evaluated expression to solve (forward reference, out of range, or not an expression).`);
|
|
7364
|
+
}
|
|
7365
|
+
if (!reads.includes(varName)) {
|
|
7366
|
+
return chunk2TZKENDH_cjs.errorValue("GOAL_SEEK_VARIABLE_NOT_USED", `Line ${targetLine} does not use ${varName}, so changing ${varName} cannot move its result toward ${target}.`);
|
|
7367
|
+
}
|
|
7368
|
+
const symbolic = probe(targetLine, varName, chunk2TZKENDH_cjs.symbolicValue(chunkHIQ5HSZL_cjs.varNode(varName)), true);
|
|
7369
|
+
if (symbolic.type === 9 /* Symbolic */) {
|
|
7370
|
+
const exact = solveClosedForm(symbolic.value, target, varName);
|
|
7371
|
+
if (exact !== null) return chunk2TZKENDH_cjs.numberValue(exact);
|
|
7372
|
+
}
|
|
7373
|
+
const maxIterations = context.goalSeekMaxIterations ?? FALLBACK_MAX_ITERATIONS;
|
|
7374
|
+
return bisect(probe, targetLine, varName, target, maxIterations);
|
|
7375
|
+
}
|
|
7376
|
+
function solveClosedForm(lhs, target, variable) {
|
|
7377
|
+
const rhs = chunkHIQ5HSZL_cjs.constNode(chunkHIQ5HSZL_cjs.rationalFromNumber(target));
|
|
7378
|
+
let outcome;
|
|
7379
|
+
try {
|
|
7380
|
+
outcome = chunk7ZX6B7SY_cjs.solveForVariable(lhs, rhs, variable);
|
|
7381
|
+
} catch {
|
|
7382
|
+
return null;
|
|
7383
|
+
}
|
|
7384
|
+
if (outcome.kind !== "roots") return null;
|
|
7385
|
+
const candidates = [];
|
|
7386
|
+
for (const node of outcome.exact) {
|
|
7387
|
+
const simplified = chunkHIQ5HSZL_cjs.simplifySymbolic(node);
|
|
7388
|
+
if (simplified.kind === "const") {
|
|
7389
|
+
const value = chunkHIQ5HSZL_cjs.rationalToNumber(simplified.value);
|
|
7390
|
+
if (Number.isFinite(value)) candidates.push(value);
|
|
7391
|
+
}
|
|
7392
|
+
}
|
|
7393
|
+
for (const root of outcome.approximate) {
|
|
7394
|
+
if (Math.abs(root.im) <= REAL_ROOT_IMAGINARY_TOLERANCE && Number.isFinite(root.re)) candidates.push(root.re);
|
|
7395
|
+
}
|
|
7396
|
+
if (candidates.length === 0) return null;
|
|
7397
|
+
const inDomain = candidates.filter((c) => c >= SEARCH_LOWER_BOUND && c <= SEARCH_UPPER_BOUND);
|
|
7398
|
+
const pool = inDomain.length > 0 ? inDomain : candidates;
|
|
7399
|
+
pool.sort((a, b) => Math.abs(a) - Math.abs(b));
|
|
7400
|
+
return pool[0];
|
|
7401
|
+
}
|
|
7402
|
+
function bisect(probe, targetLine, variable, target, maxIterations) {
|
|
7403
|
+
const sample = (candidate) => {
|
|
7404
|
+
const result = probe(targetLine, variable, chunk2TZKENDH_cjs.numberValue(candidate), false);
|
|
7405
|
+
if (result.type === 13 /* Error */) return { error: result };
|
|
7406
|
+
if (result.type !== 0 /* Number */ && result.type !== 6 /* Uom */) {
|
|
7407
|
+
return { error: chunk2TZKENDH_cjs.errorValue("GOAL_SEEK_TARGET_NOT_NUMERIC", `Line ${targetLine} did not produce a number when ${variable} was set to ${candidate}, so goal seek cannot compare it to the target.`) };
|
|
7408
|
+
}
|
|
7409
|
+
const numeric = result.toNumber();
|
|
7410
|
+
if (!Number.isFinite(numeric)) return { error: chunk2TZKENDH_cjs.errorValue("GOAL_SEEK_NON_FINITE", `Line ${targetLine}'s result is not finite when ${variable} is ${candidate}.`) };
|
|
7411
|
+
return { value: numeric };
|
|
7412
|
+
};
|
|
7413
|
+
let lo = SEARCH_LOWER_BOUND;
|
|
7414
|
+
let hi = SEARCH_UPPER_BOUND;
|
|
7415
|
+
const loSample = sample(lo);
|
|
7416
|
+
if ("error" in loSample) return loSample.error;
|
|
7417
|
+
const hiSample = sample(hi);
|
|
7418
|
+
if ("error" in hiSample) return hiSample.error;
|
|
7419
|
+
const tolerance = Math.max(ABSOLUTE_VALUE_TOLERANCE, Math.abs(target) * RELATIVE_VALUE_TOLERANCE);
|
|
7420
|
+
let flo = loSample.value - target;
|
|
7421
|
+
const fhi = hiSample.value - target;
|
|
7422
|
+
if (Math.abs(flo) <= tolerance) return chunk2TZKENDH_cjs.numberValue(lo);
|
|
7423
|
+
if (Math.abs(fhi) <= tolerance) return chunk2TZKENDH_cjs.numberValue(hi);
|
|
7424
|
+
if (Math.sign(flo) === Math.sign(fhi)) {
|
|
7425
|
+
return chunk2TZKENDH_cjs.errorValue(
|
|
7426
|
+
"GOAL_SEEK_NO_SOLUTION",
|
|
7427
|
+
`No value of ${variable} between ${lo} and ${hi} makes line ${targetLine} equal ${target}: across that whole range its result stays on one side of the target.`
|
|
7428
|
+
);
|
|
7429
|
+
}
|
|
7430
|
+
for (let step = 0; step < maxIterations; step++) {
|
|
7431
|
+
const mid = (lo + hi) / 2;
|
|
7432
|
+
const midSample = sample(mid);
|
|
7433
|
+
if ("error" in midSample) return midSample.error;
|
|
7434
|
+
const fmid = midSample.value - target;
|
|
7435
|
+
if (Math.abs(fmid) <= tolerance) return chunk2TZKENDH_cjs.numberValue(mid);
|
|
7436
|
+
if (hi - lo <= INTERVAL_COLLAPSE_WIDTH) {
|
|
7437
|
+
return chunk2TZKENDH_cjs.errorValue(
|
|
7438
|
+
"GOAL_SEEK_DID_NOT_CONVERGE",
|
|
7439
|
+
`Goal seek narrowed ${variable} to a single point near ${mid} without line ${targetLine} reaching ${target}: the relationship jumps across the target rather than passing through it.`
|
|
7440
|
+
);
|
|
7441
|
+
}
|
|
7442
|
+
if (Math.sign(fmid) === Math.sign(flo)) {
|
|
7443
|
+
lo = mid;
|
|
7444
|
+
flo = fmid;
|
|
7445
|
+
} else {
|
|
7446
|
+
hi = mid;
|
|
7447
|
+
}
|
|
7448
|
+
}
|
|
7449
|
+
return chunk2TZKENDH_cjs.errorValue(
|
|
7450
|
+
"GOAL_SEEK_DID_NOT_CONVERGE",
|
|
7451
|
+
`Goal seek did not bring line ${targetLine} within tolerance of ${target} by varying ${variable} in ${maxIterations} steps.`
|
|
7452
|
+
);
|
|
7453
|
+
}
|
|
7454
|
+
|
|
7455
|
+
// src/packages/goalseek/parselets/GoalSeekParselet.ts
|
|
7456
|
+
var GoalSeekParselet = class {
|
|
7457
|
+
constructor() {
|
|
7458
|
+
this.category = "GoalSeek";
|
|
7459
|
+
}
|
|
7460
|
+
parse(parser, _token, builder) {
|
|
7461
|
+
const lineRef = parser.peek();
|
|
7462
|
+
if (!lineRef || lineRef.type !== "LINE_REF") {
|
|
7463
|
+
throw chunkB4HBEFTB_cjs.ErrorFactory.parsing(
|
|
7464
|
+
"GOAL_SEEK_SYNTAX",
|
|
7465
|
+
`Goal seek reads "solve line N for <var> = <target>", for example "solve line 4 for rate = 900".`,
|
|
7466
|
+
{ found: lineRef?.type ?? "end of input" }
|
|
7467
|
+
);
|
|
7468
|
+
}
|
|
7469
|
+
parser.consume();
|
|
7470
|
+
const targetLine = parseInt(lineRef.value, 10);
|
|
7471
|
+
const connective = parser.peek();
|
|
7472
|
+
const isFor = !!connective && (connective.type === "FOR_DURATION" || connective.type === "IDENT" && connective.value.toLowerCase() === "for");
|
|
7473
|
+
if (!isFor) {
|
|
7474
|
+
throw chunkB4HBEFTB_cjs.ErrorFactory.parsing(
|
|
7475
|
+
"GOAL_SEEK_SYNTAX",
|
|
7476
|
+
`Goal seek reads "solve line N for <var> = <target>". Expected "for" after the line reference.`,
|
|
7477
|
+
{ found: connective?.type ?? "end of input" }
|
|
7478
|
+
);
|
|
7479
|
+
}
|
|
7480
|
+
parser.consume();
|
|
7481
|
+
const variable = parser.peek();
|
|
7482
|
+
if (!variable || variable.type !== "IDENT" && variable.type !== "UNIT") {
|
|
7483
|
+
throw chunkB4HBEFTB_cjs.ErrorFactory.parsing(
|
|
7484
|
+
"GOAL_SEEK_REQUIRES_VARIABLE_NAME",
|
|
7485
|
+
`Goal seek needs the name of the variable to vary here, as in "solve line 4 for rate = 900".`,
|
|
7486
|
+
{ found: variable?.type ?? "end of input" }
|
|
7487
|
+
);
|
|
7488
|
+
}
|
|
7489
|
+
parser.consume();
|
|
7490
|
+
parser.consume("EQUALS");
|
|
7491
|
+
builder.emitOpcode(10 /* PUSH_NUMBER */);
|
|
7492
|
+
builder.emitNumber(targetLine);
|
|
7493
|
+
builder.emitOpcode(13 /* PUSH_STRING */);
|
|
7494
|
+
builder.emitString(variable.value);
|
|
7495
|
+
parser.parseExpression(chunkJ45BCEZ4_cjs.BindingPower.Lowest, builder);
|
|
7496
|
+
builder.emitOpcode(50 /* CALL_PLUGIN */);
|
|
7497
|
+
builder.emitIndex(GOAL_SEEK_FN_IDX);
|
|
7498
|
+
builder.emitIndex(3);
|
|
7499
|
+
}
|
|
7500
|
+
};
|
|
7501
|
+
|
|
7502
|
+
// src/packages/goalseek/normalizer/GoalSeekNormalizerRule.ts
|
|
7503
|
+
var GOAL_SEEK_TYPE_ID = chunkQFTDTX6K_cjs.tokenTypeId("GOAL_SEEK");
|
|
7504
|
+
function goalSeekNormalizerRule(priority = 75) {
|
|
7505
|
+
return {
|
|
7506
|
+
name: "goalseek:solve-line",
|
|
7507
|
+
priority,
|
|
7508
|
+
match(tokens, pos) {
|
|
7509
|
+
if (pos > 0 && tokens[pos - 1].type === "COLON") return null;
|
|
7510
|
+
const token = tokens[pos];
|
|
7511
|
+
if (!token || token.type !== "IDENT" || token.value.toLowerCase() !== "solve") return null;
|
|
7512
|
+
if (tokens[pos + 1]?.type !== "LINE_REF") return null;
|
|
7513
|
+
return {
|
|
7514
|
+
consumed: 1,
|
|
7515
|
+
replacement: [
|
|
7516
|
+
new chunkYTIYVHL7_cjs.LexerToken("GOAL_SEEK", GOAL_SEEK_TYPE_ID, token.value, token.value, token.offset, 0, token.line, token.col)
|
|
7517
|
+
],
|
|
7518
|
+
ruleName: "goalseek:solve-line"
|
|
7519
|
+
};
|
|
7520
|
+
}
|
|
7521
|
+
};
|
|
7522
|
+
}
|
|
7523
|
+
|
|
7524
|
+
// src/packages/goalseek/GoalSeekPackage.ts
|
|
7525
|
+
var GOALSEEK_PACKAGE = {
|
|
7526
|
+
name: "solve-goalseek",
|
|
7527
|
+
normalizerRules: [goalSeekNormalizerRule()],
|
|
7528
|
+
prefixParselets: [{ tokenType: "GOAL_SEEK", parselet: new GoalSeekParselet() }],
|
|
7529
|
+
pluginFunctions: [{ index: GOAL_SEEK_FN_IDX, handler: goalSeekHandler }]
|
|
7530
|
+
// GOAL_SEEK's highlight category lives in the static TokenCategoryMap
|
|
7531
|
+
// alongside every other token declared in Token.ts's TokenTypes (the same
|
|
7532
|
+
// place the lines package's LINE_REF etc. are categorized), so it is not
|
|
7533
|
+
// repeated here.
|
|
7534
|
+
};
|
|
7535
|
+
|
|
7536
|
+
// src/packages/colour/ColourPluginFunctions.ts
|
|
7537
|
+
var ColourErrorCodes = {
|
|
7538
|
+
/** A string was not a hex colour or a known CSS colour name. */
|
|
7539
|
+
COLOUR_INVALID: "COLOUR_INVALID",
|
|
7540
|
+
/** A function expected a colour argument and got something else. */
|
|
7541
|
+
COLOUR_EXPECTED_COLOUR: "COLOUR_EXPECTED_COLOUR",
|
|
7542
|
+
/** A function was called with the wrong number or type of arguments. */
|
|
7543
|
+
COLOUR_BAD_ARGUMENTS: "COLOUR_BAD_ARGUMENTS"
|
|
7544
|
+
};
|
|
7545
|
+
function colourOf(v) {
|
|
7546
|
+
return v && v.type === 14 /* Colour */ ? v.value : null;
|
|
7547
|
+
}
|
|
7548
|
+
function readAmount(v) {
|
|
7549
|
+
if (!v) return 0;
|
|
7550
|
+
const n = v.toNumber();
|
|
7551
|
+
if (v.type === 5 /* Percentage */) return n;
|
|
7552
|
+
return n > 1 ? n / 100 : n;
|
|
7553
|
+
}
|
|
7554
|
+
function badArgs(fn, expected) {
|
|
7555
|
+
return chunk2TZKENDH_cjs.errorValue(ColourErrorCodes.COLOUR_BAD_ARGUMENTS, `${fn}(...) expects ${expected}`);
|
|
7556
|
+
}
|
|
7557
|
+
function notAColour(fn) {
|
|
7558
|
+
return chunk2TZKENDH_cjs.errorValue(ColourErrorCodes.COLOUR_EXPECTED_COLOUR, `${fn}(...) expects a colour as its first argument`);
|
|
7559
|
+
}
|
|
7560
|
+
var COLOUR_PARSE_FN_IDX = chunk7ZX6B7SY_cjs.allocatePluginFunctionIndex();
|
|
7561
|
+
function colourParseHandler(args) {
|
|
7562
|
+
const arg = args[0];
|
|
7563
|
+
if (!arg || arg.type !== 3 /* String */ || typeof arg.value !== "string") {
|
|
7564
|
+
return badArgs("color", 'a string, e.g. color("#ff0000") or color("red")');
|
|
7565
|
+
}
|
|
7566
|
+
const parsed = chunkALYRJ72W_cjs.parseColour(arg.value);
|
|
7567
|
+
if (!parsed) {
|
|
7568
|
+
return chunk2TZKENDH_cjs.errorValue(
|
|
7569
|
+
ColourErrorCodes.COLOUR_INVALID,
|
|
7570
|
+
`"${arg.value}" is not a hex colour (#rgb, #rgba, #rrggbb, #rrggbbaa) or a CSS colour name`
|
|
7571
|
+
);
|
|
7572
|
+
}
|
|
7573
|
+
return chunk2TZKENDH_cjs.colourValue(parsed);
|
|
7574
|
+
}
|
|
7575
|
+
var COLOUR_RGB_FN_IDX = chunk7ZX6B7SY_cjs.allocatePluginFunctionIndex();
|
|
7576
|
+
function rgbHandler(args) {
|
|
7577
|
+
if (args.length !== 3) return badArgs("rgb", "three numbers: rgb(red, green, blue)");
|
|
7578
|
+
return chunk2TZKENDH_cjs.colourValue({
|
|
7579
|
+
r: chunkALYRJ72W_cjs.clamp255(args[0].toNumber()),
|
|
7580
|
+
g: chunkALYRJ72W_cjs.clamp255(args[1].toNumber()),
|
|
7581
|
+
b: chunkALYRJ72W_cjs.clamp255(args[2].toNumber()),
|
|
7582
|
+
a: 1,
|
|
7583
|
+
format: "rgb"
|
|
7584
|
+
});
|
|
7585
|
+
}
|
|
7586
|
+
var COLOUR_RGBA_FN_IDX = chunk7ZX6B7SY_cjs.allocatePluginFunctionIndex();
|
|
7587
|
+
function rgbaHandler(args) {
|
|
7588
|
+
if (args.length !== 4) return badArgs("rgba", "four numbers: rgba(red, green, blue, alpha)");
|
|
7589
|
+
return chunk2TZKENDH_cjs.colourValue({
|
|
7590
|
+
r: chunkALYRJ72W_cjs.clamp255(args[0].toNumber()),
|
|
7591
|
+
g: chunkALYRJ72W_cjs.clamp255(args[1].toNumber()),
|
|
7592
|
+
b: chunkALYRJ72W_cjs.clamp255(args[2].toNumber()),
|
|
7593
|
+
a: chunkALYRJ72W_cjs.clamp01(readAmount(args[3])),
|
|
7594
|
+
format: "rgba"
|
|
7595
|
+
});
|
|
7596
|
+
}
|
|
7597
|
+
var COLOUR_HSL_FN_IDX = chunk7ZX6B7SY_cjs.allocatePluginFunctionIndex();
|
|
7598
|
+
function hslHandler(args) {
|
|
7599
|
+
if (args.length !== 3) return badArgs("hsl", "three values: hsl(hue, saturation%, lightness%)");
|
|
7600
|
+
const { r, g, b } = chunkALYRJ72W_cjs.hslToRgb(args[0].toNumber(), readAmount(args[1]), readAmount(args[2]));
|
|
7601
|
+
return chunk2TZKENDH_cjs.colourValue({ r, g, b, a: 1, format: "hsl" });
|
|
7602
|
+
}
|
|
7603
|
+
var COLOUR_HSLA_FN_IDX = chunk7ZX6B7SY_cjs.allocatePluginFunctionIndex();
|
|
7604
|
+
function hslaHandler(args) {
|
|
7605
|
+
if (args.length !== 4) return badArgs("hsla", "four values: hsla(hue, saturation%, lightness%, alpha)");
|
|
7606
|
+
const { r, g, b } = chunkALYRJ72W_cjs.hslToRgb(args[0].toNumber(), readAmount(args[1]), readAmount(args[2]));
|
|
7607
|
+
return chunk2TZKENDH_cjs.colourValue({ r, g, b, a: chunkALYRJ72W_cjs.clamp01(readAmount(args[3])), format: "hsla" });
|
|
7608
|
+
}
|
|
7609
|
+
function adjuster(name, op) {
|
|
7610
|
+
return (args) => {
|
|
7611
|
+
const c = colourOf(args[0]);
|
|
7612
|
+
if (!c) return notAColour(name);
|
|
7613
|
+
if (args.length < 2) return badArgs(name, `a colour and an amount, e.g. ${name}(#3366cc, 20%)`);
|
|
7614
|
+
return chunk2TZKENDH_cjs.colourValue(op(c, readAmount(args[1])));
|
|
7615
|
+
};
|
|
7616
|
+
}
|
|
7617
|
+
var COLOUR_LIGHTEN_FN_IDX = chunk7ZX6B7SY_cjs.allocatePluginFunctionIndex();
|
|
7618
|
+
var lightenHandler = adjuster("lighten", chunkALYRJ72W_cjs.lighten);
|
|
7619
|
+
var COLOUR_DARKEN_FN_IDX = chunk7ZX6B7SY_cjs.allocatePluginFunctionIndex();
|
|
7620
|
+
var darkenHandler = adjuster("darken", chunkALYRJ72W_cjs.darken);
|
|
7621
|
+
var COLOUR_SATURATE_FN_IDX = chunk7ZX6B7SY_cjs.allocatePluginFunctionIndex();
|
|
7622
|
+
var saturateHandler = adjuster("saturate", chunkALYRJ72W_cjs.saturate);
|
|
7623
|
+
var COLOUR_DESATURATE_FN_IDX = chunk7ZX6B7SY_cjs.allocatePluginFunctionIndex();
|
|
7624
|
+
var desaturateHandler = adjuster("desaturate", chunkALYRJ72W_cjs.desaturate);
|
|
7625
|
+
var COLOUR_ROTATE_FN_IDX = chunk7ZX6B7SY_cjs.allocatePluginFunctionIndex();
|
|
7626
|
+
function rotateHandler(args) {
|
|
7627
|
+
const c = colourOf(args[0]);
|
|
7628
|
+
if (!c) return notAColour("rotate");
|
|
7629
|
+
if (args.length < 2) return badArgs("rotate", "a colour and a hue angle in degrees, e.g. rotate(#ff0000, 90)");
|
|
7630
|
+
return chunk2TZKENDH_cjs.colourValue(chunkALYRJ72W_cjs.rotateHue(c, args[1].toNumber()));
|
|
7631
|
+
}
|
|
7632
|
+
var COLOUR_COMPLEMENT_FN_IDX = chunk7ZX6B7SY_cjs.allocatePluginFunctionIndex();
|
|
7633
|
+
function complementHandler(args) {
|
|
7634
|
+
const c = colourOf(args[0]);
|
|
7635
|
+
if (!c) return notAColour("complement");
|
|
7636
|
+
return chunk2TZKENDH_cjs.colourValue(chunkALYRJ72W_cjs.complement(c));
|
|
7637
|
+
}
|
|
7638
|
+
var COLOUR_GRAYSCALE_FN_IDX = chunk7ZX6B7SY_cjs.allocatePluginFunctionIndex();
|
|
7639
|
+
function grayscaleHandler(args) {
|
|
7640
|
+
const c = colourOf(args[0]);
|
|
7641
|
+
if (!c) return notAColour("grayscale");
|
|
7642
|
+
return chunk2TZKENDH_cjs.colourValue(chunkALYRJ72W_cjs.grayscale(c));
|
|
7643
|
+
}
|
|
7644
|
+
var COLOUR_INVERT_FN_IDX = chunk7ZX6B7SY_cjs.allocatePluginFunctionIndex();
|
|
7645
|
+
function invertHandler(args) {
|
|
7646
|
+
const c = colourOf(args[0]);
|
|
7647
|
+
if (!c) return notAColour("invert");
|
|
7648
|
+
return chunk2TZKENDH_cjs.colourValue(chunkALYRJ72W_cjs.invert(c, args.length > 1 ? readAmount(args[1]) : 1));
|
|
7649
|
+
}
|
|
7650
|
+
var COLOUR_MIX_FN_IDX = chunk7ZX6B7SY_cjs.allocatePluginFunctionIndex();
|
|
7651
|
+
function mixHandler(args) {
|
|
7652
|
+
const a = colourOf(args[0]);
|
|
7653
|
+
const b = colourOf(args[1]);
|
|
7654
|
+
if (!a || !b) return chunk2TZKENDH_cjs.errorValue(ColourErrorCodes.COLOUR_EXPECTED_COLOUR, "mix(...) expects two colours to blend");
|
|
7655
|
+
return chunk2TZKENDH_cjs.colourValue(chunkALYRJ72W_cjs.mix(a, b, args.length > 2 ? readAmount(args[2]) : 0.5));
|
|
7656
|
+
}
|
|
7657
|
+
var COLOUR_ALPHA_FN_IDX = chunk7ZX6B7SY_cjs.allocatePluginFunctionIndex();
|
|
7658
|
+
function alphaHandler(args) {
|
|
7659
|
+
const c = colourOf(args[0]);
|
|
7660
|
+
if (!c) return notAColour("alpha");
|
|
7661
|
+
if (args.length < 2) return chunk2TZKENDH_cjs.numberValue(c.a);
|
|
7662
|
+
return chunk2TZKENDH_cjs.colourValue(chunkALYRJ72W_cjs.withAlpha(c, readAmount(args[1])));
|
|
7663
|
+
}
|
|
7664
|
+
var COLOUR_CONTRAST_FN_IDX = chunk7ZX6B7SY_cjs.allocatePluginFunctionIndex();
|
|
7665
|
+
function contrastHandler(args) {
|
|
7666
|
+
const a = colourOf(args[0]);
|
|
7667
|
+
const b = colourOf(args[1]);
|
|
7668
|
+
if (!a || !b) return chunk2TZKENDH_cjs.errorValue(ColourErrorCodes.COLOUR_EXPECTED_COLOUR, "contrast(...) expects two colours");
|
|
7669
|
+
return chunk2TZKENDH_cjs.numberValue(chunkALYRJ72W_cjs.contrastRatio(a, b));
|
|
7670
|
+
}
|
|
7671
|
+
var COLOUR_LUMINANCE_FN_IDX = chunk7ZX6B7SY_cjs.allocatePluginFunctionIndex();
|
|
7672
|
+
function luminanceHandler(args) {
|
|
7673
|
+
const c = colourOf(args[0]);
|
|
7674
|
+
if (!c) return notAColour("luminance");
|
|
7675
|
+
return chunk2TZKENDH_cjs.numberValue(chunkALYRJ72W_cjs.relativeLuminance(c));
|
|
7676
|
+
}
|
|
7677
|
+
function extractor(name, get) {
|
|
7678
|
+
return (args) => {
|
|
7679
|
+
const c = colourOf(args[0]);
|
|
7680
|
+
if (!c) return notAColour(name);
|
|
7681
|
+
return chunk2TZKENDH_cjs.numberValue(get(c));
|
|
7682
|
+
};
|
|
7683
|
+
}
|
|
7684
|
+
var COLOUR_RED_FN_IDX = chunk7ZX6B7SY_cjs.allocatePluginFunctionIndex();
|
|
7685
|
+
var redHandler = extractor("red", (c) => c.r);
|
|
7686
|
+
var COLOUR_GREEN_FN_IDX = chunk7ZX6B7SY_cjs.allocatePluginFunctionIndex();
|
|
7687
|
+
var greenHandler = extractor("green", (c) => c.g);
|
|
7688
|
+
var COLOUR_BLUE_FN_IDX = chunk7ZX6B7SY_cjs.allocatePluginFunctionIndex();
|
|
7689
|
+
var blueHandler = extractor("blue", (c) => c.b);
|
|
7690
|
+
var COLOUR_HUE_FN_IDX = chunk7ZX6B7SY_cjs.allocatePluginFunctionIndex();
|
|
7691
|
+
var hueHandler = extractor("hue", (c) => chunkALYRJ72W_cjs.rgbToHsl(c.r, c.g, c.b).h);
|
|
7692
|
+
var COLOUR_SATURATION_FN_IDX = chunk7ZX6B7SY_cjs.allocatePluginFunctionIndex();
|
|
7693
|
+
var saturationHandler = extractor("saturation", (c) => chunkALYRJ72W_cjs.rgbToHsl(c.r, c.g, c.b).s * 100);
|
|
7694
|
+
var COLOUR_LIGHTNESS_FN_IDX = chunk7ZX6B7SY_cjs.allocatePluginFunctionIndex();
|
|
7695
|
+
var lightnessHandler = extractor("lightness", (c) => chunkALYRJ72W_cjs.rgbToHsl(c.r, c.g, c.b).l * 100);
|
|
7696
|
+
var COLOUR_HSV_FN_IDX = chunk7ZX6B7SY_cjs.allocatePluginFunctionIndex();
|
|
7697
|
+
function hsvHandler(args) {
|
|
7698
|
+
if (args.length !== 3) return badArgs("hsv", "three values: hsv(hue, saturation%, value%)");
|
|
7699
|
+
const { r, g, b } = chunkALYRJ72W_cjs.hsvToRgb(args[0].toNumber(), readAmount(args[1]), readAmount(args[2]));
|
|
7700
|
+
return chunk2TZKENDH_cjs.colourValue({ r, g, b, a: 1, format: "hex" });
|
|
7701
|
+
}
|
|
7702
|
+
var COLOUR_HSVA_FN_IDX = chunk7ZX6B7SY_cjs.allocatePluginFunctionIndex();
|
|
7703
|
+
function hsvaHandler(args) {
|
|
7704
|
+
if (args.length !== 4) return badArgs("hsva", "four values: hsva(hue, saturation%, value%, alpha)");
|
|
7705
|
+
const { r, g, b } = chunkALYRJ72W_cjs.hsvToRgb(args[0].toNumber(), readAmount(args[1]), readAmount(args[2]));
|
|
7706
|
+
return chunk2TZKENDH_cjs.colourValue({ r, g, b, a: chunkALYRJ72W_cjs.clamp01(readAmount(args[3])), format: "hex" });
|
|
7707
|
+
}
|
|
7708
|
+
var COLOUR_HWB_FN_IDX = chunk7ZX6B7SY_cjs.allocatePluginFunctionIndex();
|
|
7709
|
+
function hwbHandler(args) {
|
|
7710
|
+
if (args.length !== 3) return badArgs("hwb", "three values: hwb(hue, whiteness%, blackness%)");
|
|
7711
|
+
const { r, g, b } = chunkALYRJ72W_cjs.hwbToRgb(args[0].toNumber(), readAmount(args[1]), readAmount(args[2]));
|
|
7712
|
+
return chunk2TZKENDH_cjs.colourValue({ r, g, b, a: 1, format: "hex" });
|
|
7713
|
+
}
|
|
7714
|
+
var COLOUR_TINT_FN_IDX = chunk7ZX6B7SY_cjs.allocatePluginFunctionIndex();
|
|
7715
|
+
var tintHandler = adjuster("tint", chunkALYRJ72W_cjs.tint);
|
|
7716
|
+
var COLOUR_SHADE_FN_IDX = chunk7ZX6B7SY_cjs.allocatePluginFunctionIndex();
|
|
7717
|
+
var shadeHandler = adjuster("shade", chunkALYRJ72W_cjs.shade);
|
|
7718
|
+
var COLOUR_TONE_FN_IDX = chunk7ZX6B7SY_cjs.allocatePluginFunctionIndex();
|
|
7719
|
+
var toneHandler = adjuster("tone", chunkALYRJ72W_cjs.tone);
|
|
7720
|
+
var COLOUR_ISDARK_FN_IDX = chunk7ZX6B7SY_cjs.allocatePluginFunctionIndex();
|
|
7721
|
+
function isdarkHandler(args) {
|
|
7722
|
+
const c = colourOf(args[0]);
|
|
7723
|
+
if (!c) return notAColour("isdark");
|
|
7724
|
+
return chunk2TZKENDH_cjs.boolValue(chunkALYRJ72W_cjs.isDark(c));
|
|
7725
|
+
}
|
|
7726
|
+
var COLOUR_ISLIGHT_FN_IDX = chunk7ZX6B7SY_cjs.allocatePluginFunctionIndex();
|
|
7727
|
+
function islightHandler(args) {
|
|
7728
|
+
const c = colourOf(args[0]);
|
|
7729
|
+
if (!c) return notAColour("islight");
|
|
7730
|
+
return chunk2TZKENDH_cjs.boolValue(!chunkALYRJ72W_cjs.isDark(c));
|
|
7731
|
+
}
|
|
7732
|
+
var COLOUR_READABLE_FN_IDX = chunk7ZX6B7SY_cjs.allocatePluginFunctionIndex();
|
|
7733
|
+
function readableHandler(args) {
|
|
7734
|
+
const c = colourOf(args[0]);
|
|
7735
|
+
if (!c) return notAColour("readable");
|
|
7736
|
+
return chunk2TZKENDH_cjs.colourValue(chunkALYRJ72W_cjs.readableColour(c));
|
|
7737
|
+
}
|
|
7738
|
+
function readWcagThreshold(v) {
|
|
7739
|
+
if (!v) return chunkALYRJ72W_cjs.WCAG_THRESHOLDS.aa;
|
|
7740
|
+
if (v.type === 0 /* Number */) return v.toNumber();
|
|
7741
|
+
if (v.type === 3 /* String */) {
|
|
7742
|
+
const key = v.value.trim().toLowerCase();
|
|
7743
|
+
if (key === "aaa") return chunkALYRJ72W_cjs.WCAG_THRESHOLDS.aaa;
|
|
7744
|
+
if (key === "aa large" || key === "aa-large" || key === "large") return chunkALYRJ72W_cjs.WCAG_THRESHOLDS.aaLarge;
|
|
7745
|
+
if (key === "aaa large" || key === "aaa-large") return chunkALYRJ72W_cjs.WCAG_THRESHOLDS.aaaLarge;
|
|
7746
|
+
}
|
|
7747
|
+
return chunkALYRJ72W_cjs.WCAG_THRESHOLDS.aa;
|
|
7748
|
+
}
|
|
7749
|
+
var COLOUR_CONTRAST_COMPLIANT_FN_IDX = chunk7ZX6B7SY_cjs.allocatePluginFunctionIndex();
|
|
7750
|
+
function contrastCompliantHandler(args) {
|
|
7751
|
+
const a = colourOf(args[0]);
|
|
7752
|
+
const b = colourOf(args[1]);
|
|
7753
|
+
if (!a || !b) {
|
|
7754
|
+
return chunk2TZKENDH_cjs.errorValue(ColourErrorCodes.COLOUR_EXPECTED_COLOUR, "iscontrastcompliant(...) expects two colours");
|
|
7755
|
+
}
|
|
7756
|
+
return chunk2TZKENDH_cjs.boolValue(chunkALYRJ72W_cjs.contrastRatio(a, b) >= readWcagThreshold(args[2]));
|
|
7757
|
+
}
|
|
7758
|
+
var COLOUR_WCAG_LEVEL_FN_IDX = chunk7ZX6B7SY_cjs.allocatePluginFunctionIndex();
|
|
7759
|
+
function wcagLevelHandler(args) {
|
|
7760
|
+
const a = colourOf(args[0]);
|
|
7761
|
+
const b = colourOf(args[1]);
|
|
7762
|
+
if (!a || !b) return chunk2TZKENDH_cjs.errorValue(ColourErrorCodes.COLOUR_EXPECTED_COLOUR, "wcaglevel(...) expects two colours");
|
|
7763
|
+
return chunk2TZKENDH_cjs.stringValue(chunkALYRJ72W_cjs.wcagLevel(a, b));
|
|
7764
|
+
}
|
|
7765
|
+
var COLOUR_FUNCTION_INDEX = {
|
|
7766
|
+
color: COLOUR_PARSE_FN_IDX,
|
|
7767
|
+
colour: COLOUR_PARSE_FN_IDX,
|
|
7768
|
+
rgb: COLOUR_RGB_FN_IDX,
|
|
7769
|
+
rgba: COLOUR_RGBA_FN_IDX,
|
|
7770
|
+
hsl: COLOUR_HSL_FN_IDX,
|
|
7771
|
+
hsla: COLOUR_HSLA_FN_IDX,
|
|
7772
|
+
lighten: COLOUR_LIGHTEN_FN_IDX,
|
|
7773
|
+
darken: COLOUR_DARKEN_FN_IDX,
|
|
7774
|
+
saturate: COLOUR_SATURATE_FN_IDX,
|
|
7775
|
+
desaturate: COLOUR_DESATURATE_FN_IDX,
|
|
7776
|
+
desat: COLOUR_DESATURATE_FN_IDX,
|
|
7777
|
+
rotate: COLOUR_ROTATE_FN_IDX,
|
|
7778
|
+
spin: COLOUR_ROTATE_FN_IDX,
|
|
7779
|
+
adjusthue: COLOUR_ROTATE_FN_IDX,
|
|
7780
|
+
complement: COLOUR_COMPLEMENT_FN_IDX,
|
|
7781
|
+
grayscale: COLOUR_GRAYSCALE_FN_IDX,
|
|
7782
|
+
greyscale: COLOUR_GRAYSCALE_FN_IDX,
|
|
7783
|
+
invert: COLOUR_INVERT_FN_IDX,
|
|
7784
|
+
mix: COLOUR_MIX_FN_IDX,
|
|
7785
|
+
alpha: COLOUR_ALPHA_FN_IDX,
|
|
7786
|
+
opacity: COLOUR_ALPHA_FN_IDX,
|
|
7787
|
+
fade: COLOUR_ALPHA_FN_IDX,
|
|
7788
|
+
contrast: COLOUR_CONTRAST_FN_IDX,
|
|
7789
|
+
luminance: COLOUR_LUMINANCE_FN_IDX,
|
|
7790
|
+
red: COLOUR_RED_FN_IDX,
|
|
7791
|
+
green: COLOUR_GREEN_FN_IDX,
|
|
7792
|
+
blue: COLOUR_BLUE_FN_IDX,
|
|
7793
|
+
hue: COLOUR_HUE_FN_IDX,
|
|
7794
|
+
saturation: COLOUR_SATURATION_FN_IDX,
|
|
7795
|
+
lightness: COLOUR_LIGHTNESS_FN_IDX,
|
|
7796
|
+
hsv: COLOUR_HSV_FN_IDX,
|
|
7797
|
+
hsb: COLOUR_HSV_FN_IDX,
|
|
7798
|
+
hsva: COLOUR_HSVA_FN_IDX,
|
|
7799
|
+
hwb: COLOUR_HWB_FN_IDX,
|
|
7800
|
+
tint: COLOUR_TINT_FN_IDX,
|
|
7801
|
+
shade: COLOUR_SHADE_FN_IDX,
|
|
7802
|
+
tone: COLOUR_TONE_FN_IDX,
|
|
7803
|
+
negate: COLOUR_INVERT_FN_IDX,
|
|
7804
|
+
isdark: COLOUR_ISDARK_FN_IDX,
|
|
7805
|
+
islight: COLOUR_ISLIGHT_FN_IDX,
|
|
7806
|
+
readable: COLOUR_READABLE_FN_IDX,
|
|
7807
|
+
contrastcolor: COLOUR_READABLE_FN_IDX,
|
|
7808
|
+
contrastcolour: COLOUR_READABLE_FN_IDX,
|
|
7809
|
+
iscontrastcompliant: COLOUR_CONTRAST_COMPLIANT_FN_IDX,
|
|
7810
|
+
wcaglevel: COLOUR_WCAG_LEVEL_FN_IDX,
|
|
7811
|
+
wcag: COLOUR_WCAG_LEVEL_FN_IDX
|
|
7812
|
+
};
|
|
7813
|
+
var COLOUR_PLUGIN_FUNCTIONS = [
|
|
7814
|
+
{ index: COLOUR_PARSE_FN_IDX, handler: colourParseHandler },
|
|
7815
|
+
{ index: COLOUR_RGB_FN_IDX, handler: rgbHandler },
|
|
7816
|
+
{ index: COLOUR_RGBA_FN_IDX, handler: rgbaHandler },
|
|
7817
|
+
{ index: COLOUR_HSL_FN_IDX, handler: hslHandler },
|
|
7818
|
+
{ index: COLOUR_HSLA_FN_IDX, handler: hslaHandler },
|
|
7819
|
+
{ index: COLOUR_LIGHTEN_FN_IDX, handler: lightenHandler },
|
|
7820
|
+
{ index: COLOUR_DARKEN_FN_IDX, handler: darkenHandler },
|
|
7821
|
+
{ index: COLOUR_SATURATE_FN_IDX, handler: saturateHandler },
|
|
7822
|
+
{ index: COLOUR_DESATURATE_FN_IDX, handler: desaturateHandler },
|
|
7823
|
+
{ index: COLOUR_ROTATE_FN_IDX, handler: rotateHandler },
|
|
7824
|
+
{ index: COLOUR_COMPLEMENT_FN_IDX, handler: complementHandler },
|
|
7825
|
+
{ index: COLOUR_GRAYSCALE_FN_IDX, handler: grayscaleHandler },
|
|
7826
|
+
{ index: COLOUR_INVERT_FN_IDX, handler: invertHandler },
|
|
7827
|
+
{ index: COLOUR_MIX_FN_IDX, handler: mixHandler },
|
|
7828
|
+
{ index: COLOUR_ALPHA_FN_IDX, handler: alphaHandler },
|
|
7829
|
+
{ index: COLOUR_CONTRAST_FN_IDX, handler: contrastHandler },
|
|
7830
|
+
{ index: COLOUR_LUMINANCE_FN_IDX, handler: luminanceHandler },
|
|
7831
|
+
{ index: COLOUR_RED_FN_IDX, handler: redHandler },
|
|
7832
|
+
{ index: COLOUR_GREEN_FN_IDX, handler: greenHandler },
|
|
7833
|
+
{ index: COLOUR_BLUE_FN_IDX, handler: blueHandler },
|
|
7834
|
+
{ index: COLOUR_HUE_FN_IDX, handler: hueHandler },
|
|
7835
|
+
{ index: COLOUR_SATURATION_FN_IDX, handler: saturationHandler },
|
|
7836
|
+
{ index: COLOUR_LIGHTNESS_FN_IDX, handler: lightnessHandler },
|
|
7837
|
+
{ index: COLOUR_HSV_FN_IDX, handler: hsvHandler },
|
|
7838
|
+
{ index: COLOUR_HSVA_FN_IDX, handler: hsvaHandler },
|
|
7839
|
+
{ index: COLOUR_HWB_FN_IDX, handler: hwbHandler },
|
|
7840
|
+
{ index: COLOUR_TINT_FN_IDX, handler: tintHandler },
|
|
7841
|
+
{ index: COLOUR_SHADE_FN_IDX, handler: shadeHandler },
|
|
7842
|
+
{ index: COLOUR_TONE_FN_IDX, handler: toneHandler },
|
|
7843
|
+
{ index: COLOUR_ISDARK_FN_IDX, handler: isdarkHandler },
|
|
7844
|
+
{ index: COLOUR_ISLIGHT_FN_IDX, handler: islightHandler },
|
|
7845
|
+
{ index: COLOUR_READABLE_FN_IDX, handler: readableHandler },
|
|
7846
|
+
{ index: COLOUR_CONTRAST_COMPLIANT_FN_IDX, handler: contrastCompliantHandler },
|
|
7847
|
+
{ index: COLOUR_WCAG_LEVEL_FN_IDX, handler: wcagLevelHandler }
|
|
7848
|
+
];
|
|
7849
|
+
|
|
7850
|
+
// src/packages/colour/parselets/HexColourParselet.ts
|
|
7851
|
+
var HexColourParselet = class {
|
|
7852
|
+
constructor() {
|
|
7853
|
+
this.category = "Colour";
|
|
7854
|
+
}
|
|
7855
|
+
parse(_parser, token, builder) {
|
|
7856
|
+
builder.emitOpcode(13 /* PUSH_STRING */);
|
|
7857
|
+
builder.emitString(token.value);
|
|
7858
|
+
builder.emitOpcode(50 /* CALL_PLUGIN */);
|
|
7859
|
+
builder.emitIndex(COLOUR_PARSE_FN_IDX);
|
|
7860
|
+
builder.emitIndex(1);
|
|
7861
|
+
}
|
|
7862
|
+
};
|
|
7863
|
+
|
|
7864
|
+
// src/packages/colour/parselets/ColourCallParselet.ts
|
|
7865
|
+
var ColourCallParselet = class {
|
|
7866
|
+
constructor() {
|
|
7867
|
+
this.category = "Colour";
|
|
7868
|
+
}
|
|
7869
|
+
parse(parser, token, builder) {
|
|
7870
|
+
const name = token.value.toLowerCase();
|
|
7871
|
+
const fnIdx = COLOUR_FUNCTION_INDEX[name];
|
|
7872
|
+
if (fnIdx === void 0) {
|
|
7873
|
+
throw chunkB4HBEFTB_cjs.ErrorFactory.execution("UNKNOWN_COLOUR_FUNCTION", `Unknown colour function: ${name}`, {
|
|
7874
|
+
functionName: name
|
|
7875
|
+
});
|
|
7876
|
+
}
|
|
7877
|
+
parser.consume("LPAREN");
|
|
7878
|
+
let argCount = 0;
|
|
7879
|
+
if (parser.peek()?.type !== "RPAREN") {
|
|
7880
|
+
parser.parseExpression(chunkJ45BCEZ4_cjs.BindingPower.Lowest, builder);
|
|
7881
|
+
argCount++;
|
|
7882
|
+
while (parser.match("COMMA")) {
|
|
7883
|
+
parser.parseExpression(chunkJ45BCEZ4_cjs.BindingPower.Lowest, builder);
|
|
7884
|
+
argCount++;
|
|
7885
|
+
}
|
|
7886
|
+
}
|
|
7887
|
+
parser.consume("RPAREN");
|
|
7888
|
+
builder.emitOpcode(50 /* CALL_PLUGIN */);
|
|
7889
|
+
builder.emitIndex(fnIdx);
|
|
7890
|
+
builder.emitIndex(argCount);
|
|
7891
|
+
}
|
|
7892
|
+
};
|
|
7893
|
+
|
|
7894
|
+
// src/packages/colour/normalizer/ColourCallNormalizerRule.ts
|
|
7895
|
+
function colourCallNormalizerRule(priority = 80) {
|
|
7896
|
+
return {
|
|
7897
|
+
name: "colour:call",
|
|
7898
|
+
priority,
|
|
7899
|
+
match(tokens, pos) {
|
|
7900
|
+
const token = tokens[pos];
|
|
7901
|
+
if (!token || token.type !== "IDENT") return null;
|
|
7902
|
+
const word = token.value.toLowerCase();
|
|
7903
|
+
if (COLOUR_FUNCTION_INDEX[word] === void 0) return null;
|
|
7904
|
+
if (tokens[pos + 1]?.type !== "LPAREN") return null;
|
|
7905
|
+
return {
|
|
7906
|
+
consumed: 1,
|
|
7907
|
+
replacement: [
|
|
7908
|
+
new chunkYTIYVHL7_cjs.LexerToken(
|
|
7909
|
+
"COLOUR_CALL",
|
|
7910
|
+
chunkQFTDTX6K_cjs.tokenTypeId("COLOUR_CALL"),
|
|
7911
|
+
token.value,
|
|
7912
|
+
token.value,
|
|
7913
|
+
token.offset,
|
|
7914
|
+
0,
|
|
7915
|
+
token.line,
|
|
7916
|
+
token.col
|
|
7917
|
+
)
|
|
7918
|
+
],
|
|
7919
|
+
ruleName: "colour:call"
|
|
7920
|
+
};
|
|
7921
|
+
}
|
|
7922
|
+
};
|
|
7923
|
+
}
|
|
7924
|
+
|
|
7925
|
+
// src/packages/colour/ColourPackage.ts
|
|
7926
|
+
var retag = (format) => (v) => {
|
|
7927
|
+
if (v.type !== 14 /* Colour */) return v;
|
|
7928
|
+
const c = v.value;
|
|
7929
|
+
return chunk2TZKENDH_cjs.colourValue({ r: c.r, g: c.g, b: c.b, a: c.a, format });
|
|
7930
|
+
};
|
|
7931
|
+
var completionItems = Object.keys(COLOUR_FUNCTION_INDEX).map((label) => ({
|
|
7932
|
+
label,
|
|
7933
|
+
category: "function",
|
|
7934
|
+
detail: "colour"
|
|
7935
|
+
}));
|
|
7936
|
+
var COLOUR_PACKAGE = {
|
|
7937
|
+
name: "solve-colour",
|
|
7938
|
+
prefixParselets: [
|
|
7939
|
+
{ tokenType: "HEX_COLOUR", parselet: new HexColourParselet() },
|
|
7940
|
+
{ tokenType: "COLOUR_CALL", parselet: new ColourCallParselet() }
|
|
7941
|
+
],
|
|
7942
|
+
normalizerRules: [colourCallNormalizerRule()],
|
|
7943
|
+
pluginFunctions: COLOUR_PLUGIN_FUNCTIONS.map((f) => ({ index: f.index, handler: f.handler })),
|
|
7944
|
+
asConverters: {
|
|
7945
|
+
rgb: retag("rgb"),
|
|
7946
|
+
rgba: retag("rgba"),
|
|
7947
|
+
hsl: retag("hsl"),
|
|
7948
|
+
hsla: retag("hsla")
|
|
7949
|
+
},
|
|
7950
|
+
// HEX_COLOUR/COLOUR_CALL categories live in the core TokenCategoryMap (both
|
|
7951
|
+
// are declared TokenTypes), so no per-package tokenCategories are needed.
|
|
7952
|
+
completionItems
|
|
7953
|
+
};
|
|
7954
|
+
|
|
6488
7955
|
// src/packages/builtins.ts
|
|
6489
7956
|
var BUILTIN_PACKAGES = [
|
|
6490
7957
|
ARITHMETIC_PACKAGE,
|
|
@@ -6505,8 +7972,14 @@ var BUILTIN_PACKAGES = [
|
|
|
6505
7972
|
CONVERTERS_PACKAGE,
|
|
6506
7973
|
MATHPHRASES_PACKAGE,
|
|
6507
7974
|
FINANCE_PACKAGE,
|
|
7975
|
+
UNCERTAINTY_PACKAGE,
|
|
6508
7976
|
WEATHER_PACKAGE,
|
|
6509
|
-
LINES_PACKAGE
|
|
7977
|
+
LINES_PACKAGE,
|
|
7978
|
+
// After LINES_PACKAGE: goal seek's normalizer reads a LINE_REF the lines
|
|
7979
|
+
// rule mints, and its parselet targets a line reference.
|
|
7980
|
+
GOALSEEK_PACKAGE,
|
|
7981
|
+
TABLES_PACKAGE,
|
|
7982
|
+
COLOUR_PACKAGE
|
|
6510
7983
|
];
|
|
6511
7984
|
|
|
6512
7985
|
exports.ARITHMETIC_PACKAGE = ARITHMETIC_PACKAGE;
|
|
@@ -6525,13 +7998,15 @@ exports.MATHPHRASES_PACKAGE = MATHPHRASES_PACKAGE;
|
|
|
6525
7998
|
exports.MATRIX_PACKAGE = MATRIX_PACKAGE;
|
|
6526
7999
|
exports.PERCENTAGE_PACKAGE = PERCENTAGE_PACKAGE;
|
|
6527
8000
|
exports.SYMBOLIC_PACKAGE = SYMBOLIC_PACKAGE;
|
|
8001
|
+
exports.TABLES_PACKAGE = TABLES_PACKAGE;
|
|
6528
8002
|
exports.TIME_PACKAGE = TIME_PACKAGE;
|
|
6529
8003
|
exports.UOM_PACKAGE = UOM_PACKAGE;
|
|
6530
8004
|
exports.VARIABLES_PACKAGE = VARIABLES_PACKAGE;
|
|
6531
8005
|
exports.VECTOR_PACKAGE = VECTOR_PACKAGE;
|
|
6532
8006
|
exports.WEATHER_PACKAGE = WEATHER_PACKAGE;
|
|
6533
8007
|
exports.containsSymbolicCall = containsSymbolicCall;
|
|
8008
|
+
exports.createCurrencyPackage = createCurrencyPackage;
|
|
6534
8009
|
exports.createKnowledgePackage = createKnowledgePackage;
|
|
6535
8010
|
exports.createStocksPackage = createStocksPackage;
|
|
6536
|
-
//# sourceMappingURL=chunk-
|
|
6537
|
-
//# sourceMappingURL=chunk-
|
|
8011
|
+
//# sourceMappingURL=chunk-OTN6SZOD.cjs.map
|
|
8012
|
+
//# sourceMappingURL=chunk-OTN6SZOD.cjs.map
|