semantifold 0.3.0 → 0.5.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 (303) hide show
  1. package/README.md +61 -15
  2. package/build/index.d.ts +52 -2
  3. package/build/index.d.ts.map +1 -1
  4. package/build/index.js +60 -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/android.d.ts +49 -0
  11. package/build/src/backends/android.d.ts.map +1 -0
  12. package/build/src/backends/android.js +1274 -0
  13. package/build/src/backends/c-validation.d.ts.map +1 -1
  14. package/build/src/backends/c-validation.js +7 -3
  15. package/build/src/backends/cpp-validation.d.ts.map +1 -1
  16. package/build/src/backends/cpp-validation.js +7 -3
  17. package/build/src/backends/csharp.js +7 -1
  18. package/build/src/backends/dart-runtime.d.ts +2 -0
  19. package/build/src/backends/dart-runtime.d.ts.map +1 -0
  20. package/build/src/backends/dart-runtime.js +41 -0
  21. package/build/src/backends/dart.d.ts +20 -0
  22. package/build/src/backends/dart.d.ts.map +1 -0
  23. package/build/src/backends/dart.js +321 -0
  24. package/build/src/backends/effects.d.ts +60 -0
  25. package/build/src/backends/effects.d.ts.map +1 -0
  26. package/build/src/backends/effects.js +746 -0
  27. package/build/src/backends/go.js +18 -4
  28. package/build/src/backends/identifiers.d.ts +36 -4
  29. package/build/src/backends/identifiers.d.ts.map +1 -1
  30. package/build/src/backends/identifiers.js +160 -10
  31. package/build/src/backends/index.d.ts.map +1 -1
  32. package/build/src/backends/index.js +27 -4
  33. package/build/src/backends/ios.d.ts +68 -0
  34. package/build/src/backends/ios.d.ts.map +1 -0
  35. package/build/src/backends/ios.js +1503 -0
  36. package/build/src/backends/java.d.ts.map +1 -1
  37. package/build/src/backends/java.js +429 -36
  38. package/build/src/backends/javascript.d.ts +6 -0
  39. package/build/src/backends/javascript.d.ts.map +1 -1
  40. package/build/src/backends/javascript.js +380 -24
  41. package/build/src/backends/kotlin-runtime.d.ts +3 -0
  42. package/build/src/backends/kotlin-runtime.d.ts.map +1 -0
  43. package/build/src/backends/kotlin-runtime.js +29 -0
  44. package/build/src/backends/kotlin.d.ts +33 -0
  45. package/build/src/backends/kotlin.d.ts.map +1 -0
  46. package/build/src/backends/kotlin.js +138 -0
  47. package/build/src/backends/native-validation.d.ts +2 -2
  48. package/build/src/backends/native-validation.d.ts.map +1 -1
  49. package/build/src/backends/native-validation.js +2 -2
  50. package/build/src/backends/ordered-expressions.d.ts.map +1 -1
  51. package/build/src/backends/ordered-expressions.js +39 -7
  52. package/build/src/backends/php-stdlib-support.d.ts +19 -0
  53. package/build/src/backends/php-stdlib-support.d.ts.map +1 -0
  54. package/build/src/backends/php-stdlib-support.js +227 -0
  55. package/build/src/backends/php.d.ts.map +1 -1
  56. package/build/src/backends/php.js +448 -33
  57. package/build/src/backends/program.d.ts +83 -0
  58. package/build/src/backends/program.d.ts.map +1 -0
  59. package/build/src/backends/program.js +1309 -0
  60. package/build/src/backends/python.js +7 -1
  61. package/build/src/backends/ruby.d.ts.map +1 -1
  62. package/build/src/backends/ruby.js +310 -24
  63. package/build/src/backends/rust-runtime.d.ts +7 -0
  64. package/build/src/backends/rust-runtime.d.ts.map +1 -0
  65. package/build/src/backends/rust-runtime.js +32 -0
  66. package/build/src/backends/rust-validation.d.ts +9 -0
  67. package/build/src/backends/rust-validation.d.ts.map +1 -0
  68. package/build/src/backends/rust-validation.js +78 -0
  69. package/build/src/backends/rust.d.ts +24 -0
  70. package/build/src/backends/rust.d.ts.map +1 -0
  71. package/build/src/backends/rust.js +344 -0
  72. package/build/src/backends/scalars.d.ts +14 -6
  73. package/build/src/backends/scalars.d.ts.map +1 -1
  74. package/build/src/backends/scalars.js +167 -17
  75. package/build/src/backends/shared.d.ts +23 -4
  76. package/build/src/backends/shared.d.ts.map +1 -1
  77. package/build/src/backends/shared.js +2174 -62
  78. package/build/src/backends/stdlib-support.d.ts +14 -0
  79. package/build/src/backends/stdlib-support.d.ts.map +1 -0
  80. package/build/src/backends/stdlib-support.js +237 -0
  81. package/build/src/backends/swift-runtime.d.ts +3 -0
  82. package/build/src/backends/swift-runtime.d.ts.map +1 -0
  83. package/build/src/backends/swift-runtime.js +14 -0
  84. package/build/src/backends/swift.d.ts +8 -0
  85. package/build/src/backends/swift.d.ts.map +1 -0
  86. package/build/src/backends/swift.js +127 -0
  87. package/build/src/backends/typescript.d.ts.map +1 -1
  88. package/build/src/backends/typescript.js +344 -24
  89. package/build/src/backends/wasm.d.ts +43 -0
  90. package/build/src/backends/wasm.d.ts.map +1 -0
  91. package/build/src/backends/wasm.js +2164 -0
  92. package/build/src/backends/writer.d.ts +255 -4
  93. package/build/src/backends/writer.d.ts.map +1 -1
  94. package/build/src/backends/writer.js +491 -3
  95. package/build/src/diagnostic.d.ts +4 -3
  96. package/build/src/diagnostic.d.ts.map +1 -1
  97. package/build/src/diagnostic.js +5 -3
  98. package/build/src/frontends/c.d.ts.map +1 -1
  99. package/build/src/frontends/c.js +5 -3
  100. package/build/src/frontends/cpp.d.ts.map +1 -1
  101. package/build/src/frontends/cpp.js +5 -3
  102. package/build/src/frontends/csharp.d.ts.map +1 -1
  103. package/build/src/frontends/csharp.js +7 -3
  104. package/build/src/frontends/dart.d.ts +10 -0
  105. package/build/src/frontends/dart.d.ts.map +1 -0
  106. package/build/src/frontends/dart.js +913 -0
  107. package/build/src/frontends/index.d.ts +3 -1
  108. package/build/src/frontends/index.d.ts.map +1 -1
  109. package/build/src/frontends/index.js +15 -5
  110. package/build/src/frontends/java.d.ts +110 -1
  111. package/build/src/frontends/java.d.ts.map +1 -1
  112. package/build/src/frontends/java.js +1725 -70
  113. package/build/src/frontends/javascript-typescript.d.ts +69 -1
  114. package/build/src/frontends/javascript-typescript.d.ts.map +1 -1
  115. package/build/src/frontends/javascript-typescript.js +1825 -93
  116. package/build/src/frontends/kotlin.d.ts +10 -0
  117. package/build/src/frontends/kotlin.d.ts.map +1 -0
  118. package/build/src/frontends/kotlin.js +685 -0
  119. package/build/src/frontends/php.d.ts +118 -1
  120. package/build/src/frontends/php.d.ts.map +1 -1
  121. package/build/src/frontends/php.js +1583 -76
  122. package/build/src/frontends/program.d.ts +74 -0
  123. package/build/src/frontends/program.d.ts.map +1 -0
  124. package/build/src/frontends/program.js +989 -0
  125. package/build/src/frontends/ruby.d.ts +68 -1
  126. package/build/src/frontends/ruby.d.ts.map +1 -1
  127. package/build/src/frontends/ruby.js +1446 -101
  128. package/build/src/frontends/rust-parser.d.ts +11 -0
  129. package/build/src/frontends/rust-parser.d.ts.map +1 -0
  130. package/build/src/frontends/rust-parser.js +15 -0
  131. package/build/src/frontends/rust.d.ts +14 -0
  132. package/build/src/frontends/rust.d.ts.map +1 -0
  133. package/build/src/frontends/rust.js +715 -0
  134. package/build/src/frontends/scalars.d.ts +10 -0
  135. package/build/src/frontends/scalars.d.ts.map +1 -1
  136. package/build/src/frontends/scalars.js +28 -2
  137. package/build/src/frontends/swift.d.ts +10 -0
  138. package/build/src/frontends/swift.d.ts.map +1 -0
  139. package/build/src/frontends/swift.js +860 -0
  140. package/build/src/frontends/types.d.ts +186 -0
  141. package/build/src/frontends/types.d.ts.map +1 -0
  142. package/build/src/frontends/types.js +634 -0
  143. package/build/src/language-registry.d.ts +46 -4
  144. package/build/src/language-registry.d.ts.map +1 -1
  145. package/build/src/language-registry.js +177 -13
  146. package/build/src/mapping.d.ts +2 -2
  147. package/build/src/mapping.d.ts.map +1 -1
  148. package/build/src/mapping.js +31 -10
  149. package/build/src/semantic/capabilities.d.ts +66 -0
  150. package/build/src/semantic/capabilities.d.ts.map +1 -0
  151. package/build/src/semantic/capabilities.js +649 -0
  152. package/build/src/semantic/effects.d.ts +26 -0
  153. package/build/src/semantic/effects.d.ts.map +1 -0
  154. package/build/src/semantic/effects.js +764 -0
  155. package/build/src/semantic/generics.d.ts +23 -0
  156. package/build/src/semantic/generics.d.ts.map +1 -0
  157. package/build/src/semantic/generics.js +61 -0
  158. package/build/src/semantic/lifetime.d.ts +37 -0
  159. package/build/src/semantic/lifetime.d.ts.map +1 -0
  160. package/build/src/semantic/lifetime.js +527 -0
  161. package/build/src/semantic/provenance.d.ts +9 -2
  162. package/build/src/semantic/provenance.d.ts.map +1 -1
  163. package/build/src/semantic/provenance.js +462 -20
  164. package/build/src/semantic/scalars.d.ts +11 -0
  165. package/build/src/semantic/scalars.d.ts.map +1 -1
  166. package/build/src/semantic/scalars.js +16 -1
  167. package/build/src/semantic/stdlib.d.ts +254 -0
  168. package/build/src/semantic/stdlib.d.ts.map +1 -0
  169. package/build/src/semantic/stdlib.js +880 -0
  170. package/build/src/semantic/types.d.ts +3108 -178
  171. package/build/src/semantic/types.d.ts.map +1 -1
  172. package/build/src/semantic/types.js +730 -15
  173. package/build/src/semantic/validate.d.ts +85 -5
  174. package/build/src/semantic/validate.d.ts.map +1 -1
  175. package/build/src/semantic/validate.js +2576 -98
  176. package/build/src/stdlib-facades.d.ts +304 -0
  177. package/build/src/stdlib-facades.d.ts.map +1 -0
  178. package/build/src/stdlib-facades.js +1167 -0
  179. package/build/src/stdlib-negotiation.d.ts +69 -0
  180. package/build/src/stdlib-negotiation.d.ts.map +1 -0
  181. package/build/src/stdlib-negotiation.js +403 -0
  182. package/build/src/stdlib-providers.d.ts +72 -0
  183. package/build/src/stdlib-providers.d.ts.map +1 -0
  184. package/build/src/stdlib-providers.js +339 -0
  185. package/build/src/toolchains.d.ts +55 -1
  186. package/build/src/toolchains.d.ts.map +1 -1
  187. package/build/src/toolchains.js +15 -4
  188. package/docs/android.md +79 -0
  189. package/docs/architecture.md +47 -13
  190. package/docs/dart.md +60 -0
  191. package/docs/goals.md +3 -3
  192. package/docs/ios.md +121 -0
  193. package/docs/kotlin.md +42 -0
  194. package/docs/language-support.md +238 -26
  195. package/docs/multi-file-modules.md +52 -0
  196. package/docs/parser-qualification.md +121 -8
  197. package/docs/plans/2026-09-05-standard-library-portability.md +10 -10
  198. package/docs/rust.md +88 -0
  199. package/docs/source-maps.md +17 -7
  200. package/docs/specification.md +5 -0
  201. package/docs/standard-library-portability.md +39 -8
  202. package/docs/swift.md +44 -0
  203. package/docs/testing.md +381 -4
  204. package/docs/webassembly.md +52 -0
  205. package/index.js +66 -8
  206. package/node_modules/semantifold-tree-sitter-legacy-internal/README.md +2 -2
  207. package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/LICENSE +21 -0
  208. package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/README.md +45 -0
  209. package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/binding.gyp +30 -0
  210. package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/bindings/node/binding.cc +20 -0
  211. package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/bindings/node/binding_test.js +9 -0
  212. package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/bindings/node/index.d.ts +28 -0
  213. package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/bindings/node/index.js +11 -0
  214. package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/grammar.js +1630 -0
  215. package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/package.json +64 -0
  216. package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/prebuilds/darwin-arm64/tree-sitter-rust.node +0 -0
  217. package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/prebuilds/darwin-x64/tree-sitter-rust.node +0 -0
  218. package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/prebuilds/linux-arm64/tree-sitter-rust.node +0 -0
  219. package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/prebuilds/linux-x64/tree-sitter-rust.node +0 -0
  220. package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/prebuilds/win32-arm64/tree-sitter-rust.node +0 -0
  221. package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/prebuilds/win32-x64/tree-sitter-rust.node +0 -0
  222. package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/queries/highlights.scm +159 -0
  223. package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/queries/injections.scm +9 -0
  224. package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/queries/tags.scm +60 -0
  225. package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/src/grammar.json +9405 -0
  226. package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/src/node-types.json +5399 -0
  227. package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/src/parser.c +192569 -0
  228. package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/src/scanner.c +393 -0
  229. package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/src/tree_sitter/alloc.h +54 -0
  230. package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/src/tree_sitter/array.h +290 -0
  231. package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/src/tree_sitter/parser.h +266 -0
  232. package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/tree-sitter-rust.wasm +0 -0
  233. package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/tree-sitter.json +53 -0
  234. package/node_modules/semantifold-tree-sitter-legacy-internal/package.json +3 -2
  235. package/node_modules/semantifold-tree-sitter-legacy-internal/src/c.js +5 -4
  236. package/package.json +5 -2
  237. package/src/artifact-path.js +47 -2
  238. package/src/artifacts.js +67 -0
  239. package/src/backends/android.js +1370 -0
  240. package/src/backends/c-validation.js +6 -1
  241. package/src/backends/cpp-validation.js +6 -1
  242. package/src/backends/csharp.js +3 -0
  243. package/src/backends/dart-runtime.js +41 -0
  244. package/src/backends/dart.js +326 -0
  245. package/src/backends/effects.js +705 -0
  246. package/src/backends/go.js +14 -2
  247. package/src/backends/identifiers.js +166 -9
  248. package/src/backends/index.js +27 -2
  249. package/src/backends/ios.js +1612 -0
  250. package/src/backends/java.js +454 -36
  251. package/src/backends/javascript.js +389 -23
  252. package/src/backends/kotlin-runtime.js +29 -0
  253. package/src/backends/kotlin.js +144 -0
  254. package/src/backends/native-validation.js +1 -1
  255. package/src/backends/ordered-expressions.js +40 -6
  256. package/src/backends/php-stdlib-support.js +239 -0
  257. package/src/backends/php.js +469 -32
  258. package/src/backends/program.js +1408 -0
  259. package/src/backends/python.js +3 -0
  260. package/src/backends/ruby.js +326 -23
  261. package/src/backends/rust-runtime.js +34 -0
  262. package/src/backends/rust-validation.js +75 -0
  263. package/src/backends/rust.js +335 -0
  264. package/src/backends/scalars.js +141 -16
  265. package/src/backends/shared.js +2314 -115
  266. package/src/backends/stdlib-support.js +234 -0
  267. package/src/backends/swift-runtime.js +14 -0
  268. package/src/backends/swift.js +132 -0
  269. package/src/backends/typescript.js +349 -23
  270. package/src/backends/wasm.js +2208 -0
  271. package/src/backends/writer.js +545 -2
  272. package/src/diagnostic.js +4 -2
  273. package/src/frontends/c.js +4 -2
  274. package/src/frontends/cpp.js +4 -2
  275. package/src/frontends/csharp.js +4 -2
  276. package/src/frontends/dart.js +963 -0
  277. package/src/frontends/index.js +14 -4
  278. package/src/frontends/java.js +1977 -69
  279. package/src/frontends/javascript-typescript.js +2046 -102
  280. package/src/frontends/kotlin.js +713 -0
  281. package/src/frontends/php.js +1725 -79
  282. package/src/frontends/program.js +1062 -0
  283. package/src/frontends/ruby.js +1624 -98
  284. package/src/frontends/rust-parser.js +18 -0
  285. package/src/frontends/rust.js +714 -0
  286. package/src/frontends/scalars.js +31 -1
  287. package/src/frontends/swift.js +893 -0
  288. package/src/frontends/types.js +750 -0
  289. package/src/language-registry.js +182 -12
  290. package/src/mapping.js +33 -9
  291. package/src/semantic/capabilities.js +671 -0
  292. package/src/semantic/effects.js +737 -0
  293. package/src/semantic/generics.js +58 -0
  294. package/src/semantic/lifetime.js +517 -0
  295. package/src/semantic/provenance.js +412 -19
  296. package/src/semantic/scalars.js +17 -0
  297. package/src/semantic/stdlib.js +921 -0
  298. package/src/semantic/types.js +810 -14
  299. package/src/semantic/validate.js +2934 -209
  300. package/src/stdlib-facades.js +1211 -0
  301. package/src/stdlib-negotiation.js +446 -0
  302. package/src/stdlib-providers.js +377 -0
  303. package/src/toolchains.js +16 -3
@@ -0,0 +1,860 @@
1
+ // @ts-check
2
+ import Parser from "tree-sitter";
3
+ import SwiftLanguage from "tree-sitter-swift/bindings/node/index.js";
4
+ import { isSwiftIdentifier } from "../backends/identifiers.js";
5
+ import { swiftRuntime } from "../backends/swift-runtime.js";
6
+ import { missingType, SemantifoldDiagnostic, unsupportedSyntax } from "../diagnostic.js";
7
+ import { locationFromOffsets, moduleLocation, utf8ByteOffsetToUtf16Offset } from "../semantic/location.js";
8
+ import { withAdaptedOperation } from "../semantic/operators.js";
9
+ import { withParserRanges } from "../semantic/provenance.js";
10
+ import { hasOnlyUnicodeScalars } from "../semantic/scalars.js";
11
+ import { validateParsedModule } from "../semantic/validate.js";
12
+ import { sourceScalarType } from "./scalars.js";
13
+ const parser = new Parser();
14
+ parser.setLanguage(/** @type {import("tree-sitter").Language} */ ( /** @type {unknown} */(SwiftLanguage)));
15
+ const binaryOperations = new Map([
16
+ ["+", "Add"], ["-", "Subtract"], ["*", "Multiply"], ["==", "Equal"], ["!=", "NotEqual"],
17
+ ["<", "LessThan"], ["<=", "LessThanOrEqual"], [">", "GreaterThan"], [">=", "GreaterThanOrEqual"],
18
+ ["&&", "And"], ["||", "Or"]
19
+ ]);
20
+ const binaryNodeOperators = new Map([
21
+ ["additive_expression", new Set(["+", "-"])],
22
+ ["multiplicative_expression", new Set(["*"])],
23
+ ["equality_expression", new Set(["=="])],
24
+ ["comparison_expression", new Set(["<", ">"])],
25
+ ["conjunction_expression", new Set(["&&"])],
26
+ ["disjunction_expression", new Set(["||"])],
27
+ ["infix_expression", new Set(["!=", "<=", ">="])]
28
+ ]);
29
+ /** @type {Map<string, import("../semantic/operators.js").AdaptedOperation>} */
30
+ const helperOperations = new Map([
31
+ ["semantifold_string_equal", "StringEqual"], ["semantifold_string_not_equal", "StringNotEqual"]
32
+ ]);
33
+ /**
34
+ * Verifies a Tree-sitter binding index through the shared byte converter.
35
+ * @param {string} source - Complete source.
36
+ * @param {number} index - Binding-reported UTF-16 index.
37
+ * @returns {number} Verified UTF-16 offset.
38
+ */
39
+ function bindingIndexToUtf16Offset(source, index) {
40
+ if (!Number.isInteger(index) || index < 0 || index > source.length ||
41
+ index > 0 && index < source.length && /[\uD800-\uDBFF]/u.test(source[index - 1]) && /[\uDC00-\uDFFF]/u.test(source[index])) {
42
+ throw new RangeError("Invalid Tree-sitter source index: " + index);
43
+ }
44
+ return utf8ByteOffsetToUtf16Offset(source, new TextEncoder().encode(source.slice(0, index)).length);
45
+ }
46
+ /**
47
+ * Finds an unpaired UTF-16 surrogate.
48
+ * @param {string} source - Complete source.
49
+ * @returns {number} Invalid offset or -1.
50
+ */
51
+ function firstLoneSurrogateOffset(source) {
52
+ for (let index = 0; index < source.length; index += 1) {
53
+ const unit = source.charCodeAt(index);
54
+ if (unit >= 0xD800 && unit <= 0xDBFF) {
55
+ const next = source.charCodeAt(index + 1);
56
+ if (next >= 0xDC00 && next <= 0xDFFF)
57
+ index += 1;
58
+ else
59
+ return index;
60
+ }
61
+ else if (unit >= 0xDC00 && unit <= 0xDFFF)
62
+ return index;
63
+ }
64
+ return -1;
65
+ }
66
+ /** Consumes exact qualified Swift CST shapes without retaining parser handles. */
67
+ class SwiftReader {
68
+ /**
69
+ * Creates a reader over one parser-owned Swift source.
70
+ * @param {string} filename - Original filename.
71
+ * @param {string} source - Complete source.
72
+ */
73
+ constructor(filename, source) {
74
+ this.filename = filename;
75
+ this.source = source;
76
+ /** @type {Set<string>} */
77
+ this.helpers = new Set();
78
+ this.mutableMarker = false;
79
+ /** @type {WeakMap<object, import("tree-sitter").SyntaxNode>} */
80
+ this.nativeEqualityOperators = new WeakMap();
81
+ }
82
+ /**
83
+ * Converts one parser range to Semantifold UTF-16 coordinates.
84
+ * @param {import("tree-sitter").SyntaxNode} node - Parser node.
85
+ * @returns {import("../semantic/types.js").SourceLocation} Exact location.
86
+ */
87
+ location(node) {
88
+ return locationFromOffsets(this.filename, this.source, bindingIndexToUtf16Offset(this.source, node.startIndex), bindingIndexToUtf16Offset(this.source, node.endIndex));
89
+ }
90
+ /**
91
+ * Rejects one located source-profile violation.
92
+ * @param {import("tree-sitter").SyntaxNode} node - Violating node.
93
+ * @param {string} [detail] - Profile detail.
94
+ * @returns {never} Always throws.
95
+ */
96
+ fail(node, detail = node.type) {
97
+ unsupportedSyntax("swift", detail, this.location(node));
98
+ }
99
+ /**
100
+ * Traverses every named, anonymous, extra, directive, and recovery node.
101
+ * @param {import("tree-sitter").SyntaxNode} root - Complete parser root.
102
+ * @returns {void}
103
+ */
104
+ validateTree(root) {
105
+ const pending = [{ depth: 0, node: root, visited: false }];
106
+ while (pending.length) {
107
+ const current = pending.pop();
108
+ if (!current)
109
+ throw new Error("Swift traversal lost a pending parser node.");
110
+ const { depth, node, visited } = current;
111
+ if (depth > 512)
112
+ this.fail(node, "CST exceeds the 512-level traversal limit");
113
+ if (!visited) {
114
+ pending.push({ depth, node, visited: true });
115
+ for (let index = node.childCount - 1; index >= 0; index -= 1) {
116
+ const child = node.child(index);
117
+ if (!child)
118
+ throw new Error(`Tree-sitter omitted child ${index} of ${node.type}.`);
119
+ pending.push({ depth: depth + 1, node: child, visited: false });
120
+ }
121
+ continue;
122
+ }
123
+ if (node.hasError || node.isError || node.isMissing) {
124
+ throw new SemantifoldDiagnostic({
125
+ code: "PARSE_ERROR",
126
+ language: "swift",
127
+ location: this.location(node),
128
+ message: `Tree-sitter exposed recovery at '${node.type}'.`
129
+ });
130
+ }
131
+ if (["attribute", "directive", "shebang_line"].includes(node.type))
132
+ this.fail(node, node.type);
133
+ if (node.type == "comment" && /swift-tools-version/u.test(node.text)) {
134
+ this.fail(node, "directive-bearing comment");
135
+ }
136
+ }
137
+ }
138
+ /**
139
+ * Omits only inert comments already accounted for by exhaustive traversal.
140
+ * @param {import("tree-sitter").SyntaxNode} node - Parent node.
141
+ * @returns {import("tree-sitter").SyntaxNode[]} Structural children.
142
+ */
143
+ parts(node) {
144
+ return node.children.filter((child) => child.type != "comment");
145
+ }
146
+ /**
147
+ * Requires one exact parser field edge.
148
+ * @param {import("tree-sitter").SyntaxNode} node - Field owner.
149
+ * @param {string} name - Field name.
150
+ * @returns {import("tree-sitter").SyntaxNode} Sole field node.
151
+ */
152
+ field(node, name) {
153
+ const matches = [];
154
+ for (let index = 0; index < node.childCount; index += 1) {
155
+ const child = node.child(index);
156
+ if (!child)
157
+ throw new Error(`Tree-sitter omitted child ${index} of ${node.type}.`);
158
+ if (node.fieldNameForChild(index) == name)
159
+ matches.push(child);
160
+ }
161
+ if (matches.length != 1)
162
+ this.fail(node, `expected one '${name}' field`);
163
+ return matches[0];
164
+ }
165
+ /**
166
+ * Requires all ordered children, including anonymous punctuation.
167
+ * @param {import("tree-sitter").SyntaxNode} node - Shape owner.
168
+ * @param {(import("tree-sitter").SyntaxNode | string)[]} expected - Exact child sequence.
169
+ * @returns {void}
170
+ */
171
+ shape(node, expected) {
172
+ const actual = this.parts(node);
173
+ if (actual.length != expected.length)
174
+ this.fail(actual[Math.min(actual.length, expected.length)] ?? node, `${node.type} child shape`);
175
+ for (let index = 0; index < expected.length; index += 1) {
176
+ const wanted = expected[index];
177
+ const child = actual[index];
178
+ const matches = typeof wanted == "string" ? child.text == wanted : child.id == wanted.id;
179
+ if (!matches)
180
+ this.fail(child, `${node.type} child shape`);
181
+ }
182
+ }
183
+ /**
184
+ * Validates one Swift identifier in the portable source profile.
185
+ * @param {import("tree-sitter").SyntaxNode} node - Identifier token.
186
+ * @param {boolean} [allowPrint] - Whether the fixed print scaffold is expected.
187
+ * @returns {string} Accepted spelling.
188
+ */
189
+ identifier(node, allowPrint = false) {
190
+ const name = node.text;
191
+ if (node.type != "simple_identifier" || !(allowPrint && name == "print") &&
192
+ (!isSwiftIdentifier(name) || name.normalize("NFC") != name))
193
+ this.fail(node, "reserved or unsupported identifier");
194
+ return name;
195
+ }
196
+ /**
197
+ * Converts exactly Int64, Bool, or String.
198
+ * @param {import("tree-sitter").SyntaxNode} node - Type node.
199
+ * @returns {import("../semantic/types.js").TypeReference} Semantic scalar.
200
+ */
201
+ type(node) {
202
+ const parts = this.parts(node);
203
+ if (node.type != "user_type" || parts.length != 1 || parts[0].type != "type_identifier")
204
+ this.fail(node, "scalar type shape");
205
+ this.shape(node, [parts[0]]);
206
+ const type = sourceScalarType("swift", parts[0].text, this.location(parts[0]));
207
+ if (!type)
208
+ this.fail(parts[0], `unsupported scalar type '${parts[0].text}'`);
209
+ return type;
210
+ }
211
+ /**
212
+ * Converts one exact ordinary Swift string literal.
213
+ * @param {import("tree-sitter").SyntaxNode} node - String node.
214
+ * @returns {string} Unicode scalar value.
215
+ */
216
+ string(node) {
217
+ const parts = this.parts(node);
218
+ if (node.type != "line_string_literal" || parts.length < 2 || parts[0].text != '"' || parts.at(-1)?.text != '"') {
219
+ return this.fail(node, "ordinary noninterpolated string literal required");
220
+ }
221
+ this.shape(node, ['"', ...parts.slice(1, -1), '"']);
222
+ let value = "";
223
+ const simpleEscapes = new Map([
224
+ ["\\0", "\0"], ["\\n", "\n"], ["\\r", "\r"], ["\\t", "\t"], ["\\\\", "\\"], ['\\"', '"'], ["\\'", "'"]
225
+ ]);
226
+ for (const part of parts.slice(1, -1)) {
227
+ if (part.type == "line_str_text") {
228
+ if (/[\r\n]/u.test(part.text))
229
+ this.fail(part, "string line terminator");
230
+ value += part.text;
231
+ }
232
+ else if (part.type == "str_escaped_char") {
233
+ const escape = part.text;
234
+ if (simpleEscapes.has(escape))
235
+ value += simpleEscapes.get(escape);
236
+ else {
237
+ const match = /^\\u\{([0-9A-Fa-f]{1,8})\}$/u.exec(escape);
238
+ if (!match)
239
+ this.fail(part, "unsupported string escape");
240
+ const scalar = Number.parseInt(match[1], 16);
241
+ if (scalar > 0x10FFFF || scalar >= 0xD800 && scalar <= 0xDFFF)
242
+ this.fail(part, "non-scalar Unicode escape");
243
+ value += String.fromCodePoint(scalar);
244
+ }
245
+ }
246
+ else
247
+ this.fail(part, part.type == "interpolated_expression" ? "interpolated string" : "string child");
248
+ }
249
+ if (!hasOnlyUnicodeScalars(value))
250
+ this.fail(node, "invalid Unicode string literal");
251
+ return value;
252
+ }
253
+ /**
254
+ * Reads exact unlabeled call arguments.
255
+ * @param {import("tree-sitter").SyntaxNode} suffix - Call suffix.
256
+ * @returns {import("tree-sitter").SyntaxNode[]} Argument value nodes.
257
+ */
258
+ arguments(suffix) {
259
+ const suffixParts = this.parts(suffix);
260
+ if (suffix.type != "call_suffix" || suffixParts.length != 1 || suffixParts[0].type != "value_arguments") {
261
+ return this.fail(suffix, "call suffix shape");
262
+ }
263
+ this.shape(suffix, [suffixParts[0]]);
264
+ const list = suffixParts[0];
265
+ const parts = this.parts(list);
266
+ if (parts.length < 2 || parts[0].text != "(" || parts.at(-1)?.text != ")")
267
+ this.fail(list, "call argument list shape");
268
+ const arguments_ = parts.slice(1, -1).filter((_part, index) => index % 2 == 0);
269
+ const expected = ["(", ...arguments_.flatMap((argument, index) => index == 0 ? [argument] : [",", argument]), ")"];
270
+ this.shape(list, expected);
271
+ return arguments_.map((argument) => {
272
+ const value = this.field(argument, "value");
273
+ if (argument.type != "value_argument")
274
+ this.fail(argument, "unlabeled argument required");
275
+ this.shape(argument, [value]);
276
+ return value;
277
+ });
278
+ }
279
+ /**
280
+ * Converts a direct semantic call, including qualified negated-call and trailing-call binary shapes.
281
+ * @param {import("tree-sitter").SyntaxNode} node - Call node.
282
+ * @returns {import("../semantic/types.js").Expression} Semantic expression.
283
+ */
284
+ call(node) {
285
+ const location = this.location(node);
286
+ const parts = this.parts(node);
287
+ if (node.type != "call_expression" || parts.length != 2)
288
+ this.fail(node, "direct call shape");
289
+ const target = parts[0];
290
+ const suffix = parts[1];
291
+ if (binaryNodeOperators.has(target.type)) {
292
+ const right = this.field(target, "rhs");
293
+ const callLocation = locationFromOffsets(this.filename, this.source, bindingIndexToUtf16Offset(this.source, right.startIndex), bindingIndexToUtf16Offset(this.source, suffix.endIndex));
294
+ if (right.type != "simple_identifier")
295
+ this.fail(node, "trailing direct call shape");
296
+ this.shape(node, [target, suffix]);
297
+ return this.binary(target, undefined, location, this.callParts(right, suffix, callLocation));
298
+ }
299
+ return this.callParts(target, suffix, location);
300
+ }
301
+ /**
302
+ * Converts one direct call from its parser target and suffix.
303
+ * @param {import("tree-sitter").SyntaxNode} target - Direct call target.
304
+ * @param {import("tree-sitter").SyntaxNode} suffix - Argument suffix.
305
+ * @param {import("../semantic/types.js").SourceLocation} location - Complete call location.
306
+ * @returns {import("../semantic/types.js").Expression} Semantic call or prefixed call.
307
+ */
308
+ callParts(target, suffix, location) {
309
+ const argumentNodes = this.arguments(suffix);
310
+ let nameNode = target;
311
+ /** @type {import("tree-sitter").SyntaxNode | undefined} */
312
+ let unaryOperator;
313
+ if (["!", "-"].includes(nameNode.text)) {
314
+ if (argumentNodes.length != 1)
315
+ this.fail(target, "parenthesized unary expression shape");
316
+ const expression = this.expression(argumentNodes[0]);
317
+ return /** @type {import("../semantic/types.js").Expression} */ ( /** @type {unknown} */(withAdaptedOperation(withParserRanges({
318
+ kind: "UnaryExpression", location, operand: expression
319
+ }, { operator: this.location(nameNode) }), nameNode.text == "-" ? "Negate" : "Not")));
320
+ }
321
+ if (nameNode.type == "prefix_expression") {
322
+ const operation = this.field(nameNode, "operation");
323
+ const target = this.field(nameNode, "target");
324
+ this.shape(nameNode, [operation, target]);
325
+ if (!["!", "-"].includes(operation.text) || target.type != "simple_identifier")
326
+ this.fail(nameNode, "prefixed direct call shape");
327
+ unaryOperator = operation;
328
+ nameNode = target;
329
+ }
330
+ const name = nameNode.text;
331
+ const helperOperation = this.helpers.has(name) ? helperOperations.get(name) : undefined;
332
+ if (helperOperation) {
333
+ if (unaryOperator || argumentNodes.length != 2)
334
+ this.fail(target, "Swift scalar equality helper shape");
335
+ return /** @type {import("../semantic/types.js").Expression} */ (withAdaptedOperation(withParserRanges({
336
+ kind: "BinaryExpression", left: this.expression(argumentNodes[0]), location, right: this.expression(argumentNodes[1])
337
+ }, { operator: this.location(nameNode) }), helperOperation));
338
+ }
339
+ const semanticName = this.identifier(nameNode);
340
+ if (argumentNodes.length != 2)
341
+ this.fail(suffix, "semantic call argument count");
342
+ const call = withParserRanges({
343
+ arguments: argumentNodes.map((argument) => this.expression(argument)),
344
+ callee: semanticName,
345
+ kind: /** @type {const} */ ("CallExpression"),
346
+ location
347
+ }, { callee: this.location(nameNode) });
348
+ if (!unaryOperator)
349
+ return call;
350
+ return /** @type {import("../semantic/types.js").Expression} */ ( /** @type {unknown} */(withAdaptedOperation(withParserRanges({
351
+ kind: "UnaryExpression", location, operand: call
352
+ }, { operator: this.location(unaryOperator) }), unaryOperator.text == "-" ? "Negate" : "Not")));
353
+ }
354
+ /**
355
+ * Converts one supported scalar expression.
356
+ * @param {import("tree-sitter").SyntaxNode} node - Expression node.
357
+ * @returns {import("../semantic/types.js").Expression} Semantic expression.
358
+ */
359
+ expression(node) {
360
+ const location = this.location(node);
361
+ if (node.type == "simple_identifier") {
362
+ return withParserRanges({ kind: /** @type {const} */ ("IdentifierExpression"), location, name: this.identifier(node) }, { name: location });
363
+ }
364
+ if (node.type == "integer_literal") {
365
+ if (!/^(?:0|[1-9][0-9]*)$/u.test(node.text))
366
+ this.fail(node, "noncanonical integer literal");
367
+ const value = Number(BigInt(node.text));
368
+ if (!Number.isSafeInteger(value))
369
+ this.fail(node, "non-safe integer literal");
370
+ return withParserRanges({ kind: /** @type {const} */ ("IntegerLiteral"), location, value }, { literal: location });
371
+ }
372
+ if (node.type == "boolean_literal") {
373
+ const parts = this.parts(node);
374
+ if (parts.length != 1 || !["true", "false"].includes(parts[0].text))
375
+ this.fail(node, "Boolean literal shape");
376
+ this.shape(node, [parts[0].text]);
377
+ return withParserRanges({ kind: /** @type {const} */ ("BooleanLiteral"), location, value: parts[0].text == "true" }, { literal: location });
378
+ }
379
+ if (node.type == "line_string_literal") {
380
+ return withParserRanges({ kind: /** @type {const} */ ("StringLiteral"), location, value: this.string(node) }, { literal: location });
381
+ }
382
+ if (node.type == "tuple_expression") {
383
+ const value = this.field(node, "value");
384
+ this.shape(node, ["(", value, ")"]);
385
+ return this.expression(value);
386
+ }
387
+ if (node.type == "prefix_expression") {
388
+ const operation = this.field(node, "operation");
389
+ const target = this.field(node, "target");
390
+ this.shape(node, [operation, target]);
391
+ if (!["-", "!"].includes(operation.text))
392
+ this.fail(operation, "unary operator");
393
+ return this.prefixed(operation, target);
394
+ }
395
+ const acceptedOperators = binaryNodeOperators.get(node.type);
396
+ if (acceptedOperators) {
397
+ return this.binary(node);
398
+ }
399
+ if (node.type == "call_expression")
400
+ return this.call(node);
401
+ return this.fail(node);
402
+ }
403
+ /**
404
+ * Converts the grammar's broad prefix target with Swift's tighter prefix precedence.
405
+ * @param {import("tree-sitter").SyntaxNode} operator - Prefix operator.
406
+ * @param {import("tree-sitter").SyntaxNode} target - Grammar target.
407
+ * @returns {import("../semantic/types.js").Expression} Semantic expression.
408
+ */
409
+ prefixed(operator, target) {
410
+ const location = locationFromOffsets(this.filename, this.source, bindingIndexToUtf16Offset(this.source, operator.startIndex), bindingIndexToUtf16Offset(this.source, target.endIndex));
411
+ if (binaryNodeOperators.has(target.type)) {
412
+ const left = this.field(target, "lhs");
413
+ return this.binary(target, this.prefixed(operator, left), location);
414
+ }
415
+ return /** @type {import("../semantic/types.js").Expression} */ ( /** @type {unknown} */(withAdaptedOperation(withParserRanges({
416
+ kind: "UnaryExpression", location, operand: this.expression(target)
417
+ }, { operator: this.location(operator) }), operator.text == "-" ? "Negate" : "Not")));
418
+ }
419
+ /**
420
+ * Converts one qualified binary node, optionally replacing its left edge for prefix precedence.
421
+ * @param {import("tree-sitter").SyntaxNode} node - Binary node.
422
+ * @param {import("../semantic/types.js").Expression} [leftExpression] - Adapted left operand.
423
+ * @param {import("../semantic/types.js").SourceLocation} [location] - Adapted expression range.
424
+ * @param {import("../semantic/types.js").Expression} [rightExpression] - Adapted trailing-call right operand.
425
+ * @returns {import("../semantic/types.js").Expression} Semantic expression.
426
+ */
427
+ binary(node, leftExpression, location = this.location(node), rightExpression) {
428
+ const acceptedOperators = binaryNodeOperators.get(node.type);
429
+ const left = this.field(node, "lhs");
430
+ const operator = this.field(node, "op");
431
+ const right = this.field(node, "rhs");
432
+ const operation = binaryOperations.get(operator.text);
433
+ this.shape(node, [left, operator, right]);
434
+ if (!acceptedOperators?.has(operator.text) || !operation)
435
+ this.fail(operator, "unsupported binary operator");
436
+ const expression = /** @type {import("../semantic/types.js").Expression} */ ( /** @type {unknown} */(withAdaptedOperation(withParserRanges({
437
+ kind: "BinaryExpression", left: leftExpression ?? this.expression(left), location, right: rightExpression ?? this.expression(right)
438
+ }, { operator: this.location(operator) }), /** @type {import("../semantic/operators.js").AdaptedOperation} */ (operation))));
439
+ if (["==", "!="].includes(operator.text))
440
+ this.nativeEqualityOperators.set(expression, operator);
441
+ return expression;
442
+ }
443
+ /**
444
+ * Converts one explicitly typed initialized local.
445
+ * @param {import("tree-sitter").SyntaxNode} node - Property declaration.
446
+ * @returns {import("../semantic/types.js").LocalDeclaration} Semantic local.
447
+ */
448
+ local(node) {
449
+ const location = this.location(node);
450
+ const parts = this.parts(node);
451
+ const binding = parts.find((child) => child.type == "value_binding_pattern");
452
+ const pattern = node.childForFieldName("name");
453
+ const annotation = parts.find((child) => child.type == "type_annotation");
454
+ const value = node.childForFieldName("value");
455
+ if (!annotation)
456
+ return missingType("swift", "Local", location);
457
+ if (!binding || !pattern || !value || pattern.type != "pattern")
458
+ this.fail(node, "local declaration shape");
459
+ const bindingParts = this.parts(binding);
460
+ const nameNode = pattern.childForFieldName("bound_identifier");
461
+ const annotationParts = this.parts(annotation);
462
+ if (bindingParts.length != 1 || !["let", "var"].includes(bindingParts[0].text) || !nameNode || annotationParts.length != 2) {
463
+ this.fail(node, "local declaration shape");
464
+ }
465
+ this.shape(binding, [bindingParts[0].text]);
466
+ this.shape(pattern, [nameNode]);
467
+ this.shape(annotation, [":", annotationParts[1]]);
468
+ this.shape(node, [binding, pattern, annotation, "=", value]);
469
+ const name = this.identifier(nameNode);
470
+ return withParserRanges({
471
+ initializer: this.expression(value),
472
+ kind: /** @type {const} */ ("LocalDeclaration"),
473
+ location,
474
+ mutable: bindingParts[0].text == "var",
475
+ name,
476
+ type: this.type(annotationParts[1])
477
+ }, { name: this.location(nameNode), operator: this.location(parts[3]) });
478
+ }
479
+ /**
480
+ * Converts one plain identifier assignment.
481
+ * @param {import("tree-sitter").SyntaxNode} node - Assignment node.
482
+ * @returns {import("../semantic/types.js").AssignmentStatement} Semantic assignment.
483
+ */
484
+ assignment(node) {
485
+ const target = this.field(node, "target");
486
+ const operator = this.field(node, "operator");
487
+ const value = this.field(node, "result");
488
+ const targetParts = this.parts(target);
489
+ if (target.type != "directly_assignable_expression" || targetParts.length != 1 || operator.text != "=") {
490
+ this.fail(node, "assignment shape");
491
+ }
492
+ this.shape(target, [targetParts[0]]);
493
+ this.shape(node, [target, operator, value]);
494
+ const name = this.identifier(targetParts[0]);
495
+ const targetLocation = this.location(targetParts[0]);
496
+ return withParserRanges({
497
+ expression: this.expression(value),
498
+ kind: /** @type {const} */ ("AssignmentStatement"),
499
+ location: this.location(node),
500
+ target: withParserRanges({ kind: /** @type {const} */ ("IdentifierExpression"), location: targetLocation, name }, { name: targetLocation })
501
+ }, { operator: this.location(operator) });
502
+ }
503
+ /**
504
+ * Converts one exact print call.
505
+ * @param {import("tree-sitter").SyntaxNode} node - Call statement.
506
+ * @returns {import("../semantic/types.js").PrintStatement} Semantic print.
507
+ */
508
+ print(node) {
509
+ const parts = this.parts(node);
510
+ if (node.type != "call_expression" || parts.length != 2 || parts[0].type != "simple_identifier" ||
511
+ this.identifier(parts[0], true) != "print")
512
+ this.fail(node, "exact print call required");
513
+ const arguments_ = this.arguments(parts[1]);
514
+ if (arguments_.length != 1)
515
+ this.fail(parts[1], "print argument count");
516
+ return { expression: this.expression(arguments_[0]), kind: /** @type {const} */ ("PrintStatement"), location: this.location(node) };
517
+ }
518
+ /**
519
+ * Converts one supported statement.
520
+ * @param {import("tree-sitter").SyntaxNode} node - Statement node.
521
+ * @returns {import("../semantic/types.js").Statement} Semantic statement.
522
+ */
523
+ statement(node) {
524
+ if (node.type == "property_declaration")
525
+ return this.local(node);
526
+ if (node.type == "assignment")
527
+ return this.assignment(node);
528
+ if (node.type == "if_statement")
529
+ return this.conditional(node);
530
+ if (node.type == "call_expression")
531
+ return this.print(node);
532
+ if (node.type == "control_transfer_statement") {
533
+ const result = node.childForFieldName("result");
534
+ if (!result)
535
+ this.fail(node, "return without expression");
536
+ this.shape(node, ["return", result]);
537
+ return { expression: this.expression(result), kind: /** @type {const} */ ("ReturnStatement"), location: this.location(node) };
538
+ }
539
+ return this.fail(node);
540
+ }
541
+ /**
542
+ * Converts one parser statements node.
543
+ * @param {import("tree-sitter").SyntaxNode | undefined} node - Optional statements node.
544
+ * @returns {import("../semantic/types.js").Statement[]} Ordered statements.
545
+ */
546
+ statements(node) {
547
+ if (!node)
548
+ return [];
549
+ if (node.type != "statements")
550
+ this.fail(node, "statement list shape");
551
+ return this.statementList(this.parts(node));
552
+ }
553
+ /**
554
+ * Converts a statement sequence while collapsing an adjacent generated marker.
555
+ * @param {import("tree-sitter").SyntaxNode[]} nodes - Ordered statement nodes.
556
+ * @returns {import("../semantic/types.js").Statement[]} Semantic statements.
557
+ */
558
+ statementList(nodes) {
559
+ /** @type {import("../semantic/types.js").Statement[]} */
560
+ const statements = [];
561
+ for (const statement of nodes) {
562
+ const parts = this.parts(statement);
563
+ const marker = statement.type == "call_expression" && parts[0]?.text == "semantifold_keep_mutable";
564
+ if (marker) {
565
+ const previous = statements.at(-1);
566
+ if (!previous || previous.kind != "LocalDeclaration" || !previous.mutable)
567
+ this.fail(statement, "Swift mutable-local warning marker");
568
+ this.mutableMarkerCall(statement, previous);
569
+ }
570
+ else
571
+ statements.push(this.statement(statement));
572
+ }
573
+ return statements;
574
+ }
575
+ /**
576
+ * Collapses the generated inout call only beside its declared mutable local.
577
+ * @param {import("tree-sitter").SyntaxNode} node - Generated marker call.
578
+ * @param {import("../semantic/types.js").LocalDeclaration} local - Preceding local.
579
+ * @returns {void}
580
+ */
581
+ mutableMarkerCall(node, local) {
582
+ const parts = this.parts(node);
583
+ const arguments_ = parts.length == 2 ? this.arguments(parts[1]) : [];
584
+ const argument = arguments_[0];
585
+ const target = argument?.type == "prefix_expression" ? this.field(argument, "target") : undefined;
586
+ if (!this.mutableMarker || parts[0]?.type != "simple_identifier" || parts[0].text != "semantifold_keep_mutable" ||
587
+ arguments_.length != 1 || !target || target.type != "simple_identifier" || target.text != local.name) {
588
+ this.fail(node, "Swift mutable-local warning marker");
589
+ }
590
+ this.shape(node, [parts[0], parts[1]]);
591
+ this.shape(argument, ["&", target]);
592
+ }
593
+ /**
594
+ * Converts one exact braced conditional, including direct else-if.
595
+ * @param {import("tree-sitter").SyntaxNode} node - If node.
596
+ * @returns {import("../semantic/types.js").IfStatement} Semantic conditional.
597
+ */
598
+ conditional(node) {
599
+ const parts = this.parts(node);
600
+ const condition = this.field(node, "condition");
601
+ let index = 3;
602
+ const consequentStatements = parts[index]?.type == "statements" ? parts[index++] : undefined;
603
+ if (node.type != "if_statement" || parts[0]?.text != "if" || parts[1]?.id != condition.id || parts[2]?.text != "{" ||
604
+ parts[index]?.text != "}")
605
+ this.fail(node, "if statement shape");
606
+ index += 1;
607
+ const statement = {
608
+ condition: this.expression(condition),
609
+ consequent: { kind: /** @type {const} */ ("Block"), location: this.location(consequentStatements ?? node),
610
+ statements: this.statements(consequentStatements) },
611
+ kind: /** @type {const} */ ("IfStatement"),
612
+ location: this.location(node)
613
+ };
614
+ if (index == parts.length) {
615
+ this.shape(node, ["if", condition, "{", ...(consequentStatements ? [consequentStatements] : []), "}"]);
616
+ return statement;
617
+ }
618
+ if (parts[index]?.text != "else")
619
+ this.fail(parts[index] ?? node, "if alternate shape");
620
+ index += 1;
621
+ const branch = parts[index];
622
+ if (branch?.type == "if_statement" && index + 1 == parts.length) {
623
+ this.shape(node, ["if", condition, "{", ...(consequentStatements ? [consequentStatements] : []), "}", "else", branch]);
624
+ return { ...statement, alternate: { kind: /** @type {const} */ ("Block"), location: this.location(branch), statements: [this.conditional(branch)] } };
625
+ }
626
+ if (branch?.text != "{")
627
+ this.fail(branch ?? node, "if alternate block shape");
628
+ index += 1;
629
+ const alternateStatements = parts[index]?.type == "statements" ? parts[index++] : undefined;
630
+ if (parts[index]?.text != "}" || index + 1 != parts.length)
631
+ this.fail(parts[index] ?? node, "if alternate block shape");
632
+ this.shape(node, ["if", condition, "{", ...(consequentStatements ? [consequentStatements] : []), "}", "else", "{",
633
+ ...(alternateStatements ? [alternateStatements] : []), "}"]);
634
+ return { ...statement, alternate: { kind: /** @type {const} */ ("Block"), location: this.location(alternateStatements ?? node),
635
+ statements: this.statements(alternateStatements) } };
636
+ }
637
+ /**
638
+ * Converts one function body.
639
+ * @param {import("tree-sitter").SyntaxNode} node - Function body.
640
+ * @returns {import("../semantic/types.js").Block} Semantic block.
641
+ */
642
+ block(node) {
643
+ const parts = this.parts(node);
644
+ const statements = parts[1]?.type == "statements" ? parts[1] : undefined;
645
+ if (node.type != "function_body")
646
+ this.fail(node, "function body shape");
647
+ this.shape(node, ["{", ...(statements ? [statements] : []), "}"]);
648
+ return { kind: /** @type {const} */ ("Block"), location: this.location(node), statements: this.statements(statements) };
649
+ }
650
+ /**
651
+ * Converts one exact underscore-labeled parameter.
652
+ * @param {import("tree-sitter").SyntaxNode} node - Parameter node.
653
+ * @returns {import("../semantic/types.js").Parameter} Semantic parameter.
654
+ */
655
+ parameter(node) {
656
+ const parts = this.parts(node);
657
+ if (node.type != "parameter" || parts.length != 4 || parts[0].text != "_" || parts[0].type != "simple_identifier" ||
658
+ parts[1].type != "simple_identifier" || parts[2].text != ":")
659
+ this.fail(node, "parameter shape");
660
+ this.shape(node, [parts[0], parts[1], ":", parts[3]]);
661
+ const name = this.identifier(parts[1]);
662
+ return withParserRanges({ kind: /** @type {const} */ ("Parameter"), location: this.location(node), name, type: this.type(parts[3]) }, {
663
+ name: this.location(parts[1])
664
+ });
665
+ }
666
+ /**
667
+ * Converts one synchronous top-level scalar function.
668
+ * @param {import("tree-sitter").SyntaxNode} node - Function node.
669
+ * @returns {import("../semantic/types.js").FunctionDeclaration} Semantic function.
670
+ */
671
+ function(node) {
672
+ const parts = this.parts(node);
673
+ const nameNode = node.childForFieldName("name");
674
+ const body = node.childForFieldName("body");
675
+ const parameters = parts.filter((part) => part.type == "parameter");
676
+ if (!nameNode || !body || node.type != "function_declaration")
677
+ this.fail(node, "function declaration shape");
678
+ if (parameters.length != 2)
679
+ this.fail(node, "function parameter count other than two");
680
+ if (!parts.some((part) => part.text == "->"))
681
+ return missingType("swift", "Function return", this.location(node));
682
+ if (parts.length != 10)
683
+ this.fail(parts.find((part) => !["func", "(", ",", ")", "->"].includes(part.text) &&
684
+ part.id != nameNode.id && part.id != body.id && !parameters.some((parameter) => parameter.id == part.id)) ?? node, "function declaration shape");
685
+ const returnType = parts[8];
686
+ this.shape(node, ["func", nameNode, "(", parameters[0], ",", parameters[1], ")", "->", returnType, body]);
687
+ const name = this.identifier(nameNode);
688
+ return withParserRanges({
689
+ body: this.block(body),
690
+ kind: /** @type {const} */ ("FunctionDeclaration"),
691
+ location: this.location(node),
692
+ name,
693
+ parameters: parameters.map((parameter) => this.parameter(parameter)),
694
+ returnType: this.type(returnType)
695
+ }, { name: this.location(nameNode) });
696
+ }
697
+ /**
698
+ * Compares every child field and leaf token against target-only canonical support.
699
+ * @param {import("tree-sitter").SyntaxNode} actual - Source support node.
700
+ * @param {import("tree-sitter").SyntaxNode} expected - Canonical support node.
701
+ * @param {SwiftReader} canonical - Canonical source reader.
702
+ * @returns {void}
703
+ */
704
+ compareTree(actual, expected, canonical) {
705
+ if (actual.type != expected.type || actual.isNamed != expected.isNamed || actual.isExtra != expected.isExtra ||
706
+ actual.childCount != expected.childCount)
707
+ this.fail(actual, "modified Swift support node");
708
+ if (!actual.childCount && actual.text != expected.text)
709
+ this.fail(actual, "modified Swift support token");
710
+ for (let index = 0; index < actual.childCount; index += 1) {
711
+ const left = actual.child(index);
712
+ const right = expected.child(index);
713
+ if (!left || !right || actual.fieldNameForChild(index) != expected.fieldNameForChild(index)) {
714
+ this.fail(left ?? actual, "modified Swift support field");
715
+ }
716
+ this.compareTree(left, right, canonical);
717
+ }
718
+ }
719
+ /**
720
+ * Rejects ordinary Swift equality after shared type resolution identifies Strings.
721
+ * @param {import("../semantic/types.js").SemanticModule} module - Validated semantic module.
722
+ * @returns {void}
723
+ */
724
+ rejectNativeStringEquality(module) {
725
+ const pending = [module.entryPoint.body, ...module.functions.map((declaration) => declaration.body)];
726
+ while (pending.length) {
727
+ const block = pending.pop();
728
+ if (!block)
729
+ throw new Error("Swift semantic traversal lost a pending block.");
730
+ for (const statement of block.statements) {
731
+ if (statement.kind == "IfStatement") {
732
+ pending.push(statement.consequent);
733
+ if (statement.alternate)
734
+ pending.push(statement.alternate);
735
+ this.rejectNativeStringEqualityExpression(statement.condition);
736
+ }
737
+ else if (statement.kind == "LocalDeclaration")
738
+ this.rejectNativeStringEqualityExpression(statement.initializer);
739
+ else if (statement.kind == "AssignmentStatement")
740
+ this.rejectNativeStringEqualityExpression(statement.expression);
741
+ else if (statement.kind == "ExpressionStatement" || statement.kind == "PrintStatement") {
742
+ this.rejectNativeStringEqualityExpression(statement.expression);
743
+ }
744
+ else if (statement.kind == "ReturnStatement" && statement.expression) {
745
+ this.rejectNativeStringEqualityExpression(statement.expression);
746
+ }
747
+ }
748
+ }
749
+ }
750
+ /**
751
+ * Checks one validated expression without retaining parser state in public values.
752
+ * @param {import("../semantic/types.js").Expression} root - Validated expression.
753
+ * @returns {void}
754
+ */
755
+ rejectNativeStringEqualityExpression(root) {
756
+ const pending = [root];
757
+ while (pending.length) {
758
+ const expression = pending.pop();
759
+ if (!expression)
760
+ throw new Error("Swift semantic traversal lost a pending expression.");
761
+ if (expression.kind == "BinaryExpression") {
762
+ const operator = this.nativeEqualityOperators.get(expression);
763
+ if (operator && ["StringEqual", "StringNotEqual"].includes(expression.operation)) {
764
+ this.fail(operator, "ordinary Swift String equality");
765
+ }
766
+ pending.push(expression.left, expression.right);
767
+ }
768
+ else if (expression.kind == "UnaryExpression")
769
+ pending.push(expression.operand);
770
+ else if (expression.kind == "CallExpression")
771
+ pending.push(...expression.arguments);
772
+ }
773
+ }
774
+ /**
775
+ * Converts the complete source file with declarations before top-level entry statements.
776
+ * @param {import("tree-sitter").SyntaxNode} root - Source root.
777
+ * @returns {import("../semantic/types.js").SemanticModule} Semantic module.
778
+ */
779
+ module(root) {
780
+ this.validateTree(root);
781
+ if (root.type != "source_file")
782
+ this.fail(root, "source file root");
783
+ const parts = this.parts(root);
784
+ const canonical = new SwiftReader(this.filename, swiftRuntime);
785
+ const support = canonical.parts(parser.parse(swiftRuntime).rootNode);
786
+ let supportIndex = 0;
787
+ while (supportIndex < parts.length && supportIndex < support.length) {
788
+ const node = parts[supportIndex];
789
+ const name = node.type == "function_declaration" ? node.childForFieldName("name") : undefined;
790
+ const expectedName = support[supportIndex].childForFieldName("name");
791
+ if (!name || !expectedName || name.text != expectedName.text)
792
+ break;
793
+ this.compareTree(node, support[supportIndex], canonical);
794
+ if (helperOperations.has(name.text))
795
+ this.helpers.add(name.text);
796
+ else if (name.text == "semantifold_keep_mutable")
797
+ this.mutableMarker = true;
798
+ supportIndex += 1;
799
+ }
800
+ if (supportIndex > 0 && supportIndex != support.length)
801
+ this.fail(parts[supportIndex - 1], "complete Swift support required");
802
+ const semanticParts = parts.slice(supportIndex);
803
+ const firstEntry = semanticParts.findIndex((node) => node.type != "function_declaration");
804
+ const split = firstEntry < 0 ? semanticParts.length : firstEntry;
805
+ const declarations = semanticParts.slice(0, split);
806
+ const entries = semanticParts.slice(split);
807
+ if (!declarations.length)
808
+ this.fail(root, "top-level semantic function required");
809
+ const laterFunction = entries.find((node) => node.type == "function_declaration");
810
+ const unsupportedEntry = entries.find((node) => !["assignment", "call_expression", "control_transfer_statement", "if_statement",
811
+ "property_declaration", "function_declaration"].includes(node.type));
812
+ if (unsupportedEntry)
813
+ this.fail(unsupportedEntry);
814
+ if (laterFunction)
815
+ this.fail(laterFunction, "function declaration after entry statement");
816
+ if (!entries.length)
817
+ this.fail(root, "top-level entry/print shell required");
818
+ const module = {
819
+ entryPoint: { body: { kind: /** @type {const} */ ("Block"), location: this.location(root),
820
+ statements: this.statementList(entries) }, kind: /** @type {const} */ ("EntryPoint"), location: this.location(root) },
821
+ functions: declarations.map((declaration) => this.function(declaration)),
822
+ kind: /** @type {const} */ ("Module"),
823
+ location: this.location(root)
824
+ };
825
+ validateParsedModule(module, "swift");
826
+ this.rejectNativeStringEquality(module);
827
+ return module;
828
+ }
829
+ }
830
+ /**
831
+ * Parses the strict Task 022 Swift profile through the qualified grammar.
832
+ * @param {{filename: string, source: string}} input - Exact source request.
833
+ * @returns {import("../semantic/types.js").SemanticModule} Semantic module.
834
+ */
835
+ export function parseSwift({ filename, source }) {
836
+ if (!hasOnlyUnicodeScalars(source)) {
837
+ const offset = firstLoneSurrogateOffset(source);
838
+ throw new SemantifoldDiagnostic({
839
+ code: "PARSE_ERROR",
840
+ language: "swift",
841
+ location: locationFromOffsets(filename, source, offset, offset + 1),
842
+ message: "Swift source contains an invalid lone UTF-16 surrogate."
843
+ });
844
+ }
845
+ let tree;
846
+ try {
847
+ tree = parser.parse(source);
848
+ }
849
+ catch (error) {
850
+ throw new SemantifoldDiagnostic({
851
+ cause: error instanceof Error ? error : undefined,
852
+ code: "PARSE_ERROR",
853
+ language: "swift",
854
+ location: moduleLocation(filename, source),
855
+ message: "The qualified Swift parser could not produce a complete CST."
856
+ });
857
+ }
858
+ return new SwiftReader(filename, source).module(tree.rootNode);
859
+ }
860
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic3dpZnQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi9zcmMvZnJvbnRlbmRzL3N3aWZ0LmpzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLFlBQVk7QUFFWixPQUFPLE1BQU0sTUFBTSxhQUFhLENBQUE7QUFDaEMsT0FBTyxhQUFhLE1BQU0sMENBQTBDLENBQUE7QUFDcEUsT0FBTyxFQUFDLGlCQUFpQixFQUFDLE1BQU0sNEJBQTRCLENBQUE7QUFDNUQsT0FBTyxFQUFDLFlBQVksRUFBQyxNQUFNLDhCQUE4QixDQUFBO0FBQ3pELE9BQU8sRUFBQyxXQUFXLEVBQUUscUJBQXFCLEVBQUUsaUJBQWlCLEVBQUMsTUFBTSxrQkFBa0IsQ0FBQTtBQUN0RixPQUFPLEVBQUMsbUJBQW1CLEVBQUUsY0FBYyxFQUFFLDJCQUEyQixFQUFDLE1BQU0seUJBQXlCLENBQUE7QUFDeEcsT0FBTyxFQUFDLG9CQUFvQixFQUFDLE1BQU0sMEJBQTBCLENBQUE7QUFDN0QsT0FBTyxFQUFDLGdCQUFnQixFQUFDLE1BQU0sMkJBQTJCLENBQUE7QUFDMUQsT0FBTyxFQUFDLHFCQUFxQixFQUFDLE1BQU0sd0JBQXdCLENBQUE7QUFDNUQsT0FBTyxFQUFDLG9CQUFvQixFQUFDLE1BQU0seUJBQXlCLENBQUE7QUFDNUQsT0FBTyxFQUFDLGdCQUFnQixFQUFDLE1BQU0sY0FBYyxDQUFBO0FBRTdDLE1BQU0sTUFBTSxHQUFHLElBQUksTUFBTSxFQUFFLENBQUE7QUFFM0IsTUFBTSxDQUFDLFdBQVcsQ0FBQyw2Q0FBNkMsQ0FBQyxFQUFDLHNCQUF1QixDQUFDLGFBQWEsQ0FBQyxDQUFDLENBQUMsQ0FBQTtBQUUxRyxNQUFNLGdCQUFnQixHQUFHLElBQUksR0FBRyxDQUFDO0lBQy9CLENBQUMsR0FBRyxFQUFFLEtBQUssQ0FBQyxFQUFFLENBQUMsR0FBRyxFQUFFLFVBQVUsQ0FBQyxFQUFFLENBQUMsR0FBRyxFQUFFLFVBQVUsQ0FBQyxFQUFFLENBQUMsSUFBSSxF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QyxNQUFNLENBQUMsQ0FBQTtRQUUvQyxNQUFNLElBQUkscUJBQXFCLENBQUM7WUFDOUIsSUFBSSxFQUFFLGFBQWE7WUFDbkIsUUFBUSxFQUFFLE9BQU87WUFDakIsUUFBUSxFQUFFLG1CQUFtQixDQUFDLFFBQVEsRUFBRSxNQUFNLEVBQUUsTUFBTSxFQUFFLE1BQU0sR0FBRyxDQUFDLENBQUM7WUFDbkUsT0FBTyxFQUFFLHlEQUF5RDtTQUNuRSxDQUFDLENBQUE7SUFDSixDQUFDO0lBQ0QsSUFBSSxJQUFJLENBQUE7SUFFUixJQUFJLENBQUM7UUFDSCxJQUFJLEdBQUcsTUFBTSxDQUFDLEtBQUssQ0FBQyxNQUFNLENBQUMsQ0FBQTtJQUM3QixDQUFDO0lBQUMsT0FBTyxLQUFLLEVBQUUsQ0FBQztRQUNmLE1BQU0sSUFBSSxxQkFBcUIsQ0FBQztZQUM5QixLQUFLLEVBQUUsS0FBSyxZQUFZLEtBQUssQ0FBQyxDQUFDLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxTQUFTO1lBQ2pELElBQUksRUFBRSxhQUFhO1lBQ25CLFFBQVEsRUFBRSxPQUFPO1lBQ2pCLFFBQVEsRUFBRSxjQUFjLENBQUMsUUFBUSxFQUFFLE1BQU0sQ0FBQztZQUMxQyxPQUFPLEVBQUUsOERBQThEO1NBQ3hFLENBQUMsQ0FBQTtJQUNKLENBQUM7SUFDRCxPQUFPLElBQUksV0FBVyxDQUFDLFFBQVEsRUFBRSxNQUFNLENBQUMsQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLFFBQVEsQ0FBQyxDQUFBO0FBQ2hFLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyIvLyBAdHMtY2hlY2tcblxuaW1wb3J0IFBhcnNlciBmcm9tIFwidHJlZS1zaXR0ZXJcIlxuaW1wb3J0IFN3aWZ0TGFuZ3VhZ2UgZnJvbSBcInRyZWUtc2l0dGVyLXN3aWZ0L2JpbmRpbmdzL25vZGUvaW5kZXguanNcIlxuaW1wb3J0IHtpc1N3aWZ0SWRlbnRpZmllcn0gZnJvbSBcIi4uL2JhY2tlbmRzL2lkZW50aWZpZXJzLmpzXCJcbmltcG9ydCB7c3dpZnRSdW50aW1lfSBmcm9tIFwiLi4vYmFja2VuZHMvc3dpZnQtcnVudGltZS5qc1wiXG5pbXBvcnQge21pc3NpbmdUeXBlLCBTZW1hbnRpZm9sZERpYWdub3N0aWMsIHVuc3VwcG9ydGVkU3ludGF4fSBmcm9tIFwiLi4vZGlhZ25vc3RpYy5qc1wiXG5pbXBvcnQge2xvY2F0aW9uRnJvbU9mZnNldHMsIG1vZHVsZUxvY2F0aW9uLCB1dGY4Qnl0ZU9mZnNldFRvVXRmMTZPZmZzZXR9IGZyb20gXCIuLi9zZW1hbnRpYy9sb2NhdGlvbi5qc1wiXG5pbXBvcnQge3dpdGhBZGFwdGVkT3BlcmF0aW9ufSBmcm9tIFwiLi4vc2VtYW50aWMvb3BlcmF0b3JzLmpzXCJcbmltcG9ydCB7d2l0aFBhcnNlclJhbmdlc30gZnJvbSBcIi4uL3NlbWFudGljL3Byb3ZlbmFuY2UuanNcIlxuaW1wb3J0IHtoYXNPbmx5VW5pY29kZVNjYWxhcnN9IGZyb20gXCIuLi9zZW1hbnRpYy9zY2FsYXJzLmpzXCJcbmltcG9ydCB7dmFsaWRhdGVQYXJzZWRNb2R1bGV9IGZyb20gXCIuLi9zZW1hbnRpYy92YWxpZGF0ZS5qc1wiXG5pbXBvcnQge3NvdXJjZVNjYWxhclR5cGV9IGZyb20gXCIuL3NjYWxhcnMuanNcIlxuXG5jb25zdCBwYXJzZXIgPSBuZXcgUGFyc2VyKClcblxucGFyc2VyLnNldExhbmd1YWdlKC8qKiBAdHlwZSB7aW1wb3J0KFwidHJlZS1zaXR0ZXJcIikuTGFuZ3VhZ2V9ICovICgvKiogQHR5cGUge3Vua25vd259ICovIChTd2lmdExhbmd1YWdlKSkpXG5cbmNvbnN0IGJpbmFyeU9wZXJhdGlvbnMgPSBuZXcgTWFwKFtcbiAgW1wiK1wiLCBcIkFkZFwiXSwgW1wiLVwiLCBcIlN1YnRyYWN0XCJdLCBbXCIqXCIsIFwiTXVsdGlwbHlcIl0sIFtcIj09XCIsIFwiRXF1YWxcIl0sIFtcIiE9XCIsIFwiTm90RXF1YWxcIl0sXG4gIFtcIjxcIiwgXCJMZXNzVGhhblwiXSwgW1wiPD1cIiwgXCJMZXNzVGhhbk9yRXF1YWxcIl0sIFtcIj5cIiwgXCJHcmVhdGVyVGhhblwiXSwgW1wiPj1cIiwgXCJHcmVhdGVyVGhhbk9yRXF1YWxcIl0sXG4gIFtcIiYmXCIsIFwiQW5kXCJdLCBbXCJ8fFwiLCBcIk9yXCJdXG5dKVxuY29uc3QgYmluYXJ5Tm9kZU9wZXJhdG9ycyA9IG5ldyBNYXAoW1xuICBbXCJhZGRpdGl2ZV9leHByZXNzaW9uXCIsIG5ldyBTZXQoW1wiK1wiLCBcIi1cIl0pXSxcbiAgW1wibXVsdGlwbGljYXRpdmVfZXhwcmVzc2lvblwiLCBuZXcgU2V0KFtcIipcIl0pXSxcbiAgW1wiZXF1YWxpdHlfZXhwcmVzc2lvblwiLCBuZXcgU2V0KFtcIj09XCJdKV0sXG4gIFtcImNvbXBhcmlzb25fZXhwcmVzc2lvblwiLCBuZXcgU2V0KFtcIjxcIiwgXCI+XCJdKV0sXG4gIFtcImNvbmp1bmN0aW9uX2V4cHJlc3Npb25cIiwgbmV3IFNldChbXCImJlwiXSldLFxuICBbXCJkaXNqdW5jdGlvbl9leHByZXNzaW9uXCIsIG5ldyBTZXQoW1wifHxcIl0pXSxcbiAgW1wiaW5maXhfZXhwcmVzc2lvblwiLCBuZXcgU2V0KFtcIiE9XCIsIFwiPD1cIiwgXCI+PVwiXSldXG5dKVxuLyoqIEB0eXBlIHtNYXA8c3RyaW5nLCBpbXBvcnQoXCIuLi9zZW1hbnRpYy9vcGVyYXRvcnMuanNcIikuQWRhcHRlZE9wZXJhdGlvbj59ICovXG5jb25zdCBoZWxwZXJPcGVyYXRpb25zID0gbmV3IE1hcChbXG4gIFtcInNlbWFudGlmb2xkX3N0cmluZ19lcXVhbFwiLCBcIlN0cmluZ0VxdWFsXCJdLCBbXCJzZW1hbnRpZm9sZF9zdHJpbmdfbm90X2VxdWFsXCIsIFwiU3RyaW5nTm90RXF1YWxcIl1cbl0pXG4vKipcbiAqIFZlcmlmaWVzIGEgVHJlZS1zaXR0ZXIgYmluZGluZyBpbmRleCB0aHJvdWdoIHRoZSBzaGFyZWQgYnl0ZSBjb252ZXJ0ZXIuXG4gKiBAcGFyYW0ge3N0cmluZ30gc291cmNlIC0gQ29tcGxldGUgc291cmNlLlxuICogQHBhcmFtIHtudW1iZXJ9IGluZGV4IC0gQmluZGluZy1yZXBvcnRlZCBVVEYtMTYgaW5kZXguXG4gKiBAcmV0dXJucyB7bnVtYmVyfSBWZXJpZmllZCBVVEYtMTYgb2Zmc2V0LlxuICovXG5mdW5jdGlvbiBiaW5kaW5nSW5kZXhUb1V0ZjE2T2Zmc2V0KHNvdXJjZSwgaW5kZXgpIHtcbiAgaWYgKCFOdW1iZXIuaXNJbnRlZ2VyKGluZGV4KSB8fCBpbmRleCA8IDAgfHwgaW5kZXggPiBzb3VyY2UubGVuZ3RoIHx8XG4gICAgaW5kZXggPiAwICYmIGluZGV4IDwgc291cmNlLmxlbmd0aCAmJiAvW1xcdUQ4MDAtXFx1REJGRl0vdS50ZXN0KHNvdXJjZVtpbmRleCAtIDFdKSAmJiAvW1xcdURDMDAtXFx1REZGRl0vdS50ZXN0KHNvdXJjZVtpbmRleF0pKSB7XG4gICAgdGhyb3cgbmV3IFJhbmdlRXJyb3IoXCJJbnZhbGlkIFRyZWUtc2l0dGVyIHNvdXJjZSBpbmRleDogXCIgKyBpbmRleClcbiAgfVxuICByZXR1cm4gdXRmOEJ5dGVPZmZzZXRUb1V0ZjE2T2Zmc2V0KHNvdXJjZSwgbmV3IFRleHRFbmNvZGVyKCkuZW5jb2RlKHNvdXJjZS5zbGljZSgwLCBpbmRleCkpLmxlbmd0aClcbn1cblxuLyoqXG4gKiBGaW5kcyBhbiB1bnBhaXJlZCBVVEYtMTYgc3Vycm9nYXRlLlxuICogQHBhcmFtIHtzdHJpbmd9IHNvdXJjZSAtIENvbXBsZXRlIHNvdXJjZS5cbiAqIEByZXR1cm5zIHtudW1iZXJ9IEludmFsaWQgb2Zmc2V0IG9yIC0xLlxuICovXG5mdW5jdGlvbiBmaXJzdExvbmVTdXJyb2dhdGVPZmZzZXQoc291cmNlKSB7XG4gIGZvciAobGV0IGluZGV4ID0gMDsgaW5kZXggPCBzb3VyY2UubGVuZ3RoOyBpbmRleCArPSAxKSB7XG4gICAgY29uc3QgdW5pdCA9IHNvdXJjZS5jaGFyQ29kZUF0KGluZGV4KVxuXG4gICAgaWYgKHVuaXQgPj0gMHhEODAwICYmIHVuaXQgPD0gMHhEQkZGKSB7XG4gICAgICBjb25zdCBuZXh0ID0gc291cmNlLmNoYXJDb2RlQXQoaW5kZXggKyAxKVxuXG4gICAgICBpZiAobmV4dCA+PSAweERDMDAgJiYgbmV4dCA8PSAweERGRkYpIGluZGV4ICs9IDFcbiAgICAgIGVsc2UgcmV0dXJuIGluZGV4XG4gICAgfSBlbHNlIGlmICh1bml0ID49IDB4REMwMCAmJiB1bml0IDw9IDB4REZGRikgcmV0dXJuIGluZGV4XG4gIH1cbiAgcmV0dXJuIC0xXG59XG5cbi8qKiBDb25zdW1lcyBleGFjdCBxdWFsaWZpZWQgU3dpZnQgQ1NUIHNoYXBlcyB3aXRob3V0IHJldGFpbmluZyBwYXJzZXIgaGFuZGxlcy4gKi9cbmNsYXNzIFN3aWZ0UmVhZGVyIHtcbiAgLyoqXG4gICAqIENyZWF0ZXMgYSByZWFkZXIgb3ZlciBvbmUgcGFyc2VyLW93bmVkIFN3aWZ0IHNvdXJjZS5cbiAgICogQHBhcmFtIHtzdHJpbmd9IGZpbGVuYW1lIC0gT3JpZ2luYWwgZmlsZW5hbWUuXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBzb3VyY2UgLSBDb21wbGV0ZSBzb3VyY2UuXG4gICAqL1xuICBjb25zdHJ1Y3RvcihmaWxlbmFtZSwgc291cmNlKSB7XG4gICAgdGhpcy5maWxlbmFtZSA9IGZpbGVuYW1lXG4gICAgdGhpcy5zb3VyY2UgPSBzb3VyY2VcbiAgICAvKiogQHR5cGUge1NldDxzdHJpbmc+fSAqL1xuICAgIHRoaXMuaGVscGVycyA9IG5ldyBTZXQoKVxuICAgIHRoaXMubXV0YWJsZU1hcmtlciA9IGZhbHNlXG4gICAgLyoqIEB0eXBlIHtXZWFrTWFwPG9iamVjdCwgaW1wb3J0KFwidHJlZS1zaXR0ZXJcIikuU3ludGF4Tm9kZT59ICovXG4gICAgdGhpcy5uYXRpdmVFcXVhbGl0eU9wZXJhdG9ycyA9IG5ldyBXZWFrTWFwKClcbiAgfVxuXG4gIC8qKlxuICAgKiBDb252ZXJ0cyBvbmUgcGFyc2VyIHJhbmdlIHRvIFNlbWFudGlmb2xkIFVURi0xNiBjb29yZGluYXRlcy5cbiAgICogQHBhcmFtIHtpbXBvcnQoXCJ0cmVlLXNpdHRlclwiKS5TeW50YXhOb2RlfSBub2RlIC0gUGFyc2VyIG5vZGUuXG4gICAqIEByZXR1cm5zIHtpbXBvcnQoXCIuLi9zZW1hbnRpYy90eXBlcy5qc1wiKS5Tb3VyY2VMb2NhdGlvbn0gRXhhY3QgbG9jYXRpb24uXG4gICAqL1xuICBsb2NhdGlvbihub2RlKSB7XG4gICAgcmV0dXJuIGxvY2F0aW9uRnJvbU9mZnNldHModGhpcy5maWxlbmFtZSwgdGhpcy5zb3VyY2UsIGJpbmRpbmdJbmRleFRvVXRmMTZPZmZzZXQodGhpcy5zb3VyY2UsIG5vZGUuc3RhcnRJbmRleCksXG4gICAgICBiaW5kaW5nSW5kZXhUb1V0ZjE2T2Zmc2V0KHRoaXMuc291cmNlLCBub2RlLmVuZEluZGV4KSlcbiAgfVxuXG4gIC8qKlxuICAgKiBSZWplY3RzIG9uZSBsb2NhdGVkIHNvdXJjZS1wcm9maWxlIHZpb2xhdGlvbi5cbiAgICogQHBhcmFtIHtpbXBvcnQoXCJ0cmVlLXNpdHRlclwiKS5TeW50YXhOb2RlfSBub2RlIC0gVmlvbGF0aW5nIG5vZGUuXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBbZGV0YWlsXSAtIFByb2ZpbGUgZGV0YWlsLlxuICAgKiBAcmV0dXJucyB7bmV2ZXJ9IEFsd2F5cyB0aHJvd3MuXG4gICAqL1xuICBmYWlsKG5vZGUsIGRldGFpbCA9IG5vZGUudHlwZSkge1xuICAgIHVuc3VwcG9ydGVkU3ludGF4KFwic3dpZnRcIiwgZGV0YWlsLCB0aGlzLmxvY2F0aW9uKG5vZGUpKVxuICB9XG5cbiAgLyoqXG4gICAqIFRyYXZlcnNlcyBldmVyeSBuYW1lZCwgYW5vbnltb3VzLCBleHRyYSwgZGlyZWN0aXZlLCBhbmQgcmVjb3Zlcnkgbm9kZS5cbiAgICogQHBhcmFtIHtpbXBvcnQoXCJ0cmVlLXNpdHRlclwiKS5TeW50YXhOb2RlfSByb290IC0gQ29tcGxldGUgcGFyc2VyIHJvb3QuXG4gICAqIEByZXR1cm5zIHt2b2lkfVxuICAgKi9cbiAgdmFsaWRhdGVUcmVlKHJvb3QpIHtcbiAgICBjb25zdCBwZW5kaW5nID0gW3tkZXB0aDogMCwgbm9kZTogcm9vdCwgdmlzaXRlZDogZmFsc2V9XVxuXG4gICAgd2hpbGUgKHBlbmRpbmcubGVuZ3RoKSB7XG4gICAgICBjb25zdCBjdXJyZW50ID0gcGVuZGluZy5wb3AoKVxuXG4gICAgICBpZiAoIWN1cnJlbnQpIHRocm93IG5ldyBFcnJvcihcIlN3aWZ0IHRyYXZlcnNhbCBsb3N0IGEgcGVuZGluZyBwYXJzZXIgbm9kZS5cIilcbiAgICAgIGNvbnN0IHtkZXB0aCwgbm9kZSwgdmlzaXRlZH0gPSBjdXJyZW50XG5cbiAgICAgIGlmIChkZXB0aCA+IDUxMikgdGhpcy5mYWlsKG5vZGUsIFwiQ1NUIGV4Y2VlZHMgdGhlIDUxMi1sZXZlbCB0cmF2ZXJzYWwgbGltaXRcIilcbiAgICAgIGlmICghdmlzaXRlZCkge1xuICAgICAgICBwZW5kaW5nLnB1c2goe2RlcHRoLCBub2RlLCB2aXNpdGVkOiB0cnVlfSlcbiAgICAgICAgZm9yIChsZXQgaW5kZXggPSBub2RlLmNoaWxkQ291bnQgLSAxOyBpbmRleCA+PSAwOyBpbmRleCAtPSAxKSB7XG4gICAgICAgICAgY29uc3QgY2hpbGQgPSBub2RlLmNoaWxkKGluZGV4KVxuXG4gICAgICAgICAgaWYgKCFjaGlsZCkgdGhyb3cgbmV3IEVycm9yKGBUcmVlLXNpdHRlciBvbWl0dGVkIGNoaWxkICR7aW5kZXh9IG9mICR7bm9kZS50eXBlfS5gKVxuICAgICAgICAgIHBlbmRpbmcucHVzaCh7ZGVwdGg6IGRlcHRoICsgMSwgbm9kZTogY2hpbGQsIHZpc2l0ZWQ6IGZhbHNlfSlcbiAgICAgICAgfVxuICAgICAgICBjb250aW51ZVxuICAgICAgfVxuICAgICAgaWYgKG5vZGUuaGFzRXJyb3IgfHwgbm9kZS5pc0Vycm9yIHx8IG5vZGUuaXNNaXNzaW5nKSB7XG4gICAgICAgIHRocm93IG5ldyBTZW1hbnRpZm9sZERpYWdub3N0aWMoe1xuICAgICAgICAgIGNvZGU6IFwiUEFSU0VfRVJST1JcIixcbiAgICAgICAgICBsYW5ndWFnZTogXCJzd2lmdFwiLFxuICAgICAgICAgIGxvY2F0aW9uOiB0aGlzLmxvY2F0aW9uKG5vZGUpLFxuICAgICAgICAgIG1lc3NhZ2U6IGBUcmVlLXNpdHRlciBleHBvc2VkIHJlY292ZXJ5IGF0ICcke25vZGUudHlwZX0nLmBcbiAgICAgICAgfSlcbiAgICAgIH1cbiAgICAgIGlmIChbXCJhdHRyaWJ1dGVcIiwgXCJkaXJlY3RpdmVcIiwgXCJzaGViYW5nX2xpbmVcIl0uaW5jbHVkZXMobm9kZS50eXBlKSkgdGhpcy5mYWlsKG5vZGUsIG5vZGUudHlwZSlcbiAgICAgIGlmIChub2RlLnR5cGUgPT0gXCJjb21tZW50XCIgJiYgL3N3aWZ0LXRvb2xzLXZlcnNpb24vdS50ZXN0KG5vZGUudGV4dCkpIHtcbiAgICAgICAgdGhpcy5mYWlsKG5vZGUsIFwiZGlyZWN0aXZlLWJlYXJpbmcgY29tbWVudFwiKVxuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBPbWl0cyBvbmx5IGluZXJ0IGNvbW1lbnRzIGFscmVhZHkgYWNjb3VudGVkIGZvciBieSBleGhhdXN0aXZlIHRyYXZlcnNhbC5cbiAgICogQHBhcmFtIHtpbXBvcnQoXCJ0cmVlLXNpdHRlclwiKS5TeW50YXhOb2RlfSBub2RlIC0gUGFyZW50IG5vZGUuXG4gICAqIEByZXR1cm5zIHtpbXBvcnQoXCJ0cmVlLXNpdHRlclwiKS5TeW50YXhOb2RlW119IFN0cnVjdHVyYWwgY2hpbGRyZW4uXG4gICAqL1xuICBwYXJ0cyhub2RlKSB7XG4gICAgcmV0dXJuIG5vZGUuY2hpbGRyZW4uZmlsdGVyKChjaGlsZCkgPT4gY2hpbGQudHlwZSAhPSBcImNvbW1lbnRcIilcbiAgfVxuXG4gIC8qKlxuICAgKiBSZXF1aXJlcyBvbmUgZXhhY3QgcGFyc2VyIGZpZWxkIGVkZ2UuXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwidHJlZS1zaXR0ZXJcIikuU3ludGF4Tm9kZX0gbm9kZSAtIEZpZWxkIG93bmVyLlxuICAgKiBAcGFyYW0ge3N0cmluZ30gbmFtZSAtIEZpZWxkIG5hbWUuXG4gICAqIEByZXR1cm5zIHtpbXBvcnQoXCJ0cmVlLXNpdHRlclwiKS5TeW50YXhOb2RlfSBTb2xlIGZpZWxkIG5vZGUuXG4gICAqL1xuICBmaWVsZChub2RlLCBuYW1lKSB7XG4gICAgY29uc3QgbWF0Y2hlcyA9IFtdXG5cbiAgICBmb3IgKGxldCBpbmRleCA9IDA7IGluZGV4IDwgbm9kZS5jaGlsZENvdW50OyBpbmRleCArPSAxKSB7XG4gICAgICBjb25zdCBjaGlsZCA9IG5vZGUuY2hpbGQoaW5kZXgpXG5cbiAgICAgIGlmICghY2hpbGQpIHRocm93IG5ldyBFcnJvcihgVHJlZS1zaXR0ZXIgb21pdHRlZCBjaGlsZCAke2luZGV4fSBvZiAke25vZGUudHlwZX0uYClcbiAgICAgIGlmIChub2RlLmZpZWxkTmFtZUZvckNoaWxkKGluZGV4KSA9PSBuYW1lKSBtYXRjaGVzLnB1c2goY2hpbGQpXG4gICAgfVxuICAgIGlmIChtYXRjaGVzLmxlbmd0aCAhPSAxKSB0aGlzLmZhaWwobm9kZSwgYGV4cGVjdGVkIG9uZSAnJHtuYW1lfScgZmllbGRgKVxuICAgIHJldHVybiBtYXRjaGVzWzBdXG4gIH1cblxuICAvKipcbiAgICogUmVxdWlyZXMgYWxsIG9yZGVyZWQgY2hpbGRyZW4sIGluY2x1ZGluZyBhbm9ueW1vdXMgcHVuY3R1YXRpb24uXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwidHJlZS1zaXR0ZXJcIikuU3ludGF4Tm9kZX0gbm9kZSAtIFNoYXBlIG93bmVyLlxuICAgKiBAcGFyYW0geyhpbXBvcnQoXCJ0cmVlLXNpdHRlclwiKS5TeW50YXhOb2RlIHwgc3RyaW5nKVtdfSBleHBlY3RlZCAtIEV4YWN0IGNoaWxkIHNlcXVlbmNlLlxuICAgKiBAcmV0dXJucyB7dm9pZH1cbiAgICovXG4gIHNoYXBlKG5vZGUsIGV4cGVjdGVkKSB7XG4gICAgY29uc3QgYWN0dWFsID0gdGhpcy5wYXJ0cyhub2RlKVxuXG4gICAgaWYgKGFjdHVhbC5sZW5ndGggIT0gZXhwZWN0ZWQubGVuZ3RoKSB0aGlzLmZhaWwoYWN0dWFsW01hdGgubWluKGFjdHVhbC5sZW5ndGgsIGV4cGVjdGVkLmxlbmd0aCldID8/IG5vZGUsIGAke25vZGUudHlwZX0gY2hpbGQgc2hhcGVgKVxuICAgIGZvciAobGV0IGluZGV4ID0gMDsgaW5kZXggPCBleHBlY3RlZC5sZW5ndGg7IGluZGV4ICs9IDEpIHtcbiAgICAgIGNvbnN0IHdhbnRlZCA9IGV4cGVjdGVkW2luZGV4XVxuICAgICAgY29uc3QgY2hpbGQgPSBhY3R1YWxbaW5kZXhdXG4gICAgICBjb25zdCBtYXRjaGVzID0gdHlwZW9mIHdhbnRlZCA9PSBcInN0cmluZ1wiID8gY2hpbGQudGV4dCA9PSB3YW50ZWQgOiBjaGlsZC5pZCA9PSB3YW50ZWQuaWRcblxuICAgICAgaWYgKCFtYXRjaGVzKSB0aGlzLmZhaWwoY2hpbGQsIGAke25vZGUudHlwZX0gY2hpbGQgc2hhcGVgKVxuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBWYWxpZGF0ZXMgb25lIFN3aWZ0IGlkZW50aWZpZXIgaW4gdGhlIHBvcnRhYmxlIHNvdXJjZSBwcm9maWxlLlxuICAgKiBAcGFyYW0ge2ltcG9ydChcInRyZWUtc2l0dGVyXCIpLlN5bnRheE5vZGV9IG5vZGUgLSBJZGVudGlmaWVyIHRva2VuLlxuICAgKiBAcGFyYW0ge2Jvb2xlYW59IFthbGxvd1ByaW50XSAtIFdoZXRoZXIgdGhlIGZpeGVkIHByaW50IHNjYWZmb2xkIGlzIGV4cGVjdGVkLlxuICAgKiBAcmV0dXJucyB7c3RyaW5nfSBBY2NlcHRlZCBzcGVsbGluZy5cbiAgICovXG4gIGlkZW50aWZpZXIobm9kZSwgYWxsb3dQcmludCA9IGZhbHNlKSB7XG4gICAgY29uc3QgbmFtZSA9IG5vZGUudGV4dFxuXG4gICAgaWYgKG5vZGUudHlwZSAhPSBcInNpbXBsZV9pZGVudGlmaWVyXCIgfHwgIShhbGxvd1ByaW50ICYmIG5hbWUgPT0gXCJwcmludFwiKSAmJlxuICAgICAgKCFpc1N3aWZ0SWRlbnRpZmllcihuYW1lKSB8fCBuYW1lLm5vcm1hbGl6ZShcIk5GQ1wiKSAhPSBuYW1lKSkgdGhpcy5mYWlsKG5vZGUsIFwicmVzZXJ2ZWQgb3IgdW5zdXBwb3J0ZWQgaWRlbnRpZmllclwiKVxuICAgIHJldHVybiBuYW1lXG4gIH1cblxuICAvKipcbiAgICogQ29udmVydHMgZXhhY3RseSBJbnQ2NCwgQm9vbCwgb3IgU3RyaW5nLlxuICAgKiBAcGFyYW0ge2ltcG9ydChcInRyZWUtc2l0dGVyXCIpLlN5bnRheE5vZGV9IG5vZGUgLSBUeXBlIG5vZGUuXG4gICAqIEByZXR1cm5zIHtpbXBvcnQoXCIuLi9zZW1hbnRpYy90eXBlcy5qc1wiKS5UeXBlUmVmZXJlbmNlfSBTZW1hbnRpYyBzY2FsYXIuXG4gICAqL1xuICB0eXBlKG5vZGUpIHtcbiAgICBjb25zdCBwYXJ0cyA9IHRoaXMucGFydHMobm9kZSlcblxuICAgIGlmIChub2RlLnR5cGUgIT0gXCJ1c2VyX3R5cGVcIiB8fCBwYXJ0cy5sZW5ndGggIT0gMSB8fCBwYXJ0c1swXS50eXBlICE9IFwidHlwZV9pZGVudGlmaWVyXCIpIHRoaXMuZmFpbChub2RlLCBcInNjYWxhciB0eXBlIHNoYXBlXCIpXG4gICAgdGhpcy5zaGFwZShub2RlLCBbcGFydHNbMF1dKVxuICAgIGNvbnN0IHR5cGUgPSBzb3VyY2VTY2FsYXJUeXBlKFwic3dpZnRcIiwgcGFydHNbMF0udGV4dCwgdGhpcy5sb2NhdGlvbihwYXJ0c1swXSkpXG5cbiAgICBpZiAoIXR5cGUpIHRoaXMuZmFpbChwYXJ0c1swXSwgYHVuc3VwcG9ydGVkIHNjYWxhciB0eXBlICcke3BhcnRzWzBdLnRleHR9J2ApXG4gICAgcmV0dXJuIHR5cGVcbiAgfVxuXG4gIC8qKlxuICAgKiBDb252ZXJ0cyBvbmUgZXhhY3Qgb3JkaW5hcnkgU3dpZnQgc3RyaW5nIGxpdGVyYWwuXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwidHJlZS1zaXR0ZXJcIikuU3ludGF4Tm9kZX0gbm9kZSAtIFN0cmluZyBub2RlLlxuICAgKiBAcmV0dXJucyB7c3RyaW5nfSBVbmljb2RlIHNjYWxhciB2YWx1ZS5cbiAgICovXG4gIHN0cmluZyhub2RlKSB7XG4gICAgY29uc3QgcGFydHMgPSB0aGlzLnBhcnRzKG5vZGUpXG5cbiAgICBpZiAobm9kZS50eXBlICE9IFwibGluZV9zdHJpbmdfbGl0ZXJhbFwiIHx8IHBhcnRzLmxlbmd0aCA8IDIgfHwgcGFydHNbMF0udGV4dCAhPSAnXCInIHx8IHBhcnRzLmF0KC0xKT8udGV4dCAhPSAnXCInKSB7XG4gICAgICByZXR1cm4gdGhpcy5mYWlsKG5vZGUsIFwib3JkaW5hcnkgbm9uaW50ZXJwb2xhdGVkIHN0cmluZyBsaXRlcmFsIHJlcXVpcmVkXCIpXG4gICAgfVxuICAgIHRoaXMuc2hhcGUobm9kZSwgWydcIicsIC4uLnBhcnRzLnNsaWNlKDEsIC0xKSwgJ1wiJ10pXG4gICAgbGV0IHZhbHVlID0gXCJcIlxuICAgIGNvbnN0IHNpbXBsZUVzY2FwZXMgPSBuZXcgTWFwKFtcbiAgICAgIFtcIlxcXFwwXCIsIFwiXFwwXCJdLCBbXCJcXFxcblwiLCBcIlxcblwiXSwgW1wiXFxcXHJcIiwgXCJcXHJcIl0sIFtcIlxcXFx0XCIsIFwiXFx0XCJdLCBbXCJcXFxcXFxcXFwiLCBcIlxcXFxcIl0sIFsnXFxcXFwiJywgJ1wiJ10sIFtcIlxcXFwnXCIsIFwiJ1wiXVxuICAgIF0pXG5cbiAgICBmb3IgKGNvbnN0IHBhcnQgb2YgcGFydHMuc2xpY2UoMSwgLTEpKSB7XG4gICAgICBpZiAocGFydC50eXBlID09IFwibGluZV9zdHJfdGV4dFwiKSB7XG4gICAgICAgIGlmICgvW1xcclxcbl0vdS50ZXN0KHBhcnQudGV4dCkpIHRoaXMuZmFpbChwYXJ0LCBcInN0cmluZyBsaW5lIHRlcm1pbmF0b3JcIilcbiAgICAgICAgdmFsdWUgKz0gcGFydC50ZXh0XG4gICAgICB9IGVsc2UgaWYgKHBhcnQudHlwZSA9PSBcInN0cl9lc2NhcGVkX2NoYXJcIikge1xuICAgICAgICBjb25zdCBlc2NhcGUgPSBwYXJ0LnRleHRcblxuICAgICAgICBpZiAoc2ltcGxlRXNjYXBlcy5oYXMoZXNjYXBlKSkgdmFsdWUgKz0gc2ltcGxlRXNjYXBlcy5nZXQoZXNjYXBlKVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICBjb25zdCBtYXRjaCA9IC9eXFxcXHVcXHsoWzAtOUEtRmEtZl17MSw4fSlcXH0kL3UuZXhlYyhlc2NhcGUpXG5cbiAgICAgICAgICBpZiAoIW1hdGNoKSB0aGlzLmZhaWwocGFydCwgXCJ1bnN1cHBvcnRlZCBzdHJpbmcgZXNjYXBlXCIpXG4gICAgICAgICAgY29uc3Qgc2NhbGFyID0gTnVtYmVyLnBhcnNlSW50KG1hdGNoWzFdLCAxNilcblxuICAgICAgICAgIGlmIChzY2FsYXIgPiAweDEwRkZGRiB8fCBzY2FsYXIgPj0gMHhEODAwICYmIHNjYWxhciA8PSAweERGRkYpIHRoaXMuZmFpbChwYXJ0LCBcIm5vbi1zY2FsYXIgVW5pY29kZSBlc2NhcGVcIilcbiAgICAgICAgICB2YWx1ZSArPSBTdHJpbmcuZnJvbUNvZGVQb2ludChzY2FsYXIpXG4gICAgICAgIH1cbiAgICAgIH0gZWxzZSB0aGlzLmZhaWwocGFydCwgcGFydC50eXBlID09IFwiaW50ZXJwb2xhdGVkX2V4cHJlc3Npb25cIiA/IFwiaW50ZXJwb2xhdGVkIHN0cmluZ1wiIDogXCJzdHJpbmcgY2hpbGRcIilcbiAgICB9XG4gICAgaWYgKCFoYXNPbmx5VW5pY29kZVNjYWxhcnModmFsdWUpKSB0aGlzLmZhaWwobm9kZSwgXCJpbnZhbGlkIFVuaWNvZGUgc3RyaW5nIGxpdGVyYWxcIilcbiAgICByZXR1cm4gdmFsdWVcbiAgfVxuXG4gIC8qKlxuICAgKiBSZWFkcyBleGFjdCB1bmxhYmVsZWQgY2FsbCBhcmd1bWVudHMuXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwidHJlZS1zaXR0ZXJcIikuU3ludGF4Tm9kZX0gc3VmZml4IC0gQ2FsbCBzdWZmaXguXG4gICAqIEByZXR1cm5zIHtpbXBvcnQoXCJ0cmVlLXNpdHRlclwiKS5TeW50YXhOb2RlW119IEFyZ3VtZW50IHZhbHVlIG5vZGVzLlxuICAgKi9cbiAgYXJndW1lbnRzKHN1ZmZpeCkge1xuICAgIGNvbnN0IHN1ZmZpeFBhcnRzID0gdGhpcy5wYXJ0cyhzdWZmaXgpXG5cbiAgICBpZiAoc3VmZml4LnR5cGUgIT0gXCJjYWxsX3N1ZmZpeFwiIHx8IHN1ZmZpeFBhcnRzLmxlbmd0aCAhPSAxIHx8IHN1ZmZpeFBhcnRzWzBdLnR5cGUgIT0gXCJ2YWx1ZV9hcmd1bWVudHNcIikge1xuICAgICAgcmV0dXJuIHRoaXMuZmFpbChzdWZmaXgsIFwiY2FsbCBzdWZmaXggc2hhcGVcIilcbiAgICB9XG4gICAgdGhpcy5zaGFwZShzdWZmaXgsIFtzdWZmaXhQYXJ0c1swXV0pXG4gICAgY29uc3QgbGlzdCA9IHN1ZmZpeFBhcnRzWzBdXG4gICAgY29uc3QgcGFydHMgPSB0aGlzLnBhcnRzKGxpc3QpXG5cbiAgICBpZiAocGFydHMubGVuZ3RoIDwgMiB8fCBwYXJ0c1swXS50ZXh0ICE9IFwiKFwiIHx8IHBhcnRzLmF0KC0xKT8udGV4dCAhPSBcIilcIikgdGhpcy5mYWlsKGxpc3QsIFwiY2FsbCBhcmd1bWVudCBsaXN0IHNoYXBlXCIpXG4gICAgY29uc3QgYXJndW1lbnRzXyA9IHBhcnRzLnNsaWNlKDEsIC0xKS5maWx0ZXIoKF9wYXJ0LCBpbmRleCkgPT4gaW5kZXggJSAyID09IDApXG4gICAgY29uc3QgZXhwZWN0ZWQgPSBbXCIoXCIsIC4uLmFyZ3VtZW50c18uZmxhdE1hcCgoYXJndW1lbnQsIGluZGV4KSA9PiBpbmRleCA9PSAwID8gW2FyZ3VtZW50XSA6IFtcIixcIiwgYXJndW1lbnRdKSwgXCIpXCJdXG5cbiAgICB0aGlzLnNoYXBlKGxpc3QsIGV4cGVjdGVkKVxuICAgIHJldHVybiBhcmd1bWVudHNfLm1hcCgoYXJndW1lbnQpID0+IHtcbiAgICAgIGNvbnN0IHZhbHVlID0gdGhpcy5maWVsZChhcmd1bWVudCwgXCJ2YWx1ZVwiKVxuXG4gICAgICBpZiAoYXJndW1lbnQudHlwZSAhPSBcInZhbHVlX2FyZ3VtZW50XCIpIHRoaXMuZmFpbChhcmd1bWVudCwgXCJ1bmxhYmVsZWQgYXJndW1lbnQgcmVxdWlyZWRcIilcbiAgICAgIHRoaXMuc2hhcGUoYXJndW1lbnQsIFt2YWx1ZV0pXG4gICAgICByZXR1cm4gdmFsdWVcbiAgICB9KVxuICB9XG5cbiAgLyoqXG4gICAqIENvbnZlcnRzIGEgZGlyZWN0IHNlbWFudGljIGNhbGwsIGluY2x1ZGluZyBxdWFsaWZpZWQgbmVnYXRlZC1jYWxsIGFuZCB0cmFpbGluZy1jYWxsIGJpbmFyeSBzaGFwZXMuXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwidHJlZS1zaXR0ZXJcIikuU3ludGF4Tm9kZX0gbm9kZSAtIENhbGwgbm9kZS5cbiAgICogQHJldHVybnMge2ltcG9ydChcIi4uL3NlbWFudGljL3R5cGVzLmpzXCIpLkV4cHJlc3Npb259IFNlbWFudGljIGV4cHJlc3Npb24uXG4gICAqL1xuICBjYWxsKG5vZGUpIHtcbiAgICBjb25zdCBsb2NhdGlvbiA9IHRoaXMubG9jYXRpb24obm9kZSlcbiAgICBjb25zdCBwYXJ0cyA9IHRoaXMucGFydHMobm9kZSlcblxuICAgIGlmIChub2RlLnR5cGUgIT0gXCJjYWxsX2V4cHJlc3Npb25cIiB8fCBwYXJ0cy5sZW5ndGggIT0gMikgdGhpcy5mYWlsKG5vZGUsIFwiZGlyZWN0IGNhbGwgc2hhcGVcIilcbiAgICBjb25zdCB0YXJnZXQgPSBwYXJ0c1swXVxuICAgIGNvbnN0IHN1ZmZpeCA9IHBhcnRzWzFdXG5cbiAgICBpZiAoYmluYXJ5Tm9kZU9wZXJhdG9ycy5oYXModGFyZ2V0LnR5cGUpKSB7XG4gICAgICBjb25zdCByaWdodCA9IHRoaXMuZmllbGQodGFyZ2V0LCBcInJoc1wiKVxuICAgICAgY29uc3QgY2FsbExvY2F0aW9uID0gbG9jYXRpb25Gcm9tT2Zmc2V0cyh0aGlzLmZpbGVuYW1lLCB0aGlzLnNvdXJjZSxcbiAgICAgICAgYmluZGluZ0luZGV4VG9VdGYxNk9mZnNldCh0aGlzLnNvdXJjZSwgcmlnaHQuc3RhcnRJbmRleCksIGJpbmRpbmdJbmRleFRvVXRmMTZPZmZzZXQodGhpcy5zb3VyY2UsIHN1ZmZpeC5lbmRJbmRleCkpXG5cbiAgICAgIGlmIChyaWdodC50eXBlICE9IFwic2ltcGxlX2lkZW50aWZpZXJcIikgdGhpcy5mYWlsKG5vZGUsIFwidHJhaWxpbmcgZGlyZWN0IGNhbGwgc2hhcGVcIilcbiAgICAgIHRoaXMuc2hhcGUobm9kZSwgW3RhcmdldCwgc3VmZml4XSlcblxuICAgICAgcmV0dXJuIHRoaXMuYmluYXJ5KHRhcmdldCwgdW5kZWZpbmVkLCBsb2NhdGlvbiwgdGhpcy5jYWxsUGFydHMocmlnaHQsIHN1ZmZpeCwgY2FsbExvY2F0aW9uKSlcbiAgICB9XG5cbiAgICByZXR1cm4gdGhpcy5jYWxsUGFydHModGFyZ2V0LCBzdWZmaXgsIGxvY2F0aW9uKVxuICB9XG5cbiAgLyoqXG4gICAqIENvbnZlcnRzIG9uZSBkaXJlY3QgY2FsbCBmcm9tIGl0cyBwYXJzZXIgdGFyZ2V0IGFuZCBzdWZmaXguXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwidHJlZS1zaXR0ZXJcIikuU3ludGF4Tm9kZX0gdGFyZ2V0IC0gRGlyZWN0IGNhbGwgdGFyZ2V0LlxuICAgKiBAcGFyYW0ge2ltcG9ydChcInRyZWUtc2l0dGVyXCIpLlN5bnRheE5vZGV9IHN1ZmZpeCAtIEFyZ3VtZW50IHN1ZmZpeC5cbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuLi9zZW1hbnRpYy90eXBlcy5qc1wiKS5Tb3VyY2VMb2NhdGlvbn0gbG9jYXRpb24gLSBDb21wbGV0ZSBjYWxsIGxvY2F0aW9uLlxuICAgKiBAcmV0dXJucyB7aW1wb3J0KFwiLi4vc2VtYW50aWMvdHlwZXMuanNcIikuRXhwcmVzc2lvbn0gU2VtYW50aWMgY2FsbCBvciBwcmVmaXhlZCBjYWxsLlxuICAgKi9cbiAgY2FsbFBhcnRzKHRhcmdldCwgc3VmZml4LCBsb2NhdGlvbikge1xuICAgIGNvbnN0IGFyZ3VtZW50Tm9kZXMgPSB0aGlzLmFyZ3VtZW50cyhzdWZmaXgpXG4gICAgbGV0IG5hbWVOb2RlID0gdGFyZ2V0XG4gICAgLyoqIEB0eXBlIHtpbXBvcnQoXCJ0cmVlLXNpdHRlclwiKS5TeW50YXhOb2RlIHwgdW5kZWZpbmVkfSAqL1xuICAgIGxldCB1bmFyeU9wZXJhdG9yXG5cbiAgICBpZiAoW1wiIVwiLCBcIi1cIl0uaW5jbHVkZXMobmFtZU5vZGUudGV4dCkpIHtcbiAgICAgIGlmIChhcmd1bWVudE5vZGVzLmxlbmd0aCAhPSAxKSB0aGlzLmZhaWwodGFyZ2V0LCBcInBhcmVudGhlc2l6ZWQgdW5hcnkgZXhwcmVzc2lvbiBzaGFwZVwiKVxuICAgICAgY29uc3QgZXhwcmVzc2lvbiA9IHRoaXMuZXhwcmVzc2lvbihhcmd1bWVudE5vZGVzWzBdKVxuXG4gICAgICByZXR1cm4gLyoqIEB0eXBlIHtpbXBvcnQoXCIuLi9zZW1hbnRpYy90eXBlcy5qc1wiKS5FeHByZXNzaW9ufSAqLyAoLyoqIEB0eXBlIHt1bmtub3dufSAqLyAod2l0aEFkYXB0ZWRPcGVyYXRpb24od2l0aFBhcnNlclJhbmdlcyh7XG4gICAgICAgIGtpbmQ6IFwiVW5hcnlFeHByZXNzaW9uXCIsIGxvY2F0aW9uLCBvcGVyYW5kOiBleHByZXNzaW9uXG4gICAgICB9LCB7b3BlcmF0b3I6IHRoaXMubG9jYXRpb24obmFtZU5vZGUpfSksIG5hbWVOb2RlLnRleHQgPT0gXCItXCIgPyBcIk5lZ2F0ZVwiIDogXCJOb3RcIikpKVxuICAgIH1cbiAgICBpZiAobmFtZU5vZGUudHlwZSA9PSBcInByZWZpeF9leHByZXNzaW9uXCIpIHtcbiAgICAgIGNvbnN0IG9wZXJhdGlvbiA9IHRoaXMuZmllbGQobmFtZU5vZGUsIFwib3BlcmF0aW9uXCIpXG4gICAgICBjb25zdCB0YXJnZXQgPSB0aGlzLmZpZWxkKG5hbWVOb2RlLCBcInRhcmdldFwiKVxuXG4gICAgICB0aGlzLnNoYXBlKG5hbWVOb2RlLCBbb3BlcmF0aW9uLCB0YXJnZXRdKVxuICAgICAgaWYgKCFbXCIhXCIsIFwiLVwiXS5pbmNsdWRlcyhvcGVyYXRpb24udGV4dCkgfHwgdGFyZ2V0LnR5cGUgIT0gXCJzaW1wbGVfaWRlbnRpZmllclwiKSB0aGlzLmZhaWwobmFtZU5vZGUsIFwicHJlZml4ZWQgZGlyZWN0IGNhbGwgc2hhcGVcIilcbiAgICAgIHVuYXJ5T3BlcmF0b3IgPSBvcGVyYXRpb25cbiAgICAgIG5hbWVOb2RlID0gdGFyZ2V0XG4gICAgfVxuICAgIGNvbnN0IG5hbWUgPSBuYW1lTm9kZS50ZXh0XG5cbiAgICBjb25zdCBoZWxwZXJPcGVyYXRpb24gPSB0aGlzLmhlbHBlcnMuaGFzKG5hbWUpID8gaGVscGVyT3BlcmF0aW9ucy5nZXQobmFtZSkgOiB1bmRlZmluZWRcblxuICAgIGlmIChoZWxwZXJPcGVyYXRpb24pIHtcbiAgICAgIGlmICh1bmFyeU9wZXJhdG9yIHx8IGFyZ3VtZW50Tm9kZXMubGVuZ3RoICE9IDIpIHRoaXMuZmFpbCh0YXJnZXQsIFwiU3dpZnQgc2NhbGFyIGVxdWFsaXR5IGhlbHBlciBzaGFwZVwiKVxuICAgICAgcmV0dXJuIC8qKiBAdHlwZSB7aW1wb3J0KFwiLi4vc2VtYW50aWMvdHlwZXMuanNcIikuRXhwcmVzc2lvbn0gKi8gKHdpdGhBZGFwdGVkT3BlcmF0aW9uKHdpdGhQYXJzZXJSYW5nZXMoe1xuICAgICAgICBraW5kOiBcIkJpbmFyeUV4cHJlc3Npb25cIiwgbGVmdDogdGhpcy5leHByZXNzaW9uKGFyZ3VtZW50Tm9kZXNbMF0pLCBsb2NhdGlvbiwgcmlnaHQ6IHRoaXMuZXhwcmVzc2lvbihhcmd1bWVudE5vZGVzWzFdKVxuICAgICAgfSwge29wZXJhdG9yOiB0aGlzLmxvY2F0aW9uKG5hbWVOb2RlKX0pLCBoZWxwZXJPcGVyYXRpb24pKVxuICAgIH1cbiAgICBjb25zdCBzZW1hbnRpY05hbWUgPSB0aGlzLmlkZW50aWZpZXIobmFtZU5vZGUpXG5cbiAgICBpZiAoYXJndW1lbnROb2Rlcy5sZW5ndGggIT0gMikgdGhpcy5mYWlsKHN1ZmZpeCwgXCJzZW1hbnRpYyBjYWxsIGFyZ3VtZW50IGNvdW50XCIpXG4gICAgY29uc3QgY2FsbCA9IHdpdGhQYXJzZXJSYW5nZXMoe1xuICAgICAgYXJndW1lbnRzOiBhcmd1bWVudE5vZGVzLm1hcCgoYXJndW1lbnQpID0+IHRoaXMuZXhwcmVzc2lvbihhcmd1bWVudCkpLFxuICAgICAgY2FsbGVlOiBzZW1hbnRpY05hbWUsXG4gICAgICBraW5kOiAvKiogQHR5cGUge2NvbnN0fSAqLyAoXCJDYWxsRXhwcmVzc2lvblwiKSxcbiAgICAgIGxvY2F0aW9uXG4gICAgfSwge2NhbGxlZTogdGhpcy5sb2NhdGlvbihuYW1lTm9kZSl9KVxuXG4gICAgaWYgKCF1bmFyeU9wZXJhdG9yKSByZXR1cm4gY2FsbFxuICAgIHJldHVybiAvKiogQHR5cGUge2ltcG9ydChcIi4uL3NlbWFudGljL3R5cGVzLmpzXCIpLkV4cHJlc3Npb259ICovICgvKiogQHR5cGUge3Vua25vd259ICovICh3aXRoQWRhcHRlZE9wZXJhdGlvbih3aXRoUGFyc2VyUmFuZ2VzKHtcbiAgICAgIGtpbmQ6IFwiVW5hcnlFeHByZXNzaW9uXCIsIGxvY2F0aW9uLCBvcGVyYW5kOiBjYWxsXG4gICAgfSwge29wZXJhdG9yOiB0aGlzLmxvY2F0aW9uKHVuYXJ5T3BlcmF0b3IpfSksIHVuYXJ5T3BlcmF0b3IudGV4dCA9PSBcIi1cIiA/IFwiTmVnYXRlXCIgOiBcIk5vdFwiKSkpXG4gIH1cblxuICAvKipcbiAgICogQ29udmVydHMgb25lIHN1cHBvcnRlZCBzY2FsYXIgZXhwcmVzc2lvbi5cbiAgICogQHBhcmFtIHtpbXBvcnQoXCJ0cmVlLXNpdHRlclwiKS5TeW50YXhOb2RlfSBub2RlIC0gRXhwcmVzc2lvbiBub2RlLlxuICAgKiBAcmV0dXJucyB7aW1wb3J0KFwiLi4vc2VtYW50aWMvdHlwZXMuanNcIikuRXhwcmVzc2lvbn0gU2VtYW50aWMgZXhwcmVzc2lvbi5cbiAgICovXG4gIGV4cHJlc3Npb24obm9kZSkge1xuICAgIGNvbnN0IGxvY2F0aW9uID0gdGhpcy5sb2NhdGlvbihub2RlKVxuXG4gICAgaWYgKG5vZGUudHlwZSA9PSBcInNpbXBsZV9pZGVudGlmaWVyXCIpIHtcbiAgICAgIHJldHVybiB3aXRoUGFyc2VyUmFuZ2VzKHtraW5kOiAvKiogQHR5cGUge2NvbnN0fSAqLyAoXCJJZGVudGlmaWVyRXhwcmVzc2lvblwiKSwgbG9jYXRpb24sIG5hbWU6IHRoaXMuaWRlbnRpZmllcihub2RlKX0sIHtuYW1lOiBsb2NhdGlvbn0pXG4gICAgfVxuICAgIGlmIChub2RlLnR5cGUgPT0gXCJpbnRlZ2VyX2xpdGVyYWxcIikge1xuICAgICAgaWYgKCEvXig/OjB8WzEtOV1bMC05XSopJC91LnRlc3Qobm9kZS50ZXh0KSkgdGhpcy5mYWlsKG5vZGUsIFwibm9uY2Fub25pY2FsIGludGVnZXIgbGl0ZXJhbFwiKVxuICAgICAgY29uc3QgdmFsdWUgPSBOdW1iZXIoQmlnSW50KG5vZGUudGV4dCkpXG5cbiAgICAgIGlmICghTnVtYmVyLmlzU2FmZUludGVnZXIodmFsdWUpKSB0aGlzLmZhaWwobm9kZSwgXCJub24tc2FmZSBpbnRlZ2VyIGxpdGVyYWxcIilcbiAgICAgIHJldHVybiB3aXRoUGFyc2VyUmFuZ2VzKHtraW5kOiAvKiogQHR5cGUge2NvbnN0fSAqLyAoXCJJbnRlZ2VyTGl0ZXJhbFwiKSwgbG9jYXRpb24sIHZhbHVlfSwge2xpdGVyYWw6IGxvY2F0aW9ufSlcbiAgICB9XG4gICAgaWYgKG5vZGUudHlwZSA9PSBcImJvb2xlYW5fbGl0ZXJhbFwiKSB7XG4gICAgICBjb25zdCBwYXJ0cyA9IHRoaXMucGFydHMobm9kZSlcblxuICAgICAgaWYgKHBhcnRzLmxlbmd0aCAhPSAxIHx8ICFbXCJ0cnVlXCIsIFwiZmFsc2VcIl0uaW5jbHVkZXMocGFydHNbMF0udGV4dCkpIHRoaXMuZmFpbChub2RlLCBcIkJvb2xlYW4gbGl0ZXJhbCBzaGFwZVwiKVxuICAgICAgdGhpcy5zaGFwZShub2RlLCBbcGFydHNbMF0udGV4dF0pXG4gICAgICByZXR1cm4gd2l0aFBhcnNlclJhbmdlcyh7a2luZDogLyoqIEB0eXBlIHtjb25zdH0gKi8gKFwiQm9vbGVhbkxpdGVyYWxcIiksIGxvY2F0aW9uLCB2YWx1ZTogcGFydHNbMF0udGV4dCA9PSBcInRydWVcIn0sIHtsaXRlcmFsOiBsb2NhdGlvbn0pXG4gICAgfVxuICAgIGlmIChub2RlLnR5cGUgPT0gXCJsaW5lX3N0cmluZ19saXRlcmFsXCIpIHtcbiAgICAgIHJldHVybiB3aXRoUGFyc2VyUmFuZ2VzKHtraW5kOiAvKiogQHR5cGUge2NvbnN0fSAqLyAoXCJTdHJpbmdMaXRlcmFsXCIpLCBsb2NhdGlvbiwgdmFsdWU6IHRoaXMuc3RyaW5nKG5vZGUpfSwge2xpdGVyYWw6IGxvY2F0aW9ufSlcbiAgICB9XG4gICAgaWYgKG5vZGUudHlwZSA9PSBcInR1cGxlX2V4cHJlc3Npb25cIikge1xuICAgICAgY29uc3QgdmFsdWUgPSB0aGlzLmZpZWxkKG5vZGUsIFwidmFsdWVcIilcblxuICAgICAgdGhpcy5zaGFwZShub2RlLCBbXCIoXCIsIHZhbHVlLCBcIilcIl0pXG4gICAgICByZXR1cm4gdGhpcy5leHByZXNzaW9uKHZhbHVlKVxuICAgIH1cbiAgICBpZiAobm9kZS50eXBlID09IFwicHJlZml4X2V4cHJlc3Npb25cIikge1xuICAgICAgY29uc3Qgb3BlcmF0aW9uID0gdGhpcy5maWVsZChub2RlLCBcIm9wZXJhdGlvblwiKVxuICAgICAgY29uc3QgdGFyZ2V0ID0gdGhpcy5maWVsZChub2RlLCBcInRhcmdldFwiKVxuXG4gICAgICB0aGlzLnNoYXBlKG5vZGUsIFtvcGVyYXRpb24sIHRhcmdldF0pXG4gICAgICBpZiAoIVtcIi1cIiwgXCIhXCJdLmluY2x1ZGVzKG9wZXJhdGlvbi50ZXh0KSkgdGhpcy5mYWlsKG9wZXJhdGlvbiwgXCJ1bmFyeSBvcGVyYXRvclwiKVxuICAgICAgcmV0dXJuIHRoaXMucHJlZml4ZWQob3BlcmF0aW9uLCB0YXJnZXQpXG4gICAgfVxuICAgIGNvbnN0IGFjY2VwdGVkT3BlcmF0b3JzID0gYmluYXJ5Tm9kZU9wZXJhdG9ycy5nZXQobm9kZS50eXBlKVxuXG4gICAgaWYgKGFjY2VwdGVkT3BlcmF0b3JzKSB7XG4gICAgICByZXR1cm4gdGhpcy5iaW5hcnkobm9kZSlcbiAgICB9XG4gICAgaWYgKG5vZGUudHlwZSA9PSBcImNhbGxfZXhwcmVzc2lvblwiKSByZXR1cm4gdGhpcy5jYWxsKG5vZGUpXG4gICAgcmV0dXJuIHRoaXMuZmFpbChub2RlKVxuICB9XG5cbiAgLyoqXG4gICAqIENvbnZlcnRzIHRoZSBncmFtbWFyJ3MgYnJvYWQgcHJlZml4IHRhcmdldCB3aXRoIFN3aWZ0J3MgdGlnaHRlciBwcmVmaXggcHJlY2VkZW5jZS5cbiAgICogQHBhcmFtIHtpbXBvcnQoXCJ0cmVlLXNpdHRlclwiKS5TeW50YXhOb2RlfSBvcGVyYXRvciAtIFByZWZpeCBvcGVyYXRvci5cbiAgICogQHBhcmFtIHtpbXBvcnQoXCJ0cmVlLXNpdHRlclwiKS5TeW50YXhOb2RlfSB0YXJnZXQgLSBHcmFtbWFyIHRhcmdldC5cbiAgICogQHJldHVybnMge2ltcG9ydChcIi4uL3NlbWFudGljL3R5cGVzLmpzXCIpLkV4cHJlc3Npb259IFNlbWFudGljIGV4cHJlc3Npb24uXG4gICAqL1xuICBwcmVmaXhlZChvcGVyYXRvciwgdGFyZ2V0KSB7XG4gICAgY29uc3QgbG9jYXRpb24gPSBsb2NhdGlvbkZyb21PZmZzZXRzKHRoaXMuZmlsZW5hbWUsIHRoaXMuc291cmNlLFxuICAgICAgYmluZGluZ0luZGV4VG9VdGYxNk9mZnNldCh0aGlzLnNvdXJjZSwgb3BlcmF0b3Iuc3RhcnRJbmRleCksIGJpbmRpbmdJbmRleFRvVXRmMTZPZmZzZXQodGhpcy5zb3VyY2UsIHRhcmdldC5lbmRJbmRleCkpXG5cbiAgICBpZiAoYmluYXJ5Tm9kZU9wZXJhdG9ycy5oYXModGFyZ2V0LnR5cGUpKSB7XG4gICAgICBjb25zdCBsZWZ0ID0gdGhpcy5maWVsZCh0YXJnZXQsIFwibGhzXCIpXG5cbiAgICAgIHJldHVybiB0aGlzLmJpbmFyeSh0YXJnZXQsIHRoaXMucHJlZml4ZWQob3BlcmF0b3IsIGxlZnQpLCBsb2NhdGlvbilcbiAgICB9XG5cbiAgICByZXR1cm4gLyoqIEB0eXBlIHtpbXBvcnQoXCIuLi9zZW1hbnRpYy90eXBlcy5qc1wiKS5FeHByZXNzaW9ufSAqLyAoLyoqIEB0eXBlIHt1bmtub3dufSAqLyAod2l0aEFkYXB0ZWRPcGVyYXRpb24od2l0aFBhcnNlclJhbmdlcyh7XG4gICAgICBraW5kOiBcIlVuYXJ5RXhwcmVzc2lvblwiLCBsb2NhdGlvbiwgb3BlcmFuZDogdGhpcy5leHByZXNzaW9uKHRhcmdldClcbiAgICB9LCB7b3BlcmF0b3I6IHRoaXMubG9jYXRpb24ob3BlcmF0b3IpfSksIG9wZXJhdG9yLnRleHQgPT0gXCItXCIgPyBcIk5lZ2F0ZVwiIDogXCJOb3RcIikpKVxuICB9XG5cbiAgLyoqXG4gICAqIENvbnZlcnRzIG9uZSBxdWFsaWZpZWQgYmluYXJ5IG5vZGUsIG9wdGlvbmFsbHkgcmVwbGFjaW5nIGl0cyBsZWZ0IGVkZ2UgZm9yIHByZWZpeCBwcmVjZWRlbmNlLlxuICAgKiBAcGFyYW0ge2ltcG9ydChcInRyZWUtc2l0dGVyXCIpLlN5bnRheE5vZGV9IG5vZGUgLSBCaW5hcnkgbm9kZS5cbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuLi9zZW1hbnRpYy90eXBlcy5qc1wiKS5FeHByZXNzaW9ufSBbbGVmdEV4cHJlc3Npb25dIC0gQWRhcHRlZCBsZWZ0IG9wZXJhbmQuXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vc2VtYW50aWMvdHlwZXMuanNcIikuU291cmNlTG9jYXRpb259IFtsb2NhdGlvbl0gLSBBZGFwdGVkIGV4cHJlc3Npb24gcmFuZ2UuXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vc2VtYW50aWMvdHlwZXMuanNcIikuRXhwcmVzc2lvbn0gW3JpZ2h0RXhwcmVzc2lvbl0gLSBBZGFwdGVkIHRyYWlsaW5nLWNhbGwgcmlnaHQgb3BlcmFuZC5cbiAgICogQHJldHVybnMge2ltcG9ydChcIi4uL3NlbWFudGljL3R5cGVzLmpzXCIpLkV4cHJlc3Npb259IFNlbWFudGljIGV4cHJlc3Npb24uXG4gICAqL1xuICBiaW5hcnkobm9kZSwgbGVmdEV4cHJlc3Npb24sIGxvY2F0aW9uID0gdGhpcy5sb2NhdGlvbihub2RlKSwgcmlnaHRFeHByZXNzaW9uKSB7XG4gICAgY29uc3QgYWNjZXB0ZWRPcGVyYXRvcnMgPSBiaW5hcnlOb2RlT3BlcmF0b3JzLmdldChub2RlLnR5cGUpXG4gICAgY29uc3QgbGVmdCA9IHRoaXMuZmllbGQobm9kZSwgXCJsaHNcIilcbiAgICBjb25zdCBvcGVyYXRvciA9IHRoaXMuZmllbGQobm9kZSwgXCJvcFwiKVxuICAgIGNvbnN0IHJpZ2h0ID0gdGhpcy5maWVsZChub2RlLCBcInJoc1wiKVxuICAgIGNvbnN0IG9wZXJhdGlvbiA9IGJpbmFyeU9wZXJhdGlvbnMuZ2V0KG9wZXJhdG9yLnRleHQpXG5cbiAgICB0aGlzLnNoYXBlKG5vZGUsIFtsZWZ0LCBvcGVyYXRvciwgcmlnaHRdKVxuICAgIGlmICghYWNjZXB0ZWRPcGVyYXRvcnM/LmhhcyhvcGVyYXRvci50ZXh0KSB8fCAhb3BlcmF0aW9uKSB0aGlzLmZhaWwob3BlcmF0b3IsIFwidW5zdXBwb3J0ZWQgYmluYXJ5IG9wZXJhdG9yXCIpXG4gICAgY29uc3QgZXhwcmVzc2lvbiA9IC8qKiBAdHlwZSB7aW1wb3J0KFwiLi4vc2VtYW50aWMvdHlwZXMuanNcIikuRXhwcmVzc2lvbn0gKi8gKC8qKiBAdHlwZSB7dW5rbm93bn0gKi8gKHdpdGhBZGFwdGVkT3BlcmF0aW9uKHdpdGhQYXJzZXJSYW5nZXMoe1xuICAgICAga2luZDogXCJCaW5hcnlFeHByZXNzaW9uXCIsIGxlZnQ6IGxlZnRFeHByZXNzaW9uID8/IHRoaXMuZXhwcmVzc2lvbihsZWZ0KSwgbG9jYXRpb24sIHJpZ2h0OiByaWdodEV4cHJlc3Npb24gPz8gdGhpcy5leHByZXNzaW9uKHJpZ2h0KVxuICAgIH0sIHtvcGVyYXRvcjogdGhpcy5sb2NhdGlvbihvcGVyYXRvcil9KSwgLyoqIEB0eXBlIHtpbXBvcnQoXCIuLi9zZW1hbnRpYy9vcGVyYXRvcnMuanNcIikuQWRhcHRlZE9wZXJhdGlvbn0gKi8gKG9wZXJhdGlvbikpKSlcblxuICAgIGlmIChbXCI9PVwiLCBcIiE9XCJdLmluY2x1ZGVzKG9wZXJhdG9yLnRleHQpKSB0aGlzLm5hdGl2ZUVxdWFsaXR5T3BlcmF0b3JzLnNldChleHByZXNzaW9uLCBvcGVyYXRvcilcbiAgICByZXR1cm4gZXhwcmVzc2lvblxuICB9XG5cbiAgLyoqXG4gICAqIENvbnZlcnRzIG9uZSBleHBsaWNpdGx5IHR5cGVkIGluaXRpYWxpemVkIGxvY2FsLlxuICAgKiBAcGFyYW0ge2ltcG9ydChcInRyZWUtc2l0dGVyXCIpLlN5bnRheE5vZGV9IG5vZGUgLSBQcm9wZXJ0eSBkZWNsYXJhdGlvbi5cbiAgICogQHJldHVybnMge2ltcG9ydChcIi4uL3NlbWFudGljL3R5cGVzLmpzXCIpLkxvY2FsRGVjbGFyYXRpb259IFNlbWFudGljIGxvY2FsLlxuICAgKi9cbiAgbG9jYWwobm9kZSkge1xuICAgIGNvbnN0IGxvY2F0aW9uID0gdGhpcy5sb2NhdGlvbihub2RlKVxuICAgIGNvbnN0IHBhcnRzID0gdGhpcy5wYXJ0cyhub2RlKVxuICAgIGNvbnN0IGJpbmRpbmcgPSBwYXJ0cy5maW5kKChjaGlsZCkgPT4gY2hpbGQudHlwZSA9PSBcInZhbHVlX2JpbmRpbmdfcGF0dGVyblwiKVxuICAgIGNvbnN0IHBhdHRlcm4gPSBub2RlLmNoaWxkRm9yRmllbGROYW1lKFwibmFtZVwiKVxuICAgIGNvbnN0IGFubm90YXRpb24gPSBwYXJ0cy5maW5kKChjaGlsZCkgPT4gY2hpbGQudHlwZSA9PSBcInR5cGVfYW5ub3RhdGlvblwiKVxuICAgIGNvbnN0IHZhbHVlID0gbm9kZS5jaGlsZEZvckZpZWxkTmFtZShcInZhbHVlXCIpXG5cbiAgICBpZiAoIWFubm90YXRpb24pIHJldHVybiBtaXNzaW5nVHlwZShcInN3aWZ0XCIsIFwiTG9jYWxcIiwgbG9jYXRpb24pXG4gICAgaWYgKCFiaW5kaW5nIHx8ICFwYXR0ZXJuIHx8ICF2YWx1ZSB8fCBwYXR0ZXJuLnR5cGUgIT0gXCJwYXR0ZXJuXCIpIHRoaXMuZmFpbChub2RlLCBcImxvY2FsIGRlY2xhcmF0aW9uIHNoYXBlXCIpXG4gICAgY29uc3QgYmluZGluZ1BhcnRzID0gdGhpcy5wYXJ0cyhiaW5kaW5nKVxuICAgIGNvbnN0IG5hbWVOb2RlID0gcGF0dGVybi5jaGlsZEZvckZpZWxkTmFtZShcImJvdW5kX2lkZW50aWZpZXJcIilcbiAgICBjb25zdCBhbm5vdGF0aW9uUGFydHMgPSB0aGlzLnBhcnRzKGFubm90YXRpb24pXG5cbiAgICBpZiAoYmluZGluZ1BhcnRzLmxlbmd0aCAhPSAxIHx8ICFbXCJsZXRcIiwgXCJ2YXJcIl0uaW5jbHVkZXMoYmluZGluZ1BhcnRzWzBdLnRleHQpIHx8ICFuYW1lTm9kZSB8fCBhbm5vdGF0aW9uUGFydHMubGVuZ3RoICE9IDIpIHtcbiAgICAgIHRoaXMuZmFpbChub2RlLCBcImxvY2FsIGRlY2xhcmF0aW9uIHNoYXBlXCIpXG4gICAgfVxuICAgIHRoaXMuc2hhcGUoYmluZGluZywgW2JpbmRpbmdQYXJ0c1swXS50ZXh0XSlcbiAgICB0aGlzLnNoYXBlKHBhdHRlcm4sIFtuYW1lTm9kZV0pXG4gICAgdGhpcy5zaGFwZShhbm5vdGF0aW9uLCBbXCI6XCIsIGFubm90YXRpb25QYXJ0c1sxXV0pXG4gICAgdGhpcy5zaGFwZShub2RlLCBbYmluZGluZywgcGF0dGVybiwgYW5ub3RhdGlvbiwgXCI9XCIsIHZhbHVlXSlcbiAgICBjb25zdCBuYW1lID0gdGhpcy5pZGVudGlmaWVyKG5hbWVOb2RlKVxuXG4gICAgcmV0dXJuIHdpdGhQYXJzZXJSYW5nZXMoe1xuICAgICAgaW5pdGlhbGl6ZXI6IHRoaXMuZXhwcmVzc2lvbih2YWx1ZSksXG4gICAgICBraW5kOiAvKiogQHR5cGUge2NvbnN0fSAqLyAoXCJMb2NhbERlY2xhcmF0aW9uXCIpLFxuICAgICAgbG9jYXRpb24sXG4gICAgICBtdXRhYmxlOiBiaW5kaW5nUGFydHNbMF0udGV4dCA9PSBcInZhclwiLFxuICAgICAgbmFtZSxcbiAgICAgIHR5cGU6IHRoaXMudHlwZShhbm5vdGF0aW9uUGFydHNbMV0pXG4gICAgfSwge25hbWU6IHRoaXMubG9jYXRpb24obmFtZU5vZGUpLCBvcGVyYXRvcjogdGhpcy5sb2NhdGlvbihwYXJ0c1szXSl9KVxuICB9XG5cbiAgLyoqXG4gICAqIENvbnZlcnRzIG9uZSBwbGFpbiBpZGVudGlmaWVyIGFzc2lnbm1lbnQuXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwidHJlZS1zaXR0ZXJcIikuU3ludGF4Tm9kZX0gbm9kZSAtIEFzc2lnbm1lbnQgbm9kZS5cbiAgICogQHJldHVybnMge2ltcG9ydChcIi4uL3NlbWFudGljL3R5cGVzLmpzXCIpLkFzc2lnbm1lbnRTdGF0ZW1lbnR9IFNlbWFudGljIGFzc2lnbm1lbnQuXG4gICAqL1xuICBhc3NpZ25tZW50KG5vZGUpIHtcbiAgICBjb25zdCB0YXJnZXQgPSB0aGlzLmZpZWxkKG5vZGUsIFwidGFyZ2V0XCIpXG4gICAgY29uc3Qgb3BlcmF0b3IgPSB0aGlzLmZpZWxkKG5vZGUsIFwib3BlcmF0b3JcIilcbiAgICBjb25zdCB2YWx1ZSA9IHRoaXMuZmllbGQobm9kZSwgXCJyZXN1bHRcIilcbiAgICBjb25zdCB0YXJnZXRQYXJ0cyA9IHRoaXMucGFydHModGFyZ2V0KVxuXG4gICAgaWYgKHRhcmdldC50eXBlICE9IFwiZGlyZWN0bHlfYXNzaWduYWJsZV9leHByZXNzaW9uXCIgfHwgdGFyZ2V0UGFydHMubGVuZ3RoICE9IDEgfHwgb3BlcmF0b3IudGV4dCAhPSBcIj1cIikge1xuICAgICAgdGhpcy5mYWlsKG5vZGUsIFwiYXNzaWdubWVudCBzaGFwZVwiKVxuICAgIH1cbiAgICB0aGlzLnNoYXBlKHRhcmdldCwgW3RhcmdldFBhcnRzWzBdXSlcbiAgICB0aGlzLnNoYXBlKG5vZGUsIFt0YXJnZXQsIG9wZXJhdG9yLCB2YWx1ZV0pXG4gICAgY29uc3QgbmFtZSA9IHRoaXMuaWRlbnRpZmllcih0YXJnZXRQYXJ0c1swXSlcbiAgICBjb25zdCB0YXJnZXRMb2NhdGlvbiA9IHRoaXMubG9jYXRpb24odGFyZ2V0UGFydHNbMF0pXG5cbiAgICByZXR1cm4gd2l0aFBhcnNlclJhbmdlcyh7XG4gICAgICBleHByZXNzaW9uOiB0aGlzLmV4cHJlc3Npb24odmFsdWUpLFxuICAgICAga2luZDogLyoqIEB0eXBlIHtjb25zdH0gKi8gKFwiQXNzaWdubWVudFN0YXRlbWVudFwiKSxcbiAgICAgIGxvY2F0aW9uOiB0aGlzLmxvY2F0aW9uKG5vZGUpLFxuICAgICAgdGFyZ2V0OiB3aXRoUGFyc2VyUmFuZ2VzKHtraW5kOiAvKiogQHR5cGUge2NvbnN0fSAqLyAoXCJJZGVudGlmaWVyRXhwcmVzc2lvblwiKSwgbG9jYXRpb246IHRhcmdldExvY2F0aW9uLCBuYW1lfSwge25hbWU6IHRhcmdldExvY2F0aW9ufSlcbiAgICB9LCB7b3BlcmF0b3I6IHRoaXMubG9jYXRpb24ob3BlcmF0b3IpfSlcbiAgfVxuXG4gIC8qKlxuICAgKiBDb252ZXJ0cyBvbmUgZXhhY3QgcHJpbnQgY2FsbC5cbiAgICogQHBhcmFtIHtpbXBvcnQoXCJ0cmVlLXNpdHRlclwiKS5TeW50YXhOb2RlfSBub2RlIC0gQ2FsbCBzdGF0ZW1lbnQuXG4gICAqIEByZXR1cm5zIHtpbXBvcnQoXCIuLi9zZW1hbnRpYy90eXBlcy5qc1wiKS5QcmludFN0YXRlbWVudH0gU2VtYW50aWMgcHJpbnQuXG4gICAqL1xuICBwcmludChub2RlKSB7XG4gICAgY29uc3QgcGFydHMgPSB0aGlzLnBhcnRzKG5vZGUpXG5cbiAgICBpZiAobm9kZS50eXBlICE9IFwiY2FsbF9leHByZXNzaW9uXCIgfHwgcGFydHMubGVuZ3RoICE9IDIgfHwgcGFydHNbMF0udHlwZSAhPSBcInNpbXBsZV9pZGVudGlmaWVyXCIgfHxcbiAgICAgIHRoaXMuaWRlbnRpZmllcihwYXJ0c1swXSwgdHJ1ZSkgIT0gXCJwcmludFwiKSB0aGlzLmZhaWwobm9kZSwgXCJleGFjdCBwcmludCBjYWxsIHJlcXVpcmVkXCIpXG4gICAgY29uc3QgYXJndW1lbnRzXyA9IHRoaXMuYXJndW1lbnRzKHBhcnRzWzFdKVxuXG4gICAgaWYgKGFyZ3VtZW50c18ubGVuZ3RoICE9IDEpIHRoaXMuZmFpbChwYXJ0c1sxXSwgXCJwcmludCBhcmd1bWVudCBjb3VudFwiKVxuICAgIHJldHVybiB7ZXhwcmVzc2lvbjogdGhpcy5leHByZXNzaW9uKGFyZ3VtZW50c19bMF0pLCBraW5kOiAvKiogQHR5cGUge2NvbnN0fSAqLyAoXCJQcmludFN0YXRlbWVudFwiKSwgbG9jYXRpb246IHRoaXMubG9jYXRpb24obm9kZSl9XG4gIH1cblxuICAvKipcbiAgICogQ29udmVydHMgb25lIHN1cHBvcnRlZCBzdGF0ZW1lbnQuXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwidHJlZS1zaXR0ZXJcIikuU3ludGF4Tm9kZX0gbm9kZSAtIFN0YXRlbWVudCBub2RlLlxuICAgKiBAcmV0dXJucyB7aW1wb3J0KFwiLi4vc2VtYW50aWMvdHlwZXMuanNcIikuU3RhdGVtZW50fSBTZW1hbnRpYyBzdGF0ZW1lbnQuXG4gICAqL1xuICBzdGF0ZW1lbnQobm9kZSkge1xuICAgIGlmIChub2RlLnR5cGUgPT0gXCJwcm9wZXJ0eV9kZWNsYXJhdGlvblwiKSByZXR1cm4gdGhpcy5sb2NhbChub2RlKVxuICAgIGlmIChub2RlLnR5cGUgPT0gXCJhc3NpZ25tZW50XCIpIHJldHVybiB0aGlzLmFzc2lnbm1lbnQobm9kZSlcbiAgICBpZiAobm9kZS50eXBlID09IFwiaWZfc3RhdGVtZW50XCIpIHJldHVybiB0aGlzLmNvbmRpdGlvbmFsKG5vZGUpXG4gICAgaWYgKG5vZGUudHlwZSA9PSBcImNhbGxfZXhwcmVzc2lvblwiKSByZXR1cm4gdGhpcy5wcmludChub2RlKVxuICAgIGlmIChub2RlLnR5cGUgPT0gXCJjb250cm9sX3RyYW5zZmVyX3N0YXRlbWVudFwiKSB7XG4gICAgICBjb25zdCByZXN1bHQgPSBub2RlLmNoaWxkRm9yRmllbGROYW1lKFwicmVzdWx0XCIpXG5cbiAgICAgIGlmICghcmVzdWx0KSB0aGlzLmZhaWwobm9kZSwgXCJyZXR1cm4gd2l0aG91dCBleHByZXNzaW9uXCIpXG4gICAgICB0aGlzLnNoYXBlKG5vZGUsIFtcInJldHVyblwiLCByZXN1bHRdKVxuICAgICAgcmV0dXJuIHtleHByZXNzaW9uOiB0aGlzLmV4cHJlc3Npb24ocmVzdWx0KSwga2luZDogLyoqIEB0eXBlIHtjb25zdH0gKi8gKFwiUmV0dXJuU3RhdGVtZW50XCIpLCBsb2NhdGlvbjogdGhpcy5sb2NhdGlvbihub2RlKX1cbiAgICB9XG4gICAgcmV0dXJuIHRoaXMuZmFpbChub2RlKVxuICB9XG5cbiAgLyoqXG4gICAqIENvbnZlcnRzIG9uZSBwYXJzZXIgc3RhdGVtZW50cyBub2RlLlxuICAgKiBAcGFyYW0ge2ltcG9ydChcInRyZWUtc2l0dGVyXCIpLlN5bnRheE5vZGUgfCB1bmRlZmluZWR9IG5vZGUgLSBPcHRpb25hbCBzdGF0ZW1lbnRzIG5vZGUuXG4gICAqIEByZXR1cm5zIHtpbXBvcnQoXCIuLi9zZW1hbnRpYy90eXBlcy5qc1wiKS5TdGF0ZW1lbnRbXX0gT3JkZXJlZCBzdGF0ZW1lbnRzLlxuICAgKi9cbiAgc3RhdGVtZW50cyhub2RlKSB7XG4gICAgaWYgKCFub2RlKSByZXR1cm4gW11cbiAgICBpZiAobm9kZS50eXBlICE9IFwic3RhdGVtZW50c1wiKSB0aGlzLmZhaWwobm9kZSwgXCJzdGF0ZW1lbnQgbGlzdCBzaGFwZVwiKVxuICAgIHJldHVybiB0aGlzLnN0YXRlbWVudExpc3QodGhpcy5wYXJ0cyhub2RlKSlcbiAgfVxuXG4gIC8qKlxuICAgKiBDb252ZXJ0cyBhIHN0YXRlbWVudCBzZXF1ZW5jZSB3aGlsZSBjb2xsYXBzaW5nIGFuIGFkamFjZW50IGdlbmVyYXRlZCBtYXJrZXIuXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwidHJlZS1zaXR0ZXJcIikuU3ludGF4Tm9kZVtdfSBub2RlcyAtIE9yZGVyZWQgc3RhdGVtZW50IG5vZGVzLlxuICAgKiBAcmV0dXJucyB7aW1wb3J0KFwiLi4vc2VtYW50aWMvdHlwZXMuanNcIikuU3RhdGVtZW50W119IFNlbWFudGljIHN0YXRlbWVudHMuXG4gICAqL1xuICBzdGF0ZW1lbnRMaXN0KG5vZGVzKSB7XG4gICAgLyoqIEB0eXBlIHtpbXBvcnQoXCIuLi9zZW1hbnRpYy90eXBlcy5qc1wiKS5TdGF0ZW1lbnRbXX0gKi9cbiAgICBjb25zdCBzdGF0ZW1lbnRzID0gW11cblxuICAgIGZvciAoY29uc3Qgc3RhdGVtZW50IG9mIG5vZGVzKSB7XG4gICAgICBjb25zdCBwYXJ0cyA9IHRoaXMucGFydHMoc3RhdGVtZW50KVxuICAgICAgY29uc3QgbWFya2VyID0gc3RhdGVtZW50LnR5cGUgPT0gXCJjYWxsX2V4cHJlc3Npb25cIiAmJiBwYXJ0c1swXT8udGV4dCA9PSBcInNlbWFudGlmb2xkX2tlZXBfbXV0YWJsZVwiXG5cbiAgICAgIGlmIChtYXJrZXIpIHtcbiAgICAgICAgY29uc3QgcHJldmlvdXMgPSBzdGF0ZW1lbnRzLmF0KC0xKVxuXG4gICAgICAgIGlmICghcHJldmlvdXMgfHwgcHJldmlvdXMua2luZCAhPSBcIkxvY2FsRGVjbGFyYXRpb25cIiB8fCAhcHJldmlvdXMubXV0YWJsZSkgdGhpcy5mYWlsKHN0YXRlbWVudCwgXCJTd2lmdCBtdXRhYmxlLWxvY2FsIHdhcm5pbmcgbWFya2VyXCIpXG4gICAgICAgIHRoaXMubXV0YWJsZU1hcmtlckNhbGwoc3RhdGVtZW50LCBwcmV2aW91cylcbiAgICAgIH0gZWxzZSBzdGF0ZW1lbnRzLnB1c2godGhpcy5zdGF0ZW1lbnQoc3RhdGVtZW50KSlcbiAgICB9XG4gICAgcmV0dXJuIHN0YXRlbWVudHNcbiAgfVxuXG4gIC8qKlxuICAgKiBDb2xsYXBzZXMgdGhlIGdlbmVyYXRlZCBpbm91dCBjYWxsIG9ubHkgYmVzaWRlIGl0cyBkZWNsYXJlZCBtdXRhYmxlIGxvY2FsLlxuICAgKiBAcGFyYW0ge2ltcG9ydChcInRyZWUtc2l0dGVyXCIpLlN5bnRheE5vZGV9IG5vZGUgLSBHZW5lcmF0ZWQgbWFya2VyIGNhbGwuXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vc2VtYW50aWMvdHlwZXMuanNcIikuTG9jYWxEZWNsYXJhdGlvbn0gbG9jYWwgLSBQcmVjZWRpbmcgbG9jYWwuXG4gICAqIEByZXR1cm5zIHt2b2lkfVxuICAgKi9cbiAgbXV0YWJsZU1hcmtlckNhbGwobm9kZSwgbG9jYWwpIHtcbiAgICBjb25zdCBwYXJ0cyA9IHRoaXMucGFydHMobm9kZSlcbiAgICBjb25zdCBhcmd1bWVudHNfID0gcGFydHMubGVuZ3RoID09IDIgPyB0aGlzLmFyZ3VtZW50cyhwYXJ0c1sxXSkgOiBbXVxuICAgIGNvbnN0IGFyZ3VtZW50ID0gYXJndW1lbnRzX1swXVxuICAgIGNvbnN0IHRhcmdldCA9IGFyZ3VtZW50Py50eXBlID09IFwicHJlZml4X2V4cHJlc3Npb25cIiA/IHRoaXMuZmllbGQoYXJndW1lbnQsIFwidGFyZ2V0XCIpIDogdW5kZWZpbmVkXG5cbiAgICBpZiAoIXRoaXMubXV0YWJsZU1hcmtlciB8fCBwYXJ0c1swXT8udHlwZSAhPSBcInNpbXBsZV9pZGVudGlmaWVyXCIgfHwgcGFydHNbMF0udGV4dCAhPSBcInNlbWFudGlmb2xkX2tlZXBfbXV0YWJsZVwiIHx8XG4gICAgICBhcmd1bWVudHNfLmxlbmd0aCAhPSAxIHx8ICF0YXJnZXQgfHwgdGFyZ2V0LnR5cGUgIT0gXCJzaW1wbGVfaWRlbnRpZmllclwiIHx8IHRhcmdldC50ZXh0ICE9IGxvY2FsLm5hbWUpIHtcbiAgICAgIHRoaXMuZmFpbChub2RlLCBcIlN3aWZ0IG11dGFibGUtbG9jYWwgd2FybmluZyBtYXJrZXJcIilcbiAgICB9XG4gICAgdGhpcy5zaGFwZShub2RlLCBbcGFydHNbMF0sIHBhcnRzWzFdXSlcbiAgICB0aGlzLnNoYXBlKGFyZ3VtZW50LCBbXCImXCIsIHRhcmdldF0pXG4gIH1cblxuICAvKipcbiAgICogQ29udmVydHMgb25lIGV4YWN0IGJyYWNlZCBjb25kaXRpb25hbCwgaW5jbHVkaW5nIGRpcmVjdCBlbHNlLWlmLlxuICAgKiBAcGFyYW0ge2ltcG9ydChcInRyZWUtc2l0dGVyXCIpLlN5bnRheE5vZGV9IG5vZGUgLSBJZiBub2RlLlxuICAgKiBAcmV0dXJucyB7aW1wb3J0KFwiLi4vc2VtYW50aWMvdHlwZXMuanNcIikuSWZTdGF0ZW1lbnR9IFNlbWFudGljIGNvbmRpdGlvbmFsLlxuICAgKi9cbiAgY29uZGl0aW9uYWwobm9kZSkge1xuICAgIGNvbnN0IHBhcnRzID0gdGhpcy5wYXJ0cyhub2RlKVxuICAgIGNvbnN0IGNvbmRpdGlvbiA9IHRoaXMuZmllbGQobm9kZSwgXCJjb25kaXRpb25cIilcbiAgICBsZXQgaW5kZXggPSAzXG4gICAgY29uc3QgY29uc2VxdWVudFN0YXRlbWVudHMgPSBwYXJ0c1tpbmRleF0/LnR5cGUgPT0gXCJzdGF0ZW1lbnRzXCIgPyBwYXJ0c1tpbmRleCsrXSA6IHVuZGVmaW5lZFxuXG4gICAgaWYgKG5vZGUudHlwZSAhPSBcImlmX3N0YXRlbWVudFwiIHx8IHBhcnRzWzBdPy50ZXh0ICE9IFwiaWZcIiB8fCBwYXJ0c1sxXT8uaWQgIT0gY29uZGl0aW9uLmlkIHx8IHBhcnRzWzJdPy50ZXh0ICE9IFwie1wiIHx8XG4gICAgICBwYXJ0c1tpbmRleF0/LnRleHQgIT0gXCJ9XCIpIHRoaXMuZmFpbChub2RlLCBcImlmIHN0YXRlbWVudCBzaGFwZVwiKVxuICAgIGluZGV4ICs9IDFcbiAgICBjb25zdCBzdGF0ZW1lbnQgPSB7XG4gICAgICBjb25kaXRpb246IHRoaXMuZXhwcmVzc2lvbihjb25kaXRpb24pLFxuICAgICAgY29uc2VxdWVudDoge2tpbmQ6IC8qKiBAdHlwZSB7Y29uc3R9ICovIChcIkJsb2NrXCIpLCBsb2NhdGlvbjogdGhpcy5sb2NhdGlvbihjb25zZXF1ZW50U3RhdGVtZW50cyA/PyBub2RlKSxcbiAgICAgICAgc3RhdGVtZW50czogdGhpcy5zdGF0ZW1lbnRzKGNvbnNlcXVlbnRTdGF0ZW1lbnRzKX0sXG4gICAgICBraW5kOiAvKiogQHR5cGUge2NvbnN0fSAqLyAoXCJJZlN0YXRlbWVudFwiKSxcbiAgICAgIGxvY2F0aW9uOiB0aGlzLmxvY2F0aW9uKG5vZGUpXG4gICAgfVxuXG4gICAgaWYgKGluZGV4ID09IHBhcnRzLmxlbmd0aCkge1xuICAgICAgdGhpcy5zaGFwZShub2RlLCBbXCJpZlwiLCBjb25kaXRpb24sIFwie1wiLCAuLi4oY29uc2VxdWVudFN0YXRlbWVudHMgPyBbY29uc2VxdWVudFN0YXRlbWVudHNdIDogW10pLCBcIn1cIl0pXG4gICAgICByZXR1cm4gc3RhdGVtZW50XG4gICAgfVxuICAgIGlmIChwYXJ0c1tpbmRleF0/LnRleHQgIT0gXCJlbHNlXCIpIHRoaXMuZmFpbChwYXJ0c1tpbmRleF0gPz8gbm9kZSwgXCJpZiBhbHRlcm5hdGUgc2hhcGVcIilcbiAgICBpbmRleCArPSAxXG4gICAgY29uc3QgYnJhbmNoID0gcGFydHNbaW5kZXhdXG5cbiAgICBpZiAoYnJhbmNoPy50eXBlID09IFwiaWZfc3RhdGVtZW50XCIgJiYgaW5kZXggKyAxID09IHBhcnRzLmxlbmd0aCkge1xuICAgICAgdGhpcy5zaGFwZShub2RlLCBbXCJpZlwiLCBjb25kaXRpb24sIFwie1wiLCAuLi4oY29uc2VxdWVudFN0YXRlbWVudHMgPyBbY29uc2VxdWVudFN0YXRlbWVudHNdIDogW10pLCBcIn1cIiwgXCJlbHNlXCIsIGJyYW5jaF0pXG4gICAgICByZXR1cm4gey4uLnN0YXRlbWVudCwgYWx0ZXJuYXRlOiB7a2luZDogLyoqIEB0eXBlIHtjb25zdH0gKi8gKFwiQmxvY2tcIiksIGxvY2F0aW9uOiB0aGlzLmxvY2F0aW9uKGJyYW5jaCksIHN0YXRlbWVudHM6IFt0aGlzLmNvbmRpdGlvbmFsKGJyYW5jaCldfX1cbiAgICB9XG4gICAgaWYgKGJyYW5jaD8udGV4dCAhPSBcIntcIikgdGhpcy5mYWlsKGJyYW5jaCA/PyBub2RlLCBcImlmIGFsdGVybmF0ZSBibG9jayBzaGFwZVwiKVxuICAgIGluZGV4ICs9IDFcbiAgICBjb25zdCBhbHRlcm5hdGVTdGF0ZW1lbnRzID0gcGFydHNbaW5kZXhdPy50eXBlID09IFwic3RhdGVtZW50c1wiID8gcGFydHNbaW5kZXgrK10gOiB1bmRlZmluZWRcblxuICAgIGlmIChwYXJ0c1tpbmRleF0/LnRleHQgIT0gXCJ9XCIgfHwgaW5kZXggKyAxICE9IHBhcnRzLmxlbmd0aCkgdGhpcy5mYWlsKHBhcnRzW2luZGV4XSA/PyBub2RlLCBcImlmIGFsdGVybmF0ZSBibG9jayBzaGFwZVwiKVxuICAgIHRoaXMuc2hhcGUobm9kZSwgW1wiaWZcIiwgY29uZGl0aW9uLCBcIntcIiwgLi4uKGNvbnNlcXVlbnRTdGF0ZW1lbnRzID8gW2NvbnNlcXVlbnRTdGF0ZW1lbnRzXSA6IFtdKSwgXCJ9XCIsIFwiZWxzZVwiLCBcIntcIixcbiAgICAgIC4uLihhbHRlcm5hdGVTdGF0ZW1lbnRzID8gW2FsdGVybmF0ZVN0YXRlbWVudHNdIDogW10pLCBcIn1cIl0pXG4gICAgcmV0dXJuIHsuLi5zdGF0ZW1lbnQsIGFsdGVybmF0ZToge2tpbmQ6IC8qKiBAdHlwZSB7Y29uc3R9ICovIChcIkJsb2NrXCIpLCBsb2NhdGlvbjogdGhpcy5sb2NhdGlvbihhbHRlcm5hdGVTdGF0ZW1lbnRzID8/IG5vZGUpLFxuICAgICAgc3RhdGVtZW50czogdGhpcy5zdGF0ZW1lbnRzKGFsdGVybmF0ZVN0YXRlbWVudHMpfX1cbiAgfVxuXG4gIC8qKlxuICAgKiBDb252ZXJ0cyBvbmUgZnVuY3Rpb24gYm9keS5cbiAgICogQHBhcmFtIHtpbXBvcnQoXCJ0cmVlLXNpdHRlclwiKS5TeW50YXhOb2RlfSBub2RlIC0gRnVuY3Rpb24gYm9keS5cbiAgICogQHJldHVybnMge2ltcG9ydChcIi4uL3NlbWFudGljL3R5cGVzLmpzXCIpLkJsb2NrfSBTZW1hbnRpYyBibG9jay5cbiAgICovXG4gIGJsb2NrKG5vZGUpIHtcbiAgICBjb25zdCBwYXJ0cyA9IHRoaXMucGFydHMobm9kZSlcbiAgICBjb25zdCBzdGF0ZW1lbnRzID0gcGFydHNbMV0/LnR5cGUgPT0gXCJzdGF0ZW1lbnRzXCIgPyBwYXJ0c1sxXSA6IHVuZGVmaW5lZFxuXG4gICAgaWYgKG5vZGUudHlwZSAhPSBcImZ1bmN0aW9uX2JvZHlcIikgdGhpcy5mYWlsKG5vZGUsIFwiZnVuY3Rpb24gYm9keSBzaGFwZVwiKVxuICAgIHRoaXMuc2hhcGUobm9kZSwgW1wie1wiLCAuLi4oc3RhdGVtZW50cyA/IFtzdGF0ZW1lbnRzXSA6IFtdKSwgXCJ9XCJdKVxuICAgIHJldHVybiB7a2luZDogLyoqIEB0eXBlIHtjb25zdH0gKi8gKFwiQmxvY2tcIiksIGxvY2F0aW9uOiB0aGlzLmxvY2F0aW9uKG5vZGUpLCBzdGF0ZW1lbnRzOiB0aGlzLnN0YXRlbWVudHMoc3RhdGVtZW50cyl9XG4gIH1cblxuICAvKipcbiAgICogQ29udmVydHMgb25lIGV4YWN0IHVuZGVyc2NvcmUtbGFiZWxlZCBwYXJhbWV0ZXIuXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwidHJlZS1zaXR0ZXJcIikuU3ludGF4Tm9kZX0gbm9kZSAtIFBhcmFtZXRlciBub2RlLlxuICAgKiBAcmV0dXJucyB7aW1wb3J0KFwiLi4vc2VtYW50aWMvdHlwZXMuanNcIikuUGFyYW1ldGVyfSBTZW1hbnRpYyBwYXJhbWV0ZXIuXG4gICAqL1xuICBwYXJhbWV0ZXIobm9kZSkge1xuICAgIGNvbnN0IHBhcnRzID0gdGhpcy5wYXJ0cyhub2RlKVxuXG4gICAgaWYgKG5vZGUudHlwZSAhPSBcInBhcmFtZXRlclwiIHx8IHBhcnRzLmxlbmd0aCAhPSA0IHx8IHBhcnRzWzBdLnRleHQgIT0gXCJfXCIgfHwgcGFydHNbMF0udHlwZSAhPSBcInNpbXBsZV9pZGVudGlmaWVyXCIgfHxcbiAgICAgIHBhcnRzWzFdLnR5cGUgIT0gXCJzaW1wbGVfaWRlbnRpZmllclwiIHx8IHBhcnRzWzJdLnRleHQgIT0gXCI6XCIpIHRoaXMuZmFpbChub2RlLCBcInBhcmFtZXRlciBzaGFwZVwiKVxuICAgIHRoaXMuc2hhcGUobm9kZSwgW3BhcnRzWzBdLCBwYXJ0c1sxXSwgXCI6XCIsIHBhcnRzWzNdXSlcbiAgICBjb25zdCBuYW1lID0gdGhpcy5pZGVudGlmaWVyKHBhcnRzWzFdKVxuXG4gICAgcmV0dXJuIHdpdGhQYXJzZXJSYW5nZXMoe2tpbmQ6IC8qKiBAdHlwZSB7Y29uc3R9ICovIChcIlBhcmFtZXRlclwiKSwgbG9jYXRpb246IHRoaXMubG9jYXRpb24obm9kZSksIG5hbWUsIHR5cGU6IHRoaXMudHlwZShwYXJ0c1szXSl9LCB7XG4gICAgICBuYW1lOiB0aGlzLmxvY2F0aW9uKHBhcnRzWzFdKVxuICAgIH0pXG4gIH1cblxuICAvKipcbiAgICogQ29udmVydHMgb25lIHN5bmNocm9ub3VzIHRvcC1sZXZlbCBzY2FsYXIgZnVuY3Rpb24uXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwidHJlZS1zaXR0ZXJcIikuU3ludGF4Tm9kZX0gbm9kZSAtIEZ1bmN0aW9uIG5vZGUuXG4gICAqIEByZXR1cm5zIHtpbXBvcnQoXCIuLi9zZW1hbnRpYy90eXBlcy5qc1wiKS5GdW5jdGlvbkRlY2xhcmF0aW9ufSBTZW1hbnRpYyBmdW5jdGlvbi5cbiAgICovXG4gIGZ1bmN0aW9uKG5vZGUpIHtcbiAgICBjb25zdCBwYXJ0cyA9IHRoaXMucGFydHMobm9kZSlcbiAgICBjb25zdCBuYW1lTm9kZSA9IG5vZGUuY2hpbGRGb3JGaWVsZE5hbWUoXCJuYW1lXCIpXG4gICAgY29uc3QgYm9keSA9IG5vZGUuY2hpbGRGb3JGaWVsZE5hbWUoXCJib2R5XCIpXG4gICAgY29uc3QgcGFyYW1ldGVycyA9IHBhcnRzLmZpbHRlcigocGFydCkgPT4gcGFydC50eXBlID09IFwicGFyYW1ldGVyXCIpXG5cbiAgICBpZiAoIW5hbWVOb2RlIHx8ICFib2R5IHx8IG5vZGUudHlwZSAhPSBcImZ1bmN0aW9uX2RlY2xhcmF0aW9uXCIpIHRoaXMuZmFpbChub2RlLCBcImZ1bmN0aW9uIGRlY2xhcmF0aW9uIHNoYXBlXCIpXG4gICAgaWYgKHBhcmFtZXRlcnMubGVuZ3RoICE9IDIpIHRoaXMuZmFpbChub2RlLCBcImZ1bmN0aW9uIHBhcmFtZXRlciBjb3VudCBvdGhlciB0aGFuIHR3b1wiKVxuICAgIGlmICghcGFydHMuc29tZSgocGFydCkgPT4gcGFydC50ZXh0ID09IFwiLT5cIikpIHJldHVybiBtaXNzaW5nVHlwZShcInN3aWZ0XCIsIFwiRnVuY3Rpb24gcmV0dXJuXCIsIHRoaXMubG9jYXRpb24obm9kZSkpXG4gICAgaWYgKHBhcnRzLmxlbmd0aCAhPSAxMCkgdGhpcy5mYWlsKHBhcnRzLmZpbmQoKHBhcnQpID0+ICFbXCJmdW5jXCIsIFwiKFwiLCBcIixcIiwgXCIpXCIsIFwiLT5cIl0uaW5jbHVkZXMocGFydC50ZXh0KSAmJlxuICAgICAgcGFydC5pZCAhPSBuYW1lTm9kZS5pZCAmJiBwYXJ0LmlkICE9IGJvZHkuaWQgJiYgIXBhcmFtZXRlcnMuc29tZSgocGFyYW1ldGVyKSA9PiBwYXJhbWV0ZXIuaWQgPT0gcGFydC5pZCkpID8/IG5vZGUsIFwiZnVuY3Rpb24gZGVjbGFyYXRpb24gc2hhcGVcIilcbiAgICBjb25zdCByZXR1cm5UeXBlID0gcGFydHNbOF1cblxuICAgIHRoaXMuc2hhcGUobm9kZSwgW1wiZnVuY1wiLCBuYW1lTm9kZSwgXCIoXCIsIHBhcmFtZXRlcnNbMF0sIFwiLFwiLCBwYXJhbWV0ZXJzWzFdLCBcIilcIiwgXCItPlwiLCByZXR1cm5UeXBlLCBib2R5XSlcbiAgICBjb25zdCBuYW1lID0gdGhpcy5pZGVudGlmaWVyKG5hbWVOb2RlKVxuXG4gICAgcmV0dXJuIHdpdGhQYXJzZXJSYW5nZXMoe1xuICAgICAgYm9keTogdGhpcy5ibG9jayhib2R5KSxcbiAgICAgIGtpbmQ6IC8qKiBAdHlwZSB7Y29uc3R9ICovIChcIkZ1bmN0aW9uRGVjbGFyYXRpb25cIiksXG4gICAgICBsb2NhdGlvbjogdGhpcy5sb2NhdGlvbihub2RlKSxcbiAgICAgIG5hbWUsXG4gICAgICBwYXJhbWV0ZXJzOiBwYXJhbWV0ZXJzLm1hcCgocGFyYW1ldGVyKSA9PiB0aGlzLnBhcmFtZXRlcihwYXJhbWV0ZXIpKSxcbiAgICAgIHJldHVyblR5cGU6IHRoaXMudHlwZShyZXR1cm5UeXBlKVxuICAgIH0sIHtuYW1lOiB0aGlzLmxvY2F0aW9uKG5hbWVOb2RlKX0pXG4gIH1cblxuICAvKipcbiAgICogQ29tcGFyZXMgZXZlcnkgY2hpbGQgZmllbGQgYW5kIGxlYWYgdG9rZW4gYWdhaW5zdCB0YXJnZXQtb25seSBjYW5vbmljYWwgc3VwcG9ydC5cbiAgICogQHBhcmFtIHtpbXBvcnQoXCJ0cmVlLXNpdHRlclwiKS5TeW50YXhOb2RlfSBhY3R1YWwgLSBTb3VyY2Ugc3VwcG9ydCBub2RlLlxuICAgKiBAcGFyYW0ge2ltcG9ydChcInRyZWUtc2l0dGVyXCIpLlN5bnRheE5vZGV9IGV4cGVjdGVkIC0gQ2Fub25pY2FsIHN1cHBvcnQgbm9kZS5cbiAgICogQHBhcmFtIHtTd2lmdFJlYWRlcn0gY2Fub25pY2FsIC0gQ2Fub25pY2FsIHNvdXJjZSByZWFkZXIuXG4gICAqIEByZXR1cm5zIHt2b2lkfVxuICAgKi9cbiAgY29tcGFyZVRyZWUoYWN0dWFsLCBleHBlY3RlZCwgY2Fub25pY2FsKSB7XG4gICAgaWYgKGFjdHVhbC50eXBlICE9IGV4cGVjdGVkLnR5cGUgfHwgYWN0dWFsLmlzTmFtZWQgIT0gZXhwZWN0ZWQuaXNOYW1lZCB8fCBhY3R1YWwuaXNFeHRyYSAhPSBleHBlY3RlZC5pc0V4dHJhIHx8XG4gICAgICBhY3R1YWwuY2hpbGRDb3VudCAhPSBleHBlY3RlZC5jaGlsZENvdW50KSB0aGlzLmZhaWwoYWN0dWFsLCBcIm1vZGlmaWVkIFN3aWZ0IHN1cHBvcnQgbm9kZVwiKVxuICAgIGlmICghYWN0dWFsLmNoaWxkQ291bnQgJiYgYWN0dWFsLnRleHQgIT0gZXhwZWN0ZWQudGV4dCkgdGhpcy5mYWlsKGFjdHVhbCwgXCJtb2RpZmllZCBTd2lmdCBzdXBwb3J0IHRva2VuXCIpXG4gICAgZm9yIChsZXQgaW5kZXggPSAwOyBpbmRleCA8IGFjdHVhbC5jaGlsZENvdW50OyBpbmRleCArPSAxKSB7XG4gICAgICBjb25zdCBsZWZ0ID0gYWN0dWFsLmNoaWxkKGluZGV4KVxuICAgICAgY29uc3QgcmlnaHQgPSBleHBlY3RlZC5jaGlsZChpbmRleClcblxuICAgICAgaWYgKCFsZWZ0IHx8ICFyaWdodCB8fCBhY3R1YWwuZmllbGROYW1lRm9yQ2hpbGQoaW5kZXgpICE9IGV4cGVjdGVkLmZpZWxkTmFtZUZvckNoaWxkKGluZGV4KSkge1xuICAgICAgICB0aGlzLmZhaWwobGVmdCA/PyBhY3R1YWwsIFwibW9kaWZpZWQgU3dpZnQgc3VwcG9ydCBmaWVsZFwiKVxuICAgICAgfVxuICAgICAgdGhpcy5jb21wYXJlVHJlZShsZWZ0LCByaWdodCwgY2Fub25pY2FsKVxuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBSZWplY3RzIG9yZGluYXJ5IFN3aWZ0IGVxdWFsaXR5IGFmdGVyIHNoYXJlZCB0eXBlIHJlc29sdXRpb24gaWRlbnRpZmllcyBTdHJpbmdzLlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4uL3NlbWFudGljL3R5cGVzLmpzXCIpLlNlbWFudGljTW9kdWxlfSBtb2R1bGUgLSBWYWxpZGF0ZWQgc2VtYW50aWMgbW9kdWxlLlxuICAgKiBAcmV0dXJucyB7dm9pZH1cbiAgICovXG4gIHJlamVjdE5hdGl2ZVN0cmluZ0VxdWFsaXR5KG1vZHVsZSkge1xuICAgIGNvbnN0IHBlbmRpbmcgPSBbbW9kdWxlLmVudHJ5UG9pbnQuYm9keSwgLi4ubW9kdWxlLmZ1bmN0aW9ucy5tYXAoKGRlY2xhcmF0aW9uKSA9PiBkZWNsYXJhdGlvbi5ib2R5KV1cblxuICAgIHdoaWxlIChwZW5kaW5nLmxlbmd0aCkge1xuICAgICAgY29uc3QgYmxvY2sgPSBwZW5kaW5nLnBvcCgpXG5cbiAgICAgIGlmICghYmxvY2spIHRocm93IG5ldyBFcnJvcihcIlN3aWZ0IHNlbWFudGljIHRyYXZlcnNhbCBsb3N0IGEgcGVuZGluZyBibG9jay5cIilcbiAgICAgIGZvciAoY29uc3Qgc3RhdGVtZW50IG9mIGJsb2NrLnN0YXRlbWVudHMpIHtcbiAgICAgICAgaWYgKHN0YXRlbWVudC5raW5kID09IFwiSWZTdGF0ZW1lbnRcIikge1xuICAgICAgICAgIHBlbmRpbmcucHVzaChzdGF0ZW1lbnQuY29uc2VxdWVudClcbiAgICAgICAgICBpZiAoc3RhdGVtZW50LmFsdGVybmF0ZSkgcGVuZGluZy5wdXNoKHN0YXRlbWVudC5hbHRlcm5hdGUpXG4gICAgICAgICAgdGhpcy5yZWplY3ROYXRpdmVTdHJpbmdFcXVhbGl0eUV4cHJlc3Npb24oc3RhdGVtZW50LmNvbmRpdGlvbilcbiAgICAgICAgfSBlbHNlIGlmIChzdGF0ZW1lbnQua2luZCA9PSBcIkxvY2FsRGVjbGFyYXRpb25cIikgdGhpcy5yZWplY3ROYXRpdmVTdHJpbmdFcXVhbGl0eUV4cHJlc3Npb24oc3RhdGVtZW50LmluaXRpYWxpemVyKVxuICAgICAgICBlbHNlIGlmIChzdGF0ZW1lbnQua2luZCA9PSBcIkFzc2lnbm1lbnRTdGF0ZW1lbnRcIikgdGhpcy5yZWplY3ROYXRpdmVTdHJpbmdFcXVhbGl0eUV4cHJlc3Npb24oc3RhdGVtZW50LmV4cHJlc3Npb24pXG4gICAgICAgIGVsc2UgaWYgKHN0YXRlbWVudC5raW5kID09IFwiRXhwcmVzc2lvblN0YXRlbWVudFwiIHx8IHN0YXRlbWVudC5raW5kID09IFwiUHJpbnRTdGF0ZW1lbnRcIikge1xuICAgICAgICAgIHRoaXMucmVqZWN0TmF0aXZlU3RyaW5nRXF1YWxpdHlFeHByZXNzaW9uKHN0YXRlbWVudC5leHByZXNzaW9uKVxuICAgICAgICB9IGVsc2UgaWYgKHN0YXRlbWVudC5raW5kID09IFwiUmV0dXJuU3RhdGVtZW50XCIgJiYgc3RhdGVtZW50LmV4cHJlc3Npb24pIHtcbiAgICAgICAgICB0aGlzLnJlamVjdE5hdGl2ZVN0cmluZ0VxdWFsaXR5RXhwcmVzc2lvbihzdGF0ZW1lbnQuZXhwcmVzc2lvbilcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBDaGVja3Mgb25lIHZhbGlkYXRlZCBleHByZXNzaW9uIHdpdGhvdXQgcmV0YWluaW5nIHBhcnNlciBzdGF0ZSBpbiBwdWJsaWMgdmFsdWVzLlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4uL3NlbWFudGljL3R5cGVzLmpzXCIpLkV4cHJlc3Npb259IHJvb3QgLSBWYWxpZGF0ZWQgZXhwcmVzc2lvbi5cbiAgICogQHJldHVybnMge3ZvaWR9XG4gICAqL1xuICByZWplY3ROYXRpdmVTdHJpbmdFcXVhbGl0eUV4cHJlc3Npb24ocm9vdCkge1xuICAgIGNvbnN0IHBlbmRpbmcgPSBbcm9vdF1cblxuICAgIHdoaWxlIChwZW5kaW5nLmxlbmd0aCkge1xuICAgICAgY29uc3QgZXhwcmVzc2lvbiA9IHBlbmRpbmcucG9wKClcblxuICAgICAgaWYgKCFleHByZXNzaW9uKSB0aHJvdyBuZXcgRXJyb3IoXCJTd2lmdCBzZW1hbnRpYyB0cmF2ZXJzYWwgbG9zdCBhIHBlbmRpbmcgZXhwcmVzc2lvbi5cIilcbiAgICAgIGlmIChleHByZXNzaW9uLmtpbmQgPT0gXCJCaW5hcnlFeHByZXNzaW9uXCIpIHtcbiAgICAgICAgY29uc3Qgb3BlcmF0b3IgPSB0aGlzLm5hdGl2ZUVxdWFsaXR5T3BlcmF0b3JzLmdldChleHByZXNzaW9uKVxuXG4gICAgICAgIGlmIChvcGVyYXRvciAmJiBbXCJTdHJpbmdFcXVhbFwiLCBcIlN0cmluZ05vdEVxdWFsXCJdLmluY2x1ZGVzKGV4cHJlc3Npb24ub3BlcmF0aW9uKSkge1xuICAgICAgICAgIHRoaXMuZmFpbChvcGVyYXRvciwgXCJvcmRpbmFyeSBTd2lmdCBTdHJpbmcgZXF1YWxpdHlcIilcbiAgICAgICAgfVxuICAgICAgICBwZW5kaW5nLnB1c2goZXhwcmVzc2lvbi5sZWZ0LCBleHByZXNzaW9uLnJpZ2h0KVxuICAgICAgfSBlbHNlIGlmIChleHByZXNzaW9uLmtpbmQgPT0gXCJVbmFyeUV4cHJlc3Npb25cIikgcGVuZGluZy5wdXNoKGV4cHJlc3Npb24ub3BlcmFuZClcbiAgICAgIGVsc2UgaWYgKGV4cHJlc3Npb24ua2luZCA9PSBcIkNhbGxFeHByZXNzaW9uXCIpIHBlbmRpbmcucHVzaCguLi5leHByZXNzaW9uLmFyZ3VtZW50cylcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogQ29udmVydHMgdGhlIGNvbXBsZXRlIHNvdXJjZSBmaWxlIHdpdGggZGVjbGFyYXRpb25zIGJlZm9yZSB0b3AtbGV2ZWwgZW50cnkgc3RhdGVtZW50cy5cbiAgICogQHBhcmFtIHtpbXBvcnQoXCJ0cmVlLXNpdHRlclwiKS5TeW50YXhOb2RlfSByb290IC0gU291cmNlIHJvb3QuXG4gICAqIEByZXR1cm5zIHtpbXBvcnQoXCIuLi9zZW1hbnRpYy90eXBlcy5qc1wiKS5TZW1hbnRpY01vZHVsZX0gU2VtYW50aWMgbW9kdWxlLlxuICAgKi9cbiAgbW9kdWxlKHJvb3QpIHtcbiAgICB0aGlzLnZhbGlkYXRlVHJlZShyb290KVxuICAgIGlmIChyb290LnR5cGUgIT0gXCJzb3VyY2VfZmlsZVwiKSB0aGlzLmZhaWwocm9vdCwgXCJzb3VyY2UgZmlsZSByb290XCIpXG4gICAgY29uc3QgcGFydHMgPSB0aGlzLnBhcnRzKHJvb3QpXG4gICAgY29uc3QgY2Fub25pY2FsID0gbmV3IFN3aWZ0UmVhZGVyKHRoaXMuZmlsZW5hbWUsIHN3aWZ0UnVudGltZSlcbiAgICBjb25zdCBzdXBwb3J0ID0gY2Fub25pY2FsLnBhcnRzKHBhcnNlci5wYXJzZShzd2lmdFJ1bnRpbWUpLnJvb3ROb2RlKVxuICAgIGxldCBzdXBwb3J0SW5kZXggPSAwXG5cbiAgICB3aGlsZSAoc3VwcG9ydEluZGV4IDwgcGFydHMubGVuZ3RoICYmIHN1cHBvcnRJbmRleCA8IHN1cHBvcnQubGVuZ3RoKSB7XG4gICAgICBjb25zdCBub2RlID0gcGFydHNbc3VwcG9ydEluZGV4XVxuICAgICAgY29uc3QgbmFtZSA9IG5vZGUudHlwZSA9PSBcImZ1bmN0aW9uX2RlY2xhcmF0aW9uXCIgPyBub2RlLmNoaWxkRm9yRmllbGROYW1lKFwibmFtZVwiKSA6IHVuZGVmaW5lZFxuICAgICAgY29uc3QgZXhwZWN0ZWROYW1lID0gc3VwcG9ydFtzdXBwb3J0SW5kZXhdLmNoaWxkRm9yRmllbGROYW1lKFwibmFtZVwiKVxuXG4gICAgICBpZiAoIW5hbWUgfHwgIWV4cGVjdGVkTmFtZSB8fCBuYW1lLnRleHQgIT0gZXhwZWN0ZWROYW1lLnRleHQpIGJyZWFrXG4gICAgICB0aGlzLmNvbXBhcmVUcmVlKG5vZGUsIHN1cHBvcnRbc3VwcG9ydEluZGV4XSwgY2Fub25pY2FsKVxuICAgICAgaWYgKGhlbHBlck9wZXJhdGlvbnMuaGFzKG5hbWUudGV4dCkpIHRoaXMuaGVscGVycy5hZGQobmFtZS50ZXh0KVxuICAgICAgZWxzZSBpZiAobmFtZS50ZXh0ID09IFwic2VtYW50aWZvbGRfa2VlcF9tdXRhYmxlXCIpIHRoaXMubXV0YWJsZU1hcmtlciA9IHRydWVcbiAgICAgIHN1cHBvcnRJbmRleCArPSAxXG4gICAgfVxuICAgIGlmIChzdXBwb3J0SW5kZXggPiAwICYmIHN1cHBvcnRJbmRleCAhPSBzdXBwb3J0Lmxlbmd0aCkgdGhpcy5mYWlsKHBhcnRzW3N1cHBvcnRJbmRleCAtIDFdLCBcImNvbXBsZXRlIFN3aWZ0IHN1cHBvcnQgcmVxdWlyZWRcIilcbiAgICBjb25zdCBzZW1hbnRpY1BhcnRzID0gcGFydHMuc2xpY2Uoc3VwcG9ydEluZGV4KVxuICAgIGNvbnN0IGZpcnN0RW50cnkgPSBzZW1hbnRpY1BhcnRzLmZpbmRJbmRleCgobm9kZSkgPT4gbm9kZS50eXBlICE9IFwiZnVuY3Rpb25fZGVjbGFyYXRpb25cIilcbiAgICBjb25zdCBzcGxpdCA9IGZpcnN0RW50cnkgPCAwID8gc2VtYW50aWNQYXJ0cy5sZW5ndGggOiBmaXJzdEVudHJ5XG4gICAgY29uc3QgZGVjbGFyYXRpb25zID0gc2VtYW50aWNQYXJ0cy5zbGljZSgwLCBzcGxpdClcbiAgICBjb25zdCBlbnRyaWVzID0gc2VtYW50aWNQYXJ0cy5zbGljZShzcGxpdClcblxuICAgIGlmICghZGVjbGFyYXRpb25zLmxlbmd0aCkgdGhpcy5mYWlsKHJvb3QsIFwidG9wLWxldmVsIHNlbWFudGljIGZ1bmN0aW9uIHJlcXVpcmVkXCIpXG4gICAgY29uc3QgbGF0ZXJGdW5jdGlvbiA9IGVudHJpZXMuZmluZCgobm9kZSkgPT4gbm9kZS50eXBlID09IFwiZnVuY3Rpb25fZGVjbGFyYXRpb25cIilcbiAgICBjb25zdCB1bnN1cHBvcnRlZEVudHJ5ID0gZW50cmllcy5maW5kKChub2RlKSA9PiAhW1wiYXNzaWdubWVudFwiLCBcImNhbGxfZXhwcmVzc2lvblwiLCBcImNvbnRyb2xfdHJhbnNmZXJfc3RhdGVtZW50XCIsIFwiaWZfc3RhdGVtZW50XCIsXG4gICAgICBcInByb3BlcnR5X2RlY2xhcmF0aW9uXCIsIFwiZnVuY3Rpb25fZGVjbGFyYXRpb25cIl0uaW5jbHVkZXMobm9kZS50eXBlKSlcblxuICAgIGlmICh1bnN1cHBvcnRlZEVudHJ5KSB0aGlzLmZhaWwodW5zdXBwb3J0ZWRFbnRyeSlcbiAgICBpZiAobGF0ZXJGdW5jdGlvbikgdGhpcy5mYWlsKGxhdGVyRnVuY3Rpb24sIFwiZnVuY3Rpb24gZGVjbGFyYXRpb24gYWZ0ZXIgZW50cnkgc3RhdGVtZW50XCIpXG4gICAgaWYgKCFlbnRyaWVzLmxlbmd0aCkgdGhpcy5mYWlsKHJvb3QsIFwidG9wLWxldmVsIGVudHJ5L3ByaW50IHNoZWxsIHJlcXVpcmVkXCIpXG4gICAgY29uc3QgbW9kdWxlID0ge1xuICAgICAgZW50cnlQb2ludDoge2JvZHk6IHtraW5kOiAvKiogQHR5cGUge2NvbnN0fSAqLyAoXCJCbG9ja1wiKSwgbG9jYXRpb246IHRoaXMubG9jYXRpb24ocm9vdCksXG4gICAgICAgIHN0YXRlbWVudHM6IHRoaXMuc3RhdGVtZW50TGlzdChlbnRyaWVzKX0sIGtpbmQ6IC8qKiBAdHlwZSB7Y29uc3R9ICovIChcIkVudHJ5UG9pbnRcIiksIGxvY2F0aW9uOiB0aGlzLmxvY2F0aW9uKHJvb3QpfSxcbiAgICAgIGZ1bmN0aW9uczogZGVjbGFyYXRpb25zLm1hcCgoZGVjbGFyYXRpb24pID0+IHRoaXMuZnVuY3Rpb24oZGVjbGFyYXRpb24pKSxcbiAgICAgIGtpbmQ6IC8qKiBAdHlwZSB7Y29uc3R9ICovIChcIk1vZHVsZVwiKSxcbiAgICAgIGxvY2F0aW9uOiB0aGlzLmxvY2F0aW9uKHJvb3QpXG4gICAgfVxuXG4gICAgdmFsaWRhdGVQYXJzZWRNb2R1bGUobW9kdWxlLCBcInN3aWZ0XCIpXG4gICAgdGhpcy5yZWplY3ROYXRpdmVTdHJpbmdFcXVhbGl0eShtb2R1bGUpXG4gICAgcmV0dXJuIG1vZHVsZVxuICB9XG59XG5cbi8qKlxuICogUGFyc2VzIHRoZSBzdHJpY3QgVGFzayAwMjIgU3dpZnQgcHJvZmlsZSB0aHJvdWdoIHRoZSBxdWFsaWZpZWQgZ3JhbW1hci5cbiAqIEBwYXJhbSB7e2ZpbGVuYW1lOiBzdHJpbmcsIHNvdXJjZTogc3RyaW5nfX0gaW5wdXQgLSBFeGFjdCBzb3VyY2UgcmVxdWVzdC5cbiAqIEByZXR1cm5zIHtpbXBvcnQoXCIuLi9zZW1hbnRpYy90eXBlcy5qc1wiKS5TZW1hbnRpY01vZHVsZX0gU2VtYW50aWMgbW9kdWxlLlxuICovXG5leHBvcnQgZnVuY3Rpb24gcGFyc2VTd2lmdCh7ZmlsZW5hbWUsIHNvdXJjZX0pIHtcbiAgaWYgKCFoYXNPbmx5VW5pY29kZVNjYWxhcnMoc291cmNlKSkge1xuICAgIGNvbnN0IG9mZnNldCA9IGZpcnN0TG9uZVN1cnJvZ2F0ZU9mZnNldChzb3VyY2UpXG5cbiAgICB0aHJvdyBuZXcgU2VtYW50aWZvbGREaWFnbm9zdGljKHtcbiAgICAgIGNvZGU6IFwiUEFSU0VfRVJST1JcIixcbiAgICAgIGxhbmd1YWdlOiBcInN3aWZ0XCIsXG4gICAgICBsb2NhdGlvbjogbG9jYXRpb25Gcm9tT2Zmc2V0cyhmaWxlbmFtZSwgc291cmNlLCBvZmZzZXQsIG9mZnNldCArIDEpLFxuICAgICAgbWVzc2FnZTogXCJTd2lmdCBzb3VyY2UgY29udGFpbnMgYW4gaW52YWxpZCBsb25lIFVURi0xNiBzdXJyb2dhdGUuXCJcbiAgICB9KVxuICB9XG4gIGxldCB0cmVlXG5cbiAgdHJ5IHtcbiAgICB0cmVlID0gcGFyc2VyLnBhcnNlKHNvdXJjZSlcbiAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICB0aHJvdyBuZXcgU2VtYW50aWZvbGREaWFnbm9zdGljKHtcbiAgICAgIGNhdXNlOiBlcnJvciBpbnN0YW5jZW9mIEVycm9yID8gZXJyb3IgOiB1bmRlZmluZWQsXG4gICAgICBjb2RlOiBcIlBBUlNFX0VSUk9SXCIsXG4gICAgICBsYW5ndWFnZTogXCJzd2lmdFwiLFxuICAgICAgbG9jYXRpb246IG1vZHVsZUxvY2F0aW9uKGZpbGVuYW1lLCBzb3VyY2UpLFxuICAgICAgbWVzc2FnZTogXCJUaGUgcXVhbGlmaWVkIFN3aWZ0IHBhcnNlciBjb3VsZCBub3QgcHJvZHVjZSBhIGNvbXBsZXRlIENTVC5cIlxuICAgIH0pXG4gIH1cbiAgcmV0dXJuIG5ldyBTd2lmdFJlYWRlcihmaWxlbmFtZSwgc291cmNlKS5tb2R1bGUodHJlZS5yb290Tm9kZSlcbn1cbiJdfQ==