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,1167 @@
1
+ // @ts-check
2
+ import { isDenseArray } from "./array.js";
3
+ import { isSafeArtifactPath } from "./artifact-path.js";
4
+ import { SemantifoldDiagnostic } from "./diagnostic.js";
5
+ import { compareStdlibVersions, parseStdlibVersion, parseStdlibVersionRange, resolveStdlibModule, stdlibVersionSatisfies } from "./semantic/stdlib.js";
6
+ const facadeIdentityPattern = /^[a-z][a-z0-9.-]*$/u;
7
+ const moduleIdPattern = /^[a-z][a-z0-9_]*(?:[.-][a-z][a-z0-9_]*)*$/u;
8
+ const declarationNamePattern = /^[A-Za-z_][A-Za-z0-9_]*$/u;
9
+ const supportedLanguages = new Set(["php", "ruby", "javascript", "typescript", "java"]);
10
+ const canonicalTypes = new Set(["boolean", "integer", "string", "void"]);
11
+ /**
12
+ * @typedef StdlibFacadeFunctionDeclaration
13
+ * @property {"function"} kind - Closed public declaration kind.
14
+ * @property {string} name - Exact source-visible symbol.
15
+ * @property {{name: string, type: string}[]} parameters - Ordered source signature.
16
+ * @property {string} returnType - Canonical result type.
17
+ * @property {string[]} effects - Closed public effects.
18
+ * @property {string[]} failures - Escaping canonical failure names.
19
+ * @property {("direct-call" | "unqualified-call" | "receiver-call")[]} forms - Accepted source call forms.
20
+ * @property {"not-applicable"} ownership - Initial scalar qualification ownership.
21
+ */
22
+ /**
23
+ * @typedef StdlibFacadeClassDeclaration
24
+ * @property {"class"} kind - Closed public declaration kind.
25
+ * @property {string} name - Exact source-visible class symbol.
26
+ * @property {["constructor-call"]} forms - Accepted construction form.
27
+ * @property {"owned-reference"} ownership - Class instance ownership.
28
+ * @property {{effects: string[], failures: string[], ownership: "acquired", parameters: {name: string, type: string}[]}} constructor - Constructor contract.
29
+ * @property {{effects: string[], failures: string[], forms: ["receiver-call"], name: string, ownership: "borrowed" | "consumed", parameters: {name: string, type: string}[], returnType: string}[]} methods - Public instance methods.
30
+ */
31
+ /** @typedef {StdlibFacadeFunctionDeclaration | StdlibFacadeClassDeclaration} StdlibFacadePublicDeclaration */
32
+ /**
33
+ * @typedef StdlibFacadeRecord
34
+ * @property {{identity: string, range: string}[]} dependencies - Facade-module dependencies.
35
+ * @property {string} identity - Versioned facade identity.
36
+ * @property {import("./semantic/types.js").SemanticLanguage} language - Source language.
37
+ * @property {({identity: string, kind: "module", symbols: string[]} | {forms: ("unqualified-call" | "receiver-call")[], identity: string, kind: "builtin", symbols: string[]})[]} nativeModules - Exact source native identities.
38
+ * @property {StdlibFacadePublicDeclaration[]} publicDeclarations - Public source surface.
39
+ * @property {{module: string, operations: string[], range: string}[]} requirements - Canonical-only requirements.
40
+ * @property {string} runtimeProfile - Exact compatible source/runtime profile.
41
+ * @property {{content: string, filename: string, id: string}} source - Executable compiler-owned source module.
42
+ * @property {string} version - Exact facade version.
43
+ * @property {"internal" | "public"} visibility - Native-selectable visibility.
44
+ */
45
+ /**
46
+ * @typedef FacadeSourceNames
47
+ * @property {string} extension - Source filename extension.
48
+ * @property {string} nativeModule - Public native stdlib module identity.
49
+ * @property {string} publicName - Public native symbol.
50
+ * @property {string} unusedName - Unused-elimination fixture symbol.
51
+ * @property {string} unusedNativeModule - Unused-elimination fixture module.
52
+ * @property {string} probeSource - Public executable facade source.
53
+ * @property {string} runnerSource - Internal canonical runner source.
54
+ * @property {string} unusedSource - Unused executable facade source.
55
+ */
56
+ /**
57
+ * @typedef StdlibFacadeRegistry
58
+ * @property {readonly StdlibFacadeRecord[]} facades - Stable immutable facade records.
59
+ * @property {(language: string, nativeModule: string, symbol: string, range?: string) => StdlibFacadeRecord} resolveFacade - Exact native identity resolver.
60
+ * @property {(identity: string, language: string, range?: string) => StdlibFacadeRecord} resolveIdentity - Facade dependency resolver.
61
+ * @property {(language: string, nativeModule: string, range?: string) => StdlibFacadeRecord} resolveModule - Exact native module resolver.
62
+ */
63
+ /**
64
+ * Creates a detached immutable source-language facade registry.
65
+ * @param {unknown} records - Optional facade definitions; built-in qualification definitions by default.
66
+ * @returns {Readonly<StdlibFacadeRegistry>} Validated facade registry.
67
+ */
68
+ export function createStdlibFacadeRegistry(records = builtinFacadeRecords()) {
69
+ if (!isDenseArray(records))
70
+ invalidFacade("Facade records must be an ordered dense array.");
71
+ /** @type {StdlibFacadeRecord[]} */
72
+ const facades = [];
73
+ /** @type {Map<string, Map<string, StdlibFacadeRecord>>} */
74
+ const byIdentity = new Map();
75
+ /** @type {Map<string, StdlibFacadeRecord[]>} */
76
+ const byNativeModule = new Map();
77
+ const sourceIds = new Map();
78
+ const sourceFilenames = new Map();
79
+ for (let index = 0; index < records.length; index += 1) {
80
+ const record = validateFacadeRecord(records[index]);
81
+ const identityKey = `${record.language}\0${record.identity}`;
82
+ const versions = byIdentity.get(identityKey) ?? new Map();
83
+ if (versions.has(record.version))
84
+ invalidFacade(`Duplicate facade '${record.identity}' version '${record.version}' for '${record.language}'.`);
85
+ if (sourceIds.has(record.source.id) && sourceIds.get(record.source.id) != identityKey) {
86
+ invalidFacade(`Duplicate facade source module identity '${record.source.id}'.`);
87
+ }
88
+ if (sourceFilenames.has(record.source.filename) && sourceFilenames.get(record.source.filename) != identityKey) {
89
+ invalidFacade(`Duplicate facade source filename '${record.source.filename}'.`);
90
+ }
91
+ versions.set(record.version, record);
92
+ byIdentity.set(identityKey, versions);
93
+ sourceIds.set(record.source.id, identityKey);
94
+ sourceFilenames.set(record.source.filename, identityKey);
95
+ facades.push(record);
96
+ for (const nativeModule of record.nativeModules) {
97
+ const nativeKey = `${record.language}\0${nativeModule.identity}`;
98
+ const nativeRecords = byNativeModule.get(nativeKey) ?? [];
99
+ nativeRecords.push(record);
100
+ byNativeModule.set(nativeKey, nativeRecords);
101
+ }
102
+ }
103
+ for (const record of facades) {
104
+ for (const dependency of record.dependencies) {
105
+ resolveIdentityFromStore(byIdentity, dependency.identity, record.language, dependency.range, record.identity);
106
+ }
107
+ }
108
+ validateFacadeDependencyCycles(facades, byIdentity);
109
+ return Object.freeze(/** @type {StdlibFacadeRegistry} */ ({
110
+ facades: Object.freeze(facades),
111
+ resolveFacade(language, nativeModule, symbol, range) {
112
+ return resolveNativeFacadeFromStore(byNativeModule, language, nativeModule, symbol, range);
113
+ },
114
+ resolveIdentity(identity, language, range) {
115
+ return resolveIdentityFromStore(byIdentity, identity, language, range);
116
+ },
117
+ resolveModule(language, nativeModule, range) {
118
+ const records = byNativeModule.get(`${language}\0${nativeModule}`);
119
+ if (!records)
120
+ unprovedIdentity(language, nativeModule);
121
+ const identities = new Set(/** @type {StdlibFacadeRecord[]} */ (records).map(({ identity }) => identity));
122
+ if (identities.size != 1)
123
+ invalidFacade(`Native facade module '${nativeModule}' is ambiguous for '${language}'.`);
124
+ return selectFacadeVersion(new Map(/** @type {StdlibFacadeRecord[]} */ (records).map((record) => [record.version, record])),
125
+ /** @type {StdlibFacadeRecord} */ (records[0]).identity, language, range);
126
+ }
127
+ }));
128
+ }
129
+ /**
130
+ * Rejects cycles after every versioned dependency has resolved successfully.
131
+ * @param {StdlibFacadeRecord[]} facades - Validated facade records.
132
+ * @param {Map<string, Map<string, StdlibFacadeRecord>>} store - Records by language and identity.
133
+ * @returns {void}
134
+ */
135
+ function validateFacadeDependencyCycles(facades, store) {
136
+ const active = new Set();
137
+ const complete = new Set();
138
+ /**
139
+ * Visits one exact selected facade version.
140
+ * @param {StdlibFacadeRecord} record - Facade record.
141
+ * @returns {void}
142
+ */
143
+ function visit(record) {
144
+ const key = `${record.language}\0${record.identity}\0${record.version}`;
145
+ if (complete.has(key))
146
+ return;
147
+ if (active.has(key))
148
+ invalidFacade(`Facade dependency cycle includes '${record.identity}'.`);
149
+ active.add(key);
150
+ for (const dependency of record.dependencies) {
151
+ visit(resolveIdentityFromStore(store, dependency.identity, record.language, dependency.range, record.identity));
152
+ }
153
+ active.delete(key);
154
+ complete.add(key);
155
+ }
156
+ for (const record of facades)
157
+ visit(record);
158
+ }
159
+ /**
160
+ * Lists all built-in public and internal facade modules in stable order.
161
+ * @returns {readonly StdlibFacadeRecord[]} Immutable facade definitions.
162
+ */
163
+ export function listStdlibFacades() {
164
+ return stdlibFacadeRegistry.facades;
165
+ }
166
+ /**
167
+ * Resolves one built-in facade from parser-proved native module and symbol identities.
168
+ * @param {string} language - Source language.
169
+ * @param {string} nativeModule - Exact native module identity.
170
+ * @param {string} symbol - Exact imported or qualified symbol.
171
+ * @param {string} [range] - Compatible facade version range.
172
+ * @returns {StdlibFacadeRecord} Immutable facade definition.
173
+ */
174
+ export function resolveStdlibFacade(language, nativeModule, symbol, range) {
175
+ return stdlibFacadeRegistry.resolveFacade(language, nativeModule, symbol, range);
176
+ }
177
+ /**
178
+ * Resolves a dependency-first, cycle-free facade module closure.
179
+ * @param {StdlibFacadeRecord[]} roots - Parser-selected facade roots.
180
+ * @param {Readonly<StdlibFacadeRegistry>} [registry] - Facade registry.
181
+ * @returns {StdlibFacadeRecord[]} Stable dependency-first closure.
182
+ */
183
+ export function resolveStdlibFacadeClosure(roots, registry = stdlibFacadeRegistry) {
184
+ const active = new Set();
185
+ const complete = new Set();
186
+ /** @type {StdlibFacadeRecord[]} */
187
+ const result = [];
188
+ /**
189
+ * Visits one selected facade and its declared dependencies.
190
+ * @param {StdlibFacadeRecord} record - Facade to visit.
191
+ * @returns {void}
192
+ */
193
+ function visit(record) {
194
+ const key = `${record.language}\0${record.identity}\0${record.version}`;
195
+ if (complete.has(key))
196
+ return;
197
+ if (active.has(key))
198
+ invalidFacade(`Facade dependency cycle includes '${record.identity}'.`);
199
+ active.add(key);
200
+ for (const dependency of record.dependencies) {
201
+ visit(registry.resolveIdentity(dependency.identity, record.language, dependency.range));
202
+ }
203
+ active.delete(key);
204
+ complete.add(key);
205
+ result.push(record);
206
+ }
207
+ for (const root of roots)
208
+ visit(root);
209
+ return result;
210
+ }
211
+ /**
212
+ * Creates the detached, deterministic program descriptor for one selected facade closure.
213
+ * @param {import("./semantic/types.js").SemanticLanguage} language - Source language profile.
214
+ * @param {StdlibFacadeRecord[]} facades - Dependency-first selected facade records.
215
+ * @returns {import("./semantic/types.js").StdlibFacadeProgramDescriptor} Plain program descriptor.
216
+ */
217
+ export function stdlibFacadeProgramDescriptor(language, facades) {
218
+ return {
219
+ language,
220
+ modules: facades.map((facade) => ({
221
+ dependencies: facade.dependencies.map((dependency) => ({ ...dependency })),
222
+ identity: facade.identity,
223
+ nativeModules: facade.nativeModules.map((module) => ({ ...module,
224
+ ...(module.kind == "builtin" ? { forms: [...module.forms] } : {}), symbols: [...module.symbols] })),
225
+ publicDeclarations: facade.publicDeclarations.map(detachPublicDeclaration),
226
+ requirements: facade.requirements.map((requirement) => ({ ...requirement, operations: [...requirement.operations] })),
227
+ runtimeProfile: facade.runtimeProfile,
228
+ sourceModule: facade.source.id,
229
+ version: facade.version,
230
+ visibility: facade.visibility
231
+ })),
232
+ schema: "SemantifoldStdlibFacades",
233
+ version: 1
234
+ };
235
+ }
236
+ /**
237
+ * Derives compiler-owned semantic capability authority from selected facade requirements.
238
+ * The initial executable qualification corpus intentionally targets one canonical module.
239
+ * @param {StdlibFacadeRecord[]} records - Selected facade closure.
240
+ * @returns {{contract: {contractVersion: string, identity: string}, input: import("./semantic/types.js").CapabilityAuthorityInput} | {contracts: {contractVersion: string, identity: string}[], input: import("./semantic/types.js").CapabilityAuthorityInput} | null} Authority input.
241
+ */
242
+ export function facadeCapabilityAuthority(records) {
243
+ const requirements = records.flatMap((record) => record.requirements);
244
+ if (requirements.length == 0)
245
+ return null;
246
+ const identities = new Set(requirements.map(({ module }) => module));
247
+ const ranges = new Set(requirements.map(({ range }) => range));
248
+ const task037 = records.some(({ identity }) => identity.startsWith("semantifold.task037."));
249
+ if (task037) {
250
+ const requirementByModule = new Map();
251
+ for (const requirement of requirements) {
252
+ const current = requirementByModule.get(requirement.module);
253
+ if (current && current.range != requirement.range)
254
+ invalidFacade("Task 037 facade requirements disagree on a canonical range.");
255
+ const operations = new Set(current?.operations ?? []);
256
+ for (const operation of requirement.operations)
257
+ operations.add(operation);
258
+ requirementByModule.set(requirement.module, { operations, range: requirement.range });
259
+ }
260
+ const modules = [...requirementByModule.entries()].map(([identity, requirement]) => {
261
+ const contract = resolveStdlibModule(identity, requirement.range);
262
+ return {
263
+ capabilities: [{
264
+ failures: contract.failures.map(({ name }) => ({ name })),
265
+ name: canonicalCapabilityName(identity),
266
+ operations: contract.operations.filter(({ name }) => requirement.operations.has(name)).map((operation) => ({
267
+ effects: /** @type {["host"]} */ ([...operation.effects]),
268
+ failures: operation.failures.map(detachCanonicalReference),
269
+ name: operation.name,
270
+ parameters: operation.parameters.map((parameter) => ({
271
+ name: parameter.name,
272
+ type: canonicalCapabilityParameterType(parameter.type)
273
+ })),
274
+ resourceFlow: detachResourceFlow(operation.resourceFlow),
275
+ returnType: canonicalCapabilityType(operation.returnType)
276
+ })),
277
+ resources: contract.resources.map(({ name }) => ({ name }))
278
+ }],
279
+ contractVersion: requirement.range,
280
+ identity
281
+ };
282
+ });
283
+ return {
284
+ contracts: modules.map(({ contractVersion, identity }) => ({ contractVersion, identity })),
285
+ input: { id: "semantifold.task037.blocking-tcp", modules, schema: "SemantifoldCapabilityAuthority", schemaVersion: 2 }
286
+ };
287
+ }
288
+ if (identities.size != 1 || ranges.size != 1) {
289
+ invalidFacade("The Task 036 qualification facade closure must resolve one canonical module and version range.");
290
+ }
291
+ const identity = requirements[0].module;
292
+ const contractVersion = requirements[0].range;
293
+ const contract = resolveStdlibModule(identity, contractVersion);
294
+ return {
295
+ contract: { contractVersion, identity },
296
+ input: {
297
+ capabilities: [{
298
+ failures: contract.failures.map(({ name }) => ({ name })),
299
+ name: "ResourceProbe",
300
+ operations: contract.operations.map((operation) => ({
301
+ effects: [...operation.effects],
302
+ failures: [...operation.failures],
303
+ name: operation.name,
304
+ parameters: operation.parameters.map((parameter) => ({
305
+ name: parameter.name,
306
+ type: canonicalCapabilityParameterType(parameter.type)
307
+ })),
308
+ resourceFlow: /** @type {import("./semantic/types.js").CapabilityResourceFlowInput} */ ({ ...operation.resourceFlow }),
309
+ returnType: canonicalCapabilityType(operation.returnType)
310
+ })),
311
+ resources: contract.resources.map(({ name }) => ({ name }))
312
+ }],
313
+ contractVersion,
314
+ id: identity,
315
+ schema: "SemantifoldCapabilityAuthority",
316
+ schemaVersion: 1
317
+ }
318
+ };
319
+ }
320
+ /**
321
+ * Converts one registry contract type to a capability-authority input type.
322
+ * @param {string | import("./semantic/stdlib.js").CanonicalDeclarationReference} type - Canonical contract type.
323
+ * @returns {import("./semantic/types.js").FunctionReturnTypeName | {kind: "OwnedResourceType", resource: string | import("./semantic/types.js").CapabilityDeclarationReferenceInput} | {kind: "OptionalType", valueType: import("./semantic/types.js").SemanticTypeName}} Semantic authority type.
324
+ */
325
+ function canonicalCapabilityType(type) {
326
+ if (typeof type != "string")
327
+ return { kind: "OwnedResourceType", resource: detachCanonicalReference(type) };
328
+ if (type == "void" || type == "boolean" || type == "integer" || type == "string")
329
+ return type;
330
+ if (type.startsWith("optional:"))
331
+ return { kind: "OptionalType",
332
+ valueType: /** @type {import("./semantic/types.js").SemanticTypeName} */ (type.slice("optional:".length)) };
333
+ return { kind: "OwnedResourceType", resource: type };
334
+ }
335
+ /**
336
+ * Converts a non-void registry parameter type to capability-authority input.
337
+ * @param {string | import("./semantic/stdlib.js").CanonicalDeclarationReference} type - Canonical parameter type.
338
+ * @returns {import("./semantic/types.js").SemanticTypeName | {kind: "OwnedResourceType", resource: string} | {kind: "OptionalType", valueType: import("./semantic/types.js").SemanticTypeName}} Semantic parameter type.
339
+ */
340
+ function canonicalCapabilityParameterType(type) {
341
+ const converted = canonicalCapabilityType(type);
342
+ if (converted == "void")
343
+ invalidFacade("Canonical facade requirement parameters cannot have void type.");
344
+ return /** @type {import("./semantic/types.js").SemanticTypeName | {kind: "OwnedResourceType", resource: string} | {kind: "OptionalType", valueType: import("./semantic/types.js").SemanticTypeName}} */ (converted);
345
+ }
346
+ /**
347
+ * Resolves one dependency identity from a validated registry store.
348
+ * @param {Map<string, Map<string, StdlibFacadeRecord>>} store - Records by language and identity.
349
+ * @param {string} identity - Facade identity.
350
+ * @param {string} language - Source language.
351
+ * @param {string | undefined} range - Compatible range.
352
+ * @param {string} [owner] - Depending facade for diagnostics.
353
+ * @returns {StdlibFacadeRecord} Highest compatible record.
354
+ */
355
+ function resolveIdentityFromStore(store, identity, language, range, owner) {
356
+ const versions = store.get(`${language}\0${identity}`);
357
+ if (!versions) {
358
+ invalidFacade(owner ? `Facade '${owner}' depends on unknown facade '${identity}' for '${language}'.` :
359
+ `Unknown facade identity '${identity}' for '${language}'.`);
360
+ }
361
+ return selectFacadeVersion(/** @type {Map<string, StdlibFacadeRecord>} */ (versions), identity, language, range);
362
+ }
363
+ /**
364
+ * Resolves one exact native identity from a validated registry store.
365
+ * @param {Map<string, StdlibFacadeRecord[]>} store - Records by language and native module.
366
+ * @param {string} language - Source language.
367
+ * @param {string} nativeModule - Exact parser-owned native module identity.
368
+ * @param {string} symbol - Exact source-visible symbol.
369
+ * @param {string | undefined} range - Compatible range.
370
+ * @returns {StdlibFacadeRecord} Highest compatible record.
371
+ */
372
+ function resolveNativeFacadeFromStore(store, language, nativeModule, symbol, range) {
373
+ if (!supportedLanguages.has(language) || typeof nativeModule != "string" || nativeModule.length == 0) {
374
+ unprovedIdentity(language, nativeModule);
375
+ }
376
+ const moduleRecords = store.get(`${language}\0${nativeModule}`);
377
+ if (!moduleRecords)
378
+ unprovedIdentity(language, nativeModule);
379
+ const symbolRecords = /** @type {StdlibFacadeRecord[]} */ (moduleRecords).filter((record) => record.nativeModules.some((module) => module.identity == nativeModule && module.symbols.includes(symbol)));
380
+ if (symbolRecords.length == 0)
381
+ unsupportedMember(language, nativeModule, symbol);
382
+ const identities = new Set(symbolRecords.map(({ identity }) => identity));
383
+ if (identities.size != 1)
384
+ invalidFacade(`Native facade identity '${nativeModule}#${symbol}' is ambiguous for '${language}'.`);
385
+ const versions = new Map(symbolRecords.map((record) => [record.version, record]));
386
+ return selectFacadeVersion(versions, symbolRecords[0].identity, language, range);
387
+ }
388
+ /**
389
+ * Selects the highest facade version satisfying a canonical range.
390
+ * @param {Map<string, StdlibFacadeRecord>} versions - Records by exact version.
391
+ * @param {string} identity - Facade identity.
392
+ * @param {string} language - Source language.
393
+ * @param {string | undefined} range - Compatible range.
394
+ * @returns {StdlibFacadeRecord} Selected record.
395
+ */
396
+ function selectFacadeVersion(versions, identity, language, range) {
397
+ const parsedRange = range === undefined ? { lower: /** @type {[number, number, number]} */ ([0, 0, 0]), upper: null } :
398
+ parseStdlibVersionRange(range);
399
+ if (!parsedRange)
400
+ facadeVersionMalformed(language, String(range));
401
+ /** @type {[number, number, number] | undefined} */
402
+ let selected;
403
+ for (const version of versions.keys()) {
404
+ const parsed = /** @type {[number, number, number]} */ (parseStdlibVersion(version));
405
+ if (stdlibVersionSatisfies(parsed, parsedRange) && (!selected || compareStdlibVersions(parsed, selected) > 0))
406
+ selected = parsed;
407
+ }
408
+ if (!selected)
409
+ facadeVersionIncompatible(language, identity);
410
+ return /** @type {StdlibFacadeRecord} */ (versions.get(selected.join(".")));
411
+ }
412
+ /**
413
+ * Validates and detaches one executable facade record.
414
+ * @param {unknown} candidate - Candidate record.
415
+ * @returns {StdlibFacadeRecord} Detached frozen record.
416
+ */
417
+ function validateFacadeRecord(candidate) {
418
+ if (!isPlainObject(candidate))
419
+ invalidFacade("Every facade record must be a plain object.");
420
+ requireKeys(candidate, ["dependencies", "identity", "language", "nativeModules", "publicDeclarations", "requirements",
421
+ "runtimeProfile", "source", "version", "visibility"], "facade record");
422
+ const identity = requireString(candidate.identity, "Facade identity");
423
+ const language = requireString(candidate.language, "Facade language");
424
+ const version = requireString(candidate.version, "Facade version");
425
+ const runtimeProfile = requireString(candidate.runtimeProfile, "Facade runtime profile");
426
+ const visibility = candidate.visibility;
427
+ if (!facadeIdentityPattern.test(identity))
428
+ invalidFacade(`Facade identity '${identity}' is invalid.`);
429
+ if (!supportedLanguages.has(language))
430
+ invalidFacade(`Facade language '${language}' is outside the adopted cohort.`);
431
+ if (!parseStdlibVersion(version))
432
+ invalidFacade(`Facade version '${version}' is invalid.`);
433
+ if (!/^[a-z][a-z0-9.-]*$/u.test(runtimeProfile))
434
+ invalidFacade(`Facade runtime profile '${runtimeProfile}' is invalid.`);
435
+ if (visibility != "public" && visibility != "internal")
436
+ invalidFacade(`Facade '${identity}' has invalid visibility.`);
437
+ const source = validateSource(candidate.source, identity, language);
438
+ const publicDeclarations = validatePublicDeclarations(candidate.publicDeclarations, identity);
439
+ const nativeModules = validateNativeModules(candidate.nativeModules, identity, publicDeclarations);
440
+ const requirements = validateRequirements(candidate.requirements, identity);
441
+ const dependencies = validateDependencies(candidate.dependencies, identity);
442
+ if (visibility == "public" && (publicDeclarations.length == 0 || nativeModules.length == 0)) {
443
+ invalidFacade(`Public facade '${identity}' requires declarations and native identities.`);
444
+ }
445
+ if (visibility == "internal" && nativeModules.length > 0)
446
+ invalidFacade(`Internal facade '${identity}' cannot expose native identities.`);
447
+ return deepFreeze({
448
+ dependencies,
449
+ identity,
450
+ language: /** @type {import("./semantic/types.js").SemanticLanguage} */ (language),
451
+ nativeModules,
452
+ publicDeclarations,
453
+ requirements,
454
+ runtimeProfile,
455
+ source,
456
+ version,
457
+ visibility: /** @type {"internal" | "public"} */ (visibility)
458
+ });
459
+ }
460
+ /**
461
+ * Validates one compiler-owned executable facade source.
462
+ * @param {unknown} candidate - Candidate source descriptor.
463
+ * @param {string} identity - Owning facade identity.
464
+ * @param {string} language - Facade source language.
465
+ * @returns {{content: string, filename: string, id: string}} Validated source descriptor.
466
+ */
467
+ function validateSource(candidate, identity, language) {
468
+ if (!isPlainObject(candidate))
469
+ invalidFacade(`Facade '${identity}' requires an executable source descriptor.`);
470
+ requireKeys(candidate, ["content", "filename", "id"], `facade '${identity}' source`);
471
+ const content = requireString(candidate.content, `Facade '${identity}' source content`);
472
+ const filename = requireString(candidate.filename, `Facade '${identity}' source filename`);
473
+ const id = requireString(candidate.id, `Facade '${identity}' source module identity`);
474
+ if (content.length == 0 || !isSafeArtifactPath(filename) || !filename.startsWith(`__semantifold_facades__/${language}/`) ||
475
+ !moduleIdPattern.test(id) || !id.startsWith(`semantifold.facade.${language}.`)) {
476
+ invalidFacade(`Facade '${identity}' has an invalid compiler-owned source descriptor.`);
477
+ }
478
+ return { content, filename, id };
479
+ }
480
+ /**
481
+ * Validates one facade's closed public declaration surface.
482
+ * @param {unknown} candidate - Candidate declarations.
483
+ * @param {string} identity - Owning facade identity.
484
+ * @returns {StdlibFacadePublicDeclaration[]} Validated declarations.
485
+ */
486
+ function validatePublicDeclarations(candidate, identity) {
487
+ if (!isDenseArray(candidate))
488
+ invalidFacade(`Facade '${identity}' public declarations must be a dense array.`);
489
+ const names = new Set();
490
+ return candidate.map((value) => {
491
+ if (!isPlainObject(value))
492
+ invalidFacade(`Facade '${identity}' public declarations must be plain objects.`);
493
+ const name = requireString(value.name, `Facade '${identity}' declaration name`);
494
+ if (!declarationNamePattern.test(name) || names.has(name)) {
495
+ invalidFacade(`Facade '${identity}' has an invalid or duplicate public declaration.`);
496
+ }
497
+ names.add(name);
498
+ if (value.kind == "class")
499
+ return validatePublicClass(value, identity, name);
500
+ requireKeys(value, ["effects", "failures", "forms", "kind", "name", "ownership", "parameters", "returnType"], `facade '${identity}' public declaration`);
501
+ if (value.kind != "function")
502
+ invalidFacade(`Facade '${identity}' has an invalid public declaration kind.`);
503
+ if (!isDenseArray(value.effects) || !value.effects.every((effect) => effect == "host") || new Set(value.effects).size != value.effects.length ||
504
+ !isDenseArray(value.failures) || !value.failures.every((failure) => typeof failure == "string" && declarationNamePattern.test(failure)) ||
505
+ !isDenseArray(value.forms) || value.forms.length == 0 || !value.forms.every((form) => typeof form == "string" && ["direct-call", "unqualified-call", "receiver-call"].includes(form)) ||
506
+ new Set(value.forms).size != value.forms.length ||
507
+ value.ownership != "not-applicable" ||
508
+ !isDenseArray(value.parameters))
509
+ invalidFacade(`Facade '${identity}' declaration '${name}' has an invalid public contract.`);
510
+ const parameters = validateFacadeParameters(value.parameters, identity, name);
511
+ const returnType = requireString(value.returnType, `Facade '${identity}' return type`);
512
+ if (!isFacadeType(returnType, true))
513
+ invalidFacade(`Facade '${identity}' declaration '${name}' has an invalid return type.`);
514
+ return {
515
+ effects: /** @type {string[]} */ ([...value.effects]),
516
+ failures: /** @type {string[]} */ ([...value.failures]),
517
+ forms: /** @type {("direct-call" | "unqualified-call" | "receiver-call")[]} */ ([...value.forms]),
518
+ kind: /** @type {const} */ ("function"),
519
+ name,
520
+ ownership: /** @type {const} */ ("not-applicable"),
521
+ parameters,
522
+ returnType
523
+ };
524
+ });
525
+ }
526
+ /**
527
+ * Validates the exact native module and symbol identities selecting a facade.
528
+ * @param {unknown} candidate - Candidate native modules.
529
+ * @param {string} identity - Owning facade identity.
530
+ * @param {StdlibFacadePublicDeclaration[]} declarations - Validated public surface.
531
+ * @returns {({identity: string, kind: "module", symbols: string[]} | {forms: ("unqualified-call" | "receiver-call")[], identity: string, kind: "builtin", symbols: string[]})[]} Validated native identities.
532
+ */
533
+ function validateNativeModules(candidate, identity, declarations) {
534
+ if (!isDenseArray(candidate))
535
+ invalidFacade(`Facade '${identity}' native modules must be a dense array.`);
536
+ const modules = new Set();
537
+ const publicNames = new Set(declarations.map(({ name }) => name));
538
+ return candidate.map((value) => {
539
+ if (!isPlainObject(value))
540
+ invalidFacade(`Facade '${identity}' native modules must be plain objects.`);
541
+ const builtin = value.kind == "builtin";
542
+ requireKeys(value, builtin ? ["forms", "identity", "kind", "symbols"] : ["identity", "kind", "symbols"], `facade '${identity}' native module`);
543
+ const moduleIdentity = requireString(value.identity, `Facade '${identity}' native module identity`);
544
+ if (value.kind != "module" && value.kind != "builtin" || modules.has(moduleIdentity) ||
545
+ !isDenseArray(value.symbols) || value.symbols.length == 0 ||
546
+ !value.symbols.every((symbol) => typeof symbol == "string" && publicNames.has(symbol)) ||
547
+ new Set(value.symbols).size != value.symbols.length) {
548
+ invalidFacade(`Facade '${identity}' has an invalid native module declaration.`);
549
+ }
550
+ if (builtin && (!isDenseArray(value.forms) || value.forms.length == 0 ||
551
+ !value.forms.every((form) => form == "unqualified-call" || form == "receiver-call") ||
552
+ new Set(value.forms).size != value.forms.length))
553
+ invalidFacade(`Facade '${identity}' has invalid builtin forms.`);
554
+ modules.add(moduleIdentity);
555
+ return builtin
556
+ ? { forms: /** @type {("unqualified-call" | "receiver-call")[]} */ ([... /** @type {unknown[]} */(value.forms)]), identity: moduleIdentity,
557
+ kind: /** @type {const} */ ("builtin"), symbols: /** @type {string[]} */ ([...value.symbols]) }
558
+ : { identity: moduleIdentity, kind: /** @type {const} */ ("module"), symbols: /** @type {string[]} */ ([...value.symbols]) };
559
+ });
560
+ }
561
+ /**
562
+ * Validates canonical-only facade capability requirements.
563
+ * @param {unknown} candidate - Candidate requirements.
564
+ * @param {string} identity - Owning facade identity.
565
+ * @returns {{module: string, operations: string[], range: string}[]} Validated requirements.
566
+ */
567
+ function validateRequirements(candidate, identity) {
568
+ if (!isDenseArray(candidate))
569
+ invalidFacade(`Facade '${identity}' requirements must be a dense array.`);
570
+ const modules = new Set();
571
+ return candidate.map((value) => {
572
+ if (!isPlainObject(value))
573
+ invalidFacade(`Facade '${identity}' requirements must be plain objects.`);
574
+ requireKeys(value, ["module", "operations", "range"], `facade '${identity}' requirement`);
575
+ const module = requireString(value.module, `Facade '${identity}' canonical module`);
576
+ const range = requireString(value.range, `Facade '${identity}' canonical range`);
577
+ if (modules.has(module) || !parseStdlibVersionRange(range) || !isDenseArray(value.operations) || value.operations.length == 0 ||
578
+ !value.operations.every((operation) => typeof operation == "string" && declarationNamePattern.test(operation)) ||
579
+ new Set(value.operations).size != value.operations.length)
580
+ invalidFacade(`Facade '${identity}' has an invalid canonical requirement.`);
581
+ const contract = resolveStdlibModule(module, range);
582
+ const declared = new Set(contract.operations.map(({ name }) => name));
583
+ if (! /** @type {string[]} */(value.operations).every((operation) => declared.has(operation))) {
584
+ invalidFacade(`Facade '${identity}' requires an undeclared canonical operation.`);
585
+ }
586
+ modules.add(module);
587
+ return { module, operations: /** @type {string[]} */ ([...value.operations]), range };
588
+ });
589
+ }
590
+ /**
591
+ * Validates versioned same-language facade dependencies.
592
+ * @param {unknown} candidate - Candidate dependencies.
593
+ * @param {string} identity - Owning facade identity.
594
+ * @returns {{identity: string, range: string}[]} Validated dependencies.
595
+ */
596
+ function validateDependencies(candidate, identity) {
597
+ if (!isDenseArray(candidate))
598
+ invalidFacade(`Facade '${identity}' dependencies must be a dense array.`);
599
+ const identities = new Set();
600
+ return candidate.map((value) => {
601
+ if (!isPlainObject(value))
602
+ invalidFacade(`Facade '${identity}' dependencies must be plain objects.`);
603
+ requireKeys(value, ["identity", "range"], `facade '${identity}' dependency`);
604
+ const dependencyIdentity = requireString(value.identity, `Facade '${identity}' dependency identity`);
605
+ const range = requireString(value.range, `Facade '${identity}' dependency range`);
606
+ if (!facadeIdentityPattern.test(dependencyIdentity) || dependencyIdentity == identity || identities.has(dependencyIdentity) ||
607
+ !parseStdlibVersionRange(range))
608
+ invalidFacade(`Facade '${identity}' has an invalid dependency.`);
609
+ identities.add(dependencyIdentity);
610
+ return { identity: dependencyIdentity, range };
611
+ });
612
+ }
613
+ /**
614
+ * Builds the bounded original-five qualification facade definitions.
615
+ * @returns {unknown[]} Unvalidated built-in qualification facade definitions.
616
+ */
617
+ function builtinFacadeRecords() {
618
+ return ["php", "ruby", "javascript", "typescript", "java"].flatMap((language) => builtinLanguageFacades(language))
619
+ .concat(builtinTask037RubyFacades());
620
+ }
621
+ /**
622
+ * Builds one source language's public, internal, and unreachable qualification facades.
623
+ * @param {string} language - Source language.
624
+ * @returns {unknown[]} Language facade definitions.
625
+ */
626
+ function builtinLanguageFacades(language) {
627
+ const names = facadeNames(language);
628
+ const base = `semantifold.task036.${language}`;
629
+ const sourceBase = `semantifold.facade.${language}`;
630
+ const sourceDirectory = `__semantifold_facades__/${language}`;
631
+ const probeFilename = language == "java" ? `${sourceDirectory}/semantifold/facade/java/probe/Probe.java` :
632
+ `${sourceDirectory}/probe.${names.extension}`;
633
+ const runnerFilename = language == "java" ? `${sourceDirectory}/semantifold/facade/java/proberunner/ProbeRunner.java` :
634
+ `${sourceDirectory}/probe-runner.${names.extension}`;
635
+ const unusedFilename = language == "java" ? `${sourceDirectory}/semantifold/facade/java/unused/Unused.java` :
636
+ `${sourceDirectory}/unused.${names.extension}`;
637
+ return [{
638
+ dependencies: [{ identity: `${base}.probe-runner`, range: "1" }],
639
+ identity: `${base}.probe`,
640
+ language,
641
+ nativeModules: [{ identity: names.nativeModule, kind: "module", symbols: [names.publicName] }],
642
+ publicDeclarations: [publicDeclaration(names.publicName)],
643
+ requirements: [],
644
+ runtimeProfile: `${language}-task036-v1`,
645
+ source: { content: names.probeSource, filename: probeFilename, id: `${sourceBase}.probe` },
646
+ version: "1.0.0",
647
+ visibility: "public"
648
+ }, {
649
+ dependencies: [],
650
+ identity: `${base}.probe-runner`,
651
+ language,
652
+ nativeModules: [],
653
+ publicDeclarations: [],
654
+ requirements: [{ module: "semantifold.task034.resource-probe", operations: ["probeEffect", "probeTrace"], range: "1" }],
655
+ runtimeProfile: `${language}-task036-v1`,
656
+ source: { content: names.runnerSource, filename: runnerFilename, id: `${sourceBase}.probe_runner` },
657
+ version: "1.0.0",
658
+ visibility: "internal"
659
+ }, {
660
+ dependencies: [],
661
+ identity: `${base}.unused`,
662
+ language,
663
+ nativeModules: [{ identity: names.unusedNativeModule, kind: "module", symbols: [names.unusedName] }],
664
+ publicDeclarations: [publicDeclaration(names.unusedName)],
665
+ requirements: [{ module: "semantifold.task034.resource-probe", operations: ["probeTrace"], range: "1" }],
666
+ runtimeProfile: `${language}-task036-v1`,
667
+ source: { content: names.unusedSource, filename: unusedFilename, id: `${sourceBase}.unused` },
668
+ version: "1.0.0",
669
+ visibility: "public"
670
+ }];
671
+ }
672
+ /**
673
+ * Builds the common bounded qualification function declaration.
674
+ * @param {string} name - Source-visible function name.
675
+ * @returns {StdlibFacadePublicDeclaration} Public facade declaration.
676
+ */
677
+ function publicDeclaration(name) {
678
+ return {
679
+ effects: ["host"], failures: [], forms: ["direct-call"], kind: "function", name,
680
+ ownership: "not-applicable", parameters: [{ name: "label", type: "string" }], returnType: "string"
681
+ };
682
+ }
683
+ /**
684
+ * Builds the exact Ruby Task 037 socket and output compatibility facades.
685
+ * @returns {unknown[]} Unvalidated facade records.
686
+ */
687
+ function builtinTask037RubyFacades() {
688
+ return [{
689
+ dependencies: [],
690
+ identity: "semantifold.task037.ruby.socket",
691
+ language: "ruby",
692
+ nativeModules: [{ identity: "socket", kind: "module", symbols: ["TCPSocket"] }],
693
+ publicDeclarations: [{
694
+ constructor: {
695
+ effects: ["host"], failures: ["InvalidHost", "InvalidPort", "ConnectionFailure"], ownership: "acquired",
696
+ parameters: [{ name: "host", type: "string" }, { name: "port", type: "integer" }]
697
+ },
698
+ forms: ["constructor-call"],
699
+ kind: "class",
700
+ methods: [{
701
+ effects: ["host"], failures: ["ReadFailure", "DecodeFailure", "ResourceClosed"], forms: ["receiver-call"],
702
+ name: "gets", ownership: "borrowed", parameters: [], returnType: "optional:string"
703
+ }, {
704
+ effects: ["host"], failures: ["CloseFailure", "ResourceClosed"], forms: ["receiver-call"],
705
+ name: "close", ownership: "consumed", parameters: [], returnType: "void"
706
+ }],
707
+ name: "TCPSocket",
708
+ ownership: "owned-reference"
709
+ }],
710
+ requirements: [
711
+ { module: "semantifold.socket-client", operations: ["v1_connect"], range: "1" },
712
+ { module: "semantifold.text-stream", operations: ["v1_read_line"], range: "1" },
713
+ { module: "semantifold.resource", operations: ["v1_close"], range: "1" }
714
+ ],
715
+ runtimeProfile: "ruby-task037-socket-v1",
716
+ source: {
717
+ content: `module SemantifoldTask037Socket
718
+ class TCPSocket
719
+ # @param host [String]
720
+ # @param port [Integer]
721
+ def initialize(host, port)
722
+ @resource = v1_connect(host, port)
723
+ end
724
+
725
+ # @return [String?]
726
+ def gets
727
+ return v1_read_line(@resource)
728
+ end
729
+
730
+ # @return [void]
731
+ def close
732
+ v1_close(@resource)
733
+ end
734
+ end
735
+ end
736
+ `,
737
+ filename: "__semantifold_facades__/ruby/socket.rb",
738
+ id: "semantifold.facade.ruby.socket"
739
+ },
740
+ version: "1.0.0",
741
+ visibility: "public"
742
+ }, {
743
+ dependencies: [],
744
+ identity: "semantifold.task037.ruby.output",
745
+ language: "ruby",
746
+ nativeModules: [{ forms: ["unqualified-call", "receiver-call"], identity: "ruby:Kernel", kind: "builtin", symbols: ["puts"] }],
747
+ publicDeclarations: [{
748
+ effects: ["host"], failures: ["WriteFailure"], forms: ["unqualified-call", "receiver-call"], kind: "function",
749
+ name: "puts", ownership: "not-applicable", parameters: [{ name: "text", type: "string" }], returnType: "void"
750
+ }],
751
+ requirements: [{ module: "semantifold.output", operations: ["v1_write_line"], range: "1" }],
752
+ runtimeProfile: "ruby-task037-output-v1",
753
+ source: {
754
+ content: `module SemantifoldTask037Output
755
+ module_function
756
+ # @param text [String]
757
+ # @return [void]
758
+ def puts(text)
759
+ v1_write_line(text)
760
+ return
761
+ end
762
+ end
763
+ `,
764
+ filename: "__semantifold_facades__/ruby/output.rb",
765
+ id: "semantifold.facade.ruby.output"
766
+ },
767
+ version: "1.0.0",
768
+ visibility: "public"
769
+ }];
770
+ }
771
+ /**
772
+ * Validates one public facade class descriptor.
773
+ * @param {Record<string, unknown>} value - Candidate class.
774
+ * @param {string} identity - Owning facade.
775
+ * @param {string} name - Validated class name.
776
+ * @returns {StdlibFacadeClassDeclaration} Detached class descriptor.
777
+ */
778
+ function validatePublicClass(value, identity, name) {
779
+ requireKeys(value, ["constructor", "forms", "kind", "methods", "name", "ownership"], `facade '${identity}' public class`);
780
+ if (!isDenseArray(value.forms) || value.forms.length != 1 || value.forms[0] != "constructor-call" ||
781
+ value.ownership != "owned-reference" || !isPlainObject(value.constructor) || !isDenseArray(value.methods)) {
782
+ invalidFacade(`Facade '${identity}' class '${name}' has an invalid public contract.`);
783
+ }
784
+ const constructor = /** @type {Record<string, unknown>} */ (value.constructor);
785
+ requireKeys(constructor, ["effects", "failures", "ownership", "parameters"], `facade '${identity}' constructor`);
786
+ if (constructor.ownership != "acquired" || !validFacadeEffects(constructor.effects) ||
787
+ !validFacadeFailures(constructor.failures))
788
+ invalidFacade(`Facade '${identity}' class '${name}' has an invalid constructor.`);
789
+ const parameters = validateFacadeParameters(constructor.parameters, identity, `${name}.new`);
790
+ const methodNames = new Set();
791
+ const methods = value.methods.map((method) => {
792
+ if (!isPlainObject(method))
793
+ invalidFacade(`Facade '${identity}' class '${name}' has an invalid method.`);
794
+ requireKeys(method, ["effects", "failures", "forms", "name", "ownership", "parameters", "returnType"], `facade '${identity}' class method`);
795
+ const methodName = requireString(method.name, `Facade '${identity}' method name`);
796
+ const returnType = requireString(method.returnType, `Facade '${identity}' method return type`);
797
+ if (!declarationNamePattern.test(methodName) || methodNames.has(methodName) || !validFacadeEffects(method.effects) ||
798
+ !validFacadeFailures(method.failures) || !isDenseArray(method.forms) || method.forms.length != 1 ||
799
+ method.forms[0] != "receiver-call" || method.ownership != "borrowed" && method.ownership != "consumed" ||
800
+ !isFacadeType(returnType, true))
801
+ invalidFacade(`Facade '${identity}' class '${name}' has an invalid method.`);
802
+ methodNames.add(methodName);
803
+ return {
804
+ effects: /** @type {string[]} */ ([... /** @type {unknown[]} */(method.effects)]),
805
+ failures: /** @type {string[]} */ ([... /** @type {unknown[]} */(method.failures)]),
806
+ forms: /** @type {["receiver-call"]} */ (["receiver-call"]),
807
+ name: methodName,
808
+ ownership: /** @type {"borrowed" | "consumed"} */ (method.ownership),
809
+ parameters: validateFacadeParameters(method.parameters, identity, `${name}.${methodName}`),
810
+ returnType
811
+ };
812
+ });
813
+ return {
814
+ constructor: {
815
+ effects: /** @type {string[]} */ ([... /** @type {unknown[]} */(constructor.effects)]),
816
+ failures: /** @type {string[]} */ ([... /** @type {unknown[]} */(constructor.failures)]),
817
+ ownership: "acquired",
818
+ parameters
819
+ },
820
+ forms: ["constructor-call"],
821
+ kind: "class",
822
+ methods,
823
+ name,
824
+ ownership: "owned-reference"
825
+ };
826
+ }
827
+ /**
828
+ * Validates facade parameters shared by functions, constructors, and methods.
829
+ * @param {unknown} candidate - Candidate parameters.
830
+ * @param {string} identity - Owning facade.
831
+ * @param {string} callable - Callable name.
832
+ * @returns {{name: string, type: string}[]} Detached parameters.
833
+ */
834
+ function validateFacadeParameters(candidate, identity, callable) {
835
+ if (!isDenseArray(candidate))
836
+ invalidFacade(`Facade '${identity}' declaration '${callable}' has invalid parameters.`);
837
+ const names = new Set();
838
+ return candidate.map((parameter) => {
839
+ if (!isPlainObject(parameter))
840
+ invalidFacade(`Facade '${identity}' declaration '${callable}' has an invalid parameter.`);
841
+ requireKeys(parameter, ["name", "type"], `facade '${identity}' declaration parameter`);
842
+ const name = requireString(parameter.name, `Facade '${identity}' parameter name`);
843
+ const type = requireString(parameter.type, `Facade '${identity}' parameter type`);
844
+ if (!declarationNamePattern.test(name) || names.has(name) || !isFacadeType(type, false)) {
845
+ invalidFacade(`Facade '${identity}' declaration '${callable}' has an invalid parameter.`);
846
+ }
847
+ names.add(name);
848
+ return { name, type };
849
+ });
850
+ }
851
+ /**
852
+ * Checks one facade effect list.
853
+ * @param {unknown} candidate - Candidate effects.
854
+ * @returns {boolean} Whether effects are exact.
855
+ */
856
+ function validFacadeEffects(candidate) {
857
+ return isDenseArray(candidate) && candidate.every((effect) => effect == "host") && new Set(candidate).size == candidate.length;
858
+ }
859
+ /**
860
+ * Checks one facade failure list.
861
+ * @param {unknown} candidate - Candidate failures.
862
+ * @returns {candidate is string[]} Whether failures are exact.
863
+ */
864
+ function validFacadeFailures(candidate) {
865
+ return isDenseArray(candidate) && candidate.every((failure) => typeof failure == "string" && declarationNamePattern.test(failure)) &&
866
+ new Set(candidate).size == candidate.length;
867
+ }
868
+ /**
869
+ * Checks one facade type spelling.
870
+ * @param {string} type - Candidate type.
871
+ * @param {boolean} allowVoid - Whether void is valid in this position.
872
+ * @returns {boolean} Whether the type is canonical.
873
+ */
874
+ function isFacadeType(type, allowVoid) {
875
+ if (canonicalTypes.has(type))
876
+ return allowVoid || type != "void";
877
+ const optional = /^optional:(boolean|integer|string)$/u.exec(type);
878
+ return optional !== null;
879
+ }
880
+ /**
881
+ * Detaches one descriptor for the public program record.
882
+ * @param {StdlibFacadePublicDeclaration} declaration - Registry declaration.
883
+ * @returns {StdlibFacadePublicDeclaration} Detached declaration.
884
+ */
885
+ function detachPublicDeclaration(declaration) {
886
+ if (declaration.kind == "function")
887
+ return { ...declaration, effects: [...declaration.effects], failures: [...declaration.failures],
888
+ forms: [...declaration.forms], parameters: declaration.parameters.map((parameter) => ({ ...parameter })) };
889
+ return { ...declaration,
890
+ constructor: { ...declaration.constructor, effects: [...declaration.constructor.effects], failures: [...declaration.constructor.failures],
891
+ parameters: declaration.constructor.parameters.map((parameter) => ({ ...parameter })) },
892
+ forms: [...declaration.forms],
893
+ methods: declaration.methods.map((method) => ({ ...method, effects: [...method.effects], failures: [...method.failures],
894
+ forms: [...method.forms], parameters: method.parameters.map((parameter) => ({ ...parameter })) })) };
895
+ }
896
+ /**
897
+ * Detaches a local or dependency-qualified contract reference.
898
+ * @param {string | import("./semantic/stdlib.js").CanonicalDeclarationReference} reference - Contract reference.
899
+ * @returns {string | import("./semantic/types.js").CapabilityDeclarationReferenceInput} Detached reference.
900
+ */
901
+ function detachCanonicalReference(reference) {
902
+ return typeof reference == "string" ? reference : { module: reference.module, name: reference.name };
903
+ }
904
+ /**
905
+ * Detaches a canonical resource flow for authority construction.
906
+ * @param {object} flow - Canonical resource flow.
907
+ * @returns {import("./semantic/types.js").CapabilityResourceFlowInput} Detached flow.
908
+ */
909
+ function detachResourceFlow(flow) {
910
+ const candidate = /** @type {Record<string, unknown>} */ (flow);
911
+ if (candidate.kind == "none")
912
+ return { kind: "none" };
913
+ if (candidate.kind == "acquire")
914
+ return { kind: "acquire", resource: detachCanonicalReference(
915
+ /** @type {string | import("./semantic/stdlib.js").CanonicalDeclarationReference} */ (candidate.resource)) };
916
+ return {
917
+ kind: /** @type {"borrow" | "close"} */ (candidate.kind),
918
+ parameterIndex: /** @type {number} */ (candidate.parameterIndex),
919
+ terminalFailure: detachCanonicalReference(
920
+ /** @type {string | import("./semantic/stdlib.js").CanonicalDeclarationReference} */ (candidate.terminalFailure))
921
+ };
922
+ }
923
+ /**
924
+ * Maps one canonical module identity to its closed capability name.
925
+ * @param {string} identity - Canonical identity.
926
+ * @returns {string} Capability name.
927
+ */
928
+ function canonicalCapabilityName(identity) {
929
+ /** @type {Readonly<Record<string, string>>} */
930
+ const names = {
931
+ "semantifold.output": "Output",
932
+ "semantifold.resource": "Resource",
933
+ "semantifold.socket-client": "SocketClient",
934
+ "semantifold.task034.resource-probe": "ResourceProbe",
935
+ "semantifold.text-stream": "TextStream"
936
+ };
937
+ return names[identity] ?? invalidFacade(`Facade requirements name unknown canonical module '${identity}'.`);
938
+ }
939
+ /**
940
+ * Builds executable source and native identity spellings for one original-five language.
941
+ * @param {string} language - Source language.
942
+ * @returns {FacadeSourceNames} Facade source definitions.
943
+ */
944
+ function facadeNames(language) {
945
+ if (language == "php")
946
+ return {
947
+ extension: "php", nativeModule: "Semantifold\\Task036\\Probe", publicName: "compatibility_probe",
948
+ unusedName: "unused_probe", unusedNativeModule: "Semantifold\\Task036\\Unused",
949
+ probeSource: `<?php
950
+ declare(strict_types=1);
951
+ namespace Semantifold\\Facade\\Php\\Probe;
952
+ use function Semantifold\\Facade\\Php\\ProbeRunner\\run_compatibility_probe;
953
+ require_once __DIR__ . "/probe-runner.php";
954
+ function compatibility_probe(string $label): string { return run_compatibility_probe($label); }
955
+ `,
956
+ runnerSource: `<?php
957
+ declare(strict_types=1);
958
+ namespace Semantifold\\Facade\\Php\\ProbeRunner;
959
+ function run_compatibility_probe(string $label): string {
960
+ try {
961
+ /**
962
+ * @var int $effect
963
+ * @semantifold-immutable
964
+ */
965
+ $effect = probeEffect($label, 1, false);
966
+ return probeTrace();
967
+ }
968
+ catch (ProbeOperationFailure $error) { return $error->getMessage(); }
969
+ }
970
+ `,
971
+ unusedSource: `<?php
972
+ declare(strict_types=1);
973
+ namespace Semantifold\\Facade\\Php\\Unused;
974
+ function unused_probe(string $label): string { return probeTrace(); }
975
+ `
976
+ };
977
+ if (language == "ruby")
978
+ return {
979
+ extension: "rb", nativeModule: "semantifold/task036/probe", publicName: "compatibility_probe",
980
+ unusedName: "unused_probe", unusedNativeModule: "semantifold/task036/unused",
981
+ probeSource: `require_relative "probe-runner"
982
+ module SemantifoldTask036Probe
983
+ module_function
984
+ # @param label [String]
985
+ # @return [String]
986
+ def compatibility_probe(label)
987
+ return SemantifoldTask036ProbeRunner.run_compatibility_probe(label)
988
+ end
989
+ end
990
+ `,
991
+ runnerSource: `module SemantifoldTask036ProbeRunner
992
+ module_function
993
+ # @param label [String]
994
+ # @return [String]
995
+ def run_compatibility_probe(label)
996
+ begin
997
+ # @type [Integer]
998
+ # @semantifold-immutable
999
+ effect = probeEffect(label, 1, false)
1000
+ return probeTrace
1001
+ rescue ProbeOperationFailure => error
1002
+ return error.message
1003
+ end
1004
+ end
1005
+ end
1006
+ `,
1007
+ unusedSource: `module SemantifoldTask036Unused
1008
+ module_function
1009
+ # @param label [String]
1010
+ # @return [String]
1011
+ def unused_probe(label)
1012
+ return probeTrace
1013
+ end
1014
+ end
1015
+ `
1016
+ };
1017
+ if (language == "java")
1018
+ return {
1019
+ extension: "java", nativeModule: "semantifold.task036.Probe", publicName: "compatibilityProbe",
1020
+ unusedName: "unusedProbe", unusedNativeModule: "semantifold.task036.Unused",
1021
+ probeSource: `package semantifold.facade.java.probe;
1022
+ import semantifold.facade.java.proberunner.ProbeRunner;
1023
+ public final class Probe {
1024
+ public static String compatibilityProbe(String label) { return ProbeRunner.runCompatibilityProbe(label); }
1025
+ }
1026
+ `,
1027
+ runnerSource: `package semantifold.facade.java.proberunner;
1028
+ public final class ProbeRunner {
1029
+ public static String runCompatibilityProbe(String label) {
1030
+ try { final int effect = probeEffect(label, 1, false); return probeTrace(); }
1031
+ catch (ProbeOperationFailure error) { return error.getMessage(); }
1032
+ }
1033
+ }
1034
+ `,
1035
+ unusedSource: `package semantifold.facade.java.unused;
1036
+ public final class Unused {
1037
+ public static String unusedProbe(String label) { return probeTrace(); }
1038
+ }
1039
+ `
1040
+ };
1041
+ const typed = language == "typescript";
1042
+ const extension = typed ? "ts" : "js";
1043
+ const parameter = typed ? "label: string" : "label";
1044
+ const result = typed ? ": string" : "";
1045
+ const documentation = typed ? "" : `/**
1046
+ * @param {string} label
1047
+ * @returns {string}
1048
+ */
1049
+ `;
1050
+ return {
1051
+ extension, nativeModule: "semantifold:task036/probe", publicName: "compatibilityProbe",
1052
+ unusedName: "unusedProbe", unusedNativeModule: "semantifold:task036/unused",
1053
+ probeSource: `import {runCompatibilityProbe} from "./probe-runner.js"
1054
+ ${documentation}export function compatibilityProbe(${parameter})${result} { return runCompatibilityProbe(label) }
1055
+ `,
1056
+ runnerSource: `${documentation}export function runCompatibilityProbe(${parameter})${result} {
1057
+ try { ${typed ? "const effect: number" : "/** @type {number} */ const effect"} = probeEffect(label, 1, false); return probeTrace() }
1058
+ catch (error) { if (!(error instanceof ProbeOperationFailure)) { throw error } return error.message }
1059
+ }
1060
+ `,
1061
+ unusedSource: `${documentation}export function unusedProbe(${parameter})${result} { return probeTrace() }
1062
+ `
1063
+ };
1064
+ }
1065
+ /**
1066
+ * Requires a closed exact key set.
1067
+ * @param {Record<string, unknown>} value - Plain candidate object.
1068
+ * @param {string[]} keys - Expected keys.
1069
+ * @param {string} subject - Diagnostic subject.
1070
+ * @returns {void}
1071
+ */
1072
+ function requireKeys(value, keys, subject) {
1073
+ if (Object.keys(value).sort().join(",") != [...keys].sort().join(","))
1074
+ invalidFacade(`Invalid ${subject} fields.`);
1075
+ }
1076
+ /**
1077
+ * Requires one non-empty string.
1078
+ * @param {unknown} value - Candidate value.
1079
+ * @param {string} subject - Diagnostic subject.
1080
+ * @returns {string} Validated string.
1081
+ */
1082
+ function requireString(value, subject) {
1083
+ if (typeof value != "string" || value.length == 0)
1084
+ invalidFacade(`${subject} must be a non-empty string.`);
1085
+ return /** @type {string} */ (value);
1086
+ }
1087
+ /**
1088
+ * Checks for an ordinary object with no custom prototype.
1089
+ * @param {unknown} value - Candidate value.
1090
+ * @returns {value is Record<string, unknown>} Whether the candidate is plain.
1091
+ */
1092
+ function isPlainObject(value) {
1093
+ return value !== null && typeof value == "object" && !Array.isArray(value) && Object.getPrototypeOf(value) == Object.prototype;
1094
+ }
1095
+ /**
1096
+ * Recursively freezes one detached facade registry value.
1097
+ * @template {object} T
1098
+ * @param {T} value - Detached object.
1099
+ * @returns {Readonly<T>} Frozen value.
1100
+ */
1101
+ function deepFreeze(value) {
1102
+ for (const child of Object.values(value))
1103
+ if (child && typeof child == "object" && !Object.isFrozen(child))
1104
+ deepFreeze(child);
1105
+ return Object.freeze(value);
1106
+ }
1107
+ /**
1108
+ * Throws a stable invalid-registry diagnostic.
1109
+ * @param {string} message - Failure detail.
1110
+ * @returns {never} Always throws.
1111
+ */
1112
+ function invalidFacade(message) {
1113
+ throw new SemantifoldDiagnostic({ code: "STDLIB_FACADE_INVALID", language: "stdlib", message });
1114
+ }
1115
+ /**
1116
+ * Throws when parser evidence does not name a registered native module.
1117
+ * @param {string} language - Source language.
1118
+ * @param {unknown} nativeModule - Unproved module identity.
1119
+ * @returns {never} Always throws.
1120
+ */
1121
+ function unprovedIdentity(language, nativeModule) {
1122
+ throw new SemantifoldDiagnostic({
1123
+ code: "STDLIB_FACADE_IDENTITY_UNPROVED",
1124
+ language: supportedLanguages.has(language) ? language : "stdlib",
1125
+ message: `Native standard-library module '${String(nativeModule)}' is not a registered '${language}' facade identity.`
1126
+ });
1127
+ }
1128
+ /**
1129
+ * Throws when a native module member is outside its public facade surface.
1130
+ * @param {string} language - Source language.
1131
+ * @param {string} nativeModule - Exact native module.
1132
+ * @param {string} symbol - Unsupported member.
1133
+ * @returns {never} Always throws.
1134
+ */
1135
+ function unsupportedMember(language, nativeModule, symbol) {
1136
+ throw new SemantifoldDiagnostic({
1137
+ code: "STDLIB_FACADE_MEMBER_UNSUPPORTED",
1138
+ language,
1139
+ message: `Native standard-library symbol '${nativeModule}#${symbol}' is outside the registered facade surface.`
1140
+ });
1141
+ }
1142
+ /**
1143
+ * Throws for a malformed facade version range.
1144
+ * @param {string} language - Source language.
1145
+ * @param {string} range - Malformed range.
1146
+ * @returns {never} Always throws.
1147
+ */
1148
+ function facadeVersionMalformed(language, range) {
1149
+ throw new SemantifoldDiagnostic({
1150
+ code: "STDLIB_FACADE_VERSION_MALFORMED", language,
1151
+ message: `Facade version range '${range}' is not canonical.`
1152
+ });
1153
+ }
1154
+ /**
1155
+ * Throws when no registered facade version satisfies a range.
1156
+ * @param {string} language - Source language.
1157
+ * @param {string} identity - Facade identity.
1158
+ * @returns {never} Always throws.
1159
+ */
1160
+ function facadeVersionIncompatible(language, identity) {
1161
+ throw new SemantifoldDiagnostic({
1162
+ code: "STDLIB_FACADE_VERSION_INCOMPATIBLE", language,
1163
+ message: `No registered version of facade '${identity}' satisfies the required compatibility range.`
1164
+ });
1165
+ }
1166
+ export const stdlibFacadeRegistry = createStdlibFacadeRegistry();
1167
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic3RkbGliLWZhY2FkZXMuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvc3RkbGliLWZhY2FkZXMuanMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsWUFBWTtBQUVaLE9BQU8sRUFBQyxZQUFZLEVBQUMsTUFBTSxZQUFZLENBQUE7QUFDdkMsT0FBTyxFQUFDLGtCQUFrQixFQUFDLE1BQU0sb0JBQW9CLENBQUE7QUFDckQsT0FBTyxFQUFDLHFCQUFxQixFQUFDLE1BQU0saUJBQWlCLENBQUE7QUFDckQsT0FBTyxFQUNMLHFCQUFxQixFQUFFLGtCQUFrQixFQUFFLHVCQUF1QixFQUFFLG1CQUFtQixFQUFFLHNCQUFzQixFQUNoSCxNQUFNLHNCQUFzQixDQUFBO0FBRTdCLE1BQU0scUJBQXFCLEdBQUcscUJBQXFCLENBQUE7QUFDbkQsTUFBTSxlQUFlLEdBQUcsNENBQTRDLENBQUE7QUFDcEUsTUFBTSxzQkFBc0IsR0FBRywyQkFBMkIsQ0FBQTtBQUMxRCxNQUFNLGtCQUFrQixHQUFHLElBQUksR0FBRyxDQUFDLENBQUMsS0FBSyxFQUFFLE1BQU0sRUFBRSxZQUFZLEVBQUUsWUFBWSxFQUFFLE1BQU0sQ0FBQyxDQUFDLENBQUE7QUFDdkYsTUFBTSxjQUFjLEdBQUcsSUFBSSxHQUFHLENBQUMsQ0FBQyxTQUFTLEVBQUUsU0FBUyxFQUFFLFFBQVEsRUFBRSxNQUFNLENBQUMsQ0FBQyxDQUFBO0FBRXhFOzs7Ozs7Ozs7O0dBVUc7QUFDSDs7Ozs7Ozs7R0FRRztBQUNILDhHQUE4RztBQUM5Rzs7Ozs7Ozs7Ozs7O0dBWUc7QUFDSDs7Ozs7Ozs7OztHQVVHO0FBQ0g7Ozs7OztHQU1HO0FBRUg7Ozs7R0FJRztBQUNILE1BQU0sVUFBVSwwQkFBMEIsQ0FBQyxPQUFPLEdBQUcsb0JBQW9CLEVBQUU7SUFDekUsSUFBSSxDQUFDLFlBQVksQ0FBQyxPQUFPLENBQUM7UUFBRSxhQUFhLENBQUMsZ0RBQWdELENBQUMsQ0FBQTtJQUMzRixtQ0FBbUM7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QVMsRUFBQyxDQUFDLENBQUMsRUFBQyxDQUFBO0lBQ3pHLE9BQU8sRUFBQyxHQUFHLFdBQVc7UUFDcEIsV0FBVyxFQUFFLEVBQUMsR0FBRyxXQUFXLENBQUMsV0FBVyxFQUFFLE9BQU8sRUFBRSxDQUFDLEdBQUcsV0FBVyxDQUFDLFdBQVcsQ0FBQyxPQUFPLENBQUMsRUFBRSxRQUFRLEVBQUUsQ0FBQyxHQUFHLFdBQVcsQ0FBQyxXQUFXLENBQUMsUUFBUSxDQUFDO1lBQ3RJLFVBQVUsRUFBRSxXQUFXLENBQUMsV0FBVyxDQUFDLFVBQVUsQ0FBQyxHQUFHLENBQUMsQ0FBQyxTQUFTLEVBQUUsRUFBRSxDQUFDLENBQUMsRUFBQyxHQUFHLFNBQVMsRUFBQyxDQUFDLENBQUMsRUFBQztRQUN0RixLQUFLLEVBQUUsQ0FBQyxHQUFHLFdBQVcsQ0FBQyxLQUFLLENBQUM7UUFDN0IsT0FBTyxFQUFFLFdBQVcsQ0FBQyxPQUFPLENBQUMsR0FBRyxDQUFDLENBQUMsTUFBTSxFQUFFLEVBQUUsQ0FBQyxDQUFDLEVBQUMsR0FBRyxNQUFNLEVBQUUsT0FBTyxFQUFFLENBQUMsR0FBRyxNQUFNLENBQUMsT0FBTyxDQUFDLEVBQUUsUUFBUSxFQUFFLENBQUMsR0FBRyxNQUFNLENBQUMsUUFBUSxDQUFDO1lBQ3BILEtBQUssRUFBRSxDQUFDLEdBQUcsTUFBTSxDQUFDLEtBQUssQ0FBQyxFQUFFLFVBQVUsRUFBRSxNQUFNLENBQUMsVUFBVSxDQUFDLEdBQUcsQ0FBQyxDQUFDLFNBQVMsRUFBRSxFQUFFLENBQUMsQ0FBQyxFQUFDLEdBQUcsU0FBUyxFQUFDLENBQUMsQ0FBQyxFQUFDLENBQUMsQ0FBQyxFQUFDLENBQUE7QUFDdEcsQ0FBQztBQUVEOzs7O0dBSUc7QUFDSCxTQUFTLHdCQUF3QixDQUFDLFNBQVM7SUFDekMsT0FBTyxPQUFPLFNBQVMsSUFBSSxRQUFRLENBQUMsQ0FBQyxDQUFDLFNBQVMsQ0FBQyxDQUFDLENBQUMsRUFBQyxNQUFNLEVBQUUsU0FBUyxDQUFDLE1BQU0sRUFBRSxJQUFJLEVBQUUsU0FBUyxDQUFD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QTtBQUNKLENBQUM7QUFFRDs7Ozs7O0dBTUc7QUFDSCxTQUFTLGlCQUFpQixDQUFDLFFBQVEsRUFBRSxZQUFZLEVBQUUsTUFBTTtJQUN2RCxNQUFNLElBQUkscUJBQXFCLENBQUM7UUFDOUIsSUFBSSxFQUFFLGtDQUFrQztRQUN4QyxRQUFRO1FBQ1IsT0FBTyxFQUFFLG1DQUFtQyxZQUFZLElBQUksTUFBTSw2Q0FBNkM7S0FDaEgsQ0FBQyxDQUFBO0FBQ0osQ0FBQztBQUVEOzs7OztHQUtHO0FBQ0gsU0FBUyxzQkFBc0IsQ0FBQyxRQUFRLEVBQUUsS0FBSztJQUM3QyxNQUFNLElBQUkscUJBQXFCLENBQUM7UUFDOUIsSUFBSSxFQUFFLGlDQUFpQyxFQUFFLFFBQVE7UUFDakQsT0FBTyxFQUFFLHlCQUF5QixLQUFLLHFCQUFxQjtLQUM3RCxDQUFDLENBQUE7QUFDSixDQUFDO0FBRUQ7Ozs7O0dBS0c7QUFDSCxTQUFTLHlCQUF5QixDQUFDLFFBQVEsRUFBRSxRQUFRO0lBQ25ELE1BQU0sSUFBSSxxQkFBcUIsQ0FBQztRQUM5QixJQUFJLEVBQUUsb0NBQW9DLEVBQUUsUUFBUTtRQUNwRCxPQUFPLEVBQUUsb0NBQW9DLFFBQVEsK0NBQStDO0tBQ3JHLENBQUMsQ0FBQTtBQUNKLENBQUM7QUFFRCxNQUFNLENBQUMsTUFBTSxvQkFBb0IsR0FBRywwQkFBMEIsRUFBRSxDQUFBIiwic291cmNlc0NvbnRlbnQiOlsiLy8gQHRzLWNoZWNrXG5cbmltcG9ydCB7aXNEZW5zZUFycmF5fSBmcm9tIFwiLi9hcnJheS5qc1wiXG5pbXBvcnQge2lzU2FmZUFydGlmYWN0UGF0aH0gZnJvbSBcIi4vYXJ0aWZhY3QtcGF0aC5qc1wiXG5pbXBvcnQge1NlbWFudGlmb2xkRGlhZ25vc3RpY30gZnJvbSBcIi4vZGlhZ25vc3RpYy5qc1wiXG5pbXBvcnQge1xuICBjb21wYXJlU3RkbGliVmVyc2lvbnMsIHBhcnNlU3RkbGliVmVyc2lvbiwgcGFyc2VTdGRsaWJWZXJzaW9uUmFuZ2UsIHJlc29sdmVTdGRsaWJNb2R1bGUsIHN0ZGxpYlZlcnNpb25TYXRpc2ZpZXNcbn0gZnJvbSBcIi4vc2VtYW50aWMvc3RkbGliLmpzXCJcblxuY29uc3QgZmFjYWRlSWRlbnRpdHlQYXR0ZXJuID0gL15bYS16XVthLXowLTkuLV0qJC91XG5jb25zdCBtb2R1bGVJZFBhdHRlcm4gPSAvXlthLXpdW2EtejAtOV9dKig/OlsuLV1bYS16XVthLXowLTlfXSopKiQvdVxuY29uc3QgZGVjbGFyYXRpb25OYW1lUGF0dGVybiA9IC9eW0EtWmEtel9dW0EtWmEtejAtOV9dKiQvdVxuY29uc3Qgc3VwcG9ydGVkTGFuZ3VhZ2VzID0gbmV3IFNldChbXCJwaHBcIiwgXCJydWJ5XCIsIFwiamF2YXNjcmlwdFwiLCBcInR5cGVzY3JpcHRcIiwgXCJqYXZhXCJdKVxuY29uc3QgY2Fub25pY2FsVHlwZXMgPSBuZXcgU2V0KFtcImJvb2xlYW5cIiwgXCJpbnRlZ2VyXCIsIFwic3RyaW5nXCIsIFwidm9pZFwiXSlcblxuLyoqXG4gKiBAdHlwZWRlZiBTdGRsaWJGYWNhZGVGdW5jdGlvbkRlY2xhcmF0aW9uXG4gKiBAcHJvcGVydHkge1wiZnVuY3Rpb25cIn0ga2luZCAtIENsb3NlZCBwdWJsaWMgZGVjbGFyYXRpb24ga2luZC5cbiAqIEBwcm9wZXJ0eSB7c3RyaW5nfSBuYW1lIC0gRXhhY3Qgc291cmNlLXZpc2libGUgc3ltYm9sLlxuICogQHByb3BlcnR5IHt7bmFtZTogc3RyaW5nLCB0eXBlOiBzdHJpbmd9W119IHBhcmFtZXRlcnMgLSBPcmRlcmVkIHNvdXJjZSBzaWduYXR1cmUuXG4gKiBAcHJvcGVydHkge3N0cmluZ30gcmV0dXJuVHlwZSAtIENhbm9uaWNhbCByZXN1bHQgdHlwZS5cbiAqIEBwcm9wZXJ0eSB7c3RyaW5nW119IGVmZmVjdHMgLSBDbG9zZWQgcHVibGljIGVmZmVjdHMuXG4gKiBAcHJvcGVydHkge3N0cmluZ1tdfSBmYWlsdXJlcyAtIEVzY2FwaW5nIGNhbm9uaWNhbCBmYWlsdXJlIG5hbWVzLlxuICogQHByb3BlcnR5IHsoXCJkaXJlY3QtY2FsbFwiIHwgXCJ1bnF1YWxpZmllZC1jYWxsXCIgfCBcInJlY2VpdmVyLWNhbGxcIilbXX0gZm9ybXMgLSBBY2NlcHRlZCBzb3VyY2UgY2FsbCBmb3Jtcy5cbiAqIEBwcm9wZXJ0eSB7XCJub3QtYXBwbGljYWJsZVwifSBvd25lcnNoaXAgLSBJbml0aWFsIHNjYWxhciBxdWFsaWZpY2F0aW9uIG93bmVyc2hpcC5cbiAqL1xuLyoqXG4gKiBAdHlwZWRlZiBTdGRsaWJGYWNhZGVDbGFzc0RlY2xhcmF0aW9uXG4gKiBAcHJvcGVydHkge1wiY2xhc3NcIn0ga2luZCAtIENsb3NlZCBwdWJsaWMgZGVjbGFyYXRpb24ga2luZC5cbiAqIEBwcm9wZXJ0eSB7c3RyaW5nfSBuYW1lIC0gRXhhY3Qgc291cmNlLXZpc2libGUgY2xhc3Mgc3ltYm9sLlxuICogQHByb3BlcnR5IHtbXCJjb25zdHJ1Y3Rvci1jYWxsXCJdfSBmb3JtcyAtIEFjY2VwdGVkIGNvbnN0cnVjdGlvbiBmb3JtLlxuICogQHByb3BlcnR5IHtcIm93bmVkLXJlZmVyZW5jZVwifSBvd25lcnNoaXAgLSBDbGFzcyBpbnN0YW5jZSBvd25lcnNoaXAuXG4gKiBAcHJvcGVydHkge3tlZmZlY3RzOiBzdHJpbmdbXSwgZmFpbHVyZXM6IHN0cmluZ1tdLCBvd25lcnNoaXA6IFwiYWNxdWlyZWRcIiwgcGFyYW1ldGVyczoge25hbWU6IHN0cmluZywgdHlwZTogc3RyaW5nfVtdfX0gY29uc3RydWN0b3IgLSBDb25zdHJ1Y3RvciBjb250cmFjdC5cbiAqIEBwcm9wZXJ0eSB7e2VmZmVjdHM6IHN0cmluZ1tdLCBmYWlsdXJlczogc3RyaW5nW10sIGZvcm1zOiBbXCJyZWNlaXZlci1jYWxsXCJdLCBuYW1lOiBzdHJpbmcsIG93bmVyc2hpcDogXCJib3Jyb3dlZFwiIHwgXCJjb25zdW1lZFwiLCBwYXJhbWV0ZXJzOiB7bmFtZTogc3RyaW5nLCB0eXBlOiBzdHJpbmd9W10sIHJldHVyblR5cGU6IHN0cmluZ31bXX0gbWV0aG9kcyAtIFB1YmxpYyBpbnN0YW5jZSBtZXRob2RzLlxuICovXG4vKiogQHR5cGVkZWYge1N0ZGxpYkZhY2FkZUZ1bmN0aW9uRGVjbGFyYXRpb24gfCBTdGRsaWJGYWNhZGVDbGFzc0RlY2xhcmF0aW9ufSBTdGRsaWJGYWNhZGVQdWJsaWNEZWNsYXJhdGlvbiAqL1xuLyoqXG4gKiBAdHlwZWRlZiBTdGRsaWJGYWNhZGVSZWNvcmRcbiAqIEBwcm9wZXJ0eSB7e2lkZW50aXR5OiBzdHJpbmcsIHJhbmdlOiBzdHJpbmd9W119IGRlcGVuZGVuY2llcyAtIEZhY2FkZS1tb2R1bGUgZGVwZW5kZW5jaWVzLlxuICogQHByb3BlcnR5IHtzdHJpbmd9IGlkZW50aXR5IC0gVmVyc2lvbmVkIGZhY2FkZSBpZGVudGl0eS5cbiAqIEBwcm9wZXJ0eSB7aW1wb3J0KFwiLi9zZW1hbnRpYy90eXBlcy5qc1wiKS5TZW1hbnRpY0xhbmd1YWdlfSBsYW5ndWFnZSAtIFNvdXJjZSBsYW5ndWFnZS5cbiAqIEBwcm9wZXJ0eSB7KHtpZGVudGl0eTogc3RyaW5nLCBraW5kOiBcIm1vZHVsZVwiLCBzeW1ib2xzOiBzdHJpbmdbXX0gfCB7Zm9ybXM6IChcInVucXVhbGlmaWVkLWNhbGxcIiB8IFwicmVjZWl2ZXItY2FsbFwiKVtdLCBpZGVudGl0eTogc3RyaW5nLCBraW5kOiBcImJ1aWx0aW5cIiwgc3ltYm9sczogc3RyaW5nW119KVtdfSBuYXRpdmVNb2R1bGVzIC0gRXhhY3Qgc291cmNlIG5hdGl2ZSBpZGVudGl0aWVzLlxuICogQHByb3BlcnR5IHtTdGRsaWJGYWNhZGVQdWJsaWNEZWNsYXJhdGlvbltdfSBwdWJsaWNEZWNsYXJhdGlvbnMgLSBQdWJsaWMgc291cmNlIHN1cmZhY2UuXG4gKiBAcHJvcGVydHkge3ttb2R1bGU6IHN0cmluZywgb3BlcmF0aW9uczogc3RyaW5nW10sIHJhbmdlOiBzdHJpbmd9W119IHJlcXVpcmVtZW50cyAtIENhbm9uaWNhbC1vbmx5IHJlcXVpcmVtZW50cy5cbiAqIEBwcm9wZXJ0eSB7c3RyaW5nfSBydW50aW1lUHJvZmlsZSAtIEV4YWN0IGNvbXBhdGlibGUgc291cmNlL3J1bnRpbWUgcHJvZmlsZS5cbiAqIEBwcm9wZXJ0eSB7e2NvbnRlbnQ6IHN0cmluZywgZmlsZW5hbWU6IHN0cmluZywgaWQ6IHN0cmluZ319IHNvdXJjZSAtIEV4ZWN1dGFibGUgY29tcGlsZXItb3duZWQgc291cmNlIG1vZHVsZS5cbiAqIEBwcm9wZXJ0eSB7c3RyaW5nfSB2ZXJzaW9uIC0gRXhhY3QgZmFjYWRlIHZlcnNpb24uXG4gKiBAcHJvcGVydHkge1wiaW50ZXJuYWxcIiB8IFwicHVibGljXCJ9IHZpc2liaWxpdHkgLSBOYXRpdmUtc2VsZWN0YWJsZSB2aXNpYmlsaXR5LlxuICovXG4vKipcbiAqIEB0eXBlZGVmIEZhY2FkZVNvdXJjZU5hbWVzXG4gKiBAcHJvcGVydHkge3N0cmluZ30gZXh0ZW5zaW9uIC0gU291cmNlIGZpbGVuYW1lIGV4dGVuc2lvbi5cbiAqIEBwcm9wZXJ0eSB7c3RyaW5nfSBuYXRpdmVNb2R1bGUgLSBQdWJsaWMgbmF0aXZlIHN0ZGxpYiBtb2R1bGUgaWRlbnRpdHkuXG4gKiBAcHJvcGVydHkge3N0cmluZ30gcHVibGljTmFtZSAtIFB1YmxpYyBuYXRpdmUgc3ltYm9sLlxuICogQHByb3BlcnR5IHtzdHJpbmd9IHVudXNlZE5hbWUgLSBVbnVzZWQtZWxpbWluYXRpb24gZml4dHVyZSBzeW1ib2wuXG4gKiBAcHJvcGVydHkge3N0cmluZ30gdW51c2VkTmF0aXZlTW9kdWxlIC0gVW51c2VkLWVsaW1pbmF0aW9uIGZpeHR1cmUgbW9kdWxlLlxuICogQHByb3BlcnR5IHtzdHJpbmd9IHByb2JlU291cmNlIC0gUHVibGljIGV4ZWN1dGFibGUgZmFjYWRlIHNvdXJjZS5cbiAqIEBwcm9wZXJ0eSB7c3RyaW5nfSBydW5uZXJTb3VyY2UgLSBJbnRlcm5hbCBjYW5vbmljYWwgcnVubmVyIHNvdXJjZS5cbiAqIEBwcm9wZXJ0eSB7c3RyaW5nfSB1bnVzZWRTb3VyY2UgLSBVbnVzZWQgZXhlY3V0YWJsZSBmYWNhZGUgc291cmNlLlxuICovXG4vKipcbiAqIEB0eXBlZGVmIFN0ZGxpYkZhY2FkZVJlZ2lzdHJ5XG4gKiBAcHJvcGVydHkge3JlYWRvbmx5IFN0ZGxpYkZhY2FkZVJlY29yZFtdfSBmYWNhZGVzIC0gU3RhYmxlIGltbXV0YWJsZSBmYWNhZGUgcmVjb3Jkcy5cbiAqIEBwcm9wZXJ0eSB7KGxhbmd1YWdlOiBzdHJpbmcsIG5hdGl2ZU1vZHVsZTogc3RyaW5nLCBzeW1ib2w6IHN0cmluZywgcmFuZ2U/OiBzdHJpbmcpID0+IFN0ZGxpYkZhY2FkZVJlY29yZH0gcmVzb2x2ZUZhY2FkZSAtIEV4YWN0IG5hdGl2ZSBpZGVudGl0eSByZXNvbHZlci5cbiAqIEBwcm9wZXJ0eSB7KGlkZW50aXR5OiBzdHJpbmcsIGxhbmd1YWdlOiBzdHJpbmcsIHJhbmdlPzogc3RyaW5nKSA9PiBTdGRsaWJGYWNhZGVSZWNvcmR9IHJlc29sdmVJZGVudGl0eSAtIEZhY2FkZSBkZXBlbmRlbmN5IHJlc29sdmVyLlxuICogQHByb3BlcnR5IHsobGFuZ3VhZ2U6IHN0cmluZywgbmF0aXZlTW9kdWxlOiBzdHJpbmcsIHJhbmdlPzogc3RyaW5nKSA9PiBTdGRsaWJGYWNhZGVSZWNvcmR9IHJlc29sdmVNb2R1bGUgLSBFeGFjdCBuYXRpdmUgbW9kdWxlIHJlc29sdmVyLlxuICovXG5cbi8qKlxuICogQ3JlYXRlcyBhIGRldGFjaGVkIGltbXV0YWJsZSBzb3VyY2UtbGFuZ3VhZ2UgZmFjYWRlIHJlZ2lzdHJ5LlxuICogQHBhcmFtIHt1bmtub3dufSByZWNvcmRzIC0gT3B0aW9uYWwgZmFjYWRlIGRlZmluaXRpb25zOyBidWlsdC1pbiBxdWFsaWZpY2F0aW9uIGRlZmluaXRpb25zIGJ5IGRlZmF1bHQuXG4gKiBAcmV0dXJucyB7UmVhZG9ubHk8U3RkbGliRmFjYWRlUmVnaXN0cnk+fSBWYWxpZGF0ZWQgZmFjYWRlIHJlZ2lzdHJ5LlxuICovXG5leHBvcnQgZnVuY3Rpb24gY3JlYXRlU3RkbGliRmFjYWRlUmVnaXN0cnkocmVjb3JkcyA9IGJ1aWx0aW5GYWNhZGVSZWNvcmRzKCkpIHtcbiAgaWYgKCFpc0RlbnNlQXJyYXkocmVjb3JkcykpIGludmFsaWRGYWNhZGUoXCJGYWNhZGUgcmVjb3JkcyBtdXN0IGJlIGFuIG9yZGVyZWQgZGVuc2UgYXJyYXkuXCIpXG4gIC8qKiBAdHlwZSB7U3RkbGliRmFjYWRlUmVjb3JkW119ICovXG4gIGNvbnN0IGZhY2FkZXMgPSBbXVxuICAvKiogQHR5cGUge01hcDxzdHJpbmcsIE1hcDxzdHJpbmcsIFN0ZGxpYkZhY2FkZVJlY29yZD4+fSAqL1xuICBjb25zdCBieUlkZW50aXR5ID0gbmV3IE1hcCgpXG4gIC8qKiBAdHlwZSB7TWFwPHN0cmluZywgU3RkbGliRmFjYWRlUmVjb3JkW10+fSAqL1xuICBjb25zdCBieU5hdGl2ZU1vZHVsZSA9IG5ldyBNYXAoKVxuICBjb25zdCBzb3VyY2VJZHMgPSBuZXcgTWFwKClcbiAgY29uc3Qgc291cmNlRmlsZW5hbWVzID0gbmV3IE1hcCgpXG5cbiAgZm9yIChsZXQgaW5kZXggPSAwOyBpbmRleCA8IHJlY29yZHMubGVuZ3RoOyBpbmRleCArPSAxKSB7XG4gICAgY29uc3QgcmVjb3JkID0gdmFsaWRhdGVGYWNhZGVSZWNvcmQocmVjb3Jkc1tpbmRleF0pXG4gICAgY29uc3QgaWRlbnRpdHlLZXkgPSBgJHtyZWNvcmQubGFuZ3VhZ2V9XFwwJHtyZWNvcmQuaWRlbnRpdHl9YFxuICAgIGNvbnN0IHZlcnNpb25zID0gYnlJZGVudGl0eS5nZXQoaWRlbnRpdHlLZXkpID8/IG5ldyBNYXAoKVxuXG4gICAgaWYgKHZlcnNpb25zLmhhcyhyZWNvcmQudmVyc2lvbikpIGludmFsaWRGYWNhZGUoYER1cGxpY2F0ZSBmYWNhZGUgJyR7cmVjb3JkLmlkZW50aXR5fScgdmVyc2lvbiAnJHtyZWNvcmQudmVyc2lvbn0nIGZvciAnJHtyZWNvcmQubGFuZ3VhZ2V9Jy5gKVxuICAgIGlmIChzb3VyY2VJZHMuaGFzKHJlY29yZC5zb3VyY2UuaWQpICYmIHNvdXJjZUlkcy5nZXQocmVjb3JkLnNvdXJjZS5pZCkgIT0gaWRlbnRpdHlLZXkpIHtcbiAgICAgIGludmFsaWRGYWNhZGUoYER1cGxpY2F0ZSBmYWNhZGUgc291cmNlIG1vZHVsZSBpZGVudGl0eSAnJHtyZWNvcmQuc291cmNlLmlkfScuYClcbiAgICB9XG4gICAgaWYgKHNvdXJjZUZpbGVuYW1lcy5oYXMocmVjb3JkLnNvdXJjZS5maWxlbmFtZSkgJiYgc291cmNlRmlsZW5hbWVzLmdldChyZWNvcmQuc291cmNlLmZpbGVuYW1lKSAhPSBpZGVudGl0eUtleSkge1xuICAgICAgaW52YWxpZEZhY2FkZShgRHVwbGljYXRlIGZhY2FkZSBzb3VyY2UgZmlsZW5hbWUgJyR7cmVjb3JkLnNvdXJjZS5maWxlbmFtZX0nLmApXG4gICAgfVxuICAgIHZlcnNpb25zLnNldChyZWNvcmQudmVyc2lvbiwgcmVjb3JkKVxuICAgIGJ5SWRlbnRpdHkuc2V0KGlkZW50aXR5S2V5LCB2ZXJzaW9ucylcbiAgICBzb3VyY2VJZHMuc2V0KHJlY29yZC5zb3VyY2UuaWQsIGlkZW50aXR5S2V5KVxuICAgIHNvdXJjZUZpbGVuYW1lcy5zZXQocmVjb3JkLnNvdXJjZS5maWxlbmFtZSwgaWRlbnRpdHlLZXkpXG4gICAgZmFjYWRlcy5wdXNoKHJlY29yZClcblxuICAgIGZvciAoY29uc3QgbmF0aXZlTW9kdWxlIG9mIHJlY29yZC5uYXRpdmVNb2R1bGVzKSB7XG4gICAgICBjb25zdCBuYXRpdmVLZXkgPSBgJHtyZWNvcmQubGFuZ3VhZ2V9XFwwJHtuYXRpdmVNb2R1bGUuaWRlbnRpdHl9YFxuICAgICAgY29uc3QgbmF0aXZlUmVjb3JkcyA9IGJ5TmF0aXZlTW9kdWxlLmdldChuYXRpdmVLZXkpID8/IFtdXG5cbiAgICAgIG5hdGl2ZVJlY29yZHMucHVzaChyZWNvcmQpXG4gICAgICBieU5hdGl2ZU1vZHVsZS5zZXQobmF0aXZlS2V5LCBuYXRpdmVSZWNvcmRzKVxuICAgIH1cbiAgfVxuXG4gIGZvciAoY29uc3QgcmVjb3JkIG9mIGZhY2FkZXMpIHtcbiAgICBmb3IgKGNvbnN0IGRlcGVuZGVuY3kgb2YgcmVjb3JkLmRlcGVuZGVuY2llcykge1xuICAgICAgcmVzb2x2ZUlkZW50aXR5RnJvbVN0b3JlKGJ5SWRlbnRpdHksIGRlcGVuZGVuY3kuaWRlbnRpdHksIHJlY29yZC5sYW5ndWFnZSwgZGVwZW5kZW5jeS5yYW5nZSwgcmVjb3JkLmlkZW50aXR5KVxuICAgIH1cbiAgfVxuICB2YWxpZGF0ZUZhY2FkZURlcGVuZGVuY3lDeWNsZXMoZmFjYWRlcywgYnlJZGVudGl0eSlcblxuICByZXR1cm4gT2JqZWN0LmZyZWV6ZSgvKiogQHR5cGUge1N0ZGxpYkZhY2FkZVJlZ2lzdHJ5fSAqLyAoe1xuICAgIGZhY2FkZXM6IE9iamVjdC5mcmVlemUoZmFjYWRlcyksXG4gICAgcmVzb2x2ZUZhY2FkZShsYW5ndWFnZSwgbmF0aXZlTW9kdWxlLCBzeW1ib2wsIHJhbmdlKSB7XG4gICAgICByZXR1cm4gcmVzb2x2ZU5hdGl2ZUZhY2FkZUZyb21TdG9yZShieU5hdGl2ZU1vZHVsZSwgbGFuZ3VhZ2UsIG5hdGl2ZU1vZHVsZSwgc3ltYm9sLCByYW5nZSlcbiAgICB9LFxuICAgIHJlc29sdmVJZGVudGl0eShpZGVudGl0eSwgbGFuZ3VhZ2UsIHJhbmdlKSB7XG4gICAgICByZXR1cm4gcmVzb2x2ZUlkZW50aXR5RnJvbVN0b3JlKGJ5SWRlbnRpdHksIGlkZW50aXR5LCBsYW5ndWFnZSwgcmFuZ2UpXG4gICAgfSxcbiAgICByZXNvbHZlTW9kdWxlKGxhbmd1YWdlLCBuYXRpdmVNb2R1bGUsIHJhbmdlKSB7XG4gICAgICBjb25zdCByZWNvcmRzID0gYnlOYXRpdmVNb2R1bGUuZ2V0KGAke2xhbmd1YWdlfVxcMCR7bmF0aXZlTW9kdWxlfWApXG5cbiAgICAgIGlmICghcmVjb3JkcykgdW5wcm92ZWRJZGVudGl0eShsYW5ndWFnZSwgbmF0aXZlTW9kdWxlKVxuICAgICAgY29uc3QgaWRlbnRpdGllcyA9IG5ldyBTZXQoLyoqIEB0eXBlIHtTdGRsaWJGYWNhZGVSZWNvcmRbXX0gKi8gKHJlY29yZHMpLm1hcCgoe2lkZW50aXR5fSkgPT4gaWRlbnRpdHkpKVxuXG4gICAgICBpZiAoaWRlbnRpdGllcy5zaXplICE9IDEpIGludmFsaWRGYWNhZGUoYE5hdGl2ZSBmYWNhZGUgbW9kdWxlICcke25hdGl2ZU1vZHVsZX0nIGlzIGFtYmlndW91cyBmb3IgJyR7bGFuZ3VhZ2V9Jy5gKVxuICAgICAgcmV0dXJuIHNlbGVjdEZhY2FkZVZlcnNpb24obmV3IE1hcCgvKiogQHR5cGUge1N0ZGxpYkZhY2FkZVJlY29yZFtdfSAqLyAocmVjb3JkcykubWFwKChyZWNvcmQpID0+IFtyZWNvcmQudmVyc2lvbiwgcmVjb3JkXSkpLFxuICAgICAgICAvKiogQHR5cGUge1N0ZGxpYkZhY2FkZVJlY29yZH0gKi8gKHJlY29yZHNbMF0pLmlkZW50aXR5LCBsYW5ndWFnZSwgcmFuZ2UpXG4gICAgfVxuICB9KSlcbn1cblxuLyoqXG4gKiBSZWplY3RzIGN5Y2xlcyBhZnRlciBldmVyeSB2ZXJzaW9uZWQgZGVwZW5kZW5jeSBoYXMgcmVzb2x2ZWQgc3VjY2Vzc2Z1bGx5LlxuICogQHBhcmFtIHtTdGRsaWJGYWNhZGVSZWNvcmRbXX0gZmFjYWRlcyAtIFZhbGlkYXRlZCBmYWNhZGUgcmVjb3Jkcy5cbiAqIEBwYXJhbSB7TWFwPHN0cmluZywgTWFwPHN0cmluZywgU3RkbGliRmFjYWRlUmVjb3JkPj59IHN0b3JlIC0gUmVjb3JkcyBieSBsYW5ndWFnZSBhbmQgaWRlbnRpdHkuXG4gKiBAcmV0dXJucyB7dm9pZH1cbiAqL1xuZnVuY3Rpb24gdmFsaWRhdGVGYWNhZGVEZXBlbmRlbmN5Q3ljbGVzKGZhY2FkZXMsIHN0b3JlKSB7XG4gIGNvbnN0IGFjdGl2ZSA9IG5ldyBTZXQoKVxuICBjb25zdCBjb21wbGV0ZSA9IG5ldyBTZXQoKVxuXG4gIC8qKlxuICAgKiBWaXNpdHMgb25lIGV4YWN0IHNlbGVjdGVkIGZhY2FkZSB2ZXJzaW9uLlxuICAgKiBAcGFyYW0ge1N0ZGxpYkZhY2FkZVJlY29yZH0gcmVjb3JkIC0gRmFjYWRlIHJlY29yZC5cbiAgICogQHJldHVybnMge3ZvaWR9XG4gICAqL1xuICBmdW5jdGlvbiB2aXNpdChyZWNvcmQpIHtcbiAgICBjb25zdCBrZXkgPSBgJHtyZWNvcmQubGFuZ3VhZ2V9XFwwJHtyZWNvcmQuaWRlbnRpdHl9XFwwJHtyZWNvcmQudmVyc2lvbn1gXG5cbiAgICBpZiAoY29tcGxldGUuaGFzKGtleSkpIHJldHVyblxuICAgIGlmIChhY3RpdmUuaGFzKGtleSkpIGludmFsaWRGYWNhZGUoYEZhY2FkZSBkZXBlbmRlbmN5IGN5Y2xlIGluY2x1ZGVzICcke3JlY29yZC5pZGVudGl0eX0nLmApXG4gICAgYWN0aXZlLmFkZChrZXkpXG4gICAgZm9yIChjb25zdCBkZXBlbmRlbmN5IG9mIHJlY29yZC5kZXBlbmRlbmNpZXMpIHtcbiAgICAgIHZpc2l0KHJlc29sdmVJZGVudGl0eUZyb21TdG9yZShzdG9yZSwgZGVwZW5kZW5jeS5pZGVudGl0eSwgcmVjb3JkLmxhbmd1YWdlLCBkZXBlbmRlbmN5LnJhbmdlLCByZWNvcmQuaWRlbnRpdHkpKVxuICAgIH1cbiAgICBhY3RpdmUuZGVsZXRlKGtleSlcbiAgICBjb21wbGV0ZS5hZGQoa2V5KVxuICB9XG5cbiAgZm9yIChjb25zdCByZWNvcmQgb2YgZmFjYWRlcykgdmlzaXQocmVjb3JkKVxufVxuXG4vKipcbiAqIExpc3RzIGFsbCBidWlsdC1pbiBwdWJsaWMgYW5kIGludGVybmFsIGZhY2FkZSBtb2R1bGVzIGluIHN0YWJsZSBvcmRlci5cbiAqIEByZXR1cm5zIHtyZWFkb25seSBTdGRsaWJGYWNhZGVSZWNvcmRbXX0gSW1tdXRhYmxlIGZhY2FkZSBkZWZpbml0aW9ucy5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGxpc3RTdGRsaWJGYWNhZGVzKCkge1xuICByZXR1cm4gc3RkbGliRmFjYWRlUmVnaXN0cnkuZmFjYWRlc1xufVxuXG4vKipcbiAqIFJlc29sdmVzIG9uZSBidWlsdC1pbiBmYWNhZGUgZnJvbSBwYXJzZXItcHJvdmVkIG5hdGl2ZSBtb2R1bGUgYW5kIHN5bWJvbCBpZGVudGl0aWVzLlxuICogQHBhcmFtIHtzdHJpbmd9IGxhbmd1YWdlIC0gU291cmNlIGxhbmd1YWdlLlxuICogQHBhcmFtIHtzdHJpbmd9IG5hdGl2ZU1vZHVsZSAtIEV4YWN0IG5hdGl2ZSBtb2R1bGUgaWRlbnRpdHkuXG4gKiBAcGFyYW0ge3N0cmluZ30gc3ltYm9sIC0gRXhhY3QgaW1wb3J0ZWQgb3IgcXVhbGlmaWVkIHN5bWJvbC5cbiAqIEBwYXJhbSB7c3RyaW5nfSBbcmFuZ2VdIC0gQ29tcGF0aWJsZSBmYWNhZGUgdmVyc2lvbiByYW5nZS5cbiAqIEByZXR1cm5zIHtTdGRsaWJGYWNhZGVSZWNvcmR9IEltbXV0YWJsZSBmYWNhZGUgZGVmaW5pdGlvbi5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHJlc29sdmVTdGRsaWJGYWNhZGUobGFuZ3VhZ2UsIG5hdGl2ZU1vZHVsZSwgc3ltYm9sLCByYW5nZSkge1xuICByZXR1cm4gc3RkbGliRmFjYWRlUmVnaXN0cnkucmVzb2x2ZUZhY2FkZShsYW5ndWFnZSwgbmF0aXZlTW9kdWxlLCBzeW1ib2wsIHJhbmdlKVxufVxuXG4vKipcbiAqIFJlc29sdmVzIGEgZGVwZW5kZW5jeS1maXJzdCwgY3ljbGUtZnJlZSBmYWNhZGUgbW9kdWxlIGNsb3N1cmUuXG4gKiBAcGFyYW0ge1N0ZGxpYkZhY2FkZVJlY29yZFtdfSByb290cyAtIFBhcnNlci1zZWxlY3RlZCBmYWNhZGUgcm9vdHMuXG4gKiBAcGFyYW0ge1JlYWRvbmx5PFN0ZGxpYkZhY2FkZVJlZ2lzdHJ5Pn0gW3JlZ2lzdHJ5XSAtIEZhY2FkZSByZWdpc3RyeS5cbiAqIEByZXR1cm5zIHtTdGRsaWJGYWNhZGVSZWNvcmRbXX0gU3RhYmxlIGRlcGVuZGVuY3ktZmlyc3QgY2xvc3VyZS5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHJlc29sdmVTdGRsaWJGYWNhZGVDbG9zdXJlKHJvb3RzLCByZWdpc3RyeSA9IHN0ZGxpYkZhY2FkZVJlZ2lzdHJ5KSB7XG4gIGNvbnN0IGFjdGl2ZSA9IG5ldyBTZXQoKVxuICBjb25zdCBjb21wbGV0ZSA9IG5ldyBTZXQoKVxuICAvKiogQHR5cGUge1N0ZGxpYkZhY2FkZVJlY29yZFtdfSAqL1xuICBjb25zdCByZXN1bHQgPSBbXVxuXG4gIC8qKlxuICAgKiBWaXNpdHMgb25lIHNlbGVjdGVkIGZhY2FkZSBhbmQgaXRzIGRlY2xhcmVkIGRlcGVuZGVuY2llcy5cbiAgICogQHBhcmFtIHtTdGRsaWJGYWNhZGVSZWNvcmR9IHJlY29yZCAtIEZhY2FkZSB0byB2aXNpdC5cbiAgICogQHJldHVybnMge3ZvaWR9XG4gICAqL1xuICBmdW5jdGlvbiB2aXNpdChyZWNvcmQpIHtcbiAgICBjb25zdCBrZXkgPSBgJHtyZWNvcmQubGFuZ3VhZ2V9XFwwJHtyZWNvcmQuaWRlbnRpdHl9XFwwJHtyZWNvcmQudmVyc2lvbn1gXG5cbiAgICBpZiAoY29tcGxldGUuaGFzKGtleSkpIHJldHVyblxuICAgIGlmIChhY3RpdmUuaGFzKGtleSkpIGludmFsaWRGYWNhZGUoYEZhY2FkZSBkZXBlbmRlbmN5IGN5Y2xlIGluY2x1ZGVzICcke3JlY29yZC5pZGVudGl0eX0nLmApXG4gICAgYWN0aXZlLmFkZChrZXkpXG4gICAgZm9yIChjb25zdCBkZXBlbmRlbmN5IG9mIHJlY29yZC5kZXBlbmRlbmNpZXMpIHtcbiAgICAgIHZpc2l0KHJlZ2lzdHJ5LnJlc29sdmVJZGVudGl0eShkZXBlbmRlbmN5LmlkZW50aXR5LCByZWNvcmQubGFuZ3VhZ2UsIGRlcGVuZGVuY3kucmFuZ2UpKVxuICAgIH1cbiAgICBhY3RpdmUuZGVsZXRlKGtleSlcbiAgICBjb21wbGV0ZS5hZGQoa2V5KVxuICAgIHJlc3VsdC5wdXNoKHJlY29yZClcbiAgfVxuXG4gIGZvciAoY29uc3Qgcm9vdCBvZiByb290cykgdmlzaXQocm9vdClcbiAgcmV0dXJuIHJlc3VsdFxufVxuXG4vKipcbiAqIENyZWF0ZXMgdGhlIGRldGFjaGVkLCBkZXRlcm1pbmlzdGljIHByb2dyYW0gZGVzY3JpcHRvciBmb3Igb25lIHNlbGVjdGVkIGZhY2FkZSBjbG9zdXJlLlxuICogQHBhcmFtIHtpbXBvcnQoXCIuL3NlbWFudGljL3R5cGVzLmpzXCIpLlNlbWFudGljTGFuZ3VhZ2V9IGxhbmd1YWdlIC0gU291cmNlIGxhbmd1YWdlIHByb2ZpbGUuXG4gKiBAcGFyYW0ge1N0ZGxpYkZhY2FkZVJlY29yZFtdfSBmYWNhZGVzIC0gRGVwZW5kZW5jeS1maXJzdCBzZWxlY3RlZCBmYWNhZGUgcmVjb3Jkcy5cbiAqIEByZXR1cm5zIHtpbXBvcnQoXCIuL3NlbWFudGljL3R5cGVzLmpzXCIpLlN0ZGxpYkZhY2FkZVByb2dyYW1EZXNjcmlwdG9yfSBQbGFpbiBwcm9ncmFtIGRlc2NyaXB0b3IuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBzdGRsaWJGYWNhZGVQcm9ncmFtRGVzY3JpcHRvcihsYW5ndWFnZSwgZmFjYWRlcykge1xuICByZXR1cm4ge1xuICAgIGxhbmd1YWdlLFxuICAgIG1vZHVsZXM6IGZhY2FkZXMubWFwKChmYWNhZGUpID0+ICh7XG4gICAgICBkZXBlbmRlbmNpZXM6IGZhY2FkZS5kZXBlbmRlbmNpZXMubWFwKChkZXBlbmRlbmN5KSA9PiAoey4uLmRlcGVuZGVuY3l9KSksXG4gICAgICBpZGVudGl0eTogZmFjYWRlLmlkZW50aXR5LFxuICAgICAgbmF0aXZlTW9kdWxlczogZmFjYWRlLm5hdGl2ZU1vZHVsZXMubWFwKChtb2R1bGUpID0+ICh7Li4ubW9kdWxlLFxuICAgICAgICAuLi4obW9kdWxlLmtpbmQgPT0gXCJidWlsdGluXCIgPyB7Zm9ybXM6IFsuLi5tb2R1bGUuZm9ybXNdfSA6IHt9KSwgc3ltYm9sczogWy4uLm1vZHVsZS5zeW1ib2xzXX0pKSxcbiAgICAgIHB1YmxpY0RlY2xhcmF0aW9uczogZmFjYWRlLnB1YmxpY0RlY2xhcmF0aW9ucy5tYXAoZGV0YWNoUHVibGljRGVjbGFyYXRpb24pLFxuICAgICAgcmVxdWlyZW1lbnRzOiBmYWNhZGUucmVxdWlyZW1lbnRzLm1hcCgocmVxdWlyZW1lbnQpID0+ICh7Li4ucmVxdWlyZW1lbnQsIG9wZXJhdGlvbnM6IFsuLi5yZXF1aXJlbWVudC5vcGVyYXRpb25zXX0pKSxcbiAgICAgIHJ1bnRpbWVQcm9maWxlOiBmYWNhZGUucnVudGltZVByb2ZpbGUsXG4gICAgICBzb3VyY2VNb2R1bGU6IGZhY2FkZS5zb3VyY2UuaWQsXG4gICAgICB2ZXJzaW9uOiBmYWNhZGUudmVyc2lvbixcbiAgICAgIHZpc2liaWxpdHk6IGZhY2FkZS52aXNpYmlsaXR5XG4gICAgfSkpLFxuICAgIHNjaGVtYTogXCJTZW1hbnRpZm9sZFN0ZGxpYkZhY2FkZXNcIixcbiAgICB2ZXJzaW9uOiAxXG4gIH1cbn1cblxuLyoqXG4gKiBEZXJpdmVzIGNvbXBpbGVyLW93bmVkIHNlbWFudGljIGNhcGFiaWxpdHkgYXV0aG9yaXR5IGZyb20gc2VsZWN0ZWQgZmFjYWRlIHJlcXVpcmVtZW50cy5cbiAqIFRoZSBpbml0aWFsIGV4ZWN1dGFibGUgcXVhbGlmaWNhdGlvbiBjb3JwdXMgaW50ZW50aW9uYWxseSB0YXJnZXRzIG9uZSBjYW5vbmljYWwgbW9kdWxlLlxuICogQHBhcmFtIHtTdGRsaWJGYWNhZGVSZWNvcmRbXX0gcmVjb3JkcyAtIFNlbGVjdGVkIGZhY2FkZSBjbG9zdXJlLlxuICogQHJldHVybnMge3tjb250cmFjdDoge2NvbnRyYWN0VmVyc2lvbjogc3RyaW5nLCBpZGVudGl0eTogc3RyaW5nfSwgaW5wdXQ6IGltcG9ydChcIi4vc2VtYW50aWMvdHlwZXMuanNcIikuQ2FwYWJpbGl0eUF1dGhvcml0eUlucHV0fSB8IHtjb250cmFjdHM6IHtjb250cmFjdFZlcnNpb246IHN0cmluZywgaWRlbnRpdHk6IHN0cmluZ31bXSwgaW5wdXQ6IGltcG9ydChcIi4vc2VtYW50aWMvdHlwZXMuanNcIikuQ2FwYWJpbGl0eUF1dGhvcml0eUlucHV0fSB8IG51bGx9IEF1dGhvcml0eSBpbnB1dC5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGZhY2FkZUNhcGFiaWxpdHlBdXRob3JpdHkocmVjb3Jkcykge1xuICBjb25zdCByZXF1aXJlbWVudHMgPSByZWNvcmRzLmZsYXRNYXAoKHJlY29yZCkgPT4gcmVjb3JkLnJlcXVpcmVtZW50cylcblxuICBpZiAocmVxdWlyZW1lbnRzLmxlbmd0aCA9PSAwKSByZXR1cm4gbnVsbFxuICBjb25zdCBpZGVudGl0aWVzID0gbmV3IFNldChyZXF1aXJlbWVudHMubWFwKCh7bW9kdWxlfSkgPT4gbW9kdWxlKSlcbiAgY29uc3QgcmFuZ2VzID0gbmV3IFNldChyZXF1aXJlbWVudHMubWFwKCh7cmFuZ2V9KSA9PiByYW5nZSkpXG5cbiAgY29uc3QgdGFzazAzNyA9IHJlY29yZHMuc29tZSgoe2lkZW50aXR5fSkgPT4gaWRlbnRpdHkuc3RhcnRzV2l0aChcInNlbWFudGlmb2xkLnRhc2swMzcuXCIpKVxuXG4gIGlmICh0YXNrMDM3KSB7XG4gICAgY29uc3QgcmVxdWlyZW1lbnRCeU1vZHVsZSA9IG5ldyBNYXAoKVxuXG4gICAgZm9yIChjb25zdCByZXF1aXJlbWVudCBvZiByZXF1aXJlbWVudHMpIHtcbiAgICAgIGNvbnN0IGN1cnJlbnQgPSByZXF1aXJlbWVudEJ5TW9kdWxlLmdldChyZXF1aXJlbWVudC5tb2R1bGUpXG5cbiAgICAgIGlmIChjdXJyZW50ICYmIGN1cnJlbnQucmFuZ2UgIT0gcmVxdWlyZW1lbnQucmFuZ2UpIGludmFsaWRGYWNhZGUoXCJUYXNrIDAzNyBmYWNhZGUgcmVxdWlyZW1lbnRzIGRpc2FncmVlIG9uIGEgY2Fub25pY2FsIHJhbmdlLlwiKVxuICAgICAgY29uc3Qgb3BlcmF0aW9ucyA9IG5ldyBTZXQoY3VycmVudD8ub3BlcmF0aW9ucyA/PyBbXSlcblxuICAgICAgZm9yIChjb25zdCBvcGVyYXRpb24gb2YgcmVxdWlyZW1lbnQub3BlcmF0aW9ucykgb3BlcmF0aW9ucy5hZGQob3BlcmF0aW9uKVxuICAgICAgcmVxdWlyZW1lbnRCeU1vZHVsZS5zZXQocmVxdWlyZW1lbnQubW9kdWxlLCB7b3BlcmF0aW9ucywgcmFuZ2U6IHJlcXVpcmVtZW50LnJhbmdlfSlcbiAgICB9XG4gICAgY29uc3QgbW9kdWxlcyA9IFsuLi5yZXF1aXJlbWVudEJ5TW9kdWxlLmVudHJpZXMoKV0ubWFwKChbaWRlbnRpdHksIHJlcXVpcmVtZW50XSkgPT4ge1xuICAgICAgY29uc3QgY29udHJhY3QgPSByZXNvbHZlU3RkbGliTW9kdWxlKGlkZW50aXR5LCByZXF1aXJlbWVudC5yYW5nZSlcblxuICAgICAgcmV0dXJuIHtcbiAgICAgICAgY2FwYWJpbGl0aWVzOiBbe1xuICAgICAgICAgIGZhaWx1cmVzOiBjb250cmFjdC5mYWlsdXJlcy5tYXAoKHtuYW1lfSkgPT4gKHtuYW1lfSkpLFxuICAgICAgICAgIG5hbWU6IGNhbm9uaWNhbENhcGFiaWxpdHlOYW1lKGlkZW50aXR5KSxcbiAgICAgICAgICBvcGVyYXRpb25zOiBjb250cmFjdC5vcGVyYXRpb25zLmZpbHRlcigoe25hbWV9KSA9PiByZXF1aXJlbWVudC5vcGVyYXRpb25zLmhhcyhuYW1lKSkubWFwKChvcGVyYXRpb24pID0+ICh7XG4gICAgICAgICAgICBlZmZlY3RzOiAvKiogQHR5cGUge1tcImhvc3RcIl19ICovIChbLi4ub3BlcmF0aW9uLmVmZmVjdHNdKSxcbiAgICAgICAgICAgIGZhaWx1cmVzOiBvcGVyYXRpb24uZmFpbHVyZXMubWFwKGRldGFjaENhbm9uaWNhbFJlZmVyZW5jZSksXG4gICAgICAgICAgICBuYW1lOiBvcGVyYXRpb24ubmFtZSxcbiAgICAgICAgICAgIHBhcmFtZXRlcnM6IG9wZXJhdGlvbi5wYXJhbWV0ZXJzLm1hcCgocGFyYW1ldGVyKSA9PiAoe1xuICAgICAgICAgICAgICBuYW1lOiBwYXJhbWV0ZXIubmFtZSxcbiAgICAgICAgICAgICAgdHlwZTogY2Fub25pY2FsQ2FwYWJpbGl0eVBhcmFtZXRlclR5cGUocGFyYW1ldGVyLnR5cGUpXG4gICAgICAgICAgICB9KSksXG4gICAgICAgICAgICByZXNvdXJjZUZsb3c6IGRldGFjaFJlc291cmNlRmxvdyhvcGVyYXRpb24ucmVzb3VyY2VGbG93KSxcbiAgICAgICAgICAgIHJldHVyblR5cGU6IGNhbm9uaWNhbENhcGFiaWxpdHlUeXBlKG9wZXJhdGlvbi5yZXR1cm5UeXBlKVxuICAgICAgICAgIH0pKSxcbiAgICAgICAgICByZXNvdXJjZXM6IGNvbnRyYWN0LnJlc291cmNlcy5tYXAoKHtuYW1lfSkgPT4gKHtuYW1lfSkpXG4gICAgICAgIH1dLFxuICAgICAgICBjb250cmFjdFZlcnNpb246IHJlcXVpcmVtZW50LnJhbmdlLFxuICAgICAgICBpZGVudGl0eVxuICAgICAgfVxuICAgIH0pXG5cbiAgICByZXR1cm4ge1xuICAgICAgY29udHJhY3RzOiBtb2R1bGVzLm1hcCgoe2NvbnRyYWN0VmVyc2lvbiwgaWRlbnRpdHl9KSA9PiAoe2NvbnRyYWN0VmVyc2lvbiwgaWRlbnRpdHl9KSksXG4gICAgICBpbnB1dDoge2lkOiBcInNlbWFudGlmb2xkLnRhc2swMzcuYmxvY2tpbmctdGNwXCIsIG1vZHVsZXMsIHNjaGVtYTogXCJTZW1hbnRpZm9sZENhcGFiaWxpdHlBdXRob3JpdHlcIiwgc2NoZW1hVmVyc2lvbjogMn1cbiAgICB9XG4gIH1cbiAgaWYgKGlkZW50aXRpZXMuc2l6ZSAhPSAxIHx8IHJhbmdlcy5zaXplICE9IDEpIHtcbiAgICBpbnZhbGlkRmFjYWRlKFwiVGhlIFRhc2sgMDM2IHF1YWxpZmljYXRpb24gZmFjYWRlIGNsb3N1cmUgbXVzdCByZXNvbHZlIG9uZSBjYW5vbmljYWwgbW9kdWxlIGFuZCB2ZXJzaW9uIHJhbmdlLlwiKVxuICB9XG4gIGNvbnN0IGlkZW50aXR5ID0gcmVxdWlyZW1lbnRzWzBdLm1vZHVsZVxuICBjb25zdCBjb250cmFjdFZlcnNpb24gPSByZXF1aXJlbWVudHNbMF0ucmFuZ2VcbiAgY29uc3QgY29udHJhY3QgPSByZXNvbHZlU3RkbGliTW9kdWxlKGlkZW50aXR5LCBjb250cmFjdFZlcnNpb24pXG5cbiAgcmV0dXJuIHtcbiAgICBjb250cmFjdDoge2NvbnRyYWN0VmVyc2lvbiwgaWRlbnRpdHl9LFxuICAgIGlucHV0OiB7XG4gICAgICBjYXBhYmlsaXRpZXM6IFt7XG4gICAgICAgIGZhaWx1cmVzOiBjb250cmFjdC5mYWlsdXJlcy5tYXAoKHtuYW1lfSkgPT4gKHtuYW1lfSkpLFxuICAgICAgICBuYW1lOiBcIlJlc291cmNlUHJvYmVcIixcbiAgICAgICAgb3BlcmF0aW9uczogY29udHJhY3Qub3BlcmF0aW9ucy5tYXAoKG9wZXJhdGlvbikgPT4gKHtcbiAgICAgICAgICBlZmZlY3RzOiBbLi4ub3BlcmF0aW9uLmVmZmVjdHNdLFxuICAgICAgICAgIGZhaWx1cmVzOiBbLi4ub3BlcmF0aW9uLmZhaWx1cmVzXSxcbiAgICAgICAgICBuYW1lOiBvcGVyYXRpb24ubmFtZSxcbiAgICAgICAgICBwYXJhbWV0ZXJzOiBvcGVyYXRpb24ucGFyYW1ldGVycy5tYXAoKHBhcmFtZXRlcikgPT4gKHtcbiAgICAgICAgICAgIG5hbWU6IHBhcmFtZXRlci5uYW1lLFxuICAgICAgICAgICAgdHlwZTogY2Fub25pY2FsQ2FwYWJpbGl0eVBhcmFtZXRlclR5cGUocGFyYW1ldGVyLnR5cGUpXG4gICAgICAgICAgfSkpLFxuICAgICAgICAgIHJlc291cmNlRmxvdzogLyoqIEB0eXBlIHtpbXBvcnQoXCIuL3NlbWFudGljL3R5cGVzLmpzXCIpLkNhcGFiaWxpdHlSZXNvdXJjZUZsb3dJbnB1dH0gKi8gKHsuLi5vcGVyYXRpb24ucmVzb3VyY2VGbG93fSksXG4gICAgICAgICAgcmV0dXJuVHlwZTogY2Fub25pY2FsQ2FwYWJpbGl0eVR5cGUob3BlcmF0aW9uLnJldHVyblR5cGUpXG4gICAgICAgIH0pKSxcbiAgICAgICAgcmVzb3VyY2VzOiBjb250cmFjdC5yZXNvdXJjZXMubWFwKCh7bmFtZX0pID0+ICh7bmFtZX0pKVxuICAgICAgfV0sXG4gICAgICBjb250cmFjdFZlcnNpb24sXG4gICAgICBpZDogaWRlbnRpdHksXG4gICAgICBzY2hlbWE6IFwiU2VtYW50aWZvbGRDYXBhYmlsaXR5QXV0aG9yaXR5XCIsXG4gICAgICBzY2hlbWFWZXJzaW9uOiAxXG4gICAgfVxuICB9XG59XG5cbi8qKlxuICogQ29udmVydHMgb25lIHJlZ2lzdHJ5IGNvbnRyYWN0IHR5cGUgdG8gYSBjYXBhYmlsaXR5LWF1dGhvcml0eSBpbnB1dCB0eXBlLlxuICogQHBhcmFtIHtzdHJpbmcgfCBpbXBvcnQoXCIuL3NlbWFudGljL3N0ZGxpYi5qc1wiKS5DYW5vbmljYWxEZWNsYXJhdGlvblJlZmVyZW5jZX0gdHlwZSAtIENhbm9uaWNhbCBjb250cmFjdCB0eXBlLlxuICogQHJldHVybnMge2ltcG9ydChcIi4vc2VtYW50aWMvdHlwZXMuanNcIikuRnVuY3Rpb25SZXR1cm5UeXBlTmFtZSB8IHtraW5kOiBcIk93bmVkUmVzb3VyY2VUeXBlXCIsIHJlc291cmNlOiBzdHJpbmcgfCBpbXBvcnQoXCIuL3NlbWFudGljL3R5cGVzLmpzXCIpLkNhcGFiaWxpdHlEZWNsYXJhdGlvblJlZmVyZW5jZUlucHV0fSB8IHtraW5kOiBcIk9wdGlvbmFsVHlwZVwiLCB2YWx1ZVR5cGU6IGltcG9ydChcIi4vc2VtYW50aWMvdHlwZXMuanNcIikuU2VtYW50aWNUeXBlTmFtZX19IFNlbWFudGljIGF1dGhvcml0eSB0eXBlLlxuICovXG5mdW5jdGlvbiBjYW5vbmljYWxDYXBhYmlsaXR5VHlwZSh0eXBlKSB7XG4gIGlmICh0eXBlb2YgdHlwZSAhPSBcInN0cmluZ1wiKSByZXR1cm4ge2tpbmQ6IFwiT3duZWRSZXNvdXJjZVR5cGVcIiwgcmVzb3VyY2U6IGRldGFjaENhbm9uaWNhbFJlZmVyZW5jZSh0eXBlKX1cbiAgaWYgKHR5cGUgPT0gXCJ2b2lkXCIgfHwgdHlwZSA9PSBcImJvb2xlYW5cIiB8fCB0eXBlID09IFwiaW50ZWdlclwiIHx8IHR5cGUgPT0gXCJzdHJpbmdcIikgcmV0dXJuIHR5cGVcbiAgaWYgKHR5cGUuc3RhcnRzV2l0aChcIm9wdGlvbmFsOlwiKSkgcmV0dXJuIHtraW5kOiBcIk9wdGlvbmFsVHlwZVwiLFxuICAgIHZhbHVlVHlwZTogLyoqIEB0eXBlIHtpbXBvcnQoXCIuL3NlbWFudGljL3R5cGVzLmpzXCIpLlNlbWFudGljVHlwZU5hbWV9ICovICh0eXBlLnNsaWNlKFwib3B0aW9uYWw6XCIubGVuZ3RoKSl9XG4gIHJldHVybiB7a2luZDogXCJPd25lZFJlc291cmNlVHlwZVwiLCByZXNvdXJjZTogdHlwZX1cbn1cblxuLyoqXG4gKiBDb252ZXJ0cyBhIG5vbi12b2lkIHJlZ2lzdHJ5IHBhcmFtZXRlciB0eXBlIHRvIGNhcGFiaWxpdHktYXV0aG9yaXR5IGlucHV0LlxuICogQHBhcmFtIHtzdHJpbmcgfCBpbXBvcnQoXCIuL3NlbWFudGljL3N0ZGxpYi5qc1wiKS5DYW5vbmljYWxEZWNsYXJhdGlvblJlZmVyZW5jZX0gdHlwZSAtIENhbm9uaWNhbCBwYXJhbWV0ZXIgdHlwZS5cbiAqIEByZXR1cm5zIHtpbXBvcnQoXCIuL3NlbWFudGljL3R5cGVzLmpzXCIpLlNlbWFudGljVHlwZU5hbWUgfCB7a2luZDogXCJPd25lZFJlc291cmNlVHlwZVwiLCByZXNvdXJjZTogc3RyaW5nfSB8IHtraW5kOiBcIk9wdGlvbmFsVHlwZVwiLCB2YWx1ZVR5cGU6IGltcG9ydChcIi4vc2VtYW50aWMvdHlwZXMuanNcIikuU2VtYW50aWNUeXBlTmFtZX19IFNlbWFudGljIHBhcmFtZXRlciB0eXBlLlxuICovXG5mdW5jdGlvbiBjYW5vbmljYWxDYXBhYmlsaXR5UGFyYW1ldGVyVHlwZSh0eXBlKSB7XG4gIGNvbnN0IGNvbnZlcnRlZCA9IGNhbm9uaWNhbENhcGFiaWxpdHlUeXBlKHR5cGUpXG5cbiAgaWYgKGNvbnZlcnRlZCA9PSBcInZvaWRcIikgaW52YWxpZEZhY2FkZShcIkNhbm9uaWNhbCBmYWNhZGUgcmVxdWlyZW1lbnQgcGFyYW1ldGVycyBjYW5ub3QgaGF2ZSB2b2lkIHR5cGUuXCIpXG4gIHJldHVybiAvKiogQHR5cGUge2ltcG9ydChcIi4vc2VtYW50aWMvdHlwZXMuanNcIikuU2VtYW50aWNUeXBlTmFtZSB8IHtraW5kOiBcIk93bmVkUmVzb3VyY2VUeXBlXCIsIHJlc291cmNlOiBzdHJpbmd9IHwge2tpbmQ6IFwiT3B0aW9uYWxUeXBlXCIsIHZhbHVlVHlwZTogaW1wb3J0KFwiLi9zZW1hbnRpYy90eXBlcy5qc1wiKS5TZW1hbnRpY1R5cGVOYW1lfX0gKi8gKGNvbnZlcnRlZClcbn1cblxuLyoqXG4gKiBSZXNvbHZlcyBvbmUgZGVwZW5kZW5jeSBpZGVudGl0eSBmcm9tIGEgdmFsaWRhdGVkIHJlZ2lzdHJ5IHN0b3JlLlxuICogQHBhcmFtIHtNYXA8c3RyaW5nLCBNYXA8c3RyaW5nLCBTdGRsaWJGYWNhZGVSZWNvcmQ+Pn0gc3RvcmUgLSBSZWNvcmRzIGJ5IGxhbmd1YWdlIGFuZCBpZGVudGl0eS5cbiAqIEBwYXJhbSB7c3RyaW5nfSBpZGVudGl0eSAtIEZhY2FkZSBpZGVudGl0eS5cbiAqIEBwYXJhbSB7c3RyaW5nfSBsYW5ndWFnZSAtIFNvdXJjZSBsYW5ndWFnZS5cbiAqIEBwYXJhbSB7c3RyaW5nIHwgdW5kZWZpbmVkfSByYW5nZSAtIENvbXBhdGlibGUgcmFuZ2UuXG4gKiBAcGFyYW0ge3N0cmluZ30gW293bmVyXSAtIERlcGVuZGluZyBmYWNhZGUgZm9yIGRpYWdub3N0aWNzLlxuICogQHJldHVybnMge1N0ZGxpYkZhY2FkZVJlY29yZH0gSGlnaGVzdCBjb21wYXRpYmxlIHJlY29yZC5cbiAqL1xuZnVuY3Rpb24gcmVzb2x2ZUlkZW50aXR5RnJvbVN0b3JlKHN0b3JlLCBpZGVudGl0eSwgbGFuZ3VhZ2UsIHJhbmdlLCBvd25lcikge1xuICBjb25zdCB2ZXJzaW9ucyA9IHN0b3JlLmdldChgJHtsYW5ndWFnZX1cXDAke2lkZW50aXR5fWApXG5cbiAgaWYgKCF2ZXJzaW9ucykge1xuICAgIGludmFsaWRGYWNhZGUob3duZXIgPyBgRmFjYWRlICcke293bmVyfScgZGVwZW5kcyBvbiB1bmtub3duIGZhY2FkZSAnJHtpZGVudGl0eX0nIGZvciAnJHtsYW5ndWFnZX0nLmAgOlxuICAgICAgYFVua25vd24gZmFjYWRlIGlkZW50aXR5ICcke2lkZW50aXR5fScgZm9yICcke2xhbmd1YWdlfScuYClcbiAgfVxuICByZXR1cm4gc2VsZWN0RmFjYWRlVmVyc2lvbigvKiogQHR5cGUge01hcDxzdHJpbmcsIFN0ZGxpYkZhY2FkZVJlY29yZD59ICovICh2ZXJzaW9ucyksIGlkZW50aXR5LCBsYW5ndWFnZSwgcmFuZ2UpXG59XG5cbi8qKlxuICogUmVzb2x2ZXMgb25lIGV4YWN0IG5hdGl2ZSBpZGVudGl0eSBmcm9tIGEgdmFsaWRhdGVkIHJlZ2lzdHJ5IHN0b3JlLlxuICogQHBhcmFtIHtNYXA8c3RyaW5nLCBTdGRsaWJGYWNhZGVSZWNvcmRbXT59IHN0b3JlIC0gUmVjb3JkcyBieSBsYW5ndWFnZSBhbmQgbmF0aXZlIG1vZHVsZS5cbiAqIEBwYXJhbSB7c3RyaW5nfSBsYW5ndWFnZSAtIFNvdXJjZSBsYW5ndWFnZS5cbiAqIEBwYXJhbSB7c3RyaW5nfSBuYXRpdmVNb2R1bGUgLSBFeGFjdCBwYXJzZXItb3duZWQgbmF0aXZlIG1vZHVsZSBpZGVudGl0eS5cbiAqIEBwYXJhbSB7c3RyaW5nfSBzeW1ib2wgLSBFeGFjdCBzb3VyY2UtdmlzaWJsZSBzeW1ib2wuXG4gKiBAcGFyYW0ge3N0cmluZyB8IHVuZGVmaW5lZH0gcmFuZ2UgLSBDb21wYXRpYmxlIHJhbmdlLlxuICogQHJldHVybnMge1N0ZGxpYkZhY2FkZVJlY29yZH0gSGlnaGVzdCBjb21wYXRpYmxlIHJlY29yZC5cbiAqL1xuZnVuY3Rpb24gcmVzb2x2ZU5hdGl2ZUZhY2FkZUZyb21TdG9yZShzdG9yZSwgbGFuZ3VhZ2UsIG5hdGl2ZU1vZHVsZSwgc3ltYm9sLCByYW5nZSkge1xuICBpZiAoIXN1cHBvcnRlZExhbmd1YWdlcy5oYXMobGFuZ3VhZ2UpIHx8IHR5cGVvZiBuYXRpdmVNb2R1bGUgIT0gXCJzdHJpbmdcIiB8fCBuYXRpdmVNb2R1bGUubGVuZ3RoID09IDApIHtcbiAgICB1bnByb3ZlZElkZW50aXR5KGxhbmd1YWdlLCBuYXRpdmVNb2R1bGUpXG4gIH1cbiAgY29uc3QgbW9kdWxlUmVjb3JkcyA9IHN0b3JlLmdldChgJHtsYW5ndWFnZX1cXDAke25hdGl2ZU1vZHVsZX1gKVxuXG4gIGlmICghbW9kdWxlUmVjb3JkcykgdW5wcm92ZWRJZGVudGl0eShsYW5ndWFnZSwgbmF0aXZlTW9kdWxlKVxuICBjb25zdCBzeW1ib2xSZWNvcmRzID0gLyoqIEB0eXBlIHtTdGRsaWJGYWNhZGVSZWNvcmRbXX0gKi8gKG1vZHVsZVJlY29yZHMpLmZpbHRlcigocmVjb3JkKSA9PiByZWNvcmQubmF0aXZlTW9kdWxlcy5zb21lKChtb2R1bGUpID0+XG4gICAgbW9kdWxlLmlkZW50aXR5ID09IG5hdGl2ZU1vZHVsZSAmJiBtb2R1bGUuc3ltYm9scy5pbmNsdWRlcyhzeW1ib2wpKSlcblxuICBpZiAoc3ltYm9sUmVjb3Jkcy5sZW5ndGggPT0gMCkgdW5zdXBwb3J0ZWRNZW1iZXIobGFuZ3VhZ2UsIG5hdGl2ZU1vZHVsZSwgc3ltYm9sKVxuICBjb25zdCBpZGVudGl0aWVzID0gbmV3IFNldChzeW1ib2xSZWNvcmRzLm1hcCgoe2lkZW50aXR5fSkgPT4gaWRlbnRpdHkpKVxuXG4gIGlmIChpZGVudGl0aWVzLnNpemUgIT0gMSkgaW52YWxpZEZhY2FkZShgTmF0aXZlIGZhY2FkZSBpZGVudGl0eSAnJHtuYXRpdmVNb2R1bGV9IyR7c3ltYm9sfScgaXMgYW1iaWd1b3VzIGZvciAnJHtsYW5ndWFnZX0nLmApXG4gIGNvbnN0IHZlcnNpb25zID0gbmV3IE1hcChzeW1ib2xSZWNvcmRzLm1hcCgocmVjb3JkKSA9PiBbcmVjb3JkLnZlcnNpb24sIHJlY29yZF0pKVxuXG4gIHJldHVybiBzZWxlY3RGYWNhZGVWZXJzaW9uKHZlcnNpb25zLCBzeW1ib2xSZWNvcmRzWzBdLmlkZW50aXR5LCBsYW5ndWFnZSwgcmFuZ2UpXG59XG5cbi8qKlxuICogU2VsZWN0cyB0aGUgaGlnaGVzdCBmYWNhZGUgdmVyc2lvbiBzYXRpc2Z5aW5nIGEgY2Fub25pY2FsIHJhbmdlLlxuICogQHBhcmFtIHtNYXA8c3RyaW5nLCBTdGRsaWJGYWNhZGVSZWNvcmQ+fSB2ZXJzaW9ucyAtIFJlY29yZHMgYnkgZXhhY3QgdmVyc2lvbi5cbiAqIEBwYXJhbSB7c3RyaW5nfSBpZGVudGl0eSAtIEZhY2FkZSBpZGVudGl0eS5cbiAqIEBwYXJhbSB7c3RyaW5nfSBsYW5ndWFnZSAtIFNvdXJjZSBsYW5ndWFnZS5cbiAqIEBwYXJhbSB7c3RyaW5nIHwgdW5kZWZpbmVkfSByYW5nZSAtIENvbXBhdGlibGUgcmFuZ2UuXG4gKiBAcmV0dXJucyB7U3RkbGliRmFjYWRlUmVjb3JkfSBTZWxlY3RlZCByZWNvcmQuXG4gKi9cbmZ1bmN0aW9uIHNlbGVjdEZhY2FkZVZlcnNpb24odmVyc2lvbnMsIGlkZW50aXR5LCBsYW5ndWFnZSwgcmFuZ2UpIHtcbiAgY29uc3QgcGFyc2VkUmFuZ2UgPSByYW5nZSA9PT0gdW5kZWZpbmVkID8ge2xvd2VyOiAvKiogQHR5cGUge1tudW1iZXIsIG51bWJlciwgbnVtYmVyXX0gKi8gKFswLCAwLCAwXSksIHVwcGVyOiBudWxsfSA6XG4gICAgcGFyc2VTdGRsaWJWZXJzaW9uUmFuZ2UocmFuZ2UpXG5cbiAgaWYgKCFwYXJzZWRSYW5nZSkgZmFjYWRlVmVyc2lvbk1hbGZvcm1lZChsYW5ndWFnZSwgU3RyaW5nKHJhbmdlKSlcbiAgLyoqIEB0eXBlIHtbbnVtYmVyLCBudW1iZXIsIG51bWJlcl0gfCB1bmRlZmluZWR9ICovXG4gIGxldCBzZWxlY3RlZFxuXG4gIGZvciAoY29uc3QgdmVyc2lvbiBvZiB2ZXJzaW9ucy5rZXlzKCkpIHtcbiAgICBjb25zdCBwYXJzZWQgPSAvKiogQHR5cGUge1tudW1iZXIsIG51bWJlciwgbnVtYmVyXX0gKi8gKHBhcnNlU3RkbGliVmVyc2lvbih2ZXJzaW9uKSlcblxuICAgIGlmIChzdGRsaWJWZXJzaW9uU2F0aXNmaWVzKHBhcnNlZCwgcGFyc2VkUmFuZ2UpICYmICghc2VsZWN0ZWQgfHwgY29tcGFyZVN0ZGxpYlZlcnNpb25zKHBhcnNlZCwgc2VsZWN0ZWQpID4gMCkpIHNlbGVjdGVkID0gcGFyc2VkXG4gIH1cbiAgaWYgKCFzZWxlY3RlZCkgZmFjYWRlVmVyc2lvbkluY29tcGF0aWJsZShsYW5ndWFnZSwgaWRlbnRpdHkpXG5cbiAgcmV0dXJuIC8qKiBAdHlwZSB7U3RkbGliRmFjYWRlUmVjb3JkfSAqLyAodmVyc2lvbnMuZ2V0KHNlbGVjdGVkLmpvaW4oXCIuXCIpKSlcbn1cblxuLyoqXG4gKiBWYWxpZGF0ZXMgYW5kIGRldGFjaGVzIG9uZSBleGVjdXRhYmxlIGZhY2FkZSByZWNvcmQuXG4gKiBAcGFyYW0ge3Vua25vd259IGNhbmRpZGF0ZSAtIENhbmRpZGF0ZSByZWNvcmQuXG4gKiBAcmV0dXJucyB7U3RkbGliRmFjYWRlUmVjb3JkfSBEZXRhY2hlZCBmcm96ZW4gcmVjb3JkLlxuICovXG5mdW5jdGlvbiB2YWxpZGF0ZUZhY2FkZVJlY29yZChjYW5kaWRhdGUpIHtcbiAgaWYgKCFpc1BsYWluT2JqZWN0KGNhbmRpZGF0ZSkpIGludmFsaWRGYWNhZGUoXCJFdmVyeSBmYWNhZGUgcmVjb3JkIG11c3QgYmUgYSBwbGFpbiBvYmplY3QuXCIpXG4gIHJlcXVpcmVLZXlzKGNhbmRpZGF0ZSwgW1wiZGVwZW5kZW5jaWVzXCIsIFwiaWRlbnRpdHlcIiwgXCJsYW5ndWFnZVwiLCBcIm5hdGl2ZU1vZHVsZXNcIiwgXCJwdWJsaWNEZWNsYXJhdGlvbnNcIiwgXCJyZXF1aXJlbWVudHNcIixcbiAgICBcInJ1bnRpbWVQcm9maWxlXCIsIFwic291cmNlXCIsIFwidmVyc2lvblwiLCBcInZpc2liaWxpdHlcIl0sIFwiZmFjYWRlIHJlY29yZFwiKVxuICBjb25zdCBpZGVudGl0eSA9IHJlcXVpcmVTdHJpbmcoY2FuZGlkYXRlLmlkZW50aXR5LCBcIkZhY2FkZSBpZGVudGl0eVwiKVxuICBjb25zdCBsYW5ndWFnZSA9IHJlcXVpcmVTdHJpbmcoY2FuZGlkYXRlLmxhbmd1YWdlLCBcIkZhY2FkZSBsYW5ndWFnZVwiKVxuICBjb25zdCB2ZXJzaW9uID0gcmVxdWlyZVN0cmluZyhjYW5kaWRhdGUudmVyc2lvbiwgXCJGYWNhZGUgdmVyc2lvblwiKVxuICBjb25zdCBydW50aW1lUHJvZmlsZSA9IHJlcXVpcmVTdHJpbmcoY2FuZGlkYXRlLnJ1bnRpbWVQcm9maWxlLCBcIkZhY2FkZSBydW50aW1lIHByb2ZpbGVcIilcbiAgY29uc3QgdmlzaWJpbGl0eSA9IGNhbmRpZGF0ZS52aXNpYmlsaXR5XG5cbiAgaWYgKCFmYWNhZGVJZGVudGl0eVBhdHRlcm4udGVzdChpZGVudGl0eSkpIGludmFsaWRGYWNhZGUoYEZhY2FkZSBpZGVudGl0eSAnJHtpZGVudGl0eX0nIGlzIGludmFsaWQuYClcbiAgaWYgKCFzdXBwb3J0ZWRMYW5ndWFnZXMuaGFzKGxhbmd1YWdlKSkgaW52YWxpZEZhY2FkZShgRmFjYWRlIGxhbmd1YWdlICcke2xhbmd1YWdlfScgaXMgb3V0c2lkZSB0aGUgYWRvcHRlZCBjb2hvcnQuYClcbiAgaWYgKCFwYXJzZVN0ZGxpYlZlcnNpb24odmVyc2lvbikpIGludmFsaWRGYWNhZGUoYEZhY2FkZSB2ZXJzaW9uICcke3ZlcnNpb259JyBpcyBpbnZhbGlkLmApXG4gIGlmICghL15bYS16XVthLXowLTkuLV0qJC91LnRlc3QocnVudGltZVByb2ZpbGUpKSBpbnZhbGlkRmFjYWRlKGBGYWNhZGUgcnVudGltZSBwcm9maWxlICcke3J1bnRpbWVQcm9maWxlfScgaXMgaW52YWxpZC5gKVxuICBpZiAodmlzaWJpbGl0eSAhPSBcInB1YmxpY1wiICYmIHZpc2liaWxpdHkgIT0gXCJpbnRlcm5hbFwiKSBpbnZhbGlkRmFjYWRlKGBGYWNhZGUgJyR7aWRlbnRpdHl9JyBoYXMgaW52YWxpZCB2aXNpYmlsaXR5LmApXG4gIGNvbnN0IHNvdXJjZSA9IHZhbGlkYXRlU291cmNlKGNhbmRpZGF0ZS5zb3VyY2UsIGlkZW50aXR5LCBsYW5ndWFnZSlcbiAgY29uc3QgcHVibGljRGVjbGFyYXRpb25zID0gdmFsaWRhdGVQdWJsaWNEZWNsYXJhdGlvbnMoY2FuZGlkYXRlLnB1YmxpY0RlY2xhcmF0aW9ucywgaWRlbnRpdHkpXG4gIGNvbnN0IG5hdGl2ZU1vZHVsZXMgPSB2YWxpZGF0ZU5hdGl2ZU1vZHVsZXMoY2FuZGlkYXRlLm5hdGl2ZU1vZHVsZXMsIGlkZW50aXR5LCBwdWJsaWNEZWNsYXJhdGlvbnMpXG4gIGNvbnN0IHJlcXVpcmVtZW50cyA9IHZhbGlkYXRlUmVxdWlyZW1lbnRzKGNhbmRpZGF0ZS5yZXF1aXJlbWVudHMsIGlkZW50aXR5KVxuICBjb25zdCBkZXBlbmRlbmNpZXMgPSB2YWxpZGF0ZURlcGVuZGVuY2llcyhjYW5kaWRhdGUuZGVwZW5kZW5jaWVzLCBpZGVudGl0eSlcblxuICBpZiAodmlzaWJpbGl0eSA9PSBcInB1YmxpY1wiICYmIChwdWJsaWNEZWNsYXJhdGlvbnMubGVuZ3RoID09IDAgfHwgbmF0aXZlTW9kdWxlcy5sZW5ndGggPT0gMCkpIHtcbiAgICBpbnZhbGlkRmFjYWRlKGBQdWJsaWMgZmFjYWRlICcke2lkZW50aXR5fScgcmVxdWlyZXMgZGVjbGFyYXRpb25zIGFuZCBuYXRpdmUgaWRlbnRpdGllcy5gKVxuICB9XG4gIGlmICh2aXNpYmlsaXR5ID09IFwiaW50ZXJuYWxcIiAmJiBuYXRpdmVNb2R1bGVzLmxlbmd0aCA+IDApIGludmFsaWRGYWNhZGUoYEludGVybmFsIGZhY2FkZSAnJHtpZGVudGl0eX0nIGNhbm5vdCBleHBvc2UgbmF0aXZlIGlkZW50aXRpZXMuYClcblxuICByZXR1cm4gZGVlcEZyZWV6ZSh7XG4gICAgZGVwZW5kZW5jaWVzLFxuICAgIGlkZW50aXR5LFxuICAgIGxhbmd1YWdlOiAvKiogQHR5cGUge2ltcG9ydChcIi4vc2VtYW50aWMvdHlwZXMuanNcIikuU2VtYW50aWNMYW5ndWFnZX0gKi8gKGxhbmd1YWdlKSxcbiAgICBuYXRpdmVNb2R1bGVzLFxuICAgIHB1YmxpY0RlY2xhcmF0aW9ucyxcbiAgICByZXF1aXJlbWVudHMsXG4gICAgcnVudGltZVByb2ZpbGUsXG4gICAgc291cmNlLFxuICAgIHZlcnNpb24sXG4gICAgdmlzaWJpbGl0eTogLyoqIEB0eXBlIHtcImludGVybmFsXCIgfCBcInB1YmxpY1wifSAqLyAodmlzaWJpbGl0eSlcbiAgfSlcbn1cblxuLyoqXG4gKiBWYWxpZGF0ZXMgb25lIGNvbXBpbGVyLW93bmVkIGV4ZWN1dGFibGUgZmFjYWRlIHNvdXJjZS5cbiAqIEBwYXJhbSB7dW5rbm93bn0gY2FuZGlkYXRlIC0gQ2FuZGlkYXRlIHNvdXJjZSBkZXNjcmlwdG9yLlxuICogQHBhcmFtIHtzdHJpbmd9IGlkZW50aXR5IC0gT3duaW5nIGZhY2FkZSBpZGVudGl0eS5cbiAqIEBwYXJhbSB7c3RyaW5nfSBsYW5ndWFnZSAtIEZhY2FkZSBzb3VyY2UgbGFuZ3VhZ2UuXG4gKiBAcmV0dXJucyB7e2NvbnRlbnQ6IHN0cmluZywgZmlsZW5hbWU6IHN0cmluZywgaWQ6IHN0cmluZ319IFZhbGlkYXRlZCBzb3VyY2UgZGVzY3JpcHRvci5cbiAqL1xuZnVuY3Rpb24gdmFsaWRhdGVTb3VyY2UoY2FuZGlkYXRlLCBpZGVudGl0eSwgbGFuZ3VhZ2UpIHtcbiAgaWYgKCFpc1BsYWluT2JqZWN0KGNhbmRpZGF0ZSkpIGludmFsaWRGYWNhZGUoYEZhY2FkZSAnJHtpZGVudGl0eX0nIHJlcXVpcmVzIGFuIGV4ZWN1dGFibGUgc291cmNlIGRlc2NyaXB0b3IuYClcbiAgcmVxdWlyZUtleXMoY2FuZGlkYXRlLCBbXCJjb250ZW50XCIsIFwiZmlsZW5hbWVcIiwgXCJpZFwiXSwgYGZhY2FkZSAnJHtpZGVudGl0eX0nIHNvdXJjZWApXG4gIGNvbnN0IGNvbnRlbnQgPSByZXF1aXJlU3RyaW5nKGNhbmRpZGF0ZS5jb250ZW50LCBgRmFjYWRlICcke2lkZW50aXR5fScgc291cmNlIGNvbnRlbnRgKVxuICBjb25zdCBmaWxlbmFtZSA9IHJlcXVpcmVTdHJpbmcoY2FuZGlkYXRlLmZpbGVuYW1lLCBgRmFjYWRlICcke2lkZW50aXR5fScgc291cmNlIGZpbGVuYW1lYClcbiAgY29uc3QgaWQgPSByZXF1aXJlU3RyaW5nKGNhbmRpZGF0ZS5pZCwgYEZhY2FkZSAnJHtpZGVudGl0eX0nIHNvdXJjZSBtb2R1bGUgaWRlbnRpdHlgKVxuXG4gIGlmIChjb250ZW50Lmxlbmd0aCA9PSAwIHx8ICFpc1NhZmVBcnRpZmFjdFBhdGgoZmlsZW5hbWUpIHx8ICFmaWxlbmFtZS5zdGFydHNXaXRoKGBfX3NlbWFudGlmb2xkX2ZhY2FkZXNfXy8ke2xhbmd1YWdlfS9gKSB8fFxuICAgICFtb2R1bGVJZFBhdHRlcm4udGVzdChpZCkgfHwgIWlkLnN0YXJ0c1dpdGgoYHNlbWFudGlmb2xkLmZhY2FkZS4ke2xhbmd1YWdlfS5gKSkge1xuICAgIGludmFsaWRGYWNhZGUoYEZhY2FkZSAnJHtpZGVudGl0eX0nIGhhcyBhbiBpbnZhbGlkIGNvbXBpbGVyLW93bmVkIHNvdXJjZSBkZXNjcmlwdG9yLmApXG4gIH1cbiAgcmV0dXJuIHtjb250ZW50LCBmaWxlbmFtZSwgaWR9XG59XG5cbi8qKlxuICogVmFsaWRhdGVzIG9uZSBmYWNhZGUncyBjbG9zZWQgcHVibGljIGRlY2xhcmF0aW9uIHN1cmZhY2UuXG4gKiBAcGFyYW0ge3Vua25vd259IGNhbmRpZGF0ZSAtIENhbmRpZGF0ZSBkZWNsYXJhdGlvbnMuXG4gKiBAcGFyYW0ge3N0cmluZ30gaWRlbnRpdHkgLSBPd25pbmcgZmFjYWRlIGlkZW50aXR5LlxuICogQHJldHVybnMge1N0ZGxpYkZhY2FkZVB1YmxpY0RlY2xhcmF0aW9uW119IFZhbGlkYXRlZCBkZWNsYXJhdGlvbnMuXG4gKi9cbmZ1bmN0aW9uIHZhbGlkYXRlUHVibGljRGVjbGFyYXRpb25zKGNhbmRpZGF0ZSwgaWRlbnRpdHkpIHtcbiAgaWYgKCFpc0RlbnNlQXJyYXkoY2FuZGlkYXRlKSkgaW52YWxpZEZhY2FkZShgRmFjYWRlICcke2lkZW50aXR5fScgcHVibGljIGRlY2xhcmF0aW9ucyBtdXN0IGJlIGEgZGVuc2UgYXJyYXkuYClcbiAgY29uc3QgbmFtZXMgPSBuZXcgU2V0KClcbiAgcmV0dXJuIGNhbmRpZGF0ZS5tYXAoKHZhbHVlKSA9PiB7XG4gICAgaWYgKCFpc1BsYWluT2JqZWN0KHZhbHVlKSkgaW52YWxpZEZhY2FkZShgRmFjYWRlICcke2lkZW50aXR5fScgcHVibGljIGRlY2xhcmF0aW9ucyBtdXN0IGJlIHBsYWluIG9iamVjdHMuYClcbiAgICBjb25zdCBuYW1lID0gcmVxdWlyZVN0cmluZyh2YWx1ZS5uYW1lLCBgRmFjYWRlICcke2lkZW50aXR5fScgZGVjbGFyYXRpb24gbmFtZWApXG5cbiAgICBpZiAoIWRlY2xhcmF0aW9uTmFtZVBhdHRlcm4udGVzdChuYW1lKSB8fCBuYW1lcy5oYXMobmFtZSkpIHtcbiAgICAgIGludmFsaWRGYWNhZGUoYEZhY2FkZSAnJHtpZGVudGl0eX0nIGhhcyBhbiBpbnZhbGlkIG9yIGR1cGxpY2F0ZSBwdWJsaWMgZGVjbGFyYXRpb24uYClcbiAgICB9XG4gICAgbmFtZXMuYWRkKG5hbWUpXG4gICAgaWYgKHZhbHVlLmtpbmQgPT0gXCJjbGFzc1wiKSByZXR1cm4gdmFsaWRhdGVQdWJsaWNDbGFzcyh2YWx1ZSwgaWRlbnRpdHksIG5hbWUpXG4gICAgcmVxdWlyZUtleXModmFsdWUsIFtcImVmZmVjdHNcIiwgXCJmYWlsdXJlc1wiLCBcImZvcm1zXCIsIFwia2luZFwiLCBcIm5hbWVcIiwgXCJvd25lcnNoaXBcIiwgXCJwYXJhbWV0ZXJzXCIsIFwicmV0dXJuVHlwZVwiXSxcbiAgICAgIGBmYWNhZGUgJyR7aWRlbnRpdHl9JyBwdWJsaWMgZGVjbGFyYXRpb25gKVxuICAgIGlmICh2YWx1ZS5raW5kICE9IFwiZnVuY3Rpb25cIikgaW52YWxpZEZhY2FkZShgRmFjYWRlICcke2lkZW50aXR5fScgaGFzIGFuIGludmFsaWQgcHVibGljIGRlY2xhcmF0aW9uIGtpbmQuYClcbiAgICBpZiAoIWlzRGVuc2VBcnJheSh2YWx1ZS5lZmZlY3RzKSB8fCAhdmFsdWUuZWZmZWN0cy5ldmVyeSgoZWZmZWN0KSA9PiBlZmZlY3QgPT0gXCJob3N0XCIpIHx8IG5ldyBTZXQodmFsdWUuZWZmZWN0cykuc2l6ZSAhPSB2YWx1ZS5lZmZlY3RzLmxlbmd0aCB8fFxuICAgICAgIWlzRGVuc2VBcnJheSh2YWx1ZS5mYWlsdXJlcykgfHwgIXZhbHVlLmZhaWx1cmVzLmV2ZXJ5KChmYWlsdXJlKSA9PiB0eXBlb2YgZmFpbHVyZSA9PSBcInN0cmluZ1wiICYmIGRlY2xhcmF0aW9uTmFtZVBhdHRlcm4udGVzdChmYWlsdXJlKSkgfHxcbiAgICAgICFpc0RlbnNlQXJyYXkodmFsdWUuZm9ybXMpIHx8IHZhbHVlLmZvcm1zLmxlbmd0aCA9PSAwIHx8ICF2YWx1ZS5mb3Jtcy5ldmVyeSgoZm9ybSkgPT5cbiAgICAgICAgdHlwZW9mIGZvcm0gPT0gXCJzdHJpbmdcIiAmJiBbXCJkaXJlY3QtY2FsbFwiLCBcInVucXVhbGlmaWVkLWNhbGxcIiwgXCJyZWNlaXZlci1jYWxsXCJdLmluY2x1ZGVzKGZvcm0pKSB8fFxuICAgICAgbmV3IFNldCh2YWx1ZS5mb3Jtcykuc2l6ZSAhPSB2YWx1ZS5mb3Jtcy5sZW5ndGggfHxcbiAgICAgIHZhbHVlLm93bmVyc2hpcCAhPSBcIm5vdC1hcHBsaWNhYmxlXCIgfHxcbiAgICAgICFpc0RlbnNlQXJyYXkodmFsdWUucGFyYW1ldGVycykpIGludmFsaWRGYWNhZGUoYEZhY2FkZSAnJHtpZGVudGl0eX0nIGRlY2xhcmF0aW9uICcke25hbWV9JyBoYXMgYW4gaW52YWxpZCBwdWJsaWMgY29udHJhY3QuYClcbiAgICBjb25zdCBwYXJhbWV0ZXJzID0gdmFsaWRhdGVGYWNhZGVQYXJhbWV0ZXJzKHZhbHVlLnBhcmFtZXRlcnMsIGlkZW50aXR5LCBuYW1lKVxuICAgIGNvbnN0IHJldHVyblR5cGUgPSByZXF1aXJlU3RyaW5nKHZhbHVlLnJldHVyblR5cGUsIGBGYWNhZGUgJyR7aWRlbnRpdHl9JyByZXR1cm4gdHlwZWApXG5cbiAgICBpZiAoIWlzRmFjYWRlVHlwZShyZXR1cm5UeXBlLCB0cnVlKSkgaW52YWxpZEZhY2FkZShgRmFjYWRlICcke2lkZW50aXR5fScgZGVjbGFyYXRpb24gJyR7bmFtZX0nIGhhcyBhbiBpbnZhbGlkIHJldHVybiB0eXBlLmApXG4gICAgcmV0dXJuIHtcbiAgICAgIGVmZmVjdHM6IC8qKiBAdHlwZSB7c3RyaW5nW119ICovIChbLi4udmFsdWUuZWZmZWN0c10pLFxuICAgICAgZmFpbHVyZXM6IC8qKiBAdHlwZSB7c3RyaW5nW119ICovIChbLi4udmFsdWUuZmFpbHVyZXNdKSxcbiAgICAgIGZvcm1zOiAvKiogQHR5cGUgeyhcImRpcmVjdC1jYWxsXCIgfCBcInVucXVhbGlmaWVkLWNhbGxcIiB8IFwicmVjZWl2ZXItY2FsbFwiKVtdfSAqLyAoWy4uLnZhbHVlLmZvcm1zXSksXG4gICAgICBraW5kOiAvKiogQHR5cGUge2NvbnN0fSAqLyAoXCJmdW5jdGlvblwiKSxcbiAgICAgIG5hbWUsXG4gICAgICBvd25lcnNoaXA6IC8qKiBAdHlwZSB7Y29uc3R9ICovIChcIm5vdC1hcHBsaWNhYmxlXCIpLFxuICAgICAgcGFyYW1ldGVycyxcbiAgICAgIHJldHVyblR5cGVcbiAgICB9XG4gIH0pXG59XG5cbi8qKlxuICogVmFsaWRhdGVzIHRoZSBleGFjdCBuYXRpdmUgbW9kdWxlIGFuZCBzeW1ib2wgaWRlbnRpdGllcyBzZWxlY3RpbmcgYSBmYWNhZGUuXG4gKiBAcGFyYW0ge3Vua25vd259IGNhbmRpZGF0ZSAtIENhbmRpZGF0ZSBuYXRpdmUgbW9kdWxlcy5cbiAqIEBwYXJhbSB7c3RyaW5nfSBpZGVudGl0eSAtIE93bmluZyBmYWNhZGUgaWRlbnRpdHkuXG4gKiBAcGFyYW0ge1N0ZGxpYkZhY2FkZVB1YmxpY0RlY2xhcmF0aW9uW119IGRlY2xhcmF0aW9ucyAtIFZhbGlkYXRlZCBwdWJsaWMgc3VyZmFjZS5cbiAqIEByZXR1cm5zIHsoe2lkZW50aXR5OiBzdHJpbmcsIGtpbmQ6IFwibW9kdWxlXCIsIHN5bWJvbHM6IHN0cmluZ1tdfSB8IHtmb3JtczogKFwidW5xdWFsaWZpZWQtY2FsbFwiIHwgXCJyZWNlaXZlci1jYWxsXCIpW10sIGlkZW50aXR5OiBzdHJpbmcsIGtpbmQ6IFwiYnVpbHRpblwiLCBzeW1ib2xzOiBzdHJpbmdbXX0pW119IFZhbGlkYXRlZCBuYXRpdmUgaWRlbnRpdGllcy5cbiAqL1xuZnVuY3Rpb24gdmFsaWRhdGVOYXRpdmVNb2R1bGVzKGNhbmRpZGF0ZSwgaWRlbnRpdHksIGRlY2xhcmF0aW9ucykge1xuICBpZiAoIWlzRGVuc2VBcnJheShjYW5kaWRhdGUpKSBpbnZhbGlkRmFjYWRlKGBGYWNhZGUgJyR7aWRlbnRpdHl9JyBuYXRpdmUgbW9kdWxlcyBtdXN0IGJlIGEgZGVuc2UgYXJyYXkuYClcbiAgY29uc3QgbW9kdWxlcyA9IG5ldyBTZXQoKVxuICBjb25zdCBwdWJsaWNOYW1lcyA9IG5ldyBTZXQoZGVjbGFyYXRpb25zLm1hcCgoe25hbWV9KSA9PiBuYW1lKSlcbiAgcmV0dXJuIGNhbmRpZGF0ZS5tYXAoKHZhbHVlKSA9PiB7XG4gICAgaWYgKCFpc1BsYWluT2JqZWN0KHZhbHVlKSkgaW52YWxpZEZhY2FkZShgRmFjYWRlICcke2lkZW50aXR5fScgbmF0aXZlIG1vZHVsZXMgbXVzdCBiZSBwbGFpbiBvYmplY3RzLmApXG4gICAgY29uc3QgYnVpbHRpbiA9IHZhbHVlLmtpbmQgPT0gXCJidWlsdGluXCJcblxuICAgIHJlcXVpcmVLZXlzKHZhbHVlLCBidWlsdGluID8gW1wiZm9ybXNcIiwgXCJpZGVudGl0eVwiLCBcImtpbmRcIiwgXCJzeW1ib2xzXCJdIDogW1wiaWRlbnRpdHlcIiwgXCJraW5kXCIsIFwic3ltYm9sc1wiXSxcbiAgICAgIGBmYWNhZGUgJyR7aWRlbnRpdHl9JyBuYXRpdmUgbW9kdWxlYClcbiAgICBjb25zdCBtb2R1bGVJZGVudGl0eSA9IHJlcXVpcmVTdHJpbmcodmFsdWUuaWRlbnRpdHksIGBGYWNhZGUgJyR7aWRlbnRpdHl9JyBuYXRpdmUgbW9kdWxlIGlkZW50aXR5YClcblxuICAgIGlmICh2YWx1ZS5raW5kICE9IFwibW9kdWxlXCIgJiYgdmFsdWUua2luZCAhPSBcImJ1aWx0aW5cIiB8fCBtb2R1bGVzLmhhcyhtb2R1bGVJZGVudGl0eSkgfHxcbiAgICAgICFpc0RlbnNlQXJyYXkodmFsdWUuc3ltYm9scykgfHwgdmFsdWUuc3ltYm9scy5sZW5ndGggPT0gMCB8fFxuICAgICAgIXZhbHVlLnN5bWJvbHMuZXZlcnkoKHN5bWJvbCkgPT4gdHlwZW9mIHN5bWJvbCA9PSBcInN0cmluZ1wiICYmIHB1YmxpY05hbWVzLmhhcyhzeW1ib2wpKSB8fFxuICAgICAgbmV3IFNldCh2YWx1ZS5zeW1ib2xzKS5zaXplICE9IHZhbHVlLnN5bWJvbHMubGVuZ3RoKSB7XG4gICAgICBpbnZhbGlkRmFjYWRlKGBGYWNhZGUgJyR7aWRlbnRpdHl9JyBoYXMgYW4gaW52YWxpZCBuYXRpdmUgbW9kdWxlIGRlY2xhcmF0aW9uLmApXG4gICAgfVxuICAgIGlmIChidWlsdGluICYmICghaXNEZW5zZUFycmF5KHZhbHVlLmZvcm1zKSB8fCB2YWx1ZS5mb3Jtcy5sZW5ndGggPT0gMCB8fFxuICAgICAgIXZhbHVlLmZvcm1zLmV2ZXJ5KChmb3JtKSA9PiBmb3JtID09IFwidW5xdWFsaWZpZWQtY2FsbFwiIHx8IGZvcm0gPT0gXCJyZWNlaXZlci1jYWxsXCIpIHx8XG4gICAgICBuZXcgU2V0KHZhbHVlLmZvcm1zKS5zaXplICE9IHZhbHVlLmZvcm1zLmxlbmd0aCkpIGludmFsaWRGYWNhZGUoYEZhY2FkZSAnJHtpZGVudGl0eX0nIGhhcyBpbnZhbGlkIGJ1aWx0aW4gZm9ybXMuYClcbiAgICBtb2R1bGVzLmFkZChtb2R1bGVJZGVudGl0eSlcbiAgICByZXR1cm4gYnVpbHRpblxuICAgICAgPyB7Zm9ybXM6IC8qKiBAdHlwZSB7KFwidW5xdWFsaWZpZWQtY2FsbFwiIHwgXCJyZWNlaXZlci1jYWxsXCIpW119ICovIChbLi4uLyoqIEB0eXBlIHt1bmtub3duW119ICovICh2YWx1ZS5mb3JtcyldKSwgaWRlbnRpdHk6IG1vZHVsZUlkZW50aXR5LFxuICAgICAgICBraW5kOiAvKiogQHR5cGUge2NvbnN0fSAqLyAoXCJidWlsdGluXCIpLCBzeW1ib2xzOiAvKiogQHR5cGUge3N0cmluZ1tdfSAqLyAoWy4uLnZhbHVlLnN5bWJvbHNdKX1cbiAgICAgIDoge2lkZW50aXR5OiBtb2R1bGVJZGVudGl0eSwga2luZDogLyoqIEB0eXBlIHtjb25zdH0gKi8gKFwibW9kdWxlXCIpLCBzeW1ib2xzOiAvKiogQHR5cGUge3N0cmluZ1tdfSAqLyAoWy4uLnZhbHVlLnN5bWJvbHNdKX1cbiAgfSlcbn1cblxuLyoqXG4gKiBWYWxpZGF0ZXMgY2Fub25pY2FsLW9ubHkgZmFjYWRlIGNhcGFiaWxpdHkgcmVxdWlyZW1lbnRzLlxuICogQHBhcmFtIHt1bmtub3dufSBjYW5kaWRhdGUgLSBDYW5kaWRhdGUgcmVxdWlyZW1lbnRzLlxuICogQHBhcmFtIHtzdHJpbmd9IGlkZW50aXR5IC0gT3duaW5nIGZhY2FkZSBpZGVudGl0eS5cbiAqIEByZXR1cm5zIHt7bW9kdWxlOiBzdHJpbmcsIG9wZXJhdGlvbnM6IHN0cmluZ1tdLCByYW5nZTogc3RyaW5nfVtdfSBWYWxpZGF0ZWQgcmVxdWlyZW1lbnRzLlxuICovXG5mdW5jdGlvbiB2YWxpZGF0ZVJlcXVpcmVtZW50cyhjYW5kaWRhdGUsIGlkZW50aXR5KSB7XG4gIGlmICghaXNEZW5zZUFycmF5KGNhbmRpZGF0ZSkpIGludmFsaWRGYWNhZGUoYEZhY2FkZSAnJHtpZGVudGl0eX0nIHJlcXVpcmVtZW50cyBtdXN0IGJlIGEgZGVuc2UgYXJyYXkuYClcbiAgY29uc3QgbW9kdWxlcyA9IG5ldyBTZXQoKVxuICByZXR1cm4gY2FuZGlkYXRlLm1hcCgodmFsdWUpID0+IHtcbiAgICBpZiAoIWlzUGxhaW5PYmplY3QodmFsdWUpKSBpbnZhbGlkRmFjYWRlKGBGYWNhZGUgJyR7aWRlbnRpdHl9JyByZXF1aXJlbWVudHMgbXVzdCBiZSBwbGFpbiBvYmplY3RzLmApXG4gICAgcmVxdWlyZUtleXModmFsdWUsIFtcIm1vZHVsZVwiLCBcIm9wZXJhdGlvbnNcIiwgXCJyYW5nZVwiXSwgYGZhY2FkZSAnJHtpZGVudGl0eX0nIHJlcXVpcmVtZW50YClcbiAgICBjb25zdCBtb2R1bGUgPSByZXF1aXJlU3RyaW5nKHZhbHVlLm1vZHVsZSwgYEZhY2FkZSAnJHtpZGVudGl0eX0nIGNhbm9uaWNhbCBtb2R1bGVgKVxuICAgIGNvbnN0IHJhbmdlID0gcmVxdWlyZVN0cmluZyh2YWx1ZS5yYW5nZSwgYEZhY2FkZSAnJHtpZGVudGl0eX0nIGNhbm9uaWNhbCByYW5nZWApXG5cbiAgICBpZiAobW9kdWxlcy5oYXMobW9kdWxlKSB8fCAhcGFyc2VTdGRsaWJWZXJzaW9uUmFuZ2UocmFuZ2UpIHx8ICFpc0RlbnNlQXJyYXkodmFsdWUub3BlcmF0aW9ucykgfHwgdmFsdWUub3BlcmF0aW9ucy5sZW5ndGggPT0gMCB8fFxuICAgICAgIXZhbHVlLm9wZXJhdGlvbnMuZXZlcnkoKG9wZXJhdGlvbikgPT4gdHlwZW9mIG9wZXJhdGlvbiA9PSBcInN0cmluZ1wiICYmIGRlY2xhcmF0aW9uTmFtZVBhdHRlcm4udGVzdChvcGVyYXRpb24pKSB8fFxuICAgICAgbmV3IFNldCh2YWx1ZS5vcGVyYXRpb25zKS5zaXplICE9IHZhbHVlLm9wZXJhdGlvbnMubGVuZ3RoKSBpbnZhbGlkRmFjYWRlKGBGYWNhZGUgJyR7aWRlbnRpdHl9JyBoYXMgYW4gaW52YWxpZCBjYW5vbmljYWwgcmVxdWlyZW1lbnQuYClcbiAgICBjb25zdCBjb250cmFjdCA9IHJlc29sdmVTdGRsaWJNb2R1bGUobW9kdWxlLCByYW5nZSlcbiAgICBjb25zdCBkZWNsYXJlZCA9IG5ldyBTZXQoY29udHJhY3Qub3BlcmF0aW9ucy5tYXAoKHtuYW1lfSkgPT4gbmFtZSkpXG5cbiAgICBpZiAoIS8qKiBAdHlwZSB7c3RyaW5nW119ICovICh2YWx1ZS5vcGVyYXRpb25zKS5ldmVyeSgob3BlcmF0aW9uKSA9PiBkZWNsYXJlZC5oYXMob3BlcmF0aW9uKSkpIHtcbiAgICAgIGludmFsaWRGYWNhZGUoYEZhY2FkZSAnJHtpZGVudGl0eX0nIHJlcXVpcmVzIGFuIHVuZGVjbGFyZWQgY2Fub25pY2FsIG9wZXJhdGlvbi5gKVxuICAgIH1cbiAgICBtb2R1bGVzLmFkZChtb2R1bGUpXG4gICAgcmV0dXJuIHttb2R1bGUsIG9wZXJhdGlvbnM6IC8qKiBAdHlwZSB7c3RyaW5nW119ICovIChbLi4udmFsdWUub3BlcmF0aW9uc10pLCByYW5nZX1cbiAgfSlcbn1cblxuLyoqXG4gKiBWYWxpZGF0ZXMgdmVyc2lvbmVkIHNhbWUtbGFuZ3VhZ2UgZmFjYWRlIGRlcGVuZGVuY2llcy5cbiAqIEBwYXJhbSB7dW5rbm93bn0gY2FuZGlkYXRlIC0gQ2FuZGlkYXRlIGRlcGVuZGVuY2llcy5cbiAqIEBwYXJhbSB7c3RyaW5nfSBpZGVudGl0eSAtIE93bmluZyBmYWNhZGUgaWRlbnRpdHkuXG4gKiBAcmV0dXJucyB7e2lkZW50aXR5OiBzdHJpbmcsIHJhbmdlOiBzdHJpbmd9W119IFZhbGlkYXRlZCBkZXBlbmRlbmNpZXMuXG4gKi9cbmZ1bmN0aW9uIHZhbGlkYXRlRGVwZW5kZW5jaWVzKGNhbmRpZGF0ZSwgaWRlbnRpdHkpIHtcbiAgaWYgKCFpc0RlbnNlQXJyYXkoY2FuZGlkYXRlKSkgaW52YWxpZEZhY2FkZShgRmFjYWRlICcke2lkZW50aXR5fScgZGVwZW5kZW5jaWVzIG11c3QgYmUgYSBkZW5zZSBhcnJheS5gKVxuICBjb25zdCBpZGVudGl0aWVzID0gbmV3IFNldCgpXG4gIHJldHVybiBjYW5kaWRhdGUubWFwKCh2YWx1ZSkgPT4ge1xuICAgIGlmICghaXNQbGFpbk9iamVjdCh2YWx1ZSkpIGludmFsaWRGYWNhZGUoYEZhY2FkZSAnJHtpZGVudGl0eX0nIGRlcGVuZGVuY2llcyBtdXN0IGJlIHBsYWluIG9iamVjdHMuYClcbiAgICByZXF1aXJlS2V5cyh2YWx1ZSwgW1wiaWRlbnRpdHlcIiwgXCJyYW5nZVwiXSwgYGZhY2FkZSAnJHtpZGVudGl0eX0nIGRlcGVuZGVuY3lgKVxuICAgIGNvbnN0IGRlcGVuZGVuY3lJZGVudGl0eSA9IHJlcXVpcmVTdHJpbmcodmFsdWUuaWRlbnRpdHksIGBGYWNhZGUgJyR7aWRlbnRpdHl9JyBkZXBlbmRlbmN5IGlkZW50aXR5YClcbiAgICBjb25zdCByYW5nZSA9IHJlcXVpcmVTdHJpbmcodmFsdWUucmFuZ2UsIGBGYWNhZGUgJyR7aWRlbnRpdHl9JyBkZXBlbmRlbmN5IHJhbmdlYClcblxuICAgIGlmICghZmFjYWRlSWRlbnRpdHlQYXR0ZXJuLnRlc3QoZGVwZW5kZW5jeUlkZW50aXR5KSB8fCBkZXBlbmRlbmN5SWRlbnRpdHkgPT0gaWRlbnRpdHkgfHwgaWRlbnRpdGllcy5oYXMoZGVwZW5kZW5jeUlkZW50aXR5KSB8fFxuICAgICAgIXBhcnNlU3RkbGliVmVyc2lvblJhbmdlKHJhbmdlKSkgaW52YWxpZEZhY2FkZShgRmFjYWRlICcke2lkZW50aXR5fScgaGFzIGFuIGludmFsaWQgZGVwZW5kZW5jeS5gKVxuICAgIGlkZW50aXRpZXMuYWRkKGRlcGVuZGVuY3lJZGVudGl0eSlcbiAgICByZXR1cm4ge2lkZW50aXR5OiBkZXBlbmRlbmN5SWRlbnRpdHksIHJhbmdlfVxuICB9KVxufVxuXG4vKipcbiAqIEJ1aWxkcyB0aGUgYm91bmRlZCBvcmlnaW5hbC1maXZlIHF1YWxpZmljYXRpb24gZmFjYWRlIGRlZmluaXRpb25zLlxuICogQHJldHVybnMge3Vua25vd25bXX0gVW52YWxpZGF0ZWQgYnVpbHQtaW4gcXVhbGlmaWNhdGlvbiBmYWNhZGUgZGVmaW5pdGlvbnMuXG4gKi9cbmZ1bmN0aW9uIGJ1aWx0aW5GYWNhZGVSZWNvcmRzKCkge1xuICByZXR1cm4gW1wicGhwXCIsIFwicnVieVwiLCBcImphdmFzY3JpcHRcIiwgXCJ0eXBlc2NyaXB0XCIsIFwiamF2YVwiXS5mbGF0TWFwKChsYW5ndWFnZSkgPT4gYnVpbHRpbkxhbmd1YWdlRmFjYWRlcyhsYW5ndWFnZSkpXG4gICAgLmNvbmNhdChidWlsdGluVGFzazAzN1J1YnlGYWNhZGVzKCkpXG59XG5cbi8qKlxuICogQnVpbGRzIG9uZSBzb3VyY2UgbGFuZ3VhZ2UncyBwdWJsaWMsIGludGVybmFsLCBhbmQgdW5yZWFjaGFibGUgcXVhbGlmaWNhdGlvbiBmYWNhZGVzLlxuICogQHBhcmFtIHtzdHJpbmd9IGxhbmd1YWdlIC0gU291cmNlIGxhbmd1YWdlLlxuICogQHJldHVybnMge3Vua25vd25bXX0gTGFuZ3VhZ2UgZmFjYWRlIGRlZmluaXRpb25zLlxuICovXG5mdW5jdGlvbiBidWlsdGluTGFuZ3VhZ2VGYWNhZGVzKGxhbmd1YWdlKSB7XG4gIGNvbnN0IG5hbWVzID0gZmFjYWRlTmFtZXMobGFuZ3VhZ2UpXG4gIGNvbnN0IGJhc2UgPSBgc2VtYW50aWZvbGQudGFzazAzNi4ke2xhbmd1YWdlfWBcbiAgY29uc3Qgc291cmNlQmFzZSA9IGBzZW1hbnRpZm9sZC5mYWNhZGUuJHtsYW5ndWFnZX1gXG4gIGNvbnN0IHNvdXJjZURpcmVjdG9yeSA9IGBfX3NlbWFudGlmb2xkX2ZhY2FkZXNfXy8ke2xhbmd1YWdlfWBcbiAgY29uc3QgcHJvYmVGaWxlbmFtZSA9IGxhbmd1YWdlID09IFwiamF2YVwiID8gYCR7c291cmNlRGlyZWN0b3J5fS9zZW1hbnRpZm9sZC9mYWNhZGUvamF2YS9wcm9iZS9Qcm9iZS5qYXZhYCA6XG4gICAgYCR7c291cmNlRGlyZWN0b3J5fS9wcm9iZS4ke25hbWVzLmV4dGVuc2lvbn1gXG4gIGNvbnN0IHJ1bm5lckZpbGVuYW1lID0gbGFuZ3VhZ2UgPT0gXCJqYXZhXCIgPyBgJHtzb3VyY2VEaXJlY3Rvcnl9L3NlbWFudGlmb2xkL2ZhY2FkZS9qYXZhL3Byb2JlcnVubmVyL1Byb2JlUnVubmVyLmphdmFgIDpcbiAgICBgJHtzb3VyY2VEaXJlY3Rvcnl9L3Byb2JlLXJ1bm5lci4ke25hbWVzLmV4dGVuc2lvbn1gXG4gIGNvbnN0IHVudXNlZEZpbGVuYW1lID0gbGFuZ3VhZ2UgPT0gXCJqYXZhXCIgPyBgJHtzb3VyY2VEaXJlY3Rvcnl9L3NlbWFudGlmb2xkL2ZhY2FkZS9qYXZhL3VudXNlZC9VbnVzZWQuamF2YWAgOlxuICAgIGAke3NvdXJjZURpcmVjdG9yeX0vdW51c2VkLiR7bmFtZXMuZXh0ZW5zaW9ufWBcblxuICByZXR1cm4gW3tcbiAgICBkZXBlbmRlbmNpZXM6IFt7aWRlbnRpdHk6IGAke2Jhc2V9LnByb2JlLXJ1bm5lcmAsIHJhbmdlOiBcIjFcIn1dLFxuICAgIGlkZW50aXR5OiBgJHtiYXNlfS5wcm9iZWAsXG4gICAgbGFuZ3VhZ2UsXG4gICAgbmF0aXZlTW9kdWxlczogW3tpZGVudGl0eTogbmFtZXMubmF0aXZlTW9kdWxlLCBraW5kOiBcIm1vZHVsZVwiLCBzeW1ib2xzOiBbbmFtZXMucHVibGljTmFtZV19XSxcbiAgICBwdWJsaWNEZWNsYXJhdGlvbnM6IFtwdWJsaWNEZWNsYXJhdGlvbihuYW1lcy5wdWJsaWNOYW1lKV0sXG4gICAgcmVxdWlyZW1lbnRzOiBbXSxcbiAgICBydW50aW1lUHJvZmlsZTogYCR7bGFuZ3VhZ2V9LXRhc2swMzYtdjFgLFxuICAgIHNvdXJjZToge2NvbnRlbnQ6IG5hbWVzLnByb2JlU291cmNlLCBmaWxlbmFtZTogcHJvYmVGaWxlbmFtZSwgaWQ6IGAke3NvdXJjZUJhc2V9LnByb2JlYH0sXG4gICAgdmVyc2lvbjogXCIxLjAuMFwiLFxuICAgIHZpc2liaWxpdHk6IFwicHVibGljXCJcbiAgfSwge1xuICAgIGRlcGVuZGVuY2llczogW10sXG4gICAgaWRlbnRpdHk6IGAke2Jhc2V9LnByb2JlLXJ1bm5lcmAsXG4gICAgbGFuZ3VhZ2UsXG4gICAgbmF0aXZlTW9kdWxlczogW10sXG4gICAgcHVibGljRGVjbGFyYXRpb25zOiBbXSxcbiAgICByZXF1aXJlbWVudHM6IFt7bW9kdWxlOiBcInNlbWFudGlmb2xkLnRhc2swMzQucmVzb3VyY2UtcHJvYmVcIiwgb3BlcmF0aW9uczogW1wicHJvYmVFZmZlY3RcIiwgXCJwcm9iZVRyYWNlXCJdLCByYW5nZTogXCIxXCJ9XSxcbiAgICBydW50aW1lUHJvZmlsZTogYCR7bGFuZ3VhZ2V9LXRhc2swMzYtdjFgLFxuICAgIHNvdXJjZToge2NvbnRlbnQ6IG5hbWVzLnJ1bm5lclNvdXJjZSwgZmlsZW5hbWU6IHJ1bm5lckZpbGVuYW1lLCBpZDogYCR7c291cmNlQmFzZX0ucHJvYmVfcnVubmVyYH0sXG4gICAgdmVyc2lvbjogXCIxLjAuMFwiLFxuICAgIHZpc2liaWxpdHk6IFwiaW50ZXJuYWxcIlxuICB9LCB7XG4gICAgZGVwZW5kZW5jaWVzOiBbXSxcbiAgICBpZGVudGl0eTogYCR7YmFzZX0udW51c2VkYCxcbiAgICBsYW5ndWFnZSxcbiAgICBuYXRpdmVNb2R1bGVzOiBbe2lkZW50aXR5OiBuYW1lcy51bnVzZWROYXRpdmVNb2R1bGUsIGtpbmQ6IFwibW9kdWxlXCIsIHN5bWJvbHM6IFtuYW1lcy51bnVzZWROYW1lXX1dLFxuICAgIHB1YmxpY0RlY2xhcmF0aW9uczogW3B1YmxpY0RlY2xhcmF0aW9uKG5hbWVzLnVudXNlZE5hbWUpXSxcbiAgICByZXF1aXJlbWVudHM6IFt7bW9kdWxlOiBcInNlbWFudGlmb2xkLnRhc2swMzQucmVzb3VyY2UtcHJvYmVcIiwgb3BlcmF0aW9uczogW1wicHJvYmVUcmFjZVwiXSwgcmFuZ2U6IFwiMVwifV0sXG4gICAgcnVudGltZVByb2ZpbGU6IGAke2xhbmd1YWdlfS10YXNrMDM2LXYxYCxcbiAgICBzb3VyY2U6IHtjb250ZW50OiBuYW1lcy51bnVzZWRTb3VyY2UsIGZpbGVuYW1lOiB1bnVzZWRGaWxlbmFtZSwgaWQ6IGAke3NvdXJjZUJhc2V9LnVudXNlZGB9LFxuICAgIHZlcnNpb246IFwiMS4wLjBcIixcbiAgICB2aXNpYmlsaXR5OiBcInB1YmxpY1wiXG4gIH1dXG59XG5cbi8qKlxuICogQnVpbGRzIHRoZSBjb21tb24gYm91bmRlZCBxdWFsaWZpY2F0aW9uIGZ1bmN0aW9uIGRlY2xhcmF0aW9uLlxuICogQHBhcmFtIHtzdHJpbmd9IG5hbWUgLSBTb3VyY2UtdmlzaWJsZSBmdW5jdGlvbiBuYW1lLlxuICogQHJldHVybnMge1N0ZGxpYkZhY2FkZVB1YmxpY0RlY2xhcmF0aW9ufSBQdWJsaWMgZmFjYWRlIGRlY2xhcmF0aW9uLlxuICovXG5mdW5jdGlvbiBwdWJsaWNEZWNsYXJhdGlvbihuYW1lKSB7XG4gIHJldHVybiB7XG4gICAgZWZmZWN0czogW1wiaG9zdFwiXSwgZmFpbHVyZXM6IFtdLCBmb3JtczogW1wiZGlyZWN0LWNhbGxcIl0sIGtpbmQ6IFwiZnVuY3Rpb25cIiwgbmFtZSxcbiAgICBvd25lcnNoaXA6IFwibm90LWFwcGxpY2FibGVcIiwgcGFyYW1ldGVyczogW3tuYW1lOiBcImxhYmVsXCIsIHR5cGU6IFwic3RyaW5nXCJ9XSwgcmV0dXJuVHlwZTogXCJzdHJpbmdcIlxuICB9XG59XG5cbi8qKlxuICogQnVpbGRzIHRoZSBleGFjdCBSdWJ5IFRhc2sgMDM3IHNvY2tldCBhbmQgb3V0cHV0IGNvbXBhdGliaWxpdHkgZmFjYWRlcy5cbiAqIEByZXR1cm5zIHt1bmtub3duW119IFVudmFsaWRhdGVkIGZhY2FkZSByZWNvcmRzLlxuICovXG5mdW5jdGlvbiBidWlsdGluVGFzazAzN1J1YnlGYWNhZGVzKCkge1xuICByZXR1cm4gW3tcbiAgICBkZXBlbmRlbmNpZXM6IFtdLFxuICAgIGlkZW50aXR5OiBcInNlbWFudGlmb2xkLnRhc2swMzcucnVieS5zb2NrZXRcIixcbiAgICBsYW5ndWFnZTogXCJydWJ5XCIsXG4gICAgbmF0aXZlTW9kdWxlczogW3tpZGVudGl0eTogXCJzb2NrZXRcIiwga2luZDogXCJtb2R1bGVcIiwgc3ltYm9sczogW1wiVENQU29ja2V0XCJdfV0sXG4gICAgcHVibGljRGVjbGFyYXRpb25zOiBbe1xuICAgICAgY29uc3RydWN0b3I6IHtcbiAgICAgICAgZWZmZWN0czogW1wiaG9zdFwiXSwgZmFpbHVyZXM6IFtcIkludmFsaWRIb3N0XCIsIFwiSW52YWxpZFBvcnRcIiwgXCJDb25uZWN0aW9uRmFpbHVyZVwiXSwgb3duZXJzaGlwOiBcImFjcXVpcmVkXCIsXG4gICAgICAgIHBhcmFtZXRlcnM6IFt7bmFtZTogXCJob3N0XCIsIHR5cGU6IFwic3RyaW5nXCJ9LCB7bmFtZTogXCJwb3J0XCIsIHR5cGU6IFwiaW50ZWdlclwifV1cbiAgICAgIH0sXG4gICAgICBmb3JtczogW1wiY29uc3RydWN0b3ItY2FsbFwiXSxcbiAgICAgIGtpbmQ6IFwiY2xhc3NcIixcbiAgICAgIG1ldGhvZHM6IFt7XG4gICAgICAgIGVmZmVjdHM6IFtcImhvc3RcIl0sIGZhaWx1cmVzOiBbXCJSZWFkRmFpbHVyZVwiLCBcIkRlY29kZUZhaWx1cmVcIiwgXCJSZXNvdXJjZUNsb3NlZFwiXSwgZm9ybXM6IFtcInJlY2VpdmVyLWNhbGxcIl0sXG4gICAgICAgIG5hbWU6IFwiZ2V0c1wiLCBvd25lcnNoaXA6IFwiYm9ycm93ZWRcIiwgcGFyYW1ldGVyczogW10sIHJldHVyblR5cGU6IFwib3B0aW9uYWw6c3RyaW5nXCJcbiAgICAgIH0sIHtcbiAgICAgICAgZWZmZWN0czogW1wiaG9zdFwiXSwgZmFpbHVyZXM6IFtcIkNsb3NlRmFpbHVyZVwiLCBcIlJlc291cmNlQ2xvc2VkXCJdLCBmb3JtczogW1wicmVjZWl2ZXItY2FsbFwiXSxcbiAgICAgICAgbmFtZTogXCJjbG9zZVwiLCBvd25lcnNoaXA6IFwiY29uc3VtZWRcIiwgcGFyYW1ldGVyczogW10sIHJldHVyblR5cGU6IFwidm9pZFwiXG4gICAgICB9XSxcbiAgICAgIG5hbWU6IFwiVENQU29ja2V0XCIsXG4gICAgICBvd25lcnNoaXA6IFwib3duZWQtcmVmZXJlbmNlXCJcbiAgICB9XSxcbiAgICByZXF1aXJlbWVudHM6IFtcbiAgICAgIHttb2R1bGU6IFwic2VtYW50aWZvbGQuc29ja2V0LWNsaWVudFwiLCBvcGVyYXRpb25zOiBbXCJ2MV9jb25uZWN0XCJdLCByYW5nZTogXCIxXCJ9LFxuICAgICAge21vZHVsZTogXCJzZW1hbnRpZm9sZC50ZXh0LXN0cmVhbVwiLCBvcGVyYXRpb25zOiBbXCJ2MV9yZWFkX2xpbmVcIl0sIHJhbmdlOiBcIjFcIn0sXG4gICAgICB7bW9kdWxlOiBcInNlbWFudGlmb2xkLnJlc291cmNlXCIsIG9wZXJhdGlvbnM6IFtcInYxX2Nsb3NlXCJdLCByYW5nZTogXCIxXCJ9XG4gICAgXSxcbiAgICBydW50aW1lUHJvZmlsZTogXCJydWJ5LXRhc2swMzctc29ja2V0LXYxXCIsXG4gICAgc291cmNlOiB7XG4gICAgICBjb250ZW50OiBgbW9kdWxlIFNlbWFudGlmb2xkVGFzazAzN1NvY2tldFxuICBjbGFzcyBUQ1BTb2NrZXRcbiAgICAjIEBwYXJhbSBob3N0IFtTdHJpbmddXG4gICAgIyBAcGFyYW0gcG9ydCBbSW50ZWdlcl1cbiAgICBkZWYgaW5pdGlhbGl6ZShob3N0LCBwb3J0KVxuICAgICAgQHJlc291cmNlID0gdjFfY29ubmVjdChob3N0LCBwb3J0KVxuICAgIGVuZFxuXG4gICAgIyBAcmV0dXJuIFtTdHJpbmc/XVxuICAgIGRlZiBnZXRzXG4gICAgICByZXR1cm4gdjFfcmVhZF9saW5lKEByZXNvdXJjZSlcbiAgICBlbmRcblxuICAgICMgQHJldHVybiBbdm9pZF1cbiAgICBkZWYgY2xvc2VcbiAgICAgIHYxX2Nsb3NlKEByZXNvdXJjZSlcbiAgICBlbmRcbiAgZW5kXG5lbmRcbmAsXG4gICAgICBmaWxlbmFtZTogXCJfX3NlbWFudGlmb2xkX2ZhY2FkZXNfXy9ydWJ5L3NvY2tldC5yYlwiLFxuICAgICAgaWQ6IFwic2VtYW50aWZvbGQuZmFjYWRlLnJ1Ynkuc29ja2V0XCJcbiAgICB9LFxuICAgIHZlcnNpb246IFwiMS4wLjBcIixcbiAgICB2aXNpYmlsaXR5OiBcInB1YmxpY1wiXG4gIH0sIHtcbiAgICBkZXBlbmRlbmNpZXM6IFtdLFxuICAgIGlkZW50aXR5OiBcInNlbWFudGlmb2xkLnRhc2swMzcucnVieS5vdXRwdXRcIixcbiAgICBsYW5ndWFnZTogXCJydWJ5XCIsXG4gICAgbmF0aXZlTW9kdWxlczogW3tmb3JtczogW1widW5xdWFsaWZpZWQtY2FsbFwiLCBcInJlY2VpdmVyLWNhbGxcIl0sIGlkZW50aXR5OiBcInJ1Ynk6S2VybmVsXCIsIGtpbmQ6IFwiYnVpbHRpblwiLCBzeW1ib2xzOiBbXCJwdXRzXCJdfV0sXG4gICAgcHVibGljRGVjbGFyYXRpb25zOiBbe1xuICAgICAgZWZmZWN0czogW1wiaG9zdFwiXSwgZmFpbHVyZXM6IFtcIldyaXRlRmFpbHVyZVwiXSwgZm9ybXM6IFtcInVucXVhbGlmaWVkLWNhbGxcIiwgXCJyZWNlaXZlci1jYWxsXCJdLCBraW5kOiBcImZ1bmN0aW9uXCIsXG4gICAgICBuYW1lOiBcInB1dHNcIiwgb3duZXJzaGlwOiBcIm5vdC1hcHBsaWNhYmxlXCIsIHBhcmFtZXRlcnM6IFt7bmFtZTogXCJ0ZXh0XCIsIHR5cGU6IFwic3RyaW5nXCJ9XSwgcmV0dXJuVHlwZTogXCJ2b2lkXCJcbiAgICB9XSxcbiAgICByZXF1aXJlbWVudHM6IFt7bW9kdWxlOiBcInNlbWFudGlmb2xkLm91dHB1dFwiLCBvcGVyYXRpb25zOiBbXCJ2MV93cml0ZV9saW5lXCJdLCByYW5nZTogXCIxXCJ9XSxcbiAgICBydW50aW1lUHJvZmlsZTogXCJydWJ5LXRhc2swMzctb3V0cHV0LXYxXCIsXG4gICAgc291cmNlOiB7XG4gICAgICBjb250ZW50OiBgbW9kdWxlIFNlbWFudGlmb2xkVGFzazAzN091dHB1dFxuICBtb2R1bGVfZnVuY3Rpb25cbiAgIyBAcGFyYW0gdGV4dCBbU3RyaW5nXVxuICAjIEByZXR1cm4gW3ZvaWRdXG4gIGRlZiBwdXRzKHRleHQpXG4gICAgdjFfd3JpdGVfbGluZSh0ZXh0KVxuICAgIHJldHVyblxuICBlbmRcbmVuZFxuYCxcbiAgICAgIGZpbGVuYW1lOiBcIl9fc2VtYW50aWZvbGRfZmFjYWRlc19fL3J1Ynkvb3V0cHV0LnJiXCIsXG4gICAgICBpZDogXCJzZW1hbnRpZm9sZC5mYWNhZGUucnVieS5vdXRwdXRcIlxuICAgIH0sXG4gICAgdmVyc2lvbjogXCIxLjAuMFwiLFxuICAgIHZpc2liaWxpdHk6IFwicHVibGljXCJcbiAgfV1cbn1cblxuLyoqXG4gKiBWYWxpZGF0ZXMgb25lIHB1YmxpYyBmYWNhZGUgY2xhc3MgZGVzY3JpcHRvci5cbiAqIEBwYXJhbSB7UmVjb3JkPHN0cmluZywgdW5rbm93bj59IHZhbHVlIC0gQ2FuZGlkYXRlIGNsYXNzLlxuICogQHBhcmFtIHtzdHJpbmd9IGlkZW50aXR5IC0gT3duaW5nIGZhY2FkZS5cbiAqIEBwYXJhbSB7c3RyaW5nfSBuYW1lIC0gVmFsaWRhdGVkIGNsYXNzIG5hbWUuXG4gKiBAcmV0dXJucyB7U3RkbGliRmFjYWRlQ2xhc3NEZWNsYXJhdGlvbn0gRGV0YWNoZWQgY2xhc3MgZGVzY3JpcHRvci5cbiAqL1xuZnVuY3Rpb24gdmFsaWRhdGVQdWJsaWNDbGFzcyh2YWx1ZSwgaWRlbnRpdHksIG5hbWUpIHtcbiAgcmVxdWlyZUtleXModmFsdWUsIFtcImNvbnN0cnVjdG9yXCIsIFwiZm9ybXNcIiwgXCJraW5kXCIsIFwibWV0aG9kc1wiLCBcIm5hbWVcIiwgXCJvd25lcnNoaXBcIl0sXG4gICAgYGZhY2FkZSAnJHtpZGVudGl0eX0nIHB1YmxpYyBjbGFzc2ApXG4gIGlmICghaXNEZW5zZUFycmF5KHZhbHVlLmZvcm1zKSB8fCB2YWx1ZS5mb3Jtcy5sZW5ndGggIT0gMSB8fCB2YWx1ZS5mb3Jtc1swXSAhPSBcImNvbnN0cnVjdG9yLWNhbGxcIiB8fFxuICAgIHZhbHVlLm93bmVyc2hpcCAhPSBcIm93bmVkLXJlZmVyZW5jZVwiIHx8ICFpc1BsYWluT2JqZWN0KHZhbHVlLmNvbnN0cnVjdG9yKSB8fCAhaXNEZW5zZUFycmF5KHZhbHVlLm1ldGhvZHMpKSB7XG4gICAgaW52YWxpZEZhY2FkZShgRmFjYWRlICcke2lkZW50aXR5fScgY2xhc3MgJyR7bmFtZX0nIGhhcyBhbiBpbnZhbGlkIHB1YmxpYyBjb250cmFjdC5gKVxuICB9XG4gIGNvbnN0IGNvbnN0cnVjdG9yID0gLyoqIEB0eXBlIHtSZWNvcmQ8c3RyaW5nLCB1bmtub3duPn0gKi8gKHZhbHVlLmNvbnN0cnVjdG9yKVxuXG4gIHJlcXVpcmVLZXlzKGNvbnN0cnVjdG9yLCBbXCJlZmZlY3RzXCIsIFwiZmFpbHVyZXNcIiwgXCJvd25lcnNoaXBcIiwgXCJwYXJhbWV0ZXJzXCJdLCBgZmFjYWRlICcke2lkZW50aXR5fScgY29uc3RydWN0b3JgKVxuICBpZiAoY29uc3RydWN0b3Iub3duZXJzaGlwICE9IFwiYWNxdWlyZWRcIiB8fCAhdmFsaWRGYWNhZGVFZmZlY3RzKGNvbnN0cnVjdG9yLmVmZmVjdHMpIHx8XG4gICAgIXZhbGlkRmFjYWRlRmFpbHVyZXMoY29uc3RydWN0b3IuZmFpbHVyZXMpKSBpbnZhbGlkRmFjYWRlKGBGYWNhZGUgJyR7aWRlbnRpdHl9JyBjbGFzcyAnJHtuYW1lfScgaGFzIGFuIGludmFsaWQgY29uc3RydWN0b3IuYClcbiAgY29uc3QgcGFyYW1ldGVycyA9IHZhbGlkYXRlRmFjYWRlUGFyYW1ldGVycyhjb25zdHJ1Y3Rvci5wYXJhbWV0ZXJzLCBpZGVudGl0eSwgYCR7bmFtZX0ubmV3YClcbiAgY29uc3QgbWV0aG9kTmFtZXMgPSBuZXcgU2V0KClcbiAgY29uc3QgbWV0aG9kcyA9IHZhbHVlLm1ldGhvZHMubWFwKChtZXRob2QpID0+IHtcbiAgICBpZiAoIWlzUGxhaW5PYmplY3QobWV0aG9kKSkgaW52YWxpZEZhY2FkZShgRmFjYWRlICcke2lkZW50aXR5fScgY2xhc3MgJyR7bmFtZX0nIGhhcyBhbiBpbnZhbGlkIG1ldGhvZC5gKVxuICAgIHJlcXVpcmVLZXlzKG1ldGhvZCwgW1wiZWZmZWN0c1wiLCBcImZhaWx1cmVzXCIsIFwiZm9ybXNcIiwgXCJuYW1lXCIsIFwib3duZXJzaGlwXCIsIFwicGFyYW1ldGVyc1wiLCBcInJldHVyblR5cGVcIl0sXG4gICAgICBgZmFjYWRlICcke2lkZW50aXR5fScgY2xhc3MgbWV0aG9kYClcbiAgICBjb25zdCBtZXRob2ROYW1lID0gcmVxdWlyZVN0cmluZyhtZXRob2QubmFtZSwgYEZhY2FkZSAnJHtpZGVudGl0eX0nIG1ldGhvZCBuYW1lYClcbiAgICBjb25zdCByZXR1cm5UeXBlID0gcmVxdWlyZVN0cmluZyhtZXRob2QucmV0dXJuVHlwZSwgYEZhY2FkZSAnJHtpZGVudGl0eX0nIG1ldGhvZCByZXR1cm4gdHlwZWApXG5cbiAgICBpZiAoIWRlY2xhcmF0aW9uTmFtZVBhdHRlcm4udGVzdChtZXRob2ROYW1lKSB8fCBtZXRob2ROYW1lcy5oYXMobWV0aG9kTmFtZSkgfHwgIXZhbGlkRmFjYWRlRWZmZWN0cyhtZXRob2QuZWZmZWN0cykgfHxcbiAgICAgICF2YWxpZEZhY2FkZUZhaWx1cmVzKG1ldGhvZC5mYWlsdXJlcykgfHwgIWlzRGVuc2VBcnJheShtZXRob2QuZm9ybXMpIHx8IG1ldGhvZC5mb3Jtcy5sZW5ndGggIT0gMSB8fFxuICAgICAgbWV0aG9kLmZvcm1zWzBdICE9IFwicmVjZWl2ZXItY2FsbFwiIHx8IG1ldGhvZC5vd25lcnNoaXAgIT0gXCJib3Jyb3dlZFwiICYmIG1ldGhvZC5vd25lcnNoaXAgIT0gXCJjb25zdW1lZFwiIHx8XG4gICAgICAhaXNGYWNhZGVUeXBlKHJldHVyblR5cGUsIHRydWUpKSBpbnZhbGlkRmFjYWRlKGBGYWNhZGUgJyR7aWRlbnRpdHl9JyBjbGFzcyAnJHtuYW1lfScgaGFzIGFuIGludmFsaWQgbWV0aG9kLmApXG4gICAgbWV0aG9kTmFtZXMuYWRkKG1ldGhvZE5hbWUpXG4gICAgcmV0dXJuIHtcbiAgICAgIGVmZmVjdHM6IC8qKiBAdHlwZSB7c3RyaW5nW119ICovIChbLi4uLyoqIEB0eXBlIHt1bmtub3duW119ICovIChtZXRob2QuZWZmZWN0cyldKSxcbiAgICAgIGZhaWx1cmVzOiAvKiogQHR5cGUge3N0cmluZ1tdfSAqLyAoWy4uLi8qKiBAdHlwZSB7dW5rbm93bltdfSAqLyAobWV0aG9kLmZhaWx1cmVzKV0pLFxuICAgICAgZm9ybXM6IC8qKiBAdHlwZSB7W1wicmVjZWl2ZXItY2FsbFwiXX0gKi8gKFtcInJlY2VpdmVyLWNhbGxcIl0pLFxuICAgICAgbmFtZTogbWV0aG9kTmFtZSxcbiAgICAgIG93bmVyc2hpcDogLyoqIEB0eXBlIHtcImJvcnJvd2VkXCIgfCBcImNvbnN1bWVkXCJ9ICovIChtZXRob2Qub3duZXJzaGlwKSxcbiAgICAgIHBhcmFtZXRlcnM6IHZhbGlkYXRlRmFjYWRlUGFyYW1ldGVycyhtZXRob2QucGFyYW1ldGVycywgaWRlbnRpdHksIGAke25hbWV9LiR7bWV0aG9kTmFtZX1gKSxcbiAgICAgIHJldHVyblR5cGVcbiAgICB9XG4gIH0pXG5cbiAgcmV0dXJuIHtcbiAgICBjb25zdHJ1Y3Rvcjoge1xuICAgICAgZWZmZWN0czogLyoqIEB0eXBlIHtzdHJpbmdbXX0gKi8gKFsuLi4vKiogQHR5cGUge3Vua25vd25bXX0gKi8gKGNvbnN0cnVjdG9yLmVmZmVjdHMpXSksXG4gICAgICBmYWlsdXJlczogLyoqIEB0eXBlIHtzdHJpbmdbXX0gKi8gKFsuLi4vKiogQHR5cGUge3Vua25vd25bXX0gKi8gKGNvbnN0cnVjdG9yLmZhaWx1cmVzKV0pLFxuICAgICAgb3duZXJzaGlwOiBcImFjcXVpcmVkXCIsXG4gICAgICBwYXJhbWV0ZXJzXG4gICAgfSxcbiAgICBmb3JtczogW1wiY29uc3RydWN0b3ItY2FsbFwiXSxcbiAgICBraW5kOiBcImNsYXNzXCIsXG4gICAgbWV0aG9kcyxcbiAgICBuYW1lLFxuICAgIG93bmVyc2hpcDogXCJvd25lZC1yZWZlcmVuY2VcIlxuICB9XG59XG5cbi8qKlxuICogVmFsaWRhdGVzIGZhY2FkZSBwYXJhbWV0ZXJzIHNoYXJlZCBieSBmdW5jdGlvbnMsIGNvbnN0cnVjdG9ycywgYW5kIG1ldGhvZHMuXG4gKiBAcGFyYW0ge3Vua25vd259IGNhbmRpZGF0ZSAtIENhbmRpZGF0ZSBwYXJhbWV0ZXJzLlxuICogQHBhcmFtIHtzdHJpbmd9IGlkZW50aXR5IC0gT3duaW5nIGZhY2FkZS5cbiAqIEBwYXJhbSB7c3RyaW5nfSBjYWxsYWJsZSAtIENhbGxhYmxlIG5hbWUuXG4gKiBAcmV0dXJucyB7e25hbWU6IHN0cmluZywgdHlwZTogc3RyaW5nfVtdfSBEZXRhY2hlZCBwYXJhbWV0ZXJzLlxuICovXG5mdW5jdGlvbiB2YWxpZGF0ZUZhY2FkZVBhcmFtZXRlcnMoY2FuZGlkYXRlLCBpZGVudGl0eSwgY2FsbGFibGUpIHtcbiAgaWYgKCFpc0RlbnNlQXJyYXkoY2FuZGlkYXRlKSkgaW52YWxpZEZhY2FkZShgRmFjYWRlICcke2lkZW50aXR5fScgZGVjbGFyYXRpb24gJyR7Y2FsbGFibGV9JyBoYXMgaW52YWxpZCBwYXJhbWV0ZXJzLmApXG4gIGNvbnN0IG5hbWVzID0gbmV3IFNldCgpXG5cbiAgcmV0dXJuIGNhbmRpZGF0ZS5tYXAoKHBhcmFtZXRlcikgPT4ge1xuICAgIGlmICghaXNQbGFpbk9iamVjdChwYXJhbWV0ZXIpKSBpbnZhbGlkRmFjYWRlKGBGYWNhZGUgJyR7aWRlbnRpdHl9JyBkZWNsYXJhdGlvbiAnJHtjYWxsYWJsZX0nIGhhcyBhbiBpbnZhbGlkIHBhcmFtZXRlci5gKVxuICAgIHJlcXVpcmVLZXlzKHBhcmFtZXRlciwgW1wibmFtZVwiLCBcInR5cGVcIl0sIGBmYWNhZGUgJyR7aWRlbnRpdHl9JyBkZWNsYXJhdGlvbiBwYXJhbWV0ZXJgKVxuICAgIGNvbnN0IG5hbWUgPSByZXF1aXJlU3RyaW5nKHBhcmFtZXRlci5uYW1lLCBgRmFjYWRlICcke2lkZW50aXR5fScgcGFyYW1ldGVyIG5hbWVgKVxuICAgIGNvbnN0IHR5cGUgPSByZXF1aXJlU3RyaW5nKHBhcmFtZXRlci50eXBlLCBgRmFjYWRlICcke2lkZW50aXR5fScgcGFyYW1ldGVyIHR5cGVgKVxuXG4gICAgaWYgKCFkZWNsYXJhdGlvbk5hbWVQYXR0ZXJuLnRlc3QobmFtZSkgfHwgbmFtZXMuaGFzKG5hbWUpIHx8ICFpc0ZhY2FkZVR5cGUodHlwZSwgZmFsc2UpKSB7XG4gICAgICBpbnZhbGlkRmFjYWRlKGBGYWNhZGUgJyR7aWRlbnRpdHl9JyBkZWNsYXJhdGlvbiAnJHtjYWxsYWJsZX0nIGhhcyBhbiBpbnZhbGlkIHBhcmFtZXRlci5gKVxuICAgIH1cbiAgICBuYW1lcy5hZGQobmFtZSlcbiAgICByZXR1cm4ge25hbWUsIHR5cGV9XG4gIH0pXG59XG5cbi8qKlxuICogQ2hlY2tzIG9uZSBmYWNhZGUgZWZmZWN0IGxpc3QuXG4gKiBAcGFyYW0ge3Vua25vd259IGNhbmRpZGF0ZSAtIENhbmRpZGF0ZSBlZmZlY3RzLlxuICogQHJldHVybnMge2Jvb2xlYW59IFdoZXRoZXIgZWZmZWN0cyBhcmUgZXhhY3QuXG4gKi9cbmZ1bmN0aW9uIHZhbGlkRmFjYWRlRWZmZWN0cyhjYW5kaWRhdGUpIHtcbiAgcmV0dXJuIGlzRGVuc2VBcnJheShjYW5kaWRhdGUpICYmIGNhbmRpZGF0ZS5ldmVyeSgoZWZmZWN0KSA9PiBlZmZlY3QgPT0gXCJob3N0XCIpICYmIG5ldyBTZXQoY2FuZGlkYXRlKS5zaXplID09IGNhbmRpZGF0ZS5sZW5ndGhcbn1cblxuLyoqXG4gKiBDaGVja3Mgb25lIGZhY2FkZSBmYWlsdXJlIGxpc3QuXG4gKiBAcGFyYW0ge3Vua25vd259IGNhbmRpZGF0ZSAtIENhbmRpZGF0ZSBmYWlsdXJlcy5cbiAqIEByZXR1cm5zIHtjYW5kaWRhdGUgaXMgc3RyaW5nW119IFdoZXRoZXIgZmFpbHVyZXMgYXJlIGV4YWN0LlxuICovXG5mdW5jdGlvbiB2YWxpZEZhY2FkZUZhaWx1cmVzKGNhbmRpZGF0ZSkge1xuICByZXR1cm4gaXNEZW5zZUFycmF5KGNhbmRpZGF0ZSkgJiYgY2FuZGlkYXRlLmV2ZXJ5KChmYWlsdXJlKSA9PiB0eXBlb2YgZmFpbHVyZSA9PSBcInN0cmluZ1wiICYmIGRlY2xhcmF0aW9uTmFtZVBhdHRlcm4udGVzdChmYWlsdXJlKSkgJiZcbiAgICBuZXcgU2V0KGNhbmRpZGF0ZSkuc2l6ZSA9PSBjYW5kaWRhdGUubGVuZ3RoXG59XG5cbi8qKlxuICogQ2hlY2tzIG9uZSBmYWNhZGUgdHlwZSBzcGVsbGluZy5cbiAqIEBwYXJhbSB7c3RyaW5nfSB0eXBlIC0gQ2FuZGlkYXRlIHR5cGUuXG4gKiBAcGFyYW0ge2Jvb2xlYW59IGFsbG93Vm9pZCAtIFdoZXRoZXIgdm9pZCBpcyB2YWxpZCBpbiB0aGlzIHBvc2l0aW9uLlxuICogQHJldHVybnMge2Jvb2xlYW59IFdoZXRoZXIgdGhlIHR5cGUgaXMgY2Fub25pY2FsLlxuICovXG5mdW5jdGlvbiBpc0ZhY2FkZVR5cGUodHlwZSwgYWxsb3dWb2lkKSB7XG4gIGlmIChjYW5vbmljYWxUeXBlcy5oYXModHlwZSkpIHJldHVybiBhbGxvd1ZvaWQgfHwgdHlwZSAhPSBcInZvaWRcIlxuICBjb25zdCBvcHRpb25hbCA9IC9eb3B0aW9uYWw6KGJvb2xlYW58aW50ZWdlcnxzdHJpbmcpJC91LmV4ZWModHlwZSlcblxuICByZXR1cm4gb3B0aW9uYWwgIT09IG51bGxcbn1cblxuLyoqXG4gKiBEZXRhY2hlcyBvbmUgZGVzY3JpcHRvciBmb3IgdGhlIHB1YmxpYyBwcm9ncmFtIHJlY29yZC5cbiAqIEBwYXJhbSB7U3RkbGliRmFjYWRlUHVibGljRGVjbGFyYXRpb259IGRlY2xhcmF0aW9uIC0gUmVnaXN0cnkgZGVjbGFyYXRpb24uXG4gKiBAcmV0dXJucyB7U3RkbGliRmFjYWRlUHVibGljRGVjbGFyYXRpb259IERldGFjaGVkIGRlY2xhcmF0aW9uLlxuICovXG5mdW5jdGlvbiBkZXRhY2hQdWJsaWNEZWNsYXJhdGlvbihkZWNsYXJhdGlvbikge1xuICBpZiAoZGVjbGFyYXRpb24ua2luZCA9PSBcImZ1bmN0aW9uXCIpIHJldHVybiB7Li4uZGVjbGFyYXRpb24sIGVmZmVjdHM6IFsuLi5kZWNsYXJhdGlvbi5lZmZlY3RzXSwgZmFpbHVyZXM6IFsuLi5kZWNsYXJhdGlvbi5mYWlsdXJlc10sXG4gICAgZm9ybXM6IFsuLi5kZWNsYXJhdGlvbi5mb3Jtc10sIHBhcmFtZXRlcnM6IGRlY2xhcmF0aW9uLnBhcmFtZXRlcnMubWFwKChwYXJhbWV0ZXIpID0+ICh7Li4ucGFyYW1ldGVyfSkpfVxuICByZXR1cm4gey4uLmRlY2xhcmF0aW9uLFxuICAgIGNvbnN0cnVjdG9yOiB7Li4uZGVjbGFyYXRpb24uY29uc3RydWN0b3IsIGVmZmVjdHM6IFsuLi5kZWNsYXJhdGlvbi5jb25zdHJ1Y3Rvci5lZmZlY3RzXSwgZmFpbHVyZXM6IFsuLi5kZWNsYXJhdGlvbi5jb25zdHJ1Y3Rvci5mYWlsdXJlc10sXG4gICAgICBwYXJhbWV0ZXJzOiBkZWNsYXJhdGlvbi5jb25zdHJ1Y3Rvci5wYXJhbWV0ZXJzLm1hcCgocGFyYW1ldGVyKSA9PiAoey4uLnBhcmFtZXRlcn0pKX0sXG4gICAgZm9ybXM6IFsuLi5kZWNsYXJhdGlvbi5mb3Jtc10sXG4gICAgbWV0aG9kczogZGVjbGFyYXRpb24ubWV0aG9kcy5tYXAoKG1ldGhvZCkgPT4gKHsuLi5tZXRob2QsIGVmZmVjdHM6IFsuLi5tZXRob2QuZWZmZWN0c10sIGZhaWx1cmVzOiBbLi4ubWV0aG9kLmZhaWx1cmVzXSxcbiAgICAgIGZvcm1zOiBbLi4ubWV0aG9kLmZvcm1zXSwgcGFyYW1ldGVyczogbWV0aG9kLnBhcmFtZXRlcnMubWFwKChwYXJhbWV0ZXIpID0+ICh7Li4ucGFyYW1ldGVyfSkpfSkpfVxufVxuXG4vKipcbiAqIERldGFjaGVzIGEgbG9jYWwgb3IgZGVwZW5kZW5jeS1xdWFsaWZpZWQgY29udHJhY3QgcmVmZXJlbmNlLlxuICogQHBhcmFtIHtzdHJpbmcgfCBpbXBvcnQoXCIuL3NlbWFudGljL3N0ZGxpYi5qc1wiKS5DYW5vbmljYWxEZWNsYXJhdGlvblJlZmVyZW5jZX0gcmVmZXJlbmNlIC0gQ29udHJhY3QgcmVmZXJlbmNlLlxuICogQHJldHVybnMge3N0cmluZyB8IGltcG9ydChcIi4vc2VtYW50aWMvdHlwZXMuanNcIikuQ2FwYWJpbGl0eURlY2xhcmF0aW9uUmVmZXJlbmNlSW5wdXR9IERldGFjaGVkIHJlZmVyZW5jZS5cbiAqL1xuZnVuY3Rpb24gZGV0YWNoQ2Fub25pY2FsUmVmZXJlbmNlKHJlZmVyZW5jZSkge1xuICByZXR1cm4gdHlwZW9mIHJlZmVyZW5jZSA9PSBcInN0cmluZ1wiID8gcmVmZXJlbmNlIDoge21vZHVsZTogcmVmZXJlbmNlLm1vZHVsZSwgbmFtZTogcmVmZXJlbmNlLm5hbWV9XG59XG5cbi8qKlxuICogRGV0YWNoZXMgYSBjYW5vbmljYWwgcmVzb3VyY2UgZmxvdyBmb3IgYXV0aG9yaXR5IGNvbnN0cnVjdGlvbi5cbiAqIEBwYXJhbSB7b2JqZWN0fSBmbG93IC0gQ2Fub25pY2FsIHJlc291cmNlIGZsb3cuXG4gKiBAcmV0dXJucyB7aW1wb3J0KFwiLi9zZW1hbnRpYy90eXBlcy5qc1wiKS5DYXBhYmlsaXR5UmVzb3VyY2VGbG93SW5wdXR9IERldGFjaGVkIGZsb3cuXG4gKi9cbmZ1bmN0aW9uIGRldGFjaFJlc291cmNlRmxvdyhmbG93KSB7XG4gIGNvbnN0IGNhbmRpZGF0ZSA9IC8qKiBAdHlwZSB7UmVjb3JkPHN0cmluZywgdW5rbm93bj59ICovIChmbG93KVxuXG4gIGlmIChjYW5kaWRhdGUua2luZCA9PSBcIm5vbmVcIikgcmV0dXJuIHtraW5kOiBcIm5vbmVcIn1cbiAgaWYgKGNhbmRpZGF0ZS5raW5kID09IFwiYWNxdWlyZVwiKSByZXR1cm4ge2tpbmQ6IFwiYWNxdWlyZVwiLCByZXNvdXJjZTogZGV0YWNoQ2Fub25pY2FsUmVmZXJlbmNlKFxuICAgIC8qKiBAdHlwZSB7c3RyaW5nIHwgaW1wb3J0KFwiLi9zZW1hbnRpYy9zdGRsaWIuanNcIikuQ2Fub25pY2FsRGVjbGFyYXRpb25SZWZlcmVuY2V9ICovIChjYW5kaWRhdGUucmVzb3VyY2UpKX1cbiAgcmV0dXJuIHtcbiAgICBraW5kOiAvKiogQHR5cGUge1wiYm9ycm93XCIgfCBcImNsb3NlXCJ9ICovIChjYW5kaWRhdGUua2luZCksXG4gICAgcGFyYW1ldGVySW5kZXg6IC8qKiBAdHlwZSB7bnVtYmVyfSAqLyAoY2FuZGlkYXRlLnBhcmFtZXRlckluZGV4KSxcbiAgICB0ZXJtaW5hbEZhaWx1cmU6IGRldGFjaENhbm9uaWNhbFJlZmVyZW5jZShcbiAgICAgIC8qKiBAdHlwZSB7c3RyaW5nIHwgaW1wb3J0KFwiLi9zZW1hbnRpYy9zdGRsaWIuanNcIikuQ2Fub25pY2FsRGVjbGFyYXRpb25SZWZlcmVuY2V9ICovIChjYW5kaWRhdGUudGVybWluYWxGYWlsdXJlKSlcbiAgfVxufVxuXG4vKipcbiAqIE1hcHMgb25lIGNhbm9uaWNhbCBtb2R1bGUgaWRlbnRpdHkgdG8gaXRzIGNsb3NlZCBjYXBhYmlsaXR5IG5hbWUuXG4gKiBAcGFyYW0ge3N0cmluZ30gaWRlbnRpdHkgLSBDYW5vbmljYWwgaWRlbnRpdHkuXG4gKiBAcmV0dXJucyB7c3RyaW5nfSBDYXBhYmlsaXR5IG5hbWUuXG4gKi9cbmZ1bmN0aW9uIGNhbm9uaWNhbENhcGFiaWxpdHlOYW1lKGlkZW50aXR5KSB7XG4gIC8qKiBAdHlwZSB7UmVhZG9ubHk8UmVjb3JkPHN0cmluZywgc3RyaW5nPj59ICovXG4gIGNvbnN0IG5hbWVzID0ge1xuICAgIFwic2VtYW50aWZvbGQub3V0cHV0XCI6IFwiT3V0cHV0XCIsXG4gICAgXCJzZW1hbnRpZm9sZC5yZXNvdXJjZVwiOiBcIlJlc291cmNlXCIsXG4gICAgXCJzZW1hbnRpZm9sZC5zb2NrZXQtY2xpZW50XCI6IFwiU29ja2V0Q2xpZW50XCIsXG4gICAgXCJzZW1hbnRpZm9sZC50YXNrMDM0LnJlc291cmNlLXByb2JlXCI6IFwiUmVzb3VyY2VQcm9iZVwiLFxuICAgIFwic2VtYW50aWZvbGQudGV4dC1zdHJlYW1cIjogXCJUZXh0U3RyZWFtXCJcbiAgfVxuXG4gIHJldHVybiBuYW1lc1tpZGVudGl0eV0gPz8gaW52YWxpZEZhY2FkZShgRmFjYWRlIHJlcXVpcmVtZW50cyBuYW1lIHVua25vd24gY2Fub25pY2FsIG1vZHVsZSAnJHtpZGVudGl0eX0nLmApXG59XG5cbi8qKlxuICogQnVpbGRzIGV4ZWN1dGFibGUgc291cmNlIGFuZCBuYXRpdmUgaWRlbnRpdHkgc3BlbGxpbmdzIGZvciBvbmUgb3JpZ2luYWwtZml2ZSBsYW5ndWFnZS5cbiAqIEBwYXJhbSB7c3RyaW5nfSBsYW5ndWFnZSAtIFNvdXJjZSBsYW5ndWFnZS5cbiAqIEByZXR1cm5zIHtGYWNhZGVTb3VyY2VOYW1lc30gRmFjYWRlIHNvdXJjZSBkZWZpbml0aW9ucy5cbiAqL1xuZnVuY3Rpb24gZmFjYWRlTmFtZXMobGFuZ3VhZ2UpIHtcbiAgaWYgKGxhbmd1YWdlID09IFwicGhwXCIpIHJldHVybiB7XG4gICAgZXh0ZW5zaW9uOiBcInBocFwiLCBuYXRpdmVNb2R1bGU6IFwiU2VtYW50aWZvbGRcXFxcVGFzazAzNlxcXFxQcm9iZVwiLCBwdWJsaWNOYW1lOiBcImNvbXBhdGliaWxpdHlfcHJvYmVcIixcbiAgICB1bnVzZWROYW1lOiBcInVudXNlZF9wcm9iZVwiLCB1bnVzZWROYXRpdmVNb2R1bGU6IFwiU2VtYW50aWZvbGRcXFxcVGFzazAzNlxcXFxVbnVzZWRcIixcbiAgICBwcm9iZVNvdXJjZTogYDw/cGhwXG5kZWNsYXJlKHN0cmljdF90eXBlcz0xKTtcbm5hbWVzcGFjZSBTZW1hbnRpZm9sZFxcXFxGYWNhZGVcXFxcUGhwXFxcXFByb2JlO1xudXNlIGZ1bmN0aW9uIFNlbWFudGlmb2xkXFxcXEZhY2FkZVxcXFxQaHBcXFxcUHJvYmVSdW5uZXJcXFxccnVuX2NvbXBhdGliaWxpdHlfcHJvYmU7XG5yZXF1aXJlX29uY2UgX19ESVJfXyAuIFwiL3Byb2JlLXJ1bm5lci5waHBcIjtcbmZ1bmN0aW9uIGNvbXBhdGliaWxpdHlfcHJvYmUoc3RyaW5nICRsYWJlbCk6IHN0cmluZyB7IHJldHVybiBydW5fY29tcGF0aWJpbGl0eV9wcm9iZSgkbGFiZWwpOyB9XG5gLFxuICAgIHJ1bm5lclNvdXJjZTogYDw/cGhwXG5kZWNsYXJlKHN0cmljdF90eXBlcz0xKTtcbm5hbWVzcGFjZSBTZW1hbnRpZm9sZFxcXFxGYWNhZGVcXFxcUGhwXFxcXFByb2JlUnVubmVyO1xuZnVuY3Rpb24gcnVuX2NvbXBhdGliaWxpdHlfcHJvYmUoc3RyaW5nICRsYWJlbCk6IHN0cmluZyB7XG4gICAgdHJ5IHtcbiAgICAgICAgLyoqXG4gICAgICAgICAqIEB2YXIgaW50ICRlZmZlY3RcbiAgICAgICAgICogQHNlbWFudGlmb2xkLWltbXV0YWJsZVxuICAgICAgICAgKi9cbiAgICAgICAgJGVmZmVjdCA9IHByb2JlRWZmZWN0KCRsYWJlbCwgMSwgZmFsc2UpO1xuICAgICAgICByZXR1cm4gcHJvYmVUcmFjZSgpO1xuICAgIH1cbiAgICBjYXRjaCAoUHJvYmVPcGVyYXRpb25GYWlsdXJlICRlcnJvcikgeyByZXR1cm4gJGVycm9yLT5nZXRNZXNzYWdlKCk7IH1cbn1cbmAsXG4gICAgdW51c2VkU291cmNlOiBgPD9waHBcbmRlY2xhcmUoc3RyaWN0X3R5cGVzPTEpO1xubmFtZXNwYWNlIFNlbWFudGlmb2xkXFxcXEZhY2FkZVxcXFxQaHBcXFxcVW51c2VkO1xuZnVuY3Rpb24gdW51c2VkX3Byb2JlKHN0cmluZyAkbGFiZWwpOiBzdHJpbmcgeyByZXR1cm4gcHJvYmVUcmFjZSgpOyB9XG5gXG4gIH1cbiAgaWYgKGxhbmd1YWdlID09IFwicnVieVwiKSByZXR1cm4ge1xuICAgIGV4dGVuc2lvbjogXCJyYlwiLCBuYXRpdmVNb2R1bGU6IFwic2VtYW50aWZvbGQvdGFzazAzNi9wcm9iZVwiLCBwdWJsaWNOYW1lOiBcImNvbXBhdGliaWxpdHlfcHJvYmVcIixcbiAgICB1bnVzZWROYW1lOiBcInVudXNlZF9wcm9iZVwiLCB1bnVzZWROYXRpdmVNb2R1bGU6IFwic2VtYW50aWZvbGQvdGFzazAzNi91bnVzZWRcIixcbiAgICBwcm9iZVNvdXJjZTogYHJlcXVpcmVfcmVsYXRpdmUgXCJwcm9iZS1ydW5uZXJcIlxubW9kdWxlIFNlbWFudGlmb2xkVGFzazAzNlByb2JlXG4gIG1vZHVsZV9mdW5jdGlvblxuICAjIEBwYXJhbSBsYWJlbCBbU3RyaW5nXVxuICAjIEByZXR1cm4gW1N0cmluZ11cbiAgZGVmIGNvbXBhdGliaWxpdHlfcHJvYmUobGFiZWwpXG4gICAgcmV0dXJuIFNlbWFudGlmb2xkVGFzazAzNlByb2JlUnVubmVyLnJ1bl9jb21wYXRpYmlsaXR5X3Byb2JlKGxhYmVsKVxuICBlbmRcbmVuZFxuYCxcbiAgICBydW5uZXJTb3VyY2U6IGBtb2R1bGUgU2VtYW50aWZvbGRUYXNrMDM2UHJvYmVSdW5uZXJcbiAgbW9kdWxlX2Z1bmN0aW9uXG4gICMgQHBhcmFtIGxhYmVsIFtTdHJpbmddXG4gICMgQHJldHVybiBbU3RyaW5nXVxuICBkZWYgcnVuX2NvbXBhdGliaWxpdHlfcHJvYmUobGFiZWwpXG4gICAgYmVnaW5cbiAgICAgICMgQHR5cGUgW0ludGVnZXJdXG4gICAgICAjIEBzZW1hbnRpZm9sZC1pbW11dGFibGVcbiAgICAgIGVmZmVjdCA9IHByb2JlRWZmZWN0KGxhYmVsLCAxLCBmYWxzZSlcbiAgICAgIHJldHVybiBwcm9iZVRyYWNlXG4gICAgcmVzY3VlIFByb2JlT3BlcmF0aW9uRmFpbHVyZSA9PiBlcnJvclxuICAgICAgcmV0dXJuIGVycm9yLm1lc3NhZ2VcbiAgICBlbmRcbiAgZW5kXG5lbmRcbmAsXG4gICAgdW51c2VkU291cmNlOiBgbW9kdWxlIFNlbWFudGlmb2xkVGFzazAzNlVudXNlZFxuICBtb2R1bGVfZnVuY3Rpb25cbiAgIyBAcGFyYW0gbGFiZWwgW1N0cmluZ11cbiAgIyBAcmV0dXJuIFtTdHJpbmddXG4gIGRlZiB1bnVzZWRfcHJvYmUobGFiZWwpXG4gICAgcmV0dXJuIHByb2JlVHJhY2VcbiAgZW5kXG5lbmRcbmBcbiAgfVxuICBpZiAobGFuZ3VhZ2UgPT0gXCJqYXZhXCIpIHJldHVybiB7XG4gICAgZXh0ZW5zaW9uOiBcImphdmFcIiwgbmF0aXZlTW9kdWxlOiBcInNlbWFudGlmb2xkLnRhc2swMzYuUHJvYmVcIiwgcHVibGljTmFtZTogXCJjb21wYXRpYmlsaXR5UHJvYmVcIixcbiAgICB1bnVzZWROYW1lOiBcInVudXNlZFByb2JlXCIsIHVudXNlZE5hdGl2ZU1vZHVsZTogXCJzZW1hbnRpZm9sZC50YXNrMDM2LlVudXNlZFwiLFxuICAgIHByb2JlU291cmNlOiBgcGFja2FnZSBzZW1hbnRpZm9sZC5mYWNhZGUuamF2YS5wcm9iZTtcbmltcG9ydCBzZW1hbnRpZm9sZC5mYWNhZGUuamF2YS5wcm9iZXJ1bm5lci5Qcm9iZVJ1bm5lcjtcbnB1YmxpYyBmaW5hbCBjbGFzcyBQcm9iZSB7XG4gIHB1YmxpYyBzdGF0aWMgU3RyaW5nIGNvbXBhdGliaWxpdHlQcm9iZShTdHJpbmcgbGFiZWwpIHsgcmV0dXJuIFByb2JlUnVubmVyLnJ1bkNvbXBhdGliaWxpdHlQcm9iZShsYWJlbCk7IH1cbn1cbmAsXG4gICAgcnVubmVyU291cmNlOiBgcGFja2FnZSBzZW1hbnRpZm9sZC5mYWNhZGUuamF2YS5wcm9iZXJ1bm5lcjtcbnB1YmxpYyBmaW5hbCBjbGFzcyBQcm9iZVJ1bm5lciB7XG4gIHB1YmxpYyBzdGF0aWMgU3RyaW5nIHJ1bkNvbXBhdGliaWxpdHlQcm9iZShTdHJpbmcgbGFiZWwpIHtcbiAgICB0cnkgeyBmaW5hbCBpbnQgZWZmZWN0ID0gcHJvYmVFZmZlY3QobGFiZWwsIDEsIGZhbHNlKTsgcmV0dXJuIHByb2JlVHJhY2UoKTsgfVxuICAgIGNhdGNoIChQcm9iZU9wZXJhdGlvbkZhaWx1cmUgZXJyb3IpIHsgcmV0dXJuIGVycm9yLmdldE1lc3NhZ2UoKTsgfVxuICB9XG59XG5gLFxuICAgIHVudXNlZFNvdXJjZTogYHBhY2thZ2Ugc2VtYW50aWZvbGQuZmFjYWRlLmphdmEudW51c2VkO1xucHVibGljIGZpbmFsIGNsYXNzIFVudXNlZCB7XG4gIHB1YmxpYyBzdGF0aWMgU3RyaW5nIHVudXNlZFByb2JlKFN0cmluZyBsYWJlbCkgeyByZXR1cm4gcHJvYmVUcmFjZSgpOyB9XG59XG5gXG4gIH1cbiAgY29uc3QgdHlwZWQgPSBsYW5ndWFnZSA9PSBcInR5cGVzY3JpcHRcIlxuICBjb25zdCBleHRlbnNpb24gPSB0eXBlZCA/IFwidHNcIiA6IFwianNcIlxuICBjb25zdCBwYXJhbWV0ZXIgPSB0eXBlZCA/IFwibGFiZWw6IHN0cmluZ1wiIDogXCJsYWJlbFwiXG4gIGNvbnN0IHJlc3VsdCA9IHR5cGVkID8gXCI6IHN0cmluZ1wiIDogXCJcIlxuICBjb25zdCBkb2N1bWVudGF0aW9uID0gdHlwZWQgPyBcIlwiIDogYC8qKlxuICogQHBhcmFtIHtzdHJpbmd9IGxhYmVsXG4gKiBAcmV0dXJucyB7c3RyaW5nfVxuICovXG5gXG5cbiAgcmV0dXJuIHtcbiAgICBleHRlbnNpb24sIG5hdGl2ZU1vZHVsZTogXCJzZW1hbnRpZm9sZDp0YXNrMDM2L3Byb2JlXCIsIHB1YmxpY05hbWU6IFwiY29tcGF0aWJpbGl0eVByb2JlXCIsXG4gICAgdW51c2VkTmFtZTogXCJ1bnVzZWRQcm9iZVwiLCB1bnVzZWROYXRpdmVNb2R1bGU6IFwic2VtYW50aWZvbGQ6dGFzazAzNi91bnVzZWRcIixcbiAgICBwcm9iZVNvdXJjZTogYGltcG9ydCB7cnVuQ29tcGF0aWJpbGl0eVByb2JlfSBmcm9tIFwiLi9wcm9iZS1ydW5uZXIuanNcIlxuJHtkb2N1bWVudGF0aW9ufWV4cG9ydCBmdW5jdGlvbiBjb21wYXRpYmlsaXR5UHJvYmUoJHtwYXJhbWV0ZXJ9KSR7cmVzdWx0fSB7IHJldHVybiBydW5Db21wYXRpYmlsaXR5UHJvYmUobGFiZWwpIH1cbmAsXG4gICAgcnVubmVyU291cmNlOiBgJHtkb2N1bWVudGF0aW9ufWV4cG9ydCBmdW5jdGlvbiBydW5Db21wYXRpYmlsaXR5UHJvYmUoJHtwYXJhbWV0ZXJ9KSR7cmVzdWx0fSB7XG4gIHRyeSB7ICR7dHlwZWQgPyBcImNvbnN0IGVmZmVjdDogbnVtYmVyXCIgOiBcIi8qKiBAdHlwZSB7bnVtYmVyfSAqLyBjb25zdCBlZmZlY3RcIn0gPSBwcm9iZUVmZmVjdChsYWJlbCwgMSwgZmFsc2UpOyByZXR1cm4gcHJvYmVUcmFjZSgpIH1cbiAgY2F0Y2ggKGVycm9yKSB7IGlmICghKGVycm9yIGluc3RhbmNlb2YgUHJvYmVPcGVyYXRpb25GYWlsdXJlKSkgeyB0aHJvdyBlcnJvciB9IHJldHVybiBlcnJvci5tZXNzYWdlIH1cbn1cbmAsXG4gICAgdW51c2VkU291cmNlOiBgJHtkb2N1bWVudGF0aW9ufWV4cG9ydCBmdW5jdGlvbiB1bnVzZWRQcm9iZSgke3BhcmFtZXRlcn0pJHtyZXN1bHR9IHsgcmV0dXJuIHByb2JlVHJhY2UoKSB9XG5gXG4gIH1cbn1cblxuLyoqXG4gKiBSZXF1aXJlcyBhIGNsb3NlZCBleGFjdCBrZXkgc2V0LlxuICogQHBhcmFtIHtSZWNvcmQ8c3RyaW5nLCB1bmtub3duPn0gdmFsdWUgLSBQbGFpbiBjYW5kaWRhdGUgb2JqZWN0LlxuICogQHBhcmFtIHtzdHJpbmdbXX0ga2V5cyAtIEV4cGVjdGVkIGtleXMuXG4gKiBAcGFyYW0ge3N0cmluZ30gc3ViamVjdCAtIERpYWdub3N0aWMgc3ViamVjdC5cbiAqIEByZXR1cm5zIHt2b2lkfVxuICovXG5mdW5jdGlvbiByZXF1aXJlS2V5cyh2YWx1ZSwga2V5cywgc3ViamVjdCkge1xuICBpZiAoT2JqZWN0LmtleXModmFsdWUpLnNvcnQoKS5qb2luKFwiLFwiKSAhPSBbLi4ua2V5c10uc29ydCgpLmpvaW4oXCIsXCIpKSBpbnZhbGlkRmFjYWRlKGBJbnZhbGlkICR7c3ViamVjdH0gZmllbGRzLmApXG59XG5cbi8qKlxuICogUmVxdWlyZXMgb25lIG5vbi1lbXB0eSBzdHJpbmcuXG4gKiBAcGFyYW0ge3Vua25vd259IHZhbHVlIC0gQ2FuZGlkYXRlIHZhbHVlLlxuICogQHBhcmFtIHtzdHJpbmd9IHN1YmplY3QgLSBEaWFnbm9zdGljIHN1YmplY3QuXG4gKiBAcmV0dXJucyB7c3RyaW5nfSBWYWxpZGF0ZWQgc3RyaW5nLlxuICovXG5mdW5jdGlvbiByZXF1aXJlU3RyaW5nKHZhbHVlLCBzdWJqZWN0KSB7XG4gIGlmICh0eXBlb2YgdmFsdWUgIT0gXCJzdHJpbmdcIiB8fCB2YWx1ZS5sZW5ndGggPT0gMCkgaW52YWxpZEZhY2FkZShgJHtzdWJqZWN0fSBtdXN0IGJlIGEgbm9uLWVtcHR5IHN0cmluZy5gKVxuICByZXR1cm4gLyoqIEB0eXBlIHtzdHJpbmd9ICovICh2YWx1ZSlcbn1cblxuLyoqXG4gKiBDaGVja3MgZm9yIGFuIG9yZGluYXJ5IG9iamVjdCB3aXRoIG5vIGN1c3RvbSBwcm90b3R5cGUuXG4gKiBAcGFyYW0ge3Vua25vd259IHZhbHVlIC0gQ2FuZGlkYXRlIHZhbHVlLlxuICogQHJldHVybnMge3ZhbHVlIGlzIFJlY29yZDxzdHJpbmcsIHVua25vd24+fSBXaGV0aGVyIHRoZSBjYW5kaWRhdGUgaXMgcGxhaW4uXG4gKi9cbmZ1bmN0aW9uIGlzUGxhaW5PYmplY3QodmFsdWUpIHtcbiAgcmV0dXJuIHZhbHVlICE9PSBudWxsICYmIHR5cGVvZiB2YWx1ZSA9PSBcIm9iamVjdFwiICYmICFBcnJheS5pc0FycmF5KHZhbHVlKSAmJiBPYmplY3QuZ2V0UHJvdG90eXBlT2YodmFsdWUpID09IE9iamVjdC5wcm90b3R5cGVcbn1cblxuLyoqXG4gKiBSZWN1cnNpdmVseSBmcmVlemVzIG9uZSBkZXRhY2hlZCBmYWNhZGUgcmVnaXN0cnkgdmFsdWUuXG4gKiBAdGVtcGxhdGUge29iamVjdH0gVFxuICogQHBhcmFtIHtUfSB2YWx1ZSAtIERldGFjaGVkIG9iamVjdC5cbiAqIEByZXR1cm5zIHtSZWFkb25seTxUPn0gRnJvemVuIHZhbHVlLlxuICovXG5mdW5jdGlvbiBkZWVwRnJlZXplKHZhbHVlKSB7XG4gIGZvciAoY29uc3QgY2hpbGQgb2YgT2JqZWN0LnZhbHVlcyh2YWx1ZSkpIGlmIChjaGlsZCAmJiB0eXBlb2YgY2hpbGQgPT0gXCJvYmplY3RcIiAmJiAhT2JqZWN0LmlzRnJvemVuKGNoaWxkKSkgZGVlcEZyZWV6ZShjaGlsZClcbiAgcmV0dXJuIE9iamVjdC5mcmVlemUodmFsdWUpXG59XG5cbi8qKlxuICogVGhyb3dzIGEgc3RhYmxlIGludmFsaWQtcmVnaXN0cnkgZGlhZ25vc3RpYy5cbiAqIEBwYXJhbSB7c3RyaW5nfSBtZXNzYWdlIC0gRmFpbHVyZSBkZXRhaWwuXG4gKiBAcmV0dXJucyB7bmV2ZXJ9IEFsd2F5cyB0aHJvd3MuXG4gKi9cbmZ1bmN0aW9uIGludmFsaWRGYWNhZGUobWVzc2FnZSkge1xuICB0aHJvdyBuZXcgU2VtYW50aWZvbGREaWFnbm9zdGljKHtjb2RlOiBcIlNURExJQl9GQUNBREVfSU5WQUxJRFwiLCBsYW5ndWFnZTogXCJzdGRsaWJcIiwgbWVzc2FnZX0pXG59XG5cbi8qKlxuICogVGhyb3dzIHdoZW4gcGFyc2VyIGV2aWRlbmNlIGRvZXMgbm90IG5hbWUgYSByZWdpc3RlcmVkIG5hdGl2ZSBtb2R1bGUuXG4gKiBAcGFyYW0ge3N0cmluZ30gbGFuZ3VhZ2UgLSBTb3VyY2UgbGFuZ3VhZ2UuXG4gKiBAcGFyYW0ge3Vua25vd259IG5hdGl2ZU1vZHVsZSAtIFVucHJvdmVkIG1vZHVsZSBpZGVudGl0eS5cbiAqIEByZXR1cm5zIHtuZXZlcn0gQWx3YXlzIHRocm93cy5cbiAqL1xuZnVuY3Rpb24gdW5wcm92ZWRJZGVudGl0eShsYW5ndWFnZSwgbmF0aXZlTW9kdWxlKSB7XG4gIHRocm93IG5ldyBTZW1hbnRpZm9sZERpYWdub3N0aWMoe1xuICAgIGNvZGU6IFwiU1RETElCX0ZBQ0FERV9JREVOVElUWV9VTlBST1ZFRFwiLFxuICAgIGxhbmd1YWdlOiBzdXBwb3J0ZWRMYW5ndWFnZXMuaGFzKGxhbmd1YWdlKSA/IGxhbmd1YWdlIDogXCJzdGRsaWJcIixcbiAgICBtZXNzYWdlOiBgTmF0aXZlIHN0YW5kYXJkLWxpYnJhcnkgbW9kdWxlICcke1N0cmluZyhuYXRpdmVNb2R1bGUpfScgaXMgbm90IGEgcmVnaXN0ZXJlZCAnJHtsYW5ndWFnZX0nIGZhY2FkZSBpZGVudGl0eS5gXG4gIH0pXG59XG5cbi8qKlxuICogVGhyb3dzIHdoZW4gYSBuYXRpdmUgbW9kdWxlIG1lbWJlciBpcyBvdXRzaWRlIGl0cyBwdWJsaWMgZmFjYWRlIHN1cmZhY2UuXG4gKiBAcGFyYW0ge3N0cmluZ30gbGFuZ3VhZ2UgLSBTb3VyY2UgbGFuZ3VhZ2UuXG4gKiBAcGFyYW0ge3N0cmluZ30gbmF0aXZlTW9kdWxlIC0gRXhhY3QgbmF0aXZlIG1vZHVsZS5cbiAqIEBwYXJhbSB7c3RyaW5nfSBzeW1ib2wgLSBVbnN1cHBvcnRlZCBtZW1iZXIuXG4gKiBAcmV0dXJucyB7bmV2ZXJ9IEFsd2F5cyB0aHJvd3MuXG4gKi9cbmZ1bmN0aW9uIHVuc3VwcG9ydGVkTWVtYmVyKGxhbmd1YWdlLCBuYXRpdmVNb2R1bGUsIHN5bWJvbCkge1xuICB0aHJvdyBuZXcgU2VtYW50aWZvbGREaWFnbm9zdGljKHtcbiAgICBjb2RlOiBcIlNURExJQl9GQUNBREVfTUVNQkVSX1VOU1VQUE9SVEVEXCIsXG4gICAgbGFuZ3VhZ2UsXG4gICAgbWVzc2FnZTogYE5hdGl2ZSBzdGFuZGFyZC1saWJyYXJ5IHN5bWJvbCAnJHtuYXRpdmVNb2R1bGV9IyR7c3ltYm9sfScgaXMgb3V0c2lkZSB0aGUgcmVnaXN0ZXJlZCBmYWNhZGUgc3VyZmFjZS5gXG4gIH0pXG59XG5cbi8qKlxuICogVGhyb3dzIGZvciBhIG1hbGZvcm1lZCBmYWNhZGUgdmVyc2lvbiByYW5nZS5cbiAqIEBwYXJhbSB7c3RyaW5nfSBsYW5ndWFnZSAtIFNvdXJjZSBsYW5ndWFnZS5cbiAqIEBwYXJhbSB7c3RyaW5nfSByYW5nZSAtIE1hbGZvcm1lZCByYW5nZS5cbiAqIEByZXR1cm5zIHtuZXZlcn0gQWx3YXlzIHRocm93cy5cbiAqL1xuZnVuY3Rpb24gZmFjYWRlVmVyc2lvbk1hbGZvcm1lZChsYW5ndWFnZSwgcmFuZ2UpIHtcbiAgdGhyb3cgbmV3IFNlbWFudGlmb2xkRGlhZ25vc3RpYyh7XG4gICAgY29kZTogXCJTVERMSUJfRkFDQURFX1ZFUlNJT05fTUFMRk9STUVEXCIsIGxhbmd1YWdlLFxuICAgIG1lc3NhZ2U6IGBGYWNhZGUgdmVyc2lvbiByYW5nZSAnJHtyYW5nZX0nIGlzIG5vdCBjYW5vbmljYWwuYFxuICB9KVxufVxuXG4vKipcbiAqIFRocm93cyB3aGVuIG5vIHJlZ2lzdGVyZWQgZmFjYWRlIHZlcnNpb24gc2F0aXNmaWVzIGEgcmFuZ2UuXG4gKiBAcGFyYW0ge3N0cmluZ30gbGFuZ3VhZ2UgLSBTb3VyY2UgbGFuZ3VhZ2UuXG4gKiBAcGFyYW0ge3N0cmluZ30gaWRlbnRpdHkgLSBGYWNhZGUgaWRlbnRpdHkuXG4gKiBAcmV0dXJucyB7bmV2ZXJ9IEFsd2F5cyB0aHJvd3MuXG4gKi9cbmZ1bmN0aW9uIGZhY2FkZVZlcnNpb25JbmNvbXBhdGlibGUobGFuZ3VhZ2UsIGlkZW50aXR5KSB7XG4gIHRocm93IG5ldyBTZW1hbnRpZm9sZERpYWdub3N0aWMoe1xuICAgIGNvZGU6IFwiU1RETElCX0ZBQ0FERV9WRVJTSU9OX0lOQ09NUEFUSUJMRVwiLCBsYW5ndWFnZSxcbiAgICBtZXNzYWdlOiBgTm8gcmVnaXN0ZXJlZCB2ZXJzaW9uIG9mIGZhY2FkZSAnJHtpZGVudGl0eX0nIHNhdGlzZmllcyB0aGUgcmVxdWlyZWQgY29tcGF0aWJpbGl0eSByYW5nZS5gXG4gIH0pXG59XG5cbmV4cG9ydCBjb25zdCBzdGRsaWJGYWNhZGVSZWdpc3RyeSA9IGNyZWF0ZVN0ZGxpYkZhY2FkZVJlZ2lzdHJ5KClcbiJdfQ==