sonamu 0.10.11 → 0.10.13

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 (519) hide show
  1. package/dist/ai/agents/agent.d.ts +1 -1
  2. package/dist/ai/agents/agent.d.ts.map +1 -1
  3. package/dist/ai/agents/agent.js +5 -6
  4. package/dist/ai/agents/types.d.ts +1 -1
  5. package/dist/ai/agents/types.d.ts.map +1 -1
  6. package/dist/ai/providers/rtzr/api.js +18 -18
  7. package/dist/ai/providers/rtzr/error.d.ts.map +1 -1
  8. package/dist/ai/providers/rtzr/error.js +17 -15
  9. package/dist/ai/providers/rtzr/model.d.ts.map +1 -1
  10. package/dist/ai/providers/rtzr/model.js +3 -2
  11. package/dist/ai/providers/rtzr/options.d.ts.map +1 -1
  12. package/dist/ai/providers/rtzr/options.js +16 -16
  13. package/dist/ai/providers/rtzr/provider.d.ts.map +1 -1
  14. package/dist/ai/providers/rtzr/provider.js +9 -9
  15. package/dist/ai/providers/rtzr/utils.d.ts.map +1 -1
  16. package/dist/ai/providers/rtzr/utils.js +1 -1
  17. package/dist/api/caster.d.ts.map +1 -1
  18. package/dist/api/caster.js +17 -17
  19. package/dist/api/code-converters.d.ts +4 -2
  20. package/dist/api/code-converters.d.ts.map +1 -1
  21. package/dist/api/code-converters.js +100 -19
  22. package/dist/api/config.d.ts +16 -1
  23. package/dist/api/config.d.ts.map +1 -1
  24. package/dist/api/config.js +28 -21
  25. package/dist/api/context.d.ts +2 -2
  26. package/dist/api/context.d.ts.map +1 -1
  27. package/dist/api/context.js +1 -1
  28. package/dist/api/decorators.d.ts.map +1 -1
  29. package/dist/api/decorators.js +18 -11
  30. package/dist/api/http-validator.d.ts +36 -0
  31. package/dist/api/http-validator.d.ts.map +1 -0
  32. package/dist/api/http-validator.js +72 -0
  33. package/dist/api/index.js +6 -4
  34. package/dist/api/sonamu.d.ts +59 -20
  35. package/dist/api/sonamu.d.ts.map +1 -1
  36. package/dist/api/sonamu.js +250 -106
  37. package/dist/api/websocket-helpers.d.ts +7 -5
  38. package/dist/api/websocket-helpers.d.ts.map +1 -1
  39. package/dist/api/websocket-helpers.js +6 -6
  40. package/dist/auth/audit-log/builders.d.ts.map +1 -1
  41. package/dist/auth/audit-log/builders.js +1 -1
  42. package/dist/auth/audit-log/client-ip.d.ts +1 -1
  43. package/dist/auth/audit-log/client-ip.d.ts.map +1 -1
  44. package/dist/auth/audit-log/client-ip.js +4 -2
  45. package/dist/auth/audit-log/events.d.ts +5 -1
  46. package/dist/auth/audit-log/events.d.ts.map +1 -1
  47. package/dist/auth/audit-log/events.js +1 -1
  48. package/dist/auth/audit-log/plugin.d.ts +0 -8
  49. package/dist/auth/audit-log/plugin.d.ts.map +1 -1
  50. package/dist/auth/audit-log/plugin.js +48 -52
  51. package/dist/auth/audit-log-ingestor.d.ts.map +1 -1
  52. package/dist/auth/audit-log-ingestor.js +16 -12
  53. package/dist/auth/auth-generator.d.ts.map +1 -1
  54. package/dist/auth/auth-generator.js +1 -1
  55. package/dist/auth/better-auth-request.d.ts.map +1 -1
  56. package/dist/auth/better-auth-request.js +6 -5
  57. package/dist/auth/knex-adapter.js +1 -1
  58. package/dist/auth/plugins/entity-definitions/index.d.ts +13 -1
  59. package/dist/auth/plugins/entity-definitions/index.d.ts.map +1 -1
  60. package/dist/auth/plugins/entity-definitions/index.js +1 -1
  61. package/dist/auth/plugins/wrappers/admin.d.ts +1 -1
  62. package/dist/bin/build-config.d.ts +25 -0
  63. package/dist/bin/build-config.d.ts.map +1 -1
  64. package/dist/bin/build-config.js +105 -2
  65. package/dist/bin/cli.js +133 -29
  66. package/dist/bin/compiler-policy.d.ts +3 -0
  67. package/dist/bin/compiler-policy.d.ts.map +1 -0
  68. package/dist/bin/compiler-policy.js +24 -0
  69. package/dist/bin/fixture.d.ts.map +1 -1
  70. package/dist/bin/fixture.js +5 -3
  71. package/dist/bin/test-command.d.ts +22 -1
  72. package/dist/bin/test-command.d.ts.map +1 -1
  73. package/dist/bin/test-command.js +18 -10
  74. package/dist/bin/ts-loader-registration.d.ts +7 -1
  75. package/dist/bin/ts-loader-registration.d.ts.map +1 -1
  76. package/dist/bin/ts-loader-registration.js +13 -4
  77. package/dist/cache/decorator.d.ts.map +1 -1
  78. package/dist/cache/decorator.js +11 -4
  79. package/dist/compress/compress.d.ts.map +1 -1
  80. package/dist/compress/compress.js +1 -1
  81. package/dist/cone/cone-generator.d.ts +14 -1
  82. package/dist/cone/cone-generator.d.ts.map +1 -1
  83. package/dist/cone/cone-generator.js +13 -9
  84. package/dist/database/_batch_update.js +1 -1
  85. package/dist/database/base-model.d.ts +22 -10
  86. package/dist/database/base-model.d.ts.map +1 -1
  87. package/dist/database/base-model.js +26 -16
  88. package/dist/database/base-model.types.d.ts +15 -3
  89. package/dist/database/base-model.types.d.ts.map +1 -1
  90. package/dist/database/db.d.ts +12 -2
  91. package/dist/database/db.d.ts.map +1 -1
  92. package/dist/database/db.js +10 -7
  93. package/dist/database/knex.d.ts.map +1 -1
  94. package/dist/database/knex.js +17 -14
  95. package/dist/database/puri.d.ts +11 -9
  96. package/dist/database/puri.d.ts.map +1 -1
  97. package/dist/database/puri.js +93 -79
  98. package/dist/database/puri.types.d.ts +21 -21
  99. package/dist/database/puri.types.d.ts.map +1 -1
  100. package/dist/database/puri.types.js +1 -1
  101. package/dist/database/upsert-builder.d.ts +12 -10
  102. package/dist/database/upsert-builder.d.ts.map +1 -1
  103. package/dist/database/upsert-builder.js +20 -12
  104. package/dist/dict/sd.d.ts.map +1 -1
  105. package/dist/dict/sd.js +1 -1
  106. package/dist/dict/sonamu-dictionary.d.ts.map +1 -1
  107. package/dist/dict/sonamu-dictionary.js +1 -1
  108. package/dist/dict/utils.d.ts.map +1 -1
  109. package/dist/dict/utils.js +7 -2
  110. package/dist/entity/entity-manager.d.ts +13 -4
  111. package/dist/entity/entity-manager.d.ts.map +1 -1
  112. package/dist/entity/entity-manager.js +19 -11
  113. package/dist/entity/entity-template-cone.d.ts +73 -5
  114. package/dist/entity/entity-template-cone.d.ts.map +1 -1
  115. package/dist/entity/entity-template-cone.js +4 -2
  116. package/dist/entity/entity.d.ts +6 -2
  117. package/dist/entity/entity.d.ts.map +1 -1
  118. package/dist/entity/entity.js +30 -28
  119. package/dist/env.d.ts +3 -1
  120. package/dist/env.d.ts.map +1 -1
  121. package/dist/env.js +1 -1
  122. package/dist/exceptions/error-handler.d.ts.map +1 -1
  123. package/dist/exceptions/error-handler.js +7 -2
  124. package/dist/exceptions/so-exceptions.d.ts +24 -20
  125. package/dist/exceptions/so-exceptions.d.ts.map +1 -1
  126. package/dist/exceptions/so-exceptions.js +4 -2
  127. package/dist/filter/utils.d.ts +7 -2
  128. package/dist/filter/utils.d.ts.map +1 -1
  129. package/dist/filter/utils.js +8 -6
  130. package/dist/index.d.ts +3 -0
  131. package/dist/index.d.ts.map +1 -1
  132. package/dist/index.js +13 -7
  133. package/dist/logger/configure.d.ts.map +1 -1
  134. package/dist/logger/configure.js +10 -10
  135. package/dist/migration/code-generation.d.ts.map +1 -1
  136. package/dist/migration/code-generation.js +50 -46
  137. package/dist/migration/index-where-predicate.d.ts.map +1 -1
  138. package/dist/migration/index-where-predicate.js +22 -8
  139. package/dist/migration/migration-set.d.ts.map +1 -1
  140. package/dist/migration/migration-set.js +1 -1
  141. package/dist/migration/migrator.d.ts +61 -36
  142. package/dist/migration/migrator.d.ts.map +1 -1
  143. package/dist/migration/migrator.js +276 -167
  144. package/dist/migration/postgresql-schema-reader.d.ts.map +1 -1
  145. package/dist/migration/postgresql-schema-reader.js +51 -36
  146. package/dist/migration/slack-confirm.d.ts.map +1 -1
  147. package/dist/migration/slack-confirm.js +1 -1
  148. package/dist/migration/types.d.ts +54 -0
  149. package/dist/migration/types.d.ts.map +1 -1
  150. package/dist/naite/naite-reporter.js +2 -2
  151. package/dist/naite/naite.d.ts +74 -15
  152. package/dist/naite/naite.d.ts.map +1 -1
  153. package/dist/naite/naite.js +5 -19
  154. package/dist/runtime-type.d.ts +6 -0
  155. package/dist/runtime-type.d.ts.map +1 -0
  156. package/dist/runtime-type.js +26 -0
  157. package/dist/ssr/hmr-opt-out.d.ts +26 -0
  158. package/dist/ssr/hmr-opt-out.d.ts.map +1 -0
  159. package/dist/ssr/hmr-opt-out.js +59 -0
  160. package/dist/ssr/renderer.d.ts.map +1 -1
  161. package/dist/ssr/renderer.js +4 -1
  162. package/dist/storage/base-file.js +14 -14
  163. package/dist/storage/buffered-file.d.ts +2 -2
  164. package/dist/storage/buffered-file.d.ts.map +1 -1
  165. package/dist/storage/buffered-file.js +12 -12
  166. package/dist/storage/s3-driver.d.ts.map +1 -1
  167. package/dist/storage/s3-driver.js +1 -1
  168. package/dist/storage/uploaded-file.d.ts +2 -2
  169. package/dist/storage/uploaded-file.d.ts.map +1 -1
  170. package/dist/storage/uploaded-file.js +8 -8
  171. package/dist/stream/sse.js +11 -11
  172. package/dist/stream/ws-core.d.ts +1 -1
  173. package/dist/stream/ws-core.d.ts.map +1 -1
  174. package/dist/stream/ws-delivery.d.ts +1 -1
  175. package/dist/stream/ws-delivery.d.ts.map +1 -1
  176. package/dist/stream/ws-delivery.js +6 -4
  177. package/dist/stream/ws-local-connection-store.d.ts.map +1 -1
  178. package/dist/stream/ws-local-connection-store.js +4 -2
  179. package/dist/stream/ws-presence-store.js +1 -1
  180. package/dist/stream/ws-registry.d.ts +4 -4
  181. package/dist/stream/ws-registry.d.ts.map +1 -1
  182. package/dist/stream/ws-registry.js +4 -2
  183. package/dist/stream/ws-telemetry.d.ts +16 -12
  184. package/dist/stream/ws-telemetry.d.ts.map +1 -1
  185. package/dist/stream/ws-telemetry.js +22 -18
  186. package/dist/stream/ws.d.ts +18 -12
  187. package/dist/stream/ws.d.ts.map +1 -1
  188. package/dist/stream/ws.js +26 -22
  189. package/dist/syncer/api-parser.js +1 -1
  190. package/dist/syncer/checksum.d.ts.map +1 -1
  191. package/dist/syncer/checksum.js +7 -8
  192. package/dist/syncer/code-generator.d.ts.map +1 -1
  193. package/dist/syncer/code-generator.js +13 -14
  194. package/dist/syncer/entity-operations.d.ts.map +1 -1
  195. package/dist/syncer/entity-operations.js +5 -6
  196. package/dist/syncer/file-copy.d.ts +5 -0
  197. package/dist/syncer/file-copy.d.ts.map +1 -0
  198. package/dist/syncer/file-copy.js +36 -0
  199. package/dist/syncer/file-patterns.d.ts +1 -0
  200. package/dist/syncer/file-patterns.d.ts.map +1 -1
  201. package/dist/syncer/file-patterns.js +5 -2
  202. package/dist/syncer/file-tracking.d.ts.map +1 -1
  203. package/dist/syncer/file-tracking.js +5 -4
  204. package/dist/syncer/filesystem-dependencies.d.ts +15 -0
  205. package/dist/syncer/filesystem-dependencies.d.ts.map +1 -0
  206. package/dist/syncer/filesystem-dependencies.js +53 -0
  207. package/dist/syncer/module-loader.d.ts +1 -1
  208. package/dist/syncer/module-loader.d.ts.map +1 -1
  209. package/dist/syncer/module-loader.js +6 -4
  210. package/dist/syncer/syncer-actions.d.ts +4 -0
  211. package/dist/syncer/syncer-actions.d.ts.map +1 -1
  212. package/dist/syncer/syncer-actions.js +34 -17
  213. package/dist/syncer/syncer.d.ts +17 -6
  214. package/dist/syncer/syncer.d.ts.map +1 -1
  215. package/dist/syncer/syncer.js +71 -29
  216. package/dist/syncer/watcher.d.ts.map +1 -1
  217. package/dist/syncer/watcher.js +3 -3
  218. package/dist/tasks/decorator.d.ts +6 -6
  219. package/dist/tasks/decorator.d.ts.map +1 -1
  220. package/dist/tasks/decorator.js +4 -4
  221. package/dist/tasks/step-wrapper.d.ts +6 -4
  222. package/dist/tasks/step-wrapper.d.ts.map +1 -1
  223. package/dist/tasks/step-wrapper.js +5 -5
  224. package/dist/tasks/workflow-manager.d.ts.map +1 -1
  225. package/dist/tasks/workflow-manager.js +13 -7
  226. package/dist/template/entity-converter.d.ts +1 -1
  227. package/dist/template/entity-converter.d.ts.map +1 -1
  228. package/dist/template/entity-converter.js +2 -2
  229. package/dist/template/helpers.d.ts +8 -6
  230. package/dist/template/helpers.d.ts.map +1 -1
  231. package/dist/template/helpers.js +1 -1
  232. package/dist/template/implementations/generated.template.d.ts.map +1 -1
  233. package/dist/template/implementations/generated.template.js +4 -4
  234. package/dist/template/implementations/generated_http.template.d.ts +7 -4
  235. package/dist/template/implementations/generated_http.template.d.ts.map +1 -1
  236. package/dist/template/implementations/generated_http.template.js +21 -21
  237. package/dist/template/implementations/generated_sso.template.d.ts.map +1 -1
  238. package/dist/template/implementations/generated_sso.template.js +6 -3
  239. package/dist/template/implementations/http_validators.template.d.ts +18 -0
  240. package/dist/template/implementations/http_validators.template.d.ts.map +1 -0
  241. package/dist/template/implementations/http_validators.template.js +127 -0
  242. package/dist/template/implementations/model.template.d.ts.map +1 -1
  243. package/dist/template/implementations/model.template.js +1 -1
  244. package/dist/template/implementations/queries.template.js +1 -1
  245. package/dist/template/implementations/sd.template.d.ts.map +1 -1
  246. package/dist/template/implementations/sd.template.js +79 -39
  247. package/dist/template/implementations/services.template.d.ts.map +1 -1
  248. package/dist/template/implementations/services.template.js +6 -4
  249. package/dist/template/implementations/view_form.template.d.ts +6 -1
  250. package/dist/template/implementations/view_form.template.d.ts.map +1 -1
  251. package/dist/template/implementations/view_form.template.js +23 -15
  252. package/dist/template/implementations/view_list.template.d.ts.map +1 -1
  253. package/dist/template/implementations/view_list.template.js +11 -6
  254. package/dist/template/template-manager.d.ts.map +1 -1
  255. package/dist/template/template-manager.js +9 -7
  256. package/dist/template/template-types.d.ts +12 -5
  257. package/dist/template/template-types.d.ts.map +1 -1
  258. package/dist/template/template-types.js +1 -1
  259. package/dist/template/template.d.ts +2 -2
  260. package/dist/template/template.d.ts.map +1 -1
  261. package/dist/template/template.js +6 -4
  262. package/dist/template/zod-converter.d.ts +0 -19
  263. package/dist/template/zod-converter.d.ts.map +1 -1
  264. package/dist/template/zod-converter.js +100 -84
  265. package/dist/testing/_relation-graph.d.ts.map +1 -1
  266. package/dist/testing/_relation-graph.js +2 -1
  267. package/dist/testing/bootstrap.d.ts.map +1 -1
  268. package/dist/testing/bootstrap.js +9 -6
  269. package/dist/testing/data-explorer.d.ts +32 -7
  270. package/dist/testing/data-explorer.d.ts.map +1 -1
  271. package/dist/testing/data-explorer.js +77 -31
  272. package/dist/testing/dev-test-routes.d.ts +8 -1
  273. package/dist/testing/dev-test-routes.d.ts.map +1 -1
  274. package/dist/testing/dev-test-routes.js +125 -108
  275. package/dist/testing/dev-vitest-manager.d.ts +54 -8
  276. package/dist/testing/dev-vitest-manager.d.ts.map +1 -1
  277. package/dist/testing/dev-vitest-manager.js +24 -9
  278. package/dist/testing/faker-mappings.d.ts +412 -1
  279. package/dist/testing/faker-mappings.d.ts.map +1 -1
  280. package/dist/testing/faker-mappings.js +1 -1
  281. package/dist/testing/filesystem.d.ts +2 -0
  282. package/dist/testing/filesystem.d.ts.map +1 -0
  283. package/dist/testing/filesystem.js +7 -0
  284. package/dist/testing/fixture-generator.d.ts +25 -8
  285. package/dist/testing/fixture-generator.d.ts.map +1 -1
  286. package/dist/testing/fixture-generator.js +132 -73
  287. package/dist/testing/fixture-loader.d.ts +3 -1
  288. package/dist/testing/fixture-loader.d.ts.map +1 -1
  289. package/dist/testing/fixture-loader.js +1 -20
  290. package/dist/testing/fixture-manager.d.ts +8 -7
  291. package/dist/testing/fixture-manager.d.ts.map +1 -1
  292. package/dist/testing/fixture-manager.js +91 -59
  293. package/dist/testing/global-setup.d.ts.map +1 -1
  294. package/dist/testing/global-setup.js +5 -2
  295. package/dist/testing/index.d.ts +2 -0
  296. package/dist/testing/index.d.ts.map +1 -1
  297. package/dist/testing/index.js +6 -3
  298. package/dist/types/types.d.ts +101 -99
  299. package/dist/types/types.d.ts.map +1 -1
  300. package/dist/types/types.js +234 -225
  301. package/dist/ui/ai-api.d.ts.map +1 -1
  302. package/dist/ui/ai-api.js +1 -1
  303. package/dist/ui/ai-client.d.ts.map +1 -1
  304. package/dist/ui/ai-client.js +28 -18
  305. package/dist/ui/api.d.ts.map +1 -1
  306. package/dist/ui/api.js +146 -210
  307. package/dist/ui/async-route.d.ts +3 -0
  308. package/dist/ui/async-route.d.ts.map +1 -0
  309. package/dist/ui/async-route.js +12 -0
  310. package/dist/ui/cdd-service.d.ts +9 -7
  311. package/dist/ui/cdd-service.d.ts.map +1 -1
  312. package/dist/ui/cdd-service.js +7 -5
  313. package/dist/ui/migrations-api.d.ts +3 -0
  314. package/dist/ui/migrations-api.d.ts.map +1 -0
  315. package/dist/ui/migrations-api.js +215 -0
  316. package/dist/ui-web/assets/index-D3QNH-Dv.css +1 -0
  317. package/dist/ui-web/assets/index-DV1AAq6W.js +178 -0
  318. package/dist/ui-web/index.html +2 -2
  319. package/dist/utils/formatter.d.ts.map +1 -1
  320. package/dist/utils/formatter.js +7 -5
  321. package/dist/utils/fs-utils.d.ts +3 -3
  322. package/dist/utils/fs-utils.d.ts.map +1 -1
  323. package/dist/utils/fs-utils.js +6 -6
  324. package/dist/utils/model.d.ts +3 -5
  325. package/dist/utils/model.d.ts.map +1 -1
  326. package/dist/utils/model.js +1 -1
  327. package/dist/utils/object-utils.d.ts +1 -1
  328. package/dist/utils/object-utils.d.ts.map +1 -1
  329. package/dist/utils/object-utils.js +17 -16
  330. package/dist/utils/process-utils.d.ts.map +1 -1
  331. package/dist/utils/process-utils.js +4 -2
  332. package/dist/utils/runtime-value.d.ts +13 -0
  333. package/dist/utils/runtime-value.d.ts.map +1 -0
  334. package/dist/utils/runtime-value.js +40 -0
  335. package/dist/utils/sql-parser.d.ts +8 -1
  336. package/dist/utils/sql-parser.d.ts.map +1 -1
  337. package/dist/utils/sql-parser.js +6 -3
  338. package/dist/utils/type-utils.d.ts.map +1 -1
  339. package/dist/utils/type-utils.js +10 -8
  340. package/dist/utils/utils.d.ts +2 -2
  341. package/dist/utils/utils.d.ts.map +1 -1
  342. package/dist/utils/utils.js +11 -8
  343. package/dist/utils/zod-error.d.ts.map +1 -1
  344. package/dist/utils/zod-error.js +7 -4
  345. package/dist/vector/chunking.d.ts.map +1 -1
  346. package/dist/vector/chunking.js +1 -1
  347. package/dist/vector/embedding.d.ts.map +1 -1
  348. package/dist/vector/embedding.js +1 -1
  349. package/dist/vector/types.d.ts +3 -2
  350. package/dist/vector/types.d.ts.map +1 -1
  351. package/package.json +11 -7
  352. package/src/ai/agents/agent.ts +5 -5
  353. package/src/ai/agents/types.ts +1 -1
  354. package/src/ai/providers/rtzr/__tests__/model.test.ts +2 -2
  355. package/src/ai/providers/rtzr/error.ts +5 -3
  356. package/src/ai/providers/rtzr/model.ts +3 -2
  357. package/src/ai/providers/rtzr/options.ts +10 -5
  358. package/src/ai/providers/rtzr/provider.ts +10 -10
  359. package/src/ai/providers/rtzr/utils.ts +3 -1
  360. package/src/api/__tests__/config.test.ts +11 -21
  361. package/src/api/__tests__/sonamu.http-validator.test.ts +512 -0
  362. package/src/api/__tests__/sonamu.websocket.test.ts +51 -41
  363. package/src/api/__tests__/zod-compiler-policy.test.ts +95 -0
  364. package/src/api/caster.ts +6 -8
  365. package/src/api/code-converters.ts +136 -36
  366. package/src/api/config.ts +62 -4
  367. package/src/api/context.ts +3 -3
  368. package/src/api/decorators.ts +28 -17
  369. package/src/api/http-validator.ts +149 -0
  370. package/src/api/sonamu.ts +459 -152
  371. package/src/api/websocket-helpers.ts +24 -17
  372. package/src/auth/audit-log/builders.ts +3 -2
  373. package/src/auth/audit-log/client-ip.ts +4 -2
  374. package/src/auth/audit-log/events.ts +15 -1
  375. package/src/auth/audit-log/plugin.ts +129 -200
  376. package/src/auth/audit-log-ingestor.ts +19 -15
  377. package/src/auth/auth-generator.ts +10 -5
  378. package/src/auth/better-auth-request.ts +4 -3
  379. package/src/auth/knex-adapter.ts +8 -2
  380. package/src/auth/plugins/entity-definitions/index.ts +6 -5
  381. package/src/bin/__tests__/http-validator-benchmark.test.ts +94 -0
  382. package/src/bin/__tests__/test-command.test.ts +9 -15
  383. package/src/bin/__tests__/ts-loader-register.test.ts +15 -17
  384. package/src/bin/__tests__/zod-compiler-build.test.ts +307 -0
  385. package/src/bin/build-config.ts +167 -0
  386. package/src/bin/cli.ts +155 -38
  387. package/src/bin/compiler-policy.ts +35 -0
  388. package/src/bin/fixture.ts +14 -3
  389. package/src/bin/test-command.ts +74 -29
  390. package/src/bin/ts-loader-registration.ts +22 -4
  391. package/src/cache/decorator.ts +10 -3
  392. package/src/compress/compress.ts +17 -4
  393. package/src/cone/cone-generator.ts +34 -6
  394. package/src/database/__tests__/db.test.ts +1 -0
  395. package/src/database/__tests__/puri.test.ts +16 -15
  396. package/src/database/__tests__/transaction-scope.test.ts +5 -0
  397. package/src/database/_batch_update.ts +1 -0
  398. package/src/database/base-model.ts +81 -50
  399. package/src/database/base-model.types.ts +6 -6
  400. package/src/database/db.ts +29 -19
  401. package/src/database/knex.ts +30 -17
  402. package/src/database/puri-subset.test-d.ts +17 -0
  403. package/src/database/puri.ts +181 -143
  404. package/src/database/puri.types.test-d.ts +31 -1
  405. package/src/database/puri.types.ts +23 -21
  406. package/src/database/upsert-builder.ts +75 -53
  407. package/src/dict/sd.ts +15 -5
  408. package/src/dict/sonamu-dictionary.ts +6 -6
  409. package/src/dict/utils.ts +9 -1
  410. package/src/entity/entity-manager.ts +26 -9
  411. package/src/entity/entity-template-cone.ts +5 -10
  412. package/src/entity/entity.ts +50 -34
  413. package/src/env.ts +7 -3
  414. package/src/exceptions/error-handler.ts +17 -2
  415. package/src/exceptions/so-exceptions.ts +26 -20
  416. package/src/filter/utils.ts +21 -11
  417. package/src/index.ts +3 -0
  418. package/src/logger/configure.ts +26 -18
  419. package/src/migration/__tests__/migrator.test.ts +50 -57
  420. package/src/migration/code-generation.ts +132 -104
  421. package/src/migration/index-where-predicate.ts +51 -24
  422. package/src/migration/migration-set.ts +11 -5
  423. package/src/migration/migrator.ts +392 -244
  424. package/src/migration/postgresql-schema-reader.ts +52 -47
  425. package/src/migration/slack-confirm.ts +17 -15
  426. package/src/migration/types.ts +57 -0
  427. package/src/naite/naite-reporter.ts +1 -1
  428. package/src/naite/naite.ts +97 -24
  429. package/src/runtime-type.ts +34 -0
  430. package/src/ssr/hmr-opt-out.ts +78 -0
  431. package/src/ssr/renderer.ts +6 -0
  432. package/src/storage/base-file.ts +13 -13
  433. package/src/storage/buffered-file.ts +11 -11
  434. package/src/storage/s3-driver.ts +4 -1
  435. package/src/storage/uploaded-file.ts +8 -8
  436. package/src/stream/__tests__/ws-contracts.test.ts +4 -2
  437. package/src/stream/__tests__/ws-telemetry.test.ts +1 -1
  438. package/src/stream/__tests__/ws.test.ts +30 -6
  439. package/src/stream/sse.ts +12 -11
  440. package/src/stream/ws-core.ts +1 -1
  441. package/src/stream/ws-delivery.ts +16 -7
  442. package/src/stream/ws-local-connection-store.ts +2 -3
  443. package/src/stream/ws-presence-store.ts +6 -1
  444. package/src/stream/ws-registry.ts +16 -7
  445. package/src/stream/ws-telemetry.ts +66 -43
  446. package/src/stream/ws.ts +73 -39
  447. package/src/syncer/__tests__/api-parser.websocket-type-ref.test.ts +3 -2
  448. package/src/syncer/__tests__/http-validator-registry.test.ts +137 -0
  449. package/src/syncer/api-parser.ts +67 -27
  450. package/src/syncer/checksum.ts +17 -11
  451. package/src/syncer/code-generator.ts +25 -17
  452. package/src/syncer/entity-operations.ts +3 -5
  453. package/src/syncer/file-copy.ts +46 -0
  454. package/src/syncer/file-patterns.ts +11 -8
  455. package/src/syncer/file-tracking.ts +3 -4
  456. package/src/syncer/filesystem-dependencies.ts +73 -0
  457. package/src/syncer/module-loader.ts +8 -4
  458. package/src/syncer/syncer-actions.ts +56 -18
  459. package/src/syncer/syncer.ts +116 -43
  460. package/src/syncer/watcher.ts +8 -4
  461. package/src/tasks/decorator.ts +20 -12
  462. package/src/tasks/step-wrapper.ts +19 -9
  463. package/src/tasks/workflow-manager.ts +15 -9
  464. package/src/template/__tests__/http_validators.template.test.ts +160 -0
  465. package/src/template/__tests__/services.template.mutation.test.ts +24 -23
  466. package/src/template/__tests__/services.template.websocket.test.ts +21 -25
  467. package/src/template/entity-converter.ts +5 -2
  468. package/src/template/helpers.ts +8 -9
  469. package/src/template/implementations/generated.template.ts +5 -4
  470. package/src/template/implementations/generated_http.template.ts +61 -15
  471. package/src/template/implementations/generated_sso.template.ts +15 -4
  472. package/src/template/implementations/http_validators.template.ts +175 -0
  473. package/src/template/implementations/model.template.ts +3 -1
  474. package/src/template/implementations/sd.template.ts +81 -41
  475. package/src/template/implementations/services.template.ts +2 -2
  476. package/src/template/implementations/view_form.template.ts +56 -39
  477. package/src/template/implementations/view_list.template.ts +31 -23
  478. package/src/template/template-manager.ts +15 -13
  479. package/src/template/template-types.ts +13 -5
  480. package/src/template/template.ts +4 -3
  481. package/src/template/zod-converter.ts +206 -91
  482. package/src/testing/__tests__/dev-test-routes.test.ts +85 -25
  483. package/src/testing/__tests__/dev-vitest-manager.test.ts +15 -15
  484. package/src/testing/_relation-graph.ts +4 -1
  485. package/src/testing/bootstrap.ts +12 -5
  486. package/src/testing/data-explorer.ts +102 -53
  487. package/src/testing/dev-test-routes.ts +87 -50
  488. package/src/testing/dev-vitest-manager.ts +88 -32
  489. package/src/testing/faker-mappings.ts +2 -2
  490. package/src/testing/filesystem.ts +1 -0
  491. package/src/testing/fixture-generator.ts +191 -131
  492. package/src/testing/fixture-loader.ts +5 -1
  493. package/src/testing/fixture-manager.ts +129 -90
  494. package/src/testing/global-setup.ts +7 -3
  495. package/src/testing/index.ts +5 -0
  496. package/src/types/__tests__/entity-json-schema-search-text.test.ts +9 -3
  497. package/src/types/types.ts +184 -158
  498. package/src/ui/ai-api.ts +9 -7
  499. package/src/ui/ai-client.ts +61 -56
  500. package/src/ui/api.ts +726 -770
  501. package/src/ui/async-route.ts +4 -0
  502. package/src/ui/cdd-service.ts +35 -12
  503. package/src/ui/migrations-api.ts +381 -0
  504. package/src/utils/formatter.ts +7 -3
  505. package/src/utils/fs-utils.ts +5 -5
  506. package/src/utils/model.ts +4 -5
  507. package/src/utils/object-utils.ts +32 -22
  508. package/src/utils/process-utils.ts +4 -1
  509. package/src/utils/runtime-value.ts +43 -0
  510. package/src/utils/sql-parser.ts +13 -6
  511. package/src/utils/type-utils.ts +9 -7
  512. package/src/utils/utils.ts +19 -21
  513. package/src/utils/zod-error.ts +4 -2
  514. package/src/vector/chunking.ts +6 -1
  515. package/src/vector/embedding.ts +2 -1
  516. package/src/vector/types.ts +4 -2
  517. package/tsdown.api.config.ts +5 -2
  518. package/dist/ui-web/assets/index-CJf8uJYf.js +0 -176
  519. package/dist/ui-web/assets/index-GMMIVGja.css +0 -1
package/dist/ui/api.js CHANGED
@@ -1,51 +1,58 @@
1
1
  import { __esmMin } from "../_virtual/_rolldown/runtime.js";
2
+ import { init_runtime_value, isObjectValue } from "../utils/runtime-value.js";
2
3
  import { createKnexInstance, init_knex } from "../database/knex.js";
3
4
  import { DB, init_db } from "../database/db.js";
4
5
  import { init_utils, nonNullable } from "../utils/utils.js";
5
6
  import { SD, init_sd } from "../dict/sd.js";
6
7
  import { BadRequestException, ServiceUnavailableException, init_so_exceptions, isSoException } from "../exceptions/so-exceptions.js";
7
- import { Sonamu, init_sonamu } from "../api/sonamu.js";
8
8
  import { BUILT_IN_TYPE_IDS, TemplateKey, init_types } from "../types/types.js";
9
+ import { Sonamu, init_sonamu } from "../api/sonamu.js";
9
10
  import { EntityManager, init_entity_manager } from "../entity/entity-manager.js";
10
- import { Migrator, init_migrator } from "../migration/migrator.js";
11
- import { FixtureManager, init_fixture_manager } from "../testing/fixture-manager.js";
12
11
  import { DataExplorer, init_data_explorer } from "../testing/data-explorer.js";
12
+ import { FixtureManager, init_fixture_manager } from "../testing/fixture-manager.js";
13
13
  import { FixtureGenerator, init_fixture_generator } from "../testing/fixture-generator.js";
14
14
  import { init_sonamu_dictionary, sonamuDictionary } from "../dict/sonamu-dictionary.js";
15
15
  import { TemplateManager, init_template_manager } from "../template/template-manager.js";
16
- import { SlackConfirm, init_slack_confirm } from "../migration/slack-confirm.js";
17
16
  import { init_ai_api, setAiApi } from "./ai-api.js";
17
+ import { forwardAsyncErrors, init_async_route } from "./async-route.js";
18
18
  import { addRule, editContent, getAcList, getCddTree, init_cdd_service, listRules, openSourceFile, readContent, readRule } from "./cdd-service.js";
19
+ import { init_migrations_api, registerMigrationsApi } from "./migrations-api.js";
19
20
  import inflection from "inflection";
20
21
  import { range } from "radashi";
21
22
  import fs from "fs";
22
23
  import path from "path";
23
- import { execSync } from "child_process";
24
+ import { execFileSync, execSync } from "child_process";
24
25
  //#region src/ui/api.ts
26
+ async function waitForHMRCompleted(fn) {
27
+ const waitPromise = new Promise((resolve) => {
28
+ const handler = () => {
29
+ clearTimeout(timeout);
30
+ resolve();
31
+ };
32
+ const timeout = setTimeout(() => {
33
+ Sonamu.syncer.eventEmitter.off("onHMRCompleted", handler);
34
+ resolve();
35
+ }, 1500);
36
+ Sonamu.syncer.eventEmitter.once("onHMRCompleted", handler);
37
+ });
38
+ const result = await fn();
39
+ await waitPromise;
40
+ return result;
41
+ }
42
+ function flattenSubsetRows(subsetRows) {
43
+ return subsetRows.flatMap((subsetRow) => {
44
+ const { children, ...sRow } = subsetRow;
45
+ return [sRow, ...flattenSubsetRows(children)];
46
+ });
47
+ }
25
48
  async function sonamuUIApiPlugin(fastify) {
26
49
  fastify.register(async (server) => {
27
- const migrator = new Migrator();
28
- async function waitForHMRCompleted(fn) {
29
- const waitPromise = new Promise((resolve) => {
30
- const handler = () => {
31
- clearTimeout(timeout);
32
- resolve();
33
- };
34
- const timeout = setTimeout(() => {
35
- Sonamu.syncer.eventEmitter.off("onHMRCompleted", handler);
36
- resolve();
37
- }, 1500);
38
- Sonamu.syncer.eventEmitter.once("onHMRCompleted", handler);
39
- });
40
- const result = await fn();
41
- await waitPromise;
42
- return result;
43
- }
44
50
  await setAiApi(server);
51
+ await registerMigrationsApi(server);
45
52
  server.get("/api/sonamu/config", async () => {
46
53
  return Sonamu.config;
47
54
  });
48
- server.get("/api/tools/openVscode", async (request) => {
55
+ server.get("/api/tools/openVscode", (request) => forwardAsyncErrors(async () => {
49
56
  const { entityId, preset, absPath } = request.query;
50
57
  execSync(`code ${(() => {
51
58
  if (entityId && preset) {
@@ -65,8 +72,17 @@ async function sonamuUIApiPlugin(fastify) {
65
72
  return absPath;
66
73
  }
67
74
  })()}`);
68
- });
69
- server.get("/api/tools/getSuggestion", async (request) => {
75
+ }));
76
+ server.get("/api/tools/openEditor", (request) => forwardAsyncErrors(async () => {
77
+ const command = {
78
+ vscode: "code",
79
+ cursor: "cursor",
80
+ zed: "zed"
81
+ }[request.query.editor];
82
+ if (command === void 0) throw new BadRequestException(SD("error.badRequest"));
83
+ execFileSync(command, [request.query.absPath]);
84
+ }));
85
+ server.get("/api/tools/getSuggestion", (request) => forwardAsyncErrors(async () => {
70
86
  const { origin, entityId } = request.query;
71
87
  const glossary = /* @__PURE__ */ new Map([
72
88
  ["status", "상태"],
@@ -116,15 +132,15 @@ async function sonamuUIApiPlugin(fastify) {
116
132
  ["expected", "예상"],
117
133
  ["actual", "실제"]
118
134
  ]);
119
- for (const entityId of EntityManager.getAllIds()) {
120
- const entity = EntityManager.get(entityId);
121
- if ((entity.title ?? "") !== "") {
122
- glossary.set(inflection.underscore(entity.id), entity.title);
123
- glossary.set(inflection.underscore(inflection.pluralize(entity.id)), `${entity.title}리스트`);
135
+ for (const glossaryEntityId of EntityManager.getAllIds()) {
136
+ const glossaryEntity = EntityManager.get(glossaryEntityId);
137
+ if ((glossaryEntity.title ?? "") !== "") {
138
+ glossary.set(inflection.underscore(glossaryEntity.id), glossaryEntity.title);
139
+ glossary.set(inflection.underscore(inflection.pluralize(glossaryEntity.id)), `${glossaryEntity.title}리스트`);
124
140
  }
125
- entity.props.forEach((prop) => {
141
+ glossaryEntity.props.forEach((prop) => {
126
142
  if (glossary.has(prop.name)) return;
127
- if (prop.desc) glossary.set(prop.name, prop.desc.replace(entity.title ?? "", "{EntityID}"));
143
+ if (prop.desc) glossary.set(prop.name, prop.desc.replace(glossaryEntity.title ?? "", "{EntityID}"));
128
144
  });
129
145
  }
130
146
  return { suggested: (() => {
@@ -148,15 +164,9 @@ async function sonamuUIApiPlugin(fastify) {
148
164
  else return r.toUpperCase();
149
165
  }).join("").replace(/{EntityID}/g, entityId ? EntityManager.get(entityId).title : "");
150
166
  })() };
151
- });
167
+ }));
152
168
  server.get("/api/entity/findMany", async () => {
153
169
  const entityIds = EntityManager.getAllIds();
154
- function flattenSubsetRows(subsetRows) {
155
- return subsetRows.flatMap((subsetRow) => {
156
- const { children, ...sRow } = subsetRow;
157
- return [sRow, ...flattenSubsetRows(children)];
158
- });
159
- }
160
170
  const entities = await Promise.all(entityIds.map((entityId) => {
161
171
  const entity = EntityManager.get(entityId);
162
172
  const subsetRows = entity.getSubsetRows();
@@ -180,11 +190,14 @@ async function sonamuUIApiPlugin(fastify) {
180
190
  });
181
191
  return { entities };
182
192
  });
183
- server.get("/api/entity/typeIds", async (request) => {
193
+ server.get("/api/entity/typeIds", (request) => forwardAsyncErrors(async () => {
184
194
  const { filter, reload } = request.query;
185
195
  if (reload === "1") await Sonamu.syncer.autoloadTypes();
186
196
  return { typeIds: (() => {
187
- const projectTypeIds = Object.entries(Sonamu.syncer.types).filter(([_typeId, zodType]) => zodType._zod.def.type !== "enum").map(([typeId, _zodType]) => typeId);
197
+ const projectTypeIds = Object.entries(Sonamu.syncer.types).filter(([_typeId, zodType]) => {
198
+ const { _zod: zodMetadata } = zodType;
199
+ return zodMetadata.def.type !== "enum";
200
+ }).map(([typeId, _zodType]) => typeId);
188
201
  const allTypeIds = [...[...BUILT_IN_TYPE_IDS], ...projectTypeIds];
189
202
  if (filter === "types") return allTypeIds;
190
203
  const enumIds = EntityManager.getAllIds().flatMap((entityId) => {
@@ -194,8 +207,8 @@ async function sonamuUIApiPlugin(fastify) {
194
207
  if (filter === "enums") return enumIds;
195
208
  else return [...allTypeIds, ...enumIds];
196
209
  })() };
197
- });
198
- server.post("/api/entity/create", async (request) => {
210
+ }));
211
+ server.post("/api/entity/create", (request) => forwardAsyncErrors(async () => {
199
212
  return await waitForHMRCompleted(async () => {
200
213
  const { form } = request.body;
201
214
  await Sonamu.syncer.createEntity({
@@ -204,14 +217,14 @@ async function sonamuUIApiPlugin(fastify) {
204
217
  });
205
218
  return 1;
206
219
  });
207
- });
208
- server.post("/api/entity/del", async (request) => {
220
+ }));
221
+ server.post("/api/entity/del", (request) => forwardAsyncErrors(async () => {
209
222
  return await waitForHMRCompleted(async () => {
210
223
  const { entityId } = request.body;
211
224
  return await Sonamu.syncer.delEntity(entityId);
212
225
  });
213
- });
214
- server.post("/api/entity/modifyEntityBase", async (request) => {
226
+ }));
227
+ server.post("/api/entity/modifyEntityBase", (request) => forwardAsyncErrors(async () => {
215
228
  return await waitForHMRCompleted(async () => {
216
229
  const { entityId, newValues } = request.body;
217
230
  const entity = EntityManager.get(entityId);
@@ -221,8 +234,8 @@ async function sonamuUIApiPlugin(fastify) {
221
234
  await entity.save();
222
235
  return 1;
223
236
  });
224
- });
225
- server.post("/api/entity/modifySubset", async (request) => {
237
+ }));
238
+ server.post("/api/entity/modifySubset", (request) => forwardAsyncErrors(async () => {
226
239
  return await waitForHMRCompleted(async () => {
227
240
  const { entityId, subsetKey, fields, fieldsInternal } = request.body;
228
241
  const entity = EntityManager.get(entityId);
@@ -235,8 +248,8 @@ async function sonamuUIApiPlugin(fastify) {
235
248
  updatedInternal: fieldsInternal
236
249
  };
237
250
  });
238
- });
239
- server.post("/api/entity/delSubset", async (request) => {
251
+ }));
252
+ server.post("/api/entity/delSubset", (request) => forwardAsyncErrors(async () => {
240
253
  return await waitForHMRCompleted(async () => {
241
254
  const { entityId, subsetKey } = request.body;
242
255
  const entity = EntityManager.get(entityId);
@@ -245,36 +258,36 @@ async function sonamuUIApiPlugin(fastify) {
245
258
  await entity.save();
246
259
  return 1;
247
260
  });
248
- });
249
- server.post("/api/entity/createProp", async (request) => {
261
+ }));
262
+ server.post("/api/entity/createProp", (request) => forwardAsyncErrors(async () => {
250
263
  return await waitForHMRCompleted(async () => {
251
264
  const { entityId, at, newProp } = request.body;
252
265
  await EntityManager.get(entityId).createProp(newProp, at);
253
266
  return true;
254
267
  });
255
- });
256
- server.post("/api/entity/modifyProp", async (request) => {
268
+ }));
269
+ server.post("/api/entity/modifyProp", (request) => forwardAsyncErrors(async () => {
257
270
  return await waitForHMRCompleted(async () => {
258
271
  const { entityId, at, newProp } = request.body;
259
272
  EntityManager.get(entityId).modifyProp(newProp, at);
260
273
  return true;
261
274
  });
262
- });
263
- server.post("/api/entity/delProp", async (request) => {
275
+ }));
276
+ server.post("/api/entity/delProp", (request) => forwardAsyncErrors(async () => {
264
277
  return await waitForHMRCompleted(async () => {
265
278
  const { entityId, at } = request.body;
266
279
  EntityManager.get(entityId).delProp(at);
267
280
  return true;
268
281
  });
269
- });
270
- server.post("/api/entity/moveProp", async (request) => {
282
+ }));
283
+ server.post("/api/entity/moveProp", (request) => forwardAsyncErrors(async () => {
271
284
  return await waitForHMRCompleted(async () => {
272
285
  const { entityId, at, to } = request.body;
273
286
  EntityManager.get(entityId).moveProp(at, to);
274
287
  return true;
275
288
  });
276
- });
277
- server.post("/api/entity/modifyIndexes", async (request) => {
289
+ }));
290
+ server.post("/api/entity/modifyIndexes", (request) => forwardAsyncErrors(async () => {
278
291
  return await waitForHMRCompleted(async () => {
279
292
  const { entityId, indexes } = request.body;
280
293
  const entity = EntityManager.get(entityId);
@@ -282,8 +295,8 @@ async function sonamuUIApiPlugin(fastify) {
282
295
  await entity.save();
283
296
  return { updated: indexes };
284
297
  });
285
- });
286
- server.post("/api/entity/modifyEnumLabels", async (request) => {
298
+ }));
299
+ server.post("/api/entity/modifyEnumLabels", (request) => forwardAsyncErrors(async () => {
287
300
  return await waitForHMRCompleted(async () => {
288
301
  const { entityId, enumLabels } = request.body;
289
302
  const entity = EntityManager.get(entityId);
@@ -291,8 +304,8 @@ async function sonamuUIApiPlugin(fastify) {
291
304
  await entity.save();
292
305
  return { updated: enumLabels };
293
306
  });
294
- });
295
- server.post("/api/entity/createEnumId", async (request) => {
307
+ }));
308
+ server.post("/api/entity/createEnumId", (request) => forwardAsyncErrors(async () => {
296
309
  return await waitForHMRCompleted(async () => {
297
310
  const { entityId, newEnumId } = request.body;
298
311
  const entity = EntityManager.get(entityId);
@@ -304,36 +317,36 @@ async function sonamuUIApiPlugin(fastify) {
304
317
  await entity.save();
305
318
  return 1;
306
319
  });
307
- });
308
- server.post("/api/entity/modifyEnumId", async (request) => {
320
+ }));
321
+ server.post("/api/entity/modifyEnumId", (request) => forwardAsyncErrors(async () => {
309
322
  return await waitForHMRCompleted(async () => {
310
323
  const { entityId, enumId } = request.body;
311
324
  const entityIds = EntityManager.getAllIds();
312
- if (entityIds.some((entityId) => {
313
- const entity = EntityManager.get(entityId);
314
- return Object.keys(entity.enumLabels).includes(enumId.after);
325
+ if (entityIds.some((candidateEntityId) => {
326
+ const candidateEntity = EntityManager.get(candidateEntityId);
327
+ return Object.keys(candidateEntity.enumLabels).includes(enumId.after);
315
328
  })) throw new Error(`이미 존재하는 EnumId입니다: ${enumId.after}`);
316
329
  const entity = EntityManager.get(entityId);
317
330
  entity.enumLabels[enumId.after] = entity.enumLabels[enumId.before];
318
331
  delete entity.enumLabels[enumId.before];
319
332
  await entity.save();
320
- for (const entityId of entityIds) {
321
- const entity = EntityManager.get(entityId);
322
- for (const prop of entity.props) if (prop.type === "enum" && prop.id === enumId.before) prop.id = enumId.after;
323
- await entity.save();
333
+ for (const relatedEntityId of entityIds) {
334
+ const relatedEntity = EntityManager.get(relatedEntityId);
335
+ for (const prop of relatedEntity.props) if (prop.type === "enum" && prop.id === enumId.before) prop.id = enumId.after;
336
+ await relatedEntity.save();
324
337
  }
325
338
  });
326
- });
327
- server.post("/api/entity/deleteEnumId", async (request) => {
339
+ }));
340
+ server.post("/api/entity/deleteEnumId", (request) => forwardAsyncErrors(async () => {
328
341
  return await waitForHMRCompleted(async () => {
329
342
  const { entityId, enumId } = request.body;
330
- if (EntityManager.getAllIds().flatMap((entityId) => EntityManager.get(entityId).props).some((prop) => prop.type === "enum" && prop.id === enumId)) throw new Error(`${enumId}를 참조하는 프로퍼티가 존재합니다.`);
343
+ if (EntityManager.getAllIds().flatMap((referencingEntityId) => EntityManager.get(referencingEntityId).props).some((prop) => prop.type === "enum" && prop.id === enumId)) throw new Error(`${enumId}를 참조하는 프로퍼티가 존재합니다.`);
331
344
  const entity = EntityManager.get(entityId);
332
345
  delete entity.enumLabels[enumId];
333
346
  await entity.save();
334
347
  });
335
- });
336
- server.post("/api/entity/updateCone", async (request) => {
348
+ }));
349
+ server.post("/api/entity/updateCone", (request) => forwardAsyncErrors(async () => {
337
350
  return await waitForHMRCompleted(async () => {
338
351
  const { entityId, target, propName, enumId, subsetKey, cone } = request.body;
339
352
  const entity = EntityManager.get(entityId);
@@ -346,7 +359,7 @@ async function sonamuUIApiPlugin(fastify) {
346
359
  await entity.save();
347
360
  return true;
348
361
  });
349
- });
362
+ }));
350
363
  server.post("/api/entity/generateCones", async (request, reply) => {
351
364
  return await waitForHMRCompleted(async () => {
352
365
  const { entityId, preserveExisting, onlyEmpty, locale } = request.body;
@@ -389,89 +402,11 @@ async function sonamuUIApiPlugin(fastify) {
389
402
  }
390
403
  });
391
404
  });
392
- server.get("/api/entity/getTableColumns", async (request) => {
405
+ server.get("/api/entity/getTableColumns", (request) => forwardAsyncErrors(async () => {
393
406
  const { entityId } = request.query;
394
407
  return { columns: EntityManager.get(entityId).getTableColumns() };
395
- });
396
- server.get("/api/migrations/status", async () => {
397
- return { status: await migrator.getStatus() };
398
- });
399
- server.post("/api/migrations/runAction", async (request) => {
400
- const { action, targets, force, forceReason, requestor } = request.body;
401
- if (action === "shadow") return migrator.runShadowTest();
402
- if (action === "apply") {
403
- const slackConfirm = new SlackConfirm();
404
- const requiresApproval = targets.some((t) => slackConfirm.isTargetRequiresApproval(t));
405
- const localHosts = [
406
- "localhost",
407
- "127.0.0.1",
408
- "0.0.0.0",
409
- "::1"
410
- ];
411
- const isLocalTarget = targets.every((target) => {
412
- const host = (Sonamu.dbConfig[target]?.connection)?.host ?? "localhost";
413
- return localHosts.includes(host.toLowerCase());
414
- });
415
- if (requiresApproval && slackConfirm.isConfigured() && !isLocalTarget) {
416
- const { conns } = await migrator.getStatus();
417
- const pendingMigrations = [...new Set(conns.filter((conn) => targets.includes(conn.connKey)).flatMap((conn) => conn.pending))];
418
- if (pendingMigrations.length > 0) {
419
- const existing = await slackConfirm.getExistingRequest(pendingMigrations);
420
- if (existing) {
421
- const { approved, rejected } = await slackConfirm.checkApproval(existing.channel, existing.ts);
422
- if (approved) {
423
- const result = await migrator.runAction(action, targets);
424
- if (result.length > 0) await slackConfirm.logExecution(existing.channel, existing.ts, result, requestor);
425
- return result;
426
- } else if (rejected) throw new BadRequestException(SD("sonamu.error.migrationRejected"));
427
- else if (force) {
428
- await slackConfirm.forceApproval(existing.channel, existing.ts, forceReason ?? "사유 없음", requestor);
429
- const result = await migrator.runAction(action, targets);
430
- if (result.length > 0) await slackConfirm.logExecution(existing.channel, existing.ts, result, requestor);
431
- return result;
432
- } else return {
433
- type: "pending",
434
- channel: existing.channel,
435
- ts: existing.ts
436
- };
437
- } else {
438
- const { channel, ts } = await slackConfirm.postApprovalRequest(pendingMigrations, targets, requestor);
439
- await slackConfirm.saveRequest(pendingMigrations, channel, ts);
440
- return {
441
- type: "pending",
442
- channel,
443
- ts
444
- };
445
- }
446
- }
447
- }
448
- }
449
- return migrator.runAction(action, targets);
450
- });
451
- server.post("/api/migrations/checkApproval", async (request) => {
452
- const { channel, ts } = request.body;
453
- const slackConfirm = new SlackConfirm();
454
- if (!slackConfirm.isConfigured()) return {
455
- approved: true,
456
- rejected: false
457
- };
458
- return slackConfirm.checkApproval(channel, ts);
459
- });
460
- server.post("/api/migrations/forceApproval", async (request) => {
461
- const { channel, ts, reason, requestor } = request.body;
462
- const slackConfirm = new SlackConfirm();
463
- if (!slackConfirm.isConfigured()) throw new BadRequestException(SD("sonamu.error.slackConfirmNotConfigured"));
464
- await slackConfirm.forceApproval(channel, ts, reason, requestor);
465
- return { success: true };
466
- });
467
- server.post("/api/migrations/delCodes", async (request) => {
468
- const { codeNames } = request.body;
469
- return await migrator.delCodes(codeNames);
470
- });
471
- server.post("/api/migrations/generatePreparedCodes", async (_requestt) => {
472
- return await migrator.generatePreparedCodes();
473
- });
474
- server.post("/api/scaffolding/getStatus", async (request) => {
408
+ }));
409
+ server.post("/api/scaffolding/getStatus", (request) => forwardAsyncErrors(async () => {
475
410
  const { entityIds, templateKeys: _templateKeys } = request.body;
476
411
  if ((entityIds ?? []).length === 0) throw new BadRequestException(SD("sonamu.error.entityIdsRequired"));
477
412
  else if ((_templateKeys ?? []).length === 0) throw new BadRequestException(SD("sonamu.error.templateKeysRequired"));
@@ -490,8 +425,8 @@ async function sonamuUIApiPlugin(fastify) {
490
425
  isExists
491
426
  };
492
427
  })) };
493
- });
494
- server.post("/api/scaffolding/generate", async (request) => {
428
+ }));
429
+ server.post("/api/scaffolding/generate", (request) => forwardAsyncErrors(async () => {
495
430
  const { options } = request.body;
496
431
  if (options.length === 0) throw new BadRequestException(SD("sonamu.error.optionsRequired"));
497
432
  const keys = options.flatMap(({ templateKey }) => {
@@ -514,8 +449,8 @@ async function sonamuUIApiPlugin(fastify) {
514
449
  }));
515
450
  if (result.filter(nonNullable).length === 0) throw new ServiceUnavailableException(SD("sonamu.error.allFilesGenerated"));
516
451
  return result;
517
- });
518
- server.post("/api/scaffolding/preview", async (request) => {
452
+ }));
453
+ server.post("/api/scaffolding/preview", (request) => forwardAsyncErrors(async () => {
519
454
  const { option } = request.body;
520
455
  try {
521
456
  const { templateKey, ...templateOptions } = option;
@@ -524,19 +459,19 @@ async function sonamuUIApiPlugin(fastify) {
524
459
  console.error(e);
525
460
  throw e;
526
461
  }
527
- });
528
- server.post("/api/fixture", async (request) => {
462
+ }));
463
+ server.post("/api/fixture", (request) => forwardAsyncErrors(async () => {
529
464
  const { sourceDB, targetDB, search, duplicateCheck } = request.body;
530
465
  return FixtureManager.getFixtures(sourceDB, targetDB, search, duplicateCheck);
531
- });
532
- server.post("/api/fixture/import", async (request) => {
466
+ }));
467
+ server.post("/api/fixture/import", (request) => forwardAsyncErrors(async () => {
533
468
  const { db, fixtures } = request.body;
534
469
  return FixtureManager.insertFixtures(db, fixtures);
535
- });
536
- server.post("/api/fixture/addFixtureLoader", async (request) => {
470
+ }));
471
+ server.post("/api/fixture/addFixtureLoader", (request) => forwardAsyncErrors(async () => {
537
472
  const { code } = request.body;
538
473
  return FixtureManager.addFixtureLoader(code);
539
- });
474
+ }));
540
475
  server.get("/api/i18n/dictionary", async () => {
541
476
  return sonamuDictionary.getDictionary();
542
477
  });
@@ -544,27 +479,27 @@ async function sonamuUIApiPlugin(fastify) {
544
479
  const { filename, buffer } = await sonamuDictionary.exportToExcel();
545
480
  reply.header("Content-Type", "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet").header("Content-Disposition", `attachment; filename="${filename}"`).send(buffer);
546
481
  });
547
- server.post("/api/i18n/import", async (request) => {
482
+ server.post("/api/i18n/import", (request) => forwardAsyncErrors(async () => {
548
483
  const data = await request.file();
549
484
  if (!data) throw new BadRequestException(SD("sonamu.error.fileNotUploaded"));
550
485
  const buffer = await data.toBuffer();
551
486
  return sonamuDictionary.importFromExcel(buffer);
552
- });
553
- server.post("/api/i18n/update", async (request) => {
487
+ }));
488
+ server.post("/api/i18n/update", (request) => forwardAsyncErrors(async () => {
554
489
  await sonamuDictionary.updateEntry(request.body);
555
490
  return { success: true };
556
- });
557
- server.post("/api/i18n/create", async (request) => {
491
+ }));
492
+ server.post("/api/i18n/create", (request) => forwardAsyncErrors(async () => {
558
493
  await sonamuDictionary.createEntry(request.body);
559
494
  return { success: true };
560
- });
561
- server.post("/api/i18n/delete", async (request) => {
495
+ }));
496
+ server.post("/api/i18n/delete", (request) => forwardAsyncErrors(async () => {
562
497
  await sonamuDictionary.deleteEntry(request.body.key);
563
498
  return { success: true };
564
- });
565
- server.post("/api/i18n/checkUsage", async (request) => {
499
+ }));
500
+ server.post("/api/i18n/checkUsage", (request) => forwardAsyncErrors(async () => {
566
501
  return sonamuDictionary.checkUsage(request.body.keys);
567
- });
502
+ }));
568
503
  server.get("/api/tasks/status", async () => {
569
504
  try {
570
505
  Sonamu.workflows;
@@ -576,7 +511,7 @@ async function sonamuUIApiPlugin(fastify) {
576
511
  server.get("/api/tasks/workflowDefinitions", async () => {
577
512
  return { definitions: Sonamu.workflows.workflowDefinitions };
578
513
  });
579
- server.get("/api/tasks/workflowRuns", async (request) => {
514
+ server.get("/api/tasks/workflowRuns", (request) => forwardAsyncErrors(async () => {
580
515
  const backend = Sonamu.workflows.backend;
581
516
  const { limit, after, before, order, status, workflowName, createdAfter, createdBefore } = request.query;
582
517
  return backend.listWorkflowRuns({
@@ -589,22 +524,22 @@ async function sonamuUIApiPlugin(fastify) {
589
524
  createdAfter: createdAfter ? new Date(createdAfter) : void 0,
590
525
  createdBefore: createdBefore ? new Date(createdBefore) : void 0
591
526
  });
592
- });
593
- server.get("/api/tasks/workflowRuns/:id", async (request) => {
527
+ }));
528
+ server.get("/api/tasks/workflowRuns/:id", (request) => forwardAsyncErrors(async () => {
594
529
  const workflowRun = await Sonamu.workflows.backend.getWorkflowRun({ workflowRunId: request.params.id });
595
530
  if (!workflowRun) throw new Error(`Workflow run not found: ${request.params.id}`);
596
531
  return workflowRun;
597
- });
598
- server.post("/api/tasks/workflowRuns/:id/cancel", async (request) => {
532
+ }));
533
+ server.post("/api/tasks/workflowRuns/:id/cancel", (request) => forwardAsyncErrors(async () => {
599
534
  return Sonamu.workflows.backend.cancelWorkflowRun({ workflowRunId: request.params.id });
600
- });
601
- server.post("/api/tasks/workflowRuns/:id/pause", async (request) => {
535
+ }));
536
+ server.post("/api/tasks/workflowRuns/:id/pause", (request) => forwardAsyncErrors(async () => {
602
537
  return Sonamu.workflows.backend.pauseWorkflowRun({ workflowRunId: request.params.id });
603
- });
604
- server.post("/api/tasks/workflowRuns/:id/resume", async (request) => {
538
+ }));
539
+ server.post("/api/tasks/workflowRuns/:id/resume", (request) => forwardAsyncErrors(async () => {
605
540
  return Sonamu.workflows.backend.resumeWorkflowRun({ workflowRunId: request.params.id });
606
- });
607
- server.get("/api/tasks/workflowRuns/:id/steps", async (request) => {
541
+ }));
542
+ server.get("/api/tasks/workflowRuns/:id/steps", (request) => forwardAsyncErrors(async () => {
608
543
  const backend = Sonamu.workflows.backend;
609
544
  const { limit, after, before } = request.query;
610
545
  return backend.listStepAttempts({
@@ -613,21 +548,21 @@ async function sonamuUIApiPlugin(fastify) {
613
548
  after,
614
549
  before
615
550
  });
616
- });
551
+ }));
617
552
  /**
618
553
  * Health Check API
619
554
  * MCP 도구가 Sonamu 서버를 자동 감지하기 위한 엔드포인트
620
555
  */
621
- server.get("/api/sonamu/health", async (request) => {
556
+ server.get("/api/sonamu/health", (request) => forwardAsyncErrors(async () => {
622
557
  const address = request.server.server.address();
623
- const port = address && typeof address === "object" ? address.port : 0;
558
+ const port = address && isObjectValue(address) ? address.port : 0;
624
559
  return {
625
560
  ok: true,
626
561
  project: process.cwd().split("/").pop() || "unknown",
627
562
  port,
628
563
  timestamp: (/* @__PURE__ */ new Date()).toISOString()
629
564
  };
630
- });
565
+ }));
631
566
  /**
632
567
  * Fixture 생성 API
633
568
  */
@@ -749,29 +684,29 @@ async function sonamuUIApiPlugin(fastify) {
749
684
  server.get("/api/cdd/tree", async () => {
750
685
  return getCddTree();
751
686
  });
752
- server.post("/api/cdd/readContent", async (request) => {
687
+ server.post("/api/cdd/readContent", (request) => forwardAsyncErrors(async () => {
753
688
  const { filePath } = request.body;
754
689
  return readContent(filePath);
755
- });
756
- server.post("/api/cdd/editContent", async (request) => {
690
+ }));
691
+ server.post("/api/cdd/editContent", (request) => forwardAsyncErrors(async () => {
757
692
  const { filePath } = request.body;
758
693
  return editContent(filePath);
759
- });
760
- server.post("/api/cdd/openSource", async (request) => {
694
+ }));
695
+ server.post("/api/cdd/openSource", (request) => forwardAsyncErrors(async () => {
761
696
  const { filePath } = request.body;
762
697
  openSourceFile(filePath);
763
698
  return { success: true };
764
- });
699
+ }));
765
700
  server.get("/api/cdd/rules", async () => {
766
701
  return listRules();
767
702
  });
768
- server.post("/api/cdd/readRule", async (request) => {
703
+ server.post("/api/cdd/readRule", (request) => forwardAsyncErrors(async () => {
769
704
  const { ruleKey } = request.body;
770
705
  return readRule(ruleKey);
771
- });
772
- server.post("/api/cdd/addRule", async (request) => {
706
+ }));
707
+ server.post("/api/cdd/addRule", (request) => forwardAsyncErrors(async () => {
773
708
  return addRule(request.body);
774
- });
709
+ }));
775
710
  server.get("/api/cdd/ac", async () => {
776
711
  return getAcList();
777
712
  });
@@ -796,17 +731,18 @@ __esmMin((() => {
796
731
  init_sonamu_dictionary();
797
732
  init_entity_manager();
798
733
  init_so_exceptions();
799
- init_migrator();
800
- init_slack_confirm();
801
734
  init_template_manager();
802
735
  init_data_explorer();
803
736
  init_fixture_generator();
804
737
  init_fixture_manager();
805
738
  init_types();
739
+ init_runtime_value();
806
740
  init_utils();
807
741
  init_ai_api();
742
+ init_async_route();
808
743
  init_cdd_service();
744
+ init_migrations_api();
809
745
  }))();
810
746
  export { sonamuUIApiPlugin };
811
747
 
812
- //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYXBpLmpzIiwibmFtZXMiOltdLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy91aS9hcGkudHMiXSwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgZXhlY1N5bmMgfSBmcm9tIFwiY2hpbGRfcHJvY2Vzc1wiO1xuaW1wb3J0IGZzIGZyb20gXCJmc1wiO1xuaW1wb3J0IHBhdGggZnJvbSBcInBhdGhcIjtcblxuaW1wb3J0IHsgdHlwZSBGYXN0aWZ5SW5zdGFuY2UgfSBmcm9tIFwiZmFzdGlmeVwiO1xuaW1wb3J0IGluZmxlY3Rpb24gZnJvbSBcImluZmxlY3Rpb25cIjtcbmltcG9ydCB7IHJhbmdlIH0gZnJvbSBcInJhZGFzaGlcIjtcblxuaW1wb3J0IHsgU29uYW11IH0gZnJvbSBcIi4uL2FwaS9zb25hbXVcIjtcbmltcG9ydCB7IERCIH0gZnJvbSBcIi4uL2RhdGFiYXNlL2RiXCI7XG5pbXBvcnQgeyB0eXBlIFNvbmFtdURCQ29uZmlnIH0gZnJvbSBcIi4uL2RhdGFiYXNlL2RiXCI7XG5pbXBvcnQgeyBjcmVhdGVLbmV4SW5zdGFuY2UgfSBmcm9tIFwiLi4vZGF0YWJhc2Uva25leFwiO1xuaW1wb3J0IHsgU0QgfSBmcm9tIFwiLi4vZGljdC9zZFwiO1xuaW1wb3J0IHsgc29uYW11RGljdGlvbmFyeSB9IGZyb20gXCIuLi9kaWN0L3NvbmFtdS1kaWN0aW9uYXJ5XCI7XG5pbXBvcnQgeyB0eXBlIEVudGl0eSB9IGZyb20gXCIuLi9lbnRpdHkvZW50aXR5XCI7XG5pbXBvcnQgeyBFbnRpdHlNYW5hZ2VyIH0gZnJvbSBcIi4uL2VudGl0eS9lbnRpdHktbWFuYWdlclwiO1xuaW1wb3J0IHtcbiAgQmFkUmVxdWVzdEV4Y2VwdGlvbixcbiAgaXNTb0V4Y2VwdGlvbixcbiAgU2VydmljZVVuYXZhaWxhYmxlRXhjZXB0aW9uLFxufSBmcm9tIFwiLi4vZXhjZXB0aW9ucy9zby1leGNlcHRpb25zXCI7XG5pbXBvcnQgeyBNaWdyYXRvciB9IGZyb20gXCIuLi9taWdyYXRpb24vbWlncmF0b3JcIjtcbmltcG9ydCB7IHR5cGUgTWlncmF0aW9uUmVzdWx0IH0gZnJvbSBcIi4uL21pZ3JhdGlvbi9taWdyYXRvclwiO1xuaW1wb3J0IHsgU2xhY2tDb25maXJtIH0gZnJvbSBcIi4uL21pZ3JhdGlvbi9zbGFjay1jb25maXJtXCI7XG5pbXBvcnQgeyB0eXBlIFNsYWNrQ29uZmlybVBlbmRpbmdSZXN1bHQgfSBmcm9tIFwiLi4vbWlncmF0aW9uL3NsYWNrLWNvbmZpcm1cIjtcbmltcG9ydCB7IFRlbXBsYXRlTWFuYWdlciB9IGZyb20gXCIuLi90ZW1wbGF0ZS90ZW1wbGF0ZS1tYW5hZ2VyXCI7XG5pbXBvcnQgeyBEYXRhRXhwbG9yZXIgfSBmcm9tIFwiLi4vdGVzdGluZy9kYXRhLWV4cGxvcmVyXCI7XG5pbXBvcnQgeyBGaXh0dXJlR2VuZXJhdG9yIH0gZnJvbSBcIi4uL3Rlc3RpbmcvZml4dHVyZS1nZW5lcmF0b3JcIjtcbmltcG9ydCB7IEZpeHR1cmVNYW5hZ2VyIH0gZnJvbSBcIi4uL3Rlc3RpbmcvZml4dHVyZS1tYW5hZ2VyXCI7XG5pbXBvcnQgeyB0eXBlIER1cGxpY2F0ZUNoZWNrT3B0aW9ucyB9IGZyb20gXCIuLi90ZXN0aW5nL2ZpeHR1cmUtbWFuYWdlclwiO1xuaW1wb3J0IHsgQlVJTFRfSU5fVFlQRV9JRFMsIFRlbXBsYXRlS2V5IH0gZnJvbSBcIi4uL3R5cGVzL3R5cGVzXCI7XG5pbXBvcnQge1xuICB0eXBlIENvbmUsXG4gIHR5cGUgRW50aXR5SW5kZXgsXG4gIHR5cGUgRW50aXR5UHJvcCxcbiAgdHlwZSBFbnRpdHlTdWJzZXRSb3csXG4gIHR5cGUgRml4dHVyZVJlY29yZCxcbiAgdHlwZSBGaXh0dXJlU2VhcmNoT3B0aW9ucyxcbiAgdHlwZSBGbGF0dGVuU3Vic2V0Um93LFxuICB0eXBlIFBhdGhBbmRDb2RlLFxufSBmcm9tIFwiLi4vdHlwZXMvdHlwZXNcIjtcbmltcG9ydCB7IG5vbk51bGxhYmxlIH0gZnJvbSBcIi4uL3V0aWxzL3V0aWxzXCI7XG5pbXBvcnQgeyBzZXRBaUFwaSB9IGZyb20gXCIuL2FpLWFwaVwiO1xuaW1wb3J0IHsgdHlwZSBDZGRBZGRSdWxlUmVxdWVzdCB9IGZyb20gXCIuL2NkZC1zZXJ2aWNlXCI7XG5pbXBvcnQge1xuICBhZGRSdWxlLFxuICBlZGl0Q29udGVudCxcbiAgZ2V0QWNMaXN0LFxuICBnZXRDZGRUcmVlLFxuICBsaXN0UnVsZXMsXG4gIG9wZW5Tb3VyY2VGaWxlLFxuICByZWFkQ29udGVudCxcbiAgcmVhZFJ1bGUsXG59IGZyb20gXCIuL2NkZC1zZXJ2aWNlXCI7XG5cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiBzb25hbXVVSUFwaVBsdWdpbihmYXN0aWZ5OiBGYXN0aWZ5SW5zdGFuY2UpIHtcbiAgZmFzdGlmeS5yZWdpc3RlcihcbiAgICBhc3luYyAoc2VydmVyKSA9PiB7XG4gICAgICAvLyBtaWdyYXRvclxuICAgICAgY29uc3QgbWlncmF0b3IgPSBuZXcgTWlncmF0b3IoKTtcblxuICAgICAgLy8gd2FpdEZvckhNUkNvbXBsZXRlZFxuICAgICAgYXN5bmMgZnVuY3Rpb24gd2FpdEZvckhNUkNvbXBsZXRlZDxUPihmbjogKCkgPT4gUHJvbWlzZTxUPik6IFByb21pc2U8VD4ge1xuICAgICAgICBjb25zdCB3YWl0UHJvbWlzZSA9IG5ldyBQcm9taXNlPHZvaWQ+KChyZXNvbHZlKSA9PiB7XG4gICAgICAgICAgY29uc3QgaGFuZGxlciA9ICgpID0+IHtcbiAgICAgICAgICAgIGNsZWFyVGltZW91dCh0aW1lb3V0KTtcbiAgICAgICAgICAgIHJlc29sdmUoKTtcbiAgICAgICAgICB9O1xuXG4gICAgICAgICAgY29uc3QgdGltZW91dCA9IHNldFRpbWVvdXQoKCkgPT4ge1xuICAgICAgICAgICAgU29uYW11LnN5bmNlci5ldmVudEVtaXR0ZXIub2ZmKFwib25ITVJDb21wbGV0ZWRcIiwgaGFuZGxlcik7XG4gICAgICAgICAgICByZXNvbHZlKCk7XG4gICAgICAgICAgfSwgMTUwMCk7XG5cbiAgICAgICAgICBTb25hbXUuc3luY2VyLmV2ZW50RW1pdHRlci5vbmNlKFwib25ITVJDb21wbGV0ZWRcIiwgaGFuZGxlcik7XG4gICAgICAgIH0pO1xuXG4gICAgICAgIGNvbnN0IHJlc3VsdCA9IGF3YWl0IGZuKCk7XG4gICAgICAgIGF3YWl0IHdhaXRQcm9taXNlO1xuICAgICAgICByZXR1cm4gcmVzdWx0O1xuICAgICAgfVxuXG4gICAgICBhd2FpdCBzZXRBaUFwaShzZXJ2ZXIpO1xuXG4gICAgICBzZXJ2ZXIuZ2V0KFwiL2FwaS9zb25hbXUvY29uZmlnXCIsIGFzeW5jICgpID0+IHtcbiAgICAgICAgcmV0dXJuIFNvbmFtdS5jb25maWc7XG4gICAgICB9KTtcblxuICAgICAgc2VydmVyLmdldDx7XG4gICAgICAgIFF1ZXJ5c3RyaW5nOiB7XG4gICAgICAgICAgZW50aXR5SWQ/OiBzdHJpbmc7XG4gICAgICAgICAgcHJlc2V0PzogXCJ0eXBlc1wiIHwgXCJlbnRpdHkuanNvblwiIHwgXCJnZW5lcmF0ZWRcIjtcbiAgICAgICAgICBhYnNQYXRoPzogc3RyaW5nO1xuICAgICAgICB9O1xuICAgICAgfT4oXCIvYXBpL3Rvb2xzL29wZW5Wc2NvZGVcIiwgYXN5bmMgKHJlcXVlc3QpID0+IHtcbiAgICAgICAgY29uc3QgeyBlbnRpdHlJZCwgcHJlc2V0LCBhYnNQYXRoIH0gPSByZXF1ZXN0LnF1ZXJ5O1xuXG4gICAgICAgIGNvbnN0IHRhcmdldFBhdGggPSAoKCkgPT4ge1xuICAgICAgICAgIGlmIChlbnRpdHlJZCAmJiBwcmVzZXQpIHtcbiAgICAgICAgICAgIGNvbnN0IGVudGl0eSA9IEVudGl0eU1hbmFnZXIuZ2V0KGVudGl0eUlkKTtcbiAgICAgICAgICAgIGNvbnN0IHsgbmFtZXMgfSA9IGVudGl0eTtcblxuICAgICAgICAgICAgY29uc3QgeyBhcGlSb290UGF0aCB9ID0gU29uYW11O1xuICAgICAgICAgICAgY29uc3QgZmlsZW5hbWUgPSAoKCkgPT4ge1xuICAgICAgICAgICAgICBzd2l0Y2ggKHByZXNldCkge1xuICAgICAgICAgICAgICAgIGNhc2UgXCJ0eXBlc1wiOlxuICAgICAgICAgICAgICAgICAgcmV0dXJuIGAke25hbWVzLmZzfS50eXBlcy50c2A7XG4gICAgICAgICAgICAgICAgY2FzZSBcImVudGl0eS5qc29uXCI6XG4gICAgICAgICAgICAgICAgICByZXR1cm4gYCR7bmFtZXMuZnN9LmVudGl0eS5qc29uYDtcbiAgICAgICAgICAgICAgICBjYXNlIFwiZ2VuZXJhdGVkXCI6XG4gICAgICAgICAgICAgICAgICByZXR1cm4gYCR7bmFtZXMuZnN9LmdlbmVyYXRlZC50c2A7XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0pKCk7XG4gICAgICAgICAgICByZXR1cm4gYCR7YXBpUm9vdFBhdGh9L3NyYy9hcHBsaWNhdGlvbi8ke2VudGl0eS5uYW1lcy5wYXJlbnRGc30vJHtmaWxlbmFtZX1gO1xuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBpZiAoIWFic1BhdGgpIHtcbiAgICAgICAgICAgICAgdGhyb3cgbmV3IEJhZFJlcXVlc3RFeGNlcHRpb24oU0QoXCJzb25hbXUuZXJyb3IucHJlc2V0T3JBYnNQYXRoUmVxdWlyZWRcIikpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmV0dXJuIGFic1BhdGg7XG4gICAgICAgICAgfVxuICAgICAgICB9KSgpO1xuICAgICAgICBleGVjU3luYyhgY29kZSAke3RhcmdldFBhdGh9YCk7XG4gICAgICB9KTtcblxuICAgICAgc2VydmVyLmdldDx7XG4gICAgICAgIFF1ZXJ5c3RyaW5nOiB7XG4gICAgICAgICAgb3JpZ2luOiBzdHJpbmc7XG4gICAgICAgICAgZW50aXR5SWQ/OiBzdHJpbmc7XG4gICAgICAgIH07XG4gICAgICB9PihcIi9hcGkvdG9vbHMvZ2V0U3VnZ2VzdGlvblwiLCBhc3luYyAocmVxdWVzdCkgPT4ge1xuICAgICAgICBjb25zdCB7IG9yaWdpbiwgZW50aXR5SWQgfSA9IHJlcXVlc3QucXVlcnk7XG5cbiAgICAgICAgLy8g7LmY7ZmYIOyaqeyWtOynkVxuICAgICAgICBjb25zdCBnbG9zc2FyeSA9IG5ldyBNYXA8c3RyaW5nLCBzdHJpbmc+KFtcbiAgICAgICAgICBbXCJzdGF0dXNcIiwgXCLsg4Htg5xcIl0sXG4gICAgICAgICAgW1widHlwZVwiLCBcIu2DgOyehVwiXSxcbiAgICAgICAgICBbXCJpbWFnZVwiLCBcIuydtOuvuOyngFwiXSxcbiAgICAgICAgICBbXCJpbWFnZXNcIiwgXCLsnbTrr7jsp4DrpqzsiqTtirhcIl0sXG4gICAgICAgICAgW1widXJsXCIsIFwiVVJMXCJdLFxuICAgICAgICAgIFtcImlkXCIsIFwiSURcIl0sXG4gICAgICAgICAgW1wibmFtZVwiLCBge0VudGl0eUlEfeuqhWBdLFxuICAgICAgICAgIFtcInRpdGxlXCIsIFwie0VudGl0eUlEfeuqhVwiXSxcbiAgICAgICAgICBbXCJwYXJlbnRcIiwgXCLsg4HsnIR7RW50aXR5SUR9XCJdLFxuICAgICAgICAgIFtcImRlc2NcIiwgXCLshKTrqoVcIl0sXG4gICAgICAgICAgW1wiYXRcIiwgXCLsnbzsi5xcIl0sXG4gICAgICAgICAgW1wiY3JlYXRlZFwiLCBcIuuTseuhnVwiXSxcbiAgICAgICAgICBbXCJ1cGRhdGVkXCIsIFwi7IiY7KCVXCJdLFxuICAgICAgICAgIFtcImRlbGV0ZWRcIiwgXCLsgq3soJxcIl0sXG4gICAgICAgICAgW1wiYnlcIiwgXCLsnKDsoIBcIl0sXG4gICAgICAgICAgW1wiZGF0ZVwiLCBcIuydvOyekFwiXSxcbiAgICAgICAgICBbXCJ0aW1lXCIsIFwi7Iuc6rCEXCJdLFxuICAgICAgICAgIFtcImtvXCIsIFwiKO2VnOq4gClcIl0sXG4gICAgICAgICAgW1wiZW5cIiwgXCIo7JiB66y4KVwiXSxcbiAgICAgICAgICBbXCJrcndcIiwgXCIo7JuQKVwiXSxcbiAgICAgICAgICBbXCJ1c2RcIiwgXCIoVVNEKVwiXSxcbiAgICAgICAgICBbXCJjb2xvclwiLCBcIuy7rOufrFwiXSxcbiAgICAgICAgICBbXCJjb2RlXCIsIFwi7L2U65OcXCJdLFxuICAgICAgICAgIFtcInhcIiwgXCJY7KKM7ZGcXCJdLFxuICAgICAgICAgIFtcInlcIiwgXCJZ7KKM7ZGcXCJdLFxuICAgICAgICAgIFtcImN1cnJlbnRcIiwgXCLtmITsnqxcIl0sXG4gICAgICAgICAgW1wic3RvY2tcIiwgXCLsnqzqs6BcIl0sXG4gICAgICAgICAgW1widG90YWxcIiwgXCLstJ1cIl0sXG4gICAgICAgICAgW1wiYWRtaW5cIiwgXCLqtIDrpqzsnpBcIl0sXG4gICAgICAgICAgW1wiZ3JvdXBcIiwgXCLqt7jro7lcIl0sXG4gICAgICAgICAgW1wiaXRlbVwiLCBcIuyVhOydtO2FnFwiXSxcbiAgICAgICAgICBbXCJjbnRcIiwgXCLsiJjrn4lcIl0sXG4gICAgICAgICAgW1wicHJpY2VcIiwgXCLqsIDqsqlcIl0sXG4gICAgICAgICAgW1wicHJlc2V0XCIsIFwi7ZSE66as7IWLXCJdLFxuICAgICAgICAgIFtcImFjY3RcIiwgXCLqs4TsooxcIl0sXG4gICAgICAgICAgW1widGVsXCIsIFwi7KCE7ZmU67KI7Zi4XCJdLFxuICAgICAgICAgIFtcIm5vXCIsIFwi67KI7Zi4XCJdLFxuICAgICAgICAgIFtcImJvZHlcIiwgXCLrgrTsmqlcIl0sXG4gICAgICAgICAgW1wiY29udGVudFwiLCBcIuuCtOyaqVwiXSxcbiAgICAgICAgICBbXCJvcmRlcm5vXCIsIFwi7KCV66Cs7Iic7IScXCJdLFxuICAgICAgICAgIFtcInByaW9yaXR5XCIsIFwi7Jqw7ISg7Iic7JyEXCJdLFxuICAgICAgICAgIFtcInRleHRcIiwgXCLthY3siqTtirhcIl0sXG4gICAgICAgICAgW1wia2V5XCIsIFwi7YKkXCJdLFxuICAgICAgICAgIFtcInN1bVwiLCBcIu2VqeyCsFwiXSxcbiAgICAgICAgICBbXCJleHBlY3RlZFwiLCBcIuyYiOyDgVwiXSxcbiAgICAgICAgICBbXCJhY3R1YWxcIiwgXCLsi6TsoJxcIl0sXG4gICAgICAgIF0pO1xuICAgICAgICAvLyDsoITssrQg7JeU7Yuw7YuwIOyInO2ajO2VmOupsCwg7JeU7Yuw7YuwIO2DgOydtO2LgOqzvCDtlITroa0g7ISk66qF7J2EIOy5mO2ZmCDsmqnslrTsp5Hsl5Ag7LaU6rCAXG4gICAgICAgIGZvciAoY29uc3QgZW50aXR5SWQgb2YgRW50aXR5TWFuYWdlci5nZXRBbGxJZHMoKSkge1xuICAgICAgICAgIGNvbnN0IGVudGl0eSA9IEVudGl0eU1hbmFnZXIuZ2V0KGVudGl0eUlkKTtcbiAgICAgICAgICBpZiAoKGVudGl0eS50aXRsZSA/PyBcIlwiKSAhPT0gXCJcIikge1xuICAgICAgICAgICAgZ2xvc3Nhcnkuc2V0KGluZmxlY3Rpb24udW5kZXJzY29yZShlbnRpdHkuaWQpLCBlbnRpdHkudGl0bGUpO1xuICAgICAgICAgICAgZ2xvc3Nhcnkuc2V0KFxuICAgICAgICAgICAgICBpbmZsZWN0aW9uLnVuZGVyc2NvcmUoaW5mbGVjdGlvbi5wbHVyYWxpemUoZW50aXR5LmlkKSksXG4gICAgICAgICAgICAgIGAke2VudGl0eS50aXRsZX3rpqzsiqTtirhgLFxuICAgICAgICAgICAgKTtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICBlbnRpdHkucHJvcHMuZm9yRWFjaCgocHJvcCkgPT4ge1xuICAgICAgICAgICAgaWYgKGdsb3NzYXJ5Lmhhcyhwcm9wLm5hbWUpKSB7XG4gICAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmIChwcm9wLmRlc2MpIHtcbiAgICAgICAgICAgICAgZ2xvc3Nhcnkuc2V0KHByb3AubmFtZSwgcHJvcC5kZXNjLnJlcGxhY2UoZW50aXR5LnRpdGxlID8/IFwiXCIsIFwie0VudGl0eUlEfVwiKSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfSk7XG4gICAgICAgIH1cblxuICAgICAgICBjb25zdCBzdWdnZXN0ZWQgPSAoKCkgPT4ge1xuICAgICAgICAgIC8vIOuLqOyWtCDrtoTrpqwsIOqwgOuKpe2VnCDsobDtlakg7IOd7ISxXG4gICAgICAgICAgY29uc3Qgd29yZHMgPSBvcmlnaW4uc3BsaXQoXCJfXCIpO1xuICAgICAgICAgIGNvbnN0IGNvbWJpbmF0aW9ucyA9IFsuLi5yYW5nZSh3b3Jkcy5sZW5ndGgsIDAsIC0xKV0uZmxhdE1hcCgobGVuKSA9PiB7XG4gICAgICAgICAgICByZXR1cm4gW1xuICAgICAgICAgICAgICAuLi5yYW5nZSgwLCB3b3Jkcy5sZW5ndGggLSBsZW4gKyAxLCAoaWR4KSA9PiB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgICAgICAgIGxlbixcbiAgICAgICAgICAgICAgICAgIHc6IHdvcmRzLnNsaWNlKGlkeCwgaWR4ICsgbGVuKS5qb2luKFwiX1wiKSxcbiAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgICB9KSxcbiAgICAgICAgICAgIF07XG4gICAgICAgICAgfSk7XG5cbiAgICAgICAgICAvLyDsobDtlansnYQg7Iic7ZqM7ZWY66mwLCDsuZjtmZgg7Jqp7Ja07KeR7JeQIOyeiOuKlCDri6jslrTqsIAg7Y+s7ZWo65CcIOqyveyasCwg7LmY7ZmYIOyaqeyWtOuhnCDsuZjtmZhcbiAgICAgICAgICBjb25zdCBSRVBMQUNFRF9QUkVGSVggPSBcIiNSRVBMQUNFRC8vXCI7IC8vIOy5mO2ZmOuQnCDri6jslrTrpbwgam9pbiDsnbTtm4Tsl5Drj4Qg7Iud67OE7ZWY6riwIOychO2VtCBwcmVmaXgg7LaU6rCAXG4gICAgICAgICAgbGV0IHJlbWFpbkFycjogc3RyaW5nW10gPSBbLi4ud29yZHNdO1xuICAgICAgICAgIGZvciAoY29uc3QgY29tYiBvZiBjb21iaW5hdGlvbnMpIHtcbiAgICAgICAgICAgIGNvbnN0IHJlbWFpblN0ciA9IHJlbWFpbkFyci5qb2luKFwiX1wiKTtcbiAgICAgICAgICAgIGlmIChyZW1haW5TdHIuaW5jbHVkZXMoY29tYi53KSAmJiBnbG9zc2FyeS5oYXMoY29tYi53KSkge1xuICAgICAgICAgICAgICByZW1haW5BcnIgPSByZW1haW5TdHJcbiAgICAgICAgICAgICAgICAucmVwbGFjZShjb21iLncsIFJFUExBQ0VEX1BSRUZJWCArIGdsb3NzYXJ5LmdldChjb21iLncpKVxuICAgICAgICAgICAgICAgIC5zcGxpdChcIl9cIik7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgcmV0dXJuIHJlbWFpbkFyclxuICAgICAgICAgICAgLm1hcCgocikgPT4ge1xuICAgICAgICAgICAgICBpZiAoci5zdGFydHNXaXRoKFJFUExBQ0VEX1BSRUZJWCkpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gci5yZXBsYWNlKFJFUExBQ0VEX1BSRUZJWCwgXCJcIik7XG4gICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHIudG9VcHBlckNhc2UoKTtcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSlcbiAgICAgICAgICAgIC5qb2luKFwiXCIpXG4gICAgICAgICAgICAucmVwbGFjZSgve0VudGl0eUlEfS9nLCBlbnRpdHlJZCA/IEVudGl0eU1hbmFnZXIuZ2V0KGVudGl0eUlkKS50aXRsZSA6IFwiXCIpO1xuICAgICAgICB9KSgpO1xuXG4gICAgICAgIHJldHVybiB7IHN1Z2dlc3RlZCB9O1xuICAgICAgfSk7XG5cbiAgICAgIHNlcnZlci5nZXQoXCIvYXBpL2VudGl0eS9maW5kTWFueVwiLCBhc3luYyAoKSA9PiB7XG4gICAgICAgIGNvbnN0IGVudGl0eUlkcyA9IEVudGl0eU1hbmFnZXIuZ2V0QWxsSWRzKCk7XG5cbiAgICAgICAgZnVuY3Rpb24gZmxhdHRlblN1YnNldFJvd3Moc3Vic2V0Um93czogRW50aXR5U3Vic2V0Um93W10pOiBGbGF0dGVuU3Vic2V0Um93W10ge1xuICAgICAgICAgIHJldHVybiBzdWJzZXRSb3dzLmZsYXRNYXAoKHN1YnNldFJvdykgPT4ge1xuICAgICAgICAgICAgY29uc3QgeyBjaGlsZHJlbiwgLi4uc1JvdyB9ID0gc3Vic2V0Um93O1xuICAgICAgICAgICAgcmV0dXJuIFtzUm93LCAuLi5mbGF0dGVuU3Vic2V0Um93cyhjaGlsZHJlbildO1xuICAgICAgICAgIH0pO1xuICAgICAgICB9XG5cbiAgICAgICAgY29uc3QgZW50aXRpZXMgPSBhd2FpdCBQcm9taXNlLmFsbChcbiAgICAgICAgICBlbnRpdHlJZHMubWFwKChlbnRpdHlJZCkgPT4ge1xuICAgICAgICAgICAgY29uc3QgZW50aXR5ID0gRW50aXR5TWFuYWdlci5nZXQoZW50aXR5SWQpO1xuICAgICAgICAgICAgY29uc3Qgc3Vic2V0Um93cyA9IGVudGl0eS5nZXRTdWJzZXRSb3dzKCk7XG5cbiAgICAgICAgICAgIC8vIHpvZCDsnbjsiqTthLTsiqTrpbwgc3ByZWFk7ZWY66m0IEpTT04uc3RyaW5naWZ56rCAIHJlZmVyZW5jZeulvCDsnbjrnbzsnbjsnLzroZwg7ZKA7Ja064K066mwIOydkeuLteydtCDsiJjrsLEgTULquYzsp4Ag67aA7ZKA7Ja0IFY4IHN0cmluZyBsaW1pdOulvCDstIjqs7ztlZzri6QuXG4gICAgICAgICAgICBjb25zdCB7XG4gICAgICAgICAgICAgIHR5cGVzOiBfdHlwZXMsXG4gICAgICAgICAgICAgIGVudW1zOiBfZW51bXMsXG4gICAgICAgICAgICAgIGVudW1Db25lczogX2VudW1Db25lcyxcbiAgICAgICAgICAgICAgc3Vic2V0Q29uZXM6IF9zdWJzZXRDb25lcyxcbiAgICAgICAgICAgICAgLi4ucmVzdFxuICAgICAgICAgICAgfSA9IGVudGl0eTtcblxuICAgICAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgICAgLi4ucmVzdCxcbiAgICAgICAgICAgICAgZmxhdHRlblN1YnNldFJvd3M6IGZsYXR0ZW5TdWJzZXRSb3dzKHN1YnNldFJvd3MpLFxuICAgICAgICAgICAgfTtcbiAgICAgICAgICB9KSxcbiAgICAgICAgKTtcblxuICAgICAgICBlbnRpdGllcy5zb3J0KChhLCBiKSA9PiB7XG4gICAgICAgICAgY29uc3QgYUlkID0gYS5wYXJlbnRJZCA/PyBhLmlkO1xuICAgICAgICAgIGNvbnN0IGJJZCA9IGIucGFyZW50SWQgPz8gYi5pZDtcbiAgICAgICAgICBpZiAoYUlkIDwgYklkKSByZXR1cm4gLTE7XG4gICAgICAgICAgaWYgKGFJZCA+IGJJZCkgcmV0dXJuIDE7XG4gICAgICAgICAgaWYgKGFJZCA9PT0gYklkKSB7XG4gICAgICAgICAgICBpZiAoYS5wYXJlbnRJZCA9PT0gdW5kZWZpbmVkKSByZXR1cm4gLTE7XG4gICAgICAgICAgICBpZiAoYi5wYXJlbnRJZCA9PT0gdW5kZWZpbmVkKSByZXR1cm4gMTtcbiAgICAgICAgICAgIHJldHVybiAwO1xuICAgICAgICAgIH1cbiAgICAgICAgICByZXR1cm4gMDtcbiAgICAgICAgfSk7XG4gICAgICAgIHJldHVybiB7IGVudGl0aWVzIH07XG4gICAgICB9KTtcblxuICAgICAgc2VydmVyLmdldDx7XG4gICAgICAgIFF1ZXJ5c3RyaW5nOiB7XG4gICAgICAgICAgZmlsdGVyPzogXCJlbnVtc1wiIHwgXCJ0eXBlc1wiO1xuICAgICAgICAgIHJlbG9hZD86IFwiMVwiO1xuICAgICAgICB9O1xuICAgICAgfT4oXCIvYXBpL2VudGl0eS90eXBlSWRzXCIsIGFzeW5jIChyZXF1ZXN0KTogUHJvbWlzZTx7IHR5cGVJZHM6IHN0cmluZ1tdIH0+ID0+IHtcbiAgICAgICAgY29uc3QgeyBmaWx0ZXIsIHJlbG9hZCB9ID0gcmVxdWVzdC5xdWVyeTtcblxuICAgICAgICBpZiAocmVsb2FkID09PSBcIjFcIikge1xuICAgICAgICAgIGF3YWl0IFNvbmFtdS5zeW5jZXIuYXV0b2xvYWRUeXBlcygpO1xuICAgICAgICB9XG5cbiAgICAgICAgY29uc3QgdHlwZUlkcyA9ICgoKSA9PiB7XG4gICAgICAgICAgLy8g7ZSE66Gc7KCd7Yq47JeQ7IScIOygleydmO2VnCDtg4DsnoXrk6RcbiAgICAgICAgICBjb25zdCBwcm9qZWN0VHlwZUlkcyA9IE9iamVjdC5lbnRyaWVzKFNvbmFtdS5zeW5jZXIudHlwZXMpXG4gICAgICAgICAgICAuZmlsdGVyKChbX3R5cGVJZCwgem9kVHlwZV0pID0+ICh6b2RUeXBlLl96b2QuZGVmLnR5cGUgYXMgc3RyaW5nKSAhPT0gXCJlbnVtXCIpXG4gICAgICAgICAgICAubWFwKChbdHlwZUlkLCBfem9kVHlwZV0pID0+IHR5cGVJZCk7XG5cbiAgICAgICAgICAvLyDrgrTsnqUg7YOA7J6F65OkIChzb25hbXUg7L2U7Ja07JeQ7IScIOygnOqztSlcbiAgICAgICAgICBjb25zdCBidWlsdEluVHlwZUlkcyA9IFsuLi5CVUlMVF9JTl9UWVBFX0lEU107XG5cbiAgICAgICAgICAvLyDrqqjrk6Ag7YOA7J6FIOuzke2VqVxuICAgICAgICAgIGNvbnN0IGFsbFR5cGVJZHMgPSBbLi4uYnVpbHRJblR5cGVJZHMsIC4uLnByb2plY3RUeXBlSWRzXTtcblxuICAgICAgICAgIGlmIChmaWx0ZXIgPT09IFwidHlwZXNcIikge1xuICAgICAgICAgICAgcmV0dXJuIGFsbFR5cGVJZHM7XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgY29uc3QgZW51bUlkcyA9IEVudGl0eU1hbmFnZXIuZ2V0QWxsSWRzKCkuZmxhdE1hcCgoZW50aXR5SWQpID0+IHtcbiAgICAgICAgICAgIGNvbnN0IGVudGl0eSA9IEVudGl0eU1hbmFnZXIuZ2V0KGVudGl0eUlkKTtcbiAgICAgICAgICAgIHJldHVybiBPYmplY3Qua2V5cyhlbnRpdHkuZW51bUxhYmVscyk7XG4gICAgICAgICAgfSk7XG5cbiAgICAgICAgICBpZiAoZmlsdGVyID09PSBcImVudW1zXCIpIHtcbiAgICAgICAgICAgIHJldHVybiBlbnVtSWRzO1xuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICByZXR1cm4gWy4uLmFsbFR5cGVJZHMsIC4uLmVudW1JZHNdO1xuICAgICAgICAgIH1cbiAgICAgICAgfSkoKTtcblxuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgIHR5cGVJZHMsXG4gICAgICAgIH07XG4gICAgICB9KTtcblxuICAgICAgc2VydmVyLnBvc3Q8e1xuICAgICAgICBCb2R5OiB7XG4gICAgICAgICAgZm9ybToge1xuICAgICAgICAgICAgaWQ6IHN0cmluZztcbiAgICAgICAgICAgIHRpdGxlOiBzdHJpbmc7XG4gICAgICAgICAgICB0YWJsZTogc3RyaW5nO1xuICAgICAgICAgICAgcGFyZW50SWQ/OiBzdHJpbmc7XG4gICAgICAgICAgfTtcbiAgICAgICAgfTtcbiAgICAgIH0+KFwiL2FwaS9lbnRpdHkvY3JlYXRlXCIsIGFzeW5jIChyZXF1ZXN0KSA9PiB7XG4gICAgICAgIHJldHVybiBhd2FpdCB3YWl0Rm9ySE1SQ29tcGxldGVkKGFzeW5jICgpID0+IHtcbiAgICAgICAgICBjb25zdCB7IGZvcm0gfSA9IHJlcXVlc3QuYm9keTtcbiAgICAgICAgICBhd2FpdCBTb25hbXUuc3luY2VyLmNyZWF0ZUVudGl0eSh7IC4uLmZvcm0sIGVudGl0eUlkOiBmb3JtLmlkIH0pO1xuXG4gICAgICAgICAgcmV0dXJuIDE7XG4gICAgICAgIH0pO1xuICAgICAgfSk7XG5cbiAgICAgIHNlcnZlci5wb3N0PHtcbiAgICAgICAgQm9keToge1xuICAgICAgICAgIGVudGl0eUlkOiBzdHJpbmc7XG4gICAgICAgIH07XG4gICAgICB9PihcIi9hcGkvZW50aXR5L2RlbFwiLCBhc3luYyAocmVxdWVzdCkgPT4ge1xuICAgICAgICByZXR1cm4gYXdhaXQgd2FpdEZvckhNUkNvbXBsZXRlZChhc3luYyAoKSA9PiB7XG4gICAgICAgICAgY29uc3QgeyBlbnRpdHlJZCB9ID0gcmVxdWVzdC5ib2R5O1xuICAgICAgICAgIHJldHVybiBhd2FpdCBTb25hbXUuc3luY2VyLmRlbEVudGl0eShlbnRpdHlJZCk7XG4gICAgICAgIH0pO1xuICAgICAgfSk7XG5cbiAgICAgIHNlcnZlci5wb3N0PHtcbiAgICAgICAgQm9keToge1xuICAgICAgICAgIGVudGl0eUlkOiBzdHJpbmc7XG4gICAgICAgICAgbmV3VmFsdWVzOiB7XG4gICAgICAgICAgICB0aXRsZTogc3RyaW5nO1xuICAgICAgICAgICAgdGFibGU6IHN0cmluZztcbiAgICAgICAgICAgIHBhcmVudElkPzogc3RyaW5nO1xuICAgICAgICAgIH07XG4gICAgICAgIH07XG4gICAgICB9PihcIi9hcGkvZW50aXR5L21vZGlmeUVudGl0eUJhc2VcIiwgYXN5bmMgKHJlcXVlc3QpID0+IHtcbiAgICAgICAgcmV0dXJuIGF3YWl0IHdhaXRGb3JITVJDb21wbGV0ZWQoYXN5bmMgKCkgPT4ge1xuICAgICAgICAgIGNvbnN0IHsgZW50aXR5SWQsIG5ld1ZhbHVlcyB9ID0gcmVxdWVzdC5ib2R5O1xuICAgICAgICAgIGNvbnN0IGVudGl0eSA9IEVudGl0eU1hbmFnZXIuZ2V0KGVudGl0eUlkKTtcbiAgICAgICAgICBlbnRpdHkudGl0bGUgPSBuZXdWYWx1ZXMudGl0bGU7XG4gICAgICAgICAgZW50aXR5LnRhYmxlID0gbmV3VmFsdWVzLnRhYmxlO1xuICAgICAgICAgIGVudGl0eS5wYXJlbnRJZCA9IG5ld1ZhbHVlcy5wYXJlbnRJZDtcbiAgICAgICAgICBhd2FpdCBlbnRpdHkuc2F2ZSgpO1xuXG4gICAgICAgICAgcmV0dXJuIDE7XG4gICAgICAgIH0pO1xuICAgICAgfSk7XG5cbiAgICAgIHNlcnZlci5wb3N0PHtcbiAgICAgICAgQm9keToge1xuICAgICAgICAgIGVudGl0eUlkOiBzdHJpbmc7XG4gICAgICAgICAgc3Vic2V0S2V5OiBzdHJpbmc7XG4gICAgICAgICAgZmllbGRzOiBzdHJpbmdbXTtcbiAgICAgICAgICBmaWVsZHNJbnRlcm5hbD86IHN0cmluZ1tdO1xuICAgICAgICB9O1xuICAgICAgfT4oXCIvYXBpL2VudGl0eS9tb2RpZnlTdWJzZXRcIiwgYXN5bmMgKHJlcXVlc3QpID0+IHtcbiAgICAgICAgcmV0dXJuIGF3YWl0IHdhaXRGb3JITVJDb21wbGV0ZWQoYXN5bmMgKCkgPT4ge1xuICAgICAgICAgIGNvbnN0IHsgZW50aXR5SWQsIHN1YnNldEtleSwgZmllbGRzLCBmaWVsZHNJbnRlcm5hbCB9ID0gcmVxdWVzdC5ib2R5O1xuICAgICAgICAgIGNvbnN0IGVudGl0eSA9IEVudGl0eU1hbmFnZXIuZ2V0KGVudGl0eUlkKTtcbiAgICAgICAgICBlbnRpdHkuc3Vic2V0c1tzdWJzZXRLZXldID0gZmllbGRzO1xuICAgICAgICAgIGlmIChmaWVsZHNJbnRlcm5hbCAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICBpZiAoZmllbGRzSW50ZXJuYWwubGVuZ3RoID4gMCkge1xuICAgICAgICAgICAgICBlbnRpdHkuc3Vic2V0c0ludGVybmFsW3N1YnNldEtleV0gPSBmaWVsZHNJbnRlcm5hbDtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgIGRlbGV0ZSBlbnRpdHkuc3Vic2V0c0ludGVybmFsW3N1YnNldEtleV07XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgICAgIGF3YWl0IGVudGl0eS5zYXZlKCk7XG5cbiAgICAgICAgICByZXR1cm4geyB1cGRhdGVkOiBmaWVsZHMsIHVwZGF0ZWRJbnRlcm5hbDogZmllbGRzSW50ZXJuYWwgfTtcbiAgICAgICAgfSk7XG4gICAgICB9KTtcblxuICAgICAgc2VydmVyLnBvc3Q8e1xuICAgICAgICBCb2R5OiB7XG4gICAgICAgICAgZW50aXR5SWQ6IHN0cmluZztcbiAgICAgICAgICBzdWJzZXRLZXk6IHN0cmluZztcbiAgICAgICAgfTtcbiAgICAgIH0+KFwiL2FwaS9lbnRpdHkvZGVsU3Vic2V0XCIsIGFzeW5jIChyZXF1ZXN0KSA9PiB7XG4gICAgICAgIHJldHVybiBhd2FpdCB3YWl0Rm9ySE1SQ29tcGxldGVkKGFzeW5jICgpID0+IHtcbiAgICAgICAgICBjb25zdCB7IGVudGl0eUlkLCBzdWJzZXRLZXkgfSA9IHJlcXVlc3QuYm9keTtcbiAgICAgICAgICBjb25zdCBlbnRpdHkgPSBFbnRpdHlNYW5hZ2VyLmdldChlbnRpdHlJZCk7XG4gICAgICAgICAgZGVsZXRlIGVudGl0eS5zdWJzZXRzW3N1YnNldEtleV07XG4gICAgICAgICAgZGVsZXRlIGVudGl0eS5zdWJzZXRzSW50ZXJuYWxbc3Vic2V0S2V5XTtcbiAgICAgICAgICBhd2FpdCBlbnRpdHkuc2F2ZSgpO1xuXG4gICAgICAgICAgcmV0dXJuIDE7XG4gICAgICAgIH0pO1xuICAgICAgfSk7XG5cbiAgICAgIHNlcnZlci5wb3N0PHtcbiAgICAgICAgQm9keToge1xuICAgICAgICAgIGVudGl0eUlkOiBzdHJpbmc7XG4gICAgICAgICAgbmV3UHJvcDogRW50aXR5UHJvcDtcbiAgICAgICAgICBhdD86IG51bWJlcjtcbiAgICAgICAgfTtcbiAgICAgIH0+KFwiL2FwaS9lbnRpdHkvY3JlYXRlUHJvcFwiLCBhc3luYyAocmVxdWVzdCkgPT4ge1xuICAgICAgICByZXR1cm4gYXdhaXQgd2FpdEZvckhNUkNvbXBsZXRlZChhc3luYyAoKSA9PiB7XG4gICAgICAgICAgY29uc3QgeyBlbnRpdHlJZCwgYXQsIG5ld1Byb3AgfSA9IHJlcXVlc3QuYm9keTtcbiAgICAgICAgICBjb25zdCBlbnRpdHkgPSBFbnRpdHlNYW5hZ2VyLmdldChlbnRpdHlJZCk7XG4gICAgICAgICAgYXdhaXQgZW50aXR5LmNyZWF0ZVByb3AobmV3UHJvcCwgYXQpO1xuICAgICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgICB9KTtcbiAgICAgIH0pO1xuXG4gICAgICBzZXJ2ZXIucG9zdDx7XG4gICAgICAgIEJvZHk6IHtcbiAgICAgICAgICBlbnRpdHlJZDogc3RyaW5nO1xuICAgICAgICAgIG5ld1Byb3A6IEVudGl0eVByb3A7XG4gICAgICAgICAgYXQ6IG51bWJlcjtcbiAgICAgICAgfTtcbiAgICAgIH0+KFwiL2FwaS9lbnRpdHkvbW9kaWZ5UHJvcFwiLCBhc3luYyAocmVxdWVzdCkgPT4ge1xuICAgICAgICByZXR1cm4gYXdhaXQgd2FpdEZvckhNUkNvbXBsZXRlZChhc3luYyAoKSA9PiB7XG4gICAgICAgICAgY29uc3QgeyBlbnRpdHlJZCwgYXQsIG5ld1Byb3AgfSA9IHJlcXVlc3QuYm9keTtcblxuICAgICAgICAgIGNvbnN0IGVudGl0eSA9IEVudGl0eU1hbmFnZXIuZ2V0KGVudGl0eUlkKTtcbiAgICAgICAgICBlbnRpdHkubW9kaWZ5UHJvcChuZXdQcm9wLCBhdCk7XG5cbiAgICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgICAgfSk7XG4gICAgICB9KTtcblxuICAgICAgc2VydmVyLnBvc3Q8e1xuICAgICAgICBCb2R5OiB7XG4gICAgICAgICAgZW50aXR5SWQ6IHN0cmluZztcbiAgICAgICAgICBhdDogbnVtYmVyO1xuICAgICAgICB9O1xuICAgICAgfT4oXCIvYXBpL2VudGl0eS9kZWxQcm9wXCIsIGFzeW5jIChyZXF1ZXN0KSA9PiB7XG4gICAgICAgIHJldHVybiBhd2FpdCB3YWl0Rm9ySE1SQ29tcGxldGVkKGFzeW5jICgpID0+IHtcbiAgICAgICAgICBjb25zdCB7IGVudGl0eUlkLCBhdCB9ID0gcmVxdWVzdC5ib2R5O1xuXG4gICAgICAgICAgY29uc3QgZW50aXR5ID0gRW50aXR5TWFuYWdlci5nZXQoZW50aXR5SWQpO1xuICAgICAgICAgIGVudGl0eS5kZWxQcm9wKGF0KTtcbiAgICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgICAgfSk7XG4gICAgICB9KTtcblxuICAgICAgc2VydmVyLnBvc3Q8e1xuICAgICAgICBCb2R5OiB7XG4gICAgICAgICAgZW50aXR5SWQ6IHN0cmluZztcbiAgICAgICAgICBhdDogbnVtYmVyO1xuICAgICAgICAgIHRvOiBudW1iZXI7XG4gICAgICAgIH07XG4gICAgICB9PihcIi9hcGkvZW50aXR5L21vdmVQcm9wXCIsIGFzeW5jIChyZXF1ZXN0KSA9PiB7XG4gICAgICAgIHJldHVybiBhd2FpdCB3YWl0Rm9ySE1SQ29tcGxldGVkKGFzeW5jICgpID0+IHtcbiAgICAgICAgICBjb25zdCB7IGVudGl0eUlkLCBhdCwgdG8gfSA9IHJlcXVlc3QuYm9keTtcblxuICAgICAgICAgIGNvbnN0IGVudGl0eSA9IEVudGl0eU1hbmFnZXIuZ2V0KGVudGl0eUlkKTtcbiAgICAgICAgICBlbnRpdHkubW92ZVByb3AoYXQsIHRvKTtcblxuICAgICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgICB9KTtcbiAgICAgIH0pO1xuXG4gICAgICBzZXJ2ZXIucG9zdDx7XG4gICAgICAgIEJvZHk6IHtcbiAgICAgICAgICBlbnRpdHlJZDogc3RyaW5nO1xuICAgICAgICAgIGluZGV4ZXM6IEVudGl0eUluZGV4W107XG4gICAgICAgIH07XG4gICAgICB9PihcIi9hcGkvZW50aXR5L21vZGlmeUluZGV4ZXNcIiwgYXN5bmMgKHJlcXVlc3QpID0+IHtcbiAgICAgICAgcmV0dXJuIGF3YWl0IHdhaXRGb3JITVJDb21wbGV0ZWQoYXN5bmMgKCkgPT4ge1xuICAgICAgICAgIGNvbnN0IHsgZW50aXR5SWQsIGluZGV4ZXMgfSA9IHJlcXVlc3QuYm9keTtcbiAgICAgICAgICBjb25zdCBlbnRpdHkgPSBFbnRpdHlNYW5hZ2VyLmdldChlbnRpdHlJZCk7XG4gICAgICAgICAgZW50aXR5LmluZGV4ZXMgPSBpbmRleGVzO1xuICAgICAgICAgIGF3YWl0IGVudGl0eS5zYXZlKCk7XG5cbiAgICAgICAgICByZXR1cm4geyB1cGRhdGVkOiBpbmRleGVzIH07XG4gICAgICAgIH0pO1xuICAgICAgfSk7XG5cbiAgICAgIHNlcnZlci5wb3N0PHtcbiAgICAgICAgQm9keToge1xuICAgICAgICAgIGVudGl0eUlkOiBzdHJpbmc7XG4gICAgICAgICAgZW51bUxhYmVsczogRW50aXR5W1wiZW51bUxhYmVsc1wiXTtcbiAgICAgICAgfTtcbiAgICAgIH0+KFwiL2FwaS9lbnRpdHkvbW9kaWZ5RW51bUxhYmVsc1wiLCBhc3luYyAocmVxdWVzdCkgPT4ge1xuICAgICAgICByZXR1cm4gYXdhaXQgd2FpdEZvckhNUkNvbXBsZXRlZChhc3luYyAoKSA9PiB7XG4gICAgICAgICAgY29uc3QgeyBlbnRpdHlJZCwgZW51bUxhYmVscyB9ID0gcmVxdWVzdC5ib2R5O1xuICAgICAgICAgIGNvbnN0IGVudGl0eSA9IEVudGl0eU1hbmFnZXIuZ2V0KGVudGl0eUlkKTtcbiAgICAgICAgICBlbnRpdHkuZW51bUxhYmVscyA9IGVudW1MYWJlbHM7XG4gICAgICAgICAgYXdhaXQgZW50aXR5LnNhdmUoKTtcblxuICAgICAgICAgIHJldHVybiB7IHVwZGF0ZWQ6IGVudW1MYWJlbHMgfTtcbiAgICAgICAgfSk7XG4gICAgICB9KTtcblxuICAgICAgc2VydmVyLnBvc3Q8e1xuICAgICAgICBCb2R5OiB7XG4gICAgICAgICAgZW50aXR5SWQ6IHN0cmluZztcbiAgICAgICAgICBuZXdFbnVtSWQ6IHN0cmluZztcbiAgICAgICAgfTtcbiAgICAgIH0+KFwiL2FwaS9lbnRpdHkvY3JlYXRlRW51bUlkXCIsIGFzeW5jIChyZXF1ZXN0KSA9PiB7XG4gICAgICAgIHJldHVybiBhd2FpdCB3YWl0Rm9ySE1SQ29tcGxldGVkKGFzeW5jICgpID0+IHtcbiAgICAgICAgICBjb25zdCB7IGVudGl0eUlkLCBuZXdFbnVtSWQgfSA9IHJlcXVlc3QuYm9keTtcbiAgICAgICAgICBjb25zdCBlbnRpdHkgPSBFbnRpdHlNYW5hZ2VyLmdldChlbnRpdHlJZCk7XG5cbiAgICAgICAgICBpZiAoZW50aXR5LmVudW1MYWJlbHNbbmV3RW51bUlkXSkge1xuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKGDsnbTrr7gg7KG07J6s7ZWY64qUIGVudW1JZOyeheuLiOuLpDogJHtuZXdFbnVtSWR9YCk7XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgZW50aXR5LmVudW1MYWJlbHNbbmV3RW51bUlkXSA9IG5ld0VudW1JZC5lbmRzV2l0aChcIlN0YXR1c1wiKVxuICAgICAgICAgICAgPyB7XG4gICAgICAgICAgICAgICAgYWN0aXZlOiBcIuuFuOy2nFwiLFxuICAgICAgICAgICAgICAgIGhpZGRlbjogXCLsiKjquYBcIixcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgOiB7XG4gICAgICAgICAgICAgICAgXCJcIjogXCJcIixcbiAgICAgICAgICAgICAgfTtcbiAgICAgICAgICBhd2FpdCBlbnRpdHkuc2F2ZSgpO1xuXG4gICAgICAgICAgcmV0dXJuIDE7XG4gICAgICAgIH0pO1xuICAgICAgfSk7XG5cbiAgICAgIHNlcnZlci5wb3N0PHtcbiAgICAgICAgQm9keToge1xuICAgICAgICAgIGVudGl0eUlkOiBzdHJpbmc7XG4gICAgICAgICAgZW51bUlkOiB7XG4gICAgICAgICAgICBiZWZvcmU6IHN0cmluZztcbiAgICAgICAgICAgIGFmdGVyOiBzdHJpbmc7XG4gICAgICAgICAgfTtcbiAgICAgICAgfTtcbiAgICAgIH0+KFwiL2FwaS9lbnRpdHkvbW9kaWZ5RW51bUlkXCIsIGFzeW5jIChyZXF1ZXN0KSA9PiB7XG4gICAgICAgIHJldHVybiBhd2FpdCB3YWl0Rm9ySE1SQ29tcGxldGVkKGFzeW5jICgpID0+IHtcbiAgICAgICAgICBjb25zdCB7IGVudGl0eUlkLCBlbnVtSWQgfSA9IHJlcXVlc3QuYm9keTtcbiAgICAgICAgICBjb25zdCBlbnRpdHlJZHMgPSBFbnRpdHlNYW5hZ2VyLmdldEFsbElkcygpO1xuICAgICAgICAgIGNvbnN0IGlzRXhpc3RzID0gZW50aXR5SWRzLnNvbWUoKGVudGl0eUlkKSA9PiB7XG4gICAgICAgICAgICBjb25zdCBlbnRpdHkgPSBFbnRpdHlNYW5hZ2VyLmdldChlbnRpdHlJZCk7XG4gICAgICAgICAgICByZXR1cm4gT2JqZWN0LmtleXMoZW50aXR5LmVudW1MYWJlbHMpLmluY2x1ZGVzKGVudW1JZC5hZnRlcik7XG4gICAgICAgICAgfSk7XG4gICAgICAgICAgaWYgKGlzRXhpc3RzKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYOydtOuvuCDsobTsnqztlZjripQgRW51bUlk7J6F64uI64ukOiAke2VudW1JZC5hZnRlcn1gKTtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICBjb25zdCBlbnRpdHkgPSBFbnRpdHlNYW5hZ2VyLmdldChlbnRpdHlJZCk7XG4gICAgICAgICAgZW50aXR5LmVudW1MYWJlbHNbZW51bUlkLmFmdGVyXSA9IGVudGl0eS5lbnVtTGFiZWxzW2VudW1JZC5iZWZvcmVdO1xuICAgICAgICAgIGRlbGV0ZSBlbnRpdHkuZW51bUxhYmVsc1tlbnVtSWQuYmVmb3JlXTtcblxuICAgICAgICAgIGF3YWl0IGVudGl0eS5zYXZlKCk7XG5cbiAgICAgICAgICBmb3IgKGNvbnN0IGVudGl0eUlkIG9mIGVudGl0eUlkcykge1xuICAgICAgICAgICAgY29uc3QgZW50aXR5ID0gRW50aXR5TWFuYWdlci5nZXQoZW50aXR5SWQpO1xuICAgICAgICAgICAgZm9yIChjb25zdCBwcm9wIG9mIGVudGl0eS5wcm9wcykge1xuICAgICAgICAgICAgICBpZiAocHJvcC50eXBlID09PSBcImVudW1cIiAmJiBwcm9wLmlkID09PSBlbnVtSWQuYmVmb3JlKSB7XG4gICAgICAgICAgICAgICAgcHJvcC5pZCA9IGVudW1JZC5hZnRlcjtcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgYXdhaXQgZW50aXR5LnNhdmUoKTtcbiAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgICAgfSk7XG5cbiAgICAgIHNlcnZlci5wb3N0PHtcbiAgICAgICAgQm9keToge1xuICAgICAgICAgIGVudGl0eUlkOiBzdHJpbmc7XG4gICAgICAgICAgZW51bUlkOiBzdHJpbmc7XG4gICAgICAgIH07XG4gICAgICB9PihcIi9hcGkvZW50aXR5L2RlbGV0ZUVudW1JZFwiLCBhc3luYyAocmVxdWVzdCkgPT4ge1xuICAgICAgICByZXR1cm4gYXdhaXQgd2FpdEZvckhNUkNvbXBsZXRlZChhc3luYyAoKSA9PiB7XG4gICAgICAgICAgY29uc3QgeyBlbnRpdHlJZCwgZW51bUlkIH0gPSByZXF1ZXN0LmJvZHk7XG5cbiAgICAgICAgICBjb25zdCBlbnRpdHlJZHMgPSBFbnRpdHlNYW5hZ2VyLmdldEFsbElkcygpO1xuICAgICAgICAgIGNvbnN0IGlzUmVmZXJlbmNlZCA9IGVudGl0eUlkc1xuICAgICAgICAgICAgLmZsYXRNYXAoKGVudGl0eUlkKSA9PiBFbnRpdHlNYW5hZ2VyLmdldChlbnRpdHlJZCkucHJvcHMpXG4gICAgICAgICAgICAuc29tZSgocHJvcCkgPT4gcHJvcC50eXBlID09PSBcImVudW1cIiAmJiBwcm9wLmlkID09PSBlbnVtSWQpO1xuICAgICAgICAgIGlmIChpc1JlZmVyZW5jZWQpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihgJHtlbnVtSWR966W8IOywuOyhsO2VmOuKlCDtlITroZztjbzti7DqsIAg7KG07J6s7ZWp64uI64ukLmApO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIGNvbnN0IGVudGl0eSA9IEVudGl0eU1hbmFnZXIuZ2V0KGVudGl0eUlkKTtcbiAgICAgICAgICBkZWxldGUgZW50aXR5LmVudW1MYWJlbHNbZW51bUlkXTtcbiAgICAgICAgICBhd2FpdCBlbnRpdHkuc2F2ZSgpO1xuICAgICAgICB9KTtcbiAgICAgIH0pO1xuXG4gICAgICBzZXJ2ZXIucG9zdDx7XG4gICAgICAgIEJvZHk6IHtcbiAgICAgICAgICBlbnRpdHlJZDogc3RyaW5nO1xuICAgICAgICAgIHRhcmdldDogXCJlbnRpdHlcIiB8IFwicHJvcFwiIHwgXCJlbnVtXCIgfCBcInN1YnNldFwiO1xuICAgICAgICAgIHByb3BOYW1lPzogc3RyaW5nO1xuICAgICAgICAgIGVudW1JZD86IHN0cmluZztcbiAgICAgICAgICBzdWJzZXRLZXk/OiBzdHJpbmc7XG4gICAgICAgICAgY29uZTogQ29uZTtcbiAgICAgICAgfTtcbiAgICAgIH0+KFwiL2FwaS9lbnRpdHkvdXBkYXRlQ29uZVwiLCBhc3luYyAocmVxdWVzdCkgPT4ge1xuICAgICAgICByZXR1cm4gYXdhaXQgd2FpdEZvckhNUkNvbXBsZXRlZChhc3luYyAoKSA9PiB7XG4gICAgICAgICAgY29uc3QgeyBlbnRpdHlJZCwgdGFyZ2V0LCBwcm9wTmFtZSwgZW51bUlkLCBzdWJzZXRLZXksIGNvbmUgfSA9IHJlcXVlc3QuYm9keTtcbiAgICAgICAgICBjb25zdCBlbnRpdHkgPSBFbnRpdHlNYW5hZ2VyLmdldChlbnRpdHlJZCk7XG5cbiAgICAgICAgICBpZiAodGFyZ2V0ID09PSBcImVudGl0eVwiKSB7XG4gICAgICAgICAgICBlbnRpdHkuY29uZSA9IGNvbmU7XG4gICAgICAgICAgfSBlbHNlIGlmICh0YXJnZXQgPT09IFwicHJvcFwiICYmIHByb3BOYW1lKSB7XG4gICAgICAgICAgICBjb25zdCBwcm9wID0gZW50aXR5LnByb3BzLmZpbmQoKHApID0+IHAubmFtZSA9PT0gcHJvcE5hbWUpO1xuICAgICAgICAgICAgaWYgKHByb3ApIHtcbiAgICAgICAgICAgICAgKHByb3AgYXMgeyBjb25lPzogQ29uZSB9KS5jb25lID0gY29uZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9IGVsc2UgaWYgKHRhcmdldCA9PT0gXCJlbnVtXCIgJiYgZW51bUlkKSB7XG4gICAgICAgICAgICBlbnRpdHkuZW51bUNvbmVzW2VudW1JZF0gPSBjb25lO1xuICAgICAgICAgIH0gZWxzZSBpZiAodGFyZ2V0ID09PSBcInN1YnNldFwiICYmIHN1YnNldEtleSkge1xuICAgICAgICAgICAgZW50aXR5LnN1YnNldENvbmVzW3N1YnNldEtleV0gPSBjb25lO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIGF3YWl0IGVudGl0eS5zYXZlKCk7XG4gICAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICAgIH0pO1xuICAgICAgfSk7XG5cbiAgICAgIHNlcnZlci5wb3N0PHtcbiAgICAgICAgQm9keToge1xuICAgICAgICAgIGVudGl0eUlkOiBzdHJpbmc7XG4gICAgICAgICAgcHJlc2VydmVFeGlzdGluZz86IGJvb2xlYW47XG4gICAgICAgICAgb25seUVtcHR5PzogYm9vbGVhbjtcbiAgICAgICAgICBsb2NhbGU/OiBcImtvXCIgfCBcImVuXCIgfCBcImphXCI7XG4gICAgICAgIH07XG4gICAgICB9PihcIi9hcGkvZW50aXR5L2dlbmVyYXRlQ29uZXNcIiwgYXN5bmMgKHJlcXVlc3QsIHJlcGx5KSA9PiB7XG4gICAgICAgIHJldHVybiBhd2FpdCB3YWl0Rm9ySE1SQ29tcGxldGVkKGFzeW5jICgpID0+IHtcbiAgICAgICAgICBjb25zdCB7IGVudGl0eUlkLCBwcmVzZXJ2ZUV4aXN0aW5nLCBvbmx5RW1wdHksIGxvY2FsZSB9ID0gcmVxdWVzdC5ib2R5O1xuXG4gICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgIC8vIEVudGl0eSDsobTsnqwg7Jes67aAIO2ZleyduFxuICAgICAgICAgICAgY29uc3QgZW50aXR5ID0gRW50aXR5TWFuYWdlci5nZXQoZW50aXR5SWQpO1xuXG4gICAgICAgICAgICAvLyBsb2NhbGUg6riw67O46rCSOiBTb25hbXUuY29uZmlnLmkxOG4uZGVmYXVsdExvY2FsZSDsgqzsmqlcbiAgICAgICAgICAgIGNvbnN0IGVmZmVjdGl2ZUxvY2FsZSA9XG4gICAgICAgICAgICAgIGxvY2FsZSA/PyAoU29uYW11LmNvbmZpZy5pMThuLmRlZmF1bHRMb2NhbGUgYXMgXCJrb1wiIHwgXCJlblwiIHwgXCJqYVwiKTtcblxuICAgICAgICAgICAgLy8gQ29uZSDsg53shLFcbiAgICAgICAgICAgIGNvbnN0IHJlc3VsdCA9IGF3YWl0IGVudGl0eS5nZW5lcmF0ZUNvbmVzKHtcbiAgICAgICAgICAgICAgcHJlc2VydmVFeGlzdGluZzogcHJlc2VydmVFeGlzdGluZyA/PyB0cnVlLFxuICAgICAgICAgICAgICBvbmx5RW1wdHk6IG9ubHlFbXB0eSA/PyBmYWxzZSxcbiAgICAgICAgICAgICAgbG9jYWxlOiBlZmZlY3RpdmVMb2NhbGUsXG4gICAgICAgICAgICB9KTtcblxuICAgICAgICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICAgICAgICB9IGNhdGNoIChlcnJvcjogdW5rbm93bikge1xuICAgICAgICAgICAgY29uc3QgbWVzc2FnZSA9IGVycm9yIGluc3RhbmNlb2YgRXJyb3IgPyBlcnJvci5tZXNzYWdlIDogU3RyaW5nKGVycm9yKTtcblxuICAgICAgICAgICAgLy8gRW50aXR5IG5vdCBmb3VuZFxuICAgICAgICAgICAgaWYgKG1lc3NhZ2UuaW5jbHVkZXMoXCLsobTsnqztlZjsp4Ag7JWK64qUIEVudGl0eVwiKSkge1xuICAgICAgICAgICAgICByZXBseS5zdGF0dXMoNDA0KTtcbiAgICAgICAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgICAgICBzdWNjZXNzOiBmYWxzZSxcbiAgICAgICAgICAgICAgICBlcnJvcjogYEVudGl0eSBub3QgZm91bmQ6ICR7ZW50aXR5SWR9YCxcbiAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgLy8gQVBJIO2CpCDsl4bsnYxcbiAgICAgICAgICAgIGlmIChtZXNzYWdlLmluY2x1ZGVzKFwiQU5USFJPUElDX0FQSV9LRVkgbm90IGZvdW5kXCIpKSB7XG4gICAgICAgICAgICAgIHJlcGx5LnN0YXR1cyg1MDApO1xuICAgICAgICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgICAgIHN1Y2Nlc3M6IGZhbHNlLFxuICAgICAgICAgICAgICAgIGVycm9yOiBcIkFQSSBrZXkgbm90IGNvbmZpZ3VyZWRcIixcbiAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgLy8gUmF0ZSBsaW1pdFxuICAgICAgICAgICAgaWYgKG1lc3NhZ2UuaW5jbHVkZXMoXCJSYXRlIGxpbWl0IGV4Y2VlZGVkXCIpKSB7XG4gICAgICAgICAgICAgIHJlcGx5LnN0YXR1cyg0MjkpO1xuICAgICAgICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgICAgIHN1Y2Nlc3M6IGZhbHNlLFxuICAgICAgICAgICAgICAgIGVycm9yOiBcIlJhdGUgbGltaXQgZXhjZWVkZWQuIFBsZWFzZSB0cnkgYWdhaW4gbGF0ZXIuXCIsXG4gICAgICAgICAgICAgIH07XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIC8vIOq4sO2DgCDsl5Drn6xcbiAgICAgICAgICAgIHJlcGx5LnN0YXR1cyg1MDApO1xuICAgICAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgICAgc3VjY2VzczogZmFsc2UsXG4gICAgICAgICAgICAgIGVycm9yOiBgQ29uZSBnZW5lcmF0aW9uIGZhaWxlZDogJHttZXNzYWdlfWAsXG4gICAgICAgICAgICB9O1xuICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgICB9KTtcblxuICAgICAgc2VydmVyLmdldDx7XG4gICAgICAgIFF1ZXJ5c3RyaW5nOiB7XG4gICAgICAgICAgZW50aXR5SWQ6IHN0cmluZztcbiAgICAgICAgfTtcbiAgICAgIH0+KFwiL2FwaS9lbnRpdHkvZ2V0VGFibGVDb2x1bW5zXCIsIGFzeW5jIChyZXF1ZXN0KSA9PiB7XG4gICAgICAgIGNvbnN0IHsgZW50aXR5SWQgfSA9IHJlcXVlc3QucXVlcnk7XG4gICAgICAgIGNvbnN0IGVudGl0eSA9IEVudGl0eU1hbmFnZXIuZ2V0KGVudGl0eUlkKTtcbiAgICAgICAgY29uc3QgY29sdW1ucyA9IGVudGl0eS5nZXRUYWJsZUNvbHVtbnMoKTtcbiAgICAgICAgcmV0dXJuIHsgY29sdW1ucyB9O1xuICAgICAgfSk7XG5cbiAgICAgIHNlcnZlci5nZXQoXCIvYXBpL21pZ3JhdGlvbnMvc3RhdHVzXCIsIGFzeW5jICgpID0+IHtcbiAgICAgICAgY29uc3Qgc3RhdHVzID0gYXdhaXQgbWlncmF0b3IuZ2V0U3RhdHVzKCk7XG5cbiAgICAgICAgcmV0dXJuIHsgc3RhdHVzIH07XG4gICAgICB9KTtcblxuICAgICAgc2VydmVyLnBvc3Q8e1xuICAgICAgICBCb2R5OiB7XG4gICAgICAgICAgYWN0aW9uOiBcImFwcGx5XCIgfCBcInJvbGxiYWNrXCIgfCBcInNoYWRvd1wiO1xuICAgICAgICAgIHRhcmdldHM6IChrZXlvZiBTb25hbXVEQkNvbmZpZylbXTtcbiAgICAgICAgICBmb3JjZT86IGJvb2xlYW47XG4gICAgICAgICAgZm9yY2VSZWFzb24/OiBzdHJpbmc7XG4gICAgICAgICAgcmVxdWVzdG9yPzogc3RyaW5nO1xuICAgICAgICB9O1xuICAgICAgfT4oXG4gICAgICAgIFwiL2FwaS9taWdyYXRpb25zL3J1bkFjdGlvblwiLFxuICAgICAgICBhc3luYyAocmVxdWVzdCk6IFByb21pc2U8TWlncmF0aW9uUmVzdWx0IHwgU2xhY2tDb25maXJtUGVuZGluZ1Jlc3VsdD4gPT4ge1xuICAgICAgICAgIGNvbnN0IHsgYWN0aW9uLCB0YXJnZXRzLCBmb3JjZSwgZm9yY2VSZWFzb24sIHJlcXVlc3RvciB9ID0gcmVxdWVzdC5ib2R5O1xuXG4gICAgICAgICAgaWYgKGFjdGlvbiA9PT0gXCJzaGFkb3dcIikge1xuICAgICAgICAgICAgcmV0dXJuIG1pZ3JhdG9yLnJ1blNoYWRvd1Rlc3QoKTtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICAvLyBTbGFjayDsirnsnbgg7LK07YGsIChhcHBseSDsi5zsl5Drp4wpXG4gICAgICAgICAgaWYgKGFjdGlvbiA9PT0gXCJhcHBseVwiKSB7XG4gICAgICAgICAgICBjb25zdCBzbGFja0NvbmZpcm0gPSBuZXcgU2xhY2tDb25maXJtKCk7XG4gICAgICAgICAgICBjb25zdCByZXF1aXJlc0FwcHJvdmFsID0gdGFyZ2V0cy5zb21lKCh0KSA9PiBzbGFja0NvbmZpcm0uaXNUYXJnZXRSZXF1aXJlc0FwcHJvdmFsKHQpKTtcblxuICAgICAgICAgICAgLy8g66Gc7LusIERC7J24IOqyveyasCDsirnsnbgg7Iqk7YK1XG4gICAgICAgICAgICBjb25zdCBsb2NhbEhvc3RzID0gW1wibG9jYWxob3N0XCIsIFwiMTI3LjAuMC4xXCIsIFwiMC4wLjAuMFwiLCBcIjo6MVwiXTtcbiAgICAgICAgICAgIGNvbnN0IGlzTG9jYWxUYXJnZXQgPSB0YXJnZXRzLmV2ZXJ5KCh0YXJnZXQpID0+IHtcbiAgICAgICAgICAgICAgY29uc3QgdGFyZ2V0Q29uZmlnID0gU29uYW11LmRiQ29uZmlnW3RhcmdldF07XG4gICAgICAgICAgICAgIGNvbnN0IGhvc3QgPSAodGFyZ2V0Q29uZmlnPy5jb25uZWN0aW9uIGFzIHsgaG9zdD86IHN0cmluZyB9KT8uaG9zdCA/PyBcImxvY2FsaG9zdFwiO1xuICAgICAgICAgICAgICByZXR1cm4gbG9jYWxIb3N0cy5pbmNsdWRlcyhob3N0LnRvTG93ZXJDYXNlKCkpO1xuICAgICAgICAgICAgfSk7XG5cbiAgICAgICAgICAgIGlmIChyZXF1aXJlc0FwcHJvdmFsICYmIHNsYWNrQ29uZmlybS5pc0NvbmZpZ3VyZWQoKSAmJiAhaXNMb2NhbFRhcmdldCkge1xuICAgICAgICAgICAgICBjb25zdCB7IGNvbm5zIH0gPSBhd2FpdCBtaWdyYXRvci5nZXRTdGF0dXMoKTtcblxuICAgICAgICAgICAgICAvLyDrqqjrk6Ag7YOA6rKfIERC7JeQ7IScIHBlbmRpbmfsnbgg66eI7J206re466CI7J207IWY7J2YIO2Vqeynke2VqeydhCDqtaztlanri4jri6QuXG4gICAgICAgICAgICAgIGNvbnN0IHBlbmRpbmdNaWdyYXRpb25zID0gW1xuICAgICAgICAgICAgICAgIC4uLm5ldyBTZXQoXG4gICAgICAgICAgICAgICAgICBjb25uc1xuICAgICAgICAgICAgICAgICAgICAuZmlsdGVyKChjb25uKSA9PiB0YXJnZXRzLmluY2x1ZGVzKGNvbm4uY29ubktleSkpXG4gICAgICAgICAgICAgICAgICAgIC5mbGF0TWFwKChjb25uKSA9PiBjb25uLnBlbmRpbmcpLFxuICAgICAgICAgICAgICAgICksXG4gICAgICAgICAgICAgIF07XG5cbiAgICAgICAgICAgICAgaWYgKHBlbmRpbmdNaWdyYXRpb25zLmxlbmd0aCA+IDApIHtcbiAgICAgICAgICAgICAgICAvLyDquLDsobQg7Iq57J24IOyalOyyrSDtmZXsnbhcbiAgICAgICAgICAgICAgICBjb25zdCBleGlzdGluZyA9IGF3YWl0IHNsYWNrQ29uZmlybS5nZXRFeGlzdGluZ1JlcXVlc3QocGVuZGluZ01pZ3JhdGlvbnMpO1xuXG4gICAgICAgICAgICAgICAgaWYgKGV4aXN0aW5nKSB7XG4gICAgICAgICAgICAgICAgICAvLyDquLDsobQg7JqU7LKt7J20IOyeiOycvOuptCDsirnsnbgg7IOB7YOcIO2ZleyduFxuICAgICAgICAgICAgICAgICAgY29uc3QgeyBhcHByb3ZlZCwgcmVqZWN0ZWQgfSA9IGF3YWl0IHNsYWNrQ29uZmlybS5jaGVja0FwcHJvdmFsKFxuICAgICAgICAgICAgICAgICAgICBleGlzdGluZy5jaGFubmVsLFxuICAgICAgICAgICAgICAgICAgICBleGlzdGluZy50cyxcbiAgICAgICAgICAgICAgICAgICk7XG5cbiAgICAgICAgICAgICAgICAgIGlmIChhcHByb3ZlZCkge1xuICAgICAgICAgICAgICAgICAgICAvLyDsirnsnbjrkKgg4oaSIOyLpO2WiVxuICAgICAgICAgICAgICAgICAgICBjb25zdCByZXN1bHQgPSBhd2FpdCBtaWdyYXRvci5ydW5BY3Rpb24oYWN0aW9uLCB0YXJnZXRzKTtcbiAgICAgICAgICAgICAgICAgICAgaWYgKHJlc3VsdC5sZW5ndGggPiAwKSB7XG4gICAgICAgICAgICAgICAgICAgICAgYXdhaXQgc2xhY2tDb25maXJtLmxvZ0V4ZWN1dGlvbihcbiAgICAgICAgICAgICAgICAgICAgICAgIGV4aXN0aW5nLmNoYW5uZWwsXG4gICAgICAgICAgICAgICAgICAgICAgICBleGlzdGluZy50cyxcbiAgICAgICAgICAgICAgICAgICAgICAgIHJlc3VsdCxcbiAgICAgICAgICAgICAgICAgICAgICAgIHJlcXVlc3RvcixcbiAgICAgICAgICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKHJlamVjdGVkKSB7XG4gICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBCYWRSZXF1ZXN0RXhjZXB0aW9uKFNEKFwic29uYW11LmVycm9yLm1pZ3JhdGlvblJlamVjdGVkXCIpKTtcbiAgICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAoZm9yY2UpIHtcbiAgICAgICAgICAgICAgICAgICAgLy8gRm9yY2Ug7KeE7ZaJXG4gICAgICAgICAgICAgICAgICAgIGF3YWl0IHNsYWNrQ29uZmlybS5mb3JjZUFwcHJvdmFsKFxuICAgICAgICAgICAgICAgICAgICAgIGV4aXN0aW5nLmNoYW5uZWwsXG4gICAgICAgICAgICAgICAgICAgICAgZXhpc3RpbmcudHMsXG4gICAgICAgICAgICAgICAgICAgICAgZm9yY2VSZWFzb24gPz8gXCLsgqzsnKAg7JeG7J2MXCIsXG4gICAgICAgICAgICAgICAgICAgICAgcmVxdWVzdG9yLFxuICAgICAgICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgICAgICAgICBjb25zdCByZXN1bHQgPSBhd2FpdCBtaWdyYXRvci5ydW5BY3Rpb24oYWN0aW9uLCB0YXJnZXRzKTtcbiAgICAgICAgICAgICAgICAgICAgaWYgKHJlc3VsdC5sZW5ndGggPiAwKSB7XG4gICAgICAgICAgICAgICAgICAgICAgYXdhaXQgc2xhY2tDb25maXJtLmxvZ0V4ZWN1dGlvbihcbiAgICAgICAgICAgICAgICAgICAgICAgIGV4aXN0aW5nLmNoYW5uZWwsXG4gICAgICAgICAgICAgICAgICAgICAgICBleGlzdGluZy50cyxcbiAgICAgICAgICAgICAgICAgICAgICAgIHJlc3VsdCxcbiAgICAgICAgICAgICAgICAgICAgICAgIHJlcXVlc3RvcixcbiAgICAgICAgICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAvLyDrjIDquLDspJFcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgICAgICAgICAgICB0eXBlOiBcInBlbmRpbmdcIixcbiAgICAgICAgICAgICAgICAgICAgICBjaGFubmVsOiBleGlzdGluZy5jaGFubmVsLFxuICAgICAgICAgICAgICAgICAgICAgIHRzOiBleGlzdGluZy50cyxcbiAgICAgICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgLy8g7IOIIOyKueyduCDsmpTssq0g67Cc7IahXG4gICAgICAgICAgICAgICAgICBjb25zdCB7IGNoYW5uZWwsIHRzIH0gPSBhd2FpdCBzbGFja0NvbmZpcm0ucG9zdEFwcHJvdmFsUmVxdWVzdChcbiAgICAgICAgICAgICAgICAgICAgcGVuZGluZ01pZ3JhdGlvbnMsXG4gICAgICAgICAgICAgICAgICAgIHRhcmdldHMsXG4gICAgICAgICAgICAgICAgICAgIHJlcXVlc3RvcixcbiAgICAgICAgICAgICAgICAgICk7XG4gICAgICAgICAgICAgICAgICBhd2FpdCBzbGFja0NvbmZpcm0uc2F2ZVJlcXVlc3QocGVuZGluZ01pZ3JhdGlvbnMsIGNoYW5uZWwsIHRzKTtcblxuICAgICAgICAgICAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgICAgICAgICAgdHlwZTogXCJwZW5kaW5nXCIsXG4gICAgICAgICAgICAgICAgICAgIGNoYW5uZWwsXG4gICAgICAgICAgICAgICAgICAgIHRzLFxuICAgICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG5cbiAgICAgICAgICByZXR1cm4gbWlncmF0b3IucnVuQWN0aW9uKGFjdGlvbiwgdGFyZ2V0cyk7XG4gICAgICAgIH0sXG4gICAgICApO1xuXG4gICAgICBzZXJ2ZXIucG9zdDx7XG4gICAgICAgIEJvZHk6IHtcbiAgICAgICAgICBjaGFubmVsOiBzdHJpbmc7XG4gICAgICAgICAgdHM6IHN0cmluZztcbiAgICAgICAgfTtcbiAgICAgIH0+KFwiL2FwaS9taWdyYXRpb25zL2NoZWNrQXBwcm92YWxcIiwgYXN5bmMgKHJlcXVlc3QpID0+IHtcbiAgICAgICAgY29uc3QgeyBjaGFubmVsLCB0cyB9ID0gcmVxdWVzdC5ib2R5O1xuICAgICAgICBjb25zdCBzbGFja0NvbmZpcm0gPSBuZXcgU2xhY2tDb25maXJtKCk7XG5cbiAgICAgICAgaWYgKCFzbGFja0NvbmZpcm0uaXNDb25maWd1cmVkKCkpIHtcbiAgICAgICAgICByZXR1cm4geyBhcHByb3ZlZDogdHJ1ZSwgcmVqZWN0ZWQ6IGZhbHNlIH07XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gc2xhY2tDb25maXJtLmNoZWNrQXBwcm92YWwoY2hhbm5lbCwgdHMpO1xuICAgICAgfSk7XG5cbiAgICAgIHNlcnZlci5wb3N0PHtcbiAgICAgICAgQm9keToge1xuICAgICAgICAgIGNoYW5uZWw6IHN0cmluZztcbiAgICAgICAgICB0czogc3RyaW5nO1xuICAgICAgICAgIHJlYXNvbjogc3RyaW5nO1xuICAgICAgICAgIHJlcXVlc3Rvcj86IHN0cmluZztcbiAgICAgICAgfTtcbiAgICAgIH0+KFwiL2FwaS9taWdyYXRpb25zL2ZvcmNlQXBwcm92YWxcIiwgYXN5bmMgKHJlcXVlc3QpID0+IHtcbiAgICAgICAgY29uc3QgeyBjaGFubmVsLCB0cywgcmVhc29uLCByZXF1ZXN0b3IgfSA9IHJlcXVlc3QuYm9keTtcbiAgICAgICAgY29uc3Qgc2xhY2tDb25maXJtID0gbmV3IFNsYWNrQ29uZmlybSgpO1xuXG4gICAgICAgIGlmICghc2xhY2tDb25maXJtLmlzQ29uZmlndXJlZCgpKSB7XG4gICAgICAgICAgdGhyb3cgbmV3IEJhZFJlcXVlc3RFeGNlcHRpb24oU0QoXCJzb25hbXUuZXJyb3Iuc2xhY2tDb25maXJtTm90Q29uZmlndXJlZFwiKSk7XG4gICAgICAgIH1cblxuICAgICAgICBhd2FpdCBzbGFja0NvbmZpcm0uZm9yY2VBcHByb3ZhbChjaGFubmVsLCB0cywgcmVhc29uLCByZXF1ZXN0b3IpO1xuICAgICAgICByZXR1cm4geyBzdWNjZXNzOiB0cnVlIH07XG4gICAgICB9KTtcblxuICAgICAgc2VydmVyLnBvc3Q8e1xuICAgICAgICBCb2R5OiB7XG4gICAgICAgICAgY29kZU5hbWVzOiBzdHJpbmdbXTtcbiAgICAgICAgfTtcbiAgICAgIH0+KFwiL2FwaS9taWdyYXRpb25zL2RlbENvZGVzXCIsIGFzeW5jIChyZXF1ZXN0KSA9PiB7XG4gICAgICAgIGNvbnN0IHsgY29kZU5hbWVzIH0gPSByZXF1ZXN0LmJvZHk7XG4gICAgICAgIHJldHVybiBhd2FpdCBtaWdyYXRvci5kZWxDb2Rlcyhjb2RlTmFtZXMpO1xuICAgICAgfSk7XG5cbiAgICAgIHNlcnZlci5wb3N0KFwiL2FwaS9taWdyYXRpb25zL2dlbmVyYXRlUHJlcGFyZWRDb2Rlc1wiLCBhc3luYyAoX3JlcXVlc3R0KSA9PiB7XG4gICAgICAgIHJldHVybiBhd2FpdCBtaWdyYXRvci5nZW5lcmF0ZVByZXBhcmVkQ29kZXMoKTtcbiAgICAgIH0pO1xuXG4gICAgICBzZXJ2ZXIucG9zdDx7XG4gICAgICAgIEJvZHk6IHtcbiAgICAgICAgICBlbnRpdHlJZHM6IHN0cmluZ1tdO1xuICAgICAgICAgIHRlbXBsYXRlS2V5czogc3RyaW5nW107XG4gICAgICAgIH07XG4gICAgICB9PihcIi9hcGkvc2NhZmZvbGRpbmcvZ2V0U3RhdHVzXCIsIGFzeW5jIChyZXF1ZXN0KSA9PiB7XG4gICAgICAgIGNvbnN0IHsgZW50aXR5SWRzLCB0ZW1wbGF0ZUtleXM6IF90ZW1wbGF0ZUtleXMgfSA9IHJlcXVlc3QuYm9keTtcbiAgICAgICAgaWYgKChlbnRpdHlJZHMgPz8gW10pLmxlbmd0aCA9PT0gMCkge1xuICAgICAgICAgIHRocm93IG5ldyBCYWRSZXF1ZXN0RXhjZXB0aW9uKFNEKFwic29uYW11LmVycm9yLmVudGl0eUlkc1JlcXVpcmVkXCIpKTtcbiAgICAgICAgfSBlbHNlIGlmICgoX3RlbXBsYXRlS2V5cyA/PyBbXSkubGVuZ3RoID09PSAwKSB7XG4gICAgICAgICAgdGhyb3cgbmV3IEJhZFJlcXVlc3RFeGNlcHRpb24oU0QoXCJzb25hbXUuZXJyb3IudGVtcGxhdGVLZXlzUmVxdWlyZWRcIikpO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gc29ydGluZ1xuICAgICAgICBlbnRpdHlJZHMuc29ydCgoYSwgYikgPT4gKGEgPCBiID8gLTEgOiBhID4gYiA/IDEgOiAwKSk7XG4gICAgICAgIGNvbnN0IHRlbXBsYXRlS2V5cyA9IFRlbXBsYXRlS2V5Lm9wdGlvbnMuZmlsdGVyKCh0aykgPT4gX3RlbXBsYXRlS2V5cy5pbmNsdWRlcyh0aykpO1xuXG4gICAgICAgIGNvbnN0IGNvbWJpbmF0aW9ucyA9IGVudGl0eUlkcy5mbGF0TWFwKChlbnRpdHlJZCkgPT4ge1xuICAgICAgICAgIHJldHVybiB0ZW1wbGF0ZUtleXMubWFwKCh0ZW1wbGF0ZUtleSkgPT4gW2VudGl0eUlkLCB0ZW1wbGF0ZUtleV0pO1xuICAgICAgICB9KTtcblxuICAgICAgICBjb25zdCBzdGF0dXNlcyA9IGF3YWl0IFByb21pc2UuYWxsKFxuICAgICAgICAgIGNvbWJpbmF0aW9ucy5tYXAoYXN5bmMgKFtlbnRpdHlJZCwgdGVtcGxhdGVLZXldKSA9PiB7XG4gICAgICAgICAgICBjb25zdCB7IHN1YlBhdGgsIGZ1bGxQYXRoLCBpc0V4aXN0cyB9ID0gYXdhaXQgU29uYW11LnN5bmNlci5jaGVja0V4aXN0c0dlbkNvZGUoXG4gICAgICAgICAgICAgIGVudGl0eUlkLFxuICAgICAgICAgICAgICB0ZW1wbGF0ZUtleSBhcyBUZW1wbGF0ZUtleSxcbiAgICAgICAgICAgICk7XG4gICAgICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgICBlbnRpdHlJZCxcbiAgICAgICAgICAgICAgdGVtcGxhdGVLZXksXG4gICAgICAgICAgICAgIHN1YlBhdGgsXG4gICAgICAgICAgICAgIGZ1bGxQYXRoLFxuICAgICAgICAgICAgICBpc0V4aXN0cyxcbiAgICAgICAgICAgIH07XG4gICAgICAgICAgfSksXG4gICAgICAgICk7XG4gICAgICAgIHJldHVybiB7IHN0YXR1c2VzIH07XG4gICAgICB9KTtcblxuICAgICAgc2VydmVyLnBvc3Q8e1xuICAgICAgICBCb2R5OiB7XG4gICAgICAgICAgb3B0aW9uczoge1xuICAgICAgICAgICAgZW50aXR5SWQ6IHN0cmluZztcbiAgICAgICAgICAgIHRlbXBsYXRlS2V5OiBzdHJpbmc7XG4gICAgICAgICAgICBlbnVtSWQ/OiBzdHJpbmc7XG4gICAgICAgICAgICBvdmVyd3JpdGU/OiBib29sZWFuO1xuICAgICAgICAgIH1bXTtcbiAgICAgICAgfTtcbiAgICAgIH0+KFwiL2FwaS9zY2FmZm9sZGluZy9nZW5lcmF0ZVwiLCBhc3luYyAocmVxdWVzdCkgPT4ge1xuICAgICAgICBjb25zdCB7IG9wdGlvbnMgfSA9IHJlcXVlc3QuYm9keTtcbiAgICAgICAgaWYgKG9wdGlvbnMubGVuZ3RoID09PSAwKSB7XG4gICAgICAgICAgdGhyb3cgbmV3IEJhZFJlcXVlc3RFeGNlcHRpb24oU0QoXCJzb25hbXUuZXJyb3Iub3B0aW9uc1JlcXVpcmVkXCIpKTtcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIDEuIOuqqOuToCDthZztlIzrpr/sl5DshJwg7ZWE7JqU7ZWcIGRpY3Qg7YKk66W8IOyImOynkVxuICAgICAgICBjb25zdCBrZXlzID0gb3B0aW9ucy5mbGF0TWFwKCh7IHRlbXBsYXRlS2V5IH0pID0+IHtcbiAgICAgICAgICBjb25zdCB0ZW1wbGF0ZSA9IFRlbXBsYXRlTWFuYWdlci5nZXQodGVtcGxhdGVLZXkpO1xuICAgICAgICAgIHJldHVybiB0ZW1wbGF0ZS5nZXRSZXF1aXJlZERpY3RLZXlzKCkgPz8gW107XG4gICAgICAgIH0pO1xuXG4gICAgICAgIC8vIDIuIHRhcmdldOuzhOuhnCBlbnN1cmVEaWN0S2V5cyDtmLjstpwgKOyInOywqCDsspjrpqwpXG4gICAgICAgIGF3YWl0IHNvbmFtdURpY3Rpb25hcnkuZW5zdXJlRGljdEtleXMoWy4uLm5ldyBTZXQoa2V5cyldKTtcblxuICAgICAgICAvLyAzLiDthZztlIzrpr8g7IOd7ISxICjrs5HroKwg7LKY66asKVxuICAgICAgICBjb25zdCByZXN1bHQgPSBhd2FpdCBQcm9taXNlLmFsbChcbiAgICAgICAgICBvcHRpb25zLm1hcChhc3luYyAoeyBlbnRpdHlJZCwgdGVtcGxhdGVLZXksIGVudW1JZCwgb3ZlcndyaXRlIH0pID0+IHtcbiAgICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICAgIHJldHVybiBhd2FpdCBTb25hbXUuc3luY2VyLmdlbmVyYXRlVGVtcGxhdGUoXG4gICAgICAgICAgICAgICAgdGVtcGxhdGVLZXkgYXMgVGVtcGxhdGVLZXksXG4gICAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgICAgZW50aXR5SWQsXG4gICAgICAgICAgICAgICAgICBlbnVtSWQsXG4gICAgICAgICAgICAgICAgfSBhcyB7XG4gICAgICAgICAgICAgICAgICBlbnRpdHlJZDogc3RyaW5nO1xuICAgICAgICAgICAgICAgICAgZW51bUlkPzogc3RyaW5nO1xuICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgICAgb3ZlcndyaXRlLFxuICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICk7XG4gICAgICAgICAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgICAgICAgIGlmIChpc1NvRXhjZXB0aW9uKGUpICYmIGUuc3RhdHVzQ29kZSA9PT0gNTQxKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgY29uc29sZS5lcnJvcihlKTtcbiAgICAgICAgICAgICAgICB0aHJvdyBlO1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfSksXG4gICAgICAgICk7XG5cbiAgICAgICAgaWYgKHJlc3VsdC5maWx0ZXIobm9uTnVsbGFibGUpLmxlbmd0aCA9PT0gMCkge1xuICAgICAgICAgIHRocm93IG5ldyBTZXJ2aWNlVW5hdmFpbGFibGVFeGNlcHRpb24oU0QoXCJzb25hbXUuZXJyb3IuYWxsRmlsZXNHZW5lcmF0ZWRcIikpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgICB9KTtcblxuICAgICAgc2VydmVyLnBvc3Q8e1xuICAgICAgICBCb2R5OiB7XG4gICAgICAgICAgb3B0aW9uOiB7XG4gICAgICAgICAgICBlbnRpdHlJZDogc3RyaW5nO1xuICAgICAgICAgICAgdGVtcGxhdGVLZXk6IHN0cmluZztcbiAgICAgICAgICAgIGVudW1JZD86IHN0cmluZztcbiAgICAgICAgICB9O1xuICAgICAgICB9O1xuICAgICAgfT4oXCIvYXBpL3NjYWZmb2xkaW5nL3ByZXZpZXdcIiwgYXN5bmMgKHJlcXVlc3QpOiBQcm9taXNlPHsgcGF0aEFuZENvZGVzOiBQYXRoQW5kQ29kZVtdIH0+ID0+IHtcbiAgICAgICAgY29uc3QgeyBvcHRpb24gfSA9IHJlcXVlc3QuYm9keTtcblxuICAgICAgICB0cnkge1xuICAgICAgICAgIGNvbnN0IHsgdGVtcGxhdGVLZXksIC4uLnRlbXBsYXRlT3B0aW9ucyB9ID0gb3B0aW9uO1xuICAgICAgICAgIGNvbnN0IHBhdGhBbmRDb2RlcyA9IGF3YWl0IFNvbmFtdS5zeW5jZXIucmVuZGVyVGVtcGxhdGUoXG4gICAgICAgICAgICB0ZW1wbGF0ZUtleSBhcyBUZW1wbGF0ZUtleSxcbiAgICAgICAgICAgIHRlbXBsYXRlT3B0aW9ucyxcbiAgICAgICAgICApO1xuXG4gICAgICAgICAgcmV0dXJuIHsgcGF0aEFuZENvZGVzIH07XG4gICAgICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgICBjb25zb2xlLmVycm9yKGUpO1xuICAgICAgICAgIHRocm93IGU7XG4gICAgICAgIH1cbiAgICAgIH0pO1xuXG4gICAgICBzZXJ2ZXIucG9zdChcIi9hcGkvZml4dHVyZVwiLCBhc3luYyAocmVxdWVzdCkgPT4ge1xuICAgICAgICBjb25zdCB7IHNvdXJjZURCLCB0YXJnZXREQiwgc2VhcmNoLCBkdXBsaWNhdGVDaGVjayB9ID0gcmVxdWVzdC5ib2R5IGFzIHtcbiAgICAgICAgICBzb3VyY2VEQjoga2V5b2YgU29uYW11REJDb25maWc7XG4gICAgICAgICAgdGFyZ2V0REI6IGtleW9mIFNvbmFtdURCQ29uZmlnO1xuICAgICAgICAgIHNlYXJjaDogRml4dHVyZVNlYXJjaE9wdGlvbnM7XG4gICAgICAgICAgZHVwbGljYXRlQ2hlY2s/OiBEdXBsaWNhdGVDaGVja09wdGlvbnM7XG4gICAgICAgIH07XG5cbiAgICAgICAgcmV0dXJuIEZpeHR1cmVNYW5hZ2VyLmdldEZpeHR1cmVzKHNvdXJjZURCLCB0YXJnZXREQiwgc2VhcmNoLCBkdXBsaWNhdGVDaGVjayk7XG4gICAgICB9KTtcblxuICAgICAgc2VydmVyLnBvc3QoXCIvYXBpL2ZpeHR1cmUvaW1wb3J0XCIsIGFzeW5jIChyZXF1ZXN0KSA9PiB7XG4gICAgICAgIGNvbnN0IHsgZGIsIGZpeHR1cmVzIH0gPSByZXF1ZXN0LmJvZHkgYXMge1xuICAgICAgICAgIGRiOiBrZXlvZiBTb25hbXVEQkNvbmZpZztcbiAgICAgICAgICBmaXh0dXJlczogRml4dHVyZVJlY29yZFtdO1xuICAgICAgICB9O1xuXG4gICAgICAgIHJldHVybiBGaXh0dXJlTWFuYWdlci5pbnNlcnRGaXh0dXJlcyhkYiwgZml4dHVyZXMpO1xuICAgICAgfSk7XG5cbiAgICAgIHNlcnZlci5wb3N0KFwiL2FwaS9maXh0dXJlL2FkZEZpeHR1cmVMb2FkZXJcIiwgYXN5bmMgKHJlcXVlc3QpID0+IHtcbiAgICAgICAgY29uc3QgeyBjb2RlIH0gPSByZXF1ZXN0LmJvZHkgYXMgeyBjb2RlOiBzdHJpbmcgfTtcblxuICAgICAgICByZXR1cm4gRml4dHVyZU1hbmFnZXIuYWRkRml4dHVyZUxvYWRlcihjb2RlKTtcbiAgICAgIH0pO1xuXG4gICAgICBzZXJ2ZXIuZ2V0KFwiL2FwaS9pMThuL2RpY3Rpb25hcnlcIiwgYXN5bmMgKCkgPT4ge1xuICAgICAgICByZXR1cm4gc29uYW11RGljdGlvbmFyeS5nZXREaWN0aW9uYXJ5KCk7XG4gICAgICB9KTtcblxuICAgICAgc2VydmVyLmdldChcIi9hcGkvaTE4bi9leHBvcnRcIiwgYXN5bmMgKF9yZXF1ZXN0LCByZXBseSkgPT4ge1xuICAgICAgICBjb25zdCB7IGZpbGVuYW1lLCBidWZmZXIgfSA9IGF3YWl0IHNvbmFtdURpY3Rpb25hcnkuZXhwb3J0VG9FeGNlbCgpO1xuICAgICAgICByZXBseVxuICAgICAgICAgIC5oZWFkZXIoXG4gICAgICAgICAgICBcIkNvbnRlbnQtVHlwZVwiLFxuICAgICAgICAgICAgXCJhcHBsaWNhdGlvbi92bmQub3BlbnhtbGZvcm1hdHMtb2ZmaWNlZG9jdW1lbnQuc3ByZWFkc2hlZXRtbC5zaGVldFwiLFxuICAgICAgICAgIClcbiAgICAgICAgICAuaGVhZGVyKFwiQ29udGVudC1EaXNwb3NpdGlvblwiLCBgYXR0YWNobWVudDsgZmlsZW5hbWU9XCIke2ZpbGVuYW1lfVwiYClcbiAgICAgICAgICAuc2VuZChidWZmZXIpO1xuICAgICAgfSk7XG5cbiAgICAgIHNlcnZlci5wb3N0KFwiL2FwaS9pMThuL2ltcG9ydFwiLCBhc3luYyAocmVxdWVzdCkgPT4ge1xuICAgICAgICBjb25zdCBkYXRhID0gYXdhaXQgcmVxdWVzdC5maWxlKCk7XG4gICAgICAgIGlmICghZGF0YSkge1xuICAgICAgICAgIHRocm93IG5ldyBCYWRSZXF1ZXN0RXhjZXB0aW9uKFNEKFwic29uYW11LmVycm9yLmZpbGVOb3RVcGxvYWRlZFwiKSk7XG4gICAgICAgIH1cbiAgICAgICAgY29uc3QgYnVmZmVyID0gYXdhaXQgZGF0YS50b0J1ZmZlcigpO1xuICAgICAgICByZXR1cm4gc29uYW11RGljdGlvbmFyeS5pbXBvcnRGcm9tRXhjZWwoYnVmZmVyKTtcbiAgICAgIH0pO1xuXG4gICAgICBzZXJ2ZXIucG9zdDx7XG4gICAgICAgIEJvZHk6IHtcbiAgICAgICAgICBvbGRLZXk6IHN0cmluZztcbiAgICAgICAgICBuZXdLZXk6IHN0cmluZztcbiAgICAgICAgICBzb3VyY2U6IFwiZW50aXR5XCIgfCBcInByb2plY3RcIiB8IFwic29uYW11XCI7XG4gICAgICAgICAgdmFsdWVzOiBSZWNvcmQ8c3RyaW5nLCBzdHJpbmc+O1xuICAgICAgICB9O1xuICAgICAgfT4oXCIvYXBpL2kxOG4vdXBkYXRlXCIsIGFzeW5jIChyZXF1ZXN0KSA9PiB7XG4gICAgICAgIGF3YWl0IHNvbmFtdURpY3Rpb25hcnkudXBkYXRlRW50cnkocmVxdWVzdC5ib2R5KTtcbiAgICAgICAgcmV0dXJuIHsgc3VjY2VzczogdHJ1ZSB9O1xuICAgICAgfSk7XG5cbiAgICAgIHNlcnZlci5wb3N0PHtcbiAgICAgICAgQm9keToge1xuICAgICAgICAgIGtleTogc3RyaW5nO1xuICAgICAgICAgIHZhbHVlczogUmVjb3JkPHN0cmluZywgc3RyaW5nPjtcbiAgICAgICAgfTtcbiAgICAgIH0+KFwiL2FwaS9pMThuL2NyZWF0ZVwiLCBhc3luYyAocmVxdWVzdCkgPT4ge1xuICAgICAgICBhd2FpdCBzb25hbXVEaWN0aW9uYXJ5LmNyZWF0ZUVudHJ5KHJlcXVlc3QuYm9keSk7XG4gICAgICAgIHJldHVybiB7IHN1Y2Nlc3M6IHRydWUgfTtcbiAgICAgIH0pO1xuXG4gICAgICBzZXJ2ZXIucG9zdDx7XG4gICAgICAgIEJvZHk6IHtcbiAgICAgICAgICBrZXk6IHN0cmluZztcbiAgICAgICAgfTtcbiAgICAgIH0+KFwiL2FwaS9pMThuL2RlbGV0ZVwiLCBhc3luYyAocmVxdWVzdCkgPT4ge1xuICAgICAgICBhd2FpdCBzb25hbXVEaWN0aW9uYXJ5LmRlbGV0ZUVudHJ5KHJlcXVlc3QuYm9keS5rZXkpO1xuICAgICAgICByZXR1cm4geyBzdWNjZXNzOiB0cnVlIH07XG4gICAgICB9KTtcblxuICAgICAgc2VydmVyLnBvc3Q8eyBCb2R5OiB7IGtleXM6IHN0cmluZ1tdIH0gfT4oXCIvYXBpL2kxOG4vY2hlY2tVc2FnZVwiLCBhc3luYyAocmVxdWVzdCkgPT4ge1xuICAgICAgICByZXR1cm4gc29uYW11RGljdGlvbmFyeS5jaGVja1VzYWdlKHJlcXVlc3QuYm9keS5rZXlzKTtcbiAgICAgIH0pO1xuXG4gICAgICAvLyBUYXNrcyBBUElcbiAgICAgIHNlcnZlci5nZXQoXCIvYXBpL3Rhc2tzL3N0YXR1c1wiLCBhc3luYyAoKSA9PiB7XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgU29uYW11LndvcmtmbG93cztcbiAgICAgICAgICByZXR1cm4geyBhY3RpdmU6IHRydWUgfTtcbiAgICAgICAgfSBjYXRjaCB7XG4gICAgICAgICAgcmV0dXJuIHsgYWN0aXZlOiBmYWxzZSB9O1xuICAgICAgICB9XG4gICAgICB9KTtcblxuICAgICAgc2VydmVyLmdldChcIi9hcGkvdGFza3Mvd29ya2Zsb3dEZWZpbml0aW9uc1wiLCBhc3luYyAoKSA9PiB7XG4gICAgICAgIGNvbnN0IGRlZmluaXRpb25zID0gU29uYW11LndvcmtmbG93cy53b3JrZmxvd0RlZmluaXRpb25zO1xuICAgICAgICByZXR1cm4geyBkZWZpbml0aW9ucyB9O1xuICAgICAgfSk7XG5cbiAgICAgIHNlcnZlci5nZXQ8e1xuICAgICAgICBRdWVyeXN0cmluZzoge1xuICAgICAgICAgIGxpbWl0Pzogc3RyaW5nO1xuICAgICAgICAgIGFmdGVyPzogc3RyaW5nO1xuICAgICAgICAgIGJlZm9yZT86IHN0cmluZztcbiAgICAgICAgICBvcmRlcj86IFwiYXNjXCIgfCBcImRlc2NcIjtcbiAgICAgICAgICBzdGF0dXM/OiBzdHJpbmc7XG4gICAgICAgICAgd29ya2Zsb3dOYW1lPzogc3RyaW5nO1xuICAgICAgICAgIGNyZWF0ZWRBZnRlcj86IHN0cmluZztcbiAgICAgICAgICBjcmVhdGVkQmVmb3JlPzogc3RyaW5nO1xuICAgICAgICB9O1xuICAgICAgfT4oXCIvYXBpL3Rhc2tzL3dvcmtmbG93UnVuc1wiLCBhc3luYyAocmVxdWVzdCkgPT4ge1xuICAgICAgICBjb25zdCBiYWNrZW5kID0gU29uYW11LndvcmtmbG93cy5iYWNrZW5kO1xuICAgICAgICBjb25zdCB7IGxpbWl0LCBhZnRlciwgYmVmb3JlLCBvcmRlciwgc3RhdHVzLCB3b3JrZmxvd05hbWUsIGNyZWF0ZWRBZnRlciwgY3JlYXRlZEJlZm9yZSB9ID1cbiAgICAgICAgICByZXF1ZXN0LnF1ZXJ5O1xuICAgICAgICByZXR1cm4gYmFja2VuZC5saXN0V29ya2Zsb3dSdW5zKHtcbiAgICAgICAgICBsaW1pdDogbGltaXQgPyBOdW1iZXIucGFyc2VJbnQobGltaXQsIDEwKSA6IHVuZGVmaW5lZCxcbiAgICAgICAgICBhZnRlcixcbiAgICAgICAgICBiZWZvcmUsXG4gICAgICAgICAgb3JkZXIsXG4gICAgICAgICAgc3RhdHVzOiBzdGF0dXMgPyBzdGF0dXMuc3BsaXQoXCIsXCIpIDogdW5kZWZpbmVkLFxuICAgICAgICAgIHdvcmtmbG93TmFtZTogd29ya2Zsb3dOYW1lIHx8IHVuZGVmaW5lZCxcbiAgICAgICAgICBjcmVhdGVkQWZ0ZXI6IGNyZWF0ZWRBZnRlciA/IG5ldyBEYXRlKGNyZWF0ZWRBZnRlcikgOiB1bmRlZmluZWQsXG4gICAgICAgICAgY3JlYXRlZEJlZm9yZTogY3JlYXRlZEJlZm9yZSA/IG5ldyBEYXRlKGNyZWF0ZWRCZWZvcmUpIDogdW5kZWZpbmVkLFxuICAgICAgICB9KTtcbiAgICAgIH0pO1xuXG4gICAgICBzZXJ2ZXIuZ2V0PHtcbiAgICAgICAgUGFyYW1zOiB7IGlkOiBzdHJpbmcgfTtcbiAgICAgIH0+KFwiL2FwaS90YXNrcy93b3JrZmxvd1J1bnMvOmlkXCIsIGFzeW5jIChyZXF1ZXN0KSA9PiB7XG4gICAgICAgIGNvbnN0IGJhY2tlbmQgPSBTb25hbXUud29ya2Zsb3dzLmJhY2tlbmQ7XG4gICAgICAgIGNvbnN0IHdvcmtmbG93UnVuID0gYXdhaXQgYmFja2VuZC5nZXRXb3JrZmxvd1J1bih7XG4gICAgICAgICAgd29ya2Zsb3dSdW5JZDogcmVxdWVzdC5wYXJhbXMuaWQsXG4gICAgICAgIH0pO1xuICAgICAgICBpZiAoIXdvcmtmbG93UnVuKSB7XG4gICAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBXb3JrZmxvdyBydW4gbm90IGZvdW5kOiAke3JlcXVlc3QucGFyYW1zLmlkfWApO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB3b3JrZmxvd1J1bjtcbiAgICAgIH0pO1xuXG4gICAgICBzZXJ2ZXIucG9zdDx7XG4gICAgICAgIFBhcmFtczogeyBpZDogc3RyaW5nIH07XG4gICAgICB9PihcIi9hcGkvdGFza3Mvd29ya2Zsb3dSdW5zLzppZC9jYW5jZWxcIiwgYXN5bmMgKHJlcXVlc3QpID0+IHtcbiAgICAgICAgY29uc3QgYmFja2VuZCA9IFNvbmFtdS53b3JrZmxvd3MuYmFja2VuZDtcbiAgICAgICAgcmV0dXJuIGJhY2tlbmQuY2FuY2VsV29ya2Zsb3dSdW4oe1xuICAgICAgICAgIHdvcmtmbG93UnVuSWQ6IHJlcXVlc3QucGFyYW1zLmlkLFxuICAgICAgICB9KTtcbiAgICAgIH0pO1xuXG4gICAgICBzZXJ2ZXIucG9zdDx7XG4gICAgICAgIFBhcmFtczogeyBpZDogc3RyaW5nIH07XG4gICAgICB9PihcIi9hcGkvdGFza3Mvd29ya2Zsb3dSdW5zLzppZC9wYXVzZVwiLCBhc3luYyAocmVxdWVzdCkgPT4ge1xuICAgICAgICBjb25zdCBiYWNrZW5kID0gU29uYW11LndvcmtmbG93cy5iYWNrZW5kO1xuICAgICAgICByZXR1cm4gYmFja2VuZC5wYXVzZVdvcmtmbG93UnVuKHtcbiAgICAgICAgICB3b3JrZmxvd1J1bklkOiByZXF1ZXN0LnBhcmFtcy5pZCxcbiAgICAgICAgfSk7XG4gICAgICB9KTtcblxuICAgICAgc2VydmVyLnBvc3Q8e1xuICAgICAgICBQYXJhbXM6IHsgaWQ6IHN0cmluZyB9O1xuICAgICAgfT4oXCIvYXBpL3Rhc2tzL3dvcmtmbG93UnVucy86aWQvcmVzdW1lXCIsIGFzeW5jIChyZXF1ZXN0KSA9PiB7XG4gICAgICAgIGNvbnN0IGJhY2tlbmQgPSBTb25hbXUud29ya2Zsb3dzLmJhY2tlbmQ7XG4gICAgICAgIHJldHVybiBiYWNrZW5kLnJlc3VtZVdvcmtmbG93UnVuKHtcbiAgICAgICAgICB3b3JrZmxvd1J1bklkOiByZXF1ZXN0LnBhcmFtcy5pZCxcbiAgICAgICAgfSk7XG4gICAgICB9KTtcblxuICAgICAgc2VydmVyLmdldDx7XG4gICAgICAgIFBhcmFtczogeyBpZDogc3RyaW5nIH07XG4gICAgICAgIFF1ZXJ5c3RyaW5nOiB7XG4gICAgICAgICAgbGltaXQ/OiBzdHJpbmc7XG4gICAgICAgICAgYWZ0ZXI/OiBzdHJpbmc7XG4gICAgICAgICAgYmVmb3JlPzogc3RyaW5nO1xuICAgICAgICB9O1xuICAgICAgfT4oXCIvYXBpL3Rhc2tzL3dvcmtmbG93UnVucy86aWQvc3RlcHNcIiwgYXN5bmMgKHJlcXVlc3QpID0+IHtcbiAgICAgICAgY29uc3QgYmFja2VuZCA9IFNvbmFtdS53b3JrZmxvd3MuYmFja2VuZDtcbiAgICAgICAgY29uc3QgeyBsaW1pdCwgYWZ0ZXIsIGJlZm9yZSB9ID0gcmVxdWVzdC5xdWVyeTtcbiAgICAgICAgcmV0dXJuIGJhY2tlbmQubGlzdFN0ZXBBdHRlbXB0cyh7XG4gICAgICAgICAgd29ya2Zsb3dSdW5JZDogcmVxdWVzdC5wYXJhbXMuaWQsXG4gICAgICAgICAgbGltaXQ6IGxpbWl0ID8gTnVtYmVyLnBhcnNlSW50KGxpbWl0LCAxMCkgOiB1bmRlZmluZWQsXG4gICAgICAgICAgYWZ0ZXIsXG4gICAgICAgICAgYmVmb3JlLFxuICAgICAgICB9KTtcbiAgICAgIH0pO1xuXG4gICAgICAvKipcbiAgICAgICAqIEhlYWx0aCBDaGVjayBBUElcbiAgICAgICAqIE1DUCDrj4TqtazqsIAgU29uYW11IOyEnOuyhOulvCDsnpDrj5kg6rCQ7KeA7ZWY6riwIOychO2VnCDsl5Trk5ztj6zsnbjtirhcbiAgICAgICAqL1xuICAgICAgc2VydmVyLmdldChcIi9hcGkvc29uYW11L2hlYWx0aFwiLCBhc3luYyAocmVxdWVzdCkgPT4ge1xuICAgICAgICBjb25zdCBhZGRyZXNzID0gcmVxdWVzdC5zZXJ2ZXIuc2VydmVyLmFkZHJlc3MoKTtcbiAgICAgICAgY29uc3QgcG9ydCA9IGFkZHJlc3MgJiYgdHlwZW9mIGFkZHJlc3MgPT09IFwib2JqZWN0XCIgPyBhZGRyZXNzLnBvcnQgOiAwO1xuXG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgb2s6IHRydWUsXG4gICAgICAgICAgcHJvamVjdDogcHJvY2Vzcy5jd2QoKS5zcGxpdChcIi9cIikucG9wKCkgfHwgXCJ1bmtub3duXCIsXG4gICAgICAgICAgcG9ydCxcbiAgICAgICAgICB0aW1lc3RhbXA6IG5ldyBEYXRlKCkudG9JU09TdHJpbmcoKSxcbiAgICAgICAgfTtcbiAgICAgIH0pO1xuXG4gICAgICAvKipcbiAgICAgICAqIEZpeHR1cmUg7IOd7ISxIEFQSVxuICAgICAgICovXG4gICAgICBzZXJ2ZXIucG9zdDx7XG4gICAgICAgIEJvZHk6IHtcbiAgICAgICAgICBlbnRpdHk6IHN0cmluZztcbiAgICAgICAgICBjb3VudD86IG51bWJlcjtcbiAgICAgICAgICBvdmVycmlkZXM/OiBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPjtcbiAgICAgICAgICB0YXJnZXREYj86IFwiZml4dHVyZVwiIHwgXCJ0ZXN0XCI7XG4gICAgICAgIH07XG4gICAgICB9PihcIi9hcGkvc29uYW11L2ZpeHR1cmUvZ2VuZXJhdGVcIiwgYXN5bmMgKHJlcXVlc3QsIHJlcGx5KSA9PiB7XG4gICAgICAgIGNvbnN0IHsgZW50aXR5LCBjb3VudCA9IDEsIG92ZXJyaWRlcywgdGFyZ2V0RGIgPSBcImZpeHR1cmVcIiB9ID0gcmVxdWVzdC5ib2R5O1xuXG4gICAgICAgIC8vIO2DgOqynyBEQiDshKTsoJUg6rCA7KC47Jik6riwXG4gICAgICAgIGNvbnN0IGRiQ29uZmlnID0gdGFyZ2V0RGIgPT09IFwiZml4dHVyZVwiID8gU29uYW11LmRiQ29uZmlnLmZpeHR1cmUgOiBTb25hbXUuZGJDb25maWcudGVzdDtcblxuICAgICAgICAvLyBLbmV4IOyduOyKpO2EtOyKpCDsg53shLFcbiAgICAgICAgY29uc3QgZGIgPSBjcmVhdGVLbmV4SW5zdGFuY2UoZGJDb25maWcpO1xuXG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgLy8gRml4dHVyZUdlbmVyYXRvciDsg53shLFcbiAgICAgICAgICBjb25zdCBnZW5lcmF0b3IgPSBuZXcgRml4dHVyZUdlbmVyYXRvcihkYiwgZGIsIHRhcmdldERiLCBFbnRpdHlNYW5hZ2VyKTtcblxuICAgICAgICAgIC8vIOuLqOydvCBFbnRpdHkg67Cw7LmYIOyDneyEsVxuICAgICAgICAgIGNvbnN0IGZpeHR1cmVzID0gYXdhaXQgZ2VuZXJhdG9yLmdlbmVyYXRlQmF0Y2goW1xuICAgICAgICAgICAge1xuICAgICAgICAgICAgICBlbnRpdHksXG4gICAgICAgICAgICAgIGNvdW50LFxuICAgICAgICAgICAgICBvdmVycmlkZXM6IG92ZXJyaWRlcyA/PyB7fSxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgXSk7XG5cbiAgICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgc3VjY2VzczogdHJ1ZSxcbiAgICAgICAgICAgIGVudGl0eSxcbiAgICAgICAgICAgIGNvdW50OiBmaXh0dXJlcy5sZW5ndGgsXG4gICAgICAgICAgICBmaXh0dXJlcyxcbiAgICAgICAgICAgIHRhcmdldERiLFxuICAgICAgICAgIH07XG4gICAgICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICAgICAgcmVwbHkuc3RhdHVzKDQwMCk7XG4gICAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIHN1Y2Nlc3M6IGZhbHNlLFxuICAgICAgICAgICAgZXJyb3I6IGVycm9yIGluc3RhbmNlb2YgRXJyb3IgPyBlcnJvci5tZXNzYWdlIDogU3RyaW5nKGVycm9yKSxcbiAgICAgICAgICB9O1xuICAgICAgICB9IGZpbmFsbHkge1xuICAgICAgICAgIGF3YWl0IGRiLmRlc3Ryb3koKTtcbiAgICAgICAgfVxuICAgICAgfSk7XG5cbiAgICAgIC8qKlxuICAgICAgICogRml4dHVyZSDrjbDsnbTthLAg7YOQ7IOJIEFQSVxuICAgICAgICovXG4gICAgICBzZXJ2ZXIucG9zdDx7XG4gICAgICAgIEJvZHk6IHtcbiAgICAgICAgICBlbnRpdHk6IHN0cmluZztcbiAgICAgICAgICBzdHJhdGVneTogXCJzYW1wbGVcIiB8IFwicmVjZW50XCIgfCBcInJhbmRvbVwiIHwgXCJxdWVyeVwiO1xuICAgICAgICAgIGxpbWl0PzogbnVtYmVyO1xuICAgICAgICAgIHdoZXJlPzogUmVjb3JkPHN0cmluZywgdW5rbm93bj47XG4gICAgICAgIH07XG4gICAgICB9PihcIi9hcGkvc29uYW11L2ZpeHR1cmUvZXhwbG9yZVwiLCBhc3luYyAocmVxdWVzdCwgcmVwbHkpID0+IHtcbiAgICAgICAgY29uc3QgeyBlbnRpdHksIHN0cmF0ZWd5LCBsaW1pdCA9IDEwLCB3aGVyZSB9ID0gcmVxdWVzdC5ib2R5O1xuXG4gICAgICAgIC8vIEZpeHR1cmUgREIg7ISk7KCVIOqwgOyguOyYpOq4sFxuICAgICAgICBjb25zdCBmaXh0dXJlRGJDb25maWcgPSBTb25hbXUuZGJDb25maWcuZml4dHVyZTtcblxuICAgICAgICAvLyBLbmV4IOyduOyKpO2EtOyKpCDsg53shLFcbiAgICAgICAgY29uc3QgZml4dHVyZURiID0gY3JlYXRlS25leEluc3RhbmNlKGZpeHR1cmVEYkNvbmZpZyk7XG5cbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICAvLyBEYXRhRXhwbG9yZXIg7IOd7ISxXG4gICAgICAgICAgY29uc3QgZXhwbG9yZXIgPSBuZXcgRGF0YUV4cGxvcmVyKGZpeHR1cmVEYiwgRW50aXR5TWFuYWdlcik7XG5cbiAgICAgICAgICBjb25zdCBkYXRhID0gYXdhaXQgZXhwbG9yZXIuZXhwbG9yZShlbnRpdHksIHtcbiAgICAgICAgICAgIHN0cmF0ZWd5LFxuICAgICAgICAgICAgbGltaXQsXG4gICAgICAgICAgICB3aGVyZSxcbiAgICAgICAgICB9KTtcblxuICAgICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICBzdWNjZXNzOiB0cnVlLFxuICAgICAgICAgICAgZW50aXR5LFxuICAgICAgICAgICAgc3RyYXRlZ3ksXG4gICAgICAgICAgICBjb3VudDogZGF0YS5sZW5ndGgsXG4gICAgICAgICAgICBkYXRhLFxuICAgICAgICAgIH07XG4gICAgICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICAgICAgcmVwbHkuc3RhdHVzKDQwMCk7XG4gICAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIHN1Y2Nlc3M6IGZhbHNlLFxuICAgICAgICAgICAgZXJyb3I6IGVycm9yIGluc3RhbmNlb2YgRXJyb3IgPyBlcnJvci5tZXNzYWdlIDogU3RyaW5nKGVycm9yKSxcbiAgICAgICAgICB9O1xuICAgICAgICB9IGZpbmFsbHkge1xuICAgICAgICAgIGF3YWl0IGZpeHR1cmVEYi5kZXN0cm95KCk7XG4gICAgICAgIH1cbiAgICAgIH0pO1xuXG4gICAgICAvKipcbiAgICAgICAqIEZpeHR1cmUg642w7J207YSwIOqwgOyguOyYpOq4sCAoZmV0Y2gpIEFQSVxuICAgICAgICogcHJvZHVjdGlvbi9kZXZlbG9wbWVudCBEQuyXkOyEnCDsi6TsoJwg642w7J207YSw66W8IGZpeHR1cmUgRELroZwgaW1wb3J0XG4gICAgICAgKi9cbiAgICAgIHNlcnZlci5wb3N0PHtcbiAgICAgICAgQm9keToge1xuICAgICAgICAgIGVudGl0eTogc3RyaW5nO1xuICAgICAgICAgIHN0cmF0ZWd5PzogXCJzYW1wbGVcIiB8IFwicmVjZW50XCIgfCBcInJhbmRvbVwiIHwgXCJxdWVyeVwiO1xuICAgICAgICAgIGxpbWl0PzogbnVtYmVyO1xuICAgICAgICAgIGluY2x1ZGVSZWxhdGlvbnM/OiBib29sZWFuO1xuICAgICAgICAgIG1heERlcHRoPzogbnVtYmVyO1xuICAgICAgICB9O1xuICAgICAgfT4oXCIvYXBpL3NvbmFtdS9maXh0dXJlL2ZldGNoXCIsIGFzeW5jIChyZXF1ZXN0LCByZXBseSkgPT4ge1xuICAgICAgICBjb25zdCB7XG4gICAgICAgICAgZW50aXR5LFxuICAgICAgICAgIHN0cmF0ZWd5ID0gXCJyZWNlbnRcIixcbiAgICAgICAgICBsaW1pdCA9IDEwLFxuICAgICAgICAgIGluY2x1ZGVSZWxhdGlvbnMgPSB0cnVlLFxuICAgICAgICAgIG1heERlcHRoID0gMixcbiAgICAgICAgfSA9IHJlcXVlc3QuYm9keTtcblxuICAgICAgICAvLyBTb3VyY2UgREIgKHByb2R1Y3Rpb24vZGV2ZWxvcG1lbnQpIC0g7J296riwIOyghOyaqVxuICAgICAgICBjb25zdCBzb3VyY2VEYiA9IERCLmdldERCKFwiclwiKTtcblxuICAgICAgICAvLyBUYXJnZXQgREIgKGZpeHR1cmUpXG4gICAgICAgIGNvbnN0IGZpeHR1cmVEYiA9IGNyZWF0ZUtuZXhJbnN0YW5jZShTb25hbXUuZGJDb25maWcuZml4dHVyZSk7XG5cbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICAvLyBGaXh0dXJlR2VuZXJhdG9yIOyDneyEsVxuICAgICAgICAgIGNvbnN0IGdlbmVyYXRvciA9IG5ldyBGaXh0dXJlR2VuZXJhdG9yKHNvdXJjZURiLCBmaXh0dXJlRGIsIFwiZml4dHVyZVwiLCBFbnRpdHlNYW5hZ2VyKTtcblxuICAgICAgICAgIC8vIHByb2R1Y3Rpb24g642w7J207YSw66W8IGZpeHR1cmUgRELroZwgaW1wb3J0XG4gICAgICAgICAgY29uc3QgcmVzdWx0cyA9IGF3YWl0IGdlbmVyYXRvci5pbXBvcnRGcm9tU291cmNlKGVudGl0eSwge1xuICAgICAgICAgICAgc3RyYXRlZ3ksXG4gICAgICAgICAgICBsaW1pdCxcbiAgICAgICAgICAgIGluY2x1ZGVSZWxhdGlvbnMsXG4gICAgICAgICAgICBtYXhEZXB0aCxcbiAgICAgICAgICB9KTtcblxuICAgICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICBzdWNjZXNzOiB0cnVlLFxuICAgICAgICAgICAgZW50aXR5LFxuICAgICAgICAgICAgc3RyYXRlZ3ksXG4gICAgICAgICAgICBjb3VudDogcmVzdWx0cy5sZW5ndGgsXG4gICAgICAgICAgICBpbXBvcnRlZDogcmVzdWx0cyxcbiAgICAgICAgICB9O1xuICAgICAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgICAgIHJlcGx5LnN0YXR1cyg0MDApO1xuICAgICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICBzdWNjZXNzOiBmYWxzZSxcbiAgICAgICAgICAgIGVycm9yOiBlcnJvciBpbnN0YW5jZW9mIEVycm9yID8gZXJyb3IubWVzc2FnZSA6IFN0cmluZyhlcnJvciksXG4gICAgICAgICAgfTtcbiAgICAgICAgfSBmaW5hbGx5IHtcbiAgICAgICAgICAvLyBzb3VyY2VEYuuKlCBTb25hbXXqsIAg6rSA66as7ZWY66+A66GcIGRlc3Ryb3ntlZjsp4Ag7JWK7J2MXG4gICAgICAgICAgYXdhaXQgZml4dHVyZURiLmRlc3Ryb3koKTtcbiAgICAgICAgfVxuICAgICAgfSk7XG5cbiAgICAgIC8qKlxuICAgICAgICogRml4dHVyZSDrjbDsnbTthLAg7IKt7KCcIChjbGVhbikgQVBJXG4gICAgICAgKiBGSyDsiJzshJzrpbwg6rOg66Ck7ZWY7JesIOyViOyghO2VmOqyjCDsgq3soJxcbiAgICAgICAqL1xuICAgICAgc2VydmVyLnBvc3Q8e1xuICAgICAgICBCb2R5OiB7XG4gICAgICAgICAgZW50aXRpZXM/OiBzdHJpbmdbXTtcbiAgICAgICAgfTtcbiAgICAgIH0+KFwiL2FwaS9zb25hbXUvZml4dHVyZS9jbGVhblwiLCBhc3luYyAocmVxdWVzdCwgcmVwbHkpID0+IHtcbiAgICAgICAgY29uc3QgeyBlbnRpdGllcyB9ID0gcmVxdWVzdC5ib2R5O1xuXG4gICAgICAgIC8vIEZpeHR1cmUgREIg7Jew6rKwXG4gICAgICAgIGNvbnN0IGZpeHR1cmVEYiA9IGNyZWF0ZUtuZXhJbnN0YW5jZShTb25hbXUuZGJDb25maWcuZml4dHVyZSk7XG5cbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICAvLyDsgq3soJztlaAgRW50aXR5IOuqqeuhnSDqsrDsoJVcbiAgICAgICAgICBjb25zdCB0YXJnZXRFbnRpdGllcyA9XG4gICAgICAgICAgICBlbnRpdGllcyAmJiBlbnRpdGllcy5sZW5ndGggPiAwID8gZW50aXRpZXMgOiBFbnRpdHlNYW5hZ2VyLmdldEFsbElkcygpO1xuXG4gICAgICAgICAgLy8gRW50aXR5IElE66W8IO2FjOydtOu4lOuqheycvOuhnCDrs4DtmZggKHNuYWtlX2Nhc2Ug67O17IiY7ZiVKVxuICAgICAgICAgIGNvbnN0IHRhYmxlTmFtZXMgPSB0YXJnZXRFbnRpdGllcy5tYXAoKGVudGl0eUlkKSA9PiB7XG4gICAgICAgICAgICBjb25zdCBlbnRpdHkgPSBFbnRpdHlNYW5hZ2VyLmdldChlbnRpdHlJZCk7XG4gICAgICAgICAgICByZXR1cm4gZW50aXR5LnRhYmxlO1xuICAgICAgICAgIH0pO1xuXG4gICAgICAgICAgLy8gUG9zdGdyZVNRTDogVFJVTkNBVEUgQ0FTQ0FEReuhnCBGSyDsiJzshJwg66y06rSA7ZWY6rKMIOyViOyghO2VmOqyjCDsgq3soJxcbiAgICAgICAgICAvLyBDQVNDQURFIOyYteyFmOycvOuhnCDsnZjsobTshLEg7J6I64qUIOuNsOydtO2EsOuPhCDtlajqu5gg7IKt7KCcXG4gICAgICAgICAgYXdhaXQgZml4dHVyZURiLnJhdyhcbiAgICAgICAgICAgIGBUUlVOQ0FURSBUQUJMRSAke3RhYmxlTmFtZXMubWFwKCh0KSA9PiBgXCIke3R9XCJgKS5qb2luKFwiLCBcIil9IFJFU1RBUlQgSURFTlRJVFkgQ0FTQ0FERWAsXG4gICAgICAgICAgKTtcblxuICAgICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICBzdWNjZXNzOiB0cnVlLFxuICAgICAgICAgICAgY2xlYW5lZDogdGFibGVOYW1lcyxcbiAgICAgICAgICAgIGNvdW50OiB0YWJsZU5hbWVzLmxlbmd0aCxcbiAgICAgICAgICB9O1xuICAgICAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgICAgIHJlcGx5LnN0YXR1cyg0MDApO1xuICAgICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICBzdWNjZXNzOiBmYWxzZSxcbiAgICAgICAgICAgIGVycm9yOiBlcnJvciBpbnN0YW5jZW9mIEVycm9yID8gZXJyb3IubWVzc2FnZSA6IFN0cmluZyhlcnJvciksXG4gICAgICAgICAgfTtcbiAgICAgICAgfSBmaW5hbGx5IHtcbiAgICAgICAgICBhd2FpdCBmaXh0dXJlRGIuZGVzdHJveSgpO1xuICAgICAgICB9XG4gICAgICB9KTtcblxuICAgICAgLy8gQ0REIEFQSVxuICAgICAgc2VydmVyLmdldChcIi9hcGkvY2RkL3RyZWVcIiwgYXN5bmMgKCkgPT4ge1xuICAgICAgICByZXR1cm4gZ2V0Q2RkVHJlZSgpO1xuICAgICAgfSk7XG5cbiAgICAgIHNlcnZlci5wb3N0PHsgQm9keTogeyBmaWxlUGF0aDogc3RyaW5nIH0gfT4oXCIvYXBpL2NkZC9yZWFkQ29udGVudFwiLCBhc3luYyAocmVxdWVzdCkgPT4ge1xuICAgICAgICBjb25zdCB7IGZpbGVQYXRoIH0gPSByZXF1ZXN0LmJvZHk7XG4gICAgICAgIHJldHVybiByZWFkQ29udGVudChmaWxlUGF0aCk7XG4gICAgICB9KTtcblxuICAgICAgc2VydmVyLnBvc3Q8eyBCb2R5OiB7IGZpbGVQYXRoOiBzdHJpbmcgfSB9PihcIi9hcGkvY2RkL2VkaXRDb250ZW50XCIsIGFzeW5jIChyZXF1ZXN0KSA9PiB7XG4gICAgICAgIGNvbnN0IHsgZmlsZVBhdGggfSA9IHJlcXVlc3QuYm9keTtcbiAgICAgICAgcmV0dXJuIGVkaXRDb250ZW50KGZpbGVQYXRoKTtcbiAgICAgIH0pO1xuXG4gICAgICBzZXJ2ZXIucG9zdDx7IEJvZHk6IHsgZmlsZVBhdGg6IHN0cmluZyB9IH0+KFwiL2FwaS9jZGQvb3BlblNvdXJjZVwiLCBhc3luYyAocmVxdWVzdCkgPT4ge1xuICAgICAgICBjb25zdCB7IGZpbGVQYXRoIH0gPSByZXF1ZXN0LmJvZHk7XG4gICAgICAgIG9wZW5Tb3VyY2VGaWxlKGZpbGVQYXRoKTtcbiAgICAgICAgcmV0dXJuIHsgc3VjY2VzczogdHJ1ZSB9O1xuICAgICAgfSk7XG5cbiAgICAgIC8vIENERCBSdWxlcyBBUElcbiAgICAgIHNlcnZlci5nZXQoXCIvYXBpL2NkZC9ydWxlc1wiLCBhc3luYyAoKSA9PiB7XG4gICAgICAgIHJldHVybiBsaXN0UnVsZXMoKTtcbiAgICAgIH0pO1xuXG4gICAgICBzZXJ2ZXIucG9zdDx7IEJvZHk6IHsgcnVsZUtleTogc3RyaW5nIH0gfT4oXCIvYXBpL2NkZC9yZWFkUnVsZVwiLCBhc3luYyAocmVxdWVzdCkgPT4ge1xuICAgICAgICBjb25zdCB7IHJ1bGVLZXkgfSA9IHJlcXVlc3QuYm9keTtcbiAgICAgICAgcmV0dXJuIHJlYWRSdWxlKHJ1bGVLZXkpO1xuICAgICAgfSk7XG5cbiAgICAgIHNlcnZlci5wb3N0PHsgQm9keTogQ2RkQWRkUnVsZVJlcXVlc3QgfT4oXCIvYXBpL2NkZC9hZGRSdWxlXCIsIGFzeW5jIChyZXF1ZXN0KSA9PiB7XG4gICAgICAgIHJldHVybiBhZGRSdWxlKHJlcXVlc3QuYm9keSk7XG4gICAgICB9KTtcblxuICAgICAgLy8gQ0REIEFDIEFQSVxuICAgICAgc2VydmVyLmdldChcIi9hcGkvY2RkL2FjXCIsIGFzeW5jICgpID0+IHtcbiAgICAgICAgcmV0dXJuIGdldEFjTGlzdCgpO1xuICAgICAgfSk7XG5cbiAgICAgIC8vIHVpLXdlYiDruYzrk5wg7YyM7J28IOyEnOu5mVxuICAgICAgY29uc3QgdWlEaXN0UGF0aCA9IHBhdGgucmVzb2x2ZShpbXBvcnQubWV0YS5kaXJuYW1lLCBcIi4uL3VpLXdlYlwiKTtcblxuICAgICAgLy8g7KCV7KCBIO2MjOydvCDshJzruZk6IOujqO2KuCDtj7TrjZQg7KCE7LK0IChhc3NldHMsIHNldHRpbmcuc3ZnIOuTsSlcbiAgICAgIHNlcnZlci5yZWdpc3Rlcihhd2FpdCBpbXBvcnQoXCJAZmFzdGlmeS9zdGF0aWNcIiksIHtcbiAgICAgICAgcm9vdDogdWlEaXN0UGF0aCxcbiAgICAgICAgcHJlZml4OiBcIi9cIixcbiAgICAgICAgZGVjb3JhdGVSZXBseTogZmFsc2UsXG4gICAgICAgIHdpbGRjYXJkOiBmYWxzZSxcbiAgICAgIH0pO1xuXG4gICAgICAvLyBTUEEgZmFsbGJhY2sgLSDsoJXsoIEg7YyM7J287J20IOyXhuuKlCDrqqjrk6Ag6rK966Gc64qUIGluZGV4Lmh0bWzroZxcbiAgICAgIHNlcnZlci5nZXQoXCIqXCIsIGFzeW5jIChfcmVxdWVzdCwgcmVwbHkpID0+IHtcbiAgICAgICAgcmVwbHkuaGVhZGVycyh7IFwiQ29udGVudC10eXBlXCI6IFwidGV4dC9odG1sXCIgfSkuc2VuZChcbiAgICAgICAgICBmc1xuICAgICAgICAgICAgLnJlYWRGaWxlU3luYyhwYXRoLnJlc29sdmUodWlEaXN0UGF0aCwgXCJpbmRleC5odG1sXCIpKVxuICAgICAgICAgICAgLnRvU3RyaW5nKClcbiAgICAgICAgICAgIC5yZXBsYWNlKFwie3twcm9qZWN0TmFtZX19XCIsIFNvbmFtdS5jb25maWcucHJvamVjdE5hbWUgPz8gXCJVbmtub3duU29uYW11UHJvamVjdFwiKSxcbiAgICAgICAgKTtcbiAgICAgIH0pO1xuICAgIH0sXG4gICAgeyBwcmVmaXg6IFwiL3NvbmFtdS11aVwiIH0sXG4gICk7XG59XG4iXSwibWFwcGluZ3MiOiI7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztBQXVEQSxlQUFzQixrQkFBa0IsU0FBMEI7Q0FDaEUsUUFBUSxTQUNOLE9BQU8sV0FBVztFQUVoQixNQUFNLFdBQVcsSUFBSSxTQUFTO0VBRzlCLGVBQWUsb0JBQXVCLElBQWtDO0dBQ3RFLE1BQU0sY0FBYyxJQUFJLFNBQWUsWUFBWTtJQUNqRCxNQUFNLGdCQUFnQjtLQUNwQixhQUFhLE9BQU87S0FDcEIsUUFBUTtJQUNWO0lBRUEsTUFBTSxVQUFVLGlCQUFpQjtLQUMvQixPQUFPLE9BQU8sYUFBYSxJQUFJLGtCQUFrQixPQUFPO0tBQ3hELFFBQVE7SUFDVixHQUFHLElBQUk7SUFFUCxPQUFPLE9BQU8sYUFBYSxLQUFLLGtCQUFrQixPQUFPO0dBQzNELENBQUM7R0FFRCxNQUFNLFNBQVMsTUFBTSxHQUFHO0dBQ3hCLE1BQU07R0FDTixPQUFPO0VBQ1Q7RUFFQSxNQUFNLFNBQVMsTUFBTTtFQUVyQixPQUFPLElBQUksc0JBQXNCLFlBQVk7R0FDM0MsT0FBTyxPQUFPO0VBQ2hCLENBQUM7RUFFRCxPQUFPLElBTUoseUJB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
748
+ //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYXBpLmpzIiwibmFtZXMiOltdLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy91aS9hcGkudHMiXSwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgZXhlY0ZpbGVTeW5jLCBleGVjU3luYyB9IGZyb20gXCJjaGlsZF9wcm9jZXNzXCI7XG5pbXBvcnQgZnMgZnJvbSBcImZzXCI7XG5pbXBvcnQgcGF0aCBmcm9tIFwicGF0aFwiO1xuXG5pbXBvcnQgeyB0eXBlIEZhc3RpZnlJbnN0YW5jZSB9IGZyb20gXCJmYXN0aWZ5XCI7XG5pbXBvcnQgaW5mbGVjdGlvbiBmcm9tIFwiaW5mbGVjdGlvblwiO1xuaW1wb3J0IHsgcmFuZ2UgfSBmcm9tIFwicmFkYXNoaVwiO1xuXG5pbXBvcnQgeyBTb25hbXUgfSBmcm9tIFwiLi4vYXBpL3NvbmFtdVwiO1xuaW1wb3J0IHsgREIgfSBmcm9tIFwiLi4vZGF0YWJhc2UvZGJcIjtcbmltcG9ydCB7IHR5cGUgU29uYW11REJDb25maWcgfSBmcm9tIFwiLi4vZGF0YWJhc2UvZGJcIjtcbmltcG9ydCB7IGNyZWF0ZUtuZXhJbnN0YW5jZSB9IGZyb20gXCIuLi9kYXRhYmFzZS9rbmV4XCI7XG5pbXBvcnQgeyBTRCB9IGZyb20gXCIuLi9kaWN0L3NkXCI7XG5pbXBvcnQgeyBzb25hbXVEaWN0aW9uYXJ5IH0gZnJvbSBcIi4uL2RpY3Qvc29uYW11LWRpY3Rpb25hcnlcIjtcbmltcG9ydCB7IHR5cGUgRW50aXR5IH0gZnJvbSBcIi4uL2VudGl0eS9lbnRpdHlcIjtcbmltcG9ydCB7IEVudGl0eU1hbmFnZXIgfSBmcm9tIFwiLi4vZW50aXR5L2VudGl0eS1tYW5hZ2VyXCI7XG5pbXBvcnQge1xuICBCYWRSZXF1ZXN0RXhjZXB0aW9uLFxuICBpc1NvRXhjZXB0aW9uLFxuICBTZXJ2aWNlVW5hdmFpbGFibGVFeGNlcHRpb24sXG59IGZyb20gXCIuLi9leGNlcHRpb25zL3NvLWV4Y2VwdGlvbnNcIjtcbmltcG9ydCB7IFRlbXBsYXRlTWFuYWdlciB9IGZyb20gXCIuLi90ZW1wbGF0ZS90ZW1wbGF0ZS1tYW5hZ2VyXCI7XG5pbXBvcnQgeyBEYXRhRXhwbG9yZXIsIHR5cGUgRGF0YUV4cGxvcmVyT3B0aW9ucyB9IGZyb20gXCIuLi90ZXN0aW5nL2RhdGEtZXhwbG9yZXJcIjtcbmltcG9ydCB7IEZpeHR1cmVHZW5lcmF0b3IsIHR5cGUgRml4dHVyZUdlbmVyYXRpb25TcGVjIH0gZnJvbSBcIi4uL3Rlc3RpbmcvZml4dHVyZS1nZW5lcmF0b3JcIjtcbmltcG9ydCB7IEZpeHR1cmVNYW5hZ2VyIH0gZnJvbSBcIi4uL3Rlc3RpbmcvZml4dHVyZS1tYW5hZ2VyXCI7XG5pbXBvcnQgeyB0eXBlIER1cGxpY2F0ZUNoZWNrT3B0aW9ucyB9IGZyb20gXCIuLi90ZXN0aW5nL2ZpeHR1cmUtbWFuYWdlclwiO1xuaW1wb3J0IHsgQlVJTFRfSU5fVFlQRV9JRFMsIFRlbXBsYXRlS2V5IH0gZnJvbSBcIi4uL3R5cGVzL3R5cGVzXCI7XG5pbXBvcnQge1xuICB0eXBlIENvbmUsXG4gIHR5cGUgRW50aXR5SW5kZXgsXG4gIHR5cGUgRW50aXR5UHJvcCxcbiAgdHlwZSBFbnRpdHlTdWJzZXRSb3csXG4gIHR5cGUgRml4dHVyZVJlY29yZCxcbiAgdHlwZSBGaXh0dXJlU2VhcmNoT3B0aW9ucyxcbiAgdHlwZSBGbGF0dGVuU3Vic2V0Um93LFxuICB0eXBlIFBhdGhBbmRDb2RlLFxufSBmcm9tIFwiLi4vdHlwZXMvdHlwZXNcIjtcbmltcG9ydCB7IGlzT2JqZWN0VmFsdWUgfSBmcm9tIFwiLi4vdXRpbHMvcnVudGltZS12YWx1ZVwiO1xuaW1wb3J0IHsgbm9uTnVsbGFibGUgfSBmcm9tIFwiLi4vdXRpbHMvdXRpbHNcIjtcbmltcG9ydCB7IHNldEFpQXBpIH0gZnJvbSBcIi4vYWktYXBpXCI7XG5pbXBvcnQgeyBmb3J3YXJkQXN5bmNFcnJvcnMgfSBmcm9tIFwiLi9hc3luYy1yb3V0ZVwiO1xuaW1wb3J0IHsgdHlwZSBDZGRBZGRSdWxlUmVxdWVzdCB9IGZyb20gXCIuL2NkZC1zZXJ2aWNlXCI7XG5pbXBvcnQge1xuICBhZGRSdWxlLFxuICBlZGl0Q29udGVudCxcbiAgZ2V0QWNMaXN0LFxuICBnZXRDZGRUcmVlLFxuICBsaXN0UnVsZXMsXG4gIG9wZW5Tb3VyY2VGaWxlLFxuICByZWFkQ29udGVudCxcbiAgcmVhZFJ1bGUsXG59IGZyb20gXCIuL2NkZC1zZXJ2aWNlXCI7XG5pbXBvcnQgeyByZWdpc3Rlck1pZ3JhdGlvbnNBcGkgfSBmcm9tIFwiLi9taWdyYXRpb25zLWFwaVwiO1xuXG5pbnRlcmZhY2UgRW50aXR5VGVtcGxhdGVJbnB1dCB7XG4gIGVudGl0eUlkOiBzdHJpbmc7XG4gIGVudW1JZD86IHN0cmluZztcbn1cblxuYXN5bmMgZnVuY3Rpb24gd2FpdEZvckhNUkNvbXBsZXRlZDxUPihmbjogKCkgPT4gUHJvbWlzZTxUPik6IFByb21pc2U8VD4ge1xuICBjb25zdCB3YWl0UHJvbWlzZSA9IG5ldyBQcm9taXNlPHZvaWQ+KChyZXNvbHZlKSA9PiB7XG4gICAgY29uc3QgaGFuZGxlciA9ICgpID0+IHtcbiAgICAgIGNsZWFyVGltZW91dCh0aW1lb3V0KTtcbiAgICAgIHJlc29sdmUoKTtcbiAgICB9O1xuXG4gICAgY29uc3QgdGltZW91dCA9IHNldFRpbWVvdXQoKCkgPT4ge1xuICAgICAgU29uYW11LnN5bmNlci5ldmVudEVtaXR0ZXIub2ZmKFwib25ITVJDb21wbGV0ZWRcIiwgaGFuZGxlcik7XG4gICAgICByZXNvbHZlKCk7XG4gICAgfSwgMTUwMCk7XG5cbiAgICBTb25hbXUuc3luY2VyLmV2ZW50RW1pdHRlci5vbmNlKFwib25ITVJDb21wbGV0ZWRcIiwgaGFuZGxlcik7XG4gIH0pO1xuXG4gIGNvbnN0IHJlc3VsdCA9IGF3YWl0IGZuKCk7XG4gIGF3YWl0IHdhaXRQcm9taXNlO1xuICByZXR1cm4gcmVzdWx0O1xufVxuXG5mdW5jdGlvbiBmbGF0dGVuU3Vic2V0Um93cyhzdWJzZXRSb3dzOiBFbnRpdHlTdWJzZXRSb3dbXSk6IEZsYXR0ZW5TdWJzZXRSb3dbXSB7XG4gIHJldHVybiBzdWJzZXRSb3dzLmZsYXRNYXAoKHN1YnNldFJvdykgPT4ge1xuICAgIGNvbnN0IHsgY2hpbGRyZW4sIC4uLnNSb3cgfSA9IHN1YnNldFJvdztcbiAgICByZXR1cm4gW3NSb3csIC4uLmZsYXR0ZW5TdWJzZXRSb3dzKGNoaWxkcmVuKV07XG4gIH0pO1xufVxuXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gc29uYW11VUlBcGlQbHVnaW4oZmFzdGlmeTogRmFzdGlmeUluc3RhbmNlKSB7XG4gIGZhc3RpZnkucmVnaXN0ZXIoXG4gICAgYXN5bmMgKHNlcnZlcikgPT4ge1xuICAgICAgYXdhaXQgc2V0QWlBcGkoc2VydmVyKTtcbiAgICAgIGF3YWl0IHJlZ2lzdGVyTWlncmF0aW9uc0FwaShzZXJ2ZXIpO1xuXG4gICAgICBzZXJ2ZXIuZ2V0KFwiL2FwaS9zb25hbXUvY29uZmlnXCIsIGFzeW5jICgpID0+IHtcbiAgICAgICAgcmV0dXJuIFNvbmFtdS5jb25maWc7XG4gICAgICB9KTtcblxuICAgICAgc2VydmVyLmdldDx7XG4gICAgICAgIFF1ZXJ5c3RyaW5nOiB7XG4gICAgICAgICAgZW50aXR5SWQ/OiBzdHJpbmc7XG4gICAgICAgICAgcHJlc2V0PzogXCJ0eXBlc1wiIHwgXCJlbnRpdHkuanNvblwiIHwgXCJnZW5lcmF0ZWRcIjtcbiAgICAgICAgICBhYnNQYXRoPzogc3RyaW5nO1xuICAgICAgICB9O1xuICAgICAgfT4oXCIvYXBpL3Rvb2xzL29wZW5Wc2NvZGVcIiwgKHJlcXVlc3QpID0+XG4gICAgICAgIGZvcndhcmRBc3luY0Vycm9ycyhhc3luYyAoKSA9PiB7XG4gICAgICAgICAgY29uc3QgeyBlbnRpdHlJZCwgcHJlc2V0LCBhYnNQYXRoIH0gPSByZXF1ZXN0LnF1ZXJ5O1xuXG4gICAgICAgICAgY29uc3QgdGFyZ2V0UGF0aCA9ICgoKSA9PiB7XG4gICAgICAgICAgICBpZiAoZW50aXR5SWQgJiYgcHJlc2V0KSB7XG4gICAgICAgICAgICAgIGNvbnN0IGVudGl0eSA9IEVudGl0eU1hbmFnZXIuZ2V0KGVudGl0eUlkKTtcbiAgICAgICAgICAgICAgY29uc3QgeyBuYW1lcyB9ID0gZW50aXR5O1xuXG4gICAgICAgICAgICAgIGNvbnN0IHsgYXBpUm9vdFBhdGggfSA9IFNvbmFtdTtcbiAgICAgICAgICAgICAgY29uc3QgZmlsZW5hbWUgPSAoKCkgPT4ge1xuICAgICAgICAgICAgICAgIHN3aXRjaCAocHJlc2V0KSB7XG4gICAgICAgICAgICAgICAgICBjYXNlIFwidHlwZXNcIjpcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGAke25hbWVzLmZzfS50eXBlcy50c2A7XG4gICAgICAgICAgICAgICAgICBjYXNlIFwiZW50aXR5Lmpzb25cIjpcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGAke25hbWVzLmZzfS5lbnRpdHkuanNvbmA7XG4gICAgICAgICAgICAgICAgICBjYXNlIFwiZ2VuZXJhdGVkXCI6XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBgJHtuYW1lcy5mc30uZ2VuZXJhdGVkLnRzYDtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgICAgICAgICAgICAgfSkoKTtcbiAgICAgICAgICAgICAgcmV0dXJuIGAke2FwaVJvb3RQYXRofS9zcmMvYXBwbGljYXRpb24vJHtlbnRpdHkubmFtZXMucGFyZW50RnN9LyR7ZmlsZW5hbWV9YDtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgIGlmICghYWJzUGF0aCkge1xuICAgICAgICAgICAgICAgIHRocm93IG5ldyBCYWRSZXF1ZXN0RXhjZXB0aW9uKFNEKFwic29uYW11LmVycm9yLnByZXNldE9yQWJzUGF0aFJlcXVpcmVkXCIpKTtcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICByZXR1cm4gYWJzUGF0aDtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9KSgpO1xuICAgICAgICAgIGV4ZWNTeW5jKGBjb2RlICR7dGFyZ2V0UGF0aH1gKTtcbiAgICAgICAgfSksXG4gICAgICApO1xuXG4gICAgICBzZXJ2ZXIuZ2V0PHtcbiAgICAgICAgUXVlcnlzdHJpbmc6IHtcbiAgICAgICAgICBlZGl0b3I6IFwidnNjb2RlXCIgfCBcImN1cnNvclwiIHwgXCJ6ZWRcIjtcbiAgICAgICAgICBhYnNQYXRoOiBzdHJpbmc7XG4gICAgICAgIH07XG4gICAgICB9PihcIi9hcGkvdG9vbHMvb3BlbkVkaXRvclwiLCAocmVxdWVzdCkgPT5cbiAgICAgICAgZm9yd2FyZEFzeW5jRXJyb3JzKGFzeW5jICgpID0+IHtcbiAgICAgICAgICBjb25zdCBjb21tYW5kcyA9IHtcbiAgICAgICAgICAgIHZzY29kZTogXCJjb2RlXCIsXG4gICAgICAgICAgICBjdXJzb3I6IFwiY3Vyc29yXCIsXG4gICAgICAgICAgICB6ZWQ6IFwiemVkXCIsXG4gICAgICAgICAgfSBhcyBjb25zdDtcbiAgICAgICAgICBjb25zdCBjb21tYW5kID0gY29tbWFuZHNbcmVxdWVzdC5xdWVyeS5lZGl0b3JdO1xuICAgICAgICAgIGlmIChjb21tYW5kID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBCYWRSZXF1ZXN0RXhjZXB0aW9uKFNEKFwiZXJyb3IuYmFkUmVxdWVzdFwiKSk7XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgLy8g7IW47J2EIOqxsOy5mOyngCDslYrslYQg7YyM7J28IOqyveuhnOqwgCDrqoXroLnsnLzroZwg7ZW07ISd65CY7KeAIOyViuuPhOuhnSDtlanri4jri6QuXG4gICAgICAgICAgZXhlY0ZpbGVTeW5jKGNvbW1hbmQsIFtyZXF1ZXN0LnF1ZXJ5LmFic1BhdGhdKTtcbiAgICAgICAgfSksXG4gICAgICApO1xuXG4gICAgICBzZXJ2ZXIuZ2V0PHtcbiAgICAgICAgUXVlcnlzdHJpbmc6IHtcbiAgICAgICAgICBvcmlnaW46IHN0cmluZztcbiAgICAgICAgICBlbnRpdHlJZD86IHN0cmluZztcbiAgICAgICAgfTtcbiAgICAgIH0+KFwiL2FwaS90b29scy9nZXRTdWdnZXN0aW9uXCIsIChyZXF1ZXN0KSA9PlxuICAgICAgICBmb3J3YXJkQXN5bmNFcnJvcnMoYXN5bmMgKCkgPT4ge1xuICAgICAgICAgIGNvbnN0IHsgb3JpZ2luLCBlbnRpdHlJZCB9ID0gcmVxdWVzdC5xdWVyeTtcblxuICAgICAgICAgIC8vIOy5mO2ZmCDsmqnslrTsp5FcbiAgICAgICAgICBjb25zdCBnbG9zc2FyeSA9IG5ldyBNYXA8c3RyaW5nLCBzdHJpbmc+KFtcbiAgICAgICAgICAgIFtcInN0YXR1c1wiLCBcIuyDge2DnFwiXSxcbiAgICAgICAgICAgIFtcInR5cGVcIiwgXCLtg4DsnoVcIl0sXG4gICAgICAgICAgICBbXCJpbWFnZVwiLCBcIuydtOuvuOyngFwiXSxcbiAgICAgICAgICAgIFtcImltYWdlc1wiLCBcIuydtOuvuOyngOumrOyKpO2KuFwiXSxcbiAgICAgICAgICAgIFtcInVybFwiLCBcIlVSTFwiXSxcbiAgICAgICAgICAgIFtcImlkXCIsIFwiSURcIl0sXG4gICAgICAgICAgICBbXCJuYW1lXCIsIGB7RW50aXR5SUR966qFYF0sXG4gICAgICAgICAgICBbXCJ0aXRsZVwiLCBcIntFbnRpdHlJRH3rqoVcIl0sXG4gICAgICAgICAgICBbXCJwYXJlbnRcIiwgXCLsg4HsnIR7RW50aXR5SUR9XCJdLFxuICAgICAgICAgICAgW1wiZGVzY1wiLCBcIuyEpOuqhVwiXSxcbiAgICAgICAgICAgIFtcImF0XCIsIFwi7J287IucXCJdLFxuICAgICAgICAgICAgW1wiY3JlYXRlZFwiLCBcIuuTseuhnVwiXSxcbiAgICAgICAgICAgIFtcInVwZGF0ZWRcIiwgXCLsiJjsoJVcIl0sXG4gICAgICAgICAgICBbXCJkZWxldGVkXCIsIFwi7IKt7KCcXCJdLFxuICAgICAgICAgICAgW1wiYnlcIiwgXCLsnKDsoIBcIl0sXG4gICAgICAgICAgICBbXCJkYXRlXCIsIFwi7J287J6QXCJdLFxuICAgICAgICAgICAgW1widGltZVwiLCBcIuyLnOqwhFwiXSxcbiAgICAgICAgICAgIFtcImtvXCIsIFwiKO2VnOq4gClcIl0sXG4gICAgICAgICAgICBbXCJlblwiLCBcIijsmIHrrLgpXCJdLFxuICAgICAgICAgICAgW1wia3J3XCIsIFwiKOybkClcIl0sXG4gICAgICAgICAgICBbXCJ1c2RcIiwgXCIoVVNEKVwiXSxcbiAgICAgICAgICAgIFtcImNvbG9yXCIsIFwi7Lus65+sXCJdLFxuICAgICAgICAgICAgW1wiY29kZVwiLCBcIuy9lOuTnFwiXSxcbiAgICAgICAgICAgIFtcInhcIiwgXCJY7KKM7ZGcXCJdLFxuICAgICAgICAgICAgW1wieVwiLCBcIlnsooztkZxcIl0sXG4gICAgICAgICAgICBbXCJjdXJyZW50XCIsIFwi7ZiE7J6sXCJdLFxuICAgICAgICAgICAgW1wic3RvY2tcIiwgXCLsnqzqs6BcIl0sXG4gICAgICAgICAgICBbXCJ0b3RhbFwiLCBcIuy0nVwiXSxcbiAgICAgICAgICAgIFtcImFkbWluXCIsIFwi6rSA66as7J6QXCJdLFxuICAgICAgICAgICAgW1wiZ3JvdXBcIiwgXCLqt7jro7lcIl0sXG4gICAgICAgICAgICBbXCJpdGVtXCIsIFwi7JWE7J207YWcXCJdLFxuICAgICAgICAgICAgW1wiY250XCIsIFwi7IiY65+JXCJdLFxuICAgICAgICAgICAgW1wicHJpY2VcIiwgXCLqsIDqsqlcIl0sXG4gICAgICAgICAgICBbXCJwcmVzZXRcIiwgXCLtlITrpqzshYtcIl0sXG4gICAgICAgICAgICBbXCJhY2N0XCIsIFwi6rOE7KKMXCJdLFxuICAgICAgICAgICAgW1widGVsXCIsIFwi7KCE7ZmU67KI7Zi4XCJdLFxuICAgICAgICAgICAgW1wibm9cIiwgXCLrsojtmLhcIl0sXG4gICAgICAgICAgICBbXCJib2R5XCIsIFwi64K07JqpXCJdLFxuICAgICAgICAgICAgW1wiY29udGVudFwiLCBcIuuCtOyaqVwiXSxcbiAgICAgICAgICAgIFtcIm9yZGVybm9cIiwgXCLsoJXroKzsiJzshJxcIl0sXG4gICAgICAgICAgICBbXCJwcmlvcml0eVwiLCBcIuyasOyEoOyInOychFwiXSxcbiAgICAgICAgICAgIFtcInRleHRcIiwgXCLthY3siqTtirhcIl0sXG4gICAgICAgICAgICBbXCJrZXlcIiwgXCLtgqRcIl0sXG4gICAgICAgICAgICBbXCJzdW1cIiwgXCLtlansgrBcIl0sXG4gICAgICAgICAgICBbXCJleHBlY3RlZFwiLCBcIuyYiOyDgVwiXSxcbiAgICAgICAgICAgIFtcImFjdHVhbFwiLCBcIuyLpOygnFwiXSxcbiAgICAgICAgICBdKTtcbiAgICAgICAgICAvLyDsoITssrQg7JeU7Yuw7YuwIOyInO2ajO2VmOupsCwg7JeU7Yuw7YuwIO2DgOydtO2LgOqzvCDtlITroa0g7ISk66qF7J2EIOy5mO2ZmCDsmqnslrTsp5Hsl5Ag7LaU6rCAXG4gICAgICAgICAgZm9yIChjb25zdCBnbG9zc2FyeUVudGl0eUlkIG9mIEVudGl0eU1hbmFnZXIuZ2V0QWxsSWRzKCkpIHtcbiAgICAgICAgICAgIGNvbnN0IGdsb3NzYXJ5RW50aXR5ID0gRW50aXR5TWFuYWdlci5nZXQoZ2xvc3NhcnlFbnRpdHlJZCk7XG4gICAgICAgICAgICBpZiAoKGdsb3NzYXJ5RW50aXR5LnRpdGxlID8/IFwiXCIpICE9PSBcIlwiKSB7XG4gICAgICAgICAgICAgIGdsb3NzYXJ5LnNldChpbmZsZWN0aW9uLnVuZGVyc2NvcmUoZ2xvc3NhcnlFbnRpdHkuaWQpLCBnbG9zc2FyeUVudGl0eS50aXRsZSk7XG4gICAgICAgICAgICAgIGdsb3NzYXJ5LnNldChcbiAgICAgICAgICAgICAgICBpbmZsZWN0aW9uLnVuZGVyc2NvcmUoaW5mbGVjdGlvbi5wbHVyYWxpemUoZ2xvc3NhcnlFbnRpdHkuaWQpKSxcbiAgICAgICAgICAgICAgICBgJHtnbG9zc2FyeUVudGl0eS50aXRsZX3rpqzsiqTtirhgLFxuICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBnbG9zc2FyeUVudGl0eS5wcm9wcy5mb3JFYWNoKChwcm9wKSA9PiB7XG4gICAgICAgICAgICAgIGlmIChnbG9zc2FyeS5oYXMocHJvcC5uYW1lKSkge1xuICAgICAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICBpZiAocHJvcC5kZXNjKSB7XG4gICAgICAgICAgICAgICAgZ2xvc3Nhcnkuc2V0KFxuICAgICAgICAgICAgICAgICAgcHJvcC5uYW1lLFxuICAgICAgICAgICAgICAgICAgcHJvcC5kZXNjLnJlcGxhY2UoZ2xvc3NhcnlFbnRpdHkudGl0bGUgPz8gXCJcIiwgXCJ7RW50aXR5SUR9XCIpLFxuICAgICAgICAgICAgICAgICk7XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIGNvbnN0IHN1Z2dlc3RlZCA9ICgoKSA9PiB7XG4gICAgICAgICAgICAvLyDri6jslrQg67aE66asLCDqsIDriqXtlZwg7KGw7ZWpIOyDneyEsVxuICAgICAgICAgICAgY29uc3Qgd29yZHMgPSBvcmlnaW4uc3BsaXQoXCJfXCIpO1xuICAgICAgICAgICAgY29uc3QgY29tYmluYXRpb25zID0gWy4uLnJhbmdlKHdvcmRzLmxlbmd0aCwgMCwgLTEpXS5mbGF0TWFwKChsZW4pID0+IHtcbiAgICAgICAgICAgICAgcmV0dXJuIFtcbiAgICAgICAgICAgICAgICAuLi5yYW5nZSgwLCB3b3Jkcy5sZW5ndGggLSBsZW4gKyAxLCAoaWR4KSA9PiB7XG4gICAgICAgICAgICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgICAgICAgICBsZW4sXG4gICAgICAgICAgICAgICAgICAgIHc6IHdvcmRzLnNsaWNlKGlkeCwgaWR4ICsgbGVuKS5qb2luKFwiX1wiKSxcbiAgICAgICAgICAgICAgICAgIH07XG4gICAgICAgICAgICAgICAgfSksXG4gICAgICAgICAgICAgIF07XG4gICAgICAgICAgICB9KTtcblxuICAgICAgICAgICAgLy8g7KGw7ZWp7J2EIOyInO2ajO2VmOupsCwg7LmY7ZmYIOyaqeyWtOynkeyXkCDsnojripQg64uo7Ja06rCAIO2PrO2VqOuQnCDqsr3smrAsIOy5mO2ZmCDsmqnslrTroZwg7LmY7ZmYXG4gICAgICAgICAgICBjb25zdCBSRVBMQUNFRF9QUkVGSVggPSBcIiNSRVBMQUNFRC8vXCI7IC8vIOy5mO2ZmOuQnCDri6jslrTrpbwgam9pbiDsnbTtm4Tsl5Drj4Qg7Iud67OE7ZWY6riwIOychO2VtCBwcmVmaXgg7LaU6rCAXG4gICAgICAgICAgICBsZXQgcmVtYWluQXJyOiBzdHJpbmdbXSA9IFsuLi53b3Jkc107XG4gICAgICAgICAgICBmb3IgKGNvbnN0IGNvbWIgb2YgY29tYmluYXRpb25zKSB7XG4gICAgICAgICAgICAgIGNvbnN0IHJlbWFpblN0ciA9IHJlbWFpbkFyci5qb2luKFwiX1wiKTtcbiAgICAgICAgICAgICAgaWYgKHJlbWFpblN0ci5pbmNsdWRlcyhjb21iLncpICYmIGdsb3NzYXJ5Lmhhcyhjb21iLncpKSB7XG4gICAgICAgICAgICAgICAgcmVtYWluQXJyID0gcmVtYWluU3RyXG4gICAgICAgICAgICAgICAgICAucmVwbGFjZShjb21iLncsIFJFUExBQ0VEX1BSRUZJWCArIGdsb3NzYXJ5LmdldChjb21iLncpKVxuICAgICAgICAgICAgICAgICAgLnNwbGl0KFwiX1wiKTtcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICByZXR1cm4gcmVtYWluQXJyXG4gICAgICAgICAgICAgIC5tYXAoKHIpID0+IHtcbiAgICAgICAgICAgICAgICBpZiAoci5zdGFydHNXaXRoKFJFUExBQ0VEX1BSRUZJWCkpIHtcbiAgICAgICAgICAgICAgICAgIHJldHVybiByLnJlcGxhY2UoUkVQTEFDRURfUFJFRklYLCBcIlwiKTtcbiAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgcmV0dXJuIHIudG9VcHBlckNhc2UoKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIH0pXG4gICAgICAgICAgICAgIC5qb2luKFwiXCIpXG4gICAgICAgICAgICAgIC5yZXBsYWNlKC97RW50aXR5SUR9L2csIGVudGl0eUlkID8gRW50aXR5TWFuYWdlci5nZXQoZW50aXR5SWQpLnRpdGxlIDogXCJcIik7XG4gICAgICAgICAgfSkoKTtcblxuICAgICAgICAgIHJldHVybiB7IHN1Z2dlc3RlZCB9O1xuICAgICAgICB9KSxcbiAgICAgICk7XG5cbiAgICAgIHNlcnZlci5nZXQoXCIvYXBpL2VudGl0eS9maW5kTWFueVwiLCBhc3luYyAoKSA9PiB7XG4gICAgICAgIGNvbnN0IGVudGl0eUlkcyA9IEVudGl0eU1hbmFnZXIuZ2V0QWxsSWRzKCk7XG5cbiAgICAgICAgY29uc3QgZW50aXRpZXMgPSBhd2FpdCBQcm9taXNlLmFsbChcbiAgICAgICAgICBlbnRpdHlJZHMubWFwKChlbnRpdHlJZCkgPT4ge1xuICAgICAgICAgICAgY29uc3QgZW50aXR5ID0gRW50aXR5TWFuYWdlci5nZXQoZW50aXR5SWQpO1xuICAgICAgICAgICAgY29uc3Qgc3Vic2V0Um93cyA9IGVudGl0eS5nZXRTdWJzZXRSb3dzKCk7XG5cbiAgICAgICAgICAgIC8vIHpvZCDsnbjsiqTthLTsiqTrpbwgc3ByZWFk7ZWY66m0IEpTT04uc3RyaW5naWZ56rCAIHJlZmVyZW5jZeulvCDsnbjrnbzsnbjsnLzroZwg7ZKA7Ja064K066mwIOydkeuLteydtCDsiJjrsLEgTULquYzsp4Ag67aA7ZKA7Ja0IFY4IHN0cmluZyBsaW1pdOulvCDstIjqs7ztlZzri6QuXG4gICAgICAgICAgICBjb25zdCB7XG4gICAgICAgICAgICAgIHR5cGVzOiBfdHlwZXMsXG4gICAgICAgICAgICAgIGVudW1zOiBfZW51bXMsXG4gICAgICAgICAgICAgIGVudW1Db25lczogX2VudW1Db25lcyxcbiAgICAgICAgICAgICAgc3Vic2V0Q29uZXM6IF9zdWJzZXRDb25lcyxcbiAgICAgICAgICAgICAgLi4ucmVzdFxuICAgICAgICAgICAgfSA9IGVudGl0eTtcblxuICAgICAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgICAgLi4ucmVzdCxcbiAgICAgICAgICAgICAgZmxhdHRlblN1YnNldFJvd3M6IGZsYXR0ZW5TdWJzZXRSb3dzKHN1YnNldFJvd3MpLFxuICAgICAgICAgICAgfTtcbiAgICAgICAgICB9KSxcbiAgICAgICAgKTtcblxuICAgICAgICBlbnRpdGllcy5zb3J0KChhLCBiKSA9PiB7XG4gICAgICAgICAgY29uc3QgYUlkID0gYS5wYXJlbnRJZCA/PyBhLmlkO1xuICAgICAgICAgIGNvbnN0IGJJZCA9IGIucGFyZW50SWQgPz8gYi5pZDtcbiAgICAgICAgICBpZiAoYUlkIDwgYklkKSByZXR1cm4gLTE7XG4gICAgICAgICAgaWYgKGFJZCA+IGJJZCkgcmV0dXJuIDE7XG4gICAgICAgICAgaWYgKGFJZCA9PT0gYklkKSB7XG4gICAgICAgICAgICBpZiAoYS5wYXJlbnRJZCA9PT0gdW5kZWZpbmVkKSByZXR1cm4gLTE7XG4gICAgICAgICAgICBpZiAoYi5wYXJlbnRJZCA9PT0gdW5kZWZpbmVkKSByZXR1cm4gMTtcbiAgICAgICAgICAgIHJldHVybiAwO1xuICAgICAgICAgIH1cbiAgICAgICAgICByZXR1cm4gMDtcbiAgICAgICAgfSk7XG4gICAgICAgIHJldHVybiB7IGVudGl0aWVzIH07XG4gICAgICB9KTtcblxuICAgICAgc2VydmVyLmdldDx7XG4gICAgICAgIFF1ZXJ5c3RyaW5nOiB7XG4gICAgICAgICAgZmlsdGVyPzogXCJlbnVtc1wiIHwgXCJ0eXBlc1wiO1xuICAgICAgICAgIHJlbG9hZD86IFwiMVwiO1xuICAgICAgICB9O1xuICAgICAgfT4oXG4gICAgICAgIFwiL2FwaS9lbnRpdHkvdHlwZUlkc1wiLFxuICAgICAgICAocmVxdWVzdCk6IFByb21pc2U8eyB0eXBlSWRzOiBzdHJpbmdbXSB9PiA9PlxuICAgICAgICAgIGZvcndhcmRBc3luY0Vycm9ycyhhc3luYyAoKSA9PiB7XG4gICAgICAgICAgICBjb25zdCB7IGZpbHRlciwgcmVsb2FkIH0gPSByZXF1ZXN0LnF1ZXJ5O1xuXG4gICAgICAgICAgICBpZiAocmVsb2FkID09PSBcIjFcIikge1xuICAgICAgICAgICAgICBhd2FpdCBTb25hbXUuc3luY2VyLmF1dG9sb2FkVHlwZXMoKTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgY29uc3QgdHlwZUlkcyA9ICgoKSA9PiB7XG4gICAgICAgICAgICAgIC8vIO2UhOuhnOygne2KuOyXkOyEnCDsoJXsnZjtlZwg7YOA7J6F65OkXG4gICAgICAgICAgICAgIGNvbnN0IHByb2plY3RUeXBlSWRzID0gT2JqZWN0LmVudHJpZXMoU29uYW11LnN5bmNlci50eXBlcylcbiAgICAgICAgICAgICAgICAuZmlsdGVyKChbX3R5cGVJZCwgem9kVHlwZV0pID0+IHtcbiAgICAgICAgICAgICAgICAgIGNvbnN0IHsgX3pvZDogem9kTWV0YWRhdGEgfSA9IHpvZFR5cGU7XG4gICAgICAgICAgICAgICAgICByZXR1cm4gKFxuICAgICAgICAgICAgICAgICAgICAvKiBTQUZFVFk6IFVJIOuPhOq1rOydmCBab2Qg7J6F66ClIOyKpO2CpOuniOqwgCDsnbQg6rCS7J2YIO2DgOyeheydhCDrs7TsnqXtlZzri6QuICovICh6b2RNZXRhZGF0YVxuICAgICAgICAgICAgICAgICAgICAgIC5kZWYudHlwZSBhcyBzdHJpbmcpICE9PSBcImVudW1cIlxuICAgICAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgICAgICB9KVxuICAgICAgICAgICAgICAgIC5tYXAoKFt0eXBlSWQsIF96b2RUeXBlXSkgPT4gdHlwZUlkKTtcblxuICAgICAgICAgICAgICAvLyDrgrTsnqUg7YOA7J6F65OkIChzb25hbXUg7L2U7Ja07JeQ7IScIOygnOqztSlcbiAgICAgICAgICAgICAgY29uc3QgYnVpbHRJblR5cGVJZHMgPSBbLi4uQlVJTFRfSU5fVFlQRV9JRFNdO1xuXG4gICAgICAgICAgICAgIC8vIOuqqOuToCDtg4DsnoUg67OR7ZWpXG4gICAgICAgICAgICAgIGNvbnN0IGFsbFR5cGVJZHMgPSBbLi4uYnVpbHRJblR5cGVJZHMsIC4uLnByb2plY3RUeXBlSWRzXTtcblxuICAgICAgICAgICAgICBpZiAoZmlsdGVyID09PSBcInR5cGVzXCIpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gYWxsVHlwZUlkcztcbiAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgIGNvbnN0IGVudW1JZHMgPSBFbnRpdHlNYW5hZ2VyLmdldEFsbElkcygpLmZsYXRNYXAoKGVudGl0eUlkKSA9PiB7XG4gICAgICAgICAgICAgICAgY29uc3QgZW50aXR5ID0gRW50aXR5TWFuYWdlci5nZXQoZW50aXR5SWQpO1xuICAgICAgICAgICAgICAgIHJldHVybiBPYmplY3Qua2V5cyhlbnRpdHkuZW51bUxhYmVscyk7XG4gICAgICAgICAgICAgIH0pO1xuXG4gICAgICAgICAgICAgIGlmIChmaWx0ZXIgPT09IFwiZW51bXNcIikge1xuICAgICAgICAgICAgICAgIHJldHVybiBlbnVtSWRzO1xuICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIHJldHVybiBbLi4uYWxsVHlwZUlkcywgLi4uZW51bUlkc107XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0pKCk7XG5cbiAgICAgICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICAgIHR5cGVJZHMsXG4gICAgICAgICAgICB9O1xuICAgICAgICAgIH0pLFxuICAgICAgKTtcblxuICAgICAgc2VydmVyLnBvc3Q8e1xuICAgICAgICBCb2R5OiB7XG4gICAgICAgICAgZm9ybToge1xuICAgICAgICAgICAgaWQ6IHN0cmluZztcbiAgICAgICAgICAgIHRpdGxlOiBzdHJpbmc7XG4gICAgICAgICAgICB0YWJsZTogc3RyaW5nO1xuICAgICAgICAgICAgcGFyZW50SWQ/OiBzdHJpbmc7XG4gICAgICAgICAgfTtcbiAgICAgICAgfTtcbiAgICAgIH0+KFwiL2FwaS9lbnRpdHkvY3JlYXRlXCIsIChyZXF1ZXN0KSA9PlxuICAgICAgICBmb3J3YXJkQXN5bmNFcnJvcnMoYXN5bmMgKCkgPT4ge1xuICAgICAgICAgIHJldHVybiBhd2FpdCB3YWl0Rm9ySE1SQ29tcGxldGVkKGFzeW5jICgpID0+IHtcbiAgICAgICAgICAgIGNvbnN0IHsgZm9ybSB9ID0gcmVxdWVzdC5ib2R5O1xuICAgICAgICAgICAgYXdhaXQgU29uYW11LnN5bmNlci5jcmVhdGVFbnRpdHkoeyAuLi5mb3JtLCBlbnRpdHlJZDogZm9ybS5pZCB9KTtcblxuICAgICAgICAgICAgcmV0dXJuIDE7XG4gICAgICAgICAgfSk7XG4gICAgICAgIH0pLFxuICAgICAgKTtcblxuICAgICAgc2VydmVyLnBvc3Q8e1xuICAgICAgICBCb2R5OiB7XG4gICAgICAgICAgZW50aXR5SWQ6IHN0cmluZztcbiAgICAgICAgfTtcbiAgICAgIH0+KFwiL2FwaS9lbnRpdHkvZGVsXCIsIChyZXF1ZXN0KSA9PlxuICAgICAgICBmb3J3YXJkQXN5bmNFcnJvcnMoYXN5bmMgKCkgPT4ge1xuICAgICAgICAgIHJldHVybiBhd2FpdCB3YWl0Rm9ySE1SQ29tcGxldGVkKGFzeW5jICgpID0+IHtcbiAgICAgICAgICAgIGNvbnN0IHsgZW50aXR5SWQgfSA9IHJlcXVlc3QuYm9keTtcbiAgICAgICAgICAgIHJldHVybiBhd2FpdCBTb25hbXUuc3luY2VyLmRlbEVudGl0eShlbnRpdHlJZCk7XG4gICAgICAgICAgfSk7XG4gICAgICAgIH0pLFxuICAgICAgKTtcblxuICAgICAgc2VydmVyLnBvc3Q8e1xuICAgICAgICBCb2R5OiB7XG4gICAgICAgICAgZW50aXR5SWQ6IHN0cmluZztcbiAgICAgICAgICBuZXdWYWx1ZXM6IHtcbiAgICAgICAgICAgIHRpdGxlOiBzdHJpbmc7XG4gICAgICAgICAgICB0YWJsZTogc3RyaW5nO1xuICAgICAgICAgICAgcGFyZW50SWQ/OiBzdHJpbmc7XG4gICAgICAgICAgfTtcbiAgICAgICAgfTtcbiAgICAgIH0+KFwiL2FwaS9lbnRpdHkvbW9kaWZ5RW50aXR5QmFzZVwiLCAocmVxdWVzdCkgPT5cbiAgICAgICAgZm9yd2FyZEFzeW5jRXJyb3JzKGFzeW5jICgpID0+IHtcbiAgICAgICAgICByZXR1cm4gYXdhaXQgd2FpdEZvckhNUkNvbXBsZXRlZChhc3luYyAoKSA9PiB7XG4gICAgICAgICAgICBjb25zdCB7IGVudGl0eUlkLCBuZXdWYWx1ZXMgfSA9IHJlcXVlc3QuYm9keTtcbiAgICAgICAgICAgIGNvbnN0IGVudGl0eSA9IEVudGl0eU1hbmFnZXIuZ2V0KGVudGl0eUlkKTtcbiAgICAgICAgICAgIGVudGl0eS50aXRsZSA9IG5ld1ZhbHVlcy50aXRsZTtcbiAgICAgICAgICAgIGVudGl0eS50YWJsZSA9IG5ld1ZhbHVlcy50YWJsZTtcbiAgICAgICAgICAgIGVudGl0eS5wYXJlbnRJZCA9IG5ld1ZhbHVlcy5wYXJlbnRJZDtcbiAgICAgICAgICAgIGF3YWl0IGVudGl0eS5zYXZlKCk7XG5cbiAgICAgICAgICAgIHJldHVybiAxO1xuICAgICAgICAgIH0pO1xuICAgICAgICB9KSxcbiAgICAgICk7XG5cbiAgICAgIHNlcnZlci5wb3N0PHtcbiAgICAgICAgQm9keToge1xuICAgICAgICAgIGVudGl0eUlkOiBzdHJpbmc7XG4gICAgICAgICAgc3Vic2V0S2V5OiBzdHJpbmc7XG4gICAgICAgICAgZmllbGRzOiBzdHJpbmdbXTtcbiAgICAgICAgICBmaWVsZHNJbnRlcm5hbD86IHN0cmluZ1tdO1xuICAgICAgICB9O1xuICAgICAgfT4oXCIvYXBpL2VudGl0eS9tb2RpZnlTdWJzZXRcIiwgKHJlcXVlc3QpID0+XG4gICAgICAgIGZvcndhcmRBc3luY0Vycm9ycyhhc3luYyAoKSA9PiB7XG4gICAgICAgICAgcmV0dXJuIGF3YWl0IHdhaXRGb3JITVJDb21wbGV0ZWQoYXN5bmMgKCkgPT4ge1xuICAgICAgICAgICAgY29uc3QgeyBlbnRpdHlJZCwgc3Vic2V0S2V5LCBmaWVsZHMsIGZpZWxkc0ludGVybmFsIH0gPSByZXF1ZXN0LmJvZHk7XG4gICAgICAgICAgICBjb25zdCBlbnRpdHkgPSBFbnRpdHlNYW5hZ2VyLmdldChlbnRpdHlJZCk7XG4gICAgICAgICAgICBlbnRpdHkuc3Vic2V0c1tzdWJzZXRLZXldID0gZmllbGRzO1xuICAgICAgICAgICAgaWYgKGZpZWxkc0ludGVybmFsICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgICAgaWYgKGZpZWxkc0ludGVybmFsLmxlbmd0aCA+IDApIHtcbiAgICAgICAgICAgICAgICBlbnRpdHkuc3Vic2V0c0ludGVybmFsW3N1YnNldEtleV0gPSBmaWVsZHNJbnRlcm5hbDtcbiAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICBkZWxldGUgZW50aXR5LnN1YnNldHNJbnRlcm5hbFtzdWJzZXRLZXldO1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBhd2FpdCBlbnRpdHkuc2F2ZSgpO1xuXG4gICAgICAgICAgICByZXR1cm4geyB1cGRhdGVkOiBmaWVsZHMsIHVwZGF0ZWRJbnRlcm5hbDogZmllbGRzSW50ZXJuYWwgfTtcbiAgICAgICAgICB9KTtcbiAgICAgICAgfSksXG4gICAgICApO1xuXG4gICAgICBzZXJ2ZXIucG9zdDx7XG4gICAgICAgIEJvZHk6IHtcbiAgICAgICAgICBlbnRpdHlJZDogc3RyaW5nO1xuICAgICAgICAgIHN1YnNldEtleTogc3RyaW5nO1xuICAgICAgICB9O1xuICAgICAgfT4oXCIvYXBpL2VudGl0eS9kZWxTdWJzZXRcIiwgKHJlcXVlc3QpID0+XG4gICAgICAgIGZvcndhcmRBc3luY0Vycm9ycyhhc3luYyAoKSA9PiB7XG4gICAgICAgICAgcmV0dXJuIGF3YWl0IHdhaXRGb3JITVJDb21wbGV0ZWQoYXN5bmMgKCkgPT4ge1xuICAgICAgICAgICAgY29uc3QgeyBlbnRpdHlJZCwgc3Vic2V0S2V5IH0gPSByZXF1ZXN0LmJvZHk7XG4gICAgICAgICAgICBjb25zdCBlbnRpdHkgPSBFbnRpdHlNYW5hZ2VyLmdldChlbnRpdHlJZCk7XG4gICAgICAgICAgICBkZWxldGUgZW50aXR5LnN1YnNldHNbc3Vic2V0S2V5XTtcbiAgICAgICAgICAgIGRlbGV0ZSBlbnRpdHkuc3Vic2V0c0ludGVybmFsW3N1YnNldEtleV07XG4gICAgICAgICAgICBhd2FpdCBlbnRpdHkuc2F2ZSgpO1xuXG4gICAgICAgICAgICByZXR1cm4gMTtcbiAgICAgICAgICB9KTtcbiAgICAgICAgfSksXG4gICAgICApO1xuXG4gICAgICBzZXJ2ZXIucG9zdDx7XG4gICAgICAgIEJvZHk6IHtcbiAgICAgICAgICBlbnRpdHlJZDogc3RyaW5nO1xuICAgICAgICAgIG5ld1Byb3A6IEVudGl0eVByb3A7XG4gICAgICAgICAgYXQ/OiBudW1iZXI7XG4gICAgICAgIH07XG4gICAgICB9PihcIi9hcGkvZW50aXR5L2NyZWF0ZVByb3BcIiwgKHJlcXVlc3QpID0+XG4gICAgICAgIGZvcndhcmRBc3luY0Vycm9ycyhhc3luYyAoKSA9PiB7XG4gICAgICAgICAgcmV0dXJuIGF3YWl0IHdhaXRGb3JITVJDb21wbGV0ZWQoYXN5bmMgKCkgPT4ge1xuICAgICAgICAgICAgY29uc3QgeyBlbnRpdHlJZCwgYXQsIG5ld1Byb3AgfSA9IHJlcXVlc3QuYm9keTtcbiAgICAgICAgICAgIGNvbnN0IGVudGl0eSA9IEVudGl0eU1hbmFnZXIuZ2V0KGVudGl0eUlkKTtcbiAgICAgICAgICAgIGF3YWl0IGVudGl0eS5jcmVhdGVQcm9wKG5ld1Byb3AsIGF0KTtcbiAgICAgICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgICAgIH0pO1xuICAgICAgICB9KSxcbiAgICAgICk7XG5cbiAgICAgIHNlcnZlci5wb3N0PHtcbiAgICAgICAgQm9keToge1xuICAgICAgICAgIGVudGl0eUlkOiBzdHJpbmc7XG4gICAgICAgICAgbmV3UHJvcDogRW50aXR5UHJvcDtcbiAgICAgICAgICBhdDogbnVtYmVyO1xuICAgICAgICB9O1xuICAgICAgfT4oXCIvYXBpL2VudGl0eS9tb2RpZnlQcm9wXCIsIChyZXF1ZXN0KSA9PlxuICAgICAgICBmb3J3YXJkQXN5bmNFcnJvcnMoYXN5bmMgKCkgPT4ge1xuICAgICAgICAgIHJldHVybiBhd2FpdCB3YWl0Rm9ySE1SQ29tcGxldGVkKGFzeW5jICgpID0+IHtcbiAgICAgICAgICAgIGNvbnN0IHsgZW50aXR5SWQsIGF0LCBuZXdQcm9wIH0gPSByZXF1ZXN0LmJvZHk7XG5cbiAgICAgICAgICAgIGNvbnN0IGVudGl0eSA9IEVudGl0eU1hbmFnZXIuZ2V0KGVudGl0eUlkKTtcbiAgICAgICAgICAgIGVudGl0eS5tb2RpZnlQcm9wKG5ld1Byb3AsIGF0KTtcblxuICAgICAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICAgICAgfSk7XG4gICAgICAgIH0pLFxuICAgICAgKTtcblxuICAgICAgc2VydmVyLnBvc3Q8e1xuICAgICAgICBCb2R5OiB7XG4gICAgICAgICAgZW50aXR5SWQ6IHN0cmluZztcbiAgICAgICAgICBhdDogbnVtYmVyO1xuICAgICAgICB9O1xuICAgICAgfT4oXCIvYXBpL2VudGl0eS9kZWxQcm9wXCIsIChyZXF1ZXN0KSA9PlxuICAgICAgICBmb3J3YXJkQXN5bmNFcnJvcnMoYXN5bmMgKCkgPT4ge1xuICAgICAgICAgIHJldHVybiBhd2FpdCB3YWl0Rm9ySE1SQ29tcGxldGVkKGFzeW5jICgpID0+IHtcbiAgICAgICAgICAgIGNvbnN0IHsgZW50aXR5SWQsIGF0IH0gPSByZXF1ZXN0LmJvZHk7XG5cbiAgICAgICAgICAgIGNvbnN0IGVudGl0eSA9IEVudGl0eU1hbmFnZXIuZ2V0KGVudGl0eUlkKTtcbiAgICAgICAgICAgIGVudGl0eS5kZWxQcm9wKGF0KTtcbiAgICAgICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgICAgIH0pO1xuICAgICAgICB9KSxcbiAgICAgICk7XG5cbiAgICAgIHNlcnZlci5wb3N0PHtcbiAgICAgICAgQm9keToge1xuICAgICAgICAgIGVudGl0eUlkOiBzdHJpbmc7XG4gICAgICAgICAgYXQ6IG51bWJlcjtcbiAgICAgICAgICB0bzogbnVtYmVyO1xuICAgICAgICB9O1xuICAgICAgfT4oXCIvYXBpL2VudGl0eS9tb3ZlUHJvcFwiLCAocmVxdWVzdCkgPT5cbiAgICAgICAgZm9yd2FyZEFzeW5jRXJyb3JzKGFzeW5jICgpID0+IHtcbiAgICAgICAgICByZXR1cm4gYXdhaXQgd2FpdEZvckhNUkNvbXBsZXRlZChhc3luYyAoKSA9PiB7XG4gICAgICAgICAgICBjb25zdCB7IGVudGl0eUlkLCBhdCwgdG8gfSA9IHJlcXVlc3QuYm9keTtcblxuICAgICAgICAgICAgY29uc3QgZW50aXR5ID0gRW50aXR5TWFuYWdlci5nZXQoZW50aXR5SWQpO1xuICAgICAgICAgICAgZW50aXR5Lm1vdmVQcm9wKGF0LCB0byk7XG5cbiAgICAgICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgICAgIH0pO1xuICAgICAgICB9KSxcbiAgICAgICk7XG5cbiAgICAgIHNlcnZlci5wb3N0PHtcbiAgICAgICAgQm9keToge1xuICAgICAgICAgIGVudGl0eUlkOiBzdHJpbmc7XG4gICAgICAgICAgaW5kZXhlczogRW50aXR5SW5kZXhbXTtcbiAgICAgICAgfTtcbiAgICAgIH0+KFwiL2FwaS9lbnRpdHkvbW9kaWZ5SW5kZXhlc1wiLCAocmVxdWVzdCkgPT5cbiAgICAgICAgZm9yd2FyZEFzeW5jRXJyb3JzKGFzeW5jICgpID0+IHtcbiAgICAgICAgICByZXR1cm4gYXdhaXQgd2FpdEZvckhNUkNvbXBsZXRlZChhc3luYyAoKSA9PiB7XG4gICAgICAgICAgICBjb25zdCB7IGVudGl0eUlkLCBpbmRleGVzIH0gPSByZXF1ZXN0LmJvZHk7XG4gICAgICAgICAgICBjb25zdCBlbnRpdHkgPSBFbnRpdHlNYW5hZ2VyLmdldChlbnRpdHlJZCk7XG4gICAgICAgICAgICBlbnRpdHkuaW5kZXhlcyA9IGluZGV4ZXM7XG4gICAgICAgICAgICBhd2FpdCBlbnRpdHkuc2F2ZSgpO1xuXG4gICAgICAgICAgICByZXR1cm4geyB1cGRhdGVkOiBpbmRleGVzIH07XG4gICAgICAgICAgfSk7XG4gICAgICAgIH0pLFxuICAgICAgKTtcblxuICAgICAgc2VydmVyLnBvc3Q8e1xuICAgICAgICBCb2R5OiB7XG4gICAgICAgICAgZW50aXR5SWQ6IHN0cmluZztcbiAgICAgICAgICBlbnVtTGFiZWxzOiBFbnRpdHlbXCJlbnVtTGFiZWxzXCJdO1xuICAgICAgICB9O1xuICAgICAgfT4oXCIvYXBpL2VudGl0eS9tb2RpZnlFbnVtTGFiZWxzXCIsIChyZXF1ZXN0KSA9PlxuICAgICAgICBmb3J3YXJkQXN5bmNFcnJvcnMoYXN5bmMgKCkgPT4ge1xuICAgICAgICAgIHJldHVybiBhd2FpdCB3YWl0Rm9ySE1SQ29tcGxldGVkKGFzeW5jICgpID0+IHtcbiAgICAgICAgICAgIGNvbnN0IHsgZW50aXR5SWQsIGVudW1MYWJlbHMgfSA9IHJlcXVlc3QuYm9keTtcbiAgICAgICAgICAgIGNvbnN0IGVudGl0eSA9IEVudGl0eU1hbmFnZXIuZ2V0KGVudGl0eUlkKTtcbiAgICAgICAgICAgIGVudGl0eS5lbnVtTGFiZWxzID0gZW51bUxhYmVscztcbiAgICAgICAgICAgIGF3YWl0IGVudGl0eS5zYXZlKCk7XG5cbiAgICAgICAgICAgIHJldHVybiB7IHVwZGF0ZWQ6IGVudW1MYWJlbHMgfTtcbiAgICAgICAgICB9KTtcbiAgICAgICAgfSksXG4gICAgICApO1xuXG4gICAgICBzZXJ2ZXIucG9zdDx7XG4gICAgICAgIEJvZHk6IHtcbiAgICAgICAgICBlbnRpdHlJZDogc3RyaW5nO1xuICAgICAgICAgIG5ld0VudW1JZDogc3RyaW5nO1xuICAgICAgICB9O1xuICAgICAgfT4oXCIvYXBpL2VudGl0eS9jcmVhdGVFbnVtSWRcIiwgKHJlcXVlc3QpID0+XG4gICAgICAgIGZvcndhcmRBc3luY0Vycm9ycyhhc3luYyAoKSA9PiB7XG4gICAgICAgICAgcmV0dXJuIGF3YWl0IHdhaXRGb3JITVJDb21wbGV0ZWQoYXN5bmMgKCkgPT4ge1xuICAgICAgICAgICAgY29uc3QgeyBlbnRpdHlJZCwgbmV3RW51bUlkIH0gPSByZXF1ZXN0LmJvZHk7XG4gICAgICAgICAgICBjb25zdCBlbnRpdHkgPSBFbnRpdHlNYW5hZ2VyLmdldChlbnRpdHlJZCk7XG5cbiAgICAgICAgICAgIGlmIChlbnRpdHkuZW51bUxhYmVsc1tuZXdFbnVtSWRdKSB7XG4gICAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihg7J2066+4IOyhtOyerO2VmOuKlCBlbnVtSWTsnoXri4jri6Q6ICR7bmV3RW51bUlkfWApO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBlbnRpdHkuZW51bUxhYmVsc1tuZXdFbnVtSWRdID0gbmV3RW51bUlkLmVuZHNXaXRoKFwiU3RhdHVzXCIpXG4gICAgICAgICAgICAgID8ge1xuICAgICAgICAgICAgICAgICAgYWN0aXZlOiBcIuuFuOy2nFwiLFxuICAgICAgICAgICAgICAgICAgaGlkZGVuOiBcIuyIqOq5gFwiLFxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgOiB7XG4gICAgICAgICAgICAgICAgICBcIlwiOiBcIlwiLFxuICAgICAgICAgICAgICAgIH07XG4gICAgICAgICAgICBhd2FpdCBlbnRpdHkuc2F2ZSgpO1xuXG4gICAgICAgICAgICByZXR1cm4gMTtcbiAgICAgICAgICB9KTtcbiAgICAgICAgfSksXG4gICAgICApO1xuXG4gICAgICBzZXJ2ZXIucG9zdDx7XG4gICAgICAgIEJvZHk6IHtcbiAgICAgICAgICBlbnRpdHlJZDogc3RyaW5nO1xuICAgICAgICAgIGVudW1JZDoge1xuICAgICAgICAgICAgYmVmb3JlOiBzdHJpbmc7XG4gICAgICAgICAgICBhZnRlcjogc3RyaW5nO1xuICAgICAgICAgIH07XG4gICAgICAgIH07XG4gICAgICB9PihcIi9hcGkvZW50aXR5L21vZGlmeUVudW1JZFwiLCAocmVxdWVzdCkgPT5cbiAgICAgICAgZm9yd2FyZEFzeW5jRXJyb3JzKGFzeW5jICgpID0+IHtcbiAgICAgICAgICByZXR1cm4gYXdhaXQgd2FpdEZvckhNUkNvbXBsZXRlZChhc3luYyAoKSA9PiB7XG4gICAgICAgICAgICBjb25zdCB7IGVudGl0eUlkLCBlbnVtSWQgfSA9IHJlcXVlc3QuYm9keTtcbiAgICAgICAgICAgIGNvbnN0IGVudGl0eUlkcyA9IEVudGl0eU1hbmFnZXIuZ2V0QWxsSWRzKCk7XG4gICAgICAgICAgICBjb25zdCBpc0V4aXN0cyA9IGVudGl0eUlkcy5zb21lKChjYW5kaWRhdGVFbnRpdHlJZCkgPT4ge1xuICAgICAgICAgICAgICBjb25zdCBjYW5kaWRhdGVFbnRpdHkgPSBFbnRpdHlNYW5hZ2VyLmdldChjYW5kaWRhdGVFbnRpdHlJZCk7XG4gICAgICAgICAgICAgIHJldHVybiBPYmplY3Qua2V5cyhjYW5kaWRhdGVFbnRpdHkuZW51bUxhYmVscykuaW5jbHVkZXMoZW51bUlkLmFmdGVyKTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgaWYgKGlzRXhpc3RzKSB7XG4gICAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihg7J2066+4IOyhtOyerO2VmOuKlCBFbnVtSWTsnoXri4jri6Q6ICR7ZW51bUlkLmFmdGVyfWApO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBjb25zdCBlbnRpdHkgPSBFbnRpdHlNYW5hZ2VyLmdldChlbnRpdHlJZCk7XG4gICAgICAgICAgICBlbnRpdHkuZW51bUxhYmVsc1tlbnVtSWQuYWZ0ZXJdID0gZW50aXR5LmVudW1MYWJlbHNbZW51bUlkLmJlZm9yZV07XG4gICAgICAgICAgICBkZWxldGUgZW50aXR5LmVudW1MYWJlbHNbZW51bUlkLmJlZm9yZV07XG5cbiAgICAgICAgICAgIGF3YWl0IGVudGl0eS5zYXZlKCk7XG5cbiAgICAgICAgICAgIGZvciAoY29uc3QgcmVsYXRlZEVudGl0eUlkIG9mIGVudGl0eUlkcykge1xuICAgICAgICAgICAgICBjb25zdCByZWxhdGVkRW50aXR5ID0gRW50aXR5TWFuYWdlci5nZXQocmVsYXRlZEVudGl0eUlkKTtcbiAgICAgICAgICAgICAgZm9yIChjb25zdCBwcm9wIG9mIHJlbGF0ZWRFbnRpdHkucHJvcHMpIHtcbiAgICAgICAgICAgICAgICBpZiAocHJvcC50eXBlID09PSBcImVudW1cIiAmJiBwcm9wLmlkID09PSBlbnVtSWQuYmVmb3JlKSB7XG4gICAgICAgICAgICAgICAgICBwcm9wLmlkID0gZW51bUlkLmFmdGVyO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICBhd2FpdCByZWxhdGVkRW50aXR5LnNhdmUoKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9KTtcbiAgICAgICAgfSksXG4gICAgICApO1xuXG4gICAgICBzZXJ2ZXIucG9zdDx7XG4gICAgICAgIEJvZHk6IHtcbiAgICAgICAgICBlbnRpdHlJZDogc3RyaW5nO1xuICAgICAgICAgIGVudW1JZDogc3RyaW5nO1xuICAgICAgICB9O1xuICAgICAgfT4oXCIvYXBpL2VudGl0eS9kZWxldGVFbnVtSWRcIiwgKHJlcXVlc3QpID0+XG4gICAgICAgIGZvcndhcmRBc3luY0Vycm9ycyhhc3luYyAoKSA9PiB7XG4gICAgICAgICAgcmV0dXJuIGF3YWl0IHdhaXRGb3JITVJDb21wbGV0ZWQoYXN5bmMgKCkgPT4ge1xuICAgICAgICAgICAgY29uc3QgeyBlbnRpdHlJZCwgZW51bUlkIH0gPSByZXF1ZXN0LmJvZHk7XG5cbiAgICAgICAgICAgIGNvbnN0IGVudGl0eUlkcyA9IEVudGl0eU1hbmFnZXIuZ2V0QWxsSWRzKCk7XG4gICAgICAgICAgICBjb25zdCBpc1JlZmVyZW5jZWQgPSBlbnRpdHlJZHNcbiAgICAgICAgICAgICAgLmZsYXRNYXAoKHJlZmVyZW5jaW5nRW50aXR5SWQpID0+IEVudGl0eU1hbmFnZXIuZ2V0KHJlZmVyZW5jaW5nRW50aXR5SWQpLnByb3BzKVxuICAgICAgICAgICAgICAuc29tZSgocHJvcCkgPT4gcHJvcC50eXBlID09PSBcImVudW1cIiAmJiBwcm9wLmlkID09PSBlbnVtSWQpO1xuICAgICAgICAgICAgaWYgKGlzUmVmZXJlbmNlZCkge1xuICAgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYCR7ZW51bUlkfeulvCDssLjsobDtlZjripQg7ZSE66Gc7Y287Yuw6rCAIOyhtOyerO2VqeuLiOuLpC5gKTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgY29uc3QgZW50aXR5ID0gRW50aXR5TWFuYWdlci5nZXQoZW50aXR5SWQpO1xuICAgICAgICAgICAgZGVsZXRlIGVudGl0eS5lbnVtTGFiZWxzW2VudW1JZF07XG4gICAgICAgICAgICBhd2FpdCBlbnRpdHkuc2F2ZSgpO1xuICAgICAgICAgIH0pO1xuICAgICAgICB9KSxcbiAgICAgICk7XG5cbiAgICAgIHNlcnZlci5wb3N0PHtcbiAgICAgICAgQm9keToge1xuICAgICAgICAgIGVudGl0eUlkOiBzdHJpbmc7XG4gICAgICAgICAgdGFyZ2V0OiBcImVudGl0eVwiIHwgXCJwcm9wXCIgfCBcImVudW1cIiB8IFwic3Vic2V0XCI7XG4gICAgICAgICAgcHJvcE5hbWU/OiBzdHJpbmc7XG4gICAgICAgICAgZW51bUlkPzogc3RyaW5nO1xuICAgICAgICAgIHN1YnNldEtleT86IHN0cmluZztcbiAgICAgICAgICBjb25lOiBDb25lO1xuICAgICAgICB9O1xuICAgICAgfT4oXCIvYXBpL2VudGl0eS91cGRhdGVDb25lXCIsIChyZXF1ZXN0KSA9PlxuICAgICAgICBmb3J3YXJkQXN5bmNFcnJvcnMoYXN5bmMgKCkgPT4ge1xuICAgICAgICAgIHJldHVybiBhd2FpdCB3YWl0Rm9ySE1SQ29tcGxldGVkKGFzeW5jICgpID0+IHtcbiAgICAgICAgICAgIGNvbnN0IHsgZW50aXR5SWQsIHRhcmdldCwgcHJvcE5hbWUsIGVudW1JZCwgc3Vic2V0S2V5LCBjb25lIH0gPSByZXF1ZXN0LmJvZHk7XG4gICAgICAgICAgICBjb25zdCBlbnRpdHkgPSBFbnRpdHlNYW5hZ2VyLmdldChlbnRpdHlJZCk7XG5cbiAgICAgICAgICAgIGlmICh0YXJnZXQgPT09IFwiZW50aXR5XCIpIHtcbiAgICAgICAgICAgICAgZW50aXR5LmNvbmUgPSBjb25lO1xuICAgICAgICAgICAgfSBlbHNlIGlmICh0YXJnZXQgPT09IFwicHJvcFwiICYmIHByb3BOYW1lKSB7XG4gICAgICAgICAgICAgIGNvbnN0IHByb3AgPSBlbnRpdHkucHJvcHMuZmluZCgocCkgPT4gcC5uYW1lID09PSBwcm9wTmFtZSk7XG4gICAgICAgICAgICAgIGlmIChwcm9wKSB7XG4gICAgICAgICAgICAgICAgLyogU0FGRVRZOiBVSSDrj4TqtazsnZggWm9kIOyeheugpSDsiqTtgqTrp4jqsIAg7J20IOqwkuydmCDtg4DsnoXsnYQg67O07J6l7ZWc64ukLiAqLyAoXG4gICAgICAgICAgICAgICAgICBwcm9wIGFzIHsgY29uZT86IENvbmUgfVxuICAgICAgICAgICAgICAgICkuY29uZSA9IGNvbmU7XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0gZWxzZSBpZiAodGFyZ2V0ID09PSBcImVudW1cIiAmJiBlbnVtSWQpIHtcbiAgICAgICAgICAgICAgZW50aXR5LmVudW1Db25lc1tlbnVtSWRdID0gY29uZTtcbiAgICAgICAgICAgIH0gZWxzZSBpZiAodGFyZ2V0ID09PSBcInN1YnNldFwiICYmIHN1YnNldEtleSkge1xuICAgICAgICAgICAgICBlbnRpdHkuc3Vic2V0Q29uZXNbc3Vic2V0S2V5XSA9IGNvbmU7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGF3YWl0IGVudGl0eS5zYXZlKCk7XG4gICAgICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgICAgICB9KTtcbiAgICAgICAgfSksXG4gICAgICApO1xuXG4gICAgICBzZXJ2ZXIucG9zdDx7XG4gICAgICAgIEJvZHk6IHtcbiAgICAgICAgICBlbnRpdHlJZDogc3RyaW5nO1xuICAgICAgICAgIHByZXNlcnZlRXhpc3Rpbmc/OiBib29sZWFuO1xuICAgICAgICAgIG9ubHlFbXB0eT86IGJvb2xlYW47XG4gICAgICAgICAgbG9jYWxlPzogXCJrb1wiIHwgXCJlblwiIHwgXCJqYVwiO1xuICAgICAgICB9O1xuICAgICAgfT4oXCIvYXBpL2VudGl0eS9nZW5lcmF0ZUNvbmVzXCIsIGFzeW5jIChyZXF1ZXN0LCByZXBseSkgPT4ge1xuICAgICAgICByZXR1cm4gYXdhaXQgd2FpdEZvckhNUkNvbXBsZXRlZChhc3luYyAoKSA9PiB7XG4gICAgICAgICAgY29uc3QgeyBlbnRpdHlJZCwgcHJlc2VydmVFeGlzdGluZywgb25seUVtcHR5LCBsb2NhbGUgfSA9IHJlcXVlc3QuYm9keTtcblxuICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICAvLyBFbnRpdHkg7KG07J6sIOyXrOu2gCDtmZXsnbhcbiAgICAgICAgICAgIGNvbnN0IGVudGl0eSA9IEVudGl0eU1hbmFnZXIuZ2V0KGVudGl0eUlkKTtcblxuICAgICAgICAgICAgLy8gbG9jYWxlIOq4sOuzuOqwkjogU29uYW11LmNvbmZpZy5pMThuLmRlZmF1bHRMb2NhbGUg7IKs7JqpXG4gICAgICAgICAgICAvLyBTQUZFVFk6IGkxOG4g6rWs7ISxIOyKpO2CpOuniOqwgCDsp4Dsm5AgbG9jYWxl7J2EIGtvL2VuL2ph66GcIOygnO2VnO2VnOuLpC5cbiAgICAgICAgICAgIGNvbnN0IGVmZmVjdGl2ZUxvY2FsZSA9XG4gICAgICAgICAgICAgIGxvY2FsZSA/PyAoU29uYW11LmNvbmZpZy5pMThuLmRlZmF1bHRMb2NhbGUgYXMgXCJrb1wiIHwgXCJlblwiIHwgXCJqYVwiKTtcblxuICAgICAgICAgICAgLy8gQ29uZSDsg53shLFcbiAgICAgICAgICAgIGNvbnN0IHJlc3VsdCA9IGF3YWl0IGVudGl0eS5nZW5lcmF0ZUNvbmVzKHtcbiAgICAgICAgICAgICAgcHJlc2VydmVFeGlzdGluZzogcHJlc2VydmVFeGlzdGluZyA/PyB0cnVlLFxuICAgICAgICAgICAgICBvbmx5RW1wdHk6IG9ubHlFbXB0eSA/PyBmYWxzZSxcbiAgICAgICAgICAgICAgbG9jYWxlOiBlZmZlY3RpdmVMb2NhbGUsXG4gICAgICAgICAgICB9KTtcblxuICAgICAgICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICAgICAgICB9IGNhdGNoIChlcnJvcjogdW5rbm93bikge1xuICAgICAgICAgICAgY29uc3QgbWVzc2FnZSA9IGVycm9yIGluc3RhbmNlb2YgRXJyb3IgPyBlcnJvci5tZXNzYWdlIDogU3RyaW5nKGVycm9yKTtcblxuICAgICAgICAgICAgLy8gRW50aXR5IG5vdCBmb3VuZFxuICAgICAgICAgICAgaWYgKG1lc3NhZ2UuaW5jbHVkZXMoXCLsobTsnqztlZjsp4Ag7JWK64qUIEVudGl0eVwiKSkge1xuICAgICAgICAgICAgICByZXBseS5zdGF0dXMoNDA0KTtcbiAgICAgICAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgICAgICBzdWNjZXNzOiBmYWxzZSxcbiAgICAgICAgICAgICAgICBlcnJvcjogYEVudGl0eSBub3QgZm91bmQ6ICR7ZW50aXR5SWR9YCxcbiAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgLy8gQVBJIO2CpCDsl4bsnYxcbiAgICAgICAgICAgIGlmIChtZXNzYWdlLmluY2x1ZGVzKFwiQU5USFJPUElDX0FQSV9LRVkgbm90IGZvdW5kXCIpKSB7XG4gICAgICAgICAgICAgIHJlcGx5LnN0YXR1cyg1MDApO1xuICAgICAgICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgICAgIHN1Y2Nlc3M6IGZhbHNlLFxuICAgICAgICAgICAgICAgIGVycm9yOiBcIkFQSSBrZXkgbm90IGNvbmZpZ3VyZWRcIixcbiAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgLy8gUmF0ZSBsaW1pdFxuICAgICAgICAgICAgaWYgKG1lc3NhZ2UuaW5jbHVkZXMoXCJSYXRlIGxpbWl0IGV4Y2VlZGVkXCIpKSB7XG4gICAgICAgICAgICAgIHJlcGx5LnN0YXR1cyg0MjkpO1xuICAgICAgICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgICAgIHN1Y2Nlc3M6IGZhbHNlLFxuICAgICAgICAgICAgICAgIGVycm9yOiBcIlJhdGUgbGltaXQgZXhjZWVkZWQuIFBsZWFzZSB0cnkgYWdhaW4gbGF0ZXIuXCIsXG4gICAgICAgICAgICAgIH07XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIC8vIOq4sO2DgCDsl5Drn6xcbiAgICAgICAgICAgIHJlcGx5LnN0YXR1cyg1MDApO1xuICAgICAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgICAgc3VjY2VzczogZmFsc2UsXG4gICAgICAgICAgICAgIGVycm9yOiBgQ29uZSBnZW5lcmF0aW9uIGZhaWxlZDogJHttZXNzYWdlfWAsXG4gICAgICAgICAgICB9O1xuICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgICB9KTtcblxuICAgICAgc2VydmVyLmdldDx7XG4gICAgICAgIFF1ZXJ5c3RyaW5nOiB7XG4gICAgICAgICAgZW50aXR5SWQ6IHN0cmluZztcbiAgICAgICAgfTtcbiAgICAgIH0+KFwiL2FwaS9lbnRpdHkvZ2V0VGFibGVDb2x1bW5zXCIsIChyZXF1ZXN0KSA9PlxuICAgICAgICBmb3J3YXJkQXN5bmNFcnJvcnMoYXN5bmMgKCkgPT4ge1xuICAgICAgICAgIGNvbnN0IHsgZW50aXR5SWQgfSA9IHJlcXVlc3QucXVlcnk7XG4gICAgICAgICAgY29uc3QgZW50aXR5ID0gRW50aXR5TWFuYWdlci5nZXQoZW50aXR5SWQpO1xuICAgICAgICAgIGNvbnN0IGNvbHVtbnMgPSBlbnRpdHkuZ2V0VGFibGVDb2x1bW5zKCk7XG4gICAgICAgICAgcmV0dXJuIHsgY29sdW1ucyB9O1xuICAgICAgICB9KSxcbiAgICAgICk7XG5cbiAgICAgIHNlcnZlci5wb3N0PHtcbiAgICAgICAgQm9keToge1xuICAgICAgICAgIGVudGl0eUlkczogc3RyaW5nW107XG4gICAgICAgICAgdGVtcGxhdGVLZXlzOiBzdHJpbmdbXTtcbiAgICAgICAgfTtcbiAgICAgIH0+KFwiL2FwaS9zY2FmZm9sZGluZy9nZXRTdGF0dXNcIiwgKHJlcXVlc3QpID0+XG4gICAgICAgIGZvcndhcmRBc3luY0Vycm9ycyhhc3luYyAoKSA9PiB7XG4gICAgICAgICAgY29uc3QgeyBlbnRpdHlJZHMsIHRlbXBsYXRlS2V5czogX3RlbXBsYXRlS2V5cyB9ID0gcmVxdWVzdC5ib2R5O1xuICAgICAgICAgIGlmICgoZW50aXR5SWRzID8/IFtdKS5sZW5ndGggPT09IDApIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBCYWRSZXF1ZXN0RXhjZXB0aW9uKFNEKFwic29uYW11LmVycm9yLmVudGl0eUlkc1JlcXVpcmVkXCIpKTtcbiAgICAgICAgICB9IGVsc2UgaWYgKChfdGVtcGxhdGVLZXlzID8/IFtdKS5sZW5ndGggPT09IDApIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBCYWRSZXF1ZXN0RXhjZXB0aW9uKFNEKFwic29uYW11LmVycm9yLnRlbXBsYXRlS2V5c1JlcXVpcmVkXCIpKTtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICAvLyBzb3J0aW5nXG4gICAgICAgICAgZW50aXR5SWRzLnNvcnQoKGEsIGIpID0+IChhIDwgYiA/IC0xIDogYSA+IGIgPyAxIDogMCkpO1xuICAgICAgICAgIGNvbnN0IHRlbXBsYXRlS2V5cyA9IFRlbXBsYXRlS2V5Lm9wdGlvbnMuZmlsdGVyKCh0aykgPT4gX3RlbXBsYXRlS2V5cy5pbmNsdWRlcyh0aykpO1xuXG4gICAgICAgICAgY29uc3QgY29tYmluYXRpb25zID0gZW50aXR5SWRzLmZsYXRNYXAoKGVudGl0eUlkKSA9PiB7XG4gICAgICAgICAgICByZXR1cm4gdGVtcGxhdGVLZXlzLm1hcCgodGVtcGxhdGVLZXkpID0+IFtlbnRpdHlJZCwgdGVtcGxhdGVLZXldKTtcbiAgICAgICAgICB9KTtcblxuICAgICAgICAgIGNvbnN0IHN0YXR1c2VzID0gYXdhaXQgUHJvbWlzZS5hbGwoXG4gICAgICAgICAgICBjb21iaW5hdGlvbnMubWFwKGFzeW5jIChbZW50aXR5SWQsIHRlbXBsYXRlS2V5XSkgPT4ge1xuICAgICAgICAgICAgICBjb25zdCB7IHN1YlBhdGgsIGZ1bGxQYXRoLCBpc0V4aXN0cyB9ID0gYXdhaXQgU29uYW11LnN5bmNlci5jaGVja0V4aXN0c0dlbkNvZGUoXG4gICAgICAgICAgICAgICAgZW50aXR5SWQsXG4gICAgICAgICAgICAgICAgLyogU0FGRVRZOiBVSSDrj4TqtazsnZggWm9kIOyeheugpSDsiqTtgqTrp4jqsIAg7J20IOqwkuydmCDtg4DsnoXsnYQg67O07J6l7ZWc64ukLiAqLyB0ZW1wbGF0ZUtleSBhcyBUZW1wbGF0ZUtleSxcbiAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgICAgICBlbnRpdHlJZCxcbiAgICAgICAgICAgICAgICB0ZW1wbGF0ZUtleSxcbiAgICAgICAgICAgICAgICBzdWJQYXRoLFxuICAgICAgICAgICAgICAgIGZ1bGxQYXRoLFxuICAgICAgICAgICAgICAgIGlzRXhpc3RzLFxuICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgfSksXG4gICAgICAgICAgKTtcbiAgICAgICAgICByZXR1cm4geyBzdGF0dXNlcyB9O1xuICAgICAgICB9KSxcbiAgICAgICk7XG5cbiAgICAgIHNlcnZlci5wb3N0PHtcbiAgICAgICAgQm9keToge1xuICAgICAgICAgIG9wdGlvbnM6IHtcbiAgICAgICAgICAgIGVudGl0eUlkOiBzdHJpbmc7XG4gICAgICAgICAgICB0ZW1wbGF0ZUtleTogc3RyaW5nO1xuICAgICAgICAgICAgZW51bUlkPzogc3RyaW5nO1xuICAgICAgICAgICAgb3ZlcndyaXRlPzogYm9vbGVhbjtcbiAgICAgICAgICB9W107XG4gICAgICAgIH07XG4gICAgICB9PihcIi9hcGkvc2NhZmZvbGRpbmcvZ2VuZXJhdGVcIiwgKHJlcXVlc3QpID0+XG4gICAgICAgIGZvcndhcmRBc3luY0Vycm9ycyhhc3luYyAoKSA9PiB7XG4gICAgICAgICAgY29uc3QgeyBvcHRpb25zIH0gPSByZXF1ZXN0LmJvZHk7XG4gICAgICAgICAgaWYgKG9wdGlvbnMubGVuZ3RoID09PSAwKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgQmFkUmVxdWVzdEV4Y2VwdGlvbihTRChcInNvbmFtdS5lcnJvci5vcHRpb25zUmVxdWlyZWRcIikpO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIC8vIDEuIOuqqOuToCDthZztlIzrpr/sl5DshJwg7ZWE7JqU7ZWcIGRpY3Qg7YKk66W8IOyImOynkVxuICAgICAgICAgIGNvbnN0IGtleXMgPSBvcHRpb25zLmZsYXRNYXAoKHsgdGVtcGxhdGVLZXkgfSkgPT4ge1xuICAgICAgICAgICAgY29uc3QgdGVtcGxhdGUgPSBUZW1wbGF0ZU1hbmFnZXIuZ2V0KHRlbXBsYXRlS2V5KTtcbiAgICAgICAgICAgIHJldHVybiB0ZW1wbGF0ZS5nZXRSZXF1aXJlZERpY3RLZXlzKCkgPz8gW107XG4gICAgICAgICAgfSk7XG5cbiAgICAgICAgICAvLyAyLiB0YXJnZXTrs4TroZwgZW5zdXJlRGljdEtleXMg7Zi47LacICjsiJzssKgg7LKY66asKVxuICAgICAgICAgIGF3YWl0IHNvbmFtdURpY3Rpb25hcnkuZW5zdXJlRGljdEtleXMoWy4uLm5ldyBTZXQoa2V5cyldKTtcblxuICAgICAgICAgIC8vIDMuIO2FnO2UjOumvyDsg53shLEgKOuzkeugrCDsspjrpqwpXG4gICAgICAgICAgY29uc3QgcmVzdWx0ID0gYXdhaXQgUHJvbWlzZS5hbGwoXG4gICAgICAgICAgICBvcHRpb25zLm1hcChhc3luYyAoeyBlbnRpdHlJZCwgdGVtcGxhdGVLZXksIGVudW1JZCwgb3ZlcndyaXRlIH0pID0+IHtcbiAgICAgICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgICAgICByZXR1cm4gYXdhaXQgU29uYW11LnN5bmNlci5nZW5lcmF0ZVRlbXBsYXRlKFxuICAgICAgICAgICAgICAgICAgLyogU0FGRVRZOiBVSSDrj4TqtazsnZggWm9kIOyeheugpSDsiqTtgqTrp4jqsIAg7J20IOqwkuydmCDtg4DsnoXsnYQg67O07J6l7ZWc64ukLiAqLyB0ZW1wbGF0ZUtleSBhcyBUZW1wbGF0ZUtleSxcbiAgICAgICAgICAgICAgICAgIC8qIFNBRkVUWTogVUkg64+E6rWs7J2YIFpvZCDsnoXroKUg7Iqk7YKk66eI6rCAIEVudGl0eSDthZztlIzrpr8g7Ji17IWY7J2EIOuztOyepe2VnOuLpC4gKi8ge1xuICAgICAgICAgICAgICAgICAgICBlbnRpdHlJZCxcbiAgICAgICAgICAgICAgICAgICAgZW51bUlkLFxuICAgICAgICAgICAgICAgICAgfSBhcyBFbnRpdHlUZW1wbGF0ZUlucHV0LFxuICAgICAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgICAgICBvdmVyd3JpdGUsXG4gICAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgICk7XG4gICAgICAgICAgICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgICAgICAgICBpZiAoaXNTb0V4Y2VwdGlvbihlKSAmJiBlLnN0YXR1c0NvZGUgPT09IDU0MSkge1xuICAgICAgICAgICAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgIGNvbnNvbGUuZXJyb3IoZSk7XG4gICAgICAgICAgICAgICAgICB0aHJvdyBlO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSksXG4gICAgICAgICAgKTtcblxuICAgICAgICAgIGlmIChyZXN1bHQuZmlsdGVyKG5vbk51bGxhYmxlKS5sZW5ndGggPT09IDApIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBTZXJ2aWNlVW5hdmFpbGFibGVFeGNlcHRpb24oU0QoXCJzb25hbXUuZXJyb3IuYWxsRmlsZXNHZW5lcmF0ZWRcIikpO1xuICAgICAgICAgIH1cbiAgICAgICAgICByZXR1cm4gcmVzdWx0O1xuICAgICAgICB9KSxcbiAgICAgICk7XG5cbiAgICAgIHNlcnZlci5wb3N0PHtcbiAgICAgICAgQm9keToge1xuICAgICAgICAgIG9wdGlvbjoge1xuICAgICAgICAgICAgZW50aXR5SWQ6IHN0cmluZztcbiAgICAgICAgICAgIHRlbXBsYXRlS2V5OiBzdHJpbmc7XG4gICAgICAgICAgICBlbnVtSWQ/OiBzdHJpbmc7XG4gICAgICAgICAgfTtcbiAgICAgICAgfTtcbiAgICAgIH0+KFxuICAgICAgICBcIi9hcGkvc2NhZmZvbGRpbmcvcHJldmlld1wiLFxuICAgICAgICAocmVxdWVzdCk6IFByb21pc2U8eyBwYXRoQW5kQ29kZXM6IFBhdGhBbmRDb2RlW10gfT4gPT5cbiAgICAgICAgICBmb3J3YXJkQXN5bmNFcnJvcnMoYXN5bmMgKCkgPT4ge1xuICAgICAgICAgICAgY29uc3QgeyBvcHRpb24gfSA9IHJlcXVlc3QuYm9keTtcblxuICAgICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgICAgY29uc3QgeyB0ZW1wbGF0ZUtleSwgLi4udGVtcGxhdGVPcHRpb25zIH0gPSBvcHRpb247XG4gICAgICAgICAgICAgIGNvbnN0IHBhdGhBbmRDb2RlcyA9IGF3YWl0IFNvbmFtdS5zeW5jZXIucmVuZGVyVGVtcGxhdGUoXG4gICAgICAgICAgICAgICAgLyogU0FGRVRZOiBVSSDrj4TqtazsnZggWm9kIOyeheugpSDsiqTtgqTrp4jqsIAg7J20IOqwkuydmCDtg4DsnoXsnYQg67O07J6l7ZWc64ukLiAqLyB0ZW1wbGF0ZUtleSBhcyBUZW1wbGF0ZUtleSxcbiAgICAgICAgICAgICAgICB0ZW1wbGF0ZU9wdGlvbnMsXG4gICAgICAgICAgICAgICk7XG5cbiAgICAgICAgICAgICAgcmV0dXJuIHsgcGF0aEFuZENvZGVzIH07XG4gICAgICAgICAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgICAgICAgIGNvbnNvbGUuZXJyb3IoZSk7XG4gICAgICAgICAgICAgIHRocm93IGU7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfSksXG4gICAgICApO1xuXG4gICAgICBzZXJ2ZXIucG9zdChcIi9hcGkvZml4dHVyZVwiLCAocmVxdWVzdCkgPT5cbiAgICAgICAgZm9yd2FyZEFzeW5jRXJyb3JzKGFzeW5jICgpID0+IHtcbiAgICAgICAgICBjb25zdCB7IHNvdXJjZURCLCB0YXJnZXREQiwgc2VhcmNoLCBkdXBsaWNhdGVDaGVjayB9ID1cbiAgICAgICAgICAgIC8qIFNBRkVUWTogVUkg64+E6rWs7J2YIFpvZCDsnoXroKUg7Iqk7YKk66eI6rCAIOydtCDqsJLsnZgg7YOA7J6F7J2EIOuztOyepe2VnOuLpC4gKi8gcmVxdWVzdC5ib2R5IGFzIHtcbiAgICAgICAgICAgICAgc291cmNlREI6IGtleW9mIFNvbmFtdURCQ29uZmlnO1xuICAgICAgICAgICAgICB0YXJnZXREQjoga2V5b2YgU29uYW11REJDb25maWc7XG4gICAgICAgICAgICAgIHNlYXJjaDogRml4dHVyZVNlYXJjaE9wdGlvbnM7XG4gICAgICAgICAgICAgIGR1cGxpY2F0ZUNoZWNrPzogRHVwbGljYXRlQ2hlY2tPcHRpb25zO1xuICAgICAgICAgICAgfTtcblxuICAgICAgICAgIHJldHVybiBGaXh0dXJlTWFuYWdlci5nZXRGaXh0dXJlcyhzb3VyY2VEQiwgdGFyZ2V0REIsIHNlYXJjaCwgZHVwbGljYXRlQ2hlY2spO1xuICAgICAgICB9KSxcbiAgICAgICk7XG5cbiAgICAgIHNlcnZlci5wb3N0KFwiL2FwaS9maXh0dXJlL2ltcG9ydFwiLCAocmVxdWVzdCkgPT5cbiAgICAgICAgZm9yd2FyZEFzeW5jRXJyb3JzKGFzeW5jICgpID0+IHtcbiAgICAgICAgICBjb25zdCB7IGRiLCBmaXh0dXJlcyB9ID1cbiAgICAgICAgICAgIC8qIFNBRkVUWTogVUkg64+E6rWs7J2YIFpvZCDsnoXroKUg7Iqk7YKk66eI6rCAIOydtCDqsJLsnZgg7YOA7J6F7J2EIOuztOyepe2VnOuLpC4gKi8gcmVxdWVzdC5ib2R5IGFzIHtcbiAgICAgICAgICAgICAgZGI6IGtleW9mIFNvbmFtdURCQ29uZmlnO1xuICAgICAgICAgICAgICBmaXh0dXJlczogRml4dHVyZVJlY29yZFtdO1xuICAgICAgICAgICAgfTtcblxuICAgICAgICAgIHJldHVybiBGaXh0dXJlTWFuYWdlci5pbnNlcnRGaXh0dXJlcyhkYiwgZml4dHVyZXMpO1xuICAgICAgICB9KSxcbiAgICAgICk7XG5cbiAgICAgIHNlcnZlci5wb3N0KFwiL2FwaS9maXh0dXJlL2FkZEZpeHR1cmVMb2FkZXJcIiwgKHJlcXVlc3QpID0+XG4gICAgICAgIGZvcndhcmRBc3luY0Vycm9ycyhhc3luYyAoKSA9PiB7XG4gICAgICAgICAgY29uc3QgeyBjb2RlIH0gPVxuICAgICAgICAgICAgLyogU0FGRVRZOiBVSSDrj4TqtazsnZggWm9kIOyeheugpSDsiqTtgqTrp4jqsIAg7J20IOqwkuydmCDtg4DsnoXsnYQg67O07J6l7ZWc64ukLiAqLyByZXF1ZXN0LmJvZHkgYXMge1xuICAgICAgICAgICAgICBjb2RlOiBzdHJpbmc7XG4gICAgICAgICAgICB9O1xuXG4gICAgICAgICAgcmV0dXJuIEZpeHR1cmVNYW5hZ2VyLmFkZEZpeHR1cmVMb2FkZXIoY29kZSk7XG4gICAgICAgIH0pLFxuICAgICAgKTtcblxuICAgICAgc2VydmVyLmdldChcIi9hcGkvaTE4bi9kaWN0aW9uYXJ5XCIsIGFzeW5jICgpID0+IHtcbiAgICAgICAgcmV0dXJuIHNvbmFtdURpY3Rpb25hcnkuZ2V0RGljdGlvbmFyeSgpO1xuICAgICAgfSk7XG5cbiAgICAgIHNlcnZlci5nZXQoXCIvYXBpL2kxOG4vZXhwb3J0XCIsIGFzeW5jIChfcmVxdWVzdCwgcmVwbHkpID0+IHtcbiAgICAgICAgY29uc3QgeyBmaWxlbmFtZSwgYnVmZmVyIH0gPSBhd2FpdCBzb25hbXVEaWN0aW9uYXJ5LmV4cG9ydFRvRXhjZWwoKTtcbiAgICAgICAgcmVwbHlcbiAgICAgICAgICAuaGVhZGVyKFxuICAgICAgICAgICAgXCJDb250ZW50LVR5cGVcIixcbiAgICAgICAgICAgIFwiYXBwbGljYXRpb24vdm5kLm9wZW54bWxmb3JtYXRzLW9mZmljZWRvY3VtZW50LnNwcmVhZHNoZWV0bWwuc2hlZXRcIixcbiAgICAgICAgICApXG4gICAgICAgICAgLmhlYWRlcihcIkNvbnRlbnQtRGlzcG9zaXRpb25cIiwgYGF0dGFjaG1lbnQ7IGZpbGVuYW1lPVwiJHtmaWxlbmFtZX1cImApXG4gICAgICAgICAgLnNlbmQoYnVmZmVyKTtcbiAgICAgIH0pO1xuXG4gICAgICBzZXJ2ZXIucG9zdChcIi9hcGkvaTE4bi9pbXBvcnRcIiwgKHJlcXVlc3QpID0+XG4gICAgICAgIGZvcndhcmRBc3luY0Vycm9ycyhhc3luYyAoKSA9PiB7XG4gICAgICAgICAgY29uc3QgZGF0YSA9IGF3YWl0IHJlcXVlc3QuZmlsZSgpO1xuICAgICAgICAgIGlmICghZGF0YSkge1xuICAgICAgICAgICAgdGhyb3cgbmV3IEJhZFJlcXVlc3RFeGNlcHRpb24oU0QoXCJzb25hbXUuZXJyb3IuZmlsZU5vdFVwbG9hZGVkXCIpKTtcbiAgICAgICAgICB9XG4gICAgICAgICAgY29uc3QgYnVmZmVyID0gYXdhaXQgZGF0YS50b0J1ZmZlcigpO1xuICAgICAgICAgIHJldHVybiBzb25hbXVEaWN0aW9uYXJ5LmltcG9ydEZyb21FeGNlbChidWZmZXIpO1xuICAgICAgICB9KSxcbiAgICAgICk7XG5cbiAgICAgIHNlcnZlci5wb3N0PHtcbiAgICAgICAgQm9keToge1xuICAgICAgICAgIG9sZEtleTogc3RyaW5nO1xuICAgICAgICAgIG5ld0tleTogc3RyaW5nO1xuICAgICAgICAgIHNvdXJjZTogXCJlbnRpdHlcIiB8IFwicHJvamVjdFwiIHwgXCJzb25hbXVcIjtcbiAgICAgICAgICB2YWx1ZXM6IFJlY29yZDxzdHJpbmcsIHN0cmluZz47XG4gICAgICAgIH07XG4gICAgICB9PihcIi9hcGkvaTE4bi91cGRhdGVcIiwgKHJlcXVlc3QpID0+XG4gICAgICAgIGZvcndhcmRBc3luY0Vycm9ycyhhc3luYyAoKSA9PiB7XG4gICAgICAgICAgYXdhaXQgc29uYW11RGljdGlvbmFyeS51cGRhdGVFbnRyeShyZXF1ZXN0LmJvZHkpO1xuICAgICAgICAgIHJldHVybiB7IHN1Y2Nlc3M6IHRydWUgfTtcbiAgICAgICAgfSksXG4gICAgICApO1xuXG4gICAgICBzZXJ2ZXIucG9zdDx7XG4gICAgICAgIEJvZHk6IHtcbiAgICAgICAgICBrZXk6IHN0cmluZztcbiAgICAgICAgICB2YWx1ZXM6IFJlY29yZDxzdHJpbmcsIHN0cmluZz47XG4gICAgICAgIH07XG4gICAgICB9PihcIi9hcGkvaTE4bi9jcmVhdGVcIiwgKHJlcXVlc3QpID0+XG4gICAgICAgIGZvcndhcmRBc3luY0Vycm9ycyhhc3luYyAoKSA9PiB7XG4gICAgICAgICAgYXdhaXQgc29uYW11RGljdGlvbmFyeS5jcmVhdGVFbnRyeShyZXF1ZXN0LmJvZHkpO1xuICAgICAgICAgIHJldHVybiB7IHN1Y2Nlc3M6IHRydWUgfTtcbiAgICAgICAgfSksXG4gICAgICApO1xuXG4gICAgICBzZXJ2ZXIucG9zdDx7XG4gICAgICAgIEJvZHk6IHtcbiAgICAgICAgICBrZXk6IHN0cmluZztcbiAgICAgICAgfTtcbiAgICAgIH0+KFwiL2FwaS9pMThuL2RlbGV0ZVwiLCAocmVxdWVzdCkgPT5cbiAgICAgICAgZm9yd2FyZEFzeW5jRXJyb3JzKGFzeW5jICgpID0+IHtcbiAgICAgICAgICBhd2FpdCBzb25hbXVEaWN0aW9uYXJ5LmRlbGV0ZUVudHJ5KHJlcXVlc3QuYm9keS5rZXkpO1xuICAgICAgICAgIHJldHVybiB7IHN1Y2Nlc3M6IHRydWUgfTtcbiAgICAgICAgfSksXG4gICAgICApO1xuXG4gICAgICBzZXJ2ZXIucG9zdDx7IEJvZHk6IHsga2V5czogc3RyaW5nW10gfSB9PihcIi9hcGkvaTE4bi9jaGVja1VzYWdlXCIsIChyZXF1ZXN0KSA9PlxuICAgICAgICBmb3J3YXJkQXN5bmNFcnJvcnMoYXN5bmMgKCkgPT4ge1xuICAgICAgICAgIHJldHVybiBzb25hbXVEaWN0aW9uYXJ5LmNoZWNrVXNhZ2UocmVxdWVzdC5ib2R5LmtleXMpO1xuICAgICAgICB9KSxcbiAgICAgICk7XG5cbiAgICAgIC8vIFRhc2tzIEFQSVxuICAgICAgc2VydmVyLmdldChcIi9hcGkvdGFza3Mvc3RhdHVzXCIsIGFzeW5jICgpID0+IHtcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICBTb25hbXUud29ya2Zsb3dzO1xuICAgICAgICAgIHJldHVybiB7IGFjdGl2ZTogdHJ1ZSB9O1xuICAgICAgICB9IGNhdGNoIHtcbiAgICAgICAgICByZXR1cm4geyBhY3RpdmU6IGZhbHNlIH07XG4gICAgICAgIH1cbiAgICAgIH0pO1xuXG4gICAgICBzZXJ2ZXIuZ2V0KFwiL2FwaS90YXNrcy93b3JrZmxvd0RlZmluaXRpb25zXCIsIGFzeW5jICgpID0+IHtcbiAgICAgICAgY29uc3QgZGVmaW5pdGlvbnMgPSBTb25hbXUud29ya2Zsb3dzLndvcmtmbG93RGVmaW5pdGlvbnM7XG4gICAgICAgIHJldHVybiB7IGRlZmluaXRpb25zIH07XG4gICAgICB9KTtcblxuICAgICAgc2VydmVyLmdldDx7XG4gICAgICAgIFF1ZXJ5c3RyaW5nOiB7XG4gICAgICAgICAgbGltaXQ/OiBzdHJpbmc7XG4gICAgICAgICAgYWZ0ZXI/OiBzdHJpbmc7XG4gICAgICAgICAgYmVmb3JlPzogc3RyaW5nO1xuICAgICAgICAgIG9yZGVyPzogXCJhc2NcIiB8IFwiZGVzY1wiO1xuICAgICAgICAgIHN0YXR1cz86IHN0cmluZztcbiAgICAgICAgICB3b3JrZmxvd05hbWU/OiBzdHJpbmc7XG4gICAgICAgICAgY3JlYXRlZEFmdGVyPzogc3RyaW5nO1xuICAgICAgICAgIGNyZWF0ZWRCZWZvcmU/OiBzdHJpbmc7XG4gICAgICAgIH07XG4gICAgICB9PihcIi9hcGkvdGFza3Mvd29ya2Zsb3dSdW5zXCIsIChyZXF1ZXN0KSA9PlxuICAgICAgICBmb3J3YXJkQXN5bmNFcnJvcnMoYXN5bmMgKCkgPT4ge1xuICAgICAgICAgIGNvbnN0IGJhY2tlbmQgPSBTb25hbXUud29ya2Zsb3dzLmJhY2tlbmQ7XG4gICAgICAgICAgY29uc3QgeyBsaW1pdCwgYWZ0ZXIsIGJlZm9yZSwgb3JkZXIsIHN0YXR1cywgd29ya2Zsb3dOYW1lLCBjcmVhdGVkQWZ0ZXIsIGNyZWF0ZWRCZWZvcmUgfSA9XG4gICAgICAgICAgICByZXF1ZXN0LnF1ZXJ5O1xuICAgICAgICAgIHJldHVybiBiYWNrZW5kLmxpc3RXb3JrZmxvd1J1bnMoe1xuICAgICAgICAgICAgbGltaXQ6IGxpbWl0ID8gTnVtYmVyLnBhcnNlSW50KGxpbWl0LCAxMCkgOiB1bmRlZmluZWQsXG4gICAgICAgICAgICBhZnRlcixcbiAgICAgICAgICAgIGJlZm9yZSxcbiAgICAgICAgICAgIG9yZGVyLFxuICAgICAgICAgICAgc3RhdHVzOiBzdGF0dXMgPyBzdGF0dXMuc3BsaXQoXCIsXCIpIDogdW5kZWZpbmVkLFxuICAgICAgICAgICAgd29ya2Zsb3dOYW1lOiB3b3JrZmxvd05hbWUgfHwgdW5kZWZpbmVkLFxuICAgICAgICAgICAgY3JlYXRlZEFmdGVyOiBjcmVhdGVkQWZ0ZXIgPyBuZXcgRGF0ZShjcmVhdGVkQWZ0ZXIpIDogdW5kZWZpbmVkLFxuICAgICAgICAgICAgY3JlYXRlZEJlZm9yZTogY3JlYXRlZEJlZm9yZSA/IG5ldyBEYXRlKGNyZWF0ZWRCZWZvcmUpIDogdW5kZWZpbmVkLFxuICAgICAgICAgIH0pO1xuICAgICAgICB9KSxcbiAgICAgICk7XG5cbiAgICAgIHNlcnZlci5nZXQ8e1xuICAgICAgICBQYXJhbXM6IHsgaWQ6IHN0cmluZyB9O1xuICAgICAgfT4oXCIvYXBpL3Rhc2tzL3dvcmtmbG93UnVucy86aWRcIiwgKHJlcXVlc3QpID0+XG4gICAgICAgIGZvcndhcmRBc3luY0Vycm9ycyhhc3luYyAoKSA9PiB7XG4gICAgICAgICAgY29uc3QgYmFja2VuZCA9IFNvbmFtdS53b3JrZmxvd3MuYmFja2VuZDtcbiAgICAgICAgICBjb25zdCB3b3JrZmxvd1J1biA9IGF3YWl0IGJhY2tlbmQuZ2V0V29ya2Zsb3dSdW4oe1xuICAgICAgICAgICAgd29ya2Zsb3dSdW5JZDogcmVxdWVzdC5wYXJhbXMuaWQsXG4gICAgICAgICAgfSk7XG4gICAgICAgICAgaWYgKCF3b3JrZmxvd1J1bikge1xuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBXb3JrZmxvdyBydW4gbm90IGZvdW5kOiAke3JlcXVlc3QucGFyYW1zLmlkfWApO1xuICAgICAgICAgIH1cbiAgICAgICAgICByZXR1cm4gd29ya2Zsb3dSdW47XG4gICAgICAgIH0pLFxuICAgICAgKTtcblxuICAgICAgc2VydmVyLnBvc3Q8e1xuICAgICAgICBQYXJhbXM6IHsgaWQ6IHN0cmluZyB9O1xuICAgICAgfT4oXCIvYXBpL3Rhc2tzL3dvcmtmbG93UnVucy86aWQvY2FuY2VsXCIsIChyZXF1ZXN0KSA9PlxuICAgICAgICBmb3J3YXJkQXN5bmNFcnJvcnMoYXN5bmMgKCkgPT4ge1xuICAgICAgICAgIGNvbnN0IGJhY2tlbmQgPSBTb25hbXUud29ya2Zsb3dzLmJhY2tlbmQ7XG4gICAgICAgICAgcmV0dXJuIGJhY2tlbmQuY2FuY2VsV29ya2Zsb3dSdW4oe1xuICAgICAgICAgICAgd29ya2Zsb3dSdW5JZDogcmVxdWVzdC5wYXJhbXMuaWQsXG4gICAgICAgICAgfSk7XG4gICAgICAgIH0pLFxuICAgICAgKTtcblxuICAgICAgc2VydmVyLnBvc3Q8e1xuICAgICAgICBQYXJhbXM6IHsgaWQ6IHN0cmluZyB9O1xuICAgICAgfT4oXCIvYXBpL3Rhc2tzL3dvcmtmbG93UnVucy86aWQvcGF1c2VcIiwgKHJlcXVlc3QpID0+XG4gICAgICAgIGZvcndhcmRBc3luY0Vycm9ycyhhc3luYyAoKSA9PiB7XG4gICAgICAgICAgY29uc3QgYmFja2VuZCA9IFNvbmFtdS53b3JrZmxvd3MuYmFja2VuZDtcbiAgICAgICAgICByZXR1cm4gYmFja2VuZC5wYXVzZVdvcmtmbG93UnVuKHtcbiAgICAgICAgICAgIHdvcmtmbG93UnVuSWQ6IHJlcXVlc3QucGFyYW1zLmlkLFxuICAgICAgICAgIH0pO1xuICAgICAgICB9KSxcbiAgICAgICk7XG5cbiAgICAgIHNlcnZlci5wb3N0PHtcbiAgICAgICAgUGFyYW1zOiB7IGlkOiBzdHJpbmcgfTtcbiAgICAgIH0+KFwiL2FwaS90YXNrcy93b3JrZmxvd1J1bnMvOmlkL3Jlc3VtZVwiLCAocmVxdWVzdCkgPT5cbiAgICAgICAgZm9yd2FyZEFzeW5jRXJyb3JzKGFzeW5jICgpID0+IHtcbiAgICAgICAgICBjb25zdCBiYWNrZW5kID0gU29uYW11LndvcmtmbG93cy5iYWNrZW5kO1xuICAgICAgICAgIHJldHVybiBiYWNrZW5kLnJlc3VtZVdvcmtmbG93UnVuKHtcbiAgICAgICAgICAgIHdvcmtmbG93UnVuSWQ6IHJlcXVlc3QucGFyYW1zLmlkLFxuICAgICAgICAgIH0pO1xuICAgICAgICB9KSxcbiAgICAgICk7XG5cbiAgICAgIHNlcnZlci5nZXQ8e1xuICAgICAgICBQYXJhbXM6IHsgaWQ6IHN0cmluZyB9O1xuICAgICAgICBRdWVyeXN0cmluZzoge1xuICAgICAgICAgIGxpbWl0Pzogc3RyaW5nO1xuICAgICAgICAgIGFmdGVyPzogc3RyaW5nO1xuICAgICAgICAgIGJlZm9yZT86IHN0cmluZztcbiAgICAgICAgfTtcbiAgICAgIH0+KFwiL2FwaS90YXNrcy93b3JrZmxvd1J1bnMvOmlkL3N0ZXBzXCIsIChyZXF1ZXN0KSA9PlxuICAgICAgICBmb3J3YXJkQXN5bmNFcnJvcnMoYXN5bmMgKCkgPT4ge1xuICAgICAgICAgIGNvbnN0IGJhY2tlbmQgPSBTb25hbXUud29ya2Zsb3dzLmJhY2tlbmQ7XG4gICAgICAgICAgY29uc3QgeyBsaW1pdCwgYWZ0ZXIsIGJlZm9yZSB9ID0gcmVxdWVzdC5xdWVyeTtcbiAgICAgICAgICByZXR1cm4gYmFja2VuZC5saXN0U3RlcEF0dGVtcHRzKHtcbiAgICAgICAgICAgIHdvcmtmbG93UnVuSWQ6IHJlcXVlc3QucGFyYW1zLmlkLFxuICAgICAgICAgICAgbGltaXQ6IGxpbWl0ID8gTnVtYmVyLnBhcnNlSW50KGxpbWl0LCAxMCkgOiB1bmRlZmluZWQsXG4gICAgICAgICAgICBhZnRlcixcbiAgICAgICAgICAgIGJlZm9yZSxcbiAgICAgICAgICB9KTtcbiAgICAgICAgfSksXG4gICAgICApO1xuXG4gICAgICAvKipcbiAgICAgICAqIEhlYWx0aCBDaGVjayBBUElcbiAgICAgICAqIE1DUCDrj4TqtazqsIAgU29uYW11IOyEnOuyhOulvCDsnpDrj5kg6rCQ7KeA7ZWY6riwIOychO2VnCDsl5Trk5ztj6zsnbjtirhcbiAgICAgICAqL1xuICAgICAgc2VydmVyLmdldChcIi9hcGkvc29uYW11L2hlYWx0aFwiLCAocmVxdWVzdCkgPT5cbiAgICAgICAgZm9yd2FyZEFzeW5jRXJyb3JzKGFzeW5jICgpID0+IHtcbiAgICAgICAgICBjb25zdCBhZGRyZXNzID0gcmVxdWVzdC5zZXJ2ZXIuc2VydmVyLmFkZHJlc3MoKTtcbiAgICAgICAgICBjb25zdCBwb3J0ID0gYWRkcmVzcyAmJiBpc09iamVjdFZhbHVlKGFkZHJlc3MpID8gYWRkcmVzcy5wb3J0IDogMDtcblxuICAgICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICBvazogdHJ1ZSxcbiAgICAgICAgICAgIHByb2plY3Q6IHByb2Nlc3MuY3dkKCkuc3BsaXQoXCIvXCIpLnBvcCgpIHx8IFwidW5rbm93blwiLFxuICAgICAgICAgICAgcG9ydCxcbiAgICAgICAgICAgIHRpbWVzdGFtcDogbmV3IERhdGUoKS50b0lTT1N0cmluZygpLFxuICAgICAgICAgIH07XG4gICAgICAgIH0pLFxuICAgICAgKTtcblxuICAgICAgLyoqXG4gICAgICAgKiBGaXh0dXJlIOyDneyEsSBBUElcbiAgICAgICAqL1xuICAgICAgc2VydmVyLnBvc3Q8e1xuICAgICAgICBCb2R5OiB7XG4gICAgICAgICAgZW50aXR5OiBzdHJpbmc7XG4gICAgICAgICAgY291bnQ/OiBudW1iZXI7XG4gICAgICAgICAgb3ZlcnJpZGVzPzogRml4dHVyZUdlbmVyYXRpb25TcGVjW1wib3ZlcnJpZGVzXCJdO1xuICAgICAgICAgIHRhcmdldERiPzogXCJmaXh0dXJlXCIgfCBcInRlc3RcIjtcbiAgICAgICAgfTtcbiAgICAgIH0+KFwiL2FwaS9zb25hbXUvZml4dHVyZS9nZW5lcmF0ZVwiLCBhc3luYyAocmVxdWVzdCwgcmVwbHkpID0+IHtcbiAgICAgICAgY29uc3QgeyBlbnRpdHksIGNvdW50ID0gMSwgb3ZlcnJpZGVzLCB0YXJnZXREYiA9IFwiZml4dHVyZVwiIH0gPSByZXF1ZXN0LmJvZHk7XG5cbiAgICAgICAgLy8g7YOA6rKfIERCIOyEpOyglSDqsIDsoLjsmKTquLBcbiAgICAgICAgY29uc3QgZGJDb25maWcgPSB0YXJnZXREYiA9PT0gXCJmaXh0dXJlXCIgPyBTb25hbXUuZGJDb25maWcuZml4dHVyZSA6IFNvbmFtdS5kYkNvbmZpZy50ZXN0O1xuXG4gICAgICAgIC8vIEtuZXgg7J247Iqk7YS07IqkIOyDneyEsVxuICAgICAgICBjb25zdCBkYiA9IGNyZWF0ZUtuZXhJbnN0YW5jZShkYkNvbmZpZyk7XG5cbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICAvLyBGaXh0dXJlR2VuZXJhdG9yIOyDneyEsVxuICAgICAgICAgIGNvbnN0IGdlbmVyYXRvciA9IG5ldyBGaXh0dXJlR2VuZXJhdG9yKGRiLCBkYiwgdGFyZ2V0RGIsIEVudGl0eU1hbmFnZXIpO1xuXG4gICAgICAgICAgLy8g64uo7J28IEVudGl0eSDrsLDsuZgg7IOd7ISxXG4gICAgICAgICAgY29uc3QgZml4dHVyZXMgPSBhd2FpdCBnZW5lcmF0b3IuZ2VuZXJhdGVCYXRjaChbXG4gICAgICAgICAgICB7XG4gICAgICAgICAgICAgIGVudGl0eSxcbiAgICAgICAgICAgICAgY291bnQsXG4gICAgICAgICAgICAgIG92ZXJyaWRlczogb3ZlcnJpZGVzID8/IHt9LFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICBdKTtcblxuICAgICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICBzdWNjZXNzOiB0cnVlLFxuICAgICAgICAgICAgZW50aXR5LFxuICAgICAgICAgICAgY291bnQ6IGZpeHR1cmVzLmxlbmd0aCxcbiAgICAgICAgICAgIGZpeHR1cmVzLFxuICAgICAgICAgICAgdGFyZ2V0RGIsXG4gICAgICAgICAgfTtcbiAgICAgICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgICAgICByZXBseS5zdGF0dXMoNDAwKTtcbiAgICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgc3VjY2VzczogZmFsc2UsXG4gICAgICAgICAgICBlcnJvcjogZXJyb3IgaW5zdGFuY2VvZiBFcnJvciA/IGVycm9yLm1lc3NhZ2UgOiBTdHJpbmcoZXJyb3IpLFxuICAgICAgICAgIH07XG4gICAgICAgIH0gZmluYWxseSB7XG4gICAgICAgICAgYXdhaXQgZGIuZGVzdHJveSgpO1xuICAgICAgICB9XG4gICAgICB9KTtcblxuICAgICAgLyoqXG4gICAgICAgKiBGaXh0dXJlIOuNsOydtO2EsCDtg5Dsg4kgQVBJXG4gICAgICAgKi9cbiAgICAgIHNlcnZlci5wb3N0PHtcbiAgICAgICAgQm9keToge1xuICAgICAgICAgIGVudGl0eTogc3RyaW5nO1xuICAgICAgICAgIHN0cmF0ZWd5OiBcInNhbXBsZVwiIHwgXCJyZWNlbnRcIiB8IFwicmFuZG9tXCIgfCBcInF1ZXJ5XCI7XG4gICAgICAgICAgbGltaXQ/OiBudW1iZXI7XG4gICAgICAgICAgd2hlcmU/OiBEYXRhRXhwbG9yZXJPcHRpb25zW1wid2hlcmVcIl07XG4gICAgICAgIH07XG4gICAgICB9PihcIi9hcGkvc29uYW11L2ZpeHR1cmUvZXhwbG9yZVwiLCBhc3luYyAocmVxdWVzdCwgcmVwbHkpID0+IHtcbiAgICAgICAgY29uc3QgeyBlbnRpdHksIHN0cmF0ZWd5LCBsaW1pdCA9IDEwLCB3aGVyZSB9ID0gcmVxdWVzdC5ib2R5O1xuXG4gICAgICAgIC8vIEZpeHR1cmUgREIg7ISk7KCVIOqwgOyguOyYpOq4sFxuICAgICAgICBjb25zdCBmaXh0dXJlRGJDb25maWcgPSBTb25hbXUuZGJDb25maWcuZml4dHVyZTtcblxuICAgICAgICAvLyBLbmV4IOyduOyKpO2EtOyKpCDsg53shLFcbiAgICAgICAgY29uc3QgZml4dHVyZURiID0gY3JlYXRlS25leEluc3RhbmNlKGZpeHR1cmVEYkNvbmZpZyk7XG5cbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICAvLyBEYXRhRXhwbG9yZXIg7IOd7ISxXG4gICAgICAgICAgY29uc3QgZXhwbG9yZXIgPSBuZXcgRGF0YUV4cGxvcmVyKGZpeHR1cmVEYiwgRW50aXR5TWFuYWdlcik7XG5cbiAgICAgICAgICBjb25zdCBkYXRhID0gYXdhaXQgZXhwbG9yZXIuZXhwbG9yZShlbnRpdHksIHtcbiAgICAgICAgICAgIHN0cmF0ZWd5LFxuICAgICAgICAgICAgbGltaXQsXG4gICAgICAgICAgICB3aGVyZSxcbiAgICAgICAgICB9KTtcblxuICAgICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICBzdWNjZXNzOiB0cnVlLFxuICAgICAgICAgICAgZW50aXR5LFxuICAgICAgICAgICAgc3RyYXRlZ3ksXG4gICAgICAgICAgICBjb3VudDogZGF0YS5sZW5ndGgsXG4gICAgICAgICAgICBkYXRhLFxuICAgICAgICAgIH07XG4gICAgICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICAgICAgcmVwbHkuc3RhdHVzKDQwMCk7XG4gICAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIHN1Y2Nlc3M6IGZhbHNlLFxuICAgICAgICAgICAgZXJyb3I6IGVycm9yIGluc3RhbmNlb2YgRXJyb3IgPyBlcnJvci5tZXNzYWdlIDogU3RyaW5nKGVycm9yKSxcbiAgICAgICAgICB9O1xuICAgICAgICB9IGZpbmFsbHkge1xuICAgICAgICAgIGF3YWl0IGZpeHR1cmVEYi5kZXN0cm95KCk7XG4gICAgICAgIH1cbiAgICAgIH0pO1xuXG4gICAgICAvKipcbiAgICAgICAqIEZpeHR1cmUg642w7J207YSwIOqwgOyguOyYpOq4sCAoZmV0Y2gpIEFQSVxuICAgICAgICogcHJvZHVjdGlvbi9kZXZlbG9wbWVudCBEQuyXkOyEnCDsi6TsoJwg642w7J207YSw66W8IGZpeHR1cmUgRELroZwgaW1wb3J0XG4gICAgICAgKi9cbiAgICAgIHNlcnZlci5wb3N0PHtcbiAgICAgICAgQm9keToge1xuICAgICAgICAgIGVudGl0eTogc3RyaW5nO1xuICAgICAgICAgIHN0cmF0ZWd5PzogXCJzYW1wbGVcIiB8IFwicmVjZW50XCIgfCBcInJhbmRvbVwiIHwgXCJxdWVyeVwiO1xuICAgICAgICAgIGxpbWl0PzogbnVtYmVyO1xuICAgICAgICAgIGluY2x1ZGVSZWxhdGlvbnM/OiBib29sZWFuO1xuICAgICAgICAgIG1heERlcHRoPzogbnVtYmVyO1xuICAgICAgICB9O1xuICAgICAgfT4oXCIvYXBpL3NvbmFtdS9maXh0dXJlL2ZldGNoXCIsIGFzeW5jIChyZXF1ZXN0LCByZXBseSkgPT4ge1xuICAgICAgICBjb25zdCB7XG4gICAgICAgICAgZW50aXR5LFxuICAgICAgICAgIHN0cmF0ZWd5ID0gXCJyZWNlbnRcIixcbiAgICAgICAgICBsaW1pdCA9IDEwLFxuICAgICAgICAgIGluY2x1ZGVSZWxhdGlvbnMgPSB0cnVlLFxuICAgICAgICAgIG1heERlcHRoID0gMixcbiAgICAgICAgfSA9IHJlcXVlc3QuYm9keTtcblxuICAgICAgICAvLyBTb3VyY2UgREIgKHByb2R1Y3Rpb24vZGV2ZWxvcG1lbnQpIC0g7J296riwIOyghOyaqVxuICAgICAgICBjb25zdCBzb3VyY2VEYiA9IERCLmdldERCKFwiclwiKTtcblxuICAgICAgICAvLyBUYXJnZXQgREIgKGZpeHR1cmUpXG4gICAgICAgIGNvbnN0IGZpeHR1cmVEYiA9IGNyZWF0ZUtuZXhJbnN0YW5jZShTb25hbXUuZGJDb25maWcuZml4dHVyZSk7XG5cbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICAvLyBGaXh0dXJlR2VuZXJhdG9yIOyDneyEsVxuICAgICAgICAgIGNvbnN0IGdlbmVyYXRvciA9IG5ldyBGaXh0dXJlR2VuZXJhdG9yKHNvdXJjZURiLCBmaXh0dXJlRGIsIFwiZml4dHVyZVwiLCBFbnRpdHlNYW5hZ2VyKTtcblxuICAgICAgICAgIC8vIHByb2R1Y3Rpb24g642w7J207YSw66W8IGZpeHR1cmUgRELroZwgaW1wb3J0XG4gICAgICAgICAgY29uc3QgcmVzdWx0cyA9IGF3YWl0IGdlbmVyYXRvci5pbXBvcnRGcm9tU291cmNlKGVudGl0eSwge1xuICAgICAgICAgICAgc3RyYXRlZ3ksXG4gICAgICAgICAgICBsaW1pdCxcbiAgICAgICAgICAgIGluY2x1ZGVSZWxhdGlvbnMsXG4gICAgICAgICAgICBtYXhEZXB0aCxcbiAgICAgICAgICB9KTtcblxuICAgICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICBzdWNjZXNzOiB0cnVlLFxuICAgICAgICAgICAgZW50aXR5LFxuICAgICAgICAgICAgc3RyYXRlZ3ksXG4gICAgICAgICAgICBjb3VudDogcmVzdWx0cy5sZW5ndGgsXG4gICAgICAgICAgICBpbXBvcnRlZDogcmVzdWx0cyxcbiAgICAgICAgICB9O1xuICAgICAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgICAgIHJlcGx5LnN0YXR1cyg0MDApO1xuICAgICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICBzdWNjZXNzOiBmYWxzZSxcbiAgICAgICAgICAgIGVycm9yOiBlcnJvciBpbnN0YW5jZW9mIEVycm9yID8gZXJyb3IubWVzc2FnZSA6IFN0cmluZyhlcnJvciksXG4gICAgICAgICAgfTtcbiAgICAgICAgfSBmaW5hbGx5IHtcbiAgICAgICAgICAvLyBzb3VyY2VEYuuKlCBTb25hbXXqsIAg6rSA66as7ZWY66+A66GcIGRlc3Ryb3ntlZjsp4Ag7JWK7J2MXG4gICAgICAgICAgYXdhaXQgZml4dHVyZURiLmRlc3Ryb3koKTtcbiAgICAgICAgfVxuICAgICAgfSk7XG5cbiAgICAgIC8qKlxuICAgICAgICogRml4dHVyZSDrjbDsnbTthLAg7IKt7KCcIChjbGVhbikgQVBJXG4gICAgICAgKiBGSyDsiJzshJzrpbwg6rOg66Ck7ZWY7JesIOyViOyghO2VmOqyjCDsgq3soJxcbiAgICAgICAqL1xuICAgICAgc2VydmVyLnBvc3Q8e1xuICAgICAgICBCb2R5OiB7XG4gICAgICAgICAgZW50aXRpZXM/OiBzdHJpbmdbXTtcbiAgICAgICAgfTtcbiAgICAgIH0+KFwiL2FwaS9zb25hbXUvZml4dHVyZS9jbGVhblwiLCBhc3luYyAocmVxdWVzdCwgcmVwbHkpID0+IHtcbiAgICAgICAgY29uc3QgeyBlbnRpdGllcyB9ID0gcmVxdWVzdC5ib2R5O1xuXG4gICAgICAgIC8vIEZpeHR1cmUgREIg7Jew6rKwXG4gICAgICAgIGNvbnN0IGZpeHR1cmVEYiA9IGNyZWF0ZUtuZXhJbnN0YW5jZShTb25hbXUuZGJDb25maWcuZml4dHVyZSk7XG5cbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICAvLyDsgq3soJztlaAgRW50aXR5IOuqqeuhnSDqsrDsoJVcbiAgICAgICAgICBjb25zdCB0YXJnZXRFbnRpdGllcyA9XG4gICAgICAgICAgICBlbnRpdGllcyAmJiBlbnRpdGllcy5sZW5ndGggPiAwID8gZW50aXRpZXMgOiBFbnRpdHlNYW5hZ2VyLmdldEFsbElkcygpO1xuXG4gICAgICAgICAgLy8gRW50aXR5IElE66W8IO2FjOydtOu4lOuqheycvOuhnCDrs4DtmZggKHNuYWtlX2Nhc2Ug67O17IiY7ZiVKVxuICAgICAgICAgIGNvbnN0IHRhYmxlTmFtZXMgPSB0YXJnZXRFbnRpdGllcy5tYXAoKGVudGl0eUlkKSA9PiB7XG4gICAgICAgICAgICBjb25zdCBlbnRpdHkgPSBFbnRpdHlNYW5hZ2VyLmdldChlbnRpdHlJZCk7XG4gICAgICAgICAgICByZXR1cm4gZW50aXR5LnRhYmxlO1xuICAgICAgICAgIH0pO1xuXG4gICAgICAgICAgLy8gUG9zdGdyZVNRTDogVFJVTkNBVEUgQ0FTQ0FEReuhnCBGSyDsiJzshJwg66y06rSA7ZWY6rKMIOyViOyghO2VmOqyjCDsgq3soJxcbiAgICAgICAgICAvLyBDQVNDQURFIOyYteyFmOycvOuhnCDsnZjsobTshLEg7J6I64qUIOuNsOydtO2EsOuPhCDtlajqu5gg7IKt7KCcXG4gICAgICAgICAgYXdhaXQgZml4dHVyZURiLnJhdyhcbiAgICAgICAgICAgIGBUUlVOQ0FURSBUQUJMRSAke3RhYmxlTmFtZXMubWFwKCh0KSA9PiBgXCIke3R9XCJgKS5qb2luKFwiLCBcIil9IFJFU1RBUlQgSURFTlRJVFkgQ0FTQ0FERWAsXG4gICAgICAgICAgKTtcblxuICAgICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICBzdWNjZXNzOiB0cnVlLFxuICAgICAgICAgICAgY2xlYW5lZDogdGFibGVOYW1lcyxcbiAgICAgICAgICAgIGNvdW50OiB0YWJsZU5hbWVzLmxlbmd0aCxcbiAgICAgICAgICB9O1xuICAgICAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgICAgIHJlcGx5LnN0YXR1cyg0MDApO1xuICAgICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICBzdWNjZXNzOiBmYWxzZSxcbiAgICAgICAgICAgIGVycm9yOiBlcnJvciBpbnN0YW5jZW9mIEVycm9yID8gZXJyb3IubWVzc2FnZSA6IFN0cmluZyhlcnJvciksXG4gICAgICAgICAgfTtcbiAgICAgICAgfSBmaW5hbGx5IHtcbiAgICAgICAgICBhd2FpdCBmaXh0dXJlRGIuZGVzdHJveSgpO1xuICAgICAgICB9XG4gICAgICB9KTtcblxuICAgICAgLy8gQ0REIEFQSVxuICAgICAgc2VydmVyLmdldChcIi9hcGkvY2RkL3RyZWVcIiwgYXN5bmMgKCkgPT4ge1xuICAgICAgICByZXR1cm4gZ2V0Q2RkVHJlZSgpO1xuICAgICAgfSk7XG5cbiAgICAgIHNlcnZlci5wb3N0PHsgQm9keTogeyBmaWxlUGF0aDogc3RyaW5nIH0gfT4oXCIvYXBpL2NkZC9yZWFkQ29udGVudFwiLCAocmVxdWVzdCkgPT5cbiAgICAgICAgZm9yd2FyZEFzeW5jRXJyb3JzKGFzeW5jICgpID0+IHtcbiAgICAgICAgICBjb25zdCB7IGZpbGVQYXRoIH0gPSByZXF1ZXN0LmJvZHk7XG4gICAgICAgICAgcmV0dXJuIHJlYWRDb250ZW50KGZpbGVQYXRoKTtcbiAgICAgICAgfSksXG4gICAgICApO1xuXG4gICAgICBzZXJ2ZXIucG9zdDx7IEJvZHk6IHsgZmlsZVBhdGg6IHN0cmluZyB9IH0+KFwiL2FwaS9jZGQvZWRpdENvbnRlbnRcIiwgKHJlcXVlc3QpID0+XG4gICAgICAgIGZvcndhcmRBc3luY0Vycm9ycyhhc3luYyAoKSA9PiB7XG4gICAgICAgICAgY29uc3QgeyBmaWxlUGF0aCB9ID0gcmVxdWVzdC5ib2R5O1xuICAgICAgICAgIHJldHVybiBlZGl0Q29udGVudChmaWxlUGF0aCk7XG4gICAgICAgIH0pLFxuICAgICAgKTtcblxuICAgICAgc2VydmVyLnBvc3Q8eyBCb2R5OiB7IGZpbGVQYXRoOiBzdHJpbmcgfSB9PihcIi9hcGkvY2RkL29wZW5Tb3VyY2VcIiwgKHJlcXVlc3QpID0+XG4gICAgICAgIGZvcndhcmRBc3luY0Vycm9ycyhhc3luYyAoKSA9PiB7XG4gICAgICAgICAgY29uc3QgeyBmaWxlUGF0aCB9ID0gcmVxdWVzdC5ib2R5O1xuICAgICAgICAgIG9wZW5Tb3VyY2VGaWxlKGZpbGVQYXRoKTtcbiAgICAgICAgICByZXR1cm4geyBzdWNjZXNzOiB0cnVlIH07XG4gICAgICAgIH0pLFxuICAgICAgKTtcblxuICAgICAgLy8gQ0REIFJ1bGVzIEFQSVxuICAgICAgc2VydmVyLmdldChcIi9hcGkvY2RkL3J1bGVzXCIsIGFzeW5jICgpID0+IHtcbiAgICAgICAgcmV0dXJuIGxpc3RSdWxlcygpO1xuICAgICAgfSk7XG5cbiAgICAgIHNlcnZlci5wb3N0PHsgQm9keTogeyBydWxlS2V5OiBzdHJpbmcgfSB9PihcIi9hcGkvY2RkL3JlYWRSdWxlXCIsIChyZXF1ZXN0KSA9PlxuICAgICAgICBmb3J3YXJkQXN5bmNFcnJvcnMoYXN5bmMgKCkgPT4ge1xuICAgICAgICAgIGNvbnN0IHsgcnVsZUtleSB9ID0gcmVxdWVzdC5ib2R5O1xuICAgICAgICAgIHJldHVybiByZWFkUnVsZShydWxlS2V5KTtcbiAgICAgICAgfSksXG4gICAgICApO1xuXG4gICAgICBzZXJ2ZXIucG9zdDx7IEJvZHk6IENkZEFkZFJ1bGVSZXF1ZXN0IH0+KFwiL2FwaS9jZGQvYWRkUnVsZVwiLCAocmVxdWVzdCkgPT5cbiAgICAgICAgZm9yd2FyZEFzeW5jRXJyb3JzKGFzeW5jICgpID0+IHtcbiAgICAgICAgICByZXR1cm4gYWRkUnVsZShyZXF1ZXN0LmJvZHkpO1xuICAgICAgICB9KSxcbiAgICAgICk7XG5cbiAgICAgIC8vIENERCBBQyBBUElcbiAgICAgIHNlcnZlci5nZXQoXCIvYXBpL2NkZC9hY1wiLCBhc3luYyAoKSA9PiB7XG4gICAgICAgIHJldHVybiBnZXRBY0xpc3QoKTtcbiAgICAgIH0pO1xuXG4gICAgICAvLyB1aS13ZWIg67mM65OcIO2MjOydvCDshJzruZlcbiAgICAgIGNvbnN0IHVpRGlzdFBhdGggPSBwYXRoLnJlc29sdmUoaW1wb3J0Lm1ldGEuZGlybmFtZSwgXCIuLi91aS13ZWJcIik7XG5cbiAgICAgIC8vIOygleyggSDtjIzsnbwg7ISc67mZOiDro6jtirgg7Y+0642UIOyghOyytCAoYXNzZXRzLCBzZXR0aW5nLnN2ZyDrk7EpXG4gICAgICBzZXJ2ZXIucmVnaXN0ZXIoYXdhaXQgaW1wb3J0KFwiQGZhc3RpZnkvc3RhdGljXCIpLCB7XG4gICAgICAgIHJvb3Q6IHVpRGlzdFBhdGgsXG4gICAgICAgIHByZWZpeDogXCIvXCIsXG4gICAgICAgIGRlY29yYXRlUmVwbHk6IGZhbHNlLFxuICAgICAgICB3aWxkY2FyZDogZmFsc2UsXG4gICAgICB9KTtcblxuICAgICAgLy8gU1BBIGZhbGxiYWNrIC0g7KCV7KCBIO2MjOydvOydtCDsl4bripQg66qo65OgIOqyveuhnOuKlCBpbmRleC5odG1s66GcXG4gICAgICBzZXJ2ZXIuZ2V0KFwiKlwiLCBhc3luYyAoX3JlcXVlc3QsIHJlcGx5KSA9PiB7XG4gICAgICAgIHJlcGx5LmhlYWRlcnMoeyBcIkNvbnRlbnQtdHlwZVwiOiBcInRleHQvaHRtbFwiIH0pLnNlbmQoXG4gICAgICAgICAgZnNcbiAgICAgICAgICAgIC5yZWFkRmlsZVN5bmMocGF0aC5yZXNvbHZlKHVpRGlzdFBhdGgsIFwiaW5kZXguaHRtbFwiKSlcbiAgICAgICAgICAgIC50b1N0cmluZygpXG4gICAgICAgICAgICAucmVwbGFjZShcInt7cHJvamVjdE5hbWV9fVwiLCBTb25hbXUuY29uZmlnLnByb2plY3ROYW1lID8/IFwiVW5rbm93blNvbmFtdVByb2plY3RcIiksXG4gICAgICAgICk7XG4gICAgICB9KTtcbiAgICB9LFxuICAgIHsgcHJlZml4OiBcIi9zb25hbXUtdWlcIiB9LFxuICApO1xufVxuIl0sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0FBMkRBLGVBQWUsb0JBQXVCLElBQWtDO0NBQ3RFLE1BQU0sY0FBYyxJQUFJLFNBQWUsWUFBWTtFQUNqRCxNQUFNLGdCQUFnQjtHQUNwQixhQUFhLE9BQU87R0FDcEIsUUFBUTtFQUNWO0VBRUEsTUFBTSxVQUFVLGlCQUFpQjtHQUMvQixPQUFPLE9BQU8sYUFBYSxJQUFJLGtCQUFrQixPQUFPO0dBQ3hELFFBQVE7RUFDVixHQUFHLElBQUk7RUFFUCxPQUFPLE9BQU8sYUFBYSxLQUFLLGtCQUFrQixPQUFPO0NBQzNELENBQUM7Q0FFRCxNQUFNLFNBQVMsTUFBTSxHQUFHO0NBQ3hCLE1BQU07Q0FDTixPQUFPO0FBQ1Q7QUFFQSxTQUFTLGtCQUFrQixZQUFtRDtDQUM1RSxPQUFPLFdBQVcsU0FBUyxjQUFjO0VBQ3ZDLE1BQU0sRUFBRSxVQUFVLEdBQUcsU0FBUztFQUM5QixPQUFPLENBQUMsTUFBTSxHQUFHLGtCQUFrQixRQUFRLENBQUM7Q0FDOUMsQ0FBQztBQUNIO0FBRUEsZUFBc0Isa0JBQWtCLFNBQTBCO0NBQ2hFLFFBQVEsU0FDTixPQUFPLFdBQVc7RUFDaEIsTUFBTSxTQUFTLE1BQU07RUFDckIsTUFBTSxzQkFBc0IsTUFBTTtFQUVsQyxPQUFPLElBQUksc0JBQXNCLFlBQVk7R0FDM0MsT0FBTyxPQUFPO0VBQ2hCLENBQUM7RUFFRCxPQUFPLElBTUosMEJBQTBCLFlBQzNCLG1CQUFtQixZQUFZO0dBQzdCLE1BQU0sRUFBRSxVQUFVLFFBQVEsWUFBWSxRQUFRO0dBMkI5QyxTQUFTLGVBekJpQjtJQUN4QixJQUFJLFlBQVksUUFBUTtLQUN0QixNQUFNLFNBQVMsY0FBYyxJQUFJLFFB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