solve-engine 1.0.2 → 1.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{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-DpjdaQ98.d.cts → Lexer-BOs7euZe.d.cts} +28 -1
- package/dist/{Lexer-CNmWxabg.d.ts → Lexer-CSI_lwbW.d.ts} +28 -1
- package/dist/PackageCompatibility-B-7rK1TD.d.cts +76 -0
- package/dist/PackageCompatibility-Dh59eF-X.d.ts +76 -0
- package/dist/{PackageRegistry-zuzqt51V.d.cts → PackageRegistry-BHWJP83F.d.cts} +449 -11
- package/dist/{PackageRegistry-ClIFXxAe.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-YXCTLWOH.js → chunk-4HQKTMWG.js} +1530 -57
- package/dist/chunk-4HQKTMWG.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-IP7ASJEW.js → chunk-BYJBUL7U.js} +5 -5
- package/dist/{chunk-IP7ASJEW.js.map → chunk-BYJBUL7U.js.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-T556MJDZ.cjs → chunk-CUR2WLI4.cjs} +11 -11
- package/dist/{chunk-T556MJDZ.cjs.map → chunk-CUR2WLI4.cjs.map} +1 -1
- package/dist/{chunk-AA3KTWTX.js → chunk-DLEBSLF4.js} +4 -4
- package/dist/{chunk-AA3KTWTX.js.map → chunk-DLEBSLF4.js.map} +1 -1
- package/dist/{chunk-524F3ATQ.cjs → chunk-E23GZEWL.cjs} +15 -9
- package/dist/chunk-E23GZEWL.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-7FSDNNNC.js → chunk-GLA4JXBO.js} +11 -5
- package/dist/chunk-GLA4JXBO.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-FQGX2PA2.js → chunk-JG6ZJ2WU.js} +128 -4
- package/dist/chunk-JG6ZJ2WU.js.map +1 -0
- package/dist/chunk-L2TE7PMO.cjs +14 -0
- package/dist/chunk-L2TE7PMO.cjs.map +1 -0
- package/dist/chunk-LHZ6VOA7.js +1764 -0
- package/dist/chunk-LHZ6VOA7.js.map +1 -0
- package/dist/{chunk-SESSWASV.cjs → chunk-MN3LHRGV.cjs} +1868 -393
- package/dist/chunk-MN3LHRGV.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-FE23VSSA.cjs → chunk-N5NNW4VG.cjs} +6 -6
- package/dist/{chunk-FE23VSSA.cjs.map → chunk-N5NNW4VG.cjs.map} +1 -1
- 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-NG2JHZHE.js → chunk-NNZAEUDW.js} +1853 -2640
- package/dist/chunk-NNZAEUDW.js.map +1 -0
- package/dist/{chunk-5LI5EPGJ.cjs → chunk-QFTDTX6K.cjs} +40 -3
- package/dist/chunk-QFTDTX6K.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-HBVFFBRR.cjs → chunk-T6ZYQJ63.cjs} +1962 -2748
- package/dist/chunk-T6ZYQJ63.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-YRIKITGF.cjs +1768 -0
- package/dist/chunk-YRIKITGF.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-R7YVBHCV.cjs → chunk-ZMW6NU2K.cjs} +197 -73
- package/dist/chunk-ZMW6NU2K.cjs.map +1 -0
- package/dist/{chunk-A2N2GFCG.cjs → chunk-ZVTWQLK4.cjs} +10 -10
- package/dist/{chunk-A2N2GFCG.cjs.map → chunk-ZVTWQLK4.cjs.map} +1 -1
- 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-3D7V24DG.js.map +0 -1
- package/dist/chunk-3LAEG75D.js.map +0 -1
- package/dist/chunk-4B2CNWQU.cjs.map +0 -1
- package/dist/chunk-524F3ATQ.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-7FSDNNNC.js.map +0 -1
- package/dist/chunk-AJA6LUI7.js.map +0 -1
- package/dist/chunk-FQGX2PA2.js.map +0 -1
- package/dist/chunk-GQCOSXMG.js.map +0 -1
- package/dist/chunk-HBVFFBRR.cjs.map +0 -1
- package/dist/chunk-HDP7VK3C.cjs.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-NG2JHZHE.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-R3PY4G7J.js.map +0 -1
- package/dist/chunk-R7YVBHCV.cjs.map +0 -1
- package/dist/chunk-SESSWASV.cjs.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-VB37OC6I.js.map +0 -1
- package/dist/chunk-Y7FT4IQT.js.map +0 -1
- package/dist/chunk-YXCTLWOH.js.map +0 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/diagnostics/pipeline.ts","../src/diagnostics/collector.ts","../src/diagnostics/timeline-collector.ts","../src/diagnostics/events.ts"],"names":[],"mappings":";AAYO,IAAM,qBAAN,MAAyB;AAAA,EAAzB,WAAA,GAAA;AACL,IAAA,IAAA,CAAQ,aAAoC,EAAC;AAAA,EAAA;AAAA,EAE7C,SAAS,SAAA,EAAsC;AAC7C,IAAA,IAAA,CAAK,UAAA,CAAW,KAAK,SAAS,CAAA;AAAA,EAChC;AAAA,EAEA,WAAW,SAAA,EAAsC;AAC/C,IAAA,MAAM,GAAA,GAAM,IAAA,CAAK,UAAA,CAAW,OAAA,CAAQ,SAAS,CAAA;AAC7C,IAAA,IAAI,QAAQ,EAAA,EAAI,IAAA,CAAK,UAAA,CAAW,MAAA,CAAO,KAAK,CAAC,CAAA;AAAA,EAC/C;AAAA,EAEA,KAAA,GAAc;AACZ,IAAA,IAAA,CAAK,aAAa,EAAC;AAAA,EACrB;AAAA,EAEA,IAAI,aAAA,GAAyB;AAC3B,IAAA,OAAO,IAAA,CAAK,WAAW,MAAA,GAAS,CAAA;AAAA,EAClC;AAAA,EAEA,IAAI,cAAA,GAAyB;AAC3B,IAAA,OAAO,KAAK,UAAA,CAAW,MAAA;AAAA,EACzB;AAAA;AAAA;AAAA,EAKA,kBAAkB,KAAA,EAA2D;AAC3E,IAAA,IAAI,IAAA,CAAK,UAAA,CAAW,MAAA,KAAW,CAAA,EAAG;AAClC,IAAA,KAAA,MAAW,CAAA,IAAK,IAAA,CAAK,UAAA,EAAY,CAAA,CAAE,kBAAkB,KAAK,CAAA;AAAA,EAC5D;AAAA,EAEA,iBAAiB,KAAA,EAA0D;AACzE,IAAA,IAAI,IAAA,CAAK,UAAA,CAAW,MAAA,KAAW,CAAA,EAAG;AAClC,IAAA,KAAA,MAAW,CAAA,IAAK,IAAA,CAAK,UAAA,EAAY,CAAA,CAAE,iBAAiB,KAAK,CAAA;AAAA,EAC3D;AAAA,EAEA,oBAAoB,KAAA,EAA6D;AAC/E,IAAA,IAAI,IAAA,CAAK,UAAA,CAAW,MAAA,KAAW,CAAA,EAAG;AAClC,IAAA,KAAA,MAAW,CAAA,IAAK,IAAA,CAAK,UAAA,EAAY,CAAA,CAAE,oBAAoB,KAAK,CAAA;AAAA,EAC9D;AAAA,EAEA,eAAe,KAAA,EAAwD;AACrE,IAAA,IAAI,IAAA,CAAK,UAAA,CAAW,MAAA,KAAW,CAAA,EAAG;AAClC,IAAA,KAAA,MAAW,CAAA,IAAK,IAAA,CAAK,UAAA,EAAY,CAAA,CAAE,eAAe,KAAK,CAAA;AAAA,EACzD;AAAA,EAEA,kBAAkB,KAAA,EAA2D;AAC3E,IAAA,IAAI,IAAA,CAAK,UAAA,CAAW,MAAA,KAAW,CAAA,EAAG;AAClC,IAAA,KAAA,MAAW,CAAA,IAAK,IAAA,CAAK,UAAA,EAAY,CAAA,CAAE,kBAAkB,KAAK,CAAA;AAAA,EAC5D;AAAA,EAEA,oBAAoB,KAAA,EAA6D;AAC/E,IAAA,IAAI,IAAA,CAAK,UAAA,CAAW,MAAA,KAAW,CAAA,EAAG;AAClC,IAAA,KAAA,MAAW,CAAA,IAAK,IAAA,CAAK,UAAA,EAAY,CAAA,CAAE,oBAAoB,KAAK,CAAA;AAAA,EAC9D;AAAA,EAEA,kBAAkB,KAAA,EAA2D;AAC3E,IAAA,IAAI,IAAA,CAAK,UAAA,CAAW,MAAA,KAAW,CAAA,EAAG;AAClC,IAAA,KAAA,MAAW,CAAA,IAAK,IAAA,CAAK,UAAA,EAAY,CAAA,CAAE,kBAAkB,KAAK,CAAA;AAAA,EAC5D;AAAA,EAEA,WAAW,KAAA,EAAoD;AAC7D,IAAA,IAAI,IAAA,CAAK,UAAA,CAAW,MAAA,KAAW,CAAA,EAAG;AAClC,IAAA,KAAA,MAAW,CAAA,IAAK,IAAA,CAAK,UAAA,EAAY,CAAA,CAAE,WAAW,KAAK,CAAA;AAAA,EACrD;AAAA,EAEA,WAAW,KAAA,EAAoD;AAC7D,IAAA,IAAI,IAAA,CAAK,UAAA,CAAW,MAAA,KAAW,CAAA,EAAG;AAClC,IAAA,KAAA,MAAW,CAAA,IAAK,IAAA,CAAK,UAAA,EAAY,CAAA,CAAE,WAAW,KAAK,CAAA;AAAA,EACrD;AAAA,EAEA,aAAa,KAAA,EAAsD;AACjE,IAAA,IAAI,IAAA,CAAK,UAAA,CAAW,MAAA,KAAW,CAAA,EAAG;AAClC,IAAA,KAAA,MAAW,CAAA,IAAK,IAAA,CAAK,UAAA,EAAY,CAAA,CAAE,aAAa,KAAK,CAAA;AAAA,EACvD;AAAA,EAEA,cAAc,KAAA,EAAuD;AACnE,IAAA,IAAI,IAAA,CAAK,UAAA,CAAW,MAAA,KAAW,CAAA,EAAG;AAClC,IAAA,KAAA,MAAW,CAAA,IAAK,IAAA,CAAK,UAAA,EAAY,CAAA,CAAE,cAAc,KAAK,CAAA;AAAA,EACxD;AAAA,EAEA,gBAAgB,KAAA,EAAyD;AACvE,IAAA,IAAI,IAAA,CAAK,UAAA,CAAW,MAAA,KAAW,CAAA,EAAG;AAClC,IAAA,KAAA,MAAW,CAAA,IAAK,IAAA,CAAK,UAAA,EAAY,CAAA,CAAE,gBAAgB,KAAK,CAAA;AAAA,EAC1D;AAAA,EAEA,cAAA,GAAqC;AACnC,IAAA,MAAM,UAA8B,EAAC;AACrC,IAAA,KAAA,MAAW,CAAA,IAAK,KAAK,UAAA,EAAY;AAC/B,MAAA,MAAM,MAAA,GAAS,EAAE,SAAA,EAAU;AAC3B,MAAA,IAAI,MAAA,EAAQ,OAAA,CAAQ,IAAA,CAAK,MAAM,CAAA;AAAA,IACjC;AACA,IAAA,OAAO,OAAA;AAAA,EACT;AAAA,EAEA,KAAA,GAAc;AACZ,IAAA,KAAA,MAAW,CAAA,IAAK,IAAA,CAAK,UAAA,EAAY,CAAA,CAAE,KAAA,EAAM;AAAA,EAC3C;AACF;;;ACjGO,IAAe,sBAAf,MAAmC;AAAA,EACxC,gBAAgB,MAAA,EAA4D;AAAA,EAAC;AAAA,EAC7E,eAAe,MAAA,EAA2D;AAAA,EAAC;AAAA,EAC3E,kBAAkB,MAAA,EAA8D;AAAA,EAAC;AAAA,EACjF,aAAa,MAAA,EAAyD;AAAA,EAAC;AAAA,EACvE,gBAAgB,MAAA,EAA4D;AAAA,EAAC;AAAA,EAC7E,kBAAkB,MAAA,EAA8D;AAAA,EAAC;AAAA,EACjF,gBAAgB,MAAA,EAA4D;AAAA,EAAC;AAAA,EAC7E,SAAS,MAAA,EAAqD;AAAA,EAAC;AAAA,EAC/D,SAAS,MAAA,EAAqD;AAAA,EAAC;AAAA,EAC/D,WAAW,MAAA,EAAuD;AAAA,EAAC;AAAA,EACnE,YAAY,MAAA,EAAwD;AAAA,EAAC;AAAA,EACrE,cAAc,MAAA,EAA0D;AAAA,EAAC;AAI3E,CAAA;;;ACjBO,IAAM,2BAAA,GAAN,cAA0C,mBAAA,CAAoB;AAAA,EAA9D,WAAA,GAAA;AAAA,IAAA,KAAA,CAAA,GAAA,SAAA,CAAA;AACL,IAAA,IAAA,CAAQ,SAA4B,EAAC;AACrC,IAAA,IAAA,CAAQ,OAAA,GAAkB,CAAA;AAC1B,IAAA,IAAA,CAAQ,eAAA,uBAAwE,GAAA,EAAI;AAKpF;AAAA;AAAA;AAAA,IAAA,IAAA,CAAQ,WAAA,GAAc,CAAA;AACtB,IAAA,IAAA,CAAQ,YAAA,GAAe,KAAA;AACvB,IAAA,IAAA,CAAQ,UAAA,GAAa,KAAA;AACrB,IAAA,IAAA,CAAQ,gBAAA,GAAmB,KAAA;AAC3B,IAAA,IAAA,CAAQ,0BAAA,GAA6B,CAAA;AACrC,IAAA,IAAA,CAAQ,kBAAyC,EAAC;AAClD,IAAA,IAAA,CAAQ,cAAA,GAAiB,EAAA;AACzB,IAAA,IAAA,CAAQ,aAAA,GAAgB,EAAA;AAAA,EAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAWxB,IAAI,kBAAA,GAA6B;AAC/B,IAAA,OAAO,KAAK,eAAA,CAAgB,MAAA;AAAA,EAC9B;AAAA,EAEA,KAAA,GAAc;AACZ,IAAA,IAAA,CAAK,SAAS,EAAC;AACf,IAAA,IAAA,CAAK,gBAAgB,KAAA,EAAM;AAC3B,IAAA,IAAA,CAAK,OAAA,GAAU,CAAA;AACf,IAAA,IAAA,CAAK,WAAA,GAAc,CAAA;AACnB,IAAA,IAAA,CAAK,YAAA,GAAe,KAAA;AACpB,IAAA,IAAA,CAAK,UAAA,GAAa,KAAA;AAClB,IAAA,IAAA,CAAK,gBAAA,GAAmB,KAAA;AACxB,IAAA,IAAA,CAAK,0BAAA,GAA6B,CAAA;AAClC,IAAA,IAAA,CAAK,kBAAkB,EAAC;AACxB,IAAA,IAAA,CAAK,cAAA,GAAiB,EAAA;AACtB,IAAA,IAAA,CAAK,aAAA,GAAgB,EAAA;AAAA,EACvB;AAAA;AAAA,EAGQ,MAAiC,KAAA,EAAa;AACpD,IAAA,MAAM,SAAA,GAAY,KAAK,OAAA,KAAY,CAAA,GAC/B,YAAY,GAAA,EAAI,GAAI,GAAA,GAAM,IAAA,CAAK,OAAA,GAC/B,CAAA;AACJ,IAAA,OAAO,EAAE,GAAG,KAAA,EAAO,SAAA,EAAU;AAAA,EAC/B;AAAA,EAEA,gBAAgB,KAAA,EAA2D;AAWzE,IAAA,IAAI,IAAA,CAAK,YAAY,CAAA,EAAG;AACtB,MAAA,IAAA,CAAK,OAAA,GAAU,WAAA,CAAY,GAAA,EAAI,GAAI,GAAA;AAAA,IACrC;AAQA,IAAA,IAAA,CAAK,iBAAiB,KAAA,CAAM,UAAA;AAC5B,IAAA,IAAA,CAAK,gBAAgB,KAAA,CAAM,SAAA;AAC3B,IAAA,IAAA,CAAK,MAAA,CAAO,IAAA,CAAK,IAAA,CAAK,KAAA,CAAM,KAAK,CAAC,CAAA;AAAA,EACpC;AAAA,EAEA,eAAe,KAAA,EAA0D;AACvE,IAAA,IAAA,CAAK,MAAA,CAAO,IAAA,CAAK,IAAA,CAAK,KAAA,CAAM,KAAK,CAAC,CAAA;AAClC,IAAA,IAAA,CAAK,WAAA,EAAA;AAAA,EACP;AAAA,EAEA,kBAAkB,KAAA,EAA6D;AAC7E,IAAA,IAAA,CAAK,MAAA,CAAO,IAAA,CAAK,IAAA,CAAK,KAAA,CAAM,KAAK,CAAC,CAAA;AAAA,EACpC;AAAA,EAEA,aAAa,KAAA,EAAwD;AACnE,IAAA,IAAA,CAAK,MAAA,CAAO,IAAA,CAAK,IAAA,CAAK,KAAA,CAAM,KAAK,CAAC,CAAA;AAAA,EACpC;AAAA,EAEA,gBAAgB,KAAA,EAA2D;AACzE,IAAA,IAAA,CAAK,MAAA,CAAO,IAAA,CAAK,IAAA,CAAK,KAAA,CAAM,KAAK,CAAC,CAAA;AAAA,EACpC;AAAA,EAEA,kBAAkB,KAAA,EAA6D;AAC7E,IAAA,IAAA,CAAK,MAAA,CAAO,IAAA,CAAK,IAAA,CAAK,KAAA,CAAM,KAAK,CAAC,CAAA;AAElC,IAAA,MAAM,KAAA,GAAQ,IAAA,CAAK,eAAA,CAAgB,GAAA,CAAI,MAAM,gBAAgB,CAAA;AAC7D,IAAA,IAAI,KAAA,EAAO;AACT,MAAA,KAAA,CAAM,KAAA,EAAA;AAAA,IACR,CAAA,MAAO;AACL,MAAA,IAAA,CAAK,eAAA,CAAgB,GAAA,CAAI,KAAA,CAAM,gBAAA,EAAkB;AAAA,QAC/C,UAAU,KAAA,CAAM,gBAAA;AAAA,QAChB,KAAA,EAAO;AAAA,OACR,CAAA;AAAA,IACH;AAEA,IAAA,IAAA,CAAK,gBAAgB,IAAA,CAAK;AAAA,MACxB,WAAW,KAAA,CAAM,SAAA;AAAA,MACjB,YAAY,KAAA,CAAM,UAAA;AAAA,MAClB,kBAAkB,KAAA,CAAM,gBAAA;AAAA,MACxB,cAAc,KAAA,CAAM,YAAA;AAAA,MACpB,UAAU,KAAA,CAAM,QAAA;AAAA,MAChB,cAAc,KAAA,CAAM,YAAA;AAAA,MACpB,aAAa,KAAA,CAAM;AAAA,KACpB,CAAA;AAAA,EACH;AAAA,EAEA,gBAAgB,KAAA,EAA2D;AACzE,IAAA,IAAA,CAAK,MAAA,CAAO,IAAA,CAAK,IAAA,CAAK,KAAA,CAAM,KAAK,CAAC,CAAA;AAIlC,IAAA,IAAI,CAAC,KAAK,gBAAA,EAAkB;AAC1B,MAAA,IAAA,CAAK,gBAAA,GAAmB,IAAA;AACxB,MAAA,IAAA,CAAK,6BAA6B,KAAA,CAAM,aAAA;AAAA,IAC1C;AAAA,EACF;AAAA,EAEA,SAAS,KAAA,EAAoD;AAC3D,IAAA,IAAA,CAAK,MAAA,CAAO,IAAA,CAAK,IAAA,CAAK,KAAA,CAAM,KAAK,CAAC,CAAA;AAClC,IAAA,IAAA,CAAK,UAAA,GAAa,IAAA;AAAA,EACpB;AAAA,EAEA,SAAS,KAAA,EAAoD;AAC3D,IAAA,IAAA,CAAK,MAAA,CAAO,IAAA,CAAK,IAAA,CAAK,KAAA,CAAM,KAAK,CAAC,CAAA;AAAA,EACpC;AAAA,EAEA,WAAW,KAAA,EAAsD;AAC/D,IAAA,IAAA,CAAK,MAAA,CAAO,IAAA,CAAK,IAAA,CAAK,KAAA,CAAM,KAAK,CAAC,CAAA;AAClC,IAAA,IAAA,CAAK,YAAA,GAAe,IAAA;AAAA,EACtB;AAAA,EAEA,YAAY,KAAA,EAAuD;AACjE,IAAA,IAAA,CAAK,MAAA,CAAO,IAAA,CAAK,IAAA,CAAK,KAAA,CAAM,KAAK,CAAC,CAAA;AAAA,EACpC;AAAA,EAEA,cAAc,KAAA,EAAyD;AACrE,IAAA,IAAA,CAAK,MAAA,CAAO,IAAA,CAAK,IAAA,CAAK,KAAA,CAAM,KAAK,CAAC,CAAA;AAAA,EACpC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAqBF,SAAA,GAA0C;AACrC,IAAA,IAAI,IAAA,CAAK,MAAA,CAAO,MAAA,KAAW,CAAA,EAAG,OAAO,MAAA;AAErC,IAAA,MAAM,SAAA,GAAY,WAAA,CAAY,GAAA,EAAI,GAAI,MAAM,IAAA,CAAK,OAAA;AAEjD,IAAA,MAAM,eAAA,uBAAsB,GAAA,EAAoB;AAChD,IAAA,KAAA,MAAW,GAAG,KAAK,CAAA,IAAK,KAAK,eAAA,EAAiB;AAC5C,MAAA,eAAA,CAAgB,GAAA,CAAI,KAAA,CAAM,QAAA,EAAU,KAAA,CAAM,KAAK,CAAA;AAAA,IACjD;AAEA,IAAA,MAAM,eAAe,IAAA,CAAK,0BAAA;AAC1B,IAAA,MAAM,WAAW,IAAA,CAAK,YAAA;AACtB,IAAA,MAAM,cAAc,IAAA,CAAK,WAAA;AAEzB,IAAA,MAAM,MAAA,GAA2B;AAAA,MAC/B,QAAQ,IAAA,CAAK,MAAA;AAAA,MACb,SAAA,EAAW,KAAK,eAAA,CAAgB,GAAA,CAAI,CAAC,CAAA,MAAO,EAAE,GAAG,CAAA,EAAE,CAAE,CAAA;AAAA,MACrD,OAAA,EAAS;AAAA,QACP,WAAA;AAAA,QACA,gBAAgB,eAAA,CAAgB,IAAA;AAAA,QAChC,YAAA;AAAA,QACA,QAAA;AAAA,QACA,SAAA;AAAA,QACA;AAAA,OACF;AAAA,MACA,QAAA,EAAU;AAAA,QACR,YAAY,IAAA,CAAK,cAAA;AAAA,QACjB,WAAW,IAAA,CAAK,aAAA;AAAA,QAChB,SAAA,EAAW,KAAK,GAAA,EAAI;AAAA,QACpB,gBAAgB,IAAA,CAAK;AAAA,OACvB;AAAA,MACA,MAAA,GAA+B;AAC7B,QAAA,OAAO;AAAA,UACL,QAAQ,MAAA,CAAO,MAAA;AAAA,UACf,WAAW,MAAA,CAAO,SAAA;AAAA,UAClB,OAAA,EAAS;AAAA,YACP,WAAA,EAAa,OAAO,OAAA,CAAQ,WAAA;AAAA,YAC5B,cAAA,EAAgB,OAAO,OAAA,CAAQ,cAAA;AAAA,YAC/B,YAAA,EAAc,OAAO,OAAA,CAAQ,YAAA;AAAA,YAC7B,QAAA,EAAU,OAAO,OAAA,CAAQ,QAAA;AAAA,YACzB,SAAA,EAAW,OAAO,OAAA,CAAQ,SAAA;AAAA,YAC1B,eAAA,EAAiB,MAAA,CAAO,WAAA,CAAY,MAAA,CAAO,QAAQ,eAAe;AAAA,WACpE;AAAA,UACA,QAAA,EAAU,EAAE,GAAG,MAAA,CAAO,QAAA;AAAS,SACjC;AAAA,MACF;AAAA,KACF;AAEA,IAAA,OAAO,MAAA;AAAA,EACT;AACH;;;AClOO,IAAM,mBAAA,GAAsB;AAAA,EACjC,YAAA,EAAc,eAAA;AAAA,EACd,eAAA,EAAiB,kBAAA;AAAA,EACjB,UAAA,EAAY,aAAA;AAAA,EACZ,aAAA,EAAe,gBAAA;AAAA,EACf,eAAA,EAAiB,kBAAA;AAAA,EACjB,aAAA,EAAe,gBAAA;AAAA,EACf,MAAA,EAAQ,SAAA;AAAA,EACR,MAAA,EAAQ,SAAA;AAAA,EACR,QAAA,EAAU,WAAA;AAAA,EACV,SAAA,EAAW,YAAA;AAAA,EACX,aAAA,EAAe,gBAAA;AAAA,EACf,WAAA,EAAa;AACf","file":"chunk-G535KJEG.js","sourcesContent":["import { DiagnosticCollector } from \"./collector\";\nimport { DiagnosticEvent } from \"./events\";\nimport { DiagnosticReport } from \"./events\";\n\n/**\n * Dispatches diagnostic events to all registered collectors.\n *\n * Performance guarantee: when no collectors are registered (production mode),\n * every dispatch method is a branch on `this.collectors.length === 0` which\n * modern JS engines will predict and eliminate. The overhead is a single\n * comparison per call, effectively zero.\n */\nexport class DiagnosticPipeline {\n private collectors: DiagnosticCollector[] = [];\n\n register(collector: DiagnosticCollector): void {\n this.collectors.push(collector);\n }\n\n unregister(collector: DiagnosticCollector): void {\n const idx = this.collectors.indexOf(collector);\n if (idx !== -1) this.collectors.splice(idx, 1);\n }\n\n clear(): void {\n this.collectors = [];\n }\n\n get hasCollectors(): boolean {\n return this.collectors.length > 0;\n }\n\n get collectorCount(): number {\n return this.collectors.length;\n }\n\n // Inline-optimized dispatchers, each checks length once then loops.\n // When collectors.length === 0, the JIT eliminates the entire method body.\n\n firePipelineStart(event: DiagnosticEvent & { type: \"pipeline_start\" }): void {\n if (this.collectors.length === 0) return;\n for (const c of this.collectors) c.onPipelineStart?.(event);\n }\n\n fireTokenEmitted(event: DiagnosticEvent & { type: \"token_emitted\" }): void {\n if (this.collectors.length === 0) return;\n for (const c of this.collectors) c.onTokenEmitted?.(event);\n }\n\n fireNormalizerStart(event: DiagnosticEvent & { type: \"normalizer_start\" }): void {\n if (this.collectors.length === 0) return;\n for (const c of this.collectors) c.onNormalizerStart?.(event);\n }\n\n fireTokenFused(event: DiagnosticEvent & { type: \"token_fused\" }): void {\n if (this.collectors.length === 0) return;\n for (const c of this.collectors) c.onTokenFused?.(event);\n }\n\n fireNormalizerEnd(event: DiagnosticEvent & { type: \"normalizer_end\" }): void {\n if (this.collectors.length === 0) return;\n for (const c of this.collectors) c.onNormalizerEnd?.(event);\n }\n\n fireParseletMatched(event: DiagnosticEvent & { type: \"parselet_matched\" }): void {\n if (this.collectors.length === 0) return;\n for (const c of this.collectors) c.onParseletMatched?.(event);\n }\n\n fireBytecodeBuilt(event: DiagnosticEvent & { type: \"bytecode_built\" }): void {\n if (this.collectors.length === 0) return;\n for (const c of this.collectors) c.onBytecodeBuilt?.(event);\n }\n\n fireVmStep(event: DiagnosticEvent & { type: \"vm_step\" }): void {\n if (this.collectors.length === 0) return;\n for (const c of this.collectors) c.onVmStep?.(event);\n }\n\n fireVmHalt(event: DiagnosticEvent & { type: \"vm_halt\" }): void {\n if (this.collectors.length === 0) return;\n for (const c of this.collectors) c.onVmHalt?.(event);\n }\n\n fireCacheHit(event: DiagnosticEvent & { type: \"cache_hit\" }): void {\n if (this.collectors.length === 0) return;\n for (const c of this.collectors) c.onCacheHit?.(event);\n }\n\n fireCacheMiss(event: DiagnosticEvent & { type: \"cache_miss\" }): void {\n if (this.collectors.length === 0) return;\n for (const c of this.collectors) c.onCacheMiss?.(event);\n }\n\n firePipelineEnd(event: DiagnosticEvent & { type: \"pipeline_end\" }): void {\n if (this.collectors.length === 0) return;\n for (const c of this.collectors) c.onPipelineEnd?.(event);\n }\n\n collectReports(): DiagnosticReport[] {\n const reports: DiagnosticReport[] = [];\n for (const c of this.collectors) {\n const report = c.getReport();\n if (report) reports.push(report);\n }\n return reports;\n }\n\n reset(): void {\n for (const c of this.collectors) c.reset();\n }\n}","import { DiagnosticEvent } from \"./events\";\nimport { DiagnosticReport } from \"./events\";\n\n/**\n * Interface for collecting diagnostic data during pipeline execution.\n *\n * All methods are implemented as concrete no-ops so subclasses only\n * need to override the ones they care about. This avoids optional\n * method issues with TypeScript's strict mode.\n *\n * The parameters are named `_event` because these base implementations\n * deliberately ignore them. Overrides are free to name theirs `event` and use\n * it; TypeScript does not match parameter names when checking overrides.\n */\nexport abstract class DiagnosticCollector {\n onPipelineStart(_event: DiagnosticEvent & { type: \"pipeline_start\" }): void {}\n onTokenEmitted(_event: DiagnosticEvent & { type: \"token_emitted\" }): void {}\n onNormalizerStart(_event: DiagnosticEvent & { type: \"normalizer_start\" }): void {}\n onTokenFused(_event: DiagnosticEvent & { type: \"token_fused\" }): void {}\n onNormalizerEnd(_event: DiagnosticEvent & { type: \"normalizer_end\" }): void {}\n onParseletMatched(_event: DiagnosticEvent & { type: \"parselet_matched\" }): void {}\n onBytecodeBuilt(_event: DiagnosticEvent & { type: \"bytecode_built\" }): void {}\n onVmStep(_event: DiagnosticEvent & { type: \"vm_step\" }): void {}\n onVmHalt(_event: DiagnosticEvent & { type: \"vm_halt\" }): void {}\n onCacheHit(_event: DiagnosticEvent & { type: \"cache_hit\" }): void {}\n onCacheMiss(_event: DiagnosticEvent & { type: \"cache_miss\" }): void {}\n onPipelineEnd(_event: DiagnosticEvent & { type: \"pipeline_end\" }): void {}\n\n abstract getReport(): DiagnosticReport | undefined;\n abstract reset(): void;\n}","import { DiagnosticCollector } from \"./collector\";\nimport { DiagnosticReport, DiagnosticReportJSON, DiagnosticEvent, CategorizedParselet } from \"./events\";\n\n/**\n * Collects all pipeline events with high-resolution timestamps.\n *\n * Overrides the zero-filled `elapsedNs` on every incoming event with a\n * real `performance.now()` delta from `onPipelineStart`. This enables\n * per-stage timing extraction from the event timeline (lexer/parser/\n * compiler/VM breakdown) rather than relying on a single total elapsed.\n *\n * Produces a complete DiagnosticReport at the end of evaluation.\n */\nexport class TimelineDiagnosticCollector extends DiagnosticCollector {\n private events: DiagnosticEvent[] = [];\n private startNs: number = 0;\n private parseletEntries: Map<string, { category: string; count: number }> = new Map();\n\n // Incrementally-maintained summary state. See getReport()'s doc comment\n // for why these exist. Each mirrors exactly what getReport() used to\n // recompute by rescanning the full `events` array on every call.\n private totalTokens = 0;\n private cacheHitSeen = false;\n private vmStepSeen = false;\n private hasBytecodeBuilt = false;\n private firstBytecodeOpcodesLength = 0;\n private parseletMatches: CategorizedParselet[] = [];\n private lastExpression = \"\";\n private lastInputType = \"\";\n\n /**\n * Current cumulative count of `parselet_matched` events seen since\n * construction (or the last `reset()`), a cheap peek that doesn't build\n * the full report (`getReport()` copies the whole `parseletMatches`\n * array). Used by `ExpressionEngine.evaluateExpressionWithDiagnostic()`\n * to capture a \"before\" baseline per line, since `parseletMatches` itself\n * is deliberately cumulative across an entire document pass (see\n * `onPipelineStart`'s doc comment) rather than reset per line.\n */\n get parseletMatchCount(): number {\n return this.parseletMatches.length;\n }\n\n reset(): void {\n this.events = [];\n this.parseletEntries.clear();\n this.startNs = 0;\n this.totalTokens = 0;\n this.cacheHitSeen = false;\n this.vmStepSeen = false;\n this.hasBytecodeBuilt = false;\n this.firstBytecodeOpcodesLength = 0;\n this.parseletMatches = [];\n this.lastExpression = \"\";\n this.lastInputType = \"\";\n }\n\n /** Stamp the real wall-clock `elapsedNs` onto an event before storing it. */\n private stamp<T extends DiagnosticEvent>(event: T): T {\n const elapsedNs = this.startNs !== 0\n ? performance.now() * 1e6 - this.startNs\n : 0;\n return { ...event, elapsedNs } as T;\n }\n\n onPipelineStart(event: DiagnosticEvent & { type: \"pipeline_start\" }): void {\n // Set once per collector lifetime (until an explicit reset()), not on\n // every pipeline, a multi-line evaluation pass fires pipeline_start\n // once per line, all appending to the SAME `events` array (see\n // buildLineStats() in the playground, which relies on that shared,\n // ever-growing array to slice out each line's own events via\n // cumulative-length diffing). Resetting the origin on every line meant\n // every individual line's own timestamps were self-consistent, but\n // nothing tied one line's clock to another's, any code trying to\n // compare or span timestamps ACROSS lines (e.g. \"how far into this\n // pass are we\") had no stable reference point to do it with.\n if (this.startNs === 0) {\n this.startNs = performance.now() * 1e6;\n }\n // Tracked incrementally (most-recent wins) so getReport()'s `metadata`\n // describes the line THIS report is actually about, reading\n // `events[0]` instead (the old code) froze `expression`/`inputType` on\n // the very first line ever evaluated in the session, forever, which is\n // wrong regardless of whether a field is meant to be cumulative or\n // per-line: nothing downstream ever wanted \"line 1's expression\" once\n // the document had moved on to line 50.\n this.lastExpression = event.expression;\n this.lastInputType = event.inputType;\n this.events.push(this.stamp(event));\n }\n\n onTokenEmitted(event: DiagnosticEvent & { type: \"token_emitted\" }): void {\n this.events.push(this.stamp(event));\n this.totalTokens++;\n }\n\n onNormalizerStart(event: DiagnosticEvent & { type: \"normalizer_start\" }): void {\n this.events.push(this.stamp(event));\n }\n\n onTokenFused(event: DiagnosticEvent & { type: \"token_fused\" }): void {\n this.events.push(this.stamp(event));\n }\n\n onNormalizerEnd(event: DiagnosticEvent & { type: \"normalizer_end\" }): void {\n this.events.push(this.stamp(event));\n }\n\n onParseletMatched(event: DiagnosticEvent & { type: \"parselet_matched\" }): void {\n this.events.push(this.stamp(event));\n\n const entry = this.parseletEntries.get(event.parseletCategory);\n if (entry) {\n entry.count++;\n } else {\n this.parseletEntries.set(event.parseletCategory, {\n category: event.parseletCategory,\n count: 1,\n });\n }\n\n this.parseletMatches.push({\n tokenType: event.tokenType,\n tokenValue: event.tokenValue,\n parseletCategory: event.parseletCategory,\n parseletType: event.parseletType,\n isPrefix: event.isPrefix,\n bindingPower: event.bindingPower,\n tokenOffset: event.tokenOffset,\n });\n }\n\n onBytecodeBuilt(event: DiagnosticEvent & { type: \"bytecode_built\" }): void {\n this.events.push(this.stamp(event));\n // Matches getReport()'s original behavior: the FIRST bytecode_built\n // event ever seen (not the most recent) wins, preserved as-is here\n // this rewrite only changes HOW that value is computed, not what it is.\n if (!this.hasBytecodeBuilt) {\n this.hasBytecodeBuilt = true;\n this.firstBytecodeOpcodesLength = event.opcodesLength;\n }\n }\n\n onVmStep(event: DiagnosticEvent & { type: \"vm_step\" }): void {\n this.events.push(this.stamp(event));\n this.vmStepSeen = true;\n }\n\n onVmHalt(event: DiagnosticEvent & { type: \"vm_halt\" }): void {\n this.events.push(this.stamp(event));\n }\n\n onCacheHit(event: DiagnosticEvent & { type: \"cache_hit\" }): void {\n this.events.push(this.stamp(event));\n this.cacheHitSeen = true;\n }\n\n onCacheMiss(event: DiagnosticEvent & { type: \"cache_miss\" }): void {\n this.events.push(this.stamp(event));\n }\n\n onPipelineEnd(event: DiagnosticEvent & { type: \"pipeline_end\" }): void {\n this.events.push(this.stamp(event));\n }\n\n/**\n * Build the summary/metadata/parselets report from this collector's\n * running state.\n *\n * These fields used to be recomputed by rescanning the FULL `events`\n * array on every single call (`.some()`/`.filter()`/a manual scan), since\n * `events` is never cleared except by an explicit `reset()` (which nothing\n * in `ExpressionEngine` currently calls, the cumulative-across-the-whole-\n * document design is deliberate, see `onPipelineStart`'s comment and the\n * playground's `buildLineStats()`, which slices per-line events out of\n * this ever-growing array via cumulative-length diffing), that meant\n * per-call cost grew linearly with total prior calls: O(n²) diagnostic-mode\n * evaluation over a document's lifetime. Fixed by maintaining each of these\n * incrementally as events arrive (see the `on*` handlers above), the same\n * pattern already used for `parseletEntries`. Every value produced here is\n * identical to what the old rescanning code produced, including its\n * existing \"first bytecode_built event wins\" quirk. This is a performance\n * fix, not a behavior change.\n */\ngetReport(): DiagnosticReport | undefined {\n if (this.events.length === 0) return undefined;\n\n const elapsedNs = performance.now() * 1e6 - this.startNs;\n\n const parseCategories = new Map<string, number>();\n for (const [, entry] of this.parseletEntries) {\n parseCategories.set(entry.category, entry.count);\n }\n\n const totalOpcodes = this.firstBytecodeOpcodesLength;\n const cacheHit = this.cacheHitSeen;\n const totalTokens = this.totalTokens;\n\n const report: DiagnosticReport = {\n events: this.events,\n parselets: this.parseletMatches.map((e) => ({ ...e })),\n summary: {\n totalTokens,\n totalParselets: parseCategories.size,\n totalOpcodes,\n cacheHit,\n elapsedNs,\n parseCategories,\n },\n metadata: {\n expression: this.lastExpression,\n inputType: this.lastInputType,\n timestamp: Date.now(),\n vmTraceEnabled: this.vmStepSeen,\n },\n toJSON(): DiagnosticReportJSON {\n return {\n events: report.events,\n parselets: report.parselets,\n summary: {\n totalTokens: report.summary.totalTokens,\n totalParselets: report.summary.totalParselets,\n totalOpcodes: report.summary.totalOpcodes,\n cacheHit: report.summary.cacheHit,\n elapsedNs: report.summary.elapsedNs,\n parseCategories: Object.fromEntries(report.summary.parseCategories),\n },\n metadata: { ...report.metadata },\n };\n },\n };\n\n return report;\n }\n}","\n\nimport type { MatrixData, RangeData } from \"@solve-js/vm/Value\";\nimport type { SymbolicNode } from \"@solve-js/symbolic\";\n\n/**\n * Diagnostic event types as string constants (not const enum, for cross-module compatibility with isolatedModules)\n */\nexport const DiagnosticEventType = {\n TokenEmitted: \"token_emitted\",\n NormalizerStart: \"normalizer_start\",\n TokenFused: \"token_fused\",\n NormalizerEnd: \"normalizer_end\",\n ParseletMatched: \"parselet_matched\",\n BytecodeBuilt: \"bytecode_built\",\n VmStep: \"vm_step\",\n VmHalt: \"vm_halt\",\n CacheHit: \"cache_hit\",\n CacheMiss: \"cache_miss\",\n PipelineStart: \"pipeline_start\",\n PipelineEnd: \"pipeline_end\",\n} as const;\n\n/** Discriminator naming which pipeline event a diagnostic record describes. */\nexport type EventType = (typeof DiagnosticEventType)[keyof typeof DiagnosticEventType];\n\n/** Base event, all events include a timestamp relative to pipeline start */\nexport interface BaseEvent {\n readonly type: string;\n readonly elapsedNs: number;\n readonly expression: string;\n}\n\n/** Emitted after each token is produced by the lexer */\nexport interface TokenEmittedEvent extends BaseEvent {\n readonly type: \"token_emitted\";\n readonly token: {\n readonly type: string;\n readonly value: string;\n readonly offset: number;\n readonly line: number;\n readonly col: number;\n };\n}\n\n/** Emitted when the parser resolves a parselet for a token */\nexport interface ParseletMatchedEvent extends BaseEvent {\n readonly type: \"parselet_matched\";\n readonly tokenType: string;\n readonly tokenValue: string;\n readonly parseletCategory: string;\n readonly parseletType: string;\n readonly isPrefix: boolean;\n readonly bindingPower?: number;\n readonly tokenOffset: number;\n}\n\n/** Emitted after bytecode is built */\nexport interface BytecodeBuiltEvent extends BaseEvent {\n readonly type: \"bytecode_built\";\n readonly opcodesLength: number;\n readonly numbersLength: number;\n readonly stringsLength: number;\n readonly isCached: boolean;\n}\n\n/** Emitted after each VM opcode execution (only when vmTrace is enabled) */\nexport interface VmStepEvent extends BaseEvent {\n readonly type: \"vm_step\";\n readonly opcode: number;\n readonly opcodeName: string;\n readonly ip: number;\n readonly stackDepth: number;\n readonly instructionNumber: number;\n readonly stack: ReadonlyArray<{\n readonly type: number;\n readonly value: number | bigint | string | boolean | MatrixData | RangeData | SymbolicNode;\n readonly unit?: string;\n }>;\n}\n\n/** Emitted when the VM halts with a result */\nexport interface VmHaltEvent extends BaseEvent {\n readonly type: \"vm_halt\";\n readonly result?: {\n readonly type: number;\n readonly value: number | bigint | string | boolean | MatrixData | RangeData | SymbolicNode;\n readonly unit?: string;\n };\n}\n\n/** Emitted on cache hit */\nexport interface CacheHitEvent extends BaseEvent {\n readonly type: \"cache_hit\";\n readonly cache: \"bytecode\" | \"line\";\n readonly key: string;\n}\n\n/** Emitted on cache miss */\nexport interface CacheMissEvent extends BaseEvent {\n readonly type: \"cache_miss\";\n readonly cache: \"bytecode\" | \"line\";\n readonly key: string;\n}\n\n/** Emitted when a pipeline evaluation begins */\nexport interface PipelineStartEvent extends BaseEvent {\n readonly type: \"pipeline_start\";\n readonly inputType: string;\n}\n\n/** Emitted when a pipeline evaluation completes */\nexport interface PipelineEndEvent extends BaseEvent {\n readonly type: \"pipeline_end\";\n readonly success: boolean;\n readonly error?: string;\n readonly totalTokens: number;\n readonly totalOpcodes: number;\n}\n\n/** Emitted when the normalizer begins its pass */\nexport interface NormalizerStartEvent extends BaseEvent {\n readonly type: \"normalizer_start\";\n readonly inputTokenCount: number;\n}\n\n/** Emitted when the normalizer fuses tokens */\nexport interface TokenFusedEvent extends BaseEvent {\n readonly type: \"token_fused\";\n readonly ruleName: string;\n readonly sourceTokenCount: number;\n readonly fusedTokenType: string;\n readonly fusedTokenValue: string;\n}\n\n/** Emitted when the normalizer completes its pass */\nexport interface NormalizerEndEvent extends BaseEvent {\n readonly type: \"normalizer_end\";\n readonly outputTokenCount: number;\n readonly fusionsCount: number;\n}\n\n/** Union of all event types */\nexport type DiagnosticEvent =\n | TokenEmittedEvent\n | NormalizerStartEvent\n | TokenFusedEvent\n | NormalizerEndEvent\n | ParseletMatchedEvent\n | BytecodeBuiltEvent\n | VmStepEvent\n | VmHaltEvent\n | CacheHitEvent\n | CacheMissEvent\n | PipelineStartEvent\n | PipelineEndEvent;\n\n/** Categorized parselet info */\nexport interface CategorizedParselet {\n readonly tokenType: string;\n readonly tokenValue: string;\n readonly parseletCategory: string;\n readonly parseletType: string;\n readonly isPrefix: boolean;\n readonly bindingPower?: number;\n readonly tokenOffset: number;\n}\n\n/** JSON-serializable representation of a DiagnosticReport */\nexport interface DiagnosticReportJSON {\n readonly events: readonly DiagnosticEvent[];\n readonly parselets: readonly CategorizedParselet[];\n readonly summary: {\n readonly totalTokens: number;\n readonly totalParselets: number;\n readonly totalOpcodes: number;\n readonly cacheHit: boolean;\n readonly elapsedNs: number;\n readonly parseCategories: Record<string, number>;\n };\n readonly metadata: {\n readonly expression: string;\n readonly inputType: string;\n readonly timestamp: number;\n readonly vmTraceEnabled: boolean;\n };\n}\n\n/** Structured diagnostic report */\nexport interface DiagnosticReport {\n readonly events: readonly DiagnosticEvent[];\n readonly parselets: readonly CategorizedParselet[];\n readonly summary: {\n readonly totalTokens: number;\n readonly totalParselets: number;\n readonly totalOpcodes: number;\n readonly cacheHit: boolean;\n readonly elapsedNs: number;\n readonly parseCategories: ReadonlyMap<string, number>;\n };\n readonly metadata: {\n readonly expression: string;\n readonly inputType: string;\n readonly timestamp: number;\n readonly vmTraceEnabled: boolean;\n };\n\n /** Serialize to a JSON-safe plain object */\n toJSON(): DiagnosticReportJSON;\n}\n\n/** JSON-serializable representation of a DiagnosticReport */\nexport interface DiagnosticReportJSON {\n readonly events: readonly DiagnosticEvent[];\n readonly parselets: readonly CategorizedParselet[];\n readonly summary: {\n readonly totalTokens: number;\n readonly totalParselets: number;\n readonly totalOpcodes: number;\n readonly cacheHit: boolean;\n readonly elapsedNs: number;\n readonly parseCategories: Record<string, number>;\n };\n readonly metadata: {\n readonly expression: string;\n readonly inputType: string;\n readonly timestamp: number;\n readonly vmTraceEnabled: boolean;\n };\n}"]}
|
|
1
|
+
{"version":3,"sources":["../src/diagnostics/pipeline.ts","../src/diagnostics/collector.ts","../src/diagnostics/timeline-collector.ts","../src/diagnostics/events.ts"],"names":[],"mappings":"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","file":"chunk-CCBZZQAE.js","sourcesContent":["import { DiagnosticCollector } from \"./collector\";\nimport { DiagnosticEvent } from \"./events\";\nimport { DiagnosticReport } from \"./events\";\n\n/**\n * Dispatches diagnostic events to all registered collectors.\n *\n * Performance guarantee: when no collectors are registered (production mode),\n * every dispatch method is a branch on `this.collectors.length === 0` which\n * modern JS engines will predict and eliminate. The overhead is a single\n * comparison per call, effectively zero.\n */\nexport class DiagnosticPipeline {\n private collectors: DiagnosticCollector[] = [];\n\n register(collector: DiagnosticCollector): void {\n this.collectors.push(collector);\n }\n\n unregister(collector: DiagnosticCollector): void {\n const idx = this.collectors.indexOf(collector);\n if (idx !== -1) this.collectors.splice(idx, 1);\n }\n\n clear(): void {\n this.collectors = [];\n }\n\n get hasCollectors(): boolean {\n return this.collectors.length > 0;\n }\n\n get collectorCount(): number {\n return this.collectors.length;\n }\n\n // Inline-optimized dispatchers, each checks length once then loops.\n // When collectors.length === 0, the JIT eliminates the entire method body.\n\n firePipelineStart(event: DiagnosticEvent & { type: \"pipeline_start\" }): void {\n if (this.collectors.length === 0) return;\n for (const c of this.collectors) c.onPipelineStart?.(event);\n }\n\n fireTokenEmitted(event: DiagnosticEvent & { type: \"token_emitted\" }): void {\n if (this.collectors.length === 0) return;\n for (const c of this.collectors) c.onTokenEmitted?.(event);\n }\n\n fireNormalizerStart(event: DiagnosticEvent & { type: \"normalizer_start\" }): void {\n if (this.collectors.length === 0) return;\n for (const c of this.collectors) c.onNormalizerStart?.(event);\n }\n\n fireTokenFused(event: DiagnosticEvent & { type: \"token_fused\" }): void {\n if (this.collectors.length === 0) return;\n for (const c of this.collectors) c.onTokenFused?.(event);\n }\n\n fireNormalizerEnd(event: DiagnosticEvent & { type: \"normalizer_end\" }): void {\n if (this.collectors.length === 0) return;\n for (const c of this.collectors) c.onNormalizerEnd?.(event);\n }\n\n fireParseletMatched(event: DiagnosticEvent & { type: \"parselet_matched\" }): void {\n if (this.collectors.length === 0) return;\n for (const c of this.collectors) c.onParseletMatched?.(event);\n }\n\n fireBytecodeBuilt(event: DiagnosticEvent & { type: \"bytecode_built\" }): void {\n if (this.collectors.length === 0) return;\n for (const c of this.collectors) c.onBytecodeBuilt?.(event);\n }\n\n fireVmStep(event: DiagnosticEvent & { type: \"vm_step\" }): void {\n if (this.collectors.length === 0) return;\n for (const c of this.collectors) c.onVmStep?.(event);\n }\n\n fireVmHalt(event: DiagnosticEvent & { type: \"vm_halt\" }): void {\n if (this.collectors.length === 0) return;\n for (const c of this.collectors) c.onVmHalt?.(event);\n }\n\n fireCacheHit(event: DiagnosticEvent & { type: \"cache_hit\" }): void {\n if (this.collectors.length === 0) return;\n for (const c of this.collectors) c.onCacheHit?.(event);\n }\n\n fireCacheMiss(event: DiagnosticEvent & { type: \"cache_miss\" }): void {\n if (this.collectors.length === 0) return;\n for (const c of this.collectors) c.onCacheMiss?.(event);\n }\n\n firePipelineEnd(event: DiagnosticEvent & { type: \"pipeline_end\" }): void {\n if (this.collectors.length === 0) return;\n for (const c of this.collectors) c.onPipelineEnd?.(event);\n }\n\n collectReports(): DiagnosticReport[] {\n const reports: DiagnosticReport[] = [];\n for (const c of this.collectors) {\n const report = c.getReport();\n if (report) reports.push(report);\n }\n return reports;\n }\n\n reset(): void {\n for (const c of this.collectors) c.reset();\n }\n}","import { DiagnosticEvent } from \"./events\";\nimport { DiagnosticReport } from \"./events\";\n\n/**\n * Interface for collecting diagnostic data during pipeline execution.\n *\n * All methods are implemented as concrete no-ops so subclasses only\n * need to override the ones they care about. This avoids optional\n * method issues with TypeScript's strict mode.\n *\n * The parameters are named `_event` because these base implementations\n * deliberately ignore them. Overrides are free to name theirs `event` and use\n * it; TypeScript does not match parameter names when checking overrides.\n */\nexport abstract class DiagnosticCollector {\n onPipelineStart(_event: DiagnosticEvent & { type: \"pipeline_start\" }): void {}\n onTokenEmitted(_event: DiagnosticEvent & { type: \"token_emitted\" }): void {}\n onNormalizerStart(_event: DiagnosticEvent & { type: \"normalizer_start\" }): void {}\n onTokenFused(_event: DiagnosticEvent & { type: \"token_fused\" }): void {}\n onNormalizerEnd(_event: DiagnosticEvent & { type: \"normalizer_end\" }): void {}\n onParseletMatched(_event: DiagnosticEvent & { type: \"parselet_matched\" }): void {}\n onBytecodeBuilt(_event: DiagnosticEvent & { type: \"bytecode_built\" }): void {}\n onVmStep(_event: DiagnosticEvent & { type: \"vm_step\" }): void {}\n onVmHalt(_event: DiagnosticEvent & { type: \"vm_halt\" }): void {}\n onCacheHit(_event: DiagnosticEvent & { type: \"cache_hit\" }): void {}\n onCacheMiss(_event: DiagnosticEvent & { type: \"cache_miss\" }): void {}\n onPipelineEnd(_event: DiagnosticEvent & { type: \"pipeline_end\" }): void {}\n\n abstract getReport(): DiagnosticReport | undefined;\n abstract reset(): void;\n}","import { DiagnosticCollector } from \"./collector\";\nimport { DiagnosticReport, DiagnosticReportJSON, DiagnosticEvent, CategorizedParselet } from \"./events\";\n\n/**\n * Collects all pipeline events with high-resolution timestamps.\n *\n * Overrides the zero-filled `elapsedNs` on every incoming event with a\n * real `performance.now()` delta from `onPipelineStart`. This enables\n * per-stage timing extraction from the event timeline (lexer/parser/\n * compiler/VM breakdown) rather than relying on a single total elapsed.\n *\n * Produces a complete DiagnosticReport at the end of evaluation.\n */\nexport class TimelineDiagnosticCollector extends DiagnosticCollector {\n private events: DiagnosticEvent[] = [];\n private startNs: number = 0;\n private parseletEntries: Map<string, { category: string; count: number }> = new Map();\n\n // Incrementally-maintained summary state. See getReport()'s doc comment\n // for why these exist. Each mirrors exactly what getReport() used to\n // recompute by rescanning the full `events` array on every call.\n private totalTokens = 0;\n private cacheHitSeen = false;\n private vmStepSeen = false;\n private hasBytecodeBuilt = false;\n private firstBytecodeOpcodesLength = 0;\n private parseletMatches: CategorizedParselet[] = [];\n private lastExpression = \"\";\n private lastInputType = \"\";\n\n /**\n * Current cumulative count of `parselet_matched` events seen since\n * construction (or the last `reset()`), a cheap peek that doesn't build\n * the full report (`getReport()` copies the whole `parseletMatches`\n * array). Used by `ExpressionEngine.evaluateExpressionWithDiagnostic()`\n * to capture a \"before\" baseline per line, since `parseletMatches` itself\n * is deliberately cumulative across an entire document pass (see\n * `onPipelineStart`'s doc comment) rather than reset per line.\n */\n get parseletMatchCount(): number {\n return this.parseletMatches.length;\n }\n\n reset(): void {\n this.events = [];\n this.parseletEntries.clear();\n this.startNs = 0;\n this.totalTokens = 0;\n this.cacheHitSeen = false;\n this.vmStepSeen = false;\n this.hasBytecodeBuilt = false;\n this.firstBytecodeOpcodesLength = 0;\n this.parseletMatches = [];\n this.lastExpression = \"\";\n this.lastInputType = \"\";\n }\n\n /** Stamp the real wall-clock `elapsedNs` onto an event before storing it. */\n private stamp<T extends DiagnosticEvent>(event: T): T {\n const elapsedNs = this.startNs !== 0\n ? performance.now() * 1e6 - this.startNs\n : 0;\n return { ...event, elapsedNs } as T;\n }\n\n onPipelineStart(event: DiagnosticEvent & { type: \"pipeline_start\" }): void {\n // Set once per collector lifetime (until an explicit reset()), not on\n // every pipeline, a multi-line evaluation pass fires pipeline_start\n // once per line, all appending to the SAME `events` array (see\n // buildLineStats() in the playground, which relies on that shared,\n // ever-growing array to slice out each line's own events via\n // cumulative-length diffing). Resetting the origin on every line meant\n // every individual line's own timestamps were self-consistent, but\n // nothing tied one line's clock to another's, any code trying to\n // compare or span timestamps ACROSS lines (e.g. \"how far into this\n // pass are we\") had no stable reference point to do it with.\n if (this.startNs === 0) {\n this.startNs = performance.now() * 1e6;\n }\n // Tracked incrementally (most-recent wins) so getReport()'s `metadata`\n // describes the line THIS report is actually about, reading\n // `events[0]` instead (the old code) froze `expression`/`inputType` on\n // the very first line ever evaluated in the session, forever, which is\n // wrong regardless of whether a field is meant to be cumulative or\n // per-line: nothing downstream ever wanted \"line 1's expression\" once\n // the document had moved on to line 50.\n this.lastExpression = event.expression;\n this.lastInputType = event.inputType;\n this.events.push(this.stamp(event));\n }\n\n onTokenEmitted(event: DiagnosticEvent & { type: \"token_emitted\" }): void {\n this.events.push(this.stamp(event));\n this.totalTokens++;\n }\n\n onNormalizerStart(event: DiagnosticEvent & { type: \"normalizer_start\" }): void {\n this.events.push(this.stamp(event));\n }\n\n onTokenFused(event: DiagnosticEvent & { type: \"token_fused\" }): void {\n this.events.push(this.stamp(event));\n }\n\n onNormalizerEnd(event: DiagnosticEvent & { type: \"normalizer_end\" }): void {\n this.events.push(this.stamp(event));\n }\n\n onParseletMatched(event: DiagnosticEvent & { type: \"parselet_matched\" }): void {\n this.events.push(this.stamp(event));\n\n const entry = this.parseletEntries.get(event.parseletCategory);\n if (entry) {\n entry.count++;\n } else {\n this.parseletEntries.set(event.parseletCategory, {\n category: event.parseletCategory,\n count: 1,\n });\n }\n\n this.parseletMatches.push({\n tokenType: event.tokenType,\n tokenValue: event.tokenValue,\n parseletCategory: event.parseletCategory,\n parseletType: event.parseletType,\n isPrefix: event.isPrefix,\n bindingPower: event.bindingPower,\n tokenOffset: event.tokenOffset,\n });\n }\n\n onBytecodeBuilt(event: DiagnosticEvent & { type: \"bytecode_built\" }): void {\n this.events.push(this.stamp(event));\n // Matches getReport()'s original behavior: the FIRST bytecode_built\n // event ever seen (not the most recent) wins, preserved as-is here\n // this rewrite only changes HOW that value is computed, not what it is.\n if (!this.hasBytecodeBuilt) {\n this.hasBytecodeBuilt = true;\n this.firstBytecodeOpcodesLength = event.opcodesLength;\n }\n }\n\n onVmStep(event: DiagnosticEvent & { type: \"vm_step\" }): void {\n this.events.push(this.stamp(event));\n this.vmStepSeen = true;\n }\n\n onVmHalt(event: DiagnosticEvent & { type: \"vm_halt\" }): void {\n this.events.push(this.stamp(event));\n }\n\n onCacheHit(event: DiagnosticEvent & { type: \"cache_hit\" }): void {\n this.events.push(this.stamp(event));\n this.cacheHitSeen = true;\n }\n\n onCacheMiss(event: DiagnosticEvent & { type: \"cache_miss\" }): void {\n this.events.push(this.stamp(event));\n }\n\n onPipelineEnd(event: DiagnosticEvent & { type: \"pipeline_end\" }): void {\n this.events.push(this.stamp(event));\n }\n\n/**\n * Build the summary/metadata/parselets report from this collector's\n * running state.\n *\n * These fields used to be recomputed by rescanning the FULL `events`\n * array on every single call (`.some()`/`.filter()`/a manual scan), since\n * `events` is never cleared except by an explicit `reset()` (which nothing\n * in `ExpressionEngine` currently calls, the cumulative-across-the-whole-\n * document design is deliberate, see `onPipelineStart`'s comment and the\n * playground's `buildLineStats()`, which slices per-line events out of\n * this ever-growing array via cumulative-length diffing), that meant\n * per-call cost grew linearly with total prior calls: O(n²) diagnostic-mode\n * evaluation over a document's lifetime. Fixed by maintaining each of these\n * incrementally as events arrive (see the `on*` handlers above), the same\n * pattern already used for `parseletEntries`. Every value produced here is\n * identical to what the old rescanning code produced, including its\n * existing \"first bytecode_built event wins\" quirk. This is a performance\n * fix, not a behavior change.\n */\ngetReport(): DiagnosticReport | undefined {\n if (this.events.length === 0) return undefined;\n\n const elapsedNs = performance.now() * 1e6 - this.startNs;\n\n const parseCategories = new Map<string, number>();\n for (const [, entry] of this.parseletEntries) {\n parseCategories.set(entry.category, entry.count);\n }\n\n const totalOpcodes = this.firstBytecodeOpcodesLength;\n const cacheHit = this.cacheHitSeen;\n const totalTokens = this.totalTokens;\n\n const report: DiagnosticReport = {\n events: this.events,\n parselets: this.parseletMatches.map((e) => ({ ...e })),\n summary: {\n totalTokens,\n totalParselets: parseCategories.size,\n totalOpcodes,\n cacheHit,\n elapsedNs,\n parseCategories,\n },\n metadata: {\n expression: this.lastExpression,\n inputType: this.lastInputType,\n timestamp: Date.now(),\n vmTraceEnabled: this.vmStepSeen,\n },\n toJSON(): DiagnosticReportJSON {\n return {\n events: report.events,\n parselets: report.parselets,\n summary: {\n totalTokens: report.summary.totalTokens,\n totalParselets: report.summary.totalParselets,\n totalOpcodes: report.summary.totalOpcodes,\n cacheHit: report.summary.cacheHit,\n elapsedNs: report.summary.elapsedNs,\n parseCategories: Object.fromEntries(report.summary.parseCategories),\n },\n metadata: { ...report.metadata },\n };\n },\n };\n\n return report;\n }\n}","\n\nimport type { MatrixData, RangeData, ColourData } from \"@solve-js/vm/Value\";\nimport type { SymbolicNode } from \"@solve-js/symbolic\";\n\n/**\n * Diagnostic event types as string constants (not const enum, for cross-module compatibility with isolatedModules)\n */\nexport const DiagnosticEventType = {\n TokenEmitted: \"token_emitted\",\n NormalizerStart: \"normalizer_start\",\n TokenFused: \"token_fused\",\n NormalizerEnd: \"normalizer_end\",\n ParseletMatched: \"parselet_matched\",\n BytecodeBuilt: \"bytecode_built\",\n VmStep: \"vm_step\",\n VmHalt: \"vm_halt\",\n CacheHit: \"cache_hit\",\n CacheMiss: \"cache_miss\",\n PipelineStart: \"pipeline_start\",\n PipelineEnd: \"pipeline_end\",\n} as const;\n\n/** Discriminator naming which pipeline event a diagnostic record describes. */\nexport type EventType = (typeof DiagnosticEventType)[keyof typeof DiagnosticEventType];\n\n/** Base event, all events include a timestamp relative to pipeline start */\nexport interface BaseEvent {\n readonly type: string;\n readonly elapsedNs: number;\n readonly expression: string;\n}\n\n/** Emitted after each token is produced by the lexer */\nexport interface TokenEmittedEvent extends BaseEvent {\n readonly type: \"token_emitted\";\n readonly token: {\n readonly type: string;\n readonly value: string;\n readonly offset: number;\n readonly line: number;\n readonly col: number;\n };\n}\n\n/** Emitted when the parser resolves a parselet for a token */\nexport interface ParseletMatchedEvent extends BaseEvent {\n readonly type: \"parselet_matched\";\n readonly tokenType: string;\n readonly tokenValue: string;\n readonly parseletCategory: string;\n readonly parseletType: string;\n readonly isPrefix: boolean;\n readonly bindingPower?: number;\n readonly tokenOffset: number;\n}\n\n/** Emitted after bytecode is built */\nexport interface BytecodeBuiltEvent extends BaseEvent {\n readonly type: \"bytecode_built\";\n readonly opcodesLength: number;\n readonly numbersLength: number;\n readonly stringsLength: number;\n readonly isCached: boolean;\n}\n\n/** Emitted after each VM opcode execution (only when vmTrace is enabled) */\nexport interface VmStepEvent extends BaseEvent {\n readonly type: \"vm_step\";\n readonly opcode: number;\n readonly opcodeName: string;\n readonly ip: number;\n readonly stackDepth: number;\n readonly instructionNumber: number;\n readonly stack: ReadonlyArray<{\n readonly type: number;\n readonly value: number | bigint | string | boolean | MatrixData | RangeData | ColourData | SymbolicNode;\n readonly unit?: string;\n }>;\n}\n\n/** Emitted when the VM halts with a result */\nexport interface VmHaltEvent extends BaseEvent {\n readonly type: \"vm_halt\";\n readonly result?: {\n readonly type: number;\n readonly value: number | bigint | string | boolean | MatrixData | RangeData | ColourData | SymbolicNode;\n readonly unit?: string;\n };\n}\n\n/** Emitted on cache hit */\nexport interface CacheHitEvent extends BaseEvent {\n readonly type: \"cache_hit\";\n readonly cache: \"bytecode\" | \"line\";\n readonly key: string;\n}\n\n/** Emitted on cache miss */\nexport interface CacheMissEvent extends BaseEvent {\n readonly type: \"cache_miss\";\n readonly cache: \"bytecode\" | \"line\";\n readonly key: string;\n}\n\n/** Emitted when a pipeline evaluation begins */\nexport interface PipelineStartEvent extends BaseEvent {\n readonly type: \"pipeline_start\";\n readonly inputType: string;\n}\n\n/** Emitted when a pipeline evaluation completes */\nexport interface PipelineEndEvent extends BaseEvent {\n readonly type: \"pipeline_end\";\n readonly success: boolean;\n readonly error?: string;\n readonly totalTokens: number;\n readonly totalOpcodes: number;\n}\n\n/** Emitted when the normalizer begins its pass */\nexport interface NormalizerStartEvent extends BaseEvent {\n readonly type: \"normalizer_start\";\n readonly inputTokenCount: number;\n}\n\n/** Emitted when the normalizer fuses tokens */\nexport interface TokenFusedEvent extends BaseEvent {\n readonly type: \"token_fused\";\n readonly ruleName: string;\n readonly sourceTokenCount: number;\n readonly fusedTokenType: string;\n readonly fusedTokenValue: string;\n}\n\n/** Emitted when the normalizer completes its pass */\nexport interface NormalizerEndEvent extends BaseEvent {\n readonly type: \"normalizer_end\";\n readonly outputTokenCount: number;\n readonly fusionsCount: number;\n}\n\n/** Union of all event types */\nexport type DiagnosticEvent =\n | TokenEmittedEvent\n | NormalizerStartEvent\n | TokenFusedEvent\n | NormalizerEndEvent\n | ParseletMatchedEvent\n | BytecodeBuiltEvent\n | VmStepEvent\n | VmHaltEvent\n | CacheHitEvent\n | CacheMissEvent\n | PipelineStartEvent\n | PipelineEndEvent;\n\n/** Categorized parselet info */\nexport interface CategorizedParselet {\n readonly tokenType: string;\n readonly tokenValue: string;\n readonly parseletCategory: string;\n readonly parseletType: string;\n readonly isPrefix: boolean;\n readonly bindingPower?: number;\n readonly tokenOffset: number;\n}\n\n/** JSON-serializable representation of a DiagnosticReport */\nexport interface DiagnosticReportJSON {\n readonly events: readonly DiagnosticEvent[];\n readonly parselets: readonly CategorizedParselet[];\n readonly summary: {\n readonly totalTokens: number;\n readonly totalParselets: number;\n readonly totalOpcodes: number;\n readonly cacheHit: boolean;\n readonly elapsedNs: number;\n readonly parseCategories: Record<string, number>;\n };\n readonly metadata: {\n readonly expression: string;\n readonly inputType: string;\n readonly timestamp: number;\n readonly vmTraceEnabled: boolean;\n };\n}\n\n/** Structured diagnostic report */\nexport interface DiagnosticReport {\n readonly events: readonly DiagnosticEvent[];\n readonly parselets: readonly CategorizedParselet[];\n readonly summary: {\n readonly totalTokens: number;\n readonly totalParselets: number;\n readonly totalOpcodes: number;\n readonly cacheHit: boolean;\n readonly elapsedNs: number;\n readonly parseCategories: ReadonlyMap<string, number>;\n };\n readonly metadata: {\n readonly expression: string;\n readonly inputType: string;\n readonly timestamp: number;\n readonly vmTraceEnabled: boolean;\n };\n\n /** Serialize to a JSON-safe plain object */\n toJSON(): DiagnosticReportJSON;\n}\n\n/** JSON-serializable representation of a DiagnosticReport */\nexport interface DiagnosticReportJSON {\n readonly events: readonly DiagnosticEvent[];\n readonly parselets: readonly CategorizedParselet[];\n readonly summary: {\n readonly totalTokens: number;\n readonly totalParselets: number;\n readonly totalOpcodes: number;\n readonly cacheHit: boolean;\n readonly elapsedNs: number;\n readonly parseCategories: Record<string, number>;\n };\n readonly metadata: {\n readonly expression: string;\n readonly inputType: string;\n readonly timestamp: number;\n readonly vmTraceEnabled: boolean;\n };\n}"]}
|
|
@@ -0,0 +1,219 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var chunkN7FNVFXW_cjs = require('./chunk-N7FNVFXW.cjs');
|
|
4
|
+
var chunkALYRJ72W_cjs = require('./chunk-ALYRJ72W.cjs');
|
|
5
|
+
var chunkHIQ5HSZL_cjs = require('./chunk-HIQ5HSZL.cjs');
|
|
6
|
+
var chunkOUHT5Z36_cjs = require('./chunk-OUHT5Z36.cjs');
|
|
7
|
+
|
|
8
|
+
// src/format/FormattingSettings.ts
|
|
9
|
+
var DEFAULT_FORMATTING_SETTINGS = {
|
|
10
|
+
floatResult: {
|
|
11
|
+
decimalPlaces: 2,
|
|
12
|
+
enableSeperator: true
|
|
13
|
+
},
|
|
14
|
+
numberResult: {
|
|
15
|
+
decimalSeparatorLocale: "en-US"
|
|
16
|
+
},
|
|
17
|
+
hexResult: {
|
|
18
|
+
enablePadding: false,
|
|
19
|
+
paddingZeros: 0
|
|
20
|
+
},
|
|
21
|
+
unitOfMeasurementResult: {
|
|
22
|
+
decimalPlaces: 2
|
|
23
|
+
},
|
|
24
|
+
percentageResult: {
|
|
25
|
+
decimalPlaces: 2
|
|
26
|
+
}
|
|
27
|
+
};
|
|
28
|
+
|
|
29
|
+
// src/format/FormatEngine.ts
|
|
30
|
+
function formatNumber(value, locale, settings, decimalPlaces) {
|
|
31
|
+
const sep = settings.floatResult.enableSeperator;
|
|
32
|
+
const loc = settings.numberResult.decimalSeparatorLocale;
|
|
33
|
+
if (decimalPlaces !== void 0 && Number.isFinite(value)) {
|
|
34
|
+
const formatted2 = value.toLocaleString(loc || "en-US", {
|
|
35
|
+
minimumFractionDigits: decimalPlaces,
|
|
36
|
+
maximumFractionDigits: decimalPlaces,
|
|
37
|
+
useGrouping: sep
|
|
38
|
+
});
|
|
39
|
+
return `${locale.display.resultPrefix}${formatted2}`;
|
|
40
|
+
}
|
|
41
|
+
const dp = settings.floatResult.decimalPlaces;
|
|
42
|
+
const formatted = chunkN7FNVFXW_cjs.autoFormatIntegerOrFloat(value, dp, sep, loc);
|
|
43
|
+
return `${locale.display.resultPrefix}${formatted}`;
|
|
44
|
+
}
|
|
45
|
+
function formatUncertain(center, uncertainty, locale, settings) {
|
|
46
|
+
const dp = settings.floatResult.decimalPlaces;
|
|
47
|
+
const useGrouping = settings.floatResult.enableSeperator;
|
|
48
|
+
const loc = settings.numberResult.decimalSeparatorLocale || "en-US";
|
|
49
|
+
const spreadMax = Math.max(dp, 1);
|
|
50
|
+
const centerText = center.toLocaleString(loc, { useGrouping, minimumFractionDigits: 0, maximumFractionDigits: dp });
|
|
51
|
+
const spreadText = Math.abs(uncertainty).toLocaleString(loc, { useGrouping, minimumFractionDigits: 1, maximumFractionDigits: spreadMax });
|
|
52
|
+
return `${locale.display.resultPrefix}${centerText} \xB1 ${spreadText}`;
|
|
53
|
+
}
|
|
54
|
+
function formatHex(value, settings, base) {
|
|
55
|
+
if (typeof value === "number" && !Number.isFinite(value)) return `= ${value}`;
|
|
56
|
+
const negative = typeof value === "bigint" ? value < 0n : value < 0;
|
|
57
|
+
const sign = negative ? "-" : "";
|
|
58
|
+
const digits = (radix) => typeof value === "bigint" ? (negative ? -value : value).toString(radix) : Math.abs(Math.trunc(value)).toString(radix);
|
|
59
|
+
if (base === "bin") return `= ${sign}0b${digits(2)}`;
|
|
60
|
+
if (base === "oct") return `= ${sign}0o${digits(8)}`;
|
|
61
|
+
const padding = settings.hexResult.enablePadding ? settings.hexResult.paddingZeros : 0;
|
|
62
|
+
const hex = digits(16).toUpperCase().padStart(padding, "0");
|
|
63
|
+
return `= ${sign}0x${hex}`;
|
|
64
|
+
}
|
|
65
|
+
var MAX_DISPLAYED_BIGINT_DIGITS = 2e4;
|
|
66
|
+
function formatBigInt(value) {
|
|
67
|
+
const magnitude = value < 0n ? -value : value;
|
|
68
|
+
if (Number.isFinite(Number(magnitude))) return `= ${value}`;
|
|
69
|
+
const bits = magnitude.toString(16).length * 4;
|
|
70
|
+
if (bits * Math.LN2 / Math.LN10 <= MAX_DISPLAYED_BIGINT_DIGITS) return `= ${value}`;
|
|
71
|
+
const log10 = bits * Math.LN2 / Math.LN10;
|
|
72
|
+
const exponent = Math.floor(log10);
|
|
73
|
+
const mantissa = Math.pow(10, log10 - exponent);
|
|
74
|
+
const sign = value < 0n ? "-" : "";
|
|
75
|
+
return `= ${sign}~${mantissa.toFixed(3)}e+${exponent} (an exact integer of about ${(exponent + 1).toLocaleString("en-US")} digits, too large to print)`;
|
|
76
|
+
}
|
|
77
|
+
function formatString(value) {
|
|
78
|
+
return `= ${value}`;
|
|
79
|
+
}
|
|
80
|
+
function formatBoolean(value) {
|
|
81
|
+
return `= ${value}`;
|
|
82
|
+
}
|
|
83
|
+
function formatDatetime(value, locale) {
|
|
84
|
+
const d = new Date(value);
|
|
85
|
+
const dateStr = d.toLocaleDateString(locale.code, { weekday: "long", year: "numeric", month: "long", day: "numeric" });
|
|
86
|
+
const isMidnight = d.getHours() === 0 && d.getMinutes() === 0 && d.getSeconds() === 0 && d.getMilliseconds() === 0;
|
|
87
|
+
if (isMidnight) return `= ${dateStr}`;
|
|
88
|
+
return `= ${dateStr}, ${d.toLocaleTimeString(locale.code)}`;
|
|
89
|
+
}
|
|
90
|
+
function formatMsDuration(ms) {
|
|
91
|
+
const sign = ms < 0 ? "-" : "";
|
|
92
|
+
const totalSeconds = Math.round(Math.abs(ms) / 1e3);
|
|
93
|
+
const hours = Math.floor(totalSeconds / 3600);
|
|
94
|
+
const minutes = Math.floor(totalSeconds % 3600 / 60);
|
|
95
|
+
const seconds = totalSeconds % 60;
|
|
96
|
+
const mm = String(minutes).padStart(2, "0");
|
|
97
|
+
if (seconds === 0) return `${sign}${hours}:${mm}`;
|
|
98
|
+
const ss = String(seconds).padStart(2, "0");
|
|
99
|
+
return `${sign}${hours}:${mm}:${ss}`;
|
|
100
|
+
}
|
|
101
|
+
function formatUom(value, unit, locale, settings, exact) {
|
|
102
|
+
if (unit === "ms") return `= ${formatMsDuration(value)}`;
|
|
103
|
+
const dp = settings.unitOfMeasurementResult.decimalPlaces;
|
|
104
|
+
const timeSpanUnits = ["days", "weeks", "hours", "minutes", "seconds", "day", "week", "hour", "minute", "second"];
|
|
105
|
+
const isTimeSpan = unit && timeSpanUnits.includes(unit);
|
|
106
|
+
let formatted;
|
|
107
|
+
if (isTimeSpan && value === Math.floor(value)) {
|
|
108
|
+
formatted = value.toString();
|
|
109
|
+
} else {
|
|
110
|
+
formatted = value.toFixed(dp);
|
|
111
|
+
}
|
|
112
|
+
const currencyDisplay = unit ? chunkHIQ5HSZL_cjs.CURRENCY_DISPLAY[unit.toUpperCase()] : void 0;
|
|
113
|
+
if (currencyDisplay) {
|
|
114
|
+
const moneyText = exact ? chunkHIQ5HSZL_cjs.decimalToFixed(exact, dp) : formatted;
|
|
115
|
+
const sep = currencyDisplay.spaced ? " " : "";
|
|
116
|
+
const withSymbol = currencyDisplay.position === "prefix" ? `${currencyDisplay.symbol}${sep}${moneyText}` : `${moneyText}${sep}${currencyDisplay.symbol}`;
|
|
117
|
+
return `= ${withSymbol}`;
|
|
118
|
+
}
|
|
119
|
+
const genericText = exact ? chunkHIQ5HSZL_cjs.decimalToFixed(exact, dp) : formatted;
|
|
120
|
+
return `= ${genericText} ${unit || ""}`.trim();
|
|
121
|
+
}
|
|
122
|
+
function formatMatrixEntry(entry, settings) {
|
|
123
|
+
if (typeof entry === "boolean") return entry ? "true" : "false";
|
|
124
|
+
if (typeof entry === "object" && entry !== null) return chunkHIQ5HSZL_cjs.formatSymbolic(entry);
|
|
125
|
+
const dp = settings.floatResult.decimalPlaces;
|
|
126
|
+
const sep = settings.floatResult.enableSeperator;
|
|
127
|
+
const loc = settings.numberResult.decimalSeparatorLocale;
|
|
128
|
+
return chunkN7FNVFXW_cjs.autoFormatIntegerOrFloat(entry, dp, sep, loc);
|
|
129
|
+
}
|
|
130
|
+
function formatMatrix(m, locale, settings) {
|
|
131
|
+
const rowMajor = chunkHIQ5HSZL_cjs.columnMajorToRowMajor(m);
|
|
132
|
+
const rows = [];
|
|
133
|
+
for (let r = 0; r < m.rows; r++) {
|
|
134
|
+
const cells = [];
|
|
135
|
+
for (let c = 0; c < m.cols; c++) {
|
|
136
|
+
cells.push(formatMatrixEntry(rowMajor[r * m.cols + c], settings));
|
|
137
|
+
}
|
|
138
|
+
rows.push(cells.join(", "));
|
|
139
|
+
}
|
|
140
|
+
return `${locale.display.resultPrefix}[${rows.join("; ")}]`;
|
|
141
|
+
}
|
|
142
|
+
function formatMatrixAligned(m, settings) {
|
|
143
|
+
const us = settings || DEFAULT_FORMATTING_SETTINGS;
|
|
144
|
+
const rowMajor = chunkHIQ5HSZL_cjs.columnMajorToRowMajor(m);
|
|
145
|
+
const cells = [];
|
|
146
|
+
for (let r = 0; r < m.rows; r++) {
|
|
147
|
+
const row = [];
|
|
148
|
+
for (let c = 0; c < m.cols; c++) {
|
|
149
|
+
row.push(formatMatrixEntry(rowMajor[r * m.cols + c], us));
|
|
150
|
+
}
|
|
151
|
+
cells.push(row);
|
|
152
|
+
}
|
|
153
|
+
const colWidth = [];
|
|
154
|
+
for (let c = 0; c < m.cols; c++) {
|
|
155
|
+
let width = 0;
|
|
156
|
+
for (let r = 0; r < m.rows; r++) width = Math.max(width, cells[r][c].length);
|
|
157
|
+
colWidth.push(width);
|
|
158
|
+
}
|
|
159
|
+
return cells.map((row) => `[ ${row.map((cell, c) => cell.padStart(colWidth[c])).join(" ")} ]`).join("\n");
|
|
160
|
+
}
|
|
161
|
+
function formatRange(min, max, locale) {
|
|
162
|
+
return `${locale.display.resultPrefix}${min}:${max}`;
|
|
163
|
+
}
|
|
164
|
+
function formatPercentage(value, locale, settings) {
|
|
165
|
+
const dp = settings.percentageResult.decimalPlaces;
|
|
166
|
+
const formatted = (value * 100).toFixed(dp);
|
|
167
|
+
return `= ${formatted}${locale.display.percentageSuffix}`;
|
|
168
|
+
}
|
|
169
|
+
function formatUnit(value, unit) {
|
|
170
|
+
return `= ${value} ${unit || ""}`.trim();
|
|
171
|
+
}
|
|
172
|
+
function formatValue(value, settings) {
|
|
173
|
+
const us = settings || DEFAULT_FORMATTING_SETTINGS;
|
|
174
|
+
const localeCode = us.numberResult.decimalSeparatorLocale || "en";
|
|
175
|
+
const locale = chunkOUHT5Z36_cjs.getLocale(localeCode);
|
|
176
|
+
switch (value.type) {
|
|
177
|
+
case 0 /* Number */:
|
|
178
|
+
if (value.uncertainty !== void 0) {
|
|
179
|
+
return formatUncertain(value.value, value.uncertainty, locale, us);
|
|
180
|
+
}
|
|
181
|
+
return formatNumber(value.value, locale, us, value.decimalPlaces);
|
|
182
|
+
case 1 /* Hex */:
|
|
183
|
+
return formatHex(value.value, us, value.unit);
|
|
184
|
+
case 2 /* BigInt */:
|
|
185
|
+
return formatBigInt(value.value);
|
|
186
|
+
case 3 /* String */:
|
|
187
|
+
return formatString(value.value);
|
|
188
|
+
case 10 /* Boolean */:
|
|
189
|
+
return formatBoolean(value.value);
|
|
190
|
+
case 4 /* Datetime */:
|
|
191
|
+
return formatDatetime(value.value, locale);
|
|
192
|
+
case 6 /* Uom */:
|
|
193
|
+
return formatUom(value.value, value.unit, locale, us, value.exact);
|
|
194
|
+
case 7 /* Matrix */:
|
|
195
|
+
return formatMatrix(value.value, locale, us);
|
|
196
|
+
case 8 /* Range */: {
|
|
197
|
+
const r = value.value;
|
|
198
|
+
return formatRange(r.min, r.max, locale);
|
|
199
|
+
}
|
|
200
|
+
case 14 /* Colour */:
|
|
201
|
+
return `${locale.display.resultPrefix}${chunkALYRJ72W_cjs.formatColour(value.value)}`;
|
|
202
|
+
case 9 /* Symbolic */:
|
|
203
|
+
return chunkHIQ5HSZL_cjs.formatSymbolic(value.value);
|
|
204
|
+
case 5 /* Percentage */:
|
|
205
|
+
return formatPercentage(value.value, locale, us);
|
|
206
|
+
case 11 /* Unit */:
|
|
207
|
+
return formatUnit(value.value, value.unit);
|
|
208
|
+
case 13 /* Error */:
|
|
209
|
+
return value.unit ?? String(value.value);
|
|
210
|
+
default:
|
|
211
|
+
return `= ${String(value.value)}`;
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
exports.DEFAULT_FORMATTING_SETTINGS = DEFAULT_FORMATTING_SETTINGS;
|
|
216
|
+
exports.formatMatrixAligned = formatMatrixAligned;
|
|
217
|
+
exports.formatValue = formatValue;
|
|
218
|
+
//# sourceMappingURL=chunk-CKQMXMHR.cjs.map
|
|
219
|
+
//# sourceMappingURL=chunk-CKQMXMHR.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/format/FormattingSettings.ts","../src/format/FormatEngine.ts"],"names":["formatted","autoFormatIntegerOrFloat","CURRENCY_DISPLAY","decimalToFixed","formatSymbolic","columnMajorToRowMajor","getLocale","formatColour"],"mappings":"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","file":"chunk-CKQMXMHR.cjs","sourcesContent":["/**\n * Minimal formatting settings interface for the engine\n * This allows the engine to format values without depending on app-specific settings\n */\nexport interface FormattingSettings {\n floatResult: {\n decimalPlaces: number;\n enableSeperator: boolean;\n };\n numberResult: {\n decimalSeparatorLocale: string;\n };\n hexResult: {\n enablePadding: boolean;\n paddingZeros: number;\n };\n unitOfMeasurementResult: {\n decimalPlaces: number;\n };\n percentageResult: {\n decimalPlaces: number;\n };\n}\n\n/** Formatting used when a host supplies none. */\nexport const DEFAULT_FORMATTING_SETTINGS: FormattingSettings = {\n floatResult: {\n decimalPlaces: 2,\n enableSeperator: true,\n },\n numberResult: {\n decimalSeparatorLocale: \"en-US\",\n },\n hexResult: {\n enablePadding: false,\n paddingZeros: 0,\n },\n unitOfMeasurementResult: {\n decimalPlaces: 2,\n },\n percentageResult: {\n decimalPlaces: 2,\n },\n};\n","import { Value, ValueType, type MatrixData, type MatrixEntry, type RangeData, type ColourData } from \"@solve-js/vm/Value\";\nimport { formatColour } from \"@solve-js/packages/colour/ColourMath\";\nimport { decimalToFixed, type DecimalData } from \"@solve-js/decimal\";\nimport { getLocale, type ILocale } from \"@solve-js/constants/locales\";\nimport { autoFormatIntegerOrFloat } from \"@solve-js/utilities/Number\";\nimport { FormattingSettings, DEFAULT_FORMATTING_SETTINGS } from \"./FormattingSettings\";\nimport { CURRENCY_DISPLAY } from \"@solve-js/uom/CurrencyAliases\";\nimport { columnMajorToRowMajor } from \"@solve-js/vm/MatrixOps\";\nimport { formatSymbolic, type SymbolicNode } from \"@solve-js/symbolic\";\n\nfunction formatNumber(value: number, locale: ILocale, settings: FormattingSettings, decimalPlaces?: number): string {\n const sep = settings.floatResult.enableSeperator;\n const loc = settings.numberResult.decimalSeparatorLocale;\n // An explicit precision (`3.14159 to 4 dp`, `round(1.5, 2)`) shows EXACTLY that\n // many places with trailing zeros kept, where the default trims them and shows\n // an integer with none. The value was already rounded to this precision when\n // it was set (see VMBuiltins' roundToPlaces, exact where an exact decimal was\n // there), so rendering it to the same place count reproduces that rounding.\n if (decimalPlaces !== undefined && Number.isFinite(value)) {\n const formatted = value.toLocaleString(loc || \"en-US\", {\n minimumFractionDigits: decimalPlaces,\n maximumFractionDigits: decimalPlaces,\n useGrouping: sep,\n });\n return `${locale.display.resultPrefix}${formatted}`;\n }\n const dp = settings.floatResult.decimalPlaces;\n const formatted = autoFormatIntegerOrFloat(value, dp, sep, loc);\n return `${locale.display.resultPrefix}${formatted}`;\n}\n\n/**\n * Renders a measurement that carries a one-sigma uncertainty as\n * `center ± spread`, e.g. `49.2 ± 2.0`.\n *\n * The center is shown the way any number is, whole numbers as integers and\n * trailing zeros trimmed, so a tolerance-free-looking center still reads\n * cleanly (\"30 ± 2.24\", not \"30.00 ± 2.24\"). The spread is shown to the same\n * decimal-place budget but always keeps at least one fractional digit, which is\n * what distinguishes it as a tolerance and gives \"± 2.0\" rather than \"± 2\".\n * Both use `Intl` with `maximumFractionDigits`, so the trailing-zero trimming is\n * locale-correct (a comma-decimal locale is not string-sliced on \".\").\n *\n * The symbol is always the `±` glyph on output, even when the input was the\n * ASCII `+/-`, since the glyph is the conventional notation and unambiguous to\n * read back.\n */\nfunction formatUncertain(center: number, uncertainty: number, locale: ILocale, settings: FormattingSettings): string {\n const dp = settings.floatResult.decimalPlaces;\n const useGrouping = settings.floatResult.enableSeperator;\n const loc = settings.numberResult.decimalSeparatorLocale || \"en-US\";\n // The spread needs room for at least one fractional digit, so a zero-decimal\n // budget cannot leave minimumFractionDigits above maximumFractionDigits.\n const spreadMax = Math.max(dp, 1);\n const centerText = center.toLocaleString(loc, { useGrouping, minimumFractionDigits: 0, maximumFractionDigits: dp });\n const spreadText = Math.abs(uncertainty).toLocaleString(loc, { useGrouping, minimumFractionDigits: 1, maximumFractionDigits: spreadMax });\n return `${locale.display.resultPrefix}${centerText} ± ${spreadText}`;\n}\n\n/**\n * Renders a number in whichever base it is tagged with.\n *\n * The zero padding is a hexadecimal setting and stays one. Applying it to a\n * binary rendering would pad `0b101` out to the same digit count as a hex\n * value, which is a different quantity of zeros and not what the setting asks\n * for.\n */\nfunction formatHex(value: number | bigint, settings: FormattingSettings, base?: string): string {\n // An infinity or a NaN has no digits in any base, and asking for them\n // produced `0xINFINITY`, a literal that reads back as nothing at all. Render\n // the value itself, which is what every other non-finite result shows.\n if (typeof value === \"number\" && !Number.isFinite(value)) return `= ${value}`;\n\n // Truncate and take the sign off before converting. `Number.toString(radix)`\n // does neither: it renders -255 as \"-ff\", which lands the minus inside the\n // literal as `0x-FF`, and it renders 255.7 as \"ff.b3333333333\", inventing\n // fractional hex digits for a notation that has no use for them. Both were\n // visible on `as hex` until the builtins started sharing this path.\n //\n // A bigint needs neither truncation nor a Math call, and must not be routed\n // through one: passing it to Math.trunc() throws, and converting it to a\n // double first is exactly the precision loss it is carried as a bigint to\n // avoid.\n const negative = typeof value === \"bigint\" ? value < 0n : value < 0;\n const sign = negative ? \"-\" : \"\";\n const digits = (radix: number): string =>\n typeof value === \"bigint\"\n ? (negative ? -value : value).toString(radix)\n : Math.abs(Math.trunc(value)).toString(radix);\n\n if (base === \"bin\") return `= ${sign}0b${digits(2)}`;\n if (base === \"oct\") return `= ${sign}0o${digits(8)}`;\n const padding = settings.hexResult.enablePadding ? settings.hexResult.paddingZeros : 0;\n const hex = digits(16).toUpperCase().padStart(padding, \"0\");\n return `= ${sign}0x${hex}`;\n}\n\n/**\n * How many decimal digits of an exact integer this will render in full.\n *\n * A little above the ~19,729 digits of the largest bigint the VM will build\n * (`vm/VM.ts`'s MAX_EXACT_POW_BITS / MAX_EXACT_SHIFT_BITS, 65,536 bits), so\n * every value the engine can produce through `^` or `<<` still prints exactly\n * and this ceiling only ever meets a value that came from somewhere else.\n */\nconst MAX_DISPLAYED_BIGINT_DIGITS = 20000;\n\n/**\n * Renders an exact integer, or describes it when writing it out is itself the\n * expensive operation.\n *\n * This used to be a bare `= ${value}` template, which renders whatever it is\n * handed: `1n << 100000000` took 8.5 seconds here turning a 12.5MB integer\n * into a thirty-million-character string, and a host has no way to opt out,\n * since displaying the answer is what it asked the engine for. The VM's own\n * ceiling on `<<` and `^` now stops that value existing, so this is the\n * backstop for every other way a large bigint can arrive (repeated `x * x`,\n * a Value a host built itself), and it costs one comparison for every value\n * that is not absurd.\n *\n * The digit count is estimated from the bit length rather than measured, since\n * measuring means doing the conversion this exists to avoid. Bit length comes\n * off the hexadecimal form, which is linear in the size of the value where the\n * decimal form is not.\n */\nfunction formatBigInt(value: bigint): string {\n const magnitude = value < 0n ? -value : value;\n // Every bigint a person actually reads takes this line and nothing else:\n // anything a double can hold is at most 309 digits, so it is printable\n // without measuring it at all.\n if (Number.isFinite(Number(magnitude))) return `= ${value}`;\n const bits = magnitude.toString(16).length * 4;\n if (bits * Math.LN2 / Math.LN10 <= MAX_DISPLAYED_BIGINT_DIGITS) return `= ${value}`;\n const log10 = bits * Math.LN2 / Math.LN10;\n const exponent = Math.floor(log10);\n const mantissa = Math.pow(10, log10 - exponent);\n const sign = value < 0n ? \"-\" : \"\";\n return `= ${sign}~${mantissa.toFixed(3)}e+${exponent} (an exact integer of about ${(exponent + 1).toLocaleString(\"en-US\")} digits, too large to print)`;\n}\n\nfunction formatString(value: string): string {\n return `= ${value}`;\n}\n\nfunction formatBoolean(value: boolean): string {\n return `= ${value}`;\n}\n\n/**\n * Renders a Datetime value locale-aware, the previous implementation\n * called `d.toLocaleString()` with no arguments, which always uses the JS\n * runtime's own default locale and never actually consulted `locale.code`\n * despite receiving it as a parameter (both branches of its old\n * `dateFormat === \"default\"` check were byte-for-byte identical, dead\n * groundwork for a distinction that was never implemented). Concretely,\n * this meant every configured locale (including the shipped German one)\n * always displayed weekday/month names in English. See GitHub issue #77.\n *\n * Uses `weekday`/`month`: \"long\" for a spelled-out date (\"Monday,\n * November 17, 2025\" / \"lundi 17 novembre 2025\") since that's what a\n * literal weekday name is for; a bare numeric date doesn't need\n * localizing beyond the decimal/thousands separators `formatNumber()`\n * already handles. The time-of-day portion is only appended when it's\n * not exactly local midnight, bare date literals (\"today\", \"17/11/2025\")\n * always anchor to local midnight, and showing \"00:00:00\" on every one of\n * those would be noise, not information.\n */\nfunction formatDatetime(value: number, locale: ILocale): string {\n const d = new Date(value);\n const dateStr = d.toLocaleDateString(locale.code, { weekday: \"long\", year: \"numeric\", month: \"long\", day: \"numeric\" });\n const isMidnight = d.getHours() === 0 && d.getMinutes() === 0 && d.getSeconds() === 0 && d.getMilliseconds() === 0;\n if (isMidnight) return `= ${dateStr}`;\n return `= ${dateStr}, ${d.toLocaleTimeString(locale.code)}`;\n}\n\n/**\n * Renders a millisecond duration as clock-style `H:MM` (or `H:MM:SS` when\n * there's a non-zero seconds component). `ms` is never a user-typeable\n * unit (confirmed: it appears nowhere in `lexer/units.ts`), it's only\n * ever produced by subtracting two clock times/datetimes (`9:30 - 8:30`,\n * `VM.ts`'s Datetime SUB case), so this is a safe, narrow special case,\n * not a general change to how durations display.\n */\nfunction formatMsDuration(ms: number): string {\n const sign = ms < 0 ? \"-\" : \"\";\n const totalSeconds = Math.round(Math.abs(ms) / 1000);\n const hours = Math.floor(totalSeconds / 3600);\n const minutes = Math.floor((totalSeconds % 3600) / 60);\n const seconds = totalSeconds % 60;\n const mm = String(minutes).padStart(2, \"0\");\n if (seconds === 0) return `${sign}${hours}:${mm}`;\n const ss = String(seconds).padStart(2, \"0\");\n return `${sign}${hours}:${mm}:${ss}`;\n}\n\nfunction formatUom(value: number, unit: string | undefined, locale: ILocale, settings: FormattingSettings, exact?: DecimalData): string {\n if (unit === \"ms\") return `= ${formatMsDuration(value)}`;\n\n const dp = settings.unitOfMeasurementResult.decimalPlaces;\n\n // For TimeSpan values (days, weeks, hours, etc.), format as integer if the value is a whole number\n const timeSpanUnits = [\"days\", \"weeks\", \"hours\", \"minutes\", \"seconds\", \"day\", \"week\", \"hour\", \"minute\", \"second\"];\n const isTimeSpan = unit && timeSpanUnits.includes(unit);\n\n let formatted: string;\n if (isTimeSpan && value === Math.floor(value)) {\n // For whole number TimeSpan values, format as integer\n formatted = value.toString();\n } else {\n // For other values, use the configured decimal places\n formatted = value.toFixed(dp);\n }\n\n // Currency display: symbol + culturally-conventional placement (e.g.\n // \"$100.00\" prefix vs \"100.00 kr\" suffix) instead of the generic\n // \"amount CODE\" fallback below. See uom/CurrencyAliases.ts's\n // CURRENCY_DISPLAY table for the exact set covered and the reasoning\n // behind each placement choice. Any currency code NOT in that table\n // (most of the ~150 `CurrencyExchange.isCurrency()` recognizes) falls\n // through to the unchanged \"amount CODE\" format below.\n const currencyDisplay = unit ? CURRENCY_DISPLAY[unit.toUpperCase()] : undefined;\n if (currencyDisplay) {\n // An exact money amount rounds from its decimal, not from the double: a\n // half-cent like \"$1.005\" reads as \"$1.01\" here, where \"(1.005).toFixed(2)\"\n // answers \"1.00\" because the double it is handed already sits below the\n // value the user typed. Amounts with no exact decimal (a currency\n // conversion, whose rate is a double) keep the toFixed rendering above.\n const moneyText = exact ? decimalToFixed(exact, dp) : formatted;\n const sep = currencyDisplay.spaced ? \" \" : \"\";\n const withSymbol = currencyDisplay.position === \"prefix\"\n ? `${currencyDisplay.symbol}${sep}${moneyText}`\n : `${moneyText}${sep}${currencyDisplay.symbol}`;\n return `= ${withSymbol}`;\n }\n\n // The unit is written as the symbol the value carries. There used to be a\n // `unitOfMeasurementResult.unitNames` setting here whose two branches were\n // the same expression, so it never changed anything, and it was removed\n // rather than implemented: the engine has no unit-name data to render from.\n // The generated unit table maps a spelling to [measure, ratio] only, and\n // names cannot be recovered from it, because units that differ by an OFFSET\n // share a ratio, so \"20 C\" would come back as \"20 kelvins\". A real\n // implementation needs a hand-authored name per unit plus pluralization and\n // per-locale spelling (metre against meter), which is a feature rather than\n // the repair of a dead ternary.\n //\n // An exact currency with no symbol in the display table above (one of the\n // less common ISO codes) still rounds from its decimal here, so \"1.005 UYW\"\n // reads the same way \"$1.005\" does. Non-currency Uoms never carry an exact,\n // so this leaves \"1.50 kg\" exactly as it was.\n const genericText = exact ? decimalToFixed(exact, dp) : formatted;\n return `= ${genericText} ${unit || \"\"}`.trim();\n}\n\nfunction formatMatrixEntry(entry: MatrixEntry, settings: FormattingSettings): string {\n if (typeof entry === \"boolean\") return entry ? \"true\" : \"false\";\n if (typeof entry === \"object\" && entry !== null) return formatSymbolic(entry);\n const dp = settings.floatResult.decimalPlaces;\n const sep = settings.floatResult.enableSeperator;\n const loc = settings.numberResult.decimalSeparatorLocale;\n return autoFormatIntegerOrFloat(entry, dp, sep, loc);\n}\n\n/**\n * Renders a Matrix matching its own literal syntax: a single row (1xN,\n * including plain vectors) as `[a, b, c]`, a single column (Nx1) as\n * `[a; b; c]`, and a general shape as `[r0c0, r0c1; r1c0, r1c1]`, row-major\n * textual output read back out of the column-major storage\n * (`columnMajorToRowMajor()`), matching how `[1,2;3,4]` is written.\n */\nfunction formatMatrix(m: MatrixData, locale: ILocale, settings: FormattingSettings): string {\n const rowMajor = columnMajorToRowMajor(m);\n const rows: string[] = [];\n for (let r = 0; r < m.rows; r++) {\n const cells: string[] = [];\n for (let c = 0; c < m.cols; c++) {\n cells.push(formatMatrixEntry(rowMajor[r * m.cols + c], settings));\n }\n rows.push(cells.join(\", \"));\n }\n return `${locale.display.resultPrefix}[${rows.join(\"; \")}]`;\n}\n\n/**\n * Render a matrix as a multi-line, column-aligned block: one row per line (the\n * newline is where {@link formatValue}'s compact form writes `;`), each column\n * right-padded to its widest cell, and every row wrapped in `[ ... ]`. For\n * display where a grid reads better than a line, e.g. a docs notepad or a REPL:\n *\n * ```text\n * [ 1 2 ]\n * [ 30 4 ]\n * ```\n *\n * This is deliberately separate from {@link formatValue}, whose single-line\n * matrix form stays the stable, assertable text the API and the worker DTO use.\n * A 1xN row vector is one line; an Nx1 column vector is N lines.\n */\nexport function formatMatrixAligned(m: MatrixData, settings?: FormattingSettings): string {\n const us = settings || DEFAULT_FORMATTING_SETTINGS;\n const rowMajor = columnMajorToRowMajor(m);\n const cells: string[][] = [];\n for (let r = 0; r < m.rows; r++) {\n const row: string[] = [];\n for (let c = 0; c < m.cols; c++) {\n row.push(formatMatrixEntry(rowMajor[r * m.cols + c], us));\n }\n cells.push(row);\n }\n const colWidth: number[] = [];\n for (let c = 0; c < m.cols; c++) {\n let width = 0;\n for (let r = 0; r < m.rows; r++) width = Math.max(width, cells[r][c].length);\n colWidth.push(width);\n }\n return cells\n .map((row) => `[ ${row.map((cell, c) => cell.padStart(colWidth[c])).join(\" \")} ]`)\n .join(\"\\n\");\n}\n\nfunction formatRange(min: number, max: number, locale: ILocale): string {\n return `${locale.display.resultPrefix}${min}:${max}`;\n}\n\nfunction formatPercentage(value: number, locale: ILocale, settings: FormattingSettings): string {\n // ValueType.Percentage stores a fraction (0.25 for 25%). See Value.ts's\n // documented contract and the sole producer, VM.ts's TO_PERCENTAGE opcode\n // (`right/left - 1`, e.g. 0.25 for \"800 to 1000\"). Multiply by 100 before\n // formatting; without this every percentage-change result displayed as\n // e.g. \"0.25%\" instead of \"25.00%\".\n const dp = settings.percentageResult.decimalPlaces;\n const formatted = (value * 100).toFixed(dp);\n return `= ${formatted}${locale.display.percentageSuffix}`;\n}\n\nfunction formatUnit(value: number, unit: string | undefined): string {\n return `= ${value} ${unit || \"\"}`.trim();\n}\n\n/**\n * Render an evaluated {@link Value} as a display string, dispatching on\n * `value.type` to the type-specific formatter (number, hex, datetime, unit\n * of measurement, matrix, range, percentage, ...).\n *\n * Most branches produce a `\"= \"`-prefixed result string (matching the\n * plugin's inline-result convention); `ValueType.Error` is the one\n * exception, it returns the human-readable error message directly\n * (stored in `value.unit`), not an `\"= \"`-prefixed string.\n *\n * @param value - The evaluated value to format.\n * @param settings - Locale/precision/separator options; defaults to\n * {@link DEFAULT_FORMATTING_SETTINGS} when omitted.\n * @example\n * ```typescript\n * const [value] = engine.evaluateExpression(\"10 USD to GBP\");\n * formatValue(value); // \"= £7.85\" (exact output depends on live exchange rates)\n * ```\n */\nexport function formatValue(value: Value, settings?: FormattingSettings): string {\n const us = settings || DEFAULT_FORMATTING_SETTINGS;\n const localeCode = us.numberResult.decimalSeparatorLocale || \"en\";\n const locale = getLocale(localeCode);\n\n switch (value.type) {\n case ValueType.Number:\n // A measurement with a tolerance renders as \"center ± spread\"; every\n // other number is unchanged, so a plain value is byte-for-byte what it was.\n if (value.uncertainty !== undefined) {\n return formatUncertain(value.value as number, value.uncertainty, locale, us);\n }\n return formatNumber(value.value as number, locale, us, value.decimalPlaces);\n case ValueType.Hex:\n return formatHex(value.value as number | bigint, us, value.unit);\n case ValueType.BigInt:\n return formatBigInt(value.value as bigint);\n case ValueType.String:\n return formatString(value.value as string);\n case ValueType.Boolean:\n return formatBoolean(value.value as boolean);\n case ValueType.Datetime:\n return formatDatetime(value.value as number, locale);\n case ValueType.Uom:\n return formatUom(value.value as number, value.unit, locale, us, value.exact);\n case ValueType.Matrix:\n return formatMatrix(value.value as MatrixData, locale, us);\n case ValueType.Range: {\n const r = value.value as RangeData;\n return formatRange(r.min, r.max, locale);\n }\n case ValueType.Colour:\n return `${locale.display.resultPrefix}${formatColour(value.value as ColourData)}`;\n case ValueType.Symbolic:\n return formatSymbolic(value.value as SymbolicNode);\n case ValueType.Percentage:\n return formatPercentage(value.value as number, locale, us);\n case ValueType.Unit:\n return formatUnit(value.value as number, value.unit);\n case ValueType.Error:\n // errorValue(code, message) stores the human-readable message in\n // `.unit` (code goes in `.value`), falling through to the default\n // case here previously displayed the raw code (e.g.\n // \"CURRENCY_RATE_UNAVAILABLE\") instead of the actual message.\n return value.unit ?? String(value.value);\n default:\n return `= ${String(value.value)}`;\n }\n}\n"]}
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
var
|
|
4
|
-
var
|
|
5
|
-
var
|
|
3
|
+
var chunkZMW6NU2K_cjs = require('./chunk-ZMW6NU2K.cjs');
|
|
4
|
+
var chunkQFTDTX6K_cjs = require('./chunk-QFTDTX6K.cjs');
|
|
5
|
+
var chunkB4HBEFTB_cjs = require('./chunk-B4HBEFTB.cjs');
|
|
6
6
|
|
|
7
7
|
// src/normalizer/TokenNormalizer.ts
|
|
8
8
|
var DEFAULT_OPTIONS = {
|
|
@@ -14,9 +14,9 @@ var DEFAULT_OPTIONS = {
|
|
|
14
14
|
function createFusedToken(type, text, sourceTokens) {
|
|
15
15
|
const first = sourceTokens[0];
|
|
16
16
|
const last = sourceTokens[sourceTokens.length - 1];
|
|
17
|
-
const token = new
|
|
17
|
+
const token = new chunkZMW6NU2K_cjs.LexerToken(
|
|
18
18
|
type,
|
|
19
|
-
|
|
19
|
+
chunkQFTDTX6K_cjs.tokenTypeId(type),
|
|
20
20
|
text,
|
|
21
21
|
text,
|
|
22
22
|
first.offset,
|
|
@@ -61,7 +61,7 @@ var NON_WORD_NAMES = [
|
|
|
61
61
|
"NEWLINE"
|
|
62
62
|
];
|
|
63
63
|
var NON_WORD_TABLE = (() => {
|
|
64
|
-
const ids = NON_WORD_NAMES.map((n) =>
|
|
64
|
+
const ids = NON_WORD_NAMES.map((n) => chunkQFTDTX6K_cjs.tokenTypeId(n));
|
|
65
65
|
const len = Math.max(...ids) + 1;
|
|
66
66
|
const table = new Uint8Array(len);
|
|
67
67
|
for (const id of ids) table[id] = 1;
|
|
@@ -280,7 +280,7 @@ var TokenNormalizer = class {
|
|
|
280
280
|
}
|
|
281
281
|
}
|
|
282
282
|
if (result.length > maxTokens) {
|
|
283
|
-
throw
|
|
283
|
+
throw chunkB4HBEFTB_cjs.ErrorFactory.validation(
|
|
284
284
|
"NORMALIZED_TOKEN_LIMIT_EXCEEDED",
|
|
285
285
|
`Normalized token count (${result.length}) exceeds safety limit (${maxTokens})`,
|
|
286
286
|
{ tokenCount: result.length, maxTokens }
|
|
@@ -444,9 +444,9 @@ function implicitMultiplyRule(priority = 50, canStart) {
|
|
|
444
444
|
if (RATE_DENOMINATOR_WORDS.has(nextValue) && tokens[pos + 2]?.type === "UNIT") return null;
|
|
445
445
|
const triggers = (t.type === "NUMBER" || t.type === "RPAREN") && (next.type === "IDENT" || next.type === "LPAREN" || next.type === "PI" || next.type === "E");
|
|
446
446
|
if (!triggers) return null;
|
|
447
|
-
const starToken = new
|
|
447
|
+
const starToken = new chunkZMW6NU2K_cjs.LexerToken(
|
|
448
448
|
"STAR",
|
|
449
|
-
|
|
449
|
+
chunkQFTDTX6K_cjs.tokenTypeId("STAR"),
|
|
450
450
|
"*",
|
|
451
451
|
"*",
|
|
452
452
|
next.offset,
|
|
@@ -503,5 +503,5 @@ exports.createBuiltinNormalizerRules = createBuiltinNormalizerRules;
|
|
|
503
503
|
exports.createFusedToken = createFusedToken;
|
|
504
504
|
exports.implicitMultiplyRule = implicitMultiplyRule;
|
|
505
505
|
exports.isInsideRangeContext = isInsideRangeContext;
|
|
506
|
-
//# sourceMappingURL=chunk-
|
|
507
|
-
//# sourceMappingURL=chunk-
|
|
506
|
+
//# sourceMappingURL=chunk-CUR2WLI4.cjs.map
|
|
507
|
+
//# sourceMappingURL=chunk-CUR2WLI4.cjs.map
|