semantifold 0.3.0 → 0.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (297) hide show
  1. package/README.md +58 -15
  2. package/build/index.d.ts +48 -2
  3. package/build/index.d.ts.map +1 -1
  4. package/build/index.js +57 -8
  5. package/build/src/artifact-path.d.ts +23 -1
  6. package/build/src/artifact-path.d.ts.map +1 -1
  7. package/build/src/artifact-path.js +45 -3
  8. package/build/src/artifacts.d.ts.map +1 -1
  9. package/build/src/artifacts.js +66 -1
  10. package/build/src/backends/c-validation.d.ts.map +1 -1
  11. package/build/src/backends/c-validation.js +7 -3
  12. package/build/src/backends/cpp-validation.d.ts.map +1 -1
  13. package/build/src/backends/cpp-validation.js +7 -3
  14. package/build/src/backends/csharp.js +7 -1
  15. package/build/src/backends/dart-runtime.d.ts +2 -0
  16. package/build/src/backends/dart-runtime.d.ts.map +1 -0
  17. package/build/src/backends/dart-runtime.js +41 -0
  18. package/build/src/backends/dart.d.ts +20 -0
  19. package/build/src/backends/dart.d.ts.map +1 -0
  20. package/build/src/backends/dart.js +321 -0
  21. package/build/src/backends/effects.d.ts +60 -0
  22. package/build/src/backends/effects.d.ts.map +1 -0
  23. package/build/src/backends/effects.js +746 -0
  24. package/build/src/backends/go.js +18 -4
  25. package/build/src/backends/identifiers.d.ts +36 -4
  26. package/build/src/backends/identifiers.d.ts.map +1 -1
  27. package/build/src/backends/identifiers.js +154 -10
  28. package/build/src/backends/index.d.ts.map +1 -1
  29. package/build/src/backends/index.js +27 -4
  30. package/build/src/backends/ios.d.ts +68 -0
  31. package/build/src/backends/ios.d.ts.map +1 -0
  32. package/build/src/backends/ios.js +1503 -0
  33. package/build/src/backends/java.d.ts.map +1 -1
  34. package/build/src/backends/java.js +429 -36
  35. package/build/src/backends/javascript.d.ts +6 -0
  36. package/build/src/backends/javascript.d.ts.map +1 -1
  37. package/build/src/backends/javascript.js +380 -24
  38. package/build/src/backends/kotlin-runtime.d.ts +3 -0
  39. package/build/src/backends/kotlin-runtime.d.ts.map +1 -0
  40. package/build/src/backends/kotlin-runtime.js +29 -0
  41. package/build/src/backends/kotlin.d.ts +23 -0
  42. package/build/src/backends/kotlin.d.ts.map +1 -0
  43. package/build/src/backends/kotlin.js +136 -0
  44. package/build/src/backends/native-validation.d.ts +2 -2
  45. package/build/src/backends/native-validation.d.ts.map +1 -1
  46. package/build/src/backends/native-validation.js +2 -2
  47. package/build/src/backends/ordered-expressions.d.ts.map +1 -1
  48. package/build/src/backends/ordered-expressions.js +39 -7
  49. package/build/src/backends/php-stdlib-support.d.ts +19 -0
  50. package/build/src/backends/php-stdlib-support.d.ts.map +1 -0
  51. package/build/src/backends/php-stdlib-support.js +227 -0
  52. package/build/src/backends/php.d.ts.map +1 -1
  53. package/build/src/backends/php.js +448 -33
  54. package/build/src/backends/program.d.ts +81 -0
  55. package/build/src/backends/program.d.ts.map +1 -0
  56. package/build/src/backends/program.js +1308 -0
  57. package/build/src/backends/python.js +7 -1
  58. package/build/src/backends/ruby.d.ts.map +1 -1
  59. package/build/src/backends/ruby.js +310 -24
  60. package/build/src/backends/rust-runtime.d.ts +7 -0
  61. package/build/src/backends/rust-runtime.d.ts.map +1 -0
  62. package/build/src/backends/rust-runtime.js +32 -0
  63. package/build/src/backends/rust-validation.d.ts +9 -0
  64. package/build/src/backends/rust-validation.d.ts.map +1 -0
  65. package/build/src/backends/rust-validation.js +78 -0
  66. package/build/src/backends/rust.d.ts +24 -0
  67. package/build/src/backends/rust.d.ts.map +1 -0
  68. package/build/src/backends/rust.js +344 -0
  69. package/build/src/backends/scalars.d.ts +14 -6
  70. package/build/src/backends/scalars.d.ts.map +1 -1
  71. package/build/src/backends/scalars.js +167 -17
  72. package/build/src/backends/shared.d.ts +23 -4
  73. package/build/src/backends/shared.d.ts.map +1 -1
  74. package/build/src/backends/shared.js +2158 -62
  75. package/build/src/backends/stdlib-support.d.ts +14 -0
  76. package/build/src/backends/stdlib-support.d.ts.map +1 -0
  77. package/build/src/backends/stdlib-support.js +237 -0
  78. package/build/src/backends/swift-runtime.d.ts +3 -0
  79. package/build/src/backends/swift-runtime.d.ts.map +1 -0
  80. package/build/src/backends/swift-runtime.js +14 -0
  81. package/build/src/backends/swift.d.ts +8 -0
  82. package/build/src/backends/swift.d.ts.map +1 -0
  83. package/build/src/backends/swift.js +127 -0
  84. package/build/src/backends/typescript.d.ts.map +1 -1
  85. package/build/src/backends/typescript.js +344 -24
  86. package/build/src/backends/wasm.d.ts +43 -0
  87. package/build/src/backends/wasm.d.ts.map +1 -0
  88. package/build/src/backends/wasm.js +2164 -0
  89. package/build/src/backends/writer.d.ts +235 -4
  90. package/build/src/backends/writer.d.ts.map +1 -1
  91. package/build/src/backends/writer.js +468 -3
  92. package/build/src/diagnostic.d.ts +4 -3
  93. package/build/src/diagnostic.d.ts.map +1 -1
  94. package/build/src/diagnostic.js +5 -3
  95. package/build/src/frontends/c.d.ts.map +1 -1
  96. package/build/src/frontends/c.js +5 -3
  97. package/build/src/frontends/cpp.d.ts.map +1 -1
  98. package/build/src/frontends/cpp.js +5 -3
  99. package/build/src/frontends/csharp.d.ts.map +1 -1
  100. package/build/src/frontends/csharp.js +7 -3
  101. package/build/src/frontends/dart.d.ts +10 -0
  102. package/build/src/frontends/dart.d.ts.map +1 -0
  103. package/build/src/frontends/dart.js +913 -0
  104. package/build/src/frontends/index.d.ts +3 -1
  105. package/build/src/frontends/index.d.ts.map +1 -1
  106. package/build/src/frontends/index.js +15 -5
  107. package/build/src/frontends/java.d.ts +110 -1
  108. package/build/src/frontends/java.d.ts.map +1 -1
  109. package/build/src/frontends/java.js +1725 -70
  110. package/build/src/frontends/javascript-typescript.d.ts +69 -1
  111. package/build/src/frontends/javascript-typescript.d.ts.map +1 -1
  112. package/build/src/frontends/javascript-typescript.js +1825 -93
  113. package/build/src/frontends/kotlin.d.ts +10 -0
  114. package/build/src/frontends/kotlin.d.ts.map +1 -0
  115. package/build/src/frontends/kotlin.js +685 -0
  116. package/build/src/frontends/php.d.ts +118 -1
  117. package/build/src/frontends/php.d.ts.map +1 -1
  118. package/build/src/frontends/php.js +1583 -76
  119. package/build/src/frontends/program.d.ts +74 -0
  120. package/build/src/frontends/program.d.ts.map +1 -0
  121. package/build/src/frontends/program.js +989 -0
  122. package/build/src/frontends/ruby.d.ts +68 -1
  123. package/build/src/frontends/ruby.d.ts.map +1 -1
  124. package/build/src/frontends/ruby.js +1446 -101
  125. package/build/src/frontends/rust-parser.d.ts +11 -0
  126. package/build/src/frontends/rust-parser.d.ts.map +1 -0
  127. package/build/src/frontends/rust-parser.js +15 -0
  128. package/build/src/frontends/rust.d.ts +14 -0
  129. package/build/src/frontends/rust.d.ts.map +1 -0
  130. package/build/src/frontends/rust.js +715 -0
  131. package/build/src/frontends/scalars.d.ts +10 -0
  132. package/build/src/frontends/scalars.d.ts.map +1 -1
  133. package/build/src/frontends/scalars.js +28 -2
  134. package/build/src/frontends/swift.d.ts +10 -0
  135. package/build/src/frontends/swift.d.ts.map +1 -0
  136. package/build/src/frontends/swift.js +860 -0
  137. package/build/src/frontends/types.d.ts +186 -0
  138. package/build/src/frontends/types.d.ts.map +1 -0
  139. package/build/src/frontends/types.js +634 -0
  140. package/build/src/language-registry.d.ts +46 -4
  141. package/build/src/language-registry.d.ts.map +1 -1
  142. package/build/src/language-registry.js +167 -13
  143. package/build/src/mapping.d.ts +2 -2
  144. package/build/src/mapping.d.ts.map +1 -1
  145. package/build/src/mapping.js +31 -10
  146. package/build/src/semantic/capabilities.d.ts +66 -0
  147. package/build/src/semantic/capabilities.d.ts.map +1 -0
  148. package/build/src/semantic/capabilities.js +649 -0
  149. package/build/src/semantic/effects.d.ts +26 -0
  150. package/build/src/semantic/effects.d.ts.map +1 -0
  151. package/build/src/semantic/effects.js +764 -0
  152. package/build/src/semantic/generics.d.ts +23 -0
  153. package/build/src/semantic/generics.d.ts.map +1 -0
  154. package/build/src/semantic/generics.js +61 -0
  155. package/build/src/semantic/lifetime.d.ts +37 -0
  156. package/build/src/semantic/lifetime.d.ts.map +1 -0
  157. package/build/src/semantic/lifetime.js +527 -0
  158. package/build/src/semantic/provenance.d.ts +9 -2
  159. package/build/src/semantic/provenance.d.ts.map +1 -1
  160. package/build/src/semantic/provenance.js +462 -20
  161. package/build/src/semantic/scalars.d.ts +11 -0
  162. package/build/src/semantic/scalars.d.ts.map +1 -1
  163. package/build/src/semantic/scalars.js +16 -1
  164. package/build/src/semantic/stdlib.d.ts +254 -0
  165. package/build/src/semantic/stdlib.d.ts.map +1 -0
  166. package/build/src/semantic/stdlib.js +880 -0
  167. package/build/src/semantic/types.d.ts +2952 -202
  168. package/build/src/semantic/types.d.ts.map +1 -1
  169. package/build/src/semantic/types.js +688 -15
  170. package/build/src/semantic/validate.d.ts +85 -5
  171. package/build/src/semantic/validate.d.ts.map +1 -1
  172. package/build/src/semantic/validate.js +2576 -98
  173. package/build/src/stdlib-facades.d.ts +304 -0
  174. package/build/src/stdlib-facades.d.ts.map +1 -0
  175. package/build/src/stdlib-facades.js +1167 -0
  176. package/build/src/stdlib-negotiation.d.ts +69 -0
  177. package/build/src/stdlib-negotiation.d.ts.map +1 -0
  178. package/build/src/stdlib-negotiation.js +403 -0
  179. package/build/src/stdlib-providers.d.ts +72 -0
  180. package/build/src/stdlib-providers.d.ts.map +1 -0
  181. package/build/src/stdlib-providers.js +339 -0
  182. package/build/src/toolchains.d.ts +55 -1
  183. package/build/src/toolchains.d.ts.map +1 -1
  184. package/build/src/toolchains.js +15 -4
  185. package/docs/architecture.md +45 -13
  186. package/docs/dart.md +60 -0
  187. package/docs/goals.md +3 -3
  188. package/docs/ios.md +121 -0
  189. package/docs/kotlin.md +42 -0
  190. package/docs/language-support.md +231 -26
  191. package/docs/multi-file-modules.md +52 -0
  192. package/docs/parser-qualification.md +121 -8
  193. package/docs/plans/2026-09-05-standard-library-portability.md +10 -10
  194. package/docs/rust.md +88 -0
  195. package/docs/source-maps.md +15 -7
  196. package/docs/standard-library-portability.md +39 -8
  197. package/docs/swift.md +44 -0
  198. package/docs/testing.md +366 -4
  199. package/docs/webassembly.md +52 -0
  200. package/index.js +63 -8
  201. package/node_modules/semantifold-tree-sitter-legacy-internal/README.md +2 -2
  202. package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/LICENSE +21 -0
  203. package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/README.md +45 -0
  204. package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/binding.gyp +30 -0
  205. package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/bindings/node/binding.cc +20 -0
  206. package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/bindings/node/binding_test.js +9 -0
  207. package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/bindings/node/index.d.ts +28 -0
  208. package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/bindings/node/index.js +11 -0
  209. package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/grammar.js +1630 -0
  210. package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/package.json +64 -0
  211. package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/prebuilds/darwin-arm64/tree-sitter-rust.node +0 -0
  212. package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/prebuilds/darwin-x64/tree-sitter-rust.node +0 -0
  213. package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/prebuilds/linux-arm64/tree-sitter-rust.node +0 -0
  214. package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/prebuilds/linux-x64/tree-sitter-rust.node +0 -0
  215. package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/prebuilds/win32-arm64/tree-sitter-rust.node +0 -0
  216. package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/prebuilds/win32-x64/tree-sitter-rust.node +0 -0
  217. package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/queries/highlights.scm +159 -0
  218. package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/queries/injections.scm +9 -0
  219. package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/queries/tags.scm +60 -0
  220. package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/src/grammar.json +9405 -0
  221. package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/src/node-types.json +5399 -0
  222. package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/src/parser.c +192569 -0
  223. package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/src/scanner.c +393 -0
  224. package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/src/tree_sitter/alloc.h +54 -0
  225. package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/src/tree_sitter/array.h +290 -0
  226. package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/src/tree_sitter/parser.h +266 -0
  227. package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/tree-sitter-rust.wasm +0 -0
  228. package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/tree-sitter.json +53 -0
  229. package/node_modules/semantifold-tree-sitter-legacy-internal/package.json +3 -2
  230. package/node_modules/semantifold-tree-sitter-legacy-internal/src/c.js +5 -4
  231. package/package.json +5 -2
  232. package/src/artifact-path.js +47 -2
  233. package/src/artifacts.js +67 -0
  234. package/src/backends/c-validation.js +6 -1
  235. package/src/backends/cpp-validation.js +6 -1
  236. package/src/backends/csharp.js +3 -0
  237. package/src/backends/dart-runtime.js +41 -0
  238. package/src/backends/dart.js +326 -0
  239. package/src/backends/effects.js +705 -0
  240. package/src/backends/go.js +14 -2
  241. package/src/backends/identifiers.js +160 -9
  242. package/src/backends/index.js +27 -2
  243. package/src/backends/ios.js +1612 -0
  244. package/src/backends/java.js +454 -36
  245. package/src/backends/javascript.js +389 -23
  246. package/src/backends/kotlin-runtime.js +29 -0
  247. package/src/backends/kotlin.js +141 -0
  248. package/src/backends/native-validation.js +1 -1
  249. package/src/backends/ordered-expressions.js +40 -6
  250. package/src/backends/php-stdlib-support.js +239 -0
  251. package/src/backends/php.js +469 -32
  252. package/src/backends/program.js +1407 -0
  253. package/src/backends/python.js +3 -0
  254. package/src/backends/ruby.js +326 -23
  255. package/src/backends/rust-runtime.js +34 -0
  256. package/src/backends/rust-validation.js +75 -0
  257. package/src/backends/rust.js +335 -0
  258. package/src/backends/scalars.js +141 -16
  259. package/src/backends/shared.js +2304 -124
  260. package/src/backends/stdlib-support.js +234 -0
  261. package/src/backends/swift-runtime.js +14 -0
  262. package/src/backends/swift.js +132 -0
  263. package/src/backends/typescript.js +349 -23
  264. package/src/backends/wasm.js +2208 -0
  265. package/src/backends/writer.js +520 -2
  266. package/src/diagnostic.js +4 -2
  267. package/src/frontends/c.js +4 -2
  268. package/src/frontends/cpp.js +4 -2
  269. package/src/frontends/csharp.js +4 -2
  270. package/src/frontends/dart.js +963 -0
  271. package/src/frontends/index.js +14 -4
  272. package/src/frontends/java.js +1977 -69
  273. package/src/frontends/javascript-typescript.js +2046 -102
  274. package/src/frontends/kotlin.js +713 -0
  275. package/src/frontends/php.js +1725 -79
  276. package/src/frontends/program.js +1062 -0
  277. package/src/frontends/ruby.js +1624 -98
  278. package/src/frontends/rust-parser.js +18 -0
  279. package/src/frontends/rust.js +714 -0
  280. package/src/frontends/scalars.js +31 -1
  281. package/src/frontends/swift.js +893 -0
  282. package/src/frontends/types.js +750 -0
  283. package/src/language-registry.js +172 -12
  284. package/src/mapping.js +33 -9
  285. package/src/semantic/capabilities.js +671 -0
  286. package/src/semantic/effects.js +737 -0
  287. package/src/semantic/generics.js +58 -0
  288. package/src/semantic/lifetime.js +517 -0
  289. package/src/semantic/provenance.js +412 -19
  290. package/src/semantic/scalars.js +17 -0
  291. package/src/semantic/stdlib.js +921 -0
  292. package/src/semantic/types.js +765 -14
  293. package/src/semantic/validate.js +2934 -209
  294. package/src/stdlib-facades.js +1211 -0
  295. package/src/stdlib-negotiation.js +446 -0
  296. package/src/stdlib-providers.js +377 -0
  297. package/src/toolchains.js +16 -3
@@ -0,0 +1,715 @@
1
+ // @ts-check
2
+ import { rustRuntime } from "../backends/rust-runtime.js";
3
+ import { maximumRustSourceLength } from "../backends/rust-validation.js";
4
+ import { isRustIdentifier } from "../backends/identifiers.js";
5
+ import { missingType, SemantifoldDiagnostic, unsupportedSyntax } from "../diagnostic.js";
6
+ import { createCoordinateIndex, indexedPointAt } from "../semantic/location.js";
7
+ import { withAdaptedOperation } from "../semantic/operators.js";
8
+ import { withParserRanges } from "../semantic/provenance.js";
9
+ import { hasOnlyUnicodeScalars } from "../semantic/scalars.js";
10
+ import { validateParsedModule } from "../semantic/validate.js";
11
+ import { sourceScalarType } from "./scalars.js";
12
+ import { parseRustCst } from "./rust-parser.js";
13
+ /** @typedef {import("./rust-parser.js").CstNode} CstNode */
14
+ /** @typedef {import("../semantic/types.js").Expression} Expression */
15
+ /** @typedef {import("../semantic/types.js").Statement} Statement */
16
+ /** @typedef {import("../semantic/types.js").SemanticTypeName} Scalar */
17
+ const binaryOperations = new Map([
18
+ ["+", "Add"], ["-", "Subtract"], ["*", "Multiply"], ["==", "Equal"], ["!=", "NotEqual"],
19
+ ["<", "LessThan"], ["<=", "LessThanOrEqual"], [">", "GreaterThan"], [">=", "GreaterThanOrEqual"],
20
+ ["&&", "And"], ["||", "Or"]
21
+ ]);
22
+ const arithmeticHelpers = new Map([
23
+ ["semantifold_integer_add", "PhpAdd"], ["semantifold_integer_subtract", "Subtract"],
24
+ ["semantifold_integer_multiply", "Multiply"]
25
+ ]);
26
+ /** Consumes complete Rust CST shapes and retains source-only scaffold constraints. */
27
+ class RustReader {
28
+ /**
29
+ * Owns source text and parser-origin metadata, never native parser handles.
30
+ * @param {string} filename - Original filename.
31
+ * @param {string} source - Exact source.
32
+ */
33
+ constructor(filename, source) {
34
+ this.filename = filename;
35
+ this.source = source;
36
+ this.coordinates = createCoordinateIndex(source);
37
+ /** @type {Set<string>} */
38
+ this.helpers = new Set();
39
+ /** @type {Map<Expression, CstNode>} */
40
+ this.clones = new Map();
41
+ /** @type {Map<Expression, {borrowed: boolean, node: CstNode}>} */
42
+ this.additions = new Map();
43
+ /** @type {Map<Statement, {type: string, node: CstNode}>} */
44
+ this.prints = new Map();
45
+ /** @type {Map<string, Scalar>} */
46
+ this.functions = new Map();
47
+ }
48
+ /**
49
+ * Locates an original parser node in UTF-16 coordinates.
50
+ * @param {CstNode} node - Original node.
51
+ * @returns {import("../semantic/types.js").SourceLocation} Exact location.
52
+ */
53
+ location(node) {
54
+ return { filename: this.filename, start: indexedPointAt(this.coordinates, node.startIndex), end: indexedPointAt(this.coordinates, node.endIndex) };
55
+ }
56
+ /**
57
+ * Reads the spelling of an already recognized parser node.
58
+ * @param {CstNode} node - Recognized node.
59
+ * @returns {string} Original spelling.
60
+ */
61
+ text(node) {
62
+ return this.source.slice(node.startIndex, node.endIndex);
63
+ }
64
+ /**
65
+ * Rejects one located source-profile violation.
66
+ * @param {CstNode} node - Violating node.
67
+ * @param {string} [detail] - Profile detail.
68
+ * @returns {never} Always throws.
69
+ */
70
+ fail(node, detail = node.type) {
71
+ unsupportedSyntax("rust", detail, this.location(node));
72
+ }
73
+ /**
74
+ * Accounts for recovery, every extra, and doc comments before interpreting meaning.
75
+ * @param {CstNode} node - Current node.
76
+ * @param {number} [depth] - Bounded traversal depth.
77
+ * @returns {void}
78
+ */
79
+ validateTree(node, depth = 0) {
80
+ if (depth > 512)
81
+ this.fail(node, "Rust CST exceeds the 512-level traversal limit");
82
+ for (const { node: child } of node.children)
83
+ this.validateTree(child, depth + 1);
84
+ if (node.error || node.missing || node.hasError) {
85
+ throw new SemantifoldDiagnostic({ code: "PARSE_ERROR", language: "rust", location: this.location(node), message: `Rust parser recovery at '${node.type}'.` });
86
+ }
87
+ if (node.extra && !["line_comment", "block_comment"].includes(node.type))
88
+ this.fail(node, "unexpected extra parser child");
89
+ if (["line_comment", "block_comment"].includes(node.type) && /^(?:\/\/[!/]|\/\*[*!])/u.test(this.text(node))) {
90
+ this.fail(node, "doc-comment attribute");
91
+ }
92
+ }
93
+ /**
94
+ * Omits only inert comments already checked during exhaustive traversal.
95
+ * @param {CstNode} node - Parent.
96
+ * @returns {CstNode[]} Ordered structural children.
97
+ */
98
+ parts(node) {
99
+ return node.children.map(({ node: child }) => child).filter(child => !["line_comment", "block_comment"].includes(child.type));
100
+ }
101
+ /**
102
+ * Requires an exact sole parser field.
103
+ * @param {CstNode} node - Field owner.
104
+ * @param {string} name - Field name.
105
+ * @returns {CstNode} Sole field value.
106
+ */
107
+ field(node, name) {
108
+ const edges = node.children.filter(({ field }) => field == name);
109
+ if (edges.length != 1)
110
+ this.fail(node, `expected one '${name}' field`);
111
+ return edges[0].node;
112
+ }
113
+ /**
114
+ * Requires all ordered children, including anonymous punctuation.
115
+ * @param {CstNode} node - Shape owner.
116
+ * @param {(CstNode | string)[]} expected - Exact child sequence.
117
+ * @returns {void}
118
+ */
119
+ shape(node, expected) {
120
+ const parts = this.parts(node);
121
+ if (parts.length != expected.length || parts.some((child, index) => typeof expected[index] == "string" ? child.type != expected[index] || !child.named && this.text(child) != expected[index] : child !== expected[index]))
122
+ this.fail(node, `${node.type} child shape`);
123
+ }
124
+ /**
125
+ * Protects Rust keywords and the private support namespace.
126
+ * @param {CstNode} node - Identifier token.
127
+ * @returns {string} Validated name.
128
+ */
129
+ identifier(node) {
130
+ const name = this.text(node);
131
+ if (node.type != "identifier" || !isRustIdentifier(name))
132
+ this.fail(node, "reserved or unsupported identifier");
133
+ return name;
134
+ }
135
+ /**
136
+ * Accepts only explicitly spelled i64, bool and owned String.
137
+ * @param {CstNode} node - Type token.
138
+ * @returns {import("../semantic/types.js").TypeReference} Semantic scalar type.
139
+ */
140
+ type(node) {
141
+ if (node.children.length || !["primitive_type", "type_identifier"].includes(node.type))
142
+ this.fail(node, "scalar type shape");
143
+ const spelling = this.text(node);
144
+ const type = sourceScalarType("rust", spelling, this.location(node));
145
+ if (!type)
146
+ return missingType("rust", "scalar", this.location(node));
147
+ if ((spelling == "String") != (node.type == "type_identifier"))
148
+ this.fail(node, "scalar type spelling");
149
+ return type;
150
+ }
151
+ /**
152
+ * Converts exact call syntax without interpreting macro token trees as calls.
153
+ * @param {CstNode} node - Call expression.
154
+ * @returns {{name: CstNode, arguments: CstNode[]}} Parsed direct argument sequence.
155
+ */
156
+ call(node) {
157
+ if (node.type != "call_expression")
158
+ this.fail(node, "direct call required");
159
+ const name = this.field(node, "function");
160
+ const list = this.field(node, "arguments");
161
+ this.shape(node, [name, list]);
162
+ if (list.type != "arguments")
163
+ this.fail(list, "call arguments");
164
+ const args = this.parts(list).slice(1, -1).filter((_part, index) => index % 2 == 0);
165
+ this.shape(list, ["(", ...args.flatMap((arg, index) => index == 0 ? [arg] : [",", arg]), ")"]);
166
+ return { arguments: args, name };
167
+ }
168
+ /**
169
+ * Decodes parser-owned ordinary string content and exact scalar escapes.
170
+ * @param {CstNode} node - String literal.
171
+ * @returns {string} Unicode scalar value.
172
+ */
173
+ string(node) {
174
+ if (node.type != "string_literal")
175
+ this.fail(node, "ordinary String literal required");
176
+ const parts = this.parts(node);
177
+ this.shape(node, ['"', ...parts.slice(1, -1), '"']);
178
+ let value = "";
179
+ for (const part of parts.slice(1, -1)) {
180
+ const spelling = this.text(part);
181
+ if (part.type == "string_content") {
182
+ if (/[\r\n]/u.test(spelling))
183
+ this.fail(part, "raw string line terminator");
184
+ value += spelling;
185
+ }
186
+ else if (part.type == "escape_sequence") {
187
+ const escape = spelling.slice(1);
188
+ const simple = new Map([["0", "\0"], ["n", "\n"], ["r", "\r"], ["t", "\t"], ["\\", "\\"], ['"', '"'], ["'", "'"]]);
189
+ if (spelling[0] != "\\")
190
+ this.fail(part, "escape prefix");
191
+ if (simple.has(escape))
192
+ value += simple.get(escape);
193
+ else if (/^x[0-9a-fA-F]{2}$/u.test(escape)) {
194
+ const scalar = Number.parseInt(escape.slice(1), 16);
195
+ if (scalar > 127)
196
+ this.fail(part, "non-ASCII byte escape");
197
+ value += String.fromCodePoint(scalar);
198
+ }
199
+ else if (/^u\{[0-9a-fA-F]{1,6}\}$/u.test(escape)) {
200
+ const scalar = Number.parseInt(escape.slice(2, -1), 16);
201
+ if (scalar > 0x10FFFF || scalar >= 0xD800 && scalar <= 0xDFFF)
202
+ this.fail(part, "non-scalar Unicode escape");
203
+ value += String.fromCodePoint(scalar);
204
+ }
205
+ else
206
+ this.fail(part, "unsupported string escape");
207
+ }
208
+ else
209
+ this.fail(part, "string child");
210
+ }
211
+ return value;
212
+ }
213
+ /**
214
+ * Converts exact scalar expressions while retaining source clone/borrow constraints.
215
+ * @param {CstNode} node - Expression node.
216
+ * @returns {Expression} Pending typed semantic expression.
217
+ */
218
+ expression(node) {
219
+ const location = this.location(node);
220
+ if (node.type == "parenthesized_expression") {
221
+ const parts = this.parts(node);
222
+ this.shape(node, ["(", parts[1], ")"]);
223
+ return this.expression(parts[1]);
224
+ }
225
+ if (node.type == "identifier")
226
+ return withParserRanges({ kind: "IdentifierExpression", location, name: this.identifier(node) }, { name: location });
227
+ if (node.type == "integer_literal") {
228
+ const spelling = this.text(node);
229
+ const value = Number(spelling.slice(0, -3));
230
+ if (!/^(?:0|[1-9][0-9]*)i64$/u.test(spelling) || !Number.isSafeInteger(value))
231
+ this.fail(node, "non-safe or noncanonical i64 literal");
232
+ return withParserRanges({ kind: "IntegerLiteral", location, value }, { literal: location });
233
+ }
234
+ if (node.type == "boolean_literal") {
235
+ const spelling = this.text(node);
236
+ if (spelling != "true" && spelling != "false")
237
+ this.fail(node, "Boolean literal spelling");
238
+ this.shape(node, [spelling]);
239
+ return withParserRanges({ kind: "BooleanLiteral", location, value: spelling == "true" }, { literal: location });
240
+ }
241
+ if (node.type == "unary_expression") {
242
+ const parts = this.parts(node);
243
+ this.shape(node, [parts[0], parts[1]]);
244
+ if (!["-", "!"].includes(parts[0].type))
245
+ this.fail(parts[0], "unary operator");
246
+ return this.unary(node, parts[0].type == "-" ? "Negate" : "Not", this.expression(parts[1]), parts[0]);
247
+ }
248
+ if (node.type == "binary_expression") {
249
+ const left = this.field(node, "left");
250
+ const right = this.field(node, "right");
251
+ const operator = this.field(node, "operator");
252
+ const intent = binaryOperations.get(operator.type);
253
+ this.shape(node, [left, operator, right]);
254
+ if (!intent)
255
+ this.fail(operator, "unsupported binary operator");
256
+ const borrowed = operator.type == "+" && right.type == "reference_expression";
257
+ const value = borrowed ? this.field(right, "value") : right;
258
+ if (borrowed)
259
+ this.shape(right, ["&", value]);
260
+ const expression = this.binary(node, intent, this.expression(left), this.expression(value), operator);
261
+ if (operator.type == "+")
262
+ this.additions.set(expression, { borrowed, node: right });
263
+ return expression;
264
+ }
265
+ if (node.type == "call_expression") {
266
+ const call = this.call(node);
267
+ const name = this.text(call.name);
268
+ if (call.name.type == "scoped_identifier") {
269
+ const owner = this.field(call.name, "path");
270
+ const method = this.field(call.name, "name");
271
+ this.shape(call.name, [owner, "::", method]);
272
+ if (owner.type != "identifier" || this.text(owner) != "String" || method.type != "identifier" || this.text(method) != "from" || call.arguments.length != 1) {
273
+ this.fail(call.name, "exact String::from construction required");
274
+ }
275
+ return withParserRanges({ kind: "StringLiteral", location, value: this.string(call.arguments[0]) }, { literal: this.location(call.arguments[0]) });
276
+ }
277
+ if (call.name.type == "field_expression") {
278
+ const receiver = this.field(call.name, "value");
279
+ const method = this.field(call.name, "field");
280
+ this.shape(call.name, [receiver, ".", method]);
281
+ if (method.type != "field_identifier" || this.text(method) != "clone" || call.arguments.length)
282
+ this.fail(call.name, "exact owned String clone required");
283
+ const expression = this.expression(receiver);
284
+ this.clones.set(expression, call.name);
285
+ return expression;
286
+ }
287
+ if (call.name.type != "identifier")
288
+ this.fail(call.name, "direct function call required");
289
+ if (this.helpers.has(name) && name == "semantifold_integer_negate") {
290
+ if (call.arguments.length != 1)
291
+ this.fail(node, "negation helper arity");
292
+ return this.unary(node, "Negate", this.expression(call.arguments[0]), call.name);
293
+ }
294
+ const intent = this.helpers.has(name) ? arithmeticHelpers.get(name) : undefined;
295
+ if (intent) {
296
+ if (call.arguments.length != 2)
297
+ this.fail(node, "arithmetic helper arity");
298
+ return this.binary(node, intent, this.expression(call.arguments[0]), this.expression(call.arguments[1]), call.name);
299
+ }
300
+ const callee = this.identifier(call.name);
301
+ if (call.arguments.length != 2)
302
+ this.fail(node, "semantic call arity");
303
+ return withParserRanges({ kind: "CallExpression", location, callee, arguments: call.arguments.map(argument => this.expression(argument)) }, { callee: this.location(call.name) });
304
+ }
305
+ return this.fail(node);
306
+ }
307
+ /**
308
+ * Retains parser operator intent until shared scalar resolution.
309
+ * @param {CstNode} node - Owning node.
310
+ * @param {string} intent - Parser operation.
311
+ * @param {Expression} left - Left operand.
312
+ * @param {Expression} right - Right operand.
313
+ * @param {CstNode} operator - Exact operator token.
314
+ * @returns {Expression} Pending binary expression.
315
+ */
316
+ binary(node, intent, left, right, operator) {
317
+ return /** @type {Expression} */ (withAdaptedOperation(withParserRanges({ kind: "BinaryExpression", location: this.location(node), left, right }, { operator: this.location(operator) }), /** @type {import("../semantic/operators.js").AdaptedOperation} */ (intent)));
318
+ }
319
+ /**
320
+ * Retains unary parser intent and its original token range.
321
+ * @param {CstNode} node - Owning node.
322
+ * @param {"Negate" | "Not"} intent - Unary intent.
323
+ * @param {Expression} operand - Operand.
324
+ * @param {CstNode} operator - Exact token.
325
+ * @returns {Expression} Pending unary expression.
326
+ */
327
+ unary(node, intent, operand, operator) {
328
+ return /** @type {Expression} */ (withAdaptedOperation(withParserRanges({ kind: "UnaryExpression", location: this.location(node), operand }, { operator: this.location(operator) }), intent));
329
+ }
330
+ /**
331
+ * Converts one explicitly typed initialized binding or executable statement.
332
+ * @param {CstNode} node - Statement.
333
+ * @returns {Statement} Semantic statement.
334
+ */
335
+ statement(node) {
336
+ const location = this.location(node);
337
+ const parts = this.parts(node);
338
+ if (node.type == "let_declaration") {
339
+ const typeNode = node.children.find(({ field }) => field == "type")?.node;
340
+ if (!typeNode)
341
+ return missingType("rust", "local", location);
342
+ const name = this.field(node, "pattern");
343
+ const value = this.field(node, "value");
344
+ const mutable = parts[1].type == "mutable_specifier";
345
+ this.shape(node, ["let", ...(mutable ? [parts[1]] : []), name, ":", typeNode, "=", value, ";"]);
346
+ if (mutable && this.text(parts[1]) != "mut")
347
+ this.fail(parts[1], "mutability token");
348
+ return withParserRanges({ kind: "LocalDeclaration", location, name: this.identifier(name), type: this.type(typeNode), mutable,
349
+ initializer: this.expression(value) }, { name: this.location(name), operator: this.location(parts[parts.length - 3]) });
350
+ }
351
+ if (node.type != "expression_statement")
352
+ this.fail(node, "explicit statement required; tail expressions are unsupported");
353
+ const expression = parts[0];
354
+ if (expression.type == "if_expression") {
355
+ this.shape(node, [expression]);
356
+ return this.conditional(expression);
357
+ }
358
+ this.shape(node, [expression, ";"]);
359
+ if (expression.type == "return_expression") {
360
+ const returned = this.parts(expression);
361
+ this.shape(expression, ["return", returned[1]]);
362
+ return { kind: "ReturnStatement", location, expression: this.expression(returned[1]) };
363
+ }
364
+ if (expression.type == "assignment_expression") {
365
+ const left = this.field(expression, "left");
366
+ const right = this.field(expression, "right");
367
+ this.shape(expression, [left, "=", right]);
368
+ const target = withParserRanges({ kind: /** @type {const} */ ("IdentifierExpression"), location: this.location(left), name: this.identifier(left) }, { name: this.location(left) });
369
+ return withParserRanges({ kind: "AssignmentStatement", location, target, expression: this.expression(right) }, { operator: this.location(this.parts(expression)[1]) });
370
+ }
371
+ const call = this.call(expression);
372
+ const name = this.text(call.name);
373
+ if (call.name.type != "identifier" || !this.helpers.has(name) || !/^semantifold_print_(?:integer|boolean|string)$/u.test(name) || call.arguments.length != 1)
374
+ this.fail(node, "exact print helper call required");
375
+ const statement = { kind: /** @type {const} */ ("PrintStatement"), location, expression: this.expression(call.arguments[0]) };
376
+ this.prints.set(statement, { node: call.name, type: name.slice("semantifold_print_".length) });
377
+ return statement;
378
+ }
379
+ /**
380
+ * Converts exact braced conditionals and else-if nesting.
381
+ * @param {CstNode} node - If expression used as a statement.
382
+ * @returns {import("../semantic/types.js").IfStatement} Conditional statement.
383
+ */
384
+ conditional(node) {
385
+ const condition = this.field(node, "condition");
386
+ const consequence = this.field(node, "consequence");
387
+ const alternative = node.children.find(({ field }) => field == "alternative")?.node;
388
+ this.shape(node, ["if", condition, consequence, ...(alternative ? [alternative] : [])]);
389
+ const statement = { kind: /** @type {const} */ ("IfStatement"), location: this.location(node), condition: this.expression(condition), consequent: this.block(consequence) };
390
+ if (!alternative)
391
+ return statement;
392
+ const branch = this.parts(alternative)[1];
393
+ this.shape(alternative, ["else", branch]);
394
+ return { ...statement, alternate: branch.type == "if_expression" ? { kind: "Block", location: this.location(branch), statements: [this.conditional(branch)] } : this.block(branch) };
395
+ }
396
+ /**
397
+ * Converts one complete lexical block.
398
+ * @param {CstNode} node - Braced block.
399
+ * @returns {import("../semantic/types.js").Block} Semantic block.
400
+ */
401
+ block(node) {
402
+ if (node.type != "block")
403
+ this.fail(node, "braced block required");
404
+ const parts = this.parts(node);
405
+ this.shape(node, ["{", ...parts.slice(1, -1), "}"]);
406
+ return { kind: "Block", location: this.location(node), statements: parts.slice(1, -1).map(child => this.statement(child)) };
407
+ }
408
+ /**
409
+ * Converts a crate-root function with exactly two required by-value parameters.
410
+ * @param {CstNode} node - Function item.
411
+ * @returns {import("../semantic/types.js").FunctionDeclaration} Semantic declaration.
412
+ */
413
+ function(node) {
414
+ const name = this.field(node, "name");
415
+ const parameters = this.field(node, "parameters");
416
+ const returnType = node.children.find(({ field }) => field == "return_type")?.node;
417
+ const body = this.field(node, "body");
418
+ if (!returnType)
419
+ return missingType("rust", "function return", this.location(node));
420
+ this.shape(node, ["fn", name, parameters, "->", returnType, body]);
421
+ this.shape(parameters, ["(", "parameter", ",", "parameter", ")"]);
422
+ const converted = [this.parts(parameters)[1], this.parts(parameters)[3]].map(parameter => {
423
+ const pattern = this.field(parameter, "pattern");
424
+ const type = this.field(parameter, "type");
425
+ this.shape(parameter, [pattern, ":", type]);
426
+ return withParserRanges({ kind: /** @type {const} */ ("Parameter"), location: this.location(parameter), name: this.identifier(pattern), type: this.type(type) }, { name: this.location(pattern) });
427
+ });
428
+ return withParserRanges({ kind: "FunctionDeclaration", location: this.location(node), name: this.identifier(name), parameters: converted,
429
+ returnType: this.type(returnType), body: this.block(body) }, { name: this.location(name) });
430
+ }
431
+ /**
432
+ * Compares all fields, children and leaf spellings against qualified support syntax.
433
+ * @param {CstNode} actual - Original node.
434
+ * @param {CstNode} expected - Qualified node.
435
+ * @param {RustReader} canonical - Qualified spelling reader.
436
+ * @returns {void}
437
+ */
438
+ compareTree(actual, expected, canonical) {
439
+ if (actual.type != expected.type || actual.named != expected.named || actual.extra != expected.extra)
440
+ this.fail(actual, "modified Rust support node");
441
+ const left = this.parts(actual);
442
+ const right = canonical.parts(expected);
443
+ if (left.length != right.length)
444
+ this.fail(actual, "modified Rust support children");
445
+ if (!left.length && this.text(actual) != canonical.text(expected))
446
+ this.fail(actual, "modified Rust support token");
447
+ left.forEach((child, index) => {
448
+ if (actual.children.find(edge => edge.node === child)?.field != expected.children.find(edge => edge.node === right[index])?.field)
449
+ this.fail(child, "modified Rust support field");
450
+ this.compareTree(child, right[index], canonical);
451
+ });
452
+ }
453
+ /**
454
+ * Resolves only already validated scalar expressions for scaffold checking.
455
+ * @param {Expression} expression - Resolved semantic expression.
456
+ * @param {Map<string, Scalar>} bindings - Lexical types.
457
+ * @returns {Scalar} Semantic result type.
458
+ */
459
+ expressionType(expression, bindings) {
460
+ if (expression.kind == "StringLiteral")
461
+ return "string";
462
+ if (expression.kind == "IntegerLiteral")
463
+ return "integer";
464
+ if (expression.kind == "BooleanLiteral")
465
+ return "boolean";
466
+ if (expression.kind == "BinaryExpression" || expression.kind == "UnaryExpression")
467
+ return expression.type;
468
+ if (expression.kind != "CallExpression" && expression.kind != "IdentifierExpression") {
469
+ throw new Error("Validated Rust source exposed a collection expression.");
470
+ }
471
+ const type = expression.kind == "CallExpression" ? this.functions.get(expression.callee) : bindings.get(expression.name);
472
+ if (!type)
473
+ throw new Error("Validated Rust expression lost its scalar binding.");
474
+ return type;
475
+ }
476
+ /**
477
+ * Checks clone, borrow and print constraints after shared operation resolution.
478
+ * @param {import("../semantic/types.js").Block} block - Resolved block.
479
+ * @param {Map<string, Scalar>} inherited - Enclosing types.
480
+ * @returns {void}
481
+ */
482
+ validateScalars(block, inherited) {
483
+ const bindings = new Map(inherited);
484
+ /**
485
+ * Checks each original clone and borrowed concatenation after scalar resolution.
486
+ * @param {Expression} expression - Current expression.
487
+ * @returns {void}
488
+ */
489
+ const visit = expression => {
490
+ const clone = this.clones.get(expression);
491
+ const addition = this.additions.get(expression);
492
+ if (clone && this.expressionType(expression, bindings) != "string")
493
+ this.fail(clone, "clone requires owned String");
494
+ if (addition && (this.expressionType(expression, bindings) == "string") != addition.borrowed)
495
+ this.fail(addition.node, "string concatenation requires exactly a borrowed String RHS");
496
+ if (expression.kind == "CallExpression")
497
+ expression.arguments.forEach(visit);
498
+ else if (expression.kind == "UnaryExpression")
499
+ visit(expression.operand);
500
+ else if (expression.kind == "BinaryExpression") {
501
+ visit(expression.left);
502
+ visit(expression.right);
503
+ }
504
+ };
505
+ for (const statement of block.statements) {
506
+ const expression = statement.kind == "IfStatement" ? statement.condition :
507
+ statement.kind == "LocalDeclaration" ? statement.initializer :
508
+ statement.kind == "AssignmentStatement" || statement.kind == "ExpressionStatement" || statement.kind == "PrintStatement" ? statement.expression :
509
+ statement.kind == "ReturnStatement" ? statement.expression : undefined;
510
+ if (!expression)
511
+ throw new Error("Validated Rust source contained a bare return.");
512
+ visit(expression);
513
+ if (statement.kind == "LocalDeclaration")
514
+ bindings.set(statement.name,
515
+ /** @type {import("../semantic/types.js").TypeReference} */ (statement.type).name);
516
+ if (statement.kind == "PrintStatement") {
517
+ const print = this.prints.get(statement);
518
+ if (!print)
519
+ throw new Error("Rust print lost its original helper identity.");
520
+ if (this.expressionType(expression, bindings) != print.type)
521
+ this.fail(print.node, "print helper scalar mismatch");
522
+ }
523
+ if (statement.kind == "IfStatement") {
524
+ this.validateScalars(statement.consequent, bindings);
525
+ if (statement.alternate)
526
+ this.validateScalars(statement.alternate, bindings);
527
+ }
528
+ }
529
+ }
530
+ /**
531
+ * Validates genuine source moves in evaluation order, retaining implicit comparison borrows.
532
+ * @param {Expression} expression - Original expression occurrence.
533
+ * @param {Map<string, Scalar>} bindings - Validated lexical types.
534
+ * @param {Set<string>} moved - Definitely or possibly consumed String bindings.
535
+ * @param {Set<string>} borrowed - Borrows held by enclosing operand evaluation.
536
+ * @param {"move" | "borrow"} [usage] - How this expression's result is consumed.
537
+ * @param {boolean} [applyClone] - Whether to apply this occurrence's checked clone wrapper.
538
+ * @returns {Set<string>} Place borrows held until the containing operation completes.
539
+ */
540
+ ownershipExpression(expression, bindings, moved, borrowed, usage = "move", applyClone = true) {
541
+ if (applyClone && this.clones.has(expression)) {
542
+ this.ownershipExpression(expression, bindings, moved, borrowed, "borrow", false);
543
+ return new Set();
544
+ }
545
+ if (expression.kind == "IdentifierExpression" && this.expressionType(expression, bindings) == "string") {
546
+ const name = expression.name;
547
+ if (moved.has(name))
548
+ unsupportedSyntax("rust", `use of moved String '${name}'`, expression.location);
549
+ if (usage == "borrow")
550
+ return new Set([name]);
551
+ if (borrowed.has(name))
552
+ unsupportedSyntax("rust", `cannot move borrowed String '${name}' during operand evaluation`, expression.location);
553
+ moved.add(name);
554
+ }
555
+ else if (expression.kind == "CallExpression") {
556
+ for (const argument of expression.arguments)
557
+ this.ownershipExpression(argument, bindings, moved, borrowed);
558
+ }
559
+ else if (expression.kind == "UnaryExpression")
560
+ this.ownershipExpression(expression.operand, bindings, moved, borrowed);
561
+ else if (expression.kind == "BinaryExpression") {
562
+ if (expression.operation == "StringEqual" || expression.operation == "StringNotEqual") {
563
+ const held = this.ownershipExpression(expression.left, bindings, moved, borrowed, "borrow");
564
+ this.ownershipExpression(expression.right, bindings, moved, new Set([...borrowed, ...held]), "borrow");
565
+ }
566
+ else {
567
+ this.ownershipExpression(expression.left, bindings, moved, borrowed);
568
+ if (expression.operation == "BooleanAnd" || expression.operation == "BooleanOr") {
569
+ const conditional = new Set(moved);
570
+ this.ownershipExpression(expression.right, bindings, conditional, borrowed);
571
+ for (const name of conditional)
572
+ moved.add(name);
573
+ }
574
+ else
575
+ this.ownershipExpression(expression.right, bindings, moved, borrowed, expression.operation == "StringConcat" ? "borrow" : "move");
576
+ }
577
+ }
578
+ return new Set();
579
+ }
580
+ /**
581
+ * Merges source availability only from paths that continue, restoring explicit assignments.
582
+ * @param {import("../semantic/types.js").Block} block - Original lexical block.
583
+ * @param {Map<string, Scalar>} inherited - Visible scalar bindings.
584
+ * @param {Set<string>} inheritedMoved - Incoming consumed bindings.
585
+ * @returns {{moved: Set<string>, returns: boolean}} Outgoing source availability and control flow.
586
+ */
587
+ validateOwnership(block, inherited, inheritedMoved) {
588
+ const bindings = new Map(inherited);
589
+ const moved = new Set(inheritedMoved);
590
+ for (const statement of block.statements) {
591
+ const expression = statement.kind == "IfStatement" ? statement.condition :
592
+ statement.kind == "LocalDeclaration" ? statement.initializer :
593
+ statement.kind == "AssignmentStatement" || statement.kind == "ExpressionStatement" || statement.kind == "PrintStatement" ? statement.expression :
594
+ statement.kind == "ReturnStatement" ? statement.expression : undefined;
595
+ if (!expression)
596
+ throw new Error("Validated Rust source contained a bare return.");
597
+ this.ownershipExpression(expression, bindings, moved, new Set());
598
+ if (statement.kind == "ReturnStatement")
599
+ return { moved, returns: true };
600
+ if (statement.kind == "LocalDeclaration")
601
+ bindings.set(statement.name,
602
+ /** @type {import("../semantic/types.js").TypeReference} */ (statement.type).name);
603
+ else if (statement.kind == "AssignmentStatement")
604
+ moved.delete(statement.target.name);
605
+ else if (statement.kind == "IfStatement") {
606
+ const consequent = this.validateOwnership(statement.consequent, bindings, moved);
607
+ const alternate = statement.alternate ? this.validateOwnership(statement.alternate, bindings, moved) : { moved: new Set(moved), returns: false };
608
+ if (consequent.returns && alternate.returns)
609
+ return { moved, returns: true };
610
+ moved.clear();
611
+ for (const path of [consequent, alternate]) {
612
+ if (!path.returns)
613
+ for (const name of path.moved)
614
+ if (bindings.has(name))
615
+ moved.add(name);
616
+ }
617
+ }
618
+ }
619
+ return { moved, returns: false };
620
+ }
621
+ /**
622
+ * Validates the complete crate and collapses only exact declared support.
623
+ * @param {CstNode} root - Complete root.
624
+ * @returns {import("../semantic/types.js").SemanticModule} Resolved semantics.
625
+ */
626
+ module(root) {
627
+ this.validateTree(root);
628
+ if (root.type != "source_file")
629
+ this.fail(root, "crate root required");
630
+ const canonical = new RustReader(this.filename, rustRuntime);
631
+ const support = canonical.parts(parseRustCst(rustRuntime).root);
632
+ const helpers = new Map(support.filter(node => node.type == "function_item").map(node => [canonical.text(canonical.field(node, "name")), node]));
633
+ /** @type {CstNode[]} */
634
+ const definitions = [];
635
+ let lint = false;
636
+ /** @type {CstNode | undefined} */
637
+ let main;
638
+ for (const node of this.parts(root)) {
639
+ if (node.type == "inner_attribute_item") {
640
+ if (lint || definitions.length || main || this.helpers.size)
641
+ this.fail(node, "misplaced Rust lint support");
642
+ this.compareTree(node, support[0], canonical);
643
+ lint = true;
644
+ continue;
645
+ }
646
+ if (node.type != "function_item")
647
+ this.fail(node, "crate-root free functions only");
648
+ const name = this.text(this.field(node, "name"));
649
+ const helper = helpers.get(name);
650
+ if (helper) {
651
+ if (this.helpers.has(name))
652
+ this.fail(node, "duplicate Rust helper");
653
+ this.compareTree(node, helper, canonical);
654
+ this.helpers.add(name);
655
+ }
656
+ else if (name == "main") {
657
+ if (main)
658
+ this.fail(node, "duplicate main");
659
+ main = node;
660
+ }
661
+ else
662
+ definitions.push(node);
663
+ }
664
+ if (!main)
665
+ this.fail(root, "canonical fn main() required");
666
+ if (!definitions.length)
667
+ this.fail(root, "semantic function required");
668
+ const name = this.field(main, "name");
669
+ const parameters = this.field(main, "parameters");
670
+ const body = this.field(main, "body");
671
+ this.shape(main, ["fn", name, parameters, body]);
672
+ this.shape(parameters, ["(", ")"]);
673
+ const module = validateParsedModule({ kind: "Module", location: this.location(root), functions: definitions.map(node => this.function(node)),
674
+ entryPoint: { kind: "EntryPoint", location: this.location(main), body: this.block(body) } }, "rust");
675
+ this.functions = new Map(module.functions.map(declaration => [
676
+ declaration.name,
677
+ /** @type {Scalar} */ ( /** @type {import("../semantic/types.js").TypeReference} */(declaration.returnType).name)
678
+ ]));
679
+ for (const declaration of module.functions) {
680
+ const bindings = new Map(declaration.parameters.map(parameter => [parameter.name,
681
+ /** @type {import("../semantic/types.js").TypeReference} */ (parameter.type).name]));
682
+ this.validateScalars(declaration.body, bindings);
683
+ this.validateOwnership(declaration.body, bindings, new Set());
684
+ }
685
+ this.validateScalars(module.entryPoint.body, new Map());
686
+ this.validateOwnership(module.entryPoint.body, new Map(), new Set());
687
+ return module;
688
+ }
689
+ }
690
+ /**
691
+ * Parses only the qualified frozen CST and rejects unsupported input before adaptation.
692
+ * @param {{filename: string, source: string}} input - Exact source request.
693
+ * @returns {import("../semantic/types.js").SemanticModule} Rust semantic module.
694
+ */
695
+ export function parseRust({ filename, source }) {
696
+ const coordinates = createCoordinateIndex(source);
697
+ const location = { filename, start: indexedPointAt(coordinates, 0), end: indexedPointAt(coordinates, source.length) };
698
+ if (!hasOnlyUnicodeScalars(source)) {
699
+ const offset = source.search(/[\uD800-\uDBFF](?![\uDC00-\uDFFF])|(?<![\uD800-\uDBFF])[\uDC00-\uDFFF]/u);
700
+ throw new SemantifoldDiagnostic({ code: "PARSE_ERROR", language: "rust", message: "Rust source contains a lone UTF-16 surrogate.",
701
+ location: { filename, start: indexedPointAt(coordinates, offset), end: indexedPointAt(coordinates, offset + 1) } });
702
+ }
703
+ if (source.length > maximumRustSourceLength)
704
+ return unsupportedSyntax("rust", "source exceeds the frozen Rust parser's 32767 UTF-16 input limit", location);
705
+ let snapshot;
706
+ try {
707
+ snapshot = parseRustCst(source);
708
+ }
709
+ catch (error) {
710
+ throw new SemantifoldDiagnostic({ code: "PARSE_ERROR", language: "rust", location,
711
+ cause: error instanceof Error ? error : undefined, message: "The qualified Rust parser could not produce a complete CST." });
712
+ }
713
+ return new RustReader(filename, source).module(snapshot.root);
714
+ }
715
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicnVzdC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9mcm9udGVuZHMvcnVzdC5qcyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxZQUFZO0FBRVosT0FBTyxFQUFDLFdBQVcsRUFBQyxNQUFNLDZCQUE2QixDQUFBO0FBQ3ZELE9BQU8sRUFBQyx1QkFBdUIsRUFBQyxNQUFNLGdDQUFnQyxDQUFBO0FBQ3RFLE9BQU8sRUFBQyxnQkFBZ0IsRUFBQyxNQUFNLDRCQUE0QixDQUFBO0FBQzNELE9BQU8sRUFBQyxXQUFXLEVBQUUscUJBQXFCLEVBQUUsaUJBQWlCLEVBQUMsTUFBTSxrQkFBa0IsQ0FBQTtBQUN0RixPQUFPLEVBQUMscUJBQXFCLEVBQUUsY0FBYyxFQUFDLE1BQU0seUJBQXlCLENBQUE7QUFDN0UsT0FBTyxFQUFDLG9CQUFvQixFQUFDLE1BQU0sMEJBQTBCLENBQUE7QUFDN0QsT0FBTyxFQUFDLGdCQUFnQixFQUFDLE1BQU0sMkJBQTJCLENBQUE7QUFDMUQsT0FBTyxFQUFDLHFCQUFxQixFQUFDLE1BQU0sd0JBQXdCLENBQUE7QUFDNUQsT0FBTyxFQUFDLG9CQUFvQixFQUFDLE1BQU0seUJBQXlCLENBQUE7QUFDNUQsT0FBTyxFQUFDLGdCQUFnQixFQUFDLE1BQU0sY0FBYyxDQUFBO0FBQzdDLE9BQU8sRUFBQyxZQUFZLEVBQUMsTUFBTSxrQkFBa0IsQ0FBQTtBQUU3Qyw0REFBNEQ7QUFDNUQsc0VBQXNFO0FBQ3RFLG9FQUFvRTtBQUNwRSx3RUFBd0U7QUFFeEUsTUFBTSxnQkFBZ0IsR0FBRyxJQUFJLEdBQUcsQ0FBQztJQUMvQixDQUFDLEdBQUcsRUFBRSxLQUFLLENBQUMsRUFBRSxDQUFDLEdBQUcsRUFBRSxVQUFVLENBQUMsRUFBRSxDQUFDLEdBQUcsRUFBRSxVQUFVLENBQUMsRUFBRSxDQUFDLElBQUksRUFBRSxPQUFPLENBQUMsRUFBRSxDQUFDLElBQUksRUFBRSxVQUFVLENBQUM7SUFDdkYsQ0FBQyxHQUFH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QyxFQUFDLElBQUksRUFBRSxhQUFhLEVBQUUsUUFBUSxFQUFFLE1BQU0sRUFBRSxRQUFRO1lBQzlFLEtBQUssRUFBRSxLQUFLLFlBQVksS0FBSyxDQUFDLENBQUMsQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLFNBQVMsRUFBRSxPQUFPLEVBQUUsNkRBQTZELEVBQUMsQ0FBQyxDQUFBO0lBQy9ILENBQUM7SUFDRCxPQUFPLElBQUksVUFBVSxDQUFDLFFBQVEsRUFBRSxNQUFNLENBQUMsQ0FBQyxNQUFNLENBQUMsUUFBUSxDQUFDLElBQUksQ0FBQyxDQUFBO0FBQy9ELENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyIvLyBAdHMtY2hlY2tcblxuaW1wb3J0IHtydXN0UnVudGltZX0gZnJvbSBcIi4uL2JhY2tlbmRzL3J1c3QtcnVudGltZS5qc1wiXG5pbXBvcnQge21heGltdW1SdXN0U291cmNlTGVuZ3RofSBmcm9tIFwiLi4vYmFja2VuZHMvcnVzdC12YWxpZGF0aW9uLmpzXCJcbmltcG9ydCB7aXNSdXN0SWRlbnRpZmllcn0gZnJvbSBcIi4uL2JhY2tlbmRzL2lkZW50aWZpZXJzLmpzXCJcbmltcG9ydCB7bWlzc2luZ1R5cGUsIFNlbWFudGlmb2xkRGlhZ25vc3RpYywgdW5zdXBwb3J0ZWRTeW50YXh9IGZyb20gXCIuLi9kaWFnbm9zdGljLmpzXCJcbmltcG9ydCB7Y3JlYXRlQ29vcmRpbmF0ZUluZGV4LCBpbmRleGVkUG9pbnRBdH0gZnJvbSBcIi4uL3NlbWFudGljL2xvY2F0aW9uLmpzXCJcbmltcG9ydCB7d2l0aEFkYXB0ZWRPcGVyYXRpb259IGZyb20gXCIuLi9zZW1hbnRpYy9vcGVyYXRvcnMuanNcIlxuaW1wb3J0IHt3aXRoUGFyc2VyUmFuZ2VzfSBmcm9tIFwiLi4vc2VtYW50aWMvcHJvdmVuYW5jZS5qc1wiXG5pbXBvcnQge2hhc09ubHlVbmljb2RlU2NhbGFyc30gZnJvbSBcIi4uL3NlbWFudGljL3NjYWxhcnMuanNcIlxuaW1wb3J0IHt2YWxpZGF0ZVBhcnNlZE1vZHVsZX0gZnJvbSBcIi4uL3NlbWFudGljL3ZhbGlkYXRlLmpzXCJcbmltcG9ydCB7c291cmNlU2NhbGFyVHlwZX0gZnJvbSBcIi4vc2NhbGFycy5qc1wiXG5pbXBvcnQge3BhcnNlUnVzdENzdH0gZnJvbSBcIi4vcnVzdC1wYXJzZXIuanNcIlxuXG4vKiogQHR5cGVkZWYge2ltcG9ydChcIi4vcnVzdC1wYXJzZXIuanNcIikuQ3N0Tm9kZX0gQ3N0Tm9kZSAqL1xuLyoqIEB0eXBlZGVmIHtpbXBvcnQoXCIuLi9zZW1hbnRpYy90eXBlcy5qc1wiKS5FeHByZXNzaW9ufSBFeHByZXNzaW9uICovXG4vKiogQHR5cGVkZWYge2ltcG9ydChcIi4uL3NlbWFudGljL3R5cGVzLmpzXCIpLlN0YXRlbWVudH0gU3RhdGVtZW50ICovXG4vKiogQHR5cGVkZWYge2ltcG9ydChcIi4uL3NlbWFudGljL3R5cGVzLmpzXCIpLlNlbWFudGljVHlwZU5hbWV9IFNjYWxhciAqL1xuXG5jb25zdCBiaW5hcnlPcGVyYXRpb25zID0gbmV3IE1hcChbXG4gIFtcIitcIiwgXCJBZGRcIl0sIFtcIi1cIiwgXCJTdWJ0cmFjdFwiXSwgW1wiKlwiLCBcIk11bHRpcGx5XCJdLCBbXCI9PVwiLCBcIkVxdWFsXCJdLCBbXCIhPVwiLCBcIk5vdEVxdWFsXCJdLFxuICBbXCI8XCIsIFwiTGVzc1RoYW5cIl0sIFtcIjw9XCIsIFwiTGVzc1RoYW5PckVxdWFsXCJdLCBbXCI+XCIsIFwiR3JlYXRlclRoYW5cIl0sIFtcIj49XCIsIFwiR3JlYXRlclRoYW5PckVxdWFsXCJdLFxuICBbXCImJlwiLCBcIkFuZFwiXSwgW1wifHxcIiwgXCJPclwiXVxuXSlcbmNvbnN0IGFyaXRobWV0aWNIZWxwZXJzID0gbmV3IE1hcChbXG4gIFtcInNlbWFudGlmb2xkX2ludGVnZXJfYWRkXCIsIFwiUGhwQWRkXCJdLCBbXCJzZW1hbnRpZm9sZF9pbnRlZ2VyX3N1YnRyYWN0XCIsIFwiU3VidHJhY3RcIl0sXG4gIFtcInNlbWFudGlmb2xkX2ludGVnZXJfbXVsdGlwbHlcIiwgXCJNdWx0aXBseVwiXVxuXSlcblxuLyoqIENvbnN1bWVzIGNvbXBsZXRlIFJ1c3QgQ1NUIHNoYXBlcyBhbmQgcmV0YWlucyBzb3VyY2Utb25seSBzY2FmZm9sZCBjb25zdHJhaW50cy4gKi9cbmNsYXNzIFJ1c3RSZWFkZXIge1xuICAvKipcbiAgICogT3ducyBzb3VyY2UgdGV4dCBhbmQgcGFyc2VyLW9yaWdpbiBtZXRhZGF0YSwgbmV2ZXIgbmF0aXZlIHBhcnNlciBoYW5kbGVzLlxuICAgKiBAcGFyYW0ge3N0cmluZ30gZmlsZW5hbWUgLSBPcmlnaW5hbCBmaWxlbmFtZS5cbiAgICogQHBhcmFtIHtzdHJpbmd9IHNvdXJjZSAtIEV4YWN0IHNvdXJjZS5cbiAgICovXG4gIGNvbnN0cnVjdG9yKGZpbGVuYW1lLCBzb3VyY2UpIHtcbiAgICB0aGlzLmZpbGVuYW1lID0gZmlsZW5hbWVcbiAgICB0aGlzLnNvdXJjZSA9IHNvdXJjZVxuICAgIHRoaXMuY29vcmRpbmF0ZXMgPSBjcmVhdGVDb29yZGluYXRlSW5kZXgoc291cmNlKVxuICAgIC8qKiBAdHlwZSB7U2V0PHN0cmluZz59ICovXG4gICAgdGhpcy5oZWxwZXJzID0gbmV3IFNldCgpXG4gICAgLyoqIEB0eXBlIHtNYXA8RXhwcmVzc2lvbiwgQ3N0Tm9kZT59ICovXG4gICAgdGhpcy5jbG9uZXMgPSBuZXcgTWFwKClcbiAgICAvKiogQHR5cGUge01hcDxFeHByZXNzaW9uLCB7Ym9ycm93ZWQ6IGJvb2xlYW4sIG5vZGU6IENzdE5vZGV9Pn0gKi9cbiAgICB0aGlzLmFkZGl0aW9ucyA9IG5ldyBNYXAoKVxuICAgIC8qKiBAdHlwZSB7TWFwPFN0YXRlbWVudCwge3R5cGU6IHN0cmluZywgbm9kZTogQ3N0Tm9kZX0+fSAqL1xuICAgIHRoaXMucHJpbnRzID0gbmV3IE1hcCgpXG4gICAgLyoqIEB0eXBlIHtNYXA8c3RyaW5nLCBTY2FsYXI+fSAqL1xuICAgIHRoaXMuZnVuY3Rpb25zID0gbmV3IE1hcCgpXG4gIH1cblxuICAvKipcbiAgICogTG9jYXRlcyBhbiBvcmlnaW5hbCBwYXJzZXIgbm9kZSBpbiBVVEYtMTYgY29vcmRpbmF0ZXMuXG4gICAqIEBwYXJhbSB7Q3N0Tm9kZX0gbm9kZSAtIE9yaWdpbmFsIG5vZGUuXG4gICAqIEByZXR1cm5zIHtpbXBvcnQoXCIuLi9zZW1hbnRpYy90eXBlcy5qc1wiKS5Tb3VyY2VMb2NhdGlvbn0gRXhhY3QgbG9jYXRpb24uXG4gICAqL1xuICBsb2NhdGlvbihub2RlKSB7XG4gICAgcmV0dXJuIHtmaWxlbmFtZTogdGhpcy5maWxlbmFtZSwgc3RhcnQ6IGluZGV4ZWRQb2ludEF0KHRoaXMuY29vcmRpbmF0ZXMsIG5vZGUuc3RhcnRJbmRleCksIGVuZDogaW5kZXhlZFBvaW50QXQodGhpcy5jb29yZGluYXRlcywgbm9kZS5lbmRJbmRleCl9XG4gIH1cblxuICAvKipcbiAgICogUmVhZHMgdGhlIHNwZWxsaW5nIG9mIGFuIGFscmVhZHkgcmVjb2duaXplZCBwYXJzZXIgbm9kZS5cbiAgICogQHBhcmFtIHtDc3ROb2RlfSBub2RlIC0gUmVjb2duaXplZCBub2RlLlxuICAgKiBAcmV0dXJucyB7c3RyaW5nfSBPcmlnaW5hbCBzcGVsbGluZy5cbiAgICovXG4gIHRleHQobm9kZSkge1xuICAgIHJldHVybiB0aGlzLnNvdXJjZS5zbGljZShub2RlLnN0YXJ0SW5kZXgsIG5vZGUuZW5kSW5kZXgpXG4gIH1cblxuICAvKipcbiAgICogUmVqZWN0cyBvbmUgbG9jYXRlZCBzb3VyY2UtcHJvZmlsZSB2aW9sYXRpb24uXG4gICAqIEBwYXJhbSB7Q3N0Tm9kZX0gbm9kZSAtIFZpb2xhdGluZyBub2RlLlxuICAgKiBAcGFyYW0ge3N0cmluZ30gW2RldGFpbF0gLSBQcm9maWxlIGRldGFpbC5cbiAgICogQHJldHVybnMge25ldmVyfSBBbHdheXMgdGhyb3dzLlxuICAgKi9cbiAgZmFpbChub2RlLCBkZXRhaWwgPSBub2RlLnR5cGUpIHtcbiAgICB1bnN1cHBvcnRlZFN5bnRheChcInJ1c3RcIiwgZGV0YWlsLCB0aGlzLmxvY2F0aW9uKG5vZGUpKVxuICB9XG5cbiAgLyoqXG4gICAqIEFjY291bnRzIGZvciByZWNvdmVyeSwgZXZlcnkgZXh0cmEsIGFuZCBkb2MgY29tbWVudHMgYmVmb3JlIGludGVycHJldGluZyBtZWFuaW5nLlxuICAgKiBAcGFyYW0ge0NzdE5vZGV9IG5vZGUgLSBDdXJyZW50IG5vZGUuXG4gICAqIEBwYXJhbSB7bnVtYmVyfSBbZGVwdGhdIC0gQm91bmRlZCB0cmF2ZXJzYWwgZGVwdGguXG4gICAqIEByZXR1cm5zIHt2b2lkfVxuICAgKi9cbiAgdmFsaWRhdGVUcmVlKG5vZGUsIGRlcHRoID0gMCkge1xuICAgIGlmIChkZXB0aCA+IDUxMikgdGhpcy5mYWlsKG5vZGUsIFwiUnVzdCBDU1QgZXhjZWVkcyB0aGUgNTEyLWxldmVsIHRyYXZlcnNhbCBsaW1pdFwiKVxuICAgIGZvciAoY29uc3Qge25vZGU6IGNoaWxkfSBvZiBub2RlLmNoaWxkcmVuKSB0aGlzLnZhbGlkYXRlVHJlZShjaGlsZCwgZGVwdGggKyAxKVxuICAgIGlmIChub2RlLmVycm9yIHx8IG5vZGUubWlzc2luZyB8fCBub2RlLmhhc0Vycm9yKSB7XG4gICAgICB0aHJvdyBuZXcgU2VtYW50aWZvbGREaWFnbm9zdGljKHtjb2RlOiBcIlBBUlNFX0VSUk9SXCIsIGxhbmd1YWdlOiBcInJ1c3RcIiwgbG9jYXRpb246IHRoaXMubG9jYXRpb24obm9kZSksIG1lc3NhZ2U6IGBSdXN0IHBhcnNlciByZWNvdmVyeSBhdCAnJHtub2RlLnR5cGV9Jy5gfSlcbiAgICB9XG4gICAgaWYgKG5vZGUuZXh0cmEgJiYgIVtcImxpbmVfY29tbWVudFwiLCBcImJsb2NrX2NvbW1lbnRcIl0uaW5jbHVkZXMobm9kZS50eXBlKSkgdGhpcy5mYWlsKG5vZGUsIFwidW5leHBlY3RlZCBleHRyYSBwYXJzZXIgY2hpbGRcIilcbiAgICBpZiAoW1wibGluZV9jb21tZW50XCIsIFwiYmxvY2tfY29tbWVudFwiXS5pbmNsdWRlcyhub2RlLnR5cGUpICYmIC9eKD86XFwvXFwvWyEvXXxcXC9cXCpbKiFdKS91LnRlc3QodGhpcy50ZXh0KG5vZGUpKSkge1xuICAgICAgdGhpcy5mYWlsKG5vZGUsIFwiZG9jLWNvbW1lbnQgYXR0cmlidXRlXCIpXG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIE9taXRzIG9ubHkgaW5lcnQgY29tbWVudHMgYWxyZWFkeSBjaGVja2VkIGR1cmluZyBleGhhdXN0aXZlIHRyYXZlcnNhbC5cbiAgICogQHBhcmFtIHtDc3ROb2RlfSBub2RlIC0gUGFyZW50LlxuICAgKiBAcmV0dXJucyB7Q3N0Tm9kZVtdfSBPcmRlcmVkIHN0cnVjdHVyYWwgY2hpbGRyZW4uXG4gICAqL1xuICBwYXJ0cyhub2RlKSB7XG4gICAgcmV0dXJuIG5vZGUuY2hpbGRyZW4ubWFwKCh7bm9kZTogY2hpbGR9KSA9PiBjaGlsZCkuZmlsdGVyKGNoaWxkID0+ICFbXCJsaW5lX2NvbW1lbnRcIiwgXCJibG9ja19jb21tZW50XCJdLmluY2x1ZGVzKGNoaWxkLnR5cGUpKVxuICB9XG5cbiAgLyoqXG4gICAqIFJlcXVpcmVzIGFuIGV4YWN0IHNvbGUgcGFyc2VyIGZpZWxkLlxuICAgKiBAcGFyYW0ge0NzdE5vZGV9IG5vZGUgLSBGaWVsZCBvd25lci5cbiAgICogQHBhcmFtIHtzdHJpbmd9IG5hbWUgLSBGaWVsZCBuYW1lLlxuICAgKiBAcmV0dXJucyB7Q3N0Tm9kZX0gU29sZSBmaWVsZCB2YWx1ZS5cbiAgICovXG4gIGZpZWxkKG5vZGUsIG5hbWUpIHtcbiAgICBjb25zdCBlZGdlcyA9IG5vZGUuY2hpbGRyZW4uZmlsdGVyKCh7ZmllbGR9KSA9PiBmaWVsZCA9PSBuYW1lKVxuXG4gICAgaWYgKGVkZ2VzLmxlbmd0aCAhPSAxKSB0aGlzLmZhaWwobm9kZSwgYGV4cGVjdGVkIG9uZSAnJHtuYW1lfScgZmllbGRgKVxuICAgIHJldHVybiBlZGdlc1swXS5ub2RlXG4gIH1cblxuICAvKipcbiAgICogUmVxdWlyZXMgYWxsIG9yZGVyZWQgY2hpbGRyZW4sIGluY2x1ZGluZyBhbm9ueW1vdXMgcHVuY3R1YXRpb24uXG4gICAqIEBwYXJhbSB7Q3N0Tm9kZX0gbm9kZSAtIFNoYXBlIG93bmVyLlxuICAgKiBAcGFyYW0geyhDc3ROb2RlIHwgc3RyaW5nKVtdfSBleHBlY3RlZCAtIEV4YWN0IGNoaWxkIHNlcXVlbmNlLlxuICAgKiBAcmV0dXJucyB7dm9pZH1cbiAgICovXG4gIHNoYXBlKG5vZGUsIGV4cGVjdGVkKSB7XG4gICAgY29uc3QgcGFydHMgPSB0aGlzLnBhcnRzKG5vZGUpXG5cbiAgICBpZiAocGFydHMubGVuZ3RoICE9IGV4cGVjdGVkLmxlbmd0aCB8fCBwYXJ0cy5zb21lKChjaGlsZCwgaW5kZXgpID0+XG4gICAgICB0eXBlb2YgZXhwZWN0ZWRbaW5kZXhdID09IFwic3RyaW5nXCIgPyBjaGlsZC50eXBlICE9IGV4cGVjdGVkW2luZGV4XSB8fCAhY2hpbGQubmFtZWQgJiYgdGhpcy50ZXh0KGNoaWxkKSAhPSBleHBlY3RlZFtpbmRleF0gOiBjaGlsZCAhPT0gZXhwZWN0ZWRbaW5kZXhdKSkgdGhpcy5mYWlsKG5vZGUsIGAke25vZGUudHlwZX0gY2hpbGQgc2hhcGVgKVxuICB9XG5cbiAgLyoqXG4gICAqIFByb3RlY3RzIFJ1c3Qga2V5d29yZHMgYW5kIHRoZSBwcml2YXRlIHN1cHBvcnQgbmFtZXNwYWNlLlxuICAgKiBAcGFyYW0ge0NzdE5vZGV9IG5vZGUgLSBJZGVudGlmaWVyIHRva2VuLlxuICAgKiBAcmV0dXJucyB7c3RyaW5nfSBWYWxpZGF0ZWQgbmFtZS5cbiAgICovXG4gIGlkZW50aWZpZXIobm9kZSkge1xuICAgIGNvbnN0IG5hbWUgPSB0aGlzLnRleHQobm9kZSlcblxuICAgIGlmIChub2RlLnR5cGUgIT0gXCJpZGVudGlmaWVyXCIgfHwgIWlzUnVzdElkZW50aWZpZXIobmFtZSkpIHRoaXMuZmFpbChub2RlLCBcInJlc2VydmVkIG9yIHVuc3VwcG9ydGVkIGlkZW50aWZpZXJcIilcbiAgICByZXR1cm4gbmFtZVxuICB9XG5cbiAgLyoqXG4gICAqIEFjY2VwdHMgb25seSBleHBsaWNpdGx5IHNwZWxsZWQgaTY0LCBib29sIGFuZCBvd25lZCBTdHJpbmcuXG4gICAqIEBwYXJhbSB7Q3N0Tm9kZX0gbm9kZSAtIFR5cGUgdG9rZW4uXG4gICAqIEByZXR1cm5zIHtpbXBvcnQoXCIuLi9zZW1hbnRpYy90eXBlcy5qc1wiKS5UeXBlUmVmZXJlbmNlfSBTZW1hbnRpYyBzY2FsYXIgdHlwZS5cbiAgICovXG4gIHR5cGUobm9kZSkge1xuICAgIGlmIChub2RlLmNoaWxkcmVuLmxlbmd0aCB8fCAhW1wicHJpbWl0aXZlX3R5cGVcIiwgXCJ0eXBlX2lkZW50aWZpZXJcIl0uaW5jbHVkZXMobm9kZS50eXBlKSkgdGhpcy5mYWlsKG5vZGUsIFwic2NhbGFyIHR5cGUgc2hhcGVcIilcbiAgICBjb25zdCBzcGVsbGluZyA9IHRoaXMudGV4dChub2RlKVxuICAgIGNvbnN0IHR5cGUgPSBzb3VyY2VTY2FsYXJUeXBlKFwicnVzdFwiLCBzcGVsbGluZywgdGhpcy5sb2NhdGlvbihub2RlKSlcblxuICAgIGlmICghdHlwZSkgcmV0dXJuIG1pc3NpbmdUeXBlKFwicnVzdFwiLCBcInNjYWxhclwiLCB0aGlzLmxvY2F0aW9uKG5vZGUpKVxuICAgIGlmICgoc3BlbGxpbmcgPT0gXCJTdHJpbmdcIikgIT0gKG5vZGUudHlwZSA9PSBcInR5cGVfaWRlbnRpZmllclwiKSkgdGhpcy5mYWlsKG5vZGUsIFwic2NhbGFyIHR5cGUgc3BlbGxpbmdcIilcbiAgICByZXR1cm4gdHlwZVxuICB9XG5cbiAgLyoqXG4gICAqIENvbnZlcnRzIGV4YWN0IGNhbGwgc3ludGF4IHdpdGhvdXQgaW50ZXJwcmV0aW5nIG1hY3JvIHRva2VuIHRyZWVzIGFzIGNhbGxzLlxuICAgKiBAcGFyYW0ge0NzdE5vZGV9IG5vZGUgLSBDYWxsIGV4cHJlc3Npb24uXG4gICAqIEByZXR1cm5zIHt7bmFtZTogQ3N0Tm9kZSwgYXJndW1lbnRzOiBDc3ROb2RlW119fSBQYXJzZWQgZGlyZWN0IGFyZ3VtZW50IHNlcXVlbmNlLlxuICAgKi9cbiAgY2FsbChub2RlKSB7XG4gICAgaWYgKG5vZGUudHlwZSAhPSBcImNhbGxfZXhwcmVzc2lvblwiKSB0aGlzLmZhaWwobm9kZSwgXCJkaXJlY3QgY2FsbCByZXF1aXJlZFwiKVxuICAgIGNvbnN0IG5hbWUgPSB0aGlzLmZpZWxkKG5vZGUsIFwiZnVuY3Rpb25cIilcbiAgICBjb25zdCBsaXN0ID0gdGhpcy5maWVsZChub2RlLCBcImFyZ3VtZW50c1wiKVxuXG4gICAgdGhpcy5zaGFwZShub2RlLCBbbmFtZSwgbGlzdF0pXG4gICAgaWYgKGxpc3QudHlwZSAhPSBcImFyZ3VtZW50c1wiKSB0aGlzLmZhaWwobGlzdCwgXCJjYWxsIGFyZ3VtZW50c1wiKVxuICAgIGNvbnN0IGFyZ3MgPSB0aGlzLnBhcnRzKGxpc3QpLnNsaWNlKDEsIC0xKS5maWx0ZXIoKF9wYXJ0LCBpbmRleCkgPT4gaW5kZXggJSAyID09IDApXG5cbiAgICB0aGlzLnNoYXBlKGxpc3QsIFtcIihcIiwgLi4uYXJncy5mbGF0TWFwKChhcmcsIGluZGV4KSA9PiBpbmRleCA9PSAwID8gW2FyZ10gOiBbXCIsXCIsIGFyZ10pLCBcIilcIl0pXG4gICAgcmV0dXJuIHthcmd1bWVudHM6IGFyZ3MsIG5hbWV9XG4gIH1cblxuICAvKipcbiAgICogRGVjb2RlcyBwYXJzZXItb3duZWQgb3JkaW5hcnkgc3RyaW5nIGNvbnRlbnQgYW5kIGV4YWN0IHNjYWxhciBlc2NhcGVzLlxuICAgKiBAcGFyYW0ge0NzdE5vZGV9IG5vZGUgLSBTdHJpbmcgbGl0ZXJhbC5cbiAgICogQHJldHVybnMge3N0cmluZ30gVW5pY29kZSBzY2FsYXIgdmFsdWUuXG4gICAqL1xuICBzdHJpbmcobm9kZSkge1xuICAgIGlmIChub2RlLnR5cGUgIT0gXCJzdHJpbmdfbGl0ZXJhbFwiKSB0aGlzLmZhaWwobm9kZSwgXCJvcmRpbmFyeSBTdHJpbmcgbGl0ZXJhbCByZXF1aXJlZFwiKVxuICAgIGNvbnN0IHBhcnRzID0gdGhpcy5wYXJ0cyhub2RlKVxuXG4gICAgdGhpcy5zaGFwZShub2RlLCBbJ1wiJywgLi4ucGFydHMuc2xpY2UoMSwgLTEpLCAnXCInXSlcbiAgICBsZXQgdmFsdWUgPSBcIlwiXG5cbiAgICBmb3IgKGNvbnN0IHBhcnQgb2YgcGFydHMuc2xpY2UoMSwgLTEpKSB7XG4gICAgICBjb25zdCBzcGVsbGluZyA9IHRoaXMudGV4dChwYXJ0KVxuXG4gICAgICBpZiAocGFydC50eXBlID09IFwic3RyaW5nX2NvbnRlbnRcIikge1xuICAgICAgICBpZiAoL1tcXHJcXG5dL3UudGVzdChzcGVsbGluZykpIHRoaXMuZmFpbChwYXJ0LCBcInJhdyBzdHJpbmcgbGluZSB0ZXJtaW5hdG9yXCIpXG4gICAgICAgIHZhbHVlICs9IHNwZWxsaW5nXG4gICAgICB9IGVsc2UgaWYgKHBhcnQudHlwZSA9PSBcImVzY2FwZV9zZXF1ZW5jZVwiKSB7XG4gICAgICAgIGNvbnN0IGVzY2FwZSA9IHNwZWxsaW5nLnNsaWNlKDEpXG4gICAgICAgIGNvbnN0IHNpbXBsZSA9IG5ldyBNYXAoW1tcIjBcIiwgXCJcXDBcIl0sIFtcIm5cIiwgXCJcXG5cIl0sIFtcInJcIiwgXCJcXHJcIl0sIFtcInRcIiwgXCJcXHRcIl0sIFtcIlxcXFxcIiwgXCJcXFxcXCJdLCBbJ1wiJywgJ1wiJ10sIFtcIidcIiwgXCInXCJdXSlcblxuICAgICAgICBpZiAoc3BlbGxpbmdbMF0gIT0gXCJcXFxcXCIpIHRoaXMuZmFpbChwYXJ0LCBcImVzY2FwZSBwcmVmaXhcIilcbiAgICAgICAgaWYgKHNpbXBsZS5oYXMoZXNjYXBlKSkgdmFsdWUgKz0gc2ltcGxlLmdldChlc2NhcGUpXG4gICAgICAgIGVsc2UgaWYgKC9eeFswLTlhLWZBLUZdezJ9JC91LnRlc3QoZXNjYXBlKSkge1xuICAgICAgICAgIGNvbnN0IHNjYWxhciA9IE51bWJlci5wYXJzZUludChlc2NhcGUuc2xpY2UoMSksIDE2KVxuXG4gICAgICAgICAgaWYgKHNjYWxhciA+IDEyNykgdGhpcy5mYWlsKHBhcnQsIFwibm9uLUFTQ0lJIGJ5dGUgZXNjYXBlXCIpXG4gICAgICAgICAgdmFsdWUgKz0gU3RyaW5nLmZyb21Db2RlUG9pbnQoc2NhbGFyKVxuICAgICAgICB9IGVsc2UgaWYgKC9edVxce1swLTlhLWZBLUZdezEsNn1cXH0kL3UudGVzdChlc2NhcGUpKSB7XG4gICAgICAgICAgY29uc3Qgc2NhbGFyID0gTnVtYmVyLnBhcnNlSW50KGVzY2FwZS5zbGljZSgyLCAtMSksIDE2KVxuXG4gICAgICAgICAgaWYgKHNjYWxhciA+IDB4MTBGRkZGIHx8IHNjYWxhciA+PSAweEQ4MDAgJiYgc2NhbGFyIDw9IDB4REZGRikgdGhpcy5mYWlsKHBhcnQsIFwibm9uLXNjYWxhciBVbmljb2RlIGVzY2FwZVwiKVxuICAgICAgICAgIHZhbHVlICs9IFN0cmluZy5mcm9tQ29kZVBvaW50KHNjYWxhcilcbiAgICAgICAgfSBlbHNlIHRoaXMuZmFpbChwYXJ0LCBcInVuc3VwcG9ydGVkIHN0cmluZyBlc2NhcGVcIilcbiAgICAgIH0gZWxzZSB0aGlzLmZhaWwocGFydCwgXCJzdHJpbmcgY2hpbGRcIilcbiAgICB9XG4gICAgcmV0dXJuIHZhbHVlXG4gIH1cblxuICAvKipcbiAgICogQ29udmVydHMgZXhhY3Qgc2NhbGFyIGV4cHJlc3Npb25zIHdoaWxlIHJldGFpbmluZyBzb3VyY2UgY2xvbmUvYm9ycm93IGNvbnN0cmFpbnRzLlxuICAgKiBAcGFyYW0ge0NzdE5vZGV9IG5vZGUgLSBFeHByZXNzaW9uIG5vZGUuXG4gICAqIEByZXR1cm5zIHtFeHByZXNzaW9ufSBQZW5kaW5nIHR5cGVkIHNlbWFudGljIGV4cHJlc3Npb24uXG4gICAqL1xuICBleHByZXNzaW9uKG5vZGUpIHtcbiAgICBjb25zdCBsb2NhdGlvbiA9IHRoaXMubG9jYXRpb24obm9kZSlcblxuICAgIGlmIChub2RlLnR5cGUgPT0gXCJwYXJlbnRoZXNpemVkX2V4cHJlc3Npb25cIikge1xuICAgICAgY29uc3QgcGFydHMgPSB0aGlzLnBhcnRzKG5vZGUpXG5cbiAgICAgIHRoaXMuc2hhcGUobm9kZSwgW1wiKFwiLCBwYXJ0c1sxXSwgXCIpXCJdKVxuICAgICAgcmV0dXJuIHRoaXMuZXhwcmVzc2lvbihwYXJ0c1sxXSlcbiAgICB9XG4gICAgaWYgKG5vZGUudHlwZSA9PSBcImlkZW50aWZpZXJcIikgcmV0dXJuIHdpdGhQYXJzZXJSYW5nZXMoe2tpbmQ6IFwiSWRlbnRpZmllckV4cHJlc3Npb25cIiwgbG9jYXRpb24sIG5hbWU6IHRoaXMuaWRlbnRpZmllcihub2RlKX0sIHtuYW1lOiBsb2NhdGlvbn0pXG4gICAgaWYgKG5vZGUudHlwZSA9PSBcImludGVnZXJfbGl0ZXJhbFwiKSB7XG4gICAgICBjb25zdCBzcGVsbGluZyA9IHRoaXMudGV4dChub2RlKVxuICAgICAgY29uc3QgdmFsdWUgPSBOdW1iZXIoc3BlbGxpbmcuc2xpY2UoMCwgLTMpKVxuXG4gICAgICBpZiAoIS9eKD86MHxbMS05XVswLTldKilpNjQkL3UudGVzdChzcGVsbGluZykgfHwgIU51bWJlci5pc1NhZmVJbnRlZ2VyKHZhbHVlKSkgdGhpcy5mYWlsKG5vZGUsIFwibm9uLXNhZmUgb3Igbm9uY2Fub25pY2FsIGk2NCBsaXRlcmFsXCIpXG4gICAgICByZXR1cm4gd2l0aFBhcnNlclJhbmdlcyh7a2luZDogXCJJbnRlZ2VyTGl0ZXJhbFwiLCBsb2NhdGlvbiwgdmFsdWV9LCB7bGl0ZXJhbDogbG9jYXRpb259KVxuICAgIH1cbiAgICBpZiAobm9kZS50eXBlID09IFwiYm9vbGVhbl9saXRlcmFsXCIpIHtcbiAgICAgIGNvbnN0IHNwZWxsaW5nID0gdGhpcy50ZXh0KG5vZGUpXG5cbiAgICAgIGlmIChzcGVsbGluZyAhPSBcInRydWVcIiAmJiBzcGVsbGluZyAhPSBcImZhbHNlXCIpIHRoaXMuZmFpbChub2RlLCBcIkJvb2xlYW4gbGl0ZXJhbCBzcGVsbGluZ1wiKVxuICAgICAgdGhpcy5zaGFwZShub2RlLCBbc3BlbGxpbmddKVxuICAgICAgcmV0dXJuIHdpdGhQYXJzZXJSYW5nZXMoe2tpbmQ6IFwiQm9vbGVhbkxpdGVyYWxcIiwgbG9jYXRpb24sIHZhbHVlOiBzcGVsbGluZyA9PSBcInRydWVcIn0sIHtsaXRlcmFsOiBsb2NhdGlvbn0pXG4gICAgfVxuICAgIGlmIChub2RlLnR5cGUgPT0gXCJ1bmFyeV9leHByZXNzaW9uXCIpIHtcbiAgICAgIGNvbnN0IHBhcnRzID0gdGhpcy5wYXJ0cyhub2RlKVxuXG4gICAgICB0aGlzLnNoYXBlKG5vZGUsIFtwYXJ0c1swXSwgcGFydHNbMV1dKVxuICAgICAgaWYgKCFbXCItXCIsIFwiIVwiXS5pbmNsdWRlcyhwYXJ0c1swXS50eXBlKSkgdGhpcy5mYWlsKHBhcnRzWzBdLCBcInVuYXJ5IG9wZXJhdG9yXCIpXG4gICAgICByZXR1cm4gdGhpcy51bmFyeShub2RlLCBwYXJ0c1swXS50eXBlID09IFwiLVwiID8gXCJOZWdhdGVcIiA6IFwiTm90XCIsIHRoaXMuZXhwcmVzc2lvbihwYXJ0c1sxXSksIHBhcnRzWzBdKVxuICAgIH1cbiAgICBpZiAobm9kZS50eXBlID09IFwiYmluYXJ5X2V4cHJlc3Npb25cIikge1xuICAgICAgY29uc3QgbGVmdCA9IHRoaXMuZmllbGQobm9kZSwgXCJsZWZ0XCIpXG4gICAgICBjb25zdCByaWdodCA9IHRoaXMuZmllbGQobm9kZSwgXCJyaWdodFwiKVxuICAgICAgY29uc3Qgb3BlcmF0b3IgPSB0aGlzLmZpZWxkKG5vZGUsIFwib3BlcmF0b3JcIilcbiAgICAgIGNvbnN0IGludGVudCA9IGJpbmFyeU9wZXJhdGlvbnMuZ2V0KG9wZXJhdG9yLnR5cGUpXG5cbiAgICAgIHRoaXMuc2hhcGUobm9kZSwgW2xlZnQsIG9wZXJhdG9yLCByaWdodF0pXG4gICAgICBpZiAoIWludGVudCkgdGhpcy5mYWlsKG9wZXJhdG9yLCBcInVuc3VwcG9ydGVkIGJpbmFyeSBvcGVyYXRvclwiKVxuICAgICAgY29uc3QgYm9ycm93ZWQgPSBvcGVyYXRvci50eXBlID09IFwiK1wiICYmIHJpZ2h0LnR5cGUgPT0gXCJyZWZlcmVuY2VfZXhwcmVzc2lvblwiXG4gICAgICBjb25zdCB2YWx1ZSA9IGJvcnJvd2VkID8gdGhpcy5maWVsZChyaWdodCwgXCJ2YWx1ZVwiKSA6IHJpZ2h0XG5cbiAgICAgIGlmIChib3Jyb3dlZCkgdGhpcy5zaGFwZShyaWdodCwgW1wiJlwiLCB2YWx1ZV0pXG4gICAgICBjb25zdCBleHByZXNzaW9uID0gdGhpcy5iaW5hcnkobm9kZSwgaW50ZW50LCB0aGlzLmV4cHJlc3Npb24obGVmdCksIHRoaXMuZXhwcmVzc2lvbih2YWx1ZSksIG9wZXJhdG9yKVxuXG4gICAgICBpZiAob3BlcmF0b3IudHlwZSA9PSBcIitcIikgdGhpcy5hZGRpdGlvbnMuc2V0KGV4cHJlc3Npb24sIHtib3Jyb3dlZCwgbm9kZTogcmlnaHR9KVxuICAgICAgcmV0dXJuIGV4cHJlc3Npb25cbiAgICB9XG4gICAgaWYgKG5vZGUudHlwZSA9PSBcImNhbGxfZXhwcmVzc2lvblwiKSB7XG4gICAgICBjb25zdCBjYWxsID0gdGhpcy5jYWxsKG5vZGUpXG4gICAgICBjb25zdCBuYW1lID0gdGhpcy50ZXh0KGNhbGwubmFtZSlcblxuICAgICAgaWYgKGNhbGwubmFtZS50eXBlID09IFwic2NvcGVkX2lkZW50aWZpZXJcIikge1xuICAgICAgICBjb25zdCBvd25lciA9IHRoaXMuZmllbGQoY2FsbC5uYW1lLCBcInBhdGhcIilcbiAgICAgICAgY29uc3QgbWV0aG9kID0gdGhpcy5maWVsZChjYWxsLm5hbWUsIFwibmFtZVwiKVxuXG4gICAgICAgIHRoaXMuc2hhcGUoY2FsbC5uYW1lLCBbb3duZXIsIFwiOjpcIiwgbWV0aG9kXSlcbiAgICAgICAgaWYgKG93bmVyLnR5cGUgIT0gXCJpZGVudGlmaWVyXCIgfHwgdGhpcy50ZXh0KG93bmVyKSAhPSBcIlN0cmluZ1wiIHx8IG1ldGhvZC50eXBlICE9IFwiaWRlbnRpZmllclwiIHx8IHRoaXMudGV4dChtZXRob2QpICE9IFwiZnJvbVwiIHx8IGNhbGwuYXJndW1lbnRzLmxlbmd0aCAhPSAxKSB7XG4gICAgICAgICAgdGhpcy5mYWlsKGNhbGwubmFtZSwgXCJleGFjdCBTdHJpbmc6OmZyb20gY29uc3RydWN0aW9uIHJlcXVpcmVkXCIpXG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHdpdGhQYXJzZXJSYW5nZXMoe2tpbmQ6IFwiU3RyaW5nTGl0ZXJhbFwiLCBsb2NhdGlvbiwgdmFsdWU6IHRoaXMuc3RyaW5nKGNhbGwuYXJndW1lbnRzWzBdKX0sIHtsaXRlcmFsOiB0aGlzLmxvY2F0aW9uKGNhbGwuYXJndW1lbnRzWzBdKX0pXG4gICAgICB9XG4gICAgICBpZiAoY2FsbC5uYW1lLnR5cGUgPT0gXCJmaWVsZF9leHByZXNzaW9uXCIpIHtcbiAgICAgICAgY29uc3QgcmVjZWl2ZXIgPSB0aGlzLmZpZWxkKGNhbGwubmFtZSwgXCJ2YWx1ZVwiKVxuICAgICAgICBjb25zdCBtZXRob2QgPSB0aGlzLmZpZWxkKGNhbGwubmFtZSwgXCJmaWVsZFwiKVxuXG4gICAgICAgIHRoaXMuc2hhcGUoY2FsbC5uYW1lLCBbcmVjZWl2ZXIsIFwiLlwiLCBtZXRob2RdKVxuICAgICAgICBpZiAobWV0aG9kLnR5cGUgIT0gXCJmaWVsZF9pZGVudGlmaWVyXCIgfHwgdGhpcy50ZXh0KG1ldGhvZCkgIT0gXCJjbG9uZVwiIHx8IGNhbGwuYXJndW1lbnRzLmxlbmd0aCkgdGhpcy5mYWlsKGNhbGwubmFtZSwgXCJleGFjdCBvd25lZCBTdHJpbmcgY2xvbmUgcmVxdWlyZWRcIilcbiAgICAgICAgY29uc3QgZXhwcmVzc2lvbiA9IHRoaXMuZXhwcmVzc2lvbihyZWNlaXZlcilcblxuICAgICAgICB0aGlzLmNsb25lcy5zZXQoZXhwcmVzc2lvbiwgY2FsbC5uYW1lKVxuICAgICAgICByZXR1cm4gZXhwcmVzc2lvblxuICAgICAgfVxuICAgICAgaWYgKGNhbGwubmFtZS50eXBlICE9IFwiaWRlbnRpZmllclwiKSB0aGlzLmZhaWwoY2FsbC5uYW1lLCBcImRpcmVjdCBmdW5jdGlvbiBjYWxsIHJlcXVpcmVkXCIpXG4gICAgICBpZiAodGhpcy5oZWxwZXJzLmhhcyhuYW1lKSAmJiBuYW1lID09IFwic2VtYW50aWZvbGRfaW50ZWdlcl9uZWdhdGVcIikge1xuICAgICAgICBpZiAoY2FsbC5hcmd1bWVudHMubGVuZ3RoICE9IDEpIHRoaXMuZmFpbChub2RlLCBcIm5lZ2F0aW9uIGhlbHBlciBhcml0eVwiKVxuICAgICAgICByZXR1cm4gdGhpcy51bmFyeShub2RlLCBcIk5lZ2F0ZVwiLCB0aGlzLmV4cHJlc3Npb24oY2FsbC5hcmd1bWVudHNbMF0pLCBjYWxsLm5hbWUpXG4gICAgICB9XG4gICAgICBjb25zdCBpbnRlbnQgPSB0aGlzLmhlbHBlcnMuaGFzKG5hbWUpID8gYXJpdGhtZXRpY0hlbHBlcnMuZ2V0KG5hbWUpIDogdW5kZWZpbmVkXG5cbiAgICAgIGlmIChpbnRlbnQpIHtcbiAgICAgICAgaWYgKGNhbGwuYXJndW1lbnRzLmxlbmd0aCAhPSAyKSB0aGlzLmZhaWwobm9kZSwgXCJhcml0aG1ldGljIGhlbHBlciBhcml0eVwiKVxuICAgICAgICByZXR1cm4gdGhpcy5iaW5hcnkobm9kZSwgaW50ZW50LCB0aGlzLmV4cHJlc3Npb24oY2FsbC5hcmd1bWVudHNbMF0pLCB0aGlzLmV4cHJlc3Npb24oY2FsbC5hcmd1bWVudHNbMV0pLCBjYWxsLm5hbWUpXG4gICAgICB9XG4gICAgICBjb25zdCBjYWxsZWUgPSB0aGlzLmlkZW50aWZpZXIoY2FsbC5uYW1lKVxuXG4gICAgICBpZiAoY2FsbC5hcmd1bWVudHMubGVuZ3RoICE9IDIpIHRoaXMuZmFpbChub2RlLCBcInNlbWFudGljIGNhbGwgYXJpdHlcIilcbiAgICAgIHJldHVybiB3aXRoUGFyc2VyUmFuZ2VzKHtraW5kOiBcIkNhbGxFeHByZXNzaW9uXCIsIGxvY2F0aW9uLCBjYWxsZWUsIGFyZ3VtZW50czogY2FsbC5hcmd1bWVudHMubWFwKGFyZ3VtZW50ID0+IHRoaXMuZXhwcmVzc2lvbihhcmd1bWVudCkpfSwge2NhbGxlZTogdGhpcy5sb2NhdGlvbihjYWxsLm5hbWUpfSlcbiAgICB9XG4gICAgcmV0dXJuIHRoaXMuZmFpbChub2RlKVxuICB9XG5cbiAgLyoqXG4gICAqIFJldGFpbnMgcGFyc2VyIG9wZXJhdG9yIGludGVudCB1bnRpbCBzaGFyZWQgc2NhbGFyIHJlc29sdXRpb24uXG4gICAqIEBwYXJhbSB7Q3N0Tm9kZX0gbm9kZSAtIE93bmluZyBub2RlLlxuICAgKiBAcGFyYW0ge3N0cmluZ30gaW50ZW50IC0gUGFyc2VyIG9wZXJhdGlvbi5cbiAgICogQHBhcmFtIHtFeHByZXNzaW9ufSBsZWZ0IC0gTGVmdCBvcGVyYW5kLlxuICAgKiBAcGFyYW0ge0V4cHJlc3Npb259IHJpZ2h0IC0gUmlnaHQgb3BlcmFuZC5cbiAgICogQHBhcmFtIHtDc3ROb2RlfSBvcGVyYXRvciAtIEV4YWN0IG9wZXJhdG9yIHRva2VuLlxuICAgKiBAcmV0dXJucyB7RXhwcmVzc2lvbn0gUGVuZGluZyBiaW5hcnkgZXhwcmVzc2lvbi5cbiAgICovXG4gIGJpbmFyeShub2RlLCBpbnRlbnQsIGxlZnQsIHJpZ2h0LCBvcGVyYXRvcikge1xuICAgIHJldHVybiAvKiogQHR5cGUge0V4cHJlc3Npb259ICovICh3aXRoQWRhcHRlZE9wZXJhdGlvbih3aXRoUGFyc2VyUmFuZ2VzKHtraW5kOiBcIkJpbmFyeUV4cHJlc3Npb25cIiwgbG9jYXRpb246IHRoaXMubG9jYXRpb24obm9kZSksIGxlZnQsIHJpZ2h0fSxcbiAgICAgIHtvcGVyYXRvcjogdGhpcy5sb2NhdGlvbihvcGVyYXRvcil9KSwgLyoqIEB0eXBlIHtpbXBvcnQoXCIuLi9zZW1hbnRpYy9vcGVyYXRvcnMuanNcIikuQWRhcHRlZE9wZXJhdGlvbn0gKi8gKGludGVudCkpKVxuICB9XG5cbiAgLyoqXG4gICAqIFJldGFpbnMgdW5hcnkgcGFyc2VyIGludGVudCBhbmQgaXRzIG9yaWdpbmFsIHRva2VuIHJhbmdlLlxuICAgKiBAcGFyYW0ge0NzdE5vZGV9IG5vZGUgLSBPd25pbmcgbm9kZS5cbiAgICogQHBhcmFtIHtcIk5lZ2F0ZVwiIHwgXCJOb3RcIn0gaW50ZW50IC0gVW5hcnkgaW50ZW50LlxuICAgKiBAcGFyYW0ge0V4cHJlc3Npb259IG9wZXJhbmQgLSBPcGVyYW5kLlxuICAgKiBAcGFyYW0ge0NzdE5vZGV9IG9wZXJhdG9yIC0gRXhhY3QgdG9rZW4uXG4gICAqIEByZXR1cm5zIHtFeHByZXNzaW9ufSBQZW5kaW5nIHVuYXJ5IGV4cHJlc3Npb24uXG4gICAqL1xuICB1bmFyeShub2RlLCBpbnRlbnQsIG9wZXJhbmQsIG9wZXJhdG9yKSB7XG4gICAgcmV0dXJuIC8qKiBAdHlwZSB7RXhwcmVzc2lvbn0gKi8gKHdpdGhBZGFwdGVkT3BlcmF0aW9uKHdpdGhQYXJzZXJSYW5nZXMoe2tpbmQ6IFwiVW5hcnlFeHByZXNzaW9uXCIsIGxvY2F0aW9uOiB0aGlzLmxvY2F0aW9uKG5vZGUpLCBvcGVyYW5kfSxcbiAgICAgIHtvcGVyYXRvcjogdGhpcy5sb2NhdGlvbihvcGVyYXRvcil9KSwgaW50ZW50KSlcbiAgfVxuXG4gIC8qKlxuICAgKiBDb252ZXJ0cyBvbmUgZXhwbGljaXRseSB0eXBlZCBpbml0aWFsaXplZCBiaW5kaW5nIG9yIGV4ZWN1dGFibGUgc3RhdGVtZW50LlxuICAgKiBAcGFyYW0ge0NzdE5vZGV9IG5vZGUgLSBTdGF0ZW1lbnQuXG4gICAqIEByZXR1cm5zIHtTdGF0ZW1lbnR9IFNlbWFudGljIHN0YXRlbWVudC5cbiAgICovXG4gIHN0YXRlbWVudChub2RlKSB7XG4gICAgY29uc3QgbG9jYXRpb24gPSB0aGlzLmxvY2F0aW9uKG5vZGUpXG4gICAgY29uc3QgcGFydHMgPSB0aGlzLnBhcnRzKG5vZGUpXG5cbiAgICBpZiAobm9kZS50eXBlID09IFwibGV0X2RlY2xhcmF0aW9uXCIpIHtcbiAgICAgIGNvbnN0IHR5cGVOb2RlID0gbm9kZS5jaGlsZHJlbi5maW5kKCh7ZmllbGR9KSA9PiBmaWVsZCA9PSBcInR5cGVcIik/Lm5vZGVcblxuICAgICAgaWYgKCF0eXBlTm9kZSkgcmV0dXJuIG1pc3NpbmdUeXBlKFwicnVzdFwiLCBcImxvY2FsXCIsIGxvY2F0aW9uKVxuICAgICAgY29uc3QgbmFtZSA9IHRoaXMuZmllbGQobm9kZSwgXCJwYXR0ZXJuXCIpXG4gICAgICBjb25zdCB2YWx1ZSA9IHRoaXMuZmllbGQobm9kZSwgXCJ2YWx1ZVwiKVxuICAgICAgY29uc3QgbXV0YWJsZSA9IHBhcnRzWzFdLnR5cGUgPT0gXCJtdXRhYmxlX3NwZWNpZmllclwiXG5cbiAgICAgIHRoaXMuc2hhcGUobm9kZSwgW1wibGV0XCIsIC4uLihtdXRhYmxlID8gW3BhcnRzWzFdXSA6IFtdKSwgbmFtZSwgXCI6XCIsIHR5cGVOb2RlLCBcIj1cIiwgdmFsdWUsIFwiO1wiXSlcbiAgICAgIGlmIChtdXRhYmxlICYmIHRoaXMudGV4dChwYXJ0c1sxXSkgIT0gXCJtdXRcIikgdGhpcy5mYWlsKHBhcnRzWzFdLCBcIm11dGFiaWxpdHkgdG9rZW5cIilcbiAgICAgIHJldHVybiB3aXRoUGFyc2VyUmFuZ2VzKHtraW5kOiBcIkxvY2FsRGVjbGFyYXRpb25cIiwgbG9jYXRpb24sIG5hbWU6IHRoaXMuaWRlbnRpZmllcihuYW1lKSwgdHlwZTogdGhpcy50eXBlKHR5cGVOb2RlKSwgbXV0YWJsZSxcbiAgICAgICAgaW5pdGlhbGl6ZXI6IHRoaXMuZXhwcmVzc2lvbih2YWx1ZSl9LCB7bmFtZTogdGhpcy5sb2NhdGlvbihuYW1lKSwgb3BlcmF0b3I6IHRoaXMubG9jYXRpb24ocGFydHNbcGFydHMubGVuZ3RoIC0gM10pfSlcbiAgICB9XG4gICAgaWYgKG5vZGUudHlwZSAhPSBcImV4cHJlc3Npb25fc3RhdGVtZW50XCIpIHRoaXMuZmFpbChub2RlLCBcImV4cGxpY2l0IHN0YXRlbWVudCByZXF1aXJlZDsgdGFpbCBleHByZXNzaW9ucyBhcmUgdW5zdXBwb3J0ZWRcIilcbiAgICBjb25zdCBleHByZXNzaW9uID0gcGFydHNbMF1cblxuICAgIGlmIChleHByZXNzaW9uLnR5cGUgPT0gXCJpZl9leHByZXNzaW9uXCIpIHtcbiAgICAgIHRoaXMuc2hhcGUobm9kZSwgW2V4cHJlc3Npb25dKVxuICAgICAgcmV0dXJuIHRoaXMuY29uZGl0aW9uYWwoZXhwcmVzc2lvbilcbiAgICB9XG4gICAgdGhpcy5zaGFwZShub2RlLCBbZXhwcmVzc2lvbiwgXCI7XCJdKVxuICAgIGlmIChleHByZXNzaW9uLnR5cGUgPT0gXCJyZXR1cm5fZXhwcmVzc2lvblwiKSB7XG4gICAgICBjb25zdCByZXR1cm5lZCA9IHRoaXMucGFydHMoZXhwcmVzc2lvbilcblxuICAgICAgdGhpcy5zaGFwZShleHByZXNzaW9uLCBbXCJyZXR1cm5cIiwgcmV0dXJuZWRbMV1dKVxuICAgICAgcmV0dXJuIHtraW5kOiBcIlJldHVyblN0YXRlbWVudFwiLCBsb2NhdGlvbiwgZXhwcmVzc2lvbjogdGhpcy5leHByZXNzaW9uKHJldHVybmVkWzFdKX1cbiAgICB9XG4gICAgaWYgKGV4cHJlc3Npb24udHlwZSA9PSBcImFzc2lnbm1lbnRfZXhwcmVzc2lvblwiKSB7XG4gICAgICBjb25zdCBsZWZ0ID0gdGhpcy5maWVsZChleHByZXNzaW9uLCBcImxlZnRcIilcbiAgICAgIGNvbnN0IHJpZ2h0ID0gdGhpcy5maWVsZChleHByZXNzaW9uLCBcInJpZ2h0XCIpXG5cbiAgICAgIHRoaXMuc2hhcGUoZXhwcmVzc2lvbiwgW2xlZnQsIFwiPVwiLCByaWdodF0pXG4gICAgICBjb25zdCB0YXJnZXQgPSB3aXRoUGFyc2VyUmFuZ2VzKHtraW5kOiAvKiogQHR5cGUge2NvbnN0fSAqLyAoXCJJZGVudGlmaWVyRXhwcmVzc2lvblwiKSwgbG9jYXRpb246IHRoaXMubG9jYXRpb24obGVmdCksIG5hbWU6IHRoaXMuaWRlbnRpZmllcihsZWZ0KX0sIHtuYW1lOiB0aGlzLmxvY2F0aW9uKGxlZnQpfSlcblxuICAgICAgcmV0dXJuIHdpdGhQYXJzZXJSYW5nZXMoe2tpbmQ6IFwiQXNzaWdubWVudFN0YXRlbWVudFwiLCBsb2NhdGlvbiwgdGFyZ2V0LCBleHByZXNzaW9uOiB0aGlzLmV4cHJlc3Npb24ocmlnaHQpfSwge29wZXJhdG9yOiB0aGlzLmxvY2F0aW9uKHRoaXMucGFydHMoZXhwcmVzc2lvbilbMV0pfSlcbiAgICB9XG4gICAgY29uc3QgY2FsbCA9IHRoaXMuY2FsbChleHByZXNzaW9uKVxuICAgIGNvbnN0IG5hbWUgPSB0aGlzLnRleHQoY2FsbC5uYW1lKVxuXG4gICAgaWYgKGNhbGwubmFtZS50eXBlICE9IFwiaWRlbnRpZmllclwiIHx8ICF0aGlzLmhlbHBlcnMuaGFzKG5hbWUpIHx8ICEvXnNlbWFudGlmb2xkX3ByaW50Xyg/OmludGVnZXJ8Ym9vbGVhbnxzdHJpbmcpJC91LnRlc3QobmFtZSkgfHwgY2FsbC5hcmd1bWVudHMubGVuZ3RoICE9IDEpIHRoaXMuZmFpbChub2RlLCBcImV4YWN0IHByaW50IGhlbHBlciBjYWxsIHJlcXVpcmVkXCIpXG4gICAgY29uc3Qgc3RhdGVtZW50ID0ge2tpbmQ6IC8qKiBAdHlwZSB7Y29uc3R9ICovIChcIlByaW50U3RhdGVtZW50XCIpLCBsb2NhdGlvbiwgZXhwcmVzc2lvbjogdGhpcy5leHByZXNzaW9uKGNhbGwuYXJndW1lbnRzWzBdKX1cblxuICAgIHRoaXMucHJpbnRzLnNldChzdGF0ZW1lbnQsIHtub2RlOiBjYWxsLm5hbWUsIHR5cGU6IG5hbWUuc2xpY2UoXCJzZW1hbnRpZm9sZF9wcmludF9cIi5sZW5ndGgpfSlcbiAgICByZXR1cm4gc3RhdGVtZW50XG4gIH1cblxuICAvKipcbiAgICogQ29udmVydHMgZXhhY3QgYnJhY2VkIGNvbmRpdGlvbmFscyBhbmQgZWxzZS1pZiBuZXN0aW5nLlxuICAgKiBAcGFyYW0ge0NzdE5vZGV9IG5vZGUgLSBJZiBleHByZXNzaW9uIHVzZWQgYXMgYSBzdGF0ZW1lbnQuXG4gICAqIEByZXR1cm5zIHtpbXBvcnQoXCIuLi9zZW1hbnRpYy90eXBlcy5qc1wiKS5JZlN0YXRlbWVudH0gQ29uZGl0aW9uYWwgc3RhdGVtZW50LlxuICAgKi9cbiAgY29uZGl0aW9uYWwobm9kZSkge1xuICAgIGNvbnN0IGNvbmRpdGlvbiA9IHRoaXMuZmllbGQobm9kZSwgXCJjb25kaXRpb25cIilcbiAgICBjb25zdCBjb25zZXF1ZW5jZSA9IHRoaXMuZmllbGQobm9kZSwgXCJjb25zZXF1ZW5jZVwiKVxuICAgIGNvbnN0IGFsdGVybmF0aXZlID0gbm9kZS5jaGlsZHJlbi5maW5kKCh7ZmllbGR9KSA9PiBmaWVsZCA9PSBcImFsdGVybmF0aXZlXCIpPy5ub2RlXG5cbiAgICB0aGlzLnNoYXBlKG5vZGUsIFtcImlmXCIsIGNvbmRpdGlvbiwgY29uc2VxdWVuY2UsIC4uLihhbHRlcm5hdGl2ZSA/IFthbHRlcm5hdGl2ZV0gOiBbXSldKVxuICAgIGNvbnN0IHN0YXRlbWVudCA9IHtraW5kOiAvKiogQHR5cGUge2NvbnN0fSAqLyAoXCJJZlN0YXRlbWVudFwiKSwgbG9jYXRpb246IHRoaXMubG9jYXRpb24obm9kZSksIGNvbmRpdGlvbjogdGhpcy5leHByZXNzaW9uKGNvbmRpdGlvbiksIGNvbnNlcXVlbnQ6IHRoaXMuYmxvY2soY29uc2VxdWVuY2UpfVxuXG4gICAgaWYgKCFhbHRlcm5hdGl2ZSkgcmV0dXJuIHN0YXRlbWVudFxuICAgIGNvbnN0IGJyYW5jaCA9IHRoaXMucGFydHMoYWx0ZXJuYXRpdmUpWzFdXG5cbiAgICB0aGlzLnNoYXBlKGFsdGVybmF0aXZlLCBbXCJlbHNlXCIsIGJyYW5jaF0pXG4gICAgcmV0dXJuIHsuLi5zdGF0ZW1lbnQsIGFsdGVybmF0ZTogYnJhbmNoLnR5cGUgPT0gXCJpZl9leHByZXNzaW9uXCIgPyB7a2luZDogXCJCbG9ja1wiLCBsb2NhdGlvbjogdGhpcy5sb2NhdGlvbihicmFuY2gpLCBzdGF0ZW1lbnRzOiBbdGhpcy5jb25kaXRpb25hbChicmFuY2gpXX0gOiB0aGlzLmJsb2NrKGJyYW5jaCl9XG4gIH1cblxuICAvKipcbiAgICogQ29udmVydHMgb25lIGNvbXBsZXRlIGxleGljYWwgYmxvY2suXG4gICAqIEBwYXJhbSB7Q3N0Tm9kZX0gbm9kZSAtIEJyYWNlZCBibG9jay5cbiAgICogQHJldHVybnMge2ltcG9ydChcIi4uL3NlbWFudGljL3R5cGVzLmpzXCIpLkJsb2NrfSBTZW1hbnRpYyBibG9jay5cbiAgICovXG4gIGJsb2NrKG5vZGUpIHtcbiAgICBpZiAobm9kZS50eXBlICE9IFwiYmxvY2tcIikgdGhpcy5mYWlsKG5vZGUsIFwiYnJhY2VkIGJsb2NrIHJlcXVpcmVkXCIpXG4gICAgY29uc3QgcGFydHMgPSB0aGlzLnBhcnRzKG5vZGUpXG5cbiAgICB0aGlzLnNoYXBlKG5vZGUsIFtcIntcIiwgLi4ucGFydHMuc2xpY2UoMSwgLTEpLCBcIn1cIl0pXG4gICAgcmV0dXJuIHtraW5kOiBcIkJsb2NrXCIsIGxvY2F0aW9uOiB0aGlzLmxvY2F0aW9uKG5vZGUpLCBzdGF0ZW1lbnRzOiBwYXJ0cy5zbGljZSgxLCAtMSkubWFwKGNoaWxkID0+IHRoaXMuc3RhdGVtZW50KGNoaWxkKSl9XG4gIH1cblxuICAvKipcbiAgICogQ29udmVydHMgYSBjcmF0ZS1yb290IGZ1bmN0aW9uIHdpdGggZXhhY3RseSB0d28gcmVxdWlyZWQgYnktdmFsdWUgcGFyYW1ldGVycy5cbiAgICogQHBhcmFtIHtDc3ROb2RlfSBub2RlIC0gRnVuY3Rpb24gaXRlbS5cbiAgICogQHJldHVybnMge2ltcG9ydChcIi4uL3NlbWFudGljL3R5cGVzLmpzXCIpLkZ1bmN0aW9uRGVjbGFyYXRpb259IFNlbWFudGljIGRlY2xhcmF0aW9uLlxuICAgKi9cbiAgZnVuY3Rpb24obm9kZSkge1xuICAgIGNvbnN0IG5hbWUgPSB0aGlzLmZpZWxkKG5vZGUsIFwibmFtZVwiKVxuICAgIGNvbnN0IHBhcmFtZXRlcnMgPSB0aGlzLmZpZWxkKG5vZGUsIFwicGFyYW1ldGVyc1wiKVxuICAgIGNvbnN0IHJldHVyblR5cGUgPSBub2RlLmNoaWxkcmVuLmZpbmQoKHtmaWVsZH0pID0+IGZpZWxkID09IFwicmV0dXJuX3R5cGVcIik/Lm5vZGVcbiAgICBjb25zdCBib2R5ID0gdGhpcy5maWVsZChub2RlLCBcImJvZHlcIilcblxuICAgIGlmICghcmV0dXJuVHlwZSkgcmV0dXJuIG1pc3NpbmdUeXBlKFwicnVzdFwiLCBcImZ1bmN0aW9uIHJldHVyblwiLCB0aGlzLmxvY2F0aW9uKG5vZGUpKVxuICAgIHRoaXMuc2hhcGUobm9kZSwgW1wiZm5cIiwgbmFtZSwgcGFyYW1ldGVycywgXCItPlwiLCByZXR1cm5UeXBlLCBib2R5XSlcbiAgICB0aGlzLnNoYXBlKHBhcmFtZXRlcnMsIFtcIihcIiwgXCJwYXJhbWV0ZXJcIiwgXCIsXCIsIFwicGFyYW1ldGVyXCIsIFwiKVwiXSlcbiAgICBjb25zdCBjb252ZXJ0ZWQgPSBbdGhpcy5wYXJ0cyhwYXJhbWV0ZXJzKVsxXSwgdGhpcy5wYXJ0cyhwYXJhbWV0ZXJzKVszXV0ubWFwKHBhcmFtZXRlciA9PiB7XG4gICAgICBjb25zdCBwYXR0ZXJuID0gdGhpcy5maWVsZChwYXJhbWV0ZXIsIFwicGF0dGVyblwiKVxuICAgICAgY29uc3QgdHlwZSA9IHRoaXMuZmllbGQocGFyYW1ldGVyLCBcInR5cGVcIilcblxuICAgICAgdGhpcy5zaGFwZShwYXJhbWV0ZXIsIFtwYXR0ZXJuLCBcIjpcIiwgdHlwZV0pXG4gICAgICByZXR1cm4gd2l0aFBhcnNlclJhbmdlcyh7a2luZDogLyoqIEB0eXBlIHtjb25zdH0gKi8gKFwiUGFyYW1ldGVyXCIpLCBsb2NhdGlvbjogdGhpcy5sb2NhdGlvbihwYXJhbWV0ZXIpLCBuYW1lOiB0aGlzLmlkZW50aWZpZXIocGF0dGVybiksIHR5cGU6IHRoaXMudHlwZSh0eXBlKX0sIHtuYW1lOiB0aGlzLmxvY2F0aW9uKHBhdHRlcm4pfSlcbiAgICB9KVxuXG4gICAgcmV0dXJuIHdpdGhQYXJzZXJSYW5nZXMoe2tpbmQ6IFwiRnVuY3Rpb25EZWNsYXJhdGlvblwiLCBsb2NhdGlvbjogdGhpcy5sb2NhdGlvbihub2RlKSwgbmFtZTogdGhpcy5pZGVudGlmaWVyKG5hbWUpLCBwYXJhbWV0ZXJzOiBjb252ZXJ0ZWQsXG4gICAgICByZXR1cm5UeXBlOiB0aGlzLnR5cGUocmV0dXJuVHlwZSksIGJvZHk6IHRoaXMuYmxvY2soYm9keSl9LCB7bmFtZTogdGhpcy5sb2NhdGlvbihuYW1lKX0pXG4gIH1cblxuICAvKipcbiAgICogQ29tcGFyZXMgYWxsIGZpZWxkcywgY2hpbGRyZW4gYW5kIGxlYWYgc3BlbGxpbmdzIGFnYWluc3QgcXVhbGlmaWVkIHN1cHBvcnQgc3ludGF4LlxuICAgKiBAcGFyYW0ge0NzdE5vZGV9IGFjdHVhbCAtIE9yaWdpbmFsIG5vZGUuXG4gICAqIEBwYXJhbSB7Q3N0Tm9kZX0gZXhwZWN0ZWQgLSBRdWFsaWZpZWQgbm9kZS5cbiAgICogQHBhcmFtIHtSdXN0UmVhZGVyfSBjYW5vbmljYWwgLSBRdWFsaWZpZWQgc3BlbGxpbmcgcmVhZGVyLlxuICAgKiBAcmV0dXJucyB7dm9pZH1cbiAgICovXG4gIGNvbXBhcmVUcmVlKGFjdHVhbCwgZXhwZWN0ZWQsIGNhbm9uaWNhbCkge1xuICAgIGlmIChhY3R1YWwudHlwZSAhPSBleHBlY3RlZC50eXBlIHx8IGFjdHVhbC5uYW1lZCAhPSBleHBlY3RlZC5uYW1lZCB8fCBhY3R1YWwuZXh0cmEgIT0gZXhwZWN0ZWQuZXh0cmEpIHRoaXMuZmFpbChhY3R1YWwsIFwibW9kaWZpZWQgUnVzdCBzdXBwb3J0IG5vZGVcIilcbiAgICBjb25zdCBsZWZ0ID0gdGhpcy5wYXJ0cyhhY3R1YWwpXG4gICAgY29uc3QgcmlnaHQgPSBjYW5vbmljYWwucGFydHMoZXhwZWN0ZWQpXG5cbiAgICBpZiAobGVmdC5sZW5ndGggIT0gcmlnaHQubGVuZ3RoKSB0aGlzLmZhaWwoYWN0dWFsLCBcIm1vZGlmaWVkIFJ1c3Qgc3VwcG9ydCBjaGlsZHJlblwiKVxuICAgIGlmICghbGVmdC5sZW5ndGggJiYgdGhpcy50ZXh0KGFjdHVhbCkgIT0gY2Fub25pY2FsLnRleHQoZXhwZWN0ZWQpKSB0aGlzLmZhaWwoYWN0dWFsLCBcIm1vZGlmaWVkIFJ1c3Qgc3VwcG9ydCB0b2tlblwiKVxuICAgIGxlZnQuZm9yRWFjaCgoY2hpbGQsIGluZGV4KSA9PiB7XG4gICAgICBpZiAoYWN0dWFsLmNoaWxkcmVuLmZpbmQoZWRnZSA9PiBlZGdlLm5vZGUgPT09IGNoaWxkKT8uZmllbGQgIT0gZXhwZWN0ZWQuY2hpbGRyZW4uZmluZChlZGdlID0+IGVkZ2Uubm9kZSA9PT0gcmlnaHRbaW5kZXhdKT8uZmllbGQpIHRoaXMuZmFpbChjaGlsZCwgXCJtb2RpZmllZCBSdXN0IHN1cHBvcnQgZmllbGRcIilcbiAgICAgIHRoaXMuY29tcGFyZVRyZWUoY2hpbGQsIHJpZ2h0W2luZGV4XSwgY2Fub25pY2FsKVxuICAgIH0pXG4gIH1cblxuICAvKipcbiAgICogUmVzb2x2ZXMgb25seSBhbHJlYWR5IHZhbGlkYXRlZCBzY2FsYXIgZXhwcmVzc2lvbnMgZm9yIHNjYWZmb2xkIGNoZWNraW5nLlxuICAgKiBAcGFyYW0ge0V4cHJlc3Npb259IGV4cHJlc3Npb24gLSBSZXNvbHZlZCBzZW1hbnRpYyBleHByZXNzaW9uLlxuICAgKiBAcGFyYW0ge01hcDxzdHJpbmcsIFNjYWxhcj59IGJpbmRpbmdzIC0gTGV4aWNhbCB0eXBlcy5cbiAgICogQHJldHVybnMge1NjYWxhcn0gU2VtYW50aWMgcmVzdWx0IHR5cGUuXG4gICAqL1xuICBleHByZXNzaW9uVHlwZShleHByZXNzaW9uLCBiaW5kaW5ncykge1xuICAgIGlmIChleHByZXNzaW9uLmtpbmQgPT0gXCJTdHJpbmdMaXRlcmFsXCIpIHJldHVybiBcInN0cmluZ1wiXG4gICAgaWYgKGV4cHJlc3Npb24ua2luZCA9PSBcIkludGVnZXJMaXRlcmFsXCIpIHJldHVybiBcImludGVnZXJcIlxuICAgIGlmIChleHByZXNzaW9uLmtpbmQgPT0gXCJCb29sZWFuTGl0ZXJhbFwiKSByZXR1cm4gXCJib29sZWFuXCJcbiAgICBpZiAoZXhwcmVzc2lvbi5raW5kID09IFwiQmluYXJ5RXhwcmVzc2lvblwiIHx8IGV4cHJlc3Npb24ua2luZCA9PSBcIlVuYXJ5RXhwcmVzc2lvblwiKSByZXR1cm4gZXhwcmVzc2lvbi50eXBlXG4gICAgaWYgKGV4cHJlc3Npb24ua2luZCAhPSBcIkNhbGxFeHByZXNzaW9uXCIgJiYgZXhwcmVzc2lvbi5raW5kICE9IFwiSWRlbnRpZmllckV4cHJlc3Npb25cIikge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKFwiVmFsaWRhdGVkIFJ1c3Qgc291cmNlIGV4cG9zZWQgYSBjb2xsZWN0aW9uIGV4cHJlc3Npb24uXCIpXG4gICAgfVxuICAgIGNvbnN0IHR5cGUgPSBleHByZXNzaW9uLmtpbmQgPT0gXCJDYWxsRXhwcmVzc2lvblwiID8gdGhpcy5mdW5jdGlvbnMuZ2V0KGV4cHJlc3Npb24uY2FsbGVlKSA6IGJpbmRpbmdzLmdldChleHByZXNzaW9uLm5hbWUpXG5cbiAgICBpZiAoIXR5cGUpIHRocm93IG5ldyBFcnJvcihcIlZhbGlkYXRlZCBSdXN0IGV4cHJlc3Npb24gbG9zdCBpdHMgc2NhbGFyIGJpbmRpbmcuXCIpXG4gICAgcmV0dXJuIHR5cGVcbiAgfVxuXG4gIC8qKlxuICAgKiBDaGVja3MgY2xvbmUsIGJvcnJvdyBhbmQgcHJpbnQgY29uc3RyYWludHMgYWZ0ZXIgc2hhcmVkIG9wZXJhdGlvbiByZXNvbHV0aW9uLlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4uL3NlbWFudGljL3R5cGVzLmpzXCIpLkJsb2NrfSBibG9jayAtIFJlc29sdmVkIGJsb2NrLlxuICAgKiBAcGFyYW0ge01hcDxzdHJpbmcsIFNjYWxhcj59IGluaGVyaXRlZCAtIEVuY2xvc2luZyB0eXBlcy5cbiAgICogQHJldHVybnMge3ZvaWR9XG4gICAqL1xuICB2YWxpZGF0ZVNjYWxhcnMoYmxvY2ssIGluaGVyaXRlZCkge1xuICAgIGNvbnN0IGJpbmRpbmdzID0gbmV3IE1hcChpbmhlcml0ZWQpXG4gICAgLyoqXG4gICAgICogQ2hlY2tzIGVhY2ggb3JpZ2luYWwgY2xvbmUgYW5kIGJvcnJvd2VkIGNvbmNhdGVuYXRpb24gYWZ0ZXIgc2NhbGFyIHJlc29sdXRpb24uXG4gICAgICogQHBhcmFtIHtFeHByZXNzaW9ufSBleHByZXNzaW9uIC0gQ3VycmVudCBleHByZXNzaW9uLlxuICAgICAqIEByZXR1cm5zIHt2b2lkfVxuICAgICAqL1xuICAgIGNvbnN0IHZpc2l0ID0gZXhwcmVzc2lvbiA9PiB7XG4gICAgICBjb25zdCBjbG9uZSA9IHRoaXMuY2xvbmVzLmdldChleHByZXNzaW9uKVxuICAgICAgY29uc3QgYWRkaXRpb24gPSB0aGlzLmFkZGl0aW9ucy5nZXQoZXhwcmVzc2lvbilcblxuICAgICAgaWYgKGNsb25lICYmIHRoaXMuZXhwcmVzc2lvblR5cGUoZXhwcmVzc2lvbiwgYmluZGluZ3MpICE9IFwic3RyaW5nXCIpIHRoaXMuZmFpbChjbG9uZSwgXCJjbG9uZSByZXF1aXJlcyBvd25lZCBTdHJpbmdcIilcbiAgICAgIGlmIChhZGRpdGlvbiAmJiAodGhpcy5leHByZXNzaW9uVHlwZShleHByZXNzaW9uLCBiaW5kaW5ncykgPT0gXCJzdHJpbmdcIikgIT0gYWRkaXRpb24uYm9ycm93ZWQpIHRoaXMuZmFpbChhZGRpdGlvbi5ub2RlLCBcInN0cmluZyBjb25jYXRlbmF0aW9uIHJlcXVpcmVzIGV4YWN0bHkgYSBib3Jyb3dlZCBTdHJpbmcgUkhTXCIpXG4gICAgICBpZiAoZXhwcmVzc2lvbi5raW5kID09IFwiQ2FsbEV4cHJlc3Npb25cIikgZXhwcmVzc2lvbi5hcmd1bWVudHMuZm9yRWFjaCh2aXNpdClcbiAgICAgIGVsc2UgaWYgKGV4cHJlc3Npb24ua2luZCA9PSBcIlVuYXJ5RXhwcmVzc2lvblwiKSB2aXNpdChleHByZXNzaW9uLm9wZXJhbmQpXG4gICAgICBlbHNlIGlmIChleHByZXNzaW9uLmtpbmQgPT0gXCJCaW5hcnlFeHByZXNzaW9uXCIpIHsgdmlzaXQoZXhwcmVzc2lvbi5sZWZ0KTsgdmlzaXQoZXhwcmVzc2lvbi5yaWdodCkgfVxuICAgIH1cblxuICAgIGZvciAoY29uc3Qgc3RhdGVtZW50IG9mIGJsb2NrLnN0YXRlbWVudHMpIHtcbiAgICAgIGNvbnN0IGV4cHJlc3Npb24gPSBzdGF0ZW1lbnQua2luZCA9PSBcIklmU3RhdGVtZW50XCIgPyBzdGF0ZW1lbnQuY29uZGl0aW9uIDpcbiAgICAgICAgc3RhdGVtZW50LmtpbmQgPT0gXCJMb2NhbERlY2xhcmF0aW9uXCIgPyBzdGF0ZW1lbnQuaW5pdGlhbGl6ZXIgOlxuICAgICAgICAgIHN0YXRlbWVudC5raW5kID09IFwiQXNzaWdubWVudFN0YXRlbWVudFwiIHx8IHN0YXRlbWVudC5raW5kID09IFwiRXhwcmVzc2lvblN0YXRlbWVudFwiIHx8IHN0YXRlbWVudC5raW5kID09IFwiUHJpbnRTdGF0ZW1lbnRcIiA/IHN0YXRlbWVudC5leHByZXNzaW9uIDpcbiAgICAgICAgICAgIHN0YXRlbWVudC5raW5kID09IFwiUmV0dXJuU3RhdGVtZW50XCIgPyBzdGF0ZW1lbnQuZXhwcmVzc2lvbiA6IHVuZGVmaW5lZFxuXG4gICAgICBpZiAoIWV4cHJlc3Npb24pIHRocm93IG5ldyBFcnJvcihcIlZhbGlkYXRlZCBSdXN0IHNvdXJjZSBjb250YWluZWQgYSBiYXJlIHJldHVybi5cIilcbiAgICAgIHZpc2l0KGV4cHJlc3Npb24pXG4gICAgICBpZiAoc3RhdGVtZW50LmtpbmQgPT0gXCJMb2NhbERlY2xhcmF0aW9uXCIpIGJpbmRpbmdzLnNldChzdGF0ZW1lbnQubmFtZSxcbiAgICAgICAgLyoqIEB0eXBlIHtpbXBvcnQoXCIuLi9zZW1hbnRpYy90eXBlcy5qc1wiKS5UeXBlUmVmZXJlbmNlfSAqLyAoc3RhdGVtZW50LnR5cGUpLm5hbWUpXG4gICAgICBpZiAoc3RhdGVtZW50LmtpbmQgPT0gXCJQcmludFN0YXRlbWVudFwiKSB7XG4gICAgICAgIGNvbnN0IHByaW50ID0gdGhpcy5wcmludHMuZ2V0KHN0YXRlbWVudClcblxuICAgICAgICBpZiAoIXByaW50KSB0aHJvdyBuZXcgRXJyb3IoXCJSdXN0IHByaW50IGxvc3QgaXRzIG9yaWdpbmFsIGhlbHBlciBpZGVudGl0eS5cIilcbiAgICAgICAgaWYgKHRoaXMuZXhwcmVzc2lvblR5cGUoZXhwcmVzc2lvbiwgYmluZGluZ3MpICE9IHByaW50LnR5cGUpIHRoaXMuZmFpbChwcmludC5ub2RlLCBcInByaW50IGhlbHBlciBzY2FsYXIgbWlzbWF0Y2hcIilcbiAgICAgIH1cbiAgICAgIGlmIChzdGF0ZW1lbnQua2luZCA9PSBcIklmU3RhdGVtZW50XCIpIHtcbiAgICAgICAgdGhpcy52YWxpZGF0ZVNjYWxhcnMoc3RhdGVtZW50LmNvbnNlcXVlbnQsIGJpbmRpbmdzKVxuICAgICAgICBpZiAoc3RhdGVtZW50LmFsdGVybmF0ZSkgdGhpcy52YWxpZGF0ZVNjYWxhcnMoc3RhdGVtZW50LmFsdGVybmF0ZSwgYmluZGluZ3MpXG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIFZhbGlkYXRlcyBnZW51aW5lIHNvdXJjZSBtb3ZlcyBpbiBldmFsdWF0aW9uIG9yZGVyLCByZXRhaW5pbmcgaW1wbGljaXQgY29tcGFyaXNvbiBib3Jyb3dzLlxuICAgKiBAcGFyYW0ge0V4cHJlc3Npb259IGV4cHJlc3Npb24gLSBPcmlnaW5hbCBleHByZXNzaW9uIG9jY3VycmVuY2UuXG4gICAqIEBwYXJhbSB7TWFwPHN0cmluZywgU2NhbGFyPn0gYmluZGluZ3MgLSBWYWxpZGF0ZWQgbGV4aWNhbCB0eXBlcy5cbiAgICogQHBhcmFtIHtTZXQ8c3RyaW5nPn0gbW92ZWQgLSBEZWZpbml0ZWx5IG9yIHBvc3NpYmx5IGNvbnN1bWVkIFN0cmluZyBiaW5kaW5ncy5cbiAgICogQHBhcmFtIHtTZXQ8c3RyaW5nPn0gYm9ycm93ZWQgLSBCb3Jyb3dzIGhlbGQgYnkgZW5jbG9zaW5nIG9wZXJhbmQgZXZhbHVhdGlvbi5cbiAgICogQHBhcmFtIHtcIm1vdmVcIiB8IFwiYm9ycm93XCJ9IFt1c2FnZV0gLSBIb3cgdGhpcyBleHByZXNzaW9uJ3MgcmVzdWx0IGlzIGNvbnN1bWVkLlxuICAgKiBAcGFyYW0ge2Jvb2xlYW59IFthcHBseUNsb25lXSAtIFdoZXRoZXIgdG8gYXBwbHkgdGhpcyBvY2N1cnJlbmNlJ3MgY2hlY2tlZCBjbG9uZSB3cmFwcGVyLlxuICAgKiBAcmV0dXJucyB7U2V0PHN0cmluZz59IFBsYWNlIGJvcnJvd3MgaGVsZCB1bnRpbCB0aGUgY29udGFpbmluZyBvcGVyYXRpb24gY29tcGxldGVzLlxuICAgKi9cbiAgb3duZXJzaGlwRXhwcmVzc2lvbihleHByZXNzaW9uLCBiaW5kaW5ncywgbW92ZWQsIGJvcnJvd2VkLCB1c2FnZSA9IFwibW92ZVwiLCBhcHBseUNsb25lID0gdHJ1ZSkge1xuICAgIGlmIChhcHBseUNsb25lICYmIHRoaXMuY2xvbmVzLmhhcyhleHByZXNzaW9uKSkge1xuICAgICAgdGhpcy5vd25lcnNoaXBFeHByZXNzaW9uKGV4cHJlc3Npb24sIGJpbmRpbmdzLCBtb3ZlZCwgYm9ycm93ZWQsIFwiYm9ycm93XCIsIGZhbHNlKVxuICAgICAgcmV0dXJuIG5ldyBTZXQoKVxuICAgIH1cbiAgICBpZiAoZXhwcmVzc2lvbi5raW5kID09IFwiSWRlbnRpZmllckV4cHJlc3Npb25cIiAmJiB0aGlzLmV4cHJlc3Npb25UeXBlKGV4cHJlc3Npb24sIGJpbmRpbmdzKSA9PSBcInN0cmluZ1wiKSB7XG4gICAgICBjb25zdCBuYW1lID0gZXhwcmVzc2lvbi5uYW1lXG5cbiAgICAgIGlmIChtb3ZlZC5oYXMobmFtZSkpIHVuc3VwcG9ydGVkU3ludGF4KFwicnVzdFwiLCBgdXNlIG9mIG1vdmVkIFN0cmluZyAnJHtuYW1lfSdgLCBleHByZXNzaW9uLmxvY2F0aW9uKVxuICAgICAgaWYgKHVzYWdlID09IFwiYm9ycm93XCIpIHJldHVybiBuZXcgU2V0KFtuYW1lXSlcbiAgICAgIGlmIChib3Jyb3dlZC5oYXMobmFtZSkpIHVuc3VwcG9ydGVkU3ludGF4KFwicnVzdFwiLCBgY2Fubm90IG1vdmUgYm9ycm93ZWQgU3RyaW5nICcke25hbWV9JyBkdXJpbmcgb3BlcmFuZCBldmFsdWF0aW9uYCwgZXhwcmVzc2lvbi5sb2NhdGlvbilcbiAgICAgIG1vdmVkLmFkZChuYW1lKVxuICAgIH0gZWxzZSBpZiAoZXhwcmVzc2lvbi5raW5kID09IFwiQ2FsbEV4cHJlc3Npb25cIikge1xuICAgICAgZm9yIChjb25zdCBhcmd1bWVudCBvZiBleHByZXNzaW9uLmFyZ3VtZW50cykgdGhpcy5vd25lcnNoaXBFeHByZXNzaW9uKGFyZ3VtZW50LCBiaW5kaW5ncywgbW92ZWQsIGJvcnJvd2VkKVxuICAgIH0gZWxzZSBpZiAoZXhwcmVzc2lvbi5raW5kID09IFwiVW5hcnlFeHByZXNzaW9uXCIpIHRoaXMub3duZXJzaGlwRXhwcmVzc2lvbihleHByZXNzaW9uLm9wZXJhbmQsIGJpbmRpbmdzLCBtb3ZlZCwgYm9ycm93ZWQpXG4gICAgZWxzZSBpZiAoZXhwcmVzc2lvbi5raW5kID09IFwiQmluYXJ5RXhwcmVzc2lvblwiKSB7XG4gICAgICBpZiAoZXhwcmVzc2lvbi5vcGVyYXRpb24gPT0gXCJTdHJpbmdFcXVhbFwiIHx8IGV4cHJlc3Npb24ub3BlcmF0aW9uID09IFwiU3RyaW5nTm90RXF1YWxcIikge1xuICAgICAgICBjb25zdCBoZWxkID0gdGhpcy5vd25lcnNoaXBFeHByZXNzaW9uKGV4cHJlc3Npb24ubGVmdCwgYmluZGluZ3MsIG1vdmVkLCBib3Jyb3dlZCwgXCJib3Jyb3dcIilcblxuICAgICAgICB0aGlzLm93bmVyc2hpcEV4cHJlc3Npb24oZXhwcmVzc2lvbi5yaWdodCwgYmluZGluZ3MsIG1vdmVkLCBuZXcgU2V0KFsuLi5ib3Jyb3dlZCwgLi4uaGVsZF0pLCBcImJvcnJvd1wiKVxuICAgICAgfSBlbHNlIHtcbiAgICAgICAgdGhpcy5vd25lcnNoaXBFeHByZXNzaW9uKGV4cHJlc3Npb24ubGVmdCwgYmluZGluZ3MsIG1vdmVkLCBib3Jyb3dlZClcbiAgICAgICAgaWYgKGV4cHJlc3Npb24ub3BlcmF0aW9uID09IFwiQm9vbGVhbkFuZFwiIHx8IGV4cHJlc3Npb24ub3BlcmF0aW9uID09IFwiQm9vbGVhbk9yXCIpIHtcbiAgICAgICAgICBjb25zdCBjb25kaXRpb25hbCA9IG5ldyBTZXQobW92ZWQpXG5cbiAgICAgICAgICB0aGlzLm93bmVyc2hpcEV4cHJlc3Npb24oZXhwcmVzc2lvbi5yaWdodCwgYmluZGluZ3MsIGNvbmRpdGlvbmFsLCBib3Jyb3dlZClcbiAgICAgICAgICBmb3IgKGNvbnN0IG5hbWUgb2YgY29uZGl0aW9uYWwpIG1vdmVkLmFkZChuYW1lKVxuICAgICAgICB9IGVsc2UgdGhpcy5vd25lcnNoaXBFeHByZXNzaW9uKGV4cHJlc3Npb24ucmlnaHQsIGJpbmRpbmdzLCBtb3ZlZCwgYm9ycm93ZWQsIGV4cHJlc3Npb24ub3BlcmF0aW9uID09IFwiU3RyaW5nQ29uY2F0XCIgPyBcImJvcnJvd1wiIDogXCJtb3ZlXCIpXG4gICAgICB9XG4gICAgfVxuICAgIHJldHVybiBuZXcgU2V0KClcbiAgfVxuXG4gIC8qKlxuICAgKiBNZXJnZXMgc291cmNlIGF2YWlsYWJpbGl0eSBvbmx5IGZyb20gcGF0aHMgdGhhdCBjb250aW51ZSwgcmVzdG9yaW5nIGV4cGxpY2l0IGFzc2lnbm1lbnRzLlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4uL3NlbWFudGljL3R5cGVzLmpzXCIpLkJsb2NrfSBibG9jayAtIE9yaWdpbmFsIGxleGljYWwgYmxvY2suXG4gICAqIEBwYXJhbSB7TWFwPHN0cmluZywgU2NhbGFyPn0gaW5oZXJpdGVkIC0gVmlzaWJsZSBzY2FsYXIgYmluZGluZ3MuXG4gICAqIEBwYXJhbSB7U2V0PHN0cmluZz59IGluaGVyaXRlZE1vdmVkIC0gSW5jb21pbmcgY29uc3VtZWQgYmluZGluZ3MuXG4gICAqIEByZXR1cm5zIHt7bW92ZWQ6IFNldDxzdHJpbmc+LCByZXR1cm5zOiBib29sZWFufX0gT3V0Z29pbmcgc291cmNlIGF2YWlsYWJpbGl0eSBhbmQgY29udHJvbCBmbG93LlxuICAgKi9cbiAgdmFsaWRhdGVPd25lcnNoaXAoYmxvY2ssIGluaGVyaXRlZCwgaW5oZXJpdGVkTW92ZWQpIHtcbiAgICBjb25zdCBiaW5kaW5ncyA9IG5ldyBNYXAoaW5oZXJpdGVkKVxuICAgIGNvbnN0IG1vdmVkID0gbmV3IFNldChpbmhlcml0ZWRNb3ZlZClcblxuICAgIGZvciAoY29uc3Qgc3RhdGVtZW50IG9mIGJsb2NrLnN0YXRlbWVudHMpIHtcbiAgICAgIGNvbnN0IGV4cHJlc3Npb24gPSBzdGF0ZW1lbnQua2luZCA9PSBcIklmU3RhdGVtZW50XCIgPyBzdGF0ZW1lbnQuY29uZGl0aW9uIDpcbiAgICAgICAgc3RhdGVtZW50LmtpbmQgPT0gXCJMb2NhbERlY2xhcmF0aW9uXCIgPyBzdGF0ZW1lbnQuaW5pdGlhbGl6ZXIgOlxuICAgICAgICAgIHN0YXRlbWVudC5raW5kID09IFwiQXNzaWdubWVudFN0YXRlbWVudFwiIHx8IHN0YXRlbWVudC5raW5kID09IFwiRXhwcmVzc2lvblN0YXRlbWVudFwiIHx8IHN0YXRlbWVudC5raW5kID09IFwiUHJpbnRTdGF0ZW1lbnRcIiA/IHN0YXRlbWVudC5leHByZXNzaW9uIDpcbiAgICAgICAgICAgIHN0YXRlbWVudC5raW5kID09IFwiUmV0dXJuU3RhdGVtZW50XCIgPyBzdGF0ZW1lbnQuZXhwcmVzc2lvbiA6IHVuZGVmaW5lZFxuXG4gICAgICBpZiAoIWV4cHJlc3Npb24pIHRocm93IG5ldyBFcnJvcihcIlZhbGlkYXRlZCBSdXN0IHNvdXJjZSBjb250YWluZWQgYSBiYXJlIHJldHVybi5cIilcbiAgICAgIHRoaXMub3duZXJzaGlwRXhwcmVzc2lvbihleHByZXNzaW9uLCBiaW5kaW5ncywgbW92ZWQsIG5ldyBTZXQoKSlcbiAgICAgIGlmIChzdGF0ZW1lbnQua2luZCA9PSBcIlJldHVyblN0YXRlbWVudFwiKSByZXR1cm4ge21vdmVkLCByZXR1cm5zOiB0cnVlfVxuICAgICAgaWYgKHN0YXRlbWVudC5raW5kID09IFwiTG9jYWxEZWNsYXJhdGlvblwiKSBiaW5kaW5ncy5zZXQoc3RhdGVtZW50Lm5hbWUsXG4gICAgICAgIC8qKiBAdHlwZSB7aW1wb3J0KFwiLi4vc2VtYW50aWMvdHlwZXMuanNcIikuVHlwZVJlZmVyZW5jZX0gKi8gKHN0YXRlbWVudC50eXBlKS5uYW1lKVxuICAgICAgZWxzZSBpZiAoc3RhdGVtZW50LmtpbmQgPT0gXCJBc3NpZ25tZW50U3RhdGVtZW50XCIpIG1vdmVkLmRlbGV0ZShzdGF0ZW1lbnQudGFyZ2V0Lm5hbWUpXG4gICAgICBlbHNlIGlmIChzdGF0ZW1lbnQua2luZCA9PSBcIklmU3RhdGVtZW50XCIpIHtcbiAgICAgICAgY29uc3QgY29uc2VxdWVudCA9IHRoaXMudmFsaWRhdGVPd25lcnNoaXAoc3RhdGVtZW50LmNvbnNlcXVlbnQsIGJpbmRpbmdzLCBtb3ZlZClcbiAgICAgICAgY29uc3QgYWx0ZXJuYXRlID0gc3RhdGVtZW50LmFsdGVybmF0ZSA/IHRoaXMudmFsaWRhdGVPd25lcnNoaXAoc3RhdGVtZW50LmFsdGVybmF0ZSwgYmluZGluZ3MsIG1vdmVkKSA6IHttb3ZlZDogbmV3IFNldChtb3ZlZCksIHJldHVybnM6IGZhbHNlfVxuXG4gICAgICAgIGlmIChjb25zZXF1ZW50LnJldHVybnMgJiYgYWx0ZXJuYXRlLnJldHVybnMpIHJldHVybiB7bW92ZWQsIHJldHVybnM6IHRydWV9XG4gICAgICAgIG1vdmVkLmNsZWFyKClcbiAgICAgICAgZm9yIChjb25zdCBwYXRoIG9mIFtjb25zZXF1ZW50LCBhbHRlcm5hdGVdKSB7XG4gICAgICAgICAgaWYgKCFwYXRoLnJldHVybnMpIGZvciAoY29uc3QgbmFtZSBvZiBwYXRoLm1vdmVkKSBpZiAoYmluZGluZ3MuaGFzKG5hbWUpKSBtb3ZlZC5hZGQobmFtZSlcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4ge21vdmVkLCByZXR1cm5zOiBmYWxzZX1cbiAgfVxuXG4gIC8qKlxuICAgKiBWYWxpZGF0ZXMgdGhlIGNvbXBsZXRlIGNyYXRlIGFuZCBjb2xsYXBzZXMgb25seSBleGFjdCBkZWNsYXJlZCBzdXBwb3J0LlxuICAgKiBAcGFyYW0ge0NzdE5vZGV9IHJvb3QgLSBDb21wbGV0ZSByb290LlxuICAgKiBAcmV0dXJucyB7aW1wb3J0KFwiLi4vc2VtYW50aWMvdHlwZXMuanNcIikuU2VtYW50aWNNb2R1bGV9IFJlc29sdmVkIHNlbWFudGljcy5cbiAgICovXG4gIG1vZHVsZShyb290KSB7XG4gICAgdGhpcy52YWxpZGF0ZVRyZWUocm9vdClcbiAgICBpZiAocm9vdC50eXBlICE9IFwic291cmNlX2ZpbGVcIikgdGhpcy5mYWlsKHJvb3QsIFwiY3JhdGUgcm9vdCByZXF1aXJlZFwiKVxuICAgIGNvbnN0IGNhbm9uaWNhbCA9IG5ldyBSdXN0UmVhZGVyKHRoaXMuZmlsZW5hbWUsIHJ1c3RSdW50aW1lKVxuICAgIGNvbnN0IHN1cHBvcnQgPSBjYW5vbmljYWwucGFydHMocGFyc2VSdXN0Q3N0KHJ1c3RSdW50aW1lKS5yb290KVxuICAgIGNvbnN0IGhlbHBlcnMgPSBuZXcgTWFwKHN1cHBvcnQuZmlsdGVyKG5vZGUgPT4gbm9kZS50eXBlID09IFwiZnVuY3Rpb25faXRlbVwiKS5tYXAobm9kZSA9PiBbY2Fub25pY2FsLnRleHQoY2Fub25pY2FsLmZpZWxkKG5vZGUsIFwibmFtZVwiKSksIG5vZGVdKSlcbiAgICAvKiogQHR5cGUge0NzdE5vZGVbXX0gKi9cbiAgICBjb25zdCBkZWZpbml0aW9ucyA9IFtdXG4gICAgbGV0IGxpbnQgPSBmYWxzZVxuICAgIC8qKiBAdHlwZSB7Q3N0Tm9kZSB8IHVuZGVmaW5lZH0gKi9cbiAgICBsZXQgbWFpblxuXG4gICAgZm9yIChjb25zdCBub2RlIG9mIHRoaXMucGFydHMocm9vdCkpIHtcbiAgICAgIGlmIChub2RlLnR5cGUgPT0gXCJpbm5lcl9hdHRyaWJ1dGVfaXRlbVwiKSB7XG4gICAgICAgIGlmIChsaW50IHx8IGRlZmluaXRpb25zLmxlbmd0aCB8fCBtYWluIHx8IHRoaXMuaGVscGVycy5zaXplKSB0aGlzLmZhaWwobm9kZSwgXCJtaXNwbGFjZWQgUnVzdCBsaW50IHN1cHBvcnRcIilcbiAgICAgICAgdGhpcy5jb21wYXJlVHJlZShub2RlLCBzdXBwb3J0WzBdLCBjYW5vbmljYWwpXG4gICAgICAgIGxpbnQgPSB0cnVlXG4gICAgICAgIGNvbnRpbnVlXG4gICAgICB9XG4gICAgICBpZiAobm9kZS50eXBlICE9IFwiZnVuY3Rpb25faXRlbVwiKSB0aGlzLmZhaWwobm9kZSwgXCJjcmF0ZS1yb290IGZyZWUgZnVuY3Rpb25zIG9ubHlcIilcbiAgICAgIGNvbnN0IG5hbWUgPSB0aGlzLnRleHQodGhpcy5maWVsZChub2RlLCBcIm5hbWVcIikpXG4gICAgICBjb25zdCBoZWxwZXIgPSBoZWxwZXJzLmdldChuYW1lKVxuXG4gICAgICBpZiAoaGVscGVyKSB7XG4gICAgICAgIGlmICh0aGlzLmhlbHBlcnMuaGFzKG5hbWUpKSB0aGlzLmZhaWwobm9kZSwgXCJkdXBsaWNhdGUgUnVzdCBoZWxwZXJcIilcbiAgICAgICAgdGhpcy5jb21wYXJlVHJlZShub2RlLCBoZWxwZXIsIGNhbm9uaWNhbClcbiAgICAgICAgdGhpcy5oZWxwZXJzLmFkZChuYW1lKVxuICAgICAgfSBlbHNlIGlmIChuYW1lID09IFwibWFpblwiKSB7XG4gICAgICAgIGlmIChtYWluKSB0aGlzLmZhaWwobm9kZSwgXCJkdXBsaWNhdGUgbWFpblwiKVxuICAgICAgICBtYWluID0gbm9kZVxuICAgICAgfSBlbHNlIGRlZmluaXRpb25zLnB1c2gobm9kZSlcbiAgICB9XG4gICAgaWYgKCFtYWluKSB0aGlzLmZhaWwocm9vdCwgXCJjYW5vbmljYWwgZm4gbWFpbigpIHJlcXVpcmVkXCIpXG4gICAgaWYgKCFkZWZpbml0aW9ucy5sZW5ndGgpIHRoaXMuZmFpbChyb290LCBcInNlbWFudGljIGZ1bmN0aW9uIHJlcXVpcmVkXCIpXG4gICAgY29uc3QgbmFtZSA9IHRoaXMuZmllbGQobWFpbiwgXCJuYW1lXCIpXG4gICAgY29uc3QgcGFyYW1ldGVycyA9IHRoaXMuZmllbGQobWFpbiwgXCJwYXJhbWV0ZXJzXCIpXG4gICAgY29uc3QgYm9keSA9IHRoaXMuZmllbGQobWFpbiwgXCJib2R5XCIpXG5cbiAgICB0aGlzLnNoYXBlKG1haW4sIFtcImZuXCIsIG5hbWUsIHBhcmFtZXRlcnMsIGJvZHldKVxuICAgIHRoaXMuc2hhcGUocGFyYW1ldGVycywgW1wiKFwiLCBcIilcIl0pXG4gICAgY29uc3QgbW9kdWxlID0gdmFsaWRhdGVQYXJzZWRNb2R1bGUoe2tpbmQ6IFwiTW9kdWxlXCIsIGxvY2F0aW9uOiB0aGlzLmxvY2F0aW9uKHJvb3QpLCBmdW5jdGlvbnM6IGRlZmluaXRpb25zLm1hcChub2RlID0+IHRoaXMuZnVuY3Rpb24obm9kZSkpLFxuICAgICAgZW50cnlQb2ludDoge2tpbmQ6IFwiRW50cnlQb2ludFwiLCBsb2NhdGlvbjogdGhpcy5sb2NhdGlvbihtYWluKSwgYm9keTogdGhpcy5ibG9jayhib2R5KX19LCBcInJ1c3RcIilcblxuICAgIHRoaXMuZnVuY3Rpb25zID0gbmV3IE1hcChtb2R1bGUuZnVuY3Rpb25zLm1hcChkZWNsYXJhdGlvbiA9PiBbXG4gICAgICBkZWNsYXJhdGlvbi5uYW1lLFxuICAgICAgLyoqIEB0eXBlIHtTY2FsYXJ9ICovICgvKiogQHR5cGUge2ltcG9ydChcIi4uL3NlbWFudGljL3R5cGVzLmpzXCIpLlR5cGVSZWZlcmVuY2V9ICovIChkZWNsYXJhdGlvbi5yZXR1cm5UeXBlKS5uYW1lKVxuICAgIF0pKVxuICAgIGZvciAoY29uc3QgZGVjbGFyYXRpb24gb2YgbW9kdWxlLmZ1bmN0aW9ucykge1xuICAgICAgY29uc3QgYmluZGluZ3MgPSBuZXcgTWFwKGRlY2xhcmF0aW9uLnBhcmFtZXRlcnMubWFwKHBhcmFtZXRlciA9PiBbcGFyYW1ldGVyLm5hbWUsXG4gICAgICAgIC8qKiBAdHlwZSB7aW1wb3J0KFwiLi4vc2VtYW50aWMvdHlwZXMuanNcIikuVHlwZVJlZmVyZW5jZX0gKi8gKHBhcmFtZXRlci50eXBlKS5uYW1lXSkpXG5cbiAgICAgIHRoaXMudmFsaWRhdGVTY2FsYXJzKGRlY2xhcmF0aW9uLmJvZHksIGJpbmRpbmdzKVxuICAgICAgdGhpcy52YWxpZGF0ZU93bmVyc2hpcChkZWNsYXJhdGlvbi5ib2R5LCBiaW5kaW5ncywgbmV3IFNldCgpKVxuICAgIH1cbiAgICB0aGlzLnZhbGlkYXRlU2NhbGFycyhtb2R1bGUuZW50cnlQb2ludC5ib2R5LCBuZXcgTWFwKCkpXG4gICAgdGhpcy52YWxpZGF0ZU93bmVyc2hpcChtb2R1bGUuZW50cnlQb2ludC5ib2R5LCBuZXcgTWFwKCksIG5ldyBTZXQoKSlcbiAgICByZXR1cm4gbW9kdWxlXG4gIH1cbn1cblxuLyoqXG4gKiBQYXJzZXMgb25seSB0aGUgcXVhbGlmaWVkIGZyb3plbiBDU1QgYW5kIHJlamVjdHMgdW5zdXBwb3J0ZWQgaW5wdXQgYmVmb3JlIGFkYXB0YXRpb24uXG4gKiBAcGFyYW0ge3tmaWxlbmFtZTogc3RyaW5nLCBzb3VyY2U6IHN0cmluZ319IGlucHV0IC0gRXhhY3Qgc291cmNlIHJlcXVlc3QuXG4gKiBAcmV0dXJucyB7aW1wb3J0KFwiLi4vc2VtYW50aWMvdHlwZXMuanNcIikuU2VtYW50aWNNb2R1bGV9IFJ1c3Qgc2VtYW50aWMgbW9kdWxlLlxuICovXG5leHBvcnQgZnVuY3Rpb24gcGFyc2VSdXN0KHtmaWxlbmFtZSwgc291cmNlfSkge1xuICBjb25zdCBjb29yZGluYXRlcyA9IGNyZWF0ZUNvb3JkaW5hdGVJbmRleChzb3VyY2UpXG4gIGNvbnN0IGxvY2F0aW9uID0ge2ZpbGVuYW1lLCBzdGFydDogaW5kZXhlZFBvaW50QXQoY29vcmRpbmF0ZXMsIDApLCBlbmQ6IGluZGV4ZWRQb2ludEF0KGNvb3JkaW5hdGVzLCBzb3VyY2UubGVuZ3RoKX1cblxuICBpZiAoIWhhc09ubHlVbmljb2RlU2NhbGFycyhzb3VyY2UpKSB7XG4gICAgY29uc3Qgb2Zmc2V0ID0gc291cmNlLnNlYXJjaCgvW1xcdUQ4MDAtXFx1REJGRl0oPyFbXFx1REMwMC1cXHVERkZGXSl8KD88IVtcXHVEODAwLVxcdURCRkZdKVtcXHVEQzAwLVxcdURGRkZdL3UpXG5cbiAgICB0aHJvdyBuZXcgU2VtYW50aWZvbGREaWFnbm9zdGljKHtjb2RlOiBcIlBBUlNFX0VSUk9SXCIsIGxhbmd1YWdlOiBcInJ1c3RcIiwgbWVzc2FnZTogXCJSdXN0IHNvdXJjZSBjb250YWlucyBhIGxvbmUgVVRGLTE2IHN1cnJvZ2F0ZS5cIixcbiAgICAgIGxvY2F0aW9uOiB7ZmlsZW5hbWUsIHN0YXJ0OiBpbmRleGVkUG9pbnRBdChjb29yZGluYXRlcywgb2Zmc2V0KSwgZW5kOiBpbmRleGVkUG9pbnRBdChjb29yZGluYXRlcywgb2Zmc2V0ICsgMSl9fSlcbiAgfVxuICBpZiAoc291cmNlLmxlbmd0aCA+IG1heGltdW1SdXN0U291cmNlTGVuZ3RoKSByZXR1cm4gdW5zdXBwb3J0ZWRTeW50YXgoXCJydXN0XCIsIFwic291cmNlIGV4Y2VlZHMgdGhlIGZyb3plbiBSdXN0IHBhcnNlcidzIDMyNzY3IFVURi0xNiBpbnB1dCBsaW1pdFwiLCBsb2NhdGlvbilcbiAgbGV0IHNuYXBzaG90XG5cbiAgdHJ5IHtcbiAgICBzbmFwc2hvdCA9IHBhcnNlUnVzdENzdChzb3VyY2UpXG4gIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgdGhyb3cgbmV3IFNlbWFudGlmb2xkRGlhZ25vc3RpYyh7Y29kZTogXCJQQVJTRV9FUlJPUlwiLCBsYW5ndWFnZTogXCJydXN0XCIsIGxvY2F0aW9uLFxuICAgICAgY2F1c2U6IGVycm9yIGluc3RhbmNlb2YgRXJyb3IgPyBlcnJvciA6IHVuZGVmaW5lZCwgbWVzc2FnZTogXCJUaGUgcXVhbGlmaWVkIFJ1c3QgcGFyc2VyIGNvdWxkIG5vdCBwcm9kdWNlIGEgY29tcGxldGUgQ1NULlwifSlcbiAgfVxuICByZXR1cm4gbmV3IFJ1c3RSZWFkZXIoZmlsZW5hbWUsIHNvdXJjZSkubW9kdWxlKHNuYXBzaG90LnJvb3QpXG59XG4iXX0=