@angular/compiler-cli 12.1.1 → 12.1.2

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 (445) hide show
  1. package/linker/src/file_linker/emit_scopes/iife_emit_scope.js +1 -1
  2. package/linker/src/file_linker/partial_linkers/partial_linker_selector.js +2 -2
  3. package/ngcc/src/dependencies/commonjs_dependency_host.js +1 -1
  4. package/ngcc/src/dependencies/dts_dependency_host.js +1 -1
  5. package/ngcc/src/dependencies/esm_dependency_host.js +1 -1
  6. package/ngcc/src/dependencies/umd_dependency_host.js +1 -1
  7. package/ngcc/src/entry_point_finder/program_based_entry_point_finder.js +1 -1
  8. package/ngcc/src/entry_point_finder/targeted_entry_point_finder.js +1 -1
  9. package/ngcc/src/execution/tasks/queues/parallel_task_queue.js +1 -1
  10. package/ngcc/src/execution/tasks/queues/serial_task_queue.js +1 -1
  11. package/ngcc/src/host/commonjs_host.js +1 -1
  12. package/ngcc/src/host/esm2015_host.js +1 -1
  13. package/ngcc/src/host/esm5_host.js +1 -1
  14. package/ngcc/src/host/umd_host.js +1 -1
  15. package/ngcc/src/packages/build_marker.d.ts +1 -1
  16. package/ngcc/src/packages/build_marker.js +1 -1
  17. package/ngcc/src/packages/entry_point_manifest.js +1 -1
  18. package/ngcc/src/packages/ngcc_compiler_host.js +1 -1
  19. package/ngcc/src/rendering/commonjs_rendering_formatter.js +1 -1
  20. package/ngcc/src/rendering/esm5_rendering_formatter.js +1 -1
  21. package/ngcc/src/rendering/umd_rendering_formatter.js +1 -1
  22. package/ngcc/src/writing/new_entry_point_file_writer.js +1 -1
  23. package/package.json +2 -2
  24. package/src/ngtsc/annotations/src/component.js +1 -1
  25. package/src/ngtsc/annotations/src/directive.js +1 -1
  26. package/src/ngtsc/annotations/src/ng_module.js +1 -1
  27. package/src/ngtsc/annotations/src/pipe.js +1 -1
  28. package/src/ngtsc/core/src/compiler.js +1 -1
  29. package/src/ngtsc/file_system/testing/src/mock_file_system_native.js +1 -1
  30. package/src/ngtsc/file_system/testing/src/mock_file_system_posix.js +1 -1
  31. package/src/ngtsc/file_system/testing/src/mock_file_system_windows.js +1 -1
  32. package/src/ngtsc/incremental/semantic_graph/src/graph.js +1 -1
  33. package/src/ngtsc/incremental/src/incremental.js +30 -4
  34. package/src/ngtsc/indexer/src/template.js +1 -1
  35. package/src/ngtsc/partial_evaluator/src/builtin.js +1 -1
  36. package/src/ngtsc/partial_evaluator/src/ts_helpers.js +1 -1
  37. package/src/ngtsc/program_driver/src/api.d.ts +20 -1
  38. package/src/ngtsc/program_driver/src/api.js +3 -2
  39. package/src/ngtsc/program_driver/src/ts_create_program_driver.d.ts +2 -2
  40. package/src/ngtsc/program_driver/src/ts_create_program_driver.js +7 -3
  41. package/src/ngtsc/reflection/src/typescript.js +4 -1
  42. package/src/ngtsc/transform/src/transform.js +1 -1
  43. package/src/ngtsc/typecheck/src/context.d.ts +2 -1
  44. package/src/ngtsc/typecheck/src/context.js +11 -3
  45. package/src/ngtsc/typecheck/src/template_semantics.js +1 -1
  46. package/src/ngtsc/typecheck/src/template_symbol_builder.js +21 -1
  47. package/src/ngtsc/typecheck/src/type_check_block.js +2 -2
  48. package/src/ngtsc/typecheck/src/type_check_file.js +1 -1
  49. package/src/ngtsc/typecheck/src/type_emitter.js +25 -6
  50. package/src/ngtsc/util/src/visitor.d.ts +1 -1
  51. package/src/ngtsc/util/src/visitor.js +1 -8
  52. package/src/version.js +1 -1
  53. package/compiler-cli.externs.js +0 -0
  54. package/index.mjs +0 -20
  55. package/linker/babel/babel.externs.js +0 -0
  56. package/linker/babel/index.mjs +0 -11
  57. package/linker/babel/src/ast/babel_ast_factory.mjs +0 -137
  58. package/linker/babel/src/ast/babel_ast_host.mjs +0 -154
  59. package/linker/babel/src/babel_declaration_scope.mjs +0 -52
  60. package/linker/babel/src/babel_plugin.mjs +0 -23
  61. package/linker/babel/src/es2015_linker_plugin.mjs +0 -158
  62. package/linker/babel/src/linker_plugin_options.mjs +0 -2
  63. package/linker/index.mjs +0 -7
  64. package/linker/linker.externs.js +0 -0
  65. package/linker/src/ast/ast_host.mjs +0 -9
  66. package/linker/src/ast/ast_value.mjs +0 -256
  67. package/linker/src/ast/typescript/typescript_ast_host.mjs +0 -156
  68. package/linker/src/ast/utils.mjs +0 -17
  69. package/linker/src/fatal_linker_error.mjs +0 -30
  70. package/linker/src/file_linker/declaration_scope.mjs +0 -9
  71. package/linker/src/file_linker/emit_scopes/emit_scope.mjs +0 -41
  72. package/linker/src/file_linker/emit_scopes/iife_emit_scope.mjs +0 -33
  73. package/linker/src/file_linker/file_linker.mjs +0 -70
  74. package/linker/src/file_linker/get_source_file.mjs +0 -28
  75. package/linker/src/file_linker/linker_environment.mjs +0 -23
  76. package/linker/src/file_linker/linker_options.mjs +0 -16
  77. package/linker/src/file_linker/needs_linking.mjs +0 -27
  78. package/linker/src/file_linker/partial_linkers/partial_class_metadata_linker_1.mjs +0 -29
  79. package/linker/src/file_linker/partial_linkers/partial_component_linker_1.mjs +0 -194
  80. package/linker/src/file_linker/partial_linkers/partial_directive_linker_1.mjs +0 -137
  81. package/linker/src/file_linker/partial_linkers/partial_factory_linker_1.mjs +0 -52
  82. package/linker/src/file_linker/partial_linkers/partial_injectable_linker_1.mjs +0 -56
  83. package/linker/src/file_linker/partial_linkers/partial_injector_linker_1.mjs +0 -38
  84. package/linker/src/file_linker/partial_linkers/partial_linker.mjs +0 -2
  85. package/linker/src/file_linker/partial_linkers/partial_linker_selector.mjs +0 -166
  86. package/linker/src/file_linker/partial_linkers/partial_ng_module_linker_1.mjs +0 -110
  87. package/linker/src/file_linker/partial_linkers/partial_pipe_linker_1.mjs +0 -42
  88. package/linker/src/file_linker/partial_linkers/util.mjs +0 -78
  89. package/linker/src/file_linker/translator.mjs +0 -23
  90. package/linker/src/linker_import_generator.mjs +0 -28
  91. package/ngcc/index.mjs +0 -16
  92. package/ngcc/main-ivy-ngcc.mjs +0 -12
  93. package/ngcc/main-ngcc.mjs +0 -32
  94. package/ngcc/ngcc.externs.js +0 -0
  95. package/ngcc/src/analysis/decoration_analyzer.mjs +0 -215
  96. package/ngcc/src/analysis/migration_host.mjs +0 -80
  97. package/ngcc/src/analysis/module_with_providers_analyzer.mjs +0 -178
  98. package/ngcc/src/analysis/ngcc_references_registry.mjs +0 -45
  99. package/ngcc/src/analysis/ngcc_trait_compiler.mjs +0 -70
  100. package/ngcc/src/analysis/private_declarations_analyzer.mjs +0 -47
  101. package/ngcc/src/analysis/switch_marker_analyzer.mjs +0 -34
  102. package/ngcc/src/analysis/types.mjs +0 -2
  103. package/ngcc/src/analysis/util.mjs +0 -19
  104. package/ngcc/src/command_line_options.mjs +0 -142
  105. package/ngcc/src/constants.mjs +0 -10
  106. package/ngcc/src/dependencies/commonjs_dependency_host.mjs +0 -87
  107. package/ngcc/src/dependencies/dependency_host.mjs +0 -102
  108. package/ngcc/src/dependencies/dependency_resolver.mjs +0 -151
  109. package/ngcc/src/dependencies/dts_dependency_host.mjs +0 -18
  110. package/ngcc/src/dependencies/esm_dependency_host.mjs +0 -286
  111. package/ngcc/src/dependencies/module_resolver.mjs +0 -233
  112. package/ngcc/src/dependencies/umd_dependency_host.mjs +0 -33
  113. package/ngcc/src/entry_point_finder/directory_walker_entry_point_finder.mjs +0 -42
  114. package/ngcc/src/entry_point_finder/entry_point_collector.mjs +0 -120
  115. package/ngcc/src/entry_point_finder/interface.mjs +0 -2
  116. package/ngcc/src/entry_point_finder/program_based_entry_point_finder.mjs +0 -91
  117. package/ngcc/src/entry_point_finder/targeted_entry_point_finder.mjs +0 -216
  118. package/ngcc/src/entry_point_finder/tracing_entry_point_finder.mjs +0 -63
  119. package/ngcc/src/entry_point_finder/utils.mjs +0 -176
  120. package/ngcc/src/execution/analyze_entry_points.mjs +0 -130
  121. package/ngcc/src/execution/api.mjs +0 -2
  122. package/ngcc/src/execution/cluster/api.mjs +0 -9
  123. package/ngcc/src/execution/cluster/executor.mjs +0 -27
  124. package/ngcc/src/execution/cluster/master.mjs +0 -261
  125. package/ngcc/src/execution/cluster/package_json_updater.mjs +0 -45
  126. package/ngcc/src/execution/cluster/utils.mjs +0 -59
  127. package/ngcc/src/execution/cluster/worker.mjs +0 -81
  128. package/ngcc/src/execution/create_compile_function.mjs +0 -62
  129. package/ngcc/src/execution/single_process_executor.mjs +0 -57
  130. package/ngcc/src/execution/tasks/api.mjs +0 -22
  131. package/ngcc/src/execution/tasks/completion.mjs +0 -61
  132. package/ngcc/src/execution/tasks/queues/base_task_queue.mjs +0 -78
  133. package/ngcc/src/execution/tasks/queues/parallel_task_queue.mjs +0 -53
  134. package/ngcc/src/execution/tasks/queues/serial_task_queue.mjs +0 -29
  135. package/ngcc/src/execution/tasks/utils.mjs +0 -114
  136. package/ngcc/src/host/commonjs_host.mjs +0 -220
  137. package/ngcc/src/host/commonjs_umd_utils.mjs +0 -186
  138. package/ngcc/src/host/delegating_host.mjs +0 -140
  139. package/ngcc/src/host/esm2015_host.mjs +0 -2293
  140. package/ngcc/src/host/esm5_host.mjs +0 -721
  141. package/ngcc/src/host/ngcc_host.mjs +0 -15
  142. package/ngcc/src/host/umd_host.mjs +0 -486
  143. package/ngcc/src/host/utils.mjs +0 -12
  144. package/ngcc/src/locking/async_locker.mjs +0 -76
  145. package/ngcc/src/locking/lock_file.mjs +0 -4
  146. package/ngcc/src/locking/lock_file_with_child_process/index.mjs +0 -78
  147. package/ngcc/src/locking/lock_file_with_child_process/unlocker.mjs +0 -34
  148. package/ngcc/src/locking/lock_file_with_child_process/util.mjs +0 -29
  149. package/ngcc/src/locking/sync_locker.mjs +0 -52
  150. package/ngcc/src/main.mjs +0 -134
  151. package/ngcc/src/migrations/migration.mjs +0 -2
  152. package/ngcc/src/migrations/missing_injectable_migration.mjs +0 -164
  153. package/ngcc/src/migrations/undecorated_child_migration.mjs +0 -61
  154. package/ngcc/src/migrations/undecorated_parent_migration.mjs +0 -86
  155. package/ngcc/src/migrations/utils.mjs +0 -117
  156. package/ngcc/src/ngcc_options.mjs +0 -119
  157. package/ngcc/src/packages/build_marker.mjs +0 -84
  158. package/ngcc/src/packages/bundle_program.mjs +0 -52
  159. package/ngcc/src/packages/configuration.mjs +0 -255
  160. package/ngcc/src/packages/entry_point.mjs +0 -239
  161. package/ngcc/src/packages/entry_point_bundle.mjs +0 -68
  162. package/ngcc/src/packages/entry_point_manifest.mjs +0 -162
  163. package/ngcc/src/packages/ngcc_compiler_host.mjs +0 -77
  164. package/ngcc/src/packages/patch_ts_expando_initializer.mjs +0 -166
  165. package/ngcc/src/packages/source_file_cache.mjs +0 -187
  166. package/ngcc/src/packages/transformer.mjs +0 -140
  167. package/ngcc/src/path_mappings.mjs +0 -13
  168. package/ngcc/src/rendering/commonjs_rendering_formatter.mjs +0 -65
  169. package/ngcc/src/rendering/dts_renderer.mjs +0 -139
  170. package/ngcc/src/rendering/esm5_rendering_formatter.mjs +0 -50
  171. package/ngcc/src/rendering/esm_rendering_formatter.mjs +0 -251
  172. package/ngcc/src/rendering/ngcc_import_rewriter.mjs +0 -32
  173. package/ngcc/src/rendering/renderer.mjs +0 -170
  174. package/ngcc/src/rendering/rendering_formatter.mjs +0 -2
  175. package/ngcc/src/rendering/source_maps.mjs +0 -54
  176. package/ngcc/src/rendering/umd_rendering_formatter.mjs +0 -292
  177. package/ngcc/src/rendering/utils.mjs +0 -20
  178. package/ngcc/src/utils.mjs +0 -144
  179. package/ngcc/src/writing/cleaning/cleaning_strategies.mjs +0 -61
  180. package/ngcc/src/writing/cleaning/package_cleaner.mjs +0 -67
  181. package/ngcc/src/writing/cleaning/utils.mjs +0 -16
  182. package/ngcc/src/writing/file_writer.mjs +0 -2
  183. package/ngcc/src/writing/in_place_file_writer.mjs +0 -62
  184. package/ngcc/src/writing/new_entry_point_file_writer.mjs +0 -161
  185. package/ngcc/src/writing/package_json_updater.mjs +0 -144
  186. package/src/diagnostics/translate_diagnostics.mjs +0 -47
  187. package/src/diagnostics/typescript_version.mjs +0 -79
  188. package/src/extract_i18n.mjs +0 -46
  189. package/src/language_services.mjs +0 -18
  190. package/src/main.mjs +0 -185
  191. package/src/metadata/bundle_index_host.mjs +0 -107
  192. package/src/metadata/bundler.mjs +0 -556
  193. package/src/metadata/collector.mjs +0 -701
  194. package/src/metadata/evaluator.mjs +0 -643
  195. package/src/metadata/index.mjs +0 -11
  196. package/src/metadata/index_writer.mjs +0 -44
  197. package/src/metadata/schema.mjs +0 -102
  198. package/src/metadata/symbols.mjs +0 -117
  199. package/src/ngtsc/annotations/annotations.externs.js +0 -0
  200. package/src/ngtsc/annotations/index.mjs +0 -15
  201. package/src/ngtsc/annotations/src/api.mjs +0 -9
  202. package/src/ngtsc/annotations/src/component.mjs +0 -1068
  203. package/src/ngtsc/annotations/src/diagnostics.mjs +0 -147
  204. package/src/ngtsc/annotations/src/directive.mjs +0 -692
  205. package/src/ngtsc/annotations/src/factory.mjs +0 -17
  206. package/src/ngtsc/annotations/src/injectable.mjs +0 -260
  207. package/src/ngtsc/annotations/src/metadata.mjs +0 -145
  208. package/src/ngtsc/annotations/src/ng_module.mjs +0 -565
  209. package/src/ngtsc/annotations/src/pipe.mjs +0 -151
  210. package/src/ngtsc/annotations/src/references_registry.mjs +0 -16
  211. package/src/ngtsc/annotations/src/util.mjs +0 -495
  212. package/src/ngtsc/core/api/index.mjs +0 -12
  213. package/src/ngtsc/core/api/src/adapter.mjs +0 -9
  214. package/src/ngtsc/core/api/src/interfaces.mjs +0 -9
  215. package/src/ngtsc/core/api/src/options.mjs +0 -9
  216. package/src/ngtsc/core/api/src/public_options.mjs +0 -9
  217. package/src/ngtsc/core/api.externs.js +0 -0
  218. package/src/ngtsc/core/core.externs.js +0 -0
  219. package/src/ngtsc/core/index.mjs +0 -10
  220. package/src/ngtsc/core/src/compiler.mjs +0 -917
  221. package/src/ngtsc/core/src/config.mjs +0 -15
  222. package/src/ngtsc/core/src/host.mjs +0 -229
  223. package/src/ngtsc/cycles/cycles.externs.js +0 -0
  224. package/src/ngtsc/cycles/index.mjs +0 -10
  225. package/src/ngtsc/cycles/src/analyzer.mjs +0 -60
  226. package/src/ngtsc/cycles/src/imports.mjs +0 -152
  227. package/src/ngtsc/diagnostics/diagnostics.externs.js +0 -0
  228. package/src/ngtsc/diagnostics/index.mjs +0 -11
  229. package/src/ngtsc/diagnostics/src/error.mjs +0 -51
  230. package/src/ngtsc/diagnostics/src/error_code.mjs +0 -198
  231. package/src/ngtsc/diagnostics/src/util.mjs +0 -21
  232. package/src/ngtsc/entry_point/entry_point.externs.js +0 -0
  233. package/src/ngtsc/entry_point/index.mjs +0 -12
  234. package/src/ngtsc/entry_point/src/generator.mjs +0 -35
  235. package/src/ngtsc/entry_point/src/logic.mjs +0 -35
  236. package/src/ngtsc/entry_point/src/private_export_checker.mjs +0 -122
  237. package/src/ngtsc/entry_point/src/reference_graph.mjs +0 -73
  238. package/src/ngtsc/file_system/file_system.externs.js +0 -0
  239. package/src/ngtsc/file_system/index.mjs +0 -13
  240. package/src/ngtsc/file_system/src/compiler_host.mjs +0 -64
  241. package/src/ngtsc/file_system/src/helpers.mjs +0 -99
  242. package/src/ngtsc/file_system/src/invalid_file_system.mjs +0 -95
  243. package/src/ngtsc/file_system/src/logical.mjs +0 -84
  244. package/src/ngtsc/file_system/src/node_js_file_system.mjs +0 -142
  245. package/src/ngtsc/file_system/src/types.mjs +0 -9
  246. package/src/ngtsc/file_system/src/util.mjs +0 -22
  247. package/src/ngtsc/file_system/testing/index.mjs +0 -13
  248. package/src/ngtsc/file_system/testing/src/mock_file_system.mjs +0 -293
  249. package/src/ngtsc/file_system/testing/src/mock_file_system_native.mjs +0 -57
  250. package/src/ngtsc/file_system/testing/src/mock_file_system_posix.mjs +0 -38
  251. package/src/ngtsc/file_system/testing/src/mock_file_system_windows.mjs +0 -38
  252. package/src/ngtsc/file_system/testing/src/test_helper.mjs +0 -108
  253. package/src/ngtsc/file_system/testing/testing.externs.js +0 -0
  254. package/src/ngtsc/imports/imports.externs.js +0 -0
  255. package/src/ngtsc/imports/index.mjs +0 -14
  256. package/src/ngtsc/imports/src/alias.mjs +0 -137
  257. package/src/ngtsc/imports/src/core.mjs +0 -78
  258. package/src/ngtsc/imports/src/default.mjs +0 -135
  259. package/src/ngtsc/imports/src/emitter.mjs +0 -266
  260. package/src/ngtsc/imports/src/find_export.mjs +0 -56
  261. package/src/ngtsc/imports/src/reexport.mjs +0 -9
  262. package/src/ngtsc/imports/src/references.mjs +0 -137
  263. package/src/ngtsc/imports/src/resolver.mjs +0 -24
  264. package/src/ngtsc/incremental/api.externs.js +0 -0
  265. package/src/ngtsc/incremental/api.mjs +0 -9
  266. package/src/ngtsc/incremental/incremental.externs.js +0 -0
  267. package/src/ngtsc/incremental/index.mjs +0 -12
  268. package/src/ngtsc/incremental/semantic_graph/index.mjs +0 -12
  269. package/src/ngtsc/incremental/semantic_graph/semantic_graph.externs.js +0 -0
  270. package/src/ngtsc/incremental/semantic_graph/src/api.mjs +0 -36
  271. package/src/ngtsc/incremental/semantic_graph/src/graph.mjs +0 -237
  272. package/src/ngtsc/incremental/semantic_graph/src/type_parameters.mjs +0 -40
  273. package/src/ngtsc/incremental/semantic_graph/src/util.mjs +0 -69
  274. package/src/ngtsc/incremental/src/dependency_tracking.mjs +0 -117
  275. package/src/ngtsc/incremental/src/incremental.mjs +0 -271
  276. package/src/ngtsc/incremental/src/noop.mjs +0 -13
  277. package/src/ngtsc/incremental/src/state.mjs +0 -17
  278. package/src/ngtsc/incremental/src/strategy.mjs +0 -76
  279. package/src/ngtsc/indexer/index.mjs +0 -11
  280. package/src/ngtsc/indexer/indexer.externs.js +0 -0
  281. package/src/ngtsc/indexer/src/api.mjs +0 -30
  282. package/src/ngtsc/indexer/src/context.mjs +0 -25
  283. package/src/ngtsc/indexer/src/template.mjs +0 -303
  284. package/src/ngtsc/indexer/src/transform.mjs +0 -51
  285. package/src/ngtsc/logging/index.mjs +0 -10
  286. package/src/ngtsc/logging/logging.externs.js +0 -0
  287. package/src/ngtsc/logging/src/console_logger.mjs +0 -43
  288. package/src/ngtsc/logging/src/logger.mjs +0 -15
  289. package/src/ngtsc/logging/testing/index.mjs +0 -9
  290. package/src/ngtsc/logging/testing/src/mock_logger.mjs +0 -32
  291. package/src/ngtsc/logging/testing/testing.externs.js +0 -0
  292. package/src/ngtsc/metadata/index.mjs +0 -15
  293. package/src/ngtsc/metadata/metadata.externs.js +0 -0
  294. package/src/ngtsc/metadata/src/api.mjs +0 -13
  295. package/src/ngtsc/metadata/src/dts.mjs +0 -143
  296. package/src/ngtsc/metadata/src/inheritance.mjs +0 -71
  297. package/src/ngtsc/metadata/src/property_mapping.mjs +0 -136
  298. package/src/ngtsc/metadata/src/registry.mjs +0 -80
  299. package/src/ngtsc/metadata/src/resource_registry.mjs +0 -81
  300. package/src/ngtsc/metadata/src/util.mjs +0 -200
  301. package/src/ngtsc/partial_evaluator/index.mjs +0 -12
  302. package/src/ngtsc/partial_evaluator/partial_evaluator.externs.js +0 -0
  303. package/src/ngtsc/partial_evaluator/src/builtin.mjs +0 -65
  304. package/src/ngtsc/partial_evaluator/src/diagnostics.mjs +0 -174
  305. package/src/ngtsc/partial_evaluator/src/dynamic.mjs +0 -94
  306. package/src/ngtsc/partial_evaluator/src/interface.mjs +0 -27
  307. package/src/ngtsc/partial_evaluator/src/interpreter.mjs +0 -719
  308. package/src/ngtsc/partial_evaluator/src/known_declaration.mjs +0 -43
  309. package/src/ngtsc/partial_evaluator/src/result.mjs +0 -50
  310. package/src/ngtsc/partial_evaluator/src/ts_helpers.mjs +0 -72
  311. package/src/ngtsc/perf/index.mjs +0 -11
  312. package/src/ngtsc/perf/perf.externs.js +0 -0
  313. package/src/ngtsc/perf/src/api.mjs +0 -278
  314. package/src/ngtsc/perf/src/clock.mjs +0 -15
  315. package/src/ngtsc/perf/src/noop.mjs +0 -21
  316. package/src/ngtsc/perf/src/recorder.mjs +0 -125
  317. package/src/ngtsc/program.mjs +0 -271
  318. package/src/ngtsc/program_driver/index.mjs +0 -10
  319. package/src/ngtsc/program_driver/program_driver.externs.js +0 -0
  320. package/src/ngtsc/program_driver/src/api.mjs +0 -22
  321. package/src/ngtsc/program_driver/src/ts_create_program_driver.mjs +0 -164
  322. package/src/ngtsc/reflection/index.mjs +0 -12
  323. package/src/ngtsc/reflection/reflection.externs.js +0 -0
  324. package/src/ngtsc/reflection/src/host.mjs +0 -73
  325. package/src/ngtsc/reflection/src/type_to_value.mjs +0 -243
  326. package/src/ngtsc/reflection/src/typescript.mjs +0 -608
  327. package/src/ngtsc/reflection/src/util.mjs +0 -21
  328. package/src/ngtsc/resource/index.mjs +0 -9
  329. package/src/ngtsc/resource/resource.externs.js +0 -0
  330. package/src/ngtsc/resource/src/loader.mjs +0 -242
  331. package/src/ngtsc/routing/index.mjs +0 -11
  332. package/src/ngtsc/routing/routing.externs.js +0 -0
  333. package/src/ngtsc/routing/src/analyzer.mjs +0 -69
  334. package/src/ngtsc/routing/src/lazy.mjs +0 -168
  335. package/src/ngtsc/routing/src/route.mjs +0 -51
  336. package/src/ngtsc/scope/index.mjs +0 -12
  337. package/src/ngtsc/scope/scope.externs.js +0 -0
  338. package/src/ngtsc/scope/src/api.mjs +0 -9
  339. package/src/ngtsc/scope/src/component_scope.mjs +0 -31
  340. package/src/ngtsc/scope/src/dependency.mjs +0 -134
  341. package/src/ngtsc/scope/src/local.mjs +0 -531
  342. package/src/ngtsc/scope/src/typecheck.mjs +0 -83
  343. package/src/ngtsc/shims/api.externs.js +0 -0
  344. package/src/ngtsc/shims/api.mjs +0 -2
  345. package/src/ngtsc/shims/index.mjs +0 -14
  346. package/src/ngtsc/shims/shims.externs.js +0 -0
  347. package/src/ngtsc/shims/src/adapter.mjs +0 -188
  348. package/src/ngtsc/shims/src/expando.mjs +0 -102
  349. package/src/ngtsc/shims/src/factory_generator.mjs +0 -265
  350. package/src/ngtsc/shims/src/reference_tagger.mjs +0 -67
  351. package/src/ngtsc/shims/src/summary_generator.mjs +0 -64
  352. package/src/ngtsc/shims/src/util.mjs +0 -26
  353. package/src/ngtsc/sourcemaps/index.mjs +0 -11
  354. package/src/ngtsc/sourcemaps/sourcemaps.externs.js +0 -0
  355. package/src/ngtsc/sourcemaps/src/content_origin.mjs +0 -35
  356. package/src/ngtsc/sourcemaps/src/raw_source_map.mjs +0 -2
  357. package/src/ngtsc/sourcemaps/src/segment_marker.mjs +0 -40
  358. package/src/ngtsc/sourcemaps/src/source_file.mjs +0 -459
  359. package/src/ngtsc/sourcemaps/src/source_file_loader.mjs +0 -213
  360. package/src/ngtsc/switch/index.mjs +0 -9
  361. package/src/ngtsc/switch/src/switch.mjs +0 -115
  362. package/src/ngtsc/switch/switch.externs.js +0 -0
  363. package/src/ngtsc/transform/index.mjs +0 -14
  364. package/src/ngtsc/transform/src/alias.mjs +0 -30
  365. package/src/ngtsc/transform/src/api.mjs +0 -63
  366. package/src/ngtsc/transform/src/compilation.mjs +0 -514
  367. package/src/ngtsc/transform/src/declaration.mjs +0 -182
  368. package/src/ngtsc/transform/src/trait.mjs +0 -95
  369. package/src/ngtsc/transform/src/transform.mjs +0 -298
  370. package/src/ngtsc/transform/src/utils.mjs +0 -57
  371. package/src/ngtsc/transform/transform.externs.js +0 -0
  372. package/src/ngtsc/translator/index.mjs +0 -14
  373. package/src/ngtsc/translator/src/api/ast_factory.mjs +0 -9
  374. package/src/ngtsc/translator/src/api/import_generator.mjs +0 -9
  375. package/src/ngtsc/translator/src/context.mjs +0 -24
  376. package/src/ngtsc/translator/src/import_manager.mjs +0 -48
  377. package/src/ngtsc/translator/src/translator.mjs +0 -317
  378. package/src/ngtsc/translator/src/type_translator.mjs +0 -204
  379. package/src/ngtsc/translator/src/typescript_ast_factory.mjs +0 -211
  380. package/src/ngtsc/translator/src/typescript_translator.mjs +0 -17
  381. package/src/ngtsc/translator/translator.externs.js +0 -0
  382. package/src/ngtsc/tsc_plugin.mjs +0 -98
  383. package/src/ngtsc/typecheck/api/api.externs.js +0 -0
  384. package/src/ngtsc/typecheck/api/api.mjs +0 -9
  385. package/src/ngtsc/typecheck/api/checker.mjs +0 -31
  386. package/src/ngtsc/typecheck/api/completion.mjs +0 -16
  387. package/src/ngtsc/typecheck/api/context.mjs +0 -9
  388. package/src/ngtsc/typecheck/api/index.mjs +0 -14
  389. package/src/ngtsc/typecheck/api/scope.mjs +0 -9
  390. package/src/ngtsc/typecheck/api/symbols.mjs +0 -22
  391. package/src/ngtsc/typecheck/diagnostics/diagnostics.externs.js +0 -0
  392. package/src/ngtsc/typecheck/diagnostics/index.mjs +0 -10
  393. package/src/ngtsc/typecheck/diagnostics/src/diagnostic.mjs +0 -99
  394. package/src/ngtsc/typecheck/diagnostics/src/id.mjs +0 -23
  395. package/src/ngtsc/typecheck/index.mjs +0 -12
  396. package/src/ngtsc/typecheck/src/checker.mjs +0 -591
  397. package/src/ngtsc/typecheck/src/comments.mjs +0 -159
  398. package/src/ngtsc/typecheck/src/completion.mjs +0 -155
  399. package/src/ngtsc/typecheck/src/context.mjs +0 -350
  400. package/src/ngtsc/typecheck/src/diagnostics.mjs +0 -95
  401. package/src/ngtsc/typecheck/src/dom.mjs +0 -68
  402. package/src/ngtsc/typecheck/src/environment.mjs +0 -146
  403. package/src/ngtsc/typecheck/src/expression.mjs +0 -412
  404. package/src/ngtsc/typecheck/src/line_mappings.mjs +0 -60
  405. package/src/ngtsc/typecheck/src/oob.mjs +0 -112
  406. package/src/ngtsc/typecheck/src/shim.mjs +0 -37
  407. package/src/ngtsc/typecheck/src/source.mjs +0 -74
  408. package/src/ngtsc/typecheck/src/tcb_util.mjs +0 -135
  409. package/src/ngtsc/typecheck/src/template_semantics.mjs +0 -34
  410. package/src/ngtsc/typecheck/src/template_symbol_builder.mjs +0 -485
  411. package/src/ngtsc/typecheck/src/ts_util.mjs +0 -157
  412. package/src/ngtsc/typecheck/src/type_check_block.mjs +0 -1770
  413. package/src/ngtsc/typecheck/src/type_check_file.mjs +0 -65
  414. package/src/ngtsc/typecheck/src/type_constructor.mjs +0 -227
  415. package/src/ngtsc/typecheck/src/type_emitter.mjs +0 -127
  416. package/src/ngtsc/typecheck/src/type_parameter_emitter.mjs +0 -93
  417. package/src/ngtsc/typecheck/typecheck.externs.js +0 -0
  418. package/src/ngtsc/util/src/path.mjs +0 -18
  419. package/src/ngtsc/util/src/typescript.mjs +0 -143
  420. package/src/ngtsc/util/src/visitor.mjs +0 -107
  421. package/src/ngtsc/util/util.externs.js +0 -0
  422. package/src/ngtsc/xi18n/index.mjs +0 -9
  423. package/src/ngtsc/xi18n/src/context.mjs +0 -9
  424. package/src/ngtsc/xi18n/xi18n.externs.js +0 -0
  425. package/src/perform_compile.mjs +0 -275
  426. package/src/perform_watch.mjs +0 -247
  427. package/src/tooling.mjs +0 -32
  428. package/src/transformers/api.mjs +0 -27
  429. package/src/transformers/compiler_host.mjs +0 -593
  430. package/src/transformers/downlevel_decorators_transform.mjs +0 -507
  431. package/src/transformers/entry_points.mjs +0 -10
  432. package/src/transformers/i18n.mjs +0 -59
  433. package/src/transformers/inline_resources.mjs +0 -269
  434. package/src/transformers/lower_expressions.mjs +0 -336
  435. package/src/transformers/metadata_cache.mjs +0 -53
  436. package/src/transformers/metadata_reader.mjs +0 -104
  437. package/src/transformers/node_emitter.mjs +0 -606
  438. package/src/transformers/node_emitter_transform.mjs +0 -78
  439. package/src/transformers/patch_alias_reference_resolution.mjs +0 -109
  440. package/src/transformers/program.mjs +0 -887
  441. package/src/transformers/r3_metadata_transform.mjs +0 -46
  442. package/src/transformers/r3_transform.mjs +0 -29
  443. package/src/transformers/util.mjs +0 -89
  444. package/src/typescript_support.mjs +0 -57
  445. package/src/version.mjs +0 -15
@@ -1,1770 +0,0 @@
1
- /**
2
- * @license
3
- * Copyright Google LLC All Rights Reserved.
4
- *
5
- * Use of this source code is governed by an MIT-style license that can be
6
- * found in the LICENSE file at https://angular.io/license
7
- */
8
- import { BindingPipe, DYNAMIC_TYPE, ImplicitReceiver, MethodCall, PropertyRead, PropertyWrite, ThisReceiver, TmplAstBoundAttribute, TmplAstBoundText, TmplAstElement, TmplAstIcu, TmplAstReference, TmplAstTemplate, TmplAstTextAttribute, TmplAstVariable } from '@angular/compiler';
9
- import * as ts from 'typescript';
10
- import { addExpressionIdentifier, ExpressionIdentifier, markIgnoreDiagnostics } from './comments';
11
- import { addParseSpanInfo, addTemplateId, wrapForDiagnostics, wrapForTypeChecker } from './diagnostics';
12
- import { astToTypescript, NULL_AS_ANY } from './expression';
13
- import { ExpressionSemanticVisitor } from './template_semantics';
14
- import { tsCallMethod, tsCastToAny, tsCreateElement, tsCreateTypeQueryForCoercedInput, tsCreateVariable, tsDeclareVariable } from './ts_util';
15
- import { requiresInlineTypeCtor } from './type_constructor';
16
- import { TypeParameterEmitter } from './type_parameter_emitter';
17
- /**
18
- * Controls how generics for the component context class will be handled during TCB generation.
19
- */
20
- export var TcbGenericContextBehavior;
21
- (function (TcbGenericContextBehavior) {
22
- /**
23
- * References to generic parameter bounds will be emitted via the `TypeParameterEmitter`.
24
- *
25
- * The caller must verify that all parameter bounds are emittable in order to use this mode.
26
- */
27
- TcbGenericContextBehavior[TcbGenericContextBehavior["UseEmitter"] = 0] = "UseEmitter";
28
- /**
29
- * Generic parameter declarations will be copied directly from the `ts.ClassDeclaration` of the
30
- * component class.
31
- *
32
- * The caller must only use the generated TCB code in a context where such copies will still be
33
- * valid, such as an inline type check block.
34
- */
35
- TcbGenericContextBehavior[TcbGenericContextBehavior["CopyClassNodes"] = 1] = "CopyClassNodes";
36
- /**
37
- * Any generic parameters for the component context class will be set to `any`.
38
- *
39
- * Produces a less useful type, but is always safe to use.
40
- */
41
- TcbGenericContextBehavior[TcbGenericContextBehavior["FallbackToAny"] = 2] = "FallbackToAny";
42
- })(TcbGenericContextBehavior || (TcbGenericContextBehavior = {}));
43
- /**
44
- * Given a `ts.ClassDeclaration` for a component, and metadata regarding that component, compose a
45
- * "type check block" function.
46
- *
47
- * When passed through TypeScript's TypeChecker, type errors that arise within the type check block
48
- * function indicate issues in the template itself.
49
- *
50
- * As a side effect of generating a TCB for the component, `ts.Diagnostic`s may also be produced
51
- * directly for issues within the template which are identified during generation. These issues are
52
- * recorded in either the `domSchemaChecker` (which checks usage of DOM elements and bindings) as
53
- * well as the `oobRecorder` (which records errors when the type-checking code generator is unable
54
- * to sufficiently understand a template).
55
- *
56
- * @param env an `Environment` into which type-checking code will be generated.
57
- * @param ref a `Reference` to the component class which should be type-checked.
58
- * @param name a `ts.Identifier` to use for the generated `ts.FunctionDeclaration`.
59
- * @param meta metadata about the component's template and the function being generated.
60
- * @param domSchemaChecker used to check and record errors regarding improper usage of DOM elements
61
- * and bindings.
62
- * @param oobRecorder used to record errors regarding template elements which could not be correctly
63
- * translated into types during TCB generation.
64
- * @param genericContextBehavior controls how generic parameters (especially parameters with generic
65
- * bounds) will be referenced from the generated TCB code.
66
- */
67
- export function generateTypeCheckBlock(env, ref, name, meta, domSchemaChecker, oobRecorder, genericContextBehavior) {
68
- const tcb = new Context(env, domSchemaChecker, oobRecorder, meta.id, meta.boundTarget, meta.pipes, meta.schemas);
69
- const scope = Scope.forNodes(tcb, null, tcb.boundTarget.target.template, /* guard */ null);
70
- const ctxRawType = env.referenceType(ref);
71
- if (!ts.isTypeReferenceNode(ctxRawType)) {
72
- throw new Error(`Expected TypeReferenceNode when referencing the ctx param for ${ref.debugName}`);
73
- }
74
- let typeParameters = undefined;
75
- let typeArguments = undefined;
76
- if (ref.node.typeParameters !== undefined) {
77
- if (!env.config.useContextGenericType) {
78
- genericContextBehavior = TcbGenericContextBehavior.FallbackToAny;
79
- }
80
- switch (genericContextBehavior) {
81
- case TcbGenericContextBehavior.UseEmitter:
82
- // Guaranteed to emit type parameters since we checked that the class has them above.
83
- typeParameters = new TypeParameterEmitter(ref.node.typeParameters, env.reflector)
84
- .emit(typeRef => env.referenceType(typeRef));
85
- typeArguments = typeParameters.map(param => ts.factory.createTypeReferenceNode(param.name));
86
- break;
87
- case TcbGenericContextBehavior.CopyClassNodes:
88
- typeParameters = [...ref.node.typeParameters];
89
- typeArguments = typeParameters.map(param => ts.factory.createTypeReferenceNode(param.name));
90
- break;
91
- case TcbGenericContextBehavior.FallbackToAny:
92
- typeArguments = ref.node.typeParameters.map(() => ts.factory.createKeywordTypeNode(ts.SyntaxKind.AnyKeyword));
93
- break;
94
- }
95
- }
96
- const paramList = [tcbCtxParam(ref.node, ctxRawType.typeName, typeArguments)];
97
- const scopeStatements = scope.render();
98
- const innerBody = ts.createBlock([
99
- ...env.getPreludeStatements(),
100
- ...scopeStatements,
101
- ]);
102
- // Wrap the body in an "if (true)" expression. This is unnecessary but has the effect of causing
103
- // the `ts.Printer` to format the type-check block nicely.
104
- const body = ts.createBlock([ts.createIf(ts.createTrue(), innerBody, undefined)]);
105
- const fnDecl = ts.createFunctionDeclaration(
106
- /* decorators */ undefined,
107
- /* modifiers */ undefined,
108
- /* asteriskToken */ undefined,
109
- /* name */ name,
110
- /* typeParameters */ env.config.useContextGenericType ? typeParameters : undefined,
111
- /* parameters */ paramList,
112
- /* type */ undefined,
113
- /* body */ body);
114
- addTemplateId(fnDecl, meta.id);
115
- return fnDecl;
116
- }
117
- /**
118
- * A code generation operation that's involved in the construction of a Type Check Block.
119
- *
120
- * The generation of a TCB is non-linear. Bindings within a template may result in the need to
121
- * construct certain types earlier than they otherwise would be constructed. That is, if the
122
- * generation of a TCB for a template is broken down into specific operations (constructing a
123
- * directive, extracting a variable from a let- operation, etc), then it's possible for operations
124
- * earlier in the sequence to depend on operations which occur later in the sequence.
125
- *
126
- * `TcbOp` abstracts the different types of operations which are required to convert a template into
127
- * a TCB. This allows for two phases of processing for the template, where 1) a linear sequence of
128
- * `TcbOp`s is generated, and then 2) these operations are executed, not necessarily in linear
129
- * order.
130
- *
131
- * Each `TcbOp` may insert statements into the body of the TCB, and also optionally return a
132
- * `ts.Expression` which can be used to reference the operation's result.
133
- */
134
- class TcbOp {
135
- /**
136
- * Replacement value or operation used while this `TcbOp` is executing (i.e. to resolve circular
137
- * references during its execution).
138
- *
139
- * This is usually a `null!` expression (which asks TS to infer an appropriate type), but another
140
- * `TcbOp` can be returned in cases where additional code generation is necessary to deal with
141
- * circular references.
142
- */
143
- circularFallback() {
144
- return INFER_TYPE_FOR_CIRCULAR_OP_EXPR;
145
- }
146
- }
147
- /**
148
- * A `TcbOp` which creates an expression for a native DOM element (or web component) from a
149
- * `TmplAstElement`.
150
- *
151
- * Executing this operation returns a reference to the element variable.
152
- */
153
- class TcbElementOp extends TcbOp {
154
- constructor(tcb, scope, element) {
155
- super();
156
- this.tcb = tcb;
157
- this.scope = scope;
158
- this.element = element;
159
- }
160
- get optional() {
161
- // The statement generated by this operation is only used for type-inference of the DOM
162
- // element's type and won't report diagnostics by itself, so the operation is marked as optional
163
- // to avoid generating statements for DOM elements that are never referenced.
164
- return true;
165
- }
166
- execute() {
167
- const id = this.tcb.allocateId();
168
- // Add the declaration of the element using document.createElement.
169
- const initializer = tsCreateElement(this.element.name);
170
- addParseSpanInfo(initializer, this.element.startSourceSpan || this.element.sourceSpan);
171
- this.scope.addStatement(tsCreateVariable(id, initializer));
172
- return id;
173
- }
174
- }
175
- /**
176
- * A `TcbOp` which creates an expression for particular let- `TmplAstVariable` on a
177
- * `TmplAstTemplate`'s context.
178
- *
179
- * Executing this operation returns a reference to the variable variable (lol).
180
- */
181
- class TcbVariableOp extends TcbOp {
182
- constructor(tcb, scope, template, variable) {
183
- super();
184
- this.tcb = tcb;
185
- this.scope = scope;
186
- this.template = template;
187
- this.variable = variable;
188
- }
189
- get optional() {
190
- return false;
191
- }
192
- execute() {
193
- // Look for a context variable for the template.
194
- const ctx = this.scope.resolve(this.template);
195
- // Allocate an identifier for the TmplAstVariable, and initialize it to a read of the variable
196
- // on the template context.
197
- const id = this.tcb.allocateId();
198
- const initializer = ts.createPropertyAccess(
199
- /* expression */ ctx,
200
- /* name */ this.variable.value || '$implicit');
201
- addParseSpanInfo(id, this.variable.keySpan);
202
- // Declare the variable, and return its identifier.
203
- let variable;
204
- if (this.variable.valueSpan !== undefined) {
205
- addParseSpanInfo(initializer, this.variable.valueSpan);
206
- variable = tsCreateVariable(id, wrapForTypeChecker(initializer));
207
- }
208
- else {
209
- variable = tsCreateVariable(id, initializer);
210
- }
211
- addParseSpanInfo(variable.declarationList.declarations[0], this.variable.sourceSpan);
212
- this.scope.addStatement(variable);
213
- return id;
214
- }
215
- }
216
- /**
217
- * A `TcbOp` which generates a variable for a `TmplAstTemplate`'s context.
218
- *
219
- * Executing this operation returns a reference to the template's context variable.
220
- */
221
- class TcbTemplateContextOp extends TcbOp {
222
- constructor(tcb, scope) {
223
- super();
224
- this.tcb = tcb;
225
- this.scope = scope;
226
- // The declaration of the context variable is only needed when the context is actually referenced.
227
- this.optional = true;
228
- }
229
- execute() {
230
- // Allocate a template ctx variable and declare it with an 'any' type. The type of this variable
231
- // may be narrowed as a result of template guard conditions.
232
- const ctx = this.tcb.allocateId();
233
- const type = ts.createKeywordTypeNode(ts.SyntaxKind.AnyKeyword);
234
- this.scope.addStatement(tsDeclareVariable(ctx, type));
235
- return ctx;
236
- }
237
- }
238
- /**
239
- * A `TcbOp` which descends into a `TmplAstTemplate`'s children and generates type-checking code for
240
- * them.
241
- *
242
- * This operation wraps the children's type-checking code in an `if` block, which may include one
243
- * or more type guard conditions that narrow types within the template body.
244
- */
245
- class TcbTemplateBodyOp extends TcbOp {
246
- constructor(tcb, scope, template) {
247
- super();
248
- this.tcb = tcb;
249
- this.scope = scope;
250
- this.template = template;
251
- }
252
- get optional() {
253
- return false;
254
- }
255
- execute() {
256
- // An `if` will be constructed, within which the template's children will be type checked. The
257
- // `if` is used for two reasons: it creates a new syntactic scope, isolating variables declared
258
- // in the template's TCB from the outer context, and it allows any directives on the templates
259
- // to perform type narrowing of either expressions or the template's context.
260
- //
261
- // The guard is the `if` block's condition. It's usually set to `true` but directives that exist
262
- // on the template can trigger extra guard expressions that serve to narrow types within the
263
- // `if`. `guard` is calculated by starting with `true` and adding other conditions as needed.
264
- // Collect these into `guards` by processing the directives.
265
- const directiveGuards = [];
266
- const directives = this.tcb.boundTarget.getDirectivesOfNode(this.template);
267
- if (directives !== null) {
268
- for (const dir of directives) {
269
- const dirInstId = this.scope.resolve(this.template, dir);
270
- const dirId = this.tcb.env.reference(dir.ref);
271
- // There are two kinds of guards. Template guards (ngTemplateGuards) allow type narrowing of
272
- // the expression passed to an @Input of the directive. Scan the directive to see if it has
273
- // any template guards, and generate them if needed.
274
- dir.ngTemplateGuards.forEach(guard => {
275
- // For each template guard function on the directive, look for a binding to that input.
276
- const boundInput = this.template.inputs.find(i => i.name === guard.inputName) ||
277
- this.template.templateAttrs.find((i) => i instanceof TmplAstBoundAttribute && i.name === guard.inputName);
278
- if (boundInput !== undefined) {
279
- // If there is such a binding, generate an expression for it.
280
- const expr = tcbExpression(boundInput.value, this.tcb, this.scope);
281
- // The expression has already been checked in the type constructor invocation, so
282
- // it should be ignored when used within a template guard.
283
- markIgnoreDiagnostics(expr);
284
- if (guard.type === 'binding') {
285
- // Use the binding expression itself as guard.
286
- directiveGuards.push(expr);
287
- }
288
- else {
289
- // Call the guard function on the directive with the directive instance and that
290
- // expression.
291
- const guardInvoke = tsCallMethod(dirId, `ngTemplateGuard_${guard.inputName}`, [
292
- dirInstId,
293
- expr,
294
- ]);
295
- addParseSpanInfo(guardInvoke, boundInput.value.sourceSpan);
296
- directiveGuards.push(guardInvoke);
297
- }
298
- }
299
- });
300
- // The second kind of guard is a template context guard. This guard narrows the template
301
- // rendering context variable `ctx`.
302
- if (dir.hasNgTemplateContextGuard) {
303
- if (this.tcb.env.config.applyTemplateContextGuards) {
304
- const ctx = this.scope.resolve(this.template);
305
- const guardInvoke = tsCallMethod(dirId, 'ngTemplateContextGuard', [dirInstId, ctx]);
306
- addParseSpanInfo(guardInvoke, this.template.sourceSpan);
307
- directiveGuards.push(guardInvoke);
308
- }
309
- else if (this.template.variables.length > 0 &&
310
- this.tcb.env.config.suggestionsForSuboptimalTypeInference) {
311
- // The compiler could have inferred a better type for the variables in this template,
312
- // but was prevented from doing so by the type-checking configuration. Issue a warning
313
- // diagnostic.
314
- this.tcb.oobRecorder.suboptimalTypeInference(this.tcb.id, this.template.variables);
315
- }
316
- }
317
- }
318
- }
319
- // By default the guard is simply `true`.
320
- let guard = null;
321
- // If there are any guards from directives, use them instead.
322
- if (directiveGuards.length > 0) {
323
- // Pop the first value and use it as the initializer to reduce(). This way, a single guard
324
- // will be used on its own, but two or more will be combined into binary AND expressions.
325
- guard = directiveGuards.reduce((expr, dirGuard) => ts.createBinary(expr, ts.SyntaxKind.AmpersandAmpersandToken, dirGuard), directiveGuards.pop());
326
- }
327
- // Create a new Scope for the template. This constructs the list of operations for the template
328
- // children, as well as tracks bindings within the template.
329
- const tmplScope = Scope.forNodes(this.tcb, this.scope, this.template, guard);
330
- // Render the template's `Scope` into its statements.
331
- const statements = tmplScope.render();
332
- if (statements.length === 0) {
333
- // As an optimization, don't generate the scope's block if it has no statements. This is
334
- // beneficial for templates that contain for example `<span *ngIf="first"></span>`, in which
335
- // case there's no need to render the `NgIf` guard expression. This seems like a minor
336
- // improvement, however it reduces the number of flow-node antecedents that TypeScript needs
337
- // to keep into account for such cases, resulting in an overall reduction of
338
- // type-checking time.
339
- return null;
340
- }
341
- let tmplBlock = ts.createBlock(statements);
342
- if (guard !== null) {
343
- // The scope has a guard that needs to be applied, so wrap the template block into an `if`
344
- // statement containing the guard expression.
345
- tmplBlock = ts.createIf(/* expression */ guard, /* thenStatement */ tmplBlock);
346
- }
347
- this.scope.addStatement(tmplBlock);
348
- return null;
349
- }
350
- }
351
- /**
352
- * A `TcbOp` which renders a text binding (interpolation) into the TCB.
353
- *
354
- * Executing this operation returns nothing.
355
- */
356
- class TcbTextInterpolationOp extends TcbOp {
357
- constructor(tcb, scope, binding) {
358
- super();
359
- this.tcb = tcb;
360
- this.scope = scope;
361
- this.binding = binding;
362
- }
363
- get optional() {
364
- return false;
365
- }
366
- execute() {
367
- const expr = tcbExpression(this.binding.value, this.tcb, this.scope);
368
- this.scope.addStatement(ts.createExpressionStatement(expr));
369
- return null;
370
- }
371
- }
372
- /**
373
- * A `TcbOp` which constructs an instance of a directive. For generic directives, generic
374
- * parameters are set to `any` type.
375
- */
376
- class TcbDirectiveTypeOpBase extends TcbOp {
377
- constructor(tcb, scope, node, dir) {
378
- super();
379
- this.tcb = tcb;
380
- this.scope = scope;
381
- this.node = node;
382
- this.dir = dir;
383
- }
384
- get optional() {
385
- // The statement generated by this operation is only used to declare the directive's type and
386
- // won't report diagnostics by itself, so the operation is marked as optional to avoid
387
- // generating declarations for directives that don't have any inputs/outputs.
388
- return true;
389
- }
390
- execute() {
391
- const dirRef = this.dir.ref;
392
- const rawType = this.tcb.env.referenceType(this.dir.ref);
393
- let type;
394
- if (this.dir.isGeneric === false || dirRef.node.typeParameters === undefined) {
395
- type = rawType;
396
- }
397
- else {
398
- if (!ts.isTypeReferenceNode(rawType)) {
399
- throw new Error(`Expected TypeReferenceNode when referencing the type for ${this.dir.ref.debugName}`);
400
- }
401
- const typeArguments = dirRef.node.typeParameters.map(() => ts.factory.createKeywordTypeNode(ts.SyntaxKind.AnyKeyword));
402
- type = ts.factory.createTypeReferenceNode(rawType.typeName, typeArguments);
403
- }
404
- const id = this.tcb.allocateId();
405
- addExpressionIdentifier(type, ExpressionIdentifier.DIRECTIVE);
406
- addParseSpanInfo(type, this.node.startSourceSpan || this.node.sourceSpan);
407
- this.scope.addStatement(tsDeclareVariable(id, type));
408
- return id;
409
- }
410
- }
411
- /**
412
- * A `TcbOp` which constructs an instance of a non-generic directive _without_ setting any of its
413
- * inputs. Inputs are later set in the `TcbDirectiveInputsOp`. Type checking was found to be
414
- * faster when done in this way as opposed to `TcbDirectiveCtorOp` which is only necessary when the
415
- * directive is generic.
416
- *
417
- * Executing this operation returns a reference to the directive instance variable with its inferred
418
- * type.
419
- */
420
- class TcbNonGenericDirectiveTypeOp extends TcbDirectiveTypeOpBase {
421
- /**
422
- * Creates a variable declaration for this op's directive of the argument type. Returns the id of
423
- * the newly created variable.
424
- */
425
- execute() {
426
- const dirRef = this.dir.ref;
427
- if (this.dir.isGeneric) {
428
- throw new Error(`Assertion Error: expected ${dirRef.debugName} not to be generic.`);
429
- }
430
- return super.execute();
431
- }
432
- }
433
- /**
434
- * A `TcbOp` which constructs an instance of a generic directive with its generic parameters set
435
- * to `any` type. This op is like `TcbDirectiveTypeOp`, except that generic parameters are set to
436
- * `any` type. This is used for situations where we want to avoid inlining.
437
- *
438
- * Executing this operation returns a reference to the directive instance variable with its generic
439
- * type parameters set to `any`.
440
- */
441
- class TcbGenericDirectiveTypeWithAnyParamsOp extends TcbDirectiveTypeOpBase {
442
- execute() {
443
- const dirRef = this.dir.ref;
444
- if (dirRef.node.typeParameters === undefined) {
445
- throw new Error(`Assertion Error: expected typeParameters when creating a declaration for ${dirRef.debugName}`);
446
- }
447
- return super.execute();
448
- }
449
- }
450
- /**
451
- * A `TcbOp` which creates a variable for a local ref in a template.
452
- * The initializer for the variable is the variable expression for the directive, template, or
453
- * element the ref refers to. When the reference is used in the template, those TCB statements will
454
- * access this variable as well. For example:
455
- * ```
456
- * var _t1 = document.createElement('div');
457
- * var _t2 = _t1;
458
- * _t2.value
459
- * ```
460
- * This operation supports more fluent lookups for the `TemplateTypeChecker` when getting a symbol
461
- * for a reference. In most cases, this isn't essential; that is, the information for the symbol
462
- * could be gathered without this operation using the `BoundTarget`. However, for the case of
463
- * ng-template references, we will need this reference variable to not only provide a location in
464
- * the shim file, but also to narrow the variable to the correct `TemplateRef<T>` type rather than
465
- * `TemplateRef<any>` (this work is still TODO).
466
- *
467
- * Executing this operation returns a reference to the directive instance variable with its inferred
468
- * type.
469
- */
470
- class TcbReferenceOp extends TcbOp {
471
- constructor(tcb, scope, node, host, target) {
472
- super();
473
- this.tcb = tcb;
474
- this.scope = scope;
475
- this.node = node;
476
- this.host = host;
477
- this.target = target;
478
- // The statement generated by this operation is only used to for the Type Checker
479
- // so it can map a reference variable in the template directly to a node in the TCB.
480
- this.optional = true;
481
- }
482
- execute() {
483
- const id = this.tcb.allocateId();
484
- let initializer = this.target instanceof TmplAstTemplate || this.target instanceof TmplAstElement ?
485
- this.scope.resolve(this.target) :
486
- this.scope.resolve(this.host, this.target);
487
- // The reference is either to an element, an <ng-template> node, or to a directive on an
488
- // element or template.
489
- if ((this.target instanceof TmplAstElement && !this.tcb.env.config.checkTypeOfDomReferences) ||
490
- !this.tcb.env.config.checkTypeOfNonDomReferences) {
491
- // References to DOM nodes are pinned to 'any' when `checkTypeOfDomReferences` is `false`.
492
- // References to `TemplateRef`s and directives are pinned to 'any' when
493
- // `checkTypeOfNonDomReferences` is `false`.
494
- initializer =
495
- ts.createAsExpression(initializer, ts.createKeywordTypeNode(ts.SyntaxKind.AnyKeyword));
496
- }
497
- else if (this.target instanceof TmplAstTemplate) {
498
- // Direct references to an <ng-template> node simply require a value of type
499
- // `TemplateRef<any>`. To get this, an expression of the form
500
- // `(_t1 as any as TemplateRef<any>)` is constructed.
501
- initializer =
502
- ts.createAsExpression(initializer, ts.createKeywordTypeNode(ts.SyntaxKind.AnyKeyword));
503
- initializer = ts.createAsExpression(initializer, this.tcb.env.referenceExternalType('@angular/core', 'TemplateRef', [DYNAMIC_TYPE]));
504
- initializer = ts.createParen(initializer);
505
- }
506
- addParseSpanInfo(initializer, this.node.sourceSpan);
507
- addParseSpanInfo(id, this.node.keySpan);
508
- this.scope.addStatement(tsCreateVariable(id, initializer));
509
- return id;
510
- }
511
- }
512
- /**
513
- * A `TcbOp` which is used when the target of a reference is missing. This operation generates a
514
- * variable of type any for usages of the invalid reference to resolve to. The invalid reference
515
- * itself is recorded out-of-band.
516
- */
517
- class TcbInvalidReferenceOp extends TcbOp {
518
- constructor(tcb, scope) {
519
- super();
520
- this.tcb = tcb;
521
- this.scope = scope;
522
- // The declaration of a missing reference is only needed when the reference is resolved.
523
- this.optional = true;
524
- }
525
- execute() {
526
- const id = this.tcb.allocateId();
527
- this.scope.addStatement(tsCreateVariable(id, NULL_AS_ANY));
528
- return id;
529
- }
530
- }
531
- /**
532
- * A `TcbOp` which constructs an instance of a directive with types inferred from its inputs. The
533
- * inputs themselves are not checked here; checking of inputs is achieved in `TcbDirectiveInputsOp`.
534
- * Any errors reported in this statement are ignored, as the type constructor call is only present
535
- * for type-inference.
536
- *
537
- * When a Directive is generic, it is required that the TCB generates the instance using this method
538
- * in order to infer the type information correctly.
539
- *
540
- * Executing this operation returns a reference to the directive instance variable with its inferred
541
- * type.
542
- */
543
- class TcbDirectiveCtorOp extends TcbOp {
544
- constructor(tcb, scope, node, dir) {
545
- super();
546
- this.tcb = tcb;
547
- this.scope = scope;
548
- this.node = node;
549
- this.dir = dir;
550
- }
551
- get optional() {
552
- // The statement generated by this operation is only used to infer the directive's type and
553
- // won't report diagnostics by itself, so the operation is marked as optional.
554
- return true;
555
- }
556
- execute() {
557
- const id = this.tcb.allocateId();
558
- addExpressionIdentifier(id, ExpressionIdentifier.DIRECTIVE);
559
- addParseSpanInfo(id, this.node.startSourceSpan || this.node.sourceSpan);
560
- const genericInputs = new Map();
561
- const inputs = getBoundInputs(this.dir, this.node, this.tcb);
562
- for (const input of inputs) {
563
- // Skip text attributes if configured to do so.
564
- if (!this.tcb.env.config.checkTypeOfAttributes &&
565
- input.attribute instanceof TmplAstTextAttribute) {
566
- continue;
567
- }
568
- for (const fieldName of input.fieldNames) {
569
- // Skip the field if an attribute has already been bound to it; we can't have a duplicate
570
- // key in the type constructor call.
571
- if (genericInputs.has(fieldName)) {
572
- continue;
573
- }
574
- const expression = translateInput(input.attribute, this.tcb, this.scope);
575
- genericInputs.set(fieldName, {
576
- type: 'binding',
577
- field: fieldName,
578
- expression,
579
- sourceSpan: input.attribute.sourceSpan
580
- });
581
- }
582
- }
583
- // Add unset directive inputs for each of the remaining unset fields.
584
- for (const [fieldName] of this.dir.inputs) {
585
- if (!genericInputs.has(fieldName)) {
586
- genericInputs.set(fieldName, { type: 'unset', field: fieldName });
587
- }
588
- }
589
- // Call the type constructor of the directive to infer a type, and assign the directive
590
- // instance.
591
- const typeCtor = tcbCallTypeCtor(this.dir, this.tcb, Array.from(genericInputs.values()));
592
- markIgnoreDiagnostics(typeCtor);
593
- this.scope.addStatement(tsCreateVariable(id, typeCtor));
594
- return id;
595
- }
596
- circularFallback() {
597
- return new TcbDirectiveCtorCircularFallbackOp(this.tcb, this.scope, this.node, this.dir);
598
- }
599
- }
600
- /**
601
- * A `TcbOp` which generates code to check input bindings on an element that correspond with the
602
- * members of a directive.
603
- *
604
- * Executing this operation returns nothing.
605
- */
606
- class TcbDirectiveInputsOp extends TcbOp {
607
- constructor(tcb, scope, node, dir) {
608
- super();
609
- this.tcb = tcb;
610
- this.scope = scope;
611
- this.node = node;
612
- this.dir = dir;
613
- }
614
- get optional() {
615
- return false;
616
- }
617
- execute() {
618
- let dirId = null;
619
- // TODO(joost): report duplicate properties
620
- const inputs = getBoundInputs(this.dir, this.node, this.tcb);
621
- for (const input of inputs) {
622
- // For bound inputs, the property is assigned the binding expression.
623
- let expr = translateInput(input.attribute, this.tcb, this.scope);
624
- if (!this.tcb.env.config.checkTypeOfInputBindings) {
625
- // If checking the type of bindings is disabled, cast the resulting expression to 'any'
626
- // before the assignment.
627
- expr = tsCastToAny(expr);
628
- }
629
- else if (!this.tcb.env.config.strictNullInputBindings) {
630
- // If strict null checks are disabled, erase `null` and `undefined` from the type by
631
- // wrapping the expression in a non-null assertion.
632
- expr = ts.createNonNullExpression(expr);
633
- }
634
- let assignment = wrapForDiagnostics(expr);
635
- for (const fieldName of input.fieldNames) {
636
- let target;
637
- if (this.dir.coercedInputFields.has(fieldName)) {
638
- // The input has a coercion declaration which should be used instead of assigning the
639
- // expression into the input field directly. To achieve this, a variable is declared
640
- // with a type of `typeof Directive.ngAcceptInputType_fieldName` which is then used as
641
- // target of the assignment.
642
- const dirTypeRef = this.tcb.env.referenceType(this.dir.ref);
643
- if (!ts.isTypeReferenceNode(dirTypeRef)) {
644
- throw new Error(`Expected TypeReferenceNode from reference to ${this.dir.ref.debugName}`);
645
- }
646
- const id = this.tcb.allocateId();
647
- const type = tsCreateTypeQueryForCoercedInput(dirTypeRef.typeName, fieldName);
648
- this.scope.addStatement(tsDeclareVariable(id, type));
649
- target = id;
650
- }
651
- else if (this.dir.undeclaredInputFields.has(fieldName)) {
652
- // If no coercion declaration is present nor is the field declared (i.e. the input is
653
- // declared in a `@Directive` or `@Component` decorator's `inputs` property) there is no
654
- // assignment target available, so this field is skipped.
655
- continue;
656
- }
657
- else if (!this.tcb.env.config.honorAccessModifiersForInputBindings &&
658
- this.dir.restrictedInputFields.has(fieldName)) {
659
- // If strict checking of access modifiers is disabled and the field is restricted
660
- // (i.e. private/protected/readonly), generate an assignment into a temporary variable
661
- // that has the type of the field. This achieves type-checking but circumvents the access
662
- // modifiers.
663
- if (dirId === null) {
664
- dirId = this.scope.resolve(this.node, this.dir);
665
- }
666
- const id = this.tcb.allocateId();
667
- const dirTypeRef = this.tcb.env.referenceType(this.dir.ref);
668
- if (!ts.isTypeReferenceNode(dirTypeRef)) {
669
- throw new Error(`Expected TypeReferenceNode from reference to ${this.dir.ref.debugName}`);
670
- }
671
- const type = ts.createIndexedAccessTypeNode(ts.createTypeQueryNode(dirId), ts.createLiteralTypeNode(ts.createStringLiteral(fieldName)));
672
- const temp = tsDeclareVariable(id, type);
673
- this.scope.addStatement(temp);
674
- target = id;
675
- }
676
- else {
677
- if (dirId === null) {
678
- dirId = this.scope.resolve(this.node, this.dir);
679
- }
680
- // To get errors assign directly to the fields on the instance, using property access
681
- // when possible. String literal fields may not be valid JS identifiers so we use
682
- // literal element access instead for those cases.
683
- target = this.dir.stringLiteralInputFields.has(fieldName) ?
684
- ts.createElementAccess(dirId, ts.createStringLiteral(fieldName)) :
685
- ts.createPropertyAccess(dirId, ts.createIdentifier(fieldName));
686
- }
687
- if (input.attribute.keySpan !== undefined) {
688
- addParseSpanInfo(target, input.attribute.keySpan);
689
- }
690
- // Finally the assignment is extended by assigning it into the target expression.
691
- assignment = ts.createBinary(target, ts.SyntaxKind.EqualsToken, assignment);
692
- }
693
- addParseSpanInfo(assignment, input.attribute.sourceSpan);
694
- // Ignore diagnostics for text attributes if configured to do so.
695
- if (!this.tcb.env.config.checkTypeOfAttributes &&
696
- input.attribute instanceof TmplAstTextAttribute) {
697
- markIgnoreDiagnostics(assignment);
698
- }
699
- this.scope.addStatement(ts.createExpressionStatement(assignment));
700
- }
701
- return null;
702
- }
703
- }
704
- /**
705
- * A `TcbOp` which is used to generate a fallback expression if the inference of a directive type
706
- * via `TcbDirectiveCtorOp` requires a reference to its own type. This can happen using a template
707
- * reference:
708
- *
709
- * ```html
710
- * <some-cmp #ref [prop]="ref.foo"></some-cmp>
711
- * ```
712
- *
713
- * In this case, `TcbDirectiveCtorCircularFallbackOp` will add a second inference of the directive
714
- * type to the type-check block, this time calling the directive's type constructor without any
715
- * input expressions. This infers the widest possible supertype for the directive, which is used to
716
- * resolve any recursive references required to infer the real type.
717
- */
718
- class TcbDirectiveCtorCircularFallbackOp extends TcbOp {
719
- constructor(tcb, scope, node, dir) {
720
- super();
721
- this.tcb = tcb;
722
- this.scope = scope;
723
- this.node = node;
724
- this.dir = dir;
725
- }
726
- get optional() {
727
- return false;
728
- }
729
- execute() {
730
- const id = this.tcb.allocateId();
731
- const typeCtor = this.tcb.env.typeCtorFor(this.dir);
732
- const circularPlaceholder = ts.createCall(typeCtor, /* typeArguments */ undefined, [ts.createNonNullExpression(ts.createNull())]);
733
- this.scope.addStatement(tsCreateVariable(id, circularPlaceholder));
734
- return id;
735
- }
736
- }
737
- /**
738
- * A `TcbOp` which feeds elements and unclaimed properties to the `DomSchemaChecker`.
739
- *
740
- * The DOM schema is not checked via TCB code generation. Instead, the `DomSchemaChecker` ingests
741
- * elements and property bindings and accumulates synthetic `ts.Diagnostic`s out-of-band. These are
742
- * later merged with the diagnostics generated from the TCB.
743
- *
744
- * For convenience, the TCB iteration of the template is used to drive the `DomSchemaChecker` via
745
- * the `TcbDomSchemaCheckerOp`.
746
- */
747
- class TcbDomSchemaCheckerOp extends TcbOp {
748
- constructor(tcb, element, checkElement, claimedInputs) {
749
- super();
750
- this.tcb = tcb;
751
- this.element = element;
752
- this.checkElement = checkElement;
753
- this.claimedInputs = claimedInputs;
754
- }
755
- get optional() {
756
- return false;
757
- }
758
- execute() {
759
- if (this.checkElement) {
760
- this.tcb.domSchemaChecker.checkElement(this.tcb.id, this.element, this.tcb.schemas);
761
- }
762
- // TODO(alxhub): this could be more efficient.
763
- for (const binding of this.element.inputs) {
764
- if (binding.type === 0 /* Property */ && this.claimedInputs.has(binding.name)) {
765
- // Skip this binding as it was claimed by a directive.
766
- continue;
767
- }
768
- if (binding.type === 0 /* Property */) {
769
- if (binding.name !== 'style' && binding.name !== 'class') {
770
- // A direct binding to a property.
771
- const propertyName = ATTR_TO_PROP[binding.name] || binding.name;
772
- this.tcb.domSchemaChecker.checkProperty(this.tcb.id, this.element, propertyName, binding.sourceSpan, this.tcb.schemas);
773
- }
774
- }
775
- }
776
- return null;
777
- }
778
- }
779
- /**
780
- * Mapping between attributes names that don't correspond to their element property names.
781
- * Note: this mapping has to be kept in sync with the equally named mapping in the runtime.
782
- */
783
- const ATTR_TO_PROP = {
784
- 'class': 'className',
785
- 'for': 'htmlFor',
786
- 'formaction': 'formAction',
787
- 'innerHtml': 'innerHTML',
788
- 'readonly': 'readOnly',
789
- 'tabindex': 'tabIndex',
790
- };
791
- /**
792
- * A `TcbOp` which generates code to check "unclaimed inputs" - bindings on an element which were
793
- * not attributed to any directive or component, and are instead processed against the HTML element
794
- * itself.
795
- *
796
- * Currently, only the expressions of these bindings are checked. The targets of the bindings are
797
- * checked against the DOM schema via a `TcbDomSchemaCheckerOp`.
798
- *
799
- * Executing this operation returns nothing.
800
- */
801
- class TcbUnclaimedInputsOp extends TcbOp {
802
- constructor(tcb, scope, element, claimedInputs) {
803
- super();
804
- this.tcb = tcb;
805
- this.scope = scope;
806
- this.element = element;
807
- this.claimedInputs = claimedInputs;
808
- }
809
- get optional() {
810
- return false;
811
- }
812
- execute() {
813
- // `this.inputs` contains only those bindings not matched by any directive. These bindings go to
814
- // the element itself.
815
- let elId = null;
816
- // TODO(alxhub): this could be more efficient.
817
- for (const binding of this.element.inputs) {
818
- if (binding.type === 0 /* Property */ && this.claimedInputs.has(binding.name)) {
819
- // Skip this binding as it was claimed by a directive.
820
- continue;
821
- }
822
- let expr = tcbExpression(binding.value, this.tcb, this.scope);
823
- if (!this.tcb.env.config.checkTypeOfInputBindings) {
824
- // If checking the type of bindings is disabled, cast the resulting expression to 'any'
825
- // before the assignment.
826
- expr = tsCastToAny(expr);
827
- }
828
- else if (!this.tcb.env.config.strictNullInputBindings) {
829
- // If strict null checks are disabled, erase `null` and `undefined` from the type by
830
- // wrapping the expression in a non-null assertion.
831
- expr = ts.createNonNullExpression(expr);
832
- }
833
- if (this.tcb.env.config.checkTypeOfDomBindings && binding.type === 0 /* Property */) {
834
- if (binding.name !== 'style' && binding.name !== 'class') {
835
- if (elId === null) {
836
- elId = this.scope.resolve(this.element);
837
- }
838
- // A direct binding to a property.
839
- const propertyName = ATTR_TO_PROP[binding.name] || binding.name;
840
- const prop = ts.createElementAccess(elId, ts.createStringLiteral(propertyName));
841
- const stmt = ts.createBinary(prop, ts.SyntaxKind.EqualsToken, wrapForDiagnostics(expr));
842
- addParseSpanInfo(stmt, binding.sourceSpan);
843
- this.scope.addStatement(ts.createExpressionStatement(stmt));
844
- }
845
- else {
846
- this.scope.addStatement(ts.createExpressionStatement(expr));
847
- }
848
- }
849
- else {
850
- // A binding to an animation, attribute, class or style. For now, only validate the right-
851
- // hand side of the expression.
852
- // TODO: properly check class and style bindings.
853
- this.scope.addStatement(ts.createExpressionStatement(expr));
854
- }
855
- }
856
- return null;
857
- }
858
- }
859
- /**
860
- * A `TcbOp` which generates code to check event bindings on an element that correspond with the
861
- * outputs of a directive.
862
- *
863
- * Executing this operation returns nothing.
864
- */
865
- export class TcbDirectiveOutputsOp extends TcbOp {
866
- constructor(tcb, scope, node, dir) {
867
- super();
868
- this.tcb = tcb;
869
- this.scope = scope;
870
- this.node = node;
871
- this.dir = dir;
872
- }
873
- get optional() {
874
- return false;
875
- }
876
- execute() {
877
- let dirId = null;
878
- const outputs = this.dir.outputs;
879
- for (const output of this.node.outputs) {
880
- if (output.type !== 0 /* Regular */ || !outputs.hasBindingPropertyName(output.name)) {
881
- continue;
882
- }
883
- // TODO(alxhub): consider supporting multiple fields with the same property name for outputs.
884
- const field = outputs.getByBindingPropertyName(output.name)[0].classPropertyName;
885
- if (dirId === null) {
886
- dirId = this.scope.resolve(this.node, this.dir);
887
- }
888
- const outputField = ts.createElementAccess(dirId, ts.createStringLiteral(field));
889
- addParseSpanInfo(outputField, output.keySpan);
890
- if (this.tcb.env.config.checkTypeOfOutputEvents) {
891
- // For strict checking of directive events, generate a call to the `subscribe` method
892
- // on the directive's output field to let type information flow into the handler function's
893
- // `$event` parameter.
894
- const handler = tcbCreateEventHandler(output, this.tcb, this.scope, 0 /* Infer */);
895
- const subscribeFn = ts.createPropertyAccess(outputField, 'subscribe');
896
- const call = ts.createCall(subscribeFn, /* typeArguments */ undefined, [handler]);
897
- addParseSpanInfo(call, output.sourceSpan);
898
- this.scope.addStatement(ts.createExpressionStatement(call));
899
- }
900
- else {
901
- // If strict checking of directive events is disabled:
902
- //
903
- // * We still generate the access to the output field as a statement in the TCB so consumers
904
- // of the `TemplateTypeChecker` can still find the node for the class member for the
905
- // output.
906
- // * Emit a handler function where the `$event` parameter has an explicit `any` type.
907
- this.scope.addStatement(ts.createExpressionStatement(outputField));
908
- const handler = tcbCreateEventHandler(output, this.tcb, this.scope, 1 /* Any */);
909
- this.scope.addStatement(ts.createExpressionStatement(handler));
910
- }
911
- ExpressionSemanticVisitor.visit(output.handler, this.tcb.id, this.tcb.boundTarget, this.tcb.oobRecorder);
912
- }
913
- return null;
914
- }
915
- }
916
- /**
917
- * A `TcbOp` which generates code to check "unclaimed outputs" - event bindings on an element which
918
- * were not attributed to any directive or component, and are instead processed against the HTML
919
- * element itself.
920
- *
921
- * Executing this operation returns nothing.
922
- */
923
- class TcbUnclaimedOutputsOp extends TcbOp {
924
- constructor(tcb, scope, element, claimedOutputs) {
925
- super();
926
- this.tcb = tcb;
927
- this.scope = scope;
928
- this.element = element;
929
- this.claimedOutputs = claimedOutputs;
930
- }
931
- get optional() {
932
- return false;
933
- }
934
- execute() {
935
- let elId = null;
936
- // TODO(alxhub): this could be more efficient.
937
- for (const output of this.element.outputs) {
938
- if (this.claimedOutputs.has(output.name)) {
939
- // Skip this event handler as it was claimed by a directive.
940
- continue;
941
- }
942
- if (output.type === 1 /* Animation */) {
943
- // Animation output bindings always have an `$event` parameter of type `AnimationEvent`.
944
- const eventType = this.tcb.env.config.checkTypeOfAnimationEvents ?
945
- this.tcb.env.referenceExternalType('@angular/animations', 'AnimationEvent') :
946
- 1 /* Any */;
947
- const handler = tcbCreateEventHandler(output, this.tcb, this.scope, eventType);
948
- this.scope.addStatement(ts.createExpressionStatement(handler));
949
- }
950
- else if (this.tcb.env.config.checkTypeOfDomEvents) {
951
- // If strict checking of DOM events is enabled, generate a call to `addEventListener` on
952
- // the element instance so that TypeScript's type inference for
953
- // `HTMLElement.addEventListener` using `HTMLElementEventMap` to infer an accurate type for
954
- // `$event` depending on the event name. For unknown event names, TypeScript resorts to the
955
- // base `Event` type.
956
- const handler = tcbCreateEventHandler(output, this.tcb, this.scope, 0 /* Infer */);
957
- if (elId === null) {
958
- elId = this.scope.resolve(this.element);
959
- }
960
- const propertyAccess = ts.createPropertyAccess(elId, 'addEventListener');
961
- addParseSpanInfo(propertyAccess, output.keySpan);
962
- const call = ts.createCall(
963
- /* expression */ propertyAccess,
964
- /* typeArguments */ undefined,
965
- /* arguments */ [ts.createStringLiteral(output.name), handler]);
966
- addParseSpanInfo(call, output.sourceSpan);
967
- this.scope.addStatement(ts.createExpressionStatement(call));
968
- }
969
- else {
970
- // If strict checking of DOM inputs is disabled, emit a handler function where the `$event`
971
- // parameter has an explicit `any` type.
972
- const handler = tcbCreateEventHandler(output, this.tcb, this.scope, 1 /* Any */);
973
- this.scope.addStatement(ts.createExpressionStatement(handler));
974
- }
975
- ExpressionSemanticVisitor.visit(output.handler, this.tcb.id, this.tcb.boundTarget, this.tcb.oobRecorder);
976
- }
977
- return null;
978
- }
979
- }
980
- /**
981
- * A `TcbOp` which generates a completion point for the component context.
982
- *
983
- * This completion point looks like `ctx. ;` in the TCB output, and does not produce diagnostics.
984
- * TypeScript autocompletion APIs can be used at this completion point (after the '.') to produce
985
- * autocompletion results of properties and methods from the template's component context.
986
- */
987
- class TcbComponentContextCompletionOp extends TcbOp {
988
- constructor(scope) {
989
- super();
990
- this.scope = scope;
991
- this.optional = false;
992
- }
993
- execute() {
994
- const ctx = ts.createIdentifier('ctx');
995
- const ctxDot = ts.createPropertyAccess(ctx, '');
996
- markIgnoreDiagnostics(ctxDot);
997
- addExpressionIdentifier(ctxDot, ExpressionIdentifier.COMPONENT_COMPLETION);
998
- this.scope.addStatement(ts.createExpressionStatement(ctxDot));
999
- return null;
1000
- }
1001
- }
1002
- /**
1003
- * Value used to break a circular reference between `TcbOp`s.
1004
- *
1005
- * This value is returned whenever `TcbOp`s have a circular dependency. The expression is a non-null
1006
- * assertion of the null value (in TypeScript, the expression `null!`). This construction will infer
1007
- * the least narrow type for whatever it's assigned to.
1008
- */
1009
- const INFER_TYPE_FOR_CIRCULAR_OP_EXPR = ts.createNonNullExpression(ts.createNull());
1010
- /**
1011
- * Overall generation context for the type check block.
1012
- *
1013
- * `Context` handles operations during code generation which are global with respect to the whole
1014
- * block. It's responsible for variable name allocation and management of any imports needed. It
1015
- * also contains the template metadata itself.
1016
- */
1017
- export class Context {
1018
- constructor(env, domSchemaChecker, oobRecorder, id, boundTarget, pipes, schemas) {
1019
- this.env = env;
1020
- this.domSchemaChecker = domSchemaChecker;
1021
- this.oobRecorder = oobRecorder;
1022
- this.id = id;
1023
- this.boundTarget = boundTarget;
1024
- this.pipes = pipes;
1025
- this.schemas = schemas;
1026
- this.nextId = 1;
1027
- }
1028
- /**
1029
- * Allocate a new variable name for use within the `Context`.
1030
- *
1031
- * Currently this uses a monotonically increasing counter, but in the future the variable name
1032
- * might change depending on the type of data being stored.
1033
- */
1034
- allocateId() {
1035
- return ts.createIdentifier(`_t${this.nextId++}`);
1036
- }
1037
- getPipeByName(name) {
1038
- if (!this.pipes.has(name)) {
1039
- return null;
1040
- }
1041
- return this.pipes.get(name);
1042
- }
1043
- }
1044
- /**
1045
- * Local scope within the type check block for a particular template.
1046
- *
1047
- * The top-level template and each nested `<ng-template>` have their own `Scope`, which exist in a
1048
- * hierarchy. The structure of this hierarchy mirrors the syntactic scopes in the generated type
1049
- * check block, where each nested template is encased in an `if` structure.
1050
- *
1051
- * As a template's `TcbOp`s are executed in a given `Scope`, statements are added via
1052
- * `addStatement()`. When this processing is complete, the `Scope` can be turned into a `ts.Block`
1053
- * via `renderToBlock()`.
1054
- *
1055
- * If a `TcbOp` requires the output of another, it can call `resolve()`.
1056
- */
1057
- class Scope {
1058
- constructor(tcb, parent = null, guard = null) {
1059
- this.tcb = tcb;
1060
- this.parent = parent;
1061
- this.guard = guard;
1062
- /**
1063
- * A queue of operations which need to be performed to generate the TCB code for this scope.
1064
- *
1065
- * This array can contain either a `TcbOp` which has yet to be executed, or a `ts.Expression|null`
1066
- * representing the memoized result of executing the operation. As operations are executed, their
1067
- * results are written into the `opQueue`, overwriting the original operation.
1068
- *
1069
- * If an operation is in the process of being executed, it is temporarily overwritten here with
1070
- * `INFER_TYPE_FOR_CIRCULAR_OP_EXPR`. This way, if a cycle is encountered where an operation
1071
- * depends transitively on its own result, the inner operation will infer the least narrow type
1072
- * that fits instead. This has the same semantics as TypeScript itself when types are referenced
1073
- * circularly.
1074
- */
1075
- this.opQueue = [];
1076
- /**
1077
- * A map of `TmplAstElement`s to the index of their `TcbElementOp` in the `opQueue`
1078
- */
1079
- this.elementOpMap = new Map();
1080
- /**
1081
- * A map of maps which tracks the index of `TcbDirectiveCtorOp`s in the `opQueue` for each
1082
- * directive on a `TmplAstElement` or `TmplAstTemplate` node.
1083
- */
1084
- this.directiveOpMap = new Map();
1085
- /**
1086
- * A map of `TmplAstReference`s to the index of their `TcbReferenceOp` in the `opQueue`
1087
- */
1088
- this.referenceOpMap = new Map();
1089
- /**
1090
- * Map of immediately nested <ng-template>s (within this `Scope`) represented by `TmplAstTemplate`
1091
- * nodes to the index of their `TcbTemplateContextOp`s in the `opQueue`.
1092
- */
1093
- this.templateCtxOpMap = new Map();
1094
- /**
1095
- * Map of variables declared on the template that created this `Scope` (represented by
1096
- * `TmplAstVariable` nodes) to the index of their `TcbVariableOp`s in the `opQueue`.
1097
- */
1098
- this.varMap = new Map();
1099
- /**
1100
- * Statements for this template.
1101
- *
1102
- * Executing the `TcbOp`s in the `opQueue` populates this array.
1103
- */
1104
- this.statements = [];
1105
- }
1106
- /**
1107
- * Constructs a `Scope` given either a `TmplAstTemplate` or a list of `TmplAstNode`s.
1108
- *
1109
- * @param tcb the overall context of TCB generation.
1110
- * @param parent the `Scope` of the parent template (if any) or `null` if this is the root
1111
- * `Scope`.
1112
- * @param templateOrNodes either a `TmplAstTemplate` representing the template for which to
1113
- * calculate the `Scope`, or a list of nodes if no outer template object is available.
1114
- * @param guard an expression that is applied to this scope for type narrowing purposes.
1115
- */
1116
- static forNodes(tcb, parent, templateOrNodes, guard) {
1117
- const scope = new Scope(tcb, parent, guard);
1118
- if (parent === null && tcb.env.config.enableTemplateTypeChecker) {
1119
- // Add an autocompletion point for the component context.
1120
- scope.opQueue.push(new TcbComponentContextCompletionOp(scope));
1121
- }
1122
- let children;
1123
- // If given an actual `TmplAstTemplate` instance, then process any additional information it
1124
- // has.
1125
- if (templateOrNodes instanceof TmplAstTemplate) {
1126
- // The template's variable declarations need to be added as `TcbVariableOp`s.
1127
- const varMap = new Map();
1128
- for (const v of templateOrNodes.variables) {
1129
- // Validate that variables on the `TmplAstTemplate` are only declared once.
1130
- if (!varMap.has(v.name)) {
1131
- varMap.set(v.name, v);
1132
- }
1133
- else {
1134
- const firstDecl = varMap.get(v.name);
1135
- tcb.oobRecorder.duplicateTemplateVar(tcb.id, v, firstDecl);
1136
- }
1137
- const opIndex = scope.opQueue.push(new TcbVariableOp(tcb, scope, templateOrNodes, v)) - 1;
1138
- scope.varMap.set(v, opIndex);
1139
- }
1140
- children = templateOrNodes.children;
1141
- }
1142
- else {
1143
- children = templateOrNodes;
1144
- }
1145
- for (const node of children) {
1146
- scope.appendNode(node);
1147
- }
1148
- return scope;
1149
- }
1150
- /**
1151
- * Look up a `ts.Expression` representing the value of some operation in the current `Scope`,
1152
- * including any parent scope(s). This method always returns a mutable clone of the
1153
- * `ts.Expression` with the comments cleared.
1154
- *
1155
- * @param node a `TmplAstNode` of the operation in question. The lookup performed will depend on
1156
- * the type of this node:
1157
- *
1158
- * Assuming `directive` is not present, then `resolve` will return:
1159
- *
1160
- * * `TmplAstElement` - retrieve the expression for the element DOM node
1161
- * * `TmplAstTemplate` - retrieve the template context variable
1162
- * * `TmplAstVariable` - retrieve a template let- variable
1163
- * * `TmplAstReference` - retrieve variable created for the local ref
1164
- *
1165
- * @param directive if present, a directive type on a `TmplAstElement` or `TmplAstTemplate` to
1166
- * look up instead of the default for an element or template node.
1167
- */
1168
- resolve(node, directive) {
1169
- // Attempt to resolve the operation locally.
1170
- const res = this.resolveLocal(node, directive);
1171
- if (res !== null) {
1172
- // We want to get a clone of the resolved expression and clear the trailing comments
1173
- // so they don't continue to appear in every place the expression is used.
1174
- // As an example, this would otherwise produce:
1175
- // var _t1 /**T:DIR*/ /*1,2*/ = _ctor1();
1176
- // _t1 /**T:DIR*/ /*1,2*/.input = 'value';
1177
- //
1178
- // In addition, returning a clone prevents the consumer of `Scope#resolve` from
1179
- // attaching comments at the declaration site.
1180
- const clone = ts.getMutableClone(res);
1181
- ts.setSyntheticTrailingComments(clone, []);
1182
- return clone;
1183
- }
1184
- else if (this.parent !== null) {
1185
- // Check with the parent.
1186
- return this.parent.resolve(node, directive);
1187
- }
1188
- else {
1189
- throw new Error(`Could not resolve ${node} / ${directive}`);
1190
- }
1191
- }
1192
- /**
1193
- * Add a statement to this scope.
1194
- */
1195
- addStatement(stmt) {
1196
- this.statements.push(stmt);
1197
- }
1198
- /**
1199
- * Get the statements.
1200
- */
1201
- render() {
1202
- for (let i = 0; i < this.opQueue.length; i++) {
1203
- // Optional statements cannot be skipped when we are generating the TCB for use
1204
- // by the TemplateTypeChecker.
1205
- const skipOptional = !this.tcb.env.config.enableTemplateTypeChecker;
1206
- this.executeOp(i, skipOptional);
1207
- }
1208
- return this.statements;
1209
- }
1210
- /**
1211
- * Returns an expression of all template guards that apply to this scope, including those of
1212
- * parent scopes. If no guards have been applied, null is returned.
1213
- */
1214
- guards() {
1215
- let parentGuards = null;
1216
- if (this.parent !== null) {
1217
- // Start with the guards from the parent scope, if present.
1218
- parentGuards = this.parent.guards();
1219
- }
1220
- if (this.guard === null) {
1221
- // This scope does not have a guard, so return the parent's guards as is.
1222
- return parentGuards;
1223
- }
1224
- else if (parentGuards === null) {
1225
- // There's no guards from the parent scope, so this scope's guard represents all available
1226
- // guards.
1227
- return this.guard;
1228
- }
1229
- else {
1230
- // Both the parent scope and this scope provide a guard, so create a combination of the two.
1231
- // It is important that the parent guard is used as left operand, given that it may provide
1232
- // narrowing that is required for this scope's guard to be valid.
1233
- return ts.createBinary(parentGuards, ts.SyntaxKind.AmpersandAmpersandToken, this.guard);
1234
- }
1235
- }
1236
- resolveLocal(ref, directive) {
1237
- if (ref instanceof TmplAstReference && this.referenceOpMap.has(ref)) {
1238
- return this.resolveOp(this.referenceOpMap.get(ref));
1239
- }
1240
- else if (ref instanceof TmplAstVariable && this.varMap.has(ref)) {
1241
- // Resolving a context variable for this template.
1242
- // Execute the `TcbVariableOp` associated with the `TmplAstVariable`.
1243
- return this.resolveOp(this.varMap.get(ref));
1244
- }
1245
- else if (ref instanceof TmplAstTemplate && directive === undefined &&
1246
- this.templateCtxOpMap.has(ref)) {
1247
- // Resolving the context of the given sub-template.
1248
- // Execute the `TcbTemplateContextOp` for the template.
1249
- return this.resolveOp(this.templateCtxOpMap.get(ref));
1250
- }
1251
- else if ((ref instanceof TmplAstElement || ref instanceof TmplAstTemplate) &&
1252
- directive !== undefined && this.directiveOpMap.has(ref)) {
1253
- // Resolving a directive on an element or sub-template.
1254
- const dirMap = this.directiveOpMap.get(ref);
1255
- if (dirMap.has(directive)) {
1256
- return this.resolveOp(dirMap.get(directive));
1257
- }
1258
- else {
1259
- return null;
1260
- }
1261
- }
1262
- else if (ref instanceof TmplAstElement && this.elementOpMap.has(ref)) {
1263
- // Resolving the DOM node of an element in this template.
1264
- return this.resolveOp(this.elementOpMap.get(ref));
1265
- }
1266
- else {
1267
- return null;
1268
- }
1269
- }
1270
- /**
1271
- * Like `executeOp`, but assert that the operation actually returned `ts.Expression`.
1272
- */
1273
- resolveOp(opIndex) {
1274
- const res = this.executeOp(opIndex, /* skipOptional */ false);
1275
- if (res === null) {
1276
- throw new Error(`Error resolving operation, got null`);
1277
- }
1278
- return res;
1279
- }
1280
- /**
1281
- * Execute a particular `TcbOp` in the `opQueue`.
1282
- *
1283
- * This method replaces the operation in the `opQueue` with the result of execution (once done)
1284
- * and also protects against a circular dependency from the operation to itself by temporarily
1285
- * setting the operation's result to a special expression.
1286
- */
1287
- executeOp(opIndex, skipOptional) {
1288
- const op = this.opQueue[opIndex];
1289
- if (!(op instanceof TcbOp)) {
1290
- return op;
1291
- }
1292
- if (skipOptional && op.optional) {
1293
- return null;
1294
- }
1295
- // Set the result of the operation in the queue to its circular fallback. If executing this
1296
- // operation results in a circular dependency, this will prevent an infinite loop and allow for
1297
- // the resolution of such cycles.
1298
- this.opQueue[opIndex] = op.circularFallback();
1299
- const res = op.execute();
1300
- // Once the operation has finished executing, it's safe to cache the real result.
1301
- this.opQueue[opIndex] = res;
1302
- return res;
1303
- }
1304
- appendNode(node) {
1305
- if (node instanceof TmplAstElement) {
1306
- const opIndex = this.opQueue.push(new TcbElementOp(this.tcb, this, node)) - 1;
1307
- this.elementOpMap.set(node, opIndex);
1308
- this.appendDirectivesAndInputsOfNode(node);
1309
- this.appendOutputsOfNode(node);
1310
- for (const child of node.children) {
1311
- this.appendNode(child);
1312
- }
1313
- this.checkAndAppendReferencesOfNode(node);
1314
- }
1315
- else if (node instanceof TmplAstTemplate) {
1316
- // Template children are rendered in a child scope.
1317
- this.appendDirectivesAndInputsOfNode(node);
1318
- this.appendOutputsOfNode(node);
1319
- const ctxIndex = this.opQueue.push(new TcbTemplateContextOp(this.tcb, this)) - 1;
1320
- this.templateCtxOpMap.set(node, ctxIndex);
1321
- if (this.tcb.env.config.checkTemplateBodies) {
1322
- this.opQueue.push(new TcbTemplateBodyOp(this.tcb, this, node));
1323
- }
1324
- else if (this.tcb.env.config.alwaysCheckSchemaInTemplateBodies) {
1325
- this.appendDeepSchemaChecks(node.children);
1326
- }
1327
- this.checkAndAppendReferencesOfNode(node);
1328
- }
1329
- else if (node instanceof TmplAstBoundText) {
1330
- this.opQueue.push(new TcbTextInterpolationOp(this.tcb, this, node));
1331
- }
1332
- else if (node instanceof TmplAstIcu) {
1333
- this.appendIcuExpressions(node);
1334
- }
1335
- }
1336
- checkAndAppendReferencesOfNode(node) {
1337
- for (const ref of node.references) {
1338
- const target = this.tcb.boundTarget.getReferenceTarget(ref);
1339
- let ctxIndex;
1340
- if (target === null) {
1341
- // The reference is invalid if it doesn't have a target, so report it as an error.
1342
- this.tcb.oobRecorder.missingReferenceTarget(this.tcb.id, ref);
1343
- // Any usages of the invalid reference will be resolved to a variable of type any.
1344
- ctxIndex = this.opQueue.push(new TcbInvalidReferenceOp(this.tcb, this)) - 1;
1345
- }
1346
- else if (target instanceof TmplAstTemplate || target instanceof TmplAstElement) {
1347
- ctxIndex = this.opQueue.push(new TcbReferenceOp(this.tcb, this, ref, node, target)) - 1;
1348
- }
1349
- else {
1350
- ctxIndex =
1351
- this.opQueue.push(new TcbReferenceOp(this.tcb, this, ref, node, target.directive)) - 1;
1352
- }
1353
- this.referenceOpMap.set(ref, ctxIndex);
1354
- }
1355
- }
1356
- appendDirectivesAndInputsOfNode(node) {
1357
- // Collect all the inputs on the element.
1358
- const claimedInputs = new Set();
1359
- const directives = this.tcb.boundTarget.getDirectivesOfNode(node);
1360
- if (directives === null || directives.length === 0) {
1361
- // If there are no directives, then all inputs are unclaimed inputs, so queue an operation
1362
- // to add them if needed.
1363
- if (node instanceof TmplAstElement) {
1364
- this.opQueue.push(new TcbUnclaimedInputsOp(this.tcb, this, node, claimedInputs));
1365
- this.opQueue.push(new TcbDomSchemaCheckerOp(this.tcb, node, /* checkElement */ true, claimedInputs));
1366
- }
1367
- return;
1368
- }
1369
- const dirMap = new Map();
1370
- for (const dir of directives) {
1371
- let directiveOp;
1372
- const host = this.tcb.env.reflector;
1373
- const dirRef = dir.ref;
1374
- if (!dir.isGeneric) {
1375
- // The most common case is that when a directive is not generic, we use the normal
1376
- // `TcbNonDirectiveTypeOp`.
1377
- directiveOp = new TcbNonGenericDirectiveTypeOp(this.tcb, this, node, dir);
1378
- }
1379
- else if (!requiresInlineTypeCtor(dirRef.node, host) ||
1380
- this.tcb.env.config.useInlineTypeConstructors) {
1381
- // For generic directives, we use a type constructor to infer types. If a directive requires
1382
- // an inline type constructor, then inlining must be available to use the
1383
- // `TcbDirectiveCtorOp`. If not we, we fallback to using `any` – see below.
1384
- directiveOp = new TcbDirectiveCtorOp(this.tcb, this, node, dir);
1385
- }
1386
- else {
1387
- // If inlining is not available, then we give up on infering the generic params, and use
1388
- // `any` type for the directive's generic parameters.
1389
- directiveOp = new TcbGenericDirectiveTypeWithAnyParamsOp(this.tcb, this, node, dir);
1390
- }
1391
- const dirIndex = this.opQueue.push(directiveOp) - 1;
1392
- dirMap.set(dir, dirIndex);
1393
- this.opQueue.push(new TcbDirectiveInputsOp(this.tcb, this, node, dir));
1394
- }
1395
- this.directiveOpMap.set(node, dirMap);
1396
- // After expanding the directives, we might need to queue an operation to check any unclaimed
1397
- // inputs.
1398
- if (node instanceof TmplAstElement) {
1399
- // Go through the directives and remove any inputs that it claims from `elementInputs`.
1400
- for (const dir of directives) {
1401
- for (const propertyName of dir.inputs.propertyNames) {
1402
- claimedInputs.add(propertyName);
1403
- }
1404
- }
1405
- this.opQueue.push(new TcbUnclaimedInputsOp(this.tcb, this, node, claimedInputs));
1406
- // If there are no directives which match this element, then it's a "plain" DOM element (or a
1407
- // web component), and should be checked against the DOM schema. If any directives match,
1408
- // we must assume that the element could be custom (either a component, or a directive like
1409
- // <router-outlet>) and shouldn't validate the element name itself.
1410
- const checkElement = directives.length === 0;
1411
- this.opQueue.push(new TcbDomSchemaCheckerOp(this.tcb, node, checkElement, claimedInputs));
1412
- }
1413
- }
1414
- appendOutputsOfNode(node) {
1415
- // Collect all the outputs on the element.
1416
- const claimedOutputs = new Set();
1417
- const directives = this.tcb.boundTarget.getDirectivesOfNode(node);
1418
- if (directives === null || directives.length === 0) {
1419
- // If there are no directives, then all outputs are unclaimed outputs, so queue an operation
1420
- // to add them if needed.
1421
- if (node instanceof TmplAstElement) {
1422
- this.opQueue.push(new TcbUnclaimedOutputsOp(this.tcb, this, node, claimedOutputs));
1423
- }
1424
- return;
1425
- }
1426
- // Queue operations for all directives to check the relevant outputs for a directive.
1427
- for (const dir of directives) {
1428
- this.opQueue.push(new TcbDirectiveOutputsOp(this.tcb, this, node, dir));
1429
- }
1430
- // After expanding the directives, we might need to queue an operation to check any unclaimed
1431
- // outputs.
1432
- if (node instanceof TmplAstElement) {
1433
- // Go through the directives and register any outputs that it claims in `claimedOutputs`.
1434
- for (const dir of directives) {
1435
- for (const outputProperty of dir.outputs.propertyNames) {
1436
- claimedOutputs.add(outputProperty);
1437
- }
1438
- }
1439
- this.opQueue.push(new TcbUnclaimedOutputsOp(this.tcb, this, node, claimedOutputs));
1440
- }
1441
- }
1442
- appendDeepSchemaChecks(nodes) {
1443
- for (const node of nodes) {
1444
- if (!(node instanceof TmplAstElement || node instanceof TmplAstTemplate)) {
1445
- continue;
1446
- }
1447
- if (node instanceof TmplAstElement) {
1448
- const claimedInputs = new Set();
1449
- const directives = this.tcb.boundTarget.getDirectivesOfNode(node);
1450
- let hasDirectives;
1451
- if (directives === null || directives.length === 0) {
1452
- hasDirectives = false;
1453
- }
1454
- else {
1455
- hasDirectives = true;
1456
- for (const dir of directives) {
1457
- for (const propertyName of dir.inputs.propertyNames) {
1458
- claimedInputs.add(propertyName);
1459
- }
1460
- }
1461
- }
1462
- this.opQueue.push(new TcbDomSchemaCheckerOp(this.tcb, node, !hasDirectives, claimedInputs));
1463
- }
1464
- this.appendDeepSchemaChecks(node.children);
1465
- }
1466
- }
1467
- appendIcuExpressions(node) {
1468
- for (const variable of Object.values(node.vars)) {
1469
- this.opQueue.push(new TcbTextInterpolationOp(this.tcb, this, variable));
1470
- }
1471
- for (const placeholder of Object.values(node.placeholders)) {
1472
- if (placeholder instanceof TmplAstBoundText) {
1473
- this.opQueue.push(new TcbTextInterpolationOp(this.tcb, this, placeholder));
1474
- }
1475
- }
1476
- }
1477
- }
1478
- /**
1479
- * Create the `ctx` parameter to the top-level TCB function, with the given generic type arguments.
1480
- */
1481
- function tcbCtxParam(node, name, typeArguments) {
1482
- const type = ts.factory.createTypeReferenceNode(name, typeArguments);
1483
- return ts.factory.createParameterDeclaration(
1484
- /* decorators */ undefined,
1485
- /* modifiers */ undefined,
1486
- /* dotDotDotToken */ undefined,
1487
- /* name */ 'ctx',
1488
- /* questionToken */ undefined,
1489
- /* type */ type,
1490
- /* initializer */ undefined);
1491
- }
1492
- /**
1493
- * Process an `AST` expression and convert it into a `ts.Expression`, generating references to the
1494
- * correct identifiers in the current scope.
1495
- */
1496
- function tcbExpression(ast, tcb, scope) {
1497
- const translator = new TcbExpressionTranslator(tcb, scope);
1498
- return translator.translate(ast);
1499
- }
1500
- class TcbExpressionTranslator {
1501
- constructor(tcb, scope) {
1502
- this.tcb = tcb;
1503
- this.scope = scope;
1504
- }
1505
- translate(ast) {
1506
- // `astToTypescript` actually does the conversion. A special resolver `tcbResolve` is passed
1507
- // which interprets specific expression nodes that interact with the `ImplicitReceiver`. These
1508
- // nodes actually refer to identifiers within the current scope.
1509
- return astToTypescript(ast, ast => this.resolve(ast), this.tcb.env.config);
1510
- }
1511
- /**
1512
- * Resolve an `AST` expression within the given scope.
1513
- *
1514
- * Some `AST` expressions refer to top-level concepts (references, variables, the component
1515
- * context). This method assists in resolving those.
1516
- */
1517
- resolve(ast) {
1518
- if (ast instanceof PropertyRead && ast.receiver instanceof ImplicitReceiver) {
1519
- // Try to resolve a bound target for this expression. If no such target is available, then
1520
- // the expression is referencing the top-level component context. In that case, `null` is
1521
- // returned here to let it fall through resolution so it will be caught when the
1522
- // `ImplicitReceiver` is resolved in the branch below.
1523
- return this.resolveTarget(ast);
1524
- }
1525
- else if (ast instanceof PropertyWrite && ast.receiver instanceof ImplicitReceiver) {
1526
- const target = this.resolveTarget(ast);
1527
- if (target === null) {
1528
- return null;
1529
- }
1530
- const expr = this.translate(ast.value);
1531
- const result = ts.createParen(ts.createBinary(target, ts.SyntaxKind.EqualsToken, expr));
1532
- addParseSpanInfo(result, ast.sourceSpan);
1533
- return result;
1534
- }
1535
- else if (ast instanceof ImplicitReceiver) {
1536
- // AST instances representing variables and references look very similar to property reads
1537
- // or method calls from the component context: both have the shape
1538
- // PropertyRead(ImplicitReceiver, 'propName') or MethodCall(ImplicitReceiver, 'methodName').
1539
- //
1540
- // `translate` will first try to `resolve` the outer PropertyRead/MethodCall. If this works,
1541
- // it's because the `BoundTarget` found an expression target for the whole expression, and
1542
- // therefore `translate` will never attempt to `resolve` the ImplicitReceiver of that
1543
- // PropertyRead/MethodCall.
1544
- //
1545
- // Therefore if `resolve` is called on an `ImplicitReceiver`, it's because no outer
1546
- // PropertyRead/MethodCall resolved to a variable or reference, and therefore this is a
1547
- // property read or method call on the component context itself.
1548
- return ts.createIdentifier('ctx');
1549
- }
1550
- else if (ast instanceof BindingPipe) {
1551
- const expr = this.translate(ast.exp);
1552
- const pipeRef = this.tcb.getPipeByName(ast.name);
1553
- let pipe;
1554
- if (pipeRef === null) {
1555
- // No pipe by that name exists in scope. Record this as an error.
1556
- this.tcb.oobRecorder.missingPipe(this.tcb.id, ast);
1557
- // Use an 'any' value to at least allow the rest of the expression to be checked.
1558
- pipe = NULL_AS_ANY;
1559
- }
1560
- else {
1561
- // Use a variable declared as the pipe's type.
1562
- pipe = this.tcb.env.pipeInst(pipeRef);
1563
- }
1564
- const args = ast.args.map(arg => this.translate(arg));
1565
- let methodAccess = ts.factory.createPropertyAccessExpression(pipe, 'transform');
1566
- addParseSpanInfo(methodAccess, ast.nameSpan);
1567
- if (!this.tcb.env.config.checkTypeOfPipes) {
1568
- methodAccess = ts.factory.createAsExpression(methodAccess, ts.factory.createKeywordTypeNode(ts.SyntaxKind.AnyKeyword));
1569
- }
1570
- const result = ts.createCall(
1571
- /* expression */ methodAccess,
1572
- /* typeArguments */ undefined,
1573
- /* argumentsArray */ [expr, ...args]);
1574
- addParseSpanInfo(result, ast.sourceSpan);
1575
- return result;
1576
- }
1577
- else if (ast instanceof MethodCall && ast.receiver instanceof ImplicitReceiver &&
1578
- !(ast.receiver instanceof ThisReceiver)) {
1579
- // Resolve the special `$any(expr)` syntax to insert a cast of the argument to type `any`.
1580
- // `$any(expr)` -> `expr as any`
1581
- if (ast.name === '$any' && ast.args.length === 1) {
1582
- const expr = this.translate(ast.args[0]);
1583
- const exprAsAny = ts.createAsExpression(expr, ts.createKeywordTypeNode(ts.SyntaxKind.AnyKeyword));
1584
- const result = ts.createParen(exprAsAny);
1585
- addParseSpanInfo(result, ast.sourceSpan);
1586
- return result;
1587
- }
1588
- // Attempt to resolve a bound target for the method, and generate the method call if a target
1589
- // could be resolved. If no target is available, then the method is referencing the top-level
1590
- // component context, in which case `null` is returned to let the `ImplicitReceiver` being
1591
- // resolved to the component context.
1592
- const receiver = this.resolveTarget(ast);
1593
- if (receiver === null) {
1594
- return null;
1595
- }
1596
- const method = wrapForDiagnostics(receiver);
1597
- addParseSpanInfo(method, ast.nameSpan);
1598
- const args = ast.args.map(arg => this.translate(arg));
1599
- const node = ts.createCall(method, undefined, args);
1600
- addParseSpanInfo(node, ast.sourceSpan);
1601
- return node;
1602
- }
1603
- else {
1604
- // This AST isn't special after all.
1605
- return null;
1606
- }
1607
- }
1608
- /**
1609
- * Attempts to resolve a bound target for a given expression, and translates it into the
1610
- * appropriate `ts.Expression` that represents the bound target. If no target is available,
1611
- * `null` is returned.
1612
- */
1613
- resolveTarget(ast) {
1614
- const binding = this.tcb.boundTarget.getExpressionTarget(ast);
1615
- if (binding === null) {
1616
- return null;
1617
- }
1618
- const expr = this.scope.resolve(binding);
1619
- addParseSpanInfo(expr, ast.sourceSpan);
1620
- return expr;
1621
- }
1622
- }
1623
- /**
1624
- * Call the type constructor of a directive instance on a given template node, inferring a type for
1625
- * the directive instance from any bound inputs.
1626
- */
1627
- function tcbCallTypeCtor(dir, tcb, inputs) {
1628
- const typeCtor = tcb.env.typeCtorFor(dir);
1629
- // Construct an array of `ts.PropertyAssignment`s for each of the directive's inputs.
1630
- const members = inputs.map(input => {
1631
- const propertyName = ts.createStringLiteral(input.field);
1632
- if (input.type === 'binding') {
1633
- // For bound inputs, the property is assigned the binding expression.
1634
- let expr = input.expression;
1635
- if (!tcb.env.config.checkTypeOfInputBindings) {
1636
- // If checking the type of bindings is disabled, cast the resulting expression to 'any'
1637
- // before the assignment.
1638
- expr = tsCastToAny(expr);
1639
- }
1640
- else if (!tcb.env.config.strictNullInputBindings) {
1641
- // If strict null checks are disabled, erase `null` and `undefined` from the type by
1642
- // wrapping the expression in a non-null assertion.
1643
- expr = ts.createNonNullExpression(expr);
1644
- }
1645
- const assignment = ts.createPropertyAssignment(propertyName, wrapForDiagnostics(expr));
1646
- addParseSpanInfo(assignment, input.sourceSpan);
1647
- return assignment;
1648
- }
1649
- else {
1650
- // A type constructor is required to be called with all input properties, so any unset
1651
- // inputs are simply assigned a value of type `any` to ignore them.
1652
- return ts.createPropertyAssignment(propertyName, NULL_AS_ANY);
1653
- }
1654
- });
1655
- // Call the `ngTypeCtor` method on the directive class, with an object literal argument created
1656
- // from the matched inputs.
1657
- return ts.createCall(
1658
- /* expression */ typeCtor,
1659
- /* typeArguments */ undefined,
1660
- /* argumentsArray */ [ts.createObjectLiteral(members)]);
1661
- }
1662
- function getBoundInputs(directive, node, tcb) {
1663
- const boundInputs = [];
1664
- const processAttribute = (attr) => {
1665
- // Skip non-property bindings.
1666
- if (attr instanceof TmplAstBoundAttribute && attr.type !== 0 /* Property */) {
1667
- return;
1668
- }
1669
- // Skip the attribute if the directive does not have an input for it.
1670
- const inputs = directive.inputs.getByBindingPropertyName(attr.name);
1671
- if (inputs === null) {
1672
- return;
1673
- }
1674
- const fieldNames = inputs.map(input => input.classPropertyName);
1675
- boundInputs.push({ attribute: attr, fieldNames });
1676
- };
1677
- node.inputs.forEach(processAttribute);
1678
- node.attributes.forEach(processAttribute);
1679
- if (node instanceof TmplAstTemplate) {
1680
- node.templateAttrs.forEach(processAttribute);
1681
- }
1682
- return boundInputs;
1683
- }
1684
- /**
1685
- * Translates the given attribute binding to a `ts.Expression`.
1686
- */
1687
- function translateInput(attr, tcb, scope) {
1688
- if (attr instanceof TmplAstBoundAttribute) {
1689
- // Produce an expression representing the value of the binding.
1690
- return tcbExpression(attr.value, tcb, scope);
1691
- }
1692
- else {
1693
- // For regular attributes with a static string value, use the represented string literal.
1694
- return ts.createStringLiteral(attr.value);
1695
- }
1696
- }
1697
- const EVENT_PARAMETER = '$event';
1698
- /**
1699
- * Creates an arrow function to be used as handler function for event bindings. The handler
1700
- * function has a single parameter `$event` and the bound event's handler `AST` represented as a
1701
- * TypeScript expression as its body.
1702
- *
1703
- * When `eventType` is set to `Infer`, the `$event` parameter will not have an explicit type. This
1704
- * allows for the created handler function to have its `$event` parameter's type inferred based on
1705
- * how it's used, to enable strict type checking of event bindings. When set to `Any`, the `$event`
1706
- * parameter will have an explicit `any` type, effectively disabling strict type checking of event
1707
- * bindings. Alternatively, an explicit type can be passed for the `$event` parameter.
1708
- */
1709
- function tcbCreateEventHandler(event, tcb, scope, eventType) {
1710
- const handler = tcbEventHandlerExpression(event.handler, tcb, scope);
1711
- let eventParamType;
1712
- if (eventType === 0 /* Infer */) {
1713
- eventParamType = undefined;
1714
- }
1715
- else if (eventType === 1 /* Any */) {
1716
- eventParamType = ts.createKeywordTypeNode(ts.SyntaxKind.AnyKeyword);
1717
- }
1718
- else {
1719
- eventParamType = eventType;
1720
- }
1721
- // Obtain all guards that have been applied to the scope and its parents, as they have to be
1722
- // repeated within the handler function for their narrowing to be in effect within the handler.
1723
- const guards = scope.guards();
1724
- let body = ts.createExpressionStatement(handler);
1725
- if (guards !== null) {
1726
- // Wrap the body in an `if` statement containing all guards that have to be applied.
1727
- body = ts.createIf(guards, body);
1728
- }
1729
- const eventParam = ts.createParameter(
1730
- /* decorators */ undefined,
1731
- /* modifiers */ undefined,
1732
- /* dotDotDotToken */ undefined,
1733
- /* name */ EVENT_PARAMETER,
1734
- /* questionToken */ undefined,
1735
- /* type */ eventParamType);
1736
- addExpressionIdentifier(eventParam, ExpressionIdentifier.EVENT_PARAMETER);
1737
- return ts.createFunctionExpression(
1738
- /* modifier */ undefined,
1739
- /* asteriskToken */ undefined,
1740
- /* name */ undefined,
1741
- /* typeParameters */ undefined,
1742
- /* parameters */ [eventParam],
1743
- /* type */ ts.createKeywordTypeNode(ts.SyntaxKind.AnyKeyword),
1744
- /* body */ ts.createBlock([body]));
1745
- }
1746
- /**
1747
- * Similar to `tcbExpression`, this function converts the provided `AST` expression into a
1748
- * `ts.Expression`, with special handling of the `$event` variable that can be used within event
1749
- * bindings.
1750
- */
1751
- function tcbEventHandlerExpression(ast, tcb, scope) {
1752
- const translator = new TcbEventHandlerTranslator(tcb, scope);
1753
- return translator.translate(ast);
1754
- }
1755
- class TcbEventHandlerTranslator extends TcbExpressionTranslator {
1756
- resolve(ast) {
1757
- // Recognize a property read on the implicit receiver corresponding with the event parameter
1758
- // that is available in event bindings. Since this variable is a parameter of the handler
1759
- // function that the converted expression becomes a child of, just create a reference to the
1760
- // parameter by its name.
1761
- if (ast instanceof PropertyRead && ast.receiver instanceof ImplicitReceiver &&
1762
- !(ast.receiver instanceof ThisReceiver) && ast.name === EVENT_PARAMETER) {
1763
- const event = ts.createIdentifier(EVENT_PARAMETER);
1764
- addParseSpanInfo(event, ast.nameSpan);
1765
- return event;
1766
- }
1767
- return super.resolve(ast);
1768
- }
1769
- }
1770
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidHlwZV9jaGVja19ibG9jay5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uLy4uLy4uLy4uLy4uL3BhY2thZ2VzL2NvbXBpbGVyLWNsaS9zcmMvbmd0c2MvdHlwZWNoZWNrL3NyYy90eXBlX2NoZWNrX2Jsb2NrLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBOzs7Ozs7R0FNRztBQUVILE9BQU8sRUFBTSxXQUFXLEVBQTRCLFlBQVksRUFBRSxnQkFBZ0IsRUFBRSxVQUFVLEVBQW9DLFlBQVksRUFBRSxhQUFhLEVBQWtCLFlBQVksRUFBRSxxQkFBcUIsRUFBcUIsZ0JBQWdCLEVBQUUsY0FBYyxFQUFFLFVBQVUsRUFBZSxnQkFBZ0IsRUFBRSxlQUFlLEVBQUUsb0JBQW9CLEVBQUUsZUFBZSxFQUFDLE1BQU0sbUJBQW1CLENBQUM7QUFDclksT0FBTyxLQUFLLEVBQUUsTUFBTSxZQUFZLENBQUM7QUFPakMsT0FBTyxFQUFDLHVCQUF1QixFQUFFLG9CQUFvQixFQUFFLHFCQUFxQixFQUFDLE1BQU0sWUFBWSxDQUFDO0FBQ2hHLE9BQU8sRUFBQyxnQkFBZ0IsRUFBRSxhQUFhLEVBQUUsa0JBQWtCLEVBQUUsa0JBQWtCLEVBQUMsTUFBTSxlQUFlLENBQUM7QUFHdEcsT0FBTyxFQUFDLGVBQWUsRUFBRSxXQUFXLEVBQUMsTUFBTSxjQUFjLENBQUM7QUFFMUQsT0FBTyxFQUFDLHlCQUF5QixFQUFDLE1BQU0sc0JBQXNCLENBQUM7QUFDL0QsT0FBTyxFQUFDLFlBQVksRUFBRSxXQUFXLEVBQUUsZUFBZSxFQUFFLGdDQUFnQyxFQUFFLGdCQUFnQixFQUFFLGlCQUFpQixFQUFDLE1BQU0sV0FBVyxDQUFDO0FBQzVJLE9BQU8sRUFBQyxzQkFBc0IsRUFBQyxNQUFNLG9CQUFvQixDQUFDO0FBQzFELE9BQU8sRUFBQyxvQkFBb0IsRUFBQyxNQUFNLDBCQUEwQixDQUFDO0FBRTlEOztHQUVHO0FBQ0gsTUFBTSxDQUFOLElBQVkseUJBdUJY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OlsiLyoqXG4gKiBAbGljZW5zZVxuICogQ29weXJpZ2h0IEdvb2dsZSBMTEMgQWxsIFJpZ2h0cyBSZXNlcnZlZC5cbiAqXG4gKiBVc2Ugb2YgdGhpcyBzb3VyY2UgY29kZSBpcyBnb3Zlcm5lZCBieSBhbiBNSVQtc3R5bGUgbGljZW5zZSB0aGF0IGNhbiBiZVxuICogZm91bmQgaW4gdGhlIExJQ0VOU0UgZmlsZSBhdCBodHRwczovL2FuZ3VsYXIuaW8vbGljZW5zZVxuICovXG5cbmltcG9ydCB7QVNULCBCaW5kaW5nUGlwZSwgQmluZGluZ1R5cGUsIEJvdW5kVGFyZ2V0LCBEWU5BTUlDX1RZUEUsIEltcGxpY2l0UmVjZWl2ZXIsIE1ldGhvZENhbGwsIFBhcnNlZEV2ZW50VHlwZSwgUGFyc2VTb3VyY2VTcGFuLCBQcm9wZXJ0eVJlYWQsIFByb3BlcnR5V3JpdGUsIFNjaGVtYU1ldGFkYXRhLCBUaGlzUmVjZWl2ZXIsIFRtcGxBc3RCb3VuZEF0dHJpYnV0ZSwgVG1wbEFzdEJvdW5kRXZlbnQsIFRtcGxBc3RCb3VuZFRleHQsIFRtcGxBc3RFbGVtZW50LCBUbXBsQXN0SWN1LCBUbXBsQXN0Tm9kZSwgVG1wbEFzdFJlZmVyZW5jZSwgVG1wbEFzdFRlbXBsYXRlLCBUbXBsQXN0VGV4dEF0dHJpYnV0ZSwgVG1wbEFzdFZhcmlhYmxlfSBmcm9tICdAYW5ndWxhci9jb21waWxlcic7XG5pbXBvcnQgKiBhcyB0cyBmcm9tICd0eXBlc2NyaXB0JztcblxuaW1wb3J0IHtSZWZlcmVuY2V9IGZyb20gJy4uLy4uL2ltcG9ydHMnO1xuaW1wb3J0IHtDbGFzc1Byb3BlcnR5TmFtZX0gZnJvbSAnLi4vLi4vbWV0YWRhdGEnO1xuaW1wb3J0IHtDbGFzc0RlY2xhcmF0aW9uLCBSZWZsZWN0aW9uSG9zdH0gZnJvbSAnLi4vLi4vcmVmbGVjdGlvbic7XG5pbXBvcnQge1RlbXBsYXRlSWQsIFR5cGVDaGVja2FibGVEaXJlY3RpdmVNZXRhLCBUeXBlQ2hlY2tCbG9ja01ldGFkYXRhfSBmcm9tICcuLi9hcGknO1xuXG5pbXBvcnQge2FkZEV4cHJlc3Npb25JZGVudGlmaWVyLCBFeHByZXNzaW9uSWRlbnRpZmllciwgbWFya0lnbm9yZURpYWdub3N0aWNzfSBmcm9tICcuL2NvbW1lbnRzJztcbmltcG9ydCB7YWRkUGFyc2VTcGFuSW5mbywgYWRkVGVtcGxhdGVJZCwgd3JhcEZvckRpYWdub3N0aWNzLCB3cmFwRm9yVHlwZUNoZWNrZXJ9IGZyb20gJy4vZGlhZ25vc3RpY3MnO1xuaW1wb3J0IHtEb21TY2hlbWFDaGVja2VyfSBmcm9tICcuL2RvbSc7XG5pbXBvcnQge0Vudmlyb25tZW50fSBmcm9tICcuL2Vudmlyb25tZW50JztcbmltcG9ydCB7YXN0VG9UeXBlc2NyaXB0LCBOVUxMX0FTX0FOWX0gZnJvbSAnLi9leHByZXNzaW9uJztcbmltcG9ydCB7T3V0T2ZCYW5kRGlhZ25vc3RpY1JlY29yZGVyfSBmcm9tICcuL29vYic7XG5pbXBvcnQge0V4cHJlc3Npb25TZW1hbnRpY1Zpc2l0b3J9IGZyb20gJy4vdGVtcGxhdGVfc2VtYW50aWNzJztcbmltcG9ydCB7dHNDYWxsTWV0aG9kLCB0c0Nhc3RUb0FueSwgdHNDcmVhdGVFbGVtZW50LCB0c0NyZWF0ZVR5cGVRdWVyeUZvckNvZXJjZWRJbnB1dCwgdHNDcmVhdGVWYXJpYWJsZSwgdHNEZWNsYXJlVmFyaWFibGV9IGZyb20gJy4vdHNfdXRpbCc7XG5pbXBvcnQge3JlcXVpcmVzSW5saW5lVHlwZUN0b3J9IGZyb20gJy4vdHlwZV9jb25zdHJ1Y3Rvcic7XG5pbXBvcnQge1R5cGVQYXJhbWV0ZXJFbWl0dGVyfSBmcm9tICcuL3R5cGVfcGFyYW1ldGVyX2VtaXR0ZXInO1xuXG4vKipcbiAqIENvbnRyb2xzIGhvdyBnZW5lcmljcyBmb3IgdGhlIGNvbXBvbmVudCBjb250ZXh0IGNsYXNzIHdpbGwgYmUgaGFuZGxlZCBkdXJpbmcgVENCIGdlbmVyYXRpb24uXG4gKi9cbmV4cG9ydCBlbnVtIFRjYkdlbmVyaWNDb250ZXh0QmVoYXZpb3Ige1xuICAvKipcbiAgICogUmVmZXJlbmNlcyB0byBnZW5lcmljIHBhcmFtZXRlciBib3VuZHMgd2lsbCBiZSBlbWl0dGVkIHZpYSB0aGUgYFR5cGVQYXJhbWV0ZXJFbWl0dGVyYC5cbiAgICpcbiAgICogVGhlIGNhbGxlciBtdXN0IHZlcmlmeSB0aGF0IGFsbCBwYXJhbWV0ZXIgYm91bmRzIGFyZSBlbWl0dGFibGUgaW4gb3JkZXIgdG8gdXNlIHRoaXMgbW9kZS5cbiAgICovXG4gIFVzZUVtaXR0ZXIsXG5cbiAgLyoqXG4gICAqIEdlbmVyaWMgcGFyYW1ldGVyIGRlY2xhcmF0aW9ucyB3aWxsIGJlIGNvcGllZCBkaXJlY3RseSBmcm9tIHRoZSBgdHMuQ2xhc3NEZWNsYXJhdGlvbmAgb2YgdGhlXG4gICAqIGNvbXBvbmVudCBjbGFzcy5cbiAgICpcbiAgICogVGhlIGNhbGxlciBtdXN0IG9ubHkgdXNlIHRoZSBnZW5lcmF0ZWQgVENCIGNvZGUgaW4gYSBjb250ZXh0IHdoZXJlIHN1Y2ggY29waWVzIHdpbGwgc3RpbGwgYmVcbiAgICogdmFsaWQsIHN1Y2ggYXMgYW4gaW5saW5lIHR5cGUgY2hlY2sgYmxvY2suXG4gICAqL1xuICBDb3B5Q2xhc3NOb2RlcyxcblxuICAvKipcbiAgICogQW55IGdlbmVyaWMgcGFyYW1ldGVycyBmb3IgdGhlIGNvbXBvbmVudCBjb250ZXh0IGNsYXNzIHdpbGwgYmUgc2V0IHRvIGBhbnlgLlxuICAgKlxuICAgKiBQcm9kdWNlcyBhIGxlc3MgdXNlZnVsIHR5cGUsIGJ1dCBpcyBhbHdheXMgc2FmZSB0byB1c2UuXG4gICAqL1xuICBGYWxsYmFja1RvQW55LFxufVxuXG4vKipcbiAqIEdpdmVuIGEgYHRzLkNsYXNzRGVjbGFyYXRpb25gIGZvciBhIGNvbXBvbmVudCwgYW5kIG1ldGFkYXRhIHJlZ2FyZGluZyB0aGF0IGNvbXBvbmVudCwgY29tcG9zZSBhXG4gKiBcInR5cGUgY2hlY2sgYmxvY2tcIiBmdW5jdGlvbi5cbiAqXG4gKiBXaGVuIHBhc3NlZCB0aHJvdWdoIFR5cGVTY3JpcHQncyBUeXBlQ2hlY2tlciwgdHlwZSBlcnJvcnMgdGhhdCBhcmlzZSB3aXRoaW4gdGhlIHR5cGUgY2hlY2sgYmxvY2tcbiAqIGZ1bmN0aW9uIGluZGljYXRlIGlzc3VlcyBpbiB0aGUgdGVtcGxhdGUgaXRzZWxmLlxuICpcbiAqIEFzIGEgc2lkZSBlZmZlY3Qgb2YgZ2VuZXJhdGluZyBhIFRDQiBmb3IgdGhlIGNvbXBvbmVudCwgYHRzLkRpYWdub3N0aWNgcyBtYXkgYWxzbyBiZSBwcm9kdWNlZFxuICogZGlyZWN0bHkgZm9yIGlzc3VlcyB3aXRoaW4gdGhlIHRlbXBsYXRlIHdoaWNoIGFyZSBpZGVudGlmaWVkIGR1cmluZyBnZW5lcmF0aW9uLiBUaGVzZSBpc3N1ZXMgYXJlXG4gKiByZWNvcmRlZCBpbiBlaXRoZXIgdGhlIGBkb21TY2hlbWFDaGVja2VyYCAod2hpY2ggY2hlY2tzIHVzYWdlIG9mIERPTSBlbGVtZW50cyBhbmQgYmluZGluZ3MpIGFzXG4gKiB3ZWxsIGFzIHRoZSBgb29iUmVjb3JkZXJgICh3aGljaCByZWNvcmRzIGVycm9ycyB3aGVuIHRoZSB0eXBlLWNoZWNraW5nIGNvZGUgZ2VuZXJhdG9yIGlzIHVuYWJsZVxuICogdG8gc3VmZmljaWVudGx5IHVuZGVyc3RhbmQgYSB0ZW1wbGF0ZSkuXG4gKlxuICogQHBhcmFtIGVudiBhbiBgRW52aXJvbm1lbnRgIGludG8gd2hpY2ggdHlwZS1jaGVja2luZyBjb2RlIHdpbGwgYmUgZ2VuZXJhdGVkLlxuICogQHBhcmFtIHJlZiBhIGBSZWZlcmVuY2VgIHRvIHRoZSBjb21wb25lbnQgY2xhc3Mgd2hpY2ggc2hvdWxkIGJlIHR5cGUtY2hlY2tlZC5cbiAqIEBwYXJhbSBuYW1lIGEgYHRzLklkZW50aWZpZXJgIHRvIHVzZSBmb3IgdGhlIGdlbmVyYXRlZCBgdHMuRnVuY3Rpb25EZWNsYXJhdGlvbmAuXG4gKiBAcGFyYW0gbWV0YSBtZXRhZGF0YSBhYm91dCB0aGUgY29tcG9uZW50J3MgdGVtcGxhdGUgYW5kIHRoZSBmdW5jdGlvbiBiZWluZyBnZW5lcmF0ZWQuXG4gKiBAcGFyYW0gZG9tU2NoZW1hQ2hlY2tlciB1c2VkIHRvIGNoZWNrIGFuZCByZWNvcmQgZXJyb3JzIHJlZ2FyZGluZyBpbXByb3BlciB1c2FnZSBvZiBET00gZWxlbWVudHNcbiAqIGFuZCBiaW5kaW5ncy5cbiAqIEBwYXJhbSBvb2JSZWNvcmRlciB1c2VkIHRvIHJlY29yZCBlcnJvcnMgcmVnYXJkaW5nIHRlbXBsYXRlIGVsZW1lbnRzIHdoaWNoIGNvdWxkIG5vdCBiZSBjb3JyZWN0bHlcbiAqIHRyYW5zbGF0ZWQgaW50byB0eXBlcyBkdXJpbmcgVENCIGdlbmVyYXRpb24uXG4gKiBAcGFyYW0gZ2VuZXJpY0NvbnRleHRCZWhhdmlvciBjb250cm9scyBob3cgZ2VuZXJpYyBwYXJhbWV0ZXJzIChlc3BlY2lhbGx5IHBhcmFtZXRlcnMgd2l0aCBnZW5lcmljXG4gKiBib3VuZHMpIHdpbGwgYmUgcmVmZXJlbmNlZCBmcm9tIHRoZSBnZW5lcmF0ZWQgVENCIGNvZGUuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBnZW5lcmF0ZVR5cGVDaGVja0Jsb2NrKFxuICAgIGVudjogRW52aXJvbm1lbnQsIHJlZjogUmVmZXJlbmNlPENsYXNzRGVjbGFyYXRpb248dHMuQ2xhc3NEZWNsYXJhdGlvbj4+LCBuYW1lOiB0cy5JZGVudGlmaWVyLFxuICAgIG1ldGE6IFR5cGVDaGVja0Jsb2NrTWV0YWRhdGEsIGRvbVNjaGVtYUNoZWNrZXI6IERvbVNjaGVtYUNoZWNrZXIsXG4gICAgb29iUmVjb3JkZXI6IE91dE9mQmFuZERpYWdub3N0aWNSZWNvcmRlcixcbiAgICBnZW5lcmljQ29udGV4dEJlaGF2aW9yOiBUY2JHZW5lcmljQ29udGV4dEJlaGF2aW9yKTogdHMuRnVuY3Rpb25EZWNsYXJhdGlvbiB7XG4gIGNvbnN0IHRjYiA9IG5ldyBDb250ZXh0KFxuICAgICAgZW52LCBkb21TY2hlbWFDaGVja2VyLCBvb2JSZWNvcmRlciwgbWV0YS5pZCwgbWV0YS5ib3VuZFRhcmdldCwgbWV0YS5waXBlcywgbWV0YS5zY2hlbWFzKTtcbiAgY29uc3Qgc2NvcGUgPSBTY29wZS5mb3JOb2Rlcyh0Y2IsIG51bGwsIHRjYi5ib3VuZFRhcmdldC50YXJnZXQudGVtcGxhdGUgISwgLyogZ3VhcmQgKi8gbnVsbCk7XG4gIGNvbnN0IGN0eFJhd1R5cGUgPSBlbnYucmVmZXJlbmNlVHlwZShyZWYpO1xuICBpZiAoIXRzLmlzVHlwZVJlZmVyZW5jZU5vZGUoY3R4UmF3VHlwZSkpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoXG4gICAgICAgIGBFeHBlY3RlZCBUeXBlUmVmZXJlbmNlTm9kZSB3aGVuIHJlZmVyZW5jaW5nIHRoZSBjdHggcGFyYW0gZm9yICR7cmVmLmRlYnVnTmFtZX1gKTtcbiAgfVxuXG4gIGxldCB0eXBlUGFyYW1ldGVyczogdHMuVHlwZVBhcmFtZXRlckRlY2xhcmF0aW9uW118dW5kZWZpbmVkID0gdW5kZWZpbmVkO1xuICBsZXQgdHlwZUFyZ3VtZW50czogdHMuVHlwZU5vZGVbXXx1bmRlZmluZWQgPSB1bmRlZmluZWQ7XG5cbiAgaWYgKHJlZi5ub2RlLnR5cGVQYXJhbWV0ZXJzICE9PSB1bmRlZmluZWQpIHtcbiAgICBpZiAoIWVudi5jb25maWcudXNlQ29udGV4dEdlbmVyaWNUeXBlKSB7XG4gICAgICBnZW5lcmljQ29udGV4dEJlaGF2aW9yID0gVGNiR2VuZXJpY0NvbnRleHRCZWhhdmlvci5GYWxsYmFja1RvQW55O1xuICAgIH1cblxuICAgIHN3aXRjaCAoZ2VuZXJpY0NvbnRleHRCZWhhdmlvcikge1xuICAgICAgY2FzZSBUY2JHZW5lcmljQ29udGV4dEJlaGF2aW9yLlVzZUVtaXR0ZXI6XG4gICAgICAgIC8vIEd1YXJhbnRlZWQgdG8gZW1pdCB0eXBlIHBhcmFtZXRlcnMgc2luY2Ugd2UgY2hlY2tlZCB0aGF0IHRoZSBjbGFzcyBoYXMgdGhlbSBhYm92ZS5cbiAgICAgICAgdHlwZVBhcmFtZXRlcnMgPSBuZXcgVHlwZVBhcmFtZXRlckVtaXR0ZXIocmVmLm5vZGUudHlwZVBhcmFtZXRlcnMsIGVudi5yZWZsZWN0b3IpXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgIC5lbWl0KHR5cGVSZWYgPT4gZW52LnJlZmVyZW5jZVR5cGUodHlwZVJlZikpITtcbiAgICAgICAgdHlwZUFyZ3VtZW50cyA9IHR5cGVQYXJhbWV0ZXJzLm1hcChwYXJhbSA9PiB0cy5mYWN0b3J5LmNyZWF0ZVR5cGVSZWZlcmVuY2VOb2RlKHBhcmFtLm5hbWUpKTtcbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlIFRjYkdlbmVyaWNDb250ZXh0QmVoYXZpb3IuQ29weUNsYXNzTm9kZXM6XG4gICAgICAgIHR5cGVQYXJhbWV0ZXJzID0gWy4uLnJlZi5ub2RlLnR5cGVQYXJhbWV0ZXJzXTtcbiAgICAgICAgdHlwZUFyZ3VtZW50cyA9IHR5cGVQYXJhbWV0ZXJzLm1hcChwYXJhbSA9PiB0cy5mYWN0b3J5LmNyZWF0ZVR5cGVSZWZlcmVuY2VOb2RlKHBhcmFtLm5hbWUpKTtcbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlIFRjYkdlbmVyaWNDb250ZXh0QmVoYXZpb3IuRmFsbGJhY2tUb0FueTpcbiAgICAgICAgdHlwZUFyZ3VtZW50cyA9IHJlZi5ub2RlLnR5cGVQYXJhbWV0ZXJzLm1hcChcbiAgICAgICAgICAgICgpID0+IHRzLmZhY3RvcnkuY3JlYXRlS2V5d29yZFR5cGVOb2RlKHRzLlN5bnRheEtpbmQuQW55S2V5d29yZCkpO1xuICAgICAgICBicmVhaztcbiAgICB9XG4gIH1cblxuICBjb25zdCBwYXJhbUxpc3QgPSBbdGNiQ3R4UGFyYW0ocmVmLm5vZGUsIGN0eFJhd1R5cGUudHlwZU5hbWUsIHR5cGVBcmd1bWVudHMpXTtcblxuICBjb25zdCBzY29wZVN0YXRlbWVudHMgPSBzY29wZS5yZW5kZXIoKTtcbiAgY29uc3QgaW5uZXJCb2R5ID0gdHMuY3JlYXRlQmxvY2soW1xuICAgIC4uLmVudi5nZXRQcmVsdWRlU3RhdGVtZW50cygpLFxuICAgIC4uLnNjb3BlU3RhdGVtZW50cyxcbiAgXSk7XG5cbiAgLy8gV3JhcCB0aGUgYm9keSBpbiBhbiBcImlmICh0cnVlKVwiIGV4cHJlc3Npb24uIFRoaXMgaXMgdW5uZWNlc3NhcnkgYnV0IGhhcyB0aGUgZWZmZWN0IG9mIGNhdXNpbmdcbiAgLy8gdGhlIGB0cy5QcmludGVyYCB0byBmb3JtYXQgdGhlIHR5cGUtY2hlY2sgYmxvY2sgbmljZWx5LlxuICBjb25zdCBib2R5ID0gdHMuY3JlYXRlQmxvY2soW3RzLmNyZWF0ZUlmKHRzLmNyZWF0ZVRydWUoKSwgaW5uZXJCb2R5LCB1bmRlZmluZWQpXSk7XG4gIGNvbnN0IGZuRGVjbCA9IHRzLmNyZWF0ZUZ1bmN0aW9uRGVjbGFyYXRpb24oXG4gICAgICAvKiBkZWNvcmF0b3JzICovIHVuZGVmaW5lZCxcbiAgICAgIC8qIG1vZGlmaWVycyAqLyB1bmRlZmluZWQsXG4gICAgICAvKiBhc3Rlcmlza1Rva2VuICovIHVuZGVmaW5lZCxcbiAgICAgIC8qIG5hbWUgKi8gbmFtZSxcbiAgICAgIC8qIHR5cGVQYXJhbWV0ZXJzICovIGVudi5jb25maWcudXNlQ29udGV4dEdlbmVyaWNUeXBlID8gdHlwZVBhcmFtZXRlcnMgOiB1bmRlZmluZWQsXG4gICAgICAvKiBwYXJhbWV0ZXJzICovIHBhcmFtTGlzdCxcbiAgICAgIC8qIHR5cGUgKi8gdW5kZWZpbmVkLFxuICAgICAgLyogYm9keSAqLyBib2R5KTtcbiAgYWRkVGVtcGxhdGVJZChmbkRlY2wsIG1ldGEuaWQpO1xuICByZXR1cm4gZm5EZWNsO1xufVxuXG4vKipcbiAqIEEgY29kZSBnZW5lcmF0aW9uIG9wZXJhdGlvbiB0aGF0J3MgaW52b2x2ZWQgaW4gdGhlIGNvbnN0cnVjdGlvbiBvZiBhIFR5cGUgQ2hlY2sgQmxvY2suXG4gKlxuICogVGhlIGdlbmVyYXRpb24gb2YgYSBUQ0IgaXMgbm9uLWxpbmVhci4gQmluZGluZ3Mgd2l0aGluIGEgdGVtcGxhdGUgbWF5IHJlc3VsdCBpbiB0aGUgbmVlZCB0b1xuICogY29uc3RydWN0IGNlcnRhaW4gdHlwZXMgZWFybGllciB0aGFuIHRoZXkgb3RoZXJ3aXNlIHdvdWxkIGJlIGNvbnN0cnVjdGVkLiBUaGF0IGlzLCBpZiB0aGVcbiAqIGdlbmVyYXRpb24gb2YgYSBUQ0IgZm9yIGEgdGVtcGxhdGUgaXMgYnJva2VuIGRvd24gaW50byBzcGVjaWZpYyBvcGVyYXRpb25zIChjb25zdHJ1Y3RpbmcgYVxuICogZGlyZWN0aXZlLCBleHRyYWN0aW5nIGEgdmFyaWFibGUgZnJvbSBhIGxldC0gb3BlcmF0aW9uLCBldGMpLCB0aGVuIGl0J3MgcG9zc2libGUgZm9yIG9wZXJhdGlvbnNcbiAqIGVhcmxpZXIgaW4gdGhlIHNlcXVlbmNlIHRvIGRlcGVuZCBvbiBvcGVyYXRpb25zIHdoaWNoIG9jY3VyIGxhdGVyIGluIHRoZSBzZXF1ZW5jZS5cbiAqXG4gKiBgVGNiT3BgIGFic3RyYWN0cyB0aGUgZGlmZmVyZW50IHR5cGVzIG9mIG9wZXJhdGlvbnMgd2hpY2ggYXJlIHJlcXVpcmVkIHRvIGNvbnZlcnQgYSB0ZW1wbGF0ZSBpbnRvXG4gKiBhIFRDQi4gVGhpcyBhbGxvd3MgZm9yIHR3byBwaGFzZXMgb2YgcHJvY2Vzc2luZyBmb3IgdGhlIHRlbXBsYXRlLCB3aGVyZSAxKSBhIGxpbmVhciBzZXF1ZW5jZSBvZlxuICogYFRjYk9wYHMgaXMgZ2VuZXJhdGVkLCBhbmQgdGhlbiAyKSB0aGVzZSBvcGVyYXRpb25zIGFyZSBleGVjdXRlZCwgbm90IG5lY2Vzc2FyaWx5IGluIGxpbmVhclxuICogb3JkZXIuXG4gKlxuICogRWFjaCBgVGNiT3BgIG1heSBpbnNlcnQgc3RhdGVtZW50cyBpbnRvIHRoZSBib2R5IG9mIHRoZSBUQ0IsIGFuZCBhbHNvIG9wdGlvbmFsbHkgcmV0dXJuIGFcbiAqIGB0cy5FeHByZXNzaW9uYCB3aGljaCBjYW4gYmUgdXNlZCB0byByZWZlcmVuY2UgdGhlIG9wZXJhdGlvbidzIHJlc3VsdC5cbiAqL1xuYWJzdHJhY3QgY2xhc3MgVGNiT3Age1xuICAvKipcbiAgICogU2V0IHRvIHRydWUgaWYgdGhpcyBvcGVyYXRpb24gY2FuIGJlIGNvbnNpZGVyZWQgb3B0aW9uYWwuIE9wdGlvbmFsIG9wZXJhdGlvbnMgYXJlIG9ubHkgZXhlY3V0ZWRcbiAgICogd2hlbiBkZXBlbmRlZCB1cG9uIGJ5IG90aGVyIG9wZXJhdGlvbnMsIG90aGVyd2lzZSB0aGV5IGFyZSBkaXNyZWdhcmRlZC4gVGhpcyBhbGxvd3MgZm9yIGxlc3NcbiAgICogY29kZSB0byBnZW5lcmF0ZSwgcGFyc2UgYW5kIHR5cGUtY2hlY2ssIG92ZXJhbGwgcG9zaXRpdmVseSBjb250cmlidXRpbmcgdG8gcGVyZm9ybWFuY2UuXG4gICAqL1xuICBhYnN0cmFjdCByZWFkb25seSBvcHRpb25hbDogYm9vbGVhbjtcblxuICBhYnN0cmFjdCBleGVjdXRlKCk6IHRzLkV4cHJlc3Npb258bnVsbDtcblxuICAvKipcbiAgICogUmVwbGFjZW1lbnQgdmFsdWUgb3Igb3BlcmF0aW9uIHVzZWQgd2hpbGUgdGhpcyBgVGNiT3BgIGlzIGV4ZWN1dGluZyAoaS5lLiB0byByZXNvbHZlIGNpcmN1bGFyXG4gICAqIHJlZmVyZW5jZXMgZHVyaW5nIGl0cyBleGVjdXRpb24pLlxuICAgKlxuICAgKiBUaGlzIGlzIHVzdWFsbHkgYSBgbnVsbCFgIGV4cHJlc3Npb24gKHdoaWNoIGFza3MgVFMgdG8gaW5mZXIgYW4gYXBwcm9wcmlhdGUgdHlwZSksIGJ1dCBhbm90aGVyXG4gICAqIGBUY2JPcGAgY2FuIGJlIHJldHVybmVkIGluIGNhc2VzIHdoZXJlIGFkZGl0aW9uYWwgY29kZSBnZW5lcmF0aW9uIGlzIG5lY2Vzc2FyeSB0byBkZWFsIHdpdGhcbiAgICogY2lyY3VsYXIgcmVmZXJlbmNlcy5cbiAgICovXG4gIGNpcmN1bGFyRmFsbGJhY2soKTogVGNiT3B8dHMuRXhwcmVzc2lvbiB7XG4gICAgcmV0dXJuIElORkVSX1RZUEVfRk9SX0NJUkNVTEFSX09QX0VYUFI7XG4gIH1cbn1cblxuLyoqXG4gKiBBIGBUY2JPcGAgd2hpY2ggY3JlYXRlcyBhbiBleHByZXNzaW9uIGZvciBhIG5hdGl2ZSBET00gZWxlbWVudCAob3Igd2ViIGNvbXBvbmVudCkgZnJvbSBhXG4gKiBgVG1wbEFzdEVsZW1lbnRgLlxuICpcbiAqIEV4ZWN1dGluZyB0aGlzIG9wZXJhdGlvbiByZXR1cm5zIGEgcmVmZXJlbmNlIHRvIHRoZSBlbGVtZW50IHZhcmlhYmxlLlxuICovXG5jbGFzcyBUY2JFbGVtZW50T3AgZXh0ZW5kcyBUY2JPcCB7XG4gIGNvbnN0cnVjdG9yKHByaXZhdGUgdGNiOiBDb250ZXh0LCBwcml2YXRlIHNjb3BlOiBTY29wZSwgcHJpdmF0ZSBlbGVtZW50OiBUbXBsQXN0RWxlbWVudCkge1xuICAgIHN1cGVyKCk7XG4gIH1cblxuICBnZXQgb3B0aW9uYWwoKSB7XG4gICAgLy8gVGhlIHN0YXRlbWVudCBnZW5lcmF0ZWQgYnkgdGhpcyBvcGVyYXRpb24gaXMgb25seSB1c2VkIGZvciB0eXBlLWluZmVyZW5jZSBvZiB0aGUgRE9NXG4gICAgLy8gZWxlbWVudCdzIHR5cGUgYW5kIHdvbid0IHJlcG9ydCBkaWFnbm9zdGljcyBieSBpdHNlbGYsIHNvIHRoZSBvcGVyYXRpb24gaXMgbWFya2VkIGFzIG9wdGlvbmFsXG4gICAgLy8gdG8gYXZvaWQgZ2VuZXJhdGluZyBzdGF0ZW1lbnRzIGZvciBET00gZWxlbWVudHMgdGhhdCBhcmUgbmV2ZXIgcmVmZXJlbmNlZC5cbiAgICByZXR1cm4gdHJ1ZTtcbiAgfVxuXG4gIGV4ZWN1dGUoKTogdHMuSWRlbnRpZmllciB7XG4gICAgY29uc3QgaWQgPSB0aGlzLnRjYi5hbGxvY2F0ZUlkKCk7XG4gICAgLy8gQWRkIHRoZSBkZWNsYXJhdGlvbiBvZiB0aGUgZWxlbWVudCB1c2luZyBkb2N1bWVudC5jcmVhdGVFbGVtZW50LlxuICAgIGNvbnN0IGluaXRpYWxpemVyID0gdHNDcmVhdGVFbGVtZW50KHRoaXMuZWxlbWVudC5uYW1lKTtcbiAgICBhZGRQYXJzZVNwYW5JbmZvKGluaXRpYWxpemVyLCB0aGlzLmVsZW1lbnQuc3RhcnRTb3VyY2VTcGFuIHx8IHRoaXMuZWxlbWVudC5zb3VyY2VTcGFuKTtcbiAgICB0aGlzLnNjb3BlLmFkZFN0YXRlbWVudCh0c0NyZWF0ZVZhcmlhYmxlKGlkLCBpbml0aWFsaXplcikpO1xuICAgIHJldHVybiBpZDtcbiAgfVxufVxuXG4vKipcbiAqIEEgYFRjYk9wYCB3aGljaCBjcmVhdGVzIGFuIGV4cHJlc3Npb24gZm9yIHBhcnRpY3VsYXIgbGV0LSBgVG1wbEFzdFZhcmlhYmxlYCBvbiBhXG4gKiBgVG1wbEFzdFRlbXBsYXRlYCdzIGNvbnRleHQuXG4gKlxuICogRXhlY3V0aW5nIHRoaXMgb3BlcmF0aW9uIHJldHVybnMgYSByZWZlcmVuY2UgdG8gdGhlIHZhcmlhYmxlIHZhcmlhYmxlIChsb2wpLlxuICovXG5jbGFzcyBUY2JWYXJpYWJsZU9wIGV4dGVuZHMgVGNiT3Age1xuICBjb25zdHJ1Y3RvcihcbiAgICAgIHByaXZhdGUgdGNiOiBDb250ZXh0LCBwcml2YXRlIHNjb3BlOiBTY29wZSwgcHJpdmF0ZSB0ZW1wbGF0ZTogVG1wbEFzdFRlbXBsYXRlLFxuICAgICAgcHJpdmF0ZSB2YXJpYWJsZTogVG1wbEFzdFZhcmlhYmxlKSB7XG4gICAgc3VwZXIoKTtcbiAgfVxuXG4gIGdldCBvcHRpb25hbCgpIHtcbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cblxuICBleGVjdXRlKCk6IHRzLklkZW50aWZpZXIge1xuICAgIC8vIExvb2sgZm9yIGEgY29udGV4dCB2YXJpYWJsZSBmb3IgdGhlIHRlbXBsYXRlLlxuICAgIGNvbnN0IGN0eCA9IHRoaXMuc2NvcGUucmVzb2x2ZSh0aGlzLnRlbXBsYXRlKTtcblxuICAgIC8vIEFsbG9jYXRlIGFuIGlkZW50aWZpZXIgZm9yIHRoZSBUbXBsQXN0VmFyaWFibGUsIGFuZCBpbml0aWFsaXplIGl0IHRvIGEgcmVhZCBvZiB0aGUgdmFyaWFibGVcbiAgICAvLyBvbiB0aGUgdGVtcGxhdGUgY29udGV4dC5cbiAgICBjb25zdCBpZCA9IHRoaXMudGNiLmFsbG9jYXRlSWQoKTtcbiAgICBjb25zdCBpbml0aWFsaXplciA9IHRzLmNyZWF0ZVByb3BlcnR5QWNjZXNzKFxuICAgICAgICAvKiBleHByZXNzaW9uICovIGN0eCxcbiAgICAgICAgLyogbmFtZSAqLyB0aGlzLnZhcmlhYmxlLnZhbHVlIHx8ICckaW1wbGljaXQnKTtcbiAgICBhZGRQYXJzZVNwYW5JbmZvKGlkLCB0aGlzLnZhcmlhYmxlLmtleVNwYW4pO1xuXG4gICAgLy8gRGVjbGFyZSB0aGUgdmFyaWFibGUsIGFuZCByZXR1cm4gaXRzIGlkZW50aWZpZXIuXG4gICAgbGV0IHZhcmlhYmxlOiB0cy5WYXJpYWJsZVN0YXRlbWVudDtcbiAgICBpZiAodGhpcy52YXJpYWJsZS52YWx1ZVNwYW4gIT09IHVuZGVmaW5lZCkge1xuICAgICAgYWRkUGFyc2VTcGFuSW5mbyhpbml0aWFsaXplciwgdGhpcy52YXJpYWJsZS52YWx1ZVNwYW4pO1xuICAgICAgdmFyaWFibGUgPSB0c0NyZWF0ZVZhcmlhYmxlKGlkLCB3cmFwRm9yVHlwZUNoZWNrZXIoaW5pdGlhbGl6ZXIpKTtcbiAgICB9IGVsc2Uge1xuICAgICAgdmFyaWFibGUgPSB0c0NyZWF0ZVZhcmlhYmxlKGlkLCBpbml0aWFsaXplcik7XG4gICAgfVxuICAgIGFkZFBhcnNlU3BhbkluZm8odmFyaWFibGUuZGVjbGFyYXRpb25MaXN0LmRlY2xhcmF0aW9uc1swXSwgdGhpcy52YXJpYWJsZS5zb3VyY2VTcGFuKTtcbiAgICB0aGlzLnNjb3BlLmFkZFN0YXRlbWVudCh2YXJpYWJsZSk7XG4gICAgcmV0dXJuIGlkO1xuICB9XG59XG5cbi8qKlxuICogQSBgVGNiT3BgIHdoaWNoIGdlbmVyYXRlcyBhIHZhcmlhYmxlIGZvciBhIGBUbXBsQXN0VGVtcGxhdGVgJ3MgY29udGV4dC5cbiAqXG4gKiBFeGVjdXRpbmcgdGhpcyBvcGVyYXRpb24gcmV0dXJucyBhIHJlZmVyZW5jZSB0byB0aGUgdGVtcGxhdGUncyBjb250ZXh0IHZhcmlhYmxlLlxuICovXG5jbGFzcyBUY2JUZW1wbGF0ZUNvbnRleHRPcCBleHRlbmRzIFRjYk9wIHtcbiAgY29uc3RydWN0b3IocHJpdmF0ZSB0Y2I6IENvbnRleHQsIHByaXZhdGUgc2NvcGU6IFNjb3BlKSB7XG4gICAgc3VwZXIoKTtcbiAgfVxuXG4gIC8vIFRoZSBkZWNsYXJhdGlvbiBvZiB0aGUgY29udGV4dCB2YXJpYWJsZSBpcyBvbmx5IG5lZWRlZCB3aGVuIHRoZSBjb250ZXh0IGlzIGFjdHVhbGx5IHJlZmVyZW5jZWQuXG4gIHJlYWRvbmx5IG9wdGlvbmFsID0gdHJ1ZTtcblxuICBleGVjdXRlKCk6IHRzLklkZW50aWZpZXIge1xuICAgIC8vIEFsbG9jYXRlIGEgdGVtcGxhdGUgY3R4IHZhcmlhYmxlIGFuZCBkZWNsYXJlIGl0IHdpdGggYW4gJ2FueScgdHlwZS4gVGhlIHR5cGUgb2YgdGhpcyB2YXJpYWJsZVxuICAgIC8vIG1heSBiZSBuYXJyb3dlZCBhcyBhIHJlc3VsdCBvZiB0ZW1wbGF0ZSBndWFyZCBjb25kaXRpb25zLlxuICAgIGNvbnN0IGN0eCA9IHRoaXMudGNiLmFsbG9jYXRlSWQoKTtcbiAgICBjb25zdCB0eXBlID0gdHMuY3JlYXRlS2V5d29yZFR5cGVOb2RlKHRzLlN5bnRheEtpbmQuQW55S2V5d29yZCk7XG4gICAgdGhpcy5zY29wZS5hZGRTdGF0ZW1lbnQodHNEZWNsYXJlVmFyaWFibGUoY3R4LCB0eXBlKSk7XG4gICAgcmV0dXJuIGN0eDtcbiAgfVxufVxuXG4vKipcbiAqIEEgYFRjYk9wYCB3aGljaCBkZXNjZW5kcyBpbnRvIGEgYFRtcGxBc3RUZW1wbGF0ZWAncyBjaGlsZHJlbiBhbmQgZ2VuZXJhdGVzIHR5cGUtY2hlY2tpbmcgY29kZSBmb3JcbiAqIHRoZW0uXG4gKlxuICogVGhpcyBvcGVyYXRpb24gd3JhcHMgdGhlIGNoaWxkcmVuJ3MgdHlwZS1jaGVja2luZyBjb2RlIGluIGFuIGBpZmAgYmxvY2ssIHdoaWNoIG1heSBpbmNsdWRlIG9uZVxuICogb3IgbW9yZSB0eXBlIGd1YXJkIGNvbmRpdGlvbnMgdGhhdCBuYXJyb3cgdHlwZXMgd2l0aGluIHRoZSB0ZW1wbGF0ZSBib2R5LlxuICovXG5jbGFzcyBUY2JUZW1wbGF0ZUJvZHlPcCBleHRlbmRzIFRjYk9wIHtcbiAgY29uc3RydWN0b3IocHJpdmF0ZSB0Y2I6IENvbnRleHQsIHByaXZhdGUgc2NvcGU6IFNjb3BlLCBwcml2YXRlIHRlbXBsYXRlOiBUbXBsQXN0VGVtcGxhdGUpIHtcbiAgICBzdXBlcigpO1xuICB9XG5cbiAgZ2V0IG9wdGlvbmFsKCkge1xuICAgIHJldHVybiBmYWxzZTtcbiAgfVxuXG4gIGV4ZWN1dGUoKTogbnVsbCB7XG4gICAgLy8gQW4gYGlmYCB3aWxsIGJlIGNvbnN0cnVjdGVkLCB3aXRoaW4gd2hpY2ggdGhlIHRlbXBsYXRlJ3MgY2hpbGRyZW4gd2lsbCBiZSB0eXBlIGNoZWNrZWQuIFRoZVxuICAgIC8vIGBpZmAgaXMgdXNlZCBmb3IgdHdvIHJlYXNvbnM6IGl0IGNyZWF0ZXMgYSBuZXcgc3ludGFjdGljIHNjb3BlLCBpc29sYXRpbmcgdmFyaWFibGVzIGRlY2xhcmVkXG4gICAgLy8gaW4gdGhlIHRlbXBsYXRlJ3MgVENCIGZyb20gdGhlIG91dGVyIGNvbnRleHQsIGFuZCBpdCBhbGxvd3MgYW55IGRpcmVjdGl2ZXMgb24gdGhlIHRlbXBsYXRlc1xuICAgIC8vIHRvIHBlcmZvcm0gdHlwZSBuYXJyb3dpbmcgb2YgZWl0aGVyIGV4cHJlc3Npb25zIG9yIHRoZSB0ZW1wbGF0ZSdzIGNvbnRleHQuXG4gICAgLy9cbiAgICAvLyBUaGUgZ3VhcmQgaXMgdGhlIGBpZmAgYmxvY2sncyBjb25kaXRpb24uIEl0J3MgdXN1YWxseSBzZXQgdG8gYHRydWVgIGJ1dCBkaXJlY3RpdmVzIHRoYXQgZXhpc3RcbiAgICAvLyBvbiB0aGUgdGVtcGxhdGUgY2FuIHRyaWdnZXIgZXh0cmEgZ3VhcmQgZXhwcmVzc2lvbnMgdGhhdCBzZXJ2ZSB0byBuYXJyb3cgdHlwZXMgd2l0aGluIHRoZVxuICAgIC8vIGBpZmAuIGBndWFyZGAgaXMgY2FsY3VsYXRlZCBieSBzdGFydGluZyB3aXRoIGB0cnVlYCBhbmQgYWRkaW5nIG90aGVyIGNvbmRpdGlvbnMgYXMgbmVlZGVkLlxuICAgIC8vIENvbGxlY3QgdGhlc2UgaW50byBgZ3VhcmRzYCBieSBwcm9jZXNzaW5nIHRoZSBkaXJlY3RpdmVzLlxuICAgIGNvbnN0IGRpcmVjdGl2ZUd1YXJkczogdHMuRXhwcmVzc2lvbltdID0gW107XG5cbiAgICBjb25zdCBkaXJlY3RpdmVzID0gdGhpcy50Y2IuYm91bmRUYXJnZXQuZ2V0RGlyZWN0aXZlc09mTm9kZSh0aGlzLnRlbXBsYXRlKTtcbiAgICBpZiAoZGlyZWN0aXZlcyAhPT0gbnVsbCkge1xuICAgICAgZm9yIChjb25zdCBkaXIgb2YgZGlyZWN0aXZlcykge1xuICAgICAgICBjb25zdCBkaXJJbnN0SWQgPSB0aGlzLnNjb3BlLnJlc29sdmUodGhpcy50ZW1wbGF0ZSwgZGlyKTtcbiAgICAgICAgY29uc3QgZGlySWQgPVxuICAgICAgICAgICAgdGhpcy50Y2IuZW52LnJlZmVyZW5jZShkaXIucmVmIGFzIFJlZmVyZW5jZTxDbGFzc0RlY2xhcmF0aW9uPHRzLkNsYXNzRGVjbGFyYXRpb24+Pik7XG5cbiAgICAgICAgLy8gVGhlcmUgYXJlIHR3byBraW5kcyBvZiBndWFyZHMuIFRlbXBsYXRlIGd1YXJkcyAobmdUZW1wbGF0ZUd1YXJkcykgYWxsb3cgdHlwZSBuYXJyb3dpbmcgb2ZcbiAgICAgICAgLy8gdGhlIGV4cHJlc3Npb24gcGFzc2VkIHRvIGFuIEBJbnB1dCBvZiB0aGUgZGlyZWN0aXZlLiBTY2FuIHRoZSBkaXJlY3RpdmUgdG8gc2VlIGlmIGl0IGhhc1xuICAgICAgICAvLyBhbnkgdGVtcGxhdGUgZ3VhcmRzLCBhbmQgZ2VuZXJhdGUgdGhlbSBpZiBuZWVkZWQuXG4gICAgICAgIGRpci5uZ1RlbXBsYXRlR3VhcmRzLmZvckVhY2goZ3VhcmQgPT4ge1xuICAgICAgICAgIC8vIEZvciBlYWNoIHRlbXBsYXRlIGd1YXJkIGZ1bmN0aW9uIG9uIHRoZSBkaXJlY3RpdmUsIGxvb2sgZm9yIGEgYmluZGluZyB0byB0aGF0IGlucHV0LlxuICAgICAgICAgIGNvbnN0IGJvdW5kSW5wdXQgPSB0aGlzLnRlbXBsYXRlLmlucHV0cy5maW5kKGkgPT4gaS5uYW1lID09PSBndWFyZC5pbnB1dE5hbWUpIHx8XG4gICAgICAgICAgICAgIHRoaXMudGVtcGxhdGUudGVtcGxhdGVBdHRycy5maW5kKFxuICAgICAgICAgICAgICAgICAgKGk6IFRtcGxBc3RUZXh0QXR0cmlidXRlfFRtcGxBc3RCb3VuZEF0dHJpYnV0ZSk6IGkgaXMgVG1wbEFzdEJvdW5kQXR0cmlidXRlID0+XG4gICAgICAgICAgICAgICAgICAgICAgaSBpbnN0YW5jZW9mIFRtcGxBc3RCb3VuZEF0dHJpYnV0ZSAmJiBpLm5hbWUgPT09IGd1YXJkLmlucHV0TmFtZSk7XG4gICAgICAgICAgaWYgKGJvdW5kSW5wdXQgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgLy8gSWYgdGhlcmUgaXMgc3VjaCBhIGJpbmRpbmcsIGdlbmVyYXRlIGFuIGV4cHJlc3Npb24gZm9yIGl0LlxuICAgICAgICAgICAgY29uc3QgZXhwciA9IHRjYkV4cHJlc3Npb24oYm91bmRJbnB1dC52YWx1ZSwgdGhpcy50Y2IsIHRoaXMuc2NvcGUpO1xuXG4gICAgICAgICAgICAvLyBUaGUgZXhwcmVzc2lvbiBoYXMgYWxyZWFkeSBiZWVuIGNoZWNrZWQgaW4gdGhlIHR5cGUgY29uc3RydWN0b3IgaW52b2NhdGlvbiwgc29cbiAgICAgICAgICAgIC8vIGl0IHNob3VsZCBiZSBpZ25vcmVkIHdoZW4gdXNlZCB3aXRoaW4gYSB0ZW1wbGF0ZSBndWFyZC5cbiAgICAgICAgICAgIG1hcmtJZ25vcmVEaWFnbm9zdGljcyhleHByKTtcblxuICAgICAgICAgICAgaWYgKGd1YXJkLnR5cGUgPT09ICdiaW5kaW5nJykge1xuICAgICAgICAgICAgICAvLyBVc2UgdGhlIGJpbmRpbmcgZXhwcmVzc2lvbiBpdHNlbGYgYXMgZ3VhcmQuXG4gICAgICAgICAgICAgIGRpcmVjdGl2ZUd1YXJkcy5wdXNoKGV4cHIpO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgLy8gQ2FsbCB0aGUgZ3VhcmQgZnVuY3Rpb24gb24gdGhlIGRpcmVjdGl2ZSB3aXRoIHRoZSBkaXJlY3RpdmUgaW5zdGFuY2UgYW5kIHRoYXRcbiAgICAgICAgICAgICAgLy8gZXhwcmVzc2lvbi5cbiAgICAgICAgICAgICAgY29uc3QgZ3VhcmRJbnZva2UgPSB0c0NhbGxNZXRob2QoZGlySWQsIGBuZ1RlbXBsYXRlR3VhcmRfJHtndWFyZC5pbnB1dE5hbWV9YCwgW1xuICAgICAgICAgICAgICAgIGRpckluc3RJZCxcbiAgICAgICAgICAgICAgICBleHByLFxuICAgICAgICAgICAgICBdKTtcbiAgICAgICAgICAgICAgYWRkUGFyc2VTcGFuSW5mbyhndWFyZEludm9rZSwgYm91bmRJbnB1dC52YWx1ZS5zb3VyY2VTcGFuKTtcbiAgICAgICAgICAgICAgZGlyZWN0aXZlR3VhcmRzLnB1c2goZ3VhcmRJbnZva2UpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgfSk7XG5cbiAgICAgICAgLy8gVGhlIHNlY29uZCBraW5kIG9mIGd1YXJkIGlzIGEgdGVtcGxhdGUgY29udGV4dCBndWFyZC4gVGhpcyBndWFyZCBuYXJyb3dzIHRoZSB0ZW1wbGF0ZVxuICAgICAgICAvLyByZW5kZXJpbmcgY29udGV4dCB2YXJpYWJsZSBgY3R4YC5cbiAgICAgICAgaWYgKGRpci5oYXNOZ1RlbXBsYXRlQ29udGV4dEd1YXJkKSB7XG4gICAgICAgICAgaWYgKHRoaXMudGNiLmVudi5jb25maWcuYXBwbHlUZW1wbGF0ZUNvbnRleHRHdWFyZHMpIHtcbiAgICAgICAgICAgIGNvbnN0IGN0eCA9IHRoaXMuc2NvcGUucmVzb2x2ZSh0aGlzLnRlbXBsYXRlKTtcbiAgICAgICAgICAgIGNvbnN0IGd1YXJkSW52b2tlID0gdHNDYWxsTWV0aG9kKGRpcklkLCAnbmdUZW1wbGF0ZUNvbnRleHRHdWFyZCcsIFtkaXJJbnN0SWQsIGN0eF0pO1xuICAgICAgICAgICAgYWRkUGFyc2VTcGFuSW5mbyhndWFyZEludm9rZSwgdGhpcy50ZW1wbGF0ZS5zb3VyY2VTcGFuKTtcbiAgICAgICAgICAgIGRpcmVjdGl2ZUd1YXJkcy5wdXNoKGd1YXJkSW52b2tlKTtcbiAgICAgICAgICB9IGVsc2UgaWYgKFxuICAgICAgICAgICAgICB0aGlzLnRlbXBsYXRlLnZhcmlhYmxlcy5sZW5ndGggPiAwICYmXG4gICAgICAgICAgICAgIHRoaXMudGNiLmVudi5jb25maWcuc3VnZ2VzdGlvbnNGb3JTdWJvcHRpbWFsVHlwZUluZmVyZW5jZSkge1xuICAgICAgICAgICAgLy8gVGhlIGNvbXBpbGVyIGNvdWxkIGhhdmUgaW5mZXJyZWQgYSBiZXR0ZXIgdHlwZSBmb3IgdGhlIHZhcmlhYmxlcyBpbiB0aGlzIHRlbXBsYXRlLFxuICAgICAgICAgICAgLy8gYnV0IHdhcyBwcmV2ZW50ZWQgZnJvbSBkb2luZyBzbyBieSB0aGUgdHlwZS1jaGVja2luZyBjb25maWd1cmF0aW9uLiBJc3N1ZSBhIHdhcm5pbmdcbiAgICAgICAgICAgIC8vIGRpYWdub3N0aWMuXG4gICAgICAgICAgICB0aGlzLnRjYi5vb2JSZWNvcmRlci5zdWJvcHRpbWFsVHlwZUluZmVyZW5jZSh0aGlzLnRjYi5pZCwgdGhpcy50ZW1wbGF0ZS52YXJpYWJsZXMpO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cblxuICAgIC8vIEJ5IGRlZmF1bHQgdGhlIGd1YXJkIGlzIHNpbXBseSBgdHJ1ZWAuXG4gICAgbGV0IGd1YXJkOiB0cy5FeHByZXNzaW9ufG51bGwgPSBudWxsO1xuXG4gICAgLy8gSWYgdGhlcmUgYXJlIGFueSBndWFyZHMgZnJvbSBkaXJlY3RpdmVzLCB1c2UgdGhlbSBpbnN0ZWFkLlxuICAgIGlmIChkaXJlY3RpdmVHdWFyZHMubGVuZ3RoID4gMCkge1xuICAgICAgLy8gUG9wIHRoZSBmaXJzdCB2YWx1ZSBhbmQgdXNlIGl0IGFzIHRoZSBpbml0aWFsaXplciB0byByZWR1Y2UoKS4gVGhpcyB3YXksIGEgc2luZ2xlIGd1YXJkXG4gICAgICAvLyB3aWxsIGJlIHVzZWQgb24gaXRzIG93biwgYnV0IHR3byBvciBtb3JlIHdpbGwgYmUgY29tYmluZWQgaW50byBiaW5hcnkgQU5EIGV4cHJlc3Npb25zLlxuICAgICAgZ3VhcmQgPSBkaXJlY3RpdmVHdWFyZHMucmVkdWNlKFxuICAgICAgICAgIChleHByLCBkaXJHdWFyZCkgPT5cbiAgICAgICAgICAgICAgdHMuY3JlYXRlQmluYXJ5KGV4cHIsIHRzLlN5bnRheEtpbmQuQW1wZXJzYW5kQW1wZXJzYW5kVG9rZW4sIGRpckd1YXJkKSxcbiAgICAgICAgICBkaXJlY3RpdmVHdWFyZHMucG9wKCkhKTtcbiAgICB9XG5cbiAgICAvLyBDcmVhdGUgYSBuZXcgU2NvcGUgZm9yIHRoZSB0ZW1wbGF0ZS4gVGhpcyBjb25zdHJ1Y3RzIHRoZSBsaXN0IG9mIG9wZXJhdGlvbnMgZm9yIHRoZSB0ZW1wbGF0ZVxuICAgIC8vIGNoaWxkcmVuLCBhcyB3ZWxsIGFzIHRyYWNrcyBiaW5kaW5ncyB3aXRoaW4gdGhlIHRlbXBsYXRlLlxuICAgIGNvbnN0IHRtcGxTY29wZSA9IFNjb3BlLmZvck5vZGVzKHRoaXMudGNiLCB0aGlzLnNjb3BlLCB0aGlzLnRlbXBsYXRlLCBndWFyZCk7XG5cbiAgICAvLyBSZW5kZXIgdGhlIHRlbXBsYXRlJ3MgYFNjb3BlYCBpbnRvIGl0cyBzdGF0ZW1lbnRzLlxuICAgIGNvbnN0IHN0YXRlbWVudHMgPSB0bXBsU2NvcGUucmVuZGVyKCk7XG4gICAgaWYgKHN0YXRlbWVudHMubGVuZ3RoID09PSAwKSB7XG4gICAgICAvLyBBcyBhbiBvcHRpbWl6YXRpb24sIGRvbid0IGdlbmVyYXRlIHRoZSBzY29wZSdzIGJsb2NrIGlmIGl0IGhhcyBubyBzdGF0ZW1lbnRzLiBUaGlzIGlzXG4gICAgICAvLyBiZW5lZmljaWFsIGZvciB0ZW1wbGF0ZXMgdGhhdCBjb250YWluIGZvciBleGFtcGxlIGA8c3BhbiAqbmdJZj1cImZpcnN0XCI+PC9zcGFuPmAsIGluIHdoaWNoXG4gICAgICAvLyBjYXNlIHRoZXJlJ3Mgbm8gbmVlZCB0byByZW5kZXIgdGhlIGBOZ0lmYCBndWFyZCBleHByZXNzaW9uLiBUaGlzIHNlZW1zIGxpa2UgYSBtaW5vclxuICAgICAgLy8gaW1wcm92ZW1lbnQsIGhvd2V2ZXIgaXQgcmVkdWNlcyB0aGUgbnVtYmVyIG9mIGZsb3ctbm9kZSBhbnRlY2VkZW50cyB0aGF0IFR5cGVTY3JpcHQgbmVlZHNcbiAgICAgIC8vIHRvIGtlZXAgaW50byBhY2NvdW50IGZvciBzdWNoIGNhc2VzLCByZXN1bHRpbmcgaW4gYW4gb3ZlcmFsbCByZWR1Y3Rpb24gb2ZcbiAgICAgIC8vIHR5cGUtY2hlY2tpbmcgdGltZS5cbiAgICAgIHJldHVybiBudWxsO1xuICAgIH1cblxuICAgIGxldCB0bXBsQmxvY2s6IHRzLlN0YXRlbWVudCA9IHRzLmNyZWF0ZUJsb2NrKHN0YXRlbWVudHMpO1xuICAgIGlmIChndWFyZCAhPT0gbnVsbCkge1xuICAgICAgLy8gVGhlIHNjb3BlIGhhcyBhIGd1YXJkIHRoYXQgbmVlZHMgdG8gYmUgYXBwbGllZCwgc28gd3JhcCB0aGUgdGVtcGxhdGUgYmxvY2sgaW50byBhbiBgaWZgXG4gICAgICAvLyBzdGF0ZW1lbnQgY29udGFpbmluZyB0aGUgZ3VhcmQgZXhwcmVzc2lvbi5cbiAgICAgIHRtcGxCbG9jayA9IHRzLmNyZWF0ZUlmKC8qIGV4cHJlc3Npb24gKi8gZ3VhcmQsIC8qIHRoZW5TdGF0ZW1lbnQgKi8gdG1wbEJsb2NrKTtcbiAgICB9XG4gICAgdGhpcy5zY29wZS5hZGRTdGF0ZW1lbnQodG1wbEJsb2NrKTtcblxuICAgIHJldHVybiBudWxsO1xuICB9XG59XG5cbi8qKlxuICogQSBgVGNiT3BgIHdoaWNoIHJlbmRlcnMgYSB0ZXh0IGJpbmRpbmcgKGludGVycG9sYXRpb24pIGludG8gdGhlIFRDQi5cbiAqXG4gKiBFeGVjdXRpbmcgdGhpcyBvcGVyYXRpb24gcmV0dXJucyBub3RoaW5nLlxuICovXG5jbGFzcyBUY2JUZXh0SW50ZXJwb2xhdGlvbk9wIGV4dGVuZHMgVGNiT3Age1xuICBjb25zdHJ1Y3Rvcihwcml2YXRlIHRjYjogQ29udGV4dCwgcHJpdmF0ZSBzY29wZTogU2NvcGUsIHByaXZhdGUgYmluZGluZzogVG1wbEFzdEJvdW5kVGV4dCkge1xuICAgIHN1cGVyKCk7XG4gIH1cblxuICBnZXQgb3B0aW9uYWwoKSB7XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG5cbiAgZXhlY3V0ZSgpOiBudWxsIHtcbiAgICBjb25zdCBleHByID0gdGNiRXhwcmVzc2lvbih0aGlzLmJpbmRpbmcudmFsdWUsIHRoaXMudGNiLCB0aGlzLnNjb3BlKTtcbiAgICB0aGlzLnNjb3BlLmFkZFN0YXRlbWVudCh0cy5jcmVhdGVFeHByZXNzaW9uU3RhdGVtZW50KGV4cHIpKTtcbiAgICByZXR1cm4gbnVsbDtcbiAgfVxufVxuXG4vKipcbiAqIEEgYFRjYk9wYCB3aGljaCBjb25zdHJ1Y3RzIGFuIGluc3RhbmNlIG9mIGEgZGlyZWN0aXZlLiBGb3IgZ2VuZXJpYyBkaXJlY3RpdmVzLCBnZW5lcmljXG4gKiBwYXJhbWV0ZXJzIGFyZSBzZXQgdG8gYGFueWAgdHlwZS5cbiAqL1xuYWJzdHJhY3QgY2xhc3MgVGNiRGlyZWN0aXZlVHlwZU9wQmFzZSBleHRlbmRzIFRjYk9wIHtcbiAgY29uc3RydWN0b3IoXG4gICAgICBwcm90ZWN0ZWQgdGNiOiBDb250ZXh0LCBwcm90ZWN0ZWQgc2NvcGU6IFNjb3BlLFxuICAgICAgcHJvdGVjdGVkIG5vZGU6IFRtcGxBc3RUZW1wbGF0ZXxUbXBsQXN0RWxlbWVudCwgcHJvdGVjdGVkIGRpcjogVHlwZUNoZWNrYWJsZURpcmVjdGl2ZU1ldGEpIHtcbiAgICBzdXBlcigpO1xuICB9XG5cbiAgZ2V0IG9wdGlvbmFsKCkge1xuICAgIC8vIFRoZSBzdGF0ZW1lbnQgZ2VuZXJhdGVkIGJ5IHRoaXMgb3BlcmF0aW9uIGlzIG9ubHkgdXNlZCB0byBkZWNsYXJlIHRoZSBkaXJlY3RpdmUncyB0eXBlIGFuZFxuICAgIC8vIHdvbid0IHJlcG9ydCBkaWFnbm9zdGljcyBieSBpdHNlbGYsIHNvIHRoZSBvcGVyYXRpb24gaXMgbWFya2VkIGFzIG9wdGlvbmFsIHRvIGF2b2lkXG4gICAgLy8gZ2VuZXJhdGluZyBkZWNsYXJhdGlvbnMgZm9yIGRpcmVjdGl2ZXMgdGhhdCBkb24ndCBoYXZlIGFueSBpbnB1dHMvb3V0cHV0cy5cbiAgICByZXR1cm4gdHJ1ZTtcbiAgfVxuXG4gIGV4ZWN1dGUoKTogdHMuSWRlbnRpZmllciB7XG4gICAgY29uc3QgZGlyUmVmID0gdGhpcy5kaXIucmVmIGFzIFJlZmVyZW5jZTxDbGFzc0RlY2xhcmF0aW9uPHRzLkNsYXNzRGVjbGFyYXRpb24+PjtcblxuICAgIGNvbnN0IHJhd1R5cGUgPSB0aGlzLnRjYi5lbnYucmVmZXJlbmNlVHlwZSh0aGlzLmRpci5yZWYpO1xuXG4gICAgbGV0IHR5cGU6IHRzLlR5cGVOb2RlO1xuICAgIGlmICh0aGlzLmRpci5pc0dlbmVyaWMgPT09IGZhbHNlIHx8IGRpclJlZi5ub2RlLnR5cGVQYXJhbWV0ZXJzID09PSB1bmRlZmluZWQpIHtcbiAgICAgIHR5cGUgPSByYXdUeXBlO1xuICAgIH0gZWxzZSB7XG4gICAgICBpZiAoIXRzLmlzVHlwZVJlZmVyZW5jZU5vZGUocmF3VHlwZSkpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKFxuICAgICAgICAgICAgYEV4cGVjdGVkIFR5cGVSZWZlcmVuY2VOb2RlIHdoZW4gcmVmZXJlbmNpbmcgdGhlIHR5cGUgZm9yICR7dGhpcy5kaXIucmVmLmRlYnVnTmFtZX1gKTtcbiAgICAgIH1cbiAgICAgIGNvbnN0IHR5cGVBcmd1bWVudHMgPSBkaXJSZWYubm9kZS50eXBlUGFyYW1ldGVycy5tYXAoXG4gICAgICAgICAgKCkgPT4gdHMuZmFjdG9yeS5jcmVhdGVLZXl3b3JkVHlwZU5vZGUodHMuU3ludGF4S2luZC5BbnlLZXl3b3JkKSk7XG4gICAgICB0eXBlID0gdHMuZmFjdG9yeS5jcmVhdGVUeXBlUmVmZXJlbmNlTm9kZShyYXdUeXBlLnR5cGVOYW1lLCB0eXBlQXJndW1lbnRzKTtcbiAgICB9XG5cbiAgICBjb25zdCBpZCA9IHRoaXMudGNiLmFsbG9jYXRlSWQoKTtcbiAgICBhZGRFeHByZXNzaW9uSWRlbnRpZmllcih0eXBlLCBFeHByZXNzaW9uSWRlbnRpZmllci5ESVJFQ1RJVkUpO1xuICAgIGFkZFBhcnNlU3BhbkluZm8odHlwZSwgdGhpcy5ub2RlLnN0YXJ0U291cmNlU3BhbiB8fCB0aGlzLm5vZGUuc291cmNlU3Bhbik7XG4gICAgdGhpcy5zY29wZS5hZGRTdGF0ZW1lbnQodHNEZWNsYXJlVmFyaWFibGUoaWQsIHR5cGUpKTtcbiAgICByZXR1cm4gaWQ7XG4gIH1cbn1cblxuLyoqXG4gKiBBIGBUY2JPcGAgd2hpY2ggY29uc3RydWN0cyBhbiBpbnN0YW5jZSBvZiBhIG5vbi1nZW5lcmljIGRpcmVjdGl2ZSBfd2l0aG91dF8gc2V0dGluZyBhbnkgb2YgaXRzXG4gKiBpbnB1dHMuIElucHV0cyAgYXJlIGxhdGVyIHNldCBpbiB0aGUgYFRjYkRpcmVjdGl2ZUlucHV0c09wYC4gVHlwZSBjaGVja2luZyB3YXMgZm91bmQgdG8gYmVcbiAqIGZhc3RlciB3aGVuIGRvbmUgaW4gdGhpcyB3YXkgYXMgb3Bwb3NlZCB0byBgVGNiRGlyZWN0aXZlQ3Rvck9wYCB3aGljaCBpcyBvbmx5IG5lY2Vzc2FyeSB3aGVuIHRoZVxuICogZGlyZWN0aXZlIGlzIGdlbmVyaWMuXG4gKlxuICogRXhlY3V0aW5nIHRoaXMgb3BlcmF0aW9uIHJldHVybnMgYSByZWZlcmVuY2UgdG8gdGhlIGRpcmVjdGl2ZSBpbnN0YW5jZSB2YXJpYWJsZSB3aXRoIGl0cyBpbmZlcnJlZFxuICogdHlwZS5cbiAqL1xuY2xhc3MgVGNiTm9uR2VuZXJpY0RpcmVjdGl2ZVR5cGVPcCBleHRlbmRzIFRjYkRpcmVjdGl2ZVR5cGVPcEJhc2Uge1xuICAvKipcbiAgICogQ3JlYXRlcyBhIHZhcmlhYmxlIGRlY2xhcmF0aW9uIGZvciB0aGlzIG9wJ3MgZGlyZWN0aXZlIG9mIHRoZSBhcmd1bWVudCB0eXBlLiBSZXR1cm5zIHRoZSBpZCBvZlxuICAgKiB0aGUgbmV3bHkgY3JlYXRlZCB2YXJpYWJsZS5cbiAgICovXG4gIGV4ZWN1dGUoKTogdHMuSWRlbnRpZmllciB7XG4gICAgY29uc3QgZGlyUmVmID0gdGhpcy5kaXIucmVmIGFzIFJlZmVyZW5jZTxDbGFzc0RlY2xhcmF0aW9uPHRzLkNsYXNzRGVjbGFyYXRpb24+PjtcbiAgICBpZiAodGhpcy5kaXIuaXNHZW5lcmljKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoYEFzc2VydGlvbiBFcnJvcjogZXhwZWN0ZWQgJHtkaXJSZWYuZGVidWdOYW1lfSBub3QgdG8gYmUgZ2VuZXJpYy5gKTtcbiAgICB9XG4gICAgcmV0dXJuIHN1cGVyLmV4ZWN1dGUoKTtcbiAgfVxufVxuXG4vKipcbiAqIEEgYFRjYk9wYCB3aGljaCBjb25zdHJ1Y3RzIGFuIGluc3RhbmNlIG9mIGEgZ2VuZXJpYyBkaXJlY3RpdmUgd2l0aCBpdHMgZ2VuZXJpYyBwYXJhbWV0ZXJzIHNldFxuICogdG8gYGFueWAgdHlwZS4gVGhpcyBvcCBpcyBsaWtlIGBUY2JEaXJlY3RpdmVUeXBlT3BgLCBleGNlcHQgdGhhdCBnZW5lcmljIHBhcmFtZXRlcnMgYXJlIHNldCB0b1xuICogYGFueWAgdHlwZS4gVGhpcyBpcyB1c2VkIGZvciBzaXR1YXRpb25zIHdoZXJlIHdlIHdhbnQgdG8gYXZvaWQgaW5saW5pbmcuXG4gKlxuICogRXhlY3V0aW5nIHRoaXMgb3BlcmF0aW9uIHJldHVybnMgYSByZWZlcmVuY2UgdG8gdGhlIGRpcmVjdGl2ZSBpbnN0YW5jZSB2YXJpYWJsZSB3aXRoIGl0cyBnZW5lcmljXG4gKiB0eXBlIHBhcmFtZXRlcnMgc2V0IHRvIGBhbnlgLlxuICovXG5jbGFzcyBUY2JHZW5lcmljRGlyZWN0aXZlVHlwZVdpdGhBbnlQYXJhbXNPcCBleHRlbmRzIFRjYkRpcmVjdGl2ZVR5cGVPcEJhc2Uge1xuICBleGVjdXRlKCk6IHRzLklkZW50aWZpZXIge1xuICAgIGNvbnN0IGRpclJlZiA9IHRoaXMuZGlyLnJlZiBhcyBSZWZlcmVuY2U8Q2xhc3NEZWNsYXJhdGlvbjx0cy5DbGFzc0RlY2xhcmF0aW9uPj47XG4gICAgaWYgKGRpclJlZi5ub2RlLnR5cGVQYXJhbWV0ZXJzID09PSB1bmRlZmluZWQpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihgQXNzZXJ0aW9uIEVycm9yOiBleHBlY3RlZCB0eXBlUGFyYW1ldGVycyB3aGVuIGNyZWF0aW5nIGEgZGVjbGFyYXRpb24gZm9yICR7XG4gICAgICAgICAgZGlyUmVmLmRlYnVnTmFtZX1gKTtcbiAgICB9XG5cbiAgICByZXR1cm4gc3VwZXIuZXhlY3V0ZSgpO1xuICB9XG59XG5cbi8qKlxuICogQSBgVGNiT3BgIHdoaWNoIGNyZWF0ZXMgYSB2YXJpYWJsZSBmb3IgYSBsb2NhbCByZWYgaW4gYSB0ZW1wbGF0ZS5cbiAqIFRoZSBpbml0aWFsaXplciBmb3IgdGhlIHZhcmlhYmxlIGlzIHRoZSB2YXJpYWJsZSBleHByZXNzaW9uIGZvciB0aGUgZGlyZWN0aXZlLCB0ZW1wbGF0ZSwgb3JcbiAqIGVsZW1lbnQgdGhlIHJlZiByZWZlcnMgdG8uIFdoZW4gdGhlIHJlZmVyZW5jZSBpcyB1c2VkIGluIHRoZSB0ZW1wbGF0ZSwgdGhvc2UgVENCIHN0YXRlbWVudHMgd2lsbFxuICogYWNjZXNzIHRoaXMgdmFyaWFibGUgYXMgd2VsbC4gRm9yIGV4YW1wbGU6XG4gKiBgYGBcbiAqIHZhciBfdDEgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdkaXYnKTtcbiAqIHZhciBfdDIgPSBfdDE7XG4gKiBfdDIudmFsdWVcbiAqIGBgYFxuICogVGhpcyBvcGVyYXRpb24gc3VwcG9ydHMgbW9yZSBmbHVlbnQgbG9va3VwcyBmb3IgdGhlIGBUZW1wbGF0ZVR5cGVDaGVja2VyYCB3aGVuIGdldHRpbmcgYSBzeW1ib2xcbiAqIGZvciBhIHJlZmVyZW5jZS4gSW4gbW9zdCBjYXNlcywgdGhpcyBpc24ndCBlc3NlbnRpYWw7IHRoYXQgaXMsIHRoZSBpbmZvcm1hdGlvbiBmb3IgdGhlIHN5bWJvbFxuICogY291bGQgYmUgZ2F0aGVyZWQgd2l0aG91dCB0aGlzIG9wZXJhdGlvbiB1c2luZyB0aGUgYEJvdW5kVGFyZ2V0YC4gSG93ZXZlciwgZm9yIHRoZSBjYXNlIG9mXG4gKiBuZy10ZW1wbGF0ZSByZWZlcmVuY2VzLCB3ZSB3aWxsIG5lZWQgdGhpcyByZWZlcmVuY2UgdmFyaWFibGUgdG8gbm90IG9ubHkgcHJvdmlkZSBhIGxvY2F0aW9uIGluXG4gKiB0aGUgc2hpbSBmaWxlLCBidXQgYWxzbyB0byBuYXJyb3cgdGhlIHZhcmlhYmxlIHRvIHRoZSBjb3JyZWN0IGBUZW1wbGF0ZVJlZjxUPmAgdHlwZSByYXRoZXIgdGhhblxuICogYFRlbXBsYXRlUmVmPGFueT5gICh0aGlzIHdvcmsgaXMgc3RpbGwgVE9ETykuXG4gKlxuICogRXhlY3V0aW5nIHRoaXMgb3BlcmF0aW9uIHJldHVybnMgYSByZWZlcmVuY2UgdG8gdGhlIGRpcmVjdGl2ZSBpbnN0YW5jZSB2YXJpYWJsZSB3aXRoIGl0cyBpbmZlcnJlZFxuICogdHlwZS5cbiAqL1xuY2xhc3MgVGNiUmVmZXJlbmNlT3AgZXh0ZW5kcyBUY2JPcCB7XG4gIGNvbnN0cnVjdG9yKFxuICAgICAgcHJpdmF0ZSByZWFkb25seSB0Y2I6IENvbnRleHQsIHByaXZhdGUgcmVhZG9ubHkgc2NvcGU6IFNjb3BlLFxuICAgICAgcHJpdmF0ZSByZWFkb25seSBub2RlOiBUbXBsQXN0UmVmZXJlbmNlLFxuICAgICAgcHJpdmF0ZSByZWFkb25seSBob3N0OiBUbXBsQXN0RWxlbWVudHxUbXBsQXN0VGVtcGxhdGUsXG4gICAgICBwcml2YXRlIHJlYWRvbmx5IHRhcmdldDogVHlwZUNoZWNrYWJsZURpcmVjdGl2ZU1ldGF8VG1wbEFzdFRlbXBsYXRlfFRtcGxBc3RFbGVtZW50KSB7XG4gICAgc3VwZXIoKTtcbiAgfVxuXG4gIC8vIFRoZSBzdGF0ZW1lbnQgZ2VuZXJhdGVkIGJ5IHRoaXMgb3BlcmF0aW9uIGlzIG9ubHkgdXNlZCB0byBmb3IgdGhlIFR5cGUgQ2hlY2tlclxuICAvLyBzbyBpdCBjYW4gbWFwIGEgcmVmZXJlbmNlIHZhcmlhYmxlIGluIHRoZSB0ZW1wbGF0ZSBkaXJlY3RseSB0byBhIG5vZGUgaW4gdGhlIFRDQi5cbiAgcmVhZG9ubHkgb3B0aW9uYWwgPSB0cnVlO1xuXG4gIGV4ZWN1dGUoKTogdHMuSWRlbnRpZmllciB7XG4gICAgY29uc3QgaWQgPSB0aGlzLnRjYi5hbGxvY2F0ZUlkKCk7XG4gICAgbGV0IGluaXRpYWxpemVyID1cbiAgICAgICAgdGhpcy50YXJnZXQgaW5zdGFuY2VvZiBUbXBsQXN0VGVtcGxhdGUgfHwgdGhpcy50YXJnZXQgaW5zdGFuY2VvZiBUbXBsQXN0RWxlbWVudCA/XG4gICAgICAgIHRoaXMuc2NvcGUucmVzb2x2ZSh0aGlzLnRhcmdldCkgOlxuICAgICAgICB0aGlzLnNjb3BlLnJlc29sdmUodGhpcy5ob3N0LCB0aGlzLnRhcmdldCk7XG5cbiAgICAvLyBUaGUgcmVmZXJlbmNlIGlzIGVpdGhlciB0byBhbiBlbGVtZW50LCBhbiA8bmctdGVtcGxhdGU+IG5vZGUsIG9yIHRvIGEgZGlyZWN0aXZlIG9uIGFuXG4gICAgLy8gZWxlbWVudCBvciB0ZW1wbGF0ZS5cbiAgICBpZiAoKHRoaXMudGFyZ2V0IGluc3RhbmNlb2YgVG1wbEFzdEVsZW1lbnQgJiYgIXRoaXMudGNiLmVudi5jb25maWcuY2hlY2tUeXBlT2ZEb21SZWZlcmVuY2VzKSB8fFxuICAgICAgICAhdGhpcy50Y2IuZW52LmNvbmZpZy5jaGVja1R5cGVPZk5vbkRvbVJlZmVyZW5jZXMpIHtcbiAgICAgIC8vIFJlZmVyZW5jZXMgdG8gRE9NIG5vZGVzIGFyZSBwaW5uZWQgdG8gJ2FueScgd2hlbiBgY2hlY2tUeXBlT2ZEb21SZWZlcmVuY2VzYCBpcyBgZmFsc2VgLlxuICAgICAgLy8gUmVmZXJlbmNlcyB0byBgVGVtcGxhdGVSZWZgcyBhbmQgZGlyZWN0aXZlcyBhcmUgcGlubmVkIHRvICdhbnknIHdoZW5cbiAgICAgIC8vIGBjaGVja1R5cGVPZk5vbkRvbVJlZmVyZW5jZXNgIGlzIGBmYWxzZWAuXG4gICAgICBpbml0aWFsaXplciA9XG4gICAgICAgICAgdHMuY3JlYXRlQXNFeHByZXNzaW9uKGluaXRpYWxpemVyLCB0cy5jcmVhdGVLZXl3b3JkVHlwZU5vZGUodHMuU3ludGF4S2luZC5BbnlLZXl3b3JkKSk7XG4gICAgfSBlbHNlIGlmICh0aGlzLnRhcmdldCBpbnN0YW5jZW9mIFRtcGxBc3RUZW1wbGF0ZSkge1xuICAgICAgLy8gRGlyZWN0IHJlZmVyZW5jZXMgdG8gYW4gPG5nLXRlbXBsYXRlPiBub2RlIHNpbXBseSByZXF1aXJlIGEgdmFsdWUgb2YgdHlwZVxuICAgICAgLy8gYFRlbXBsYXRlUmVmPGFueT5gLiBUbyBnZXQgdGhpcywgYW4gZXhwcmVzc2lvbiBvZiB0aGUgZm9ybVxuICAgICAgLy8gYChfdDEgYXMgYW55IGFzIFRlbXBsYXRlUmVmPGFueT4pYCBpcyBjb25zdHJ1Y3RlZC5cbiAgICAgIGluaXRpYWxpemVyID1cbiAgICAgICAgICB0cy5jcmVhdGVBc0V4cHJlc3Npb24oaW5pdGlhbGl6ZXIsIHRzLmNyZWF0ZUtleXdvcmRUeXBlTm9kZSh0cy5TeW50YXhLaW5kLkFueUtleXdvcmQpKTtcbiAgICAgIGluaXRpYWxpemVyID0gdHMuY3JlYXRlQXNFeHByZXNzaW9uKFxuICAgICAgICAgIGluaXRpYWxpemVyLFxuICAgICAgICAgIHRoaXMudGNiLmVudi5yZWZlcmVuY2VFeHRlcm5hbFR5cGUoJ0Bhbmd1bGFyL2NvcmUnLCAnVGVtcGxhdGVSZWYnLCBbRFlOQU1JQ19UWVBFXSkpO1xuICAgICAgaW5pdGlhbGl6ZXIgPSB0cy5jcmVhdGVQYXJlbihpbml0aWFsaXplcik7XG4gICAgfVxuICAgIGFkZFBhcnNlU3BhbkluZm8oaW5pdGlhbGl6ZXIsIHRoaXMubm9kZS5zb3VyY2VTcGFuKTtcbiAgICBhZGRQYXJzZVNwYW5JbmZvKGlkLCB0aGlzLm5vZGUua2V5U3Bhbik7XG5cbiAgICB0aGlzLnNjb3BlLmFkZFN0YXRlbWVudCh0c0NyZWF0ZVZhcmlhYmxlKGlkLCBpbml0aWFsaXplcikpO1xuICAgIHJldHVybiBpZDtcbiAgfVxufVxuXG4vKipcbiAqIEEgYFRjYk9wYCB3aGljaCBpcyB1c2VkIHdoZW4gdGhlIHRhcmdldCBvZiBhIHJlZmVyZW5jZSBpcyBtaXNzaW5nLiBUaGlzIG9wZXJhdGlvbiBnZW5lcmF0ZXMgYVxuICogdmFyaWFibGUgb2YgdHlwZSBhbnkgZm9yIHVzYWdlcyBvZiB0aGUgaW52YWxpZCByZWZlcmVuY2UgdG8gcmVzb2x2ZSB0by4gVGhlIGludmFsaWQgcmVmZXJlbmNlXG4gKiBpdHNlbGYgaXMgcmVjb3JkZWQgb3V0LW9mLWJhbmQuXG4gKi9cbmNsYXNzIFRjYkludmFsaWRSZWZlcmVuY2VPcCBleHRlbmRzIFRjYk9wIHtcbiAgY29uc3RydWN0b3IocHJpdmF0ZSByZWFkb25seSB0Y2I6IENvbnRleHQsIHByaXZhdGUgcmVhZG9ubHkgc2NvcGU6IFNjb3BlKSB7XG4gICAgc3VwZXIoKTtcbiAgfVxuXG4gIC8vIFRoZSBkZWNsYXJhdGlvbiBvZiBhIG1pc3NpbmcgcmVmZXJlbmNlIGlzIG9ubHkgbmVlZGVkIHdoZW4gdGhlIHJlZmVyZW5jZSBpcyByZXNvbHZlZC5cbiAgcmVhZG9ubHkgb3B0aW9uYWwgPSB0cnVlO1xuXG4gIGV4ZWN1dGUoKTogdHMuSWRlbnRpZmllciB7XG4gICAgY29uc3QgaWQgPSB0aGlzLnRjYi5hbGxvY2F0ZUlkKCk7XG4gICAgdGhpcy5zY29wZS5hZGRTdGF0ZW1lbnQodHNDcmVhdGVWYXJpYWJsZShpZCwgTlVMTF9BU19BTlkpKTtcbiAgICByZXR1cm4gaWQ7XG4gIH1cbn1cblxuLyoqXG4gKiBBIGBUY2JPcGAgd2hpY2ggY29uc3RydWN0cyBhbiBpbnN0YW5jZSBvZiBhIGRpcmVjdGl2ZSB3aXRoIHR5cGVzIGluZmVycmVkIGZyb20gaXRzIGlucHV0cy4gVGhlXG4gKiBpbnB1dHMgdGhlbXNlbHZlcyBhcmUgbm90IGNoZWNrZWQgaGVyZTsgY2hlY2tpbmcgb2YgaW5wdXRzIGlzIGFjaGlldmVkIGluIGBUY2JEaXJlY3RpdmVJbnB1dHNPcGAuXG4gKiBBbnkgZXJyb3JzIHJlcG9ydGVkIGluIHRoaXMgc3RhdGVtZW50IGFyZSBpZ25vcmVkLCBhcyB0aGUgdHlwZSBjb25zdHJ1Y3RvciBjYWxsIGlzIG9ubHkgcHJlc2VudFxuICogZm9yIHR5cGUtaW5mZXJlbmNlLlxuICpcbiAqIFdoZW4gYSBEaXJlY3RpdmUgaXMgZ2VuZXJpYywgaXQgaXMgcmVxdWlyZWQgdGhhdCB0aGUgVENCIGdlbmVyYXRlcyB0aGUgaW5zdGFuY2UgdXNpbmcgdGhpcyBtZXRob2RcbiAqIGluIG9yZGVyIHRvIGluZmVyIHRoZSB0eXBlIGluZm9ybWF0aW9uIGNvcnJlY3RseS5cbiAqXG4gKiBFeGVjdXRpbmcgdGhpcyBvcGVyYXRpb24gcmV0dXJucyBhIHJlZmVyZW5jZSB0byB0aGUgZGlyZWN0aXZlIGluc3RhbmNlIHZhcmlhYmxlIHdpdGggaXRzIGluZmVycmVkXG4gKiB0eXBlLlxuICovXG5jbGFzcyBUY2JEaXJlY3RpdmVDdG9yT3AgZXh0ZW5kcyBUY2JPcCB7XG4gIGNvbnN0cnVjdG9yKFxuICAgICAgcHJpdmF0ZSB0Y2I6IENvbnRleHQsIHByaXZhdGUgc2NvcGU6IFNjb3BlLCBwcml2YXRlIG5vZGU6IFRtcGxBc3RUZW1wbGF0ZXxUbXBsQXN0RWxlbWVudCxcbiAgICAgIHByaXZhdGUgZGlyOiBUeXBlQ2hlY2thYmxlRGlyZWN0aXZlTWV0YSkge1xuICAgIHN1cGVyKCk7XG4gIH1cblxuICBnZXQgb3B0aW9uYWwoKSB7XG4gICAgLy8gVGhlIHN0YXRlbWVudCBnZW5lcmF0ZWQgYnkgdGhpcyBvcGVyYXRpb24gaXMgb25seSB1c2VkIHRvIGluZmVyIHRoZSBkaXJlY3RpdmUncyB0eXBlIGFuZFxuICAgIC8vIHdvbid0IHJlcG9ydCBkaWFnbm9zdGljcyBieSBpdHNlbGYsIHNvIHRoZSBvcGVyYXRpb24gaXMgbWFya2VkIGFzIG9wdGlvbmFsLlxuICAgIHJldHVybiB0cnVlO1xuICB9XG5cbiAgZXhlY3V0ZSgpOiB0cy5JZGVudGlmaWVyIHtcbiAgICBjb25zdCBpZCA9IHRoaXMudGNiLmFsbG9jYXRlSWQoKTtcbiAgICBhZGRFeHByZXNzaW9uSWRlbnRpZmllcihpZCwgRXhwcmVzc2lvbklkZW50aWZpZXIuRElSRUNUSVZFKTtcbiAgICBhZGRQYXJzZVNwYW5JbmZvKGlkLCB0aGlzLm5vZGUuc3RhcnRTb3VyY2VTcGFuIHx8IHRoaXMubm9kZS5zb3VyY2VTcGFuKTtcblxuICAgIGNvbnN0IGdlbmVyaWNJbnB1dHMgPSBuZXcgTWFwPHN0cmluZywgVGNiRGlyZWN0aXZlSW5wdXQ+KCk7XG5cbiAgICBjb25zdCBpbnB1dHMgPSBnZXRCb3VuZElucHV0cyh0aGlzLmRpciwgdGhpcy5ub2RlLCB0aGlzLnRjYik7XG4gICAgZm9yIChjb25zdCBpbnB1dCBvZiBpbnB1dHMpIHtcbiAgICAgIC8vIFNraXAgdGV4dCBhdHRyaWJ1dGVzIGlmIGNvbmZpZ3VyZWQgdG8gZG8gc28uXG4gICAgICBpZiAoIXRoaXMudGNiLmVudi5jb25maWcuY2hlY2tUeXBlT2ZBdHRyaWJ1dGVzICYmXG4gICAgICAgICAgaW5wdXQuYXR0cmlidXRlIGluc3RhbmNlb2YgVG1wbEFzdFRleHRBdHRyaWJ1dGUpIHtcbiAgICAgICAgY29udGludWU7XG4gICAgICB9XG4gICAgICBmb3IgKGNvbnN0IGZpZWxkTmFtZSBvZiBpbnB1dC5maWVsZE5hbWVzKSB7XG4gICAgICAgIC8vIFNraXAgdGhlIGZpZWxkIGlmIGFuIGF0dHJpYnV0ZSBoYXMgYWxyZWFkeSBiZWVuIGJvdW5kIHRvIGl0OyB3ZSBjYW4ndCBoYXZlIGEgZHVwbGljYXRlXG4gICAgICAgIC8vIGtleSBpbiB0aGUgdHlwZSBjb25zdHJ1Y3RvciBjYWxsLlxuICAgICAgICBpZiAoZ2VuZXJpY0lucHV0cy5oYXMoZmllbGROYW1lKSkge1xuICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICB9XG5cbiAgICAgICAgY29uc3QgZXhwcmVzc2lvbiA9IHRyYW5zbGF0ZUlucHV0KGlucHV0LmF0dHJpYnV0ZSwgdGhpcy50Y2IsIHRoaXMuc2NvcGUpO1xuICAgICAgICBnZW5lcmljSW5wdXRzLnNldChmaWVsZE5hbWUsIHtcbiAgICAgICAgICB0eXBlOiAnYmluZGluZycsXG4gICAgICAgICAgZmllbGQ6IGZpZWxkTmFtZSxcbiAgICAgICAgICBleHByZXNzaW9uLFxuICAgICAgICAgIHNvdXJjZVNwYW46IGlucHV0LmF0dHJpYnV0ZS5zb3VyY2VTcGFuXG4gICAgICAgIH0pO1xuICAgICAgfVxuICAgIH1cblxuICAgIC8vIEFkZCB1bnNldCBkaXJlY3RpdmUgaW5wdXRzIGZvciBlYWNoIG9mIHRoZSByZW1haW5pbmcgdW5zZXQgZmllbGRzLlxuICAgIGZvciAoY29uc3QgW2ZpZWxkTmFtZV0gb2YgdGhpcy5kaXIuaW5wdXRzKSB7XG4gICAgICBpZiAoIWdlbmVyaWNJbnB1dHMuaGFzKGZpZWxkTmFtZSkpIHtcbiAgICAgICAgZ2VuZXJpY0lucHV0cy5zZXQoZmllbGROYW1lLCB7dHlwZTogJ3Vuc2V0JywgZmllbGQ6IGZpZWxkTmFtZX0pO1xuICAgICAgfVxuICAgIH1cblxuICAgIC8vIENhbGwgdGhlIHR5cGUgY29uc3RydWN0b3Igb2YgdGhlIGRpcmVjdGl2ZSB0byBpbmZlciBhIHR5cGUsIGFuZCBhc3NpZ24gdGhlIGRpcmVjdGl2ZVxuICAgIC8vIGluc3RhbmNlLlxuICAgIGNvbnN0IHR5cGVDdG9yID0gdGNiQ2FsbFR5cGVDdG9yKHRoaXMuZGlyLCB0aGlzLnRjYiwgQXJyYXkuZnJvbShnZW5lcmljSW5wdXRzLnZhbHVlcygpKSk7XG4gICAgbWFya0lnbm9yZURpYWdub3N0aWNzKHR5cGVDdG9yKTtcbiAgICB0aGlzLnNjb3BlLmFkZFN0YXRlbWVudCh0c0NyZWF0ZVZhcmlhYmxlKGlkLCB0eXBlQ3RvcikpO1xuICAgIHJldHVybiBpZDtcbiAgfVxuXG4gIGNpcmN1bGFyRmFsbGJhY2soKTogVGNiT3Age1xuICAgIHJldHVybiBuZXcgVGNiRGlyZWN0aXZlQ3RvckNpcmN1bGFyRmFsbGJhY2tPcCh0aGlzLnRjYiwgdGhpcy5zY29wZSwgdGhpcy5ub2RlLCB0aGlzLmRpcik7XG4gIH1cbn1cblxuLyoqXG4gKiBBIGBUY2JPcGAgd2hpY2ggZ2VuZXJhdGVzIGNvZGUgdG8gY2hlY2sgaW5wdXQgYmluZGluZ3Mgb24gYW4gZWxlbWVudCB0aGF0IGNvcnJlc3BvbmQgd2l0aCB0aGVcbiAqIG1lbWJlcnMgb2YgYSBkaXJlY3RpdmUuXG4gKlxuICogRXhlY3V0aW5nIHRoaXMgb3BlcmF0aW9uIHJldHVybnMgbm90aGluZy5cbiAqL1xuY2xhc3MgVGNiRGlyZWN0aXZlSW5wdXRzT3AgZXh0ZW5kcyBUY2JPcCB7XG4gIGNvbnN0cnVjdG9yKFxuICAgICAgcHJpdmF0ZSB0Y2I6IENvbnRleHQsIHByaXZhdGUgc2NvcGU6IFNjb3BlLCBwcml2YXRlIG5vZGU6IFRtcGxBc3RUZW1wbGF0ZXxUbXBsQXN0RWxlbWVudCxcbiAgICAgIHByaXZhdGUgZGlyOiBUeXBlQ2hlY2thYmxlRGlyZWN0aXZlTWV0YSkge1xuICAgIHN1cGVyKCk7XG4gIH1cblxuICBnZXQgb3B0aW9uYWwoKSB7XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG5cbiAgZXhlY3V0ZSgpOiBudWxsIHtcbiAgICBsZXQgZGlySWQ6IHRzLkV4cHJlc3Npb258bnVsbCA9IG51bGw7XG5cbiAgICAvLyBUT0RPKGpvb3N0KTogcmVwb3J0IGR1cGxpY2F0ZSBwcm9wZXJ0aWVzXG5cbiAgICBjb25zdCBpbnB1dHMgPSBnZXRCb3VuZElucHV0cyh0aGlzLmRpciwgdGhpcy5ub2RlLCB0aGlzLnRjYik7XG4gICAgZm9yIChjb25zdCBpbnB1dCBvZiBpbnB1dHMpIHtcbiAgICAgIC8vIEZvciBib3VuZCBpbnB1dHMsIHRoZSBwcm9wZXJ0eSBpcyBhc3NpZ25lZCB0aGUgYmluZGluZyBleHByZXNzaW9uLlxuICAgICAgbGV0IGV4cHIgPSB0cmFuc2xhdGVJbnB1dChpbnB1dC5hdHRyaWJ1dGUsIHRoaXMudGNiLCB0aGlzLnNjb3BlKTtcbiAgICAgIGlmICghdGhpcy50Y2IuZW52LmNvbmZpZy5jaGVja1R5cGVPZklucHV0QmluZGluZ3MpIHtcbiAgICAgICAgLy8gSWYgY2hlY2tpbmcgdGhlIHR5cGUgb2YgYmluZGluZ3MgaXMgZGlzYWJsZWQsIGNhc3QgdGhlIHJlc3VsdGluZyBleHByZXNzaW9uIHRvICdhbnknXG4gICAgICAgIC8vIGJlZm9yZSB0aGUgYXNzaWdubWVudC5cbiAgICAgICAgZXhwciA9IHRzQ2FzdFRvQW55KGV4cHIpO1xuICAgICAgfSBlbHNlIGlmICghdGhpcy50Y2IuZW52LmNvbmZpZy5zdHJpY3ROdWxsSW5wdXRCaW5kaW5ncykge1xuICAgICAgICAvLyBJZiBzdHJpY3QgbnVsbCBjaGVja3MgYXJlIGRpc2FibGVkLCBlcmFzZSBgbnVsbGAgYW5kIGB1bmRlZmluZWRgIGZyb20gdGhlIHR5cGUgYnlcbiAgICAgICAgLy8gd3JhcHBpbmcgdGhlIGV4cHJlc3Npb24gaW4gYSBub24tbnVsbCBhc3NlcnRpb24uXG4gICAgICAgIGV4cHIgPSB0cy5jcmVhdGVOb25OdWxsRXhwcmVzc2lvbihleHByKTtcbiAgICAgIH1cblxuICAgICAgbGV0IGFzc2lnbm1lbnQ6IHRzLkV4cHJlc3Npb24gPSB3cmFwRm9yRGlhZ25vc3RpY3MoZXhwcik7XG5cbiAgICAgIGZvciAoY29uc3QgZmllbGROYW1lIG9mIGlucHV0LmZpZWxkTmFtZXMpIHtcbiAgICAgICAgbGV0IHRhcmdldDogdHMuTGVmdEhhbmRTaWRlRXhwcmVzc2lvbjtcbiAgICAgICAgaWYgKHRoaXMuZGlyLmNvZXJjZWRJbnB1dEZpZWxkcy5oYXMoZmllbGROYW1lKSkge1xuICAgICAgICAgIC8vIFRoZSBpbnB1dCBoYXMgYSBjb2VyY2lvbiBkZWNsYXJhdGlvbiB3aGljaCBzaG91bGQgYmUgdXNlZCBpbnN0ZWFkIG9mIGFzc2lnbmluZyB0aGVcbiAgICAgICAgICAvLyBleHByZXNzaW9uIGludG8gdGhlIGlucHV0IGZpZWxkIGRpcmVjdGx5LiBUbyBhY2hpZXZlIHRoaXMsIGEgdmFyaWFibGUgaXMgZGVjbGFyZWRcbiAgICAgICAgICAvLyB3aXRoIGEgdHlwZSBvZiBgdHlwZW9mIERpcmVjdGl2ZS5uZ0FjY2VwdElucHV0VHlwZV9maWVsZE5hbWVgIHdoaWNoIGlzIHRoZW4gdXNlZCBhc1xuICAgICAgICAgIC8vIHRhcmdldCBvZiB0aGUgYXNzaWdubWVudC5cbiAgICAgICAgICBjb25zdCBkaXJUeXBlUmVmID0gdGhpcy50Y2IuZW52LnJlZmVyZW5jZVR5cGUodGhpcy5kaXIucmVmKTtcbiAgICAgICAgICBpZiAoIXRzLmlzVHlwZVJlZmVyZW5jZU5vZGUoZGlyVHlwZVJlZikpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihcbiAgICAgICAgICAgICAgICBgRXhwZWN0ZWQgVHlwZVJlZmVyZW5jZU5vZGUgZnJvbSByZWZlcmVuY2UgdG8gJHt0aGlzLmRpci5yZWYuZGVidWdOYW1lfWApO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIGNvbnN0IGlkID0gdGhpcy50Y2IuYWxsb2NhdGVJZCgpO1xuICAgICAgICAgIGNvbnN0IHR5cGUgPSB0c0NyZWF0ZVR5cGVRdWVyeUZvckNvZXJjZWRJbnB1dChkaXJUeXBlUmVmLnR5cGVOYW1lLCBmaWVsZE5hbWUpO1xuICAgICAgICAgIHRoaXMuc2NvcGUuYWRkU3RhdGVtZW50KHRzRGVjbGFyZVZhcmlhYmxlKGlkLCB0eXBlKSk7XG5cbiAgICAgICAgICB0YXJnZXQgPSBpZDtcbiAgICAgICAgfSBlbHNlIGlmICh0aGlzLmRpci51bmRlY2xhcmVkSW5wdXRGaWVsZHMuaGFzKGZpZWxkTmFtZSkpIHtcbiAgICAgICAgICAvLyBJZiBubyBjb2VyY2lvbiBkZWNsYXJhdGlvbiBpcyBwcmVzZW50IG5vciBpcyB0aGUgZmllbGQgZGVjbGFyZWQgKGkuZS4gdGhlIGlucHV0IGlzXG4gICAgICAgICAgLy8gZGVjbGFyZWQgaW4gYSBgQERpcmVjdGl2ZWAgb3IgYEBDb21wb25lbnRgIGRlY29yYXRvcidzIGBpbnB1dHNgIHByb3BlcnR5KSB0aGVyZSBpcyBub1xuICAgICAgICAgIC8vIGFzc2lnbm1lbnQgdGFyZ2V0IGF2YWlsYWJsZSwgc28gdGhpcyBmaWVsZCBpcyBza2lwcGVkLlxuICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICB9IGVsc2UgaWYgKFxuICAgICAgICAgICAgIXRoaXMudGNiLmVudi5jb25maWcuaG9ub3JBY2Nlc3NNb2RpZmllcnNGb3JJbnB1dEJpbmRpbmdzICYmXG4gICAgICAgICAgICB0aGlzLmRpci5yZXN0cmljdGVkSW5wdXRGaWVsZHMuaGFzKGZpZWxkTmFtZSkpIHtcbiAgICAgICAgICAvLyBJZiBzdHJpY3QgY2hlY2tpbmcgb2YgYWNjZXNzIG1vZGlmaWVycyBpcyBkaXNhYmxlZCBhbmQgdGhlIGZpZWxkIGlzIHJlc3RyaWN0ZWRcbiAgICAgICAgICAvLyAoaS5lLiBwcml2YXRlL3Byb3RlY3RlZC9yZWFkb25seSksIGdlbmVyYXRlIGFuIGFzc2lnbm1lbnQgaW50byBhIHRlbXBvcmFyeSB2YXJpYWJsZVxuICAgICAgICAgIC8vIHRoYXQgaGFzIHRoZSB0eXBlIG9mIHRoZSBmaWVsZC4gVGhpcyBhY2hpZXZlcyB0eXBlLWNoZWNraW5nIGJ1dCBjaXJjdW12ZW50cyB0aGUgYWNjZXNzXG4gICAgICAgICAgLy8gbW9kaWZpZXJzLlxuICAgICAgICAgIGlmIChkaXJJZCA9PT0gbnVsbCkge1xuICAgICAgICAgICAgZGlySWQgPSB0aGlzLnNjb3BlLnJlc29sdmUodGhpcy5ub2RlLCB0aGlzLmRpcik7XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgY29uc3QgaWQgPSB0aGlzLnRjYi5hbGxvY2F0ZUlkKCk7XG4gICAgICAgICAgY29uc3QgZGlyVHlwZVJlZiA9IHRoaXMudGNiLmVudi5yZWZlcmVuY2VUeXBlKHRoaXMuZGlyLnJlZik7XG4gICAgICAgICAgaWYgKCF0cy5pc1R5cGVSZWZlcmVuY2VOb2RlKGRpclR5cGVSZWYpKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXG4gICAgICAgICAgICAgICAgYEV4cGVjdGVkIFR5cGVSZWZlcmVuY2VOb2RlIGZyb20gcmVmZXJlbmNlIHRvICR7dGhpcy5kaXIucmVmLmRlYnVnTmFtZX1gKTtcbiAgICAgICAgICB9XG4gICAgICAgICAgY29uc3QgdHlwZSA9IHRzLmNyZWF0ZUluZGV4ZWRBY2Nlc3NUeXBlTm9kZShcbiAgICAgICAgICAgICAgdHMuY3JlYXRlVHlwZVF1ZXJ5Tm9kZShkaXJJZCBhcyB0cy5JZGVudGlmaWVyKSxcbiAgICAgICAgICAgICAgdHMuY3JlYXRlTGl0ZXJhbFR5cGVOb2RlKHRzLmNyZWF0ZVN0cmluZ0xpdGVyYWwoZmllbGROYW1lKSkpO1xuICAgICAgICAgIGNvbnN0IHRlbXAgPSB0c0RlY2xhcmVWYXJpYWJsZShpZCwgdHlwZSk7XG4gICAgICAgICAgdGhpcy5zY29wZS5hZGRTdGF0ZW1lbnQodGVtcCk7XG4gICAgICAgICAgdGFyZ2V0ID0gaWQ7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgaWYgKGRpcklkID09PSBudWxsKSB7XG4gICAgICAgICAgICBkaXJJZCA9IHRoaXMuc2NvcGUucmVzb2x2ZSh0aGlzLm5vZGUsIHRoaXMuZGlyKTtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICAvLyBUbyBnZXQgZXJyb3JzIGFzc2lnbiBkaXJlY3RseSB0byB0aGUgZmllbGRzIG9uIHRoZSBpbnN0YW5jZSwgdXNpbmcgcHJvcGVydHkgYWNjZXNzXG4gICAgICAgICAgLy8gd2hlbiBwb3NzaWJsZS4gU3RyaW5nIGxpdGVyYWwgZmllbGRzIG1heSBub3QgYmUgdmFsaWQgSlMgaWRlbnRpZmllcnMgc28gd2UgdXNlXG4gICAgICAgICAgLy8gbGl0ZXJhbCBlbGVtZW50IGFjY2VzcyBpbnN0ZWFkIGZvciB0aG9zZSBjYXNlcy5cbiAgICAgICAgICB0YXJnZXQgPSB0aGlzLmRpci5zdHJpbmdMaXRlcmFsSW5wdXRGaWVsZHMuaGFzKGZpZWxkTmFtZSkgP1xuICAgICAgICAgICAgICB0cy5jcmVhdGVFbGVtZW50QWNjZXNzKGRpcklkLCB0cy5jcmVhdGVTdHJpbmdMaXRlcmFsKGZpZWxkTmFtZSkpIDpcbiAgICAgICAgICAgICAgdHMuY3JlYXRlUHJvcGVydHlBY2Nlc3MoZGlySWQsIHRzLmNyZWF0ZUlkZW50aWZpZXIoZmllbGROYW1lKSk7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoaW5wdXQuYXR0cmlidXRlLmtleVNwYW4gIT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgIGFkZFBhcnNlU3BhbkluZm8odGFyZ2V0LCBpbnB1dC5hdHRyaWJ1dGUua2V5U3Bhbik7XG4gICAgICAgIH1cbiAgICAgICAgLy8gRmluYWxseSB0aGUgYXNzaWdubWVudCBpcyBleHRlbmRlZCBieSBhc3NpZ25pbmcgaXQgaW50byB0aGUgdGFyZ2V0IGV4cHJlc3Npb24uXG4gICAgICAgIGFzc2lnbm1lbnQgPSB0cy5jcmVhdGVCaW5hcnkodGFyZ2V0LCB0cy5TeW50YXhLaW5kLkVxdWFsc1Rva2VuLCBhc3NpZ25tZW50KTtcbiAgICAgIH1cblxuICAgICAgYWRkUGFyc2VTcGFuSW5mbyhhc3NpZ25tZW50LCBpbnB1dC5hdHRyaWJ1dGUuc291cmNlU3Bhbik7XG4gICAgICAvLyBJZ25vcmUgZGlhZ25vc3RpY3MgZm9yIHRleHQgYXR0cmlidXRlcyBpZiBjb25maWd1cmVkIHRvIGRvIHNvLlxuICAgICAgaWYgKCF0aGlzLnRjYi5lbnYuY29uZmlnLmNoZWNrVHlwZU9mQXR0cmlidXRlcyAmJlxuICAgICAgICAgIGlucHV0LmF0dHJpYnV0ZSBpbnN0YW5jZW9mIFRtcGxBc3RUZXh0QXR0cmlidXRlKSB7XG4gICAgICAgIG1hcmtJZ25vcmVEaWFnbm9zdGljcyhhc3NpZ25tZW50KTtcbiAgICAgIH1cblxuICAgICAgdGhpcy5zY29wZS5hZGRTdGF0ZW1lbnQodHMuY3JlYXRlRXhwcmVzc2lvblN0YXRlbWVudChhc3NpZ25tZW50KSk7XG4gICAgfVxuXG4gICAgcmV0dXJuIG51bGw7XG4gIH1cbn1cblxuLyoqXG4gKiBBIGBUY2JPcGAgd2hpY2ggaXMgdXNlZCB0byBnZW5lcmF0ZSBhIGZhbGxiYWNrIGV4cHJlc3Npb24gaWYgdGhlIGluZmVyZW5jZSBvZiBhIGRpcmVjdGl2ZSB0eXBlXG4gKiB2aWEgYFRjYkRpcmVjdGl2ZUN0b3JPcGAgcmVxdWlyZXMgYSByZWZlcmVuY2UgdG8gaXRzIG93biB0eXBlLiBUaGlzIGNhbiBoYXBwZW4gdXNpbmcgYSB0ZW1wbGF0ZVxuICogcmVmZXJlbmNlOlxuICpcbiAqIGBgYGh0bWxcbiAqIDxzb21lLWNtcCAjcmVmIFtwcm9wXT1cInJlZi5mb29cIj48L3NvbWUtY21wPlxuICogYGBgXG4gKlxuICogSW4gdGhpcyBjYXNlLCBgVGNiRGlyZWN0aXZlQ3RvckNpcmN1bGFyRmFsbGJhY2tPcGAgd2lsbCBhZGQgYSBzZWNvbmQgaW5mZXJlbmNlIG9mIHRoZSBkaXJlY3RpdmVcbiAqIHR5cGUgdG8gdGhlIHR5cGUtY2hlY2sgYmxvY2ssIHRoaXMgdGltZSBjYWxsaW5nIHRoZSBkaXJlY3RpdmUncyB0eXBlIGNvbnN0cnVjdG9yIHdpdGhvdXQgYW55XG4gKiBpbnB1dCBleHByZXNzaW9ucy4gVGhpcyBpbmZlcnMgdGhlIHdpZGVzdCBwb3NzaWJsZSBzdXBlcnR5cGUgZm9yIHRoZSBkaXJlY3RpdmUsIHdoaWNoIGlzIHVzZWQgdG9cbiAqIHJlc29sdmUgYW55IHJlY3Vyc2l2ZSByZWZlcmVuY2VzIHJlcXVpcmVkIHRvIGluZmVyIHRoZSByZWFsIHR5cGUuXG4gKi9cbmNsYXNzIFRjYkRpcmVjdGl2ZUN0b3JDaXJjdWxhckZhbGxiYWNrT3AgZXh0ZW5kcyBUY2JPcCB7XG4gIGNvbnN0cnVjdG9yKFxuICAgICAgcHJpdmF0ZSB0Y2I6IENvbnRleHQsIHByaXZhdGUgc2NvcGU6IFNjb3BlLCBwcml2YXRlIG5vZGU6IFRtcGxBc3RUZW1wbGF0ZXxUbXBsQXN0RWxlbWVudCxcbiAgICAgIHByaXZhdGUgZGlyOiBUeXBlQ2hlY2thYmxlRGlyZWN0aXZlTWV0YSkge1xuICAgIHN1cGVyKCk7XG4gIH1cblxuICBnZXQgb3B0aW9uYWwoKSB7XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG5cbiAgZXhlY3V0ZSgpOiB0cy5JZGVudGlmaWVyIHtcbiAgICBjb25zdCBpZCA9IHRoaXMudGNiLmFsbG9jYXRlSWQoKTtcbiAgICBjb25zdCB0eXBlQ3RvciA9IHRoaXMudGNiLmVudi50eXBlQ3RvckZvcih0aGlzLmRpcik7XG4gICAgY29uc3QgY2lyY3VsYXJQbGFjZWhvbGRlciA9IHRzLmNyZWF0ZUNhbGwoXG4gICAgICAgIHR5cGVDdG9yLCAvKiB0eXBlQXJndW1lbnRzICovIHVuZGVmaW5lZCwgW3RzLmNyZWF0ZU5vbk51bGxFeHByZXNzaW9uKHRzLmNyZWF0ZU51bGwoKSldKTtcbiAgICB0aGlzLnNjb3BlLmFkZFN0YXRlbWVudCh0c0NyZWF0ZVZhcmlhYmxlKGlkLCBjaXJjdWxhclBsYWNlaG9sZGVyKSk7XG4gICAgcmV0dXJuIGlkO1xuICB9XG59XG5cbi8qKlxuICogQSBgVGNiT3BgIHdoaWNoIGZlZWRzIGVsZW1lbnRzIGFuZCB1bmNsYWltZWQgcHJvcGVydGllcyB0byB0aGUgYERvbVNjaGVtYUNoZWNrZXJgLlxuICpcbiAqIFRoZSBET00gc2NoZW1hIGlzIG5vdCBjaGVja2VkIHZpYSBUQ0IgY29kZSBnZW5lcmF0aW9uLiBJbnN0ZWFkLCB0aGUgYERvbVNjaGVtYUNoZWNrZXJgIGluZ2VzdHNcbiAqIGVsZW1lbnRzIGFuZCBwcm9wZXJ0eSBiaW5kaW5ncyBhbmQgYWNjdW11bGF0ZXMgc3ludGhldGljIGB0cy5EaWFnbm9zdGljYHMgb3V0LW9mLWJhbmQuIFRoZXNlIGFyZVxuICogbGF0ZXIgbWVyZ2VkIHdpdGggdGhlIGRpYWdub3N0aWNzIGdlbmVyYXRlZCBmcm9tIHRoZSBUQ0IuXG4gKlxuICogRm9yIGNvbnZlbmllbmNlLCB0aGUgVENCIGl0ZXJhdGlvbiBvZiB0aGUgdGVtcGxhdGUgaXMgdXNlZCB0byBkcml2ZSB0aGUgYERvbVNjaGVtYUNoZWNrZXJgIHZpYVxuICogdGhlIGBUY2JEb21TY2hlbWFDaGVja2VyT3BgLlxuICovXG5jbGFzcyBUY2JEb21TY2hlbWFDaGVja2VyT3AgZXh0ZW5kcyBUY2JPcCB7XG4gIGNvbnN0cnVjdG9yKFxuICAgICAgcHJpdmF0ZSB0Y2I6IENvbnRleHQsIHByaXZhdGUgZWxlbWVudDogVG1wbEFzdEVsZW1lbnQsIHByaXZhdGUgY2hlY2tFbGVtZW50OiBib29sZWFuLFxuICAgICAgcHJpdmF0ZSBjbGFpbWVkSW5wdXRzOiBTZXQ8c3RyaW5nPikge1xuICAgIHN1cGVyKCk7XG4gIH1cblxuICBnZXQgb3B0aW9uYWwoKSB7XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG5cbiAgZXhlY3V0ZSgpOiB0cy5FeHByZXNzaW9ufG51bGwge1xuICAgIGlmICh0aGlzLmNoZWNrRWxlbWVudCkge1xuICAgICAgdGhpcy50Y2IuZG9tU2NoZW1hQ2hlY2tlci5jaGVja0VsZW1lbnQodGhpcy50Y2IuaWQsIHRoaXMuZWxlbWVudCwgdGhpcy50Y2Iuc2NoZW1hcyk7XG4gICAgfVxuXG4gICAgLy8gVE9ETyhhbHhodWIpOiB0aGlzIGNvdWxkIGJlIG1vcmUgZWZmaWNpZW50LlxuICAgIGZvciAoY29uc3QgYmluZGluZyBvZiB0aGlzLmVsZW1lbnQuaW5wdXRzKSB7XG4gICAgICBpZiAoYmluZGluZy50eXBlID09PSBCaW5kaW5nVHlwZS5Qcm9wZXJ0eSAmJiB0aGlzLmNsYWltZWRJbnB1dHMuaGFzKGJpbmRpbmcubmFtZSkpIHtcbiAgICAgICAgLy8gU2tpcCB0aGlzIGJpbmRpbmcgYXMgaXQgd2FzIGNsYWltZWQgYnkgYSBkaXJlY3RpdmUuXG4gICAgICAgIGNvbnRpbnVlO1xuICAgICAgfVxuXG4gICAgICBpZiAoYmluZGluZy50eXBlID09PSBCaW5kaW5nVHlwZS5Qcm9wZXJ0eSkge1xuICAgICAgICBpZiAoYmluZGluZy5uYW1lICE9PSAnc3R5bGUnICYmIGJpbmRpbmcubmFtZSAhPT0gJ2NsYXNzJykge1xuICAgICAgICAgIC8vIEEgZGlyZWN0IGJpbmRpbmcgdG8gYSBwcm9wZXJ0eS5cbiAgICAgICAgICBjb25zdCBwcm9wZXJ0eU5hbWUgPSBBVFRSX1RPX1BST1BbYmluZGluZy5uYW1lXSB8fCBiaW5kaW5nLm5hbWU7XG4gICAgICAgICAgdGhpcy50Y2IuZG9tU2NoZW1hQ2hlY2tlci5jaGVja1Byb3BlcnR5KFxuICAgICAgICAgICAgICB0aGlzLnRjYi5pZCwgdGhpcy5lbGVtZW50LCBwcm9wZXJ0eU5hbWUsIGJpbmRpbmcuc291cmNlU3BhbiwgdGhpcy50Y2Iuc2NoZW1hcyk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIG51bGw7XG4gIH1cbn1cblxuXG4vKipcbiAqIE1hcHBpbmcgYmV0d2VlbiBhdHRyaWJ1dGVzIG5hbWVzIHRoYXQgZG9uJ3QgY29ycmVzcG9uZCB0byB0aGVpciBlbGVtZW50IHByb3BlcnR5IG5hbWVzLlxuICogTm90ZTogdGhpcyBtYXBwaW5nIGhhcyB0byBiZSBrZXB0IGluIHN5bmMgd2l0aCB0aGUgZXF1YWxseSBuYW1lZCBtYXBwaW5nIGluIHRoZSBydW50aW1lLlxuICovXG5jb25zdCBBVFRSX1RPX1BST1A6IHtbbmFtZTogc3RyaW5nXTogc3RyaW5nfSA9IHtcbiAgJ2NsYXNzJzogJ2NsYXNzTmFtZScsXG4gICdmb3InOiAnaHRtbEZvcicsXG4gICdmb3JtYWN0aW9uJzogJ2Zvcm1BY3Rpb24nLFxuICAnaW5uZXJIdG1sJzogJ2lubmVySFRNTCcsXG4gICdyZWFkb25seSc6ICdyZWFkT25seScsXG4gICd0YWJpbmRleCc6ICd0YWJJbmRleCcsXG59O1xuXG4vKipcbiAqIEEgYFRjYk9wYCB3aGljaCBnZW5lcmF0ZXMgY29kZSB0byBjaGVjayBcInVuY2xhaW1lZCBpbnB1dHNcIiAtIGJpbmRpbmdzIG9uIGFuIGVsZW1lbnQgd2hpY2ggd2VyZVxuICogbm90IGF0dHJpYnV0ZWQgdG8gYW55IGRpcmVjdGl2ZSBvciBjb21wb25lbnQsIGFuZCBhcmUgaW5zdGVhZCBwcm9jZXNzZWQgYWdhaW5zdCB0aGUgSFRNTCBlbGVtZW50XG4gKiBpdHNlbGYuXG4gKlxuICogQ3VycmVudGx5LCBvbmx5IHRoZSBleHByZXNzaW9ucyBvZiB0aGVzZSBiaW5kaW5ncyBhcmUgY2hlY2tlZC4gVGhlIHRhcmdldHMgb2YgdGhlIGJpbmRpbmdzIGFyZVxuICogY2hlY2tlZCBhZ2FpbnN0IHRoZSBET00gc2NoZW1hIHZpYSBhIGBUY2JEb21TY2hlbWFDaGVja2VyT3BgLlxuICpcbiAqIEV4ZWN1dGluZyB0aGlzIG9wZXJhdGlvbiByZXR1cm5zIG5vdGhpbmcuXG4gKi9cbmNsYXNzIFRjYlVuY2xhaW1lZElucHV0c09wIGV4dGVuZHMgVGNiT3Age1xuICBjb25zdHJ1Y3RvcihcbiAgICAgIHByaXZhdGUgdGNiOiBDb250ZXh0LCBwcml2YXRlIHNjb3BlOiBTY29wZSwgcHJpdmF0ZSBlbGVtZW50OiBUbXBsQXN0RWxlbWVudCxcbiAgICAgIHByaXZhdGUgY2xhaW1lZElucHV0czogU2V0PHN0cmluZz4pIHtcbiAgICBzdXBlcigpO1xuICB9XG5cbiAgZ2V0IG9wdGlvbmFsKCkge1xuICAgIHJldHVybiBmYWxzZTtcbiAgfVxuXG4gIGV4ZWN1dGUoKTogbnVsbCB7XG4gICAgLy8gYHRoaXMuaW5wdXRzYCBjb250YWlucyBvbmx5IHRob3NlIGJpbmRpbmdzIG5vdCBtYXRjaGVkIGJ5IGFueSBkaXJlY3RpdmUuIFRoZXNlIGJpbmRpbmdzIGdvIHRvXG4gICAgLy8gdGhlIGVsZW1lbnQgaXRzZWxmLlxuICAgIGxldCBlbElkOiB0cy5FeHByZXNzaW9ufG51bGwgPSBudWxsO1xuXG4gICAgLy8gVE9ETyhhbHhodWIpOiB0aGlzIGNvdWxkIGJlIG1vcmUgZWZmaWNpZW50LlxuICAgIGZvciAoY29uc3QgYmluZGluZyBvZiB0aGlzLmVsZW1lbnQuaW5wdXRzKSB7XG4gICAgICBpZiAoYmluZGluZy50eXBlID09PSBCaW5kaW5nVHlwZS5Qcm9wZXJ0eSAmJiB0aGlzLmNsYWltZWRJbnB1dHMuaGFzKGJpbmRpbmcubmFtZSkpIHtcbiAgICAgICAgLy8gU2tpcCB0aGlzIGJpbmRpbmcgYXMgaXQgd2FzIGNsYWltZWQgYnkgYSBkaXJlY3RpdmUuXG4gICAgICAgIGNvbnRpbnVlO1xuICAgICAgfVxuXG4gICAgICBsZXQgZXhwciA9IHRjYkV4cHJlc3Npb24oYmluZGluZy52YWx1ZSwgdGhpcy50Y2IsIHRoaXMuc2NvcGUpO1xuICAgICAgaWYgKCF0aGlzLnRjYi5lbnYuY29uZmlnLmNoZWNrVHlwZU9mSW5wdXRCaW5kaW5ncykge1xuICAgICAgICAvLyBJZiBjaGVja2luZyB0aGUgdHlwZSBvZiBiaW5kaW5ncyBpcyBkaXNhYmxlZCwgY2FzdCB0aGUgcmVzdWx0aW5nIGV4cHJlc3Npb24gdG8gJ2FueSdcbiAgICAgICAgLy8gYmVmb3JlIHRoZSBhc3NpZ25tZW50LlxuICAgICAgICBleHByID0gdHNDYXN0VG9BbnkoZXhwcik7XG4gICAgICB9IGVsc2UgaWYgKCF0aGlzLnRjYi5lbnYuY29uZmlnLnN0cmljdE51bGxJbnB1dEJpbmRpbmdzKSB7XG4gICAgICAgIC8vIElmIHN0cmljdCBudWxsIGNoZWNrcyBhcmUgZGlzYWJsZWQsIGVyYXNlIGBudWxsYCBhbmQgYHVuZGVmaW5lZGAgZnJvbSB0aGUgdHlwZSBieVxuICAgICAgICAvLyB3cmFwcGluZyB0aGUgZXhwcmVzc2lvbiBpbiBhIG5vbi1udWxsIGFzc2VydGlvbi5cbiAgICAgICAgZXhwciA9IHRzLmNyZWF0ZU5vbk51bGxFeHByZXNzaW9uKGV4cHIpO1xuICAgICAgfVxuXG4gICAgICBpZiAodGhpcy50Y2IuZW52LmNvbmZpZy5jaGVja1R5cGVPZkRvbUJpbmRpbmdzICYmIGJpbmRpbmcudHlwZSA9PT0gQmluZGluZ1R5cGUuUHJvcGVydHkpIHtcbiAgICAgICAgaWYgKGJpbmRpbmcubmFtZSAhPT0gJ3N0eWxlJyAmJiBiaW5kaW5nLm5hbWUgIT09ICdjbGFzcycpIHtcbiAgICAgICAgICBpZiAoZWxJZCA9PT0gbnVsbCkge1xuICAgICAgICAgICAgZWxJZCA9IHRoaXMuc2NvcGUucmVzb2x2ZSh0aGlzLmVsZW1lbnQpO1xuICAgICAgICAgIH1cbiAgICAgICAgICAvLyBBIGRpcmVjdCBiaW5kaW5nIHRvIGEgcHJvcGVydHkuXG4gICAgICAgICAgY29uc3QgcHJvcGVydHlOYW1lID0gQVRUUl9UT19QUk9QW2JpbmRpbmcubmFtZV0gfHwgYmluZGluZy5uYW1lO1xuICAgICAgICAgIGNvbnN0IHByb3AgPSB0cy5jcmVhdGVFbGVtZW50QWNjZXNzKGVsSWQsIHRzLmNyZWF0ZVN0cmluZ0xpdGVyYWwocHJvcGVydHlOYW1lKSk7XG4gICAgICAgICAgY29uc3Qgc3RtdCA9IHRzLmNyZWF0ZUJpbmFyeShwcm9wLCB0cy5TeW50YXhLaW5kLkVxdWFsc1Rva2VuLCB3cmFwRm9yRGlhZ25vc3RpY3MoZXhwcikpO1xuICAgICAgICAgIGFkZFBhcnNlU3BhbkluZm8oc3RtdCwgYmluZGluZy5zb3VyY2VTcGFuKTtcbiAgICAgICAgICB0aGlzLnNjb3BlLmFkZFN0YXRlbWVudCh0cy5jcmVhdGVFeHByZXNzaW9uU3RhdGVtZW50KHN0bXQpKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICB0aGlzLnNjb3BlLmFkZFN0YXRlbWVudCh0cy5jcmVhdGVFeHByZXNzaW9uU3RhdGVtZW50KGV4cHIpKTtcbiAgICAgICAgfVxuICAgICAgfSBlbHNlIHtcbiAgICAgICAgLy8gQSBiaW5kaW5nIHRvIGFuIGFuaW1hdGlvbiwgYXR0cmlidXRlLCBjbGFzcyBvciBzdHlsZS4gRm9yIG5vdywgb25seSB2YWxpZGF0ZSB0aGUgcmlnaHQtXG4gICAgICAgIC8vIGhhbmQgc2lkZSBvZiB0aGUgZXhwcmVzc2lvbi5cbiAgICAgICAgLy8gVE9ETzogcHJvcGVybHkgY2hlY2sgY2xhc3MgYW5kIHN0eWxlIGJpbmRpbmdzLlxuICAgICAgICB0aGlzLnNjb3BlLmFkZFN0YXRlbWVudCh0cy5jcmVhdGVFeHByZXNzaW9uU3RhdGVtZW50KGV4cHIpKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICByZXR1cm4gbnVsbDtcbiAgfVxufVxuXG4vKipcbiAqIEEgYFRjYk9wYCB3aGljaCBnZW5lcmF0ZXMgY29kZSB0byBjaGVjayBldmVudCBiaW5kaW5ncyBvbiBhbiBlbGVtZW50IHRoYXQgY29ycmVzcG9uZCB3aXRoIHRoZVxuICogb3V0cHV0cyBvZiBhIGRpcmVjdGl2ZS5cbiAqXG4gKiBFeGVjdXRpbmcgdGhpcyBvcGVyYXRpb24gcmV0dXJucyBub3RoaW5nLlxuICovXG5leHBvcnQgY2xhc3MgVGNiRGlyZWN0aXZlT3V0cHV0c09wIGV4dGVuZHMgVGNiT3Age1xuICBjb25zdHJ1Y3RvcihcbiAgICAgIHByaXZhdGUgdGNiOiBDb250ZXh0LCBwcml2YXRlIHNjb3BlOiBTY29wZSwgcHJpdmF0ZSBub2RlOiBUbXBsQXN0VGVtcGxhdGV8VG1wbEFzdEVsZW1lbnQsXG4gICAgICBwcml2YXRlIGRpcjogVHlwZUNoZWNrYWJsZURpcmVjdGl2ZU1ldGEpIHtcbiAgICBzdXBlcigpO1xuICB9XG5cbiAgZ2V0IG9wdGlvbmFsKCkge1xuICAgIHJldHVybiBmYWxzZTtcbiAgfVxuXG4gIGV4ZWN1dGUoKTogbnVsbCB7XG4gICAgbGV0IGRpcklkOiB0cy5FeHByZXNzaW9ufG51bGwgPSBudWxsO1xuICAgIGNvbnN0IG91dHB1dHMgPSB0aGlzLmRpci5vdXRwdXRzO1xuXG4gICAgZm9yIChjb25zdCBvdXRwdXQgb2YgdGhpcy5ub2RlLm91dHB1dHMpIHtcbiAgICAgIGlmIChvdXRwdXQudHlwZSAhPT0gUGFyc2VkRXZlbnRUeXBlLlJlZ3VsYXIgfHwgIW91dHB1dHMuaGFzQmluZGluZ1Byb3BlcnR5TmFtZShvdXRwdXQubmFtZSkpIHtcbiAgICAgICAgY29udGludWU7XG4gICAgICB9XG4gICAgICAvLyBUT0RPKGFseGh1Yik6IGNvbnNpZGVyIHN1cHBvcnRpbmcgbXVsdGlwbGUgZmllbGRzIHdpdGggdGhlIHNhbWUgcHJvcGVydHkgbmFtZSBmb3Igb3V0cHV0cy5cbiAgICAgIGNvbnN0IGZpZWxkID0gb3V0cHV0cy5nZXRCeUJpbmRpbmdQcm9wZXJ0eU5hbWUob3V0cHV0Lm5hbWUpIVswXS5jbGFzc1Byb3BlcnR5TmFtZTtcblxuICAgICAgaWYgKGRpcklkID09PSBudWxsKSB7XG4gICAgICAgIGRpcklkID0gdGhpcy5zY29wZS5yZXNvbHZlKHRoaXMubm9kZSwgdGhpcy5kaXIpO1xuICAgICAgfVxuICAgICAgY29uc3Qgb3V0cHV0RmllbGQgPSB0cy5jcmVhdGVFbGVtZW50QWNjZXNzKGRpcklkLCB0cy5jcmVhdGVTdHJpbmdMaXRlcmFsKGZpZWxkKSk7XG4gICAgICBhZGRQYXJzZVNwYW5JbmZvKG91dHB1dEZpZWxkLCBvdXRwdXQua2V5U3Bhbik7XG4gICAgICBpZiAodGhpcy50Y2IuZW52LmNvbmZpZy5jaGVja1R5cGVPZk91dHB1dEV2ZW50cykge1xuICAgICAgICAvLyBGb3Igc3RyaWN0IGNoZWNraW5nIG9mIGRpcmVjdGl2ZSBldmVudHMsIGdlbmVyYXRlIGEgY2FsbCB0byB0aGUgYHN1YnNjcmliZWAgbWV0aG9kXG4gICAgICAgIC8vIG9uIHRoZSBkaXJlY3RpdmUncyBvdXRwdXQgZmllbGQgdG8gbGV0IHR5cGUgaW5mb3JtYXRpb24gZmxvdyBpbnRvIHRoZSBoYW5kbGVyIGZ1bmN0aW9uJ3NcbiAgICAgICAgLy8gYCRldmVudGAgcGFyYW1ldGVyLlxuICAgICAgICBjb25zdCBoYW5kbGVyID0gdGNiQ3JlYXRlRXZlbnRIYW5kbGVyKG91dHB1dCwgdGhpcy50Y2IsIHRoaXMuc2NvcGUsIEV2ZW50UGFyYW1UeXBlLkluZmVyKTtcbiAgICAgICAgY29uc3Qgc3Vic2NyaWJlRm4gPSB0cy5jcmVhdGVQcm9wZXJ0eUFjY2VzcyhvdXRwdXRGaWVsZCwgJ3N1YnNjcmliZScpO1xuICAgICAgICBjb25zdCBjYWxsID0gdHMuY3JlYXRlQ2FsbChzdWJzY3JpYmVGbiwgLyogdHlwZUFyZ3VtZW50cyAqLyB1bmRlZmluZWQsIFtoYW5kbGVyXSk7XG4gICAgICAgIGFkZFBhcnNlU3BhbkluZm8oY2FsbCwgb3V0cHV0LnNvdXJjZVNwYW4pO1xuICAgICAgICB0aGlzLnNjb3BlLmFkZFN0YXRlbWVudCh0cy5jcmVhdGVFeHByZXNzaW9uU3RhdGVtZW50KGNhbGwpKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIC8vIElmIHN0cmljdCBjaGVja2luZyBvZiBkaXJlY3RpdmUgZXZlbnRzIGlzIGRpc2FibGVkOlxuICAgICAgICAvL1xuICAgICAgICAvLyAqIFdlIHN0aWxsIGdlbmVyYXRlIHRoZSBhY2Nlc3MgdG8gdGhlIG91dHB1dCBmaWVsZCBhcyBhIHN0YXRlbWVudCBpbiB0aGUgVENCIHNvIGNvbnN1bWVyc1xuICAgICAgICAvLyAgIG9mIHRoZSBgVGVtcGxhdGVUeXBlQ2hlY2tlcmAgY2FuIHN0aWxsIGZpbmQgdGhlIG5vZGUgZm9yIHRoZSBjbGFzcyBtZW1iZXIgZm9yIHRoZVxuICAgICAgICAvLyAgIG91dHB1dC5cbiAgICAgICAgLy8gKiBFbWl0IGEgaGFuZGxlciBmdW5jdGlvbiB3aGVyZSB0aGUgYCRldmVudGAgcGFyYW1ldGVyIGhhcyBhbiBleHBsaWNpdCBgYW55YCB0eXBlLlxuICAgICAgICB0aGlzLnNjb3BlLmFkZFN0YXRlbWVudCh0cy5jcmVhdGVFeHByZXNzaW9uU3RhdGVtZW50KG91dHB1dEZpZWxkKSk7XG4gICAgICAgIGNvbnN0IGhhbmRsZXIgPSB0Y2JDcmVhdGVFdmVudEhhbmRsZXIob3V0cHV0LCB0aGlzLnRjYiwgdGhpcy5zY29wZSwgRXZlbnRQYXJhbVR5cGUuQW55KTtcbiAgICAgICAgdGhpcy5zY29wZS5hZGRTdGF0ZW1lbnQodHMuY3JlYXRlRXhwcmVzc2lvblN0YXRlbWVudChoYW5kbGVyKSk7XG4gICAgICB9XG5cbiAgICAgIEV4cHJlc3Npb25TZW1hbnRpY1Zpc2l0b3IudmlzaXQoXG4gICAgICAgICAgb3V0cHV0LmhhbmRsZXIsIHRoaXMudGNiLmlkLCB0aGlzLnRjYi5ib3VuZFRhcmdldCwgdGhpcy50Y2Iub29iUmVjb3JkZXIpO1xuICAgIH1cblxuICAgIHJldHVybiBudWxsO1xuICB9XG59XG5cbi8qKlxuICogQSBgVGNiT3BgIHdoaWNoIGdlbmVyYXRlcyBjb2RlIHRvIGNoZWNrIFwidW5jbGFpbWVkIG91dHB1dHNcIiAtIGV2ZW50IGJpbmRpbmdzIG9uIGFuIGVsZW1lbnQgd2hpY2hcbiAqIHdlcmUgbm90IGF0dHJpYnV0ZWQgdG8gYW55IGRpcmVjdGl2ZSBvciBjb21wb25lbnQsIGFuZCBhcmUgaW5zdGVhZCBwcm9jZXNzZWQgYWdhaW5zdCB0aGUgSFRNTFxuICogZWxlbWVudCBpdHNlbGYuXG4gKlxuICogRXhlY3V0aW5nIHRoaXMgb3BlcmF0aW9uIHJldHVybnMgbm90aGluZy5cbiAqL1xuY2xhc3MgVGNiVW5jbGFpbWVkT3V0cHV0c09wIGV4dGVuZHMgVGNiT3Age1xuICBjb25zdHJ1Y3RvcihcbiAgICAgIHByaXZhdGUgdGNiOiBDb250ZXh0LCBwcml2YXRlIHNjb3BlOiBTY29wZSwgcHJpdmF0ZSBlbGVtZW50OiBUbXBsQXN0RWxlbWVudCxcbiAgICAgIHByaXZhdGUgY2xhaW1lZE91dHB1dHM6IFNldDxzdHJpbmc+KSB7XG4gICAgc3VwZXIoKTtcbiAgfVxuXG4gIGdldCBvcHRpb25hbCgpIHtcbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cblxuICBleGVjdXRlKCk6IG51bGwge1xuICAgIGxldCBlbElkOiB0cy5FeHByZXNzaW9ufG51bGwgPSBudWxsO1xuXG4gICAgLy8gVE9ETyhhbHhodWIpOiB0aGlzIGNvdWxkIGJlIG1vcmUgZWZmaWNpZW50LlxuICAgIGZvciAoY29uc3Qgb3V0cHV0IG9mIHRoaXMuZWxlbWVudC5vdXRwdXRzKSB7XG4gICAgICBpZiAodGhpcy5jbGFpbWVkT3V0cHV0cy5oYXMob3V0cHV0Lm5hbWUpKSB7XG4gICAgICAgIC8vIFNraXAgdGhpcyBldmVudCBoYW5kbGVyIGFzIGl0IHdhcyBjbGFpbWVkIGJ5IGEgZGlyZWN0aXZlLlxuICAgICAgICBjb250aW51ZTtcbiAgICAgIH1cblxuICAgICAgaWYgKG91dHB1dC50eXBlID09PSBQYXJzZWRFdmVudFR5cGUuQW5pbWF0aW9uKSB7XG4gICAgICAgIC8vIEFuaW1hdGlvbiBvdXRwdXQgYmluZGluZ3MgYWx3YXlzIGhhdmUgYW4gYCRldmVudGAgcGFyYW1ldGVyIG9mIHR5cGUgYEFuaW1hdGlvbkV2ZW50YC5cbiAgICAgICAgY29uc3QgZXZlbnRUeXBlID0gdGhpcy50Y2IuZW52LmNvbmZpZy5jaGVja1R5cGVPZkFuaW1hdGlvbkV2ZW50cyA/XG4gICAgICAgICAgICB0aGlzLnRjYi5lbnYucmVmZXJlbmNlRXh0ZXJuYWxUeXBlKCdAYW5ndWxhci9hbmltYXRpb25zJywgJ0FuaW1hdGlvbkV2ZW50JykgOlxuICAgICAgICAgICAgRXZlbnRQYXJhbVR5cGUuQW55O1xuXG4gICAgICAgIGNvbnN0IGhhbmRsZXIgPSB0Y2JDcmVhdGVFdmVudEhhbmRsZXIob3V0cHV0LCB0aGlzLnRjYiwgdGhpcy5zY29wZSwgZXZlbnRUeXBlKTtcbiAgICAgICAgdGhpcy5zY29wZS5hZGRTdGF0ZW1lbnQodHMuY3JlYXRlRXhwcmVzc2lvblN0YXRlbWVudChoYW5kbGVyKSk7XG4gICAgICB9IGVsc2UgaWYgKHRoaXMudGNiLmVudi5jb25maWcuY2hlY2tUeXBlT2ZEb21FdmVudHMpIHtcbiAgICAgICAgLy8gSWYgc3RyaWN0IGNoZWNraW5nIG9mIERPTSBldmVudHMgaXMgZW5hYmxlZCwgZ2VuZXJhdGUgYSBjYWxsIHRvIGBhZGRFdmVudExpc3RlbmVyYCBvblxuICAgICAgICAvLyB0aGUgZWxlbWVudCBpbnN0YW5jZSBzbyB0aGF0IFR5cGVTY3JpcHQncyB0eXBlIGluZmVyZW5jZSBmb3JcbiAgICAgICAgLy8gYEhUTUxFbGVtZW50LmFkZEV2ZW50TGlzdGVuZXJgIHVzaW5nIGBIVE1MRWxlbWVudEV2ZW50TWFwYCB0byBpbmZlciBhbiBhY2N1cmF0ZSB0eXBlIGZvclxuICAgICAgICAvLyBgJGV2ZW50YCBkZXBlbmRpbmcgb24gdGhlIGV2ZW50IG5hbWUuIEZvciB1bmtub3duIGV2ZW50IG5hbWVzLCBUeXBlU2NyaXB0IHJlc29ydHMgdG8gdGhlXG4gICAgICAgIC8vIGJhc2UgYEV2ZW50YCB0eXBlLlxuICAgICAgICBjb25zdCBoYW5kbGVyID0gdGNiQ3JlYXRlRXZlbnRIYW5kbGVyKG91dHB1dCwgdGhpcy50Y2IsIHRoaXMuc2NvcGUsIEV2ZW50UGFyYW1UeXBlLkluZmVyKTtcblxuICAgICAgICBpZiAoZWxJZCA9PT0gbnVsbCkge1xuICAgICAgICAgIGVsSWQgPSB0aGlzLnNjb3BlLnJlc29sdmUodGhpcy5lbGVtZW50KTtcbiAgICAgICAgfVxuICAgICAgICBjb25zdCBwcm9wZXJ0eUFjY2VzcyA9IHRzLmNyZWF0ZVByb3BlcnR5QWNjZXNzKGVsSWQsICdhZGRFdmVudExpc3RlbmVyJyk7XG4gICAgICAgIGFkZFBhcnNlU3BhbkluZm8ocHJvcGVydHlBY2Nlc3MsIG91dHB1dC5rZXlTcGFuKTtcbiAgICAgICAgY29uc3QgY2FsbCA9IHRzLmNyZWF0ZUNhbGwoXG4gICAgICAgICAgICAvKiBleHByZXNzaW9uICovIHByb3BlcnR5QWNjZXNzLFxuICAgICAgICAgICAgLyogdHlwZUFyZ3VtZW50cyAqLyB1bmRlZmluZWQsXG4gICAgICAgICAgICAvKiBhcmd1bWVudHMgKi9bdHMuY3JlYXRlU3RyaW5nTGl0ZXJhbChvdXRwdXQubmFtZSksIGhhbmRsZXJdKTtcbiAgICAgICAgYWRkUGFyc2VTcGFuSW5mbyhjYWxsLCBvdXRwdXQuc291cmNlU3Bhbik7XG4gICAgICAgIHRoaXMuc2NvcGUuYWRkU3RhdGVtZW50KHRzLmNyZWF0ZUV4cHJlc3Npb25TdGF0ZW1lbnQoY2FsbCkpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgLy8gSWYgc3RyaWN0IGNoZWNraW5nIG9mIERPTSBpbnB1dHMgaXMgZGlzYWJsZWQsIGVtaXQgYSBoYW5kbGVyIGZ1bmN0aW9uIHdoZXJlIHRoZSBgJGV2ZW50YFxuICAgICAgICAvLyBwYXJhbWV0ZXIgaGFzIGFuIGV4cGxpY2l0IGBhbnlgIHR5cGUuXG4gICAgICAgIGNvbnN0IGhhbmRsZXIgPSB0Y2JDcmVhdGVFdmVudEhhbmRsZXIob3V0cHV0LCB0aGlzLnRjYiwgdGhpcy5zY29wZSwgRXZlbnRQYXJhbVR5cGUuQW55KTtcbiAgICAgICAgdGhpcy5zY29wZS5hZGRTdGF0ZW1lbnQodHMuY3JlYXRlRXhwcmVzc2lvblN0YXRlbWVudChoYW5kbGVyKSk7XG4gICAgICB9XG5cbiAgICAgIEV4cHJlc3Npb25TZW1hbnRpY1Zpc2l0b3IudmlzaXQoXG4gICAgICAgICAgb3V0cHV0LmhhbmRsZXIsIHRoaXMudGNiLmlkLCB0aGlzLnRjYi5ib3VuZFRhcmdldCwgdGhpcy50Y2Iub29iUmVjb3JkZXIpO1xuICAgIH1cblxuICAgIHJldHVybiBudWxsO1xuICB9XG59XG5cbi8qKlxuICogQSBgVGNiT3BgIHdoaWNoIGdlbmVyYXRlcyBhIGNvbXBsZXRpb24gcG9pbnQgZm9yIHRoZSBjb21wb25lbnQgY29udGV4dC5cbiAqXG4gKiBUaGlzIGNvbXBsZXRpb24gcG9pbnQgbG9va3MgbGlrZSBgY3R4LiA7YCBpbiB0aGUgVENCIG91dHB1dCwgYW5kIGRvZXMgbm90IHByb2R1Y2UgZGlhZ25vc3RpY3MuXG4gKiBUeXBlU2NyaXB0IGF1dG9jb21wbGV0aW9uIEFQSXMgY2FuIGJlIHVzZWQgYXQgdGhpcyBjb21wbGV0aW9uIHBvaW50IChhZnRlciB0aGUgJy4nKSB0byBwcm9kdWNlXG4gKiBhdXRvY29tcGxldGlvbiByZXN1bHRzIG9mIHByb3BlcnRpZXMgYW5kIG1ldGhvZHMgZnJvbSB0aGUgdGVtcGxhdGUncyBjb21wb25lbnQgY29udGV4dC5cbiAqL1xuY2xhc3MgVGNiQ29tcG9uZW50Q29udGV4dENvbXBsZXRpb25PcCBleHRlbmRzIFRjYk9wIHtcbiAgY29uc3RydWN0b3IocHJpdmF0ZSBzY29wZTogU2NvcGUpIHtcbiAgICBzdXBlcigpO1xuICB9XG5cbiAgcmVhZG9ubHkgb3B0aW9uYWwgPSBmYWxzZTtcblxuICBleGVjdXRlKCk6IG51bGwge1xuICAgIGNvbnN0IGN0eCA9IHRzLmNyZWF0ZUlkZW50aWZpZXIoJ2N0eCcpO1xuICAgIGNvbnN0IGN0eERvdCA9IHRzLmNyZWF0ZVByb3BlcnR5QWNjZXNzKGN0eCwgJycpO1xuICAgIG1hcmtJZ25vcmVEaWFnbm9zdGljcyhjdHhEb3QpO1xuICAgIGFkZEV4cHJlc3Npb25JZGVudGlmaWVyKGN0eERvdCwgRXhwcmVzc2lvbklkZW50aWZpZXIuQ09NUE9ORU5UX0NPTVBMRVRJT04pO1xuICAgIHRoaXMuc2NvcGUuYWRkU3RhdGVtZW50KHRzLmNyZWF0ZUV4cHJlc3Npb25TdGF0ZW1lbnQoY3R4RG90KSk7XG4gICAgcmV0dXJuIG51bGw7XG4gIH1cbn1cblxuLyoqXG4gKiBWYWx1ZSB1c2VkIHRvIGJyZWFrIGEgY2lyY3VsYXIgcmVmZXJlbmNlIGJldHdlZW4gYFRjYk9wYHMuXG4gKlxuICogVGhpcyB2YWx1ZSBpcyByZXR1cm5lZCB3aGVuZXZlciBgVGNiT3BgcyBoYXZlIGEgY2lyY3VsYXIgZGVwZW5kZW5jeS4gVGhlIGV4cHJlc3Npb24gaXMgYSBub24tbnVsbFxuICogYXNzZXJ0aW9uIG9mIHRoZSBudWxsIHZhbHVlIChpbiBUeXBlU2NyaXB0LCB0aGUgZXhwcmVzc2lvbiBgbnVsbCFgKS4gVGhpcyBjb25zdHJ1Y3Rpb24gd2lsbCBpbmZlclxuICogdGhlIGxlYXN0IG5hcnJvdyB0eXBlIGZvciB3aGF0ZXZlciBpdCdzIGFzc2lnbmVkIHRvLlxuICovXG5jb25zdCBJTkZFUl9UWVBFX0ZPUl9DSVJDVUxBUl9PUF9FWFBSID0gdHMuY3JlYXRlTm9uTnVsbEV4cHJlc3Npb24odHMuY3JlYXRlTnVsbCgpKTtcblxuLyoqXG4gKiBPdmVyYWxsIGdlbmVyYXRpb24gY29udGV4dCBmb3IgdGhlIHR5cGUgY2hlY2sgYmxvY2suXG4gKlxuICogYENvbnRleHRgIGhhbmRsZXMgb3BlcmF0aW9ucyBkdXJpbmcgY29kZSBnZW5lcmF0aW9uIHdoaWNoIGFyZSBnbG9iYWwgd2l0aCByZXNwZWN0IHRvIHRoZSB3aG9sZVxuICogYmxvY2suIEl0J3MgcmVzcG9uc2libGUgZm9yIHZhcmlhYmxlIG5hbWUgYWxsb2NhdGlvbiBhbmQgbWFuYWdlbWVudCBvZiBhbnkgaW1wb3J0cyBuZWVkZWQuIEl0XG4gKiBhbHNvIGNvbnRhaW5zIHRoZSB0ZW1wbGF0ZSBtZXRhZGF0YSBpdHNlbGYuXG4gKi9cbmV4cG9ydCBjbGFzcyBDb250ZXh0IHtcbiAgcHJpdmF0ZSBuZXh0SWQgPSAxO1xuXG4gIGNvbnN0cnVjdG9yKFxuICAgICAgcmVhZG9ubHkgZW52OiBFbnZpcm9ubWVudCwgcmVhZG9ubHkgZG9tU2NoZW1hQ2hlY2tlcjogRG9tU2NoZW1hQ2hlY2tlcixcbiAgICAgIHJlYWRvbmx5IG9vYlJlY29yZGVyOiBPdXRPZkJhbmREaWFnbm9zdGljUmVjb3JkZXIsIHJlYWRvbmx5IGlkOiBUZW1wbGF0ZUlkLFxuICAgICAgcmVhZG9ubHkgYm91bmRUYXJnZXQ6IEJvdW5kVGFyZ2V0PFR5cGVDaGVja2FibGVEaXJlY3RpdmVNZXRhPixcbiAgICAgIHByaXZhdGUgcGlwZXM6IE1hcDxzdHJpbmcsIFJlZmVyZW5jZTxDbGFzc0RlY2xhcmF0aW9uPHRzLkNsYXNzRGVjbGFyYXRpb24+Pj4sXG4gICAgICByZWFkb25seSBzY2hlbWFzOiBTY2hlbWFNZXRhZGF0YVtdKSB7fVxuXG4gIC8qKlxuICAgKiBBbGxvY2F0ZSBhIG5ldyB2YXJpYWJsZSBuYW1lIGZvciB1c2Ugd2l0aGluIHRoZSBgQ29udGV4dGAuXG4gICAqXG4gICAqIEN1cnJlbnRseSB0aGlzIHVzZXMgYSBtb25vdG9uaWNhbGx5IGluY3JlYXNpbmcgY291bnRlciwgYnV0IGluIHRoZSBmdXR1cmUgdGhlIHZhcmlhYmxlIG5hbWVcbiAgICogbWlnaHQgY2hhbmdlIGRlcGVuZGluZyBvbiB0aGUgdHlwZSBvZiBkYXRhIGJlaW5nIHN0b3JlZC5cbiAgICovXG4gIGFsbG9jYXRlSWQoKTogdHMuSWRlbnRpZmllciB7XG4gICAgcmV0dXJuIHRzLmNyZWF0ZUlkZW50aWZpZXIoYF90JHt0aGlzLm5leHRJZCsrfWApO1xuICB9XG5cbiAgZ2V0UGlwZUJ5TmFtZShuYW1lOiBzdHJpbmcpOiBSZWZlcmVuY2U8Q2xhc3NEZWNsYXJhdGlvbjx0cy5DbGFzc0RlY2xhcmF0aW9uPj58bnVsbCB7XG4gICAgaWYgKCF0aGlzLnBpcGVzLmhhcyhuYW1lKSkge1xuICAgICAgcmV0dXJuIG51bGw7XG4gICAgfVxuICAgIHJldHVybiB0aGlzLnBpcGVzLmdldChuYW1lKSE7XG4gIH1cbn1cblxuLyoqXG4gKiBMb2NhbCBzY29wZSB3aXRoaW4gdGhlIHR5cGUgY2hlY2sgYmxvY2sgZm9yIGEgcGFydGljdWxhciB0ZW1wbGF0ZS5cbiAqXG4gKiBUaGUgdG9wLWxldmVsIHRlbXBsYXRlIGFuZCBlYWNoIG5lc3RlZCBgPG5nLXRlbXBsYXRlPmAgaGF2ZSB0aGVpciBvd24gYFNjb3BlYCwgd2hpY2ggZXhpc3QgaW4gYVxuICogaGllcmFyY2h5LiBUaGUgc3RydWN0dXJlIG9mIHRoaXMgaGllcmFyY2h5IG1pcnJvcnMgdGhlIHN5bnRhY3RpYyBzY29wZXMgaW4gdGhlIGdlbmVyYXRlZCB0eXBlXG4gKiBjaGVjayBibG9jaywgd2hlcmUgZWFjaCBuZXN0ZWQgdGVtcGxhdGUgaXMgZW5jYXNlZCBpbiBhbiBgaWZgIHN0cnVjdHVyZS5cbiAqXG4gKiBBcyBhIHRlbXBsYXRlJ3MgYFRjYk9wYHMgYXJlIGV4ZWN1dGVkIGluIGEgZ2l2ZW4gYFNjb3BlYCwgc3RhdGVtZW50cyBhcmUgYWRkZWQgdmlhXG4gKiBgYWRkU3RhdGVtZW50KClgLiBXaGVuIHRoaXMgcHJvY2Vzc2luZyBpcyBjb21wbGV0ZSwgdGhlIGBTY29wZWAgY2FuIGJlIHR1cm5lZCBpbnRvIGEgYHRzLkJsb2NrYFxuICogdmlhIGByZW5kZXJUb0Jsb2NrKClgLlxuICpcbiAqIElmIGEgYFRjYk9wYCByZXF1aXJlcyB0aGUgb3V0cHV0IG9mIGFub3RoZXIsIGl0IGNhbiBjYWxsIGByZXNvbHZlKClgLlxuICovXG5jbGFzcyBTY29wZSB7XG4gIC8qKlxuICAgKiBBIHF1ZXVlIG9mIG9wZXJhdGlvbnMgd2hpY2ggbmVlZCB0byBiZSBwZXJmb3JtZWQgdG8gZ2VuZXJhdGUgdGhlIFRDQiBjb2RlIGZvciB0aGlzIHNjb3BlLlxuICAgKlxuICAgKiBUaGlzIGFycmF5IGNhbiBjb250YWluIGVpdGhlciBhIGBUY2JPcGAgd2hpY2ggaGFzIHlldCB0byBiZSBleGVjdXRlZCwgb3IgYSBgdHMuRXhwcmVzc2lvbnxudWxsYFxuICAgKiByZXByZXNlbnRpbmcgdGhlIG1lbW9pemVkIHJlc3VsdCBvZiBleGVjdXRpbmcgdGhlIG9wZXJhdGlvbi4gQXMgb3BlcmF0aW9ucyBhcmUgZXhlY3V0ZWQsIHRoZWlyXG4gICAqIHJlc3VsdHMgYXJlIHdyaXR0ZW4gaW50byB0aGUgYG9wUXVldWVgLCBvdmVyd3JpdGluZyB0aGUgb3JpZ2luYWwgb3BlcmF0aW9uLlxuICAgKlxuICAgKiBJZiBhbiBvcGVyYXRpb24gaXMgaW4gdGhlIHByb2Nlc3Mgb2YgYmVpbmcgZXhlY3V0ZWQsIGl0IGlzIHRlbXBvcmFyaWx5IG92ZXJ3cml0dGVuIGhlcmUgd2l0aFxuICAgKiBgSU5GRVJfVFlQRV9GT1JfQ0lSQ1VMQVJfT1BfRVhQUmAuIFRoaXMgd2F5LCBpZiBhIGN5Y2xlIGlzIGVuY291bnRlcmVkIHdoZXJlIGFuIG9wZXJhdGlvblxuICAgKiBkZXBlbmRzIHRyYW5zaXRpdmVseSBvbiBpdHMgb3duIHJlc3VsdCwgdGhlIGlubmVyIG9wZXJhdGlvbiB3aWxsIGluZmVyIHRoZSBsZWFzdCBuYXJyb3cgdHlwZVxuICAgKiB0aGF0IGZpdHMgaW5zdGVhZC4gVGhpcyBoYXMgdGhlIHNhbWUgc2VtYW50aWNzIGFzIFR5cGVTY3JpcHQgaXRzZWxmIHdoZW4gdHlwZXMgYXJlIHJlZmVyZW5jZWRcbiAgICogY2lyY3VsYXJseS5cbiAgICovXG4gIHByaXZhdGUgb3BRdWV1ZTogKFRjYk9wfHRzLkV4cHJlc3Npb258bnVsbClbXSA9IFtdO1xuXG4gIC8qKlxuICAgKiBBIG1hcCBvZiBgVG1wbEFzdEVsZW1lbnRgcyB0byB0aGUgaW5kZXggb2YgdGhlaXIgYFRjYkVsZW1lbnRPcGAgaW4gdGhlIGBvcFF1ZXVlYFxuICAgKi9cbiAgcHJpdmF0ZSBlbGVtZW50T3BNYXAgPSBuZXcgTWFwPFRtcGxBc3RFbGVtZW50LCBudW1iZXI+KCk7XG4gIC8qKlxuICAgKiBBIG1hcCBvZiBtYXBzIHdoaWNoIHRyYWNrcyB0aGUgaW5kZXggb2YgYFRjYkRpcmVjdGl2ZUN0b3JPcGBzIGluIHRoZSBgb3BRdWV1ZWAgZm9yIGVhY2hcbiAgICogZGlyZWN0aXZlIG9uIGEgYFRtcGxBc3RFbGVtZW50YCBvciBgVG1wbEFzdFRlbXBsYXRlYCBub2RlLlxuICAgKi9cbiAgcHJpdmF0ZSBkaXJlY3RpdmVPcE1hcCA9XG4gICAgICBuZXcgTWFwPFRtcGxBc3RFbGVtZW50fFRtcGxBc3RUZW1wbGF0ZSwgTWFwPFR5cGVDaGVja2FibGVEaXJlY3RpdmVNZXRhLCBudW1iZXI+PigpO1xuXG4gIC8qKlxuICAgKiBBIG1hcCBvZiBgVG1wbEFzdFJlZmVyZW5jZWBzIHRvIHRoZSBpbmRleCBvZiB0aGVpciBgVGNiUmVmZXJlbmNlT3BgIGluIHRoZSBgb3BRdWV1ZWBcbiAgICovXG4gIHByaXZhdGUgcmVmZXJlbmNlT3BNYXAgPSBuZXcgTWFwPFRtcGxBc3RSZWZlcmVuY2UsIG51bWJlcj4oKTtcblxuICAvKipcbiAgICogTWFwIG9mIGltbWVkaWF0ZWx5IG5lc3RlZCA8bmctdGVtcGxhdGU+cyAod2l0aGluIHRoaXMgYFNjb3BlYCkgcmVwcmVzZW50ZWQgYnkgYFRtcGxBc3RUZW1wbGF0ZWBcbiAgICogbm9kZXMgdG8gdGhlIGluZGV4IG9mIHRoZWlyIGBUY2JUZW1wbGF0ZUNvbnRleHRPcGBzIGluIHRoZSBgb3BRdWV1ZWAuXG4gICAqL1xuICBwcml2YXRlIHRlbXBsYXRlQ3R4T3BNYXAgPSBuZXcgTWFwPFRtcGxBc3RUZW1wbGF0ZSwgbnVtYmVyPigpO1xuXG4gIC8qKlxuICAgKiBNYXAgb2YgdmFyaWFibGVzIGRlY2xhcmVkIG9uIHRoZSB0ZW1wbGF0ZSB0aGF0IGNyZWF0ZWQgdGhpcyBgU2NvcGVgIChyZXByZXNlbnRlZCBieVxuICAgKiBgVG1wbEFzdFZhcmlhYmxlYCBub2RlcykgdG8gdGhlIGluZGV4IG9mIHRoZWlyIGBUY2JWYXJpYWJsZU9wYHMgaW4gdGhlIGBvcFF1ZXVlYC5cbiAgICovXG4gIHByaXZhdGUgdmFyTWFwID0gbmV3IE1hcDxUbXBsQXN0VmFyaWFibGUsIG51bWJlcj4oKTtcblxuICAvKipcbiAgICogU3RhdGVtZW50cyBmb3IgdGhpcyB0ZW1wbGF0ZS5cbiAgICpcbiAgICogRXhlY3V0aW5nIHRoZSBgVGNiT3BgcyBpbiB0aGUgYG9wUXVldWVgIHBvcHVsYXRlcyB0aGlzIGFycmF5LlxuICAgKi9cbiAgcHJpdmF0ZSBzdGF0ZW1lbnRzOiB0cy5TdGF0ZW1lbnRbXSA9IFtdO1xuXG4gIHByaXZhdGUgY29uc3RydWN0b3IoXG4gICAgICBwcml2YXRlIHRjYjogQ29udGV4dCwgcHJpdmF0ZSBwYXJlbnQ6IFNjb3BlfG51bGwgPSBudWxsLFxuICAgICAgcHJpdmF0ZSBndWFyZDogdHMuRXhwcmVzc2lvbnxudWxsID0gbnVsbCkge31cblxuICAvKipcbiAgICogQ29uc3RydWN0cyBhIGBTY29wZWAgZ2l2ZW4gZWl0aGVyIGEgYFRtcGxBc3RUZW1wbGF0ZWAgb3IgYSBsaXN0IG9mIGBUbXBsQXN0Tm9kZWBzLlxuICAgKlxuICAgKiBAcGFyYW0gdGNiIHRoZSBvdmVyYWxsIGNvbnRleHQgb2YgVENCIGdlbmVyYXRpb24uXG4gICAqIEBwYXJhbSBwYXJlbnQgdGhlIGBTY29wZWAgb2YgdGhlIHBhcmVudCB0ZW1wbGF0ZSAoaWYgYW55KSBvciBgbnVsbGAgaWYgdGhpcyBpcyB0aGUgcm9vdFxuICAgKiBgU2NvcGVgLlxuICAgKiBAcGFyYW0gdGVtcGxhdGVPck5vZGVzIGVpdGhlciBhIGBUbXBsQXN0VGVtcGxhdGVgIHJlcHJlc2VudGluZyB0aGUgdGVtcGxhdGUgZm9yIHdoaWNoIHRvXG4gICAqIGNhbGN1bGF0ZSB0aGUgYFNjb3BlYCwgb3IgYSBsaXN0IG9mIG5vZGVzIGlmIG5vIG91dGVyIHRlbXBsYXRlIG9iamVjdCBpcyBhdmFpbGFibGUuXG4gICAqIEBwYXJhbSBndWFyZCBhbiBleHByZXNzaW9uIHRoYXQgaXMgYXBwbGllZCB0byB0aGlzIHNjb3BlIGZvciB0eXBlIG5hcnJvd2luZyBwdXJwb3Nlcy5cbiAgICovXG4gIHN0YXRpYyBmb3JOb2RlcyhcbiAgICAgIHRjYjogQ29udGV4dCwgcGFyZW50OiBTY29wZXxudWxsLCB0ZW1wbGF0ZU9yTm9kZXM6IFRtcGxBc3RUZW1wbGF0ZXwoVG1wbEFzdE5vZGVbXSksXG4gICAgICBndWFyZDogdHMuRXhwcmVzc2lvbnxudWxsKTogU2NvcGUge1xuICAgIGNvbnN0IHNjb3BlID0gbmV3IFNjb3BlKHRjYiwgcGFyZW50LCBndWFyZCk7XG5cbiAgICBpZiAocGFyZW50ID09PSBudWxsICYmIHRjYi5lbnYuY29uZmlnLmVuYWJsZVRlbXBsYXRlVHlwZUNoZWNrZXIpIHtcbiAgICAgIC8vIEFkZCBhbiBhdXRvY29tcGxldGlvbiBwb2ludCBmb3IgdGhlIGNvbXBvbmVudCBjb250ZXh0LlxuICAgICAgc2NvcGUub3BRdWV1ZS5wdXNoKG5ldyBUY2JDb21wb25lbnRDb250ZXh0Q29tcGxldGlvbk9wKHNjb3BlKSk7XG4gICAgfVxuXG4gICAgbGV0IGNoaWxkcmVuOiBUbXBsQXN0Tm9kZVtdO1xuXG4gICAgLy8gSWYgZ2l2ZW4gYW4gYWN0dWFsIGBUbXBsQXN0VGVtcGxhdGVgIGluc3RhbmNlLCB0aGVuIHByb2Nlc3MgYW55IGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gaXRcbiAgICAvLyBoYXMuXG4gICAgaWYgKHRlbXBsYXRlT3JOb2RlcyBpbnN0YW5jZW9mIFRtcGxBc3RUZW1wbGF0ZSkge1xuICAgICAgLy8gVGhlIHRlbXBsYXRlJ3MgdmFyaWFibGUgZGVjbGFyYXRpb25zIG5lZWQgdG8gYmUgYWRkZWQgYXMgYFRjYlZhcmlhYmxlT3Bgcy5cbiAgICAgIGNvbnN0IHZhck1hcCA9IG5ldyBNYXA8c3RyaW5nLCBUbXBsQXN0VmFyaWFibGU+KCk7XG5cbiAgICAgIGZvciAoY29uc3QgdiBvZiB0ZW1wbGF0ZU9yTm9kZXMudmFyaWFibGVzKSB7XG4gICAgICAgIC8vIFZhbGlkYXRlIHRoYXQgdmFyaWFibGVzIG9uIHRoZSBgVG1wbEFzdFRlbXBsYXRlYCBhcmUgb25seSBkZWNsYXJlZCBvbmNlLlxuICAgICAgICBpZiAoIXZhck1hcC5oYXModi5uYW1lKSkge1xuICAgICAgICAgIHZhck1hcC5zZXQodi5uYW1lLCB2KTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBjb25zdCBmaXJzdERlY2wgPSB2YXJNYXAuZ2V0KHYubmFtZSkhO1xuICAgICAgICAgIHRjYi5vb2JSZWNvcmRlci5kdXBsaWNhdGVUZW1wbGF0ZVZhcih0Y2IuaWQsIHYsIGZpcnN0RGVjbCk7XG4gICAgICAgIH1cblxuICAgICAgICBjb25zdCBvcEluZGV4ID0gc2NvcGUub3BRdWV1ZS5wdXNoKG5ldyBUY2JWYXJpYWJsZU9wKHRjYiwgc2NvcGUsIHRlbXBsYXRlT3JOb2RlcywgdikpIC0gMTtcbiAgICAgICAgc2NvcGUudmFyTWFwLnNldCh2LCBvcEluZGV4KTtcbiAgICAgIH1cbiAgICAgIGNoaWxkcmVuID0gdGVtcGxhdGVPck5vZGVzLmNoaWxkcmVuO1xuICAgIH0gZWxzZSB7XG4gICAgICBjaGlsZHJlbiA9IHRlbXBsYXRlT3JOb2RlcztcbiAgICB9XG4gICAgZm9yIChjb25zdCBub2RlIG9mIGNoaWxkcmVuKSB7XG4gICAgICBzY29wZS5hcHBlbmROb2RlKG5vZGUpO1xuICAgIH1cbiAgICByZXR1cm4gc2NvcGU7XG4gIH1cblxuICAvKipcbiAgICogTG9vayB1cCBhIGB0cy5FeHByZXNzaW9uYCByZXByZXNlbnRpbmcgdGhlIHZhbHVlIG9mIHNvbWUgb3BlcmF0aW9uIGluIHRoZSBjdXJyZW50IGBTY29wZWAsXG4gICAqIGluY2x1ZGluZyBhbnkgcGFyZW50IHNjb3BlKHMpLiBUaGlzIG1ldGhvZCBhbHdheXMgcmV0dXJucyBhIG11dGFibGUgY2xvbmUgb2YgdGhlXG4gICAqIGB0cy5FeHByZXNzaW9uYCB3aXRoIHRoZSBjb21tZW50cyBjbGVhcmVkLlxuICAgKlxuICAgKiBAcGFyYW0gbm9kZSBhIGBUbXBsQXN0Tm9kZWAgb2YgdGhlIG9wZXJhdGlvbiBpbiBxdWVzdGlvbi4gVGhlIGxvb2t1cCBwZXJmb3JtZWQgd2lsbCBkZXBlbmQgb25cbiAgICogdGhlIHR5cGUgb2YgdGhpcyBub2RlOlxuICAgKlxuICAgKiBBc3N1bWluZyBgZGlyZWN0aXZlYCBpcyBub3QgcHJlc2VudCwgdGhlbiBgcmVzb2x2ZWAgd2lsbCByZXR1cm46XG4gICAqXG4gICAqICogYFRtcGxBc3RFbGVtZW50YCAtIHJldHJpZXZlIHRoZSBleHByZXNzaW9uIGZvciB0aGUgZWxlbWVudCBET00gbm9kZVxuICAgKiAqIGBUbXBsQXN0VGVtcGxhdGVgIC0gcmV0cmlldmUgdGhlIHRlbXBsYXRlIGNvbnRleHQgdmFyaWFibGVcbiAgICogKiBgVG1wbEFzdFZhcmlhYmxlYCAtIHJldHJpZXZlIGEgdGVtcGxhdGUgbGV0LSB2YXJpYWJsZVxuICAgKiAqIGBUbXBsQXN0UmVmZXJlbmNlYCAtIHJldHJpZXZlIHZhcmlhYmxlIGNyZWF0ZWQgZm9yIHRoZSBsb2NhbCByZWZcbiAgICpcbiAgICogQHBhcmFtIGRpcmVjdGl2ZSBpZiBwcmVzZW50LCBhIGRpcmVjdGl2ZSB0eXBlIG9uIGEgYFRtcGxBc3RFbGVtZW50YCBvciBgVG1wbEFzdFRlbXBsYXRlYCB0b1xuICAgKiBsb29rIHVwIGluc3RlYWQgb2YgdGhlIGRlZmF1bHQgZm9yIGFuIGVsZW1lbnQgb3IgdGVtcGxhdGUgbm9kZS5cbiAgICovXG4gIHJlc29sdmUoXG4gICAgICBub2RlOiBUbXBsQXN0RWxlbWVudHxUbXBsQXN0VGVtcGxhdGV8VG1wbEFzdFZhcmlhYmxlfFRtcGxBc3RSZWZlcmVuY2UsXG4gICAgICBkaXJlY3RpdmU/OiBUeXBlQ2hlY2thYmxlRGlyZWN0aXZlTWV0YSk6IHRzLkV4cHJlc3Npb24ge1xuICAgIC8vIEF0dGVtcHQgdG8gcmVzb2x2ZSB0aGUgb3BlcmF0aW9uIGxvY2FsbHkuXG4gICAgY29uc3QgcmVzID0gdGhpcy5yZXNvbHZlTG9jYWwobm9kZSwgZGlyZWN0aXZlKTtcbiAgICBpZiAocmVzICE9PSBudWxsKSB7XG4gICAgICAvLyBXZSB3YW50IHRvIGdldCBhIGNsb25lIG9mIHRoZSByZXNvbHZlZCBleHByZXNzaW9uIGFuZCBjbGVhciB0aGUgdHJhaWxpbmcgY29tbWVudHNcbiAgICAgIC8vIHNvIHRoZXkgZG9uJ3QgY29udGludWUgdG8gYXBwZWFyIGluIGV2ZXJ5IHBsYWNlIHRoZSBleHByZXNzaW9uIGlzIHVzZWQuXG4gICAgICAvLyBBcyBhbiBleGFtcGxlLCB0aGlzIHdvdWxkIG90aGVyd2lzZSBwcm9kdWNlOlxuICAgICAgLy8gdmFyIF90MSAvKipUOkRJUiovIC8qMSwyKi8gPSBfY3RvcjEoKTtcbiAgICAgIC8vIF90MSAvKipUOkRJUiovIC8qMSwyKi8uaW5wdXQgPSAndmFsdWUnO1xuICAgICAgLy9cbiAgICAgIC8vIEluIGFkZGl0aW9uLCByZXR1cm5pbmcgYSBjbG9uZSBwcmV2ZW50cyB0aGUgY29uc3VtZXIgb2YgYFNjb3BlI3Jlc29sdmVgIGZyb21cbiAgICAgIC8vIGF0dGFjaGluZyBjb21tZW50cyBhdCB0aGUgZGVjbGFyYXRpb24gc2l0ZS5cblxuICAgICAgY29uc3QgY2xvbmUgPSB0cy5nZXRNdXRhYmxlQ2xvbmUocmVzKTtcbiAgICAgIHRzLnNldFN5bnRoZXRpY1RyYWlsaW5nQ29tbWVudHMoY2xvbmUsIFtdKTtcbiAgICAgIHJldHVybiBjbG9uZTtcbiAgICB9IGVsc2UgaWYgKHRoaXMucGFyZW50ICE9PSBudWxsKSB7XG4gICAgICAvLyBDaGVjayB3aXRoIHRoZSBwYXJlbnQuXG4gICAgICByZXR1cm4gdGhpcy5wYXJlbnQucmVzb2x2ZShub2RlLCBkaXJlY3RpdmUpO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoYENvdWxkIG5vdCByZXNvbHZlICR7bm9kZX0gLyAke2RpcmVjdGl2ZX1gKTtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogQWRkIGEgc3RhdGVtZW50IHRvIHRoaXMgc2NvcGUuXG4gICAqL1xuICBhZGRTdGF0ZW1lbnQoc3RtdDogdHMuU3RhdGVtZW50KTogdm9pZCB7XG4gICAgdGhpcy5zdGF0ZW1lbnRzLnB1c2goc3RtdCk7XG4gIH1cblxuICAvKipcbiAgICogR2V0IHRoZSBzdGF0ZW1lbnRzLlxuICAgKi9cbiAgcmVuZGVyKCk6IHRzLlN0YXRlbWVudFtdIHtcbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IHRoaXMub3BRdWV1ZS5sZW5ndGg7IGkrKykge1xuICAgICAgLy8gT3B0aW9uYWwgc3RhdGVtZW50cyBjYW5ub3QgYmUgc2tpcHBlZCB3aGVuIHdlIGFyZSBnZW5lcmF0aW5nIHRoZSBUQ0IgZm9yIHVzZVxuICAgICAgLy8gYnkgdGhlIFRlbXBsYXRlVHlwZUNoZWNrZXIuXG4gICAgICBjb25zdCBza2lwT3B0aW9uYWwgPSAhdGhpcy50Y2IuZW52LmNvbmZpZy5lbmFibGVUZW1wbGF0ZVR5cGVDaGVja2VyO1xuICAgICAgdGhpcy5leGVjdXRlT3AoaSwgc2tpcE9wdGlvbmFsKTtcbiAgICB9XG4gICAgcmV0dXJuIHRoaXMuc3RhdGVtZW50cztcbiAgfVxuXG4gIC8qKlxuICAgKiBSZXR1cm5zIGFuIGV4cHJlc3Npb24gb2YgYWxsIHRlbXBsYXRlIGd1YXJkcyB0aGF0IGFwcGx5IHRvIHRoaXMgc2NvcGUsIGluY2x1ZGluZyB0aG9zZSBvZlxuICAgKiBwYXJlbnQgc2NvcGVzLiBJZiBubyBndWFyZHMgaGF2ZSBiZWVuIGFwcGxpZWQsIG51bGwgaXMgcmV0dXJuZWQuXG4gICAqL1xuICBndWFyZHMoKTogdHMuRXhwcmVzc2lvbnxudWxsIHtcbiAgICBsZXQgcGFyZW50R3VhcmRzOiB0cy5FeHByZXNzaW9ufG51bGwgPSBudWxsO1xuICAgIGlmICh0aGlzLnBhcmVudCAhPT0gbnVsbCkge1xuICAgICAgLy8gU3RhcnQgd2l0aCB0aGUgZ3VhcmRzIGZyb20gdGhlIHBhcmVudCBzY29wZSwgaWYgcHJlc2VudC5cbiAgICAgIHBhcmVudEd1YXJkcyA9IHRoaXMucGFyZW50Lmd1YXJkcygpO1xuICAgIH1cblxuICAgIGlmICh0aGlzLmd1YXJkID09PSBudWxsKSB7XG4gICAgICAvLyBUaGlzIHNjb3BlIGRvZXMgbm90IGhhdmUgYSBndWFyZCwgc28gcmV0dXJuIHRoZSBwYXJlbnQncyBndWFyZHMgYXMgaXMuXG4gICAgICByZXR1cm4gcGFyZW50R3VhcmRzO1xuICAgIH0gZWxzZSBpZiAocGFyZW50R3VhcmRzID09PSBudWxsKSB7XG4gICAgICAvLyBUaGVyZSdzIG5vIGd1YXJkcyBmcm9tIHRoZSBwYXJlbnQgc2NvcGUsIHNvIHRoaXMgc2NvcGUncyBndWFyZCByZXByZXNlbnRzIGFsbCBhdmFpbGFibGVcbiAgICAgIC8vIGd1YXJkcy5cbiAgICAgIHJldHVybiB0aGlzLmd1YXJkO1xuICAgIH0gZWxzZSB7XG4gICAgICAvLyBCb3RoIHRoZSBwYXJlbnQgc2NvcGUgYW5kIHRoaXMgc2NvcGUgcHJvdmlkZSBhIGd1YXJkLCBzbyBjcmVhdGUgYSBjb21iaW5hdGlvbiBvZiB0aGUgdHdvLlxuICAgICAgLy8gSXQgaXMgaW1wb3J0YW50IHRoYXQgdGhlIHBhcmVudCBndWFyZCBpcyB1c2VkIGFzIGxlZnQgb3BlcmFuZCwgZ2l2ZW4gdGhhdCBpdCBtYXkgcHJvdmlkZVxuICAgICAgLy8gbmFycm93aW5nIHRoYXQgaXMgcmVxdWlyZWQgZm9yIHRoaXMgc2NvcGUncyBndWFyZCB0byBiZSB2YWxpZC5cbiAgICAgIHJldHVybiB0cy5jcmVhdGVCaW5hcnkocGFyZW50R3VhcmRzLCB0cy5TeW50YXhLaW5kLkFtcGVyc2FuZEFtcGVyc2FuZFRva2VuLCB0aGlzLmd1YXJkKTtcbiAgICB9XG4gIH1cblxuICBwcml2YXRlIHJlc29sdmVMb2NhbChcbiAgICAgIHJlZjogVG1wbEFzdEVsZW1lbnR8VG1wbEFzdFRlbXBsYXRlfFRtcGxBc3RWYXJpYWJsZXxUbXBsQXN0UmVmZXJlbmNlLFxuICAgICAgZGlyZWN0aXZlPzogVHlwZUNoZWNrYWJsZURpcmVjdGl2ZU1ldGEpOiB0cy5FeHByZXNzaW9ufG51bGwge1xuICAgIGlmIChyZWYgaW5zdGFuY2VvZiBUbXBsQXN0UmVmZXJlbmNlICYmIHRoaXMucmVmZXJlbmNlT3BNYXAuaGFzKHJlZikpIHtcbiAgICAgIHJldHVybiB0aGlzLnJlc29sdmVPcCh0aGlzLnJlZmVyZW5jZU9wTWFwLmdldChyZWYpISk7XG4gICAgfSBlbHNlIGlmIChyZWYgaW5zdGFuY2VvZiBUbXBsQXN0VmFyaWFibGUgJiYgdGhpcy52YXJNYXAuaGFzKHJlZikpIHtcbiAgICAgIC8vIFJlc29sdmluZyBhIGNvbnRleHQgdmFyaWFibGUgZm9yIHRoaXMgdGVtcGxhdGUuXG4gICAgICAvLyBFeGVjdXRlIHRoZSBgVGNiVmFyaWFibGVPcGAgYXNzb2NpYXRlZCB3aXRoIHRoZSBgVG1wbEFzdFZhcmlhYmxlYC5cbiAgICAgIHJldHVybiB0aGlzLnJlc29sdmVPcCh0aGlzLnZhck1hcC5nZXQocmVmKSEpO1xuICAgIH0gZWxzZSBpZiAoXG4gICAgICAgIHJlZiBpbnN0YW5jZW9mIFRtcGxBc3RUZW1wbGF0ZSAmJiBkaXJlY3RpdmUgPT09IHVuZGVmaW5lZCAmJlxuICAgICAgICB0aGlzLnRlbXBsYXRlQ3R4T3BNYXAuaGFzKHJlZikpIHtcbiAgICAgIC8vIFJlc29sdmluZyB0aGUgY29udGV4dCBvZiB0aGUgZ2l2ZW4gc3ViLXRlbXBsYXRlLlxuICAgICAgLy8gRXhlY3V0ZSB0aGUgYFRjYlRlbXBsYXRlQ29udGV4dE9wYCBmb3IgdGhlIHRlbXBsYXRlLlxuICAgICAgcmV0dXJuIHRoaXMucmVzb2x2ZU9wKHRoaXMudGVtcGxhdGVDdHhPcE1hcC5nZXQocmVmKSEpO1xuICAgIH0gZWxzZSBpZiAoXG4gICAgICAgIChyZWYgaW5zdGFuY2VvZiBUbXBsQXN0RWxlbWVudCB8fCByZWYgaW5zdGFuY2VvZiBUbXBsQXN0VGVtcGxhdGUpICYmXG4gICAgICAgIGRpcmVjdGl2ZSAhPT0gdW5kZWZpbmVkICYmIHRoaXMuZGlyZWN0aXZlT3BNYXAuaGFzKHJlZikpIHtcbiAgICAgIC8vIFJlc29sdmluZyBhIGRpcmVjdGl2ZSBvbiBhbiBlbGVtZW50IG9yIHN1Yi10ZW1wbGF0ZS5cbiAgICAgIGNvbnN0IGRpck1hcCA9IHRoaXMuZGlyZWN0aXZlT3BNYXAuZ2V0KHJlZikhO1xuICAgICAgaWYgKGRpck1hcC5oYXMoZGlyZWN0aXZlKSkge1xuICAgICAgICByZXR1cm4gdGhpcy5yZXNvbHZlT3AoZGlyTWFwLmdldChkaXJlY3RpdmUpISk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICByZXR1cm4gbnVsbDtcbiAgICAgIH1cbiAgICB9IGVsc2UgaWYgKHJlZiBpbnN0YW5jZW9mIFRtcGxBc3RFbGVtZW50ICYmIHRoaXMuZWxlbWVudE9wTWFwLmhhcyhyZWYpKSB7XG4gICAgICAvLyBSZXNvbHZpbmcgdGhlIERPTSBub2RlIG9mIGFuIGVsZW1lbnQgaW4gdGhpcyB0ZW1wbGF0ZS5cbiAgICAgIHJldHVybiB0aGlzLnJlc29sdmVPcCh0aGlzLmVsZW1lbnRPcE1hcC5nZXQocmVmKSEpO1xuICAgIH0gZWxzZSB7XG4gICAgICByZXR1cm4gbnVsbDtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogTGlrZSBgZXhlY3V0ZU9wYCwgYnV0IGFzc2VydCB0aGF0IHRoZSBvcGVyYXRpb24gYWN0dWFsbHkgcmV0dXJuZWQgYHRzLkV4cHJlc3Npb25gLlxuICAgKi9cbiAgcHJpdmF0ZSByZXNvbHZlT3Aob3BJbmRleDogbnVtYmVyKTogdHMuRXhwcmVzc2lvbiB7XG4gICAgY29uc3QgcmVzID0gdGhpcy5leGVjdXRlT3Aob3BJbmRleCwgLyogc2tpcE9wdGlvbmFsICovIGZhbHNlKTtcbiAgICBpZiAocmVzID09PSBudWxsKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoYEVycm9yIHJlc29sdmluZyBvcGVyYXRpb24sIGdvdCBudWxsYCk7XG4gICAgfVxuICAgIHJldHVybiByZXM7XG4gIH1cblxuICAvKipcbiAgICogRXhlY3V0ZSBhIHBhcnRpY3VsYXIgYFRjYk9wYCBpbiB0aGUgYG9wUXVldWVgLlxuICAgKlxuICAgKiBUaGlzIG1ldGhvZCByZXBsYWNlcyB0aGUgb3BlcmF0aW9uIGluIHRoZSBgb3BRdWV1ZWAgd2l0aCB0aGUgcmVzdWx0IG9mIGV4ZWN1dGlvbiAob25jZSBkb25lKVxuICAgKiBhbmQgYWxzbyBwcm90ZWN0cyBhZ2FpbnN0IGEgY2lyY3VsYXIgZGVwZW5kZW5jeSBmcm9tIHRoZSBvcGVyYXRpb24gdG8gaXRzZWxmIGJ5IHRlbXBvcmFyaWx5XG4gICAqIHNldHRpbmcgdGhlIG9wZXJhdGlvbidzIHJlc3VsdCB0byBhIHNwZWNpYWwgZXhwcmVzc2lvbi5cbiAgICovXG4gIHByaXZhdGUgZXhlY3V0ZU9wKG9wSW5kZXg6IG51bWJlciwgc2tpcE9wdGlvbmFsOiBib29sZWFuKTogdHMuRXhwcmVzc2lvbnxudWxsIHtcbiAgICBjb25zdCBvcCA9IHRoaXMub3BRdWV1ZVtvcEluZGV4XTtcbiAgICBpZiAoIShvcCBpbnN0YW5jZW9mIFRjYk9wKSkge1xuICAgICAgcmV0dXJuIG9wO1xuICAgIH1cblxuICAgIGlmIChza2lwT3B0aW9uYWwgJiYgb3Aub3B0aW9uYWwpIHtcbiAgICAgIHJldHVybiBudWxsO1xuICAgIH1cblxuICAgIC8vIFNldCB0aGUgcmVzdWx0IG9mIHRoZSBvcGVyYXRpb24gaW4gdGhlIHF1ZXVlIHRvIGl0cyBjaXJjdWxhciBmYWxsYmFjay4gSWYgZXhlY3V0aW5nIHRoaXNcbiAgICAvLyBvcGVyYXRpb24gcmVzdWx0cyBpbiBhIGNpcmN1bGFyIGRlcGVuZGVuY3ksIHRoaXMgd2lsbCBwcmV2ZW50IGFuIGluZmluaXRlIGxvb3AgYW5kIGFsbG93IGZvclxuICAgIC8vIHRoZSByZXNvbHV0aW9uIG9mIHN1Y2ggY3ljbGVzLlxuICAgIHRoaXMub3BRdWV1ZVtvcEluZGV4XSA9IG9wLmNpcmN1bGFyRmFsbGJhY2soKTtcbiAgICBjb25zdCByZXMgPSBvcC5leGVjdXRlKCk7XG4gICAgLy8gT25jZSB0aGUgb3BlcmF0aW9uIGhhcyBmaW5pc2hlZCBleGVjdXRpbmcsIGl0J3Mgc2FmZSB0byBjYWNoZSB0aGUgcmVhbCByZXN1bHQuXG4gICAgdGhpcy5vcFF1ZXVlW29wSW5kZXhdID0gcmVzO1xuICAgIHJldHVybiByZXM7XG4gIH1cblxuICBwcml2YXRlIGFwcGVuZE5vZGUobm9kZTogVG1wbEFzdE5vZGUpOiB2b2lkIHtcbiAgICBpZiAobm9kZSBpbnN0YW5jZW9mIFRtcGxBc3RFbGVtZW50KSB7XG4gICAgICBjb25zdCBvcEluZGV4ID0gdGhpcy5vcFF1ZXVlLnB1c2gobmV3IFRjYkVsZW1lbnRPcCh0aGlzLnRjYiwgdGhpcywgbm9kZSkpIC0gMTtcbiAgICAgIHRoaXMuZWxlbWVudE9wTWFwLnNldChub2RlLCBvcEluZGV4KTtcbiAgICAgIHRoaXMuYXBwZW5kRGlyZWN0aXZlc0FuZElucHV0c09mTm9kZShub2RlKTtcbiAgICAgIHRoaXMuYXBwZW5kT3V0cHV0c09mTm9kZShub2RlKTtcbiAgICAgIGZvciAoY29uc3QgY2hpbGQgb2Ygbm9kZS5jaGlsZHJlbikge1xuICAgICAgICB0aGlzLmFwcGVuZE5vZGUoY2hpbGQpO1xuICAgICAgfVxuICAgICAgdGhpcy5jaGVja0FuZEFwcGVuZFJlZmVyZW5jZXNPZk5vZGUobm9kZSk7XG4gICAgfSBlbHNlIGlmIChub2RlIGluc3RhbmNlb2YgVG1wbEFzdFRlbXBsYXRlKSB7XG4gICAgICAvLyBUZW1wbGF0ZSBjaGlsZHJlbiBhcmUgcmVuZGVyZWQgaW4gYSBjaGlsZCBzY29wZS5cbiAgICAgIHRoaXMuYXBwZW5kRGlyZWN0aXZlc0FuZElucHV0c09mTm9kZShub2RlKTtcbiAgICAgIHRoaXMuYXBwZW5kT3V0cHV0c09mTm9kZShub2RlKTtcbiAgICAgIGNvbnN0IGN0eEluZGV4ID0gdGhpcy5vcFF1ZXVlLnB1c2gobmV3IFRjYlRlbXBsYXRlQ29udGV4dE9wKHRoaXMudGNiLCB0aGlzKSkgLSAxO1xuICAgICAgdGhpcy50ZW1wbGF0ZUN0eE9wTWFwLnNldChub2RlLCBjdHhJbmRleCk7XG4gICAgICBpZiAodGhpcy50Y2IuZW52LmNvbmZpZy5jaGVja1RlbXBsYXRlQm9kaWVzKSB7XG4gICAgICAgIHRoaXMub3BRdWV1ZS5wdXNoKG5ldyBUY2JUZW1wbGF0ZUJvZHlPcCh0aGlzLnRjYiwgdGhpcywgbm9kZSkpO1xuICAgICAgfSBlbHNlIGlmICh0aGlzLnRjYi5lbnYuY29uZmlnLmFsd2F5c0NoZWNrU2NoZW1hSW5UZW1wbGF0ZUJvZGllcykge1xuICAgICAgICB0aGlzLmFwcGVuZERlZXBTY2hlbWFDaGVja3Mobm9kZS5jaGlsZHJlbik7XG4gICAgICB9XG4gICAgICB0aGlzLmNoZWNrQW5kQXBwZW5kUmVmZXJlbmNlc09mTm9kZShub2RlKTtcbiAgICB9IGVsc2UgaWYgKG5vZGUgaW5zdGFuY2VvZiBUbXBsQXN0Qm91bmRUZXh0KSB7XG4gICAgICB0aGlzLm9wUXVldWUucHVzaChuZXcgVGNiVGV4dEludGVycG9sYXRpb25PcCh0aGlzLnRjYiwgdGhpcywgbm9kZSkpO1xuICAgIH0gZWxzZSBpZiAobm9kZSBpbnN0YW5jZW9mIFRtcGxBc3RJY3UpIHtcbiAgICAgIHRoaXMuYXBwZW5kSWN1RXhwcmVzc2lvbnMobm9kZSk7XG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSBjaGVja0FuZEFwcGVuZFJlZmVyZW5jZXNPZk5vZGUobm9kZTogVG1wbEFzdEVsZW1lbnR8VG1wbEFzdFRlbXBsYXRlKTogdm9pZCB7XG4gICAgZm9yIChjb25zdCByZWYgb2Ygbm9kZS5yZWZlcmVuY2VzKSB7XG4gICAgICBjb25zdCB0YXJnZXQgPSB0aGlzLnRjYi5ib3VuZFRhcmdldC5nZXRSZWZlcmVuY2VUYXJnZXQocmVmKTtcblxuICAgICAgbGV0IGN0eEluZGV4OiBudW1iZXI7XG4gICAgICBpZiAodGFyZ2V0ID09PSBudWxsKSB7XG4gICAgICAgIC8vIFRoZSByZWZlcmVuY2UgaXMgaW52YWxpZCBpZiBpdCBkb2Vzbid0IGhhdmUgYSB0YXJnZXQsIHNvIHJlcG9ydCBpdCBhcyBhbiBlcnJvci5cbiAgICAgICAgdGhpcy50Y2Iub29iUmVjb3JkZXIubWlzc2luZ1JlZmVyZW5jZVRhcmdldCh0aGlzLnRjYi5pZCwgcmVmKTtcblxuICAgICAgICAvLyBBbnkgdXNhZ2VzIG9mIHRoZSBpbnZhbGlkIHJlZmVyZW5jZSB3aWxsIGJlIHJlc29sdmVkIHRvIGEgdmFyaWFibGUgb2YgdHlwZSBhbnkuXG4gICAgICAgIGN0eEluZGV4ID0gdGhpcy5vcFF1ZXVlLnB1c2gobmV3IFRjYkludmFsaWRSZWZlcmVuY2VPcCh0aGlzLnRjYiwgdGhpcykpIC0gMTtcbiAgICAgIH0gZWxzZSBpZiAodGFyZ2V0IGluc3RhbmNlb2YgVG1wbEFzdFRlbXBsYXRlIHx8IHRhcmdldCBpbnN0YW5jZW9mIFRtcGxBc3RFbGVtZW50KSB7XG4gICAgICAgIGN0eEluZGV4ID0gdGhpcy5vcFF1ZXVlLnB1c2gobmV3IFRjYlJlZmVyZW5jZU9wKHRoaXMudGNiLCB0aGlzLCByZWYsIG5vZGUsIHRhcmdldCkpIC0gMTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGN0eEluZGV4ID1cbiAgICAgICAgICAgIHRoaXMub3BRdWV1ZS5wdXNoKG5ldyBUY2JSZWZlcmVuY2VPcCh0aGlzLnRjYiwgdGhpcywgcmVmLCBub2RlLCB0YXJnZXQuZGlyZWN0aXZlKSkgLSAxO1xuICAgICAgfVxuICAgICAgdGhpcy5yZWZlcmVuY2VPcE1hcC5zZXQocmVmLCBjdHhJbmRleCk7XG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSBhcHBlbmREaXJlY3RpdmVzQW5kSW5wdXRzT2ZOb2RlKG5vZGU6IFRtcGxBc3RFbGVtZW50fFRtcGxBc3RUZW1wbGF0ZSk6IHZvaWQge1xuICAgIC8vIENvbGxlY3QgYWxsIHRoZSBpbnB1dHMgb24gdGhlIGVsZW1lbnQuXG4gICAgY29uc3QgY2xhaW1lZElucHV0cyA9IG5ldyBTZXQ8c3RyaW5nPigpO1xuICAgIGNvbnN0IGRpcmVjdGl2ZXMgPSB0aGlzLnRjYi5ib3VuZFRhcmdldC5nZXREaXJlY3RpdmVzT2ZOb2RlKG5vZGUpO1xuICAgIGlmIChkaXJlY3RpdmVzID09PSBudWxsIHx8IGRpcmVjdGl2ZXMubGVuZ3RoID09PSAwKSB7XG4gICAgICAvLyBJZiB0aGVyZSBhcmUgbm8gZGlyZWN0aXZlcywgdGhlbiBhbGwgaW5wdXRzIGFyZSB1bmNsYWltZWQgaW5wdXRzLCBzbyBxdWV1ZSBhbiBvcGVyYXRpb25cbiAgICAgIC8vIHRvIGFkZCB0aGVtIGlmIG5lZWRlZC5cbiAgICAgIGlmIChub2RlIGluc3RhbmNlb2YgVG1wbEFzdEVsZW1lbnQpIHtcbiAgICAgICAgdGhpcy5vcFF1ZXVlLnB1c2gobmV3IFRjYlVuY2xhaW1lZElucHV0c09wKHRoaXMudGNiLCB0aGlzLCBub2RlLCBjbGFpbWVkSW5wdXRzKSk7XG4gICAgICAgIHRoaXMub3BRdWV1ZS5wdXNoKFxuICAgICAgICAgICAgbmV3IFRjYkRvbVNjaGVtYUNoZWNrZXJPcCh0aGlzLnRjYiwgbm9kZSwgLyogY2hlY2tFbGVtZW50ICovIHRydWUsIGNsYWltZWRJbnB1dHMpKTtcbiAgICAgIH1cbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBjb25zdCBkaXJNYXAgPSBuZXcgTWFwPFR5cGVDaGVja2FibGVEaXJlY3RpdmVNZXRhLCBudW1iZXI+KCk7XG4gICAgZm9yIChjb25zdCBkaXIgb2YgZGlyZWN0aXZlcykge1xuICAgICAgbGV0IGRpcmVjdGl2ZU9wOiBUY2JPcDtcbiAgICAgIGNvbnN0IGhvc3QgPSB0aGlzLnRjYi5lbnYucmVmbGVjdG9yO1xuICAgICAgY29uc3QgZGlyUmVmID0gZGlyLnJlZiBhcyBSZWZlcmVuY2U8Q2xhc3NEZWNsYXJhdGlvbjx0cy5DbGFzc0RlY2xhcmF0aW9uPj47XG5cbiAgICAgIGlmICghZGlyLmlzR2VuZXJpYykge1xuICAgICAgICAvLyBUaGUgbW9zdCBjb21tb24gY2FzZSBpcyB0aGF0IHdoZW4gYSBkaXJlY3RpdmUgaXMgbm90IGdlbmVyaWMsIHdlIHVzZSB0aGUgbm9ybWFsXG4gICAgICAgIC8vIGBUY2JOb25EaXJlY3RpdmVUeXBlT3BgLlxuICAgICAgICBkaXJlY3RpdmVPcCA9IG5ldyBUY2JOb25HZW5lcmljRGlyZWN0aXZlVHlwZU9wKHRoaXMudGNiLCB0aGlzLCBub2RlLCBkaXIpO1xuICAgICAgfSBlbHNlIGlmIChcbiAgICAgICAgICAhcmVxdWlyZXNJbmxpbmVUeXBlQ3RvcihkaXJSZWYubm9kZSwgaG9zdCkgfHxcbiAgICAgICAgICB0aGlzLnRjYi5lbnYuY29uZmlnLnVzZUlubGluZVR5cGVDb25zdHJ1Y3RvcnMpIHtcbiAgICAgICAgLy8gRm9yIGdlbmVyaWMgZGlyZWN0aXZlcywgd2UgdXNlIGEgdHlwZSBjb25zdHJ1Y3RvciB0byBpbmZlciB0eXBlcy4gSWYgYSBkaXJlY3RpdmUgcmVxdWlyZXNcbiAgICAgICAgLy8gYW4gaW5saW5lIHR5cGUgY29uc3RydWN0b3IsIHRoZW4gaW5saW5pbmcgbXVzdCBiZSBhdmFpbGFibGUgdG8gdXNlIHRoZVxuICAgICAgICAvLyBgVGNiRGlyZWN0aXZlQ3Rvck9wYC4gSWYgbm90IHdlLCB3ZSBmYWxsYmFjayB0byB1c2luZyBgYW55YCDigJMgc2VlIGJlbG93LlxuICAgICAgICBkaXJlY3RpdmVPcCA9IG5ldyBUY2JEaXJlY3RpdmVDdG9yT3AodGhpcy50Y2IsIHRoaXMsIG5vZGUsIGRpcik7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICAvLyBJZiBpbmxpbmluZyBpcyBub3QgYXZhaWxhYmxlLCB0aGVuIHdlIGdpdmUgdXAgb24gaW5mZXJpbmcgdGhlIGdlbmVyaWMgcGFyYW1zLCBhbmQgdXNlXG4gICAgICAgIC8vIGBhbnlgIHR5cGUgZm9yIHRoZSBkaXJlY3RpdmUncyBnZW5lcmljIHBhcmFtZXRlcnMuXG4gICAgICAgIGRpcmVjdGl2ZU9wID0gbmV3IFRjYkdlbmVyaWNEaXJlY3RpdmVUeXBlV2l0aEFueVBhcmFtc09wKHRoaXMudGNiLCB0aGlzLCBub2RlLCBkaXIpO1xuICAgICAgfVxuXG4gICAgICBjb25zdCBkaXJJbmRleCA9IHRoaXMub3BRdWV1ZS5wdXNoKGRpcmVjdGl2ZU9wKSAtIDE7XG4gICAgICBkaXJNYXAuc2V0KGRpciwgZGlySW5kZXgpO1xuXG4gICAgICB0aGlzLm9wUXVldWUucHVzaChuZXcgVGNiRGlyZWN0aXZlSW5wdXRzT3AodGhpcy50Y2IsIHRoaXMsIG5vZGUsIGRpcikpO1xuICAgIH1cbiAgICB0aGlzLmRpcmVjdGl2ZU9wTWFwLnNldChub2RlLCBkaXJNYXApO1xuXG4gICAgLy8gQWZ0ZXIgZXhwYW5kaW5nIHRoZSBkaXJlY3RpdmVzLCB3ZSBtaWdodCBuZWVkIHRvIHF1ZXVlIGFuIG9wZXJhdGlvbiB0byBjaGVjayBhbnkgdW5jbGFpbWVkXG4gICAgLy8gaW5wdXRzLlxuICAgIGlmIChub2RlIGluc3RhbmNlb2YgVG1wbEFzdEVsZW1lbnQpIHtcbiAgICAgIC8vIEdvIHRocm91Z2ggdGhlIGRpcmVjdGl2ZXMgYW5kIHJlbW92ZSBhbnkgaW5wdXRzIHRoYXQgaXQgY2xhaW1zIGZyb20gYGVsZW1lbnRJbnB1dHNgLlxuICAgICAgZm9yIChjb25zdCBkaXIgb2YgZGlyZWN0aXZlcykge1xuICAgICAgICBmb3IgKGNvbnN0IHByb3BlcnR5TmFtZSBvZiBkaXIuaW5wdXRzLnByb3BlcnR5TmFtZXMpIHtcbiAgICAgICAgICBjbGFpbWVkSW5wdXRzLmFkZChwcm9wZXJ0eU5hbWUpO1xuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIHRoaXMub3BRdWV1ZS5wdXNoKG5ldyBUY2JVbmNsYWltZWRJbnB1dHNPcCh0aGlzLnRjYiwgdGhpcywgbm9kZSwgY2xhaW1lZElucHV0cykpO1xuICAgICAgLy8gSWYgdGhlcmUgYXJlIG5vIGRpcmVjdGl2ZXMgd2hpY2ggbWF0Y2ggdGhpcyBlbGVtZW50LCB0aGVuIGl0J3MgYSBcInBsYWluXCIgRE9NIGVsZW1lbnQgKG9yIGFcbiAgICAgIC8vIHdlYiBjb21wb25lbnQpLCBhbmQgc2hvdWxkIGJlIGNoZWNrZWQgYWdhaW5zdCB0aGUgRE9NIHNjaGVtYS4gSWYgYW55IGRpcmVjdGl2ZXMgbWF0Y2gsXG4gICAgICAvLyB3ZSBtdXN0IGFzc3VtZSB0aGF0IHRoZSBlbGVtZW50IGNvdWxkIGJlIGN1c3RvbSAoZWl0aGVyIGEgY29tcG9uZW50LCBvciBhIGRpcmVjdGl2ZSBsaWtlXG4gICAgICAvLyA8cm91dGVyLW91dGxldD4pIGFuZCBzaG91bGRuJ3QgdmFsaWRhdGUgdGhlIGVsZW1lbnQgbmFtZSBpdHNlbGYuXG4gICAgICBjb25zdCBjaGVja0VsZW1lbnQgPSBkaXJlY3RpdmVzLmxlbmd0aCA9PT0gMDtcbiAgICAgIHRoaXMub3BRdWV1ZS5wdXNoKG5ldyBUY2JEb21TY2hlbWFDaGVja2VyT3AodGhpcy50Y2IsIG5vZGUsIGNoZWNrRWxlbWVudCwgY2xhaW1lZElucHV0cykpO1xuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgYXBwZW5kT3V0cHV0c09mTm9kZShub2RlOiBUbXBsQXN0RWxlbWVudHxUbXBsQXN0VGVtcGxhdGUpOiB2b2lkIHtcbiAgICAvLyBDb2xsZWN0IGFsbCB0aGUgb3V0cHV0cyBvbiB0aGUgZWxlbWVudC5cbiAgICBjb25zdCBjbGFpbWVkT3V0cHV0cyA9IG5ldyBTZXQ8c3RyaW5nPigpO1xuICAgIGNvbnN0IGRpcmVjdGl2ZXMgPSB0aGlzLnRjYi5ib3VuZFRhcmdldC5nZXREaXJlY3RpdmVzT2ZOb2RlKG5vZGUpO1xuICAgIGlmIChkaXJlY3RpdmVzID09PSBudWxsIHx8IGRpcmVjdGl2ZXMubGVuZ3RoID09PSAwKSB7XG4gICAgICAvLyBJZiB0aGVyZSBhcmUgbm8gZGlyZWN0aXZlcywgdGhlbiBhbGwgb3V0cHV0cyBhcmUgdW5jbGFpbWVkIG91dHB1dHMsIHNvIHF1ZXVlIGFuIG9wZXJhdGlvblxuICAgICAgLy8gdG8gYWRkIHRoZW0gaWYgbmVlZGVkLlxuICAgICAgaWYgKG5vZGUgaW5zdGFuY2VvZiBUbXBsQXN0RWxlbWVudCkge1xuICAgICAgICB0aGlzLm9wUXVldWUucHVzaChuZXcgVGNiVW5jbGFpbWVkT3V0cHV0c09wKHRoaXMudGNiLCB0aGlzLCBub2RlLCBjbGFpbWVkT3V0cHV0cykpO1xuICAgICAgfVxuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIC8vIFF1ZXVlIG9wZXJhdGlvbnMgZm9yIGFsbCBkaXJlY3RpdmVzIHRvIGNoZWNrIHRoZSByZWxldmFudCBvdXRwdXRzIGZvciBhIGRpcmVjdGl2ZS5cbiAgICBmb3IgKGNvbnN0IGRpciBvZiBkaXJlY3RpdmVzKSB7XG4gICAgICB0aGlzLm9wUXVldWUucHVzaChuZXcgVGNiRGlyZWN0aXZlT3V0cHV0c09wKHRoaXMudGNiLCB0aGlzLCBub2RlLCBkaXIpKTtcbiAgICB9XG5cbiAgICAvLyBBZnRlciBleHBhbmRpbmcgdGhlIGRpcmVjdGl2ZXMsIHdlIG1pZ2h0IG5lZWQgdG8gcXVldWUgYW4gb3BlcmF0aW9uIHRvIGNoZWNrIGFueSB1bmNsYWltZWRcbiAgICAvLyBvdXRwdXRzLlxuICAgIGlmIChub2RlIGluc3RhbmNlb2YgVG1wbEFzdEVsZW1lbnQpIHtcbiAgICAgIC8vIEdvIHRocm91Z2ggdGhlIGRpcmVjdGl2ZXMgYW5kIHJlZ2lzdGVyIGFueSBvdXRwdXRzIHRoYXQgaXQgY2xhaW1zIGluIGBjbGFpbWVkT3V0cHV0c2AuXG4gICAgICBmb3IgKGNvbnN0IGRpciBvZiBkaXJlY3RpdmVzKSB7XG4gICAgICAgIGZvciAoY29uc3Qgb3V0cHV0UHJvcGVydHkgb2YgZGlyLm91dHB1dHMucHJvcGVydHlOYW1lcykge1xuICAgICAgICAgIGNsYWltZWRPdXRwdXRzLmFkZChvdXRwdXRQcm9wZXJ0eSk7XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgdGhpcy5vcFF1ZXVlLnB1c2gobmV3IFRjYlVuY2xhaW1lZE91dHB1dHNPcCh0aGlzLnRjYiwgdGhpcywgbm9kZSwgY2xhaW1lZE91dHB1dHMpKTtcbiAgICB9XG4gIH1cblxuICBwcml2YXRlIGFwcGVuZERlZXBTY2hlbWFDaGVja3Mobm9kZXM6IFRtcGxBc3ROb2RlW10pOiB2b2lkIHtcbiAgICBmb3IgKGNvbnN0IG5vZGUgb2Ygbm9kZXMpIHtcbiAgICAgIGlmICghKG5vZGUgaW5zdGFuY2VvZiBUbXBsQXN0RWxlbWVudCB8fCBub2RlIGluc3RhbmNlb2YgVG1wbEFzdFRlbXBsYXRlKSkge1xuICAgICAgICBjb250aW51ZTtcbiAgICAgIH1cblxuICAgICAgaWYgKG5vZGUgaW5zdGFuY2VvZiBUbXBsQXN0RWxlbWVudCkge1xuICAgICAgICBjb25zdCBjbGFpbWVkSW5wdXRzID0gbmV3IFNldDxzdHJpbmc+KCk7XG4gICAgICAgIGNvbnN0IGRpcmVjdGl2ZXMgPSB0aGlzLnRjYi5ib3VuZFRhcmdldC5nZXREaXJlY3RpdmVzT2ZOb2RlKG5vZGUpO1xuICAgICAgICBsZXQgaGFzRGlyZWN0aXZlczogYm9vbGVhbjtcbiAgICAgICAgaWYgKGRpcmVjdGl2ZXMgPT09IG51bGwgfHwgZGlyZWN0aXZlcy5sZW5ndGggPT09IDApIHtcbiAgICAgICAgICBoYXNEaXJlY3RpdmVzID0gZmFsc2U7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgaGFzRGlyZWN0aXZlcyA9IHRydWU7XG4gICAgICAgICAgZm9yIChjb25zdCBkaXIgb2YgZGlyZWN0aXZlcykge1xuICAgICAgICAgICAgZm9yIChjb25zdCBwcm9wZXJ0eU5hbWUgb2YgZGlyLmlucHV0cy5wcm9wZXJ0eU5hbWVzKSB7XG4gICAgICAgICAgICAgIGNsYWltZWRJbnB1dHMuYWRkKHByb3BlcnR5TmFtZSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHRoaXMub3BRdWV1ZS5wdXNoKG5ldyBUY2JEb21TY2hlbWFDaGVja2VyT3AodGhpcy50Y2IsIG5vZGUsICFoYXNEaXJlY3RpdmVzLCBjbGFpbWVkSW5wdXRzKSk7XG4gICAgICB9XG5cbiAgICAgIHRoaXMuYXBwZW5kRGVlcFNjaGVtYUNoZWNrcyhub2RlLmNoaWxkcmVuKTtcbiAgICB9XG4gIH1cblxuICBwcml2YXRlIGFwcGVuZEljdUV4cHJlc3Npb25zKG5vZGU6IFRtcGxBc3RJY3UpOiB2b2lkIHtcbiAgICBmb3IgKGNvbnN0IHZhcmlhYmxlIG9mIE9iamVjdC52YWx1ZXMobm9kZS52YXJzKSkge1xuICAgICAgdGhpcy5vcFF1ZXVlLnB1c2gobmV3IFRjYlRleHRJbnRlcnBvbGF0aW9uT3AodGhpcy50Y2IsIHRoaXMsIHZhcmlhYmxlKSk7XG4gICAgfVxuICAgIGZvciAoY29uc3QgcGxhY2Vob2xkZXIgb2YgT2JqZWN0LnZhbHVlcyhub2RlLnBsYWNlaG9sZGVycykpIHtcbiAgICAgIGlmIChwbGFjZWhvbGRlciBpbnN0YW5jZW9mIFRtcGxBc3RCb3VuZFRleHQpIHtcbiAgICAgICAgdGhpcy5vcFF1ZXVlLnB1c2gobmV3IFRjYlRleHRJbnRlcnBvbGF0aW9uT3AodGhpcy50Y2IsIHRoaXMsIHBsYWNlaG9sZGVyKSk7XG4gICAgICB9XG4gICAgfVxuICB9XG59XG5cbmludGVyZmFjZSBUY2JCb3VuZElucHV0IHtcbiAgYXR0cmlidXRlOiBUbXBsQXN0Qm91bmRBdHRyaWJ1dGV8VG1wbEFzdFRleHRBdHRyaWJ1dGU7XG4gIGZpZWxkTmFtZXM6IENsYXNzUHJvcGVydHlOYW1lW107XG59XG5cbi8qKlxuICogQ3JlYXRlIHRoZSBgY3R4YCBwYXJhbWV0ZXIgdG8gdGhlIHRvcC1sZXZlbCBUQ0IgZnVuY3Rpb24sIHdpdGggdGhlIGdpdmVuIGdlbmVyaWMgdHlwZSBhcmd1bWVudHMuXG4gKi9cbmZ1bmN0aW9uIHRjYkN0eFBhcmFtKFxuICAgIG5vZGU6IENsYXNzRGVjbGFyYXRpb248dHMuQ2xhc3NEZWNsYXJhdGlvbj4sIG5hbWU6IHRzLkVudGl0eU5hbWUsXG4gICAgdHlwZUFyZ3VtZW50czogdHMuVHlwZU5vZGVbXXx1bmRlZmluZWQpOiB0cy5QYXJhbWV0ZXJEZWNsYXJhdGlvbiB7XG4gIGNvbnN0IHR5cGUgPSB0cy5mYWN0b3J5LmNyZWF0ZVR5cGVSZWZlcmVuY2VOb2RlKG5hbWUsIHR5cGVBcmd1bWVudHMpO1xuICByZXR1cm4gdHMuZmFjdG9yeS5jcmVhdGVQYXJhbWV0ZXJEZWNsYXJhdGlvbihcbiAgICAgIC8qIGRlY29yYXRvcnMgKi8gdW5kZWZpbmVkLFxuICAgICAgLyogbW9kaWZpZXJzICovIHVuZGVmaW5lZCxcbiAgICAgIC8qIGRvdERvdERvdFRva2VuICovIHVuZGVmaW5lZCxcbiAgICAgIC8qIG5hbWUgKi8gJ2N0eCcsXG4gICAgICAvKiBxdWVzdGlvblRva2VuICovIHVuZGVmaW5lZCxcbiAgICAgIC8qIHR5cGUgKi8gdHlwZSxcbiAgICAgIC8qIGluaXRpYWxpemVyICovIHVuZGVmaW5lZCk7XG59XG5cbi8qKlxuICogUHJvY2VzcyBhbiBgQVNUYCBleHByZXNzaW9uIGFuZCBjb252ZXJ0IGl0IGludG8gYSBgdHMuRXhwcmVzc2lvbmAsIGdlbmVyYXRpbmcgcmVmZXJlbmNlcyB0byB0aGVcbiAqIGNvcnJlY3QgaWRlbnRpZmllcnMgaW4gdGhlIGN1cnJlbnQgc2NvcGUuXG4gKi9cbmZ1bmN0aW9uIHRjYkV4cHJlc3Npb24oYXN0OiBBU1QsIHRjYjogQ29udGV4dCwgc2NvcGU6IFNjb3BlKTogdHMuRXhwcmVzc2lvbiB7XG4gIGNvbnN0IHRyYW5zbGF0b3IgPSBuZXcgVGNiRXhwcmVzc2lvblRyYW5zbGF0b3IodGNiLCBzY29wZSk7XG4gIHJldHVybiB0cmFuc2xhdG9yLnRyYW5zbGF0ZShhc3QpO1xufVxuXG5jbGFzcyBUY2JFeHByZXNzaW9uVHJhbnNsYXRvciB7XG4gIGNvbnN0cnVjdG9yKHByb3RlY3RlZCB0Y2I6IENvbnRleHQsIHByb3RlY3RlZCBzY29wZTogU2NvcGUpIHt9XG5cbiAgdHJhbnNsYXRlKGFzdDogQVNUKTogdHMuRXhwcmVzc2lvbiB7XG4gICAgLy8gYGFzdFRvVHlwZXNjcmlwdGAgYWN0dWFsbHkgZG9lcyB0aGUgY29udmVyc2lvbi4gQSBzcGVjaWFsIHJlc29sdmVyIGB0Y2JSZXNvbHZlYCBpcyBwYXNzZWRcbiAgICAvLyB3aGljaCBpbnRlcnByZXRzIHNwZWNpZmljIGV4cHJlc3Npb24gbm9kZXMgdGhhdCBpbnRlcmFjdCB3aXRoIHRoZSBgSW1wbGljaXRSZWNlaXZlcmAuIFRoZXNlXG4gICAgLy8gbm9kZXMgYWN0dWFsbHkgcmVmZXIgdG8gaWRlbnRpZmllcnMgd2l0aGluIHRoZSBjdXJyZW50IHNjb3BlLlxuICAgIHJldHVybiBhc3RUb1R5cGVzY3JpcHQoYXN0LCBhc3QgPT4gdGhpcy5yZXNvbHZlKGFzdCksIHRoaXMudGNiLmVudi5jb25maWcpO1xuICB9XG5cbiAgLyoqXG4gICAqIFJlc29sdmUgYW4gYEFTVGAgZXhwcmVzc2lvbiB3aXRoaW4gdGhlIGdpdmVuIHNjb3BlLlxuICAgKlxuICAgKiBTb21lIGBBU1RgIGV4cHJlc3Npb25zIHJlZmVyIHRvIHRvcC1sZXZlbCBjb25jZXB0cyAocmVmZXJlbmNlcywgdmFyaWFibGVzLCB0aGUgY29tcG9uZW50XG4gICAqIGNvbnRleHQpLiBUaGlzIG1ldGhvZCBhc3Npc3RzIGluIHJlc29sdmluZyB0aG9zZS5cbiAgICovXG4gIHByb3RlY3RlZCByZXNvbHZlKGFzdDogQVNUKTogdHMuRXhwcmVzc2lvbnxudWxsIHtcbiAgICBpZiAoYXN0IGluc3RhbmNlb2YgUHJvcGVydHlSZWFkICYmIGFzdC5yZWNlaXZlciBpbnN0YW5jZW9mIEltcGxpY2l0UmVjZWl2ZXIpIHtcbiAgICAgIC8vIFRyeSB0byByZXNvbHZlIGEgYm91bmQgdGFyZ2V0IGZvciB0aGlzIGV4cHJlc3Npb24uIElmIG5vIHN1Y2ggdGFyZ2V0IGlzIGF2YWlsYWJsZSwgdGhlblxuICAgICAgLy8gdGhlIGV4cHJlc3Npb24gaXMgcmVmZXJlbmNpbmcgdGhlIHRvcC1sZXZlbCBjb21wb25lbnQgY29udGV4dC4gSW4gdGhhdCBjYXNlLCBgbnVsbGAgaXNcbiAgICAgIC8vIHJldHVybmVkIGhlcmUgdG8gbGV0IGl0IGZhbGwgdGhyb3VnaCByZXNvbHV0aW9uIHNvIGl0IHdpbGwgYmUgY2F1Z2h0IHdoZW4gdGhlXG4gICAgICAvLyBgSW1wbGljaXRSZWNlaXZlcmAgaXMgcmVzb2x2ZWQgaW4gdGhlIGJyYW5jaCBiZWxvdy5cbiAgICAgIHJldHVybiB0aGlzLnJlc29sdmVUYXJnZXQoYXN0KTtcbiAgICB9IGVsc2UgaWYgKGFzdCBpbnN0YW5jZW9mIFByb3BlcnR5V3JpdGUgJiYgYXN0LnJlY2VpdmVyIGluc3RhbmNlb2YgSW1wbGljaXRSZWNlaXZlcikge1xuICAgICAgY29uc3QgdGFyZ2V0ID0gdGhpcy5yZXNvbHZlVGFyZ2V0KGFzdCk7XG4gICAgICBpZiAodGFyZ2V0ID09PSBudWxsKSB7XG4gICAgICAgIHJldHVybiBudWxsO1xuICAgICAgfVxuXG4gICAgICBjb25zdCBleHByID0gdGhpcy50cmFuc2xhdGUoYXN0LnZhbHVlKTtcbiAgICAgIGNvbnN0IHJlc3VsdCA9IHRzLmNyZWF0ZVBhcmVuKHRzLmNyZWF0ZUJpbmFyeSh0YXJnZXQsIHRzLlN5bnRheEtpbmQuRXF1YWxzVG9rZW4sIGV4cHIpKTtcbiAgICAgIGFkZFBhcnNlU3BhbkluZm8ocmVzdWx0LCBhc3Quc291cmNlU3Bhbik7XG4gICAgICByZXR1cm4gcmVzdWx0O1xuICAgIH0gZWxzZSBpZiAoYXN0IGluc3RhbmNlb2YgSW1wbGljaXRSZWNlaXZlcikge1xuICAgICAgLy8gQVNUIGluc3RhbmNlcyByZXByZXNlbnRpbmcgdmFyaWFibGVzIGFuZCByZWZlcmVuY2VzIGxvb2sgdmVyeSBzaW1pbGFyIHRvIHByb3BlcnR5IHJlYWRzXG4gICAgICAvLyBvciBtZXRob2QgY2FsbHMgZnJvbSB0aGUgY29tcG9uZW50IGNvbnRleHQ6IGJvdGggaGF2ZSB0aGUgc2hhcGVcbiAgICAgIC8vIFByb3BlcnR5UmVhZChJbXBsaWNpdFJlY2VpdmVyLCAncHJvcE5hbWUnKSBvciBNZXRob2RDYWxsKEltcGxpY2l0UmVjZWl2ZXIsICdtZXRob2ROYW1lJykuXG4gICAgICAvL1xuICAgICAgLy8gYHRyYW5zbGF0ZWAgd2lsbCBmaXJzdCB0cnkgdG8gYHJlc29sdmVgIHRoZSBvdXRlciBQcm9wZXJ0eVJlYWQvTWV0aG9kQ2FsbC4gSWYgdGhpcyB3b3JrcyxcbiAgICAgIC8vIGl0J3MgYmVjYXVzZSB0aGUgYEJvdW5kVGFyZ2V0YCBmb3VuZCBhbiBleHByZXNzaW9uIHRhcmdldCBmb3IgdGhlIHdob2xlIGV4cHJlc3Npb24sIGFuZFxuICAgICAgLy8gdGhlcmVmb3JlIGB0cmFuc2xhdGVgIHdpbGwgbmV2ZXIgYXR0ZW1wdCB0byBgcmVzb2x2ZWAgdGhlIEltcGxpY2l0UmVjZWl2ZXIgb2YgdGhhdFxuICAgICAgLy8gUHJvcGVydHlSZWFkL01ldGhvZENhbGwuXG4gICAgICAvL1xuICAgICAgLy8gVGhlcmVmb3JlIGlmIGByZXNvbHZlYCBpcyBjYWxsZWQgb24gYW4gYEltcGxpY2l0UmVjZWl2ZXJgLCBpdCdzIGJlY2F1c2Ugbm8gb3V0ZXJcbiAgICAgIC8vIFByb3BlcnR5UmVhZC9NZXRob2RDYWxsIHJlc29sdmVkIHRvIGEgdmFyaWFibGUgb3IgcmVmZXJlbmNlLCBhbmQgdGhlcmVmb3JlIHRoaXMgaXMgYVxuICAgICAgLy8gcHJvcGVydHkgcmVhZCBvciBtZXRob2QgY2FsbCBvbiB0aGUgY29tcG9uZW50IGNvbnRleHQgaXRzZWxmLlxuICAgICAgcmV0dXJuIHRzLmNyZWF0ZUlkZW50aWZpZXIoJ2N0eCcpO1xuICAgIH0gZWxzZSBpZiAoYXN0IGluc3RhbmNlb2YgQmluZGluZ1BpcGUpIHtcbiAgICAgIGNvbnN0IGV4cHIgPSB0aGlzLnRyYW5zbGF0ZShhc3QuZXhwKTtcbiAgICAgIGNvbnN0IHBpcGVSZWYgPSB0aGlzLnRjYi5nZXRQaXBlQnlOYW1lKGFzdC5uYW1lKTtcbiAgICAgIGxldCBwaXBlOiB0cy5FeHByZXNzaW9ufG51bGw7XG4gICAgICBpZiAocGlwZVJlZiA9PT0gbnVsbCkge1xuICAgICAgICAvLyBObyBwaXBlIGJ5IHRoYXQgbmFtZSBleGlzdHMgaW4gc2NvcGUuIFJlY29yZCB0aGlzIGFzIGFuIGVycm9yLlxuICAgICAgICB0aGlzLnRjYi5vb2JSZWNvcmRlci5taXNzaW5nUGlwZSh0aGlzLnRjYi5pZCwgYXN0KTtcblxuICAgICAgICAvLyBVc2UgYW4gJ2FueScgdmFsdWUgdG8gYXQgbGVhc3QgYWxsb3cgdGhlIHJlc3Qgb2YgdGhlIGV4cHJlc3Npb24gdG8gYmUgY2hlY2tlZC5cbiAgICAgICAgcGlwZSA9IE5VTExfQVNfQU5ZO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgLy8gVXNlIGEgdmFyaWFibGUgZGVjbGFyZWQgYXMgdGhlIHBpcGUncyB0eXBlLlxuICAgICAgICBwaXBlID0gdGhpcy50Y2IuZW52LnBpcGVJbnN0KHBpcGVSZWYpO1xuICAgICAgfVxuICAgICAgY29uc3QgYXJncyA9IGFzdC5hcmdzLm1hcChhcmcgPT4gdGhpcy50cmFuc2xhdGUoYXJnKSk7XG4gICAgICBsZXQgbWV0aG9kQWNjZXNzOiB0cy5FeHByZXNzaW9uID1cbiAgICAgICAgICB0cy5mYWN0b3J5LmNyZWF0ZVByb3BlcnR5QWNjZXNzRXhwcmVzc2lvbihwaXBlLCAndHJhbnNmb3JtJyk7XG4gICAgICBhZGRQYXJzZVNwYW5JbmZvKG1ldGhvZEFjY2VzcywgYXN0Lm5hbWVTcGFuKTtcbiAgICAgIGlmICghdGhpcy50Y2IuZW52LmNvbmZpZy5jaGVja1R5cGVPZlBpcGVzKSB7XG4gICAgICAgIG1ldGhvZEFjY2VzcyA9IHRzLmZhY3RvcnkuY3JlYXRlQXNFeHByZXNzaW9uKFxuICAgICAgICAgICAgbWV0aG9kQWNjZXNzLCB0cy5mYWN0b3J5LmNyZWF0ZUtleXdvcmRUeXBlTm9kZSh0cy5TeW50YXhLaW5kLkFueUtleXdvcmQpKTtcbiAgICAgIH1cblxuICAgICAgY29uc3QgcmVzdWx0ID0gdHMuY3JlYXRlQ2FsbChcbiAgICAgICAgICAvKiBleHByZXNzaW9uICovIG1ldGhvZEFjY2VzcyxcbiAgICAgICAgICAvKiB0eXBlQXJndW1lbnRzICovIHVuZGVmaW5lZCxcbiAgICAgICAgICAvKiBhcmd1bWVudHNBcnJheSAqL1tleHByLCAuLi5hcmdzXSk7XG4gICAgICBhZGRQYXJzZVNwYW5JbmZvKHJlc3VsdCwgYXN0LnNvdXJjZVNwYW4pO1xuICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICB9IGVsc2UgaWYgKFxuICAgICAgICBhc3QgaW5zdGFuY2VvZiBNZXRob2RDYWxsICYmIGFzdC5yZWNlaXZlciBpbnN0YW5jZW9mIEltcGxpY2l0UmVjZWl2ZXIgJiZcbiAgICAgICAgIShhc3QucmVjZWl2ZXIgaW5zdGFuY2VvZiBUaGlzUmVjZWl2ZXIpKSB7XG4gICAgICAvLyBSZXNvbHZlIHRoZSBzcGVjaWFsIGAkYW55KGV4cHIpYCBzeW50YXggdG8gaW5zZXJ0IGEgY2FzdCBvZiB0aGUgYXJndW1lbnQgdG8gdHlwZSBgYW55YC5cbiAgICAgIC8vIGAkYW55KGV4cHIpYCAtPiBgZXhwciBhcyBhbnlgXG4gICAgICBpZiAoYXN0Lm5hbWUgPT09ICckYW55JyAmJiBhc3QuYXJncy5sZW5ndGggPT09IDEpIHtcbiAgICAgICAgY29uc3QgZXhwciA9IHRoaXMudHJhbnNsYXRlKGFzdC5hcmdzWzBdKTtcbiAgICAgICAgY29uc3QgZXhwckFzQW55ID1cbiAgICAgICAgICAgIHRzLmNyZWF0ZUFzRXhwcmVzc2lvbihleHByLCB0cy5jcmVhdGVLZXl3b3JkVHlwZU5vZGUodHMuU3ludGF4S2luZC5BbnlLZXl3b3JkKSk7XG4gICAgICAgIGNvbnN0IHJlc3VsdCA9IHRzLmNyZWF0ZVBhcmVuKGV4cHJBc0FueSk7XG4gICAgICAgIGFkZFBhcnNlU3BhbkluZm8ocmVzdWx0LCBhc3Quc291cmNlU3Bhbik7XG4gICAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgICB9XG5cbiAgICAgIC8vIEF0dGVtcHQgdG8gcmVzb2x2ZSBhIGJvdW5kIHRhcmdldCBmb3IgdGhlIG1ldGhvZCwgYW5kIGdlbmVyYXRlIHRoZSBtZXRob2QgY2FsbCBpZiBhIHRhcmdldFxuICAgICAgLy8gY291bGQgYmUgcmVzb2x2ZWQuIElmIG5vIHRhcmdldCBpcyBhdmFpbGFibGUsIHRoZW4gdGhlIG1ldGhvZCBpcyByZWZlcmVuY2luZyB0aGUgdG9wLWxldmVsXG4gICAgICAvLyBjb21wb25lbnQgY29udGV4dCwgaW4gd2hpY2ggY2FzZSBgbnVsbGAgaXMgcmV0dXJuZWQgdG8gbGV0IHRoZSBgSW1wbGljaXRSZWNlaXZlcmAgYmVpbmdcbiAgICAgIC8vIHJlc29sdmVkIHRvIHRoZSBjb21wb25lbnQgY29udGV4dC5cbiAgICAgIGNvbnN0IHJlY2VpdmVyID0gdGhpcy5yZXNvbHZlVGFyZ2V0KGFzdCk7XG4gICAgICBpZiAocmVjZWl2ZXIgPT09IG51bGwpIHtcbiAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgICB9XG5cbiAgICAgIGNvbnN0IG1ldGhvZCA9IHdyYXBGb3JEaWFnbm9zdGljcyhyZWNlaXZlcik7XG4gICAgICBhZGRQYXJzZVNwYW5JbmZvKG1ldGhvZCwgYXN0Lm5hbWVTcGFuKTtcbiAgICAgIGNvbnN0IGFyZ3MgPSBhc3QuYXJncy5tYXAoYXJnID0+IHRoaXMudHJhbnNsYXRlKGFyZykpO1xuICAgICAgY29uc3Qgbm9kZSA9IHRzLmNyZWF0ZUNhbGwobWV0aG9kLCB1bmRlZmluZWQsIGFyZ3MpO1xuICAgICAgYWRkUGFyc2VTcGFuSW5mbyhub2RlLCBhc3Quc291cmNlU3Bhbik7XG4gICAgICByZXR1cm4gbm9kZTtcbiAgICB9IGVsc2Uge1xuICAgICAgLy8gVGhpcyBBU1QgaXNuJ3Qgc3BlY2lhbCBhZnRlciBhbGwuXG4gICAgICByZXR1cm4gbnVsbDtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogQXR0ZW1wdHMgdG8gcmVzb2x2ZSBhIGJvdW5kIHRhcmdldCBmb3IgYSBnaXZlbiBleHByZXNzaW9uLCBhbmQgdHJhbnNsYXRlcyBpdCBpbnRvIHRoZVxuICAgKiBhcHByb3ByaWF0ZSBgdHMuRXhwcmVzc2lvbmAgdGhhdCByZXByZXNlbnRzIHRoZSBib3VuZCB0YXJnZXQuIElmIG5vIHRhcmdldCBpcyBhdmFpbGFibGUsXG4gICAqIGBudWxsYCBpcyByZXR1cm5lZC5cbiAgICovXG4gIHByb3RlY3RlZCByZXNvbHZlVGFyZ2V0KGFzdDogQVNUKTogdHMuRXhwcmVzc2lvbnxudWxsIHtcbiAgICBjb25zdCBiaW5kaW5nID0gdGhpcy50Y2IuYm91bmRUYXJnZXQuZ2V0RXhwcmVzc2lvblRhcmdldChhc3QpO1xuICAgIGlmIChiaW5kaW5nID09PSBudWxsKSB7XG4gICAgICByZXR1cm4gbnVsbDtcbiAgICB9XG5cbiAgICBjb25zdCBleHByID0gdGhpcy5zY29wZS5yZXNvbHZlKGJpbmRpbmcpO1xuICAgIGFkZFBhcnNlU3BhbkluZm8oZXhwciwgYXN0LnNvdXJjZVNwYW4pO1xuICAgIHJldHVybiBleHByO1xuICB9XG59XG5cbi8qKlxuICogQ2FsbCB0aGUgdHlwZSBjb25zdHJ1Y3RvciBvZiBhIGRpcmVjdGl2ZSBpbnN0YW5jZSBvbiBhIGdpdmVuIHRlbXBsYXRlIG5vZGUsIGluZmVycmluZyBhIHR5cGUgZm9yXG4gKiB0aGUgZGlyZWN0aXZlIGluc3RhbmNlIGZyb20gYW55IGJvdW5kIGlucHV0cy5cbiAqL1xuZnVuY3Rpb24gdGNiQ2FsbFR5cGVDdG9yKFxuICAgIGRpcjogVHlwZUNoZWNrYWJsZURpcmVjdGl2ZU1ldGEsIHRjYjogQ29udGV4dCwgaW5wdXRzOiBUY2JEaXJlY3RpdmVJbnB1dFtdKTogdHMuRXhwcmVzc2lvbiB7XG4gIGNvbnN0IHR5cGVDdG9yID0gdGNiLmVudi50eXBlQ3RvckZvcihkaXIpO1xuXG4gIC8vIENvbnN0cnVjdCBhbiBhcnJheSBvZiBgdHMuUHJvcGVydHlBc3NpZ25tZW50YHMgZm9yIGVhY2ggb2YgdGhlIGRpcmVjdGl2ZSdzIGlucHV0cy5cbiAgY29uc3QgbWVtYmVycyA9IGlucHV0cy5tYXAoaW5wdXQgPT4ge1xuICAgIGNvbnN0IHByb3BlcnR5TmFtZSA9IHRzLmNyZWF0ZVN0cmluZ0xpdGVyYWwoaW5wdXQuZmllbGQpO1xuXG4gICAgaWYgKGlucHV0LnR5cGUgPT09ICdiaW5kaW5nJykge1xuICAgICAgLy8gRm9yIGJvdW5kIGlucHV0cywgdGhlIHByb3BlcnR5IGlzIGFzc2lnbmVkIHRoZSBiaW5kaW5nIGV4cHJlc3Npb24uXG4gICAgICBsZXQgZXhwciA9IGlucHV0LmV4cHJlc3Npb247XG4gICAgICBpZiAoIXRjYi5lbnYuY29uZmlnLmNoZWNrVHlwZU9mSW5wdXRCaW5kaW5ncykge1xuICAgICAgICAvLyBJZiBjaGVja2luZyB0aGUgdHlwZSBvZiBiaW5kaW5ncyBpcyBkaXNhYmxlZCwgY2FzdCB0aGUgcmVzdWx0aW5nIGV4cHJlc3Npb24gdG8gJ2FueSdcbiAgICAgICAgLy8gYmVmb3JlIHRoZSBhc3NpZ25tZW50LlxuICAgICAgICBleHByID0gdHNDYXN0VG9BbnkoZXhwcik7XG4gICAgICB9IGVsc2UgaWYgKCF0Y2IuZW52LmNvbmZpZy5zdHJpY3ROdWxsSW5wdXRCaW5kaW5ncykge1xuICAgICAgICAvLyBJZiBzdHJpY3QgbnVsbCBjaGVja3MgYXJlIGRpc2FibGVkLCBlcmFzZSBgbnVsbGAgYW5kIGB1bmRlZmluZWRgIGZyb20gdGhlIHR5cGUgYnlcbiAgICAgICAgLy8gd3JhcHBpbmcgdGhlIGV4cHJlc3Npb24gaW4gYSBub24tbnVsbCBhc3NlcnRpb24uXG4gICAgICAgIGV4cHIgPSB0cy5jcmVhdGVOb25OdWxsRXhwcmVzc2lvbihleHByKTtcbiAgICAgIH1cblxuICAgICAgY29uc3QgYXNzaWdubWVudCA9IHRzLmNyZWF0ZVByb3BlcnR5QXNzaWdubWVudChwcm9wZXJ0eU5hbWUsIHdyYXBGb3JEaWFnbm9zdGljcyhleHByKSk7XG4gICAgICBhZGRQYXJzZVNwYW5JbmZvKGFzc2lnbm1lbnQsIGlucHV0LnNvdXJjZVNwYW4pO1xuICAgICAgcmV0dXJuIGFzc2lnbm1lbnQ7XG4gICAgfSBlbHNlIHtcbiAgICAgIC8vIEEgdHlwZSBjb25zdHJ1Y3RvciBpcyByZXF1aXJlZCB0byBiZSBjYWxsZWQgd2l0aCBhbGwgaW5wdXQgcHJvcGVydGllcywgc28gYW55IHVuc2V0XG4gICAgICAvLyBpbnB1dHMgYXJlIHNpbXBseSBhc3NpZ25lZCBhIHZhbHVlIG9mIHR5cGUgYGFueWAgdG8gaWdub3JlIHRoZW0uXG4gICAgICByZXR1cm4gdHMuY3JlYXRlUHJvcGVydHlBc3NpZ25tZW50KHByb3BlcnR5TmFtZSwgTlVMTF9BU19BTlkpO1xuICAgIH1cbiAgfSk7XG5cbiAgLy8gQ2FsbCB0aGUgYG5nVHlwZUN0b3JgIG1ldGhvZCBvbiB0aGUgZGlyZWN0aXZlIGNsYXNzLCB3aXRoIGFuIG9iamVjdCBsaXRlcmFsIGFyZ3VtZW50IGNyZWF0ZWRcbiAgLy8gZnJvbSB0aGUgbWF0Y2hlZCBpbnB1dHMuXG4gIHJldHVybiB0cy5jcmVhdGVDYWxsKFxuICAgICAgLyogZXhwcmVzc2lvbiAqLyB0eXBlQ3RvcixcbiAgICAgIC8qIHR5cGVBcmd1bWVudHMgKi8gdW5kZWZpbmVkLFxuICAgICAgLyogYXJndW1lbnRzQXJyYXkgKi9bdHMuY3JlYXRlT2JqZWN0TGl0ZXJhbChtZW1iZXJzKV0pO1xufVxuXG5mdW5jdGlvbiBnZXRCb3VuZElucHV0cyhcbiAgICBkaXJlY3RpdmU6IFR5cGVDaGVja2FibGVEaXJlY3RpdmVNZXRhLCBub2RlOiBUbXBsQXN0VGVtcGxhdGV8VG1wbEFzdEVsZW1lbnQsXG4gICAgdGNiOiBDb250ZXh0KTogVGNiQm91bmRJbnB1dFtdIHtcbiAgY29uc3QgYm91bmRJbnB1dHM6IFRjYkJvdW5kSW5wdXRbXSA9IFtdO1xuXG4gIGNvbnN0IHByb2Nlc3NBdHRyaWJ1dGUgPSAoYXR0cjogVG1wbEFzdEJvdW5kQXR0cmlidXRlfFRtcGxBc3RUZXh0QXR0cmlidXRlKSA9PiB7XG4gICAgLy8gU2tpcCBub24tcHJvcGVydHkgYmluZGluZ3MuXG4gICAgaWYgKGF0dHIgaW5zdGFuY2VvZiBUbXBsQXN0Qm91bmRBdHRyaWJ1dGUgJiYgYXR0ci50eXBlICE9PSBCaW5kaW5nVHlwZS5Qcm9wZXJ0eSkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIC8vIFNraXAgdGhlIGF0dHJpYnV0ZSBpZiB0aGUgZGlyZWN0aXZlIGRvZXMgbm90IGhhdmUgYW4gaW5wdXQgZm9yIGl0LlxuICAgIGNvbnN0IGlucHV0cyA9IGRpcmVjdGl2ZS5pbnB1dHMuZ2V0QnlCaW5kaW5nUHJvcGVydHlOYW1lKGF0dHIubmFtZSk7XG4gICAgaWYgKGlucHV0cyA9PT0gbnVsbCkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBjb25zdCBmaWVsZE5hbWVzID0gaW5wdXRzLm1hcChpbnB1dCA9PiBpbnB1dC5jbGFzc1Byb3BlcnR5TmFtZSk7XG4gICAgYm91bmRJbnB1dHMucHVzaCh7YXR0cmlidXRlOiBhdHRyLCBmaWVsZE5hbWVzfSk7XG4gIH07XG5cbiAgbm9kZS5pbnB1dHMuZm9yRWFjaChwcm9jZXNzQXR0cmlidXRlKTtcbiAgbm9kZS5hdHRyaWJ1dGVzLmZvckVhY2gocHJvY2Vzc0F0dHJpYnV0ZSk7XG4gIGlmIChub2RlIGluc3RhbmNlb2YgVG1wbEFzdFRlbXBsYXRlKSB7XG4gICAgbm9kZS50ZW1wbGF0ZUF0dHJzLmZvckVhY2gocHJvY2Vzc0F0dHJpYnV0ZSk7XG4gIH1cblxuICByZXR1cm4gYm91bmRJbnB1dHM7XG59XG5cbi8qKlxuICogVHJhbnNsYXRlcyB0aGUgZ2l2ZW4gYXR0cmlidXRlIGJpbmRpbmcgdG8gYSBgdHMuRXhwcmVzc2lvbmAuXG4gKi9cbmZ1bmN0aW9uIHRyYW5zbGF0ZUlucHV0KFxuICAgIGF0dHI6IFRtcGxBc3RCb3VuZEF0dHJpYnV0ZXxUbXBsQXN0VGV4dEF0dHJpYnV0ZSwgdGNiOiBDb250ZXh0LCBzY29wZTogU2NvcGUpOiB0cy5FeHByZXNzaW9uIHtcbiAgaWYgKGF0dHIgaW5zdGFuY2VvZiBUbXBsQXN0Qm91bmRBdHRyaWJ1dGUpIHtcbiAgICAvLyBQcm9kdWNlIGFuIGV4cHJlc3Npb24gcmVwcmVzZW50aW5nIHRoZSB2YWx1ZSBvZiB0aGUgYmluZGluZy5cbiAgICByZXR1cm4gdGNiRXhwcmVzc2lvbihhdHRyLnZhbHVlLCB0Y2IsIHNjb3BlKTtcbiAgfSBlbHNlIHtcbiAgICAvLyBGb3IgcmVndWxhciBhdHRyaWJ1dGVzIHdpdGggYSBzdGF0aWMgc3RyaW5nIHZhbHVlLCB1c2UgdGhlIHJlcHJlc2VudGVkIHN0cmluZyBsaXRlcmFsLlxuICAgIHJldHVybiB0cy5jcmVhdGVTdHJpbmdMaXRlcmFsKGF0dHIudmFsdWUpO1xuICB9XG59XG5cbi8qKlxuICogQW4gaW5wdXQgYmluZGluZyB0aGF0IGNvcnJlc3BvbmRzIHdpdGggYSBmaWVsZCBvZiBhIGRpcmVjdGl2ZS5cbiAqL1xuaW50ZXJmYWNlIFRjYkRpcmVjdGl2ZUJvdW5kSW5wdXQge1xuICB0eXBlOiAnYmluZGluZyc7XG5cbiAgLyoqXG4gICAqIFRoZSBuYW1lIG9mIGEgZmllbGQgb24gdGhlIGRpcmVjdGl2ZSB0aGF0IGlzIHNldC5cbiAgICovXG4gIGZpZWxkOiBzdHJpbmc7XG5cbiAgLyoqXG4gICAqIFRoZSBgdHMuRXhwcmVzc2lvbmAgY29ycmVzcG9uZGluZyB3aXRoIHRoZSBpbnB1dCBiaW5kaW5nIGV4cHJlc3Npb24uXG4gICAqL1xuICBleHByZXNzaW9uOiB0cy5FeHByZXNzaW9uO1xuXG4gIC8qKlxuICAgKiBUaGUgc291cmNlIHNwYW4gb2YgdGhlIGZ1bGwgYXR0cmlidXRlIGJpbmRpbmcuXG4gICAqL1xuICBzb3VyY2VTcGFuOiBQYXJzZVNvdXJjZVNwYW47XG59XG5cbi8qKlxuICogSW5kaWNhdGVzIHRoYXQgYSBjZXJ0YWluIGZpZWxkIG9mIGEgZGlyZWN0aXZlIGRvZXMgbm90IGhhdmUgYSBjb3JyZXNwb25kaW5nIGlucHV0IGJpbmRpbmcuXG4gKi9cbmludGVyZmFjZSBUY2JEaXJlY3RpdmVVbnNldElucHV0IHtcbiAgdHlwZTogJ3Vuc2V0JztcblxuICAvKipcbiAgICogVGhlIG5hbWUgb2YgYSBmaWVsZCBvbiB0aGUgZGlyZWN0aXZlIGZvciB3aGljaCBubyBpbnB1dCBiaW5kaW5nIGlzIHByZXNlbnQuXG4gICAqL1xuICBmaWVsZDogc3RyaW5nO1xufVxuXG50eXBlIFRjYkRpcmVjdGl2ZUlucHV0ID0gVGNiRGlyZWN0aXZlQm91bmRJbnB1dHxUY2JEaXJlY3RpdmVVbnNldElucHV0O1xuXG5jb25zdCBFVkVOVF9QQVJBTUVURVIgPSAnJGV2ZW50JztcblxuY29uc3QgZW51bSBFdmVudFBhcmFtVHlwZSB7XG4gIC8qIEdlbmVyYXRlcyBjb2RlIHRvIGluZmVyIHRoZSB0eXBlIG9mIGAkZXZlbnRgIGJhc2VkIG9uIGhvdyB0aGUgbGlzdGVuZXIgaXMgcmVnaXN0ZXJlZC4gKi9cbiAgSW5mZXIsXG5cbiAgLyogRGVjbGFyZXMgdGhlIHR5cGUgb2YgdGhlIGAkZXZlbnRgIHBhcmFtZXRlciBhcyBgYW55YC4gKi9cbiAgQW55LFxufVxuXG4vKipcbiAqIENyZWF0ZXMgYW4gYXJyb3cgZnVuY3Rpb24gdG8gYmUgdXNlZCBhcyBoYW5kbGVyIGZ1bmN0aW9uIGZvciBldmVudCBiaW5kaW5ncy4gVGhlIGhhbmRsZXJcbiAqIGZ1bmN0aW9uIGhhcyBhIHNpbmdsZSBwYXJhbWV0ZXIgYCRldmVudGAgYW5kIHRoZSBib3VuZCBldmVudCdzIGhhbmRsZXIgYEFTVGAgcmVwcmVzZW50ZWQgYXMgYVxuICogVHlwZVNjcmlwdCBleHByZXNzaW9uIGFzIGl0cyBib2R5LlxuICpcbiAqIFdoZW4gYGV2ZW50VHlwZWAgaXMgc2V0IHRvIGBJbmZlcmAsIHRoZSBgJGV2ZW50YCBwYXJhbWV0ZXIgd2lsbCBub3QgaGF2ZSBhbiBleHBsaWNpdCB0eXBlLiBUaGlzXG4gKiBhbGxvd3MgZm9yIHRoZSBjcmVhdGVkIGhhbmRsZXIgZnVuY3Rpb24gdG8gaGF2ZSBpdHMgYCRldmVudGAgcGFyYW1ldGVyJ3MgdHlwZSBpbmZlcnJlZCBiYXNlZCBvblxuICogaG93IGl0J3MgdXNlZCwgdG8gZW5hYmxlIHN0cmljdCB0eXBlIGNoZWNraW5nIG9mIGV2ZW50IGJpbmRpbmdzLiBXaGVuIHNldCB0byBgQW55YCwgdGhlIGAkZXZlbnRgXG4gKiBwYXJhbWV0ZXIgd2lsbCBoYXZlIGFuIGV4cGxpY2l0IGBhbnlgIHR5cGUsIGVmZmVjdGl2ZWx5IGRpc2FibGluZyBzdHJpY3QgdHlwZSBjaGVja2luZyBvZiBldmVudFxuICogYmluZGluZ3MuIEFsdGVybmF0aXZlbHksIGFuIGV4cGxpY2l0IHR5cGUgY2FuIGJlIHBhc3NlZCBmb3IgdGhlIGAkZXZlbnRgIHBhcmFtZXRlci5cbiAqL1xuZnVuY3Rpb24gdGNiQ3JlYXRlRXZlbnRIYW5kbGVyKFxuICAgIGV2ZW50OiBUbXBsQXN0Qm91bmRFdmVudCwgdGNiOiBDb250ZXh0LCBzY29wZTogU2NvcGUsXG4gICAgZXZlbnRUeXBlOiBFdmVudFBhcmFtVHlwZXx0cy5UeXBlTm9kZSk6IHRzLkV4cHJlc3Npb24ge1xuICBjb25zdCBoYW5kbGVyID0gdGNiRXZlbnRIYW5kbGVyRXhwcmVzc2lvbihldmVudC5oYW5kbGVyLCB0Y2IsIHNjb3BlKTtcblxuICBsZXQgZXZlbnRQYXJhbVR5cGU6IHRzLlR5cGVOb2RlfHVuZGVmaW5lZDtcbiAgaWYgKGV2ZW50VHlwZSA9PT0gRXZlbnRQYXJhbVR5cGUuSW5mZXIpIHtcbiAgICBldmVudFBhcmFtVHlwZSA9IHVuZGVmaW5lZDtcbiAgfSBlbHNlIGlmIChldmVudFR5cGUgPT09IEV2ZW50UGFyYW1UeXBlLkFueSkge1xuICAgIGV2ZW50UGFyYW1UeXBlID0gdHMuY3JlYXRlS2V5d29yZFR5cGVOb2RlKHRzLlN5bnRheEtpbmQuQW55S2V5d29yZCk7XG4gIH0gZWxzZSB7XG4gICAgZXZlbnRQYXJhbVR5cGUgPSBldmVudFR5cGU7XG4gIH1cblxuICAvLyBPYnRhaW4gYWxsIGd1YXJkcyB0aGF0IGhhdmUgYmVlbiBhcHBsaWVkIHRvIHRoZSBzY29wZSBhbmQgaXRzIHBhcmVudHMsIGFzIHRoZXkgaGF2ZSB0byBiZVxuICAvLyByZXBlYXRlZCB3aXRoaW4gdGhlIGhhbmRsZXIgZnVuY3Rpb24gZm9yIHRoZWlyIG5hcnJvd2luZyB0byBiZSBpbiBlZmZlY3Qgd2l0aGluIHRoZSBoYW5kbGVyLlxuICBjb25zdCBndWFyZHMgPSBzY29wZS5ndWFyZHMoKTtcblxuICBsZXQgYm9keTogdHMuU3RhdGVtZW50ID0gdHMuY3JlYXRlRXhwcmVzc2lvblN0YXRlbWVudChoYW5kbGVyKTtcbiAgaWYgKGd1YXJkcyAhPT0gbnVsbCkge1xuICAgIC8vIFdyYXAgdGhlIGJvZHkgaW4gYW4gYGlmYCBzdGF0ZW1lbnQgY29udGFpbmluZyBhbGwgZ3VhcmRzIHRoYXQgaGF2ZSB0byBiZSBhcHBsaWVkLlxuICAgIGJvZHkgPSB0cy5jcmVhdGVJZihndWFyZHMsIGJvZHkpO1xuICB9XG5cbiAgY29uc3QgZXZlbnRQYXJhbSA9IHRzLmNyZWF0ZVBhcmFtZXRlcihcbiAgICAgIC8qIGRlY29yYXRvcnMgKi8gdW5kZWZpbmVkLFxuICAgICAgLyogbW9kaWZpZXJzICovIHVuZGVmaW5lZCxcbiAgICAgIC8qIGRvdERvdERvdFRva2VuICovIHVuZGVmaW5lZCxcbiAgICAgIC8qIG5hbWUgKi8gRVZFTlRfUEFSQU1FVEVSLFxuICAgICAgLyogcXVlc3Rpb25Ub2tlbiAqLyB1bmRlZmluZWQsXG4gICAgICAvKiB0eXBlICovIGV2ZW50UGFyYW1UeXBlKTtcbiAgYWRkRXhwcmVzc2lvbklkZW50aWZpZXIoZXZlbnRQYXJhbSwgRXhwcmVzc2lvbklkZW50aWZpZXIuRVZFTlRfUEFSQU1FVEVSKTtcblxuICByZXR1cm4gdHMuY3JlYXRlRnVuY3Rpb25FeHByZXNzaW9uKFxuICAgICAgLyogbW9kaWZpZXIgKi8gdW5kZWZpbmVkLFxuICAgICAgLyogYXN0ZXJpc2tUb2tlbiAqLyB1bmRlZmluZWQsXG4gICAgICAvKiBuYW1lICovIHVuZGVmaW5lZCxcbiAgICAgIC8qIHR5cGVQYXJhbWV0ZXJzICovIHVuZGVmaW5lZCxcbiAgICAgIC8qIHBhcmFtZXRlcnMgKi9bZXZlbnRQYXJhbV0sXG4gICAgICAvKiB0eXBlICovIHRzLmNyZWF0ZUtleXdvcmRUeXBlTm9kZSh0cy5TeW50YXhLaW5kLkFueUtleXdvcmQpLFxuICAgICAgLyogYm9keSAqLyB0cy5jcmVhdGVCbG9jayhbYm9keV0pKTtcbn1cblxuLyoqXG4gKiBTaW1pbGFyIHRvIGB0Y2JFeHByZXNzaW9uYCwgdGhpcyBmdW5jdGlvbiBjb252ZXJ0cyB0aGUgcHJvdmlkZWQgYEFTVGAgZXhwcmVzc2lvbiBpbnRvIGFcbiAqIGB0cy5FeHByZXNzaW9uYCwgd2l0aCBzcGVjaWFsIGhhbmRsaW5nIG9mIHRoZSBgJGV2ZW50YCB2YXJpYWJsZSB0aGF0IGNhbiBiZSB1c2VkIHdpdGhpbiBldmVudFxuICogYmluZGluZ3MuXG4gKi9cbmZ1bmN0aW9uIHRjYkV2ZW50SGFuZGxlckV4cHJlc3Npb24oYXN0OiBBU1QsIHRjYjogQ29udGV4dCwgc2NvcGU6IFNjb3BlKTogdHMuRXhwcmVzc2lvbiB7XG4gIGNvbnN0IHRyYW5zbGF0b3IgPSBuZXcgVGNiRXZlbnRIYW5kbGVyVHJhbnNsYXRvcih0Y2IsIHNjb3BlKTtcbiAgcmV0dXJuIHRyYW5zbGF0b3IudHJhbnNsYXRlKGFzdCk7XG59XG5cbmNsYXNzIFRjYkV2ZW50SGFuZGxlclRyYW5zbGF0b3IgZXh0ZW5kcyBUY2JFeHByZXNzaW9uVHJhbnNsYXRvciB7XG4gIHByb3RlY3RlZCByZXNvbHZlKGFzdDogQVNUKTogdHMuRXhwcmVzc2lvbnxudWxsIHtcbiAgICAvLyBSZWNvZ25pemUgYSBwcm9wZXJ0eSByZWFkIG9uIHRoZSBpbXBsaWNpdCByZWNlaXZlciBjb3JyZXNwb25kaW5nIHdpdGggdGhlIGV2ZW50IHBhcmFtZXRlclxuICAgIC8vIHRoYXQgaXMgYXZhaWxhYmxlIGluIGV2ZW50IGJpbmRpbmdzLiBTaW5jZSB0aGlzIHZhcmlhYmxlIGlzIGEgcGFyYW1ldGVyIG9mIHRoZSBoYW5kbGVyXG4gICAgLy8gZnVuY3Rpb24gdGhhdCB0aGUgY29udmVydGVkIGV4cHJlc3Npb24gYmVjb21lcyBhIGNoaWxkIG9mLCBqdXN0IGNyZWF0ZSBhIHJlZmVyZW5jZSB0byB0aGVcbiAgICAvLyBwYXJhbWV0ZXIgYnkgaXRzIG5hbWUuXG4gICAgaWYgKGFzdCBpbnN0YW5jZW9mIFByb3BlcnR5UmVhZCAmJiBhc3QucmVjZWl2ZXIgaW5zdGFuY2VvZiBJbXBsaWNpdFJlY2VpdmVyICYmXG4gICAgICAgICEoYXN0LnJlY2VpdmVyIGluc3RhbmNlb2YgVGhpc1JlY2VpdmVyKSAmJiBhc3QubmFtZSA9PT0gRVZFTlRfUEFSQU1FVEVSKSB7XG4gICAgICBjb25zdCBldmVudCA9IHRzLmNyZWF0ZUlkZW50aWZpZXIoRVZFTlRfUEFSQU1FVEVSKTtcbiAgICAgIGFkZFBhcnNlU3BhbkluZm8oZXZlbnQsIGFzdC5uYW1lU3Bhbik7XG4gICAgICByZXR1cm4gZXZlbnQ7XG4gICAgfVxuXG4gICAgcmV0dXJuIHN1cGVyLnJlc29sdmUoYXN0KTtcbiAgfVxufVxuIl19