semantifold 0.3.0 → 0.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (303) hide show
  1. package/README.md +61 -15
  2. package/build/index.d.ts +52 -2
  3. package/build/index.d.ts.map +1 -1
  4. package/build/index.js +60 -8
  5. package/build/src/artifact-path.d.ts +23 -1
  6. package/build/src/artifact-path.d.ts.map +1 -1
  7. package/build/src/artifact-path.js +45 -3
  8. package/build/src/artifacts.d.ts.map +1 -1
  9. package/build/src/artifacts.js +66 -1
  10. package/build/src/backends/android.d.ts +49 -0
  11. package/build/src/backends/android.d.ts.map +1 -0
  12. package/build/src/backends/android.js +1274 -0
  13. package/build/src/backends/c-validation.d.ts.map +1 -1
  14. package/build/src/backends/c-validation.js +7 -3
  15. package/build/src/backends/cpp-validation.d.ts.map +1 -1
  16. package/build/src/backends/cpp-validation.js +7 -3
  17. package/build/src/backends/csharp.js +7 -1
  18. package/build/src/backends/dart-runtime.d.ts +2 -0
  19. package/build/src/backends/dart-runtime.d.ts.map +1 -0
  20. package/build/src/backends/dart-runtime.js +41 -0
  21. package/build/src/backends/dart.d.ts +20 -0
  22. package/build/src/backends/dart.d.ts.map +1 -0
  23. package/build/src/backends/dart.js +321 -0
  24. package/build/src/backends/effects.d.ts +60 -0
  25. package/build/src/backends/effects.d.ts.map +1 -0
  26. package/build/src/backends/effects.js +746 -0
  27. package/build/src/backends/go.js +18 -4
  28. package/build/src/backends/identifiers.d.ts +36 -4
  29. package/build/src/backends/identifiers.d.ts.map +1 -1
  30. package/build/src/backends/identifiers.js +160 -10
  31. package/build/src/backends/index.d.ts.map +1 -1
  32. package/build/src/backends/index.js +27 -4
  33. package/build/src/backends/ios.d.ts +68 -0
  34. package/build/src/backends/ios.d.ts.map +1 -0
  35. package/build/src/backends/ios.js +1503 -0
  36. package/build/src/backends/java.d.ts.map +1 -1
  37. package/build/src/backends/java.js +429 -36
  38. package/build/src/backends/javascript.d.ts +6 -0
  39. package/build/src/backends/javascript.d.ts.map +1 -1
  40. package/build/src/backends/javascript.js +380 -24
  41. package/build/src/backends/kotlin-runtime.d.ts +3 -0
  42. package/build/src/backends/kotlin-runtime.d.ts.map +1 -0
  43. package/build/src/backends/kotlin-runtime.js +29 -0
  44. package/build/src/backends/kotlin.d.ts +33 -0
  45. package/build/src/backends/kotlin.d.ts.map +1 -0
  46. package/build/src/backends/kotlin.js +138 -0
  47. package/build/src/backends/native-validation.d.ts +2 -2
  48. package/build/src/backends/native-validation.d.ts.map +1 -1
  49. package/build/src/backends/native-validation.js +2 -2
  50. package/build/src/backends/ordered-expressions.d.ts.map +1 -1
  51. package/build/src/backends/ordered-expressions.js +39 -7
  52. package/build/src/backends/php-stdlib-support.d.ts +19 -0
  53. package/build/src/backends/php-stdlib-support.d.ts.map +1 -0
  54. package/build/src/backends/php-stdlib-support.js +227 -0
  55. package/build/src/backends/php.d.ts.map +1 -1
  56. package/build/src/backends/php.js +448 -33
  57. package/build/src/backends/program.d.ts +83 -0
  58. package/build/src/backends/program.d.ts.map +1 -0
  59. package/build/src/backends/program.js +1309 -0
  60. package/build/src/backends/python.js +7 -1
  61. package/build/src/backends/ruby.d.ts.map +1 -1
  62. package/build/src/backends/ruby.js +310 -24
  63. package/build/src/backends/rust-runtime.d.ts +7 -0
  64. package/build/src/backends/rust-runtime.d.ts.map +1 -0
  65. package/build/src/backends/rust-runtime.js +32 -0
  66. package/build/src/backends/rust-validation.d.ts +9 -0
  67. package/build/src/backends/rust-validation.d.ts.map +1 -0
  68. package/build/src/backends/rust-validation.js +78 -0
  69. package/build/src/backends/rust.d.ts +24 -0
  70. package/build/src/backends/rust.d.ts.map +1 -0
  71. package/build/src/backends/rust.js +344 -0
  72. package/build/src/backends/scalars.d.ts +14 -6
  73. package/build/src/backends/scalars.d.ts.map +1 -1
  74. package/build/src/backends/scalars.js +167 -17
  75. package/build/src/backends/shared.d.ts +23 -4
  76. package/build/src/backends/shared.d.ts.map +1 -1
  77. package/build/src/backends/shared.js +2174 -62
  78. package/build/src/backends/stdlib-support.d.ts +14 -0
  79. package/build/src/backends/stdlib-support.d.ts.map +1 -0
  80. package/build/src/backends/stdlib-support.js +237 -0
  81. package/build/src/backends/swift-runtime.d.ts +3 -0
  82. package/build/src/backends/swift-runtime.d.ts.map +1 -0
  83. package/build/src/backends/swift-runtime.js +14 -0
  84. package/build/src/backends/swift.d.ts +8 -0
  85. package/build/src/backends/swift.d.ts.map +1 -0
  86. package/build/src/backends/swift.js +127 -0
  87. package/build/src/backends/typescript.d.ts.map +1 -1
  88. package/build/src/backends/typescript.js +344 -24
  89. package/build/src/backends/wasm.d.ts +43 -0
  90. package/build/src/backends/wasm.d.ts.map +1 -0
  91. package/build/src/backends/wasm.js +2164 -0
  92. package/build/src/backends/writer.d.ts +255 -4
  93. package/build/src/backends/writer.d.ts.map +1 -1
  94. package/build/src/backends/writer.js +491 -3
  95. package/build/src/diagnostic.d.ts +4 -3
  96. package/build/src/diagnostic.d.ts.map +1 -1
  97. package/build/src/diagnostic.js +5 -3
  98. package/build/src/frontends/c.d.ts.map +1 -1
  99. package/build/src/frontends/c.js +5 -3
  100. package/build/src/frontends/cpp.d.ts.map +1 -1
  101. package/build/src/frontends/cpp.js +5 -3
  102. package/build/src/frontends/csharp.d.ts.map +1 -1
  103. package/build/src/frontends/csharp.js +7 -3
  104. package/build/src/frontends/dart.d.ts +10 -0
  105. package/build/src/frontends/dart.d.ts.map +1 -0
  106. package/build/src/frontends/dart.js +913 -0
  107. package/build/src/frontends/index.d.ts +3 -1
  108. package/build/src/frontends/index.d.ts.map +1 -1
  109. package/build/src/frontends/index.js +15 -5
  110. package/build/src/frontends/java.d.ts +110 -1
  111. package/build/src/frontends/java.d.ts.map +1 -1
  112. package/build/src/frontends/java.js +1725 -70
  113. package/build/src/frontends/javascript-typescript.d.ts +69 -1
  114. package/build/src/frontends/javascript-typescript.d.ts.map +1 -1
  115. package/build/src/frontends/javascript-typescript.js +1825 -93
  116. package/build/src/frontends/kotlin.d.ts +10 -0
  117. package/build/src/frontends/kotlin.d.ts.map +1 -0
  118. package/build/src/frontends/kotlin.js +685 -0
  119. package/build/src/frontends/php.d.ts +118 -1
  120. package/build/src/frontends/php.d.ts.map +1 -1
  121. package/build/src/frontends/php.js +1583 -76
  122. package/build/src/frontends/program.d.ts +74 -0
  123. package/build/src/frontends/program.d.ts.map +1 -0
  124. package/build/src/frontends/program.js +989 -0
  125. package/build/src/frontends/ruby.d.ts +68 -1
  126. package/build/src/frontends/ruby.d.ts.map +1 -1
  127. package/build/src/frontends/ruby.js +1446 -101
  128. package/build/src/frontends/rust-parser.d.ts +11 -0
  129. package/build/src/frontends/rust-parser.d.ts.map +1 -0
  130. package/build/src/frontends/rust-parser.js +15 -0
  131. package/build/src/frontends/rust.d.ts +14 -0
  132. package/build/src/frontends/rust.d.ts.map +1 -0
  133. package/build/src/frontends/rust.js +715 -0
  134. package/build/src/frontends/scalars.d.ts +10 -0
  135. package/build/src/frontends/scalars.d.ts.map +1 -1
  136. package/build/src/frontends/scalars.js +28 -2
  137. package/build/src/frontends/swift.d.ts +10 -0
  138. package/build/src/frontends/swift.d.ts.map +1 -0
  139. package/build/src/frontends/swift.js +860 -0
  140. package/build/src/frontends/types.d.ts +186 -0
  141. package/build/src/frontends/types.d.ts.map +1 -0
  142. package/build/src/frontends/types.js +634 -0
  143. package/build/src/language-registry.d.ts +46 -4
  144. package/build/src/language-registry.d.ts.map +1 -1
  145. package/build/src/language-registry.js +177 -13
  146. package/build/src/mapping.d.ts +2 -2
  147. package/build/src/mapping.d.ts.map +1 -1
  148. package/build/src/mapping.js +31 -10
  149. package/build/src/semantic/capabilities.d.ts +66 -0
  150. package/build/src/semantic/capabilities.d.ts.map +1 -0
  151. package/build/src/semantic/capabilities.js +649 -0
  152. package/build/src/semantic/effects.d.ts +26 -0
  153. package/build/src/semantic/effects.d.ts.map +1 -0
  154. package/build/src/semantic/effects.js +764 -0
  155. package/build/src/semantic/generics.d.ts +23 -0
  156. package/build/src/semantic/generics.d.ts.map +1 -0
  157. package/build/src/semantic/generics.js +61 -0
  158. package/build/src/semantic/lifetime.d.ts +37 -0
  159. package/build/src/semantic/lifetime.d.ts.map +1 -0
  160. package/build/src/semantic/lifetime.js +527 -0
  161. package/build/src/semantic/provenance.d.ts +9 -2
  162. package/build/src/semantic/provenance.d.ts.map +1 -1
  163. package/build/src/semantic/provenance.js +462 -20
  164. package/build/src/semantic/scalars.d.ts +11 -0
  165. package/build/src/semantic/scalars.d.ts.map +1 -1
  166. package/build/src/semantic/scalars.js +16 -1
  167. package/build/src/semantic/stdlib.d.ts +254 -0
  168. package/build/src/semantic/stdlib.d.ts.map +1 -0
  169. package/build/src/semantic/stdlib.js +880 -0
  170. package/build/src/semantic/types.d.ts +3108 -178
  171. package/build/src/semantic/types.d.ts.map +1 -1
  172. package/build/src/semantic/types.js +730 -15
  173. package/build/src/semantic/validate.d.ts +85 -5
  174. package/build/src/semantic/validate.d.ts.map +1 -1
  175. package/build/src/semantic/validate.js +2576 -98
  176. package/build/src/stdlib-facades.d.ts +304 -0
  177. package/build/src/stdlib-facades.d.ts.map +1 -0
  178. package/build/src/stdlib-facades.js +1167 -0
  179. package/build/src/stdlib-negotiation.d.ts +69 -0
  180. package/build/src/stdlib-negotiation.d.ts.map +1 -0
  181. package/build/src/stdlib-negotiation.js +403 -0
  182. package/build/src/stdlib-providers.d.ts +72 -0
  183. package/build/src/stdlib-providers.d.ts.map +1 -0
  184. package/build/src/stdlib-providers.js +339 -0
  185. package/build/src/toolchains.d.ts +55 -1
  186. package/build/src/toolchains.d.ts.map +1 -1
  187. package/build/src/toolchains.js +15 -4
  188. package/docs/android.md +79 -0
  189. package/docs/architecture.md +47 -13
  190. package/docs/dart.md +60 -0
  191. package/docs/goals.md +3 -3
  192. package/docs/ios.md +121 -0
  193. package/docs/kotlin.md +42 -0
  194. package/docs/language-support.md +238 -26
  195. package/docs/multi-file-modules.md +52 -0
  196. package/docs/parser-qualification.md +121 -8
  197. package/docs/plans/2026-09-05-standard-library-portability.md +10 -10
  198. package/docs/rust.md +88 -0
  199. package/docs/source-maps.md +17 -7
  200. package/docs/specification.md +5 -0
  201. package/docs/standard-library-portability.md +39 -8
  202. package/docs/swift.md +44 -0
  203. package/docs/testing.md +381 -4
  204. package/docs/webassembly.md +52 -0
  205. package/index.js +66 -8
  206. package/node_modules/semantifold-tree-sitter-legacy-internal/README.md +2 -2
  207. package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/LICENSE +21 -0
  208. package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/README.md +45 -0
  209. package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/binding.gyp +30 -0
  210. package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/bindings/node/binding.cc +20 -0
  211. package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/bindings/node/binding_test.js +9 -0
  212. package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/bindings/node/index.d.ts +28 -0
  213. package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/bindings/node/index.js +11 -0
  214. package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/grammar.js +1630 -0
  215. package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/package.json +64 -0
  216. package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/prebuilds/darwin-arm64/tree-sitter-rust.node +0 -0
  217. package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/prebuilds/darwin-x64/tree-sitter-rust.node +0 -0
  218. package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/prebuilds/linux-arm64/tree-sitter-rust.node +0 -0
  219. package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/prebuilds/linux-x64/tree-sitter-rust.node +0 -0
  220. package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/prebuilds/win32-arm64/tree-sitter-rust.node +0 -0
  221. package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/prebuilds/win32-x64/tree-sitter-rust.node +0 -0
  222. package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/queries/highlights.scm +159 -0
  223. package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/queries/injections.scm +9 -0
  224. package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/queries/tags.scm +60 -0
  225. package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/src/grammar.json +9405 -0
  226. package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/src/node-types.json +5399 -0
  227. package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/src/parser.c +192569 -0
  228. package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/src/scanner.c +393 -0
  229. package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/src/tree_sitter/alloc.h +54 -0
  230. package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/src/tree_sitter/array.h +290 -0
  231. package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/src/tree_sitter/parser.h +266 -0
  232. package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/tree-sitter-rust.wasm +0 -0
  233. package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/tree-sitter.json +53 -0
  234. package/node_modules/semantifold-tree-sitter-legacy-internal/package.json +3 -2
  235. package/node_modules/semantifold-tree-sitter-legacy-internal/src/c.js +5 -4
  236. package/package.json +5 -2
  237. package/src/artifact-path.js +47 -2
  238. package/src/artifacts.js +67 -0
  239. package/src/backends/android.js +1370 -0
  240. package/src/backends/c-validation.js +6 -1
  241. package/src/backends/cpp-validation.js +6 -1
  242. package/src/backends/csharp.js +3 -0
  243. package/src/backends/dart-runtime.js +41 -0
  244. package/src/backends/dart.js +326 -0
  245. package/src/backends/effects.js +705 -0
  246. package/src/backends/go.js +14 -2
  247. package/src/backends/identifiers.js +166 -9
  248. package/src/backends/index.js +27 -2
  249. package/src/backends/ios.js +1612 -0
  250. package/src/backends/java.js +454 -36
  251. package/src/backends/javascript.js +389 -23
  252. package/src/backends/kotlin-runtime.js +29 -0
  253. package/src/backends/kotlin.js +144 -0
  254. package/src/backends/native-validation.js +1 -1
  255. package/src/backends/ordered-expressions.js +40 -6
  256. package/src/backends/php-stdlib-support.js +239 -0
  257. package/src/backends/php.js +469 -32
  258. package/src/backends/program.js +1408 -0
  259. package/src/backends/python.js +3 -0
  260. package/src/backends/ruby.js +326 -23
  261. package/src/backends/rust-runtime.js +34 -0
  262. package/src/backends/rust-validation.js +75 -0
  263. package/src/backends/rust.js +335 -0
  264. package/src/backends/scalars.js +141 -16
  265. package/src/backends/shared.js +2314 -115
  266. package/src/backends/stdlib-support.js +234 -0
  267. package/src/backends/swift-runtime.js +14 -0
  268. package/src/backends/swift.js +132 -0
  269. package/src/backends/typescript.js +349 -23
  270. package/src/backends/wasm.js +2208 -0
  271. package/src/backends/writer.js +545 -2
  272. package/src/diagnostic.js +4 -2
  273. package/src/frontends/c.js +4 -2
  274. package/src/frontends/cpp.js +4 -2
  275. package/src/frontends/csharp.js +4 -2
  276. package/src/frontends/dart.js +963 -0
  277. package/src/frontends/index.js +14 -4
  278. package/src/frontends/java.js +1977 -69
  279. package/src/frontends/javascript-typescript.js +2046 -102
  280. package/src/frontends/kotlin.js +713 -0
  281. package/src/frontends/php.js +1725 -79
  282. package/src/frontends/program.js +1062 -0
  283. package/src/frontends/ruby.js +1624 -98
  284. package/src/frontends/rust-parser.js +18 -0
  285. package/src/frontends/rust.js +714 -0
  286. package/src/frontends/scalars.js +31 -1
  287. package/src/frontends/swift.js +893 -0
  288. package/src/frontends/types.js +750 -0
  289. package/src/language-registry.js +182 -12
  290. package/src/mapping.js +33 -9
  291. package/src/semantic/capabilities.js +671 -0
  292. package/src/semantic/effects.js +737 -0
  293. package/src/semantic/generics.js +58 -0
  294. package/src/semantic/lifetime.js +517 -0
  295. package/src/semantic/provenance.js +412 -19
  296. package/src/semantic/scalars.js +17 -0
  297. package/src/semantic/stdlib.js +921 -0
  298. package/src/semantic/types.js +810 -14
  299. package/src/semantic/validate.js +2934 -209
  300. package/src/stdlib-facades.js +1211 -0
  301. package/src/stdlib-negotiation.js +446 -0
  302. package/src/stdlib-providers.js +377 -0
  303. package/src/toolchains.js +16 -3
@@ -0,0 +1,746 @@
1
+ // @ts-check
2
+ import { unsupportedCapability } from "../diagnostic.js";
3
+ import { isTask034ResourceProbe } from "../semantic/capabilities.js";
4
+ const adoptedTargets = new Set(["php", "ruby", "javascript", "typescript", "java"]);
5
+ const task037Authorities = new Set([
6
+ "semantifold.output", "semantifold.resource", "semantifold.socket-client", "semantifold.text-stream"
7
+ ]);
8
+ const protectedSupportNames = new Set([
9
+ "ProbeOperationFailure", "ProbeAcquireFailure", "ProbeReadFailure", "ProbeCloseFailure", "ProbeResourceClosed", "ProbeResource",
10
+ "probeEffect", "probeAcquire", "probeRead", "probeClose", "probeTrace"
11
+ ]);
12
+ /** @typedef {{expression: import("../semantic/types.js").Expression, path: string}} ExpressionPath */
13
+ /** @typedef {{detail: string, location: import("../semantic/types.js").SourceLocation}} ExcludedEffect */
14
+ /**
15
+ * Validates Task 034 target support before a SourceWriter is allocated.
16
+ * @param {import("../semantic/types.js").SemanticModule} module - Candidate module.
17
+ * @param {import("../semantic/types.js").BackendLanguage} language - Requested target.
18
+ * @param {{usedOperations?: readonly string[]}} [options] - Program-wide used canonical
19
+ * operations for a linked stdlib provider; restricts the reserved support surface to the
20
+ * operations actually materialized in the provider artifact.
21
+ * @returns {void}
22
+ */
23
+ export function preflightEffectCapabilities(module, language, options = {}) {
24
+ const capabilities = module?.capabilities;
25
+ if (capabilities === undefined) {
26
+ const unauthorized = findTask034Node(module);
27
+ if (unauthorized) {
28
+ unsupportedCapability(language, "MISSING_CAPABILITY_AUTHORITY: Task 034 IR requires its compiler authority graph",
29
+ /** @type {import("../semantic/types.js").SourceLocation | undefined} */ (Reflect.get(unauthorized, "location") ?? module?.location));
30
+ }
31
+ return;
32
+ }
33
+ if (!Array.isArray(capabilities) || capabilities.length == 0) {
34
+ unsupportedCapability(language, "malformed or empty Task 034 capability graph", module?.location);
35
+ }
36
+ if (!adoptedTargets.has(language)) {
37
+ unsupportedCapability(language, "Task 034 effectful capabilities and owned resources", module.location);
38
+ }
39
+ const task037 = language == "php" && capabilities.every((capability) => task037Authorities.has(capability.authorityId));
40
+ if (!isTask034ResourceProbe(capabilities) && !task037) {
41
+ unsupportedCapability(language, "unbound Task 034 capability authority", module.location);
42
+ }
43
+ if (!Array.isArray(module.functions) || !module.entryPoint || typeof module.entryPoint != "object" ||
44
+ !module.entryPoint.body || !Array.isArray(module.entryPoint.body.statements) ||
45
+ [module.records, module.classes, module.errors].some((declarations) => declarations !== undefined && !Array.isArray(declarations))) {
46
+ unsupportedCapability(language, "malformed Task 034 semantic module", module.location);
47
+ }
48
+ const collision = moduleNeedsEffectSupport(module) ? findSupportCollision(module, language, options.usedOperations) : undefined;
49
+ if (collision)
50
+ unsupportedCapability(language, `protected Task 034 support name '${collision.name}'`, collision.location);
51
+ const excluded = findExcludedEffectContext(module);
52
+ if (excluded)
53
+ unsupportedCapability(language, excluded.detail, excluded.location);
54
+ }
55
+ /**
56
+ * Finds compiler-authorized Task 034 IR that has been detached from its authority graph.
57
+ * @param {unknown} value - Candidate semantic graph.
58
+ * @param {Set<object>} [seen] - Cycle protection.
59
+ * @returns {object | undefined} First unauthorized Task 034 node.
60
+ */
61
+ function findTask034Node(value, seen = new Set()) {
62
+ if (!value || typeof value != "object" || seen.has(value))
63
+ return undefined;
64
+ seen.add(value);
65
+ if (!Array.isArray(value)) {
66
+ const kind = Reflect.get(value, "kind");
67
+ if (["EffectCallExpression", "OwnedBorrowExpression", "OwnedMoveExpression", "OwnedReferenceType", "OwnedResourceType"].includes(String(kind)) ||
68
+ kind == "ErrorType" && /^capability:[0-9]+\/failure:[0-9]+$/u.test(String(Reflect.get(value, "declarationId"))))
69
+ return value;
70
+ }
71
+ for (const [key, child] of Object.entries(value)) {
72
+ if (["location", "sourceProvenance"].includes(key))
73
+ continue;
74
+ const found = findTask034Node(child, seen);
75
+ if (found)
76
+ return found;
77
+ }
78
+ return undefined;
79
+ }
80
+ /**
81
+ * Finds one user declaration that would collide with the protected support surface.
82
+ * @param {import("../semantic/types.js").SemanticModule} module - Validated semantic graph.
83
+ * @param {import("../semantic/types.js").BackendLanguage} language - Target language.
84
+ * @param {readonly string[]} [usedOperations] - Linked provider operations; omitted for the full inlined surface.
85
+ * @returns {{name: string, location: import("../semantic/types.js").SourceLocation} | undefined} First collision.
86
+ */
87
+ function findSupportCollision(module, language, usedOperations) {
88
+ const reserved = new Set();
89
+ if (usedOperations === undefined) {
90
+ for (const name of protectedSupportNames)
91
+ reserved.add(supportNameKey(name, language));
92
+ if (language == "javascript" || language == "typescript") {
93
+ reserved.add("__semantifoldTask034Fs");
94
+ reserved.add("__semantifoldTask034Trace");
95
+ }
96
+ else if (language == "php")
97
+ reserved.add("__semantifold_task034_trace");
98
+ }
99
+ else {
100
+ const used = new Set(usedOperations);
101
+ for (const name of used)
102
+ reserved.add(supportNameKey(name, language));
103
+ if (used.has("probeEffect"))
104
+ reserved.add(supportNameKey("ProbeOperationFailure", language));
105
+ if (used.has("probeAcquire"))
106
+ reserved.add(supportNameKey("ProbeAcquireFailure", language));
107
+ if (used.has("probeRead"))
108
+ reserved.add(supportNameKey("ProbeReadFailure", language));
109
+ if (used.has("probeClose"))
110
+ reserved.add(supportNameKey("ProbeCloseFailure", language));
111
+ if (used.has("probeRead") || used.has("probeClose"))
112
+ reserved.add(supportNameKey("ProbeResourceClosed", language));
113
+ if (used.has("probeAcquire") || used.has("probeRead") || used.has("probeClose")) {
114
+ reserved.add(supportNameKey("ProbeResource", language));
115
+ }
116
+ if (used.size > 0) {
117
+ if (language == "javascript" || language == "typescript") {
118
+ reserved.add("__semantifoldTask034Trace");
119
+ if (used.has("probeAcquire"))
120
+ reserved.add("__semantifoldTask034Fs");
121
+ }
122
+ else if (language == "php")
123
+ reserved.add("__semantifold_task034_trace");
124
+ }
125
+ }
126
+ const declarations = [...module.records ?? [], ...module.classes ?? [], ...module.errors ?? [], ...module.functions];
127
+ for (const declaration of declarations) {
128
+ if (!declaration || typeof declaration != "object")
129
+ continue;
130
+ if (reserved.has(supportNameKey(declaration.name, language)))
131
+ return { location: declaration.location, name: declaration.name };
132
+ }
133
+ if (language == "javascript" || language == "typescript" || language == "php") {
134
+ for (const statement of module.entryPoint.body.statements) {
135
+ if (!statement || typeof statement != "object")
136
+ continue;
137
+ if (statement.kind == "LocalDeclaration" && reserved.has(supportNameKey(statement.name, language))) {
138
+ return { location: statement.location, name: statement.name };
139
+ }
140
+ }
141
+ }
142
+ return undefined;
143
+ }
144
+ /**
145
+ * Applies target namespace casing to a protected support name.
146
+ * @param {string} name - Source name.
147
+ * @param {import("../semantic/types.js").BackendLanguage} language - Target language.
148
+ * @returns {string} Comparable name.
149
+ */
150
+ function supportNameKey(name, language) {
151
+ return language == "php" ? name.toLowerCase() : name;
152
+ }
153
+ /**
154
+ * Emits fixed target-private Task 034 conformance support.
155
+ * @param {import("./writer.js").SourceWriter} writer - Destination writer.
156
+ * @param {import("../semantic/types.js").SemanticModule} module - Authorized module.
157
+ * @param {"php" | "ruby" | "javascript" | "typescript" | "java"} language - Adopted target.
158
+ * @param {"top" | "members"} [placement] - Java support placement.
159
+ * @returns {void}
160
+ */
161
+ export function emitEffectSupport(writer, module, language, placement = "top") {
162
+ const linked = writer.stdlibProviderEntries !== undefined;
163
+ if (language == "java" && linked) {
164
+ if (placement != "members" || writer.stdlibProviderShims === undefined)
165
+ return;
166
+ }
167
+ else if (linked || !module.capabilities || !moduleNeedsEffectSupport(module)) {
168
+ return;
169
+ }
170
+ const content = language == "php" ? phpSupport : language == "ruby" ? rubySupport : language == "javascript" ? javascriptSupport :
171
+ language == "typescript" ? typescriptSupport :
172
+ writer.stdlibProviderShims !== undefined ? javaProgramNestedSupport + javaMemberSupport :
173
+ placement == "top" ? javaTopSupport : javaMemberSupport;
174
+ writer.synthetic(content, "semantifold-task034-support", [module]);
175
+ }
176
+ /**
177
+ * Emits the public static provider shims for the program-wide used operations on the Java owner module.
178
+ * @param {import("./writer.js").SourceWriter} writer - Destination writer.
179
+ * @param {import("../semantic/types.js").SemanticModule} module - Owner module.
180
+ * @returns {void}
181
+ */
182
+ export function emitEffectProviderEntries(writer, module) {
183
+ const operations = writer.stdlibProviderShims ?? [];
184
+ if (operations.length == 0)
185
+ return;
186
+ const lines = operations.map((operation) => ` ${javaProviderShims[operation]}`);
187
+ writer.synthetic(`${lines.join("\n")}\n\n`, "semantifold-stdlib-provider-entries", [module]);
188
+ }
189
+ /**
190
+ * Recognizes only the byte-exact protected support emitted by this backend.
191
+ * Frontends use this in addition to parser-shape checks during generated-source reparse.
192
+ * @param {string} source - Complete candidate source.
193
+ * @param {"php" | "ruby" | "javascript" | "typescript" | "java"} language - Adopted target.
194
+ * @param {"top" | "members"} [placement] - Java support placement.
195
+ * @returns {boolean} Whether the exact protected segment is present.
196
+ */
197
+ export function hasExactEffectSupport(source, language, placement = "top") {
198
+ const content = language == "php" ? phpSupport : language == "ruby" ? rubySupport : language == "javascript" ? javascriptSupport :
199
+ language == "typescript" ? typescriptSupport : placement == "top" ? javaTopSupport : javaMemberSupport;
200
+ return source.includes(content);
201
+ }
202
+ /**
203
+ * Materializes nested effect sites before their enclosing eager expression.
204
+ * The installed replacements remain active until the next statement begins.
205
+ * @param {import("./writer.js").SourceWriter} writer - Destination writer.
206
+ * @param {import("../semantic/types.js").Statement} statement - Current statement.
207
+ * @param {string} indent - Current target indentation.
208
+ * @param {string} path - Exact statement path.
209
+ * @param {"php" | "ruby" | "javascript" | "typescript" | "java"} language - Adopted target.
210
+ * @param {(expression: import("../semantic/types.js").Expression, path: string) => void} emit - Target expression emitter.
211
+ * @returns {void}
212
+ */
213
+ export function emitEffectPrefixes(writer, statement, indent, path, language, emit) {
214
+ /** @type {ExpressionPath[]} */
215
+ const planned = [];
216
+ for (const root of statementExpressionRoots(statement, path))
217
+ collectNestedEffects(root.expression, root.path, root.expression, planned);
218
+ writer.planEffectReplacements(planned.map(({ expression }) => expression));
219
+ for (const { expression, path: expressionPath } of planned) {
220
+ const name = writer.effectTemporaryName(expression);
221
+ const type = effectExpressionType(writer, expression);
222
+ const typeName = emittedTypeName(writer, type, language);
223
+ const declaration = language == "php"
224
+ ? `/**\n${indent} * @var ${typeName} $${name}\n${indent} * @semantifold-immutable\n${indent} */\n${indent}$${name} = `
225
+ : language == "ruby"
226
+ ? `# @type [${typeName}]\n${indent}# @semantifold-immutable\n${indent}${name} = `
227
+ : language == "javascript" ? `/** @type {${typeName}} */\n${indent}const ${name} = `
228
+ : language == "typescript" ? `const ${name}: ${typeName} = ` : `final ${typeName} ${name} = `;
229
+ writer.synthetic(`${indent}${declaration}`, "exactly-once effect temporary", [expression], [expressionPath]);
230
+ writer.emitEffectDefinition(expression, () => emit(expression, expressionPath));
231
+ writer.synthetic(language == "ruby" ? "\n" : ";\n", "exactly-once effect temporary terminator", [expression], [expressionPath]);
232
+ }
233
+ }
234
+ /**
235
+ * Resolves the result type needed for an effect temporary.
236
+ * @param {import("./writer.js").SourceWriter} writer - Active writer.
237
+ * @param {import("../semantic/types.js").Expression} expression - Effectful expression.
238
+ * @returns {import("../semantic/types.js").SemanticFunctionReturnType | undefined} Result type.
239
+ */
240
+ function effectExpressionType(writer, expression) {
241
+ if (expression.kind == "EffectCallExpression")
242
+ return writer.effectOperationForId(expression.operation).returnType;
243
+ if (expression.kind == "MethodCallExpression" || expression.kind == "CallExpression") {
244
+ return expression.resolution ? semanticTypeForIdentity(expression.resolution.returnType) : undefined;
245
+ }
246
+ return undefined;
247
+ }
248
+ /**
249
+ * Rehydrates a resolved call result for target-local temporary spelling.
250
+ * @param {import("../semantic/types.js").FunctionReturnTypeIdentity} identity - Exact resolved result identity.
251
+ * @returns {import("../semantic/types.js").SemanticFunctionReturnType} Detached semantic type.
252
+ */
253
+ function semanticTypeForIdentity(identity) {
254
+ if (typeof identity == "string") {
255
+ return { kind: "TypeReference", name: /** @type {import("../semantic/types.js").FunctionReturnTypeName} */ (identity) };
256
+ }
257
+ if (identity.kind == "ListType")
258
+ return { elementType: semanticTypeForValueIdentity(identity.elementType), kind: "ListType" };
259
+ if (identity.kind == "MapType")
260
+ return { keyType: /** @type {import("../semantic/types.js").TypeReference} */ (semanticTypeForValueIdentity(identity.keyType)), kind: "MapType",
261
+ valueType: semanticTypeForValueIdentity(identity.valueType) };
262
+ if (identity.kind == "OrderedMapType")
263
+ return { keyType: /** @type {import("../semantic/types.js").TypeReference} */ (semanticTypeForValueIdentity(identity.keyType)), kind: "OrderedMapType",
264
+ order: "insertion", valueType: semanticTypeForValueIdentity(identity.valueType) };
265
+ if (identity.kind == "OptionalType")
266
+ return { kind: "OptionalType", valueType: semanticTypeForValueIdentity(identity.valueType) };
267
+ if (identity.kind == "RecordType")
268
+ return { arguments: identity.arguments?.map(semanticTypeForValueIdentity),
269
+ declarationId: identity.declarationId, kind: "RecordType" };
270
+ if (identity.kind == "ReferenceType")
271
+ return { declarationId: identity.declarationId, kind: "ReferenceType" };
272
+ if (identity.kind == "OwnedResourceType")
273
+ return { kind: "OwnedResourceType", resourceId: identity.resourceId };
274
+ if (identity.kind == "OwnedReferenceType")
275
+ return { declarationId: identity.declarationId, kind: "OwnedReferenceType" };
276
+ return { kind: "TypeVariableReference", location: /** @type {never} */ (undefined), parameterId: identity.parameterId };
277
+ }
278
+ /**
279
+ * Rehydrates one non-void resolved type identity.
280
+ * @param {import("../semantic/types.js").SemanticTypeIdentity} identity - Exact type identity.
281
+ * @returns {import("../semantic/types.js").SemanticValueType} Detached semantic type.
282
+ */
283
+ function semanticTypeForValueIdentity(identity) {
284
+ return /** @type {import("../semantic/types.js").SemanticValueType} */ (semanticTypeForIdentity(identity));
285
+ }
286
+ /**
287
+ * Renders the subset of semantic types admitted for synthetic temporaries.
288
+ * @param {import("./writer.js").SourceWriter} writer - Active writer.
289
+ * @param {import("../semantic/types.js").SemanticFunctionReturnType | undefined} type - Semantic type.
290
+ * @param {"php" | "ruby" | "javascript" | "typescript" | "java"} language - Target.
291
+ * @param {boolean} [nested] - Whether Java requires a boxed scalar.
292
+ * @returns {string} Target type spelling.
293
+ */
294
+ function emittedTypeName(writer, type, language, nested = false) {
295
+ if (!type || type.kind == "TypeReference" && type.name == "void")
296
+ return language == "java" ? "Object" : "unknown";
297
+ if (type.kind == "TypeReference") {
298
+ if (language == "php")
299
+ return type.name == "integer" ? "int" : type.name == "boolean" ? "bool" : "string";
300
+ if (language == "ruby")
301
+ return type.name == "integer" ? "Integer" : type.name == "boolean" ? "Boolean" : "String";
302
+ if (language == "java")
303
+ return type.name == "integer" ? nested ? "Integer" : "int" :
304
+ type.name == "boolean" ? nested ? "Boolean" : "boolean" : "String";
305
+ return type.name == "integer" ? "number" : type.name;
306
+ }
307
+ if (type.kind == "OwnedResourceType")
308
+ return writer.resourceForId(type.resourceId).name;
309
+ if (type.kind == "ReferenceType" || type.kind == "OwnedReferenceType")
310
+ return writer.classNameForId(type.declarationId);
311
+ if (type.kind == "TypeVariableReference")
312
+ return writer.typeParameterForId(type.parameterId).name;
313
+ if (type.kind == "RecordType") {
314
+ const name = writer.recordNameForId(type.declarationId);
315
+ const arguments_ = type.arguments?.map((argument) => emittedTypeName(writer, argument, language, true)) ?? [];
316
+ return arguments_.length == 0 ? name : language == "ruby" ? `${name}[${arguments_.join(",")}]` : `${name}<${arguments_.join(",")}>`;
317
+ }
318
+ if (type.kind == "OptionalType") {
319
+ const value = emittedTypeName(writer, type.valueType, language, true);
320
+ return language == "php" ? `?${value}` : language == "ruby" ? `${value}?` :
321
+ language == "java" ? `java.util.Optional<${value}>` : `${value} | null`;
322
+ }
323
+ if (type.kind == "ListType") {
324
+ const value = emittedTypeName(writer, type.elementType, language, true);
325
+ return language == "php" ? `list<${value}>` : language == "ruby" ? `Array<${value}>` :
326
+ language == "java" ? `java.util.List<${value}>` : `readonly ${value}[]`;
327
+ }
328
+ if (type.kind == "MapType" || type.kind == "OrderedMapType") {
329
+ const key = emittedTypeName(writer, type.keyType, language, true);
330
+ const value = emittedTypeName(writer, type.valueType, language, true);
331
+ if (language == "php")
332
+ return `array<${key},${value}>`;
333
+ if (language == "ruby")
334
+ return `Hash[${key},${value}]`;
335
+ if (language == "java")
336
+ return `${type.kind == "OrderedMapType" ? "java.util.SequencedMap" : "java.util.Map"}<${key},${value}>`;
337
+ return `ReadonlyMap<${key}, ${value}>`;
338
+ }
339
+ return language == "java" ? "Object" : "unknown";
340
+ }
341
+ /**
342
+ * Returns the expression roots evaluated by one statement.
343
+ * @param {import("../semantic/types.js").Statement} statement - Statement.
344
+ * @param {string} path - Stable statement path.
345
+ * @returns {ExpressionPath[]} Expression roots.
346
+ */
347
+ function statementExpressionRoots(statement, path) {
348
+ if (statement.kind == "LocalDeclaration")
349
+ return [{ expression: statement.initializer, path: `${path}/initializer` }];
350
+ if (statement.kind == "AssignmentStatement" || statement.kind == "ExpressionStatement" || statement.kind == "PrintStatement") {
351
+ return [{ expression: statement.expression, path: `${path}/expression` }];
352
+ }
353
+ if (statement.kind == "ReturnStatement")
354
+ return statement.expression ? [{ expression: statement.expression, path: `${path}/expression` }] : [];
355
+ if (statement.kind == "PrivateFieldWriteStatement")
356
+ return [{ expression: statement.expression, path: `${path}/expression` }];
357
+ if (statement.kind == "IfStatement" || statement.kind == "WhileStatement")
358
+ return [{ expression: statement.condition, path: `${path}/condition` }];
359
+ if (statement.kind == "ForEachStatement")
360
+ return [{ expression: statement.list, path: `${path}/list` }];
361
+ if (statement.kind == "ForEachMapStatement")
362
+ return [{ expression: statement.map, path: `${path}/map` }];
363
+ if (statement.kind == "RaiseStatement")
364
+ return [{ expression: statement.error.message, path: `${path}/error/message` }];
365
+ return [];
366
+ }
367
+ /**
368
+ * Collects nested effect sites in postorder so children are materialized first.
369
+ * @param {import("../semantic/types.js").Expression} expression - Current expression.
370
+ * @param {string} path - Current occurrence path.
371
+ * @param {import("../semantic/types.js").Expression} root - Statement expression root.
372
+ * @param {ExpressionPath[]} output - Ordered plan receiving nested sites.
373
+ * @returns {void}
374
+ */
375
+ function collectNestedEffects(expression, path, root, output) {
376
+ for (const child of expressionChildren(expression, path))
377
+ collectNestedEffects(child.expression, child.path, root, output);
378
+ if (expression !== root && (expression.kind == "EffectCallExpression" || typeof Reflect.get(expression, "effectSiteId") == "string")) {
379
+ output.push({ expression, path });
380
+ }
381
+ }
382
+ /**
383
+ * Returns path-bearing expression children in evaluation order.
384
+ * @param {import("../semantic/types.js").Expression} expression - Parent expression.
385
+ * @param {string} path - Parent path.
386
+ * @returns {ExpressionPath[]} Children.
387
+ */
388
+ function expressionChildren(expression, path) {
389
+ if (expression.kind == "CallExpression" || expression.kind == "EffectCallExpression" || expression.kind == "ReferenceConstruction" ||
390
+ expression.kind == "RecordConstruction")
391
+ return expression.arguments.map((child, index) => ({ expression: child, path: `${path}/arguments/${index}` }));
392
+ if (expression.kind == "MethodCallExpression")
393
+ return [
394
+ { expression: expression.receiver, path: `${path}/receiver` },
395
+ ...expression.arguments.map((child, index) => ({ expression: child, path: `${path}/arguments/${index}` }))
396
+ ];
397
+ if (expression.kind == "OwnedMoveExpression" || expression.kind == "OwnedBorrowExpression") {
398
+ return [{ expression: expression.expression, path: `${path}/expression` }];
399
+ }
400
+ if (expression.kind == "BinaryExpression")
401
+ return [
402
+ { expression: expression.left, path: `${path}/left` }, { expression: expression.right, path: `${path}/right` }
403
+ ];
404
+ if (expression.kind == "UnaryExpression")
405
+ return [{ expression: expression.operand, path: `${path}/operand` }];
406
+ if (expression.kind == "OptionalSome")
407
+ return [{ expression: expression.value, path: `${path}/value` }];
408
+ if (expression.kind == "OptionalIsPresent" || expression.kind == "OptionalUnwrap") {
409
+ return [{ expression: expression.operand, path: `${path}/operand` }];
410
+ }
411
+ if (expression.kind == "ListLiteral")
412
+ return expression.elements.map((child, index) => ({ expression: child, path: `${path}/elements/${index}` }));
413
+ if (expression.kind == "MapLiteral" || expression.kind == "OrderedMapLiteral")
414
+ return expression.entries.flatMap((entry, index) => [
415
+ { expression: entry.key, path: `${path}/entries/${index}/key` }, { expression: entry.value, path: `${path}/entries/${index}/value` }
416
+ ]);
417
+ if (expression.kind == "ListIndexExpression")
418
+ return [
419
+ { expression: expression.collection, path: `${path}/collection` }, { expression: expression.index, path: `${path}/index` }
420
+ ];
421
+ if (expression.kind == "MapLookupExpression")
422
+ return [
423
+ { expression: expression.collection, path: `${path}/collection` }, { expression: expression.key, path: `${path}/key` }
424
+ ];
425
+ if (expression.kind == "CollectionSizeExpression")
426
+ return [{ expression: expression.collection, path: `${path}/collection` }];
427
+ if (expression.kind == "MemberRead")
428
+ return [{ expression: expression.receiver, path: `${path}/receiver` }];
429
+ return [];
430
+ }
431
+ /**
432
+ * Checks whether generated support is required by a semantic capability node or type.
433
+ * @param {import("../semantic/types.js").SemanticModule} module - Semantic module.
434
+ * @returns {boolean} Whether the protected binding is required.
435
+ */
436
+ function moduleNeedsEffectSupport(module) {
437
+ /** @type {unknown[]} */
438
+ const pending = [module.entryPoint, ...module.functions, ...module.records ?? [], ...module.errors ?? [], ...module.classes ?? []];
439
+ const seen = new Set();
440
+ while (pending.length > 0) {
441
+ const value = pending.pop();
442
+ if (!value || typeof value != "object" || seen.has(value))
443
+ continue;
444
+ seen.add(value);
445
+ const kind = Reflect.get(value, "kind");
446
+ if (kind == "EffectCallExpression" || kind == "OwnedResourceType" || kind == "OwnedReferenceType" ||
447
+ kind == "ErrorType" && /^capability:[0-9]+\/failure:[0-9]+$/u.test(String(Reflect.get(value, "declarationId"))))
448
+ return true;
449
+ for (const [key, child] of Object.entries(value)) {
450
+ if (["location", "sourceProvenance"].includes(key))
451
+ continue;
452
+ if (Array.isArray(child))
453
+ pending.push(...child);
454
+ else if (child && typeof child == "object")
455
+ pending.push(child);
456
+ }
457
+ }
458
+ return false;
459
+ }
460
+ /**
461
+ * Finds a context excluded from bounded eager lowering.
462
+ * @param {import("../semantic/types.js").SemanticModule} module - Semantic module.
463
+ * @returns {ExcludedEffect | undefined} First deterministic exclusion.
464
+ */
465
+ function findExcludedEffectContext(module) {
466
+ /** @type {object[]} */
467
+ const owners = [...module.functions.filter((owner) => owner && typeof owner == "object"), module.entryPoint];
468
+ for (const declaration of module.classes ?? []) {
469
+ if (!declaration || typeof declaration != "object")
470
+ continue;
471
+ if (declaration.constructor && typeof declaration.constructor == "object")
472
+ owners.push(declaration.constructor);
473
+ if (Array.isArray(declaration.methods))
474
+ owners.push(...declaration.methods.filter((owner) => owner && typeof owner == "object"));
475
+ }
476
+ for (const owner of owners) {
477
+ const body = Reflect.get(owner, "body");
478
+ if (!body || typeof body != "object")
479
+ continue;
480
+ const found = blockExcluded(/** @type {import("../semantic/types.js").Block} */ (body));
481
+ if (found)
482
+ return found;
483
+ }
484
+ return undefined;
485
+ }
486
+ /**
487
+ * Finds an excluded context in one structured block.
488
+ * @param {import("../semantic/types.js").Block} block - Semantic block.
489
+ * @returns {ExcludedEffect | undefined} First deterministic exclusion.
490
+ */
491
+ function blockExcluded(block) {
492
+ if (!block || typeof block != "object" || !Array.isArray(block.statements))
493
+ return undefined;
494
+ for (const statement of block.statements) {
495
+ if (!statement || typeof statement != "object")
496
+ continue;
497
+ if (statement.kind == "WhileStatement" && containsEffect(statement.condition)) {
498
+ return { detail: "effectful condition-controlled loop condition", location: statement.condition.location };
499
+ }
500
+ const expressions = statement.kind == "LocalDeclaration" ? [statement.initializer] :
501
+ statement.kind == "AssignmentStatement" || statement.kind == "ExpressionStatement" || statement.kind == "PrintStatement" ? [statement.expression] :
502
+ statement.kind == "ReturnStatement" ? statement.expression ? [statement.expression] : [] :
503
+ statement.kind == "IfStatement" ? [statement.condition] : statement.kind == "ForEachStatement" ? [statement.list] :
504
+ statement.kind == "ForEachMapStatement" ? [statement.map] : statement.kind == "PrivateFieldWriteStatement" ? [statement.expression] :
505
+ statement.kind == "RaiseStatement" ? [statement.error.message] : [];
506
+ for (const expression of expressions) {
507
+ const conditional = findConditionalEffect(expression);
508
+ if (conditional)
509
+ return { detail: "effectful short-circuit BooleanAnd/BooleanOr expression", location: conditional.location };
510
+ }
511
+ const nested = statement.kind == "IfStatement" ? [statement.consequent, ...(statement.alternate ? [statement.alternate] : [])] :
512
+ statement.kind == "ForEachStatement" || statement.kind == "ForEachMapStatement" || statement.kind == "WhileStatement" ? [statement.body] :
513
+ statement.kind == "TryStatement" ? [statement.body, statement.catchBody] : [];
514
+ for (const child of nested) {
515
+ const found = blockExcluded(child);
516
+ if (found)
517
+ return found;
518
+ }
519
+ }
520
+ return undefined;
521
+ }
522
+ /**
523
+ * Finds an effect below a short-circuit operator.
524
+ * @param {import("../semantic/types.js").Expression} expression - Expression root.
525
+ * @returns {import("../semantic/types.js").Expression | undefined} Invalid conditional effect.
526
+ */
527
+ function findConditionalEffect(expression) {
528
+ if (!expression || typeof expression != "object")
529
+ return undefined;
530
+ if (expression.kind == "BinaryExpression" && ["BooleanAnd", "BooleanOr"].includes(expression.operation) &&
531
+ (containsEffect(expression.left) || containsEffect(expression.right)))
532
+ return expression;
533
+ for (const child of children(expression)) {
534
+ const found = findConditionalEffect(child);
535
+ if (found)
536
+ return found;
537
+ }
538
+ return undefined;
539
+ }
540
+ /**
541
+ * Checks whether an expression evaluates an effect.
542
+ * @param {import("../semantic/types.js").Expression} expression - Expression root.
543
+ * @returns {boolean} Whether an effect is reachable.
544
+ */
545
+ function containsEffect(expression) {
546
+ if (!expression || typeof expression != "object")
547
+ return false;
548
+ return expression.kind == "EffectCallExpression" || Boolean(Reflect.get(expression, "effectSiteId")) || children(expression).some(containsEffect);
549
+ }
550
+ /**
551
+ * Returns child expressions in evaluation order.
552
+ * @param {import("../semantic/types.js").Expression} expression - Parent expression.
553
+ * @returns {import("../semantic/types.js").Expression[]} Children.
554
+ */
555
+ function children(expression) {
556
+ if (!expression || typeof expression != "object")
557
+ return [];
558
+ if (expression.kind == "CallExpression" || expression.kind == "EffectCallExpression" || expression.kind == "ReferenceConstruction" ||
559
+ expression.kind == "RecordConstruction")
560
+ return expression.arguments;
561
+ if (expression.kind == "MethodCallExpression")
562
+ return [expression.receiver, ...expression.arguments];
563
+ if (expression.kind == "OwnedMoveExpression" || expression.kind == "OwnedBorrowExpression")
564
+ return [expression.expression];
565
+ if (expression.kind == "BinaryExpression")
566
+ return [expression.left, expression.right];
567
+ if (expression.kind == "UnaryExpression")
568
+ return [expression.operand];
569
+ if (expression.kind == "OptionalSome")
570
+ return [expression.value];
571
+ if (expression.kind == "OptionalIsPresent" || expression.kind == "OptionalUnwrap")
572
+ return [expression.operand];
573
+ if (expression.kind == "ListLiteral")
574
+ return expression.elements;
575
+ if (expression.kind == "MapLiteral" || expression.kind == "OrderedMapLiteral")
576
+ return expression.entries.flatMap(({ key, value }) => [key, value]);
577
+ if (expression.kind == "ListIndexExpression")
578
+ return [expression.collection, expression.index];
579
+ if (expression.kind == "MapLookupExpression")
580
+ return [expression.collection, expression.key];
581
+ if (expression.kind == "CollectionSizeExpression")
582
+ return [expression.collection];
583
+ if (expression.kind == "MemberRead")
584
+ return [expression.receiver];
585
+ return [];
586
+ }
587
+ const phpSupport = `/* semantifold-task034-support */
588
+ final class ProbeOperationFailure extends RuntimeException {}
589
+ final class ProbeAcquireFailure extends RuntimeException {}
590
+ final class ProbeReadFailure extends RuntimeException {}
591
+ final class ProbeCloseFailure extends RuntimeException {}
592
+ final class ProbeResourceClosed extends RuntimeException {}
593
+ final class ProbeResource {
594
+ public bool $closed = false;
595
+ public function __construct(public mixed $handle) {}
596
+ }
597
+ $GLOBALS['__semantifold_task034_trace'] = [];
598
+ function probeEffect(string $label, int $value, bool $fail): int {
599
+ $GLOBALS['__semantifold_task034_trace'][] = 'effect:' . $label;
600
+ if ($fail) throw new ProbeOperationFailure('ProbeOperationFailure');
601
+ return $value;
602
+ }
603
+ function probeAcquire(bool $fail): ProbeResource {
604
+ $GLOBALS['__semantifold_task034_trace'][] = 'acquire';
605
+ if ($fail) throw new ProbeAcquireFailure('ProbeAcquireFailure');
606
+ try { $handle = @fopen((string) getenv('SEMANTIFOLD_TASK034_PROBE_PATH'), 'rb'); }
607
+ catch (Throwable) { throw new ProbeAcquireFailure('ProbeAcquireFailure'); }
608
+ if ($handle === false) throw new ProbeAcquireFailure('ProbeAcquireFailure');
609
+ return new ProbeResource($handle);
610
+ }
611
+ function probeRead(ProbeResource $resource, bool $fail): ?string {
612
+ if ($resource->closed) throw new ProbeResourceClosed('ProbeResourceClosed');
613
+ $GLOBALS['__semantifold_task034_trace'][] = 'read';
614
+ if ($fail) throw new ProbeReadFailure('ProbeReadFailure');
615
+ try { $line = @fgets($resource->handle); }
616
+ catch (Throwable) { throw new ProbeReadFailure('ProbeReadFailure'); }
617
+ if ($line === false) {
618
+ if (feof($resource->handle)) return null;
619
+ throw new ProbeReadFailure('ProbeReadFailure');
620
+ }
621
+ return rtrim($line, "\\r\\n");
622
+ }
623
+ function probeClose(ProbeResource $resource, bool $fail): void {
624
+ if ($resource->closed) throw new ProbeResourceClosed('ProbeResourceClosed');
625
+ $GLOBALS['__semantifold_task034_trace'][] = 'close';
626
+ try { $closed = @fclose($resource->handle); }
627
+ catch (Throwable) { $resource->closed = true; throw new ProbeCloseFailure('ProbeCloseFailure'); }
628
+ $resource->closed = true;
629
+ if ($fail || !$closed) throw new ProbeCloseFailure('ProbeCloseFailure');
630
+ }
631
+ function probeTrace(): string { return implode(',', $GLOBALS['__semantifold_task034_trace']); }
632
+ /* semantifold-task034-support-end */
633
+
634
+ `;
635
+ const rubySupport = `# semantifold-task034-support
636
+ class ProbeOperationFailure < StandardError; end
637
+ class ProbeAcquireFailure < StandardError; end
638
+ class ProbeReadFailure < StandardError; end
639
+ class ProbeCloseFailure < StandardError; end
640
+ class ProbeResourceClosed < StandardError; end
641
+ class ProbeResource
642
+ attr_accessor :handle, :closed
643
+ def initialize(handle); @handle = handle; @closed = false; end
644
+ end
645
+ $__semantifold_task034_trace = []
646
+ def probeEffect(label, value, fail_value)
647
+ $__semantifold_task034_trace << "effect:#{label}"
648
+ raise ProbeOperationFailure, "ProbeOperationFailure" if fail_value
649
+ value
650
+ end
651
+ def probeAcquire(fail_value)
652
+ $__semantifold_task034_trace << "acquire"
653
+ raise ProbeAcquireFailure, "ProbeAcquireFailure" if fail_value
654
+ begin; ProbeResource.new(File.open(ENV.fetch("SEMANTIFOLD_TASK034_PROBE_PATH"), "r")); rescue ProbeAcquireFailure; raise; rescue StandardError; raise ProbeAcquireFailure, "ProbeAcquireFailure"; end
655
+ end
656
+ def probeRead(resource, fail_value)
657
+ raise ProbeResourceClosed, "ProbeResourceClosed" if resource.closed
658
+ $__semantifold_task034_trace << "read"
659
+ raise ProbeReadFailure, "ProbeReadFailure" if fail_value
660
+ begin; value = resource.handle.gets; value.nil? ? nil : value.chomp; rescue ProbeReadFailure; raise; rescue StandardError; raise ProbeReadFailure, "ProbeReadFailure"; end
661
+ end
662
+ def probeClose(resource, fail_value)
663
+ raise ProbeResourceClosed, "ProbeResourceClosed" if resource.closed
664
+ $__semantifold_task034_trace << "close"
665
+ begin; resource.handle.close; rescue StandardError; resource.closed = true; raise ProbeCloseFailure, "ProbeCloseFailure"; end
666
+ resource.closed = true
667
+ raise ProbeCloseFailure, "ProbeCloseFailure" if fail_value
668
+ nil
669
+ end
670
+ def probeTrace; $__semantifold_task034_trace.join(","); end
671
+ # semantifold-task034-support-end
672
+
673
+ `;
674
+ const javascriptSupport = `/* semantifold-task034-support */
675
+ const __semantifoldTask034Fs = process.getBuiltinModule("node:fs")
676
+ class ProbeOperationFailure extends Error {}
677
+ class ProbeAcquireFailure extends Error {}
678
+ class ProbeReadFailure extends Error {}
679
+ class ProbeCloseFailure extends Error {}
680
+ class ProbeResourceClosed extends Error {}
681
+ class ProbeResource { constructor(handle) { this.handle = handle; this.closed = false; this.position = 0 } }
682
+ const __semantifoldTask034Trace = []
683
+ function probeEffect(label, value, fail) { __semantifoldTask034Trace.push(\`effect:\${label}\`); if (fail) throw new ProbeOperationFailure("ProbeOperationFailure"); return value }
684
+ function probeAcquire(fail) { __semantifoldTask034Trace.push("acquire"); if (fail) throw new ProbeAcquireFailure("ProbeAcquireFailure"); try { return new ProbeResource(__semantifoldTask034Fs.openSync(process.env.SEMANTIFOLD_TASK034_PROBE_PATH, "r")) } catch { throw new ProbeAcquireFailure("ProbeAcquireFailure") } }
685
+ function probeRead(resource, fail) { if (resource.closed) throw new ProbeResourceClosed("ProbeResourceClosed"); __semantifoldTask034Trace.push("read"); if (fail) throw new ProbeReadFailure("ProbeReadFailure"); try { const bytes = []; const buffer = Buffer.alloc(1); while (true) { const count = __semantifoldTask034Fs.readSync(resource.handle, buffer, 0, 1, resource.position++); if (count === 0) return bytes.length === 0 ? null : Buffer.from(bytes).toString("utf8"); if (buffer[0] === 10) return Buffer.from(bytes).toString("utf8").replace(/\\r$/u, ""); bytes.push(buffer[0]) } } catch { throw new ProbeReadFailure("ProbeReadFailure") } }
686
+ function probeClose(resource, fail) { if (resource.closed) throw new ProbeResourceClosed("ProbeResourceClosed"); __semantifoldTask034Trace.push("close"); try { __semantifoldTask034Fs.closeSync(resource.handle) } catch { resource.closed = true; throw new ProbeCloseFailure("ProbeCloseFailure") } resource.closed = true; if (fail) throw new ProbeCloseFailure("ProbeCloseFailure") }
687
+ function probeTrace() { return __semantifoldTask034Trace.join(",") }
688
+ /* semantifold-task034-support-end */
689
+
690
+ `;
691
+ const typescriptSupport = `/* semantifold-task034-support */
692
+ const __semantifoldTask034Fs = process.getBuiltinModule("node:fs")
693
+ class ProbeOperationFailure extends Error {}
694
+ class ProbeAcquireFailure extends Error {}
695
+ class ProbeReadFailure extends Error {}
696
+ class ProbeCloseFailure extends Error {}
697
+ class ProbeResourceClosed extends Error {}
698
+ class ProbeResource { closed = false; position = 0; constructor(readonly handle: number) {} }
699
+ const __semantifoldTask034Trace: string[] = []
700
+ function probeEffect(label: string, value: number, fail: boolean): number { __semantifoldTask034Trace.push(\`effect:\${label}\`); if (fail) throw new ProbeOperationFailure("ProbeOperationFailure"); return value }
701
+ function probeAcquire(fail: boolean): ProbeResource { __semantifoldTask034Trace.push("acquire"); if (fail) throw new ProbeAcquireFailure("ProbeAcquireFailure"); try { return new ProbeResource(__semantifoldTask034Fs.openSync(process.env.SEMANTIFOLD_TASK034_PROBE_PATH as string, "r")) } catch { throw new ProbeAcquireFailure("ProbeAcquireFailure") } }
702
+ function probeRead(resource: ProbeResource, fail: boolean): string | null { if (resource.closed) throw new ProbeResourceClosed("ProbeResourceClosed"); __semantifoldTask034Trace.push("read"); if (fail) throw new ProbeReadFailure("ProbeReadFailure"); try { const bytes: number[] = []; const buffer = Buffer.alloc(1); while (true) { const count = __semantifoldTask034Fs.readSync(resource.handle, buffer, 0, 1, resource.position++); if (count === 0) return bytes.length === 0 ? null : Buffer.from(bytes).toString("utf8"); if (buffer[0] === 10) return Buffer.from(bytes).toString("utf8").replace(/\\r$/u, ""); bytes.push(buffer[0]) } } catch { throw new ProbeReadFailure("ProbeReadFailure") } }
703
+ function probeClose(resource: ProbeResource, fail: boolean): void { if (resource.closed) throw new ProbeResourceClosed("ProbeResourceClosed"); __semantifoldTask034Trace.push("close"); try { __semantifoldTask034Fs.closeSync(resource.handle) } catch { resource.closed = true; throw new ProbeCloseFailure("ProbeCloseFailure") } resource.closed = true; if (fail) throw new ProbeCloseFailure("ProbeCloseFailure") }
704
+ function probeTrace(): string { return __semantifoldTask034Trace.join(",") }
705
+ /* semantifold-task034-support-end */
706
+
707
+ `;
708
+ const javaTopSupport = `// semantifold-task034-support
709
+ final class ProbeOperationFailure extends RuntimeException { ProbeOperationFailure() { super("ProbeOperationFailure"); } }
710
+ final class ProbeAcquireFailure extends RuntimeException { ProbeAcquireFailure() { super("ProbeAcquireFailure"); } }
711
+ final class ProbeReadFailure extends RuntimeException { ProbeReadFailure() { super("ProbeReadFailure"); } }
712
+ final class ProbeCloseFailure extends RuntimeException { ProbeCloseFailure() { super("ProbeCloseFailure"); } }
713
+ final class ProbeResourceClosed extends RuntimeException { ProbeResourceClosed() { super("ProbeResourceClosed"); } }
714
+ final class ProbeResource { final java.nio.channels.FileChannel handle; boolean closed = false; ProbeResource(java.nio.channels.FileChannel handle) { this.handle = handle; } }
715
+ // semantifold-task034-support-top-end
716
+
717
+ `;
718
+ const javaMemberSupport = ` // semantifold-task034-support-members
719
+ private static final java.util.ArrayList<String> __semantifoldTask034Trace = new java.util.ArrayList<>();
720
+ static int probeEffect(String label, int value, boolean fail) { __semantifoldTask034Trace.add("effect:" + label); if (fail) throw new ProbeOperationFailure(); return value; }
721
+ static ProbeResource probeAcquire(boolean fail) { __semantifoldTask034Trace.add("acquire"); if (fail) throw new ProbeAcquireFailure(); try { return new ProbeResource(java.nio.channels.FileChannel.open(java.nio.file.Path.of(System.getenv("SEMANTIFOLD_TASK034_PROBE_PATH")))); } catch (RuntimeException | java.io.IOException exception) { throw new ProbeAcquireFailure(); } }
722
+ static java.util.Optional<String> probeRead(ProbeResource resource, boolean fail) { if (resource.closed) throw new ProbeResourceClosed(); __semantifoldTask034Trace.add("read"); if (fail) throw new ProbeReadFailure(); try { java.io.ByteArrayOutputStream bytes = new java.io.ByteArrayOutputStream(); java.nio.ByteBuffer buffer = java.nio.ByteBuffer.allocate(1); while (true) { buffer.clear(); int count = resource.handle.read(buffer); if (count < 0) return bytes.size() == 0 ? java.util.Optional.empty() : java.util.Optional.of(bytes.toString(java.nio.charset.StandardCharsets.UTF_8)); buffer.flip(); byte value = buffer.get(); if (value == 10) return java.util.Optional.of(bytes.toString(java.nio.charset.StandardCharsets.UTF_8).replaceFirst("\\r$", "")); bytes.write(value); } } catch (java.io.IOException exception) { throw new ProbeReadFailure(); } }
723
+ static void probeClose(ProbeResource resource, boolean fail) { if (resource.closed) throw new ProbeResourceClosed(); __semantifoldTask034Trace.add("close"); try { resource.handle.close(); } catch (java.io.IOException exception) { resource.closed = true; throw new ProbeCloseFailure(); } resource.closed = true; if (fail) throw new ProbeCloseFailure(); }
724
+ static String probeTrace() { return String.join(",", __semantifoldTask034Trace); }
725
+ // semantifold-task034-support-members-end
726
+
727
+ `;
728
+ const javaProgramNestedSupport = ` // semantifold-task034-support-program
729
+ public static final class ProbeOperationFailure extends RuntimeException { ProbeOperationFailure() { super("ProbeOperationFailure"); } }
730
+ public static final class ProbeAcquireFailure extends RuntimeException { ProbeAcquireFailure() { super("ProbeAcquireFailure"); } }
731
+ public static final class ProbeReadFailure extends RuntimeException { ProbeReadFailure() { super("ProbeReadFailure"); } }
732
+ public static final class ProbeCloseFailure extends RuntimeException { ProbeCloseFailure() { super("ProbeCloseFailure"); } }
733
+ public static final class ProbeResourceClosed extends RuntimeException { ProbeResourceClosed() { super("ProbeResourceClosed"); } }
734
+ public static final class ProbeResource { final java.nio.channels.FileChannel handle; boolean closed = false; ProbeResource(java.nio.channels.FileChannel handle) { this.handle = handle; } }
735
+ // semantifold-task034-support-program-end
736
+
737
+ `;
738
+ /** @type {Record<string, string>} */
739
+ const javaProviderShims = {
740
+ probeAcquire: "public static ProbeResource __semantifold_provider_java_probeAcquire(boolean fail) { return probeAcquire(fail); }",
741
+ probeClose: "public static void __semantifold_provider_java_probeClose(ProbeResource resource, boolean fail) { probeClose(resource, fail); }",
742
+ probeEffect: "public static int __semantifold_provider_java_probeEffect(String label, int value, boolean fail) { return probeEffect(label, value, fail); }",
743
+ probeRead: "public static java.util.Optional<String> __semantifold_provider_java_probeRead(ProbeResource resource, boolean fail) { return probeRead(resource, fail); }",
744
+ probeTrace: "public static String __semantifold_provider_java_probeTrace() { return probeTrace(); }"
745
+ };
746
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZWZmZWN0cy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9iYWNrZW5kcy9lZmZlY3RzLmpzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLFlBQVk7QUFFWixPQUFPLEVBQUMscUJBQXFCLEVBQUMsTUFBTSxrQkFBa0IsQ0FBQTtBQUN0RCxPQUFPLEVBQUMsc0JBQXNCLEVBQUMsTUFBTSw2QkFBNkIsQ0FBQTtBQUVsRSxNQUFNLGNBQWMsR0FBRyxJQUFJLEdBQUcsQ0FBQyxDQUFDLEtBQUssRUFBRSxNQUFNLEVBQUUsWUFBWSxFQUFFLFlBQVksRUFBRSxNQUFNLENBQUMsQ0FBQyxDQUFBO0FBQ25GLE1BQU0sa0JBQWtCLEdBQUcsSUFBSSxHQUFHLENBQUM7SUFDakMsb0JBQW9CLEVBQUUsc0JBQXNCLEVBQUUsMkJBQTJCLEVBQUUseUJBQXlCO0NBQ3JHLENBQUMsQ0FBQTtBQUNGLE1BQU0scUJBQXFCLEdBQUcsSUFBSSxHQUFHLENBQUM7SUFDcEMsdUJBQXVCLEVBQUUscUJBQXFCLEVBQUUsa0JBQWtCLEVBQUUsbUJBQW1CLEVBQUUscUJBQXFCLEVBQUUsZUFBZTtJQUMvSCxhQUFhLEVBQUUsY0FBYyxFQUFFLFdBQVcsRUFBRSxZQUFZLEVBQUUsWUFBWTtDQUN2RSxDQUFDLENBQUE7QUFFRixzR0FBc0c7QUFDdEcsMEdBQTBHO0FBRTFHOzs7Ozs7OztHQVFHO0FBQ0gsTUFBTSxVQUFVLDJCQUEyQixDQUFDLE1BQU0sRUFBRSxRQUFRLEVBQUUsT0FBTyxHQUFHLEVBQUU7SUFDeEUsTUFBTSxZQUFZLEdBQUcsTUFBTSxFQUFFLFlBQVksQ0FBQTtJQUV6QyxJQUFJLFlBQVksS0FBSyxTQUFTLEVBQUUsQ0FBQztRQUMvQixNQUFNLFlBQVksR0FBRyxlQUFlLENBQUMsTUFBTSxDQUFDLENBQUE7UUFFNUMsSUFBSSxZQUFZLEVBQUUsQ0FBQztZQUNqQixxQkFBcUIsQ0FBQyxRQUFRLEVBQUUsaUZBQWlGO1lBQy9HLHdFQUF3RSxD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QkFBaUIsR0FBRzs7Ozs7Ozs7Ozs7Ozs7OztDQWdCekIsQ0FBQTtBQUVELE1BQU0sY0FBYyxHQUFHOzs7Ozs7Ozs7Q0FTdEIsQ0FBQTtBQUVELE1BQU0saUJBQWlCLEdBQUc7Ozs7Ozs7OztDQVN6QixDQUFBO0FBRUQsTUFBTSx3QkFBd0IsR0FBRzs7Ozs7Ozs7O0NBU2hDLENBQUE7QUFFRCxxQ0FBcUM7QUFDckMsTUFBTSxpQkFBaUIsR0FBRztJQUN4QixZQUFZLEVBQUUsbUhBQW1IO0lBQ2pJLFVBQVUsRUFBRSxpSUFBaUk7SUFDN0ksV0FBVyxFQUFFLDhJQUE4STtJQUMzSixTQUFTLEVBQUUsNEpBQTRKO0lBQ3ZLLFVBQVUsRUFBRSx3RkFBd0Y7Q0FDckcsQ0FBQSIsInNvdXJjZXNDb250ZW50IjpbIi8vIEB0cy1jaGVja1xuXG5pbXBvcnQge3Vuc3VwcG9ydGVkQ2FwYWJpbGl0eX0gZnJvbSBcIi4uL2RpYWdub3N0aWMuanNcIlxuaW1wb3J0IHtpc1Rhc2swMzRSZXNvdXJjZVByb2JlfSBmcm9tIFwiLi4vc2VtYW50aWMvY2FwYWJpbGl0aWVzLmpzXCJcblxuY29uc3QgYWRvcHRlZFRhcmdldHMgPSBuZXcgU2V0KFtcInBocFwiLCBcInJ1YnlcIiwgXCJqYXZhc2NyaXB0XCIsIFwidHlwZXNjcmlwdFwiLCBcImphdmFcIl0pXG5jb25zdCB0YXNrMDM3QXV0aG9yaXRpZXMgPSBuZXcgU2V0KFtcbiAgXCJzZW1hbnRpZm9sZC5vdXRwdXRcIiwgXCJzZW1hbnRpZm9sZC5yZXNvdXJjZVwiLCBcInNlbWFudGlmb2xkLnNvY2tldC1jbGllbnRcIiwgXCJzZW1hbnRpZm9sZC50ZXh0LXN0cmVhbVwiXG5dKVxuY29uc3QgcHJvdGVjdGVkU3VwcG9ydE5hbWVzID0gbmV3IFNldChbXG4gIFwiUHJvYmVPcGVyYXRpb25GYWlsdXJlXCIsIFwiUHJvYmVBY3F1aXJlRmFpbHVyZVwiLCBcIlByb2JlUmVhZEZhaWx1cmVcIiwgXCJQcm9iZUNsb3NlRmFpbHVyZVwiLCBcIlByb2JlUmVzb3VyY2VDbG9zZWRcIiwgXCJQcm9iZVJlc291cmNlXCIsXG4gIFwicHJvYmVFZmZlY3RcIiwgXCJwcm9iZUFjcXVpcmVcIiwgXCJwcm9iZVJlYWRcIiwgXCJwcm9iZUNsb3NlXCIsIFwicHJvYmVUcmFjZVwiXG5dKVxuXG4vKiogQHR5cGVkZWYge3tleHByZXNzaW9uOiBpbXBvcnQoXCIuLi9zZW1hbnRpYy90eXBlcy5qc1wiKS5FeHByZXNzaW9uLCBwYXRoOiBzdHJpbmd9fSBFeHByZXNzaW9uUGF0aCAqL1xuLyoqIEB0eXBlZGVmIHt7ZGV0YWlsOiBzdHJpbmcsIGxvY2F0aW9uOiBpbXBvcnQoXCIuLi9zZW1hbnRpYy90eXBlcy5qc1wiKS5Tb3VyY2VMb2NhdGlvbn19IEV4Y2x1ZGVkRWZmZWN0ICovXG5cbi8qKlxuICogVmFsaWRhdGVzIFRhc2sgMDM0IHRhcmdldCBzdXBwb3J0IGJlZm9yZSBhIFNvdXJjZVdyaXRlciBpcyBhbGxvY2F0ZWQuXG4gKiBAcGFyYW0ge2ltcG9ydChcIi4uL3NlbWFudGljL3R5cGVzLmpzXCIpLlNlbWFudGljTW9kdWxlfSBtb2R1bGUgLSBDYW5kaWRhdGUgbW9kdWxlLlxuICogQHBhcmFtIHtpbXBvcnQoXCIuLi9zZW1hbnRpYy90eXBlcy5qc1wiKS5CYWNrZW5kTGFuZ3VhZ2V9IGxhbmd1YWdlIC0gUmVxdWVzdGVkIHRhcmdldC5cbiAqIEBwYXJhbSB7e3VzZWRPcGVyYXRpb25zPzogcmVhZG9ubHkgc3RyaW5nW119fSBbb3B0aW9uc10gLSBQcm9ncmFtLXdpZGUgdXNlZCBjYW5vbmljYWxcbiAqICAgb3BlcmF0aW9ucyBmb3IgYSBsaW5rZWQgc3RkbGliIHByb3ZpZGVyOyByZXN0cmljdHMgdGhlIHJlc2VydmVkIHN1cHBvcnQgc3VyZmFjZSB0byB0aGVcbiAqICAgb3BlcmF0aW9ucyBhY3R1YWxseSBtYXRlcmlhbGl6ZWQgaW4gdGhlIHByb3ZpZGVyIGFydGlmYWN0LlxuICogQHJldHVybnMge3ZvaWR9XG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBwcmVmbGlnaHRFZmZlY3RDYXBhYmlsaXRpZXMobW9kdWxlLCBsYW5ndWFnZSwgb3B0aW9ucyA9IHt9KSB7XG4gIGNvbnN0IGNhcGFiaWxpdGllcyA9IG1vZHVsZT8uY2FwYWJpbGl0aWVzXG5cbiAgaWYgKGNhcGFiaWxpdGllcyA9PT0gdW5kZWZpbmVkKSB7XG4gICAgY29uc3QgdW5hdXRob3JpemVkID0gZmluZFRhc2swMzROb2RlKG1vZHVsZSlcblxuICAgIGlmICh1bmF1dGhvcml6ZWQpIHtcbiAgICAgIHVuc3VwcG9ydGVkQ2FwYWJpbGl0eShsYW5ndWFnZSwgXCJNSVNTSU5HX0NBUEFCSUxJVFlfQVVUSE9SSVRZOiBUYXNrIDAzNCBJUiByZXF1aXJlcyBpdHMgY29tcGlsZXIgYXV0aG9yaXR5IGdyYXBoXCIsXG4gICAgICAgIC8qKiBAdHlwZSB7aW1wb3J0KFwiLi4vc2VtYW50aWMvdHlwZXMuanNcIikuU291cmNlTG9jYXRpb24gfCB1bmRlZmluZWR9ICovIChSZWZsZWN0LmdldCh1bmF1dGhvcml6ZWQsIFwibG9jYXRpb25cIikgPz8gbW9kdWxlPy5sb2NhdGlvbikpXG4gICAgfVxuICAgIHJldHVyblxuICB9XG4gIGlmICghQXJyYXkuaXNBcnJheShjYXBhYmlsaXRpZXMpIHx8IGNhcGFiaWxpdGllcy5sZW5ndGggPT0gMCkge1xuICAgIHVuc3VwcG9ydGVkQ2FwYWJpbGl0eShsYW5ndWFnZSwgXCJtYWxmb3JtZWQgb3IgZW1wdHkgVGFzayAwMzQgY2FwYWJpbGl0eSBncmFwaFwiLCBtb2R1bGU/LmxvY2F0aW9uKVxuICB9XG4gIGlmICghYWRvcHRlZFRhcmdldHMuaGFzKGxhbmd1YWdlKSkge1xuICAgIHVuc3VwcG9ydGVkQ2FwYWJpbGl0eShsYW5ndWFnZSwgXCJUYXNrIDAzNCBlZmZlY3RmdWwgY2FwYWJpbGl0aWVzIGFuZCBvd25lZCByZXNvdXJjZXNcIiwgbW9kdWxlLmxvY2F0aW9uKVxuICB9XG4gIGNvbnN0IHRhc2swMzcgPSBsYW5ndWFnZSA9PSBcInBocFwiICYmIGNhcGFiaWxpdGllcy5ldmVyeSgoY2FwYWJpbGl0eSkgPT4gdGFzazAzN0F1dGhvcml0aWVzLmhhcyhjYXBhYmlsaXR5LmF1dGhvcml0eUlkKSlcblxuICBpZiAoIWlzVGFzazAzNFJlc291cmNlUHJvYmUoY2FwYWJpbGl0aWVzKSAmJiAhdGFzazAzNykge1xuICAgIHVuc3VwcG9ydGVkQ2FwYWJpbGl0eShsYW5ndWFnZSwgXCJ1bmJvdW5kIFRhc2sgMDM0IGNhcGFiaWxpdHkgYXV0aG9yaXR5XCIsIG1vZHVsZS5sb2NhdGlvbilcbiAgfVxuICBpZiAoIUFycmF5LmlzQXJyYXkobW9kdWxlLmZ1bmN0aW9ucykgfHwgIW1vZHVsZS5lbnRyeVBvaW50IHx8IHR5cGVvZiBtb2R1bGUuZW50cnlQb2ludCAhPSBcIm9iamVjdFwiIHx8XG4gICAgIW1vZHVsZS5lbnRyeVBvaW50LmJvZHkgfHwgIUFycmF5LmlzQXJyYXkobW9kdWxlLmVudHJ5UG9pbnQuYm9keS5zdGF0ZW1lbnRzKSB8fFxuICAgIFttb2R1bGUucmVjb3JkcywgbW9kdWxlLmNsYXNzZXMsIG1vZHVsZS5lcnJvcnNdLnNvbWUoKGRlY2xhcmF0aW9ucykgPT4gZGVjbGFyYXRpb25zICE9PSB1bmRlZmluZWQgJiYgIUFycmF5LmlzQXJyYXkoZGVjbGFyYXRpb25zKSkpIHtcbiAgICB1bnN1cHBvcnRlZENhcGFiaWxpdHkobGFuZ3VhZ2UsIFwibWFsZm9ybWVkIFRhc2sgMDM0IHNlbWFudGljIG1vZHVsZVwiLCBtb2R1bGUubG9jYXRpb24pXG4gIH1cbiAgY29uc3QgY29sbGlzaW9uID0gbW9kdWxlTmVlZHNFZmZlY3RTdXBwb3J0KG1vZHVsZSkgPyBmaW5kU3VwcG9ydENvbGxpc2lvbihtb2R1bGUsIGxhbmd1YWdlLCBvcHRpb25zLnVzZWRPcGVyYXRpb25zKSA6IHVuZGVmaW5lZFxuXG4gIGlmIChjb2xsaXNpb24pIHVuc3VwcG9ydGVkQ2FwYWJpbGl0eShsYW5ndWFnZSwgYHByb3RlY3RlZCBUYXNrIDAzNCBzdXBwb3J0IG5hbWUgJyR7Y29sbGlzaW9uLm5hbWV9J2AsIGNvbGxpc2lvbi5sb2NhdGlvbilcbiAgY29uc3QgZXhjbHVkZWQgPSBmaW5kRXhjbHVkZWRFZmZlY3RDb250ZXh0KG1vZHVsZSlcbiAgaWYgKGV4Y2x1ZGVkKSB1bnN1cHBvcnRlZENhcGFiaWxpdHkobGFuZ3VhZ2UsIGV4Y2x1ZGVkLmRldGFpbCwgZXhjbHVkZWQubG9jYXRpb24pXG59XG5cbi8qKlxuICogRmluZHMgY29tcGlsZXItYXV0aG9yaXplZCBUYXNrIDAzNCBJUiB0aGF0IGhhcyBiZWVuIGRldGFjaGVkIGZyb20gaXRzIGF1dGhvcml0eSBncmFwaC5cbiAqIEBwYXJhbSB7dW5rbm93bn0gdmFsdWUgLSBDYW5kaWRhdGUgc2VtYW50aWMgZ3JhcGguXG4gKiBAcGFyYW0ge1NldDxvYmplY3Q+fSBbc2Vlbl0gLSBDeWNsZSBwcm90ZWN0aW9uLlxuICogQHJldHVybnMge29iamVjdCB8IHVuZGVmaW5lZH0gRmlyc3QgdW5hdXRob3JpemVkIFRhc2sgMDM0IG5vZGUuXG4gKi9cbmZ1bmN0aW9uIGZpbmRUYXNrMDM0Tm9kZSh2YWx1ZSwgc2VlbiA9IG5ldyBTZXQoKSkge1xuICBpZiAoIXZhbHVlIHx8IHR5cGVvZiB2YWx1ZSAhPSBcIm9iamVjdFwiIHx8IHNlZW4uaGFzKHZhbHVlKSkgcmV0dXJuIHVuZGVmaW5lZFxuICBzZWVuLmFkZCh2YWx1ZSlcbiAgaWYgKCFBcnJheS5pc0FycmF5KHZhbHVlKSkge1xuICAgIGNvbnN0IGtpbmQgPSBSZWZsZWN0LmdldCh2YWx1ZSwgXCJraW5kXCIpXG5cbiAgICBpZiAoW1wiRWZmZWN0Q2FsbEV4cHJlc3Npb25cIiwgXCJPd25lZEJvcnJvd0V4cHJlc3Npb25cIiwgXCJPd25lZE1vdmVFeHByZXNzaW9uXCIsIFwiT3duZWRSZWZlcmVuY2VUeXBlXCIsIFwiT3duZWRSZXNvdXJjZVR5cGVcIl0uaW5jbHVkZXMoU3RyaW5nKGtpbmQpKSB8fFxuICAgICAga2luZCA9PSBcIkVycm9yVHlwZVwiICYmIC9eY2FwYWJpbGl0eTpbMC05XStcXC9mYWlsdXJlOlswLTldKyQvdS50ZXN0KFN0cmluZyhSZWZsZWN0LmdldCh2YWx1ZSwgXCJkZWNsYXJhdGlvbklkXCIpKSkpIHJldHVybiB2YWx1ZVxuICB9XG4gIGZvciAoY29uc3QgW2tleSwgY2hpbGRdIG9mIE9iamVjdC5lbnRyaWVzKHZhbHVlKSkge1xuICAgIGlmIChbXCJsb2NhdGlvblwiLCBcInNvdXJjZVByb3ZlbmFuY2VcIl0uaW5jbHVkZXMoa2V5KSkgY29udGludWVcbiAgICBjb25zdCBmb3VuZCA9IGZpbmRUYXNrMDM0Tm9kZShjaGlsZCwgc2VlbilcbiAgICBpZiAoZm91bmQpIHJldHVybiBmb3VuZFxuICB9XG4gIHJldHVybiB1bmRlZmluZWRcbn1cblxuLyoqXG4gKiBGaW5kcyBvbmUgdXNlciBkZWNsYXJhdGlvbiB0aGF0IHdvdWxkIGNvbGxpZGUgd2l0aCB0aGUgcHJvdGVjdGVkIHN1cHBvcnQgc3VyZmFjZS5cbiAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vc2VtYW50aWMvdHlwZXMuanNcIikuU2VtYW50aWNNb2R1bGV9IG1vZHVsZSAtIFZhbGlkYXRlZCBzZW1hbnRpYyBncmFwaC5cbiAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vc2VtYW50aWMvdHlwZXMuanNcIikuQmFja2VuZExhbmd1YWdlfSBsYW5ndWFnZSAtIFRhcmdldCBsYW5ndWFnZS5cbiAqIEBwYXJhbSB7cmVhZG9ubHkgc3RyaW5nW119IFt1c2VkT3BlcmF0aW9uc10gLSBMaW5rZWQgcHJvdmlkZXIgb3BlcmF0aW9uczsgb21pdHRlZCBmb3IgdGhlIGZ1bGwgaW5saW5lZCBzdXJmYWNlLlxuICogQHJldHVybnMge3tuYW1lOiBzdHJpbmcsIGxvY2F0aW9uOiBpbXBvcnQoXCIuLi9zZW1hbnRpYy90eXBlcy5qc1wiKS5Tb3VyY2VMb2NhdGlvbn0gfCB1bmRlZmluZWR9IEZpcnN0IGNvbGxpc2lvbi5cbiAqL1xuZnVuY3Rpb24gZmluZFN1cHBvcnRDb2xsaXNpb24obW9kdWxlLCBsYW5ndWFnZSwgdXNlZE9wZXJhdGlvbnMpIHtcbiAgY29uc3QgcmVzZXJ2ZWQgPSBuZXcgU2V0KClcblxuICBpZiAodXNlZE9wZXJhdGlvbnMgPT09IHVuZGVmaW5lZCkge1xuICAgIGZvciAoY29uc3QgbmFtZSBvZiBwcm90ZWN0ZWRTdXBwb3J0TmFtZXMpIHJlc2VydmVkLmFkZChzdXBwb3J0TmFtZUtleShuYW1lLCBsYW5ndWFnZSkpXG4gICAgaWYgKGxhbmd1YWdlID09IFwiamF2YXNjcmlwdFwiIHx8IGxhbmd1YWdlID09IFwidHlwZXNjcmlwdFwiKSB7XG4gICAgICByZXNlcnZlZC5hZGQoXCJfX3NlbWFudGlmb2xkVGFzazAzNEZzXCIpXG4gICAgICByZXNlcnZlZC5hZGQoXCJfX3NlbWFudGlmb2xkVGFzazAzNFRyYWNlXCIpXG4gICAgfSBlbHNlIGlmIChsYW5ndWFnZSA9PSBcInBocFwiKSByZXNlcnZlZC5hZGQoXCJfX3NlbWFudGlmb2xkX3Rhc2swMzRfdHJhY2VcIilcbiAgfSBlbHNlIHtcbiAgICBjb25zdCB1c2VkID0gbmV3IFNldCh1c2VkT3BlcmF0aW9ucylcblxuICAgIGZvciAoY29uc3QgbmFtZSBvZiB1c2VkKSByZXNlcnZlZC5hZGQoc3VwcG9ydE5hbWVLZXkobmFtZSwgbGFuZ3VhZ2UpKVxuICAgIGlmICh1c2VkLmhhcyhcInByb2JlRWZmZWN0XCIpKSByZXNlcnZlZC5hZGQoc3VwcG9ydE5hbWVLZXkoXCJQcm9iZU9wZXJhdGlvbkZhaWx1cmVcIiwgbGFuZ3VhZ2UpKVxuICAgIGlmICh1c2VkLmhhcyhcInByb2JlQWNxdWlyZVwiKSkgcmVzZXJ2ZWQuYWRkKHN1cHBvcnROYW1lS2V5KFwiUHJvYmVBY3F1aXJlRmFpbHVyZVwiLCBsYW5ndWFnZSkpXG4gICAgaWYgKHVzZWQuaGFzKFwicHJvYmVSZWFkXCIpKSByZXNlcnZlZC5hZGQoc3VwcG9ydE5hbWVLZXkoXCJQcm9iZVJlYWRGYWlsdXJlXCIsIGxhbmd1YWdlKSlcbiAgICBpZiAodXNlZC5oYXMoXCJwcm9iZUNsb3NlXCIpKSByZXNlcnZlZC5hZGQoc3VwcG9ydE5hbWVLZXkoXCJQcm9iZUNsb3NlRmFpbHVyZVwiLCBsYW5ndWFnZSkpXG4gICAgaWYgKHVzZWQuaGFzKFwicHJvYmVSZWFkXCIpIHx8IHVzZWQuaGFzKFwicHJvYmVDbG9zZVwiKSkgcmVzZXJ2ZWQuYWRkKHN1cHBvcnROYW1lS2V5KFwiUHJvYmVSZXNvdXJjZUNsb3NlZFwiLCBsYW5ndWFnZSkpXG4gICAgaWYgKHVzZWQuaGFzKFwicHJvYmVBY3F1aXJlXCIpIHx8IHVzZWQuaGFzKFwicHJvYmVSZWFkXCIpIHx8IHVzZWQuaGFzKFwicHJvYmVDbG9zZVwiKSkge1xuICAgICAgcmVzZXJ2ZWQuYWRkKHN1cHBvcnROYW1lS2V5KFwiUHJvYmVSZXNvdXJjZVwiLCBsYW5ndWFnZSkpXG4gICAgfVxuICAgIGlmICh1c2VkLnNpemUgPiAwKSB7XG4gICAgICBpZiAobGFuZ3VhZ2UgPT0gXCJqYXZhc2NyaXB0XCIgfHwgbGFuZ3VhZ2UgPT0gXCJ0eXBlc2NyaXB0XCIpIHtcbiAgICAgICAgcmVzZXJ2ZWQuYWRkKFwiX19zZW1hbnRpZm9sZFRhc2swMzRUcmFjZVwiKVxuICAgICAgICBpZiAodXNlZC5oYXMoXCJwcm9iZUFjcXVpcmVcIikpIHJlc2VydmVkLmFkZChcIl9fc2VtYW50aWZvbGRUYXNrMDM0RnNcIilcbiAgICAgIH0gZWxzZSBpZiAobGFuZ3VhZ2UgPT0gXCJwaHBcIikgcmVzZXJ2ZWQuYWRkKFwiX19zZW1hbnRpZm9sZF90YXNrMDM0X3RyYWNlXCIpXG4gICAgfVxuICB9XG4gIGNvbnN0IGRlY2xhcmF0aW9ucyA9IFsuLi5tb2R1bGUucmVjb3JkcyA/PyBbXSwgLi4ubW9kdWxlLmNsYXNzZXMgPz8gW10sIC4uLm1vZHVsZS5lcnJvcnMgPz8gW10sIC4uLm1vZHVsZS5mdW5jdGlvbnNdXG5cbiAgZm9yIChjb25zdCBkZWNsYXJhdGlvbiBvZiBkZWNsYXJhdGlvbnMpIHtcbiAgICBpZiAoIWRlY2xhcmF0aW9uIHx8IHR5cGVvZiBkZWNsYXJhdGlvbiAhPSBcIm9iamVjdFwiKSBjb250aW51ZVxuICAgIGlmIChyZXNlcnZlZC5oYXMoc3VwcG9ydE5hbWVLZXkoZGVjbGFyYXRpb24ubmFtZSwgbGFuZ3VhZ2UpKSkgcmV0dXJuIHtsb2NhdGlvbjogZGVjbGFyYXRpb24ubG9jYXRpb24sIG5hbWU6IGRlY2xhcmF0aW9uLm5hbWV9XG4gIH1cbiAgaWYgKGxhbmd1YWdlID09IFwiamF2YXNjcmlwdFwiIHx8IGxhbmd1YWdlID09IFwidHlwZXNjcmlwdFwiIHx8IGxhbmd1YWdlID09IFwicGhwXCIpIHtcbiAgICBmb3IgKGNvbnN0IHN0YXRlbWVudCBvZiBtb2R1bGUuZW50cnlQb2ludC5ib2R5LnN0YXRlbWVudHMpIHtcbiAgICAgIGlmICghc3RhdGVtZW50IHx8IHR5cGVvZiBzdGF0ZW1lbnQgIT0gXCJvYmplY3RcIikgY29udGludWVcbiAgICAgIGlmIChzdGF0ZW1lbnQua2luZCA9PSBcIkxvY2FsRGVjbGFyYXRpb25cIiAmJiByZXNlcnZlZC5oYXMoc3VwcG9ydE5hbWVLZXkoc3RhdGVtZW50Lm5hbWUsIGxhbmd1YWdlKSkpIHtcbiAgICAgICAgcmV0dXJuIHtsb2NhdGlvbjogc3RhdGVtZW50LmxvY2F0aW9uLCBuYW1lOiBzdGF0ZW1lbnQubmFtZX1cbiAgICAgIH1cbiAgICB9XG4gIH1cbiAgcmV0dXJuIHVuZGVmaW5lZFxufVxuXG4vKipcbiAqIEFwcGxpZXMgdGFyZ2V0IG5hbWVzcGFjZSBjYXNpbmcgdG8gYSBwcm90ZWN0ZWQgc3VwcG9ydCBuYW1lLlxuICogQHBhcmFtIHtzdHJpbmd9IG5hbWUgLSBTb3VyY2UgbmFtZS5cbiAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vc2VtYW50aWMvdHlwZXMuanNcIikuQmFja2VuZExhbmd1YWdlfSBsYW5ndWFnZSAtIFRhcmdldCBsYW5ndWFnZS5cbiAqIEByZXR1cm5zIHtzdHJpbmd9IENvbXBhcmFibGUgbmFtZS5cbiAqL1xuZnVuY3Rpb24gc3VwcG9ydE5hbWVLZXkobmFtZSwgbGFuZ3VhZ2UpIHtcbiAgcmV0dXJuIGxhbmd1YWdlID09IFwicGhwXCIgPyBuYW1lLnRvTG93ZXJDYXNlKCkgOiBuYW1lXG59XG5cbi8qKlxuICogRW1pdHMgZml4ZWQgdGFyZ2V0LXByaXZhdGUgVGFzayAwMzQgY29uZm9ybWFuY2Ugc3VwcG9ydC5cbiAqIEBwYXJhbSB7aW1wb3J0KFwiLi93cml0ZXIuanNcIikuU291cmNlV3JpdGVyfSB3cml0ZXIgLSBEZXN0aW5hdGlvbiB3cml0ZXIuXG4gKiBAcGFyYW0ge2ltcG9ydChcIi4uL3NlbWFudGljL3R5cGVzLmpzXCIpLlNlbWFudGljTW9kdWxlfSBtb2R1bGUgLSBBdXRob3JpemVkIG1vZHVsZS5cbiAqIEBwYXJhbSB7XCJwaHBcIiB8IFwicnVieVwiIHwgXCJqYXZhc2NyaXB0XCIgfCBcInR5cGVzY3JpcHRcIiB8IFwiamF2YVwifSBsYW5ndWFnZSAtIEFkb3B0ZWQgdGFyZ2V0LlxuICogQHBhcmFtIHtcInRvcFwiIHwgXCJtZW1iZXJzXCJ9IFtwbGFjZW1lbnRdIC0gSmF2YSBzdXBwb3J0IHBsYWNlbWVudC5cbiAqIEByZXR1cm5zIHt2b2lkfVxuICovXG5leHBvcnQgZnVuY3Rpb24gZW1pdEVmZmVjdFN1cHBvcnQod3JpdGVyLCBtb2R1bGUsIGxhbmd1YWdlLCBwbGFjZW1lbnQgPSBcInRvcFwiKSB7XG4gIGNvbnN0IGxpbmtlZCA9IHdyaXRlci5zdGRsaWJQcm92aWRlckVudHJpZXMgIT09IHVuZGVmaW5lZFxuXG4gIGlmIChsYW5ndWFnZSA9PSBcImphdmFcIiAmJiBsaW5rZWQpIHtcbiAgICBpZiAocGxhY2VtZW50ICE9IFwibWVtYmVyc1wiIHx8IHdyaXRlci5zdGRsaWJQcm92aWRlclNoaW1zID09PSB1bmRlZmluZWQpIHJldHVyblxuICB9IGVsc2UgaWYgKGxpbmtlZCB8fCAhbW9kdWxlLmNhcGFiaWxpdGllcyB8fCAhbW9kdWxlTmVlZHNFZmZlY3RTdXBwb3J0KG1vZHVsZSkpIHtcbiAgICByZXR1cm5cbiAgfVxuICBjb25zdCBjb250ZW50ID0gbGFuZ3VhZ2UgPT0gXCJwaHBcIiA/IHBocFN1cHBvcnQgOiBsYW5ndWFnZSA9PSBcInJ1YnlcIiA/IHJ1YnlTdXBwb3J0IDogbGFuZ3VhZ2UgPT0gXCJqYXZhc2NyaXB0XCIgPyBqYXZhc2NyaXB0U3VwcG9ydCA6XG4gICAgbGFuZ3VhZ2UgPT0gXCJ0eXBlc2NyaXB0XCIgPyB0eXBlc2NyaXB0U3VwcG9ydCA6XG4gICAgd3JpdGVyLnN0ZGxpYlByb3ZpZGVyU2hpbXMgIT09IHVuZGVmaW5lZCA/IGphdmFQcm9ncmFtTmVzdGVkU3VwcG9ydCArIGphdmFNZW1iZXJTdXBwb3J0IDpcbiAgICBwbGFjZW1lbnQgPT0gXCJ0b3BcIiA/IGphdmFUb3BTdXBwb3J0IDogamF2YU1lbWJlclN1cHBvcnRcblxuICB3cml0ZXIuc3ludGhldGljKGNvbnRlbnQsIFwic2VtYW50aWZvbGQtdGFzazAzNC1zdXBwb3J0XCIsIFttb2R1bGVdKVxufVxuXG4vKipcbiAqIEVtaXRzIHRoZSBwdWJsaWMgc3RhdGljIHByb3ZpZGVyIHNoaW1zIGZvciB0aGUgcHJvZ3JhbS13aWRlIHVzZWQgb3BlcmF0aW9ucyBvbiB0aGUgSmF2YSBvd25lciBtb2R1bGUuXG4gKiBAcGFyYW0ge2ltcG9ydChcIi4vd3JpdGVyLmpzXCIpLlNvdXJjZVdyaXRlcn0gd3JpdGVyIC0gRGVzdGluYXRpb24gd3JpdGVyLlxuICogQHBhcmFtIHtpbXBvcnQoXCIuLi9zZW1hbnRpYy90eXBlcy5qc1wiKS5TZW1hbnRpY01vZHVsZX0gbW9kdWxlIC0gT3duZXIgbW9kdWxlLlxuICogQHJldHVybnMge3ZvaWR9XG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBlbWl0RWZmZWN0UHJvdmlkZXJFbnRyaWVzKHdyaXRlciwgbW9kdWxlKSB7XG4gIGNvbnN0IG9wZXJhdGlvbnMgPSB3cml0ZXIuc3RkbGliUHJvdmlkZXJTaGltcyA/PyBbXVxuXG4gIGlmIChvcGVyYXRpb25zLmxlbmd0aCA9PSAwKSByZXR1cm5cbiAgY29uc3QgbGluZXMgPSBvcGVyYXRpb25zLm1hcCgob3BlcmF0aW9uKSA9PiBgICAke2phdmFQcm92aWRlclNoaW1zW29wZXJhdGlvbl19YClcblxuICB3cml0ZXIuc3ludGhldGljKGAke2xpbmVzLmpvaW4oXCJcXG5cIil9XFxuXFxuYCwgXCJzZW1hbnRpZm9sZC1zdGRsaWItcHJvdmlkZXItZW50cmllc1wiLCBbbW9kdWxlXSlcbn1cblxuLyoqXG4gKiBSZWNvZ25pemVzIG9ubHkgdGhlIGJ5dGUtZXhhY3QgcHJvdGVjdGVkIHN1cHBvcnQgZW1pdHRlZCBieSB0aGlzIGJhY2tlbmQuXG4gKiBGcm9udGVuZHMgdXNlIHRoaXMgaW4gYWRkaXRpb24gdG8gcGFyc2VyLXNoYXBlIGNoZWNrcyBkdXJpbmcgZ2VuZXJhdGVkLXNvdXJjZSByZXBhcnNlLlxuICogQHBhcmFtIHtzdHJpbmd9IHNvdXJjZSAtIENvbXBsZXRlIGNhbmRpZGF0ZSBzb3VyY2UuXG4gKiBAcGFyYW0ge1wicGhwXCIgfCBcInJ1YnlcIiB8IFwiamF2YXNjcmlwdFwiIHwgXCJ0eXBlc2NyaXB0XCIgfCBcImphdmFcIn0gbGFuZ3VhZ2UgLSBBZG9wdGVkIHRhcmdldC5cbiAqIEBwYXJhbSB7XCJ0b3BcIiB8IFwibWVtYmVyc1wifSBbcGxhY2VtZW50XSAtIEphdmEgc3VwcG9ydCBwbGFjZW1lbnQuXG4gKiBAcmV0dXJucyB7Ym9vbGVhbn0gV2hldGhlciB0aGUgZXhhY3QgcHJvdGVjdGVkIHNlZ21lbnQgaXMgcHJlc2VudC5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGhhc0V4YWN0RWZmZWN0U3VwcG9ydChzb3VyY2UsIGxhbmd1YWdlLCBwbGFjZW1lbnQgPSBcInRvcFwiKSB7XG4gIGNvbnN0IGNvbnRlbnQgPSBsYW5ndWFnZSA9PSBcInBocFwiID8gcGhwU3VwcG9ydCA6IGxhbmd1YWdlID09IFwicnVieVwiID8gcnVieVN1cHBvcnQgOiBsYW5ndWFnZSA9PSBcImphdmFzY3JpcHRcIiA/IGphdmFzY3JpcHRTdXBwb3J0IDpcbiAgICBsYW5ndWFnZSA9PSBcInR5cGVzY3JpcHRcIiA/IHR5cGVzY3JpcHRTdXBwb3J0IDogcGxhY2VtZW50ID09IFwidG9wXCIgPyBqYXZhVG9wU3VwcG9ydCA6IGphdmFNZW1iZXJTdXBwb3J0XG5cbiAgcmV0dXJuIHNvdXJjZS5pbmNsdWRlcyhjb250ZW50KVxufVxuXG4vKipcbiAqIE1hdGVyaWFsaXplcyBuZXN0ZWQgZWZmZWN0IHNpdGVzIGJlZm9yZSB0aGVpciBlbmNsb3NpbmcgZWFnZXIgZXhwcmVzc2lvbi5cbiAqIFRoZSBpbnN0YWxsZWQgcmVwbGFjZW1lbnRzIHJlbWFpbiBhY3RpdmUgdW50aWwgdGhlIG5leHQgc3RhdGVtZW50IGJlZ2lucy5cbiAqIEBwYXJhbSB7aW1wb3J0KFwiLi93cml0ZXIuanNcIikuU291cmNlV3JpdGVyfSB3cml0ZXIgLSBEZXN0aW5hdGlvbiB3cml0ZXIuXG4gKiBAcGFyYW0ge2ltcG9ydChcIi4uL3NlbWFudGljL3R5cGVzLmpzXCIpLlN0YXRlbWVudH0gc3RhdGVtZW50IC0gQ3VycmVudCBzdGF0ZW1lbnQuXG4gKiBAcGFyYW0ge3N0cmluZ30gaW5kZW50IC0gQ3VycmVudCB0YXJnZXQgaW5kZW50YXRpb24uXG4gKiBAcGFyYW0ge3N0cmluZ30gcGF0aCAtIEV4YWN0IHN0YXRlbWVudCBwYXRoLlxuICogQHBhcmFtIHtcInBocFwiIHwgXCJydWJ5XCIgfCBcImphdmFzY3JpcHRcIiB8IFwidHlwZXNjcmlwdFwiIHwgXCJqYXZhXCJ9IGxhbmd1YWdlIC0gQWRvcHRlZCB0YXJnZXQuXG4gKiBAcGFyYW0geyhleHByZXNzaW9uOiBpbXBvcnQoXCIuLi9zZW1hbnRpYy90eXBlcy5qc1wiKS5FeHByZXNzaW9uLCBwYXRoOiBzdHJpbmcpID0+IHZvaWR9IGVtaXQgLSBUYXJnZXQgZXhwcmVzc2lvbiBlbWl0dGVyLlxuICogQHJldHVybnMge3ZvaWR9XG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBlbWl0RWZmZWN0UHJlZml4ZXMod3JpdGVyLCBzdGF0ZW1lbnQsIGluZGVudCwgcGF0aCwgbGFuZ3VhZ2UsIGVtaXQpIHtcbiAgLyoqIEB0eXBlIHtFeHByZXNzaW9uUGF0aFtdfSAqL1xuICBjb25zdCBwbGFubmVkID0gW11cblxuICBmb3IgKGNvbnN0IHJvb3Qgb2Ygc3RhdGVtZW50RXhwcmVzc2lvblJvb3RzKHN0YXRlbWVudCwgcGF0aCkpIGNvbGxlY3ROZXN0ZWRFZmZlY3RzKHJvb3QuZXhwcmVzc2lvbiwgcm9vdC5wYXRoLCByb290LmV4cHJlc3Npb24sIHBsYW5uZWQpXG4gIHdyaXRlci5wbGFuRWZmZWN0UmVwbGFjZW1lbnRzKHBsYW5uZWQubWFwKCh7ZXhwcmVzc2lvbn0pID0+IGV4cHJlc3Npb24pKVxuICBmb3IgKGNvbnN0IHtleHByZXNzaW9uLCBwYXRoOiBleHByZXNzaW9uUGF0aH0gb2YgcGxhbm5lZCkge1xuICAgIGNvbnN0IG5hbWUgPSB3cml0ZXIuZWZmZWN0VGVtcG9yYXJ5TmFtZShleHByZXNzaW9uKVxuICAgIGNvbnN0IHR5cGUgPSBlZmZlY3RFeHByZXNzaW9uVHlwZSh3cml0ZXIsIGV4cHJlc3Npb24pXG4gICAgY29uc3QgdHlwZU5hbWUgPSBlbWl0dGVkVHlwZU5hbWUod3JpdGVyLCB0eXBlLCBsYW5ndWFnZSlcbiAgICBjb25zdCBkZWNsYXJhdGlvbiA9IGxhbmd1YWdlID09IFwicGhwXCJcbiAgICAgID8gYC8qKlxcbiR7aW5kZW50fSAqIEB2YXIgJHt0eXBlTmFtZX0gJCR7bmFtZX1cXG4ke2luZGVudH0gKiBAc2VtYW50aWZvbGQtaW1tdXRhYmxlXFxuJHtpbmRlbnR9ICovXFxuJHtpbmRlbnR9JCR7bmFtZX0gPSBgXG4gICAgICA6IGxhbmd1YWdlID09IFwicnVieVwiXG4gICAgICAgID8gYCMgQHR5cGUgWyR7dHlwZU5hbWV9XVxcbiR7aW5kZW50fSMgQHNlbWFudGlmb2xkLWltbXV0YWJsZVxcbiR7aW5kZW50fSR7bmFtZX0gPSBgXG4gICAgICAgIDogbGFuZ3VhZ2UgPT0gXCJqYXZhc2NyaXB0XCIgPyBgLyoqIEB0eXBlIHske3R5cGVOYW1lfX0gKi9cXG4ke2luZGVudH1jb25zdCAke25hbWV9ID0gYFxuICAgICAgICAgIDogbGFuZ3VhZ2UgPT0gXCJ0eXBlc2NyaXB0XCIgPyBgY29uc3QgJHtuYW1lfTogJHt0eXBlTmFtZX0gPSBgIDogYGZpbmFsICR7dHlwZU5hbWV9ICR7bmFtZX0gPSBgXG5cbiAgICB3cml0ZXIuc3ludGhldGljKGAke2luZGVudH0ke2RlY2xhcmF0aW9ufWAsIFwiZXhhY3RseS1vbmNlIGVmZmVjdCB0ZW1wb3JhcnlcIiwgW2V4cHJlc3Npb25dLCBbZXhwcmVzc2lvblBhdGhdKVxuICAgIHdyaXRlci5lbWl0RWZmZWN0RGVmaW5pdGlvbihleHByZXNzaW9uLCAoKSA9PiBlbWl0KGV4cHJlc3Npb24sIGV4cHJlc3Npb25QYXRoKSlcbiAgICB3cml0ZXIuc3ludGhldGljKGxhbmd1YWdlID09IFwicnVieVwiID8gXCJcXG5cIiA6IFwiO1xcblwiLCBcImV4YWN0bHktb25jZSBlZmZlY3QgdGVtcG9yYXJ5IHRlcm1pbmF0b3JcIiwgW2V4cHJlc3Npb25dLCBbZXhwcmVzc2lvblBhdGhdKVxuICB9XG59XG5cbi8qKlxuICogUmVzb2x2ZXMgdGhlIHJlc3VsdCB0eXBlIG5lZWRlZCBmb3IgYW4gZWZmZWN0IHRlbXBvcmFyeS5cbiAqIEBwYXJhbSB7aW1wb3J0KFwiLi93cml0ZXIuanNcIikuU291cmNlV3JpdGVyfSB3cml0ZXIgLSBBY3RpdmUgd3JpdGVyLlxuICogQHBhcmFtIHtpbXBvcnQoXCIuLi9zZW1hbnRpYy90eXBlcy5qc1wiKS5FeHByZXNzaW9ufSBleHByZXNzaW9uIC0gRWZmZWN0ZnVsIGV4cHJlc3Npb24uXG4gKiBAcmV0dXJucyB7aW1wb3J0KFwiLi4vc2VtYW50aWMvdHlwZXMuanNcIikuU2VtYW50aWNGdW5jdGlvblJldHVyblR5cGUgfCB1bmRlZmluZWR9IFJlc3VsdCB0eXBlLlxuICovXG5mdW5jdGlvbiBlZmZlY3RFeHByZXNzaW9uVHlwZSh3cml0ZXIsIGV4cHJlc3Npb24pIHtcbiAgaWYgKGV4cHJlc3Npb24ua2luZCA9PSBcIkVmZmVjdENhbGxFeHByZXNzaW9uXCIpIHJldHVybiB3cml0ZXIuZWZmZWN0T3BlcmF0aW9uRm9ySWQoZXhwcmVzc2lvbi5vcGVyYXRpb24pLnJldHVyblR5cGVcbiAgaWYgKGV4cHJlc3Npb24ua2luZCA9PSBcIk1ldGhvZENhbGxFeHByZXNzaW9uXCIgfHwgZXhwcmVzc2lvbi5raW5kID09IFwiQ2FsbEV4cHJlc3Npb25cIikge1xuICAgIHJldHVybiBleHByZXNzaW9uLnJlc29sdXRpb24gPyBzZW1hbnRpY1R5cGVGb3JJZGVudGl0eShleHByZXNzaW9uLnJlc29sdXRpb24ucmV0dXJuVHlwZSkgOiB1bmRlZmluZWRcbiAgfVxuICByZXR1cm4gdW5kZWZpbmVkXG59XG5cbi8qKlxuICogUmVoeWRyYXRlcyBhIHJlc29sdmVkIGNhbGwgcmVzdWx0IGZvciB0YXJnZXQtbG9jYWwgdGVtcG9yYXJ5IHNwZWxsaW5nLlxuICogQHBhcmFtIHtpbXBvcnQoXCIuLi9zZW1hbnRpYy90eXBlcy5qc1wiKS5GdW5jdGlvblJldHVyblR5cGVJZGVudGl0eX0gaWRlbnRpdHkgLSBFeGFjdCByZXNvbHZlZCByZXN1bHQgaWRlbnRpdHkuXG4gKiBAcmV0dXJucyB7aW1wb3J0KFwiLi4vc2VtYW50aWMvdHlwZXMuanNcIikuU2VtYW50aWNGdW5jdGlvblJldHVyblR5cGV9IERldGFjaGVkIHNlbWFudGljIHR5cGUuXG4gKi9cbmZ1bmN0aW9uIHNlbWFudGljVHlwZUZvcklkZW50aXR5KGlkZW50aXR5KSB7XG4gIGlmICh0eXBlb2YgaWRlbnRpdHkgPT0gXCJzdHJpbmdcIikge1xuICAgIHJldHVybiB7a2luZDogXCJUeXBlUmVmZXJlbmNlXCIsIG5hbWU6IC8qKiBAdHlwZSB7aW1wb3J0KFwiLi4vc2VtYW50aWMvdHlwZXMuanNcIikuRnVuY3Rpb25SZXR1cm5UeXBlTmFtZX0gKi8gKGlkZW50aXR5KX1cbiAgfVxuICBpZiAoaWRlbnRpdHkua2luZCA9PSBcIkxpc3RUeXBlXCIpIHJldHVybiB7ZWxlbWVudFR5cGU6IHNlbWFudGljVHlwZUZvclZhbHVlSWRlbnRpdHkoaWRlbnRpdHkuZWxlbWVudFR5cGUpLCBraW5kOiBcIkxpc3RUeXBlXCJ9XG4gIGlmIChpZGVudGl0eS5raW5kID09IFwiTWFwVHlwZVwiKSByZXR1cm4ge2tleVR5cGU6IC8qKiBAdHlwZSB7aW1wb3J0KFwiLi4vc2VtYW50aWMvdHlwZXMuanNcIikuVHlwZVJlZmVyZW5jZX0gKi8gKFxuICAgIHNlbWFudGljVHlwZUZvclZhbHVlSWRlbnRpdHkoaWRlbnRpdHkua2V5VHlwZSkpLCBraW5kOiBcIk1hcFR5cGVcIixcbiAgICB2YWx1ZVR5cGU6IHNlbWFudGljVHlwZUZvclZhbHVlSWRlbnRpdHkoaWRlbnRpdHkudmFsdWVUeXBlKX1cbiAgaWYgKGlkZW50aXR5LmtpbmQgPT0gXCJPcmRlcmVkTWFwVHlwZVwiKSByZXR1cm4ge2tleVR5cGU6IC8qKiBAdHlwZSB7aW1wb3J0KFwiLi4vc2VtYW50aWMvdHlwZXMuanNcIikuVHlwZVJlZmVyZW5jZX0gKi8gKFxuICAgIHNlbWFudGljVHlwZUZvclZhbHVlSWRlbnRpdHkoaWRlbnRpdHkua2V5VHlwZSkpLCBraW5kOiBcIk9yZGVyZWRNYXBUeXBlXCIsXG4gICAgb3JkZXI6IFwiaW5zZXJ0aW9uXCIsIHZhbHVlVHlwZTogc2VtYW50aWNUeXBlRm9yVmFsdWVJZGVudGl0eShpZGVudGl0eS52YWx1ZVR5cGUpfVxuICBpZiAoaWRlbnRpdHkua2luZCA9PSBcIk9wdGlvbmFsVHlwZVwiKSByZXR1cm4ge2tpbmQ6IFwiT3B0aW9uYWxUeXBlXCIsIHZhbHVlVHlwZTogc2VtYW50aWNUeXBlRm9yVmFsdWVJZGVudGl0eShpZGVudGl0eS52YWx1ZVR5cGUpfVxuICBpZiAoaWRlbnRpdHkua2luZCA9PSBcIlJlY29yZFR5cGVcIikgcmV0dXJuIHthcmd1bWVudHM6IGlkZW50aXR5LmFyZ3VtZW50cz8ubWFwKHNlbWFudGljVHlwZUZvclZhbHVlSWRlbnRpdHkpLFxuICAgIGRlY2xhcmF0aW9uSWQ6IGlkZW50aXR5LmRlY2xhcmF0aW9uSWQsIGtpbmQ6IFwiUmVjb3JkVHlwZVwifVxuICBpZiAoaWRlbnRpdHkua2luZCA9PSBcIlJlZmVyZW5jZVR5cGVcIikgcmV0dXJuIHtkZWNsYXJhdGlvbklkOiBpZGVudGl0eS5kZWNsYXJhdGlvbklkLCBraW5kOiBcIlJlZmVyZW5jZVR5cGVcIn1cbiAgaWYgKGlkZW50aXR5LmtpbmQgPT0gXCJPd25lZFJlc291cmNlVHlwZVwiKSByZXR1cm4ge2tpbmQ6IFwiT3duZWRSZXNvdXJjZVR5cGVcIiwgcmVzb3VyY2VJZDogaWRlbnRpdHkucmVzb3VyY2VJZH1cbiAgaWYgKGlkZW50aXR5LmtpbmQgPT0gXCJPd25lZFJlZmVyZW5jZVR5cGVcIikgcmV0dXJuIHtkZWNsYXJhdGlvbklkOiBpZGVudGl0eS5kZWNsYXJhdGlvbklkLCBraW5kOiBcIk93bmVkUmVmZXJlbmNlVHlwZVwifVxuICByZXR1cm4ge2tpbmQ6IFwiVHlwZVZhcmlhYmxlUmVmZXJlbmNlXCIsIGxvY2F0aW9uOiAvKiogQHR5cGUge25ldmVyfSAqLyAodW5kZWZpbmVkKSwgcGFyYW1ldGVySWQ6IGlkZW50aXR5LnBhcmFtZXRlcklkfVxufVxuXG4vKipcbiAqIFJlaHlkcmF0ZXMgb25lIG5vbi12b2lkIHJlc29sdmVkIHR5cGUgaWRlbnRpdHkuXG4gKiBAcGFyYW0ge2ltcG9ydChcIi4uL3NlbWFudGljL3R5cGVzLmpzXCIpLlNlbWFudGljVHlwZUlkZW50aXR5fSBpZGVudGl0eSAtIEV4YWN0IHR5cGUgaWRlbnRpdHkuXG4gKiBAcmV0dXJucyB7aW1wb3J0KFwiLi4vc2VtYW50aWMvdHlwZXMuanNcIikuU2VtYW50aWNWYWx1ZVR5cGV9IERldGFjaGVkIHNlbWFudGljIHR5cGUuXG4gKi9cbmZ1bmN0aW9uIHNlbWFudGljVHlwZUZvclZhbHVlSWRlbnRpdHkoaWRlbnRpdHkpIHtcbiAgcmV0dXJuIC8qKiBAdHlwZSB7aW1wb3J0KFwiLi4vc2VtYW50aWMvdHlwZXMuanNcIikuU2VtYW50aWNWYWx1ZVR5cGV9ICovIChzZW1hbnRpY1R5cGVGb3JJZGVudGl0eShpZGVudGl0eSkpXG59XG5cbi8qKlxuICogUmVuZGVycyB0aGUgc3Vic2V0IG9mIHNlbWFudGljIHR5cGVzIGFkbWl0dGVkIGZvciBzeW50aGV0aWMgdGVtcG9yYXJpZXMuXG4gKiBAcGFyYW0ge2ltcG9ydChcIi4vd3JpdGVyLmpzXCIpLlNvdXJjZVdyaXRlcn0gd3JpdGVyIC0gQWN0aXZlIHdyaXRlci5cbiAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vc2VtYW50aWMvdHlwZXMuanNcIikuU2VtYW50aWNGdW5jdGlvblJldHVyblR5cGUgfCB1bmRlZmluZWR9IHR5cGUgLSBTZW1hbnRpYyB0eXBlLlxuICogQHBhcmFtIHtcInBocFwiIHwgXCJydWJ5XCIgfCBcImphdmFzY3JpcHRcIiB8IFwidHlwZXNjcmlwdFwiIHwgXCJqYXZhXCJ9IGxhbmd1YWdlIC0gVGFyZ2V0LlxuICogQHBhcmFtIHtib29sZWFufSBbbmVzdGVkXSAtIFdoZXRoZXIgSmF2YSByZXF1aXJlcyBhIGJveGVkIHNjYWxhci5cbiAqIEByZXR1cm5zIHtzdHJpbmd9IFRhcmdldCB0eXBlIHNwZWxsaW5nLlxuICovXG5mdW5jdGlvbiBlbWl0dGVkVHlwZU5hbWUod3JpdGVyLCB0eXBlLCBsYW5ndWFnZSwgbmVzdGVkID0gZmFsc2UpIHtcbiAgaWYgKCF0eXBlIHx8IHR5cGUua2luZCA9PSBcIlR5cGVSZWZlcmVuY2VcIiAmJiB0eXBlLm5hbWUgPT0gXCJ2b2lkXCIpIHJldHVybiBsYW5ndWFnZSA9PSBcImphdmFcIiA/IFwiT2JqZWN0XCIgOiBcInVua25vd25cIlxuICBpZiAodHlwZS5raW5kID09IFwiVHlwZVJlZmVyZW5jZVwiKSB7XG4gICAgaWYgKGxhbmd1YWdlID09IFwicGhwXCIpIHJldHVybiB0eXBlLm5hbWUgPT0gXCJpbnRlZ2VyXCIgPyBcImludFwiIDogdHlwZS5uYW1lID09IFwiYm9vbGVhblwiID8gXCJib29sXCIgOiBcInN0cmluZ1wiXG4gICAgaWYgKGxhbmd1YWdlID09IFwicnVieVwiKSByZXR1cm4gdHlwZS5uYW1lID09IFwiaW50ZWdlclwiID8gXCJJbnRlZ2VyXCIgOiB0eXBlLm5hbWUgPT0gXCJib29sZWFuXCIgPyBcIkJvb2xlYW5cIiA6IFwiU3RyaW5nXCJcbiAgICBpZiAobGFuZ3VhZ2UgPT0gXCJqYXZhXCIpIHJldHVybiB0eXBlLm5hbWUgPT0gXCJpbnRlZ2VyXCIgPyBuZXN0ZWQgPyBcIkludGVnZXJcIiA6IFwiaW50XCIgOlxuICAgICAgdHlwZS5uYW1lID09IFwiYm9vbGVhblwiID8gbmVzdGVkID8gXCJCb29sZWFuXCIgOiBcImJvb2xlYW5cIiA6IFwiU3RyaW5nXCJcbiAgICByZXR1cm4gdHlwZS5uYW1lID09IFwiaW50ZWdlclwiID8gXCJudW1iZXJcIiA6IHR5cGUubmFtZVxuICB9XG4gIGlmICh0eXBlLmtpbmQgPT0gXCJPd25lZFJlc291cmNlVHlwZVwiKSByZXR1cm4gd3JpdGVyLnJlc291cmNlRm9ySWQodHlwZS5yZXNvdXJjZUlkKS5uYW1lXG4gIGlmICh0eXBlLmtpbmQgPT0gXCJSZWZlcmVuY2VUeXBlXCIgfHwgdHlwZS5raW5kID09IFwiT3duZWRSZWZlcmVuY2VUeXBlXCIpIHJldHVybiB3cml0ZXIuY2xhc3NOYW1lRm9ySWQodHlwZS5kZWNsYXJhdGlvbklkKVxuICBpZiAodHlwZS5raW5kID09IFwiVHlwZVZhcmlhYmxlUmVmZXJlbmNlXCIpIHJldHVybiB3cml0ZXIudHlwZVBhcmFtZXRlckZvcklkKHR5cGUucGFyYW1ldGVySWQpLm5hbWVcbiAgaWYgKHR5cGUua2luZCA9PSBcIlJlY29yZFR5cGVcIikge1xuICAgIGNvbnN0IG5hbWUgPSB3cml0ZXIucmVjb3JkTmFtZUZvcklkKHR5cGUuZGVjbGFyYXRpb25JZClcbiAgICBjb25zdCBhcmd1bWVudHNfID0gdHlwZS5hcmd1bWVudHM/Lm1hcCgoYXJndW1lbnQpID0+IGVtaXR0ZWRUeXBlTmFtZSh3cml0ZXIsIGFyZ3VtZW50LCBsYW5ndWFnZSwgdHJ1ZSkpID8/IFtdXG5cbiAgICByZXR1cm4gYXJndW1lbnRzXy5sZW5ndGggPT0gMCA/IG5hbWUgOiBsYW5ndWFnZSA9PSBcInJ1YnlcIiA/IGAke25hbWV9WyR7YXJndW1lbnRzXy5qb2luKFwiLFwiKX1dYCA6IGAke25hbWV9PCR7YXJndW1lbnRzXy5qb2luKFwiLFwiKX0+YFxuICB9XG4gIGlmICh0eXBlLmtpbmQgPT0gXCJPcHRpb25hbFR5cGVcIikge1xuICAgIGNvbnN0IHZhbHVlID0gZW1pdHRlZFR5cGVOYW1lKHdyaXRlciwgdHlwZS52YWx1ZVR5cGUsIGxhbmd1YWdlLCB0cnVlKVxuICAgIHJldHVybiBsYW5ndWFnZSA9PSBcInBocFwiID8gYD8ke3ZhbHVlfWAgOiBsYW5ndWFnZSA9PSBcInJ1YnlcIiA/IGAke3ZhbHVlfT9gIDpcbiAgICAgIGxhbmd1YWdlID09IFwiamF2YVwiID8gYGphdmEudXRpbC5PcHRpb25hbDwke3ZhbHVlfT5gIDogYCR7dmFsdWV9IHwgbnVsbGBcbiAgfVxuICBpZiAodHlwZS5raW5kID09IFwiTGlzdFR5cGVcIikge1xuICAgIGNvbnN0IHZhbHVlID0gZW1pdHRlZFR5cGVOYW1lKHdyaXRlciwgdHlwZS5lbGVtZW50VHlwZSwgbGFuZ3VhZ2UsIHRydWUpXG4gICAgcmV0dXJuIGxhbmd1YWdlID09IFwicGhwXCIgPyBgbGlzdDwke3ZhbHVlfT5gIDogbGFuZ3VhZ2UgPT0gXCJydWJ5XCIgPyBgQXJyYXk8JHt2YWx1ZX0+YCA6XG4gICAgICBsYW5ndWFnZSA9PSBcImphdmFcIiA/IGBqYXZhLnV0aWwuTGlzdDwke3ZhbHVlfT5gIDogYHJlYWRvbmx5ICR7dmFsdWV9W11gXG4gIH1cbiAgaWYgKHR5cGUua2luZCA9PSBcIk1hcFR5cGVcIiB8fCB0eXBlLmtpbmQgPT0gXCJPcmRlcmVkTWFwVHlwZVwiKSB7XG4gICAgY29uc3Qga2V5ID0gZW1pdHRlZFR5cGVOYW1lKHdyaXRlciwgdHlwZS5rZXlUeXBlLCBsYW5ndWFnZSwgdHJ1ZSlcbiAgICBjb25zdCB2YWx1ZSA9IGVtaXR0ZWRUeXBlTmFtZSh3cml0ZXIsIHR5cGUudmFsdWVUeXBlLCBsYW5ndWFnZSwgdHJ1ZSlcblxuICAgIGlmIChsYW5ndWFnZSA9PSBcInBocFwiKSByZXR1cm4gYGFycmF5PCR7a2V5fSwke3ZhbHVlfT5gXG4gICAgaWYgKGxhbmd1YWdlID09IFwicnVieVwiKSByZXR1cm4gYEhhc2hbJHtrZXl9LCR7dmFsdWV9XWBcbiAgICBpZiAobGFuZ3VhZ2UgPT0gXCJqYXZhXCIpIHJldHVybiBgJHt0eXBlLmtpbmQgPT0gXCJPcmRlcmVkTWFwVHlwZVwiID8gXCJqYXZhLnV0aWwuU2VxdWVuY2VkTWFwXCIgOiBcImphdmEudXRpbC5NYXBcIn08JHtrZXl9LCR7dmFsdWV9PmBcbiAgICByZXR1cm4gYFJlYWRvbmx5TWFwPCR7a2V5fSwgJHt2YWx1ZX0+YFxuICB9XG4gIHJldHVybiBsYW5ndWFnZSA9PSBcImphdmFcIiA/IFwiT2JqZWN0XCIgOiBcInVua25vd25cIlxufVxuXG4vKipcbiAqIFJldHVybnMgdGhlIGV4cHJlc3Npb24gcm9vdHMgZXZhbHVhdGVkIGJ5IG9uZSBzdGF0ZW1lbnQuXG4gKiBAcGFyYW0ge2ltcG9ydChcIi4uL3NlbWFudGljL3R5cGVzLmpzXCIpLlN0YXRlbWVudH0gc3RhdGVtZW50IC0gU3RhdGVtZW50LlxuICogQHBhcmFtIHtzdHJpbmd9IHBhdGggLSBTdGFibGUgc3RhdGVtZW50IHBhdGguXG4gKiBAcmV0dXJucyB7RXhwcmVzc2lvblBhdGhbXX0gRXhwcmVzc2lvbiByb290cy5cbiAqL1xuZnVuY3Rpb24gc3RhdGVtZW50RXhwcmVzc2lvblJvb3RzKHN0YXRlbWVudCwgcGF0aCkge1xuICBpZiAoc3RhdGVtZW50LmtpbmQgPT0gXCJMb2NhbERlY2xhcmF0aW9uXCIpIHJldHVybiBbe2V4cHJlc3Npb246IHN0YXRlbWVudC5pbml0aWFsaXplciwgcGF0aDogYCR7cGF0aH0vaW5pdGlhbGl6ZXJgfV1cbiAgaWYgKHN0YXRlbWVudC5raW5kID09IFwiQXNzaWdubWVudFN0YXRlbWVudFwiIHx8IHN0YXRlbWVudC5raW5kID09IFwiRXhwcmVzc2lvblN0YXRlbWVudFwiIHx8IHN0YXRlbWVudC5raW5kID09IFwiUHJpbnRTdGF0ZW1lbnRcIikge1xuICAgIHJldHVybiBbe2V4cHJlc3Npb246IHN0YXRlbWVudC5leHByZXNzaW9uLCBwYXRoOiBgJHtwYXRofS9leHByZXNzaW9uYH1dXG4gIH1cbiAgaWYgKHN0YXRlbWVudC5raW5kID09IFwiUmV0dXJuU3RhdGVtZW50XCIpIHJldHVybiBzdGF0ZW1lbnQuZXhwcmVzc2lvbiA/IFt7ZXhwcmVzc2lvbjogc3RhdGVtZW50LmV4cHJlc3Npb24sIHBhdGg6IGAke3BhdGh9L2V4cHJlc3Npb25gfV0gOiBbXVxuICBpZiAoc3RhdGVtZW50LmtpbmQgPT0gXCJQcml2YXRlRmllbGRXcml0ZVN0YXRlbWVudFwiKSByZXR1cm4gW3tleHByZXNzaW9uOiBzdGF0ZW1lbnQuZXhwcmVzc2lvbiwgcGF0aDogYCR7cGF0aH0vZXhwcmVzc2lvbmB9XVxuICBpZiAoc3RhdGVtZW50LmtpbmQgPT0gXCJJZlN0YXRlbWVudFwiIHx8IHN0YXRlbWVudC5raW5kID09IFwiV2hpbGVTdGF0ZW1lbnRcIikgcmV0dXJuIFt7ZXhwcmVzc2lvbjogc3RhdGVtZW50LmNvbmRpdGlvbiwgcGF0aDogYCR7cGF0aH0vY29uZGl0aW9uYH1dXG4gIGlmIChzdGF0ZW1lbnQua2luZCA9PSBcIkZvckVhY2hTdGF0ZW1lbnRcIikgcmV0dXJuIFt7ZXhwcmVzc2lvbjogc3RhdGVtZW50Lmxpc3QsIHBhdGg6IGAke3BhdGh9L2xpc3RgfV1cbiAgaWYgKHN0YXRlbWVudC5raW5kID09IFwiRm9yRWFjaE1hcFN0YXRlbWVudFwiKSByZXR1cm4gW3tleHByZXNzaW9uOiBzdGF0ZW1lbnQubWFwLCBwYXRoOiBgJHtwYXRofS9tYXBgfV1cbiAgaWYgKHN0YXRlbWVudC5raW5kID09IFwiUmFpc2VTdGF0ZW1lbnRcIikgcmV0dXJuIFt7ZXhwcmVzc2lvbjogc3RhdGVtZW50LmVycm9yLm1lc3NhZ2UsIHBhdGg6IGAke3BhdGh9L2Vycm9yL21lc3NhZ2VgfV1cbiAgcmV0dXJuIFtdXG59XG5cbi8qKlxuICogQ29sbGVjdHMgbmVzdGVkIGVmZmVjdCBzaXRlcyBpbiBwb3N0b3JkZXIgc28gY2hpbGRyZW4gYXJlIG1hdGVyaWFsaXplZCBmaXJzdC5cbiAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vc2VtYW50aWMvdHlwZXMuanNcIikuRXhwcmVzc2lvbn0gZXhwcmVzc2lvbiAtIEN1cnJlbnQgZXhwcmVzc2lvbi5cbiAqIEBwYXJhbSB7c3RyaW5nfSBwYXRoIC0gQ3VycmVudCBvY2N1cnJlbmNlIHBhdGguXG4gKiBAcGFyYW0ge2ltcG9ydChcIi4uL3NlbWFudGljL3R5cGVzLmpzXCIpLkV4cHJlc3Npb259IHJvb3QgLSBTdGF0ZW1lbnQgZXhwcmVzc2lvbiByb290LlxuICogQHBhcmFtIHtFeHByZXNzaW9uUGF0aFtdfSBvdXRwdXQgLSBPcmRlcmVkIHBsYW4gcmVjZWl2aW5nIG5lc3RlZCBzaXRlcy5cbiAqIEByZXR1cm5zIHt2b2lkfVxuICovXG5mdW5jdGlvbiBjb2xsZWN0TmVzdGVkRWZmZWN0cyhleHByZXNzaW9uLCBwYXRoLCByb290LCBvdXRwdXQpIHtcbiAgZm9yIChjb25zdCBjaGlsZCBvZiBleHByZXNzaW9uQ2hpbGRyZW4oZXhwcmVzc2lvbiwgcGF0aCkpIGNvbGxlY3ROZXN0ZWRFZmZlY3RzKGNoaWxkLmV4cHJlc3Npb24sIGNoaWxkLnBhdGgsIHJvb3QsIG91dHB1dClcbiAgaWYgKGV4cHJlc3Npb24gIT09IHJvb3QgJiYgKGV4cHJlc3Npb24ua2luZCA9PSBcIkVmZmVjdENhbGxFeHByZXNzaW9uXCIgfHwgdHlwZW9mIFJlZmxlY3QuZ2V0KGV4cHJlc3Npb24sIFwiZWZmZWN0U2l0ZUlkXCIpID09IFwic3RyaW5nXCIpKSB7XG4gICAgb3V0cHV0LnB1c2goe2V4cHJlc3Npb24sIHBhdGh9KVxuICB9XG59XG5cbi8qKlxuICogUmV0dXJucyBwYXRoLWJlYXJpbmcgZXhwcmVzc2lvbiBjaGlsZHJlbiBpbiBldmFsdWF0aW9uIG9yZGVyLlxuICogQHBhcmFtIHtpbXBvcnQoXCIuLi9zZW1hbnRpYy90eXBlcy5qc1wiKS5FeHByZXNzaW9ufSBleHByZXNzaW9uIC0gUGFyZW50IGV4cHJlc3Npb24uXG4gKiBAcGFyYW0ge3N0cmluZ30gcGF0aCAtIFBhcmVudCBwYXRoLlxuICogQHJldHVybnMge0V4cHJlc3Npb25QYXRoW119IENoaWxkcmVuLlxuICovXG5mdW5jdGlvbiBleHByZXNzaW9uQ2hpbGRyZW4oZXhwcmVzc2lvbiwgcGF0aCkge1xuICBpZiAoZXhwcmVzc2lvbi5raW5kID09IFwiQ2FsbEV4cHJlc3Npb25cIiB8fCBleHByZXNzaW9uLmtpbmQgPT0gXCJFZmZlY3RDYWxsRXhwcmVzc2lvblwiIHx8IGV4cHJlc3Npb24ua2luZCA9PSBcIlJlZmVyZW5jZUNvbnN0cnVjdGlvblwiIHx8XG4gICAgZXhwcmVzc2lvbi5raW5kID09IFwiUmVjb3JkQ29uc3RydWN0aW9uXCIpIHJldHVybiBleHByZXNzaW9uLmFyZ3VtZW50cy5tYXAoKGNoaWxkLCBpbmRleCkgPT4gKHtleHByZXNzaW9uOiBjaGlsZCwgcGF0aDogYCR7cGF0aH0vYXJndW1lbnRzLyR7aW5kZXh9YH0pKVxuICBpZiAoZXhwcmVzc2lvbi5raW5kID09IFwiTWV0aG9kQ2FsbEV4cHJlc3Npb25cIikgcmV0dXJuIFtcbiAgICB7ZXhwcmVzc2lvbjogZXhwcmVzc2lvbi5yZWNlaXZlciwgcGF0aDogYCR7cGF0aH0vcmVjZWl2ZXJgfSxcbiAgICAuLi5leHByZXNzaW9uLmFyZ3VtZW50cy5tYXAoKGNoaWxkLCBpbmRleCkgPT4gKHtleHByZXNzaW9uOiBjaGlsZCwgcGF0aDogYCR7cGF0aH0vYXJndW1lbnRzLyR7aW5kZXh9YH0pKVxuICBdXG4gIGlmIChleHByZXNzaW9uLmtpbmQgPT0gXCJPd25lZE1vdmVFeHByZXNzaW9uXCIgfHwgZXhwcmVzc2lvbi5raW5kID09IFwiT3duZWRCb3Jyb3dFeHByZXNzaW9uXCIpIHtcbiAgICByZXR1cm4gW3tleHByZXNzaW9uOiBleHByZXNzaW9uLmV4cHJlc3Npb24sIHBhdGg6IGAke3BhdGh9L2V4cHJlc3Npb25gfV1cbiAgfVxuICBpZiAoZXhwcmVzc2lvbi5raW5kID09IFwiQmluYXJ5RXhwcmVzc2lvblwiKSByZXR1cm4gW1xuICAgIHtleHByZXNzaW9uOiBleHByZXNzaW9uLmxlZnQsIHBhdGg6IGAke3BhdGh9L2xlZnRgfSwge2V4cHJlc3Npb246IGV4cHJlc3Npb24ucmlnaHQsIHBhdGg6IGAke3BhdGh9L3JpZ2h0YH1cbiAgXVxuICBpZiAoZXhwcmVzc2lvbi5raW5kID09IFwiVW5hcnlFeHByZXNzaW9uXCIpIHJldHVybiBbe2V4cHJlc3Npb246IGV4cHJlc3Npb24ub3BlcmFuZCwgcGF0aDogYCR7cGF0aH0vb3BlcmFuZGB9XVxuICBpZiAoZXhwcmVzc2lvbi5raW5kID09IFwiT3B0aW9uYWxTb21lXCIpIHJldHVybiBbe2V4cHJlc3Npb246IGV4cHJlc3Npb24udmFsdWUsIHBhdGg6IGAke3BhdGh9L3ZhbHVlYH1dXG4gIGlmIChleHByZXNzaW9uLmtpbmQgPT0gXCJPcHRpb25hbElzUHJlc2VudFwiIHx8IGV4cHJlc3Npb24ua2luZCA9PSBcIk9wdGlvbmFsVW53cmFwXCIpIHtcbiAgICByZXR1cm4gW3tleHByZXNzaW9uOiBleHByZXNzaW9uLm9wZXJhbmQsIHBhdGg6IGAke3BhdGh9L29wZXJhbmRgfV1cbiAgfVxuICBpZiAoZXhwcmVzc2lvbi5raW5kID09IFwiTGlzdExpdGVyYWxcIikgcmV0dXJuIGV4cHJlc3Npb24uZWxlbWVudHMubWFwKChjaGlsZCwgaW5kZXgpID0+ICh7ZXhwcmVzc2lvbjogY2hpbGQsIHBhdGg6IGAke3BhdGh9L2VsZW1lbnRzLyR7aW5kZXh9YH0pKVxuICBpZiAoZXhwcmVzc2lvbi5raW5kID09IFwiTWFwTGl0ZXJhbFwiIHx8IGV4cHJlc3Npb24ua2luZCA9PSBcIk9yZGVyZWRNYXBMaXRlcmFsXCIpIHJldHVybiBleHByZXNzaW9uLmVudHJpZXMuZmxhdE1hcCgoZW50cnksIGluZGV4KSA9PiBbXG4gICAge2V4cHJlc3Npb246IGVudHJ5LmtleSwgcGF0aDogYCR7cGF0aH0vZW50cmllcy8ke2luZGV4fS9rZXlgfSwge2V4cHJlc3Npb246IGVudHJ5LnZhbHVlLCBwYXRoOiBgJHtwYXRofS9lbnRyaWVzLyR7aW5kZXh9L3ZhbHVlYH1cbiAgXSlcbiAgaWYgKGV4cHJlc3Npb24ua2luZCA9PSBcIkxpc3RJbmRleEV4cHJlc3Npb25cIikgcmV0dXJuIFtcbiAgICB7ZXhwcmVzc2lvbjogZXhwcmVzc2lvbi5jb2xsZWN0aW9uLCBwYXRoOiBgJHtwYXRofS9jb2xsZWN0aW9uYH0sIHtleHByZXNzaW9uOiBleHByZXNzaW9uLmluZGV4LCBwYXRoOiBgJHtwYXRofS9pbmRleGB9XG4gIF1cbiAgaWYgKGV4cHJlc3Npb24ua2luZCA9PSBcIk1hcExvb2t1cEV4cHJlc3Npb25cIikgcmV0dXJuIFtcbiAgICB7ZXhwcmVzc2lvbjogZXhwcmVzc2lvbi5jb2xsZWN0aW9uLCBwYXRoOiBgJHtwYXRofS9jb2xsZWN0aW9uYH0sIHtleHByZXNzaW9uOiBleHByZXNzaW9uLmtleSwgcGF0aDogYCR7cGF0aH0va2V5YH1cbiAgXVxuICBpZiAoZXhwcmVzc2lvbi5raW5kID09IFwiQ29sbGVjdGlvblNpemVFeHByZXNzaW9uXCIpIHJldHVybiBbe2V4cHJlc3Npb246IGV4cHJlc3Npb24uY29sbGVjdGlvbiwgcGF0aDogYCR7cGF0aH0vY29sbGVjdGlvbmB9XVxuICBpZiAoZXhwcmVzc2lvbi5raW5kID09IFwiTWVtYmVyUmVhZFwiKSByZXR1cm4gW3tleHByZXNzaW9uOiBleHByZXNzaW9uLnJlY2VpdmVyLCBwYXRoOiBgJHtwYXRofS9yZWNlaXZlcmB9XVxuICByZXR1cm4gW11cbn1cblxuLyoqXG4gKiBDaGVja3Mgd2hldGhlciBnZW5lcmF0ZWQgc3VwcG9ydCBpcyByZXF1aXJlZCBieSBhIHNlbWFudGljIGNhcGFiaWxpdHkgbm9kZSBvciB0eXBlLlxuICogQHBhcmFtIHtpbXBvcnQoXCIuLi9zZW1hbnRpYy90eXBlcy5qc1wiKS5TZW1hbnRpY01vZHVsZX0gbW9kdWxlIC0gU2VtYW50aWMgbW9kdWxlLlxuICogQHJldHVybnMge2Jvb2xlYW59IFdoZXRoZXIgdGhlIHByb3RlY3RlZCBiaW5kaW5nIGlzIHJlcXVpcmVkLlxuICovXG5mdW5jdGlvbiBtb2R1bGVOZWVkc0VmZmVjdFN1cHBvcnQobW9kdWxlKSB7XG4gIC8qKiBAdHlwZSB7dW5rbm93bltdfSAqL1xuICBjb25zdCBwZW5kaW5nID0gW21vZHVsZS5lbnRyeVBvaW50LCAuLi5tb2R1bGUuZnVuY3Rpb25zLCAuLi5tb2R1bGUucmVjb3JkcyA/PyBbXSwgLi4ubW9kdWxlLmVycm9ycyA/PyBbXSwgLi4ubW9kdWxlLmNsYXNzZXMgPz8gW11dXG4gIGNvbnN0IHNlZW4gPSBuZXcgU2V0KClcblxuICB3aGlsZSAocGVuZGluZy5sZW5ndGggPiAwKSB7XG4gICAgY29uc3QgdmFsdWUgPSBwZW5kaW5nLnBvcCgpXG5cbiAgICBpZiAoIXZhbHVlIHx8IHR5cGVvZiB2YWx1ZSAhPSBcIm9iamVjdFwiIHx8IHNlZW4uaGFzKHZhbHVlKSkgY29udGludWVcbiAgICBzZWVuLmFkZCh2YWx1ZSlcbiAgICBjb25zdCBraW5kID0gUmVmbGVjdC5nZXQodmFsdWUsIFwia2luZFwiKVxuXG4gICAgaWYgKGtpbmQgPT0gXCJFZmZlY3RDYWxsRXhwcmVzc2lvblwiIHx8IGtpbmQgPT0gXCJPd25lZFJlc291cmNlVHlwZVwiIHx8IGtpbmQgPT0gXCJPd25lZFJlZmVyZW5jZVR5cGVcIiB8fFxuICAgICAga2luZCA9PSBcIkVycm9yVHlwZVwiICYmIC9eY2FwYWJpbGl0eTpbMC05XStcXC9mYWlsdXJlOlswLTldKyQvdS50ZXN0KFN0cmluZyhSZWZsZWN0LmdldCh2YWx1ZSwgXCJkZWNsYXJhdGlvbklkXCIpKSkpIHJldHVybiB0cnVlXG4gICAgZm9yIChjb25zdCBba2V5LCBjaGlsZF0gb2YgT2JqZWN0LmVudHJpZXModmFsdWUpKSB7XG4gICAgICBpZiAoW1wibG9jYXRpb25cIiwgXCJzb3VyY2VQcm92ZW5hbmNlXCJdLmluY2x1ZGVzKGtleSkpIGNvbnRpbnVlXG4gICAgICBpZiAoQXJyYXkuaXNBcnJheShjaGlsZCkpIHBlbmRpbmcucHVzaCguLi5jaGlsZClcbiAgICAgIGVsc2UgaWYgKGNoaWxkICYmIHR5cGVvZiBjaGlsZCA9PSBcIm9iamVjdFwiKSBwZW5kaW5nLnB1c2goY2hpbGQpXG4gICAgfVxuICB9XG4gIHJldHVybiBmYWxzZVxufVxuXG4vKipcbiAqIEZpbmRzIGEgY29udGV4dCBleGNsdWRlZCBmcm9tIGJvdW5kZWQgZWFnZXIgbG93ZXJpbmcuXG4gKiBAcGFyYW0ge2ltcG9ydChcIi4uL3NlbWFudGljL3R5cGVzLmpzXCIpLlNlbWFudGljTW9kdWxlfSBtb2R1bGUgLSBTZW1hbnRpYyBtb2R1bGUuXG4gKiBAcmV0dXJucyB7RXhjbHVkZWRFZmZlY3QgfCB1bmRlZmluZWR9IEZpcnN0IGRldGVybWluaXN0aWMgZXhjbHVzaW9uLlxuICovXG5mdW5jdGlvbiBmaW5kRXhjbHVkZWRFZmZlY3RDb250ZXh0KG1vZHVsZSkge1xuICAvKiogQHR5cGUge29iamVjdFtdfSAqL1xuICBjb25zdCBvd25lcnMgPSBbLi4ubW9kdWxlLmZ1bmN0aW9ucy5maWx0ZXIoKG93bmVyKSA9PiBvd25lciAmJiB0eXBlb2Ygb3duZXIgPT0gXCJvYmplY3RcIiksIG1vZHVsZS5lbnRyeVBvaW50XVxuXG4gIGZvciAoY29uc3QgZGVjbGFyYXRpb24gb2YgbW9kdWxlLmNsYXNzZXMgPz8gW10pIHtcbiAgICBpZiAoIWRlY2xhcmF0aW9uIHx8IHR5cGVvZiBkZWNsYXJhdGlvbiAhPSBcIm9iamVjdFwiKSBjb250aW51ZVxuICAgIGlmIChkZWNsYXJhdGlvbi5jb25zdHJ1Y3RvciAmJiB0eXBlb2YgZGVjbGFyYXRpb24uY29uc3RydWN0b3IgPT0gXCJvYmplY3RcIikgb3duZXJzLnB1c2goZGVjbGFyYXRpb24uY29uc3RydWN0b3IpXG4gICAgaWYgKEFycmF5LmlzQXJyYXkoZGVjbGFyYXRpb24ubWV0aG9kcykpIG93bmVycy5wdXNoKC4uLmRlY2xhcmF0aW9uLm1ldGhvZHMuZmlsdGVyKChvd25lcikgPT4gb3duZXIgJiYgdHlwZW9mIG93bmVyID09IFwib2JqZWN0XCIpKVxuICB9XG4gIGZvciAoY29uc3Qgb3duZXIgb2Ygb3duZXJzKSB7XG4gICAgY29uc3QgYm9keSA9IFJlZmxlY3QuZ2V0KG93bmVyLCBcImJvZHlcIilcblxuICAgIGlmICghYm9keSB8fCB0eXBlb2YgYm9keSAhPSBcIm9iamVjdFwiKSBjb250aW51ZVxuICAgIGNvbnN0IGZvdW5kID0gYmxvY2tFeGNsdWRlZCgvKiogQHR5cGUge2ltcG9ydChcIi4uL3NlbWFudGljL3R5cGVzLmpzXCIpLkJsb2NrfSAqLyAoYm9keSkpXG4gICAgaWYgKGZvdW5kKSByZXR1cm4gZm91bmRcbiAgfVxuICByZXR1cm4gdW5kZWZpbmVkXG59XG5cbi8qKlxuICogRmluZHMgYW4gZXhjbHVkZWQgY29udGV4dCBpbiBvbmUgc3RydWN0dXJlZCBibG9jay5cbiAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vc2VtYW50aWMvdHlwZXMuanNcIikuQmxvY2t9IGJsb2NrIC0gU2VtYW50aWMgYmxvY2suXG4gKiBAcmV0dXJucyB7RXhjbHVkZWRFZmZlY3QgfCB1bmRlZmluZWR9IEZpcnN0IGRldGVybWluaXN0aWMgZXhjbHVzaW9uLlxuICovXG5mdW5jdGlvbiBibG9ja0V4Y2x1ZGVkKGJsb2NrKSB7XG4gIGlmICghYmxvY2sgfHwgdHlwZW9mIGJsb2NrICE9IFwib2JqZWN0XCIgfHwgIUFycmF5LmlzQXJyYXkoYmxvY2suc3RhdGVtZW50cykpIHJldHVybiB1bmRlZmluZWRcbiAgZm9yIChjb25zdCBzdGF0ZW1lbnQgb2YgYmxvY2suc3RhdGVtZW50cykge1xuICAgIGlmICghc3RhdGVtZW50IHx8IHR5cGVvZiBzdGF0ZW1lbnQgIT0gXCJvYmplY3RcIikgY29udGludWVcbiAgICBpZiAoc3RhdGVtZW50LmtpbmQgPT0gXCJXaGlsZVN0YXRlbWVudFwiICYmIGNvbnRhaW5zRWZmZWN0KHN0YXRlbWVudC5jb25kaXRpb24pKSB7XG4gICAgICByZXR1cm4ge2RldGFpbDogXCJlZmZlY3RmdWwgY29uZGl0aW9uLWNvbnRyb2xsZWQgbG9vcCBjb25kaXRpb25cIiwgbG9jYXRpb246IHN0YXRlbWVudC5jb25kaXRpb24ubG9jYXRpb259XG4gICAgfVxuICAgIGNvbnN0IGV4cHJlc3Npb25zID0gc3RhdGVtZW50LmtpbmQgPT0gXCJMb2NhbERlY2xhcmF0aW9uXCIgPyBbc3RhdGVtZW50LmluaXRpYWxpemVyXSA6XG4gICAgICBzdGF0ZW1lbnQua2luZCA9PSBcIkFzc2lnbm1lbnRTdGF0ZW1lbnRcIiB8fCBzdGF0ZW1lbnQua2luZCA9PSBcIkV4cHJlc3Npb25TdGF0ZW1lbnRcIiB8fCBzdGF0ZW1lbnQua2luZCA9PSBcIlByaW50U3RhdGVtZW50XCIgPyBbc3RhdGVtZW50LmV4cHJlc3Npb25dIDpcbiAgICAgICAgc3RhdGVtZW50LmtpbmQgPT0gXCJSZXR1cm5TdGF0ZW1lbnRcIiA/IHN0YXRlbWVudC5leHByZXNzaW9uID8gW3N0YXRlbWVudC5leHByZXNzaW9uXSA6IFtdIDpcbiAgICAgICAgICBzdGF0ZW1lbnQua2luZCA9PSBcIklmU3RhdGVtZW50XCIgPyBbc3RhdGVtZW50LmNvbmRpdGlvbl0gOiBzdGF0ZW1lbnQua2luZCA9PSBcIkZvckVhY2hTdGF0ZW1lbnRcIiA/IFtzdGF0ZW1lbnQubGlzdF0gOlxuICAgICAgICAgICAgc3RhdGVtZW50LmtpbmQgPT0gXCJGb3JFYWNoTWFwU3RhdGVtZW50XCIgPyBbc3RhdGVtZW50Lm1hcF0gOiBzdGF0ZW1lbnQua2luZCA9PSBcIlByaXZhdGVGaWVsZFdyaXRlU3RhdGVtZW50XCIgPyBbc3RhdGVtZW50LmV4cHJlc3Npb25dIDpcbiAgICAgICAgICAgICAgc3RhdGVtZW50LmtpbmQgPT0gXCJSYWlzZVN0YXRlbWVudFwiID8gW3N0YXRlbWVudC5lcnJvci5tZXNzYWdlXSA6IFtdXG4gICAgZm9yIChjb25zdCBleHByZXNzaW9uIG9mIGV4cHJlc3Npb25zKSB7XG4gICAgICBjb25zdCBjb25kaXRpb25hbCA9IGZpbmRDb25kaXRpb25hbEVmZmVjdChleHByZXNzaW9uKVxuICAgICAgaWYgKGNvbmRpdGlvbmFsKSByZXR1cm4ge2RldGFpbDogXCJlZmZlY3RmdWwgc2hvcnQtY2lyY3VpdCBCb29sZWFuQW5kL0Jvb2xlYW5PciBleHByZXNzaW9uXCIsIGxvY2F0aW9uOiBjb25kaXRpb25hbC5sb2NhdGlvbn1cbiAgICB9XG4gICAgY29uc3QgbmVzdGVkID0gc3RhdGVtZW50LmtpbmQgPT0gXCJJZlN0YXRlbWVudFwiID8gW3N0YXRlbWVudC5jb25zZXF1ZW50LCAuLi4oc3RhdGVtZW50LmFsdGVybmF0ZSA/IFtzdGF0ZW1lbnQuYWx0ZXJuYXRlXSA6IFtdKV0gOlxuICAgICAgc3RhdGVtZW50LmtpbmQgPT0gXCJGb3JFYWNoU3RhdGVtZW50XCIgfHwgc3RhdGVtZW50LmtpbmQgPT0gXCJGb3JFYWNoTWFwU3RhdGVtZW50XCIgfHwgc3RhdGVtZW50LmtpbmQgPT0gXCJXaGlsZVN0YXRlbWVudFwiID8gW3N0YXRlbWVudC5ib2R5XSA6XG4gICAgICAgIHN0YXRlbWVudC5raW5kID09IFwiVHJ5U3RhdGVtZW50XCIgPyBbc3RhdGVtZW50LmJvZHksIHN0YXRlbWVudC5jYXRjaEJvZHldIDogW11cbiAgICBmb3IgKGNvbnN0IGNoaWxkIG9mIG5lc3RlZCkge1xuICAgICAgY29uc3QgZm91bmQgPSBibG9ja0V4Y2x1ZGVkKGNoaWxkKVxuICAgICAgaWYgKGZvdW5kKSByZXR1cm4gZm91bmRcbiAgICB9XG4gIH1cbiAgcmV0dXJuIHVuZGVmaW5lZFxufVxuXG4vKipcbiAqIEZpbmRzIGFuIGVmZmVjdCBiZWxvdyBhIHNob3J0LWNpcmN1aXQgb3BlcmF0b3IuXG4gKiBAcGFyYW0ge2ltcG9ydChcIi4uL3NlbWFudGljL3R5cGVzLmpzXCIpLkV4cHJlc3Npb259IGV4cHJlc3Npb24gLSBFeHByZXNzaW9uIHJvb3QuXG4gKiBAcmV0dXJucyB7aW1wb3J0KFwiLi4vc2VtYW50aWMvdHlwZXMuanNcIikuRXhwcmVzc2lvbiB8IHVuZGVmaW5lZH0gSW52YWxpZCBjb25kaXRpb25hbCBlZmZlY3QuXG4gKi9cbmZ1bmN0aW9uIGZpbmRDb25kaXRpb25hbEVmZmVjdChleHByZXNzaW9uKSB7XG4gIGlmICghZXhwcmVzc2lvbiB8fCB0eXBlb2YgZXhwcmVzc2lvbiAhPSBcIm9iamVjdFwiKSByZXR1cm4gdW5kZWZpbmVkXG4gIGlmIChleHByZXNzaW9uLmtpbmQgPT0gXCJCaW5hcnlFeHByZXNzaW9uXCIgJiYgW1wiQm9vbGVhbkFuZFwiLCBcIkJvb2xlYW5PclwiXS5pbmNsdWRlcyhleHByZXNzaW9uLm9wZXJhdGlvbikgJiZcbiAgICAoY29udGFpbnNFZmZlY3QoZXhwcmVzc2lvbi5sZWZ0KSB8fCBjb250YWluc0VmZmVjdChleHByZXNzaW9uLnJpZ2h0KSkpIHJldHVybiBleHByZXNzaW9uXG4gIGZvciAoY29uc3QgY2hpbGQgb2YgY2hpbGRyZW4oZXhwcmVzc2lvbikpIHtcbiAgICBjb25zdCBmb3VuZCA9IGZpbmRDb25kaXRpb25hbEVmZmVjdChjaGlsZClcbiAgICBpZiAoZm91bmQpIHJldHVybiBmb3VuZFxuICB9XG4gIHJldHVybiB1bmRlZmluZWRcbn1cblxuLyoqXG4gKiBDaGVja3Mgd2hldGhlciBhbiBleHByZXNzaW9uIGV2YWx1YXRlcyBhbiBlZmZlY3QuXG4gKiBAcGFyYW0ge2ltcG9ydChcIi4uL3NlbWFudGljL3R5cGVzLmpzXCIpLkV4cHJlc3Npb259IGV4cHJlc3Npb24gLSBFeHByZXNzaW9uIHJvb3QuXG4gKiBAcmV0dXJucyB7Ym9vbGVhbn0gV2hldGhlciBhbiBlZmZlY3QgaXMgcmVhY2hhYmxlLlxuICovXG5mdW5jdGlvbiBjb250YWluc0VmZmVjdChleHByZXNzaW9uKSB7XG4gIGlmICghZXhwcmVzc2lvbiB8fCB0eXBlb2YgZXhwcmVzc2lvbiAhPSBcIm9iamVjdFwiKSByZXR1cm4gZmFsc2VcbiAgcmV0dXJuIGV4cHJlc3Npb24ua2luZCA9PSBcIkVmZmVjdENhbGxFeHByZXNzaW9uXCIgfHwgQm9vbGVhbihSZWZsZWN0LmdldChleHByZXNzaW9uLCBcImVmZmVjdFNpdGVJZFwiKSkgfHwgY2hpbGRyZW4oZXhwcmVzc2lvbikuc29tZShjb250YWluc0VmZmVjdClcbn1cblxuLyoqXG4gKiBSZXR1cm5zIGNoaWxkIGV4cHJlc3Npb25zIGluIGV2YWx1YXRpb24gb3JkZXIuXG4gKiBAcGFyYW0ge2ltcG9ydChcIi4uL3NlbWFudGljL3R5cGVzLmpzXCIpLkV4cHJlc3Npb259IGV4cHJlc3Npb24gLSBQYXJlbnQgZXhwcmVzc2lvbi5cbiAqIEByZXR1cm5zIHtpbXBvcnQoXCIuLi9zZW1hbnRpYy90eXBlcy5qc1wiKS5FeHByZXNzaW9uW119IENoaWxkcmVuLlxuICovXG5mdW5jdGlvbiBjaGlsZHJlbihleHByZXNzaW9uKSB7XG4gIGlmICghZXhwcmVzc2lvbiB8fCB0eXBlb2YgZXhwcmVzc2lvbiAhPSBcIm9iamVjdFwiKSByZXR1cm4gW11cbiAgaWYgKGV4cHJlc3Npb24ua2luZCA9PSBcIkNhbGxFeHByZXNzaW9uXCIgfHwgZXhwcmVzc2lvbi5raW5kID09IFwiRWZmZWN0Q2FsbEV4cHJlc3Npb25cIiB8fCBleHByZXNzaW9uLmtpbmQgPT0gXCJSZWZlcmVuY2VDb25zdHJ1Y3Rpb25cIiB8fFxuICAgIGV4cHJlc3Npb24ua2luZCA9PSBcIlJlY29yZENvbnN0cnVjdGlvblwiKSByZXR1cm4gZXhwcmVzc2lvbi5hcmd1bWVudHNcbiAgaWYgKGV4cHJlc3Npb24ua2luZCA9PSBcIk1ldGhvZENhbGxFeHByZXNzaW9uXCIpIHJldHVybiBbZXhwcmVzc2lvbi5yZWNlaXZlciwgLi4uZXhwcmVzc2lvbi5hcmd1bWVudHNdXG4gIGlmIChleHByZXNzaW9uLmtpbmQgPT0gXCJPd25lZE1vdmVFeHByZXNzaW9uXCIgfHwgZXhwcmVzc2lvbi5raW5kID09IFwiT3duZWRCb3Jyb3dFeHByZXNzaW9uXCIpIHJldHVybiBbZXhwcmVzc2lvbi5leHByZXNzaW9uXVxuICBpZiAoZXhwcmVzc2lvbi5raW5kID09IFwiQmluYXJ5RXhwcmVzc2lvblwiKSByZXR1cm4gW2V4cHJlc3Npb24ubGVmdCwgZXhwcmVzc2lvbi5yaWdodF1cbiAgaWYgKGV4cHJlc3Npb24ua2luZCA9PSBcIlVuYXJ5RXhwcmVzc2lvblwiKSByZXR1cm4gW2V4cHJlc3Npb24ub3BlcmFuZF1cbiAgaWYgKGV4cHJlc3Npb24ua2luZCA9PSBcIk9wdGlvbmFsU29tZVwiKSByZXR1cm4gW2V4cHJlc3Npb24udmFsdWVdXG4gIGlmIChleHByZXNzaW9uLmtpbmQgPT0gXCJPcHRpb25hbElzUHJlc2VudFwiIHx8IGV4cHJlc3Npb24ua2luZCA9PSBcIk9wdGlvbmFsVW53cmFwXCIpIHJldHVybiBbZXhwcmVzc2lvbi5vcGVyYW5kXVxuICBpZiAoZXhwcmVzc2lvbi5raW5kID09IFwiTGlzdExpdGVyYWxcIikgcmV0dXJuIGV4cHJlc3Npb24uZWxlbWVudHNcbiAgaWYgKGV4cHJlc3Npb24ua2luZCA9PSBcIk1hcExpdGVyYWxcIiB8fCBleHByZXNzaW9uLmtpbmQgPT0gXCJPcmRlcmVkTWFwTGl0ZXJhbFwiKSByZXR1cm4gZXhwcmVzc2lvbi5lbnRyaWVzLmZsYXRNYXAoKHtrZXksIHZhbHVlfSkgPT4gW2tleSwgdmFsdWVdKVxuICBpZiAoZXhwcmVzc2lvbi5raW5kID09IFwiTGlzdEluZGV4RXhwcmVzc2lvblwiKSByZXR1cm4gW2V4cHJlc3Npb24uY29sbGVjdGlvbiwgZXhwcmVzc2lvbi5pbmRleF1cbiAgaWYgKGV4cHJlc3Npb24ua2luZCA9PSBcIk1hcExvb2t1cEV4cHJlc3Npb25cIikgcmV0dXJuIFtleHByZXNzaW9uLmNvbGxlY3Rpb24sIGV4cHJlc3Npb24ua2V5XVxuICBpZiAoZXhwcmVzc2lvbi5raW5kID09IFwiQ29sbGVjdGlvblNpemVFeHByZXNzaW9uXCIpIHJldHVybiBbZXhwcmVzc2lvbi5jb2xsZWN0aW9uXVxuICBpZiAoZXhwcmVzc2lvbi5raW5kID09IFwiTWVtYmVyUmVhZFwiKSByZXR1cm4gW2V4cHJlc3Npb24ucmVjZWl2ZXJdXG4gIHJldHVybiBbXVxufVxuXG5jb25zdCBwaHBTdXBwb3J0ID0gYC8qIHNlbWFudGlmb2xkLXRhc2swMzQtc3VwcG9ydCAqL1xuZmluYWwgY2xhc3MgUHJvYmVPcGVyYXRpb25GYWlsdXJlIGV4dGVuZHMgUnVudGltZUV4Y2VwdGlvbiB7fVxuZmluYWwgY2xhc3MgUHJvYmVBY3F1aXJlRmFpbHVyZSBleHRlbmRzIFJ1bnRpbWVFeGNlcHRpb24ge31cbmZpbmFsIGNsYXNzIFByb2JlUmVhZEZhaWx1cmUgZXh0ZW5kcyBSdW50aW1lRXhjZXB0aW9uIHt9XG5maW5hbCBjbGFzcyBQcm9iZUNsb3NlRmFpbHVyZSBleHRlbmRzIFJ1bnRpbWVFeGNlcHRpb24ge31cbmZpbmFsIGNsYXNzIFByb2JlUmVzb3VyY2VDbG9zZWQgZXh0ZW5kcyBSdW50aW1lRXhjZXB0aW9uIHt9XG5maW5hbCBjbGFzcyBQcm9iZVJlc291cmNlIHtcbiAgICBwdWJsaWMgYm9vbCAkY2xvc2VkID0gZmFsc2U7XG4gICAgcHVibGljIGZ1bmN0aW9uIF9fY29uc3RydWN0KHB1YmxpYyBtaXhlZCAkaGFuZGxlKSB7fVxufVxuJEdMT0JBTFNbJ19fc2VtYW50aWZvbGRfdGFzazAzNF90cmFjZSddID0gW107XG5mdW5jdGlvbiBwcm9iZUVmZmVjdChzdHJpbmcgJGxhYmVsLCBpbnQgJHZhbHVlLCBib29sICRmYWlsKTogaW50IHtcbiAgICAkR0xPQkFMU1snX19zZW1hbnRpZm9sZF90YXNrMDM0X3RyYWNlJ11bXSA9ICdlZmZlY3Q6JyAuICRsYWJlbDtcbiAgICBpZiAoJGZhaWwpIHRocm93IG5ldyBQcm9iZU9wZXJhdGlvbkZhaWx1cmUoJ1Byb2JlT3BlcmF0aW9uRmFpbHVyZScpO1xuICAgIHJldHVybiAkdmFsdWU7XG59XG5mdW5jdGlvbiBwcm9iZUFjcXVpcmUoYm9vbCAkZmFpbCk6IFByb2JlUmVzb3VyY2Uge1xuICAgICRHTE9CQUxTWydfX3NlbWFudGlmb2xkX3Rhc2swMzRfdHJhY2UnXVtdID0gJ2FjcXVpcmUnO1xuICAgIGlmICgkZmFpbCkgdGhyb3cgbmV3IFByb2JlQWNxdWlyZUZhaWx1cmUoJ1Byb2JlQWNxdWlyZUZhaWx1cmUnKTtcbiAgICB0cnkgeyAkaGFuZGxlID0gQGZvcGVuKChzdHJpbmcpIGdldGVudignU0VNQU5USUZPTERfVEFTSzAzNF9QUk9CRV9QQVRIJyksICdyYicpOyB9XG4gICAgY2F0Y2ggKFRocm93YWJsZSkgeyB0aHJvdyBuZXcgUHJvYmVBY3F1aXJlRmFpbHVyZSgnUHJvYmVBY3F1aXJlRmFpbHVyZScpOyB9XG4gICAgaWYgKCRoYW5kbGUgPT09IGZhbHNlKSB0aHJvdyBuZXcgUHJvYmVBY3F1aXJlRmFpbHVyZSgnUHJvYmVBY3F1aXJlRmFpbHVyZScpO1xuICAgIHJldHVybiBuZXcgUHJvYmVSZXNvdXJjZSgkaGFuZGxlKTtcbn1cbmZ1bmN0aW9uIHByb2JlUmVhZChQcm9iZVJlc291cmNlICRyZXNvdXJjZSwgYm9vbCAkZmFpbCk6ID9zdHJpbmcge1xuICAgIGlmICgkcmVzb3VyY2UtPmNsb3NlZCkgdGhyb3cgbmV3IFByb2JlUmVzb3VyY2VDbG9zZWQoJ1Byb2JlUmVzb3VyY2VDbG9zZWQnKTtcbiAgICAkR0xPQkFMU1snX19zZW1hbnRpZm9sZF90YXNrMDM0X3RyYWNlJ11bXSA9ICdyZWFkJztcbiAgICBpZiAoJGZhaWwpIHRocm93IG5ldyBQcm9iZVJlYWRGYWlsdXJlKCdQcm9iZVJlYWRGYWlsdXJlJyk7XG4gICAgdHJ5IHsgJGxpbmUgPSBAZmdldHMoJHJlc291cmNlLT5oYW5kbGUpOyB9XG4gICAgY2F0Y2ggKFRocm93YWJsZSkgeyB0aHJvdyBuZXcgUHJvYmVSZWFkRmFpbHVyZSgnUHJvYmVSZWFkRmFpbHVyZScpOyB9XG4gICAgaWYgKCRsaW5lID09PSBmYWxzZSkge1xuICAgICAgICBpZiAoZmVvZigkcmVzb3VyY2UtPmhhbmRsZSkpIHJldHVybiBudWxsO1xuICAgICAgICB0aHJvdyBuZXcgUHJvYmVSZWFkRmFpbHVyZSgnUHJvYmVSZWFkRmFpbHVyZScpO1xuICAgIH1cbiAgICByZXR1cm4gcnRyaW0oJGxpbmUsIFwiXFxcXHJcXFxcblwiKTtcbn1cbmZ1bmN0aW9uIHByb2JlQ2xvc2UoUHJvYmVSZXNvdXJjZSAkcmVzb3VyY2UsIGJvb2wgJGZhaWwpOiB2b2lkIHtcbiAgICBpZiAoJHJlc291cmNlLT5jbG9zZWQpIHRocm93IG5ldyBQcm9iZVJlc291cmNlQ2xvc2VkKCdQcm9iZVJlc291cmNlQ2xvc2VkJyk7XG4gICAgJEdMT0JBTFNbJ19fc2VtYW50aWZvbGRfdGFzazAzNF90cmFjZSddW10gPSAnY2xvc2UnO1xuICAgIHRyeSB7ICRjbG9zZWQgPSBAZmNsb3NlKCRyZXNvdXJjZS0+aGFuZGxlKTsgfVxuICAgIGNhdGNoIChUaHJvd2FibGUpIHsgJHJlc291cmNlLT5jbG9zZWQgPSB0cnVlOyB0aHJvdyBuZXcgUHJvYmVDbG9zZUZhaWx1cmUoJ1Byb2JlQ2xvc2VGYWlsdXJlJyk7IH1cbiAgICAkcmVzb3VyY2UtPmNsb3NlZCA9IHRydWU7XG4gICAgaWYgKCRmYWlsIHx8ICEkY2xvc2VkKSB0aHJvdyBuZXcgUHJvYmVDbG9zZUZhaWx1cmUoJ1Byb2JlQ2xvc2VGYWlsdXJlJyk7XG59XG5mdW5jdGlvbiBwcm9iZVRyYWNlKCk6IHN0cmluZyB7IHJldHVybiBpbXBsb2RlKCcsJywgJEdMT0JBTFNbJ19fc2VtYW50aWZvbGRfdGFzazAzNF90cmFjZSddKTsgfVxuLyogc2VtYW50aWZvbGQtdGFzazAzNC1zdXBwb3J0LWVuZCAqL1xuXG5gXG5cbmNvbnN0IHJ1YnlTdXBwb3J0ID0gYCMgc2VtYW50aWZvbGQtdGFzazAzNC1zdXBwb3J0XG5jbGFzcyBQcm9iZU9wZXJhdGlvbkZhaWx1cmUgPCBTdGFuZGFyZEVycm9yOyBlbmRcbmNsYXNzIFByb2JlQWNxdWlyZUZhaWx1cmUgPCBTdGFuZGFyZEVycm9yOyBlbmRcbmNsYXNzIFByb2JlUmVhZEZhaWx1cmUgPCBTdGFuZGFyZEVycm9yOyBlbmRcbmNsYXNzIFByb2JlQ2xvc2VGYWlsdXJlIDwgU3RhbmRhcmRFcnJvcjsgZW5kXG5jbGFzcyBQcm9iZVJlc291cmNlQ2xvc2VkIDwgU3RhbmRhcmRFcnJvcjsgZW5kXG5jbGFzcyBQcm9iZVJlc291cmNlXG4gIGF0dHJfYWNjZXNzb3IgOmhhbmRsZSwgOmNsb3NlZFxuICBkZWYgaW5pdGlhbGl6ZShoYW5kbGUpOyBAaGFuZGxlID0gaGFuZGxlOyBAY2xvc2VkID0gZmFsc2U7IGVuZFxuZW5kXG4kX19zZW1hbnRpZm9sZF90YXNrMDM0X3RyYWNlID0gW11cbmRlZiBwcm9iZUVmZmVjdChsYWJlbCwgdmFsdWUsIGZhaWxfdmFsdWUpXG4gICRfX3NlbWFudGlmb2xkX3Rhc2swMzRfdHJhY2UgPDwgXCJlZmZlY3Q6I3tsYWJlbH1cIlxuICByYWlzZSBQcm9iZU9wZXJhdGlvbkZhaWx1cmUsIFwiUHJvYmVPcGVyYXRpb25GYWlsdXJlXCIgaWYgZmFpbF92YWx1ZVxuICB2YWx1ZVxuZW5kXG5kZWYgcHJvYmVBY3F1aXJlKGZhaWxfdmFsdWUpXG4gICRfX3NlbWFudGlmb2xkX3Rhc2swMzRfdHJhY2UgPDwgXCJhY3F1aXJlXCJcbiAgcmFpc2UgUHJvYmVBY3F1aXJlRmFpbHVyZSwgXCJQcm9iZUFjcXVpcmVGYWlsdXJlXCIgaWYgZmFpbF92YWx1ZVxuICBiZWdpbjsgUHJvYmVSZXNvdXJjZS5uZXcoRmlsZS5vcGVuKEVOVi5mZXRjaChcIlNFTUFOVElGT0xEX1RBU0swMzRfUFJPQkVfUEFUSFwiKSwgXCJyXCIpKTsgcmVzY3VlIFByb2JlQWNxdWlyZUZhaWx1cmU7IHJhaXNlOyByZXNjdWUgU3RhbmRhcmRFcnJvcjsgcmFpc2UgUHJvYmVBY3F1aXJlRmFpbHVyZSwgXCJQcm9iZUFjcXVpcmVGYWlsdXJlXCI7IGVuZFxuZW5kXG5kZWYgcHJvYmVSZWFkKHJlc291cmNlLCBmYWlsX3ZhbHVlKVxuICByYWlzZSBQcm9iZVJlc291cmNlQ2xvc2VkLCBcIlByb2JlUmVzb3VyY2VDbG9zZWRcIiBpZiByZXNvdXJjZS5jbG9zZWRcbiAgJF9fc2VtYW50aWZvbGRfdGFzazAzNF90cmFjZSA8PCBcInJlYWRcIlxuICByYWlzZSBQcm9iZVJlYWRGYWlsdXJlLCBcIlByb2JlUmVhZEZhaWx1cmVcIiBpZiBmYWlsX3ZhbHVlXG4gIGJlZ2luOyB2YWx1ZSA9IHJlc291cmNlLmhhbmRsZS5nZXRzOyB2YWx1ZS5uaWw/ID8gbmlsIDogdmFsdWUuY2hvbXA7IHJlc2N1ZSBQcm9iZVJlYWRGYWlsdXJlOyByYWlzZTsgcmVzY3VlIFN0YW5kYXJkRXJyb3I7IHJhaXNlIFByb2JlUmVhZEZhaWx1cmUsIFwiUHJvYmVSZWFkRmFpbHVyZVwiOyBlbmRcbmVuZFxuZGVmIHByb2JlQ2xvc2UocmVzb3VyY2UsIGZhaWxfdmFsdWUpXG4gIHJhaXNlIFByb2JlUmVzb3VyY2VDbG9zZWQsIFwiUHJvYmVSZXNvdXJjZUNsb3NlZFwiIGlmIHJlc291cmNlLmNsb3NlZFxuICAkX19zZW1hbnRpZm9sZF90YXNrMDM0X3RyYWNlIDw8IFwiY2xvc2VcIlxuICBiZWdpbjsgcmVzb3VyY2UuaGFuZGxlLmNsb3NlOyByZXNjdWUgU3RhbmRhcmRFcnJvcjsgcmVzb3VyY2UuY2xvc2VkID0gdHJ1ZTsgcmFpc2UgUHJvYmVDbG9zZUZhaWx1cmUsIFwiUHJvYmVDbG9zZUZhaWx1cmVcIjsgZW5kXG4gIHJlc291cmNlLmNsb3NlZCA9IHRydWVcbiAgcmFpc2UgUHJvYmVDbG9zZUZhaWx1cmUsIFwiUHJvYmVDbG9zZUZhaWx1cmVcIiBpZiBmYWlsX3ZhbHVlXG4gIG5pbFxuZW5kXG5kZWYgcHJvYmVUcmFjZTsgJF9fc2VtYW50aWZvbGRfdGFzazAzNF90cmFjZS5qb2luKFwiLFwiKTsgZW5kXG4jIHNlbWFudGlmb2xkLXRhc2swMzQtc3VwcG9ydC1lbmRcblxuYFxuXG5jb25zdCBqYXZhc2NyaXB0U3VwcG9ydCA9IGAvKiBzZW1hbnRpZm9sZC10YXNrMDM0LXN1cHBvcnQgKi9cbmNvbnN0IF9fc2VtYW50aWZvbGRUYXNrMDM0RnMgPSBwcm9jZXNzLmdldEJ1aWx0aW5Nb2R1bGUoXCJub2RlOmZzXCIpXG5jbGFzcyBQcm9iZU9wZXJhdGlvbkZhaWx1cmUgZXh0ZW5kcyBFcnJvciB7fVxuY2xhc3MgUHJvYmVBY3F1aXJlRmFpbHVyZSBleHRlbmRzIEVycm9yIHt9XG5jbGFzcyBQcm9iZVJlYWRGYWlsdXJlIGV4dGVuZHMgRXJyb3Ige31cbmNsYXNzIFByb2JlQ2xvc2VGYWlsdXJlIGV4dGVuZHMgRXJyb3Ige31cbmNsYXNzIFByb2JlUmVzb3VyY2VDbG9zZWQgZXh0ZW5kcyBFcnJvciB7fVxuY2xhc3MgUHJvYmVSZXNvdXJjZSB7IGNvbnN0cnVjdG9yKGhhbmRsZSkgeyB0aGlzLmhhbmRsZSA9IGhhbmRsZTsgdGhpcy5jbG9zZWQgPSBmYWxzZTsgdGhpcy5wb3NpdGlvbiA9IDAgfSB9XG5jb25zdCBfX3NlbWFudGlmb2xkVGFzazAzNFRyYWNlID0gW11cbmZ1bmN0aW9uIHByb2JlRWZmZWN0KGxhYmVsLCB2YWx1ZSwgZmFpbCkgeyBfX3NlbWFudGlmb2xkVGFzazAzNFRyYWNlLnB1c2goXFxgZWZmZWN0OlxcJHtsYWJlbH1cXGApOyBpZiAoZmFpbCkgdGhyb3cgbmV3IFByb2JlT3BlcmF0aW9uRmFpbHVyZShcIlByb2JlT3BlcmF0aW9uRmFpbHVyZVwiKTsgcmV0dXJuIHZhbHVlIH1cbmZ1bmN0aW9uIHByb2JlQWNxdWlyZShmYWlsKSB7IF9fc2VtYW50aWZvbGRUYXNrMDM0VHJhY2UucHVzaChcImFjcXVpcmVcIik7IGlmIChmYWlsKSB0aHJvdyBuZXcgUHJvYmVBY3F1aXJlRmFpbHVyZShcIlByb2JlQWNxdWlyZUZhaWx1cmVcIik7IHRyeSB7IHJldHVybiBuZXcgUHJvYmVSZXNvdXJjZShfX3NlbWFudGlmb2xkVGFzazAzNEZzLm9wZW5TeW5jKHByb2Nlc3MuZW52LlNFTUFOVElGT0xEX1RBU0swMzRfUFJPQkVfUEFUSCwgXCJyXCIpKSB9IGNhdGNoIHsgdGhyb3cgbmV3IFByb2JlQWNxdWlyZUZhaWx1cmUoXCJQcm9iZUFjcXVpcmVGYWlsdXJlXCIpIH0gfVxuZnVuY3Rpb24gcHJvYmVSZWFkKHJlc291cmNlLCBmYWlsKSB7IGlmIChyZXNvdXJjZS5jbG9zZWQpIHRocm93IG5ldyBQcm9iZVJlc291cmNlQ2xvc2VkKFwiUHJvYmVSZXNvdXJjZUNsb3NlZFwiKTsgX19zZW1hbnRpZm9sZFRhc2swMzRUcmFjZS5wdXNoKFwicmVhZFwiKTsgaWYgKGZhaWwpIHRocm93IG5ldyBQcm9iZVJlYWRGYWlsdXJlKFwiUHJvYmVSZWFkRmFpbHVyZVwiKTsgdHJ5IHsgY29uc3QgYnl0ZXMgPSBbXTsgY29uc3QgYnVmZmVyID0gQnVmZmVyLmFsbG9jKDEpOyB3aGlsZSAodHJ1ZSkgeyBjb25zdCBjb3VudCA9IF9fc2VtYW50aWZvbGRUYXNrMDM0RnMucmVhZFN5bmMocmVzb3VyY2UuaGFuZGxlLCBidWZmZXIsIDAsIDEsIHJlc291cmNlLnBvc2l0aW9uKyspOyBpZiAoY291bnQgPT09IDApIHJldHVybiBieXRlcy5sZW5ndGggPT09IDAgPyBudWxsIDogQnVmZmVyLmZyb20oYnl0ZXMpLnRvU3RyaW5nKFwidXRmOFwiKTsgaWYgKGJ1ZmZlclswXSA9PT0gMTApIHJldHVybiBCdWZmZXIuZnJvbShieXRlcykudG9TdHJpbmcoXCJ1dGY4XCIpLnJlcGxhY2UoL1xcXFxyJC91LCBcIlwiKTsgYnl0ZXMucHVzaChidWZmZXJbMF0pIH0gfSBjYXRjaCB7IHRocm93IG5ldyBQcm9iZVJlYWRGYWlsdXJlKFwiUHJvYmVSZWFkRmFpbHVyZVwiKSB9IH1cbmZ1bmN0aW9uIHByb2JlQ2xvc2UocmVzb3VyY2UsIGZhaWwpIHsgaWYgKHJlc291cmNlLmNsb3NlZCkgdGhyb3cgbmV3IFByb2JlUmVzb3VyY2VDbG9zZWQoXCJQcm9iZVJlc291cmNlQ2xvc2VkXCIpOyBfX3NlbWFudGlmb2xkVGFzazAzNFRyYWNlLnB1c2goXCJjbG9zZVwiKTsgdHJ5IHsgX19zZW1hbnRpZm9sZFRhc2swMzRGcy5jbG9zZVN5bmMocmVzb3VyY2UuaGFuZGxlKSB9IGNhdGNoIHsgcmVzb3VyY2UuY2xvc2VkID0gdHJ1ZTsgdGhyb3cgbmV3IFByb2JlQ2xvc2VGYWlsdXJlKFwiUHJvYmVDbG9zZUZhaWx1cmVcIikgfSByZXNvdXJjZS5jbG9zZWQgPSB0cnVlOyBpZiAoZmFpbCkgdGhyb3cgbmV3IFByb2JlQ2xvc2VGYWlsdXJlKFwiUHJvYmVDbG9zZUZhaWx1cmVcIikgfVxuZnVuY3Rpb24gcHJvYmVUcmFjZSgpIHsgcmV0dXJuIF9fc2VtYW50aWZvbGRUYXNrMDM0VHJhY2Uuam9pbihcIixcIikgfVxuLyogc2VtYW50aWZvbGQtdGFzazAzNC1zdXBwb3J0LWVuZCAqL1xuXG5gXG5cbmNvbnN0IHR5cGVzY3JpcHRTdXBwb3J0ID0gYC8qIHNlbWFudGlmb2xkLXRhc2swMzQtc3VwcG9ydCAqL1xuY29uc3QgX19zZW1hbnRpZm9sZFRhc2swMzRGcyA9IHByb2Nlc3MuZ2V0QnVpbHRpbk1vZHVsZShcIm5vZGU6ZnNcIilcbmNsYXNzIFByb2JlT3BlcmF0aW9uRmFpbHVyZSBleHRlbmRzIEVycm9yIHt9XG5jbGFzcyBQcm9iZUFjcXVpcmVGYWlsdXJlIGV4dGVuZHMgRXJyb3Ige31cbmNsYXNzIFByb2JlUmVhZEZhaWx1cmUgZXh0ZW5kcyBFcnJvciB7fVxuY2xhc3MgUHJvYmVDbG9zZUZhaWx1cmUgZXh0ZW5kcyBFcnJvciB7fVxuY2xhc3MgUHJvYmVSZXNvdXJjZUNsb3NlZCBleHRlbmRzIEVycm9yIHt9XG5jbGFzcyBQcm9iZVJlc291cmNlIHsgY2xvc2VkID0gZmFsc2U7IHBvc2l0aW9uID0gMDsgY29uc3RydWN0b3IocmVhZG9ubHkgaGFuZGxlOiBudW1iZXIpIHt9IH1cbmNvbnN0IF9fc2VtYW50aWZvbGRUYXNrMDM0VHJhY2U6IHN0cmluZ1tdID0gW11cbmZ1bmN0aW9uIHByb2JlRWZmZWN0KGxhYmVsOiBzdHJpbmcsIHZhbHVlOiBudW1iZXIsIGZhaWw6IGJvb2xlYW4pOiBudW1iZXIgeyBfX3NlbWFudGlmb2xkVGFzazAzNFRyYWNlLnB1c2goXFxgZWZmZWN0OlxcJHtsYWJlbH1cXGApOyBpZiAoZmFpbCkgdGhyb3cgbmV3IFByb2JlT3BlcmF0aW9uRmFpbHVyZShcIlByb2JlT3BlcmF0aW9uRmFpbHVyZVwiKTsgcmV0dXJuIHZhbHVlIH1cbmZ1bmN0aW9uIHByb2JlQWNxdWlyZShmYWlsOiBib29sZWFuKTogUHJvYmVSZXNvdXJjZSB7IF9fc2VtYW50aWZvbGRUYXNrMDM0VHJhY2UucHVzaChcImFjcXVpcmVcIik7IGlmIChmYWlsKSB0aHJvdyBuZXcgUHJvYmVBY3F1aXJlRmFpbHVyZShcIlByb2JlQWNxdWlyZUZhaWx1cmVcIik7IHRyeSB7IHJldHVybiBuZXcgUHJvYmVSZXNvdXJjZShfX3NlbWFudGlmb2xkVGFzazAzNEZzLm9wZW5TeW5jKHByb2Nlc3MuZW52LlNFTUFOVElGT0xEX1RBU0swMzRfUFJPQkVfUEFUSCBhcyBzdHJpbmcsIFwiclwiKSkgfSBjYXRjaCB7IHRocm93IG5ldyBQcm9iZUFjcXVpcmVGYWlsdXJlKFwiUHJvYmVBY3F1aXJlRmFpbHVyZVwiKSB9IH1cbmZ1bmN0aW9uIHByb2JlUmVhZChyZXNvdXJjZTogUHJvYmVSZXNvdXJjZSwgZmFpbDogYm9vbGVhbik6IHN0cmluZyB8IG51bGwgeyBpZiAocmVzb3VyY2UuY2xvc2VkKSB0aHJvdyBuZXcgUHJvYmVSZXNvdXJjZUNsb3NlZChcIlByb2JlUmVzb3VyY2VDbG9zZWRcIik7IF9fc2VtYW50aWZvbGRUYXNrMDM0VHJhY2UucHVzaChcInJlYWRcIik7IGlmIChmYWlsKSB0aHJvdyBuZXcgUHJvYmVSZWFkRmFpbHVyZShcIlByb2JlUmVhZEZhaWx1cmVcIik7IHRyeSB7IGNvbnN0IGJ5dGVzOiBudW1iZXJbXSA9IFtdOyBjb25zdCBidWZmZXIgPSBCdWZmZXIuYWxsb2MoMSk7IHdoaWxlICh0cnVlKSB7IGNvbnN0IGNvdW50ID0gX19zZW1hbnRpZm9sZFRhc2swMzRGcy5yZWFkU3luYyhyZXNvdXJjZS5oYW5kbGUsIGJ1ZmZlciwgMCwgMSwgcmVzb3VyY2UucG9zaXRpb24rKyk7IGlmIChjb3VudCA9PT0gMCkgcmV0dXJuIGJ5dGVzLmxlbmd0aCA9PT0gMCA/IG51bGwgOiBCdWZmZXIuZnJvbShieXRlcykudG9TdHJpbmcoXCJ1dGY4XCIpOyBpZiAoYnVmZmVyWzBdID09PSAxMCkgcmV0dXJuIEJ1ZmZlci5mcm9tKGJ5dGVzKS50b1N0cmluZyhcInV0ZjhcIikucmVwbGFjZSgvXFxcXHIkL3UsIFwiXCIpOyBieXRlcy5wdXNoKGJ1ZmZlclswXSkgfSB9IGNhdGNoIHsgdGhyb3cgbmV3IFByb2JlUmVhZEZhaWx1cmUoXCJQcm9iZVJlYWRGYWlsdXJlXCIpIH0gfVxuZnVuY3Rpb24gcHJvYmVDbG9zZShyZXNvdXJjZTogUHJvYmVSZXNvdXJjZSwgZmFpbDogYm9vbGVhbik6IHZvaWQgeyBpZiAocmVzb3VyY2UuY2xvc2VkKSB0aHJvdyBuZXcgUHJvYmVSZXNvdXJjZUNsb3NlZChcIlByb2JlUmVzb3VyY2VDbG9zZWRcIik7IF9fc2VtYW50aWZvbGRUYXNrMDM0VHJhY2UucHVzaChcImNsb3NlXCIpOyB0cnkgeyBfX3NlbWFudGlmb2xkVGFzazAzNEZzLmNsb3NlU3luYyhyZXNvdXJjZS5oYW5kbGUpIH0gY2F0Y2ggeyByZXNvdXJjZS5jbG9zZWQgPSB0cnVlOyB0aHJvdyBuZXcgUHJvYmVDbG9zZUZhaWx1cmUoXCJQcm9iZUNsb3NlRmFpbHVyZVwiKSB9IHJlc291cmNlLmNsb3NlZCA9IHRydWU7IGlmIChmYWlsKSB0aHJvdyBuZXcgUHJvYmVDbG9zZUZhaWx1cmUoXCJQcm9iZUNsb3NlRmFpbHVyZVwiKSB9XG5mdW5jdGlvbiBwcm9iZVRyYWNlKCk6IHN0cmluZyB7IHJldHVybiBfX3NlbWFudGlmb2xkVGFzazAzNFRyYWNlLmpvaW4oXCIsXCIpIH1cbi8qIHNlbWFudGlmb2xkLXRhc2swMzQtc3VwcG9ydC1lbmQgKi9cblxuYFxuXG5jb25zdCBqYXZhVG9wU3VwcG9ydCA9IGAvLyBzZW1hbnRpZm9sZC10YXNrMDM0LXN1cHBvcnRcbmZpbmFsIGNsYXNzIFByb2JlT3BlcmF0aW9uRmFpbHVyZSBleHRlbmRzIFJ1bnRpbWVFeGNlcHRpb24geyBQcm9iZU9wZXJhdGlvbkZhaWx1cmUoKSB7IHN1cGVyKFwiUHJvYmVPcGVyYXRpb25GYWlsdXJlXCIpOyB9IH1cbmZpbmFsIGNsYXNzIFByb2JlQWNxdWlyZUZhaWx1cmUgZXh0ZW5kcyBSdW50aW1lRXhjZXB0aW9uIHsgUHJvYmVBY3F1aXJlRmFpbHVyZSgpIHsgc3VwZXIoXCJQcm9iZUFjcXVpcmVGYWlsdXJlXCIpOyB9IH1cbmZpbmFsIGNsYXNzIFByb2JlUmVhZEZhaWx1cmUgZXh0ZW5kcyBSdW50aW1lRXhjZXB0aW9uIHsgUHJvYmVSZWFkRmFpbHVyZSgpIHsgc3VwZXIoXCJQcm9iZVJlYWRGYWlsdXJlXCIpOyB9IH1cbmZpbmFsIGNsYXNzIFByb2JlQ2xvc2VGYWlsdXJlIGV4dGVuZHMgUnVudGltZUV4Y2VwdGlvbiB7IFByb2JlQ2xvc2VGYWlsdXJlKCkgeyBzdXBlcihcIlByb2JlQ2xvc2VGYWlsdXJlXCIpOyB9IH1cbmZpbmFsIGNsYXNzIFByb2JlUmVzb3VyY2VDbG9zZWQgZXh0ZW5kcyBSdW50aW1lRXhjZXB0aW9uIHsgUHJvYmVSZXNvdXJjZUNsb3NlZCgpIHsgc3VwZXIoXCJQcm9iZVJlc291cmNlQ2xvc2VkXCIpOyB9IH1cbmZpbmFsIGNsYXNzIFByb2JlUmVzb3VyY2UgeyBmaW5hbCBqYXZhLm5pby5jaGFubmVscy5GaWxlQ2hhbm5lbCBoYW5kbGU7IGJvb2xlYW4gY2xvc2VkID0gZmFsc2U7IFByb2JlUmVzb3VyY2UoamF2YS5uaW8uY2hhbm5lbHMuRmlsZUNoYW5uZWwgaGFuZGxlKSB7IHRoaXMuaGFuZGxlID0gaGFuZGxlOyB9IH1cbi8vIHNlbWFudGlmb2xkLXRhc2swMzQtc3VwcG9ydC10b3AtZW5kXG5cbmBcblxuY29uc3QgamF2YU1lbWJlclN1cHBvcnQgPSBgICAvLyBzZW1hbnRpZm9sZC10YXNrMDM0LXN1cHBvcnQtbWVtYmVyc1xuICBwcml2YXRlIHN0YXRpYyBmaW5hbCBqYXZhLnV0aWwuQXJyYXlMaXN0PFN0cmluZz4gX19zZW1hbnRpZm9sZFRhc2swMzRUcmFjZSA9IG5ldyBqYXZhLnV0aWwuQXJyYXlMaXN0PD4oKTtcbiAgc3RhdGljIGludCBwcm9iZUVmZmVjdChTdHJpbmcgbGFiZWwsIGludCB2YWx1ZSwgYm9vbGVhbiBmYWlsKSB7IF9fc2VtYW50aWZvbGRUYXNrMDM0VHJhY2UuYWRkKFwiZWZmZWN0OlwiICsgbGFiZWwpOyBpZiAoZmFpbCkgdGhyb3cgbmV3IFByb2JlT3BlcmF0aW9uRmFpbHVyZSgpOyByZXR1cm4gdmFsdWU7IH1cbiAgc3RhdGljIFByb2JlUmVzb3VyY2UgcHJvYmVBY3F1aXJlKGJvb2xlYW4gZmFpbCkgeyBfX3NlbWFudGlmb2xkVGFzazAzNFRyYWNlLmFkZChcImFjcXVpcmVcIik7IGlmIChmYWlsKSB0aHJvdyBuZXcgUHJvYmVBY3F1aXJlRmFpbHVyZSgpOyB0cnkgeyByZXR1cm4gbmV3IFByb2JlUmVzb3VyY2UoamF2YS5uaW8uY2hhbm5lbHMuRmlsZUNoYW5uZWwub3BlbihqYXZhLm5pby5maWxlLlBhdGgub2YoU3lzdGVtLmdldGVudihcIlNFTUFOVElGT0xEX1RBU0swMzRfUFJPQkVfUEFUSFwiKSkpKTsgfSBjYXRjaCAoUnVudGltZUV4Y2VwdGlvbiB8IGphdmEuaW8uSU9FeGNlcHRpb24gZXhjZXB0aW9uKSB7IHRocm93IG5ldyBQcm9iZUFjcXVpcmVGYWlsdXJlKCk7IH0gfVxuICBzdGF0aWMgamF2YS51dGlsLk9wdGlvbmFsPFN0cmluZz4gcHJvYmVSZWFkKFByb2JlUmVzb3VyY2UgcmVzb3VyY2UsIGJvb2xlYW4gZmFpbCkgeyBpZiAocmVzb3VyY2UuY2xvc2VkKSB0aHJvdyBuZXcgUHJvYmVSZXNvdXJjZUNsb3NlZCgpOyBfX3NlbWFudGlmb2xkVGFzazAzNFRyYWNlLmFkZChcInJlYWRcIik7IGlmIChmYWlsKSB0aHJvdyBuZXcgUHJvYmVSZWFkRmFpbHVyZSgpOyB0cnkgeyBqYXZhLmlvLkJ5dGVBcnJheU91dHB1dFN0cmVhbSBieXRlcyA9IG5ldyBqYXZhLmlvLkJ5dGVBcnJheU91dHB1dFN0cmVhbSgpOyBqYXZhLm5pby5CeXRlQnVmZmVyIGJ1ZmZlciA9IGphdmEubmlvLkJ5dGVCdWZmZXIuYWxsb2NhdGUoMSk7IHdoaWxlICh0cnVlKSB7IGJ1ZmZlci5jbGVhcigpOyBpbnQgY291bnQgPSByZXNvdXJjZS5oYW5kbGUucmVhZChidWZmZXIpOyBpZiAoY291bnQgPCAwKSByZXR1cm4gYnl0ZXMuc2l6ZSgpID09IDAgPyBqYXZhLnV0aWwuT3B0aW9uYWwuZW1wdHkoKSA6IGphdmEudXRpbC5PcHRpb25hbC5vZihieXRlcy50b1N0cmluZyhqYXZhLm5pby5jaGFyc2V0LlN0YW5kYXJkQ2hhcnNldHMuVVRGXzgpKTsgYnVmZmVyLmZsaXAoKTsgYnl0ZSB2YWx1ZSA9IGJ1ZmZlci5nZXQoKTsgaWYgKHZhbHVlID09IDEwKSByZXR1cm4gamF2YS51dGlsLk9wdGlvbmFsLm9mKGJ5dGVzLnRvU3RyaW5nKGphdmEubmlvLmNoYXJzZXQuU3RhbmRhcmRDaGFyc2V0cy5VVEZfOCkucmVwbGFjZUZpcnN0KFwiXFxcXHIkXCIsIFwiXCIpKTsgYnl0ZXMud3JpdGUodmFsdWUpOyB9IH0gY2F0Y2ggKGphdmEuaW8uSU9FeGNlcHRpb24gZXhjZXB0aW9uKSB7IHRocm93IG5ldyBQcm9iZVJlYWRGYWlsdXJlKCk7IH0gfVxuICBzdGF0aWMgdm9pZCBwcm9iZUNsb3NlKFByb2JlUmVzb3VyY2UgcmVzb3VyY2UsIGJvb2xlYW4gZmFpbCkgeyBpZiAocmVzb3VyY2UuY2xvc2VkKSB0aHJvdyBuZXcgUHJvYmVSZXNvdXJjZUNsb3NlZCgpOyBfX3NlbWFudGlmb2xkVGFzazAzNFRyYWNlLmFkZChcImNsb3NlXCIpOyB0cnkgeyByZXNvdXJjZS5oYW5kbGUuY2xvc2UoKTsgfSBjYXRjaCAoamF2YS5pby5JT0V4Y2VwdGlvbiBleGNlcHRpb24pIHsgcmVzb3VyY2UuY2xvc2VkID0gdHJ1ZTsgdGhyb3cgbmV3IFByb2JlQ2xvc2VGYWlsdXJlKCk7IH0gcmVzb3VyY2UuY2xvc2VkID0gdHJ1ZTsgaWYgKGZhaWwpIHRocm93IG5ldyBQcm9iZUNsb3NlRmFpbHVyZSgpOyB9XG4gIHN0YXRpYyBTdHJpbmcgcHJvYmVUcmFjZSgpIHsgcmV0dXJuIFN0cmluZy5qb2luKFwiLFwiLCBfX3NlbWFudGlmb2xkVGFzazAzNFRyYWNlKTsgfVxuICAvLyBzZW1hbnRpZm9sZC10YXNrMDM0LXN1cHBvcnQtbWVtYmVycy1lbmRcblxuYFxuXG5jb25zdCBqYXZhUHJvZ3JhbU5lc3RlZFN1cHBvcnQgPSBgICAvLyBzZW1hbnRpZm9sZC10YXNrMDM0LXN1cHBvcnQtcHJvZ3JhbVxuICBwdWJsaWMgc3RhdGljIGZpbmFsIGNsYXNzIFByb2JlT3BlcmF0aW9uRmFpbHVyZSBleHRlbmRzIFJ1bnRpbWVFeGNlcHRpb24geyBQcm9iZU9wZXJhdGlvbkZhaWx1cmUoKSB7IHN1cGVyKFwiUHJvYmVPcGVyYXRpb25GYWlsdXJlXCIpOyB9IH1cbiAgcHVibGljIHN0YXRpYyBmaW5hbCBjbGFzcyBQcm9iZUFjcXVpcmVGYWlsdXJlIGV4dGVuZHMgUnVudGltZUV4Y2VwdGlvbiB7IFByb2JlQWNxdWlyZUZhaWx1cmUoKSB7IHN1cGVyKFwiUHJvYmVBY3F1aXJlRmFpbHVyZVwiKTsgfSB9XG4gIHB1YmxpYyBzdGF0aWMgZmluYWwgY2xhc3MgUHJvYmVSZWFkRmFpbHVyZSBleHRlbmRzIFJ1bnRpbWVFeGNlcHRpb24geyBQcm9iZVJlYWRGYWlsdXJlKCkgeyBzdXBlcihcIlByb2JlUmVhZEZhaWx1cmVcIik7IH0gfVxuICBwdWJsaWMgc3RhdGljIGZpbmFsIGNsYXNzIFByb2JlQ2xvc2VGYWlsdXJlIGV4dGVuZHMgUnVudGltZUV4Y2VwdGlvbiB7IFByb2JlQ2xvc2VGYWlsdXJlKCkgeyBzdXBlcihcIlByb2JlQ2xvc2VGYWlsdXJlXCIpOyB9IH1cbiAgcHVibGljIHN0YXRpYyBmaW5hbCBjbGFzcyBQcm9iZVJlc291cmNlQ2xvc2VkIGV4dGVuZHMgUnVudGltZUV4Y2VwdGlvbiB7IFByb2JlUmVzb3VyY2VDbG9zZWQoKSB7IHN1cGVyKFwiUHJvYmVSZXNvdXJjZUNsb3NlZFwiKTsgfSB9XG4gIHB1YmxpYyBzdGF0aWMgZmluYWwgY2xhc3MgUHJvYmVSZXNvdXJjZSB7IGZpbmFsIGphdmEubmlvLmNoYW5uZWxzLkZpbGVDaGFubmVsIGhhbmRsZTsgYm9vbGVhbiBjbG9zZWQgPSBmYWxzZTsgUHJvYmVSZXNvdXJjZShqYXZhLm5pby5jaGFubmVscy5GaWxlQ2hhbm5lbCBoYW5kbGUpIHsgdGhpcy5oYW5kbGUgPSBoYW5kbGU7IH0gfVxuICAvLyBzZW1hbnRpZm9sZC10YXNrMDM0LXN1cHBvcnQtcHJvZ3JhbS1lbmRcblxuYFxuXG4vKiogQHR5cGUge1JlY29yZDxzdHJpbmcsIHN0cmluZz59ICovXG5jb25zdCBqYXZhUHJvdmlkZXJTaGltcyA9IHtcbiAgcHJvYmVBY3F1aXJlOiBcInB1YmxpYyBzdGF0aWMgUHJvYmVSZXNvdXJjZSBfX3NlbWFudGlmb2xkX3Byb3ZpZGVyX2phdmFfcHJvYmVBY3F1aXJlKGJvb2xlYW4gZmFpbCkgeyByZXR1cm4gcHJvYmVBY3F1aXJlKGZhaWwpOyB9XCIsXG4gIHByb2JlQ2xvc2U6IFwicHVibGljIHN0YXRpYyB2b2lkIF9fc2VtYW50aWZvbGRfcHJvdmlkZXJfamF2YV9wcm9iZUNsb3NlKFByb2JlUmVzb3VyY2UgcmVzb3VyY2UsIGJvb2xlYW4gZmFpbCkgeyBwcm9iZUNsb3NlKHJlc291cmNlLCBmYWlsKTsgfVwiLFxuICBwcm9iZUVmZmVjdDogXCJwdWJsaWMgc3RhdGljIGludCBfX3NlbWFudGlmb2xkX3Byb3ZpZGVyX2phdmFfcHJvYmVFZmZlY3QoU3RyaW5nIGxhYmVsLCBpbnQgdmFsdWUsIGJvb2xlYW4gZmFpbCkgeyByZXR1cm4gcHJvYmVFZmZlY3QobGFiZWwsIHZhbHVlLCBmYWlsKTsgfVwiLFxuICBwcm9iZVJlYWQ6IFwicHVibGljIHN0YXRpYyBqYXZhLnV0aWwuT3B0aW9uYWw8U3RyaW5nPiBfX3NlbWFudGlmb2xkX3Byb3ZpZGVyX2phdmFfcHJvYmVSZWFkKFByb2JlUmVzb3VyY2UgcmVzb3VyY2UsIGJvb2xlYW4gZmFpbCkgeyByZXR1cm4gcHJvYmVSZWFkKHJlc291cmNlLCBmYWlsKTsgfVwiLFxuICBwcm9iZVRyYWNlOiBcInB1YmxpYyBzdGF0aWMgU3RyaW5nIF9fc2VtYW50aWZvbGRfcHJvdmlkZXJfamF2YV9wcm9iZVRyYWNlKCkgeyByZXR1cm4gcHJvYmVUcmFjZSgpOyB9XCJcbn1cbiJdfQ==