semantifold 0.4.0 → 0.6.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 (203) hide show
  1. package/README.md +13 -7
  2. package/build/index.d.ts +12 -8
  3. package/build/index.d.ts.map +1 -1
  4. package/build/index.js +10 -7
  5. package/build/src/backends/android.d.ts +49 -0
  6. package/build/src/backends/android.d.ts.map +1 -0
  7. package/build/src/backends/android.js +1278 -0
  8. package/build/src/backends/identifiers.d.ts +6 -0
  9. package/build/src/backends/identifiers.d.ts.map +1 -1
  10. package/build/src/backends/identifiers.js +30 -1
  11. package/build/src/backends/ios.js +2 -2
  12. package/build/src/backends/kotlin.d.ts +10 -0
  13. package/build/src/backends/kotlin.d.ts.map +1 -1
  14. package/build/src/backends/kotlin.js +11 -9
  15. package/build/src/backends/native-validation.d.ts +2 -2
  16. package/build/src/backends/native-validation.d.ts.map +1 -1
  17. package/build/src/backends/native-validation.js +2 -2
  18. package/build/src/backends/program.d.ts +6 -4
  19. package/build/src/backends/program.d.ts.map +1 -1
  20. package/build/src/backends/program.js +5 -4
  21. package/build/src/backends/scalars.d.ts.map +1 -1
  22. package/build/src/backends/scalars.js +2 -1
  23. package/build/src/backends/shared.d.ts.map +1 -1
  24. package/build/src/backends/shared.js +20 -4
  25. package/build/src/backends/writer.d.ts +21 -1
  26. package/build/src/backends/writer.d.ts.map +1 -1
  27. package/build/src/backends/writer.js +25 -2
  28. package/build/src/backends/zig-runtime.d.ts +5 -0
  29. package/build/src/backends/zig-runtime.d.ts.map +1 -0
  30. package/build/src/backends/zig-runtime.js +92 -0
  31. package/build/src/backends/zig-validation.d.ts +9 -0
  32. package/build/src/backends/zig-validation.d.ts.map +1 -0
  33. package/build/src/backends/zig-validation.js +73 -0
  34. package/build/src/backends/zig.d.ts +42 -0
  35. package/build/src/backends/zig.d.ts.map +1 -0
  36. package/build/src/backends/zig.js +584 -0
  37. package/build/src/frontends/scalars.d.ts.map +1 -1
  38. package/build/src/frontends/scalars.js +2 -1
  39. package/build/src/frontends/zig-parser.d.ts +31 -0
  40. package/build/src/frontends/zig-parser.d.ts.map +1 -0
  41. package/build/src/frontends/zig-parser.js +17 -0
  42. package/build/src/frontends/zig.d.ts +14 -0
  43. package/build/src/frontends/zig.d.ts.map +1 -0
  44. package/build/src/frontends/zig.js +970 -0
  45. package/build/src/language-registry.d.ts.map +1 -1
  46. package/build/src/language-registry.js +40 -1
  47. package/build/src/mapping.js +2 -2
  48. package/build/src/semantic/provenance.js +3 -3
  49. package/build/src/semantic/types.d.ts +184 -4
  50. package/build/src/semantic/types.d.ts.map +1 -1
  51. package/build/src/semantic/types.js +45 -3
  52. package/build/src/semantic/validate.js +2 -2
  53. package/build/src/toolchains.d.ts +6 -0
  54. package/build/src/toolchains.d.ts.map +1 -1
  55. package/build/src/toolchains.js +2 -1
  56. package/build/src/zig-bindings.d.ts +10 -0
  57. package/build/src/zig-bindings.d.ts.map +1 -0
  58. package/build/src/zig-bindings.js +54 -0
  59. package/docs/android.md +79 -0
  60. package/docs/architecture.md +13 -5
  61. package/docs/goals.md +1 -1
  62. package/docs/ios.md +1 -1
  63. package/docs/language-support.md +15 -4
  64. package/docs/parser-qualification.md +31 -1
  65. package/docs/source-maps.md +7 -3
  66. package/docs/specification.md +5 -0
  67. package/docs/testing.md +40 -3
  68. package/docs/zig.md +33 -0
  69. package/index.js +9 -6
  70. package/node_modules/semantifold-tree-sitter-zig-internal/LICENSE +15 -0
  71. package/node_modules/semantifold-tree-sitter-zig-internal/README.md +5 -0
  72. package/node_modules/semantifold-tree-sitter-zig-internal/node_modules/@tree-sitter-grammars/tree-sitter-zig/LICENSE +21 -0
  73. package/node_modules/semantifold-tree-sitter-zig-internal/node_modules/@tree-sitter-grammars/tree-sitter-zig/README.md +21 -0
  74. package/node_modules/semantifold-tree-sitter-zig-internal/node_modules/@tree-sitter-grammars/tree-sitter-zig/binding.gyp +29 -0
  75. package/node_modules/semantifold-tree-sitter-zig-internal/node_modules/@tree-sitter-grammars/tree-sitter-zig/bindings/node/binding.cc +20 -0
  76. package/node_modules/semantifold-tree-sitter-zig-internal/node_modules/@tree-sitter-grammars/tree-sitter-zig/bindings/node/binding_test.js +9 -0
  77. package/node_modules/semantifold-tree-sitter-zig-internal/node_modules/@tree-sitter-grammars/tree-sitter-zig/bindings/node/index.d.ts +28 -0
  78. package/node_modules/semantifold-tree-sitter-zig-internal/node_modules/@tree-sitter-grammars/tree-sitter-zig/bindings/node/index.js +11 -0
  79. package/node_modules/semantifold-tree-sitter-zig-internal/node_modules/@tree-sitter-grammars/tree-sitter-zig/grammar.js +900 -0
  80. package/node_modules/semantifold-tree-sitter-zig-internal/node_modules/@tree-sitter-grammars/tree-sitter-zig/package.json +57 -0
  81. package/node_modules/semantifold-tree-sitter-zig-internal/node_modules/@tree-sitter-grammars/tree-sitter-zig/prebuilds/darwin-arm64/@tree-sitter-grammars+tree-sitter-zig.node +0 -0
  82. package/node_modules/semantifold-tree-sitter-zig-internal/node_modules/@tree-sitter-grammars/tree-sitter-zig/prebuilds/darwin-x64/@tree-sitter-grammars+tree-sitter-zig.node +0 -0
  83. package/node_modules/semantifold-tree-sitter-zig-internal/node_modules/@tree-sitter-grammars/tree-sitter-zig/prebuilds/linux-arm64/@tree-sitter-grammars+tree-sitter-zig.node +0 -0
  84. package/node_modules/semantifold-tree-sitter-zig-internal/node_modules/@tree-sitter-grammars/tree-sitter-zig/prebuilds/linux-x64/@tree-sitter-grammars+tree-sitter-zig.node +0 -0
  85. package/node_modules/semantifold-tree-sitter-zig-internal/node_modules/@tree-sitter-grammars/tree-sitter-zig/prebuilds/win32-arm64/@tree-sitter-grammars+tree-sitter-zig.node +0 -0
  86. package/node_modules/semantifold-tree-sitter-zig-internal/node_modules/@tree-sitter-grammars/tree-sitter-zig/prebuilds/win32-x64/@tree-sitter-grammars+tree-sitter-zig.node +0 -0
  87. package/node_modules/semantifold-tree-sitter-zig-internal/node_modules/@tree-sitter-grammars/tree-sitter-zig/queries/folds.scm +23 -0
  88. package/node_modules/semantifold-tree-sitter-zig-internal/node_modules/@tree-sitter-grammars/tree-sitter-zig/queries/highlights.scm +291 -0
  89. package/node_modules/semantifold-tree-sitter-zig-internal/node_modules/@tree-sitter-grammars/tree-sitter-zig/queries/indents.scm +22 -0
  90. package/node_modules/semantifold-tree-sitter-zig-internal/node_modules/@tree-sitter-grammars/tree-sitter-zig/queries/injections.scm +10 -0
  91. package/node_modules/semantifold-tree-sitter-zig-internal/node_modules/@tree-sitter-grammars/tree-sitter-zig/src/grammar.json +6570 -0
  92. package/node_modules/semantifold-tree-sitter-zig-internal/node_modules/@tree-sitter-grammars/tree-sitter-zig/src/node-types.json +3178 -0
  93. package/node_modules/semantifold-tree-sitter-zig-internal/node_modules/@tree-sitter-grammars/tree-sitter-zig/src/parser.c +169829 -0
  94. package/node_modules/semantifold-tree-sitter-zig-internal/node_modules/@tree-sitter-grammars/tree-sitter-zig/src/tree_sitter/alloc.h +54 -0
  95. package/node_modules/semantifold-tree-sitter-zig-internal/node_modules/@tree-sitter-grammars/tree-sitter-zig/src/tree_sitter/array.h +291 -0
  96. package/node_modules/semantifold-tree-sitter-zig-internal/node_modules/@tree-sitter-grammars/tree-sitter-zig/src/tree_sitter/parser.h +266 -0
  97. package/node_modules/semantifold-tree-sitter-zig-internal/node_modules/@tree-sitter-grammars/tree-sitter-zig/tree-sitter-zig.wasm +0 -0
  98. package/node_modules/semantifold-tree-sitter-zig-internal/node_modules/@tree-sitter-grammars/tree-sitter-zig/tree-sitter.json +38 -0
  99. package/node_modules/semantifold-tree-sitter-zig-internal/node_modules/tree-sitter/LICENSE +21 -0
  100. package/node_modules/semantifold-tree-sitter-zig-internal/node_modules/tree-sitter/README.md +128 -0
  101. package/node_modules/semantifold-tree-sitter-zig-internal/node_modules/tree-sitter/binding.gyp +80 -0
  102. package/node_modules/semantifold-tree-sitter-zig-internal/node_modules/tree-sitter/index.js +916 -0
  103. package/node_modules/semantifold-tree-sitter-zig-internal/node_modules/tree-sitter/package.json +76 -0
  104. package/node_modules/semantifold-tree-sitter-zig-internal/node_modules/tree-sitter/prebuilds/darwin-arm64/tree-sitter.node +0 -0
  105. package/node_modules/semantifold-tree-sitter-zig-internal/node_modules/tree-sitter/prebuilds/darwin-x64/tree-sitter.node +0 -0
  106. package/node_modules/semantifold-tree-sitter-zig-internal/node_modules/tree-sitter/prebuilds/linux-arm64/tree-sitter.node +0 -0
  107. package/node_modules/semantifold-tree-sitter-zig-internal/node_modules/tree-sitter/prebuilds/linux-x64/tree-sitter.node +0 -0
  108. package/node_modules/semantifold-tree-sitter-zig-internal/node_modules/tree-sitter/prebuilds/win32-arm64/tree-sitter.node +0 -0
  109. package/node_modules/semantifold-tree-sitter-zig-internal/node_modules/tree-sitter/prebuilds/win32-x64/tree-sitter.node +0 -0
  110. package/node_modules/semantifold-tree-sitter-zig-internal/node_modules/tree-sitter/src/addon_data.h +47 -0
  111. package/node_modules/semantifold-tree-sitter-zig-internal/node_modules/tree-sitter/src/binding.cc +35 -0
  112. package/node_modules/semantifold-tree-sitter-zig-internal/node_modules/tree-sitter/src/conversions.cc +140 -0
  113. package/node_modules/semantifold-tree-sitter-zig-internal/node_modules/tree-sitter/src/conversions.h +22 -0
  114. package/node_modules/semantifold-tree-sitter-zig-internal/node_modules/tree-sitter/src/language.cc +106 -0
  115. package/node_modules/semantifold-tree-sitter-zig-internal/node_modules/tree-sitter/src/language.h +17 -0
  116. package/node_modules/semantifold-tree-sitter-zig-internal/node_modules/tree-sitter/src/logger.cc +70 -0
  117. package/node_modules/semantifold-tree-sitter-zig-internal/node_modules/tree-sitter/src/logger.h +19 -0
  118. package/node_modules/semantifold-tree-sitter-zig-internal/node_modules/tree-sitter/src/lookaheaditerator.cc +122 -0
  119. package/node_modules/semantifold-tree-sitter-zig-internal/node_modules/tree-sitter/src/lookaheaditerator.h +33 -0
  120. package/node_modules/semantifold-tree-sitter-zig-internal/node_modules/tree-sitter/src/node.cc +1088 -0
  121. package/node_modules/semantifold-tree-sitter-zig-internal/node_modules/tree-sitter/src/node.h +30 -0
  122. package/node_modules/semantifold-tree-sitter-zig-internal/node_modules/tree-sitter/src/parser.cc +306 -0
  123. package/node_modules/semantifold-tree-sitter-zig-internal/node_modules/tree-sitter/src/parser.h +35 -0
  124. package/node_modules/semantifold-tree-sitter-zig-internal/node_modules/tree-sitter/src/query.cc +397 -0
  125. package/node_modules/semantifold-tree-sitter-zig-internal/node_modules/tree-sitter/src/query.h +40 -0
  126. package/node_modules/semantifold-tree-sitter-zig-internal/node_modules/tree-sitter/src/tree.cc +316 -0
  127. package/node_modules/semantifold-tree-sitter-zig-internal/node_modules/tree-sitter/src/tree.h +45 -0
  128. package/node_modules/semantifold-tree-sitter-zig-internal/node_modules/tree-sitter/src/tree_cursor.cc +213 -0
  129. package/node_modules/semantifold-tree-sitter-zig-internal/node_modules/tree-sitter/src/tree_cursor.h +52 -0
  130. package/node_modules/semantifold-tree-sitter-zig-internal/node_modules/tree-sitter/tree-sitter.d.ts +1042 -0
  131. package/node_modules/semantifold-tree-sitter-zig-internal/node_modules/tree-sitter/vendor/tree-sitter/lib/include/tree_sitter/api.h +1318 -0
  132. package/node_modules/semantifold-tree-sitter-zig-internal/node_modules/tree-sitter/vendor/tree-sitter/lib/src/alloc.c +48 -0
  133. package/node_modules/semantifold-tree-sitter-zig-internal/node_modules/tree-sitter/vendor/tree-sitter/lib/src/alloc.h +41 -0
  134. package/node_modules/semantifold-tree-sitter-zig-internal/node_modules/tree-sitter/vendor/tree-sitter/lib/src/array.h +291 -0
  135. package/node_modules/semantifold-tree-sitter-zig-internal/node_modules/tree-sitter/vendor/tree-sitter/lib/src/atomic.h +68 -0
  136. package/node_modules/semantifold-tree-sitter-zig-internal/node_modules/tree-sitter/vendor/tree-sitter/lib/src/clock.h +146 -0
  137. package/node_modules/semantifold-tree-sitter-zig-internal/node_modules/tree-sitter/vendor/tree-sitter/lib/src/error_costs.h +11 -0
  138. package/node_modules/semantifold-tree-sitter-zig-internal/node_modules/tree-sitter/vendor/tree-sitter/lib/src/get_changed_ranges.c +501 -0
  139. package/node_modules/semantifold-tree-sitter-zig-internal/node_modules/tree-sitter/vendor/tree-sitter/lib/src/get_changed_ranges.h +36 -0
  140. package/node_modules/semantifold-tree-sitter-zig-internal/node_modules/tree-sitter/vendor/tree-sitter/lib/src/host.h +21 -0
  141. package/node_modules/semantifold-tree-sitter-zig-internal/node_modules/tree-sitter/vendor/tree-sitter/lib/src/language.c +223 -0
  142. package/node_modules/semantifold-tree-sitter-zig-internal/node_modules/tree-sitter/vendor/tree-sitter/lib/src/language.h +297 -0
  143. package/node_modules/semantifold-tree-sitter-zig-internal/node_modules/tree-sitter/vendor/tree-sitter/lib/src/length.h +52 -0
  144. package/node_modules/semantifold-tree-sitter-zig-internal/node_modules/tree-sitter/vendor/tree-sitter/lib/src/lexer.c +435 -0
  145. package/node_modules/semantifold-tree-sitter-zig-internal/node_modules/tree-sitter/vendor/tree-sitter/lib/src/lexer.h +49 -0
  146. package/node_modules/semantifold-tree-sitter-zig-internal/node_modules/tree-sitter/vendor/tree-sitter/lib/src/lib.c +12 -0
  147. package/node_modules/semantifold-tree-sitter-zig-internal/node_modules/tree-sitter/vendor/tree-sitter/lib/src/node.c +920 -0
  148. package/node_modules/semantifold-tree-sitter-zig-internal/node_modules/tree-sitter/vendor/tree-sitter/lib/src/parser.c +2165 -0
  149. package/node_modules/semantifold-tree-sitter-zig-internal/node_modules/tree-sitter/vendor/tree-sitter/lib/src/parser.h +266 -0
  150. package/node_modules/semantifold-tree-sitter-zig-internal/node_modules/tree-sitter/vendor/tree-sitter/lib/src/point.h +62 -0
  151. package/node_modules/semantifold-tree-sitter-zig-internal/node_modules/tree-sitter/vendor/tree-sitter/lib/src/portable/endian.h +206 -0
  152. package/node_modules/semantifold-tree-sitter-zig-internal/node_modules/tree-sitter/vendor/tree-sitter/lib/src/query.c +4187 -0
  153. package/node_modules/semantifold-tree-sitter-zig-internal/node_modules/tree-sitter/vendor/tree-sitter/lib/src/reduce_action.h +34 -0
  154. package/node_modules/semantifold-tree-sitter-zig-internal/node_modules/tree-sitter/vendor/tree-sitter/lib/src/reusable_node.h +95 -0
  155. package/node_modules/semantifold-tree-sitter-zig-internal/node_modules/tree-sitter/vendor/tree-sitter/lib/src/stack.c +899 -0
  156. package/node_modules/semantifold-tree-sitter-zig-internal/node_modules/tree-sitter/vendor/tree-sitter/lib/src/stack.h +130 -0
  157. package/node_modules/semantifold-tree-sitter-zig-internal/node_modules/tree-sitter/vendor/tree-sitter/lib/src/subtree.c +1066 -0
  158. package/node_modules/semantifold-tree-sitter-zig-internal/node_modules/tree-sitter/vendor/tree-sitter/lib/src/subtree.h +399 -0
  159. package/node_modules/semantifold-tree-sitter-zig-internal/node_modules/tree-sitter/vendor/tree-sitter/lib/src/tree.c +170 -0
  160. package/node_modules/semantifold-tree-sitter-zig-internal/node_modules/tree-sitter/vendor/tree-sitter/lib/src/tree.h +31 -0
  161. package/node_modules/semantifold-tree-sitter-zig-internal/node_modules/tree-sitter/vendor/tree-sitter/lib/src/tree_cursor.c +712 -0
  162. package/node_modules/semantifold-tree-sitter-zig-internal/node_modules/tree-sitter/vendor/tree-sitter/lib/src/tree_cursor.h +48 -0
  163. package/node_modules/semantifold-tree-sitter-zig-internal/node_modules/tree-sitter/vendor/tree-sitter/lib/src/ts_assert.h +11 -0
  164. package/node_modules/semantifold-tree-sitter-zig-internal/node_modules/tree-sitter/vendor/tree-sitter/lib/src/unicode/ICU_SHA +1 -0
  165. package/node_modules/semantifold-tree-sitter-zig-internal/node_modules/tree-sitter/vendor/tree-sitter/lib/src/unicode/LICENSE +414 -0
  166. package/node_modules/semantifold-tree-sitter-zig-internal/node_modules/tree-sitter/vendor/tree-sitter/lib/src/unicode/README.md +29 -0
  167. package/node_modules/semantifold-tree-sitter-zig-internal/node_modules/tree-sitter/vendor/tree-sitter/lib/src/unicode/ptypes.h +1 -0
  168. package/node_modules/semantifold-tree-sitter-zig-internal/node_modules/tree-sitter/vendor/tree-sitter/lib/src/unicode/umachine.h +448 -0
  169. package/node_modules/semantifold-tree-sitter-zig-internal/node_modules/tree-sitter/vendor/tree-sitter/lib/src/unicode/urename.h +1 -0
  170. package/node_modules/semantifold-tree-sitter-zig-internal/node_modules/tree-sitter/vendor/tree-sitter/lib/src/unicode/utf.h +1 -0
  171. package/node_modules/semantifold-tree-sitter-zig-internal/node_modules/tree-sitter/vendor/tree-sitter/lib/src/unicode/utf16.h +733 -0
  172. package/node_modules/semantifold-tree-sitter-zig-internal/node_modules/tree-sitter/vendor/tree-sitter/lib/src/unicode/utf8.h +881 -0
  173. package/node_modules/semantifold-tree-sitter-zig-internal/node_modules/tree-sitter/vendor/tree-sitter/lib/src/unicode.h +83 -0
  174. package/node_modules/semantifold-tree-sitter-zig-internal/node_modules/tree-sitter/vendor/tree-sitter/lib/src/wasm/stdlib-symbols.txt +24 -0
  175. package/node_modules/semantifold-tree-sitter-zig-internal/node_modules/tree-sitter/vendor/tree-sitter/lib/src/wasm/stdlib.c +109 -0
  176. package/node_modules/semantifold-tree-sitter-zig-internal/node_modules/tree-sitter/vendor/tree-sitter/lib/src/wasm/wasm-stdlib.h +1302 -0
  177. package/node_modules/semantifold-tree-sitter-zig-internal/node_modules/tree-sitter/vendor/tree-sitter/lib/src/wasm_store.c +1859 -0
  178. package/node_modules/semantifold-tree-sitter-zig-internal/node_modules/tree-sitter/vendor/tree-sitter/lib/src/wasm_store.h +31 -0
  179. package/node_modules/semantifold-tree-sitter-zig-internal/package.json +21 -0
  180. package/node_modules/semantifold-tree-sitter-zig-internal/src/zig.js +134 -0
  181. package/package.json +11 -6
  182. package/src/backends/android.js +1374 -0
  183. package/src/backends/identifiers.js +30 -0
  184. package/src/backends/ios.js +1 -1
  185. package/src/backends/kotlin.js +11 -8
  186. package/src/backends/native-validation.js +1 -1
  187. package/src/backends/program.js +4 -3
  188. package/src/backends/scalars.js +1 -0
  189. package/src/backends/shared.js +22 -3
  190. package/src/backends/writer.js +27 -2
  191. package/src/backends/zig-runtime.js +93 -0
  192. package/src/backends/zig-validation.js +68 -0
  193. package/src/backends/zig.js +579 -0
  194. package/src/frontends/scalars.js +1 -0
  195. package/src/frontends/zig-parser.js +20 -0
  196. package/src/frontends/zig.js +994 -0
  197. package/src/language-registry.js +40 -0
  198. package/src/mapping.js +1 -1
  199. package/src/semantic/provenance.js +2 -2
  200. package/src/semantic/types.js +47 -2
  201. package/src/semantic/validate.js +1 -1
  202. package/src/toolchains.js +1 -0
  203. package/src/zig-bindings.js +46 -0
@@ -0,0 +1,970 @@
1
+ // @ts-check
2
+ import { isZigIdentifier } from "../backends/identifiers.js";
3
+ import { generateZigProject } from "../backends/zig.js";
4
+ import { zigRuntime } from "../backends/zig-runtime.js";
5
+ import { maximumZigSourceLength } from "../backends/zig-validation.js";
6
+ import { missingType, SemantifoldDiagnostic, unsupportedSyntax } from "../diagnostic.js";
7
+ import { createCoordinateIndex, indexedPointAt } from "../semantic/location.js";
8
+ import { withAdaptedOperation } from "../semantic/operators.js";
9
+ import { withParserRanges } from "../semantic/provenance.js";
10
+ import { hasOnlyUnicodeScalars } from "../semantic/scalars.js";
11
+ import { validateParsedModule } from "../semantic/validate.js";
12
+ import { sourceScalarType } from "./scalars.js";
13
+ import { parseZigCst } from "./zig-parser.js";
14
+ import { collectZigBindingUsage } from "../zig-bindings.js";
15
+ /** @typedef {import("./zig-parser.js").CstNode} CstNode */
16
+ /** @typedef {import("../semantic/types.js").Expression} Expression */
17
+ /** @typedef {import("../semantic/types.js").Statement} Statement */
18
+ /** @typedef {import("../semantic/types.js").FunctionReturnTypeName} Scalar */
19
+ const binaryOperations = new Map([
20
+ ["+", "Add"], ["-", "Subtract"], ["*", "Multiply"], ["==", "Equal"], ["!=", "NotEqual"],
21
+ ["<", "LessThan"], ["<=", "LessThanOrEqual"], [">", "GreaterThan"], [">=", "GreaterThanOrEqual"],
22
+ ["and", "And"], ["or", "Or"]
23
+ ]);
24
+ const helperOperations = new Map([
25
+ ["semantifold_integer_add", "Add"], ["semantifold_integer_subtract", "Subtract"],
26
+ ["semantifold_integer_multiply", "Multiply"], ["semantifold_string_concat", "Add"],
27
+ ["semantifold_string_equal", "Equal"], ["semantifold_string_not_equal", "NotEqual"]
28
+ ]);
29
+ const operationSpellings = new Map([
30
+ ["IntegerAdd", "semantifold_integer_add"], ["IntegerSubtract", "semantifold_integer_subtract"],
31
+ ["IntegerMultiply", "semantifold_integer_multiply"], ["IntegerNegate", "semantifold_integer_negate"],
32
+ ["IntegerEqual", "=="], ["IntegerNotEqual", "!="], ["IntegerLessThan", "<"],
33
+ ["IntegerLessThanOrEqual", "<="], ["IntegerGreaterThan", ">"], ["IntegerGreaterThanOrEqual", ">="],
34
+ ["BooleanEqual", "=="], ["BooleanNotEqual", "!="], ["BooleanAnd", "and"], ["BooleanOr", "or"], ["BooleanNot", "!"],
35
+ ["StringConcat", "semantifold_string_concat"], ["StringEqual", "semantifold_string_equal"],
36
+ ["StringNotEqual", "semantifold_string_not_equal"]
37
+ ]);
38
+ /** Consumes the complete qualified Zig CST and retains exact generated-shell constraints. */
39
+ class ZigReader {
40
+ /**
41
+ * Creates a reader over one complete parser snapshot.
42
+ * @param {string} filename - Logical source filename.
43
+ * @param {string} source - Exact Zig source text.
44
+ */
45
+ constructor(filename, source) {
46
+ this.filename = filename;
47
+ this.source = source;
48
+ this.coordinates = createCoordinateIndex(source);
49
+ this.generated = false;
50
+ /** @type {Map<string, Expression> | undefined} */
51
+ this.temporaryExpressions = undefined;
52
+ /** @type {Set<string> | undefined} */
53
+ this.temporaryNames = undefined;
54
+ /** @type {Map<Expression, {node: CstNode, spelling: string}>} */
55
+ this.operations = new Map();
56
+ /** @type {Map<Statement, {node: CstNode, type: string}>} */
57
+ this.prints = new Map();
58
+ /** @type {Map<string, Scalar>} */
59
+ this.functions = new Map();
60
+ /** @type {Map<import("../semantic/types.js").Parameter | import("../semantic/types.js").LocalDeclaration, "use" | "address" | "none">} */
61
+ this.scaffolds = new Map();
62
+ }
63
+ /**
64
+ * Converts a parser node boundary to a semantic location.
65
+ * @param {CstNode} node - Parser node.
66
+ * @returns {import("../semantic/types.js").SourceLocation} UTF-16 location.
67
+ */
68
+ location(node) {
69
+ return { filename: this.filename, start: indexedPointAt(this.coordinates, node.startIndex), end: indexedPointAt(this.coordinates, node.endIndex) };
70
+ }
71
+ /**
72
+ * Reads the exact source spelling owned by a parser node.
73
+ * @param {CstNode} node - Parser node.
74
+ * @returns {string} Node source text.
75
+ */
76
+ text(node) {
77
+ return this.source.slice(node.startIndex, node.endIndex);
78
+ }
79
+ /**
80
+ * Reads one generated line-comment marker independent of the source newline convention.
81
+ * @param {CstNode} node - Marker comment node.
82
+ * @returns {string} Marker spelling without a parser-owned trailing carriage return.
83
+ */
84
+ marker(node) {
85
+ return this.text(node).replace(/\r$/u, "");
86
+ }
87
+ /**
88
+ * Raises a located unsupported-syntax diagnostic.
89
+ * @param {CstNode} node - Rejected parser node.
90
+ * @param {string} [detail] - Diagnostic detail.
91
+ * @returns {never} This function always throws.
92
+ */
93
+ fail(node, detail = node.type) {
94
+ unsupportedSyntax("zig", detail, this.location(node));
95
+ }
96
+ /**
97
+ * Exhaustively rejects recovery, unexpected extras, directives, and excessive nesting.
98
+ * @param {CstNode} node - Current CST node.
99
+ * @param {number} [depth] - Current nesting depth.
100
+ */
101
+ validateTree(node, depth = 0) {
102
+ if (depth > 512)
103
+ this.fail(node, "Zig CST exceeds the 512-level traversal limit");
104
+ for (const { node: child } of node.children)
105
+ this.validateTree(child, depth + 1);
106
+ if (node.error || node.missing || node.hasError) {
107
+ throw new SemantifoldDiagnostic({ code: "PARSE_ERROR", language: "zig", location: this.location(node), message: `Zig parser recovery at '${node.type}'.` });
108
+ }
109
+ if (node.extra && node.type != "comment")
110
+ this.fail(node, "unexpected extra parser child");
111
+ if (node.type == "comment" && (/^\s*\/\/[/!]/u.test(this.text(node)) || /^\s*\/\/\s*zig fmt:/u.test(this.text(node)))) {
112
+ this.fail(node, "doc or formatter-directive comment");
113
+ }
114
+ }
115
+ /**
116
+ * Returns every non-comment child without hiding syntax edges.
117
+ * @param {CstNode} node - Parent parser node.
118
+ * @returns {CstNode[]} Ordered non-comment children.
119
+ */
120
+ parts(node) {
121
+ return node.children.map(({ node: child }) => child).filter(child => child.type != "comment");
122
+ }
123
+ /**
124
+ * Retains compiler-owned scaffold markers while ignoring ordinary inert comments.
125
+ * @param {CstNode} node - Parent parser node.
126
+ * @returns {CstNode[]} Complete significant child list.
127
+ */
128
+ significant(node) {
129
+ return node.children.map(({ node: child }) => child).filter(child => child.type != "comment" || /semantifold:/u.test(this.text(child)));
130
+ }
131
+ /**
132
+ * Requires exactly one parser field edge.
133
+ * @param {CstNode} node - Parent parser node.
134
+ * @param {string} name - Required field name.
135
+ * @returns {CstNode} Field child.
136
+ */
137
+ field(node, name) {
138
+ const edges = node.children.filter(({ field }) => field == name);
139
+ if (edges.length != 1)
140
+ this.fail(node, `expected one '${name}' field`);
141
+ return edges[0].node;
142
+ }
143
+ /**
144
+ * Requires an exact ordered child/token shape.
145
+ * @param {CstNode} node - Parser node to check.
146
+ * @param {(CstNode | string)[]} expected - Expected node identities or token types.
147
+ */
148
+ shape(node, expected) {
149
+ const parts = this.parts(node);
150
+ if (parts.length != expected.length || parts.some((child, index) => typeof expected[index] == "string" ? child.type != expected[index] || !child.named && this.text(child) != expected[index] : child !== expected[index])) {
151
+ this.fail(node, `${node.type} child shape`);
152
+ }
153
+ }
154
+ /**
155
+ * Validates and returns one ordinary Zig identifier.
156
+ * @param {CstNode} node - Candidate identifier node.
157
+ * @returns {string} Validated identifier.
158
+ */
159
+ identifier(node) {
160
+ const name = this.text(node);
161
+ if (node.type != "identifier" || !isZigIdentifier(name))
162
+ this.fail(node, "reserved or unsupported identifier");
163
+ return name;
164
+ }
165
+ /**
166
+ * Converts an exact source scalar annotation.
167
+ * @param {CstNode} node - Type node.
168
+ * @param {boolean} [allowVoid] - Whether void is valid here.
169
+ * @returns {import("../semantic/types.js").SemanticFunctionReturnType} Semantic type.
170
+ */
171
+ type(node, allowVoid = false) {
172
+ const spelling = this.text(node);
173
+ if (allowVoid && node.type == "builtin_type" && spelling == "void") {
174
+ this.shape(node, ["void"]);
175
+ return withParserRanges({ kind: "TypeReference", name: "void" }, { type: this.location(node) });
176
+ }
177
+ if (node.type == "builtin_type" && ["i64", "bool"].includes(spelling)) {
178
+ if (spelling == "bool")
179
+ this.shape(node, ["bool"]);
180
+ else if (node.children.length)
181
+ this.fail(node, "scalar type shape");
182
+ }
183
+ else if (node.type == "slice_type" && spelling == "[]const u8") {
184
+ this.shape(node, ["[", "]", "const", this.parts(node)[3]]);
185
+ const child = this.parts(node)[3];
186
+ if (child.type != "builtin_type" || this.text(child) != "u8" || child.children.length)
187
+ this.fail(child, "immutable UTF-8 slice element");
188
+ }
189
+ else
190
+ return missingType("zig", allowVoid ? "function return" : "scalar", this.location(node));
191
+ const type = sourceScalarType("zig", spelling, this.location(node));
192
+ if (!type)
193
+ return missingType("zig", "scalar", this.location(node));
194
+ return type;
195
+ }
196
+ /**
197
+ * Decomposes an exact direct call.
198
+ * @param {CstNode} node - Call expression node.
199
+ * @returns {{name: CstNode, arguments: CstNode[]}} Callee and ordered arguments.
200
+ */
201
+ call(node) {
202
+ if (node.type != "call_expression")
203
+ this.fail(node, "direct call required");
204
+ const name = this.field(node, "function");
205
+ const parts = this.parts(node);
206
+ const argumentsAndCommas = parts.slice(2, -1);
207
+ const args = argumentsAndCommas.filter((_part, index) => index % 2 == 0);
208
+ this.shape(node, [name, "(", ...args.flatMap((argument, index) => index ? [",", argument] : [argument]), ")"]);
209
+ return { name, arguments: args };
210
+ }
211
+ /**
212
+ * Decodes one bounded ordinary Zig string literal.
213
+ * @param {CstNode} node - String node.
214
+ * @returns {string} Unicode scalar value.
215
+ */
216
+ string(node) {
217
+ if (node.type != "string")
218
+ this.fail(node, "ordinary UTF-8 string literal required");
219
+ const parts = this.parts(node);
220
+ this.shape(node, ['"', ...parts.slice(1, -1), '"']);
221
+ let value = "";
222
+ for (const part of parts.slice(1, -1)) {
223
+ const spelling = this.text(part);
224
+ if (part.type == "string_content") {
225
+ if (/[\r\n]/u.test(spelling))
226
+ this.fail(part, "raw string line terminator");
227
+ value += spelling;
228
+ }
229
+ else if (part.type == "escape_sequence") {
230
+ const simple = new Map([["\\n", "\n"], ["\\r", "\r"], ["\\t", "\t"], ["\\\\", "\\"], ['\\"', '"']]);
231
+ if (simple.has(spelling))
232
+ value += simple.get(spelling);
233
+ else if (/^\\x[0-9a-fA-F]{2}$/u.test(spelling)) {
234
+ const scalar = Number.parseInt(spelling.slice(2), 16);
235
+ if (scalar > 127)
236
+ this.fail(part, "non-ASCII byte escape");
237
+ value += String.fromCodePoint(scalar);
238
+ }
239
+ else if (/^\\u\{[0-9a-fA-F]{1,6}\}$/u.test(spelling)) {
240
+ const scalar = Number.parseInt(spelling.slice(3, -1), 16);
241
+ if (scalar > 0x10FFFF || scalar >= 0xD800 && scalar <= 0xDFFF)
242
+ this.fail(part, "non-scalar Unicode escape");
243
+ value += String.fromCodePoint(scalar);
244
+ }
245
+ else
246
+ this.fail(part, "unsupported string escape");
247
+ }
248
+ else
249
+ this.fail(part, "string child");
250
+ }
251
+ if (!hasOnlyUnicodeScalars(value))
252
+ this.fail(node, "non-scalar string value");
253
+ return value;
254
+ }
255
+ /**
256
+ * Converts one supported scalar expression.
257
+ * @param {CstNode} node - Expression node.
258
+ * @returns {Expression} Semantic expression.
259
+ */
260
+ expression(node) {
261
+ const location = this.location(node);
262
+ if (node.type == "parenthesized_expression") {
263
+ const parts = this.parts(node);
264
+ this.shape(node, ["(", parts[1], ")"]);
265
+ return this.expression(parts[1]);
266
+ }
267
+ if (node.type == "identifier") {
268
+ const temporary = this.temporaryExpressions?.get(this.text(node));
269
+ if (temporary) {
270
+ this.temporaryExpressions?.delete(this.text(node));
271
+ return temporary;
272
+ }
273
+ return withParserRanges({ kind: "IdentifierExpression", location, name: this.identifier(node) }, { name: location });
274
+ }
275
+ if (node.type == "integer") {
276
+ const spelling = this.text(node);
277
+ const value = Number(spelling);
278
+ if (!/^(?:0|[1-9][0-9]*)$/u.test(spelling) || !Number.isSafeInteger(value))
279
+ this.fail(node, "non-safe or noncanonical i64 literal");
280
+ return withParserRanges({ kind: "IntegerLiteral", location, value }, { literal: location });
281
+ }
282
+ if (node.type == "boolean") {
283
+ const spelling = this.text(node);
284
+ if (spelling != "true" && spelling != "false")
285
+ this.fail(node, "Boolean literal spelling");
286
+ this.shape(node, [spelling]);
287
+ return withParserRanges({ kind: "BooleanLiteral", location, value: spelling == "true" }, { literal: location });
288
+ }
289
+ if (node.type == "string")
290
+ return withParserRanges({ kind: "StringLiteral", location, value: this.string(node) }, { literal: location });
291
+ if (node.type == "unary_expression" || node.type == "error_union_type") {
292
+ const parts = this.parts(node);
293
+ const operator = node.type == "unary_expression" ? this.field(node, "operator") : parts[0];
294
+ const operand = node.type == "unary_expression" ? this.field(node, "argument") : this.field(node, "ok");
295
+ this.shape(node, [operator, operand]);
296
+ if (operator.type != "-" && operator.type != "!")
297
+ this.fail(operator, "unary operator");
298
+ return this.unary(node, operator.type == "-" ? "Negate" : "Not", this.expression(operand), operator);
299
+ }
300
+ if (node.type == "binary_expression") {
301
+ const left = this.field(node, "left");
302
+ const right = this.field(node, "right");
303
+ const operator = this.field(node, "operator");
304
+ const intent = binaryOperations.get(operator.type);
305
+ this.shape(node, [left, operator, right]);
306
+ if (!intent)
307
+ this.fail(operator, "unsupported binary operator");
308
+ return this.binary(node, intent, this.expression(left), this.expression(right), operator);
309
+ }
310
+ if (node.type == "call_expression") {
311
+ const call = this.call(node);
312
+ if (call.name.type != "identifier")
313
+ this.fail(call.name, "direct function call required");
314
+ const name = this.text(call.name);
315
+ if (name == "semantifold_integer_negate") {
316
+ if (call.arguments.length != 1)
317
+ this.fail(node, "negation helper arity");
318
+ return this.unary(node, "Negate", this.expression(call.arguments[0]), call.name);
319
+ }
320
+ const intent = helperOperations.get(name);
321
+ if (intent) {
322
+ if (call.arguments.length != 2)
323
+ this.fail(node, "operator helper arity");
324
+ return this.binary(node, intent, this.expression(call.arguments[0]), this.expression(call.arguments[1]), call.name);
325
+ }
326
+ if (name.startsWith("semantifold_"))
327
+ this.fail(call.name, "support helper outside its exact semantic role");
328
+ const callee = this.identifier(call.name);
329
+ return withParserRanges({ kind: "CallExpression", location, callee, arguments: call.arguments.map(argument => this.expression(argument)) }, { callee: this.location(call.name) });
330
+ }
331
+ return this.fail(node);
332
+ }
333
+ /**
334
+ * Adapts one typed binary operator.
335
+ * @param {CstNode} node - Whole expression node.
336
+ * @param {string} intent - Shared operator intent.
337
+ * @param {Expression} left - Left operand.
338
+ * @param {Expression} right - Right operand.
339
+ * @param {CstNode} operator - Source operator occurrence.
340
+ * @returns {Expression} Adapted semantic expression.
341
+ */
342
+ binary(node, intent, left, right, operator) {
343
+ const expression = /** @type {Expression} */ (withAdaptedOperation(withParserRanges({ kind: "BinaryExpression", location: this.location(node), left, right }, { operator: this.location(operator) }), /** @type {import("../semantic/operators.js").AdaptedOperation} */ (intent)));
344
+ this.operations.set(expression, { node: operator, spelling: this.text(operator) });
345
+ return expression;
346
+ }
347
+ /**
348
+ * Adapts one typed unary operator.
349
+ * @param {CstNode} node - Whole expression node.
350
+ * @param {"Negate" | "Not"} intent - Shared operator intent.
351
+ * @param {Expression} operand - Converted operand.
352
+ * @param {CstNode} operator - Source operator occurrence.
353
+ * @returns {Expression} Adapted semantic expression.
354
+ */
355
+ unary(node, intent, operand, operator) {
356
+ const expression = /** @type {Expression} */ (withAdaptedOperation(withParserRanges({ kind: "UnaryExpression", location: this.location(node), operand }, { operator: this.location(operator) }), intent));
357
+ this.operations.set(expression, { node: operator, spelling: this.text(operator) });
358
+ return expression;
359
+ }
360
+ /**
361
+ * Converts one supported statement.
362
+ * @param {CstNode} node - Statement node.
363
+ * @returns {Statement} Semantic statement.
364
+ */
365
+ statement(node) {
366
+ const location = this.location(node);
367
+ const parts = this.parts(node);
368
+ if (node.type == "variable_declaration") {
369
+ if (["const", "var"].includes(parts[0]?.type)) {
370
+ const typeNode = node.children.find(({ field }) => field == "type")?.node;
371
+ if (!typeNode)
372
+ return missingType("zig", "local", location);
373
+ const name = parts[1];
374
+ const value = parts[5];
375
+ this.shape(node, [parts[0], name, ":", typeNode, "=", value, ";"]);
376
+ return withParserRanges({ kind: "LocalDeclaration", location, name: this.identifier(name), type: /** @type {import("../semantic/types.js").TypeReference} */ (this.type(typeNode)), mutable: parts[0].type == "var",
377
+ initializer: this.expression(value) }, { name: this.location(name), operator: this.location(parts[4]) });
378
+ }
379
+ const targetNode = parts[0];
380
+ const value = parts[2];
381
+ this.shape(node, [targetNode, "=", value, ";"]);
382
+ const target = withParserRanges({ kind: /** @type {const} */ ("IdentifierExpression"), location: this.location(targetNode), name: this.identifier(targetNode) }, { name: this.location(targetNode) });
383
+ return withParserRanges({ kind: "AssignmentStatement", location, target, expression: this.expression(value) }, { operator: this.location(parts[1]) });
384
+ }
385
+ if (node.type == "if_statement")
386
+ return this.conditional(node);
387
+ if (node.type != "expression_statement")
388
+ this.fail(node, "explicit statement required");
389
+ const expression = parts[0];
390
+ this.shape(node, [expression, ";"]);
391
+ if (expression.type == "return_expression") {
392
+ const returned = this.parts(expression);
393
+ if (returned.length == 1) {
394
+ this.shape(expression, ["return"]);
395
+ return { kind: "ReturnStatement", location };
396
+ }
397
+ this.shape(expression, ["return", returned[1]]);
398
+ return { kind: "ReturnStatement", location, expression: this.expression(returned[1]) };
399
+ }
400
+ if (expression.type != "call_expression")
401
+ this.fail(expression, "direct void call statement required");
402
+ const call = this.call(expression);
403
+ const name = this.text(call.name);
404
+ if (/^semantifold_print_(?:integer|boolean|string)$/u.test(name)) {
405
+ if (call.name.type != "identifier" || call.arguments.length != 1)
406
+ this.fail(expression, "exact print helper call required");
407
+ const statement = { kind: /** @type {const} */ ("PrintStatement"), location, expression: this.expression(call.arguments[0]) };
408
+ this.prints.set(statement, { node: call.name, type: name.slice("semantifold_print_".length) });
409
+ return statement;
410
+ }
411
+ const value = this.expression(expression);
412
+ if (value.kind != "CallExpression")
413
+ this.fail(expression, "direct void call statement required");
414
+ return { kind: "ExpressionStatement", location, expression: value };
415
+ }
416
+ /**
417
+ * Converts one strict Boolean conditional.
418
+ * @param {CstNode} node - If-statement node.
419
+ * @returns {import("../semantic/types.js").IfStatement} Semantic conditional.
420
+ */
421
+ conditional(node) {
422
+ const condition = this.field(node, "condition");
423
+ const body = this.field(node, "body");
424
+ const alternative = this.parts(node).find(child => child.type == "else_clause");
425
+ this.shape(node, ["if", "(", condition, ")", body, ...(alternative ? [alternative] : [])]);
426
+ const statement = { kind: /** @type {const} */ ("IfStatement"), location: this.location(node), condition: this.expression(condition), consequent: this.blockExpression(body) };
427
+ if (!alternative)
428
+ return statement;
429
+ const branch = this.field(alternative, "alternative");
430
+ this.shape(alternative, ["else", branch]);
431
+ if (branch.type != "labeled_statement")
432
+ this.fail(branch, "braced else block required");
433
+ const block = this.parts(branch)[0];
434
+ this.shape(branch, [block]);
435
+ return { ...statement, alternate: this.block(block) };
436
+ }
437
+ /**
438
+ * Unwraps one braced conditional block expression.
439
+ * @param {CstNode} node - Block-expression node.
440
+ * @returns {import("../semantic/types.js").Block} Semantic block.
441
+ */
442
+ blockExpression(node) {
443
+ if (node.type != "block_expression")
444
+ this.fail(node, "braced conditional block required");
445
+ const block = this.parts(node)[0];
446
+ this.shape(node, [block]);
447
+ return this.block(block);
448
+ }
449
+ /**
450
+ * Converts one lexical block while consuming exact compiler scaffolds.
451
+ * @param {CstNode} node - Block node.
452
+ * @param {number} [skip] - Fixed leading generated statements to omit.
453
+ * @param {import("../semantic/types.js").Parameter[]} [parameters] - Parameters requiring scaffold checks.
454
+ * @returns {import("../semantic/types.js").Block} Semantic block.
455
+ */
456
+ block(node, skip = 0, parameters = []) {
457
+ if (node.type != "block")
458
+ this.fail(node, "braced block required");
459
+ const parts = this.parts(node);
460
+ this.shape(node, ["{", ...parts.slice(1, -1), "}"]);
461
+ const sourceStatements = this.significant(node).slice(1 + skip, -1);
462
+ return { kind: "Block", location: this.location(node), statements: this.generated
463
+ ? this.generatedStatements(sourceStatements, parameters)
464
+ : this.directStatements(sourceStatements, parameters) };
465
+ }
466
+ /**
467
+ * Converts the legacy direct statement shape when diagnosing a missing generated marker.
468
+ * @param {CstNode[]} sourceStatements - Ordered direct children.
469
+ * @param {import("../semantic/types.js").Parameter[]} parameters - Function parameters.
470
+ * @returns {Statement[]} Semantic statements.
471
+ */
472
+ directStatements(sourceStatements, parameters) {
473
+ let cursor = 0;
474
+ for (const parameter of parameters) {
475
+ const kind = sourceStatements[cursor] ? this.useScaffold(sourceStatements[cursor], parameter.name) : undefined;
476
+ this.scaffolds.set(parameter, kind ?? "none");
477
+ if (kind)
478
+ cursor += 1;
479
+ }
480
+ /** @type {Statement[]} */
481
+ const statements = [];
482
+ while (cursor < sourceStatements.length) {
483
+ const statement = this.statement(sourceStatements[cursor]);
484
+ statements.push(statement);
485
+ cursor += 1;
486
+ if (statement.kind == "LocalDeclaration") {
487
+ const kind = sourceStatements[cursor] ? this.useScaffold(sourceStatements[cursor], statement.name) : undefined;
488
+ this.scaffolds.set(statement, kind ?? "none");
489
+ if (kind)
490
+ cursor += 1;
491
+ }
492
+ }
493
+ return statements;
494
+ }
495
+ /**
496
+ * Reconstructs complete generated statement regions before canonical whole-CST verification.
497
+ * @param {CstNode[]} sourceStatements - Significant direct block children.
498
+ * @param {import("../semantic/types.js").Parameter[]} parameters - Function parameters.
499
+ * @returns {Statement[]} Reconstructed semantic statements.
500
+ */
501
+ generatedStatements(sourceStatements, parameters) {
502
+ /** @type {Statement[]} */
503
+ const statements = [];
504
+ let cursor = 0;
505
+ for (const parameter of parameters) {
506
+ const kind = sourceStatements[cursor] ? this.useScaffold(sourceStatements[cursor], parameter.name) : undefined;
507
+ this.scaffolds.set(parameter, kind ?? "none");
508
+ if (kind)
509
+ cursor += 1;
510
+ }
511
+ while (cursor < sourceStatements.length) {
512
+ const begin = sourceStatements[cursor++];
513
+ const match = begin.type == "comment" &&
514
+ /^\/\/ semantifold:ordered-expression:zig:v1 begin ([0-9]{6}) ([0-9a-f]{64})$/u.exec(this.marker(begin));
515
+ if (!match)
516
+ this.fail(begin, "complete generated ordered statement region required");
517
+ const outerExpressions = this.temporaryExpressions;
518
+ const outerNames = this.temporaryNames;
519
+ this.temporaryExpressions = new Map();
520
+ this.temporaryNames = new Set();
521
+ while (cursor < sourceStatements.length && this.temporaryDeclaration(sourceStatements[cursor])) {
522
+ cursor = this.readTemporary(sourceStatements, cursor);
523
+ }
524
+ const consumer = sourceStatements[cursor++];
525
+ if (!consumer)
526
+ this.fail(begin, "missing generated ordered consumer");
527
+ const statement = this.statement(consumer);
528
+ if (this.temporaryExpressions.size != 0)
529
+ this.fail(consumer, "unconsumed generated ordered temporary");
530
+ if (statement.kind == "LocalDeclaration") {
531
+ const kind = sourceStatements[cursor] ? this.useScaffold(sourceStatements[cursor], statement.name) : undefined;
532
+ this.scaffolds.set(statement, kind ?? "none");
533
+ if (kind)
534
+ cursor += 1;
535
+ }
536
+ const end = sourceStatements[cursor++];
537
+ if (!end || end.type != "comment" || this.marker(end) !=
538
+ `// semantifold:ordered-expression:zig:v1 end ${match[1]} ${match[2]}`)
539
+ this.fail(end ?? begin, "generated ordered marker pair");
540
+ this.temporaryExpressions = outerExpressions;
541
+ this.temporaryNames = outerNames;
542
+ statements.push(statement);
543
+ }
544
+ return statements;
545
+ }
546
+ /**
547
+ * Identifies a reserved ordered temporary declaration at the current region level.
548
+ * @param {CstNode} node - Candidate direct child.
549
+ * @returns {boolean} Whether it declares a reserved ordered temporary.
550
+ */
551
+ temporaryDeclaration(node) {
552
+ const parts = this.parts(node);
553
+ return node.type == "variable_declaration" && ["const", "var"].includes(parts[0]?.type) &&
554
+ parts[1]?.type == "identifier" && this.text(parts[1]).startsWith("semantifold_ordered_");
555
+ }
556
+ /**
557
+ * Expands one typed ordered temporary and an optional conditional Boolean RHS.
558
+ * @param {CstNode[]} nodes - Current region children.
559
+ * @param {number} cursor - Temporary declaration position.
560
+ * @returns {number} Next unconsumed position.
561
+ */
562
+ readTemporary(nodes, cursor) {
563
+ const node = nodes[cursor++];
564
+ const parts = this.parts(node);
565
+ const nameNode = parts[1];
566
+ const name = this.text(nameNode);
567
+ const typeNode = this.field(node, "type");
568
+ const value = parts[5];
569
+ this.shape(node, [parts[0], nameNode, ":", typeNode, "=", value, ";"]);
570
+ this.type(typeNode);
571
+ if (!/^semantifold_ordered_[0-9]{6}$/u.test(name) || this.temporaryNames?.has(name)) {
572
+ this.fail(nameNode, "generated ordered temporary declaration");
573
+ }
574
+ this.temporaryNames?.add(name);
575
+ let expression = this.expression(value);
576
+ const branch = nodes[cursor];
577
+ if (branch && this.shortCircuitBranch(branch, name)) {
578
+ const condition = this.field(branch, "condition");
579
+ const body = this.field(branch, "body");
580
+ const conditionParts = this.parts(condition);
581
+ const isOr = conditionParts[0]?.type == "!";
582
+ const target = isOr ? this.field(condition, condition.type == "unary_expression" ? "argument" : "ok") : condition;
583
+ this.shape(branch, ["if", "(", condition, ")", body]);
584
+ if (target.type != "identifier" || this.text(target) != name)
585
+ this.fail(target, "generated short-circuit temporary test");
586
+ if (isOr)
587
+ this.shape(condition, [conditionParts[0], target]);
588
+ if (isOr && conditionParts[0]?.type != "!")
589
+ this.fail(conditionParts[0] ?? condition, "generated short-circuit negation");
590
+ if (body.type != "block_expression")
591
+ this.fail(body, "generated short-circuit block");
592
+ const block = this.parts(body)[0];
593
+ this.shape(body, [block]);
594
+ if (block.type != "block")
595
+ this.fail(block, "generated short-circuit block");
596
+ const inside = this.significant(block).slice(1, -1);
597
+ let offset = 0;
598
+ while (offset < inside.length && this.temporaryDeclaration(inside[offset]))
599
+ offset = this.readTemporary(inside, offset);
600
+ if (offset != inside.length - 1)
601
+ this.fail(block, "generated short-circuit final assignment");
602
+ const assignment = inside[offset];
603
+ const assignmentParts = this.parts(assignment);
604
+ const left = assignmentParts[0];
605
+ const right = assignmentParts[2];
606
+ this.shape(assignment, [left, "=", right, ";"]);
607
+ if (left.type != "identifier" || this.text(left) != name)
608
+ this.fail(left, "generated short-circuit result write");
609
+ if (right.type != "binary_expression")
610
+ this.fail(right, "generated short-circuit result expression");
611
+ const repeated = this.field(right, "left");
612
+ const operand = this.field(right, "right");
613
+ const operator = this.field(right, "operator");
614
+ const spelling = isOr ? "or" : "and";
615
+ this.shape(right, [repeated, spelling, operand]);
616
+ if (repeated.type != "identifier" || this.text(repeated) != name)
617
+ this.fail(repeated, "generated short-circuit consumed value");
618
+ expression = this.binary(right, isOr ? "Or" : "And", expression, this.expression(operand), operator);
619
+ cursor += 1;
620
+ }
621
+ this.temporaryExpressions?.set(name, expression);
622
+ return cursor;
623
+ }
624
+ /**
625
+ * Distinguishes an internal conditional RHS from the following semantic `if` consumer using only direct CST structure.
626
+ * @param {CstNode} node - Candidate conditional.
627
+ * @param {string} name - Ordered Boolean result name.
628
+ * @returns {boolean} Whether the node has the complete outer shape of a short-circuit update.
629
+ */
630
+ shortCircuitBranch(node, name) {
631
+ if (node.type != "if_statement" || this.parts(node).some(child => child.type == "else_clause"))
632
+ return false;
633
+ const body = node.children.find(({ field }) => field == "body")?.node;
634
+ if (body?.type != "block_expression")
635
+ return false;
636
+ const block = this.parts(body)[0];
637
+ if (block?.type != "block")
638
+ return false;
639
+ const inside = this.significant(block).slice(1, -1);
640
+ const final = inside.at(-1);
641
+ const finalParts = final ? this.parts(final) : [];
642
+ return inside.length > 0 && !inside.some(child => child.type == "comment") && final?.type == "variable_declaration" &&
643
+ finalParts[0]?.type == "identifier" && this.text(finalParts[0]) == name && finalParts[1]?.type == "=";
644
+ }
645
+ /**
646
+ * Recognizes one exact generated unused or unmutated binding scaffold.
647
+ * @param {CstNode} node - Candidate statement node.
648
+ * @param {string} name - Binding name.
649
+ * @returns {"use" | "address" | undefined} Scaffold form when matched.
650
+ */
651
+ useScaffold(node, name) {
652
+ const parts = this.parts(node);
653
+ if (node.type != "variable_declaration" || parts.length != 4 || parts[0].type != "identifier" || this.text(parts[0]) != "_" || parts[1].type != "=" || parts[3].type != ";")
654
+ return undefined;
655
+ if (parts[2].type == "identifier" && this.text(parts[2]) == name)
656
+ return "use";
657
+ if (parts[2].type == "reference_expression") {
658
+ const reference = this.parts(parts[2]);
659
+ if (reference.length == 2 && reference[0].type == "&" && reference[1].type == "identifier" && this.text(reference[1]) == name)
660
+ return "address";
661
+ }
662
+ return undefined;
663
+ }
664
+ /**
665
+ * Converts one canonical top-level semantic function.
666
+ * @param {CstNode} node - Function declaration node.
667
+ * @returns {import("../semantic/types.js").FunctionDeclaration} Semantic function.
668
+ */
669
+ function(node) {
670
+ const name = this.field(node, "name");
671
+ const parameters = this.parts(node).find(child => child.type == "parameters");
672
+ const returnType = this.field(node, "type");
673
+ const body = this.field(node, "body");
674
+ if (!parameters)
675
+ this.fail(node, "parameter list required");
676
+ this.shape(node, ["fn", name, parameters, returnType, body]);
677
+ const parameterParts = this.parts(parameters);
678
+ const declarations = parameterParts.slice(1, -1).filter((_part, index) => index % 2 == 0);
679
+ this.shape(parameters, ["(", ...declarations.flatMap((parameter, index) => index ? [",", parameter] : [parameter]), ")"]);
680
+ const converted = declarations.map(parameter => {
681
+ if (parameter.type != "parameter")
682
+ this.fail(parameter, "required typed parameter");
683
+ const parameterName = this.field(parameter, "name");
684
+ const type = this.field(parameter, "type");
685
+ this.shape(parameter, [parameterName, ":", type]);
686
+ return withParserRanges({ kind: /** @type {const} */ ("Parameter"), location: this.location(parameter), name: this.identifier(parameterName), type: /** @type {import("../semantic/types.js").TypeReference} */ (this.type(type)) }, { name: this.location(parameterName) });
687
+ });
688
+ return withParserRanges({ kind: "FunctionDeclaration", location: this.location(node), name: this.identifier(name), parameters: converted,
689
+ returnType: this.type(returnType, true), body: this.block(body, 0, converted) }, { name: this.location(name) });
690
+ }
691
+ /**
692
+ * Compares every node, token, and field against canonical generated support.
693
+ * @param {CstNode} actual - Source subtree.
694
+ * @param {CstNode} expected - Canonical subtree.
695
+ * @param {ZigReader} canonical - Reader owning the canonical source.
696
+ */
697
+ compareTree(actual, expected, canonical) {
698
+ if (actual.type != expected.type || actual.named != expected.named || actual.extra != expected.extra)
699
+ this.fail(actual, "modified Zig support node");
700
+ const left = this.significant(actual);
701
+ const right = canonical.significant(expected);
702
+ if (left.length != right.length)
703
+ this.fail(actual, "modified Zig support children");
704
+ if (!left.length) {
705
+ const actualText = actual.type == "comment" && /semantifold:/u.test(this.text(actual)) ? this.marker(actual) : this.text(actual);
706
+ const expectedText = expected.type == "comment" && /semantifold:/u.test(canonical.text(expected)) ? canonical.marker(expected) : canonical.text(expected);
707
+ if (actualText != expectedText)
708
+ this.fail(actual, "modified Zig support token");
709
+ }
710
+ left.forEach((child, index) => {
711
+ const expectedChild = right[index];
712
+ if (!expectedChild || actual.children.find(edge => edge.node === child)?.field != expected.children.find(edge => edge.node === expectedChild)?.field) {
713
+ this.fail(child, "modified Zig support field");
714
+ }
715
+ this.compareTree(child, expectedChild, canonical);
716
+ });
717
+ }
718
+ /**
719
+ * Resolves a validated expression's scalar result.
720
+ * @param {Expression} expression - Semantic expression.
721
+ * @param {Map<string, Scalar>} bindings - Visible binding types.
722
+ * @returns {Scalar} Scalar result name.
723
+ */
724
+ expressionType(expression, bindings) {
725
+ if (expression.kind == "StringLiteral")
726
+ return "string";
727
+ if (expression.kind == "IntegerLiteral")
728
+ return "integer";
729
+ if (expression.kind == "BooleanLiteral")
730
+ return "boolean";
731
+ if (expression.kind == "BinaryExpression" || expression.kind == "UnaryExpression")
732
+ return expression.type;
733
+ if (expression.kind != "CallExpression" && expression.kind != "IdentifierExpression")
734
+ throw new Error("Validated Zig source exposed a collection expression.");
735
+ const type = expression.kind == "CallExpression" ? this.functions.get(expression.callee) : bindings.get(expression.name);
736
+ if (!type)
737
+ throw new Error("Validated Zig expression lost its scalar binding.");
738
+ return type;
739
+ }
740
+ /**
741
+ * Requires each typed operation to retain the one exact Zig operator/helper spelling that implements it.
742
+ * @param {Expression} expression - Resolved scalar expression.
743
+ */
744
+ validateOperationExpression(expression) {
745
+ if (expression.kind == "CallExpression") {
746
+ expression.arguments.forEach(argument => this.validateOperationExpression(argument));
747
+ return;
748
+ }
749
+ if (expression.kind == "UnaryExpression") {
750
+ const identity = this.operations.get(expression);
751
+ const expected = operationSpellings.get(expression.operation);
752
+ if (!identity)
753
+ throw new Error("Resolved Zig unary operation lost its parser identity.");
754
+ if (identity.spelling != expected)
755
+ this.fail(identity.node, `exact ${expression.operation} Zig operator/helper required`);
756
+ this.validateOperationExpression(expression.operand);
757
+ return;
758
+ }
759
+ if (expression.kind == "BinaryExpression") {
760
+ const identity = this.operations.get(expression);
761
+ const expected = operationSpellings.get(expression.operation);
762
+ if (!identity)
763
+ throw new Error("Resolved Zig binary operation lost its parser identity.");
764
+ if (identity.spelling != expected)
765
+ this.fail(identity.node, `exact ${expression.operation} Zig operator/helper required`);
766
+ this.validateOperationExpression(expression.left);
767
+ this.validateOperationExpression(expression.right);
768
+ }
769
+ }
770
+ /**
771
+ * Validates operation identity throughout one lexical block.
772
+ * @param {import("../semantic/types.js").Block} block - Block whose expressions must retain exact Zig identity.
773
+ */
774
+ validateOperations(block) {
775
+ for (const statement of block.statements) {
776
+ if (statement.kind == "LocalDeclaration")
777
+ this.validateOperationExpression(statement.initializer);
778
+ else if (statement.kind == "AssignmentStatement" || statement.kind == "ExpressionStatement" || statement.kind == "PrintStatement") {
779
+ this.validateOperationExpression(statement.expression);
780
+ }
781
+ else if (statement.kind == "ReturnStatement") {
782
+ if (statement.expression)
783
+ this.validateOperationExpression(statement.expression);
784
+ }
785
+ else if (statement.kind == "IfStatement") {
786
+ this.validateOperationExpression(statement.condition);
787
+ this.validateOperations(statement.consequent);
788
+ if (statement.alternate)
789
+ this.validateOperations(statement.alternate);
790
+ }
791
+ }
792
+ }
793
+ /**
794
+ * Confirms each generated output helper matches its semantic operand.
795
+ * @param {import("../semantic/types.js").Block} block - Block to inspect.
796
+ * @param {Map<string, Scalar>} inherited - Visible binding types.
797
+ */
798
+ validatePrints(block, inherited) {
799
+ const bindings = new Map(inherited);
800
+ for (const statement of block.statements) {
801
+ if (statement.kind == "LocalDeclaration") {
802
+ bindings.set(statement.name, /** @type {import("../semantic/types.js").TypeReference} */ (statement.type).name);
803
+ }
804
+ else if (statement.kind == "PrintStatement") {
805
+ const print = this.prints.get(statement);
806
+ if (!print || this.expressionType(statement.expression, bindings) != print.type)
807
+ this.fail(print?.node ?? /** @type {CstNode} */ ({}), "print helper scalar mismatch");
808
+ }
809
+ else if (statement.kind == "IfStatement") {
810
+ this.validatePrints(statement.consequent, bindings);
811
+ if (statement.alternate)
812
+ this.validatePrints(statement.alternate, bindings);
813
+ }
814
+ }
815
+ }
816
+ /**
817
+ * Confirms all and only compiler-required binding scaffolds are present.
818
+ * @param {import("../semantic/types.js").FunctionDeclaration | import("../semantic/types.js").EntryPoint} owner - Function or entry owner.
819
+ */
820
+ validateScaffolds(owner) {
821
+ const usage = collectZigBindingUsage(owner.body);
822
+ const parameters = owner.kind == "FunctionDeclaration" ? owner.parameters : [];
823
+ for (const parameter of parameters) {
824
+ const expected = usage.reads.has(parameter.name) ? "none" : "use";
825
+ if (this.scaffolds.get(parameter) != expected)
826
+ unsupportedSyntax("zig", `incorrect unused-parameter scaffold for '${parameter.name}'`, parameter.location);
827
+ }
828
+ /**
829
+ * Checks local scaffolds recursively.
830
+ * @param {import("../semantic/types.js").Block} block - Block to inspect.
831
+ */
832
+ const visit = (block) => {
833
+ for (const statement of block.statements) {
834
+ if (statement.kind == "LocalDeclaration") {
835
+ const expected = statement.mutable && !usage.writes.has(statement.name) ? "address" :
836
+ !statement.mutable && !usage.reads.has(statement.name) ? "use" : "none";
837
+ if (this.scaffolds.get(statement) != expected)
838
+ unsupportedSyntax("zig", `incorrect local binding scaffold for '${statement.name}'`, statement.location);
839
+ }
840
+ else if (statement.kind == "IfStatement") {
841
+ visit(statement.consequent);
842
+ if (statement.alternate)
843
+ visit(statement.alternate);
844
+ }
845
+ }
846
+ };
847
+ visit(owner.body);
848
+ }
849
+ /**
850
+ * Converts a complete canonical Zig project entry.
851
+ * @param {CstNode} root - Source-file root.
852
+ * @returns {import("../semantic/types.js").SemanticModule} Validated semantic module.
853
+ */
854
+ module(root) {
855
+ this.validateTree(root);
856
+ if (root.type != "source_file")
857
+ this.fail(root, "Zig source root required");
858
+ const canonical = new ZigReader(this.filename, zigRuntime);
859
+ const support = canonical.significant(parseZigCst(zigRuntime).root);
860
+ const nodes = this.significant(root);
861
+ if (nodes.length < support.length + 2)
862
+ this.fail(root, "complete Zig runtime, ordered marker, and main shell required");
863
+ support.forEach((expected, index) => this.compareTree(nodes[index], expected, canonical));
864
+ const programMarker = nodes[support.length];
865
+ if (programMarker.type != "comment" || this.marker(programMarker) != "// semantifold:program:zig:v1") {
866
+ this.fail(programMarker, "exact generated Zig ordered-expression marker required");
867
+ }
868
+ this.generated = true;
869
+ const definitions = nodes.slice(support.length + 1);
870
+ /** @type {CstNode | undefined} */
871
+ let main;
872
+ /** @type {CstNode[]} */
873
+ const functions = [];
874
+ for (const node of definitions) {
875
+ if (node.type != "function_declaration")
876
+ this.fail(node, "top-level free functions only");
877
+ const name = this.text(this.field(node, "name"));
878
+ if (name == "main") {
879
+ if (main)
880
+ this.fail(node, "duplicate main");
881
+ main = node;
882
+ }
883
+ else {
884
+ if (main)
885
+ this.fail(node, "semantic function after main");
886
+ functions.push(node);
887
+ }
888
+ }
889
+ if (!main)
890
+ this.fail(root, "canonical pub fn main() void required");
891
+ const mainParts = this.parts(main);
892
+ const mainName = this.field(main, "name");
893
+ const parameters = mainParts.find(child => child.type == "parameters");
894
+ const returnType = this.field(main, "type");
895
+ const body = this.field(main, "body");
896
+ if (!parameters)
897
+ this.fail(main, "main parameters");
898
+ this.shape(main, ["pub", "fn", mainName, parameters, returnType, body]);
899
+ if (this.text(mainName) != "main")
900
+ this.fail(mainName, "main name");
901
+ this.shape(parameters, ["(", ")"]);
902
+ this.type(returnType, true);
903
+ if (this.text(returnType) != "void")
904
+ this.fail(returnType, "main return type");
905
+ const bodyParts = this.parts(body);
906
+ const deferNode = bodyParts[1];
907
+ const shellSource = "pub fn main() void {\n defer semantifold_arena.deinit();\n}\n";
908
+ const shellReader = new ZigReader(this.filename, shellSource);
909
+ const shellMain = shellReader.parts(parseZigCst(shellSource).root)[0];
910
+ const expectedDefer = shellReader.parts(shellReader.field(shellMain, "body"))[1];
911
+ if (!deferNode)
912
+ this.fail(body, "arena lifetime defer required");
913
+ this.compareTree(deferNode, expectedDefer, shellReader);
914
+ const module = validateParsedModule({ kind: "Module", location: this.location(root), functions: functions.map(node => this.function(node)),
915
+ entryPoint: { kind: "EntryPoint", location: this.location(main), body: this.block(body, 1) } }, "zig");
916
+ this.functions = new Map(module.functions.map(declaration => [declaration.name,
917
+ /** @type {import("../semantic/types.js").TypeReference} */ (declaration.returnType).name]));
918
+ for (const declaration of module.functions)
919
+ this.validateOperations(declaration.body);
920
+ this.validateOperations(module.entryPoint.body);
921
+ for (const declaration of module.functions)
922
+ this.validatePrints(declaration.body, new Map(declaration.parameters.map(parameter => [parameter.name,
923
+ /** @type {import("../semantic/types.js").TypeReference} */ (parameter.type).name])));
924
+ this.validatePrints(module.entryPoint.body, new Map());
925
+ for (const declaration of module.functions)
926
+ this.validateScaffolds(declaration);
927
+ this.validateScaffolds(module.entryPoint);
928
+ const canonicalSource = generateZigProject({ module }).artifacts[1]?.content;
929
+ if (typeof canonicalSource != "string")
930
+ throw new Error("Zig backend returned a nontext entry artifact.");
931
+ this.compareTree(root, parseZigCst(canonicalSource).root, new ZigReader(this.filename, canonicalSource));
932
+ return module;
933
+ }
934
+ }
935
+ /**
936
+ * Parses only the qualified frozen Zig CST and rejects unsupported input before adaptation.
937
+ * @param {{filename: string, source: string}} input - Exact source request.
938
+ * @returns {import("../semantic/types.js").SemanticModule} Zig semantic module.
939
+ */
940
+ export function parseZig({ filename, source }) {
941
+ const coordinates = createCoordinateIndex(source);
942
+ const location = { filename, start: indexedPointAt(coordinates, 0), end: indexedPointAt(coordinates, source.length) };
943
+ if (!hasOnlyUnicodeScalars(source)) {
944
+ const offset = source.search(/[\uD800-\uDBFF](?![\uDC00-\uDFFF])|(?<![\uD800-\uDBFF])[\uDC00-\uDFFF]/u);
945
+ throw new SemantifoldDiagnostic({ code: "PARSE_ERROR", language: "zig", message: "Zig source contains a lone UTF-16 surrogate.",
946
+ location: { filename, start: indexedPointAt(coordinates, offset), end: indexedPointAt(coordinates, offset + 1) } });
947
+ }
948
+ if (source.length > maximumZigSourceLength)
949
+ return unsupportedSyntax("zig", "source exceeds the 1000000 UTF-16 input limit", location);
950
+ let snapshot;
951
+ try {
952
+ snapshot = parseZigCst(source);
953
+ }
954
+ catch (error) {
955
+ throw new SemantifoldDiagnostic({ code: "PARSE_ERROR", language: "zig", location,
956
+ cause: error instanceof Error ? error : undefined, message: "The qualified Zig parser could not produce a complete CST." });
957
+ }
958
+ const reader = new ZigReader(filename, source);
959
+ try {
960
+ return reader.module(snapshot.root);
961
+ }
962
+ catch (error) {
963
+ if (reader.generated && error instanceof SemantifoldDiagnostic && error.language == "zig" &&
964
+ error.code != "PARSE_ERROR" && error.code != "UNSUPPORTED_SYNTAX") {
965
+ return unsupportedSyntax("zig", `invalid generated ordered scaffold: ${error.code}`, error.location ?? location);
966
+ }
967
+ throw error;
968
+ }
969
+ }
970
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiemlnLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vc3JjL2Zyb250ZW5kcy96aWcuanMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsWUFBWTtBQUVaLE9BQU8sRUFBQyxlQUFlLEVBQUMsTUFBTSw0QkFBNEIsQ0FBQTtBQUMxRCxPQUFPLEVBQUMsa0JBQWtCLEVBQUMsTUFBTSxvQkFBb0IsQ0FBQTtBQUNyRCxPQUFPLEVBQUMsVUFBVSxFQUFDLE1BQU0sNEJBQTRCLENBQUE7QUFDckQsT0FBTyxFQUFDLHNCQUFzQixFQUFDLE1BQU0sK0JBQStCLENBQUE7QUFDcEUsT0FBTyxFQUFDLFdBQVcsRUFBRSxxQkFBcUIsRUFBRSxpQkFBaUIsRUFBQyxNQUFNLGtCQUFrQixDQUFBO0FBQ3RGLE9BQU8sRUFBQyxxQkFBcUIsRUFBRSxjQUFjLEVBQUMsTUFBTSx5QkFBeUIsQ0FBQTtBQUM3RSxPQUFPLEVBQUMsb0JBQW9CLEVBQUMsTUFBTSwwQkFBMEIsQ0FBQTtBQUM3RCxPQUFPLEVBQUMsZ0JBQWdCLEVBQUMsTUFBTSwyQkFBMkIsQ0FBQTtBQUMxRCxPQUFPLEVBQUMscUJBQXFCLEVBQUMsTUFBTSx3QkFBd0IsQ0FBQTtBQUM1RCxPQUFPLEVBQUMsb0JBQW9CLEVBQUMsTUFBTSx5QkFBeUIsQ0FBQTtBQUM1RCxPQUFPLEVBQUMsZ0JBQWdCLEVBQUMsTUFBTSxjQUFjLENBQUE7QUFDN0MsT0FBTyxFQUFDLFdBQVcsRUFBQyxNQUFNLGlCQUFpQixDQUFBO0FBQzNDLE9BQU8sRUFBQyxzQkFBc0IsRUFBQyxNQUFNLG9CQUFvQixDQUFBO0FBRXpELDJEQUEyRDtBQUMzRCxzRUFBc0U7QUFDdEUsb0VBQW9FO0FBQ3BFLDhFQUE4RTtBQUU5RSxNQUFNLGdCQUFnQixHQUFHLElBQUksR0FBRyxDQUFDO0lBQy9CLENBQUMsR0FBRyxFQUFFLEtBQUssQ0FBQyxFQUFFLENBQUMsR0FBRyxFQUFFLFVBQVUsQ0FBQyxFQUFFLENBQUMsR0FBRyxFQUFF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LEVBQUUsV0FBVyxDQUFDLENBQUE7UUFDL0MsTUFBTSxJQUFJLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQyxJQUFJLEVBQUUsTUFBTSxDQUFDLENBQUE7UUFDckMsTUFBTSxXQUFXLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQyxJQUFJLENBQUMsQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLEVBQUUsQ0FBQyxLQUFLLENBQUMsSUFBSSxJQUFJLGFBQWEsQ0FBQyxDQUFBO1FBRS9FLElBQUksQ0FBQyxLQUFLLENBQUMsSUFBSSxFQUFFLENBQUMsSUFBSSxFQUFFLEdBQUcsRUFBRSxTQUFTLEVBQUUsR0FBRyxFQUFFLElBQUksRUFBRSxHQUFHLENBQUMsV0FBVyxDQUFDLENBQUMsQ0FBQyxDQUFDLFdBQVcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDLENBQUE7UUFDMUYsTUFBTSxTQUFTLEdBQUcsRUFBQyxJQUFJLEVBQUUsb0JBQW9CLENBQUMsQ0FBQyxhQUFhLENBQUMsRUFBRSxRQUFRLEVBQUUsSUFBSSxDQUFDLFFBQVEsQ0FBQyxJQUFJLENBQUMsRUFBRSxTQUFTLEVBQUUsSUFBSSxDQUFDLFVBQVUsQ0FBQyxTQUFTLENBQUMsRUFBRSxVQUFVLEVBQUUsSUFBSSxDQUFDLGVBQWUsQ0FBQyxJQUFJLENBQUMsRUFBQyxDQUFBO1FBRTVLLElBQUksQ0FBQyxXQUFXO1lBQUUsT0FBTyxTQUFTLENBQUE7UUFDbEMsTUFBTSxNQUFNLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQyxXQUFXLEVBQUUsYUFBYSxDQUFDLENBQUE7UUFFckQsSUFBSSxDQUFDLEtBQUssQ0FBQyxXQUFXLEVBQUUsQ0FBQyxNQUFNLEVBQUUsTUFBTSxDQUFDLENBQUMsQ0FBQTtRQUN6QyxJQUFJLE1BQU0sQ0FBQyxJQUFJLElBQUksbUJBQW1CO1lBQUUsSUFBSSxDQUFDLElBQUksQ0FBQyxNQUFNLEVBQUUsNEJBQTRCLENBQUMsQ0FBQTtRQUN2RixNQUFNLEtBQUssR0FBRyxJQUFJLENBQUMsS0FBSyxDQUFD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QUFLLFlBQVkscUJBQXFCLElBQUksS0FBSyxDQUFDLFFBQVEsSUFBSSxLQUFLO1lBQ3ZGLEtBQUssQ0FBQyxJQUFJLElBQUksYUFBYSxJQUFJLEtBQUssQ0FBQyxJQUFJLElBQUksb0JBQW9CLEVBQUUsQ0FBQztZQUNwRSxPQUFPLGlCQUFpQixDQUFDLEtBQUssRUFBRSx1Q0FBdUMsS0FBSyxDQUFDLElBQUksRUFBRSxFQUFFLEtBQUssQ0FBQyxRQUFRLElBQUksUUFBUSxDQUFDLENBQUE7UUFDbEgsQ0FBQztRQUNELE1BQU0sS0FBSyxDQUFBO0lBQ2IsQ0FBQztBQUNILENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyIvLyBAdHMtY2hlY2tcblxuaW1wb3J0IHtpc1ppZ0lkZW50aWZpZXJ9IGZyb20gXCIuLi9iYWNrZW5kcy9pZGVudGlmaWVycy5qc1wiXG5pbXBvcnQge2dlbmVyYXRlWmlnUHJvamVjdH0gZnJvbSBcIi4uL2JhY2tlbmRzL3ppZy5qc1wiXG5pbXBvcnQge3ppZ1J1bnRpbWV9IGZyb20gXCIuLi9iYWNrZW5kcy96aWctcnVudGltZS5qc1wiXG5pbXBvcnQge21heGltdW1aaWdTb3VyY2VMZW5ndGh9IGZyb20gXCIuLi9iYWNrZW5kcy96aWctdmFsaWRhdGlvbi5qc1wiXG5pbXBvcnQge21pc3NpbmdUeXBlLCBTZW1hbnRpZm9sZERpYWdub3N0aWMsIHVuc3VwcG9ydGVkU3ludGF4fSBmcm9tIFwiLi4vZGlhZ25vc3RpYy5qc1wiXG5pbXBvcnQge2NyZWF0ZUNvb3JkaW5hdGVJbmRleCwgaW5kZXhlZFBvaW50QXR9IGZyb20gXCIuLi9zZW1hbnRpYy9sb2NhdGlvbi5qc1wiXG5pbXBvcnQge3dpdGhBZGFwdGVkT3BlcmF0aW9ufSBmcm9tIFwiLi4vc2VtYW50aWMvb3BlcmF0b3JzLmpzXCJcbmltcG9ydCB7d2l0aFBhcnNlclJhbmdlc30gZnJvbSBcIi4uL3NlbWFudGljL3Byb3ZlbmFuY2UuanNcIlxuaW1wb3J0IHtoYXNPbmx5VW5pY29kZVNjYWxhcnN9IGZyb20gXCIuLi9zZW1hbnRpYy9zY2FsYXJzLmpzXCJcbmltcG9ydCB7dmFsaWRhdGVQYXJzZWRNb2R1bGV9IGZyb20gXCIuLi9zZW1hbnRpYy92YWxpZGF0ZS5qc1wiXG5pbXBvcnQge3NvdXJjZVNjYWxhclR5cGV9IGZyb20gXCIuL3NjYWxhcnMuanNcIlxuaW1wb3J0IHtwYXJzZVppZ0NzdH0gZnJvbSBcIi4vemlnLXBhcnNlci5qc1wiXG5pbXBvcnQge2NvbGxlY3RaaWdCaW5kaW5nVXNhZ2V9IGZyb20gXCIuLi96aWctYmluZGluZ3MuanNcIlxuXG4vKiogQHR5cGVkZWYge2ltcG9ydChcIi4vemlnLXBhcnNlci5qc1wiKS5Dc3ROb2RlfSBDc3ROb2RlICovXG4vKiogQHR5cGVkZWYge2ltcG9ydChcIi4uL3NlbWFudGljL3R5cGVzLmpzXCIpLkV4cHJlc3Npb259IEV4cHJlc3Npb24gKi9cbi8qKiBAdHlwZWRlZiB7aW1wb3J0KFwiLi4vc2VtYW50aWMvdHlwZXMuanNcIikuU3RhdGVtZW50fSBTdGF0ZW1lbnQgKi9cbi8qKiBAdHlwZWRlZiB7aW1wb3J0KFwiLi4vc2VtYW50aWMvdHlwZXMuanNcIikuRnVuY3Rpb25SZXR1cm5UeXBlTmFtZX0gU2NhbGFyICovXG5cbmNvbnN0IGJpbmFyeU9wZXJhdGlvbnMgPSBuZXcgTWFwKFtcbiAgW1wiK1wiLCBcIkFkZFwiXSwgW1wiLVwiLCBcIlN1YnRyYWN0XCJdLCBbXCIqXCIsIFwiTXVsdGlwbHlcIl0sIFtcIj09XCIsIFwiRXF1YWxcIl0sIFtcIiE9XCIsIFwiTm90RXF1YWxcIl0sXG4gIFtcIjxcIiwgXCJMZXNzVGhhblwiXSwgW1wiPD1cIiwgXCJMZXNzVGhhbk9yRXF1YWxcIl0sIFtcIj5cIiwgXCJHcmVhdGVyVGhhblwiXSwgW1wiPj1cIiwgXCJHcmVhdGVyVGhhbk9yRXF1YWxcIl0sXG4gIFtcImFuZFwiLCBcIkFuZFwiXSwgW1wib3JcIiwgXCJPclwiXVxuXSlcbmNvbnN0IGhlbHBlck9wZXJhdGlvbnMgPSBuZXcgTWFwKFtcbiAgW1wic2VtYW50aWZvbGRfaW50ZWdlcl9hZGRcIiwgXCJBZGRcIl0sIFtcInNlbWFudGlmb2xkX2ludGVnZXJfc3VidHJhY3RcIiwgXCJTdWJ0cmFjdFwiXSxcbiAgW1wic2VtYW50aWZvbGRfaW50ZWdlcl9tdWx0aXBseVwiLCBcIk11bHRpcGx5XCJdLCBbXCJzZW1hbnRpZm9sZF9zdHJpbmdfY29uY2F0XCIsIFwiQWRkXCJdLFxuICBbXCJzZW1hbnRpZm9sZF9zdHJpbmdfZXF1YWxcIiwgXCJFcXVhbFwiXSwgW1wic2VtYW50aWZvbGRfc3RyaW5nX25vdF9lcXVhbFwiLCBcIk5vdEVxdWFsXCJdXG5dKVxuY29uc3Qgb3BlcmF0aW9uU3BlbGxpbmdzID0gbmV3IE1hcChbXG4gIFtcIkludGVnZXJBZGRcIiwgXCJzZW1hbnRpZm9sZF9pbnRlZ2VyX2FkZFwiXSwgW1wiSW50ZWdlclN1YnRyYWN0XCIsIFwic2VtYW50aWZvbGRfaW50ZWdlcl9zdWJ0cmFjdFwiXSxcbiAgW1wiSW50ZWdlck11bHRpcGx5XCIsIFwic2VtYW50aWZvbGRfaW50ZWdlcl9tdWx0aXBseVwiXSwgW1wiSW50ZWdlck5lZ2F0ZVwiLCBcInNlbWFudGlmb2xkX2ludGVnZXJfbmVnYXRlXCJdLFxuICBbXCJJbnRlZ2VyRXF1YWxcIiwgXCI9PVwiXSwgW1wiSW50ZWdlck5vdEVxdWFsXCIsIFwiIT1cIl0sIFtcIkludGVnZXJMZXNzVGhhblwiLCBcIjxcIl0sXG4gIFtcIkludGVnZXJMZXNzVGhhbk9yRXF1YWxcIiwgXCI8PVwiXSwgW1wiSW50ZWdlckdyZWF0ZXJUaGFuXCIsIFwiPlwiXSwgW1wiSW50ZWdlckdyZWF0ZXJUaGFuT3JFcXVhbFwiLCBcIj49XCJdLFxuICBbXCJCb29sZWFuRXF1YWxcIiwgXCI9PVwiXSwgW1wiQm9vbGVhbk5vdEVxdWFsXCIsIFwiIT1cIl0sIFtcIkJvb2xlYW5BbmRcIiwgXCJhbmRcIl0sIFtcIkJvb2xlYW5PclwiLCBcIm9yXCJdLCBbXCJCb29sZWFuTm90XCIsIFwiIVwiXSxcbiAgW1wiU3RyaW5nQ29uY2F0XCIsIFwic2VtYW50aWZvbGRfc3RyaW5nX2NvbmNhdFwiXSwgW1wiU3RyaW5nRXF1YWxcIiwgXCJzZW1hbnRpZm9sZF9zdHJpbmdfZXF1YWxcIl0sXG4gIFtcIlN0cmluZ05vdEVxdWFsXCIsIFwic2VtYW50aWZvbGRfc3RyaW5nX25vdF9lcXVhbFwiXVxuXSlcblxuLyoqIENvbnN1bWVzIHRoZSBjb21wbGV0ZSBxdWFsaWZpZWQgWmlnIENTVCBhbmQgcmV0YWlucyBleGFjdCBnZW5lcmF0ZWQtc2hlbGwgY29uc3RyYWludHMuICovXG5jbGFzcyBaaWdSZWFkZXIge1xuICAvKipcbiAgICogQ3JlYXRlcyBhIHJlYWRlciBvdmVyIG9uZSBjb21wbGV0ZSBwYXJzZXIgc25hcHNob3QuXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBmaWxlbmFtZSAtIExvZ2ljYWwgc291cmNlIGZpbGVuYW1lLlxuICAgKiBAcGFyYW0ge3N0cmluZ30gc291cmNlIC0gRXhhY3QgWmlnIHNvdXJjZSB0ZXh0LlxuICAgKi9cbiAgY29uc3RydWN0b3IoZmlsZW5hbWUsIHNvdXJjZSkge1xuICAgIHRoaXMuZmlsZW5hbWUgPSBmaWxlbmFtZVxuICAgIHRoaXMuc291cmNlID0gc291cmNlXG4gICAgdGhpcy5jb29yZGluYXRlcyA9IGNyZWF0ZUNvb3JkaW5hdGVJbmRleChzb3VyY2UpXG4gICAgdGhpcy5nZW5lcmF0ZWQgPSBmYWxzZVxuICAgIC8qKiBAdHlwZSB7TWFwPHN0cmluZywgRXhwcmVzc2lvbj4gfCB1bmRlZmluZWR9ICovXG4gICAgdGhpcy50ZW1wb3JhcnlFeHByZXNzaW9ucyA9IHVuZGVmaW5lZFxuICAgIC8qKiBAdHlwZSB7U2V0PHN0cmluZz4gfCB1bmRlZmluZWR9ICovXG4gICAgdGhpcy50ZW1wb3JhcnlOYW1lcyA9IHVuZGVmaW5lZFxuICAgIC8qKiBAdHlwZSB7TWFwPEV4cHJlc3Npb24sIHtub2RlOiBDc3ROb2RlLCBzcGVsbGluZzogc3RyaW5nfT59ICovXG4gICAgdGhpcy5vcGVyYXRpb25zID0gbmV3IE1hcCgpXG4gICAgLyoqIEB0eXBlIHtNYXA8U3RhdGVtZW50LCB7bm9kZTogQ3N0Tm9kZSwgdHlwZTogc3RyaW5nfT59ICovXG4gICAgdGhpcy5wcmludHMgPSBuZXcgTWFwKClcbiAgICAvKiogQHR5cGUge01hcDxzdHJpbmcsIFNjYWxhcj59ICovXG4gICAgdGhpcy5mdW5jdGlvbnMgPSBuZXcgTWFwKClcbiAgICAvKiogQHR5cGUge01hcDxpbXBvcnQoXCIuLi9zZW1hbnRpYy90eXBlcy5qc1wiKS5QYXJhbWV0ZXIgfCBpbXBvcnQoXCIuLi9zZW1hbnRpYy90eXBlcy5qc1wiKS5Mb2NhbERlY2xhcmF0aW9uLCBcInVzZVwiIHwgXCJhZGRyZXNzXCIgfCBcIm5vbmVcIj59ICovXG4gICAgdGhpcy5zY2FmZm9sZHMgPSBuZXcgTWFwKClcbiAgfVxuXG4gIC8qKlxuICAgKiBDb252ZXJ0cyBhIHBhcnNlciBub2RlIGJvdW5kYXJ5IHRvIGEgc2VtYW50aWMgbG9jYXRpb24uXG4gICAqIEBwYXJhbSB7Q3N0Tm9kZX0gbm9kZSAtIFBhcnNlciBub2RlLlxuICAgKiBAcmV0dXJucyB7aW1wb3J0KFwiLi4vc2VtYW50aWMvdHlwZXMuanNcIikuU291cmNlTG9jYXRpb259IFVURi0xNiBsb2NhdGlvbi5cbiAgICovXG4gIGxvY2F0aW9uKG5vZGUpIHtcbiAgICByZXR1cm4ge2ZpbGVuYW1lOiB0aGlzLmZpbGVuYW1lLCBzdGFydDogaW5kZXhlZFBvaW50QXQodGhpcy5jb29yZGluYXRlcywgbm9kZS5zdGFydEluZGV4KSwgZW5kOiBpbmRleGVkUG9pbnRBdCh0aGlzLmNvb3JkaW5hdGVzLCBub2RlLmVuZEluZGV4KX1cbiAgfVxuXG4gIC8qKlxuICAgKiBSZWFkcyB0aGUgZXhhY3Qgc291cmNlIHNwZWxsaW5nIG93bmVkIGJ5IGEgcGFyc2VyIG5vZGUuXG4gICAqIEBwYXJhbSB7Q3N0Tm9kZX0gbm9kZSAtIFBhcnNlciBub2RlLlxuICAgKiBAcmV0dXJucyB7c3RyaW5nfSBOb2RlIHNvdXJjZSB0ZXh0LlxuICAgKi9cbiAgdGV4dChub2RlKSB7XG4gICAgcmV0dXJuIHRoaXMuc291cmNlLnNsaWNlKG5vZGUuc3RhcnRJbmRleCwgbm9kZS5lbmRJbmRleClcbiAgfVxuXG4gIC8qKlxuICAgKiBSZWFkcyBvbmUgZ2VuZXJhdGVkIGxpbmUtY29tbWVudCBtYXJrZXIgaW5kZXBlbmRlbnQgb2YgdGhlIHNvdXJjZSBuZXdsaW5lIGNvbnZlbnRpb24uXG4gICAqIEBwYXJhbSB7Q3N0Tm9kZX0gbm9kZSAtIE1hcmtlciBjb21tZW50IG5vZGUuXG4gICAqIEByZXR1cm5zIHtzdHJpbmd9IE1hcmtlciBzcGVsbGluZyB3aXRob3V0IGEgcGFyc2VyLW93bmVkIHRyYWlsaW5nIGNhcnJpYWdlIHJldHVybi5cbiAgICovXG4gIG1hcmtlcihub2RlKSB7XG4gICAgcmV0dXJuIHRoaXMudGV4dChub2RlKS5yZXBsYWNlKC9cXHIkL3UsIFwiXCIpXG4gIH1cblxuICAvKipcbiAgICogUmFpc2VzIGEgbG9jYXRlZCB1bnN1cHBvcnRlZC1zeW50YXggZGlhZ25vc3RpYy5cbiAgICogQHBhcmFtIHtDc3ROb2RlfSBub2RlIC0gUmVqZWN0ZWQgcGFyc2VyIG5vZGUuXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBbZGV0YWlsXSAtIERpYWdub3N0aWMgZGV0YWlsLlxuICAgKiBAcmV0dXJucyB7bmV2ZXJ9IFRoaXMgZnVuY3Rpb24gYWx3YXlzIHRocm93cy5cbiAgICovXG4gIGZhaWwobm9kZSwgZGV0YWlsID0gbm9kZS50eXBlKSB7XG4gICAgdW5zdXBwb3J0ZWRTeW50YXgoXCJ6aWdcIiwgZGV0YWlsLCB0aGlzLmxvY2F0aW9uKG5vZGUpKVxuICB9XG5cbiAgLyoqXG4gICAqIEV4aGF1c3RpdmVseSByZWplY3RzIHJlY292ZXJ5LCB1bmV4cGVjdGVkIGV4dHJhcywgZGlyZWN0aXZlcywgYW5kIGV4Y2Vzc2l2ZSBuZXN0aW5nLlxuICAgKiBAcGFyYW0ge0NzdE5vZGV9IG5vZGUgLSBDdXJyZW50IENTVCBub2RlLlxuICAgKiBAcGFyYW0ge251bWJlcn0gW2RlcHRoXSAtIEN1cnJlbnQgbmVzdGluZyBkZXB0aC5cbiAgICovXG4gIHZhbGlkYXRlVHJlZShub2RlLCBkZXB0aCA9IDApIHtcbiAgICBpZiAoZGVwdGggPiA1MTIpIHRoaXMuZmFpbChub2RlLCBcIlppZyBDU1QgZXhjZWVkcyB0aGUgNTEyLWxldmVsIHRyYXZlcnNhbCBsaW1pdFwiKVxuICAgIGZvciAoY29uc3Qge25vZGU6IGNoaWxkfSBvZiBub2RlLmNoaWxkcmVuKSB0aGlzLnZhbGlkYXRlVHJlZShjaGlsZCwgZGVwdGggKyAxKVxuICAgIGlmIChub2RlLmVycm9yIHx8IG5vZGUubWlzc2luZyB8fCBub2RlLmhhc0Vycm9yKSB7XG4gICAgICB0aHJvdyBuZXcgU2VtYW50aWZvbGREaWFnbm9zdGljKHtjb2RlOiBcIlBBUlNFX0VSUk9SXCIsIGxhbmd1YWdlOiBcInppZ1wiLCBsb2NhdGlvbjogdGhpcy5sb2NhdGlvbihub2RlKSwgbWVzc2FnZTogYFppZyBwYXJzZXIgcmVjb3ZlcnkgYXQgJyR7bm9kZS50eXBlfScuYH0pXG4gICAgfVxuICAgIGlmIChub2RlLmV4dHJhICYmIG5vZGUudHlwZSAhPSBcImNvbW1lbnRcIikgdGhpcy5mYWlsKG5vZGUsIFwidW5leHBlY3RlZCBleHRyYSBwYXJzZXIgY2hpbGRcIilcbiAgICBpZiAobm9kZS50eXBlID09IFwiY29tbWVudFwiICYmICgvXlxccypcXC9cXC9bLyFdL3UudGVzdCh0aGlzLnRleHQobm9kZSkpIHx8IC9eXFxzKlxcL1xcL1xccyp6aWcgZm10Oi91LnRlc3QodGhpcy50ZXh0KG5vZGUpKSkpIHtcbiAgICAgIHRoaXMuZmFpbChub2RlLCBcImRvYyBvciBmb3JtYXR0ZXItZGlyZWN0aXZlIGNvbW1lbnRcIilcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogUmV0dXJucyBldmVyeSBub24tY29tbWVudCBjaGlsZCB3aXRob3V0IGhpZGluZyBzeW50YXggZWRnZXMuXG4gICAqIEBwYXJhbSB7Q3N0Tm9kZX0gbm9kZSAtIFBhcmVudCBwYXJzZXIgbm9kZS5cbiAgICogQHJldHVybnMge0NzdE5vZGVbXX0gT3JkZXJlZCBub24tY29tbWVudCBjaGlsZHJlbi5cbiAgICovXG4gIHBhcnRzKG5vZGUpIHtcbiAgICByZXR1cm4gbm9kZS5jaGlsZHJlbi5tYXAoKHtub2RlOiBjaGlsZH0pID0+IGNoaWxkKS5maWx0ZXIoY2hpbGQgPT4gY2hpbGQudHlwZSAhPSBcImNvbW1lbnRcIilcbiAgfVxuXG4gIC8qKlxuICAgKiBSZXRhaW5zIGNvbXBpbGVyLW93bmVkIHNjYWZmb2xkIG1hcmtlcnMgd2hpbGUgaWdub3Jpbmcgb3JkaW5hcnkgaW5lcnQgY29tbWVudHMuXG4gICAqIEBwYXJhbSB7Q3N0Tm9kZX0gbm9kZSAtIFBhcmVudCBwYXJzZXIgbm9kZS5cbiAgICogQHJldHVybnMge0NzdE5vZGVbXX0gQ29tcGxldGUgc2lnbmlmaWNhbnQgY2hpbGQgbGlzdC5cbiAgICovXG4gIHNpZ25pZmljYW50KG5vZGUpIHtcbiAgICByZXR1cm4gbm9kZS5jaGlsZHJlbi5tYXAoKHtub2RlOiBjaGlsZH0pID0+IGNoaWxkKS5maWx0ZXIoY2hpbGQgPT5cbiAgICAgIGNoaWxkLnR5cGUgIT0gXCJjb21tZW50XCIgfHwgL3NlbWFudGlmb2xkOi91LnRlc3QodGhpcy50ZXh0KGNoaWxkKSkpXG4gIH1cblxuICAvKipcbiAgICogUmVxdWlyZXMgZXhhY3RseSBvbmUgcGFyc2VyIGZpZWxkIGVkZ2UuXG4gICAqIEBwYXJhbSB7Q3N0Tm9kZX0gbm9kZSAtIFBhcmVudCBwYXJzZXIgbm9kZS5cbiAgICogQHBhcmFtIHtzdHJpbmd9IG5hbWUgLSBSZXF1aXJlZCBmaWVsZCBuYW1lLlxuICAgKiBAcmV0dXJucyB7Q3N0Tm9kZX0gRmllbGQgY2hpbGQuXG4gICAqL1xuICBmaWVsZChub2RlLCBuYW1lKSB7XG4gICAgY29uc3QgZWRnZXMgPSBub2RlLmNoaWxkcmVuLmZpbHRlcigoe2ZpZWxkfSkgPT4gZmllbGQgPT0gbmFtZSlcblxuICAgIGlmIChlZGdlcy5sZW5ndGggIT0gMSkgdGhpcy5mYWlsKG5vZGUsIGBleHBlY3RlZCBvbmUgJyR7bmFtZX0nIGZpZWxkYClcbiAgICByZXR1cm4gZWRnZXNbMF0ubm9kZVxuICB9XG5cbiAgLyoqXG4gICAqIFJlcXVpcmVzIGFuIGV4YWN0IG9yZGVyZWQgY2hpbGQvdG9rZW4gc2hhcGUuXG4gICAqIEBwYXJhbSB7Q3N0Tm9kZX0gbm9kZSAtIFBhcnNlciBub2RlIHRvIGNoZWNrLlxuICAgKiBAcGFyYW0geyhDc3ROb2RlIHwgc3RyaW5nKVtdfSBleHBlY3RlZCAtIEV4cGVjdGVkIG5vZGUgaWRlbnRpdGllcyBvciB0b2tlbiB0eXBlcy5cbiAgICovXG4gIHNoYXBlKG5vZGUsIGV4cGVjdGVkKSB7XG4gICAgY29uc3QgcGFydHMgPSB0aGlzLnBhcnRzKG5vZGUpXG5cbiAgICBpZiAocGFydHMubGVuZ3RoICE9IGV4cGVjdGVkLmxlbmd0aCB8fCBwYXJ0cy5zb21lKChjaGlsZCwgaW5kZXgpID0+XG4gICAgICB0eXBlb2YgZXhwZWN0ZWRbaW5kZXhdID09IFwic3RyaW5nXCIgPyBjaGlsZC50eXBlICE9IGV4cGVjdGVkW2luZGV4XSB8fCAhY2hpbGQubmFtZWQgJiYgdGhpcy50ZXh0KGNoaWxkKSAhPSBleHBlY3RlZFtpbmRleF0gOiBjaGlsZCAhPT0gZXhwZWN0ZWRbaW5kZXhdKSkge1xuICAgICAgdGhpcy5mYWlsKG5vZGUsIGAke25vZGUudHlwZX0gY2hpbGQgc2hhcGVgKVxuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBWYWxpZGF0ZXMgYW5kIHJldHVybnMgb25lIG9yZGluYXJ5IFppZyBpZGVudGlmaWVyLlxuICAgKiBAcGFyYW0ge0NzdE5vZGV9IG5vZGUgLSBDYW5kaWRhdGUgaWRlbnRpZmllciBub2RlLlxuICAgKiBAcmV0dXJucyB7c3RyaW5nfSBWYWxpZGF0ZWQgaWRlbnRpZmllci5cbiAgICovXG4gIGlkZW50aWZpZXIobm9kZSkge1xuICAgIGNvbnN0IG5hbWUgPSB0aGlzLnRleHQobm9kZSlcblxuICAgIGlmIChub2RlLnR5cGUgIT0gXCJpZGVudGlmaWVyXCIgfHwgIWlzWmlnSWRlbnRpZmllcihuYW1lKSkgdGhpcy5mYWlsKG5vZGUsIFwicmVzZXJ2ZWQgb3IgdW5zdXBwb3J0ZWQgaWRlbnRpZmllclwiKVxuICAgIHJldHVybiBuYW1lXG4gIH1cblxuICAvKipcbiAgICogQ29udmVydHMgYW4gZXhhY3Qgc291cmNlIHNjYWxhciBhbm5vdGF0aW9uLlxuICAgKiBAcGFyYW0ge0NzdE5vZGV9IG5vZGUgLSBUeXBlIG5vZGUuXG4gICAqIEBwYXJhbSB7Ym9vbGVhbn0gW2FsbG93Vm9pZF0gLSBXaGV0aGVyIHZvaWQgaXMgdmFsaWQgaGVyZS5cbiAgICogQHJldHVybnMge2ltcG9ydChcIi4uL3NlbWFudGljL3R5cGVzLmpzXCIpLlNlbWFudGljRnVuY3Rpb25SZXR1cm5UeXBlfSBTZW1hbnRpYyB0eXBlLlxuICAgKi9cbiAgdHlwZShub2RlLCBhbGxvd1ZvaWQgPSBmYWxzZSkge1xuICAgIGNvbnN0IHNwZWxsaW5nID0gdGhpcy50ZXh0KG5vZGUpXG5cbiAgICBpZiAoYWxsb3dWb2lkICYmIG5vZGUudHlwZSA9PSBcImJ1aWx0aW5fdHlwZVwiICYmIHNwZWxsaW5nID09IFwidm9pZFwiKSB7XG4gICAgICB0aGlzLnNoYXBlKG5vZGUsIFtcInZvaWRcIl0pXG4gICAgICByZXR1cm4gd2l0aFBhcnNlclJhbmdlcyh7a2luZDogXCJUeXBlUmVmZXJlbmNlXCIsIG5hbWU6IFwidm9pZFwifSwge3R5cGU6IHRoaXMubG9jYXRpb24obm9kZSl9KVxuICAgIH1cbiAgICBpZiAobm9kZS50eXBlID09IFwiYnVpbHRpbl90eXBlXCIgJiYgW1wiaTY0XCIsIFwiYm9vbFwiXS5pbmNsdWRlcyhzcGVsbGluZykpIHtcbiAgICAgIGlmIChzcGVsbGluZyA9PSBcImJvb2xcIikgdGhpcy5zaGFwZShub2RlLCBbXCJib29sXCJdKVxuICAgICAgZWxzZSBpZiAobm9kZS5jaGlsZHJlbi5sZW5ndGgpIHRoaXMuZmFpbChub2RlLCBcInNjYWxhciB0eXBlIHNoYXBlXCIpXG4gICAgfSBlbHNlIGlmIChub2RlLnR5cGUgPT0gXCJzbGljZV90eXBlXCIgJiYgc3BlbGxpbmcgPT0gXCJbXWNvbnN0IHU4XCIpIHtcbiAgICAgIHRoaXMuc2hhcGUobm9kZSwgW1wiW1wiLCBcIl1cIiwgXCJjb25zdFwiLCB0aGlzLnBhcnRzKG5vZGUpWzNdXSlcbiAgICAgIGNvbnN0IGNoaWxkID0gdGhpcy5wYXJ0cyhub2RlKVszXVxuXG4gICAgICBpZiAoY2hpbGQudHlwZSAhPSBcImJ1aWx0aW5fdHlwZVwiIHx8IHRoaXMudGV4dChjaGlsZCkgIT0gXCJ1OFwiIHx8IGNoaWxkLmNoaWxkcmVuLmxlbmd0aCkgdGhpcy5mYWlsKGNoaWxkLCBcImltbXV0YWJsZSBVVEYtOCBzbGljZSBlbGVtZW50XCIpXG4gICAgfSBlbHNlIHJldHVybiBtaXNzaW5nVHlwZShcInppZ1wiLCBhbGxvd1ZvaWQgPyBcImZ1bmN0aW9uIHJldHVyblwiIDogXCJzY2FsYXJcIiwgdGhpcy5sb2NhdGlvbihub2RlKSlcbiAgICBjb25zdCB0eXBlID0gc291cmNlU2NhbGFyVHlwZShcInppZ1wiLCBzcGVsbGluZywgdGhpcy5sb2NhdGlvbihub2RlKSlcblxuICAgIGlmICghdHlwZSkgcmV0dXJuIG1pc3NpbmdUeXBlKFwiemlnXCIsIFwic2NhbGFyXCIsIHRoaXMubG9jYXRpb24obm9kZSkpXG4gICAgcmV0dXJuIHR5cGVcbiAgfVxuXG4gIC8qKlxuICAgKiBEZWNvbXBvc2VzIGFuIGV4YWN0IGRpcmVjdCBjYWxsLlxuICAgKiBAcGFyYW0ge0NzdE5vZGV9IG5vZGUgLSBDYWxsIGV4cHJlc3Npb24gbm9kZS5cbiAgICogQHJldHVybnMge3tuYW1lOiBDc3ROb2RlLCBhcmd1bWVudHM6IENzdE5vZGVbXX19IENhbGxlZSBhbmQgb3JkZXJlZCBhcmd1bWVudHMuXG4gICAqL1xuICBjYWxsKG5vZGUpIHtcbiAgICBpZiAobm9kZS50eXBlICE9IFwiY2FsbF9leHByZXNzaW9uXCIpIHRoaXMuZmFpbChub2RlLCBcImRpcmVjdCBjYWxsIHJlcXVpcmVkXCIpXG4gICAgY29uc3QgbmFtZSA9IHRoaXMuZmllbGQobm9kZSwgXCJmdW5jdGlvblwiKVxuICAgIGNvbnN0IHBhcnRzID0gdGhpcy5wYXJ0cyhub2RlKVxuICAgIGNvbnN0IGFyZ3VtZW50c0FuZENvbW1hcyA9IHBhcnRzLnNsaWNlKDIsIC0xKVxuICAgIGNvbnN0IGFyZ3MgPSBhcmd1bWVudHNBbmRDb21tYXMuZmlsdGVyKChfcGFydCwgaW5kZXgpID0+IGluZGV4ICUgMiA9PSAwKVxuXG4gICAgdGhpcy5zaGFwZShub2RlLCBbbmFtZSwgXCIoXCIsIC4uLmFyZ3MuZmxhdE1hcCgoYXJndW1lbnQsIGluZGV4KSA9PiBpbmRleCA/IFtcIixcIiwgYXJndW1lbnRdIDogW2FyZ3VtZW50XSksIFwiKVwiXSlcbiAgICByZXR1cm4ge25hbWUsIGFyZ3VtZW50czogYXJnc31cbiAgfVxuXG4gIC8qKlxuICAgKiBEZWNvZGVzIG9uZSBib3VuZGVkIG9yZGluYXJ5IFppZyBzdHJpbmcgbGl0ZXJhbC5cbiAgICogQHBhcmFtIHtDc3ROb2RlfSBub2RlIC0gU3RyaW5nIG5vZGUuXG4gICAqIEByZXR1cm5zIHtzdHJpbmd9IFVuaWNvZGUgc2NhbGFyIHZhbHVlLlxuICAgKi9cbiAgc3RyaW5nKG5vZGUpIHtcbiAgICBpZiAobm9kZS50eXBlICE9IFwic3RyaW5nXCIpIHRoaXMuZmFpbChub2RlLCBcIm9yZGluYXJ5IFVURi04IHN0cmluZyBsaXRlcmFsIHJlcXVpcmVkXCIpXG4gICAgY29uc3QgcGFydHMgPSB0aGlzLnBhcnRzKG5vZGUpXG5cbiAgICB0aGlzLnNoYXBlKG5vZGUsIFsnXCInLCAuLi5wYXJ0cy5zbGljZSgxLCAtMSksICdcIiddKVxuICAgIGxldCB2YWx1ZSA9IFwiXCJcblxuICAgIGZvciAoY29uc3QgcGFydCBvZiBwYXJ0cy5zbGljZSgxLCAtMSkpIHtcbiAgICAgIGNvbnN0IHNwZWxsaW5nID0gdGhpcy50ZXh0KHBhcnQpXG5cbiAgICAgIGlmIChwYXJ0LnR5cGUgPT0gXCJzdHJpbmdfY29udGVudFwiKSB7XG4gICAgICAgIGlmICgvW1xcclxcbl0vdS50ZXN0KHNwZWxsaW5nKSkgdGhpcy5mYWlsKHBhcnQsIFwicmF3IHN0cmluZyBsaW5lIHRlcm1pbmF0b3JcIilcbiAgICAgICAgdmFsdWUgKz0gc3BlbGxpbmdcbiAgICAgIH0gZWxzZSBpZiAocGFydC50eXBlID09IFwiZXNjYXBlX3NlcXVlbmNlXCIpIHtcbiAgICAgICAgY29uc3Qgc2ltcGxlID0gbmV3IE1hcChbW1wiXFxcXG5cIiwgXCJcXG5cIl0sIFtcIlxcXFxyXCIsIFwiXFxyXCJdLCBbXCJcXFxcdFwiLCBcIlxcdFwiXSwgW1wiXFxcXFxcXFxcIiwgXCJcXFxcXCJdLCBbJ1xcXFxcIicsICdcIiddXSlcblxuICAgICAgICBpZiAoc2ltcGxlLmhhcyhzcGVsbGluZykpIHZhbHVlICs9IHNpbXBsZS5nZXQoc3BlbGxpbmcpXG4gICAgICAgIGVsc2UgaWYgKC9eXFxcXHhbMC05YS1mQS1GXXsyfSQvdS50ZXN0KHNwZWxsaW5nKSkge1xuICAgICAgICAgIGNvbnN0IHNjYWxhciA9IE51bWJlci5wYXJzZUludChzcGVsbGluZy5zbGljZSgyKSwgMTYpXG5cbiAgICAgICAgICBpZiAoc2NhbGFyID4gMTI3KSB0aGlzLmZhaWwocGFydCwgXCJub24tQVNDSUkgYnl0ZSBlc2NhcGVcIilcbiAgICAgICAgICB2YWx1ZSArPSBTdHJpbmcuZnJvbUNvZGVQb2ludChzY2FsYXIpXG4gICAgICAgIH0gZWxzZSBpZiAoL15cXFxcdVxce1swLTlhLWZBLUZdezEsNn1cXH0kL3UudGVzdChzcGVsbGluZykpIHtcbiAgICAgICAgICBjb25zdCBzY2FsYXIgPSBOdW1iZXIucGFyc2VJbnQoc3BlbGxpbmcuc2xpY2UoMywgLTEpLCAxNilcblxuICAgICAgICAgIGlmIChzY2FsYXIgPiAweDEwRkZGRiB8fCBzY2FsYXIgPj0gMHhEODAwICYmIHNjYWxhciA8PSAweERGRkYpIHRoaXMuZmFpbChwYXJ0LCBcIm5vbi1zY2FsYXIgVW5pY29kZSBlc2NhcGVcIilcbiAgICAgICAgICB2YWx1ZSArPSBTdHJpbmcuZnJvbUNvZGVQb2ludChzY2FsYXIpXG4gICAgICAgIH0gZWxzZSB0aGlzLmZhaWwocGFydCwgXCJ1bnN1cHBvcnRlZCBzdHJpbmcgZXNjYXBlXCIpXG4gICAgICB9IGVsc2UgdGhpcy5mYWlsKHBhcnQsIFwic3RyaW5nIGNoaWxkXCIpXG4gICAgfVxuICAgIGlmICghaGFzT25seVVuaWNvZGVTY2FsYXJzKHZhbHVlKSkgdGhpcy5mYWlsKG5vZGUsIFwibm9uLXNjYWxhciBzdHJpbmcgdmFsdWVcIilcbiAgICByZXR1cm4gdmFsdWVcbiAgfVxuXG4gIC8qKlxuICAgKiBDb252ZXJ0cyBvbmUgc3VwcG9ydGVkIHNjYWxhciBleHByZXNzaW9uLlxuICAgKiBAcGFyYW0ge0NzdE5vZGV9IG5vZGUgLSBFeHByZXNzaW9uIG5vZGUuXG4gICAqIEByZXR1cm5zIHtFeHByZXNzaW9ufSBTZW1hbnRpYyBleHByZXNzaW9uLlxuICAgKi9cbiAgZXhwcmVzc2lvbihub2RlKSB7XG4gICAgY29uc3QgbG9jYXRpb24gPSB0aGlzLmxvY2F0aW9uKG5vZGUpXG5cbiAgICBpZiAobm9kZS50eXBlID09IFwicGFyZW50aGVzaXplZF9leHByZXNzaW9uXCIpIHtcbiAgICAgIGNvbnN0IHBhcnRzID0gdGhpcy5wYXJ0cyhub2RlKVxuXG4gICAgICB0aGlzLnNoYXBlKG5vZGUsIFtcIihcIiwgcGFydHNbMV0sIFwiKVwiXSlcbiAgICAgIHJldHVybiB0aGlzLmV4cHJlc3Npb24ocGFydHNbMV0pXG4gICAgfVxuICAgIGlmIChub2RlLnR5cGUgPT0gXCJpZGVudGlmaWVyXCIpIHtcbiAgICAgIGNvbnN0IHRlbXBvcmFyeSA9IHRoaXMudGVtcG9yYXJ5RXhwcmVzc2lvbnM/LmdldCh0aGlzLnRleHQobm9kZSkpXG5cbiAgICAgIGlmICh0ZW1wb3JhcnkpIHtcbiAgICAgICAgdGhpcy50ZW1wb3JhcnlFeHByZXNzaW9ucz8uZGVsZXRlKHRoaXMudGV4dChub2RlKSlcbiAgICAgICAgcmV0dXJuIHRlbXBvcmFyeVxuICAgICAgfVxuICAgICAgcmV0dXJuIHdpdGhQYXJzZXJSYW5nZXMoe2tpbmQ6IFwiSWRlbnRpZmllckV4cHJlc3Npb25cIiwgbG9jYXRpb24sIG5hbWU6IHRoaXMuaWRlbnRpZmllcihub2RlKX0sIHtuYW1lOiBsb2NhdGlvbn0pXG4gICAgfVxuICAgIGlmIChub2RlLnR5cGUgPT0gXCJpbnRlZ2VyXCIpIHtcbiAgICAgIGNvbnN0IHNwZWxsaW5nID0gdGhpcy50ZXh0KG5vZGUpXG4gICAgICBjb25zdCB2YWx1ZSA9IE51bWJlcihzcGVsbGluZylcblxuICAgICAgaWYgKCEvXig/OjB8WzEtOV1bMC05XSopJC91LnRlc3Qoc3BlbGxpbmcpIHx8ICFOdW1iZXIuaXNTYWZlSW50ZWdlcih2YWx1ZSkpIHRoaXMuZmFpbChub2RlLCBcIm5vbi1zYWZlIG9yIG5vbmNhbm9uaWNhbCBpNjQgbGl0ZXJhbFwiKVxuICAgICAgcmV0dXJuIHdpdGhQYXJzZXJSYW5nZXMoe2tpbmQ6IFwiSW50ZWdlckxpdGVyYWxcIiwgbG9jYXRpb24sIHZhbHVlfSwge2xpdGVyYWw6IGxvY2F0aW9ufSlcbiAgICB9XG4gICAgaWYgKG5vZGUudHlwZSA9PSBcImJvb2xlYW5cIikge1xuICAgICAgY29uc3Qgc3BlbGxpbmcgPSB0aGlzLnRleHQobm9kZSlcblxuICAgICAgaWYgKHNwZWxsaW5nICE9IFwidHJ1ZVwiICYmIHNwZWxsaW5nICE9IFwiZmFsc2VcIikgdGhpcy5mYWlsKG5vZGUsIFwiQm9vbGVhbiBsaXRlcmFsIHNwZWxsaW5nXCIpXG4gICAgICB0aGlzLnNoYXBlKG5vZGUsIFtzcGVsbGluZ10pXG4gICAgICByZXR1cm4gd2l0aFBhcnNlclJhbmdlcyh7a2luZDogXCJCb29sZWFuTGl0ZXJhbFwiLCBsb2NhdGlvbiwgdmFsdWU6IHNwZWxsaW5nID09IFwidHJ1ZVwifSwge2xpdGVyYWw6IGxvY2F0aW9ufSlcbiAgICB9XG4gICAgaWYgKG5vZGUudHlwZSA9PSBcInN0cmluZ1wiKSByZXR1cm4gd2l0aFBhcnNlclJhbmdlcyh7a2luZDogXCJTdHJpbmdMaXRlcmFsXCIsIGxvY2F0aW9uLCB2YWx1ZTogdGhpcy5zdHJpbmcobm9kZSl9LCB7bGl0ZXJhbDogbG9jYXRpb259KVxuICAgIGlmIChub2RlLnR5cGUgPT0gXCJ1bmFyeV9leHByZXNzaW9uXCIgfHwgbm9kZS50eXBlID09IFwiZXJyb3JfdW5pb25fdHlwZVwiKSB7XG4gICAgICBjb25zdCBwYXJ0cyA9IHRoaXMucGFydHMobm9kZSlcbiAgICAgIGNvbnN0IG9wZXJhdG9yID0gbm9kZS50eXBlID09IFwidW5hcnlfZXhwcmVzc2lvblwiID8gdGhpcy5maWVsZChub2RlLCBcIm9wZXJhdG9yXCIpIDogcGFydHNbMF1cbiAgICAgIGNvbnN0IG9wZXJhbmQgPSBub2RlLnR5cGUgPT0gXCJ1bmFyeV9leHByZXNzaW9uXCIgPyB0aGlzLmZpZWxkKG5vZGUsIFwiYXJndW1lbnRcIikgOiB0aGlzLmZpZWxkKG5vZGUsIFwib2tcIilcblxuICAgICAgdGhpcy5zaGFwZShub2RlLCBbb3BlcmF0b3IsIG9wZXJhbmRdKVxuICAgICAgaWYgKG9wZXJhdG9yLnR5cGUgIT0gXCItXCIgJiYgb3BlcmF0b3IudHlwZSAhPSBcIiFcIikgdGhpcy5mYWlsKG9wZXJhdG9yLCBcInVuYXJ5IG9wZXJhdG9yXCIpXG4gICAgICByZXR1cm4gdGhpcy51bmFyeShub2RlLCBvcGVyYXRvci50eXBlID09IFwiLVwiID8gXCJOZWdhdGVcIiA6IFwiTm90XCIsIHRoaXMuZXhwcmVzc2lvbihvcGVyYW5kKSwgb3BlcmF0b3IpXG4gICAgfVxuICAgIGlmIChub2RlLnR5cGUgPT0gXCJiaW5hcnlfZXhwcmVzc2lvblwiKSB7XG4gICAgICBjb25zdCBsZWZ0ID0gdGhpcy5maWVsZChub2RlLCBcImxlZnRcIilcbiAgICAgIGNvbnN0IHJpZ2h0ID0gdGhpcy5maWVsZChub2RlLCBcInJpZ2h0XCIpXG4gICAgICBjb25zdCBvcGVyYXRvciA9IHRoaXMuZmllbGQobm9kZSwgXCJvcGVyYXRvclwiKVxuICAgICAgY29uc3QgaW50ZW50ID0gYmluYXJ5T3BlcmF0aW9ucy5nZXQob3BlcmF0b3IudHlwZSlcblxuICAgICAgdGhpcy5zaGFwZShub2RlLCBbbGVmdCwgb3BlcmF0b3IsIHJpZ2h0XSlcbiAgICAgIGlmICghaW50ZW50KSB0aGlzLmZhaWwob3BlcmF0b3IsIFwidW5zdXBwb3J0ZWQgYmluYXJ5IG9wZXJhdG9yXCIpXG4gICAgICByZXR1cm4gdGhpcy5iaW5hcnkobm9kZSwgaW50ZW50LCB0aGlzLmV4cHJlc3Npb24obGVmdCksIHRoaXMuZXhwcmVzc2lvbihyaWdodCksIG9wZXJhdG9yKVxuICAgIH1cbiAgICBpZiAobm9kZS50eXBlID09IFwiY2FsbF9leHByZXNzaW9uXCIpIHtcbiAgICAgIGNvbnN0IGNhbGwgPSB0aGlzLmNhbGwobm9kZSlcblxuICAgICAgaWYgKGNhbGwubmFtZS50eXBlICE9IFwiaWRlbnRpZmllclwiKSB0aGlzLmZhaWwoY2FsbC5uYW1lLCBcImRpcmVjdCBmdW5jdGlvbiBjYWxsIHJlcXVpcmVkXCIpXG4gICAgICBjb25zdCBuYW1lID0gdGhpcy50ZXh0KGNhbGwubmFtZSlcblxuICAgICAgaWYgKG5hbWUgPT0gXCJzZW1hbnRpZm9sZF9pbnRlZ2VyX25lZ2F0ZVwiKSB7XG4gICAgICAgIGlmIChjYWxsLmFyZ3VtZW50cy5sZW5ndGggIT0gMSkgdGhpcy5mYWlsKG5vZGUsIFwibmVnYXRpb24gaGVscGVyIGFyaXR5XCIpXG4gICAgICAgIHJldHVybiB0aGlzLnVuYXJ5KG5vZGUsIFwiTmVnYXRlXCIsIHRoaXMuZXhwcmVzc2lvbihjYWxsLmFyZ3VtZW50c1swXSksIGNhbGwubmFtZSlcbiAgICAgIH1cbiAgICAgIGNvbnN0IGludGVudCA9IGhlbHBlck9wZXJhdGlvbnMuZ2V0KG5hbWUpXG5cbiAgICAgIGlmIChpbnRlbnQpIHtcbiAgICAgICAgaWYgKGNhbGwuYXJndW1lbnRzLmxlbmd0aCAhPSAyKSB0aGlzLmZhaWwobm9kZSwgXCJvcGVyYXRvciBoZWxwZXIgYXJpdHlcIilcbiAgICAgICAgcmV0dXJuIHRoaXMuYmluYXJ5KG5vZGUsIGludGVudCwgdGhpcy5leHByZXNzaW9uKGNhbGwuYXJndW1lbnRzWzBdKSwgdGhpcy5leHByZXNzaW9uKGNhbGwuYXJndW1lbnRzWzFdKSwgY2FsbC5uYW1lKVxuICAgICAgfVxuICAgICAgaWYgKG5hbWUuc3RhcnRzV2l0aChcInNlbWFudGlmb2xkX1wiKSkgdGhpcy5mYWlsKGNhbGwubmFtZSwgXCJzdXBwb3J0IGhlbHBlciBvdXRzaWRlIGl0cyBleGFjdCBzZW1hbnRpYyByb2xlXCIpXG4gICAgICBjb25zdCBjYWxsZWUgPSB0aGlzLmlkZW50aWZpZXIoY2FsbC5uYW1lKVxuXG4gICAgICByZXR1cm4gd2l0aFBhcnNlclJhbmdlcyh7a2luZDogXCJDYWxsRXhwcmVzc2lvblwiLCBsb2NhdGlvbiwgY2FsbGVlLCBhcmd1bWVudHM6IGNhbGwuYXJndW1lbnRzLm1hcChhcmd1bWVudCA9PiB0aGlzLmV4cHJlc3Npb24oYXJndW1lbnQpKX0sIHtjYWxsZWU6IHRoaXMubG9jYXRpb24oY2FsbC5uYW1lKX0pXG4gICAgfVxuICAgIHJldHVybiB0aGlzLmZhaWwobm9kZSlcbiAgfVxuXG4gIC8qKlxuICAgKiBBZGFwdHMgb25lIHR5cGVkIGJpbmFyeSBvcGVyYXRvci5cbiAgICogQHBhcmFtIHtDc3ROb2RlfSBub2RlIC0gV2hvbGUgZXhwcmVzc2lvbiBub2RlLlxuICAgKiBAcGFyYW0ge3N0cmluZ30gaW50ZW50IC0gU2hhcmVkIG9wZXJhdG9yIGludGVudC5cbiAgICogQHBhcmFtIHtFeHByZXNzaW9ufSBsZWZ0IC0gTGVmdCBvcGVyYW5kLlxuICAgKiBAcGFyYW0ge0V4cHJlc3Npb259IHJpZ2h0IC0gUmlnaHQgb3BlcmFuZC5cbiAgICogQHBhcmFtIHtDc3ROb2RlfSBvcGVyYXRvciAtIFNvdXJjZSBvcGVyYXRvciBvY2N1cnJlbmNlLlxuICAgKiBAcmV0dXJucyB7RXhwcmVzc2lvbn0gQWRhcHRlZCBzZW1hbnRpYyBleHByZXNzaW9uLlxuICAgKi9cbiAgYmluYXJ5KG5vZGUsIGludGVudCwgbGVmdCwgcmlnaHQsIG9wZXJhdG9yKSB7XG4gICAgY29uc3QgZXhwcmVzc2lvbiA9IC8qKiBAdHlwZSB7RXhwcmVzc2lvbn0gKi8gKHdpdGhBZGFwdGVkT3BlcmF0aW9uKHdpdGhQYXJzZXJSYW5nZXMoe2tpbmQ6IFwiQmluYXJ5RXhwcmVzc2lvblwiLCBsb2NhdGlvbjogdGhpcy5sb2NhdGlvbihub2RlKSwgbGVmdCwgcmlnaHR9LFxuICAgICAge29wZXJhdG9yOiB0aGlzLmxvY2F0aW9uKG9wZXJhdG9yKX0pLCAvKiogQHR5cGUge2ltcG9ydChcIi4uL3NlbWFudGljL29wZXJhdG9ycy5qc1wiKS5BZGFwdGVkT3BlcmF0aW9ufSAqLyAoaW50ZW50KSkpXG5cbiAgICB0aGlzLm9wZXJhdGlvbnMuc2V0KGV4cHJlc3Npb24sIHtub2RlOiBvcGVyYXRvciwgc3BlbGxpbmc6IHRoaXMudGV4dChvcGVyYXRvcil9KVxuICAgIHJldHVybiBleHByZXNzaW9uXG4gIH1cblxuICAvKipcbiAgICogQWRhcHRzIG9uZSB0eXBlZCB1bmFyeSBvcGVyYXRvci5cbiAgICogQHBhcmFtIHtDc3ROb2RlfSBub2RlIC0gV2hvbGUgZXhwcmVzc2lvbiBub2RlLlxuICAgKiBAcGFyYW0ge1wiTmVnYXRlXCIgfCBcIk5vdFwifSBpbnRlbnQgLSBTaGFyZWQgb3BlcmF0b3IgaW50ZW50LlxuICAgKiBAcGFyYW0ge0V4cHJlc3Npb259IG9wZXJhbmQgLSBDb252ZXJ0ZWQgb3BlcmFuZC5cbiAgICogQHBhcmFtIHtDc3ROb2RlfSBvcGVyYXRvciAtIFNvdXJjZSBvcGVyYXRvciBvY2N1cnJlbmNlLlxuICAgKiBAcmV0dXJucyB7RXhwcmVzc2lvbn0gQWRhcHRlZCBzZW1hbnRpYyBleHByZXNzaW9uLlxuICAgKi9cbiAgdW5hcnkobm9kZSwgaW50ZW50LCBvcGVyYW5kLCBvcGVyYXRvcikge1xuICAgIGNvbnN0IGV4cHJlc3Npb24gPSAvKiogQHR5cGUge0V4cHJlc3Npb259ICovICh3aXRoQWRhcHRlZE9wZXJhdGlvbih3aXRoUGFyc2VyUmFuZ2VzKHtraW5kOiBcIlVuYXJ5RXhwcmVzc2lvblwiLCBsb2NhdGlvbjogdGhpcy5sb2NhdGlvbihub2RlKSwgb3BlcmFuZH0sXG4gICAgICB7b3BlcmF0b3I6IHRoaXMubG9jYXRpb24ob3BlcmF0b3IpfSksIGludGVudCkpXG5cbiAgICB0aGlzLm9wZXJhdGlvbnMuc2V0KGV4cHJlc3Npb24sIHtub2RlOiBvcGVyYXRvciwgc3BlbGxpbmc6IHRoaXMudGV4dChvcGVyYXRvcil9KVxuICAgIHJldHVybiBleHByZXNzaW9uXG4gIH1cblxuICAvKipcbiAgICogQ29udmVydHMgb25lIHN1cHBvcnRlZCBzdGF0ZW1lbnQuXG4gICAqIEBwYXJhbSB7Q3N0Tm9kZX0gbm9kZSAtIFN0YXRlbWVudCBub2RlLlxuICAgKiBAcmV0dXJucyB7U3RhdGVtZW50fSBTZW1hbnRpYyBzdGF0ZW1lbnQuXG4gICAqL1xuICBzdGF0ZW1lbnQobm9kZSkge1xuICAgIGNvbnN0IGxvY2F0aW9uID0gdGhpcy5sb2NhdGlvbihub2RlKVxuICAgIGNvbnN0IHBhcnRzID0gdGhpcy5wYXJ0cyhub2RlKVxuXG4gICAgaWYgKG5vZGUudHlwZSA9PSBcInZhcmlhYmxlX2RlY2xhcmF0aW9uXCIpIHtcbiAgICAgIGlmIChbXCJjb25zdFwiLCBcInZhclwiXS5pbmNsdWRlcyhwYXJ0c1swXT8udHlwZSkpIHtcbiAgICAgICAgY29uc3QgdHlwZU5vZGUgPSBub2RlLmNoaWxkcmVuLmZpbmQoKHtmaWVsZH0pID0+IGZpZWxkID09IFwidHlwZVwiKT8ubm9kZVxuXG4gICAgICAgIGlmICghdHlwZU5vZGUpIHJldHVybiBtaXNzaW5nVHlwZShcInppZ1wiLCBcImxvY2FsXCIsIGxvY2F0aW9uKVxuICAgICAgICBjb25zdCBuYW1lID0gcGFydHNbMV1cbiAgICAgICAgY29uc3QgdmFsdWUgPSBwYXJ0c1s1XVxuXG4gICAgICAgIHRoaXMuc2hhcGUobm9kZSwgW3BhcnRzWzBdLCBuYW1lLCBcIjpcIiwgdHlwZU5vZGUsIFwiPVwiLCB2YWx1ZSwgXCI7XCJdKVxuICAgICAgICByZXR1cm4gd2l0aFBhcnNlclJhbmdlcyh7a2luZDogXCJMb2NhbERlY2xhcmF0aW9uXCIsIGxvY2F0aW9uLCBuYW1lOiB0aGlzLmlkZW50aWZpZXIobmFtZSksIHR5cGU6IC8qKiBAdHlwZSB7aW1wb3J0KFwiLi4vc2VtYW50aWMvdHlwZXMuanNcIikuVHlwZVJlZmVyZW5jZX0gKi8gKHRoaXMudHlwZSh0eXBlTm9kZSkpLCBtdXRhYmxlOiBwYXJ0c1swXS50eXBlID09IFwidmFyXCIsXG4gICAgICAgICAgaW5pdGlhbGl6ZXI6IHRoaXMuZXhwcmVzc2lvbih2YWx1ZSl9LCB7bmFtZTogdGhpcy5sb2NhdGlvbihuYW1lKSwgb3BlcmF0b3I6IHRoaXMubG9jYXRpb24ocGFydHNbNF0pfSlcbiAgICAgIH1cbiAgICAgIGNvbnN0IHRhcmdldE5vZGUgPSBwYXJ0c1swXVxuICAgICAgY29uc3QgdmFsdWUgPSBwYXJ0c1syXVxuXG4gICAgICB0aGlzLnNoYXBlKG5vZGUsIFt0YXJnZXROb2RlLCBcIj1cIiwgdmFsdWUsIFwiO1wiXSlcbiAgICAgIGNvbnN0IHRhcmdldCA9IHdpdGhQYXJzZXJSYW5nZXMoe2tpbmQ6IC8qKiBAdHlwZSB7Y29uc3R9ICovIChcIklkZW50aWZpZXJFeHByZXNzaW9uXCIpLCBsb2NhdGlvbjogdGhpcy5sb2NhdGlvbih0YXJnZXROb2RlKSwgbmFtZTogdGhpcy5pZGVudGlmaWVyKHRhcmdldE5vZGUpfSwge25hbWU6IHRoaXMubG9jYXRpb24odGFyZ2V0Tm9kZSl9KVxuXG4gICAgICByZXR1cm4gd2l0aFBhcnNlclJhbmdlcyh7a2luZDogXCJBc3NpZ25tZW50U3RhdGVtZW50XCIsIGxvY2F0aW9uLCB0YXJnZXQsIGV4cHJlc3Npb246IHRoaXMuZXhwcmVzc2lvbih2YWx1ZSl9LCB7b3BlcmF0b3I6IHRoaXMubG9jYXRpb24ocGFydHNbMV0pfSlcbiAgICB9XG4gICAgaWYgKG5vZGUudHlwZSA9PSBcImlmX3N0YXRlbWVudFwiKSByZXR1cm4gdGhpcy5jb25kaXRpb25hbChub2RlKVxuICAgIGlmIChub2RlLnR5cGUgIT0gXCJleHByZXNzaW9uX3N0YXRlbWVudFwiKSB0aGlzLmZhaWwobm9kZSwgXCJleHBsaWNpdCBzdGF0ZW1lbnQgcmVxdWlyZWRcIilcbiAgICBjb25zdCBleHByZXNzaW9uID0gcGFydHNbMF1cblxuICAgIHRoaXMuc2hhcGUobm9kZSwgW2V4cHJlc3Npb24sIFwiO1wiXSlcbiAgICBpZiAoZXhwcmVzc2lvbi50eXBlID09IFwicmV0dXJuX2V4cHJlc3Npb25cIikge1xuICAgICAgY29uc3QgcmV0dXJuZWQgPSB0aGlzLnBhcnRzKGV4cHJlc3Npb24pXG5cbiAgICAgIGlmIChyZXR1cm5lZC5sZW5ndGggPT0gMSkge1xuICAgICAgICB0aGlzLnNoYXBlKGV4cHJlc3Npb24sIFtcInJldHVyblwiXSlcbiAgICAgICAgcmV0dXJuIHtraW5kOiBcIlJldHVyblN0YXRlbWVudFwiLCBsb2NhdGlvbn1cbiAgICAgIH1cbiAgICAgIHRoaXMuc2hhcGUoZXhwcmVzc2lvbiwgW1wicmV0dXJuXCIsIHJldHVybmVkWzFdXSlcbiAgICAgIHJldHVybiB7a2luZDogXCJSZXR1cm5TdGF0ZW1lbnRcIiwgbG9jYXRpb24sIGV4cHJlc3Npb246IHRoaXMuZXhwcmVzc2lvbihyZXR1cm5lZFsxXSl9XG4gICAgfVxuICAgIGlmIChleHByZXNzaW9uLnR5cGUgIT0gXCJjYWxsX2V4cHJlc3Npb25cIikgdGhpcy5mYWlsKGV4cHJlc3Npb24sIFwiZGlyZWN0IHZvaWQgY2FsbCBzdGF0ZW1lbnQgcmVxdWlyZWRcIilcbiAgICBjb25zdCBjYWxsID0gdGhpcy5jYWxsKGV4cHJlc3Npb24pXG4gICAgY29uc3QgbmFtZSA9IHRoaXMudGV4dChjYWxsLm5hbWUpXG5cbiAgICBpZiAoL15zZW1hbnRpZm9sZF9wcmludF8oPzppbnRlZ2VyfGJvb2xlYW58c3RyaW5nKSQvdS50ZXN0KG5hbWUpKSB7XG4gICAgICBpZiAoY2FsbC5uYW1lLnR5cGUgIT0gXCJpZGVudGlmaWVyXCIgfHwgY2FsbC5hcmd1bWVudHMubGVuZ3RoICE9IDEpIHRoaXMuZmFpbChleHByZXNzaW9uLCBcImV4YWN0IHByaW50IGhlbHBlciBjYWxsIHJlcXVpcmVkXCIpXG4gICAgICBjb25zdCBzdGF0ZW1lbnQgPSB7a2luZDogLyoqIEB0eXBlIHtjb25zdH0gKi8gKFwiUHJpbnRTdGF0ZW1lbnRcIiksIGxvY2F0aW9uLCBleHByZXNzaW9uOiB0aGlzLmV4cHJlc3Npb24oY2FsbC5hcmd1bWVudHNbMF0pfVxuXG4gICAgICB0aGlzLnByaW50cy5zZXQoc3RhdGVtZW50LCB7bm9kZTogY2FsbC5uYW1lLCB0eXBlOiBuYW1lLnNsaWNlKFwic2VtYW50aWZvbGRfcHJpbnRfXCIubGVuZ3RoKX0pXG4gICAgICByZXR1cm4gc3RhdGVtZW50XG4gICAgfVxuICAgIGNvbnN0IHZhbHVlID0gdGhpcy5leHByZXNzaW9uKGV4cHJlc3Npb24pXG5cbiAgICBpZiAodmFsdWUua2luZCAhPSBcIkNhbGxFeHByZXNzaW9uXCIpIHRoaXMuZmFpbChleHByZXNzaW9uLCBcImRpcmVjdCB2b2lkIGNhbGwgc3RhdGVtZW50IHJlcXVpcmVkXCIpXG4gICAgcmV0dXJuIHtraW5kOiBcIkV4cHJlc3Npb25TdGF0ZW1lbnRcIiwgbG9jYXRpb24sIGV4cHJlc3Npb246IHZhbHVlfVxuICB9XG5cbiAgLyoqXG4gICAqIENvbnZlcnRzIG9uZSBzdHJpY3QgQm9vbGVhbiBjb25kaXRpb25hbC5cbiAgICogQHBhcmFtIHtDc3ROb2RlfSBub2RlIC0gSWYtc3RhdGVtZW50IG5vZGUuXG4gICAqIEByZXR1cm5zIHtpbXBvcnQoXCIuLi9zZW1hbnRpYy90eXBlcy5qc1wiKS5JZlN0YXRlbWVudH0gU2VtYW50aWMgY29uZGl0aW9uYWwuXG4gICAqL1xuICBjb25kaXRpb25hbChub2RlKSB7XG4gICAgY29uc3QgY29uZGl0aW9uID0gdGhpcy5maWVsZChub2RlLCBcImNvbmRpdGlvblwiKVxuICAgIGNvbnN0IGJvZHkgPSB0aGlzLmZpZWxkKG5vZGUsIFwiYm9keVwiKVxuICAgIGNvbnN0IGFsdGVybmF0aXZlID0gdGhpcy5wYXJ0cyhub2RlKS5maW5kKGNoaWxkID0+IGNoaWxkLnR5cGUgPT0gXCJlbHNlX2NsYXVzZVwiKVxuXG4gICAgdGhpcy5zaGFwZShub2RlLCBbXCJpZlwiLCBcIihcIiwgY29uZGl0aW9uLCBcIilcIiwgYm9keSwgLi4uKGFsdGVybmF0aXZlID8gW2FsdGVybmF0aXZlXSA6IFtdKV0pXG4gICAgY29uc3Qgc3RhdGVtZW50ID0ge2tpbmQ6IC8qKiBAdHlwZSB7Y29uc3R9ICovIChcIklmU3RhdGVtZW50XCIpLCBsb2NhdGlvbjogdGhpcy5sb2NhdGlvbihub2RlKSwgY29uZGl0aW9uOiB0aGlzLmV4cHJlc3Npb24oY29uZGl0aW9uKSwgY29uc2VxdWVudDogdGhpcy5ibG9ja0V4cHJlc3Npb24oYm9keSl9XG5cbiAgICBpZiAoIWFsdGVybmF0aXZlKSByZXR1cm4gc3RhdGVtZW50XG4gICAgY29uc3QgYnJhbmNoID0gdGhpcy5maWVsZChhbHRlcm5hdGl2ZSwgXCJhbHRlcm5hdGl2ZVwiKVxuXG4gICAgdGhpcy5zaGFwZShhbHRlcm5hdGl2ZSwgW1wiZWxzZVwiLCBicmFuY2hdKVxuICAgIGlmIChicmFuY2gudHlwZSAhPSBcImxhYmVsZWRfc3RhdGVtZW50XCIpIHRoaXMuZmFpbChicmFuY2gsIFwiYnJhY2VkIGVsc2UgYmxvY2sgcmVxdWlyZWRcIilcbiAgICBjb25zdCBibG9jayA9IHRoaXMucGFydHMoYnJhbmNoKVswXVxuXG4gICAgdGhpcy5zaGFwZShicmFuY2gsIFtibG9ja10pXG4gICAgcmV0dXJuIHsuLi5zdGF0ZW1lbnQsIGFsdGVybmF0ZTogdGhpcy5ibG9jayhibG9jayl9XG4gIH1cblxuICAvKipcbiAgICogVW53cmFwcyBvbmUgYnJhY2VkIGNvbmRpdGlvbmFsIGJsb2NrIGV4cHJlc3Npb24uXG4gICAqIEBwYXJhbSB7Q3N0Tm9kZX0gbm9kZSAtIEJsb2NrLWV4cHJlc3Npb24gbm9kZS5cbiAgICogQHJldHVybnMge2ltcG9ydChcIi4uL3NlbWFudGljL3R5cGVzLmpzXCIpLkJsb2NrfSBTZW1hbnRpYyBibG9jay5cbiAgICovXG4gIGJsb2NrRXhwcmVzc2lvbihub2RlKSB7XG4gICAgaWYgKG5vZGUudHlwZSAhPSBcImJsb2NrX2V4cHJlc3Npb25cIikgdGhpcy5mYWlsKG5vZGUsIFwiYnJhY2VkIGNvbmRpdGlvbmFsIGJsb2NrIHJlcXVpcmVkXCIpXG4gICAgY29uc3QgYmxvY2sgPSB0aGlzLnBhcnRzKG5vZGUpWzBdXG5cbiAgICB0aGlzLnNoYXBlKG5vZGUsIFtibG9ja10pXG4gICAgcmV0dXJuIHRoaXMuYmxvY2soYmxvY2spXG4gIH1cblxuICAvKipcbiAgICogQ29udmVydHMgb25lIGxleGljYWwgYmxvY2sgd2hpbGUgY29uc3VtaW5nIGV4YWN0IGNvbXBpbGVyIHNjYWZmb2xkcy5cbiAgICogQHBhcmFtIHtDc3ROb2RlfSBub2RlIC0gQmxvY2sgbm9kZS5cbiAgICogQHBhcmFtIHtudW1iZXJ9IFtza2lwXSAtIEZpeGVkIGxlYWRpbmcgZ2VuZXJhdGVkIHN0YXRlbWVudHMgdG8gb21pdC5cbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuLi9zZW1hbnRpYy90eXBlcy5qc1wiKS5QYXJhbWV0ZXJbXX0gW3BhcmFtZXRlcnNdIC0gUGFyYW1ldGVycyByZXF1aXJpbmcgc2NhZmZvbGQgY2hlY2tzLlxuICAgKiBAcmV0dXJucyB7aW1wb3J0KFwiLi4vc2VtYW50aWMvdHlwZXMuanNcIikuQmxvY2t9IFNlbWFudGljIGJsb2NrLlxuICAgKi9cbiAgYmxvY2sobm9kZSwgc2tpcCA9IDAsIHBhcmFtZXRlcnMgPSBbXSkge1xuICAgIGlmIChub2RlLnR5cGUgIT0gXCJibG9ja1wiKSB0aGlzLmZhaWwobm9kZSwgXCJicmFjZWQgYmxvY2sgcmVxdWlyZWRcIilcbiAgICBjb25zdCBwYXJ0cyA9IHRoaXMucGFydHMobm9kZSlcblxuICAgIHRoaXMuc2hhcGUobm9kZSwgW1wie1wiLCAuLi5wYXJ0cy5zbGljZSgxLCAtMSksIFwifVwiXSlcbiAgICBjb25zdCBzb3VyY2VTdGF0ZW1lbnRzID0gdGhpcy5zaWduaWZpY2FudChub2RlKS5zbGljZSgxICsgc2tpcCwgLTEpXG4gICAgcmV0dXJuIHtraW5kOiBcIkJsb2NrXCIsIGxvY2F0aW9uOiB0aGlzLmxvY2F0aW9uKG5vZGUpLCBzdGF0ZW1lbnRzOiB0aGlzLmdlbmVyYXRlZFxuICAgICAgPyB0aGlzLmdlbmVyYXRlZFN0YXRlbWVudHMoc291cmNlU3RhdGVtZW50cywgcGFyYW1ldGVycylcbiAgICAgIDogdGhpcy5kaXJlY3RTdGF0ZW1lbnRzKHNvdXJjZVN0YXRlbWVudHMsIHBhcmFtZXRlcnMpfVxuICB9XG5cbiAgLyoqXG4gICAqIENvbnZlcnRzIHRoZSBsZWdhY3kgZGlyZWN0IHN0YXRlbWVudCBzaGFwZSB3aGVuIGRpYWdub3NpbmcgYSBtaXNzaW5nIGdlbmVyYXRlZCBtYXJrZXIuXG4gICAqIEBwYXJhbSB7Q3N0Tm9kZVtdfSBzb3VyY2VTdGF0ZW1lbnRzIC0gT3JkZXJlZCBkaXJlY3QgY2hpbGRyZW4uXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vc2VtYW50aWMvdHlwZXMuanNcIikuUGFyYW1ldGVyW119IHBhcmFtZXRlcnMgLSBGdW5jdGlvbiBwYXJhbWV0ZXJzLlxuICAgKiBAcmV0dXJucyB7U3RhdGVtZW50W119IFNlbWFudGljIHN0YXRlbWVudHMuXG4gICAqL1xuICBkaXJlY3RTdGF0ZW1lbnRzKHNvdXJjZVN0YXRlbWVudHMsIHBhcmFtZXRlcnMpIHtcbiAgICBsZXQgY3Vyc29yID0gMFxuXG4gICAgZm9yIChjb25zdCBwYXJhbWV0ZXIgb2YgcGFyYW1ldGVycykge1xuICAgICAgY29uc3Qga2luZCA9IHNvdXJjZVN0YXRlbWVudHNbY3Vyc29yXSA/IHRoaXMudXNlU2NhZmZvbGQoc291cmNlU3RhdGVtZW50c1tjdXJzb3JdLCBwYXJhbWV0ZXIubmFtZSkgOiB1bmRlZmluZWRcblxuICAgICAgdGhpcy5zY2FmZm9sZHMuc2V0KHBhcmFtZXRlciwga2luZCA/PyBcIm5vbmVcIilcbiAgICAgIGlmIChraW5kKSBjdXJzb3IgKz0gMVxuICAgIH1cbiAgICAvKiogQHR5cGUge1N0YXRlbWVudFtdfSAqL1xuICAgIGNvbnN0IHN0YXRlbWVudHMgPSBbXVxuXG4gICAgd2hpbGUgKGN1cnNvciA8IHNvdXJjZVN0YXRlbWVudHMubGVuZ3RoKSB7XG4gICAgICBjb25zdCBzdGF0ZW1lbnQgPSB0aGlzLnN0YXRlbWVudChzb3VyY2VTdGF0ZW1lbnRzW2N1cnNvcl0pXG5cbiAgICAgIHN0YXRlbWVudHMucHVzaChzdGF0ZW1lbnQpXG4gICAgICBjdXJzb3IgKz0gMVxuICAgICAgaWYgKHN0YXRlbWVudC5raW5kID09IFwiTG9jYWxEZWNsYXJhdGlvblwiKSB7XG4gICAgICAgIGNvbnN0IGtpbmQgPSBzb3VyY2VTdGF0ZW1lbnRzW2N1cnNvcl0gPyB0aGlzLnVzZVNjYWZmb2xkKHNvdXJjZVN0YXRlbWVudHNbY3Vyc29yXSwgc3RhdGVtZW50Lm5hbWUpIDogdW5kZWZpbmVkXG5cbiAgICAgICAgdGhpcy5zY2FmZm9sZHMuc2V0KHN0YXRlbWVudCwga2luZCA/PyBcIm5vbmVcIilcbiAgICAgICAgaWYgKGtpbmQpIGN1cnNvciArPSAxXG4gICAgICB9XG4gICAgfVxuICAgIHJldHVybiBzdGF0ZW1lbnRzXG4gIH1cblxuICAvKipcbiAgICogUmVjb25zdHJ1Y3RzIGNvbXBsZXRlIGdlbmVyYXRlZCBzdGF0ZW1lbnQgcmVnaW9ucyBiZWZvcmUgY2Fub25pY2FsIHdob2xlLUNTVCB2ZXJpZmljYXRpb24uXG4gICAqIEBwYXJhbSB7Q3N0Tm9kZVtdfSBzb3VyY2VTdGF0ZW1lbnRzIC0gU2lnbmlmaWNhbnQgZGlyZWN0IGJsb2NrIGNoaWxkcmVuLlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4uL3NlbWFudGljL3R5cGVzLmpzXCIpLlBhcmFtZXRlcltdfSBwYXJhbWV0ZXJzIC0gRnVuY3Rpb24gcGFyYW1ldGVycy5cbiAgICogQHJldHVybnMge1N0YXRlbWVudFtdfSBSZWNvbnN0cnVjdGVkIHNlbWFudGljIHN0YXRlbWVudHMuXG4gICAqL1xuICBnZW5lcmF0ZWRTdGF0ZW1lbnRzKHNvdXJjZVN0YXRlbWVudHMsIHBhcmFtZXRlcnMpIHtcbiAgICAvKiogQHR5cGUge1N0YXRlbWVudFtdfSAqL1xuICAgIGNvbnN0IHN0YXRlbWVudHMgPSBbXVxuICAgIGxldCBjdXJzb3IgPSAwXG5cbiAgICBmb3IgKGNvbnN0IHBhcmFtZXRlciBvZiBwYXJhbWV0ZXJzKSB7XG4gICAgICBjb25zdCBraW5kID0gc291cmNlU3RhdGVtZW50c1tjdXJzb3JdID8gdGhpcy51c2VTY2FmZm9sZChzb3VyY2VTdGF0ZW1lbnRzW2N1cnNvcl0sIHBhcmFtZXRlci5uYW1lKSA6IHVuZGVmaW5lZFxuXG4gICAgICB0aGlzLnNjYWZmb2xkcy5zZXQocGFyYW1ldGVyLCBraW5kID8/IFwibm9uZVwiKVxuICAgICAgaWYgKGtpbmQpIGN1cnNvciArPSAxXG4gICAgfVxuICAgIHdoaWxlIChjdXJzb3IgPCBzb3VyY2VTdGF0ZW1lbnRzLmxlbmd0aCkge1xuICAgICAgY29uc3QgYmVnaW4gPSBzb3VyY2VTdGF0ZW1lbnRzW2N1cnNvcisrXVxuICAgICAgY29uc3QgbWF0Y2ggPSBiZWdpbi50eXBlID09IFwiY29tbWVudFwiICYmXG4gICAgICAgIC9eXFwvXFwvIHNlbWFudGlmb2xkOm9yZGVyZWQtZXhwcmVzc2lvbjp6aWc6djEgYmVnaW4gKFswLTldezZ9KSAoWzAtOWEtZl17NjR9KSQvdS5leGVjKHRoaXMubWFya2VyKGJlZ2luKSlcblxuICAgICAgaWYgKCFtYXRjaCkgdGhpcy5mYWlsKGJlZ2luLCBcImNvbXBsZXRlIGdlbmVyYXRlZCBvcmRlcmVkIHN0YXRlbWVudCByZWdpb24gcmVxdWlyZWRcIilcbiAgICAgIGNvbnN0IG91dGVyRXhwcmVzc2lvbnMgPSB0aGlzLnRlbXBvcmFyeUV4cHJlc3Npb25zXG4gICAgICBjb25zdCBvdXRlck5hbWVzID0gdGhpcy50ZW1wb3JhcnlOYW1lc1xuXG4gICAgICB0aGlzLnRlbXBvcmFyeUV4cHJlc3Npb25zID0gbmV3IE1hcCgpXG4gICAgICB0aGlzLnRlbXBvcmFyeU5hbWVzID0gbmV3IFNldCgpXG4gICAgICB3aGlsZSAoY3Vyc29yIDwgc291cmNlU3RhdGVtZW50cy5sZW5ndGggJiYgdGhpcy50ZW1wb3JhcnlEZWNsYXJhdGlvbihzb3VyY2VTdGF0ZW1lbnRzW2N1cnNvcl0pKSB7XG4gICAgICAgIGN1cnNvciA9IHRoaXMucmVhZFRlbXBvcmFyeShzb3VyY2VTdGF0ZW1lbnRzLCBjdXJzb3IpXG4gICAgICB9XG4gICAgICBjb25zdCBjb25zdW1lciA9IHNvdXJjZVN0YXRlbWVudHNbY3Vyc29yKytdXG5cbiAgICAgIGlmICghY29uc3VtZXIpIHRoaXMuZmFpbChiZWdpbiwgXCJtaXNzaW5nIGdlbmVyYXRlZCBvcmRlcmVkIGNvbnN1bWVyXCIpXG4gICAgICBjb25zdCBzdGF0ZW1lbnQgPSB0aGlzLnN0YXRlbWVudChjb25zdW1lcilcblxuICAgICAgaWYgKHRoaXMudGVtcG9yYXJ5RXhwcmVzc2lvbnMuc2l6ZSAhPSAwKSB0aGlzLmZhaWwoY29uc3VtZXIsIFwidW5jb25zdW1lZCBnZW5lcmF0ZWQgb3JkZXJlZCB0ZW1wb3JhcnlcIilcbiAgICAgIGlmIChzdGF0ZW1lbnQua2luZCA9PSBcIkxvY2FsRGVjbGFyYXRpb25cIikge1xuICAgICAgICBjb25zdCBraW5kID0gc291cmNlU3RhdGVtZW50c1tjdXJzb3JdID8gdGhpcy51c2VTY2FmZm9sZChzb3VyY2VTdGF0ZW1lbnRzW2N1cnNvcl0sIHN0YXRlbWVudC5uYW1lKSA6IHVuZGVmaW5lZFxuXG4gICAgICAgIHRoaXMuc2NhZmZvbGRzLnNldChzdGF0ZW1lbnQsIGtpbmQgPz8gXCJub25lXCIpXG4gICAgICAgIGlmIChraW5kKSBjdXJzb3IgKz0gMVxuICAgICAgfVxuICAgICAgY29uc3QgZW5kID0gc291cmNlU3RhdGVtZW50c1tjdXJzb3IrK11cblxuICAgICAgaWYgKCFlbmQgfHwgZW5kLnR5cGUgIT0gXCJjb21tZW50XCIgfHwgdGhpcy5tYXJrZXIoZW5kKSAhPVxuICAgICAgICBgLy8gc2VtYW50aWZvbGQ6b3JkZXJlZC1leHByZXNzaW9uOnppZzp2MSBlbmQgJHttYXRjaFsxXX0gJHttYXRjaFsyXX1gKSB0aGlzLmZhaWwoZW5kID8/IGJlZ2luLCBcImdlbmVyYXRlZCBvcmRlcmVkIG1hcmtlciBwYWlyXCIpXG4gICAgICB0aGlzLnRlbXBvcmFyeUV4cHJlc3Npb25zID0gb3V0ZXJFeHByZXNzaW9uc1xuICAgICAgdGhpcy50ZW1wb3JhcnlOYW1lcyA9IG91dGVyTmFtZXNcbiAgICAgIHN0YXRlbWVudHMucHVzaChzdGF0ZW1lbnQpXG4gICAgfVxuICAgIHJldHVybiBzdGF0ZW1lbnRzXG4gIH1cblxuICAvKipcbiAgICogSWRlbnRpZmllcyBhIHJlc2VydmVkIG9yZGVyZWQgdGVtcG9yYXJ5IGRlY2xhcmF0aW9uIGF0IHRoZSBjdXJyZW50IHJlZ2lvbiBsZXZlbC5cbiAgICogQHBhcmFtIHtDc3ROb2RlfSBub2RlIC0gQ2FuZGlkYXRlIGRpcmVjdCBjaGlsZC5cbiAgICogQHJldHVybnMge2Jvb2xlYW59IFdoZXRoZXIgaXQgZGVjbGFyZXMgYSByZXNlcnZlZCBvcmRlcmVkIHRlbXBvcmFyeS5cbiAgICovXG4gIHRlbXBvcmFyeURlY2xhcmF0aW9uKG5vZGUpIHtcbiAgICBjb25zdCBwYXJ0cyA9IHRoaXMucGFydHMobm9kZSlcblxuICAgIHJldHVybiBub2RlLnR5cGUgPT0gXCJ2YXJpYWJsZV9kZWNsYXJhdGlvblwiICYmIFtcImNvbnN0XCIsIFwidmFyXCJdLmluY2x1ZGVzKHBhcnRzWzBdPy50eXBlKSAmJlxuICAgICAgcGFydHNbMV0/LnR5cGUgPT0gXCJpZGVudGlmaWVyXCIgJiYgdGhpcy50ZXh0KHBhcnRzWzFdKS5zdGFydHNXaXRoKFwic2VtYW50aWZvbGRfb3JkZXJlZF9cIilcbiAgfVxuXG4gIC8qKlxuICAgKiBFeHBhbmRzIG9uZSB0eXBlZCBvcmRlcmVkIHRlbXBvcmFyeSBhbmQgYW4gb3B0aW9uYWwgY29uZGl0aW9uYWwgQm9vbGVhbiBSSFMuXG4gICAqIEBwYXJhbSB7Q3N0Tm9kZVtdfSBub2RlcyAtIEN1cnJlbnQgcmVnaW9uIGNoaWxkcmVuLlxuICAgKiBAcGFyYW0ge251bWJlcn0gY3Vyc29yIC0gVGVtcG9yYXJ5IGRlY2xhcmF0aW9uIHBvc2l0aW9uLlxuICAgKiBAcmV0dXJucyB7bnVtYmVyfSBOZXh0IHVuY29uc3VtZWQgcG9zaXRpb24uXG4gICAqL1xuICByZWFkVGVtcG9yYXJ5KG5vZGVzLCBjdXJzb3IpIHtcbiAgICBjb25zdCBub2RlID0gbm9kZXNbY3Vyc29yKytdXG4gICAgY29uc3QgcGFydHMgPSB0aGlzLnBhcnRzKG5vZGUpXG4gICAgY29uc3QgbmFtZU5vZGUgPSBwYXJ0c1sxXVxuICAgIGNvbnN0IG5hbWUgPSB0aGlzLnRleHQobmFtZU5vZGUpXG4gICAgY29uc3QgdHlwZU5vZGUgPSB0aGlzLmZpZWxkKG5vZGUsIFwidHlwZVwiKVxuICAgIGNvbnN0IHZhbHVlID0gcGFydHNbNV1cblxuICAgIHRoaXMuc2hhcGUobm9kZSwgW3BhcnRzWzBdLCBuYW1lTm9kZSwgXCI6XCIsIHR5cGVOb2RlLCBcIj1cIiwgdmFsdWUsIFwiO1wiXSlcbiAgICB0aGlzLnR5cGUodHlwZU5vZGUpXG4gICAgaWYgKCEvXnNlbWFudGlmb2xkX29yZGVyZWRfWzAtOV17Nn0kL3UudGVzdChuYW1lKSB8fCB0aGlzLnRlbXBvcmFyeU5hbWVzPy5oYXMobmFtZSkpIHtcbiAgICAgIHRoaXMuZmFpbChuYW1lTm9kZSwgXCJnZW5lcmF0ZWQgb3JkZXJlZCB0ZW1wb3JhcnkgZGVjbGFyYXRpb25cIilcbiAgICB9XG4gICAgdGhpcy50ZW1wb3JhcnlOYW1lcz8uYWRkKG5hbWUpXG4gICAgbGV0IGV4cHJlc3Npb24gPSB0aGlzLmV4cHJlc3Npb24odmFsdWUpXG4gICAgY29uc3QgYnJhbmNoID0gbm9kZXNbY3Vyc29yXVxuXG4gICAgaWYgKGJyYW5jaCAmJiB0aGlzLnNob3J0Q2lyY3VpdEJyYW5jaChicmFuY2gsIG5hbWUpKSB7XG4gICAgICBjb25zdCBjb25kaXRpb24gPSB0aGlzLmZpZWxkKGJyYW5jaCwgXCJjb25kaXRpb25cIilcbiAgICAgIGNvbnN0IGJvZHkgPSB0aGlzLmZpZWxkKGJyYW5jaCwgXCJib2R5XCIpXG4gICAgICBjb25zdCBjb25kaXRpb25QYXJ0cyA9IHRoaXMucGFydHMoY29uZGl0aW9uKVxuICAgICAgY29uc3QgaXNPciA9IGNvbmRpdGlvblBhcnRzWzBdPy50eXBlID09IFwiIVwiXG4gICAgICBjb25zdCB0YXJnZXQgPSBpc09yID8gdGhpcy5maWVsZChjb25kaXRpb24sIGNvbmRpdGlvbi50eXBlID09IFwidW5hcnlfZXhwcmVzc2lvblwiID8gXCJhcmd1bWVudFwiIDogXCJva1wiKSA6IGNvbmRpdGlvblxuXG4gICAgICB0aGlzLnNoYXBlKGJyYW5jaCwgW1wiaWZcIiwgXCIoXCIsIGNvbmRpdGlvbiwgXCIpXCIsIGJvZHldKVxuICAgICAgaWYgKHRhcmdldC50eXBlICE9IFwiaWRlbnRpZmllclwiIHx8IHRoaXMudGV4dCh0YXJnZXQpICE9IG5hbWUpIHRoaXMuZmFpbCh0YXJnZXQsIFwiZ2VuZXJhdGVkIHNob3J0LWNpcmN1aXQgdGVtcG9yYXJ5IHRlc3RcIilcbiAgICAgIGlmIChpc09yKSB0aGlzLnNoYXBlKGNvbmRpdGlvbiwgW2NvbmRpdGlvblBhcnRzWzBdLCB0YXJnZXRdKVxuICAgICAgaWYgKGlzT3IgJiYgY29uZGl0aW9uUGFydHNbMF0/LnR5cGUgIT0gXCIhXCIpIHRoaXMuZmFpbChjb25kaXRpb25QYXJ0c1swXSA/PyBjb25kaXRpb24sIFwiZ2VuZXJhdGVkIHNob3J0LWNpcmN1aXQgbmVnYXRpb25cIilcbiAgICAgIGlmIChib2R5LnR5cGUgIT0gXCJibG9ja19leHByZXNzaW9uXCIpIHRoaXMuZmFpbChib2R5LCBcImdlbmVyYXRlZCBzaG9ydC1jaXJjdWl0IGJsb2NrXCIpXG4gICAgICBjb25zdCBibG9jayA9IHRoaXMucGFydHMoYm9keSlbMF1cblxuICAgICAgdGhpcy5zaGFwZShib2R5LCBbYmxvY2tdKVxuICAgICAgaWYgKGJsb2NrLnR5cGUgIT0gXCJibG9ja1wiKSB0aGlzLmZhaWwoYmxvY2ssIFwiZ2VuZXJhdGVkIHNob3J0LWNpcmN1aXQgYmxvY2tcIilcbiAgICAgIGNvbnN0IGluc2lkZSA9IHRoaXMuc2lnbmlmaWNhbnQoYmxvY2spLnNsaWNlKDEsIC0xKVxuICAgICAgbGV0IG9mZnNldCA9IDBcblxuICAgICAgd2hpbGUgKG9mZnNldCA8IGluc2lkZS5sZW5ndGggJiYgdGhpcy50ZW1wb3JhcnlEZWNsYXJhdGlvbihpbnNpZGVbb2Zmc2V0XSkpIG9mZnNldCA9IHRoaXMucmVhZFRlbXBvcmFyeShpbnNpZGUsIG9mZnNldClcbiAgICAgIGlmIChvZmZzZXQgIT0gaW5zaWRlLmxlbmd0aCAtIDEpIHRoaXMuZmFpbChibG9jaywgXCJnZW5lcmF0ZWQgc2hvcnQtY2lyY3VpdCBmaW5hbCBhc3NpZ25tZW50XCIpXG4gICAgICBjb25zdCBhc3NpZ25tZW50ID0gaW5zaWRlW29mZnNldF1cbiAgICAgIGNvbnN0IGFzc2lnbm1lbnRQYXJ0cyA9IHRoaXMucGFydHMoYXNzaWdubWVudClcbiAgICAgIGNvbnN0IGxlZnQgPSBhc3NpZ25tZW50UGFydHNbMF1cbiAgICAgIGNvbnN0IHJpZ2h0ID0gYXNzaWdubWVudFBhcnRzWzJdXG5cbiAgICAgIHRoaXMuc2hhcGUoYXNzaWdubWVudCwgW2xlZnQsIFwiPVwiLCByaWdodCwgXCI7XCJdKVxuICAgICAgaWYgKGxlZnQudHlwZSAhPSBcImlkZW50aWZpZXJcIiB8fCB0aGlzLnRleHQobGVmdCkgIT0gbmFtZSkgdGhpcy5mYWlsKGxlZnQsIFwiZ2VuZXJhdGVkIHNob3J0LWNpcmN1aXQgcmVzdWx0IHdyaXRlXCIpXG4gICAgICBpZiAocmlnaHQudHlwZSAhPSBcImJpbmFyeV9leHByZXNzaW9uXCIpIHRoaXMuZmFpbChyaWdodCwgXCJnZW5lcmF0ZWQgc2hvcnQtY2lyY3VpdCByZXN1bHQgZXhwcmVzc2lvblwiKVxuICAgICAgY29uc3QgcmVwZWF0ZWQgPSB0aGlzLmZpZWxkKHJpZ2h0LCBcImxlZnRcIilcbiAgICAgIGNvbnN0IG9wZXJhbmQgPSB0aGlzLmZpZWxkKHJpZ2h0LCBcInJpZ2h0XCIpXG4gICAgICBjb25zdCBvcGVyYXRvciA9IHRoaXMuZmllbGQocmlnaHQsIFwib3BlcmF0b3JcIilcbiAgICAgIGNvbnN0IHNwZWxsaW5nID0gaXNPciA/IFwib3JcIiA6IFwiYW5kXCJcblxuICAgICAgdGhpcy5zaGFwZShyaWdodCwgW3JlcGVhdGVkLCBzcGVsbGluZywgb3BlcmFuZF0pXG4gICAgICBpZiAocmVwZWF0ZWQudHlwZSAhPSBcImlkZW50aWZpZXJcIiB8fCB0aGlzLnRleHQocmVwZWF0ZWQpICE9IG5hbWUpIHRoaXMuZmFpbChyZXBlYXRlZCwgXCJnZW5lcmF0ZWQgc2hvcnQtY2lyY3VpdCBjb25zdW1lZCB2YWx1ZVwiKVxuICAgICAgZXhwcmVzc2lvbiA9IHRoaXMuYmluYXJ5KHJpZ2h0LCBpc09yID8gXCJPclwiIDogXCJBbmRcIiwgZXhwcmVzc2lvbiwgdGhpcy5leHByZXNzaW9uKG9wZXJhbmQpLCBvcGVyYXRvcilcbiAgICAgIGN1cnNvciArPSAxXG4gICAgfVxuICAgIHRoaXMudGVtcG9yYXJ5RXhwcmVzc2lvbnM/LnNldChuYW1lLCBleHByZXNzaW9uKVxuICAgIHJldHVybiBjdXJzb3JcbiAgfVxuXG4gIC8qKlxuICAgKiBEaXN0aW5ndWlzaGVzIGFuIGludGVybmFsIGNvbmRpdGlvbmFsIFJIUyBmcm9tIHRoZSBmb2xsb3dpbmcgc2VtYW50aWMgYGlmYCBjb25zdW1lciB1c2luZyBvbmx5IGRpcmVjdCBDU1Qgc3RydWN0dXJlLlxuICAgKiBAcGFyYW0ge0NzdE5vZGV9IG5vZGUgLSBDYW5kaWRhdGUgY29uZGl0aW9uYWwuXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBuYW1lIC0gT3JkZXJlZCBCb29sZWFuIHJlc3VsdCBuYW1lLlxuICAgKiBAcmV0dXJucyB7Ym9vbGVhbn0gV2hldGhlciB0aGUgbm9kZSBoYXMgdGhlIGNvbXBsZXRlIG91dGVyIHNoYXBlIG9mIGEgc2hvcnQtY2lyY3VpdCB1cGRhdGUuXG4gICAqL1xuICBzaG9ydENpcmN1aXRCcmFuY2gobm9kZSwgbmFtZSkge1xuICAgIGlmIChub2RlLnR5cGUgIT0gXCJpZl9zdGF0ZW1lbnRcIiB8fCB0aGlzLnBhcnRzKG5vZGUpLnNvbWUoY2hpbGQgPT4gY2hpbGQudHlwZSA9PSBcImVsc2VfY2xhdXNlXCIpKSByZXR1cm4gZmFsc2VcbiAgICBjb25zdCBib2R5ID0gbm9kZS5jaGlsZHJlbi5maW5kKCh7ZmllbGR9KSA9PiBmaWVsZCA9PSBcImJvZHlcIik/Lm5vZGVcblxuICAgIGlmIChib2R5Py50eXBlICE9IFwiYmxvY2tfZXhwcmVzc2lvblwiKSByZXR1cm4gZmFsc2VcbiAgICBjb25zdCBibG9jayA9IHRoaXMucGFydHMoYm9keSlbMF1cblxuICAgIGlmIChibG9jaz8udHlwZSAhPSBcImJsb2NrXCIpIHJldHVybiBmYWxzZVxuICAgIGNvbnN0IGluc2lkZSA9IHRoaXMuc2lnbmlmaWNhbnQoYmxvY2spLnNsaWNlKDEsIC0xKVxuICAgIGNvbnN0IGZpbmFsID0gaW5zaWRlLmF0KC0xKVxuICAgIGNvbnN0IGZpbmFsUGFydHMgPSBmaW5hbCA/IHRoaXMucGFydHMoZmluYWwpIDogW11cblxuICAgIHJldHVybiBpbnNpZGUubGVuZ3RoID4gMCAmJiAhaW5zaWRlLnNvbWUoY2hpbGQgPT4gY2hpbGQudHlwZSA9PSBcImNvbW1lbnRcIikgJiYgZmluYWw/LnR5cGUgPT0gXCJ2YXJpYWJsZV9kZWNsYXJhdGlvblwiICYmXG4gICAgICBmaW5hbFBhcnRzWzBdPy50eXBlID09IFwiaWRlbnRpZmllclwiICYmIHRoaXMudGV4dChmaW5hbFBhcnRzWzBdKSA9PSBuYW1lICYmIGZpbmFsUGFydHNbMV0/LnR5cGUgPT0gXCI9XCJcbiAgfVxuXG4gIC8qKlxuICAgKiBSZWNvZ25pemVzIG9uZSBleGFjdCBnZW5lcmF0ZWQgdW51c2VkIG9yIHVubXV0YXRlZCBiaW5kaW5nIHNjYWZmb2xkLlxuICAgKiBAcGFyYW0ge0NzdE5vZGV9IG5vZGUgLSBDYW5kaWRhdGUgc3RhdGVtZW50IG5vZGUuXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBuYW1lIC0gQmluZGluZyBuYW1lLlxuICAgKiBAcmV0dXJucyB7XCJ1c2VcIiB8IFwiYWRkcmVzc1wiIHwgdW5kZWZpbmVkfSBTY2FmZm9sZCBmb3JtIHdoZW4gbWF0Y2hlZC5cbiAgICovXG4gIHVzZVNjYWZmb2xkKG5vZGUsIG5hbWUpIHtcbiAgICBjb25zdCBwYXJ0cyA9IHRoaXMucGFydHMobm9kZSlcblxuICAgIGlmIChub2RlLnR5cGUgIT0gXCJ2YXJpYWJsZV9kZWNsYXJhdGlvblwiIHx8IHBhcnRzLmxlbmd0aCAhPSA0IHx8IHBhcnRzWzBdLnR5cGUgIT0gXCJpZGVudGlmaWVyXCIgfHwgdGhpcy50ZXh0KHBhcnRzWzBdKSAhPSBcIl9cIiB8fCBwYXJ0c1sxXS50eXBlICE9IFwiPVwiIHx8IHBhcnRzWzNdLnR5cGUgIT0gXCI7XCIpIHJldHVybiB1bmRlZmluZWRcbiAgICBpZiAocGFydHNbMl0udHlwZSA9PSBcImlkZW50aWZpZXJcIiAmJiB0aGlzLnRleHQocGFydHNbMl0pID09IG5hbWUpIHJldHVybiBcInVzZVwiXG4gICAgaWYgKHBhcnRzWzJdLnR5cGUgPT0gXCJyZWZlcmVuY2VfZXhwcmVzc2lvblwiKSB7XG4gICAgICBjb25zdCByZWZlcmVuY2UgPSB0aGlzLnBhcnRzKHBhcnRzWzJdKVxuXG4gICAgICBpZiAocmVmZXJlbmNlLmxlbmd0aCA9PSAyICYmIHJlZmVyZW5jZVswXS50eXBlID09IFwiJlwiICYmIHJlZmVyZW5jZVsxXS50eXBlID09IFwiaWRlbnRpZmllclwiICYmIHRoaXMudGV4dChyZWZlcmVuY2VbMV0pID09IG5hbWUpIHJldHVybiBcImFkZHJlc3NcIlxuICAgIH1cbiAgICByZXR1cm4gdW5kZWZpbmVkXG4gIH1cblxuICAvKipcbiAgICogQ29udmVydHMgb25lIGNhbm9uaWNhbCB0b3AtbGV2ZWwgc2VtYW50aWMgZnVuY3Rpb24uXG4gICAqIEBwYXJhbSB7Q3N0Tm9kZX0gbm9kZSAtIEZ1bmN0aW9uIGRlY2xhcmF0aW9uIG5vZGUuXG4gICAqIEByZXR1cm5zIHtpbXBvcnQoXCIuLi9zZW1hbnRpYy90eXBlcy5qc1wiKS5GdW5jdGlvbkRlY2xhcmF0aW9ufSBTZW1hbnRpYyBmdW5jdGlvbi5cbiAgICovXG4gIGZ1bmN0aW9uKG5vZGUpIHtcbiAgICBjb25zdCBuYW1lID0gdGhpcy5maWVsZChub2RlLCBcIm5hbWVcIilcbiAgICBjb25zdCBwYXJhbWV0ZXJzID0gdGhpcy5wYXJ0cyhub2RlKS5maW5kKGNoaWxkID0+IGNoaWxkLnR5cGUgPT0gXCJwYXJhbWV0ZXJzXCIpXG4gICAgY29uc3QgcmV0dXJuVHlwZSA9IHRoaXMuZmllbGQobm9kZSwgXCJ0eXBlXCIpXG4gICAgY29uc3QgYm9keSA9IHRoaXMuZmllbGQobm9kZSwgXCJib2R5XCIpXG5cbiAgICBpZiAoIXBhcmFtZXRlcnMpIHRoaXMuZmFpbChub2RlLCBcInBhcmFtZXRlciBsaXN0IHJlcXVpcmVkXCIpXG4gICAgdGhpcy5zaGFwZShub2RlLCBbXCJmblwiLCBuYW1lLCBwYXJhbWV0ZXJzLCByZXR1cm5UeXBlLCBib2R5XSlcbiAgICBjb25zdCBwYXJhbWV0ZXJQYXJ0cyA9IHRoaXMucGFydHMocGFyYW1ldGVycylcbiAgICBjb25zdCBkZWNsYXJhdGlvbnMgPSBwYXJhbWV0ZXJQYXJ0cy5zbGljZSgxLCAtMSkuZmlsdGVyKChfcGFydCwgaW5kZXgpID0+IGluZGV4ICUgMiA9PSAwKVxuXG4gICAgdGhpcy5zaGFwZShwYXJhbWV0ZXJzLCBbXCIoXCIsIC4uLmRlY2xhcmF0aW9ucy5mbGF0TWFwKChwYXJhbWV0ZXIsIGluZGV4KSA9PiBpbmRleCA/IFtcIixcIiwgcGFyYW1ldGVyXSA6IFtwYXJhbWV0ZXJdKSwgXCIpXCJdKVxuICAgIGNvbnN0IGNvbnZlcnRlZCA9IGRlY2xhcmF0aW9ucy5tYXAocGFyYW1ldGVyID0+IHtcbiAgICAgIGlmIChwYXJhbWV0ZXIudHlwZSAhPSBcInBhcmFtZXRlclwiKSB0aGlzLmZhaWwocGFyYW1ldGVyLCBcInJlcXVpcmVkIHR5cGVkIHBhcmFtZXRlclwiKVxuICAgICAgY29uc3QgcGFyYW1ldGVyTmFtZSA9IHRoaXMuZmllbGQocGFyYW1ldGVyLCBcIm5hbWVcIilcbiAgICAgIGNvbnN0IHR5cGUgPSB0aGlzLmZpZWxkKHBhcmFtZXRlciwgXCJ0eXBlXCIpXG5cbiAgICAgIHRoaXMuc2hhcGUocGFyYW1ldGVyLCBbcGFyYW1ldGVyTmFtZSwgXCI6XCIsIHR5cGVdKVxuICAgICAgcmV0dXJuIHdpdGhQYXJzZXJSYW5nZXMoe2tpbmQ6IC8qKiBAdHlwZSB7Y29uc3R9ICovIChcIlBhcmFtZXRlclwiKSwgbG9jYXRpb246IHRoaXMubG9jYXRpb24ocGFyYW1ldGVyKSwgbmFtZTogdGhpcy5pZGVudGlmaWVyKHBhcmFtZXRlck5hbWUpLCB0eXBlOiAvKiogQHR5cGUge2ltcG9ydChcIi4uL3NlbWFudGljL3R5cGVzLmpzXCIpLlR5cGVSZWZlcmVuY2V9ICovICh0aGlzLnR5cGUodHlwZSkpfSwge25hbWU6IHRoaXMubG9jYXRpb24ocGFyYW1ldGVyTmFtZSl9KVxuICAgIH0pXG5cbiAgICByZXR1cm4gd2l0aFBhcnNlclJhbmdlcyh7a2luZDogXCJGdW5jdGlvbkRlY2xhcmF0aW9uXCIsIGxvY2F0aW9uOiB0aGlzLmxvY2F0aW9uKG5vZGUpLCBuYW1lOiB0aGlzLmlkZW50aWZpZXIobmFtZSksIHBhcmFtZXRlcnM6IGNvbnZlcnRlZCxcbiAgICAgIHJldHVyblR5cGU6IHRoaXMudHlwZShyZXR1cm5UeXBlLCB0cnVlKSwgYm9keTogdGhpcy5ibG9jayhib2R5LCAwLCBjb252ZXJ0ZWQpfSwge25hbWU6IHRoaXMubG9jYXRpb24obmFtZSl9KVxuICB9XG5cbiAgLyoqXG4gICAqIENvbXBhcmVzIGV2ZXJ5IG5vZGUsIHRva2VuLCBhbmQgZmllbGQgYWdhaW5zdCBjYW5vbmljYWwgZ2VuZXJhdGVkIHN1cHBvcnQuXG4gICAqIEBwYXJhbSB7Q3N0Tm9kZX0gYWN0dWFsIC0gU291cmNlIHN1YnRyZWUuXG4gICAqIEBwYXJhbSB7Q3N0Tm9kZX0gZXhwZWN0ZWQgLSBDYW5vbmljYWwgc3VidHJlZS5cbiAgICogQHBhcmFtIHtaaWdSZWFkZXJ9IGNhbm9uaWNhbCAtIFJlYWRlciBvd25pbmcgdGhlIGNhbm9uaWNhbCBzb3VyY2UuXG4gICAqL1xuICBjb21wYXJlVHJlZShhY3R1YWwsIGV4cGVjdGVkLCBjYW5vbmljYWwpIHtcbiAgICBpZiAoYWN0dWFsLnR5cGUgIT0gZXhwZWN0ZWQudHlwZSB8fCBhY3R1YWwubmFtZWQgIT0gZXhwZWN0ZWQubmFtZWQgfHwgYWN0dWFsLmV4dHJhICE9IGV4cGVjdGVkLmV4dHJhKSB0aGlzLmZhaWwoYWN0dWFsLCBcIm1vZGlmaWVkIFppZyBzdXBwb3J0IG5vZGVcIilcbiAgICBjb25zdCBsZWZ0ID0gdGhpcy5zaWduaWZpY2FudChhY3R1YWwpXG4gICAgY29uc3QgcmlnaHQgPSBjYW5vbmljYWwuc2lnbmlmaWNhbnQoZXhwZWN0ZWQpXG5cbiAgICBpZiAobGVmdC5sZW5ndGggIT0gcmlnaHQubGVuZ3RoKSB0aGlzLmZhaWwoYWN0dWFsLCBcIm1vZGlmaWVkIFppZyBzdXBwb3J0IGNoaWxkcmVuXCIpXG4gICAgaWYgKCFsZWZ0Lmxlbmd0aCkge1xuICAgICAgY29uc3QgYWN0dWFsVGV4dCA9IGFjdHVhbC50eXBlID09IFwiY29tbWVudFwiICYmIC9zZW1hbnRpZm9sZDovdS50ZXN0KHRoaXMudGV4dChhY3R1YWwpKSA/IHRoaXMubWFya2VyKGFjdHVhbCkgOiB0aGlzLnRleHQoYWN0dWFsKVxuICAgICAgY29uc3QgZXhwZWN0ZWRUZXh0ID0gZXhwZWN0ZWQudHlwZSA9PSBcImNvbW1lbnRcIiAmJiAvc2VtYW50aWZvbGQ6L3UudGVzdChjYW5vbmljYWwudGV4dChleHBlY3RlZCkpID8gY2Fub25pY2FsLm1hcmtlcihleHBlY3RlZCkgOiBjYW5vbmljYWwudGV4dChleHBlY3RlZClcblxuICAgICAgaWYgKGFjdHVhbFRleHQgIT0gZXhwZWN0ZWRUZXh0KSB0aGlzLmZhaWwoYWN0dWFsLCBcIm1vZGlmaWVkIFppZyBzdXBwb3J0IHRva2VuXCIpXG4gICAgfVxuICAgIGxlZnQuZm9yRWFjaCgoY2hpbGQsIGluZGV4KSA9PiB7XG4gICAgICBjb25zdCBleHBlY3RlZENoaWxkID0gcmlnaHRbaW5kZXhdXG5cbiAgICAgIGlmICghZXhwZWN0ZWRDaGlsZCB8fCBhY3R1YWwuY2hpbGRyZW4uZmluZChlZGdlID0+IGVkZ2Uubm9kZSA9PT0gY2hpbGQpPy5maWVsZCAhPSBleHBlY3RlZC5jaGlsZHJlbi5maW5kKGVkZ2UgPT4gZWRnZS5ub2RlID09PSBleHBlY3RlZENoaWxkKT8uZmllbGQpIHtcbiAgICAgICAgdGhpcy5mYWlsKGNoaWxkLCBcIm1vZGlmaWVkIFppZyBzdXBwb3J0IGZpZWxkXCIpXG4gICAgICB9XG4gICAgICB0aGlzLmNvbXBhcmVUcmVlKGNoaWxkLCBleHBlY3RlZENoaWxkLCBjYW5vbmljYWwpXG4gICAgfSlcbiAgfVxuXG4gIC8qKlxuICAgKiBSZXNvbHZlcyBhIHZhbGlkYXRlZCBleHByZXNzaW9uJ3Mgc2NhbGFyIHJlc3VsdC5cbiAgICogQHBhcmFtIHtFeHByZXNzaW9ufSBleHByZXNzaW9uIC0gU2VtYW50aWMgZXhwcmVzc2lvbi5cbiAgICogQHBhcmFtIHtNYXA8c3RyaW5nLCBTY2FsYXI+fSBiaW5kaW5ncyAtIFZpc2libGUgYmluZGluZyB0eXBlcy5cbiAgICogQHJldHVybnMge1NjYWxhcn0gU2NhbGFyIHJlc3VsdCBuYW1lLlxuICAgKi9cbiAgZXhwcmVzc2lvblR5cGUoZXhwcmVzc2lvbiwgYmluZGluZ3MpIHtcbiAgICBpZiAoZXhwcmVzc2lvbi5raW5kID09IFwiU3RyaW5nTGl0ZXJhbFwiKSByZXR1cm4gXCJzdHJpbmdcIlxuICAgIGlmIChleHByZXNzaW9uLmtpbmQgPT0gXCJJbnRlZ2VyTGl0ZXJhbFwiKSByZXR1cm4gXCJpbnRlZ2VyXCJcbiAgICBpZiAoZXhwcmVzc2lvbi5raW5kID09IFwiQm9vbGVhbkxpdGVyYWxcIikgcmV0dXJuIFwiYm9vbGVhblwiXG4gICAgaWYgKGV4cHJlc3Npb24ua2luZCA9PSBcIkJpbmFyeUV4cHJlc3Npb25cIiB8fCBleHByZXNzaW9uLmtpbmQgPT0gXCJVbmFyeUV4cHJlc3Npb25cIikgcmV0dXJuIGV4cHJlc3Npb24udHlwZVxuICAgIGlmIChleHByZXNzaW9uLmtpbmQgIT0gXCJDYWxsRXhwcmVzc2lvblwiICYmIGV4cHJlc3Npb24ua2luZCAhPSBcIklkZW50aWZpZXJFeHByZXNzaW9uXCIpIHRocm93IG5ldyBFcnJvcihcIlZhbGlkYXRlZCBaaWcgc291cmNlIGV4cG9zZWQgYSBjb2xsZWN0aW9uIGV4cHJlc3Npb24uXCIpXG4gICAgY29uc3QgdHlwZSA9IGV4cHJlc3Npb24ua2luZCA9PSBcIkNhbGxFeHByZXNzaW9uXCIgPyB0aGlzLmZ1bmN0aW9ucy5nZXQoZXhwcmVzc2lvbi5jYWxsZWUpIDogYmluZGluZ3MuZ2V0KGV4cHJlc3Npb24ubmFtZSlcblxuICAgIGlmICghdHlwZSkgdGhyb3cgbmV3IEVycm9yKFwiVmFsaWRhdGVkIFppZyBleHByZXNzaW9uIGxvc3QgaXRzIHNjYWxhciBiaW5kaW5nLlwiKVxuICAgIHJldHVybiB0eXBlXG4gIH1cblxuICAvKipcbiAgICogUmVxdWlyZXMgZWFjaCB0eXBlZCBvcGVyYXRpb24gdG8gcmV0YWluIHRoZSBvbmUgZXhhY3QgWmlnIG9wZXJhdG9yL2hlbHBlciBzcGVsbGluZyB0aGF0IGltcGxlbWVudHMgaXQuXG4gICAqIEBwYXJhbSB7RXhwcmVzc2lvbn0gZXhwcmVzc2lvbiAtIFJlc29sdmVkIHNjYWxhciBleHByZXNzaW9uLlxuICAgKi9cbiAgdmFsaWRhdGVPcGVyYXRpb25FeHByZXNzaW9uKGV4cHJlc3Npb24pIHtcbiAgICBpZiAoZXhwcmVzc2lvbi5raW5kID09IFwiQ2FsbEV4cHJlc3Npb25cIikge1xuICAgICAgZXhwcmVzc2lvbi5hcmd1bWVudHMuZm9yRWFjaChhcmd1bWVudCA9PiB0aGlzLnZhbGlkYXRlT3BlcmF0aW9uRXhwcmVzc2lvbihhcmd1bWVudCkpXG4gICAgICByZXR1cm5cbiAgICB9XG4gICAgaWYgKGV4cHJlc3Npb24ua2luZCA9PSBcIlVuYXJ5RXhwcmVzc2lvblwiKSB7XG4gICAgICBjb25zdCBpZGVudGl0eSA9IHRoaXMub3BlcmF0aW9ucy5nZXQoZXhwcmVzc2lvbilcbiAgICAgIGNvbnN0IGV4cGVjdGVkID0gb3BlcmF0aW9uU3BlbGxpbmdzLmdldChleHByZXNzaW9uLm9wZXJhdGlvbilcblxuICAgICAgaWYgKCFpZGVudGl0eSkgdGhyb3cgbmV3IEVycm9yKFwiUmVzb2x2ZWQgWmlnIHVuYXJ5IG9wZXJhdGlvbiBsb3N0IGl0cyBwYXJzZXIgaWRlbnRpdHkuXCIpXG4gICAgICBpZiAoaWRlbnRpdHkuc3BlbGxpbmcgIT0gZXhwZWN0ZWQpIHRoaXMuZmFpbChpZGVudGl0eS5ub2RlLCBgZXhhY3QgJHtleHByZXNzaW9uLm9wZXJhdGlvbn0gWmlnIG9wZXJhdG9yL2hlbHBlciByZXF1aXJlZGApXG4gICAgICB0aGlzLnZhbGlkYXRlT3BlcmF0aW9uRXhwcmVzc2lvbihleHByZXNzaW9uLm9wZXJhbmQpXG4gICAgICByZXR1cm5cbiAgICB9XG4gICAgaWYgKGV4cHJlc3Npb24ua2luZCA9PSBcIkJpbmFyeUV4cHJlc3Npb25cIikge1xuICAgICAgY29uc3QgaWRlbnRpdHkgPSB0aGlzLm9wZXJhdGlvbnMuZ2V0KGV4cHJlc3Npb24pXG4gICAgICBjb25zdCBleHBlY3RlZCA9IG9wZXJhdGlvblNwZWxsaW5ncy5nZXQoZXhwcmVzc2lvbi5vcGVyYXRpb24pXG5cbiAgICAgIGlmICghaWRlbnRpdHkpIHRocm93IG5ldyBFcnJvcihcIlJlc29sdmVkIFppZyBiaW5hcnkgb3BlcmF0aW9uIGxvc3QgaXRzIHBhcnNlciBpZGVudGl0eS5cIilcbiAgICAgIGlmIChpZGVudGl0eS5zcGVsbGluZyAhPSBleHBlY3RlZCkgdGhpcy5mYWlsKGlkZW50aXR5Lm5vZGUsIGBleGFjdCAke2V4cHJlc3Npb24ub3BlcmF0aW9ufSBaaWcgb3BlcmF0b3IvaGVscGVyIHJlcXVpcmVkYClcbiAgICAgIHRoaXMudmFsaWRhdGVPcGVyYXRpb25FeHByZXNzaW9uKGV4cHJlc3Npb24ubGVmdClcbiAgICAgIHRoaXMudmFsaWRhdGVPcGVyYXRpb25FeHByZXNzaW9uKGV4cHJlc3Npb24ucmlnaHQpXG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIFZhbGlkYXRlcyBvcGVyYXRpb24gaWRlbnRpdHkgdGhyb3VnaG91dCBvbmUgbGV4aWNhbCBibG9jay5cbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuLi9zZW1hbnRpYy90eXBlcy5qc1wiKS5CbG9ja30gYmxvY2sgLSBCbG9jayB3aG9zZSBleHByZXNzaW9ucyBtdXN0IHJldGFpbiBleGFjdCBaaWcgaWRlbnRpdHkuXG4gICAqL1xuICB2YWxpZGF0ZU9wZXJhdGlvbnMoYmxvY2spIHtcbiAgICBmb3IgKGNvbnN0IHN0YXRlbWVudCBvZiBibG9jay5zdGF0ZW1lbnRzKSB7XG4gICAgICBpZiAoc3RhdGVtZW50LmtpbmQgPT0gXCJMb2NhbERlY2xhcmF0aW9uXCIpIHRoaXMudmFsaWRhdGVPcGVyYXRpb25FeHByZXNzaW9uKHN0YXRlbWVudC5pbml0aWFsaXplcilcbiAgICAgIGVsc2UgaWYgKHN0YXRlbWVudC5raW5kID09IFwiQXNzaWdubWVudFN0YXRlbWVudFwiIHx8IHN0YXRlbWVudC5raW5kID09IFwiRXhwcmVzc2lvblN0YXRlbWVudFwiIHx8IHN0YXRlbWVudC5raW5kID09IFwiUHJpbnRTdGF0ZW1lbnRcIikge1xuICAgICAgICB0aGlzLnZhbGlkYXRlT3BlcmF0aW9uRXhwcmVzc2lvbihzdGF0ZW1lbnQuZXhwcmVzc2lvbilcbiAgICAgIH0gZWxzZSBpZiAoc3RhdGVtZW50LmtpbmQgPT0gXCJSZXR1cm5TdGF0ZW1lbnRcIikge1xuICAgICAgICBpZiAoc3RhdGVtZW50LmV4cHJlc3Npb24pIHRoaXMudmFsaWRhdGVPcGVyYXRpb25FeHByZXNzaW9uKHN0YXRlbWVudC5leHByZXNzaW9uKVxuICAgICAgfSBlbHNlIGlmIChzdGF0ZW1lbnQua2luZCA9PSBcIklmU3RhdGVtZW50XCIpIHtcbiAgICAgICAgdGhpcy52YWxpZGF0ZU9wZXJhdGlvbkV4cHJlc3Npb24oc3RhdGVtZW50LmNvbmRpdGlvbilcbiAgICAgICAgdGhpcy52YWxpZGF0ZU9wZXJhdGlvbnMoc3RhdGVtZW50LmNvbnNlcXVlbnQpXG4gICAgICAgIGlmIChzdGF0ZW1lbnQuYWx0ZXJuYXRlKSB0aGlzLnZhbGlkYXRlT3BlcmF0aW9ucyhzdGF0ZW1lbnQuYWx0ZXJuYXRlKVxuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBDb25maXJtcyBlYWNoIGdlbmVyYXRlZCBvdXRwdXQgaGVscGVyIG1hdGNoZXMgaXRzIHNlbWFudGljIG9wZXJhbmQuXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vc2VtYW50aWMvdHlwZXMuanNcIikuQmxvY2t9IGJsb2NrIC0gQmxvY2sgdG8gaW5zcGVjdC5cbiAgICogQHBhcmFtIHtNYXA8c3RyaW5nLCBTY2FsYXI+fSBpbmhlcml0ZWQgLSBWaXNpYmxlIGJpbmRpbmcgdHlwZXMuXG4gICAqL1xuICB2YWxpZGF0ZVByaW50cyhibG9jaywgaW5oZXJpdGVkKSB7XG4gICAgY29uc3QgYmluZGluZ3MgPSBuZXcgTWFwKGluaGVyaXRlZClcblxuICAgIGZvciAoY29uc3Qgc3RhdGVtZW50IG9mIGJsb2NrLnN0YXRlbWVudHMpIHtcbiAgICAgIGlmIChzdGF0ZW1lbnQua2luZCA9PSBcIkxvY2FsRGVjbGFyYXRpb25cIikge1xuICAgICAgICBiaW5kaW5ncy5zZXQoc3RhdGVtZW50Lm5hbWUsIC8qKiBAdHlwZSB7aW1wb3J0KFwiLi4vc2VtYW50aWMvdHlwZXMuanNcIikuVHlwZVJlZmVyZW5jZX0gKi8gKHN0YXRlbWVudC50eXBlKS5uYW1lKVxuICAgICAgfSBlbHNlIGlmIChzdGF0ZW1lbnQua2luZCA9PSBcIlByaW50U3RhdGVtZW50XCIpIHtcbiAgICAgICAgY29uc3QgcHJpbnQgPSB0aGlzLnByaW50cy5nZXQoc3RhdGVtZW50KVxuXG4gICAgICAgIGlmICghcHJpbnQgfHwgdGhpcy5leHByZXNzaW9uVHlwZShzdGF0ZW1lbnQuZXhwcmVzc2lvbiwgYmluZGluZ3MpICE9IHByaW50LnR5cGUpIHRoaXMuZmFpbChwcmludD8ubm9kZSA/PyAvKiogQHR5cGUge0NzdE5vZGV9ICovICh7fSksIFwicHJpbnQgaGVscGVyIHNjYWxhciBtaXNtYXRjaFwiKVxuICAgICAgfSBlbHNlIGlmIChzdGF0ZW1lbnQua2luZCA9PSBcIklmU3RhdGVtZW50XCIpIHtcbiAgICAgICAgdGhpcy52YWxpZGF0ZVByaW50cyhzdGF0ZW1lbnQuY29uc2VxdWVudCwgYmluZGluZ3MpXG4gICAgICAgIGlmIChzdGF0ZW1lbnQuYWx0ZXJuYXRlKSB0aGlzLnZhbGlkYXRlUHJpbnRzKHN0YXRlbWVudC5hbHRlcm5hdGUsIGJpbmRpbmdzKVxuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBDb25maXJtcyBhbGwgYW5kIG9ubHkgY29tcGlsZXItcmVxdWlyZWQgYmluZGluZyBzY2FmZm9sZHMgYXJlIHByZXNlbnQuXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vc2VtYW50aWMvdHlwZXMuanNcIikuRnVuY3Rpb25EZWNsYXJhdGlvbiB8IGltcG9ydChcIi4uL3NlbWFudGljL3R5cGVzLmpzXCIpLkVudHJ5UG9pbnR9IG93bmVyIC0gRnVuY3Rpb24gb3IgZW50cnkgb3duZXIuXG4gICAqL1xuICB2YWxpZGF0ZVNjYWZmb2xkcyhvd25lcikge1xuICAgIGNvbnN0IHVzYWdlID0gY29sbGVjdFppZ0JpbmRpbmdVc2FnZShvd25lci5ib2R5KVxuICAgIGNvbnN0IHBhcmFtZXRlcnMgPSBvd25lci5raW5kID09IFwiRnVuY3Rpb25EZWNsYXJhdGlvblwiID8gb3duZXIucGFyYW1ldGVycyA6IFtdXG5cbiAgICBmb3IgKGNvbnN0IHBhcmFtZXRlciBvZiBwYXJhbWV0ZXJzKSB7XG4gICAgICBjb25zdCBleHBlY3RlZCA9IHVzYWdlLnJlYWRzLmhhcyhwYXJhbWV0ZXIubmFtZSkgPyBcIm5vbmVcIiA6IFwidXNlXCJcblxuICAgICAgaWYgKHRoaXMuc2NhZmZvbGRzLmdldChwYXJhbWV0ZXIpICE9IGV4cGVjdGVkKSB1bnN1cHBvcnRlZFN5bnRheChcInppZ1wiLCBgaW5jb3JyZWN0IHVudXNlZC1wYXJhbWV0ZXIgc2NhZmZvbGQgZm9yICcke3BhcmFtZXRlci5uYW1lfSdgLCBwYXJhbWV0ZXIubG9jYXRpb24pXG4gICAgfVxuICAgIC8qKlxuICAgICAqIENoZWNrcyBsb2NhbCBzY2FmZm9sZHMgcmVjdXJzaXZlbHkuXG4gICAgICogQHBhcmFtIHtpbXBvcnQoXCIuLi9zZW1hbnRpYy90eXBlcy5qc1wiKS5CbG9ja30gYmxvY2sgLSBCbG9jayB0byBpbnNwZWN0LlxuICAgICAqL1xuICAgIGNvbnN0IHZpc2l0ID0gKGJsb2NrKSA9PiB7XG4gICAgICBmb3IgKGNvbnN0IHN0YXRlbWVudCBvZiBibG9jay5zdGF0ZW1lbnRzKSB7XG4gICAgICAgIGlmIChzdGF0ZW1lbnQua2luZCA9PSBcIkxvY2FsRGVjbGFyYXRpb25cIikge1xuICAgICAgICAgIGNvbnN0IGV4cGVjdGVkID0gc3RhdGVtZW50Lm11dGFibGUgJiYgIXVzYWdlLndyaXRlcy5oYXMoc3RhdGVtZW50Lm5hbWUpID8gXCJhZGRyZXNzXCIgOlxuICAgICAgICAgICAgIXN0YXRlbWVudC5tdXRhYmxlICYmICF1c2FnZS5yZWFkcy5oYXMoc3RhdGVtZW50Lm5hbWUpID8gXCJ1c2VcIiA6IFwibm9uZVwiXG5cbiAgICAgICAgICBpZiAodGhpcy5zY2FmZm9sZHMuZ2V0KHN0YXRlbWVudCkgIT0gZXhwZWN0ZWQpIHVuc3VwcG9ydGVkU3ludGF4KFwiemlnXCIsIGBpbmNvcnJlY3QgbG9jYWwgYmluZGluZyBzY2FmZm9sZCBmb3IgJyR7c3RhdGVtZW50Lm5hbWV9J2AsIHN0YXRlbWVudC5sb2NhdGlvbilcbiAgICAgICAgfSBlbHNlIGlmIChzdGF0ZW1lbnQua2luZCA9PSBcIklmU3RhdGVtZW50XCIpIHtcbiAgICAgICAgICB2aXNpdChzdGF0ZW1lbnQuY29uc2VxdWVudClcbiAgICAgICAgICBpZiAoc3RhdGVtZW50LmFsdGVybmF0ZSkgdmlzaXQoc3RhdGVtZW50LmFsdGVybmF0ZSlcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cblxuICAgIHZpc2l0KG93bmVyLmJvZHkpXG4gIH1cblxuICAvKipcbiAgICogQ29udmVydHMgYSBjb21wbGV0ZSBjYW5vbmljYWwgWmlnIHByb2plY3QgZW50cnkuXG4gICAqIEBwYXJhbSB7Q3N0Tm9kZX0gcm9vdCAtIFNvdXJjZS1maWxlIHJvb3QuXG4gICAqIEByZXR1cm5zIHtpbXBvcnQoXCIuLi9zZW1hbnRpYy90eXBlcy5qc1wiKS5TZW1hbnRpY01vZHVsZX0gVmFsaWRhdGVkIHNlbWFudGljIG1vZHVsZS5cbiAgICovXG4gIG1vZHVsZShyb290KSB7XG4gICAgdGhpcy52YWxpZGF0ZVRyZWUocm9vdClcbiAgICBpZiAocm9vdC50eXBlICE9IFwic291cmNlX2ZpbGVcIikgdGhpcy5mYWlsKHJvb3QsIFwiWmlnIHNvdXJjZSByb290IHJlcXVpcmVkXCIpXG4gICAgY29uc3QgY2Fub25pY2FsID0gbmV3IFppZ1JlYWRlcih0aGlzLmZpbGVuYW1lLCB6aWdSdW50aW1lKVxuICAgIGNvbnN0IHN1cHBvcnQgPSBjYW5vbmljYWwuc2lnbmlmaWNhbnQocGFyc2VaaWdDc3QoemlnUnVudGltZSkucm9vdClcbiAgICBjb25zdCBub2RlcyA9IHRoaXMuc2lnbmlmaWNhbnQocm9vdClcblxuICAgIGlmIChub2Rlcy5sZW5ndGggPCBzdXBwb3J0Lmxlbmd0aCArIDIpIHRoaXMuZmFpbChyb290LCBcImNvbXBsZXRlIFppZyBydW50aW1lLCBvcmRlcmVkIG1hcmtlciwgYW5kIG1haW4gc2hlbGwgcmVxdWlyZWRcIilcbiAgICBzdXBwb3J0LmZvckVhY2goKGV4cGVjdGVkLCBpbmRleCkgPT4gdGhpcy5jb21wYXJlVHJlZShub2Rlc1tpbmRleF0sIGV4cGVjdGVkLCBjYW5vbmljYWwpKVxuICAgIGNvbnN0IHByb2dyYW1NYXJrZXIgPSBub2Rlc1tzdXBwb3J0Lmxlbmd0aF1cblxuICAgIGlmIChwcm9ncmFtTWFya2VyLnR5cGUgIT0gXCJjb21tZW50XCIgfHwgdGhpcy5tYXJrZXIocHJvZ3JhbU1hcmtlcikgIT0gXCIvLyBzZW1hbnRpZm9sZDpwcm9ncmFtOnppZzp2MVwiKSB7XG4gICAgICB0aGlzLmZhaWwocHJvZ3JhbU1hcmtlciwgXCJleGFjdCBnZW5lcmF0ZWQgWmlnIG9yZGVyZWQtZXhwcmVzc2lvbiBtYXJrZXIgcmVxdWlyZWRcIilcbiAgICB9XG4gICAgdGhpcy5nZW5lcmF0ZWQgPSB0cnVlXG4gICAgY29uc3QgZGVmaW5pdGlvbnMgPSBub2Rlcy5zbGljZShzdXBwb3J0Lmxlbmd0aCArIDEpXG4gICAgLyoqIEB0eXBlIHtDc3ROb2RlIHwgdW5kZWZpbmVkfSAqL1xuICAgIGxldCBtYWluXG4gICAgLyoqIEB0eXBlIHtDc3ROb2RlW119ICovXG4gICAgY29uc3QgZnVuY3Rpb25zID0gW11cblxuICAgIGZvciAoY29uc3Qgbm9kZSBvZiBkZWZpbml0aW9ucykge1xuICAgICAgaWYgKG5vZGUudHlwZSAhPSBcImZ1bmN0aW9uX2RlY2xhcmF0aW9uXCIpIHRoaXMuZmFpbChub2RlLCBcInRvcC1sZXZlbCBmcmVlIGZ1bmN0aW9ucyBvbmx5XCIpXG4gICAgICBjb25zdCBuYW1lID0gdGhpcy50ZXh0KHRoaXMuZmllbGQobm9kZSwgXCJuYW1lXCIpKVxuXG4gICAgICBpZiAobmFtZSA9PSBcIm1haW5cIikge1xuICAgICAgICBpZiAobWFpbikgdGhpcy5mYWlsKG5vZGUsIFwiZHVwbGljYXRlIG1haW5cIilcbiAgICAgICAgbWFpbiA9IG5vZGVcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGlmIChtYWluKSB0aGlzLmZhaWwobm9kZSwgXCJzZW1hbnRpYyBmdW5jdGlvbiBhZnRlciBtYWluXCIpXG4gICAgICAgIGZ1bmN0aW9ucy5wdXNoKG5vZGUpXG4gICAgICB9XG4gICAgfVxuICAgIGlmICghbWFpbikgdGhpcy5mYWlsKHJvb3QsIFwiY2Fub25pY2FsIHB1YiBmbiBtYWluKCkgdm9pZCByZXF1aXJlZFwiKVxuICAgIGNvbnN0IG1haW5QYXJ0cyA9IHRoaXMucGFydHMobWFpbilcbiAgICBjb25zdCBtYWluTmFtZSA9IHRoaXMuZmllbGQobWFpbiwgXCJuYW1lXCIpXG4gICAgY29uc3QgcGFyYW1ldGVycyA9IG1haW5QYXJ0cy5maW5kKGNoaWxkID0+IGNoaWxkLnR5cGUgPT0gXCJwYXJhbWV0ZXJzXCIpXG4gICAgY29uc3QgcmV0dXJuVHlwZSA9IHRoaXMuZmllbGQobWFpbiwgXCJ0eXBlXCIpXG4gICAgY29uc3QgYm9keSA9IHRoaXMuZmllbGQobWFpbiwgXCJib2R5XCIpXG5cbiAgICBpZiAoIXBhcmFtZXRlcnMpIHRoaXMuZmFpbChtYWluLCBcIm1haW4gcGFyYW1ldGVyc1wiKVxuICAgIHRoaXMuc2hhcGUobWFpbiwgW1wicHViXCIsIFwiZm5cIiwgbWFpbk5hbWUsIHBhcmFtZXRlcnMsIHJldHVyblR5cGUsIGJvZHldKVxuICAgIGlmICh0aGlzLnRleHQobWFpbk5hbWUpICE9IFwibWFpblwiKSB0aGlzLmZhaWwobWFpbk5hbWUsIFwibWFpbiBuYW1lXCIpXG4gICAgdGhpcy5zaGFwZShwYXJhbWV0ZXJzLCBbXCIoXCIsIFwiKVwiXSlcbiAgICB0aGlzLnR5cGUocmV0dXJuVHlwZSwgdHJ1ZSlcbiAgICBpZiAodGhpcy50ZXh0KHJldHVyblR5cGUpICE9IFwidm9pZFwiKSB0aGlzLmZhaWwocmV0dXJuVHlwZSwgXCJtYWluIHJldHVybiB0eXBlXCIpXG4gICAgY29uc3QgYm9keVBhcnRzID0gdGhpcy5wYXJ0cyhib2R5KVxuICAgIGNvbnN0IGRlZmVyTm9kZSA9IGJvZHlQYXJ0c1sxXVxuICAgIGNvbnN0IHNoZWxsU291cmNlID0gXCJwdWIgZm4gbWFpbigpIHZvaWQge1xcbiAgICBkZWZlciBzZW1hbnRpZm9sZF9hcmVuYS5kZWluaXQoKTtcXG59XFxuXCJcbiAgICBjb25zdCBzaGVsbFJlYWRlciA9IG5ldyBaaWdSZWFkZXIodGhpcy5maWxlbmFtZSwgc2hlbGxTb3VyY2UpXG4gICAgY29uc3Qgc2hlbGxNYWluID0gc2hlbGxSZWFkZXIucGFydHMocGFyc2VaaWdDc3Qoc2hlbGxTb3VyY2UpLnJvb3QpWzBdXG4gICAgY29uc3QgZXhwZWN0ZWREZWZlciA9IHNoZWxsUmVhZGVyLnBhcnRzKHNoZWxsUmVhZGVyLmZpZWxkKHNoZWxsTWFpbiwgXCJib2R5XCIpKVsxXVxuXG4gICAgaWYgKCFkZWZlck5vZGUpIHRoaXMuZmFpbChib2R5LCBcImFyZW5hIGxpZmV0aW1lIGRlZmVyIHJlcXVpcmVkXCIpXG4gICAgdGhpcy5jb21wYXJlVHJlZShkZWZlck5vZGUsIGV4cGVjdGVkRGVmZXIsIHNoZWxsUmVhZGVyKVxuICAgIGNvbnN0IG1vZHVsZSA9IHZhbGlkYXRlUGFyc2VkTW9kdWxlKHtraW5kOiBcIk1vZHVsZVwiLCBsb2NhdGlvbjogdGhpcy5sb2NhdGlvbihyb290KSwgZnVuY3Rpb25zOiBmdW5jdGlvbnMubWFwKG5vZGUgPT4gdGhpcy5mdW5jdGlvbihub2RlKSksXG4gICAgICBlbnRyeVBvaW50OiB7a2luZDogXCJFbnRyeVBvaW50XCIsIGxvY2F0aW9uOiB0aGlzLmxvY2F0aW9uKG1haW4pLCBib2R5OiB0aGlzLmJsb2NrKGJvZHksIDEpfX0sIFwiemlnXCIpXG5cbiAgICB0aGlzLmZ1bmN0aW9ucyA9IG5ldyBNYXAobW9kdWxlLmZ1bmN0aW9ucy5tYXAoZGVjbGFyYXRpb24gPT4gW2RlY2xhcmF0aW9uLm5hbWUsXG4gICAgICAvKiogQHR5cGUge2ltcG9ydChcIi4uL3NlbWFudGljL3R5cGVzLmpzXCIpLlR5cGVSZWZlcmVuY2V9ICovIChkZWNsYXJhdGlvbi5yZXR1cm5UeXBlKS5uYW1lXSkpXG4gICAgZm9yIChjb25zdCBkZWNsYXJhdGlvbiBvZiBtb2R1bGUuZnVuY3Rpb25zKSB0aGlzLnZhbGlkYXRlT3BlcmF0aW9ucyhkZWNsYXJhdGlvbi5ib2R5KVxuICAgIHRoaXMudmFsaWRhdGVPcGVyYXRpb25zKG1vZHVsZS5lbnRyeVBvaW50LmJvZHkpXG4gICAgZm9yIChjb25zdCBkZWNsYXJhdGlvbiBvZiBtb2R1bGUuZnVuY3Rpb25zKSB0aGlzLnZhbGlkYXRlUHJpbnRzKGRlY2xhcmF0aW9uLmJvZHksIG5ldyBNYXAoZGVjbGFyYXRpb24ucGFyYW1ldGVycy5tYXAocGFyYW1ldGVyID0+IFtwYXJhbWV0ZXIubmFtZSxcbiAgICAgIC8qKiBAdHlwZSB7aW1wb3J0KFwiLi4vc2VtYW50aWMvdHlwZXMuanNcIikuVHlwZVJlZmVyZW5jZX0gKi8gKHBhcmFtZXRlci50eXBlKS5uYW1lXSkpKVxuICAgIHRoaXMudmFsaWRhdGVQcmludHMobW9kdWxlLmVudHJ5UG9pbnQuYm9keSwgbmV3IE1hcCgpKVxuICAgIGZvciAoY29uc3QgZGVjbGFyYXRpb24gb2YgbW9kdWxlLmZ1bmN0aW9ucykgdGhpcy52YWxpZGF0ZVNjYWZmb2xkcyhkZWNsYXJhdGlvbilcbiAgICB0aGlzLnZhbGlkYXRlU2NhZmZvbGRzKG1vZHVsZS5lbnRyeVBvaW50KVxuICAgIGNvbnN0IGNhbm9uaWNhbFNvdXJjZSA9IGdlbmVyYXRlWmlnUHJvamVjdCh7bW9kdWxlfSkuYXJ0aWZhY3RzWzFdPy5jb250ZW50XG5cbiAgICBpZiAodHlwZW9mIGNhbm9uaWNhbFNvdXJjZSAhPSBcInN0cmluZ1wiKSB0aHJvdyBuZXcgRXJyb3IoXCJaaWcgYmFja2VuZCByZXR1cm5lZCBhIG5vbnRleHQgZW50cnkgYXJ0aWZhY3QuXCIpXG4gICAgdGhpcy5jb21wYXJlVHJlZShyb290LCBwYXJzZVppZ0NzdChjYW5vbmljYWxTb3VyY2UpLnJvb3QsIG5ldyBaaWdSZWFkZXIodGhpcy5maWxlbmFtZSwgY2Fub25pY2FsU291cmNlKSlcbiAgICByZXR1cm4gbW9kdWxlXG4gIH1cbn1cblxuLyoqXG4gKiBQYXJzZXMgb25seSB0aGUgcXVhbGlmaWVkIGZyb3plbiBaaWcgQ1NUIGFuZCByZWplY3RzIHVuc3VwcG9ydGVkIGlucHV0IGJlZm9yZSBhZGFwdGF0aW9uLlxuICogQHBhcmFtIHt7ZmlsZW5hbWU6IHN0cmluZywgc291cmNlOiBzdHJpbmd9fSBpbnB1dCAtIEV4YWN0IHNvdXJjZSByZXF1ZXN0LlxuICogQHJldHVybnMge2ltcG9ydChcIi4uL3NlbWFudGljL3R5cGVzLmpzXCIpLlNlbWFudGljTW9kdWxlfSBaaWcgc2VtYW50aWMgbW9kdWxlLlxuICovXG5leHBvcnQgZnVuY3Rpb24gcGFyc2VaaWcoe2ZpbGVuYW1lLCBzb3VyY2V9KSB7XG4gIGNvbnN0IGNvb3JkaW5hdGVzID0gY3JlYXRlQ29vcmRpbmF0ZUluZGV4KHNvdXJjZSlcbiAgY29uc3QgbG9jYXRpb24gPSB7ZmlsZW5hbWUsIHN0YXJ0OiBpbmRleGVkUG9pbnRBdChjb29yZGluYXRlcywgMCksIGVuZDogaW5kZXhlZFBvaW50QXQoY29vcmRpbmF0ZXMsIHNvdXJjZS5sZW5ndGgpfVxuXG4gIGlmICghaGFzT25seVVuaWNvZGVTY2FsYXJzKHNvdXJjZSkpIHtcbiAgICBjb25zdCBvZmZzZXQgPSBzb3VyY2Uuc2VhcmNoKC9bXFx1RDgwMC1cXHVEQkZGXSg/IVtcXHVEQzAwLVxcdURGRkZdKXwoPzwhW1xcdUQ4MDAtXFx1REJGRl0pW1xcdURDMDAtXFx1REZGRl0vdSlcblxuICAgIHRocm93IG5ldyBTZW1hbnRpZm9sZERpYWdub3N0aWMoe2NvZGU6IFwiUEFSU0VfRVJST1JcIiwgbGFuZ3VhZ2U6IFwiemlnXCIsIG1lc3NhZ2U6IFwiWmlnIHNvdXJjZSBjb250YWlucyBhIGxvbmUgVVRGLTE2IHN1cnJvZ2F0ZS5cIixcbiAgICAgIGxvY2F0aW9uOiB7ZmlsZW5hbWUsIHN0YXJ0OiBpbmRleGVkUG9pbnRBdChjb29yZGluYXRlcywgb2Zmc2V0KSwgZW5kOiBpbmRleGVkUG9pbnRBdChjb29yZGluYXRlcywgb2Zmc2V0ICsgMSl9fSlcbiAgfVxuICBpZiAoc291cmNlLmxlbmd0aCA+IG1heGltdW1aaWdTb3VyY2VMZW5ndGgpIHJldHVybiB1bnN1cHBvcnRlZFN5bnRheChcInppZ1wiLCBcInNvdXJjZSBleGNlZWRzIHRoZSAxMDAwMDAwIFVURi0xNiBpbnB1dCBsaW1pdFwiLCBsb2NhdGlvbilcbiAgbGV0IHNuYXBzaG90XG5cbiAgdHJ5IHtcbiAgICBzbmFwc2hvdCA9IHBhcnNlWmlnQ3N0KHNvdXJjZSlcbiAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICB0aHJvdyBuZXcgU2VtYW50aWZvbGREaWFnbm9zdGljKHtjb2RlOiBcIlBBUlNFX0VSUk9SXCIsIGxhbmd1YWdlOiBcInppZ1wiLCBsb2NhdGlvbixcbiAgICAgIGNhdXNlOiBlcnJvciBpbnN0YW5jZW9mIEVycm9yID8gZXJyb3IgOiB1bmRlZmluZWQsIG1lc3NhZ2U6IFwiVGhlIHF1YWxpZmllZCBaaWcgcGFyc2VyIGNvdWxkIG5vdCBwcm9kdWNlIGEgY29tcGxldGUgQ1NULlwifSlcbiAgfVxuICBjb25zdCByZWFkZXIgPSBuZXcgWmlnUmVhZGVyKGZpbGVuYW1lLCBzb3VyY2UpXG5cbiAgdHJ5IHtcbiAgICByZXR1cm4gcmVhZGVyLm1vZHVsZShzbmFwc2hvdC5yb290KVxuICB9IGNhdGNoIChlcnJvcikge1xuICAgIGlmIChyZWFkZXIuZ2VuZXJhdGVkICYmIGVycm9yIGluc3RhbmNlb2YgU2VtYW50aWZvbGREaWFnbm9zdGljICYmIGVycm9yLmxhbmd1YWdlID09IFwiemlnXCIgJiZcbiAgICAgIGVycm9yLmNvZGUgIT0gXCJQQVJTRV9FUlJPUlwiICYmIGVycm9yLmNvZGUgIT0gXCJVTlNVUFBPUlRFRF9TWU5UQVhcIikge1xuICAgICAgcmV0dXJuIHVuc3VwcG9ydGVkU3ludGF4KFwiemlnXCIsIGBpbnZhbGlkIGdlbmVyYXRlZCBvcmRlcmVkIHNjYWZmb2xkOiAke2Vycm9yLmNvZGV9YCwgZXJyb3IubG9jYXRpb24gPz8gbG9jYXRpb24pXG4gICAgfVxuICAgIHRocm93IGVycm9yXG4gIH1cbn1cbiJdfQ==