solve-engine 1.0.0-beta.0 → 1.0.0-beta.2

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.
Files changed (253) hide show
  1. package/dist/BytecodeBuilder-3egMyuDi.d.cts +274 -0
  2. package/dist/BytecodeBuilder-3egMyuDi.d.ts +274 -0
  3. package/dist/Configuration-fVpd-HC-.d.cts +228 -0
  4. package/dist/Configuration-fVpd-HC-.d.ts +228 -0
  5. package/dist/EngineError-DvPSnhZi.d.cts +304 -0
  6. package/dist/EngineError-DvPSnhZi.d.ts +304 -0
  7. package/dist/Lexer-BJdhlnej.d.cts +531 -0
  8. package/dist/Lexer-D9l4Yrk2.d.ts +531 -0
  9. package/dist/NormalizerRule-BrVoVjmP.d.cts +163 -0
  10. package/dist/NormalizerRule-CEjf1FyD.d.ts +163 -0
  11. package/dist/PackageRegistry-D-Tv_7ca.d.cts +2572 -0
  12. package/dist/PackageRegistry-DaH4aIKP.d.ts +2572 -0
  13. package/dist/Parselet-CK8cQu2a.d.cts +299 -0
  14. package/dist/Parselet-ConOIdRO.d.ts +299 -0
  15. package/dist/ScopeManager-B5k0nk05.d.ts +559 -0
  16. package/dist/ScopeManager-CKfQtl7l.d.cts +559 -0
  17. package/dist/Token-0jpvUdPY.d.cts +245 -0
  18. package/dist/Token-0jpvUdPY.d.ts +245 -0
  19. package/dist/VMCheckpoints-BmDwIXgK.d.ts +171 -0
  20. package/dist/VMCheckpoints-CqFuLwrT.d.cts +171 -0
  21. package/dist/Value-KtAQNHur.d.cts +295 -0
  22. package/dist/Value-KtAQNHur.d.ts +295 -0
  23. package/dist/chunk-2RWAXT6O.js +3 -0
  24. package/dist/chunk-2RWAXT6O.js.map +1 -0
  25. package/dist/chunk-34RRD7PC.js +1492 -0
  26. package/dist/chunk-34RRD7PC.js.map +1 -0
  27. package/dist/chunk-3PPFLFH4.js +5097 -0
  28. package/dist/chunk-3PPFLFH4.js.map +1 -0
  29. package/dist/chunk-3VGDNEE3.js +84 -0
  30. package/dist/chunk-3VGDNEE3.js.map +1 -0
  31. package/dist/chunk-3YNVWKR2.cjs +370 -0
  32. package/dist/chunk-3YNVWKR2.cjs.map +1 -0
  33. package/dist/chunk-47LRVGOT.cjs +316 -0
  34. package/dist/chunk-47LRVGOT.cjs.map +1 -0
  35. package/dist/chunk-4MG4XKO2.js +1644 -0
  36. package/dist/chunk-4MG4XKO2.js.map +1 -0
  37. package/dist/chunk-4QADQTWS.js +2392 -0
  38. package/dist/chunk-4QADQTWS.js.map +1 -0
  39. package/dist/chunk-53B6KDDJ.cjs +1651 -0
  40. package/dist/chunk-53B6KDDJ.cjs.map +1 -0
  41. package/dist/chunk-5X2PTP6F.cjs +104 -0
  42. package/dist/chunk-5X2PTP6F.cjs.map +1 -0
  43. package/dist/chunk-5YEMOYSE.js +264 -0
  44. package/dist/chunk-5YEMOYSE.js.map +1 -0
  45. package/dist/chunk-64W6GLLZ.js +481 -0
  46. package/dist/chunk-64W6GLLZ.js.map +1 -0
  47. package/dist/chunk-6BKTCEUP.cjs +233 -0
  48. package/dist/chunk-6BKTCEUP.cjs.map +1 -0
  49. package/dist/chunk-6NTVRDQV.cjs +1642 -0
  50. package/dist/chunk-6NTVRDQV.cjs.map +1 -0
  51. package/dist/chunk-6RDSQURE.js +290 -0
  52. package/dist/chunk-6RDSQURE.js.map +1 -0
  53. package/dist/chunk-75JP4BZX.js +93 -0
  54. package/dist/chunk-75JP4BZX.js.map +1 -0
  55. package/dist/chunk-B7LXJ6LC.cjs +36 -0
  56. package/dist/chunk-B7LXJ6LC.cjs.map +1 -0
  57. package/dist/chunk-BVAR5J2F.js +257 -0
  58. package/dist/chunk-BVAR5J2F.js.map +1 -0
  59. package/dist/chunk-C4XZV6E7.cjs +269 -0
  60. package/dist/chunk-C4XZV6E7.cjs.map +1 -0
  61. package/dist/chunk-CCJPSHGI.cjs +40 -0
  62. package/dist/chunk-CCJPSHGI.cjs.map +1 -0
  63. package/dist/chunk-CLL7RUQV.cjs +316 -0
  64. package/dist/chunk-CLL7RUQV.cjs.map +1 -0
  65. package/dist/chunk-DM3LMRBC.js +329 -0
  66. package/dist/chunk-DM3LMRBC.js.map +1 -0
  67. package/dist/chunk-DUEZFTK2.js +38 -0
  68. package/dist/chunk-DUEZFTK2.js.map +1 -0
  69. package/dist/chunk-EBSPLUW4.cjs +489 -0
  70. package/dist/chunk-EBSPLUW4.cjs.map +1 -0
  71. package/dist/chunk-EHAHVROS.cjs +261 -0
  72. package/dist/chunk-EHAHVROS.cjs.map +1 -0
  73. package/dist/chunk-EIGTWK5N.js +167 -0
  74. package/dist/chunk-EIGTWK5N.js.map +1 -0
  75. package/dist/chunk-EPOXXJBK.js +96 -0
  76. package/dist/chunk-EPOXXJBK.js.map +1 -0
  77. package/dist/chunk-FEAIOR7N.cjs +91 -0
  78. package/dist/chunk-FEAIOR7N.cjs.map +1 -0
  79. package/dist/chunk-G535KJEG.js +312 -0
  80. package/dist/chunk-G535KJEG.js.map +1 -0
  81. package/dist/chunk-GCM5JHMX.js +88 -0
  82. package/dist/chunk-GCM5JHMX.js.map +1 -0
  83. package/dist/chunk-GOLDJNMZ.js +368 -0
  84. package/dist/chunk-GOLDJNMZ.js.map +1 -0
  85. package/dist/chunk-GW32KPCU.cjs +360 -0
  86. package/dist/chunk-GW32KPCU.cjs.map +1 -0
  87. package/dist/chunk-HTXVVJRA.cjs +1549 -0
  88. package/dist/chunk-HTXVVJRA.cjs.map +1 -0
  89. package/dist/chunk-HWSZJQCI.js +311 -0
  90. package/dist/chunk-HWSZJQCI.js.map +1 -0
  91. package/dist/chunk-IF532O7C.js +101 -0
  92. package/dist/chunk-IF532O7C.js.map +1 -0
  93. package/dist/chunk-J73SJHR3.cjs +2415 -0
  94. package/dist/chunk-J73SJHR3.cjs.map +1 -0
  95. package/dist/chunk-JBSYC7BB.cjs +7473 -0
  96. package/dist/chunk-JBSYC7BB.cjs.map +1 -0
  97. package/dist/chunk-KVILKGMS.js +228 -0
  98. package/dist/chunk-KVILKGMS.js.map +1 -0
  99. package/dist/chunk-LIPPNDBE.js +258 -0
  100. package/dist/chunk-LIPPNDBE.js.map +1 -0
  101. package/dist/chunk-LR7YASZF.cjs +172 -0
  102. package/dist/chunk-LR7YASZF.cjs.map +1 -0
  103. package/dist/chunk-M4N5GA5Z.cjs +309 -0
  104. package/dist/chunk-M4N5GA5Z.cjs.map +1 -0
  105. package/dist/chunk-M5LX5AOO.js +7459 -0
  106. package/dist/chunk-M5LX5AOO.js.map +1 -0
  107. package/dist/chunk-MZOVP3WI.cjs +96 -0
  108. package/dist/chunk-MZOVP3WI.cjs.map +1 -0
  109. package/dist/chunk-N5YFR4UP.cjs +10 -0
  110. package/dist/chunk-N5YFR4UP.cjs.map +1 -0
  111. package/dist/chunk-NGBBNL4K.cjs +4 -0
  112. package/dist/chunk-NGBBNL4K.cjs.map +1 -0
  113. package/dist/chunk-NH2O2AUR.js +146 -0
  114. package/dist/chunk-NH2O2AUR.js.map +1 -0
  115. package/dist/chunk-NLNDMWZC.js +31 -0
  116. package/dist/chunk-NLNDMWZC.js.map +1 -0
  117. package/dist/chunk-NMCRQP3Z.cjs +778 -0
  118. package/dist/chunk-NMCRQP3Z.cjs.map +1 -0
  119. package/dist/chunk-NMD5VRN4.cjs +1327 -0
  120. package/dist/chunk-NMD5VRN4.cjs.map +1 -0
  121. package/dist/chunk-OC6LTXYS.cjs +286 -0
  122. package/dist/chunk-OC6LTXYS.cjs.map +1 -0
  123. package/dist/chunk-OT6OJY7C.cjs +114 -0
  124. package/dist/chunk-OT6OJY7C.cjs.map +1 -0
  125. package/dist/chunk-PFSDGGYL.js +8 -0
  126. package/dist/chunk-PFSDGGYL.js.map +1 -0
  127. package/dist/chunk-QNJ4ACRT.cjs +155 -0
  128. package/dist/chunk-QNJ4ACRT.cjs.map +1 -0
  129. package/dist/chunk-QWY3VEZN.js +1637 -0
  130. package/dist/chunk-QWY3VEZN.js.map +1 -0
  131. package/dist/chunk-RFYD5TJE.js +111 -0
  132. package/dist/chunk-RFYD5TJE.js.map +1 -0
  133. package/dist/chunk-RIN643A3.js +354 -0
  134. package/dist/chunk-RIN643A3.js.map +1 -0
  135. package/dist/chunk-RZCWSXTA.cjs +5122 -0
  136. package/dist/chunk-RZCWSXTA.cjs.map +1 -0
  137. package/dist/chunk-SDGRK7EP.js +774 -0
  138. package/dist/chunk-SDGRK7EP.js.map +1 -0
  139. package/dist/chunk-VEKIWQ3F.cjs +39 -0
  140. package/dist/chunk-VEKIWQ3F.cjs.map +1 -0
  141. package/dist/chunk-WQTTOGXC.cjs +99 -0
  142. package/dist/chunk-WQTTOGXC.cjs.map +1 -0
  143. package/dist/chunk-X6K3HUOY.cjs +86 -0
  144. package/dist/chunk-X6K3HUOY.cjs.map +1 -0
  145. package/dist/chunk-XJCMXB2E.cjs +333 -0
  146. package/dist/chunk-XJCMXB2E.cjs.map +1 -0
  147. package/dist/chunk-XVWCOTR6.js +1324 -0
  148. package/dist/chunk-XVWCOTR6.js.map +1 -0
  149. package/dist/chunk-YLJ4XMA6.js +33 -0
  150. package/dist/chunk-YLJ4XMA6.js.map +1 -0
  151. package/dist/chunk-Z2XP767T.cjs +35 -0
  152. package/dist/chunk-Z2XP767T.cjs.map +1 -0
  153. package/dist/chunk-Z4X2RWOF.js +37 -0
  154. package/dist/chunk-Z4X2RWOF.js.map +1 -0
  155. package/dist/constants.cjs +22 -0
  156. package/dist/constants.cjs.map +1 -0
  157. package/dist/constants.d.cts +12 -0
  158. package/dist/constants.d.ts +12 -0
  159. package/dist/constants.js +5 -0
  160. package/dist/constants.js.map +1 -0
  161. package/dist/engine.cjs +79 -0
  162. package/dist/engine.cjs.map +1 -0
  163. package/dist/engine.d.cts +587 -0
  164. package/dist/engine.d.ts +587 -0
  165. package/dist/engine.js +34 -0
  166. package/dist/engine.js.map +1 -0
  167. package/dist/errors.cjs +81 -0
  168. package/dist/errors.cjs.map +1 -0
  169. package/dist/errors.d.cts +95 -0
  170. package/dist/errors.d.ts +95 -0
  171. package/dist/errors.js +4 -0
  172. package/dist/errors.js.map +1 -0
  173. package/dist/format.cjs +171 -0
  174. package/dist/format.cjs.map +1 -0
  175. package/dist/format.d.cts +51 -0
  176. package/dist/format.d.ts +51 -0
  177. package/dist/format.js +168 -0
  178. package/dist/format.js.map +1 -0
  179. package/dist/index.cjs +97 -0
  180. package/dist/index.cjs.map +1 -0
  181. package/dist/index.d.cts +152 -0
  182. package/dist/index.d.ts +152 -0
  183. package/dist/index.js +75 -0
  184. package/dist/index.js.map +1 -0
  185. package/dist/language.cjs +308 -0
  186. package/dist/language.cjs.map +1 -0
  187. package/dist/language.d.cts +110 -0
  188. package/dist/language.d.ts +110 -0
  189. package/dist/language.js +287 -0
  190. package/dist/language.js.map +1 -0
  191. package/dist/lexer.cjs +64 -0
  192. package/dist/lexer.cjs.map +1 -0
  193. package/dist/lexer.d.cts +56 -0
  194. package/dist/lexer.d.ts +56 -0
  195. package/dist/lexer.js +11 -0
  196. package/dist/lexer.js.map +1 -0
  197. package/dist/normalizer.cjs +40 -0
  198. package/dist/normalizer.cjs.map +1 -0
  199. package/dist/normalizer.d.cts +364 -0
  200. package/dist/normalizer.d.ts +364 -0
  201. package/dist/normalizer.js +11 -0
  202. package/dist/normalizer.js.map +1 -0
  203. package/dist/packages.cjs +121 -0
  204. package/dist/packages.cjs.map +1 -0
  205. package/dist/packages.d.cts +691 -0
  206. package/dist/packages.d.ts +691 -0
  207. package/dist/packages.js +24 -0
  208. package/dist/packages.js.map +1 -0
  209. package/dist/parser.cjs +55 -0
  210. package/dist/parser.cjs.map +1 -0
  211. package/dist/parser.d.cts +46 -0
  212. package/dist/parser.d.ts +46 -0
  213. package/dist/parser.js +10 -0
  214. package/dist/parser.js.map +1 -0
  215. package/dist/pipeline-CrsRPmsv.d.ts +285 -0
  216. package/dist/pipeline-DPUQt7yL.d.cts +285 -0
  217. package/dist/resolvers.cjs +13 -0
  218. package/dist/resolvers.cjs.map +1 -0
  219. package/dist/resolvers.d.cts +111 -0
  220. package/dist/resolvers.d.ts +111 -0
  221. package/dist/resolvers.js +4 -0
  222. package/dist/resolvers.js.map +1 -0
  223. package/dist/services.cjs +21 -0
  224. package/dist/services.cjs.map +1 -0
  225. package/dist/services.d.cts +30 -0
  226. package/dist/services.d.ts +30 -0
  227. package/dist/services.js +4 -0
  228. package/dist/services.js.map +1 -0
  229. package/dist/uom.cjs +56 -0
  230. package/dist/uom.cjs.map +1 -0
  231. package/dist/uom.d.cts +224 -0
  232. package/dist/uom.d.ts +224 -0
  233. package/dist/uom.js +11 -0
  234. package/dist/uom.js.map +1 -0
  235. package/dist/utilities.cjs +32 -0
  236. package/dist/utilities.cjs.map +1 -0
  237. package/dist/utilities.d.cts +113 -0
  238. package/dist/utilities.d.ts +113 -0
  239. package/dist/utilities.js +7 -0
  240. package/dist/utilities.js.map +1 -0
  241. package/dist/variables.cjs +17 -0
  242. package/dist/variables.cjs.map +1 -0
  243. package/dist/variables.d.cts +87 -0
  244. package/dist/variables.d.ts +87 -0
  245. package/dist/variables.js +4 -0
  246. package/dist/variables.js.map +1 -0
  247. package/dist/vm.cjs +284 -0
  248. package/dist/vm.cjs.map +1 -0
  249. package/dist/vm.d.cts +68 -0
  250. package/dist/vm.d.ts +68 -0
  251. package/dist/vm.js +194 -0
  252. package/dist/vm.js.map +1 -0
  253. package/package.json +4 -4
@@ -0,0 +1,1642 @@
1
+ 'use strict';
2
+
3
+ var chunk47LRVGOT_cjs = require('./chunk-47LRVGOT.cjs');
4
+ var chunkJ73SJHR3_cjs = require('./chunk-J73SJHR3.cjs');
5
+ var chunkXJCMXB2E_cjs = require('./chunk-XJCMXB2E.cjs');
6
+ var chunkMZOVP3WI_cjs = require('./chunk-MZOVP3WI.cjs');
7
+ var chunkHTXVVJRA_cjs = require('./chunk-HTXVVJRA.cjs');
8
+ var chunkOC6LTXYS_cjs = require('./chunk-OC6LTXYS.cjs');
9
+ var chunkQNJ4ACRT_cjs = require('./chunk-QNJ4ACRT.cjs');
10
+ var chunkM4N5GA5Z_cjs = require('./chunk-M4N5GA5Z.cjs');
11
+
12
+ // src/vm/DependencyGraph.ts
13
+ var DependencyGraph = class {
14
+ constructor() {
15
+ this.consumers = /* @__PURE__ */ new Map();
16
+ this.dependencies = /* @__PURE__ */ new Map();
17
+ this.writes = /* @__PURE__ */ new Map();
18
+ this.lineReads = /* @__PURE__ */ new Map();
19
+ // Data source dependencies: line number -> Set of query keys
20
+ this.dataSourceDependencies = /* @__PURE__ */ new Map();
21
+ // Reverse map: query key -> Set of line numbers
22
+ this.dataSourceConsumers = /* @__PURE__ */ new Map();
23
+ }
24
+ /**
25
+ * Register a line's variable reads and writes in the dependency graph.
26
+ *
27
+ * If re-registering the same line (e.g., after editing), old consumer
28
+ * references are cleaned up first. Write-variables are removed from
29
+ * the consumer set so that redefinition breaks the old dependency chain.
30
+ *
31
+ * @param lineNumber - 1-based line number in the document
32
+ * @param reads - Variable names this line reads
33
+ * @param writes - Variable names this line writes (assigns to)
34
+ */
35
+ registerLine(lineNumber, reads, writes) {
36
+ const oldReads = this.lineReads.get(lineNumber);
37
+ if (oldReads) {
38
+ for (const oldRead of oldReads) {
39
+ const consumers = this.consumers.get(oldRead);
40
+ if (consumers) consumers.delete(lineNumber);
41
+ }
42
+ }
43
+ this.lineReads.set(lineNumber, new Set(reads));
44
+ for (const dep of reads) {
45
+ if (!this.consumers.has(dep)) this.consumers.set(dep, /* @__PURE__ */ new Set());
46
+ this.consumers.get(dep).add(lineNumber);
47
+ }
48
+ if (writes.length > 0) {
49
+ this.dependencies.set(lineNumber, new Set(reads));
50
+ this.writes.set(lineNumber, new Set(writes));
51
+ for (const write of writes) {
52
+ const prevConsumer = this.consumers.get(write);
53
+ if (prevConsumer) prevConsumer.delete(lineNumber);
54
+ }
55
+ }
56
+ }
57
+ /**
58
+ * Register a line's dependency on an external data source (e.g., currency rate, OSRS GE price).
59
+ *
60
+ * When the data source updates, {@link getAffectedLinesByDataSource} returns all lines
61
+ * that depend on this data, enabling targeted re-evaluation.
62
+ *
63
+ * @param lineNumber - 1-based line number in the document
64
+ * @param dataSourceId - Unique identifier for the data source (e.g., "currency", "osrs-ge")
65
+ * @param queryKey - Query key array identifying the specific data (e.g., ["USD", "EUR"])
66
+ */
67
+ registerLineDataSourceDependency(lineNumber, dataSourceId, queryKey) {
68
+ const queryKeyStr = JSON.stringify(queryKey);
69
+ const key = `${dataSourceId}:${queryKeyStr}`;
70
+ if (!this.dataSourceDependencies.has(lineNumber)) {
71
+ this.dataSourceDependencies.set(lineNumber, /* @__PURE__ */ new Set());
72
+ }
73
+ this.dataSourceDependencies.get(lineNumber).add(key);
74
+ if (!this.dataSourceConsumers.has(key)) {
75
+ this.dataSourceConsumers.set(key, /* @__PURE__ */ new Set());
76
+ }
77
+ this.dataSourceConsumers.get(key).add(lineNumber);
78
+ }
79
+ /**
80
+ * Find all lines affected by a changed variable via BFS through the consumer graph.
81
+ *
82
+ * When a variable is modified (e.g., `:x = 5` changes to `:x = 10`), this returns
83
+ * all lines that transitively depend on it, lines that read `x`, lines that read
84
+ * variables written by those lines, and so on.
85
+ *
86
+ * @param changedVariable - The variable name that changed
87
+ * @returns Set of line numbers that need re-evaluation
88
+ */
89
+ getAffectedLines(changedVariable) {
90
+ const visited = /* @__PURE__ */ new Set();
91
+ const queue = [changedVariable];
92
+ while (queue.length > 0) {
93
+ const varName = queue.pop();
94
+ const consumers = this.consumers.get(varName);
95
+ if (!consumers) continue;
96
+ for (const line of consumers) {
97
+ if (visited.has(line)) continue;
98
+ visited.add(line);
99
+ const lineWrites = this.writes.get(line);
100
+ if (lineWrites) {
101
+ for (const writtenVar of lineWrites) {
102
+ queue.push(writtenVar);
103
+ }
104
+ }
105
+ }
106
+ }
107
+ return visited;
108
+ }
109
+ /**
110
+ * Phase 1.4 DAG-walk optimization: return affected lines in dependency-safe
111
+ * topological order. Uses Kahn's algorithm (BFS-based) to ensure every line
112
+ * is evaluated AFTER all lines it depends on have been processed.
113
+ *
114
+ * This is more correct than ascending line-number sort, which fails when
115
+ * variable definitions and their consumers are not in document order.
116
+ *
117
+ * @returns Line numbers in topological order (producers before consumers).
118
+ */
119
+ getAffectedLinesInOrder(startVariable) {
120
+ const affected = this.getAffectedLines(startVariable);
121
+ if (affected.size === 0) return [];
122
+ const inDegree = /* @__PURE__ */ new Map();
123
+ const adjacency = /* @__PURE__ */ new Map();
124
+ for (const line of affected) {
125
+ if (!inDegree.has(line)) inDegree.set(line, 0);
126
+ if (!adjacency.has(line)) adjacency.set(line, []);
127
+ }
128
+ const producerOf = /* @__PURE__ */ new Map();
129
+ for (const line of affected) {
130
+ const lineWrites = this.writes.get(line);
131
+ if (lineWrites) {
132
+ for (const w of lineWrites) producerOf.set(w, line);
133
+ }
134
+ }
135
+ for (const line of affected) {
136
+ const reads = this.lineReads.get(line);
137
+ if (!reads) continue;
138
+ for (const readVar of reads) {
139
+ const producer = producerOf.get(readVar);
140
+ if (producer !== void 0 && producer !== line) {
141
+ adjacency.get(producer).push(line);
142
+ inDegree.set(line, (inDegree.get(line) ?? 0) + 1);
143
+ }
144
+ }
145
+ }
146
+ const queue = [];
147
+ for (const [line, degree] of inDegree) {
148
+ if (degree === 0) queue.push(line);
149
+ }
150
+ if (queue.length === 0 && affected.size > 0) {
151
+ const sorted = Array.from(affected).sort((a, b) => a - b);
152
+ queue.push(sorted[0]);
153
+ }
154
+ const ordered = [];
155
+ while (queue.length > 0) {
156
+ const current = queue.shift();
157
+ ordered.push(current);
158
+ for (const downstream of adjacency.get(current) ?? []) {
159
+ const newDegree = (inDegree.get(downstream) ?? 1) - 1;
160
+ inDegree.set(downstream, newDegree);
161
+ if (newDegree === 0) queue.push(downstream);
162
+ }
163
+ }
164
+ if (ordered.length < affected.size) {
165
+ const orderedSet = new Set(ordered);
166
+ const remaining = Array.from(affected).filter((l) => !orderedSet.has(l)).sort((a, b) => a - b);
167
+ ordered.push(...remaining);
168
+ }
169
+ return ordered;
170
+ }
171
+ /**
172
+ * Find all lines affected by a data source update.
173
+ *
174
+ * When an async data source resolves (e.g., currency rate fetch completes),
175
+ * this returns all lines that depend on that specific data query.
176
+ *
177
+ * @param dataSourceId - The data source identifier
178
+ * @param queryKey - The query key that was updated
179
+ * @returns Set of line numbers that need re-evaluation
180
+ */
181
+ getAffectedLinesByDataSource(dataSourceId, queryKey) {
182
+ const queryKeyStr = JSON.stringify(queryKey);
183
+ const key = `${dataSourceId}:${queryKeyStr}`;
184
+ return this.dataSourceConsumers.get(key) ?? /* @__PURE__ */ new Set();
185
+ }
186
+ /**
187
+ * Remove a line from the dependency graph (e.g., when a line is deleted from the document).
188
+ *
189
+ * Cleans up all consumer references, write registrations, and data source dependencies
190
+ * for the removed line. O(k) where k is the number of variables the line reads.
191
+ *
192
+ * @param lineNumber - The line number being removed
193
+ */
194
+ removeLine(lineNumber) {
195
+ const reads = this.lineReads.get(lineNumber);
196
+ if (reads) {
197
+ for (const readVar of reads) {
198
+ const consumers = this.consumers.get(readVar);
199
+ if (consumers) consumers.delete(lineNumber);
200
+ }
201
+ this.lineReads.delete(lineNumber);
202
+ }
203
+ this.dependencies.delete(lineNumber);
204
+ this.writes.delete(lineNumber);
205
+ const dataSourceKeys = this.dataSourceDependencies.get(lineNumber);
206
+ if (dataSourceKeys) {
207
+ for (const key of dataSourceKeys) {
208
+ this.dataSourceConsumers.get(key)?.delete(lineNumber);
209
+ }
210
+ this.dataSourceDependencies.delete(lineNumber);
211
+ }
212
+ }
213
+ /**
214
+ * Get all line numbers that consume (read) a given variable.
215
+ *
216
+ * @param variable - The variable name
217
+ * @returns Set of line numbers that read this variable, or empty set if none
218
+ */
219
+ getConsumers(variable) {
220
+ return this.consumers.get(variable) ?? /* @__PURE__ */ new Set();
221
+ }
222
+ /**
223
+ * Get all variables that a line depends on (reads).
224
+ *
225
+ * @param lineNumber - The line number to query
226
+ * @returns Set of variable names this line reads, or empty set if none
227
+ */
228
+ getDependencies(lineNumber) {
229
+ return this.dependencies.get(lineNumber) ?? /* @__PURE__ */ new Set();
230
+ }
231
+ /**
232
+ * Get all variables that a line writes (assigns to).
233
+ *
234
+ * @param lineNumber - The line number to query
235
+ * @returns Set of variable names this line writes, or empty set if none
236
+ */
237
+ getWrites(lineNumber) {
238
+ return this.writes.get(lineNumber) ?? /* @__PURE__ */ new Set();
239
+ }
240
+ /**
241
+ * Get a serializable snapshot of the entire dependency graph for diagnostics.
242
+ *
243
+ * Returns plain objects (not Maps/Sets) so consumers don't need to reach
244
+ * into private fields. Used by playground diagnostic tabs for DAG visualization.
245
+ */
246
+ getSnapshot() {
247
+ const consumers = {};
248
+ for (const [variable, lines] of this.consumers) {
249
+ consumers[variable] = Array.from(lines);
250
+ }
251
+ const writes = {};
252
+ for (const [line, vars] of this.writes) {
253
+ writes[line] = Array.from(vars);
254
+ }
255
+ const reads = {};
256
+ for (const [line, vars] of this.lineReads) {
257
+ reads[line] = Array.from(vars);
258
+ }
259
+ const dataSourceDeps = {};
260
+ for (const [line, keys] of this.dataSourceDependencies) {
261
+ dataSourceDeps[line] = Array.from(keys);
262
+ }
263
+ const dataSourceConsumers = {};
264
+ for (const [key, lines] of this.dataSourceConsumers) {
265
+ dataSourceConsumers[key] = Array.from(lines);
266
+ }
267
+ return { consumers, writes, reads, dataSourceDeps, dataSourceConsumers };
268
+ }
269
+ /** Clear all dependency graph state. Called on document switch or engine reset. */
270
+ clear() {
271
+ this.consumers.clear();
272
+ this.dependencies.clear();
273
+ this.writes.clear();
274
+ this.lineReads.clear();
275
+ this.dataSourceDependencies.clear();
276
+ this.dataSourceConsumers.clear();
277
+ }
278
+ };
279
+
280
+ // src/vm/ScopeManager.ts
281
+ var ScopeManager = class {
282
+ constructor() {
283
+ this.definitions = /* @__PURE__ */ new Map();
284
+ }
285
+ /**
286
+ * Record a variable definition at `lineNumber`. A variable may have
287
+ * multiple definitions across different lines (e.g. redefined further
288
+ * down a document), each call adds one, keeping the internal stack
289
+ * sorted by line so {@link read} can binary-scan for "most recent
290
+ * definition at or before" a given line.
291
+ */
292
+ write(variable, lineNumber, expr) {
293
+ if (!this.definitions.has(variable)) {
294
+ this.definitions.set(variable, []);
295
+ }
296
+ const stack = this.definitions.get(variable);
297
+ stack.push({ line: lineNumber, expr });
298
+ stack.sort((a, b) => a.line - b.line);
299
+ }
300
+ /**
301
+ * Look up a variable's value as seen from `readLine`: returns the result
302
+ * of the closest definition at or before `readLine`, not simply the most
303
+ * recently-written one, so a read on line 5 of a variable redefined on
304
+ * lines 2 and 10 sees line 2's value, not line 10's. Returns `undefined`
305
+ * if the variable has no definition at or before `readLine`.
306
+ */
307
+ read(variable, readLine) {
308
+ const stack = this.definitions.get(variable);
309
+ if (!stack) return void 0;
310
+ for (let i = stack.length - 1; i >= 0; i--) {
311
+ if (stack[i].line <= readLine) return stack[i].expr.lastResult;
312
+ }
313
+ return void 0;
314
+ }
315
+ /**
316
+ * Drop every definition of `variable` that comes strictly after
317
+ * `definitionLine`. Call this when a line is re-evaluated with a new
318
+ * definition, so stale later-line definitions from a previous edit don't
319
+ * linger and get returned by {@link read}.
320
+ */
321
+ invalidateDownstream(variable, definitionLine) {
322
+ const stack = this.definitions.get(variable);
323
+ if (!stack) return;
324
+ const idx = stack.findIndex((s) => s.line === definitionLine);
325
+ if (idx === -1) return;
326
+ stack.splice(idx + 1);
327
+ }
328
+ /** Remove every tracked variable definition, used when an engine/document is reset. */
329
+ clear() {
330
+ this.definitions.clear();
331
+ }
332
+ };
333
+
334
+ // src/vm/VM.ts
335
+ function createVM(registry, maxStackDepth = 200, maxInstructions = 5e4, maxFunctionRecursionDepth = 50, context = chunkJ73SJHR3_cjs.defaultEngineContext) {
336
+ const stack = [];
337
+ const variables = /* @__PURE__ */ new Map();
338
+ let instructionCount = 0;
339
+ let activeSignal;
340
+ let abortCurrent;
341
+ const callFrames = [];
342
+ const userFunctions = /* @__PURE__ */ new Map();
343
+ const equations = /* @__PURE__ */ new Map();
344
+ const scalarEquations = /* @__PURE__ */ new Map();
345
+ return {
346
+ push(v) {
347
+ if (stack.length < maxStackDepth) {
348
+ stack.push(v);
349
+ }
350
+ },
351
+ getMaxStackDepth() {
352
+ return maxStackDepth;
353
+ },
354
+ pop() {
355
+ if (stack.length === 0) {
356
+ return chunkOC6LTXYS_cjs.numberValue(0);
357
+ }
358
+ return stack.pop();
359
+ },
360
+ popNumber() {
361
+ return stack.pop().toNumber();
362
+ },
363
+ popString() {
364
+ return stack.pop().value;
365
+ },
366
+ peek() {
367
+ return stack[stack.length - 1];
368
+ },
369
+ getStack() {
370
+ return stack;
371
+ },
372
+ registry,
373
+ getVar(key) {
374
+ if (callFrames.length > 0) {
375
+ const frameValue = callFrames[callFrames.length - 1].get(key);
376
+ if (frameValue !== void 0) return frameValue;
377
+ }
378
+ return variables.get(key);
379
+ },
380
+ setVar(key, val) {
381
+ variables.set(key, val);
382
+ },
383
+ pushCallFrame(frame) {
384
+ if (callFrames.length >= maxFunctionRecursionDepth) {
385
+ throw chunkM4N5GA5Z_cjs.ErrorFactory.execution(
386
+ "FUNCTION_RECURSION_LIMIT_EXCEEDED",
387
+ `Function call nesting exceeded maximum depth of ${maxFunctionRecursionDepth} (possible infinite recursion, e.g. f(x) = f(x))`,
388
+ { maxFunctionRecursionDepth }
389
+ );
390
+ }
391
+ callFrames.push(frame);
392
+ },
393
+ popCallFrame() {
394
+ callFrames.pop();
395
+ },
396
+ defineUserFunction(name, params, program) {
397
+ userFunctions.set(name, { name, params, program });
398
+ },
399
+ getUserFunction(name) {
400
+ return userFunctions.get(name);
401
+ },
402
+ hasUserFunction(name) {
403
+ return userFunctions.has(name);
404
+ },
405
+ defineEquation(variable, factorNames, rhsProgram) {
406
+ equations.set(variable, { variable, factorNames, rhsProgram });
407
+ },
408
+ getEquation(variable) {
409
+ return equations.get(variable);
410
+ },
411
+ hasEquation(variable) {
412
+ return equations.has(variable);
413
+ },
414
+ defineScalarEquation(variable, lhsProgram, rhsProgram) {
415
+ scalarEquations.set(variable, { variable, lhsProgram, rhsProgram });
416
+ },
417
+ getScalarEquation(variable) {
418
+ return scalarEquations.get(variable);
419
+ },
420
+ hasScalarEquation(variable) {
421
+ return scalarEquations.has(variable);
422
+ },
423
+ reset() {
424
+ stack.length = 0;
425
+ variables.clear();
426
+ callFrames.length = 0;
427
+ userFunctions.clear();
428
+ equations.clear();
429
+ scalarEquations.clear();
430
+ instructionCount = 0;
431
+ if (abortCurrent) {
432
+ abortCurrent();
433
+ abortCurrent = void 0;
434
+ }
435
+ activeSignal = void 0;
436
+ },
437
+ get activeSignal() {
438
+ return activeSignal;
439
+ },
440
+ set activeSignal(s) {
441
+ activeSignal = s;
442
+ },
443
+ get abortCurrent() {
444
+ return abortCurrent;
445
+ },
446
+ set abortCurrent(f) {
447
+ abortCurrent = f;
448
+ },
449
+ context,
450
+ getMaxInstructions() {
451
+ return maxInstructions;
452
+ },
453
+ getInstructionCount() {
454
+ return instructionCount;
455
+ },
456
+ incrementInstructions(n) {
457
+ instructionCount += n;
458
+ if (instructionCount > maxInstructions) {
459
+ throw chunkM4N5GA5Z_cjs.ErrorFactory.execution("INSTRUCTION_LIMIT_EXCEEDED", `Execution exceeded maximum of ${maxInstructions} instructions`);
460
+ }
461
+ }
462
+ };
463
+ }
464
+ function safePop(stack) {
465
+ if (stack.length === 0) {
466
+ throw chunkM4N5GA5Z_cjs.ErrorFactory.internal({
467
+ code: "STACK_UNDERFLOW",
468
+ message: "Stack underflow: an opcode expected a value on the stack but it was empty",
469
+ expected: "at least one value on the VM stack",
470
+ found: "an empty stack",
471
+ suggestion: "this indicates corrupted bytecode or a bug in a package's parselet (mismatched push/pop counts), not a user-input error"
472
+ });
473
+ }
474
+ return stack.pop();
475
+ }
476
+ function invokeFrameBody(params, program, args, vm, pipeline, expression, context, symbolicTolerant) {
477
+ const frame = /* @__PURE__ */ new Map();
478
+ for (let i = 0; i < params.length; i++) frame.set(params[i], args[i]);
479
+ vm.pushCallFrame(frame);
480
+ let bodyResult;
481
+ try {
482
+ bodyResult = executeBytecode(program, vm, pipeline, expression, context, symbolicTolerant);
483
+ } finally {
484
+ vm.popCallFrame();
485
+ }
486
+ if (bodyResult.type === "pending") {
487
+ throw chunkM4N5GA5Z_cjs.ErrorFactory.execution(
488
+ "MAP_REDUCE_ASYNC_UNSUPPORTED",
489
+ `map/reduce transform bodies calling an async operation (weather, stocks, currency, ...) aren't supported`
490
+ );
491
+ }
492
+ if (bodyResult.type === "error") {
493
+ throw bodyResult.error;
494
+ }
495
+ return bodyResult.value;
496
+ }
497
+ function extractDurationMs(value) {
498
+ if (value.type === 6 /* Uom */) {
499
+ const unit = value.unit;
500
+ if (unit && chunkQNJ4ACRT_cjs.getMeasure(unit) === "time") {
501
+ try {
502
+ return chunkQNJ4ACRT_cjs.convertUnit(value.toNumber(), unit, "ms");
503
+ } catch {
504
+ }
505
+ }
506
+ return 0;
507
+ }
508
+ return value.toNumber();
509
+ }
510
+ function addBusinessDays(epochMs, n) {
511
+ const date = new Date(epochMs);
512
+ let remaining = Math.trunc(Math.abs(n));
513
+ const direction = n >= 0 ? 1 : -1;
514
+ while (remaining > 0) {
515
+ date.setDate(date.getDate() + direction);
516
+ const day = date.getDay();
517
+ if (day !== 0 && day !== 6) remaining--;
518
+ }
519
+ return date.getTime();
520
+ }
521
+ function combineTimecode(tc, r, sign) {
522
+ const fps = chunkOC6LTXYS_cjs.timecodeFps(tc.unit);
523
+ if (r.type === 6 /* Uom */ && chunkOC6LTXYS_cjs.isTimecodeUnit(r.unit)) {
524
+ const rFps = chunkOC6LTXYS_cjs.timecodeFps(r.unit);
525
+ if (rFps !== fps) {
526
+ return chunkOC6LTXYS_cjs.errorValue(
527
+ "TIMECODE_FPS_MISMATCH",
528
+ `Cannot combine timecodes at different frame rates (${fps} fps vs ${rFps} fps)`
529
+ );
530
+ }
531
+ return sign === 1 ? chunkOC6LTXYS_cjs.uomValue(tc.toNumber() + r.toNumber(), tc.unit) : chunkOC6LTXYS_cjs.uomValue(tc.toNumber() - r.toNumber(), "frames");
532
+ }
533
+ if (r.type === 6 /* Uom */ && r.unit === "frames") {
534
+ return chunkOC6LTXYS_cjs.uomValue(tc.toNumber() + sign * r.toNumber(), tc.unit);
535
+ }
536
+ if (r.type === 6 /* Uom */ && r.unit && chunkQNJ4ACRT_cjs.getMeasure(r.unit) === "time") {
537
+ const seconds = chunkQNJ4ACRT_cjs.convertUnit(r.toNumber(), r.unit, "s");
538
+ return chunkOC6LTXYS_cjs.uomValue(tc.toNumber() + sign * seconds * fps, tc.unit);
539
+ }
540
+ return chunkOC6LTXYS_cjs.uomValue(tc.toNumber() + sign * r.toNumber(), tc.unit);
541
+ }
542
+ function isTruthy(value) {
543
+ if (value.type === 10 /* Boolean */) return value.value;
544
+ return value.toNumber() !== 0;
545
+ }
546
+ function multiplyRateByMatchingUom(rate, multiplier) {
547
+ const { numerator, denominator } = chunkOC6LTXYS_cjs.splitRateUnit(rate.unit);
548
+ const rateMeasure = chunkQNJ4ACRT_cjs.getMeasure(denominator);
549
+ const multiplierMeasure = chunkQNJ4ACRT_cjs.getMeasure(multiplier.unit);
550
+ if (!rateMeasure || rateMeasure !== multiplierMeasure) {
551
+ return chunkOC6LTXYS_cjs.errorValue(
552
+ "RATE_MUL_MEASURE_MISMATCH",
553
+ `Cannot multiply a "${denominator}"-denominated rate by "${multiplier.unit}" \u2014 different measures`
554
+ );
555
+ }
556
+ const multiplierInDenominatorUnit = chunkQNJ4ACRT_cjs.convertUnit(multiplier.toNumber(), multiplier.unit, denominator);
557
+ const total = rate.toNumber() * multiplierInDenominatorUnit;
558
+ return numerator ? chunkOC6LTXYS_cjs.uomValue(total, numerator) : chunkOC6LTXYS_cjs.numberValue(total);
559
+ }
560
+ function toFractionString(n) {
561
+ if (Number.isNaN(n)) return "NaN";
562
+ if (!isFinite(n)) return n > 0 ? "Infinity" : "-Infinity";
563
+ const negative = n < 0;
564
+ const abs = Math.abs(n);
565
+ const whole = Math.floor(abs);
566
+ const frac = abs - whole;
567
+ if (frac < 1e-9) return `${negative ? "-" : ""}${whole}`;
568
+ let h0 = 0, h1 = 1, k0 = 1, k1 = 0;
569
+ let b = frac;
570
+ const maxDenominator = 1e6;
571
+ for (let i = 0; i < 30; i++) {
572
+ const a = Math.floor(b + 1e-9);
573
+ const h2 = a * h1 + h0, k2 = a * k1 + k0;
574
+ if (k2 > maxDenominator) break;
575
+ h0 = h1;
576
+ h1 = h2;
577
+ k0 = k1;
578
+ k1 = k2;
579
+ if (Math.abs(frac - h1 / k1) < 1e-9) break;
580
+ const rem = b - a;
581
+ if (rem < 1e-9) break;
582
+ b = 1 / rem;
583
+ }
584
+ const numerator = whole * k1 + h1;
585
+ return `${negative ? "-" : ""}${numerator}/${k1}`;
586
+ }
587
+ function toMultiplierString(n) {
588
+ const multiplier = Math.round((1 + n) * 1e6) / 1e6;
589
+ return `${multiplier}x`;
590
+ }
591
+ function toScientificString(n) {
592
+ if (n === 0) return "0e+0";
593
+ const [mantissa, exponent] = n.toExponential().split("e");
594
+ const trimmed = mantissa.includes(".") ? mantissa.replace(/0+$/, "").replace(/\.$/, "") : mantissa;
595
+ return `${trimmed}e${exponent}`;
596
+ }
597
+ function executeBytecode(bytecode, vm, pipeline, expression, context, symbolicTolerant) {
598
+ const { opcodes, numbers, strings, userFunctionBodies, anonymousBodies } = bytecode;
599
+ let ip = 0;
600
+ let localInstructionCount = 0;
601
+ const maxInstructions = vm.getMaxInstructions();
602
+ const maxStackDepth = vm.getMaxStackDepth();
603
+ const stack = vm.getStack();
604
+ const shouldTrace = pipeline?.hasCollectors ?? false;
605
+ const hasArena = chunkOC6LTXYS_cjs.isArenaActive();
606
+ if (opcodes.length === 0) return { type: "value", value: chunkOC6LTXYS_cjs.numberValue(0) };
607
+ try {
608
+ while (ip < opcodes.length) {
609
+ if (++localInstructionCount > maxInstructions) {
610
+ throw chunkM4N5GA5Z_cjs.ErrorFactory.execution("INSTRUCTION_LIMIT_EXCEEDED", `Execution exceeded maximum of ${maxInstructions} instructions`);
611
+ }
612
+ if (stack.length > maxStackDepth) {
613
+ throw chunkM4N5GA5Z_cjs.ErrorFactory.execution("STACK_LIMIT_EXCEEDED", `Execution exceeded maximum stack depth of ${maxStackDepth}`);
614
+ }
615
+ const op = opcodes[ip++];
616
+ if (shouldTrace) {
617
+ const stackSnapshot = stack.map((v) => ({
618
+ type: v.type,
619
+ value: v.value,
620
+ unit: v.unit
621
+ }));
622
+ pipeline.fireVmStep({
623
+ type: chunk47LRVGOT_cjs.DiagnosticEventType.VmStep,
624
+ elapsedNs: 0,
625
+ expression: expression ?? "",
626
+ opcode: op,
627
+ opcodeName: chunkMZOVP3WI_cjs.getOpCodeName(op),
628
+ ip: ip - 1,
629
+ stackDepth: stack.length,
630
+ instructionNumber: localInstructionCount,
631
+ stack: stackSnapshot
632
+ });
633
+ }
634
+ switch (op) {
635
+ // ═══════════════════════════════════════════════════════════════
636
+ // §1 Stack operations (OpCode 0–3)
637
+ // ═══════════════════════════════════════════════════════════════
638
+ case 0 /* NOP */:
639
+ break;
640
+ case 1 /* HALT */: {
641
+ const result = safePop(stack);
642
+ return { type: "value", value: hasArena ? chunkOC6LTXYS_cjs.persistentValue(result) : result };
643
+ }
644
+ case 3 /* DUP */:
645
+ stack.push(stack[stack.length - 1]);
646
+ break;
647
+ case 2 /* SWAP */: {
648
+ const a = safePop(stack), b = safePop(stack);
649
+ stack.push(a);
650
+ stack.push(b);
651
+ break;
652
+ }
653
+ // ═══════════════════════════════════════════════════════════════
654
+ // §2 Push literals (OpCode 10–15)
655
+ // ═══════════════════════════════════════════════════════════════
656
+ case 10 /* PUSH_NUMBER */:
657
+ stack.push(chunkOC6LTXYS_cjs.numberValue(numbers[opcodes[ip++]]));
658
+ break;
659
+ case 11 /* PUSH_BIGINT */:
660
+ stack.push(chunkOC6LTXYS_cjs.bigIntValue(BigInt(strings[opcodes[ip++]])));
661
+ break;
662
+ case 12 /* PUSH_HEX */:
663
+ stack.push(chunkOC6LTXYS_cjs.hexValue(numbers[opcodes[ip++]]));
664
+ break;
665
+ case 13 /* PUSH_STRING */:
666
+ stack.push(chunkOC6LTXYS_cjs.stringValue(strings[opcodes[ip++]]));
667
+ break;
668
+ case 14 /* PUSH_BOOLEAN */:
669
+ stack.push(chunkOC6LTXYS_cjs.boolValue(opcodes[ip++] === 1));
670
+ break;
671
+ // ═══════════════════════════════════════════════════════════════
672
+ // §3 Arithmetic (OpCode 20–27)
673
+ // Binary ops (ADD/SUB/MUL/DIV/MOD/EXP) have inlined numeric
674
+ // fast paths; unary ops (NEG/POS) handle BigInt and UoM.
675
+ // ═══════════════════════════════════════════════════════════════
676
+ case 20 /* ADD */: {
677
+ const r = safePop(stack), l = safePop(stack);
678
+ if (l.type === 0 /* Number */ && r.type === 0 /* Number */) {
679
+ stack.push(chunkOC6LTXYS_cjs.numberValue(l.value + r.value));
680
+ } else if (l.type === 10 /* Boolean */ && r.type === 10 /* Boolean */) {
681
+ stack.push(chunkOC6LTXYS_cjs.boolValue(l.value && r.value));
682
+ } else if (l.type === 4 /* Datetime */) {
683
+ if (r.type === 4 /* Datetime */) {
684
+ stack.push(chunkOC6LTXYS_cjs.errorValue("INVALID_DATETIME_OP", "Cannot add two datetimes together"));
685
+ } else if (r.type === 6 /* Uom */ && chunkQNJ4ACRT_cjs.isWorkdayUnit(r.unit)) {
686
+ stack.push(chunkOC6LTXYS_cjs.datetimeValue(addBusinessDays(l.toNumber(), r.toNumber())));
687
+ } else {
688
+ stack.push(chunkOC6LTXYS_cjs.datetimeValue(l.toNumber() + extractDurationMs(r)));
689
+ }
690
+ } else if (l.type === 6 /* Uom */ && chunkOC6LTXYS_cjs.isTimecodeUnit(l.unit)) {
691
+ stack.push(combineTimecode(l, r, 1));
692
+ } else {
693
+ stack.push(chunkJ73SJHR3_cjs.binaryOp(l, r, (a, b) => a + b, (a, b) => a + b, "add"));
694
+ }
695
+ break;
696
+ }
697
+ case 21 /* SUB */: {
698
+ const r = safePop(stack), l = safePop(stack);
699
+ if (l.type === 0 /* Number */ && r.type === 0 /* Number */) {
700
+ stack.push(chunkOC6LTXYS_cjs.numberValue(l.value - r.value));
701
+ } else if (l.type === 4 /* Datetime */) {
702
+ if (r.type === 4 /* Datetime */) {
703
+ stack.push(chunkOC6LTXYS_cjs.uomValue(l.toNumber() - r.toNumber(), "ms"));
704
+ } else if (r.type === 6 /* Uom */ && chunkQNJ4ACRT_cjs.isWorkdayUnit(r.unit)) {
705
+ stack.push(chunkOC6LTXYS_cjs.datetimeValue(addBusinessDays(l.toNumber(), -r.toNumber())));
706
+ } else {
707
+ stack.push(chunkOC6LTXYS_cjs.datetimeValue(l.toNumber() - extractDurationMs(r)));
708
+ }
709
+ } else if (l.type === 6 /* Uom */ && chunkOC6LTXYS_cjs.isTimecodeUnit(l.unit)) {
710
+ stack.push(combineTimecode(l, r, -1));
711
+ } else {
712
+ stack.push(chunkJ73SJHR3_cjs.binaryOp(l, r, (a, b) => a - b, (a, b) => a - b, "sub"));
713
+ }
714
+ break;
715
+ }
716
+ case 22 /* MUL */: {
717
+ const r = safePop(stack), l = safePop(stack);
718
+ if (l.type === 0 /* Number */ && r.type === 0 /* Number */) {
719
+ stack.push(chunkOC6LTXYS_cjs.numberValue(l.value * r.value));
720
+ } else if (l.type === 7 /* Matrix */ && r.type === 7 /* Matrix */) {
721
+ stack.push(chunkHTXVVJRA_cjs.matrixMultiply(l.value, r.value));
722
+ } else if (l.type === 6 /* Uom */ && chunkOC6LTXYS_cjs.isRateUnit(l.unit) && r.type === 6 /* Uom */ && r.unit) {
723
+ stack.push(multiplyRateByMatchingUom(l, r));
724
+ } else if (r.type === 6 /* Uom */ && chunkOC6LTXYS_cjs.isRateUnit(r.unit) && l.type === 6 /* Uom */ && l.unit) {
725
+ stack.push(multiplyRateByMatchingUom(r, l));
726
+ } else {
727
+ stack.push(chunkJ73SJHR3_cjs.binaryOp(l, r, (a, b) => a * b, (a, b) => a * b, "mul"));
728
+ }
729
+ break;
730
+ }
731
+ case 23 /* DIV */: {
732
+ const r = safePop(stack), l = safePop(stack);
733
+ if (l.type === 6 /* Uom */ && r.type === 6 /* Uom */) {
734
+ const { lv, rv, sameMeasure } = chunkJ73SJHR3_cjs.unifyUom(l, r);
735
+ if (sameMeasure) {
736
+ stack.push(chunkOC6LTXYS_cjs.numberValue(lv / rv));
737
+ } else if (chunkXJCMXB2E_cjs.sharedCurrencyExchange.isCurrency(l.unit) && chunkXJCMXB2E_cjs.sharedCurrencyExchange.isCurrency(r.unit)) {
738
+ stack.push(chunkOC6LTXYS_cjs.errorValue("INCOMPATIBLE_UNITS", `Cannot combine incompatible units: ${l.unit} and ${r.unit}`));
739
+ } else {
740
+ stack.push(chunkOC6LTXYS_cjs.rateValue(lv / rv, l.unit, r.unit));
741
+ }
742
+ } else {
743
+ stack.push(chunkJ73SJHR3_cjs.binaryOp(l, r, (a, b) => a / b, (a, b) => a / b, "div"));
744
+ }
745
+ break;
746
+ }
747
+ case 24 /* MOD */: {
748
+ const r = safePop(stack), l = safePop(stack);
749
+ stack.push(chunkJ73SJHR3_cjs.binaryOp(l, r, (a, b) => a % b, (a, b) => a % b));
750
+ break;
751
+ }
752
+ case 25 /* EXP */: {
753
+ const r = safePop(stack), l = safePop(stack);
754
+ if (l.type === 13 /* Error */) {
755
+ stack.push(l);
756
+ break;
757
+ }
758
+ if (r.type === 13 /* Error */) {
759
+ stack.push(r);
760
+ break;
761
+ }
762
+ if (l.type === 12 /* Pending */) {
763
+ stack.push(l);
764
+ break;
765
+ }
766
+ if (r.type === 12 /* Pending */) {
767
+ stack.push(r);
768
+ break;
769
+ }
770
+ if (l.type === 0 /* Number */ && r.type === 0 /* Number */) {
771
+ stack.push(chunkOC6LTXYS_cjs.numberValue(Math.pow(l.value, r.value)));
772
+ break;
773
+ }
774
+ if (l.type === 9 /* Symbolic */ || r.type === 9 /* Symbolic */) {
775
+ stack.push(chunkJ73SJHR3_cjs.symbolicPow(l, r));
776
+ break;
777
+ }
778
+ stack.push(chunkOC6LTXYS_cjs.numberValue(Math.pow(l.toNumber(), r.toNumber())));
779
+ break;
780
+ }
781
+ case 26 /* NEG */: {
782
+ const v = safePop(stack);
783
+ if (v.type === 2 /* BigInt */) stack.push(chunkOC6LTXYS_cjs.bigIntValue(-v.value));
784
+ else if (v.type === 6 /* Uom */) stack.push(chunkOC6LTXYS_cjs.uomValue(-v.toNumber(), v.unit));
785
+ else if (v.type === 9 /* Symbolic */) stack.push(chunkJ73SJHR3_cjs.symbolicNeg(v));
786
+ else stack.push(chunkOC6LTXYS_cjs.numberValue(-v.toNumber()));
787
+ break;
788
+ }
789
+ case 27 /* POS */: {
790
+ const v = safePop(stack);
791
+ if (v.type === 6 /* Uom */) stack.push(chunkOC6LTXYS_cjs.uomValue(v.toNumber(), v.unit));
792
+ else stack.push(chunkOC6LTXYS_cjs.numberValue(v.toNumber()));
793
+ break;
794
+ }
795
+ // ═══════════════════════════════════════════════════════════════
796
+ // §4 Bitwise (OpCode 30–36)
797
+ // ═══════════════════════════════════════════════════════════════
798
+ case 30 /* LSHIFT */: {
799
+ const r = safePop(stack), l = safePop(stack);
800
+ if (l.type === 2 /* BigInt */ || r.type === 2 /* BigInt */) {
801
+ stack.push(chunkOC6LTXYS_cjs.bigIntValue(BigInt(l.toNumber()) << BigInt(r.toNumber())));
802
+ } else {
803
+ stack.push(chunkOC6LTXYS_cjs.numberValue(l.toNumber() << r.toNumber()));
804
+ }
805
+ break;
806
+ }
807
+ case 31 /* RSHIFT */: {
808
+ const r = safePop(stack), l = safePop(stack);
809
+ if (l.type === 2 /* BigInt */ || r.type === 2 /* BigInt */) {
810
+ stack.push(chunkOC6LTXYS_cjs.bigIntValue(BigInt(l.toNumber()) >> BigInt(r.toNumber())));
811
+ } else {
812
+ stack.push(chunkOC6LTXYS_cjs.numberValue(l.toNumber() >> r.toNumber()));
813
+ }
814
+ break;
815
+ }
816
+ case 32 /* URSHIFT */: {
817
+ const r = safePop(stack), l = safePop(stack);
818
+ stack.push(chunkOC6LTXYS_cjs.numberValue(l.toNumber() >>> r.toNumber()));
819
+ break;
820
+ }
821
+ case 33 /* BIT_AND */: {
822
+ const r = safePop(stack), l = safePop(stack);
823
+ if (l.type === 2 /* BigInt */ || r.type === 2 /* BigInt */) {
824
+ stack.push(chunkOC6LTXYS_cjs.bigIntValue(BigInt(l.toNumber()) & BigInt(r.toNumber())));
825
+ } else {
826
+ stack.push(chunkOC6LTXYS_cjs.numberValue(l.toNumber() & r.toNumber()));
827
+ }
828
+ break;
829
+ }
830
+ case 34 /* BIT_OR */: {
831
+ const r = safePop(stack), l = safePop(stack);
832
+ if (l.type === 2 /* BigInt */ || r.type === 2 /* BigInt */) {
833
+ stack.push(chunkOC6LTXYS_cjs.bigIntValue(BigInt(l.toNumber()) | BigInt(r.toNumber())));
834
+ } else {
835
+ stack.push(chunkOC6LTXYS_cjs.numberValue(l.toNumber() | r.toNumber()));
836
+ }
837
+ break;
838
+ }
839
+ case 35 /* BIT_XOR */: {
840
+ const r = safePop(stack), l = safePop(stack);
841
+ if (l.type === 2 /* BigInt */ || r.type === 2 /* BigInt */) {
842
+ stack.push(chunkOC6LTXYS_cjs.bigIntValue(BigInt(l.toNumber()) ^ BigInt(r.toNumber())));
843
+ } else {
844
+ stack.push(chunkOC6LTXYS_cjs.numberValue(l.toNumber() ^ r.toNumber()));
845
+ }
846
+ break;
847
+ }
848
+ case 36 /* BIT_NOT */: {
849
+ const v = safePop(stack);
850
+ if (v.type === 2 /* BigInt */) stack.push(chunkOC6LTXYS_cjs.bigIntValue(~v.value));
851
+ else stack.push(chunkOC6LTXYS_cjs.numberValue(~v.toNumber()));
852
+ break;
853
+ }
854
+ // ═══════════════════════════════════════════════════════════════
855
+ // §4b Comparison (OpCode 40–45)
856
+ // Numeric fast path when both operands are Number;
857
+ // EQ/NEQ support UoM unification for same-measure comparison.
858
+ // ═══════════════════════════════════════════════════════════════
859
+ case 40 /* EQ */: {
860
+ const r = safePop(stack), l = safePop(stack);
861
+ if (l.type === 0 /* Number */ && r.type === 0 /* Number */) {
862
+ stack.push(chunkOC6LTXYS_cjs.boolValue(l.value === r.value));
863
+ } else if (l.type === 6 /* Uom */ && r.type === 6 /* Uom */) {
864
+ const { lv, rv, sameMeasure } = chunkJ73SJHR3_cjs.unifyUom(l, r);
865
+ stack.push(chunkOC6LTXYS_cjs.boolValue(sameMeasure && lv === rv));
866
+ } else if (l.type === 7 /* Matrix */ && r.type === 7 /* Matrix */) {
867
+ stack.push(chunkHTXVVJRA_cjs.matrixCompare(l.value, r.value, (a, b) => a === b));
868
+ } else {
869
+ stack.push(chunkOC6LTXYS_cjs.boolValue(l.toNumber() === r.toNumber()));
870
+ }
871
+ break;
872
+ }
873
+ case 41 /* NEQ */: {
874
+ const r = safePop(stack), l = safePop(stack);
875
+ if (l.type === 0 /* Number */ && r.type === 0 /* Number */) {
876
+ stack.push(chunkOC6LTXYS_cjs.boolValue(l.value !== r.value));
877
+ } else if (l.type === 6 /* Uom */ && r.type === 6 /* Uom */) {
878
+ const { lv, rv, sameMeasure } = chunkJ73SJHR3_cjs.unifyUom(l, r);
879
+ stack.push(chunkOC6LTXYS_cjs.boolValue(!sameMeasure || lv !== rv));
880
+ } else if (l.type === 7 /* Matrix */ && r.type === 7 /* Matrix */) {
881
+ stack.push(chunkHTXVVJRA_cjs.matrixCompare(l.value, r.value, (a, b) => a !== b));
882
+ } else {
883
+ stack.push(chunkOC6LTXYS_cjs.boolValue(l.toNumber() !== r.toNumber()));
884
+ }
885
+ break;
886
+ }
887
+ case 42 /* LT */: {
888
+ const r = safePop(stack), l = safePop(stack);
889
+ if (l.type === 0 /* Number */ && r.type === 0 /* Number */) {
890
+ stack.push(chunkOC6LTXYS_cjs.boolValue(l.value < r.value));
891
+ } else if (l.type === 7 /* Matrix */ && r.type === 7 /* Matrix */) {
892
+ stack.push(chunkHTXVVJRA_cjs.matrixCompare(l.value, r.value, (a, b) => a < b));
893
+ } else {
894
+ stack.push(chunkOC6LTXYS_cjs.boolValue(l.toNumber() < r.toNumber()));
895
+ }
896
+ break;
897
+ }
898
+ case 43 /* LTE */: {
899
+ const r = safePop(stack), l = safePop(stack);
900
+ if (l.type === 0 /* Number */ && r.type === 0 /* Number */) {
901
+ stack.push(chunkOC6LTXYS_cjs.boolValue(l.value <= r.value));
902
+ } else if (l.type === 7 /* Matrix */ && r.type === 7 /* Matrix */) {
903
+ stack.push(chunkHTXVVJRA_cjs.matrixCompare(l.value, r.value, (a, b) => a <= b));
904
+ } else {
905
+ stack.push(chunkOC6LTXYS_cjs.boolValue(l.toNumber() <= r.toNumber()));
906
+ }
907
+ break;
908
+ }
909
+ case 44 /* GT */: {
910
+ const r = safePop(stack), l = safePop(stack);
911
+ if (l.type === 0 /* Number */ && r.type === 0 /* Number */) {
912
+ stack.push(chunkOC6LTXYS_cjs.boolValue(l.value > r.value));
913
+ } else if (l.type === 7 /* Matrix */ && r.type === 7 /* Matrix */) {
914
+ stack.push(chunkHTXVVJRA_cjs.matrixCompare(l.value, r.value, (a, b) => a > b));
915
+ } else {
916
+ stack.push(chunkOC6LTXYS_cjs.boolValue(l.toNumber() > r.toNumber()));
917
+ }
918
+ break;
919
+ }
920
+ case 45 /* GTE */: {
921
+ const r = safePop(stack), l = safePop(stack);
922
+ if (l.type === 0 /* Number */ && r.type === 0 /* Number */) {
923
+ stack.push(chunkOC6LTXYS_cjs.boolValue(l.value >= r.value));
924
+ } else if (l.type === 7 /* Matrix */ && r.type === 7 /* Matrix */) {
925
+ stack.push(chunkHTXVVJRA_cjs.matrixCompare(l.value, r.value, (a, b) => a >= b));
926
+ } else {
927
+ stack.push(chunkOC6LTXYS_cjs.boolValue(l.toNumber() >= r.toNumber()));
928
+ }
929
+ break;
930
+ }
931
+ // ═══════════════════════════════════════════════════════════════
932
+ // §4c Logical / conditional select (OpCode 130–132)
933
+ // ═══════════════════════════════════════════════════════════════
934
+ case 130 /* LOGICAL_AND */: {
935
+ const r = safePop(stack), l = safePop(stack);
936
+ stack.push(chunkOC6LTXYS_cjs.boolValue(isTruthy(l) && isTruthy(r)));
937
+ break;
938
+ }
939
+ case 131 /* LOGICAL_OR */: {
940
+ const r = safePop(stack), l = safePop(stack);
941
+ stack.push(chunkOC6LTXYS_cjs.boolValue(isTruthy(l) || isTruthy(r)));
942
+ break;
943
+ }
944
+ case 132 /* SELECT */: {
945
+ const elseVal = safePop(stack);
946
+ const thenVal = safePop(stack);
947
+ const condition = safePop(stack);
948
+ stack.push(isTruthy(condition) ? thenVal : elseVal);
949
+ break;
950
+ }
951
+ // ═══════════════════════════════════════════════════════════════
952
+ // §5 Functions (OpCode 50–52)
953
+ // ═══════════════════════════════════════════════════════════════
954
+ case 50 /* CALL_PLUGIN */: {
955
+ const fnIdx = opcodes[ip++];
956
+ const argCount = opcodes[ip++];
957
+ const args = [];
958
+ for (let i = 0; i < argCount; i++) args.push(safePop(stack));
959
+ args.reverse();
960
+ const fn = vm.context.pluginFunctions[fnIdx];
961
+ if (!fn) {
962
+ stack.push(chunkOC6LTXYS_cjs.numberValue(0));
963
+ } else {
964
+ const result = fn(args, context);
965
+ if (result instanceof Promise) {
966
+ const cacheKey = `plugin:${fnIdx}:${args.map((a) => String(a.value ?? "")).join("|")}`;
967
+ const signal = vm.activeSignal;
968
+ const packageId = vm.context.pluginFunctionOwners[fnIdx] ?? "";
969
+ return { type: "pending", queryKey: cacheKey, resolver: result, packageId, signal };
970
+ }
971
+ stack.push(result);
972
+ }
973
+ break;
974
+ }
975
+ case 51 /* CALL_BUILTIN */: {
976
+ const fnIdx = opcodes[ip++];
977
+ const argCount = opcodes[ip++];
978
+ const args = [];
979
+ let sawSymbolic = false;
980
+ for (let i = 0; i < argCount; i++) {
981
+ const arg = safePop(stack);
982
+ if (arg.type === 9 /* Symbolic */) sawSymbolic = true;
983
+ args.push(arg);
984
+ }
985
+ const fn = chunkJ73SJHR3_cjs.builtinFunctions[fnIdx];
986
+ if (fn) {
987
+ const ordered = args.reverse();
988
+ const routeSymbolically = sawSymbolic && !chunkJ73SJHR3_cjs.SYMBOLIC_NATIVE_BUILTINS.has(fnIdx);
989
+ stack.push(routeSymbolically ? chunkJ73SJHR3_cjs.symbolicBuiltin(fnIdx, ordered) : fn(ordered));
990
+ }
991
+ break;
992
+ }
993
+ case 150 /* DEFINE_USER_FUNCTION */: {
994
+ const bodyIdx = opcodes[ip++];
995
+ const def = userFunctionBodies?.[bodyIdx];
996
+ if (!def) {
997
+ throw chunkM4N5GA5Z_cjs.ErrorFactory.internal(
998
+ "INTERNAL_MISSING_FUNCTION_BODY",
999
+ `Internal error: DEFINE_USER_FUNCTION referenced missing body index ${bodyIdx}`,
1000
+ { bodyIdx }
1001
+ );
1002
+ }
1003
+ vm.defineUserFunction(def.name, def.params, def.program);
1004
+ break;
1005
+ }
1006
+ case 151 /* CALL_USER_FUNCTION */: {
1007
+ const nameIdx = opcodes[ip++];
1008
+ const argCount = opcodes[ip++];
1009
+ const name = strings[nameIdx];
1010
+ const args = [];
1011
+ for (let i = 0; i < argCount; i++) args.push(safePop(stack));
1012
+ args.reverse();
1013
+ const fn = vm.getUserFunction(name);
1014
+ if (!fn) {
1015
+ throw chunkM4N5GA5Z_cjs.ErrorFactory.execution("UNDEFINED_FUNCTION", `Undefined function: ${name}`, { name });
1016
+ }
1017
+ if (argCount !== fn.params.length) {
1018
+ throw chunkM4N5GA5Z_cjs.ErrorFactory.execution(
1019
+ "FUNCTION_ARITY_MISMATCH",
1020
+ `${name} expects ${fn.params.length} argument(s) but got ${argCount}`,
1021
+ { name, expected: fn.params.length, actual: argCount }
1022
+ );
1023
+ }
1024
+ const frame = /* @__PURE__ */ new Map();
1025
+ for (let i = 0; i < fn.params.length; i++) frame.set(fn.params[i], args[i]);
1026
+ vm.pushCallFrame(frame);
1027
+ let bodyResult;
1028
+ try {
1029
+ bodyResult = executeBytecode(fn.program, vm, pipeline, expression, context);
1030
+ } finally {
1031
+ vm.popCallFrame();
1032
+ }
1033
+ if (bodyResult.type === "pending") {
1034
+ throw chunkM4N5GA5Z_cjs.ErrorFactory.execution(
1035
+ "USER_FUNCTION_ASYNC_UNSUPPORTED",
1036
+ `${name}: user-defined functions with async bodies (weather, stocks, currency, ...) aren't supported`,
1037
+ { name }
1038
+ );
1039
+ }
1040
+ if (bodyResult.type === "error") {
1041
+ throw bodyResult.error;
1042
+ }
1043
+ stack.push(bodyResult.value);
1044
+ break;
1045
+ }
1046
+ // ═══════════════════════════════════════════════════════════════
1047
+ // §6 Variables (OpCode 60–63)
1048
+ // ═══════════════════════════════════════════════════════════════
1049
+ case 60 /* LOAD_VAR */: {
1050
+ const varName = strings[opcodes[ip++]];
1051
+ const val = vm.getVar(varName);
1052
+ if (val !== void 0) {
1053
+ stack.push(val);
1054
+ } else if (symbolicTolerant) {
1055
+ stack.push(chunkOC6LTXYS_cjs.symbolicValue(chunkHTXVVJRA_cjs.varNode(varName)));
1056
+ } else {
1057
+ throw chunkM4N5GA5Z_cjs.ErrorFactory.execution(
1058
+ "UNDEFINED_VARIABLE",
1059
+ `Undefined variable: ${varName}`,
1060
+ { varName }
1061
+ );
1062
+ }
1063
+ break;
1064
+ }
1065
+ case 61 /* STORE_VAR */: {
1066
+ const val = safePop(stack);
1067
+ const varName = strings[opcodes[ip++]];
1068
+ vm.setVar(varName, hasArena ? chunkOC6LTXYS_cjs.persistentValue(val) : val);
1069
+ stack.push(val);
1070
+ break;
1071
+ }
1072
+ case 62 /* LOAD_GLOBAL_VAR */: {
1073
+ const varName = strings[opcodes[ip++]];
1074
+ const globalValue = chunkJ73SJHR3_cjs.sharedGlobalVariableStore.get(varName);
1075
+ if (globalValue === void 0) {
1076
+ throw chunkM4N5GA5Z_cjs.ErrorFactory.internal({
1077
+ code: "GLOBAL_VARIABLE_NOT_RESOLVED",
1078
+ message: `Global variable "${varName}" was read before it resolved`,
1079
+ expected: `global variable "${varName}" to already be resolved (async preflight should guarantee this)`,
1080
+ found: "no value in the global variable store",
1081
+ context: { varName }
1082
+ });
1083
+ }
1084
+ stack.push(globalValue);
1085
+ break;
1086
+ }
1087
+ case 63 /* STORE_GLOBAL_VAR */: {
1088
+ const val = safePop(stack);
1089
+ const varName = strings[opcodes[ip++]];
1090
+ chunkJ73SJHR3_cjs.sharedGlobalVariableStore.set(varName, hasArena ? chunkOC6LTXYS_cjs.persistentValue(val) : val);
1091
+ stack.push(val);
1092
+ break;
1093
+ }
1094
+ // ═══════════════════════════════════════════════════════════════
1095
+ // §7 Type conversions (OpCode 70–74, 140–145)
1096
+ // ═══════════════════════════════════════════════════════════════
1097
+ case 70 /* TO_NUMBER */: {
1098
+ const v = safePop(stack);
1099
+ stack.push(chunkOC6LTXYS_cjs.numberValue(v.toNumber()));
1100
+ break;
1101
+ }
1102
+ case 71 /* TO_HEX */: {
1103
+ const v = safePop(stack);
1104
+ stack.push(chunkOC6LTXYS_cjs.hexValue(v.toNumber()));
1105
+ break;
1106
+ }
1107
+ case 74 /* TO_PERCENTAGE */: {
1108
+ const v = safePop(stack);
1109
+ stack.push(chunkOC6LTXYS_cjs.percentageValue(v.toNumber()));
1110
+ break;
1111
+ }
1112
+ case 140 /* TO_FRACTION */: {
1113
+ const v = safePop(stack);
1114
+ stack.push(chunkOC6LTXYS_cjs.stringValue(toFractionString(v.toNumber())));
1115
+ break;
1116
+ }
1117
+ case 141 /* TO_MULTIPLIER */: {
1118
+ const v = safePop(stack);
1119
+ stack.push(chunkOC6LTXYS_cjs.stringValue(toMultiplierString(v.toNumber())));
1120
+ break;
1121
+ }
1122
+ case 142 /* TO_SCI */: {
1123
+ const v = safePop(stack);
1124
+ stack.push(chunkOC6LTXYS_cjs.stringValue(toScientificString(v.toNumber())));
1125
+ break;
1126
+ }
1127
+ // Numeric, like TO_HEX above. A base is a way of writing a number, so
1128
+ // `(255 as binary) + 1` has to be 256; as a string it was 1.
1129
+ case 143 /* TO_BINARY */: {
1130
+ const v = safePop(stack);
1131
+ stack.push(chunkOC6LTXYS_cjs.hexValue(v.toNumber(), "bin"));
1132
+ break;
1133
+ }
1134
+ case 144 /* TO_OCTAL */: {
1135
+ const v = safePop(stack);
1136
+ stack.push(chunkOC6LTXYS_cjs.hexValue(v.toNumber(), "oct"));
1137
+ break;
1138
+ }
1139
+ case 145 /* CALL_AS_CONVERTER */: {
1140
+ const name = safePop(stack).value.toLowerCase();
1141
+ const value = safePop(stack);
1142
+ const converter = chunkJ73SJHR3_cjs.asConverterRegistry.get(name);
1143
+ if (!converter) {
1144
+ stack.push(chunkOC6LTXYS_cjs.errorValue("UNKNOWN_AS_CONVERTER", `Unknown converter "as ${name}"`));
1145
+ } else {
1146
+ stack.push(converter(value));
1147
+ }
1148
+ break;
1149
+ }
1150
+ // ═══════════════════════════════════════════════════════════════
1151
+ // §8 UoM (OpCode 80–84)
1152
+ // ═══════════════════════════════════════════════════════════════
1153
+ case 80 /* UOM_CONVERT */: {
1154
+ const unit = safePop(stack).value;
1155
+ const val = safePop(stack).toNumber();
1156
+ stack.push(chunkOC6LTXYS_cjs.uomValue(val, unit));
1157
+ break;
1158
+ }
1159
+ case 81 /* UOM_CONVERT_TO */: {
1160
+ const toUnit = safePop(stack).value;
1161
+ const fromUnit = safePop(stack).value;
1162
+ const val = safePop(stack).toNumber();
1163
+ const measure = chunkQNJ4ACRT_cjs.getMeasure(fromUnit);
1164
+ const isCurrency = chunkXJCMXB2E_cjs.sharedCurrencyExchange.isCurrency(fromUnit) && chunkXJCMXB2E_cjs.sharedCurrencyExchange.isCurrency(toUnit);
1165
+ if (measure && chunkQNJ4ACRT_cjs.getMeasure(toUnit) === measure) {
1166
+ stack.push(chunkOC6LTXYS_cjs.uomValue(chunkQNJ4ACRT_cjs.convertUnit(val, fromUnit, toUnit), toUnit));
1167
+ } else if (isCurrency) {
1168
+ const converted = chunkXJCMXB2E_cjs.sharedCurrencyExchange.convertSync(val, fromUnit, toUnit);
1169
+ if (converted !== null) {
1170
+ stack.push(chunkOC6LTXYS_cjs.uomValue(converted, toUnit));
1171
+ } else {
1172
+ stack.push(chunkOC6LTXYS_cjs.errorValue("CURRENCY_RATE_UNAVAILABLE", `No exchange rate available for ${fromUnit} to ${toUnit}`));
1173
+ }
1174
+ } else {
1175
+ stack.push(chunkOC6LTXYS_cjs.uomValue(val, fromUnit));
1176
+ }
1177
+ break;
1178
+ }
1179
+ case 85 /* UOM_POSSIBILITIES */: {
1180
+ const unit = safePop(stack).value;
1181
+ const possibilities = chunkQNJ4ACRT_cjs.getConvertiblePossibilities(unit);
1182
+ stack.push(chunkOC6LTXYS_cjs.stringValue(possibilities.length > 0 ? possibilities.join(", ") : `No known units for "${unit}"`));
1183
+ break;
1184
+ }
1185
+ case 83 /* UOM_BEST */: {
1186
+ const unit = safePop(stack).value;
1187
+ const val = safePop(stack).toNumber();
1188
+ const { value, unit: bestUnit } = chunkQNJ4ACRT_cjs.getBestUnit(val, unit);
1189
+ stack.push(chunkOC6LTXYS_cjs.uomValue(value, bestUnit));
1190
+ break;
1191
+ }
1192
+ case 84 /* UOM_CONVERT_IN */: {
1193
+ const toUnit = safePop(stack).value;
1194
+ const left = safePop(stack);
1195
+ if (left.type === 6 /* Uom */) {
1196
+ const fromUnit = left.unit;
1197
+ const val = left.toNumber();
1198
+ const measure = chunkQNJ4ACRT_cjs.getMeasure(fromUnit);
1199
+ const isCurrency = chunkXJCMXB2E_cjs.sharedCurrencyExchange.isCurrency(fromUnit) && chunkXJCMXB2E_cjs.sharedCurrencyExchange.isCurrency(toUnit);
1200
+ if (measure && chunkQNJ4ACRT_cjs.getMeasure(toUnit) === measure) {
1201
+ stack.push(chunkOC6LTXYS_cjs.uomValue(chunkQNJ4ACRT_cjs.convertUnit(val, fromUnit, toUnit), toUnit));
1202
+ } else if (isCurrency) {
1203
+ const converted = chunkXJCMXB2E_cjs.sharedCurrencyExchange.convertSync(val, fromUnit, toUnit);
1204
+ if (converted !== null) {
1205
+ stack.push(chunkOC6LTXYS_cjs.uomValue(converted, toUnit));
1206
+ } else {
1207
+ stack.push(chunkOC6LTXYS_cjs.errorValue("CURRENCY_RATE_UNAVAILABLE", `No exchange rate available for ${fromUnit} to ${toUnit}`));
1208
+ }
1209
+ } else {
1210
+ stack.push(left);
1211
+ }
1212
+ } else {
1213
+ stack.push(chunkOC6LTXYS_cjs.uomValue(left.toNumber(), toUnit));
1214
+ }
1215
+ break;
1216
+ }
1217
+ case 82 /* UOM_GET_VALUE */: {
1218
+ const v = safePop(stack);
1219
+ stack.push(chunkOC6LTXYS_cjs.numberValue(v.toNumber()));
1220
+ break;
1221
+ }
1222
+ // ═══════════════════════════════════════════════════════════════
1223
+ // §8.5 Rate, "quantity per unit of something" (OpCode 110–112)
1224
+ // See vm/Value.ts's rateValue()/isRateUnit()/splitRateUnit().
1225
+ // ═══════════════════════════════════════════════════════════════
1226
+ case 110 /* RATE_DIV */: {
1227
+ const denominatorVal = safePop(stack);
1228
+ const numeratorVal = safePop(stack);
1229
+ if (denominatorVal.type !== 6 /* Uom */ || !denominatorVal.unit) {
1230
+ stack.push(chunkOC6LTXYS_cjs.errorValue("RATE_MISSING_DENOMINATOR_UNIT", 'Cannot build a rate: the right-hand side of "/" has no unit'));
1231
+ break;
1232
+ }
1233
+ const numeratorUnit = numeratorVal.type === 6 /* Uom */ ? numeratorVal.unit ?? "" : "";
1234
+ stack.push(chunkOC6LTXYS_cjs.rateValue(numeratorVal.toNumber() / denominatorVal.toNumber(), numeratorUnit, denominatorVal.unit));
1235
+ break;
1236
+ }
1237
+ case 111 /* RATE_MUL */: {
1238
+ const multiplier = safePop(stack);
1239
+ const rate = safePop(stack);
1240
+ if (rate.type !== 6 /* Uom */ || !chunkOC6LTXYS_cjs.isRateUnit(rate.unit)) {
1241
+ stack.push(chunkOC6LTXYS_cjs.errorValue("RATE_MUL_LEFT_NOT_A_RATE", 'Left-hand side of a rate multiplication must be a rate (e.g. "$50/week")'));
1242
+ break;
1243
+ }
1244
+ if (multiplier.type !== 6 /* Uom */ || !multiplier.unit) {
1245
+ stack.push(chunkOC6LTXYS_cjs.errorValue("RATE_MUL_RIGHT_MISSING_UNIT", "Right-hand side of a rate multiplication must have a unit matching the rate's denominator"));
1246
+ break;
1247
+ }
1248
+ stack.push(multiplyRateByMatchingUom(rate, multiplier));
1249
+ break;
1250
+ }
1251
+ case 112 /* RATE_CONVERT */: {
1252
+ const newDenominatorUnit = safePop(stack).value;
1253
+ const rate = safePop(stack);
1254
+ if (rate.type !== 6 /* Uom */ || !chunkOC6LTXYS_cjs.isRateUnit(rate.unit)) {
1255
+ stack.push(chunkOC6LTXYS_cjs.errorValue("RATE_CONVERT_NOT_A_RATE", "Cannot convert a non-rate value's denominator"));
1256
+ break;
1257
+ }
1258
+ const { numerator, denominator } = chunkOC6LTXYS_cjs.splitRateUnit(rate.unit);
1259
+ const rateMeasure = chunkQNJ4ACRT_cjs.getMeasure(denominator);
1260
+ const targetMeasure = chunkQNJ4ACRT_cjs.getMeasure(newDenominatorUnit);
1261
+ if (!rateMeasure || rateMeasure !== targetMeasure) {
1262
+ stack.push(chunkOC6LTXYS_cjs.errorValue(
1263
+ "RATE_CONVERT_MEASURE_MISMATCH",
1264
+ `Cannot convert a "${denominator}"-denominated rate to "${newDenominatorUnit}" \u2014 different measures`
1265
+ ));
1266
+ break;
1267
+ }
1268
+ const factor = chunkQNJ4ACRT_cjs.convertUnit(1, newDenominatorUnit, denominator);
1269
+ stack.push(chunkOC6LTXYS_cjs.rateValue(rate.toNumber() * factor, numerator, newDenominatorUnit));
1270
+ break;
1271
+ }
1272
+ // ═══════════════════════════════════════════════════════════════
1273
+ // §8.7 Time, clock-time-of-day (OpCode 120)
1274
+ // ═══════════════════════════════════════════════════════════════
1275
+ case 120 /* CLOCK_TIME_TODAY */: {
1276
+ const totalMinutes = safePop(stack).toNumber();
1277
+ const now = /* @__PURE__ */ new Date();
1278
+ const anchored = new Date(now.getFullYear(), now.getMonth(), now.getDate(), 0, 0, 0, 0);
1279
+ anchored.setMinutes(totalMinutes);
1280
+ stack.push(chunkOC6LTXYS_cjs.datetimeValue(anchored.getTime()));
1281
+ break;
1282
+ }
1283
+ // ═══════════════════════════════════════════════════════════════
1284
+ // §9 Datetime (OpCode 90–93)
1285
+ // ═══════════════════════════════════════════════════════════════
1286
+ case 90 /* DATE_NOW */:
1287
+ stack.push(chunkOC6LTXYS_cjs.datetimeValue(Date.now()));
1288
+ break;
1289
+ case 95 /* DATE_LITERAL */:
1290
+ stack.push(chunkOC6LTXYS_cjs.datetimeValue(numbers[opcodes[ip++]]));
1291
+ break;
1292
+ case 91 /* DATE_ADD */: {
1293
+ const durValue = safePop(stack), dtValue = safePop(stack);
1294
+ stack.push(chunkOC6LTXYS_cjs.datetimeValue(dtValue.toNumber() + extractDurationMs(durValue)));
1295
+ break;
1296
+ }
1297
+ case 92 /* DATE_SUB */: {
1298
+ const durValue = safePop(stack), dtValue = safePop(stack);
1299
+ stack.push(chunkOC6LTXYS_cjs.datetimeValue(dtValue.toNumber() - extractDurationMs(durValue)));
1300
+ break;
1301
+ }
1302
+ case 93 /* DATE_NEXT_WEEKDAY */:
1303
+ case 94 /* DATE_LAST_WEEKDAY */: {
1304
+ const targetDay = safePop(stack).toNumber();
1305
+ const nowValue = safePop(stack);
1306
+ const now = nowValue.toNumber();
1307
+ const currentDay = new Date(now).getDay();
1308
+ let diffDays = op === 93 /* DATE_NEXT_WEEKDAY */ ? (targetDay - currentDay + 7) % 7 : (currentDay - targetDay + 7) % 7;
1309
+ if (diffDays === 0) diffDays = 7;
1310
+ const offsetMs = diffDays * 24 * 60 * 60 * 1e3;
1311
+ stack.push(chunkOC6LTXYS_cjs.datetimeValue(op === 93 /* DATE_NEXT_WEEKDAY */ ? now + offsetMs : now - offsetMs));
1312
+ break;
1313
+ }
1314
+ // ═══════════════════════════════════════════════════════════════
1315
+ // §10 Matrix (OpCode 152+, see parser/OpCode.ts's Matrix band)
1316
+ // Replaces the old ARR_* vector-only opcodes (100-107), which
1317
+ // were never emitted by any registered parselet in production
1318
+ // confirmed dead code, deleted outright rather than repurposed.
1319
+ // See vm/Value.ts's MatrixData and vm/MatrixOps.ts's shared
1320
+ // column-major storage helpers.
1321
+ // ═══════════════════════════════════════════════════════════════
1322
+ case 152 /* MAT_NEW */: {
1323
+ const rows = opcodes[ip++];
1324
+ const cols = opcodes[ip++];
1325
+ const count = rows * cols;
1326
+ const rowMajor = new Array(count);
1327
+ for (let i = count - 1; i >= 0; i--) {
1328
+ const cellVal = safePop(stack);
1329
+ rowMajor[i] = cellVal.type === 10 /* Boolean */ ? cellVal.value : cellVal.type === 9 /* Symbolic */ ? cellVal.value : cellVal.toNumber();
1330
+ }
1331
+ stack.push(chunkOC6LTXYS_cjs.matrixValue(rows, cols, chunkHTXVVJRA_cjs.rowMajorToColumnMajor(rows, cols, rowMajor)));
1332
+ break;
1333
+ }
1334
+ case 153 /* MAT_INDEX1 */: {
1335
+ const indexVal = safePop(stack), matrixVal = safePop(stack);
1336
+ if (matrixVal.type === 13 /* Error */) {
1337
+ stack.push(matrixVal);
1338
+ break;
1339
+ }
1340
+ if (indexVal.type === 13 /* Error */) {
1341
+ stack.push(indexVal);
1342
+ break;
1343
+ }
1344
+ if (matrixVal.type !== 7 /* Matrix */) {
1345
+ stack.push(chunkOC6LTXYS_cjs.errorValue("MATRIX_INDEX_NOT_A_MATRIX", `Cannot index a non-matrix value with "[...]".`));
1346
+ break;
1347
+ }
1348
+ const m = matrixVal.value;
1349
+ const index = Math.trunc(indexVal.toNumber());
1350
+ if (index < 0 || index >= m.data.length) {
1351
+ stack.push(chunkOC6LTXYS_cjs.errorValue(
1352
+ "MATRIX_INDEX_OUT_OF_BOUNDS",
1353
+ `Index ${index} is out of bounds for a ${m.rows}x${m.cols} matrix (valid range: 0-${m.data.length - 1}).`
1354
+ ));
1355
+ break;
1356
+ }
1357
+ const cell = chunkHTXVVJRA_cjs.matIndex(m, index);
1358
+ stack.push(chunkHTXVVJRA_cjs.matrixEntryToValue(cell));
1359
+ break;
1360
+ }
1361
+ case 154 /* MAT_INDEX2 */: {
1362
+ const colVal = safePop(stack), rowVal = safePop(stack), matrixVal = safePop(stack);
1363
+ if (matrixVal.type === 13 /* Error */) {
1364
+ stack.push(matrixVal);
1365
+ break;
1366
+ }
1367
+ if (rowVal.type === 13 /* Error */) {
1368
+ stack.push(rowVal);
1369
+ break;
1370
+ }
1371
+ if (colVal.type === 13 /* Error */) {
1372
+ stack.push(colVal);
1373
+ break;
1374
+ }
1375
+ if (matrixVal.type !== 7 /* Matrix */) {
1376
+ stack.push(chunkOC6LTXYS_cjs.errorValue("MATRIX_INDEX_NOT_A_MATRIX", `Cannot index a non-matrix value with "[...]".`));
1377
+ break;
1378
+ }
1379
+ const m = matrixVal.value;
1380
+ const row = Math.trunc(rowVal.toNumber());
1381
+ const col = Math.trunc(colVal.toNumber());
1382
+ if (!chunkHTXVVJRA_cjs.inBounds(m, row, col)) {
1383
+ stack.push(chunkOC6LTXYS_cjs.errorValue(
1384
+ "MATRIX_INDEX_OUT_OF_BOUNDS",
1385
+ `[${row}, ${col}] is out of bounds for a ${m.rows}x${m.cols} matrix.`
1386
+ ));
1387
+ break;
1388
+ }
1389
+ const cell = chunkHTXVVJRA_cjs.matAt(m, row, col);
1390
+ stack.push(chunkHTXVVJRA_cjs.matrixEntryToValue(cell));
1391
+ break;
1392
+ }
1393
+ case 156 /* RANGE_NEW */: {
1394
+ const maxVal = safePop(stack), minVal = safePop(stack);
1395
+ if (minVal.type === 13 /* Error */) {
1396
+ stack.push(minVal);
1397
+ break;
1398
+ }
1399
+ if (maxVal.type === 13 /* Error */) {
1400
+ stack.push(maxVal);
1401
+ break;
1402
+ }
1403
+ if (minVal.type !== 0 /* Number */ || maxVal.type !== 0 /* Number */) {
1404
+ stack.push(chunkOC6LTXYS_cjs.errorValue("INVALID_RANGE_BOUND", `A range's bounds must be plain numbers (e.g. "0:3").`));
1405
+ break;
1406
+ }
1407
+ const min = minVal.value;
1408
+ const max = maxVal.value;
1409
+ if (!Number.isInteger(min) || !Number.isInteger(max)) {
1410
+ stack.push(chunkOC6LTXYS_cjs.errorValue("NON_INTEGER_RANGE_BOUND", `A range's bounds must be whole numbers, got "${min}:${max}".`));
1411
+ break;
1412
+ }
1413
+ if (min > max) {
1414
+ stack.push(chunkOC6LTXYS_cjs.errorValue(
1415
+ "DESCENDING_RANGE",
1416
+ `A range's min (${min}) cannot be greater than its max (${max}) \u2014 did you mean "${max}:${min}"?`
1417
+ ));
1418
+ break;
1419
+ }
1420
+ stack.push(chunkOC6LTXYS_cjs.rangeValue(min, max));
1421
+ break;
1422
+ }
1423
+ case 155 /* MAT_SLICE */: {
1424
+ const colRangeVal = safePop(stack), rowRangeVal = safePop(stack), matrixVal = safePop(stack);
1425
+ if (matrixVal.type === 13 /* Error */) {
1426
+ stack.push(matrixVal);
1427
+ break;
1428
+ }
1429
+ if (rowRangeVal.type === 13 /* Error */) {
1430
+ stack.push(rowRangeVal);
1431
+ break;
1432
+ }
1433
+ if (colRangeVal.type === 13 /* Error */) {
1434
+ stack.push(colRangeVal);
1435
+ break;
1436
+ }
1437
+ if (matrixVal.type !== 7 /* Matrix */) {
1438
+ stack.push(chunkOC6LTXYS_cjs.errorValue("MATRIX_INDEX_NOT_A_MATRIX", `Cannot slice a non-matrix value with "[...]".`));
1439
+ break;
1440
+ }
1441
+ if (rowRangeVal.type !== 8 /* Range */ || colRangeVal.type !== 8 /* Range */) {
1442
+ stack.push(chunkOC6LTXYS_cjs.errorValue("INVALID_MATRIX_SLICE_BOUND", `Matrix slicing needs range bounds (e.g. "a[0:1, 1:2]").`));
1443
+ break;
1444
+ }
1445
+ const m = matrixVal.value;
1446
+ const rowRange = rowRangeVal.value;
1447
+ const colRange = colRangeVal.value;
1448
+ if (rowRange.min < 0 || rowRange.max >= m.rows || colRange.min < 0 || colRange.max >= m.cols) {
1449
+ stack.push(chunkOC6LTXYS_cjs.errorValue(
1450
+ "MATRIX_INDEX_OUT_OF_BOUNDS",
1451
+ `Slice [${rowRange.min}:${rowRange.max}, ${colRange.min}:${colRange.max}] is out of bounds for a ${m.rows}x${m.cols} matrix.`
1452
+ ));
1453
+ break;
1454
+ }
1455
+ const newRows = rowRange.max - rowRange.min + 1;
1456
+ const newCols = colRange.max - colRange.min + 1;
1457
+ const data = new Array(newRows * newCols);
1458
+ for (let r = 0; r < newRows; r++) {
1459
+ for (let c = 0; c < newCols; c++) {
1460
+ data[r + c * newRows] = chunkHTXVVJRA_cjs.matAt(m, rowRange.min + r, colRange.min + c);
1461
+ }
1462
+ }
1463
+ stack.push(chunkOC6LTXYS_cjs.matrixValue(newRows, newCols, data));
1464
+ break;
1465
+ }
1466
+ // ═══════════════════════════════════════════════════════════════
1467
+ // §11 map/reduce (OpCode 157-158, see parser/OpCode.ts's Matrix
1468
+ // band). See packages/mapreduce/ for the parselets that decide
1469
+ // `kind` (0=inline anonymous body, 1=builtin function,
1470
+ // 2=user-defined function) at parse time, and
1471
+ // `BytecodeBuilder.ts`'s AnonymousBodyDef doc comment for why
1472
+ // kind-0 bodies are a SEPARATE side-table from userFunctionBodies.
1473
+ // ═══════════════════════════════════════════════════════════════
1474
+ case 157 /* MAP_INVOKE */: {
1475
+ const kind = opcodes[ip++];
1476
+ const ref = opcodes[ip++];
1477
+ const collectionCount = opcodes[ip++];
1478
+ const rawCollections = new Array(collectionCount);
1479
+ for (let i = collectionCount - 1; i >= 0; i--) rawCollections[i] = safePop(stack);
1480
+ let paramNames = [];
1481
+ let program;
1482
+ if (kind === 0) {
1483
+ const def = anonymousBodies?.[ref];
1484
+ if (!def) {
1485
+ throw chunkM4N5GA5Z_cjs.ErrorFactory.internal(
1486
+ "INTERNAL_MISSING_ANONYMOUS_BODY",
1487
+ `Internal error: MAP_INVOKE referenced missing anonymous body index ${ref}`,
1488
+ { ref }
1489
+ );
1490
+ }
1491
+ paramNames = def.params;
1492
+ program = def.program;
1493
+ } else if (kind === 2) {
1494
+ const name = strings[ref];
1495
+ const fn = vm.getUserFunction(name);
1496
+ if (!fn) {
1497
+ stack.push(chunkOC6LTXYS_cjs.errorValue("UNDEFINED_FUNCTION", `map: undefined function "${name}"`));
1498
+ break;
1499
+ }
1500
+ if (fn.params.length !== collectionCount) {
1501
+ stack.push(chunkOC6LTXYS_cjs.errorValue(
1502
+ "FUNCTION_ARITY_MISMATCH",
1503
+ `map: "${name}" expects ${fn.params.length} argument(s) but ${collectionCount} collection(s) were given`
1504
+ ));
1505
+ break;
1506
+ }
1507
+ paramNames = fn.params;
1508
+ program = fn.program;
1509
+ }
1510
+ let collectionLength = -1;
1511
+ const cellArrays = new Array(collectionCount);
1512
+ let mapEarlyError;
1513
+ for (let i = 0; i < collectionCount; i++) {
1514
+ const resolved = chunkHTXVVJRA_cjs.collectionToValues(rawCollections[i]);
1515
+ if (!Array.isArray(resolved)) {
1516
+ mapEarlyError = resolved;
1517
+ break;
1518
+ }
1519
+ if (collectionLength === -1) {
1520
+ collectionLength = resolved.length;
1521
+ } else if (resolved.length !== collectionLength) {
1522
+ mapEarlyError = chunkOC6LTXYS_cjs.errorValue(
1523
+ "MAP_COLLECTION_LENGTH_MISMATCH",
1524
+ `map: all collections must have the same length (got ${collectionLength} and ${resolved.length}).`
1525
+ );
1526
+ break;
1527
+ }
1528
+ cellArrays[i] = resolved;
1529
+ }
1530
+ if (mapEarlyError) {
1531
+ stack.push(mapEarlyError);
1532
+ break;
1533
+ }
1534
+ const resultData = new Array(collectionLength);
1535
+ let mapError;
1536
+ for (let i = 0; i < collectionLength; i++) {
1537
+ const args = new Array(collectionCount);
1538
+ for (let j = 0; j < collectionCount; j++) args[j] = cellArrays[j][i];
1539
+ const resultVal = kind === 1 ? chunkJ73SJHR3_cjs.builtinFunctions[ref]?.(args) ?? chunkOC6LTXYS_cjs.errorValue("UNKNOWN_BUILTIN_FUNCTION", `map: unknown builtin function index ${ref}`) : invokeFrameBody(paramNames, program, args, vm, pipeline, expression, context, !!symbolicTolerant);
1540
+ if (resultVal.type === 13 /* Error */) {
1541
+ mapError = resultVal;
1542
+ break;
1543
+ }
1544
+ resultData[i] = resultVal.type === 10 /* Boolean */ ? resultVal.value : resultVal.type === 9 /* Symbolic */ ? resultVal.value : resultVal.toNumber();
1545
+ }
1546
+ if (mapError) {
1547
+ stack.push(mapError);
1548
+ break;
1549
+ }
1550
+ stack.push(chunkOC6LTXYS_cjs.matrixValue(1, collectionLength, resultData));
1551
+ break;
1552
+ }
1553
+ case 158 /* REDUCE_INVOKE */: {
1554
+ const kind = opcodes[ip++];
1555
+ const ref = opcodes[ip++];
1556
+ const hasInitial = opcodes[ip++];
1557
+ const initialVal = hasInitial ? safePop(stack) : void 0;
1558
+ const collectionVal = safePop(stack);
1559
+ let paramNames = [];
1560
+ let program;
1561
+ if (kind === 0) {
1562
+ const def = anonymousBodies?.[ref];
1563
+ if (!def) {
1564
+ throw chunkM4N5GA5Z_cjs.ErrorFactory.internal(
1565
+ "INTERNAL_MISSING_ANONYMOUS_BODY",
1566
+ `Internal error: REDUCE_INVOKE referenced missing anonymous body index ${ref}`,
1567
+ { ref }
1568
+ );
1569
+ }
1570
+ paramNames = def.params;
1571
+ program = def.program;
1572
+ } else if (kind === 2) {
1573
+ const name = strings[ref];
1574
+ const fn = vm.getUserFunction(name);
1575
+ if (!fn) {
1576
+ stack.push(chunkOC6LTXYS_cjs.errorValue("UNDEFINED_FUNCTION", `reduce: undefined function "${name}"`));
1577
+ break;
1578
+ }
1579
+ if (fn.params.length !== 2) {
1580
+ stack.push(chunkOC6LTXYS_cjs.errorValue(
1581
+ "FUNCTION_ARITY_MISMATCH",
1582
+ `reduce: "${name}" must take exactly 2 arguments (accumulator, element), got ${fn.params.length}`
1583
+ ));
1584
+ break;
1585
+ }
1586
+ paramNames = fn.params;
1587
+ program = fn.program;
1588
+ }
1589
+ const cells = chunkHTXVVJRA_cjs.collectionToValues(collectionVal);
1590
+ if (!Array.isArray(cells)) {
1591
+ stack.push(cells);
1592
+ break;
1593
+ }
1594
+ let acc;
1595
+ let startIdx;
1596
+ if (initialVal !== void 0) {
1597
+ if (initialVal.type === 13 /* Error */) {
1598
+ stack.push(initialVal);
1599
+ break;
1600
+ }
1601
+ acc = initialVal;
1602
+ startIdx = 0;
1603
+ } else {
1604
+ if (cells.length === 0) {
1605
+ stack.push(chunkOC6LTXYS_cjs.errorValue("REDUCE_EMPTY_COLLECTION", `reduce: cannot reduce an empty collection without an initial value.`));
1606
+ break;
1607
+ }
1608
+ acc = cells[0];
1609
+ startIdx = 1;
1610
+ }
1611
+ let reduceError;
1612
+ for (let i = startIdx; i < cells.length; i++) {
1613
+ const args = [acc, cells[i]];
1614
+ const resultVal = kind === 1 ? chunkJ73SJHR3_cjs.builtinFunctions[ref]?.(args) ?? chunkOC6LTXYS_cjs.errorValue("UNKNOWN_BUILTIN_FUNCTION", `reduce: unknown builtin function index ${ref}`) : invokeFrameBody(paramNames, program, args, vm, pipeline, expression, context, !!symbolicTolerant);
1615
+ if (resultVal.type === 13 /* Error */) {
1616
+ reduceError = resultVal;
1617
+ break;
1618
+ }
1619
+ acc = resultVal;
1620
+ }
1621
+ if (reduceError) {
1622
+ stack.push(reduceError);
1623
+ break;
1624
+ }
1625
+ stack.push(acc);
1626
+ break;
1627
+ }
1628
+ }
1629
+ }
1630
+ const fallback = safePop(stack);
1631
+ return { type: "value", value: hasArena ? chunkOC6LTXYS_cjs.persistentValue(fallback) : fallback };
1632
+ } catch (e) {
1633
+ return { type: "error", error: chunkM4N5GA5Z_cjs.normalizeUnknownError(e) };
1634
+ }
1635
+ }
1636
+
1637
+ exports.DependencyGraph = DependencyGraph;
1638
+ exports.ScopeManager = ScopeManager;
1639
+ exports.createVM = createVM;
1640
+ exports.executeBytecode = executeBytecode;
1641
+ //# sourceMappingURL=chunk-6NTVRDQV.cjs.map
1642
+ //# sourceMappingURL=chunk-6NTVRDQV.cjs.map