circle-ir 4.9.20 → 4.9.22

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 (263) hide show
  1. package/dist/analysis/config-loader.js.map +1 -1
  2. package/dist/analysis/constant-propagation/evaluator.d.ts.map +1 -1
  3. package/dist/analysis/constant-propagation/evaluator.js.map +1 -1
  4. package/dist/analysis/constant-propagation/index.js.map +1 -1
  5. package/dist/analysis/constant-propagation/propagator.d.ts.map +1 -1
  6. package/dist/analysis/constant-propagation/propagator.js +3 -1
  7. package/dist/analysis/constant-propagation/propagator.js.map +1 -1
  8. package/dist/analysis/dfg-verifier.d.ts.map +1 -1
  9. package/dist/analysis/dfg-verifier.js.map +1 -1
  10. package/dist/analysis/dfg-walk.js.map +1 -1
  11. package/dist/analysis/findings.d.ts +1 -1
  12. package/dist/analysis/findings.d.ts.map +1 -1
  13. package/dist/analysis/findings.js +27 -1
  14. package/dist/analysis/findings.js.map +1 -1
  15. package/dist/analysis/interprocedural.js.map +1 -1
  16. package/dist/analysis/metrics/metric-runner.d.ts.map +1 -1
  17. package/dist/analysis/metrics/passes/cohesion-metrics-pass.d.ts.map +1 -1
  18. package/dist/analysis/metrics/passes/complexity-metrics-pass.d.ts.map +1 -1
  19. package/dist/analysis/metrics/passes/composite-metrics-pass.d.ts.map +1 -1
  20. package/dist/analysis/metrics/passes/coupling-metrics-pass.d.ts.map +1 -1
  21. package/dist/analysis/metrics/passes/data-flow-metrics-pass.d.ts.map +1 -1
  22. package/dist/analysis/metrics/passes/documentation-metrics-pass.d.ts.map +1 -1
  23. package/dist/analysis/metrics/passes/halstead-metrics-pass.d.ts.map +1 -1
  24. package/dist/analysis/metrics/passes/inheritance-metrics-pass.d.ts.map +1 -1
  25. package/dist/analysis/metrics/passes/size-metrics-pass.d.ts.map +1 -1
  26. package/dist/analysis/modelled-cwes.d.ts +35 -0
  27. package/dist/analysis/modelled-cwes.d.ts.map +1 -0
  28. package/dist/analysis/modelled-cwes.js +63 -0
  29. package/dist/analysis/modelled-cwes.js.map +1 -0
  30. package/dist/analysis/passes/blocking-main-thread-pass.d.ts +1 -1
  31. package/dist/analysis/passes/blocking-main-thread-pass.d.ts.map +1 -1
  32. package/dist/analysis/passes/broad-catch-pass.d.ts +1 -1
  33. package/dist/analysis/passes/broad-catch-pass.d.ts.map +1 -1
  34. package/dist/analysis/passes/cache-no-vary-pass.d.ts +1 -1
  35. package/dist/analysis/passes/cache-no-vary-pass.d.ts.map +1 -1
  36. package/dist/analysis/passes/circular-dependency-pass.d.ts.map +1 -1
  37. package/dist/analysis/passes/cleanup-verify-pass.d.ts +1 -1
  38. package/dist/analysis/passes/cleanup-verify-pass.d.ts.map +1 -1
  39. package/dist/analysis/passes/cleartext-credential-transport-pass.d.ts +1 -1
  40. package/dist/analysis/passes/cleartext-credential-transport-pass.d.ts.map +1 -1
  41. package/dist/analysis/passes/cli-main-reflection-suppress-pass.d.ts +1 -1
  42. package/dist/analysis/passes/cli-main-reflection-suppress-pass.d.ts.map +1 -1
  43. package/dist/analysis/passes/constant-propagation-pass.d.ts +1 -1
  44. package/dist/analysis/passes/constant-propagation-pass.d.ts.map +1 -1
  45. package/dist/analysis/passes/constant-propagation-pass.js.map +1 -1
  46. package/dist/analysis/passes/cross-file-pass.d.ts.map +1 -1
  47. package/dist/analysis/passes/cross-file-pass.js +1 -1
  48. package/dist/analysis/passes/cross-file-pass.js.map +1 -1
  49. package/dist/analysis/passes/csrf-protection-disabled-pass.d.ts +1 -1
  50. package/dist/analysis/passes/csrf-protection-disabled-pass.d.ts.map +1 -1
  51. package/dist/analysis/passes/dead-code-pass.d.ts +1 -1
  52. package/dist/analysis/passes/dead-code-pass.d.ts.map +1 -1
  53. package/dist/analysis/passes/deep-inheritance-pass.d.ts +1 -1
  54. package/dist/analysis/passes/deep-inheritance-pass.d.ts.map +1 -1
  55. package/dist/analysis/passes/dependency-fan-out-pass.d.ts +1 -1
  56. package/dist/analysis/passes/dependency-fan-out-pass.d.ts.map +1 -1
  57. package/dist/analysis/passes/deserialization-safety-gate-pass.d.ts +1 -1
  58. package/dist/analysis/passes/deserialization-safety-gate-pass.d.ts.map +1 -1
  59. package/dist/analysis/passes/deserialization-safety-gate-pass.js.map +1 -1
  60. package/dist/analysis/passes/double-close-pass.d.ts +1 -1
  61. package/dist/analysis/passes/double-close-pass.d.ts.map +1 -1
  62. package/dist/analysis/passes/excessive-allocation-pass.d.ts +1 -1
  63. package/dist/analysis/passes/excessive-allocation-pass.d.ts.map +1 -1
  64. package/dist/analysis/passes/feature-envy-pass.d.ts +1 -1
  65. package/dist/analysis/passes/feature-envy-pass.d.ts.map +1 -1
  66. package/dist/analysis/passes/god-class-pass.d.ts +1 -1
  67. package/dist/analysis/passes/god-class-pass.d.ts.map +1 -1
  68. package/dist/analysis/passes/infinite-loop-pass.d.ts +1 -1
  69. package/dist/analysis/passes/infinite-loop-pass.d.ts.map +1 -1
  70. package/dist/analysis/passes/info-disclosure-stacktrace-pass.d.ts +1 -1
  71. package/dist/analysis/passes/info-disclosure-stacktrace-pass.d.ts.map +1 -1
  72. package/dist/analysis/passes/insecure-cookie-pass.d.ts +1 -1
  73. package/dist/analysis/passes/insecure-cookie-pass.d.ts.map +1 -1
  74. package/dist/analysis/passes/insecure-deserialization-config-pass.d.ts +1 -1
  75. package/dist/analysis/passes/insecure-deserialization-config-pass.d.ts.map +1 -1
  76. package/dist/analysis/passes/interprocedural-pass.d.ts +1 -1
  77. package/dist/analysis/passes/interprocedural-pass.d.ts.map +1 -1
  78. package/dist/analysis/passes/jwt-verify-disabled-pass.d.ts +1 -1
  79. package/dist/analysis/passes/jwt-verify-disabled-pass.d.ts.map +1 -1
  80. package/dist/analysis/passes/language-sources-pass.d.ts +10 -10
  81. package/dist/analysis/passes/language-sources-pass.d.ts.map +1 -1
  82. package/dist/analysis/passes/language-sources-pass.js +3 -8
  83. package/dist/analysis/passes/language-sources-pass.js.map +1 -1
  84. package/dist/analysis/passes/leaked-global-pass.d.ts +1 -1
  85. package/dist/analysis/passes/leaked-global-pass.d.ts.map +1 -1
  86. package/dist/analysis/passes/library-profile-sink-gate-pass.d.ts +2 -2
  87. package/dist/analysis/passes/library-profile-sink-gate-pass.d.ts.map +1 -1
  88. package/dist/analysis/passes/library-profile-source-gate-pass.d.ts +1 -1
  89. package/dist/analysis/passes/library-profile-source-gate-pass.d.ts.map +1 -1
  90. package/dist/analysis/passes/library-profile-xss-gate-pass.d.ts +1 -1
  91. package/dist/analysis/passes/library-profile-xss-gate-pass.d.ts.map +1 -1
  92. package/dist/analysis/passes/mass-assignment-pass.d.ts +1 -1
  93. package/dist/analysis/passes/mass-assignment-pass.d.ts.map +1 -1
  94. package/dist/analysis/passes/missing-await-pass.d.ts +1 -1
  95. package/dist/analysis/passes/missing-await-pass.d.ts.map +1 -1
  96. package/dist/analysis/passes/missing-guard-dom-pass.d.ts +1 -1
  97. package/dist/analysis/passes/missing-guard-dom-pass.d.ts.map +1 -1
  98. package/dist/analysis/passes/missing-override-pass.d.ts +1 -1
  99. package/dist/analysis/passes/missing-override-pass.d.ts.map +1 -1
  100. package/dist/analysis/passes/missing-public-doc-pass.d.ts +1 -1
  101. package/dist/analysis/passes/missing-public-doc-pass.d.ts.map +1 -1
  102. package/dist/analysis/passes/missing-sanitizer-gate-pass.d.ts +1 -1
  103. package/dist/analysis/passes/missing-sanitizer-gate-pass.d.ts.map +1 -1
  104. package/dist/analysis/passes/missing-stream-pass.d.ts +1 -1
  105. package/dist/analysis/passes/missing-stream-pass.d.ts.map +1 -1
  106. package/dist/analysis/passes/module-side-effect-pass.d.ts +1 -1
  107. package/dist/analysis/passes/module-side-effect-pass.d.ts.map +1 -1
  108. package/dist/analysis/passes/mybatis-annotation-sql-sink-pass.d.ts +1 -1
  109. package/dist/analysis/passes/mybatis-annotation-sql-sink-pass.d.ts.map +1 -1
  110. package/dist/analysis/passes/n-plus-one-pass.d.ts +1 -1
  111. package/dist/analysis/passes/n-plus-one-pass.d.ts.map +1 -1
  112. package/dist/analysis/passes/naming-convention-pass.d.ts +1 -1
  113. package/dist/analysis/passes/naming-convention-pass.d.ts.map +1 -1
  114. package/dist/analysis/passes/naming-convention-pass.js.map +1 -1
  115. package/dist/analysis/passes/null-deref-pass.d.ts +1 -1
  116. package/dist/analysis/passes/null-deref-pass.d.ts.map +1 -1
  117. package/dist/analysis/passes/orphan-module-pass.d.ts.map +1 -1
  118. package/dist/analysis/passes/plaintext-password-storage-pass.d.ts +1 -1
  119. package/dist/analysis/passes/plaintext-password-storage-pass.d.ts.map +1 -1
  120. package/dist/analysis/passes/prompt-injection-safety-gate-pass.d.ts +1 -1
  121. package/dist/analysis/passes/prompt-injection-safety-gate-pass.d.ts.map +1 -1
  122. package/dist/analysis/passes/python-receiver-taint-format-pass.d.ts +1 -1
  123. package/dist/analysis/passes/python-receiver-taint-format-pass.d.ts.map +1 -1
  124. package/dist/analysis/passes/react-inline-jsx-pass.d.ts +1 -1
  125. package/dist/analysis/passes/react-inline-jsx-pass.d.ts.map +1 -1
  126. package/dist/analysis/passes/redundant-loop-pass.d.ts +1 -1
  127. package/dist/analysis/passes/redundant-loop-pass.d.ts.map +1 -1
  128. package/dist/analysis/passes/resource-leak-pass.d.ts +1 -1
  129. package/dist/analysis/passes/resource-leak-pass.d.ts.map +1 -1
  130. package/dist/analysis/passes/scan-secrets-pass.d.ts +1 -1
  131. package/dist/analysis/passes/scan-secrets-pass.d.ts.map +1 -1
  132. package/dist/analysis/passes/security-headers-pass.d.ts +1 -1
  133. package/dist/analysis/passes/security-headers-pass.d.ts.map +1 -1
  134. package/dist/analysis/passes/security-headers-pass.js.map +1 -1
  135. package/dist/analysis/passes/serial-await-pass.d.ts +1 -1
  136. package/dist/analysis/passes/serial-await-pass.d.ts.map +1 -1
  137. package/dist/analysis/passes/sink-filter-pass.d.ts +1 -1
  138. package/dist/analysis/passes/sink-filter-pass.d.ts.map +1 -1
  139. package/dist/analysis/passes/sink-filter-pass.js +1 -1
  140. package/dist/analysis/passes/sink-filter-pass.js.map +1 -1
  141. package/dist/analysis/passes/sink-semantics-pass.d.ts +1 -1
  142. package/dist/analysis/passes/sink-semantics-pass.d.ts.map +1 -1
  143. package/dist/analysis/passes/source-semantics-pass.d.ts +1 -1
  144. package/dist/analysis/passes/source-semantics-pass.d.ts.map +1 -1
  145. package/dist/analysis/passes/speculative-prompt-param-source-pass.d.ts +1 -1
  146. package/dist/analysis/passes/speculative-prompt-param-source-pass.d.ts.map +1 -1
  147. package/dist/analysis/passes/speculative-prompt-param-source-pass.js.map +1 -1
  148. package/dist/analysis/passes/spring4shell-pass.d.ts +1 -1
  149. package/dist/analysis/passes/spring4shell-pass.d.ts.map +1 -1
  150. package/dist/analysis/passes/stale-doc-ref-pass.d.ts +1 -1
  151. package/dist/analysis/passes/stale-doc-ref-pass.d.ts.map +1 -1
  152. package/dist/analysis/passes/string-concat-loop-pass.d.ts +1 -1
  153. package/dist/analysis/passes/string-concat-loop-pass.d.ts.map +1 -1
  154. package/dist/analysis/passes/swallowed-exception-pass.d.ts +1 -1
  155. package/dist/analysis/passes/swallowed-exception-pass.d.ts.map +1 -1
  156. package/dist/analysis/passes/sync-io-async-pass.d.ts +1 -1
  157. package/dist/analysis/passes/sync-io-async-pass.d.ts.map +1 -1
  158. package/dist/analysis/passes/taint-matcher-pass.d.ts +1 -1
  159. package/dist/analysis/passes/taint-matcher-pass.d.ts.map +1 -1
  160. package/dist/analysis/passes/taint-propagation-pass.d.ts +1 -1
  161. package/dist/analysis/passes/taint-propagation-pass.d.ts.map +1 -1
  162. package/dist/analysis/passes/tls-verify-disabled-pass.d.ts +1 -1
  163. package/dist/analysis/passes/tls-verify-disabled-pass.d.ts.map +1 -1
  164. package/dist/analysis/passes/todo-in-prod-pass.d.ts +1 -1
  165. package/dist/analysis/passes/todo-in-prod-pass.d.ts.map +1 -1
  166. package/dist/analysis/passes/unbounded-collection-pass.d.ts +1 -1
  167. package/dist/analysis/passes/unbounded-collection-pass.d.ts.map +1 -1
  168. package/dist/analysis/passes/unchecked-return-pass.d.ts +1 -1
  169. package/dist/analysis/passes/unchecked-return-pass.d.ts.map +1 -1
  170. package/dist/analysis/passes/unhandled-exception-pass.d.ts +1 -1
  171. package/dist/analysis/passes/unhandled-exception-pass.d.ts.map +1 -1
  172. package/dist/analysis/passes/unhandled-exception-pass.js +4 -20
  173. package/dist/analysis/passes/unhandled-exception-pass.js.map +1 -1
  174. package/dist/analysis/passes/unrestricted-file-upload-pass.d.ts +1 -1
  175. package/dist/analysis/passes/unrestricted-file-upload-pass.d.ts.map +1 -1
  176. package/dist/analysis/passes/unused-interface-method-pass.d.ts +1 -1
  177. package/dist/analysis/passes/unused-interface-method-pass.d.ts.map +1 -1
  178. package/dist/analysis/passes/unused-variable-pass.d.ts +1 -1
  179. package/dist/analysis/passes/unused-variable-pass.d.ts.map +1 -1
  180. package/dist/analysis/passes/use-after-close-pass.d.ts +1 -1
  181. package/dist/analysis/passes/use-after-close-pass.d.ts.map +1 -1
  182. package/dist/analysis/passes/variable-shadowing-pass.d.ts +1 -1
  183. package/dist/analysis/passes/variable-shadowing-pass.d.ts.map +1 -1
  184. package/dist/analysis/passes/weak-crypto-pass.d.ts +1 -1
  185. package/dist/analysis/passes/weak-crypto-pass.d.ts.map +1 -1
  186. package/dist/analysis/passes/weak-hash-pass.d.ts +1 -1
  187. package/dist/analysis/passes/weak-hash-pass.d.ts.map +1 -1
  188. package/dist/analysis/passes/weak-password-encoding-pass.d.ts +1 -1
  189. package/dist/analysis/passes/weak-password-encoding-pass.d.ts.map +1 -1
  190. package/dist/analysis/passes/weak-password-hash-pass.d.ts +1 -1
  191. package/dist/analysis/passes/weak-password-hash-pass.d.ts.map +1 -1
  192. package/dist/analysis/passes/weak-random-pass.d.ts +1 -1
  193. package/dist/analysis/passes/weak-random-pass.d.ts.map +1 -1
  194. package/dist/analysis/passes/xml-entity-expansion-pass.d.ts +47 -4
  195. package/dist/analysis/passes/xml-entity-expansion-pass.d.ts.map +1 -1
  196. package/dist/analysis/passes/xml-entity-expansion-pass.js +139 -13
  197. package/dist/analysis/passes/xml-entity-expansion-pass.js.map +1 -1
  198. package/dist/analysis/path-finder.d.ts.map +1 -1
  199. package/dist/analysis/path-finder.js.map +1 -1
  200. package/dist/analysis/project-profile-transform.js.map +1 -1
  201. package/dist/analysis/require-entry-path.js.map +1 -1
  202. package/dist/analysis/sbom.js.map +1 -1
  203. package/dist/analysis/taint-matcher.js.map +1 -1
  204. package/dist/analyzer.d.ts.map +1 -1
  205. package/dist/analyzer.js +4 -0
  206. package/dist/analyzer.js.map +1 -1
  207. package/dist/browser/circle-ir.js +199 -62
  208. package/dist/browser.js.map +1 -1
  209. package/dist/core/circle-ir-core.cjs +94 -22
  210. package/dist/core/circle-ir-core.js +94 -22
  211. package/dist/core/extractors/cfg.js +2 -2
  212. package/dist/core/extractors/cfg.js.map +1 -1
  213. package/dist/core/extractors/dfg.js +1 -1
  214. package/dist/core/extractors/dfg.js.map +1 -1
  215. package/dist/core/extractors/runtime-registrations.js +2 -2
  216. package/dist/core/extractors/runtime-registrations.js.map +1 -1
  217. package/dist/core/extractors/types.js.map +1 -1
  218. package/dist/core/parser.d.ts.map +1 -1
  219. package/dist/core/parser.js +4 -0
  220. package/dist/core/parser.js.map +1 -1
  221. package/dist/graph/analysis-pass.d.ts.map +1 -1
  222. package/dist/graph/code-graph.d.ts.map +1 -1
  223. package/dist/graph/dominator-graph.d.ts.map +1 -1
  224. package/dist/graph/exception-flow-graph.d.ts.map +1 -1
  225. package/dist/graph/import-graph.d.ts.map +1 -1
  226. package/dist/graph/project-graph.d.ts.map +1 -1
  227. package/dist/graph/scope-graph.d.ts.map +1 -1
  228. package/dist/index.d.ts +1 -0
  229. package/dist/index.d.ts.map +1 -1
  230. package/dist/index.js +3 -0
  231. package/dist/index.js.map +1 -1
  232. package/dist/languages/plugins/base.d.ts.map +1 -1
  233. package/dist/languages/plugins/bash.d.ts +1 -1
  234. package/dist/languages/plugins/bash.d.ts.map +1 -1
  235. package/dist/languages/plugins/csharp.d.ts +1 -1
  236. package/dist/languages/plugins/csharp.d.ts.map +1 -1
  237. package/dist/languages/plugins/go.d.ts +1 -1
  238. package/dist/languages/plugins/go.d.ts.map +1 -1
  239. package/dist/languages/plugins/html.d.ts +1 -1
  240. package/dist/languages/plugins/html.d.ts.map +1 -1
  241. package/dist/languages/plugins/index.d.ts +8 -0
  242. package/dist/languages/plugins/index.d.ts.map +1 -1
  243. package/dist/languages/plugins/index.js +21 -9
  244. package/dist/languages/plugins/index.js.map +1 -1
  245. package/dist/languages/plugins/java.d.ts +1 -1
  246. package/dist/languages/plugins/java.d.ts.map +1 -1
  247. package/dist/languages/plugins/javascript.d.ts +1 -1
  248. package/dist/languages/plugins/javascript.d.ts.map +1 -1
  249. package/dist/languages/plugins/python.d.ts +1 -1
  250. package/dist/languages/plugins/python.d.ts.map +1 -1
  251. package/dist/languages/plugins/rust.d.ts +1 -1
  252. package/dist/languages/plugins/rust.d.ts.map +1 -1
  253. package/dist/languages/plugins/vue.d.ts +1 -1
  254. package/dist/languages/plugins/vue.d.ts.map +1 -1
  255. package/dist/resolution/cross-file.d.ts.map +1 -1
  256. package/dist/resolution/symbol-table.d.ts.map +1 -1
  257. package/dist/resolution/type-hierarchy.d.ts.map +1 -1
  258. package/dist/resolution/type-hierarchy.js.map +1 -1
  259. package/dist/types/index.d.ts +28 -0
  260. package/dist/types/index.d.ts.map +1 -1
  261. package/dist/utils/logger.d.ts.map +1 -1
  262. package/dist/wasm/web-tree-sitter.wasm +0 -0
  263. package/package.json +7 -7
@@ -122,6 +122,18 @@ function setModule(module2) {
122
122
  }
123
123
  __name(setModule, "setModule");
124
124
  var C;
125
+ function newFinalizer(handler) {
126
+ try {
127
+ return new FinalizationRegistry(handler);
128
+ } catch (e) {
129
+ console.error("Unsupported FinalizationRegistry:", e);
130
+ return;
131
+ }
132
+ }
133
+ __name(newFinalizer, "newFinalizer");
134
+ var finalizer = newFinalizer((address) => {
135
+ C._ts_lookahead_iterator_delete(address);
136
+ });
125
137
  var LookaheadIterator = class {
126
138
  static {
127
139
  __name(this, "LookaheadIterator");
@@ -132,21 +144,39 @@ var LookaheadIterator = class {
132
144
  /** @internal */
133
145
  language;
134
146
  /** @internal */
147
+ positioned = false;
148
+ /** @internal */
135
149
  constructor(internal, address, language) {
136
150
  assertInternal(internal);
137
151
  this[0] = address;
138
152
  this.language = language;
153
+ finalizer?.register(this, address, this);
139
154
  }
140
- /** Get the current symbol of the lookahead iterator. */
155
+ /**
156
+ * Get the current symbol of the lookahead iterator.
157
+ *
158
+ * Returns `null` if the iterator is not positioned on a symbol:
159
+ *
160
+ * - Before the first iteration step
161
+ * - After the iterator is exhausted
162
+ * - After a {@link reset} or {@link resetState} call
163
+ */
141
164
  get currentTypeId() {
142
- return C._ts_lookahead_iterator_current_symbol(this[0]);
165
+ return this.positioned ? C._ts_lookahead_iterator_current_symbol(this[0]) : null;
143
166
  }
144
- /** Get the current symbol name of the lookahead iterator. */
167
+ /**
168
+ * Get the current symbol name of the lookahead iterator.
169
+ *
170
+ * Returns `null` if the iterator is not positioned on a symbol.
171
+ */
145
172
  get currentType() {
146
- return this.language.types[this.currentTypeId] || "ERROR";
173
+ const id = this.currentTypeId;
174
+ if (id === null) return null;
175
+ return this.language.types[id] ?? C.UTF8ToString(C._ts_language_symbol_name(this.language[0], id));
147
176
  }
148
177
  /** Delete the lookahead iterator, freeing its resources. */
149
178
  delete() {
179
+ finalizer?.unregister(this);
150
180
  C._ts_lookahead_iterator_delete(this[0]);
151
181
  this[0] = 0;
152
182
  }
@@ -159,6 +189,7 @@ var LookaheadIterator = class {
159
189
  reset(language, stateId) {
160
190
  if (C._ts_lookahead_iterator_reset(this[0], language[0], stateId)) {
161
191
  this.language = language;
192
+ this.positioned = false;
162
193
  return true;
163
194
  }
164
195
  return false;
@@ -170,7 +201,9 @@ var LookaheadIterator = class {
170
201
  * `false` otherwise.
171
202
  */
172
203
  resetState(stateId) {
173
- return Boolean(C._ts_lookahead_iterator_reset_state(this[0], stateId));
204
+ if (!C._ts_lookahead_iterator_reset_state(this[0], stateId)) return false;
205
+ this.positioned = false;
206
+ return true;
174
207
  }
175
208
  /**
176
209
  * Returns an iterator that iterates over the symbols of the lookahead iterator.
@@ -181,10 +214,9 @@ var LookaheadIterator = class {
181
214
  [Symbol.iterator]() {
182
215
  return {
183
216
  next: /* @__PURE__ */ __name(() => {
184
- if (C._ts_lookahead_iterator_next(this[0])) {
185
- return { done: false, value: this.currentType };
186
- }
187
- return { done: true, value: "" };
217
+ this.positioned = Boolean(C._ts_lookahead_iterator_next(this[0]));
218
+ const value = this.currentType;
219
+ return value === null ? { done: true, value: "" } : { done: false, value };
188
220
  }, "next")
189
221
  };
190
222
  }
@@ -210,6 +242,9 @@ function getText(tree, startIndex, endIndex, startPosition) {
210
242
  return result ?? "";
211
243
  }
212
244
  __name(getText, "getText");
245
+ var finalizer2 = newFinalizer((address) => {
246
+ C._ts_tree_delete(address);
247
+ });
213
248
  var Tree = class _Tree {
214
249
  static {
215
250
  __name(this, "Tree");
@@ -227,6 +262,7 @@ var Tree = class _Tree {
227
262
  this[0] = address;
228
263
  this.language = language;
229
264
  this.textCallback = textCallback;
265
+ finalizer2?.register(this, address, this);
230
266
  }
231
267
  /** Create a shallow copy of the syntax tree. This is very fast. */
232
268
  copy() {
@@ -235,6 +271,7 @@ var Tree = class _Tree {
235
271
  }
236
272
  /** Delete the syntax tree, freeing its resources. */
237
273
  delete() {
274
+ finalizer2?.unregister(this);
238
275
  C._ts_tree_delete(this[0]);
239
276
  this[0] = 0;
240
277
  }
@@ -315,6 +352,9 @@ var Tree = class _Tree {
315
352
  return result;
316
353
  }
317
354
  };
355
+ var finalizer3 = newFinalizer((address) => {
356
+ C._ts_tree_cursor_delete_wasm(address);
357
+ });
318
358
  var TreeCursor = class _TreeCursor {
319
359
  static {
320
360
  __name(this, "TreeCursor");
@@ -342,6 +382,7 @@ var TreeCursor = class _TreeCursor {
342
382
  assertInternal(internal);
343
383
  this.tree = tree;
344
384
  unmarshalTreeCursor(this);
385
+ finalizer3?.register(this, this.tree[0], this);
345
386
  }
346
387
  /** Creates a deep copy of the tree cursor. This allocates new memory. */
347
388
  copy() {
@@ -352,6 +393,7 @@ var TreeCursor = class _TreeCursor {
352
393
  }
353
394
  /** Delete the tree cursor, freeing its resources. */
354
395
  delete() {
396
+ finalizer3?.unregister(this);
355
397
  marshalTreeCursor(this);
356
398
  C._ts_tree_cursor_delete_wasm(this.tree[0]);
357
399
  this[0] = this[1] = this[2] = 0;
@@ -1446,8 +1488,9 @@ var Language = class _Language {
1446
1488
  * This returns `null` if state is invalid for this language.
1447
1489
  *
1448
1490
  * Iterating {@link LookaheadIterator} will yield valid symbols in the given
1449
- * parse state. Newly created lookahead iterators will return the `ERROR`
1450
- * symbol from {@link LookaheadIterator#currentType}.
1491
+ * parse state. A newly created iterator is not positioned on a symbol, so
1492
+ * {@link LookaheadIterator#currentType} returns `null` until the first
1493
+ * iteration step.
1451
1494
  *
1452
1495
  * Lookahead iterators can be useful for generating suggestions and improving
1453
1496
  * syntax error diagnostics. To get symbols valid in an `ERROR` node, use the
@@ -1462,7 +1505,8 @@ var Language = class _Language {
1462
1505
  }
1463
1506
  /**
1464
1507
  * Load a language from a WebAssembly module.
1465
- * The module can be provided as a path to a file or as a buffer.
1508
+ * The module can be provided as a path to a file, a `URL` to a file, or as a
1509
+ * buffer.
1466
1510
  */
1467
1511
  static async load(input) {
1468
1512
  let binary2;
@@ -1489,16 +1533,27 @@ ${body2}`);
1489
1533
  }
1490
1534
  }
1491
1535
  const mod = await C.loadWebAssemblyModule(binary2, { loadAsync: true });
1536
+ return _Language.loadFromWasmExports(mod, { sync: false });
1537
+ }
1538
+ static loadFromWasmExports(mod, { sync }) {
1492
1539
  const symbolNames = Object.keys(mod);
1493
1540
  const functionName = symbolNames.find((key) => LANGUAGE_FUNCTION_REGEX.test(key) && !key.includes("external_scanner_"));
1494
1541
  if (!functionName) {
1495
1542
  console.log(`Couldn't find language function in Wasm file. Symbols:
1496
1543
  ${JSON.stringify(symbolNames, null, 2)}`);
1497
- throw new Error("Language.load failed: no language function found in Wasm file");
1544
+ throw new Error(`Language.${sync ? "loadSync" : "load"} failed: no language function found in Wasm file`);
1498
1545
  }
1499
1546
  const languageAddress = mod[functionName]();
1500
1547
  return new _Language(INTERNAL, languageAddress);
1501
1548
  }
1549
+ /**
1550
+ * Load a language synchronously from a pre-compiled WebAssembly module.
1551
+ * Use this when the host environment provides a `WebAssembly.Module` directly.
1552
+ */
1553
+ static loadSync(wasmModule) {
1554
+ const mod = C.loadWebAssemblyModule(wasmModule, { loadAsync: false });
1555
+ return _Language.loadFromWasmExports(mod, { sync: true });
1556
+ }
1502
1557
  };
1503
1558
  async function Module2(moduleArg = {}) {
1504
1559
  var moduleRtn;
@@ -2021,7 +2076,7 @@ async function Module2(moduleArg = {}) {
2021
2076
  newDSO("__main__", 0, wasmImports);
2022
2077
  }
2023
2078
  };
2024
- var ___heap_base = 78240;
2079
+ var ___heap_base = 82240;
2025
2080
  var alignMemory = /* @__PURE__ */ __name((size, alignment) => Math.ceil(size / alignment) * alignment, "alignMemory");
2026
2081
  var getMemory = /* @__PURE__ */ __name((size) => {
2027
2082
  if (runtimeInitialized) {
@@ -2586,12 +2641,12 @@ async function Module2(moduleArg = {}) {
2586
2641
  "value": "i32",
2587
2642
  "mutable": false
2588
2643
  }, 1024);
2589
- var ___stack_high = 78240;
2590
- var ___stack_low = 12704;
2644
+ var ___stack_high = 82240;
2645
+ var ___stack_low = 16704;
2591
2646
  var ___stack_pointer = new WebAssembly.Global({
2592
2647
  "value": "i32",
2593
2648
  "mutable": true
2594
- }, 78240);
2649
+ }, 82240);
2595
2650
  var ___table_base = new WebAssembly.Global({
2596
2651
  "value": "i32",
2597
2652
  "mutable": false
@@ -2852,7 +2907,7 @@ async function Module2(moduleArg = {}) {
2852
2907
  Module["loadWebAssemblyModule"] = loadWebAssemblyModule;
2853
2908
  Module["LE_HEAP_STORE_I64"] = LE_HEAP_STORE_I64;
2854
2909
  var ASM_CONSTS = {};
2855
- var _malloc, _calloc, _realloc, _free, _ts_range_edit, _memcmp, _ts_language_symbol_count, _ts_language_state_count, _ts_language_abi_version, _ts_language_name, _ts_language_field_count, _ts_language_next_state, _ts_language_symbol_name, _ts_language_symbol_for_name, _strncmp, _ts_language_symbol_type, _ts_language_field_name_for_id, _ts_lookahead_iterator_new, _ts_lookahead_iterator_delete, _ts_lookahead_iterator_reset_state, _ts_lookahead_iterator_reset, _ts_lookahead_iterator_next, _ts_lookahead_iterator_current_symbol, _ts_point_edit, _ts_parser_delete, _ts_parser_reset, _ts_parser_set_language, _ts_parser_set_included_ranges, _ts_query_new, _ts_query_delete, _iswspace, _iswalnum, _ts_query_pattern_count, _ts_query_capture_count, _ts_query_string_count, _ts_query_capture_name_for_id, _ts_query_capture_quantifier_for_id, _ts_query_string_value_for_id, _ts_query_predicates_for_pattern, _ts_query_start_byte_for_pattern, _ts_query_end_byte_for_pattern, _ts_query_is_pattern_rooted, _ts_query_is_pattern_non_local, _ts_query_is_pattern_guaranteed_at_step, _ts_query_disable_capture, _ts_query_disable_pattern, _ts_tree_copy, _ts_tree_delete, _ts_init, _ts_parser_new_wasm, _ts_parser_enable_logger_wasm, _ts_parser_parse_wasm, _ts_parser_included_ranges_wasm, _ts_language_type_is_named_wasm, _ts_language_type_is_visible_wasm, _ts_language_metadata_wasm, _ts_language_supertypes_wasm, _ts_language_subtypes_wasm, _ts_tree_root_node_wasm, _ts_tree_root_node_with_offset_wasm, _ts_tree_edit_wasm, _ts_tree_included_ranges_wasm, _ts_tree_get_changed_ranges_wasm, _ts_tree_cursor_new_wasm, _ts_tree_cursor_copy_wasm, _ts_tree_cursor_delete_wasm, _ts_tree_cursor_reset_wasm, _ts_tree_cursor_reset_to_wasm, _ts_tree_cursor_goto_first_child_wasm, _ts_tree_cursor_goto_last_child_wasm, _ts_tree_cursor_goto_first_child_for_index_wasm, _ts_tree_cursor_goto_first_child_for_position_wasm, _ts_tree_cursor_goto_next_sibling_wasm, _ts_tree_cursor_goto_previous_sibling_wasm, _ts_tree_cursor_goto_descendant_wasm, _ts_tree_cursor_goto_parent_wasm, _ts_tree_cursor_current_node_type_id_wasm, _ts_tree_cursor_current_node_state_id_wasm, _ts_tree_cursor_current_node_is_named_wasm, _ts_tree_cursor_current_node_is_missing_wasm, _ts_tree_cursor_current_node_id_wasm, _ts_tree_cursor_start_position_wasm, _ts_tree_cursor_end_position_wasm, _ts_tree_cursor_start_index_wasm, _ts_tree_cursor_end_index_wasm, _ts_tree_cursor_current_field_id_wasm, _ts_tree_cursor_current_depth_wasm, _ts_tree_cursor_current_descendant_index_wasm, _ts_tree_cursor_current_node_wasm, _ts_node_symbol_wasm, _ts_node_field_name_for_child_wasm, _ts_node_field_name_for_named_child_wasm, _ts_node_children_by_field_id_wasm, _ts_node_first_child_for_byte_wasm, _ts_node_first_named_child_for_byte_wasm, _ts_node_grammar_symbol_wasm, _ts_node_child_count_wasm, _ts_node_named_child_count_wasm, _ts_node_child_wasm, _ts_node_named_child_wasm, _ts_node_child_by_field_id_wasm, _ts_node_next_sibling_wasm, _ts_node_prev_sibling_wasm, _ts_node_next_named_sibling_wasm, _ts_node_prev_named_sibling_wasm, _ts_node_descendant_count_wasm, _ts_node_parent_wasm, _ts_node_child_with_descendant_wasm, _ts_node_descendant_for_index_wasm, _ts_node_named_descendant_for_index_wasm, _ts_node_descendant_for_position_wasm, _ts_node_named_descendant_for_position_wasm, _ts_node_start_point_wasm, _ts_node_end_point_wasm, _ts_node_start_index_wasm, _ts_node_end_index_wasm, _ts_node_to_string_wasm, _ts_node_children_wasm, _ts_node_named_children_wasm, _ts_node_descendants_of_type_wasm, _ts_node_is_named_wasm, _ts_node_has_changes_wasm, _ts_node_has_error_wasm, _ts_node_is_error_wasm, _ts_node_is_missing_wasm, _ts_node_is_extra_wasm, _ts_node_parse_state_wasm, _ts_node_next_parse_state_wasm, _ts_query_matches_wasm, _ts_query_captures_wasm, _memset, _memcpy, _memmove, _iswalpha, _iswblank, _iswdigit, _iswlower, _iswupper, _iswxdigit, _memchr, _strlen, _strcmp, _strncat, _strncpy, _towlower, _towupper, _setThrew, __emscripten_stack_restore, __emscripten_stack_alloc, _emscripten_stack_get_current, ___wasm_apply_data_relocs;
2910
+ var _malloc, _calloc, _realloc, _free, _ts_range_edit, _memcmp, _ts_language_symbol_count, _ts_language_state_count, _ts_language_abi_version, _ts_language_name, _ts_language_field_count, _ts_language_next_state, _ts_language_symbol_name, _ts_language_symbol_for_name, _strncmp, _ts_language_symbol_type, _ts_language_field_name_for_id, _ts_lookahead_iterator_new, _ts_lookahead_iterator_delete, _ts_lookahead_iterator_reset_state, _ts_lookahead_iterator_reset, _ts_lookahead_iterator_next, _ts_lookahead_iterator_current_symbol, _ts_point_edit, _ts_parser_delete, _ts_parser_reset, _ts_parser_set_language, _ts_parser_set_included_ranges, _ts_query_new, _ts_query_delete, _iswspace, _iswalnum, _ts_query_copy, _ts_query_pattern_count, _ts_query_capture_count, _ts_query_string_count, _ts_query_capture_name_for_id, _ts_query_capture_quantifier_for_id, _ts_query_string_value_for_id, _ts_query_predicates_for_pattern, _ts_query_start_byte_for_pattern, _ts_query_end_byte_for_pattern, _ts_query_is_pattern_rooted, _ts_query_is_pattern_non_local, _ts_query_is_pattern_guaranteed_at_step, _ts_query_disable_capture, _ts_query_disable_pattern, _ts_tree_copy, _ts_tree_delete, _ts_init, _ts_parser_new_wasm, _ts_parser_enable_logger_wasm, _ts_parser_parse_wasm, _ts_parser_included_ranges_wasm, _ts_language_type_is_named_wasm, _ts_language_type_is_visible_wasm, _ts_language_metadata_wasm, _ts_language_supertypes_wasm, _ts_language_subtypes_wasm, _ts_tree_root_node_wasm, _ts_tree_root_node_with_offset_wasm, _ts_tree_edit_wasm, _ts_tree_included_ranges_wasm, _ts_tree_get_changed_ranges_wasm, _ts_tree_cursor_new_wasm, _ts_tree_cursor_copy_wasm, _ts_tree_cursor_delete_wasm, _ts_tree_cursor_reset_wasm, _ts_tree_cursor_reset_to_wasm, _ts_tree_cursor_goto_first_child_wasm, _ts_tree_cursor_goto_last_child_wasm, _ts_tree_cursor_goto_first_child_for_index_wasm, _ts_tree_cursor_goto_first_child_for_position_wasm, _ts_tree_cursor_goto_next_sibling_wasm, _ts_tree_cursor_goto_previous_sibling_wasm, _ts_tree_cursor_goto_descendant_wasm, _ts_tree_cursor_goto_parent_wasm, _ts_tree_cursor_current_node_type_id_wasm, _ts_tree_cursor_current_node_state_id_wasm, _ts_tree_cursor_current_node_is_named_wasm, _ts_tree_cursor_current_node_is_missing_wasm, _ts_tree_cursor_current_node_id_wasm, _ts_tree_cursor_start_position_wasm, _ts_tree_cursor_end_position_wasm, _ts_tree_cursor_start_index_wasm, _ts_tree_cursor_end_index_wasm, _ts_tree_cursor_current_field_id_wasm, _ts_tree_cursor_current_depth_wasm, _ts_tree_cursor_current_descendant_index_wasm, _ts_tree_cursor_current_node_wasm, _ts_node_symbol_wasm, _ts_node_field_name_for_child_wasm, _ts_node_field_name_for_named_child_wasm, _ts_node_children_by_field_id_wasm, _ts_node_first_child_for_byte_wasm, _ts_node_first_named_child_for_byte_wasm, _ts_node_grammar_symbol_wasm, _ts_node_child_count_wasm, _ts_node_named_child_count_wasm, _ts_node_child_wasm, _ts_node_named_child_wasm, _ts_node_child_by_field_id_wasm, _ts_node_next_sibling_wasm, _ts_node_prev_sibling_wasm, _ts_node_next_named_sibling_wasm, _ts_node_prev_named_sibling_wasm, _ts_node_descendant_count_wasm, _ts_node_parent_wasm, _ts_node_child_with_descendant_wasm, _ts_node_descendant_for_index_wasm, _ts_node_named_descendant_for_index_wasm, _ts_node_descendant_for_position_wasm, _ts_node_named_descendant_for_position_wasm, _ts_node_start_point_wasm, _ts_node_end_point_wasm, _ts_node_start_index_wasm, _ts_node_end_index_wasm, _ts_node_to_string_wasm, _ts_node_children_wasm, _ts_node_named_children_wasm, _ts_node_descendants_of_type_wasm, _ts_node_is_named_wasm, _ts_node_has_changes_wasm, _ts_node_has_error_wasm, _ts_node_is_error_wasm, _ts_node_is_missing_wasm, _ts_node_is_extra_wasm, _ts_node_parse_state_wasm, _ts_node_next_parse_state_wasm, _ts_query_matches_wasm, _ts_query_captures_wasm, _memset, _memcpy, _memmove, _iswalpha, _iswblank, _iswdigit, _iswlower, _iswpunct, _iswupper, _iswxdigit, _memchr, _strlen, _strcmp, _strncat, _strncpy, _towlower, _towupper, _setThrew, __emscripten_stack_restore, __emscripten_stack_alloc, _emscripten_stack_get_current, ___wasm_apply_data_relocs;
2856
2911
  function assignWasmExports(wasmExports2) {
2857
2912
  Module["_malloc"] = _malloc = wasmExports2["malloc"];
2858
2913
  Module["_calloc"] = _calloc = wasmExports2["calloc"];
@@ -2886,6 +2941,7 @@ async function Module2(moduleArg = {}) {
2886
2941
  Module["_ts_query_delete"] = _ts_query_delete = wasmExports2["ts_query_delete"];
2887
2942
  Module["_iswspace"] = _iswspace = wasmExports2["iswspace"];
2888
2943
  Module["_iswalnum"] = _iswalnum = wasmExports2["iswalnum"];
2944
+ Module["_ts_query_copy"] = _ts_query_copy = wasmExports2["ts_query_copy"];
2889
2945
  Module["_ts_query_pattern_count"] = _ts_query_pattern_count = wasmExports2["ts_query_pattern_count"];
2890
2946
  Module["_ts_query_capture_count"] = _ts_query_capture_count = wasmExports2["ts_query_capture_count"];
2891
2947
  Module["_ts_query_string_count"] = _ts_query_string_count = wasmExports2["ts_query_string_count"];
@@ -2991,6 +3047,7 @@ async function Module2(moduleArg = {}) {
2991
3047
  Module["_iswblank"] = _iswblank = wasmExports2["iswblank"];
2992
3048
  Module["_iswdigit"] = _iswdigit = wasmExports2["iswdigit"];
2993
3049
  Module["_iswlower"] = _iswlower = wasmExports2["iswlower"];
3050
+ Module["_iswpunct"] = _iswpunct = wasmExports2["iswpunct"];
2994
3051
  Module["_iswupper"] = _iswupper = wasmExports2["iswupper"];
2995
3052
  Module["_iswxdigit"] = _iswxdigit = wasmExports2["iswxdigit"];
2996
3053
  Module["_memchr"] = _memchr = wasmExports2["memchr"];
@@ -3128,6 +3185,10 @@ __name(checkModule, "checkModule");
3128
3185
  var TRANSFER_BUFFER;
3129
3186
  var LANGUAGE_VERSION;
3130
3187
  var MIN_COMPATIBLE_VERSION;
3188
+ var finalizer4 = newFinalizer((addresses) => {
3189
+ C._ts_parser_delete(addresses[0]);
3190
+ C._free(addresses[1]);
3191
+ });
3131
3192
  var Parser = class {
3132
3193
  static {
3133
3194
  __name(this, "Parser");
@@ -3159,6 +3220,7 @@ var Parser = class {
3159
3220
  */
3160
3221
  constructor() {
3161
3222
  this.initialize();
3223
+ finalizer4?.register(this, [this[0], this[1]], this);
3162
3224
  }
3163
3225
  /** @internal */
3164
3226
  initialize() {
@@ -3171,6 +3233,7 @@ var Parser = class {
3171
3233
  }
3172
3234
  /** Delete the parser, freeing its resources. */
3173
3235
  delete() {
3236
+ finalizer4?.unregister(this);
3174
3237
  C._ts_parser_delete(this[0]);
3175
3238
  C._free(this[1]);
3176
3239
  this[0] = 0;
@@ -3346,6 +3409,10 @@ var QueryError = class _QueryError extends Error {
3346
3409
  this.length = length;
3347
3410
  this.name = "QueryError";
3348
3411
  }
3412
+ kind;
3413
+ info;
3414
+ index;
3415
+ length;
3349
3416
  static {
3350
3417
  __name(this, "QueryError");
3351
3418
  }
@@ -3541,6 +3608,9 @@ function parsePattern(index, stepType, stepValueId, captureNames, stringValues,
3541
3608
  }
3542
3609
  }
3543
3610
  __name(parsePattern, "parsePattern");
3611
+ var finalizer5 = newFinalizer((address) => {
3612
+ C._ts_query_delete(address);
3613
+ });
3544
3614
  var Query = class {
3545
3615
  static {
3546
3616
  __name(this, "Query");
@@ -3695,9 +3765,11 @@ var Query = class {
3695
3765
  this.assertedProperties = assertedProperties;
3696
3766
  this.refutedProperties = refutedProperties;
3697
3767
  this.exceededMatchLimit = false;
3768
+ finalizer5?.register(this, address, this);
3698
3769
  }
3699
3770
  /** Delete the query, freeing its resources. */
3700
3771
  delete() {
3772
+ finalizer5?.unregister(this);
3701
3773
  C._ts_query_delete(this[0]);
3702
3774
  this[0] = 0;
3703
3775
  }
@@ -9153,7 +9225,7 @@ function buildBashCFG(tree, startId, cache) {
9153
9225
  allEdges.push({ from: entryBlock.id, to: firstBlockId, type: "sequential" });
9154
9226
  }
9155
9227
  const exitBlock = {
9156
- id: blockIdCounter++,
9228
+ id: blockIdCounter,
9157
9229
  type: "exit",
9158
9230
  start_line: topLevelStatements[topLevelStatements.length - 1].endPosition.row + 1,
9159
9231
  end_line: topLevelStatements[topLevelStatements.length - 1].endPosition.row + 1
@@ -9271,7 +9343,7 @@ function buildGoCFG(tree, blockIdCounter, cache) {
9271
9343
  );
9272
9344
  if (hasTopLevelDecls) {
9273
9345
  const block = {
9274
- id: blockIdCounter++,
9346
+ id: blockIdCounter,
9275
9347
  type: "normal",
9276
9348
  start_line: 1,
9277
9349
  end_line: tree.rootNode.endPosition.row + 1
@@ -10290,7 +10362,7 @@ function buildRustDFG(tree, cache) {
10290
10362
  const defs = [];
10291
10363
  const uses = [];
10292
10364
  let defIdCounter = 1;
10293
- let useIdCounter = 1;
10365
+ const useIdCounter = 1;
10294
10366
  const scopeStack = [/* @__PURE__ */ new Map()];
10295
10367
  const functions = findNodes(tree.rootNode, "function_item");
10296
10368
  for (const func2 of functions) {
@@ -11169,7 +11241,7 @@ function parsePythonDecorator(dec) {
11169
11241
  const fnNode = target.childForFieldName("function");
11170
11242
  if (!fnNode) return null;
11171
11243
  let receiver = "";
11172
- let method = "";
11244
+ let method;
11173
11245
  if (fnNode.type === "identifier") {
11174
11246
  method = getNodeText(fnNode);
11175
11247
  } else if (fnNode.type === "attribute") {
@@ -11235,7 +11307,7 @@ function classifyPythonDecorator(receiver, method, imp) {
11235
11307
  if (receiver && PY_HTTP_ROUTE_METHODS.has(method)) {
11236
11308
  const isRoutey = isPyRouterReceiver(receiver);
11237
11309
  if (isRoutey) {
11238
- let framework = "unknown";
11310
+ let framework;
11239
11311
  if (imp.hasFlask) framework = "flask";
11240
11312
  else if (imp.hasFastApi) framework = "fastapi";
11241
11313
  else if (method === "route") framework = "flask";
@@ -21568,7 +21640,7 @@ var ConstantPropagator = class _ConstantPropagator {
21568
21640
  }
21569
21641
  }
21570
21642
  const startIdx = matchingIdx >= 0 ? matchingIdx : defaultIdx;
21571
- for (let i2 = 0; i2 < startIdx && startIdx >= 0; i2++) {
21643
+ for (let i2 = 0; i2 < startIdx; i2++) {
21572
21644
  this.markUnreachable(caseGroups[i2]);
21573
21645
  }
21574
21646
  if (startIdx >= 0) {
@@ -26374,16 +26446,21 @@ var CSharpPlugin = class extends BaseLanguagePlugin {
26374
26446
  };
26375
26447
 
26376
26448
  // src/languages/plugins/index.ts
26449
+ function createBuiltinPlugins() {
26450
+ return [
26451
+ new JavaPlugin(),
26452
+ new JavaScriptPlugin(),
26453
+ new PythonPlugin(),
26454
+ new RustPlugin(),
26455
+ new BashPlugin(),
26456
+ new HtmlPlugin(),
26457
+ new VuePlugin(),
26458
+ new GoPlugin(),
26459
+ new CSharpPlugin()
26460
+ ];
26461
+ }
26377
26462
  function registerBuiltinPlugins() {
26378
- registerLanguage(new JavaPlugin());
26379
- registerLanguage(new JavaScriptPlugin());
26380
- registerLanguage(new PythonPlugin());
26381
- registerLanguage(new RustPlugin());
26382
- registerLanguage(new BashPlugin());
26383
- registerLanguage(new HtmlPlugin());
26384
- registerLanguage(new VuePlugin());
26385
- registerLanguage(new GoPlugin());
26386
- registerLanguage(new CSharpPlugin());
26463
+ for (const plugin of createBuiltinPlugins()) registerLanguage(plugin);
26387
26464
  }
26388
26465
 
26389
26466
  // src/analysis/html/html-extractor.ts
@@ -29525,16 +29602,12 @@ function findPythonRegexAllowlistWrapperSanitizers(code) {
29525
29602
  const argName = m[3];
29526
29603
  let foundGuard = false;
29527
29604
  let returnsArg = false;
29528
- let blockEnd = -1;
29529
29605
  const maxScan = Math.min(lines.length, i2 + 40);
29530
29606
  for (let j = i2 + 1; j < maxScan; j++) {
29531
29607
  const line = lines[j];
29532
29608
  if (line.trim() === "") continue;
29533
29609
  const indent = line.length - line.trimStart().length;
29534
- if (indent <= defIndent) {
29535
- blockEnd = j - 1;
29536
- break;
29537
- }
29610
+ if (indent <= defIndent) break;
29538
29611
  if (!foundGuard) {
29539
29612
  const guard = new RegExp(
29540
29613
  `if\\s+not\\s+re\\.(?:fullmatch|match)\\s*\\(\\s*(${tightRegex.source})\\s*,\\s*${argName}\\s*\\)\\s*:`
@@ -29554,7 +29627,6 @@ function findPythonRegexAllowlistWrapperSanitizers(code) {
29554
29627
  returnsArg = true;
29555
29628
  }
29556
29629
  }
29557
- if (blockEnd === -1) blockEnd = Math.min(lines.length - 1, i2 + 39);
29558
29630
  if (!foundGuard || !returnsArg) continue;
29559
29631
  wrappers.push({ name: wrapperName, defLine: i2, defIndent });
29560
29632
  }
@@ -32271,7 +32343,7 @@ function findRustEvalCrateCodeInjectionFindings(code, file) {
32271
32343
  }
32272
32344
  if (arg === null) continue;
32273
32345
  if (arg.length === 0) continue;
32274
- let unwrapped = arg.replace(/^&\s*/, "").trim();
32346
+ const unwrapped = arg.replace(/^&\s*/, "").trim();
32275
32347
  if (/^"[^"]*"$/.test(unwrapped)) continue;
32276
32348
  let tainted = false;
32277
32349
  for (const v of fn.tainted) {
@@ -32884,7 +32956,7 @@ function findJsLdapInjectionFindings(code, file) {
32884
32956
  for (let i2 = 0; i2 < lines.length; i2++) {
32885
32957
  const line = lines[i2];
32886
32958
  const fm = line.match(filterPropRe);
32887
- let expr = null;
32959
+ let expr;
32888
32960
  if (fm) {
32889
32961
  expr = fm[1].trim();
32890
32962
  } else if (filterShorthandRe.test(line)) {
@@ -35345,7 +35417,7 @@ var SinkFilterPass = class {
35345
35417
  if (/^-?\d+$/.test(t) || /^"(?:[^"\\]|\\.)*"$/.test(t) || /^'(?:[^'\\]|\\.)*'$/.test(t)) {
35346
35418
  continue;
35347
35419
  }
35348
- let helperName = null;
35420
+ let helperName;
35349
35421
  const directCall = t.match(/^([A-Za-z_]\w*)\s*\(/);
35350
35422
  if (directCall) {
35351
35423
  helperName = directCall[1] ?? null;
@@ -40631,7 +40703,7 @@ function buildSourceCoveredRanges(codeLines, language) {
40631
40703
  function buildJsCoveredRanges(codeLines) {
40632
40704
  const ranges = [];
40633
40705
  const tryStack = [];
40634
- let braceDepthAtTry = [];
40706
+ const braceDepthAtTry = [];
40635
40707
  let braceDepth = 0;
40636
40708
  for (let i2 = 0; i2 < codeLines.length; i2++) {
40637
40709
  const line = codeLines[i2];
@@ -40703,12 +40775,6 @@ var UnhandledExceptionPass = class {
40703
40775
  coveredRanges.push(range);
40704
40776
  }
40705
40777
  }
40706
- const catchStarts = new Set(
40707
- exGraph.pairs.map((p) => p.catchBlock.start_line)
40708
- );
40709
- for (const range of coveredRanges) {
40710
- catchStarts.add(range.end + 1);
40711
- }
40712
40778
  const throwRe = language === "python" ? PYTHON_RAISE_RE : JS_THROW_RE;
40713
40779
  const unhandled = [];
40714
40780
  const reportedMethods = /* @__PURE__ */ new Set();
@@ -40716,13 +40782,6 @@ var UnhandledExceptionPass = class {
40716
40782
  const lineText = codeLines[ln - 1] ?? "";
40717
40783
  if (!throwRe.test(lineText)) continue;
40718
40784
  let inCatch = false;
40719
- for (const cs of catchStarts) {
40720
- if (ln >= cs) {
40721
- inCatch = true;
40722
- break;
40723
- }
40724
- }
40725
- inCatch = false;
40726
40785
  for (const pair of exGraph.pairs) {
40727
40786
  if (ln >= pair.catchBlock.start_line) {
40728
40787
  const mThrow = graph.methodAtLine(ln);
@@ -46187,6 +46246,8 @@ var JAVA_XML_OUTPUT_ONLY_RE = /\bnew\s+(?:DOMSource|StreamResult)\s*\(/;
46187
46246
  var JAVA_XML_PARSE_INPUT_RE = /\bnew\s+(?:StreamSource|SAXSource|InputSource)\s*\(/;
46188
46247
  var JAVA_DOC_BUILDER_NEW_DOCUMENT_RE = /\.\s*newDocument\s*\(\s*\)/;
46189
46248
  var JAVA_DOC_BUILDER_PARSE_RE = /(?:DocumentBuilder|builder)\s*\.\s*parse\s*\(/;
46249
+ var JAVA_HARDENING_SETTER_RE = /\.\s*(?:setFeature|setAttribute|setProperty|setXIncludeAware|setExpandEntityReferences)\s*\(/;
46250
+ var JAVA_FACTORY_CHAINED_RE = /\bnewInstance\s*\([^()]*\)\s*\.\s*(?:newDocumentBuilder|newSAXParser|newTransformer|newTemplates|newSchema|createXMLStreamReader|createXMLEventReader)\s*\(/;
46190
46251
  var PY_LXML_PARSER_INSECURE_DEFAULT_RE = /\bresolve_entities\s*=\s*False\b/;
46191
46252
  var XmlEntityExpansionPass = class {
46192
46253
  name = "xml-entity-expansion";
@@ -46198,7 +46259,9 @@ var XmlEntityExpansionPass = class {
46198
46259
  const code = ctx.code ?? "";
46199
46260
  if (language === "java") {
46200
46261
  const safeInFile = JAVA_SAFE_EVIDENCE_RE.test(code);
46201
- if (safeInFile) return { findings };
46262
+ const processWide = safeInFile && /jdk\.xml\./.test(code);
46263
+ const lines = safeInFile ? code.split("\n") : [];
46264
+ const methodRanges = safeInFile ? this.methodRanges(graph.ir.types) : [];
46202
46265
  const isXmlOutputOnly = JAVA_XML_OUTPUT_ONLY_RE.test(code) && !JAVA_XML_PARSE_INPUT_RE.test(code);
46203
46266
  const isDocumentBuilderEmptyOnly = JAVA_DOC_BUILDER_NEW_DOCUMENT_RE.test(code) && !JAVA_DOC_BUILDER_PARSE_RE.test(code);
46204
46267
  for (const call of graph.ir.calls) {
@@ -46208,6 +46271,8 @@ var XmlEntityExpansionPass = class {
46208
46271
  if (det.api === "DocumentBuilderFactory" && isDocumentBuilderEmptyOnly)
46209
46272
  continue;
46210
46273
  const line = call.location.line;
46274
+ if (safeInFile && (processWide || !this.isProvablyUnhardened(lines, line, methodRanges, det.api)))
46275
+ continue;
46211
46276
  findings.push({ line, language, ...det });
46212
46277
  ctx.addFinding({
46213
46278
  id: `${this.name}-${file}-${line}-${det.api}`,
@@ -46217,11 +46282,11 @@ var XmlEntityExpansionPass = class {
46217
46282
  cwe: det.cwe,
46218
46283
  severity: "high",
46219
46284
  level: "error",
46220
- message: `${det.api} created without disabling DTD / external-entity processing. Vulnerable to billion-laughs / quadratic blow-up DoS (CWE-776) and external-entity disclosure (CWE-611). Add \`setFeature("http://apache.org/xml/features/disallow-doctype-decl", true)\` (or the equivalent) before parsing.`,
46285
+ message: `${det.api} created without disabling DTD / external-entity processing. Vulnerable to external-entity disclosure (CWE-611) and billion-laughs / quadratic blow-up DoS (CWE-776). Add \`setFeature("http://apache.org/xml/features/disallow-doctype-decl", true)\` (or the equivalent) before parsing.`,
46221
46286
  file,
46222
46287
  line,
46223
46288
  fix: this.fixForJava(det.api),
46224
- evidence: { ...det, language, safeFeatureInFile: false }
46289
+ evidence: { ...det, language, safeFeatureInFile: safeInFile }
46225
46290
  });
46226
46291
  }
46227
46292
  return { findings };
@@ -46242,7 +46307,7 @@ var XmlEntityExpansionPass = class {
46242
46307
  cwe: det.cwe,
46243
46308
  severity: "high",
46244
46309
  level: "error",
46245
- message: `${det.api} called without an entity-safe parser. Vulnerable to billion-laughs / quadratic blow-up DoS (CWE-776) and external-entity disclosure (CWE-611). Use \`defusedxml\` or pass an \`XMLParser(resolve_entities=False)\` to lxml.`,
46310
+ message: `${det.api} called without an entity-safe parser. Vulnerable ` + (det.cwe === "CWE-611" ? "to external-entity disclosure (CWE-611) and billion-laughs / quadratic blow-up DoS (CWE-776). " : "to billion-laughs / quadratic blow-up DoS (CWE-776). ") + "Use `defusedxml` or pass an `XMLParser(resolve_entities=False)` to lxml.",
46246
46311
  file,
46247
46312
  line,
46248
46313
  fix: this.fixForPython(det.api),
@@ -46253,6 +46318,78 @@ var XmlEntityExpansionPass = class {
46253
46318
  }
46254
46319
  return { findings };
46255
46320
  }
46321
+ methodRanges(types) {
46322
+ const out2 = [];
46323
+ for (const t of types ?? []) {
46324
+ for (const m of t.methods ?? []) {
46325
+ if (typeof m.start_line === "number" && typeof m.end_line === "number")
46326
+ out2.push([m.start_line, m.end_line]);
46327
+ }
46328
+ }
46329
+ return out2;
46330
+ }
46331
+ /**
46332
+ * In a file that DOES contain hardening evidence, is the factory created on
46333
+ * `line` one that provably never receives it?
46334
+ *
46335
+ * Deliberately one-sided. It answers true for exactly two shapes:
46336
+ *
46337
+ * 1. CHAINED — `Factory.newInstance().newDocumentBuilder()`, where the
46338
+ * product is not handed on or returned either.
46339
+ * 2. LOCAL — `Factory f = Factory.newInstance();` where the enclosing method
46340
+ * builds a parser from `f`, never hands `f` to another call, and never
46341
+ * returns it.
46342
+ *
46343
+ * and in both only when the enclosing method contains NO hardening-capable
46344
+ * setter on ANY receiver, since hardening may land on the factory's product
46345
+ * (`parser.getXMLReader().setFeature(…)`) rather than the factory.
46346
+ *
46347
+ * Every other shape — a field, a helper that takes the factory, a caller that
46348
+ * receives it — may be hardened somewhere this check cannot see, so it keeps
46349
+ * the previous file-level silence.
46350
+ *
46351
+ * A TransformerFactory additionally needs a `StreamSource` in its method: that
46352
+ * is the input the transformer parses with its OWN parser. Fed a `DOMSource`
46353
+ * it parses nothing, and fed a `SAXSource` it uses the reader it was given —
46354
+ * whose hardening is that reader's business, not this factory's.
46355
+ */
46356
+ isProvablyUnhardened(lines, line, methodRanges, api) {
46357
+ let range = null;
46358
+ for (const r of methodRanges) {
46359
+ if (line < r[0] || line > r[1]) continue;
46360
+ if (!range || r[1] - r[0] < range[1] - range[0]) range = r;
46361
+ }
46362
+ if (!range) return false;
46363
+ let decl = "";
46364
+ let declEnd = line;
46365
+ for (; declEnd <= Math.min(line + 3, range[1]); declEnd++) {
46366
+ decl += " " + (lines[declEnd - 1] ?? "").trim();
46367
+ if (decl.includes(";")) break;
46368
+ }
46369
+ const body2 = lines.slice(line - 1, range[1]).join("\n");
46370
+ if (api === "TransformerFactory" && !/\bnew\s+StreamSource\s*\(/.test(body2))
46371
+ return false;
46372
+ if (JAVA_HARDENING_SETTER_RE.test(body2)) return false;
46373
+ const chained = JAVA_FACTORY_CHAINED_RE.exec(decl);
46374
+ if (chained) {
46375
+ const prod = /[\w>\]]\s+([A-Za-z_$][\w$]*)\s*=/.exec(decl);
46376
+ if (!prod) return true;
46377
+ const pn = prod[1].replace(/\$/g, "\\$");
46378
+ const after = lines.slice(declEnd, range[1]).join("\n");
46379
+ return !new RegExp(`[(,]\\s*${pn}\\s*[,)]|\\breturn\\s+${pn}\\s*;`).test(after);
46380
+ }
46381
+ const m = /[\w>\]]\s+([A-Za-z_$][\w$]*)\s*=\s*[\w.]*\bnewInstance\s*\([^()]*\)\s*;/.exec(decl);
46382
+ if (!m) return false;
46383
+ const name2 = m[1].replace(/\$/g, "\\$");
46384
+ const rest = lines.slice(declEnd, range[1]).join("\n");
46385
+ const builds = new RegExp(
46386
+ `\\b${name2}\\s*\\.\\s*(?:newDocumentBuilder|newSAXParser|newTransformer|newTemplates|newSchema|createXMLStreamReader|createXMLEventReader)\\s*\\(`
46387
+ );
46388
+ if (!builds.test(rest)) return false;
46389
+ const escapes = new RegExp(`[(,]\\s*${name2}\\s*[,)]|\\breturn\\s+${name2}\\s*;`);
46390
+ if (escapes.test(rest)) return false;
46391
+ return true;
46392
+ }
46256
46393
  detectJavaCall(call) {
46257
46394
  if (call.method_name !== "newInstance") return null;
46258
46395
  const recv = call.receiver ?? "";
@@ -46262,7 +46399,7 @@ var XmlEntityExpansionPass = class {
46262
46399
  return {
46263
46400
  pattern: `${factory}.newInstance()`,
46264
46401
  api: factory,
46265
- cwe: "CWE-776"
46402
+ cwe: "CWE-611"
46266
46403
  };
46267
46404
  }
46268
46405
  }
@@ -46275,7 +46412,7 @@ var XmlEntityExpansionPass = class {
46275
46412
  return {
46276
46413
  pattern: `etree.${method}`,
46277
46414
  api: `lxml.etree.${method}`,
46278
- cwe: "CWE-776"
46415
+ cwe: "CWE-611"
46279
46416
  };
46280
46417
  }
46281
46418
  if ((method === "parse" || method === "fromstring") && (recv === "ET" || recv === "ElementTree" || recv.endsWith(".ElementTree"))) {
@@ -1 +1 @@
1
- {"version":3,"file":"browser.js","sourceRoot":"","sources":["../src/browser.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EACL,YAAY,EACZ,OAAO,EACP,aAAa,EACb,qBAAqB,GAEtB,MAAM,eAAe,CAAC;AAkBvB;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,IAAI,CAAC,OAA+B;IACxD,MAAM,WAAW,GAAuC;QACtD,WAAW,EAAE,OAAO,CAAC,WAAW;KACjC,CAAC;IAEF,IAAI,OAAO,OAAO,CAAC,OAAO,KAAK,QAAQ,EAAE,CAAC;QACxC,WAAW,CAAC,QAAQ,GAAG,OAAO,CAAC,OAAO,CAAC;IACzC,CAAC;SAAM,CAAC;QACN,WAAW,CAAC,UAAU,GAAG,OAAO,CAAC,OAAO,CAAC;IAC3C,CAAC;IAED,IAAI,OAAO,CAAC,YAAY,EAAE,CAAC;QACzB,MAAM,KAAK,GAA+C,EAAE,CAAC;QAC7D,MAAM,OAAO,GAA2D,EAAE,CAAC;QAE3E,KAAK,MAAM,CAAC,IAAI,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,OAAO,CAAC,YAAY,CAAC,EAAE,CAAC;YACjE,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;gBAC9B,KAAK,CAAC,IAAyB,CAAC,GAAG,KAAK,CAAC;YAC3C,CAAC;iBAAM,IAAI,KAAK,EAAE,CAAC;gBACjB,OAAO,CAAC,IAAyB,CAAC,GAAG,KAAK,CAAC;YAC7C,CAAC;QACH,CAAC;QAED,IAAI,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,MAAM,GAAG,CAAC;YAAE,WAAW,CAAC,aAAa,GAAG,KAAK,CAAC;QACrE,IAAI,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,MAAM,GAAG,CAAC;YAAE,WAAW,CAAC,eAAe,GAAG,OAAO,CAAC;IAC7E,CAAC;IAED,MAAM,YAAY,CAAC,WAAW,CAAC,CAAC;AAClC,CAAC;AAED;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,WAAW,CAC/B,IAAY,EACZ,UAGI,EAAE;IAEN,MAAM,QAAQ,GAAG,OAAO,CAAC,QAAQ,IAAI,YAAY,CAAC;IAClD,MAAM,QAAQ,GAAG,OAAO,CAAC,QAAQ,IAAI,MAAM,CAAC;IAE5C,IAAI,CAAC,qBAAqB,EAAE,EAAE,CAAC;QAC7B,MAAM,IAAI,KAAK,CAAC,8CAA8C,CAAC,CAAC;IAClE,CAAC;IAED,OAAO,OAAO,CAAC,IAAI,EAAE,QAAQ,EAAE,QAAQ,CAAC,CAAC;AAC3C,CAAC;AAED;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,iBAAiB,CACrC,IAAY,EACZ,UAGI,EAAE;IAEN,MAAM,QAAQ,GAAG,OAAO,CAAC,QAAQ,IAAI,YAAY,CAAC;IAClD,MAAM,QAAQ,GAAG,OAAO,CAAC,QAAQ,IAAI,MAAM,CAAC;IAE5C,IAAI,CAAC,qBAAqB,EAAE,EAAE,CAAC;QAC7B,MAAM,IAAI,KAAK,CAAC,8CAA8C,CAAC,CAAC;IAClE,CAAC;IAED,OAAO,aAAa,CAAC,IAAI,EAAE,QAAQ,EAAE,QAAQ,CAAC,CAAC;AACjD,CAAC"}
1
+ {"version":3,"file":"browser.js","sourceRoot":"","sources":["../src/browser.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EACL,YAAY,EACZ,OAAO,EACP,aAAa,EACb,qBAAqB,GAEtB,MAAM,eAAe,CAAC;AAkBvB;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,IAAI,CAAC,OAA+B;IACxD,MAAM,WAAW,GAAuC;QACtD,WAAW,EAAE,OAAO,CAAC,WAAW;KACjC,CAAC;IAEF,IAAI,OAAO,OAAO,CAAC,OAAO,KAAK,QAAQ,EAAE,CAAC;QACxC,WAAW,CAAC,QAAQ,GAAG,OAAO,CAAC,OAAO,CAAC;IACzC,CAAC;SAAM,CAAC;QACN,WAAW,CAAC,UAAU,GAAG,OAAO,CAAC,OAAO,CAAC;IAC3C,CAAC;IAED,IAAI,OAAO,CAAC,YAAY,EAAE,CAAC;QACzB,MAAM,KAAK,GAA+C,EAAE,CAAC;QAC7D,MAAM,OAAO,GAA2D,EAAE,CAAC;QAE3E,KAAK,MAAM,CAAC,IAAI,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,OAAO,CAAC,YAAY,CAAC,EAAE,CAAC;YACjE,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;gBAC9B,KAAK,CAAC,IAAyB,CAAC,GAAG,KAAK,CAAC;YAC3C,CAAC;iBAAM,IAAI,KAAK,EAAE,CAAC;gBACjB,OAAO,CAAC,IAAyB,CAAC,GAAG,KAAK,CAAC;YAC7C,CAAC;QACH,CAAC;QAED,IAAI,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,MAAM,GAAG,CAAC;YAAE,WAAW,CAAC,aAAa,GAAG,KAAK,CAAC;QACrE,IAAI,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,MAAM,GAAG,CAAC;YAAE,WAAW,CAAC,eAAe,GAAG,OAAO,CAAC;IAC7E,CAAC;IAED,MAAM,YAAY,CAAC,WAAW,CAAC,CAAC;AAClC,CAAC;AAED;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,WAAW,CAC/B,IAAY,EACZ,OAAO,GAGH,EAAE;IAEN,MAAM,QAAQ,GAAG,OAAO,CAAC,QAAQ,IAAI,YAAY,CAAC;IAClD,MAAM,QAAQ,GAAG,OAAO,CAAC,QAAQ,IAAI,MAAM,CAAC;IAE5C,IAAI,CAAC,qBAAqB,EAAE,EAAE,CAAC;QAC7B,MAAM,IAAI,KAAK,CAAC,8CAA8C,CAAC,CAAC;IAClE,CAAC;IAED,OAAO,OAAO,CAAC,IAAI,EAAE,QAAQ,EAAE,QAAQ,CAAC,CAAC;AAC3C,CAAC;AAED;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,iBAAiB,CACrC,IAAY,EACZ,OAAO,GAGH,EAAE;IAEN,MAAM,QAAQ,GAAG,OAAO,CAAC,QAAQ,IAAI,YAAY,CAAC;IAClD,MAAM,QAAQ,GAAG,OAAO,CAAC,QAAQ,IAAI,MAAM,CAAC;IAE5C,IAAI,CAAC,qBAAqB,EAAE,EAAE,CAAC;QAC7B,MAAM,IAAI,KAAK,CAAC,8CAA8C,CAAC,CAAC;IAClE,CAAC;IAED,OAAO,aAAa,CAAC,IAAI,EAAE,QAAQ,EAAE,QAAQ,CAAC,CAAC;AACjD,CAAC"}