semantifold 0.3.0 → 0.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (297) hide show
  1. package/README.md +58 -15
  2. package/build/index.d.ts +48 -2
  3. package/build/index.d.ts.map +1 -1
  4. package/build/index.js +57 -8
  5. package/build/src/artifact-path.d.ts +23 -1
  6. package/build/src/artifact-path.d.ts.map +1 -1
  7. package/build/src/artifact-path.js +45 -3
  8. package/build/src/artifacts.d.ts.map +1 -1
  9. package/build/src/artifacts.js +66 -1
  10. package/build/src/backends/c-validation.d.ts.map +1 -1
  11. package/build/src/backends/c-validation.js +7 -3
  12. package/build/src/backends/cpp-validation.d.ts.map +1 -1
  13. package/build/src/backends/cpp-validation.js +7 -3
  14. package/build/src/backends/csharp.js +7 -1
  15. package/build/src/backends/dart-runtime.d.ts +2 -0
  16. package/build/src/backends/dart-runtime.d.ts.map +1 -0
  17. package/build/src/backends/dart-runtime.js +41 -0
  18. package/build/src/backends/dart.d.ts +20 -0
  19. package/build/src/backends/dart.d.ts.map +1 -0
  20. package/build/src/backends/dart.js +321 -0
  21. package/build/src/backends/effects.d.ts +60 -0
  22. package/build/src/backends/effects.d.ts.map +1 -0
  23. package/build/src/backends/effects.js +746 -0
  24. package/build/src/backends/go.js +18 -4
  25. package/build/src/backends/identifiers.d.ts +36 -4
  26. package/build/src/backends/identifiers.d.ts.map +1 -1
  27. package/build/src/backends/identifiers.js +154 -10
  28. package/build/src/backends/index.d.ts.map +1 -1
  29. package/build/src/backends/index.js +27 -4
  30. package/build/src/backends/ios.d.ts +68 -0
  31. package/build/src/backends/ios.d.ts.map +1 -0
  32. package/build/src/backends/ios.js +1503 -0
  33. package/build/src/backends/java.d.ts.map +1 -1
  34. package/build/src/backends/java.js +429 -36
  35. package/build/src/backends/javascript.d.ts +6 -0
  36. package/build/src/backends/javascript.d.ts.map +1 -1
  37. package/build/src/backends/javascript.js +380 -24
  38. package/build/src/backends/kotlin-runtime.d.ts +3 -0
  39. package/build/src/backends/kotlin-runtime.d.ts.map +1 -0
  40. package/build/src/backends/kotlin-runtime.js +29 -0
  41. package/build/src/backends/kotlin.d.ts +23 -0
  42. package/build/src/backends/kotlin.d.ts.map +1 -0
  43. package/build/src/backends/kotlin.js +136 -0
  44. package/build/src/backends/native-validation.d.ts +2 -2
  45. package/build/src/backends/native-validation.d.ts.map +1 -1
  46. package/build/src/backends/native-validation.js +2 -2
  47. package/build/src/backends/ordered-expressions.d.ts.map +1 -1
  48. package/build/src/backends/ordered-expressions.js +39 -7
  49. package/build/src/backends/php-stdlib-support.d.ts +19 -0
  50. package/build/src/backends/php-stdlib-support.d.ts.map +1 -0
  51. package/build/src/backends/php-stdlib-support.js +227 -0
  52. package/build/src/backends/php.d.ts.map +1 -1
  53. package/build/src/backends/php.js +448 -33
  54. package/build/src/backends/program.d.ts +81 -0
  55. package/build/src/backends/program.d.ts.map +1 -0
  56. package/build/src/backends/program.js +1308 -0
  57. package/build/src/backends/python.js +7 -1
  58. package/build/src/backends/ruby.d.ts.map +1 -1
  59. package/build/src/backends/ruby.js +310 -24
  60. package/build/src/backends/rust-runtime.d.ts +7 -0
  61. package/build/src/backends/rust-runtime.d.ts.map +1 -0
  62. package/build/src/backends/rust-runtime.js +32 -0
  63. package/build/src/backends/rust-validation.d.ts +9 -0
  64. package/build/src/backends/rust-validation.d.ts.map +1 -0
  65. package/build/src/backends/rust-validation.js +78 -0
  66. package/build/src/backends/rust.d.ts +24 -0
  67. package/build/src/backends/rust.d.ts.map +1 -0
  68. package/build/src/backends/rust.js +344 -0
  69. package/build/src/backends/scalars.d.ts +14 -6
  70. package/build/src/backends/scalars.d.ts.map +1 -1
  71. package/build/src/backends/scalars.js +167 -17
  72. package/build/src/backends/shared.d.ts +23 -4
  73. package/build/src/backends/shared.d.ts.map +1 -1
  74. package/build/src/backends/shared.js +2158 -62
  75. package/build/src/backends/stdlib-support.d.ts +14 -0
  76. package/build/src/backends/stdlib-support.d.ts.map +1 -0
  77. package/build/src/backends/stdlib-support.js +237 -0
  78. package/build/src/backends/swift-runtime.d.ts +3 -0
  79. package/build/src/backends/swift-runtime.d.ts.map +1 -0
  80. package/build/src/backends/swift-runtime.js +14 -0
  81. package/build/src/backends/swift.d.ts +8 -0
  82. package/build/src/backends/swift.d.ts.map +1 -0
  83. package/build/src/backends/swift.js +127 -0
  84. package/build/src/backends/typescript.d.ts.map +1 -1
  85. package/build/src/backends/typescript.js +344 -24
  86. package/build/src/backends/wasm.d.ts +43 -0
  87. package/build/src/backends/wasm.d.ts.map +1 -0
  88. package/build/src/backends/wasm.js +2164 -0
  89. package/build/src/backends/writer.d.ts +235 -4
  90. package/build/src/backends/writer.d.ts.map +1 -1
  91. package/build/src/backends/writer.js +468 -3
  92. package/build/src/diagnostic.d.ts +4 -3
  93. package/build/src/diagnostic.d.ts.map +1 -1
  94. package/build/src/diagnostic.js +5 -3
  95. package/build/src/frontends/c.d.ts.map +1 -1
  96. package/build/src/frontends/c.js +5 -3
  97. package/build/src/frontends/cpp.d.ts.map +1 -1
  98. package/build/src/frontends/cpp.js +5 -3
  99. package/build/src/frontends/csharp.d.ts.map +1 -1
  100. package/build/src/frontends/csharp.js +7 -3
  101. package/build/src/frontends/dart.d.ts +10 -0
  102. package/build/src/frontends/dart.d.ts.map +1 -0
  103. package/build/src/frontends/dart.js +913 -0
  104. package/build/src/frontends/index.d.ts +3 -1
  105. package/build/src/frontends/index.d.ts.map +1 -1
  106. package/build/src/frontends/index.js +15 -5
  107. package/build/src/frontends/java.d.ts +110 -1
  108. package/build/src/frontends/java.d.ts.map +1 -1
  109. package/build/src/frontends/java.js +1725 -70
  110. package/build/src/frontends/javascript-typescript.d.ts +69 -1
  111. package/build/src/frontends/javascript-typescript.d.ts.map +1 -1
  112. package/build/src/frontends/javascript-typescript.js +1825 -93
  113. package/build/src/frontends/kotlin.d.ts +10 -0
  114. package/build/src/frontends/kotlin.d.ts.map +1 -0
  115. package/build/src/frontends/kotlin.js +685 -0
  116. package/build/src/frontends/php.d.ts +118 -1
  117. package/build/src/frontends/php.d.ts.map +1 -1
  118. package/build/src/frontends/php.js +1583 -76
  119. package/build/src/frontends/program.d.ts +74 -0
  120. package/build/src/frontends/program.d.ts.map +1 -0
  121. package/build/src/frontends/program.js +989 -0
  122. package/build/src/frontends/ruby.d.ts +68 -1
  123. package/build/src/frontends/ruby.d.ts.map +1 -1
  124. package/build/src/frontends/ruby.js +1446 -101
  125. package/build/src/frontends/rust-parser.d.ts +11 -0
  126. package/build/src/frontends/rust-parser.d.ts.map +1 -0
  127. package/build/src/frontends/rust-parser.js +15 -0
  128. package/build/src/frontends/rust.d.ts +14 -0
  129. package/build/src/frontends/rust.d.ts.map +1 -0
  130. package/build/src/frontends/rust.js +715 -0
  131. package/build/src/frontends/scalars.d.ts +10 -0
  132. package/build/src/frontends/scalars.d.ts.map +1 -1
  133. package/build/src/frontends/scalars.js +28 -2
  134. package/build/src/frontends/swift.d.ts +10 -0
  135. package/build/src/frontends/swift.d.ts.map +1 -0
  136. package/build/src/frontends/swift.js +860 -0
  137. package/build/src/frontends/types.d.ts +186 -0
  138. package/build/src/frontends/types.d.ts.map +1 -0
  139. package/build/src/frontends/types.js +634 -0
  140. package/build/src/language-registry.d.ts +46 -4
  141. package/build/src/language-registry.d.ts.map +1 -1
  142. package/build/src/language-registry.js +167 -13
  143. package/build/src/mapping.d.ts +2 -2
  144. package/build/src/mapping.d.ts.map +1 -1
  145. package/build/src/mapping.js +31 -10
  146. package/build/src/semantic/capabilities.d.ts +66 -0
  147. package/build/src/semantic/capabilities.d.ts.map +1 -0
  148. package/build/src/semantic/capabilities.js +649 -0
  149. package/build/src/semantic/effects.d.ts +26 -0
  150. package/build/src/semantic/effects.d.ts.map +1 -0
  151. package/build/src/semantic/effects.js +764 -0
  152. package/build/src/semantic/generics.d.ts +23 -0
  153. package/build/src/semantic/generics.d.ts.map +1 -0
  154. package/build/src/semantic/generics.js +61 -0
  155. package/build/src/semantic/lifetime.d.ts +37 -0
  156. package/build/src/semantic/lifetime.d.ts.map +1 -0
  157. package/build/src/semantic/lifetime.js +527 -0
  158. package/build/src/semantic/provenance.d.ts +9 -2
  159. package/build/src/semantic/provenance.d.ts.map +1 -1
  160. package/build/src/semantic/provenance.js +462 -20
  161. package/build/src/semantic/scalars.d.ts +11 -0
  162. package/build/src/semantic/scalars.d.ts.map +1 -1
  163. package/build/src/semantic/scalars.js +16 -1
  164. package/build/src/semantic/stdlib.d.ts +254 -0
  165. package/build/src/semantic/stdlib.d.ts.map +1 -0
  166. package/build/src/semantic/stdlib.js +880 -0
  167. package/build/src/semantic/types.d.ts +2952 -202
  168. package/build/src/semantic/types.d.ts.map +1 -1
  169. package/build/src/semantic/types.js +688 -15
  170. package/build/src/semantic/validate.d.ts +85 -5
  171. package/build/src/semantic/validate.d.ts.map +1 -1
  172. package/build/src/semantic/validate.js +2576 -98
  173. package/build/src/stdlib-facades.d.ts +304 -0
  174. package/build/src/stdlib-facades.d.ts.map +1 -0
  175. package/build/src/stdlib-facades.js +1167 -0
  176. package/build/src/stdlib-negotiation.d.ts +69 -0
  177. package/build/src/stdlib-negotiation.d.ts.map +1 -0
  178. package/build/src/stdlib-negotiation.js +403 -0
  179. package/build/src/stdlib-providers.d.ts +72 -0
  180. package/build/src/stdlib-providers.d.ts.map +1 -0
  181. package/build/src/stdlib-providers.js +339 -0
  182. package/build/src/toolchains.d.ts +55 -1
  183. package/build/src/toolchains.d.ts.map +1 -1
  184. package/build/src/toolchains.js +15 -4
  185. package/docs/architecture.md +45 -13
  186. package/docs/dart.md +60 -0
  187. package/docs/goals.md +3 -3
  188. package/docs/ios.md +121 -0
  189. package/docs/kotlin.md +42 -0
  190. package/docs/language-support.md +231 -26
  191. package/docs/multi-file-modules.md +52 -0
  192. package/docs/parser-qualification.md +121 -8
  193. package/docs/plans/2026-09-05-standard-library-portability.md +10 -10
  194. package/docs/rust.md +88 -0
  195. package/docs/source-maps.md +15 -7
  196. package/docs/standard-library-portability.md +39 -8
  197. package/docs/swift.md +44 -0
  198. package/docs/testing.md +366 -4
  199. package/docs/webassembly.md +52 -0
  200. package/index.js +63 -8
  201. package/node_modules/semantifold-tree-sitter-legacy-internal/README.md +2 -2
  202. package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/LICENSE +21 -0
  203. package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/README.md +45 -0
  204. package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/binding.gyp +30 -0
  205. package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/bindings/node/binding.cc +20 -0
  206. package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/bindings/node/binding_test.js +9 -0
  207. package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/bindings/node/index.d.ts +28 -0
  208. package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/bindings/node/index.js +11 -0
  209. package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/grammar.js +1630 -0
  210. package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/package.json +64 -0
  211. package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/prebuilds/darwin-arm64/tree-sitter-rust.node +0 -0
  212. package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/prebuilds/darwin-x64/tree-sitter-rust.node +0 -0
  213. package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/prebuilds/linux-arm64/tree-sitter-rust.node +0 -0
  214. package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/prebuilds/linux-x64/tree-sitter-rust.node +0 -0
  215. package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/prebuilds/win32-arm64/tree-sitter-rust.node +0 -0
  216. package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/prebuilds/win32-x64/tree-sitter-rust.node +0 -0
  217. package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/queries/highlights.scm +159 -0
  218. package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/queries/injections.scm +9 -0
  219. package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/queries/tags.scm +60 -0
  220. package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/src/grammar.json +9405 -0
  221. package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/src/node-types.json +5399 -0
  222. package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/src/parser.c +192569 -0
  223. package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/src/scanner.c +393 -0
  224. package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/src/tree_sitter/alloc.h +54 -0
  225. package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/src/tree_sitter/array.h +290 -0
  226. package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/src/tree_sitter/parser.h +266 -0
  227. package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/tree-sitter-rust.wasm +0 -0
  228. package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/tree-sitter.json +53 -0
  229. package/node_modules/semantifold-tree-sitter-legacy-internal/package.json +3 -2
  230. package/node_modules/semantifold-tree-sitter-legacy-internal/src/c.js +5 -4
  231. package/package.json +5 -2
  232. package/src/artifact-path.js +47 -2
  233. package/src/artifacts.js +67 -0
  234. package/src/backends/c-validation.js +6 -1
  235. package/src/backends/cpp-validation.js +6 -1
  236. package/src/backends/csharp.js +3 -0
  237. package/src/backends/dart-runtime.js +41 -0
  238. package/src/backends/dart.js +326 -0
  239. package/src/backends/effects.js +705 -0
  240. package/src/backends/go.js +14 -2
  241. package/src/backends/identifiers.js +160 -9
  242. package/src/backends/index.js +27 -2
  243. package/src/backends/ios.js +1612 -0
  244. package/src/backends/java.js +454 -36
  245. package/src/backends/javascript.js +389 -23
  246. package/src/backends/kotlin-runtime.js +29 -0
  247. package/src/backends/kotlin.js +141 -0
  248. package/src/backends/native-validation.js +1 -1
  249. package/src/backends/ordered-expressions.js +40 -6
  250. package/src/backends/php-stdlib-support.js +239 -0
  251. package/src/backends/php.js +469 -32
  252. package/src/backends/program.js +1407 -0
  253. package/src/backends/python.js +3 -0
  254. package/src/backends/ruby.js +326 -23
  255. package/src/backends/rust-runtime.js +34 -0
  256. package/src/backends/rust-validation.js +75 -0
  257. package/src/backends/rust.js +335 -0
  258. package/src/backends/scalars.js +141 -16
  259. package/src/backends/shared.js +2304 -124
  260. package/src/backends/stdlib-support.js +234 -0
  261. package/src/backends/swift-runtime.js +14 -0
  262. package/src/backends/swift.js +132 -0
  263. package/src/backends/typescript.js +349 -23
  264. package/src/backends/wasm.js +2208 -0
  265. package/src/backends/writer.js +520 -2
  266. package/src/diagnostic.js +4 -2
  267. package/src/frontends/c.js +4 -2
  268. package/src/frontends/cpp.js +4 -2
  269. package/src/frontends/csharp.js +4 -2
  270. package/src/frontends/dart.js +963 -0
  271. package/src/frontends/index.js +14 -4
  272. package/src/frontends/java.js +1977 -69
  273. package/src/frontends/javascript-typescript.js +2046 -102
  274. package/src/frontends/kotlin.js +713 -0
  275. package/src/frontends/php.js +1725 -79
  276. package/src/frontends/program.js +1062 -0
  277. package/src/frontends/ruby.js +1624 -98
  278. package/src/frontends/rust-parser.js +18 -0
  279. package/src/frontends/rust.js +714 -0
  280. package/src/frontends/scalars.js +31 -1
  281. package/src/frontends/swift.js +893 -0
  282. package/src/frontends/types.js +750 -0
  283. package/src/language-registry.js +172 -12
  284. package/src/mapping.js +33 -9
  285. package/src/semantic/capabilities.js +671 -0
  286. package/src/semantic/effects.js +737 -0
  287. package/src/semantic/generics.js +58 -0
  288. package/src/semantic/lifetime.js +517 -0
  289. package/src/semantic/provenance.js +412 -19
  290. package/src/semantic/scalars.js +17 -0
  291. package/src/semantic/stdlib.js +921 -0
  292. package/src/semantic/types.js +765 -14
  293. package/src/semantic/validate.js +2934 -209
  294. package/src/stdlib-facades.js +1211 -0
  295. package/src/stdlib-negotiation.js +446 -0
  296. package/src/stdlib-providers.js +377 -0
  297. package/src/toolchains.js +16 -3
@@ -0,0 +1,913 @@
1
+ // @ts-check
2
+ import Parser from "tree-sitter";
3
+ import DartLanguage from "tree-sitter-dart-orchard/bindings/node/index.js";
4
+ import { isDartIdentifier } from "../backends/identifiers.js";
5
+ import { dartRuntime } from "../backends/dart-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} */(DartLanguage)));
15
+ const binaryOperations = new Map([
16
+ ["+", "Add"], ["-", "Subtract"], ["*", "Multiply"], ["==", "Equal"], ["!=", "NotEqual"],
17
+ ["<", "LessThan"], ["<=", "LessThanOrEqual"], [">", "GreaterThan"], [">=", "GreaterThanOrEqual"],
18
+ ["&&", "And"], ["||", "Or"]
19
+ ]);
20
+ /** @type {Map<string, readonly [string, Set<string>]>} */
21
+ const binaryNodeOperators = new Map([
22
+ ["additive_expression", ["additive_operator", new Set(["+", "-"])]],
23
+ ["multiplicative_expression", ["multiplicative_operator", new Set(["*"])]],
24
+ ["equality_expression", ["equality_operator", new Set(["==", "!="])]],
25
+ ["relational_expression", ["relational_operator", new Set(["<", "<=", ">", ">="])]],
26
+ ["logical_and_expression", ["logical_and_operator", new Set(["&&"])]],
27
+ ["logical_or_expression", ["logical_or_operator", new Set(["||"])]]
28
+ ]);
29
+ const commentTypes = new Set(["comment", "documentation_comment"]);
30
+ /** @type {Map<string, import("../semantic/operators.js").AdaptedOperation>} */
31
+ const helperOperations = new Map([
32
+ ["_semantifoldIntegerAdd", "Add"], ["_semantifoldIntegerSubtract", "Subtract"],
33
+ ["_semantifoldIntegerMultiply", "Multiply"], ["_semantifoldIntegerNegate", "Negate"]
34
+ ]);
35
+ /**
36
+ * Verifies a binding-reported UTF-16 index through the shared UTF-8 converter.
37
+ * @param {string} source Complete source.
38
+ * @param {number} index Binding index.
39
+ * @returns {number} Verified UTF-16 offset.
40
+ */
41
+ function bindingIndexToUtf16Offset(source, index) {
42
+ if (!Number.isInteger(index) || index < 0 || index > source.length ||
43
+ index > 0 && index < source.length && /[\uD800-\uDBFF]/u.test(source[index - 1]) && /[\uDC00-\uDFFF]/u.test(source[index])) {
44
+ throw new RangeError("Invalid Tree-sitter source index: " + index);
45
+ }
46
+ return utf8ByteOffsetToUtf16Offset(source, new TextEncoder().encode(source.slice(0, index)).length);
47
+ }
48
+ /**
49
+ * Finds the first unpaired UTF-16 surrogate.
50
+ * @param {string} source Complete source.
51
+ * @returns {number} Invalid offset or -1.
52
+ */
53
+ function firstLoneSurrogateOffset(source) {
54
+ for (let index = 0; index < source.length; index += 1) {
55
+ const unit = source.charCodeAt(index);
56
+ if (unit >= 0xD800 && unit <= 0xDBFF) {
57
+ const next = source.charCodeAt(index + 1);
58
+ if (next >= 0xDC00 && next <= 0xDFFF)
59
+ index += 1;
60
+ else
61
+ return index;
62
+ }
63
+ else if (unit >= 0xDC00 && unit <= 0xDFFF)
64
+ return index;
65
+ }
66
+ return -1;
67
+ }
68
+ /** Consumes exact qualified Dart CST shapes without retaining parser values. */
69
+ class DartReader {
70
+ /**
71
+ * Creates a reader bound to one exact Dart source unit.
72
+ * @param {string} filename Original filename.
73
+ * @param {string} source Complete source.
74
+ */
75
+ constructor(filename, source) {
76
+ this.filename = filename;
77
+ this.source = source;
78
+ /** @type {Set<string>} */
79
+ this.functionNames = new Set();
80
+ this.runtime = false;
81
+ }
82
+ /**
83
+ * Builds a semantic source location from one parser node.
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 parser node with a located unsupported-syntax diagnostic.
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("dart", detail, this.location(node));
98
+ }
99
+ /**
100
+ * Traverses every named, anonymous, extra, field, and recovery edge.
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 > 0) {
107
+ const current = pending.pop();
108
+ if (!current)
109
+ throw new Error("Dart 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
+ node.fieldNameForChild(index);
120
+ pending.push({ depth: depth + 1, node: child, visited: false });
121
+ }
122
+ continue;
123
+ }
124
+ if (node.hasError || node.isError || node.isMissing) {
125
+ throw new SemantifoldDiagnostic({
126
+ code: "PARSE_ERROR",
127
+ language: "dart",
128
+ location: this.location(node),
129
+ message: `Tree-sitter exposed recovery at '${node.type}'.`
130
+ });
131
+ }
132
+ if (["annotation", "import_or_export", "library_name", "part_header", "part_of_header"].includes(node.type)) {
133
+ this.fail(node, node.type);
134
+ }
135
+ if (commentTypes.has(node.type) && (/(?:@dart\s*=|dartfmt|ignore(?:_for_file)?\s*:|language[-_ ]version)/iu.test(node.text) ||
136
+ /^\/\/ dart format (?:off|on)[\t ]*$/u.test(node.text))) {
137
+ this.fail(node, "directive-bearing comment");
138
+ }
139
+ }
140
+ }
141
+ /**
142
+ * Omits only ordinary comments already covered by exhaustive traversal.
143
+ * @param {import("tree-sitter").SyntaxNode} node Parent node.
144
+ * @returns {import("tree-sitter").SyntaxNode[]} Structural children.
145
+ */
146
+ parts(node) {
147
+ return node.children.filter((child) => !commentTypes.has(child.type));
148
+ }
149
+ /**
150
+ * Verifies an exact structural child sequence.
151
+ * @param {import("tree-sitter").SyntaxNode} node Shape owner.
152
+ * @param {(import("tree-sitter").SyntaxNode | string)[]} expected Exact child sequence.
153
+ * @returns {void}
154
+ */
155
+ shape(node, expected) {
156
+ const actual = this.parts(node);
157
+ if (actual.length != expected.length)
158
+ this.fail(actual[Math.min(actual.length, expected.length)] ?? node, `${node.type} child shape`);
159
+ for (let index = 0; index < expected.length; index += 1) {
160
+ const wanted = expected[index];
161
+ const child = actual[index];
162
+ const matches = typeof wanted == "string" ? child.text == wanted : child.id == wanted.id;
163
+ if (!matches)
164
+ this.fail(child, `${node.type} child shape`);
165
+ }
166
+ }
167
+ /**
168
+ * Consumes an Orchard operator wrapper whether its token is aliased into the wrapper or exposed anonymously.
169
+ * @param {import("tree-sitter").SyntaxNode} node Operator node.
170
+ * @returns {void}
171
+ */
172
+ operatorShape(node) {
173
+ const parts = this.parts(node);
174
+ if (parts.length > 1 || parts.length == 1 && (parts[0].isNamed || parts[0].text != node.text)) {
175
+ this.fail(node, `${node.type} child shape`);
176
+ }
177
+ this.shape(node, parts.length == 0 ? [] : [node.text]);
178
+ }
179
+ /**
180
+ * Returns exactly one parser child carrying a requested field name.
181
+ * @param {import("tree-sitter").SyntaxNode} node Field owner.
182
+ * @param {string} name Field name.
183
+ * @returns {import("tree-sitter").SyntaxNode} Sole field node.
184
+ */
185
+ field(node, name) {
186
+ const matches = [];
187
+ for (let index = 0; index < node.childCount; index += 1) {
188
+ const child = node.child(index);
189
+ if (!child)
190
+ throw new Error(`Tree-sitter omitted child ${index} of ${node.type}.`);
191
+ if (node.fieldNameForChild(index) == name)
192
+ matches.push(child);
193
+ }
194
+ if (matches.length != 1)
195
+ this.fail(node, `expected one '${name}' field`);
196
+ return matches[0];
197
+ }
198
+ /**
199
+ * Validates and returns a source identifier.
200
+ * @param {import("tree-sitter").SyntaxNode} node Identifier token.
201
+ * @param {boolean} [allowMain] Whether fixed main is expected.
202
+ * @param {boolean} [allowPrint] Whether fixed print is expected.
203
+ * @returns {string} Accepted name.
204
+ */
205
+ identifier(node, allowMain = false, allowPrint = false) {
206
+ const name = node.text;
207
+ if (node.type != "identifier" || !(allowMain && name == "main") && !(allowPrint && name == "print") &&
208
+ !isDartIdentifier(name))
209
+ this.fail(node, "reserved or unsupported identifier");
210
+ return name;
211
+ }
212
+ /**
213
+ * Converts one explicitly named scalar type.
214
+ * @param {import("tree-sitter").SyntaxNode} node Type node.
215
+ * @returns {import("../semantic/types.js").TypeReference} Scalar type.
216
+ */
217
+ scalarType(node) {
218
+ if (node.type != "type_identifier" || this.parts(node).length != 0)
219
+ this.fail(node, "scalar type shape");
220
+ const type = sourceScalarType("dart", node.text, this.location(node));
221
+ if (!type)
222
+ this.fail(node, `unsupported scalar type '${node.text}'`);
223
+ return type;
224
+ }
225
+ /**
226
+ * Converts one explicit scalar or void result type.
227
+ * @param {import("tree-sitter").SyntaxNode} node Return type node.
228
+ * @returns {import("../semantic/types.js").SemanticFunctionReturnType} Function return type.
229
+ */
230
+ returnType(node) {
231
+ if (node.type == "void_type") {
232
+ const parts = this.parts(node);
233
+ if (node.text != "void" || parts.length > 1 || parts.length == 1 && parts[0].text != "void") {
234
+ this.fail(node, "void type shape");
235
+ }
236
+ this.shape(node, parts);
237
+ const type = { kind: /** @type {const} */ ("TypeReference"), name: /** @type {const} */ ("void") };
238
+ return withParserRanges(type, { type: this.location(node) });
239
+ }
240
+ return this.scalarType(node);
241
+ }
242
+ /**
243
+ * Decodes one ordinary noninterpolated, non-raw, single-line Dart string.
244
+ * @param {import("tree-sitter").SyntaxNode} node String node.
245
+ * @returns {string} Decoded Unicode scalar value.
246
+ */
247
+ string(node) {
248
+ const parts = this.parts(node);
249
+ const delimiter = node.text[0];
250
+ if (node.type != "string_literal" || !["\"", "'"].includes(delimiter) || node.text.startsWith(delimiter.repeat(3)) ||
251
+ node.text.at(-1) != delimiter || parts.length < 2 || parts[0].text != delimiter || parts.at(-1)?.text != delimiter ||
252
+ parts.slice(1, -1).some(({ type }) => type != "escape_sequence")) {
253
+ this.fail(node, "ordinary noninterpolated string literal required");
254
+ }
255
+ this.shape(node, parts);
256
+ const source = node.text.slice(1, -1);
257
+ const simpleEscapes = new Map([
258
+ ["b", "\b"], ["f", "\f"], ["n", "\n"], ["r", "\r"], ["t", "\t"], ["v", "\v"],
259
+ ["$", "$"], ["'", "'"], ['"', '"'], ["\\", "\\"]
260
+ ]);
261
+ let value = "";
262
+ for (let index = 0; index < source.length; index += 1) {
263
+ const character = source[index];
264
+ if (character != "\\") {
265
+ if (character == "\n" || character == "\r" || character == delimiter || character == "$") {
266
+ this.fail(node, "invalid or interpolated string content");
267
+ }
268
+ value += character;
269
+ continue;
270
+ }
271
+ const escaped = source[++index];
272
+ if (simpleEscapes.has(escaped))
273
+ value += simpleEscapes.get(escaped);
274
+ else if (escaped == "x") {
275
+ const hexadecimal = source.slice(index + 1, index + 3);
276
+ if (!/^[0-9A-Fa-f]{2}$/u.test(hexadecimal))
277
+ this.fail(node, "unsupported string escape");
278
+ value += String.fromCodePoint(Number.parseInt(hexadecimal, 16));
279
+ index += 2;
280
+ }
281
+ else if (escaped == "u") {
282
+ if (source[index + 1] == "{") {
283
+ const closing = source.indexOf("}", index + 2);
284
+ const hexadecimal = closing < 0 ? "" : source.slice(index + 2, closing);
285
+ const codePoint = /^[0-9A-Fa-f]{1,6}$/u.test(hexadecimal) ? Number.parseInt(hexadecimal, 16) : -1;
286
+ if (codePoint < 0 || codePoint > 0x10FFFF)
287
+ this.fail(node, "unsupported string escape");
288
+ value += String.fromCodePoint(codePoint);
289
+ index = closing;
290
+ }
291
+ else {
292
+ const hexadecimal = source.slice(index + 1, index + 5);
293
+ if (!/^[0-9A-Fa-f]{4}$/u.test(hexadecimal))
294
+ this.fail(node, "unsupported string escape");
295
+ value += String.fromCharCode(Number.parseInt(hexadecimal, 16));
296
+ index += 4;
297
+ }
298
+ }
299
+ else
300
+ this.fail(node, "unsupported string escape");
301
+ }
302
+ if (!hasOnlyUnicodeScalars(value))
303
+ this.fail(node, "invalid Unicode string literal");
304
+ return value;
305
+ }
306
+ /**
307
+ * Extracts exact required positional arguments.
308
+ * @param {import("tree-sitter").SyntaxNode} part Call argument part.
309
+ * @returns {import("tree-sitter").SyntaxNode[][]} Argument expression edges.
310
+ */
311
+ arguments(part) {
312
+ const partChildren = this.parts(part);
313
+ if (part.type != "argument_part" || partChildren.length != 1 || partChildren[0].type != "arguments") {
314
+ this.fail(part, "call argument part shape");
315
+ }
316
+ this.shape(part, [partChildren[0]]);
317
+ const list = partChildren[0];
318
+ const listParts = this.parts(list);
319
+ if (listParts.length < 2 || listParts[0].text != "(" || listParts.at(-1)?.text != ")") {
320
+ this.fail(list, "call argument list shape");
321
+ }
322
+ const interior = listParts.slice(1, -1);
323
+ const hasGeneratedTrailingComma = this.runtime && interior.at(-1)?.text == ",";
324
+ const argumentParts = hasGeneratedTrailingComma ? interior.slice(0, -1) : interior;
325
+ const arguments_ = argumentParts.filter((_child, index) => index % 2 == 0);
326
+ this.shape(list, ["(", ...arguments_.flatMap((argument, index) => index ? [",", argument] : [argument]),
327
+ ...(hasGeneratedTrailingComma ? [","] : []), ")"]);
328
+ return arguments_.map((argument) => {
329
+ if (argument.type != "argument")
330
+ this.fail(argument, "required positional argument");
331
+ const expressionParts = this.parts(argument);
332
+ if (expressionParts.length == 0)
333
+ this.fail(argument, "empty argument");
334
+ return expressionParts;
335
+ });
336
+ }
337
+ /**
338
+ * Converts one direct method-invocation node whose function is a plain identifier.
339
+ * @param {import("tree-sitter").SyntaxNode[]} nodes Exact one-node call.
340
+ * @param {import("tree-sitter").SyntaxNode} owner Expression owner.
341
+ * @param {boolean} [allowPrint] Whether this is the print scaffold.
342
+ * @returns {import("../semantic/types.js").Expression} Semantic call or private generated operation.
343
+ */
344
+ call(nodes, owner, allowPrint = false) {
345
+ if (nodes.length != 1 || nodes[0].type != "method_invocation") {
346
+ this.fail(nodes[0] ?? owner, "direct call shape");
347
+ }
348
+ const invocation = nodes[0];
349
+ const parts = this.parts(invocation);
350
+ const functionNode = this.field(invocation, "function");
351
+ const argumentPart = this.field(invocation, "arguments");
352
+ if (parts.length != 2 || parts[0].id != functionNode.id || functionNode.type != "identifier" ||
353
+ parts[1].id != argumentPart.id || argumentPart.type != "argument_part")
354
+ this.fail(invocation, "direct call shape");
355
+ this.shape(invocation, [functionNode, argumentPart]);
356
+ const name = functionNode.text;
357
+ const helper = this.runtime ? helperOperations.get(name) : undefined;
358
+ const location = this.location(invocation);
359
+ const argumentNodes = this.arguments(argumentPart);
360
+ if (this.runtime && name == "_semantifoldBoolean") {
361
+ if (argumentNodes.length != 1)
362
+ this.fail(argumentPart, "Dart Boolean literal helper shape");
363
+ const literal = this.expression(argumentNodes[0], owner);
364
+ if (literal.kind != "BooleanLiteral")
365
+ this.fail(argumentPart, "Dart Boolean literal helper shape");
366
+ return literal;
367
+ }
368
+ if (helper) {
369
+ const count = helper == "Negate" ? 1 : 2;
370
+ if (argumentNodes.length != count)
371
+ this.fail(argumentPart, "Dart checked-integer helper shape");
372
+ if (helper == "Negate") {
373
+ return /** @type {import("../semantic/types.js").Expression} */ ( /** @type {unknown} */(withAdaptedOperation(withParserRanges({
374
+ kind: /** @type {const} */ ("UnaryExpression"), location,
375
+ operand: this.expression(argumentNodes[0], owner)
376
+ }, { operator: this.location(functionNode) }), helper)));
377
+ }
378
+ return /** @type {import("../semantic/types.js").Expression} */ ( /** @type {unknown} */(withAdaptedOperation(withParserRanges({
379
+ kind: /** @type {const} */ ("BinaryExpression"), left: this.expression(argumentNodes[0], owner), location,
380
+ right: this.expression(argumentNodes[1], owner)
381
+ }, { operator: this.location(functionNode) }), helper)));
382
+ }
383
+ this.identifier(functionNode, false, allowPrint);
384
+ return withParserRanges({
385
+ arguments: argumentNodes.map((argument) => this.expression(argument, owner)),
386
+ callee: name,
387
+ kind: /** @type {const} */ ("CallExpression"),
388
+ location
389
+ }, { callee: this.location(functionNode) });
390
+ }
391
+ /**
392
+ * Recursively compares one source support subtree with the canonical runtime CST.
393
+ * @param {import("tree-sitter").SyntaxNode} actual Source node.
394
+ * @param {import("tree-sitter").SyntaxNode} expected Canonical node.
395
+ * @returns {void}
396
+ */
397
+ compareTree(actual, expected) {
398
+ if (actual.type != expected.type || actual.isNamed != expected.isNamed || actual.isExtra != expected.isExtra ||
399
+ actual.childCount != expected.childCount)
400
+ this.fail(actual, "modified Dart support node");
401
+ if (actual.childCount == 0 && actual.text != expected.text)
402
+ this.fail(actual, "modified Dart support token");
403
+ for (let index = 0; index < actual.childCount; index += 1) {
404
+ const left = actual.child(index);
405
+ const right = expected.child(index);
406
+ if (!left || !right || actual.fieldNameForChild(index) != expected.fieldNameForChild(index)) {
407
+ this.fail(left ?? actual, "modified Dart support field");
408
+ }
409
+ this.compareTree(left, right);
410
+ }
411
+ }
412
+ /**
413
+ * Converts an expression represented by one or more adjacent Dart CST nodes.
414
+ * @param {import("tree-sitter").SyntaxNode[]} nodes Expression nodes.
415
+ * @param {import("tree-sitter").SyntaxNode} owner Owning node.
416
+ * @returns {import("../semantic/types.js").Expression} Semantic expression.
417
+ */
418
+ expression(nodes, owner) {
419
+ if (nodes.length == 1 && nodes[0].type == "method_invocation")
420
+ return this.call(nodes, owner);
421
+ if (nodes.length != 1)
422
+ return this.fail(nodes[0] ?? owner, "scalar expression shape");
423
+ const node = nodes[0];
424
+ const location = this.location(node);
425
+ if (node.type == "identifier") {
426
+ const name = this.identifier(node);
427
+ if (this.functionNames.has(name))
428
+ this.fail(node, "function tear-off");
429
+ return withParserRanges({ kind: /** @type {const} */ ("IdentifierExpression"), location, name }, { name: location });
430
+ }
431
+ if (node.type == "decimal_integer_literal") {
432
+ if (this.parts(node).length != 0 || !/^(?:0|[1-9][0-9]*)$/u.test(node.text))
433
+ this.fail(node, "noncanonical integer literal");
434
+ const value = Number(BigInt(node.text));
435
+ if (!Number.isSafeInteger(value))
436
+ this.fail(node, "non-safe integer literal");
437
+ return withParserRanges({ kind: /** @type {const} */ ("IntegerLiteral"), location, value }, { literal: location });
438
+ }
439
+ if (node.type == "true" || node.type == "false") {
440
+ this.shape(node, [node.type]);
441
+ return withParserRanges({ kind: /** @type {const} */ ("BooleanLiteral"), location, value: node.type == "true" }, { literal: location });
442
+ }
443
+ if (node.type == "string_literal") {
444
+ return withParserRanges({ kind: /** @type {const} */ ("StringLiteral"), location, value: this.string(node) }, { literal: location });
445
+ }
446
+ if (node.type == "parenthesized_expression") {
447
+ const parts = this.parts(node);
448
+ if (parts.length < 3 || parts[0].text != "(" || parts.at(-1)?.text != ")")
449
+ this.fail(node, "parenthesized expression shape");
450
+ this.shape(node, ["(", ...parts.slice(1, -1), ")"]);
451
+ return this.expression(parts.slice(1, -1), node);
452
+ }
453
+ if (node.type == "unary_expression") {
454
+ const parts = this.parts(node);
455
+ const operator = parts[0];
456
+ if (parts.length < 2 || operator.type != "prefix_operator" || !["-", "!"].includes(operator.text)) {
457
+ this.fail(node, "unary operator");
458
+ }
459
+ const operatorParts = this.parts(operator);
460
+ if (operatorParts.length != 1 || operatorParts[0].text != operator.text ||
461
+ !["minus_operator", "negation_operator"].includes(operatorParts[0].type))
462
+ this.fail(operator, "unary operator shape");
463
+ this.operatorShape(operatorParts[0]);
464
+ this.shape(node, [operator, ...parts.slice(1)]);
465
+ return /** @type {import("../semantic/types.js").Expression} */ ( /** @type {unknown} */(withAdaptedOperation(withParserRanges({
466
+ kind: /** @type {const} */ ("UnaryExpression"),
467
+ location,
468
+ operand: this.expression(parts.slice(1), node)
469
+ }, { operator: this.location(operator) }), operator.text == "-" ? "Negate" : "Not")));
470
+ }
471
+ if (binaryNodeOperators.has(node.type))
472
+ return this.binary(node);
473
+ return this.fail(node);
474
+ }
475
+ /**
476
+ * Converts a bounded binary expression tree.
477
+ * @param {import("tree-sitter").SyntaxNode} node Binary expression node.
478
+ * @returns {import("../semantic/types.js").Expression} Semantic binary expression.
479
+ */
480
+ binary(node) {
481
+ /** @type {import("tree-sitter").SyntaxNode[][]} */
482
+ const operands = [];
483
+ /** @type {import("tree-sitter").SyntaxNode[]} */
484
+ const operators = [];
485
+ let current = node;
486
+ while (true) {
487
+ const parts = this.parts(current);
488
+ const declaration = binaryNodeOperators.get(current.type);
489
+ const operatorType = declaration?.[0];
490
+ const accepted = declaration?.[1];
491
+ const operatorIndexes = parts.flatMap((part, index) => part.type == operatorType ? [index] : []);
492
+ if (operatorIndexes.length != 1)
493
+ this.fail(current, `${current.type} child shape`);
494
+ const operatorIndex = operatorIndexes[0];
495
+ const operator = parts[operatorIndex];
496
+ if (operatorIndex == 0 || operatorIndex == parts.length - 1 || !accepted?.has(operator.text) ||
497
+ !binaryOperations.has(operator.text))
498
+ this.fail(operator, "unsupported binary operator");
499
+ this.operatorShape(operator);
500
+ this.shape(current, parts);
501
+ operands.push(parts.slice(0, operatorIndex));
502
+ operators.push(operator);
503
+ const right = parts.slice(operatorIndex + 1);
504
+ if (right.length == 1 && right[0].type == node.type)
505
+ current = right[0];
506
+ else {
507
+ operands.push(right);
508
+ break;
509
+ }
510
+ }
511
+ let expression = this.expression(operands[0], node);
512
+ for (let index = 0; index < operators.length; index += 1) {
513
+ const operator = operators[index];
514
+ const operation = binaryOperations.get(operator.text);
515
+ const right = this.expression(operands[index + 1], node);
516
+ const first = operands[0][0];
517
+ const last = operands[index + 1].at(-1);
518
+ const location = first && last
519
+ ? locationFromOffsets(this.filename, this.source, bindingIndexToUtf16Offset(this.source, first.startIndex), bindingIndexToUtf16Offset(this.source, last.endIndex))
520
+ : this.location(node);
521
+ expression = /** @type {import("../semantic/types.js").Expression} */ (withAdaptedOperation(withParserRanges({
522
+ kind: /** @type {const} */ ("BinaryExpression"), left: expression, location, right
523
+ }, { operator: this.location(operator) }), /** @type {import("../semantic/operators.js").AdaptedOperation} */ (operation)));
524
+ }
525
+ return expression;
526
+ }
527
+ /**
528
+ * Converts one explicitly typed initialized local declaration.
529
+ * @param {import("tree-sitter").SyntaxNode} node Local declaration.
530
+ * @returns {import("../semantic/types.js").LocalDeclaration} Semantic local.
531
+ */
532
+ local(node) {
533
+ const declarationParts = this.parts(node);
534
+ if (node.type != "local_variable_declaration" || declarationParts.length != 2 ||
535
+ declarationParts[0].type != "initialized_variable_definition" || declarationParts[1].text != ";") {
536
+ this.fail(node, "local declaration shape");
537
+ }
538
+ this.shape(node, [declarationParts[0], ";"]);
539
+ const definition = declarationParts[0];
540
+ const parts = this.parts(definition);
541
+ if (parts[0]?.type == "inferred_type" || parts[0]?.type == "final_builtin" && parts[1]?.type == "identifier") {
542
+ return missingType("dart", "Local", this.location(definition));
543
+ }
544
+ const immutable = parts[0]?.type == "final_builtin";
545
+ const typeIndex = immutable ? 1 : 0;
546
+ const typeNode = parts[typeIndex];
547
+ const nameNode = parts[typeIndex + 1];
548
+ const equals = parts[typeIndex + 2];
549
+ const expressionParts = parts.slice(typeIndex + 3);
550
+ if (parts.length < typeIndex + 4 || typeNode?.type != "type_identifier" || nameNode?.type != "identifier" ||
551
+ equals?.text != "=" || expressionParts.length == 0 || immutable && parts[0].text != "final") {
552
+ this.fail(parts[0] ?? definition, "explicitly typed initialized local required");
553
+ }
554
+ this.shape(definition, [...(immutable ? [parts[0]] : []), typeNode, nameNode, "=", ...expressionParts]);
555
+ if (this.field(definition, "name").id != nameNode.id)
556
+ this.fail(nameNode, "local name field");
557
+ const name = this.identifier(nameNode);
558
+ return withParserRanges({
559
+ initializer: this.expression(expressionParts, definition),
560
+ kind: /** @type {const} */ ("LocalDeclaration"),
561
+ location: this.location(node),
562
+ mutable: !immutable,
563
+ name,
564
+ type: this.scalarType(typeNode)
565
+ }, { name: this.location(nameNode), operator: this.location(equals) });
566
+ }
567
+ /**
568
+ * Converts one simple identifier assignment.
569
+ * @param {import("tree-sitter").SyntaxNode} node Assignment expression.
570
+ * @returns {import("../semantic/types.js").AssignmentStatement} Semantic assignment.
571
+ */
572
+ assignment(node) {
573
+ const parts = this.parts(node);
574
+ const target = parts[0];
575
+ const operator = parts[1];
576
+ if (node.type != "assignment_expression" || parts.length < 3 || target?.type != "assignable_expression" ||
577
+ operator?.type != "assignment_operator" || operator.text != "=")
578
+ this.fail(node, "simple assignment shape");
579
+ const targetParts = this.parts(target);
580
+ if (targetParts.length != 1 || targetParts[0].type != "identifier")
581
+ this.fail(target, "simple assignment target");
582
+ this.shape(target, [targetParts[0]]);
583
+ this.operatorShape(operator);
584
+ this.shape(node, [target, "=", ...parts.slice(2)]);
585
+ const name = this.identifier(targetParts[0]);
586
+ const targetLocation = this.location(targetParts[0]);
587
+ return withParserRanges({
588
+ expression: this.expression(parts.slice(2), node),
589
+ kind: /** @type {const} */ ("AssignmentStatement"),
590
+ location: this.location(node),
591
+ target: withParserRanges({ kind: /** @type {const} */ ("IdentifierExpression"), location: targetLocation, name }, { name: targetLocation })
592
+ }, { operator: this.location(operator) });
593
+ }
594
+ /**
595
+ * Converts one supported Dart statement.
596
+ * @param {import("tree-sitter").SyntaxNode} node Source statement.
597
+ * @returns {import("../semantic/types.js").Statement} Semantic statement.
598
+ */
599
+ statement(node) {
600
+ if (node.type == "local_variable_declaration")
601
+ return this.local(node);
602
+ if (node.type == "if_statement")
603
+ return this.conditional(node);
604
+ if (node.type == "return_statement") {
605
+ const parts = this.parts(node);
606
+ if (parts.length < 2 || parts[0].text != "return" || parts.at(-1)?.text != ";")
607
+ this.fail(node, "return statement shape");
608
+ this.shape(node, ["return", ...parts.slice(1, -1), ";"]);
609
+ const expressionParts = parts.slice(1, -1);
610
+ return {
611
+ ...(expressionParts.length > 0 ? { expression: this.expression(expressionParts, node) } : {}),
612
+ kind: /** @type {const} */ ("ReturnStatement"),
613
+ location: this.location(node)
614
+ };
615
+ }
616
+ if (node.type == "expression_statement") {
617
+ const parts = this.parts(node);
618
+ if (parts.length < 2 || parts.at(-1)?.text != ";")
619
+ this.fail(node, "expression statement shape");
620
+ this.shape(node, [...parts.slice(0, -1), ";"]);
621
+ if (parts.length == 2 && parts[0].type == "assignment_expression")
622
+ return this.assignment(parts[0]);
623
+ const callParts = parts.slice(0, -1);
624
+ const callChildren = callParts.length == 1 && callParts[0].type == "method_invocation"
625
+ ? this.parts(callParts[0]) : [];
626
+ const print = callChildren[0]?.type == "identifier" && callChildren[0].text == "print";
627
+ const expression = this.call(callParts, node, print);
628
+ if (print) {
629
+ if (expression.kind != "CallExpression" || expression.arguments.length != 1) {
630
+ this.fail(callParts[0], "print argument count");
631
+ }
632
+ return { expression: expression.arguments[0], kind: /** @type {const} */ ("PrintStatement"), location: this.location(node) };
633
+ }
634
+ if (expression.kind != "CallExpression")
635
+ this.fail(callParts[0], "generated helper expression statement");
636
+ return { expression, kind: /** @type {const} */ ("ExpressionStatement"), location: this.location(node) };
637
+ }
638
+ return this.fail(node);
639
+ }
640
+ /**
641
+ * Consumes one compiler-owned read that prevents Dart from rejecting an otherwise unread local.
642
+ * @param {import("tree-sitter").SyntaxNode} node Candidate source statement.
643
+ * @param {import("../semantic/types.js").Statement | undefined} previous Previous semantic statement.
644
+ * @returns {boolean} Whether the exact authenticated support statement was consumed.
645
+ */
646
+ generatedLocalUse(node, previous) {
647
+ if (!this.runtime || previous?.kind != "LocalDeclaration" || node.type != "expression_statement")
648
+ return false;
649
+ const statementParts = this.parts(node);
650
+ const invocation = statementParts[0];
651
+ if (statementParts.length != 2 || invocation?.type != "method_invocation" || statementParts[1].text != ";")
652
+ return false;
653
+ const invocationParts = this.parts(invocation);
654
+ const functionNode = this.field(invocation, "function");
655
+ const argumentPart = this.field(invocation, "arguments");
656
+ if (invocationParts.length != 2 || invocationParts[0].id != functionNode.id || functionNode.type != "identifier" ||
657
+ functionNode.text != "_semantifoldUse" || invocationParts[1].id != argumentPart.id || argumentPart.type != "argument_part") {
658
+ return false;
659
+ }
660
+ this.shape(node, [invocation, ";"]);
661
+ this.shape(invocation, [functionNode, argumentPart]);
662
+ const arguments_ = this.arguments(argumentPart);
663
+ if (arguments_.length != 1 || arguments_[0].length != 1 || arguments_[0][0].type != "identifier" ||
664
+ this.identifier(arguments_[0][0]) != previous.name)
665
+ this.fail(argumentPart, "Dart analyzer local-use support shape");
666
+ return true;
667
+ }
668
+ /**
669
+ * Converts a braced Dart block.
670
+ * @param {import("tree-sitter").SyntaxNode} node Braced block.
671
+ * @returns {import("../semantic/types.js").Block} Semantic block.
672
+ */
673
+ block(node) {
674
+ const parts = this.parts(node);
675
+ if (node.type != "block" || parts.length < 2 || parts[0].text != "{" || parts.at(-1)?.text != "}") {
676
+ this.fail(node, "braced block shape");
677
+ }
678
+ this.shape(node, ["{", ...parts.slice(1, -1), "}"]);
679
+ /** @type {import("../semantic/types.js").Statement[]} */
680
+ const statements = [];
681
+ for (const statement of parts.slice(1, -1)) {
682
+ if (!this.generatedLocalUse(statement, statements.at(-1)))
683
+ statements.push(this.statement(statement));
684
+ }
685
+ return {
686
+ kind: /** @type {const} */ ("Block"),
687
+ location: this.location(node),
688
+ statements
689
+ };
690
+ }
691
+ /**
692
+ * Unwraps a synchronous braced function body.
693
+ * @param {import("tree-sitter").SyntaxNode} body Function body wrapper.
694
+ * @returns {import("../semantic/types.js").Block} Semantic body.
695
+ */
696
+ functionBody(body) {
697
+ const parts = this.parts(body);
698
+ if (body.type != "function_body" || parts.length != 1 || parts[0].type != "block") {
699
+ this.fail(body, "synchronous braced function body required");
700
+ }
701
+ this.shape(body, [parts[0]]);
702
+ return this.block(parts[0]);
703
+ }
704
+ /**
705
+ * Converts one strict-Boolean conditional.
706
+ * @param {import("tree-sitter").SyntaxNode} node Strict Boolean conditional.
707
+ * @returns {import("../semantic/types.js").IfStatement} Semantic conditional.
708
+ */
709
+ conditional(node) {
710
+ const parts = this.parts(node);
711
+ const consequence = this.field(node, "consequence");
712
+ const consequenceIndex = parts.findIndex(({ id }) => id == consequence.id);
713
+ if (node.type != "if_statement" || parts[0]?.text != "if" || parts[1]?.text != "(" || consequence.type != "block" ||
714
+ consequenceIndex < 4 || parts[consequenceIndex - 1]?.text != ")")
715
+ this.fail(node, "if statement shape");
716
+ const conditionParts = parts.slice(2, consequenceIndex - 1);
717
+ if (conditionParts.length == 0)
718
+ this.fail(node, "empty if condition");
719
+ const statement = /** @type {import("../semantic/types.js").IfStatement} */ ({
720
+ condition: this.expression(conditionParts, node),
721
+ consequent: this.block(consequence),
722
+ kind: /** @type {const} */ ("IfStatement"),
723
+ location: this.location(node)
724
+ });
725
+ if (parts.length == consequenceIndex + 1) {
726
+ this.shape(node, ["if", "(", ...conditionParts, ")", consequence]);
727
+ return statement;
728
+ }
729
+ const alternative = this.field(node, "alternative");
730
+ if (parts.length != consequenceIndex + 3 || parts[consequenceIndex + 1]?.text != "else" ||
731
+ parts[consequenceIndex + 2]?.id != alternative.id)
732
+ this.fail(alternative, "if alternate shape");
733
+ this.shape(node, ["if", "(", ...conditionParts, ")", consequence, "else", alternative]);
734
+ if (alternative.type == "block")
735
+ return { ...statement, alternate: this.block(alternative) };
736
+ if (alternative.type == "if_statement") {
737
+ return { ...statement, alternate: {
738
+ kind: /** @type {const} */ ("Block"), location: this.location(alternative), statements: [this.conditional(alternative)]
739
+ } };
740
+ }
741
+ return this.fail(alternative, "braced block or else-if required");
742
+ }
743
+ /**
744
+ * Converts one required explicitly typed positional parameter.
745
+ * @param {import("tree-sitter").SyntaxNode} node Required positional parameter.
746
+ * @returns {import("../semantic/types.js").Parameter} Semantic parameter.
747
+ */
748
+ parameter(node) {
749
+ const parts = this.parts(node);
750
+ if (parts.length == 1 && parts[0].type == "identifier")
751
+ return missingType("dart", "Parameter", this.location(node));
752
+ if (node.type != "formal_parameter" || parts.length != 2 || parts[0].type != "type_identifier" ||
753
+ parts[1].type != "identifier")
754
+ this.fail(node, "required explicitly typed positional parameter");
755
+ this.shape(node, [parts[0], parts[1]]);
756
+ if (this.field(node, "name").id != parts[1].id)
757
+ this.fail(parts[1], "parameter name field");
758
+ const name = this.identifier(parts[1]);
759
+ return withParserRanges({
760
+ kind: /** @type {const} */ ("Parameter"), location: this.location(node), name, type: this.scalarType(parts[0])
761
+ }, { name: this.location(parts[1]) });
762
+ }
763
+ /**
764
+ * Converts a required positional parameter list.
765
+ * @param {import("tree-sitter").SyntaxNode} node Parameter list.
766
+ * @returns {import("../semantic/types.js").Parameter[]} Semantic parameters.
767
+ */
768
+ parameters(node) {
769
+ const parts = this.parts(node);
770
+ if (node.type != "formal_parameter_list" || parts.length < 2 || parts[0].text != "(" || parts.at(-1)?.text != ")") {
771
+ this.fail(node, "formal parameter list shape");
772
+ }
773
+ const interior = parts.slice(1, -1);
774
+ const hasGeneratedTrailingComma = this.runtime && interior.at(-1)?.text == ",";
775
+ const parameterParts = hasGeneratedTrailingComma ? interior.slice(0, -1) : interior;
776
+ const parameters = parameterParts.filter((_child, index) => index % 2 == 0);
777
+ this.shape(node, ["(", ...parameters.flatMap((parameter, index) => index ? [",", parameter] : [parameter]),
778
+ ...(hasGeneratedTrailingComma ? [","] : []), ")"]);
779
+ return parameters.map((parameter) => this.parameter(parameter));
780
+ }
781
+ /**
782
+ * Converts one ordinary top-level function declaration.
783
+ * @param {import("tree-sitter").SyntaxNode} signature Function signature.
784
+ * @param {import("tree-sitter").SyntaxNode} body Function body.
785
+ * @returns {import("../semantic/types.js").FunctionDeclaration} Semantic function.
786
+ */
787
+ function(signature, body) {
788
+ const parts = this.parts(signature);
789
+ if (signature.type != "function_signature")
790
+ this.fail(signature, "function signature");
791
+ if (parts.length == 2 && parts[0].type == "identifier")
792
+ return missingType("dart", "Function return", this.location(signature));
793
+ if (parts.length != 3 || !["type_identifier", "void_type"].includes(parts[0].type) || parts[1].type != "identifier" ||
794
+ parts[2].type != "formal_parameter_list")
795
+ this.fail(signature, "explicit top-level function signature");
796
+ this.shape(signature, [parts[0], parts[1], parts[2]]);
797
+ if (this.field(signature, "name").id != parts[1].id)
798
+ this.fail(parts[1], "function name field");
799
+ const name = this.identifier(parts[1]);
800
+ const location = locationFromOffsets(this.filename, this.source, bindingIndexToUtf16Offset(this.source, signature.startIndex), bindingIndexToUtf16Offset(this.source, body.endIndex));
801
+ return withParserRanges({
802
+ body: this.functionBody(body),
803
+ kind: /** @type {const} */ ("FunctionDeclaration"),
804
+ location,
805
+ name,
806
+ parameters: this.parameters(parts[2]),
807
+ returnType: this.returnType(parts[0])
808
+ }, { name: this.location(parts[1]) });
809
+ }
810
+ /**
811
+ * Converts the exact void main entry shell.
812
+ * @param {import("tree-sitter").SyntaxNode} signature Main signature.
813
+ * @param {import("tree-sitter").SyntaxNode} body Main body.
814
+ * @returns {import("../semantic/types.js").EntryPoint} Semantic entry point.
815
+ */
816
+ main(signature, body) {
817
+ const parts = this.parts(signature);
818
+ if (signature.type != "function_signature" || parts.length != 3 || parts[0].type != "void_type" ||
819
+ this.identifier(parts[1], true) != "main" || parts[2].type != "formal_parameter_list") {
820
+ this.fail(signature, "exact void main() signature required");
821
+ }
822
+ this.shape(signature, [parts[0], parts[1], parts[2]]);
823
+ this.shape(parts[2], ["(", ")"]);
824
+ const location = locationFromOffsets(this.filename, this.source, bindingIndexToUtf16Offset(this.source, signature.startIndex), bindingIndexToUtf16Offset(this.source, body.endIndex));
825
+ return { body: this.functionBody(body), kind: /** @type {const} */ ("EntryPoint"), location };
826
+ }
827
+ /**
828
+ * Converts one complete Dart compilation unit.
829
+ * @param {import("tree-sitter").SyntaxNode} root Complete Dart program.
830
+ * @returns {import("../semantic/types.js").SemanticModule} Semantic module.
831
+ */
832
+ module(root) {
833
+ this.validateTree(root);
834
+ if (root.type != "program")
835
+ this.fail(root, "program root");
836
+ const parts = this.parts(root);
837
+ const supportTree = parser.parse(dartRuntime);
838
+ const support = this.parts(supportTree.rootNode);
839
+ let supportIndex = 0;
840
+ while (supportIndex < parts.length && supportIndex < support.length &&
841
+ parts[supportIndex].type == support[supportIndex].type) {
842
+ this.compareTree(parts[supportIndex], support[supportIndex]);
843
+ supportIndex += 1;
844
+ }
845
+ if (supportIndex > 0 && supportIndex != support.length) {
846
+ this.fail(parts[supportIndex - 1], "complete Dart support required");
847
+ }
848
+ this.runtime = supportIndex == support.length;
849
+ const semanticParts = parts.slice(supportIndex);
850
+ if (semanticParts.length == 0)
851
+ this.fail(root, "program without main");
852
+ /** @type {{body: import("tree-sitter").SyntaxNode, signature: import("tree-sitter").SyntaxNode}[]} */
853
+ const declarations = [];
854
+ for (const declaration of semanticParts) {
855
+ if (declaration.type != "function_declaration")
856
+ this.fail(declaration, "top-level function declaration required");
857
+ const signature = this.field(declaration, "signature");
858
+ const body = this.field(declaration, "body");
859
+ const declarationParts = this.parts(declaration);
860
+ if (declarationParts.length != 2 || declarationParts[0].id != signature.id || signature.type != "function_signature" ||
861
+ declarationParts[1].id != body.id || body.type != "function_body") {
862
+ this.fail(declaration, "paired top-level function signature and body required");
863
+ }
864
+ this.shape(declaration, [signature, body]);
865
+ declarations.push({ body, signature });
866
+ }
867
+ const mainIndexes = declarations.flatMap(({ signature }, index) => this.parts(signature)[1]?.text == "main" ? [index] : []);
868
+ if (mainIndexes.length != 1)
869
+ this.fail(root, "exactly one main declaration required");
870
+ const mainIndex = mainIndexes[0];
871
+ this.functionNames = new Set(declarations.map(({ signature }) => this.parts(signature)[1]?.text).filter(Boolean));
872
+ if (mainIndex != declarations.length - 1)
873
+ this.fail(declarations[mainIndex + 1].signature, "declaration after main");
874
+ const main = declarations[mainIndex];
875
+ const module = {
876
+ entryPoint: this.main(main.signature, main.body),
877
+ functions: declarations.slice(0, mainIndex).map(({ body, signature }) => this.function(signature, body)),
878
+ kind: /** @type {const} */ ("Module"),
879
+ location: this.location(root)
880
+ };
881
+ validateParsedModule(module, "dart");
882
+ return module;
883
+ }
884
+ }
885
+ /**
886
+ * Parses the strict Task 029 Dart VM/native profile through the qualified grammar.
887
+ * @param {{filename: string, source: string}} input Exact source request.
888
+ * @returns {import("../semantic/types.js").SemanticModule} Semantic module.
889
+ */
890
+ export function parseDart({ filename, source }) {
891
+ if (!hasOnlyUnicodeScalars(source)) {
892
+ const offset = firstLoneSurrogateOffset(source);
893
+ throw new SemantifoldDiagnostic({
894
+ code: "PARSE_ERROR", language: "dart", location: locationFromOffsets(filename, source, offset, offset + 1),
895
+ message: "Dart source contains an invalid lone UTF-16 surrogate."
896
+ });
897
+ }
898
+ let tree;
899
+ try {
900
+ tree = parser.parse(source);
901
+ }
902
+ catch (error) {
903
+ throw new SemantifoldDiagnostic({
904
+ cause: error instanceof Error ? error : undefined,
905
+ code: "PARSE_ERROR",
906
+ language: "dart",
907
+ location: moduleLocation(filename, source),
908
+ message: "The qualified Dart parser could not produce a complete CST."
909
+ });
910
+ }
911
+ return new DartReader(filename, source).module(tree.rootNode);
912
+ }
913
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZGFydC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9mcm9udGVuZHMvZGFydC5qcyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxZQUFZO0FBRVosT0FBTyxNQUFNLE1BQU0sYUFBYSxDQUFBO0FBQ2hDLE9BQU8sWUFBWSxNQUFNLGlEQUFpRCxDQUFBO0FBQzFFLE9BQU8sRUFBQyxnQkFBZ0IsRUFBQyxNQUFNLDRCQUE0QixDQUFBO0FBQzNELE9BQU8sRUFBQyxXQUFXLEVBQUMsTUFBTSw2QkFBNkIsQ0FBQTtBQUN2RCxPQUFPLEVBQUMsV0FBVyxFQUFFLHFCQUFxQixFQUFFLGlCQUFpQixFQUFDLE1BQU0sa0JBQWtCLENBQUE7QUFDdEYsT0FBTyxFQUFDLG1CQUFtQixFQUFFLGNBQWMsRUFBRSwyQkFBMkIsRUFBQyxNQUFNLHlCQUF5QixDQUFBO0FBQ3hHLE9BQU8sRUFBQyxvQkFBb0IsRUFBQyxNQUFNLDBCQUEwQixDQUFBO0FBQzdELE9BQU8sRUFBQyxnQkFBZ0IsRUFBQyxNQUFNLDJCQUEyQixDQUFBO0FBQzFELE9BQU8sRUFBQyxxQkFBcUIsRUFBQyxNQUFNLHdCQUF3QixDQUFBO0FBQzVELE9BQU8sRUFBQyxvQkFBb0IsRUFBQyxNQUFNLHlCQUF5QixDQUFBO0FBQzVELE9BQU8sRUFBQyxnQkFBZ0IsRUFBQyxNQUFNLGNBQWMsQ0FBQTtBQUU3QyxNQUFNLE1BQU0sR0FBRyxJQUFJLE1BQU0sRUFBRSxDQUFBO0FBRTNCLE1BQU0sQ0FBQyxXQUFXLENBQUMsNkNBQTZDLENBQUMsRUFBQyxzQkFBdUIsQ0FBQyxZQUFZLENBQUMsQ0FBQyxDQUFDLENBQUE7QUFFekcsTUFBTSxnQkFBZ0IsR0FBRyxJQUFJLEdBQUcsQ0FBQztJQUMvQixDQUFDLEdBQUcsRUFBRSxLQUFLLENBQUMsRUFBRSxDQUFDLEdBQUcsRUFBRSxVQUFVLENBQUMsRUFBRSxDQUFDLEdBQUcsRUFBRSxVQUFVLENBQUMsRUFBRSxDQUFDLElBQUksRUFB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LENBQUMsRUFBRSxJQUFJLElBQUksZUFBZSxDQUFBO1FBQ25ELE1BQU0sU0FBUyxHQUFHLFNBQVMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUE7UUFDbkMsTUFBTSxRQUFRLEdBQUcsS0FBSyxDQUFDLFNBQVMsQ0FBQyxDQUFBO1FBQ2pDLE1BQU0sUUFBUSxHQUFHLEtBQUssQ0FBQyxTQUFTLEdBQUcsQ0FBQyxDQUFDLENBQUE7UUFDckMsTUFBTSxNQUFNLEdBQUcsS0FBSyxDQUFDLFNBQVMsR0FBRyxDQUFDLENBQUMsQ0FBQTtRQUNuQyxNQUFNLGVBQWUsR0FBRyxLQUFLLENBQUMsS0FBSyxDQUFDLFNBQVMsR0FBRyxDQUFDLENBQUMsQ0FBQTtRQUVsRCxJQUFJLEtBQUssQ0FBQyxNQUFNLEdBQUcsU0FBUyxHQUFHLENBQUMsSUFBSSxRQUFRLEVBQUUsSUFBSSxJQUFJLGlCQUFpQixJQUFJLFFBQVEsRUFBRSxJQUFJLElBQUksWUFBWTtZQUN2RyxNQUFNLEVBQUUsSUFBSSxJQUFJLEdBQUcsSUFBSSxlQUFlLENBQUMsTUFBTSxJQUFJLENBQUMsSUFBSSxTQUFTLElBQUksS0FBSyxDQUFDLENBQUMsQ0FBQyxDQUFDLElBQUksSUFBSSxPQUFPLEVBQUUsQ0FBQztZQUM5RixJQUFJLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsSUFBSSxVQUFVLEVBQUUsNkNBQTZDLENBQUMsQ0FBQTtRQUNsRixDQUFDO1FBQ0QsSUFBSSxDQUFDLEtBQUssQ0FBQyxVQUFVLEVBQUUsQ0FBQyxHQUFHLENBQUMsU0FBUyxDQUFDLENBQUMsQ0FBQyxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsRUFBRSxRQUFRLEVBQUUsUUFBUSxFQUFFLEdBQUcsRUFBRSxHQUFHLGVBQWUsQ0FBQyxDQUFDLENBQUE7UUFDdkcsSUFBSSxJQUFJLENBQUMsS0FBSyxDQUFDLFVBQVUsRUFBRSxNQUFNLENBQUMsQ0FBQyxFQUFFLElBQUks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QUE7SUFFUixJQUFJLENBQUM7UUFDSCxJQUFJLEdBQUcsTUFBTSxDQUFDLEtBQUssQ0FBQyxNQUFNLENBQUMsQ0FBQTtJQUM3QixDQUFDO0lBQUMsT0FBTyxLQUFLLEVBQUUsQ0FBQztRQUNmLE1BQU0sSUFBSSxxQkFBcUIsQ0FBQztZQUM5QixLQUFLLEVBQUUsS0FBSyxZQUFZLEtBQUssQ0FBQyxDQUFDLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxTQUFTO1lBQ2pELElBQUksRUFBRSxhQUFhO1lBQ25CLFFBQVEsRUFBRSxNQUFNO1lBQ2hCLFFBQVEsRUFBRSxjQUFjLENBQUMsUUFBUSxFQUFFLE1BQU0sQ0FBQztZQUMxQyxPQUFPLEVBQUUsNkRBQTZEO1NBQ3ZFLENBQUMsQ0FBQTtJQUNKLENBQUM7SUFDRCxPQUFPLElBQUksVUFBVSxDQUFDLFFBQVEsRUFBRSxNQUFNLENBQUMsQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLFFBQVEsQ0FBQyxDQUFBO0FBQy9ELENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyIvLyBAdHMtY2hlY2tcblxuaW1wb3J0IFBhcnNlciBmcm9tIFwidHJlZS1zaXR0ZXJcIlxuaW1wb3J0IERhcnRMYW5ndWFnZSBmcm9tIFwidHJlZS1zaXR0ZXItZGFydC1vcmNoYXJkL2JpbmRpbmdzL25vZGUvaW5kZXguanNcIlxuaW1wb3J0IHtpc0RhcnRJZGVudGlmaWVyfSBmcm9tIFwiLi4vYmFja2VuZHMvaWRlbnRpZmllcnMuanNcIlxuaW1wb3J0IHtkYXJ0UnVudGltZX0gZnJvbSBcIi4uL2JhY2tlbmRzL2RhcnQtcnVudGltZS5qc1wiXG5pbXBvcnQge21pc3NpbmdUeXBlLCBTZW1hbnRpZm9sZERpYWdub3N0aWMsIHVuc3VwcG9ydGVkU3ludGF4fSBmcm9tIFwiLi4vZGlhZ25vc3RpYy5qc1wiXG5pbXBvcnQge2xvY2F0aW9uRnJvbU9mZnNldHMsIG1vZHVsZUxvY2F0aW9uLCB1dGY4Qnl0ZU9mZnNldFRvVXRmMTZPZmZzZXR9IGZyb20gXCIuLi9zZW1hbnRpYy9sb2NhdGlvbi5qc1wiXG5pbXBvcnQge3dpdGhBZGFwdGVkT3BlcmF0aW9ufSBmcm9tIFwiLi4vc2VtYW50aWMvb3BlcmF0b3JzLmpzXCJcbmltcG9ydCB7d2l0aFBhcnNlclJhbmdlc30gZnJvbSBcIi4uL3NlbWFudGljL3Byb3ZlbmFuY2UuanNcIlxuaW1wb3J0IHtoYXNPbmx5VW5pY29kZVNjYWxhcnN9IGZyb20gXCIuLi9zZW1hbnRpYy9zY2FsYXJzLmpzXCJcbmltcG9ydCB7dmFsaWRhdGVQYXJzZWRNb2R1bGV9IGZyb20gXCIuLi9zZW1hbnRpYy92YWxpZGF0ZS5qc1wiXG5pbXBvcnQge3NvdXJjZVNjYWxhclR5cGV9IGZyb20gXCIuL3NjYWxhcnMuanNcIlxuXG5jb25zdCBwYXJzZXIgPSBuZXcgUGFyc2VyKClcblxucGFyc2VyLnNldExhbmd1YWdlKC8qKiBAdHlwZSB7aW1wb3J0KFwidHJlZS1zaXR0ZXJcIikuTGFuZ3VhZ2V9ICovICgvKiogQHR5cGUge3Vua25vd259ICovIChEYXJ0TGFuZ3VhZ2UpKSlcblxuY29uc3QgYmluYXJ5T3BlcmF0aW9ucyA9IG5ldyBNYXAoW1xuICBbXCIrXCIsIFwiQWRkXCJdLCBbXCItXCIsIFwiU3VidHJhY3RcIl0sIFtcIipcIiwgXCJNdWx0aXBseVwiXSwgW1wiPT1cIiwgXCJFcXVhbFwiXSwgW1wiIT1cIiwgXCJOb3RFcXVhbFwiXSxcbiAgW1wiPFwiLCBcIkxlc3NUaGFuXCJdLCBbXCI8PVwiLCBcIkxlc3NUaGFuT3JFcXVhbFwiXSwgW1wiPlwiLCBcIkdyZWF0ZXJUaGFuXCJdLCBbXCI+PVwiLCBcIkdyZWF0ZXJUaGFuT3JFcXVhbFwiXSxcbiAgW1wiJiZcIiwgXCJBbmRcIl0sIFtcInx8XCIsIFwiT3JcIl1cbl0pXG4vKiogQHR5cGUge01hcDxzdHJpbmcsIHJlYWRvbmx5IFtzdHJpbmcsIFNldDxzdHJpbmc+XT59ICovXG5jb25zdCBiaW5hcnlOb2RlT3BlcmF0b3JzID0gbmV3IE1hcChbXG4gIFtcImFkZGl0aXZlX2V4cHJlc3Npb25cIiwgW1wiYWRkaXRpdmVfb3BlcmF0b3JcIiwgbmV3IFNldChbXCIrXCIsIFwiLVwiXSldXSxcbiAgW1wibXVsdGlwbGljYXRpdmVfZXhwcmVzc2lvblwiLCBbXCJtdWx0aXBsaWNhdGl2ZV9vcGVyYXRvclwiLCBuZXcgU2V0KFtcIipcIl0pXV0sXG4gIFtcImVxdWFsaXR5X2V4cHJlc3Npb25cIiwgW1wiZXF1YWxpdHlfb3BlcmF0b3JcIiwgbmV3IFNldChbXCI9PVwiLCBcIiE9XCJdKV1dLFxuICBbXCJyZWxhdGlvbmFsX2V4cHJlc3Npb25cIiwgW1wicmVsYXRpb25hbF9vcGVyYXRvclwiLCBuZXcgU2V0KFtcIjxcIiwgXCI8PVwiLCBcIj5cIiwgXCI+PVwiXSldXSxcbiAgW1wibG9naWNhbF9hbmRfZXhwcmVzc2lvblwiLCBbXCJsb2dpY2FsX2FuZF9vcGVyYXRvclwiLCBuZXcgU2V0KFtcIiYmXCJdKV1dLFxuICBbXCJsb2dpY2FsX29yX2V4cHJlc3Npb25cIiwgW1wibG9naWNhbF9vcl9vcGVyYXRvclwiLCBuZXcgU2V0KFtcInx8XCJdKV1dXG5dKVxuY29uc3QgY29tbWVudFR5cGVzID0gbmV3IFNldChbXCJjb21tZW50XCIsIFwiZG9jdW1lbnRhdGlvbl9jb21tZW50XCJdKVxuLyoqIEB0eXBlIHtNYXA8c3RyaW5nLCBpbXBvcnQoXCIuLi9zZW1hbnRpYy9vcGVyYXRvcnMuanNcIikuQWRhcHRlZE9wZXJhdGlvbj59ICovXG5jb25zdCBoZWxwZXJPcGVyYXRpb25zID0gbmV3IE1hcChbXG4gIFtcIl9zZW1hbnRpZm9sZEludGVnZXJBZGRcIiwgXCJBZGRcIl0sIFtcIl9zZW1hbnRpZm9sZEludGVnZXJTdWJ0cmFjdFwiLCBcIlN1YnRyYWN0XCJdLFxuICBbXCJfc2VtYW50aWZvbGRJbnRlZ2VyTXVsdGlwbHlcIiwgXCJNdWx0aXBseVwiXSwgW1wiX3NlbWFudGlmb2xkSW50ZWdlck5lZ2F0ZVwiLCBcIk5lZ2F0ZVwiXVxuXSlcblxuLyoqXG4gKiBWZXJpZmllcyBhIGJpbmRpbmctcmVwb3J0ZWQgVVRGLTE2IGluZGV4IHRocm91Z2ggdGhlIHNoYXJlZCBVVEYtOCBjb252ZXJ0ZXIuXG4gKiBAcGFyYW0ge3N0cmluZ30gc291cmNlIENvbXBsZXRlIHNvdXJjZS5cbiAqIEBwYXJhbSB7bnVtYmVyfSBpbmRleCBCaW5kaW5nIGluZGV4LlxuICogQHJldHVybnMge251bWJlcn0gVmVyaWZpZWQgVVRGLTE2IG9mZnNldC5cbiAqL1xuZnVuY3Rpb24gYmluZGluZ0luZGV4VG9VdGYxNk9mZnNldChzb3VyY2UsIGluZGV4KSB7XG4gIGlmICghTnVtYmVyLmlzSW50ZWdlcihpbmRleCkgfHwgaW5kZXggPCAwIHx8IGluZGV4ID4gc291cmNlLmxlbmd0aCB8fFxuICAgIGluZGV4ID4gMCAmJiBpbmRleCA8IHNvdXJjZS5sZW5ndGggJiYgL1tcXHVEODAwLVxcdURCRkZdL3UudGVzdChzb3VyY2VbaW5kZXggLSAxXSkgJiYgL1tcXHVEQzAwLVxcdURGRkZdL3UudGVzdChzb3VyY2VbaW5kZXhdKSkge1xuICAgIHRocm93IG5ldyBSYW5nZUVycm9yKFwiSW52YWxpZCBUcmVlLXNpdHRlciBzb3VyY2UgaW5kZXg6IFwiICsgaW5kZXgpXG4gIH1cbiAgcmV0dXJuIHV0ZjhCeXRlT2Zmc2V0VG9VdGYxNk9mZnNldChzb3VyY2UsIG5ldyBUZXh0RW5jb2RlcigpLmVuY29kZShzb3VyY2Uuc2xpY2UoMCwgaW5kZXgpKS5sZW5ndGgpXG59XG5cbi8qKlxuICogRmluZHMgdGhlIGZpcnN0IHVucGFpcmVkIFVURi0xNiBzdXJyb2dhdGUuXG4gKiBAcGFyYW0ge3N0cmluZ30gc291cmNlIENvbXBsZXRlIHNvdXJjZS5cbiAqIEByZXR1cm5zIHtudW1iZXJ9IEludmFsaWQgb2Zmc2V0IG9yIC0xLlxuICovXG5mdW5jdGlvbiBmaXJzdExvbmVTdXJyb2dhdGVPZmZzZXQoc291cmNlKSB7XG4gIGZvciAobGV0IGluZGV4ID0gMDsgaW5kZXggPCBzb3VyY2UubGVuZ3RoOyBpbmRleCArPSAxKSB7XG4gICAgY29uc3QgdW5pdCA9IHNvdXJjZS5jaGFyQ29kZUF0KGluZGV4KVxuXG4gICAgaWYgKHVuaXQgPj0gMHhEODAwICYmIHVuaXQgPD0gMHhEQkZGKSB7XG4gICAgICBjb25zdCBuZXh0ID0gc291cmNlLmNoYXJDb2RlQXQoaW5kZXggKyAxKVxuXG4gICAgICBpZiAobmV4dCA+PSAweERDMDAgJiYgbmV4dCA8PSAweERGRkYpIGluZGV4ICs9IDFcbiAgICAgIGVsc2UgcmV0dXJuIGluZGV4XG4gICAgfSBlbHNlIGlmICh1bml0ID49IDB4REMwMCAmJiB1bml0IDw9IDB4REZGRikgcmV0dXJuIGluZGV4XG4gIH1cbiAgcmV0dXJuIC0xXG59XG5cbi8qKiBDb25zdW1lcyBleGFjdCBxdWFsaWZpZWQgRGFydCBDU1Qgc2hhcGVzIHdpdGhvdXQgcmV0YWluaW5nIHBhcnNlciB2YWx1ZXMuICovXG5jbGFzcyBEYXJ0UmVhZGVyIHtcbiAgLyoqXG4gICAqIENyZWF0ZXMgYSByZWFkZXIgYm91bmQgdG8gb25lIGV4YWN0IERhcnQgc291cmNlIHVuaXQuXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBmaWxlbmFtZSBPcmlnaW5hbCBmaWxlbmFtZS5cbiAgICogQHBhcmFtIHtzdHJpbmd9IHNvdXJjZSBDb21wbGV0ZSBzb3VyY2UuXG4gICAqL1xuICBjb25zdHJ1Y3RvcihmaWxlbmFtZSwgc291cmNlKSB7XG4gICAgdGhpcy5maWxlbmFtZSA9IGZpbGVuYW1lXG4gICAgdGhpcy5zb3VyY2UgPSBzb3VyY2VcbiAgICAvKiogQHR5cGUge1NldDxzdHJpbmc+fSAqL1xuICAgIHRoaXMuZnVuY3Rpb25OYW1lcyA9IG5ldyBTZXQoKVxuICAgIHRoaXMucnVudGltZSA9IGZhbHNlXG4gIH1cblxuICAvKipcbiAgICogQnVpbGRzIGEgc2VtYW50aWMgc291cmNlIGxvY2F0aW9uIGZyb20gb25lIHBhcnNlciBub2RlLlxuICAgKiBAcGFyYW0ge2ltcG9ydChcInRyZWUtc2l0dGVyXCIpLlN5bnRheE5vZGV9IG5vZGUgUGFyc2VyIG5vZGUuXG4gICAqIEByZXR1cm5zIHtpbXBvcnQoXCIuLi9zZW1hbnRpYy90eXBlcy5qc1wiKS5Tb3VyY2VMb2NhdGlvbn0gRXhhY3QgbG9jYXRpb24uXG4gICAqL1xuICBsb2NhdGlvbihub2RlKSB7XG4gICAgcmV0dXJuIGxvY2F0aW9uRnJvbU9mZnNldHModGhpcy5maWxlbmFtZSwgdGhpcy5zb3VyY2UsIGJpbmRpbmdJbmRleFRvVXRmMTZPZmZzZXQodGhpcy5zb3VyY2UsIG5vZGUuc3RhcnRJbmRleCksXG4gICAgICBiaW5kaW5nSW5kZXhUb1V0ZjE2T2Zmc2V0KHRoaXMuc291cmNlLCBub2RlLmVuZEluZGV4KSlcbiAgfVxuXG4gIC8qKlxuICAgKiBSZWplY3RzIG9uZSBwYXJzZXIgbm9kZSB3aXRoIGEgbG9jYXRlZCB1bnN1cHBvcnRlZC1zeW50YXggZGlhZ25vc3RpYy5cbiAgICogQHBhcmFtIHtpbXBvcnQoXCJ0cmVlLXNpdHRlclwiKS5TeW50YXhOb2RlfSBub2RlIFZpb2xhdGluZyBub2RlLlxuICAgKiBAcGFyYW0ge3N0cmluZ30gW2RldGFpbF0gUHJvZmlsZSBkZXRhaWwuXG4gICAqIEByZXR1cm5zIHtuZXZlcn0gQWx3YXlzIHRocm93cy5cbiAgICovXG4gIGZhaWwobm9kZSwgZGV0YWlsID0gbm9kZS50eXBlKSB7XG4gICAgdW5zdXBwb3J0ZWRTeW50YXgoXCJkYXJ0XCIsIGRldGFpbCwgdGhpcy5sb2NhdGlvbihub2RlKSlcbiAgfVxuXG4gIC8qKlxuICAgKiBUcmF2ZXJzZXMgZXZlcnkgbmFtZWQsIGFub255bW91cywgZXh0cmEsIGZpZWxkLCBhbmQgcmVjb3ZlcnkgZWRnZS5cbiAgICogQHBhcmFtIHtpbXBvcnQoXCJ0cmVlLXNpdHRlclwiKS5TeW50YXhOb2RlfSByb290IENvbXBsZXRlIHBhcnNlciByb290LlxuICAgKiBAcmV0dXJucyB7dm9pZH1cbiAgICovXG4gIHZhbGlkYXRlVHJlZShyb290KSB7XG4gICAgY29uc3QgcGVuZGluZyA9IFt7ZGVwdGg6IDAsIG5vZGU6IHJvb3QsIHZpc2l0ZWQ6IGZhbHNlfV1cblxuICAgIHdoaWxlIChwZW5kaW5nLmxlbmd0aCA+IDApIHtcbiAgICAgIGNvbnN0IGN1cnJlbnQgPSBwZW5kaW5nLnBvcCgpXG5cbiAgICAgIGlmICghY3VycmVudCkgdGhyb3cgbmV3IEVycm9yKFwiRGFydCB0cmF2ZXJzYWwgbG9zdCBhIHBlbmRpbmcgcGFyc2VyIG5vZGUuXCIpXG4gICAgICBjb25zdCB7ZGVwdGgsIG5vZGUsIHZpc2l0ZWR9ID0gY3VycmVudFxuXG4gICAgICBpZiAoZGVwdGggPiA1MTIpIHRoaXMuZmFpbChub2RlLCBcIkNTVCBleGNlZWRzIHRoZSA1MTItbGV2ZWwgdHJhdmVyc2FsIGxpbWl0XCIpXG4gICAgICBpZiAoIXZpc2l0ZWQpIHtcbiAgICAgICAgcGVuZGluZy5wdXNoKHtkZXB0aCwgbm9kZSwgdmlzaXRlZDogdHJ1ZX0pXG4gICAgICAgIGZvciAobGV0IGluZGV4ID0gbm9kZS5jaGlsZENvdW50IC0gMTsgaW5kZXggPj0gMDsgaW5kZXggLT0gMSkge1xuICAgICAgICAgIGNvbnN0IGNoaWxkID0gbm9kZS5jaGlsZChpbmRleClcblxuICAgICAgICAgIGlmICghY2hpbGQpIHRocm93IG5ldyBFcnJvcihgVHJlZS1zaXR0ZXIgb21pdHRlZCBjaGlsZCAke2luZGV4fSBvZiAke25vZGUudHlwZX0uYClcbiAgICAgICAgICBub2RlLmZpZWxkTmFtZUZvckNoaWxkKGluZGV4KVxuICAgICAgICAgIHBlbmRpbmcucHVzaCh7ZGVwdGg6IGRlcHRoICsgMSwgbm9kZTogY2hpbGQsIHZpc2l0ZWQ6IGZhbHNlfSlcbiAgICAgICAgfVxuICAgICAgICBjb250aW51ZVxuICAgICAgfVxuICAgICAgaWYgKG5vZGUuaGFzRXJyb3IgfHwgbm9kZS5pc0Vycm9yIHx8IG5vZGUuaXNNaXNzaW5nKSB7XG4gICAgICAgIHRocm93IG5ldyBTZW1hbnRpZm9sZERpYWdub3N0aWMoe1xuICAgICAgICAgIGNvZGU6IFwiUEFSU0VfRVJST1JcIixcbiAgICAgICAgICBsYW5ndWFnZTogXCJkYXJ0XCIsXG4gICAgICAgICAgbG9jYXRpb246IHRoaXMubG9jYXRpb24obm9kZSksXG4gICAgICAgICAgbWVzc2FnZTogYFRyZWUtc2l0dGVyIGV4cG9zZWQgcmVjb3ZlcnkgYXQgJyR7bm9kZS50eXBlfScuYFxuICAgICAgICB9KVxuICAgICAgfVxuICAgICAgaWYgKFtcImFubm90YXRpb25cIiwgXCJpbXBvcnRfb3JfZXhwb3J0XCIsIFwibGlicmFyeV9uYW1lXCIsIFwicGFydF9oZWFkZXJcIiwgXCJwYXJ0X29mX2hlYWRlclwiXS5pbmNsdWRlcyhub2RlLnR5cGUpKSB7XG4gICAgICAgIHRoaXMuZmFpbChub2RlLCBub2RlLnR5cGUpXG4gICAgICB9XG4gICAgICBpZiAoY29tbWVudFR5cGVzLmhhcyhub2RlLnR5cGUpICYmICgvKD86QGRhcnRcXHMqPXxkYXJ0Zm10fGlnbm9yZSg/Ol9mb3JfZmlsZSk/XFxzKjp8bGFuZ3VhZ2VbLV8gXXZlcnNpb24pL2l1LnRlc3Qobm9kZS50ZXh0KSB8fFxuICAgICAgICAvXlxcL1xcLyBkYXJ0IGZvcm1hdCAoPzpvZmZ8b24pW1xcdCBdKiQvdS50ZXN0KG5vZGUudGV4dCkpKSB7XG4gICAgICAgIHRoaXMuZmFpbChub2RlLCBcImRpcmVjdGl2ZS1iZWFyaW5nIGNvbW1lbnRcIilcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogT21pdHMgb25seSBvcmRpbmFyeSBjb21tZW50cyBhbHJlYWR5IGNvdmVyZWQgYnkgZXhoYXVzdGl2ZSB0cmF2ZXJzYWwuXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwidHJlZS1zaXR0ZXJcIikuU3ludGF4Tm9kZX0gbm9kZSBQYXJlbnQgbm9kZS5cbiAgICogQHJldHVybnMge2ltcG9ydChcInRyZWUtc2l0dGVyXCIpLlN5bnRheE5vZGVbXX0gU3RydWN0dXJhbCBjaGlsZHJlbi5cbiAgICovXG4gIHBhcnRzKG5vZGUpIHtcbiAgICByZXR1cm4gbm9kZS5jaGlsZHJlbi5maWx0ZXIoKGNoaWxkKSA9PiAhY29tbWVudFR5cGVzLmhhcyhjaGlsZC50eXBlKSlcbiAgfVxuXG4gIC8qKlxuICAgKiBWZXJpZmllcyBhbiBleGFjdCBzdHJ1Y3R1cmFsIGNoaWxkIHNlcXVlbmNlLlxuICAgKiBAcGFyYW0ge2ltcG9ydChcInRyZWUtc2l0dGVyXCIpLlN5bnRheE5vZGV9IG5vZGUgU2hhcGUgb3duZXIuXG4gICAqIEBwYXJhbSB7KGltcG9ydChcInRyZWUtc2l0dGVyXCIpLlN5bnRheE5vZGUgfCBzdHJpbmcpW119IGV4cGVjdGVkIEV4YWN0IGNoaWxkIHNlcXVlbmNlLlxuICAgKiBAcmV0dXJucyB7dm9pZH1cbiAgICovXG4gIHNoYXBlKG5vZGUsIGV4cGVjdGVkKSB7XG4gICAgY29uc3QgYWN0dWFsID0gdGhpcy5wYXJ0cyhub2RlKVxuXG4gICAgaWYgKGFjdHVhbC5sZW5ndGggIT0gZXhwZWN0ZWQubGVuZ3RoKSB0aGlzLmZhaWwoYWN0dWFsW01hdGgubWluKGFjdHVhbC5sZW5ndGgsIGV4cGVjdGVkLmxlbmd0aCldID8/IG5vZGUsIGAke25vZGUudHlwZX0gY2hpbGQgc2hhcGVgKVxuICAgIGZvciAobGV0IGluZGV4ID0gMDsgaW5kZXggPCBleHBlY3RlZC5sZW5ndGg7IGluZGV4ICs9IDEpIHtcbiAgICAgIGNvbnN0IHdhbnRlZCA9IGV4cGVjdGVkW2luZGV4XVxuICAgICAgY29uc3QgY2hpbGQgPSBhY3R1YWxbaW5kZXhdXG4gICAgICBjb25zdCBtYXRjaGVzID0gdHlwZW9mIHdhbnRlZCA9PSBcInN0cmluZ1wiID8gY2hpbGQudGV4dCA9PSB3YW50ZWQgOiBjaGlsZC5pZCA9PSB3YW50ZWQuaWRcblxuICAgICAgaWYgKCFtYXRjaGVzKSB0aGlzLmZhaWwoY2hpbGQsIGAke25vZGUudHlwZX0gY2hpbGQgc2hhcGVgKVxuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBDb25zdW1lcyBhbiBPcmNoYXJkIG9wZXJhdG9yIHdyYXBwZXIgd2hldGhlciBpdHMgdG9rZW4gaXMgYWxpYXNlZCBpbnRvIHRoZSB3cmFwcGVyIG9yIGV4cG9zZWQgYW5vbnltb3VzbHkuXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwidHJlZS1zaXR0ZXJcIikuU3ludGF4Tm9kZX0gbm9kZSBPcGVyYXRvciBub2RlLlxuICAgKiBAcmV0dXJucyB7dm9pZH1cbiAgICovXG4gIG9wZXJhdG9yU2hhcGUobm9kZSkge1xuICAgIGNvbnN0IHBhcnRzID0gdGhpcy5wYXJ0cyhub2RlKVxuXG4gICAgaWYgKHBhcnRzLmxlbmd0aCA+IDEgfHwgcGFydHMubGVuZ3RoID09IDEgJiYgKHBhcnRzWzBdLmlzTmFtZWQgfHwgcGFydHNbMF0udGV4dCAhPSBub2RlLnRleHQpKSB7XG4gICAgICB0aGlzLmZhaWwobm9kZSwgYCR7bm9kZS50eXBlfSBjaGlsZCBzaGFwZWApXG4gICAgfVxuICAgIHRoaXMuc2hhcGUobm9kZSwgcGFydHMubGVuZ3RoID09IDAgPyBbXSA6IFtub2RlLnRleHRdKVxuICB9XG5cbiAgLyoqXG4gICAqIFJldHVybnMgZXhhY3RseSBvbmUgcGFyc2VyIGNoaWxkIGNhcnJ5aW5nIGEgcmVxdWVzdGVkIGZpZWxkIG5hbWUuXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwidHJlZS1zaXR0ZXJcIikuU3ludGF4Tm9kZX0gbm9kZSBGaWVsZCBvd25lci5cbiAgICogQHBhcmFtIHtzdHJpbmd9IG5hbWUgRmllbGQgbmFtZS5cbiAgICogQHJldHVybnMge2ltcG9ydChcInRyZWUtc2l0dGVyXCIpLlN5bnRheE5vZGV9IFNvbGUgZmllbGQgbm9kZS5cbiAgICovXG4gIGZpZWxkKG5vZGUsIG5hbWUpIHtcbiAgICBjb25zdCBtYXRjaGVzID0gW11cblxuICAgIGZvciAobGV0IGluZGV4ID0gMDsgaW5kZXggPCBub2RlLmNoaWxkQ291bnQ7IGluZGV4ICs9IDEpIHtcbiAgICAgIGNvbnN0IGNoaWxkID0gbm9kZS5jaGlsZChpbmRleClcblxuICAgICAgaWYgKCFjaGlsZCkgdGhyb3cgbmV3IEVycm9yKGBUcmVlLXNpdHRlciBvbWl0dGVkIGNoaWxkICR7aW5kZXh9IG9mICR7bm9kZS50eXBlfS5gKVxuICAgICAgaWYgKG5vZGUuZmllbGROYW1lRm9yQ2hpbGQoaW5kZXgpID09IG5hbWUpIG1hdGNoZXMucHVzaChjaGlsZClcbiAgICB9XG4gICAgaWYgKG1hdGNoZXMubGVuZ3RoICE9IDEpIHRoaXMuZmFpbChub2RlLCBgZXhwZWN0ZWQgb25lICcke25hbWV9JyBmaWVsZGApXG4gICAgcmV0dXJuIG1hdGNoZXNbMF1cbiAgfVxuXG4gIC8qKlxuICAgKiBWYWxpZGF0ZXMgYW5kIHJldHVybnMgYSBzb3VyY2UgaWRlbnRpZmllci5cbiAgICogQHBhcmFtIHtpbXBvcnQoXCJ0cmVlLXNpdHRlclwiKS5TeW50YXhOb2RlfSBub2RlIElkZW50aWZpZXIgdG9rZW4uXG4gICAqIEBwYXJhbSB7Ym9vbGVhbn0gW2FsbG93TWFpbl0gV2hldGhlciBmaXhlZCBtYWluIGlzIGV4cGVjdGVkLlxuICAgKiBAcGFyYW0ge2Jvb2xlYW59IFthbGxvd1ByaW50XSBXaGV0aGVyIGZpeGVkIHByaW50IGlzIGV4cGVjdGVkLlxuICAgKiBAcmV0dXJucyB7c3RyaW5nfSBBY2NlcHRlZCBuYW1lLlxuICAgKi9cbiAgaWRlbnRpZmllcihub2RlLCBhbGxvd01haW4gPSBmYWxzZSwgYWxsb3dQcmludCA9IGZhbHNlKSB7XG4gICAgY29uc3QgbmFtZSA9IG5vZGUudGV4dFxuXG4gICAgaWYgKG5vZGUudHlwZSAhPSBcImlkZW50aWZpZXJcIiB8fCAhKGFsbG93TWFpbiAmJiBuYW1lID09IFwibWFpblwiKSAmJiAhKGFsbG93UHJpbnQgJiYgbmFtZSA9PSBcInByaW50XCIpICYmXG4gICAgICAhaXNEYXJ0SWRlbnRpZmllcihuYW1lKSkgdGhpcy5mYWlsKG5vZGUsIFwicmVzZXJ2ZWQgb3IgdW5zdXBwb3J0ZWQgaWRlbnRpZmllclwiKVxuICAgIHJldHVybiBuYW1lXG4gIH1cblxuICAvKipcbiAgICogQ29udmVydHMgb25lIGV4cGxpY2l0bHkgbmFtZWQgc2NhbGFyIHR5cGUuXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwidHJlZS1zaXR0ZXJcIikuU3ludGF4Tm9kZX0gbm9kZSBUeXBlIG5vZGUuXG4gICAqIEByZXR1cm5zIHtpbXBvcnQoXCIuLi9zZW1hbnRpYy90eXBlcy5qc1wiKS5UeXBlUmVmZXJlbmNlfSBTY2FsYXIgdHlwZS5cbiAgICovXG4gIHNjYWxhclR5cGUobm9kZSkge1xuICAgIGlmIChub2RlLnR5cGUgIT0gXCJ0eXBlX2lkZW50aWZpZXJcIiB8fCB0aGlzLnBhcnRzKG5vZGUpLmxlbmd0aCAhPSAwKSB0aGlzLmZhaWwobm9kZSwgXCJzY2FsYXIgdHlwZSBzaGFwZVwiKVxuICAgIGNvbnN0IHR5cGUgPSBzb3VyY2VTY2FsYXJUeXBlKFwiZGFydFwiLCBub2RlLnRleHQsIHRoaXMubG9jYXRpb24obm9kZSkpXG5cbiAgICBpZiAoIXR5cGUpIHRoaXMuZmFpbChub2RlLCBgdW5zdXBwb3J0ZWQgc2NhbGFyIHR5cGUgJyR7bm9kZS50ZXh0fSdgKVxuICAgIHJldHVybiB0eXBlXG4gIH1cblxuICAvKipcbiAgICogQ29udmVydHMgb25lIGV4cGxpY2l0IHNjYWxhciBvciB2b2lkIHJlc3VsdCB0eXBlLlxuICAgKiBAcGFyYW0ge2ltcG9ydChcInRyZWUtc2l0dGVyXCIpLlN5bnRheE5vZGV9IG5vZGUgUmV0dXJuIHR5cGUgbm9kZS5cbiAgICogQHJldHVybnMge2ltcG9ydChcIi4uL3NlbWFudGljL3R5cGVzLmpzXCIpLlNlbWFudGljRnVuY3Rpb25SZXR1cm5UeXBlfSBGdW5jdGlvbiByZXR1cm4gdHlwZS5cbiAgICovXG4gIHJldHVyblR5cGUobm9kZSkge1xuICAgIGlmIChub2RlLnR5cGUgPT0gXCJ2b2lkX3R5cGVcIikge1xuICAgICAgY29uc3QgcGFydHMgPSB0aGlzLnBhcnRzKG5vZGUpXG5cbiAgICAgIGlmIChub2RlLnRleHQgIT0gXCJ2b2lkXCIgfHwgcGFydHMubGVuZ3RoID4gMSB8fCBwYXJ0cy5sZW5ndGggPT0gMSAmJiBwYXJ0c1swXS50ZXh0ICE9IFwidm9pZFwiKSB7XG4gICAgICAgIHRoaXMuZmFpbChub2RlLCBcInZvaWQgdHlwZSBzaGFwZVwiKVxuICAgICAgfVxuICAgICAgdGhpcy5zaGFwZShub2RlLCBwYXJ0cylcbiAgICAgIGNvbnN0IHR5cGUgPSB7a2luZDogLyoqIEB0eXBlIHtjb25zdH0gKi8gKFwiVHlwZVJlZmVyZW5jZVwiKSwgbmFtZTogLyoqIEB0eXBlIHtjb25zdH0gKi8gKFwidm9pZFwiKX1cblxuICAgICAgcmV0dXJuIHdpdGhQYXJzZXJSYW5nZXModHlwZSwge3R5cGU6IHRoaXMubG9jYXRpb24obm9kZSl9KVxuICAgIH1cbiAgICByZXR1cm4gdGhpcy5zY2FsYXJUeXBlKG5vZGUpXG4gIH1cblxuICAvKipcbiAgICogRGVjb2RlcyBvbmUgb3JkaW5hcnkgbm9uaW50ZXJwb2xhdGVkLCBub24tcmF3LCBzaW5nbGUtbGluZSBEYXJ0IHN0cmluZy5cbiAgICogQHBhcmFtIHtpbXBvcnQoXCJ0cmVlLXNpdHRlclwiKS5TeW50YXhOb2RlfSBub2RlIFN0cmluZyBub2RlLlxuICAgKiBAcmV0dXJucyB7c3RyaW5nfSBEZWNvZGVkIFVuaWNvZGUgc2NhbGFyIHZhbHVlLlxuICAgKi9cbiAgc3RyaW5nKG5vZGUpIHtcbiAgICBjb25zdCBwYXJ0cyA9IHRoaXMucGFydHMobm9kZSlcbiAgICBjb25zdCBkZWxpbWl0ZXIgPSBub2RlLnRleHRbMF1cblxuICAgIGlmIChub2RlLnR5cGUgIT0gXCJzdHJpbmdfbGl0ZXJhbFwiIHx8ICFbXCJcXFwiXCIsIFwiJ1wiXS5pbmNsdWRlcyhkZWxpbWl0ZXIpIHx8IG5vZGUudGV4dC5zdGFydHNXaXRoKGRlbGltaXRlci5yZXBlYXQoMykpIHx8XG4gICAgICBub2RlLnRleHQuYXQoLTEpICE9IGRlbGltaXRlciB8fCBwYXJ0cy5sZW5ndGggPCAyIHx8IHBhcnRzWzBdLnRleHQgIT0gZGVsaW1pdGVyIHx8IHBhcnRzLmF0KC0xKT8udGV4dCAhPSBkZWxpbWl0ZXIgfHxcbiAgICAgIHBhcnRzLnNsaWNlKDEsIC0xKS5zb21lKCh7dHlwZX0pID0+IHR5cGUgIT0gXCJlc2NhcGVfc2VxdWVuY2VcIikpIHtcbiAgICAgIHRoaXMuZmFpbChub2RlLCBcIm9yZGluYXJ5IG5vbmludGVycG9sYXRlZCBzdHJpbmcgbGl0ZXJhbCByZXF1aXJlZFwiKVxuICAgIH1cbiAgICB0aGlzLnNoYXBlKG5vZGUsIHBhcnRzKVxuICAgIGNvbnN0IHNvdXJjZSA9IG5vZGUudGV4dC5zbGljZSgxLCAtMSlcbiAgICBjb25zdCBzaW1wbGVFc2NhcGVzID0gbmV3IE1hcChbXG4gICAgICBbXCJiXCIsIFwiXFxiXCJdLCBbXCJmXCIsIFwiXFxmXCJdLCBbXCJuXCIsIFwiXFxuXCJdLCBbXCJyXCIsIFwiXFxyXCJdLCBbXCJ0XCIsIFwiXFx0XCJdLCBbXCJ2XCIsIFwiXFx2XCJdLFxuICAgICAgW1wiJFwiLCBcIiRcIl0sIFtcIidcIiwgXCInXCJdLCBbJ1wiJywgJ1wiJ10sIFtcIlxcXFxcIiwgXCJcXFxcXCJdXG4gICAgXSlcbiAgICBsZXQgdmFsdWUgPSBcIlwiXG5cbiAgICBmb3IgKGxldCBpbmRleCA9IDA7IGluZGV4IDwgc291cmNlLmxlbmd0aDsgaW5kZXggKz0gMSkge1xuICAgICAgY29uc3QgY2hhcmFjdGVyID0gc291cmNlW2luZGV4XVxuXG4gICAgICBpZiAoY2hhcmFjdGVyICE9IFwiXFxcXFwiKSB7XG4gICAgICAgIGlmIChjaGFyYWN0ZXIgPT0gXCJcXG5cIiB8fCBjaGFyYWN0ZXIgPT0gXCJcXHJcIiB8fCBjaGFyYWN0ZXIgPT0gZGVsaW1pdGVyIHx8IGNoYXJhY3RlciA9PSBcIiRcIikge1xuICAgICAgICAgIHRoaXMuZmFpbChub2RlLCBcImludmFsaWQgb3IgaW50ZXJwb2xhdGVkIHN0cmluZyBjb250ZW50XCIpXG4gICAgICAgIH1cbiAgICAgICAgdmFsdWUgKz0gY2hhcmFjdGVyXG4gICAgICAgIGNvbnRpbnVlXG4gICAgICB9XG4gICAgICBjb25zdCBlc2NhcGVkID0gc291cmNlWysraW5kZXhdXG5cbiAgICAgIGlmIChzaW1wbGVFc2NhcGVzLmhhcyhlc2NhcGVkKSkgdmFsdWUgKz0gc2ltcGxlRXNjYXBlcy5nZXQoZXNjYXBlZClcbiAgICAgIGVsc2UgaWYgKGVzY2FwZWQgPT0gXCJ4XCIpIHtcbiAgICAgICAgY29uc3QgaGV4YWRlY2ltYWwgPSBzb3VyY2Uuc2xpY2UoaW5kZXggKyAxLCBpbmRleCArIDMpXG5cbiAgICAgICAgaWYgKCEvXlswLTlBLUZhLWZdezJ9JC91LnRlc3QoaGV4YWRlY2ltYWwpKSB0aGlzLmZhaWwobm9kZSwgXCJ1bnN1cHBvcnRlZCBzdHJpbmcgZXNjYXBlXCIpXG4gICAgICAgIHZhbHVlICs9IFN0cmluZy5mcm9tQ29kZVBvaW50KE51bWJlci5wYXJzZUludChoZXhhZGVjaW1hbCwgMTYpKVxuICAgICAgICBpbmRleCArPSAyXG4gICAgICB9IGVsc2UgaWYgKGVzY2FwZWQgPT0gXCJ1XCIpIHtcbiAgICAgICAgaWYgKHNvdXJjZVtpbmRleCArIDFdID09IFwie1wiKSB7XG4gICAgICAgICAgY29uc3QgY2xvc2luZyA9IHNvdXJjZS5pbmRleE9mKFwifVwiLCBpbmRleCArIDIpXG4gICAgICAgICAgY29uc3QgaGV4YWRlY2ltYWwgPSBjbG9zaW5nIDwgMCA/IFwiXCIgOiBzb3VyY2Uuc2xpY2UoaW5kZXggKyAyLCBjbG9zaW5nKVxuICAgICAgICAgIGNvbnN0IGNvZGVQb2ludCA9IC9eWzAtOUEtRmEtZl17MSw2fSQvdS50ZXN0KGhleGFkZWNpbWFsKSA/IE51bWJlci5wYXJzZUludChoZXhhZGVjaW1hbCwgMTYpIDogLTFcblxuICAgICAgICAgIGlmIChjb2RlUG9pbnQgPCAwIHx8IGNvZGVQb2ludCA+IDB4MTBGRkZGKSB0aGlzLmZhaWwobm9kZSwgXCJ1bnN1cHBvcnRlZCBzdHJpbmcgZXNjYXBlXCIpXG4gICAgICAgICAgdmFsdWUgKz0gU3RyaW5nLmZyb21Db2RlUG9pbnQoY29kZVBvaW50KVxuICAgICAgICAgIGluZGV4ID0gY2xvc2luZ1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIGNvbnN0IGhleGFkZWNpbWFsID0gc291cmNlLnNsaWNlKGluZGV4ICsgMSwgaW5kZXggKyA1KVxuXG4gICAgICAgICAgaWYgKCEvXlswLTlBLUZhLWZdezR9JC91LnRlc3QoaGV4YWRlY2ltYWwpKSB0aGlzLmZhaWwobm9kZSwgXCJ1bnN1cHBvcnRlZCBzdHJpbmcgZXNjYXBlXCIpXG4gICAgICAgICAgdmFsdWUgKz0gU3RyaW5nLmZyb21DaGFyQ29kZShOdW1iZXIucGFyc2VJbnQoaGV4YWRlY2ltYWwsIDE2KSlcbiAgICAgICAgICBpbmRleCArPSA0XG4gICAgICAgIH1cbiAgICAgIH0gZWxzZSB0aGlzLmZhaWwobm9kZSwgXCJ1bnN1cHBvcnRlZCBzdHJpbmcgZXNjYXBlXCIpXG4gICAgfVxuICAgIGlmICghaGFzT25seVVuaWNvZGVTY2FsYXJzKHZhbHVlKSkgdGhpcy5mYWlsKG5vZGUsIFwiaW52YWxpZCBVbmljb2RlIHN0cmluZyBsaXRlcmFsXCIpXG4gICAgcmV0dXJuIHZhbHVlXG4gIH1cblxuICAvKipcbiAgICogRXh0cmFjdHMgZXhhY3QgcmVxdWlyZWQgcG9zaXRpb25hbCBhcmd1bWVudHMuXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwidHJlZS1zaXR0ZXJcIikuU3ludGF4Tm9kZX0gcGFydCBDYWxsIGFyZ3VtZW50IHBhcnQuXG4gICAqIEByZXR1cm5zIHtpbXBvcnQoXCJ0cmVlLXNpdHRlclwiKS5TeW50YXhOb2RlW11bXX0gQXJndW1lbnQgZXhwcmVzc2lvbiBlZGdlcy5cbiAgICovXG4gIGFyZ3VtZW50cyhwYXJ0KSB7XG4gICAgY29uc3QgcGFydENoaWxkcmVuID0gdGhpcy5wYXJ0cyhwYXJ0KVxuXG4gICAgaWYgKHBhcnQudHlwZSAhPSBcImFyZ3VtZW50X3BhcnRcIiB8fCBwYXJ0Q2hpbGRyZW4ubGVuZ3RoICE9IDEgfHwgcGFydENoaWxkcmVuWzBdLnR5cGUgIT0gXCJhcmd1bWVudHNcIikge1xuICAgICAgdGhpcy5mYWlsKHBhcnQsIFwiY2FsbCBhcmd1bWVudCBwYXJ0IHNoYXBlXCIpXG4gICAgfVxuICAgIHRoaXMuc2hhcGUocGFydCwgW3BhcnRDaGlsZHJlblswXV0pXG4gICAgY29uc3QgbGlzdCA9IHBhcnRDaGlsZHJlblswXVxuICAgIGNvbnN0IGxpc3RQYXJ0cyA9IHRoaXMucGFydHMobGlzdClcblxuICAgIGlmIChsaXN0UGFydHMubGVuZ3RoIDwgMiB8fCBsaXN0UGFydHNbMF0udGV4dCAhPSBcIihcIiB8fCBsaXN0UGFydHMuYXQoLTEpPy50ZXh0ICE9IFwiKVwiKSB7XG4gICAgICB0aGlzLmZhaWwobGlzdCwgXCJjYWxsIGFyZ3VtZW50IGxpc3Qgc2hhcGVcIilcbiAgICB9XG4gICAgY29uc3QgaW50ZXJpb3IgPSBsaXN0UGFydHMuc2xpY2UoMSwgLTEpXG4gICAgY29uc3QgaGFzR2VuZXJhdGVkVHJhaWxpbmdDb21tYSA9IHRoaXMucnVudGltZSAmJiBpbnRlcmlvci5hdCgtMSk/LnRleHQgPT0gXCIsXCJcbiAgICBjb25zdCBhcmd1bWVudFBhcnRzID0gaGFzR2VuZXJhdGVkVHJhaWxpbmdDb21tYSA/IGludGVyaW9yLnNsaWNlKDAsIC0xKSA6IGludGVyaW9yXG4gICAgY29uc3QgYXJndW1lbnRzXyA9IGFyZ3VtZW50UGFydHMuZmlsdGVyKChfY2hpbGQsIGluZGV4KSA9PiBpbmRleCAlIDIgPT0gMClcblxuICAgIHRoaXMuc2hhcGUobGlzdCwgW1wiKFwiLCAuLi5hcmd1bWVudHNfLmZsYXRNYXAoKGFyZ3VtZW50LCBpbmRleCkgPT4gaW5kZXggPyBbXCIsXCIsIGFyZ3VtZW50XSA6IFthcmd1bWVudF0pLFxuICAgICAgLi4uKGhhc0dlbmVyYXRlZFRyYWlsaW5nQ29tbWEgPyBbXCIsXCJdIDogW10pLCBcIilcIl0pXG4gICAgcmV0dXJuIGFyZ3VtZW50c18ubWFwKChhcmd1bWVudCkgPT4ge1xuICAgICAgaWYgKGFyZ3VtZW50LnR5cGUgIT0gXCJhcmd1bWVudFwiKSB0aGlzLmZhaWwoYXJndW1lbnQsIFwicmVxdWlyZWQgcG9zaXRpb25hbCBhcmd1bWVudFwiKVxuICAgICAgY29uc3QgZXhwcmVzc2lvblBhcnRzID0gdGhpcy5wYXJ0cyhhcmd1bWVudClcblxuICAgICAgaWYgKGV4cHJlc3Npb25QYXJ0cy5sZW5ndGggPT0gMCkgdGhpcy5mYWlsKGFyZ3VtZW50LCBcImVtcHR5IGFyZ3VtZW50XCIpXG4gICAgICByZXR1cm4gZXhwcmVzc2lvblBhcnRzXG4gICAgfSlcbiAgfVxuXG4gIC8qKlxuICAgKiBDb252ZXJ0cyBvbmUgZGlyZWN0IG1ldGhvZC1pbnZvY2F0aW9uIG5vZGUgd2hvc2UgZnVuY3Rpb24gaXMgYSBwbGFpbiBpZGVudGlmaWVyLlxuICAgKiBAcGFyYW0ge2ltcG9ydChcInRyZWUtc2l0dGVyXCIpLlN5bnRheE5vZGVbXX0gbm9kZXMgRXhhY3Qgb25lLW5vZGUgY2FsbC5cbiAgICogQHBhcmFtIHtpbXBvcnQoXCJ0cmVlLXNpdHRlclwiKS5TeW50YXhOb2RlfSBvd25lciBFeHByZXNzaW9uIG93bmVyLlxuICAgKiBAcGFyYW0ge2Jvb2xlYW59IFthbGxvd1ByaW50XSBXaGV0aGVyIHRoaXMgaXMgdGhlIHByaW50IHNjYWZmb2xkLlxuICAgKiBAcmV0dXJucyB7aW1wb3J0KFwiLi4vc2VtYW50aWMvdHlwZXMuanNcIikuRXhwcmVzc2lvbn0gU2VtYW50aWMgY2FsbCBvciBwcml2YXRlIGdlbmVyYXRlZCBvcGVyYXRpb24uXG4gICAqL1xuICBjYWxsKG5vZGVzLCBvd25lciwgYWxsb3dQcmludCA9IGZhbHNlKSB7XG4gICAgaWYgKG5vZGVzLmxlbmd0aCAhPSAxIHx8IG5vZGVzWzBdLnR5cGUgIT0gXCJtZXRob2RfaW52b2NhdGlvblwiKSB7XG4gICAgICB0aGlzLmZhaWwobm9kZXNbMF0gPz8gb3duZXIsIFwiZGlyZWN0IGNhbGwgc2hhcGVcIilcbiAgICB9XG4gICAgY29uc3QgaW52b2NhdGlvbiA9IG5vZGVzWzBdXG4gICAgY29uc3QgcGFydHMgPSB0aGlzLnBhcnRzKGludm9jYXRpb24pXG4gICAgY29uc3QgZnVuY3Rpb25Ob2RlID0gdGhpcy5maWVsZChpbnZvY2F0aW9uLCBcImZ1bmN0aW9uXCIpXG4gICAgY29uc3QgYXJndW1lbnRQYXJ0ID0gdGhpcy5maWVsZChpbnZvY2F0aW9uLCBcImFyZ3VtZW50c1wiKVxuXG4gICAgaWYgKHBhcnRzLmxlbmd0aCAhPSAyIHx8IHBhcnRzWzBdLmlkICE9IGZ1bmN0aW9uTm9kZS5pZCB8fCBmdW5jdGlvbk5vZGUudHlwZSAhPSBcImlkZW50aWZpZXJcIiB8fFxuICAgICAgcGFydHNbMV0uaWQgIT0gYXJndW1lbnRQYXJ0LmlkIHx8IGFyZ3VtZW50UGFydC50eXBlICE9IFwiYXJndW1lbnRfcGFydFwiKSB0aGlzLmZhaWwoaW52b2NhdGlvbiwgXCJkaXJlY3QgY2FsbCBzaGFwZVwiKVxuICAgIHRoaXMuc2hhcGUoaW52b2NhdGlvbiwgW2Z1bmN0aW9uTm9kZSwgYXJndW1lbnRQYXJ0XSlcbiAgICBjb25zdCBuYW1lID0gZnVuY3Rpb25Ob2RlLnRleHRcbiAgICBjb25zdCBoZWxwZXIgPSB0aGlzLnJ1bnRpbWUgPyBoZWxwZXJPcGVyYXRpb25zLmdldChuYW1lKSA6IHVuZGVmaW5lZFxuICAgIGNvbnN0IGxvY2F0aW9uID0gdGhpcy5sb2NhdGlvbihpbnZvY2F0aW9uKVxuICAgIGNvbnN0IGFyZ3VtZW50Tm9kZXMgPSB0aGlzLmFyZ3VtZW50cyhhcmd1bWVudFBhcnQpXG5cbiAgICBpZiAodGhpcy5ydW50aW1lICYmIG5hbWUgPT0gXCJfc2VtYW50aWZvbGRCb29sZWFuXCIpIHtcbiAgICAgIGlmIChhcmd1bWVudE5vZGVzLmxlbmd0aCAhPSAxKSB0aGlzLmZhaWwoYXJndW1lbnRQYXJ0LCBcIkRhcnQgQm9vbGVhbiBsaXRlcmFsIGhlbHBlciBzaGFwZVwiKVxuICAgICAgY29uc3QgbGl0ZXJhbCA9IHRoaXMuZXhwcmVzc2lvbihhcmd1bWVudE5vZGVzWzBdLCBvd25lcilcblxuICAgICAgaWYgKGxpdGVyYWwua2luZCAhPSBcIkJvb2xlYW5MaXRlcmFsXCIpIHRoaXMuZmFpbChhcmd1bWVudFBhcnQsIFwiRGFydCBCb29sZWFuIGxpdGVyYWwgaGVscGVyIHNoYXBlXCIpXG4gICAgICByZXR1cm4gbGl0ZXJhbFxuICAgIH1cbiAgICBpZiAoaGVscGVyKSB7XG4gICAgICBjb25zdCBjb3VudCA9IGhlbHBlciA9PSBcIk5lZ2F0ZVwiID8gMSA6IDJcblxuICAgICAgaWYgKGFyZ3VtZW50Tm9kZXMubGVuZ3RoICE9IGNvdW50KSB0aGlzLmZhaWwoYXJndW1lbnRQYXJ0LCBcIkRhcnQgY2hlY2tlZC1pbnRlZ2VyIGhlbHBlciBzaGFwZVwiKVxuICAgICAgaWYgKGhlbHBlciA9PSBcIk5lZ2F0ZVwiKSB7XG4gICAgICAgIHJldHVybiAvKiogQHR5cGUge2ltcG9ydChcIi4uL3NlbWFudGljL3R5cGVzLmpzXCIpLkV4cHJlc3Npb259ICovICgvKiogQHR5cGUge3Vua25vd259ICovIChcbiAgICAgICAgICB3aXRoQWRhcHRlZE9wZXJhdGlvbih3aXRoUGFyc2VyUmFuZ2VzKHtcbiAgICAgICAgICAgIGtpbmQ6IC8qKiBAdHlwZSB7Y29uc3R9ICovIChcIlVuYXJ5RXhwcmVzc2lvblwiKSwgbG9jYXRpb24sXG4gICAgICAgICAgICBvcGVyYW5kOiB0aGlzLmV4cHJlc3Npb24oYXJndW1lbnROb2Rlc1swXSwgb3duZXIpXG4gICAgICAgICAgfSwge29wZXJhdG9yOiB0aGlzLmxvY2F0aW9uKGZ1bmN0aW9uTm9kZSl9KSwgaGVscGVyKSkpXG4gICAgICB9XG4gICAgICByZXR1cm4gLyoqIEB0eXBlIHtpbXBvcnQoXCIuLi9zZW1hbnRpYy90eXBlcy5qc1wiKS5FeHByZXNzaW9ufSAqLyAoLyoqIEB0eXBlIHt1bmtub3dufSAqLyAoXG4gICAgICAgIHdpdGhBZGFwdGVkT3BlcmF0aW9uKHdpdGhQYXJzZXJSYW5nZXMoe1xuICAgICAgICAgIGtpbmQ6IC8qKiBAdHlwZSB7Y29uc3R9ICovIChcIkJpbmFyeUV4cHJlc3Npb25cIiksIGxlZnQ6IHRoaXMuZXhwcmVzc2lvbihhcmd1bWVudE5vZGVzWzBdLCBvd25lciksIGxvY2F0aW9uLFxuICAgICAgICAgIHJpZ2h0OiB0aGlzLmV4cHJlc3Npb24oYXJndW1lbnROb2Rlc1sxXSwgb3duZXIpXG4gICAgICAgIH0sIHtvcGVyYXRvcjogdGhpcy5sb2NhdGlvbihmdW5jdGlvbk5vZGUpfSksIGhlbHBlcikpKVxuICAgIH1cbiAgICB0aGlzLmlkZW50aWZpZXIoZnVuY3Rpb25Ob2RlLCBmYWxzZSwgYWxsb3dQcmludClcblxuICAgIHJldHVybiB3aXRoUGFyc2VyUmFuZ2VzKHtcbiAgICAgIGFyZ3VtZW50czogYXJndW1lbnROb2Rlcy5tYXAoKGFyZ3VtZW50KSA9PiB0aGlzLmV4cHJlc3Npb24oYXJndW1lbnQsIG93bmVyKSksXG4gICAgICBjYWxsZWU6IG5hbWUsXG4gICAgICBraW5kOiAvKiogQHR5cGUge2NvbnN0fSAqLyAoXCJDYWxsRXhwcmVzc2lvblwiKSxcbiAgICAgIGxvY2F0aW9uXG4gICAgfSwge2NhbGxlZTogdGhpcy5sb2NhdGlvbihmdW5jdGlvbk5vZGUpfSlcbiAgfVxuXG4gIC8qKlxuICAgKiBSZWN1cnNpdmVseSBjb21wYXJlcyBvbmUgc291cmNlIHN1cHBvcnQgc3VidHJlZSB3aXRoIHRoZSBjYW5vbmljYWwgcnVudGltZSBDU1QuXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwidHJlZS1zaXR0ZXJcIikuU3ludGF4Tm9kZX0gYWN0dWFsIFNvdXJjZSBub2RlLlxuICAgKiBAcGFyYW0ge2ltcG9ydChcInRyZWUtc2l0dGVyXCIpLlN5bnRheE5vZGV9IGV4cGVjdGVkIENhbm9uaWNhbCBub2RlLlxuICAgKiBAcmV0dXJucyB7dm9pZH1cbiAgICovXG4gIGNvbXBhcmVUcmVlKGFjdHVhbCwgZXhwZWN0ZWQpIHtcbiAgICBpZiAoYWN0dWFsLnR5cGUgIT0gZXhwZWN0ZWQudHlwZSB8fCBhY3R1YWwuaXNOYW1lZCAhPSBleHBlY3RlZC5pc05hbWVkIHx8IGFjdHVhbC5pc0V4dHJhICE9IGV4cGVjdGVkLmlzRXh0cmEgfHxcbiAgICAgIGFjdHVhbC5jaGlsZENvdW50ICE9IGV4cGVjdGVkLmNoaWxkQ291bnQpIHRoaXMuZmFpbChhY3R1YWwsIFwibW9kaWZpZWQgRGFydCBzdXBwb3J0IG5vZGVcIilcbiAgICBpZiAoYWN0dWFsLmNoaWxkQ291bnQgPT0gMCAmJiBhY3R1YWwudGV4dCAhPSBleHBlY3RlZC50ZXh0KSB0aGlzLmZhaWwoYWN0dWFsLCBcIm1vZGlmaWVkIERhcnQgc3VwcG9ydCB0b2tlblwiKVxuICAgIGZvciAobGV0IGluZGV4ID0gMDsgaW5kZXggPCBhY3R1YWwuY2hpbGRDb3VudDsgaW5kZXggKz0gMSkge1xuICAgICAgY29uc3QgbGVmdCA9IGFjdHVhbC5jaGlsZChpbmRleClcbiAgICAgIGNvbnN0IHJpZ2h0ID0gZXhwZWN0ZWQuY2hpbGQoaW5kZXgpXG5cbiAgICAgIGlmICghbGVmdCB8fCAhcmlnaHQgfHwgYWN0dWFsLmZpZWxkTmFtZUZvckNoaWxkKGluZGV4KSAhPSBleHBlY3RlZC5maWVsZE5hbWVGb3JDaGlsZChpbmRleCkpIHtcbiAgICAgICAgdGhpcy5mYWlsKGxlZnQgPz8gYWN0dWFsLCBcIm1vZGlmaWVkIERhcnQgc3VwcG9ydCBmaWVsZFwiKVxuICAgICAgfVxuICAgICAgdGhpcy5jb21wYXJlVHJlZShsZWZ0LCByaWdodClcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogQ29udmVydHMgYW4gZXhwcmVzc2lvbiByZXByZXNlbnRlZCBieSBvbmUgb3IgbW9yZSBhZGphY2VudCBEYXJ0IENTVCBub2Rlcy5cbiAgICogQHBhcmFtIHtpbXBvcnQoXCJ0cmVlLXNpdHRlclwiKS5TeW50YXhOb2RlW119IG5vZGVzIEV4cHJlc3Npb24gbm9kZXMuXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwidHJlZS1zaXR0ZXJcIikuU3ludGF4Tm9kZX0gb3duZXIgT3duaW5nIG5vZGUuXG4gICAqIEByZXR1cm5zIHtpbXBvcnQoXCIuLi9zZW1hbnRpYy90eXBlcy5qc1wiKS5FeHByZXNzaW9ufSBTZW1hbnRpYyBleHByZXNzaW9uLlxuICAgKi9cbiAgZXhwcmVzc2lvbihub2Rlcywgb3duZXIpIHtcbiAgICBpZiAobm9kZXMubGVuZ3RoID09IDEgJiYgbm9kZXNbMF0udHlwZSA9PSBcIm1ldGhvZF9pbnZvY2F0aW9uXCIpIHJldHVybiB0aGlzLmNhbGwobm9kZXMsIG93bmVyKVxuICAgIGlmIChub2Rlcy5sZW5ndGggIT0gMSkgcmV0dXJuIHRoaXMuZmFpbChub2Rlc1swXSA/PyBvd25lciwgXCJzY2FsYXIgZXhwcmVzc2lvbiBzaGFwZVwiKVxuICAgIGNvbnN0IG5vZGUgPSBub2Rlc1swXVxuICAgIGNvbnN0IGxvY2F0aW9uID0gdGhpcy5sb2NhdGlvbihub2RlKVxuXG4gICAgaWYgKG5vZGUudHlwZSA9PSBcImlkZW50aWZpZXJcIikge1xuICAgICAgY29uc3QgbmFtZSA9IHRoaXMuaWRlbnRpZmllcihub2RlKVxuXG4gICAgICBpZiAodGhpcy5mdW5jdGlvbk5hbWVzLmhhcyhuYW1lKSkgdGhpcy5mYWlsKG5vZGUsIFwiZnVuY3Rpb24gdGVhci1vZmZcIilcbiAgICAgIHJldHVybiB3aXRoUGFyc2VyUmFuZ2VzKHtraW5kOiAvKiogQHR5cGUge2NvbnN0fSAqLyAoXCJJZGVudGlmaWVyRXhwcmVzc2lvblwiKSwgbG9jYXRpb24sIG5hbWV9LCB7bmFtZTogbG9jYXRpb259KVxuICAgIH1cbiAgICBpZiAobm9kZS50eXBlID09IFwiZGVjaW1hbF9pbnRlZ2VyX2xpdGVyYWxcIikge1xuICAgICAgaWYgKHRoaXMucGFydHMobm9kZSkubGVuZ3RoICE9IDAgfHwgIS9eKD86MHxbMS05XVswLTldKikkL3UudGVzdChub2RlLnRleHQpKSB0aGlzLmZhaWwobm9kZSwgXCJub25jYW5vbmljYWwgaW50ZWdlciBsaXRlcmFsXCIpXG4gICAgICBjb25zdCB2YWx1ZSA9IE51bWJlcihCaWdJbnQobm9kZS50ZXh0KSlcblxuICAgICAgaWYgKCFOdW1iZXIuaXNTYWZlSW50ZWdlcih2YWx1ZSkpIHRoaXMuZmFpbChub2RlLCBcIm5vbi1zYWZlIGludGVnZXIgbGl0ZXJhbFwiKVxuICAgICAgcmV0dXJuIHdpdGhQYXJzZXJSYW5nZXMoe2tpbmQ6IC8qKiBAdHlwZSB7Y29uc3R9ICovIChcIkludGVnZXJMaXRlcmFsXCIpLCBsb2NhdGlvbiwgdmFsdWV9LCB7bGl0ZXJhbDogbG9jYXRpb259KVxuICAgIH1cbiAgICBpZiAobm9kZS50eXBlID09IFwidHJ1ZVwiIHx8IG5vZGUudHlwZSA9PSBcImZhbHNlXCIpIHtcbiAgICAgIHRoaXMuc2hhcGUobm9kZSwgW25vZGUudHlwZV0pXG4gICAgICByZXR1cm4gd2l0aFBhcnNlclJhbmdlcyh7a2luZDogLyoqIEB0eXBlIHtjb25zdH0gKi8gKFwiQm9vbGVhbkxpdGVyYWxcIiksIGxvY2F0aW9uLCB2YWx1ZTogbm9kZS50eXBlID09IFwidHJ1ZVwifSwge2xpdGVyYWw6IGxvY2F0aW9ufSlcbiAgICB9XG4gICAgaWYgKG5vZGUudHlwZSA9PSBcInN0cmluZ19saXRlcmFsXCIpIHtcbiAgICAgIHJldHVybiB3aXRoUGFyc2VyUmFuZ2VzKHtraW5kOiAvKiogQHR5cGUge2NvbnN0fSAqLyAoXCJTdHJpbmdMaXRlcmFsXCIpLCBsb2NhdGlvbiwgdmFsdWU6IHRoaXMuc3RyaW5nKG5vZGUpfSwge2xpdGVyYWw6IGxvY2F0aW9ufSlcbiAgICB9XG4gICAgaWYgKG5vZGUudHlwZSA9PSBcInBhcmVudGhlc2l6ZWRfZXhwcmVzc2lvblwiKSB7XG4gICAgICBjb25zdCBwYXJ0cyA9IHRoaXMucGFydHMobm9kZSlcblxuICAgICAgaWYgKHBhcnRzLmxlbmd0aCA8IDMgfHwgcGFydHNbMF0udGV4dCAhPSBcIihcIiB8fCBwYXJ0cy5hdCgtMSk/LnRleHQgIT0gXCIpXCIpIHRoaXMuZmFpbChub2RlLCBcInBhcmVudGhlc2l6ZWQgZXhwcmVzc2lvbiBzaGFwZVwiKVxuICAgICAgdGhpcy5zaGFwZShub2RlLCBbXCIoXCIsIC4uLnBhcnRzLnNsaWNlKDEsIC0xKSwgXCIpXCJdKVxuICAgICAgcmV0dXJuIHRoaXMuZXhwcmVzc2lvbihwYXJ0cy5zbGljZSgxLCAtMSksIG5vZGUpXG4gICAgfVxuICAgIGlmIChub2RlLnR5cGUgPT0gXCJ1bmFyeV9leHByZXNzaW9uXCIpIHtcbiAgICAgIGNvbnN0IHBhcnRzID0gdGhpcy5wYXJ0cyhub2RlKVxuICAgICAgY29uc3Qgb3BlcmF0b3IgPSBwYXJ0c1swXVxuXG4gICAgICBpZiAocGFydHMubGVuZ3RoIDwgMiB8fCBvcGVyYXRvci50eXBlICE9IFwicHJlZml4X29wZXJhdG9yXCIgfHwgIVtcIi1cIiwgXCIhXCJdLmluY2x1ZGVzKG9wZXJhdG9yLnRleHQpKSB7XG4gICAgICAgIHRoaXMuZmFpbChub2RlLCBcInVuYXJ5IG9wZXJhdG9yXCIpXG4gICAgICB9XG4gICAgICBjb25zdCBvcGVyYXRvclBhcnRzID0gdGhpcy5wYXJ0cyhvcGVyYXRvcilcblxuICAgICAgaWYgKG9wZXJhdG9yUGFydHMubGVuZ3RoICE9IDEgfHwgb3BlcmF0b3JQYXJ0c1swXS50ZXh0ICE9IG9wZXJhdG9yLnRleHQgfHxcbiAgICAgICAgIVtcIm1pbnVzX29wZXJhdG9yXCIsIFwibmVnYXRpb25fb3BlcmF0b3JcIl0uaW5jbHVkZXMob3BlcmF0b3JQYXJ0c1swXS50eXBlKSkgdGhpcy5mYWlsKG9wZXJhdG9yLCBcInVuYXJ5IG9wZXJhdG9yIHNoYXBlXCIpXG4gICAgICB0aGlzLm9wZXJhdG9yU2hhcGUob3BlcmF0b3JQYXJ0c1swXSlcbiAgICAgIHRoaXMuc2hhcGUobm9kZSwgW29wZXJhdG9yLCAuLi5wYXJ0cy5zbGljZSgxKV0pXG4gICAgICByZXR1cm4gLyoqIEB0eXBlIHtpbXBvcnQoXCIuLi9zZW1hbnRpYy90eXBlcy5qc1wiKS5FeHByZXNzaW9ufSAqLyAoLyoqIEB0eXBlIHt1bmtub3dufSAqLyAod2l0aEFkYXB0ZWRPcGVyYXRpb24od2l0aFBhcnNlclJhbmdlcyh7XG4gICAgICAgIGtpbmQ6IC8qKiBAdHlwZSB7Y29uc3R9ICovIChcIlVuYXJ5RXhwcmVzc2lvblwiKSxcbiAgICAgICAgbG9jYXRpb24sXG4gICAgICAgIG9wZXJhbmQ6IHRoaXMuZXhwcmVzc2lvbihwYXJ0cy5zbGljZSgxKSwgbm9kZSlcbiAgICAgIH0sIHtvcGVyYXRvcjogdGhpcy5sb2NhdGlvbihvcGVyYXRvcil9KSwgb3BlcmF0b3IudGV4dCA9PSBcIi1cIiA/IFwiTmVnYXRlXCIgOiBcIk5vdFwiKSkpXG4gICAgfVxuICAgIGlmIChiaW5hcnlOb2RlT3BlcmF0b3JzLmhhcyhub2RlLnR5cGUpKSByZXR1cm4gdGhpcy5iaW5hcnkobm9kZSlcbiAgICByZXR1cm4gdGhpcy5mYWlsKG5vZGUpXG4gIH1cblxuICAvKipcbiAgICogQ29udmVydHMgYSBib3VuZGVkIGJpbmFyeSBleHByZXNzaW9uIHRyZWUuXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwidHJlZS1zaXR0ZXJcIikuU3ludGF4Tm9kZX0gbm9kZSBCaW5hcnkgZXhwcmVzc2lvbiBub2RlLlxuICAgKiBAcmV0dXJucyB7aW1wb3J0KFwiLi4vc2VtYW50aWMvdHlwZXMuanNcIikuRXhwcmVzc2lvbn0gU2VtYW50aWMgYmluYXJ5IGV4cHJlc3Npb24uXG4gICAqL1xuICBiaW5hcnkobm9kZSkge1xuICAgIC8qKiBAdHlwZSB7aW1wb3J0KFwidHJlZS1zaXR0ZXJcIikuU3ludGF4Tm9kZVtdW119ICovXG4gICAgY29uc3Qgb3BlcmFuZHMgPSBbXVxuICAgIC8qKiBAdHlwZSB7aW1wb3J0KFwidHJlZS1zaXR0ZXJcIikuU3ludGF4Tm9kZVtdfSAqL1xuICAgIGNvbnN0IG9wZXJhdG9ycyA9IFtdXG4gICAgbGV0IGN1cnJlbnQgPSBub2RlXG5cbiAgICB3aGlsZSAodHJ1ZSkge1xuICAgICAgY29uc3QgcGFydHMgPSB0aGlzLnBhcnRzKGN1cnJlbnQpXG4gICAgICBjb25zdCBkZWNsYXJhdGlvbiA9IGJpbmFyeU5vZGVPcGVyYXRvcnMuZ2V0KGN1cnJlbnQudHlwZSlcbiAgICAgIGNvbnN0IG9wZXJhdG9yVHlwZSA9IGRlY2xhcmF0aW9uPy5bMF1cbiAgICAgIGNvbnN0IGFjY2VwdGVkID0gZGVjbGFyYXRpb24/LlsxXVxuICAgICAgY29uc3Qgb3BlcmF0b3JJbmRleGVzID0gcGFydHMuZmxhdE1hcCgocGFydCwgaW5kZXgpID0+IHBhcnQudHlwZSA9PSBvcGVyYXRvclR5cGUgPyBbaW5kZXhdIDogW10pXG5cbiAgICAgIGlmIChvcGVyYXRvckluZGV4ZXMubGVuZ3RoICE9IDEpIHRoaXMuZmFpbChjdXJyZW50LCBgJHtjdXJyZW50LnR5cGV9IGNoaWxkIHNoYXBlYClcbiAgICAgIGNvbnN0IG9wZXJhdG9ySW5kZXggPSBvcGVyYXRvckluZGV4ZXNbMF1cbiAgICAgIGNvbnN0IG9wZXJhdG9yID0gcGFydHNbb3BlcmF0b3JJbmRleF1cblxuICAgICAgaWYgKG9wZXJhdG9ySW5kZXggPT0gMCB8fCBvcGVyYXRvckluZGV4ID09IHBhcnRzLmxlbmd0aCAtIDEgfHwgIWFjY2VwdGVkPy5oYXMob3BlcmF0b3IudGV4dCkgfHxcbiAgICAgICAgIWJpbmFyeU9wZXJhdGlvbnMuaGFzKG9wZXJhdG9yLnRleHQpKSB0aGlzLmZhaWwob3BlcmF0b3IsIFwidW5zdXBwb3J0ZWQgYmluYXJ5IG9wZXJhdG9yXCIpXG4gICAgICB0aGlzLm9wZXJhdG9yU2hhcGUob3BlcmF0b3IpXG4gICAgICB0aGlzLnNoYXBlKGN1cnJlbnQsIHBhcnRzKVxuICAgICAgb3BlcmFuZHMucHVzaChwYXJ0cy5zbGljZSgwLCBvcGVyYXRvckluZGV4KSlcbiAgICAgIG9wZXJhdG9ycy5wdXNoKG9wZXJhdG9yKVxuICAgICAgY29uc3QgcmlnaHQgPSBwYXJ0cy5zbGljZShvcGVyYXRvckluZGV4ICsgMSlcblxuICAgICAgaWYgKHJpZ2h0Lmxlbmd0aCA9PSAxICYmIHJpZ2h0WzBdLnR5cGUgPT0gbm9kZS50eXBlKSBjdXJyZW50ID0gcmlnaHRbMF1cbiAgICAgIGVsc2Uge1xuICAgICAgICBvcGVyYW5kcy5wdXNoKHJpZ2h0KVxuICAgICAgICBicmVha1xuICAgICAgfVxuICAgIH1cbiAgICBsZXQgZXhwcmVzc2lvbiA9IHRoaXMuZXhwcmVzc2lvbihvcGVyYW5kc1swXSwgbm9kZSlcblxuICAgIGZvciAobGV0IGluZGV4ID0gMDsgaW5kZXggPCBvcGVyYXRvcnMubGVuZ3RoOyBpbmRleCArPSAxKSB7XG4gICAgICBjb25zdCBvcGVyYXRvciA9IG9wZXJhdG9yc1tpbmRleF1cbiAgICAgIGNvbnN0IG9wZXJhdGlvbiA9IGJpbmFyeU9wZXJhdGlvbnMuZ2V0KG9wZXJhdG9yLnRleHQpXG4gICAgICBjb25zdCByaWdodCA9IHRoaXMuZXhwcmVzc2lvbihvcGVyYW5kc1tpbmRleCArIDFdLCBub2RlKVxuICAgICAgY29uc3QgZmlyc3QgPSBvcGVyYW5kc1swXVswXVxuICAgICAgY29uc3QgbGFzdCA9IG9wZXJhbmRzW2luZGV4ICsgMV0uYXQoLTEpXG4gICAgICBjb25zdCBsb2NhdGlvbiA9IGZpcnN0ICYmIGxhc3RcbiAgICAgICAgPyBsb2NhdGlvbkZyb21PZmZzZXRzKHRoaXMuZmlsZW5hbWUsIHRoaXMuc291cmNlLCBiaW5kaW5nSW5kZXhUb1V0ZjE2T2Zmc2V0KHRoaXMuc291cmNlLCBmaXJzdC5zdGFydEluZGV4KSxcbiAgICAgICAgICBiaW5kaW5nSW5kZXhUb1V0ZjE2T2Zmc2V0KHRoaXMuc291cmNlLCBsYXN0LmVuZEluZGV4KSlcbiAgICAgICAgOiB0aGlzLmxvY2F0aW9uKG5vZGUpXG5cbiAgICAgIGV4cHJlc3Npb24gPSAvKiogQHR5cGUge2ltcG9ydChcIi4uL3NlbWFudGljL3R5cGVzLmpzXCIpLkV4cHJlc3Npb259ICovICh3aXRoQWRhcHRlZE9wZXJhdGlvbih3aXRoUGFyc2VyUmFuZ2VzKHtcbiAgICAgICAga2luZDogLyoqIEB0eXBlIHtjb25zdH0gKi8gKFwiQmluYXJ5RXhwcmVzc2lvblwiKSwgbGVmdDogZXhwcmVzc2lvbiwgbG9jYXRpb24sIHJpZ2h0XG4gICAgICB9LCB7b3BlcmF0b3I6IHRoaXMubG9jYXRpb24ob3BlcmF0b3IpfSksIC8qKiBAdHlwZSB7aW1wb3J0KFwiLi4vc2VtYW50aWMvb3BlcmF0b3JzLmpzXCIpLkFkYXB0ZWRPcGVyYXRpb259ICovIChvcGVyYXRpb24pKSlcbiAgICB9XG4gICAgcmV0dXJuIGV4cHJlc3Npb25cbiAgfVxuXG4gIC8qKlxuICAgKiBDb252ZXJ0cyBvbmUgZXhwbGljaXRseSB0eXBlZCBpbml0aWFsaXplZCBsb2NhbCBkZWNsYXJhdGlvbi5cbiAgICogQHBhcmFtIHtpbXBvcnQoXCJ0cmVlLXNpdHRlclwiKS5TeW50YXhOb2RlfSBub2RlIExvY2FsIGRlY2xhcmF0aW9uLlxuICAgKiBAcmV0dXJucyB7aW1wb3J0KFwiLi4vc2VtYW50aWMvdHlwZXMuanNcIikuTG9jYWxEZWNsYXJhdGlvbn0gU2VtYW50aWMgbG9jYWwuXG4gICAqL1xuICBsb2NhbChub2RlKSB7XG4gICAgY29uc3QgZGVjbGFyYXRpb25QYXJ0cyA9IHRoaXMucGFydHMobm9kZSlcblxuICAgIGlmIChub2RlLnR5cGUgIT0gXCJsb2NhbF92YXJpYWJsZV9kZWNsYXJhdGlvblwiIHx8IGRlY2xhcmF0aW9uUGFydHMubGVuZ3RoICE9IDIgfHxcbiAgICAgIGRlY2xhcmF0aW9uUGFydHNbMF0udHlwZSAhPSBcImluaXRpYWxpemVkX3ZhcmlhYmxlX2RlZmluaXRpb25cIiB8fCBkZWNsYXJhdGlvblBhcnRzWzFdLnRleHQgIT0gXCI7XCIpIHtcbiAgICAgIHRoaXMuZmFpbChub2RlLCBcImxvY2FsIGRlY2xhcmF0aW9uIHNoYXBlXCIpXG4gICAgfVxuICAgIHRoaXMuc2hhcGUobm9kZSwgW2RlY2xhcmF0aW9uUGFydHNbMF0sIFwiO1wiXSlcbiAgICBjb25zdCBkZWZpbml0aW9uID0gZGVjbGFyYXRpb25QYXJ0c1swXVxuICAgIGNvbnN0IHBhcnRzID0gdGhpcy5wYXJ0cyhkZWZpbml0aW9uKVxuXG4gICAgaWYgKHBhcnRzWzBdPy50eXBlID09IFwiaW5mZXJyZWRfdHlwZVwiIHx8IHBhcnRzWzBdPy50eXBlID09IFwiZmluYWxfYnVpbHRpblwiICYmIHBhcnRzWzFdPy50eXBlID09IFwiaWRlbnRpZmllclwiKSB7XG4gICAgICByZXR1cm4gbWlzc2luZ1R5cGUoXCJkYXJ0XCIsIFwiTG9jYWxcIiwgdGhpcy5sb2NhdGlvbihkZWZpbml0aW9uKSlcbiAgICB9XG4gICAgY29uc3QgaW1tdXRhYmxlID0gcGFydHNbMF0/LnR5cGUgPT0gXCJmaW5hbF9idWlsdGluXCJcbiAgICBjb25zdCB0eXBlSW5kZXggPSBpbW11dGFibGUgPyAxIDogMFxuICAgIGNvbnN0IHR5cGVOb2RlID0gcGFydHNbdHlwZUluZGV4XVxuICAgIGNvbnN0IG5hbWVOb2RlID0gcGFydHNbdHlwZUluZGV4ICsgMV1cbiAgICBjb25zdCBlcXVhbHMgPSBwYXJ0c1t0eXBlSW5kZXggKyAyXVxuICAgIGNvbnN0IGV4cHJlc3Npb25QYXJ0cyA9IHBhcnRzLnNsaWNlKHR5cGVJbmRleCArIDMpXG5cbiAgICBpZiAocGFydHMubGVuZ3RoIDwgdHlwZUluZGV4ICsgNCB8fCB0eXBlTm9kZT8udHlwZSAhPSBcInR5cGVfaWRlbnRpZmllclwiIHx8IG5hbWVOb2RlPy50eXBlICE9IFwiaWRlbnRpZmllclwiIHx8XG4gICAgICBlcXVhbHM/LnRleHQgIT0gXCI9XCIgfHwgZXhwcmVzc2lvblBhcnRzLmxlbmd0aCA9PSAwIHx8IGltbXV0YWJsZSAmJiBwYXJ0c1swXS50ZXh0ICE9IFwiZmluYWxcIikge1xuICAgICAgdGhpcy5mYWlsKHBhcnRzWzBdID8/IGRlZmluaXRpb24sIFwiZXhwbGljaXRseSB0eXBlZCBpbml0aWFsaXplZCBsb2NhbCByZXF1aXJlZFwiKVxuICAgIH1cbiAgICB0aGlzLnNoYXBlKGRlZmluaXRpb24sIFsuLi4oaW1tdXRhYmxlID8gW3BhcnRzWzBdXSA6IFtdKSwgdHlwZU5vZGUsIG5hbWVOb2RlLCBcIj1cIiwgLi4uZXhwcmVzc2lvblBhcnRzXSlcbiAgICBpZiAodGhpcy5maWVsZChkZWZpbml0aW9uLCBcIm5hbWVcIikuaWQgIT0gbmFtZU5vZGUuaWQpIHRoaXMuZmFpbChuYW1lTm9kZSwgXCJsb2NhbCBuYW1lIGZpZWxkXCIpXG4gICAgY29uc3QgbmFtZSA9IHRoaXMuaWRlbnRpZmllcihuYW1lTm9kZSlcblxuICAgIHJldHVybiB3aXRoUGFyc2VyUmFuZ2VzKHtcbiAgICAgIGluaXRpYWxpemVyOiB0aGlzLmV4cHJlc3Npb24oZXhwcmVzc2lvblBhcnRzLCBkZWZpbml0aW9uKSxcbiAgICAgIGtpbmQ6IC8qKiBAdHlwZSB7Y29uc3R9ICovIChcIkxvY2FsRGVjbGFyYXRpb25cIiksXG4gICAgICBsb2NhdGlvbjogdGhpcy5sb2NhdGlvbihub2RlKSxcbiAgICAgIG11dGFibGU6ICFpbW11dGFibGUsXG4gICAgICBuYW1lLFxuICAgICAgdHlwZTogdGhpcy5zY2FsYXJUeXBlKHR5cGVOb2RlKVxuICAgIH0sIHtuYW1lOiB0aGlzLmxvY2F0aW9uKG5hbWVOb2RlKSwgb3BlcmF0b3I6IHRoaXMubG9jYXRpb24oZXF1YWxzKX0pXG4gIH1cblxuICAvKipcbiAgICogQ29udmVydHMgb25lIHNpbXBsZSBpZGVudGlmaWVyIGFzc2lnbm1lbnQuXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwidHJlZS1zaXR0ZXJcIikuU3ludGF4Tm9kZX0gbm9kZSBBc3NpZ25tZW50IGV4cHJlc3Npb24uXG4gICAqIEByZXR1cm5zIHtpbXBvcnQoXCIuLi9zZW1hbnRpYy90eXBlcy5qc1wiKS5Bc3NpZ25tZW50U3RhdGVtZW50fSBTZW1hbnRpYyBhc3NpZ25tZW50LlxuICAgKi9cbiAgYXNzaWdubWVudChub2RlKSB7XG4gICAgY29uc3QgcGFydHMgPSB0aGlzLnBhcnRzKG5vZGUpXG4gICAgY29uc3QgdGFyZ2V0ID0gcGFydHNbMF1cbiAgICBjb25zdCBvcGVyYXRvciA9IHBhcnRzWzFdXG5cbiAgICBpZiAobm9kZS50eXBlICE9IFwiYXNzaWdubWVudF9leHByZXNzaW9uXCIgfHwgcGFydHMubGVuZ3RoIDwgMyB8fCB0YXJnZXQ/LnR5cGUgIT0gXCJhc3NpZ25hYmxlX2V4cHJlc3Npb25cIiB8fFxuICAgICAgb3BlcmF0b3I/LnR5cGUgIT0gXCJhc3NpZ25tZW50X29wZXJhdG9yXCIgfHwgb3BlcmF0b3IudGV4dCAhPSBcIj1cIikgdGhpcy5mYWlsKG5vZGUsIFwic2ltcGxlIGFzc2lnbm1lbnQgc2hhcGVcIilcbiAgICBjb25zdCB0YXJnZXRQYXJ0cyA9IHRoaXMucGFydHModGFyZ2V0KVxuXG4gICAgaWYgKHRhcmdldFBhcnRzLmxlbmd0aCAhPSAxIHx8IHRhcmdldFBhcnRzWzBdLnR5cGUgIT0gXCJpZGVudGlmaWVyXCIpIHRoaXMuZmFpbCh0YXJnZXQsIFwic2ltcGxlIGFzc2lnbm1lbnQgdGFyZ2V0XCIpXG4gICAgdGhpcy5zaGFwZSh0YXJnZXQsIFt0YXJnZXRQYXJ0c1swXV0pXG4gICAgdGhpcy5vcGVyYXRvclNoYXBlKG9wZXJhdG9yKVxuICAgIHRoaXMuc2hhcGUobm9kZSwgW3RhcmdldCwgXCI9XCIsIC4uLnBhcnRzLnNsaWNlKDIpXSlcbiAgICBjb25zdCBuYW1lID0gdGhpcy5pZGVudGlmaWVyKHRhcmdldFBhcnRzWzBdKVxuICAgIGNvbnN0IHRhcmdldExvY2F0aW9uID0gdGhpcy5sb2NhdGlvbih0YXJnZXRQYXJ0c1swXSlcblxuICAgIHJldHVybiB3aXRoUGFyc2VyUmFuZ2VzKHtcbiAgICAgIGV4cHJlc3Npb246IHRoaXMuZXhwcmVzc2lvbihwYXJ0cy5zbGljZSgyKSwgbm9kZSksXG4gICAgICBraW5kOiAvKiogQHR5cGUge2NvbnN0fSAqLyAoXCJBc3NpZ25tZW50U3RhdGVtZW50XCIpLFxuICAgICAgbG9jYXRpb246IHRoaXMubG9jYXRpb24obm9kZSksXG4gICAgICB0YXJnZXQ6IHdpdGhQYXJzZXJSYW5nZXMoe2tpbmQ6IC8qKiBAdHlwZSB7Y29uc3R9ICovIChcIklkZW50aWZpZXJFeHByZXNzaW9uXCIpLCBsb2NhdGlvbjogdGFyZ2V0TG9jYXRpb24sIG5hbWV9LCB7bmFtZTogdGFyZ2V0TG9jYXRpb259KVxuICAgIH0sIHtvcGVyYXRvcjogdGhpcy5sb2NhdGlvbihvcGVyYXRvcil9KVxuICB9XG5cbiAgLyoqXG4gICAqIENvbnZlcnRzIG9uZSBzdXBwb3J0ZWQgRGFydCBzdGF0ZW1lbnQuXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwidHJlZS1zaXR0ZXJcIikuU3ludGF4Tm9kZX0gbm9kZSBTb3VyY2Ugc3RhdGVtZW50LlxuICAgKiBAcmV0dXJucyB7aW1wb3J0KFwiLi4vc2VtYW50aWMvdHlwZXMuanNcIikuU3RhdGVtZW50fSBTZW1hbnRpYyBzdGF0ZW1lbnQuXG4gICAqL1xuICBzdGF0ZW1lbnQobm9kZSkge1xuICAgIGlmIChub2RlLnR5cGUgPT0gXCJsb2NhbF92YXJpYWJsZV9kZWNsYXJhdGlvblwiKSByZXR1cm4gdGhpcy5sb2NhbChub2RlKVxuICAgIGlmIChub2RlLnR5cGUgPT0gXCJpZl9zdGF0ZW1lbnRcIikgcmV0dXJuIHRoaXMuY29uZGl0aW9uYWwobm9kZSlcbiAgICBpZiAobm9kZS50eXBlID09IFwicmV0dXJuX3N0YXRlbWVudFwiKSB7XG4gICAgICBjb25zdCBwYXJ0cyA9IHRoaXMucGFydHMobm9kZSlcblxuICAgICAgaWYgKHBhcnRzLmxlbmd0aCA8IDIgfHwgcGFydHNbMF0udGV4dCAhPSBcInJldHVyblwiIHx8IHBhcnRzLmF0KC0xKT8udGV4dCAhPSBcIjtcIikgdGhpcy5mYWlsKG5vZGUsIFwicmV0dXJuIHN0YXRlbWVudCBzaGFwZVwiKVxuICAgICAgdGhpcy5zaGFwZShub2RlLCBbXCJyZXR1cm5cIiwgLi4ucGFydHMuc2xpY2UoMSwgLTEpLCBcIjtcIl0pXG4gICAgICBjb25zdCBleHByZXNzaW9uUGFydHMgPSBwYXJ0cy5zbGljZSgxLCAtMSlcblxuICAgICAgcmV0dXJuIHtcbiAgICAgICAgLi4uKGV4cHJlc3Npb25QYXJ0cy5sZW5ndGggPiAwID8ge2V4cHJlc3Npb246IHRoaXMuZXhwcmVzc2lvbihleHByZXNzaW9uUGFydHMsIG5vZGUpfSA6IHt9KSxcbiAgICAgICAga2luZDogLyoqIEB0eXBlIHtjb25zdH0gKi8gKFwiUmV0dXJuU3RhdGVtZW50XCIpLFxuICAgICAgICBsb2NhdGlvbjogdGhpcy5sb2NhdGlvbihub2RlKVxuICAgICAgfVxuICAgIH1cbiAgICBpZiAobm9kZS50eXBlID09IFwiZXhwcmVzc2lvbl9zdGF0ZW1lbnRcIikge1xuICAgICAgY29uc3QgcGFydHMgPSB0aGlzLnBhcnRzKG5vZGUpXG5cbiAgICAgIGlmIChwYXJ0cy5sZW5ndGggPCAyIHx8IHBhcnRzLmF0KC0xKT8udGV4dCAhPSBcIjtcIikgdGhpcy5mYWlsKG5vZGUsIFwiZXhwcmVzc2lvbiBzdGF0ZW1lbnQgc2hhcGVcIilcbiAgICAgIHRoaXMuc2hhcGUobm9kZSwgWy4uLnBhcnRzLnNsaWNlKDAsIC0xKSwgXCI7XCJdKVxuICAgICAgaWYgKHBhcnRzLmxlbmd0aCA9PSAyICYmIHBhcnRzWzBdLnR5cGUgPT0gXCJhc3NpZ25tZW50X2V4cHJlc3Npb25cIikgcmV0dXJuIHRoaXMuYXNzaWdubWVudChwYXJ0c1swXSlcbiAgICAgIGNvbnN0IGNhbGxQYXJ0cyA9IHBhcnRzLnNsaWNlKDAsIC0xKVxuICAgICAgY29uc3QgY2FsbENoaWxkcmVuID0gY2FsbFBhcnRzLmxlbmd0aCA9PSAxICYmIGNhbGxQYXJ0c1swXS50eXBlID09IFwibWV0aG9kX2ludm9jYXRpb25cIlxuICAgICAgICA/IHRoaXMucGFydHMoY2FsbFBhcnRzWzBdKSA6IFtdXG4gICAgICBjb25zdCBwcmludCA9IGNhbGxDaGlsZHJlblswXT8udHlwZSA9PSBcImlkZW50aWZpZXJcIiAmJiBjYWxsQ2hpbGRyZW5bMF0udGV4dCA9PSBcInByaW50XCJcbiAgICAgIGNvbnN0IGV4cHJlc3Npb24gPSB0aGlzLmNhbGwoY2FsbFBhcnRzLCBub2RlLCBwcmludClcblxuICAgICAgaWYgKHByaW50KSB7XG4gICAgICAgIGlmIChleHByZXNzaW9uLmtpbmQgIT0gXCJDYWxsRXhwcmVzc2lvblwiIHx8IGV4cHJlc3Npb24uYXJndW1lbnRzLmxlbmd0aCAhPSAxKSB7XG4gICAgICAgICAgdGhpcy5mYWlsKGNhbGxQYXJ0c1swXSwgXCJwcmludCBhcmd1bWVudCBjb3VudFwiKVxuICAgICAgICB9XG4gICAgICAgIHJldHVybiB7ZXhwcmVzc2lvbjogZXhwcmVzc2lvbi5hcmd1bWVudHNbMF0sIGtpbmQ6IC8qKiBAdHlwZSB7Y29uc3R9ICovIChcIlByaW50U3RhdGVtZW50XCIpLCBsb2NhdGlvbjogdGhpcy5sb2NhdGlvbihub2RlKX1cbiAgICAgIH1cbiAgICAgIGlmIChleHByZXNzaW9uLmtpbmQgIT0gXCJDYWxsRXhwcmVzc2lvblwiKSB0aGlzLmZhaWwoY2FsbFBhcnRzWzBdLCBcImdlbmVyYXRlZCBoZWxwZXIgZXhwcmVzc2lvbiBzdGF0ZW1lbnRcIilcbiAgICAgIHJldHVybiB7ZXhwcmVzc2lvbiwga2luZDogLyoqIEB0eXBlIHtjb25zdH0gKi8gKFwiRXhwcmVzc2lvblN0YXRlbWVudFwiKSwgbG9jYXRpb246IHRoaXMubG9jYXRpb24obm9kZSl9XG4gICAgfVxuICAgIHJldHVybiB0aGlzLmZhaWwobm9kZSlcbiAgfVxuXG4gIC8qKlxuICAgKiBDb25zdW1lcyBvbmUgY29tcGlsZXItb3duZWQgcmVhZCB0aGF0IHByZXZlbnRzIERhcnQgZnJvbSByZWplY3RpbmcgYW4gb3RoZXJ3aXNlIHVucmVhZCBsb2NhbC5cbiAgICogQHBhcmFtIHtpbXBvcnQoXCJ0cmVlLXNpdHRlclwiKS5TeW50YXhOb2RlfSBub2RlIENhbmRpZGF0ZSBzb3VyY2Ugc3RhdGVtZW50LlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4uL3NlbWFudGljL3R5cGVzLmpzXCIpLlN0YXRlbWVudCB8IHVuZGVmaW5lZH0gcHJldmlvdXMgUHJldmlvdXMgc2VtYW50aWMgc3RhdGVtZW50LlxuICAgKiBAcmV0dXJucyB7Ym9vbGVhbn0gV2hldGhlciB0aGUgZXhhY3QgYXV0aGVudGljYXRlZCBzdXBwb3J0IHN0YXRlbWVudCB3YXMgY29uc3VtZWQuXG4gICAqL1xuICBnZW5lcmF0ZWRMb2NhbFVzZShub2RlLCBwcmV2aW91cykge1xuICAgIGlmICghdGhpcy5ydW50aW1lIHx8IHByZXZpb3VzPy5raW5kICE9IFwiTG9jYWxEZWNsYXJhdGlvblwiIHx8IG5vZGUudHlwZSAhPSBcImV4cHJlc3Npb25fc3RhdGVtZW50XCIpIHJldHVybiBmYWxzZVxuICAgIGNvbnN0IHN0YXRlbWVudFBhcnRzID0gdGhpcy5wYXJ0cyhub2RlKVxuICAgIGNvbnN0IGludm9jYXRpb24gPSBzdGF0ZW1lbnRQYXJ0c1swXVxuXG4gICAgaWYgKHN0YXRlbWVudFBhcnRzLmxlbmd0aCAhPSAyIHx8IGludm9jYXRpb24/LnR5cGUgIT0gXCJtZXRob2RfaW52b2NhdGlvblwiIHx8IHN0YXRlbWVudFBhcnRzWzFdLnRleHQgIT0gXCI7XCIpIHJldHVybiBmYWxzZVxuICAgIGNvbnN0IGludm9jYXRpb25QYXJ0cyA9IHRoaXMucGFydHMoaW52b2NhdGlvbilcbiAgICBjb25zdCBmdW5jdGlvbk5vZGUgPSB0aGlzLmZpZWxkKGludm9jYXRpb24sIFwiZnVuY3Rpb25cIilcbiAgICBjb25zdCBhcmd1bWVudFBhcnQgPSB0aGlzLmZpZWxkKGludm9jYXRpb24sIFwiYXJndW1lbnRzXCIpXG5cbiAgICBpZiAoaW52b2NhdGlvblBhcnRzLmxlbmd0aCAhPSAyIHx8IGludm9jYXRpb25QYXJ0c1swXS5pZCAhPSBmdW5jdGlvbk5vZGUuaWQgfHwgZnVuY3Rpb25Ob2RlLnR5cGUgIT0gXCJpZGVudGlmaWVyXCIgfHxcbiAgICAgIGZ1bmN0aW9uTm9kZS50ZXh0ICE9IFwiX3NlbWFudGlmb2xkVXNlXCIgfHwgaW52b2NhdGlvblBhcnRzWzFdLmlkICE9IGFyZ3VtZW50UGFydC5pZCB8fCBhcmd1bWVudFBhcnQudHlwZSAhPSBcImFyZ3VtZW50X3BhcnRcIikge1xuICAgICAgcmV0dXJuIGZhbHNlXG4gICAgfVxuICAgIHRoaXMuc2hhcGUobm9kZSwgW2ludm9jYXRpb24sIFwiO1wiXSlcbiAgICB0aGlzLnNoYXBlKGludm9jYXRpb24sIFtmdW5jdGlvbk5vZGUsIGFyZ3VtZW50UGFydF0pXG4gICAgY29uc3QgYXJndW1lbnRzXyA9IHRoaXMuYXJndW1lbnRzKGFyZ3VtZW50UGFydClcblxuICAgIGlmIChhcmd1bWVudHNfLmxlbmd0aCAhPSAxIHx8IGFyZ3VtZW50c19bMF0ubGVuZ3RoICE9IDEgfHwgYXJndW1lbnRzX1swXVswXS50eXBlICE9IFwiaWRlbnRpZmllclwiIHx8XG4gICAgICB0aGlzLmlkZW50aWZpZXIoYXJndW1lbnRzX1swXVswXSkgIT0gcHJldmlvdXMubmFtZSkgdGhpcy5mYWlsKGFyZ3VtZW50UGFydCwgXCJEYXJ0IGFuYWx5emVyIGxvY2FsLXVzZSBzdXBwb3J0IHNoYXBlXCIpXG4gICAgcmV0dXJuIHRydWVcbiAgfVxuXG4gIC8qKlxuICAgKiBDb252ZXJ0cyBhIGJyYWNlZCBEYXJ0IGJsb2NrLlxuICAgKiBAcGFyYW0ge2ltcG9ydChcInRyZWUtc2l0dGVyXCIpLlN5bnRheE5vZGV9IG5vZGUgQnJhY2VkIGJsb2NrLlxuICAgKiBAcmV0dXJucyB7aW1wb3J0KFwiLi4vc2VtYW50aWMvdHlwZXMuanNcIikuQmxvY2t9IFNlbWFudGljIGJsb2NrLlxuICAgKi9cbiAgYmxvY2sobm9kZSkge1xuICAgIGNvbnN0IHBhcnRzID0gdGhpcy5wYXJ0cyhub2RlKVxuXG4gICAgaWYgKG5vZGUudHlwZSAhPSBcImJsb2NrXCIgfHwgcGFydHMubGVuZ3RoIDwgMiB8fCBwYXJ0c1swXS50ZXh0ICE9IFwie1wiIHx8IHBhcnRzLmF0KC0xKT8udGV4dCAhPSBcIn1cIikge1xuICAgICAgdGhpcy5mYWlsKG5vZGUsIFwiYnJhY2VkIGJsb2NrIHNoYXBlXCIpXG4gICAgfVxuICAgIHRoaXMuc2hhcGUobm9kZSwgW1wie1wiLCAuLi5wYXJ0cy5zbGljZSgxLCAtMSksIFwifVwiXSlcbiAgICAvKiogQHR5cGUge2ltcG9ydChcIi4uL3NlbWFudGljL3R5cGVzLmpzXCIpLlN0YXRlbWVudFtdfSAqL1xuICAgIGNvbnN0IHN0YXRlbWVudHMgPSBbXVxuXG4gICAgZm9yIChjb25zdCBzdGF0ZW1lbnQgb2YgcGFydHMuc2xpY2UoMSwgLTEpKSB7XG4gICAgICBpZiAoIXRoaXMuZ2VuZXJhdGVkTG9jYWxVc2Uoc3RhdGVtZW50LCBzdGF0ZW1lbnRzLmF0KC0xKSkpIHN0YXRlbWVudHMucHVzaCh0aGlzLnN0YXRlbWVudChzdGF0ZW1lbnQpKVxuICAgIH1cbiAgICByZXR1cm4ge1xuICAgICAga2luZDogLyoqIEB0eXBlIHtjb25zdH0gKi8gKFwiQmxvY2tcIiksXG4gICAgICBsb2NhdGlvbjogdGhpcy5sb2NhdGlvbihub2RlKSxcbiAgICAgIHN0YXRlbWVudHNcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogVW53cmFwcyBhIHN5bmNocm9ub3VzIGJyYWNlZCBmdW5jdGlvbiBib2R5LlxuICAgKiBAcGFyYW0ge2ltcG9ydChcInRyZWUtc2l0dGVyXCIpLlN5bnRheE5vZGV9IGJvZHkgRnVuY3Rpb24gYm9keSB3cmFwcGVyLlxuICAgKiBAcmV0dXJucyB7aW1wb3J0KFwiLi4vc2VtYW50aWMvdHlwZXMuanNcIikuQmxvY2t9IFNlbWFudGljIGJvZHkuXG4gICAqL1xuICBmdW5jdGlvbkJvZHkoYm9keSkge1xuICAgIGNvbnN0IHBhcnRzID0gdGhpcy5wYXJ0cyhib2R5KVxuXG4gICAgaWYgKGJvZHkudHlwZSAhPSBcImZ1bmN0aW9uX2JvZHlcIiB8fCBwYXJ0cy5sZW5ndGggIT0gMSB8fCBwYXJ0c1swXS50eXBlICE9IFwiYmxvY2tcIikge1xuICAgICAgdGhpcy5mYWlsKGJvZHksIFwic3luY2hyb25vdXMgYnJhY2VkIGZ1bmN0aW9uIGJvZHkgcmVxdWlyZWRcIilcbiAgICB9XG4gICAgdGhpcy5zaGFwZShib2R5LCBbcGFydHNbMF1dKVxuICAgIHJldHVybiB0aGlzLmJsb2NrKHBhcnRzWzBdKVxuICB9XG5cbiAgLyoqXG4gICAqIENvbnZlcnRzIG9uZSBzdHJpY3QtQm9vbGVhbiBjb25kaXRpb25hbC5cbiAgICogQHBhcmFtIHtpbXBvcnQoXCJ0cmVlLXNpdHRlclwiKS5TeW50YXhOb2RlfSBub2RlIFN0cmljdCBCb29sZWFuIGNvbmRpdGlvbmFsLlxuICAgKiBAcmV0dXJucyB7aW1wb3J0KFwiLi4vc2VtYW50aWMvdHlwZXMuanNcIikuSWZTdGF0ZW1lbnR9IFNlbWFudGljIGNvbmRpdGlvbmFsLlxuICAgKi9cbiAgY29uZGl0aW9uYWwobm9kZSkge1xuICAgIGNvbnN0IHBhcnRzID0gdGhpcy5wYXJ0cyhub2RlKVxuICAgIGNvbnN0IGNvbnNlcXVlbmNlID0gdGhpcy5maWVsZChub2RlLCBcImNvbnNlcXVlbmNlXCIpXG4gICAgY29uc3QgY29uc2VxdWVuY2VJbmRleCA9IHBhcnRzLmZpbmRJbmRleCgoe2lkfSkgPT4gaWQgPT0gY29uc2VxdWVuY2UuaWQpXG5cbiAgICBpZiAobm9kZS50eXBlICE9IFwiaWZfc3RhdGVtZW50XCIgfHwgcGFydHNbMF0/LnRleHQgIT0gXCJpZlwiIHx8IHBhcnRzWzFdPy50ZXh0ICE9IFwiKFwiIHx8IGNvbnNlcXVlbmNlLnR5cGUgIT0gXCJibG9ja1wiIHx8XG4gICAgICBjb25zZXF1ZW5jZUluZGV4IDwgNCB8fCBwYXJ0c1tjb25zZXF1ZW5jZUluZGV4IC0gMV0/LnRleHQgIT0gXCIpXCIpIHRoaXMuZmFpbChub2RlLCBcImlmIHN0YXRlbWVudCBzaGFwZVwiKVxuICAgIGNvbnN0IGNvbmRpdGlvblBhcnRzID0gcGFydHMuc2xpY2UoMiwgY29uc2VxdWVuY2VJbmRleCAtIDEpXG5cbiAgICBpZiAoY29uZGl0aW9uUGFydHMubGVuZ3RoID09IDApIHRoaXMuZmFpbChub2RlLCBcImVtcHR5IGlmIGNvbmRpdGlvblwiKVxuICAgIGNvbnN0IHN0YXRlbWVudCA9IC8qKiBAdHlwZSB7aW1wb3J0KFwiLi4vc2VtYW50aWMvdHlwZXMuanNcIikuSWZTdGF0ZW1lbnR9ICovICh7XG4gICAgICBjb25kaXRpb246IHRoaXMuZXhwcmVzc2lvbihjb25kaXRpb25QYXJ0cywgbm9kZSksXG4gICAgICBjb25zZXF1ZW50OiB0aGlzLmJsb2NrKGNvbnNlcXVlbmNlKSxcbiAgICAgIGtpbmQ6IC8qKiBAdHlwZSB7Y29uc3R9ICovIChcIklmU3RhdGVtZW50XCIpLFxuICAgICAgbG9jYXRpb246IHRoaXMubG9jYXRpb24obm9kZSlcbiAgICB9KVxuICAgIGlmIChwYXJ0cy5sZW5ndGggPT0gY29uc2VxdWVuY2VJbmRleCArIDEpIHtcbiAgICAgIHRoaXMuc2hhcGUobm9kZSwgW1wiaWZcIiwgXCIoXCIsIC4uLmNvbmRpdGlvblBhcnRzLCBcIilcIiwgY29uc2VxdWVuY2VdKVxuICAgICAgcmV0dXJuIHN0YXRlbWVudFxuICAgIH1cbiAgICBjb25zdCBhbHRlcm5hdGl2ZSA9IHRoaXMuZmllbGQobm9kZSwgXCJhbHRlcm5hdGl2ZVwiKVxuXG4gICAgaWYgKHBhcnRzLmxlbmd0aCAhPSBjb25zZXF1ZW5jZUluZGV4ICsgMyB8fCBwYXJ0c1tjb25zZXF1ZW5jZUluZGV4ICsgMV0/LnRleHQgIT0gXCJlbHNlXCIgfHxcbiAgICAgIHBhcnRzW2NvbnNlcXVlbmNlSW5kZXggKyAyXT8uaWQgIT0gYWx0ZXJuYXRpdmUuaWQpIHRoaXMuZmFpbChhbHRlcm5hdGl2ZSwgXCJpZiBhbHRlcm5hdGUgc2hhcGVcIilcbiAgICB0aGlzLnNoYXBlKG5vZGUsIFtcImlmXCIsIFwiKFwiLCAuLi5jb25kaXRpb25QYXJ0cywgXCIpXCIsIGNvbnNlcXVlbmNlLCBcImVsc2VcIiwgYWx0ZXJuYXRpdmVdKVxuICAgIGlmIChhbHRlcm5hdGl2ZS50eXBlID09IFwiYmxvY2tcIikgcmV0dXJuIHsuLi5zdGF0ZW1lbnQsIGFsdGVybmF0ZTogdGhpcy5ibG9jayhhbHRlcm5hdGl2ZSl9XG4gICAgaWYgKGFsdGVybmF0aXZlLnR5cGUgPT0gXCJpZl9zdGF0ZW1lbnRcIikge1xuICAgICAgcmV0dXJuIHsuLi5zdGF0ZW1lbnQsIGFsdGVybmF0ZToge1xuICAgICAgICBraW5kOiAvKiogQHR5cGUge2NvbnN0fSAqLyAoXCJCbG9ja1wiKSwgbG9jYXRpb246IHRoaXMubG9jYXRpb24oYWx0ZXJuYXRpdmUpLCBzdGF0ZW1lbnRzOiBbdGhpcy5jb25kaXRpb25hbChhbHRlcm5hdGl2ZSldXG4gICAgICB9fVxuICAgIH1cbiAgICByZXR1cm4gdGhpcy5mYWlsKGFsdGVybmF0aXZlLCBcImJyYWNlZCBibG9jayBvciBlbHNlLWlmIHJlcXVpcmVkXCIpXG4gIH1cblxuICAvKipcbiAgICogQ29udmVydHMgb25lIHJlcXVpcmVkIGV4cGxpY2l0bHkgdHlwZWQgcG9zaXRpb25hbCBwYXJhbWV0ZXIuXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwidHJlZS1zaXR0ZXJcIikuU3ludGF4Tm9kZX0gbm9kZSBSZXF1aXJlZCBwb3NpdGlvbmFsIHBhcmFtZXRlci5cbiAgICogQHJldHVybnMge2ltcG9ydChcIi4uL3NlbWFudGljL3R5cGVzLmpzXCIpLlBhcmFtZXRlcn0gU2VtYW50aWMgcGFyYW1ldGVyLlxuICAgKi9cbiAgcGFyYW1ldGVyKG5vZGUpIHtcbiAgICBjb25zdCBwYXJ0cyA9IHRoaXMucGFydHMobm9kZSlcblxuICAgIGlmIChwYXJ0cy5sZW5ndGggPT0gMSAmJiBwYXJ0c1swXS50eXBlID09IFwiaWRlbnRpZmllclwiKSByZXR1cm4gbWlzc2luZ1R5cGUoXCJkYXJ0XCIsIFwiUGFyYW1ldGVyXCIsIHRoaXMubG9jYXRpb24obm9kZSkpXG4gICAgaWYgKG5vZGUudHlwZSAhPSBcImZvcm1hbF9wYXJhbWV0ZXJcIiB8fCBwYXJ0cy5sZW5ndGggIT0gMiB8fCBwYXJ0c1swXS50eXBlICE9IFwidHlwZV9pZGVudGlmaWVyXCIgfHxcbiAgICAgIHBhcnRzWzFdLnR5cGUgIT0gXCJpZGVudGlmaWVyXCIpIHRoaXMuZmFpbChub2RlLCBcInJlcXVpcmVkIGV4cGxpY2l0bHkgdHlwZWQgcG9zaXRpb25hbCBwYXJhbWV0ZXJcIilcbiAgICB0aGlzLnNoYXBlKG5vZGUsIFtwYXJ0c1swXSwgcGFydHNbMV1dKVxuICAgIGlmICh0aGlzLmZpZWxkKG5vZGUsIFwibmFtZVwiKS5pZCAhPSBwYXJ0c1sxXS5pZCkgdGhpcy5mYWlsKHBhcnRzWzFdLCBcInBhcmFtZXRlciBuYW1lIGZpZWxkXCIpXG4gICAgY29uc3QgbmFtZSA9IHRoaXMuaWRlbnRpZmllcihwYXJ0c1sxXSlcblxuICAgIHJldHVybiB3aXRoUGFyc2VyUmFuZ2VzKHtcbiAgICAgIGtpbmQ6IC8qKiBAdHlwZSB7Y29uc3R9ICovIChcIlBhcmFtZXRlclwiKSwgbG9jYXRpb246IHRoaXMubG9jYXRpb24obm9kZSksIG5hbWUsIHR5cGU6IHRoaXMuc2NhbGFyVHlwZShwYXJ0c1swXSlcbiAgICB9LCB7bmFtZTogdGhpcy5sb2NhdGlvbihwYXJ0c1sxXSl9KVxuICB9XG5cbiAgLyoqXG4gICAqIENvbnZlcnRzIGEgcmVxdWlyZWQgcG9zaXRpb25hbCBwYXJhbWV0ZXIgbGlzdC5cbiAgICogQHBhcmFtIHtpbXBvcnQoXCJ0cmVlLXNpdHRlclwiKS5TeW50YXhOb2RlfSBub2RlIFBhcmFtZXRlciBsaXN0LlxuICAgKiBAcmV0dXJucyB7aW1wb3J0KFwiLi4vc2VtYW50aWMvdHlwZXMuanNcIikuUGFyYW1ldGVyW119IFNlbWFudGljIHBhcmFtZXRlcnMuXG4gICAqL1xuICBwYXJhbWV0ZXJzKG5vZGUpIHtcbiAgICBjb25zdCBwYXJ0cyA9IHRoaXMucGFydHMobm9kZSlcblxuICAgIGlmIChub2RlLnR5cGUgIT0gXCJmb3JtYWxfcGFyYW1ldGVyX2xpc3RcIiB8fCBwYXJ0cy5sZW5ndGggPCAyIHx8IHBhcnRzWzBdLnRleHQgIT0gXCIoXCIgfHwgcGFydHMuYXQoLTEpPy50ZXh0ICE9IFwiKVwiKSB7XG4gICAgICB0aGlzLmZhaWwobm9kZSwgXCJmb3JtYWwgcGFyYW1ldGVyIGxpc3Qgc2hhcGVcIilcbiAgICB9XG4gICAgY29uc3QgaW50ZXJpb3IgPSBwYXJ0cy5zbGljZSgxLCAtMSlcbiAgICBjb25zdCBoYXNHZW5lcmF0ZWRUcmFpbGluZ0NvbW1hID0gdGhpcy5ydW50aW1lICYmIGludGVyaW9yLmF0KC0xKT8udGV4dCA9PSBcIixcIlxuICAgIGNvbnN0IHBhcmFtZXRlclBhcnRzID0gaGFzR2VuZXJhdGVkVHJhaWxpbmdDb21tYSA/IGludGVyaW9yLnNsaWNlKDAsIC0xKSA6IGludGVyaW9yXG4gICAgY29uc3QgcGFyYW1ldGVycyA9IHBhcmFtZXRlclBhcnRzLmZpbHRlcigoX2NoaWxkLCBpbmRleCkgPT4gaW5kZXggJSAyID09IDApXG5cbiAgICB0aGlzLnNoYXBlKG5vZGUsIFtcIihcIiwgLi4ucGFyYW1ldGVycy5mbGF0TWFwKChwYXJhbWV0ZXIsIGluZGV4KSA9PiBpbmRleCA/IFtcIixcIiwgcGFyYW1ldGVyXSA6IFtwYXJhbWV0ZXJdKSxcbiAgICAgIC4uLihoYXNHZW5lcmF0ZWRUcmFpbGluZ0NvbW1hID8gW1wiLFwiXSA6IFtdKSwgXCIpXCJdKVxuICAgIHJldHVybiBwYXJhbWV0ZXJzLm1hcCgocGFyYW1ldGVyKSA9PiB0aGlzLnBhcmFtZXRlcihwYXJhbWV0ZXIpKVxuICB9XG5cbiAgLyoqXG4gICAqIENvbnZlcnRzIG9uZSBvcmRpbmFyeSB0b3AtbGV2ZWwgZnVuY3Rpb24gZGVjbGFyYXRpb24uXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwidHJlZS1zaXR0ZXJcIikuU3ludGF4Tm9kZX0gc2lnbmF0dXJlIEZ1bmN0aW9uIHNpZ25hdHVyZS5cbiAgICogQHBhcmFtIHtpbXBvcnQoXCJ0cmVlLXNpdHRlclwiKS5TeW50YXhOb2RlfSBib2R5IEZ1bmN0aW9uIGJvZHkuXG4gICAqIEByZXR1cm5zIHtpbXBvcnQoXCIuLi9zZW1hbnRpYy90eXBlcy5qc1wiKS5GdW5jdGlvbkRlY2xhcmF0aW9ufSBTZW1hbnRpYyBmdW5jdGlvbi5cbiAgICovXG4gIGZ1bmN0aW9uKHNpZ25hdHVyZSwgYm9keSkge1xuICAgIGNvbnN0IHBhcnRzID0gdGhpcy5wYXJ0cyhzaWduYXR1cmUpXG5cbiAgICBpZiAoc2lnbmF0dXJlLnR5cGUgIT0gXCJmdW5jdGlvbl9zaWduYXR1cmVcIikgdGhpcy5mYWlsKHNpZ25hdHVyZSwgXCJmdW5jdGlvbiBzaWduYXR1cmVcIilcbiAgICBpZiAocGFydHMubGVuZ3RoID09IDIgJiYgcGFydHNbMF0udHlwZSA9PSBcImlkZW50aWZpZXJcIikgcmV0dXJuIG1pc3NpbmdUeXBlKFwiZGFydFwiLCBcIkZ1bmN0aW9uIHJldHVyblwiLCB0aGlzLmxvY2F0aW9uKHNpZ25hdHVyZSkpXG4gICAgaWYgKHBhcnRzLmxlbmd0aCAhPSAzIHx8ICFbXCJ0eXBlX2lkZW50aWZpZXJcIiwgXCJ2b2lkX3R5cGVcIl0uaW5jbHVkZXMocGFydHNbMF0udHlwZSkgfHwgcGFydHNbMV0udHlwZSAhPSBcImlkZW50aWZpZXJcIiB8fFxuICAgICAgcGFydHNbMl0udHlwZSAhPSBcImZvcm1hbF9wYXJhbWV0ZXJfbGlzdFwiKSB0aGlzLmZhaWwoc2lnbmF0dXJlLCBcImV4cGxpY2l0IHRvcC1sZXZlbCBmdW5jdGlvbiBzaWduYXR1cmVcIilcbiAgICB0aGlzLnNoYXBlKHNpZ25hdHVyZSwgW3BhcnRzWzBdLCBwYXJ0c1sxXSwgcGFydHNbMl1dKVxuICAgIGlmICh0aGlzLmZpZWxkKHNpZ25hdHVyZSwgXCJuYW1lXCIpLmlkICE9IHBhcnRzWzFdLmlkKSB0aGlzLmZhaWwocGFydHNbMV0sIFwiZnVuY3Rpb24gbmFtZSBmaWVsZFwiKVxuICAgIGNvbnN0IG5hbWUgPSB0aGlzLmlkZW50aWZpZXIocGFydHNbMV0pXG4gICAgY29uc3QgbG9jYXRpb24gPSBsb2NhdGlvbkZyb21PZmZzZXRzKHRoaXMuZmlsZW5hbWUsIHRoaXMuc291cmNlLCBiaW5kaW5nSW5kZXhUb1V0ZjE2T2Zmc2V0KHRoaXMuc291cmNlLCBzaWduYXR1cmUuc3RhcnRJbmRleCksXG4gICAgICBiaW5kaW5nSW5kZXhUb1V0ZjE2T2Zmc2V0KHRoaXMuc291cmNlLCBib2R5LmVuZEluZGV4KSlcblxuICAgIHJldHVybiB3aXRoUGFyc2VyUmFuZ2VzKHtcbiAgICAgIGJvZHk6IHRoaXMuZnVuY3Rpb25Cb2R5KGJvZHkpLFxuICAgICAga2luZDogLyoqIEB0eXBlIHtjb25zdH0gKi8gKFwiRnVuY3Rpb25EZWNsYXJhdGlvblwiKSxcbiAgICAgIGxvY2F0aW9uLFxuICAgICAgbmFtZSxcbiAgICAgIHBhcmFtZXRlcnM6IHRoaXMucGFyYW1ldGVycyhwYXJ0c1syXSksXG4gICAgICByZXR1cm5UeXBlOiB0aGlzLnJldHVyblR5cGUocGFydHNbMF0pXG4gICAgfSwge25hbWU6IHRoaXMubG9jYXRpb24ocGFydHNbMV0pfSlcbiAgfVxuXG4gIC8qKlxuICAgKiBDb252ZXJ0cyB0aGUgZXhhY3Qgdm9pZCBtYWluIGVudHJ5IHNoZWxsLlxuICAgKiBAcGFyYW0ge2ltcG9ydChcInRyZWUtc2l0dGVyXCIpLlN5bnRheE5vZGV9IHNpZ25hdHVyZSBNYWluIHNpZ25hdHVyZS5cbiAgICogQHBhcmFtIHtpbXBvcnQoXCJ0cmVlLXNpdHRlclwiKS5TeW50YXhOb2RlfSBib2R5IE1haW4gYm9keS5cbiAgICogQHJldHVybnMge2ltcG9ydChcIi4uL3NlbWFudGljL3R5cGVzLmpzXCIpLkVudHJ5UG9pbnR9IFNlbWFudGljIGVudHJ5IHBvaW50LlxuICAgKi9cbiAgbWFpbihzaWduYXR1cmUsIGJvZHkpIHtcbiAgICBjb25zdCBwYXJ0cyA9IHRoaXMucGFydHMoc2lnbmF0dXJlKVxuXG4gICAgaWYgKHNpZ25hdHVyZS50eXBlICE9IFwiZnVuY3Rpb25fc2lnbmF0dXJlXCIgfHwgcGFydHMubGVuZ3RoICE9IDMgfHwgcGFydHNbMF0udHlwZSAhPSBcInZvaWRfdHlwZVwiIHx8XG4gICAgICB0aGlzLmlkZW50aWZpZXIocGFydHNbMV0sIHRydWUpICE9IFwibWFpblwiIHx8IHBhcnRzWzJdLnR5cGUgIT0gXCJmb3JtYWxfcGFyYW1ldGVyX2xpc3RcIikge1xuICAgICAgdGhpcy5mYWlsKHNpZ25hdHVyZSwgXCJleGFjdCB2b2lkIG1haW4oKSBzaWduYXR1cmUgcmVxdWlyZWRcIilcbiAgICB9XG4gICAgdGhpcy5zaGFwZShzaWduYXR1cmUsIFtwYXJ0c1swXSwgcGFydHNbMV0sIHBhcnRzWzJdXSlcbiAgICB0aGlzLnNoYXBlKHBhcnRzWzJdLCBbXCIoXCIsIFwiKVwiXSlcbiAgICBjb25zdCBsb2NhdGlvbiA9IGxvY2F0aW9uRnJvbU9mZnNldHModGhpcy5maWxlbmFtZSwgdGhpcy5zb3VyY2UsIGJpbmRpbmdJbmRleFRvVXRmMTZPZmZzZXQodGhpcy5zb3VyY2UsIHNpZ25hdHVyZS5zdGFydEluZGV4KSxcbiAgICAgIGJpbmRpbmdJbmRleFRvVXRmMTZPZmZzZXQodGhpcy5zb3VyY2UsIGJvZHkuZW5kSW5kZXgpKVxuXG4gICAgcmV0dXJuIHtib2R5OiB0aGlzLmZ1bmN0aW9uQm9keShib2R5KSwga2luZDogLyoqIEB0eXBlIHtjb25zdH0gKi8gKFwiRW50cnlQb2ludFwiKSwgbG9jYXRpb259XG4gIH1cblxuICAvKipcbiAgICogQ29udmVydHMgb25lIGNvbXBsZXRlIERhcnQgY29tcGlsYXRpb24gdW5pdC5cbiAgICogQHBhcmFtIHtpbXBvcnQoXCJ0cmVlLXNpdHRlclwiKS5TeW50YXhOb2RlfSByb290IENvbXBsZXRlIERhcnQgcHJvZ3JhbS5cbiAgICogQHJldHVybnMge2ltcG9ydChcIi4uL3NlbWFudGljL3R5cGVzLmpzXCIpLlNlbWFudGljTW9kdWxlfSBTZW1hbnRpYyBtb2R1bGUuXG4gICAqL1xuICBtb2R1bGUocm9vdCkge1xuICAgIHRoaXMudmFsaWRhdGVUcmVlKHJvb3QpXG4gICAgaWYgKHJvb3QudHlwZSAhPSBcInByb2dyYW1cIikgdGhpcy5mYWlsKHJvb3QsIFwicHJvZ3JhbSByb290XCIpXG4gICAgY29uc3QgcGFydHMgPSB0aGlzLnBhcnRzKHJvb3QpXG4gICAgY29uc3Qgc3VwcG9ydFRyZWUgPSBwYXJzZXIucGFyc2UoZGFydFJ1bnRpbWUpXG4gICAgY29uc3Qgc3VwcG9ydCA9IHRoaXMucGFydHMoc3VwcG9ydFRyZWUucm9vdE5vZGUpXG4gICAgbGV0IHN1cHBvcnRJbmRleCA9IDBcblxuICAgIHdoaWxlIChzdXBwb3J0SW5kZXggPCBwYXJ0cy5sZW5ndGggJiYgc3VwcG9ydEluZGV4IDwgc3VwcG9ydC5sZW5ndGggJiZcbiAgICAgIHBhcnRzW3N1cHBvcnRJbmRleF0udHlwZSA9PSBzdXBwb3J0W3N1cHBvcnRJbmRleF0udHlwZSkge1xuICAgICAgdGhpcy5jb21wYXJlVHJlZShwYXJ0c1tzdXBwb3J0SW5kZXhdLCBzdXBwb3J0W3N1cHBvcnRJbmRleF0pXG4gICAgICBzdXBwb3J0SW5kZXggKz0gMVxuICAgIH1cbiAgICBpZiAoc3VwcG9ydEluZGV4ID4gMCAmJiBzdXBwb3J0SW5kZXggIT0gc3VwcG9ydC5sZW5ndGgpIHtcbiAgICAgIHRoaXMuZmFpbChwYXJ0c1tzdXBwb3J0SW5kZXggLSAxXSwgXCJjb21wbGV0ZSBEYXJ0IHN1cHBvcnQgcmVxdWlyZWRcIilcbiAgICB9XG4gICAgdGhpcy5ydW50aW1lID0gc3VwcG9ydEluZGV4ID09IHN1cHBvcnQubGVuZ3RoXG4gICAgY29uc3Qgc2VtYW50aWNQYXJ0cyA9IHBhcnRzLnNsaWNlKHN1cHBvcnRJbmRleClcblxuICAgIGlmIChzZW1hbnRpY1BhcnRzLmxlbmd0aCA9PSAwKSB0aGlzLmZhaWwocm9vdCwgXCJwcm9ncmFtIHdpdGhvdXQgbWFpblwiKVxuICAgIC8qKiBAdHlwZSB7e2JvZHk6IGltcG9ydChcInRyZWUtc2l0dGVyXCIpLlN5bnRheE5vZGUsIHNpZ25hdHVyZTogaW1wb3J0KFwidHJlZS1zaXR0ZXJcIikuU3ludGF4Tm9kZX1bXX0gKi9cbiAgICBjb25zdCBkZWNsYXJhdGlvbnMgPSBbXVxuXG4gICAgZm9yIChjb25zdCBkZWNsYXJhdGlvbiBvZiBzZW1hbnRpY1BhcnRzKSB7XG4gICAgICBpZiAoZGVjbGFyYXRpb24udHlwZSAhPSBcImZ1bmN0aW9uX2RlY2xhcmF0aW9uXCIpIHRoaXMuZmFpbChkZWNsYXJhdGlvbiwgXCJ0b3AtbGV2ZWwgZnVuY3Rpb24gZGVjbGFyYXRpb24gcmVxdWlyZWRcIilcbiAgICAgIGNvbnN0IHNpZ25hdHVyZSA9IHRoaXMuZmllbGQoZGVjbGFyYXRpb24sIFwic2lnbmF0dXJlXCIpXG4gICAgICBjb25zdCBib2R5ID0gdGhpcy5maWVsZChkZWNsYXJhdGlvbiwgXCJib2R5XCIpXG4gICAgICBjb25zdCBkZWNsYXJhdGlvblBhcnRzID0gdGhpcy5wYXJ0cyhkZWNsYXJhdGlvbilcblxuICAgICAgaWYgKGRlY2xhcmF0aW9uUGFydHMubGVuZ3RoICE9IDIgfHwgZGVjbGFyYXRpb25QYXJ0c1swXS5pZCAhPSBzaWduYXR1cmUuaWQgfHwgc2lnbmF0dXJlLnR5cGUgIT0gXCJmdW5jdGlvbl9zaWduYXR1cmVcIiB8fFxuICAgICAgICBkZWNsYXJhdGlvblBhcnRzWzFdLmlkICE9IGJvZHkuaWQgfHwgYm9keS50eXBlICE9IFwiZnVuY3Rpb25fYm9keVwiKSB7XG4gICAgICAgIHRoaXMuZmFpbChkZWNsYXJhdGlvbiwgXCJwYWlyZWQgdG9wLWxldmVsIGZ1bmN0aW9uIHNpZ25hdHVyZSBhbmQgYm9keSByZXF1aXJlZFwiKVxuICAgICAgfVxuICAgICAgdGhpcy5zaGFwZShkZWNsYXJhdGlvbiwgW3NpZ25hdHVyZSwgYm9keV0pXG4gICAgICBkZWNsYXJhdGlvbnMucHVzaCh7Ym9keSwgc2lnbmF0dXJlfSlcbiAgICB9XG4gICAgY29uc3QgbWFpbkluZGV4ZXMgPSBkZWNsYXJhdGlvbnMuZmxhdE1hcCgoe3NpZ25hdHVyZX0sIGluZGV4KSA9PiB0aGlzLnBhcnRzKHNpZ25hdHVyZSlbMV0/LnRleHQgPT0gXCJtYWluXCIgPyBbaW5kZXhdIDogW10pXG5cbiAgICBpZiAobWFpbkluZGV4ZXMubGVuZ3RoICE9IDEpIHRoaXMuZmFpbChyb290LCBcImV4YWN0bHkgb25lIG1haW4gZGVjbGFyYXRpb24gcmVxdWlyZWRcIilcbiAgICBjb25zdCBtYWluSW5kZXggPSBtYWluSW5kZXhlc1swXVxuXG4gICAgdGhpcy5mdW5jdGlvbk5hbWVzID0gbmV3IFNldChkZWNsYXJhdGlvbnMubWFwKCh7c2lnbmF0dXJlfSkgPT4gdGhpcy5wYXJ0cyhzaWduYXR1cmUpWzFdPy50ZXh0KS5maWx0ZXIoQm9vbGVhbikpXG5cbiAgICBpZiAobWFpbkluZGV4ICE9IGRlY2xhcmF0aW9ucy5sZW5ndGggLSAxKSB0aGlzLmZhaWwoZGVjbGFyYXRpb25zW21haW5JbmRleCArIDFdLnNpZ25hdHVyZSwgXCJkZWNsYXJhdGlvbiBhZnRlciBtYWluXCIpXG4gICAgY29uc3QgbWFpbiA9IGRlY2xhcmF0aW9uc1ttYWluSW5kZXhdXG4gICAgY29uc3QgbW9kdWxlID0ge1xuICAgICAgZW50cnlQb2ludDogdGhpcy5tYWluKG1haW4uc2lnbmF0dXJlLCBtYWluLmJvZHkpLFxuICAgICAgZnVuY3Rpb25zOiBkZWNsYXJhdGlvbnMuc2xpY2UoMCwgbWFpbkluZGV4KS5tYXAoKHtib2R5LCBzaWduYXR1cmV9KSA9PiB0aGlzLmZ1bmN0aW9uKHNpZ25hdHVyZSwgYm9keSkpLFxuICAgICAga2luZDogLyoqIEB0eXBlIHtjb25zdH0gKi8gKFwiTW9kdWxlXCIpLFxuICAgICAgbG9jYXRpb246IHRoaXMubG9jYXRpb24ocm9vdClcbiAgICB9XG5cbiAgICB2YWxpZGF0ZVBhcnNlZE1vZHVsZShtb2R1bGUsIFwiZGFydFwiKVxuICAgIHJldHVybiBtb2R1bGVcbiAgfVxufVxuXG4vKipcbiAqIFBhcnNlcyB0aGUgc3RyaWN0IFRhc2sgMDI5IERhcnQgVk0vbmF0aXZlIHByb2ZpbGUgdGhyb3VnaCB0aGUgcXVhbGlmaWVkIGdyYW1tYXIuXG4gKiBAcGFyYW0ge3tmaWxlbmFtZTogc3RyaW5nLCBzb3VyY2U6IHN0cmluZ319IGlucHV0IEV4YWN0IHNvdXJjZSByZXF1ZXN0LlxuICogQHJldHVybnMge2ltcG9ydChcIi4uL3NlbWFudGljL3R5cGVzLmpzXCIpLlNlbWFudGljTW9kdWxlfSBTZW1hbnRpYyBtb2R1bGUuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBwYXJzZURhcnQoe2ZpbGVuYW1lLCBzb3VyY2V9KSB7XG4gIGlmICghaGFzT25seVVuaWNvZGVTY2FsYXJzKHNvdXJjZSkpIHtcbiAgICBjb25zdCBvZmZzZXQgPSBmaXJzdExvbmVTdXJyb2dhdGVPZmZzZXQoc291cmNlKVxuXG4gICAgdGhyb3cgbmV3IFNlbWFudGlmb2xkRGlhZ25vc3RpYyh7XG4gICAgICBjb2RlOiBcIlBBUlNFX0VSUk9SXCIsIGxhbmd1YWdlOiBcImRhcnRcIiwgbG9jYXRpb246IGxvY2F0aW9uRnJvbU9mZnNldHMoZmlsZW5hbWUsIHNvdXJjZSwgb2Zmc2V0LCBvZmZzZXQgKyAxKSxcbiAgICAgIG1lc3NhZ2U6IFwiRGFydCBzb3VyY2UgY29udGFpbnMgYW4gaW52YWxpZCBsb25lIFVURi0xNiBzdXJyb2dhdGUuXCJcbiAgICB9KVxuICB9XG4gIGxldCB0cmVlXG5cbiAgdHJ5IHtcbiAgICB0cmVlID0gcGFyc2VyLnBhcnNlKHNvdXJjZSlcbiAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICB0aHJvdyBuZXcgU2VtYW50aWZvbGREaWFnbm9zdGljKHtcbiAgICAgIGNhdXNlOiBlcnJvciBpbnN0YW5jZW9mIEVycm9yID8gZXJyb3IgOiB1bmRlZmluZWQsXG4gICAgICBjb2RlOiBcIlBBUlNFX0VSUk9SXCIsXG4gICAgICBsYW5ndWFnZTogXCJkYXJ0XCIsXG4gICAgICBsb2NhdGlvbjogbW9kdWxlTG9jYXRpb24oZmlsZW5hbWUsIHNvdXJjZSksXG4gICAgICBtZXNzYWdlOiBcIlRoZSBxdWFsaWZpZWQgRGFydCBwYXJzZXIgY291bGQgbm90IHByb2R1Y2UgYSBjb21wbGV0ZSBDU1QuXCJcbiAgICB9KVxuICB9XG4gIHJldHVybiBuZXcgRGFydFJlYWRlcihmaWxlbmFtZSwgc291cmNlKS5tb2R1bGUodHJlZS5yb290Tm9kZSlcbn1cbiJdfQ==