aws-cdk 0.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (402) hide show
  1. package/CONTRIBUTING.md +276 -0
  2. package/LICENSE +202 -0
  3. package/NOTICE +16 -0
  4. package/README.md +1274 -0
  5. package/THIRD_PARTY_LICENSES +26821 -0
  6. package/bin/cdk +6 -0
  7. package/build-info.json +4 -0
  8. package/db.json.gz +0 -0
  9. package/generate.sh +25 -0
  10. package/images/garbage-collection.png +0 -0
  11. package/lib/api/aws-auth/account-cache.d.ts +39 -0
  12. package/lib/api/aws-auth/account-cache.js +102 -0
  13. package/lib/api/aws-auth/awscli-compatible.d.ts +42 -0
  14. package/lib/api/aws-auth/awscli-compatible.js +264 -0
  15. package/lib/api/aws-auth/cached.d.ts +11 -0
  16. package/lib/api/aws-auth/cached.js +26 -0
  17. package/lib/api/aws-auth/credential-plugins.d.ts +36 -0
  18. package/lib/api/aws-auth/credential-plugins.js +153 -0
  19. package/lib/api/aws-auth/index.d.ts +3 -0
  20. package/lib/api/aws-auth/index.js +20 -0
  21. package/lib/api/aws-auth/provider-caching.d.ts +13 -0
  22. package/lib/api/aws-auth/provider-caching.js +24 -0
  23. package/lib/api/aws-auth/sdk-logger.d.ts +69 -0
  24. package/lib/api/aws-auth/sdk-logger.js +130 -0
  25. package/lib/api/aws-auth/sdk-provider.d.ts +207 -0
  26. package/lib/api/aws-auth/sdk-provider.js +359 -0
  27. package/lib/api/aws-auth/sdk.d.ts +223 -0
  28. package/lib/api/aws-auth/sdk.js +366 -0
  29. package/lib/api/aws-auth/tracing.d.ts +11 -0
  30. package/lib/api/aws-auth/tracing.js +61 -0
  31. package/lib/api/aws-auth/user-agent.d.ts +7 -0
  32. package/lib/api/aws-auth/user-agent.js +21 -0
  33. package/lib/api/aws-auth/util.d.ts +6 -0
  34. package/lib/api/aws-auth/util.js +23 -0
  35. package/lib/api/bootstrap/bootstrap-environment.d.ts +33 -0
  36. package/lib/api/bootstrap/bootstrap-environment.js +322 -0
  37. package/lib/api/bootstrap/bootstrap-props.d.ts +130 -0
  38. package/lib/api/bootstrap/bootstrap-props.js +14 -0
  39. package/lib/api/bootstrap/bootstrap-template.yaml +692 -0
  40. package/lib/api/bootstrap/deploy-bootstrap.d.ts +37 -0
  41. package/lib/api/bootstrap/deploy-bootstrap.js +143 -0
  42. package/lib/api/bootstrap/index.d.ts +2 -0
  43. package/lib/api/bootstrap/index.js +19 -0
  44. package/lib/api/bootstrap/legacy-template.d.ts +2 -0
  45. package/lib/api/bootstrap/legacy-template.js +82 -0
  46. package/lib/api/context.d.ts +40 -0
  47. package/lib/api/context.js +82 -0
  48. package/lib/api/cxapp/cloud-assembly.d.ts +150 -0
  49. package/lib/api/cxapp/cloud-assembly.js +305 -0
  50. package/lib/api/cxapp/cloud-executable.d.ts +44 -0
  51. package/lib/api/cxapp/cloud-executable.js +90 -0
  52. package/lib/api/cxapp/environments.d.ts +9 -0
  53. package/lib/api/cxapp/environments.js +66 -0
  54. package/lib/api/cxapp/exec.d.ts +56 -0
  55. package/lib/api/cxapp/exec.js +275 -0
  56. package/lib/api/deployments/asset-manifest-builder.d.ts +8 -0
  57. package/lib/api/deployments/asset-manifest-builder.js +35 -0
  58. package/lib/api/deployments/asset-publishing.d.ts +77 -0
  59. package/lib/api/deployments/asset-publishing.js +163 -0
  60. package/lib/api/deployments/assets.d.ts +10 -0
  61. package/lib/api/deployments/assets.js +111 -0
  62. package/lib/api/deployments/checks.d.ts +8 -0
  63. package/lib/api/deployments/checks.js +73 -0
  64. package/lib/api/deployments/cloudformation.d.ts +235 -0
  65. package/lib/api/deployments/cloudformation.js +598 -0
  66. package/lib/api/deployments/deploy-stack.d.ts +177 -0
  67. package/lib/api/deployments/deploy-stack.js +484 -0
  68. package/lib/api/deployments/deployment-method.d.ts +24 -0
  69. package/lib/api/deployments/deployment-method.js +3 -0
  70. package/lib/api/deployments/deployment-result.d.ts +21 -0
  71. package/lib/api/deployments/deployment-result.js +10 -0
  72. package/lib/api/deployments/deployments.d.ts +340 -0
  73. package/lib/api/deployments/deployments.js +369 -0
  74. package/lib/api/deployments/hotswap-deployments.d.ts +14 -0
  75. package/lib/api/deployments/hotswap-deployments.js +357 -0
  76. package/lib/api/deployments/index.d.ts +6 -0
  77. package/lib/api/deployments/index.js +23 -0
  78. package/lib/api/deployments/nested-stack-helpers.d.ts +25 -0
  79. package/lib/api/deployments/nested-stack-helpers.js +88 -0
  80. package/lib/api/environment-access.d.ts +138 -0
  81. package/lib/api/environment-access.js +203 -0
  82. package/lib/api/environment-resources.d.ts +73 -0
  83. package/lib/api/environment-resources.js +208 -0
  84. package/lib/api/evaluate-cloudformation-template.d.ts +84 -0
  85. package/lib/api/evaluate-cloudformation-template.js +443 -0
  86. package/lib/api/garbage-collection/garbage-collector.d.ts +152 -0
  87. package/lib/api/garbage-collection/garbage-collector.js +607 -0
  88. package/lib/api/garbage-collection/progress-printer.d.ts +21 -0
  89. package/lib/api/garbage-collection/progress-printer.js +69 -0
  90. package/lib/api/garbage-collection/stack-refresh.d.ts +44 -0
  91. package/lib/api/garbage-collection/stack-refresh.js +154 -0
  92. package/lib/api/hotswap/appsync-mapping-templates.d.ts +3 -0
  93. package/lib/api/hotswap/appsync-mapping-templates.js +157 -0
  94. package/lib/api/hotswap/code-build-projects.d.ts +3 -0
  95. package/lib/api/hotswap/code-build-projects.js +55 -0
  96. package/lib/api/hotswap/common.d.ts +126 -0
  97. package/lib/api/hotswap/common.js +170 -0
  98. package/lib/api/hotswap/ecs-services.d.ts +3 -0
  99. package/lib/api/hotswap/ecs-services.js +140 -0
  100. package/lib/api/hotswap/lambda-functions.d.ts +3 -0
  101. package/lib/api/hotswap/lambda-functions.js +309 -0
  102. package/lib/api/hotswap/s3-bucket-deployments.d.ts +9 -0
  103. package/lib/api/hotswap/s3-bucket-deployments.js +112 -0
  104. package/lib/api/hotswap/stepfunctions-state-machines.d.ts +3 -0
  105. package/lib/api/hotswap/stepfunctions-state-machines.js +42 -0
  106. package/lib/api/index.d.ts +5 -0
  107. package/lib/api/index.js +22 -0
  108. package/lib/api/logs/find-cloudwatch-logs.d.ts +24 -0
  109. package/lib/api/logs/find-cloudwatch-logs.js +97 -0
  110. package/lib/api/logs/logs-monitor.d.ts +53 -0
  111. package/lib/api/logs/logs-monitor.js +169 -0
  112. package/lib/api/plugin/context-provider-plugin.d.ts +6 -0
  113. package/lib/api/plugin/context-provider-plugin.js +7 -0
  114. package/lib/api/plugin/index.d.ts +3 -0
  115. package/lib/api/plugin/index.js +20 -0
  116. package/lib/api/plugin/mode.d.ts +4 -0
  117. package/lib/api/plugin/mode.js +9 -0
  118. package/lib/api/plugin/plugin.d.ts +63 -0
  119. package/lib/api/plugin/plugin.js +106 -0
  120. package/lib/api/settings.d.ts +29 -0
  121. package/lib/api/settings.js +141 -0
  122. package/lib/api/tags.d.ts +9 -0
  123. package/lib/api/tags.js +10 -0
  124. package/lib/api/toolkit-info.d.ts +51 -0
  125. package/lib/api/toolkit-info.js +156 -0
  126. package/lib/api/util/cloudformation/stack-activity-monitor.d.ts +237 -0
  127. package/lib/api/util/cloudformation/stack-activity-monitor.js +550 -0
  128. package/lib/api/util/cloudformation/stack-event-poller.d.ts +63 -0
  129. package/lib/api/util/cloudformation/stack-event-poller.js +129 -0
  130. package/lib/api/util/cloudformation/stack-status.d.ts +42 -0
  131. package/lib/api/util/cloudformation/stack-status.js +88 -0
  132. package/lib/api/util/display.d.ts +13 -0
  133. package/lib/api/util/display.js +80 -0
  134. package/lib/api/util/placeholders.d.ts +10 -0
  135. package/lib/api/util/placeholders.js +24 -0
  136. package/lib/api/util/rwlock.d.ts +65 -0
  137. package/lib/api/util/rwlock.js +179 -0
  138. package/lib/api/util/string-manipulation.d.ts +10 -0
  139. package/lib/api/util/string-manipulation.js +33 -0
  140. package/lib/api/util/template-body-parameter.d.ts +21 -0
  141. package/lib/api/util/template-body-parameter.js +104 -0
  142. package/lib/cli/cdk-toolkit.d.ts +594 -0
  143. package/lib/cli/cdk-toolkit.js +1019 -0
  144. package/lib/cli/cli-config.d.ts +10 -0
  145. package/lib/cli/cli-config.js +406 -0
  146. package/lib/cli/cli.d.ts +4 -0
  147. package/lib/cli/cli.js +538 -0
  148. package/lib/cli/convert-to-user-input.d.ts +3 -0
  149. package/lib/cli/convert-to-user-input.js +434 -0
  150. package/lib/cli/parse-command-line-arguments.d.ts +1 -0
  151. package/lib/cli/parse-command-line-arguments.js +806 -0
  152. package/lib/cli/platform-warnings.d.ts +2 -0
  153. package/lib/cli/platform-warnings.js +45 -0
  154. package/lib/cli/user-configuration.d.ts +90 -0
  155. package/lib/cli/user-configuration.js +272 -0
  156. package/lib/cli/user-input.d.ts +1163 -0
  157. package/lib/cli/user-input.js +3 -0
  158. package/lib/cli/util/console-formatters.d.ts +18 -0
  159. package/lib/cli/util/console-formatters.js +42 -0
  160. package/lib/cli/util/npm.d.ts +1 -0
  161. package/lib/cli/util/npm.js +22 -0
  162. package/lib/cli/util/yargs-helpers.d.ts +22 -0
  163. package/lib/cli/util/yargs-helpers.js +49 -0
  164. package/lib/cli/version.d.ts +13 -0
  165. package/lib/cli/version.js +120 -0
  166. package/lib/commands/context.d.ts +35 -0
  167. package/lib/commands/context.js +156 -0
  168. package/lib/commands/docs.d.ts +13 -0
  169. package/lib/commands/docs.js +32 -0
  170. package/lib/commands/doctor.d.ts +1 -0
  171. package/lib/commands/doctor.js +69 -0
  172. package/lib/commands/migrate.d.ts +327 -0
  173. package/lib/commands/migrate.js +804 -0
  174. package/lib/context-providers/ami.d.ts +11 -0
  175. package/lib/context-providers/ami.js +50 -0
  176. package/lib/context-providers/availability-zones.d.ts +11 -0
  177. package/lib/context-providers/availability-zones.js +27 -0
  178. package/lib/context-providers/endpoint-service-availability-zones.d.ts +11 -0
  179. package/lib/context-providers/endpoint-service-availability-zones.js +33 -0
  180. package/lib/context-providers/hosted-zones.d.ts +10 -0
  181. package/lib/context-providers/hosted-zones.js +67 -0
  182. package/lib/context-providers/index.d.ts +30 -0
  183. package/lib/context-providers/index.js +109 -0
  184. package/lib/context-providers/keys.d.ts +11 -0
  185. package/lib/context-providers/keys.js +52 -0
  186. package/lib/context-providers/load-balancers.d.ts +20 -0
  187. package/lib/context-providers/load-balancers.js +159 -0
  188. package/lib/context-providers/security-groups.d.ts +9 -0
  189. package/lib/context-providers/security-groups.js +70 -0
  190. package/lib/context-providers/ssm-parameters.d.ts +23 -0
  191. package/lib/context-providers/ssm-parameters.js +59 -0
  192. package/lib/context-providers/vpcs.d.ts +11 -0
  193. package/lib/context-providers/vpcs.js +288 -0
  194. package/lib/diff.d.ts +28 -0
  195. package/lib/diff.js +165 -0
  196. package/lib/import.d.ts +182 -0
  197. package/lib/import.js +335 -0
  198. package/lib/index.d.ts +3 -0
  199. package/lib/index.js +348304 -0
  200. package/lib/index_bg.wasm +0 -0
  201. package/lib/init-hooks.d.ts +40 -0
  202. package/lib/init-hooks.js +64 -0
  203. package/lib/init-templates/.init-version.json +1 -0
  204. package/lib/init-templates/.no-packagejson-validator +0 -0
  205. package/lib/init-templates/.recommended-feature-flags.json +68 -0
  206. package/lib/init-templates/LICENSE +16 -0
  207. package/lib/init-templates/app/csharp/.template.gitignore +342 -0
  208. package/lib/init-templates/app/csharp/README.md +14 -0
  209. package/lib/init-templates/app/csharp/cdk.template.json +15 -0
  210. package/lib/init-templates/app/csharp/src/%name.PascalCased%/%name.PascalCased%.template.csproj +20 -0
  211. package/lib/init-templates/app/csharp/src/%name.PascalCased%/%name.PascalCased%Stack.template.cs +13 -0
  212. package/lib/init-templates/app/csharp/src/%name.PascalCased%/GlobalSuppressions.cs +1 -0
  213. package/lib/init-templates/app/csharp/src/%name.PascalCased%/Program.template.cs +44 -0
  214. package/lib/init-templates/app/csharp/src/%name.PascalCased%.template.sln +18 -0
  215. package/lib/init-templates/app/fsharp/.template.gitignore +342 -0
  216. package/lib/init-templates/app/fsharp/README.md +18 -0
  217. package/lib/init-templates/app/fsharp/cdk.template.json +14 -0
  218. package/lib/init-templates/app/fsharp/src/%name.PascalCased%/%name.PascalCased%.template.fsproj +25 -0
  219. package/lib/init-templates/app/fsharp/src/%name.PascalCased%/%name.PascalCased%Stack.template.fs +8 -0
  220. package/lib/init-templates/app/fsharp/src/%name.PascalCased%/Program.template.fs +11 -0
  221. package/lib/init-templates/app/fsharp/src/%name.PascalCased%.template.sln +18 -0
  222. package/lib/init-templates/app/go/%name%.template.go +70 -0
  223. package/lib/init-templates/app/go/%name%_test.template.go +26 -0
  224. package/lib/init-templates/app/go/.template.gitignore +19 -0
  225. package/lib/init-templates/app/go/README.md +12 -0
  226. package/lib/init-templates/app/go/cdk.template.json +13 -0
  227. package/lib/init-templates/app/go/go.template.mod +9 -0
  228. package/lib/init-templates/app/info.json +4 -0
  229. package/lib/init-templates/app/java/.template.gitignore +13 -0
  230. package/lib/init-templates/app/java/README.md +18 -0
  231. package/lib/init-templates/app/java/cdk.json +13 -0
  232. package/lib/init-templates/app/java/pom.xml +60 -0
  233. package/lib/init-templates/app/java/src/main/java/com/myorg/%name.PascalCased%App.template.java +42 -0
  234. package/lib/init-templates/app/java/src/main/java/com/myorg/%name.PascalCased%Stack.template.java +24 -0
  235. package/lib/init-templates/app/java/src/test/java/com/myorg/%name.PascalCased%Test.template.java +26 -0
  236. package/lib/init-templates/app/javascript/.template.gitignore +5 -0
  237. package/lib/init-templates/app/javascript/.template.npmignore +3 -0
  238. package/lib/init-templates/app/javascript/README.md +12 -0
  239. package/lib/init-templates/app/javascript/bin/%name%.template.js +21 -0
  240. package/lib/init-templates/app/javascript/cdk.template.json +15 -0
  241. package/lib/init-templates/app/javascript/jest.config.js +3 -0
  242. package/lib/init-templates/app/javascript/lib/%name%-stack.template.js +23 -0
  243. package/lib/init-templates/app/javascript/package.json +20 -0
  244. package/lib/init-templates/app/javascript/test/%name%.test.template.js +17 -0
  245. package/lib/init-templates/app/python/%name.PythonModule%/%name.PythonModule%_stack.template.py +19 -0
  246. package/lib/init-templates/app/python/%name.PythonModule%/__init__.py +0 -0
  247. package/lib/init-templates/app/python/.template.gitignore +10 -0
  248. package/lib/init-templates/app/python/README.template.md +58 -0
  249. package/lib/init-templates/app/python/app.template.py +28 -0
  250. package/lib/init-templates/app/python/cdk.template.json +15 -0
  251. package/lib/init-templates/app/python/requirements-dev.txt +1 -0
  252. package/lib/init-templates/app/python/requirements.txt +2 -0
  253. package/lib/init-templates/app/python/source.bat +13 -0
  254. package/lib/init-templates/app/python/tests/__init__.py +0 -0
  255. package/lib/init-templates/app/python/tests/unit/__init__.py +0 -0
  256. package/lib/init-templates/app/python/tests/unit/test_%name.PythonModule%_stack.template.py +15 -0
  257. package/lib/init-templates/app/typescript/.template.gitignore +8 -0
  258. package/lib/init-templates/app/typescript/.template.npmignore +6 -0
  259. package/lib/init-templates/app/typescript/README.md +14 -0
  260. package/lib/init-templates/app/typescript/bin/%name%.template.ts +20 -0
  261. package/lib/init-templates/app/typescript/cdk.template.json +17 -0
  262. package/lib/init-templates/app/typescript/jest.config.js +8 -0
  263. package/lib/init-templates/app/typescript/lib/%name%-stack.template.ts +16 -0
  264. package/lib/init-templates/app/typescript/package.json +26 -0
  265. package/lib/init-templates/app/typescript/test/%name%.test.template.ts +17 -0
  266. package/lib/init-templates/app/typescript/tsconfig.json +31 -0
  267. package/lib/init-templates/lib/info.json +4 -0
  268. package/lib/init-templates/lib/typescript/.template.gitignore +8 -0
  269. package/lib/init-templates/lib/typescript/.template.npmignore +6 -0
  270. package/lib/init-templates/lib/typescript/README.template.md +12 -0
  271. package/lib/init-templates/lib/typescript/jest.config.js +8 -0
  272. package/lib/init-templates/lib/typescript/lib/index.template.ts +21 -0
  273. package/lib/init-templates/lib/typescript/package.json +24 -0
  274. package/lib/init-templates/lib/typescript/test/%name%.test.template.ts +18 -0
  275. package/lib/init-templates/lib/typescript/tsconfig.json +31 -0
  276. package/lib/init-templates/sample-app/csharp/.template.gitignore +342 -0
  277. package/lib/init-templates/sample-app/csharp/README.template.md +19 -0
  278. package/lib/init-templates/sample-app/csharp/cdk.template.json +15 -0
  279. package/lib/init-templates/sample-app/csharp/src/%name.PascalCased%/%name.PascalCased%.template.csproj +20 -0
  280. package/lib/init-templates/sample-app/csharp/src/%name.PascalCased%/%name.PascalCased%Stack.template.cs +24 -0
  281. package/lib/init-templates/sample-app/csharp/src/%name.PascalCased%/GlobalSuppressions.cs +1 -0
  282. package/lib/init-templates/sample-app/csharp/src/%name.PascalCased%/Program.template.cs +15 -0
  283. package/lib/init-templates/sample-app/csharp/src/%name.PascalCased%.template.sln +18 -0
  284. package/lib/init-templates/sample-app/fsharp/.template.gitignore +342 -0
  285. package/lib/init-templates/sample-app/fsharp/README.template.md +20 -0
  286. package/lib/init-templates/sample-app/fsharp/cdk.template.json +14 -0
  287. package/lib/init-templates/sample-app/fsharp/src/%name.PascalCased%/%name.PascalCased%.template.fsproj +25 -0
  288. package/lib/init-templates/sample-app/fsharp/src/%name.PascalCased%/%name.PascalCased%Stack.template.fs +14 -0
  289. package/lib/init-templates/sample-app/fsharp/src/%name.PascalCased%/Program.template.fs +11 -0
  290. package/lib/init-templates/sample-app/fsharp/src/%name.PascalCased%.template.sln +18 -0
  291. package/lib/init-templates/sample-app/go/%name%.template.go +73 -0
  292. package/lib/init-templates/sample-app/go/%name%_test.template.go +25 -0
  293. package/lib/init-templates/sample-app/go/.template.gitignore +19 -0
  294. package/lib/init-templates/sample-app/go/README.md +12 -0
  295. package/lib/init-templates/sample-app/go/cdk.template.json +13 -0
  296. package/lib/init-templates/sample-app/go/go.template.mod +9 -0
  297. package/lib/init-templates/sample-app/info.json +4 -0
  298. package/lib/init-templates/sample-app/java/.template.gitignore +13 -0
  299. package/lib/init-templates/sample-app/java/README.template.md +19 -0
  300. package/lib/init-templates/sample-app/java/cdk.json +13 -0
  301. package/lib/init-templates/sample-app/java/pom.xml +55 -0
  302. package/lib/init-templates/sample-app/java/src/main/java/com/myorg/%name.PascalCased%App.template.java +13 -0
  303. package/lib/init-templates/sample-app/java/src/main/java/com/myorg/%name.PascalCased%Stack.template.java +29 -0
  304. package/lib/init-templates/sample-app/java/src/test/java/com/myorg/%name.PascalCased%StackTest.template.java +27 -0
  305. package/lib/init-templates/sample-app/javascript/.template.gitignore +5 -0
  306. package/lib/init-templates/sample-app/javascript/.template.npmignore +3 -0
  307. package/lib/init-templates/sample-app/javascript/README.template.md +13 -0
  308. package/lib/init-templates/sample-app/javascript/bin/%name%.template.js +6 -0
  309. package/lib/init-templates/sample-app/javascript/cdk.template.json +15 -0
  310. package/lib/init-templates/sample-app/javascript/jest.config.js +3 -0
  311. package/lib/init-templates/sample-app/javascript/lib/%name%-stack.template.js +25 -0
  312. package/lib/init-templates/sample-app/javascript/package.json +20 -0
  313. package/lib/init-templates/sample-app/javascript/test/%name%.test.template.js +16 -0
  314. package/lib/init-templates/sample-app/javascript/tsconfig.json +34 -0
  315. package/lib/init-templates/sample-app/python/%name.PythonModule%/%name.PythonModule%_stack.template.py +26 -0
  316. package/lib/init-templates/sample-app/python/%name.PythonModule%/__init__.py +0 -0
  317. package/lib/init-templates/sample-app/python/.template.gitignore +22 -0
  318. package/lib/init-templates/sample-app/python/README.template.md +65 -0
  319. package/lib/init-templates/sample-app/python/app.template.py +11 -0
  320. package/lib/init-templates/sample-app/python/cdk.template.json +15 -0
  321. package/lib/init-templates/sample-app/python/requirements-dev.txt +1 -0
  322. package/lib/init-templates/sample-app/python/requirements.txt +2 -0
  323. package/lib/init-templates/sample-app/python/source.bat +13 -0
  324. package/lib/init-templates/sample-app/python/tests/__init__.py +0 -0
  325. package/lib/init-templates/sample-app/python/tests/unit/__init__.py +0 -0
  326. package/lib/init-templates/sample-app/python/tests/unit/test_%name.PythonModule%_stack.template.py +21 -0
  327. package/lib/init-templates/sample-app/typescript/.template.gitignore +8 -0
  328. package/lib/init-templates/sample-app/typescript/.template.npmignore +6 -0
  329. package/lib/init-templates/sample-app/typescript/README.template.md +15 -0
  330. package/lib/init-templates/sample-app/typescript/bin/%name%.template.ts +6 -0
  331. package/lib/init-templates/sample-app/typescript/cdk.template.json +17 -0
  332. package/lib/init-templates/sample-app/typescript/jest.config.js +8 -0
  333. package/lib/init-templates/sample-app/typescript/lib/%name%-stack.template.ts +19 -0
  334. package/lib/init-templates/sample-app/typescript/package.json +26 -0
  335. package/lib/init-templates/sample-app/typescript/test/%name%.test.template.ts +17 -0
  336. package/lib/init-templates/sample-app/typescript/tsconfig.json +31 -0
  337. package/lib/init.d.ts +52 -0
  338. package/lib/init.js +430 -0
  339. package/lib/legacy-exports-source.d.ts +27 -0
  340. package/lib/legacy-exports-source.js +88 -0
  341. package/lib/legacy-exports.d.ts +10 -0
  342. package/lib/legacy-exports.js +28 -0
  343. package/lib/legacy-logging-source.d.ts +32 -0
  344. package/lib/legacy-logging-source.js +107 -0
  345. package/lib/list-stacks.d.ts +22 -0
  346. package/lib/list-stacks.js +23 -0
  347. package/lib/logging.d.ts +109 -0
  348. package/lib/logging.js +159 -0
  349. package/lib/migrator.d.ts +25 -0
  350. package/lib/migrator.js +67 -0
  351. package/lib/notices.d.ts +156 -0
  352. package/lib/notices.js +373 -0
  353. package/lib/os.d.ts +7 -0
  354. package/lib/os.js +92 -0
  355. package/lib/serialize.d.ts +27 -0
  356. package/lib/serialize.js +86 -0
  357. package/lib/toolkit/cli-io-host.d.ts +208 -0
  358. package/lib/toolkit/cli-io-host.js +282 -0
  359. package/lib/toolkit/error.d.ts +44 -0
  360. package/lib/toolkit/error.js +78 -0
  361. package/lib/tree.d.ts +31 -0
  362. package/lib/tree.js +40 -0
  363. package/lib/util/archive.d.ts +1 -0
  364. package/lib/util/archive.js +86 -0
  365. package/lib/util/arrays.d.ts +14 -0
  366. package/lib/util/arrays.js +36 -0
  367. package/lib/util/bool.d.ts +7 -0
  368. package/lib/util/bool.js +13 -0
  369. package/lib/util/bytes.d.ts +8 -0
  370. package/lib/util/bytes.js +21 -0
  371. package/lib/util/content-hash.d.ts +5 -0
  372. package/lib/util/content-hash.js +43 -0
  373. package/lib/util/directories.d.ts +23 -0
  374. package/lib/util/directories.js +57 -0
  375. package/lib/util/error.d.ts +9 -0
  376. package/lib/util/error.js +22 -0
  377. package/lib/util/index.d.ts +5 -0
  378. package/lib/util/index.js +22 -0
  379. package/lib/util/objects.d.ts +52 -0
  380. package/lib/util/objects.js +183 -0
  381. package/lib/util/parallel.d.ts +6 -0
  382. package/lib/util/parallel.js +44 -0
  383. package/lib/util/tables.d.ts +1 -0
  384. package/lib/util/tables.js +10 -0
  385. package/lib/util/type-brands.d.ts +39 -0
  386. package/lib/util/type-brands.js +38 -0
  387. package/lib/util/types.d.ts +27 -0
  388. package/lib/util/types.js +25 -0
  389. package/lib/util/validate-notification-arn.d.ts +4 -0
  390. package/lib/util/validate-notification-arn.js +10 -0
  391. package/lib/util/version-range.d.ts +2 -0
  392. package/lib/util/version-range.js +36 -0
  393. package/lib/util/work-graph-builder.d.ts +32 -0
  394. package/lib/util/work-graph-builder.js +167 -0
  395. package/lib/util/work-graph-types.d.ts +50 -0
  396. package/lib/util/work-graph-types.js +14 -0
  397. package/lib/util/work-graph.d.ts +70 -0
  398. package/lib/util/work-graph.js +344 -0
  399. package/lib/util/yaml-cfn.d.ts +15 -0
  400. package/lib/util/yaml-cfn.js +56 -0
  401. package/package.json +197 -0
  402. package/scripts/user-input-gen +2 -0
@@ -0,0 +1,1019 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.CdkToolkit = exports.AssetBuildTime = void 0;
4
+ exports.markTesting = markTesting;
5
+ const path = require("path");
6
+ const util_1 = require("util");
7
+ const cxapi = require("@aws-cdk/cx-api");
8
+ const chalk = require("chalk");
9
+ const chokidar = require("chokidar");
10
+ const fs = require("fs-extra");
11
+ const promptly = require("promptly");
12
+ const uuid = require("uuid");
13
+ const user_configuration_1 = require("./user-configuration");
14
+ const bootstrap_1 = require("../api/bootstrap");
15
+ const cloud_assembly_1 = require("../api/cxapp/cloud-assembly");
16
+ const environments_1 = require("../api/cxapp/environments");
17
+ const deployments_1 = require("../api/deployments");
18
+ const garbage_collector_1 = require("../api/garbage-collection/garbage-collector");
19
+ const common_1 = require("../api/hotswap/common");
20
+ const find_cloudwatch_logs_1 = require("../api/logs/find-cloudwatch-logs");
21
+ const logs_monitor_1 = require("../api/logs/logs-monitor");
22
+ const tags_1 = require("../api/tags");
23
+ const stack_activity_monitor_1 = require("../api/util/cloudformation/stack-activity-monitor");
24
+ const string_manipulation_1 = require("../api/util/string-manipulation");
25
+ const migrate_1 = require("../commands/migrate");
26
+ const diff_1 = require("../diff");
27
+ const import_1 = require("../import");
28
+ const list_stacks_1 = require("../list-stacks");
29
+ const logging_1 = require("../logging");
30
+ const migrator_1 = require("../migrator");
31
+ const serialize_1 = require("../serialize");
32
+ const cli_io_host_1 = require("../toolkit/cli-io-host");
33
+ const error_1 = require("../toolkit/error");
34
+ const util_2 = require("../util");
35
+ const error_2 = require("../util/error");
36
+ const validate_notification_arn_1 = require("../util/validate-notification-arn");
37
+ const work_graph_builder_1 = require("../util/work-graph-builder");
38
+ // Must use a require() otherwise esbuild complains about calling a namespace
39
+ // eslint-disable-next-line @typescript-eslint/no-require-imports
40
+ const pLimit = require('p-limit');
41
+ let TESTING = false;
42
+ function markTesting() {
43
+ TESTING = true;
44
+ }
45
+ /**
46
+ * When to build assets
47
+ */
48
+ var AssetBuildTime;
49
+ (function (AssetBuildTime) {
50
+ /**
51
+ * Build all assets before deploying the first stack
52
+ *
53
+ * This is intended for expensive Docker image builds; so that if the Docker image build
54
+ * fails, no stacks are unnecessarily deployed (with the attendant wait time).
55
+ */
56
+ AssetBuildTime[AssetBuildTime["ALL_BEFORE_DEPLOY"] = 0] = "ALL_BEFORE_DEPLOY";
57
+ /**
58
+ * Build assets just-in-time, before publishing
59
+ */
60
+ AssetBuildTime[AssetBuildTime["JUST_IN_TIME"] = 1] = "JUST_IN_TIME";
61
+ })(AssetBuildTime || (exports.AssetBuildTime = AssetBuildTime = {}));
62
+ /**
63
+ * Toolkit logic
64
+ *
65
+ * The toolkit runs the `cloudExecutable` to obtain a cloud assembly and
66
+ * deploys applies them to `cloudFormation`.
67
+ */
68
+ class CdkToolkit {
69
+ constructor(props) {
70
+ var _a;
71
+ this.props = props;
72
+ this.ioHost = (_a = props.ioHost) !== null && _a !== void 0 ? _a : cli_io_host_1.CliIoHost.instance();
73
+ }
74
+ async metadata(stackName, json) {
75
+ var _a;
76
+ const stacks = await this.selectSingleStackByName(stackName);
77
+ printSerializedObject((_a = stacks.firstStack.manifest.metadata) !== null && _a !== void 0 ? _a : {}, json);
78
+ }
79
+ async acknowledge(noticeId) {
80
+ var _a;
81
+ const acks = (_a = this.props.configuration.context.get('acknowledged-issue-numbers')) !== null && _a !== void 0 ? _a : [];
82
+ acks.push(Number(noticeId));
83
+ this.props.configuration.context.set('acknowledged-issue-numbers', acks);
84
+ await this.props.configuration.saveContext();
85
+ }
86
+ async diff(options) {
87
+ const stacks = await this.selectStacksForDiff(options.stackNames, options.exclusively);
88
+ const strict = !!options.strict;
89
+ const contextLines = options.contextLines || 3;
90
+ const stream = options.stream || process.stderr;
91
+ const quiet = options.quiet || false;
92
+ let diffs = 0;
93
+ const parameterMap = buildParameterMap(options.parameters);
94
+ if (options.templatePath !== undefined) {
95
+ // Compare single stack against fixed template
96
+ if (stacks.stackCount !== 1) {
97
+ throw new error_1.ToolkitError('Can only select one stack when comparing to fixed template. Use --exclusively to avoid selecting multiple stacks.');
98
+ }
99
+ if (!(await fs.pathExists(options.templatePath))) {
100
+ throw new error_1.ToolkitError(`There is no file at ${options.templatePath}`);
101
+ }
102
+ const template = (0, serialize_1.deserializeStructure)(await fs.readFile(options.templatePath, { encoding: 'UTF-8' }));
103
+ diffs = options.securityOnly
104
+ ? (0, util_2.numberFromBool)((0, diff_1.printSecurityDiff)(template, stacks.firstStack, diff_1.RequireApproval.Broadening, quiet))
105
+ : (0, diff_1.printStackDiff)(template, stacks.firstStack, strict, contextLines, quiet, undefined, undefined, false, stream);
106
+ }
107
+ else {
108
+ // Compare N stacks against deployed templates
109
+ for (const stack of stacks.stackArtifacts) {
110
+ const templateWithNestedStacks = await this.props.deployments.readCurrentTemplateWithNestedStacks(stack, options.compareAgainstProcessedTemplate);
111
+ const currentTemplate = templateWithNestedStacks.deployedRootTemplate;
112
+ const nestedStacks = templateWithNestedStacks.nestedStacks;
113
+ const migrator = new migrator_1.ResourceMigrator({
114
+ deployments: this.props.deployments,
115
+ });
116
+ const resourcesToImport = await migrator.tryGetResources(await this.props.deployments.resolveEnvironment(stack));
117
+ if (resourcesToImport) {
118
+ (0, import_1.removeNonImportResources)(stack);
119
+ }
120
+ let changeSet = undefined;
121
+ if (options.changeSet) {
122
+ let stackExists = false;
123
+ try {
124
+ stackExists = await this.props.deployments.stackExists({
125
+ stack,
126
+ deployName: stack.stackName,
127
+ tryLookupRole: true,
128
+ });
129
+ }
130
+ catch (e) {
131
+ (0, logging_1.debug)((0, error_2.formatErrorMessage)(e));
132
+ if (!quiet) {
133
+ stream.write(`Checking if the stack ${stack.stackName} exists before creating the changeset has failed, will base the diff on template differences (run again with -v to see the reason)\n`);
134
+ }
135
+ stackExists = false;
136
+ }
137
+ if (stackExists) {
138
+ changeSet = await (0, deployments_1.createDiffChangeSet)({
139
+ stack,
140
+ uuid: uuid.v4(),
141
+ deployments: this.props.deployments,
142
+ willExecute: false,
143
+ sdkProvider: this.props.sdkProvider,
144
+ parameters: Object.assign({}, parameterMap['*'], parameterMap[stack.stackName]),
145
+ resourcesToImport,
146
+ stream,
147
+ });
148
+ }
149
+ else {
150
+ (0, logging_1.debug)(`the stack '${stack.stackName}' has not been deployed to CloudFormation or describeStacks call failed, skipping changeset creation.`);
151
+ }
152
+ }
153
+ const stackCount = options.securityOnly
154
+ ? (0, util_2.numberFromBool)((0, diff_1.printSecurityDiff)(currentTemplate, stack, diff_1.RequireApproval.Broadening, quiet, stack.displayName, changeSet))
155
+ : (0, diff_1.printStackDiff)(currentTemplate, stack, strict, contextLines, quiet, stack.displayName, changeSet, !!resourcesToImport, stream, nestedStacks);
156
+ diffs += stackCount;
157
+ }
158
+ }
159
+ stream.write((0, util_1.format)('\n✨ Number of stacks with differences: %s\n', diffs));
160
+ return diffs && options.fail ? 1 : 0;
161
+ }
162
+ async deploy(options) {
163
+ var _a, _b, _c, _d, _e;
164
+ if (options.watch) {
165
+ return this.watch(options);
166
+ }
167
+ const startSynthTime = new Date().getTime();
168
+ const stackCollection = await this.selectStacksForDeploy(options.selector, options.exclusively, options.cacheCloudAssembly, options.ignoreNoStacks);
169
+ const elapsedSynthTime = new Date().getTime() - startSynthTime;
170
+ (0, logging_1.info)(`\n✨ Synthesis time: ${(0, string_manipulation_1.formatTime)(elapsedSynthTime)}s\n`);
171
+ if (stackCollection.stackCount === 0) {
172
+ (0, logging_1.error)('This app contains no stacks');
173
+ return;
174
+ }
175
+ const migrator = new migrator_1.ResourceMigrator({
176
+ deployments: this.props.deployments,
177
+ });
178
+ await migrator.tryMigrateResources(stackCollection, options);
179
+ const requireApproval = (_a = options.requireApproval) !== null && _a !== void 0 ? _a : diff_1.RequireApproval.Broadening;
180
+ const parameterMap = buildParameterMap(options.parameters);
181
+ if (options.hotswap !== common_1.HotswapMode.FULL_DEPLOYMENT) {
182
+ (0, logging_1.warning)('⚠️ The --hotswap and --hotswap-fallback flags deliberately introduce CloudFormation drift to speed up deployments');
183
+ (0, logging_1.warning)('⚠️ They should only be used for development - never use them for your production Stacks!\n');
184
+ }
185
+ let hotswapPropertiesFromSettings = this.props.configuration.settings.get(['hotswap']) || {};
186
+ let hotswapPropertyOverrides = new common_1.HotswapPropertyOverrides();
187
+ hotswapPropertyOverrides.ecsHotswapProperties = new common_1.EcsHotswapProperties((_b = hotswapPropertiesFromSettings.ecs) === null || _b === void 0 ? void 0 : _b.minimumHealthyPercent, (_c = hotswapPropertiesFromSettings.ecs) === null || _c === void 0 ? void 0 : _c.maximumHealthyPercent);
188
+ const stacks = stackCollection.stackArtifacts;
189
+ const stackOutputs = {};
190
+ const outputsFile = options.outputsFile;
191
+ const buildAsset = async (assetNode) => {
192
+ await this.props.deployments.buildSingleAsset(assetNode.assetManifestArtifact, assetNode.assetManifest, assetNode.asset, {
193
+ stack: assetNode.parentStack,
194
+ roleArn: options.roleArn,
195
+ stackName: assetNode.parentStack.stackName,
196
+ });
197
+ };
198
+ const publishAsset = async (assetNode) => {
199
+ await this.props.deployments.publishSingleAsset(assetNode.assetManifest, assetNode.asset, {
200
+ stack: assetNode.parentStack,
201
+ roleArn: options.roleArn,
202
+ stackName: assetNode.parentStack.stackName,
203
+ });
204
+ };
205
+ const deployStack = async (stackNode) => {
206
+ var _a, _b;
207
+ const stack = stackNode.stack;
208
+ if (stackCollection.stackCount !== 1) {
209
+ (0, logging_1.highlight)(stack.displayName);
210
+ }
211
+ if (!stack.environment) {
212
+ // eslint-disable-next-line max-len
213
+ throw new error_1.ToolkitError(`Stack ${stack.displayName} does not define an environment, and AWS credentials could not be obtained from standard locations or no region was configured.`);
214
+ }
215
+ if (Object.keys(stack.template.Resources || {}).length === 0) {
216
+ // The generated stack has no resources
217
+ if (!(await this.props.deployments.stackExists({ stack }))) {
218
+ (0, logging_1.warning)('%s: stack has no resources, skipping deployment.', chalk.bold(stack.displayName));
219
+ }
220
+ else {
221
+ (0, logging_1.warning)('%s: stack has no resources, deleting existing stack.', chalk.bold(stack.displayName));
222
+ await this.destroy({
223
+ selector: { patterns: [stack.hierarchicalId] },
224
+ exclusively: true,
225
+ force: true,
226
+ roleArn: options.roleArn,
227
+ fromDeploy: true,
228
+ ci: options.ci,
229
+ });
230
+ }
231
+ return;
232
+ }
233
+ if (requireApproval !== diff_1.RequireApproval.Never) {
234
+ const currentTemplate = await this.props.deployments.readCurrentTemplate(stack);
235
+ if ((0, diff_1.printSecurityDiff)(currentTemplate, stack, requireApproval)) {
236
+ await askUserConfirmation(this.ioHost, concurrency, '"--require-approval" is enabled and stack includes security-sensitive updates', 'Do you wish to deploy these changes');
237
+ }
238
+ }
239
+ // Following are the same semantics we apply with respect to Notification ARNs (dictated by the SDK)
240
+ //
241
+ // - undefined => cdk ignores it, as if it wasn't supported (allows external management).
242
+ // - []: => cdk manages it, and the user wants to wipe it out.
243
+ // - ['arn-1'] => cdk manages it, and the user wants to set it to ['arn-1'].
244
+ const notificationArns = (!!options.notificationArns || !!stack.notificationArns)
245
+ ? ((_a = options.notificationArns) !== null && _a !== void 0 ? _a : []).concat((_b = stack.notificationArns) !== null && _b !== void 0 ? _b : [])
246
+ : undefined;
247
+ for (const notificationArn of notificationArns !== null && notificationArns !== void 0 ? notificationArns : []) {
248
+ if (!(0, validate_notification_arn_1.validateSnsTopicArn)(notificationArn)) {
249
+ throw new error_1.ToolkitError(`Notification arn ${notificationArn} is not a valid arn for an SNS topic`);
250
+ }
251
+ }
252
+ const stackIndex = stacks.indexOf(stack) + 1;
253
+ (0, logging_1.info)(`${chalk.bold(stack.displayName)}: deploying... [${stackIndex}/${stackCollection.stackCount}]`);
254
+ const startDeployTime = new Date().getTime();
255
+ let tags = options.tags;
256
+ if (!tags || tags.length === 0) {
257
+ tags = (0, tags_1.tagsForStack)(stack);
258
+ }
259
+ let elapsedDeployTime = 0;
260
+ try {
261
+ let deployResult;
262
+ let rollback = options.rollback;
263
+ let iteration = 0;
264
+ while (!deployResult) {
265
+ if (++iteration > 2) {
266
+ throw new error_1.ToolkitError('This loop should have stabilized in 2 iterations, but didn\'t. If you are seeing this error, please report it at https://github.com/aws/aws-cdk/issues/new/choose');
267
+ }
268
+ const r = await this.props.deployments.deployStack({
269
+ stack,
270
+ deployName: stack.stackName,
271
+ roleArn: options.roleArn,
272
+ toolkitStackName: options.toolkitStackName,
273
+ reuseAssets: options.reuseAssets,
274
+ notificationArns,
275
+ tags,
276
+ execute: options.execute,
277
+ changeSetName: options.changeSetName,
278
+ deploymentMethod: options.deploymentMethod,
279
+ force: options.force,
280
+ parameters: Object.assign({}, parameterMap['*'], parameterMap[stack.stackName]),
281
+ usePreviousParameters: options.usePreviousParameters,
282
+ progress,
283
+ ci: options.ci,
284
+ rollback,
285
+ hotswap: options.hotswap,
286
+ hotswapPropertyOverrides: hotswapPropertyOverrides,
287
+ extraUserAgent: options.extraUserAgent,
288
+ assetParallelism: options.assetParallelism,
289
+ ignoreNoStacks: options.ignoreNoStacks,
290
+ });
291
+ switch (r.type) {
292
+ case 'did-deploy-stack':
293
+ deployResult = r;
294
+ break;
295
+ case 'failpaused-need-rollback-first': {
296
+ const motivation = r.reason === 'replacement'
297
+ ? `Stack is in a paused fail state (${r.status}) and change includes a replacement which cannot be deployed with "--no-rollback"`
298
+ : `Stack is in a paused fail state (${r.status}) and command line arguments do not include "--no-rollback"`;
299
+ if (options.force) {
300
+ (0, logging_1.warning)(`${motivation}. Rolling back first (--force).`);
301
+ }
302
+ else {
303
+ await askUserConfirmation(this.ioHost, concurrency, motivation, `${motivation}. Roll back first and then proceed with deployment`);
304
+ }
305
+ // Perform a rollback
306
+ await this.rollback({
307
+ selector: { patterns: [stack.hierarchicalId] },
308
+ toolkitStackName: options.toolkitStackName,
309
+ force: options.force,
310
+ });
311
+ // Go around through the 'while' loop again but switch rollback to true.
312
+ rollback = true;
313
+ break;
314
+ }
315
+ case 'replacement-requires-rollback': {
316
+ const motivation = 'Change includes a replacement which cannot be deployed with "--no-rollback"';
317
+ if (options.force) {
318
+ (0, logging_1.warning)(`${motivation}. Proceeding with regular deployment (--force).`);
319
+ }
320
+ else {
321
+ await askUserConfirmation(this.ioHost, concurrency, motivation, `${motivation}. Perform a regular deployment`);
322
+ }
323
+ // Go around through the 'while' loop again but switch rollback to true.
324
+ rollback = true;
325
+ break;
326
+ }
327
+ default:
328
+ throw new error_1.ToolkitError(`Unexpected result type from deployStack: ${JSON.stringify(r)}. If you are seeing this error, please report it at https://github.com/aws/aws-cdk/issues/new/choose`);
329
+ }
330
+ }
331
+ const message = deployResult.noOp
332
+ ? ' ✅ %s (no changes)'
333
+ : ' ✅ %s';
334
+ (0, logging_1.success)('\n' + message, stack.displayName);
335
+ elapsedDeployTime = new Date().getTime() - startDeployTime;
336
+ (0, logging_1.info)(`\n✨ Deployment time: ${(0, string_manipulation_1.formatTime)(elapsedDeployTime)}s\n`);
337
+ if (Object.keys(deployResult.outputs).length > 0) {
338
+ (0, logging_1.info)('Outputs:');
339
+ stackOutputs[stack.stackName] = deployResult.outputs;
340
+ }
341
+ for (const name of Object.keys(deployResult.outputs).sort()) {
342
+ const value = deployResult.outputs[name];
343
+ (0, logging_1.info)(`${chalk.cyan(stack.id)}.${chalk.cyan(name)} = ${chalk.underline(chalk.cyan(value))}`);
344
+ }
345
+ (0, logging_1.info)('Stack ARN:');
346
+ (0, logging_1.result)(deployResult.stackArn);
347
+ }
348
+ catch (e) {
349
+ // It has to be exactly this string because an integration test tests for
350
+ // "bold(stackname) failed: ResourceNotReady: <error>"
351
+ throw new error_1.ToolkitError([`❌ ${chalk.bold(stack.stackName)} failed:`, ...(e.name ? [`${e.name}:`] : []), (0, error_2.formatErrorMessage)(e)].join(' '));
352
+ }
353
+ finally {
354
+ if (options.cloudWatchLogMonitor) {
355
+ const foundLogGroupsResult = await (0, find_cloudwatch_logs_1.findCloudWatchLogGroups)(this.props.sdkProvider, stack);
356
+ options.cloudWatchLogMonitor.addLogGroups(foundLogGroupsResult.env, foundLogGroupsResult.sdk, foundLogGroupsResult.logGroupNames);
357
+ }
358
+ // If an outputs file has been specified, create the file path and write stack outputs to it once.
359
+ // Outputs are written after all stacks have been deployed. If a stack deployment fails,
360
+ // all of the outputs from successfully deployed stacks before the failure will still be written.
361
+ if (outputsFile) {
362
+ fs.ensureFileSync(outputsFile);
363
+ await fs.writeJson(outputsFile, stackOutputs, {
364
+ spaces: 2,
365
+ encoding: 'utf8',
366
+ });
367
+ }
368
+ }
369
+ (0, logging_1.info)(`\n✨ Total time: ${(0, string_manipulation_1.formatTime)(elapsedSynthTime + elapsedDeployTime)}s\n`);
370
+ };
371
+ const assetBuildTime = (_d = options.assetBuildTime) !== null && _d !== void 0 ? _d : AssetBuildTime.ALL_BEFORE_DEPLOY;
372
+ const prebuildAssets = assetBuildTime === AssetBuildTime.ALL_BEFORE_DEPLOY;
373
+ const concurrency = options.concurrency || 1;
374
+ const progress = concurrency > 1 ? stack_activity_monitor_1.StackActivityProgress.EVENTS : options.progress;
375
+ if (concurrency > 1 && options.progress && options.progress != stack_activity_monitor_1.StackActivityProgress.EVENTS) {
376
+ (0, logging_1.warning)('⚠️ The --concurrency flag only supports --progress "events". Switching to "events".');
377
+ }
378
+ const stacksAndTheirAssetManifests = stacks.flatMap((stack) => [
379
+ stack,
380
+ ...stack.dependencies.filter(cxapi.AssetManifestArtifact.isAssetManifestArtifact),
381
+ ]);
382
+ const workGraph = new work_graph_builder_1.WorkGraphBuilder(prebuildAssets).build(stacksAndTheirAssetManifests);
383
+ // Unless we are running with '--force', skip already published assets
384
+ if (!options.force) {
385
+ await this.removePublishedAssets(workGraph, options);
386
+ }
387
+ const graphConcurrency = {
388
+ 'stack': concurrency,
389
+ 'asset-build': 1, // This will be CPU-bound/memory bound, mostly matters for Docker builds
390
+ 'asset-publish': ((_e = options.assetParallelism) !== null && _e !== void 0 ? _e : true) ? 8 : 1, // This will be I/O-bound, 8 in parallel seems reasonable
391
+ };
392
+ await workGraph.doParallel(graphConcurrency, {
393
+ deployStack,
394
+ buildAsset,
395
+ publishAsset,
396
+ });
397
+ }
398
+ /**
399
+ * Roll back the given stack or stacks.
400
+ */
401
+ async rollback(options) {
402
+ const startSynthTime = new Date().getTime();
403
+ const stackCollection = await this.selectStacksForDeploy(options.selector, true);
404
+ const elapsedSynthTime = new Date().getTime() - startSynthTime;
405
+ (0, logging_1.info)(`\n✨ Synthesis time: ${(0, string_manipulation_1.formatTime)(elapsedSynthTime)}s\n`);
406
+ if (stackCollection.stackCount === 0) {
407
+ (0, logging_1.error)('No stacks selected');
408
+ return;
409
+ }
410
+ let anyRollbackable = false;
411
+ for (const stack of stackCollection.stackArtifacts) {
412
+ (0, logging_1.info)('Rolling back %s', chalk.bold(stack.displayName));
413
+ const startRollbackTime = new Date().getTime();
414
+ try {
415
+ const result = await this.props.deployments.rollbackStack({
416
+ stack,
417
+ roleArn: options.roleArn,
418
+ toolkitStackName: options.toolkitStackName,
419
+ force: options.force,
420
+ validateBootstrapStackVersion: options.validateBootstrapStackVersion,
421
+ orphanLogicalIds: options.orphanLogicalIds,
422
+ });
423
+ if (!result.notInRollbackableState) {
424
+ anyRollbackable = true;
425
+ }
426
+ const elapsedRollbackTime = new Date().getTime() - startRollbackTime;
427
+ (0, logging_1.info)(`\n✨ Rollback time: ${(0, string_manipulation_1.formatTime)(elapsedRollbackTime).toString()}s\n`);
428
+ }
429
+ catch (e) {
430
+ (0, logging_1.error)('\n ❌ %s failed: %s', chalk.bold(stack.displayName), (0, error_2.formatErrorMessage)(e));
431
+ throw new error_1.ToolkitError('Rollback failed (use --force to orphan failing resources)');
432
+ }
433
+ }
434
+ if (!anyRollbackable) {
435
+ throw new error_1.ToolkitError('No stacks were in a state that could be rolled back');
436
+ }
437
+ }
438
+ async watch(options) {
439
+ const rootDir = path.dirname(path.resolve(user_configuration_1.PROJECT_CONFIG));
440
+ (0, logging_1.debug)("root directory used for 'watch' is: %s", rootDir);
441
+ const watchSettings = this.props.configuration.settings.get(['watch']);
442
+ if (!watchSettings) {
443
+ throw new error_1.ToolkitError("Cannot use the 'watch' command without specifying at least one directory to monitor. " +
444
+ 'Make sure to add a "watch" key to your cdk.json');
445
+ }
446
+ // For the "include" subkey under the "watch" key, the behavior is:
447
+ // 1. No "watch" setting? We error out.
448
+ // 2. "watch" setting without an "include" key? We default to observing "./**".
449
+ // 3. "watch" setting with an empty "include" key? We default to observing "./**".
450
+ // 4. Non-empty "include" key? Just use the "include" key.
451
+ const watchIncludes = this.patternsArrayForWatch(watchSettings.include, {
452
+ rootDir,
453
+ returnRootDirIfEmpty: true,
454
+ });
455
+ (0, logging_1.debug)("'include' patterns for 'watch': %s", watchIncludes);
456
+ // For the "exclude" subkey under the "watch" key,
457
+ // the behavior is to add some default excludes in addition to the ones specified by the user:
458
+ // 1. The CDK output directory.
459
+ // 2. Any file whose name starts with a dot.
460
+ // 3. Any directory's content whose name starts with a dot.
461
+ // 4. Any node_modules and its content (even if it's not a JS/TS project, you might be using a local aws-cli package)
462
+ const outputDir = this.props.configuration.settings.get(['output']);
463
+ const watchExcludes = this.patternsArrayForWatch(watchSettings.exclude, {
464
+ rootDir,
465
+ returnRootDirIfEmpty: false,
466
+ }).concat(`${outputDir}/**`, '**/.*', '**/.*/**', '**/node_modules/**');
467
+ (0, logging_1.debug)("'exclude' patterns for 'watch': %s", watchExcludes);
468
+ // Since 'cdk deploy' is a relatively slow operation for a 'watch' process,
469
+ // introduce a concurrency latch that tracks the state.
470
+ // This way, if file change events arrive when a 'cdk deploy' is still executing,
471
+ // we will batch them, and trigger another 'cdk deploy' after the current one finishes,
472
+ // making sure 'cdk deploy's always execute one at a time.
473
+ // Here's a diagram showing the state transitions:
474
+ // -------------- -------- file changed -------------- file changed -------------- file changed
475
+ // | | ready event | | ------------------> | | ------------------> | | --------------|
476
+ // | pre-ready | -------------> | open | | deploying | | queued | |
477
+ // | | | | <------------------ | | <------------------ | | <-------------|
478
+ // -------------- -------- 'cdk deploy' done -------------- 'cdk deploy' done --------------
479
+ let latch = 'pre-ready';
480
+ const cloudWatchLogMonitor = options.traceLogs ? new logs_monitor_1.CloudWatchLogEventMonitor() : undefined;
481
+ const deployAndWatch = async () => {
482
+ latch = 'deploying';
483
+ cloudWatchLogMonitor === null || cloudWatchLogMonitor === void 0 ? void 0 : cloudWatchLogMonitor.deactivate();
484
+ await this.invokeDeployFromWatch(options, cloudWatchLogMonitor);
485
+ // If latch is still 'deploying' after the 'await', that's fine,
486
+ // but if it's 'queued', that means we need to deploy again
487
+ while (latch === 'queued') {
488
+ // TypeScript doesn't realize latch can change between 'awaits',
489
+ // and thinks the above 'while' condition is always 'false' without the cast
490
+ latch = 'deploying';
491
+ (0, logging_1.info)("Detected file changes during deployment. Invoking 'cdk deploy' again");
492
+ await this.invokeDeployFromWatch(options, cloudWatchLogMonitor);
493
+ }
494
+ latch = 'open';
495
+ cloudWatchLogMonitor === null || cloudWatchLogMonitor === void 0 ? void 0 : cloudWatchLogMonitor.activate();
496
+ };
497
+ chokidar
498
+ .watch(watchIncludes, {
499
+ ignored: watchExcludes,
500
+ cwd: rootDir,
501
+ })
502
+ .on('ready', async () => {
503
+ latch = 'open';
504
+ (0, logging_1.debug)("'watch' received the 'ready' event. From now on, all file changes will trigger a deployment");
505
+ (0, logging_1.info)("Triggering initial 'cdk deploy'");
506
+ await deployAndWatch();
507
+ })
508
+ .on('all', async (event, filePath) => {
509
+ if (latch === 'pre-ready') {
510
+ (0, logging_1.info)(`'watch' is observing ${event === 'addDir' ? 'directory' : 'the file'} '%s' for changes`, filePath);
511
+ }
512
+ else if (latch === 'open') {
513
+ (0, logging_1.info)("Detected change to '%s' (type: %s). Triggering 'cdk deploy'", filePath, event);
514
+ await deployAndWatch();
515
+ }
516
+ else {
517
+ // this means latch is either 'deploying' or 'queued'
518
+ latch = 'queued';
519
+ (0, logging_1.info)("Detected change to '%s' (type: %s) while 'cdk deploy' is still running. " +
520
+ 'Will queue for another deployment after this one finishes', filePath, event);
521
+ }
522
+ });
523
+ }
524
+ async import(options) {
525
+ const stacks = await this.selectStacksForDeploy(options.selector, true, true, false);
526
+ if (stacks.stackCount > 1) {
527
+ throw new error_1.ToolkitError(`Stack selection is ambiguous, please choose a specific stack for import [${stacks.stackArtifacts.map((x) => x.id).join(', ')}]`);
528
+ }
529
+ if (!process.stdout.isTTY && !options.resourceMappingFile) {
530
+ throw new error_1.ToolkitError('--resource-mapping is required when input is not a terminal');
531
+ }
532
+ const stack = stacks.stackArtifacts[0];
533
+ (0, logging_1.highlight)(stack.displayName);
534
+ const resourceImporter = new import_1.ResourceImporter(stack, this.props.deployments);
535
+ const { additions, hasNonAdditions } = await resourceImporter.discoverImportableResources(options.force);
536
+ if (additions.length === 0) {
537
+ (0, logging_1.warning)('%s: no new resources compared to the currently deployed stack, skipping import.', chalk.bold(stack.displayName));
538
+ return;
539
+ }
540
+ // Prepare a mapping of physical resources to CDK constructs
541
+ const actualImport = !options.resourceMappingFile
542
+ ? await resourceImporter.askForResourceIdentifiers(additions)
543
+ : await resourceImporter.loadResourceIdentifiers(additions, options.resourceMappingFile);
544
+ if (actualImport.importResources.length === 0) {
545
+ (0, logging_1.warning)('No resources selected for import.');
546
+ return;
547
+ }
548
+ // If "--create-resource-mapping" option was passed, write the resource mapping to the given file and exit
549
+ if (options.recordResourceMapping) {
550
+ const outputFile = options.recordResourceMapping;
551
+ fs.ensureFileSync(outputFile);
552
+ await fs.writeJson(outputFile, actualImport.resourceMap, {
553
+ spaces: 2,
554
+ encoding: 'utf8',
555
+ });
556
+ (0, logging_1.info)('%s: mapping file written.', outputFile);
557
+ return;
558
+ }
559
+ // Import the resources according to the given mapping
560
+ (0, logging_1.info)('%s: importing resources into stack...', chalk.bold(stack.displayName));
561
+ const tags = (0, tags_1.tagsForStack)(stack);
562
+ await resourceImporter.importResourcesFromMap(actualImport, {
563
+ roleArn: options.roleArn,
564
+ toolkitStackName: options.toolkitStackName,
565
+ tags,
566
+ deploymentMethod: options.deploymentMethod,
567
+ usePreviousParameters: true,
568
+ progress: options.progress,
569
+ rollback: options.rollback,
570
+ });
571
+ // Notify user of next steps
572
+ (0, logging_1.info)(`Import operation complete. We recommend you run a ${chalk.blueBright('drift detection')} operation ` +
573
+ 'to confirm your CDK app resource definitions are up-to-date. Read more here: ' +
574
+ chalk.underline.blueBright('https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/detect-drift-stack.html'));
575
+ if (actualImport.importResources.length < additions.length) {
576
+ (0, logging_1.info)('');
577
+ (0, logging_1.warning)(`Some resources were skipped. Run another ${chalk.blueBright('cdk import')} or a ${chalk.blueBright('cdk deploy')} to bring the stack up-to-date with your CDK app definition.`);
578
+ }
579
+ else if (hasNonAdditions) {
580
+ (0, logging_1.info)('');
581
+ (0, logging_1.warning)(`Your app has pending updates or deletes excluded from this import operation. Run a ${chalk.blueBright('cdk deploy')} to bring the stack up-to-date with your CDK app definition.`);
582
+ }
583
+ }
584
+ async destroy(options) {
585
+ let stacks = await this.selectStacksForDestroy(options.selector, options.exclusively);
586
+ // The stacks will have been ordered for deployment, so reverse them for deletion.
587
+ stacks = stacks.reversed();
588
+ if (!options.force) {
589
+ // eslint-disable-next-line max-len
590
+ const confirmed = await promptly.confirm(`Are you sure you want to delete: ${chalk.blue(stacks.stackArtifacts.map((s) => s.hierarchicalId).join(', '))} (y/n)?`);
591
+ if (!confirmed) {
592
+ return;
593
+ }
594
+ }
595
+ const action = options.fromDeploy ? 'deploy' : 'destroy';
596
+ for (const [index, stack] of stacks.stackArtifacts.entries()) {
597
+ (0, logging_1.success)('%s: destroying... [%s/%s]', chalk.blue(stack.displayName), index + 1, stacks.stackCount);
598
+ try {
599
+ await this.props.deployments.destroyStack({
600
+ stack,
601
+ deployName: stack.stackName,
602
+ roleArn: options.roleArn,
603
+ ci: options.ci,
604
+ });
605
+ (0, logging_1.success)(`\n ✅ %s: ${action}ed`, chalk.blue(stack.displayName));
606
+ }
607
+ catch (e) {
608
+ (0, logging_1.error)(`\n ❌ %s: ${action} failed`, chalk.blue(stack.displayName), e);
609
+ throw e;
610
+ }
611
+ }
612
+ }
613
+ async list(selectors, options = {}) {
614
+ var _a, _b, _c;
615
+ const stacks = await (0, list_stacks_1.listStacks)(this, {
616
+ selectors: selectors,
617
+ });
618
+ if (options.long && options.showDeps) {
619
+ printSerializedObject(stacks, (_a = options.json) !== null && _a !== void 0 ? _a : false);
620
+ return 0;
621
+ }
622
+ if (options.showDeps) {
623
+ const stackDeps = [];
624
+ for (const stack of stacks) {
625
+ stackDeps.push({
626
+ id: stack.id,
627
+ dependencies: stack.dependencies,
628
+ });
629
+ }
630
+ printSerializedObject(stackDeps, (_b = options.json) !== null && _b !== void 0 ? _b : false);
631
+ return 0;
632
+ }
633
+ if (options.long) {
634
+ const long = [];
635
+ for (const stack of stacks) {
636
+ long.push({
637
+ id: stack.id,
638
+ name: stack.name,
639
+ environment: stack.environment,
640
+ });
641
+ }
642
+ printSerializedObject(long, (_c = options.json) !== null && _c !== void 0 ? _c : false);
643
+ return 0;
644
+ }
645
+ // just print stack IDs
646
+ for (const stack of stacks) {
647
+ (0, logging_1.result)(stack.id);
648
+ }
649
+ return 0; // exit-code
650
+ }
651
+ /**
652
+ * Synthesize the given set of stacks (called when the user runs 'cdk synth')
653
+ *
654
+ * INPUT: Stack names can be supplied using a glob filter. If no stacks are
655
+ * given, all stacks from the application are implicitly selected.
656
+ *
657
+ * OUTPUT: If more than one stack ends up being selected, an output directory
658
+ * should be supplied, where the templates will be written.
659
+ */
660
+ async synth(stackNames, exclusively, quiet, autoValidate, json) {
661
+ const stacks = await this.selectStacksForDiff(stackNames, exclusively, autoValidate);
662
+ // if we have a single stack, print it to STDOUT
663
+ if (stacks.stackCount === 1) {
664
+ if (!quiet) {
665
+ printSerializedObject((0, serialize_1.obscureTemplate)(stacks.firstStack.template), json !== null && json !== void 0 ? json : false);
666
+ }
667
+ return undefined;
668
+ }
669
+ // not outputting template to stdout, let's explain things to the user a little bit...
670
+ (0, logging_1.success)(`Successfully synthesized to ${chalk.blue(path.resolve(stacks.assembly.directory))}`);
671
+ (0, logging_1.info)(`Supply a stack id (${stacks.stackArtifacts.map((s) => chalk.green(s.hierarchicalId)).join(', ')}) to display its template.`);
672
+ return undefined;
673
+ }
674
+ /**
675
+ * Bootstrap the CDK Toolkit stack in the accounts used by the specified stack(s).
676
+ *
677
+ * @param userEnvironmentSpecs environment names that need to have toolkit support
678
+ * provisioned, as a glob filter. If none is provided, all stacks are implicitly selected.
679
+ * @param options The name, role ARN, bootstrapping parameters, etc. to be used for the CDK Toolkit stack.
680
+ */
681
+ async bootstrap(userEnvironmentSpecs, options) {
682
+ const bootstrapper = new bootstrap_1.Bootstrapper(options.source);
683
+ // If there is an '--app' argument and an environment looks like a glob, we
684
+ // select the environments from the app. Otherwise, use what the user said.
685
+ const environments = await this.defineEnvironments(userEnvironmentSpecs);
686
+ const limit = pLimit(20);
687
+ // eslint-disable-next-line @cdklabs/promiseall-no-unbounded-parallelism
688
+ await Promise.all(environments.map((environment) => limit(async () => {
689
+ (0, logging_1.success)(' ⏳ Bootstrapping environment %s...', chalk.blue(environment.name));
690
+ try {
691
+ const result = await bootstrapper.bootstrapEnvironment(environment, this.props.sdkProvider, options);
692
+ const message = result.noOp
693
+ ? ' ✅ Environment %s bootstrapped (no changes).'
694
+ : ' ✅ Environment %s bootstrapped.';
695
+ (0, logging_1.success)(message, chalk.blue(environment.name));
696
+ }
697
+ catch (e) {
698
+ (0, logging_1.error)(' ❌ Environment %s failed bootstrapping: %s', chalk.blue(environment.name), e);
699
+ throw e;
700
+ }
701
+ })));
702
+ }
703
+ /**
704
+ * Garbage collects assets from a CDK app's environment
705
+ * @param options Options for Garbage Collection
706
+ */
707
+ async garbageCollect(userEnvironmentSpecs, options) {
708
+ var _a, _b, _c;
709
+ const environments = await this.defineEnvironments(userEnvironmentSpecs);
710
+ for (const environment of environments) {
711
+ (0, logging_1.success)(' ⏳ Garbage Collecting environment %s...', chalk.blue(environment.name));
712
+ const gc = new garbage_collector_1.GarbageCollector({
713
+ sdkProvider: this.props.sdkProvider,
714
+ resolvedEnvironment: environment,
715
+ bootstrapStackName: options.bootstrapStackName,
716
+ rollbackBufferDays: options.rollbackBufferDays,
717
+ createdBufferDays: options.createdBufferDays,
718
+ action: (_a = options.action) !== null && _a !== void 0 ? _a : 'full',
719
+ type: (_b = options.type) !== null && _b !== void 0 ? _b : 'all',
720
+ confirm: (_c = options.confirm) !== null && _c !== void 0 ? _c : true,
721
+ });
722
+ await gc.garbageCollect();
723
+ }
724
+ ;
725
+ }
726
+ async defineEnvironments(userEnvironmentSpecs) {
727
+ // By default, glob for everything
728
+ const environmentSpecs = userEnvironmentSpecs.length > 0 ? [...userEnvironmentSpecs] : ['**'];
729
+ // Partition into globs and non-globs (this will mutate environmentSpecs).
730
+ const globSpecs = (0, util_2.partition)(environmentSpecs, environments_1.looksLikeGlob);
731
+ if (globSpecs.length > 0 && !this.props.cloudExecutable.hasApp) {
732
+ if (userEnvironmentSpecs.length > 0) {
733
+ // User did request this glob
734
+ throw new error_1.ToolkitError(`'${globSpecs}' is not an environment name. Specify an environment name like 'aws://123456789012/us-east-1', or run in a directory with 'cdk.json' to use wildcards.`);
735
+ }
736
+ else {
737
+ // User did not request anything
738
+ throw new error_1.ToolkitError("Specify an environment name like 'aws://123456789012/us-east-1', or run in a directory with 'cdk.json'.");
739
+ }
740
+ }
741
+ const environments = [...(0, environments_1.environmentsFromDescriptors)(environmentSpecs)];
742
+ // If there is an '--app' argument, select the environments from the app.
743
+ if (this.props.cloudExecutable.hasApp) {
744
+ environments.push(...(await (0, environments_1.globEnvironmentsFromStacks)(await this.selectStacksForList([]), globSpecs, this.props.sdkProvider)));
745
+ }
746
+ return environments;
747
+ }
748
+ /**
749
+ * Migrates a CloudFormation stack/template to a CDK app
750
+ * @param options Options for CDK app creation
751
+ */
752
+ async migrate(options) {
753
+ var _a, _b, _c, _d, _e;
754
+ (0, logging_1.warning)('This command is an experimental feature.');
755
+ const language = (_b = (_a = options.language) === null || _a === void 0 ? void 0 : _a.toLowerCase()) !== null && _b !== void 0 ? _b : 'typescript';
756
+ const environment = (0, migrate_1.setEnvironment)(options.account, options.region);
757
+ let generateTemplateOutput;
758
+ let cfn;
759
+ let templateToDelete;
760
+ try {
761
+ // if neither fromPath nor fromStack is provided, generate a template using cloudformation
762
+ const scanType = (0, migrate_1.parseSourceOptions)(options.fromPath, options.fromStack, options.stackName).source;
763
+ if (scanType == migrate_1.TemplateSourceOptions.SCAN) {
764
+ generateTemplateOutput = await (0, migrate_1.generateTemplate)({
765
+ stackName: options.stackName,
766
+ filters: options.filter,
767
+ fromScan: options.fromScan,
768
+ sdkProvider: this.props.sdkProvider,
769
+ environment: environment,
770
+ });
771
+ templateToDelete = generateTemplateOutput.templateId;
772
+ }
773
+ else if (scanType == migrate_1.TemplateSourceOptions.PATH) {
774
+ const templateBody = (0, migrate_1.readFromPath)(options.fromPath);
775
+ const parsedTemplate = (0, serialize_1.deserializeStructure)(templateBody);
776
+ const templateId = (_d = (_c = parsedTemplate.Metadata) === null || _c === void 0 ? void 0 : _c.TemplateId) === null || _d === void 0 ? void 0 : _d.toString();
777
+ if (templateId) {
778
+ // if we have a template id, we can call describe generated template to get the resource identifiers
779
+ // resource metadata, and template source to generate the template
780
+ cfn = new migrate_1.CfnTemplateGeneratorProvider(await (0, migrate_1.buildCfnClient)(this.props.sdkProvider, environment));
781
+ const generatedTemplateSummary = await cfn.describeGeneratedTemplate(templateId);
782
+ generateTemplateOutput = (0, migrate_1.buildGenertedTemplateOutput)(generatedTemplateSummary, templateBody, generatedTemplateSummary.GeneratedTemplateId);
783
+ }
784
+ else {
785
+ generateTemplateOutput = {
786
+ migrateJson: {
787
+ templateBody: templateBody,
788
+ source: 'localfile',
789
+ },
790
+ };
791
+ }
792
+ }
793
+ else if (scanType == migrate_1.TemplateSourceOptions.STACK) {
794
+ const template = await (0, migrate_1.readFromStack)(options.stackName, this.props.sdkProvider, environment);
795
+ if (!template) {
796
+ throw new error_1.ToolkitError(`No template found for stack-name: ${options.stackName}`);
797
+ }
798
+ generateTemplateOutput = {
799
+ migrateJson: {
800
+ templateBody: template,
801
+ source: options.stackName,
802
+ },
803
+ };
804
+ }
805
+ else {
806
+ // We shouldn't ever get here, but just in case.
807
+ throw new error_1.ToolkitError(`Invalid source option provided: ${scanType}`);
808
+ }
809
+ const stack = (0, migrate_1.generateStack)(generateTemplateOutput.migrateJson.templateBody, options.stackName, language);
810
+ (0, logging_1.success)(' ⏳ Generating CDK app for %s...', chalk.blue(options.stackName));
811
+ await (0, migrate_1.generateCdkApp)(options.stackName, stack, language, options.outputPath, options.compress);
812
+ if (generateTemplateOutput) {
813
+ (0, migrate_1.writeMigrateJsonFile)(options.outputPath, options.stackName, generateTemplateOutput.migrateJson);
814
+ }
815
+ if ((0, migrate_1.isThereAWarning)(generateTemplateOutput)) {
816
+ (0, logging_1.warning)(' ⚠️ Some resources could not be migrated completely. Please review the README.md file for more information.');
817
+ (0, migrate_1.appendWarningsToReadme)(`${path.join((_e = options.outputPath) !== null && _e !== void 0 ? _e : process.cwd(), options.stackName)}/README.md`, generateTemplateOutput.resources);
818
+ }
819
+ }
820
+ catch (e) {
821
+ (0, logging_1.error)(' ❌ Migrate failed for `%s`: %s', options.stackName, e.message);
822
+ throw e;
823
+ }
824
+ finally {
825
+ if (templateToDelete) {
826
+ if (!cfn) {
827
+ cfn = new migrate_1.CfnTemplateGeneratorProvider(await (0, migrate_1.buildCfnClient)(this.props.sdkProvider, environment));
828
+ }
829
+ if (!process.env.MIGRATE_INTEG_TEST) {
830
+ await cfn.deleteGeneratedTemplate(templateToDelete);
831
+ }
832
+ }
833
+ }
834
+ }
835
+ async selectStacksForList(patterns) {
836
+ const assembly = await this.assembly();
837
+ const stacks = await assembly.selectStacks({ patterns }, { defaultBehavior: cloud_assembly_1.DefaultSelection.AllStacks });
838
+ // No validation
839
+ return stacks;
840
+ }
841
+ async selectStacksForDeploy(selector, exclusively, cacheCloudAssembly, ignoreNoStacks) {
842
+ const assembly = await this.assembly(cacheCloudAssembly);
843
+ const stacks = await assembly.selectStacks(selector, {
844
+ extend: exclusively ? cloud_assembly_1.ExtendedStackSelection.None : cloud_assembly_1.ExtendedStackSelection.Upstream,
845
+ defaultBehavior: cloud_assembly_1.DefaultSelection.OnlySingle,
846
+ ignoreNoStacks,
847
+ });
848
+ this.validateStacksSelected(stacks, selector.patterns);
849
+ await this.validateStacks(stacks);
850
+ return stacks;
851
+ }
852
+ async selectStacksForDiff(stackNames, exclusively, autoValidate) {
853
+ const assembly = await this.assembly();
854
+ const selectedForDiff = await assembly.selectStacks({ patterns: stackNames }, {
855
+ extend: exclusively ? cloud_assembly_1.ExtendedStackSelection.None : cloud_assembly_1.ExtendedStackSelection.Upstream,
856
+ defaultBehavior: cloud_assembly_1.DefaultSelection.MainAssembly,
857
+ });
858
+ const allStacks = await this.selectStacksForList([]);
859
+ const autoValidateStacks = autoValidate
860
+ ? allStacks.filter((art) => { var _a; return (_a = art.validateOnSynth) !== null && _a !== void 0 ? _a : false; })
861
+ : new cloud_assembly_1.StackCollection(assembly, []);
862
+ this.validateStacksSelected(selectedForDiff.concat(autoValidateStacks), stackNames);
863
+ await this.validateStacks(selectedForDiff.concat(autoValidateStacks));
864
+ return selectedForDiff;
865
+ }
866
+ async selectStacksForDestroy(selector, exclusively) {
867
+ const assembly = await this.assembly();
868
+ const stacks = await assembly.selectStacks(selector, {
869
+ extend: exclusively ? cloud_assembly_1.ExtendedStackSelection.None : cloud_assembly_1.ExtendedStackSelection.Downstream,
870
+ defaultBehavior: cloud_assembly_1.DefaultSelection.OnlySingle,
871
+ });
872
+ // No validation
873
+ return stacks;
874
+ }
875
+ /**
876
+ * Validate the stacks for errors and warnings according to the CLI's current settings
877
+ */
878
+ async validateStacks(stacks) {
879
+ let failAt = 'error';
880
+ if (this.props.ignoreErrors) {
881
+ failAt = 'none';
882
+ }
883
+ if (this.props.strict) {
884
+ failAt = 'warn';
885
+ }
886
+ await stacks.validateMetadata(failAt, stackMetadataLogger(this.props.verbose));
887
+ }
888
+ /**
889
+ * Validate that if a user specified a stack name there exists at least 1 stack selected
890
+ */
891
+ validateStacksSelected(stacks, stackNames) {
892
+ if (stackNames.length != 0 && stacks.stackCount == 0) {
893
+ throw new error_1.ToolkitError(`No stacks match the name(s) ${stackNames}`);
894
+ }
895
+ }
896
+ /**
897
+ * Select a single stack by its name
898
+ */
899
+ async selectSingleStackByName(stackName) {
900
+ const assembly = await this.assembly();
901
+ const stacks = await assembly.selectStacks({ patterns: [stackName] }, {
902
+ extend: cloud_assembly_1.ExtendedStackSelection.None,
903
+ defaultBehavior: cloud_assembly_1.DefaultSelection.None,
904
+ });
905
+ // Could have been a glob so check that we evaluated to exactly one
906
+ if (stacks.stackCount > 1) {
907
+ throw new error_1.ToolkitError(`This command requires exactly one stack and we matched more than one: ${stacks.stackIds}`);
908
+ }
909
+ return assembly.stackById(stacks.firstStack.id);
910
+ }
911
+ assembly(cacheCloudAssembly) {
912
+ return this.props.cloudExecutable.synthesize(cacheCloudAssembly);
913
+ }
914
+ patternsArrayForWatch(patterns, options) {
915
+ const patternsArray = patterns !== undefined ? (Array.isArray(patterns) ? patterns : [patterns]) : [];
916
+ return patternsArray.length > 0 ? patternsArray : options.returnRootDirIfEmpty ? [options.rootDir] : [];
917
+ }
918
+ async invokeDeployFromWatch(options, cloudWatchLogMonitor) {
919
+ const deployOptions = {
920
+ ...options,
921
+ requireApproval: diff_1.RequireApproval.Never,
922
+ // if 'watch' is called by invoking 'cdk deploy --watch',
923
+ // we need to make sure to not call 'deploy' with 'watch' again,
924
+ // as that would lead to a cycle
925
+ watch: false,
926
+ cloudWatchLogMonitor,
927
+ cacheCloudAssembly: false,
928
+ hotswap: options.hotswap,
929
+ extraUserAgent: `cdk-watch/hotswap-${options.hotswap !== common_1.HotswapMode.FALL_BACK ? 'on' : 'off'}`,
930
+ concurrency: options.concurrency,
931
+ };
932
+ try {
933
+ await this.deploy(deployOptions);
934
+ }
935
+ catch {
936
+ // just continue - deploy will show the error
937
+ }
938
+ }
939
+ /**
940
+ * Remove the asset publishing and building from the work graph for assets that are already in place
941
+ */
942
+ async removePublishedAssets(graph, options) {
943
+ await graph.removeUnnecessaryAssets(assetNode => this.props.deployments.isSingleAssetPublished(assetNode.assetManifest, assetNode.asset, {
944
+ stack: assetNode.parentStack,
945
+ roleArn: options.roleArn,
946
+ stackName: assetNode.parentStack.stackName,
947
+ }));
948
+ }
949
+ }
950
+ exports.CdkToolkit = CdkToolkit;
951
+ /**
952
+ * Print a serialized object (YAML or JSON) to stdout.
953
+ */
954
+ function printSerializedObject(obj, json) {
955
+ (0, logging_1.result)((0, serialize_1.serializeStructure)(obj, json));
956
+ }
957
+ function buildParameterMap(parameters) {
958
+ const parameterMap = { '*': {} };
959
+ for (const key in parameters) {
960
+ if (parameters.hasOwnProperty(key)) {
961
+ const [stack, parameter] = key.split(':', 2);
962
+ if (!parameter) {
963
+ parameterMap['*'][stack] = parameters[key];
964
+ }
965
+ else {
966
+ if (!parameterMap[stack]) {
967
+ parameterMap[stack] = {};
968
+ }
969
+ parameterMap[stack][parameter] = parameters[key];
970
+ }
971
+ }
972
+ }
973
+ return parameterMap;
974
+ }
975
+ /**
976
+ * Ask the user for a yes/no confirmation
977
+ *
978
+ * Automatically fail the confirmation in case we're in a situation where the confirmation
979
+ * cannot be interactively obtained from a human at the keyboard.
980
+ */
981
+ async function askUserConfirmation(ioHost, concurrency, motivation, question) {
982
+ await ioHost.withCorkedLogging(async () => {
983
+ // only talk to user if STDIN is a terminal (otherwise, fail)
984
+ if (!TESTING && !process.stdin.isTTY) {
985
+ throw new error_1.ToolkitError(`${motivation}, but terminal (TTY) is not attached so we are unable to get a confirmation from the user`);
986
+ }
987
+ // only talk to user if concurrency is 1 (otherwise, fail)
988
+ if (concurrency > 1) {
989
+ throw new error_1.ToolkitError(`${motivation}, but concurrency is greater than 1 so we are unable to get a confirmation from the user`);
990
+ }
991
+ const confirmed = await promptly.confirm(`${chalk.cyan(question)} (y/n)?`);
992
+ if (!confirmed) {
993
+ throw new error_1.ToolkitError('Aborted by user');
994
+ }
995
+ });
996
+ }
997
+ /**
998
+ * Logger for processing stack metadata
999
+ */
1000
+ function stackMetadataLogger(verbose) {
1001
+ const makeLogger = (level) => {
1002
+ switch (level) {
1003
+ case 'error':
1004
+ return [logging_1.error, 'Error'];
1005
+ case 'warn':
1006
+ return [logging_1.warning, 'Warning'];
1007
+ default:
1008
+ return [logging_1.info, 'Info'];
1009
+ }
1010
+ };
1011
+ return async (level, msg) => {
1012
+ const [logFn, prefix] = makeLogger(level);
1013
+ logFn(`[${prefix} at ${msg.id}] ${msg.entry.data}`);
1014
+ if (verbose && msg.entry.trace) {
1015
+ logFn(` ${msg.entry.trace.join('\n ')}`);
1016
+ }
1017
+ };
1018
+ }
1019
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2RrLXRvb2xraXQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyJjZGstdG9vbGtpdC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7QUFtRUEsa0NBRUM7QUFyRUQsNkJBQTZCO0FBQzdCLCtCQUE4QjtBQUM5Qix5Q0FBeUM7QUFDekMsK0JBQStCO0FBQy9CLHFDQUFxQztBQUNyQywrQkFBK0I7QUFDL0IscUNBQXFDO0FBQ3JDLDZCQUE2QjtBQUM3Qiw2REFBcUU7QUFFckUsZ0RBQTZFO0FBQzdFLGdFQU1xQztBQUVyQyw0REFBbUg7QUFDbkgsb0RBQXFIO0FBQ3JILG1GQUErRTtBQUMvRSxrREFBb0c7QUFDcEcsMkVBQTJFO0FBQzNFLDJEQUFxRTtBQUNyRSxzQ0FBcUQ7QUFDckQsOEZBQTBGO0FBQzFGLHlFQUE2RDtBQUM3RCxpREFpQjZCO0FBQzdCLGtDQUE2RTtBQUM3RSxzQ0FBdUU7QUFDdkUsZ0RBQTRDO0FBQzVDLHdDQUFrRztBQUNsRywwQ0FBK0M7QUFDL0MsNENBQXlGO0FBQ3pGLHdEQUFtRDtBQUNuRCw0Q0FBZ0Q7QUFDaEQsa0NBQW9EO0FBQ3BELHlDQUFtRDtBQUNuRCxpRkFBd0U7QUFFeEUsbUVBQThEO0FBRzlELDZFQUE2RTtBQUM3RSxpRUFBaUU7QUFDakUsTUFBTSxNQUFNLEdBQTZCLE9BQU8sQ0FBQyxTQUFTLENBQUMsQ0FBQztBQUU1RCxJQUFJLE9BQU8sR0FBRyxLQUFLLENBQUM7QUFFcEIsU0FBZ0IsV0FBVztJQUN6QixPQUFPLEdBQUcsSUFBSSxDQUFDO0FBQ2pCLENBQUM7QUFrREQ7O0dBRUc7QUFDSCxJQUFZLGNBYVg7QUFiRCxXQUFZLGNBQWM7SUFDeEI7Ozs7O09BS0c7SUFDSCw2RUFBaUIsQ0FBQTtJQUVqQjs7T0FFRztJQUNILG1FQUFZLENBQUE7QUFDZCxDQUFDLEVBYlcsY0FBYyw4QkFBZCxjQUFjLFFBYXpCO0FBRUQ7Ozs7O0dBS0c7QUFDSCxNQUFhLFVBQVU7SUFHckIsWUFBNkIsS0FBc0I7O1FBQXRC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RSxNQUFNLENBQUMsQ0FBQztRQUMxQixDQUFDO0lBQ0gsQ0FBQyxDQUFDO0lBRUYsT0FBTyxLQUFLLEVBQUUsS0FBSyxFQUFFLEdBQUcsRUFBRSxFQUFFO1FBQzFCLE1BQU0sQ0FBQyxLQUFLLEVBQUUsTUFBTSxDQUFDLEdBQUcsVUFBVSxDQUFDLEtBQUssQ0FBQyxDQUFDO1FBQzFDLEtBQUssQ0FBQyxJQUFJLE1BQU0sT0FBTyxHQUFHLENBQUMsRUFBRSxLQUFLLEdBQUcsQ0FBQyxLQUFLLENBQUMsSUFBSSxFQUFFLENBQUMsQ0FBQztRQUVwRCxJQUFJLE9BQU8sSUFBSSxHQUFHLENBQUMsS0FBSyxDQUFDLEtBQUssRUFBRSxDQUFDO1lBQy9CLEtBQUssQ0FBQyxLQUFLLEdBQUcsQ0FBQyxLQUFLLENBQUMsS0FBSyxDQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsRUFBRSxDQUFDLENBQUM7UUFDN0MsQ0FBQztJQUNILENBQUMsQ0FBQztBQUNKLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgKiBhcyBwYXRoIGZyb20gJ3BhdGgnO1xuaW1wb3J0IHsgZm9ybWF0IH0gZnJvbSAndXRpbCc7XG5pbXBvcnQgKiBhcyBjeGFwaSBmcm9tICdAYXdzLWNkay9jeC1hcGknO1xuaW1wb3J0ICogYXMgY2hhbGsgZnJvbSAnY2hhbGsnO1xuaW1wb3J0ICogYXMgY2hva2lkYXIgZnJvbSAnY2hva2lkYXInO1xuaW1wb3J0ICogYXMgZnMgZnJvbSAnZnMtZXh0cmEnO1xuaW1wb3J0ICogYXMgcHJvbXB0bHkgZnJvbSAncHJvbXB0bHknO1xuaW1wb3J0ICogYXMgdXVpZCBmcm9tICd1dWlkJztcbmltcG9ydCB7IENvbmZpZ3VyYXRpb24sIFBST0pFQ1RfQ09ORklHIH0gZnJvbSAnLi91c2VyLWNvbmZpZ3VyYXRpb24nO1xuaW1wb3J0IHsgU2RrUHJvdmlkZXIgfSBmcm9tICcuLi9hcGkvYXdzLWF1dGgnO1xuaW1wb3J0IHsgQm9vdHN0cmFwcGVyLCBCb290c3RyYXBFbnZpcm9ubWVudE9wdGlvbnMgfSBmcm9tICcuLi9hcGkvYm9vdHN0cmFwJztcbmltcG9ydCB7XG4gIENsb3VkQXNzZW1ibHksXG4gIERlZmF1bHRTZWxlY3Rpb24sXG4gIEV4dGVuZGVkU3RhY2tTZWxlY3Rpb24sXG4gIFN0YWNrQ29sbGVjdGlvbixcbiAgU3RhY2tTZWxlY3Rvcixcbn0gZnJvbSAnLi4vYXBpL2N4YXBwL2Nsb3VkLWFzc2VtYmx5JztcbmltcG9ydCB7IENsb3VkRXhlY3V0YWJsZSB9IGZyb20gJy4uL2FwaS9jeGFwcC9jbG91ZC1leGVjdXRhYmxlJztcbmltcG9ydCB7IGVudmlyb25tZW50c0Zyb21EZXNjcmlwdG9ycywgZ2xvYkVudmlyb25tZW50c0Zyb21TdGFja3MsIGxvb2tzTGlrZUdsb2IgfSBmcm9tICcuLi9hcGkvY3hhcHAvZW52aXJvbm1lbnRzJztcbmltcG9ydCB7IERlcGxveW1lbnRzLCBEZXBsb3ltZW50TWV0aG9kLCBTdWNjZXNzZnVsRGVwbG95U3RhY2tSZXN1bHQsIGNyZWF0ZURpZmZDaGFuZ2VTZXQgfSBmcm9tICcuLi9hcGkvZGVwbG95bWVudHMnO1xuaW1wb3J0IHsgR2FyYmFnZUNvbGxlY3RvciB9IGZyb20gJy4uL2FwaS9nYXJiYWdlLWNvbGxlY3Rpb24vZ2FyYmFnZS1jb2xsZWN0b3InO1xuaW1wb3J0IHsgSG90c3dhcE1vZGUsIEhvdHN3YXBQcm9wZXJ0eU92ZXJyaWRlcywgRWNzSG90c3dhcFByb3BlcnRpZXMgfSBmcm9tICcuLi9hcGkvaG90c3dhcC9jb21tb24nO1xuaW1wb3J0IHsgZmluZENsb3VkV2F0Y2hMb2dHcm91cHMgfSBmcm9tICcuLi9hcGkvbG9ncy9maW5kLWNsb3Vkd2F0Y2gtbG9ncyc7XG5pbXBvcnQgeyBDbG91ZFdhdGNoTG9nRXZlbnRNb25pdG9yIH0gZnJvbSAnLi4vYXBpL2xvZ3MvbG9ncy1tb25pdG9yJztcbmltcG9ydCB7IHRhZ3NGb3JTdGFjaywgdHlwZSBUYWcgfSBmcm9tICcuLi9hcGkvdGFncyc7XG5pbXBvcnQgeyBTdGFja0FjdGl2aXR5UHJvZ3Jlc3MgfSBmcm9tICcuLi9hcGkvdXRpbC9jbG91ZGZvcm1hdGlvbi9zdGFjay1hY3Rpdml0eS1tb25pdG9yJztcbmltcG9ydCB7IGZvcm1hdFRpbWUgfSBmcm9tICcuLi9hcGkvdXRpbC9zdHJpbmctbWFuaXB1bGF0aW9uJztcbmltcG9ydCB7XG4gIGdlbmVyYXRlQ2RrQXBwLFxuICBnZW5lcmF0ZVN0YWNrLFxuICByZWFkRnJvbVBhdGgsXG4gIHJlYWRGcm9tU3RhY2ssXG4gIHNldEVudmlyb25tZW50LFxuICBwYXJzZVNvdXJjZU9wdGlvbnMsXG4gIGdlbmVyYXRlVGVtcGxhdGUsXG4gIEZyb21TY2FuLFxuICBUZW1wbGF0ZVNvdXJjZU9wdGlvbnMsXG4gIEdlbmVyYXRlVGVtcGxhdGVPdXRwdXQsXG4gIENmblRlbXBsYXRlR2VuZXJhdG9yUHJvdmlkZXIsXG4gIHdyaXRlTWlncmF0ZUpzb25GaWxlLFxuICBidWlsZEdlbmVydGVkVGVtcGxhdGVPdXRwdXQsXG4gIGFwcGVuZFdhcm5pbmdzVG9SZWFkbWUsXG4gIGlzVGhlcmVBV2FybmluZyxcbiAgYnVpbGRDZm5DbGllbnQsXG59IGZyb20gJy4uL2NvbW1hbmRzL21pZ3JhdGUnO1xuaW1wb3J0IHsgcHJpbnRTZWN1cml0eURpZmYsIHByaW50U3RhY2tEaWZmLCBSZXF1aXJlQXBwcm92YWwgfSBmcm9tICcuLi9kaWZmJztcbmltcG9ydCB7IFJlc291cmNlSW1wb3J0ZXIsIHJlbW92ZU5vbkltcG9ydFJlc291cmNlcyB9IGZyb20gJy4uL2ltcG9ydCc7XG5pbXBvcnQgeyBsaXN0U3RhY2tzIH0gZnJvbSAnLi4vbGlzdC1zdGFja3MnO1xuaW1wb3J0IHsgcmVzdWx0IGFzIGxvZ1Jlc3VsdCwgZGVidWcsIGVycm9yLCBoaWdobGlnaHQsIGluZm8sIHN1Y2Nlc3MsIHdhcm5pbmcgfSBmcm9tICcuLi9sb2dnaW5nJztcbmltcG9ydCB7IFJlc291cmNlTWlncmF0b3IgfSBmcm9tICcuLi9taWdyYXRvcic7XG5pbXBvcnQgeyBkZXNlcmlhbGl6ZVN0cnVjdHVyZSwgb2JzY3VyZVRlbXBsYXRlLCBzZXJpYWxpemVTdHJ1Y3R1cmUgfSBmcm9tICcuLi9zZXJpYWxpemUnO1xuaW1wb3J0IHsgQ2xpSW9Ib3N0IH0gZnJvbSAnLi4vdG9vbGtpdC9jbGktaW8taG9zdCc7XG5pbXBvcnQgeyBUb29sa2l0RXJyb3IgfSBmcm9tICcuLi90b29sa2l0L2Vycm9yJztcbmltcG9ydCB7IG51bWJlckZyb21Cb29sLCBwYXJ0aXRpb24gfSBmcm9tICcuLi91dGlsJztcbmltcG9ydCB7IGZvcm1hdEVycm9yTWVzc2FnZSB9IGZyb20gJy4uL3V0aWwvZXJyb3InO1xuaW1wb3J0IHsgdmFsaWRhdGVTbnNUb3BpY0FybiB9IGZyb20gJy4uL3V0aWwvdmFsaWRhdGUtbm90aWZpY2F0aW9uLWFybic7XG5pbXBvcnQgeyBDb25jdXJyZW5jeSwgV29ya0dyYXBoIH0gZnJvbSAnLi4vdXRpbC93b3JrLWdyYXBoJztcbmltcG9ydCB7IFdvcmtHcmFwaEJ1aWxkZXIgfSBmcm9tICcuLi91dGlsL3dvcmstZ3JhcGgtYnVpbGRlcic7XG5pbXBvcnQgeyBBc3NldEJ1aWxkTm9kZSwgQXNzZXRQdWJsaXNoTm9kZSwgU3RhY2tOb2RlIH0gZnJvbSAnLi4vdXRpbC93b3JrLWdyYXBoLXR5cGVzJztcblxuLy8gTXVzdCB1c2UgYSByZXF1aXJlKCkgb3RoZXJ3aXNlIGVzYnVpbGQgY29tcGxhaW5zIGFib3V0IGNhbGxpbmcgYSBuYW1lc3BhY2Vcbi8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tcmVxdWlyZS1pbXBvcnRzXG5jb25zdCBwTGltaXQ6IHR5cGVvZiBpbXBvcnQoJ3AtbGltaXQnKSA9IHJlcXVpcmUoJ3AtbGltaXQnKTtcblxubGV0IFRFU1RJTkcgPSBmYWxzZTtcblxuZXhwb3J0IGZ1bmN0aW9uIG1hcmtUZXN0aW5nKCkge1xuICBURVNUSU5HID0gdHJ1ZTtcbn1cblxuZXhwb3J0IGludGVyZmFjZSBDZGtUb29sa2l0UHJvcHMge1xuICAvKipcbiAgICogVGhlIENsb3VkIEV4ZWN1dGFibGVcbiAgICovXG4gIGNsb3VkRXhlY3V0YWJsZTogQ2xvdWRFeGVjdXRhYmxlO1xuXG4gIC8qKlxuICAgKiBUaGUgcHJvdmlzaW9uaW5nIGVuZ2luZSB1c2VkIHRvIGFwcGx5IGNoYW5nZXMgdG8gdGhlIGNsb3VkXG4gICAqL1xuICBkZXBsb3ltZW50czogRGVwbG95bWVudHM7XG5cbiAgLyoqXG4gICAqIFRoZSBDbGlJb0hvc3QgdGhhdCdzIHVzZWQgZm9yIEkvTyBvcGVyYXRpb25zXG4gICAqL1xuICBpb0hvc3Q/OiBDbGlJb0hvc3Q7XG5cbiAgLyoqXG4gICAqIFdoZXRoZXIgdG8gYmUgdmVyYm9zZVxuICAgKlxuICAgKiBAZGVmYXVsdCBmYWxzZVxuICAgKi9cbiAgdmVyYm9zZT86IGJvb2xlYW47XG5cbiAgLyoqXG4gICAqIERvbid0IHN0b3Agb24gZXJyb3IgbWV0YWRhdGFcbiAgICpcbiAgICogQGRlZmF1bHQgZmFsc2VcbiAgICovXG4gIGlnbm9yZUVycm9ycz86IGJvb2xlYW47XG5cbiAgLyoqXG4gICAqIFRyZWF0IHdhcm5pbmdzIGluIG1ldGFkYXRhIGFzIGVycm9yc1xuICAgKlxuICAgKiBAZGVmYXVsdCBmYWxzZVxuICAgKi9cbiAgc3RyaWN0PzogYm9vbGVhbjtcblxuICAvKipcbiAgICogQXBwbGljYXRpb24gY29uZmlndXJhdGlvbiAoc2V0dGluZ3MgYW5kIGNvbnRleHQpXG4gICAqL1xuICBjb25maWd1cmF0aW9uOiBDb25maWd1cmF0aW9uO1xuXG4gIC8qKlxuICAgKiBBV1Mgb2JqZWN0ICh1c2VkIGJ5IHN5bnRoZXNpemVyIGFuZCBjb250ZXh0cHJvdmlkZXIpXG4gICAqL1xuICBzZGtQcm92aWRlcjogU2RrUHJvdmlkZXI7XG59XG5cbi8qKlxuICogV2hlbiB0byBidWlsZCBhc3NldHNcbiAqL1xuZXhwb3J0IGVudW0gQXNzZXRCdWlsZFRpbWUge1xuICAvKipcbiAgICogQnVpbGQgYWxsIGFzc2V0cyBiZWZvcmUgZGVwbG95aW5nIHRoZSBmaXJzdCBzdGFja1xuICAgKlxuICAgKiBUaGlzIGlzIGludGVuZGVkIGZvciBleHBlbnNpdmUgRG9ja2VyIGltYWdlIGJ1aWxkczsgc28gdGhhdCBpZiB0aGUgRG9ja2VyIGltYWdlIGJ1aWxkXG4gICAqIGZhaWxzLCBubyBzdGFja3MgYXJlIHVubmVjZXNzYXJpbHkgZGVwbG95ZWQgKHdpdGggdGhlIGF0dGVuZGFudCB3YWl0IHRpbWUpLlxuICAgKi9cbiAgQUxMX0JFRk9SRV9ERVBMT1ksXG5cbiAgLyoqXG4gICAqIEJ1aWxkIGFzc2V0cyBqdXN0LWluLXRpbWUsIGJlZm9yZSBwdWJsaXNoaW5nXG4gICAqL1xuICBKVVNUX0lOX1RJTUUsXG59XG5cbi8qKlxuICogVG9vbGtpdCBsb2dpY1xuICpcbiAqIFRoZSB0b29sa2l0IHJ1bnMgdGhlIGBjbG91ZEV4ZWN1dGFibGVgIHRvIG9idGFpbiBhIGNsb3VkIGFzc2VtYmx5IGFuZFxuICogZGVwbG95cyBhcHBsaWVzIHRoZW0gdG8gYGNsb3VkRm9ybWF0aW9uYC5cbiAqL1xuZXhwb3J0IGNsYXNzIENka1Rvb2xraXQge1xuICBwcml2YXRlIGlvSG9zdDogQ2xpSW9Ib3N0O1xuXG4gIGNvbnN0cnVjdG9yKHByaXZhdGUgcmVhZG9ubHkgcHJvcHM6IENka1Rvb2xraXRQcm9wcykge1xuICAgIHRoaXMuaW9Ib3N0ID0gcHJvcHMuaW9Ib3N0ID8/IENsaUlvSG9zdC5pbnN0YW5jZSgpO1xuICB9XG5cbiAgcHVibGljIGFzeW5jIG1ldGFkYXRhKHN0YWNrTmFtZTogc3RyaW5nLCBqc29uOiBib29sZWFuKSB7XG4gICAgY29uc3Qgc3RhY2tzID0gYXdhaXQgdGhpcy5zZWxlY3RTaW5nbGVTdGFja0J5TmFtZShzdGFja05hbWUpO1xuICAgIHByaW50U2VyaWFsaXplZE9iamVjdChzdGFja3MuZmlyc3RTdGFjay5tYW5pZmVzdC5tZXRhZGF0YSA/PyB7fSwganNvbik7XG4gIH1cblxuICBwdWJsaWMgYXN5bmMgYWNrbm93bGVkZ2Uobm90aWNlSWQ6IHN0cmluZykge1xuICAgIGNvbnN0IGFja3MgPSB0aGlzLnByb3BzLmNvbmZpZ3VyYXRpb24uY29udGV4dC5nZXQoJ2Fja25vd2xlZGdlZC1pc3N1ZS1udW1iZXJzJykgPz8gW107XG4gICAgYWNrcy5wdXNoKE51bWJlcihub3RpY2VJZCkpO1xuICAgIHRoaXMucHJvcHMuY29uZmlndXJhdGlvbi5jb250ZXh0LnNldCgnYWNrbm93bGVkZ2VkLWlzc3VlLW51bWJlcnMnLCBhY2tzKTtcbiAgICBhd2FpdCB0aGlzLnByb3BzLmNvbmZpZ3VyYXRpb24uc2F2ZUNvbnRleHQoKTtcbiAgfVxuXG4gIHB1YmxpYyBhc3luYyBkaWZmKG9wdGlvbnM6IERpZmZPcHRpb25zKTogUHJvbWlzZTxudW1iZXI+IHtcbiAgICBjb25zdCBzdGFja3MgPSBhd2FpdCB0aGlzLnNlbGVjdFN0YWNrc0ZvckRpZmYob3B0aW9ucy5zdGFja05hbWVzLCBvcHRpb25zLmV4Y2x1c2l2ZWx5KTtcblxuICAgIGNvbnN0IHN0cmljdCA9ICEhb3B0aW9ucy5zdHJpY3Q7XG4gICAgY29uc3QgY29udGV4dExpbmVzID0gb3B0aW9ucy5jb250ZXh0TGluZXMgfHwgMztcbiAgICBjb25zdCBzdHJlYW0gPSBvcHRpb25zLnN0cmVhbSB8fCBwcm9jZXNzLnN0ZGVycjtcbiAgICBjb25zdCBxdWlldCA9IG9wdGlvbnMucXVpZXQgfHwgZmFsc2U7XG5cbiAgICBsZXQgZGlmZnMgPSAwO1xuICAgIGNvbnN0IHBhcmFtZXRlck1hcCA9IGJ1aWxkUGFyYW1ldGVyTWFwKG9wdGlvbnMucGFyYW1ldGVycyk7XG5cbiAgICBpZiAob3B0aW9ucy50ZW1wbGF0ZVBhdGggIT09IHVuZGVmaW5lZCkge1xuICAgICAgLy8gQ29tcGFyZSBzaW5nbGUgc3RhY2sgYWdhaW5zdCBmaXhlZCB0ZW1wbGF0ZVxuICAgICAgaWYgKHN0YWNrcy5zdGFja0NvdW50ICE9PSAxKSB7XG4gICAgICAgIHRocm93IG5ldyBUb29sa2l0RXJyb3IoXG4gICAgICAgICAgJ0NhbiBvbmx5IHNlbGVjdCBvbmUgc3RhY2sgd2hlbiBjb21wYXJpbmcgdG8gZml4ZWQgdGVtcGxhdGUuIFVzZSAtLWV4Y2x1c2l2ZWx5IHRvIGF2b2lkIHNlbGVjdGluZyBtdWx0aXBsZSBzdGFja3MuJyxcbiAgICAgICAgKTtcbiAgICAgIH1cblxuICAgICAgaWYgKCEoYXdhaXQgZnMucGF0aEV4aXN0cyhvcHRpb25zLnRlbXBsYXRlUGF0aCkpKSB7XG4gICAgICAgIHRocm93IG5ldyBUb29sa2l0RXJyb3IoYFRoZXJlIGlzIG5vIGZpbGUgYXQgJHtvcHRpb25zLnRlbXBsYXRlUGF0aH1gKTtcbiAgICAgIH1cblxuICAgICAgY29uc3QgdGVtcGxhdGUgPSBkZXNlcmlhbGl6ZVN0cnVjdHVyZShhd2FpdCBmcy5yZWFkRmlsZShvcHRpb25zLnRlbXBsYXRlUGF0aCwgeyBlbmNvZGluZzogJ1VURi04JyB9KSk7XG4gICAgICBkaWZmcyA9IG9wdGlvbnMuc2VjdXJpdHlPbmx5XG4gICAgICAgID8gbnVtYmVyRnJvbUJvb2wocHJpbnRTZWN1cml0eURpZmYodGVtcGxhdGUsIHN0YWNrcy5maXJzdFN0YWNrLCBSZXF1aXJlQXBwcm92YWwuQnJvYWRlbmluZywgcXVpZXQpKVxuICAgICAgICA6IHByaW50U3RhY2tEaWZmKHRlbXBsYXRlLCBzdGFja3MuZmlyc3RTdGFjaywgc3RyaWN0LCBjb250ZXh0TGluZXMsIHF1aWV0LCB1bmRlZmluZWQsIHVuZGVmaW5lZCwgZmFsc2UsIHN0cmVhbSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIC8vIENvbXBhcmUgTiBzdGFja3MgYWdhaW5zdCBkZXBsb3llZCB0ZW1wbGF0ZXNcbiAgICAgIGZvciAoY29uc3Qgc3RhY2sgb2Ygc3RhY2tzLnN0YWNrQXJ0aWZhY3RzKSB7XG4gICAgICAgIGNvbnN0IHRlbXBsYXRlV2l0aE5lc3RlZFN0YWNrcyA9IGF3YWl0IHRoaXMucHJvcHMuZGVwbG95bWVudHMucmVhZEN1cnJlbnRUZW1wbGF0ZVdpdGhOZXN0ZWRTdGFja3MoXG4gICAgICAgICAgc3RhY2ssXG4gICAgICAgICAgb3B0aW9ucy5jb21wYXJlQWdhaW5zdFByb2Nlc3NlZFRlbXBsYXRlLFxuICAgICAgICApO1xuICAgICAgICBjb25zdCBjdXJyZW50VGVtcGxhdGUgPSB0ZW1wbGF0ZVdpdGhOZXN0ZWRTdGFja3MuZGVwbG95ZWRSb290VGVtcGxhdGU7XG4gICAgICAgIGNvbnN0IG5lc3RlZFN0YWNrcyA9IHRlbXBsYXRlV2l0aE5lc3RlZFN0YWNrcy5uZXN0ZWRTdGFja3M7XG5cbiAgICAgICAgY29uc3QgbWlncmF0b3IgPSBuZXcgUmVzb3VyY2VNaWdyYXRvcih7XG4gICAgICAgICAgZGVwbG95bWVudHM6IHRoaXMucHJvcHMuZGVwbG95bWVudHMsXG4gICAgICAgIH0pO1xuICAgICAgICBjb25zdCByZXNvdXJjZXNUb0ltcG9ydCA9IGF3YWl0IG1pZ3JhdG9yLnRyeUdldFJlc291cmNlcyhhd2FpdCB0aGlzLnByb3BzLmRlcGxveW1lbnRzLnJlc29sdmVFbnZpcm9ubWVudChzdGFjaykpO1xuICAgICAgICBpZiAocmVzb3VyY2VzVG9JbXBvcnQpIHtcbiAgICAgICAgICByZW1vdmVOb25JbXBvcnRSZXNvdXJjZXMoc3RhY2spO1xuICAgICAgICB9XG5cbiAgICAgICAgbGV0IGNoYW5nZVNldCA9IHVuZGVmaW5lZDtcblxuICAgICAgICBpZiAob3B0aW9ucy5jaGFuZ2VTZXQpIHtcbiAgICAgICAgICBsZXQgc3RhY2tFeGlzdHMgPSBmYWxzZTtcbiAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgc3RhY2tFeGlzdHMgPSBhd2FpdCB0aGlzLnByb3BzLmRlcGxveW1lbnRzLnN0YWNrRXhpc3RzKHtcbiAgICAgICAgICAgICAgc3RhY2ssXG4gICAgICAgICAgICAgIGRlcGxveU5hbWU6IHN0YWNrLnN0YWNrTmFtZSxcbiAgICAgICAgICAgICAgdHJ5TG9va3VwUm9sZTogdHJ1ZSxcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgIH0gY2F0Y2ggKGU6IGFueSkge1xuICAgICAgICAgICAgZGVidWcoZm9ybWF0RXJyb3JNZXNzYWdlKGUpKTtcbiAgICAgICAgICAgIGlmICghcXVpZXQpIHtcbiAgICAgICAgICAgICAgc3RyZWFtLndyaXRlKFxuICAgICAgICAgICAgICAgIGBDaGVja2luZyBpZiB0aGUgc3RhY2sgJHtzdGFjay5zdGFja05hbWV9IGV4aXN0cyBiZWZvcmUgY3JlYXRpbmcgdGhlIGNoYW5nZXNldCBoYXMgZmFpbGVkLCB3aWxsIGJhc2UgdGhlIGRpZmYgb24gdGVtcGxhdGUgZGlmZmVyZW5jZXMgKHJ1biBhZ2FpbiB3aXRoIC12IHRvIHNlZSB0aGUgcmVhc29uKVxcbmAsXG4gICAgICAgICAgICAgICk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBzdGFja0V4aXN0cyA9IGZhbHNlO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIGlmIChzdGFja0V4aXN0cykge1xuICAgICAgICAgICAgY2hhbmdlU2V0ID0gYXdhaXQgY3JlYXRlRGlmZkNoYW5nZVNldCh7XG4gICAgICAgICAgICAgIHN0YWNrLFxuICAgICAgICAgICAgICB1dWlkOiB1dWlkLnY0KCksXG4gICAgICAgICAgICAgIGRlcGxveW1lbnRzOiB0aGlzLnByb3BzLmRlcGxveW1lbnRzLFxuICAgICAgICAgICAgICB3aWxsRXhlY3V0ZTogZmFsc2UsXG4gICAgICAgICAgICAgIHNka1Byb3ZpZGVyOiB0aGlzLnByb3BzLnNka1Byb3ZpZGVyLFxuICAgICAgICAgICAgICBwYXJhbWV0ZXJzOiBPYmplY3QuYXNzaWduKHt9LCBwYXJhbWV0ZXJNYXBbJyonXSwgcGFyYW1ldGVyTWFwW3N0YWNrLnN0YWNrTmFtZV0pLFxuICAgICAgICAgICAgICByZXNvdXJjZXNUb0ltcG9ydCxcbiAgICAgICAgICAgICAgc3RyZWFtLFxuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGRlYnVnKFxuICAgICAgICAgICAgICBgdGhlIHN0YWNrICcke3N0YWNrLnN0YWNrTmFtZX0nIGhhcyBub3QgYmVlbiBkZXBsb3llZCB0byBDbG91ZEZvcm1hdGlvbiBvciBkZXNjcmliZVN0YWNrcyBjYWxsIGZhaWxlZCwgc2tpcHBpbmcgY2hhbmdlc2V0IGNyZWF0aW9uLmAsXG4gICAgICAgICAgICApO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIGNvbnN0IHN0YWNrQ291bnQgPSBvcHRpb25zLnNlY3VyaXR5T25seVxuICAgICAgICAgID8gbnVtYmVyRnJvbUJvb2woXG4gICAgICAgICAgICBwcmludFNlY3VyaXR5RGlmZihcbiAgICAgICAgICAgICAgY3VycmVudFRlbXBsYXRlLFxuICAgICAgICAgICAgICBzdGFjayxcbiAgICAgICAgICAgICAgUmVxdWlyZUFwcHJvdmFsLkJyb2FkZW5pbmcsXG4gICAgICAgICAgICAgIHF1aWV0LFxuICAgICAgICAgICAgICBzdGFjay5kaXNwbGF5TmFtZSxcbiAgICAgICAgICAgICAgY2hhbmdlU2V0LFxuICAgICAgICAgICAgKSxcbiAgICAgICAgICApXG4gICAgICAgICAgOiBwcmludFN0YWNrRGlmZihcbiAgICAgICAgICAgIGN1cnJlbnRUZW1wbGF0ZSxcbiAgICAgICAgICAgIHN0YWNrLFxuICAgICAgICAgICAgc3RyaWN0LFxuICAgICAgICAgICAgY29udGV4dExpbmVzLFxuICAgICAgICAgICAgcXVpZXQsXG4gICAgICAgICAgICBzdGFjay5kaXNwbGF5TmFtZSxcbiAgICAgICAgICAgIGNoYW5nZVNldCxcbiAgICAgICAgICAgICEhcmVzb3VyY2VzVG9JbXBvcnQsXG4gICAgICAgICAgICBzdHJlYW0sXG4gICAgICAgICAgICBuZXN0ZWRTdGFja3MsXG4gICAgICAgICAgKTtcblxuICAgICAgICBkaWZmcyArPSBzdGFja0NvdW50O1xuICAgICAgfVxuICAgIH1cblxuICAgIHN0cmVhbS53cml0ZShmb3JtYXQoJ1xcbuKcqCAgTnVtYmVyIG9mIHN0YWNrcyB3aXRoIGRpZmZlcmVuY2VzOiAlc1xcbicsIGRpZmZzKSk7XG5cbiAgICByZXR1cm4gZGlmZnMgJiYgb3B0aW9ucy5mYWlsID8gMSA6IDA7XG4gIH1cblxuICBwdWJsaWMgYXN5bmMgZGVwbG95KG9wdGlvbnM6IERlcGxveU9wdGlvbnMpIHtcbiAgICBpZiAob3B0aW9ucy53YXRjaCkge1xuICAgICAgcmV0dXJuIHRoaXMud2F0Y2gob3B0aW9ucyk7XG4gICAgfVxuXG4gICAgY29uc3Qgc3RhcnRTeW50aFRpbWUgPSBuZXcgRGF0ZSgpLmdldFRpbWUoKTtcbiAgICBjb25zdCBzdGFja0NvbGxlY3Rpb24gPSBhd2FpdCB0aGlzLnNlbGVjdFN0YWNrc0ZvckRlcGxveShcbiAgICAgIG9wdGlvbnMuc2VsZWN0b3IsXG4gICAgICBvcHRpb25zLmV4Y2x1c2l2ZWx5LFxuICAgICAgb3B0aW9ucy5jYWNoZUNsb3VkQXNzZW1ibHksXG4gICAgICBvcHRpb25zLmlnbm9yZU5vU3RhY2tzLFxuICAgICk7XG4gICAgY29uc3QgZWxhcHNlZFN5bnRoVGltZSA9IG5ldyBEYXRlKCkuZ2V0VGltZSgpIC0gc3RhcnRTeW50aFRpbWU7XG4gICAgaW5mbyhgXFxu4pyoICBTeW50aGVzaXMgdGltZTogJHtmb3JtYXRUaW1lKGVsYXBzZWRTeW50aFRpbWUpfXNcXG5gKTtcblxuICAgIGlmIChzdGFja0NvbGxlY3Rpb24uc3RhY2tDb3VudCA9PT0gMCkge1xuICAgICAgZXJyb3IoJ1RoaXMgYXBwIGNvbnRhaW5zIG5vIHN0YWNrcycpO1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGNvbnN0IG1pZ3JhdG9yID0gbmV3IFJlc291cmNlTWlncmF0b3Ioe1xuICAgICAgZGVwbG95bWVudHM6IHRoaXMucHJvcHMuZGVwbG95bWVudHMsXG4gICAgfSk7XG4gICAgYXdhaXQgbWlncmF0b3IudHJ5TWlncmF0ZVJlc291cmNlcyhzdGFja0NvbGxlY3Rpb24sIG9wdGlvbnMpO1xuXG4gICAgY29uc3QgcmVxdWlyZUFwcHJvdmFsID0gb3B0aW9ucy5yZXF1aXJlQXBwcm92YWwgPz8gUmVxdWlyZUFwcHJvdmFsLkJyb2FkZW5pbmc7XG5cbiAgICBjb25zdCBwYXJhbWV0ZXJNYXAgPSBidWlsZFBhcmFtZXRlck1hcChvcHRpb25zLnBhcmFtZXRlcnMpO1xuXG4gICAgaWYgKG9wdGlvbnMuaG90c3dhcCAhPT0gSG90c3dhcE1vZGUuRlVMTF9ERVBMT1lNRU5UKSB7XG4gICAgICB3YXJuaW5nKFxuICAgICAgICAn4pqg77iPIFRoZSAtLWhvdHN3YXAgYW5kIC0taG90c3dhcC1mYWxsYmFjayBmbGFncyBkZWxpYmVyYXRlbHkgaW50cm9kdWNlIENsb3VkRm9ybWF0aW9uIGRyaWZ0IHRvIHNwZWVkIHVwIGRlcGxveW1lbnRzJyxcbiAgICAgICk7XG4gICAgICB3YXJuaW5nKCfimqDvuI8gVGhleSBzaG91bGQgb25seSBiZSB1c2VkIGZvciBkZXZlbG9wbWVudCAtIG5ldmVyIHVzZSB0aGVtIGZvciB5b3VyIHByb2R1Y3Rpb24gU3RhY2tzIVxcbicpO1xuICAgIH1cblxuICAgIGxldCBob3Rzd2FwUHJvcGVydGllc0Zyb21TZXR0aW5ncyA9IHRoaXMucHJvcHMuY29uZmlndXJhdGlvbi5zZXR0aW5ncy5nZXQoWydob3Rzd2FwJ10pIHx8IHt9O1xuXG4gICAgbGV0IGhvdHN3YXBQcm9wZXJ0eU92ZXJyaWRlcyA9IG5ldyBIb3Rzd2FwUHJvcGVydHlPdmVycmlkZXMoKTtcbiAgICBob3Rzd2FwUHJvcGVydHlPdmVycmlkZXMuZWNzSG90c3dhcFByb3BlcnRpZXMgPSBuZXcgRWNzSG90c3dhcFByb3BlcnRpZXMoXG4gICAgICBob3Rzd2FwUHJvcGVydGllc0Zyb21TZXR0aW5ncy5lY3M/Lm1pbmltdW1IZWFsdGh5UGVyY2VudCxcbiAgICAgIGhvdHN3YXBQcm9wZXJ0aWVzRnJvbVNldHRpbmdzLmVjcz8ubWF4aW11bUhlYWx0aHlQZXJjZW50LFxuICAgICk7XG5cbiAgICBjb25zdCBzdGFja3MgPSBzdGFja0NvbGxlY3Rpb24uc3RhY2tBcnRpZmFjdHM7XG5cbiAgICBjb25zdCBzdGFja091dHB1dHM6IHsgW2tleTogc3RyaW5nXTogYW55IH0gPSB7fTtcbiAgICBjb25zdCBvdXRwdXRzRmlsZSA9IG9wdGlvbnMub3V0cHV0c0ZpbGU7XG5cbiAgICBjb25zdCBidWlsZEFzc2V0ID0gYXN5bmMgKGFzc2V0Tm9kZTogQXNzZXRCdWlsZE5vZGUpID0+IHtcbiAgICAgIGF3YWl0IHRoaXMucHJvcHMuZGVwbG95bWVudHMuYnVpbGRTaW5nbGVBc3NldChcbiAgICAgICAgYXNzZXROb2RlLmFzc2V0TWFuaWZlc3RBcnRpZmFjdCxcbiAgICAgICAgYXNzZXROb2RlLmFzc2V0TWFuaWZlc3QsXG4gICAgICAgIGFzc2V0Tm9kZS5hc3NldCxcbiAgICAgICAge1xuICAgICAgICAgIHN0YWNrOiBhc3NldE5vZGUucGFyZW50U3RhY2ssXG4gICAgICAgICAgcm9sZUFybjogb3B0aW9ucy5yb2xlQXJuLFxuICAgICAgICAgIHN0YWNrTmFtZTogYXNzZXROb2RlLnBhcmVudFN0YWNrLnN0YWNrTmFtZSxcbiAgICAgICAgfSxcbiAgICAgICk7XG4gICAgfTtcblxuICAgIGNvbnN0IHB1Ymxpc2hBc3NldCA9IGFzeW5jIChhc3NldE5vZGU6IEFzc2V0UHVibGlzaE5vZGUpID0+IHtcbiAgICAgIGF3YWl0IHRoaXMucHJvcHMuZGVwbG95bWVudHMucHVibGlzaFNpbmdsZUFzc2V0KGFzc2V0Tm9kZS5hc3NldE1hbmlmZXN0LCBhc3NldE5vZGUuYXNzZXQsIHtcbiAgICAgICAgc3RhY2s6IGFzc2V0Tm9kZS5wYXJlbnRTdGFjayxcbiAgICAgICAgcm9sZUFybjogb3B0aW9ucy5yb2xlQXJuLFxuICAgICAgICBzdGFja05hbWU6IGFzc2V0Tm9kZS5wYXJlbnRTdGFjay5zdGFja05hbWUsXG4gICAgICB9KTtcbiAgICB9O1xuXG4gICAgY29uc3QgZGVwbG95U3RhY2sgPSBhc3luYyAoc3RhY2tOb2RlOiBTdGFja05vZGUpID0+IHtcbiAgICAgIGNvbnN0IHN0YWNrID0gc3RhY2tOb2RlLnN0YWNrO1xuICAgICAgaWYgKHN0YWNrQ29sbGVjdGlvbi5zdGFja0NvdW50ICE9PSAxKSB7XG4gICAgICAgIGhpZ2hsaWdodChzdGFjay5kaXNwbGF5TmFtZSk7XG4gICAgICB9XG5cbiAgICAgIGlmICghc3RhY2suZW52aXJvbm1lbnQpIHtcbiAgICAgICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIG1heC1sZW5cbiAgICAgICAgdGhyb3cgbmV3IFRvb2xraXRFcnJvcihcbiAgICAgICAgICBgU3RhY2sgJHtzdGFjay5kaXNwbGF5TmFtZX0gZG9lcyBub3QgZGVmaW5lIGFuIGVudmlyb25tZW50LCBhbmQgQVdTIGNyZWRlbnRpYWxzIGNvdWxkIG5vdCBiZSBvYnRhaW5lZCBmcm9tIHN0YW5kYXJkIGxvY2F0aW9ucyBvciBubyByZWdpb24gd2FzIGNvbmZpZ3VyZWQuYCxcbiAgICAgICAgKTtcbiAgICAgIH1cblxuICAgICAgaWYgKE9iamVjdC5rZXlzKHN0YWNrLnRlbXBsYXRlLlJlc291cmNlcyB8fCB7fSkubGVuZ3RoID09PSAwKSB7XG4gICAgICAgIC8vIFRoZSBnZW5lcmF0ZWQgc3RhY2sgaGFzIG5vIHJlc291cmNlc1xuICAgICAgICBpZiAoIShhd2FpdCB0aGlzLnByb3BzLmRlcGxveW1lbnRzLnN0YWNrRXhpc3RzKHsgc3RhY2sgfSkpKSB7XG4gICAgICAgICAgd2FybmluZygnJXM6IHN0YWNrIGhhcyBubyByZXNvdXJjZXMsIHNraXBwaW5nIGRlcGxveW1lbnQuJywgY2hhbGsuYm9sZChzdGFjay5kaXNwbGF5TmFtZSkpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHdhcm5pbmcoJyVzOiBzdGFjayBoYXMgbm8gcmVzb3VyY2VzLCBkZWxldGluZyBleGlzdGluZyBzdGFjay4nLCBjaGFsay5ib2xkKHN0YWNrLmRpc3BsYXlOYW1lKSk7XG4gICAgICAgICAgYXdhaXQgdGhpcy5kZXN0cm95KHtcbiAgICAgICAgICAgIHNlbGVjdG9yOiB7IHBhdHRlcm5zOiBbc3RhY2suaGllcmFyY2hpY2FsSWRdIH0sXG4gICAgICAgICAgICBleGNsdXNpdmVseTogdHJ1ZSxcbiAgICAgICAgICAgIGZvcmNlOiB0cnVlLFxuICAgICAgICAgICAgcm9sZUFybjogb3B0aW9ucy5yb2xlQXJuLFxuICAgICAgICAgICAgZnJvbURlcGxveTogdHJ1ZSxcbiAgICAgICAgICAgIGNpOiBvcHRpb25zLmNpLFxuICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cblxuICAgICAgaWYgKHJlcXVpcmVBcHByb3ZhbCAhPT0gUmVxdWlyZUFwcHJvdmFsLk5ldmVyKSB7XG4gICAgICAgIGNvbnN0IGN1cnJlbnRUZW1wbGF0ZSA9IGF3YWl0IHRoaXMucHJvcHMuZGVwbG95bWVudHMucmVhZEN1cnJlbnRUZW1wbGF0ZShzdGFjayk7XG4gICAgICAgIGlmIChwcmludFNlY3VyaXR5RGlmZihjdXJyZW50VGVtcGxhdGUsIHN0YWNrLCByZXF1aXJlQXBwcm92YWwpKSB7XG4gICAgICAgICAgYXdhaXQgYXNrVXNlckNvbmZpcm1hdGlvbihcbiAgICAgICAgICAgIHRoaXMuaW9Ib3N0LFxuICAgICAgICAgICAgY29uY3VycmVuY3ksXG4gICAgICAgICAgICAnXCItLXJlcXVpcmUtYXBwcm92YWxcIiBpcyBlbmFibGVkIGFuZCBzdGFjayBpbmNsdWRlcyBzZWN1cml0eS1zZW5zaXRpdmUgdXBkYXRlcycsXG4gICAgICAgICAgICAnRG8geW91IHdpc2ggdG8gZGVwbG95IHRoZXNlIGNoYW5nZXMnLFxuICAgICAgICAgICk7XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgLy8gRm9sbG93aW5nIGFyZSB0aGUgc2FtZSBzZW1hbnRpY3Mgd2UgYXBwbHkgd2l0aCByZXNwZWN0IHRvIE5vdGlmaWNhdGlvbiBBUk5zIChkaWN0YXRlZCBieSB0aGUgU0RLKVxuICAgICAgLy9cbiAgICAgIC8vICAtIHVuZGVmaW5lZCAgPT4gIGNkayBpZ25vcmVzIGl0LCBhcyBpZiBpdCB3YXNuJ3Qgc3VwcG9ydGVkIChhbGxvd3MgZXh0ZXJuYWwgbWFuYWdlbWVudCkuXG4gICAgICAvLyAgLSBbXTogICAgICAgID0+ICBjZGsgbWFuYWdlcyBpdCwgYW5kIHRoZSB1c2VyIHdhbnRzIHRvIHdpcGUgaXQgb3V0LlxuICAgICAgLy8gIC0gWydhcm4tMSddICA9PiAgY2RrIG1hbmFnZXMgaXQsIGFuZCB0aGUgdXNlciB3YW50cyB0byBzZXQgaXQgdG8gWydhcm4tMSddLlxuICAgICAgY29uc3Qgbm90aWZpY2F0aW9uQXJucyA9ICghIW9wdGlvbnMubm90aWZpY2F0aW9uQXJucyB8fCAhIXN0YWNrLm5vdGlmaWNhdGlvbkFybnMpXG4gICAgICAgID8gKG9wdGlvbnMubm90aWZpY2F0aW9uQXJucyA/PyBbXSkuY29uY2F0KHN0YWNrLm5vdGlmaWNhdGlvbkFybnMgPz8gW10pXG4gICAgICAgIDogdW5kZWZpbmVkO1xuXG4gICAgICBmb3IgKGNvbnN0IG5vdGlmaWNhdGlvbkFybiBvZiBub3RpZmljYXRpb25Bcm5zID8/IFtdKSB7XG4gICAgICAgIGlmICghdmFsaWRhdGVTbnNUb3BpY0Fybihub3RpZmljYXRpb25Bcm4pKSB7XG4gICAgICAgICAgdGhyb3cgbmV3IFRvb2xraXRFcnJvcihgTm90aWZpY2F0aW9uIGFybiAke25vdGlmaWNhdGlvbkFybn0gaXMgbm90IGEgdmFsaWQgYXJuIGZvciBhbiBTTlMgdG9waWNgKTtcbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICBjb25zdCBzdGFja0luZGV4ID0gc3RhY2tzLmluZGV4T2Yoc3RhY2spICsgMTtcbiAgICAgIGluZm8oYCR7Y2hhbGsuYm9sZChzdGFjay5kaXNwbGF5TmFtZSl9OiBkZXBsb3lpbmcuLi4gWyR7c3RhY2tJbmRleH0vJHtzdGFja0NvbGxlY3Rpb24uc3RhY2tDb3VudH1dYCk7XG4gICAgICBjb25zdCBzdGFydERlcGxveVRpbWUgPSBuZXcgRGF0ZSgpLmdldFRpbWUoKTtcblxuICAgICAgbGV0IHRhZ3MgPSBvcHRpb25zLnRhZ3M7XG4gICAgICBpZiAoIXRhZ3MgfHwgdGFncy5sZW5ndGggPT09IDApIHtcbiAgICAgICAgdGFncyA9IHRhZ3NGb3JTdGFjayhzdGFjayk7XG4gICAgICB9XG5cbiAgICAgIGxldCBlbGFwc2VkRGVwbG95VGltZSA9IDA7XG4gICAgICB0cnkge1xuICAgICAgICBsZXQgZGVwbG95UmVzdWx0OiBTdWNjZXNzZnVsRGVwbG95U3RhY2tSZXN1bHQgfCB1bmRlZmluZWQ7XG5cbiAgICAgICAgbGV0IHJvbGxiYWNrID0gb3B0aW9ucy5yb2xsYmFjaztcbiAgICAgICAgbGV0IGl0ZXJhdGlvbiA9IDA7XG4gICAgICAgIHdoaWxlICghZGVwbG95UmVzdWx0KSB7XG4gICAgICAgICAgaWYgKCsraXRlcmF0aW9uID4gMikge1xuICAgICAgICAgICAgdGhyb3cgbmV3IFRvb2xraXRFcnJvcignVGhpcyBsb29wIHNob3VsZCBoYXZlIHN0YWJpbGl6ZWQgaW4gMiBpdGVyYXRpb25zLCBidXQgZGlkblxcJ3QuIElmIHlvdSBhcmUgc2VlaW5nIHRoaXMgZXJyb3IsIHBsZWFzZSByZXBvcnQgaXQgYXQgaHR0cHM6Ly9naXRodWIuY29tL2F3cy9hd3MtY2RrL2lzc3Vlcy9uZXcvY2hvb3NlJyk7XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgY29uc3QgciA9IGF3YWl0IHRoaXMucHJvcHMuZGVwbG95bWVudHMuZGVwbG95U3RhY2soe1xuICAgICAgICAgICAgc3RhY2ssXG4gICAgICAgICAgICBkZXBsb3lOYW1lOiBzdGFjay5zdGFja05hbWUsXG4gICAgICAgICAgICByb2xlQXJuOiBvcHRpb25zLnJvbGVBcm4sXG4gICAgICAgICAgICB0b29sa2l0U3RhY2tOYW1lOiBvcHRpb25zLnRvb2xraXRTdGFja05hbWUsXG4gICAgICAgICAgICByZXVzZUFzc2V0czogb3B0aW9ucy5yZXVzZUFzc2V0cyxcbiAgICAgICAgICAgIG5vdGlmaWNhdGlvbkFybnMsXG4gICAgICAgICAgICB0YWdzLFxuICAgICAgICAgICAgZXhlY3V0ZTogb3B0aW9ucy5leGVjdXRlLFxuICAgICAgICAgICAgY2hhbmdlU2V0TmFtZTogb3B0aW9ucy5jaGFuZ2VTZXROYW1lLFxuICAgICAgICAgICAgZGVwbG95bWVudE1ldGhvZDogb3B0aW9ucy5kZXBsb3ltZW50TWV0aG9kLFxuICAgICAgICAgICAgZm9yY2U6IG9wdGlvbnMuZm9yY2UsXG4gICAgICAgICAgICBwYXJhbWV0ZXJzOiBPYmplY3QuYXNzaWduKHt9LCBwYXJhbWV0ZXJNYXBbJyonXSwgcGFyYW1ldGVyTWFwW3N0YWNrLnN0YWNrTmFtZV0pLFxuICAgICAgICAgICAgdXNlUHJldmlvdXNQYXJhbWV0ZXJzOiBvcHRpb25zLnVzZVByZXZpb3VzUGFyYW1ldGVycyxcbiAgICAgICAgICAgIHByb2dyZXNzLFxuICAgICAgICAgICAgY2k6IG9wdGlvbnMuY2ksXG4gICAgICAgICAgICByb2xsYmFjayxcbiAgICAgICAgICAgIGhvdHN3YXA6IG9wdGlvbnMuaG90c3dhcCxcbiAgICAgICAgICAgIGhvdHN3YXBQcm9wZXJ0eU92ZXJyaWRlczogaG90c3dhcFByb3BlcnR5T3ZlcnJpZGVzLFxuICAgICAgICAgICAgZXh0cmFVc2VyQWdlbnQ6IG9wdGlvbnMuZXh0cmFVc2VyQWdlbnQsXG4gICAgICAgICAgICBhc3NldFBhcmFsbGVsaXNtOiBvcHRpb25zLmFzc2V0UGFyYWxsZWxpc20sXG4gICAgICAgICAgICBpZ25vcmVOb1N0YWNrczogb3B0aW9ucy5pZ25vcmVOb1N0YWNrcyxcbiAgICAgICAgICB9KTtcblxuICAgICAgICAgIHN3aXRjaCAoci50eXBlKSB7XG4gICAgICAgICAgICBjYXNlICdkaWQtZGVwbG95LXN0YWNrJzpcbiAgICAgICAgICAgICAgZGVwbG95UmVzdWx0ID0gcjtcbiAgICAgICAgICAgICAgYnJlYWs7XG5cbiAgICAgICAgICAgIGNhc2UgJ2ZhaWxwYXVzZWQtbmVlZC1yb2xsYmFjay1maXJzdCc6IHtcbiAgICAgICAgICAgICAgY29uc3QgbW90aXZhdGlvbiA9IHIucmVhc29uID09PSAncmVwbGFjZW1lbnQnXG4gICAgICAgICAgICAgICAgPyBgU3RhY2sgaXMgaW4gYSBwYXVzZWQgZmFpbCBzdGF0ZSAoJHtyLnN0YXR1c30pIGFuZCBjaGFuZ2UgaW5jbHVkZXMgYSByZXBsYWNlbWVudCB3aGljaCBjYW5ub3QgYmUgZGVwbG95ZWQgd2l0aCBcIi0tbm8tcm9sbGJhY2tcImBcbiAgICAgICAgICAgICAgICA6IGBTdGFjayBpcyBpbiBhIHBhdXNlZCBmYWlsIHN0YXRlICgke3Iuc3RhdHVzfSkgYW5kIGNvbW1hbmQgbGluZSBhcmd1bWVudHMgZG8gbm90IGluY2x1ZGUgXCItLW5vLXJvbGxiYWNrXCJgO1xuXG4gICAgICAgICAgICAgIGlmIChvcHRpb25zLmZvcmNlKSB7XG4gICAgICAgICAgICAgICAgd2FybmluZyhgJHttb3RpdmF0aW9ufS4gUm9sbGluZyBiYWNrIGZpcnN0ICgtLWZvcmNlKS5gKTtcbiAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICBhd2FpdCBhc2tVc2VyQ29uZmlybWF0aW9uKFxuICAgICAgICAgICAgICAgICAgdGhpcy5pb0hvc3QsXG4gICAgICAgICAgICAgICAgICBjb25jdXJyZW5jeSxcbiAgICAgICAgICAgICAgICAgIG1vdGl2YXRpb24sXG4gICAgICAgICAgICAgICAgICBgJHttb3RpdmF0aW9ufS4gUm9sbCBiYWNrIGZpcnN0IGFuZCB0aGVuIHByb2NlZWQgd2l0aCBkZXBsb3ltZW50YCxcbiAgICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgLy8gUGVyZm9ybSBhIHJvbGxiYWNrXG4gICAgICAgICAgICAgIGF3YWl0IHRoaXMucm9sbGJhY2soe1xuICAgICAgICAgICAgICAgIHNlbGVjdG9yOiB7IHBhdHRlcm5zOiBbc3RhY2suaGllcmFyY2hpY2FsSWRdIH0sXG4gICAgICAgICAgICAgICAgdG9vbGtpdFN0YWNrTmFtZTogb3B0aW9ucy50b29sa2l0U3RhY2tOYW1lLFxuICAgICAgICAgICAgICAgIGZvcmNlOiBvcHRpb25zLmZvcmNlLFxuICAgICAgICAgICAgICB9KTtcblxuICAgICAgICAgICAgICAvLyBHbyBhcm91bmQgdGhyb3VnaCB0aGUgJ3doaWxlJyBsb29wIGFnYWluIGJ1dCBzd2l0Y2ggcm9sbGJhY2sgdG8gdHJ1ZS5cbiAgICAgICAgICAgICAgcm9sbGJhY2sgPSB0cnVlO1xuICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgY2FzZSAncmVwbGFjZW1lbnQtcmVxdWlyZXMtcm9sbGJhY2snOiB7XG4gICAgICAgICAgICAgIGNvbnN0IG1vdGl2YXRpb24gPSAnQ2hhbmdlIGluY2x1ZGVzIGEgcmVwbGFjZW1lbnQgd2hpY2ggY2Fubm90IGJlIGRlcGxveWVkIHdpdGggXCItLW5vLXJvbGxiYWNrXCInO1xuXG4gICAgICAgICAgICAgIGlmIChvcHRpb25zLmZvcmNlKSB7XG4gICAgICAgICAgICAgICAgd2FybmluZyhgJHttb3RpdmF0aW9ufS4gUHJvY2VlZGluZyB3aXRoIHJlZ3VsYXIgZGVwbG95bWVudCAoLS1mb3JjZSkuYCk7XG4gICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgYXdhaXQgYXNrVXNlckNvbmZpcm1hdGlvbihcbiAgICAgICAgICAgICAgICAgIHRoaXMuaW9Ib3N0LFxuICAgICAgICAgICAgICAgICAgY29uY3VycmVuY3ksXG4gICAgICAgICAgICAgICAgICBtb3RpdmF0aW9uLFxuICAgICAgICAgICAgICAgICAgYCR7bW90aXZhdGlvbn0uIFBlcmZvcm0gYSByZWd1bGFyIGRlcGxveW1lbnRgLFxuICAgICAgICAgICAgICAgICk7XG4gICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAvLyBHbyBhcm91bmQgdGhyb3VnaCB0aGUgJ3doaWxlJyBsb29wIGFnYWluIGJ1dCBzd2l0Y2ggcm9sbGJhY2sgdG8gdHJ1ZS5cbiAgICAgICAgICAgICAgcm9sbGJhY2sgPSB0cnVlO1xuICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgZGVmYXVsdDpcbiAgICAgICAgICAgICAgdGhyb3cgbmV3IFRvb2xraXRFcnJvcihgVW5leHBlY3RlZCByZXN1bHQgdHlwZSBmcm9tIGRlcGxveVN0YWNrOiAke0pTT04uc3RyaW5naWZ5KHIpfS4gSWYgeW91IGFyZSBzZWVpbmcgdGhpcyBlcnJvciwgcGxlYXNlIHJlcG9ydCBpdCBhdCBodHRwczovL2dpdGh1Yi5jb20vYXdzL2F3cy1jZGsvaXNzdWVzL25ldy9jaG9vc2VgKTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICBjb25zdCBtZXNzYWdlID0gZGVwbG95UmVzdWx0Lm5vT3BcbiAgICAgICAgICA/ICcg4pyFICAlcyAobm8gY2hhbmdlcyknXG4gICAgICAgICAgOiAnIOKchSAgJXMnO1xuXG4gICAgICAgIHN1Y2Nlc3MoJ1xcbicgKyBtZXNzYWdlLCBzdGFjay5kaXNwbGF5TmFtZSk7XG4gICAgICAgIGVsYXBzZWREZXBsb3lUaW1lID0gbmV3IERhdGUoKS5nZXRUaW1lKCkgLSBzdGFydERlcGxveVRpbWU7XG4gICAgICAgIGluZm8oYFxcbuKcqCAgRGVwbG95bWVudCB0aW1lOiAke2Zvcm1hdFRpbWUoZWxhcHNlZERlcGxveVRpbWUpfXNcXG5gKTtcblxuICAgICAgICBpZiAoT2JqZWN0LmtleXMoZGVwbG95UmVzdWx0Lm91dHB1dHMpLmxlbmd0aCA+IDApIHtcbiAgICAgICAgICBpbmZvKCdPdXRwdXRzOicpO1xuXG4gICAgICAgICAgc3RhY2tPdXRwdXRzW3N0YWNrLnN0YWNrTmFtZV0gPSBkZXBsb3lSZXN1bHQub3V0cHV0cztcbiAgICAgICAgfVxuXG4gICAgICAgIGZvciAoY29uc3QgbmFtZSBvZiBPYmplY3Qua2V5cyhkZXBsb3lSZXN1bHQub3V0cHV0cykuc29ydCgpKSB7XG4gICAgICAgICAgY29uc3QgdmFsdWUgPSBkZXBsb3lSZXN1bHQub3V0cHV0c1tuYW1lXTtcbiAgICAgICAgICBpbmZvKGAke2NoYWxrLmN5YW4oc3RhY2suaWQpfS4ke2NoYWxrLmN5YW4obmFtZSl9ID0gJHtjaGFsay51bmRlcmxpbmUoY2hhbGsuY3lhbih2YWx1ZSkpfWApO1xuICAgICAgICB9XG5cbiAgICAgICAgaW5mbygnU3RhY2sgQVJOOicpO1xuXG4gICAgICAgIGxvZ1Jlc3VsdChkZXBsb3lSZXN1bHQuc3RhY2tBcm4pO1xuICAgICAgfSBjYXRjaCAoZTogYW55KSB7XG4gICAgICAgIC8vIEl0IGhhcyB0byBiZSBleGFjdGx5IHRoaXMgc3RyaW5nIGJlY2F1c2UgYW4gaW50ZWdyYXRpb24gdGVzdCB0ZXN0cyBmb3JcbiAgICAgICAgLy8gXCJib2xkKHN0YWNrbmFtZSkgZmFpbGVkOiBSZXNvdXJjZU5vdFJlYWR5OiA8ZXJyb3I+XCJcbiAgICAgICAgdGhyb3cgbmV3IFRvb2xraXRFcnJvcihcbiAgICAgICAgICBbYOKdjCAgJHtjaGFsay5ib2xkKHN0YWNrLnN0YWNrTmFtZSl9IGZhaWxlZDpgLCAuLi4oZS5uYW1lID8gW2Ake2UubmFtZX06YF0gOiBbXSksIGZvcm1hdEVycm9yTWVzc2FnZShlKV0uam9pbignICcpLFxuICAgICAgICApO1xuICAgICAgfSBmaW5hbGx5IHtcbiAgICAgICAgaWYgKG9wdGlvbnMuY2xvdWRXYXRjaExvZ01vbml0b3IpIHtcbiAgICAgICAgICBjb25zdCBmb3VuZExvZ0dyb3Vwc1Jlc3VsdCA9IGF3YWl0IGZpbmRDbG91ZFdhdGNoTG9nR3JvdXBzKHRoaXMucHJvcHMuc2RrUHJvdmlkZXIsIHN0YWNrKTtcbiAgICAgICAgICBvcHRpb25zLmNsb3VkV2F0Y2hMb2dNb25pdG9yLmFkZExvZ0dyb3VwcyhcbiAgICAgICAgICAgIGZvdW5kTG9nR3JvdXBzUmVzdWx0LmVudixcbiAgICAgICAgICAgIGZvdW5kTG9nR3JvdXBzUmVzdWx0LnNkayxcbiAgICAgICAgICAgIGZvdW5kTG9nR3JvdXBzUmVzdWx0LmxvZ0dyb3VwTmFtZXMsXG4gICAgICAgICAgKTtcbiAgICAgICAgfVxuICAgICAgICAvLyBJZiBhbiBvdXRwdXRzIGZpbGUgaGFzIGJlZW4gc3BlY2lmaWVkLCBjcmVhdGUgdGhlIGZpbGUgcGF0aCBhbmQgd3JpdGUgc3RhY2sgb3V0cHV0cyB0byBpdCBvbmNlLlxuICAgICAgICAvLyBPdXRwdXRzIGFyZSB3cml0dGVuIGFmdGVyIGFsbCBzdGFja3MgaGF2ZSBiZWVuIGRlcGxveWVkLiBJZiBhIHN0YWNrIGRlcGxveW1lbnQgZmFpbHMsXG4gICAgICAgIC8vIGFsbCBvZiB0aGUgb3V0cHV0cyBmcm9tIHN1Y2Nlc3NmdWxseSBkZXBsb3llZCBzdGFja3MgYmVmb3JlIHRoZSBmYWlsdXJlIHdpbGwgc3RpbGwgYmUgd3JpdHRlbi5cbiAgICAgICAgaWYgKG91dHB1dHNGaWxlKSB7XG4gICAgICAgICAgZnMuZW5zdXJlRmlsZVN5bmMob3V0cHV0c0ZpbGUpO1xuICAgICAgICAgIGF3YWl0IGZzLndyaXRlSnNvbihvdXRwdXRzRmlsZSwgc3RhY2tPdXRwdXRzLCB7XG4gICAgICAgICAgICBzcGFjZXM6IDIsXG4gICAgICAgICAgICBlbmNvZGluZzogJ3V0ZjgnLFxuICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICBpbmZvKGBcXG7inKggIFRvdGFsIHRpbWU6ICR7Zm9ybWF0VGltZShlbGFwc2VkU3ludGhUaW1lICsgZWxhcHNlZERlcGxveVRpbWUpfXNcXG5gKTtcbiAgICB9O1xuXG4gICAgY29uc3QgYXNzZXRCdWlsZFRpbWUgPSBvcHRpb25zLmFzc2V0QnVpbGRUaW1lID8/IEFzc2V0QnVpbGRUaW1lLkFMTF9CRUZPUkVfREVQTE9ZO1xuICAgIGNvbnN0IHByZWJ1aWxkQXNzZXRzID0gYXNzZXRCdWlsZFRpbWUgPT09IEFzc2V0QnVpbGRUaW1lLkFMTF9CRUZPUkVfREVQTE9ZO1xuICAgIGNvbnN0IGNvbmN1cnJlbmN5ID0gb3B0aW9ucy5jb25jdXJyZW5jeSB8fCAxO1xuICAgIGNvbnN0IHByb2dyZXNzID0gY29uY3VycmVuY3kgPiAxID8gU3RhY2tBY3Rpdml0eVByb2dyZXNzLkVWRU5UUyA6IG9wdGlvbnMucHJvZ3Jlc3M7XG4gICAgaWYgKGNvbmN1cnJlbmN5ID4gMSAmJiBvcHRpb25zLnByb2dyZXNzICYmIG9wdGlvbnMucHJvZ3Jlc3MgIT0gU3RhY2tBY3Rpdml0eVByb2dyZXNzLkVWRU5UUykge1xuICAgICAgd2FybmluZygn4pqg77iPIFRoZSAtLWNvbmN1cnJlbmN5IGZsYWcgb25seSBzdXBwb3J0cyAtLXByb2dyZXNzIFwiZXZlbnRzXCIuIFN3aXRjaGluZyB0byBcImV2ZW50c1wiLicpO1xuICAgIH1cblxuICAgIGNvbnN0IHN0YWNrc0FuZFRoZWlyQXNzZXRNYW5pZmVzdHMgPSBzdGFja3MuZmxhdE1hcCgoc3RhY2spID0+IFtcbiAgICAgIHN0YWNrLFxuICAgICAgLi4uc3RhY2suZGVwZW5kZW5jaWVzLmZpbHRlcihjeGFwaS5Bc3NldE1hbmlmZXN0QXJ0aWZhY3QuaXNBc3NldE1hbmlmZXN0QXJ0aWZhY3QpLFxuICAgIF0pO1xuICAgIGNvbnN0IHdvcmtHcmFwaCA9IG5ldyBXb3JrR3JhcGhCdWlsZGVyKHByZWJ1aWxkQXNzZXRzKS5idWlsZChzdGFja3NBbmRUaGVpckFzc2V0TWFuaWZlc3RzKTtcblxuICAgIC8vIFVubGVzcyB3ZSBhcmUgcnVubmluZyB3aXRoICctLWZvcmNlJywgc2tpcCBhbHJlYWR5IHB1Ymxpc2hlZCBhc3NldHNcbiAgICBpZiAoIW9wdGlvbnMuZm9yY2UpIHtcbiAgICAgIGF3YWl0IHRoaXMucmVtb3ZlUHVibGlzaGVkQXNzZXRzKHdvcmtHcmFwaCwgb3B0aW9ucyk7XG4gICAgfVxuXG4gICAgY29uc3QgZ3JhcGhDb25jdXJyZW5jeTogQ29uY3VycmVuY3kgPSB7XG4gICAgICAnc3RhY2snOiBjb25jdXJyZW5jeSxcbiAgICAgICdhc3NldC1idWlsZCc6IDEsIC8vIFRoaXMgd2lsbCBiZSBDUFUtYm91bmQvbWVtb3J5IGJvdW5kLCBtb3N0bHkgbWF0dGVycyBmb3IgRG9ja2VyIGJ1aWxkc1xuICAgICAgJ2Fzc2V0LXB1Ymxpc2gnOiAob3B0aW9ucy5hc3NldFBhcmFsbGVsaXNtID8/IHRydWUpID8gOCA6IDEsIC8vIFRoaXMgd2lsbCBiZSBJL08tYm91bmQsIDggaW4gcGFyYWxsZWwgc2VlbXMgcmVhc29uYWJsZVxuICAgIH07XG5cbiAgICBhd2FpdCB3b3JrR3JhcGguZG9QYXJhbGxlbChncmFwaENvbmN1cnJlbmN5LCB7XG4gICAgICBkZXBsb3lTdGFjayxcbiAgICAgIGJ1aWxkQXNzZXQsXG4gICAgICBwdWJsaXNoQXNzZXQsXG4gICAgfSk7XG4gIH1cblxuICAvKipcbiAgICogUm9sbCBiYWNrIHRoZSBnaXZlbiBzdGFjayBvciBzdGFja3MuXG4gICAqL1xuICBwdWJsaWMgYXN5bmMgcm9sbGJhY2sob3B0aW9uczogUm9sbGJhY2tPcHRpb25zKSB7XG4gICAgY29uc3Qgc3RhcnRTeW50aFRpbWUgPSBuZXcgRGF0ZSgpLmdldFRpbWUoKTtcbiAgICBjb25zdCBzdGFja0NvbGxlY3Rpb24gPSBhd2FpdCB0aGlzLnNlbGVjdFN0YWNrc0ZvckRlcGxveShvcHRpb25zLnNlbGVjdG9yLCB0cnVlKTtcbiAgICBjb25zdCBlbGFwc2VkU3ludGhUaW1lID0gbmV3IERhdGUoKS5nZXRUaW1lKCkgLSBzdGFydFN5bnRoVGltZTtcbiAgICBpbmZvKGBcXG7inKggIFN5bnRoZXNpcyB0aW1lOiAke2Zvcm1hdFRpbWUoZWxhcHNlZFN5bnRoVGltZSl9c1xcbmApO1xuXG4gICAgaWYgKHN0YWNrQ29sbGVjdGlvbi5zdGFja0NvdW50ID09PSAwKSB7XG4gICAgICBlcnJvcignTm8gc3RhY2tzIHNlbGVjdGVkJyk7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgbGV0IGFueVJvbGxiYWNrYWJsZSA9IGZhbHNlO1xuXG4gICAgZm9yIChjb25zdCBzdGFjayBvZiBzdGFja0NvbGxlY3Rpb24uc3RhY2tBcnRpZmFjdHMpIHtcbiAgICAgIGluZm8oJ1JvbGxpbmcgYmFjayAlcycsIGNoYWxrLmJvbGQoc3RhY2suZGlzcGxheU5hbWUpKTtcbiAgICAgIGNvbnN0IHN0YXJ0Um9sbGJhY2tUaW1lID0gbmV3IERhdGUoKS5nZXRUaW1lKCk7XG4gICAgICB0cnkge1xuICAgICAgICBjb25zdCByZXN1bHQgPSBhd2FpdCB0aGlzLnByb3BzLmRlcGxveW1lbnRzLnJvbGxiYWNrU3RhY2soe1xuICAgICAgICAgIHN0YWNrLFxuICAgICAgICAgIHJvbGVBcm46IG9wdGlvbnMucm9sZUFybixcbiAgICAgICAgICB0b29sa2l0U3RhY2tOYW1lOiBvcHRpb25zLnRvb2xraXRTdGFja05hbWUsXG4gICAgICAgICAgZm9yY2U6IG9wdGlvbnMuZm9yY2UsXG4gICAgICAgICAgdmFsaWRhdGVCb290c3RyYXBTdGFja1ZlcnNpb246IG9wdGlvbnMudmFsaWRhdGVCb290c3RyYXBTdGFja1ZlcnNpb24sXG4gICAgICAgICAgb3JwaGFuTG9naWNhbElkczogb3B0aW9ucy5vcnBoYW5Mb2dpY2FsSWRzLFxuICAgICAgICB9KTtcbiAgICAgICAgaWYgKCFyZXN1bHQubm90SW5Sb2xsYmFja2FibGVTdGF0ZSkge1xuICAgICAgICAgIGFueVJvbGxiYWNrYWJsZSA9IHRydWU7XG4gICAgICAgIH1cbiAgICAgICAgY29uc3QgZWxhcHNlZFJvbGxiYWNrVGltZSA9IG5ldyBEYXRlKCkuZ2V0VGltZSgpIC0gc3RhcnRSb2xsYmFja1RpbWU7XG4gICAgICAgIGluZm8oYFxcbuKcqCAgUm9sbGJhY2sgdGltZTogJHtmb3JtYXRUaW1lKGVsYXBzZWRSb2xsYmFja1RpbWUpLnRvU3RyaW5nKCl9c1xcbmApO1xuICAgICAgfSBjYXRjaCAoZTogYW55KSB7XG4gICAgICAgIGVycm9yKCdcXG4g4p2MICAlcyBmYWlsZWQ6ICVzJywgY2hhbGsuYm9sZChzdGFjay5kaXNwbGF5TmFtZSksIGZvcm1hdEVycm9yTWVzc2FnZShlKSk7XG4gICAgICAgIHRocm93IG5ldyBUb29sa2l0RXJyb3IoJ1JvbGxiYWNrIGZhaWxlZCAodXNlIC0tZm9yY2UgdG8gb3JwaGFuIGZhaWxpbmcgcmVzb3VyY2VzKScpO1xuICAgICAgfVxuICAgIH1cbiAgICBpZiAoIWFueVJvbGxiYWNrYWJsZSkge1xuICAgICAgdGhyb3cgbmV3IFRvb2xraXRFcnJvcignTm8gc3RhY2tzIHdlcmUgaW4gYSBzdGF0ZSB0aGF0IGNvdWxkIGJlIHJvbGxlZCBiYWNrJyk7XG4gICAgfVxuICB9XG5cbiAgcHVibGljIGFzeW5jIHdhdGNoKG9wdGlvbnM6IFdhdGNoT3B0aW9ucykge1xuICAgIGNvbnN0IHJvb3REaXIgPSBwYXRoLmRpcm5hbWUocGF0aC5yZXNvbHZlKFBST0pFQ1RfQ09ORklHKSk7XG4gICAgZGVidWcoXCJyb290IGRpcmVjdG9yeSB1c2VkIGZvciAnd2F0Y2gnIGlzOiAlc1wiLCByb290RGlyKTtcblxuICAgIGNvbnN0IHdhdGNoU2V0dGluZ3M6IHsgaW5jbHVkZT86IHN0cmluZyB8IHN0cmluZ1tdOyBleGNsdWRlOiBzdHJpbmcgfCBzdHJpbmdbXSB9IHwgdW5kZWZpbmVkID1cbiAgICAgIHRoaXMucHJvcHMuY29uZmlndXJhdGlvbi5zZXR0aW5ncy5nZXQoWyd3YXRjaCddKTtcbiAgICBpZiAoIXdhdGNoU2V0dGluZ3MpIHtcbiAgICAgIHRocm93IG5ldyBUb29sa2l0RXJyb3IoXG4gICAgICAgIFwiQ2Fubm90IHVzZSB0aGUgJ3dhdGNoJyBjb21tYW5kIHdpdGhvdXQgc3BlY2lmeWluZyBhdCBsZWFzdCBvbmUgZGlyZWN0b3J5IHRvIG1vbml0b3IuIFwiICtcbiAgICAgICAgICAnTWFrZSBzdXJlIHRvIGFkZCBhIFwid2F0Y2hcIiBrZXkgdG8geW91ciBjZGsuanNvbicsXG4gICAgICApO1xuICAgIH1cblxuICAgIC8vIEZvciB0aGUgXCJpbmNsdWRlXCIgc3Via2V5IHVuZGVyIHRoZSBcIndhdGNoXCIga2V5LCB0aGUgYmVoYXZpb3IgaXM6XG4gICAgLy8gMS4gTm8gXCJ3YXRjaFwiIHNldHRpbmc/IFdlIGVycm9yIG91dC5cbiAgICAvLyAyLiBcIndhdGNoXCIgc2V0dGluZyB3aXRob3V0IGFuIFwiaW5jbHVkZVwiIGtleT8gV2UgZGVmYXVsdCB0byBvYnNlcnZpbmcgXCIuLyoqXCIuXG4gICAgLy8gMy4gXCJ3YXRjaFwiIHNldHRpbmcgd2l0aCBhbiBlbXB0eSBcImluY2x1ZGVcIiBrZXk/IFdlIGRlZmF1bHQgdG8gb2JzZXJ2aW5nIFwiLi8qKlwiLlxuICAgIC8vIDQuIE5vbi1lbXB0eSBcImluY2x1ZGVcIiBrZXk/IEp1c3QgdXNlIHRoZSBcImluY2x1ZGVcIiBrZXkuXG4gICAgY29uc3Qgd2F0Y2hJbmNsdWRlcyA9IHRoaXMucGF0dGVybnNBcnJheUZvcldhdGNoKHdhdGNoU2V0dGluZ3MuaW5jbHVkZSwge1xuICAgICAgcm9vdERpcixcbiAgICAgIHJldHVyblJvb3REaXJJZkVtcHR5OiB0cnVlLFxuICAgIH0pO1xuICAgIGRlYnVnKFwiJ2luY2x1ZGUnIHBhdHRlcm5zIGZvciAnd2F0Y2gnOiAlc1wiLCB3YXRjaEluY2x1ZGVzKTtcblxuICAgIC8vIEZvciB0aGUgXCJleGNsdWRlXCIgc3Via2V5IHVuZGVyIHRoZSBcIndhdGNoXCIga2V5LFxuICAgIC8vIHRoZSBiZWhhdmlvciBpcyB0byBhZGQgc29tZSBkZWZhdWx0IGV4Y2x1ZGVzIGluIGFkZGl0aW9uIHRvIHRoZSBvbmVzIHNwZWNpZmllZCBieSB0aGUgdXNlcjpcbiAgICAvLyAxLiBUaGUgQ0RLIG91dHB1dCBkaXJlY3RvcnkuXG4gICAgLy8gMi4gQW55IGZpbGUgd2hvc2UgbmFtZSBzdGFydHMgd2l0aCBhIGRvdC5cbiAgICAvLyAzLiBBbnkgZGlyZWN0b3J5J3MgY29udGVudCB3aG9zZSBuYW1lIHN0YXJ0cyB3aXRoIGEgZG90LlxuICAgIC8vIDQuIEFueSBub2RlX21vZHVsZXMgYW5kIGl0cyBjb250ZW50IChldmVuIGlmIGl0J3Mgbm90IGEgSlMvVFMgcHJvamVjdCwgeW91IG1pZ2h0IGJlIHVzaW5nIGEgbG9jYWwgYXdzLWNsaSBwYWNrYWdlKVxuICAgIGNvbnN0IG91dHB1dERpciA9IHRoaXMucHJvcHMuY29uZmlndXJhdGlvbi5zZXR0aW5ncy5nZXQoWydvdXRwdXQnXSk7XG4gICAgY29uc3Qgd2F0Y2hFeGNsdWRlcyA9IHRoaXMucGF0dGVybnNBcnJheUZvcldhdGNoKHdhdGNoU2V0dGluZ3MuZXhjbHVkZSwge1xuICAgICAgcm9vdERpcixcbiAgICAgIHJldHVyblJvb3REaXJJZkVtcHR5OiBmYWxzZSxcbiAgICB9KS5jb25jYXQoYCR7b3V0cHV0RGlyfS8qKmAsICcqKi8uKicsICcqKi8uKi8qKicsICcqKi9ub2RlX21vZHVsZXMvKionKTtcbiAgICBkZWJ1ZyhcIidleGNsdWRlJyBwYXR0ZXJucyBmb3IgJ3dhdGNoJzogJXNcIiwgd2F0Y2hFeGNsdWRlcyk7XG5cbiAgICAvLyBTaW5jZSAnY2RrIGRlcGxveScgaXMgYSByZWxhdGl2ZWx5IHNsb3cgb3BlcmF0aW9uIGZvciBhICd3YXRjaCcgcHJvY2VzcyxcbiAgICAvLyBpbnRyb2R1Y2UgYSBjb25jdXJyZW5jeSBsYXRjaCB0aGF0IHRyYWNrcyB0aGUgc3RhdGUuXG4gICAgLy8gVGhpcyB3YXksIGlmIGZpbGUgY2hhbmdlIGV2ZW50cyBhcnJpdmUgd2hlbiBhICdjZGsgZGVwbG95JyBpcyBzdGlsbCBleGVjdXRpbmcsXG4gICAgLy8gd2Ugd2lsbCBiYXRjaCB0aGVtLCBhbmQgdHJpZ2dlciBhbm90aGVyICdjZGsgZGVwbG95JyBhZnRlciB0aGUgY3VycmVudCBvbmUgZmluaXNoZXMsXG4gICAgLy8gbWFraW5nIHN1cmUgJ2NkayBkZXBsb3kncyAgYWx3YXlzIGV4ZWN1dGUgb25lIGF0IGEgdGltZS5cbiAgICAvLyBIZXJlJ3MgYSBkaWFncmFtIHNob3dpbmcgdGhlIHN0YXRlIHRyYW5zaXRpb25zOlxuICAgIC8vIC0tLS0tLS0tLS0tLS0tICAgICAgICAgICAgICAgIC0tLS0tLS0tICAgIGZpbGUgY2hhbmdlZCAgICAgLS0tLS0tLS0tLS0tLS0gICAgZmlsZSBjaGFuZ2VkICAgICAtLS0tLS0tLS0tLS0tLSAgZmlsZSBjaGFuZ2VkXG4gICAgLy8gfCAgICAgICAgICAgIHwgIHJlYWR5IGV2ZW50ICAgfCAgICAgIHwgLS0tLS0tLS0tLS0tLS0tLS0tPiB8ICAgICAgICAgICAgfCAtLS0tLS0tLS0tLS0tLS0tLS0+IHwgICAgICAgICAgICB8IC0tLS0tLS0tLS0tLS0tfFxuICAgIC8vIHwgcHJlLXJlYWR5ICB8IC0tLS0tLS0tLS0tLS0+IHwgb3BlbiB8ICAgICAgICAgICAgICAgICAgICAgfCBkZXBsb3lpbmcgIHwgICAgICAgICAgICAgICAgICAgICB8ICAgcXVldWVkICAgfCAgICAgICAgICAgICAgIHxcbiAgICAvLyB8ICAgICAgICAgICAgfCAgICAgICAgICAgICAgICB8ICAgICAgfCA8LS0tLS0tLS0tLS0tLS0tLS0tIHwgICAgICAgICAgICB8IDwtLS0tLS0tLS0tLS0tLS0tLS0gfCAgICAgICAgICAgIHwgPC0tLS0tLS0tLS0tLS18XG4gICAgLy8gLS0tLS0tLS0tLS0tLS0gICAgICAgICAgICAgICAgLS0tLS0tLS0gICdjZGsgZGVwbG95JyBkb25lICAtLS0tLS0tLS0tLS0tLSAgJ2NkayBkZXBsb3knIGRvbmUgIC0tLS0tLS0tLS0tLS0tXG4gICAgbGV0IGxhdGNoOiAncHJlLXJlYWR5JyB8ICdvcGVuJyB8ICdkZXBsb3lpbmcnIHwgJ3F1ZXVlZCcgPSAncHJlLXJlYWR5JztcblxuICAgIGNvbnN0IGNsb3VkV2F0Y2hMb2dNb25pdG9yID0gb3B0aW9ucy50cmFjZUxvZ3MgPyBuZXcgQ2xvdWRXYXRjaExvZ0V2ZW50TW9uaXRvcigpIDogdW5kZWZpbmVkO1xuICAgIGNvbnN0IGRlcGxveUFuZFdhdGNoID0gYXN5bmMgKCkgPT4ge1xuICAgICAgbGF0Y2ggPSAnZGVwbG95aW5nJztcbiAgICAgIGNsb3VkV2F0Y2hMb2dNb25pdG9yPy5kZWFjdGl2YXRlKCk7XG5cbiAgICAgIGF3YWl0IHRoaXMuaW52b2tlRGVwbG95RnJvbVdhdGNoKG9wdGlvbnMsIGNsb3VkV2F0Y2hMb2dNb25pdG9yKTtcblxuICAgICAgLy8gSWYgbGF0Y2ggaXMgc3RpbGwgJ2RlcGxveWluZycgYWZ0ZXIgdGhlICdhd2FpdCcsIHRoYXQncyBmaW5lLFxuICAgICAgLy8gYnV0IGlmIGl0J3MgJ3F1ZXVlZCcsIHRoYXQgbWVhbnMgd2UgbmVlZCB0byBkZXBsb3kgYWdhaW5cbiAgICAgIHdoaWxlICgobGF0Y2ggYXMgJ2RlcGxveWluZycgfCAncXVldWVkJykgPT09ICdxdWV1ZWQnKSB7XG4gICAgICAgIC8vIFR5cGVTY3JpcHQgZG9lc24ndCByZWFsaXplIGxhdGNoIGNhbiBjaGFuZ2UgYmV0d2VlbiAnYXdhaXRzJyxcbiAgICAgICAgLy8gYW5kIHRoaW5rcyB0aGUgYWJvdmUgJ3doaWxlJyBjb25kaXRpb24gaXMgYWx3YXlzICdmYWxzZScgd2l0aG91dCB0aGUgY2FzdFxuICAgICAgICBsYXRjaCA9ICdkZXBsb3lpbmcnO1xuICAgICAgICBpbmZvKFwiRGV0ZWN0ZWQgZmlsZSBjaGFuZ2VzIGR1cmluZyBkZXBsb3ltZW50LiBJbnZva2luZyAnY2RrIGRlcGxveScgYWdhaW5cIik7XG4gICAgICAgIGF3YWl0IHRoaXMuaW52b2tlRGVwbG95RnJvbVdhdGNoKG9wdGlvbnMsIGNsb3VkV2F0Y2hMb2dNb25pdG9yKTtcbiAgICAgIH1cbiAgICAgIGxhdGNoID0gJ29wZW4nO1xuICAgICAgY2xvdWRXYXRjaExvZ01vbml0b3I/LmFjdGl2YXRlKCk7XG4gICAgfTtcblxuICAgIGNob2tpZGFyXG4gICAgICAud2F0Y2god2F0Y2hJbmNsdWRlcywge1xuICAgICAgICBpZ25vcmVkOiB3YXRjaEV4Y2x1ZGVzLFxuICAgICAgICBjd2Q6IHJvb3REaXIsXG4gICAgICB9KVxuICAgICAgLm9uKCdyZWFkeScsIGFzeW5jICgpID0+IHtcbiAgICAgICAgbGF0Y2ggPSAnb3Blbic7XG4gICAgICAgIGRlYnVnKFwiJ3dhdGNoJyByZWNlaXZlZCB0aGUgJ3JlYWR5JyBldmVudC4gRnJvbSBub3cgb24sIGFsbCBmaWxlIGNoYW5nZXMgd2lsbCB0cmlnZ2VyIGEgZGVwbG95bWVudFwiKTtcbiAgICAgICAgaW5mbyhcIlRyaWdnZXJpbmcgaW5pdGlhbCAnY2RrIGRlcGxveSdcIik7XG4gICAgICAgIGF3YWl0IGRlcGxveUFuZFdhdGNoKCk7XG4gICAgICB9KVxuICAgICAgLm9uKCdhbGwnLCBhc3luYyAoZXZlbnQ6ICdhZGQnIHwgJ2FkZERpcicgfCAnY2hhbmdlJyB8ICd1bmxpbmsnIHwgJ3VubGlua0RpcicsIGZpbGVQYXRoPzogc3RyaW5nKSA9PiB7XG4gICAgICAgIGlmIChsYXRjaCA9PT0gJ3ByZS1yZWFkeScpIHtcbiAgICAgICAgICBpbmZvKGAnd2F0Y2gnIGlzIG9ic2VydmluZyAke2V2ZW50ID09PSAnYWRkRGlyJyA/ICdkaXJlY3RvcnknIDogJ3RoZSBmaWxlJ30gJyVzJyBmb3IgY2hhbmdlc2AsIGZpbGVQYXRoKTtcbiAgICAgICAgfSBlbHNlIGlmIChsYXRjaCA9PT0gJ29wZW4nKSB7XG4gICAgICAgICAgaW5mbyhcIkRldGVjdGVkIGNoYW5nZSB0byAnJXMnICh0eXBlOiAlcykuIFRyaWdnZXJpbmcgJ2NkayBkZXBsb3knXCIsIGZpbGVQYXRoLCBldmVudCk7XG4gICAgICAgICAgYXdhaXQgZGVwbG95QW5kV2F0Y2goKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAvLyB0aGlzIG1lYW5zIGxhdGNoIGlzIGVpdGhlciAnZGVwbG95aW5nJyBvciAncXVldWVkJ1xuICAgICAgICAgIGxhdGNoID0gJ3F1ZXVlZCc7XG4gICAgICAgICAgaW5mbyhcbiAgICAgICAgICAgIFwiRGV0ZWN0ZWQgY2hhbmdlIHRvICclcycgKHR5cGU6ICVzKSB3aGlsZSAnY2RrIGRlcGxveScgaXMgc3RpbGwgcnVubmluZy4gXCIgK1xuICAgICAgICAgICAgICAnV2lsbCBxdWV1ZSBmb3IgYW5vdGhlciBkZXBsb3ltZW50IGFmdGVyIHRoaXMgb25lIGZpbmlzaGVzJyxcbiAgICAgICAgICAgIGZpbGVQYXRoLFxuICAgICAgICAgICAgZXZlbnQsXG4gICAgICAgICAgKTtcbiAgICAgICAgfVxuICAgICAgfSk7XG4gIH1cblxuICBwdWJsaWMgYXN5bmMgaW1wb3J0KG9wdGlvbnM6IEltcG9ydE9wdGlvbnMpIHtcbiAgICBjb25zdCBzdGFja3MgPSBhd2FpdCB0aGlzLnNlbGVjdFN0YWNrc0ZvckRlcGxveShvcHRpb25zLnNlbGVjdG9yLCB0cnVlLCB0cnVlLCBmYWxzZSk7XG5cbiAgICBpZiAoc3RhY2tzLnN0YWNrQ291bnQgPiAxKSB7XG4gICAgICB0aHJvdyBuZXcgVG9vbGtpdEVycm9yKFxuICAgICAgICBgU3RhY2sgc2VsZWN0aW9uIGlzIGFtYmlndW91cywgcGxlYXNlIGNob29zZSBhIHNwZWNpZmljIHN0YWNrIGZvciBpbXBvcnQgWyR7c3RhY2tzLnN0YWNrQXJ0aWZhY3RzLm1hcCgoeCkgPT4geC5pZCkuam9pbignLCAnKX1dYCxcbiAgICAgICk7XG4gICAgfVxuXG4gICAgaWYgKCFwcm9jZXNzLnN0ZG91dC5pc1RUWSAmJiAhb3B0aW9ucy5yZXNvdXJjZU1hcHBpbmdGaWxlKSB7XG4gICAgICB0aHJvdyBuZXcgVG9vbGtpdEVycm9yKCctLXJlc291cmNlLW1hcHBpbmcgaXMgcmVxdWlyZWQgd2hlbiBpbnB1dCBpcyBub3QgYSB0ZXJtaW5hbCcpO1xuICAgIH1cblxuICAgIGNvbnN0IHN0YWNrID0gc3RhY2tzLnN0YWNrQXJ0aWZhY3RzWzBdO1xuXG4gICAgaGlnaGxpZ2h0KHN0YWNrLmRpc3BsYXlOYW1lKTtcblxuICAgIGNvbnN0IHJlc291cmNlSW1wb3J0ZXIgPSBuZXcgUmVzb3VyY2VJbXBvcnRlcihzdGFjaywgdGhpcy5wcm9wcy5kZXBsb3ltZW50cyk7XG4gICAgY29uc3QgeyBhZGRpdGlvbnMsIGhhc05vbkFkZGl0aW9ucyB9ID0gYXdhaXQgcmVzb3VyY2VJbXBvcnRlci5kaXNjb3ZlckltcG9ydGFibGVSZXNvdXJjZXMob3B0aW9ucy5mb3JjZSk7XG4gICAgaWYgKGFkZGl0aW9ucy5sZW5ndGggPT09IDApIHtcbiAgICAgIHdhcm5pbmcoXG4gICAgICAgICclczogbm8gbmV3IHJlc291cmNlcyBjb21wYXJlZCB0byB0aGUgY3VycmVudGx5IGRlcGxveWVkIHN0YWNrLCBza2lwcGluZyBpbXBvcnQuJyxcbiAgICAgICAgY2hhbGsuYm9sZChzdGFjay5kaXNwbGF5TmFtZSksXG4gICAgICApO1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIC8vIFByZXBhcmUgYSBtYXBwaW5nIG9mIHBoeXNpY2FsIHJlc291cmNlcyB0byBDREsgY29uc3RydWN0c1xuICAgIGNvbnN0IGFjdHVhbEltcG9ydCA9ICFvcHRpb25zLnJlc291cmNlTWFwcGluZ0ZpbGVcbiAgICAgID8gYXdhaXQgcmVzb3VyY2VJbXBvcnRlci5hc2tGb3JSZXNvdXJjZUlkZW50aWZpZXJzKGFkZGl0aW9ucylcbiAgICAgIDogYXdhaXQgcmVzb3VyY2VJbXBvcnRlci5sb2FkUmVzb3VyY2VJZGVudGlmaWVycyhhZGRpdGlvbnMsIG9wdGlvbnMucmVzb3VyY2VNYXBwaW5nRmlsZSk7XG5cbiAgICBpZiAoYWN0dWFsSW1wb3J0LmltcG9ydFJlc291cmNlcy5sZW5ndGggPT09IDApIHtcbiAgICAgIHdhcm5pbmcoJ05vIHJlc291cmNlcyBzZWxlY3RlZCBmb3IgaW1wb3J0LicpO1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIC8vIElmIFwiLS1jcmVhdGUtcmVzb3VyY2UtbWFwcGluZ1wiIG9wdGlvbiB3YXMgcGFzc2VkLCB3cml0ZSB0aGUgcmVzb3VyY2UgbWFwcGluZyB0byB0aGUgZ2l2ZW4gZmlsZSBhbmQgZXhpdFxuICAgIGlmIChvcHRpb25zLnJlY29yZFJlc291cmNlTWFwcGluZykge1xuICAgICAgY29uc3Qgb3V0cHV0RmlsZSA9IG9wdGlvbnMucmVjb3JkUmVzb3VyY2VNYXBwaW5nO1xuICAgICAgZnMuZW5zdXJlRmlsZVN5bmMob3V0cHV0RmlsZSk7XG4gICAgICBhd2FpdCBmcy53cml0ZUpzb24ob3V0cHV0RmlsZSwgYWN0dWFsSW1wb3J0LnJlc291cmNlTWFwLCB7XG4gICAgICAgIHNwYWNlczogMixcbiAgICAgICAgZW5jb2Rpbmc6ICd1dGY4JyxcbiAgICAgIH0pO1xuICAgICAgaW5mbygnJXM6IG1hcHBpbmcgZmlsZSB3cml0dGVuLicsIG91dHB1dEZpbGUpO1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIC8vIEltcG9ydCB0aGUgcmVzb3VyY2VzIGFjY29yZGluZyB0byB0aGUgZ2l2ZW4gbWFwcGluZ1xuICAgIGluZm8oJyVzOiBpbXBvcnRpbmcgcmVzb3VyY2VzIGludG8gc3RhY2suLi4nLCBjaGFsay5ib2xkKHN0YWNrLmRpc3BsYXlOYW1lKSk7XG4gICAgY29uc3QgdGFncyA9IHRhZ3NGb3JTdGFjayhzdGFjayk7XG4gICAgYXdhaXQgcmVzb3VyY2VJbXBvcnRlci5pbXBvcnRSZXNvdXJjZXNGcm9tTWFwKGFjdHVhbEltcG9ydCwge1xuICAgICAgcm9sZUFybjogb3B0aW9ucy5yb2xlQXJuLFxuICAgICAgdG9vbGtpdFN0YWNrTmFtZTogb3B0aW9ucy50b29sa2l0U3RhY2tOYW1lLFxuICAgICAgdGFncyxcbiAgICAgIGRlcGxveW1lbnRNZXRob2Q6IG9wdGlvbnMuZGVwbG95bWVudE1ldGhvZCxcbiAgICAgIHVzZVByZXZpb3VzUGFyYW1ldGVyczogdHJ1ZSxcbiAgICAgIHByb2dyZXNzOiBvcHRpb25zLnByb2dyZXNzLFxuICAgICAgcm9sbGJhY2s6IG9wdGlvbnMucm9sbGJhY2ssXG4gICAgfSk7XG5cbiAgICAvLyBOb3RpZnkgdXNlciBvZiBuZXh0IHN0ZXBzXG4gICAgaW5mbyhcbiAgICAgIGBJbXBvcnQgb3BlcmF0aW9uIGNvbXBsZXRlLiBXZSByZWNvbW1lbmQgeW91IHJ1biBhICR7Y2hhbGsuYmx1ZUJyaWdodCgnZHJpZnQgZGV0ZWN0aW9uJyl9IG9wZXJhdGlvbiBgICtcbiAgICAgICAgJ3RvIGNvbmZpcm0geW91ciBDREsgYXBwIHJlc291cmNlIGRlZmluaXRpb25zIGFyZSB1cC10by1kYXRlLiBSZWFkIG1vcmUgaGVyZTogJyArXG4gICAgICAgIGNoYWxrLnVuZGVybGluZS5ibHVlQnJpZ2h0KFxuICAgICAgICAgICdodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vQVdTQ2xvdWRGb3JtYXRpb24vbGF0ZXN0L1VzZXJHdWlkZS9kZXRlY3QtZHJpZnQtc3RhY2suaHRtbCcsXG4gICAgICAgICksXG4gICAgKTtcbiAgICBpZiAoYWN0dWFsSW1wb3J0LmltcG9ydFJlc291cmNlcy5sZW5ndGggPCBhZGRpdGlvbnMubGVuZ3RoKSB7XG4gICAgICBpbmZvKCcnKTtcbiAgICAgIHdhcm5pbmcoXG4gICAgICAgIGBTb21lIHJlc291cmNlcyB3ZXJlIHNraXBwZWQuIFJ1biBhbm90aGVyICR7Y2hhbGsuYmx1ZUJyaWdodCgnY2RrIGltcG9ydCcpfSBvciBhICR7Y2hhbGsuYmx1ZUJyaWdodCgnY2RrIGRlcGxveScpfSB0byBicmluZyB0aGUgc3RhY2sgdXAtdG8tZGF0ZSB3aXRoIHlvdXIgQ0RLIGFwcCBkZWZpbml0aW9uLmAsXG4gICAgICApO1xuICAgIH0gZWxzZSBpZiAoaGFzTm9uQWRkaXRpb25zKSB7XG4gICAgICBpbmZvKCcnKTtcbiAgICAgIHdhcm5pbmcoXG4gICAgICAgIGBZb3VyIGFwcCBoYXMgcGVuZGluZyB1cGRhdGVzIG9yIGRlbGV0ZXMgZXhjbHVkZWQgZnJvbSB0aGlzIGltcG9ydCBvcGVyYXRpb24uIFJ1biBhICR7Y2hhbGsuYmx1ZUJyaWdodCgnY2RrIGRlcGxveScpfSB0byBicmluZyB0aGUgc3RhY2sgdXAtdG8tZGF0ZSB3aXRoIHlvdXIgQ0RLIGFwcCBkZWZpbml0aW9uLmAsXG4gICAgICApO1xuICAgIH1cbiAgfVxuXG4gIHB1YmxpYyBhc3luYyBkZXN0cm95KG9wdGlvbnM6IERlc3Ryb3lPcHRpb25zKSB7XG4gICAgbGV0IHN0YWNrcyA9IGF3YWl0IHRoaXMuc2VsZWN0U3RhY2tzRm9yRGVzdHJveShvcHRpb25zLnNlbGVjdG9yLCBvcHRpb25zLmV4Y2x1c2l2ZWx5KTtcblxuICAgIC8vIFRoZSBzdGFja3Mgd2lsbCBoYXZlIGJlZW4gb3JkZXJlZCBmb3IgZGVwbG95bWVudCwgc28gcmV2ZXJzZSB0aGVtIGZvciBkZWxldGlvbi5cbiAgICBzdGFja3MgPSBzdGFja3MucmV2ZXJzZWQoKTtcblxuICAgIGlmICghb3B0aW9ucy5mb3JjZSkge1xuICAgICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIG1heC1sZW5cbiAgICAgIGNvbnN0IGNvbmZpcm1lZCA9IGF3YWl0IHByb21wdGx5LmNvbmZpcm0oXG4gICAgICAgIGBBcmUgeW91IHN1cmUgeW91IHdhbnQgdG8gZGVsZXRlOiAke2NoYWxrLmJsdWUoc3RhY2tzLnN0YWNrQXJ0aWZhY3RzLm1hcCgocykgPT4gcy5oaWVyYXJjaGljYWxJZCkuam9pbignLCAnKSl9ICh5L24pP2AsXG4gICAgICApO1xuICAgICAgaWYgKCFjb25maXJtZWQpIHtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuICAgIH1cblxuICAgIGNvbnN0IGFjdGlvbiA9IG9wdGlvbnMuZnJvbURlcGxveSA/ICdkZXBsb3knIDogJ2Rlc3Ryb3knO1xuICAgIGZvciAoY29uc3QgW2luZGV4LCBzdGFja10gb2Ygc3RhY2tzLnN0YWNrQXJ0aWZhY3RzLmVudHJpZXMoKSkge1xuICAgICAgc3VjY2VzcygnJXM6IGRlc3Ryb3lpbmcuLi4gWyVzLyVzXScsIGNoYWxrLmJsdWUoc3RhY2suZGlzcGxheU5hbWUpLCBpbmRleCArIDEsIHN0YWNrcy5zdGFja0NvdW50KTtcbiAgICAgIHRyeSB7XG4gICAgICAgIGF3YWl0IHRoaXMucHJvcHMuZGVwbG95bWVudHMuZGVzdHJveVN0YWNrKHtcbiAgICAgICAgICBzdGFjayxcbiAgICAgICAgICBkZXBsb3lOYW1lOiBzdGFjay5zdGFja05hbWUsXG4gICAgICAgICAgcm9sZUFybjogb3B0aW9ucy5yb2xlQXJuLFxuICAgICAgICAgIGNpOiBvcHRpb25zLmNpLFxuICAgICAgICB9KTtcbiAgICAgICAgc3VjY2VzcyhgXFxuIOKchSAgJXM6ICR7YWN0aW9ufWVkYCwgY2hhbGsuYmx1ZShzdGFjay5kaXNwbGF5TmFtZSkpO1xuICAgICAgfSBjYXRjaCAoZSkge1xuICAgICAgICBlcnJvcihgXFxuIOKdjCAgJXM6ICR7YWN0aW9ufSBmYWlsZWRgLCBjaGFsay5ibHVlKHN0YWNrLmRpc3BsYXlOYW1lKSwgZSk7XG4gICAgICAgIHRocm93IGU7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgcHVibGljIGFzeW5jIGxpc3QoXG4gICAgc2VsZWN0b3JzOiBzdHJpbmdbXSxcbiAgICBvcHRpb25zOiB7IGxvbmc/OiBib29sZWFuOyBqc29uPzogYm9vbGVhbjsgc2hvd0RlcHM/OiBib29sZWFuIH0gPSB7fSxcbiAgKTogUHJvbWlzZTxudW1iZXI+IHtcbiAgICBjb25zdCBzdGFja3MgPSBhd2FpdCBsaXN0U3RhY2tzKHRoaXMsIHtcbiAgICAgIHNlbGVjdG9yczogc2VsZWN0b3JzLFxuICAgIH0pO1xuXG4gICAgaWYgKG9wdGlvbnMubG9uZyAmJiBvcHRpb25zLnNob3dEZXBzKSB7XG4gICAgICBwcmludFNlcmlhbGl6ZWRPYmplY3Qoc3RhY2tzLCBvcHRpb25zLmpzb24gPz8gZmFsc2UpO1xuICAgICAgcmV0dXJuIDA7XG4gICAgfVxuXG4gICAgaWYgKG9wdGlvbnMuc2hvd0RlcHMpIHtcbiAgICAgIGNvbnN0IHN0YWNrRGVwcyA9IFtdO1xuXG4gICAgICBmb3IgKGNvbnN0IHN0YWNrIG9mIHN0YWNrcykge1xuICAgICAgICBzdGFja0RlcHMucHVzaCh7XG4gICAgICAgICAgaWQ6IHN0YWNrLmlkLFxuICAgICAgICAgIGRlcGVuZGVuY2llczogc3RhY2suZGVwZW5kZW5jaWVzLFxuICAgICAgICB9KTtcbiAgICAgIH1cblxuICAgICAgcHJpbnRTZXJpYWxpemVkT2JqZWN0KHN0YWNrRGVwcywgb3B0aW9ucy5qc29uID8/IGZhbHNlKTtcbiAgICAgIHJldHVybiAwO1xuICAgIH1cblxuICAgIGlmIChvcHRpb25zLmxvbmcpIHtcbiAgICAgIGNvbnN0IGxvbmcgPSBbXTtcblxuICAgICAgZm9yIChjb25zdCBzdGFjayBvZiBzdGFja3MpIHtcbiAgICAgICAgbG9uZy5wdXNoKHtcbiAgICAgICAgICBpZDogc3RhY2suaWQsXG4gICAgICAgICAgbmFtZTogc3RhY2submFtZSxcbiAgICAgICAgICBlbnZpcm9ubWVudDogc3RhY2suZW52aXJvbm1lbnQsXG4gICAgICAgIH0pO1xuICAgICAgfVxuICAgICAgcHJpbnRTZXJpYWxpemVkT2JqZWN0KGxvbmcsIG9wdGlvbnMuanNvbiA/PyBmYWxzZSk7XG4gICAgICByZXR1cm4gMDtcbiAgICB9XG5cbiAgICAvLyBqdXN0IHByaW50IHN0YWNrIElEc1xuICAgIGZvciAoY29uc3Qgc3RhY2sgb2Ygc3RhY2tzKSB7XG4gICAgICBsb2dSZXN1bHQoc3RhY2suaWQpO1xuICAgIH1cblxuICAgIHJldHVybiAwOyAvLyBleGl0LWNvZGVcbiAgfVxuXG4gIC8qKlxuICAgKiBTeW50aGVzaXplIHRoZSBnaXZlbiBzZXQgb2Ygc3RhY2tzIChjYWxsZWQgd2hlbiB0aGUgdXNlciBydW5zICdjZGsgc3ludGgnKVxuICAgKlxuICAgKiBJTlBVVDogU3RhY2sgbmFtZXMgY2FuIGJlIHN1cHBsaWVkIHVzaW5nIGEgZ2xvYiBmaWx0ZXIuIElmIG5vIHN0YWNrcyBhcmVcbiAgICogZ2l2ZW4sIGFsbCBzdGFja3MgZnJvbSB0aGUgYXBwbGljYXRpb24gYXJlIGltcGxpY2l0bHkgc2VsZWN0ZWQuXG4gICAqXG4gICAqIE9VVFBVVDogSWYgbW9yZSB0aGFuIG9uZSBzdGFjayBlbmRzIHVwIGJlaW5nIHNlbGVjdGVkLCBhbiBvdXRwdXQgZGlyZWN0b3J5XG4gICAqIHNob3VsZCBiZSBzdXBwbGllZCwgd2hlcmUgdGhlIHRlbXBsYXRlcyB3aWxsIGJlIHdyaXR0ZW4uXG4gICAqL1xuICBwdWJsaWMgYXN5bmMgc3ludGgoXG4gICAgc3RhY2tOYW1lczogc3RyaW5nW10sXG4gICAgZXhjbHVzaXZlbHk6IGJvb2xlYW4sXG4gICAgcXVpZXQ6IGJvb2xlYW4sXG4gICAgYXV0b1ZhbGlkYXRlPzogYm9vbGVhbixcbiAgICBqc29uPzogYm9vbGVhbixcbiAgKTogUHJvbWlzZTxhbnk+IHtcbiAgICBjb25zdCBzdGFja3MgPSBhd2FpdCB0aGlzLnNlbGVjdFN0YWNrc0ZvckRpZmYoc3RhY2tOYW1lcywgZXhjbHVzaXZlbHksIGF1dG9WYWxpZGF0ZSk7XG5cbiAgICAvLyBpZiB3ZSBoYXZlIGEgc2luZ2xlIHN0YWNrLCBwcmludCBpdCB0byBTVERPVVRcbiAgICBpZiAoc3RhY2tzLnN0YWNrQ291bnQgPT09IDEpIHtcbiAgICAgIGlmICghcXVpZXQpIHtcbiAgICAgICAgcHJpbnRTZXJpYWxpemVkT2JqZWN0KG9ic2N1cmVUZW1wbGF0ZShzdGFja3MuZmlyc3RTdGFjay50ZW1wbGF0ZSksIGpzb24gPz8gZmFsc2UpO1xuICAgICAgfVxuICAgICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgICB9XG5cbiAgICAvLyBub3Qgb3V0cHV0dGluZyB0ZW1wbGF0ZSB0byBzdGRvdXQsIGxldCdzIGV4cGxhaW4gdGhpbmdzIHRvIHRoZSB1c2VyIGEgbGl0dGxlIGJpdC4uLlxuICAgIHN1Y2Nlc3MoYFN1Y2Nlc3NmdWxseSBzeW50aGVzaXplZCB0byAke2NoYWxrLmJsdWUocGF0aC5yZXNvbHZlKHN0YWNrcy5hc3NlbWJseS5kaXJlY3RvcnkpKX1gKTtcbiAgICBpbmZvKFxuICAgICAgYFN1cHBseSBhIHN0YWNrIGlkICgke3N0YWNrcy5zdGFja0FydGlmYWN0cy5tYXAoKHMpID0+IGNoYWxrLmdyZWVuKHMuaGllcmFyY2hpY2FsSWQpKS5qb2luKCcsICcpfSkgdG8gZGlzcGxheSBpdHMgdGVtcGxhdGUuYCxcbiAgICApO1xuXG4gICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgfVxuXG4gIC8qKlxuICAgKiBCb290c3RyYXAgdGhlIENESyBUb29sa2l0IHN0YWNrIGluIHRoZSBhY2NvdW50cyB1c2VkIGJ5IHRoZSBzcGVjaWZpZWQgc3RhY2socykuXG4gICAqXG4gICAqIEBwYXJhbSB1c2VyRW52aXJvbm1lbnRTcGVjcyBlbnZpcm9ubWVudCBuYW1lcyB0aGF0IG5lZWQgdG8gaGF2ZSB0b29sa2l0IHN1cHBvcnRcbiAgICogICAgICAgICAgICAgcHJvdmlzaW9uZWQsIGFzIGEgZ2xvYiBmaWx0ZXIuIElmIG5vbmUgaXMgcHJvdmlkZWQsIGFsbCBzdGFja3MgYXJlIGltcGxpY2l0bHkgc2VsZWN0ZWQuXG4gICAqIEBwYXJhbSBvcHRpb25zIFRoZSBuYW1lLCByb2xlIEFSTiwgYm9vdHN0cmFwcGluZyBwYXJhbWV0ZXJzLCBldGMuIHRvIGJlIHVzZWQgZm9yIHRoZSBDREsgVG9vbGtpdCBzdGFjay5cbiAgICovXG4gIHB1YmxpYyBhc3luYyBib290c3RyYXAoXG4gICAgdXNlckVudmlyb25tZW50U3BlY3M6IHN0cmluZ1tdLFxuICAgIG9wdGlvbnM6IEJvb3RzdHJhcEVudmlyb25tZW50T3B0aW9ucyxcbiAgKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgY29uc3QgYm9vdHN0cmFwcGVyID0gbmV3IEJvb3RzdHJhcHBlcihvcHRpb25zLnNvdXJjZSk7XG4gICAgLy8gSWYgdGhlcmUgaXMgYW4gJy0tYXBwJyBhcmd1bWVudCBhbmQgYW4gZW52aXJvbm1lbnQgbG9va3MgbGlrZSBhIGdsb2IsIHdlXG4gICAgLy8gc2VsZWN0IHRoZSBlbnZpcm9ubWVudHMgZnJvbSB0aGUgYXBwLiBPdGhlcndpc2UsIHVzZSB3aGF0IHRoZSB1c2VyIHNhaWQuXG5cbiAgICBjb25zdCBlbnZpcm9ubWVudHMgPSBhd2FpdCB0aGlzLmRlZmluZUVudmlyb25tZW50cyh1c2VyRW52aXJvbm1lbnRTcGVjcyk7XG5cbiAgICBjb25zdCBsaW1pdCA9IHBMaW1pdCgyMCk7XG5cbiAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgQGNka2xhYnMvcHJvbWlzZWFsbC1uby11bmJvdW5kZWQtcGFyYWxsZWxpc21cbiAgICBhd2FpdCBQcm9taXNlLmFsbChlbnZpcm9ubWVudHMubWFwKChlbnZpcm9ubWVudCkgPT4gbGltaXQoYXN5bmMgKCkgPT4ge1xuICAgICAgc3VjY2VzcygnIOKPsyAgQm9vdHN0cmFwcGluZyBlbnZpcm9ubWVudCAlcy4uLicsIGNoYWxrLmJsdWUoZW52aXJvbm1lbnQubmFtZSkpO1xuICAgICAgdHJ5IHtcbiAgICAgICAgY29uc3QgcmVzdWx0ID0gYXdhaXQgYm9vdHN0cmFwcGVyLmJvb3RzdHJhcEVudmlyb25tZW50KGVudmlyb25tZW50LCB0aGlzLnByb3BzLnNka1Byb3ZpZGVyLCBvcHRpb25zKTtcbiAgICAgICAgY29uc3QgbWVzc2FnZSA9IHJlc3VsdC5ub09wXG4gICAgICAgICAgPyAnIOKchSAgRW52aXJvbm1lbnQgJXMgYm9vdHN0cmFwcGVkIChubyBjaGFuZ2VzKS4nXG4gICAgICAgICAgOiAnIOKchSAgRW52aXJvbm1lbnQgJXMgYm9vdHN0cmFwcGVkLic7XG4gICAgICAgIHN1Y2Nlc3MobWVzc2FnZSwgY2hhbGsuYmx1ZShlbnZpcm9ubWVudC5uYW1lKSk7XG4gICAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgIGVycm9yKCcg4p2MICBFbnZpcm9ubWVudCAlcyBmYWlsZWQgYm9vdHN0cmFwcGluZzogJXMnLCBjaGFsay5ibHVlKGVudmlyb25tZW50Lm5hbWUpLCBlKTtcbiAgICAgICAgdGhyb3cgZTtcbiAgICAgIH1cbiAgICB9KSkpO1xuICB9XG5cbiAgLyoqXG4gICAqIEdhcmJhZ2UgY29sbGVjdHMgYXNzZXRzIGZyb20gYSBDREsgYXBwJ3MgZW52aXJvbm1lbnRcbiAgICogQHBhcmFtIG9wdGlvbnMgT3B0aW9ucyBmb3IgR2FyYmFnZSBDb2xsZWN0aW9uXG4gICAqL1xuICBwdWJsaWMgYXN5bmMgZ2FyYmFnZUNvbGxlY3QodXNlckVudmlyb25tZW50U3BlY3M6IHN0cmluZ1tdLCBvcHRpb25zOiBHYXJiYWdlQ29sbGVjdGlvbk9wdGlvbnMpIHtcbiAgICBjb25zdCBlbnZpcm9ubWVudHMgPSBhd2FpdCB0aGlzLmRlZmluZUVudmlyb25tZW50cyh1c2VyRW52aXJvbm1lbnRTcGVjcyk7XG5cbiAgICBmb3IgKGNvbnN0IGVudmlyb25tZW50IG9mIGVudmlyb25tZW50cykge1xuICAgICAgc3VjY2VzcygnIOKPsyAgR2FyYmFnZSBDb2xsZWN0aW5nIGVudmlyb25tZW50ICVzLi4uJywgY2hhbGsuYmx1ZShlbnZpcm9ubWVudC5uYW1lKSk7XG4gICAgICBjb25zdCBnYyA9IG5ldyBHYXJiYWdlQ29sbGVjdG9yKHtcbiAgICAgICAgc2RrUHJvdmlkZXI6IHRoaXMucHJvcHMuc2RrUHJvdmlkZXIsXG4gICAgICAgIHJlc29sdmVkRW52aXJvbm1lbnQ6IGVudmlyb25tZW50LFxuICAgICAgICBib290c3RyYXBTdGFja05hbWU6IG9wdGlvbnMuYm9vdHN0cmFwU3RhY2tOYW1lLFxuICAgICAgICByb2xsYmFja0J1ZmZlckRheXM6IG9wdGlvbnMucm9sbGJhY2tCdWZmZXJEYXlzLFxuICAgICAgICBjcmVhdGVkQnVmZmVyRGF5czogb3B0aW9ucy5jcmVhdGVkQnVmZmVyRGF5cyxcbiAgICAgICAgYWN0aW9uOiBvcHRpb25zLmFjdGlvbiA/PyAnZnVsbCcsXG4gICAgICAgIHR5cGU6IG9wdGlvbnMudHlwZSA/PyAnYWxsJyxcbiAgICAgICAgY29uZmlybTogb3B0aW9ucy5jb25maXJtID8/IHRydWUsXG4gICAgICB9KTtcbiAgICAgIGF3YWl0IGdjLmdhcmJhZ2VDb2xsZWN0KCk7XG4gICAgfTtcbiAgfVxuXG4gIHByaXZhdGUgYXN5bmMgZGVmaW5lRW52aXJvbm1lbnRzKHVzZXJFbnZpcm9ubWVudFNwZWNzOiBzdHJpbmdbXSk6IFByb21pc2U8Y3hhcGkuRW52aXJvbm1lbnRbXT4ge1xuICAgIC8vIEJ5IGRlZmF1bHQsIGdsb2IgZm9yIGV2ZXJ5dGhpbmdcbiAgICBjb25zdCBlbnZpcm9ubWVudFNwZWNzID0gdXNlckVudmlyb25tZW50U3BlY3MubGVuZ3RoID4gMCA/IFsuLi51c2VyRW52aXJvbm1lbnRTcGVjc10gOiBbJyoqJ107XG5cbiAgICAvLyBQYXJ0aXRpb24gaW50byBnbG9icyBhbmQgbm9uLWdsb2JzICh0aGlzIHdpbGwgbXV0YXRlIGVudmlyb25tZW50U3BlY3MpLlxuICAgIGNvbnN0IGdsb2JTcGVjcyA9IHBhcnRpdGlvbihlbnZpcm9ubWVudFNwZWNzLCBsb29rc0xpa2VHbG9iKTtcbiAgICBpZiAoZ2xvYlNwZWNzLmxlbmd0aCA+IDAgJiYgIXRoaXMucHJvcHMuY2xvdWRFeGVjdXRhYmxlLmhhc0FwcCkge1xuICAgICAgaWYgKHVzZXJFbnZpcm9ubWVudFNwZWNzLmxlbmd0aCA+IDApIHtcbiAgICAgICAgLy8gVXNlciBkaWQgcmVxdWVzdCB0aGlzIGdsb2JcbiAgICAgICAgdGhyb3cgbmV3IFRvb2xraXRFcnJvcihcbiAgICAgICAgICBgJyR7Z2xvYlNwZWNzfScgaXMgbm90IGFuIGVudmlyb25tZW50IG5hbWUuIFNwZWNpZnkgYW4gZW52aXJvbm1lbnQgbmFtZSBsaWtlICdhd3M6Ly8xMjM0NTY3ODkwMTIvdXMtZWFzdC0xJywgb3IgcnVuIGluIGEgZGlyZWN0b3J5IHdpdGggJ2Nkay5qc29uJyB0byB1c2Ugd2lsZGNhcmRzLmAsXG4gICAgICAgICk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICAvLyBVc2VyIGRpZCBub3QgcmVxdWVzdCBhbnl0aGluZ1xuICAgICAgICB0aHJvdyBuZXcgVG9vbGtpdEVycm9yKFxuICAgICAgICAgIFwiU3BlY2lmeSBhbiBlbnZpcm9ubWVudCBuYW1lIGxpa2UgJ2F3czovLzEyMzQ1Njc4OTAxMi91cy1lYXN0LTEnLCBvciBydW4gaW4gYSBkaXJlY3Rvcnkgd2l0aCAnY2RrLmpzb24nLlwiLFxuICAgICAgICApO1xuICAgICAgfVxuICAgIH1cblxuICAgIGNvbnN0IGVudmlyb25tZW50czogY3hhcGkuRW52aXJvbm1lbnRbXSA9IFsuLi5lbnZpcm9ubWVudHNGcm9tRGVzY3JpcHRvcnMoZW52aXJvbm1lbnRTcGVjcyldO1xuXG4gICAgLy8gSWYgdGhlcmUgaXMgYW4gJy0tYXBwJyBhcmd1bWVudCwgc2VsZWN0IHRoZSBlbnZpcm9ubWVudHMgZnJvbSB0aGUgYXBwLlxuICAgIGlmICh0aGlzLnByb3BzLmNsb3VkRXhlY3V0YWJsZS5oYXNBcHApIHtcbiAgICAgIGVudmlyb25tZW50cy5wdXNoKFxuICAgICAgICAuLi4oYXdhaXQgZ2xvYkVudmlyb25tZW50c0Zyb21TdGFja3MoYXdhaXQgdGhpcy5zZWxlY3RTdGFja3NGb3JMaXN0KFtdKSwgZ2xvYlNwZWNzLCB0aGlzLnByb3BzLnNka1Byb3ZpZGVyKSksXG4gICAgICApO1xuICAgIH1cblxuICAgIHJldHVybiBlbnZpcm9ubWVudHM7XG4gIH1cblxuICAvKipcbiAgICogTWlncmF0ZXMgYSBDbG91ZEZvcm1hdGlvbiBzdGFjay90ZW1wbGF0ZSB0byBhIENESyBhcHBcbiAgICogQHBhcmFtIG9wdGlvbnMgT3B0aW9ucyBmb3IgQ0RLIGFwcCBjcmVhdGlvblxuICAgKi9cbiAgcHVibGljIGFzeW5jIG1pZ3JhdGUob3B0aW9uczogTWlncmF0ZU9wdGlvbnMpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICB3YXJuaW5nKCdUaGlzIGNvbW1hbmQgaXMgYW4gZXhwZXJpbWVudGFsIGZlYXR1cmUuJyk7XG4gICAgY29uc3QgbGFuZ3VhZ2UgPSBvcHRpb25zLmxhbmd1YWdlPy50b0xvd2VyQ2FzZSgpID8/ICd0eXBlc2NyaXB0JztcbiAgICBjb25zdCBlbnZpcm9ubWVudCA9IHNldEVudmlyb25tZW50KG9wdGlvbnMuYWNjb3VudCwgb3B0aW9ucy5yZWdpb24pO1xuICAgIGxldCBnZW5lcmF0ZVRlbXBsYXRlT3V0cHV0OiBHZW5lcmF0ZVRlbXBsYXRlT3V0cHV0IHwgdW5kZWZpbmVkO1xuICAgIGxldCBjZm46IENmblRlbXBsYXRlR2VuZXJhdG9yUHJvdmlkZXIgfCB1bmRlZmluZWQ7XG4gICAgbGV0IHRlbXBsYXRlVG9EZWxldGU6IHN0cmluZyB8IHVuZGVmaW5lZDtcblxuICAgIHRyeSB7XG4gICAgICAvLyBpZiBuZWl0aGVyIGZyb21QYXRoIG5vciBmcm9tU3RhY2sgaXMgcHJvdmlkZWQsIGdlbmVyYXRlIGEgdGVtcGxhdGUgdXNpbmcgY2xvdWRmb3JtYXRpb25cbiAgICAgIGNvbnN0IHNjYW5UeXBlID0gcGFyc2VTb3VyY2VPcHRpb25zKG9wdGlvbnMuZnJvbVBhdGgsIG9wdGlvbnMuZnJvbVN0YWNrLCBvcHRpb25zLnN0YWNrTmFtZSkuc291cmNlO1xuICAgICAgaWYgKHNjYW5UeXBlID09IFRlbXBsYXRlU291cmNlT3B0aW9ucy5TQ0FOKSB7XG4gICAgICAgIGdlbmVyYXRlVGVtcGxhdGVPdXRwdXQgPSBhd2FpdCBnZW5lcmF0ZVRlbXBsYXRlKHtcbiAgICAgICAgICBzdGFja05hbWU6IG9wdGlvbnMuc3RhY2tOYW1lLFxuICAgICAgICAgIGZpbHRlcnM6IG9wdGlvbnMuZmlsdGVyLFxuICAgICAgICAgIGZyb21TY2FuOiBvcHRpb25zLmZyb21TY2FuLFxuICAgICAgICAgIHNka1Byb3ZpZGVyOiB0aGlzLnByb3BzLnNka1Byb3ZpZGVyLFxuICAgICAgICAgIGVudmlyb25tZW50OiBlbnZpcm9ubWVudCxcbiAgICAgICAgfSk7XG4gICAgICAgIHRlbXBsYXRlVG9EZWxldGUgPSBnZW5lcmF0ZVRlbXBsYXRlT3V0cHV0LnRlbXBsYXRlSWQ7XG4gICAgICB9IGVsc2UgaWYgKHNjYW5UeXBlID09IFRlbXBsYXRlU291cmNlT3B0aW9ucy5QQVRIKSB7XG4gICAgICAgIGNvbnN0IHRlbXBsYXRlQm9keSA9IHJlYWRGcm9tUGF0aChvcHRpb25zLmZyb21QYXRoISk7XG5cbiAgICAgICAgY29uc3QgcGFyc2VkVGVtcGxhdGUgPSBkZXNlcmlhbGl6ZVN0cnVjdHVyZSh0ZW1wbGF0ZUJvZHkpO1xuICAgICAgICBjb25zdCB0ZW1wbGF0ZUlkID0gcGFyc2VkVGVtcGxhdGUuTWV0YWRhdGE/LlRlbXBsYXRlSWQ/LnRvU3RyaW5nKCk7XG4gICAgICAgIGlmICh0ZW1wbGF0ZUlkKSB7XG4gICAgICAgICAgLy8gaWYgd2UgaGF2ZSBhIHRlbXBsYXRlIGlkLCB3ZSBjYW4gY2FsbCBkZXNjcmliZSBnZW5lcmF0ZWQgdGVtcGxhdGUgdG8gZ2V0IHRoZSByZXNvdXJjZSBpZGVudGlmaWVyc1xuICAgICAgICAgIC8vIHJlc291cmNlIG1ldGFkYXRhLCBhbmQgdGVtcGxhdGUgc291cmNlIHRvIGdlbmVyYXRlIHRoZSB0ZW1wbGF0ZVxuICAgICAgICAgIGNmbiA9IG5ldyBDZm5UZW1wbGF0ZUdlbmVyYXRvclByb3ZpZGVyKGF3YWl0IGJ1aWxkQ2ZuQ2xpZW50KHRoaXMucHJvcHMuc2RrUHJvdmlkZXIsIGVudmlyb25tZW50KSk7XG4gICAgICAgICAgY29uc3QgZ2VuZXJhdGVkVGVtcGxhdGVTdW1tYXJ5ID0gYXdhaXQgY2ZuLmRlc2NyaWJlR2VuZXJhdGVkVGVtcGxhdGUodGVtcGxhdGVJZCk7XG4gICAgICAgICAgZ2VuZXJhdGVUZW1wbGF0ZU91dHB1dCA9IGJ1aWxkR2VuZXJ0ZWRUZW1wbGF0ZU91dHB1dChcbiAgICAgICAgICAgIGdlbmVyYXRlZFRlbXBsYXRlU3VtbWFyeSxcbiAgICAgICAgICAgIHRlbXBsYXRlQm9keSxcbiAgICAgICAgICAgIGdlbmVyYXRlZFRlbXBsYXRlU3VtbWFyeS5HZW5lcmF0ZWRUZW1wbGF0ZUlkISxcbiAgICAgICAgICApO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIGdlbmVyYXRlVGVtcGxhdGVPdXRwdXQgPSB7XG4gICAgICAgICAgICBtaWdyYXRlSnNvbjoge1xuICAgICAgICAgICAgICB0ZW1wbGF0ZUJvZHk6IHRlbXBsYXRlQm9keSxcbiAgICAgICAgICAgICAgc291cmNlOiAnbG9jYWxmaWxlJyxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgfTtcbiAgICAgICAgfVxuICAgICAgfSBlbHNlIGlmIChzY2FuVHlwZSA9PSBUZW1wbGF0ZVNvdXJjZU9wdGlvbnMuU1RBQ0spIHtcbiAgICAgICAgY29uc3QgdGVtcGxhdGUgPSBhd2FpdCByZWFkRnJvbVN0YWNrKG9wdGlvbnMuc3RhY2tOYW1lLCB0aGlzLnByb3BzLnNka1Byb3ZpZGVyLCBlbnZpcm9ubWVudCk7XG4gICAgICAgIGlmICghdGVtcGxhdGUpIHtcbiAgICAgICAgICB0aHJvdyBuZXcgVG9vbGtpdEVycm9yKGBObyB0ZW1wbGF0ZSBmb3VuZCBmb3Igc3RhY2stbmFtZTogJHtvcHRpb25zLnN0YWNrTmFtZX1gKTtcbiAgICAgICAgfVxuICAgICAgICBnZW5lcmF0ZVRlbXBsYXRlT3V0cHV0ID0ge1xuICAgICAgICAgIG1pZ3JhdGVKc29uOiB7XG4gICAgICAgICAgICB0ZW1wbGF0ZUJvZHk6IHRlbXBsYXRlLFxuICAgICAgICAgICAgc291cmNlOiBvcHRpb25zLnN0YWNrTmFtZSxcbiAgICAgICAgICB9LFxuICAgICAgICB9O1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgLy8gV2Ugc2hvdWxkbid0IGV2ZXIgZ2V0IGhlcmUsIGJ1dCBqdXN0IGluIGNhc2UuXG4gICAgICAgIHRocm93IG5ldyBUb29sa2l0RXJyb3IoYEludmFsaWQgc291cmNlIG9wdGlvbiBwcm92aWRlZDogJHtzY2FuVHlwZX1gKTtcbiAgICAgIH1cbiAgICAgIGNvbnN0IHN0YWNrID0gZ2VuZXJhdGVTdGFjayhnZW5lcmF0ZVRlbXBsYXRlT3V0cHV0Lm1pZ3JhdGVKc29uLnRlbXBsYXRlQm9keSwgb3B0aW9ucy5zdGFja05hbWUsIGxhbmd1YWdlKTtcbiAgICAgIHN1Y2Nlc3MoJyDij7MgIEdlbmVyYXRpbmcgQ0RLIGFwcCBmb3IgJXMuLi4nLCBjaGFsay5ibHVlKG9wdGlvbnMuc3RhY2tOYW1lKSk7XG4gICAgICBhd2FpdCBnZW5lcmF0ZUNka0FwcChvcHRpb25zLnN0YWNrTmFtZSwgc3RhY2shLCBsYW5ndWFnZSwgb3B0aW9ucy5vdXRwdXRQYXRoLCBvcHRpb25zLmNvbXByZXNzKTtcbiAgICAgIGlmIChnZW5lcmF0ZVRlbXBsYXRlT3V0cHV0KSB7XG4gICAgICAgIHdyaXRlTWlncmF0ZUpzb25GaWxlKG9wdGlvbnMub3V0cHV0UGF0aCwgb3B0aW9ucy5zdGFja05hbWUsIGdlbmVyYXRlVGVtcGxhdGVPdXRwdXQubWlncmF0ZUpzb24pO1xuICAgICAgfVxuICAgICAgaWYgKGlzVGhlcmVBV2FybmluZyhnZW5lcmF0ZVRlbXBsYXRlT3V0cHV0KSkge1xuICAgICAgICB3YXJuaW5nKFxuICAgICAgICAgICcg4pqg77iPICBTb21lIHJlc291cmNlcyBjb3VsZCBub3QgYmUgbWlncmF0ZWQgY29tcGxldGVseS4gUGxlYXNlIHJldmlldyB0aGUgUkVBRE1FLm1kIGZpbGUgZm9yIG1vcmUgaW5mb3JtYXRpb24uJyxcbiAgICAgICAgKTtcbiAgICAgICAgYXBwZW5kV2FybmluZ3NUb1JlYWRtZShcbiAgICAgICAgICBgJHtwYXRoLmpvaW4ob3B0aW9ucy5vdXRwdXRQYXRoID8/IHByb2Nlc3MuY3dkKCksIG9wdGlvbnMuc3RhY2tOYW1lKX0vUkVBRE1FLm1kYCxcbiAgICAgICAgICBnZW5lcmF0ZVRlbXBsYXRlT3V0cHV0LnJlc291cmNlcyEsXG4gICAgICAgICk7XG4gICAgICB9XG4gICAgfSBjYXRjaCAoZSkge1xuICAgICAgZXJyb3IoJyDinYwgIE1pZ3JhdGUgZmFpbGVkIGZvciBgJXNgOiAlcycsIG9wdGlvbnMuc3RhY2tOYW1lLCAoZSBhcyBFcnJvcikubWVzc2FnZSk7XG4gICAgICB0aHJvdyBlO1xuICAgIH0gZmluYWxseSB7XG4gICAgICBpZiAodGVtcGxhdGVUb0RlbGV0ZSkge1xuICAgICAgICBpZiAoIWNmbikge1xuICAgICAgICAgIGNmbiA9IG5ldyBDZm5UZW1wbGF0ZUdlbmVyYXRvclByb3ZpZGVyKGF3YWl0IGJ1aWxkQ2ZuQ2xpZW50KHRoaXMucHJvcHMuc2RrUHJvdmlkZXIsIGVudmlyb25tZW50KSk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKCFwcm9jZXNzLmVudi5NSUdSQVRFX0lOVEVHX1RFU1QpIHtcbiAgICAgICAgICBhd2FpdCBjZm4uZGVsZXRlR2VuZXJhdGVkVGVtcGxhdGUodGVtcGxhdGVUb0RlbGV0ZSk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICBwcml2YXRlIGFzeW5jIHNlbGVjdFN0YWNrc0Zvckxpc3QocGF0dGVybnM6IHN0cmluZ1tdKSB7XG4gICAgY29uc3QgYXNzZW1ibHkgPSBhd2FpdCB0aGlzLmFzc2VtYmx5KCk7XG4gICAgY29uc3Qgc3RhY2tzID0gYXdhaXQgYXNzZW1ibHkuc2VsZWN0U3RhY2tzKHsgcGF0dGVybnMgfSwgeyBkZWZhdWx0QmVoYXZpb3I6IERlZmF1bHRTZWxlY3Rpb24uQWxsU3RhY2tzIH0pO1xuXG4gICAgLy8gTm8gdmFsaWRhdGlvblxuXG4gICAgcmV0dXJuIHN0YWNrcztcbiAgfVxuXG4gIHByaXZhdGUgYXN5bmMgc2VsZWN0U3RhY2tzRm9yRGVwbG95KFxuICAgIHNlbGVjdG9yOiBTdGFja1NlbGVjdG9yLFxuICAgIGV4Y2x1c2l2ZWx5PzogYm9vbGVhbixcbiAgICBjYWNoZUNsb3VkQXNzZW1ibHk/OiBib29sZWFuLFxuICAgIGlnbm9yZU5vU3RhY2tzPzogYm9vbGVhbixcbiAgKTogUHJvbWlzZTxTdGFja0NvbGxlY3Rpb24+IHtcbiAgICBjb25zdCBhc3NlbWJseSA9IGF3YWl0IHRoaXMuYXNzZW1ibHkoY2FjaGVDbG91ZEFzc2VtYmx5KTtcbiAgICBjb25zdCBzdGFja3MgPSBhd2FpdCBhc3NlbWJseS5zZWxlY3RTdGFja3Moc2VsZWN0b3IsIHtcbiAgICAgIGV4dGVuZDogZXhjbHVzaXZlbHkgPyBFeHRlbmRlZFN0YWNrU2VsZWN0aW9uLk5vbmUgOiBFeHRlbmRlZFN0YWNrU2VsZWN0aW9uLlVwc3RyZWFtLFxuICAgICAgZGVmYXVsdEJlaGF2aW9yOiBEZWZhdWx0U2VsZWN0aW9uLk9ubHlTaW5nbGUsXG4gICAgICBpZ25vcmVOb1N0YWNrcyxcbiAgICB9KTtcblxuICAgIHRoaXMudmFsaWRhdGVTdGFja3NTZWxlY3RlZChzdGFja3MsIHNlbGVjdG9yLnBhdHRlcm5zKTtcbiAgICBhd2FpdCB0aGlzLnZhbGlkYXRlU3RhY2tzKHN0YWNrcyk7XG5cbiAgICByZXR1cm4gc3RhY2tzO1xuICB9XG5cbiAgcHJpdmF0ZSBhc3luYyBzZWxlY3RTdGFja3NGb3JEaWZmKFxuICAgIHN0YWNrTmFtZXM6IHN0cmluZ1tdLFxuICAgIGV4Y2x1c2l2ZWx5PzogYm9vbGVhbixcbiAgICBhdXRvVmFsaWRhdGU/OiBib29sZWFuLFxuICApOiBQcm9taXNlPFN0YWNrQ29sbGVjdGlvbj4ge1xuICAgIGNvbnN0IGFzc2VtYmx5ID0gYXdhaXQgdGhpcy5hc3NlbWJseSgpO1xuXG4gICAgY29uc3Qgc2VsZWN0ZWRGb3JEaWZmID0gYXdhaXQgYXNzZW1ibHkuc2VsZWN0U3RhY2tzKFxuICAgICAgeyBwYXR0ZXJuczogc3RhY2tOYW1lcyB9LFxuICAgICAge1xuICAgICAgICBleHRlbmQ6IGV4Y2x1c2l2ZWx5ID8gRXh0ZW5kZWRTdGFja1NlbGVjdGlvbi5Ob25lIDogRXh0ZW5kZWRTdGFja1NlbGVjdGlvbi5VcHN0cmVhbSxcbiAgICAgICAgZGVmYXVsdEJlaGF2aW9yOiBEZWZhdWx0U2VsZWN0aW9uLk1haW5Bc3NlbWJseSxcbiAgICAgIH0sXG4gICAgKTtcblxuICAgIGNvbnN0IGFsbFN0YWNrcyA9IGF3YWl0IHRoaXMuc2VsZWN0U3RhY2tzRm9yTGlzdChbXSk7XG4gICAgY29uc3QgYXV0b1ZhbGlkYXRlU3RhY2tzID0gYXV0b1ZhbGlkYXRlXG4gICAgICA/IGFsbFN0YWNrcy5maWx0ZXIoKGFydCkgPT4gYXJ0LnZhbGlkYXRlT25TeW50aCA/PyBmYWxzZSlcbiAgICAgIDogbmV3IFN0YWNrQ29sbGVjdGlvbihhc3NlbWJseSwgW10pO1xuXG4gICAgdGhpcy52YWxpZGF0ZVN0YWNrc1NlbGVjdGVkKHNlbGVjdGVkRm9yRGlmZi5jb25jYXQoYXV0b1ZhbGlkYXRlU3RhY2tzKSwgc3RhY2tOYW1lcyk7XG4gICAgYXdhaXQgdGhpcy52YWxpZGF0ZVN0YWNrcyhzZWxlY3RlZEZvckRpZmYuY29uY2F0KGF1dG9WYWxpZGF0ZVN0YWNrcykpO1xuXG4gICAgcmV0dXJuIHNlbGVjdGVkRm9yRGlmZjtcbiAgfVxuXG4gIHByaXZhdGUgYXN5bmMgc2VsZWN0U3RhY2tzRm9yRGVzdHJveShzZWxlY3RvcjogU3RhY2tTZWxlY3RvciwgZXhjbHVzaXZlbHk/OiBib29sZWFuKSB7XG4gICAgY29uc3QgYXNzZW1ibHkgPSBhd2FpdCB0aGlzLmFzc2VtYmx5KCk7XG4gICAgY29uc3Qgc3RhY2tzID0gYXdhaXQgYXNzZW1ibHkuc2VsZWN0U3RhY2tzKHNlbGVjdG9yLCB7XG4gICAgICBleHRlbmQ6IGV4Y2x1c2l2ZWx5ID8gRXh0ZW5kZWRTdGFja1NlbGVjdGlvbi5Ob25lIDogRXh0ZW5kZWRTdGFja1NlbGVjdGlvbi5Eb3duc3RyZWFtLFxuICAgICAgZGVmYXVsdEJlaGF2aW9yOiBEZWZhdWx0U2VsZWN0aW9uLk9ubHlTaW5nbGUsXG4gICAgfSk7XG5cbiAgICAvLyBObyB2YWxpZGF0aW9uXG5cbiAgICByZXR1cm4gc3RhY2tzO1xuICB9XG5cbiAgLyoqXG4gICAqIFZhbGlkYXRlIHRoZSBzdGFja3MgZm9yIGVycm9ycyBhbmQgd2FybmluZ3MgYWNjb3JkaW5nIHRvIHRoZSBDTEkncyBjdXJyZW50IHNldHRpbmdzXG4gICAqL1xuICBwcml2YXRlIGFzeW5jIHZhbGlkYXRlU3RhY2tzKHN0YWNrczogU3RhY2tDb2xsZWN0aW9uKSB7XG4gICAgbGV0IGZhaWxBdDogJ3dhcm4nIHwgJ2Vycm9yJyB8ICdub25lJyA9ICdlcnJvcic7XG4gICAgaWYgKHRoaXMucHJvcHMuaWdub3JlRXJyb3JzKSB7IGZhaWxBdCA9ICdub25lJzsgfVxuICAgIGlmICh0aGlzLnByb3BzLnN0cmljdCkgeyBmYWlsQXQgPSAnd2Fybic7IH1cblxuICAgIGF3YWl0IHN0YWNrcy52YWxpZGF0ZU1ldGFkYXRhKGZhaWxBdCwgc3RhY2tNZXRhZGF0YUxvZ2dlcih0aGlzLnByb3BzLnZlcmJvc2UpKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBWYWxpZGF0ZSB0aGF0IGlmIGEgdXNlciBzcGVjaWZpZWQgYSBzdGFjayBuYW1lIHRoZXJlIGV4aXN0cyBhdCBsZWFzdCAxIHN0YWNrIHNlbGVjdGVkXG4gICAqL1xuICBwcml2YXRlIHZhbGlkYXRlU3RhY2tzU2VsZWN0ZWQoc3RhY2tzOiBTdGFja0NvbGxlY3Rpb24sIHN0YWNrTmFtZXM6IHN0cmluZ1tdKSB7XG4gICAgaWYgKHN0YWNrTmFtZXMubGVuZ3RoICE9IDAgJiYgc3RhY2tzLnN0YWNrQ291bnQgPT0gMCkge1xuICAgICAgdGhyb3cgbmV3IFRvb2xraXRFcnJvcihgTm8gc3RhY2tzIG1hdGNoIHRoZSBuYW1lKHMpICR7c3RhY2tOYW1lc31gKTtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogU2VsZWN0IGEgc2luZ2xlIHN0YWNrIGJ5IGl0cyBuYW1lXG4gICAqL1xuICBwcml2YXRlIGFzeW5jIHNlbGVjdFNpbmdsZVN0YWNrQnlOYW1lKHN0YWNrTmFtZTogc3RyaW5nKSB7XG4gICAgY29uc3QgYXNzZW1ibHkgPSBhd2FpdCB0aGlzLmFzc2VtYmx5KCk7XG5cbiAgICBjb25zdCBzdGFja3MgPSBhd2FpdCBhc3NlbWJseS5zZWxlY3RTdGFja3MoXG4gICAgICB7IHBhdHRlcm5zOiBbc3RhY2tOYW1lXSB9LFxuICAgICAge1xuICAgICAgICBleHRlbmQ6IEV4dGVuZGVkU3RhY2tTZWxlY3Rpb24uTm9uZSxcbiAgICAgICAgZGVmYXVsdEJlaGF2aW9yOiBEZWZhdWx0U2VsZWN0aW9uLk5vbmUsXG4gICAgICB9LFxuICAgICk7XG5cbiAgICAvLyBDb3VsZCBoYXZlIGJlZW4gYSBnbG9iIHNvIGNoZWNrIHRoYXQgd2UgZXZhbHVhdGVkIHRvIGV4YWN0bHkgb25lXG4gICAgaWYgKHN0YWNrcy5zdGFja0NvdW50ID4gMSkge1xuICAgICAgdGhyb3cgbmV3IFRvb2xraXRFcnJvcihgVGhpcyBjb21tYW5kIHJlcXVpcmVzIGV4YWN0bHkgb25lIHN0YWNrIGFuZCB3ZSBtYXRjaGVkIG1vcmUgdGhhbiBvbmU6ICR7c3RhY2tzLnN0YWNrSWRzfWApO1xuICAgIH1cblxuICAgIHJldHVybiBhc3NlbWJseS5zdGFja0J5SWQoc3RhY2tzLmZpcnN0U3RhY2suaWQpO1xuICB9XG5cbiAgcHVibGljIGFzc2VtYmx5KGNhY2hlQ2xvdWRBc3NlbWJseT86IGJvb2xlYW4pOiBQcm9taXNlPENsb3VkQXNzZW1ibHk+IHtcbiAgICByZXR1cm4gdGhpcy5wcm9wcy5jbG91ZEV4ZWN1dGFibGUuc3ludGhlc2l6ZShjYWNoZUNsb3VkQXNzZW1ibHkpO1xuICB9XG5cbiAgcHJpdmF0ZSBwYXR0ZXJuc0FycmF5Rm9yV2F0Y2goXG4gICAgcGF0dGVybnM6IHN0cmluZyB8IHN0cmluZ1tdIHwgdW5kZWZpbmVkLFxuICAgIG9wdGlvbnM6IHsgcm9vdERpcjogc3RyaW5nOyByZXR1cm5Sb290RGlySWZFbXB0eTogYm9vbGVhbiB9LFxuICApOiBzdHJpbmdbXSB7XG4gICAgY29uc3QgcGF0dGVybnNBcnJheTogc3RyaW5nW10gPSBwYXR0ZXJucyAhPT0gdW5kZWZpbmVkID8gKEFycmF5LmlzQXJyYXkocGF0dGVybnMpID8gcGF0dGVybnMgOiBbcGF0dGVybnNdKSA6IFtdO1xuICAgIHJldHVybiBwYXR0ZXJuc0FycmF5Lmxlbmd0aCA+IDAgPyBwYXR0ZXJuc0FycmF5IDogb3B0aW9ucy5yZXR1cm5Sb290RGlySWZFbXB0eSA/IFtvcHRpb25zLnJvb3REaXJdIDogW107XG4gIH1cblxuICBwcml2YXRlIGFzeW5jIGludm9rZURlcGxveUZyb21XYXRjaChcbiAgICBvcHRpb25zOiBXYXRjaE9wdGlvbnMsXG4gICAgY2xvdWRXYXRjaExvZ01vbml0b3I/OiBDbG91ZFdhdGNoTG9nRXZlbnRNb25pdG9yLFxuICApOiBQcm9taXNlPHZvaWQ+IHtcbiAgICBjb25zdCBkZXBsb3lPcHRpb25zOiBEZXBsb3lPcHRpb25zID0ge1xuICAgICAgLi4ub3B0aW9ucyxcbiAgICAgIHJlcXVpcmVBcHByb3ZhbDogUmVxdWlyZUFwcHJvdmFsLk5ldmVyLFxuICAgICAgLy8gaWYgJ3dhdGNoJyBpcyBjYWxsZWQgYnkgaW52b2tpbmcgJ2NkayBkZXBsb3kgLS13YXRjaCcsXG4gICAgICAvLyB3ZSBuZWVkIHRvIG1ha2Ugc3VyZSB0byBub3QgY2FsbCAnZGVwbG95JyB3aXRoICd3YXRjaCcgYWdhaW4sXG4gICAgICAvLyBhcyB0aGF0IHdvdWxkIGxlYWQgdG8gYSBjeWNsZVxuICAgICAgd2F0Y2g6IGZhbHNlLFxuICAgICAgY2xvdWRXYXRjaExvZ01vbml0b3IsXG4gICAgICBjYWNoZUNsb3VkQXNzZW1ibHk6IGZhbHNlLFxuICAgICAgaG90c3dhcDogb3B0aW9ucy5ob3Rzd2FwLFxuICAgICAgZXh0cmFVc2VyQWdlbnQ6IGBjZGstd2F0Y2gvaG90c3dhcC0ke29wdGlvbnMuaG90c3dhcCAhPT0gSG90c3dhcE1vZGUuRkFMTF9CQUNLID8gJ29uJyA6ICdvZmYnfWAsXG4gICAgICBjb25jdXJyZW5jeTogb3B0aW9ucy5jb25jdXJyZW5jeSxcbiAgICB9O1xuXG4gICAgdHJ5IHtcbiAgICAgIGF3YWl0IHRoaXMuZGVwbG95KGRlcGxveU9wdGlvbnMpO1xuICAgIH0gY2F0Y2gge1xuICAgICAgLy8ganVzdCBjb250aW51ZSAtIGRlcGxveSB3aWxsIHNob3cgdGhlIGVycm9yXG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIFJlbW92ZSB0aGUgYXNzZXQgcHVibGlzaGluZyBhbmQgYnVpbGRpbmcgZnJvbSB0aGUgd29yayBncmFwaCBmb3IgYXNzZXRzIHRoYXQgYXJlIGFscmVhZHkgaW4gcGxhY2VcbiAgICovXG4gIHByaXZhdGUgYXN5bmMgcmVtb3ZlUHVibGlzaGVkQXNzZXRzKGdyYXBoOiBXb3JrR3JhcGgsIG9wdGlvbnM6IERlcGxveU9wdGlvbnMpIHtcbiAgICBhd2FpdCBncmFwaC5yZW1vdmVVbm5lY2Vzc2FyeUFzc2V0cyhhc3NldE5vZGUgPT4gdGhpcy5wcm9wcy5kZXBsb3ltZW50cy5pc1NpbmdsZUFzc2V0UHVibGlzaGVkKGFzc2V0Tm9kZS5hc3NldE1hbmlmZXN0LCBhc3NldE5vZGUuYXNzZXQsIHtcbiAgICAgIHN0YWNrOiBhc3NldE5vZGUucGFyZW50U3RhY2ssXG4gICAgICByb2xlQXJuOiBvcHRpb25zLnJvbGVBcm4sXG4gICAgICBzdGFja05hbWU6IGFzc2V0Tm9kZS5wYXJlbnRTdGFjay5zdGFja05hbWUsXG4gICAgfSkpO1xuICB9XG59XG5cbi8qKlxuICogUHJpbnQgYSBzZXJpYWxpemVkIG9iamVjdCAoWUFNTCBvciBKU09OKSB0byBzdGRvdXQuXG4gKi9cbmZ1bmN0aW9uIHByaW50U2VyaWFsaXplZE9iamVjdChvYmo6IGFueSwganNvbjogYm9vbGVhbikge1xuICBsb2dSZXN1bHQoc2VyaWFsaXplU3RydWN0dXJlKG9iaiwganNvbikpO1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIERpZmZPcHRpb25zIHtcbiAgLyoqXG4gICAqIFN0YWNrIG5hbWVzIHRvIGRpZmZcbiAgICovXG4gIHN0YWNrTmFtZXM6IHN0cmluZ1tdO1xuXG4gIC8qKlxuICAgKiBOYW1lIG9mIHRoZSB0b29sa2l0IHN0YWNrLCBpZiBub3QgdGhlIGRlZmF1bHQgbmFtZVxuICAgKlxuICAgKiBAZGVmYXVsdCAnQ0RLVG9vbGtpdCdcbiAgICovXG4gIHJlYWRvbmx5IHRvb2xraXRTdGFja05hbWU/OiBzdHJpbmc7XG5cbiAgLyoqXG4gICAqIE9ubHkgc2VsZWN0IHRoZSBnaXZlbiBzdGFja1xuICAgKlxuICAgKiBAZGVmYXVsdCBmYWxzZVxuICAgKi9cbiAgZXhjbHVzaXZlbHk/OiBib29sZWFuO1xuXG4gIC8qKlxuICAgKiBVc2VkIGEgdGVtcGxhdGUgZnJvbSBkaXNrIGluc3RlYWQgb2YgZnJvbSB0aGUgc2VydmVyXG4gICAqXG4gICAqIEBkZWZhdWx0IFVzZSBmcm9tIHRoZSBzZXJ2ZXJcbiAgICovXG4gIHRlbXBsYXRlUGF0aD86IHN0cmluZztcblxuICAvKipcbiAgICogU3RyaWN0IGRpZmYgbW9kZVxuICAgKlxuICAgKiBAZGVmYXVsdCBmYWxzZVxuICAgKi9cbiAgc3RyaWN0PzogYm9vbGVhbjtcblxuICAvKipcbiAgICogSG93IG1hbnkgbGluZXMgb2YgY29udGV4dCB0byBzaG93IGluIHRoZSBkaWZmXG4gICAqXG4gICAqIEBkZWZhdWx0IDNcbiAgICovXG4gIGNvbnRleHRMaW5lcz86IG51bWJlcjtcblxuICAvKipcbiAgICogV2hlcmUgdG8gd3JpdGUgdGhlIGRlZmF1bHRcbiAgICpcbiAgICogQGRlZmF1bHQgc3RkZXJyXG4gICAqL1xuICBzdHJlYW0/OiBOb2RlSlMuV3JpdGFibGVTdHJlYW07XG5cbiAgLyoqXG4gICAqIFdoZXRoZXIgdG8gZmFpbCB3aXRoIGV4aXQgY29kZSAxIGluIGNhc2Ugb2YgZGlmZlxuICAgKlxuICAgKiBAZGVmYXVsdCBmYWxzZVxuICAgKi9cbiAgZmFpbD86IGJvb2xlYW47XG5cbiAgLyoqXG4gICAqIE9ubHkgcnVuIGRpZmYgb24gYnJvYWRlbmVkIHNlY3VyaXR5IGNoYW5nZXNcbiAgICpcbiAgICogQGRlZmF1bHQgZmFsc2VcbiAgICovXG4gIHNlY3VyaXR5T25seT86IGJvb2xlYW47XG5cbiAgLyoqXG4gICAqIFdoZXRoZXIgdG8gcnVuIHRoZSBkaWZmIGFnYWluc3QgdGhlIHRlbXBsYXRlIGFmdGVyIHRoZSBDbG91ZEZvcm1hdGlvbiBUcmFuc2Zvcm1zIGluc2lkZSBpdCBoYXZlIGJlZW4gZXhlY3V0ZWRcbiAgICogKGFzIG9wcG9zZWQgdG8gdGhlIG9yaWdpbmFsIHRlbXBsYXRlLCB0aGUgZGVmYXVsdCwgd2hpY2ggY29udGFpbnMgdGhlIHVucHJvY2Vzc2VkIFRyYW5zZm9ybXMpLlxuICAgKlxuICAgKiBAZGVmYXVsdCBmYWxzZVxuICAgKi9cbiAgY29tcGFyZUFnYWluc3RQcm9jZXNzZWRUZW1wbGF0ZT86IGJvb2xlYW47XG5cbiAgLypcbiAgICogUnVuIGRpZmYgaW4gcXVpZXQgbW9kZSB3aXRob3V0IHByaW50aW5nIHRoZSBkaWZmIHN0YXR1c2VzXG4gICAqXG4gICAqIEBkZWZhdWx0IGZhbHNlXG4gICAqL1xuICBxdWlldD86IGJvb2xlYW47XG5cbiAgLyoqXG4gICAqIEFkZGl0aW9uYWwgcGFyYW1ldGVycyBmb3IgQ2xvdWRGb3JtYXRpb24gYXQgZGlmZiB0aW1lLCB1c2VkIHRvIGNyZWF0ZSBhIGNoYW5nZSBzZXRcbiAgICogQGRlZmF1bHQge31cbiAgICovXG4gIHBhcmFtZXRlcnM/OiB7IFtuYW1lOiBzdHJpbmddOiBzdHJpbmcgfCB1bmRlZmluZWQgfTtcblxuICAvKipcbiAgICogV2hldGhlciBvciBub3QgdG8gY3JlYXRlLCBhbmFseXplLCBhbmQgc3Vic2VxdWVudGx5IGRlbGV0ZSBhIGNoYW5nZXNldFxuICAgKlxuICAgKiBAZGVmYXVsdCB0cnVlXG4gICAqL1xuICBjaGFuZ2VTZXQ/OiBib29sZWFuO1xufVxuXG5pbnRlcmZhY2UgQ2ZuRGVwbG95T3B0aW9ucyB7XG4gIC8qKlxuICAgKiBDcml0ZXJpYSBmb3Igc2VsZWN0aW5nIHN0YWNrcyB0byBkZXBsb3lcbiAgICovXG4gIHNlbGVjdG9yOiBTdGFja1NlbGVjdG9yO1xuXG4gIC8qKlxuICAgKiBOYW1lIG9mIHRoZSB0b29sa2l0IHN0YWNrIHRvIHVzZS9kZXBsb3lcbiAgICpcbiAgICogQGRlZmF1bHQgQ0RLVG9vbGtpdFxuICAgKi9cbiAgdG9vbGtpdFN0YWNrTmFtZT86IHN0cmluZztcblxuICAvKipcbiAgICogUm9sZSB0byBwYXNzIHRvIENsb3VkRm9ybWF0aW9uIGZvciBkZXBsb3ltZW50XG4gICAqL1xuICByb2xlQXJuPzogc3RyaW5nO1xuXG4gIC8qKlxuICAgKiBPcHRpb25hbCBuYW1lIHRvIHVzZSBmb3IgdGhlIENsb3VkRm9ybWF0aW9uIGNoYW5nZSBzZXQuXG4gICAqIElmIG5vdCBwcm92aWRlZCwgYSBuYW1lIHdpbGwgYmUgZ2VuZXJhdGVkIGF1dG9tYXRpY2FsbHkuXG4gICAqXG4gICAqIEBkZXByZWNhdGVkIFVzZSAnZGVwbG95bWVudE1ldGhvZCcgaW5zdGVhZFxuICAgKi9cbiAgY2hhbmdlU2V0TmFtZT86IHN0cmluZztcblxuICAvKipcbiAgICogV2hldGhlciB0byBleGVjdXRlIHRoZSBDaGFuZ2VTZXRcbiAgICogTm90IHByb3ZpZGluZyBgZXhlY3V0ZWAgcGFyYW1ldGVyIHdpbGwgcmVzdWx0IGluIGV4ZWN1dGlvbiBvZiBDaGFuZ2VTZXRcbiAgICpcbiAgICogQGRlZmF1bHQgdHJ1ZVxuICAgKiBAZGVwcmVjYXRlZCBVc2UgJ2RlcGxveW1lbnRNZXRob2QnIGluc3RlYWRcbiAgICovXG4gIGV4ZWN1dGU/OiBib29sZWFuO1xuXG4gIC8qKlxuICAgKiBEZXBsb3ltZW50IG1ldGhvZFxuICAgKi9cbiAgcmVhZG9ubHkgZGVwbG95bWVudE1ldGhvZD86IERlcGxveW1lbnRNZXRob2Q7XG5cbiAgLyoqXG4gICAqIERpc3BsYXkgbW9kZSBmb3Igc3RhY2sgZGVwbG95bWVudCBwcm9ncmVzcy5cbiAgICpcbiAgICogQGRlZmF1bHQgLSBTdGFja0FjdGl2aXR5UHJvZ3Jlc3MuQmFyIC0gc3RhY2sgZXZlbnRzIHdpbGwgYmUgZGlzcGxheWVkIGZvclxuICAgKiAgIHRoZSByZXNvdXJjZSBjdXJyZW50bHkgYmVpbmcgZGVwbG95ZWQuXG4gICAqL1xuICBwcm9ncmVzcz86IFN0YWNrQWN0aXZpdHlQcm9ncmVzcztcblxuICAvKipcbiAgICogUm9sbGJhY2sgZmFpbGVkIGRlcGxveW1lbnRzXG4gICAqXG4gICAqIEBkZWZhdWx0IHRydWVcbiAgICovXG4gIHJlYWRvbmx5IHJvbGxiYWNrPzogYm9vbGVhbjtcbn1cblxuaW50ZXJmYWNlIFdhdGNoT3B0aW9ucyBleHRlbmRzIE9taXQ8Q2ZuRGVwbG95T3B0aW9ucywgJ2V4ZWN1dGUnPiB7XG4gIC8qKlxuICAgKiBPbmx5IHNlbGVjdCB0aGUgZ2l2ZW4gc3RhY2tcbiAgICpcbiAgICogQGRlZmF1bHQgZmFsc2VcbiAgICovXG4gIGV4Y2x1c2l2ZWx5PzogYm9vbGVhbjtcblxuICAvKipcbiAgICogUmV1c2UgdGhlIGFzc2V0cyB3aXRoIHRoZSBnaXZlbiBhc3NldCBJRHNcbiAgICovXG4gIHJldXNlQXNzZXRzPzogc3RyaW5nW107XG5cbiAgLyoqXG4gICAqIEFsd2F5cyBkZXBsb3ksIGV2ZW4gaWYgdGVtcGxhdGVzIGFyZSBpZGVudGljYWwuXG4gICAqIEBkZWZhdWx0IGZhbHNlXG4gICAqL1xuICBmb3JjZT86IGJvb2xlYW47XG5cbiAgLyoqXG4gICAqIFdoZXRoZXIgdG8gcGVyZm9ybSBhICdob3Rzd2FwJyBkZXBsb3ltZW50LlxuICAgKiBBICdob3Rzd2FwJyBkZXBsb3ltZW50IHdpbGwgYXR0ZW1wdCB0byBzaG9ydC1jaXJjdWl0IENsb3VkRm9ybWF0aW9uXG4gICAqIGFuZCB1cGRhdGUgdGhlIGFmZmVjdGVkIHJlc291cmNlcyBsaWtlIExhbWJkYSBmdW5jdGlvbnMgZGlyZWN0bHkuXG4gICAqXG4gICAqIEBkZWZhdWx0IC0gYEhvdHN3YXBNb2RlLkZBTExfQkFDS2AgZm9yIHJlZ3VsYXIgZGVwbG95bWVudHMsIGBIb3Rzd2FwTW9kZS5IT1RTV0FQX09OTFlgIGZvciAnd2F0Y2gnIGRlcGxveW1lbnRzXG4gICAqL1xuICByZWFkb25seSBob3Rzd2FwOiBIb3Rzd2FwTW9kZTtcblxuICAvKipcbiAgICogVGhlIGV4dHJhIHN0cmluZyB0byBhcHBlbmQgdG8gdGhlIFVzZXItQWdlbnQgaGVhZGVyIHdoZW4gcGVyZm9ybWluZyBBV1MgU0RLIGNhbGxzLlxuICAgKlxuICAgKiBAZGVmYXVsdCAtIG5vdGhpbmcgZXh0cmEgaXMgYXBwZW5kZWQgdG8gdGhlIFVzZXItQWdlbnQgaGVhZGVyXG4gICAqL1xuICByZWFkb25seSBleHRyYVVzZXJBZ2VudD86IHN0cmluZztcblxuICAvKipcbiAgICogV2hldGhlciB0byBzaG93IENsb3VkV2F0Y2ggbG9ncyBmb3IgaG90c3dhcHBlZCByZXNvdXJjZXNcbiAgICogbG9jYWxseSBpbiB0aGUgdXNlcnMgdGVybWluYWxcbiAgICpcbiAgICogQGRlZmF1bHQgLSBmYWxzZVxuICAgKi9cbiAgcmVhZG9ubHkgdHJhY2VMb2dzPzogYm9vbGVhbjtcblxuICAvKipcbiAgICogTWF4aW11bSBudW1iZXIgb2Ygc2ltdWx0YW5lb3VzIGRlcGxveW1lbnRzIChkZXBlbmRlbmN5IHBlcm1pdHRpbmcpIHRvIGV4ZWN1dGUuXG4gICAqIFRoZSBkZWZhdWx0IGlzICcxJywgd2hpY2ggZXhlY3V0ZXMgYWxsIGRlcGxveW1lbnRzIHNlcmlhbGx5LlxuICAgKlxuICAgKiBAZGVmYXVsdCAxXG4gICAqL1xuICByZWFkb25seSBjb25jdXJyZW5jeT86IG51bWJlcjtcbn1cblxuZXhwb3J0IGludGVyZmFjZSBEZXBsb3lPcHRpb25zIGV4dGVuZHMgQ2ZuRGVwbG95T3B0aW9ucywgV2F0Y2hPcHRpb25zIHtcbiAgLyoqXG4gICAqIEFSTnMgb2YgU05TIHRvcGljcyB0aGF0IENsb3VkRm9ybWF0aW9uIHdpbGwgbm90aWZ5IHdpdGggc3RhY2sgcmVsYXRlZCBldmVudHNcbiAgICovXG4gIG5vdGlmaWNhdGlvbkFybnM/OiBzdHJpbmdbXTtcblxuICAvKipcbiAgICogV2hhdCBraW5kIG9mIHNlY3VyaXR5IGNoYW5nZXMgcmVxdWlyZSBhcHByb3ZhbFxuICAgKlxuICAgKiBAZGVmYXVsdCBSZXF1aXJlQXBwcm92YWwuQnJvYWRlbmluZ1xuICAgKi9cbiAgcmVxdWlyZUFwcHJvdmFsPzogUmVxdWlyZUFwcHJvdmFsO1xuXG4gIC8qKlxuICAgKiBUYWdzIHRvIHBhc3MgdG8gQ2xvdWRGb3JtYXRpb24gZm9yIGRlcGxveW1lbnRcbiAgICovXG4gIHRhZ3M/OiBUYWdbXTtcblxuICAvKipcbiAgICogQWRkaXRpb25hbCBwYXJhbWV0ZXJzIGZvciBDbG91ZEZvcm1hdGlvbiBhdCBkZXBsb3kgdGltZVxuICAgKiBAZGVmYXVsdCB7fVxuICAgKi9cbiAgcGFyYW1ldGVycz86IHsgW25hbWU6IHN0cmluZ106IHN0cmluZyB8IHVuZGVmaW5lZCB9O1xuXG4gIC8qKlxuICAgKiBVc2UgcHJldmlvdXMgdmFsdWVzIGZvciB1bnNwZWNpZmllZCBwYXJhbWV0ZXJzXG4gICAqXG4gICAqIElmIG5vdCBzZXQsIGFsbCBwYXJhbWV0ZXJzIG11c3QgYmUgc3BlY2lmaWVkIGZvciBldmVyeSBkZXBsb3ltZW50LlxuICAgKlxuICAgKiBAZGVmYXVsdCB0cnVlXG4gICAqL1xuICB1c2VQcmV2aW91c1BhcmFtZXRlcnM/OiBib29sZWFuO1xuXG4gIC8qKlxuICAgKiBQYXRoIHRvIGZpbGUgd2hlcmUgc3RhY2sgb3V0cHV0cyB3aWxsIGJlIHdyaXR0ZW4gYWZ0ZXIgYSBzdWNjZXNzZnVsIGRlcGxveSBhcyBKU09OXG4gICAqIEBkZWZhdWx0IC0gT3V0cHV0cyBhcmUgbm90IHdyaXR0ZW4gdG8gYW55IGZpbGVcbiAgICovXG4gIG91dHB1dHNGaWxlPzogc3RyaW5nO1xuXG4gIC8qKlxuICAgKiBXaGV0aGVyIHdlIGFyZSBvbiBhIENJIHN5c3RlbVxuICAgKlxuICAgKiBAZGVmYXVsdCBmYWxzZVxuICAgKi9cbiAgcmVhZG9ubHkgY2k/OiBib29sZWFuO1xuXG4gIC8qKlxuICAgKiBXaGV0aGVyIHRoaXMgJ2RlcGxveScgY29tbWFuZCBzaG91bGQgYWN0dWFsbHkgZGVsZWdhdGUgdG8gdGhlICd3YXRjaCcgY29tbWFuZC5cbiAgICpcbiAgICogQGRlZmF1bHQgZmFsc2VcbiAgICovXG4gIHJlYWRvbmx5IHdhdGNoPzogYm9vbGVhbjtcblxuICAvKipcbiAgICogV2hldGhlciB3ZSBzaG91bGQgY2FjaGUgdGhlIENsb3VkIEFzc2VtYmx5IGFmdGVyIHRoZSBmaXJzdCB0aW1lIGl0IGhhcyBiZWVuIHN5bnRoZXNpemVkLlxuICAgKiBUaGUgZGVmYXVsdCBpcyAndHJ1ZScsIHdlIG9ubHkgZG9uJ3Qgd2FudCB0byBkbyBpdCBpbiBjYXNlIHRoZSBkZXBsb3ltZW50IGlzIHRyaWdnZXJlZCBieVxuICAgKiAnY2RrIHdhdGNoJy5cbiAgICpcbiAgICogQGRlZmF1bHQgdHJ1ZVxuICAgKi9cbiAgcmVhZG9ubHkgY2FjaGVDbG91ZEFzc2VtYmx5PzogYm9vbGVhbjtcblxuICAvKipcbiAgICogQWxsb3dzIGFkZGluZyBDbG91ZFdhdGNoIGxvZyBncm91cHMgdG8gdGhlIGxvZyBtb25pdG9yIHZpYVxuICAgKiBjbG91ZFdhdGNoTG9nTW9uaXRvci5zZXRMb2dHcm91cHMoKTtcbiAgICpcbiAgICogQGRlZmF1bHQgLSBub3QgbW9uaXRvcmluZyBDbG91ZFdhdGNoIGxvZ3NcbiAgICovXG4gIHJlYWRvbmx5IGNsb3VkV2F0Y2hMb2dNb25pdG9yPzogQ2xvdWRXYXRjaExvZ0V2ZW50TW9uaXRvcjtcblxuICAvKipcbiAgICogTWF4aW11bSBudW1iZXIgb2Ygc2ltdWx0YW5lb3VzIGRlcGxveW1lbnRzIChkZXBlbmRlbmN5IHBlcm1pdHRpbmcpIHRvIGV4ZWN1dGUuXG4gICAqIFRoZSBkZWZhdWx0IGlzICcxJywgd2hpY2ggZXhlY3V0ZXMgYWxsIGRlcGxveW1lbnRzIHNlcmlhbGx5LlxuICAgKlxuICAgKiBAZGVmYXVsdCAxXG4gICAqL1xuICByZWFkb25seSBjb25jdXJyZW5jeT86IG51bWJlcjtcblxuICAvKipcbiAgICogQnVpbGQvcHVibGlzaCBhc3NldHMgZm9yIGEgc2luZ2xlIHN0YWNrIGluIHBhcmFsbGVsXG4gICAqXG4gICAqIEluZGVwZW5kZW50IG9mIHdoZXRoZXIgc3RhY2tzIGFyZSBiZWluZyBkb25lIGluIHBhcmFsbGVsIG9yIG5vLlxuICAgKlxuICAgKiBAZGVmYXVsdCB0cnVlXG4gICAqL1xuICByZWFkb25seSBhc3NldFBhcmFsbGVsaXNtPzogYm9vbGVhbjtcblxuICAvKipcbiAgICogV2hlbiB0byBidWlsZCBhc3NldHNcbiAgICpcbiAgICogVGhlIGRlZmF1bHQgaXMgdGhlIERvY2tlci1mcmllbmRseSBkZWZhdWx0LlxuICAgKlxuICAgKiBAZGVmYXVsdCBBc3NldEJ1aWxkVGltZS5BTExfQkVGT1JFX0RFUExPWVxuICAgKi9cbiAgcmVhZG9ubHkgYXNzZXRCdWlsZFRpbWU/OiBBc3NldEJ1aWxkVGltZTtcblxuICAvKipcbiAgICogV2hldGhlciB0byBkZXBsb3kgaWYgdGhlIGFwcCBjb250YWlucyBubyBzdGFja3MuXG4gICAqXG4gICAqIEBkZWZhdWx0IGZhbHNlXG4gICAqL1xuICByZWFkb25seSBpZ25vcmVOb1N0YWNrcz86IGJvb2xlYW47XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgUm9sbGJhY2tPcHRpb25zIHtcbiAgLyoqXG4gICAqIENyaXRlcmlhIGZvciBzZWxlY3Rpbmcgc3RhY2tzIHRvIGRlcGxveVxuICAgKi9cbiAgcmVhZG9ubHkgc2VsZWN0b3I6IFN0YWNrU2VsZWN0b3I7XG5cbiAgLyoqXG4gICAqIE5hbWUgb2YgdGhlIHRvb2xraXQgc3RhY2sgdG8gdXNlL2RlcGxveVxuICAgKlxuICAgKiBAZGVmYXVsdCBDREtUb29sa2l0XG4gICAqL1xuICByZWFkb25seSB0b29sa2l0U3RhY2tOYW1lPzogc3RyaW5nO1xuXG4gIC8qKlxuICAgKiBSb2xlIHRvIHBhc3MgdG8gQ2xvdWRGb3JtYXRpb24gZm9yIGRlcGxveW1lbnRcbiAgICpcbiAgICogQGRlZmF1bHQgLSBEZWZhdWx0IHN0YWNrIHJvbGVcbiAgICovXG4gIHJlYWRvbmx5IHJvbGVBcm4/OiBzdHJpbmc7XG5cbiAgLyoqXG4gICAqIFdoZXRoZXIgdG8gZm9yY2UgdGhlIHJvbGxiYWNrIG9yIG5vdFxuICAgKlxuICAgKiBAZGVmYXVsdCBmYWxzZVxuICAgKi9cbiAgcmVhZG9ubHkgZm9yY2U/OiBib29sZWFuO1xuXG4gIC8qKlxuICAgKiBMb2dpY2FsIElEcyBvZiByZXNvdXJjZXMgdG8gb3JwaGFuXG4gICAqXG4gICAqIEBkZWZhdWx0IC0gTm8gb3JwaGFuaW5nXG4gICAqL1xuICByZWFkb25seSBvcnBoYW5Mb2dpY2FsSWRzPzogc3RyaW5nW107XG5cbiAgLyoqXG4gICAqIFdoZXRoZXIgdG8gdmFsaWRhdGUgdGhlIHZlcnNpb24gb2YgdGhlIGJvb3RzdHJhcCBzdGFjayBwZXJtaXNzaW9uc1xuICAgKlxuICAgKiBAZGVmYXVsdCB0cnVlXG4gICAqL1xuICByZWFkb25seSB2YWxpZGF0ZUJvb3RzdHJhcFN0YWNrVmVyc2lvbj86IGJvb2xlYW47XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgSW1wb3J0T3B0aW9ucyBleHRlbmRzIENmbkRlcGxveU9wdGlvbnMge1xuICAvKipcbiAgICogQnVpbGQgYSBwaHlzaWNhbCByZXNvdXJjZSBtYXBwaW5nIGFuZCB3cml0ZSBpdCB0byB0aGUgZ2l2ZW4gZmlsZSwgd2l0aG91dCBwZXJmb3JtaW5nIHRoZSBhY3R1YWwgaW1wb3J0IG9wZXJhdGlvblxuICAgKlxuICAgKiBAZGVmYXVsdCAtIE5vIGZpbGVcbiAgICovXG5cbiAgcmVhZG9ubHkgcmVjb3JkUmVzb3VyY2VNYXBwaW5nPzogc3RyaW5nO1xuXG4gIC8qKlxuICAgKiBQYXRoIHRvIGEgZmlsZSB3aXRoIHRoZSBwaHlzaWNhbCByZXNvdXJjZSBtYXBwaW5nIHRvIENESyBjb25zdHJ1Y3RzIGluIEpTT04gZm9ybWF0XG4gICAqXG4gICAqIEBkZWZhdWx0IC0gTm8gbWFwcGluZyBmaWxlXG4gICAqL1xuICByZWFkb25seSByZXNvdXJjZU1hcHBpbmdGaWxlPzogc3RyaW5nO1xuXG4gIC8qKlxuICAgKiBBbGxvdyBub24tYWRkaXRpb24gY2hhbmdlcyB0byB0aGUgdGVtcGxhdGVcbiAgICpcbiAgICogQGRlZmF1bHQgZmFsc2VcbiAgICovXG4gIHJlYWRvbmx5IGZvcmNlPzogYm9vbGVhbjtcbn1cblxuZXhwb3J0IGludGVyZmFjZSBEZXN0cm95T3B0aW9ucyB7XG4gIC8qKlxuICAgKiBDcml0ZXJpYSBmb3Igc2VsZWN0aW5nIHN0YWNrcyB0byBkZXBsb3lcbiAgICovXG4gIHNlbGVjdG9yOiBTdGFja1NlbGVjdG9yO1xuXG4gIC8qKlxuICAgKiBXaGV0aGVyIHRvIGV4Y2x1ZGUgc3RhY2tzIHRoYXQgZGVwZW5kIG9uIHRoZSBzdGFja3MgdG8gYmUgZGVsZXRlZFxuICAgKi9cbiAgZXhjbHVzaXZlbHk6IGJvb2xlYW47XG5cbiAgLyoqXG4gICAqIFdoZXRoZXIgdG8gc2tpcCBwcm9tcHRpbmcgZm9yIGNvbmZpcm1hdGlvblxuICAgKi9cbiAgZm9yY2U6IGJvb2xlYW47XG5cbiAgLyoqXG4gICAqIFRoZSBhcm4gb2YgdGhlIElBTSByb2xlIHRvIHVzZVxuICAgKi9cbiAgcm9sZUFybj86IHN0cmluZztcblxuICAvKipcbiAgICogV2hldGhlciB0aGUgZGVzdHJveSByZXF1ZXN0IGNhbWUgZnJvbSBhIGRlcGxveS5cbiAgICovXG4gIGZyb21EZXBsb3k/OiBib29sZWFuO1xuXG4gIC8qKlxuICAgKiBXaGV0aGVyIHdlIGFyZSBvbiBhIENJIHN5c3RlbVxuICAgKlxuICAgKiBAZGVmYXVsdCBmYWxzZVxuICAgKi9cbiAgcmVhZG9ubHkgY2k/OiBib29sZWFuO1xufVxuXG4vKipcbiAqIE9wdGlvbnMgZm9yIHRoZSBnYXJiYWdlIGNvbGxlY3Rpb25cbiAqL1xuZXhwb3J0IGludGVyZmFjZSBHYXJiYWdlQ29sbGVjdGlvbk9wdGlvbnMge1xuICAvKipcbiAgICogVGhlIGFjdGlvbiB0byBwZXJmb3JtLlxuICAgKlxuICAgKiBAZGVmYXVsdCAnZnVsbCdcbiAgICovXG4gIHJlYWRvbmx5IGFjdGlvbjogJ3ByaW50JyB8ICd0YWcnIHwgJ2RlbGV0ZS10YWdnZWQnIHwgJ2Z1bGwnO1xuXG4gIC8qKlxuICAgKiBUaGUgdHlwZSBvZiB0aGUgYXNzZXRzIHRvIGJlIGdhcmJhZ2UgY29sbGVjdGVkLlxuICAgKlxuICAgKiBAZGVmYXVsdCAnYWxsJ1xuICAgKi9cbiAgcmVhZG9ubHkgdHlwZTogJ3MzJyB8ICdlY3InIHwgJ2FsbCc7XG5cbiAgLyoqXG4gICAqIEVsYXBzZWQgdGltZSBiZXR3ZWVuIGFuIGFzc2V0IGJlaW5nIG1hcmtlZCBhcyBpc29sYXRlZCBhbmQgYWN0dWFsbHkgZGVsZXRlZC5cbiAgICpcbiAgICogQGRlZmF1bHQgMFxuICAgKi9cbiAgcmVhZG9ubHkgcm9sbGJhY2tCdWZmZXJEYXlzOiBudW1iZXI7XG5cbiAgLyoqXG4gICAqIFJlZnVzZSBkZWxldGlvbiBvZiBhbnkgYXNzZXRzIHlvdW5nZXIgdGhhbiB0aGlzIG51bWJlciBvZiBkYXlzLlxuICAgKi9cbiAgcmVhZG9ubHkgY3JlYXRlZEJ1ZmZlckRheXM6IG51bWJlcjtcblxuICAvKipcbiAgICogVGhlIHN0YWNrIG5hbWUgb2YgdGhlIGJvb3RzdHJhcCBzdGFjay5cbiAgICpcbiAgICogQGRlZmF1bHQgREVGQVVMVF9UT09MS0lUX1NUQUNLX05BTUVcbiAgICovXG4gIHJlYWRvbmx5IGJvb3RzdHJhcFN0YWNrTmFtZT86IHN0cmluZztcblxuICAvKipcbiAgICogU2tpcHMgdGhlIHByb21wdCBiZWZvcmUgYWN0dWFsIGRlbGV0aW9uIGJlZ2luc1xuICAgKlxuICAgKiBAZGVmYXVsdCBmYWxzZVxuICAgKi9cbiAgcmVhZG9ubHkgY29uZmlybT86IGJvb2xlYW47XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgTWlncmF0ZU9wdGlvbnMge1xuICAvKipcbiAgICogVGhlIG5hbWUgYXNzaWduZWQgdG8gdGhlIGdlbmVyYXRlZCBzdGFjay4gVGhpcyBpcyBhbHNvIHVzZWQgdG8gZ2V0XG4gICAqIHRoZSBzdGFjayBmcm9tIHRoZSB1c2VyJ3MgYWNjb3VudCBpZiBgLS1mcm9tLXN0YWNrYCBpcyB1c2VkLlxuICAgKi9cbiAgcmVhZG9ubHkgc3RhY2tOYW1lOiBzdHJpbmc7XG5cbiAgLyoqXG4gICAqIFRoZSB0YXJnZXQgbGFuZ3VhZ2UgZm9yIHRoZSBnZW5lcmF0ZWQgdGhlIENESyBhcHAuXG4gICAqXG4gICAqIEBkZWZhdWx0IHR5cGVzY3JpcHRcbiAgICovXG4gIHJlYWRvbmx5IGxhbmd1YWdlPzogc3RyaW5nO1xuXG4gIC8qKlxuICAgKiBUaGUgbG9jYWwgcGF0aCBvZiB0aGUgdGVtcGxhdGUgdXNlZCB0byBnZW5lcmF0ZSB0aGUgQ0RLIGFwcC5cbiAgICpcbiAgICogQGRlZmF1bHQgLSBMb2NhbCBwYXRoIGlzIG5vdCB1c2VkIGZvciB0aGUgdGVtcGxhdGUgc291cmNlLlxuICAgKi9cbiAgcmVhZG9ubHkgZnJvbVBhdGg/OiBzdHJpbmc7XG5cbiAgLyoqXG4gICAqIFdoZXRoZXIgdG8gZ2V0IHRoZSB0ZW1wbGF0ZSBmcm9tIGFuIGV4aXN0aW5nIENsb3VkRm9ybWF0aW9uIHN0YWNrLlxuICAgKlxuICAgKiBAZGVmYXVsdCBmYWxzZVxuICAgKi9cbiAgcmVhZG9ubHkgZnJvbVN0YWNrPzogYm9vbGVhbjtcblxuICAvKipcbiAgICogVGhlIG91dHB1dCBwYXRoIGF0IHdoaWNoIHRvIGNyZWF0ZSB0aGUgQ0RLIGFwcC5cbiAgICpcbiAgICogQGRlZmF1bHQgLSBUaGUgY3VycmVudCBkaXJlY3RvcnlcbiAgICovXG4gIHJlYWRvbmx5IG91dHB1dFBhdGg/OiBzdHJpbmc7XG5cbiAgLyoqXG4gICAqIFRoZSBhY2NvdW50IGZyb20gd2hpY2ggdG8gcmV0cmlldmUgdGhlIHRlbXBsYXRlIG9mIHRoZSBDbG91ZEZvcm1hdGlvbiBzdGFjay5cbiAgICpcbiAgICogQGRlZmF1bHQgLSBVc2VzIHRoZSBhY2NvdW50IGZvciB0aGUgY3JlZGVudGlhbHMgaW4gdXNlIGJ5IHRoZSB1c2VyLlxuICAgKi9cbiAgcmVhZG9ubHkgYWNjb3VudD86IHN0cmluZztcblxuICAvKipcbiAgICogVGhlIHJlZ2lvbiBmcm9tIHdoaWNoIHRvIHJldHJpZXZlIHRoZSB0ZW1wbGF0ZSBvZiB0aGUgQ2xvdWRGb3JtYXRpb24gc3RhY2suXG4gICAqXG4gICAqIEBkZWZhdWx0IC0gVXNlcyB0aGUgZGVmYXVsdCByZWdpb24gZm9yIHRoZSBjcmVkZW50aWFscyBpbiB1c2UgYnkgdGhlIHVzZXIuXG4gICAqL1xuICByZWFkb25seSByZWdpb24/OiBzdHJpbmc7XG5cbiAgLyoqXG4gICAqIEZpbHRlcmluZyBjcml0ZXJpYSB1c2VkIHRvIHNlbGVjdCB0aGUgcmVzb3VyY2VzIHRvIGJlIGluY2x1ZGVkIGluIHRoZSBnZW5lcmF0ZWQgQ0RLIGFwcC5cbiAgICpcbiAgICogQGRlZmF1bHQgLSBJbmNsdWRlIGFsbCByZXNvdXJjZXNcbiAgICovXG4gIHJlYWRvbmx5IGZpbHRlcj86IHN0cmluZ1tdO1xuXG4gIC8qKlxuICAgKiBXaGV0aGVyIHRvIGluaXRpYXRlIGEgbmV3IGFjY291bnQgc2NhbiBmb3IgZ2VuZXJhdGluZyB0aGUgQ0RLIGFwcC5cbiAgICpcbiAgICogQGRlZmF1bHQgZmFsc2VcbiAgICovXG4gIHJlYWRvbmx5IGZyb21TY2FuPzogRnJvbVNjYW47XG5cbiAgLyoqXG4gICAqIFdoZXRoZXIgdG8gemlwIHRoZSBnZW5lcmF0ZWQgY2RrIGFwcCBmb2xkZXIuXG4gICAqXG4gICAqIEBkZWZhdWx0IGZhbHNlXG4gICAqL1xuICByZWFkb25seSBjb21wcmVzcz86IGJvb2xlYW47XG59XG5cbmZ1bmN0aW9uIGJ1aWxkUGFyYW1ldGVyTWFwKFxuICBwYXJhbWV0ZXJzOlxuICB8IHtcbiAgICBbbmFtZTogc3RyaW5nXTogc3RyaW5nIHwgdW5kZWZpbmVkO1xuICB9XG4gIHwgdW5kZWZpbmVkLFxuKTogeyBbbmFtZTogc3RyaW5nXTogeyBbbmFtZTogc3RyaW5nXTogc3RyaW5nIHwgdW5kZWZpbmVkIH0gfSB7XG4gIGNvbnN0IHBhcmFtZXRlck1hcDoge1xuICAgIFtuYW1lOiBzdHJpbmddOiB7IFtuYW1lOiBzdHJpbmddOiBzdHJpbmcgfCB1bmRlZmluZWQgfTtcbiAgfSA9IHsgJyonOiB7fSB9O1xuICBmb3IgKGNvbnN0IGtleSBpbiBwYXJhbWV0ZXJzKSB7XG4gICAgaWYgKHBhcmFtZXRlcnMuaGFzT3duUHJvcGVydHkoa2V5KSkge1xuICAgICAgY29uc3QgW3N0YWNrLCBwYXJhbWV0ZXJdID0ga2V5LnNwbGl0KCc6JywgMik7XG4gICAgICBpZiAoIXBhcmFtZXRlcikge1xuICAgICAgICBwYXJhbWV0ZXJNYXBbJyonXVtzdGFja10gPSBwYXJhbWV0ZXJzW2tleV07XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBpZiAoIXBhcmFtZXRlck1hcFtzdGFja10pIHtcbiAgICAgICAgICBwYXJhbWV0ZXJNYXBbc3RhY2tdID0ge307XG4gICAgICAgIH1cbiAgICAgICAgcGFyYW1ldGVyTWFwW3N0YWNrXVtwYXJhbWV0ZXJdID0gcGFyYW1ldGVyc1trZXldO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIHJldHVybiBwYXJhbWV0ZXJNYXA7XG59XG5cbi8qKlxuICogQXNrIHRoZSB1c2VyIGZvciBhIHllcy9ubyBjb25maXJtYXRpb25cbiAqXG4gKiBBdXRvbWF0aWNhbGx5IGZhaWwgdGhlIGNvbmZpcm1hdGlvbiBpbiBjYXNlIHdlJ3JlIGluIGEgc2l0dWF0aW9uIHdoZXJlIHRoZSBjb25maXJtYXRpb25cbiAqIGNhbm5vdCBiZSBpbnRlcmFjdGl2ZWx5IG9idGFpbmVkIGZyb20gYSBodW1hbiBhdCB0aGUga2V5Ym9hcmQuXG4gKi9cbmFzeW5jIGZ1bmN0aW9uIGFza1VzZXJDb25maXJtYXRpb24oXG4gIGlvSG9zdDogQ2xpSW9Ib3N0LFxuICBjb25jdXJyZW5jeTogbnVtYmVyLFxuICBtb3RpdmF0aW9uOiBzdHJpbmcsXG4gIHF1ZXN0aW9uOiBzdHJpbmcsXG4pIHtcbiAgYXdhaXQgaW9Ib3N0LndpdGhDb3JrZWRMb2dnaW5nKGFzeW5jICgpID0+IHtcbiAgICAvLyBvbmx5IHRhbGsgdG8gdXNlciBpZiBTVERJTiBpcyBhIHRlcm1pbmFsIChvdGhlcndpc2UsIGZhaWwpXG4gICAgaWYgKCFURVNUSU5HICYmICFwcm9jZXNzLnN0ZGluLmlzVFRZKSB7XG4gICAgICB0aHJvdyBuZXcgVG9vbGtpdEVycm9yKGAke21vdGl2YXRpb259LCBidXQgdGVybWluYWwgKFRUWSkgaXMgbm90IGF0dGFjaGVkIHNvIHdlIGFyZSB1bmFibGUgdG8gZ2V0IGEgY29uZmlybWF0aW9uIGZyb20gdGhlIHVzZXJgKTtcbiAgICB9XG5cbiAgICAvLyBvbmx5IHRhbGsgdG8gdXNlciBpZiBjb25jdXJyZW5jeSBpcyAxIChvdGhlcndpc2UsIGZhaWwpXG4gICAgaWYgKGNvbmN1cnJlbmN5ID4gMSkge1xuICAgICAgdGhyb3cgbmV3IFRvb2xraXRFcnJvcihgJHttb3RpdmF0aW9ufSwgYnV0IGNvbmN1cnJlbmN5IGlzIGdyZWF0ZXIgdGhhbiAxIHNvIHdlIGFyZSB1bmFibGUgdG8gZ2V0IGEgY29uZmlybWF0aW9uIGZyb20gdGhlIHVzZXJgKTtcbiAgICB9XG5cbiAgICBjb25zdCBjb25maXJtZWQgPSBhd2FpdCBwcm9tcHRseS5jb25maXJtKGAke2NoYWxrLmN5YW4ocXVlc3Rpb24pfSAoeS9uKT9gKTtcbiAgICBpZiAoIWNvbmZpcm1lZCkgeyB0aHJvdyBuZXcgVG9vbGtpdEVycm9yKCdBYm9ydGVkIGJ5IHVzZXInKTsgfVxuICB9KTtcbn1cblxuLyoqXG4gKiBMb2dnZXIgZm9yIHByb2Nlc3Npbmcgc3RhY2sgbWV0YWRhdGFcbiAqL1xuZnVuY3Rpb24gc3RhY2tNZXRhZGF0YUxvZ2dlcih2ZXJib3NlPzogYm9vbGVhbik6IChsZXZlbDogJ2luZm8nIHwgJ2Vycm9yJyB8ICd3YXJuJywgbXNnOiBjeGFwaS5TeW50aGVzaXNNZXNzYWdlKSA9PiBQcm9taXNlPHZvaWQ+IHtcbiAgY29uc3QgbWFrZUxvZ2dlciA9IChsZXZlbDogc3RyaW5nKTogW2xvZ2dlcjogKG06IHN0cmluZykgPT4gdm9pZCwgcHJlZml4OiBzdHJpbmddID0+IHtcbiAgICBzd2l0Y2ggKGxldmVsKSB7XG4gICAgICBjYXNlICdlcnJvcic6XG4gICAgICAgIHJldHVybiBbZXJyb3IsICdFcnJvciddO1xuICAgICAgY2FzZSAnd2Fybic6XG4gICAgICAgIHJldHVybiBbd2FybmluZywgJ1dhcm5pbmcnXTtcbiAgICAgIGRlZmF1bHQ6XG4gICAgICAgIHJldHVybiBbaW5mbywgJ0luZm8nXTtcbiAgICB9XG4gIH07XG5cbiAgcmV0dXJuIGFzeW5jIChsZXZlbCwgbXNnKSA9PiB7XG4gICAgY29uc3QgW2xvZ0ZuLCBwcmVmaXhdID0gbWFrZUxvZ2dlcihsZXZlbCk7XG4gICAgbG9nRm4oYFske3ByZWZpeH0gYXQgJHttc2cuaWR9XSAke21zZy5lbnRyeS5kYXRhfWApO1xuXG4gICAgaWYgKHZlcmJvc2UgJiYgbXNnLmVudHJ5LnRyYWNlKSB7XG4gICAgICBsb2dGbihgICAke21zZy5lbnRyeS50cmFjZS5qb2luKCdcXG4gICcpfWApO1xuICAgIH1cbiAgfTtcbn1cbiJdfQ==