semantifold 0.3.0 → 0.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (297) hide show
  1. package/README.md +58 -15
  2. package/build/index.d.ts +48 -2
  3. package/build/index.d.ts.map +1 -1
  4. package/build/index.js +57 -8
  5. package/build/src/artifact-path.d.ts +23 -1
  6. package/build/src/artifact-path.d.ts.map +1 -1
  7. package/build/src/artifact-path.js +45 -3
  8. package/build/src/artifacts.d.ts.map +1 -1
  9. package/build/src/artifacts.js +66 -1
  10. package/build/src/backends/c-validation.d.ts.map +1 -1
  11. package/build/src/backends/c-validation.js +7 -3
  12. package/build/src/backends/cpp-validation.d.ts.map +1 -1
  13. package/build/src/backends/cpp-validation.js +7 -3
  14. package/build/src/backends/csharp.js +7 -1
  15. package/build/src/backends/dart-runtime.d.ts +2 -0
  16. package/build/src/backends/dart-runtime.d.ts.map +1 -0
  17. package/build/src/backends/dart-runtime.js +41 -0
  18. package/build/src/backends/dart.d.ts +20 -0
  19. package/build/src/backends/dart.d.ts.map +1 -0
  20. package/build/src/backends/dart.js +321 -0
  21. package/build/src/backends/effects.d.ts +60 -0
  22. package/build/src/backends/effects.d.ts.map +1 -0
  23. package/build/src/backends/effects.js +746 -0
  24. package/build/src/backends/go.js +18 -4
  25. package/build/src/backends/identifiers.d.ts +36 -4
  26. package/build/src/backends/identifiers.d.ts.map +1 -1
  27. package/build/src/backends/identifiers.js +154 -10
  28. package/build/src/backends/index.d.ts.map +1 -1
  29. package/build/src/backends/index.js +27 -4
  30. package/build/src/backends/ios.d.ts +68 -0
  31. package/build/src/backends/ios.d.ts.map +1 -0
  32. package/build/src/backends/ios.js +1503 -0
  33. package/build/src/backends/java.d.ts.map +1 -1
  34. package/build/src/backends/java.js +429 -36
  35. package/build/src/backends/javascript.d.ts +6 -0
  36. package/build/src/backends/javascript.d.ts.map +1 -1
  37. package/build/src/backends/javascript.js +380 -24
  38. package/build/src/backends/kotlin-runtime.d.ts +3 -0
  39. package/build/src/backends/kotlin-runtime.d.ts.map +1 -0
  40. package/build/src/backends/kotlin-runtime.js +29 -0
  41. package/build/src/backends/kotlin.d.ts +23 -0
  42. package/build/src/backends/kotlin.d.ts.map +1 -0
  43. package/build/src/backends/kotlin.js +136 -0
  44. package/build/src/backends/native-validation.d.ts +2 -2
  45. package/build/src/backends/native-validation.d.ts.map +1 -1
  46. package/build/src/backends/native-validation.js +2 -2
  47. package/build/src/backends/ordered-expressions.d.ts.map +1 -1
  48. package/build/src/backends/ordered-expressions.js +39 -7
  49. package/build/src/backends/php-stdlib-support.d.ts +19 -0
  50. package/build/src/backends/php-stdlib-support.d.ts.map +1 -0
  51. package/build/src/backends/php-stdlib-support.js +227 -0
  52. package/build/src/backends/php.d.ts.map +1 -1
  53. package/build/src/backends/php.js +448 -33
  54. package/build/src/backends/program.d.ts +81 -0
  55. package/build/src/backends/program.d.ts.map +1 -0
  56. package/build/src/backends/program.js +1308 -0
  57. package/build/src/backends/python.js +7 -1
  58. package/build/src/backends/ruby.d.ts.map +1 -1
  59. package/build/src/backends/ruby.js +310 -24
  60. package/build/src/backends/rust-runtime.d.ts +7 -0
  61. package/build/src/backends/rust-runtime.d.ts.map +1 -0
  62. package/build/src/backends/rust-runtime.js +32 -0
  63. package/build/src/backends/rust-validation.d.ts +9 -0
  64. package/build/src/backends/rust-validation.d.ts.map +1 -0
  65. package/build/src/backends/rust-validation.js +78 -0
  66. package/build/src/backends/rust.d.ts +24 -0
  67. package/build/src/backends/rust.d.ts.map +1 -0
  68. package/build/src/backends/rust.js +344 -0
  69. package/build/src/backends/scalars.d.ts +14 -6
  70. package/build/src/backends/scalars.d.ts.map +1 -1
  71. package/build/src/backends/scalars.js +167 -17
  72. package/build/src/backends/shared.d.ts +23 -4
  73. package/build/src/backends/shared.d.ts.map +1 -1
  74. package/build/src/backends/shared.js +2158 -62
  75. package/build/src/backends/stdlib-support.d.ts +14 -0
  76. package/build/src/backends/stdlib-support.d.ts.map +1 -0
  77. package/build/src/backends/stdlib-support.js +237 -0
  78. package/build/src/backends/swift-runtime.d.ts +3 -0
  79. package/build/src/backends/swift-runtime.d.ts.map +1 -0
  80. package/build/src/backends/swift-runtime.js +14 -0
  81. package/build/src/backends/swift.d.ts +8 -0
  82. package/build/src/backends/swift.d.ts.map +1 -0
  83. package/build/src/backends/swift.js +127 -0
  84. package/build/src/backends/typescript.d.ts.map +1 -1
  85. package/build/src/backends/typescript.js +344 -24
  86. package/build/src/backends/wasm.d.ts +43 -0
  87. package/build/src/backends/wasm.d.ts.map +1 -0
  88. package/build/src/backends/wasm.js +2164 -0
  89. package/build/src/backends/writer.d.ts +235 -4
  90. package/build/src/backends/writer.d.ts.map +1 -1
  91. package/build/src/backends/writer.js +468 -3
  92. package/build/src/diagnostic.d.ts +4 -3
  93. package/build/src/diagnostic.d.ts.map +1 -1
  94. package/build/src/diagnostic.js +5 -3
  95. package/build/src/frontends/c.d.ts.map +1 -1
  96. package/build/src/frontends/c.js +5 -3
  97. package/build/src/frontends/cpp.d.ts.map +1 -1
  98. package/build/src/frontends/cpp.js +5 -3
  99. package/build/src/frontends/csharp.d.ts.map +1 -1
  100. package/build/src/frontends/csharp.js +7 -3
  101. package/build/src/frontends/dart.d.ts +10 -0
  102. package/build/src/frontends/dart.d.ts.map +1 -0
  103. package/build/src/frontends/dart.js +913 -0
  104. package/build/src/frontends/index.d.ts +3 -1
  105. package/build/src/frontends/index.d.ts.map +1 -1
  106. package/build/src/frontends/index.js +15 -5
  107. package/build/src/frontends/java.d.ts +110 -1
  108. package/build/src/frontends/java.d.ts.map +1 -1
  109. package/build/src/frontends/java.js +1725 -70
  110. package/build/src/frontends/javascript-typescript.d.ts +69 -1
  111. package/build/src/frontends/javascript-typescript.d.ts.map +1 -1
  112. package/build/src/frontends/javascript-typescript.js +1825 -93
  113. package/build/src/frontends/kotlin.d.ts +10 -0
  114. package/build/src/frontends/kotlin.d.ts.map +1 -0
  115. package/build/src/frontends/kotlin.js +685 -0
  116. package/build/src/frontends/php.d.ts +118 -1
  117. package/build/src/frontends/php.d.ts.map +1 -1
  118. package/build/src/frontends/php.js +1583 -76
  119. package/build/src/frontends/program.d.ts +74 -0
  120. package/build/src/frontends/program.d.ts.map +1 -0
  121. package/build/src/frontends/program.js +989 -0
  122. package/build/src/frontends/ruby.d.ts +68 -1
  123. package/build/src/frontends/ruby.d.ts.map +1 -1
  124. package/build/src/frontends/ruby.js +1446 -101
  125. package/build/src/frontends/rust-parser.d.ts +11 -0
  126. package/build/src/frontends/rust-parser.d.ts.map +1 -0
  127. package/build/src/frontends/rust-parser.js +15 -0
  128. package/build/src/frontends/rust.d.ts +14 -0
  129. package/build/src/frontends/rust.d.ts.map +1 -0
  130. package/build/src/frontends/rust.js +715 -0
  131. package/build/src/frontends/scalars.d.ts +10 -0
  132. package/build/src/frontends/scalars.d.ts.map +1 -1
  133. package/build/src/frontends/scalars.js +28 -2
  134. package/build/src/frontends/swift.d.ts +10 -0
  135. package/build/src/frontends/swift.d.ts.map +1 -0
  136. package/build/src/frontends/swift.js +860 -0
  137. package/build/src/frontends/types.d.ts +186 -0
  138. package/build/src/frontends/types.d.ts.map +1 -0
  139. package/build/src/frontends/types.js +634 -0
  140. package/build/src/language-registry.d.ts +46 -4
  141. package/build/src/language-registry.d.ts.map +1 -1
  142. package/build/src/language-registry.js +167 -13
  143. package/build/src/mapping.d.ts +2 -2
  144. package/build/src/mapping.d.ts.map +1 -1
  145. package/build/src/mapping.js +31 -10
  146. package/build/src/semantic/capabilities.d.ts +66 -0
  147. package/build/src/semantic/capabilities.d.ts.map +1 -0
  148. package/build/src/semantic/capabilities.js +649 -0
  149. package/build/src/semantic/effects.d.ts +26 -0
  150. package/build/src/semantic/effects.d.ts.map +1 -0
  151. package/build/src/semantic/effects.js +764 -0
  152. package/build/src/semantic/generics.d.ts +23 -0
  153. package/build/src/semantic/generics.d.ts.map +1 -0
  154. package/build/src/semantic/generics.js +61 -0
  155. package/build/src/semantic/lifetime.d.ts +37 -0
  156. package/build/src/semantic/lifetime.d.ts.map +1 -0
  157. package/build/src/semantic/lifetime.js +527 -0
  158. package/build/src/semantic/provenance.d.ts +9 -2
  159. package/build/src/semantic/provenance.d.ts.map +1 -1
  160. package/build/src/semantic/provenance.js +462 -20
  161. package/build/src/semantic/scalars.d.ts +11 -0
  162. package/build/src/semantic/scalars.d.ts.map +1 -1
  163. package/build/src/semantic/scalars.js +16 -1
  164. package/build/src/semantic/stdlib.d.ts +254 -0
  165. package/build/src/semantic/stdlib.d.ts.map +1 -0
  166. package/build/src/semantic/stdlib.js +880 -0
  167. package/build/src/semantic/types.d.ts +2952 -202
  168. package/build/src/semantic/types.d.ts.map +1 -1
  169. package/build/src/semantic/types.js +688 -15
  170. package/build/src/semantic/validate.d.ts +85 -5
  171. package/build/src/semantic/validate.d.ts.map +1 -1
  172. package/build/src/semantic/validate.js +2576 -98
  173. package/build/src/stdlib-facades.d.ts +304 -0
  174. package/build/src/stdlib-facades.d.ts.map +1 -0
  175. package/build/src/stdlib-facades.js +1167 -0
  176. package/build/src/stdlib-negotiation.d.ts +69 -0
  177. package/build/src/stdlib-negotiation.d.ts.map +1 -0
  178. package/build/src/stdlib-negotiation.js +403 -0
  179. package/build/src/stdlib-providers.d.ts +72 -0
  180. package/build/src/stdlib-providers.d.ts.map +1 -0
  181. package/build/src/stdlib-providers.js +339 -0
  182. package/build/src/toolchains.d.ts +55 -1
  183. package/build/src/toolchains.d.ts.map +1 -1
  184. package/build/src/toolchains.js +15 -4
  185. package/docs/architecture.md +45 -13
  186. package/docs/dart.md +60 -0
  187. package/docs/goals.md +3 -3
  188. package/docs/ios.md +121 -0
  189. package/docs/kotlin.md +42 -0
  190. package/docs/language-support.md +231 -26
  191. package/docs/multi-file-modules.md +52 -0
  192. package/docs/parser-qualification.md +121 -8
  193. package/docs/plans/2026-09-05-standard-library-portability.md +10 -10
  194. package/docs/rust.md +88 -0
  195. package/docs/source-maps.md +15 -7
  196. package/docs/standard-library-portability.md +39 -8
  197. package/docs/swift.md +44 -0
  198. package/docs/testing.md +366 -4
  199. package/docs/webassembly.md +52 -0
  200. package/index.js +63 -8
  201. package/node_modules/semantifold-tree-sitter-legacy-internal/README.md +2 -2
  202. package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/LICENSE +21 -0
  203. package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/README.md +45 -0
  204. package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/binding.gyp +30 -0
  205. package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/bindings/node/binding.cc +20 -0
  206. package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/bindings/node/binding_test.js +9 -0
  207. package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/bindings/node/index.d.ts +28 -0
  208. package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/bindings/node/index.js +11 -0
  209. package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/grammar.js +1630 -0
  210. package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/package.json +64 -0
  211. package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/prebuilds/darwin-arm64/tree-sitter-rust.node +0 -0
  212. package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/prebuilds/darwin-x64/tree-sitter-rust.node +0 -0
  213. package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/prebuilds/linux-arm64/tree-sitter-rust.node +0 -0
  214. package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/prebuilds/linux-x64/tree-sitter-rust.node +0 -0
  215. package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/prebuilds/win32-arm64/tree-sitter-rust.node +0 -0
  216. package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/prebuilds/win32-x64/tree-sitter-rust.node +0 -0
  217. package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/queries/highlights.scm +159 -0
  218. package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/queries/injections.scm +9 -0
  219. package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/queries/tags.scm +60 -0
  220. package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/src/grammar.json +9405 -0
  221. package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/src/node-types.json +5399 -0
  222. package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/src/parser.c +192569 -0
  223. package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/src/scanner.c +393 -0
  224. package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/src/tree_sitter/alloc.h +54 -0
  225. package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/src/tree_sitter/array.h +290 -0
  226. package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/src/tree_sitter/parser.h +266 -0
  227. package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/tree-sitter-rust.wasm +0 -0
  228. package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/tree-sitter.json +53 -0
  229. package/node_modules/semantifold-tree-sitter-legacy-internal/package.json +3 -2
  230. package/node_modules/semantifold-tree-sitter-legacy-internal/src/c.js +5 -4
  231. package/package.json +5 -2
  232. package/src/artifact-path.js +47 -2
  233. package/src/artifacts.js +67 -0
  234. package/src/backends/c-validation.js +6 -1
  235. package/src/backends/cpp-validation.js +6 -1
  236. package/src/backends/csharp.js +3 -0
  237. package/src/backends/dart-runtime.js +41 -0
  238. package/src/backends/dart.js +326 -0
  239. package/src/backends/effects.js +705 -0
  240. package/src/backends/go.js +14 -2
  241. package/src/backends/identifiers.js +160 -9
  242. package/src/backends/index.js +27 -2
  243. package/src/backends/ios.js +1612 -0
  244. package/src/backends/java.js +454 -36
  245. package/src/backends/javascript.js +389 -23
  246. package/src/backends/kotlin-runtime.js +29 -0
  247. package/src/backends/kotlin.js +141 -0
  248. package/src/backends/native-validation.js +1 -1
  249. package/src/backends/ordered-expressions.js +40 -6
  250. package/src/backends/php-stdlib-support.js +239 -0
  251. package/src/backends/php.js +469 -32
  252. package/src/backends/program.js +1407 -0
  253. package/src/backends/python.js +3 -0
  254. package/src/backends/ruby.js +326 -23
  255. package/src/backends/rust-runtime.js +34 -0
  256. package/src/backends/rust-validation.js +75 -0
  257. package/src/backends/rust.js +335 -0
  258. package/src/backends/scalars.js +141 -16
  259. package/src/backends/shared.js +2304 -124
  260. package/src/backends/stdlib-support.js +234 -0
  261. package/src/backends/swift-runtime.js +14 -0
  262. package/src/backends/swift.js +132 -0
  263. package/src/backends/typescript.js +349 -23
  264. package/src/backends/wasm.js +2208 -0
  265. package/src/backends/writer.js +520 -2
  266. package/src/diagnostic.js +4 -2
  267. package/src/frontends/c.js +4 -2
  268. package/src/frontends/cpp.js +4 -2
  269. package/src/frontends/csharp.js +4 -2
  270. package/src/frontends/dart.js +963 -0
  271. package/src/frontends/index.js +14 -4
  272. package/src/frontends/java.js +1977 -69
  273. package/src/frontends/javascript-typescript.js +2046 -102
  274. package/src/frontends/kotlin.js +713 -0
  275. package/src/frontends/php.js +1725 -79
  276. package/src/frontends/program.js +1062 -0
  277. package/src/frontends/ruby.js +1624 -98
  278. package/src/frontends/rust-parser.js +18 -0
  279. package/src/frontends/rust.js +714 -0
  280. package/src/frontends/scalars.js +31 -1
  281. package/src/frontends/swift.js +893 -0
  282. package/src/frontends/types.js +750 -0
  283. package/src/language-registry.js +172 -12
  284. package/src/mapping.js +33 -9
  285. package/src/semantic/capabilities.js +671 -0
  286. package/src/semantic/effects.js +737 -0
  287. package/src/semantic/generics.js +58 -0
  288. package/src/semantic/lifetime.js +517 -0
  289. package/src/semantic/provenance.js +412 -19
  290. package/src/semantic/scalars.js +17 -0
  291. package/src/semantic/stdlib.js +921 -0
  292. package/src/semantic/types.js +765 -14
  293. package/src/semantic/validate.js +2934 -209
  294. package/src/stdlib-facades.js +1211 -0
  295. package/src/stdlib-negotiation.js +446 -0
  296. package/src/stdlib-providers.js +377 -0
  297. package/src/toolchains.js +16 -3
@@ -0,0 +1,764 @@
1
+ // @ts-check
2
+ import { authorizedOperation, isTask034OperationName } from "./capabilities.js";
3
+ import { parseProtectedEntryName } from "./stdlib.js";
4
+ /** @typedef {{failureIds: Set<string>, host: boolean}} EffectSummary */
5
+ /** @typedef {(expression: import("./types.js").Expression) => void} ExpressionVisitor */
6
+ /**
7
+ * Resolves compiler-authorized calls before ordinary semantic type validation.
8
+ * Source functions always win; authority is never inferred from spelling alone.
9
+ * @param {import("./types.js").SemanticModule} module - Parser-authored module.
10
+ * @param {string} language - Source language identity for protected entry targets.
11
+ * @param {Map<string, import("./types.js").FunctionDeclaration>} functions - Visible ordinary functions.
12
+ * @param {(code: string, detail: string, location: import("./types.js").SourceLocation) => never} fail - Located failure.
13
+ * @param {boolean} normalize - Whether parser-authored operation intent may be normalized.
14
+ * @param {Map<string, import("./types.js").ClassDeclaration>} [visibleClasses] - Resolved reference classes.
15
+ * @returns {void}
16
+ */
17
+ export function validateEffectGraph(module, language, functions, fail, normalize, visibleClasses = new Map()) {
18
+ const capabilities = module.capabilities ?? [];
19
+ const capabilityIds = new Set();
20
+ const operationIds = new Set();
21
+ const resourceIds = new Set();
22
+ const failureIds = new Set();
23
+ const operationNames = new Set();
24
+ if (!Array.isArray(capabilities))
25
+ fail("INVALID_CAPABILITY_AUTHORITY", "Capabilities must be an ordered array.", module.location);
26
+ for (const [capabilityIndex, capability] of capabilities.entries()) {
27
+ const legacyId = `capability:${capabilityIndex}`;
28
+ if (!capability || capability.kind != "EffectCapabilityDeclaration" ||
29
+ capability.id != legacyId && !/^module:\d+\/capability:\d+$/u.test(capability.id) || capabilityIds.has(capability.id) ||
30
+ typeof capability.authorityId != "string" || typeof capability.name != "string" || !Array.isArray(capability.resources) ||
31
+ !Array.isArray(capability.failures) || !Array.isArray(capability.operations)) {
32
+ fail("INVALID_CAPABILITY_AUTHORITY", "Malformed capability declaration graph.", module.location);
33
+ }
34
+ capabilityIds.add(capability.id);
35
+ for (const [index, resource] of capability.resources.entries()) {
36
+ if (resource.kind != "EffectResourceDeclaration" || resource.id != `${capability.id}/resource:${index}` ||
37
+ resourceIds.has(resource.id))
38
+ fail("INVALID_CAPABILITY_AUTHORITY", "Malformed capability resource identity.", module.location);
39
+ resourceIds.add(resource.id);
40
+ }
41
+ for (const [index, failure] of capability.failures.entries()) {
42
+ if (failure.kind != "EffectFailureDeclaration" || failure.id != `${capability.id}/failure:${index}` ||
43
+ failureIds.has(failure.id))
44
+ fail("INVALID_CAPABILITY_AUTHORITY", "Malformed capability failure identity.", module.location);
45
+ failureIds.add(failure.id);
46
+ }
47
+ }
48
+ for (const capability of capabilities) {
49
+ for (const [index, operation] of capability.operations.entries()) {
50
+ if (operation.kind != "EffectOperationDeclaration" || operation.id != `${capability.id}/operation:${index}` ||
51
+ operationIds.has(operation.id) || operationNames.has(operation.name) || !Array.isArray(operation.parameters) ||
52
+ !Array.isArray(operation.failureIds) || operation.effects?.length != 1 || operation.effects[0] != "host" ||
53
+ operation.failureIds.some((id) => !failureIds.has(id))) {
54
+ fail("INVALID_CAPABILITY_AUTHORITY", "Malformed or ambiguous capability operation graph.", module.location);
55
+ }
56
+ operationIds.add(operation.id);
57
+ operationNames.add(operation.name);
58
+ }
59
+ }
60
+ for (const declaration of [
61
+ ...module.functions,
62
+ ...(module.records ?? []),
63
+ ...(module.classes ?? []),
64
+ ...(module.errors ?? [])
65
+ ]) {
66
+ if (parseProtectedEntryName(declaration.name) !== null) {
67
+ fail("STDLIB_PROTECTED_BINDING_ACCESS", `Source declaration '${declaration.name}' captures a reserved protected provider binding.`, declaration.location);
68
+ }
69
+ }
70
+ forEachExpression(module, (expression) => {
71
+ if (expression.kind == "EffectCallExpression") {
72
+ const capability = capabilities.find(({ id }) => id == expression.resolution?.capabilityId);
73
+ const operation = capability?.operations.find(({ id }) => id == expression.operation);
74
+ if (operation && expression.resolution.operationId == operation.id &&
75
+ (!Array.isArray(expression.resolution.failureIds) ||
76
+ expression.resolution.failureIds.join(",") != operation.failureIds.join(","))) {
77
+ fail("UNDECLARED_FAILURE", "UNDECLARED_FAILURE: Effect call failure boundary does not match its compiler authority.", expression.location);
78
+ }
79
+ if (!operation || expression.resolution.operationId != operation.id ||
80
+ JSON.stringify(expression.resolution) != JSON.stringify(signature(/** @type {import("./types.js").EffectCapabilityDeclaration} */ (capability), operation))) {
81
+ fail("UNDECLARED_EFFECT", "Effect call resolution does not match its compiler authority.", expression.location);
82
+ }
83
+ return;
84
+ }
85
+ if (expression.kind == "IdentifierExpression" && parseProtectedEntryName(expression.name) !== null) {
86
+ fail("STDLIB_PROTECTED_BINDING_ACCESS", `Reference to protected provider entry '${expression.name}' is not portable code.`, expression.location);
87
+ }
88
+ if (expression.kind != "CallExpression")
89
+ return;
90
+ if (functions.has(expression.callee))
91
+ return;
92
+ let operationName = expression.callee;
93
+ const protectedEntry = parseProtectedEntryName(expression.callee);
94
+ if (protectedEntry !== null) {
95
+ if (capabilities.length == 0) {
96
+ fail("STDLIB_PROTECTED_BINDING_ACCESS", `Protected provider entry '${expression.callee}' requires an explicit capability authority.`, expression.location);
97
+ }
98
+ if (protectedEntry.target != language) {
99
+ fail("STDLIB_PROTECTED_BINDING_ACCESS", `Protected provider entry target '${protectedEntry.target}' does not match source language '${language}'.`, expression.location);
100
+ }
101
+ operationName = protectedEntry.operation;
102
+ }
103
+ const match = authorizedOperation(capabilities, operationName);
104
+ if (!match) {
105
+ if (protectedEntry !== null) {
106
+ fail("STDLIB_PROTECTED_BINDING_ACCESS", `Protected provider entry for undeclared operation '${operationName}' has no authorized capability operation.`, expression.location);
107
+ }
108
+ if (isTask034OperationName(operationName)) {
109
+ fail("MISSING_CAPABILITY_AUTHORITY", `Operation '${operationName}' requires explicit compiler authority.`, expression.location);
110
+ }
111
+ return;
112
+ }
113
+ if (!normalize) {
114
+ fail("UNDECLARED_EFFECT", `Caller-authored ordinary call '${expression.callee}' cannot forge a capability operation.`, expression.location);
115
+ }
116
+ const { capability, operation } = match;
117
+ const flow = operation.resourceFlow;
118
+ if ((flow.kind == "borrow" || flow.kind == "close") && expression.arguments[flow.parameterIndex]) {
119
+ const argument = expression.arguments[flow.parameterIndex];
120
+ if (argument.kind != "IdentifierExpression" && argument.kind != "PrivateFieldRead" && argument.kind != "ReceiverExpression") {
121
+ fail("INVALID_RESOURCE_BORROW", "An owned borrow must name one immediate resource place.", argument.location);
122
+ }
123
+ expression.arguments[flow.parameterIndex] = {
124
+ expression: argument,
125
+ kind: "OwnedBorrowExpression",
126
+ location: argument.location,
127
+ mode: flow.kind == "close" ? "exclusive" : "shared",
128
+ sourceProvenance: argument.sourceProvenance,
129
+ type: /** @type {import("./types.js").OwnedResourceType | import("./types.js").OwnedReferenceType} */ (operation.parameters[flow.parameterIndex].type)
130
+ };
131
+ }
132
+ const replacement = /** @type {import("./types.js").EffectCallExpression} */ ( /** @type {unknown} */(expression));
133
+ delete /** @type {{callee?: string}} */ (replacement).callee;
134
+ replacement.kind = "EffectCallExpression";
135
+ replacement.operation = operation.id;
136
+ replacement.resolution = signature(capability, operation);
137
+ });
138
+ const complete = completeEffectSummaries(module, failureIds, visibleClasses);
139
+ const summaries = complete.functions;
140
+ const methodSummaries = complete.methods;
141
+ const constructorSummaries = complete.constructors;
142
+ for (const declaration of module.classes ?? []) {
143
+ applyDeclarationSummary(declaration.constructor, constructorSummaries.get(/** @type {string} */ (declaration.constructor.id)), normalize, fail);
144
+ for (const method of declaration.methods) {
145
+ applyDeclarationSummary(method, methodSummaries.get(/** @type {string} */ (method.id)), normalize, fail);
146
+ }
147
+ }
148
+ let site = 0;
149
+ forEachExpression(module, (expression) => {
150
+ if (expression.kind == "EffectCallExpression") {
151
+ if (normalize)
152
+ expression.effectSiteId = `effect:${site}`;
153
+ else
154
+ validateSite(expression, site, fail);
155
+ site += 1;
156
+ return;
157
+ }
158
+ if (expression.kind == "CallExpression") {
159
+ const summary = summaries.get(expression.callee);
160
+ if (!summary?.host) {
161
+ if (normalize) {
162
+ delete expression.effectSiteId;
163
+ delete expression.effects;
164
+ delete expression.failureIds;
165
+ }
166
+ if (!normalize && Array.isArray(expression.failureIds) && expression.failureIds.length > 0) {
167
+ fail("UNDECLARED_FAILURE", "UNDECLARED_FAILURE: Pure call carries a forged typed failure boundary.", expression.location);
168
+ }
169
+ if (!normalize && (expression.effectSiteId !== undefined || expression.effects !== undefined || expression.failureIds !== undefined)) {
170
+ fail("UNDECLARED_EFFECT", "Pure call carries forged effect metadata.", expression.location);
171
+ }
172
+ return;
173
+ }
174
+ if (normalize) {
175
+ expression.effectSiteId = `effect:${site}`;
176
+ expression.effects = ["host"];
177
+ expression.failureIds = [...summary.failureIds];
178
+ }
179
+ else {
180
+ validateSite(expression, site, fail);
181
+ if (!Array.isArray(expression.failureIds) || expression.failureIds.join(",") != [...summary.failureIds].join(",")) {
182
+ fail("UNDECLARED_FAILURE", "UNDECLARED_FAILURE: Call failure boundary does not match its resolved function.", expression.location);
183
+ }
184
+ if (expression.effects?.length != 1 || expression.effects[0] != "host") {
185
+ fail("UNDECLARED_EFFECT", "Call effect summary does not match its resolved function.", expression.location);
186
+ }
187
+ }
188
+ site += 1;
189
+ return;
190
+ }
191
+ if (expression.kind == "MethodCallExpression" || expression.kind == "ReferenceConstruction") {
192
+ const summary = expression.kind == "MethodCallExpression"
193
+ ? methodSummaries.get(expression.method)
194
+ : constructorSummaries.get(expression.resolution?.declarationId ?? `${expression.reference.declarationId}:constructor`);
195
+ const label = expression.kind == "MethodCallExpression" ? "method call" : "construction";
196
+ if (!summary?.host) {
197
+ if (normalize) {
198
+ delete expression.effectSiteId;
199
+ delete expression.effects;
200
+ delete expression.failureIds;
201
+ }
202
+ if (!normalize && Array.isArray(expression.failureIds) && expression.failureIds.length > 0) {
203
+ fail("UNDECLARED_FAILURE", `UNDECLARED_FAILURE: Pure ${label} carries a forged typed failure boundary.`, expression.location);
204
+ }
205
+ if (!normalize && (expression.effectSiteId !== undefined || expression.effects !== undefined || expression.failureIds !== undefined)) {
206
+ fail("UNDECLARED_EFFECT", `Pure ${label} carries forged effect metadata.`, expression.location);
207
+ }
208
+ return;
209
+ }
210
+ if (normalize) {
211
+ expression.effectSiteId = `effect:${site}`;
212
+ expression.effects = ["host"];
213
+ expression.failureIds = [...summary.failureIds];
214
+ }
215
+ else {
216
+ validateSite(expression, site, fail);
217
+ if (!Array.isArray(expression.failureIds) || expression.failureIds.join(",") != [...summary.failureIds].join(",")) {
218
+ fail("UNDECLARED_FAILURE", `UNDECLARED_FAILURE: ${label} failure boundary does not match its resolved declaration.`, expression.location);
219
+ }
220
+ if (expression.effects?.length != 1 || expression.effects[0] != "host") {
221
+ fail("UNDECLARED_EFFECT", `${label} effect summary does not match its resolved declaration.`, expression.location);
222
+ }
223
+ }
224
+ site += 1;
225
+ }
226
+ }, true);
227
+ }
228
+ /**
229
+ * Computes the joint finite fixed point across functions and resolved receiver methods.
230
+ * @param {import("./types.js").SemanticModule} module - Resolved module.
231
+ * @param {Set<string>} capabilityFailureIds - Declared capability failures.
232
+ * @param {Map<string, import("./types.js").ClassDeclaration>} visibleClasses - Resolved reference classes.
233
+ * @returns {{constructors: Map<string, EffectSummary>, functions: Map<string, EffectSummary>, methods: Map<string, EffectSummary>}} Complete summaries.
234
+ */
235
+ function completeEffectSummaries(module, capabilityFailureIds, visibleClasses) {
236
+ const importedMethods = declaredClassSummaries(visibleClasses, "methods");
237
+ let functions = effectSummaries(module.functions, new Map(), capabilityFailureIds);
238
+ let methods = directMethodSummaries(module, functions, importedMethods, capabilityFailureIds, importedMethods);
239
+ while (true) {
240
+ const nextFunctions = effectSummaries(module.functions, methods, capabilityFailureIds);
241
+ const nextMethods = directMethodSummaries(module, nextFunctions, methods, capabilityFailureIds, importedMethods);
242
+ if (sameSummaries(functions, nextFunctions) && sameSummaries(methods, nextMethods)) {
243
+ return { constructors: directConstructorSummaries(module, nextFunctions, nextMethods, capabilityFailureIds, declaredClassSummaries(visibleClasses, "constructors")), functions: nextFunctions, methods: nextMethods };
244
+ }
245
+ functions = nextFunctions;
246
+ methods = nextMethods;
247
+ }
248
+ }
249
+ /**
250
+ * Compares stable host/failure summary maps.
251
+ * @param {Map<string, EffectSummary>} left - Previous summaries.
252
+ * @param {Map<string, EffectSummary>} right - Next summaries.
253
+ * @returns {boolean} Whether the summaries are identical.
254
+ */
255
+ function sameSummaries(left, right) {
256
+ if (left.size != right.size)
257
+ return false;
258
+ for (const [name, summary] of left) {
259
+ const candidate = right.get(name);
260
+ if (!candidate || summary.host != candidate.host || summary.failureIds.size != candidate.failureIds.size ||
261
+ [...summary.failureIds].some((id) => !candidate.failureIds.has(id)))
262
+ return false;
263
+ }
264
+ return true;
265
+ }
266
+ /**
267
+ * Builds the complete immutable resolution recorded at an effect call site.
268
+ * @param {import("./types.js").EffectCapabilityDeclaration} capability - Declaring capability.
269
+ * @param {import("./types.js").EffectOperationDeclaration} operation - Resolved operation.
270
+ * @returns {import("./types.js").ResolvedEffectOperationSignature} Complete resolution.
271
+ */
272
+ function signature(capability, operation) {
273
+ return {
274
+ capabilityId: capability.id,
275
+ effects: /** @type {const} */ (["host"]),
276
+ failureIds: [...operation.failureIds],
277
+ kind: /** @type {const} */ ("ResolvedEffectOperationSignature"),
278
+ operationId: operation.id,
279
+ parameterTypes: operation.parameters.map(({ type }) => /** @type {import("./types.js").SemanticTypeIdentity} */ (typeIdentity(type))),
280
+ resourceFlow: structuredClone(operation.resourceFlow),
281
+ returnType: typeIdentity(operation.returnType)
282
+ };
283
+ }
284
+ /**
285
+ * Removes locations and provenance from one resolved type.
286
+ * @param {import("./types.js").SemanticFunctionReturnType} type - Semantic type.
287
+ * @returns {import("./types.js").FunctionReturnTypeIdentity} Stable type identity.
288
+ */
289
+ function typeIdentity(type) {
290
+ if (type.kind == "TypeReference")
291
+ return type.name;
292
+ if (type.kind == "OwnedResourceType")
293
+ return { kind: type.kind, resourceId: type.resourceId };
294
+ if (type.kind == "OwnedReferenceType")
295
+ return { declarationId: type.declarationId, kind: type.kind };
296
+ if (type.kind == "OptionalType")
297
+ return { kind: type.kind,
298
+ valueType: /** @type {import("./types.js").SemanticTypeIdentity} */ (typeIdentity(type.valueType)) };
299
+ if (type.kind == "ListType")
300
+ return {
301
+ elementType: /** @type {import("./types.js").SemanticTypeIdentity} */ (typeIdentity(type.elementType)), kind: type.kind
302
+ };
303
+ if (type.kind == "MapType" || type.kind == "OrderedMapType") {
304
+ const keyType = /** @type {import("./types.js").SemanticTypeIdentity} */ (typeIdentity(type.keyType));
305
+ const valueType = /** @type {import("./types.js").SemanticTypeIdentity} */ (typeIdentity(type.valueType));
306
+ return type.kind == "OrderedMapType" ? { keyType, kind: type.kind, order: "insertion", valueType } :
307
+ { keyType, kind: type.kind, valueType };
308
+ }
309
+ if (type.kind == "RecordType")
310
+ return { arguments: type.arguments?.map((argument) =>
311
+ /** @type {import("./types.js").SemanticTypeIdentity} */ (typeIdentity(argument))), declarationId: type.declarationId, kind: type.kind };
312
+ if (type.kind == "ReferenceType")
313
+ return { declarationId: type.declarationId, kind: type.kind };
314
+ return { kind: type.kind, parameterId: type.parameterId };
315
+ }
316
+ /**
317
+ * Computes the fixed-point host-effect summary for ordinary functions.
318
+ * @param {import("./types.js").FunctionDeclaration[]} functions - Module functions.
319
+ * @param {Map<string, EffectSummary>} [methodSummaries] - Receiver-call summaries from the current fixed-point round.
320
+ * @param {Set<string>} [capabilityFailureIds] - Capability failures eligible for call-site propagation.
321
+ * @returns {Map<string, EffectSummary>} Summaries by source function name.
322
+ */
323
+ function effectSummaries(functions, methodSummaries = new Map(), capabilityFailureIds = new Set()) {
324
+ const summaries = new Map(functions.map(({ name }) => /** @type {[string, EffectSummary]} */ ([name, { failureIds: new Set(), host: false }])));
325
+ let changed = true;
326
+ while (changed) {
327
+ changed = false;
328
+ for (const declaration of functions) {
329
+ const summary = summaries.get(declaration.name);
330
+ if (!summary)
331
+ continue;
332
+ forEachBlockExpression(declaration.body, (expression) => {
333
+ if (expression.kind == "EffectCallExpression") {
334
+ if (!summary.host) {
335
+ summary.host = true;
336
+ changed = true;
337
+ }
338
+ }
339
+ else if (expression.kind == "CallExpression") {
340
+ const called = summaries.get(expression.callee);
341
+ if (called?.host && !summary.host) {
342
+ summary.host = true;
343
+ changed = true;
344
+ }
345
+ }
346
+ else if (expression.kind == "MethodCallExpression") {
347
+ const called = methodSummaries.get(expression.method);
348
+ if (called?.host && !summary.host) {
349
+ summary.host = true;
350
+ changed = true;
351
+ }
352
+ }
353
+ }, false);
354
+ const escaping = escapingBlockFailures(declaration.body, summaries, methodSummaries, capabilityFailureIds);
355
+ for (const id of escaping)
356
+ if (!summary.failureIds.has(id)) {
357
+ summary.failureIds.add(id);
358
+ changed = true;
359
+ }
360
+ }
361
+ }
362
+ return summaries;
363
+ }
364
+ /**
365
+ * Computes the capability failures escaping one structured block.
366
+ * @param {import("./types.js").Block} block - Function body.
367
+ * @param {Map<string, EffectSummary>} functionSummaries - Current function fixed point.
368
+ * @param {Map<string, EffectSummary>} methodSummaries - Resolved method summaries.
369
+ * @param {Set<string>} capabilityFailureIds - Declared capability failures.
370
+ * @returns {Set<string>} Escaping failure identities.
371
+ */
372
+ function escapingBlockFailures(block, functionSummaries, methodSummaries, capabilityFailureIds) {
373
+ const result = new Set();
374
+ for (const statement of block.statements) {
375
+ if (statement.kind == "TryStatement") {
376
+ const body = escapingBlockFailures(statement.body, functionSummaries, methodSummaries, capabilityFailureIds);
377
+ if (body.delete(statement.catchType.declarationId)) {
378
+ addFailures(result, escapingBlockFailures(statement.catchBody, functionSummaries, methodSummaries, capabilityFailureIds));
379
+ }
380
+ addFailures(result, body);
381
+ continue;
382
+ }
383
+ for (const expression of statementExpressions(statement)) {
384
+ addExpressionFailures(result, expression, functionSummaries, methodSummaries);
385
+ }
386
+ if (statement.kind == "RaiseStatement" && capabilityFailureIds.has(statement.error.error.declarationId)) {
387
+ result.add(statement.error.error.declarationId);
388
+ }
389
+ for (const child of statementBlocks(statement)) {
390
+ addFailures(result, escapingBlockFailures(child, functionSummaries, methodSummaries, capabilityFailureIds));
391
+ }
392
+ }
393
+ return result;
394
+ }
395
+ /**
396
+ * Adds failures evaluated by one expression subtree.
397
+ * @param {Set<string>} target - Destination identities.
398
+ * @param {import("./types.js").Expression} expression - Expression root.
399
+ * @param {Map<string, EffectSummary>} functionSummaries - Function summaries.
400
+ * @param {Map<string, EffectSummary>} methodSummaries - Method summaries.
401
+ * @returns {void}
402
+ */
403
+ function addExpressionFailures(target, expression, functionSummaries, methodSummaries) {
404
+ if (expression.kind == "EffectCallExpression")
405
+ addFailures(target, expression.resolution.failureIds);
406
+ else if (expression.kind == "CallExpression")
407
+ addFailures(target, functionSummaries.get(expression.callee)?.failureIds ?? []);
408
+ else if (expression.kind == "MethodCallExpression")
409
+ addFailures(target, methodSummaries.get(expression.method)?.failureIds ?? []);
410
+ for (const child of expressionChildren(expression))
411
+ addExpressionFailures(target, child, functionSummaries, methodSummaries);
412
+ }
413
+ /**
414
+ * Returns directly evaluated expressions for one statement.
415
+ * @param {import("./types.js").Statement} statement - Statement.
416
+ * @returns {import("./types.js").Expression[]} Expression roots.
417
+ */
418
+ function statementExpressions(statement) {
419
+ if (statement.kind == "LocalDeclaration")
420
+ return [statement.initializer];
421
+ if (statement.kind == "AssignmentStatement" || statement.kind == "PrivateFieldWriteStatement" ||
422
+ statement.kind == "ExpressionStatement" || statement.kind == "PrintStatement")
423
+ return [statement.expression];
424
+ if (statement.kind == "ReturnStatement")
425
+ return statement.expression ? [statement.expression] : [];
426
+ if (statement.kind == "RaiseStatement")
427
+ return [statement.error.message];
428
+ if (statement.kind == "IfStatement" || statement.kind == "WhileStatement")
429
+ return [statement.condition];
430
+ if (statement.kind == "ForEachStatement")
431
+ return [statement.list];
432
+ if (statement.kind == "ForEachMapStatement")
433
+ return [statement.map];
434
+ return [];
435
+ }
436
+ /**
437
+ * Returns nested blocks whose failures propagate through one statement.
438
+ * @param {import("./types.js").Statement} statement - Statement.
439
+ * @returns {import("./types.js").Block[]} Child blocks.
440
+ */
441
+ function statementBlocks(statement) {
442
+ if (statement.kind == "IfStatement")
443
+ return [statement.consequent, ...(statement.alternate ? [statement.alternate] : [])];
444
+ if (statement.kind == "WhileStatement" || statement.kind == "ForEachStatement" || statement.kind == "ForEachMapStatement") {
445
+ return [statement.body];
446
+ }
447
+ return [];
448
+ }
449
+ /**
450
+ * Adds an iterable of failure identities to a set.
451
+ * @param {Set<string>} target - Destination.
452
+ * @param {Iterable<string>} source - Source identities.
453
+ * @returns {void}
454
+ */
455
+ function addFailures(target, source) {
456
+ for (const id of source)
457
+ target.add(id);
458
+ }
459
+ /**
460
+ * Computes bounded direct summaries for class methods.
461
+ * @param {import("./types.js").SemanticModule} module - Resolved module.
462
+ * @param {Map<string, EffectSummary>} functionSummaries - Ordinary function summaries.
463
+ * @param {Map<string, EffectSummary>} priorMethodSummaries - Receiver summaries from the previous fixed-point round.
464
+ * @param {Set<string>} capabilityFailureIds - Declared capability failures.
465
+ * @param {Map<string, EffectSummary>} baseSummaries - Imported receiver summaries.
466
+ * @returns {Map<string, EffectSummary>} Summaries by resolved method identity.
467
+ */
468
+ function directMethodSummaries(module, functionSummaries, priorMethodSummaries, capabilityFailureIds, baseSummaries = new Map()) {
469
+ /** @type {Map<string, EffectSummary>} */
470
+ const summaries = new Map(baseSummaries);
471
+ for (const declaration of module.classes ?? []) {
472
+ for (const method of declaration.methods) {
473
+ /** @type {EffectSummary} */
474
+ const summary = { failureIds: escapingBlockFailures(method.body, functionSummaries, priorMethodSummaries, capabilityFailureIds), host: false };
475
+ forEachBlockExpression(method.body, (expression) => {
476
+ if (expression.kind == "EffectCallExpression") {
477
+ summary.host = true;
478
+ const flow = expression.resolution.resourceFlow;
479
+ const argument = flow.kind == "borrow" || flow.kind == "close" ? expression.arguments[flow.parameterIndex] : undefined;
480
+ const borrowedParameterName = argument?.kind == "OwnedBorrowExpression" && argument.expression.kind == "IdentifierExpression"
481
+ ? argument.expression.name : undefined;
482
+ const knownOpenBorrow = declaration.ownership?.kind == "ownedResource" && argument?.kind == "OwnedBorrowExpression" && (argument.expression.kind == "PrivateFieldRead" && argument.expression.field == declaration.ownership.fieldId ||
483
+ borrowedParameterName !== undefined && method.parameters.some((parameter) => parameter.name == borrowedParameterName &&
484
+ (parameter.type.kind == "OwnedResourceType" || parameter.type.kind == "OwnedReferenceType")));
485
+ const terminalFailureId = knownOpenBorrow
486
+ ? flow.kind == "borrow" || flow.kind == "close" ? flow.terminalFailureId : undefined
487
+ : undefined;
488
+ if (terminalFailureId)
489
+ summary.failureIds.delete(terminalFailureId);
490
+ }
491
+ else if (expression.kind == "CallExpression") {
492
+ const called = functionSummaries.get(expression.callee);
493
+ if (called?.host)
494
+ summary.host = true;
495
+ }
496
+ else if (expression.kind == "MethodCallExpression") {
497
+ const called = priorMethodSummaries.get(expression.method);
498
+ if (called?.host)
499
+ summary.host = true;
500
+ }
501
+ }, false);
502
+ summaries.set(/** @type {string} */ (method.id), summary);
503
+ }
504
+ }
505
+ return summaries;
506
+ }
507
+ /**
508
+ * Reads checked summaries already proved on imported class declarations.
509
+ * @param {Map<string, import("./types.js").ClassDeclaration>} classes - Visible classes.
510
+ * @param {"constructors" | "methods"} kind - Declaration cohort.
511
+ * @returns {Map<string, EffectSummary>} Imported summaries by declaration identity.
512
+ */
513
+ function declaredClassSummaries(classes, kind) {
514
+ /** @type {Map<string, EffectSummary>} */
515
+ const summaries = new Map();
516
+ for (const declaration of classes.values()) {
517
+ const members = kind == "constructors" ? [declaration.constructor] : declaration.methods;
518
+ for (const member of members) {
519
+ if (member.effects?.length == 1 && member.effects[0] == "host" && Array.isArray(member.failureIds)) {
520
+ summaries.set(/** @type {string} */ (member.id), { failureIds: new Set(member.failureIds), host: true });
521
+ }
522
+ }
523
+ }
524
+ return summaries;
525
+ }
526
+ /**
527
+ * Computes direct constructor effects after function and method fixed points stabilize.
528
+ * @param {import("./types.js").SemanticModule} module - Resolved module.
529
+ * @param {Map<string, EffectSummary>} functionSummaries - Stable function summaries.
530
+ * @param {Map<string, EffectSummary>} methodSummaries - Stable method summaries.
531
+ * @param {Set<string>} capabilityFailureIds - Declared capability failures.
532
+ * @param {Map<string, EffectSummary>} baseSummaries - Imported constructor summaries.
533
+ * @returns {Map<string, EffectSummary>} Constructor summaries by identity.
534
+ */
535
+ function directConstructorSummaries(module, functionSummaries, methodSummaries, capabilityFailureIds, baseSummaries) {
536
+ const summaries = new Map(baseSummaries);
537
+ for (const declaration of module.classes ?? []) {
538
+ const constructor = declaration.constructor;
539
+ /** @type {EffectSummary} */
540
+ const summary = {
541
+ failureIds: escapingBlockFailures(constructor.body, functionSummaries, methodSummaries, capabilityFailureIds),
542
+ host: false
543
+ };
544
+ forEachBlockExpression(constructor.body, (expression) => {
545
+ if (expression.kind == "EffectCallExpression")
546
+ summary.host = true;
547
+ else if (expression.kind == "CallExpression" && functionSummaries.get(expression.callee)?.host)
548
+ summary.host = true;
549
+ else if (expression.kind == "MethodCallExpression" && methodSummaries.get(expression.method)?.host)
550
+ summary.host = true;
551
+ }, false);
552
+ summaries.set(/** @type {string} */ (constructor.id), summary);
553
+ }
554
+ return summaries;
555
+ }
556
+ /**
557
+ * Records or verifies one checked class-member summary.
558
+ * @param {import("./types.js").ConstructorDeclaration | import("./types.js").MethodDeclaration} declaration - Class member.
559
+ * @param {EffectSummary | undefined} summary - Computed summary.
560
+ * @param {boolean} normalize - Whether metadata may be written.
561
+ * @param {(code: string, detail: string, location: import("./types.js").SourceLocation) => never} fail - Located failure.
562
+ * @returns {void}
563
+ */
564
+ function applyDeclarationSummary(declaration, summary, normalize, fail) {
565
+ if (!summary?.host) {
566
+ if (normalize) {
567
+ delete declaration.effects;
568
+ delete declaration.failureIds;
569
+ }
570
+ else if (declaration.effects !== undefined || declaration.failureIds !== undefined) {
571
+ fail("UNDECLARED_EFFECT", "Pure class member carries forged effect metadata.", declaration.location);
572
+ }
573
+ return;
574
+ }
575
+ const failureIds = [...summary.failureIds];
576
+ if (normalize) {
577
+ declaration.effects = ["host"];
578
+ declaration.failureIds = failureIds;
579
+ }
580
+ else if (declaration.effects?.length != 1 || declaration.effects[0] != "host" ||
581
+ !Array.isArray(declaration.failureIds) || declaration.failureIds.join(",") != failureIds.join(",")) {
582
+ fail("UNDECLARED_EFFECT", "Class member effect summary does not match its body.", declaration.location);
583
+ }
584
+ }
585
+ /**
586
+ * Validates one deterministic effect-site identity.
587
+ * @param {import("./types.js").CallExpression | import("./types.js").EffectCallExpression | import("./types.js").MethodCallExpression | import("./types.js").ReferenceConstruction} expression - Effectful call.
588
+ * @param {number} site - Expected traversal index.
589
+ * @param {(code: string, detail: string, location: import("./types.js").SourceLocation) => never} fail - Located failure.
590
+ * @returns {void}
591
+ */
592
+ function validateSite(expression, site, fail) {
593
+ if (expression.effectSiteId != `effect:${site}`) {
594
+ fail("INVALID_EFFECT_ORDER", `Effect site '${String(expression.effectSiteId)}' is not expected site 'effect:${site}'.`, expression.location);
595
+ }
596
+ }
597
+ /**
598
+ * Visits every expression in deterministic declaration and evaluation order.
599
+ * @param {import("./types.js").SemanticModule} module - Module to traverse.
600
+ * @param {ExpressionVisitor} visitor - Expression visitor.
601
+ * @param {boolean} [postorder] - Visit children before parents.
602
+ * @returns {void}
603
+ */
604
+ function forEachExpression(module, visitor, postorder = false) {
605
+ for (const declaration of module.classes ?? []) {
606
+ forEachBlockExpression(declaration.constructor.body, visitor, postorder);
607
+ for (const method of declaration.methods)
608
+ forEachBlockExpression(method.body, visitor, postorder);
609
+ }
610
+ for (const declaration of module.functions)
611
+ forEachBlockExpression(declaration.body, visitor, postorder);
612
+ forEachBlockExpression(module.entryPoint.body, visitor, postorder);
613
+ }
614
+ /**
615
+ * Visits expressions in one structured block.
616
+ * @param {import("./types.js").Block} block - Block to traverse.
617
+ * @param {ExpressionVisitor} visitor - Expression visitor.
618
+ * @param {boolean} postorder - Visit children before parents.
619
+ * @returns {void}
620
+ */
621
+ function forEachBlockExpression(block, visitor, postorder) {
622
+ for (const statement of block.statements) {
623
+ if (statement.kind == "LocalDeclaration")
624
+ visit(statement.initializer);
625
+ else if (statement.kind == "AssignmentStatement" || statement.kind == "PrivateFieldWriteStatement")
626
+ visit(statement.expression);
627
+ else if (statement.kind == "ReturnStatement" && statement.expression)
628
+ visit(statement.expression);
629
+ else if (statement.kind == "ExpressionStatement" || statement.kind == "PrintStatement")
630
+ visit(statement.expression);
631
+ else if (statement.kind == "IfStatement") {
632
+ visit(statement.condition);
633
+ forEachBlockExpression(statement.consequent, visitor, postorder);
634
+ if (statement.alternate)
635
+ forEachBlockExpression(statement.alternate, visitor, postorder);
636
+ }
637
+ else if (statement.kind == "ForEachStatement") {
638
+ visit(statement.list);
639
+ forEachBlockExpression(statement.body, visitor, postorder);
640
+ }
641
+ else if (statement.kind == "ForEachMapStatement") {
642
+ visit(statement.map);
643
+ forEachBlockExpression(statement.body, visitor, postorder);
644
+ }
645
+ else if (statement.kind == "WhileStatement") {
646
+ visit(statement.condition);
647
+ forEachBlockExpression(statement.body, visitor, postorder);
648
+ }
649
+ else if (statement.kind == "RaiseStatement")
650
+ visit(statement.error.message);
651
+ else if (statement.kind == "TryStatement") {
652
+ forEachBlockExpression(statement.body, visitor, postorder);
653
+ forEachBlockExpression(statement.catchBody, visitor, postorder);
654
+ }
655
+ }
656
+ /**
657
+ * Visits one expression subtree.
658
+ * @param {import("./types.js").Expression} expression - Expression root.
659
+ * @returns {void}
660
+ */
661
+ function visit(expression) {
662
+ if (!postorder)
663
+ visitor(expression);
664
+ for (const child of expressionChildren(expression))
665
+ visit(child);
666
+ if (postorder)
667
+ visitor(expression);
668
+ }
669
+ }
670
+ /**
671
+ * Reports whether one semantic block references a reserved protected provider entry.
672
+ * @param {import("./types.js").Block} block - Semantic block.
673
+ * @returns {boolean} Whether a protected entry name is referenced.
674
+ */
675
+ export function blockReferencesProtectedEntry(block) {
676
+ return block.statements.some(statementReferencesProtectedEntry);
677
+ }
678
+ /**
679
+ * Reports whether one semantic statement references a reserved protected provider entry.
680
+ * @param {import("./types.js").Statement} statement - Semantic statement.
681
+ * @returns {boolean} Whether a protected entry name is referenced.
682
+ */
683
+ function statementReferencesProtectedEntry(statement) {
684
+ switch (statement.kind) {
685
+ case "LocalDeclaration":
686
+ return expressionReferencesProtectedEntry(statement.initializer);
687
+ case "AssignmentStatement":
688
+ case "PrivateFieldWriteStatement":
689
+ return expressionReferencesProtectedEntry(statement.expression);
690
+ case "ReturnStatement":
691
+ return statement.expression ? expressionReferencesProtectedEntry(statement.expression) : false;
692
+ case "ExpressionStatement":
693
+ case "PrintStatement":
694
+ return expressionReferencesProtectedEntry(statement.expression);
695
+ case "IfStatement":
696
+ return expressionReferencesProtectedEntry(statement.condition) ||
697
+ blockReferencesProtectedEntry(statement.consequent) ||
698
+ (statement.alternate ? blockReferencesProtectedEntry(statement.alternate) : false);
699
+ case "ForEachStatement":
700
+ return expressionReferencesProtectedEntry(statement.list) || blockReferencesProtectedEntry(statement.body);
701
+ case "ForEachMapStatement":
702
+ return expressionReferencesProtectedEntry(statement.map) || blockReferencesProtectedEntry(statement.body);
703
+ case "WhileStatement":
704
+ return expressionReferencesProtectedEntry(statement.condition) || blockReferencesProtectedEntry(statement.body);
705
+ case "RaiseStatement":
706
+ return expressionReferencesProtectedEntry(statement.error.message);
707
+ case "TryStatement":
708
+ return blockReferencesProtectedEntry(statement.body) || blockReferencesProtectedEntry(statement.catchBody);
709
+ default:
710
+ return false;
711
+ }
712
+ }
713
+ /**
714
+ * Reports whether one semantic expression references a reserved protected provider entry.
715
+ * @param {import("./types.js").Expression} expression - Semantic expression.
716
+ * @returns {boolean} Whether a protected entry name is referenced.
717
+ */
718
+ function expressionReferencesProtectedEntry(expression) {
719
+ if (expression.kind == "IdentifierExpression" && parseProtectedEntryName(expression.name) !== null)
720
+ return true;
721
+ if (expression.kind == "CallExpression" && parseProtectedEntryName(expression.callee) !== null)
722
+ return true;
723
+ return expressionChildren(expression).some(expressionReferencesProtectedEntry);
724
+ }
725
+ /**
726
+ * Returns semantic child expressions in evaluation order.
727
+ * @param {import("./types.js").Expression} expression - Parent expression.
728
+ * @returns {import("./types.js").Expression[]} Children.
729
+ */
730
+ function expressionChildren(expression) {
731
+ if (expression.kind == "CallExpression" || expression.kind == "EffectCallExpression" || expression.kind == "ReferenceConstruction" ||
732
+ expression.kind == "RecordConstruction")
733
+ return expression.arguments;
734
+ if (expression.kind == "MethodCallExpression")
735
+ return [expression.receiver, ...expression.arguments];
736
+ if (expression.kind == "OwnedBorrowExpression" || expression.kind == "OwnedMoveExpression")
737
+ return [expression.expression];
738
+ if (expression.kind == "BinaryExpression")
739
+ return [expression.left, expression.right];
740
+ if (expression.kind == "UnaryExpression")
741
+ return [expression.operand];
742
+ if (expression.kind == "OptionalSome")
743
+ return [expression.value];
744
+ if (expression.kind == "OptionalIsPresent" || expression.kind == "OptionalUnwrap")
745
+ return [expression.operand];
746
+ if (expression.kind == "ListLiteral")
747
+ return expression.elements;
748
+ if (expression.kind == "MapLiteral" || expression.kind == "OrderedMapLiteral")
749
+ return expression.entries.map(({ value }) => value);
750
+ if (expression.kind == "ListIndexExpression")
751
+ return [expression.collection, expression.index];
752
+ if (expression.kind == "MapLookupExpression")
753
+ return [expression.collection, expression.key];
754
+ if (expression.kind == "CollectionSizeExpression")
755
+ return [expression.collection];
756
+ if (expression.kind == "MemberRead")
757
+ return [expression.receiver];
758
+ if (expression.kind == "PrivateFieldRead")
759
+ return [expression.receiver];
760
+ if (expression.kind == "ErrorMessageRead")
761
+ return [expression.receiver];
762
+ return [];
763
+ }
764
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZWZmZWN0cy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9zZW1hbnRpYy9lZmZlY3RzLmpzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLFlBQVk7QUFFWixPQUFPLEVBQUMsbUJBQW1CLEVBQUUsc0JBQXNCLEVBQUMsTUFBTSxtQkFBbUIsQ0FBQTtBQUM3RSxPQUFPLEVBQUMsdUJBQXVCLEVBQUMsTUFBTSxhQUFhLENBQUE7QUFFbkQsd0VBQXdFO0FBQ3hFLHlGQUF5RjtBQUV6Rjs7Ozs7Ozs7OztHQVVHO0FBQ0gsTUFBTSxVQUFVLG1CQUFtQixDQUFDLE1BQU0sRUFBRSxRQUFRLEVBQUUsU0FBUyxFQUFFLElBQUksRUFBRSxTQUFTLEVBQUUsY0FBYyxHQUFHLElBQUksR0FBRyxFQUFFO0lBQzFHLE1BQU0sWUFBWSxHQUFHLE1BQU0sQ0FBQyxZQUFZLElBQUksRUFBRSxDQUFBO0lBQzlDLE1BQU0sYUFBYSxHQUFHLElBQUksR0FBRyxFQUFFLENBQUE7SUFDL0IsTUFBTSxZQUFZLEdBQUcsSUFBSSxHQUFHLEVBQUUsQ0FBQTtJQUM5QixNQUFNLFdBQVcsR0FBRyxJQUFJLEdBQUcsRUFBRSxDQUFBO0lBQzdCLE1BQU0sVUFBVSxHQUFHLElBQUksR0FBRyxFQUFFLENBQUE7SUFDNUIsTUFBTSxjQUFjLEdBQUcsSUFBSSxHQUFHLEVBQUUsQ0FBQTtJQUVoQyxJQUFJLENBQUMsS0FBSyxDQUFDLE9BQU8sQ0FBQyxZQUFZLENBQUM7UUFBRSxJQUFJLENBQUMsOEJBQThCLEVBQUUsd0NBQXdDLEVBQUUsTUFBTSxDQUFDLFFBQVEsQ0FBQyxDQUFBO0lBQ2pJLEtBQUssTUFBTSxDQUFDLGVBQWUsRUFBRSxVQUFVLENBQUMsSUFBSSxZQUFZLENBQUMsT0FBTyxFQUFFLEVBQUUsQ0FBQztRQUNuRSxNQUFNLFFBQVEsR0FBRyxjQUFjLGVBQWUsRUFBRSxDQUFBO1FBRWhELElBQUksQ0FBQyxVQUFVLElBQUksVUFBVSxDQUFDLElBQUks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Q0FBQyxHQUFHLENBQUMsQ0FBQTtJQUM1RixJQUFJLFVBQVUsQ0FBQyxJQUFJLElBQUksMEJBQTBCO1FBQUUsT0FBTyxDQUFDLFVBQVUsQ0FBQyxVQUFVLENBQUMsQ0FBQTtJQUNqRixJQUFJLFVBQVUsQ0FBQyxJQUFJLElBQUksWUFBWTtRQUFFLE9BQU8sQ0FBQyxVQUFVLENBQUMsUUFBUSxDQUFDLENBQUE7SUFDakUsSUFBSSxVQUFVLENBQUMsSUFBSSxJQUFJLGtCQUFrQjtRQUFFLE9BQU8sQ0FBQyxVQUFVLENBQUMsUUFBUSxDQUFDLENBQUE7SUFDdkUsSUFBSSxVQUFVLENBQUMsSUFBSSxJQUFJLGtCQUFrQjtRQUFFLE9BQU8sQ0FBQyxVQUFVLENBQUMsUUFBUSxDQUFDLENBQUE7SUFDdkUsT0FBTyxFQUFFLENBQUE7QUFDWCxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiLy8gQHRzLWNoZWNrXG5cbmltcG9ydCB7YXV0aG9yaXplZE9wZXJhdGlvbiwgaXNUYXNrMDM0T3BlcmF0aW9uTmFtZX0gZnJvbSBcIi4vY2FwYWJpbGl0aWVzLmpzXCJcbmltcG9ydCB7cGFyc2VQcm90ZWN0ZWRFbnRyeU5hbWV9IGZyb20gXCIuL3N0ZGxpYi5qc1wiXG5cbi8qKiBAdHlwZWRlZiB7e2ZhaWx1cmVJZHM6IFNldDxzdHJpbmc+LCBob3N0OiBib29sZWFufX0gRWZmZWN0U3VtbWFyeSAqL1xuLyoqIEB0eXBlZGVmIHsoZXhwcmVzc2lvbjogaW1wb3J0KFwiLi90eXBlcy5qc1wiKS5FeHByZXNzaW9uKSA9PiB2b2lkfSBFeHByZXNzaW9uVmlzaXRvciAqL1xuXG4vKipcbiAqIFJlc29sdmVzIGNvbXBpbGVyLWF1dGhvcml6ZWQgY2FsbHMgYmVmb3JlIG9yZGluYXJ5IHNlbWFudGljIHR5cGUgdmFsaWRhdGlvbi5cbiAqIFNvdXJjZSBmdW5jdGlvbnMgYWx3YXlzIHdpbjsgYXV0aG9yaXR5IGlzIG5ldmVyIGluZmVycmVkIGZyb20gc3BlbGxpbmcgYWxvbmUuXG4gKiBAcGFyYW0ge2ltcG9ydChcIi4vdHlwZXMuanNcIikuU2VtYW50aWNNb2R1bGV9IG1vZHVsZSAtIFBhcnNlci1hdXRob3JlZCBtb2R1bGUuXG4gKiBAcGFyYW0ge3N0cmluZ30gbGFuZ3VhZ2UgLSBTb3VyY2UgbGFuZ3VhZ2UgaWRlbnRpdHkgZm9yIHByb3RlY3RlZCBlbnRyeSB0YXJnZXRzLlxuICogQHBhcmFtIHtNYXA8c3RyaW5nLCBpbXBvcnQoXCIuL3R5cGVzLmpzXCIpLkZ1bmN0aW9uRGVjbGFyYXRpb24+fSBmdW5jdGlvbnMgLSBWaXNpYmxlIG9yZGluYXJ5IGZ1bmN0aW9ucy5cbiAqIEBwYXJhbSB7KGNvZGU6IHN0cmluZywgZGV0YWlsOiBzdHJpbmcsIGxvY2F0aW9uOiBpbXBvcnQoXCIuL3R5cGVzLmpzXCIpLlNvdXJjZUxvY2F0aW9uKSA9PiBuZXZlcn0gZmFpbCAtIExvY2F0ZWQgZmFpbHVyZS5cbiAqIEBwYXJhbSB7Ym9vbGVhbn0gbm9ybWFsaXplIC0gV2hldGhlciBwYXJzZXItYXV0aG9yZWQgb3BlcmF0aW9uIGludGVudCBtYXkgYmUgbm9ybWFsaXplZC5cbiAqIEBwYXJhbSB7TWFwPHN0cmluZywgaW1wb3J0KFwiLi90eXBlcy5qc1wiKS5DbGFzc0RlY2xhcmF0aW9uPn0gW3Zpc2libGVDbGFzc2VzXSAtIFJlc29sdmVkIHJlZmVyZW5jZSBjbGFzc2VzLlxuICogQHJldHVybnMge3ZvaWR9XG4gKi9cbmV4cG9ydCBmdW5jdGlvbiB2YWxpZGF0ZUVmZmVjdEdyYXBoKG1vZHVsZSwgbGFuZ3VhZ2UsIGZ1bmN0aW9ucywgZmFpbCwgbm9ybWFsaXplLCB2aXNpYmxlQ2xhc3NlcyA9IG5ldyBNYXAoKSkge1xuICBjb25zdCBjYXBhYmlsaXRpZXMgPSBtb2R1bGUuY2FwYWJpbGl0aWVzID8/IFtdXG4gIGNvbnN0IGNhcGFiaWxpdHlJZHMgPSBuZXcgU2V0KClcbiAgY29uc3Qgb3BlcmF0aW9uSWRzID0gbmV3IFNldCgpXG4gIGNvbnN0IHJlc291cmNlSWRzID0gbmV3IFNldCgpXG4gIGNvbnN0IGZhaWx1cmVJZHMgPSBuZXcgU2V0KClcbiAgY29uc3Qgb3BlcmF0aW9uTmFtZXMgPSBuZXcgU2V0KClcblxuICBpZiAoIUFycmF5LmlzQXJyYXkoY2FwYWJpbGl0aWVzKSkgZmFpbChcIklOVkFMSURfQ0FQQUJJTElUWV9BVVRIT1JJVFlcIiwgXCJDYXBhYmlsaXRpZXMgbXVzdCBiZSBhbiBvcmRlcmVkIGFycmF5LlwiLCBtb2R1bGUubG9jYXRpb24pXG4gIGZvciAoY29uc3QgW2NhcGFiaWxpdHlJbmRleCwgY2FwYWJpbGl0eV0gb2YgY2FwYWJpbGl0aWVzLmVudHJpZXMoKSkge1xuICAgIGNvbnN0IGxlZ2FjeUlkID0gYGNhcGFiaWxpdHk6JHtjYXBhYmlsaXR5SW5kZXh9YFxuXG4gICAgaWYgKCFjYXBhYmlsaXR5IHx8IGNhcGFiaWxpdHkua2luZCAhPSBcIkVmZmVjdENhcGFiaWxpdHlEZWNsYXJhdGlvblwiIHx8XG4gICAgICBjYXBhYmlsaXR5LmlkICE9IGxlZ2FjeUlkICYmICEvXm1vZHVsZTpcXGQrXFwvY2FwYWJpbGl0eTpcXGQrJC91LnRlc3QoY2FwYWJpbGl0eS5pZCkgfHwgY2FwYWJpbGl0eUlkcy5oYXMoY2FwYWJpbGl0eS5pZCkgfHxcbiAgICAgIHR5cGVvZiBjYXBhYmlsaXR5LmF1dGhvcml0eUlkICE9IFwic3RyaW5nXCIgfHwgdHlwZW9mIGNhcGFiaWxpdHkubmFtZSAhPSBcInN0cmluZ1wiIHx8ICFBcnJheS5pc0FycmF5KGNhcGFiaWxpdHkucmVzb3VyY2VzKSB8fFxuICAgICAgIUFycmF5LmlzQXJyYXkoY2FwYWJpbGl0eS5mYWlsdXJlcykgfHwgIUFycmF5LmlzQXJyYXkoY2FwYWJpbGl0eS5vcGVyYXRpb25zKSkge1xuICAgICAgZmFpbChcIklOVkFMSURfQ0FQQUJJTElUWV9BVVRIT1JJVFlcIiwgXCJNYWxmb3JtZWQgY2FwYWJpbGl0eSBkZWNsYXJhdGlvbiBncmFwaC5cIiwgbW9kdWxlLmxvY2F0aW9uKVxuICAgIH1cbiAgICBjYXBhYmlsaXR5SWRzLmFkZChjYXBhYmlsaXR5LmlkKVxuICAgIGZvciAoY29uc3QgW2luZGV4LCByZXNvdXJjZV0gb2YgY2FwYWJpbGl0eS5yZXNvdXJjZXMuZW50cmllcygpKSB7XG4gICAgICBpZiAocmVzb3VyY2Uua2luZCAhPSBcIkVmZmVjdFJlc291cmNlRGVjbGFyYXRpb25cIiB8fCByZXNvdXJjZS5pZCAhPSBgJHtjYXBhYmlsaXR5LmlkfS9yZXNvdXJjZToke2luZGV4fWAgfHxcbiAgICAgICAgcmVzb3VyY2VJZHMuaGFzKHJlc291cmNlLmlkKSkgZmFpbChcIklOVkFMSURfQ0FQQUJJTElUWV9BVVRIT1JJVFlcIiwgXCJNYWxmb3JtZWQgY2FwYWJpbGl0eSByZXNvdXJjZSBpZGVudGl0eS5cIiwgbW9kdWxlLmxvY2F0aW9uKVxuICAgICAgcmVzb3VyY2VJZHMuYWRkKHJlc291cmNlLmlkKVxuICAgIH1cbiAgICBmb3IgKGNvbnN0IFtpbmRleCwgZmFpbHVyZV0gb2YgY2FwYWJpbGl0eS5mYWlsdXJlcy5lbnRyaWVzKCkpIHtcbiAgICAgIGlmIChmYWlsdXJlLmtpbmQgIT0gXCJFZmZlY3RGYWlsdXJlRGVjbGFyYXRpb25cIiB8fCBmYWlsdXJlLmlkICE9IGAke2NhcGFiaWxpdHkuaWR9L2ZhaWx1cmU6JHtpbmRleH1gIHx8XG4gICAgICAgIGZhaWx1cmVJZHMuaGFzKGZhaWx1cmUuaWQpKSBmYWlsKFwiSU5WQUxJRF9DQVBBQklMSVRZX0FVVEhPUklUWVwiLCBcIk1hbGZvcm1lZCBjYXBhYmlsaXR5IGZhaWx1cmUgaWRlbnRpdHkuXCIsIG1vZHVsZS5sb2NhdGlvbilcbiAgICAgIGZhaWx1cmVJZHMuYWRkKGZhaWx1cmUuaWQpXG4gICAgfVxuICB9XG4gIGZvciAoY29uc3QgY2FwYWJpbGl0eSBvZiBjYXBhYmlsaXRpZXMpIHtcbiAgICBmb3IgKGNvbnN0IFtpbmRleCwgb3BlcmF0aW9uXSBvZiBjYXBhYmlsaXR5Lm9wZXJhdGlvbnMuZW50cmllcygpKSB7XG4gICAgICBpZiAob3BlcmF0aW9uLmtpbmQgIT0gXCJFZmZlY3RPcGVyYXRpb25EZWNsYXJhdGlvblwiIHx8IG9wZXJhdGlvbi5pZCAhPSBgJHtjYXBhYmlsaXR5LmlkfS9vcGVyYXRpb246JHtpbmRleH1gIHx8XG4gICAgICAgIG9wZXJhdGlvbklkcy5oYXMob3BlcmF0aW9uLmlkKSB8fCBvcGVyYXRpb25OYW1lcy5oYXMob3BlcmF0aW9uLm5hbWUpIHx8ICFBcnJheS5pc0FycmF5KG9wZXJhdGlvbi5wYXJhbWV0ZXJzKSB8fFxuICAgICAgICAhQXJyYXkuaXNBcnJheShvcGVyYXRpb24uZmFpbHVyZUlkcykgfHwgb3BlcmF0aW9uLmVmZmVjdHM/Lmxlbmd0aCAhPSAxIHx8IG9wZXJhdGlvbi5lZmZlY3RzWzBdICE9IFwiaG9zdFwiIHx8XG4gICAgICAgIG9wZXJhdGlvbi5mYWlsdXJlSWRzLnNvbWUoKGlkKSA9PiAhZmFpbHVyZUlkcy5oYXMoaWQpKSkge1xuICAgICAgICBmYWlsKFwiSU5WQUxJRF9DQVBBQklMSVRZX0FVVEhPUklUWVwiLCBcIk1hbGZvcm1lZCBvciBhbWJpZ3VvdXMgY2FwYWJpbGl0eSBvcGVyYXRpb24gZ3JhcGguXCIsIG1vZHVsZS5sb2NhdGlvbilcbiAgICAgIH1cbiAgICAgIG9wZXJhdGlvbklkcy5hZGQob3BlcmF0aW9uLmlkKVxuICAgICAgb3BlcmF0aW9uTmFtZXMuYWRkKG9wZXJhdGlvbi5uYW1lKVxuICAgIH1cbiAgfVxuXG4gIGZvciAoY29uc3QgZGVjbGFyYXRpb24gb2YgW1xuICAgIC4uLm1vZHVsZS5mdW5jdGlvbnMsXG4gICAgLi4uKG1vZHVsZS5yZWNvcmRzID8/IFtdKSxcbiAgICAuLi4obW9kdWxlLmNsYXNzZXMgPz8gW10pLFxuICAgIC4uLihtb2R1bGUuZXJyb3JzID8/IFtdKVxuICBdKSB7XG4gICAgaWYgKHBhcnNlUHJvdGVjdGVkRW50cnlOYW1lKGRlY2xhcmF0aW9uLm5hbWUpICE9PSBudWxsKSB7XG4gICAgICBmYWlsKFwiU1RETElCX1BST1RFQ1RFRF9CSU5ESU5HX0FDQ0VTU1wiLFxuICAgICAgICBgU291cmNlIGRlY2xhcmF0aW9uICcke2RlY2xhcmF0aW9uLm5hbWV9JyBjYXB0dXJlcyBhIHJlc2VydmVkIHByb3RlY3RlZCBwcm92aWRlciBiaW5kaW5nLmAsIGRlY2xhcmF0aW9uLmxvY2F0aW9uKVxuICAgIH1cbiAgfVxuXG4gIGZvckVhY2hFeHByZXNzaW9uKG1vZHVsZSwgKGV4cHJlc3Npb24pID0+IHtcbiAgICBpZiAoZXhwcmVzc2lvbi5raW5kID09IFwiRWZmZWN0Q2FsbEV4cHJlc3Npb25cIikge1xuICAgICAgY29uc3QgY2FwYWJpbGl0eSA9IGNhcGFiaWxpdGllcy5maW5kKCh7aWR9KSA9PiBpZCA9PSBleHByZXNzaW9uLnJlc29sdXRpb24/LmNhcGFiaWxpdHlJZClcbiAgICAgIGNvbnN0IG9wZXJhdGlvbiA9IGNhcGFiaWxpdHk/Lm9wZXJhdGlvbnMuZmluZCgoe2lkfSkgPT4gaWQgPT0gZXhwcmVzc2lvbi5vcGVyYXRpb24pXG5cbiAgICAgIGlmIChvcGVyYXRpb24gJiYgZXhwcmVzc2lvbi5yZXNvbHV0aW9uLm9wZXJhdGlvbklkID09IG9wZXJhdGlvbi5pZCAmJlxuICAgICAgICAoIUFycmF5LmlzQXJyYXkoZXhwcmVzc2lvbi5yZXNvbHV0aW9uLmZhaWx1cmVJZHMpIHx8XG4gICAgICAgICAgZXhwcmVzc2lvbi5yZXNvbHV0aW9uLmZhaWx1cmVJZHMuam9pbihcIixcIikgIT0gb3BlcmF0aW9uLmZhaWx1cmVJZHMuam9pbihcIixcIikpKSB7XG4gICAgICAgIGZhaWwoXCJVTkRFQ0xBUkVEX0ZBSUxVUkVcIiwgXCJVTkRFQ0xBUkVEX0ZBSUxVUkU6IEVmZmVjdCBjYWxsIGZhaWx1cmUgYm91bmRhcnkgZG9lcyBub3QgbWF0Y2ggaXRzIGNvbXBpbGVyIGF1dGhvcml0eS5cIixcbiAgICAgICAgICBleHByZXNzaW9uLmxvY2F0aW9uKVxuICAgICAgfVxuICAgICAgaWYgKCFvcGVyYXRpb24gfHwgZXhwcmVzc2lvbi5yZXNvbHV0aW9uLm9wZXJhdGlvbklkICE9IG9wZXJhdGlvbi5pZCB8fFxuICAgICAgICBKU09OLnN0cmluZ2lmeShleHByZXNzaW9uLnJlc29sdXRpb24pICE9IEpTT04uc3RyaW5naWZ5KHNpZ25hdHVyZSgvKiogQHR5cGUge2ltcG9ydChcIi4vdHlwZXMuanNcIikuRWZmZWN0Q2FwYWJpbGl0eURlY2xhcmF0aW9ufSAqLyAoY2FwYWJpbGl0eSksIG9wZXJhdGlvbikpKSB7XG4gICAgICAgIGZhaWwoXCJVTkRFQ0xBUkVEX0VGRkVDVFwiLCBcIkVmZmVjdCBjYWxsIHJlc29sdXRpb24gZG9lcyBub3QgbWF0Y2ggaXRzIGNvbXBpbGVyIGF1dGhvcml0eS5cIiwgZXhwcmVzc2lvbi5sb2NhdGlvbilcbiAgICAgIH1cbiAgICAgIHJldHVyblxuICAgIH1cbiAgICBpZiAoZXhwcmVzc2lvbi5raW5kID09IFwiSWRlbnRpZmllckV4cHJlc3Npb25cIiAmJiBwYXJzZVByb3RlY3RlZEVudHJ5TmFtZShleHByZXNzaW9uLm5hbWUpICE9PSBudWxsKSB7XG4gICAgICBmYWlsKFwiU1RETElCX1BST1RFQ1RFRF9CSU5ESU5HX0FDQ0VTU1wiLFxuICAgICAgICBgUmVmZXJlbmNlIHRvIHByb3RlY3RlZCBwcm92aWRlciBlbnRyeSAnJHtleHByZXNzaW9uLm5hbWV9JyBpcyBub3QgcG9ydGFibGUgY29kZS5gLCBleHByZXNzaW9uLmxvY2F0aW9uKVxuICAgIH1cbiAgICBpZiAoZXhwcmVzc2lvbi5raW5kICE9IFwiQ2FsbEV4cHJlc3Npb25cIikgcmV0dXJuXG4gICAgaWYgKGZ1bmN0aW9ucy5oYXMoZXhwcmVzc2lvbi5jYWxsZWUpKSByZXR1cm5cbiAgICBsZXQgb3BlcmF0aW9uTmFtZSA9IGV4cHJlc3Npb24uY2FsbGVlXG4gICAgY29uc3QgcHJvdGVjdGVkRW50cnkgPSBwYXJzZVByb3RlY3RlZEVudHJ5TmFtZShleHByZXNzaW9uLmNhbGxlZSlcblxuICAgIGlmIChwcm90ZWN0ZWRFbnRyeSAhPT0gbnVsbCkge1xuICAgICAgaWYgKGNhcGFiaWxpdGllcy5sZW5ndGggPT0gMCkge1xuICAgICAgICBmYWlsKFwiU1RETElCX1BST1RFQ1RFRF9CSU5ESU5HX0FDQ0VTU1wiLFxuICAgICAgICAgIGBQcm90ZWN0ZWQgcHJvdmlkZXIgZW50cnkgJyR7ZXhwcmVzc2lvbi5jYWxsZWV9JyByZXF1aXJlcyBhbiBleHBsaWNpdCBjYXBhYmlsaXR5IGF1dGhvcml0eS5gLCBleHByZXNzaW9uLmxvY2F0aW9uKVxuICAgICAgfVxuICAgICAgaWYgKHByb3RlY3RlZEVudHJ5LnRhcmdldCAhPSBsYW5ndWFnZSkge1xuICAgICAgICBmYWlsKFwiU1RETElCX1BST1RFQ1RFRF9CSU5ESU5HX0FDQ0VTU1wiLFxuICAgICAgICAgIGBQcm90ZWN0ZWQgcHJvdmlkZXIgZW50cnkgdGFyZ2V0ICcke3Byb3RlY3RlZEVudHJ5LnRhcmdldH0nIGRvZXMgbm90IG1hdGNoIHNvdXJjZSBsYW5ndWFnZSAnJHtsYW5ndWFnZX0nLmAsXG4gICAgICAgICAgZXhwcmVzc2lvbi5sb2NhdGlvbilcbiAgICAgIH1cbiAgICAgIG9wZXJhdGlvbk5hbWUgPSBwcm90ZWN0ZWRFbnRyeS5vcGVyYXRpb25cbiAgICB9XG4gICAgY29uc3QgbWF0Y2ggPSBhdXRob3JpemVkT3BlcmF0aW9uKGNhcGFiaWxpdGllcywgb3BlcmF0aW9uTmFtZSlcblxuICAgIGlmICghbWF0Y2gpIHtcbiAgICAgIGlmIChwcm90ZWN0ZWRFbnRyeSAhPT0gbnVsbCkge1xuICAgICAgICBmYWlsKFwiU1RETElCX1BST1RFQ1RFRF9CSU5ESU5HX0FDQ0VTU1wiLFxuICAgICAgICAgIGBQcm90ZWN0ZWQgcHJvdmlkZXIgZW50cnkgZm9yIHVuZGVjbGFyZWQgb3BlcmF0aW9uICcke29wZXJhdGlvbk5hbWV9JyBoYXMgbm8gYXV0aG9yaXplZCBjYXBhYmlsaXR5IG9wZXJhdGlvbi5gLFxuICAgICAgICAgIGV4cHJlc3Npb24ubG9jYXRpb24pXG4gICAgICB9XG4gICAgICBpZiAoaXNUYXNrMDM0T3BlcmF0aW9uTmFtZShvcGVyYXRpb25OYW1lKSkge1xuICAgICAgICBmYWlsKFwiTUlTU0lOR19DQVBBQklMSVRZX0FVVEhPUklUWVwiLCBgT3BlcmF0aW9uICcke29wZXJhdGlvbk5hbWV9JyByZXF1aXJlcyBleHBsaWNpdCBjb21waWxlciBhdXRob3JpdHkuYCwgZXhwcmVzc2lvbi5sb2NhdGlvbilcbiAgICAgIH1cbiAgICAgIHJldHVyblxuICAgIH1cbiAgICBpZiAoIW5vcm1hbGl6ZSkge1xuICAgICAgZmFpbChcIlVOREVDTEFSRURfRUZGRUNUXCIsIGBDYWxsZXItYXV0aG9yZWQgb3JkaW5hcnkgY2FsbCAnJHtleHByZXNzaW9uLmNhbGxlZX0nIGNhbm5vdCBmb3JnZSBhIGNhcGFiaWxpdHkgb3BlcmF0aW9uLmAsIGV4cHJlc3Npb24ubG9jYXRpb24pXG4gICAgfVxuICAgIGNvbnN0IHtjYXBhYmlsaXR5LCBvcGVyYXRpb259ID0gbWF0Y2hcbiAgICBjb25zdCBmbG93ID0gb3BlcmF0aW9uLnJlc291cmNlRmxvd1xuXG4gICAgaWYgKChmbG93LmtpbmQgPT0gXCJib3Jyb3dcIiB8fCBmbG93LmtpbmQgPT0gXCJjbG9zZVwiKSAmJiBleHByZXNzaW9uLmFyZ3VtZW50c1tmbG93LnBhcmFtZXRlckluZGV4XSkge1xuICAgICAgY29uc3QgYXJndW1lbnQgPSBleHByZXNzaW9uLmFyZ3VtZW50c1tmbG93LnBhcmFtZXRlckluZGV4XVxuICAgICAgaWYgKGFyZ3VtZW50LmtpbmQgIT0gXCJJZGVudGlmaWVyRXhwcmVzc2lvblwiICYmIGFyZ3VtZW50LmtpbmQgIT0gXCJQcml2YXRlRmllbGRSZWFkXCIgJiYgYXJndW1lbnQua2luZCAhPSBcIlJlY2VpdmVyRXhwcmVzc2lvblwiKSB7XG4gICAgICAgIGZhaWwoXCJJTlZBTElEX1JFU09VUkNFX0JPUlJPV1wiLCBcIkFuIG93bmVkIGJvcnJvdyBtdXN0IG5hbWUgb25lIGltbWVkaWF0ZSByZXNvdXJjZSBwbGFjZS5cIiwgYXJndW1lbnQubG9jYXRpb24pXG4gICAgICB9XG4gICAgICBleHByZXNzaW9uLmFyZ3VtZW50c1tmbG93LnBhcmFtZXRlckluZGV4XSA9IHtcbiAgICAgICAgZXhwcmVzc2lvbjogYXJndW1lbnQsXG4gICAgICAgIGtpbmQ6IFwiT3duZWRCb3Jyb3dFeHByZXNzaW9uXCIsXG4gICAgICAgIGxvY2F0aW9uOiBhcmd1bWVudC5sb2NhdGlvbixcbiAgICAgICAgbW9kZTogZmxvdy5raW5kID09IFwiY2xvc2VcIiA/IFwiZXhjbHVzaXZlXCIgOiBcInNoYXJlZFwiLFxuICAgICAgICBzb3VyY2VQcm92ZW5hbmNlOiBhcmd1bWVudC5zb3VyY2VQcm92ZW5hbmNlLFxuICAgICAgICB0eXBlOiAvKiogQHR5cGUge2ltcG9ydChcIi4vdHlwZXMuanNcIikuT3duZWRSZXNvdXJjZVR5cGUgfCBpbXBvcnQoXCIuL3R5cGVzLmpzXCIpLk93bmVkUmVmZXJlbmNlVHlwZX0gKi8gKFxuICAgICAgICAgIG9wZXJhdGlvbi5wYXJhbWV0ZXJzW2Zsb3cucGFyYW1ldGVySW5kZXhdLnR5cGVcbiAgICAgICAgKVxuICAgICAgfVxuICAgIH1cbiAgICBjb25zdCByZXBsYWNlbWVudCA9IC8qKiBAdHlwZSB7aW1wb3J0KFwiLi90eXBlcy5qc1wiKS5FZmZlY3RDYWxsRXhwcmVzc2lvbn0gKi8gKC8qKiBAdHlwZSB7dW5rbm93bn0gKi8gKGV4cHJlc3Npb24pKVxuICAgIGRlbGV0ZSAvKiogQHR5cGUge3tjYWxsZWU/OiBzdHJpbmd9fSAqLyAocmVwbGFjZW1lbnQpLmNhbGxlZVxuICAgIHJlcGxhY2VtZW50LmtpbmQgPSBcIkVmZmVjdENhbGxFeHByZXNzaW9uXCJcbiAgICByZXBsYWNlbWVudC5vcGVyYXRpb24gPSBvcGVyYXRpb24uaWRcbiAgICByZXBsYWNlbWVudC5yZXNvbHV0aW9uID0gc2lnbmF0dXJlKGNhcGFiaWxpdHksIG9wZXJhdGlvbilcbiAgfSlcblxuICBjb25zdCBjb21wbGV0ZSA9IGNvbXBsZXRlRWZmZWN0U3VtbWFyaWVzKG1vZHVsZSwgZmFpbHVyZUlkcywgdmlzaWJsZUNsYXNzZXMpXG4gIGNvbnN0IHN1bW1hcmllcyA9IGNvbXBsZXRlLmZ1bmN0aW9uc1xuICBjb25zdCBtZXRob2RTdW1tYXJpZXMgPSBjb21wbGV0ZS5tZXRob2RzXG4gIGNvbnN0IGNvbnN0cnVjdG9yU3VtbWFyaWVzID0gY29tcGxldGUuY29uc3RydWN0b3JzXG5cbiAgZm9yIChjb25zdCBkZWNsYXJhdGlvbiBvZiBtb2R1bGUuY2xhc3NlcyA/PyBbXSkge1xuICAgIGFwcGx5RGVjbGFyYXRpb25TdW1tYXJ5KGRlY2xhcmF0aW9uLmNvbnN0cnVjdG9yLFxuICAgICAgY29uc3RydWN0b3JTdW1tYXJpZXMuZ2V0KC8qKiBAdHlwZSB7c3RyaW5nfSAqLyAoZGVjbGFyYXRpb24uY29uc3RydWN0b3IuaWQpKSwgbm9ybWFsaXplLCBmYWlsKVxuICAgIGZvciAoY29uc3QgbWV0aG9kIG9mIGRlY2xhcmF0aW9uLm1ldGhvZHMpIHtcbiAgICAgIGFwcGx5RGVjbGFyYXRpb25TdW1tYXJ5KG1ldGhvZCwgbWV0aG9kU3VtbWFyaWVzLmdldCgvKiogQHR5cGUge3N0cmluZ30gKi8gKG1ldGhvZC5pZCkpLCBub3JtYWxpemUsIGZhaWwpXG4gICAgfVxuICB9XG4gIGxldCBzaXRlID0gMFxuXG4gIGZvckVhY2hFeHByZXNzaW9uKG1vZHVsZSwgKGV4cHJlc3Npb24pID0+IHtcbiAgICBpZiAoZXhwcmVzc2lvbi5raW5kID09IFwiRWZmZWN0Q2FsbEV4cHJlc3Npb25cIikge1xuICAgICAgaWYgKG5vcm1hbGl6ZSkgZXhwcmVzc2lvbi5lZmZlY3RTaXRlSWQgPSBgZWZmZWN0OiR7c2l0ZX1gXG4gICAgICBlbHNlIHZhbGlkYXRlU2l0ZShleHByZXNzaW9uLCBzaXRlLCBmYWlsKVxuICAgICAgc2l0ZSArPSAxXG4gICAgICByZXR1cm5cbiAgICB9XG4gICAgaWYgKGV4cHJlc3Npb24ua2luZCA9PSBcIkNhbGxFeHByZXNzaW9uXCIpIHtcbiAgICAgIGNvbnN0IHN1bW1hcnkgPSBzdW1tYXJpZXMuZ2V0KGV4cHJlc3Npb24uY2FsbGVlKVxuICAgICAgaWYgKCFzdW1tYXJ5Py5ob3N0KSB7XG4gICAgICAgIGlmIChub3JtYWxpemUpIHtcbiAgICAgICAgICBkZWxldGUgZXhwcmVzc2lvbi5lZmZlY3RTaXRlSWRcbiAgICAgICAgICBkZWxldGUgZXhwcmVzc2lvbi5lZmZlY3RzXG4gICAgICAgICAgZGVsZXRlIGV4cHJlc3Npb24uZmFpbHVyZUlkc1xuICAgICAgICB9XG4gICAgICAgIGlmICghbm9ybWFsaXplICYmIEFycmF5LmlzQXJyYXkoZXhwcmVzc2lvbi5mYWlsdXJlSWRzKSAmJiBleHByZXNzaW9uLmZhaWx1cmVJZHMubGVuZ3RoID4gMCkge1xuICAgICAgICAgIGZhaWwoXCJVTkRFQ0xBUkVEX0ZBSUxVUkVcIiwgXCJVTkRFQ0xBUkVEX0ZBSUxVUkU6IFB1cmUgY2FsbCBjYXJyaWVzIGEgZm9yZ2VkIHR5cGVkIGZhaWx1cmUgYm91bmRhcnkuXCIsIGV4cHJlc3Npb24ubG9jYXRpb24pXG4gICAgICAgIH1cbiAgICAgICAgaWYgKCFub3JtYWxpemUgJiYgKGV4cHJlc3Npb24uZWZmZWN0U2l0ZUlkICE9PSB1bmRlZmluZWQgfHwgZXhwcmVzc2lvbi5lZmZlY3RzICE9PSB1bmRlZmluZWQgfHwgZXhwcmVzc2lvbi5mYWlsdXJlSWRzICE9PSB1bmRlZmluZWQpKSB7XG4gICAgICAgICAgZmFpbChcIlVOREVDTEFSRURfRUZGRUNUXCIsIFwiUHVyZSBjYWxsIGNhcnJpZXMgZm9yZ2VkIGVmZmVjdCBtZXRhZGF0YS5cIiwgZXhwcmVzc2lvbi5sb2NhdGlvbilcbiAgICAgICAgfVxuICAgICAgICByZXR1cm5cbiAgICAgIH1cbiAgICAgIGlmIChub3JtYWxpemUpIHtcbiAgICAgICAgZXhwcmVzc2lvbi5lZmZlY3RTaXRlSWQgPSBgZWZmZWN0OiR7c2l0ZX1gXG4gICAgICAgIGV4cHJlc3Npb24uZWZmZWN0cyA9IFtcImhvc3RcIl1cbiAgICAgICAgZXhwcmVzc2lvbi5mYWlsdXJlSWRzID0gWy4uLnN1bW1hcnkuZmFpbHVyZUlkc11cbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHZhbGlkYXRlU2l0ZShleHByZXNzaW9uLCBzaXRlLCBmYWlsKVxuICAgICAgICBpZiAoIUFycmF5LmlzQXJyYXkoZXhwcmVzc2lvbi5mYWlsdXJlSWRzKSB8fCBleHByZXNzaW9uLmZhaWx1cmVJZHMuam9pbihcIixcIikgIT0gWy4uLnN1bW1hcnkuZmFpbHVyZUlkc10uam9pbihcIixcIikpIHtcbiAgICAgICAgICBmYWlsKFwiVU5ERUNMQVJFRF9GQUlMVVJFXCIsIFwiVU5ERUNMQVJFRF9GQUlMVVJFOiBDYWxsIGZhaWx1cmUgYm91bmRhcnkgZG9lcyBub3QgbWF0Y2ggaXRzIHJlc29sdmVkIGZ1bmN0aW9uLlwiLCBleHByZXNzaW9uLmxvY2F0aW9uKVxuICAgICAgICB9XG4gICAgICAgIGlmIChleHByZXNzaW9uLmVmZmVjdHM/Lmxlbmd0aCAhPSAxIHx8IGV4cHJlc3Npb24uZWZmZWN0c1swXSAhPSBcImhvc3RcIikge1xuICAgICAgICAgIGZhaWwoXCJVTkRFQ0xBUkVEX0VGRkVDVFwiLCBcIkNhbGwgZWZmZWN0IHN1bW1hcnkgZG9lcyBub3QgbWF0Y2ggaXRzIHJlc29sdmVkIGZ1bmN0aW9uLlwiLCBleHByZXNzaW9uLmxvY2F0aW9uKVxuICAgICAgICB9XG4gICAgICB9XG4gICAgICBzaXRlICs9IDFcbiAgICAgIHJldHVyblxuICAgIH1cbiAgICBpZiAoZXhwcmVzc2lvbi5raW5kID09IFwiTWV0aG9kQ2FsbEV4cHJlc3Npb25cIiB8fCBleHByZXNzaW9uLmtpbmQgPT0gXCJSZWZlcmVuY2VDb25zdHJ1Y3Rpb25cIikge1xuICAgICAgY29uc3Qgc3VtbWFyeSA9IGV4cHJlc3Npb24ua2luZCA9PSBcIk1ldGhvZENhbGxFeHByZXNzaW9uXCJcbiAgICAgICAgPyBtZXRob2RTdW1tYXJpZXMuZ2V0KGV4cHJlc3Npb24ubWV0aG9kKVxuICAgICAgICA6IGNvbnN0cnVjdG9yU3VtbWFyaWVzLmdldChleHByZXNzaW9uLnJlc29sdXRpb24/LmRlY2xhcmF0aW9uSWQgPz8gYCR7ZXhwcmVzc2lvbi5yZWZlcmVuY2UuZGVjbGFyYXRpb25JZH06Y29uc3RydWN0b3JgKVxuICAgICAgY29uc3QgbGFiZWwgPSBleHByZXNzaW9uLmtpbmQgPT0gXCJNZXRob2RDYWxsRXhwcmVzc2lvblwiID8gXCJtZXRob2QgY2FsbFwiIDogXCJjb25zdHJ1Y3Rpb25cIlxuICAgICAgaWYgKCFzdW1tYXJ5Py5ob3N0KSB7XG4gICAgICAgIGlmIChub3JtYWxpemUpIHtcbiAgICAgICAgICBkZWxldGUgZXhwcmVzc2lvbi5lZmZlY3RTaXRlSWRcbiAgICAgICAgICBkZWxldGUgZXhwcmVzc2lvbi5lZmZlY3RzXG4gICAgICAgICAgZGVsZXRlIGV4cHJlc3Npb24uZmFpbHVyZUlkc1xuICAgICAgICB9XG4gICAgICAgIGlmICghbm9ybWFsaXplICYmIEFycmF5LmlzQXJyYXkoZXhwcmVzc2lvbi5mYWlsdXJlSWRzKSAmJiBleHByZXNzaW9uLmZhaWx1cmVJZHMubGVuZ3RoID4gMCkge1xuICAgICAgICAgIGZhaWwoXCJVTkRFQ0xBUkVEX0ZBSUxVUkVcIiwgYFVOREVDTEFSRURfRkFJTFVSRTogUHVyZSAke2xhYmVsfSBjYXJyaWVzIGEgZm9yZ2VkIHR5cGVkIGZhaWx1cmUgYm91bmRhcnkuYCwgZXhwcmVzc2lvbi5sb2NhdGlvbilcbiAgICAgICAgfVxuICAgICAgICBpZiAoIW5vcm1hbGl6ZSAmJiAoZXhwcmVzc2lvbi5lZmZlY3RTaXRlSWQgIT09IHVuZGVmaW5lZCB8fCBleHByZXNzaW9uLmVmZmVjdHMgIT09IHVuZGVmaW5lZCB8fCBleHByZXNzaW9uLmZhaWx1cmVJZHMgIT09IHVuZGVmaW5lZCkpIHtcbiAgICAgICAgICBmYWlsKFwiVU5ERUNMQVJFRF9FRkZFQ1RcIiwgYFB1cmUgJHtsYWJlbH0gY2FycmllcyBmb3JnZWQgZWZmZWN0IG1ldGFkYXRhLmAsIGV4cHJlc3Npb24ubG9jYXRpb24pXG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuXG4gICAgICB9XG4gICAgICBpZiAobm9ybWFsaXplKSB7XG4gICAgICAgIGV4cHJlc3Npb24uZWZmZWN0U2l0ZUlkID0gYGVmZmVjdDoke3NpdGV9YFxuICAgICAgICBleHByZXNzaW9uLmVmZmVjdHMgPSBbXCJob3N0XCJdXG4gICAgICAgIGV4cHJlc3Npb24uZmFpbHVyZUlkcyA9IFsuLi5zdW1tYXJ5LmZhaWx1cmVJZHNdXG4gICAgICB9IGVsc2Uge1xuICAgICAgICB2YWxpZGF0ZVNpdGUoZXhwcmVzc2lvbiwgc2l0ZSwgZmFpbClcbiAgICAgICAgaWYgKCFBcnJheS5pc0FycmF5KGV4cHJlc3Npb24uZmFpbHVyZUlkcykgfHwgZXhwcmVzc2lvbi5mYWlsdXJlSWRzLmpvaW4oXCIsXCIpICE9IFsuLi5zdW1tYXJ5LmZhaWx1cmVJZHNdLmpvaW4oXCIsXCIpKSB7XG4gICAgICAgICAgZmFpbChcIlVOREVDTEFSRURfRkFJTFVSRVwiLCBgVU5ERUNMQVJFRF9GQUlMVVJFOiAke2xhYmVsfSBmYWlsdXJlIGJvdW5kYXJ5IGRvZXMgbm90IG1hdGNoIGl0cyByZXNvbHZlZCBkZWNsYXJhdGlvbi5gLCBleHByZXNzaW9uLmxvY2F0aW9uKVxuICAgICAgICB9XG4gICAgICAgIGlmIChleHByZXNzaW9uLmVmZmVjdHM/Lmxlbmd0aCAhPSAxIHx8IGV4cHJlc3Npb24uZWZmZWN0c1swXSAhPSBcImhvc3RcIikge1xuICAgICAgICAgIGZhaWwoXCJVTkRFQ0xBUkVEX0VGRkVDVFwiLCBgJHtsYWJlbH0gZWZmZWN0IHN1bW1hcnkgZG9lcyBub3QgbWF0Y2ggaXRzIHJlc29sdmVkIGRlY2xhcmF0aW9uLmAsIGV4cHJlc3Npb24ubG9jYXRpb24pXG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIHNpdGUgKz0gMVxuICAgIH1cbiAgfSwgdHJ1ZSlcbn1cblxuLyoqXG4gKiBDb21wdXRlcyB0aGUgam9pbnQgZmluaXRlIGZpeGVkIHBvaW50IGFjcm9zcyBmdW5jdGlvbnMgYW5kIHJlc29sdmVkIHJlY2VpdmVyIG1ldGhvZHMuXG4gKiBAcGFyYW0ge2ltcG9ydChcIi4vdHlwZXMuanNcIikuU2VtYW50aWNNb2R1bGV9IG1vZHVsZSAtIFJlc29sdmVkIG1vZHVsZS5cbiAqIEBwYXJhbSB7U2V0PHN0cmluZz59IGNhcGFiaWxpdHlGYWlsdXJlSWRzIC0gRGVjbGFyZWQgY2FwYWJpbGl0eSBmYWlsdXJlcy5cbiAqIEBwYXJhbSB7TWFwPHN0cmluZywgaW1wb3J0KFwiLi90eXBlcy5qc1wiKS5DbGFzc0RlY2xhcmF0aW9uPn0gdmlzaWJsZUNsYXNzZXMgLSBSZXNvbHZlZCByZWZlcmVuY2UgY2xhc3Nlcy5cbiAqIEByZXR1cm5zIHt7Y29uc3RydWN0b3JzOiBNYXA8c3RyaW5nLCBFZmZlY3RTdW1tYXJ5PiwgZnVuY3Rpb25zOiBNYXA8c3RyaW5nLCBFZmZlY3RTdW1tYXJ5PiwgbWV0aG9kczogTWFwPHN0cmluZywgRWZmZWN0U3VtbWFyeT59fSBDb21wbGV0ZSBzdW1tYXJpZXMuXG4gKi9cbmZ1bmN0aW9uIGNvbXBsZXRlRWZmZWN0U3VtbWFyaWVzKG1vZHVsZSwgY2FwYWJpbGl0eUZhaWx1cmVJZHMsIHZpc2libGVDbGFzc2VzKSB7XG4gIGNvbnN0IGltcG9ydGVkTWV0aG9kcyA9IGRlY2xhcmVkQ2xhc3NTdW1tYXJpZXModmlzaWJsZUNsYXNzZXMsIFwibWV0aG9kc1wiKVxuICBsZXQgZnVuY3Rpb25zID0gZWZmZWN0U3VtbWFyaWVzKG1vZHVsZS5mdW5jdGlvbnMsIG5ldyBNYXAoKSwgY2FwYWJpbGl0eUZhaWx1cmVJZHMpXG4gIGxldCBtZXRob2RzID0gZGlyZWN0TWV0aG9kU3VtbWFyaWVzKG1vZHVsZSwgZnVuY3Rpb25zLCBpbXBvcnRlZE1ldGhvZHMsIGNhcGFiaWxpdHlGYWlsdXJlSWRzLCBpbXBvcnRlZE1ldGhvZHMpXG5cbiAgd2hpbGUgKHRydWUpIHtcbiAgICBjb25zdCBuZXh0RnVuY3Rpb25zID0gZWZmZWN0U3VtbWFyaWVzKG1vZHVsZS5mdW5jdGlvbnMsIG1ldGhvZHMsIGNhcGFiaWxpdHlGYWlsdXJlSWRzKVxuICAgIGNvbnN0IG5leHRNZXRob2RzID0gZGlyZWN0TWV0aG9kU3VtbWFyaWVzKG1vZHVsZSwgbmV4dEZ1bmN0aW9ucywgbWV0aG9kcywgY2FwYWJpbGl0eUZhaWx1cmVJZHMsIGltcG9ydGVkTWV0aG9kcylcblxuICAgIGlmIChzYW1lU3VtbWFyaWVzKGZ1bmN0aW9ucywgbmV4dEZ1bmN0aW9ucykgJiYgc2FtZVN1bW1hcmllcyhtZXRob2RzLCBuZXh0TWV0aG9kcykpIHtcbiAgICAgIHJldHVybiB7Y29uc3RydWN0b3JzOiBkaXJlY3RDb25zdHJ1Y3RvclN1bW1hcmllcyhtb2R1bGUsIG5leHRGdW5jdGlvbnMsIG5leHRNZXRob2RzLCBjYXBhYmlsaXR5RmFpbHVyZUlkcyxcbiAgICAgICAgZGVjbGFyZWRDbGFzc1N1bW1hcmllcyh2aXNpYmxlQ2xhc3NlcywgXCJjb25zdHJ1Y3RvcnNcIikpLCBmdW5jdGlvbnM6IG5leHRGdW5jdGlvbnMsIG1ldGhvZHM6IG5leHRNZXRob2RzfVxuICAgIH1cbiAgICBmdW5jdGlvbnMgPSBuZXh0RnVuY3Rpb25zXG4gICAgbWV0aG9kcyA9IG5leHRNZXRob2RzXG4gIH1cbn1cblxuLyoqXG4gKiBDb21wYXJlcyBzdGFibGUgaG9zdC9mYWlsdXJlIHN1bW1hcnkgbWFwcy5cbiAqIEBwYXJhbSB7TWFwPHN0cmluZywgRWZmZWN0U3VtbWFyeT59IGxlZnQgLSBQcmV2aW91cyBzdW1tYXJpZXMuXG4gKiBAcGFyYW0ge01hcDxzdHJpbmcsIEVmZmVjdFN1bW1hcnk+fSByaWdodCAtIE5leHQgc3VtbWFyaWVzLlxuICogQHJldHVybnMge2Jvb2xlYW59IFdoZXRoZXIgdGhlIHN1bW1hcmllcyBhcmUgaWRlbnRpY2FsLlxuICovXG5mdW5jdGlvbiBzYW1lU3VtbWFyaWVzKGxlZnQsIHJpZ2h0KSB7XG4gIGlmIChsZWZ0LnNpemUgIT0gcmlnaHQuc2l6ZSkgcmV0dXJuIGZhbHNlXG4gIGZvciAoY29uc3QgW25hbWUsIHN1bW1hcnldIG9mIGxlZnQpIHtcbiAgICBjb25zdCBjYW5kaWRhdGUgPSByaWdodC5nZXQobmFtZSlcblxuICAgIGlmICghY2FuZGlkYXRlIHx8IHN1bW1hcnkuaG9zdCAhPSBjYW5kaWRhdGUuaG9zdCB8fCBzdW1tYXJ5LmZhaWx1cmVJZHMuc2l6ZSAhPSBjYW5kaWRhdGUuZmFpbHVyZUlkcy5zaXplIHx8XG4gICAgICBbLi4uc3VtbWFyeS5mYWlsdXJlSWRzXS5zb21lKChpZCkgPT4gIWNhbmRpZGF0ZS5mYWlsdXJlSWRzLmhhcyhpZCkpKSByZXR1cm4gZmFsc2VcbiAgfVxuICByZXR1cm4gdHJ1ZVxufVxuXG4vKipcbiAqIEJ1aWxkcyB0aGUgY29tcGxldGUgaW1tdXRhYmxlIHJlc29sdXRpb24gcmVjb3JkZWQgYXQgYW4gZWZmZWN0IGNhbGwgc2l0ZS5cbiAqIEBwYXJhbSB7aW1wb3J0KFwiLi90eXBlcy5qc1wiKS5FZmZlY3RDYXBhYmlsaXR5RGVjbGFyYXRpb259IGNhcGFiaWxpdHkgLSBEZWNsYXJpbmcgY2FwYWJpbGl0eS5cbiAqIEBwYXJhbSB7aW1wb3J0KFwiLi90eXBlcy5qc1wiKS5FZmZlY3RPcGVyYXRpb25EZWNsYXJhdGlvbn0gb3BlcmF0aW9uIC0gUmVzb2x2ZWQgb3BlcmF0aW9uLlxuICogQHJldHVybnMge2ltcG9ydChcIi4vdHlwZXMuanNcIikuUmVzb2x2ZWRFZmZlY3RPcGVyYXRpb25TaWduYXR1cmV9IENvbXBsZXRlIHJlc29sdXRpb24uXG4gKi9cbmZ1bmN0aW9uIHNpZ25hdHVyZShjYXBhYmlsaXR5LCBvcGVyYXRpb24pIHtcbiAgcmV0dXJuIHtcbiAgICBjYXBhYmlsaXR5SWQ6IGNhcGFiaWxpdHkuaWQsXG4gICAgZWZmZWN0czogLyoqIEB0eXBlIHtjb25zdH0gKi8gKFtcImhvc3RcIl0pLFxuICAgIGZhaWx1cmVJZHM6IFsuLi5vcGVyYXRpb24uZmFpbHVyZUlkc10sXG4gICAga2luZDogLyoqIEB0eXBlIHtjb25zdH0gKi8gKFwiUmVzb2x2ZWRFZmZlY3RPcGVyYXRpb25TaWduYXR1cmVcIiksXG4gICAgb3BlcmF0aW9uSWQ6IG9wZXJhdGlvbi5pZCxcbiAgICBwYXJhbWV0ZXJUeXBlczogb3BlcmF0aW9uLnBhcmFtZXRlcnMubWFwKCh7dHlwZX0pID0+IC8qKiBAdHlwZSB7aW1wb3J0KFwiLi90eXBlcy5qc1wiKS5TZW1hbnRpY1R5cGVJZGVudGl0eX0gKi8gKHR5cGVJZGVudGl0eSh0eXBlKSkpLFxuICAgIHJlc291cmNlRmxvdzogc3RydWN0dXJlZENsb25lKG9wZXJhdGlvbi5yZXNvdXJjZUZsb3cpLFxuICAgIHJldHVyblR5cGU6IHR5cGVJZGVudGl0eShvcGVyYXRpb24ucmV0dXJuVHlwZSlcbiAgfVxufVxuXG4vKipcbiAqIFJlbW92ZXMgbG9jYXRpb25zIGFuZCBwcm92ZW5hbmNlIGZyb20gb25lIHJlc29sdmVkIHR5cGUuXG4gKiBAcGFyYW0ge2ltcG9ydChcIi4vdHlwZXMuanNcIikuU2VtYW50aWNGdW5jdGlvblJldHVyblR5cGV9IHR5cGUgLSBTZW1hbnRpYyB0eXBlLlxuICogQHJldHVybnMge2ltcG9ydChcIi4vdHlwZXMuanNcIikuRnVuY3Rpb25SZXR1cm5UeXBlSWRlbnRpdHl9IFN0YWJsZSB0eXBlIGlkZW50aXR5LlxuICovXG5mdW5jdGlvbiB0eXBlSWRlbnRpdHkodHlwZSkge1xuICBpZiAodHlwZS5raW5kID09IFwiVHlwZVJlZmVyZW5jZVwiKSByZXR1cm4gdHlwZS5uYW1lXG4gIGlmICh0eXBlLmtpbmQgPT0gXCJPd25lZFJlc291cmNlVHlwZVwiKSByZXR1cm4ge2tpbmQ6IHR5cGUua2luZCwgcmVzb3VyY2VJZDogdHlwZS5yZXNvdXJjZUlkfVxuICBpZiAodHlwZS5raW5kID09IFwiT3duZWRSZWZlcmVuY2VUeXBlXCIpIHJldHVybiB7ZGVjbGFyYXRpb25JZDogdHlwZS5kZWNsYXJhdGlvbklkLCBraW5kOiB0eXBlLmtpbmR9XG4gIGlmICh0eXBlLmtpbmQgPT0gXCJPcHRpb25hbFR5cGVcIikgcmV0dXJuIHtraW5kOiB0eXBlLmtpbmQsXG4gICAgdmFsdWVUeXBlOiAvKiogQHR5cGUge2ltcG9ydChcIi4vdHlwZXMuanNcIikuU2VtYW50aWNUeXBlSWRlbnRpdHl9ICovICh0eXBlSWRlbnRpdHkodHlwZS52YWx1ZVR5cGUpKX1cbiAgaWYgKHR5cGUua2luZCA9PSBcIkxpc3RUeXBlXCIpIHJldHVybiB7XG4gICAgZWxlbWVudFR5cGU6IC8qKiBAdHlwZSB7aW1wb3J0KFwiLi90eXBlcy5qc1wiKS5TZW1hbnRpY1R5cGVJZGVudGl0eX0gKi8gKHR5cGVJZGVudGl0eSh0eXBlLmVsZW1lbnRUeXBlKSksIGtpbmQ6IHR5cGUua2luZH1cbiAgaWYgKHR5cGUua2luZCA9PSBcIk1hcFR5cGVcIiB8fCB0eXBlLmtpbmQgPT0gXCJPcmRlcmVkTWFwVHlwZVwiKSB7XG4gICAgY29uc3Qga2V5VHlwZSA9IC8qKiBAdHlwZSB7aW1wb3J0KFwiLi90eXBlcy5qc1wiKS5TZW1hbnRpY1R5cGVJZGVudGl0eX0gKi8gKHR5cGVJZGVudGl0eSh0eXBlLmtleVR5cGUpKVxuICAgIGNvbnN0IHZhbHVlVHlwZSA9IC8qKiBAdHlwZSB7aW1wb3J0KFwiLi90eXBlcy5qc1wiKS5TZW1hbnRpY1R5cGVJZGVudGl0eX0gKi8gKHR5cGVJZGVudGl0eSh0eXBlLnZhbHVlVHlwZSkpXG5cbiAgICByZXR1cm4gdHlwZS5raW5kID09IFwiT3JkZXJlZE1hcFR5cGVcIiA/IHtrZXlUeXBlLCBraW5kOiB0eXBlLmtpbmQsIG9yZGVyOiBcImluc2VydGlvblwiLCB2YWx1ZVR5cGV9IDpcbiAgICAgIHtrZXlUeXBlLCBraW5kOiB0eXBlLmtpbmQsIHZhbHVlVHlwZX1cbiAgfVxuICBpZiAodHlwZS5raW5kID09IFwiUmVjb3JkVHlwZVwiKSByZXR1cm4ge2FyZ3VtZW50czogdHlwZS5hcmd1bWVudHM/Lm1hcCgoYXJndW1lbnQpID0+XG4gICAgLyoqIEB0eXBlIHtpbXBvcnQoXCIuL3R5cGVzLmpzXCIpLlNlbWFudGljVHlwZUlkZW50aXR5fSAqLyAodHlwZUlkZW50aXR5KGFyZ3VtZW50KSkpLCBkZWNsYXJhdGlvbklkOiB0eXBlLmRlY2xhcmF0aW9uSWQsIGtpbmQ6IHR5cGUua2luZH1cbiAgaWYgKHR5cGUua2luZCA9PSBcIlJlZmVyZW5jZVR5cGVcIikgcmV0dXJuIHtkZWNsYXJhdGlvbklkOiB0eXBlLmRlY2xhcmF0aW9uSWQsIGtpbmQ6IHR5cGUua2luZH1cbiAgcmV0dXJuIHtraW5kOiB0eXBlLmtpbmQsIHBhcmFtZXRlcklkOiB0eXBlLnBhcmFtZXRlcklkfVxufVxuXG4vKipcbiAqIENvbXB1dGVzIHRoZSBmaXhlZC1wb2ludCBob3N0LWVmZmVjdCBzdW1tYXJ5IGZvciBvcmRpbmFyeSBmdW5jdGlvbnMuXG4gKiBAcGFyYW0ge2ltcG9ydChcIi4vdHlwZXMuanNcIikuRnVuY3Rpb25EZWNsYXJhdGlvbltdfSBmdW5jdGlvbnMgLSBNb2R1bGUgZnVuY3Rpb25zLlxuICogQHBhcmFtIHtNYXA8c3RyaW5nLCBFZmZlY3RTdW1tYXJ5Pn0gW21ldGhvZFN1bW1hcmllc10gLSBSZWNlaXZlci1jYWxsIHN1bW1hcmllcyBmcm9tIHRoZSBjdXJyZW50IGZpeGVkLXBvaW50IHJvdW5kLlxuICogQHBhcmFtIHtTZXQ8c3RyaW5nPn0gW2NhcGFiaWxpdHlGYWlsdXJlSWRzXSAtIENhcGFiaWxpdHkgZmFpbHVyZXMgZWxpZ2libGUgZm9yIGNhbGwtc2l0ZSBwcm9wYWdhdGlvbi5cbiAqIEByZXR1cm5zIHtNYXA8c3RyaW5nLCBFZmZlY3RTdW1tYXJ5Pn0gU3VtbWFyaWVzIGJ5IHNvdXJjZSBmdW5jdGlvbiBuYW1lLlxuICovXG5mdW5jdGlvbiBlZmZlY3RTdW1tYXJpZXMoZnVuY3Rpb25zLCBtZXRob2RTdW1tYXJpZXMgPSBuZXcgTWFwKCksIGNhcGFiaWxpdHlGYWlsdXJlSWRzID0gbmV3IFNldCgpKSB7XG4gIGNvbnN0IHN1bW1hcmllcyA9IG5ldyBNYXAoZnVuY3Rpb25zLm1hcCgoe25hbWV9KSA9PiAvKiogQHR5cGUge1tzdHJpbmcsIEVmZmVjdFN1bW1hcnldfSAqLyAoXG4gICAgW25hbWUsIHtmYWlsdXJlSWRzOiBuZXcgU2V0KCksIGhvc3Q6IGZhbHNlfV1cbiAgKSkpXG4gIGxldCBjaGFuZ2VkID0gdHJ1ZVxuXG4gIHdoaWxlIChjaGFuZ2VkKSB7XG4gICAgY2hhbmdlZCA9IGZhbHNlXG4gICAgZm9yIChjb25zdCBkZWNsYXJhdGlvbiBvZiBmdW5jdGlvbnMpIHtcbiAgICAgIGNvbnN0IHN1bW1hcnkgPSBzdW1tYXJpZXMuZ2V0KGRlY2xhcmF0aW9uLm5hbWUpXG4gICAgICBpZiAoIXN1bW1hcnkpIGNvbnRpbnVlXG4gICAgICBmb3JFYWNoQmxvY2tFeHByZXNzaW9uKGRlY2xhcmF0aW9uLmJvZHksIChleHByZXNzaW9uKSA9PiB7XG4gICAgICAgIGlmIChleHByZXNzaW9uLmtpbmQgPT0gXCJFZmZlY3RDYWxsRXhwcmVzc2lvblwiKSB7XG4gICAgICAgICAgaWYgKCFzdW1tYXJ5Lmhvc3QpIHsgc3VtbWFyeS5ob3N0ID0gdHJ1ZTsgY2hhbmdlZCA9IHRydWUgfVxuICAgICAgICB9IGVsc2UgaWYgKGV4cHJlc3Npb24ua2luZCA9PSBcIkNhbGxFeHByZXNzaW9uXCIpIHtcbiAgICAgICAgICBjb25zdCBjYWxsZWQgPSBzdW1tYXJpZXMuZ2V0KGV4cHJlc3Npb24uY2FsbGVlKVxuICAgICAgICAgIGlmIChjYWxsZWQ/Lmhvc3QgJiYgIXN1bW1hcnkuaG9zdCkgeyBzdW1tYXJ5Lmhvc3QgPSB0cnVlOyBjaGFuZ2VkID0gdHJ1ZSB9XG4gICAgICAgIH0gZWxzZSBpZiAoZXhwcmVzc2lvbi5raW5kID09IFwiTWV0aG9kQ2FsbEV4cHJlc3Npb25cIikge1xuICAgICAgICAgIGNvbnN0IGNhbGxlZCA9IG1ldGhvZFN1bW1hcmllcy5nZXQoZXhwcmVzc2lvbi5tZXRob2QpXG4gICAgICAgICAgaWYgKGNhbGxlZD8uaG9zdCAmJiAhc3VtbWFyeS5ob3N0KSB7IHN1bW1hcnkuaG9zdCA9IHRydWU7IGNoYW5nZWQgPSB0cnVlIH1cbiAgICAgICAgfVxuICAgICAgfSwgZmFsc2UpXG4gICAgICBjb25zdCBlc2NhcGluZyA9IGVzY2FwaW5nQmxvY2tGYWlsdXJlcyhkZWNsYXJhdGlvbi5ib2R5LCBzdW1tYXJpZXMsIG1ldGhvZFN1bW1hcmllcywgY2FwYWJpbGl0eUZhaWx1cmVJZHMpXG5cbiAgICAgIGZvciAoY29uc3QgaWQgb2YgZXNjYXBpbmcpIGlmICghc3VtbWFyeS5mYWlsdXJlSWRzLmhhcyhpZCkpIHsgc3VtbWFyeS5mYWlsdXJlSWRzLmFkZChpZCk7IGNoYW5nZWQgPSB0cnVlIH1cbiAgICB9XG4gIH1cbiAgcmV0dXJuIHN1bW1hcmllc1xufVxuXG4vKipcbiAqIENvbXB1dGVzIHRoZSBjYXBhYmlsaXR5IGZhaWx1cmVzIGVzY2FwaW5nIG9uZSBzdHJ1Y3R1cmVkIGJsb2NrLlxuICogQHBhcmFtIHtpbXBvcnQoXCIuL3R5cGVzLmpzXCIpLkJsb2NrfSBibG9jayAtIEZ1bmN0aW9uIGJvZHkuXG4gKiBAcGFyYW0ge01hcDxzdHJpbmcsIEVmZmVjdFN1bW1hcnk+fSBmdW5jdGlvblN1bW1hcmllcyAtIEN1cnJlbnQgZnVuY3Rpb24gZml4ZWQgcG9pbnQuXG4gKiBAcGFyYW0ge01hcDxzdHJpbmcsIEVmZmVjdFN1bW1hcnk+fSBtZXRob2RTdW1tYXJpZXMgLSBSZXNvbHZlZCBtZXRob2Qgc3VtbWFyaWVzLlxuICogQHBhcmFtIHtTZXQ8c3RyaW5nPn0gY2FwYWJpbGl0eUZhaWx1cmVJZHMgLSBEZWNsYXJlZCBjYXBhYmlsaXR5IGZhaWx1cmVzLlxuICogQHJldHVybnMge1NldDxzdHJpbmc+fSBFc2NhcGluZyBmYWlsdXJlIGlkZW50aXRpZXMuXG4gKi9cbmZ1bmN0aW9uIGVzY2FwaW5nQmxvY2tGYWlsdXJlcyhibG9jaywgZnVuY3Rpb25TdW1tYXJpZXMsIG1ldGhvZFN1bW1hcmllcywgY2FwYWJpbGl0eUZhaWx1cmVJZHMpIHtcbiAgY29uc3QgcmVzdWx0ID0gbmV3IFNldCgpXG5cbiAgZm9yIChjb25zdCBzdGF0ZW1lbnQgb2YgYmxvY2suc3RhdGVtZW50cykge1xuICAgIGlmIChzdGF0ZW1lbnQua2luZCA9PSBcIlRyeVN0YXRlbWVudFwiKSB7XG4gICAgICBjb25zdCBib2R5ID0gZXNjYXBpbmdCbG9ja0ZhaWx1cmVzKHN0YXRlbWVudC5ib2R5LCBmdW5jdGlvblN1bW1hcmllcywgbWV0aG9kU3VtbWFyaWVzLCBjYXBhYmlsaXR5RmFpbHVyZUlkcylcblxuICAgICAgaWYgKGJvZHkuZGVsZXRlKHN0YXRlbWVudC5jYXRjaFR5cGUuZGVjbGFyYXRpb25JZCkpIHtcbiAgICAgICAgYWRkRmFpbHVyZXMocmVzdWx0LCBlc2NhcGluZ0Jsb2NrRmFpbHVyZXMoc3RhdGVtZW50LmNhdGNoQm9keSwgZnVuY3Rpb25TdW1tYXJpZXMsIG1ldGhvZFN1bW1hcmllcywgY2FwYWJpbGl0eUZhaWx1cmVJZHMpKVxuICAgICAgfVxuICAgICAgYWRkRmFpbHVyZXMocmVzdWx0LCBib2R5KVxuICAgICAgY29udGludWVcbiAgICB9XG4gICAgZm9yIChjb25zdCBleHByZXNzaW9uIG9mIHN0YXRlbWVudEV4cHJlc3Npb25zKHN0YXRlbWVudCkpIHtcbiAgICAgIGFkZEV4cHJlc3Npb25GYWlsdXJlcyhyZXN1bHQsIGV4cHJlc3Npb24sIGZ1bmN0aW9uU3VtbWFyaWVzLCBtZXRob2RTdW1tYXJpZXMpXG4gICAgfVxuICAgIGlmIChzdGF0ZW1lbnQua2luZCA9PSBcIlJhaXNlU3RhdGVtZW50XCIgJiYgY2FwYWJpbGl0eUZhaWx1cmVJZHMuaGFzKHN0YXRlbWVudC5lcnJvci5lcnJvci5kZWNsYXJhdGlvbklkKSkge1xuICAgICAgcmVzdWx0LmFkZChzdGF0ZW1lbnQuZXJyb3IuZXJyb3IuZGVjbGFyYXRpb25JZClcbiAgICB9XG4gICAgZm9yIChjb25zdCBjaGlsZCBvZiBzdGF0ZW1lbnRCbG9ja3Moc3RhdGVtZW50KSkge1xuICAgICAgYWRkRmFpbHVyZXMocmVzdWx0LCBlc2NhcGluZ0Jsb2NrRmFpbHVyZXMoY2hpbGQsIGZ1bmN0aW9uU3VtbWFyaWVzLCBtZXRob2RTdW1tYXJpZXMsIGNhcGFiaWxpdHlGYWlsdXJlSWRzKSlcbiAgICB9XG4gIH1cbiAgcmV0dXJuIHJlc3VsdFxufVxuXG4vKipcbiAqIEFkZHMgZmFpbHVyZXMgZXZhbHVhdGVkIGJ5IG9uZSBleHByZXNzaW9uIHN1YnRyZWUuXG4gKiBAcGFyYW0ge1NldDxzdHJpbmc+fSB0YXJnZXQgLSBEZXN0aW5hdGlvbiBpZGVudGl0aWVzLlxuICogQHBhcmFtIHtpbXBvcnQoXCIuL3R5cGVzLmpzXCIpLkV4cHJlc3Npb259IGV4cHJlc3Npb24gLSBFeHByZXNzaW9uIHJvb3QuXG4gKiBAcGFyYW0ge01hcDxzdHJpbmcsIEVmZmVjdFN1bW1hcnk+fSBmdW5jdGlvblN1bW1hcmllcyAtIEZ1bmN0aW9uIHN1bW1hcmllcy5cbiAqIEBwYXJhbSB7TWFwPHN0cmluZywgRWZmZWN0U3VtbWFyeT59IG1ldGhvZFN1bW1hcmllcyAtIE1ldGhvZCBzdW1tYXJpZXMuXG4gKiBAcmV0dXJucyB7dm9pZH1cbiAqL1xuZnVuY3Rpb24gYWRkRXhwcmVzc2lvbkZhaWx1cmVzKHRhcmdldCwgZXhwcmVzc2lvbiwgZnVuY3Rpb25TdW1tYXJpZXMsIG1ldGhvZFN1bW1hcmllcykge1xuICBpZiAoZXhwcmVzc2lvbi5raW5kID09IFwiRWZmZWN0Q2FsbEV4cHJlc3Npb25cIikgYWRkRmFpbHVyZXModGFyZ2V0LCBleHByZXNzaW9uLnJlc29sdXRpb24uZmFpbHVyZUlkcylcbiAgZWxzZSBpZiAoZXhwcmVzc2lvbi5raW5kID09IFwiQ2FsbEV4cHJlc3Npb25cIikgYWRkRmFpbHVyZXModGFyZ2V0LCBmdW5jdGlvblN1bW1hcmllcy5nZXQoZXhwcmVzc2lvbi5jYWxsZWUpPy5mYWlsdXJlSWRzID8/IFtdKVxuICBlbHNlIGlmIChleHByZXNzaW9uLmtpbmQgPT0gXCJNZXRob2RDYWxsRXhwcmVzc2lvblwiKSBhZGRGYWlsdXJlcyh0YXJnZXQsIG1ldGhvZFN1bW1hcmllcy5nZXQoZXhwcmVzc2lvbi5tZXRob2QpPy5mYWlsdXJlSWRzID8/IFtdKVxuICBmb3IgKGNvbnN0IGNoaWxkIG9mIGV4cHJlc3Npb25DaGlsZHJlbihleHByZXNzaW9uKSkgYWRkRXhwcmVzc2lvbkZhaWx1cmVzKHRhcmdldCwgY2hpbGQsIGZ1bmN0aW9uU3VtbWFyaWVzLCBtZXRob2RTdW1tYXJpZXMpXG59XG5cbi8qKlxuICogUmV0dXJucyBkaXJlY3RseSBldmFsdWF0ZWQgZXhwcmVzc2lvbnMgZm9yIG9uZSBzdGF0ZW1lbnQuXG4gKiBAcGFyYW0ge2ltcG9ydChcIi4vdHlwZXMuanNcIikuU3RhdGVtZW50fSBzdGF0ZW1lbnQgLSBTdGF0ZW1lbnQuXG4gKiBAcmV0dXJucyB7aW1wb3J0KFwiLi90eXBlcy5qc1wiKS5FeHByZXNzaW9uW119IEV4cHJlc3Npb24gcm9vdHMuXG4gKi9cbmZ1bmN0aW9uIHN0YXRlbWVudEV4cHJlc3Npb25zKHN0YXRlbWVudCkge1xuICBpZiAoc3RhdGVtZW50LmtpbmQgPT0gXCJMb2NhbERlY2xhcmF0aW9uXCIpIHJldHVybiBbc3RhdGVtZW50LmluaXRpYWxpemVyXVxuICBpZiAoc3RhdGVtZW50LmtpbmQgPT0gXCJBc3NpZ25tZW50U3RhdGVtZW50XCIgfHwgc3RhdGVtZW50LmtpbmQgPT0gXCJQcml2YXRlRmllbGRXcml0ZVN0YXRlbWVudFwiIHx8XG4gICAgc3RhdGVtZW50LmtpbmQgPT0gXCJFeHByZXNzaW9uU3RhdGVtZW50XCIgfHwgc3RhdGVtZW50LmtpbmQgPT0gXCJQcmludFN0YXRlbWVudFwiKSByZXR1cm4gW3N0YXRlbWVudC5leHByZXNzaW9uXVxuICBpZiAoc3RhdGVtZW50LmtpbmQgPT0gXCJSZXR1cm5TdGF0ZW1lbnRcIikgcmV0dXJuIHN0YXRlbWVudC5leHByZXNzaW9uID8gW3N0YXRlbWVudC5leHByZXNzaW9uXSA6IFtdXG4gIGlmIChzdGF0ZW1lbnQua2luZCA9PSBcIlJhaXNlU3RhdGVtZW50XCIpIHJldHVybiBbc3RhdGVtZW50LmVycm9yLm1lc3NhZ2VdXG4gIGlmIChzdGF0ZW1lbnQua2luZCA9PSBcIklmU3RhdGVtZW50XCIgfHwgc3RhdGVtZW50LmtpbmQgPT0gXCJXaGlsZVN0YXRlbWVudFwiKSByZXR1cm4gW3N0YXRlbWVudC5jb25kaXRpb25dXG4gIGlmIChzdGF0ZW1lbnQua2luZCA9PSBcIkZvckVhY2hTdGF0ZW1lbnRcIikgcmV0dXJuIFtzdGF0ZW1lbnQubGlzdF1cbiAgaWYgKHN0YXRlbWVudC5raW5kID09IFwiRm9yRWFjaE1hcFN0YXRlbWVudFwiKSByZXR1cm4gW3N0YXRlbWVudC5tYXBdXG4gIHJldHVybiBbXVxufVxuXG4vKipcbiAqIFJldHVybnMgbmVzdGVkIGJsb2NrcyB3aG9zZSBmYWlsdXJlcyBwcm9wYWdhdGUgdGhyb3VnaCBvbmUgc3RhdGVtZW50LlxuICogQHBhcmFtIHtpbXBvcnQoXCIuL3R5cGVzLmpzXCIpLlN0YXRlbWVudH0gc3RhdGVtZW50IC0gU3RhdGVtZW50LlxuICogQHJldHVybnMge2ltcG9ydChcIi4vdHlwZXMuanNcIikuQmxvY2tbXX0gQ2hpbGQgYmxvY2tzLlxuICovXG5mdW5jdGlvbiBzdGF0ZW1lbnRCbG9ja3Moc3RhdGVtZW50KSB7XG4gIGlmIChzdGF0ZW1lbnQua2luZCA9PSBcIklmU3RhdGVtZW50XCIpIHJldHVybiBbc3RhdGVtZW50LmNvbnNlcXVlbnQsIC4uLihzdGF0ZW1lbnQuYWx0ZXJuYXRlID8gW3N0YXRlbWVudC5hbHRlcm5hdGVdIDogW10pXVxuICBpZiAoc3RhdGVtZW50LmtpbmQgPT0gXCJXaGlsZVN0YXRlbWVudFwiIHx8IHN0YXRlbWVudC5raW5kID09IFwiRm9yRWFjaFN0YXRlbWVudFwiIHx8IHN0YXRlbWVudC5raW5kID09IFwiRm9yRWFjaE1hcFN0YXRlbWVudFwiKSB7XG4gICAgcmV0dXJuIFtzdGF0ZW1lbnQuYm9keV1cbiAgfVxuICByZXR1cm4gW11cbn1cblxuLyoqXG4gKiBBZGRzIGFuIGl0ZXJhYmxlIG9mIGZhaWx1cmUgaWRlbnRpdGllcyB0byBhIHNldC5cbiAqIEBwYXJhbSB7U2V0PHN0cmluZz59IHRhcmdldCAtIERlc3RpbmF0aW9uLlxuICogQHBhcmFtIHtJdGVyYWJsZTxzdHJpbmc+fSBzb3VyY2UgLSBTb3VyY2UgaWRlbnRpdGllcy5cbiAqIEByZXR1cm5zIHt2b2lkfVxuICovXG5mdW5jdGlvbiBhZGRGYWlsdXJlcyh0YXJnZXQsIHNvdXJjZSkge1xuICBmb3IgKGNvbnN0IGlkIG9mIHNvdXJjZSkgdGFyZ2V0LmFkZChpZClcbn1cblxuLyoqXG4gKiBDb21wdXRlcyBib3VuZGVkIGRpcmVjdCBzdW1tYXJpZXMgZm9yIGNsYXNzIG1ldGhvZHMuXG4gKiBAcGFyYW0ge2ltcG9ydChcIi4vdHlwZXMuanNcIikuU2VtYW50aWNNb2R1bGV9IG1vZHVsZSAtIFJlc29sdmVkIG1vZHVsZS5cbiAqIEBwYXJhbSB7TWFwPHN0cmluZywgRWZmZWN0U3VtbWFyeT59IGZ1bmN0aW9uU3VtbWFyaWVzIC0gT3JkaW5hcnkgZnVuY3Rpb24gc3VtbWFyaWVzLlxuICogQHBhcmFtIHtNYXA8c3RyaW5nLCBFZmZlY3RTdW1tYXJ5Pn0gcHJpb3JNZXRob2RTdW1tYXJpZXMgLSBSZWNlaXZlciBzdW1tYXJpZXMgZnJvbSB0aGUgcHJldmlvdXMgZml4ZWQtcG9pbnQgcm91bmQuXG4gKiBAcGFyYW0ge1NldDxzdHJpbmc+fSBjYXBhYmlsaXR5RmFpbHVyZUlkcyAtIERlY2xhcmVkIGNhcGFiaWxpdHkgZmFpbHVyZXMuXG4gKiBAcGFyYW0ge01hcDxzdHJpbmcsIEVmZmVjdFN1bW1hcnk+fSBiYXNlU3VtbWFyaWVzIC0gSW1wb3J0ZWQgcmVjZWl2ZXIgc3VtbWFyaWVzLlxuICogQHJldHVybnMge01hcDxzdHJpbmcsIEVmZmVjdFN1bW1hcnk+fSBTdW1tYXJpZXMgYnkgcmVzb2x2ZWQgbWV0aG9kIGlkZW50aXR5LlxuICovXG5mdW5jdGlvbiBkaXJlY3RNZXRob2RTdW1tYXJpZXMobW9kdWxlLCBmdW5jdGlvblN1bW1hcmllcywgcHJpb3JNZXRob2RTdW1tYXJpZXMsIGNhcGFiaWxpdHlGYWlsdXJlSWRzLCBiYXNlU3VtbWFyaWVzID0gbmV3IE1hcCgpKSB7XG4gIC8qKiBAdHlwZSB7TWFwPHN0cmluZywgRWZmZWN0U3VtbWFyeT59ICovXG4gIGNvbnN0IHN1bW1hcmllcyA9IG5ldyBNYXAoYmFzZVN1bW1hcmllcylcblxuICBmb3IgKGNvbnN0IGRlY2xhcmF0aW9uIG9mIG1vZHVsZS5jbGFzc2VzID8/IFtdKSB7XG4gICAgZm9yIChjb25zdCBtZXRob2Qgb2YgZGVjbGFyYXRpb24ubWV0aG9kcykge1xuICAgICAgLyoqIEB0eXBlIHtFZmZlY3RTdW1tYXJ5fSAqL1xuICAgICAgY29uc3Qgc3VtbWFyeSA9IHtmYWlsdXJlSWRzOiBlc2NhcGluZ0Jsb2NrRmFpbHVyZXMobWV0aG9kLmJvZHksIGZ1bmN0aW9uU3VtbWFyaWVzLCBwcmlvck1ldGhvZFN1bW1hcmllcywgY2FwYWJpbGl0eUZhaWx1cmVJZHMpLCBob3N0OiBmYWxzZX1cblxuICAgICAgZm9yRWFjaEJsb2NrRXhwcmVzc2lvbihtZXRob2QuYm9keSwgKGV4cHJlc3Npb24pID0+IHtcbiAgICAgICAgaWYgKGV4cHJlc3Npb24ua2luZCA9PSBcIkVmZmVjdENhbGxFeHByZXNzaW9uXCIpIHtcbiAgICAgICAgICBzdW1tYXJ5Lmhvc3QgPSB0cnVlXG4gICAgICAgICAgY29uc3QgZmxvdyA9IGV4cHJlc3Npb24ucmVzb2x1dGlvbi5yZXNvdXJjZUZsb3dcbiAgICAgICAgICBjb25zdCBhcmd1bWVudCA9IGZsb3cua2luZCA9PSBcImJvcnJvd1wiIHx8IGZsb3cua2luZCA9PSBcImNsb3NlXCIgPyBleHByZXNzaW9uLmFyZ3VtZW50c1tmbG93LnBhcmFtZXRlckluZGV4XSA6IHVuZGVmaW5lZFxuICAgICAgICAgIGNvbnN0IGJvcnJvd2VkUGFyYW1ldGVyTmFtZSA9IGFyZ3VtZW50Py5raW5kID09IFwiT3duZWRCb3Jyb3dFeHByZXNzaW9uXCIgJiYgYXJndW1lbnQuZXhwcmVzc2lvbi5raW5kID09IFwiSWRlbnRpZmllckV4cHJlc3Npb25cIlxuICAgICAgICAgICAgPyBhcmd1bWVudC5leHByZXNzaW9uLm5hbWUgOiB1bmRlZmluZWRcbiAgICAgICAgICBjb25zdCBrbm93bk9wZW5Cb3Jyb3cgPSBkZWNsYXJhdGlvbi5vd25lcnNoaXA/LmtpbmQgPT0gXCJvd25lZFJlc291cmNlXCIgJiYgYXJndW1lbnQ/LmtpbmQgPT0gXCJPd25lZEJvcnJvd0V4cHJlc3Npb25cIiAmJiAoXG4gICAgICAgICAgICBhcmd1bWVudC5leHByZXNzaW9uLmtpbmQgPT0gXCJQcml2YXRlRmllbGRSZWFkXCIgJiYgYXJndW1lbnQuZXhwcmVzc2lvbi5maWVsZCA9PSBkZWNsYXJhdGlvbi5vd25lcnNoaXAuZmllbGRJZCB8fFxuICAgICAgICAgICAgYm9ycm93ZWRQYXJhbWV0ZXJOYW1lICE9PSB1bmRlZmluZWQgJiYgbWV0aG9kLnBhcmFtZXRlcnMuc29tZSgocGFyYW1ldGVyKSA9PlxuICAgICAgICAgICAgICBwYXJhbWV0ZXIubmFtZSA9PSBib3Jyb3dlZFBhcmFtZXRlck5hbWUgJiZcbiAgICAgICAgICAgICAgKHBhcmFtZXRlci50eXBlLmtpbmQgPT0gXCJPd25lZFJlc291cmNlVHlwZVwiIHx8IHBhcmFtZXRlci50eXBlLmtpbmQgPT0gXCJPd25lZFJlZmVyZW5jZVR5cGVcIikpXG4gICAgICAgICAgKVxuICAgICAgICAgIGNvbnN0IHRlcm1pbmFsRmFpbHVyZUlkID0ga25vd25PcGVuQm9ycm93XG4gICAgICAgICAgICA/IGZsb3cua2luZCA9PSBcImJvcnJvd1wiIHx8IGZsb3cua2luZCA9PSBcImNsb3NlXCIgPyBmbG93LnRlcm1pbmFsRmFpbHVyZUlkIDogdW5kZWZpbmVkXG4gICAgICAgICAgICA6IHVuZGVmaW5lZFxuXG4gICAgICAgICAgaWYgKHRlcm1pbmFsRmFpbHVyZUlkKSBzdW1tYXJ5LmZhaWx1cmVJZHMuZGVsZXRlKHRlcm1pbmFsRmFpbHVyZUlkKVxuICAgICAgICB9IGVsc2UgaWYgKGV4cHJlc3Npb24ua2luZCA9PSBcIkNhbGxFeHByZXNzaW9uXCIpIHtcbiAgICAgICAgICBjb25zdCBjYWxsZWQgPSBmdW5jdGlvblN1bW1hcmllcy5nZXQoZXhwcmVzc2lvbi5jYWxsZWUpXG4gICAgICAgICAgaWYgKGNhbGxlZD8uaG9zdCkgc3VtbWFyeS5ob3N0ID0gdHJ1ZVxuICAgICAgICB9IGVsc2UgaWYgKGV4cHJlc3Npb24ua2luZCA9PSBcIk1ldGhvZENhbGxFeHByZXNzaW9uXCIpIHtcbiAgICAgICAgICBjb25zdCBjYWxsZWQgPSBwcmlvck1ldGhvZFN1bW1hcmllcy5nZXQoZXhwcmVzc2lvbi5tZXRob2QpXG4gICAgICAgICAgaWYgKGNhbGxlZD8uaG9zdCkgc3VtbWFyeS5ob3N0ID0gdHJ1ZVxuICAgICAgICB9XG4gICAgICB9LCBmYWxzZSlcbiAgICAgIHN1bW1hcmllcy5zZXQoLyoqIEB0eXBlIHtzdHJpbmd9ICovIChtZXRob2QuaWQpLCBzdW1tYXJ5KVxuICAgIH1cbiAgfVxuICByZXR1cm4gc3VtbWFyaWVzXG59XG5cbi8qKlxuICogUmVhZHMgY2hlY2tlZCBzdW1tYXJpZXMgYWxyZWFkeSBwcm92ZWQgb24gaW1wb3J0ZWQgY2xhc3MgZGVjbGFyYXRpb25zLlxuICogQHBhcmFtIHtNYXA8c3RyaW5nLCBpbXBvcnQoXCIuL3R5cGVzLmpzXCIpLkNsYXNzRGVjbGFyYXRpb24+fSBjbGFzc2VzIC0gVmlzaWJsZSBjbGFzc2VzLlxuICogQHBhcmFtIHtcImNvbnN0cnVjdG9yc1wiIHwgXCJtZXRob2RzXCJ9IGtpbmQgLSBEZWNsYXJhdGlvbiBjb2hvcnQuXG4gKiBAcmV0dXJucyB7TWFwPHN0cmluZywgRWZmZWN0U3VtbWFyeT59IEltcG9ydGVkIHN1bW1hcmllcyBieSBkZWNsYXJhdGlvbiBpZGVudGl0eS5cbiAqL1xuZnVuY3Rpb24gZGVjbGFyZWRDbGFzc1N1bW1hcmllcyhjbGFzc2VzLCBraW5kKSB7XG4gIC8qKiBAdHlwZSB7TWFwPHN0cmluZywgRWZmZWN0U3VtbWFyeT59ICovXG4gIGNvbnN0IHN1bW1hcmllcyA9IG5ldyBNYXAoKVxuXG4gIGZvciAoY29uc3QgZGVjbGFyYXRpb24gb2YgY2xhc3Nlcy52YWx1ZXMoKSkge1xuICAgIGNvbnN0IG1lbWJlcnMgPSBraW5kID09IFwiY29uc3RydWN0b3JzXCIgPyBbZGVjbGFyYXRpb24uY29uc3RydWN0b3JdIDogZGVjbGFyYXRpb24ubWV0aG9kc1xuXG4gICAgZm9yIChjb25zdCBtZW1iZXIgb2YgbWVtYmVycykge1xuICAgICAgaWYgKG1lbWJlci5lZmZlY3RzPy5sZW5ndGggPT0gMSAmJiBtZW1iZXIuZWZmZWN0c1swXSA9PSBcImhvc3RcIiAmJiBBcnJheS5pc0FycmF5KG1lbWJlci5mYWlsdXJlSWRzKSkge1xuICAgICAgICBzdW1tYXJpZXMuc2V0KC8qKiBAdHlwZSB7c3RyaW5nfSAqLyAobWVtYmVyLmlkKSwge2ZhaWx1cmVJZHM6IG5ldyBTZXQobWVtYmVyLmZhaWx1cmVJZHMpLCBob3N0OiB0cnVlfSlcbiAgICAgIH1cbiAgICB9XG4gIH1cbiAgcmV0dXJuIHN1bW1hcmllc1xufVxuXG4vKipcbiAqIENvbXB1dGVzIGRpcmVjdCBjb25zdHJ1Y3RvciBlZmZlY3RzIGFmdGVyIGZ1bmN0aW9uIGFuZCBtZXRob2QgZml4ZWQgcG9pbnRzIHN0YWJpbGl6ZS5cbiAqIEBwYXJhbSB7aW1wb3J0KFwiLi90eXBlcy5qc1wiKS5TZW1hbnRpY01vZHVsZX0gbW9kdWxlIC0gUmVzb2x2ZWQgbW9kdWxlLlxuICogQHBhcmFtIHtNYXA8c3RyaW5nLCBFZmZlY3RTdW1tYXJ5Pn0gZnVuY3Rpb25TdW1tYXJpZXMgLSBTdGFibGUgZnVuY3Rpb24gc3VtbWFyaWVzLlxuICogQHBhcmFtIHtNYXA8c3RyaW5nLCBFZmZlY3RTdW1tYXJ5Pn0gbWV0aG9kU3VtbWFyaWVzIC0gU3RhYmxlIG1ldGhvZCBzdW1tYXJpZXMuXG4gKiBAcGFyYW0ge1NldDxzdHJpbmc+fSBjYXBhYmlsaXR5RmFpbHVyZUlkcyAtIERlY2xhcmVkIGNhcGFiaWxpdHkgZmFpbHVyZXMuXG4gKiBAcGFyYW0ge01hcDxzdHJpbmcsIEVmZmVjdFN1bW1hcnk+fSBiYXNlU3VtbWFyaWVzIC0gSW1wb3J0ZWQgY29uc3RydWN0b3Igc3VtbWFyaWVzLlxuICogQHJldHVybnMge01hcDxzdHJpbmcsIEVmZmVjdFN1bW1hcnk+fSBDb25zdHJ1Y3RvciBzdW1tYXJpZXMgYnkgaWRlbnRpdHkuXG4gKi9cbmZ1bmN0aW9uIGRpcmVjdENvbnN0cnVjdG9yU3VtbWFyaWVzKG1vZHVsZSwgZnVuY3Rpb25TdW1tYXJpZXMsIG1ldGhvZFN1bW1hcmllcywgY2FwYWJpbGl0eUZhaWx1cmVJZHMsIGJhc2VTdW1tYXJpZXMpIHtcbiAgY29uc3Qgc3VtbWFyaWVzID0gbmV3IE1hcChiYXNlU3VtbWFyaWVzKVxuXG4gIGZvciAoY29uc3QgZGVjbGFyYXRpb24gb2YgbW9kdWxlLmNsYXNzZXMgPz8gW10pIHtcbiAgICBjb25zdCBjb25zdHJ1Y3RvciA9IGRlY2xhcmF0aW9uLmNvbnN0cnVjdG9yXG4gICAgLyoqIEB0eXBlIHtFZmZlY3RTdW1tYXJ5fSAqL1xuICAgIGNvbnN0IHN1bW1hcnkgPSB7XG4gICAgICBmYWlsdXJlSWRzOiBlc2NhcGluZ0Jsb2NrRmFpbHVyZXMoY29uc3RydWN0b3IuYm9keSwgZnVuY3Rpb25TdW1tYXJpZXMsIG1ldGhvZFN1bW1hcmllcywgY2FwYWJpbGl0eUZhaWx1cmVJZHMpLFxuICAgICAgaG9zdDogZmFsc2VcbiAgICB9XG5cbiAgICBmb3JFYWNoQmxvY2tFeHByZXNzaW9uKGNvbnN0cnVjdG9yLmJvZHksIChleHByZXNzaW9uKSA9PiB7XG4gICAgICBpZiAoZXhwcmVzc2lvbi5raW5kID09IFwiRWZmZWN0Q2FsbEV4cHJlc3Npb25cIikgc3VtbWFyeS5ob3N0ID0gdHJ1ZVxuICAgICAgZWxzZSBpZiAoZXhwcmVzc2lvbi5raW5kID09IFwiQ2FsbEV4cHJlc3Npb25cIiAmJiBmdW5jdGlvblN1bW1hcmllcy5nZXQoZXhwcmVzc2lvbi5jYWxsZWUpPy5ob3N0KSBzdW1tYXJ5Lmhvc3QgPSB0cnVlXG4gICAgICBlbHNlIGlmIChleHByZXNzaW9uLmtpbmQgPT0gXCJNZXRob2RDYWxsRXhwcmVzc2lvblwiICYmIG1ldGhvZFN1bW1hcmllcy5nZXQoZXhwcmVzc2lvbi5tZXRob2QpPy5ob3N0KSBzdW1tYXJ5Lmhvc3QgPSB0cnVlXG4gICAgfSwgZmFsc2UpXG4gICAgc3VtbWFyaWVzLnNldCgvKiogQHR5cGUge3N0cmluZ30gKi8gKGNvbnN0cnVjdG9yLmlkKSwgc3VtbWFyeSlcbiAgfVxuICByZXR1cm4gc3VtbWFyaWVzXG59XG5cbi8qKlxuICogUmVjb3JkcyBvciB2ZXJpZmllcyBvbmUgY2hlY2tlZCBjbGFzcy1tZW1iZXIgc3VtbWFyeS5cbiAqIEBwYXJhbSB7aW1wb3J0KFwiLi90eXBlcy5qc1wiKS5Db25zdHJ1Y3RvckRlY2xhcmF0aW9uIHwgaW1wb3J0KFwiLi90eXBlcy5qc1wiKS5NZXRob2REZWNsYXJhdGlvbn0gZGVjbGFyYXRpb24gLSBDbGFzcyBtZW1iZXIuXG4gKiBAcGFyYW0ge0VmZmVjdFN1bW1hcnkgfCB1bmRlZmluZWR9IHN1bW1hcnkgLSBDb21wdXRlZCBzdW1tYXJ5LlxuICogQHBhcmFtIHtib29sZWFufSBub3JtYWxpemUgLSBXaGV0aGVyIG1ldGFkYXRhIG1heSBiZSB3cml0dGVuLlxuICogQHBhcmFtIHsoY29kZTogc3RyaW5nLCBkZXRhaWw6IHN0cmluZywgbG9jYXRpb246IGltcG9ydChcIi4vdHlwZXMuanNcIikuU291cmNlTG9jYXRpb24pID0+IG5ldmVyfSBmYWlsIC0gTG9jYXRlZCBmYWlsdXJlLlxuICogQHJldHVybnMge3ZvaWR9XG4gKi9cbmZ1bmN0aW9uIGFwcGx5RGVjbGFyYXRpb25TdW1tYXJ5KGRlY2xhcmF0aW9uLCBzdW1tYXJ5LCBub3JtYWxpemUsIGZhaWwpIHtcbiAgaWYgKCFzdW1tYXJ5Py5ob3N0KSB7XG4gICAgaWYgKG5vcm1hbGl6ZSkge1xuICAgICAgZGVsZXRlIGRlY2xhcmF0aW9uLmVmZmVjdHNcbiAgICAgIGRlbGV0ZSBkZWNsYXJhdGlvbi5mYWlsdXJlSWRzXG4gICAgfSBlbHNlIGlmIChkZWNsYXJhdGlvbi5lZmZlY3RzICE9PSB1bmRlZmluZWQgfHwgZGVjbGFyYXRpb24uZmFpbHVyZUlkcyAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICBmYWlsKFwiVU5ERUNMQVJFRF9FRkZFQ1RcIiwgXCJQdXJlIGNsYXNzIG1lbWJlciBjYXJyaWVzIGZvcmdlZCBlZmZlY3QgbWV0YWRhdGEuXCIsIGRlY2xhcmF0aW9uLmxvY2F0aW9uKVxuICAgIH1cbiAgICByZXR1cm5cbiAgfVxuICBjb25zdCBmYWlsdXJlSWRzID0gWy4uLnN1bW1hcnkuZmFpbHVyZUlkc11cblxuICBpZiAobm9ybWFsaXplKSB7XG4gICAgZGVjbGFyYXRpb24uZWZmZWN0cyA9IFtcImhvc3RcIl1cbiAgICBkZWNsYXJhdGlvbi5mYWlsdXJlSWRzID0gZmFpbHVyZUlkc1xuICB9IGVsc2UgaWYgKGRlY2xhcmF0aW9uLmVmZmVjdHM/Lmxlbmd0aCAhPSAxIHx8IGRlY2xhcmF0aW9uLmVmZmVjdHNbMF0gIT0gXCJob3N0XCIgfHxcbiAgICAhQXJyYXkuaXNBcnJheShkZWNsYXJhdGlvbi5mYWlsdXJlSWRzKSB8fCBkZWNsYXJhdGlvbi5mYWlsdXJlSWRzLmpvaW4oXCIsXCIpICE9IGZhaWx1cmVJZHMuam9pbihcIixcIikpIHtcbiAgICBmYWlsKFwiVU5ERUNMQVJFRF9FRkZFQ1RcIiwgXCJDbGFzcyBtZW1iZXIgZWZmZWN0IHN1bW1hcnkgZG9lcyBub3QgbWF0Y2ggaXRzIGJvZHkuXCIsIGRlY2xhcmF0aW9uLmxvY2F0aW9uKVxuICB9XG59XG5cbi8qKlxuICogVmFsaWRhdGVzIG9uZSBkZXRlcm1pbmlzdGljIGVmZmVjdC1zaXRlIGlkZW50aXR5LlxuICogQHBhcmFtIHtpbXBvcnQoXCIuL3R5cGVzLmpzXCIpLkNhbGxFeHByZXNzaW9uIHwgaW1wb3J0KFwiLi90eXBlcy5qc1wiKS5FZmZlY3RDYWxsRXhwcmVzc2lvbiB8IGltcG9ydChcIi4vdHlwZXMuanNcIikuTWV0aG9kQ2FsbEV4cHJlc3Npb24gfCBpbXBvcnQoXCIuL3R5cGVzLmpzXCIpLlJlZmVyZW5jZUNvbnN0cnVjdGlvbn0gZXhwcmVzc2lvbiAtIEVmZmVjdGZ1bCBjYWxsLlxuICogQHBhcmFtIHtudW1iZXJ9IHNpdGUgLSBFeHBlY3RlZCB0cmF2ZXJzYWwgaW5kZXguXG4gKiBAcGFyYW0geyhjb2RlOiBzdHJpbmcsIGRldGFpbDogc3RyaW5nLCBsb2NhdGlvbjogaW1wb3J0KFwiLi90eXBlcy5qc1wiKS5Tb3VyY2VMb2NhdGlvbikgPT4gbmV2ZXJ9IGZhaWwgLSBMb2NhdGVkIGZhaWx1cmUuXG4gKiBAcmV0dXJucyB7dm9pZH1cbiAqL1xuZnVuY3Rpb24gdmFsaWRhdGVTaXRlKGV4cHJlc3Npb24sIHNpdGUsIGZhaWwpIHtcbiAgaWYgKGV4cHJlc3Npb24uZWZmZWN0U2l0ZUlkICE9IGBlZmZlY3Q6JHtzaXRlfWApIHtcbiAgICBmYWlsKFwiSU5WQUxJRF9FRkZFQ1RfT1JERVJcIiwgYEVmZmVjdCBzaXRlICcke1N0cmluZyhleHByZXNzaW9uLmVmZmVjdFNpdGVJZCl9JyBpcyBub3QgZXhwZWN0ZWQgc2l0ZSAnZWZmZWN0OiR7c2l0ZX0nLmAsIGV4cHJlc3Npb24ubG9jYXRpb24pXG4gIH1cbn1cblxuLyoqXG4gKiBWaXNpdHMgZXZlcnkgZXhwcmVzc2lvbiBpbiBkZXRlcm1pbmlzdGljIGRlY2xhcmF0aW9uIGFuZCBldmFsdWF0aW9uIG9yZGVyLlxuICogQHBhcmFtIHtpbXBvcnQoXCIuL3R5cGVzLmpzXCIpLlNlbWFudGljTW9kdWxlfSBtb2R1bGUgLSBNb2R1bGUgdG8gdHJhdmVyc2UuXG4gKiBAcGFyYW0ge0V4cHJlc3Npb25WaXNpdG9yfSB2aXNpdG9yIC0gRXhwcmVzc2lvbiB2aXNpdG9yLlxuICogQHBhcmFtIHtib29sZWFufSBbcG9zdG9yZGVyXSAtIFZpc2l0IGNoaWxkcmVuIGJlZm9yZSBwYXJlbnRzLlxuICogQHJldHVybnMge3ZvaWR9XG4gKi9cbmZ1bmN0aW9uIGZvckVhY2hFeHByZXNzaW9uKG1vZHVsZSwgdmlzaXRvciwgcG9zdG9yZGVyID0gZmFsc2UpIHtcbiAgZm9yIChjb25zdCBkZWNsYXJhdGlvbiBvZiBtb2R1bGUuY2xhc3NlcyA/PyBbXSkge1xuICAgIGZvckVhY2hCbG9ja0V4cHJlc3Npb24oZGVjbGFyYXRpb24uY29uc3RydWN0b3IuYm9keSwgdmlzaXRvciwgcG9zdG9yZGVyKVxuICAgIGZvciAoY29uc3QgbWV0aG9kIG9mIGRlY2xhcmF0aW9uLm1ldGhvZHMpIGZvckVhY2hCbG9ja0V4cHJlc3Npb24obWV0aG9kLmJvZHksIHZpc2l0b3IsIHBvc3RvcmRlcilcbiAgfVxuICBmb3IgKGNvbnN0IGRlY2xhcmF0aW9uIG9mIG1vZHVsZS5mdW5jdGlvbnMpIGZvckVhY2hCbG9ja0V4cHJlc3Npb24oZGVjbGFyYXRpb24uYm9keSwgdmlzaXRvciwgcG9zdG9yZGVyKVxuICBmb3JFYWNoQmxvY2tFeHByZXNzaW9uKG1vZHVsZS5lbnRyeVBvaW50LmJvZHksIHZpc2l0b3IsIHBvc3RvcmRlcilcbn1cblxuLyoqXG4gKiBWaXNpdHMgZXhwcmVzc2lvbnMgaW4gb25lIHN0cnVjdHVyZWQgYmxvY2suXG4gKiBAcGFyYW0ge2ltcG9ydChcIi4vdHlwZXMuanNcIikuQmxvY2t9IGJsb2NrIC0gQmxvY2sgdG8gdHJhdmVyc2UuXG4gKiBAcGFyYW0ge0V4cHJlc3Npb25WaXNpdG9yfSB2aXNpdG9yIC0gRXhwcmVzc2lvbiB2aXNpdG9yLlxuICogQHBhcmFtIHtib29sZWFufSBwb3N0b3JkZXIgLSBWaXNpdCBjaGlsZHJlbiBiZWZvcmUgcGFyZW50cy5cbiAqIEByZXR1cm5zIHt2b2lkfVxuICovXG5mdW5jdGlvbiBmb3JFYWNoQmxvY2tFeHByZXNzaW9uKGJsb2NrLCB2aXNpdG9yLCBwb3N0b3JkZXIpIHtcbiAgZm9yIChjb25zdCBzdGF0ZW1lbnQgb2YgYmxvY2suc3RhdGVtZW50cykge1xuICAgIGlmIChzdGF0ZW1lbnQua2luZCA9PSBcIkxvY2FsRGVjbGFyYXRpb25cIikgdmlzaXQoc3RhdGVtZW50LmluaXRpYWxpemVyKVxuICAgIGVsc2UgaWYgKHN0YXRlbWVudC5raW5kID09IFwiQXNzaWdubWVudFN0YXRlbWVudFwiIHx8IHN0YXRlbWVudC5raW5kID09IFwiUHJpdmF0ZUZpZWxkV3JpdGVTdGF0ZW1lbnRcIikgdmlzaXQoc3RhdGVtZW50LmV4cHJlc3Npb24pXG4gICAgZWxzZSBpZiAoc3RhdGVtZW50LmtpbmQgPT0gXCJSZXR1cm5TdGF0ZW1lbnRcIiAmJiBzdGF0ZW1lbnQuZXhwcmVzc2lvbikgdmlzaXQoc3RhdGVtZW50LmV4cHJlc3Npb24pXG4gICAgZWxzZSBpZiAoc3RhdGVtZW50LmtpbmQgPT0gXCJFeHByZXNzaW9uU3RhdGVtZW50XCIgfHwgc3RhdGVtZW50LmtpbmQgPT0gXCJQcmludFN0YXRlbWVudFwiKSB2aXNpdChzdGF0ZW1lbnQuZXhwcmVzc2lvbilcbiAgICBlbHNlIGlmIChzdGF0ZW1lbnQua2luZCA9PSBcIklmU3RhdGVtZW50XCIpIHtcbiAgICAgIHZpc2l0KHN0YXRlbWVudC5jb25kaXRpb24pOyBmb3JFYWNoQmxvY2tFeHByZXNzaW9uKHN0YXRlbWVudC5jb25zZXF1ZW50LCB2aXNpdG9yLCBwb3N0b3JkZXIpXG4gICAgICBpZiAoc3RhdGVtZW50LmFsdGVybmF0ZSkgZm9yRWFjaEJsb2NrRXhwcmVzc2lvbihzdGF0ZW1lbnQuYWx0ZXJuYXRlLCB2aXNpdG9yLCBwb3N0b3JkZXIpXG4gICAgfSBlbHNlIGlmIChzdGF0ZW1lbnQua2luZCA9PSBcIkZvckVhY2hTdGF0ZW1lbnRcIikge1xuICAgICAgdmlzaXQoc3RhdGVtZW50Lmxpc3QpOyBmb3JFYWNoQmxvY2tFeHByZXNzaW9uKHN0YXRlbWVudC5ib2R5LCB2aXNpdG9yLCBwb3N0b3JkZXIpXG4gICAgfSBlbHNlIGlmIChzdGF0ZW1lbnQua2luZCA9PSBcIkZvckVhY2hNYXBTdGF0ZW1lbnRcIikge1xuICAgICAgdmlzaXQoc3RhdGVtZW50Lm1hcCk7IGZvckVhY2hCbG9ja0V4cHJlc3Npb24oc3RhdGVtZW50LmJvZHksIHZpc2l0b3IsIHBvc3RvcmRlcilcbiAgICB9IGVsc2UgaWYgKHN0YXRlbWVudC5raW5kID09IFwiV2hpbGVTdGF0ZW1lbnRcIikge1xuICAgICAgdmlzaXQoc3RhdGVtZW50LmNvbmRpdGlvbik7IGZvckVhY2hCbG9ja0V4cHJlc3Npb24oc3RhdGVtZW50LmJvZHksIHZpc2l0b3IsIHBvc3RvcmRlcilcbiAgICB9IGVsc2UgaWYgKHN0YXRlbWVudC5raW5kID09IFwiUmFpc2VTdGF0ZW1lbnRcIikgdmlzaXQoc3RhdGVtZW50LmVycm9yLm1lc3NhZ2UpXG4gICAgZWxzZSBpZiAoc3RhdGVtZW50LmtpbmQgPT0gXCJUcnlTdGF0ZW1lbnRcIikge1xuICAgICAgZm9yRWFjaEJsb2NrRXhwcmVzc2lvbihzdGF0ZW1lbnQuYm9keSwgdmlzaXRvciwgcG9zdG9yZGVyKTsgZm9yRWFjaEJsb2NrRXhwcmVzc2lvbihzdGF0ZW1lbnQuY2F0Y2hCb2R5LCB2aXNpdG9yLCBwb3N0b3JkZXIpXG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIFZpc2l0cyBvbmUgZXhwcmVzc2lvbiBzdWJ0cmVlLlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4vdHlwZXMuanNcIikuRXhwcmVzc2lvbn0gZXhwcmVzc2lvbiAtIEV4cHJlc3Npb24gcm9vdC5cbiAgICogQHJldHVybnMge3ZvaWR9XG4gICAqL1xuICBmdW5jdGlvbiB2aXNpdChleHByZXNzaW9uKSB7XG4gICAgaWYgKCFwb3N0b3JkZXIpIHZpc2l0b3IoZXhwcmVzc2lvbilcbiAgICBmb3IgKGNvbnN0IGNoaWxkIG9mIGV4cHJlc3Npb25DaGlsZHJlbihleHByZXNzaW9uKSkgdmlzaXQoY2hpbGQpXG4gICAgaWYgKHBvc3RvcmRlcikgdmlzaXRvcihleHByZXNzaW9uKVxuICB9XG59XG5cbi8qKlxuICogUmVwb3J0cyB3aGV0aGVyIG9uZSBzZW1hbnRpYyBibG9jayByZWZlcmVuY2VzIGEgcmVzZXJ2ZWQgcHJvdGVjdGVkIHByb3ZpZGVyIGVudHJ5LlxuICogQHBhcmFtIHtpbXBvcnQoXCIuL3R5cGVzLmpzXCIpLkJsb2NrfSBibG9jayAtIFNlbWFudGljIGJsb2NrLlxuICogQHJldHVybnMge2Jvb2xlYW59IFdoZXRoZXIgYSBwcm90ZWN0ZWQgZW50cnkgbmFtZSBpcyByZWZlcmVuY2VkLlxuICovXG5leHBvcnQgZnVuY3Rpb24gYmxvY2tSZWZlcmVuY2VzUHJvdGVjdGVkRW50cnkoYmxvY2spIHtcbiAgcmV0dXJuIGJsb2NrLnN0YXRlbWVudHMuc29tZShzdGF0ZW1lbnRSZWZlcmVuY2VzUHJvdGVjdGVkRW50cnkpXG59XG5cbi8qKlxuICogUmVwb3J0cyB3aGV0aGVyIG9uZSBzZW1hbnRpYyBzdGF0ZW1lbnQgcmVmZXJlbmNlcyBhIHJlc2VydmVkIHByb3RlY3RlZCBwcm92aWRlciBlbnRyeS5cbiAqIEBwYXJhbSB7aW1wb3J0KFwiLi90eXBlcy5qc1wiKS5TdGF0ZW1lbnR9IHN0YXRlbWVudCAtIFNlbWFudGljIHN0YXRlbWVudC5cbiAqIEByZXR1cm5zIHtib29sZWFufSBXaGV0aGVyIGEgcHJvdGVjdGVkIGVudHJ5IG5hbWUgaXMgcmVmZXJlbmNlZC5cbiAqL1xuZnVuY3Rpb24gc3RhdGVtZW50UmVmZXJlbmNlc1Byb3RlY3RlZEVudHJ5KHN0YXRlbWVudCkge1xuICBzd2l0Y2ggKHN0YXRlbWVudC5raW5kKSB7XG4gICAgY2FzZSBcIkxvY2FsRGVjbGFyYXRpb25cIjpcbiAgICAgIHJldHVybiBleHByZXNzaW9uUmVmZXJlbmNlc1Byb3RlY3RlZEVudHJ5KHN0YXRlbWVudC5pbml0aWFsaXplcilcbiAgICBjYXNlIFwiQXNzaWdubWVudFN0YXRlbWVudFwiOlxuICAgIGNhc2UgXCJQcml2YXRlRmllbGRXcml0ZVN0YXRlbWVudFwiOlxuICAgICAgcmV0dXJuIGV4cHJlc3Npb25SZWZlcmVuY2VzUHJvdGVjdGVkRW50cnkoc3RhdGVtZW50LmV4cHJlc3Npb24pXG4gICAgY2FzZSBcIlJldHVyblN0YXRlbWVudFwiOlxuICAgICAgcmV0dXJuIHN0YXRlbWVudC5leHByZXNzaW9uID8gZXhwcmVzc2lvblJlZmVyZW5jZXNQcm90ZWN0ZWRFbnRyeShzdGF0ZW1lbnQuZXhwcmVzc2lvbikgOiBmYWxzZVxuICAgIGNhc2UgXCJFeHByZXNzaW9uU3RhdGVtZW50XCI6XG4gICAgY2FzZSBcIlByaW50U3RhdGVtZW50XCI6XG4gICAgICByZXR1cm4gZXhwcmVzc2lvblJlZmVyZW5jZXNQcm90ZWN0ZWRFbnRyeShzdGF0ZW1lbnQuZXhwcmVzc2lvbilcbiAgICBjYXNlIFwiSWZTdGF0ZW1lbnRcIjpcbiAgICAgIHJldHVybiBleHByZXNzaW9uUmVmZXJlbmNlc1Byb3RlY3RlZEVudHJ5KHN0YXRlbWVudC5jb25kaXRpb24pIHx8XG4gICAgICAgIGJsb2NrUmVmZXJlbmNlc1Byb3RlY3RlZEVudHJ5KHN0YXRlbWVudC5jb25zZXF1ZW50KSB8fFxuICAgICAgICAoc3RhdGVtZW50LmFsdGVybmF0ZSA/IGJsb2NrUmVmZXJlbmNlc1Byb3RlY3RlZEVudHJ5KHN0YXRlbWVudC5hbHRlcm5hdGUpIDogZmFsc2UpXG4gICAgY2FzZSBcIkZvckVhY2hTdGF0ZW1lbnRcIjpcbiAgICAgIHJldHVybiBleHByZXNzaW9uUmVmZXJlbmNlc1Byb3RlY3RlZEVudHJ5KHN0YXRlbWVudC5saXN0KSB8fCBibG9ja1JlZmVyZW5jZXNQcm90ZWN0ZWRFbnRyeShzdGF0ZW1lbnQuYm9keSlcbiAgICBjYXNlIFwiRm9yRWFjaE1hcFN0YXRlbWVudFwiOlxuICAgICAgcmV0dXJuIGV4cHJlc3Npb25SZWZlcmVuY2VzUHJvdGVjdGVkRW50cnkoc3RhdGVtZW50Lm1hcCkgfHwgYmxvY2tSZWZlcmVuY2VzUHJvdGVjdGVkRW50cnkoc3RhdGVtZW50LmJvZHkpXG4gICAgY2FzZSBcIldoaWxlU3RhdGVtZW50XCI6XG4gICAgICByZXR1cm4gZXhwcmVzc2lvblJlZmVyZW5jZXNQcm90ZWN0ZWRFbnRyeShzdGF0ZW1lbnQuY29uZGl0aW9uKSB8fCBibG9ja1JlZmVyZW5jZXNQcm90ZWN0ZWRFbnRyeShzdGF0ZW1lbnQuYm9keSlcbiAgICBjYXNlIFwiUmFpc2VTdGF0ZW1lbnRcIjpcbiAgICAgIHJldHVybiBleHByZXNzaW9uUmVmZXJlbmNlc1Byb3RlY3RlZEVudHJ5KHN0YXRlbWVudC5lcnJvci5tZXNzYWdlKVxuICAgIGNhc2UgXCJUcnlTdGF0ZW1lbnRcIjpcbiAgICAgIHJldHVybiBibG9ja1JlZmVyZW5jZXNQcm90ZWN0ZWRFbnRyeShzdGF0ZW1lbnQuYm9keSkgfHwgYmxvY2tSZWZlcmVuY2VzUHJvdGVjdGVkRW50cnkoc3RhdGVtZW50LmNhdGNoQm9keSlcbiAgICBkZWZhdWx0OlxuICAgICAgcmV0dXJuIGZhbHNlXG4gIH1cbn1cblxuLyoqXG4gKiBSZXBvcnRzIHdoZXRoZXIgb25lIHNlbWFudGljIGV4cHJlc3Npb24gcmVmZXJlbmNlcyBhIHJlc2VydmVkIHByb3RlY3RlZCBwcm92aWRlciBlbnRyeS5cbiAqIEBwYXJhbSB7aW1wb3J0KFwiLi90eXBlcy5qc1wiKS5FeHByZXNzaW9ufSBleHByZXNzaW9uIC0gU2VtYW50aWMgZXhwcmVzc2lvbi5cbiAqIEByZXR1cm5zIHtib29sZWFufSBXaGV0aGVyIGEgcHJvdGVjdGVkIGVudHJ5IG5hbWUgaXMgcmVmZXJlbmNlZC5cbiAqL1xuZnVuY3Rpb24gZXhwcmVzc2lvblJlZmVyZW5jZXNQcm90ZWN0ZWRFbnRyeShleHByZXNzaW9uKSB7XG4gIGlmIChleHByZXNzaW9uLmtpbmQgPT0gXCJJZGVudGlmaWVyRXhwcmVzc2lvblwiICYmIHBhcnNlUHJvdGVjdGVkRW50cnlOYW1lKGV4cHJlc3Npb24ubmFtZSkgIT09IG51bGwpIHJldHVybiB0cnVlXG4gIGlmIChleHByZXNzaW9uLmtpbmQgPT0gXCJDYWxsRXhwcmVzc2lvblwiICYmIHBhcnNlUHJvdGVjdGVkRW50cnlOYW1lKGV4cHJlc3Npb24uY2FsbGVlKSAhPT0gbnVsbCkgcmV0dXJuIHRydWVcbiAgcmV0dXJuIGV4cHJlc3Npb25DaGlsZHJlbihleHByZXNzaW9uKS5zb21lKGV4cHJlc3Npb25SZWZlcmVuY2VzUHJvdGVjdGVkRW50cnkpXG59XG5cbi8qKlxuICogUmV0dXJucyBzZW1hbnRpYyBjaGlsZCBleHByZXNzaW9ucyBpbiBldmFsdWF0aW9uIG9yZGVyLlxuICogQHBhcmFtIHtpbXBvcnQoXCIuL3R5cGVzLmpzXCIpLkV4cHJlc3Npb259IGV4cHJlc3Npb24gLSBQYXJlbnQgZXhwcmVzc2lvbi5cbiAqIEByZXR1cm5zIHtpbXBvcnQoXCIuL3R5cGVzLmpzXCIpLkV4cHJlc3Npb25bXX0gQ2hpbGRyZW4uXG4gKi9cbmZ1bmN0aW9uIGV4cHJlc3Npb25DaGlsZHJlbihleHByZXNzaW9uKSB7XG4gIGlmIChleHByZXNzaW9uLmtpbmQgPT0gXCJDYWxsRXhwcmVzc2lvblwiIHx8IGV4cHJlc3Npb24ua2luZCA9PSBcIkVmZmVjdENhbGxFeHByZXNzaW9uXCIgfHwgZXhwcmVzc2lvbi5raW5kID09IFwiUmVmZXJlbmNlQ29uc3RydWN0aW9uXCIgfHxcbiAgICBleHByZXNzaW9uLmtpbmQgPT0gXCJSZWNvcmRDb25zdHJ1Y3Rpb25cIikgcmV0dXJuIGV4cHJlc3Npb24uYXJndW1lbnRzXG4gIGlmIChleHByZXNzaW9uLmtpbmQgPT0gXCJNZXRob2RDYWxsRXhwcmVzc2lvblwiKSByZXR1cm4gW2V4cHJlc3Npb24ucmVjZWl2ZXIsIC4uLmV4cHJlc3Npb24uYXJndW1lbnRzXVxuICBpZiAoZXhwcmVzc2lvbi5raW5kID09IFwiT3duZWRCb3Jyb3dFeHByZXNzaW9uXCIgfHwgZXhwcmVzc2lvbi5raW5kID09IFwiT3duZWRNb3ZlRXhwcmVzc2lvblwiKSByZXR1cm4gW2V4cHJlc3Npb24uZXhwcmVzc2lvbl1cbiAgaWYgKGV4cHJlc3Npb24ua2luZCA9PSBcIkJpbmFyeUV4cHJlc3Npb25cIikgcmV0dXJuIFtleHByZXNzaW9uLmxlZnQsIGV4cHJlc3Npb24ucmlnaHRdXG4gIGlmIChleHByZXNzaW9uLmtpbmQgPT0gXCJVbmFyeUV4cHJlc3Npb25cIikgcmV0dXJuIFtleHByZXNzaW9uLm9wZXJhbmRdXG4gIGlmIChleHByZXNzaW9uLmtpbmQgPT0gXCJPcHRpb25hbFNvbWVcIikgcmV0dXJuIFtleHByZXNzaW9uLnZhbHVlXVxuICBpZiAoZXhwcmVzc2lvbi5raW5kID09IFwiT3B0aW9uYWxJc1ByZXNlbnRcIiB8fCBleHByZXNzaW9uLmtpbmQgPT0gXCJPcHRpb25hbFVud3JhcFwiKSByZXR1cm4gW2V4cHJlc3Npb24ub3BlcmFuZF1cbiAgaWYgKGV4cHJlc3Npb24ua2luZCA9PSBcIkxpc3RMaXRlcmFsXCIpIHJldHVybiBleHByZXNzaW9uLmVsZW1lbnRzXG4gIGlmIChleHByZXNzaW9uLmtpbmQgPT0gXCJNYXBMaXRlcmFsXCIgfHwgZXhwcmVzc2lvbi5raW5kID09IFwiT3JkZXJlZE1hcExpdGVyYWxcIikgcmV0dXJuIGV4cHJlc3Npb24uZW50cmllcy5tYXAoKHt2YWx1ZX0pID0+IHZhbHVlKVxuICBpZiAoZXhwcmVzc2lvbi5raW5kID09IFwiTGlzdEluZGV4RXhwcmVzc2lvblwiKSByZXR1cm4gW2V4cHJlc3Npb24uY29sbGVjdGlvbiwgZXhwcmVzc2lvbi5pbmRleF1cbiAgaWYgKGV4cHJlc3Npb24ua2luZCA9PSBcIk1hcExvb2t1cEV4cHJlc3Npb25cIikgcmV0dXJuIFtleHByZXNzaW9uLmNvbGxlY3Rpb24sIGV4cHJlc3Npb24ua2V5XVxuICBpZiAoZXhwcmVzc2lvbi5raW5kID09IFwiQ29sbGVjdGlvblNpemVFeHByZXNzaW9uXCIpIHJldHVybiBbZXhwcmVzc2lvbi5jb2xsZWN0aW9uXVxuICBpZiAoZXhwcmVzc2lvbi5raW5kID09IFwiTWVtYmVyUmVhZFwiKSByZXR1cm4gW2V4cHJlc3Npb24ucmVjZWl2ZXJdXG4gIGlmIChleHByZXNzaW9uLmtpbmQgPT0gXCJQcml2YXRlRmllbGRSZWFkXCIpIHJldHVybiBbZXhwcmVzc2lvbi5yZWNlaXZlcl1cbiAgaWYgKGV4cHJlc3Npb24ua2luZCA9PSBcIkVycm9yTWVzc2FnZVJlYWRcIikgcmV0dXJuIFtleHByZXNzaW9uLnJlY2VpdmVyXVxuICByZXR1cm4gW11cbn1cbiJdfQ==