velocious 1.0.428 → 1.0.429

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 (933) hide show
  1. package/README.md +2 -0
  2. package/build/src/application.d.ts +96 -9
  3. package/build/src/application.d.ts.map +1 -1
  4. package/build/src/application.js +127 -28
  5. package/build/src/authorization/ability.d.ts +72 -31
  6. package/build/src/authorization/ability.d.ts.map +1 -1
  7. package/build/src/authorization/ability.js +59 -22
  8. package/build/src/authorization/base-resource.d.ts +47 -20
  9. package/build/src/authorization/base-resource.d.ts.map +1 -1
  10. package/build/src/authorization/base-resource.js +43 -14
  11. package/build/src/background-jobs/client.d.ts +4 -2
  12. package/build/src/background-jobs/client.d.ts.map +1 -1
  13. package/build/src/background-jobs/client.js +4 -2
  14. package/build/src/background-jobs/cron-expression.d.ts +9 -5
  15. package/build/src/background-jobs/cron-expression.d.ts.map +1 -1
  16. package/build/src/background-jobs/cron-expression.js +16 -6
  17. package/build/src/background-jobs/forked-runner-child.js +12 -5
  18. package/build/src/background-jobs/job-registry.d.ts +7 -1
  19. package/build/src/background-jobs/job-registry.d.ts.map +1 -1
  20. package/build/src/background-jobs/job-registry.js +8 -2
  21. package/build/src/background-jobs/job-runner.d.ts +1 -0
  22. package/build/src/background-jobs/job-runner.d.ts.map +1 -1
  23. package/build/src/background-jobs/job-runner.js +8 -3
  24. package/build/src/background-jobs/job.d.ts +12 -8
  25. package/build/src/background-jobs/job.d.ts.map +1 -1
  26. package/build/src/background-jobs/job.js +12 -6
  27. package/build/src/background-jobs/json-socket.d.ts +17 -5
  28. package/build/src/background-jobs/json-socket.d.ts.map +1 -1
  29. package/build/src/background-jobs/json-socket.js +18 -6
  30. package/build/src/background-jobs/main.d.ts +118 -32
  31. package/build/src/background-jobs/main.d.ts.map +1 -1
  32. package/build/src/background-jobs/main.js +123 -35
  33. package/build/src/background-jobs/normalize-error.d.ts +2 -1
  34. package/build/src/background-jobs/normalize-error.d.ts.map +1 -1
  35. package/build/src/background-jobs/normalize-error.js +5 -3
  36. package/build/src/background-jobs/scheduler.d.ts +31 -10
  37. package/build/src/background-jobs/scheduler.d.ts.map +1 -1
  38. package/build/src/background-jobs/scheduler.js +33 -11
  39. package/build/src/background-jobs/socket-request.d.ts +2 -0
  40. package/build/src/background-jobs/socket-request.d.ts.map +1 -1
  41. package/build/src/background-jobs/socket-request.js +11 -3
  42. package/build/src/background-jobs/status-reporter.d.ts +5 -2
  43. package/build/src/background-jobs/status-reporter.d.ts.map +1 -1
  44. package/build/src/background-jobs/status-reporter.js +6 -3
  45. package/build/src/background-jobs/store.d.ts +57 -19
  46. package/build/src/background-jobs/store.d.ts.map +1 -1
  47. package/build/src/background-jobs/store.js +70 -20
  48. package/build/src/background-jobs/types.d.ts +7 -7
  49. package/build/src/background-jobs/types.d.ts.map +1 -1
  50. package/build/src/background-jobs/types.js +6 -6
  51. package/build/src/background-jobs/web/authorization.d.ts.map +1 -1
  52. package/build/src/background-jobs/web/authorization.js +3 -1
  53. package/build/src/background-jobs/web/controller.d.ts +40 -14
  54. package/build/src/background-jobs/web/controller.d.ts.map +1 -1
  55. package/build/src/background-jobs/web/controller.js +46 -15
  56. package/build/src/background-jobs/web/registry.d.ts +5 -0
  57. package/build/src/background-jobs/web/registry.d.ts.map +1 -1
  58. package/build/src/background-jobs/web/registry.js +4 -1
  59. package/build/src/background-jobs/worker.d.ts +41 -8
  60. package/build/src/background-jobs/worker.d.ts.map +1 -1
  61. package/build/src/background-jobs/worker.js +64 -16
  62. package/build/src/beacon/client.d.ts +39 -12
  63. package/build/src/beacon/client.d.ts.map +1 -1
  64. package/build/src/beacon/client.js +45 -15
  65. package/build/src/beacon/in-process-broker.d.ts +4 -0
  66. package/build/src/beacon/in-process-broker.d.ts.map +1 -1
  67. package/build/src/beacon/in-process-broker.js +8 -3
  68. package/build/src/beacon/in-process-client.d.ts +28 -9
  69. package/build/src/beacon/in-process-client.d.ts.map +1 -1
  70. package/build/src/beacon/in-process-client.js +27 -9
  71. package/build/src/beacon/server.d.ts +13 -2
  72. package/build/src/beacon/server.d.ts.map +1 -1
  73. package/build/src/beacon/server.js +21 -5
  74. package/build/src/beacon/types.d.ts +3 -3
  75. package/build/src/beacon/types.d.ts.map +1 -1
  76. package/build/src/beacon/types.js +2 -2
  77. package/build/src/cli/base-command.d.ts +18 -4
  78. package/build/src/cli/base-command.d.ts.map +1 -1
  79. package/build/src/cli/base-command.js +15 -4
  80. package/build/src/cli/browser-cli.d.ts +3 -0
  81. package/build/src/cli/browser-cli.d.ts.map +1 -1
  82. package/build/src/cli/browser-cli.js +7 -2
  83. package/build/src/cli/commands/background-jobs-main.d.ts +0 -1
  84. package/build/src/cli/commands/background-jobs-main.d.ts.map +1 -1
  85. package/build/src/cli/commands/background-jobs-runner.d.ts +0 -1
  86. package/build/src/cli/commands/background-jobs-runner.d.ts.map +1 -1
  87. package/build/src/cli/commands/background-jobs-worker.d.ts +0 -1
  88. package/build/src/cli/commands/background-jobs-worker.d.ts.map +1 -1
  89. package/build/src/cli/commands/beacon.d.ts +0 -1
  90. package/build/src/cli/commands/beacon.d.ts.map +1 -1
  91. package/build/src/cli/commands/console.d.ts +0 -2
  92. package/build/src/cli/commands/console.d.ts.map +1 -1
  93. package/build/src/cli/commands/console.js +5 -2
  94. package/build/src/cli/commands/db/base-command.d.ts +11 -2
  95. package/build/src/cli/commands/db/base-command.d.ts.map +1 -1
  96. package/build/src/cli/commands/db/base-command.js +12 -3
  97. package/build/src/cli/commands/db/create.d.ts +3 -0
  98. package/build/src/cli/commands/db/create.d.ts.map +1 -1
  99. package/build/src/cli/commands/db/create.js +4 -1
  100. package/build/src/cli/commands/db/drop.d.ts +3 -0
  101. package/build/src/cli/commands/db/drop.d.ts.map +1 -1
  102. package/build/src/cli/commands/db/drop.js +4 -1
  103. package/build/src/cli/commands/db/schema/dump.d.ts +0 -2
  104. package/build/src/cli/commands/db/schema/dump.d.ts.map +1 -1
  105. package/build/src/cli/commands/db/schema/dump.js +5 -2
  106. package/build/src/cli/commands/db/schema/load.d.ts +0 -2
  107. package/build/src/cli/commands/db/schema/load.d.ts.map +1 -1
  108. package/build/src/cli/commands/db/schema/load.js +5 -2
  109. package/build/src/cli/commands/db/seed.d.ts +0 -2
  110. package/build/src/cli/commands/db/seed.d.ts.map +1 -1
  111. package/build/src/cli/commands/db/seed.js +5 -2
  112. package/build/src/cli/commands/db/tenants/check.d.ts +4 -1
  113. package/build/src/cli/commands/db/tenants/check.d.ts.map +1 -1
  114. package/build/src/cli/commands/db/tenants/check.js +5 -2
  115. package/build/src/cli/commands/db/tenants/create.d.ts +4 -1
  116. package/build/src/cli/commands/db/tenants/create.d.ts.map +1 -1
  117. package/build/src/cli/commands/db/tenants/create.js +5 -2
  118. package/build/src/cli/commands/db/tenants/migrate.d.ts +4 -1
  119. package/build/src/cli/commands/db/tenants/migrate.d.ts.map +1 -1
  120. package/build/src/cli/commands/db/tenants/migrate.js +5 -2
  121. package/build/src/cli/commands/destroy/migration.d.ts +0 -1
  122. package/build/src/cli/commands/destroy/migration.d.ts.map +1 -1
  123. package/build/src/cli/commands/generate/base-models.d.ts +0 -1
  124. package/build/src/cli/commands/generate/base-models.d.ts.map +1 -1
  125. package/build/src/cli/commands/generate/frontend-models.d.ts +0 -2
  126. package/build/src/cli/commands/generate/frontend-models.d.ts.map +1 -1
  127. package/build/src/cli/commands/generate/frontend-models.js +5 -2
  128. package/build/src/cli/commands/generate/migration.d.ts +0 -1
  129. package/build/src/cli/commands/generate/migration.d.ts.map +1 -1
  130. package/build/src/cli/commands/generate/model.d.ts +0 -1
  131. package/build/src/cli/commands/generate/model.d.ts.map +1 -1
  132. package/build/src/cli/commands/init.d.ts +0 -1
  133. package/build/src/cli/commands/init.d.ts.map +1 -1
  134. package/build/src/cli/commands/routes.d.ts +0 -1
  135. package/build/src/cli/commands/routes.d.ts.map +1 -1
  136. package/build/src/cli/commands/run-script.d.ts +0 -2
  137. package/build/src/cli/commands/run-script.d.ts.map +1 -1
  138. package/build/src/cli/commands/run-script.js +5 -2
  139. package/build/src/cli/commands/runner.d.ts +0 -2
  140. package/build/src/cli/commands/runner.d.ts.map +1 -1
  141. package/build/src/cli/commands/runner.js +5 -2
  142. package/build/src/cli/commands/server.d.ts +0 -1
  143. package/build/src/cli/commands/server.d.ts.map +1 -1
  144. package/build/src/cli/commands/test.d.ts +0 -1
  145. package/build/src/cli/commands/test.d.ts.map +1 -1
  146. package/build/src/cli/index.d.ts +18 -5
  147. package/build/src/cli/index.d.ts.map +1 -1
  148. package/build/src/cli/index.js +25 -8
  149. package/build/src/cli/tenant-database-command-helper.d.ts +24 -9
  150. package/build/src/cli/tenant-database-command-helper.d.ts.map +1 -1
  151. package/build/src/cli/tenant-database-command-helper.js +30 -11
  152. package/build/src/cli/use-browser-cli.d.ts +1 -0
  153. package/build/src/cli/use-browser-cli.d.ts.map +1 -1
  154. package/build/src/cli/use-browser-cli.js +5 -2
  155. package/build/src/configuration-resolver.d.ts +1 -0
  156. package/build/src/configuration-resolver.d.ts.map +1 -1
  157. package/build/src/configuration-resolver.js +2 -1
  158. package/build/src/configuration-types.d.ts +44 -44
  159. package/build/src/configuration-types.d.ts.map +1 -1
  160. package/build/src/configuration-types.js +27 -27
  161. package/build/src/configuration.d.ts +350 -114
  162. package/build/src/configuration.d.ts.map +1 -1
  163. package/build/src/configuration.js +416 -128
  164. package/build/src/controller.d.ts +67 -18
  165. package/build/src/controller.d.ts.map +1 -1
  166. package/build/src/controller.js +88 -23
  167. package/build/src/current-configuration.d.ts +2 -0
  168. package/build/src/current-configuration.d.ts.map +1 -1
  169. package/build/src/current-configuration.js +6 -2
  170. package/build/src/current.d.ts +16 -9
  171. package/build/src/current.d.ts.map +1 -1
  172. package/build/src/current.js +15 -8
  173. package/build/src/database/annotations-async-hooks.js +13 -6
  174. package/build/src/database/annotations.d.ts +7 -1
  175. package/build/src/database/annotations.d.ts.map +1 -1
  176. package/build/src/database/annotations.js +12 -5
  177. package/build/src/database/drivers/base-column.d.ts +21 -3
  178. package/build/src/database/drivers/base-column.d.ts.map +1 -1
  179. package/build/src/database/drivers/base-column.js +21 -3
  180. package/build/src/database/drivers/base-columns-index.d.ts +9 -0
  181. package/build/src/database/drivers/base-columns-index.d.ts.map +1 -1
  182. package/build/src/database/drivers/base-columns-index.js +10 -1
  183. package/build/src/database/drivers/base-foreign-key.d.ts +15 -3
  184. package/build/src/database/drivers/base-foreign-key.d.ts.map +1 -1
  185. package/build/src/database/drivers/base-foreign-key.js +15 -3
  186. package/build/src/database/drivers/base-table.d.ts +16 -3
  187. package/build/src/database/drivers/base-table.d.ts.map +1 -1
  188. package/build/src/database/drivers/base-table.js +16 -3
  189. package/build/src/database/drivers/base.d.ts +174 -37
  190. package/build/src/database/drivers/base.d.ts.map +1 -1
  191. package/build/src/database/drivers/base.js +156 -40
  192. package/build/src/database/drivers/mssql/column.d.ts +3 -2
  193. package/build/src/database/drivers/mssql/column.d.ts.map +1 -1
  194. package/build/src/database/drivers/mssql/column.js +3 -2
  195. package/build/src/database/drivers/mssql/index.d.ts +5 -6
  196. package/build/src/database/drivers/mssql/index.d.ts.map +1 -1
  197. package/build/src/database/drivers/mssql/index.js +38 -7
  198. package/build/src/database/drivers/mssql/options.d.ts +1 -0
  199. package/build/src/database/drivers/mssql/options.d.ts.map +1 -1
  200. package/build/src/database/drivers/mssql/options.js +8 -2
  201. package/build/src/database/drivers/mssql/sql/create-database.d.ts +1 -0
  202. package/build/src/database/drivers/mssql/sql/create-database.d.ts.map +1 -1
  203. package/build/src/database/drivers/mssql/sql/create-database.js +2 -1
  204. package/build/src/database/drivers/mssql/sql/drop-database.d.ts.map +1 -1
  205. package/build/src/database/drivers/mssql/sql/drop-database.js +2 -1
  206. package/build/src/database/drivers/mssql/structure-sql.d.ts +5 -2
  207. package/build/src/database/drivers/mssql/structure-sql.d.ts.map +1 -1
  208. package/build/src/database/drivers/mssql/structure-sql.js +5 -2
  209. package/build/src/database/drivers/mssql/table.d.ts +1 -0
  210. package/build/src/database/drivers/mssql/table.d.ts.map +1 -1
  211. package/build/src/database/drivers/mssql/table.js +9 -4
  212. package/build/src/database/drivers/mysql/column.d.ts +3 -2
  213. package/build/src/database/drivers/mysql/column.d.ts.map +1 -1
  214. package/build/src/database/drivers/mysql/column.js +4 -3
  215. package/build/src/database/drivers/mysql/index.d.ts +11 -3
  216. package/build/src/database/drivers/mysql/index.d.ts.map +1 -1
  217. package/build/src/database/drivers/mysql/index.js +54 -10
  218. package/build/src/database/drivers/mysql/options.d.ts +1 -0
  219. package/build/src/database/drivers/mysql/options.d.ts.map +1 -1
  220. package/build/src/database/drivers/mysql/options.js +4 -2
  221. package/build/src/database/drivers/mysql/query.d.ts +3 -2
  222. package/build/src/database/drivers/mysql/query.d.ts.map +1 -1
  223. package/build/src/database/drivers/mysql/query.js +6 -3
  224. package/build/src/database/drivers/mysql/sql/create-database.d.ts.map +1 -1
  225. package/build/src/database/drivers/mysql/sql/create-database.js +3 -1
  226. package/build/src/database/drivers/mysql/structure-sql.d.ts +7 -2
  227. package/build/src/database/drivers/mysql/structure-sql.d.ts.map +1 -1
  228. package/build/src/database/drivers/mysql/structure-sql.js +7 -2
  229. package/build/src/database/drivers/mysql/table.d.ts +1 -0
  230. package/build/src/database/drivers/mysql/table.d.ts.map +1 -1
  231. package/build/src/database/drivers/mysql/table.js +7 -3
  232. package/build/src/database/drivers/pgsql/column.d.ts +3 -2
  233. package/build/src/database/drivers/pgsql/column.d.ts.map +1 -1
  234. package/build/src/database/drivers/pgsql/column.js +3 -2
  235. package/build/src/database/drivers/pgsql/index.d.ts +1 -1
  236. package/build/src/database/drivers/pgsql/index.d.ts.map +1 -1
  237. package/build/src/database/drivers/pgsql/index.js +36 -11
  238. package/build/src/database/drivers/pgsql/options.d.ts +2 -0
  239. package/build/src/database/drivers/pgsql/options.d.ts.map +1 -1
  240. package/build/src/database/drivers/pgsql/options.js +3 -1
  241. package/build/src/database/drivers/pgsql/structure-sql.d.ts +5 -2
  242. package/build/src/database/drivers/pgsql/structure-sql.d.ts.map +1 -1
  243. package/build/src/database/drivers/pgsql/structure-sql.js +5 -2
  244. package/build/src/database/drivers/pgsql/table.d.ts +1 -0
  245. package/build/src/database/drivers/pgsql/table.d.ts.map +1 -1
  246. package/build/src/database/drivers/pgsql/table.js +6 -2
  247. package/build/src/database/drivers/sqlite/base.d.ts +15 -5
  248. package/build/src/database/drivers/sqlite/base.d.ts.map +1 -1
  249. package/build/src/database/drivers/sqlite/base.js +79 -27
  250. package/build/src/database/drivers/sqlite/column.d.ts +3 -2
  251. package/build/src/database/drivers/sqlite/column.d.ts.map +1 -1
  252. package/build/src/database/drivers/sqlite/column.js +3 -2
  253. package/build/src/database/drivers/sqlite/connection-sql-js.d.ts +4 -2
  254. package/build/src/database/drivers/sqlite/connection-sql-js.d.ts.map +1 -1
  255. package/build/src/database/drivers/sqlite/connection-sql-js.js +4 -2
  256. package/build/src/database/drivers/sqlite/foreign-key.d.ts +3 -2
  257. package/build/src/database/drivers/sqlite/foreign-key.d.ts.map +1 -1
  258. package/build/src/database/drivers/sqlite/foreign-key.js +3 -2
  259. package/build/src/database/drivers/sqlite/index.d.ts +18 -5
  260. package/build/src/database/drivers/sqlite/index.d.ts.map +1 -1
  261. package/build/src/database/drivers/sqlite/index.js +40 -16
  262. package/build/src/database/drivers/sqlite/index.native.d.ts +1 -1
  263. package/build/src/database/drivers/sqlite/index.native.d.ts.map +1 -1
  264. package/build/src/database/drivers/sqlite/index.native.js +6 -3
  265. package/build/src/database/drivers/sqlite/index.web.d.ts +16 -4
  266. package/build/src/database/drivers/sqlite/index.web.d.ts.map +1 -1
  267. package/build/src/database/drivers/sqlite/index.web.js +17 -7
  268. package/build/src/database/drivers/sqlite/options.d.ts +2 -0
  269. package/build/src/database/drivers/sqlite/options.d.ts.map +1 -1
  270. package/build/src/database/drivers/sqlite/options.js +3 -1
  271. package/build/src/database/drivers/sqlite/query.d.ts +3 -2
  272. package/build/src/database/drivers/sqlite/query.d.ts.map +1 -1
  273. package/build/src/database/drivers/sqlite/query.js +6 -3
  274. package/build/src/database/drivers/sqlite/query.native.d.ts +2 -2
  275. package/build/src/database/drivers/sqlite/query.native.d.ts.map +1 -1
  276. package/build/src/database/drivers/sqlite/query.native.js +3 -3
  277. package/build/src/database/drivers/sqlite/query.web.d.ts +3 -2
  278. package/build/src/database/drivers/sqlite/query.web.d.ts.map +1 -1
  279. package/build/src/database/drivers/sqlite/query.web.js +6 -3
  280. package/build/src/database/drivers/sqlite/sql/alter-table.d.ts.map +1 -1
  281. package/build/src/database/drivers/sqlite/sql/alter-table.js +9 -3
  282. package/build/src/database/drivers/sqlite/structure-sql.d.ts +2 -0
  283. package/build/src/database/drivers/sqlite/structure-sql.d.ts.map +1 -1
  284. package/build/src/database/drivers/sqlite/structure-sql.js +3 -1
  285. package/build/src/database/drivers/sqlite/table-rebuilder.d.ts +2 -0
  286. package/build/src/database/drivers/sqlite/table-rebuilder.d.ts.map +1 -1
  287. package/build/src/database/drivers/sqlite/table-rebuilder.js +3 -1
  288. package/build/src/database/drivers/sqlite/table.d.ts +2 -0
  289. package/build/src/database/drivers/sqlite/table.d.ts.map +1 -1
  290. package/build/src/database/drivers/sqlite/table.js +14 -4
  291. package/build/src/database/drivers/structure-sql/utils.d.ts +2 -0
  292. package/build/src/database/drivers/structure-sql/utils.d.ts.map +1 -1
  293. package/build/src/database/drivers/structure-sql/utils.js +3 -1
  294. package/build/src/database/handler.d.ts +1 -0
  295. package/build/src/database/handler.d.ts.map +1 -1
  296. package/build/src/database/handler.js +2 -1
  297. package/build/src/database/initializer-from-require-context.d.ts +8 -0
  298. package/build/src/database/initializer-from-require-context.d.ts.map +1 -1
  299. package/build/src/database/initializer-from-require-context.js +4 -1
  300. package/build/src/database/migration/index.d.ts +40 -5
  301. package/build/src/database/migration/index.d.ts.map +1 -1
  302. package/build/src/database/migration/index.js +34 -6
  303. package/build/src/database/migrator/files-finder.d.ts +2 -0
  304. package/build/src/database/migrator/files-finder.d.ts.map +1 -1
  305. package/build/src/database/migrator/files-finder.js +6 -2
  306. package/build/src/database/migrator.d.ts +29 -4
  307. package/build/src/database/migrator.d.ts.map +1 -1
  308. package/build/src/database/migrator.js +45 -10
  309. package/build/src/database/pool/async-tracked-multi-connection.d.ts +125 -31
  310. package/build/src/database/pool/async-tracked-multi-connection.d.ts.map +1 -1
  311. package/build/src/database/pool/async-tracked-multi-connection.js +189 -52
  312. package/build/src/database/pool/base-methods-forward.d.ts +1 -0
  313. package/build/src/database/pool/base-methods-forward.d.ts.map +1 -1
  314. package/build/src/database/pool/base-methods-forward.js +12 -3
  315. package/build/src/database/pool/base.d.ts +39 -7
  316. package/build/src/database/pool/base.d.ts.map +1 -1
  317. package/build/src/database/pool/base.js +59 -18
  318. package/build/src/database/pool/single-multi-use.d.ts +1 -0
  319. package/build/src/database/pool/single-multi-use.d.ts.map +1 -1
  320. package/build/src/database/pool/single-multi-use.js +16 -4
  321. package/build/src/database/query/alter-table-base.d.ts +1 -0
  322. package/build/src/database/query/alter-table-base.d.ts.map +1 -1
  323. package/build/src/database/query/alter-table-base.js +3 -1
  324. package/build/src/database/query/base.d.ts +3 -0
  325. package/build/src/database/query/base.d.ts.map +1 -1
  326. package/build/src/database/query/base.js +4 -1
  327. package/build/src/database/query/create-database-base.d.ts +5 -0
  328. package/build/src/database/query/create-database-base.d.ts.map +1 -1
  329. package/build/src/database/query/create-database-base.js +4 -1
  330. package/build/src/database/query/create-index-base.d.ts +5 -0
  331. package/build/src/database/query/create-index-base.d.ts.map +1 -1
  332. package/build/src/database/query/create-index-base.js +4 -1
  333. package/build/src/database/query/create-table-base.d.ts +2 -0
  334. package/build/src/database/query/create-table-base.d.ts.map +1 -1
  335. package/build/src/database/query/create-table-base.js +3 -1
  336. package/build/src/database/query/delete-base.d.ts +3 -2
  337. package/build/src/database/query/delete-base.d.ts.map +1 -1
  338. package/build/src/database/query/delete-base.js +3 -2
  339. package/build/src/database/query/drop-database-base.d.ts +5 -0
  340. package/build/src/database/query/drop-database-base.d.ts.map +1 -1
  341. package/build/src/database/query/drop-database-base.js +4 -1
  342. package/build/src/database/query/drop-table-base.d.ts +1 -0
  343. package/build/src/database/query/drop-table-base.d.ts.map +1 -1
  344. package/build/src/database/query/drop-table-base.js +3 -1
  345. package/build/src/database/query/from-base.d.ts +6 -1
  346. package/build/src/database/query/from-base.d.ts.map +1 -1
  347. package/build/src/database/query/from-base.js +7 -2
  348. package/build/src/database/query/from-plain.d.ts +1 -0
  349. package/build/src/database/query/from-plain.d.ts.map +1 -1
  350. package/build/src/database/query/from-plain.js +2 -1
  351. package/build/src/database/query/from-table.d.ts +1 -0
  352. package/build/src/database/query/from-table.d.ts.map +1 -1
  353. package/build/src/database/query/from-table.js +2 -1
  354. package/build/src/database/query/index.d.ts +72 -12
  355. package/build/src/database/query/index.d.ts.map +1 -1
  356. package/build/src/database/query/index.js +79 -19
  357. package/build/src/database/query/insert-base.d.ts +13 -8
  358. package/build/src/database/query/insert-base.d.ts.map +1 -1
  359. package/build/src/database/query/insert-base.js +10 -5
  360. package/build/src/database/query/join-base.d.ts +4 -0
  361. package/build/src/database/query/join-base.d.ts.map +1 -1
  362. package/build/src/database/query/join-base.js +5 -1
  363. package/build/src/database/query/join-object.d.ts +11 -0
  364. package/build/src/database/query/join-object.d.ts.map +1 -1
  365. package/build/src/database/query/join-object.js +15 -4
  366. package/build/src/database/query/join-plain.d.ts +1 -0
  367. package/build/src/database/query/join-plain.d.ts.map +1 -1
  368. package/build/src/database/query/join-plain.js +2 -1
  369. package/build/src/database/query/join-tracker.d.ts +7 -0
  370. package/build/src/database/query/join-tracker.d.ts.map +1 -1
  371. package/build/src/database/query/join-tracker.js +8 -1
  372. package/build/src/database/query/model-class-query.d.ts +92 -26
  373. package/build/src/database/query/model-class-query.d.ts.map +1 -1
  374. package/build/src/database/query/model-class-query.js +230 -76
  375. package/build/src/database/query/order-base.d.ts +3 -0
  376. package/build/src/database/query/order-base.d.ts.map +1 -1
  377. package/build/src/database/query/order-base.js +4 -1
  378. package/build/src/database/query/order-column.d.ts +9 -1
  379. package/build/src/database/query/order-column.d.ts.map +1 -1
  380. package/build/src/database/query/order-column.js +10 -2
  381. package/build/src/database/query/order-plain.d.ts +1 -0
  382. package/build/src/database/query/order-plain.d.ts.map +1 -1
  383. package/build/src/database/query/order-plain.js +2 -1
  384. package/build/src/database/query/preloader/belongs-to.d.ts +1 -0
  385. package/build/src/database/query/preloader/belongs-to.d.ts.map +1 -1
  386. package/build/src/database/query/preloader/belongs-to.js +68 -23
  387. package/build/src/database/query/preloader/ensure-model-class-initialized.d.ts +1 -0
  388. package/build/src/database/query/preloader/ensure-model-class-initialized.d.ts.map +1 -1
  389. package/build/src/database/query/preloader/ensure-model-class-initialized.js +2 -1
  390. package/build/src/database/query/preloader/has-many.d.ts +5 -3
  391. package/build/src/database/query/preloader/has-many.d.ts.map +1 -1
  392. package/build/src/database/query/preloader/has-many.js +66 -24
  393. package/build/src/database/query/preloader/has-one.d.ts +1 -0
  394. package/build/src/database/query/preloader/has-one.d.ts.map +1 -1
  395. package/build/src/database/query/preloader/has-one.js +26 -9
  396. package/build/src/database/query/preloader/selection.d.ts +7 -1
  397. package/build/src/database/query/preloader/selection.d.ts.map +1 -1
  398. package/build/src/database/query/preloader/selection.js +13 -5
  399. package/build/src/database/query/preloader.d.ts +1 -0
  400. package/build/src/database/query/preloader.d.ts.map +1 -1
  401. package/build/src/database/query/preloader.js +28 -9
  402. package/build/src/database/query/query-data.d.ts +21 -7
  403. package/build/src/database/query/query-data.d.ts.map +1 -1
  404. package/build/src/database/query/query-data.js +37 -18
  405. package/build/src/database/query/select-base.d.ts +3 -0
  406. package/build/src/database/query/select-base.d.ts.map +1 -1
  407. package/build/src/database/query/select-base.js +4 -1
  408. package/build/src/database/query/select-plain.d.ts +1 -0
  409. package/build/src/database/query/select-plain.d.ts.map +1 -1
  410. package/build/src/database/query/select-plain.js +2 -1
  411. package/build/src/database/query/select-table-and-column.d.ts +1 -0
  412. package/build/src/database/query/select-table-and-column.d.ts.map +1 -1
  413. package/build/src/database/query/select-table-and-column.js +2 -1
  414. package/build/src/database/query/update-base.d.ts +9 -6
  415. package/build/src/database/query/update-base.d.ts.map +1 -1
  416. package/build/src/database/query/update-base.js +7 -4
  417. package/build/src/database/query/upsert-base.d.ts +13 -4
  418. package/build/src/database/query/upsert-base.d.ts.map +1 -1
  419. package/build/src/database/query/upsert-base.js +12 -3
  420. package/build/src/database/query/where-base.d.ts +4 -0
  421. package/build/src/database/query/where-base.d.ts.map +1 -1
  422. package/build/src/database/query/where-base.js +5 -1
  423. package/build/src/database/query/where-combinator.d.ts +1 -0
  424. package/build/src/database/query/where-combinator.d.ts.map +1 -1
  425. package/build/src/database/query/where-combinator.js +6 -2
  426. package/build/src/database/query/where-hash.d.ts +6 -0
  427. package/build/src/database/query/where-hash.d.ts.map +1 -1
  428. package/build/src/database/query/where-hash.js +5 -1
  429. package/build/src/database/query/where-model-class-hash.d.ts +30 -16
  430. package/build/src/database/query/where-model-class-hash.d.ts.map +1 -1
  431. package/build/src/database/query/where-model-class-hash.js +55 -20
  432. package/build/src/database/query/where-not.d.ts +1 -0
  433. package/build/src/database/query/where-not.d.ts.map +1 -1
  434. package/build/src/database/query/where-not.js +3 -1
  435. package/build/src/database/query/where-plain.d.ts +1 -0
  436. package/build/src/database/query/where-plain.d.ts.map +1 -1
  437. package/build/src/database/query/where-plain.js +2 -1
  438. package/build/src/database/query/with-count.d.ts +11 -5
  439. package/build/src/database/query/with-count.d.ts.map +1 -1
  440. package/build/src/database/query/with-count.js +36 -15
  441. package/build/src/database/query-parser/base-query-parser.d.ts +1 -0
  442. package/build/src/database/query-parser/base-query-parser.d.ts.map +1 -1
  443. package/build/src/database/query-parser/base-query-parser.js +2 -1
  444. package/build/src/database/query-parser/from-parser.d.ts +5 -1
  445. package/build/src/database/query-parser/from-parser.d.ts.map +1 -1
  446. package/build/src/database/query-parser/from-parser.js +6 -2
  447. package/build/src/database/query-parser/group-parser.d.ts +2 -0
  448. package/build/src/database/query-parser/group-parser.d.ts.map +1 -1
  449. package/build/src/database/query-parser/group-parser.js +3 -1
  450. package/build/src/database/query-parser/joins-parser.d.ts +1 -0
  451. package/build/src/database/query-parser/joins-parser.d.ts.map +1 -1
  452. package/build/src/database/query-parser/joins-parser.js +2 -1
  453. package/build/src/database/query-parser/limit-parser.d.ts +1 -0
  454. package/build/src/database/query-parser/limit-parser.d.ts.map +1 -1
  455. package/build/src/database/query-parser/limit-parser.js +2 -1
  456. package/build/src/database/query-parser/options.d.ts +15 -4
  457. package/build/src/database/query-parser/options.d.ts.map +1 -1
  458. package/build/src/database/query-parser/options.js +11 -3
  459. package/build/src/database/query-parser/order-parser.d.ts +1 -0
  460. package/build/src/database/query-parser/order-parser.d.ts.map +1 -1
  461. package/build/src/database/query-parser/order-parser.js +2 -1
  462. package/build/src/database/query-parser/select-parser.d.ts +1 -0
  463. package/build/src/database/query-parser/select-parser.d.ts.map +1 -1
  464. package/build/src/database/query-parser/select-parser.js +2 -1
  465. package/build/src/database/query-parser/where-parser.d.ts +1 -0
  466. package/build/src/database/query-parser/where-parser.d.ts.map +1 -1
  467. package/build/src/database/query-parser/where-parser.js +2 -1
  468. package/build/src/database/record/acts-as-list.d.ts +0 -1
  469. package/build/src/database/record/acts-as-list.d.ts.map +1 -1
  470. package/build/src/database/record/acts-as-list.js +61 -23
  471. package/build/src/database/record/attachments/download.d.ts +34 -15
  472. package/build/src/database/record/attachments/download.d.ts.map +1 -1
  473. package/build/src/database/record/attachments/download.js +34 -22
  474. package/build/src/database/record/attachments/handle.d.ts +17 -5
  475. package/build/src/database/record/attachments/handle.d.ts.map +1 -1
  476. package/build/src/database/record/attachments/handle.js +25 -9
  477. package/build/src/database/record/attachments/normalize-input.d.ts +6 -1
  478. package/build/src/database/record/attachments/normalize-input.d.ts.map +1 -1
  479. package/build/src/database/record/attachments/normalize-input.js +54 -17
  480. package/build/src/database/record/attachments/storage-drivers/filesystem.d.ts +7 -1
  481. package/build/src/database/record/attachments/storage-drivers/filesystem.d.ts.map +1 -1
  482. package/build/src/database/record/attachments/storage-drivers/filesystem.js +10 -2
  483. package/build/src/database/record/attachments/storage-drivers/native.d.ts +12 -7
  484. package/build/src/database/record/attachments/storage-drivers/native.d.ts.map +1 -1
  485. package/build/src/database/record/attachments/storage-drivers/native.js +13 -6
  486. package/build/src/database/record/attachments/storage-drivers/s3.d.ts +18 -9
  487. package/build/src/database/record/attachments/storage-drivers/s3.d.ts.map +1 -1
  488. package/build/src/database/record/attachments/storage-drivers/s3.js +38 -13
  489. package/build/src/database/record/attachments/store.d.ts +48 -25
  490. package/build/src/database/record/attachments/store.d.ts.map +1 -1
  491. package/build/src/database/record/attachments/store.js +63 -25
  492. package/build/src/database/record/index.d.ts +388 -146
  493. package/build/src/database/record/index.d.ts.map +1 -1
  494. package/build/src/database/record/index.js +686 -248
  495. package/build/src/database/record/instance-relationships/base.d.ts +78 -19
  496. package/build/src/database/record/instance-relationships/base.d.ts.map +1 -1
  497. package/build/src/database/record/instance-relationships/base.js +98 -26
  498. package/build/src/database/record/instance-relationships/belongs-to.d.ts +1 -0
  499. package/build/src/database/record/instance-relationships/belongs-to.d.ts.map +1 -1
  500. package/build/src/database/record/instance-relationships/belongs-to.js +13 -5
  501. package/build/src/database/record/instance-relationships/has-many.d.ts +27 -7
  502. package/build/src/database/record/instance-relationships/has-many.d.ts.map +1 -1
  503. package/build/src/database/record/instance-relationships/has-many.js +50 -16
  504. package/build/src/database/record/instance-relationships/has-one.d.ts +4 -1
  505. package/build/src/database/record/instance-relationships/has-one.d.ts.map +1 -1
  506. package/build/src/database/record/instance-relationships/has-one.js +28 -10
  507. package/build/src/database/record/relationships/base.d.ts +61 -14
  508. package/build/src/database/record/relationships/base.d.ts.map +1 -1
  509. package/build/src/database/record/relationships/base.js +60 -15
  510. package/build/src/database/record/relationships/belongs-to.d.ts.map +1 -1
  511. package/build/src/database/record/relationships/belongs-to.js +9 -3
  512. package/build/src/database/record/relationships/has-many.d.ts.map +1 -1
  513. package/build/src/database/record/relationships/has-many.js +9 -3
  514. package/build/src/database/record/relationships/has-one.d.ts.map +1 -1
  515. package/build/src/database/record/relationships/has-one.js +9 -3
  516. package/build/src/database/record/state-machine.d.ts +9 -1
  517. package/build/src/database/record/state-machine.d.ts.map +1 -1
  518. package/build/src/database/record/state-machine.js +35 -14
  519. package/build/src/database/record/user-module.d.ts +2 -0
  520. package/build/src/database/record/user-module.d.ts.map +1 -1
  521. package/build/src/database/record/user-module.js +3 -1
  522. package/build/src/database/record/validators/base.d.ts +4 -2
  523. package/build/src/database/record/validators/base.d.ts.map +1 -1
  524. package/build/src/database/record/validators/base.js +4 -2
  525. package/build/src/database/record/validators/format.d.ts.map +1 -1
  526. package/build/src/database/record/validators/format.js +2 -1
  527. package/build/src/database/record/validators/presence.d.ts.map +1 -1
  528. package/build/src/database/record/validators/presence.js +5 -2
  529. package/build/src/database/record/validators/uniqueness.d.ts +0 -2
  530. package/build/src/database/record/validators/uniqueness.d.ts.map +1 -1
  531. package/build/src/database/record/validators/uniqueness.js +18 -8
  532. package/build/src/database/table-data/index.d.ts +40 -4
  533. package/build/src/database/table-data/index.d.ts.map +1 -1
  534. package/build/src/database/table-data/index.js +38 -5
  535. package/build/src/database/table-data/table-column.d.ts +43 -5
  536. package/build/src/database/table-data/table-column.d.ts.map +1 -1
  537. package/build/src/database/table-data/table-column.js +37 -4
  538. package/build/src/database/table-data/table-foreign-key.d.ts +8 -0
  539. package/build/src/database/table-data/table-foreign-key.d.ts.map +1 -1
  540. package/build/src/database/table-data/table-foreign-key.js +9 -1
  541. package/build/src/database/table-data/table-index.d.ts +8 -0
  542. package/build/src/database/table-data/table-index.d.ts.map +1 -1
  543. package/build/src/database/table-data/table-index.js +6 -1
  544. package/build/src/database/table-data/table-reference.d.ts +1 -0
  545. package/build/src/database/table-data/table-reference.d.ts.map +1 -1
  546. package/build/src/database/table-data/table-reference.js +2 -1
  547. package/build/src/database/use-database.d.ts +1 -0
  548. package/build/src/database/use-database.d.ts.map +1 -1
  549. package/build/src/database/use-database.js +2 -1
  550. package/build/src/environment-handlers/base.d.ts +94 -36
  551. package/build/src/environment-handlers/base.d.ts.map +1 -1
  552. package/build/src/environment-handlers/base.js +90 -36
  553. package/build/src/environment-handlers/browser.d.ts +33 -3
  554. package/build/src/environment-handlers/browser.d.ts.map +1 -1
  555. package/build/src/environment-handlers/browser.js +36 -9
  556. package/build/src/environment-handlers/node/cli/commands/cli-command-context.d.ts +5 -0
  557. package/build/src/environment-handlers/node/cli/commands/cli-command-context.d.ts.map +1 -1
  558. package/build/src/environment-handlers/node/cli/commands/cli-command-context.js +6 -2
  559. package/build/src/environment-handlers/node/cli/commands/console.d.ts +3 -2
  560. package/build/src/environment-handlers/node/cli/commands/console.d.ts.map +1 -1
  561. package/build/src/environment-handlers/node/cli/commands/console.js +23 -9
  562. package/build/src/environment-handlers/node/cli/commands/db/schema/dump.d.ts +4 -1
  563. package/build/src/environment-handlers/node/cli/commands/db/schema/dump.d.ts.map +1 -1
  564. package/build/src/environment-handlers/node/cli/commands/db/schema/dump.js +5 -2
  565. package/build/src/environment-handlers/node/cli/commands/db/schema/load.d.ts +6 -2
  566. package/build/src/environment-handlers/node/cli/commands/db/schema/load.d.ts.map +1 -1
  567. package/build/src/environment-handlers/node/cli/commands/db/schema/load.js +11 -5
  568. package/build/src/environment-handlers/node/cli/commands/db/seed.d.ts +15 -5
  569. package/build/src/environment-handlers/node/cli/commands/db/seed.d.ts.map +1 -1
  570. package/build/src/environment-handlers/node/cli/commands/db/seed.js +20 -6
  571. package/build/src/environment-handlers/node/cli/commands/destroy/migration.d.ts +5 -0
  572. package/build/src/environment-handlers/node/cli/commands/destroy/migration.d.ts.map +1 -1
  573. package/build/src/environment-handlers/node/cli/commands/destroy/migration.js +3 -1
  574. package/build/src/environment-handlers/node/cli/commands/generate/base-models.d.ts +2 -0
  575. package/build/src/environment-handlers/node/cli/commands/generate/base-models.d.ts.map +1 -1
  576. package/build/src/environment-handlers/node/cli/commands/generate/base-models.js +6 -4
  577. package/build/src/environment-handlers/node/cli/commands/generate/frontend-models.d.ts +43 -29
  578. package/build/src/environment-handlers/node/cli/commands/generate/frontend-models.d.ts.map +1 -1
  579. package/build/src/environment-handlers/node/cli/commands/generate/frontend-models.js +99 -40
  580. package/build/src/environment-handlers/node/cli/commands/generate/migration.d.ts +5 -0
  581. package/build/src/environment-handlers/node/cli/commands/generate/migration.d.ts.map +1 -1
  582. package/build/src/environment-handlers/node/cli/commands/generate/migration.js +3 -1
  583. package/build/src/environment-handlers/node/cli/commands/generate/model.d.ts +5 -0
  584. package/build/src/environment-handlers/node/cli/commands/generate/model.d.ts.map +1 -1
  585. package/build/src/environment-handlers/node/cli/commands/generate/model.js +3 -1
  586. package/build/src/environment-handlers/node/cli/commands/init.d.ts +5 -0
  587. package/build/src/environment-handlers/node/cli/commands/init.d.ts.map +1 -1
  588. package/build/src/environment-handlers/node/cli/commands/init.js +3 -1
  589. package/build/src/environment-handlers/node/cli/commands/routes.d.ts +3 -0
  590. package/build/src/environment-handlers/node/cli/commands/routes.d.ts.map +1 -1
  591. package/build/src/environment-handlers/node/cli/commands/routes.js +4 -1
  592. package/build/src/environment-handlers/node/cli/commands/run-script.d.ts +15 -5
  593. package/build/src/environment-handlers/node/cli/commands/run-script.d.ts.map +1 -1
  594. package/build/src/environment-handlers/node/cli/commands/run-script.js +20 -6
  595. package/build/src/environment-handlers/node/cli/commands/runner.d.ts +18 -6
  596. package/build/src/environment-handlers/node/cli/commands/runner.d.ts.map +1 -1
  597. package/build/src/environment-handlers/node/cli/commands/runner.js +20 -6
  598. package/build/src/environment-handlers/node/cli/commands/server.d.ts +13 -1
  599. package/build/src/environment-handlers/node/cli/commands/server.d.ts.map +1 -1
  600. package/build/src/environment-handlers/node/cli/commands/server.js +23 -6
  601. package/build/src/environment-handlers/node.d.ts +14 -2
  602. package/build/src/environment-handlers/node.d.ts.map +1 -1
  603. package/build/src/environment-handlers/node.js +107 -39
  604. package/build/src/error-logger.d.ts +4 -3
  605. package/build/src/error-logger.d.ts.map +1 -1
  606. package/build/src/error-logger.js +4 -3
  607. package/build/src/frontend-model-controller.d.ts +239 -90
  608. package/build/src/frontend-model-controller.d.ts.map +1 -1
  609. package/build/src/frontend-model-controller.js +577 -787
  610. package/build/src/frontend-model-resource/base-resource.d.ts +118 -66
  611. package/build/src/frontend-model-resource/base-resource.d.ts.map +1 -1
  612. package/build/src/frontend-model-resource/base-resource.js +205 -82
  613. package/build/src/frontend-models/base.d.ts +319 -163
  614. package/build/src/frontend-models/base.d.ts.map +1 -1
  615. package/build/src/frontend-models/base.js +717 -366
  616. package/build/src/frontend-models/clear-pending-debounced-callback.d.ts +2 -1
  617. package/build/src/frontend-models/clear-pending-debounced-callback.d.ts.map +1 -1
  618. package/build/src/frontend-models/clear-pending-debounced-callback.js +6 -3
  619. package/build/src/frontend-models/event-hook-models.d.ts +5 -0
  620. package/build/src/frontend-models/event-hook-models.d.ts.map +1 -1
  621. package/build/src/frontend-models/event-hook-models.js +10 -3
  622. package/build/src/frontend-models/model-registry.d.ts +5 -5
  623. package/build/src/frontend-models/model-registry.d.ts.map +1 -1
  624. package/build/src/frontend-models/model-registry.js +5 -5
  625. package/build/src/frontend-models/outgoing-event-buffer.d.ts +11 -3
  626. package/build/src/frontend-models/outgoing-event-buffer.d.ts.map +1 -1
  627. package/build/src/frontend-models/outgoing-event-buffer.js +13 -5
  628. package/build/src/frontend-models/preloader.d.ts +9 -6
  629. package/build/src/frontend-models/preloader.d.ts.map +1 -1
  630. package/build/src/frontend-models/preloader.js +21 -9
  631. package/build/src/frontend-models/query.d.ts +283 -73
  632. package/build/src/frontend-models/query.d.ts.map +1 -1
  633. package/build/src/frontend-models/query.js +331 -203
  634. package/build/src/frontend-models/resource-config-validation.d.ts +2 -0
  635. package/build/src/frontend-models/resource-config-validation.d.ts.map +1 -1
  636. package/build/src/frontend-models/resource-config-validation.js +3 -1
  637. package/build/src/frontend-models/resource-definition.d.ts +12 -5
  638. package/build/src/frontend-models/resource-definition.d.ts.map +1 -1
  639. package/build/src/frontend-models/resource-definition.js +39 -13
  640. package/build/src/frontend-models/transport-serialization.d.ts +14 -11
  641. package/build/src/frontend-models/transport-serialization.d.ts.map +1 -1
  642. package/build/src/frontend-models/transport-serialization.js +80 -53
  643. package/build/src/frontend-models/use-destroyed-event.d.ts +21 -0
  644. package/build/src/frontend-models/use-destroyed-event.d.ts.map +1 -1
  645. package/build/src/frontend-models/use-destroyed-event.js +34 -11
  646. package/build/src/frontend-models/use-model-class-event.d.ts +24 -0
  647. package/build/src/frontend-models/use-model-class-event.d.ts.map +1 -1
  648. package/build/src/frontend-models/use-model-class-event.js +39 -12
  649. package/build/src/frontend-models/use-updated-event.d.ts +21 -0
  650. package/build/src/frontend-models/use-updated-event.d.ts.map +1 -1
  651. package/build/src/frontend-models/use-updated-event.js +37 -12
  652. package/build/src/frontend-models/websocket-channel.d.ts +51 -9
  653. package/build/src/frontend-models/websocket-channel.d.ts.map +1 -1
  654. package/build/src/frontend-models/websocket-channel.js +96 -26
  655. package/build/src/frontend-models/websocket-publishers.d.ts +2 -0
  656. package/build/src/frontend-models/websocket-publishers.d.ts.map +1 -1
  657. package/build/src/frontend-models/websocket-publishers.js +33 -11
  658. package/build/src/http-client/header.d.ts +1 -0
  659. package/build/src/http-client/header.d.ts.map +1 -1
  660. package/build/src/http-client/header.js +2 -1
  661. package/build/src/http-client/index.d.ts +4 -0
  662. package/build/src/http-client/index.d.ts.map +1 -1
  663. package/build/src/http-client/index.js +5 -1
  664. package/build/src/http-client/request.d.ts +5 -0
  665. package/build/src/http-client/request.d.ts.map +1 -1
  666. package/build/src/http-client/request.js +6 -1
  667. package/build/src/http-client/response.d.ts +14 -4
  668. package/build/src/http-client/response.d.ts.map +1 -1
  669. package/build/src/http-client/response.js +14 -4
  670. package/build/src/http-client/websocket-client.d.ts +1 -0
  671. package/build/src/http-client/websocket-client.d.ts.map +1 -1
  672. package/build/src/http-client/websocket-client.js +2 -1
  673. package/build/src/http-server/client/index.d.ts +16 -2
  674. package/build/src/http-server/client/index.d.ts.map +1 -1
  675. package/build/src/http-server/client/index.js +44 -13
  676. package/build/src/http-server/client/params-to-object.d.ts +16 -10
  677. package/build/src/http-server/client/params-to-object.d.ts.map +1 -1
  678. package/build/src/http-server/client/params-to-object.js +46 -17
  679. package/build/src/http-server/client/request-buffer/form-data-part.d.ts +10 -6
  680. package/build/src/http-server/client/request-buffer/form-data-part.d.ts.map +1 -1
  681. package/build/src/http-server/client/request-buffer/form-data-part.js +11 -7
  682. package/build/src/http-server/client/request-buffer/header.d.ts +1 -0
  683. package/build/src/http-server/client/request-buffer/header.d.ts.map +1 -1
  684. package/build/src/http-server/client/request-buffer/header.js +2 -1
  685. package/build/src/http-server/client/request-buffer/index.d.ts +29 -4
  686. package/build/src/http-server/client/request-buffer/index.d.ts.map +1 -1
  687. package/build/src/http-server/client/request-buffer/index.js +43 -9
  688. package/build/src/http-server/client/request-parser.d.ts +52 -13
  689. package/build/src/http-server/client/request-parser.d.ts.map +1 -1
  690. package/build/src/http-server/client/request-parser.js +58 -15
  691. package/build/src/http-server/client/request-runner.d.ts +5 -1
  692. package/build/src/http-server/client/request-runner.d.ts.map +1 -1
  693. package/build/src/http-server/client/request-runner.js +32 -8
  694. package/build/src/http-server/client/request-timing.d.ts +37 -7
  695. package/build/src/http-server/client/request-timing.d.ts.map +1 -1
  696. package/build/src/http-server/client/request-timing.js +32 -8
  697. package/build/src/http-server/client/request.d.ts +15 -5
  698. package/build/src/http-server/client/request.d.ts.map +1 -1
  699. package/build/src/http-server/client/request.js +17 -5
  700. package/build/src/http-server/client/response.d.ts +22 -4
  701. package/build/src/http-server/client/response.d.ts.map +1 -1
  702. package/build/src/http-server/client/response.js +29 -7
  703. package/build/src/http-server/client/uploaded-file/memory-uploaded-file.d.ts +1 -0
  704. package/build/src/http-server/client/uploaded-file/memory-uploaded-file.d.ts.map +1 -1
  705. package/build/src/http-server/client/uploaded-file/memory-uploaded-file.js +3 -1
  706. package/build/src/http-server/client/uploaded-file/temporary-uploaded-file.d.ts +1 -0
  707. package/build/src/http-server/client/uploaded-file/temporary-uploaded-file.d.ts.map +1 -1
  708. package/build/src/http-server/client/uploaded-file/temporary-uploaded-file.js +3 -1
  709. package/build/src/http-server/client/uploaded-file/uploaded-file.d.ts +2 -0
  710. package/build/src/http-server/client/uploaded-file/uploaded-file.d.ts.map +1 -1
  711. package/build/src/http-server/client/uploaded-file/uploaded-file.js +3 -1
  712. package/build/src/http-server/client/websocket-request.d.ts +24 -12
  713. package/build/src/http-server/client/websocket-request.d.ts.map +1 -1
  714. package/build/src/http-server/client/websocket-request.js +24 -10
  715. package/build/src/http-server/client/websocket-session.d.ts +101 -62
  716. package/build/src/http-server/client/websocket-session.d.ts.map +1 -1
  717. package/build/src/http-server/client/websocket-session.js +118 -61
  718. package/build/src/http-server/cookie.d.ts +36 -8
  719. package/build/src/http-server/cookie.d.ts.map +1 -1
  720. package/build/src/http-server/cookie.js +37 -9
  721. package/build/src/http-server/development-reloader.d.ts +32 -7
  722. package/build/src/http-server/development-reloader.d.ts.map +1 -1
  723. package/build/src/http-server/development-reloader.js +39 -10
  724. package/build/src/http-server/index.d.ts +102 -25
  725. package/build/src/http-server/index.d.ts.map +1 -1
  726. package/build/src/http-server/index.js +117 -32
  727. package/build/src/http-server/remote-address.d.ts +1 -0
  728. package/build/src/http-server/remote-address.d.ts.map +1 -1
  729. package/build/src/http-server/remote-address.js +15 -4
  730. package/build/src/http-server/server-client.d.ts +37 -8
  731. package/build/src/http-server/server-client.d.ts.map +1 -1
  732. package/build/src/http-server/server-client.js +48 -12
  733. package/build/src/http-server/server-lock.d.ts +76 -0
  734. package/build/src/http-server/server-lock.d.ts.map +1 -0
  735. package/build/src/http-server/server-lock.js +164 -0
  736. package/build/src/http-server/websocket-channel-subscribers.d.ts +13 -8
  737. package/build/src/http-server/websocket-channel-subscribers.d.ts.map +1 -1
  738. package/build/src/http-server/websocket-channel-subscribers.js +16 -7
  739. package/build/src/http-server/websocket-channel.d.ts +13 -11
  740. package/build/src/http-server/websocket-channel.d.ts.map +1 -1
  741. package/build/src/http-server/websocket-channel.js +8 -12
  742. package/build/src/http-server/websocket-connection.d.ts +10 -14
  743. package/build/src/http-server/websocket-connection.d.ts.map +1 -1
  744. package/build/src/http-server/websocket-connection.js +8 -12
  745. package/build/src/http-server/websocket-event-log-store.d.ts +48 -10
  746. package/build/src/http-server/websocket-event-log-store.d.ts.map +1 -1
  747. package/build/src/http-server/websocket-event-log-store.js +76 -34
  748. package/build/src/http-server/websocket-events-host.d.ts +21 -15
  749. package/build/src/http-server/websocket-events-host.d.ts.map +1 -1
  750. package/build/src/http-server/websocket-events-host.js +20 -11
  751. package/build/src/http-server/websocket-events.d.ts +8 -7
  752. package/build/src/http-server/websocket-events.d.ts.map +1 -1
  753. package/build/src/http-server/websocket-events.js +6 -5
  754. package/build/src/http-server/worker-handler/channel-subscriber-dispatch.d.ts +3 -2
  755. package/build/src/http-server/worker-handler/channel-subscriber-dispatch.d.ts.map +1 -1
  756. package/build/src/http-server/worker-handler/channel-subscriber-dispatch.js +3 -2
  757. package/build/src/http-server/worker-handler/in-process.d.ts +18 -18
  758. package/build/src/http-server/worker-handler/in-process.d.ts.map +1 -1
  759. package/build/src/http-server/worker-handler/in-process.js +28 -20
  760. package/build/src/http-server/worker-handler/index.d.ts +39 -20
  761. package/build/src/http-server/worker-handler/index.d.ts.map +1 -1
  762. package/build/src/http-server/worker-handler/index.js +34 -14
  763. package/build/src/http-server/worker-handler/worker-thread.d.ts +31 -15
  764. package/build/src/http-server/worker-handler/worker-thread.d.ts.map +1 -1
  765. package/build/src/http-server/worker-handler/worker-thread.js +31 -12
  766. package/build/src/initializer.d.ts +4 -0
  767. package/build/src/initializer.d.ts.map +1 -1
  768. package/build/src/initializer.js +5 -1
  769. package/build/src/jobs/mail-delivery.d.ts +1 -0
  770. package/build/src/jobs/mail-delivery.d.ts.map +1 -1
  771. package/build/src/jobs/mail-delivery.js +2 -1
  772. package/build/src/logger/base-logger.js +2 -2
  773. package/build/src/logger/console-logger.d.ts +2 -0
  774. package/build/src/logger/console-logger.d.ts.map +1 -1
  775. package/build/src/logger/console-logger.js +3 -1
  776. package/build/src/logger/file-logger.d.ts +2 -0
  777. package/build/src/logger/file-logger.d.ts.map +1 -1
  778. package/build/src/logger/file-logger.js +3 -1
  779. package/build/src/logger/outputs/array-output.d.ts +21 -5
  780. package/build/src/logger/outputs/array-output.d.ts.map +1 -1
  781. package/build/src/logger/outputs/array-output.js +19 -6
  782. package/build/src/logger/outputs/console-output.d.ts +10 -2
  783. package/build/src/logger/outputs/console-output.d.ts.map +1 -1
  784. package/build/src/logger/outputs/console-output.js +8 -3
  785. package/build/src/logger/outputs/file-output.d.ts +20 -5
  786. package/build/src/logger/outputs/file-output.d.ts.map +1 -1
  787. package/build/src/logger/outputs/file-output.js +18 -6
  788. package/build/src/logger/outputs/stdout-output.d.ts +7 -1
  789. package/build/src/logger/outputs/stdout-output.d.ts.map +1 -1
  790. package/build/src/logger/outputs/stdout-output.js +9 -3
  791. package/build/src/logger.d.ts +28 -13
  792. package/build/src/logger.d.ts.map +1 -1
  793. package/build/src/logger.js +60 -23
  794. package/build/src/mailer/backends/smtp.d.ts +5 -0
  795. package/build/src/mailer/backends/smtp.d.ts.map +1 -1
  796. package/build/src/mailer/backends/smtp.js +17 -4
  797. package/build/src/mailer/base.d.ts +33 -17
  798. package/build/src/mailer/base.d.ts.map +1 -1
  799. package/build/src/mailer/base.js +54 -18
  800. package/build/src/mailer/delivery.d.ts +16 -5
  801. package/build/src/mailer/delivery.d.ts.map +1 -1
  802. package/build/src/mailer/delivery.js +18 -7
  803. package/build/src/mailer/index.d.ts +5 -5
  804. package/build/src/mailer/index.d.ts.map +1 -1
  805. package/build/src/mailer/index.js +2 -2
  806. package/build/src/mailer.d.ts +5 -5
  807. package/build/src/mailer.d.ts.map +1 -1
  808. package/build/src/mailer.js +2 -2
  809. package/build/src/plugins/sqljs-wasm-route-controller.d.ts +4 -1
  810. package/build/src/plugins/sqljs-wasm-route-controller.d.ts.map +1 -1
  811. package/build/src/plugins/sqljs-wasm-route-controller.js +11 -4
  812. package/build/src/plugins/sqljs-wasm-route.d.ts +6 -0
  813. package/build/src/plugins/sqljs-wasm-route.d.ts.map +1 -1
  814. package/build/src/plugins/sqljs-wasm-route.js +4 -1
  815. package/build/src/record-payload-values.d.ts +54 -0
  816. package/build/src/record-payload-values.d.ts.map +1 -0
  817. package/build/src/record-payload-values.js +80 -0
  818. package/build/src/routes/app-routes.d.ts +1 -0
  819. package/build/src/routes/app-routes.d.ts.map +1 -1
  820. package/build/src/routes/app-routes.js +2 -1
  821. package/build/src/routes/base-route.d.ts +52 -16
  822. package/build/src/routes/base-route.d.ts.map +1 -1
  823. package/build/src/routes/base-route.js +50 -14
  824. package/build/src/routes/basic-route.d.ts +1 -0
  825. package/build/src/routes/basic-route.d.ts.map +1 -1
  826. package/build/src/routes/basic-route.js +13 -4
  827. package/build/src/routes/built-in/debug/controller.d.ts +4 -1
  828. package/build/src/routes/built-in/debug/controller.d.ts.map +1 -1
  829. package/build/src/routes/built-in/debug/controller.js +5 -2
  830. package/build/src/routes/get-route.d.ts +1 -0
  831. package/build/src/routes/get-route.d.ts.map +1 -1
  832. package/build/src/routes/get-route.js +7 -4
  833. package/build/src/routes/hooks/frontend-model-command-route-hook.d.ts +1 -0
  834. package/build/src/routes/hooks/frontend-model-command-route-hook.d.ts.map +1 -1
  835. package/build/src/routes/hooks/frontend-model-command-route-hook.js +6 -2
  836. package/build/src/routes/index.d.ts +3 -2
  837. package/build/src/routes/index.d.ts.map +1 -1
  838. package/build/src/routes/index.js +10 -4
  839. package/build/src/routes/namespace-route.d.ts +1 -0
  840. package/build/src/routes/namespace-route.d.ts.map +1 -1
  841. package/build/src/routes/namespace-route.js +5 -3
  842. package/build/src/routes/plugin-routes.d.ts +10 -1
  843. package/build/src/routes/plugin-routes.d.ts.map +1 -1
  844. package/build/src/routes/plugin-routes.js +11 -3
  845. package/build/src/routes/post-route.d.ts +1 -0
  846. package/build/src/routes/post-route.d.ts.map +1 -1
  847. package/build/src/routes/post-route.js +7 -4
  848. package/build/src/routes/resolver.d.ts +20 -5
  849. package/build/src/routes/resolver.d.ts.map +1 -1
  850. package/build/src/routes/resolver.js +47 -14
  851. package/build/src/routes/resource-route.d.ts +6 -1
  852. package/build/src/routes/resource-route.d.ts.map +1 -1
  853. package/build/src/routes/resource-route.js +10 -4
  854. package/build/src/testing/base-expect.d.ts +2 -0
  855. package/build/src/testing/base-expect.d.ts.map +1 -1
  856. package/build/src/testing/base-expect.js +3 -1
  857. package/build/src/testing/browser-frontend-model-event-hook-scenarios.d.ts +33 -5
  858. package/build/src/testing/browser-frontend-model-event-hook-scenarios.d.ts.map +1 -1
  859. package/build/src/testing/browser-frontend-model-event-hook-scenarios.js +95 -23
  860. package/build/src/testing/expect-to-change.d.ts +3 -0
  861. package/build/src/testing/expect-to-change.d.ts.map +1 -1
  862. package/build/src/testing/expect-to-change.js +4 -1
  863. package/build/src/testing/expect-utils.d.ts +22 -16
  864. package/build/src/testing/expect-utils.d.ts.map +1 -1
  865. package/build/src/testing/expect-utils.js +62 -30
  866. package/build/src/testing/expect.d.ts +50 -21
  867. package/build/src/testing/expect.d.ts.map +1 -1
  868. package/build/src/testing/expect.js +58 -17
  869. package/build/src/testing/request-client.d.ts +16 -3
  870. package/build/src/testing/request-client.d.ts.map +1 -1
  871. package/build/src/testing/request-client.js +17 -4
  872. package/build/src/testing/test-files-finder.d.ts +41 -9
  873. package/build/src/testing/test-files-finder.d.ts.map +1 -1
  874. package/build/src/testing/test-files-finder.js +42 -10
  875. package/build/src/testing/test-filter-parser.d.ts +6 -0
  876. package/build/src/testing/test-filter-parser.d.ts.map +1 -1
  877. package/build/src/testing/test-filter-parser.js +12 -3
  878. package/build/src/testing/test-runner.d.ts +102 -6
  879. package/build/src/testing/test-runner.d.ts.map +1 -1
  880. package/build/src/testing/test-runner.js +115 -23
  881. package/build/src/testing/test-suite-splitter.d.ts +7 -0
  882. package/build/src/testing/test-suite-splitter.d.ts.map +1 -1
  883. package/build/src/testing/test-suite-splitter.js +7 -2
  884. package/build/src/testing/test.d.ts +20 -4
  885. package/build/src/testing/test.d.ts.map +1 -1
  886. package/build/src/testing/test.js +67 -20
  887. package/build/src/utils/backtrace-cleaner-node.d.ts.map +1 -1
  888. package/build/src/utils/backtrace-cleaner-node.js +6 -1
  889. package/build/src/utils/backtrace-cleaner.d.ts +16 -1
  890. package/build/src/utils/backtrace-cleaner.d.ts.map +1 -1
  891. package/build/src/utils/backtrace-cleaner.js +20 -2
  892. package/build/src/utils/ensure-error.d.ts +3 -2
  893. package/build/src/utils/ensure-error.d.ts.map +1 -1
  894. package/build/src/utils/ensure-error.js +3 -2
  895. package/build/src/utils/event-emitter.d.ts.map +1 -1
  896. package/build/src/utils/event-emitter.js +2 -2
  897. package/build/src/utils/file-exists.d.ts +1 -0
  898. package/build/src/utils/file-exists.d.ts.map +1 -1
  899. package/build/src/utils/file-exists.js +2 -1
  900. package/build/src/utils/format-value.d.ts +5 -4
  901. package/build/src/utils/format-value.d.ts.map +1 -1
  902. package/build/src/utils/format-value.js +12 -7
  903. package/build/src/utils/model-scope.d.ts +18 -12
  904. package/build/src/utils/model-scope.d.ts.map +1 -1
  905. package/build/src/utils/model-scope.js +19 -11
  906. package/build/src/utils/nest-callbacks.d.ts +1 -0
  907. package/build/src/utils/nest-callbacks.d.ts.map +1 -1
  908. package/build/src/utils/nest-callbacks.js +2 -1
  909. package/build/src/utils/plain-object.d.ts +7 -0
  910. package/build/src/utils/plain-object.d.ts.map +1 -0
  911. package/build/src/utils/plain-object.js +13 -0
  912. package/build/src/utils/ransack.d.ts +29 -5
  913. package/build/src/utils/ransack.d.ts.map +1 -1
  914. package/build/src/utils/ransack.js +136 -49
  915. package/build/src/utils/rest-args-error.d.ts +1 -0
  916. package/build/src/utils/rest-args-error.d.ts.map +1 -1
  917. package/build/src/utils/rest-args-error.js +2 -1
  918. package/build/src/utils/singularize-model-name.d.ts +1 -0
  919. package/build/src/utils/singularize-model-name.d.ts.map +1 -1
  920. package/build/src/utils/singularize-model-name.js +2 -1
  921. package/build/src/utils/to-import-specifier.d.ts.map +1 -1
  922. package/build/src/utils/to-import-specifier.js +3 -1
  923. package/build/src/utils/with-tracked-stack-async-hooks.d.ts +8 -5
  924. package/build/src/utils/with-tracked-stack-async-hooks.d.ts.map +1 -1
  925. package/build/src/utils/with-tracked-stack-async-hooks.js +32 -13
  926. package/build/src/utils/with-tracked-stack.d.ts +9 -5
  927. package/build/src/utils/with-tracked-stack.d.ts.map +1 -1
  928. package/build/src/utils/with-tracked-stack.js +19 -8
  929. package/build/src/velocious-error.d.ts +4 -2
  930. package/build/src/velocious-error.d.ts.map +1 -1
  931. package/build/src/velocious-error.js +5 -3
  932. package/build/tsconfig.tsbuildinfo +1 -1
  933. package/package.json +1 -1
@@ -4,165 +4,40 @@ import Controller from "./controller.js";
4
4
  import Response from "./http-server/client/response.js";
5
5
  import FrontendModelBaseResource from "./frontend-model-resource/base-resource.js";
6
6
  import { frontendModelResourceClassFromDefinition, frontendModelResourceConfigurationFromDefinition, frontendModelResourcePath, frontendModelResourcesForBackendProject } from "./frontend-models/resource-definition.js";
7
+ import { normalizeGroup as normalizeQueryGroup, normalizeJoins as normalizeQueryJoins, normalizePluck as normalizeQueryPluck, normalizePreload as normalizeQueryPreload, normalizeSearchOperator as normalizeQuerySearchOperator, normalizeSort as normalizeQuerySort } from "./frontend-models/query.js";
7
8
  import { assignSafeProperty, deserializeFrontendModelTransportValue, isBackendModelInstance, serializeFrontendModelTransportValue } from "./frontend-models/transport-serialization.js";
8
9
  import RoutesResolver from "./routes/resolver.js";
9
10
  import { ValidationError } from "./database/record/index.js";
10
11
  import VelociousError from "./velocious-error.js";
12
+ import isPlainObject from "./utils/plain-object.js";
11
13
  /**
12
- * @param {unknown} value - Candidate value.
13
- * @returns {value is Record<string, any>} - Whether value is a plain object.
14
- */
15
- function isPlainObject(value) {
16
- if (!value || typeof value !== "object" || Array.isArray(value))
17
- return false;
18
- const prototype = Object.getPrototypeOf(value);
19
- return prototype === Object.prototype || prototype === null;
20
- }
21
- /**
14
+ * Runs normalize frontend model preload.
22
15
  * @param {import("./database/query/index.js").NestedPreloadRecord | string | string[] | boolean | undefined | null} preload - Preload shorthand.
23
16
  * @returns {import("./database/query/index.js").NestedPreloadRecord | null} - Normalized preload.
24
17
  */
25
18
  function normalizeFrontendModelPreload(preload) {
26
19
  if (!preload)
27
20
  return null;
28
- if (preload === true)
29
- return {};
30
- if (typeof preload === "string") {
31
- return { [preload]: true };
32
- }
33
- if (Array.isArray(preload)) {
34
- /** @type {import("./database/query/index.js").NestedPreloadRecord} */
35
- const normalized = {};
36
- for (const entry of preload) {
37
- if (typeof entry === "string") {
38
- normalized[entry] = true;
39
- continue;
40
- }
41
- if (isPlainObject(entry)) {
42
- const nested = normalizeFrontendModelPreload(entry);
43
- if (nested) {
44
- mergeNormalizedPreload(normalized, nested);
45
- }
46
- continue;
47
- }
48
- throw frontendModelValidationError(`Invalid preload entry type: ${typeof entry}`);
49
- }
50
- return normalized;
51
- }
52
- if (!isPlainObject(preload)) {
53
- throw frontendModelValidationError(`Invalid preload type: ${typeof preload}`);
54
- }
55
- /** @type {import("./database/query/index.js").NestedPreloadRecord} */
56
- const normalized = {};
57
- for (const [relationshipName, relationshipPreload] of Object.entries(preload)) {
58
- if (relationshipPreload === true || relationshipPreload === false) {
59
- normalized[relationshipName] = relationshipPreload;
60
- continue;
61
- }
62
- if (typeof relationshipPreload === "string" || Array.isArray(relationshipPreload) || isPlainObject(relationshipPreload)) {
63
- const nested = normalizeFrontendModelPreload(relationshipPreload);
64
- normalized[relationshipName] = nested || {};
65
- continue;
66
- }
67
- throw frontendModelValidationError(`Invalid preload value for ${relationshipName}: ${typeof relationshipPreload}`);
68
- }
69
- return normalized;
21
+ return normalizeQueryPreload(preload);
70
22
  }
71
23
  /**
72
- * @param {import("./database/query/index.js").NestedPreloadRecord} target - Target preload object.
73
- * @param {import("./database/query/index.js").NestedPreloadRecord} source - Source preload object.
74
- * @returns {void} - Mutates target with merged nested preload tree.
75
- */
76
- function mergeNormalizedPreload(target, source) {
77
- for (const [relationshipName, relationshipPreload] of Object.entries(source)) {
78
- const existingValue = target[relationshipName];
79
- if (relationshipPreload === false) {
80
- target[relationshipName] = false;
81
- continue;
82
- }
83
- if (relationshipPreload === true) {
84
- if (existingValue === undefined) {
85
- target[relationshipName] = true;
86
- }
87
- continue;
88
- }
89
- if (!isPlainObject(relationshipPreload)) {
90
- throw frontendModelValidationError(`Invalid preload value for ${relationshipName}: ${typeof relationshipPreload}`);
91
- }
92
- if (isPlainObject(existingValue)) {
93
- mergeNormalizedPreload(
94
- /** @type {import("./database/query/index.js").NestedPreloadRecord} */ (existingValue),
95
- /** @type {import("./database/query/index.js").NestedPreloadRecord} */ (relationshipPreload));
96
- continue;
97
- }
98
- target[relationshipName] = relationshipPreload;
99
- }
100
- }
101
- /**
102
- * @param {Record<string, any>} target - Target joins object.
103
- * @param {Record<string, any>} source - Source joins object.
104
- * @returns {void} - Mutates target with merged nested joins tree.
105
- */
106
- function mergeNormalizedJoins(target, source) {
107
- for (const [relationshipName, relationshipJoin] of Object.entries(source)) {
108
- const existingValue = target[relationshipName];
109
- if (relationshipJoin === true) {
110
- if (existingValue === undefined) {
111
- target[relationshipName] = true;
112
- }
113
- continue;
114
- }
115
- if (!isPlainObject(relationshipJoin)) {
116
- throw frontendModelValidationError(`Invalid join definition for "${relationshipName}": ${typeof relationshipJoin}`);
117
- }
118
- if (isPlainObject(existingValue)) {
119
- mergeNormalizedJoins(existingValue, relationshipJoin);
120
- continue;
121
- }
122
- target[relationshipName] = relationshipJoin;
123
- }
124
- }
125
- /**
126
- * @param {unknown} joins - Joins payload.
127
- * @returns {Record<string, any> | null} - Normalized relationship-object joins.
24
+ * Runs normalize frontend model joins.
25
+ * @param {?} joins - Joins payload.
26
+ * @returns {Record<string, ?> | null} - Normalized relationship-object joins.
128
27
  */
129
28
  function normalizeFrontendModelJoins(joins) {
130
29
  if (!joins)
131
30
  return null;
132
- if (Array.isArray(joins)) {
133
- /** @type {Record<string, any>} */
134
- const normalized = {};
135
- for (const joinEntry of joins) {
136
- if (!isPlainObject(joinEntry)) {
137
- throw frontendModelValidationError(`Invalid joins entry type: ${typeof joinEntry}`);
138
- }
139
- const nested = normalizeFrontendModelJoins(joinEntry);
140
- if (nested) {
141
- mergeNormalizedJoins(normalized, nested);
142
- }
143
- }
144
- return normalized;
31
+ try {
32
+ return normalizeQueryJoins(joins);
145
33
  }
146
- if (!isPlainObject(joins)) {
147
- throw frontendModelValidationError(`Invalid joins type: ${typeof joins}`);
34
+ catch (error) {
35
+ throw frontendModelValidationErrorForError(error);
148
36
  }
149
- /** @type {Record<string, any>} */
150
- const normalized = {};
151
- for (const [relationshipName, relationshipJoin] of Object.entries(joins)) {
152
- if (relationshipJoin === true) {
153
- normalized[relationshipName] = true;
154
- continue;
155
- }
156
- if (isPlainObject(relationshipJoin)) {
157
- normalized[relationshipName] = normalizeFrontendModelJoins(relationshipJoin) || {};
158
- continue;
159
- }
160
- throw frontendModelValidationError(`Invalid join definition for "${relationshipName}": ${typeof relationshipJoin}`);
161
- }
162
- return normalized;
163
37
  }
164
38
  /**
165
- * @param {unknown} select - Select payload.
39
+ * Runs normalize frontend model select.
40
+ * @param {?} select - Select payload.
166
41
  * @param {string | null} [rootModelName] - Optional root model name for shorthand payloads.
167
42
  * @returns {Record<string, string[]> | null} - Normalized model-name keyed select record.
168
43
  */
@@ -189,7 +64,9 @@ function normalizeFrontendModelSelect(select, rootModelName = null) {
189
64
  if (!isPlainObject(select)) {
190
65
  throw frontendModelValidationError(`Invalid select type: ${typeof select}`);
191
66
  }
192
- /** @type {Record<string, string[]>} */
67
+ /**
68
+ * Normalized.
69
+ @type {Record<string, string[]>} */
193
70
  const normalized = {};
194
71
  for (const [modelName, selectValue] of Object.entries(select)) {
195
72
  if (typeof selectValue === "string") {
@@ -209,47 +86,34 @@ function normalizeFrontendModelSelect(select, rootModelName = null) {
209
86
  return normalized;
210
87
  }
211
88
  /**
89
+ * FrontendModelSearch type.
212
90
  * @typedef {object} FrontendModelSearch
213
91
  * @property {string[]} path - Relationship path.
214
92
  * @property {string} column - Column or attribute name.
215
93
  * @property {"eq" | "like" | "notEq" | "gt" | "gteq" | "lt" | "lteq"} operator - Search operator.
216
- * @property {any} value - Search value.
94
+ * @property {?} value - Search value.
217
95
  */
218
96
  /**
219
- * @param {string} operator - Raw search operator.
220
- * @returns {FrontendModelSearch["operator"]} - Normalized search operator.
221
- */
222
- function normalizeFrontendModelSearchOperator(operator) {
223
- const operatorAliases = {
224
- "<": "lt",
225
- "<=": "lteq",
226
- ">": "gt",
227
- ">=": "gteq"
228
- };
229
- const normalizedOperator = operatorAliases[ /** @type {"<" | "<=" | ">" | ">="} */(operator)] || operator;
230
- const supportedOperators = new Set(["eq", "like", "notEq", "gt", "gteq", "lt", "lteq"]);
231
- if (!supportedOperators.has(normalizedOperator)) {
232
- throw frontendModelValidationError(`Invalid search operator: ${operator}`);
233
- }
234
- return /** @type {FrontendModelSearch["operator"]} */ (normalizedOperator);
235
- }
236
- /**
97
+ * FrontendModelSort type.
237
98
  * @typedef {object} FrontendModelSort
238
99
  * @property {string} column - Attribute name to sort by.
239
100
  * @property {"asc" | "desc"} direction - Sort direction.
240
101
  * @property {string[]} path - Relationship path from root model.
241
102
  */
242
103
  /**
104
+ * FrontendModelGroup type.
243
105
  * @typedef {object} FrontendModelGroup
244
106
  * @property {string} column - Attribute name to group by.
245
107
  * @property {string[]} path - Relationship path from root model.
246
108
  */
247
109
  /**
110
+ * FrontendModelPluck type.
248
111
  * @typedef {object} FrontendModelPluck
249
112
  * @property {string} column - Attribute name to pluck.
250
113
  * @property {string[]} path - Relationship path from root model.
251
114
  */
252
115
  /**
116
+ * FrontendModelPagination type.
253
117
  * @typedef {object} FrontendModelPagination
254
118
  * @property {number | null} limit - Maximum number of records.
255
119
  * @property {number | null} offset - Number of records to skip.
@@ -262,43 +126,66 @@ const frontendModelWhereNoMatchSymbol = Symbol("frontendModelWhereNoMatch");
262
126
  const frontendModelClientSafeErrorMessage = "Request failed.";
263
127
  const frontendModelDebugErrorEnvironments = new Set(["development", "test"]);
264
128
  /**
129
+ * Runs frontend model query metadata.
265
130
  * @param {import("./database/query/model-class-query.js").default} query - Query instance.
266
131
  * @returns {import("./database/query/model-class-query.js").default & {[frontendModelJoinedPathsSymbol]?: Set<string>, [frontendModelGroupedColumnsSymbol]?: Set<string>}} - Query metadata access helper.
267
132
  */
268
133
  function frontendModelQueryMetadata(query) {
269
- return /** @type {import("./database/query/model-class-query.js").default & {[frontendModelJoinedPathsSymbol]?: Set<string>, [frontendModelGroupedColumnsSymbol]?: Set<string>}} */ (query);
134
+ return /** Narrows the runtime value to the documented type. @type {import("./database/query/model-class-query.js").default & {[frontendModelJoinedPathsSymbol]?: Set<string>, [frontendModelGroupedColumnsSymbol]?: Set<string>}} */ (query);
270
135
  }
271
136
  /**
137
+ * Runs frontend model validation error.
272
138
  * @param {string} message - Validation error message.
273
139
  * @returns {VelociousError} - Client-safe validation error.
274
140
  */
275
141
  function frontendModelValidationError(message) {
276
142
  return VelociousError.safe(message, { code: "frontend-model-validation" });
277
143
  }
144
+ /**
145
+ * Runs frontend model validation error for error.
146
+ * @param {?} error - Error raised while normalizing client query params.
147
+ * @returns {VelociousError} - Client-safe validation error preserving the normalizer message.
148
+ */
149
+ function frontendModelValidationErrorForError(error) {
150
+ if (error instanceof VelociousError && error.safeToExpose)
151
+ return error;
152
+ const message = error instanceof Error
153
+ ? error.message
154
+ : String(error);
155
+ return frontendModelValidationError(message);
156
+ }
278
157
  /**
279
158
  * Whether the error carries an `error.velocious` metadata bag. The
280
159
  * presence of any such bag marks the error as "annotated by the
281
160
  * developer for the frontend" — the framework treats it as
282
161
  * user-facing: surface the message, forward the metadata, and skip
283
162
  * the noisy endpoint-error log.
284
- *
285
- * @param {unknown} error - Caught error.
163
+ * @param {?} error - Caught error.
286
164
  * @returns {boolean}
287
165
  */
288
166
  function frontendModelErrorHasVelociousMetadata(error) {
289
- return Boolean(error && typeof error === "object" && /** @type {any} */ (error).velocious && typeof /** @type {any} */ (error).velocious === "object");
167
+ return Boolean(error && typeof error === "object" && /**
168
+ * Types the following value.
169
+ @type {?} */
170
+ (error).velocious && typeof /**
171
+ * Types the following value.
172
+ @type {?} */ (error).velocious === "object");
290
173
  }
291
174
  /**
292
- * @param {unknown} error - Caught error.
293
- * @returns {Record<string, any> | null}
175
+ * Runs frontend model velocious metadata for error.
176
+ * @param {?} error - Caught error.
177
+ * @returns {Record<string, ?> | null}
294
178
  */
295
179
  function frontendModelVelociousMetadataForError(error) {
296
180
  if (!frontendModelErrorHasVelociousMetadata(error))
297
181
  return null;
298
- return /** @type {Record<string, any>} */ ( /** @type {any} */(error).velocious);
182
+ return /** Narrows the runtime value to the documented type. @type {Record<string, ?>} */ ( /**
183
+ * Types the following value.
184
+ @type {?} */(error).velocious);
299
185
  }
300
186
  /**
301
- * @param {unknown} error - Caught error.
187
+ * Runs frontend model client message for error.
188
+ * @param {?} error - Caught error.
302
189
  * @returns {string} - Message safe to return to API clients.
303
190
  */
304
191
  function frontendModelClientMessageForError(error) {
@@ -311,11 +198,12 @@ function frontendModelClientMessageForError(error) {
311
198
  return frontendModelClientSafeErrorMessage;
312
199
  }
313
200
  /**
201
+ * Runs frontend model debug payload for error.
314
202
  * @param {object} args - Arguments.
315
203
  * @param {import("./configuration.js").default} args.configuration - Current configuration.
316
204
  * @param {string} args.environment - Current environment.
317
- * @param {unknown} args.error - Caught error.
318
- * @returns {Record<string, any>} - Optional debug payload for non-production environments.
205
+ * @param {?} args.error - Caught error.
206
+ * @returns {Record<string, ?>} - Optional debug payload for non-production environments.
319
207
  */
320
208
  function frontendModelDebugPayloadForError({ configuration, environment, error }) {
321
209
  const debugAllowed = frontendModelDebugErrorEnvironments.has(environment) || environment !== "production" && configuration.getExposeInternalErrorsToClients();
@@ -344,215 +232,8 @@ function frontendModelDebugPayloadForError({ configuration, environment, error }
344
232
  };
345
233
  }
346
234
  /**
347
- * @param {unknown} direction - Direction candidate.
348
- * @returns {"asc" | "desc"} - Normalized direction.
349
- */
350
- function normalizeFrontendModelSortDirection(direction) {
351
- if (typeof direction !== "string") {
352
- throw frontendModelValidationError(`Invalid sort direction type: ${typeof direction}`);
353
- }
354
- const normalizedDirection = direction.trim().toLowerCase();
355
- if (normalizedDirection !== "asc" && normalizedDirection !== "desc") {
356
- throw frontendModelValidationError(`Invalid sort direction: ${direction}`);
357
- }
358
- return normalizedDirection;
359
- }
360
- /**
361
- * @param {unknown} value - Candidate tuple.
362
- * @returns {value is [string, string]} - Whether candidate is a sort tuple.
363
- */
364
- function frontendModelSortTuple(value) {
365
- if (!Array.isArray(value))
366
- return false;
367
- if (value.length !== 2)
368
- return false;
369
- if (typeof value[0] !== "string")
370
- return false;
371
- if (typeof value[1] !== "string")
372
- return false;
373
- if (value[0].trim().length < 1)
374
- return false;
375
- const direction = value[1].trim().toLowerCase();
376
- return direction === "asc" || direction === "desc";
377
- }
378
- /**
379
- * @param {unknown} value - Candidate descriptor.
380
- * @returns {value is {column: string, direction: string, path: string[]}} - Whether candidate is an explicit sort descriptor object.
381
- */
382
- function frontendModelSortDescriptor(value) {
383
- if (!isPlainObject(value))
384
- return false;
385
- if (!("column" in value) || !("direction" in value) || !("path" in value))
386
- return false;
387
- if (typeof value.column !== "string")
388
- return false;
389
- if (typeof value.direction !== "string")
390
- return false;
391
- if (!Array.isArray(value.path))
392
- return false;
393
- return value.path.every((pathEntry) => typeof pathEntry === "string");
394
- }
395
- /**
396
- * @param {unknown} value - Candidate descriptor.
397
- * @returns {value is {column: string, path: string[]}} - Whether candidate is an explicit group descriptor object.
398
- */
399
- function frontendModelGroupDescriptor(value) {
400
- if (!isPlainObject(value))
401
- return false;
402
- if (!("column" in value) || !("path" in value))
403
- return false;
404
- if (typeof value.column !== "string")
405
- return false;
406
- if (!Array.isArray(value.path))
407
- return false;
408
- return value.path.every((pathEntry) => typeof pathEntry === "string");
409
- }
410
- /**
411
- * @param {string} sortValue - Sort string.
412
- * @param {string[]} [path] - Relationship path.
413
- * @returns {FrontendModelSort} - Normalized sort descriptor.
414
- */
415
- function frontendModelSortFromString(sortValue, path = []) {
416
- const trimmed = sortValue.trim();
417
- if (trimmed.length < 1) {
418
- throw frontendModelValidationError("Invalid sort value: expected non-empty string");
419
- }
420
- if (trimmed.startsWith("-")) {
421
- const column = trimmed.slice(1).trim();
422
- if (column.length < 1) {
423
- throw frontendModelValidationError(`Invalid sort definition: ${sortValue}`);
424
- }
425
- return {
426
- column,
427
- direction: "desc",
428
- path: [...path]
429
- };
430
- }
431
- const sortParts = trimmed.split(/\s+/).filter(Boolean);
432
- if (sortParts.length > 2) {
433
- throw frontendModelValidationError(`Invalid sort definition: ${sortValue}`);
434
- }
435
- const column = sortParts[0];
436
- if (column.length < 1) {
437
- throw frontendModelValidationError(`Invalid sort definition: ${sortValue}`);
438
- }
439
- const direction = sortParts.length === 2
440
- ? normalizeFrontendModelSortDirection(sortParts[1])
441
- : "asc";
442
- return {
443
- column,
444
- direction,
445
- path: [...path]
446
- };
447
- }
448
- /**
449
- * @param {[string, string]} sortValue - Sort tuple.
450
- * @param {string[]} [path] - Relationship path.
451
- * @returns {FrontendModelSort} - Normalized sort descriptor.
452
- */
453
- function frontendModelSortFromTuple(sortValue, path = []) {
454
- const [columnValue, directionValue] = sortValue;
455
- const column = columnValue.trim();
456
- if (column.length < 1) {
457
- throw new Error("sort tuple column must be a non-empty string");
458
- }
459
- return {
460
- column,
461
- direction: normalizeFrontendModelSortDirection(directionValue),
462
- path: [...path]
463
- };
464
- }
465
- /**
466
- * @param {string} groupValue - Group string.
467
- * @param {string[]} [path] - Relationship path.
468
- * @returns {FrontendModelGroup} - Normalized group descriptor.
469
- */
470
- function frontendModelGroupFromString(groupValue, path = []) {
471
- const trimmed = groupValue.trim();
472
- if (!/^[a-zA-Z_][a-zA-Z0-9_]*$/.test(trimmed)) {
473
- throw frontendModelValidationError(`Invalid group column: ${groupValue}`);
474
- }
475
- return {
476
- column: trimmed,
477
- path: [...path]
478
- };
479
- }
480
- /**
481
- * @param {Record<string, any>} sortValue - Nested sort object.
482
- * @param {string[]} path - Relationship path.
483
- * @returns {FrontendModelSort[]} - Normalized sort descriptors.
484
- */
485
- function normalizeFrontendModelSortObject(sortValue, path) {
486
- /** @type {FrontendModelSort[]} */
487
- const normalizedSorts = [];
488
- for (const [sortKey, sortEntry] of Object.entries(sortValue)) {
489
- if (typeof sortEntry === "string") {
490
- normalizedSorts.push({
491
- column: sortKey,
492
- direction: normalizeFrontendModelSortDirection(sortEntry),
493
- path: [...path]
494
- });
495
- continue;
496
- }
497
- if (frontendModelSortTuple(sortEntry)) {
498
- normalizedSorts.push(frontendModelSortFromTuple(sortEntry, [...path, sortKey]));
499
- continue;
500
- }
501
- if (Array.isArray(sortEntry)) {
502
- if (sortEntry.length < 1) {
503
- throw frontendModelValidationError(`Invalid sort definition for "${sortKey}": empty array`);
504
- }
505
- for (const nestedSortEntry of sortEntry) {
506
- if (!frontendModelSortTuple(nestedSortEntry)) {
507
- throw frontendModelValidationError(`Invalid sort definition for "${sortKey}": expected [column, direction] tuples`);
508
- }
509
- normalizedSorts.push(frontendModelSortFromTuple(nestedSortEntry, [...path, sortKey]));
510
- }
511
- continue;
512
- }
513
- if (isPlainObject(sortEntry)) {
514
- normalizedSorts.push(...normalizeFrontendModelSortObject(sortEntry, [...path, sortKey]));
515
- continue;
516
- }
517
- throw frontendModelValidationError(`Invalid sort definition for "${sortKey}": ${typeof sortEntry}`);
518
- }
519
- return normalizedSorts;
520
- }
521
- /**
522
- * @param {Record<string, any>} groupValue - Nested group object.
523
- * @param {string[]} path - Relationship path.
524
- * @returns {FrontendModelGroup[]} - Normalized group descriptors.
525
- */
526
- function normalizeFrontendModelGroupObject(groupValue, path) {
527
- /** @type {FrontendModelGroup[]} */
528
- const normalizedGroups = [];
529
- for (const [groupKey, groupEntry] of Object.entries(groupValue)) {
530
- if (typeof groupEntry === "string") {
531
- normalizedGroups.push(frontendModelGroupFromString(groupEntry, [...path, groupKey]));
532
- continue;
533
- }
534
- if (Array.isArray(groupEntry)) {
535
- if (groupEntry.length < 1) {
536
- throw frontendModelValidationError(`Invalid group definition for "${groupKey}": empty array`);
537
- }
538
- for (const nestedGroupEntry of groupEntry) {
539
- if (typeof nestedGroupEntry !== "string") {
540
- throw frontendModelValidationError(`Invalid group definition for "${groupKey}": expected string columns`);
541
- }
542
- normalizedGroups.push(frontendModelGroupFromString(nestedGroupEntry, [...path, groupKey]));
543
- }
544
- continue;
545
- }
546
- if (isPlainObject(groupEntry)) {
547
- normalizedGroups.push(...normalizeFrontendModelGroupObject(groupEntry, [...path, groupKey]));
548
- continue;
549
- }
550
- throw frontendModelValidationError(`Invalid group definition for "${groupKey}": ${typeof groupEntry}`);
551
- }
552
- return normalizedGroups;
553
- }
554
- /**
555
- * @param {unknown} searches - Search payload.
235
+ * Runs normalize frontend model searches.
236
+ * @param {?} searches - Search payload.
556
237
  * @returns {FrontendModelSearch[]} - Normalized searches.
557
238
  */
558
239
  function normalizeFrontendModelSearches(searches) {
@@ -561,7 +242,9 @@ function normalizeFrontendModelSearches(searches) {
561
242
  if (!Array.isArray(searches)) {
562
243
  throw frontendModelValidationError(`Invalid searches type: ${typeof searches}`);
563
244
  }
564
- /** @type {FrontendModelSearch[]} */
245
+ /**
246
+ * Normalized.
247
+ @type {FrontendModelSearch[]} */
565
248
  const normalized = [];
566
249
  for (const search of searches) {
567
250
  if (!isPlainObject(search)) {
@@ -586,7 +269,7 @@ function normalizeFrontendModelSearches(searches) {
586
269
  }
587
270
  normalized.push({
588
271
  column,
589
- operator: normalizeFrontendModelSearchOperator(operator),
272
+ operator: normalizeQuerySearchOperator(operator),
590
273
  path: [...path],
591
274
  value: search.value
592
275
  });
@@ -594,8 +277,9 @@ function normalizeFrontendModelSearches(searches) {
594
277
  return normalized;
595
278
  }
596
279
  /**
597
- * @param {unknown} where - Where payload.
598
- * @returns {Record<string, any> | null} - Normalized where hash.
280
+ * Runs normalize frontend model where.
281
+ * @param {?} where - Where payload.
282
+ * @returns {Record<string, ?> | null} - Normalized where hash.
599
283
  */
600
284
  function normalizeFrontendModelWhere(where) {
601
285
  if (!where)
@@ -603,11 +287,12 @@ function normalizeFrontendModelWhere(where) {
603
287
  if (!isPlainObject(where)) {
604
288
  throw frontendModelValidationError(`Invalid where type: ${typeof where}`);
605
289
  }
606
- return /** @type {Record<string, any>} */ (JSON.parse(JSON.stringify(where)));
290
+ return where;
607
291
  }
608
292
  /**
609
- * @param {unknown} ransack - Ransack payload.
610
- * @returns {Record<string, any> | null} - Normalized Ransack hash.
293
+ * Runs normalize frontend model ransack.
294
+ * @param {?} ransack - Ransack payload.
295
+ * @returns {Record<string, ?> | null} - Normalized Ransack hash.
611
296
  */
612
297
  function normalizeFrontendModelRansack(ransack) {
613
298
  if (!ransack)
@@ -615,10 +300,11 @@ function normalizeFrontendModelRansack(ransack) {
615
300
  if (!isPlainObject(ransack)) {
616
301
  throw frontendModelValidationError(`Invalid ransack type: ${typeof ransack}`);
617
302
  }
618
- return /** @type {Record<string, any>} */ (JSON.parse(JSON.stringify(ransack)));
303
+ return ransack;
619
304
  }
620
305
  /**
621
- * @param {unknown} value - Candidate integer.
306
+ * Runs normalize frontend model integer param.
307
+ * @param {?} value - Candidate integer.
622
308
  * @param {string} name - Param name for errors.
623
309
  * @param {number} min - Minimum allowed value.
624
310
  * @returns {number | null} - Normalized integer.
@@ -635,11 +321,12 @@ function normalizeFrontendModelIntegerParam(value, name, min) {
635
321
  return value;
636
322
  }
637
323
  /**
324
+ * Runs normalize frontend model pagination.
638
325
  * @param {object} args - Pagination args.
639
- * @param {unknown} args.limit - Limit payload.
640
- * @param {unknown} args.offset - Offset payload.
641
- * @param {unknown} args.page - Page payload.
642
- * @param {unknown} args.perPage - Per-page payload.
326
+ * @param {?} args.limit - Limit payload.
327
+ * @param {?} args.offset - Offset payload.
328
+ * @param {?} args.page - Page payload.
329
+ * @param {?} args.perPage - Per-page payload.
643
330
  * @returns {FrontendModelPagination} - Normalized pagination data.
644
331
  */
645
332
  function normalizeFrontendModelPagination({ limit, offset, page, perPage }) {
@@ -651,7 +338,8 @@ function normalizeFrontendModelPagination({ limit, offset, page, perPage }) {
651
338
  };
652
339
  }
653
340
  /**
654
- * @param {unknown} distinct - Distinct payload.
341
+ * Runs normalize frontend model distinct.
342
+ * @param {?} distinct - Distinct payload.
655
343
  * @returns {boolean | null} - Normalized distinct flag when provided.
656
344
  */
657
345
  function normalizeFrontendModelDistinct(distinct) {
@@ -663,245 +351,100 @@ function normalizeFrontendModelDistinct(distinct) {
663
351
  return distinct;
664
352
  }
665
353
  /**
666
- * @param {unknown} sort - Sort payload.
667
- * @returns {FrontendModelSort[]} - Normalized sort definitions.
668
- */
669
- function normalizeFrontendModelSort(sort) {
670
- if (!sort)
671
- return [];
672
- if (typeof sort === "string") {
673
- return [frontendModelSortFromString(sort)];
674
- }
675
- if (frontendModelSortTuple(sort)) {
676
- return [frontendModelSortFromTuple(sort)];
677
- }
678
- if (frontendModelSortDescriptor(sort)) {
679
- return [{
680
- column: sort.column.trim(),
681
- direction: normalizeFrontendModelSortDirection(sort.direction),
682
- path: [...sort.path]
683
- }];
684
- }
685
- if (isPlainObject(sort)) {
686
- return normalizeFrontendModelSortObject(sort, []);
687
- }
688
- if (Array.isArray(sort)) {
689
- /** @type {FrontendModelSort[]} */
690
- const normalized = [];
691
- for (const sortEntry of sort) {
692
- if (typeof sortEntry === "string") {
693
- normalized.push(frontendModelSortFromString(sortEntry));
694
- continue;
695
- }
696
- if (frontendModelSortTuple(sortEntry)) {
697
- normalized.push(frontendModelSortFromTuple(sortEntry));
698
- continue;
699
- }
700
- if (frontendModelSortDescriptor(sortEntry)) {
701
- normalized.push({
702
- column: sortEntry.column.trim(),
703
- direction: normalizeFrontendModelSortDirection(sortEntry.direction),
704
- path: [...sortEntry.path]
705
- });
706
- continue;
707
- }
708
- if (isPlainObject(sortEntry)) {
709
- normalized.push(...normalizeFrontendModelSortObject(sortEntry, []));
710
- continue;
711
- }
712
- throw frontendModelValidationError(`Invalid sort entry type: ${typeof sortEntry}`);
713
- }
714
- return normalized;
715
- }
716
- throw frontendModelValidationError(`Invalid sort type: ${typeof sort}`);
717
- }
718
- /**
719
- * @param {unknown} group - Group payload.
720
- * @returns {FrontendModelGroup[]} - Normalized group definitions.
354
+ * Runs build frontend model join object from path.
355
+ * @param {string[]} path - Relationship path.
356
+ * @returns {Record<string, ?>} - Join object.
721
357
  */
722
- function normalizeFrontendModelGroup(group) {
723
- if (!group)
724
- return [];
725
- if (typeof group === "string") {
726
- return [frontendModelGroupFromString(group)];
727
- }
728
- if (frontendModelGroupDescriptor(group)) {
729
- return [{
730
- column: frontendModelGroupFromString(group.column).column,
731
- path: [...group.path]
732
- }];
733
- }
734
- if (isPlainObject(group)) {
735
- return normalizeFrontendModelGroupObject(group, []);
736
- }
737
- if (Array.isArray(group)) {
738
- /** @type {FrontendModelGroup[]} */
739
- const normalized = [];
740
- for (const groupEntry of group) {
741
- if (typeof groupEntry === "string") {
742
- normalized.push(frontendModelGroupFromString(groupEntry));
743
- continue;
744
- }
745
- if (frontendModelGroupDescriptor(groupEntry)) {
746
- normalized.push({
747
- column: frontendModelGroupFromString(groupEntry.column).column,
748
- path: [...groupEntry.path]
749
- });
750
- continue;
751
- }
752
- if (isPlainObject(groupEntry)) {
753
- normalized.push(...normalizeFrontendModelGroupObject(groupEntry, []));
754
- continue;
755
- }
756
- throw frontendModelValidationError(`Invalid group entry type: ${typeof groupEntry}`);
757
- }
758
- return normalized;
358
+ function buildFrontendModelJoinObjectFromPath(path) {
359
+ /**
360
+ * Join object.
361
+ @type {Record<string, ?>} */
362
+ const joinObject = {};
363
+ /**
364
+ * Current node.
365
+ @type {Record<string, ?>} */
366
+ let currentNode = joinObject;
367
+ for (const relationshipName of path) {
368
+ currentNode[relationshipName] = {};
369
+ currentNode = currentNode[relationshipName];
759
370
  }
760
- throw frontendModelValidationError(`Invalid group type: ${typeof group}`);
371
+ return joinObject;
761
372
  }
762
373
  /**
763
- * @param {unknown} value - Candidate descriptor.
764
- * @returns {value is {column: string, path: string[]}} - Whether candidate is an explicit pluck descriptor object.
374
+ * Build a successful single-model frontend-model response payload.
375
+ * @param {Record<string, ?>} model - Serialized model payload.
376
+ * @returns {{model: Record<string, ?>, status: "success"}} - Success response payload.
765
377
  */
766
- function frontendModelPluckDescriptor(value) {
767
- if (!isPlainObject(value))
768
- return false;
769
- if (!("column" in value) || !("path" in value))
770
- return false;
771
- if (typeof value.column !== "string")
772
- return false;
773
- if (!Array.isArray(value.path))
774
- return false;
775
- return value.path.every((pathEntry) => typeof pathEntry === "string");
378
+ function frontendModelSerializedModelSuccess(model) {
379
+ return { model, status: "success" };
776
380
  }
777
381
  /**
778
- * @param {string} pluckValue - Pluck string.
779
- * @param {string[]} [path] - Relationship path.
780
- * @returns {FrontendModelPluck} - Normalized pluck descriptor.
382
+ * Resolve and validate attachment params shared by attachment commands.
383
+ * @param {Record<string, ?>} params - Frontend-model request params.
384
+ * @returns {{attachmentId: string | undefined, attachmentName: string} | string} - Attachment params or validation error message.
781
385
  */
782
- function frontendModelPluckFromString(pluckValue, path = []) {
783
- const trimmed = pluckValue.trim();
784
- if (!/^[a-zA-Z_][a-zA-Z0-9_]*$/.test(trimmed)) {
785
- throw frontendModelValidationError(`Invalid pluck column: ${pluckValue}`);
386
+ function frontendModelAttachmentParams(params) {
387
+ const attachmentName = params.attachmentName;
388
+ if (typeof attachmentName !== "string" || attachmentName.length < 1) {
389
+ return "Expected attachmentName.";
786
390
  }
787
391
  return {
788
- column: trimmed,
789
- path: [...path]
392
+ attachmentId: typeof params.attachmentId === "string" ? params.attachmentId : undefined,
393
+ attachmentName
790
394
  };
791
395
  }
792
396
  /**
793
- * @param {Record<string, any>} pluckValue - Nested pluck object.
794
- * @param {string[]} path - Relationship path.
795
- * @returns {FrontendModelPluck[]} - Normalized pluck descriptors.
397
+ * Extract mutation attributes shared by create and update commands.
398
+ * @param {Record<string, ?>} params - Frontend-model request params.
399
+ * @returns {{attributes: Record<string, ?>, nestedAttributes: Record<string, ?> | null} | string} - Mutation attributes or validation error message.
796
400
  */
797
- function normalizeFrontendModelPluckObject(pluckValue, path) {
798
- /** @type {FrontendModelPluck[]} */
799
- const normalizedPlucks = [];
800
- for (const [pluckKey, pluckEntry] of Object.entries(pluckValue)) {
801
- if (typeof pluckEntry === "string") {
802
- normalizedPlucks.push(frontendModelPluckFromString(pluckEntry, [...path, pluckKey]));
803
- continue;
804
- }
805
- if (Array.isArray(pluckEntry)) {
806
- if (pluckEntry.length < 1) {
807
- throw frontendModelValidationError(`Invalid pluck definition for "${pluckKey}": empty array`);
808
- }
809
- for (const nestedPluckEntry of pluckEntry) {
810
- if (typeof nestedPluckEntry !== "string") {
811
- throw frontendModelValidationError(`Invalid pluck definition for "${pluckKey}": expected string columns`);
812
- }
813
- normalizedPlucks.push(frontendModelPluckFromString(nestedPluckEntry, [...path, pluckKey]));
814
- }
815
- continue;
816
- }
817
- if (isPlainObject(pluckEntry)) {
818
- normalizedPlucks.push(...normalizeFrontendModelPluckObject(pluckEntry, [...path, pluckKey]));
819
- continue;
820
- }
821
- throw frontendModelValidationError(`Invalid pluck definition for "${pluckKey}": ${typeof pluckEntry}`);
401
+ function frontendModelMutationAttributes(params) {
402
+ const attributes = params.attributes;
403
+ if (!attributes || typeof attributes !== "object") {
404
+ return "Expected model attributes.";
822
405
  }
823
- return normalizedPlucks;
824
- }
825
- /**
826
- * @param {unknown} pluck - Pluck payload.
827
- * @returns {FrontendModelPluck[]} - Normalized pluck definitions.
828
- */
829
- function normalizeFrontendModelPluck(pluck) {
830
- if (!pluck)
831
- return [];
832
- if (typeof pluck === "string") {
833
- return [frontendModelPluckFromString(pluck)];
834
- }
835
- if (frontendModelPluckDescriptor(pluck)) {
836
- return [{
837
- column: frontendModelPluckFromString(pluck.column).column,
838
- path: [...pluck.path]
839
- }];
840
- }
841
- if (isPlainObject(pluck)) {
842
- return normalizeFrontendModelPluckObject(pluck, []);
843
- }
844
- if (Array.isArray(pluck)) {
845
- /** @type {FrontendModelPluck[]} */
846
- const normalized = [];
847
- for (const pluckEntry of pluck) {
848
- if (typeof pluckEntry === "string") {
849
- normalized.push(frontendModelPluckFromString(pluckEntry));
850
- continue;
851
- }
852
- if (frontendModelPluckDescriptor(pluckEntry)) {
853
- normalized.push({
854
- column: frontendModelPluckFromString(pluckEntry.column).column,
855
- path: [...pluckEntry.path]
856
- });
857
- continue;
858
- }
859
- if (isPlainObject(pluckEntry)) {
860
- normalized.push(...normalizeFrontendModelPluckObject(pluckEntry, []));
861
- continue;
862
- }
863
- throw frontendModelValidationError(`Invalid pluck entry type: ${typeof pluckEntry}`);
864
- }
865
- return normalized;
866
- }
867
- throw frontendModelValidationError(`Invalid pluck type: ${typeof pluck}`);
868
- }
869
- /**
870
- * @param {string[]} path - Relationship path.
871
- * @returns {Record<string, any>} - Join object.
872
- */
873
- function buildFrontendModelJoinObjectFromPath(path) {
874
- /** @type {Record<string, any>} */
875
- const joinObject = {};
876
- /** @type {Record<string, any>} */
877
- let currentNode = joinObject;
878
- for (const relationshipName of path) {
879
- currentNode[relationshipName] = {};
880
- currentNode = currentNode[relationshipName];
881
- }
882
- return joinObject;
406
+ return {
407
+ attributes,
408
+ nestedAttributes: params.nestedAttributes && typeof params.nestedAttributes === "object"
409
+ ? /**
410
+ * Types the following value.
411
+ @type {Record<string, ?>} */
412
+ (params.nestedAttributes)
413
+ : null
414
+ };
883
415
  }
884
416
  /** Controller with built-in frontend model resource actions. */
885
417
  export default class FrontendModelController extends Controller {
886
- /** @type {Record<string, any> | undefined} */
418
+ /**
419
+ * Frontend model params.
420
+ @type {Record<string, ?> | undefined} */
887
421
  _frontendModelParams = undefined;
888
- /** @type {Record<string, any> | undefined} */
422
+ /**
423
+ * Frontend model params override.
424
+ @type {Record<string, ?> | undefined} */
889
425
  _frontendModelParamsOverride = undefined;
890
- /** @type {import("./authorization/ability.js").default | undefined} */
426
+ /**
427
+ * Frontend model ability override.
428
+ @type {import("./authorization/ability.js").default | undefined} */
891
429
  _frontendModelAbilityOverride = undefined;
892
430
  /**
893
- * @returns {Record<string, any>} - Decoded request params.
431
+ * Runs frontend model params.
432
+ * @returns {Record<string, ?>} - Decoded request params.
894
433
  */
895
434
  frontendModelParams() {
896
435
  if (this._frontendModelParamsOverride) {
897
436
  return this._frontendModelParamsOverride;
898
437
  }
899
- this._frontendModelParams ||= /** @type {Record<string, any>} */ (deserializeFrontendModelTransportValue(this.params()));
438
+ this._frontendModelParams ||= /**
439
+ * Types the following value.
440
+ @type {Record<string, ?>} */
441
+ (deserializeFrontendModelTransportValue(this.params()));
900
442
  return this._frontendModelParams;
901
443
  }
902
444
  /**
445
+ * Runs with frontend model params.
903
446
  * @template T
904
- * @param {Record<string, any>} params - Temporary frontend model params.
447
+ * @param {Record<string, ?>} params - Temporary frontend model params.
905
448
  * @param {() => Promise<T>} callback - Callback executed with temporary params.
906
449
  * @returns {Promise<T>} - Callback return value.
907
450
  */
@@ -919,8 +462,9 @@ export default class FrontendModelController extends Controller {
919
462
  }
920
463
  }
921
464
  /**
465
+ * Runs with frontend model request context.
922
466
  * @template T
923
- * @param {Record<string, any>} params - Request-scoped params.
467
+ * @param {Record<string, ?>} params - Request-scoped params.
924
468
  * @param {import("./http-server/client/response.js").default} response - Response instance.
925
469
  * @param {() => Promise<T>} callback - Callback executed inside resolved tenant and ability context.
926
470
  * @returns {Promise<T>} - Callback return value.
@@ -939,7 +483,9 @@ export default class FrontendModelController extends Controller {
939
483
  request: this.request(),
940
484
  response
941
485
  });
942
- /** @type {import("./authorization/ability.js").default | undefined} */
486
+ /**
487
+ * Previous ability override.
488
+ @type {import("./authorization/ability.js").default | undefined} */
943
489
  const previousAbilityOverride = this._frontendModelAbilityOverride;
944
490
  this._frontendModelAbilityOverride = ability;
945
491
  try {
@@ -953,11 +499,15 @@ export default class FrontendModelController extends Controller {
953
499
  });
954
500
  });
955
501
  }
956
- /** @returns {import("./authorization/ability.js").default | undefined} - Current ability for frontend-model request scope. */
502
+ /**
503
+ * Runs current ability.
504
+ * @returns {import("./authorization/ability.js").default | undefined} - Current ability for frontend-model request scope.
505
+ */
957
506
  currentAbility() {
958
507
  return this._frontendModelAbilityOverride || super.currentAbility();
959
508
  }
960
509
  /**
510
+ * Runs frontend model class.
961
511
  * @returns {typeof import("./database/record/index.js").default} - Frontend model class for controller resource actions.
962
512
  */
963
513
  frontendModelClass() {
@@ -970,6 +520,7 @@ export default class FrontendModelController extends Controller {
970
520
  throw new Error(`No frontend model configured for model '${modelName || "unknown"}' and controller '${controllerName || "unknown"}'. Ensure a FrontendModelBaseResource subclass exists in src/resources/ or is listed in the ability resolver.`);
971
521
  }
972
522
  /**
523
+ * Runs frontend model resource configuration.
973
524
  * @returns {{backendProject: import("./configuration-types.js").BackendProjectConfiguration, modelName: string, resourceClass: import("./configuration-types.js").FrontendModelResourceClassType, resourceConfiguration: import("./configuration-types.js").NormalizedFrontendModelResourceConfiguration} | null} - Frontend model resource configuration for current controller.
974
525
  */
975
526
  frontendModelResourceConfiguration() {
@@ -1016,6 +567,7 @@ export default class FrontendModelController extends Controller {
1016
567
  return null;
1017
568
  }
1018
569
  /**
570
+ * Runs frontend model resource configuration for backend project model name.
1019
571
  * @param {object} args - Arguments.
1020
572
  * @param {import("./configuration-types.js").BackendProjectConfiguration} args.backendProject - Backend project configuration.
1021
573
  * @param {string} args.modelName - Model name.
@@ -1038,6 +590,7 @@ export default class FrontendModelController extends Controller {
1038
590
  };
1039
591
  }
1040
592
  /**
593
+ * Runs frontend model resource configuration for model class.
1041
594
  * @param {typeof import("./database/record/index.js").default} modelClass - Model class.
1042
595
  * @returns {{backendProject: import("./configuration-types.js").BackendProjectConfiguration, modelName: string, resourceClass: import("./configuration-types.js").FrontendModelResourceClassType, resourceConfiguration: import("./configuration-types.js").NormalizedFrontendModelResourceConfiguration} | null} - Frontend model resource configuration for model class.
1043
596
  */
@@ -1051,6 +604,7 @@ export default class FrontendModelController extends Controller {
1051
604
  });
1052
605
  }
1053
606
  /**
607
+ * Runs frontend model resource model class.
1054
608
  * @param {{modelName: string, resourceClass: import("./configuration-types.js").FrontendModelResourceClassType}} frontendModelResource - Frontend model resource configuration.
1055
609
  * @returns {typeof import("./database/record/index.js").default | null} - Backing record class, when available.
1056
610
  */
@@ -1061,6 +615,7 @@ export default class FrontendModelController extends Controller {
1061
615
  return this.getConfiguration().getModelClasses()[frontendModelResource.modelName] || null;
1062
616
  }
1063
617
  /**
618
+ * Runs frontend model class from configuration.
1064
619
  * @returns {typeof import("./database/record/index.js").default | null} - Frontend model class resolved from backend project configuration.
1065
620
  */
1066
621
  frontendModelClassFromConfiguration() {
@@ -1097,6 +652,7 @@ export default class FrontendModelController extends Controller {
1097
652
  });
1098
653
  }
1099
654
  /**
655
+ * Runs ensure frontend model record class initialized.
1100
656
  * @param {typeof import("./database/record/index.js").default} modelClass - Model class to initialize.
1101
657
  * @returns {Promise<void>} - Resolves when the model class is ready.
1102
658
  */
@@ -1112,6 +668,7 @@ export default class FrontendModelController extends Controller {
1112
668
  }
1113
669
  }
1114
670
  /**
671
+ * Runs ensure frontend model preload classes initialized.
1115
672
  * @param {object} args - Arguments.
1116
673
  * @param {import("./configuration-types.js").BackendProjectConfiguration} args.backendProject - Backend project configuration.
1117
674
  * @param {typeof import("./database/record/index.js").default} args.modelClass - Model class whose preload tree is being resolved.
@@ -1134,11 +691,14 @@ export default class FrontendModelController extends Controller {
1134
691
  await this.ensureFrontendModelPreloadClassesInitialized({
1135
692
  backendProject,
1136
693
  modelClass: targetModelClass,
1137
- preload: /** @type {import("./database/query/index.js").NestedPreloadRecord} */ (relationshipPreload)
694
+ preload: /**
695
+ * Types the following value.
696
+ @type {import("./database/query/index.js").NestedPreloadRecord} */ (relationshipPreload)
1138
697
  });
1139
698
  }
1140
699
  }
1141
700
  /**
701
+ * Runs ensure frontend model relationship target class initialized.
1142
702
  * @param {object} args - Arguments.
1143
703
  * @param {import("./configuration-types.js").BackendProjectConfiguration} args.backendProject - Backend project configuration.
1144
704
  * @param {import("./database/record/relationships/base.js").default} args.relationship - Relationship definition.
@@ -1162,6 +722,7 @@ export default class FrontendModelController extends Controller {
1162
722
  return targetModelClass;
1163
723
  }
1164
724
  /**
725
+ * Runs frontend model relationship target model class.
1165
726
  * @param {object} args - Arguments.
1166
727
  * @param {import("./configuration-types.js").BackendProjectConfiguration} args.backendProject - Backend project configuration.
1167
728
  * @param {import("./database/record/relationships/base.js").default} args.relationship - Relationship definition.
@@ -1188,14 +749,16 @@ export default class FrontendModelController extends Controller {
1188
749
  return targetModelClass || null;
1189
750
  }
1190
751
  /**
752
+ * Runs frontend model resource path.
1191
753
  * @param {string} modelName - Model class name.
1192
- * @param {unknown} resourceDefinition - Resource definition.
754
+ * @param {?} resourceDefinition - Resource definition.
1193
755
  * @returns {string} - Normalized resource path.
1194
756
  */
1195
757
  frontendModelResourcePath(modelName, resourceDefinition) {
1196
758
  return frontendModelResourcePath(modelName, resourceDefinition);
1197
759
  }
1198
760
  /**
761
+ * Runs frontend model resource matches controller.
1199
762
  * @param {object} args - Arguments.
1200
763
  * @param {string} args.controllerName - Controller name from params.
1201
764
  * @param {string} args.resourcePath - Resource path from configuration.
@@ -1209,6 +772,7 @@ export default class FrontendModelController extends Controller {
1209
772
  return normalizedResourcePath.endsWith(`/${normalizedController}`);
1210
773
  }
1211
774
  /**
775
+ * Runs frontend model resource instance.
1212
776
  * @returns {FrontendModelBaseResource} - Backend resource instance for current frontend-model action.
1213
777
  */
1214
778
  frontendModelResourceInstance() {
@@ -1233,12 +797,14 @@ export default class FrontendModelController extends Controller {
1233
797
  return new frontendModelResource.resourceClass(resourceArgs);
1234
798
  }
1235
799
  /**
800
+ * Runs frontend model primary key.
1236
801
  * @returns {string} - Frontend model primary key.
1237
802
  */
1238
803
  frontendModelPrimaryKey() {
1239
804
  return this.frontendModelClass().primaryKey();
1240
805
  }
1241
806
  /**
807
+ * Runs frontend model ability action.
1242
808
  * @param {"index" | "find" | "create" | "update" | "destroy" | "attach" | "download" | "url"} action - Frontend action.
1243
809
  * @returns {string} - Ability action configured for the frontend action.
1244
810
  */
@@ -1261,14 +827,16 @@ export default class FrontendModelController extends Controller {
1261
827
  return abilityAction;
1262
828
  }
1263
829
  /**
830
+ * Runs frontend model authorized query.
1264
831
  * @param {"index" | "find" | "create" | "update" | "destroy" | "attach" | "download" | "url"} action - Frontend action.
1265
- * @returns {import("./database/query/model-class-query.js").default<any>} - Authorized query for the action.
832
+ * @returns {import("./database/query/model-class-query.js").default<?>} - Authorized query for the action.
1266
833
  */
1267
834
  frontendModelAuthorizedQuery(action) {
1268
835
  const abilityAction = this.frontendModelAbilityAction(action);
1269
836
  return this.frontendModelClass().accessibleFor(abilityAction, this.currentAbility());
1270
837
  }
1271
838
  /**
839
+ * Runs frontend model primary key value.
1272
840
  * @param {import("./database/record/index.js").default} model - Model instance.
1273
841
  * @returns {string} - Primary key value as string.
1274
842
  */
@@ -1280,6 +848,7 @@ export default class FrontendModelController extends Controller {
1280
848
  return String(value);
1281
849
  }
1282
850
  /**
851
+ * Runs frontend model filter authorized models.
1283
852
  * @param {object} args - Arguments.
1284
853
  * @param {"index" | "find" | "create" | "update" | "destroy" | "attach" | "download" | "url"} args.action - Frontend action.
1285
854
  * @param {import("./database/record/index.js").default[]} args.models - Candidate models.
@@ -1296,6 +865,7 @@ export default class FrontendModelController extends Controller {
1296
865
  return models.filter((model) => authorizedIds.has(this.frontendModelPrimaryKeyValue(model)));
1297
866
  }
1298
867
  /**
868
+ * Runs run frontend model before action.
1299
869
  * @param {"index" | "find" | "create" | "update" | "destroy" | "attach" | "download" | "url"} action - Frontend action.
1300
870
  * @returns {Promise<boolean>} - Whether action should continue.
1301
871
  */
@@ -1304,6 +874,7 @@ export default class FrontendModelController extends Controller {
1304
874
  return result !== false;
1305
875
  }
1306
876
  /**
877
+ * Runs frontend model find record.
1307
878
  * @param {"find" | "update" | "destroy" | "attach" | "download" | "url"} action - Frontend action.
1308
879
  * @param {string | number} id - Record id.
1309
880
  * @returns {Promise<import("./database/record/index.js").default | null>} - Located model record.
@@ -1316,8 +887,9 @@ export default class FrontendModelController extends Controller {
1316
887
  return authorizedModels[0] || null;
1317
888
  }
1318
889
  /**
1319
- * @param {Record<string, any>} attributes - Create attributes.
1320
- * @param {Record<string, any> | null} [nestedAttributes] - Optional nested-attribute payload for cascading writes.
890
+ * Runs frontend model create record.
891
+ * @param {Record<string, ?>} attributes - Create attributes.
892
+ * @param {Record<string, ?> | null} [nestedAttributes] - Optional nested-attribute payload for cascading writes.
1321
893
  * @returns {Promise<import("./database/record/index.js").default | null>} - Created model when authorized.
1322
894
  */
1323
895
  async frontendModelCreateRecord(attributes, nestedAttributes = null) {
@@ -1331,6 +903,7 @@ export default class FrontendModelController extends Controller {
1331
903
  return null;
1332
904
  }
1333
905
  /**
906
+ * Runs frontend model records.
1334
907
  * @returns {Promise<import("./database/record/index.js").default[]>} - Frontend model records.
1335
908
  */
1336
909
  async frontendModelRecords() {
@@ -1338,52 +911,77 @@ export default class FrontendModelController extends Controller {
1338
911
  return await this.frontendModelFilterAuthorizedModels({ action: "index", models });
1339
912
  }
1340
913
  /**
914
+ * Runs frontend model preload.
1341
915
  * @returns {import("./database/query/index.js").NestedPreloadRecord | null} - Frontend preload data.
1342
916
  */
1343
917
  frontendModelPreload() {
1344
918
  return normalizeFrontendModelPreload(this.frontendModelParams().preload);
1345
919
  }
1346
920
  /**
921
+ * Runs frontend model select.
1347
922
  * @returns {Record<string, string[]> | null} - Frontend select data.
1348
923
  */
1349
924
  frontendModelSelect() {
1350
925
  return normalizeFrontendModelSelect(this.frontendModelParams().select, this.frontendModelClass().getModelName());
1351
926
  }
1352
927
  /**
928
+ * Runs frontend model selects extra.
1353
929
  * @returns {Record<string, string[]> | null} - Frontend extra-select data (defaults plus these), keyed by model name.
1354
930
  */
1355
931
  frontendModelSelectsExtra() {
1356
932
  return normalizeFrontendModelSelect(this.frontendModelParams().selectsExtra, this.frontendModelClass().getModelName());
1357
933
  }
1358
934
  /**
935
+ * Runs frontend model searches.
1359
936
  * @returns {FrontendModelSearch[]} - Frontend search filters.
1360
937
  */
1361
938
  frontendModelSearches() {
1362
939
  return normalizeFrontendModelSearches(this.frontendModelParams().searches);
1363
940
  }
1364
941
  /**
1365
- * @returns {Record<string, any> | null} - Frontend where filters.
942
+ * Runs frontend model where.
943
+ * @returns {Record<string, ?> | null} - Frontend where filters.
1366
944
  */
1367
945
  frontendModelWhere() {
1368
946
  return normalizeFrontendModelWhere(this.frontendModelParams().where);
1369
947
  }
1370
- /** @returns {Record<string, any> | null} - Frontend Ransack filters. */
948
+ /**
949
+ * Runs frontend model ransack.
950
+ * @returns {Record<string, ?> | null} - Frontend Ransack filters.
951
+ */
1371
952
  frontendModelRansack() {
1372
953
  return normalizeFrontendModelRansack(this.frontendModelParams().ransack);
1373
954
  }
1374
- /** @returns {Record<string, any> | null} - Frontend joins descriptors. */
955
+ /**
956
+ * Runs frontend model joins.
957
+ * @returns {Record<string, ?> | null} - Frontend joins descriptors.
958
+ */
1375
959
  frontendModelJoins() {
1376
960
  return normalizeFrontendModelJoins(this.frontendModelParams().joins);
1377
961
  }
1378
- /** @returns {FrontendModelSort[]} - Frontend sort definitions. */
962
+ /**
963
+ * Runs frontend model sort.
964
+ * @returns {FrontendModelSort[]} - Frontend sort definitions.
965
+ */
1379
966
  frontendModelSort() {
1380
- return normalizeFrontendModelSort(this.frontendModelParams().sort);
967
+ return normalizeQuerySort(this.frontendModelParams().sort);
1381
968
  }
1382
- /** @returns {FrontendModelGroup[]} - Frontend group definitions. */
969
+ /**
970
+ * Runs frontend model group.
971
+ * @returns {FrontendModelGroup[]} - Frontend group definitions.
972
+ */
1383
973
  frontendModelGroup() {
1384
- return normalizeFrontendModelGroup(this.frontendModelParams().group);
974
+ try {
975
+ return normalizeQueryGroup(this.frontendModelParams().group);
976
+ }
977
+ catch (error) {
978
+ throw frontendModelValidationErrorForError(error);
979
+ }
1385
980
  }
1386
- /** @returns {FrontendModelPagination} - Frontend pagination params. */
981
+ /**
982
+ * Runs frontend model pagination.
983
+ * @returns {FrontendModelPagination} - Frontend pagination params.
984
+ */
1387
985
  frontendModelPagination() {
1388
986
  const params = this.frontendModelParams();
1389
987
  return normalizeFrontendModelPagination({
@@ -1393,27 +991,44 @@ export default class FrontendModelController extends Controller {
1393
991
  perPage: params.perPage
1394
992
  });
1395
993
  }
1396
- /** @returns {boolean | null} - Frontend distinct flag when provided. */
994
+ /**
995
+ * Runs frontend model distinct.
996
+ * @returns {boolean | null} - Frontend distinct flag when provided.
997
+ */
1397
998
  frontendModelDistinct() {
1398
999
  return normalizeFrontendModelDistinct(this.frontendModelParams().distinct);
1399
1000
  }
1400
- /** @returns {FrontendModelPluck[]} - Frontend pluck definitions. */
1001
+ /**
1002
+ * Runs frontend model pluck.
1003
+ * @returns {FrontendModelPluck[]} - Frontend pluck definitions.
1004
+ */
1401
1005
  frontendModelPluck() {
1402
- return normalizeFrontendModelPluck(this.frontendModelParams().pluck);
1006
+ try {
1007
+ return normalizeQueryPluck(this.frontendModelParams().pluck);
1008
+ }
1009
+ catch (error) {
1010
+ throw frontendModelValidationErrorForError(error);
1011
+ }
1403
1012
  }
1404
- /** @returns {boolean} - Whether the request asks for an aggregate count. */
1013
+ /**
1014
+ * Runs frontend model count requested.
1015
+ * @returns {boolean} - Whether the request asks for an aggregate count.
1016
+ */
1405
1017
  frontendModelCountRequested() {
1406
1018
  return this.frontendModelParams().count === true;
1407
1019
  }
1408
1020
  /**
1409
- * @returns {Array<{attributeName: string, relationshipName: string, where?: Record<string, unknown>}>}
1021
+ * Runs frontend model with count.
1022
+ * @returns {Array<{attributeName: string, relationshipName: string, where?: Record<string, ?>}>}
1410
1023
  * Frontend withCount entries. Empty array when not requested.
1411
1024
  */
1412
1025
  frontendModelWithCount() {
1413
1026
  const raw = this.frontendModelParams().withCount;
1414
1027
  if (!Array.isArray(raw))
1415
1028
  return [];
1416
- /** @type {Array<{attributeName: string, relationshipName: string, where?: Record<string, unknown>}>} */
1029
+ /**
1030
+ * Entries.
1031
+ @type {Array<{attributeName: string, relationshipName: string, where?: Record<string, ?>}>} */
1417
1032
  const entries = [];
1418
1033
  for (const entry of raw) {
1419
1034
  if (!entry || typeof entry !== "object")
@@ -1437,7 +1052,6 @@ export default class FrontendModelController extends Controller {
1437
1052
  * resource matches — the spec entry is then silently ignored so a
1438
1053
  * caller requesting abilities for a model they cannot resolve does
1439
1054
  * not crash the request.
1440
- *
1441
1055
  * @param {string} modelName
1442
1056
  * @returns {typeof import("./database/record/index.js").default | null}
1443
1057
  */
@@ -1470,17 +1084,22 @@ export default class FrontendModelController extends Controller {
1470
1084
  * preloaded relationships at any depth. Used to evaluate per-record
1471
1085
  * abilities against nested preloaded children with a single batched
1472
1086
  * query per (modelClass, action) pair.
1473
- *
1474
1087
  * @param {import("./database/record/index.js").default[]} rootModels
1475
1088
  * @param {string} modelName
1476
1089
  * @returns {import("./database/record/index.js").default[]}
1477
1090
  */
1478
1091
  _frontendModelCollectRecordsForName(rootModels, modelName) {
1479
- /** @type {import("./database/record/index.js").default[]} */
1092
+ /**
1093
+ * Out.
1094
+ @type {import("./database/record/index.js").default[]} */
1480
1095
  const out = [];
1481
- /** @type {Set<import("./database/record/index.js").default>} */
1096
+ /**
1097
+ * Seen.
1098
+ @type {Set<import("./database/record/index.js").default>} */
1482
1099
  const seen = new Set();
1483
- /** @param {import("./database/record/index.js").default | null | undefined} record */
1100
+ /**
1101
+ * Walk.
1102
+ @param {import("./database/record/index.js").default | null | undefined} record */
1484
1103
  const walk = (record) => {
1485
1104
  if (!record || typeof record !== "object")
1486
1105
  return;
@@ -1527,7 +1146,6 @@ export default class FrontendModelController extends Controller {
1527
1146
  * `_setComputedAbility`. Runs one batched `authorized query + pluck`
1528
1147
  * per (modelClass, action) pair, regardless of how many records
1529
1148
  * were loaded.
1530
- *
1531
1149
  * @param {import("./database/record/index.js").default[]} rootModels
1532
1150
  * @returns {Promise<void>}
1533
1151
  */
@@ -1582,14 +1200,15 @@ export default class FrontendModelController extends Controller {
1582
1200
  * Unknown entries are silently skipped — downstream code resolves
1583
1201
  * model names to classes when applying the check, so unresolved
1584
1202
  * names naturally become no-ops.
1585
- *
1586
1203
  * @returns {Array<{modelName: string, actions: string[]}>}
1587
1204
  */
1588
1205
  frontendModelAbilities() {
1589
1206
  const raw = this.frontendModelParams().abilities;
1590
1207
  if (!Array.isArray(raw))
1591
1208
  return [];
1592
- /** @type {Array<{modelName: string, actions: string[]}>} */
1209
+ /**
1210
+ * Entries.
1211
+ @type {Array<{modelName: string, actions: string[]}>} */
1593
1212
  const entries = [];
1594
1213
  for (const entry of raw) {
1595
1214
  if (!entry || typeof entry !== "object")
@@ -1598,7 +1217,9 @@ export default class FrontendModelController extends Controller {
1598
1217
  continue;
1599
1218
  if (!Array.isArray(entry.actions))
1600
1219
  continue;
1601
- const actions = entry.actions.filter((/** @type {unknown} */ action) => typeof action === "string" && action.length > 0);
1220
+ const actions = entry.actions.filter((/**
1221
+ * Types the following value.
1222
+ @type {?} */ action) => typeof action === "string" && action.length > 0);
1602
1223
  if (actions.length === 0)
1603
1224
  continue;
1604
1225
  entries.push({ actions, modelName: entry.modelName });
@@ -1614,7 +1235,6 @@ export default class FrontendModelController extends Controller {
1614
1235
  *
1615
1236
  * Returns the raw nested-record spec (shape validated by the
1616
1237
  * normalizer inside `Query.queryData`) or `null` when not requested.
1617
- *
1618
1238
  * @returns {import("./database/query/query-data.js").QueryDataSpec | null}
1619
1239
  */
1620
1240
  frontendModelQueryData() {
@@ -1630,6 +1250,7 @@ export default class FrontendModelController extends Controller {
1630
1250
  return null;
1631
1251
  }
1632
1252
  /**
1253
+ * Runs frontend model index query.
1633
1254
  * @returns {import("./database/query/model-class-query.js").default} - Frontend index query with normalized params applied.
1634
1255
  */
1635
1256
  frontendModelIndexQuery() {
@@ -1675,7 +1296,9 @@ export default class FrontendModelController extends Controller {
1675
1296
  }
1676
1297
  const withCount = this.frontendModelWithCount();
1677
1298
  for (const entry of withCount) {
1678
- /** @type {Record<string, boolean | {relationship?: string, where?: Record<string, unknown>}>} */
1299
+ /**
1300
+ * Spec.
1301
+ @type {Record<string, boolean | {relationship?: string, where?: Record<string, ?>}>} */
1679
1302
  const spec = {};
1680
1303
  spec[entry.attributeName] = { relationship: entry.relationshipName, where: entry.where };
1681
1304
  query.withCount(spec);
@@ -1713,10 +1336,11 @@ export default class FrontendModelController extends Controller {
1713
1336
  return distinctRootQuery;
1714
1337
  }
1715
1338
  /**
1339
+ * Runs frontend model pluck values.
1716
1340
  * @param {object} args - Pluck args.
1717
1341
  * @param {import("./database/query/model-class-query.js").default} args.query - Query instance.
1718
1342
  * @param {FrontendModelPluck[]} args.pluck - Pluck descriptors.
1719
- * @returns {Promise<any[]>} - Plucked values.
1343
+ * @returns {Promise<Array<?>>} - Plucked values.
1720
1344
  */
1721
1345
  async frontendModelPluckValues({ query, pluck }) {
1722
1346
  if (pluck.length < 1) {
@@ -1724,7 +1348,9 @@ export default class FrontendModelController extends Controller {
1724
1348
  }
1725
1349
  const modelClass = this.frontendModelClass();
1726
1350
  const pluckQuery = query.clone();
1727
- /** @type {string[]} */
1351
+ /**
1352
+ * Aliases.
1353
+ @type {string[]} */
1728
1354
  const aliases = [];
1729
1355
  const queryMetadata = frontendModelQueryMetadata(query);
1730
1356
  const pluckQueryMetadata = frontendModelQueryMetadata(pluckQuery);
@@ -1753,14 +1379,19 @@ export default class FrontendModelController extends Controller {
1753
1379
  const rows = await pluckQuery.results();
1754
1380
  if (aliases.length === 1) {
1755
1381
  const [alias] = aliases;
1756
- return rows.map((row) => /** @type {Record<string, any>} */ (row)[alias]);
1382
+ return rows.map((row) => /**
1383
+ * Types the following value.
1384
+ @type {Record<string, ?>} */ (row)[alias]);
1757
1385
  }
1758
1386
  return rows.map((row) => {
1759
- const rowHash = /** @type {Record<string, any>} */ (row);
1387
+ const rowHash = /**
1388
+ * Types the following value.
1389
+ @type {Record<string, ?>} */ (row);
1760
1390
  return aliases.map((alias) => rowHash[alias]);
1761
1391
  });
1762
1392
  }
1763
1393
  /**
1394
+ * Runs frontend model search target model class.
1764
1395
  * @param {object} args - Search args.
1765
1396
  * @param {typeof import("./database/record/index.js").default} args.modelClass - Root model class.
1766
1397
  * @param {string[]} args.path - Relationship path.
@@ -1782,6 +1413,7 @@ export default class FrontendModelController extends Controller {
1782
1413
  return targetModelClass;
1783
1414
  }
1784
1415
  /**
1416
+ * Runs apply frontend model search.
1785
1417
  * @param {object} args - Search args.
1786
1418
  * @param {import("./database/query/model-class-query.js").default} args.query - Query instance.
1787
1419
  * @param {FrontendModelSearch} args.search - Search filter.
@@ -1813,30 +1445,16 @@ export default class FrontendModelController extends Controller {
1813
1445
  };
1814
1446
  const sqlOperator = operatorMap[search.operator];
1815
1447
  if (search.operator === "eq") {
1816
- if (Array.isArray(search.value)) {
1817
- if (search.value.length === 0) {
1818
- query.where("1=0");
1819
- }
1820
- else {
1821
- query.where(`${columnSql} IN (${search.value.map((entry) => query.driver.quote(entry)).join(", ")})`);
1822
- }
1448
+ if (this.applyFrontendModelArraySearch({ emptySql: "1=0", operatorSql: "IN", query, search, columnSql }))
1823
1449
  return;
1824
- }
1825
1450
  if (search.value === null) {
1826
1451
  query.where(`${columnSql} IS NULL`);
1827
1452
  return;
1828
1453
  }
1829
1454
  }
1830
1455
  if (search.operator === "notEq") {
1831
- if (Array.isArray(search.value)) {
1832
- if (search.value.length === 0) {
1833
- query.where("1=1");
1834
- }
1835
- else {
1836
- query.where(`${columnSql} NOT IN (${search.value.map((entry) => query.driver.quote(entry)).join(", ")})`);
1837
- }
1456
+ if (this.applyFrontendModelArraySearch({ emptySql: "1=1", operatorSql: "NOT IN", query, search, columnSql }))
1838
1457
  return;
1839
- }
1840
1458
  if (search.value === null) {
1841
1459
  query.where(`${columnSql} IS NOT NULL`);
1842
1460
  return;
@@ -1845,6 +1463,28 @@ export default class FrontendModelController extends Controller {
1845
1463
  query.where(`${columnSql} ${sqlOperator} ${query.driver.quote(search.value)}`);
1846
1464
  }
1847
1465
  /**
1466
+ * Apply array-valued equality search filters.
1467
+ * @param {object} args - Search arguments.
1468
+ * @param {string} args.columnSql - SQL for the searched column.
1469
+ * @param {string} args.emptySql - SQL predicate used when the array is empty.
1470
+ * @param {"IN" | "NOT IN"} args.operatorSql - SQL array operator.
1471
+ * @param {import("./database/query/model-class-query.js").default} args.query - Query instance.
1472
+ * @param {FrontendModelSearch} args.search - Search descriptor.
1473
+ * @returns {boolean} - Whether an array predicate was applied.
1474
+ */
1475
+ applyFrontendModelArraySearch({ columnSql, emptySql, operatorSql, query, search }) {
1476
+ if (!Array.isArray(search.value))
1477
+ return false;
1478
+ if (search.value.length === 0) {
1479
+ query.where(emptySql);
1480
+ }
1481
+ else {
1482
+ query.where(`${columnSql} ${operatorSql} (${search.value.map((entry) => query.driver.quote(entry)).join(", ")})`);
1483
+ }
1484
+ return true;
1485
+ }
1486
+ /**
1487
+ * Runs apply frontend model pagination.
1848
1488
  * @param {object} args - Pagination args.
1849
1489
  * @param {import("./database/query/model-class-query.js").default} args.query - Query instance.
1850
1490
  * @param {FrontendModelPagination} args.pagination - Pagination values.
@@ -1865,9 +1505,10 @@ export default class FrontendModelController extends Controller {
1865
1505
  }
1866
1506
  }
1867
1507
  /**
1508
+ * Runs apply frontend model where.
1868
1509
  * @param {object} args - Where args.
1869
1510
  * @param {import("./database/query/model-class-query.js").default} args.query - Query instance.
1870
- * @param {Record<string, any>} args.where - Root-model where conditions.
1511
+ * @param {Record<string, ?>} args.where - Root-model where conditions.
1871
1512
  * @returns {void}
1872
1513
  */
1873
1514
  applyFrontendModelWhere({ query, where }) {
@@ -1879,8 +1520,9 @@ export default class FrontendModelController extends Controller {
1879
1520
  });
1880
1521
  }
1881
1522
  /**
1523
+ * Runs apply frontend model joins.
1882
1524
  * @param {object} args - Joins args.
1883
- * @param {Record<string, any>} args.joins - Relationship-object joins.
1525
+ * @param {Record<string, ?>} args.joins - Relationship-object joins.
1884
1526
  * @param {import("./database/query/model-class-query.js").default} args.query - Query instance.
1885
1527
  * @returns {void}
1886
1528
  */
@@ -1902,8 +1544,9 @@ export default class FrontendModelController extends Controller {
1902
1544
  queryMetadata[frontendModelJoinedPathsSymbol] = joinedPaths;
1903
1545
  }
1904
1546
  /**
1547
+ * Runs apply frontend model joins for path.
1905
1548
  * @param {object} args - Joins args.
1906
- * @param {Record<string, any>} args.joins - Joins for current path.
1549
+ * @param {Record<string, ?>} args.joins - Joins for current path.
1907
1550
  * @param {Set<string>} args.joinPathKeys - Joined path keys.
1908
1551
  * @param {typeof import("./database/record/index.js").default} args.modelClass - Model class for current path.
1909
1552
  * @param {string[]} args.path - Relationship path.
@@ -1938,7 +1581,6 @@ export default class FrontendModelController extends Controller {
1938
1581
  * Resolves a key that may be either a camelCase attribute name or a raw DB
1939
1582
  * column name to its canonical column name. Returns `undefined` when the
1940
1583
  * key matches neither map.
1941
- *
1942
1584
  * @param {typeof import("./database/record/index.js").default} modelClass - Model class.
1943
1585
  * @param {string} key - Attribute name or column name to resolve.
1944
1586
  * @returns {string | undefined} - Resolved DB column name, or `undefined`.
@@ -1955,11 +1597,12 @@ export default class FrontendModelController extends Controller {
1955
1597
  return undefined;
1956
1598
  }
1957
1599
  /**
1600
+ * Runs apply frontend model where for path.
1958
1601
  * @param {object} args - Where args.
1959
1602
  * @param {typeof import("./database/record/index.js").default} args.modelClass - Model class for current where scope.
1960
1603
  * @param {string[]} args.path - Relationship path from root.
1961
1604
  * @param {import("./database/query/model-class-query.js").default} args.query - Query instance.
1962
- * @param {Record<string, any>} args.where - Where conditions for current scope.
1605
+ * @param {Record<string, ?>} args.where - Where conditions for current scope.
1963
1606
  * @returns {void}
1964
1607
  */
1965
1608
  applyFrontendModelWhereForPath({ modelClass, path, query, where }) {
@@ -2020,11 +1663,12 @@ export default class FrontendModelController extends Controller {
2020
1663
  }
2021
1664
  }
2022
1665
  /**
1666
+ * Runs normalize frontend model where column value.
2023
1667
  * @param {object} args - Args.
2024
1668
  * @param {typeof import("./database/record/index.js").default} args.modelClass - Model class.
2025
1669
  * @param {string} args.columnName - Column name.
2026
- * @param {unknown} args.value - Where value.
2027
- * @returns {unknown | symbol} - SQL-safe where value.
1670
+ * @param {?} args.value - Where value.
1671
+ * @returns {? | symbol} - SQL-safe where value.
2028
1672
  */
2029
1673
  normalizeFrontendModelWhereColumnValue({ columnName, modelClass, value }) {
2030
1674
  if (typeof value === "string") {
@@ -2053,6 +1697,7 @@ export default class FrontendModelController extends Controller {
2053
1697
  return value;
2054
1698
  }
2055
1699
  /**
1700
+ * Runs apply frontend model group.
2056
1701
  * @param {object} args - Group args.
2057
1702
  * @param {import("./database/query/model-class-query.js").default} args.query - Query instance.
2058
1703
  * @param {FrontendModelGroup} args.group - Group definition.
@@ -2105,9 +1750,10 @@ export default class FrontendModelController extends Controller {
2105
1750
  queryMetadata[frontendModelGroupedColumnsSymbol] = groupedColumns;
2106
1751
  }
2107
1752
  /**
1753
+ * Runs apply frontend model translated attribute preloads.
2108
1754
  * @param {object} args - Args.
2109
- * @param {import("./database/query/model-class-query.js").default<any>} args.query - Query instance.
2110
- * @returns {import("./database/query/model-class-query.js").default<any>} - Query with translations preloaded if needed.
1755
+ * @param {import("./database/query/model-class-query.js").default<?>} args.query - Query instance.
1756
+ * @returns {import("./database/query/model-class-query.js").default<?>} - Query with translations preloaded if needed.
2111
1757
  */
2112
1758
  applyFrontendModelTranslatedAttributePreloads({ query }) {
2113
1759
  const modelClass = this.frontendModelClass();
@@ -2116,12 +1762,18 @@ export default class FrontendModelController extends Controller {
2116
1762
  if (!selectedAttributes)
2117
1763
  return query;
2118
1764
  const resource = this.frontendModelResourceInstance();
2119
- const resourceClass = /** @type {typeof import("./frontend-model-resource/base-resource.js").default} */ (resource.constructor);
1765
+ const resourceClass = /**
1766
+ * Types the following value.
1767
+ @type {typeof import("./frontend-model-resource/base-resource.js").default} */ (resource.constructor);
2120
1768
  const translatedSet = new Set(resourceClass.translatedAttributes || []);
2121
1769
  let needsTranslations = false;
2122
1770
  for (const attributeName of selectedAttributes) {
2123
1771
  const hookName = `${attributeName}AttributeSelected`;
2124
- const dynamicResource = /** @type {Record<string, any>} */ ( /** @type {unknown} */(resource));
1772
+ const dynamicResource = /**
1773
+ * Types the following value.
1774
+ @type {Record<string, ?>} */ ( /**
1775
+ * Types the following value.
1776
+ @type {?} */(resource));
2125
1777
  if (typeof dynamicResource[hookName] === "function") {
2126
1778
  const result = dynamicResource[hookName]({ query });
2127
1779
  if (result) {
@@ -2138,6 +1790,7 @@ export default class FrontendModelController extends Controller {
2138
1790
  return query;
2139
1791
  }
2140
1792
  /**
1793
+ * Runs apply frontend model sort.
2141
1794
  * @param {object} args - Sort args.
2142
1795
  * @param {import("./database/query/model-class-query.js").default} args.query - Query instance.
2143
1796
  * @param {FrontendModelSort} args.sort - Sort definition.
@@ -2206,6 +1859,7 @@ export default class FrontendModelController extends Controller {
2206
1859
  queryMetadata[frontendModelJoinedPathsSymbol] = joinedPaths;
2207
1860
  }
2208
1861
  /**
1862
+ * Runs frontend model selected attributes for model class.
2209
1863
  * @param {typeof import("./database/record/index.js").default} modelClass - Model class.
2210
1864
  * @returns {string[] | null} - Selected attributes for model class.
2211
1865
  */
@@ -2216,6 +1870,7 @@ export default class FrontendModelController extends Controller {
2216
1870
  return select[modelClass.getModelName()] || null;
2217
1871
  }
2218
1872
  /**
1873
+ * Runs frontend model selects extra for model class.
2219
1874
  * @param {typeof import("./database/record/index.js").default} modelClass - Model class.
2220
1875
  * @returns {string[] | null} - Extra attributes (loaded in addition to the defaults) for the model class.
2221
1876
  */
@@ -2244,6 +1899,7 @@ export default class FrontendModelController extends Controller {
2244
1899
  return Array.from(new Set([...defaultAttributes, ...extraAttributes]));
2245
1900
  }
2246
1901
  /**
1902
+ * Runs frontend model default attributes for model class.
2247
1903
  * @param {typeof import("./database/record/index.js").default} modelClass - Model class.
2248
1904
  * @returns {string[] | null} - Default frontend-model attributes declared on the resource.
2249
1905
  */
@@ -2257,25 +1913,31 @@ export default class FrontendModelController extends Controller {
2257
1913
  .filter((entry) => {
2258
1914
  if (typeof entry === "string")
2259
1915
  return true;
2260
- const config = /** @type {Record<string, any>} */ (entry);
1916
+ const config = /**
1917
+ * Types the following value.
1918
+ @type {Record<string, ?>} */ (entry);
2261
1919
  if (config && config.selectedByDefault === false)
2262
1920
  return false;
2263
1921
  return true;
2264
1922
  })
2265
- .map((entry) => typeof entry === "string" ? entry : /** @type {Record<string, any>} */ (entry).name);
1923
+ .map((entry) => typeof entry === "string" ? entry : /**
1924
+ * Types the following value.
1925
+ @type {Record<string, ?>} */
1926
+ (entry).name);
2266
1927
  }
2267
1928
  if (typeof attributes === "object") {
2268
1929
  return Object.entries(attributes)
2269
1930
  .filter(([, config]) => {
2270
1931
  if (!config || typeof config !== "object")
2271
1932
  return true;
2272
- return /** @type {Record<string, any>} */ (config).selectedByDefault !== false;
1933
+ return /** Narrows the runtime value to the documented type. @type {Record<string, ?>} */ (config).selectedByDefault !== false;
2273
1934
  })
2274
1935
  .map(([name]) => name);
2275
1936
  }
2276
1937
  return null;
2277
1938
  }
2278
1939
  /**
1940
+ * Runs frontend model non default attributes for model class.
2279
1941
  * @param {typeof import("./database/record/index.js").default} modelClass - Model class.
2280
1942
  * @returns {string[]} - Attribute names explicitly marked selectedByDefault: false.
2281
1943
  */
@@ -2289,35 +1951,58 @@ export default class FrontendModelController extends Controller {
2289
1951
  .filter((entry) => {
2290
1952
  if (typeof entry !== "object" || !entry)
2291
1953
  return false;
2292
- return /** @type {Record<string, any>} */ (entry).selectedByDefault === false;
1954
+ return /** Narrows the runtime value to the documented type. @type {Record<string, ?>} */ (entry).selectedByDefault === false;
2293
1955
  })
2294
- .map((entry) => /** @type {Record<string, any>} */ ( /** @type {unknown} */(entry)).name);
1956
+ .map((entry) => /**
1957
+ * Types the following value.
1958
+ @type {Record<string, ?>} */ ( /**
1959
+ * Types the following value.
1960
+ @type {?} */(entry)).name);
2295
1961
  }
2296
1962
  if (typeof attributes === "object") {
2297
1963
  return Object.entries(attributes)
2298
- .filter(([, config]) => typeof config === "object" && config && /** @type {Record<string, any>} */ (config).selectedByDefault === false)
1964
+ .filter(([, config]) => typeof config === "object" && config && /**
1965
+ * Types the following value.
1966
+ @type {Record<string, ?>} */
1967
+ (config).selectedByDefault === false)
2299
1968
  .map(([name]) => name);
2300
1969
  }
2301
1970
  return [];
2302
1971
  }
2303
1972
  /**
1973
+ * Runs serialize frontend model attributes.
2304
1974
  * @param {import("./database/record/index.js").default} model - Model instance.
2305
- * @returns {Promise<Record<string, any>>} - Serialized attributes filtered by select map.
1975
+ * @returns {Promise<Record<string, ?>>} - Serialized attributes filtered by select map.
2306
1976
  */
2307
1977
  async serializeFrontendModelAttributes(model) {
2308
- const modelClass = /** @type {typeof import("./database/record/index.js").default} */ (model.constructor);
1978
+ const modelClass = /**
1979
+ * Types the following value.
1980
+ @type {typeof import("./database/record/index.js").default} */ (model.constructor);
2309
1981
  const modelAttributes = model.attributes();
2310
1982
  const selectedAttributes = this.frontendModelEffectiveSelectedAttributesForModelClass(modelClass, Object.keys(modelAttributes));
2311
1983
  const defaultAttributes = this.frontendModelDefaultAttributesForModelClass(modelClass);
2312
1984
  const resourceInstance = this._serializationResourceInstanceForModel(model);
2313
- /** @param {string} attributeName - Attribute name. */
1985
+ /**
1986
+ * Resource attribute method name.
1987
+ * @param {string} attributeName - Attribute name.
1988
+ */
2314
1989
  const resourceAttributeMethodName = (attributeName) => `${attributeName}Attribute`;
2315
- /** @param {string} attributeName - Attribute name. */
1990
+ /**
1991
+ * Resource has attribute.
1992
+ * @param {string} attributeName - Attribute name.
1993
+ */
2316
1994
  const resourceHasAttribute = (attributeName) => {
2317
1995
  const methodName = resourceAttributeMethodName(attributeName);
2318
- return resourceInstance && typeof /** @type {Record<string, any>} */ ( /** @type {unknown} */(resourceInstance))[methodName] === "function";
1996
+ return resourceInstance && typeof /**
1997
+ * Types the following value.
1998
+ @type {Record<string, ?>} */ ( /**
1999
+ * Types the following value.
2000
+ @type {?} */(resourceInstance))[methodName] === "function";
2319
2001
  };
2320
- /** @param {string} attributeName - Attribute name. */
2002
+ /**
2003
+ * Prototype attribute method.
2004
+ * @param {string} attributeName - Attribute name.
2005
+ */
2321
2006
  const prototypeAttributeMethod = (attributeName) => {
2322
2007
  let currentPrototype = Object.getPrototypeOf(model);
2323
2008
  while (currentPrototype && currentPrototype !== Object.prototype) {
@@ -2331,12 +2016,19 @@ export default class FrontendModelController extends Controller {
2331
2016
  currentPrototype = Object.getPrototypeOf(currentPrototype);
2332
2017
  }
2333
2018
  };
2334
- /** @param {string} attributeName - Attribute name. */
2019
+ /**
2020
+ * Serialized attribute value.
2021
+ * @param {string} attributeName - Attribute name.
2022
+ */
2335
2023
  const serializedAttributeValue = async (attributeName) => {
2336
2024
  // Check resource instance first (virtual/computed attributes via ${name}Attribute convention)
2337
2025
  if (resourceHasAttribute(attributeName)) {
2338
2026
  const methodName = resourceAttributeMethodName(attributeName);
2339
- return await /** @type {Record<string, Function>} */ ( /** @type {unknown} */(resourceInstance))[methodName](model);
2027
+ return await /**
2028
+ * Types the following value.
2029
+ @type {Record<string, Function>} */ ( /**
2030
+ * Types the following value.
2031
+ @type {?} */(resourceInstance))[methodName](model);
2340
2032
  }
2341
2033
  // Fall back to model method
2342
2034
  const attributeMethodLookup = prototypeAttributeMethod(attributeName);
@@ -2346,9 +2038,15 @@ export default class FrontendModelController extends Controller {
2346
2038
  }
2347
2039
  return modelAttributes[attributeName];
2348
2040
  };
2349
- /** @param {string} attributeName - Attribute name. */
2041
+ /**
2042
+ * Attribute exists.
2043
+ * @param {string} attributeName - Attribute name.
2044
+ */
2350
2045
  const attributeExists = (attributeName) => {
2351
- return (attributeName in modelAttributes) || (attributeName in /** @type {Record<string, any>} */ (model)) || resourceHasAttribute(attributeName);
2046
+ return (attributeName in modelAttributes) || (attributeName in /**
2047
+ * Types the following value.
2048
+ @type {Record<string, ?>} */
2049
+ (model)) || resourceHasAttribute(attributeName);
2352
2050
  };
2353
2051
  if (!selectedAttributes) {
2354
2052
  if (!defaultAttributes || defaultAttributes.length < 1) {
@@ -2366,7 +2064,9 @@ export default class FrontendModelController extends Controller {
2366
2064
  }
2367
2065
  return serializedAttributes;
2368
2066
  }
2369
- /** @type {Record<string, any>} */
2067
+ /**
2068
+ * Serialized attributes.
2069
+ @type {Record<string, ?>} */
2370
2070
  const serializedAttributes = {};
2371
2071
  for (const attributeName of selectedAttributes) {
2372
2072
  if (!attributeExists(attributeName))
@@ -2376,6 +2076,7 @@ export default class FrontendModelController extends Controller {
2376
2076
  return serializedAttributes;
2377
2077
  }
2378
2078
  /**
2079
+ * Runs serialization resource instance for model.
2379
2080
  * @param {import("./database/record/index.js").default} model - Model instance.
2380
2081
  * @returns {import("./frontend-model-resource/base-resource.js").default | null} - Resource instance or null.
2381
2082
  */
@@ -2386,7 +2087,9 @@ export default class FrontendModelController extends Controller {
2386
2087
  }
2387
2088
  const configuration = this.getConfiguration();
2388
2089
  const backendProjects = configuration.getBackendProjects?.() || [];
2389
- const modelClassName = /** @type {typeof import("./database/record/index.js").default} */ (model.constructor).getModelName();
2090
+ const modelClassName = /**
2091
+ * Types the following value.
2092
+ @type {typeof import("./database/record/index.js").default} */ (model.constructor).getModelName();
2390
2093
  for (const backendProject of backendProjects) {
2391
2094
  const resources = frontendModelResourcesForBackendProject(backendProject);
2392
2095
  const resourceDefinition = resources[modelClassName];
@@ -2396,16 +2099,21 @@ export default class FrontendModelController extends Controller {
2396
2099
  ability: this.currentAbility(),
2397
2100
  context: this.currentAbility()?.getContext() || {},
2398
2101
  locals: this.currentAbility()?.getLocals() || {},
2399
- modelClass: /** @type {typeof import("./database/record/index.js").default} */ (model.constructor),
2102
+ modelClass: /**
2103
+ * Types the following value.
2104
+ @type {typeof import("./database/record/index.js").default} */ (model.constructor),
2400
2105
  modelName: modelClassName,
2401
2106
  params: {},
2402
- resourceConfiguration: /** @type {import("./configuration-types.js").FrontendModelResourceConfiguration | undefined} */ (typeof resourceClass.resourceConfig === "function" ? resourceClass.resourceConfig() : undefined)
2107
+ resourceConfiguration: /**
2108
+ * Types the following value.
2109
+ @type {import("./configuration-types.js").FrontendModelResourceConfiguration | undefined} */ (typeof resourceClass.resourceConfig === "function" ? resourceClass.resourceConfig() : undefined)
2403
2110
  });
2404
2111
  }
2405
2112
  }
2406
2113
  return null;
2407
2114
  }
2408
2115
  /**
2116
+ * Runs frontend model filter serializable related models.
2409
2117
  * @param {object} args - Arguments.
2410
2118
  * @param {import("./database/record/index.js").default[]} args.models - Frontend model records.
2411
2119
  * @param {boolean} args.relationshipIsCollection - Whether relation is has-many.
@@ -2416,17 +2124,25 @@ export default class FrontendModelController extends Controller {
2416
2124
  return models;
2417
2125
  if (models.length === 0)
2418
2126
  return models;
2419
- /** @type {Map<typeof import("./database/record/index.js").default, import("./database/record/index.js").default[]>} */
2127
+ /**
2128
+ * Models by class.
2129
+ @type {Map<typeof import("./database/record/index.js").default, import("./database/record/index.js").default[]>} */
2420
2130
  const modelsByClass = new Map();
2421
2131
  for (const model of models) {
2422
- const relatedModelClass = /** @type {typeof import("./database/record/index.js").default} */ (model.constructor);
2132
+ const relatedModelClass = /**
2133
+ * Types the following value.
2134
+ @type {typeof import("./database/record/index.js").default} */ (model.constructor);
2423
2135
  const existingModelsForClass = modelsByClass.get(relatedModelClass) || [];
2424
2136
  existingModelsForClass.push(model);
2425
2137
  modelsByClass.set(relatedModelClass, existingModelsForClass);
2426
2138
  }
2427
- /** @type {Map<typeof import("./database/record/index.js").default, Set<string>>} */
2139
+ /**
2140
+ * Authorized ids by class.
2141
+ @type {Map<typeof import("./database/record/index.js").default, Set<string>>} */
2428
2142
  const authorizedIdsByClass = new Map();
2429
- /** @type {Map<typeof import("./database/record/index.js").default, string>} */
2143
+ /**
2144
+ * Primary keys by class.
2145
+ @type {Map<typeof import("./database/record/index.js").default, string>} */
2430
2146
  const primaryKeysByClass = new Map();
2431
2147
  for (const [relatedModelClass, relatedModels] of modelsByClass.entries()) {
2432
2148
  const relatedResource = this.frontendModelResourceConfigurationForModelClass(relatedModelClass);
@@ -2457,7 +2173,9 @@ export default class FrontendModelController extends Controller {
2457
2173
  authorizedIdsByClass.set(relatedModelClass, new Set(authorizedIdsRaw.map((id) => String(id))));
2458
2174
  }
2459
2175
  return models.filter((model) => {
2460
- const relatedModelClass = /** @type {typeof import("./database/record/index.js").default} */ (model.constructor);
2176
+ const relatedModelClass = /**
2177
+ * Types the following value.
2178
+ @type {typeof import("./database/record/index.js").default} */ (model.constructor);
2461
2179
  const authorizedIds = authorizedIdsByClass.get(relatedModelClass);
2462
2180
  const primaryKey = primaryKeysByClass.get(relatedModelClass);
2463
2181
  if (!authorizedIds || !primaryKey)
@@ -2469,27 +2187,39 @@ export default class FrontendModelController extends Controller {
2469
2187
  });
2470
2188
  }
2471
2189
  /**
2472
- * @param {unknown} value - Candidate preloaded value.
2190
+ * Runs is serializable frontend model.
2191
+ * @param {?} value - Candidate preloaded value.
2473
2192
  * @returns {value is import("./database/record/index.js").default} - Whether value behaves like a model.
2474
2193
  */
2475
2194
  isSerializableFrontendModel(value) {
2476
- return Boolean(value && typeof value === "object" && typeof /** @type {any} */ (value).attributes === "function");
2195
+ return Boolean(value && typeof value === "object" && typeof /**
2196
+ * Types the following value.
2197
+ @type {?} */ (value).attributes === "function");
2477
2198
  }
2478
2199
  /**
2200
+ * Runs serialize frontend models.
2479
2201
  * @param {import("./database/record/index.js").default[]} models - Models to serialize.
2480
- * @returns {Promise<Record<string, any>[]>} - Serialized model payloads.
2202
+ * @returns {Promise<Record<string, ?>[]>} - Serialized model payloads.
2481
2203
  */
2482
2204
  async serializeFrontendModels(models) {
2483
2205
  if (models.length < 1)
2484
2206
  return [];
2485
- /** @type {Array<Record<string, any>>} */
2207
+ /**
2208
+ * Preloaded relationships per model.
2209
+ @type {Array<Record<string, ?>>} */
2486
2210
  const preloadedRelationshipsPerModel = Array.from({ length: models.length }, () => ({}));
2487
- /** @type {Array<{loadedModels: import("./database/record/index.js").default[], modelIndex: number, relationshipName: string}>} */
2211
+ /**
2212
+ * Collection relationship entries.
2213
+ @type {Array<{loadedModels: import("./database/record/index.js").default[], modelIndex: number, relationshipName: string}>} */
2488
2214
  const collectionRelationshipEntries = [];
2489
- /** @type {Array<{loadedModel: import("./database/record/index.js").default, modelIndex: number, relationshipName: string}>} */
2215
+ /**
2216
+ * Singular relationship entries.
2217
+ @type {Array<{loadedModel: import("./database/record/index.js").default, modelIndex: number, relationshipName: string}>} */
2490
2218
  const singularRelationshipEntries = [];
2491
2219
  models.forEach((model, modelIndex) => {
2492
- const modelClass = /** @type {typeof import("./database/record/index.js").default} */ (model.constructor);
2220
+ const modelClass = /**
2221
+ * Types the following value.
2222
+ @type {typeof import("./database/record/index.js").default} */ (model.constructor);
2493
2223
  const relationshipsMap = modelClass.getRelationshipsMap();
2494
2224
  for (const relationshipName in relationshipsMap) {
2495
2225
  const relationship = model.getRelationshipByName(relationshipName);
@@ -2536,7 +2266,9 @@ export default class FrontendModelController extends Controller {
2536
2266
  preloadedRelationshipsPerModel[relationshipEntry.modelIndex][relationshipEntry.relationshipName] = serializedModel;
2537
2267
  }
2538
2268
  }
2539
- /** @type {Record<string, any>[]} */
2269
+ /**
2270
+ * Serialized models.
2271
+ @type {Record<string, ?>[]} */
2540
2272
  const serializedModels = [];
2541
2273
  for (const [modelIndex, model] of models.entries()) {
2542
2274
  const serializedAttributes = await this.serializeFrontendModelAttributes(model);
@@ -2558,7 +2290,9 @@ export default class FrontendModelController extends Controller {
2558
2290
  serializedModels.push(serializedAttributes);
2559
2291
  continue;
2560
2292
  }
2561
- /** @type {Record<string, any>} */
2293
+ /**
2294
+ * Serialized.
2295
+ @type {Record<string, ?>} */
2562
2296
  const serialized = { ...serializedAttributes };
2563
2297
  if (hasPreloaded)
2564
2298
  serialized.__preloadedRelationships = preloadedRelationships;
@@ -2573,35 +2307,44 @@ export default class FrontendModelController extends Controller {
2573
2307
  return serializedModels;
2574
2308
  }
2575
2309
  /**
2310
+ * Runs serialize frontend model.
2576
2311
  * @param {import("./database/record/index.js").default} model - Frontend model record.
2577
- * @returns {Promise<Record<string, any>>} - Serialized frontend model payload.
2312
+ * @returns {Promise<Record<string, ?>>} - Serialized frontend model payload.
2578
2313
  */
2579
2314
  async serializeFrontendModel(model) {
2580
2315
  const serializedModels = await this.serializeFrontendModels([model]);
2581
2316
  return serializedModels[0];
2582
2317
  }
2583
2318
  /**
2319
+ * Runs frontend model render error.
2584
2320
  * @param {string} errorMessage - Error message.
2585
2321
  * @returns {Promise<void>} - Resolves when error has been rendered.
2586
2322
  */
2587
2323
  async frontendModelRenderError(errorMessage) {
2588
2324
  await this.logger.error(`Frontend model request failed: ${errorMessage}`);
2589
- const renderError = /** @type {((errorMessage: string) => Promise<void>) | undefined} */ (
2590
- /** @type {any} */ (this).renderError);
2325
+ const renderError = /**
2326
+ * Types the following value.
2327
+ @type {((errorMessage: string) => Promise<void>) | undefined} */ (
2328
+ /**
2329
+ * Types the following value.
2330
+ @type {?} */ (this).renderError);
2591
2331
  if (typeof renderError === "function") {
2592
2332
  await renderError.call(this, frontendModelClientSafeErrorMessage);
2593
2333
  return;
2594
2334
  }
2595
2335
  await this.render({
2596
- json: /** @type {Record<string, any>} */ (serializeFrontendModelTransportValue({
2336
+ json: /**
2337
+ * Types the following value.
2338
+ @type {Record<string, ?>} */ (serializeFrontendModelTransportValue({
2597
2339
  errorMessage: frontendModelClientSafeErrorMessage,
2598
2340
  status: "error"
2599
2341
  }))
2600
2342
  });
2601
2343
  }
2602
2344
  /**
2345
+ * Runs frontend model error payload.
2603
2346
  * @param {string} errorMessage - Error message.
2604
- * @returns {Record<string, any>} - Error payload.
2347
+ * @returns {Record<string, ?>} - Error payload.
2605
2348
  */
2606
2349
  frontendModelErrorPayload(errorMessage) {
2607
2350
  return {
@@ -2610,14 +2353,16 @@ export default class FrontendModelController extends Controller {
2610
2353
  };
2611
2354
  }
2612
2355
  /**
2613
- * @returns {Record<string, any>} - Client-safe error payload.
2356
+ * Runs frontend model client safe error payload.
2357
+ * @returns {Record<string, ?>} - Client-safe error payload.
2614
2358
  */
2615
2359
  frontendModelClientSafeErrorPayload() {
2616
2360
  return this.frontendModelErrorPayload(frontendModelClientSafeErrorMessage);
2617
2361
  }
2618
2362
  /**
2619
- * @param {unknown} error - Caught error.
2620
- * @returns {Record<string, any>} - Client payload for the current environment.
2363
+ * Runs frontend model client error payload for error.
2364
+ * @param {?} error - Caught error.
2365
+ * @returns {Record<string, ?>} - Client payload for the current environment.
2621
2366
  */
2622
2367
  frontendModelClientErrorPayloadForError(error) {
2623
2368
  const velociousMetadata = frontendModelVelociousMetadataForError(error);
@@ -2625,7 +2370,9 @@ export default class FrontendModelController extends Controller {
2625
2370
  if (error instanceof ValidationError) {
2626
2371
  const validationErrors = error.getValidationErrors();
2627
2372
  const model = error.getModel();
2628
- /** @type {Record<string, {type: string, message: string, fullMessage: string}[]>} */
2373
+ /**
2374
+ * Structured errors.
2375
+ @type {Record<string, {type: string, message: string, fullMessage: string}[]>} */
2629
2376
  const structuredErrors = {};
2630
2377
  for (const attributeName in validationErrors) {
2631
2378
  structuredErrors[attributeName] = validationErrors[attributeName].map(err => ({
@@ -2651,9 +2398,10 @@ export default class FrontendModelController extends Controller {
2651
2398
  };
2652
2399
  }
2653
2400
  /**
2401
+ * Runs frontend model log endpoint error.
2654
2402
  * @param {object} args - Error log args.
2655
2403
  * @param {string} args.action - Endpoint/action label.
2656
- * @param {unknown} args.error - Caught error.
2404
+ * @param {?} args.error - Caught error.
2657
2405
  * @param {"index" | "find" | "create" | "update" | "destroy" | "attach" | "download" | "url" | "custom-command"} [args.commandType] - Frontend-model command type.
2658
2406
  * @param {string | undefined} [args.model] - Request model name when available.
2659
2407
  * @param {string | undefined} [args.requestId] - Batch request id when available.
@@ -2689,6 +2437,7 @@ export default class FrontendModelController extends Controller {
2689
2437
  }]);
2690
2438
  }
2691
2439
  /**
2440
+ * Runs frontend model render command response.
2692
2441
  * @param {"index" | "find" | "create" | "update" | "destroy" | "attach" | "download" | "url"} action - Frontend action.
2693
2442
  * @returns {Promise<void>} - Resolves when response has been rendered.
2694
2443
  */
@@ -2698,19 +2447,24 @@ export default class FrontendModelController extends Controller {
2698
2447
  if (!responsePayload)
2699
2448
  return;
2700
2449
  await this.render({
2701
- json: /** @type {Record<string, any>} */ (serializeFrontendModelTransportValue(responsePayload))
2450
+ json: /**
2451
+ * Types the following value.
2452
+ @type {Record<string, ?>} */ (serializeFrontendModelTransportValue(responsePayload))
2702
2453
  });
2703
2454
  }
2704
2455
  catch (error) {
2705
2456
  await this.frontendModelLogEndpointError({ action, commandType: action, error });
2706
2457
  await this.render({
2707
- json: /** @type {Record<string, any>} */ (serializeFrontendModelTransportValue(this.frontendModelClientErrorPayloadForError(error)))
2458
+ json: /**
2459
+ * Types the following value.
2460
+ @type {Record<string, ?>} */ (serializeFrontendModelTransportValue(this.frontendModelClientErrorPayloadForError(error)))
2708
2461
  });
2709
2462
  }
2710
2463
  }
2711
2464
  /**
2465
+ * Runs frontend model command payload.
2712
2466
  * @param {"index" | "find" | "create" | "update" | "destroy" | "attach" | "download" | "url"} action - Frontend action.
2713
- * @returns {Promise<Record<string, any> | null>} - Response payload.
2467
+ * @returns {Promise<Record<string, ?> | null>} - Response payload.
2714
2468
  */
2715
2469
  async frontendModelCommandPayload(action) {
2716
2470
  await this.ensureFrontendModelClassInitialized();
@@ -2754,22 +2508,15 @@ export default class FrontendModelController extends Controller {
2754
2508
  const modelClass = this.frontendModelClass();
2755
2509
  const id = params.id;
2756
2510
  if (action === "create") {
2757
- const attributes = params.attributes;
2758
- if (!attributes || typeof attributes !== "object") {
2759
- return this.frontendModelErrorPayload("Expected model attributes.");
2760
- }
2761
- const nestedAttributes = params.nestedAttributes && typeof params.nestedAttributes === "object"
2762
- ? /** @type {Record<string, any>} */ (params.nestedAttributes)
2763
- : null;
2764
- const model = await this.frontendModelCreateRecord(attributes, nestedAttributes);
2511
+ const mutationAttributes = frontendModelMutationAttributes(params);
2512
+ if (typeof mutationAttributes === "string")
2513
+ return this.frontendModelErrorPayload(mutationAttributes);
2514
+ const model = await this.frontendModelCreateRecord(mutationAttributes.attributes, mutationAttributes.nestedAttributes);
2765
2515
  if (!model) {
2766
2516
  return this.frontendModelErrorPayload(`${modelClass.name} not found.`);
2767
2517
  }
2768
2518
  const serializedModel = await resource.serialize(model, "create");
2769
- return {
2770
- model: serializedModel,
2771
- status: "success"
2772
- };
2519
+ return frontendModelSerializedModelSuccess(serializedModel);
2773
2520
  }
2774
2521
  if ((typeof id !== "string" && typeof id !== "number") || `${id}`.length < 1) {
2775
2522
  return this.frontendModelErrorPayload("Expected model id.");
@@ -2789,22 +2536,17 @@ export default class FrontendModelController extends Controller {
2789
2536
  }
2790
2537
  await model.getAttachmentByName(attachmentName).attach(attachmentInput);
2791
2538
  const serializedModel = await this.serializeFrontendModel(model);
2792
- return {
2793
- model: serializedModel,
2794
- status: "success"
2795
- };
2539
+ return frontendModelSerializedModelSuccess(serializedModel);
2796
2540
  }
2797
2541
  if (action === "download") {
2798
- const attachmentName = params.attachmentName;
2799
- const attachmentId = typeof params.attachmentId === "string" ? params.attachmentId : undefined;
2800
- if (typeof attachmentName !== "string" || attachmentName.length < 1) {
2801
- return this.frontendModelErrorPayload("Expected attachmentName.");
2802
- }
2542
+ const attachmentParams = frontendModelAttachmentParams(params);
2543
+ if (typeof attachmentParams === "string")
2544
+ return this.frontendModelErrorPayload(attachmentParams);
2803
2545
  const model = await this.frontendModelFindRecord("download", id);
2804
2546
  if (!model) {
2805
2547
  return this.frontendModelErrorPayload(`${modelClass.name} not found.`);
2806
2548
  }
2807
- const downloadedAttachment = await model.getAttachmentByName(attachmentName).download(attachmentId);
2549
+ const downloadedAttachment = await model.getAttachmentByName(attachmentParams.attachmentName).download(attachmentParams.attachmentId);
2808
2550
  if (!downloadedAttachment) {
2809
2551
  return this.frontendModelErrorPayload("Attachment not found.");
2810
2552
  }
@@ -2821,16 +2563,14 @@ export default class FrontendModelController extends Controller {
2821
2563
  };
2822
2564
  }
2823
2565
  if (action === "url") {
2824
- const attachmentName = params.attachmentName;
2825
- const attachmentId = typeof params.attachmentId === "string" ? params.attachmentId : undefined;
2826
- if (typeof attachmentName !== "string" || attachmentName.length < 1) {
2827
- return this.frontendModelErrorPayload("Expected attachmentName.");
2828
- }
2566
+ const attachmentParams = frontendModelAttachmentParams(params);
2567
+ if (typeof attachmentParams === "string")
2568
+ return this.frontendModelErrorPayload(attachmentParams);
2829
2569
  const model = await this.frontendModelFindRecord("url", id);
2830
2570
  if (!model) {
2831
2571
  return this.frontendModelErrorPayload(`${modelClass.name} not found.`);
2832
2572
  }
2833
- const url = await model.getAttachmentByName(attachmentName).url(attachmentId);
2573
+ const url = await model.getAttachmentByName(attachmentParams.attachmentName).url(attachmentParams.attachmentId);
2834
2574
  if (!url) {
2835
2575
  return this.frontendModelErrorPayload("Attachment URL not available.");
2836
2576
  }
@@ -2846,29 +2586,19 @@ export default class FrontendModelController extends Controller {
2846
2586
  }
2847
2587
  await this.frontendModelComputeAbilities([model]);
2848
2588
  const serializedModel = await resource.serialize(model, "find");
2849
- return {
2850
- model: serializedModel,
2851
- status: "success"
2852
- };
2589
+ return frontendModelSerializedModelSuccess(serializedModel);
2853
2590
  }
2854
2591
  if (action === "update") {
2855
- const attributes = params.attributes;
2856
- if (!attributes || typeof attributes !== "object") {
2857
- return this.frontendModelErrorPayload("Expected model attributes.");
2858
- }
2859
- const nestedAttributes = params.nestedAttributes && typeof params.nestedAttributes === "object"
2860
- ? /** @type {Record<string, any>} */ (params.nestedAttributes)
2861
- : null;
2592
+ const mutationAttributes = frontendModelMutationAttributes(params);
2593
+ if (typeof mutationAttributes === "string")
2594
+ return this.frontendModelErrorPayload(mutationAttributes);
2862
2595
  const model = await this.frontendModelFindRecord("update", id);
2863
2596
  if (!model) {
2864
2597
  return this.frontendModelErrorPayload(`${modelClass.name} not found.`);
2865
2598
  }
2866
- const updatedModel = await resource.update(model, attributes, { nestedAttributes, controller: this });
2599
+ const updatedModel = await resource.update(model, mutationAttributes.attributes, { nestedAttributes: mutationAttributes.nestedAttributes, controller: this });
2867
2600
  const serializedModel = await resource.serialize(updatedModel, "update");
2868
- return {
2869
- model: serializedModel,
2870
- status: "success"
2871
- };
2601
+ return frontendModelSerializedModelSuccess(serializedModel);
2872
2602
  }
2873
2603
  const model = await this.frontendModelFindRecord("destroy", id);
2874
2604
  if (!model) {
@@ -2877,15 +2607,22 @@ export default class FrontendModelController extends Controller {
2877
2607
  await resource.destroy(model);
2878
2608
  return { status: "success" };
2879
2609
  }
2880
- /** @returns {Promise<void>} - Shared frontend model API action with batch support. */
2610
+ /**
2611
+ * Runs frontend api.
2612
+ * @returns {Promise<void>} - Shared frontend model API action with batch support.
2613
+ */
2881
2614
  async frontendApi() {
2882
2615
  if (this.request().httpMethod() === "OPTIONS") {
2883
2616
  await this.render({ status: 204, json: {} });
2884
2617
  return;
2885
2618
  }
2886
- const params = /** @type {Record<string, any>} */ (deserializeFrontendModelTransportValue(this.params()));
2619
+ const params = /**
2620
+ * Types the following value.
2621
+ @type {Record<string, ?>} */ (deserializeFrontendModelTransportValue(this.params()));
2887
2622
  const requests = Array.isArray(params.requests) ? params.requests : [params];
2888
- /** @type {Array<Record<string, any>>} */
2623
+ /**
2624
+ * Responses.
2625
+ @type {Array<Record<string, ?>>} */
2889
2626
  const responses = [];
2890
2627
  for (const requestEntry of requests) {
2891
2628
  const commandType = requestEntry?.commandType;
@@ -2947,7 +2684,9 @@ export default class FrontendModelController extends Controller {
2947
2684
  }
2948
2685
  }
2949
2686
  await this.render({
2950
- json: /** @type {Record<string, any>} */ (serializeFrontendModelTransportValue({
2687
+ json: /**
2688
+ * Types the following value.
2689
+ @type {Record<string, ?>} */ (serializeFrontendModelTransportValue({
2951
2690
  responses,
2952
2691
  status: "success"
2953
2692
  }))
@@ -2957,8 +2696,8 @@ export default class FrontendModelController extends Controller {
2957
2696
  * Dispatches a custom frontend-model command through the shared frontend-model API endpoint.
2958
2697
  * @param {object} args - Arguments.
2959
2698
  * @param {string} args.customPath - Custom backend route path.
2960
- * @param {unknown} args.payload - Request payload.
2961
- * @returns {Promise<Record<string, any>>} - Parsed JSON response payload.
2699
+ * @param {?} args.payload - Request payload.
2700
+ * @returns {Promise<Record<string, ?>>} - Parsed JSON response payload.
2962
2701
  */
2963
2702
  async frontendApiCustomCommandPayload({ customPath, payload }) {
2964
2703
  const configuration = this.getConfiguration();
@@ -2997,13 +2736,19 @@ export default class FrontendModelController extends Controller {
2997
2736
  configuration,
2998
2737
  controller,
2999
2738
  params: controllerParams,
3000
- request: /** @type {import("./http-server/client/request.js").default} */ (this.getRequest()),
2739
+ request: /**
2740
+ * Types the following value.
2741
+ @type {import("./http-server/client/request.js").default} */ (this.getRequest()),
3001
2742
  response,
3002
2743
  viewPath
3003
2744
  });
3004
2745
  await this.withFrontendModelRequestContext(controllerParams, response, async () => {
3005
2746
  await controllerInstance._runBeforeCallbacks();
3006
- const controllerMethods = /** @type {Record<string, () => Promise<void> | void>} */ ( /** @type {unknown} */(controllerInstance));
2747
+ const controllerMethods = /**
2748
+ * Types the following value.
2749
+ @type {Record<string, () => Promise<void> | void>} */ ( /**
2750
+ * Types the following value.
2751
+ @type {?} */(controllerInstance));
3007
2752
  await controllerMethods[action]();
3008
2753
  });
3009
2754
  const setCookieHeaders = response.headers["Set-Cookie"] || [];
@@ -3016,9 +2761,12 @@ export default class FrontendModelController extends Controller {
3016
2761
  }
3017
2762
  // Preserve nested transport markers so the outer shared frontend-model API
3018
2763
  // can return them unchanged and let the client hydrate once at the edge.
3019
- return /** @type {Record<string, any>} */ (JSON.parse(responseBody));
2764
+ return /** Narrows the runtime value to the documented type. @type {Record<string, ?>} */ (JSON.parse(responseBody));
3020
2765
  }
3021
- /** @returns {Promise<void>} - Collection action for frontend model resources. */
2766
+ /**
2767
+ * Runs frontend index.
2768
+ * @returns {Promise<void>} - Collection action for frontend model resources.
2769
+ */
3022
2770
  async frontendIndex() {
3023
2771
  if (this.request().httpMethod() === "OPTIONS") {
3024
2772
  await this.render({ status: 204, json: {} });
@@ -3026,7 +2774,10 @@ export default class FrontendModelController extends Controller {
3026
2774
  }
3027
2775
  await this.frontendModelRenderCommandResponse("index");
3028
2776
  }
3029
- /** @returns {Promise<void>} - Member find action for frontend model resources. */
2777
+ /**
2778
+ * Runs frontend find.
2779
+ * @returns {Promise<void>} - Member find action for frontend model resources.
2780
+ */
3030
2781
  async frontendFind() {
3031
2782
  if (this.request().httpMethod() === "OPTIONS") {
3032
2783
  await this.render({ status: 204, json: {} });
@@ -3034,7 +2785,10 @@ export default class FrontendModelController extends Controller {
3034
2785
  }
3035
2786
  await this.frontendModelRenderCommandResponse("find");
3036
2787
  }
3037
- /** @returns {Promise<void>} - Member update action for frontend model resources. */
2788
+ /**
2789
+ * Runs frontend update.
2790
+ * @returns {Promise<void>} - Member update action for frontend model resources.
2791
+ */
3038
2792
  async frontendUpdate() {
3039
2793
  if (this.request().httpMethod() === "OPTIONS") {
3040
2794
  await this.render({ status: 204, json: {} });
@@ -3042,7 +2796,10 @@ export default class FrontendModelController extends Controller {
3042
2796
  }
3043
2797
  await this.frontendModelRenderCommandResponse("update");
3044
2798
  }
3045
- /** @returns {Promise<void>} - Member attach action for frontend model resources. */
2799
+ /**
2800
+ * Runs frontend attach.
2801
+ * @returns {Promise<void>} - Member attach action for frontend model resources.
2802
+ */
3046
2803
  async frontendAttach() {
3047
2804
  if (this.request().httpMethod() === "OPTIONS") {
3048
2805
  await this.render({ status: 204, json: {} });
@@ -3050,7 +2807,10 @@ export default class FrontendModelController extends Controller {
3050
2807
  }
3051
2808
  await this.frontendModelRenderCommandResponse("attach");
3052
2809
  }
3053
- /** @returns {Promise<void>} - Member download action for frontend model resources. */
2810
+ /**
2811
+ * Runs frontend download.
2812
+ * @returns {Promise<void>} - Member download action for frontend model resources.
2813
+ */
3054
2814
  async frontendDownload() {
3055
2815
  if (this.request().httpMethod() === "OPTIONS") {
3056
2816
  await this.render({ status: 204, json: {} });
@@ -3058,7 +2818,10 @@ export default class FrontendModelController extends Controller {
3058
2818
  }
3059
2819
  await this.frontendModelRenderCommandResponse("download");
3060
2820
  }
3061
- /** @returns {Promise<void>} - Member URL action for frontend model resources. */
2821
+ /**
2822
+ * Runs frontend url.
2823
+ * @returns {Promise<void>} - Member URL action for frontend model resources.
2824
+ */
3062
2825
  async frontendUrl() {
3063
2826
  if (this.request().httpMethod() === "OPTIONS") {
3064
2827
  await this.render({ status: 204, json: {} });
@@ -3066,7 +2829,10 @@ export default class FrontendModelController extends Controller {
3066
2829
  }
3067
2830
  await this.frontendModelRenderCommandResponse("url");
3068
2831
  }
3069
- /** @returns {Promise<void>} - Member create action for frontend model resources. */
2832
+ /**
2833
+ * Runs frontend create.
2834
+ * @returns {Promise<void>} - Member create action for frontend model resources.
2835
+ */
3070
2836
  async frontendCreate() {
3071
2837
  if (this.request().httpMethod() === "OPTIONS") {
3072
2838
  await this.render({ status: 204, json: {} });
@@ -3074,7 +2840,10 @@ export default class FrontendModelController extends Controller {
3074
2840
  }
3075
2841
  await this.frontendModelRenderCommandResponse("create");
3076
2842
  }
3077
- /** @returns {Promise<void>} - Member destroy action for frontend model resources. */
2843
+ /**
2844
+ * Runs frontend destroy.
2845
+ * @returns {Promise<void>} - Member destroy action for frontend model resources.
2846
+ */
3078
2847
  async frontendDestroy() {
3079
2848
  if (this.request().httpMethod() === "OPTIONS") {
3080
2849
  await this.render({ status: 204, json: {} });
@@ -3082,7 +2851,10 @@ export default class FrontendModelController extends Controller {
3082
2851
  }
3083
2852
  await this.frontendModelRenderCommandResponse("destroy");
3084
2853
  }
3085
- /** @returns {Promise<void>} - Custom collection/member command action for frontend-model resources. */
2854
+ /**
2855
+ * Runs frontend custom command.
2856
+ * @returns {Promise<void>} - Custom collection/member command action for frontend-model resources.
2857
+ */
3086
2858
  async frontendCustomCommand() {
3087
2859
  if (this.request().httpMethod() === "OPTIONS") {
3088
2860
  await this.render({ status: 204, json: {} });
@@ -3091,17 +2863,24 @@ export default class FrontendModelController extends Controller {
3091
2863
  try {
3092
2864
  const responsePayload = await this.frontendModelCustomCommandPayload();
3093
2865
  await this.render({
3094
- json: /** @type {Record<string, any>} */ (serializeFrontendModelTransportValue(responsePayload))
2866
+ json: /**
2867
+ * Types the following value.
2868
+ @type {Record<string, ?>} */ (serializeFrontendModelTransportValue(responsePayload))
3095
2869
  });
3096
2870
  }
3097
2871
  catch (error) {
3098
2872
  await this.frontendModelLogEndpointError({ action: "frontendCustomCommand", commandType: "custom-command", error });
3099
2873
  await this.render({
3100
- json: /** @type {Record<string, any>} */ (serializeFrontendModelTransportValue(this.frontendModelClientErrorPayloadForError(error)))
2874
+ json: /**
2875
+ * Types the following value.
2876
+ @type {Record<string, ?>} */ (serializeFrontendModelTransportValue(this.frontendModelClientErrorPayloadForError(error)))
3101
2877
  });
3102
2878
  }
3103
2879
  }
3104
- /** @returns {Promise<Record<string, any>>} - Response payload. */
2880
+ /**
2881
+ * Runs frontend model custom command payload.
2882
+ * @returns {Promise<Record<string, ?>>} - Response payload.
2883
+ */
3105
2884
  async frontendModelCustomCommandPayload() {
3106
2885
  const params = this.frontendModelParams();
3107
2886
  const methodName = params.frontendModelCustomCommandMethodName;
@@ -3112,7 +2891,9 @@ export default class FrontendModelController extends Controller {
3112
2891
  if (scope !== "collection" && scope !== "member") {
3113
2892
  return this.frontendModelErrorPayload("Expected frontend-model custom command scope.");
3114
2893
  }
3115
- const resource = /** @type {Record<string, any>} */ (this.frontendModelResourceInstance());
2894
+ const resource = /**
2895
+ * Types the following value.
2896
+ @type {Record<string, ?>} */ (this.frontendModelResourceInstance());
3116
2897
  const commandMethod = resource[methodName];
3117
2898
  if (typeof commandMethod !== "function") {
3118
2899
  return this.frontendModelErrorPayload(`Missing frontend-model custom command '${methodName}'.`);
@@ -3121,8 +2902,10 @@ export default class FrontendModelController extends Controller {
3121
2902
  if (!responsePayload || typeof responsePayload !== "object") {
3122
2903
  return { status: "success" };
3123
2904
  }
3124
- return /** @type {Record<string, any>} */ (await this.autoSerializeFrontendModelsInPayload(responsePayload,
3125
- /** @type {{serialize: (model: unknown, action: string) => Promise<Record<string, any>>}} */ (resource), methodName));
2905
+ return /** Narrows the runtime value to the documented type. @type {Record<string, ?>} */ (await this.autoSerializeFrontendModelsInPayload(responsePayload,
2906
+ /**
2907
+ * Types the following value.
2908
+ @type {{serialize: (model: ?, action: string) => Promise<Record<string, ?>>}} */ (resource), methodName));
3126
2909
  }
3127
2910
  /**
3128
2911
  * Walks a custom-command response payload and replaces any backend `Record`
@@ -3131,12 +2914,11 @@ export default class FrontendModelController extends Controller {
3131
2914
  * `await this.serialize(record, action)`. Plain objects, arrays, and
3132
2915
  * primitive values pass through and are later encoded by
3133
2916
  * `serializeFrontendModelTransportValue`.
3134
- *
3135
- * @param {unknown} value - Payload value.
3136
- * @param {{serialize: (model: unknown, action: string) => Promise<Record<string, any>>}} resource - Resource instance providing `serialize`.
2917
+ * @param {?} value - Payload value.
2918
+ * @param {{serialize: (model: ?, action: string) => Promise<Record<string, ?>>}} resource - Resource instance providing `serialize`.
3137
2919
  * @param {string} action - Custom command method name passed to `resource.serialize` for per-action authorization filtering.
3138
2920
  * @param {WeakSet<object>} [seen] - Recursion stack of plain-object containers currently being walked. Membership is added on entry and removed on exit so a container shared between siblings (i.e. referenced twice but not cyclically) is walked on each reference instead of being short-circuited the second time, which would let backend `Record` instances inside it bypass `resource.serialize`.
3139
- * @returns {Promise<unknown>} - Payload with backend `Record` instances replaced by serialized markers.
2921
+ * @returns {Promise<?>} - Payload with backend `Record` instances replaced by serialized markers.
3140
2922
  */
3141
2923
  async autoSerializeFrontendModelsInPayload(value, resource, action, seen = new WeakSet()) {
3142
2924
  if (value === null || value === undefined) {
@@ -3144,7 +2926,9 @@ export default class FrontendModelController extends Controller {
3144
2926
  }
3145
2927
  if (isBackendModelInstance(value)) {
3146
2928
  const richSerialized = await resource.serialize(value, action);
3147
- const modelClass = /** @type {{constructor: {getModelName?: () => string, name?: string}}} */ (value).constructor;
2929
+ const modelClass = /**
2930
+ * Types the following value.
2931
+ @type {{constructor: {getModelName?: () => string, name?: string}}} */ (value).constructor;
3148
2932
  const modelName = typeof modelClass.getModelName === "function" ? modelClass.getModelName() : (modelClass.name || "");
3149
2933
  // Wrap the resource-serialized payload in the frontend_model transport
3150
2934
  // marker. Marker-based decoding routes through `instantiateFromResponse`,
@@ -3158,7 +2942,9 @@ export default class FrontendModelController extends Controller {
3158
2942
  };
3159
2943
  }
3160
2944
  if (Array.isArray(value)) {
3161
- /** @type {unknown[]} */
2945
+ /**
2946
+ * Result.
2947
+ @type {Array<?>} */
3162
2948
  const result = [];
3163
2949
  for (const entry of value) {
3164
2950
  result.push(await this.autoSerializeFrontendModelsInPayload(entry, resource, action, seen));
@@ -3166,7 +2952,9 @@ export default class FrontendModelController extends Controller {
3166
2952
  return result;
3167
2953
  }
3168
2954
  if (typeof value === "object" && Object.getPrototypeOf(value) === Object.prototype) {
3169
- const container = /** @type {Record<string, unknown>} */ (value);
2955
+ const container = /**
2956
+ * Types the following value.
2957
+ @type {Record<string, ?>} */ (value);
3170
2958
  if (seen.has(container)) {
3171
2959
  // Cyclic back-reference along the current recursion path; the
3172
2960
  // ancestor frame is still walking this container and will produce
@@ -3178,7 +2966,9 @@ export default class FrontendModelController extends Controller {
3178
2966
  }
3179
2967
  seen.add(container);
3180
2968
  try {
3181
- /** @type {Record<string, unknown>} */
2969
+ /**
2970
+ * Result.
2971
+ @type {Record<string, ?>} */
3182
2972
  const result = {};
3183
2973
  for (const [key, nested] of Object.entries(container)) {
3184
2974
  // `assignSafeProperty` stores keys like `__proto__` as own
@@ -3198,4 +2988,4 @@ export default class FrontendModelController extends Controller {
3198
2988
  return value;
3199
2989
  }
3200
2990
  }
3201
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZnJvbnRlbmQtbW9kZWwtY29udHJvbGxlci5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9mcm9udGVuZC1tb2RlbC1jb250cm9sbGVyLmpzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLFlBQVk7QUFFWixPQUFPLEtBQUssVUFBVSxNQUFNLFlBQVksQ0FBQTtBQUN4QyxPQUFPLFVBQVUsTUFBTSxpQkFBaUIsQ0FBQTtBQUN4QyxPQUFPLFFBQVEsTUFBTSxrQ0FBa0MsQ0FBQTtBQUN2RCxPQUFPLHlCQUF5QixNQUFNLDRDQUE0QyxDQUFBO0FBQ2xGLE9BQU8sRUFBQyx3Q0FBd0MsRUFBRSxnREFBZ0QsRUFBRSx5QkFBeUIsRUFBRSx1Q0FBdUMsRUFBQyxNQUFNLDBDQUEwQyxDQUFBO0FBQ3ZOLE9BQU8sRUFBQyxrQkFBa0IsRUFBRSxzQ0FBc0MsRUFBRSxzQkFBc0IsRUFBRSxvQ0FBb0MsRUFBQyxNQUFNLDhDQUE4QyxDQUFBO0FBQ3JMLE9BQU8sY0FBYyxNQUFNLHNCQUFzQixDQUFBO0FBQ2pELE9BQU8sRUFBQyxlQUFlLEVBQUMsTUFBTSw0QkFBNEIsQ0FBQTtBQUMxRCxPQUFPLGNBQWMsTUFBTSxzQkFBc0IsQ0FBQTtBQUVqRDs7O0dBR0c7QUFDSCxTQUFTLGFBQWEsQ0FBQyxLQUFLO0lBQzFCLElBQUksQ0FBQyxLQUFLLElBQUksT0FBTyxLQUFLLEtBQUssUUFBUSxJQUFJLEtBQUssQ0FBQyxPQUFPLENBQUMsS0FBSyxDQUFDO1FBQUUsT0FBTyxLQUFLLENBQUE7SUFFN0UsTUFBTSxTQUFTLEdBQUcsTUFBTSxDQUFDLGNBQWMsQ0FBQyxLQUFLLENBQUMsQ0FBQTtJQUU5QyxPQUFPLFNBQVMsS0FBSyxNQUFNLENBQUMsU0FBUyxJQUFJLFNBQVMsS0FBSyxJQUFJLENBQUE7QUFDN0QsQ0FBQztBQUVEOzs7R0FHRztBQUNILFNBQVMsNkJBQTZCLENBQUMsT0FBTztJQUM1QyxJQUFJLENBQUMsT0FBTztRQUFFLE9BQU8sSUFB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QUFHLHNDQUFzQyxDQUFDLENBQUMsS0FBSyxDQUFDLENBQUE7WUFFaEUsSUFBSSxJQUFJLENBQUMsR0FBRyxDQUFDLFNBQVMsQ0FBQyxFQUFFLENBQUM7Z0JBQ3hCLDhEQUE4RDtnQkFDOUQsa0VBQWtFO2dCQUNsRSw2REFBNkQ7Z0JBQzdELGtFQUFrRTtnQkFDbEUsZ0VBQWdFO2dCQUNoRSwrREFBK0Q7Z0JBQy9ELE9BQU8sU0FBUyxDQUFBO1lBQ2xCLENBQUM7WUFFRCxJQUFJLENBQUMsR0FBRyxDQUFDLFNBQVMsQ0FBQyxDQUFBO1lBRW5CLElBQUksQ0FBQztnQkFDSCxzQ0FBc0M7Z0JBQ3RDLE1BQU0sTUFBTSxHQUFHLEVBQUUsQ0FBQTtnQkFFakIsS0FBSyxNQUFNLENBQUMsR0FBRyxFQUFFLE1BQU0sQ0FBQyxJQUFJLE1BQU0sQ0FBQyxPQUFPLENBQUMsU0FBUyxDQUFDLEVBQUUsQ0FBQztvQkFDdEQsMkRBQTJEO29CQUMzRCw0REFBNEQ7b0JBQzVELHlEQUF5RDtvQkFDekQsOERBQThEO29CQUM5RCw2REFBNkQ7b0JBQzdELG1EQUFtRDtvQkFDbkQsa0JBQWtCLENBQUMsTUFBTSxFQUFFLEdBQUcsRUFBRSxNQUFNLElBQUksQ0FBQyxvQ0FBb0MsQ0FBQyxNQUFNLEVBQUUsUUFBUSxFQUFFLE1BQU0sRUFBRSxJQUFJLENBQUMsQ0FBQyxDQUFBO2dCQUNsSCxDQUFDO2dCQUVELE9BQU8sTUFBTSxDQUFBO1lBQ2YsQ0FBQztvQkFBUyxDQUFDO2dCQUNULElBQUksQ0FBQyxNQUFNLENBQUMsU0FBUyxDQUFDLENBQUE7WUFDeEIsQ0FBQztRQUNILENBQUM7UUFFRCxPQUFPLEtBQUssQ0FBQTtJQUNkLENBQUM7Q0FFRiIsInNvdXJjZXNDb250ZW50IjpbIi8vIEB0cy1jaGVja1xuXG5pbXBvcnQgKiBhcyBpbmZsZWN0aW9uIGZyb20gXCJpbmZsZWN0aW9uXCJcbmltcG9ydCBDb250cm9sbGVyIGZyb20gXCIuL2NvbnRyb2xsZXIuanNcIlxuaW1wb3J0IFJlc3BvbnNlIGZyb20gXCIuL2h0dHAtc2VydmVyL2NsaWVudC9yZXNwb25zZS5qc1wiXG5pbXBvcnQgRnJvbnRlbmRNb2RlbEJhc2VSZXNvdXJjZSBmcm9tIFwiLi9mcm9udGVuZC1tb2RlbC1yZXNvdXJjZS9iYXNlLXJlc291cmNlLmpzXCJcbmltcG9ydCB7ZnJvbnRlbmRNb2RlbFJlc291cmNlQ2xhc3NGcm9tRGVmaW5pdGlvbiwgZnJvbnRlbmRNb2RlbFJlc291cmNlQ29uZmlndXJhdGlvbkZyb21EZWZpbml0aW9uLCBmcm9udGVuZE1vZGVsUmVzb3VyY2VQYXRoLCBmcm9udGVuZE1vZGVsUmVzb3VyY2VzRm9yQmFja2VuZFByb2plY3R9IGZyb20gXCIuL2Zyb250ZW5kLW1vZGVscy9yZXNvdXJjZS1kZWZpbml0aW9uLmpzXCJcbmltcG9ydCB7YXNzaWduU2FmZVByb3BlcnR5LCBkZXNlcmlhbGl6ZUZyb250ZW5kTW9kZWxUcmFuc3BvcnRWYWx1ZSwgaXNCYWNrZW5kTW9kZWxJbnN0YW5jZSwgc2VyaWFsaXplRnJvbnRlbmRNb2RlbFRyYW5zcG9ydFZhbHVlfSBmcm9tIFwiLi9mcm9udGVuZC1tb2RlbHMvdHJhbnNwb3J0LXNlcmlhbGl6YXRpb24uanNcIlxuaW1wb3J0IFJvdXRlc1Jlc29sdmVyIGZyb20gXCIuL3JvdXRlcy9yZXNvbHZlci5qc1wiXG5pbXBvcnQge1ZhbGlkYXRpb25FcnJvcn0gZnJvbSBcIi4vZGF0YWJhc2UvcmVjb3JkL2luZGV4LmpzXCJcbmltcG9ydCBWZWxvY2lvdXNFcnJvciBmcm9tIFwiLi92ZWxvY2lvdXMtZXJyb3IuanNcIlxuXG4vKipcbiAqIEBwYXJhbSB7dW5rbm93bn0gdmFsdWUgLSBDYW5kaWRhdGUgdmFsdWUuXG4gKiBAcmV0dXJucyB7dmFsdWUgaXMgUmVjb3JkPHN0cmluZywgYW55Pn0gLSBXaGV0aGVyIHZhbHVlIGlzIGEgcGxhaW4gb2JqZWN0LlxuICovXG5mdW5jdGlvbiBpc1BsYWluT2JqZWN0KHZhbHVlKSB7XG4gIGlmICghdmFsdWUgfHwgdHlwZW9mIHZhbHVlICE9PSBcIm9iamVjdFwiIHx8IEFycmF5LmlzQXJyYXkodmFsdWUpKSByZXR1cm4gZmFsc2VcblxuICBjb25zdCBwcm90b3R5cGUgPSBPYmplY3QuZ2V0UHJvdG90eXBlT2YodmFsdWUpXG5cbiAgcmV0dXJuIHByb3RvdHlwZSA9PT0gT2JqZWN0LnByb3RvdHlwZSB8fCBwcm90b3R5cGUgPT09IG51bGxcbn1cblxuLyoqXG4gKiBAcGFyYW0ge2ltcG9ydChcIi4vZGF0YWJhc2UvcXVlcnkvaW5kZXguanNcIikuTmVzdGVkUHJlbG9hZFJlY29yZCB8IHN0cmluZyB8IHN0cmluZ1tdIHwgYm9vbGVhbiB8IHVuZGVmaW5lZCB8IG51bGx9IHByZWxvYWQgLSBQcmVsb2FkIHNob3J0aGFuZC5cbiAqIEByZXR1cm5zIHtpbXBvcnQoXCIuL2RhdGFiYXNlL3F1ZXJ5L2luZGV4LmpzXCIpLk5lc3RlZFByZWxvYWRSZWNvcmQgfCBudWxsfSAtIE5vcm1hbGl6ZWQgcHJlbG9hZC5cbiAqL1xuZnVuY3Rpb24gbm9ybWFsaXplRnJvbnRlbmRNb2RlbFByZWxvYWQocHJlbG9hZCkge1xuICBpZiAoIXByZWxvYWQpIHJldHVybiBudWxsXG5cbiAgaWYgKHByZWxvYWQgPT09IHRydWUpIHJldHVybiB7fVxuXG4gIGlmICh0eXBlb2YgcHJlbG9hZCA9PT0gXCJzdHJpbmdcIikge1xuICAgIHJldHVybiB7W3ByZWxvYWRdOiB0cnVlfVxuICB9XG5cbiAgaWYgKEFycmF5LmlzQXJyYXkocHJlbG9hZCkpIHtcbiAgICAvKiogQHR5cGUge2ltcG9ydChcIi4vZGF0YWJhc2UvcXVlcnkvaW5kZXguanNcIikuTmVzdGVkUHJlbG9hZFJlY29yZH0gKi9cbiAgICBjb25zdCBub3JtYWxpemVkID0ge31cblxuICAgIGZvciAoY29uc3QgZW50cnkgb2YgcHJlbG9hZCkge1xuICAgICAgaWYgKHR5cGVvZiBlbnRyeSA9PT0gXCJzdHJpbmdcIikge1xuICAgICAgICBub3JtYWxpemVkW2VudHJ5XSA9IHRydWVcbiAgICAgICAgY29udGludWVcbiAgICAgIH1cblxuICAgICAgaWYgKGlzUGxhaW5PYmplY3QoZW50cnkpKSB7XG4gICAgICAgIGNvbnN0IG5lc3RlZCA9IG5vcm1hbGl6ZUZyb250ZW5kTW9kZWxQcmVsb2FkKGVudHJ5KVxuXG4gICAgICAgIGlmIChuZXN0ZWQpIHtcbiAgICAgICAgICBtZXJnZU5vcm1hbGl6ZWRQcmVsb2FkKG5vcm1hbGl6ZWQsIG5lc3RlZClcbiAgICAgICAgfVxuICAgICAgICBjb250aW51ZVxuICAgICAgfVxuXG4gICAgICB0aHJvdyBmcm9udGVuZE1vZGVsVmFsaWRhdGlvbkVycm9yKGBJbnZhbGlkIHByZWxvYWQgZW50cnkgdHlwZTogJHt0eXBlb2YgZW50cnl9YClcbiAgICB9XG5cbiAgICByZXR1cm4gbm9ybWFsaXplZFxuICB9XG5cbiAgaWYgKCFpc1BsYWluT2JqZWN0KHByZWxvYWQpKSB7XG4gICAgdGhyb3cgZnJvbnRlbmRNb2RlbFZhbGlkYXRpb25FcnJvcihgSW52YWxpZCBwcmVsb2FkIHR5cGU6ICR7dHlwZW9mIHByZWxvYWR9YClcbiAgfVxuXG4gIC8qKiBAdHlwZSB7aW1wb3J0KFwiLi9kYXRhYmFzZS9xdWVyeS9pbmRleC5qc1wiKS5OZXN0ZWRQcmVsb2FkUmVjb3JkfSAqL1xuICBjb25zdCBub3JtYWxpemVkID0ge31cblxuICBmb3IgKGNvbnN0IFtyZWxhdGlvbnNoaXBOYW1lLCByZWxhdGlvbnNoaXBQcmVsb2FkXSBvZiBPYmplY3QuZW50cmllcyhwcmVsb2FkKSkge1xuICAgIGlmIChyZWxhdGlvbnNoaXBQcmVsb2FkID09PSB0cnVlIHx8IHJlbGF0aW9uc2hpcFByZWxvYWQgPT09IGZhbHNlKSB7XG4gICAgICBub3JtYWxpemVkW3JlbGF0aW9uc2hpcE5hbWVdID0gcmVsYXRpb25zaGlwUHJlbG9hZFxuICAgICAgY29udGludWVcbiAgICB9XG5cbiAgICBpZiAodHlwZW9mIHJlbGF0aW9uc2hpcFByZWxvYWQgPT09IFwic3RyaW5nXCIgfHwgQXJyYXkuaXNBcnJheShyZWxhdGlvbnNoaXBQcmVsb2FkKSB8fCBpc1BsYWluT2JqZWN0KHJlbGF0aW9uc2hpcFByZWxvYWQpKSB7XG4gICAgICBjb25zdCBuZXN0ZWQgPSBub3JtYWxpemVGcm9udGVuZE1vZGVsUHJlbG9hZChyZWxhdGlvbnNoaXBQcmVsb2FkKVxuXG4gICAgICBub3JtYWxpemVkW3JlbGF0aW9uc2hpcE5hbWVdID0gbmVzdGVkIHx8IHt9XG4gICAgICBjb250aW51ZVxuICAgIH1cblxuICAgIHRocm93IGZyb250ZW5kTW9kZWxWYWxpZGF0aW9uRXJyb3IoYEludmFsaWQgcHJlbG9hZCB2YWx1ZSBmb3IgJHtyZWxhdGlvbnNoaXBOYW1lfTogJHt0eXBlb2YgcmVsYXRpb25zaGlwUHJlbG9hZH1gKVxuICB9XG5cbiAgcmV0dXJuIG5vcm1hbGl6ZWRcbn1cblxuLyoqXG4gKiBAcGFyYW0ge2ltcG9ydChcIi4vZGF0YWJhc2UvcXVlcnkvaW5kZXguanNcIikuTmVzdGVkUHJlbG9hZFJlY29yZH0gdGFyZ2V0IC0gVGFyZ2V0IHByZWxvYWQgb2JqZWN0LlxuICogQHBhcmFtIHtpbXBvcnQoXCIuL2RhdGFiYXNlL3F1ZXJ5L2luZGV4LmpzXCIpLk5lc3RlZFByZWxvYWRSZWNvcmR9IHNvdXJjZSAtIFNvdXJjZSBwcmVsb2FkIG9iamVjdC5cbiAqIEByZXR1cm5zIHt2b2lkfSAtIE11dGF0ZXMgdGFyZ2V0IHdpdGggbWVyZ2VkIG5lc3RlZCBwcmVsb2FkIHRyZWUuXG4gKi9cbmZ1bmN0aW9uIG1lcmdlTm9ybWFsaXplZFByZWxvYWQodGFyZ2V0LCBzb3VyY2UpIHtcbiAgZm9yIChjb25zdCBbcmVsYXRpb25zaGlwTmFtZSwgcmVsYXRpb25zaGlwUHJlbG9hZF0gb2YgT2JqZWN0LmVudHJpZXMoc291cmNlKSkge1xuICAgIGNvbnN0IGV4aXN0aW5nVmFsdWUgPSB0YXJnZXRbcmVsYXRpb25zaGlwTmFtZV1cblxuICAgIGlmIChyZWxhdGlvbnNoaXBQcmVsb2FkID09PSBmYWxzZSkge1xuICAgICAgdGFyZ2V0W3JlbGF0aW9uc2hpcE5hbWVdID0gZmFsc2VcbiAgICAgIGNvbnRpbnVlXG4gICAgfVxuXG4gICAgaWYgKHJlbGF0aW9uc2hpcFByZWxvYWQgPT09IHRydWUpIHtcbiAgICAgIGlmIChleGlzdGluZ1ZhbHVlID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgdGFyZ2V0W3JlbGF0aW9uc2hpcE5hbWVdID0gdHJ1ZVxuICAgICAgfVxuICAgICAgY29udGludWVcbiAgICB9XG5cbiAgICBpZiAoIWlzUGxhaW5PYmplY3QocmVsYXRpb25zaGlwUHJlbG9hZCkpIHtcbiAgICAgIHRocm93IGZyb250ZW5kTW9kZWxWYWxpZGF0aW9uRXJyb3IoYEludmFsaWQgcHJlbG9hZCB2YWx1ZSBmb3IgJHtyZWxhdGlvbnNoaXBOYW1lfTogJHt0eXBlb2YgcmVsYXRpb25zaGlwUHJlbG9hZH1gKVxuICAgIH1cblxuICAgIGlmIChpc1BsYWluT2JqZWN0KGV4aXN0aW5nVmFsdWUpKSB7XG4gICAgICBtZXJnZU5vcm1hbGl6ZWRQcmVsb2FkKFxuICAgICAgICAvKiogQHR5cGUge2ltcG9ydChcIi4vZGF0YWJhc2UvcXVlcnkvaW5kZXguanNcIikuTmVzdGVkUHJlbG9hZFJlY29yZH0gKi8gKGV4aXN0aW5nVmFsdWUpLFxuICAgICAgICAvKiogQHR5cGUge2ltcG9ydChcIi4vZGF0YWJhc2UvcXVlcnkvaW5kZXguanNcIikuTmVzdGVkUHJlbG9hZFJlY29yZH0gKi8gKHJlbGF0aW9uc2hpcFByZWxvYWQpXG4gICAgICApXG4gICAgICBjb250aW51ZVxuICAgIH1cblxuICAgIHRhcmdldFtyZWxhdGlvbnNoaXBOYW1lXSA9IHJlbGF0aW9uc2hpcFByZWxvYWRcbiAgfVxufVxuXG4vKipcbiAqIEBwYXJhbSB7UmVjb3JkPHN0cmluZywgYW55Pn0gdGFyZ2V0IC0gVGFyZ2V0IGpvaW5zIG9iamVjdC5cbiAqIEBwYXJhbSB7UmVjb3JkPHN0cmluZywgYW55Pn0gc291cmNlIC0gU291cmNlIGpvaW5zIG9iamVjdC5cbiAqIEByZXR1cm5zIHt2b2lkfSAtIE11dGF0ZXMgdGFyZ2V0IHdpdGggbWVyZ2VkIG5lc3RlZCBqb2lucyB0cmVlLlxuICovXG5mdW5jdGlvbiBtZXJnZU5vcm1hbGl6ZWRKb2lucyh0YXJnZXQsIHNvdXJjZSkge1xuICBmb3IgKGNvbnN0IFtyZWxhdGlvbnNoaXBOYW1lLCByZWxhdGlvbnNoaXBKb2luXSBvZiBPYmplY3QuZW50cmllcyhzb3VyY2UpKSB7XG4gICAgY29uc3QgZXhpc3RpbmdWYWx1ZSA9IHRhcmdldFtyZWxhdGlvbnNoaXBOYW1lXVxuXG4gICAgaWYgKHJlbGF0aW9uc2hpcEpvaW4gPT09IHRydWUpIHtcbiAgICAgIGlmIChleGlzdGluZ1ZhbHVlID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgdGFyZ2V0W3JlbGF0aW9uc2hpcE5hbWVdID0gdHJ1ZVxuICAgICAgfVxuICAgICAgY29udGludWVcbiAgICB9XG5cbiAgICBpZiAoIWlzUGxhaW5PYmplY3QocmVsYXRpb25zaGlwSm9pbikpIHtcbiAgICAgIHRocm93IGZyb250ZW5kTW9kZWxWYWxpZGF0aW9uRXJyb3IoYEludmFsaWQgam9pbiBkZWZpbml0aW9uIGZvciBcIiR7cmVsYXRpb25zaGlwTmFtZX1cIjogJHt0eXBlb2YgcmVsYXRpb25zaGlwSm9pbn1gKVxuICAgIH1cblxuICAgIGlmIChpc1BsYWluT2JqZWN0KGV4aXN0aW5nVmFsdWUpKSB7XG4gICAgICBtZXJnZU5vcm1hbGl6ZWRKb2lucyhleGlzdGluZ1ZhbHVlLCByZWxhdGlvbnNoaXBKb2luKVxuICAgICAgY29udGludWVcbiAgICB9XG5cbiAgICB0YXJnZXRbcmVsYXRpb25zaGlwTmFtZV0gPSByZWxhdGlvbnNoaXBKb2luXG4gIH1cbn1cblxuLyoqXG4gKiBAcGFyYW0ge3Vua25vd259IGpvaW5zIC0gSm9pbnMgcGF5bG9hZC5cbiAqIEByZXR1cm5zIHtSZWNvcmQ8c3RyaW5nLCBhbnk+IHwgbnVsbH0gLSBOb3JtYWxpemVkIHJlbGF0aW9uc2hpcC1vYmplY3Qgam9pbnMuXG4gKi9cbmZ1bmN0aW9uIG5vcm1hbGl6ZUZyb250ZW5kTW9kZWxKb2lucyhqb2lucykge1xuICBpZiAoIWpvaW5zKSByZXR1cm4gbnVsbFxuXG4gIGlmIChBcnJheS5pc0FycmF5KGpvaW5zKSkge1xuICAgIC8qKiBAdHlwZSB7UmVjb3JkPHN0cmluZywgYW55Pn0gKi9cbiAgICBjb25zdCBub3JtYWxpemVkID0ge31cblxuICAgIGZvciAoY29uc3Qgam9pbkVudHJ5IG9mIGpvaW5zKSB7XG4gICAgICBpZiAoIWlzUGxhaW5PYmplY3Qoam9pbkVudHJ5KSkge1xuICAgICAgICB0aHJvdyBmcm9udGVuZE1vZGVsVmFsaWRhdGlvbkVycm9yKGBJbnZhbGlkIGpvaW5zIGVudHJ5IHR5cGU6ICR7dHlwZW9mIGpvaW5FbnRyeX1gKVxuICAgICAgfVxuXG4gICAgICBjb25zdCBuZXN0ZWQgPSBub3JtYWxpemVGcm9udGVuZE1vZGVsSm9pbnMoam9pbkVudHJ5KVxuXG4gICAgICBpZiAobmVzdGVkKSB7XG4gICAgICAgIG1lcmdlTm9ybWFsaXplZEpvaW5zKG5vcm1hbGl6ZWQsIG5lc3RlZClcbiAgICAgIH1cbiAgICB9XG5cbiAgICByZXR1cm4gbm9ybWFsaXplZFxuICB9XG5cbiAgaWYgKCFpc1BsYWluT2JqZWN0KGpvaW5zKSkge1xuICAgIHRocm93IGZyb250ZW5kTW9kZWxWYWxpZGF0aW9uRXJyb3IoYEludmFsaWQgam9pbnMgdHlwZTogJHt0eXBlb2Ygam9pbnN9YClcbiAgfVxuXG4gIC8qKiBAdHlwZSB7UmVjb3JkPHN0cmluZywgYW55Pn0gKi9cbiAgY29uc3Qgbm9ybWFsaXplZCA9IHt9XG5cbiAgZm9yIChjb25zdCBbcmVsYXRpb25zaGlwTmFtZSwgcmVsYXRpb25zaGlwSm9pbl0gb2YgT2JqZWN0LmVudHJpZXMoam9pbnMpKSB7XG4gICAgaWYgKHJlbGF0aW9uc2hpcEpvaW4gPT09IHRydWUpIHtcbiAgICAgIG5vcm1hbGl6ZWRbcmVsYXRpb25zaGlwTmFtZV0gPSB0cnVlXG4gICAgICBjb250aW51ZVxuICAgIH1cblxuICAgIGlmIChpc1BsYWluT2JqZWN0KHJlbGF0aW9uc2hpcEpvaW4pKSB7XG4gICAgICBub3JtYWxpemVkW3JlbGF0aW9uc2hpcE5hbWVdID0gbm9ybWFsaXplRnJvbnRlbmRNb2RlbEpvaW5zKHJlbGF0aW9uc2hpcEpvaW4pIHx8IHt9XG4gICAgICBjb250aW51ZVxuICAgIH1cblxuICAgIHRocm93IGZyb250ZW5kTW9kZWxWYWxpZGF0aW9uRXJyb3IoYEludmFsaWQgam9pbiBkZWZpbml0aW9uIGZvciBcIiR7cmVsYXRpb25zaGlwTmFtZX1cIjogJHt0eXBlb2YgcmVsYXRpb25zaGlwSm9pbn1gKVxuICB9XG5cbiAgcmV0dXJuIG5vcm1hbGl6ZWRcbn1cblxuLyoqXG4gKiBAcGFyYW0ge3Vua25vd259IHNlbGVjdCAtIFNlbGVjdCBwYXlsb2FkLlxuICogQHBhcmFtIHtzdHJpbmcgfCBudWxsfSBbcm9vdE1vZGVsTmFtZV0gLSBPcHRpb25hbCByb290IG1vZGVsIG5hbWUgZm9yIHNob3J0aGFuZCBwYXlsb2Fkcy5cbiAqIEByZXR1cm5zIHtSZWNvcmQ8c3RyaW5nLCBzdHJpbmdbXT4gfCBudWxsfSAtIE5vcm1hbGl6ZWQgbW9kZWwtbmFtZSBrZXllZCBzZWxlY3QgcmVjb3JkLlxuICovXG5mdW5jdGlvbiBub3JtYWxpemVGcm9udGVuZE1vZGVsU2VsZWN0KHNlbGVjdCwgcm9vdE1vZGVsTmFtZSA9IG51bGwpIHtcbiAgaWYgKCFzZWxlY3QpIHJldHVybiBudWxsXG5cbiAgaWYgKHR5cGVvZiBzZWxlY3QgPT09IFwic3RyaW5nXCIpIHtcbiAgICBpZiAoIXJvb3RNb2RlbE5hbWUpIHtcbiAgICAgIHRocm93IGZyb250ZW5kTW9kZWxWYWxpZGF0aW9uRXJyb3IoXCJJbnZhbGlkIHNlbGVjdCBzaG9ydGhhbmQgd2l0aG91dCByb290IG1vZGVsIG5hbWVcIilcbiAgICB9XG5cbiAgICByZXR1cm4ge1tyb290TW9kZWxOYW1lXTogW3NlbGVjdF19XG4gIH1cblxuICBpZiAoQXJyYXkuaXNBcnJheShzZWxlY3QpKSB7XG4gICAgaWYgKCFyb290TW9kZWxOYW1lKSB7XG4gICAgICB0aHJvdyBmcm9udGVuZE1vZGVsVmFsaWRhdGlvbkVycm9yKFwiSW52YWxpZCBzZWxlY3Qgc2hvcnRoYW5kIHdpdGhvdXQgcm9vdCBtb2RlbCBuYW1lXCIpXG4gICAgfVxuXG4gICAgZm9yIChjb25zdCBhdHRyaWJ1dGVOYW1lIG9mIHNlbGVjdCkge1xuICAgICAgaWYgKHR5cGVvZiBhdHRyaWJ1dGVOYW1lICE9PSBcInN0cmluZ1wiKSB7XG4gICAgICAgIHRocm93IGZyb250ZW5kTW9kZWxWYWxpZGF0aW9uRXJyb3IoYEludmFsaWQgc2VsZWN0IGF0dHJpYnV0ZSBmb3IgJHtyb290TW9kZWxOYW1lfTogJHt0eXBlb2YgYXR0cmlidXRlTmFtZX1gKVxuICAgICAgfVxuICAgIH1cblxuICAgIHJldHVybiB7W3Jvb3RNb2RlbE5hbWVdOiBBcnJheS5mcm9tKG5ldyBTZXQoc2VsZWN0KSl9XG4gIH1cblxuICBpZiAoIWlzUGxhaW5PYmplY3Qoc2VsZWN0KSkge1xuICAgIHRocm93IGZyb250ZW5kTW9kZWxWYWxpZGF0aW9uRXJyb3IoYEludmFsaWQgc2VsZWN0IHR5cGU6ICR7dHlwZW9mIHNlbGVjdH1gKVxuICB9XG5cbiAgLyoqIEB0eXBlIHtSZWNvcmQ8c3RyaW5nLCBzdHJpbmdbXT59ICovXG4gIGNvbnN0IG5vcm1hbGl6ZWQgPSB7fVxuXG4gIGZvciAoY29uc3QgW21vZGVsTmFtZSwgc2VsZWN0VmFsdWVdIG9mIE9iamVjdC5lbnRyaWVzKHNlbGVjdCkpIHtcbiAgICBpZiAodHlwZW9mIHNlbGVjdFZhbHVlID09PSBcInN0cmluZ1wiKSB7XG4gICAgICBub3JtYWxpemVkW21vZGVsTmFtZV0gPSBbc2VsZWN0VmFsdWVdXG4gICAgICBjb250aW51ZVxuICAgIH1cblxuICAgIGlmICghQXJyYXkuaXNBcnJheShzZWxlY3RWYWx1ZSkpIHtcbiAgICAgIHRocm93IGZyb250ZW5kTW9kZWxWYWxpZGF0aW9uRXJyb3IoYEludmFsaWQgc2VsZWN0IHZhbHVlIGZvciAke21vZGVsTmFtZX06ICR7dHlwZW9mIHNlbGVjdFZhbHVlfWApXG4gICAgfVxuXG4gICAgZm9yIChjb25zdCBhdHRyaWJ1dGVOYW1lIG9mIHNlbGVjdFZhbHVlKSB7XG4gICAgICBpZiAodHlwZW9mIGF0dHJpYnV0ZU5hbWUgIT09IFwic3RyaW5nXCIpIHtcbiAgICAgICAgdGhyb3cgZnJvbnRlbmRNb2RlbFZhbGlkYXRpb25FcnJvcihgSW52YWxpZCBzZWxlY3QgYXR0cmlidXRlIGZvciAke21vZGVsTmFtZX06ICR7dHlwZW9mIGF0dHJpYnV0ZU5hbWV9YClcbiAgICAgIH1cbiAgICB9XG5cbiAgICBub3JtYWxpemVkW21vZGVsTmFtZV0gPSBBcnJheS5mcm9tKG5ldyBTZXQoc2VsZWN0VmFsdWUpKVxuICB9XG5cbiAgcmV0dXJuIG5vcm1hbGl6ZWRcbn1cblxuLyoqXG4gKiBAdHlwZWRlZiB7b2JqZWN0fSBGcm9udGVuZE1vZGVsU2VhcmNoXG4gKiBAcHJvcGVydHkge3N0cmluZ1tdfSBwYXRoIC0gUmVsYXRpb25zaGlwIHBhdGguXG4gKiBAcHJvcGVydHkge3N0cmluZ30gY29sdW1uIC0gQ29sdW1uIG9yIGF0dHJpYnV0ZSBuYW1lLlxuICogQHByb3BlcnR5IHtcImVxXCIgfCBcImxpa2VcIiB8IFwibm90RXFcIiB8IFwiZ3RcIiB8IFwiZ3RlcVwiIHwgXCJsdFwiIHwgXCJsdGVxXCJ9IG9wZXJhdG9yIC0gU2VhcmNoIG9wZXJhdG9yLlxuICogQHByb3BlcnR5IHthbnl9IHZhbHVlIC0gU2VhcmNoIHZhbHVlLlxuICovXG5cbi8qKlxuICogQHBhcmFtIHtzdHJpbmd9IG9wZXJhdG9yIC0gUmF3IHNlYXJjaCBvcGVyYXRvci5cbiAqIEByZXR1cm5zIHtGcm9udGVuZE1vZGVsU2VhcmNoW1wib3BlcmF0b3JcIl19IC0gTm9ybWFsaXplZCBzZWFyY2ggb3BlcmF0b3IuXG4gKi9cbmZ1bmN0aW9uIG5vcm1hbGl6ZUZyb250ZW5kTW9kZWxTZWFyY2hPcGVyYXRvcihvcGVyYXRvcikge1xuICBjb25zdCBvcGVyYXRvckFsaWFzZXMgPSB7XG4gICAgXCI8XCI6IFwibHRcIixcbiAgICBcIjw9XCI6IFwibHRlcVwiLFxuICAgIFwiPlwiOiBcImd0XCIsXG4gICAgXCI+PVwiOiBcImd0ZXFcIlxuICB9XG4gIGNvbnN0IG5vcm1hbGl6ZWRPcGVyYXRvciA9IG9wZXJhdG9yQWxpYXNlc1svKiogQHR5cGUge1wiPFwiIHwgXCI8PVwiIHwgXCI+XCIgfCBcIj49XCJ9ICovIChvcGVyYXRvcildIHx8IG9wZXJhdG9yXG4gIGNvbnN0IHN1cHBvcnRlZE9wZXJhdG9ycyA9IG5ldyBTZXQoW1wiZXFcIiwgXCJsaWtlXCIsIFwibm90RXFcIiwgXCJndFwiLCBcImd0ZXFcIiwgXCJsdFwiLCBcImx0ZXFcIl0pXG5cbiAgaWYgKCFzdXBwb3J0ZWRPcGVyYXRvcnMuaGFzKG5vcm1hbGl6ZWRPcGVyYXRvcikpIHtcbiAgICB0aHJvdyBmcm9udGVuZE1vZGVsVmFsaWRhdGlvbkVycm9yKGBJbnZhbGlkIHNlYXJjaCBvcGVyYXRvcjogJHtvcGVyYXRvcn1gKVxuICB9XG5cbiAgcmV0dXJuIC8qKiBAdHlwZSB7RnJvbnRlbmRNb2RlbFNlYXJjaFtcIm9wZXJhdG9yXCJdfSAqLyAobm9ybWFsaXplZE9wZXJhdG9yKVxufVxuXG4vKipcbiAqIEB0eXBlZGVmIHtvYmplY3R9IEZyb250ZW5kTW9kZWxTb3J0XG4gKiBAcHJvcGVydHkge3N0cmluZ30gY29sdW1uIC0gQXR0cmlidXRlIG5hbWUgdG8gc29ydCBieS5cbiAqIEBwcm9wZXJ0eSB7XCJhc2NcIiB8IFwiZGVzY1wifSBkaXJlY3Rpb24gLSBTb3J0IGRpcmVjdGlvbi5cbiAqIEBwcm9wZXJ0eSB7c3RyaW5nW119IHBhdGggLSBSZWxhdGlvbnNoaXAgcGF0aCBmcm9tIHJvb3QgbW9kZWwuXG4gKi9cblxuLyoqXG4gKiBAdHlwZWRlZiB7b2JqZWN0fSBGcm9udGVuZE1vZGVsR3JvdXBcbiAqIEBwcm9wZXJ0eSB7c3RyaW5nfSBjb2x1bW4gLSBBdHRyaWJ1dGUgbmFtZSB0byBncm91cCBieS5cbiAqIEBwcm9wZXJ0eSB7c3RyaW5nW119IHBhdGggLSBSZWxhdGlvbnNoaXAgcGF0aCBmcm9tIHJvb3QgbW9kZWwuXG4gKi9cblxuLyoqXG4gKiBAdHlwZWRlZiB7b2JqZWN0fSBGcm9udGVuZE1vZGVsUGx1Y2tcbiAqIEBwcm9wZXJ0eSB7c3RyaW5nfSBjb2x1bW4gLSBBdHRyaWJ1dGUgbmFtZSB0byBwbHVjay5cbiAqIEBwcm9wZXJ0eSB7c3RyaW5nW119IHBhdGggLSBSZWxhdGlvbnNoaXAgcGF0aCBmcm9tIHJvb3QgbW9kZWwuXG4gKi9cblxuLyoqXG4gKiBAdHlwZWRlZiB7b2JqZWN0fSBGcm9udGVuZE1vZGVsUGFnaW5hdGlvblxuICogQHByb3BlcnR5IHtudW1iZXIgfCBudWxsfSBsaW1pdCAtIE1heGltdW0gbnVtYmVyIG9mIHJlY29yZHMuXG4gKiBAcHJvcGVydHkge251bWJlciB8IG51bGx9IG9mZnNldCAtIE51bWJlciBvZiByZWNvcmRzIHRvIHNraXAuXG4gKiBAcHJvcGVydHkge251bWJlciB8IG51bGx9IHBhZ2UgLSAxLWJhc2VkIHBhZ2UgbnVtYmVyLlxuICogQHByb3BlcnR5IHtudW1iZXIgfCBudWxsfSBwZXJQYWdlIC0gUGFnZSBzaXplLlxuICovXG5cbmNvbnN0IGZyb250ZW5kTW9kZWxKb2luZWRQYXRoc1N5bWJvbCA9IFN5bWJvbChcImZyb250ZW5kTW9kZWxKb2luZWRQYXRoc1wiKVxuY29uc3QgZnJvbnRlbmRNb2RlbEdyb3VwZWRDb2x1bW5zU3ltYm9sID0gU3ltYm9sKFwiZnJvbnRlbmRNb2RlbEdyb3VwZWRDb2x1bW5zXCIpXG5jb25zdCBmcm9udGVuZE1vZGVsV2hlcmVOb01hdGNoU3ltYm9sID0gU3ltYm9sKFwiZnJvbnRlbmRNb2RlbFdoZXJlTm9NYXRjaFwiKVxuY29uc3QgZnJvbnRlbmRNb2RlbENsaWVudFNhZmVFcnJvck1lc3NhZ2UgPSBcIlJlcXVlc3QgZmFpbGVkLlwiXG5jb25zdCBmcm9udGVuZE1vZGVsRGVidWdFcnJvckVudmlyb25tZW50cyA9IG5ldyBTZXQoW1wiZGV2ZWxvcG1lbnRcIiwgXCJ0ZXN0XCJdKVxuXG4vKipcbiAqIEBwYXJhbSB7aW1wb3J0KFwiLi9kYXRhYmFzZS9xdWVyeS9tb2RlbC1jbGFzcy1xdWVyeS5qc1wiKS5kZWZhdWx0fSBxdWVyeSAtIFF1ZXJ5IGluc3RhbmNlLlxuICogQHJldHVybnMge2ltcG9ydChcIi4vZGF0YWJhc2UvcXVlcnkvbW9kZWwtY2xhc3MtcXVlcnkuanNcIikuZGVmYXVsdCAmIHtbZnJvbnRlbmRNb2RlbEpvaW5lZFBhdGhzU3ltYm9sXT86IFNldDxzdHJpbmc+LCBbZnJvbnRlbmRNb2RlbEdyb3VwZWRDb2x1bW5zU3ltYm9sXT86IFNldDxzdHJpbmc+fX0gLSBRdWVyeSBtZXRhZGF0YSBhY2Nlc3MgaGVscGVyLlxuICovXG5mdW5jdGlvbiBmcm9udGVuZE1vZGVsUXVlcnlNZXRhZGF0YShxdWVyeSkge1xuICByZXR1cm4gLyoqIEB0eXBlIHtpbXBvcnQoXCIuL2RhdGFiYXNlL3F1ZXJ5L21vZGVsLWNsYXNzLXF1ZXJ5LmpzXCIpLmRlZmF1bHQgJiB7W2Zyb250ZW5kTW9kZWxKb2luZWRQYXRoc1N5bWJvbF0/OiBTZXQ8c3RyaW5nPiwgW2Zyb250ZW5kTW9kZWxHcm91cGVkQ29sdW1uc1N5bWJvbF0/OiBTZXQ8c3RyaW5nPn19ICovIChxdWVyeSlcbn1cblxuLyoqXG4gKiBAcGFyYW0ge3N0cmluZ30gbWVzc2FnZSAtIFZhbGlkYXRpb24gZXJyb3IgbWVzc2FnZS5cbiAqIEByZXR1cm5zIHtWZWxvY2lvdXNFcnJvcn0gLSBDbGllbnQtc2FmZSB2YWxpZGF0aW9uIGVycm9yLlxuICovXG5mdW5jdGlvbiBmcm9udGVuZE1vZGVsVmFsaWRhdGlvbkVycm9yKG1lc3NhZ2UpIHtcbiAgcmV0dXJuIFZlbG9jaW91c0Vycm9yLnNhZmUobWVzc2FnZSwge2NvZGU6IFwiZnJvbnRlbmQtbW9kZWwtdmFsaWRhdGlvblwifSlcbn1cblxuLyoqXG4gKiBXaGV0aGVyIHRoZSBlcnJvciBjYXJyaWVzIGFuIGBlcnJvci52ZWxvY2lvdXNgIG1ldGFkYXRhIGJhZy4gVGhlXG4gKiBwcmVzZW5jZSBvZiBhbnkgc3VjaCBiYWcgbWFya3MgdGhlIGVycm9yIGFzIFwiYW5ub3RhdGVkIGJ5IHRoZVxuICogZGV2ZWxvcGVyIGZvciB0aGUgZnJvbnRlbmRcIiDigJQgdGhlIGZyYW1ld29yayB0cmVhdHMgaXQgYXNcbiAqIHVzZXItZmFjaW5nOiBzdXJmYWNlIHRoZSBtZXNzYWdlLCBmb3J3YXJkIHRoZSBtZXRhZGF0YSwgYW5kIHNraXBcbiAqIHRoZSBub2lzeSBlbmRwb2ludC1lcnJvciBsb2cuXG4gKlxuICogQHBhcmFtIHt1bmtub3dufSBlcnJvciAtIENhdWdodCBlcnJvci5cbiAqIEByZXR1cm5zIHtib29sZWFufVxuICovXG5mdW5jdGlvbiBmcm9udGVuZE1vZGVsRXJyb3JIYXNWZWxvY2lvdXNNZXRhZGF0YShlcnJvcikge1xuICByZXR1cm4gQm9vbGVhbihlcnJvciAmJiB0eXBlb2YgZXJyb3IgPT09IFwib2JqZWN0XCIgJiYgLyoqIEB0eXBlIHthbnl9ICovIChlcnJvcikudmVsb2Npb3VzICYmIHR5cGVvZiAvKiogQHR5cGUge2FueX0gKi8gKGVycm9yKS52ZWxvY2lvdXMgPT09IFwib2JqZWN0XCIpXG59XG5cbi8qKlxuICogQHBhcmFtIHt1bmtub3dufSBlcnJvciAtIENhdWdodCBlcnJvci5cbiAqIEByZXR1cm5zIHtSZWNvcmQ8c3RyaW5nLCBhbnk+IHwgbnVsbH1cbiAqL1xuZnVuY3Rpb24gZnJvbnRlbmRNb2RlbFZlbG9jaW91c01ldGFkYXRhRm9yRXJyb3IoZXJyb3IpIHtcbiAgaWYgKCFmcm9udGVuZE1vZGVsRXJyb3JIYXNWZWxvY2lvdXNNZXRhZGF0YShlcnJvcikpIHJldHVybiBudWxsXG4gIHJldHVybiAvKiogQHR5cGUge1JlY29yZDxzdHJpbmcsIGFueT59ICovICgvKiogQHR5cGUge2FueX0gKi8gKGVycm9yKS52ZWxvY2lvdXMpXG59XG5cbi8qKlxuICogQHBhcmFtIHt1bmtub3dufSBlcnJvciAtIENhdWdodCBlcnJvci5cbiAqIEByZXR1cm5zIHtzdHJpbmd9IC0gTWVzc2FnZSBzYWZlIHRvIHJldHVybiB0byBBUEkgY2xpZW50cy5cbiAqL1xuZnVuY3Rpb24gZnJvbnRlbmRNb2RlbENsaWVudE1lc3NhZ2VGb3JFcnJvcihlcnJvcikge1xuICBpZiAoZXJyb3IgaW5zdGFuY2VvZiBWZWxvY2lvdXNFcnJvciAmJiBlcnJvci5zYWZlVG9FeHBvc2UpIHtcbiAgICByZXR1cm4gZXJyb3IubWVzc2FnZVxuICB9XG5cbiAgaWYgKGZyb250ZW5kTW9kZWxFcnJvckhhc1ZlbG9jaW91c01ldGFkYXRhKGVycm9yKSAmJiBlcnJvciBpbnN0YW5jZW9mIEVycm9yKSB7XG4gICAgcmV0dXJuIGVycm9yLm1lc3NhZ2VcbiAgfVxuXG4gIHJldHVybiBmcm9udGVuZE1vZGVsQ2xpZW50U2FmZUVycm9yTWVzc2FnZVxufVxuXG4vKipcbiAqIEBwYXJhbSB7b2JqZWN0fSBhcmdzIC0gQXJndW1lbnRzLlxuICogQHBhcmFtIHtpbXBvcnQoXCIuL2NvbmZpZ3VyYXRpb24uanNcIikuZGVmYXVsdH0gYXJncy5jb25maWd1cmF0aW9uIC0gQ3VycmVudCBjb25maWd1cmF0aW9uLlxuICogQHBhcmFtIHtzdHJpbmd9IGFyZ3MuZW52aXJvbm1lbnQgLSBDdXJyZW50IGVudmlyb25tZW50LlxuICogQHBhcmFtIHt1bmtub3dufSBhcmdzLmVycm9yIC0gQ2F1Z2h0IGVycm9yLlxuICogQHJldHVybnMge1JlY29yZDxzdHJpbmcsIGFueT59IC0gT3B0aW9uYWwgZGVidWcgcGF5bG9hZCBmb3Igbm9uLXByb2R1Y3Rpb24gZW52aXJvbm1lbnRzLlxuICovXG5mdW5jdGlvbiBmcm9udGVuZE1vZGVsRGVidWdQYXlsb2FkRm9yRXJyb3Ioe2NvbmZpZ3VyYXRpb24sIGVudmlyb25tZW50LCBlcnJvcn0pIHtcbiAgY29uc3QgZGVidWdBbGxvd2VkID0gZnJvbnRlbmRNb2RlbERlYnVnRXJyb3JFbnZpcm9ubWVudHMuaGFzKGVudmlyb25tZW50KSB8fCBlbnZpcm9ubWVudCAhPT0gXCJwcm9kdWN0aW9uXCIgJiYgY29uZmlndXJhdGlvbi5nZXRFeHBvc2VJbnRlcm5hbEVycm9yc1RvQ2xpZW50cygpXG5cbiAgaWYgKCFkZWJ1Z0FsbG93ZWQpIHtcbiAgICByZXR1cm4ge31cbiAgfVxuXG4gIGlmIChlcnJvciBpbnN0YW5jZW9mIFZlbG9jaW91c0Vycm9yICYmIGVycm9yLnNhZmVUb0V4cG9zZSkge1xuICAgIHJldHVybiB7fVxuICB9XG5cbiAgaWYgKGZyb250ZW5kTW9kZWxFcnJvckhhc1ZlbG9jaW91c01ldGFkYXRhKGVycm9yKSkge1xuICAgIHJldHVybiB7fVxuICB9XG5cbiAgY29uc3QgZGVidWdFcnJvckNsYXNzID0gZXJyb3IgaW5zdGFuY2VvZiBFcnJvciAmJiBlcnJvci5uYW1lXG4gICAgPyBlcnJvci5uYW1lXG4gICAgOiB0eXBlb2YgZXJyb3JcbiAgY29uc3QgZGVidWdFcnJvck1lc3NhZ2UgPSBlcnJvciBpbnN0YW5jZW9mIEVycm9yXG4gICAgPyBlcnJvci5tZXNzYWdlXG4gICAgOiBTdHJpbmcoZXJyb3IpXG4gIGNvbnN0IGRlYnVnQmFja3RyYWNlID0gZXJyb3IgaW5zdGFuY2VvZiBFcnJvciAmJiB0eXBlb2YgZXJyb3Iuc3RhY2sgPT09IFwic3RyaW5nXCIgJiYgZXJyb3Iuc3RhY2subGVuZ3RoID4gMFxuICAgID8gZXJyb3Iuc3RhY2suc3BsaXQoXCJcXG5cIilcbiAgICA6IHVuZGVmaW5lZFxuXG4gIHJldHVybiB7XG4gICAgZGVidWdFcnJvckNsYXNzLFxuICAgIGRlYnVnRXJyb3JNZXNzYWdlLFxuICAgIC4uLihkZWJ1Z0JhY2t0cmFjZSA/IHtkZWJ1Z0JhY2t0cmFjZX0gOiB7fSlcbiAgfVxufVxuXG4vKipcbiAqIEBwYXJhbSB7dW5rbm93bn0gZGlyZWN0aW9uIC0gRGlyZWN0aW9uIGNhbmRpZGF0ZS5cbiAqIEByZXR1cm5zIHtcImFzY1wiIHwgXCJkZXNjXCJ9IC0gTm9ybWFsaXplZCBkaXJlY3Rpb24uXG4gKi9cbmZ1bmN0aW9uIG5vcm1hbGl6ZUZyb250ZW5kTW9kZWxTb3J0RGlyZWN0aW9uKGRpcmVjdGlvbikge1xuICBpZiAodHlwZW9mIGRpcmVjdGlvbiAhPT0gXCJzdHJpbmdcIikge1xuICAgIHRocm93IGZyb250ZW5kTW9kZWxWYWxpZGF0aW9uRXJyb3IoYEludmFsaWQgc29ydCBkaXJlY3Rpb24gdHlwZTogJHt0eXBlb2YgZGlyZWN0aW9ufWApXG4gIH1cblxuICBjb25zdCBub3JtYWxpemVkRGlyZWN0aW9uID0gZGlyZWN0aW9uLnRyaW0oKS50b0xvd2VyQ2FzZSgpXG5cbiAgaWYgKG5vcm1hbGl6ZWREaXJlY3Rpb24gIT09IFwiYXNjXCIgJiYgbm9ybWFsaXplZERpcmVjdGlvbiAhPT0gXCJkZXNjXCIpIHtcbiAgICB0aHJvdyBmcm9udGVuZE1vZGVsVmFsaWRhdGlvbkVycm9yKGBJbnZhbGlkIHNvcnQgZGlyZWN0aW9uOiAke2RpcmVjdGlvbn1gKVxuICB9XG5cbiAgcmV0dXJuIG5vcm1hbGl6ZWREaXJlY3Rpb25cbn1cblxuLyoqXG4gKiBAcGFyYW0ge3Vua25vd259IHZhbHVlIC0gQ2FuZGlkYXRlIHR1cGxlLlxuICogQHJldHVybnMge3ZhbHVlIGlzIFtzdHJpbmcsIHN0cmluZ119IC0gV2hldGhlciBjYW5kaWRhdGUgaXMgYSBzb3J0IHR1cGxlLlxuICovXG5mdW5jdGlvbiBmcm9udGVuZE1vZGVsU29ydFR1cGxlKHZhbHVlKSB7XG4gIGlmICghQXJyYXkuaXNBcnJheSh2YWx1ZSkpIHJldHVybiBmYWxzZVxuICBpZiAodmFsdWUubGVuZ3RoICE9PSAyKSByZXR1cm4gZmFsc2VcbiAgaWYgKHR5cGVvZiB2YWx1ZVswXSAhPT0gXCJzdHJpbmdcIikgcmV0dXJuIGZhbHNlXG4gIGlmICh0eXBlb2YgdmFsdWVbMV0gIT09IFwic3RyaW5nXCIpIHJldHVybiBmYWxzZVxuICBpZiAodmFsdWVbMF0udHJpbSgpLmxlbmd0aCA8IDEpIHJldHVybiBmYWxzZVxuXG4gIGNvbnN0IGRpcmVjdGlvbiA9IHZhbHVlWzFdLnRyaW0oKS50b0xvd2VyQ2FzZSgpXG5cbiAgcmV0dXJuIGRpcmVjdGlvbiA9PT0gXCJhc2NcIiB8fCBkaXJlY3Rpb24gPT09IFwiZGVzY1wiXG59XG5cbi8qKlxuICogQHBhcmFtIHt1bmtub3dufSB2YWx1ZSAtIENhbmRpZGF0ZSBkZXNjcmlwdG9yLlxuICogQHJldHVybnMge3ZhbHVlIGlzIHtjb2x1bW46IHN0cmluZywgZGlyZWN0aW9uOiBzdHJpbmcsIHBhdGg6IHN0cmluZ1tdfX0gLSBXaGV0aGVyIGNhbmRpZGF0ZSBpcyBhbiBleHBsaWNpdCBzb3J0IGRlc2NyaXB0b3Igb2JqZWN0LlxuICovXG5mdW5jdGlvbiBmcm9udGVuZE1vZGVsU29ydERlc2NyaXB0b3IodmFsdWUpIHtcbiAgaWYgKCFpc1BsYWluT2JqZWN0KHZhbHVlKSkgcmV0dXJuIGZhbHNlXG4gIGlmICghKFwiY29sdW1uXCIgaW4gdmFsdWUpIHx8ICEoXCJkaXJlY3Rpb25cIiBpbiB2YWx1ZSkgfHwgIShcInBhdGhcIiBpbiB2YWx1ZSkpIHJldHVybiBmYWxzZVxuICBpZiAodHlwZW9mIHZhbHVlLmNvbHVtbiAhPT0gXCJzdHJpbmdcIikgcmV0dXJuIGZhbHNlXG4gIGlmICh0eXBlb2YgdmFsdWUuZGlyZWN0aW9uICE9PSBcInN0cmluZ1wiKSByZXR1cm4gZmFsc2VcbiAgaWYgKCFBcnJheS5pc0FycmF5KHZhbHVlLnBhdGgpKSByZXR1cm4gZmFsc2VcblxuICByZXR1cm4gdmFsdWUucGF0aC5ldmVyeSgocGF0aEVudHJ5KSA9PiB0eXBlb2YgcGF0aEVudHJ5ID09PSBcInN0cmluZ1wiKVxufVxuXG4vKipcbiAqIEBwYXJhbSB7dW5rbm93bn0gdmFsdWUgLSBDYW5kaWRhdGUgZGVzY3JpcHRvci5cbiAqIEByZXR1cm5zIHt2YWx1ZSBpcyB7Y29sdW1uOiBzdHJpbmcsIHBhdGg6IHN0cmluZ1tdfX0gLSBXaGV0aGVyIGNhbmRpZGF0ZSBpcyBhbiBleHBsaWNpdCBncm91cCBkZXNjcmlwdG9yIG9iamVjdC5cbiAqL1xuZnVuY3Rpb24gZnJvbnRlbmRNb2RlbEdyb3VwRGVzY3JpcHRvcih2YWx1ZSkge1xuICBpZiAoIWlzUGxhaW5PYmplY3QodmFsdWUpKSByZXR1cm4gZmFsc2VcbiAgaWYgKCEoXCJjb2x1bW5cIiBpbiB2YWx1ZSkgfHwgIShcInBhdGhcIiBpbiB2YWx1ZSkpIHJldHVybiBmYWxzZVxuICBpZiAodHlwZW9mIHZhbHVlLmNvbHVtbiAhPT0gXCJzdHJpbmdcIikgcmV0dXJuIGZhbHNlXG4gIGlmICghQXJyYXkuaXNBcnJheSh2YWx1ZS5wYXRoKSkgcmV0dXJuIGZhbHNlXG5cbiAgcmV0dXJuIHZhbHVlLnBhdGguZXZlcnkoKHBhdGhFbnRyeSkgPT4gdHlwZW9mIHBhdGhFbnRyeSA9PT0gXCJzdHJpbmdcIilcbn1cblxuLyoqXG4gKiBAcGFyYW0ge3N0cmluZ30gc29ydFZhbHVlIC0gU29ydCBzdHJpbmcuXG4gKiBAcGFyYW0ge3N0cmluZ1tdfSBbcGF0aF0gLSBSZWxhdGlvbnNoaXAgcGF0aC5cbiAqIEByZXR1cm5zIHtGcm9udGVuZE1vZGVsU29ydH0gLSBOb3JtYWxpemVkIHNvcnQgZGVzY3JpcHRvci5cbiAqL1xuZnVuY3Rpb24gZnJvbnRlbmRNb2RlbFNvcnRGcm9tU3RyaW5nKHNvcnRWYWx1ZSwgcGF0aCA9IFtdKSB7XG4gIGNvbnN0IHRyaW1tZWQgPSBzb3J0VmFsdWUudHJpbSgpXG5cbiAgaWYgKHRyaW1tZWQubGVuZ3RoIDwgMSkge1xuICAgIHRocm93IGZyb250ZW5kTW9kZWxWYWxpZGF0aW9uRXJyb3IoXCJJbnZhbGlkIHNvcnQgdmFsdWU6IGV4cGVjdGVkIG5vbi1lbXB0eSBzdHJpbmdcIilcbiAgfVxuXG4gIGlmICh0cmltbWVkLnN0YXJ0c1dpdGgoXCItXCIpKSB7XG4gICAgY29uc3QgY29sdW1uID0gdHJpbW1lZC5zbGljZSgxKS50cmltKClcblxuICAgIGlmIChjb2x1bW4ubGVuZ3RoIDwgMSkge1xuICAgICAgdGhyb3cgZnJvbnRlbmRNb2RlbFZhbGlkYXRpb25FcnJvcihgSW52YWxpZCBzb3J0IGRlZmluaXRpb246ICR7c29ydFZhbHVlfWApXG4gICAgfVxuXG4gICAgcmV0dXJuIHtcbiAgICAgIGNvbHVtbixcbiAgICAgIGRpcmVjdGlvbjogXCJkZXNjXCIsXG4gICAgICBwYXRoOiBbLi4ucGF0aF1cbiAgICB9XG4gIH1cblxuICBjb25zdCBzb3J0UGFydHMgPSB0cmltbWVkLnNwbGl0KC9cXHMrLykuZmlsdGVyKEJvb2xlYW4pXG5cbiAgaWYgKHNvcnRQYXJ0cy5sZW5ndGggPiAyKSB7XG4gICAgdGhyb3cgZnJvbnRlbmRNb2RlbFZhbGlkYXRpb25FcnJvcihgSW52YWxpZCBzb3J0IGRlZmluaXRpb246ICR7c29ydFZhbHVlfWApXG4gIH1cblxuICBjb25zdCBjb2x1bW4gPSBzb3J0UGFydHNbMF1cblxuICBpZiAoY29sdW1uLmxlbmd0aCA8IDEpIHtcbiAgICB0aHJvdyBmcm9udGVuZE1vZGVsVmFsaWRhdGlvbkVycm9yKGBJbnZhbGlkIHNvcnQgZGVmaW5pdGlvbjogJHtzb3J0VmFsdWV9YClcbiAgfVxuXG4gIGNvbnN0IGRpcmVjdGlvbiA9IHNvcnRQYXJ0cy5sZW5ndGggPT09IDJcbiAgICA/IG5vcm1hbGl6ZUZyb250ZW5kTW9kZWxTb3J0RGlyZWN0aW9uKHNvcnRQYXJ0c1sxXSlcbiAgICA6IFwiYXNjXCJcblxuICByZXR1cm4ge1xuICAgIGNvbHVtbixcbiAgICBkaXJlY3Rpb24sXG4gICAgcGF0aDogWy4uLnBhdGhdXG4gIH1cbn1cblxuLyoqXG4gKiBAcGFyYW0ge1tzdHJpbmcsIHN0cmluZ119IHNvcnRWYWx1ZSAtIFNvcnQgdHVwbGUuXG4gKiBAcGFyYW0ge3N0cmluZ1tdfSBbcGF0aF0gLSBSZWxhdGlvbnNoaXAgcGF0aC5cbiAqIEByZXR1cm5zIHtGcm9udGVuZE1vZGVsU29ydH0gLSBOb3JtYWxpemVkIHNvcnQgZGVzY3JpcHRvci5cbiAqL1xuZnVuY3Rpb24gZnJvbnRlbmRNb2RlbFNvcnRGcm9tVHVwbGUoc29ydFZhbHVlLCBwYXRoID0gW10pIHtcbiAgY29uc3QgW2NvbHVtblZhbHVlLCBkaXJlY3Rpb25WYWx1ZV0gPSBzb3J0VmFsdWVcbiAgY29uc3QgY29sdW1uID0gY29sdW1uVmFsdWUudHJpbSgpXG5cbiAgaWYgKGNvbHVtbi5sZW5ndGggPCAxKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKFwic29ydCB0dXBsZSBjb2x1bW4gbXVzdCBiZSBhIG5vbi1lbXB0eSBzdHJpbmdcIilcbiAgfVxuXG4gIHJldHVybiB7XG4gICAgY29sdW1uLFxuICAgIGRpcmVjdGlvbjogbm9ybWFsaXplRnJvbnRlbmRNb2RlbFNvcnREaXJlY3Rpb24oZGlyZWN0aW9uVmFsdWUpLFxuICAgIHBhdGg6IFsuLi5wYXRoXVxuICB9XG59XG5cbi8qKlxuICogQHBhcmFtIHtzdHJpbmd9IGdyb3VwVmFsdWUgLSBHcm91cCBzdHJpbmcuXG4gKiBAcGFyYW0ge3N0cmluZ1tdfSBbcGF0aF0gLSBSZWxhdGlvbnNoaXAgcGF0aC5cbiAqIEByZXR1cm5zIHtGcm9udGVuZE1vZGVsR3JvdXB9IC0gTm9ybWFsaXplZCBncm91cCBkZXNjcmlwdG9yLlxuICovXG5mdW5jdGlvbiBmcm9udGVuZE1vZGVsR3JvdXBGcm9tU3RyaW5nKGdyb3VwVmFsdWUsIHBhdGggPSBbXSkge1xuICBjb25zdCB0cmltbWVkID0gZ3JvdXBWYWx1ZS50cmltKClcblxuICBpZiAoIS9eW2EtekEtWl9dW2EtekEtWjAtOV9dKiQvLnRlc3QodHJpbW1lZCkpIHtcbiAgICB0aHJvdyBmcm9udGVuZE1vZGVsVmFsaWRhdGlvbkVycm9yKGBJbnZhbGlkIGdyb3VwIGNvbHVtbjogJHtncm91cFZhbHVlfWApXG4gIH1cblxuICByZXR1cm4ge1xuICAgIGNvbHVtbjogdHJpbW1lZCxcbiAgICBwYXRoOiBbLi4ucGF0aF1cbiAgfVxufVxuXG4vKipcbiAqIEBwYXJhbSB7UmVjb3JkPHN0cmluZywgYW55Pn0gc29ydFZhbHVlIC0gTmVzdGVkIHNvcnQgb2JqZWN0LlxuICogQHBhcmFtIHtzdHJpbmdbXX0gcGF0aCAtIFJlbGF0aW9uc2hpcCBwYXRoLlxuICogQHJldHVybnMge0Zyb250ZW5kTW9kZWxTb3J0W119IC0gTm9ybWFsaXplZCBzb3J0IGRlc2NyaXB0b3JzLlxuICovXG5mdW5jdGlvbiBub3JtYWxpemVGcm9udGVuZE1vZGVsU29ydE9iamVjdChzb3J0VmFsdWUsIHBhdGgpIHtcbiAgLyoqIEB0eXBlIHtGcm9udGVuZE1vZGVsU29ydFtdfSAqL1xuICBjb25zdCBub3JtYWxpemVkU29ydHMgPSBbXVxuXG4gIGZvciAoY29uc3QgW3NvcnRLZXksIHNvcnRFbnRyeV0gb2YgT2JqZWN0LmVudHJpZXMoc29ydFZhbHVlKSkge1xuICAgIGlmICh0eXBlb2Ygc29ydEVudHJ5ID09PSBcInN0cmluZ1wiKSB7XG4gICAgICBub3JtYWxpemVkU29ydHMucHVzaCh7XG4gICAgICAgIGNvbHVtbjogc29ydEtleSxcbiAgICAgICAgZGlyZWN0aW9uOiBub3JtYWxpemVGcm9udGVuZE1vZGVsU29ydERpcmVjdGlvbihzb3J0RW50cnkpLFxuICAgICAgICBwYXRoOiBbLi4ucGF0aF1cbiAgICAgIH0pXG4gICAgICBjb250aW51ZVxuICAgIH1cblxuICAgIGlmIChmcm9udGVuZE1vZGVsU29ydFR1cGxlKHNvcnRFbnRyeSkpIHtcbiAgICAgIG5vcm1hbGl6ZWRTb3J0cy5wdXNoKGZyb250ZW5kTW9kZWxTb3J0RnJvbVR1cGxlKHNvcnRFbnRyeSwgWy4uLnBhdGgsIHNvcnRLZXldKSlcbiAgICAgIGNvbnRpbnVlXG4gICAgfVxuXG4gICAgaWYgKEFycmF5LmlzQXJyYXkoc29ydEVudHJ5KSkge1xuICAgICAgaWYgKHNvcnRFbnRyeS5sZW5ndGggPCAxKSB7XG4gICAgICAgIHRocm93IGZyb250ZW5kTW9kZWxWYWxpZGF0aW9uRXJyb3IoYEludmFsaWQgc29ydCBkZWZpbml0aW9uIGZvciBcIiR7c29ydEtleX1cIjogZW1wdHkgYXJyYXlgKVxuICAgICAgfVxuXG4gICAgICBmb3IgKGNvbnN0IG5lc3RlZFNvcnRFbnRyeSBvZiBzb3J0RW50cnkpIHtcbiAgICAgICAgaWYgKCFmcm9udGVuZE1vZGVsU29ydFR1cGxlKG5lc3RlZFNvcnRFbnRyeSkpIHtcbiAgICAgICAgICB0aHJvdyBmcm9udGVuZE1vZGVsVmFsaWRhdGlvbkVycm9yKGBJbnZhbGlkIHNvcnQgZGVmaW5pdGlvbiBmb3IgXCIke3NvcnRLZXl9XCI6IGV4cGVjdGVkIFtjb2x1bW4sIGRpcmVjdGlvbl0gdHVwbGVzYClcbiAgICAgICAgfVxuXG4gICAgICAgIG5vcm1hbGl6ZWRTb3J0cy5wdXNoKGZyb250ZW5kTW9kZWxTb3J0RnJvbVR1cGxlKG5lc3RlZFNvcnRFbnRyeSwgWy4uLnBhdGgsIHNvcnRLZXldKSlcbiAgICAgIH1cblxuICAgICAgY29udGludWVcbiAgICB9XG5cbiAgICBpZiAoaXNQbGFpbk9iamVjdChzb3J0RW50cnkpKSB7XG4gICAgICBub3JtYWxpemVkU29ydHMucHVzaCguLi5ub3JtYWxpemVGcm9udGVuZE1vZGVsU29ydE9iamVjdChzb3J0RW50cnksIFsuLi5wYXRoLCBzb3J0S2V5XSkpXG4gICAgICBjb250aW51ZVxuICAgIH1cblxuICAgIHRocm93IGZyb250ZW5kTW9kZWxWYWxpZGF0aW9uRXJyb3IoYEludmFsaWQgc29ydCBkZWZpbml0aW9uIGZvciBcIiR7c29ydEtleX1cIjogJHt0eXBlb2Ygc29ydEVudHJ5fWApXG4gIH1cblxuICByZXR1cm4gbm9ybWFsaXplZFNvcnRzXG59XG5cbi8qKlxuICogQHBhcmFtIHtSZWNvcmQ8c3RyaW5nLCBhbnk+fSBncm91cFZhbHVlIC0gTmVzdGVkIGdyb3VwIG9iamVjdC5cbiAqIEBwYXJhbSB7c3RyaW5nW119IHBhdGggLSBSZWxhdGlvbnNoaXAgcGF0aC5cbiAqIEByZXR1cm5zIHtGcm9udGVuZE1vZGVsR3JvdXBbXX0gLSBOb3JtYWxpemVkIGdyb3VwIGRlc2NyaXB0b3JzLlxuICovXG5mdW5jdGlvbiBub3JtYWxpemVGcm9udGVuZE1vZGVsR3JvdXBPYmplY3QoZ3JvdXBWYWx1ZSwgcGF0aCkge1xuICAvKiogQHR5cGUge0Zyb250ZW5kTW9kZWxHcm91cFtdfSAqL1xuICBjb25zdCBub3JtYWxpemVkR3JvdXBzID0gW11cblxuICBmb3IgKGNvbnN0IFtncm91cEtleSwgZ3JvdXBFbnRyeV0gb2YgT2JqZWN0LmVudHJpZXMoZ3JvdXBWYWx1ZSkpIHtcbiAgICBpZiAodHlwZW9mIGdyb3VwRW50cnkgPT09IFwic3RyaW5nXCIpIHtcbiAgICAgIG5vcm1hbGl6ZWRHcm91cHMucHVzaChmcm9udGVuZE1vZGVsR3JvdXBGcm9tU3RyaW5nKGdyb3VwRW50cnksIFsuLi5wYXRoLCBncm91cEtleV0pKVxuICAgICAgY29udGludWVcbiAgICB9XG5cbiAgICBpZiAoQXJyYXkuaXNBcnJheShncm91cEVudHJ5KSkge1xuICAgICAgaWYgKGdyb3VwRW50cnkubGVuZ3RoIDwgMSkge1xuICAgICAgICB0aHJvdyBmcm9udGVuZE1vZGVsVmFsaWRhdGlvbkVycm9yKGBJbnZhbGlkIGdyb3VwIGRlZmluaXRpb24gZm9yIFwiJHtncm91cEtleX1cIjogZW1wdHkgYXJyYXlgKVxuICAgICAgfVxuXG4gICAgICBmb3IgKGNvbnN0IG5lc3RlZEdyb3VwRW50cnkgb2YgZ3JvdXBFbnRyeSkge1xuICAgICAgICBpZiAodHlwZW9mIG5lc3RlZEdyb3VwRW50cnkgIT09IFwic3RyaW5nXCIpIHtcbiAgICAgICAgICB0aHJvdyBmcm9udGVuZE1vZGVsVmFsaWRhdGlvbkVycm9yKGBJbnZhbGlkIGdyb3VwIGRlZmluaXRpb24gZm9yIFwiJHtncm91cEtleX1cIjogZXhwZWN0ZWQgc3RyaW5nIGNvbHVtbnNgKVxuICAgICAgICB9XG5cbiAgICAgICAgbm9ybWFsaXplZEdyb3Vwcy5wdXNoKGZyb250ZW5kTW9kZWxHcm91cEZyb21TdHJpbmcobmVzdGVkR3JvdXBFbnRyeSwgWy4uLnBhdGgsIGdyb3VwS2V5XSkpXG4gICAgICB9XG5cbiAgICAgIGNvbnRpbnVlXG4gICAgfVxuXG4gICAgaWYgKGlzUGxhaW5PYmplY3QoZ3JvdXBFbnRyeSkpIHtcbiAgICAgIG5vcm1hbGl6ZWRHcm91cHMucHVzaCguLi5ub3JtYWxpemVGcm9udGVuZE1vZGVsR3JvdXBPYmplY3QoZ3JvdXBFbnRyeSwgWy4uLnBhdGgsIGdyb3VwS2V5XSkpXG4gICAgICBjb250aW51ZVxuICAgIH1cblxuICAgIHRocm93IGZyb250ZW5kTW9kZWxWYWxpZGF0aW9uRXJyb3IoYEludmFsaWQgZ3JvdXAgZGVmaW5pdGlvbiBmb3IgXCIke2dyb3VwS2V5fVwiOiAke3R5cGVvZiBncm91cEVudHJ5fWApXG4gIH1cblxuICByZXR1cm4gbm9ybWFsaXplZEdyb3Vwc1xufVxuXG4vKipcbiAqIEBwYXJhbSB7dW5rbm93bn0gc2VhcmNoZXMgLSBTZWFyY2ggcGF5bG9hZC5cbiAqIEByZXR1cm5zIHtGcm9udGVuZE1vZGVsU2VhcmNoW119IC0gTm9ybWFsaXplZCBzZWFyY2hlcy5cbiAqL1xuZnVuY3Rpb24gbm9ybWFsaXplRnJvbnRlbmRNb2RlbFNlYXJjaGVzKHNlYXJjaGVzKSB7XG4gIGlmICghc2VhcmNoZXMpIHJldHVybiBbXVxuXG4gIGlmICghQXJyYXkuaXNBcnJheShzZWFyY2hlcykpIHtcbiAgICB0aHJvdyBmcm9udGVuZE1vZGVsVmFsaWRhdGlvbkVycm9yKGBJbnZhbGlkIHNlYXJjaGVzIHR5cGU6ICR7dHlwZW9mIHNlYXJjaGVzfWApXG4gIH1cblxuICAvKiogQHR5cGUge0Zyb250ZW5kTW9kZWxTZWFyY2hbXX0gKi9cbiAgY29uc3Qgbm9ybWFsaXplZCA9IFtdXG5cbiAgZm9yIChjb25zdCBzZWFyY2ggb2Ygc2VhcmNoZXMpIHtcbiAgICBpZiAoIWlzUGxhaW5PYmplY3Qoc2VhcmNoKSkge1xuICAgICAgdGhyb3cgZnJvbnRlbmRNb2RlbFZhbGlkYXRpb25FcnJvcihgSW52YWxpZCBzZWFyY2ggZW50cnkgdHlwZTogJHt0eXBlb2Ygc2VhcmNofWApXG4gICAgfVxuXG4gICAgY29uc3QgcGF0aCA9IHNlYXJjaC5wYXRoXG4gICAgY29uc3QgY29sdW1uID0gc2VhcmNoLmNvbHVtblxuICAgIGNvbnN0IG9wZXJhdG9yID0gc2VhcmNoLm9wZXJhdG9yXG5cbiAgICBpZiAoIUFycmF5LmlzQXJyYXkocGF0aCkpIHtcbiAgICAgIHRocm93IGZyb250ZW5kTW9kZWxWYWxpZGF0aW9uRXJyb3IoXCJJbnZhbGlkIHNlYXJjaCBwYXRoOiBleHBlY3RlZCBhbiBhcnJheVwiKVxuICAgIH1cblxuICAgIGZvciAoY29uc3QgcGF0aEVudHJ5IG9mIHBhdGgpIHtcbiAgICAgIGlmICh0eXBlb2YgcGF0aEVudHJ5ICE9PSBcInN0cmluZ1wiIHx8IHBhdGhFbnRyeS5sZW5ndGggPCAxKSB7XG4gICAgICAgIHRocm93IGZyb250ZW5kTW9kZWxWYWxpZGF0aW9uRXJyb3IoXCJJbnZhbGlkIHNlYXJjaCBwYXRoIGVudHJ5OiBleHBlY3RlZCBub24tZW1wdHkgc3RyaW5nXCIpXG4gICAgICB9XG4gICAgfVxuXG4gICAgaWYgKHR5cGVvZiBjb2x1bW4gIT09IFwic3RyaW5nXCIgfHwgY29sdW1uLmxlbmd0aCA8IDEpIHtcbiAgICAgIHRocm93IGZyb250ZW5kTW9kZWxWYWxpZGF0aW9uRXJyb3IoXCJJbnZhbGlkIHNlYXJjaCBjb2x1bW46IGV4cGVjdGVkIG5vbi1lbXB0eSBzdHJpbmdcIilcbiAgICB9XG5cbiAgICBpZiAodHlwZW9mIG9wZXJhdG9yICE9PSBcInN0cmluZ1wiKSB7XG4gICAgICB0aHJvdyBmcm9udGVuZE1vZGVsVmFsaWRhdGlvbkVycm9yKGBJbnZhbGlkIHNlYXJjaCBvcGVyYXRvcjogJHtvcGVyYXRvcn1gKVxuICAgIH1cblxuICAgIG5vcm1hbGl6ZWQucHVzaCh7XG4gICAgICBjb2x1bW4sXG4gICAgICBvcGVyYXRvcjogbm9ybWFsaXplRnJvbnRlbmRNb2RlbFNlYXJjaE9wZXJhdG9yKG9wZXJhdG9yKSxcbiAgICAgIHBhdGg6IFsuLi5wYXRoXSxcbiAgICAgIHZhbHVlOiBzZWFyY2gudmFsdWVcbiAgICB9KVxuICB9XG5cbiAgcmV0dXJuIG5vcm1hbGl6ZWRcbn1cblxuLyoqXG4gKiBAcGFyYW0ge3Vua25vd259IHdoZXJlIC0gV2hlcmUgcGF5bG9hZC5cbiAqIEByZXR1cm5zIHtSZWNvcmQ8c3RyaW5nLCBhbnk+IHwgbnVsbH0gLSBOb3JtYWxpemVkIHdoZXJlIGhhc2guXG4gKi9cbmZ1bmN0aW9uIG5vcm1hbGl6ZUZyb250ZW5kTW9kZWxXaGVyZSh3aGVyZSkge1xuICBpZiAoIXdoZXJlKSByZXR1cm4gbnVsbFxuXG4gIGlmICghaXNQbGFpbk9iamVjdCh3aGVyZSkpIHtcbiAgICB0aHJvdyBmcm9udGVuZE1vZGVsVmFsaWRhdGlvbkVycm9yKGBJbnZhbGlkIHdoZXJlIHR5cGU6ICR7dHlwZW9mIHdoZXJlfWApXG4gIH1cblxuICByZXR1cm4gLyoqIEB0eXBlIHtSZWNvcmQ8c3RyaW5nLCBhbnk+fSAqLyAoSlNPTi5wYXJzZShKU09OLnN0cmluZ2lmeSh3aGVyZSkpKVxufVxuXG4vKipcbiAqIEBwYXJhbSB7dW5rbm93bn0gcmFuc2FjayAtIFJhbnNhY2sgcGF5bG9hZC5cbiAqIEByZXR1cm5zIHtSZWNvcmQ8c3RyaW5nLCBhbnk+IHwgbnVsbH0gLSBOb3JtYWxpemVkIFJhbnNhY2sgaGFzaC5cbiAqL1xuZnVuY3Rpb24gbm9ybWFsaXplRnJvbnRlbmRNb2RlbFJhbnNhY2socmFuc2Fjaykge1xuICBpZiAoIXJhbnNhY2spIHJldHVybiBudWxsXG5cbiAgaWYgKCFpc1BsYWluT2JqZWN0KHJhbnNhY2spKSB7XG4gICAgdGhyb3cgZnJvbnRlbmRNb2RlbFZhbGlkYXRpb25FcnJvcihgSW52YWxpZCByYW5zYWNrIHR5cGU6ICR7dHlwZW9mIHJhbnNhY2t9YClcbiAgfVxuXG4gIHJldHVybiAvKiogQHR5cGUge1JlY29yZDxzdHJpbmcsIGFueT59ICovIChKU09OLnBhcnNlKEpTT04uc3RyaW5naWZ5KHJhbnNhY2spKSlcbn1cblxuLyoqXG4gKiBAcGFyYW0ge3Vua25vd259IHZhbHVlIC0gQ2FuZGlkYXRlIGludGVnZXIuXG4gKiBAcGFyYW0ge3N0cmluZ30gbmFtZSAtIFBhcmFtIG5hbWUgZm9yIGVycm9ycy5cbiAqIEBwYXJhbSB7bnVtYmVyfSBtaW4gLSBNaW5pbXVtIGFsbG93ZWQgdmFsdWUuXG4gKiBAcmV0dXJucyB7bnVtYmVyIHwgbnVsbH0gLSBOb3JtYWxpemVkIGludGVnZXIuXG4gKi9cbmZ1bmN0aW9uIG5vcm1hbGl6ZUZyb250ZW5kTW9kZWxJbnRlZ2VyUGFyYW0odmFsdWUsIG5hbWUsIG1pbikge1xuICBpZiAodmFsdWUgPT0gbnVsbCkgcmV0dXJuIG51bGxcblxuICBpZiAodHlwZW9mIHZhbHVlICE9PSBcIm51bWJlclwiIHx8ICFOdW1iZXIuaXNJbnRlZ2VyKHZhbHVlKSkge1xuICAgIHRocm93IGZyb250ZW5kTW9kZWxWYWxpZGF0aW9uRXJyb3IoYEludmFsaWQgJHtuYW1lfTogZXhwZWN0ZWQgaW50ZWdlciBudW1iZXJgKVxuICB9XG5cbiAgaWYgKHZhbHVlIDwgbWluKSB7XG4gICAgdGhyb3cgZnJvbnRlbmRNb2RlbFZhbGlkYXRpb25FcnJvcihgSW52YWxpZCAke25hbWV9OiBleHBlY3RlZCB2YWx1ZSA+PSAke21pbn1gKVxuICB9XG5cbiAgcmV0dXJuIHZhbHVlXG59XG5cbi8qKlxuICogQHBhcmFtIHtvYmplY3R9IGFyZ3MgLSBQYWdpbmF0aW9uIGFyZ3MuXG4gKiBAcGFyYW0ge3Vua25vd259IGFyZ3MubGltaXQgLSBMaW1pdCBwYXlsb2FkLlxuICogQHBhcmFtIHt1bmtub3dufSBhcmdzLm9mZnNldCAtIE9mZnNldCBwYXlsb2FkLlxuICogQHBhcmFtIHt1bmtub3dufSBhcmdzLnBhZ2UgLSBQYWdlIHBheWxvYWQuXG4gKiBAcGFyYW0ge3Vua25vd259IGFyZ3MucGVyUGFnZSAtIFBlci1wYWdlIHBheWxvYWQuXG4gKiBAcmV0dXJucyB7RnJvbnRlbmRNb2RlbFBhZ2luYXRpb259IC0gTm9ybWFsaXplZCBwYWdpbmF0aW9uIGRhdGEuXG4gKi9cbmZ1bmN0aW9uIG5vcm1hbGl6ZUZyb250ZW5kTW9kZWxQYWdpbmF0aW9uKHtsaW1pdCwgb2Zmc2V0LCBwYWdlLCBwZXJQYWdlfSkge1xuICByZXR1cm4ge1xuICAgIGxpbWl0OiBub3JtYWxpemVGcm9udGVuZE1vZGVsSW50ZWdlclBhcmFtKGxpbWl0LCBcImxpbWl0XCIsIDApLFxuICAgIG9mZnNldDogbm9ybWFsaXplRnJvbnRlbmRNb2RlbEludGVnZXJQYXJhbShvZmZzZXQsIFwib2Zmc2V0XCIsIDApLFxuICAgIHBhZ2U6IG5vcm1hbGl6ZUZyb250ZW5kTW9kZWxJbnRlZ2VyUGFyYW0ocGFnZSwgXCJwYWdlXCIsIDEpLFxuICAgIHBlclBhZ2U6IG5vcm1hbGl6ZUZyb250ZW5kTW9kZWxJbnRlZ2VyUGFyYW0ocGVyUGFnZSwgXCJwZXJQYWdlXCIsIDEpXG4gIH1cbn1cblxuLyoqXG4gKiBAcGFyYW0ge3Vua25vd259IGRpc3RpbmN0IC0gRGlzdGluY3QgcGF5bG9hZC5cbiAqIEByZXR1cm5zIHtib29sZWFuIHwgbnVsbH0gLSBOb3JtYWxpemVkIGRpc3RpbmN0IGZsYWcgd2hlbiBwcm92aWRlZC5cbiAqL1xuZnVuY3Rpb24gbm9ybWFsaXplRnJvbnRlbmRNb2RlbERpc3RpbmN0KGRpc3RpbmN0KSB7XG4gIGlmIChkaXN0aW5jdCA9PSBudWxsKSByZXR1cm4gbnVsbFxuXG4gIGlmICh0eXBlb2YgZGlzdGluY3QgIT09IFwiYm9vbGVhblwiKSB7XG4gICAgdGhyb3cgZnJvbnRlbmRNb2RlbFZhbGlkYXRpb25FcnJvcihgSW52YWxpZCBkaXN0aW5jdDogZXhwZWN0ZWQgYm9vbGVhbmApXG4gIH1cblxuICByZXR1cm4gZGlzdGluY3Rcbn1cblxuLyoqXG4gKiBAcGFyYW0ge3Vua25vd259IHNvcnQgLSBTb3J0IHBheWxvYWQuXG4gKiBAcmV0dXJucyB7RnJvbnRlbmRNb2RlbFNvcnRbXX0gLSBOb3JtYWxpemVkIHNvcnQgZGVmaW5pdGlvbnMuXG4gKi9cbmZ1bmN0aW9uIG5vcm1hbGl6ZUZyb250ZW5kTW9kZWxTb3J0KHNvcnQpIHtcbiAgaWYgKCFzb3J0KSByZXR1cm4gW11cblxuICBpZiAodHlwZW9mIHNvcnQgPT09IFwic3RyaW5nXCIpIHtcbiAgICByZXR1cm4gW2Zyb250ZW5kTW9kZWxTb3J0RnJvbVN0cmluZyhzb3J0KV1cbiAgfVxuXG4gIGlmIChmcm9udGVuZE1vZGVsU29ydFR1cGxlKHNvcnQpKSB7XG4gICAgcmV0dXJuIFtmcm9udGVuZE1vZGVsU29ydEZyb21UdXBsZShzb3J0KV1cbiAgfVxuXG4gIGlmIChmcm9udGVuZE1vZGVsU29ydERlc2NyaXB0b3Ioc29ydCkpIHtcbiAgICByZXR1cm4gW3tcbiAgICAgIGNvbHVtbjogc29ydC5jb2x1bW4udHJpbSgpLFxuICAgICAgZGlyZWN0aW9uOiBub3JtYWxpemVGcm9udGVuZE1vZGVsU29ydERpcmVjdGlvbihzb3J0LmRpcmVjdGlvbiksXG4gICAgICBwYXRoOiBbLi4uc29ydC5wYXRoXVxuICAgIH1dXG4gIH1cblxuICBpZiAoaXNQbGFpbk9iamVjdChzb3J0KSkge1xuICAgIHJldHVybiBub3JtYWxpemVGcm9udGVuZE1vZGVsU29ydE9iamVjdChzb3J0LCBbXSlcbiAgfVxuXG4gIGlmIChBcnJheS5pc0FycmF5KHNvcnQpKSB7XG4gICAgLyoqIEB0eXBlIHtGcm9udGVuZE1vZGVsU29ydFtdfSAqL1xuICAgIGNvbnN0IG5vcm1hbGl6ZWQgPSBbXVxuXG4gICAgZm9yIChjb25zdCBzb3J0RW50cnkgb2Ygc29ydCkge1xuICAgICAgaWYgKHR5cGVvZiBzb3J0RW50cnkgPT09IFwic3RyaW5nXCIpIHtcbiAgICAgICAgbm9ybWFsaXplZC5wdXNoKGZyb250ZW5kTW9kZWxTb3J0RnJvbVN0cmluZyhzb3J0RW50cnkpKVxuICAgICAgICBjb250aW51ZVxuICAgICAgfVxuXG4gICAgICBpZiAoZnJvbnRlbmRNb2RlbFNvcnRUdXBsZShzb3J0RW50cnkpKSB7XG4gICAgICAgIG5vcm1hbGl6ZWQucHVzaChmcm9udGVuZE1vZGVsU29ydEZyb21UdXBsZShzb3J0RW50cnkpKVxuICAgICAgICBjb250aW51ZVxuICAgICAgfVxuXG4gICAgICBpZiAoZnJvbnRlbmRNb2RlbFNvcnREZXNjcmlwdG9yKHNvcnRFbnRyeSkpIHtcbiAgICAgICAgbm9ybWFsaXplZC5wdXNoKHtcbiAgICAgICAgICBjb2x1bW46IHNvcnRFbnRyeS5jb2x1bW4udHJpbSgpLFxuICAgICAgICAgIGRpcmVjdGlvbjogbm9ybWFsaXplRnJvbnRlbmRNb2RlbFNvcnREaXJlY3Rpb24oc29ydEVudHJ5LmRpcmVjdGlvbiksXG4gICAgICAgICAgcGF0aDogWy4uLnNvcnRFbnRyeS5wYXRoXVxuICAgICAgICB9KVxuICAgICAgICBjb250aW51ZVxuICAgICAgfVxuXG4gICAgICBpZiAoaXNQbGFpbk9iamVjdChzb3J0RW50cnkpKSB7XG4gICAgICAgIG5vcm1hbGl6ZWQucHVzaCguLi5ub3JtYWxpemVGcm9udGVuZE1vZGVsU29ydE9iamVjdChzb3J0RW50cnksIFtdKSlcbiAgICAgICAgY29udGludWVcbiAgICAgIH1cblxuICAgICAgdGhyb3cgZnJvbnRlbmRNb2RlbFZhbGlkYXRpb25FcnJvcihgSW52YWxpZCBzb3J0IGVudHJ5IHR5cGU6ICR7dHlwZW9mIHNvcnRFbnRyeX1gKVxuICAgIH1cblxuICAgIHJldHVybiBub3JtYWxpemVkXG4gIH1cblxuICB0aHJvdyBmcm9udGVuZE1vZGVsVmFsaWRhdGlvbkVycm9yKGBJbnZhbGlkIHNvcnQgdHlwZTogJHt0eXBlb2Ygc29ydH1gKVxufVxuXG4vKipcbiAqIEBwYXJhbSB7dW5rbm93bn0gZ3JvdXAgLSBHcm91cCBwYXlsb2FkLlxuICogQHJldHVybnMge0Zyb250ZW5kTW9kZWxHcm91cFtdfSAtIE5vcm1hbGl6ZWQgZ3JvdXAgZGVmaW5pdGlvbnMuXG4gKi9cbmZ1bmN0aW9uIG5vcm1hbGl6ZUZyb250ZW5kTW9kZWxHcm91cChncm91cCkge1xuICBpZiAoIWdyb3VwKSByZXR1cm4gW11cblxuICBpZiAodHlwZW9mIGdyb3VwID09PSBcInN0cmluZ1wiKSB7XG4gICAgcmV0dXJuIFtmcm9udGVuZE1vZGVsR3JvdXBGcm9tU3RyaW5nKGdyb3VwKV1cbiAgfVxuXG4gIGlmIChmcm9udGVuZE1vZGVsR3JvdXBEZXNjcmlwdG9yKGdyb3VwKSkge1xuICAgIHJldHVybiBbe1xuICAgICAgY29sdW1uOiBmcm9udGVuZE1vZGVsR3JvdXBGcm9tU3RyaW5nKGdyb3VwLmNvbHVtbikuY29sdW1uLFxuICAgICAgcGF0aDogWy4uLmdyb3VwLnBhdGhdXG4gICAgfV1cbiAgfVxuXG4gIGlmIChpc1BsYWluT2JqZWN0KGdyb3VwKSkge1xuICAgIHJldHVybiBub3JtYWxpemVGcm9udGVuZE1vZGVsR3JvdXBPYmplY3QoZ3JvdXAsIFtdKVxuICB9XG5cbiAgaWYgKEFycmF5LmlzQXJyYXkoZ3JvdXApKSB7XG4gICAgLyoqIEB0eXBlIHtGcm9udGVuZE1vZGVsR3JvdXBbXX0gKi9cbiAgICBjb25zdCBub3JtYWxpemVkID0gW11cblxuICAgIGZvciAoY29uc3QgZ3JvdXBFbnRyeSBvZiBncm91cCkge1xuICAgICAgaWYgKHR5cGVvZiBncm91cEVudHJ5ID09PSBcInN0cmluZ1wiKSB7XG4gICAgICAgIG5vcm1hbGl6ZWQucHVzaChmcm9udGVuZE1vZGVsR3JvdXBGcm9tU3RyaW5nKGdyb3VwRW50cnkpKVxuICAgICAgICBjb250aW51ZVxuICAgICAgfVxuXG4gICAgICBpZiAoZnJvbnRlbmRNb2RlbEdyb3VwRGVzY3JpcHRvcihncm91cEVudHJ5KSkge1xuICAgICAgICBub3JtYWxpemVkLnB1c2goe1xuICAgICAgICAgIGNvbHVtbjogZnJvbnRlbmRNb2RlbEdyb3VwRnJvbVN0cmluZyhncm91cEVudHJ5LmNvbHVtbikuY29sdW1uLFxuICAgICAgICAgIHBhdGg6IFsuLi5ncm91cEVudHJ5LnBhdGhdXG4gICAgICAgIH0pXG4gICAgICAgIGNvbnRpbnVlXG4gICAgICB9XG5cbiAgICAgIGlmIChpc1BsYWluT2JqZWN0KGdyb3VwRW50cnkpKSB7XG4gICAgICAgIG5vcm1hbGl6ZWQucHVzaCguLi5ub3JtYWxpemVGcm9udGVuZE1vZGVsR3JvdXBPYmplY3QoZ3JvdXBFbnRyeSwgW10pKVxuICAgICAgICBjb250aW51ZVxuICAgICAgfVxuXG4gICAgICB0aHJvdyBmcm9udGVuZE1vZGVsVmFsaWRhdGlvbkVycm9yKGBJbnZhbGlkIGdyb3VwIGVudHJ5IHR5cGU6ICR7dHlwZW9mIGdyb3VwRW50cnl9YClcbiAgICB9XG5cbiAgICByZXR1cm4gbm9ybWFsaXplZFxuICB9XG5cbiAgdGhyb3cgZnJvbnRlbmRNb2RlbFZhbGlkYXRpb25FcnJvcihgSW52YWxpZCBncm91cCB0eXBlOiAke3R5cGVvZiBncm91cH1gKVxufVxuXG4vKipcbiAqIEBwYXJhbSB7dW5rbm93bn0gdmFsdWUgLSBDYW5kaWRhdGUgZGVzY3JpcHRvci5cbiAqIEByZXR1cm5zIHt2YWx1ZSBpcyB7Y29sdW1uOiBzdHJpbmcsIHBhdGg6IHN0cmluZ1tdfX0gLSBXaGV0aGVyIGNhbmRpZGF0ZSBpcyBhbiBleHBsaWNpdCBwbHVjayBkZXNjcmlwdG9yIG9iamVjdC5cbiAqL1xuZnVuY3Rpb24gZnJvbnRlbmRNb2RlbFBsdWNrRGVzY3JpcHRvcih2YWx1ZSkge1xuICBpZiAoIWlzUGxhaW5PYmplY3QodmFsdWUpKSByZXR1cm4gZmFsc2VcbiAgaWYgKCEoXCJjb2x1bW5cIiBpbiB2YWx1ZSkgfHwgIShcInBhdGhcIiBpbiB2YWx1ZSkpIHJldHVybiBmYWxzZVxuICBpZiAodHlwZW9mIHZhbHVlLmNvbHVtbiAhPT0gXCJzdHJpbmdcIikgcmV0dXJuIGZhbHNlXG4gIGlmICghQXJyYXkuaXNBcnJheSh2YWx1ZS5wYXRoKSkgcmV0dXJuIGZhbHNlXG5cbiAgcmV0dXJuIHZhbHVlLnBhdGguZXZlcnkoKHBhdGhFbnRyeSkgPT4gdHlwZW9mIHBhdGhFbnRyeSA9PT0gXCJzdHJpbmdcIilcbn1cblxuLyoqXG4gKiBAcGFyYW0ge3N0cmluZ30gcGx1Y2tWYWx1ZSAtIFBsdWNrIHN0cmluZy5cbiAqIEBwYXJhbSB7c3RyaW5nW119IFtwYXRoXSAtIFJlbGF0aW9uc2hpcCBwYXRoLlxuICogQHJldHVybnMge0Zyb250ZW5kTW9kZWxQbHVja30gLSBOb3JtYWxpemVkIHBsdWNrIGRlc2NyaXB0b3IuXG4gKi9cbmZ1bmN0aW9uIGZyb250ZW5kTW9kZWxQbHVja0Zyb21TdHJpbmcocGx1Y2tWYWx1ZSwgcGF0aCA9IFtdKSB7XG4gIGNvbnN0IHRyaW1tZWQgPSBwbHVja1ZhbHVlLnRyaW0oKVxuXG4gIGlmICghL15bYS16QS1aX11bYS16QS1aMC05X10qJC8udGVzdCh0cmltbWVkKSkge1xuICAgIHRocm93IGZyb250ZW5kTW9kZWxWYWxpZGF0aW9uRXJyb3IoYEludmFsaWQgcGx1Y2sgY29sdW1uOiAke3BsdWNrVmFsdWV9YClcbiAgfVxuXG4gIHJldHVybiB7XG4gICAgY29sdW1uOiB0cmltbWVkLFxuICAgIHBhdGg6IFsuLi5wYXRoXVxuICB9XG59XG5cbi8qKlxuICogQHBhcmFtIHtSZWNvcmQ8c3RyaW5nLCBhbnk+fSBwbHVja1ZhbHVlIC0gTmVzdGVkIHBsdWNrIG9iamVjdC5cbiAqIEBwYXJhbSB7c3RyaW5nW119IHBhdGggLSBSZWxhdGlvbnNoaXAgcGF0aC5cbiAqIEByZXR1cm5zIHtGcm9udGVuZE1vZGVsUGx1Y2tbXX0gLSBOb3JtYWxpemVkIHBsdWNrIGRlc2NyaXB0b3JzLlxuICovXG5mdW5jdGlvbiBub3JtYWxpemVGcm9udGVuZE1vZGVsUGx1Y2tPYmplY3QocGx1Y2tWYWx1ZSwgcGF0aCkge1xuICAvKiogQHR5cGUge0Zyb250ZW5kTW9kZWxQbHVja1tdfSAqL1xuICBjb25zdCBub3JtYWxpemVkUGx1Y2tzID0gW11cblxuICBmb3IgKGNvbnN0IFtwbHVja0tleSwgcGx1Y2tFbnRyeV0gb2YgT2JqZWN0LmVudHJpZXMocGx1Y2tWYWx1ZSkpIHtcbiAgICBpZiAodHlwZW9mIHBsdWNrRW50cnkgPT09IFwic3RyaW5nXCIpIHtcbiAgICAgIG5vcm1hbGl6ZWRQbHVja3MucHVzaChmcm9udGVuZE1vZGVsUGx1Y2tGcm9tU3RyaW5nKHBsdWNrRW50cnksIFsuLi5wYXRoLCBwbHVja0tleV0pKVxuICAgICAgY29udGludWVcbiAgICB9XG5cbiAgICBpZiAoQXJyYXkuaXNBcnJheShwbHVja0VudHJ5KSkge1xuICAgICAgaWYgKHBsdWNrRW50cnkubGVuZ3RoIDwgMSkge1xuICAgICAgICB0aHJvdyBmcm9udGVuZE1vZGVsVmFsaWRhdGlvbkVycm9yKGBJbnZhbGlkIHBsdWNrIGRlZmluaXRpb24gZm9yIFwiJHtwbHVja0tleX1cIjogZW1wdHkgYXJyYXlgKVxuICAgICAgfVxuXG4gICAgICBmb3IgKGNvbnN0IG5lc3RlZFBsdWNrRW50cnkgb2YgcGx1Y2tFbnRyeSkge1xuICAgICAgICBpZiAodHlwZW9mIG5lc3RlZFBsdWNrRW50cnkgIT09IFwic3RyaW5nXCIpIHtcbiAgICAgICAgICB0aHJvdyBmcm9udGVuZE1vZGVsVmFsaWRhdGlvbkVycm9yKGBJbnZhbGlkIHBsdWNrIGRlZmluaXRpb24gZm9yIFwiJHtwbHVja0tleX1cIjogZXhwZWN0ZWQgc3RyaW5nIGNvbHVtbnNgKVxuICAgICAgICB9XG5cbiAgICAgICAgbm9ybWFsaXplZFBsdWNrcy5wdXNoKGZyb250ZW5kTW9kZWxQbHVja0Zyb21TdHJpbmcobmVzdGVkUGx1Y2tFbnRyeSwgWy4uLnBhdGgsIHBsdWNrS2V5XSkpXG4gICAgICB9XG5cbiAgICAgIGNvbnRpbnVlXG4gICAgfVxuXG4gICAgaWYgKGlzUGxhaW5PYmplY3QocGx1Y2tFbnRyeSkpIHtcbiAgICAgIG5vcm1hbGl6ZWRQbHVja3MucHVzaCguLi5ub3JtYWxpemVGcm9udGVuZE1vZGVsUGx1Y2tPYmplY3QocGx1Y2tFbnRyeSwgWy4uLnBhdGgsIHBsdWNrS2V5XSkpXG4gICAgICBjb250aW51ZVxuICAgIH1cblxuICAgIHRocm93IGZyb250ZW5kTW9kZWxWYWxpZGF0aW9uRXJyb3IoYEludmFsaWQgcGx1Y2sgZGVmaW5pdGlvbiBmb3IgXCIke3BsdWNrS2V5fVwiOiAke3R5cGVvZiBwbHVja0VudHJ5fWApXG4gIH1cblxuICByZXR1cm4gbm9ybWFsaXplZFBsdWNrc1xufVxuXG4vKipcbiAqIEBwYXJhbSB7dW5rbm93bn0gcGx1Y2sgLSBQbHVjayBwYXlsb2FkLlxuICogQHJldHVybnMge0Zyb250ZW5kTW9kZWxQbHVja1tdfSAtIE5vcm1hbGl6ZWQgcGx1Y2sgZGVmaW5pdGlvbnMuXG4gKi9cbmZ1bmN0aW9uIG5vcm1hbGl6ZUZyb250ZW5kTW9kZWxQbHVjayhwbHVjaykge1xuICBpZiAoIXBsdWNrKSByZXR1cm4gW11cblxuICBpZiAodHlwZW9mIHBsdWNrID09PSBcInN0cmluZ1wiKSB7XG4gICAgcmV0dXJuIFtmcm9udGVuZE1vZGVsUGx1Y2tGcm9tU3RyaW5nKHBsdWNrKV1cbiAgfVxuXG4gIGlmIChmcm9udGVuZE1vZGVsUGx1Y2tEZXNjcmlwdG9yKHBsdWNrKSkge1xuICAgIHJldHVybiBbe1xuICAgICAgY29sdW1uOiBmcm9udGVuZE1vZGVsUGx1Y2tGcm9tU3RyaW5nKHBsdWNrLmNvbHVtbikuY29sdW1uLFxuICAgICAgcGF0aDogWy4uLnBsdWNrLnBhdGhdXG4gICAgfV1cbiAgfVxuXG4gIGlmIChpc1BsYWluT2JqZWN0KHBsdWNrKSkge1xuICAgIHJldHVybiBub3JtYWxpemVGcm9udGVuZE1vZGVsUGx1Y2tPYmplY3QocGx1Y2ssIFtdKVxuICB9XG5cbiAgaWYgKEFycmF5LmlzQXJyYXkocGx1Y2spKSB7XG4gICAgLyoqIEB0eXBlIHtGcm9udGVuZE1vZGVsUGx1Y2tbXX0gKi9cbiAgICBjb25zdCBub3JtYWxpemVkID0gW11cblxuICAgIGZvciAoY29uc3QgcGx1Y2tFbnRyeSBvZiBwbHVjaykge1xuICAgICAgaWYgKHR5cGVvZiBwbHVja0VudHJ5ID09PSBcInN0cmluZ1wiKSB7XG4gICAgICAgIG5vcm1hbGl6ZWQucHVzaChmcm9udGVuZE1vZGVsUGx1Y2tGcm9tU3RyaW5nKHBsdWNrRW50cnkpKVxuICAgICAgICBjb250aW51ZVxuICAgICAgfVxuXG4gICAgICBpZiAoZnJvbnRlbmRNb2RlbFBsdWNrRGVzY3JpcHRvcihwbHVja0VudHJ5KSkge1xuICAgICAgICBub3JtYWxpemVkLnB1c2goe1xuICAgICAgICAgIGNvbHVtbjogZnJvbnRlbmRNb2RlbFBsdWNrRnJvbVN0cmluZyhwbHVja0VudHJ5LmNvbHVtbikuY29sdW1uLFxuICAgICAgICAgIHBhdGg6IFsuLi5wbHVja0VudHJ5LnBhdGhdXG4gICAgICAgIH0pXG4gICAgICAgIGNvbnRpbnVlXG4gICAgICB9XG5cbiAgICAgIGlmIChpc1BsYWluT2JqZWN0KHBsdWNrRW50cnkpKSB7XG4gICAgICAgIG5vcm1hbGl6ZWQucHVzaCguLi5ub3JtYWxpemVGcm9udGVuZE1vZGVsUGx1Y2tPYmplY3QocGx1Y2tFbnRyeSwgW10pKVxuICAgICAgICBjb250aW51ZVxuICAgICAgfVxuXG4gICAgICB0aHJvdyBmcm9udGVuZE1vZGVsVmFsaWRhdGlvbkVycm9yKGBJbnZhbGlkIHBsdWNrIGVudHJ5IHR5cGU6ICR7dHlwZW9mIHBsdWNrRW50cnl9YClcbiAgICB9XG5cbiAgICByZXR1cm4gbm9ybWFsaXplZFxuICB9XG5cbiAgdGhyb3cgZnJvbnRlbmRNb2RlbFZhbGlkYXRpb25FcnJvcihgSW52YWxpZCBwbHVjayB0eXBlOiAke3R5cGVvZiBwbHVja31gKVxufVxuXG4vKipcbiAqIEBwYXJhbSB7c3RyaW5nW119IHBhdGggLSBSZWxhdGlvbnNoaXAgcGF0aC5cbiAqIEByZXR1cm5zIHtSZWNvcmQ8c3RyaW5nLCBhbnk+fSAtIEpvaW4gb2JqZWN0LlxuICovXG5mdW5jdGlvbiBidWlsZEZyb250ZW5kTW9kZWxKb2luT2JqZWN0RnJvbVBhdGgocGF0aCkge1xuICAvKiogQHR5cGUge1JlY29yZDxzdHJpbmcsIGFueT59ICovXG4gIGNvbnN0IGpvaW5PYmplY3QgPSB7fVxuICAvKiogQHR5cGUge1JlY29yZDxzdHJpbmcsIGFueT59ICovXG4gIGxldCBjdXJyZW50Tm9kZSA9IGpvaW5PYmplY3RcblxuICBmb3IgKGNvbnN0IHJlbGF0aW9uc2hpcE5hbWUgb2YgcGF0aCkge1xuICAgIGN1cnJlbnROb2RlW3JlbGF0aW9uc2hpcE5hbWVdID0ge31cbiAgICBjdXJyZW50Tm9kZSA9IGN1cnJlbnROb2RlW3JlbGF0aW9uc2hpcE5hbWVdXG4gIH1cblxuICByZXR1cm4gam9pbk9iamVjdFxufVxuXG4vKiogQ29udHJvbGxlciB3aXRoIGJ1aWx0LWluIGZyb250ZW5kIG1vZGVsIHJlc291cmNlIGFjdGlvbnMuICovXG5leHBvcnQgZGVmYXVsdCBjbGFzcyBGcm9udGVuZE1vZGVsQ29udHJvbGxlciBleHRlbmRzIENvbnRyb2xsZXIge1xuICAvKiogQHR5cGUge1JlY29yZDxzdHJpbmcsIGFueT4gfCB1bmRlZmluZWR9ICovXG4gIF9mcm9udGVuZE1vZGVsUGFyYW1zID0gdW5kZWZpbmVkXG4gIC8qKiBAdHlwZSB7UmVjb3JkPHN0cmluZywgYW55PiB8IHVuZGVmaW5lZH0gKi9cbiAgX2Zyb250ZW5kTW9kZWxQYXJhbXNPdmVycmlkZSA9IHVuZGVmaW5lZFxuICAvKiogQHR5cGUge2ltcG9ydChcIi4vYXV0aG9yaXphdGlvbi9hYmlsaXR5LmpzXCIpLmRlZmF1bHQgfCB1bmRlZmluZWR9ICovXG4gIF9mcm9udGVuZE1vZGVsQWJpbGl0eU92ZXJyaWRlID0gdW5kZWZpbmVkXG5cbiAgLyoqXG4gICAqIEByZXR1cm5zIHtSZWNvcmQ8c3RyaW5nLCBhbnk+fSAtIERlY29kZWQgcmVxdWVzdCBwYXJhbXMuXG4gICAqL1xuICBmcm9udGVuZE1vZGVsUGFyYW1zKCkge1xuICAgIGlmICh0aGlzLl9mcm9udGVuZE1vZGVsUGFyYW1zT3ZlcnJpZGUpIHtcbiAgICAgIHJldHVybiB0aGlzLl9mcm9udGVuZE1vZGVsUGFyYW1zT3ZlcnJpZGVcbiAgICB9XG5cbiAgICB0aGlzLl9mcm9udGVuZE1vZGVsUGFyYW1zIHx8PSAvKiogQHR5cGUge1JlY29yZDxzdHJpbmcsIGFueT59ICovIChkZXNlcmlhbGl6ZUZyb250ZW5kTW9kZWxUcmFuc3BvcnRWYWx1ZSh0aGlzLnBhcmFtcygpKSlcblxuICAgIHJldHVybiB0aGlzLl9mcm9udGVuZE1vZGVsUGFyYW1zXG4gIH1cblxuICAvKipcbiAgICogQHRlbXBsYXRlIFRcbiAgICogQHBhcmFtIHtSZWNvcmQ8c3RyaW5nLCBhbnk+fSBwYXJhbXMgLSBUZW1wb3JhcnkgZnJvbnRlbmQgbW9kZWwgcGFyYW1zLlxuICAgKiBAcGFyYW0geygpID0+IFByb21pc2U8VD59IGNhbGxiYWNrIC0gQ2FsbGJhY2sgZXhlY3V0ZWQgd2l0aCB0ZW1wb3JhcnkgcGFyYW1zLlxuICAgKiBAcmV0dXJucyB7UHJvbWlzZTxUPn0gLSBDYWxsYmFjayByZXR1cm4gdmFsdWUuXG4gICAqL1xuICBhc3luYyB3aXRoRnJvbnRlbmRNb2RlbFBhcmFtcyhwYXJhbXMsIGNhbGxiYWNrKSB7XG4gICAgY29uc3QgcHJldmlvdXNPdmVycmlkZSA9IHRoaXMuX2Zyb250ZW5kTW9kZWxQYXJhbXNPdmVycmlkZVxuICAgIGNvbnN0IHByZXZpb3VzUGFyYW1zID0gdGhpcy5fZnJvbnRlbmRNb2RlbFBhcmFtc1xuXG4gICAgdGhpcy5fZnJvbnRlbmRNb2RlbFBhcmFtc092ZXJyaWRlID0gcGFyYW1zXG4gICAgdGhpcy5fZnJvbnRlbmRNb2RlbFBhcmFtcyA9IHVuZGVmaW5lZFxuXG4gICAgdHJ5IHtcbiAgICAgIHJldHVybiBhd2FpdCBjYWxsYmFjaygpXG4gICAgfSBmaW5hbGx5IHtcbiAgICAgIHRoaXMuX2Zyb250ZW5kTW9kZWxQYXJhbXNPdmVycmlkZSA9IHByZXZpb3VzT3ZlcnJpZGVcbiAgICAgIHRoaXMuX2Zyb250ZW5kTW9kZWxQYXJhbXMgPSBwcmV2aW91c1BhcmFtc1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBAdGVtcGxhdGUgVFxuICAgKiBAcGFyYW0ge1JlY29yZDxzdHJpbmcsIGFueT59IHBhcmFtcyAtIFJlcXVlc3Qtc2NvcGVkIHBhcmFtcy5cbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuL2h0dHAtc2VydmVyL2NsaWVudC9yZXNwb25zZS5qc1wiKS5kZWZhdWx0fSByZXNwb25zZSAtIFJlc3BvbnNlIGluc3RhbmNlLlxuICAgKiBAcGFyYW0geygpID0+IFByb21pc2U8VD59IGNhbGxiYWNrIC0gQ2FsbGJhY2sgZXhlY3V0ZWQgaW5zaWRlIHJlc29sdmVkIHRlbmFudCBhbmQgYWJpbGl0eSBjb250ZXh0LlxuICAgKiBAcmV0dXJucyB7UHJvbWlzZTxUPn0gLSBDYWxsYmFjayByZXR1cm4gdmFsdWUuXG4gICAqL1xuICBhc3luYyB3aXRoRnJvbnRlbmRNb2RlbFJlcXVlc3RDb250ZXh0KHBhcmFtcywgcmVzcG9uc2UsIGNhbGxiYWNrKSB7XG4gICAgY29uc3QgY29uZmlndXJhdGlvbiA9IHRoaXMuZ2V0Q29uZmlndXJhdGlvbigpXG4gICAgY29uc3QgdGVuYW50ID0gYXdhaXQgY29uZmlndXJhdGlvbi5yZXNvbHZlVGVuYW50KHtcbiAgICAgIHBhcmFtcyxcbiAgICAgIHJlcXVlc3Q6IHRoaXMucmVxdWVzdCgpLFxuICAgICAgcmVzcG9uc2VcbiAgICB9KVxuXG4gICAgcmV0dXJuIGF3YWl0IGNvbmZpZ3VyYXRpb24ucnVuV2l0aFRlbmFudCh0ZW5hbnQsIGFzeW5jICgpID0+IHtcbiAgICAgIHJldHVybiBhd2FpdCBjb25maWd1cmF0aW9uLmVuc3VyZUNvbm5lY3Rpb25zKHtuYW1lOiBcIkZyb250ZW5kIG1vZGVsIHJlcXVlc3RcIn0sIGFzeW5jICgpID0+IHtcbiAgICAgICAgY29uc3QgYWJpbGl0eSA9IGF3YWl0IGNvbmZpZ3VyYXRpb24ucmVzb2x2ZUFiaWxpdHkoe1xuICAgICAgICAgIHBhcmFtcyxcbiAgICAgICAgICByZXF1ZXN0OiB0aGlzLnJlcXVlc3QoKSxcbiAgICAgICAgICByZXNwb25zZVxuICAgICAgICB9KVxuICAgICAgICAvKiogQHR5cGUge2ltcG9ydChcIi4vYXV0aG9yaXphdGlvbi9hYmlsaXR5LmpzXCIpLmRlZmF1bHQgfCB1bmRlZmluZWR9ICovXG4gICAgICAgIGNvbnN0IHByZXZpb3VzQWJpbGl0eU92ZXJyaWRlID0gdGhpcy5fZnJvbnRlbmRNb2RlbEFiaWxpdHlPdmVycmlkZVxuXG4gICAgICAgIHRoaXMuX2Zyb250ZW5kTW9kZWxBYmlsaXR5T3ZlcnJpZGUgPSBhYmlsaXR5XG5cbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICByZXR1cm4gYXdhaXQgY29uZmlndXJhdGlvbi5ydW5XaXRoQWJpbGl0eShhYmlsaXR5LCBhc3luYyAoKSA9PiB7XG4gICAgICAgICAgICByZXR1cm4gYXdhaXQgY2FsbGJhY2soKVxuICAgICAgICAgIH0pXG4gICAgICAgIH0gZmluYWxseSB7XG4gICAgICAgICAgdGhpcy5fZnJvbnRlbmRNb2RlbEFiaWxpdHlPdmVycmlkZSA9IHByZXZpb3VzQWJpbGl0eU92ZXJyaWRlXG4gICAgICAgIH1cbiAgICAgIH0pXG4gICAgfSlcbiAgfVxuXG4gIC8qKiBAcmV0dXJucyB7aW1wb3J0KFwiLi9hdXRob3JpemF0aW9uL2FiaWxpdHkuanNcIikuZGVmYXVsdCB8IHVuZGVmaW5lZH0gLSBDdXJyZW50IGFiaWxpdHkgZm9yIGZyb250ZW5kLW1vZGVsIHJlcXVlc3Qgc2NvcGUuICovXG4gIGN1cnJlbnRBYmlsaXR5KCkge1xuICAgIHJldHVybiB0aGlzLl9mcm9udGVuZE1vZGVsQWJpbGl0eU92ZXJyaWRlIHx8IHN1cGVyLmN1cnJlbnRBYmlsaXR5KClcbiAgfVxuXG4gIC8qKlxuICAgKiBAcmV0dXJucyB7dHlwZW9mIGltcG9ydChcIi4vZGF0YWJhc2UvcmVjb3JkL2luZGV4LmpzXCIpLmRlZmF1bHR9IC0gRnJvbnRlbmQgbW9kZWwgY2xhc3MgZm9yIGNvbnRyb2xsZXIgcmVzb3VyY2UgYWN0aW9ucy5cbiAgICovXG4gIGZyb250ZW5kTW9kZWxDbGFzcygpIHtcbiAgICBjb25zdCBmcm9udGVuZE1vZGVsQ2xhc3MgPSB0aGlzLmZyb250ZW5kTW9kZWxDbGFzc0Zyb21Db25maWd1cmF0aW9uKClcbiAgICBjb25zdCBwYXJhbXMgPSB0aGlzLmZyb250ZW5kTW9kZWxQYXJhbXMoKVxuICAgIGNvbnN0IG1vZGVsTmFtZSA9IHR5cGVvZiBwYXJhbXMubW9kZWwgPT09IFwic3RyaW5nXCIgPyBwYXJhbXMubW9kZWwgOiB1bmRlZmluZWRcbiAgICBjb25zdCBjb250cm9sbGVyTmFtZSA9IHR5cGVvZiBwYXJhbXMuY29udHJvbGxlciA9PT0gXCJzdHJpbmdcIiA/IHBhcmFtcy5jb250cm9sbGVyIDogdW5kZWZpbmVkXG5cbiAgICBpZiAoZnJvbnRlbmRNb2RlbENsYXNzKSByZXR1cm4gZnJvbnRlbmRNb2RlbENsYXNzXG5cbiAgICB0aHJvdyBuZXcgRXJyb3IoYE5vIGZyb250ZW5kIG1vZGVsIGNvbmZpZ3VyZWQgZm9yIG1vZGVsICcke21vZGVsTmFtZSB8fCBcInVua25vd25cIn0nIGFuZCBjb250cm9sbGVyICcke2NvbnRyb2xsZXJOYW1lIHx8IFwidW5rbm93blwifScuIEVuc3VyZSBhIEZyb250ZW5kTW9kZWxCYXNlUmVzb3VyY2Ugc3ViY2xhc3MgZXhpc3RzIGluIHNyYy9yZXNvdXJjZXMvIG9yIGlzIGxpc3RlZCBpbiB0aGUgYWJpbGl0eSByZXNvbHZlci5gKVxuICB9XG5cbiAgLyoqXG4gICAqIEByZXR1cm5zIHt7YmFja2VuZFByb2plY3Q6IGltcG9ydChcIi4vY29uZmlndXJhdGlvbi10eXBlcy5qc1wiKS5CYWNrZW5kUHJvamVjdENvbmZpZ3VyYXRpb24sIG1vZGVsTmFtZTogc3RyaW5nLCByZXNvdXJjZUNsYXNzOiBpbXBvcnQoXCIuL2NvbmZpZ3VyYXRpb24tdHlwZXMuanNcIikuRnJvbnRlbmRNb2RlbFJlc291cmNlQ2xhc3NUeXBlLCByZXNvdXJjZUNvbmZpZ3VyYXRpb246IGltcG9ydChcIi4vY29uZmlndXJhdGlvbi10eXBlcy5qc1wiKS5Ob3JtYWxpemVkRnJvbnRlbmRNb2RlbFJlc291cmNlQ29uZmlndXJhdGlvbn0gfCBudWxsfSAtIEZyb250ZW5kIG1vZGVsIHJlc291cmNlIGNvbmZpZ3VyYXRpb24gZm9yIGN1cnJlbnQgY29udHJvbGxlci5cbiAgICovXG4gIGZyb250ZW5kTW9kZWxSZXNvdXJjZUNvbmZpZ3VyYXRpb24oKSB7XG4gICAgY29uc3QgcGFyYW1zID0gdGhpcy5mcm9udGVuZE1vZGVsUGFyYW1zKClcbiAgICBjb25zdCBtb2RlbE5hbWUgPSB0eXBlb2YgcGFyYW1zLm1vZGVsID09PSBcInN0cmluZ1wiID8gcGFyYW1zLm1vZGVsIDogdW5kZWZpbmVkXG4gICAgY29uc3QgY29udHJvbGxlck5hbWUgPSB0eXBlb2YgcGFyYW1zLmNvbnRyb2xsZXIgPT09IFwic3RyaW5nXCIgPyBwYXJhbXMuY29udHJvbGxlciA6IHVuZGVmaW5lZFxuICAgIGNvbnN0IGJhY2tlbmRQcm9qZWN0cyA9IHRoaXMuZ2V0Q29uZmlndXJhdGlvbigpLmdldEJhY2tlbmRQcm9qZWN0cygpXG5cbiAgICBmb3IgKGNvbnN0IGJhY2tlbmRQcm9qZWN0IG9mIGJhY2tlbmRQcm9qZWN0cykge1xuICAgICAgY29uc3QgcmVzb3VyY2VzID0gZnJvbnRlbmRNb2RlbFJlc291cmNlc0ZvckJhY2tlbmRQcm9qZWN0KGJhY2tlbmRQcm9qZWN0KVxuXG4gICAgICBpZiAobW9kZWxOYW1lICYmIG1vZGVsTmFtZS5sZW5ndGggPiAwICYmIHJlc291cmNlc1ttb2RlbE5hbWVdKSB7XG4gICAgICAgIGNvbnN0IHJlc291cmNlRGVmaW5pdGlvbiA9IHJlc291cmNlc1ttb2RlbE5hbWVdXG4gICAgICAgIGNvbnN0IHJlc291cmNlQ29uZmlndXJhdGlvbiA9IGZyb250ZW5kTW9kZWxSZXNvdXJjZUNvbmZpZ3VyYXRpb25Gcm9tRGVmaW5pdGlvbihyZXNvdXJjZURlZmluaXRpb24pXG4gICAgICAgIGNvbnN0IHJlc291cmNlQ2xhc3MgPSBmcm9udGVuZE1vZGVsUmVzb3VyY2VDbGFzc0Zyb21EZWZpbml0aW9uKHJlc291cmNlRGVmaW5pdGlvbilcblxuICAgICAgICBpZiAoIXJlc291cmNlQ29uZmlndXJhdGlvbiB8fCAhcmVzb3VyY2VDbGFzcykge1xuICAgICAgICAgIHRocm93IG5ldyBFcnJvcihgRnJvbnRlbmQgbW9kZWwgcmVzb3VyY2UgJyR7bW9kZWxOYW1lfScgbXVzdCBiZSBhIEZyb250ZW5kTW9kZWxCYXNlUmVzb3VyY2Ugc3ViY2xhc3NgKVxuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICBiYWNrZW5kUHJvamVjdCxcbiAgICAgICAgICBtb2RlbE5hbWUsXG4gICAgICAgICAgcmVzb3VyY2VDbGFzcyxcbiAgICAgICAgICByZXNvdXJjZUNvbmZpZ3VyYXRpb25cbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICBpZiAoIWNvbnRyb2xsZXJOYW1lIHx8IGNvbnRyb2xsZXJOYW1lLmxlbmd0aCA8IDEpIGNvbnRpbnVlXG5cbiAgICAgIGZvciAoY29uc3QgcmVzb3VyY2VNb2RlbE5hbWUgaW4gcmVzb3VyY2VzKSB7XG4gICAgICAgIGNvbnN0IHJlc291cmNlRGVmaW5pdGlvbiA9IHJlc291cmNlc1tyZXNvdXJjZU1vZGVsTmFtZV1cbiAgICAgICAgY29uc3QgcmVzb3VyY2VDb25maWd1cmF0aW9uID0gZnJvbnRlbmRNb2RlbFJlc291cmNlQ29uZmlndXJhdGlvbkZyb21EZWZpbml0aW9uKHJlc291cmNlRGVmaW5pdGlvbilcbiAgICAgICAgY29uc3QgcmVzb3VyY2VDbGFzcyA9IGZyb250ZW5kTW9kZWxSZXNvdXJjZUNsYXNzRnJvbURlZmluaXRpb24ocmVzb3VyY2VEZWZpbml0aW9uKVxuXG4gICAgICAgIGlmICghcmVzb3VyY2VDb25maWd1cmF0aW9uIHx8ICFyZXNvdXJjZUNsYXNzKSB7XG4gICAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBGcm9udGVuZCBtb2RlbCByZXNvdXJjZSAnJHtyZXNvdXJjZU1vZGVsTmFtZX0nIG11c3QgYmUgYSBGcm9udGVuZE1vZGVsQmFzZVJlc291cmNlIHN1YmNsYXNzYClcbiAgICAgICAgfVxuXG4gICAgICAgIGNvbnN0IHJlc291cmNlUGF0aCA9IHRoaXMuZnJvbnRlbmRNb2RlbFJlc291cmNlUGF0aChyZXNvdXJjZU1vZGVsTmFtZSwgcmVzb3VyY2VEZWZpbml0aW9uKVxuXG4gICAgICAgIGlmICh0aGlzLmZyb250ZW5kTW9kZWxSZXNvdXJjZU1hdGNoZXNDb250cm9sbGVyKHtjb250cm9sbGVyTmFtZSwgcmVzb3VyY2VQYXRofSkpIHtcbiAgICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgYmFja2VuZFByb2plY3QsXG4gICAgICAgICAgICBtb2RlbE5hbWU6IHJlc291cmNlTW9kZWxOYW1lLFxuICAgICAgICAgICAgcmVzb3VyY2VDbGFzcyxcbiAgICAgICAgICAgIHJlc291cmNlQ29uZmlndXJhdGlvblxuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cblxuICAgIHJldHVybiBudWxsXG4gIH1cblxuICAvKipcbiAgICogQHBhcmFtIHtvYmplY3R9IGFyZ3MgLSBBcmd1bWVudHMuXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi9jb25maWd1cmF0aW9uLXR5cGVzLmpzXCIpLkJhY2tlbmRQcm9qZWN0Q29uZmlndXJhdGlvbn0gYXJncy5iYWNrZW5kUHJvamVjdCAtIEJhY2tlbmQgcHJvamVjdCBjb25maWd1cmF0aW9uLlxuICAgKiBAcGFyYW0ge3N0cmluZ30gYXJncy5tb2RlbE5hbWUgLSBNb2RlbCBuYW1lLlxuICAgKiBAcmV0dXJucyB7e2JhY2tlbmRQcm9qZWN0OiBpbXBvcnQoXCIuL2NvbmZpZ3VyYXRpb24tdHlwZXMuanNcIikuQmFja2VuZFByb2plY3RDb25maWd1cmF0aW9uLCBtb2RlbE5hbWU6IHN0cmluZywgcmVzb3VyY2VDbGFzczogaW1wb3J0KFwiLi9jb25maWd1cmF0aW9uLXR5cGVzLmpzXCIpLkZyb250ZW5kTW9kZWxSZXNvdXJjZUNsYXNzVHlwZSwgcmVzb3VyY2VDb25maWd1cmF0aW9uOiBpbXBvcnQoXCIuL2NvbmZpZ3VyYXRpb24tdHlwZXMuanNcIikuTm9ybWFsaXplZEZyb250ZW5kTW9kZWxSZXNvdXJjZUNvbmZpZ3VyYXRpb259IHwgbnVsbH0gLSBGcm9udGVuZCBtb2RlbCByZXNvdXJjZSBjb25maWd1cmF0aW9uIGZvciBtb2RlbCBuYW1lLlxuICAgKi9cbiAgZnJvbnRlbmRNb2RlbFJlc291cmNlQ29uZmlndXJhdGlvbkZvckJhY2tlbmRQcm9qZWN0TW9kZWxOYW1lKHtiYWNrZW5kUHJvamVjdCwgbW9kZWxOYW1lfSkge1xuICAgIGNvbnN0IHJlc291cmNlcyA9IGZyb250ZW5kTW9kZWxSZXNvdXJjZXNGb3JCYWNrZW5kUHJvamVjdChiYWNrZW5kUHJvamVjdClcbiAgICBjb25zdCByZXNvdXJjZURlZmluaXRpb24gPSByZXNvdXJjZXNbbW9kZWxOYW1lXVxuXG4gICAgaWYgKCFyZXNvdXJjZURlZmluaXRpb24pIHJldHVybiBudWxsXG5cbiAgICBjb25zdCByZXNvdXJjZUNvbmZpZ3VyYXRpb24gPSBmcm9udGVuZE1vZGVsUmVzb3VyY2VDb25maWd1cmF0aW9uRnJvbURlZmluaXRpb24ocmVzb3VyY2VEZWZpbml0aW9uKVxuICAgIGNvbnN0IHJlc291cmNlQ2xhc3MgPSBmcm9udGVuZE1vZGVsUmVzb3VyY2VDbGFzc0Zyb21EZWZpbml0aW9uKHJlc291cmNlRGVmaW5pdGlvbilcblxuICAgIGlmICghcmVzb3VyY2VDb25maWd1cmF0aW9uIHx8ICFyZXNvdXJjZUNsYXNzKSByZXR1cm4gbnVsbFxuXG4gICAgcmV0dXJuIHtcbiAgICAgIGJhY2tlbmRQcm9qZWN0LFxuICAgICAgbW9kZWxOYW1lLFxuICAgICAgcmVzb3VyY2VDbGFzcyxcbiAgICAgIHJlc291cmNlQ29uZmlndXJhdGlvblxuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBAcGFyYW0ge3R5cGVvZiBpbXBvcnQoXCIuL2RhdGFiYXNlL3JlY29yZC9pbmRleC5qc1wiKS5kZWZhdWx0fSBtb2RlbENsYXNzIC0gTW9kZWwgY2xhc3MuXG4gICAqIEByZXR1cm5zIHt7YmFja2VuZFByb2plY3Q6IGltcG9ydChcIi4vY29uZmlndXJhdGlvbi10eXBlcy5qc1wiKS5CYWNrZW5kUHJvamVjdENvbmZpZ3VyYXRpb24sIG1vZGVsTmFtZTogc3RyaW5nLCByZXNvdXJjZUNsYXNzOiBpbXBvcnQoXCIuL2NvbmZpZ3VyYXRpb24tdHlwZXMuanNcIikuRnJvbnRlbmRNb2RlbFJlc291cmNlQ2xhc3NUeXBlLCByZXNvdXJjZUNvbmZpZ3VyYXRpb246IGltcG9ydChcIi4vY29uZmlndXJhdGlvbi10eXBlcy5qc1wiKS5Ob3JtYWxpemVkRnJvbnRlbmRNb2RlbFJlc291cmNlQ29uZmlndXJhdGlvbn0gfCBudWxsfSAtIEZyb250ZW5kIG1vZGVsIHJlc291cmNlIGNvbmZpZ3VyYXRpb24gZm9yIG1vZGVsIGNsYXNzLlxuICAgKi9cbiAgZnJvbnRlbmRNb2RlbFJlc291cmNlQ29uZmlndXJhdGlvbkZvck1vZGVsQ2xhc3MobW9kZWxDbGFzcykge1xuICAgIGNvbnN0IGZyb250ZW5kTW9kZWxSZXNvdXJjZSA9IHRoaXMuZnJvbnRlbmRNb2RlbFJlc291cmNlQ29uZmlndXJhdGlvbigpXG5cbiAgICBpZiAoIWZyb250ZW5kTW9kZWxSZXNvdXJjZSkgcmV0dXJuIG51bGxcblxuICAgIHJldHVybiB0aGlzLmZyb250ZW5kTW9kZWxSZXNvdXJjZUNvbmZpZ3VyYXRpb25Gb3JCYWNrZW5kUHJvamVjdE1vZGVsTmFtZSh7XG4gICAgICBiYWNrZW5kUHJvamVjdDogZnJvbnRlbmRNb2RlbFJlc291cmNlLmJhY2tlbmRQcm9qZWN0LFxuICAgICAgbW9kZWxOYW1lOiBtb2RlbENsYXNzLmdldE1vZGVsTmFtZSgpXG4gICAgfSlcbiAgfVxuXG4gIC8qKlxuICAgKiBAcGFyYW0ge3ttb2RlbE5hbWU6IHN0cmluZywgcmVzb3VyY2VDbGFzczogaW1wb3J0KFwiLi9jb25maWd1cmF0aW9uLXR5cGVzLmpzXCIpLkZyb250ZW5kTW9kZWxSZXNvdXJjZUNsYXNzVHlwZX19IGZyb250ZW5kTW9kZWxSZXNvdXJjZSAtIEZyb250ZW5kIG1vZGVsIHJlc291cmNlIGNvbmZpZ3VyYXRpb24uXG4gICAqIEByZXR1cm5zIHt0eXBlb2YgaW1wb3J0KFwiLi9kYXRhYmFzZS9yZWNvcmQvaW5kZXguanNcIikuZGVmYXVsdCB8IG51bGx9IC0gQmFja2luZyByZWNvcmQgY2xhc3MsIHdoZW4gYXZhaWxhYmxlLlxuICAgKi9cbiAgZnJvbnRlbmRNb2RlbFJlc291cmNlTW9kZWxDbGFzcyhmcm9udGVuZE1vZGVsUmVzb3VyY2UpIHtcbiAgICBjb25zdCByZXNvdXJjZU1vZGVsQ2xhc3MgPSBmcm9udGVuZE1vZGVsUmVzb3VyY2UucmVzb3VyY2VDbGFzcy5Nb2RlbENsYXNzXG5cbiAgICBpZiAocmVzb3VyY2VNb2RlbENsYXNzKSByZXR1cm4gcmVzb3VyY2VNb2RlbENsYXNzXG5cbiAgICByZXR1cm4gdGhpcy5nZXRDb25maWd1cmF0aW9uKCkuZ2V0TW9kZWxDbGFzc2VzKClbZnJvbnRlbmRNb2RlbFJlc291cmNlLm1vZGVsTmFtZV0gfHwgbnVsbFxuICB9XG5cbiAgLyoqXG4gICAqIEByZXR1cm5zIHt0eXBlb2YgaW1wb3J0KFwiLi9kYXRhYmFzZS9yZWNvcmQvaW5kZXguanNcIikuZGVmYXVsdCB8IG51bGx9IC0gRnJvbnRlbmQgbW9kZWwgY2xhc3MgcmVzb2x2ZWQgZnJvbSBiYWNrZW5kIHByb2plY3QgY29uZmlndXJhdGlvbi5cbiAgICovXG4gIGZyb250ZW5kTW9kZWxDbGFzc0Zyb21Db25maWd1cmF0aW9uKCkge1xuICAgIGNvbnN0IGZyb250ZW5kTW9kZWxSZXNvdXJjZSA9IHRoaXMuZnJvbnRlbmRNb2RlbFJlc291cmNlQ29uZmlndXJhdGlvbigpXG5cbiAgICBpZiAoIWZyb250ZW5kTW9kZWxSZXNvdXJjZSkgcmV0dXJuIG51bGxcblxuICAgIGNvbnN0IHJlc291cmNlTW9kZWxDbGFzcyA9IHRoaXMuZnJvbnRlbmRNb2RlbFJlc291cmNlTW9kZWxDbGFzcyhmcm9udGVuZE1vZGVsUmVzb3VyY2UpXG5cbiAgICBpZiAocmVzb3VyY2VNb2RlbENsYXNzKSByZXR1cm4gcmVzb3VyY2VNb2RlbENsYXNzXG5cbiAgICBjb25zdCBtb2RlbENsYXNzZXMgPSB0aGlzLmdldENvbmZpZ3VyYXRpb24oKS5nZXRNb2RlbENsYXNzZXMoKVxuICAgIGNvbnN0IG1vZGVsQ2xhc3MgPSBtb2RlbENsYXNzZXNbZnJvbnRlbmRNb2RlbFJlc291cmNlLm1vZGVsTmFtZV1cblxuICAgIGlmICghbW9kZWxDbGFzcykge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKGBGcm9udGVuZCBtb2RlbCAnJHtmcm9udGVuZE1vZGVsUmVzb3VyY2UubW9kZWxOYW1lfScgaXMgY29uZmlndXJlZCBmb3IgJyR7dGhpcy5mcm9udGVuZE1vZGVsUGFyYW1zKCkuY29udHJvbGxlcn0nLCBidXQgbm8gbW9kZWwgY2xhc3Mgd2FzIHJlZ2lzdGVyZWQuIFJlZ2lzdGVyZWQgbW9kZWxzOiAke09iamVjdC5rZXlzKG1vZGVsQ2xhc3Nlcykuam9pbihcIiwgXCIpfWApXG4gICAgfVxuXG4gICAgcmV0dXJuIG1vZGVsQ2xhc3NcbiAgfVxuXG4gIC8qKlxuICAgKiBFbnN1cmVzIHRoZSBmcm9udGVuZCBtb2RlbCBjbGFzcyBhbmQgcmVxdWVzdGVkIHByZWxvYWQgdGFyZ2V0IGNsYXNzZXMgYXJlIGluaXRpYWxpemVkLlxuICAgKiBUaGlzIGhhbmRsZXMgdGhlIGNhc2Ugd2hlcmUgbW9kZWwgaW5pdGlhbGl6YXRpb24gd2FzIHNraXBwZWQgYXQgc3RhcnR1cCAoZS5nLiwgYnJvd3NlciB0ZXN0cykuXG4gICAqIEByZXR1cm5zIHtQcm9taXNlPHZvaWQ+fSAtIFJlc29sdmVzIHdoZW4gdGhlIG1vZGVsIGNsYXNzIGlzIHJlYWR5LlxuICAgKi9cbiAgYXN5bmMgZW5zdXJlRnJvbnRlbmRNb2RlbENsYXNzSW5pdGlhbGl6ZWQoKSB7XG4gICAgY29uc3QgZnJvbnRlbmRNb2RlbFJlc291cmNlID0gdGhpcy5mcm9udGVuZE1vZGVsUmVzb3VyY2VDb25maWd1cmF0aW9uKClcbiAgICBjb25zdCBtb2RlbENsYXNzID0gdGhpcy5mcm9udGVuZE1vZGVsQ2xhc3NGcm9tQ29uZmlndXJhdGlvbigpXG5cbiAgICBpZiAoIW1vZGVsQ2xhc3MpIHJldHVyblxuXG4gICAgYXdhaXQgdGhpcy5lbnN1cmVGcm9udGVuZE1vZGVsUmVjb3JkQ2xhc3NJbml0aWFsaXplZChtb2RlbENsYXNzKVxuXG4gICAgaWYgKCFmcm9udGVuZE1vZGVsUmVzb3VyY2UpIHJldHVyblxuXG4gICAgYXdhaXQgdGhpcy5lbnN1cmVGcm9udGVuZE1vZGVsUHJlbG9hZENsYXNzZXNJbml0aWFsaXplZCh7XG4gICAgICBiYWNrZW5kUHJvamVjdDogZnJvbnRlbmRNb2RlbFJlc291cmNlLmJhY2tlbmRQcm9qZWN0LFxuICAgICAgbW9kZWxDbGFzcyxcbiAgICAgIHByZWxvYWQ6IHRoaXMuZnJvbnRlbmRNb2RlbFByZWxvYWQoKVxuICAgIH0pXG4gIH1cblxuICAvKipcbiAgICogQHBhcmFtIHt0eXBlb2YgaW1wb3J0KFwiLi9kYXRhYmFzZS9yZWNvcmQvaW5kZXguanNcIikuZGVmYXVsdH0gbW9kZWxDbGFzcyAtIE1vZGVsIGNsYXNzIHRvIGluaXRpYWxpemUuXG4gICAqIEByZXR1cm5zIHtQcm9taXNlPHZvaWQ+fSAtIFJlc29sdmVzIHdoZW4gdGhlIG1vZGVsIGNsYXNzIGlzIHJlYWR5LlxuICAgKi9cbiAgYXN5bmMgZW5zdXJlRnJvbnRlbmRNb2RlbFJlY29yZENsYXNzSW5pdGlhbGl6ZWQobW9kZWxDbGFzcykge1xuICAgIGlmICghbW9kZWxDbGFzcyB8fCBtb2RlbENsYXNzLmlzSW5pdGlhbGl6ZWQoKSkgcmV0dXJuXG5cbiAgICBjb25zdCBjb25maWd1cmF0aW9uID0gdGhpcy5nZXRDb25maWd1cmF0aW9uKClcblxuICAgIGlmICh0eXBlb2YgbW9kZWxDbGFzcy5lbnN1cmVJbml0aWFsaXplZCA9PT0gXCJmdW5jdGlvblwiKSB7XG4gICAgICBhd2FpdCBtb2RlbENsYXNzLmVuc3VyZUluaXRpYWxpemVkKHtjb25maWd1cmF0aW9ufSlcbiAgICB9IGVsc2UgaWYgKHR5cGVvZiBtb2RlbENsYXNzLmluaXRpYWxpemVSZWNvcmQgPT09IFwiZnVuY3Rpb25cIikge1xuICAgICAgYXdhaXQgbW9kZWxDbGFzcy5pbml0aWFsaXplUmVjb3JkKHtjb25maWd1cmF0aW9ufSlcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogQHBhcmFtIHtvYmplY3R9IGFyZ3MgLSBBcmd1bWVudHMuXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi9jb25maWd1cmF0aW9uLXR5cGVzLmpzXCIpLkJhY2tlbmRQcm9qZWN0Q29uZmlndXJhdGlvbn0gYXJncy5iYWNrZW5kUHJvamVjdCAtIEJhY2tlbmQgcHJvamVjdCBjb25maWd1cmF0aW9uLlxuICAgKiBAcGFyYW0ge3R5cGVvZiBpbXBvcnQoXCIuL2RhdGFiYXNlL3JlY29yZC9pbmRleC5qc1wiKS5kZWZhdWx0fSBhcmdzLm1vZGVsQ2xhc3MgLSBNb2RlbCBjbGFzcyB3aG9zZSBwcmVsb2FkIHRyZWUgaXMgYmVpbmcgcmVzb2x2ZWQuXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi9kYXRhYmFzZS9xdWVyeS9pbmRleC5qc1wiKS5OZXN0ZWRQcmVsb2FkUmVjb3JkIHwgbnVsbH0gYXJncy5wcmVsb2FkIC0gTm9ybWFsaXplZCBwcmVsb2FkIHRyZWUuXG4gICAqIEByZXR1cm5zIHtQcm9taXNlPHZvaWQ+fSAtIFJlc29sdmVzIHdoZW4gcHJlbG9hZCB0YXJnZXQgY2xhc3NlcyBhcmUgaW5pdGlhbGl6ZWQuXG4gICAqL1xuICBhc3luYyBlbnN1cmVGcm9udGVuZE1vZGVsUHJlbG9hZENsYXNzZXNJbml0aWFsaXplZCh7YmFja2VuZFByb2plY3QsIG1vZGVsQ2xhc3MsIHByZWxvYWR9KSB7XG4gICAgaWYgKCFwcmVsb2FkKSByZXR1cm5cblxuICAgIGZvciAoY29uc3QgW3JlbGF0aW9uc2hpcE5hbWUsIHJlbGF0aW9uc2hpcFByZWxvYWRdIG9mIE9iamVjdC5lbnRyaWVzKHByZWxvYWQpKSB7XG4gICAgICBpZiAocmVsYXRpb25zaGlwUHJlbG9hZCA9PT0gZmFsc2UpIGNvbnRpbnVlXG5cbiAgICAgIGNvbnN0IHJlbGF0aW9uc2hpcCA9IG1vZGVsQ2xhc3MuZ2V0UmVsYXRpb25zaGlwQnlOYW1lKHJlbGF0aW9uc2hpcE5hbWUpXG4gICAgICBjb25zdCB0YXJnZXRNb2RlbENsYXNzID0gYXdhaXQgdGhpcy5lbnN1cmVGcm9udGVuZE1vZGVsUmVsYXRpb25zaGlwVGFyZ2V0Q2xhc3NJbml0aWFsaXplZCh7XG4gICAgICAgIGJhY2tlbmRQcm9qZWN0LFxuICAgICAgICByZWxhdGlvbnNoaXBcbiAgICAgIH0pXG5cbiAgICAgIGlmICghdGFyZ2V0TW9kZWxDbGFzcyB8fCAhaXNQbGFpbk9iamVjdChyZWxhdGlvbnNoaXBQcmVsb2FkKSkgY29udGludWVcblxuICAgICAgYXdhaXQgdGhpcy5lbnN1cmVGcm9udGVuZE1vZGVsUHJlbG9hZENsYXNzZXNJbml0aWFsaXplZCh7XG4gICAgICAgIGJhY2tlbmRQcm9qZWN0LFxuICAgICAgICBtb2RlbENsYXNzOiB0YXJnZXRNb2RlbENsYXNzLFxuICAgICAgICBwcmVsb2FkOiAvKiogQHR5cGUge2ltcG9ydChcIi4vZGF0YWJhc2UvcXVlcnkvaW5kZXguanNcIikuTmVzdGVkUHJlbG9hZFJlY29yZH0gKi8gKHJlbGF0aW9uc2hpcFByZWxvYWQpXG4gICAgICB9KVxuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBAcGFyYW0ge29iamVjdH0gYXJncyAtIEFyZ3VtZW50cy5cbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuL2NvbmZpZ3VyYXRpb24tdHlwZXMuanNcIikuQmFja2VuZFByb2plY3RDb25maWd1cmF0aW9ufSBhcmdzLmJhY2tlbmRQcm9qZWN0IC0gQmFja2VuZCBwcm9qZWN0IGNvbmZpZ3VyYXRpb24uXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi9kYXRhYmFzZS9yZWNvcmQvcmVsYXRpb25zaGlwcy9iYXNlLmpzXCIpLmRlZmF1bHR9IGFyZ3MucmVsYXRpb25zaGlwIC0gUmVsYXRpb25zaGlwIGRlZmluaXRpb24uXG4gICAqIEByZXR1cm5zIHtQcm9taXNlPHR5cGVvZiBpbXBvcnQoXCIuL2RhdGFiYXNlL3JlY29yZC9pbmRleC5qc1wiKS5kZWZhdWx0IHwgbnVsbD59IC0gVGFyZ2V0IG1vZGVsIGNsYXNzLCB3aGVuIGF2YWlsYWJsZS5cbiAgICovXG4gIGFzeW5jIGVuc3VyZUZyb250ZW5kTW9kZWxSZWxhdGlvbnNoaXBUYXJnZXRDbGFzc0luaXRpYWxpemVkKHtiYWNrZW5kUHJvamVjdCwgcmVsYXRpb25zaGlwfSkge1xuICAgIGlmIChyZWxhdGlvbnNoaXAudGhyb3VnaCkge1xuICAgICAgY29uc3QgdGhyb3VnaFJlbGF0aW9uc2hpcCA9IHJlbGF0aW9uc2hpcC5nZXRNb2RlbENsYXNzKCkuZ2V0UmVsYXRpb25zaGlwQnlOYW1lKHJlbGF0aW9uc2hpcC50aHJvdWdoKVxuICAgICAgYXdhaXQgdGhpcy5lbnN1cmVGcm9udGVuZE1vZGVsUmVsYXRpb25zaGlwVGFyZ2V0Q2xhc3NJbml0aWFsaXplZCh7XG4gICAgICAgIGJhY2tlbmRQcm9qZWN0LFxuICAgICAgICByZWxhdGlvbnNoaXA6IHRocm91Z2hSZWxhdGlvbnNoaXBcbiAgICAgIH0pXG4gICAgfVxuXG4gICAgY29uc3QgdGFyZ2V0TW9kZWxDbGFzcyA9IHRoaXMuZnJvbnRlbmRNb2RlbFJlbGF0aW9uc2hpcFRhcmdldE1vZGVsQ2xhc3Moe1xuICAgICAgYmFja2VuZFByb2plY3QsXG4gICAgICByZWxhdGlvbnNoaXBcbiAgICB9KVxuXG4gICAgaWYgKCF0YXJnZXRNb2RlbENsYXNzKSByZXR1cm4gbnVsbFxuXG4gICAgYXdhaXQgdGhpcy5lbnN1cmVGcm9udGVuZE1vZGVsUmVjb3JkQ2xhc3NJbml0aWFsaXplZCh0YXJnZXRNb2RlbENsYXNzKVxuXG4gICAgcmV0dXJuIHRhcmdldE1vZGVsQ2xhc3NcbiAgfVxuXG4gIC8qKlxuICAgKiBAcGFyYW0ge29iamVjdH0gYXJncyAtIEFyZ3VtZW50cy5cbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuL2NvbmZpZ3VyYXRpb24tdHlwZXMuanNcIikuQmFja2VuZFByb2plY3RDb25maWd1cmF0aW9ufSBhcmdzLmJhY2tlbmRQcm9qZWN0IC0gQmFja2VuZCBwcm9qZWN0IGNvbmZpZ3VyYXRpb24uXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi9kYXRhYmFzZS9yZWNvcmQvcmVsYXRpb25zaGlwcy9iYXNlLmpzXCIpLmRlZmF1bHR9IGFyZ3MucmVsYXRpb25zaGlwIC0gUmVsYXRpb25zaGlwIGRlZmluaXRpb24uXG4gICAqIEByZXR1cm5zIHt0eXBlb2YgaW1wb3J0KFwiLi9kYXRhYmFzZS9yZWNvcmQvaW5kZXguanNcIikuZGVmYXVsdCB8IG51bGx9IC0gVGFyZ2V0IG1vZGVsIGNsYXNzLCB3aGVuIGF2YWlsYWJsZS5cbiAgICovXG4gIGZyb250ZW5kTW9kZWxSZWxhdGlvbnNoaXBUYXJnZXRNb2RlbENsYXNzKHtiYWNrZW5kUHJvamVjdCwgcmVsYXRpb25zaGlwfSkge1xuICAgIGlmIChyZWxhdGlvbnNoaXAuZ2V0UG9seW1vcnBoaWMoKSAmJiByZWxhdGlvbnNoaXAuZ2V0VHlwZSgpID09PSBcImJlbG9uZ3NUb1wiKSByZXR1cm4gbnVsbFxuXG4gICAgaWYgKHJlbGF0aW9uc2hpcC5rbGFzcykgcmV0dXJuIHJlbGF0aW9uc2hpcC5rbGFzc1xuXG4gICAgaWYgKHJlbGF0aW9uc2hpcC5jbGFzc05hbWUpIHtcbiAgICAgIGNvbnN0IGZyb250ZW5kTW9kZWxSZXNvdXJjZSA9IHRoaXMuZnJvbnRlbmRNb2RlbFJlc291cmNlQ29uZmlndXJhdGlvbkZvckJhY2tlbmRQcm9qZWN0TW9kZWxOYW1lKHtcbiAgICAgICAgYmFja2VuZFByb2plY3QsXG4gICAgICAgIG1vZGVsTmFtZTogcmVsYXRpb25zaGlwLmNsYXNzTmFtZVxuICAgICAgfSlcbiAgICAgIGNvbnN0IHJlc291cmNlTW9kZWxDbGFzcyA9IGZyb250ZW5kTW9kZWxSZXNvdXJjZSA/IHRoaXMuZnJvbnRlbmRNb2RlbFJlc291cmNlTW9kZWxDbGFzcyhmcm9udGVuZE1vZGVsUmVzb3VyY2UpIDogbnVsbFxuXG4gICAgICBpZiAocmVzb3VyY2VNb2RlbENsYXNzKSByZXR1cm4gcmVzb3VyY2VNb2RlbENsYXNzXG5cbiAgICAgIGNvbnN0IHJlZ2lzdGVyZWRNb2RlbENsYXNzID0gdGhpcy5nZXRDb25maWd1cmF0aW9uKCkuZ2V0TW9kZWxDbGFzc2VzKClbcmVsYXRpb25zaGlwLmNsYXNzTmFtZV1cblxuICAgICAgaWYgKHJlZ2lzdGVyZWRNb2RlbENsYXNzKSByZXR1cm4gcmVnaXN0ZXJlZE1vZGVsQ2xhc3NcbiAgICB9XG5cbiAgICBjb25zdCB0YXJnZXRNb2RlbENsYXNzID0gcmVsYXRpb25zaGlwLmdldFRhcmdldE1vZGVsQ2xhc3MoKVxuXG4gICAgcmV0dXJuIHRhcmdldE1vZGVsQ2xhc3MgfHwgbnVsbFxuICB9XG5cbiAgLyoqXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBtb2RlbE5hbWUgLSBNb2RlbCBjbGFzcyBuYW1lLlxuICAgKiBAcGFyYW0ge3Vua25vd259IHJlc291cmNlRGVmaW5pdGlvbiAtIFJlc291cmNlIGRlZmluaXRpb24uXG4gICAqIEByZXR1cm5zIHtzdHJpbmd9IC0gTm9ybWFsaXplZCByZXNvdXJjZSBwYXRoLlxuICAgKi9cbiAgZnJvbnRlbmRNb2RlbFJlc291cmNlUGF0aChtb2RlbE5hbWUsIHJlc291cmNlRGVmaW5pdGlvbikge1xuICAgIHJldHVybiBmcm9udGVuZE1vZGVsUmVzb3VyY2VQYXRoKG1vZGVsTmFtZSwgcmVzb3VyY2VEZWZpbml0aW9uKVxuICB9XG5cbiAgLyoqXG4gICAqIEBwYXJhbSB7b2JqZWN0fSBhcmdzIC0gQXJndW1lbnRzLlxuICAgKiBAcGFyYW0ge3N0cmluZ30gYXJncy5jb250cm9sbGVyTmFtZSAtIENvbnRyb2xsZXIgbmFtZSBmcm9tIHBhcmFtcy5cbiAgICogQHBhcmFtIHtzdHJpbmd9IGFyZ3MucmVzb3VyY2VQYXRoIC0gUmVzb3VyY2UgcGF0aCBmcm9tIGNvbmZpZ3VyYXRpb24uXG4gICAqIEByZXR1cm5zIHtib29sZWFufSAtIFdoZXRoZXIgcmVzb3VyY2UgcGF0aCBtYXRjaGVzIGN1cnJlbnQgY29udHJvbGxlci5cbiAgICovXG4gIGZyb250ZW5kTW9kZWxSZXNvdXJjZU1hdGNoZXNDb250cm9sbGVyKHtjb250cm9sbGVyTmFtZSwgcmVzb3VyY2VQYXRofSkge1xuICAgIGNvbnN0IG5vcm1hbGl6ZWRDb250cm9sbGVyID0gY29udHJvbGxlck5hbWUucmVwbGFjZSgvXlxcLyt8XFwvKyQvZywgXCJcIilcbiAgICBjb25zdCBub3JtYWxpemVkUmVzb3VyY2VQYXRoID0gcmVzb3VyY2VQYXRoLnJlcGxhY2UoL15cXC8rfFxcLyskL2csIFwiXCIpXG5cbiAgICBpZiAobm9ybWFsaXplZFJlc291cmNlUGF0aCA9PT0gbm9ybWFsaXplZENvbnRyb2xsZXIpIHJldHVybiB0cnVlXG5cbiAgICByZXR1cm4gbm9ybWFsaXplZFJlc291cmNlUGF0aC5lbmRzV2l0aChgLyR7bm9ybWFsaXplZENvbnRyb2xsZXJ9YClcbiAgfVxuXG4gIC8qKlxuICAgKiBAcmV0dXJucyB7RnJvbnRlbmRNb2RlbEJhc2VSZXNvdXJjZX0gLSBCYWNrZW5kIHJlc291cmNlIGluc3RhbmNlIGZvciBjdXJyZW50IGZyb250ZW5kLW1vZGVsIGFjdGlvbi5cbiAgICovXG4gIGZyb250ZW5kTW9kZWxSZXNvdXJjZUluc3RhbmNlKCkge1xuICAgIGNvbnN0IGZyb250ZW5kTW9kZWxSZXNvdXJjZSA9IHRoaXMuZnJvbnRlbmRNb2RlbFJlc291cmNlQ29uZmlndXJhdGlvbigpXG5cbiAgICBpZiAoIWZyb250ZW5kTW9kZWxSZXNvdXJjZSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKGBObyBmcm9udGVuZCBtb2RlbCByZXNvdXJjZSBjb25maWd1cmF0aW9uIGZvciBjb250cm9sbGVyICcke3RoaXMuZnJvbnRlbmRNb2RlbFBhcmFtcygpLmNvbnRyb2xsZXJ9J2ApXG4gICAgfVxuXG4gICAgY29uc3QgcmVzb3VyY2VBcmdzID0ge1xuICAgICAgYWJpbGl0eTogdGhpcy5jdXJyZW50QWJpbGl0eSgpLFxuICAgICAgY29udHJvbGxlcjogdGhpcyxcbiAgICAgIGNvbnRleHQ6IHtcbiAgICAgICAgLi4uKHRoaXMuY3VycmVudEFiaWxpdHkoKT8uZ2V0Q29udGV4dCgpIHx8IHt9KSxcbiAgICAgICAgcGFyYW1zOiB0aGlzLmZyb250ZW5kTW9kZWxQYXJhbXMoKSxcbiAgICAgICAgcmVxdWVzdDogdGhpcy5yZXF1ZXN0KClcbiAgICAgIH0sXG4gICAgICBsb2NhbHM6IHRoaXMuY3VycmVudEFiaWxpdHkoKT8uZ2V0TG9jYWxzKCkgfHwge30sXG4gICAgICBtb2RlbENsYXNzOiB0aGlzLmZyb250ZW5kTW9kZWxDbGFzcygpLFxuICAgICAgbW9kZWxOYW1lOiBmcm9udGVuZE1vZGVsUmVzb3VyY2UubW9kZWxOYW1lLFxuICAgICAgcGFyYW1zOiB0aGlzLmZyb250ZW5kTW9kZWxQYXJhbXMoKSxcbiAgICAgIHJlc291cmNlQ29uZmlndXJhdGlvbjogZnJvbnRlbmRNb2RlbFJlc291cmNlLnJlc291cmNlQ29uZmlndXJhdGlvblxuICAgIH1cblxuICAgIHJldHVybiBuZXcgZnJvbnRlbmRNb2RlbFJlc291cmNlLnJlc291cmNlQ2xhc3MocmVzb3VyY2VBcmdzKVxuICB9XG5cbiAgLyoqXG4gICAqIEByZXR1cm5zIHtzdHJpbmd9IC0gRnJvbnRlbmQgbW9kZWwgcHJpbWFyeSBrZXkuXG4gICAqL1xuICBmcm9udGVuZE1vZGVsUHJpbWFyeUtleSgpIHtcbiAgICByZXR1cm4gdGhpcy5mcm9udGVuZE1vZGVsQ2xhc3MoKS5wcmltYXJ5S2V5KClcbiAgfVxuXG4gIC8qKlxuICAgKiBAcGFyYW0ge1wiaW5kZXhcIiB8IFwiZmluZFwiIHwgXCJjcmVhdGVcIiB8IFwidXBkYXRlXCIgfCBcImRlc3Ryb3lcIiB8IFwiYXR0YWNoXCIgfCBcImRvd25sb2FkXCIgfCBcInVybFwifSBhY3Rpb24gLSBGcm9udGVuZCBhY3Rpb24uXG4gICAqIEByZXR1cm5zIHtzdHJpbmd9IC0gQWJpbGl0eSBhY3Rpb24gY29uZmlndXJlZCBmb3IgdGhlIGZyb250ZW5kIGFjdGlvbi5cbiAgICovXG4gIGZyb250ZW5kTW9kZWxBYmlsaXR5QWN0aW9uKGFjdGlvbikge1xuICAgIGNvbnN0IGZyb250ZW5kTW9kZWxSZXNvdXJjZSA9IHRoaXMuZnJvbnRlbmRNb2RlbFJlc291cmNlQ29uZmlndXJhdGlvbigpXG5cbiAgICBpZiAoIWZyb250ZW5kTW9kZWxSZXNvdXJjZSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKGBObyBmcm9udGVuZCBtb2RlbCByZXNvdXJjZSBjb25maWd1cmF0aW9uIGZvciBjb250cm9sbGVyICcke3RoaXMuZnJvbnRlbmRNb2RlbFBhcmFtcygpLmNvbnRyb2xsZXJ9J2ApXG4gICAgfVxuXG4gICAgY29uc3QgYWJpbGl0aWVzID0gZnJvbnRlbmRNb2RlbFJlc291cmNlLnJlc291cmNlQ29uZmlndXJhdGlvbi5hYmlsaXRpZXNcblxuICAgIGlmICghYWJpbGl0aWVzIHx8IHR5cGVvZiBhYmlsaXRpZXMgIT09IFwib2JqZWN0XCIpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihgUmVzb3VyY2UgJyR7ZnJvbnRlbmRNb2RlbFJlc291cmNlLm1vZGVsTmFtZX0nIG11c3QgZGVmaW5lIGFuICdhYmlsaXRpZXMnIG9iamVjdGApXG4gICAgfVxuXG4gICAgY29uc3QgYWJpbGl0eUtleSA9IGFjdGlvbiA9PT0gXCJhdHRhY2hcIlxuICAgICAgPyBcInVwZGF0ZVwiXG4gICAgICA6ICgoYWN0aW9uID09PSBcImRvd25sb2FkXCIgfHwgYWN0aW9uID09PSBcInVybFwiKSA/IFwiZmluZFwiIDogYWN0aW9uKVxuICAgIGNvbnN0IGFiaWxpdHlBY3Rpb24gPSBhYmlsaXRpZXNbYWJpbGl0eUtleV1cblxuICAgIGlmICh0eXBlb2YgYWJpbGl0eUFjdGlvbiAhPT0gXCJzdHJpbmdcIiB8fCBhYmlsaXR5QWN0aW9uLmxlbmd0aCA8IDEpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihgUmVzb3VyY2UgJyR7ZnJvbnRlbmRNb2RlbFJlc291cmNlLm1vZGVsTmFtZX0nIG11c3QgZGVmaW5lIGFiaWxpdGllcy4ke2FiaWxpdHlLZXl9YClcbiAgICB9XG5cbiAgICByZXR1cm4gYWJpbGl0eUFjdGlvblxuICB9XG5cbiAgLyoqXG4gICAqIEBwYXJhbSB7XCJpbmRleFwiIHwgXCJmaW5kXCIgfCBcImNyZWF0ZVwiIHwgXCJ1cGRhdGVcIiB8IFwiZGVzdHJveVwiIHwgXCJhdHRhY2hcIiB8IFwiZG93bmxvYWRcIiB8IFwidXJsXCJ9IGFjdGlvbiAtIEZyb250ZW5kIGFjdGlvbi5cbiAgICogQHJldHVybnMge2ltcG9ydChcIi4vZGF0YWJhc2UvcXVlcnkvbW9kZWwtY2xhc3MtcXVlcnkuanNcIikuZGVmYXVsdDxhbnk+fSAtIEF1dGhvcml6ZWQgcXVlcnkgZm9yIHRoZSBhY3Rpb24uXG4gICAqL1xuICBmcm9udGVuZE1vZGVsQXV0aG9yaXplZFF1ZXJ5KGFjdGlvbikge1xuICAgIGNvbnN0IGFiaWxpdHlBY3Rpb24gPSB0aGlzLmZyb250ZW5kTW9kZWxBYmlsaXR5QWN0aW9uKGFjdGlvbilcblxuICAgIHJldHVybiB0aGlzLmZyb250ZW5kTW9kZWxDbGFzcygpLmFjY2Vzc2libGVGb3IoYWJpbGl0eUFjdGlvbiwgdGhpcy5jdXJyZW50QWJpbGl0eSgpKVxuICB9XG5cbiAgLyoqXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi9kYXRhYmFzZS9yZWNvcmQvaW5kZXguanNcIikuZGVmYXVsdH0gbW9kZWwgLSBNb2RlbCBpbnN0YW5jZS5cbiAgICogQHJldHVybnMge3N0cmluZ30gLSBQcmltYXJ5IGtleSB2YWx1ZSBhcyBzdHJpbmcuXG4gICAqL1xuICBmcm9udGVuZE1vZGVsUHJpbWFyeUtleVZhbHVlKG1vZGVsKSB7XG4gICAgY29uc3QgY29sdW1uTmFtZSA9IHRoaXMuZnJvbnRlbmRNb2RlbFByaW1hcnlLZXkoKVxuICAgIGNvbnN0IGF0dHJpYnV0ZU5hbWVNYXAgPSBtb2RlbC5nZXRNb2RlbENsYXNzKCkuZ2V0Q29sdW1uTmFtZVRvQXR0cmlidXRlTmFtZU1hcCgpXG4gICAgY29uc3QgYXR0cmlidXRlTmFtZSA9IGF0dHJpYnV0ZU5hbWVNYXBbY29sdW1uTmFtZV0gfHwgY29sdW1uTmFtZVxuICAgIGNvbnN0IHZhbHVlID0gbW9kZWwucmVhZEF0dHJpYnV0ZShhdHRyaWJ1dGVOYW1lKVxuXG4gICAgcmV0dXJuIFN0cmluZyh2YWx1ZSlcbiAgfVxuXG4gIC8qKlxuICAgKiBAcGFyYW0ge29iamVjdH0gYXJncyAtIEFyZ3VtZW50cy5cbiAgICogQHBhcmFtIHtcImluZGV4XCIgfCBcImZpbmRcIiB8IFwiY3JlYXRlXCIgfCBcInVwZGF0ZVwiIHwgXCJkZXN0cm95XCIgfCBcImF0dGFjaFwiIHwgXCJkb3dubG9hZFwiIHwgXCJ1cmxcIn0gYXJncy5hY3Rpb24gLSBGcm9udGVuZCBhY3Rpb24uXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi9kYXRhYmFzZS9yZWNvcmQvaW5kZXguanNcIikuZGVmYXVsdFtdfSBhcmdzLm1vZGVscyAtIENhbmRpZGF0ZSBtb2RlbHMuXG4gICAqIEByZXR1cm5zIHtQcm9taXNlPGltcG9ydChcIi4vZGF0YWJhc2UvcmVjb3JkL2luZGV4LmpzXCIpLmRlZmF1bHRbXT59IC0gQXV0aG9yaXplZCBtb2RlbHMuXG4gICAqL1xuICBhc3luYyBmcm9udGVuZE1vZGVsRmlsdGVyQXV0aG9yaXplZE1vZGVscyh7YWN0aW9uLCBtb2RlbHN9KSB7XG4gICAgaWYgKG1vZGVscy5sZW5ndGggPT09IDApIHJldHVybiBtb2RlbHNcblxuICAgIGNvbnN0IHByaW1hcnlLZXkgPSB0aGlzLmZyb250ZW5kTW9kZWxQcmltYXJ5S2V5KClcbiAgICBjb25zdCBpZHMgPSBtb2RlbHMubWFwKChtb2RlbCkgPT4gdGhpcy5mcm9udGVuZE1vZGVsUHJpbWFyeUtleVZhbHVlKG1vZGVsKSlcbiAgICBjb25zdCBhdXRob3JpemVkUXVlcnkgPSB0aGlzLmZyb250ZW5kTW9kZWxBdXRob3JpemVkUXVlcnkoYWN0aW9uKS53aGVyZSh7W3ByaW1hcnlLZXldOiBpZHN9KVxuXG4gICAgY29uc3QgYXV0aG9yaXplZElkc1JhdyA9IGF3YWl0IGF1dGhvcml6ZWRRdWVyeS5wbHVjayhwcmltYXJ5S2V5KVxuXG4gICAgY29uc3QgYXV0aG9yaXplZElkcyA9IG5ldyBTZXQoYXV0aG9yaXplZElkc1Jhdy5tYXAoKGlkKSA9PiBTdHJpbmcoaWQpKSlcblxuICAgIHJldHVybiBtb2RlbHMuZmlsdGVyKChtb2RlbCkgPT4gYXV0aG9yaXplZElkcy5oYXModGhpcy5mcm9udGVuZE1vZGVsUHJpbWFyeUtleVZhbHVlKG1vZGVsKSkpXG4gIH1cblxuICAvKipcbiAgICogQHBhcmFtIHtcImluZGV4XCIgfCBcImZpbmRcIiB8IFwiY3JlYXRlXCIgfCBcInVwZGF0ZVwiIHwgXCJkZXN0cm95XCIgfCBcImF0dGFjaFwiIHwgXCJkb3dubG9hZFwiIHwgXCJ1cmxcIn0gYWN0aW9uIC0gRnJvbnRlbmQgYWN0aW9uLlxuICAgKiBAcmV0dXJucyB7UHJvbWlzZTxib29sZWFuPn0gLSBXaGV0aGVyIGFjdGlvbiBzaG91bGQgY29udGludWUuXG4gICAqL1xuICBhc3luYyBydW5Gcm9udGVuZE1vZGVsQmVmb3JlQWN0aW9uKGFjdGlvbikge1xuICAgIGNvbnN0IHJlc3VsdCA9IGF3YWl0IHRoaXMuZnJvbnRlbmRNb2RlbFJlc291cmNlSW5zdGFuY2UoKS5iZWZvcmVBY3Rpb24oYWN0aW9uKVxuXG4gICAgcmV0dXJuIHJlc3VsdCAhPT0gZmFsc2VcbiAgfVxuXG4gIC8qKlxuICAgKiBAcGFyYW0ge1wiZmluZFwiIHwgXCJ1cGRhdGVcIiB8IFwiZGVzdHJveVwiIHwgXCJhdHRhY2hcIiB8IFwiZG93bmxvYWRcIiB8IFwidXJsXCJ9IGFjdGlvbiAtIEZyb250ZW5kIGFjdGlvbi5cbiAgICogQHBhcmFtIHtzdHJpbmcgfCBudW1iZXJ9IGlkIC0gUmVjb3JkIGlkLlxuICAgKiBAcmV0dXJucyB7UHJvbWlzZTxpbXBvcnQoXCIuL2RhdGFiYXNlL3JlY29yZC9pbmRleC5qc1wiKS5kZWZhdWx0IHwgbnVsbD59IC0gTG9jYXRlZCBtb2RlbCByZWNvcmQuXG4gICAqL1xuICBhc3luYyBmcm9udGVuZE1vZGVsRmluZFJlY29yZChhY3Rpb24sIGlkKSB7XG4gICAgY29uc3QgbW9kZWwgPSBhd2FpdCB0aGlzLmZyb250ZW5kTW9kZWxSZXNvdXJjZUluc3RhbmNlKCkuZmluZChhY3Rpb24sIGlkKVxuXG4gICAgaWYgKCFtb2RlbCkgcmV0dXJuIG51bGxcblxuICAgIGNvbnN0IGF1dGhvcml6ZWRNb2RlbHMgPSBhd2FpdCB0aGlzLmZyb250ZW5kTW9kZWxGaWx0ZXJBdXRob3JpemVkTW9kZWxzKHthY3Rpb24sIG1vZGVsczogW21vZGVsXX0pXG5cbiAgICByZXR1cm4gYXV0aG9yaXplZE1vZGVsc1swXSB8fCBudWxsXG4gIH1cblxuICAvKipcbiAgICogQHBhcmFtIHtSZWNvcmQ8c3RyaW5nLCBhbnk+fSBhdHRyaWJ1dGVzIC0gQ3JlYXRlIGF0dHJpYnV0ZXMuXG4gICAqIEBwYXJhbSB7UmVjb3JkPHN0cmluZywgYW55PiB8IG51bGx9IFtuZXN0ZWRBdHRyaWJ1dGVzXSAtIE9wdGlvbmFsIG5lc3RlZC1hdHRyaWJ1dGUgcGF5bG9hZCBmb3IgY2FzY2FkaW5nIHdyaXRlcy5cbiAgICogQHJldHVybnMge1Byb21pc2U8aW1wb3J0KFwiLi9kYXRhYmFzZS9yZWNvcmQvaW5kZXguanNcIikuZGVmYXVsdCB8IG51bGw+fSAtIENyZWF0ZWQgbW9kZWwgd2hlbiBhdXRob3JpemVkLlxuICAgKi9cbiAgYXN5bmMgZnJvbnRlbmRNb2RlbENyZWF0ZVJlY29yZChhdHRyaWJ1dGVzLCBuZXN0ZWRBdHRyaWJ1dGVzID0gbnVsbCkge1xuICAgIGNvbnN0IHJlc291cmNlID0gdGhpcy5mcm9udGVuZE1vZGVsUmVzb3VyY2VJbnN0YW5jZSgpXG4gICAgY29uc3QgbW9kZWwgPSBhd2FpdCByZXNvdXJjZS5jcmVhdGUoYXR0cmlidXRlcywge25lc3RlZEF0dHJpYnV0ZXMsIGNvbnRyb2xsZXI6IHRoaXN9KVxuXG4gICAgY29uc3QgYXV0aG9yaXplZE1vZGVscyA9IGF3YWl0IHRoaXMuZnJvbnRlbmRNb2RlbEZpbHRlckF1dGhvcml6ZWRNb2RlbHMoe2FjdGlvbjogXCJjcmVhdGVcIiwgbW9kZWxzOiBbbW9kZWxdfSlcblxuICAgIGlmIChhdXRob3JpemVkTW9kZWxzLmxlbmd0aCA+IDApIHtcbiAgICAgIHJldHVybiBhdXRob3JpemVkTW9kZWxzWzBdXG4gICAgfVxuXG4gICAgYXdhaXQgcmVzb3VyY2UuaGFuZGxlVW5hdXRob3JpemVkQ3JlYXRlZE1vZGVsKG1vZGVsKVxuXG4gICAgcmV0dXJuIG51bGxcbiAgfVxuXG4gIC8qKlxuICAgKiBAcmV0dXJucyB7UHJvbWlzZTxpbXBvcnQoXCIuL2RhdGFiYXNlL3JlY29yZC9pbmRleC5qc1wiKS5kZWZhdWx0W10+fSAtIEZyb250ZW5kIG1vZGVsIHJlY29yZHMuXG4gICAqL1xuICBhc3luYyBmcm9udGVuZE1vZGVsUmVjb3JkcygpIHtcbiAgICBjb25zdCBtb2RlbHMgPSBhd2FpdCB0aGlzLmZyb250ZW5kTW9kZWxSZXNvdXJjZUluc3RhbmNlKCkucmVjb3JkcygpXG5cbiAgICByZXR1cm4gYXdhaXQgdGhpcy5mcm9udGVuZE1vZGVsRmlsdGVyQXV0aG9yaXplZE1vZGVscyh7YWN0aW9uOiBcImluZGV4XCIsIG1vZGVsc30pXG4gIH1cblxuICAvKipcbiAgICogQHJldHVybnMge2ltcG9ydChcIi4vZGF0YWJhc2UvcXVlcnkvaW5kZXguanNcIikuTmVzdGVkUHJlbG9hZFJlY29yZCB8IG51bGx9IC0gRnJvbnRlbmQgcHJlbG9hZCBkYXRhLlxuICAgKi9cbiAgZnJvbnRlbmRNb2RlbFByZWxvYWQoKSB7XG4gICAgcmV0dXJuIG5vcm1hbGl6ZUZyb250ZW5kTW9kZWxQcmVsb2FkKHRoaXMuZnJvbnRlbmRNb2RlbFBhcmFtcygpLnByZWxvYWQpXG4gIH1cblxuICAvKipcbiAgICogQHJldHVybnMge1JlY29yZDxzdHJpbmcsIHN0cmluZ1tdPiB8IG51bGx9IC0gRnJvbnRlbmQgc2VsZWN0IGRhdGEuXG4gICAqL1xuICBmcm9udGVuZE1vZGVsU2VsZWN0KCkge1xuICAgIHJldHVybiBub3JtYWxpemVGcm9udGVuZE1vZGVsU2VsZWN0KHRoaXMuZnJvbnRlbmRNb2RlbFBhcmFtcygpLnNlbGVjdCwgdGhpcy5mcm9udGVuZE1vZGVsQ2xhc3MoKS5nZXRNb2RlbE5hbWUoKSlcbiAgfVxuXG4gIC8qKlxuICAgKiBAcmV0dXJucyB7UmVjb3JkPHN0cmluZywgc3RyaW5nW10+IHwgbnVsbH0gLSBGcm9udGVuZCBleHRyYS1zZWxlY3QgZGF0YSAoZGVmYXVsdHMgcGx1cyB0aGVzZSksIGtleWVkIGJ5IG1vZGVsIG5hbWUuXG4gICAqL1xuICBmcm9udGVuZE1vZGVsU2VsZWN0c0V4dHJhKCkge1xuICAgIHJldHVybiBub3JtYWxpemVGcm9udGVuZE1vZGVsU2VsZWN0KHRoaXMuZnJvbnRlbmRNb2RlbFBhcmFtcygpLnNlbGVjdHNFeHRyYSwgdGhpcy5mcm9udGVuZE1vZGVsQ2xhc3MoKS5nZXRNb2RlbE5hbWUoKSlcbiAgfVxuXG4gIC8qKlxuICAgKiBAcmV0dXJucyB7RnJvbnRlbmRNb2RlbFNlYXJjaFtdfSAtIEZyb250ZW5kIHNlYXJjaCBmaWx0ZXJzLlxuICAgKi9cbiAgZnJvbnRlbmRNb2RlbFNlYXJjaGVzKCkge1xuICAgIHJldHVybiBub3JtYWxpemVGcm9udGVuZE1vZGVsU2VhcmNoZXModGhpcy5mcm9udGVuZE1vZGVsUGFyYW1zKCkuc2VhcmNoZXMpXG4gIH1cblxuICAvKipcbiAgICogQHJldHVybnMge1JlY29yZDxzdHJpbmcsIGFueT4gfCBudWxsfSAtIEZyb250ZW5kIHdoZXJlIGZpbHRlcnMuXG4gICAqL1xuICBmcm9udGVuZE1vZGVsV2hlcmUoKSB7XG4gICAgcmV0dXJuIG5vcm1hbGl6ZUZyb250ZW5kTW9kZWxXaGVyZSh0aGlzLmZyb250ZW5kTW9kZWxQYXJhbXMoKS53aGVyZSlcbiAgfVxuXG4gIC8qKiBAcmV0dXJucyB7UmVjb3JkPHN0cmluZywgYW55PiB8IG51bGx9IC0gRnJvbnRlbmQgUmFuc2FjayBmaWx0ZXJzLiAqL1xuICBmcm9udGVuZE1vZGVsUmFuc2FjaygpIHtcbiAgICByZXR1cm4gbm9ybWFsaXplRnJvbnRlbmRNb2RlbFJhbnNhY2sodGhpcy5mcm9udGVuZE1vZGVsUGFyYW1zKCkucmFuc2FjaylcbiAgfVxuXG4gIC8qKiBAcmV0dXJucyB7UmVjb3JkPHN0cmluZywgYW55PiB8IG51bGx9IC0gRnJvbnRlbmQgam9pbnMgZGVzY3JpcHRvcnMuICovXG4gIGZyb250ZW5kTW9kZWxKb2lucygpIHtcbiAgICByZXR1cm4gbm9ybWFsaXplRnJvbnRlbmRNb2RlbEpvaW5zKHRoaXMuZnJvbnRlbmRNb2RlbFBhcmFtcygpLmpvaW5zKVxuICB9XG5cbiAgLyoqIEByZXR1cm5zIHtGcm9udGVuZE1vZGVsU29ydFtdfSAtIEZyb250ZW5kIHNvcnQgZGVmaW5pdGlvbnMuICovXG4gIGZyb250ZW5kTW9kZWxTb3J0KCkge1xuICAgIHJldHVybiBub3JtYWxpemVGcm9udGVuZE1vZGVsU29ydCh0aGlzLmZyb250ZW5kTW9kZWxQYXJhbXMoKS5zb3J0KVxuICB9XG5cbiAgLyoqIEByZXR1cm5zIHtGcm9udGVuZE1vZGVsR3JvdXBbXX0gLSBGcm9udGVuZCBncm91cCBkZWZpbml0aW9ucy4gKi9cbiAgZnJvbnRlbmRNb2RlbEdyb3VwKCkge1xuICAgIHJldHVybiBub3JtYWxpemVGcm9udGVuZE1vZGVsR3JvdXAodGhpcy5mcm9udGVuZE1vZGVsUGFyYW1zKCkuZ3JvdXApXG4gIH1cblxuICAvKiogQHJldHVybnMge0Zyb250ZW5kTW9kZWxQYWdpbmF0aW9ufSAtIEZyb250ZW5kIHBhZ2luYXRpb24gcGFyYW1zLiAqL1xuICBmcm9udGVuZE1vZGVsUGFnaW5hdGlvbigpIHtcbiAgICBjb25zdCBwYXJhbXMgPSB0aGlzLmZyb250ZW5kTW9kZWxQYXJhbXMoKVxuXG4gICAgcmV0dXJuIG5vcm1hbGl6ZUZyb250ZW5kTW9kZWxQYWdpbmF0aW9uKHtcbiAgICAgIGxpbWl0OiBwYXJhbXMubGltaXQsXG4gICAgICBvZmZzZXQ6IHBhcmFtcy5vZmZzZXQsXG4gICAgICBwYWdlOiBwYXJhbXMucGFnZSxcbiAgICAgIHBlclBhZ2U6IHBhcmFtcy5wZXJQYWdlXG4gICAgfSlcbiAgfVxuXG4gIC8qKiBAcmV0dXJucyB7Ym9vbGVhbiB8IG51bGx9IC0gRnJvbnRlbmQgZGlzdGluY3QgZmxhZyB3aGVuIHByb3ZpZGVkLiAqL1xuICBmcm9udGVuZE1vZGVsRGlzdGluY3QoKSB7XG4gICAgcmV0dXJuIG5vcm1hbGl6ZUZyb250ZW5kTW9kZWxEaXN0aW5jdCh0aGlzLmZyb250ZW5kTW9kZWxQYXJhbXMoKS5kaXN0aW5jdClcbiAgfVxuXG4gIC8qKiBAcmV0dXJucyB7RnJvbnRlbmRNb2RlbFBsdWNrW119IC0gRnJvbnRlbmQgcGx1Y2sgZGVmaW5pdGlvbnMuICovXG4gIGZyb250ZW5kTW9kZWxQbHVjaygpIHtcbiAgICByZXR1cm4gbm9ybWFsaXplRnJvbnRlbmRNb2RlbFBsdWNrKHRoaXMuZnJvbnRlbmRNb2RlbFBhcmFtcygpLnBsdWNrKVxuICB9XG5cbiAgLyoqIEByZXR1cm5zIHtib29sZWFufSAtIFdoZXRoZXIgdGhlIHJlcXVlc3QgYXNrcyBmb3IgYW4gYWdncmVnYXRlIGNvdW50LiAqL1xuICBmcm9udGVuZE1vZGVsQ291bnRSZXF1ZXN0ZWQoKSB7XG4gICAgcmV0dXJuIHRoaXMuZnJvbnRlbmRNb2RlbFBhcmFtcygpLmNvdW50ID09PSB0cnVlXG4gIH1cblxuICAvKipcbiAgICogQHJldHVybnMge0FycmF5PHthdHRyaWJ1dGVOYW1lOiBzdHJpbmcsIHJlbGF0aW9uc2hpcE5hbWU6IHN0cmluZywgd2hlcmU/OiBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPn0+fVxuICAgKiAgIEZyb250ZW5kIHdpdGhDb3VudCBlbnRyaWVzLiBFbXB0eSBhcnJheSB3aGVuIG5vdCByZXF1ZXN0ZWQuXG4gICAqL1xuICBmcm9udGVuZE1vZGVsV2l0aENvdW50KCkge1xuICAgIGNvbnN0IHJhdyA9IHRoaXMuZnJvbnRlbmRNb2RlbFBhcmFtcygpLndpdGhDb3VudFxuXG4gICAgaWYgKCFBcnJheS5pc0FycmF5KHJhdykpIHJldHVybiBbXVxuXG4gICAgLyoqIEB0eXBlIHtBcnJheTx7YXR0cmlidXRlTmFtZTogc3RyaW5nLCByZWxhdGlvbnNoaXBOYW1lOiBzdHJpbmcsIHdoZXJlPzogUmVjb3JkPHN0cmluZywgdW5rbm93bj59Pn0gKi9cbiAgICBjb25zdCBlbnRyaWVzID0gW11cblxuICAgIGZvciAoY29uc3QgZW50cnkgb2YgcmF3KSB7XG4gICAgICBpZiAoIWVudHJ5IHx8IHR5cGVvZiBlbnRyeSAhPT0gXCJvYmplY3RcIikgY29udGludWVcbiAgICAgIGlmICh0eXBlb2YgZW50cnkuYXR0cmlidXRlTmFtZSAhPT0gXCJzdHJpbmdcIiB8fCBlbnRyeS5hdHRyaWJ1dGVOYW1lLmxlbmd0aCA9PT0gMCkgY29udGludWVcbiAgICAgIGlmICh0eXBlb2YgZW50cnkucmVsYXRpb25zaGlwTmFtZSAhPT0gXCJzdHJpbmdcIiB8fCBlbnRyeS5yZWxhdGlvbnNoaXBOYW1lLmxlbmd0aCA9PT0gMCkgY29udGludWVcblxuICAgICAgZW50cmllcy5wdXNoKHtcbiAgICAgICAgYXR0cmlidXRlTmFtZTogZW50cnkuYXR0cmlidXRlTmFtZSxcbiAgICAgICAgcmVsYXRpb25zaGlwTmFtZTogZW50cnkucmVsYXRpb25zaGlwTmFtZSxcbiAgICAgICAgd2hlcmU6IGVudHJ5LndoZXJlICYmIHR5cGVvZiBlbnRyeS53aGVyZSA9PT0gXCJvYmplY3RcIiA/IGVudHJ5LndoZXJlIDogdW5kZWZpbmVkXG4gICAgICB9KVxuICAgIH1cblxuICAgIHJldHVybiBlbnRyaWVzXG4gIH1cblxuICAvKipcbiAgICogUmVzb2x2ZSBhbiBlbnRyeSBmcm9tIHRoZSBmcm9udGVuZC1tb2RlbCBgYWJpbGl0aWVzYCBwYXlsb2FkIHRvXG4gICAqIGl0cyBiYWNrZW5kIG1vZGVsIGNsYXNzIGJ5IGxvb2tpbmcgdXAgdGhlIHJlc291cmNlIGJ5IG1vZGVsTmFtZVxuICAgKiBhY3Jvc3MgYWxsIGNvbmZpZ3VyZWQgYmFja2VuZCBwcm9qZWN0cy4gUmV0dXJucyBudWxsIHdoZW4gbm9cbiAgICogcmVzb3VyY2UgbWF0Y2hlcyDigJQgdGhlIHNwZWMgZW50cnkgaXMgdGhlbiBzaWxlbnRseSBpZ25vcmVkIHNvIGFcbiAgICogY2FsbGVyIHJlcXVlc3RpbmcgYWJpbGl0aWVzIGZvciBhIG1vZGVsIHRoZXkgY2Fubm90IHJlc29sdmUgZG9lc1xuICAgKiBub3QgY3Jhc2ggdGhlIHJlcXVlc3QuXG4gICAqXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBtb2RlbE5hbWVcbiAgICogQHJldHVybnMge3R5cGVvZiBpbXBvcnQoXCIuL2RhdGFiYXNlL3JlY29yZC9pbmRleC5qc1wiKS5kZWZhdWx0IHwgbnVsbH1cbiAgICovXG4gIF9mcm9udGVuZE1vZGVsQ2xhc3NGb3JBYmlsaXRpZXMobW9kZWxOYW1lKSB7XG4gICAgaWYgKHR5cGVvZiBtb2RlbE5hbWUgIT09IFwic3RyaW5nXCIgfHwgbW9kZWxOYW1lLmxlbmd0aCA9PT0gMCkgcmV0dXJuIG51bGxcblxuICAgIGNvbnN0IGNvbmZpZ3VyYXRpb24gPSB0aGlzLmdldENvbmZpZ3VyYXRpb24oKVxuICAgIGNvbnN0IGJhY2tlbmRQcm9qZWN0cyA9IGNvbmZpZ3VyYXRpb24/LmdldEJhY2tlbmRQcm9qZWN0cz8uKCkgPz8gW11cblxuICAgIGZvciAoY29uc3QgYmFja2VuZFByb2plY3Qgb2YgYmFja2VuZFByb2plY3RzKSB7XG4gICAgICBjb25zdCBmcm9udGVuZE1vZGVscyA9IGJhY2tlbmRQcm9qZWN0Py5mcm9udGVuZE1vZGVsc1xuICAgICAgaWYgKCFmcm9udGVuZE1vZGVscyB8fCB0eXBlb2YgZnJvbnRlbmRNb2RlbHMgIT09IFwib2JqZWN0XCIpIGNvbnRpbnVlXG5cbiAgICAgIGNvbnN0IHJlc291cmNlRGVmaW5pdGlvbiA9IGZyb250ZW5kTW9kZWxzW21vZGVsTmFtZV1cbiAgICAgIGlmICghcmVzb3VyY2VEZWZpbml0aW9uKSBjb250aW51ZVxuXG4gICAgICBjb25zdCByZXNvdXJjZUNsYXNzID0gZnJvbnRlbmRNb2RlbFJlc291cmNlQ2xhc3NGcm9tRGVmaW5pdGlvbihyZXNvdXJjZURlZmluaXRpb24pXG4gICAgICBpZiAoIXJlc291cmNlQ2xhc3MpIGNvbnRpbnVlXG5cbiAgICAgIGNvbnN0IG1vZGVsQ2xhc3MgPSB0eXBlb2YgcmVzb3VyY2VDbGFzcy5tb2RlbENsYXNzID09PSBcImZ1bmN0aW9uXCJcbiAgICAgICAgPyByZXNvdXJjZUNsYXNzLm1vZGVsQ2xhc3MoKVxuICAgICAgICA6IHJlc291cmNlQ2xhc3MuTW9kZWxDbGFzc1xuXG4gICAgICBpZiAodHlwZW9mIG1vZGVsQ2xhc3MgPT09IFwiZnVuY3Rpb25cIikgcmV0dXJuIG1vZGVsQ2xhc3NcbiAgICB9XG5cbiAgICByZXR1cm4gbnVsbFxuICB9XG5cbiAgLyoqXG4gICAqIENvbGxlY3QgZXZlcnkgbG9hZGVkIHJlY29yZCB3aG9zZSBgZ2V0TW9kZWxOYW1lKClgIG1hdGNoZXMgdGhlXG4gICAqIHJlcXVlc3RlZCBuYW1lLCB3YWxraW5nIGFjcm9zcyB0aGUgcm9vdC1sZXZlbCBzbGljZSBwbHVzIGFueVxuICAgKiBwcmVsb2FkZWQgcmVsYXRpb25zaGlwcyBhdCBhbnkgZGVwdGguIFVzZWQgdG8gZXZhbHVhdGUgcGVyLXJlY29yZFxuICAgKiBhYmlsaXRpZXMgYWdhaW5zdCBuZXN0ZWQgcHJlbG9hZGVkIGNoaWxkcmVuIHdpdGggYSBzaW5nbGUgYmF0Y2hlZFxuICAgKiBxdWVyeSBwZXIgKG1vZGVsQ2xhc3MsIGFjdGlvbikgcGFpci5cbiAgICpcbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuL2RhdGFiYXNlL3JlY29yZC9pbmRleC5qc1wiKS5kZWZhdWx0W119IHJvb3RNb2RlbHNcbiAgICogQHBhcmFtIHtzdHJpbmd9IG1vZGVsTmFtZVxuICAgKiBAcmV0dXJucyB7aW1wb3J0KFwiLi9kYXRhYmFzZS9yZWNvcmQvaW5kZXguanNcIikuZGVmYXVsdFtdfVxuICAgKi9cbiAgX2Zyb250ZW5kTW9kZWxDb2xsZWN0UmVjb3Jkc0Zvck5hbWUocm9vdE1vZGVscywgbW9kZWxOYW1lKSB7XG4gICAgLyoqIEB0eXBlIHtpbXBvcnQoXCIuL2RhdGFiYXNlL3JlY29yZC9pbmRleC5qc1wiKS5kZWZhdWx0W119ICovXG4gICAgY29uc3Qgb3V0ID0gW11cbiAgICAvKiogQHR5cGUge1NldDxpbXBvcnQoXCIuL2RhdGFiYXNlL3JlY29yZC9pbmRleC5qc1wiKS5kZWZhdWx0Pn0gKi9cbiAgICBjb25zdCBzZWVuID0gbmV3IFNldCgpXG5cbiAgICAvKiogQHBhcmFtIHtpbXBvcnQoXCIuL2RhdGFiYXNlL3JlY29yZC9pbmRleC5qc1wiKS5kZWZhdWx0IHwgbnVsbCB8IHVuZGVmaW5lZH0gcmVjb3JkICovXG4gICAgY29uc3Qgd2FsayA9IChyZWNvcmQpID0+IHtcbiAgICAgIGlmICghcmVjb3JkIHx8IHR5cGVvZiByZWNvcmQgIT09IFwib2JqZWN0XCIpIHJldHVyblxuICAgICAgaWYgKHNlZW4uaGFzKHJlY29yZCkpIHJldHVyblxuICAgICAgc2Vlbi5hZGQocmVjb3JkKVxuXG4gICAgICBjb25zdCBNb2RlbENsYXNzID0gdHlwZW9mIHJlY29yZC5nZXRNb2RlbENsYXNzID09PSBcImZ1bmN0aW9uXCJcbiAgICAgICAgPyByZWNvcmQuZ2V0TW9kZWxDbGFzcygpXG4gICAgICAgIDogbnVsbFxuICAgICAgaWYgKE1vZGVsQ2xhc3MgJiYgdHlwZW9mIE1vZGVsQ2xhc3MuZ2V0TW9kZWxOYW1lID09PSBcImZ1bmN0aW9uXCIgJiYgTW9kZWxDbGFzcy5nZXRNb2RlbE5hbWUoKSA9PT0gbW9kZWxOYW1lKSB7XG4gICAgICAgIG91dC5wdXNoKHJlY29yZClcbiAgICAgIH1cblxuICAgICAgY29uc3QgcmVsYXRpb25zaGlwc01hcCA9IHR5cGVvZiBNb2RlbENsYXNzPy5nZXRSZWxhdGlvbnNoaXBzTWFwID09PSBcImZ1bmN0aW9uXCJcbiAgICAgICAgPyBNb2RlbENsYXNzLmdldFJlbGF0aW9uc2hpcHNNYXAoKVxuICAgICAgICA6IG51bGxcbiAgICAgIGlmICghcmVsYXRpb25zaGlwc01hcCkgcmV0dXJuXG5cbiAgICAgIGZvciAoY29uc3QgcmVsYXRpb25zaGlwTmFtZSBvZiBPYmplY3Qua2V5cyhyZWxhdGlvbnNoaXBzTWFwKSkge1xuICAgICAgICBjb25zdCByZWxhdGlvbnNoaXAgPSB0eXBlb2YgcmVjb3JkLmdldFJlbGF0aW9uc2hpcEJ5TmFtZSA9PT0gXCJmdW5jdGlvblwiXG4gICAgICAgICAgPyByZWNvcmQuZ2V0UmVsYXRpb25zaGlwQnlOYW1lKHJlbGF0aW9uc2hpcE5hbWUpXG4gICAgICAgICAgOiBudWxsXG4gICAgICAgIGlmICghcmVsYXRpb25zaGlwIHx8IHR5cGVvZiByZWxhdGlvbnNoaXAuZ2V0TG9hZGVkT3JVbmRlZmluZWQgIT09IFwiZnVuY3Rpb25cIikgY29udGludWVcblxuICAgICAgICBjb25zdCBsb2FkZWQgPSByZWxhdGlvbnNoaXAuZ2V0TG9hZGVkT3JVbmRlZmluZWQoKVxuICAgICAgICBpZiAobG9hZGVkID09PSB1bmRlZmluZWQpIGNvbnRpbnVlXG5cbiAgICAgICAgaWYgKEFycmF5LmlzQXJyYXkobG9hZGVkKSkge1xuICAgICAgICAgIGZvciAoY29uc3QgY2hpbGQgb2YgbG9hZGVkKSB3YWxrKGNoaWxkKVxuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHdhbGsobG9hZGVkKVxuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuXG4gICAgZm9yIChjb25zdCByb290IG9mIHJvb3RNb2RlbHMpIHdhbGsocm9vdClcblxuICAgIHJldHVybiBvdXRcbiAgfVxuXG4gIC8qKlxuICAgKiBFdmFsdWF0ZSBldmVyeSBhYmlsaXR5IHJlcXVlc3RlZCB2aWEgdGhlIGZyb250ZW5kIGBhYmlsaXRpZXNgXG4gICAqIHBhcmFtIGFnYWluc3QgdGhlIGxvYWRlZCBtb2RlbCBjb2hvcnQgKHBsdXMgYW55IHByZWxvYWRlZFxuICAgKiBjaGlsZHJlbiksIGF0dGFjaGluZyB0aGUgcmVzdWx0cyB0byBlYWNoIHJlY29yZCB2aWFcbiAgICogYF9zZXRDb21wdXRlZEFiaWxpdHlgLiBSdW5zIG9uZSBiYXRjaGVkIGBhdXRob3JpemVkIHF1ZXJ5ICsgcGx1Y2tgXG4gICAqIHBlciAobW9kZWxDbGFzcywgYWN0aW9uKSBwYWlyLCByZWdhcmRsZXNzIG9mIGhvdyBtYW55IHJlY29yZHNcbiAgICogd2VyZSBsb2FkZWQuXG4gICAqXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi9kYXRhYmFzZS9yZWNvcmQvaW5kZXguanNcIikuZGVmYXVsdFtdfSByb290TW9kZWxzXG4gICAqIEByZXR1cm5zIHtQcm9taXNlPHZvaWQ+fVxuICAgKi9cbiAgYXN5bmMgZnJvbnRlbmRNb2RlbENvbXB1dGVBYmlsaXRpZXMocm9vdE1vZGVscykge1xuICAgIGNvbnN0IGVudHJpZXMgPSB0aGlzLmZyb250ZW5kTW9kZWxBYmlsaXRpZXMoKVxuICAgIGlmIChlbnRyaWVzLmxlbmd0aCA9PT0gMCkgcmV0dXJuXG4gICAgaWYgKCFBcnJheS5pc0FycmF5KHJvb3RNb2RlbHMpIHx8IHJvb3RNb2RlbHMubGVuZ3RoID09PSAwKSByZXR1cm5cblxuICAgIGNvbnN0IGFiaWxpdHkgPSB0aGlzLmN1cnJlbnRBYmlsaXR5KClcbiAgICBpZiAoIWFiaWxpdHkpIHJldHVyblxuXG4gICAgZm9yIChjb25zdCBlbnRyeSBvZiBlbnRyaWVzKSB7XG4gICAgICBjb25zdCBtb2RlbENsYXNzID0gdGhpcy5fZnJvbnRlbmRNb2RlbENsYXNzRm9yQWJpbGl0aWVzKGVudHJ5Lm1vZGVsTmFtZSlcbiAgICAgIGlmICghbW9kZWxDbGFzcykgY29udGludWVcblxuICAgICAgY29uc3QgY2FuZGlkYXRlcyA9IHRoaXMuX2Zyb250ZW5kTW9kZWxDb2xsZWN0UmVjb3Jkc0Zvck5hbWUocm9vdE1vZGVscywgZW50cnkubW9kZWxOYW1lKVxuICAgICAgaWYgKGNhbmRpZGF0ZXMubGVuZ3RoID09PSAwKSBjb250aW51ZVxuXG4gICAgICBjb25zdCBwcmltYXJ5S2V5ID0gbW9kZWxDbGFzcy5wcmltYXJ5S2V5KClcbiAgICAgIGNvbnN0IGlkcyA9IGNhbmRpZGF0ZXNcbiAgICAgICAgLm1hcCgocmVjb3JkKSA9PiByZWNvcmQucmVhZEF0dHJpYnV0ZShwcmltYXJ5S2V5KSlcbiAgICAgICAgLmZpbHRlcigodmFsdWUpID0+IHZhbHVlICE9PSBudWxsICYmIHZhbHVlICE9PSB1bmRlZmluZWQpXG4gICAgICBpZiAoaWRzLmxlbmd0aCA9PT0gMCkgY29udGludWVcblxuICAgICAgZm9yIChjb25zdCBhY3Rpb24gb2YgZW50cnkuYWN0aW9ucykge1xuICAgICAgICBsZXQgYWxsb3dlZElkc1xuICAgICAgICB0cnkge1xuICAgICAgICAgIGNvbnN0IGF1dGhvcml6ZWRRdWVyeSA9IG1vZGVsQ2xhc3MuYWNjZXNzaWJsZUZvcihhY3Rpb24sIGFiaWxpdHkpLndoZXJlKHtbcHJpbWFyeUtleV06IGlkc30pXG4gICAgICAgICAgY29uc3QgcGx1Y2tlZCA9IGF3YWl0IGF1dGhvcml6ZWRRdWVyeS5wbHVjayhwcmltYXJ5S2V5KVxuICAgICAgICAgIGFsbG93ZWRJZHMgPSBuZXcgU2V0KHBsdWNrZWQubWFwKCh2YWx1ZSkgPT4gU3RyaW5nKHZhbHVlKSkpXG4gICAgICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICAgICAgLy8gQW4gYWJpbGl0eSB3aXRoIG5vIGFsbG93IHJ1bGVzIGZvciB0aGUgYWN0aW9uIHRocm93cyB2aWFcbiAgICAgICAgICAvLyBgYWNjZXNzaWJsZUZvcmA7IHRyZWF0IGFzIGEgdW5pdmVyc2FsIGRlbnkgc28gdGhlIGZyb250ZW5kXG4gICAgICAgICAgLy8gZ2V0cyBgY2FuKGFjdGlvbikgPT09IGZhbHNlYCBmb3IgZXZlcnkgY2FuZGlkYXRlLCBpbnN0ZWFkXG4gICAgICAgICAgLy8gb2Ygc3VyZmFjaW5nIGFuIGVycm9yIHRoYXQgdGhlIFVJIGNhbid0IGFjdCBvbi5cbiAgICAgICAgICB2b2lkIGVycm9yXG4gICAgICAgICAgYWxsb3dlZElkcyA9IG5ldyBTZXQoKVxuICAgICAgICB9XG5cbiAgICAgICAgZm9yIChjb25zdCByZWNvcmQgb2YgY2FuZGlkYXRlcykge1xuICAgICAgICAgIGNvbnN0IGlkVmFsdWUgPSByZWNvcmQucmVhZEF0dHJpYnV0ZShwcmltYXJ5S2V5KVxuICAgICAgICAgIGNvbnN0IGFsbG93ZWQgPSBpZFZhbHVlICE9PSBudWxsICYmIGlkVmFsdWUgIT09IHVuZGVmaW5lZCAmJiBhbGxvd2VkSWRzLmhhcyhTdHJpbmcoaWRWYWx1ZSkpXG4gICAgICAgICAgcmVjb3JkLl9zZXRDb21wdXRlZEFiaWxpdHkoYWN0aW9uLCBhbGxvd2VkKVxuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIFBhcnNlIHRoZSBmcm9udGVuZC1tb2RlbCBgYWJpbGl0aWVzYCBwYXJhbSBpbnRvIGEgbGlzdCBvZlxuICAgKiBge21vZGVsTmFtZSwgYWN0aW9uc31gIGVudHJpZXMgdG8gZXZhbHVhdGUgYWdhaW5zdCBsb2FkZWQgcmVjb3Jkcy5cbiAgICogVW5rbm93biBlbnRyaWVzIGFyZSBzaWxlbnRseSBza2lwcGVkIOKAlCBkb3duc3RyZWFtIGNvZGUgcmVzb2x2ZXNcbiAgICogbW9kZWwgbmFtZXMgdG8gY2xhc3NlcyB3aGVuIGFwcGx5aW5nIHRoZSBjaGVjaywgc28gdW5yZXNvbHZlZFxuICAgKiBuYW1lcyBuYXR1cmFsbHkgYmVjb21lIG5vLW9wcy5cbiAgICpcbiAgICogQHJldHVybnMge0FycmF5PHttb2RlbE5hbWU6IHN0cmluZywgYWN0aW9uczogc3RyaW5nW119Pn1cbiAgICovXG4gIGZyb250ZW5kTW9kZWxBYmlsaXRpZXMoKSB7XG4gICAgY29uc3QgcmF3ID0gdGhpcy5mcm9udGVuZE1vZGVsUGFyYW1zKCkuYWJpbGl0aWVzXG5cbiAgICBpZiAoIUFycmF5LmlzQXJyYXkocmF3KSkgcmV0dXJuIFtdXG5cbiAgICAvKiogQHR5cGUge0FycmF5PHttb2RlbE5hbWU6IHN0cmluZywgYWN0aW9uczogc3RyaW5nW119Pn0gKi9cbiAgICBjb25zdCBlbnRyaWVzID0gW11cblxuICAgIGZvciAoY29uc3QgZW50cnkgb2YgcmF3KSB7XG4gICAgICBpZiAoIWVudHJ5IHx8IHR5cGVvZiBlbnRyeSAhPT0gXCJvYmplY3RcIikgY29udGludWVcbiAgICAgIGlmICh0eXBlb2YgZW50cnkubW9kZWxOYW1lICE9PSBcInN0cmluZ1wiIHx8IGVudHJ5Lm1vZGVsTmFtZS5sZW5ndGggPT09IDApIGNvbnRpbnVlXG4gICAgICBpZiAoIUFycmF5LmlzQXJyYXkoZW50cnkuYWN0aW9ucykpIGNvbnRpbnVlXG5cbiAgICAgIGNvbnN0IGFjdGlvbnMgPSBlbnRyeS5hY3Rpb25zLmZpbHRlcihcbiAgICAgICAgKC8qKiBAdHlwZSB7dW5rbm93bn0gKi8gYWN0aW9uKSA9PiB0eXBlb2YgYWN0aW9uID09PSBcInN0cmluZ1wiICYmIGFjdGlvbi5sZW5ndGggPiAwXG4gICAgICApXG5cbiAgICAgIGlmIChhY3Rpb25zLmxlbmd0aCA9PT0gMCkgY29udGludWVcblxuICAgICAgZW50cmllcy5wdXNoKHthY3Rpb25zLCBtb2RlbE5hbWU6IGVudHJ5Lm1vZGVsTmFtZX0pXG4gICAgfVxuXG4gICAgcmV0dXJuIGVudHJpZXNcbiAgfVxuXG4gIC8qKlxuICAgKiBSZWFkIHRoZSBmcm9udGVuZC1tb2RlbCBgcXVlcnlEYXRhYCBwYXJhbS4gVGhlIHdpcmUgZm9ybWF0IGNhcnJpZXNcbiAgICogb25seSAqKm5hbWVzKiogKHRoZSBrZXlzIHRoZSBmcm9udGVuZCB3YW50cyBhdHRhY2hlZCkgcGx1cyB0aGVcbiAgICogb3B0aW9uYWwgbmVzdGVkLXJlbGF0aW9uc2hpcCBjaGFpbiBsZWFkaW5nIHRvIHRoZW0g4oCUIHRoZSBhY3R1YWwgU1FMXG4gICAqIGZyYWdtZW50cyBsaXZlIG9uIHRoZSBiYWNrZW5kIG1vZGVsIGFzIGBNb2RlbC5xdWVyeURhdGEobmFtZSwgZm4pYFxuICAgKiByZWdpc3RyYXRpb25zLiBDYWxsZXJzIGNhbm5vdCBwdXNoIFNRTCB0aHJvdWdoIHRoaXMgZW5kcG9pbnQuXG4gICAqXG4gICAqIFJldHVybnMgdGhlIHJhdyBuZXN0ZWQtcmVjb3JkIHNwZWMgKHNoYXBlIHZhbGlkYXRlZCBieSB0aGVcbiAgICogbm9ybWFsaXplciBpbnNpZGUgYFF1ZXJ5LnF1ZXJ5RGF0YWApIG9yIGBudWxsYCB3aGVuIG5vdCByZXF1ZXN0ZWQuXG4gICAqXG4gICAqIEByZXR1cm5zIHtpbXBvcnQoXCIuL2RhdGFiYXNlL3F1ZXJ5L3F1ZXJ5LWRhdGEuanNcIikuUXVlcnlEYXRhU3BlYyB8IG51bGx9XG4gICAqL1xuICBmcm9udGVuZE1vZGVsUXVlcnlEYXRhKCkge1xuICAgIGNvbnN0IHJhdyA9IHRoaXMuZnJvbnRlbmRNb2RlbFBhcmFtcygpLnF1ZXJ5RGF0YVxuXG4gICAgaWYgKHJhdyA9PSBudWxsKSByZXR1cm4gbnVsbFxuXG4gICAgaWYgKHR5cGVvZiByYXcgPT09IFwic3RyaW5nXCIpIHJldHVybiByYXdcbiAgICBpZiAoQXJyYXkuaXNBcnJheShyYXcpKSByZXR1cm4gcmF3XG4gICAgaWYgKHR5cGVvZiByYXcgPT09IFwib2JqZWN0XCIpIHJldHVybiByYXdcblxuICAgIHJldHVybiBudWxsXG4gIH1cblxuICAvKipcbiAgICogQHJldHVybnMge2ltcG9ydChcIi4vZGF0YWJhc2UvcXVlcnkvbW9kZWwtY2xhc3MtcXVlcnkuanNcIikuZGVmYXVsdH0gLSBGcm9udGVuZCBpbmRleCBxdWVyeSB3aXRoIG5vcm1hbGl6ZWQgcGFyYW1zIGFwcGxpZWQuXG4gICAqL1xuICBmcm9udGVuZE1vZGVsSW5kZXhRdWVyeSgpIHtcbiAgICBsZXQgcXVlcnkgPSB0aGlzLmZyb250ZW5kTW9kZWxBdXRob3JpemVkUXVlcnkoXCJpbmRleFwiKVxuICAgIGNvbnN0IHByZWxvYWQgPSB0aGlzLmZyb250ZW5kTW9kZWxQcmVsb2FkKClcblxuICAgIGlmIChwcmVsb2FkKSB7XG4gICAgICBxdWVyeSA9IHF1ZXJ5LnByZWxvYWQocHJlbG9hZClcbiAgICB9XG5cbiAgICBjb25zdCBqb2lucyA9IHRoaXMuZnJvbnRlbmRNb2RlbEpvaW5zKClcbiAgICBjb25zdCB3aGVyZSA9IHRoaXMuZnJvbnRlbmRNb2RlbFdoZXJlKClcbiAgICBjb25zdCBwYWdpbmF0aW9uID0gdGhpcy5mcm9udGVuZE1vZGVsUGFnaW5hdGlvbigpXG4gICAgY29uc3QgZGlzdGluY3QgPSB0aGlzLmZyb250ZW5kTW9kZWxEaXN0aW5jdCgpXG5cbiAgICB0aGlzLmFwcGx5RnJvbnRlbmRNb2RlbFBhZ2luYXRpb24oe3BhZ2luYXRpb24sIHF1ZXJ5fSlcblxuICAgIGlmIChkaXN0aW5jdCAhPT0gbnVsbCkge1xuICAgICAgcXVlcnkuZGlzdGluY3QoZGlzdGluY3QpXG4gICAgfVxuXG4gICAgaWYgKHdoZXJlKSB7XG4gICAgICB0aGlzLmFwcGx5RnJvbnRlbmRNb2RlbFdoZXJlKHtxdWVyeSwgd2hlcmV9KVxuICAgIH1cblxuICAgIGNvbnN0IHJhbnNhY2sgPSB0aGlzLmZyb250ZW5kTW9kZWxSYW5zYWNrKClcblxuICAgIGlmIChyYW5zYWNrKSB7XG4gICAgICBxdWVyeS5yYW5zYWNrKHJhbnNhY2spXG4gICAgfVxuXG4gICAgaWYgKGpvaW5zKSB7XG4gICAgICB0aGlzLmFwcGx5RnJvbnRlbmRNb2RlbEpvaW5zKHtqb2lucywgcXVlcnl9KVxuICAgIH1cblxuICAgIGNvbnN0IHNlYXJjaGVzID0gdGhpcy5mcm9udGVuZE1vZGVsU2VhcmNoZXMoKVxuXG4gICAgZm9yIChjb25zdCBzZWFyY2ggb2Ygc2VhcmNoZXMpIHtcbiAgICAgIHRoaXMuYXBwbHlGcm9udGVuZE1vZGVsU2VhcmNoKHtxdWVyeSwgc2VhcmNofSlcbiAgICB9XG5cbiAgICBjb25zdCBncm91cHMgPSB0aGlzLmZyb250ZW5kTW9kZWxHcm91cCgpXG5cbiAgICBpZiAoZ3JvdXBzLmxlbmd0aCA+IDApIHtcbiAgICAgIHRoaXMuYXBwbHlGcm9udGVuZE1vZGVsUm9vdEdyb3VwQ29sdW1ucyh7cXVlcnl9KVxuICAgIH1cblxuICAgIGZvciAoY29uc3QgZ3JvdXAgb2YgZ3JvdXBzKSB7XG4gICAgICB0aGlzLmFwcGx5RnJvbnRlbmRNb2RlbEdyb3VwKHtncm91cCwgcXVlcnl9KVxuICAgIH1cblxuICAgIGNvbnN0IHNvcnRzID0gdGhpcy5mcm9udGVuZE1vZGVsU29ydCgpXG5cbiAgICBpZiAoc29ydHMubGVuZ3RoID4gMCkge1xuICAgICAgZm9yIChjb25zdCBzb3J0IG9mIHNvcnRzKSB7XG4gICAgICAgIHRoaXMuYXBwbHlGcm9udGVuZE1vZGVsU29ydCh7cXVlcnksIHNvcnR9KVxuICAgICAgfVxuICAgIH1cblxuICAgIGNvbnN0IHdpdGhDb3VudCA9IHRoaXMuZnJvbnRlbmRNb2RlbFdpdGhDb3VudCgpXG5cbiAgICBmb3IgKGNvbnN0IGVudHJ5IG9mIHdpdGhDb3VudCkge1xuICAgICAgLyoqIEB0eXBlIHtSZWNvcmQ8c3RyaW5nLCBib29sZWFuIHwge3JlbGF0aW9uc2hpcD86IHN0cmluZywgd2hlcmU/OiBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPn0+fSAqL1xuICAgICAgY29uc3Qgc3BlYyA9IHt9XG4gICAgICBzcGVjW2VudHJ5LmF0dHJpYnV0ZU5hbWVdID0ge3JlbGF0aW9uc2hpcDogZW50cnkucmVsYXRpb25zaGlwTmFtZSwgd2hlcmU6IGVudHJ5LndoZXJlfVxuICAgICAgcXVlcnkud2l0aENvdW50KHNwZWMpXG4gICAgfVxuXG4gICAgY29uc3QgcXVlcnlEYXRhID0gdGhpcy5mcm9udGVuZE1vZGVsUXVlcnlEYXRhKClcblxuICAgIGlmIChxdWVyeURhdGEgIT0gbnVsbCkge1xuICAgICAgcXVlcnkucXVlcnlEYXRhKHF1ZXJ5RGF0YSlcbiAgICB9XG5cbiAgICBxdWVyeSA9IHRoaXMuYXBwbHlGcm9udGVuZE1vZGVsVHJhbnNsYXRlZEF0dHJpYnV0ZVByZWxvYWRzKHtxdWVyeX0pXG5cbiAgICBpZiAocXVlcnkuX2Rpc3RpbmN0ICYmIHF1ZXJ5LmRyaXZlci5nZXRUeXBlKCkgPT09IFwibXNzcWxcIikge1xuICAgICAgcmV0dXJuIHRoaXMuZnJvbnRlbmRNb2RlbE1zc3FsRGlzdGluY3RCeVByaW1hcnlLZXlRdWVyeSh7cXVlcnl9KVxuICAgIH1cblxuICAgIHJldHVybiBxdWVyeVxuICB9XG5cbiAgLyoqXG4gICAqIE1TU1FMIGNhbm5vdCBhcHBseSBESVNUSU5DVCBvdmVyIG5vbi1jb21wYXJhYmxlIHRleHQgY29sdW1ucyBpbiB0YWJsZS4qIHNlbGVjdHMuXG4gICAqIFRoaXMgcmV3cml0ZXMgZGlzdGluY3QgZnJvbnRlbmQtbW9kZWwgcXVlcmllcyB0byBzZWxlY3Qgcm9vdCByZWNvcmRzIGJ5IGRpc3RpbmN0IFBLIHN1YnF1ZXJ5LlxuICAgKiBAcGFyYW0ge29iamVjdH0gYXJncyAtIEFyZ3MuXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi9kYXRhYmFzZS9xdWVyeS9tb2RlbC1jbGFzcy1xdWVyeS5qc1wiKS5kZWZhdWx0fSBhcmdzLnF1ZXJ5IC0gUXVlcnkgd2l0aCBkaXN0aW5jdCBhbmQgZmlsdGVycy5cbiAgICogQHJldHVybnMge2ltcG9ydChcIi4vZGF0YWJhc2UvcXVlcnkvbW9kZWwtY2xhc3MtcXVlcnkuanNcIikuZGVmYXVsdH0gLSBNU1NRTC1zYWZlIGRpc3RpbmN0IHF1ZXJ5LlxuICAgKi9cbiAgZnJvbnRlbmRNb2RlbE1zc3FsRGlzdGluY3RCeVByaW1hcnlLZXlRdWVyeSh7cXVlcnl9KSB7XG4gICAgY29uc3QgbW9kZWxDbGFzcyA9IHRoaXMuZnJvbnRlbmRNb2RlbENsYXNzKClcbiAgICBjb25zdCBwcmltYXJ5S2V5ID0gbW9kZWxDbGFzcy5wcmltYXJ5S2V5KClcbiAgICBjb25zdCByb290VGFibGVTcWwgPSBxdWVyeS5kcml2ZXIucXVvdGVUYWJsZShtb2RlbENsYXNzLnRhYmxlTmFtZSgpKVxuICAgIGNvbnN0IHByaW1hcnlLZXlTcWwgPSBgJHtyb290VGFibGVTcWx9LiR7cXVlcnkuZHJpdmVyLnF1b3RlQ29sdW1uKHByaW1hcnlLZXkpfWBcbiAgICBjb25zdCBkaXN0aW5jdElkc1F1ZXJ5ID0gcXVlcnkuY2xvbmUoKVxuXG4gICAgZGlzdGluY3RJZHNRdWVyeS5fcHJlbG9hZCA9IHt9XG4gICAgZGlzdGluY3RJZHNRdWVyeS5fc2VsZWN0cyA9IFtdXG4gICAgZGlzdGluY3RJZHNRdWVyeS5zZWxlY3QocHJpbWFyeUtleVNxbClcbiAgICBkaXN0aW5jdElkc1F1ZXJ5LmRpc3RpbmN0KHRydWUpXG5cbiAgICBjb25zdCBkaXN0aW5jdFJvb3RRdWVyeSA9IG1vZGVsQ2xhc3MuX25ld1F1ZXJ5KClcblxuICAgIGRpc3RpbmN0Um9vdFF1ZXJ5LndoZXJlKGAke3ByaW1hcnlLZXlTcWx9IElOICgke2Rpc3RpbmN0SWRzUXVlcnkudG9TcWwoKX0pYClcbiAgICBkaXN0aW5jdFJvb3RRdWVyeS5fcHJlbG9hZCA9IHsuLi5xdWVyeS5fcHJlbG9hZH1cblxuICAgIHJldHVybiBkaXN0aW5jdFJvb3RRdWVyeVxuICB9XG5cbiAgLyoqXG4gICAqIEBwYXJhbSB7b2JqZWN0fSBhcmdzIC0gUGx1Y2sgYXJncy5cbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuL2RhdGFiYXNlL3F1ZXJ5L21vZGVsLWNsYXNzLXF1ZXJ5LmpzXCIpLmRlZmF1bHR9IGFyZ3MucXVlcnkgLSBRdWVyeSBpbnN0YW5jZS5cbiAgICogQHBhcmFtIHtGcm9udGVuZE1vZGVsUGx1Y2tbXX0gYXJncy5wbHVjayAtIFBsdWNrIGRlc2NyaXB0b3JzLlxuICAgKiBAcmV0dXJucyB7UHJvbWlzZTxhbnlbXT59IC0gUGx1Y2tlZCB2YWx1ZXMuXG4gICAqL1xuICBhc3luYyBmcm9udGVuZE1vZGVsUGx1Y2tWYWx1ZXMoe3F1ZXJ5LCBwbHVja30pIHtcbiAgICBpZiAocGx1Y2subGVuZ3RoIDwgMSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKFwiTm8gY29sdW1ucyBnaXZlbiB0byBwbHVja1wiKVxuICAgIH1cblxuICAgIGNvbnN0IG1vZGVsQ2xhc3MgPSB0aGlzLmZyb250ZW5kTW9kZWxDbGFzcygpXG4gICAgY29uc3QgcGx1Y2tRdWVyeSA9IHF1ZXJ5LmNsb25lKClcbiAgICAvKiogQHR5cGUge3N0cmluZ1tdfSAqL1xuICAgIGNvbnN0IGFsaWFzZXMgPSBbXVxuICAgIGNvbnN0IHF1ZXJ5TWV0YWRhdGEgPSBmcm9udGVuZE1vZGVsUXVlcnlNZXRhZGF0YShxdWVyeSlcbiAgICBjb25zdCBwbHVja1F1ZXJ5TWV0YWRhdGEgPSBmcm9udGVuZE1vZGVsUXVlcnlNZXRhZGF0YShwbHVja1F1ZXJ5KVxuICAgIGNvbnN0IGpvaW5lZFBhdGhzID0gcXVlcnlNZXRhZGF0YVtmcm9udGVuZE1vZGVsSm9pbmVkUGF0aHNTeW1ib2xdXG5cbiAgICBwbHVja1F1ZXJ5Ll9wcmVsb2FkID0ge31cbiAgICBwbHVja1F1ZXJ5Ll9zZWxlY3RzID0gW11cbiAgICBwbHVja1F1ZXJ5TWV0YWRhdGFbZnJvbnRlbmRNb2RlbEpvaW5lZFBhdGhzU3ltYm9sXSA9IGpvaW5lZFBhdGhzID8gbmV3IFNldChqb2luZWRQYXRocykgOiBuZXcgU2V0KClcblxuICAgIGZvciAoY29uc3QgW3BsdWNrSW5kZXgsIHBsdWNrRW50cnldIG9mIHBsdWNrLmVudHJpZXMoKSkge1xuICAgICAgY29uc3QgdGFyZ2V0TW9kZWxDbGFzcyA9IHRoaXMuZnJvbnRlbmRNb2RlbFNlYXJjaFRhcmdldE1vZGVsQ2xhc3Moe1xuICAgICAgICBtb2RlbENsYXNzLFxuICAgICAgICBwYXRoOiBwbHVja0VudHJ5LnBhdGhcbiAgICAgIH0pXG4gICAgICBjb25zdCBjb2x1bW5OYW1lID0gdGhpcy5yZXNvbHZlRnJvbnRlbmRNb2RlbENvbHVtbk5hbWUodGFyZ2V0TW9kZWxDbGFzcywgcGx1Y2tFbnRyeS5jb2x1bW4pXG5cbiAgICAgIGlmICghY29sdW1uTmFtZSkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYFVua25vd24gcGx1Y2sgY29sdW1uIFwiJHtwbHVja0VudHJ5LmNvbHVtbn1cIiBmb3IgJHt0YXJnZXRNb2RlbENsYXNzLm5hbWV9YClcbiAgICAgIH1cblxuICAgICAgaWYgKHBsdWNrRW50cnkucGF0aC5sZW5ndGggPiAwKSB7XG4gICAgICAgIHRoaXMuZW5zdXJlRnJvbnRlbmRNb2RlbEpvaW5QYXRoKHtwYXRoOiBwbHVja0VudHJ5LnBhdGgsIHF1ZXJ5OiBwbHVja1F1ZXJ5fSlcbiAgICAgIH1cblxuICAgICAgY29uc3QgdGFibGVSZWZlcmVuY2UgPSBwbHVja1F1ZXJ5LmdldFRhYmxlUmVmZXJlbmNlRm9ySm9pbiguLi5wbHVja0VudHJ5LnBhdGgpXG4gICAgICBjb25zdCBjb2x1bW5TcWwgPSBgJHtwbHVja1F1ZXJ5LmRyaXZlci5xdW90ZVRhYmxlKHRhYmxlUmVmZXJlbmNlKX0uJHtwbHVja1F1ZXJ5LmRyaXZlci5xdW90ZUNvbHVtbihjb2x1bW5OYW1lKX1gXG4gICAgICBjb25zdCBhbGlhcyA9IGBmcm9udGVuZF9tb2RlbF9wbHVja18ke3BsdWNrSW5kZXh9YFxuXG4gICAgICBwbHVja1F1ZXJ5LnNlbGVjdChgJHtjb2x1bW5TcWx9IEFTICR7cGx1Y2tRdWVyeS5kcml2ZXIucXVvdGVDb2x1bW4oYWxpYXMpfWApXG4gICAgICBhbGlhc2VzLnB1c2goYWxpYXMpXG4gICAgfVxuXG4gICAgY29uc3Qgcm93cyA9IGF3YWl0IHBsdWNrUXVlcnkucmVzdWx0cygpXG5cbiAgICBpZiAoYWxpYXNlcy5sZW5ndGggPT09IDEpIHtcbiAgICAgIGNvbnN0IFthbGlhc10gPSBhbGlhc2VzXG5cbiAgICAgIHJldHVybiByb3dzLm1hcCgocm93KSA9PiAvKiogQHR5cGUge1JlY29yZDxzdHJpbmcsIGFueT59ICovIChyb3cpW2FsaWFzXSlcbiAgICB9XG5cbiAgICByZXR1cm4gcm93cy5tYXAoKHJvdykgPT4ge1xuICAgICAgY29uc3Qgcm93SGFzaCA9IC8qKiBAdHlwZSB7UmVjb3JkPHN0cmluZywgYW55Pn0gKi8gKHJvdylcblxuICAgICAgcmV0dXJuIGFsaWFzZXMubWFwKChhbGlhcykgPT4gcm93SGFzaFthbGlhc10pXG4gICAgfSlcbiAgfVxuXG4gIC8qKlxuICAgKiBAcGFyYW0ge29iamVjdH0gYXJncyAtIFNlYXJjaCBhcmdzLlxuICAgKiBAcGFyYW0ge3R5cGVvZiBpbXBvcnQoXCIuL2RhdGFiYXNlL3JlY29yZC9pbmRleC5qc1wiKS5kZWZhdWx0fSBhcmdzLm1vZGVsQ2xhc3MgLSBSb290IG1vZGVsIGNsYXNzLlxuICAgKiBAcGFyYW0ge3N0cmluZ1tdfSBhcmdzLnBhdGggLSBSZWxhdGlvbnNoaXAgcGF0aC5cbiAgICogQHJldHVybnMge3R5cGVvZiBpbXBvcnQoXCIuL2RhdGFiYXNlL3JlY29yZC9pbmRleC5qc1wiKS5kZWZhdWx0fSAtIFRhcmdldCBtb2RlbCBjbGFzcy5cbiAgICovXG4gIGZyb250ZW5kTW9kZWxTZWFyY2hUYXJnZXRNb2RlbENsYXNzKHttb2RlbENsYXNzLCBwYXRofSkge1xuICAgIGxldCB0YXJnZXRNb2RlbENsYXNzID0gbW9kZWxDbGFzc1xuXG4gICAgZm9yIChjb25zdCByZWxhdGlvbnNoaXBOYW1lIG9mIHBhdGgpIHtcbiAgICAgIGNvbnN0IHJlbGF0aW9uc2hpcCA9IHRhcmdldE1vZGVsQ2xhc3MuZ2V0UmVsYXRpb25zaGlwc01hcCgpW3JlbGF0aW9uc2hpcE5hbWVdXG5cbiAgICAgIGlmICghcmVsYXRpb25zaGlwKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihgVW5rbm93biBzZWFyY2ggcmVsYXRpb25zaGlwIFwiJHtyZWxhdGlvbnNoaXBOYW1lfVwiIGZvciAke3RhcmdldE1vZGVsQ2xhc3MubmFtZX1gKVxuICAgICAgfVxuXG4gICAgICBjb25zdCByZWxhdGlvbnNoaXBUYXJnZXRNb2RlbENsYXNzID0gcmVsYXRpb25zaGlwLmdldFRhcmdldE1vZGVsQ2xhc3MoKVxuXG4gICAgICBpZiAoIXJlbGF0aW9uc2hpcFRhcmdldE1vZGVsQ2xhc3MpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBObyB0YXJnZXQgbW9kZWwgY2xhc3MgZm9yICR7dGFyZ2V0TW9kZWxDbGFzcy5uYW1lfSMke3JlbGF0aW9uc2hpcE5hbWV9YClcbiAgICAgIH1cblxuICAgICAgdGFyZ2V0TW9kZWxDbGFzcyA9IHJlbGF0aW9uc2hpcFRhcmdldE1vZGVsQ2xhc3NcbiAgICB9XG5cbiAgICByZXR1cm4gdGFyZ2V0TW9kZWxDbGFzc1xuICB9XG5cbiAgLyoqXG4gICAqIEBwYXJhbSB7b2JqZWN0fSBhcmdzIC0gU2VhcmNoIGFyZ3MuXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi9kYXRhYmFzZS9xdWVyeS9tb2RlbC1jbGFzcy1xdWVyeS5qc1wiKS5kZWZhdWx0fSBhcmdzLnF1ZXJ5IC0gUXVlcnkgaW5zdGFuY2UuXG4gICAqIEBwYXJhbSB7RnJvbnRlbmRNb2RlbFNlYXJjaH0gYXJncy5zZWFyY2ggLSBTZWFyY2ggZmlsdGVyLlxuICAgKiBAcmV0dXJucyB7dm9pZH1cbiAgICovXG4gIGFwcGx5RnJvbnRlbmRNb2RlbFNlYXJjaCh7cXVlcnksIHNlYXJjaH0pIHtcbiAgICBjb25zdCBtb2RlbENsYXNzID0gdGhpcy5mcm9udGVuZE1vZGVsQ2xhc3MoKVxuICAgIGNvbnN0IHRhcmdldE1vZGVsQ2xhc3MgPSB0aGlzLmZyb250ZW5kTW9kZWxTZWFyY2hUYXJnZXRNb2RlbENsYXNzKHtcbiAgICAgIG1vZGVsQ2xhc3MsXG4gICAgICBwYXRoOiBzZWFyY2gucGF0aFxuICAgIH0pXG4gICAgY29uc3QgY29sdW1uTmFtZSA9IHRoaXMucmVzb2x2ZUZyb250ZW5kTW9kZWxDb2x1bW5OYW1lKHRhcmdldE1vZGVsQ2xhc3MsIHNlYXJjaC5jb2x1bW4pXG5cbiAgICBpZiAoIWNvbHVtbk5hbWUpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihgVW5rbm93biBzZWFyY2ggY29sdW1uIFwiJHtzZWFyY2guY29sdW1ufVwiIGZvciAke3RhcmdldE1vZGVsQ2xhc3MubmFtZX1gKVxuICAgIH1cblxuICAgIGlmIChzZWFyY2gucGF0aC5sZW5ndGggPiAwKSB7XG4gICAgICB0aGlzLmVuc3VyZUZyb250ZW5kTW9kZWxKb2luUGF0aCh7cGF0aDogc2VhcmNoLnBhdGgsIHF1ZXJ5fSlcbiAgICB9XG5cbiAgICBjb25zdCB0YWJsZVJlZmVyZW5jZSA9IHF1ZXJ5LmdldFRhYmxlUmVmZXJlbmNlRm9ySm9pbiguLi5zZWFyY2gucGF0aClcbiAgICBjb25zdCBjb2x1bW5TcWwgPSBgJHtxdWVyeS5kcml2ZXIucXVvdGVUYWJsZSh0YWJsZVJlZmVyZW5jZSl9LiR7cXVlcnkuZHJpdmVyLnF1b3RlQ29sdW1uKGNvbHVtbk5hbWUpfWBcbiAgICBjb25zdCBvcGVyYXRvck1hcCA9IHtcbiAgICAgIGVxOiBcIj1cIixcbiAgICAgIGd0OiBcIj5cIixcbiAgICAgIGd0ZXE6IFwiPj1cIixcbiAgICAgIGxpa2U6IFwiTElLRVwiLFxuICAgICAgbHQ6IFwiPFwiLFxuICAgICAgbHRlcTogXCI8PVwiLFxuICAgICAgbm90RXE6IFwiIT1cIlxuICAgIH1cbiAgICBjb25zdCBzcWxPcGVyYXRvciA9IG9wZXJhdG9yTWFwW3NlYXJjaC5vcGVyYXRvcl1cblxuICAgIGlmIChzZWFyY2gub3BlcmF0b3IgPT09IFwiZXFcIikge1xuICAgICAgaWYgKEFycmF5LmlzQXJyYXkoc2VhcmNoLnZhbHVlKSkge1xuICAgICAgICBpZiAoc2VhcmNoLnZhbHVlLmxlbmd0aCA9PT0gMCkge1xuICAgICAgICAgIHF1ZXJ5LndoZXJlKFwiMT0wXCIpXG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgcXVlcnkud2hlcmUoYCR7Y29sdW1uU3FsfSBJTiAoJHtzZWFyY2gudmFsdWUubWFwKChlbnRyeSkgPT4gcXVlcnkuZHJpdmVyLnF1b3RlKGVudHJ5KSkuam9pbihcIiwgXCIpfSlgKVxuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuXG4gICAgICB9XG5cbiAgICAgIGlmIChzZWFyY2gudmFsdWUgPT09IG51bGwpIHtcbiAgICAgICAgcXVlcnkud2hlcmUoYCR7Y29sdW1uU3FsfSBJUyBOVUxMYClcbiAgICAgICAgcmV0dXJuXG4gICAgICB9XG4gICAgfVxuXG4gICAgaWYgKHNlYXJjaC5vcGVyYXRvciA9PT0gXCJub3RFcVwiKSB7XG4gICAgICBpZiAoQXJyYXkuaXNBcnJheShzZWFyY2gudmFsdWUpKSB7XG4gICAgICAgIGlmIChzZWFyY2gudmFsdWUubGVuZ3RoID09PSAwKSB7XG4gICAgICAgICAgcXVlcnkud2hlcmUoXCIxPTFcIilcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBxdWVyeS53aGVyZShgJHtjb2x1bW5TcWx9IE5PVCBJTiAoJHtzZWFyY2gudmFsdWUubWFwKChlbnRyeSkgPT4gcXVlcnkuZHJpdmVyLnF1b3RlKGVudHJ5KSkuam9pbihcIiwgXCIpfSlgKVxuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuXG4gICAgICB9XG5cbiAgICAgIGlmIChzZWFyY2gudmFsdWUgPT09IG51bGwpIHtcbiAgICAgICAgcXVlcnkud2hlcmUoYCR7Y29sdW1uU3FsfSBJUyBOT1QgTlVMTGApXG4gICAgICAgIHJldHVyblxuICAgICAgfVxuICAgIH1cblxuICAgIHF1ZXJ5LndoZXJlKGAke2NvbHVtblNxbH0gJHtzcWxPcGVyYXRvcn0gJHtxdWVyeS5kcml2ZXIucXVvdGUoc2VhcmNoLnZhbHVlKX1gKVxuICB9XG5cbiAgLyoqXG4gICAqIEBwYXJhbSB7b2JqZWN0fSBhcmdzIC0gUGFnaW5hdGlvbiBhcmdzLlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4vZGF0YWJhc2UvcXVlcnkvbW9kZWwtY2xhc3MtcXVlcnkuanNcIikuZGVmYXVsdH0gYXJncy5xdWVyeSAtIFF1ZXJ5IGluc3RhbmNlLlxuICAgKiBAcGFyYW0ge0Zyb250ZW5kTW9kZWxQYWdpbmF0aW9ufSBhcmdzLnBhZ2luYXRpb24gLSBQYWdpbmF0aW9uIHZhbHVlcy5cbiAgICogQHJldHVybnMge3ZvaWR9XG4gICAqL1xuICBhcHBseUZyb250ZW5kTW9kZWxQYWdpbmF0aW9uKHtxdWVyeSwgcGFnaW5hdGlvbn0pIHtcbiAgICBpZiAocGFnaW5hdGlvbi5saW1pdCAhPT0gbnVsbCkge1xuICAgICAgcXVlcnkubGltaXQocGFnaW5hdGlvbi5saW1pdClcbiAgICB9XG5cbiAgICBpZiAocGFnaW5hdGlvbi5vZmZzZXQgIT09IG51bGwpIHtcbiAgICAgIHF1ZXJ5Lm9mZnNldChwYWdpbmF0aW9uLm9mZnNldClcbiAgICB9XG5cbiAgICBpZiAocGFnaW5hdGlvbi5wZXJQYWdlICE9PSBudWxsKSB7XG4gICAgICBxdWVyeS5wZXJQYWdlKHBhZ2luYXRpb24ucGVyUGFnZSlcbiAgICB9XG5cbiAgICBpZiAocGFnaW5hdGlvbi5wYWdlICE9PSBudWxsKSB7XG4gICAgICBxdWVyeS5wYWdlKHBhZ2luYXRpb24ucGFnZSlcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogQHBhcmFtIHtvYmplY3R9IGFyZ3MgLSBXaGVyZSBhcmdzLlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4vZGF0YWJhc2UvcXVlcnkvbW9kZWwtY2xhc3MtcXVlcnkuanNcIikuZGVmYXVsdH0gYXJncy5xdWVyeSAtIFF1ZXJ5IGluc3RhbmNlLlxuICAgKiBAcGFyYW0ge1JlY29yZDxzdHJpbmcsIGFueT59IGFyZ3Mud2hlcmUgLSBSb290LW1vZGVsIHdoZXJlIGNvbmRpdGlvbnMuXG4gICAqIEByZXR1cm5zIHt2b2lkfVxuICAgKi9cbiAgYXBwbHlGcm9udGVuZE1vZGVsV2hlcmUoe3F1ZXJ5LCB3aGVyZX0pIHtcbiAgICB0aGlzLmFwcGx5RnJvbnRlbmRNb2RlbFdoZXJlRm9yUGF0aCh7XG4gICAgICBtb2RlbENsYXNzOiB0aGlzLmZyb250ZW5kTW9kZWxDbGFzcygpLFxuICAgICAgcGF0aDogW10sXG4gICAgICBxdWVyeSxcbiAgICAgIHdoZXJlXG4gICAgfSlcbiAgfVxuXG4gIC8qKlxuICAgKiBAcGFyYW0ge29iamVjdH0gYXJncyAtIEpvaW5zIGFyZ3MuXG4gICAqIEBwYXJhbSB7UmVjb3JkPHN0cmluZywgYW55Pn0gYXJncy5qb2lucyAtIFJlbGF0aW9uc2hpcC1vYmplY3Qgam9pbnMuXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi9kYXRhYmFzZS9xdWVyeS9tb2RlbC1jbGFzcy1xdWVyeS5qc1wiKS5kZWZhdWx0fSBhcmdzLnF1ZXJ5IC0gUXVlcnkgaW5zdGFuY2UuXG4gICAqIEByZXR1cm5zIHt2b2lkfVxuICAgKi9cbiAgYXBwbHlGcm9udGVuZE1vZGVsSm9pbnMoe2pvaW5zLCBxdWVyeX0pIHtcbiAgICBjb25zdCBqb2luUGF0aEtleXMgPSBuZXcgU2V0KClcblxuICAgIHRoaXMuYXBwbHlGcm9udGVuZE1vZGVsSm9pbnNGb3JQYXRoKHtcbiAgICAgIGpvaW5zLFxuICAgICAgam9pblBhdGhLZXlzLFxuICAgICAgbW9kZWxDbGFzczogdGhpcy5mcm9udGVuZE1vZGVsQ2xhc3MoKSxcbiAgICAgIHBhdGg6IFtdLFxuICAgICAgcXVlcnlcbiAgICB9KVxuXG4gICAgcXVlcnkuam9pbnMoam9pbnMpXG5cbiAgICBjb25zdCBxdWVyeU1ldGFkYXRhID0gZnJvbnRlbmRNb2RlbFF1ZXJ5TWV0YWRhdGEocXVlcnkpXG4gICAgY29uc3Qgam9pbmVkUGF0aHMgPSBxdWVyeU1ldGFkYXRhW2Zyb250ZW5kTW9kZWxKb2luZWRQYXRoc1N5bWJvbF0gfHwgbmV3IFNldCgpXG5cbiAgICBmb3IgKGNvbnN0IGpvaW5QYXRoS2V5IG9mIGpvaW5QYXRoS2V5cykge1xuICAgICAgam9pbmVkUGF0aHMuYWRkKGpvaW5QYXRoS2V5KVxuICAgIH1cblxuICAgIHF1ZXJ5TWV0YWRhdGFbZnJvbnRlbmRNb2RlbEpvaW5lZFBhdGhzU3ltYm9sXSA9IGpvaW5lZFBhdGhzXG4gIH1cblxuICAvKipcbiAgICogQHBhcmFtIHtvYmplY3R9IGFyZ3MgLSBKb2lucyBhcmdzLlxuICAgKiBAcGFyYW0ge1JlY29yZDxzdHJpbmcsIGFueT59IGFyZ3Muam9pbnMgLSBKb2lucyBmb3IgY3VycmVudCBwYXRoLlxuICAgKiBAcGFyYW0ge1NldDxzdHJpbmc+fSBhcmdzLmpvaW5QYXRoS2V5cyAtIEpvaW5lZCBwYXRoIGtleXMuXG4gICAqIEBwYXJhbSB7dHlwZW9mIGltcG9ydChcIi4vZGF0YWJhc2UvcmVjb3JkL2luZGV4LmpzXCIpLmRlZmF1bHR9IGFyZ3MubW9kZWxDbGFzcyAtIE1vZGVsIGNsYXNzIGZvciBjdXJyZW50IHBhdGguXG4gICAqIEBwYXJhbSB7c3RyaW5nW119IGFyZ3MucGF0aCAtIFJlbGF0aW9uc2hpcCBwYXRoLlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4vZGF0YWJhc2UvcXVlcnkvbW9kZWwtY2xhc3MtcXVlcnkuanNcIikuZGVmYXVsdH0gYXJncy5xdWVyeSAtIFF1ZXJ5IGluc3RhbmNlLlxuICAgKiBAcmV0dXJucyB7dm9pZH1cbiAgICovXG4gIGFwcGx5RnJvbnRlbmRNb2RlbEpvaW5zRm9yUGF0aCh7am9pbnMsIGpvaW5QYXRoS2V5cywgbW9kZWxDbGFzcywgcGF0aCwgcXVlcnl9KSB7XG4gICAgdm9pZCBxdWVyeVxuXG4gICAgZm9yIChjb25zdCBbcmVsYXRpb25zaGlwTmFtZSwgcmVsYXRpb25zaGlwSm9pbl0gb2YgT2JqZWN0LmVudHJpZXMoam9pbnMpKSB7XG4gICAgICBjb25zdCByZWxhdGlvbnNoaXAgPSBtb2RlbENsYXNzLmdldFJlbGF0aW9uc2hpcHNNYXAoKVtyZWxhdGlvbnNoaXBOYW1lXVxuXG4gICAgICBpZiAoIXJlbGF0aW9uc2hpcCkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYFVua25vd24gam9pbiByZWxhdGlvbnNoaXAgXCIke3JlbGF0aW9uc2hpcE5hbWV9XCIgZm9yICR7bW9kZWxDbGFzcy5uYW1lfWApXG4gICAgICB9XG5cbiAgICAgIGNvbnN0IHRhcmdldE1vZGVsQ2xhc3MgPSByZWxhdGlvbnNoaXAuZ2V0VGFyZ2V0TW9kZWxDbGFzcygpXG5cbiAgICAgIGlmICghdGFyZ2V0TW9kZWxDbGFzcykge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYE5vIHRhcmdldCBtb2RlbCBjbGFzcyBmb3Igam9pbiByZWxhdGlvbnNoaXAgXCIke3JlbGF0aW9uc2hpcE5hbWV9XCIgb24gJHttb2RlbENsYXNzLm5hbWV9YClcbiAgICAgIH1cblxuICAgICAgY29uc3QgcmVsYXRpb25zaGlwUGF0aCA9IFsuLi5wYXRoLCByZWxhdGlvbnNoaXBOYW1lXVxuICAgICAgam9pblBhdGhLZXlzLmFkZChyZWxhdGlvbnNoaXBQYXRoLmpvaW4oXCIuXCIpKVxuXG4gICAgICBpZiAocmVsYXRpb25zaGlwSm9pbiA9PT0gdHJ1ZSkgY29udGludWVcblxuICAgICAgdGhpcy5hcHBseUZyb250ZW5kTW9kZWxKb2luc0ZvclBhdGgoe1xuICAgICAgICBqb2luczogcmVsYXRpb25zaGlwSm9pbixcbiAgICAgICAgam9pblBhdGhLZXlzLFxuICAgICAgICBtb2RlbENsYXNzOiB0YXJnZXRNb2RlbENsYXNzLFxuICAgICAgICBwYXRoOiByZWxhdGlvbnNoaXBQYXRoLFxuICAgICAgICBxdWVyeVxuICAgICAgfSlcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogUmVzb2x2ZXMgYSBrZXkgdGhhdCBtYXkgYmUgZWl0aGVyIGEgY2FtZWxDYXNlIGF0dHJpYnV0ZSBuYW1lIG9yIGEgcmF3IERCXG4gICAqIGNvbHVtbiBuYW1lIHRvIGl0cyBjYW5vbmljYWwgY29sdW1uIG5hbWUuICBSZXR1cm5zIGB1bmRlZmluZWRgIHdoZW4gdGhlXG4gICAqIGtleSBtYXRjaGVzIG5laXRoZXIgbWFwLlxuICAgKlxuICAgKiBAcGFyYW0ge3R5cGVvZiBpbXBvcnQoXCIuL2RhdGFiYXNlL3JlY29yZC9pbmRleC5qc1wiKS5kZWZhdWx0fSBtb2RlbENsYXNzIC0gTW9kZWwgY2xhc3MuXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBrZXkgLSBBdHRyaWJ1dGUgbmFtZSBvciBjb2x1bW4gbmFtZSB0byByZXNvbHZlLlxuICAgKiBAcmV0dXJucyB7c3RyaW5nIHwgdW5kZWZpbmVkfSAtIFJlc29sdmVkIERCIGNvbHVtbiBuYW1lLCBvciBgdW5kZWZpbmVkYC5cbiAgICovXG4gIHJlc29sdmVGcm9udGVuZE1vZGVsQ29sdW1uTmFtZShtb2RlbENsYXNzLCBrZXkpIHtcbiAgICBjb25zdCBhdHRyaWJ1dGVOYW1lVG9Db2x1bW5OYW1lTWFwID0gbW9kZWxDbGFzcy5nZXRBdHRyaWJ1dGVOYW1lVG9Db2x1bW5OYW1lTWFwKClcbiAgICBjb25zdCBjb2x1bW5OYW1lID0gYXR0cmlidXRlTmFtZVRvQ29sdW1uTmFtZU1hcFtrZXldXG5cbiAgICBpZiAoY29sdW1uTmFtZSkgcmV0dXJuIGNvbHVtbk5hbWVcblxuICAgIC8vIEZhbGwgYmFjazogY2hlY2sgd2hldGhlciB0aGUga2V5IGlzIGFscmVhZHkgYSByYXcgREIgY29sdW1uIG5hbWUuXG4gICAgY29uc3QgY29sdW1uTmFtZVRvQXR0cmlidXRlTmFtZU1hcCA9IG1vZGVsQ2xhc3MuZ2V0Q29sdW1uTmFtZVRvQXR0cmlidXRlTmFtZU1hcCgpXG5cbiAgICBpZiAoY29sdW1uTmFtZVRvQXR0cmlidXRlTmFtZU1hcFtrZXldKSByZXR1cm4ga2V5XG5cbiAgICByZXR1cm4gdW5kZWZpbmVkXG4gIH1cblxuICAvKipcbiAgICogQHBhcmFtIHtvYmplY3R9IGFyZ3MgLSBXaGVyZSBhcmdzLlxuICAgKiBAcGFyYW0ge3R5cGVvZiBpbXBvcnQoXCIuL2RhdGFiYXNlL3JlY29yZC9pbmRleC5qc1wiKS5kZWZhdWx0fSBhcmdzLm1vZGVsQ2xhc3MgLSBNb2RlbCBjbGFzcyBmb3IgY3VycmVudCB3aGVyZSBzY29wZS5cbiAgICogQHBhcmFtIHtzdHJpbmdbXX0gYXJncy5wYXRoIC0gUmVsYXRpb25zaGlwIHBhdGggZnJvbSByb290LlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4vZGF0YWJhc2UvcXVlcnkvbW9kZWwtY2xhc3MtcXVlcnkuanNcIikuZGVmYXVsdH0gYXJncy5xdWVyeSAtIFF1ZXJ5IGluc3RhbmNlLlxuICAgKiBAcGFyYW0ge1JlY29yZDxzdHJpbmcsIGFueT59IGFyZ3Mud2hlcmUgLSBXaGVyZSBjb25kaXRpb25zIGZvciBjdXJyZW50IHNjb3BlLlxuICAgKiBAcmV0dXJucyB7dm9pZH1cbiAgICovXG4gIGFwcGx5RnJvbnRlbmRNb2RlbFdoZXJlRm9yUGF0aCh7bW9kZWxDbGFzcywgcGF0aCwgcXVlcnksIHdoZXJlfSkge1xuICAgIGZvciAoY29uc3QgW2F0dHJpYnV0ZU5hbWUsIHZhbHVlXSBvZiBPYmplY3QuZW50cmllcyh3aGVyZSkpIHtcbiAgICAgIGNvbnN0IGNvbHVtbk5hbWUgPSB0aGlzLnJlc29sdmVGcm9udGVuZE1vZGVsQ29sdW1uTmFtZShtb2RlbENsYXNzLCBhdHRyaWJ1dGVOYW1lKVxuXG4gICAgICBpZiAoY29sdW1uTmFtZSkge1xuICAgICAgICB0aGlzLmVuc3VyZUZyb250ZW5kTW9kZWxKb2luUGF0aCh7cGF0aCwgcXVlcnl9KVxuXG4gICAgICAgIGNvbnN0IHRhYmxlUmVmZXJlbmNlID0gcXVlcnkuZ2V0VGFibGVSZWZlcmVuY2VGb3JKb2luKC4uLnBhdGgpXG4gICAgICAgIGNvbnN0IGNvbHVtblNxbCA9IGAke3F1ZXJ5LmRyaXZlci5xdW90ZVRhYmxlKHRhYmxlUmVmZXJlbmNlKX0uJHtxdWVyeS5kcml2ZXIucXVvdGVDb2x1bW4oY29sdW1uTmFtZSl9YFxuXG4gICAgICAgIGlmIChBcnJheS5pc0FycmF5KHZhbHVlKSkge1xuICAgICAgICAgIGlmICh2YWx1ZS5sZW5ndGggPT09IDApIHtcbiAgICAgICAgICAgIHF1ZXJ5LndoZXJlKFwiMT0wXCIpXG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGNvbnN0IG5vcm1hbGl6ZWRWYWx1ZXMgPSB2YWx1ZS5tYXAoKGVudHJ5KSA9PiB0aGlzLm5vcm1hbGl6ZUZyb250ZW5kTW9kZWxXaGVyZUNvbHVtblZhbHVlKHtjb2x1bW5OYW1lLCBtb2RlbENsYXNzLCB2YWx1ZTogZW50cnl9KSlcblxuICAgICAgICAgICAgaWYgKG5vcm1hbGl6ZWRWYWx1ZXMuaW5jbHVkZXMoZnJvbnRlbmRNb2RlbFdoZXJlTm9NYXRjaFN5bWJvbCkpIHtcbiAgICAgICAgICAgICAgcXVlcnkud2hlcmUoXCIxPTBcIilcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgIHF1ZXJ5LndoZXJlKGAke2NvbHVtblNxbH0gSU4gKCR7bm9ybWFsaXplZFZhbHVlcy5tYXAoKGVudHJ5KSA9PiBxdWVyeS5kcml2ZXIucXVvdGUoZW50cnkpKS5qb2luKFwiLCBcIil9KWApXG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgY29udGludWVcbiAgICAgICAgfVxuXG4gICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7XG4gICAgICAgICAgcXVlcnkud2hlcmUoYCR7Y29sdW1uU3FsfSBJUyBOVUxMYClcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBjb25zdCBub3JtYWxpemVkVmFsdWUgPSB0aGlzLm5vcm1hbGl6ZUZyb250ZW5kTW9kZWxXaGVyZUNvbHVtblZhbHVlKHtjb2x1bW5OYW1lLCBtb2RlbENsYXNzLCB2YWx1ZX0pXG5cbiAgICAgICAgICBpZiAobm9ybWFsaXplZFZhbHVlID09PSBmcm9udGVuZE1vZGVsV2hlcmVOb01hdGNoU3ltYm9sKSB7XG4gICAgICAgICAgICBxdWVyeS53aGVyZShcIjE9MFwiKVxuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBxdWVyeS53aGVyZShgJHtjb2x1bW5TcWx9ID0gJHtxdWVyeS5kcml2ZXIucXVvdGUobm9ybWFsaXplZFZhbHVlKX1gKVxuICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIGNvbnRpbnVlXG4gICAgICB9XG5cbiAgICAgIGlmIChpc1BsYWluT2JqZWN0KHZhbHVlKSkge1xuICAgICAgICBjb25zdCByZWxhdGlvbnNoaXAgPSBtb2RlbENsYXNzLmdldFJlbGF0aW9uc2hpcHNNYXAoKVthdHRyaWJ1dGVOYW1lXVxuXG4gICAgICAgIGlmICghcmVsYXRpb25zaGlwKSB7XG4gICAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBVbmtub3duIHdoZXJlIHJlbGF0aW9uc2hpcCBcIiR7YXR0cmlidXRlTmFtZX1cIiBmb3IgJHttb2RlbENsYXNzLm5hbWV9YClcbiAgICAgICAgfVxuXG4gICAgICAgIGNvbnN0IHRhcmdldE1vZGVsQ2xhc3MgPSByZWxhdGlvbnNoaXAuZ2V0VGFyZ2V0TW9kZWxDbGFzcygpXG5cbiAgICAgICAgaWYgKCF0YXJnZXRNb2RlbENsYXNzKSB7XG4gICAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBObyB0YXJnZXQgbW9kZWwgY2xhc3MgZm9yIHdoZXJlIHJlbGF0aW9uc2hpcCBcIiR7YXR0cmlidXRlTmFtZX1cIiBvbiAke21vZGVsQ2xhc3MubmFtZX1gKVxuICAgICAgICB9XG5cbiAgICAgICAgY29uc3QgcmVsYXRpb25zaGlwUGF0aCA9IFsuLi5wYXRoLCBhdHRyaWJ1dGVOYW1lXVxuXG4gICAgICAgIHRoaXMuYXBwbHlGcm9udGVuZE1vZGVsV2hlcmVGb3JQYXRoKHtcbiAgICAgICAgICBtb2RlbENsYXNzOiB0YXJnZXRNb2RlbENsYXNzLFxuICAgICAgICAgIHBhdGg6IHJlbGF0aW9uc2hpcFBhdGgsXG4gICAgICAgICAgcXVlcnksXG4gICAgICAgICAgd2hlcmU6IHZhbHVlXG4gICAgICAgIH0pXG5cbiAgICAgICAgY29udGludWVcbiAgICAgIH1cblxuICAgICAgdGhyb3cgbmV3IEVycm9yKGBVbmtub3duIHdoZXJlIGNvbHVtbiBcIiR7YXR0cmlidXRlTmFtZX1cIiBmb3IgJHttb2RlbENsYXNzLm5hbWV9YClcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogQHBhcmFtIHtvYmplY3R9IGFyZ3MgLSBBcmdzLlxuICAgKiBAcGFyYW0ge3R5cGVvZiBpbXBvcnQoXCIuL2RhdGFiYXNlL3JlY29yZC9pbmRleC5qc1wiKS5kZWZhdWx0fSBhcmdzLm1vZGVsQ2xhc3MgLSBNb2RlbCBjbGFzcy5cbiAgICogQHBhcmFtIHtzdHJpbmd9IGFyZ3MuY29sdW1uTmFtZSAtIENvbHVtbiBuYW1lLlxuICAgKiBAcGFyYW0ge3Vua25vd259IGFyZ3MudmFsdWUgLSBXaGVyZSB2YWx1ZS5cbiAgICogQHJldHVybnMge3Vua25vd24gfCBzeW1ib2x9IC0gU1FMLXNhZmUgd2hlcmUgdmFsdWUuXG4gICAqL1xuICBub3JtYWxpemVGcm9udGVuZE1vZGVsV2hlcmVDb2x1bW5WYWx1ZSh7Y29sdW1uTmFtZSwgbW9kZWxDbGFzcywgdmFsdWV9KSB7XG4gICAgaWYgKHR5cGVvZiB2YWx1ZSA9PT0gXCJzdHJpbmdcIikge1xuICAgICAgY29uc3QgY29sdW1uVHlwZSA9IG1vZGVsQ2xhc3MuZ2V0Q29sdW1uVHlwZUJ5TmFtZShjb2x1bW5OYW1lKT8udG9Mb3dlckNhc2UoKVxuICAgICAgY29uc3QgaXNEYXRlVGltZUNvbHVtbiA9IHR5cGVvZiBjb2x1bW5UeXBlID09PSBcInN0cmluZ1wiICYmIFtcImRhdGVcIiwgXCJkYXRldGltZVwiLCBcInRpbWVzdGFtcFwiXS5zb21lKCh0eXBlKSA9PiBjb2x1bW5UeXBlLmluY2x1ZGVzKHR5cGUpKVxuXG4gICAgICBpZiAoaXNEYXRlVGltZUNvbHVtbikge1xuICAgICAgICBjb25zdCBwYXJzZWREYXRlID0gbmV3IERhdGUodmFsdWUpXG5cbiAgICAgICAgaWYgKCFOdW1iZXIuaXNOYU4ocGFyc2VkRGF0ZS5nZXRUaW1lKCkpKSB7XG4gICAgICAgICAgcmV0dXJuIHBhcnNlZERhdGVcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cblxuICAgIGlmIChpc1BsYWluT2JqZWN0KHZhbHVlKSkge1xuICAgICAgY29uc3QgY29sdW1uVHlwZSA9IG1vZGVsQ2xhc3MuZ2V0Q29sdW1uVHlwZUJ5TmFtZShjb2x1bW5OYW1lKVxuXG4gICAgICBpZiAodHlwZW9mIGNvbHVtblR5cGUgIT09IFwic3RyaW5nXCIpIHtcbiAgICAgICAgcmV0dXJuIGZyb250ZW5kTW9kZWxXaGVyZU5vTWF0Y2hTeW1ib2xcbiAgICAgIH1cblxuICAgICAgY29uc3Qgbm9ybWFsaXplZFR5cGUgPSBjb2x1bW5UeXBlLnRvTG93ZXJDYXNlKClcbiAgICAgIGNvbnN0IG9iamVjdFZhbHVlVHlwZXMgPSBuZXcgU2V0KFtcImNoYXJcIiwgXCJ2YXJjaGFyXCIsIFwibnZhcmNoYXJcIiwgXCJzdHJpbmdcIiwgXCJlbnVtXCIsIFwianNvblwiLCBcImpzb25iXCIsIFwiY2l0ZXh0XCIsIFwiYmluYXJ5XCIsIFwidmFyYmluYXJ5XCJdKVxuICAgICAgY29uc3Qgc3VwcG9ydHNPYmplY3RWYWx1ZXMgPSBub3JtYWxpemVkVHlwZS5pbmNsdWRlcyhcInRleHRcIikgfHwgb2JqZWN0VmFsdWVUeXBlcy5oYXMobm9ybWFsaXplZFR5cGUpXG5cbiAgICAgIGlmICghc3VwcG9ydHNPYmplY3RWYWx1ZXMpIHtcbiAgICAgICAgcmV0dXJuIGZyb250ZW5kTW9kZWxXaGVyZU5vTWF0Y2hTeW1ib2xcbiAgICAgIH1cblxuICAgICAgcmV0dXJuIEpTT04uc3RyaW5naWZ5KHZhbHVlKVxuICAgIH1cblxuICAgIHJldHVybiB2YWx1ZVxuICB9XG5cbiAgLyoqXG4gICAqIEBwYXJhbSB7b2JqZWN0fSBhcmdzIC0gR3JvdXAgYXJncy5cbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuL2RhdGFiYXNlL3F1ZXJ5L21vZGVsLWNsYXNzLXF1ZXJ5LmpzXCIpLmRlZmF1bHR9IGFyZ3MucXVlcnkgLSBRdWVyeSBpbnN0YW5jZS5cbiAgICogQHBhcmFtIHtGcm9udGVuZE1vZGVsR3JvdXB9IGFyZ3MuZ3JvdXAgLSBHcm91cCBkZWZpbml0aW9uLlxuICAgKiBAcmV0dXJucyB7dm9pZH1cbiAgICovXG4gIGFwcGx5RnJvbnRlbmRNb2RlbEdyb3VwKHtxdWVyeSwgZ3JvdXB9KSB7XG4gICAgY29uc3QgbW9kZWxDbGFzcyA9IHRoaXMuZnJvbnRlbmRNb2RlbENsYXNzKClcbiAgICBjb25zdCB0YXJnZXRNb2RlbENsYXNzID0gdGhpcy5mcm9udGVuZE1vZGVsU2VhcmNoVGFyZ2V0TW9kZWxDbGFzcyh7XG4gICAgICBtb2RlbENsYXNzLFxuICAgICAgcGF0aDogZ3JvdXAucGF0aFxuICAgIH0pXG4gICAgY29uc3QgY29sdW1uTmFtZSA9IHRoaXMucmVzb2x2ZUZyb250ZW5kTW9kZWxDb2x1bW5OYW1lKHRhcmdldE1vZGVsQ2xhc3MsIGdyb3VwLmNvbHVtbilcblxuICAgIGlmICghY29sdW1uTmFtZSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKGBVbmtub3duIGdyb3VwIGNvbHVtbiBcIiR7Z3JvdXAuY29sdW1ufVwiIGZvciAke3RhcmdldE1vZGVsQ2xhc3MubmFtZX1gKVxuICAgIH1cblxuICAgIHRoaXMuZW5zdXJlRnJvbnRlbmRNb2RlbEpvaW5QYXRoKHtwYXRoOiBncm91cC5wYXRoLCBxdWVyeX0pXG5cbiAgICBjb25zdCB0YWJsZVJlZmVyZW5jZSA9IHF1ZXJ5LmdldFRhYmxlUmVmZXJlbmNlRm9ySm9pbiguLi5ncm91cC5wYXRoKVxuICAgIGNvbnN0IGNvbHVtblNxbCA9IGAke3F1ZXJ5LmRyaXZlci5xdW90ZVRhYmxlKHRhYmxlUmVmZXJlbmNlKX0uJHtxdWVyeS5kcml2ZXIucXVvdGVDb2x1bW4oY29sdW1uTmFtZSl9YFxuXG4gICAgdGhpcy5lbnN1cmVGcm9udGVuZE1vZGVsR3JvdXBDb2x1bW4oe2NvbHVtblNxbCwgcXVlcnl9KVxuICB9XG5cbiAgLyoqXG4gICAqIEFkZHMgcm9vdC1tb2RlbCBjb2x1bW5zIHRvIEdST1VQIEJZIHNvIHN0cmljdCBTUUwgZW5naW5lcyBhY2NlcHQgZGVmYXVsdCByb290LXRhYmxlIHNlbGVjdHMuXG4gICAqIEBwYXJhbSB7b2JqZWN0fSBhcmdzIC0gQXJncy5cbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuL2RhdGFiYXNlL3F1ZXJ5L21vZGVsLWNsYXNzLXF1ZXJ5LmpzXCIpLmRlZmF1bHR9IGFyZ3MucXVlcnkgLSBRdWVyeSBpbnN0YW5jZS5cbiAgICogQHJldHVybnMge3ZvaWR9XG4gICAqL1xuICBhcHBseUZyb250ZW5kTW9kZWxSb290R3JvdXBDb2x1bW5zKHtxdWVyeX0pIHtcbiAgICBjb25zdCBtb2RlbENsYXNzID0gdGhpcy5mcm9udGVuZE1vZGVsQ2xhc3MoKVxuICAgIGNvbnN0IGF0dHJpYnV0ZU5hbWVUb0NvbHVtbk5hbWVNYXAgPSBtb2RlbENsYXNzLmdldEF0dHJpYnV0ZU5hbWVUb0NvbHVtbk5hbWVNYXAoKVxuICAgIGNvbnN0IHJvb3RUYWJsZVJlZmVyZW5jZSA9IHF1ZXJ5LmdldFRhYmxlUmVmZXJlbmNlRm9ySm9pbigpXG5cbiAgICBmb3IgKGNvbnN0IGNvbHVtbk5hbWUgb2YgT2JqZWN0LnZhbHVlcyhhdHRyaWJ1dGVOYW1lVG9Db2x1bW5OYW1lTWFwKSkge1xuICAgICAgY29uc3QgY29sdW1uU3FsID0gYCR7cXVlcnkuZHJpdmVyLnF1b3RlVGFibGUocm9vdFRhYmxlUmVmZXJlbmNlKX0uJHtxdWVyeS5kcml2ZXIucXVvdGVDb2x1bW4oY29sdW1uTmFtZSl9YFxuXG4gICAgICB0aGlzLmVuc3VyZUZyb250ZW5kTW9kZWxHcm91cENvbHVtbih7Y29sdW1uU3FsLCBxdWVyeX0pXG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIEVuc3VyZXMgYSBncm91cC1ieSBTUUwgY29sdW1uIGlzIG9ubHkgYXBwZW5kZWQgb25jZS5cbiAgICogQHBhcmFtIHtvYmplY3R9IGFyZ3MgLSBBcmdzLlxuICAgKiBAcGFyYW0ge3N0cmluZ30gYXJncy5jb2x1bW5TcWwgLSBGdWxseS1xdWFsaWZpZWQgY29sdW1uIFNRTC5cbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuL2RhdGFiYXNlL3F1ZXJ5L21vZGVsLWNsYXNzLXF1ZXJ5LmpzXCIpLmRlZmF1bHR9IGFyZ3MucXVlcnkgLSBRdWVyeSBpbnN0YW5jZS5cbiAgICogQHJldHVybnMge3ZvaWR9XG4gICAqL1xuICBlbnN1cmVGcm9udGVuZE1vZGVsR3JvdXBDb2x1bW4oe2NvbHVtblNxbCwgcXVlcnl9KSB7XG4gICAgY29uc3QgcXVlcnlNZXRhZGF0YSA9IGZyb250ZW5kTW9kZWxRdWVyeU1ldGFkYXRhKHF1ZXJ5KVxuICAgIGNvbnN0IGdyb3VwZWRDb2x1bW5zID0gcXVlcnlNZXRhZGF0YVtmcm9udGVuZE1vZGVsR3JvdXBlZENvbHVtbnNTeW1ib2xdIHx8IG5ldyBTZXQoKVxuXG4gICAgaWYgKGdyb3VwZWRDb2x1bW5zLmhhcyhjb2x1bW5TcWwpKSByZXR1cm5cblxuICAgIHF1ZXJ5Lmdyb3VwKGNvbHVtblNxbClcbiAgICBncm91cGVkQ29sdW1ucy5hZGQoY29sdW1uU3FsKVxuICAgIHF1ZXJ5TWV0YWRhdGFbZnJvbnRlbmRNb2RlbEdyb3VwZWRDb2x1bW5zU3ltYm9sXSA9IGdyb3VwZWRDb2x1bW5zXG4gIH1cblxuICAvKipcbiAgICogQHBhcmFtIHtvYmplY3R9IGFyZ3MgLSBBcmdzLlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4vZGF0YWJhc2UvcXVlcnkvbW9kZWwtY2xhc3MtcXVlcnkuanNcIikuZGVmYXVsdDxhbnk+fSBhcmdzLnF1ZXJ5IC0gUXVlcnkgaW5zdGFuY2UuXG4gICAqIEByZXR1cm5zIHtpbXBvcnQoXCIuL2RhdGFiYXNlL3F1ZXJ5L21vZGVsLWNsYXNzLXF1ZXJ5LmpzXCIpLmRlZmF1bHQ8YW55Pn0gLSBRdWVyeSB3aXRoIHRyYW5zbGF0aW9ucyBwcmVsb2FkZWQgaWYgbmVlZGVkLlxuICAgKi9cbiAgYXBwbHlGcm9udGVuZE1vZGVsVHJhbnNsYXRlZEF0dHJpYnV0ZVByZWxvYWRzKHtxdWVyeX0pIHtcbiAgICBjb25zdCBtb2RlbENsYXNzID0gdGhpcy5mcm9udGVuZE1vZGVsQ2xhc3MoKVxuICAgIGNvbnN0IHNlbGVjdGVkQXR0cmlidXRlcyA9IHRoaXMuZnJvbnRlbmRNb2RlbEVmZmVjdGl2ZVNlbGVjdGVkQXR0cmlidXRlc0Zvck1vZGVsQ2xhc3MobW9kZWxDbGFzcywgdGhpcy5mcm9udGVuZE1vZGVsRGVmYXVsdEF0dHJpYnV0ZXNGb3JNb2RlbENsYXNzKG1vZGVsQ2xhc3MpIHx8IFtdKVxuICAgICAgfHwgdGhpcy5mcm9udGVuZE1vZGVsRGVmYXVsdEF0dHJpYnV0ZXNGb3JNb2RlbENsYXNzKG1vZGVsQ2xhc3MpXG5cbiAgICBpZiAoIXNlbGVjdGVkQXR0cmlidXRlcykgcmV0dXJuIHF1ZXJ5XG5cbiAgICBjb25zdCByZXNvdXJjZSA9IHRoaXMuZnJvbnRlbmRNb2RlbFJlc291cmNlSW5zdGFuY2UoKVxuICAgIGNvbnN0IHJlc291cmNlQ2xhc3MgPSAvKiogQHR5cGUge3R5cGVvZiBpbXBvcnQoXCIuL2Zyb250ZW5kLW1vZGVsLXJlc291cmNlL2Jhc2UtcmVzb3VyY2UuanNcIikuZGVmYXVsdH0gKi8gKHJlc291cmNlLmNvbnN0cnVjdG9yKVxuICAgIGNvbnN0IHRyYW5zbGF0ZWRTZXQgPSBuZXcgU2V0KHJlc291cmNlQ2xhc3MudHJhbnNsYXRlZEF0dHJpYnV0ZXMgfHwgW10pXG4gICAgbGV0IG5lZWRzVHJhbnNsYXRpb25zID0gZmFsc2VcblxuICAgIGZvciAoY29uc3QgYXR0cmlidXRlTmFtZSBvZiBzZWxlY3RlZEF0dHJpYnV0ZXMpIHtcbiAgICAgIGNvbnN0IGhvb2tOYW1lID0gYCR7YXR0cmlidXRlTmFtZX1BdHRyaWJ1dGVTZWxlY3RlZGBcbiAgICAgIGNvbnN0IGR5bmFtaWNSZXNvdXJjZSA9IC8qKiBAdHlwZSB7UmVjb3JkPHN0cmluZywgYW55Pn0gKi8gKC8qKiBAdHlwZSB7dW5rbm93bn0gKi8gKHJlc291cmNlKSlcblxuICAgICAgaWYgKHR5cGVvZiBkeW5hbWljUmVzb3VyY2VbaG9va05hbWVdID09PSBcImZ1bmN0aW9uXCIpIHtcbiAgICAgICAgY29uc3QgcmVzdWx0ID0gZHluYW1pY1Jlc291cmNlW2hvb2tOYW1lXSh7cXVlcnl9KVxuXG4gICAgICAgIGlmIChyZXN1bHQpIHtcbiAgICAgICAgICBxdWVyeSA9IHJlc3VsdFxuICAgICAgICB9XG4gICAgICB9IGVsc2UgaWYgKHRyYW5zbGF0ZWRTZXQuaGFzKGF0dHJpYnV0ZU5hbWUpKSB7XG4gICAgICAgIG5lZWRzVHJhbnNsYXRpb25zID0gdHJ1ZVxuICAgICAgfVxuICAgIH1cblxuICAgIGlmIChuZWVkc1RyYW5zbGF0aW9ucykge1xuICAgICAgcXVlcnkgPSBxdWVyeS5wcmVsb2FkKHt0cmFuc2xhdGlvbnM6IHt9fSlcbiAgICB9XG5cbiAgICByZXR1cm4gcXVlcnlcbiAgfVxuXG4gIC8qKlxuICAgKiBAcGFyYW0ge29iamVjdH0gYXJncyAtIFNvcnQgYXJncy5cbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuL2RhdGFiYXNlL3F1ZXJ5L21vZGVsLWNsYXNzLXF1ZXJ5LmpzXCIpLmRlZmF1bHR9IGFyZ3MucXVlcnkgLSBRdWVyeSBpbnN0YW5jZS5cbiAgICogQHBhcmFtIHtGcm9udGVuZE1vZGVsU29ydH0gYXJncy5zb3J0IC0gU29ydCBkZWZpbml0aW9uLlxuICAgKiBAcmV0dXJucyB7dm9pZH1cbiAgICovXG4gIGFwcGx5RnJvbnRlbmRNb2RlbFNvcnQoe3F1ZXJ5LCBzb3J0fSkge1xuICAgIGNvbnN0IG1vZGVsQ2xhc3MgPSB0aGlzLmZyb250ZW5kTW9kZWxDbGFzcygpXG4gICAgY29uc3QgdGFyZ2V0TW9kZWxDbGFzcyA9IHRoaXMuZnJvbnRlbmRNb2RlbFNlYXJjaFRhcmdldE1vZGVsQ2xhc3Moe1xuICAgICAgbW9kZWxDbGFzcyxcbiAgICAgIHBhdGg6IHNvcnQucGF0aFxuICAgIH0pXG4gICAgY29uc3QgdHJhbnNsYXRlZEF0dHJpYnV0ZXNNYXAgPSB0YXJnZXRNb2RlbENsYXNzLmdldFRyYW5zbGF0aW9uc01hcCgpXG4gICAgY29uc3QgdHJhbnNsYXRlZEF0dHJpYnV0ZU5hbWVzID0gT2JqZWN0LmtleXModHJhbnNsYXRlZEF0dHJpYnV0ZXNNYXApXG4gICAgY29uc3QgaXNUcmFuc2xhdGVkU29ydEF0dHJpYnV0ZSA9IHRyYW5zbGF0ZWRBdHRyaWJ1dGVOYW1lcy5pbmNsdWRlcyhzb3J0LmNvbHVtbilcblxuICAgIGNvbnN0IGNvbHVtbk5hbWUgPSB0aGlzLnJlc29sdmVGcm9udGVuZE1vZGVsQ29sdW1uTmFtZSh0YXJnZXRNb2RlbENsYXNzLCBzb3J0LmNvbHVtbilcbiAgICBjb25zdCBkaXJlY3Rpb24gPSBzb3J0LmRpcmVjdGlvbi50b1VwcGVyQ2FzZSgpXG5cbiAgICBpZiAoaXNUcmFuc2xhdGVkU29ydEF0dHJpYnV0ZSkge1xuICAgICAgY29uc3QgdHJhbnNsYXRpb25Nb2RlbENsYXNzID0gdGFyZ2V0TW9kZWxDbGFzcy5nZXRUcmFuc2xhdGlvbkNsYXNzKClcbiAgICAgIGNvbnN0IHRyYW5zbGF0aW9uQXR0cmlidXRlTmFtZVRvQ29sdW1uTmFtZU1hcCA9IHRyYW5zbGF0aW9uTW9kZWxDbGFzcy5nZXRBdHRyaWJ1dGVOYW1lVG9Db2x1bW5OYW1lTWFwKClcbiAgICAgIGNvbnN0IHRyYW5zbGF0aW9uQ29sdW1uTmFtZSA9IHRyYW5zbGF0aW9uQXR0cmlidXRlTmFtZVRvQ29sdW1uTmFtZU1hcFtzb3J0LmNvbHVtbl1cbiAgICAgIGNvbnN0IHRyYW5zbGF0aW9uUGF0aCA9IHNvcnQucGF0aC5jb25jYXQoW1wiY3VycmVudFRyYW5zbGF0aW9uXCJdKVxuXG4gICAgICBpZiAoIXRyYW5zbGF0aW9uQ29sdW1uTmFtZSkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYFVua25vd24gdHJhbnNsYXRlZCBzb3J0IGNvbHVtbiBcIiR7c29ydC5jb2x1bW59XCIgZm9yICR7dGFyZ2V0TW9kZWxDbGFzcy5uYW1lfWApXG4gICAgICB9XG5cbiAgICAgIHRoaXMuZW5zdXJlRnJvbnRlbmRNb2RlbFNvcnRKb2luUGF0aCh7cGF0aDogdHJhbnNsYXRpb25QYXRoLCBxdWVyeX0pXG5cbiAgICAgIGNvbnN0IHRyYW5zbGF0aW9uVGFibGVSZWZlcmVuY2UgPSBxdWVyeS5nZXRUYWJsZVJlZmVyZW5jZUZvckpvaW4oLi4udHJhbnNsYXRpb25QYXRoKVxuICAgICAgY29uc3QgdHJhbnNsYXRpb25Db2x1bW5TcWwgPSBgJHtxdWVyeS5kcml2ZXIucXVvdGVUYWJsZSh0cmFuc2xhdGlvblRhYmxlUmVmZXJlbmNlKX0uJHtxdWVyeS5kcml2ZXIucXVvdGVDb2x1bW4odHJhbnNsYXRpb25Db2x1bW5OYW1lKX1gXG5cbiAgICAgIHF1ZXJ5Lm9yZGVyKGAke3RyYW5zbGF0aW9uQ29sdW1uU3FsfSAke2RpcmVjdGlvbn1gKVxuXG4gICAgICByZXR1cm5cbiAgICB9XG5cbiAgICBpZiAoIWNvbHVtbk5hbWUpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihgVW5rbm93biBzb3J0IGNvbHVtbiBcIiR7c29ydC5jb2x1bW59XCIgZm9yICR7dGFyZ2V0TW9kZWxDbGFzcy5uYW1lfWApXG4gICAgfVxuXG4gICAgdGhpcy5lbnN1cmVGcm9udGVuZE1vZGVsU29ydEpvaW5QYXRoKHtwYXRoOiBzb3J0LnBhdGgsIHF1ZXJ5fSlcblxuICAgIGNvbnN0IHRhYmxlUmVmZXJlbmNlID0gcXVlcnkuZ2V0VGFibGVSZWZlcmVuY2VGb3JKb2luKC4uLnNvcnQucGF0aClcbiAgICBjb25zdCBjb2x1bW5TcWwgPSBgJHtxdWVyeS5kcml2ZXIucXVvdGVUYWJsZSh0YWJsZVJlZmVyZW5jZSl9LiR7cXVlcnkuZHJpdmVyLnF1b3RlQ29sdW1uKGNvbHVtbk5hbWUpfWBcblxuICAgIHF1ZXJ5Lm9yZGVyKGAke2NvbHVtblNxbH0gJHtkaXJlY3Rpb259YClcbiAgfVxuXG4gIC8qKlxuICAgKiBFbnN1cmVzIGEgc29ydCBqb2luIHBhdGggaGFzIGJlZW4gam9pbmVkIG9uIHF1ZXJ5LlxuICAgKiBAcGFyYW0ge29iamVjdH0gYXJncyAtIEpvaW4gYXJncy5cbiAgICogQHBhcmFtIHtzdHJpbmdbXX0gYXJncy5wYXRoIC0gUmVsYXRpb25zaGlwIGpvaW4gcGF0aC5cbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuL2RhdGFiYXNlL3F1ZXJ5L21vZGVsLWNsYXNzLXF1ZXJ5LmpzXCIpLmRlZmF1bHR9IGFyZ3MucXVlcnkgLSBRdWVyeSBpbnN0YW5jZS5cbiAgICogQHJldHVybnMge3ZvaWR9XG4gICAqL1xuICBlbnN1cmVGcm9udGVuZE1vZGVsU29ydEpvaW5QYXRoKHtwYXRoLCBxdWVyeX0pIHtcbiAgICB0aGlzLmVuc3VyZUZyb250ZW5kTW9kZWxKb2luUGF0aCh7cGF0aCwgcXVlcnl9KVxuICB9XG5cbiAgLyoqXG4gICAqIEVuc3VyZXMgYSByZWxhdGlvbnNoaXAgcGF0aCBoYXMgZXhhY3RseSBvbmUgU1FMIGpvaW4uXG4gICAqIEBwYXJhbSB7b2JqZWN0fSBhcmdzIC0gSm9pbiBhcmdzLlxuICAgKiBAcGFyYW0ge3N0cmluZ1tdfSBhcmdzLnBhdGggLSBSZWxhdGlvbnNoaXAgam9pbiBwYXRoLlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4vZGF0YWJhc2UvcXVlcnkvbW9kZWwtY2xhc3MtcXVlcnkuanNcIikuZGVmYXVsdH0gYXJncy5xdWVyeSAtIFF1ZXJ5IGluc3RhbmNlLlxuICAgKiBAcmV0dXJucyB7dm9pZH1cbiAgICovXG4gIGVuc3VyZUZyb250ZW5kTW9kZWxKb2luUGF0aCh7cGF0aCwgcXVlcnl9KSB7XG4gICAgaWYgKHBhdGgubGVuZ3RoIDwgMSkgcmV0dXJuXG5cbiAgICBjb25zdCBxdWVyeU1ldGFkYXRhID0gZnJvbnRlbmRNb2RlbFF1ZXJ5TWV0YWRhdGEocXVlcnkpXG4gICAgY29uc3Qgam9pbmVkUGF0aHMgPSBxdWVyeU1ldGFkYXRhW2Zyb250ZW5kTW9kZWxKb2luZWRQYXRoc1N5bWJvbF0gfHwgbmV3IFNldCgpXG4gICAgY29uc3QgcGF0aEtleSA9IHBhdGguam9pbihcIi5cIilcblxuICAgIGlmIChqb2luZWRQYXRocy5oYXMocGF0aEtleSkpIHJldHVyblxuXG4gICAgcXVlcnkuam9pbnMoYnVpbGRGcm9udGVuZE1vZGVsSm9pbk9iamVjdEZyb21QYXRoKHBhdGgpKVxuICAgIGpvaW5lZFBhdGhzLmFkZChwYXRoS2V5KVxuICAgIHF1ZXJ5TWV0YWRhdGFbZnJvbnRlbmRNb2RlbEpvaW5lZFBhdGhzU3ltYm9sXSA9IGpvaW5lZFBhdGhzXG4gIH1cblxuICAvKipcbiAgICogQHBhcmFtIHt0eXBlb2YgaW1wb3J0KFwiLi9kYXRhYmFzZS9yZWNvcmQvaW5kZXguanNcIikuZGVmYXVsdH0gbW9kZWxDbGFzcyAtIE1vZGVsIGNsYXNzLlxuICAgKiBAcmV0dXJucyB7c3RyaW5nW10gfCBudWxsfSAtIFNlbGVjdGVkIGF0dHJpYnV0ZXMgZm9yIG1vZGVsIGNsYXNzLlxuICAgKi9cbiAgZnJvbnRlbmRNb2RlbFNlbGVjdGVkQXR0cmlidXRlc0Zvck1vZGVsQ2xhc3MobW9kZWxDbGFzcykge1xuICAgIGNvbnN0IHNlbGVjdCA9IHRoaXMuZnJvbnRlbmRNb2RlbFNlbGVjdCgpXG5cbiAgICBpZiAoIXNlbGVjdCkgcmV0dXJuIG51bGxcblxuICAgIHJldHVybiBzZWxlY3RbbW9kZWxDbGFzcy5nZXRNb2RlbE5hbWUoKV0gfHwgbnVsbFxuICB9XG5cbiAgLyoqXG4gICAqIEBwYXJhbSB7dHlwZW9mIGltcG9ydChcIi4vZGF0YWJhc2UvcmVjb3JkL2luZGV4LmpzXCIpLmRlZmF1bHR9IG1vZGVsQ2xhc3MgLSBNb2RlbCBjbGFzcy5cbiAgICogQHJldHVybnMge3N0cmluZ1tdIHwgbnVsbH0gLSBFeHRyYSBhdHRyaWJ1dGVzIChsb2FkZWQgaW4gYWRkaXRpb24gdG8gdGhlIGRlZmF1bHRzKSBmb3IgdGhlIG1vZGVsIGNsYXNzLlxuICAgKi9cbiAgZnJvbnRlbmRNb2RlbFNlbGVjdHNFeHRyYUZvck1vZGVsQ2xhc3MobW9kZWxDbGFzcykge1xuICAgIGNvbnN0IHNlbGVjdHNFeHRyYSA9IHRoaXMuZnJvbnRlbmRNb2RlbFNlbGVjdHNFeHRyYSgpXG5cbiAgICBpZiAoIXNlbGVjdHNFeHRyYSkgcmV0dXJuIG51bGxcblxuICAgIHJldHVybiBzZWxlY3RzRXh0cmFbbW9kZWxDbGFzcy5nZXRNb2RlbE5hbWUoKV0gfHwgbnVsbFxuICB9XG5cbiAgLyoqXG4gICAqIFJlc29sdmVzIHRoZSBmaW5hbCBzZXQgb2YgYXR0cmlidXRlIG5hbWVzIHRvIHNlcmlhbGl6ZSBmb3IgYSBtb2RlbCBjbGFzczpcbiAgICogYW4gZXhwbGljaXQgbmFycm93aW5nIGBzZWxlY3RgIHdpbnM7IG90aGVyd2lzZSwgd2hlbiBgc2VsZWN0c0V4dHJhYCBpcyBnaXZlbixcbiAgICogdGhlIGRlZmF1bHQgYXR0cmlidXRlcyBwbHVzIHRoZSBleHRyYXM7IG90aGVyd2lzZSBudWxsIChkZWZhdWx0IGJlaGF2aW9yKS5cbiAgICogQHBhcmFtIHt0eXBlb2YgaW1wb3J0KFwiLi9kYXRhYmFzZS9yZWNvcmQvaW5kZXguanNcIikuZGVmYXVsdH0gbW9kZWxDbGFzcyAtIE1vZGVsIGNsYXNzLlxuICAgKiBAcGFyYW0ge3N0cmluZ1tdfSBmYWxsYmFja0F0dHJpYnV0ZU5hbWVzIC0gQXR0cmlidXRlIG5hbWVzIHRvIHRyZWF0IGFzIHRoZSBkZWZhdWx0cyB3aGVuIHRoZSByZXNvdXJjZSBkZWNsYXJlcyBub25lLlxuICAgKiBAcmV0dXJucyB7c3RyaW5nW10gfCBudWxsfSAtIEVmZmVjdGl2ZSBzZWxlY3RlZCBhdHRyaWJ1dGUgbmFtZXMsIG9yIG51bGwgZm9yIGRlZmF1bHQgc2VyaWFsaXphdGlvbi5cbiAgICovXG4gIGZyb250ZW5kTW9kZWxFZmZlY3RpdmVTZWxlY3RlZEF0dHJpYnV0ZXNGb3JNb2RlbENsYXNzKG1vZGVsQ2xhc3MsIGZhbGxiYWNrQXR0cmlidXRlTmFtZXMpIHtcbiAgICBjb25zdCBzZWxlY3RlZEF0dHJpYnV0ZXMgPSB0aGlzLmZyb250ZW5kTW9kZWxTZWxlY3RlZEF0dHJpYnV0ZXNGb3JNb2RlbENsYXNzKG1vZGVsQ2xhc3MpXG5cbiAgICBpZiAoc2VsZWN0ZWRBdHRyaWJ1dGVzKSByZXR1cm4gc2VsZWN0ZWRBdHRyaWJ1dGVzXG5cbiAgICBjb25zdCBleHRyYUF0dHJpYnV0ZXMgPSB0aGlzLmZyb250ZW5kTW9kZWxTZWxlY3RzRXh0cmFGb3JNb2RlbENsYXNzKG1vZGVsQ2xhc3MpXG5cbiAgICBpZiAoIWV4dHJhQXR0cmlidXRlcykgcmV0dXJuIG51bGxcblxuICAgIGNvbnN0IGRlZmF1bHRBdHRyaWJ1dGVzID0gdGhpcy5mcm9udGVuZE1vZGVsRGVmYXVsdEF0dHJpYnV0ZXNGb3JNb2RlbENsYXNzKG1vZGVsQ2xhc3MpIHx8IGZhbGxiYWNrQXR0cmlidXRlTmFtZXNcblxuICAgIHJldHVybiBBcnJheS5mcm9tKG5ldyBTZXQoWy4uLmRlZmF1bHRBdHRyaWJ1dGVzLCAuLi5leHRyYUF0dHJpYnV0ZXNdKSlcbiAgfVxuXG4gIC8qKlxuICAgKiBAcGFyYW0ge3R5cGVvZiBpbXBvcnQoXCIuL2RhdGFiYXNlL3JlY29yZC9pbmRleC5qc1wiKS5kZWZhdWx0fSBtb2RlbENsYXNzIC0gTW9kZWwgY2xhc3MuXG4gICAqIEByZXR1cm5zIHtzdHJpbmdbXSB8IG51bGx9IC0gRGVmYXVsdCBmcm9udGVuZC1tb2RlbCBhdHRyaWJ1dGVzIGRlY2xhcmVkIG9uIHRoZSByZXNvdXJjZS5cbiAgICovXG4gIGZyb250ZW5kTW9kZWxEZWZhdWx0QXR0cmlidXRlc0Zvck1vZGVsQ2xhc3MobW9kZWxDbGFzcykge1xuICAgIGNvbnN0IGZyb250ZW5kTW9kZWxSZXNvdXJjZSA9IHRoaXMuZnJvbnRlbmRNb2RlbFJlc291cmNlQ29uZmlndXJhdGlvbkZvck1vZGVsQ2xhc3MobW9kZWxDbGFzcylcbiAgICBjb25zdCBhdHRyaWJ1dGVzID0gZnJvbnRlbmRNb2RlbFJlc291cmNlPy5yZXNvdXJjZUNvbmZpZ3VyYXRpb24uYXR0cmlidXRlc1xuXG4gICAgaWYgKCFhdHRyaWJ1dGVzKSByZXR1cm4gbnVsbFxuXG4gICAgaWYgKEFycmF5LmlzQXJyYXkoYXR0cmlidXRlcykpIHtcbiAgICAgIHJldHVybiBhdHRyaWJ1dGVzXG4gICAgICAgIC5maWx0ZXIoKGVudHJ5KSA9PiB7XG4gICAgICAgICAgaWYgKHR5cGVvZiBlbnRyeSA9PT0gXCJzdHJpbmdcIikgcmV0dXJuIHRydWVcblxuICAgICAgICAgIGNvbnN0IGNvbmZpZyA9IC8qKiBAdHlwZSB7UmVjb3JkPHN0cmluZywgYW55Pn0gKi8gKGVudHJ5KVxuXG4gICAgICAgICAgaWYgKGNvbmZpZyAmJiBjb25maWcuc2VsZWN0ZWRCeURlZmF1bHQgPT09IGZhbHNlKSByZXR1cm4gZmFsc2VcblxuICAgICAgICAgIHJldHVybiB0cnVlXG4gICAgICAgIH0pXG4gICAgICAgIC5tYXAoKGVudHJ5KSA9PiB0eXBlb2YgZW50cnkgPT09IFwic3RyaW5nXCIgPyBlbnRyeSA6IC8qKiBAdHlwZSB7UmVjb3JkPHN0cmluZywgYW55Pn0gKi8gKGVudHJ5KS5uYW1lKVxuICAgIH1cblxuICAgIGlmICh0eXBlb2YgYXR0cmlidXRlcyA9PT0gXCJvYmplY3RcIikge1xuICAgICAgcmV0dXJuIE9iamVjdC5lbnRyaWVzKGF0dHJpYnV0ZXMpXG4gICAgICAgIC5maWx0ZXIoKFssIGNvbmZpZ10pID0+IHtcbiAgICAgICAgICBpZiAoIWNvbmZpZyB8fCB0eXBlb2YgY29uZmlnICE9PSBcIm9iamVjdFwiKSByZXR1cm4gdHJ1ZVxuXG4gICAgICAgICAgcmV0dXJuIC8qKiBAdHlwZSB7UmVjb3JkPHN0cmluZywgYW55Pn0gKi8gKGNvbmZpZykuc2VsZWN0ZWRCeURlZmF1bHQgIT09IGZhbHNlXG4gICAgICAgIH0pXG4gICAgICAgIC5tYXAoKFtuYW1lXSkgPT4gbmFtZSlcbiAgICB9XG5cbiAgICByZXR1cm4gbnVsbFxuICB9XG5cbiAgLyoqXG4gICAqIEBwYXJhbSB7dHlwZW9mIGltcG9ydChcIi4vZGF0YWJhc2UvcmVjb3JkL2luZGV4LmpzXCIpLmRlZmF1bHR9IG1vZGVsQ2xhc3MgLSBNb2RlbCBjbGFzcy5cbiAgICogQHJldHVybnMge3N0cmluZ1tdfSAtIEF0dHJpYnV0ZSBuYW1lcyBleHBsaWNpdGx5IG1hcmtlZCBzZWxlY3RlZEJ5RGVmYXVsdDogZmFsc2UuXG4gICAqL1xuICBmcm9udGVuZE1vZGVsTm9uRGVmYXVsdEF0dHJpYnV0ZXNGb3JNb2RlbENsYXNzKG1vZGVsQ2xhc3MpIHtcbiAgICBjb25zdCBmcm9udGVuZE1vZGVsUmVzb3VyY2UgPSB0aGlzLmZyb250ZW5kTW9kZWxSZXNvdXJjZUNvbmZpZ3VyYXRpb25Gb3JNb2RlbENsYXNzKG1vZGVsQ2xhc3MpXG4gICAgY29uc3QgYXR0cmlidXRlcyA9IGZyb250ZW5kTW9kZWxSZXNvdXJjZT8ucmVzb3VyY2VDb25maWd1cmF0aW9uLmF0dHJpYnV0ZXNcblxuICAgIGlmICghYXR0cmlidXRlcykgcmV0dXJuIFtdXG5cbiAgICBpZiAoQXJyYXkuaXNBcnJheShhdHRyaWJ1dGVzKSkge1xuICAgICAgcmV0dXJuIGF0dHJpYnV0ZXNcbiAgICAgICAgLmZpbHRlcigoZW50cnkpID0+IHtcbiAgICAgICAgICBpZiAodHlwZW9mIGVudHJ5ICE9PSBcIm9iamVjdFwiIHx8ICFlbnRyeSkgcmV0dXJuIGZhbHNlXG5cbiAgICAgICAgICByZXR1cm4gLyoqIEB0eXBlIHtSZWNvcmQ8c3RyaW5nLCBhbnk+fSAqLyAoZW50cnkpLnNlbGVjdGVkQnlEZWZhdWx0ID09PSBmYWxzZVxuICAgICAgICB9KVxuICAgICAgICAubWFwKChlbnRyeSkgPT4gLyoqIEB0eXBlIHtSZWNvcmQ8c3RyaW5nLCBhbnk+fSAqLyAoLyoqIEB0eXBlIHt1bmtub3dufSAqLyAoZW50cnkpKS5uYW1lKVxuICAgIH1cblxuICAgIGlmICh0eXBlb2YgYXR0cmlidXRlcyA9PT0gXCJvYmplY3RcIikge1xuICAgICAgcmV0dXJuIE9iamVjdC5lbnRyaWVzKGF0dHJpYnV0ZXMpXG4gICAgICAgIC5maWx0ZXIoKFssIGNvbmZpZ10pID0+IHR5cGVvZiBjb25maWcgPT09IFwib2JqZWN0XCIgJiYgY29uZmlnICYmIC8qKiBAdHlwZSB7UmVjb3JkPHN0cmluZywgYW55Pn0gKi8gKGNvbmZpZykuc2VsZWN0ZWRCeURlZmF1bHQgPT09IGZhbHNlKVxuICAgICAgICAubWFwKChbbmFtZV0pID0+IG5hbWUpXG4gICAgfVxuXG4gICAgcmV0dXJuIFtdXG4gIH1cblxuICAvKipcbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuL2RhdGFiYXNlL3JlY29yZC9pbmRleC5qc1wiKS5kZWZhdWx0fSBtb2RlbCAtIE1vZGVsIGluc3RhbmNlLlxuICAgKiBAcmV0dXJucyB7UHJvbWlzZTxSZWNvcmQ8c3RyaW5nLCBhbnk+Pn0gLSBTZXJpYWxpemVkIGF0dHJpYnV0ZXMgZmlsdGVyZWQgYnkgc2VsZWN0IG1hcC5cbiAgICovXG4gIGFzeW5jIHNlcmlhbGl6ZUZyb250ZW5kTW9kZWxBdHRyaWJ1dGVzKG1vZGVsKSB7XG4gICAgY29uc3QgbW9kZWxDbGFzcyA9IC8qKiBAdHlwZSB7dHlwZW9mIGltcG9ydChcIi4vZGF0YWJhc2UvcmVjb3JkL2luZGV4LmpzXCIpLmRlZmF1bHR9ICovIChtb2RlbC5jb25zdHJ1Y3RvcilcbiAgICBjb25zdCBtb2RlbEF0dHJpYnV0ZXMgPSBtb2RlbC5hdHRyaWJ1dGVzKClcbiAgICBjb25zdCBzZWxlY3RlZEF0dHJpYnV0ZXMgPSB0aGlzLmZyb250ZW5kTW9kZWxFZmZlY3RpdmVTZWxlY3RlZEF0dHJpYnV0ZXNGb3JNb2RlbENsYXNzKG1vZGVsQ2xhc3MsIE9iamVjdC5rZXlzKG1vZGVsQXR0cmlidXRlcykpXG4gICAgY29uc3QgZGVmYXVsdEF0dHJpYnV0ZXMgPSB0aGlzLmZyb250ZW5kTW9kZWxEZWZhdWx0QXR0cmlidXRlc0Zvck1vZGVsQ2xhc3MobW9kZWxDbGFzcylcbiAgICBjb25zdCByZXNvdXJjZUluc3RhbmNlID0gdGhpcy5fc2VyaWFsaXphdGlvblJlc291cmNlSW5zdGFuY2VGb3JNb2RlbChtb2RlbClcblxuICAgIC8qKiBAcGFyYW0ge3N0cmluZ30gYXR0cmlidXRlTmFtZSAtIEF0dHJpYnV0ZSBuYW1lLiAqL1xuICAgIGNvbnN0IHJlc291cmNlQXR0cmlidXRlTWV0aG9kTmFtZSA9IChhdHRyaWJ1dGVOYW1lKSA9PiBgJHthdHRyaWJ1dGVOYW1lfUF0dHJpYnV0ZWBcblxuICAgIC8qKiBAcGFyYW0ge3N0cmluZ30gYXR0cmlidXRlTmFtZSAtIEF0dHJpYnV0ZSBuYW1lLiAqL1xuICAgIGNvbnN0IHJlc291cmNlSGFzQXR0cmlidXRlID0gKGF0dHJpYnV0ZU5hbWUpID0+IHtcbiAgICAgIGNvbnN0IG1ldGhvZE5hbWUgPSByZXNvdXJjZUF0dHJpYnV0ZU1ldGhvZE5hbWUoYXR0cmlidXRlTmFtZSlcblxuICAgICAgcmV0dXJuIHJlc291cmNlSW5zdGFuY2UgJiYgdHlwZW9mIC8qKiBAdHlwZSB7UmVjb3JkPHN0cmluZywgYW55Pn0gKi8gKC8qKiBAdHlwZSB7dW5rbm93bn0gKi8gKHJlc291cmNlSW5zdGFuY2UpKVttZXRob2ROYW1lXSA9PT0gXCJmdW5jdGlvblwiXG4gICAgfVxuXG4gICAgLyoqIEBwYXJhbSB7c3RyaW5nfSBhdHRyaWJ1dGVOYW1lIC0gQXR0cmlidXRlIG5hbWUuICovXG4gICAgY29uc3QgcHJvdG90eXBlQXR0cmlidXRlTWV0aG9kID0gKGF0dHJpYnV0ZU5hbWUpID0+IHtcbiAgICAgIGxldCBjdXJyZW50UHJvdG90eXBlID0gT2JqZWN0LmdldFByb3RvdHlwZU9mKG1vZGVsKVxuXG4gICAgICB3aGlsZSAoY3VycmVudFByb3RvdHlwZSAmJiBjdXJyZW50UHJvdG90eXBlICE9PSBPYmplY3QucHJvdG90eXBlKSB7XG4gICAgICAgIGNvbnN0IGNhbmRpZGF0ZSA9IE9iamVjdC5nZXRPd25Qcm9wZXJ0eURlc2NyaXB0b3IoY3VycmVudFByb3RvdHlwZSwgYXR0cmlidXRlTmFtZSk/LnZhbHVlXG5cbiAgICAgICAgaWYgKHR5cGVvZiBjYW5kaWRhdGUgPT09IFwiZnVuY3Rpb25cIikge1xuICAgICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICBtZXRob2Q6IGNhbmRpZGF0ZSxcbiAgICAgICAgICAgIG93bmVyTmFtZTogY3VycmVudFByb3RvdHlwZS5jb25zdHJ1Y3Rvcj8ubmFtZVxuICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIGN1cnJlbnRQcm90b3R5cGUgPSBPYmplY3QuZ2V0UHJvdG90eXBlT2YoY3VycmVudFByb3RvdHlwZSlcbiAgICAgIH1cbiAgICB9XG5cbiAgICAvKiogQHBhcmFtIHtzdHJpbmd9IGF0dHJpYnV0ZU5hbWUgLSBBdHRyaWJ1dGUgbmFtZS4gKi9cbiAgICBjb25zdCBzZXJpYWxpemVkQXR0cmlidXRlVmFsdWUgPSBhc3luYyAoYXR0cmlidXRlTmFtZSkgPT4ge1xuICAgICAgLy8gQ2hlY2sgcmVzb3VyY2UgaW5zdGFuY2UgZmlyc3QgKHZpcnR1YWwvY29tcHV0ZWQgYXR0cmlidXRlcyB2aWEgJHtuYW1lfUF0dHJpYnV0ZSBjb252ZW50aW9uKVxuICAgICAgaWYgKHJlc291cmNlSGFzQXR0cmlidXRlKGF0dHJpYnV0ZU5hbWUpKSB7XG4gICAgICAgIGNvbnN0IG1ldGhvZE5hbWUgPSByZXNvdXJjZUF0dHJpYnV0ZU1ldGhvZE5hbWUoYXR0cmlidXRlTmFtZSlcblxuICAgICAgICByZXR1cm4gYXdhaXQgLyoqIEB0eXBlIHtSZWNvcmQ8c3RyaW5nLCBGdW5jdGlvbj59ICovICgvKiogQHR5cGUge3Vua25vd259ICovIChyZXNvdXJjZUluc3RhbmNlKSlbbWV0aG9kTmFtZV0obW9kZWwpXG4gICAgICB9XG5cbiAgICAgIC8vIEZhbGwgYmFjayB0byBtb2RlbCBtZXRob2RcbiAgICAgIGNvbnN0IGF0dHJpYnV0ZU1ldGhvZExvb2t1cCA9IHByb3RvdHlwZUF0dHJpYnV0ZU1ldGhvZChhdHRyaWJ1dGVOYW1lKVxuICAgICAgY29uc3QgYXR0cmlidXRlTWV0aG9kID0gYXR0cmlidXRlTWV0aG9kTG9va3VwPy5tZXRob2RcblxuICAgICAgaWYgKHR5cGVvZiBhdHRyaWJ1dGVNZXRob2QgPT09IFwiZnVuY3Rpb25cIikge1xuICAgICAgICByZXR1cm4gYXdhaXQgYXR0cmlidXRlTWV0aG9kLmNhbGwobW9kZWwpXG4gICAgICB9XG5cbiAgICAgIHJldHVybiBtb2RlbEF0dHJpYnV0ZXNbYXR0cmlidXRlTmFtZV1cbiAgICB9XG5cbiAgICAvKiogQHBhcmFtIHtzdHJpbmd9IGF0dHJpYnV0ZU5hbWUgLSBBdHRyaWJ1dGUgbmFtZS4gKi9cbiAgICBjb25zdCBhdHRyaWJ1dGVFeGlzdHMgPSAoYXR0cmlidXRlTmFtZSkgPT4ge1xuICAgICAgcmV0dXJuIChhdHRyaWJ1dGVOYW1lIGluIG1vZGVsQXR0cmlidXRlcykgfHwgKGF0dHJpYnV0ZU5hbWUgaW4gLyoqIEB0eXBlIHtSZWNvcmQ8c3RyaW5nLCBhbnk+fSAqLyAobW9kZWwpKSB8fCByZXNvdXJjZUhhc0F0dHJpYnV0ZShhdHRyaWJ1dGVOYW1lKVxuICAgIH1cblxuICAgIGlmICghc2VsZWN0ZWRBdHRyaWJ1dGVzKSB7XG4gICAgICBpZiAoIWRlZmF1bHRBdHRyaWJ1dGVzIHx8IGRlZmF1bHRBdHRyaWJ1dGVzLmxlbmd0aCA8IDEpIHtcbiAgICAgICAgcmV0dXJuIG1vZGVsQXR0cmlidXRlc1xuICAgICAgfVxuXG4gICAgICBjb25zdCBleGNsdWRlZEF0dHJpYnV0ZXMgPSB0aGlzLmZyb250ZW5kTW9kZWxOb25EZWZhdWx0QXR0cmlidXRlc0Zvck1vZGVsQ2xhc3MobW9kZWxDbGFzcylcbiAgICAgIGNvbnN0IHNlcmlhbGl6ZWRBdHRyaWJ1dGVzID0gey4uLm1vZGVsQXR0cmlidXRlc31cblxuICAgICAgZm9yIChjb25zdCBleGNsdWRlZE5hbWUgb2YgZXhjbHVkZWRBdHRyaWJ1dGVzKSB7XG4gICAgICAgIGRlbGV0ZSBzZXJpYWxpemVkQXR0cmlidXRlc1tleGNsdWRlZE5hbWVdXG4gICAgICB9XG5cbiAgICAgIGZvciAoY29uc3QgYXR0cmlidXRlTmFtZSBvZiBkZWZhdWx0QXR0cmlidXRlcykge1xuICAgICAgICBpZiAoIWF0dHJpYnV0ZUV4aXN0cyhhdHRyaWJ1dGVOYW1lKSkgY29udGludWVcbiAgICAgICAgc2VyaWFsaXplZEF0dHJpYnV0ZXNbYXR0cmlidXRlTmFtZV0gPSBhd2FpdCBzZXJpYWxpemVkQXR0cmlidXRlVmFsdWUoYXR0cmlidXRlTmFtZSlcbiAgICAgIH1cblxuICAgICAgcmV0dXJuIHNlcmlhbGl6ZWRBdHRyaWJ1dGVzXG4gICAgfVxuXG4gICAgLyoqIEB0eXBlIHtSZWNvcmQ8c3RyaW5nLCBhbnk+fSAqL1xuICAgIGNvbnN0IHNlcmlhbGl6ZWRBdHRyaWJ1dGVzID0ge31cblxuICAgIGZvciAoY29uc3QgYXR0cmlidXRlTmFtZSBvZiBzZWxlY3RlZEF0dHJpYnV0ZXMpIHtcbiAgICAgIGlmICghYXR0cmlidXRlRXhpc3RzKGF0dHJpYnV0ZU5hbWUpKSBjb250aW51ZVxuICAgICAgc2VyaWFsaXplZEF0dHJpYnV0ZXNbYXR0cmlidXRlTmFtZV0gPSBhd2FpdCBzZXJpYWxpemVkQXR0cmlidXRlVmFsdWUoYXR0cmlidXRlTmFtZSlcbiAgICB9XG5cbiAgICByZXR1cm4gc2VyaWFsaXplZEF0dHJpYnV0ZXNcbiAgfVxuXG4gIC8qKlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4vZGF0YWJhc2UvcmVjb3JkL2luZGV4LmpzXCIpLmRlZmF1bHR9IG1vZGVsIC0gTW9kZWwgaW5zdGFuY2UuXG4gICAqIEByZXR1cm5zIHtpbXBvcnQoXCIuL2Zyb250ZW5kLW1vZGVsLXJlc291cmNlL2Jhc2UtcmVzb3VyY2UuanNcIikuZGVmYXVsdCB8IG51bGx9IC0gUmVzb3VyY2UgaW5zdGFuY2Ugb3IgbnVsbC5cbiAgICovXG4gIF9zZXJpYWxpemF0aW9uUmVzb3VyY2VJbnN0YW5jZUZvck1vZGVsKG1vZGVsKSB7XG4gICAgY29uc3QgcmVzb3VyY2UgPSB0aGlzLmZyb250ZW5kTW9kZWxSZXNvdXJjZUluc3RhbmNlKClcblxuICAgIGlmIChyZXNvdXJjZS5tb2RlbENsYXNzKCkgPT09IG1vZGVsLmNvbnN0cnVjdG9yKSB7XG4gICAgICByZXR1cm4gcmVzb3VyY2VcbiAgICB9XG5cbiAgICBjb25zdCBjb25maWd1cmF0aW9uID0gdGhpcy5nZXRDb25maWd1cmF0aW9uKClcbiAgICBjb25zdCBiYWNrZW5kUHJvamVjdHMgPSBjb25maWd1cmF0aW9uLmdldEJhY2tlbmRQcm9qZWN0cz8uKCkgfHwgW11cbiAgICBjb25zdCBtb2RlbENsYXNzTmFtZSA9IC8qKiBAdHlwZSB7dHlwZW9mIGltcG9ydChcIi4vZGF0YWJhc2UvcmVjb3JkL2luZGV4LmpzXCIpLmRlZmF1bHR9ICovIChtb2RlbC5jb25zdHJ1Y3RvcikuZ2V0TW9kZWxOYW1lKClcblxuICAgIGZvciAoY29uc3QgYmFja2VuZFByb2plY3Qgb2YgYmFja2VuZFByb2plY3RzKSB7XG4gICAgICBjb25zdCByZXNvdXJjZXMgPSBmcm9udGVuZE1vZGVsUmVzb3VyY2VzRm9yQmFja2VuZFByb2plY3QoYmFja2VuZFByb2plY3QpXG4gICAgICBjb25zdCByZXNvdXJjZURlZmluaXRpb24gPSByZXNvdXJjZXNbbW9kZWxDbGFzc05hbWVdXG4gICAgICBjb25zdCByZXNvdXJjZUNsYXNzID0gcmVzb3VyY2VEZWZpbml0aW9uID8gZnJvbnRlbmRNb2RlbFJlc291cmNlQ2xhc3NGcm9tRGVmaW5pdGlvbihyZXNvdXJjZURlZmluaXRpb24pIDogbnVsbFxuXG4gICAgICBpZiAocmVzb3VyY2VDbGFzcykge1xuICAgICAgICByZXR1cm4gbmV3IHJlc291cmNlQ2xhc3Moe1xuICAgICAgICAgIGFiaWxpdHk6IHRoaXMuY3VycmVudEFiaWxpdHkoKSxcbiAgICAgICAgICBjb250ZXh0OiB0aGlzLmN1cnJlbnRBYmlsaXR5KCk/LmdldENvbnRleHQoKSB8fCB7fSxcbiAgICAgICAgICBsb2NhbHM6IHRoaXMuY3VycmVudEFiaWxpdHkoKT8uZ2V0TG9jYWxzKCkgfHwge30sXG4gICAgICAgICAgbW9kZWxDbGFzczogLyoqIEB0eXBlIHt0eXBlb2YgaW1wb3J0KFwiLi9kYXRhYmFzZS9yZWNvcmQvaW5kZXguanNcIikuZGVmYXVsdH0gKi8gKG1vZGVsLmNvbnN0cnVjdG9yKSxcbiAgICAgICAgICBtb2RlbE5hbWU6IG1vZGVsQ2xhc3NOYW1lLFxuICAgICAgICAgIHBhcmFtczoge30sXG4gICAgICAgICAgcmVzb3VyY2VDb25maWd1cmF0aW9uOiAvKiogQHR5cGUge2ltcG9ydChcIi4vY29uZmlndXJhdGlvbi10eXBlcy5qc1wiKS5Gcm9udGVuZE1vZGVsUmVzb3VyY2VDb25maWd1cmF0aW9uIHwgdW5kZWZpbmVkfSAqLyAodHlwZW9mIHJlc291cmNlQ2xhc3MucmVzb3VyY2VDb25maWcgPT09IFwiZnVuY3Rpb25cIiA/IHJlc291cmNlQ2xhc3MucmVzb3VyY2VDb25maWcoKSA6IHVuZGVmaW5lZClcbiAgICAgICAgfSlcbiAgICAgIH1cbiAgICB9XG5cbiAgICByZXR1cm4gbnVsbFxuICB9XG5cbiAgLyoqXG4gICAqIEBwYXJhbSB7b2JqZWN0fSBhcmdzIC0gQXJndW1lbnRzLlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4vZGF0YWJhc2UvcmVjb3JkL2luZGV4LmpzXCIpLmRlZmF1bHRbXX0gYXJncy5tb2RlbHMgLSBGcm9udGVuZCBtb2RlbCByZWNvcmRzLlxuICAgKiBAcGFyYW0ge2Jvb2xlYW59IGFyZ3MucmVsYXRpb25zaGlwSXNDb2xsZWN0aW9uIC0gV2hldGhlciByZWxhdGlvbiBpcyBoYXMtbWFueS5cbiAgICogQHJldHVybnMge1Byb21pc2U8aW1wb3J0KFwiLi9kYXRhYmFzZS9yZWNvcmQvaW5kZXguanNcIikuZGVmYXVsdFtdPn0gLSBTZXJpYWxpemFibGUgcmVsYXRlZCBtb2RlbHMuXG4gICAqL1xuICBhc3luYyBmcm9udGVuZE1vZGVsRmlsdGVyU2VyaWFsaXphYmxlUmVsYXRlZE1vZGVscyh7bW9kZWxzLCByZWxhdGlvbnNoaXBJc0NvbGxlY3Rpb259KSB7XG4gICAgaWYgKCF0aGlzLmN1cnJlbnRBYmlsaXR5KCkpIHJldHVybiBtb2RlbHNcbiAgICBpZiAobW9kZWxzLmxlbmd0aCA9PT0gMCkgcmV0dXJuIG1vZGVsc1xuXG4gICAgLyoqIEB0eXBlIHtNYXA8dHlwZW9mIGltcG9ydChcIi4vZGF0YWJhc2UvcmVjb3JkL2luZGV4LmpzXCIpLmRlZmF1bHQsIGltcG9ydChcIi4vZGF0YWJhc2UvcmVjb3JkL2luZGV4LmpzXCIpLmRlZmF1bHRbXT59ICovXG4gICAgY29uc3QgbW9kZWxzQnlDbGFzcyA9IG5ldyBNYXAoKVxuXG4gICAgZm9yIChjb25zdCBtb2RlbCBvZiBtb2RlbHMpIHtcbiAgICAgIGNvbnN0IHJlbGF0ZWRNb2RlbENsYXNzID0gLyoqIEB0eXBlIHt0eXBlb2YgaW1wb3J0KFwiLi9kYXRhYmFzZS9yZWNvcmQvaW5kZXguanNcIikuZGVmYXVsdH0gKi8gKG1vZGVsLmNvbnN0cnVjdG9yKVxuICAgICAgY29uc3QgZXhpc3RpbmdNb2RlbHNGb3JDbGFzcyA9IG1vZGVsc0J5Q2xhc3MuZ2V0KHJlbGF0ZWRNb2RlbENsYXNzKSB8fCBbXVxuXG4gICAgICBleGlzdGluZ01vZGVsc0ZvckNsYXNzLnB1c2gobW9kZWwpXG4gICAgICBtb2RlbHNCeUNsYXNzLnNldChyZWxhdGVkTW9kZWxDbGFzcywgZXhpc3RpbmdNb2RlbHNGb3JDbGFzcylcbiAgICB9XG5cbiAgICAvKiogQHR5cGUge01hcDx0eXBlb2YgaW1wb3J0KFwiLi9kYXRhYmFzZS9yZWNvcmQvaW5kZXguanNcIikuZGVmYXVsdCwgU2V0PHN0cmluZz4+fSAqL1xuICAgIGNvbnN0IGF1dGhvcml6ZWRJZHNCeUNsYXNzID0gbmV3IE1hcCgpXG4gICAgLyoqIEB0eXBlIHtNYXA8dHlwZW9mIGltcG9ydChcIi4vZGF0YWJhc2UvcmVjb3JkL2luZGV4LmpzXCIpLmRlZmF1bHQsIHN0cmluZz59ICovXG4gICAgY29uc3QgcHJpbWFyeUtleXNCeUNsYXNzID0gbmV3IE1hcCgpXG5cbiAgICBmb3IgKGNvbnN0IFtyZWxhdGVkTW9kZWxDbGFzcywgcmVsYXRlZE1vZGVsc10gb2YgbW9kZWxzQnlDbGFzcy5lbnRyaWVzKCkpIHtcbiAgICAgIGNvbnN0IHJlbGF0ZWRSZXNvdXJjZSA9IHRoaXMuZnJvbnRlbmRNb2RlbFJlc291cmNlQ29uZmlndXJhdGlvbkZvck1vZGVsQ2xhc3MocmVsYXRlZE1vZGVsQ2xhc3MpXG5cbiAgICAgIGlmICghcmVsYXRlZFJlc291cmNlKSB7XG4gICAgICAgIGF1dGhvcml6ZWRJZHNCeUNsYXNzLnNldChyZWxhdGVkTW9kZWxDbGFzcywgbmV3IFNldCgpKVxuICAgICAgICBjb250aW51ZVxuICAgICAgfVxuXG4gICAgICBjb25zdCBhYmlsaXR5QWN0aW9uID0gcmVsYXRpb25zaGlwSXNDb2xsZWN0aW9uXG4gICAgICAgID8gcmVsYXRlZFJlc291cmNlLnJlc291cmNlQ29uZmlndXJhdGlvbi5hYmlsaXRpZXM/LmluZGV4XG4gICAgICAgIDogcmVsYXRlZFJlc291cmNlLnJlc291cmNlQ29uZmlndXJhdGlvbi5hYmlsaXRpZXM/LmZpbmRcblxuICAgICAgaWYgKHR5cGVvZiBhYmlsaXR5QWN0aW9uICE9PSBcInN0cmluZ1wiIHx8IGFiaWxpdHlBY3Rpb24ubGVuZ3RoIDwgMSkge1xuICAgICAgICBhdXRob3JpemVkSWRzQnlDbGFzcy5zZXQocmVsYXRlZE1vZGVsQ2xhc3MsIG5ldyBTZXQoKSlcbiAgICAgICAgY29udGludWVcbiAgICAgIH1cblxuICAgICAgY29uc3QgcHJpbWFyeUtleSA9IHJlbGF0ZWRNb2RlbENsYXNzLnByaW1hcnlLZXkoKVxuICAgICAgY29uc3QgaWRzID0gcmVsYXRlZE1vZGVsc1xuICAgICAgICAubWFwKChtb2RlbCkgPT4gbW9kZWwuYXR0cmlidXRlcygpW3ByaW1hcnlLZXldKVxuICAgICAgICAuZmlsdGVyKChpZCkgPT4gaWQgIT09IHVuZGVmaW5lZCAmJiBpZCAhPT0gbnVsbClcblxuICAgICAgaWYgKGlkcy5sZW5ndGggPCAxKSB7XG4gICAgICAgIGF1dGhvcml6ZWRJZHNCeUNsYXNzLnNldChyZWxhdGVkTW9kZWxDbGFzcywgbmV3IFNldCgpKVxuICAgICAgICBjb250aW51ZVxuICAgICAgfVxuXG4gICAgICBjb25zdCBhdXRob3JpemVkSWRzUmF3ID0gYXdhaXQgcmVsYXRlZE1vZGVsQ2xhc3NcbiAgICAgICAgLmFjY2Vzc2libGVGb3IoYWJpbGl0eUFjdGlvbilcbiAgICAgICAgLndoZXJlKHtbcHJpbWFyeUtleV06IGlkc30pXG4gICAgICAgIC5wbHVjayhwcmltYXJ5S2V5KVxuXG4gICAgICBwcmltYXJ5S2V5c0J5Q2xhc3Muc2V0KHJlbGF0ZWRNb2RlbENsYXNzLCBwcmltYXJ5S2V5KVxuICAgICAgYXV0aG9yaXplZElkc0J5Q2xhc3Muc2V0KHJlbGF0ZWRNb2RlbENsYXNzLCBuZXcgU2V0KGF1dGhvcml6ZWRJZHNSYXcubWFwKChpZCkgPT4gU3RyaW5nKGlkKSkpKVxuICAgIH1cblxuICAgIHJldHVybiBtb2RlbHMuZmlsdGVyKChtb2RlbCkgPT4ge1xuICAgICAgY29uc3QgcmVsYXRlZE1vZGVsQ2xhc3MgPSAvKiogQHR5cGUge3R5cGVvZiBpbXBvcnQoXCIuL2RhdGFiYXNlL3JlY29yZC9pbmRleC5qc1wiKS5kZWZhdWx0fSAqLyAobW9kZWwuY29uc3RydWN0b3IpXG4gICAgICBjb25zdCBhdXRob3JpemVkSWRzID0gYXV0aG9yaXplZElkc0J5Q2xhc3MuZ2V0KHJlbGF0ZWRNb2RlbENsYXNzKVxuICAgICAgY29uc3QgcHJpbWFyeUtleSA9IHByaW1hcnlLZXlzQnlDbGFzcy5nZXQocmVsYXRlZE1vZGVsQ2xhc3MpXG5cbiAgICAgIGlmICghYXV0aG9yaXplZElkcyB8fCAhcHJpbWFyeUtleSkgcmV0dXJuIGZhbHNlXG5cbiAgICAgIGNvbnN0IHByaW1hcnlLZXlWYWx1ZSA9IG1vZGVsLmF0dHJpYnV0ZXMoKVtwcmltYXJ5S2V5XVxuXG4gICAgICBpZiAocHJpbWFyeUtleVZhbHVlID09PSB1bmRlZmluZWQgfHwgcHJpbWFyeUtleVZhbHVlID09PSBudWxsKSByZXR1cm4gZmFsc2VcblxuICAgICAgcmV0dXJuIGF1dGhvcml6ZWRJZHMuaGFzKFN0cmluZyhwcmltYXJ5S2V5VmFsdWUpKVxuICAgIH0pXG4gIH1cblxuICAvKipcbiAgICogQHBhcmFtIHt1bmtub3dufSB2YWx1ZSAtIENhbmRpZGF0ZSBwcmVsb2FkZWQgdmFsdWUuXG4gICAqIEByZXR1cm5zIHt2YWx1ZSBpcyBpbXBvcnQoXCIuL2RhdGFiYXNlL3JlY29yZC9pbmRleC5qc1wiKS5kZWZhdWx0fSAtIFdoZXRoZXIgdmFsdWUgYmVoYXZlcyBsaWtlIGEgbW9kZWwuXG4gICAqL1xuICBpc1NlcmlhbGl6YWJsZUZyb250ZW5kTW9kZWwodmFsdWUpIHtcbiAgICByZXR1cm4gQm9vbGVhbih2YWx1ZSAmJiB0eXBlb2YgdmFsdWUgPT09IFwib2JqZWN0XCIgJiYgdHlwZW9mIC8qKiBAdHlwZSB7YW55fSAqLyAodmFsdWUpLmF0dHJpYnV0ZXMgPT09IFwiZnVuY3Rpb25cIilcbiAgfVxuXG4gIC8qKlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4vZGF0YWJhc2UvcmVjb3JkL2luZGV4LmpzXCIpLmRlZmF1bHRbXX0gbW9kZWxzIC0gTW9kZWxzIHRvIHNlcmlhbGl6ZS5cbiAgICogQHJldHVybnMge1Byb21pc2U8UmVjb3JkPHN0cmluZywgYW55PltdPn0gLSBTZXJpYWxpemVkIG1vZGVsIHBheWxvYWRzLlxuICAgKi9cbiAgYXN5bmMgc2VyaWFsaXplRnJvbnRlbmRNb2RlbHMobW9kZWxzKSB7XG4gICAgaWYgKG1vZGVscy5sZW5ndGggPCAxKSByZXR1cm4gW11cblxuICAgIC8qKiBAdHlwZSB7QXJyYXk8UmVjb3JkPHN0cmluZywgYW55Pj59ICovXG4gICAgY29uc3QgcHJlbG9hZGVkUmVsYXRpb25zaGlwc1Blck1vZGVsID0gQXJyYXkuZnJvbSh7bGVuZ3RoOiBtb2RlbHMubGVuZ3RofSwgKCkgPT4gKHt9KSlcblxuICAgIC8qKiBAdHlwZSB7QXJyYXk8e2xvYWRlZE1vZGVsczogaW1wb3J0KFwiLi9kYXRhYmFzZS9yZWNvcmQvaW5kZXguanNcIikuZGVmYXVsdFtdLCBtb2RlbEluZGV4OiBudW1iZXIsIHJlbGF0aW9uc2hpcE5hbWU6IHN0cmluZ30+fSAqL1xuICAgIGNvbnN0IGNvbGxlY3Rpb25SZWxhdGlvbnNoaXBFbnRyaWVzID0gW11cbiAgICAvKiogQHR5cGUge0FycmF5PHtsb2FkZWRNb2RlbDogaW1wb3J0KFwiLi9kYXRhYmFzZS9yZWNvcmQvaW5kZXguanNcIikuZGVmYXVsdCwgbW9kZWxJbmRleDogbnVtYmVyLCByZWxhdGlvbnNoaXBOYW1lOiBzdHJpbmd9Pn0gKi9cbiAgICBjb25zdCBzaW5ndWxhclJlbGF0aW9uc2hpcEVudHJpZXMgPSBbXVxuXG4gICAgbW9kZWxzLmZvckVhY2goKG1vZGVsLCBtb2RlbEluZGV4KSA9PiB7XG4gICAgICBjb25zdCBtb2RlbENsYXNzID0gLyoqIEB0eXBlIHt0eXBlb2YgaW1wb3J0KFwiLi9kYXRhYmFzZS9yZWNvcmQvaW5kZXguanNcIikuZGVmYXVsdH0gKi8gKG1vZGVsLmNvbnN0cnVjdG9yKVxuICAgICAgY29uc3QgcmVsYXRpb25zaGlwc01hcCA9IG1vZGVsQ2xhc3MuZ2V0UmVsYXRpb25zaGlwc01hcCgpXG5cbiAgICAgIGZvciAoY29uc3QgcmVsYXRpb25zaGlwTmFtZSBpbiByZWxhdGlvbnNoaXBzTWFwKSB7XG4gICAgICAgIGNvbnN0IHJlbGF0aW9uc2hpcCA9IG1vZGVsLmdldFJlbGF0aW9uc2hpcEJ5TmFtZShyZWxhdGlvbnNoaXBOYW1lKVxuXG4gICAgICAgIGlmICghcmVsYXRpb25zaGlwLmdldFByZWxvYWRlZCgpKSBjb250aW51ZVxuXG4gICAgICAgIGNvbnN0IGxvYWRlZFJlbGF0aW9uc2hpcCA9IHJlbGF0aW9uc2hpcC5sb2FkZWQoKVxuXG4gICAgICAgIGlmIChBcnJheS5pc0FycmF5KGxvYWRlZFJlbGF0aW9uc2hpcCkpIHtcbiAgICAgICAgICBjb2xsZWN0aW9uUmVsYXRpb25zaGlwRW50cmllcy5wdXNoKHtsb2FkZWRNb2RlbHM6IGxvYWRlZFJlbGF0aW9uc2hpcCwgbW9kZWxJbmRleCwgcmVsYXRpb25zaGlwTmFtZX0pXG4gICAgICAgICAgY29udGludWVcbiAgICAgICAgfVxuXG4gICAgICAgIGlmICh0aGlzLmlzU2VyaWFsaXphYmxlRnJvbnRlbmRNb2RlbChsb2FkZWRSZWxhdGlvbnNoaXApKSB7XG4gICAgICAgICAgc2luZ3VsYXJSZWxhdGlvbnNoaXBFbnRyaWVzLnB1c2goe2xvYWRlZE1vZGVsOiBsb2FkZWRSZWxhdGlvbnNoaXAsIG1vZGVsSW5kZXgsIHJlbGF0aW9uc2hpcE5hbWV9KVxuICAgICAgICAgIGNvbnRpbnVlXG4gICAgICAgIH1cblxuICAgICAgICBwcmVsb2FkZWRSZWxhdGlvbnNoaXBzUGVyTW9kZWxbbW9kZWxJbmRleF1bcmVsYXRpb25zaGlwTmFtZV0gPSBsb2FkZWRSZWxhdGlvbnNoaXAgPT0gdW5kZWZpbmVkID8gbnVsbCA6IGxvYWRlZFJlbGF0aW9uc2hpcFxuICAgICAgfVxuICAgIH0pXG5cbiAgICBpZiAoY29sbGVjdGlvblJlbGF0aW9uc2hpcEVudHJpZXMubGVuZ3RoID4gMCkge1xuICAgICAgY29uc3QgYWxsQ29sbGVjdGlvbk1vZGVscyA9IGNvbGxlY3Rpb25SZWxhdGlvbnNoaXBFbnRyaWVzLmZsYXRNYXAoKGVudHJ5KSA9PiBlbnRyeS5sb2FkZWRNb2RlbHMpXG4gICAgICBjb25zdCBzZXJpYWxpemFibGVDb2xsZWN0aW9uTW9kZWxzID0gYXdhaXQgdGhpcy5mcm9udGVuZE1vZGVsRmlsdGVyU2VyaWFsaXphYmxlUmVsYXRlZE1vZGVscyh7XG4gICAgICAgIG1vZGVsczogYWxsQ29sbGVjdGlvbk1vZGVscyxcbiAgICAgICAgcmVsYXRpb25zaGlwSXNDb2xsZWN0aW9uOiB0cnVlXG4gICAgICB9KVxuICAgICAgY29uc3Qgc2VyaWFsaXphYmxlQ29sbGVjdGlvbk1vZGVsc1NldCA9IG5ldyBTZXQoc2VyaWFsaXphYmxlQ29sbGVjdGlvbk1vZGVscylcblxuICAgICAgZm9yIChjb25zdCByZWxhdGlvbnNoaXBFbnRyeSBvZiBjb2xsZWN0aW9uUmVsYXRpb25zaGlwRW50cmllcykge1xuICAgICAgICBjb25zdCBhbGxvd2VkTW9kZWxzID0gcmVsYXRpb25zaGlwRW50cnkubG9hZGVkTW9kZWxzLmZpbHRlcigocmVsYXRlZE1vZGVsKSA9PiBzZXJpYWxpemFibGVDb2xsZWN0aW9uTW9kZWxzU2V0LmhhcyhyZWxhdGVkTW9kZWwpKVxuICAgICAgICBjb25zdCBzZXJpYWxpemVkUmVsYXRlZE1vZGVscyA9IGF3YWl0IHRoaXMuc2VyaWFsaXplRnJvbnRlbmRNb2RlbHMoYWxsb3dlZE1vZGVscylcblxuICAgICAgICBwcmVsb2FkZWRSZWxhdGlvbnNoaXBzUGVyTW9kZWxbcmVsYXRpb25zaGlwRW50cnkubW9kZWxJbmRleF1bcmVsYXRpb25zaGlwRW50cnkucmVsYXRpb25zaGlwTmFtZV0gPSBzZXJpYWxpemVkUmVsYXRlZE1vZGVsc1xuICAgICAgfVxuICAgIH1cblxuICAgIGlmIChzaW5ndWxhclJlbGF0aW9uc2hpcEVudHJpZXMubGVuZ3RoID4gMCkge1xuICAgICAgY29uc3QgYWxsU2luZ3VsYXJNb2RlbHMgPSBzaW5ndWxhclJlbGF0aW9uc2hpcEVudHJpZXMubWFwKChlbnRyeSkgPT4gZW50cnkubG9hZGVkTW9kZWwpXG4gICAgICBjb25zdCBzZXJpYWxpemFibGVTaW5ndWxhck1vZGVscyA9IGF3YWl0IHRoaXMuZnJvbnRlbmRNb2RlbEZpbHRlclNlcmlhbGl6YWJsZVJlbGF0ZWRNb2RlbHMoe1xuICAgICAgICBtb2RlbHM6IGFsbFNpbmd1bGFyTW9kZWxzLFxuICAgICAgICByZWxhdGlvbnNoaXBJc0NvbGxlY3Rpb246IGZhbHNlXG4gICAgICB9KVxuICAgICAgY29uc3Qgc2VyaWFsaXphYmxlU2luZ3VsYXJNb2RlbHNTZXQgPSBuZXcgU2V0KHNlcmlhbGl6YWJsZVNpbmd1bGFyTW9kZWxzKVxuXG4gICAgICBmb3IgKGNvbnN0IHJlbGF0aW9uc2hpcEVudHJ5IG9mIHNpbmd1bGFyUmVsYXRpb25zaGlwRW50cmllcykge1xuICAgICAgICBpZiAoIXNlcmlhbGl6YWJsZVNpbmd1bGFyTW9kZWxzU2V0LmhhcyhyZWxhdGlvbnNoaXBFbnRyeS5sb2FkZWRNb2RlbCkpIHtcbiAgICAgICAgICBwcmVsb2FkZWRSZWxhdGlvbnNoaXBzUGVyTW9kZWxbcmVsYXRpb25zaGlwRW50cnkubW9kZWxJbmRleF1bcmVsYXRpb25zaGlwRW50cnkucmVsYXRpb25zaGlwTmFtZV0gPSBudWxsXG4gICAgICAgICAgY29udGludWVcbiAgICAgICAgfVxuXG4gICAgICAgIGNvbnN0IHNlcmlhbGl6ZWRNb2RlbCA9IChhd2FpdCB0aGlzLnNlcmlhbGl6ZUZyb250ZW5kTW9kZWxzKFtyZWxhdGlvbnNoaXBFbnRyeS5sb2FkZWRNb2RlbF0pKVswXVxuICAgICAgICBwcmVsb2FkZWRSZWxhdGlvbnNoaXBzUGVyTW9kZWxbcmVsYXRpb25zaGlwRW50cnkubW9kZWxJbmRleF1bcmVsYXRpb25zaGlwRW50cnkucmVsYXRpb25zaGlwTmFtZV0gPSBzZXJpYWxpemVkTW9kZWxcbiAgICAgIH1cbiAgICB9XG5cbiAgICAvKiogQHR5cGUge1JlY29yZDxzdHJpbmcsIGFueT5bXX0gKi9cbiAgICBjb25zdCBzZXJpYWxpemVkTW9kZWxzID0gW11cblxuICAgIGZvciAoY29uc3QgW21vZGVsSW5kZXgsIG1vZGVsXSBvZiBtb2RlbHMuZW50cmllcygpKSB7XG4gICAgICBjb25zdCBzZXJpYWxpemVkQXR0cmlidXRlcyA9IGF3YWl0IHRoaXMuc2VyaWFsaXplRnJvbnRlbmRNb2RlbEF0dHJpYnV0ZXMobW9kZWwpXG4gICAgICBjb25zdCBwcmVsb2FkZWRSZWxhdGlvbnNoaXBzID0gcHJlbG9hZGVkUmVsYXRpb25zaGlwc1Blck1vZGVsW21vZGVsSW5kZXhdXG4gICAgICBjb25zdCBhc3NvY2lhdGlvbkNvdW50cyA9IHR5cGVvZiBtb2RlbC5hc3NvY2lhdGlvbkNvdW50cyA9PT0gXCJmdW5jdGlvblwiXG4gICAgICAgID8gbW9kZWwuYXNzb2NpYXRpb25Db3VudHMoKVxuICAgICAgICA6IHt9XG4gICAgICBjb25zdCBxdWVyeURhdGFWYWx1ZXMgPSB0eXBlb2YgbW9kZWwucXVlcnlEYXRhVmFsdWVzID09PSBcImZ1bmN0aW9uXCJcbiAgICAgICAgPyBtb2RlbC5xdWVyeURhdGFWYWx1ZXMoKVxuICAgICAgICA6IHt9XG4gICAgICBjb25zdCBjb21wdXRlZEFiaWxpdGllcyA9IHR5cGVvZiBtb2RlbC5jb21wdXRlZEFiaWxpdGllcyA9PT0gXCJmdW5jdGlvblwiXG4gICAgICAgID8gbW9kZWwuY29tcHV0ZWRBYmlsaXRpZXMoKVxuICAgICAgICA6IHt9XG4gICAgICBjb25zdCBoYXNDb3VudHMgPSBPYmplY3Qua2V5cyhhc3NvY2lhdGlvbkNvdW50cykubGVuZ3RoID4gMFxuICAgICAgY29uc3QgaGFzUXVlcnlEYXRhID0gT2JqZWN0LmtleXMocXVlcnlEYXRhVmFsdWVzKS5sZW5ndGggPiAwXG4gICAgICBjb25zdCBoYXNBYmlsaXRpZXMgPSBPYmplY3Qua2V5cyhjb21wdXRlZEFiaWxpdGllcykubGVuZ3RoID4gMFxuICAgICAgY29uc3QgaGFzUHJlbG9hZGVkID0gT2JqZWN0LmtleXMocHJlbG9hZGVkUmVsYXRpb25zaGlwcykubGVuZ3RoID4gMFxuXG4gICAgICBpZiAoIWhhc1ByZWxvYWRlZCAmJiAhaGFzQ291bnRzICYmICFoYXNRdWVyeURhdGEgJiYgIWhhc0FiaWxpdGllcykge1xuICAgICAgICBzZXJpYWxpemVkTW9kZWxzLnB1c2goc2VyaWFsaXplZEF0dHJpYnV0ZXMpXG4gICAgICAgIGNvbnRpbnVlXG4gICAgICB9XG5cbiAgICAgIC8qKiBAdHlwZSB7UmVjb3JkPHN0cmluZywgYW55Pn0gKi9cbiAgICAgIGNvbnN0IHNlcmlhbGl6ZWQgPSB7Li4uc2VyaWFsaXplZEF0dHJpYnV0ZXN9XG5cbiAgICAgIGlmIChoYXNQcmVsb2FkZWQpIHNlcmlhbGl6ZWQuX19wcmVsb2FkZWRSZWxhdGlvbnNoaXBzID0gcHJlbG9hZGVkUmVsYXRpb25zaGlwc1xuICAgICAgaWYgKGhhc0NvdW50cykgc2VyaWFsaXplZC5fX2Fzc29jaWF0aW9uQ291bnRzID0gYXNzb2NpYXRpb25Db3VudHNcbiAgICAgIGlmIChoYXNRdWVyeURhdGEpIHNlcmlhbGl6ZWQuX19xdWVyeURhdGEgPSBxdWVyeURhdGFWYWx1ZXNcbiAgICAgIGlmIChoYXNBYmlsaXRpZXMpIHNlcmlhbGl6ZWQuX19hYmlsaXRpZXMgPSBjb21wdXRlZEFiaWxpdGllc1xuXG4gICAgICBzZXJpYWxpemVkTW9kZWxzLnB1c2goc2VyaWFsaXplZClcbiAgICB9XG5cbiAgICByZXR1cm4gc2VyaWFsaXplZE1vZGVsc1xuICB9XG5cbiAgLyoqXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi9kYXRhYmFzZS9yZWNvcmQvaW5kZXguanNcIikuZGVmYXVsdH0gbW9kZWwgLSBGcm9udGVuZCBtb2RlbCByZWNvcmQuXG4gICAqIEByZXR1cm5zIHtQcm9taXNlPFJlY29yZDxzdHJpbmcsIGFueT4+fSAtIFNlcmlhbGl6ZWQgZnJvbnRlbmQgbW9kZWwgcGF5bG9hZC5cbiAgICovXG4gIGFzeW5jIHNlcmlhbGl6ZUZyb250ZW5kTW9kZWwobW9kZWwpIHtcbiAgICBjb25zdCBzZXJpYWxpemVkTW9kZWxzID0gYXdhaXQgdGhpcy5zZXJpYWxpemVGcm9udGVuZE1vZGVscyhbbW9kZWxdKVxuXG4gICAgcmV0dXJuIHNlcmlhbGl6ZWRNb2RlbHNbMF1cbiAgfVxuXG4gIC8qKlxuICAgKiBAcGFyYW0ge3N0cmluZ30gZXJyb3JNZXNzYWdlIC0gRXJyb3IgbWVzc2FnZS5cbiAgICogQHJldHVybnMge1Byb21pc2U8dm9pZD59IC0gUmVzb2x2ZXMgd2hlbiBlcnJvciBoYXMgYmVlbiByZW5kZXJlZC5cbiAgICovXG4gIGFzeW5jIGZyb250ZW5kTW9kZWxSZW5kZXJFcnJvcihlcnJvck1lc3NhZ2UpIHtcbiAgICBhd2FpdCB0aGlzLmxvZ2dlci5lcnJvcihgRnJvbnRlbmQgbW9kZWwgcmVxdWVzdCBmYWlsZWQ6ICR7ZXJyb3JNZXNzYWdlfWApXG5cbiAgICBjb25zdCByZW5kZXJFcnJvciA9IC8qKiBAdHlwZSB7KChlcnJvck1lc3NhZ2U6IHN0cmluZykgPT4gUHJvbWlzZTx2b2lkPikgfCB1bmRlZmluZWR9ICovIChcbiAgICAgIC8qKiBAdHlwZSB7YW55fSAqLyAodGhpcykucmVuZGVyRXJyb3JcbiAgICApXG5cbiAgICBpZiAodHlwZW9mIHJlbmRlckVycm9yID09PSBcImZ1bmN0aW9uXCIpIHtcbiAgICAgIGF3YWl0IHJlbmRlckVycm9yLmNhbGwodGhpcywgZnJvbnRlbmRNb2RlbENsaWVudFNhZmVFcnJvck1lc3NhZ2UpXG4gICAgICByZXR1cm5cbiAgICB9XG5cbiAgICBhd2FpdCB0aGlzLnJlbmRlcih7XG4gICAgICBqc29uOiAvKiogQHR5cGUge1JlY29yZDxzdHJpbmcsIGFueT59ICovIChzZXJpYWxpemVGcm9udGVuZE1vZGVsVHJhbnNwb3J0VmFsdWUoe1xuICAgICAgICBlcnJvck1lc3NhZ2U6IGZyb250ZW5kTW9kZWxDbGllbnRTYWZlRXJyb3JNZXNzYWdlLFxuICAgICAgICBzdGF0dXM6IFwiZXJyb3JcIlxuICAgICAgfSkpXG4gICAgfSlcbiAgfVxuXG4gIC8qKlxuICAgKiBAcGFyYW0ge3N0cmluZ30gZXJyb3JNZXNzYWdlIC0gRXJyb3IgbWVzc2FnZS5cbiAgICogQHJldHVybnMge1JlY29yZDxzdHJpbmcsIGFueT59IC0gRXJyb3IgcGF5bG9hZC5cbiAgICovXG4gIGZyb250ZW5kTW9kZWxFcnJvclBheWxvYWQoZXJyb3JNZXNzYWdlKSB7XG4gICAgcmV0dXJuIHtcbiAgICAgIGVycm9yTWVzc2FnZSxcbiAgICAgIHN0YXR1czogXCJlcnJvclwiXG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIEByZXR1cm5zIHtSZWNvcmQ8c3RyaW5nLCBhbnk+fSAtIENsaWVudC1zYWZlIGVycm9yIHBheWxvYWQuXG4gICAqL1xuICBmcm9udGVuZE1vZGVsQ2xpZW50U2FmZUVycm9yUGF5bG9hZCgpIHtcbiAgICByZXR1cm4gdGhpcy5mcm9udGVuZE1vZGVsRXJyb3JQYXlsb2FkKGZyb250ZW5kTW9kZWxDbGllbnRTYWZlRXJyb3JNZXNzYWdlKVxuICB9XG5cbiAgLyoqXG4gICAqIEBwYXJhbSB7dW5rbm93bn0gZXJyb3IgLSBDYXVnaHQgZXJyb3IuXG4gICAqIEByZXR1cm5zIHtSZWNvcmQ8c3RyaW5nLCBhbnk+fSAtIENsaWVudCBwYXlsb2FkIGZvciB0aGUgY3VycmVudCBlbnZpcm9ubWVudC5cbiAgICovXG4gIGZyb250ZW5kTW9kZWxDbGllbnRFcnJvclBheWxvYWRGb3JFcnJvcihlcnJvcikge1xuICAgIGNvbnN0IHZlbG9jaW91c01ldGFkYXRhID0gZnJvbnRlbmRNb2RlbFZlbG9jaW91c01ldGFkYXRhRm9yRXJyb3IoZXJyb3IpXG5cbiAgICBsZXQgdmFsaWRhdGlvbkVycm9yc1BheWxvYWQgPSB7fVxuXG4gICAgaWYgKGVycm9yIGluc3RhbmNlb2YgVmFsaWRhdGlvbkVycm9yKSB7XG4gICAgICBjb25zdCB2YWxpZGF0aW9uRXJyb3JzID0gZXJyb3IuZ2V0VmFsaWRhdGlvbkVycm9ycygpXG4gICAgICBjb25zdCBtb2RlbCA9IGVycm9yLmdldE1vZGVsKClcbiAgICAgIC8qKiBAdHlwZSB7UmVjb3JkPHN0cmluZywge3R5cGU6IHN0cmluZywgbWVzc2FnZTogc3RyaW5nLCBmdWxsTWVzc2FnZTogc3RyaW5nfVtdPn0gKi9cbiAgICAgIGNvbnN0IHN0cnVjdHVyZWRFcnJvcnMgPSB7fVxuXG4gICAgICBmb3IgKGNvbnN0IGF0dHJpYnV0ZU5hbWUgaW4gdmFsaWRhdGlvbkVycm9ycykge1xuICAgICAgICBzdHJ1Y3R1cmVkRXJyb3JzW2F0dHJpYnV0ZU5hbWVdID0gdmFsaWRhdGlvbkVycm9yc1thdHRyaWJ1dGVOYW1lXS5tYXAoZXJyID0+ICh7XG4gICAgICAgICAgdHlwZTogZXJyLnR5cGUsXG4gICAgICAgICAgbWVzc2FnZTogZXJyLm1lc3NhZ2UsXG4gICAgICAgICAgZnVsbE1lc3NhZ2U6IGAke21vZGVsLmdldE1vZGVsQ2xhc3MoKS5odW1hbkF0dHJpYnV0ZU5hbWUoYXR0cmlidXRlTmFtZSl9ICR7ZXJyLm1lc3NhZ2V9YFxuICAgICAgICB9KSlcbiAgICAgIH1cblxuICAgICAgdmFsaWRhdGlvbkVycm9yc1BheWxvYWQgPSB7XG4gICAgICAgIGVycm9yVHlwZTogXCJ2YWxpZGF0aW9uX2Vycm9yXCIsXG4gICAgICAgIHZhbGlkYXRpb25FcnJvcnM6IHN0cnVjdHVyZWRFcnJvcnNcbiAgICAgIH1cbiAgICB9XG5cbiAgICByZXR1cm4ge1xuICAgICAgLi4udGhpcy5mcm9udGVuZE1vZGVsRXJyb3JQYXlsb2FkKGZyb250ZW5kTW9kZWxDbGllbnRNZXNzYWdlRm9yRXJyb3IoZXJyb3IpKSxcbiAgICAgIC4uLmZyb250ZW5kTW9kZWxEZWJ1Z1BheWxvYWRGb3JFcnJvcih7XG4gICAgICAgIGNvbmZpZ3VyYXRpb246IHRoaXMuZ2V0Q29uZmlndXJhdGlvbigpLFxuICAgICAgICBlbnZpcm9ubWVudDogdGhpcy5nZXRDb25maWd1cmF0aW9uKCkuZ2V0RW52aXJvbm1lbnQoKSxcbiAgICAgICAgZXJyb3JcbiAgICAgIH0pLFxuICAgICAgLi4uKHZlbG9jaW91c01ldGFkYXRhID8ge3ZlbG9jaW91czogdmVsb2Npb3VzTWV0YWRhdGF9IDoge30pLFxuICAgICAgLi4udmFsaWRhdGlvbkVycm9yc1BheWxvYWRcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogQHBhcmFtIHtvYmplY3R9IGFyZ3MgLSBFcnJvciBsb2cgYXJncy5cbiAgICogQHBhcmFtIHtzdHJpbmd9IGFyZ3MuYWN0aW9uIC0gRW5kcG9pbnQvYWN0aW9uIGxhYmVsLlxuICAgKiBAcGFyYW0ge3Vua25vd259IGFyZ3MuZXJyb3IgLSBDYXVnaHQgZXJyb3IuXG4gICAqIEBwYXJhbSB7XCJpbmRleFwiIHwgXCJmaW5kXCIgfCBcImNyZWF0ZVwiIHwgXCJ1cGRhdGVcIiB8IFwiZGVzdHJveVwiIHwgXCJhdHRhY2hcIiB8IFwiZG93bmxvYWRcIiB8IFwidXJsXCIgfCBcImN1c3RvbS1jb21tYW5kXCJ9IFthcmdzLmNvbW1hbmRUeXBlXSAtIEZyb250ZW5kLW1vZGVsIGNvbW1hbmQgdHlwZS5cbiAgICogQHBhcmFtIHtzdHJpbmcgfCB1bmRlZmluZWR9IFthcmdzLm1vZGVsXSAtIFJlcXVlc3QgbW9kZWwgbmFtZSB3aGVuIGF2YWlsYWJsZS5cbiAgICogQHBhcmFtIHtzdHJpbmcgfCB1bmRlZmluZWR9IFthcmdzLnJlcXVlc3RJZF0gLSBCYXRjaCByZXF1ZXN0IGlkIHdoZW4gYXZhaWxhYmxlLlxuICAgKiBAcmV0dXJucyB7UHJvbWlzZTx2b2lkPn0gLSBSZXNvbHZlcyBhZnRlciBsb2dnaW5nLlxuICAgKi9cbiAgYXN5bmMgZnJvbnRlbmRNb2RlbExvZ0VuZHBvaW50RXJyb3Ioe2FjdGlvbiwgZXJyb3IsIGNvbW1hbmRUeXBlLCBtb2RlbCwgcmVxdWVzdElkfSkge1xuICAgIC8vIEVycm9ycyBhbm5vdGF0ZWQgd2l0aCBgZXJyb3IudmVsb2Npb3VzID0gey4uLn1gIGFyZSB1c2VyLWZsb3dcbiAgICAvLyBmYWlsdXJlcyB0aGUgZGV2ZWxvcGVyIGhhcyBtYXJrZWQgYXMgZXhwZWN0ZWQgKGJhZCBwYXNzd29yZCxcbiAgICAvLyB2YWxpZGF0aW9uIG1lc3NhZ2UsIGV0Yy4pLiBTdXJmYWNlIHRoZSBtZXNzYWdlICsgbWV0YWRhdGEgdG9cbiAgICAvLyB0aGUgY2xpZW50IChoYW5kbGVkIGJ5IGZyb250ZW5kTW9kZWxDbGllbnRFcnJvclBheWxvYWRGb3JFcnJvciksXG4gICAgLy8gYnV0IHNraXAgdGhlIGVycm9yIGxvZyBzbyBtb25pdG9yaW5nIHN0YXlzIGZvY3VzZWQgb24gcmVhbFxuICAgIC8vIGJhY2tlbmQgZmFpbHVyZXMuXG4gICAgaWYgKGZyb250ZW5kTW9kZWxFcnJvckhhc1ZlbG9jaW91c01ldGFkYXRhKGVycm9yKSkgcmV0dXJuXG5cbiAgICBsZXQgcmVzb2x2ZWRNb2RlbCA9IG1vZGVsXG5cbiAgICBpZiAoIXJlc29sdmVkTW9kZWwpIHtcbiAgICAgIHRyeSB7XG4gICAgICAgIHJlc29sdmVkTW9kZWwgPSB0aGlzLmZyb250ZW5kTW9kZWxQYXJhbXMoKS5tb2RlbFxuICAgICAgfSBjYXRjaCB7XG4gICAgICAgIHJlc29sdmVkTW9kZWwgPSB1bmRlZmluZWRcbiAgICAgIH1cbiAgICB9XG5cbiAgICBjb25zdCBlcnJvck1lc3NhZ2UgPSBlcnJvciBpbnN0YW5jZW9mIEVycm9yXG4gICAgICA/IGAke2Vycm9yLm1lc3NhZ2V9XFxuJHtlcnJvci5zdGFjayB8fCBcIlwifWBcbiAgICAgIDogU3RyaW5nKGVycm9yKVxuXG4gICAgYXdhaXQgdGhpcy5sb2dnZXIuZXJyb3IoKCkgPT4gW1wiRnJvbnRlbmQgbW9kZWwgZW5kcG9pbnQgcmVxdWVzdCBmYWlsZWRcIiwge1xuICAgICAgYWN0aW9uLFxuICAgICAgY29tbWFuZFR5cGUsXG4gICAgICBlcnJvcjogZXJyb3JNZXNzYWdlLFxuICAgICAgbW9kZWw6IHJlc29sdmVkTW9kZWwsXG4gICAgICByZXF1ZXN0SWRcbiAgICB9XSlcbiAgfVxuXG4gIC8qKlxuICAgKiBAcGFyYW0ge1wiaW5kZXhcIiB8IFwiZmluZFwiIHwgXCJjcmVhdGVcIiB8IFwidXBkYXRlXCIgfCBcImRlc3Ryb3lcIiB8IFwiYXR0YWNoXCIgfCBcImRvd25sb2FkXCIgfCBcInVybFwifSBhY3Rpb24gLSBGcm9udGVuZCBhY3Rpb24uXG4gICAqIEByZXR1cm5zIHtQcm9taXNlPHZvaWQ+fSAtIFJlc29sdmVzIHdoZW4gcmVzcG9uc2UgaGFzIGJlZW4gcmVuZGVyZWQuXG4gICAqL1xuICBhc3luYyBmcm9udGVuZE1vZGVsUmVuZGVyQ29tbWFuZFJlc3BvbnNlKGFjdGlvbikge1xuICAgIHRyeSB7XG4gICAgICBjb25zdCByZXNwb25zZVBheWxvYWQgPSBhd2FpdCB0aGlzLmZyb250ZW5kTW9kZWxDb21tYW5kUGF5bG9hZChhY3Rpb24pXG4gICAgICBpZiAoIXJlc3BvbnNlUGF5bG9hZCkgcmV0dXJuXG5cbiAgICAgIGF3YWl0IHRoaXMucmVuZGVyKHtcbiAgICAgICAganNvbjogLyoqIEB0eXBlIHtSZWNvcmQ8c3RyaW5nLCBhbnk+fSAqLyAoc2VyaWFsaXplRnJvbnRlbmRNb2RlbFRyYW5zcG9ydFZhbHVlKHJlc3BvbnNlUGF5bG9hZCkpXG4gICAgICB9KVxuICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICBhd2FpdCB0aGlzLmZyb250ZW5kTW9kZWxMb2dFbmRwb2ludEVycm9yKHthY3Rpb24sIGNvbW1hbmRUeXBlOiBhY3Rpb24sIGVycm9yfSlcblxuICAgICAgYXdhaXQgdGhpcy5yZW5kZXIoe1xuICAgICAgICBqc29uOiAvKiogQHR5cGUge1JlY29yZDxzdHJpbmcsIGFueT59ICovIChzZXJpYWxpemVGcm9udGVuZE1vZGVsVHJhbnNwb3J0VmFsdWUodGhpcy5mcm9udGVuZE1vZGVsQ2xpZW50RXJyb3JQYXlsb2FkRm9yRXJyb3IoZXJyb3IpKSlcbiAgICAgIH0pXG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIEBwYXJhbSB7XCJpbmRleFwiIHwgXCJmaW5kXCIgfCBcImNyZWF0ZVwiIHwgXCJ1cGRhdGVcIiB8IFwiZGVzdHJveVwiIHwgXCJhdHRhY2hcIiB8IFwiZG93bmxvYWRcIiB8IFwidXJsXCJ9IGFjdGlvbiAtIEZyb250ZW5kIGFjdGlvbi5cbiAgICogQHJldHVybnMge1Byb21pc2U8UmVjb3JkPHN0cmluZywgYW55PiB8IG51bGw+fSAtIFJlc3BvbnNlIHBheWxvYWQuXG4gICAqL1xuICBhc3luYyBmcm9udGVuZE1vZGVsQ29tbWFuZFBheWxvYWQoYWN0aW9uKSB7XG4gICAgYXdhaXQgdGhpcy5lbnN1cmVGcm9udGVuZE1vZGVsQ2xhc3NJbml0aWFsaXplZCgpXG5cbiAgICBpZiAoIShhd2FpdCB0aGlzLnJ1bkZyb250ZW5kTW9kZWxCZWZvcmVBY3Rpb24oYWN0aW9uKSkpIHtcbiAgICAgIHJldHVybiBudWxsXG4gICAgfVxuXG4gICAgY29uc3QgcmVzb3VyY2UgPSB0aGlzLmZyb250ZW5kTW9kZWxSZXNvdXJjZUluc3RhbmNlKClcblxuICAgIGlmIChhY3Rpb24gPT09IFwiaW5kZXhcIikge1xuICAgICAgaWYgKHRoaXMuZnJvbnRlbmRNb2RlbENvdW50UmVxdWVzdGVkKCkpIHtcbiAgICAgICAgaWYgKCEoYXdhaXQgcmVzb3VyY2Uuc3VwcG9ydHNDb3VudChcImluZGV4XCIpKSkge1xuICAgICAgICAgIHRocm93IG5ldyBFcnJvcihcImNvdW50IGlzIG5vdCBzdXBwb3J0ZWQgd2hlbiByZXNvdXJjZSByZWNvcmRzIGFyZSBjdXN0b21pemVkXCIpXG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgIGNvdW50OiBhd2FpdCByZXNvdXJjZS5jb3VudCgpLFxuICAgICAgICAgIHN0YXR1czogXCJzdWNjZXNzXCJcbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICBjb25zdCBwbHVjayA9IHRoaXMuZnJvbnRlbmRNb2RlbFBsdWNrKClcblxuICAgICAgaWYgKHBsdWNrLmxlbmd0aCA+IDApIHtcbiAgICAgICAgaWYgKCEoYXdhaXQgcmVzb3VyY2Uuc3VwcG9ydHNQbHVjayhcImluZGV4XCIpKSkge1xuICAgICAgICAgIHRocm93IG5ldyBFcnJvcihcInBsdWNrIGlzIG5vdCBzdXBwb3J0ZWQgd2hlbiByZXNvdXJjZSByZWNvcmRzIGFyZSBjdXN0b21pemVkXCIpXG4gICAgICAgIH1cblxuICAgICAgICBjb25zdCB2YWx1ZXMgPSBhd2FpdCB0aGlzLmZyb250ZW5kTW9kZWxQbHVja1ZhbHVlcyh7XG4gICAgICAgICAgcGx1Y2ssXG4gICAgICAgICAgcXVlcnk6IHRoaXMuZnJvbnRlbmRNb2RlbEluZGV4UXVlcnkoKVxuICAgICAgICB9KVxuXG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgc3RhdHVzOiBcInN1Y2Nlc3NcIixcbiAgICAgICAgICB2YWx1ZXNcbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICBjb25zdCBtb2RlbHMgPSBhd2FpdCB0aGlzLmZyb250ZW5kTW9kZWxSZWNvcmRzKClcbiAgICAgIGF3YWl0IHRoaXMuZnJvbnRlbmRNb2RlbENvbXB1dGVBYmlsaXRpZXMobW9kZWxzKVxuICAgICAgY29uc3Qgc2VyaWFsaXplZE1vZGVscyA9IGF3YWl0IFByb21pc2UuYWxsKG1vZGVscy5tYXAoYXN5bmMgKG1vZGVsKSA9PiBhd2FpdCByZXNvdXJjZS5zZXJpYWxpemUobW9kZWwsIFwiaW5kZXhcIikpKVxuXG4gICAgICByZXR1cm4ge1xuICAgICAgICBtb2RlbHM6IHNlcmlhbGl6ZWRNb2RlbHMsXG4gICAgICAgIHN0YXR1czogXCJzdWNjZXNzXCJcbiAgICAgIH1cbiAgICB9XG5cbiAgICBjb25zdCBwYXJhbXMgPSB0aGlzLmZyb250ZW5kTW9kZWxQYXJhbXMoKVxuICAgIGNvbnN0IG1vZGVsQ2xhc3MgPSB0aGlzLmZyb250ZW5kTW9kZWxDbGFzcygpXG4gICAgY29uc3QgaWQgPSBwYXJhbXMuaWRcblxuICAgIGlmIChhY3Rpb24gPT09IFwiY3JlYXRlXCIpIHtcbiAgICAgIGNvbnN0IGF0dHJpYnV0ZXMgPSBwYXJhbXMuYXR0cmlidXRlc1xuXG4gICAgICBpZiAoIWF0dHJpYnV0ZXMgfHwgdHlwZW9mIGF0dHJpYnV0ZXMgIT09IFwib2JqZWN0XCIpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZnJvbnRlbmRNb2RlbEVycm9yUGF5bG9hZChcIkV4cGVjdGVkIG1vZGVsIGF0dHJpYnV0ZXMuXCIpXG4gICAgICB9XG5cbiAgICAgIGNvbnN0IG5lc3RlZEF0dHJpYnV0ZXMgPSBwYXJhbXMubmVzdGVkQXR0cmlidXRlcyAmJiB0eXBlb2YgcGFyYW1zLm5lc3RlZEF0dHJpYnV0ZXMgPT09IFwib2JqZWN0XCJcbiAgICAgICAgPyAvKiogQHR5cGUge1JlY29yZDxzdHJpbmcsIGFueT59ICovIChwYXJhbXMubmVzdGVkQXR0cmlidXRlcylcbiAgICAgICAgOiBudWxsXG5cbiAgICAgIGNvbnN0IG1vZGVsID0gYXdhaXQgdGhpcy5mcm9udGVuZE1vZGVsQ3JlYXRlUmVjb3JkKGF0dHJpYnV0ZXMsIG5lc3RlZEF0dHJpYnV0ZXMpXG5cbiAgICAgIGlmICghbW9kZWwpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZnJvbnRlbmRNb2RlbEVycm9yUGF5bG9hZChgJHttb2RlbENsYXNzLm5hbWV9IG5vdCBmb3VuZC5gKVxuICAgICAgfVxuXG4gICAgICBjb25zdCBzZXJpYWxpemVkTW9kZWwgPSBhd2FpdCByZXNvdXJjZS5zZXJpYWxpemUobW9kZWwsIFwiY3JlYXRlXCIpXG5cbiAgICAgIHJldHVybiB7XG4gICAgICAgIG1vZGVsOiBzZXJpYWxpemVkTW9kZWwsXG4gICAgICAgIHN0YXR1czogXCJzdWNjZXNzXCJcbiAgICAgIH1cbiAgICB9XG5cbiAgICBpZiAoKHR5cGVvZiBpZCAhPT0gXCJzdHJpbmdcIiAmJiB0eXBlb2YgaWQgIT09IFwibnVtYmVyXCIpIHx8IGAke2lkfWAubGVuZ3RoIDwgMSkge1xuICAgICAgcmV0dXJuIHRoaXMuZnJvbnRlbmRNb2RlbEVycm9yUGF5bG9hZChcIkV4cGVjdGVkIG1vZGVsIGlkLlwiKVxuICAgIH1cblxuICAgIGlmIChhY3Rpb24gPT09IFwiYXR0YWNoXCIpIHtcbiAgICAgIGNvbnN0IGF0dGFjaG1lbnROYW1lID0gcGFyYW1zLmF0dGFjaG1lbnROYW1lXG4gICAgICBjb25zdCBhdHRhY2htZW50SW5wdXQgPSBwYXJhbXMuYXR0YWNobWVudFxuXG4gICAgICBpZiAodHlwZW9mIGF0dGFjaG1lbnROYW1lICE9PSBcInN0cmluZ1wiIHx8IGF0dGFjaG1lbnROYW1lLmxlbmd0aCA8IDEpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZnJvbnRlbmRNb2RlbEVycm9yUGF5bG9hZChcIkV4cGVjdGVkIGF0dGFjaG1lbnROYW1lLlwiKVxuICAgICAgfVxuXG4gICAgICBpZiAodHlwZW9mIGF0dGFjaG1lbnRJbnB1dCA9PT0gXCJ1bmRlZmluZWRcIikge1xuICAgICAgICByZXR1cm4gdGhpcy5mcm9udGVuZE1vZGVsRXJyb3JQYXlsb2FkKFwiRXhwZWN0ZWQgYXR0YWNobWVudCBpbnB1dC5cIilcbiAgICAgIH1cblxuICAgICAgY29uc3QgbW9kZWwgPSBhd2FpdCB0aGlzLmZyb250ZW5kTW9kZWxGaW5kUmVjb3JkKFwiYXR0YWNoXCIsIGlkKVxuXG4gICAgICBpZiAoIW1vZGVsKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmZyb250ZW5kTW9kZWxFcnJvclBheWxvYWQoYCR7bW9kZWxDbGFzcy5uYW1lfSBub3QgZm91bmQuYClcbiAgICAgIH1cblxuICAgICAgYXdhaXQgbW9kZWwuZ2V0QXR0YWNobWVudEJ5TmFtZShhdHRhY2htZW50TmFtZSkuYXR0YWNoKGF0dGFjaG1lbnRJbnB1dClcbiAgICAgIGNvbnN0IHNlcmlhbGl6ZWRNb2RlbCA9IGF3YWl0IHRoaXMuc2VyaWFsaXplRnJvbnRlbmRNb2RlbChtb2RlbClcblxuICAgICAgcmV0dXJuIHtcbiAgICAgICAgbW9kZWw6IHNlcmlhbGl6ZWRNb2RlbCxcbiAgICAgICAgc3RhdHVzOiBcInN1Y2Nlc3NcIlxuICAgICAgfVxuICAgIH1cblxuICAgIGlmIChhY3Rpb24gPT09IFwiZG93bmxvYWRcIikge1xuICAgICAgY29uc3QgYXR0YWNobWVudE5hbWUgPSBwYXJhbXMuYXR0YWNobWVudE5hbWVcbiAgICAgIGNvbnN0IGF0dGFjaG1lbnRJZCA9IHR5cGVvZiBwYXJhbXMuYXR0YWNobWVudElkID09PSBcInN0cmluZ1wiID8gcGFyYW1zLmF0dGFjaG1lbnRJZCA6IHVuZGVmaW5lZFxuXG4gICAgICBpZiAodHlwZW9mIGF0dGFjaG1lbnROYW1lICE9PSBcInN0cmluZ1wiIHx8IGF0dGFjaG1lbnROYW1lLmxlbmd0aCA8IDEpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZnJvbnRlbmRNb2RlbEVycm9yUGF5bG9hZChcIkV4cGVjdGVkIGF0dGFjaG1lbnROYW1lLlwiKVxuICAgICAgfVxuXG4gICAgICBjb25zdCBtb2RlbCA9IGF3YWl0IHRoaXMuZnJvbnRlbmRNb2RlbEZpbmRSZWNvcmQoXCJkb3dubG9hZFwiLCBpZClcblxuICAgICAgaWYgKCFtb2RlbCkge1xuICAgICAgICByZXR1cm4gdGhpcy5mcm9udGVuZE1vZGVsRXJyb3JQYXlsb2FkKGAke21vZGVsQ2xhc3MubmFtZX0gbm90IGZvdW5kLmApXG4gICAgICB9XG5cbiAgICAgIGNvbnN0IGRvd25sb2FkZWRBdHRhY2htZW50ID0gYXdhaXQgbW9kZWwuZ2V0QXR0YWNobWVudEJ5TmFtZShhdHRhY2htZW50TmFtZSkuZG93bmxvYWQoYXR0YWNobWVudElkKVxuXG4gICAgICBpZiAoIWRvd25sb2FkZWRBdHRhY2htZW50KSB7XG4gICAgICAgIHJldHVybiB0aGlzLmZyb250ZW5kTW9kZWxFcnJvclBheWxvYWQoXCJBdHRhY2htZW50IG5vdCBmb3VuZC5cIilcbiAgICAgIH1cblxuICAgICAgcmV0dXJuIHtcbiAgICAgICAgYXR0YWNobWVudDoge1xuICAgICAgICAgIGJ5dGVTaXplOiBkb3dubG9hZGVkQXR0YWNobWVudC5ieXRlU2l6ZSgpLFxuICAgICAgICAgIGNvbnRlbnRCYXNlNjQ6IGRvd25sb2FkZWRBdHRhY2htZW50LmNvbnRlbnQoKS50b1N0cmluZyhcImJhc2U2NFwiKSxcbiAgICAgICAgICBjb250ZW50VHlwZTogZG93bmxvYWRlZEF0dGFjaG1lbnQuY29udGVudFR5cGUoKSxcbiAgICAgICAgICBmaWxlbmFtZTogZG93bmxvYWRlZEF0dGFjaG1lbnQuZmlsZW5hbWUoKSxcbiAgICAgICAgICBpZDogZG93bmxvYWRlZEF0dGFjaG1lbnQuaWQoKSxcbiAgICAgICAgICB1cmw6IGRvd25sb2FkZWRBdHRhY2htZW50LnVybCgpXG4gICAgICAgIH0sXG4gICAgICAgIHN0YXR1czogXCJzdWNjZXNzXCJcbiAgICAgIH1cbiAgICB9XG5cbiAgICBpZiAoYWN0aW9uID09PSBcInVybFwiKSB7XG4gICAgICBjb25zdCBhdHRhY2htZW50TmFtZSA9IHBhcmFtcy5hdHRhY2htZW50TmFtZVxuICAgICAgY29uc3QgYXR0YWNobWVudElkID0gdHlwZW9mIHBhcmFtcy5hdHRhY2htZW50SWQgPT09IFwic3RyaW5nXCIgPyBwYXJhbXMuYXR0YWNobWVudElkIDogdW5kZWZpbmVkXG5cbiAgICAgIGlmICh0eXBlb2YgYXR0YWNobWVudE5hbWUgIT09IFwic3RyaW5nXCIgfHwgYXR0YWNobWVudE5hbWUubGVuZ3RoIDwgMSkge1xuICAgICAgICByZXR1cm4gdGhpcy5mcm9udGVuZE1vZGVsRXJyb3JQYXlsb2FkKFwiRXhwZWN0ZWQgYXR0YWNobWVudE5hbWUuXCIpXG4gICAgICB9XG5cbiAgICAgIGNvbnN0IG1vZGVsID0gYXdhaXQgdGhpcy5mcm9udGVuZE1vZGVsRmluZFJlY29yZChcInVybFwiLCBpZClcblxuICAgICAgaWYgKCFtb2RlbCkge1xuICAgICAgICByZXR1cm4gdGhpcy5mcm9udGVuZE1vZGVsRXJyb3JQYXlsb2FkKGAke21vZGVsQ2xhc3MubmFtZX0gbm90IGZvdW5kLmApXG4gICAgICB9XG5cbiAgICAgIGNvbnN0IHVybCA9IGF3YWl0IG1vZGVsLmdldEF0dGFjaG1lbnRCeU5hbWUoYXR0YWNobWVudE5hbWUpLnVybChhdHRhY2htZW50SWQpXG5cbiAgICAgIGlmICghdXJsKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmZyb250ZW5kTW9kZWxFcnJvclBheWxvYWQoXCJBdHRhY2htZW50IFVSTCBub3QgYXZhaWxhYmxlLlwiKVxuICAgICAgfVxuXG4gICAgICByZXR1cm4ge1xuICAgICAgICBzdGF0dXM6IFwic3VjY2Vzc1wiLFxuICAgICAgICB1cmxcbiAgICAgIH1cbiAgICB9XG5cbiAgICBpZiAoYWN0aW9uID09PSBcImZpbmRcIikge1xuICAgICAgY29uc3QgbW9kZWwgPSBhd2FpdCB0aGlzLmZyb250ZW5kTW9kZWxGaW5kUmVjb3JkKFwiZmluZFwiLCBpZClcblxuICAgICAgaWYgKCFtb2RlbCkge1xuICAgICAgICByZXR1cm4gdGhpcy5mcm9udGVuZE1vZGVsRXJyb3JQYXlsb2FkKGAke21vZGVsQ2xhc3MubmFtZX0gbm90IGZvdW5kLmApXG4gICAgICB9XG5cbiAgICAgIGF3YWl0IHRoaXMuZnJvbnRlbmRNb2RlbENvbXB1dGVBYmlsaXRpZXMoW21vZGVsXSlcbiAgICAgIGNvbnN0IHNlcmlhbGl6ZWRNb2RlbCA9IGF3YWl0IHJlc291cmNlLnNlcmlhbGl6ZShtb2RlbCwgXCJmaW5kXCIpXG5cbiAgICAgIHJldHVybiB7XG4gICAgICAgIG1vZGVsOiBzZXJpYWxpemVkTW9kZWwsXG4gICAgICAgIHN0YXR1czogXCJzdWNjZXNzXCJcbiAgICAgIH1cbiAgICB9XG5cbiAgICBpZiAoYWN0aW9uID09PSBcInVwZGF0ZVwiKSB7XG4gICAgICBjb25zdCBhdHRyaWJ1dGVzID0gcGFyYW1zLmF0dHJpYnV0ZXNcblxuICAgICAgaWYgKCFhdHRyaWJ1dGVzIHx8IHR5cGVvZiBhdHRyaWJ1dGVzICE9PSBcIm9iamVjdFwiKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmZyb250ZW5kTW9kZWxFcnJvclBheWxvYWQoXCJFeHBlY3RlZCBtb2RlbCBhdHRyaWJ1dGVzLlwiKVxuICAgICAgfVxuXG4gICAgICBjb25zdCBuZXN0ZWRBdHRyaWJ1dGVzID0gcGFyYW1zLm5lc3RlZEF0dHJpYnV0ZXMgJiYgdHlwZW9mIHBhcmFtcy5uZXN0ZWRBdHRyaWJ1dGVzID09PSBcIm9iamVjdFwiXG4gICAgICAgID8gLyoqIEB0eXBlIHtSZWNvcmQ8c3RyaW5nLCBhbnk+fSAqLyAocGFyYW1zLm5lc3RlZEF0dHJpYnV0ZXMpXG4gICAgICAgIDogbnVsbFxuXG4gICAgICBjb25zdCBtb2RlbCA9IGF3YWl0IHRoaXMuZnJvbnRlbmRNb2RlbEZpbmRSZWNvcmQoXCJ1cGRhdGVcIiwgaWQpXG5cbiAgICAgIGlmICghbW9kZWwpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZnJvbnRlbmRNb2RlbEVycm9yUGF5bG9hZChgJHttb2RlbENsYXNzLm5hbWV9IG5vdCBmb3VuZC5gKVxuICAgICAgfVxuXG4gICAgICBjb25zdCB1cGRhdGVkTW9kZWwgPSBhd2FpdCByZXNvdXJjZS51cGRhdGUobW9kZWwsIGF0dHJpYnV0ZXMsIHtuZXN0ZWRBdHRyaWJ1dGVzLCBjb250cm9sbGVyOiB0aGlzfSlcbiAgICAgIGNvbnN0IHNlcmlhbGl6ZWRNb2RlbCA9IGF3YWl0IHJlc291cmNlLnNlcmlhbGl6ZSh1cGRhdGVkTW9kZWwsIFwidXBkYXRlXCIpXG5cbiAgICAgIHJldHVybiB7XG4gICAgICAgIG1vZGVsOiBzZXJpYWxpemVkTW9kZWwsXG4gICAgICAgIHN0YXR1czogXCJzdWNjZXNzXCJcbiAgICAgIH1cbiAgICB9XG5cbiAgICBjb25zdCBtb2RlbCA9IGF3YWl0IHRoaXMuZnJvbnRlbmRNb2RlbEZpbmRSZWNvcmQoXCJkZXN0cm95XCIsIGlkKVxuXG4gICAgaWYgKCFtb2RlbCkge1xuICAgICAgcmV0dXJuIHRoaXMuZnJvbnRlbmRNb2RlbEVycm9yUGF5bG9hZChgJHttb2RlbENsYXNzLm5hbWV9IG5vdCBmb3VuZC5gKVxuICAgIH1cblxuICAgIGF3YWl0IHJlc291cmNlLmRlc3Ryb3kobW9kZWwpXG5cbiAgICByZXR1cm4ge3N0YXR1czogXCJzdWNjZXNzXCJ9XG4gIH1cblxuICAvKiogQHJldHVybnMge1Byb21pc2U8dm9pZD59IC0gU2hhcmVkIGZyb250ZW5kIG1vZGVsIEFQSSBhY3Rpb24gd2l0aCBiYXRjaCBzdXBwb3J0LiAqL1xuICBhc3luYyBmcm9udGVuZEFwaSgpIHtcbiAgICBpZiAodGhpcy5yZXF1ZXN0KCkuaHR0cE1ldGhvZCgpID09PSBcIk9QVElPTlNcIikge1xuICAgICAgYXdhaXQgdGhpcy5yZW5kZXIoe3N0YXR1czogMjA0LCBqc29uOiB7fX0pXG4gICAgICByZXR1cm5cbiAgICB9XG5cbiAgICBjb25zdCBwYXJhbXMgPSAvKiogQHR5cGUge1JlY29yZDxzdHJpbmcsIGFueT59ICovIChkZXNlcmlhbGl6ZUZyb250ZW5kTW9kZWxUcmFuc3BvcnRWYWx1ZSh0aGlzLnBhcmFtcygpKSlcbiAgICBjb25zdCByZXF1ZXN0cyA9IEFycmF5LmlzQXJyYXkocGFyYW1zLnJlcXVlc3RzKSA/IHBhcmFtcy5yZXF1ZXN0cyA6IFtwYXJhbXNdXG4gICAgLyoqIEB0eXBlIHtBcnJheTxSZWNvcmQ8c3RyaW5nLCBhbnk+Pn0gKi9cbiAgICBjb25zdCByZXNwb25zZXMgPSBbXVxuXG4gICAgZm9yIChjb25zdCByZXF1ZXN0RW50cnkgb2YgcmVxdWVzdHMpIHtcbiAgICAgIGNvbnN0IGNvbW1hbmRUeXBlID0gcmVxdWVzdEVudHJ5Py5jb21tYW5kVHlwZVxuICAgICAgY29uc3QgY3VzdG9tUGF0aCA9IHJlcXVlc3RFbnRyeT8uY3VzdG9tUGF0aFxuICAgICAgY29uc3QgbW9kZWwgPSByZXF1ZXN0RW50cnk/Lm1vZGVsXG4gICAgICBjb25zdCBwYXlsb2FkID0gcmVxdWVzdEVudHJ5Py5wYXlsb2FkXG4gICAgICBjb25zdCByZXF1ZXN0SWQgPSByZXF1ZXN0RW50cnk/LnJlcXVlc3RJZFxuXG4gICAgICBpZiAodHlwZW9mIG1vZGVsICE9PSBcInN0cmluZ1wiIHx8IG1vZGVsLmxlbmd0aCA8IDEpIHtcbiAgICAgICAgcmVzcG9uc2VzLnB1c2goe1xuICAgICAgICAgIHJlcXVlc3RJZCxcbiAgICAgICAgICByZXNwb25zZTogdGhpcy5mcm9udGVuZE1vZGVsRXJyb3JQYXlsb2FkKFwiRXhwZWN0ZWQgcmVxdWVzdCBtb2RlbC5cIilcbiAgICAgICAgfSlcbiAgICAgICAgY29udGludWVcbiAgICAgIH1cblxuICAgICAgY29uc3QgaXNCdWlsdEluQ29tbWFuZCA9IFtcImluZGV4XCIsIFwiZmluZFwiLCBcImNyZWF0ZVwiLCBcInVwZGF0ZVwiLCBcImRlc3Ryb3lcIiwgXCJhdHRhY2hcIiwgXCJkb3dubG9hZFwiLCBcInVybFwiXS5pbmNsdWRlcyhjb21tYW5kVHlwZSlcblxuICAgICAgaWYgKCFpc0J1aWx0SW5Db21tYW5kICYmICh0eXBlb2YgY3VzdG9tUGF0aCAhPT0gXCJzdHJpbmdcIiB8fCAhY3VzdG9tUGF0aC5zdGFydHNXaXRoKFwiL1wiKSkpIHtcbiAgICAgICAgcmVzcG9uc2VzLnB1c2goe1xuICAgICAgICAgIHJlcXVlc3RJZCxcbiAgICAgICAgICByZXNwb25zZTogdGhpcy5mcm9udGVuZE1vZGVsRXJyb3JQYXlsb2FkKFwiRXhwZWN0ZWQgcmVxdWVzdCBjdXN0b21QYXRoLlwiKVxuICAgICAgICB9KVxuICAgICAgICBjb250aW51ZVxuICAgICAgfVxuXG4gICAgICB0cnkge1xuICAgICAgICBsZXQgcmVzcG9uc2VQYXlsb2FkXG5cbiAgICAgICAgaWYgKGlzQnVpbHRJbkNvbW1hbmQpIHtcbiAgICAgICAgICBjb25zdCBjb21tYW5kUGFyYW1zID0ge1xuICAgICAgICAgICAgLi4uKHBheWxvYWQgJiYgdHlwZW9mIHBheWxvYWQgPT09IFwib2JqZWN0XCIgPyBwYXlsb2FkIDoge30pLFxuICAgICAgICAgICAgbW9kZWxcbiAgICAgICAgICB9XG5cbiAgICAgICAgICByZXNwb25zZVBheWxvYWQgPSBhd2FpdCB0aGlzLndpdGhGcm9udGVuZE1vZGVsUGFyYW1zKGNvbW1hbmRQYXJhbXMsIGFzeW5jICgpID0+IHtcbiAgICAgICAgICAgIHJldHVybiBhd2FpdCB0aGlzLndpdGhGcm9udGVuZE1vZGVsUmVxdWVzdENvbnRleHQoY29tbWFuZFBhcmFtcywgdGhpcy5yZXNwb25zZSgpLCBhc3luYyAoKSA9PiB7XG4gICAgICAgICAgICAgIHJldHVybiBhd2FpdCB0aGlzLmZyb250ZW5kTW9kZWxDb21tYW5kUGF5bG9hZChjb21tYW5kVHlwZSlcbiAgICAgICAgICAgIH0pXG4gICAgICAgICAgfSlcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICByZXNwb25zZVBheWxvYWQgPSBhd2FpdCB0aGlzLmZyb250ZW5kQXBpQ3VzdG9tQ29tbWFuZFBheWxvYWQoe1xuICAgICAgICAgICAgY3VzdG9tUGF0aCxcbiAgICAgICAgICAgIHBheWxvYWRcbiAgICAgICAgICB9KVxuICAgICAgICB9XG5cbiAgICAgICAgcmVzcG9uc2VzLnB1c2goe1xuICAgICAgICAgIHJlcXVlc3RJZCxcbiAgICAgICAgICByZXNwb25zZTogcmVzcG9uc2VQYXlsb2FkIHx8IHRoaXMuZnJvbnRlbmRNb2RlbEVycm9yUGF5bG9hZChcIkFjdGlvbiBoYWx0ZWQgYnkgYmVmb3JlQWN0aW9uLlwiKVxuICAgICAgICB9KVxuICAgICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgICAgYXdhaXQgdGhpcy5mcm9udGVuZE1vZGVsTG9nRW5kcG9pbnRFcnJvcih7XG4gICAgICAgICAgYWN0aW9uOiBcImZyb250ZW5kQXBpXCIsXG4gICAgICAgICAgY29tbWFuZFR5cGUsXG4gICAgICAgICAgZXJyb3IsXG4gICAgICAgICAgbW9kZWwsXG4gICAgICAgICAgcmVxdWVzdElkXG4gICAgICAgIH0pXG5cbiAgICAgICAgcmVzcG9uc2VzLnB1c2goe1xuICAgICAgICAgIHJlcXVlc3RJZCxcbiAgICAgICAgICByZXNwb25zZTogdGhpcy5mcm9udGVuZE1vZGVsQ2xpZW50RXJyb3JQYXlsb2FkRm9yRXJyb3IoZXJyb3IpXG4gICAgICAgIH0pXG4gICAgICB9XG4gICAgfVxuXG4gICAgYXdhaXQgdGhpcy5yZW5kZXIoe1xuICAgICAganNvbjogLyoqIEB0eXBlIHtSZWNvcmQ8c3RyaW5nLCBhbnk+fSAqLyAoc2VyaWFsaXplRnJvbnRlbmRNb2RlbFRyYW5zcG9ydFZhbHVlKHtcbiAgICAgICAgcmVzcG9uc2VzLFxuICAgICAgICBzdGF0dXM6IFwic3VjY2Vzc1wiXG4gICAgICB9KSlcbiAgICB9KVxuICB9XG5cbiAgLyoqXG4gICAqIERpc3BhdGNoZXMgYSBjdXN0b20gZnJvbnRlbmQtbW9kZWwgY29tbWFuZCB0aHJvdWdoIHRoZSBzaGFyZWQgZnJvbnRlbmQtbW9kZWwgQVBJIGVuZHBvaW50LlxuICAgKiBAcGFyYW0ge29iamVjdH0gYXJncyAtIEFyZ3VtZW50cy5cbiAgICogQHBhcmFtIHtzdHJpbmd9IGFyZ3MuY3VzdG9tUGF0aCAtIEN1c3RvbSBiYWNrZW5kIHJvdXRlIHBhdGguXG4gICAqIEBwYXJhbSB7dW5rbm93bn0gYXJncy5wYXlsb2FkIC0gUmVxdWVzdCBwYXlsb2FkLlxuICAgKiBAcmV0dXJucyB7UHJvbWlzZTxSZWNvcmQ8c3RyaW5nLCBhbnk+Pn0gLSBQYXJzZWQgSlNPTiByZXNwb25zZSBwYXlsb2FkLlxuICAgKi9cbiAgYXN5bmMgZnJvbnRlbmRBcGlDdXN0b21Db21tYW5kUGF5bG9hZCh7Y3VzdG9tUGF0aCwgcGF5bG9hZH0pIHtcbiAgICBjb25zdCBjb25maWd1cmF0aW9uID0gdGhpcy5nZXRDb25maWd1cmF0aW9uKClcbiAgICBjb25zdCByZXNwb25zZSA9IG5ldyBSZXNwb25zZSh7Y29uZmlndXJhdGlvbn0pXG4gICAgY29uc3QgcmVzb2x2ZXIgPSBuZXcgUm91dGVzUmVzb2x2ZXIoe1xuICAgICAgY29uZmlndXJhdGlvbixcbiAgICAgIHJlcXVlc3Q6IHRoaXMuZ2V0UmVxdWVzdCgpLFxuICAgICAgcmVzcG9uc2VcbiAgICB9KVxuICAgIHJlc29sdmVyLnBhcmFtcyA9IHt9XG4gICAgY29uc3Qgcm91dGVIb29rTWF0Y2ggPSBhd2FpdCByZXNvbHZlci5yZXNvbHZlUm91dGVSZXNvbHZlckhvb2tzKGN1c3RvbVBhdGgpXG4gICAgY29uc3QgY29uZmlndXJhdGlvblJvdXRlcyA9IGNvbmZpZ3VyYXRpb24uZ2V0Um91dGVzKClcbiAgICBjb25zdCByb3V0ZU1hdGNoID0gcm91dGVIb29rTWF0Y2ggfHwgIWNvbmZpZ3VyYXRpb25Sb3V0ZXM/LnJvb3RSb3V0ZSA/IHVuZGVmaW5lZCA6IHJlc29sdmVyLm1hdGNoUGF0aFdpdGhSb3V0ZXMoY29uZmlndXJhdGlvblJvdXRlcy5yb290Um91dGUsIGN1c3RvbVBhdGgpXG5cbiAgICBpZiAoIXJvdXRlSG9va01hdGNoICYmICFyb3V0ZU1hdGNoKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoYE5vIGN1c3RvbSBmcm9udGVuZCBtb2RlbCByb3V0ZSBtYXRjaGVkICcke2N1c3RvbVBhdGh9J2ApXG4gICAgfVxuXG4gICAgY29uc3QgYWN0aW9uUGFyYW0gPSByb3V0ZUhvb2tNYXRjaD8uYWN0aW9uIHx8IHJlc29sdmVyLnBhcmFtcy5hY3Rpb25cbiAgICBjb25zdCBjb250cm9sbGVyUGFyYW0gPSByb3V0ZUhvb2tNYXRjaD8uY29udHJvbGxlciB8fCByZXNvbHZlci5wYXJhbXMuY29udHJvbGxlclxuICAgIGNvbnN0IGFjdGlvblZhbHVlID0gdHlwZW9mIGFjdGlvblBhcmFtID09PSBcInN0cmluZ1wiID8gYWN0aW9uUGFyYW0gOiAoQXJyYXkuaXNBcnJheShhY3Rpb25QYXJhbSkgPyBhY3Rpb25QYXJhbVswXSA6IHVuZGVmaW5lZClcbiAgICBjb25zdCBjb250cm9sbGVyVmFsdWUgPSB0eXBlb2YgY29udHJvbGxlclBhcmFtID09PSBcInN0cmluZ1wiID8gY29udHJvbGxlclBhcmFtIDogKEFycmF5LmlzQXJyYXkoY29udHJvbGxlclBhcmFtKSA/IGNvbnRyb2xsZXJQYXJhbVswXSA6IHVuZGVmaW5lZClcblxuICAgIGlmICh0eXBlb2YgYWN0aW9uVmFsdWUgIT09IFwic3RyaW5nXCIgfHwgYWN0aW9uVmFsdWUubGVuZ3RoIDwgMSB8fCB0eXBlb2YgY29udHJvbGxlclZhbHVlICE9PSBcInN0cmluZ1wiIHx8IGNvbnRyb2xsZXJWYWx1ZS5sZW5ndGggPCAxKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoYEN1c3RvbSBmcm9udGVuZCBtb2RlbCByb3V0ZSBtYXRjaGVkICcke2N1c3RvbVBhdGh9JyB3aXRob3V0IGNvbnRyb2xsZXIvYWN0aW9uIHBhcmFtc2ApXG4gICAgfVxuXG4gICAgY29uc3QgYWN0aW9uID0gaW5mbGVjdGlvbi5jYW1lbGl6ZShhY3Rpb25WYWx1ZS5yZXBsYWNlQWxsKFwiLVwiLCBcIl9cIikucmVwbGFjZUFsbChcIi9cIiwgXCJfXCIpLCB0cnVlKVxuICAgIGNvbnN0IGNvbnRyb2xsZXIgPSBjb250cm9sbGVyVmFsdWVcbiAgICBjb25zdCBjb250cm9sbGVyUGF0aCA9IHJvdXRlSG9va01hdGNoPy5jb250cm9sbGVyUGF0aCB8fCBgJHtjb25maWd1cmF0aW9uLmdldERpcmVjdG9yeSgpfS9zcmMvcm91dGVzLyR7Y29udHJvbGxlcn0vY29udHJvbGxlci5qc2BcbiAgICBjb25zdCB2aWV3UGF0aCA9IHJvdXRlSG9va01hdGNoPy52aWV3UGF0aCB8fCBgJHtjb25maWd1cmF0aW9uLmdldERpcmVjdG9yeSgpfS9zcmMvcm91dGVzLyR7Y29udHJvbGxlcn1gXG4gICAgcmVzb2x2ZXIucm91dGVIb29rQ29udHJvbGxlckNsYXNzID0gcm91dGVIb29rTWF0Y2g/LmNvbnRyb2xsZXJDbGFzc1xuICAgIGNvbnN0IGNvbnRyb2xsZXJDbGFzcyA9IGF3YWl0IHJlc29sdmVyLnJlc29sdmVDb250cm9sbGVyQ2xhc3Moe2NvbnRyb2xsZXJQYXRofSlcbiAgICBjb25zdCBjb250cm9sbGVyUGFyYW1zID0ge1xuICAgICAgLi4uKChwYXlsb2FkICYmIHR5cGVvZiBwYXlsb2FkID09PSBcIm9iamVjdFwiKSA/IHBheWxvYWQgOiB7fSksXG4gICAgICAuLi5yZXNvbHZlci5wYXJhbXNcbiAgICB9XG4gICAgY29uc3QgY29udHJvbGxlckluc3RhbmNlID0gbmV3IGNvbnRyb2xsZXJDbGFzcyh7XG4gICAgICBhY3Rpb24sXG4gICAgICBjb25maWd1cmF0aW9uLFxuICAgICAgY29udHJvbGxlcixcbiAgICAgIHBhcmFtczogY29udHJvbGxlclBhcmFtcyxcbiAgICAgIHJlcXVlc3Q6IC8qKiBAdHlwZSB7aW1wb3J0KFwiLi9odHRwLXNlcnZlci9jbGllbnQvcmVxdWVzdC5qc1wiKS5kZWZhdWx0fSAqLyAodGhpcy5nZXRSZXF1ZXN0KCkpLFxuICAgICAgcmVzcG9uc2UsXG4gICAgICB2aWV3UGF0aFxuICAgIH0pXG5cbiAgICBhd2FpdCB0aGlzLndpdGhGcm9udGVuZE1vZGVsUmVxdWVzdENvbnRleHQoY29udHJvbGxlclBhcmFtcywgcmVzcG9uc2UsIGFzeW5jICgpID0+IHtcbiAgICAgIGF3YWl0IGNvbnRyb2xsZXJJbnN0YW5jZS5fcnVuQmVmb3JlQ2FsbGJhY2tzKClcbiAgICAgIGNvbnN0IGNvbnRyb2xsZXJNZXRob2RzID0gLyoqIEB0eXBlIHtSZWNvcmQ8c3RyaW5nLCAoKSA9PiBQcm9taXNlPHZvaWQ+IHwgdm9pZD59ICovICgvKiogQHR5cGUge3Vua25vd259ICovIChjb250cm9sbGVySW5zdGFuY2UpKVxuXG4gICAgICBhd2FpdCBjb250cm9sbGVyTWV0aG9kc1thY3Rpb25dKClcbiAgICB9KVxuXG4gICAgY29uc3Qgc2V0Q29va2llSGVhZGVycyA9IHJlc3BvbnNlLmhlYWRlcnNbXCJTZXQtQ29va2llXCJdIHx8IFtdXG5cbiAgICBmb3IgKGNvbnN0IHNldENvb2tpZUhlYWRlciBvZiBzZXRDb29raWVIZWFkZXJzKSB7XG4gICAgICB0aGlzLnJlc3BvbnNlKCkuYWRkSGVhZGVyKFwiU2V0LUNvb2tpZVwiLCBzZXRDb29raWVIZWFkZXIpXG4gICAgfVxuXG4gICAgY29uc3QgcmVzcG9uc2VCb2R5ID0gcmVzcG9uc2UuZ2V0Qm9keSgpXG5cbiAgICBpZiAodHlwZW9mIHJlc3BvbnNlQm9keSAhPT0gXCJzdHJpbmdcIiB8fCByZXNwb25zZUJvZHkubGVuZ3RoIDwgMSkge1xuICAgICAgcmV0dXJuIHt9XG4gICAgfVxuXG4gICAgLy8gUHJlc2VydmUgbmVzdGVkIHRyYW5zcG9ydCBtYXJrZXJzIHNvIHRoZSBvdXRlciBzaGFyZWQgZnJvbnRlbmQtbW9kZWwgQVBJXG4gICAgLy8gY2FuIHJldHVybiB0aGVtIHVuY2hhbmdlZCBhbmQgbGV0IHRoZSBjbGllbnQgaHlkcmF0ZSBvbmNlIGF0IHRoZSBlZGdlLlxuICAgIHJldHVybiAvKiogQHR5cGUge1JlY29yZDxzdHJpbmcsIGFueT59ICovIChKU09OLnBhcnNlKHJlc3BvbnNlQm9keSkpXG4gIH1cblxuICAvKiogQHJldHVybnMge1Byb21pc2U8dm9pZD59IC0gQ29sbGVjdGlvbiBhY3Rpb24gZm9yIGZyb250ZW5kIG1vZGVsIHJlc291cmNlcy4gKi9cbiAgYXN5bmMgZnJvbnRlbmRJbmRleCgpIHtcbiAgICBpZiAodGhpcy5yZXF1ZXN0KCkuaHR0cE1ldGhvZCgpID09PSBcIk9QVElPTlNcIikge1xuICAgICAgYXdhaXQgdGhpcy5yZW5kZXIoe3N0YXR1czogMjA0LCBqc29uOiB7fX0pXG4gICAgICByZXR1cm5cbiAgICB9XG5cbiAgICBhd2FpdCB0aGlzLmZyb250ZW5kTW9kZWxSZW5kZXJDb21tYW5kUmVzcG9uc2UoXCJpbmRleFwiKVxuICB9XG5cbiAgLyoqIEByZXR1cm5zIHtQcm9taXNlPHZvaWQ+fSAtIE1lbWJlciBmaW5kIGFjdGlvbiBmb3IgZnJvbnRlbmQgbW9kZWwgcmVzb3VyY2VzLiAqL1xuICBhc3luYyBmcm9udGVuZEZpbmQoKSB7XG4gICAgaWYgKHRoaXMucmVxdWVzdCgpLmh0dHBNZXRob2QoKSA9PT0gXCJPUFRJT05TXCIpIHtcbiAgICAgIGF3YWl0IHRoaXMucmVuZGVyKHtzdGF0dXM6IDIwNCwganNvbjoge319KVxuICAgICAgcmV0dXJuXG4gICAgfVxuXG4gICAgYXdhaXQgdGhpcy5mcm9udGVuZE1vZGVsUmVuZGVyQ29tbWFuZFJlc3BvbnNlKFwiZmluZFwiKVxuICB9XG5cbiAgLyoqIEByZXR1cm5zIHtQcm9taXNlPHZvaWQ+fSAtIE1lbWJlciB1cGRhdGUgYWN0aW9uIGZvciBmcm9udGVuZCBtb2RlbCByZXNvdXJjZXMuICovXG4gIGFzeW5jIGZyb250ZW5kVXBkYXRlKCkge1xuICAgIGlmICh0aGlzLnJlcXVlc3QoKS5odHRwTWV0aG9kKCkgPT09IFwiT1BUSU9OU1wiKSB7XG4gICAgICBhd2FpdCB0aGlzLnJlbmRlcih7c3RhdHVzOiAyMDQsIGpzb246IHt9fSlcbiAgICAgIHJldHVyblxuICAgIH1cblxuICAgIGF3YWl0IHRoaXMuZnJvbnRlbmRNb2RlbFJlbmRlckNvbW1hbmRSZXNwb25zZShcInVwZGF0ZVwiKVxuICB9XG5cbiAgLyoqIEByZXR1cm5zIHtQcm9taXNlPHZvaWQ+fSAtIE1lbWJlciBhdHRhY2ggYWN0aW9uIGZvciBmcm9udGVuZCBtb2RlbCByZXNvdXJjZXMuICovXG4gIGFzeW5jIGZyb250ZW5kQXR0YWNoKCkge1xuICAgIGlmICh0aGlzLnJlcXVlc3QoKS5odHRwTWV0aG9kKCkgPT09IFwiT1BUSU9OU1wiKSB7XG4gICAgICBhd2FpdCB0aGlzLnJlbmRlcih7c3RhdHVzOiAyMDQsIGpzb246IHt9fSlcbiAgICAgIHJldHVyblxuICAgIH1cblxuICAgIGF3YWl0IHRoaXMuZnJvbnRlbmRNb2RlbFJlbmRlckNvbW1hbmRSZXNwb25zZShcImF0dGFjaFwiKVxuICB9XG5cbiAgLyoqIEByZXR1cm5zIHtQcm9taXNlPHZvaWQ+fSAtIE1lbWJlciBkb3dubG9hZCBhY3Rpb24gZm9yIGZyb250ZW5kIG1vZGVsIHJlc291cmNlcy4gKi9cbiAgYXN5bmMgZnJvbnRlbmREb3dubG9hZCgpIHtcbiAgICBpZiAodGhpcy5yZXF1ZXN0KCkuaHR0cE1ldGhvZCgpID09PSBcIk9QVElPTlNcIikge1xuICAgICAgYXdhaXQgdGhpcy5yZW5kZXIoe3N0YXR1czogMjA0LCBqc29uOiB7fX0pXG4gICAgICByZXR1cm5cbiAgICB9XG5cbiAgICBhd2FpdCB0aGlzLmZyb250ZW5kTW9kZWxSZW5kZXJDb21tYW5kUmVzcG9uc2UoXCJkb3dubG9hZFwiKVxuICB9XG5cbiAgLyoqIEByZXR1cm5zIHtQcm9taXNlPHZvaWQ+fSAtIE1lbWJlciBVUkwgYWN0aW9uIGZvciBmcm9udGVuZCBtb2RlbCByZXNvdXJjZXMuICovXG4gIGFzeW5jIGZyb250ZW5kVXJsKCkge1xuICAgIGlmICh0aGlzLnJlcXVlc3QoKS5odHRwTWV0aG9kKCkgPT09IFwiT1BUSU9OU1wiKSB7XG4gICAgICBhd2FpdCB0aGlzLnJlbmRlcih7c3RhdHVzOiAyMDQsIGpzb246IHt9fSlcbiAgICAgIHJldHVyblxuICAgIH1cblxuICAgIGF3YWl0IHRoaXMuZnJvbnRlbmRNb2RlbFJlbmRlckNvbW1hbmRSZXNwb25zZShcInVybFwiKVxuICB9XG5cbiAgLyoqIEByZXR1cm5zIHtQcm9taXNlPHZvaWQ+fSAtIE1lbWJlciBjcmVhdGUgYWN0aW9uIGZvciBmcm9udGVuZCBtb2RlbCByZXNvdXJjZXMuICovXG4gIGFzeW5jIGZyb250ZW5kQ3JlYXRlKCkge1xuICAgIGlmICh0aGlzLnJlcXVlc3QoKS5odHRwTWV0aG9kKCkgPT09IFwiT1BUSU9OU1wiKSB7XG4gICAgICBhd2FpdCB0aGlzLnJlbmRlcih7c3RhdHVzOiAyMDQsIGpzb246IHt9fSlcbiAgICAgIHJldHVyblxuICAgIH1cblxuICAgIGF3YWl0IHRoaXMuZnJvbnRlbmRNb2RlbFJlbmRlckNvbW1hbmRSZXNwb25zZShcImNyZWF0ZVwiKVxuICB9XG5cbiAgLyoqIEByZXR1cm5zIHtQcm9taXNlPHZvaWQ+fSAtIE1lbWJlciBkZXN0cm95IGFjdGlvbiBmb3IgZnJvbnRlbmQgbW9kZWwgcmVzb3VyY2VzLiAqL1xuICBhc3luYyBmcm9udGVuZERlc3Ryb3koKSB7XG4gICAgaWYgKHRoaXMucmVxdWVzdCgpLmh0dHBNZXRob2QoKSA9PT0gXCJPUFRJT05TXCIpIHtcbiAgICAgIGF3YWl0IHRoaXMucmVuZGVyKHtzdGF0dXM6IDIwNCwganNvbjoge319KVxuICAgICAgcmV0dXJuXG4gICAgfVxuXG4gICAgYXdhaXQgdGhpcy5mcm9udGVuZE1vZGVsUmVuZGVyQ29tbWFuZFJlc3BvbnNlKFwiZGVzdHJveVwiKVxuICB9XG5cbiAgLyoqIEByZXR1cm5zIHtQcm9taXNlPHZvaWQ+fSAtIEN1c3RvbSBjb2xsZWN0aW9uL21lbWJlciBjb21tYW5kIGFjdGlvbiBmb3IgZnJvbnRlbmQtbW9kZWwgcmVzb3VyY2VzLiAqL1xuICBhc3luYyBmcm9udGVuZEN1c3RvbUNvbW1hbmQoKSB7XG4gICAgaWYgKHRoaXMucmVxdWVzdCgpLmh0dHBNZXRob2QoKSA9PT0gXCJPUFRJT05TXCIpIHtcbiAgICAgIGF3YWl0IHRoaXMucmVuZGVyKHtzdGF0dXM6IDIwNCwganNvbjoge319KVxuICAgICAgcmV0dXJuXG4gICAgfVxuXG4gICAgdHJ5IHtcbiAgICAgIGNvbnN0IHJlc3BvbnNlUGF5bG9hZCA9IGF3YWl0IHRoaXMuZnJvbnRlbmRNb2RlbEN1c3RvbUNvbW1hbmRQYXlsb2FkKClcblxuICAgICAgYXdhaXQgdGhpcy5yZW5kZXIoe1xuICAgICAgICBqc29uOiAvKiogQHR5cGUge1JlY29yZDxzdHJpbmcsIGFueT59ICovIChzZXJpYWxpemVGcm9udGVuZE1vZGVsVHJhbnNwb3J0VmFsdWUocmVzcG9uc2VQYXlsb2FkKSlcbiAgICAgIH0pXG4gICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgIGF3YWl0IHRoaXMuZnJvbnRlbmRNb2RlbExvZ0VuZHBvaW50RXJyb3Ioe2FjdGlvbjogXCJmcm9udGVuZEN1c3RvbUNvbW1hbmRcIiwgY29tbWFuZFR5cGU6IFwiY3VzdG9tLWNvbW1hbmRcIiwgZXJyb3J9KVxuXG4gICAgICBhd2FpdCB0aGlzLnJlbmRlcih7XG4gICAgICAgIGpzb246IC8qKiBAdHlwZSB7UmVjb3JkPHN0cmluZywgYW55Pn0gKi8gKHNlcmlhbGl6ZUZyb250ZW5kTW9kZWxUcmFuc3BvcnRWYWx1ZSh0aGlzLmZyb250ZW5kTW9kZWxDbGllbnRFcnJvclBheWxvYWRGb3JFcnJvcihlcnJvcikpKVxuICAgICAgfSlcbiAgICB9XG4gIH1cblxuICAvKiogQHJldHVybnMge1Byb21pc2U8UmVjb3JkPHN0cmluZywgYW55Pj59IC0gUmVzcG9uc2UgcGF5bG9hZC4gKi9cbiAgYXN5bmMgZnJvbnRlbmRNb2RlbEN1c3RvbUNvbW1hbmRQYXlsb2FkKCkge1xuICAgIGNvbnN0IHBhcmFtcyA9IHRoaXMuZnJvbnRlbmRNb2RlbFBhcmFtcygpXG4gICAgY29uc3QgbWV0aG9kTmFtZSA9IHBhcmFtcy5mcm9udGVuZE1vZGVsQ3VzdG9tQ29tbWFuZE1ldGhvZE5hbWVcbiAgICBjb25zdCBzY29wZSA9IHBhcmFtcy5mcm9udGVuZE1vZGVsQ3VzdG9tQ29tbWFuZFNjb3BlXG5cbiAgICBpZiAodHlwZW9mIG1ldGhvZE5hbWUgIT09IFwic3RyaW5nXCIgfHwgbWV0aG9kTmFtZS5sZW5ndGggPCAxKSB7XG4gICAgICByZXR1cm4gdGhpcy5mcm9udGVuZE1vZGVsRXJyb3JQYXlsb2FkKFwiRXhwZWN0ZWQgZnJvbnRlbmQtbW9kZWwgY3VzdG9tIGNvbW1hbmQgbWV0aG9kIG5hbWUuXCIpXG4gICAgfVxuXG4gICAgaWYgKHNjb3BlICE9PSBcImNvbGxlY3Rpb25cIiAmJiBzY29wZSAhPT0gXCJtZW1iZXJcIikge1xuICAgICAgcmV0dXJuIHRoaXMuZnJvbnRlbmRNb2RlbEVycm9yUGF5bG9hZChcIkV4cGVjdGVkIGZyb250ZW5kLW1vZGVsIGN1c3RvbSBjb21tYW5kIHNjb3BlLlwiKVxuICAgIH1cblxuICAgIGNvbnN0IHJlc291cmNlID0gLyoqIEB0eXBlIHtSZWNvcmQ8c3RyaW5nLCBhbnk+fSAqLyAodGhpcy5mcm9udGVuZE1vZGVsUmVzb3VyY2VJbnN0YW5jZSgpKVxuICAgIGNvbnN0IGNvbW1hbmRNZXRob2QgPSByZXNvdXJjZVttZXRob2ROYW1lXVxuXG4gICAgaWYgKHR5cGVvZiBjb21tYW5kTWV0aG9kICE9PSBcImZ1bmN0aW9uXCIpIHtcbiAgICAgIHJldHVybiB0aGlzLmZyb250ZW5kTW9kZWxFcnJvclBheWxvYWQoYE1pc3NpbmcgZnJvbnRlbmQtbW9kZWwgY3VzdG9tIGNvbW1hbmQgJyR7bWV0aG9kTmFtZX0nLmApXG4gICAgfVxuXG4gICAgY29uc3QgcmVzcG9uc2VQYXlsb2FkID0gYXdhaXQgY29tbWFuZE1ldGhvZC5jYWxsKHJlc291cmNlKVxuXG4gICAgaWYgKCFyZXNwb25zZVBheWxvYWQgfHwgdHlwZW9mIHJlc3BvbnNlUGF5bG9hZCAhPT0gXCJvYmplY3RcIikge1xuICAgICAgcmV0dXJuIHtzdGF0dXM6IFwic3VjY2Vzc1wifVxuICAgIH1cblxuICAgIHJldHVybiAvKiogQHR5cGUge1JlY29yZDxzdHJpbmcsIGFueT59ICovIChcbiAgICAgIGF3YWl0IHRoaXMuYXV0b1NlcmlhbGl6ZUZyb250ZW5kTW9kZWxzSW5QYXlsb2FkKFxuICAgICAgICByZXNwb25zZVBheWxvYWQsXG4gICAgICAgIC8qKiBAdHlwZSB7e3NlcmlhbGl6ZTogKG1vZGVsOiB1bmtub3duLCBhY3Rpb246IHN0cmluZykgPT4gUHJvbWlzZTxSZWNvcmQ8c3RyaW5nLCBhbnk+Pn19ICovIChyZXNvdXJjZSksXG4gICAgICAgIG1ldGhvZE5hbWVcbiAgICAgIClcbiAgICApXG4gIH1cblxuICAvKipcbiAgICogV2Fsa3MgYSBjdXN0b20tY29tbWFuZCByZXNwb25zZSBwYXlsb2FkIGFuZCByZXBsYWNlcyBhbnkgYmFja2VuZCBgUmVjb3JkYFxuICAgKiBpbnN0YW5jZSB3aXRoIHRoZSByZXNvdXJjZSdzIHBlci1hY3Rpb24gc2VyaWFsaXplZCBmb3JtIHNvIGhhbmRsZXJzIGNhblxuICAgKiByZXR1cm4gYHtyZWNvcmQsIHN0YXR1czogXCJva1wifWAgaW5zdGVhZCBvZiBleHBsaWNpdGx5IGNhbGxpbmdcbiAgICogYGF3YWl0IHRoaXMuc2VyaWFsaXplKHJlY29yZCwgYWN0aW9uKWAuIFBsYWluIG9iamVjdHMsIGFycmF5cywgYW5kXG4gICAqIHByaW1pdGl2ZSB2YWx1ZXMgcGFzcyB0aHJvdWdoIGFuZCBhcmUgbGF0ZXIgZW5jb2RlZCBieVxuICAgKiBgc2VyaWFsaXplRnJvbnRlbmRNb2RlbFRyYW5zcG9ydFZhbHVlYC5cbiAgICpcbiAgICogQHBhcmFtIHt1bmtub3dufSB2YWx1ZSAtIFBheWxvYWQgdmFsdWUuXG4gICAqIEBwYXJhbSB7e3NlcmlhbGl6ZTogKG1vZGVsOiB1bmtub3duLCBhY3Rpb246IHN0cmluZykgPT4gUHJvbWlzZTxSZWNvcmQ8c3RyaW5nLCBhbnk+Pn19IHJlc291cmNlIC0gUmVzb3VyY2UgaW5zdGFuY2UgcHJvdmlkaW5nIGBzZXJpYWxpemVgLlxuICAgKiBAcGFyYW0ge3N0cmluZ30gYWN0aW9uIC0gQ3VzdG9tIGNvbW1hbmQgbWV0aG9kIG5hbWUgcGFzc2VkIHRvIGByZXNvdXJjZS5zZXJpYWxpemVgIGZvciBwZXItYWN0aW9uIGF1dGhvcml6YXRpb24gZmlsdGVyaW5nLlxuICAgKiBAcGFyYW0ge1dlYWtTZXQ8b2JqZWN0Pn0gW3NlZW5dIC0gUmVjdXJzaW9uIHN0YWNrIG9mIHBsYWluLW9iamVjdCBjb250YWluZXJzIGN1cnJlbnRseSBiZWluZyB3YWxrZWQuIE1lbWJlcnNoaXAgaXMgYWRkZWQgb24gZW50cnkgYW5kIHJlbW92ZWQgb24gZXhpdCBzbyBhIGNvbnRhaW5lciBzaGFyZWQgYmV0d2VlbiBzaWJsaW5ncyAoaS5lLiByZWZlcmVuY2VkIHR3aWNlIGJ1dCBub3QgY3ljbGljYWxseSkgaXMgd2Fsa2VkIG9uIGVhY2ggcmVmZXJlbmNlIGluc3RlYWQgb2YgYmVpbmcgc2hvcnQtY2lyY3VpdGVkIHRoZSBzZWNvbmQgdGltZSwgd2hpY2ggd291bGQgbGV0IGJhY2tlbmQgYFJlY29yZGAgaW5zdGFuY2VzIGluc2lkZSBpdCBieXBhc3MgYHJlc291cmNlLnNlcmlhbGl6ZWAuXG4gICAqIEByZXR1cm5zIHtQcm9taXNlPHVua25vd24+fSAtIFBheWxvYWQgd2l0aCBiYWNrZW5kIGBSZWNvcmRgIGluc3RhbmNlcyByZXBsYWNlZCBieSBzZXJpYWxpemVkIG1hcmtlcnMuXG4gICAqL1xuICBhc3luYyBhdXRvU2VyaWFsaXplRnJvbnRlbmRNb2RlbHNJblBheWxvYWQodmFsdWUsIHJlc291cmNlLCBhY3Rpb24sIHNlZW4gPSBuZXcgV2Vha1NldCgpKSB7XG4gICAgaWYgKHZhbHVlID09PSBudWxsIHx8IHZhbHVlID09PSB1bmRlZmluZWQpIHtcbiAgICAgIHJldHVybiB2YWx1ZVxuICAgIH1cblxuICAgIGlmIChpc0JhY2tlbmRNb2RlbEluc3RhbmNlKHZhbHVlKSkge1xuICAgICAgY29uc3QgcmljaFNlcmlhbGl6ZWQgPSBhd2FpdCByZXNvdXJjZS5zZXJpYWxpemUodmFsdWUsIGFjdGlvbilcbiAgICAgIGNvbnN0IG1vZGVsQ2xhc3MgPSAvKiogQHR5cGUge3tjb25zdHJ1Y3Rvcjoge2dldE1vZGVsTmFtZT86ICgpID0+IHN0cmluZywgbmFtZT86IHN0cmluZ319fSAqLyAodmFsdWUpLmNvbnN0cnVjdG9yXG4gICAgICBjb25zdCBtb2RlbE5hbWUgPSB0eXBlb2YgbW9kZWxDbGFzcy5nZXRNb2RlbE5hbWUgPT09IFwiZnVuY3Rpb25cIiA/IG1vZGVsQ2xhc3MuZ2V0TW9kZWxOYW1lKCkgOiAobW9kZWxDbGFzcy5uYW1lIHx8IFwiXCIpXG5cbiAgICAgIC8vIFdyYXAgdGhlIHJlc291cmNlLXNlcmlhbGl6ZWQgcGF5bG9hZCBpbiB0aGUgZnJvbnRlbmRfbW9kZWwgdHJhbnNwb3J0XG4gICAgICAvLyBtYXJrZXIuIE1hcmtlci1iYXNlZCBkZWNvZGluZyByb3V0ZXMgdGhyb3VnaCBgaW5zdGFudGlhdGVGcm9tUmVzcG9uc2VgLFxuICAgICAgLy8gc28gYWJpbGl0aWVzIC8gcXVlcnlEYXRhIC8gYXNzb2NpYXRpb25Db3VudHMgLyBwcmVsb2FkZWRSZWxhdGlvbnNoaXBzXG4gICAgICAvLyBiYWtlZCBpbnRvIHRoZSByaWNoIGF0dHJpYnV0ZXMgYnkgYHJlc291cmNlLnNlcmlhbGl6ZWAgYXJlIHJlc3RvcmVkIG9uXG4gICAgICAvLyB0aGUgY2xpZW50IHdpdGhvdXQgY2FsbGVycyBuZWVkaW5nIHRvIHdyYXAgbW9kZWxzIG1hbnVhbGx5LlxuICAgICAgcmV0dXJuIHtcbiAgICAgICAgX192ZWxvY2lvdXNfdHlwZTogXCJmcm9udGVuZF9tb2RlbFwiLFxuICAgICAgICBhdHRyaWJ1dGVzOiByaWNoU2VyaWFsaXplZCxcbiAgICAgICAgbW9kZWxOYW1lXG4gICAgICB9XG4gICAgfVxuXG4gICAgaWYgKEFycmF5LmlzQXJyYXkodmFsdWUpKSB7XG4gICAgICAvKiogQHR5cGUge3Vua25vd25bXX0gKi9cbiAgICAgIGNvbnN0IHJlc3VsdCA9IFtdXG5cbiAgICAgIGZvciAoY29uc3QgZW50cnkgb2YgdmFsdWUpIHtcbiAgICAgICAgcmVzdWx0LnB1c2goYXdhaXQgdGhpcy5hdXRvU2VyaWFsaXplRnJvbnRlbmRNb2RlbHNJblBheWxvYWQoZW50cnksIHJlc291cmNlLCBhY3Rpb24sIHNlZW4pKVxuICAgICAgfVxuXG4gICAgICByZXR1cm4gcmVzdWx0XG4gICAgfVxuXG4gICAgaWYgKHR5cGVvZiB2YWx1ZSA9PT0gXCJvYmplY3RcIiAmJiBPYmplY3QuZ2V0UHJvdG90eXBlT2YodmFsdWUpID09PSBPYmplY3QucHJvdG90eXBlKSB7XG4gICAgICBjb25zdCBjb250YWluZXIgPSAvKiogQHR5cGUge1JlY29yZDxzdHJpbmcsIHVua25vd24+fSAqLyAodmFsdWUpXG5cbiAgICAgIGlmIChzZWVuLmhhcyhjb250YWluZXIpKSB7XG4gICAgICAgIC8vIEN5Y2xpYyBiYWNrLXJlZmVyZW5jZSBhbG9uZyB0aGUgY3VycmVudCByZWN1cnNpb24gcGF0aDsgdGhlXG4gICAgICAgIC8vIGFuY2VzdG9yIGZyYW1lIGlzIHN0aWxsIHdhbGtpbmcgdGhpcyBjb250YWluZXIgYW5kIHdpbGwgcHJvZHVjZVxuICAgICAgICAvLyBpdHMgc2VyaWFsaXplZCBmb3JtLiBSZXR1cm5pbmcgdGhlIG9yaWdpbmFsIGNvbnRhaW5lciBoZXJlXG4gICAgICAgIC8vIGJyZWFrcyB0aGUgY3ljbGUgd2l0aG91dCBieXBhc3NpbmcgdGhlIHdhbGtlciBmb3Igc2libGluZ3MgdGhhdFxuICAgICAgICAvLyBzaGFyZSBhIG5vbi1jeWNsaWMgcmVmZXJlbmNlICh0aG9zZSByZS1lbnRlciB0aGUgYnJhbmNoIGJlbG93XG4gICAgICAgIC8vIGJlY2F1c2UgdGhlIGNvbnRhaW5lciBpcyByZW1vdmVkIGZyb20gYHNlZW5gIG9uIHN0YWNrIGV4aXQpLlxuICAgICAgICByZXR1cm4gY29udGFpbmVyXG4gICAgICB9XG5cbiAgICAgIHNlZW4uYWRkKGNvbnRhaW5lcilcblxuICAgICAgdHJ5IHtcbiAgICAgICAgLyoqIEB0eXBlIHtSZWNvcmQ8c3RyaW5nLCB1bmtub3duPn0gKi9cbiAgICAgICAgY29uc3QgcmVzdWx0ID0ge31cblxuICAgICAgICBmb3IgKGNvbnN0IFtrZXksIG5lc3RlZF0gb2YgT2JqZWN0LmVudHJpZXMoY29udGFpbmVyKSkge1xuICAgICAgICAgIC8vIGBhc3NpZ25TYWZlUHJvcGVydHlgIHN0b3JlcyBrZXlzIGxpa2UgYF9fcHJvdG9fX2AgYXMgb3duXG4gICAgICAgICAgLy8gZGF0YSBwcm9wZXJ0aWVzIGluc3RlYWQgb2YgaW52b2tpbmcgdGhlIHByb3RvdHlwZSBzZXR0ZXIsXG4gICAgICAgICAgLy8gc28gYSBjdXN0b20tY29tbWFuZCByZXNwb25zZSB0aGF0IGVjaG9lcyBwYXJzZWQgY2xpZW50XG4gICAgICAgICAgLy8gaW5wdXQgY2Fubm90IHBvbGx1dGUgYE9iamVjdC5wcm90b3R5cGVgIGhlcmUuIFRoZSB0cmFuc3BvcnRcbiAgICAgICAgICAvLyBzZXJpYWxpemVyIGFwcGxpZXMgdGhlIHNhbWUgcHJvdGVjdGlvbiBvbiBpdHMgb3duIHBhc3M7IHdlXG4gICAgICAgICAgLy8ganVzdCBwcmVzZXJ2ZSBpdCBhY3Jvc3MgdGhlIGF1dG8tc2VyaWFsaXplIHdhbGsuXG4gICAgICAgICAgYXNzaWduU2FmZVByb3BlcnR5KHJlc3VsdCwga2V5LCBhd2FpdCB0aGlzLmF1dG9TZXJpYWxpemVGcm9udGVuZE1vZGVsc0luUGF5bG9hZChuZXN0ZWQsIHJlc291cmNlLCBhY3Rpb24sIHNlZW4pKVxuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIHJlc3VsdFxuICAgICAgfSBmaW5hbGx5IHtcbiAgICAgICAgc2Vlbi5kZWxldGUoY29udGFpbmVyKVxuICAgICAgfVxuICAgIH1cblxuICAgIHJldHVybiB2YWx1ZVxuICB9XG5cbn1cbiJdfQ==
2991
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZnJvbnRlbmQtbW9kZWwtY29udHJvbGxlci5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9mcm9udGVuZC1tb2RlbC1jb250cm9sbGVyLmpzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLFlBQVk7QUFFWixPQUFPLEtBQUssVUFBVSxNQUFNLFlBQVksQ0FBQTtBQUN4QyxPQUFPLFVBQVUsTUFBTSxpQkFBaUIsQ0FBQTtBQUN4QyxPQUFPLFFBQVEsTUFBTSxrQ0FBa0MsQ0FBQTtBQUN2RCxPQUFPLHlCQUF5QixNQUFNLDRDQUE0QyxDQUFBO0FBQ2xGLE9BQU8sRUFBQyx3Q0FBd0MsRUFBRSxnREFBZ0QsRUFBRSx5QkFBeUIsRUFBRSx1Q0FBdUMsRUFBQyxNQUFNLDBDQUEwQyxDQUFBO0FBQ3ZOLE9BQU8sRUFBQyxjQUFjLElBQUksbUJBQW1CLEVBQUUsY0FBYyxJQUFJLG1CQUFtQixFQUFFLGNBQWMsSUFBSSxtQkFBbUIsRUFBRSxnQkFBZ0IsSUFBSSxxQkFBcUIsRUFBRSx1QkFBdUIsSUFBSSw0QkFBNEIsRUFBRSxhQUFhLElBQUksa0JBQWtCLEVBQUMsTUFBTSw0QkFBNEIsQ0FBQTtBQUN2UyxPQUFPLEVBQUMsa0JBQWtCLEVBQUUsc0NBQXNDLEVBQUUsc0JBQXNCLEVBQUUsb0NBQW9DLEVBQUMsTUFBTSw4Q0FBOEMsQ0FBQTtBQUNyTCxPQUFPLGNBQWMsTUFBTSxzQkFBc0IsQ0FBQTtBQUNqRCxPQUFPLEVBQUMsZUFBZSxFQUFDLE1BQU0sNEJBQTRCLENBQUE7QUFDMUQsT0FBTyxjQUFjLE1BQU0sc0JBQXNCLENBQUE7QUFDakQsT0FBTyxhQUFhLE1BQU0seUJBQXlCLENBQUE7QUFFbkQ7Ozs7R0FJRztBQUNILFNBQVMsNkJBQTZCLENBQUMsT0FBTztJQUM1QyxJQUFJLENBQUMsT0FBTztRQUFFLE9BQU8sSUFBSSxDQUFBO0lBRXpCLE9BQU8scUJBQXFCLENBQUMsT0FBTyxDQUFDLENBQUE7QUFDdkMsQ0FBQztBQUVEOzs7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QUFDLFNBQVMsQ0FBQyxFQUFFLENBQUM7Z0JBQ3hCLDhEQUE4RDtnQkFDOUQsa0VBQWtFO2dCQUNsRSw2REFBNkQ7Z0JBQzdELGtFQUFrRTtnQkFDbEUsZ0VBQWdFO2dCQUNoRSwrREFBK0Q7Z0JBQy9ELE9BQU8sU0FBUyxDQUFBO1lBQ2xCLENBQUM7WUFFRCxJQUFJLENBQUMsR0FBRyxDQUFDLFNBQVMsQ0FBQyxDQUFBO1lBRW5CLElBQUksQ0FBQztnQkFDSDs7OENBRThCO2dCQUM5QixNQUFNLE1BQU0sR0FBRyxFQUFFLENBQUE7Z0JBRWpCLEtBQUssTUFBTSxDQUFDLEdBQUcsRUFBRSxNQUFNLENBQUMsSUFBSSxNQUFNLENBQUMsT0FBTyxDQUFDLFNBQVMsQ0FBQyxFQUFFLENBQUM7b0JBQ3RELDJEQUEyRDtvQkFDM0QsNERBQTREO29CQUM1RCx5REFBeUQ7b0JBQ3pELDhEQUE4RDtvQkFDOUQsNkRBQTZEO29CQUM3RCxtREFBbUQ7b0JBQ25ELGtCQUFrQixDQUFDLE1BQU0sRUFBRSxHQUFHLEVBQUUsTUFBTSxJQUFJLENBQUMsb0NBQW9DLENBQUMsTUFBTSxFQUFFLFFBQVEsRUFBRSxNQUFNLEVBQUUsSUFBSSxDQUFDLENBQUMsQ0FBQTtnQkFDbEgsQ0FBQztnQkFFRCxPQUFPLE1BQU0sQ0FBQTtZQUNmLENBQUM7b0JBQVMsQ0FBQztnQkFDVCxJQUFJLENBQUMsTUFBTSxDQUFDLFNBQVMsQ0FBQyxDQUFBO1lBQ3hCLENBQUM7UUFDSCxDQUFDO1FBRUQsT0FBTyxLQUFLLENBQUE7SUFDZCxDQUFDO0NBRUYiLCJzb3VyY2VzQ29udGVudCI6WyIvLyBAdHMtY2hlY2tcblxuaW1wb3J0ICogYXMgaW5mbGVjdGlvbiBmcm9tIFwiaW5mbGVjdGlvblwiXG5pbXBvcnQgQ29udHJvbGxlciBmcm9tIFwiLi9jb250cm9sbGVyLmpzXCJcbmltcG9ydCBSZXNwb25zZSBmcm9tIFwiLi9odHRwLXNlcnZlci9jbGllbnQvcmVzcG9uc2UuanNcIlxuaW1wb3J0IEZyb250ZW5kTW9kZWxCYXNlUmVzb3VyY2UgZnJvbSBcIi4vZnJvbnRlbmQtbW9kZWwtcmVzb3VyY2UvYmFzZS1yZXNvdXJjZS5qc1wiXG5pbXBvcnQge2Zyb250ZW5kTW9kZWxSZXNvdXJjZUNsYXNzRnJvbURlZmluaXRpb24sIGZyb250ZW5kTW9kZWxSZXNvdXJjZUNvbmZpZ3VyYXRpb25Gcm9tRGVmaW5pdGlvbiwgZnJvbnRlbmRNb2RlbFJlc291cmNlUGF0aCwgZnJvbnRlbmRNb2RlbFJlc291cmNlc0ZvckJhY2tlbmRQcm9qZWN0fSBmcm9tIFwiLi9mcm9udGVuZC1tb2RlbHMvcmVzb3VyY2UtZGVmaW5pdGlvbi5qc1wiXG5pbXBvcnQge25vcm1hbGl6ZUdyb3VwIGFzIG5vcm1hbGl6ZVF1ZXJ5R3JvdXAsIG5vcm1hbGl6ZUpvaW5zIGFzIG5vcm1hbGl6ZVF1ZXJ5Sm9pbnMsIG5vcm1hbGl6ZVBsdWNrIGFzIG5vcm1hbGl6ZVF1ZXJ5UGx1Y2ssIG5vcm1hbGl6ZVByZWxvYWQgYXMgbm9ybWFsaXplUXVlcnlQcmVsb2FkLCBub3JtYWxpemVTZWFyY2hPcGVyYXRvciBhcyBub3JtYWxpemVRdWVyeVNlYXJjaE9wZXJhdG9yLCBub3JtYWxpemVTb3J0IGFzIG5vcm1hbGl6ZVF1ZXJ5U29ydH0gZnJvbSBcIi4vZnJvbnRlbmQtbW9kZWxzL3F1ZXJ5LmpzXCJcbmltcG9ydCB7YXNzaWduU2FmZVByb3BlcnR5LCBkZXNlcmlhbGl6ZUZyb250ZW5kTW9kZWxUcmFuc3BvcnRWYWx1ZSwgaXNCYWNrZW5kTW9kZWxJbnN0YW5jZSwgc2VyaWFsaXplRnJvbnRlbmRNb2RlbFRyYW5zcG9ydFZhbHVlfSBmcm9tIFwiLi9mcm9udGVuZC1tb2RlbHMvdHJhbnNwb3J0LXNlcmlhbGl6YXRpb24uanNcIlxuaW1wb3J0IFJvdXRlc1Jlc29sdmVyIGZyb20gXCIuL3JvdXRlcy9yZXNvbHZlci5qc1wiXG5pbXBvcnQge1ZhbGlkYXRpb25FcnJvcn0gZnJvbSBcIi4vZGF0YWJhc2UvcmVjb3JkL2luZGV4LmpzXCJcbmltcG9ydCBWZWxvY2lvdXNFcnJvciBmcm9tIFwiLi92ZWxvY2lvdXMtZXJyb3IuanNcIlxuaW1wb3J0IGlzUGxhaW5PYmplY3QgZnJvbSBcIi4vdXRpbHMvcGxhaW4tb2JqZWN0LmpzXCJcblxuLyoqXG4gKiBSdW5zIG5vcm1hbGl6ZSBmcm9udGVuZCBtb2RlbCBwcmVsb2FkLlxuICogQHBhcmFtIHtpbXBvcnQoXCIuL2RhdGFiYXNlL3F1ZXJ5L2luZGV4LmpzXCIpLk5lc3RlZFByZWxvYWRSZWNvcmQgfCBzdHJpbmcgfCBzdHJpbmdbXSB8IGJvb2xlYW4gfCB1bmRlZmluZWQgfCBudWxsfSBwcmVsb2FkIC0gUHJlbG9hZCBzaG9ydGhhbmQuXG4gKiBAcmV0dXJucyB7aW1wb3J0KFwiLi9kYXRhYmFzZS9xdWVyeS9pbmRleC5qc1wiKS5OZXN0ZWRQcmVsb2FkUmVjb3JkIHwgbnVsbH0gLSBOb3JtYWxpemVkIHByZWxvYWQuXG4gKi9cbmZ1bmN0aW9uIG5vcm1hbGl6ZUZyb250ZW5kTW9kZWxQcmVsb2FkKHByZWxvYWQpIHtcbiAgaWYgKCFwcmVsb2FkKSByZXR1cm4gbnVsbFxuXG4gIHJldHVybiBub3JtYWxpemVRdWVyeVByZWxvYWQocHJlbG9hZClcbn1cblxuLyoqXG4gKiBSdW5zIG5vcm1hbGl6ZSBmcm9udGVuZCBtb2RlbCBqb2lucy5cbiAqIEBwYXJhbSB7P30gam9pbnMgLSBKb2lucyBwYXlsb2FkLlxuICogQHJldHVybnMge1JlY29yZDxzdHJpbmcsID8+IHwgbnVsbH0gLSBOb3JtYWxpemVkIHJlbGF0aW9uc2hpcC1vYmplY3Qgam9pbnMuXG4gKi9cbmZ1bmN0aW9uIG5vcm1hbGl6ZUZyb250ZW5kTW9kZWxKb2lucyhqb2lucykge1xuICBpZiAoIWpvaW5zKSByZXR1cm4gbnVsbFxuXG4gIHRyeSB7XG4gICAgcmV0dXJuIG5vcm1hbGl6ZVF1ZXJ5Sm9pbnMoam9pbnMpXG4gIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgdGhyb3cgZnJvbnRlbmRNb2RlbFZhbGlkYXRpb25FcnJvckZvckVycm9yKGVycm9yKVxuICB9XG59XG5cbi8qKlxuICogUnVucyBub3JtYWxpemUgZnJvbnRlbmQgbW9kZWwgc2VsZWN0LlxuICogQHBhcmFtIHs/fSBzZWxlY3QgLSBTZWxlY3QgcGF5bG9hZC5cbiAqIEBwYXJhbSB7c3RyaW5nIHwgbnVsbH0gW3Jvb3RNb2RlbE5hbWVdIC0gT3B0aW9uYWwgcm9vdCBtb2RlbCBuYW1lIGZvciBzaG9ydGhhbmQgcGF5bG9hZHMuXG4gKiBAcmV0dXJucyB7UmVjb3JkPHN0cmluZywgc3RyaW5nW10+IHwgbnVsbH0gLSBOb3JtYWxpemVkIG1vZGVsLW5hbWUga2V5ZWQgc2VsZWN0IHJlY29yZC5cbiAqL1xuZnVuY3Rpb24gbm9ybWFsaXplRnJvbnRlbmRNb2RlbFNlbGVjdChzZWxlY3QsIHJvb3RNb2RlbE5hbWUgPSBudWxsKSB7XG4gIGlmICghc2VsZWN0KSByZXR1cm4gbnVsbFxuXG4gIGlmICh0eXBlb2Ygc2VsZWN0ID09PSBcInN0cmluZ1wiKSB7XG4gICAgaWYgKCFyb290TW9kZWxOYW1lKSB7XG4gICAgICB0aHJvdyBmcm9udGVuZE1vZGVsVmFsaWRhdGlvbkVycm9yKFwiSW52YWxpZCBzZWxlY3Qgc2hvcnRoYW5kIHdpdGhvdXQgcm9vdCBtb2RlbCBuYW1lXCIpXG4gICAgfVxuXG4gICAgcmV0dXJuIHtbcm9vdE1vZGVsTmFtZV06IFtzZWxlY3RdfVxuICB9XG5cbiAgaWYgKEFycmF5LmlzQXJyYXkoc2VsZWN0KSkge1xuICAgIGlmICghcm9vdE1vZGVsTmFtZSkge1xuICAgICAgdGhyb3cgZnJvbnRlbmRNb2RlbFZhbGlkYXRpb25FcnJvcihcIkludmFsaWQgc2VsZWN0IHNob3J0aGFuZCB3aXRob3V0IHJvb3QgbW9kZWwgbmFtZVwiKVxuICAgIH1cblxuICAgIGZvciAoY29uc3QgYXR0cmlidXRlTmFtZSBvZiBzZWxlY3QpIHtcbiAgICAgIGlmICh0eXBlb2YgYXR0cmlidXRlTmFtZSAhPT0gXCJzdHJpbmdcIikge1xuICAgICAgICB0aHJvdyBmcm9udGVuZE1vZGVsVmFsaWRhdGlvbkVycm9yKGBJbnZhbGlkIHNlbGVjdCBhdHRyaWJ1dGUgZm9yICR7cm9vdE1vZGVsTmFtZX06ICR7dHlwZW9mIGF0dHJpYnV0ZU5hbWV9YClcbiAgICAgIH1cbiAgICB9XG5cbiAgICByZXR1cm4ge1tyb290TW9kZWxOYW1lXTogQXJyYXkuZnJvbShuZXcgU2V0KHNlbGVjdCkpfVxuICB9XG5cbiAgaWYgKCFpc1BsYWluT2JqZWN0KHNlbGVjdCkpIHtcbiAgICB0aHJvdyBmcm9udGVuZE1vZGVsVmFsaWRhdGlvbkVycm9yKGBJbnZhbGlkIHNlbGVjdCB0eXBlOiAke3R5cGVvZiBzZWxlY3R9YClcbiAgfVxuXG4gIC8qKlxuICAgKiBOb3JtYWxpemVkLlxuICAgIEB0eXBlIHtSZWNvcmQ8c3RyaW5nLCBzdHJpbmdbXT59ICovXG4gIGNvbnN0IG5vcm1hbGl6ZWQgPSB7fVxuXG4gIGZvciAoY29uc3QgW21vZGVsTmFtZSwgc2VsZWN0VmFsdWVdIG9mIE9iamVjdC5lbnRyaWVzKHNlbGVjdCkpIHtcbiAgICBpZiAodHlwZW9mIHNlbGVjdFZhbHVlID09PSBcInN0cmluZ1wiKSB7XG4gICAgICBub3JtYWxpemVkW21vZGVsTmFtZV0gPSBbc2VsZWN0VmFsdWVdXG4gICAgICBjb250aW51ZVxuICAgIH1cblxuICAgIGlmICghQXJyYXkuaXNBcnJheShzZWxlY3RWYWx1ZSkpIHtcbiAgICAgIHRocm93IGZyb250ZW5kTW9kZWxWYWxpZGF0aW9uRXJyb3IoYEludmFsaWQgc2VsZWN0IHZhbHVlIGZvciAke21vZGVsTmFtZX06ICR7dHlwZW9mIHNlbGVjdFZhbHVlfWApXG4gICAgfVxuXG4gICAgZm9yIChjb25zdCBhdHRyaWJ1dGVOYW1lIG9mIHNlbGVjdFZhbHVlKSB7XG4gICAgICBpZiAodHlwZW9mIGF0dHJpYnV0ZU5hbWUgIT09IFwic3RyaW5nXCIpIHtcbiAgICAgICAgdGhyb3cgZnJvbnRlbmRNb2RlbFZhbGlkYXRpb25FcnJvcihgSW52YWxpZCBzZWxlY3QgYXR0cmlidXRlIGZvciAke21vZGVsTmFtZX06ICR7dHlwZW9mIGF0dHJpYnV0ZU5hbWV9YClcbiAgICAgIH1cbiAgICB9XG5cbiAgICBub3JtYWxpemVkW21vZGVsTmFtZV0gPSBBcnJheS5mcm9tKG5ldyBTZXQoc2VsZWN0VmFsdWUpKVxuICB9XG5cbiAgcmV0dXJuIG5vcm1hbGl6ZWRcbn1cblxuLyoqXG4gKiBGcm9udGVuZE1vZGVsU2VhcmNoIHR5cGUuXG4gKiBAdHlwZWRlZiB7b2JqZWN0fSBGcm9udGVuZE1vZGVsU2VhcmNoXG4gKiBAcHJvcGVydHkge3N0cmluZ1tdfSBwYXRoIC0gUmVsYXRpb25zaGlwIHBhdGguXG4gKiBAcHJvcGVydHkge3N0cmluZ30gY29sdW1uIC0gQ29sdW1uIG9yIGF0dHJpYnV0ZSBuYW1lLlxuICogQHByb3BlcnR5IHtcImVxXCIgfCBcImxpa2VcIiB8IFwibm90RXFcIiB8IFwiZ3RcIiB8IFwiZ3RlcVwiIHwgXCJsdFwiIHwgXCJsdGVxXCJ9IG9wZXJhdG9yIC0gU2VhcmNoIG9wZXJhdG9yLlxuICogQHByb3BlcnR5IHs/fSB2YWx1ZSAtIFNlYXJjaCB2YWx1ZS5cbiAqL1xuXG4vKipcbiAqIEZyb250ZW5kTW9kZWxTb3J0IHR5cGUuXG4gKiBAdHlwZWRlZiB7b2JqZWN0fSBGcm9udGVuZE1vZGVsU29ydFxuICogQHByb3BlcnR5IHtzdHJpbmd9IGNvbHVtbiAtIEF0dHJpYnV0ZSBuYW1lIHRvIHNvcnQgYnkuXG4gKiBAcHJvcGVydHkge1wiYXNjXCIgfCBcImRlc2NcIn0gZGlyZWN0aW9uIC0gU29ydCBkaXJlY3Rpb24uXG4gKiBAcHJvcGVydHkge3N0cmluZ1tdfSBwYXRoIC0gUmVsYXRpb25zaGlwIHBhdGggZnJvbSByb290IG1vZGVsLlxuICovXG5cbi8qKlxuICogRnJvbnRlbmRNb2RlbEdyb3VwIHR5cGUuXG4gKiBAdHlwZWRlZiB7b2JqZWN0fSBGcm9udGVuZE1vZGVsR3JvdXBcbiAqIEBwcm9wZXJ0eSB7c3RyaW5nfSBjb2x1bW4gLSBBdHRyaWJ1dGUgbmFtZSB0byBncm91cCBieS5cbiAqIEBwcm9wZXJ0eSB7c3RyaW5nW119IHBhdGggLSBSZWxhdGlvbnNoaXAgcGF0aCBmcm9tIHJvb3QgbW9kZWwuXG4gKi9cblxuLyoqXG4gKiBGcm9udGVuZE1vZGVsUGx1Y2sgdHlwZS5cbiAqIEB0eXBlZGVmIHtvYmplY3R9IEZyb250ZW5kTW9kZWxQbHVja1xuICogQHByb3BlcnR5IHtzdHJpbmd9IGNvbHVtbiAtIEF0dHJpYnV0ZSBuYW1lIHRvIHBsdWNrLlxuICogQHByb3BlcnR5IHtzdHJpbmdbXX0gcGF0aCAtIFJlbGF0aW9uc2hpcCBwYXRoIGZyb20gcm9vdCBtb2RlbC5cbiAqL1xuXG4vKipcbiAqIEZyb250ZW5kTW9kZWxQYWdpbmF0aW9uIHR5cGUuXG4gKiBAdHlwZWRlZiB7b2JqZWN0fSBGcm9udGVuZE1vZGVsUGFnaW5hdGlvblxuICogQHByb3BlcnR5IHtudW1iZXIgfCBudWxsfSBsaW1pdCAtIE1heGltdW0gbnVtYmVyIG9mIHJlY29yZHMuXG4gKiBAcHJvcGVydHkge251bWJlciB8IG51bGx9IG9mZnNldCAtIE51bWJlciBvZiByZWNvcmRzIHRvIHNraXAuXG4gKiBAcHJvcGVydHkge251bWJlciB8IG51bGx9IHBhZ2UgLSAxLWJhc2VkIHBhZ2UgbnVtYmVyLlxuICogQHByb3BlcnR5IHtudW1iZXIgfCBudWxsfSBwZXJQYWdlIC0gUGFnZSBzaXplLlxuICovXG5cbmNvbnN0IGZyb250ZW5kTW9kZWxKb2luZWRQYXRoc1N5bWJvbCA9IFN5bWJvbChcImZyb250ZW5kTW9kZWxKb2luZWRQYXRoc1wiKVxuY29uc3QgZnJvbnRlbmRNb2RlbEdyb3VwZWRDb2x1bW5zU3ltYm9sID0gU3ltYm9sKFwiZnJvbnRlbmRNb2RlbEdyb3VwZWRDb2x1bW5zXCIpXG5jb25zdCBmcm9udGVuZE1vZGVsV2hlcmVOb01hdGNoU3ltYm9sID0gU3ltYm9sKFwiZnJvbnRlbmRNb2RlbFdoZXJlTm9NYXRjaFwiKVxuY29uc3QgZnJvbnRlbmRNb2RlbENsaWVudFNhZmVFcnJvck1lc3NhZ2UgPSBcIlJlcXVlc3QgZmFpbGVkLlwiXG5jb25zdCBmcm9udGVuZE1vZGVsRGVidWdFcnJvckVudmlyb25tZW50cyA9IG5ldyBTZXQoW1wiZGV2ZWxvcG1lbnRcIiwgXCJ0ZXN0XCJdKVxuXG4vKipcbiAqIFJ1bnMgZnJvbnRlbmQgbW9kZWwgcXVlcnkgbWV0YWRhdGEuXG4gKiBAcGFyYW0ge2ltcG9ydChcIi4vZGF0YWJhc2UvcXVlcnkvbW9kZWwtY2xhc3MtcXVlcnkuanNcIikuZGVmYXVsdH0gcXVlcnkgLSBRdWVyeSBpbnN0YW5jZS5cbiAqIEByZXR1cm5zIHtpbXBvcnQoXCIuL2RhdGFiYXNlL3F1ZXJ5L21vZGVsLWNsYXNzLXF1ZXJ5LmpzXCIpLmRlZmF1bHQgJiB7W2Zyb250ZW5kTW9kZWxKb2luZWRQYXRoc1N5bWJvbF0/OiBTZXQ8c3RyaW5nPiwgW2Zyb250ZW5kTW9kZWxHcm91cGVkQ29sdW1uc1N5bWJvbF0/OiBTZXQ8c3RyaW5nPn19IC0gUXVlcnkgbWV0YWRhdGEgYWNjZXNzIGhlbHBlci5cbiAqL1xuZnVuY3Rpb24gZnJvbnRlbmRNb2RlbFF1ZXJ5TWV0YWRhdGEocXVlcnkpIHtcbiAgcmV0dXJuIC8qKiBOYXJyb3dzIHRoZSBydW50aW1lIHZhbHVlIHRvIHRoZSBkb2N1bWVudGVkIHR5cGUuIEB0eXBlIHtpbXBvcnQoXCIuL2RhdGFiYXNlL3F1ZXJ5L21vZGVsLWNsYXNzLXF1ZXJ5LmpzXCIpLmRlZmF1bHQgJiB7W2Zyb250ZW5kTW9kZWxKb2luZWRQYXRoc1N5bWJvbF0/OiBTZXQ8c3RyaW5nPiwgW2Zyb250ZW5kTW9kZWxHcm91cGVkQ29sdW1uc1N5bWJvbF0/OiBTZXQ8c3RyaW5nPn19ICovIChxdWVyeSlcbn1cblxuLyoqXG4gKiBSdW5zIGZyb250ZW5kIG1vZGVsIHZhbGlkYXRpb24gZXJyb3IuXG4gKiBAcGFyYW0ge3N0cmluZ30gbWVzc2FnZSAtIFZhbGlkYXRpb24gZXJyb3IgbWVzc2FnZS5cbiAqIEByZXR1cm5zIHtWZWxvY2lvdXNFcnJvcn0gLSBDbGllbnQtc2FmZSB2YWxpZGF0aW9uIGVycm9yLlxuICovXG5mdW5jdGlvbiBmcm9udGVuZE1vZGVsVmFsaWRhdGlvbkVycm9yKG1lc3NhZ2UpIHtcbiAgcmV0dXJuIFZlbG9jaW91c0Vycm9yLnNhZmUobWVzc2FnZSwge2NvZGU6IFwiZnJvbnRlbmQtbW9kZWwtdmFsaWRhdGlvblwifSlcbn1cblxuLyoqXG4gKiBSdW5zIGZyb250ZW5kIG1vZGVsIHZhbGlkYXRpb24gZXJyb3IgZm9yIGVycm9yLlxuICogQHBhcmFtIHs/fSBlcnJvciAtIEVycm9yIHJhaXNlZCB3aGlsZSBub3JtYWxpemluZyBjbGllbnQgcXVlcnkgcGFyYW1zLlxuICogQHJldHVybnMge1ZlbG9jaW91c0Vycm9yfSAtIENsaWVudC1zYWZlIHZhbGlkYXRpb24gZXJyb3IgcHJlc2VydmluZyB0aGUgbm9ybWFsaXplciBtZXNzYWdlLlxuICovXG5mdW5jdGlvbiBmcm9udGVuZE1vZGVsVmFsaWRhdGlvbkVycm9yRm9yRXJyb3IoZXJyb3IpIHtcbiAgaWYgKGVycm9yIGluc3RhbmNlb2YgVmVsb2Npb3VzRXJyb3IgJiYgZXJyb3Iuc2FmZVRvRXhwb3NlKSByZXR1cm4gZXJyb3JcblxuICBjb25zdCBtZXNzYWdlID0gZXJyb3IgaW5zdGFuY2VvZiBFcnJvclxuICAgID8gZXJyb3IubWVzc2FnZVxuICAgIDogU3RyaW5nKGVycm9yKVxuXG4gIHJldHVybiBmcm9udGVuZE1vZGVsVmFsaWRhdGlvbkVycm9yKG1lc3NhZ2UpXG59XG5cbi8qKlxuICogV2hldGhlciB0aGUgZXJyb3IgY2FycmllcyBhbiBgZXJyb3IudmVsb2Npb3VzYCBtZXRhZGF0YSBiYWcuIFRoZVxuICogcHJlc2VuY2Ugb2YgYW55IHN1Y2ggYmFnIG1hcmtzIHRoZSBlcnJvciBhcyBcImFubm90YXRlZCBieSB0aGVcbiAqIGRldmVsb3BlciBmb3IgdGhlIGZyb250ZW5kXCIg4oCUIHRoZSBmcmFtZXdvcmsgdHJlYXRzIGl0IGFzXG4gKiB1c2VyLWZhY2luZzogc3VyZmFjZSB0aGUgbWVzc2FnZSwgZm9yd2FyZCB0aGUgbWV0YWRhdGEsIGFuZCBza2lwXG4gKiB0aGUgbm9pc3kgZW5kcG9pbnQtZXJyb3IgbG9nLlxuICogQHBhcmFtIHs/fSBlcnJvciAtIENhdWdodCBlcnJvci5cbiAqIEByZXR1cm5zIHtib29sZWFufVxuICovXG5mdW5jdGlvbiBmcm9udGVuZE1vZGVsRXJyb3JIYXNWZWxvY2lvdXNNZXRhZGF0YShlcnJvcikge1xuICByZXR1cm4gQm9vbGVhbihlcnJvciAmJiB0eXBlb2YgZXJyb3IgPT09IFwib2JqZWN0XCIgJiYgLyoqXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICogVHlwZXMgdGhlIGZvbGxvd2luZyB2YWx1ZS5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEB0eXBlIHs/fSAqLyAoZXJyb3IpLnZlbG9jaW91cyAmJiB0eXBlb2YgLyoqXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqIFR5cGVzIHRoZSBmb2xsb3dpbmcgdmFsdWUuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQHR5cGUgez99ICovIChlcnJvcikudmVsb2Npb3VzID09PSBcIm9iamVjdFwiKVxufVxuXG4vKipcbiAqIFJ1bnMgZnJvbnRlbmQgbW9kZWwgdmVsb2Npb3VzIG1ldGFkYXRhIGZvciBlcnJvci5cbiAqIEBwYXJhbSB7P30gZXJyb3IgLSBDYXVnaHQgZXJyb3IuXG4gKiBAcmV0dXJucyB7UmVjb3JkPHN0cmluZywgPz4gfCBudWxsfVxuICovXG5mdW5jdGlvbiBmcm9udGVuZE1vZGVsVmVsb2Npb3VzTWV0YWRhdGFGb3JFcnJvcihlcnJvcikge1xuICBpZiAoIWZyb250ZW5kTW9kZWxFcnJvckhhc1ZlbG9jaW91c01ldGFkYXRhKGVycm9yKSkgcmV0dXJuIG51bGxcbiAgcmV0dXJuIC8qKiBOYXJyb3dzIHRoZSBydW50aW1lIHZhbHVlIHRvIHRoZSBkb2N1bWVudGVkIHR5cGUuIEB0eXBlIHtSZWNvcmQ8c3RyaW5nLCA/Pn0gKi8gKC8qKlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICogVHlwZXMgdGhlIGZvbGxvd2luZyB2YWx1ZS5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQHR5cGUgez99ICovIChlcnJvcikudmVsb2Npb3VzKVxufVxuXG4vKipcbiAqIFJ1bnMgZnJvbnRlbmQgbW9kZWwgY2xpZW50IG1lc3NhZ2UgZm9yIGVycm9yLlxuICogQHBhcmFtIHs/fSBlcnJvciAtIENhdWdodCBlcnJvci5cbiAqIEByZXR1cm5zIHtzdHJpbmd9IC0gTWVzc2FnZSBzYWZlIHRvIHJldHVybiB0byBBUEkgY2xpZW50cy5cbiAqL1xuZnVuY3Rpb24gZnJvbnRlbmRNb2RlbENsaWVudE1lc3NhZ2VGb3JFcnJvcihlcnJvcikge1xuICBpZiAoZXJyb3IgaW5zdGFuY2VvZiBWZWxvY2lvdXNFcnJvciAmJiBlcnJvci5zYWZlVG9FeHBvc2UpIHtcbiAgICByZXR1cm4gZXJyb3IubWVzc2FnZVxuICB9XG5cbiAgaWYgKGZyb250ZW5kTW9kZWxFcnJvckhhc1ZlbG9jaW91c01ldGFkYXRhKGVycm9yKSAmJiBlcnJvciBpbnN0YW5jZW9mIEVycm9yKSB7XG4gICAgcmV0dXJuIGVycm9yLm1lc3NhZ2VcbiAgfVxuXG4gIHJldHVybiBmcm9udGVuZE1vZGVsQ2xpZW50U2FmZUVycm9yTWVzc2FnZVxufVxuXG4vKipcbiAqIFJ1bnMgZnJvbnRlbmQgbW9kZWwgZGVidWcgcGF5bG9hZCBmb3IgZXJyb3IuXG4gKiBAcGFyYW0ge29iamVjdH0gYXJncyAtIEFyZ3VtZW50cy5cbiAqIEBwYXJhbSB7aW1wb3J0KFwiLi9jb25maWd1cmF0aW9uLmpzXCIpLmRlZmF1bHR9IGFyZ3MuY29uZmlndXJhdGlvbiAtIEN1cnJlbnQgY29uZmlndXJhdGlvbi5cbiAqIEBwYXJhbSB7c3RyaW5nfSBhcmdzLmVudmlyb25tZW50IC0gQ3VycmVudCBlbnZpcm9ubWVudC5cbiAqIEBwYXJhbSB7P30gYXJncy5lcnJvciAtIENhdWdodCBlcnJvci5cbiAqIEByZXR1cm5zIHtSZWNvcmQ8c3RyaW5nLCA/Pn0gLSBPcHRpb25hbCBkZWJ1ZyBwYXlsb2FkIGZvciBub24tcHJvZHVjdGlvbiBlbnZpcm9ubWVudHMuXG4gKi9cbmZ1bmN0aW9uIGZyb250ZW5kTW9kZWxEZWJ1Z1BheWxvYWRGb3JFcnJvcih7Y29uZmlndXJhdGlvbiwgZW52aXJvbm1lbnQsIGVycm9yfSkge1xuICBjb25zdCBkZWJ1Z0FsbG93ZWQgPSBmcm9udGVuZE1vZGVsRGVidWdFcnJvckVudmlyb25tZW50cy5oYXMoZW52aXJvbm1lbnQpIHx8IGVudmlyb25tZW50ICE9PSBcInByb2R1Y3Rpb25cIiAmJiBjb25maWd1cmF0aW9uLmdldEV4cG9zZUludGVybmFsRXJyb3JzVG9DbGllbnRzKClcblxuICBpZiAoIWRlYnVnQWxsb3dlZCkge1xuICAgIHJldHVybiB7fVxuICB9XG5cbiAgaWYgKGVycm9yIGluc3RhbmNlb2YgVmVsb2Npb3VzRXJyb3IgJiYgZXJyb3Iuc2FmZVRvRXhwb3NlKSB7XG4gICAgcmV0dXJuIHt9XG4gIH1cblxuICBpZiAoZnJvbnRlbmRNb2RlbEVycm9ySGFzVmVsb2Npb3VzTWV0YWRhdGEoZXJyb3IpKSB7XG4gICAgcmV0dXJuIHt9XG4gIH1cblxuICBjb25zdCBkZWJ1Z0Vycm9yQ2xhc3MgPSBlcnJvciBpbnN0YW5jZW9mIEVycm9yICYmIGVycm9yLm5hbWVcbiAgICA/IGVycm9yLm5hbWVcbiAgICA6IHR5cGVvZiBlcnJvclxuICBjb25zdCBkZWJ1Z0Vycm9yTWVzc2FnZSA9IGVycm9yIGluc3RhbmNlb2YgRXJyb3JcbiAgICA/IGVycm9yLm1lc3NhZ2VcbiAgICA6IFN0cmluZyhlcnJvcilcbiAgY29uc3QgZGVidWdCYWNrdHJhY2UgPSBlcnJvciBpbnN0YW5jZW9mIEVycm9yICYmIHR5cGVvZiBlcnJvci5zdGFjayA9PT0gXCJzdHJpbmdcIiAmJiBlcnJvci5zdGFjay5sZW5ndGggPiAwXG4gICAgPyBlcnJvci5zdGFjay5zcGxpdChcIlxcblwiKVxuICAgIDogdW5kZWZpbmVkXG5cbiAgcmV0dXJuIHtcbiAgICBkZWJ1Z0Vycm9yQ2xhc3MsXG4gICAgZGVidWdFcnJvck1lc3NhZ2UsXG4gICAgLi4uKGRlYnVnQmFja3RyYWNlID8ge2RlYnVnQmFja3RyYWNlfSA6IHt9KVxuICB9XG59XG5cbi8qKlxuICogUnVucyBub3JtYWxpemUgZnJvbnRlbmQgbW9kZWwgc2VhcmNoZXMuXG4gKiBAcGFyYW0gez99IHNlYXJjaGVzIC0gU2VhcmNoIHBheWxvYWQuXG4gKiBAcmV0dXJucyB7RnJvbnRlbmRNb2RlbFNlYXJjaFtdfSAtIE5vcm1hbGl6ZWQgc2VhcmNoZXMuXG4gKi9cbmZ1bmN0aW9uIG5vcm1hbGl6ZUZyb250ZW5kTW9kZWxTZWFyY2hlcyhzZWFyY2hlcykge1xuICBpZiAoIXNlYXJjaGVzKSByZXR1cm4gW11cblxuICBpZiAoIUFycmF5LmlzQXJyYXkoc2VhcmNoZXMpKSB7XG4gICAgdGhyb3cgZnJvbnRlbmRNb2RlbFZhbGlkYXRpb25FcnJvcihgSW52YWxpZCBzZWFyY2hlcyB0eXBlOiAke3R5cGVvZiBzZWFyY2hlc31gKVxuICB9XG5cbiAgLyoqXG4gICAqIE5vcm1hbGl6ZWQuXG4gICAgQHR5cGUge0Zyb250ZW5kTW9kZWxTZWFyY2hbXX0gKi9cbiAgY29uc3Qgbm9ybWFsaXplZCA9IFtdXG5cbiAgZm9yIChjb25zdCBzZWFyY2ggb2Ygc2VhcmNoZXMpIHtcbiAgICBpZiAoIWlzUGxhaW5PYmplY3Qoc2VhcmNoKSkge1xuICAgICAgdGhyb3cgZnJvbnRlbmRNb2RlbFZhbGlkYXRpb25FcnJvcihgSW52YWxpZCBzZWFyY2ggZW50cnkgdHlwZTogJHt0eXBlb2Ygc2VhcmNofWApXG4gICAgfVxuXG4gICAgY29uc3QgcGF0aCA9IHNlYXJjaC5wYXRoXG4gICAgY29uc3QgY29sdW1uID0gc2VhcmNoLmNvbHVtblxuICAgIGNvbnN0IG9wZXJhdG9yID0gc2VhcmNoLm9wZXJhdG9yXG5cbiAgICBpZiAoIUFycmF5LmlzQXJyYXkocGF0aCkpIHtcbiAgICAgIHRocm93IGZyb250ZW5kTW9kZWxWYWxpZGF0aW9uRXJyb3IoXCJJbnZhbGlkIHNlYXJjaCBwYXRoOiBleHBlY3RlZCBhbiBhcnJheVwiKVxuICAgIH1cblxuICAgIGZvciAoY29uc3QgcGF0aEVudHJ5IG9mIHBhdGgpIHtcbiAgICAgIGlmICh0eXBlb2YgcGF0aEVudHJ5ICE9PSBcInN0cmluZ1wiIHx8IHBhdGhFbnRyeS5sZW5ndGggPCAxKSB7XG4gICAgICAgIHRocm93IGZyb250ZW5kTW9kZWxWYWxpZGF0aW9uRXJyb3IoXCJJbnZhbGlkIHNlYXJjaCBwYXRoIGVudHJ5OiBleHBlY3RlZCBub24tZW1wdHkgc3RyaW5nXCIpXG4gICAgICB9XG4gICAgfVxuXG4gICAgaWYgKHR5cGVvZiBjb2x1bW4gIT09IFwic3RyaW5nXCIgfHwgY29sdW1uLmxlbmd0aCA8IDEpIHtcbiAgICAgIHRocm93IGZyb250ZW5kTW9kZWxWYWxpZGF0aW9uRXJyb3IoXCJJbnZhbGlkIHNlYXJjaCBjb2x1bW46IGV4cGVjdGVkIG5vbi1lbXB0eSBzdHJpbmdcIilcbiAgICB9XG5cbiAgICBpZiAodHlwZW9mIG9wZXJhdG9yICE9PSBcInN0cmluZ1wiKSB7XG4gICAgICB0aHJvdyBmcm9udGVuZE1vZGVsVmFsaWRhdGlvbkVycm9yKGBJbnZhbGlkIHNlYXJjaCBvcGVyYXRvcjogJHtvcGVyYXRvcn1gKVxuICAgIH1cblxuICAgIG5vcm1hbGl6ZWQucHVzaCh7XG4gICAgICBjb2x1bW4sXG4gICAgICBvcGVyYXRvcjogbm9ybWFsaXplUXVlcnlTZWFyY2hPcGVyYXRvcihvcGVyYXRvciksXG4gICAgICBwYXRoOiBbLi4ucGF0aF0sXG4gICAgICB2YWx1ZTogc2VhcmNoLnZhbHVlXG4gICAgfSlcbiAgfVxuXG4gIHJldHVybiBub3JtYWxpemVkXG59XG5cbi8qKlxuICogUnVucyBub3JtYWxpemUgZnJvbnRlbmQgbW9kZWwgd2hlcmUuXG4gKiBAcGFyYW0gez99IHdoZXJlIC0gV2hlcmUgcGF5bG9hZC5cbiAqIEByZXR1cm5zIHtSZWNvcmQ8c3RyaW5nLCA/PiB8IG51bGx9IC0gTm9ybWFsaXplZCB3aGVyZSBoYXNoLlxuICovXG5mdW5jdGlvbiBub3JtYWxpemVGcm9udGVuZE1vZGVsV2hlcmUod2hlcmUpIHtcbiAgaWYgKCF3aGVyZSkgcmV0dXJuIG51bGxcblxuICBpZiAoIWlzUGxhaW5PYmplY3Qod2hlcmUpKSB7XG4gICAgdGhyb3cgZnJvbnRlbmRNb2RlbFZhbGlkYXRpb25FcnJvcihgSW52YWxpZCB3aGVyZSB0eXBlOiAke3R5cGVvZiB3aGVyZX1gKVxuICB9XG5cbiAgcmV0dXJuIHdoZXJlXG59XG5cbi8qKlxuICogUnVucyBub3JtYWxpemUgZnJvbnRlbmQgbW9kZWwgcmFuc2Fjay5cbiAqIEBwYXJhbSB7P30gcmFuc2FjayAtIFJhbnNhY2sgcGF5bG9hZC5cbiAqIEByZXR1cm5zIHtSZWNvcmQ8c3RyaW5nLCA/PiB8IG51bGx9IC0gTm9ybWFsaXplZCBSYW5zYWNrIGhhc2guXG4gKi9cbmZ1bmN0aW9uIG5vcm1hbGl6ZUZyb250ZW5kTW9kZWxSYW5zYWNrKHJhbnNhY2spIHtcbiAgaWYgKCFyYW5zYWNrKSByZXR1cm4gbnVsbFxuXG4gIGlmICghaXNQbGFpbk9iamVjdChyYW5zYWNrKSkge1xuICAgIHRocm93IGZyb250ZW5kTW9kZWxWYWxpZGF0aW9uRXJyb3IoYEludmFsaWQgcmFuc2FjayB0eXBlOiAke3R5cGVvZiByYW5zYWNrfWApXG4gIH1cblxuICByZXR1cm4gcmFuc2Fja1xufVxuXG4vKipcbiAqIFJ1bnMgbm9ybWFsaXplIGZyb250ZW5kIG1vZGVsIGludGVnZXIgcGFyYW0uXG4gKiBAcGFyYW0gez99IHZhbHVlIC0gQ2FuZGlkYXRlIGludGVnZXIuXG4gKiBAcGFyYW0ge3N0cmluZ30gbmFtZSAtIFBhcmFtIG5hbWUgZm9yIGVycm9ycy5cbiAqIEBwYXJhbSB7bnVtYmVyfSBtaW4gLSBNaW5pbXVtIGFsbG93ZWQgdmFsdWUuXG4gKiBAcmV0dXJucyB7bnVtYmVyIHwgbnVsbH0gLSBOb3JtYWxpemVkIGludGVnZXIuXG4gKi9cbmZ1bmN0aW9uIG5vcm1hbGl6ZUZyb250ZW5kTW9kZWxJbnRlZ2VyUGFyYW0odmFsdWUsIG5hbWUsIG1pbikge1xuICBpZiAodmFsdWUgPT0gbnVsbCkgcmV0dXJuIG51bGxcblxuICBpZiAodHlwZW9mIHZhbHVlICE9PSBcIm51bWJlclwiIHx8ICFOdW1iZXIuaXNJbnRlZ2VyKHZhbHVlKSkge1xuICAgIHRocm93IGZyb250ZW5kTW9kZWxWYWxpZGF0aW9uRXJyb3IoYEludmFsaWQgJHtuYW1lfTogZXhwZWN0ZWQgaW50ZWdlciBudW1iZXJgKVxuICB9XG5cbiAgaWYgKHZhbHVlIDwgbWluKSB7XG4gICAgdGhyb3cgZnJvbnRlbmRNb2RlbFZhbGlkYXRpb25FcnJvcihgSW52YWxpZCAke25hbWV9OiBleHBlY3RlZCB2YWx1ZSA+PSAke21pbn1gKVxuICB9XG5cbiAgcmV0dXJuIHZhbHVlXG59XG5cbi8qKlxuICogUnVucyBub3JtYWxpemUgZnJvbnRlbmQgbW9kZWwgcGFnaW5hdGlvbi5cbiAqIEBwYXJhbSB7b2JqZWN0fSBhcmdzIC0gUGFnaW5hdGlvbiBhcmdzLlxuICogQHBhcmFtIHs/fSBhcmdzLmxpbWl0IC0gTGltaXQgcGF5bG9hZC5cbiAqIEBwYXJhbSB7P30gYXJncy5vZmZzZXQgLSBPZmZzZXQgcGF5bG9hZC5cbiAqIEBwYXJhbSB7P30gYXJncy5wYWdlIC0gUGFnZSBwYXlsb2FkLlxuICogQHBhcmFtIHs/fSBhcmdzLnBlclBhZ2UgLSBQZXItcGFnZSBwYXlsb2FkLlxuICogQHJldHVybnMge0Zyb250ZW5kTW9kZWxQYWdpbmF0aW9ufSAtIE5vcm1hbGl6ZWQgcGFnaW5hdGlvbiBkYXRhLlxuICovXG5mdW5jdGlvbiBub3JtYWxpemVGcm9udGVuZE1vZGVsUGFnaW5hdGlvbih7bGltaXQsIG9mZnNldCwgcGFnZSwgcGVyUGFnZX0pIHtcbiAgcmV0dXJuIHtcbiAgICBsaW1pdDogbm9ybWFsaXplRnJvbnRlbmRNb2RlbEludGVnZXJQYXJhbShsaW1pdCwgXCJsaW1pdFwiLCAwKSxcbiAgICBvZmZzZXQ6IG5vcm1hbGl6ZUZyb250ZW5kTW9kZWxJbnRlZ2VyUGFyYW0ob2Zmc2V0LCBcIm9mZnNldFwiLCAwKSxcbiAgICBwYWdlOiBub3JtYWxpemVGcm9udGVuZE1vZGVsSW50ZWdlclBhcmFtKHBhZ2UsIFwicGFnZVwiLCAxKSxcbiAgICBwZXJQYWdlOiBub3JtYWxpemVGcm9udGVuZE1vZGVsSW50ZWdlclBhcmFtKHBlclBhZ2UsIFwicGVyUGFnZVwiLCAxKVxuICB9XG59XG5cbi8qKlxuICogUnVucyBub3JtYWxpemUgZnJvbnRlbmQgbW9kZWwgZGlzdGluY3QuXG4gKiBAcGFyYW0gez99IGRpc3RpbmN0IC0gRGlzdGluY3QgcGF5bG9hZC5cbiAqIEByZXR1cm5zIHtib29sZWFuIHwgbnVsbH0gLSBOb3JtYWxpemVkIGRpc3RpbmN0IGZsYWcgd2hlbiBwcm92aWRlZC5cbiAqL1xuZnVuY3Rpb24gbm9ybWFsaXplRnJvbnRlbmRNb2RlbERpc3RpbmN0KGRpc3RpbmN0KSB7XG4gIGlmIChkaXN0aW5jdCA9PSBudWxsKSByZXR1cm4gbnVsbFxuXG4gIGlmICh0eXBlb2YgZGlzdGluY3QgIT09IFwiYm9vbGVhblwiKSB7XG4gICAgdGhyb3cgZnJvbnRlbmRNb2RlbFZhbGlkYXRpb25FcnJvcihgSW52YWxpZCBkaXN0aW5jdDogZXhwZWN0ZWQgYm9vbGVhbmApXG4gIH1cblxuICByZXR1cm4gZGlzdGluY3Rcbn1cblxuLyoqXG4gKiBSdW5zIGJ1aWxkIGZyb250ZW5kIG1vZGVsIGpvaW4gb2JqZWN0IGZyb20gcGF0aC5cbiAqIEBwYXJhbSB7c3RyaW5nW119IHBhdGggLSBSZWxhdGlvbnNoaXAgcGF0aC5cbiAqIEByZXR1cm5zIHtSZWNvcmQ8c3RyaW5nLCA/Pn0gLSBKb2luIG9iamVjdC5cbiAqL1xuZnVuY3Rpb24gYnVpbGRGcm9udGVuZE1vZGVsSm9pbk9iamVjdEZyb21QYXRoKHBhdGgpIHtcbiAgLyoqXG4gICAqIEpvaW4gb2JqZWN0LlxuICAgIEB0eXBlIHtSZWNvcmQ8c3RyaW5nLCA/Pn0gKi9cbiAgY29uc3Qgam9pbk9iamVjdCA9IHt9XG4gIC8qKlxuICAgKiBDdXJyZW50IG5vZGUuXG4gICAgQHR5cGUge1JlY29yZDxzdHJpbmcsID8+fSAqL1xuICBsZXQgY3VycmVudE5vZGUgPSBqb2luT2JqZWN0XG5cbiAgZm9yIChjb25zdCByZWxhdGlvbnNoaXBOYW1lIG9mIHBhdGgpIHtcbiAgICBjdXJyZW50Tm9kZVtyZWxhdGlvbnNoaXBOYW1lXSA9IHt9XG4gICAgY3VycmVudE5vZGUgPSBjdXJyZW50Tm9kZVtyZWxhdGlvbnNoaXBOYW1lXVxuICB9XG5cbiAgcmV0dXJuIGpvaW5PYmplY3Rcbn1cblxuLyoqXG4gKiBCdWlsZCBhIHN1Y2Nlc3NmdWwgc2luZ2xlLW1vZGVsIGZyb250ZW5kLW1vZGVsIHJlc3BvbnNlIHBheWxvYWQuXG4gKiBAcGFyYW0ge1JlY29yZDxzdHJpbmcsID8+fSBtb2RlbCAtIFNlcmlhbGl6ZWQgbW9kZWwgcGF5bG9hZC5cbiAqIEByZXR1cm5zIHt7bW9kZWw6IFJlY29yZDxzdHJpbmcsID8+LCBzdGF0dXM6IFwic3VjY2Vzc1wifX0gLSBTdWNjZXNzIHJlc3BvbnNlIHBheWxvYWQuXG4gKi9cbmZ1bmN0aW9uIGZyb250ZW5kTW9kZWxTZXJpYWxpemVkTW9kZWxTdWNjZXNzKG1vZGVsKSB7XG4gIHJldHVybiB7bW9kZWwsIHN0YXR1czogXCJzdWNjZXNzXCJ9XG59XG5cbi8qKlxuICogUmVzb2x2ZSBhbmQgdmFsaWRhdGUgYXR0YWNobWVudCBwYXJhbXMgc2hhcmVkIGJ5IGF0dGFjaG1lbnQgY29tbWFuZHMuXG4gKiBAcGFyYW0ge1JlY29yZDxzdHJpbmcsID8+fSBwYXJhbXMgLSBGcm9udGVuZC1tb2RlbCByZXF1ZXN0IHBhcmFtcy5cbiAqIEByZXR1cm5zIHt7YXR0YWNobWVudElkOiBzdHJpbmcgfCB1bmRlZmluZWQsIGF0dGFjaG1lbnROYW1lOiBzdHJpbmd9IHwgc3RyaW5nfSAtIEF0dGFjaG1lbnQgcGFyYW1zIG9yIHZhbGlkYXRpb24gZXJyb3IgbWVzc2FnZS5cbiAqL1xuZnVuY3Rpb24gZnJvbnRlbmRNb2RlbEF0dGFjaG1lbnRQYXJhbXMocGFyYW1zKSB7XG4gIGNvbnN0IGF0dGFjaG1lbnROYW1lID0gcGFyYW1zLmF0dGFjaG1lbnROYW1lXG5cbiAgaWYgKHR5cGVvZiBhdHRhY2htZW50TmFtZSAhPT0gXCJzdHJpbmdcIiB8fCBhdHRhY2htZW50TmFtZS5sZW5ndGggPCAxKSB7XG4gICAgcmV0dXJuIFwiRXhwZWN0ZWQgYXR0YWNobWVudE5hbWUuXCJcbiAgfVxuXG4gIHJldHVybiB7XG4gICAgYXR0YWNobWVudElkOiB0eXBlb2YgcGFyYW1zLmF0dGFjaG1lbnRJZCA9PT0gXCJzdHJpbmdcIiA/IHBhcmFtcy5hdHRhY2htZW50SWQgOiB1bmRlZmluZWQsXG4gICAgYXR0YWNobWVudE5hbWVcbiAgfVxufVxuXG4vKipcbiAqIEV4dHJhY3QgbXV0YXRpb24gYXR0cmlidXRlcyBzaGFyZWQgYnkgY3JlYXRlIGFuZCB1cGRhdGUgY29tbWFuZHMuXG4gKiBAcGFyYW0ge1JlY29yZDxzdHJpbmcsID8+fSBwYXJhbXMgLSBGcm9udGVuZC1tb2RlbCByZXF1ZXN0IHBhcmFtcy5cbiAqIEByZXR1cm5zIHt7YXR0cmlidXRlczogUmVjb3JkPHN0cmluZywgPz4sIG5lc3RlZEF0dHJpYnV0ZXM6IFJlY29yZDxzdHJpbmcsID8+IHwgbnVsbH0gfCBzdHJpbmd9IC0gTXV0YXRpb24gYXR0cmlidXRlcyBvciB2YWxpZGF0aW9uIGVycm9yIG1lc3NhZ2UuXG4gKi9cbmZ1bmN0aW9uIGZyb250ZW5kTW9kZWxNdXRhdGlvbkF0dHJpYnV0ZXMocGFyYW1zKSB7XG4gIGNvbnN0IGF0dHJpYnV0ZXMgPSBwYXJhbXMuYXR0cmlidXRlc1xuXG4gIGlmICghYXR0cmlidXRlcyB8fCB0eXBlb2YgYXR0cmlidXRlcyAhPT0gXCJvYmplY3RcIikge1xuICAgIHJldHVybiBcIkV4cGVjdGVkIG1vZGVsIGF0dHJpYnV0ZXMuXCJcbiAgfVxuXG4gIHJldHVybiB7XG4gICAgYXR0cmlidXRlcyxcbiAgICBuZXN0ZWRBdHRyaWJ1dGVzOiBwYXJhbXMubmVzdGVkQXR0cmlidXRlcyAmJiB0eXBlb2YgcGFyYW1zLm5lc3RlZEF0dHJpYnV0ZXMgPT09IFwib2JqZWN0XCJcbiAgICAgID8gLyoqXG4gICAgICAgICAqIFR5cGVzIHRoZSBmb2xsb3dpbmcgdmFsdWUuXG4gICAgICAgICAgQHR5cGUge1JlY29yZDxzdHJpbmcsID8+fSAqLyAocGFyYW1zLm5lc3RlZEF0dHJpYnV0ZXMpXG4gICAgICA6IG51bGxcbiAgfVxufVxuXG4vKiogQ29udHJvbGxlciB3aXRoIGJ1aWx0LWluIGZyb250ZW5kIG1vZGVsIHJlc291cmNlIGFjdGlvbnMuICovXG5leHBvcnQgZGVmYXVsdCBjbGFzcyBGcm9udGVuZE1vZGVsQ29udHJvbGxlciBleHRlbmRzIENvbnRyb2xsZXIge1xuICAvKipcbiAgICogRnJvbnRlbmQgbW9kZWwgcGFyYW1zLlxuICAgIEB0eXBlIHtSZWNvcmQ8c3RyaW5nLCA/PiB8IHVuZGVmaW5lZH0gKi9cbiAgX2Zyb250ZW5kTW9kZWxQYXJhbXMgPSB1bmRlZmluZWRcbiAgLyoqXG4gICAqIEZyb250ZW5kIG1vZGVsIHBhcmFtcyBvdmVycmlkZS5cbiAgICBAdHlwZSB7UmVjb3JkPHN0cmluZywgPz4gfCB1bmRlZmluZWR9ICovXG4gIF9mcm9udGVuZE1vZGVsUGFyYW1zT3ZlcnJpZGUgPSB1bmRlZmluZWRcbiAgLyoqXG4gICAqIEZyb250ZW5kIG1vZGVsIGFiaWxpdHkgb3ZlcnJpZGUuXG4gICAgQHR5cGUge2ltcG9ydChcIi4vYXV0aG9yaXphdGlvbi9hYmlsaXR5LmpzXCIpLmRlZmF1bHQgfCB1bmRlZmluZWR9ICovXG4gIF9mcm9udGVuZE1vZGVsQWJpbGl0eU92ZXJyaWRlID0gdW5kZWZpbmVkXG5cbiAgLyoqXG4gICAqIFJ1bnMgZnJvbnRlbmQgbW9kZWwgcGFyYW1zLlxuICAgKiBAcmV0dXJucyB7UmVjb3JkPHN0cmluZywgPz59IC0gRGVjb2RlZCByZXF1ZXN0IHBhcmFtcy5cbiAgICovXG4gIGZyb250ZW5kTW9kZWxQYXJhbXMoKSB7XG4gICAgaWYgKHRoaXMuX2Zyb250ZW5kTW9kZWxQYXJhbXNPdmVycmlkZSkge1xuICAgICAgcmV0dXJuIHRoaXMuX2Zyb250ZW5kTW9kZWxQYXJhbXNPdmVycmlkZVxuICAgIH1cblxuICAgIHRoaXMuX2Zyb250ZW5kTW9kZWxQYXJhbXMgfHw9IC8qKlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqIFR5cGVzIHRoZSBmb2xsb3dpbmcgdmFsdWUuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBAdHlwZSB7UmVjb3JkPHN0cmluZywgPz59ICovIChkZXNlcmlhbGl6ZUZyb250ZW5kTW9kZWxUcmFuc3BvcnRWYWx1ZSh0aGlzLnBhcmFtcygpKSlcblxuICAgIHJldHVybiB0aGlzLl9mcm9udGVuZE1vZGVsUGFyYW1zXG4gIH1cblxuICAvKipcbiAgICogUnVucyB3aXRoIGZyb250ZW5kIG1vZGVsIHBhcmFtcy5cbiAgICogQHRlbXBsYXRlIFRcbiAgICogQHBhcmFtIHtSZWNvcmQ8c3RyaW5nLCA/Pn0gcGFyYW1zIC0gVGVtcG9yYXJ5IGZyb250ZW5kIG1vZGVsIHBhcmFtcy5cbiAgICogQHBhcmFtIHsoKSA9PiBQcm9taXNlPFQ+fSBjYWxsYmFjayAtIENhbGxiYWNrIGV4ZWN1dGVkIHdpdGggdGVtcG9yYXJ5IHBhcmFtcy5cbiAgICogQHJldHVybnMge1Byb21pc2U8VD59IC0gQ2FsbGJhY2sgcmV0dXJuIHZhbHVlLlxuICAgKi9cbiAgYXN5bmMgd2l0aEZyb250ZW5kTW9kZWxQYXJhbXMocGFyYW1zLCBjYWxsYmFjaykge1xuICAgIGNvbnN0IHByZXZpb3VzT3ZlcnJpZGUgPSB0aGlzLl9mcm9udGVuZE1vZGVsUGFyYW1zT3ZlcnJpZGVcbiAgICBjb25zdCBwcmV2aW91c1BhcmFtcyA9IHRoaXMuX2Zyb250ZW5kTW9kZWxQYXJhbXNcblxuICAgIHRoaXMuX2Zyb250ZW5kTW9kZWxQYXJhbXNPdmVycmlkZSA9IHBhcmFtc1xuICAgIHRoaXMuX2Zyb250ZW5kTW9kZWxQYXJhbXMgPSB1bmRlZmluZWRcblxuICAgIHRyeSB7XG4gICAgICByZXR1cm4gYXdhaXQgY2FsbGJhY2soKVxuICAgIH0gZmluYWxseSB7XG4gICAgICB0aGlzLl9mcm9udGVuZE1vZGVsUGFyYW1zT3ZlcnJpZGUgPSBwcmV2aW91c092ZXJyaWRlXG4gICAgICB0aGlzLl9mcm9udGVuZE1vZGVsUGFyYW1zID0gcHJldmlvdXNQYXJhbXNcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogUnVucyB3aXRoIGZyb250ZW5kIG1vZGVsIHJlcXVlc3QgY29udGV4dC5cbiAgICogQHRlbXBsYXRlIFRcbiAgICogQHBhcmFtIHtSZWNvcmQ8c3RyaW5nLCA/Pn0gcGFyYW1zIC0gUmVxdWVzdC1zY29wZWQgcGFyYW1zLlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4vaHR0cC1zZXJ2ZXIvY2xpZW50L3Jlc3BvbnNlLmpzXCIpLmRlZmF1bHR9IHJlc3BvbnNlIC0gUmVzcG9uc2UgaW5zdGFuY2UuXG4gICAqIEBwYXJhbSB7KCkgPT4gUHJvbWlzZTxUPn0gY2FsbGJhY2sgLSBDYWxsYmFjayBleGVjdXRlZCBpbnNpZGUgcmVzb2x2ZWQgdGVuYW50IGFuZCBhYmlsaXR5IGNvbnRleHQuXG4gICAqIEByZXR1cm5zIHtQcm9taXNlPFQ+fSAtIENhbGxiYWNrIHJldHVybiB2YWx1ZS5cbiAgICovXG4gIGFzeW5jIHdpdGhGcm9udGVuZE1vZGVsUmVxdWVzdENvbnRleHQocGFyYW1zLCByZXNwb25zZSwgY2FsbGJhY2spIHtcbiAgICBjb25zdCBjb25maWd1cmF0aW9uID0gdGhpcy5nZXRDb25maWd1cmF0aW9uKClcbiAgICBjb25zdCB0ZW5hbnQgPSBhd2FpdCBjb25maWd1cmF0aW9uLnJlc29sdmVUZW5hbnQoe1xuICAgICAgcGFyYW1zLFxuICAgICAgcmVxdWVzdDogdGhpcy5yZXF1ZXN0KCksXG4gICAgICByZXNwb25zZVxuICAgIH0pXG5cbiAgICByZXR1cm4gYXdhaXQgY29uZmlndXJhdGlvbi5ydW5XaXRoVGVuYW50KHRlbmFudCwgYXN5bmMgKCkgPT4ge1xuICAgICAgcmV0dXJuIGF3YWl0IGNvbmZpZ3VyYXRpb24uZW5zdXJlQ29ubmVjdGlvbnMoe25hbWU6IFwiRnJvbnRlbmQgbW9kZWwgcmVxdWVzdFwifSwgYXN5bmMgKCkgPT4ge1xuICAgICAgICBjb25zdCBhYmlsaXR5ID0gYXdhaXQgY29uZmlndXJhdGlvbi5yZXNvbHZlQWJpbGl0eSh7XG4gICAgICAgICAgcGFyYW1zLFxuICAgICAgICAgIHJlcXVlc3Q6IHRoaXMucmVxdWVzdCgpLFxuICAgICAgICAgIHJlc3BvbnNlXG4gICAgICAgIH0pXG4gICAgICAgIC8qKlxuICAgICAgICAgKiBQcmV2aW91cyBhYmlsaXR5IG92ZXJyaWRlLlxuICAgICAgICAgIEB0eXBlIHtpbXBvcnQoXCIuL2F1dGhvcml6YXRpb24vYWJpbGl0eS5qc1wiKS5kZWZhdWx0IHwgdW5kZWZpbmVkfSAqL1xuICAgICAgICBjb25zdCBwcmV2aW91c0FiaWxpdHlPdmVycmlkZSA9IHRoaXMuX2Zyb250ZW5kTW9kZWxBYmlsaXR5T3ZlcnJpZGVcblxuICAgICAgICB0aGlzLl9mcm9udGVuZE1vZGVsQWJpbGl0eU92ZXJyaWRlID0gYWJpbGl0eVxuXG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgcmV0dXJuIGF3YWl0IGNvbmZpZ3VyYXRpb24ucnVuV2l0aEFiaWxpdHkoYWJpbGl0eSwgYXN5bmMgKCkgPT4ge1xuICAgICAgICAgICAgcmV0dXJuIGF3YWl0IGNhbGxiYWNrKClcbiAgICAgICAgICB9KVxuICAgICAgICB9IGZpbmFsbHkge1xuICAgICAgICAgIHRoaXMuX2Zyb250ZW5kTW9kZWxBYmlsaXR5T3ZlcnJpZGUgPSBwcmV2aW91c0FiaWxpdHlPdmVycmlkZVxuICAgICAgICB9XG4gICAgICB9KVxuICAgIH0pXG4gIH1cblxuICAvKipcbiAgICogUnVucyBjdXJyZW50IGFiaWxpdHkuXG4gICAqIEByZXR1cm5zIHtpbXBvcnQoXCIuL2F1dGhvcml6YXRpb24vYWJpbGl0eS5qc1wiKS5kZWZhdWx0IHwgdW5kZWZpbmVkfSAtIEN1cnJlbnQgYWJpbGl0eSBmb3IgZnJvbnRlbmQtbW9kZWwgcmVxdWVzdCBzY29wZS5cbiAgICovXG4gIGN1cnJlbnRBYmlsaXR5KCkge1xuICAgIHJldHVybiB0aGlzLl9mcm9udGVuZE1vZGVsQWJpbGl0eU92ZXJyaWRlIHx8IHN1cGVyLmN1cnJlbnRBYmlsaXR5KClcbiAgfVxuXG4gIC8qKlxuICAgKiBSdW5zIGZyb250ZW5kIG1vZGVsIGNsYXNzLlxuICAgKiBAcmV0dXJucyB7dHlwZW9mIGltcG9ydChcIi4vZGF0YWJhc2UvcmVjb3JkL2luZGV4LmpzXCIpLmRlZmF1bHR9IC0gRnJvbnRlbmQgbW9kZWwgY2xhc3MgZm9yIGNvbnRyb2xsZXIgcmVzb3VyY2UgYWN0aW9ucy5cbiAgICovXG4gIGZyb250ZW5kTW9kZWxDbGFzcygpIHtcbiAgICBjb25zdCBmcm9udGVuZE1vZGVsQ2xhc3MgPSB0aGlzLmZyb250ZW5kTW9kZWxDbGFzc0Zyb21Db25maWd1cmF0aW9uKClcbiAgICBjb25zdCBwYXJhbXMgPSB0aGlzLmZyb250ZW5kTW9kZWxQYXJhbXMoKVxuICAgIGNvbnN0IG1vZGVsTmFtZSA9IHR5cGVvZiBwYXJhbXMubW9kZWwgPT09IFwic3RyaW5nXCIgPyBwYXJhbXMubW9kZWwgOiB1bmRlZmluZWRcbiAgICBjb25zdCBjb250cm9sbGVyTmFtZSA9IHR5cGVvZiBwYXJhbXMuY29udHJvbGxlciA9PT0gXCJzdHJpbmdcIiA/IHBhcmFtcy5jb250cm9sbGVyIDogdW5kZWZpbmVkXG5cbiAgICBpZiAoZnJvbnRlbmRNb2RlbENsYXNzKSByZXR1cm4gZnJvbnRlbmRNb2RlbENsYXNzXG5cbiAgICB0aHJvdyBuZXcgRXJyb3IoYE5vIGZyb250ZW5kIG1vZGVsIGNvbmZpZ3VyZWQgZm9yIG1vZGVsICcke21vZGVsTmFtZSB8fCBcInVua25vd25cIn0nIGFuZCBjb250cm9sbGVyICcke2NvbnRyb2xsZXJOYW1lIHx8IFwidW5rbm93blwifScuIEVuc3VyZSBhIEZyb250ZW5kTW9kZWxCYXNlUmVzb3VyY2Ugc3ViY2xhc3MgZXhpc3RzIGluIHNyYy9yZXNvdXJjZXMvIG9yIGlzIGxpc3RlZCBpbiB0aGUgYWJpbGl0eSByZXNvbHZlci5gKVxuICB9XG5cbiAgLyoqXG4gICAqIFJ1bnMgZnJvbnRlbmQgbW9kZWwgcmVzb3VyY2UgY29uZmlndXJhdGlvbi5cbiAgICogQHJldHVybnMge3tiYWNrZW5kUHJvamVjdDogaW1wb3J0KFwiLi9jb25maWd1cmF0aW9uLXR5cGVzLmpzXCIpLkJhY2tlbmRQcm9qZWN0Q29uZmlndXJhdGlvbiwgbW9kZWxOYW1lOiBzdHJpbmcsIHJlc291cmNlQ2xhc3M6IGltcG9ydChcIi4vY29uZmlndXJhdGlvbi10eXBlcy5qc1wiKS5Gcm9udGVuZE1vZGVsUmVzb3VyY2VDbGFzc1R5cGUsIHJlc291cmNlQ29uZmlndXJhdGlvbjogaW1wb3J0KFwiLi9jb25maWd1cmF0aW9uLXR5cGVzLmpzXCIpLk5vcm1hbGl6ZWRGcm9udGVuZE1vZGVsUmVzb3VyY2VDb25maWd1cmF0aW9ufSB8IG51bGx9IC0gRnJvbnRlbmQgbW9kZWwgcmVzb3VyY2UgY29uZmlndXJhdGlvbiBmb3IgY3VycmVudCBjb250cm9sbGVyLlxuICAgKi9cbiAgZnJvbnRlbmRNb2RlbFJlc291cmNlQ29uZmlndXJhdGlvbigpIHtcbiAgICBjb25zdCBwYXJhbXMgPSB0aGlzLmZyb250ZW5kTW9kZWxQYXJhbXMoKVxuICAgIGNvbnN0IG1vZGVsTmFtZSA9IHR5cGVvZiBwYXJhbXMubW9kZWwgPT09IFwic3RyaW5nXCIgPyBwYXJhbXMubW9kZWwgOiB1bmRlZmluZWRcbiAgICBjb25zdCBjb250cm9sbGVyTmFtZSA9IHR5cGVvZiBwYXJhbXMuY29udHJvbGxlciA9PT0gXCJzdHJpbmdcIiA/IHBhcmFtcy5jb250cm9sbGVyIDogdW5kZWZpbmVkXG4gICAgY29uc3QgYmFja2VuZFByb2plY3RzID0gdGhpcy5nZXRDb25maWd1cmF0aW9uKCkuZ2V0QmFja2VuZFByb2plY3RzKClcblxuICAgIGZvciAoY29uc3QgYmFja2VuZFByb2plY3Qgb2YgYmFja2VuZFByb2plY3RzKSB7XG4gICAgICBjb25zdCByZXNvdXJjZXMgPSBmcm9udGVuZE1vZGVsUmVzb3VyY2VzRm9yQmFja2VuZFByb2plY3QoYmFja2VuZFByb2plY3QpXG5cbiAgICAgIGlmIChtb2RlbE5hbWUgJiYgbW9kZWxOYW1lLmxlbmd0aCA+IDAgJiYgcmVzb3VyY2VzW21vZGVsTmFtZV0pIHtcbiAgICAgICAgY29uc3QgcmVzb3VyY2VEZWZpbml0aW9uID0gcmVzb3VyY2VzW21vZGVsTmFtZV1cbiAgICAgICAgY29uc3QgcmVzb3VyY2VDb25maWd1cmF0aW9uID0gZnJvbnRlbmRNb2RlbFJlc291cmNlQ29uZmlndXJhdGlvbkZyb21EZWZpbml0aW9uKHJlc291cmNlRGVmaW5pdGlvbilcbiAgICAgICAgY29uc3QgcmVzb3VyY2VDbGFzcyA9IGZyb250ZW5kTW9kZWxSZXNvdXJjZUNsYXNzRnJvbURlZmluaXRpb24ocmVzb3VyY2VEZWZpbml0aW9uKVxuXG4gICAgICAgIGlmICghcmVzb3VyY2VDb25maWd1cmF0aW9uIHx8ICFyZXNvdXJjZUNsYXNzKSB7XG4gICAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBGcm9udGVuZCBtb2RlbCByZXNvdXJjZSAnJHttb2RlbE5hbWV9JyBtdXN0IGJlIGEgRnJvbnRlbmRNb2RlbEJhc2VSZXNvdXJjZSBzdWJjbGFzc2ApXG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgIGJhY2tlbmRQcm9qZWN0LFxuICAgICAgICAgIG1vZGVsTmFtZSxcbiAgICAgICAgICByZXNvdXJjZUNsYXNzLFxuICAgICAgICAgIHJlc291cmNlQ29uZmlndXJhdGlvblxuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIGlmICghY29udHJvbGxlck5hbWUgfHwgY29udHJvbGxlck5hbWUubGVuZ3RoIDwgMSkgY29udGludWVcblxuICAgICAgZm9yIChjb25zdCByZXNvdXJjZU1vZGVsTmFtZSBpbiByZXNvdXJjZXMpIHtcbiAgICAgICAgY29uc3QgcmVzb3VyY2VEZWZpbml0aW9uID0gcmVzb3VyY2VzW3Jlc291cmNlTW9kZWxOYW1lXVxuICAgICAgICBjb25zdCByZXNvdXJjZUNvbmZpZ3VyYXRpb24gPSBmcm9udGVuZE1vZGVsUmVzb3VyY2VDb25maWd1cmF0aW9uRnJvbURlZmluaXRpb24ocmVzb3VyY2VEZWZpbml0aW9uKVxuICAgICAgICBjb25zdCByZXNvdXJjZUNsYXNzID0gZnJvbnRlbmRNb2RlbFJlc291cmNlQ2xhc3NGcm9tRGVmaW5pdGlvbihyZXNvdXJjZURlZmluaXRpb24pXG5cbiAgICAgICAgaWYgKCFyZXNvdXJjZUNvbmZpZ3VyYXRpb24gfHwgIXJlc291cmNlQ2xhc3MpIHtcbiAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYEZyb250ZW5kIG1vZGVsIHJlc291cmNlICcke3Jlc291cmNlTW9kZWxOYW1lfScgbXVzdCBiZSBhIEZyb250ZW5kTW9kZWxCYXNlUmVzb3VyY2Ugc3ViY2xhc3NgKVxuICAgICAgICB9XG5cbiAgICAgICAgY29uc3QgcmVzb3VyY2VQYXRoID0gdGhpcy5mcm9udGVuZE1vZGVsUmVzb3VyY2VQYXRoKHJlc291cmNlTW9kZWxOYW1lLCByZXNvdXJjZURlZmluaXRpb24pXG5cbiAgICAgICAgaWYgKHRoaXMuZnJvbnRlbmRNb2RlbFJlc291cmNlTWF0Y2hlc0NvbnRyb2xsZXIoe2NvbnRyb2xsZXJOYW1lLCByZXNvdXJjZVBhdGh9KSkge1xuICAgICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICBiYWNrZW5kUHJvamVjdCxcbiAgICAgICAgICAgIG1vZGVsTmFtZTogcmVzb3VyY2VNb2RlbE5hbWUsXG4gICAgICAgICAgICByZXNvdXJjZUNsYXNzLFxuICAgICAgICAgICAgcmVzb3VyY2VDb25maWd1cmF0aW9uXG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuXG4gICAgcmV0dXJuIG51bGxcbiAgfVxuXG4gIC8qKlxuICAgKiBSdW5zIGZyb250ZW5kIG1vZGVsIHJlc291cmNlIGNvbmZpZ3VyYXRpb24gZm9yIGJhY2tlbmQgcHJvamVjdCBtb2RlbCBuYW1lLlxuICAgKiBAcGFyYW0ge29iamVjdH0gYXJncyAtIEFyZ3VtZW50cy5cbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuL2NvbmZpZ3VyYXRpb24tdHlwZXMuanNcIikuQmFja2VuZFByb2plY3RDb25maWd1cmF0aW9ufSBhcmdzLmJhY2tlbmRQcm9qZWN0IC0gQmFja2VuZCBwcm9qZWN0IGNvbmZpZ3VyYXRpb24uXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBhcmdzLm1vZGVsTmFtZSAtIE1vZGVsIG5hbWUuXG4gICAqIEByZXR1cm5zIHt7YmFja2VuZFByb2plY3Q6IGltcG9ydChcIi4vY29uZmlndXJhdGlvbi10eXBlcy5qc1wiKS5CYWNrZW5kUHJvamVjdENvbmZpZ3VyYXRpb24sIG1vZGVsTmFtZTogc3RyaW5nLCByZXNvdXJjZUNsYXNzOiBpbXBvcnQoXCIuL2NvbmZpZ3VyYXRpb24tdHlwZXMuanNcIikuRnJvbnRlbmRNb2RlbFJlc291cmNlQ2xhc3NUeXBlLCByZXNvdXJjZUNvbmZpZ3VyYXRpb246IGltcG9ydChcIi4vY29uZmlndXJhdGlvbi10eXBlcy5qc1wiKS5Ob3JtYWxpemVkRnJvbnRlbmRNb2RlbFJlc291cmNlQ29uZmlndXJhdGlvbn0gfCBudWxsfSAtIEZyb250ZW5kIG1vZGVsIHJlc291cmNlIGNvbmZpZ3VyYXRpb24gZm9yIG1vZGVsIG5hbWUuXG4gICAqL1xuICBmcm9udGVuZE1vZGVsUmVzb3VyY2VDb25maWd1cmF0aW9uRm9yQmFja2VuZFByb2plY3RNb2RlbE5hbWUoe2JhY2tlbmRQcm9qZWN0LCBtb2RlbE5hbWV9KSB7XG4gICAgY29uc3QgcmVzb3VyY2VzID0gZnJvbnRlbmRNb2RlbFJlc291cmNlc0ZvckJhY2tlbmRQcm9qZWN0KGJhY2tlbmRQcm9qZWN0KVxuICAgIGNvbnN0IHJlc291cmNlRGVmaW5pdGlvbiA9IHJlc291cmNlc1ttb2RlbE5hbWVdXG5cbiAgICBpZiAoIXJlc291cmNlRGVmaW5pdGlvbikgcmV0dXJuIG51bGxcblxuICAgIGNvbnN0IHJlc291cmNlQ29uZmlndXJhdGlvbiA9IGZyb250ZW5kTW9kZWxSZXNvdXJjZUNvbmZpZ3VyYXRpb25Gcm9tRGVmaW5pdGlvbihyZXNvdXJjZURlZmluaXRpb24pXG4gICAgY29uc3QgcmVzb3VyY2VDbGFzcyA9IGZyb250ZW5kTW9kZWxSZXNvdXJjZUNsYXNzRnJvbURlZmluaXRpb24ocmVzb3VyY2VEZWZpbml0aW9uKVxuXG4gICAgaWYgKCFyZXNvdXJjZUNvbmZpZ3VyYXRpb24gfHwgIXJlc291cmNlQ2xhc3MpIHJldHVybiBudWxsXG5cbiAgICByZXR1cm4ge1xuICAgICAgYmFja2VuZFByb2plY3QsXG4gICAgICBtb2RlbE5hbWUsXG4gICAgICByZXNvdXJjZUNsYXNzLFxuICAgICAgcmVzb3VyY2VDb25maWd1cmF0aW9uXG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIFJ1bnMgZnJvbnRlbmQgbW9kZWwgcmVzb3VyY2UgY29uZmlndXJhdGlvbiBmb3IgbW9kZWwgY2xhc3MuXG4gICAqIEBwYXJhbSB7dHlwZW9mIGltcG9ydChcIi4vZGF0YWJhc2UvcmVjb3JkL2luZGV4LmpzXCIpLmRlZmF1bHR9IG1vZGVsQ2xhc3MgLSBNb2RlbCBjbGFzcy5cbiAgICogQHJldHVybnMge3tiYWNrZW5kUHJvamVjdDogaW1wb3J0KFwiLi9jb25maWd1cmF0aW9uLXR5cGVzLmpzXCIpLkJhY2tlbmRQcm9qZWN0Q29uZmlndXJhdGlvbiwgbW9kZWxOYW1lOiBzdHJpbmcsIHJlc291cmNlQ2xhc3M6IGltcG9ydChcIi4vY29uZmlndXJhdGlvbi10eXBlcy5qc1wiKS5Gcm9udGVuZE1vZGVsUmVzb3VyY2VDbGFzc1R5cGUsIHJlc291cmNlQ29uZmlndXJhdGlvbjogaW1wb3J0KFwiLi9jb25maWd1cmF0aW9uLXR5cGVzLmpzXCIpLk5vcm1hbGl6ZWRGcm9udGVuZE1vZGVsUmVzb3VyY2VDb25maWd1cmF0aW9ufSB8IG51bGx9IC0gRnJvbnRlbmQgbW9kZWwgcmVzb3VyY2UgY29uZmlndXJhdGlvbiBmb3IgbW9kZWwgY2xhc3MuXG4gICAqL1xuICBmcm9udGVuZE1vZGVsUmVzb3VyY2VDb25maWd1cmF0aW9uRm9yTW9kZWxDbGFzcyhtb2RlbENsYXNzKSB7XG4gICAgY29uc3QgZnJvbnRlbmRNb2RlbFJlc291cmNlID0gdGhpcy5mcm9udGVuZE1vZGVsUmVzb3VyY2VDb25maWd1cmF0aW9uKClcblxuICAgIGlmICghZnJvbnRlbmRNb2RlbFJlc291cmNlKSByZXR1cm4gbnVsbFxuXG4gICAgcmV0dXJuIHRoaXMuZnJvbnRlbmRNb2RlbFJlc291cmNlQ29uZmlndXJhdGlvbkZvckJhY2tlbmRQcm9qZWN0TW9kZWxOYW1lKHtcbiAgICAgIGJhY2tlbmRQcm9qZWN0OiBmcm9udGVuZE1vZGVsUmVzb3VyY2UuYmFja2VuZFByb2plY3QsXG4gICAgICBtb2RlbE5hbWU6IG1vZGVsQ2xhc3MuZ2V0TW9kZWxOYW1lKClcbiAgICB9KVxuICB9XG5cbiAgLyoqXG4gICAqIFJ1bnMgZnJvbnRlbmQgbW9kZWwgcmVzb3VyY2UgbW9kZWwgY2xhc3MuXG4gICAqIEBwYXJhbSB7e21vZGVsTmFtZTogc3RyaW5nLCByZXNvdXJjZUNsYXNzOiBpbXBvcnQoXCIuL2NvbmZpZ3VyYXRpb24tdHlwZXMuanNcIikuRnJvbnRlbmRNb2RlbFJlc291cmNlQ2xhc3NUeXBlfX0gZnJvbnRlbmRNb2RlbFJlc291cmNlIC0gRnJvbnRlbmQgbW9kZWwgcmVzb3VyY2UgY29uZmlndXJhdGlvbi5cbiAgICogQHJldHVybnMge3R5cGVvZiBpbXBvcnQoXCIuL2RhdGFiYXNlL3JlY29yZC9pbmRleC5qc1wiKS5kZWZhdWx0IHwgbnVsbH0gLSBCYWNraW5nIHJlY29yZCBjbGFzcywgd2hlbiBhdmFpbGFibGUuXG4gICAqL1xuICBmcm9udGVuZE1vZGVsUmVzb3VyY2VNb2RlbENsYXNzKGZyb250ZW5kTW9kZWxSZXNvdXJjZSkge1xuICAgIGNvbnN0IHJlc291cmNlTW9kZWxDbGFzcyA9IGZyb250ZW5kTW9kZWxSZXNvdXJjZS5yZXNvdXJjZUNsYXNzLk1vZGVsQ2xhc3NcblxuICAgIGlmIChyZXNvdXJjZU1vZGVsQ2xhc3MpIHJldHVybiByZXNvdXJjZU1vZGVsQ2xhc3NcblxuICAgIHJldHVybiB0aGlzLmdldENvbmZpZ3VyYXRpb24oKS5nZXRNb2RlbENsYXNzZXMoKVtmcm9udGVuZE1vZGVsUmVzb3VyY2UubW9kZWxOYW1lXSB8fCBudWxsXG4gIH1cblxuICAvKipcbiAgICogUnVucyBmcm9udGVuZCBtb2RlbCBjbGFzcyBmcm9tIGNvbmZpZ3VyYXRpb24uXG4gICAqIEByZXR1cm5zIHt0eXBlb2YgaW1wb3J0KFwiLi9kYXRhYmFzZS9yZWNvcmQvaW5kZXguanNcIikuZGVmYXVsdCB8IG51bGx9IC0gRnJvbnRlbmQgbW9kZWwgY2xhc3MgcmVzb2x2ZWQgZnJvbSBiYWNrZW5kIHByb2plY3QgY29uZmlndXJhdGlvbi5cbiAgICovXG4gIGZyb250ZW5kTW9kZWxDbGFzc0Zyb21Db25maWd1cmF0aW9uKCkge1xuICAgIGNvbnN0IGZyb250ZW5kTW9kZWxSZXNvdXJjZSA9IHRoaXMuZnJvbnRlbmRNb2RlbFJlc291cmNlQ29uZmlndXJhdGlvbigpXG5cbiAgICBpZiAoIWZyb250ZW5kTW9kZWxSZXNvdXJjZSkgcmV0dXJuIG51bGxcblxuICAgIGNvbnN0IHJlc291cmNlTW9kZWxDbGFzcyA9IHRoaXMuZnJvbnRlbmRNb2RlbFJlc291cmNlTW9kZWxDbGFzcyhmcm9udGVuZE1vZGVsUmVzb3VyY2UpXG5cbiAgICBpZiAocmVzb3VyY2VNb2RlbENsYXNzKSByZXR1cm4gcmVzb3VyY2VNb2RlbENsYXNzXG5cbiAgICBjb25zdCBtb2RlbENsYXNzZXMgPSB0aGlzLmdldENvbmZpZ3VyYXRpb24oKS5nZXRNb2RlbENsYXNzZXMoKVxuICAgIGNvbnN0IG1vZGVsQ2xhc3MgPSBtb2RlbENsYXNzZXNbZnJvbnRlbmRNb2RlbFJlc291cmNlLm1vZGVsTmFtZV1cblxuICAgIGlmICghbW9kZWxDbGFzcykge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKGBGcm9udGVuZCBtb2RlbCAnJHtmcm9udGVuZE1vZGVsUmVzb3VyY2UubW9kZWxOYW1lfScgaXMgY29uZmlndXJlZCBmb3IgJyR7dGhpcy5mcm9udGVuZE1vZGVsUGFyYW1zKCkuY29udHJvbGxlcn0nLCBidXQgbm8gbW9kZWwgY2xhc3Mgd2FzIHJlZ2lzdGVyZWQuIFJlZ2lzdGVyZWQgbW9kZWxzOiAke09iamVjdC5rZXlzKG1vZGVsQ2xhc3Nlcykuam9pbihcIiwgXCIpfWApXG4gICAgfVxuXG4gICAgcmV0dXJuIG1vZGVsQ2xhc3NcbiAgfVxuXG4gIC8qKlxuICAgKiBFbnN1cmVzIHRoZSBmcm9udGVuZCBtb2RlbCBjbGFzcyBhbmQgcmVxdWVzdGVkIHByZWxvYWQgdGFyZ2V0IGNsYXNzZXMgYXJlIGluaXRpYWxpemVkLlxuICAgKiBUaGlzIGhhbmRsZXMgdGhlIGNhc2Ugd2hlcmUgbW9kZWwgaW5pdGlhbGl6YXRpb24gd2FzIHNraXBwZWQgYXQgc3RhcnR1cCAoZS5nLiwgYnJvd3NlciB0ZXN0cykuXG4gICAqIEByZXR1cm5zIHtQcm9taXNlPHZvaWQ+fSAtIFJlc29sdmVzIHdoZW4gdGhlIG1vZGVsIGNsYXNzIGlzIHJlYWR5LlxuICAgKi9cbiAgYXN5bmMgZW5zdXJlRnJvbnRlbmRNb2RlbENsYXNzSW5pdGlhbGl6ZWQoKSB7XG4gICAgY29uc3QgZnJvbnRlbmRNb2RlbFJlc291cmNlID0gdGhpcy5mcm9udGVuZE1vZGVsUmVzb3VyY2VDb25maWd1cmF0aW9uKClcbiAgICBjb25zdCBtb2RlbENsYXNzID0gdGhpcy5mcm9udGVuZE1vZGVsQ2xhc3NGcm9tQ29uZmlndXJhdGlvbigpXG5cbiAgICBpZiAoIW1vZGVsQ2xhc3MpIHJldHVyblxuXG4gICAgYXdhaXQgdGhpcy5lbnN1cmVGcm9udGVuZE1vZGVsUmVjb3JkQ2xhc3NJbml0aWFsaXplZChtb2RlbENsYXNzKVxuXG4gICAgaWYgKCFmcm9udGVuZE1vZGVsUmVzb3VyY2UpIHJldHVyblxuXG4gICAgYXdhaXQgdGhpcy5lbnN1cmVGcm9udGVuZE1vZGVsUHJlbG9hZENsYXNzZXNJbml0aWFsaXplZCh7XG4gICAgICBiYWNrZW5kUHJvamVjdDogZnJvbnRlbmRNb2RlbFJlc291cmNlLmJhY2tlbmRQcm9qZWN0LFxuICAgICAgbW9kZWxDbGFzcyxcbiAgICAgIHByZWxvYWQ6IHRoaXMuZnJvbnRlbmRNb2RlbFByZWxvYWQoKVxuICAgIH0pXG4gIH1cblxuICAvKipcbiAgICogUnVucyBlbnN1cmUgZnJvbnRlbmQgbW9kZWwgcmVjb3JkIGNsYXNzIGluaXRpYWxpemVkLlxuICAgKiBAcGFyYW0ge3R5cGVvZiBpbXBvcnQoXCIuL2RhdGFiYXNlL3JlY29yZC9pbmRleC5qc1wiKS5kZWZhdWx0fSBtb2RlbENsYXNzIC0gTW9kZWwgY2xhc3MgdG8gaW5pdGlhbGl6ZS5cbiAgICogQHJldHVybnMge1Byb21pc2U8dm9pZD59IC0gUmVzb2x2ZXMgd2hlbiB0aGUgbW9kZWwgY2xhc3MgaXMgcmVhZHkuXG4gICAqL1xuICBhc3luYyBlbnN1cmVGcm9udGVuZE1vZGVsUmVjb3JkQ2xhc3NJbml0aWFsaXplZChtb2RlbENsYXNzKSB7XG4gICAgaWYgKCFtb2RlbENsYXNzIHx8IG1vZGVsQ2xhc3MuaXNJbml0aWFsaXplZCgpKSByZXR1cm5cblxuICAgIGNvbnN0IGNvbmZpZ3VyYXRpb24gPSB0aGlzLmdldENvbmZpZ3VyYXRpb24oKVxuXG4gICAgaWYgKHR5cGVvZiBtb2RlbENsYXNzLmVuc3VyZUluaXRpYWxpemVkID09PSBcImZ1bmN0aW9uXCIpIHtcbiAgICAgIGF3YWl0IG1vZGVsQ2xhc3MuZW5zdXJlSW5pdGlhbGl6ZWQoe2NvbmZpZ3VyYXRpb259KVxuICAgIH0gZWxzZSBpZiAodHlwZW9mIG1vZGVsQ2xhc3MuaW5pdGlhbGl6ZVJlY29yZCA9PT0gXCJmdW5jdGlvblwiKSB7XG4gICAgICBhd2FpdCBtb2RlbENsYXNzLmluaXRpYWxpemVSZWNvcmQoe2NvbmZpZ3VyYXRpb259KVxuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBSdW5zIGVuc3VyZSBmcm9udGVuZCBtb2RlbCBwcmVsb2FkIGNsYXNzZXMgaW5pdGlhbGl6ZWQuXG4gICAqIEBwYXJhbSB7b2JqZWN0fSBhcmdzIC0gQXJndW1lbnRzLlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4vY29uZmlndXJhdGlvbi10eXBlcy5qc1wiKS5CYWNrZW5kUHJvamVjdENvbmZpZ3VyYXRpb259IGFyZ3MuYmFja2VuZFByb2plY3QgLSBCYWNrZW5kIHByb2plY3QgY29uZmlndXJhdGlvbi5cbiAgICogQHBhcmFtIHt0eXBlb2YgaW1wb3J0KFwiLi9kYXRhYmFzZS9yZWNvcmQvaW5kZXguanNcIikuZGVmYXVsdH0gYXJncy5tb2RlbENsYXNzIC0gTW9kZWwgY2xhc3Mgd2hvc2UgcHJlbG9hZCB0cmVlIGlzIGJlaW5nIHJlc29sdmVkLlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4vZGF0YWJhc2UvcXVlcnkvaW5kZXguanNcIikuTmVzdGVkUHJlbG9hZFJlY29yZCB8IG51bGx9IGFyZ3MucHJlbG9hZCAtIE5vcm1hbGl6ZWQgcHJlbG9hZCB0cmVlLlxuICAgKiBAcmV0dXJucyB7UHJvbWlzZTx2b2lkPn0gLSBSZXNvbHZlcyB3aGVuIHByZWxvYWQgdGFyZ2V0IGNsYXNzZXMgYXJlIGluaXRpYWxpemVkLlxuICAgKi9cbiAgYXN5bmMgZW5zdXJlRnJvbnRlbmRNb2RlbFByZWxvYWRDbGFzc2VzSW5pdGlhbGl6ZWQoe2JhY2tlbmRQcm9qZWN0LCBtb2RlbENsYXNzLCBwcmVsb2FkfSkge1xuICAgIGlmICghcHJlbG9hZCkgcmV0dXJuXG5cbiAgICBmb3IgKGNvbnN0IFtyZWxhdGlvbnNoaXBOYW1lLCByZWxhdGlvbnNoaXBQcmVsb2FkXSBvZiBPYmplY3QuZW50cmllcyhwcmVsb2FkKSkge1xuICAgICAgaWYgKHJlbGF0aW9uc2hpcFByZWxvYWQgPT09IGZhbHNlKSBjb250aW51ZVxuXG4gICAgICBjb25zdCByZWxhdGlvbnNoaXAgPSBtb2RlbENsYXNzLmdldFJlbGF0aW9uc2hpcEJ5TmFtZShyZWxhdGlvbnNoaXBOYW1lKVxuICAgICAgY29uc3QgdGFyZ2V0TW9kZWxDbGFzcyA9IGF3YWl0IHRoaXMuZW5zdXJlRnJvbnRlbmRNb2RlbFJlbGF0aW9uc2hpcFRhcmdldENsYXNzSW5pdGlhbGl6ZWQoe1xuICAgICAgICBiYWNrZW5kUHJvamVjdCxcbiAgICAgICAgcmVsYXRpb25zaGlwXG4gICAgICB9KVxuXG4gICAgICBpZiAoIXRhcmdldE1vZGVsQ2xhc3MgfHwgIWlzUGxhaW5PYmplY3QocmVsYXRpb25zaGlwUHJlbG9hZCkpIGNvbnRpbnVlXG5cbiAgICAgIGF3YWl0IHRoaXMuZW5zdXJlRnJvbnRlbmRNb2RlbFByZWxvYWRDbGFzc2VzSW5pdGlhbGl6ZWQoe1xuICAgICAgICBiYWNrZW5kUHJvamVjdCxcbiAgICAgICAgbW9kZWxDbGFzczogdGFyZ2V0TW9kZWxDbGFzcyxcbiAgICAgICAgcHJlbG9hZDogLyoqXG4gICAgICAgICAgICAgICAgICAqIFR5cGVzIHRoZSBmb2xsb3dpbmcgdmFsdWUuXG4gICAgICAgICAgICAgICAgICAgQHR5cGUge2ltcG9ydChcIi4vZGF0YWJhc2UvcXVlcnkvaW5kZXguanNcIikuTmVzdGVkUHJlbG9hZFJlY29yZH0gKi8gKHJlbGF0aW9uc2hpcFByZWxvYWQpXG4gICAgICB9KVxuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBSdW5zIGVuc3VyZSBmcm9udGVuZCBtb2RlbCByZWxhdGlvbnNoaXAgdGFyZ2V0IGNsYXNzIGluaXRpYWxpemVkLlxuICAgKiBAcGFyYW0ge29iamVjdH0gYXJncyAtIEFyZ3VtZW50cy5cbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuL2NvbmZpZ3VyYXRpb24tdHlwZXMuanNcIikuQmFja2VuZFByb2plY3RDb25maWd1cmF0aW9ufSBhcmdzLmJhY2tlbmRQcm9qZWN0IC0gQmFja2VuZCBwcm9qZWN0IGNvbmZpZ3VyYXRpb24uXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi9kYXRhYmFzZS9yZWNvcmQvcmVsYXRpb25zaGlwcy9iYXNlLmpzXCIpLmRlZmF1bHR9IGFyZ3MucmVsYXRpb25zaGlwIC0gUmVsYXRpb25zaGlwIGRlZmluaXRpb24uXG4gICAqIEByZXR1cm5zIHtQcm9taXNlPHR5cGVvZiBpbXBvcnQoXCIuL2RhdGFiYXNlL3JlY29yZC9pbmRleC5qc1wiKS5kZWZhdWx0IHwgbnVsbD59IC0gVGFyZ2V0IG1vZGVsIGNsYXNzLCB3aGVuIGF2YWlsYWJsZS5cbiAgICovXG4gIGFzeW5jIGVuc3VyZUZyb250ZW5kTW9kZWxSZWxhdGlvbnNoaXBUYXJnZXRDbGFzc0luaXRpYWxpemVkKHtiYWNrZW5kUHJvamVjdCwgcmVsYXRpb25zaGlwfSkge1xuICAgIGlmIChyZWxhdGlvbnNoaXAudGhyb3VnaCkge1xuICAgICAgY29uc3QgdGhyb3VnaFJlbGF0aW9uc2hpcCA9IHJlbGF0aW9uc2hpcC5nZXRNb2RlbENsYXNzKCkuZ2V0UmVsYXRpb25zaGlwQnlOYW1lKHJlbGF0aW9uc2hpcC50aHJvdWdoKVxuICAgICAgYXdhaXQgdGhpcy5lbnN1cmVGcm9udGVuZE1vZGVsUmVsYXRpb25zaGlwVGFyZ2V0Q2xhc3NJbml0aWFsaXplZCh7XG4gICAgICAgIGJhY2tlbmRQcm9qZWN0LFxuICAgICAgICByZWxhdGlvbnNoaXA6IHRocm91Z2hSZWxhdGlvbnNoaXBcbiAgICAgIH0pXG4gICAgfVxuXG4gICAgY29uc3QgdGFyZ2V0TW9kZWxDbGFzcyA9IHRoaXMuZnJvbnRlbmRNb2RlbFJlbGF0aW9uc2hpcFRhcmdldE1vZGVsQ2xhc3Moe1xuICAgICAgYmFja2VuZFByb2plY3QsXG4gICAgICByZWxhdGlvbnNoaXBcbiAgICB9KVxuXG4gICAgaWYgKCF0YXJnZXRNb2RlbENsYXNzKSByZXR1cm4gbnVsbFxuXG4gICAgYXdhaXQgdGhpcy5lbnN1cmVGcm9udGVuZE1vZGVsUmVjb3JkQ2xhc3NJbml0aWFsaXplZCh0YXJnZXRNb2RlbENsYXNzKVxuXG4gICAgcmV0dXJuIHRhcmdldE1vZGVsQ2xhc3NcbiAgfVxuXG4gIC8qKlxuICAgKiBSdW5zIGZyb250ZW5kIG1vZGVsIHJlbGF0aW9uc2hpcCB0YXJnZXQgbW9kZWwgY2xhc3MuXG4gICAqIEBwYXJhbSB7b2JqZWN0fSBhcmdzIC0gQXJndW1lbnRzLlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4vY29uZmlndXJhdGlvbi10eXBlcy5qc1wiKS5CYWNrZW5kUHJvamVjdENvbmZpZ3VyYXRpb259IGFyZ3MuYmFja2VuZFByb2plY3QgLSBCYWNrZW5kIHByb2plY3QgY29uZmlndXJhdGlvbi5cbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuL2RhdGFiYXNlL3JlY29yZC9yZWxhdGlvbnNoaXBzL2Jhc2UuanNcIikuZGVmYXVsdH0gYXJncy5yZWxhdGlvbnNoaXAgLSBSZWxhdGlvbnNoaXAgZGVmaW5pdGlvbi5cbiAgICogQHJldHVybnMge3R5cGVvZiBpbXBvcnQoXCIuL2RhdGFiYXNlL3JlY29yZC9pbmRleC5qc1wiKS5kZWZhdWx0IHwgbnVsbH0gLSBUYXJnZXQgbW9kZWwgY2xhc3MsIHdoZW4gYXZhaWxhYmxlLlxuICAgKi9cbiAgZnJvbnRlbmRNb2RlbFJlbGF0aW9uc2hpcFRhcmdldE1vZGVsQ2xhc3Moe2JhY2tlbmRQcm9qZWN0LCByZWxhdGlvbnNoaXB9KSB7XG4gICAgaWYgKHJlbGF0aW9uc2hpcC5nZXRQb2x5bW9ycGhpYygpICYmIHJlbGF0aW9uc2hpcC5nZXRUeXBlKCkgPT09IFwiYmVsb25nc1RvXCIpIHJldHVybiBudWxsXG5cbiAgICBpZiAocmVsYXRpb25zaGlwLmtsYXNzKSByZXR1cm4gcmVsYXRpb25zaGlwLmtsYXNzXG5cbiAgICBpZiAocmVsYXRpb25zaGlwLmNsYXNzTmFtZSkge1xuICAgICAgY29uc3QgZnJvbnRlbmRNb2RlbFJlc291cmNlID0gdGhpcy5mcm9udGVuZE1vZGVsUmVzb3VyY2VDb25maWd1cmF0aW9uRm9yQmFja2VuZFByb2plY3RNb2RlbE5hbWUoe1xuICAgICAgICBiYWNrZW5kUHJvamVjdCxcbiAgICAgICAgbW9kZWxOYW1lOiByZWxhdGlvbnNoaXAuY2xhc3NOYW1lXG4gICAgICB9KVxuICAgICAgY29uc3QgcmVzb3VyY2VNb2RlbENsYXNzID0gZnJvbnRlbmRNb2RlbFJlc291cmNlID8gdGhpcy5mcm9udGVuZE1vZGVsUmVzb3VyY2VNb2RlbENsYXNzKGZyb250ZW5kTW9kZWxSZXNvdXJjZSkgOiBudWxsXG5cbiAgICAgIGlmIChyZXNvdXJjZU1vZGVsQ2xhc3MpIHJldHVybiByZXNvdXJjZU1vZGVsQ2xhc3NcblxuICAgICAgY29uc3QgcmVnaXN0ZXJlZE1vZGVsQ2xhc3MgPSB0aGlzLmdldENvbmZpZ3VyYXRpb24oKS5nZXRNb2RlbENsYXNzZXMoKVtyZWxhdGlvbnNoaXAuY2xhc3NOYW1lXVxuXG4gICAgICBpZiAocmVnaXN0ZXJlZE1vZGVsQ2xhc3MpIHJldHVybiByZWdpc3RlcmVkTW9kZWxDbGFzc1xuICAgIH1cblxuICAgIGNvbnN0IHRhcmdldE1vZGVsQ2xhc3MgPSByZWxhdGlvbnNoaXAuZ2V0VGFyZ2V0TW9kZWxDbGFzcygpXG5cbiAgICByZXR1cm4gdGFyZ2V0TW9kZWxDbGFzcyB8fCBudWxsXG4gIH1cblxuICAvKipcbiAgICogUnVucyBmcm9udGVuZCBtb2RlbCByZXNvdXJjZSBwYXRoLlxuICAgKiBAcGFyYW0ge3N0cmluZ30gbW9kZWxOYW1lIC0gTW9kZWwgY2xhc3MgbmFtZS5cbiAgICogQHBhcmFtIHs/fSByZXNvdXJjZURlZmluaXRpb24gLSBSZXNvdXJjZSBkZWZpbml0aW9uLlxuICAgKiBAcmV0dXJucyB7c3RyaW5nfSAtIE5vcm1hbGl6ZWQgcmVzb3VyY2UgcGF0aC5cbiAgICovXG4gIGZyb250ZW5kTW9kZWxSZXNvdXJjZVBhdGgobW9kZWxOYW1lLCByZXNvdXJjZURlZmluaXRpb24pIHtcbiAgICByZXR1cm4gZnJvbnRlbmRNb2RlbFJlc291cmNlUGF0aChtb2RlbE5hbWUsIHJlc291cmNlRGVmaW5pdGlvbilcbiAgfVxuXG4gIC8qKlxuICAgKiBSdW5zIGZyb250ZW5kIG1vZGVsIHJlc291cmNlIG1hdGNoZXMgY29udHJvbGxlci5cbiAgICogQHBhcmFtIHtvYmplY3R9IGFyZ3MgLSBBcmd1bWVudHMuXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBhcmdzLmNvbnRyb2xsZXJOYW1lIC0gQ29udHJvbGxlciBuYW1lIGZyb20gcGFyYW1zLlxuICAgKiBAcGFyYW0ge3N0cmluZ30gYXJncy5yZXNvdXJjZVBhdGggLSBSZXNvdXJjZSBwYXRoIGZyb20gY29uZmlndXJhdGlvbi5cbiAgICogQHJldHVybnMge2Jvb2xlYW59IC0gV2hldGhlciByZXNvdXJjZSBwYXRoIG1hdGNoZXMgY3VycmVudCBjb250cm9sbGVyLlxuICAgKi9cbiAgZnJvbnRlbmRNb2RlbFJlc291cmNlTWF0Y2hlc0NvbnRyb2xsZXIoe2NvbnRyb2xsZXJOYW1lLCByZXNvdXJjZVBhdGh9KSB7XG4gICAgY29uc3Qgbm9ybWFsaXplZENvbnRyb2xsZXIgPSBjb250cm9sbGVyTmFtZS5yZXBsYWNlKC9eXFwvK3xcXC8rJC9nLCBcIlwiKVxuICAgIGNvbnN0IG5vcm1hbGl6ZWRSZXNvdXJjZVBhdGggPSByZXNvdXJjZVBhdGgucmVwbGFjZSgvXlxcLyt8XFwvKyQvZywgXCJcIilcblxuICAgIGlmIChub3JtYWxpemVkUmVzb3VyY2VQYXRoID09PSBub3JtYWxpemVkQ29udHJvbGxlcikgcmV0dXJuIHRydWVcblxuICAgIHJldHVybiBub3JtYWxpemVkUmVzb3VyY2VQYXRoLmVuZHNXaXRoKGAvJHtub3JtYWxpemVkQ29udHJvbGxlcn1gKVxuICB9XG5cbiAgLyoqXG4gICAqIFJ1bnMgZnJvbnRlbmQgbW9kZWwgcmVzb3VyY2UgaW5zdGFuY2UuXG4gICAqIEByZXR1cm5zIHtGcm9udGVuZE1vZGVsQmFzZVJlc291cmNlfSAtIEJhY2tlbmQgcmVzb3VyY2UgaW5zdGFuY2UgZm9yIGN1cnJlbnQgZnJvbnRlbmQtbW9kZWwgYWN0aW9uLlxuICAgKi9cbiAgZnJvbnRlbmRNb2RlbFJlc291cmNlSW5zdGFuY2UoKSB7XG4gICAgY29uc3QgZnJvbnRlbmRNb2RlbFJlc291cmNlID0gdGhpcy5mcm9udGVuZE1vZGVsUmVzb3VyY2VDb25maWd1cmF0aW9uKClcblxuICAgIGlmICghZnJvbnRlbmRNb2RlbFJlc291cmNlKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoYE5vIGZyb250ZW5kIG1vZGVsIHJlc291cmNlIGNvbmZpZ3VyYXRpb24gZm9yIGNvbnRyb2xsZXIgJyR7dGhpcy5mcm9udGVuZE1vZGVsUGFyYW1zKCkuY29udHJvbGxlcn0nYClcbiAgICB9XG5cbiAgICBjb25zdCByZXNvdXJjZUFyZ3MgPSB7XG4gICAgICBhYmlsaXR5OiB0aGlzLmN1cnJlbnRBYmlsaXR5KCksXG4gICAgICBjb250cm9sbGVyOiB0aGlzLFxuICAgICAgY29udGV4dDoge1xuICAgICAgICAuLi4odGhpcy5jdXJyZW50QWJpbGl0eSgpPy5nZXRDb250ZXh0KCkgfHwge30pLFxuICAgICAgICBwYXJhbXM6IHRoaXMuZnJvbnRlbmRNb2RlbFBhcmFtcygpLFxuICAgICAgICByZXF1ZXN0OiB0aGlzLnJlcXVlc3QoKVxuICAgICAgfSxcbiAgICAgIGxvY2FsczogdGhpcy5jdXJyZW50QWJpbGl0eSgpPy5nZXRMb2NhbHMoKSB8fCB7fSxcbiAgICAgIG1vZGVsQ2xhc3M6IHRoaXMuZnJvbnRlbmRNb2RlbENsYXNzKCksXG4gICAgICBtb2RlbE5hbWU6IGZyb250ZW5kTW9kZWxSZXNvdXJjZS5tb2RlbE5hbWUsXG4gICAgICBwYXJhbXM6IHRoaXMuZnJvbnRlbmRNb2RlbFBhcmFtcygpLFxuICAgICAgcmVzb3VyY2VDb25maWd1cmF0aW9uOiBmcm9udGVuZE1vZGVsUmVzb3VyY2UucmVzb3VyY2VDb25maWd1cmF0aW9uXG4gICAgfVxuXG4gICAgcmV0dXJuIG5ldyBmcm9udGVuZE1vZGVsUmVzb3VyY2UucmVzb3VyY2VDbGFzcyhyZXNvdXJjZUFyZ3MpXG4gIH1cblxuICAvKipcbiAgICogUnVucyBmcm9udGVuZCBtb2RlbCBwcmltYXJ5IGtleS5cbiAgICogQHJldHVybnMge3N0cmluZ30gLSBGcm9udGVuZCBtb2RlbCBwcmltYXJ5IGtleS5cbiAgICovXG4gIGZyb250ZW5kTW9kZWxQcmltYXJ5S2V5KCkge1xuICAgIHJldHVybiB0aGlzLmZyb250ZW5kTW9kZWxDbGFzcygpLnByaW1hcnlLZXkoKVxuICB9XG5cbiAgLyoqXG4gICAqIFJ1bnMgZnJvbnRlbmQgbW9kZWwgYWJpbGl0eSBhY3Rpb24uXG4gICAqIEBwYXJhbSB7XCJpbmRleFwiIHwgXCJmaW5kXCIgfCBcImNyZWF0ZVwiIHwgXCJ1cGRhdGVcIiB8IFwiZGVzdHJveVwiIHwgXCJhdHRhY2hcIiB8IFwiZG93bmxvYWRcIiB8IFwidXJsXCJ9IGFjdGlvbiAtIEZyb250ZW5kIGFjdGlvbi5cbiAgICogQHJldHVybnMge3N0cmluZ30gLSBBYmlsaXR5IGFjdGlvbiBjb25maWd1cmVkIGZvciB0aGUgZnJvbnRlbmQgYWN0aW9uLlxuICAgKi9cbiAgZnJvbnRlbmRNb2RlbEFiaWxpdHlBY3Rpb24oYWN0aW9uKSB7XG4gICAgY29uc3QgZnJvbnRlbmRNb2RlbFJlc291cmNlID0gdGhpcy5mcm9udGVuZE1vZGVsUmVzb3VyY2VDb25maWd1cmF0aW9uKClcblxuICAgIGlmICghZnJvbnRlbmRNb2RlbFJlc291cmNlKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoYE5vIGZyb250ZW5kIG1vZGVsIHJlc291cmNlIGNvbmZpZ3VyYXRpb24gZm9yIGNvbnRyb2xsZXIgJyR7dGhpcy5mcm9udGVuZE1vZGVsUGFyYW1zKCkuY29udHJvbGxlcn0nYClcbiAgICB9XG5cbiAgICBjb25zdCBhYmlsaXRpZXMgPSBmcm9udGVuZE1vZGVsUmVzb3VyY2UucmVzb3VyY2VDb25maWd1cmF0aW9uLmFiaWxpdGllc1xuXG4gICAgaWYgKCFhYmlsaXRpZXMgfHwgdHlwZW9mIGFiaWxpdGllcyAhPT0gXCJvYmplY3RcIikge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKGBSZXNvdXJjZSAnJHtmcm9udGVuZE1vZGVsUmVzb3VyY2UubW9kZWxOYW1lfScgbXVzdCBkZWZpbmUgYW4gJ2FiaWxpdGllcycgb2JqZWN0YClcbiAgICB9XG5cbiAgICBjb25zdCBhYmlsaXR5S2V5ID0gYWN0aW9uID09PSBcImF0dGFjaFwiXG4gICAgICA/IFwidXBkYXRlXCJcbiAgICAgIDogKChhY3Rpb24gPT09IFwiZG93bmxvYWRcIiB8fCBhY3Rpb24gPT09IFwidXJsXCIpID8gXCJmaW5kXCIgOiBhY3Rpb24pXG4gICAgY29uc3QgYWJpbGl0eUFjdGlvbiA9IGFiaWxpdGllc1thYmlsaXR5S2V5XVxuXG4gICAgaWYgKHR5cGVvZiBhYmlsaXR5QWN0aW9uICE9PSBcInN0cmluZ1wiIHx8IGFiaWxpdHlBY3Rpb24ubGVuZ3RoIDwgMSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKGBSZXNvdXJjZSAnJHtmcm9udGVuZE1vZGVsUmVzb3VyY2UubW9kZWxOYW1lfScgbXVzdCBkZWZpbmUgYWJpbGl0aWVzLiR7YWJpbGl0eUtleX1gKVxuICAgIH1cblxuICAgIHJldHVybiBhYmlsaXR5QWN0aW9uXG4gIH1cblxuICAvKipcbiAgICogUnVucyBmcm9udGVuZCBtb2RlbCBhdXRob3JpemVkIHF1ZXJ5LlxuICAgKiBAcGFyYW0ge1wiaW5kZXhcIiB8IFwiZmluZFwiIHwgXCJjcmVhdGVcIiB8IFwidXBkYXRlXCIgfCBcImRlc3Ryb3lcIiB8IFwiYXR0YWNoXCIgfCBcImRvd25sb2FkXCIgfCBcInVybFwifSBhY3Rpb24gLSBGcm9udGVuZCBhY3Rpb24uXG4gICAqIEByZXR1cm5zIHtpbXBvcnQoXCIuL2RhdGFiYXNlL3F1ZXJ5L21vZGVsLWNsYXNzLXF1ZXJ5LmpzXCIpLmRlZmF1bHQ8Pz59IC0gQXV0aG9yaXplZCBxdWVyeSBmb3IgdGhlIGFjdGlvbi5cbiAgICovXG4gIGZyb250ZW5kTW9kZWxBdXRob3JpemVkUXVlcnkoYWN0aW9uKSB7XG4gICAgY29uc3QgYWJpbGl0eUFjdGlvbiA9IHRoaXMuZnJvbnRlbmRNb2RlbEFiaWxpdHlBY3Rpb24oYWN0aW9uKVxuXG4gICAgcmV0dXJuIHRoaXMuZnJvbnRlbmRNb2RlbENsYXNzKCkuYWNjZXNzaWJsZUZvcihhYmlsaXR5QWN0aW9uLCB0aGlzLmN1cnJlbnRBYmlsaXR5KCkpXG4gIH1cblxuICAvKipcbiAgICogUnVucyBmcm9udGVuZCBtb2RlbCBwcmltYXJ5IGtleSB2YWx1ZS5cbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuL2RhdGFiYXNlL3JlY29yZC9pbmRleC5qc1wiKS5kZWZhdWx0fSBtb2RlbCAtIE1vZGVsIGluc3RhbmNlLlxuICAgKiBAcmV0dXJucyB7c3RyaW5nfSAtIFByaW1hcnkga2V5IHZhbHVlIGFzIHN0cmluZy5cbiAgICovXG4gIGZyb250ZW5kTW9kZWxQcmltYXJ5S2V5VmFsdWUobW9kZWwpIHtcbiAgICBjb25zdCBjb2x1bW5OYW1lID0gdGhpcy5mcm9udGVuZE1vZGVsUHJpbWFyeUtleSgpXG4gICAgY29uc3QgYXR0cmlidXRlTmFtZU1hcCA9IG1vZGVsLmdldE1vZGVsQ2xhc3MoKS5nZXRDb2x1bW5OYW1lVG9BdHRyaWJ1dGVOYW1lTWFwKClcbiAgICBjb25zdCBhdHRyaWJ1dGVOYW1lID0gYXR0cmlidXRlTmFtZU1hcFtjb2x1bW5OYW1lXSB8fCBjb2x1bW5OYW1lXG4gICAgY29uc3QgdmFsdWUgPSBtb2RlbC5yZWFkQXR0cmlidXRlKGF0dHJpYnV0ZU5hbWUpXG5cbiAgICByZXR1cm4gU3RyaW5nKHZhbHVlKVxuICB9XG5cbiAgLyoqXG4gICAqIFJ1bnMgZnJvbnRlbmQgbW9kZWwgZmlsdGVyIGF1dGhvcml6ZWQgbW9kZWxzLlxuICAgKiBAcGFyYW0ge29iamVjdH0gYXJncyAtIEFyZ3VtZW50cy5cbiAgICogQHBhcmFtIHtcImluZGV4XCIgfCBcImZpbmRcIiB8IFwiY3JlYXRlXCIgfCBcInVwZGF0ZVwiIHwgXCJkZXN0cm95XCIgfCBcImF0dGFjaFwiIHwgXCJkb3dubG9hZFwiIHwgXCJ1cmxcIn0gYXJncy5hY3Rpb24gLSBGcm9udGVuZCBhY3Rpb24uXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi9kYXRhYmFzZS9yZWNvcmQvaW5kZXguanNcIikuZGVmYXVsdFtdfSBhcmdzLm1vZGVscyAtIENhbmRpZGF0ZSBtb2RlbHMuXG4gICAqIEByZXR1cm5zIHtQcm9taXNlPGltcG9ydChcIi4vZGF0YWJhc2UvcmVjb3JkL2luZGV4LmpzXCIpLmRlZmF1bHRbXT59IC0gQXV0aG9yaXplZCBtb2RlbHMuXG4gICAqL1xuICBhc3luYyBmcm9udGVuZE1vZGVsRmlsdGVyQXV0aG9yaXplZE1vZGVscyh7YWN0aW9uLCBtb2RlbHN9KSB7XG4gICAgaWYgKG1vZGVscy5sZW5ndGggPT09IDApIHJldHVybiBtb2RlbHNcblxuICAgIGNvbnN0IHByaW1hcnlLZXkgPSB0aGlzLmZyb250ZW5kTW9kZWxQcmltYXJ5S2V5KClcbiAgICBjb25zdCBpZHMgPSBtb2RlbHMubWFwKChtb2RlbCkgPT4gdGhpcy5mcm9udGVuZE1vZGVsUHJpbWFyeUtleVZhbHVlKG1vZGVsKSlcbiAgICBjb25zdCBhdXRob3JpemVkUXVlcnkgPSB0aGlzLmZyb250ZW5kTW9kZWxBdXRob3JpemVkUXVlcnkoYWN0aW9uKS53aGVyZSh7W3ByaW1hcnlLZXldOiBpZHN9KVxuXG4gICAgY29uc3QgYXV0aG9yaXplZElkc1JhdyA9IGF3YWl0IGF1dGhvcml6ZWRRdWVyeS5wbHVjayhwcmltYXJ5S2V5KVxuXG4gICAgY29uc3QgYXV0aG9yaXplZElkcyA9IG5ldyBTZXQoYXV0aG9yaXplZElkc1Jhdy5tYXAoKGlkKSA9PiBTdHJpbmcoaWQpKSlcblxuICAgIHJldHVybiBtb2RlbHMuZmlsdGVyKChtb2RlbCkgPT4gYXV0aG9yaXplZElkcy5oYXModGhpcy5mcm9udGVuZE1vZGVsUHJpbWFyeUtleVZhbHVlKG1vZGVsKSkpXG4gIH1cblxuICAvKipcbiAgICogUnVucyBydW4gZnJvbnRlbmQgbW9kZWwgYmVmb3JlIGFjdGlvbi5cbiAgICogQHBhcmFtIHtcImluZGV4XCIgfCBcImZpbmRcIiB8IFwiY3JlYXRlXCIgfCBcInVwZGF0ZVwiIHwgXCJkZXN0cm95XCIgfCBcImF0dGFjaFwiIHwgXCJkb3dubG9hZFwiIHwgXCJ1cmxcIn0gYWN0aW9uIC0gRnJvbnRlbmQgYWN0aW9uLlxuICAgKiBAcmV0dXJucyB7UHJvbWlzZTxib29sZWFuPn0gLSBXaGV0aGVyIGFjdGlvbiBzaG91bGQgY29udGludWUuXG4gICAqL1xuICBhc3luYyBydW5Gcm9udGVuZE1vZGVsQmVmb3JlQWN0aW9uKGFjdGlvbikge1xuICAgIGNvbnN0IHJlc3VsdCA9IGF3YWl0IHRoaXMuZnJvbnRlbmRNb2RlbFJlc291cmNlSW5zdGFuY2UoKS5iZWZvcmVBY3Rpb24oYWN0aW9uKVxuXG4gICAgcmV0dXJuIHJlc3VsdCAhPT0gZmFsc2VcbiAgfVxuXG4gIC8qKlxuICAgKiBSdW5zIGZyb250ZW5kIG1vZGVsIGZpbmQgcmVjb3JkLlxuICAgKiBAcGFyYW0ge1wiZmluZFwiIHwgXCJ1cGRhdGVcIiB8IFwiZGVzdHJveVwiIHwgXCJhdHRhY2hcIiB8IFwiZG93bmxvYWRcIiB8IFwidXJsXCJ9IGFjdGlvbiAtIEZyb250ZW5kIGFjdGlvbi5cbiAgICogQHBhcmFtIHtzdHJpbmcgfCBudW1iZXJ9IGlkIC0gUmVjb3JkIGlkLlxuICAgKiBAcmV0dXJucyB7UHJvbWlzZTxpbXBvcnQoXCIuL2RhdGFiYXNlL3JlY29yZC9pbmRleC5qc1wiKS5kZWZhdWx0IHwgbnVsbD59IC0gTG9jYXRlZCBtb2RlbCByZWNvcmQuXG4gICAqL1xuICBhc3luYyBmcm9udGVuZE1vZGVsRmluZFJlY29yZChhY3Rpb24sIGlkKSB7XG4gICAgY29uc3QgbW9kZWwgPSBhd2FpdCB0aGlzLmZyb250ZW5kTW9kZWxSZXNvdXJjZUluc3RhbmNlKCkuZmluZChhY3Rpb24sIGlkKVxuXG4gICAgaWYgKCFtb2RlbCkgcmV0dXJuIG51bGxcblxuICAgIGNvbnN0IGF1dGhvcml6ZWRNb2RlbHMgPSBhd2FpdCB0aGlzLmZyb250ZW5kTW9kZWxGaWx0ZXJBdXRob3JpemVkTW9kZWxzKHthY3Rpb24sIG1vZGVsczogW21vZGVsXX0pXG5cbiAgICByZXR1cm4gYXV0aG9yaXplZE1vZGVsc1swXSB8fCBudWxsXG4gIH1cblxuICAvKipcbiAgICogUnVucyBmcm9udGVuZCBtb2RlbCBjcmVhdGUgcmVjb3JkLlxuICAgKiBAcGFyYW0ge1JlY29yZDxzdHJpbmcsID8+fSBhdHRyaWJ1dGVzIC0gQ3JlYXRlIGF0dHJpYnV0ZXMuXG4gICAqIEBwYXJhbSB7UmVjb3JkPHN0cmluZywgPz4gfCBudWxsfSBbbmVzdGVkQXR0cmlidXRlc10gLSBPcHRpb25hbCBuZXN0ZWQtYXR0cmlidXRlIHBheWxvYWQgZm9yIGNhc2NhZGluZyB3cml0ZXMuXG4gICAqIEByZXR1cm5zIHtQcm9taXNlPGltcG9ydChcIi4vZGF0YWJhc2UvcmVjb3JkL2luZGV4LmpzXCIpLmRlZmF1bHQgfCBudWxsPn0gLSBDcmVhdGVkIG1vZGVsIHdoZW4gYXV0aG9yaXplZC5cbiAgICovXG4gIGFzeW5jIGZyb250ZW5kTW9kZWxDcmVhdGVSZWNvcmQoYXR0cmlidXRlcywgbmVzdGVkQXR0cmlidXRlcyA9IG51bGwpIHtcbiAgICBjb25zdCByZXNvdXJjZSA9IHRoaXMuZnJvbnRlbmRNb2RlbFJlc291cmNlSW5zdGFuY2UoKVxuICAgIGNvbnN0IG1vZGVsID0gYXdhaXQgcmVzb3VyY2UuY3JlYXRlKGF0dHJpYnV0ZXMsIHtuZXN0ZWRBdHRyaWJ1dGVzLCBjb250cm9sbGVyOiB0aGlzfSlcblxuICAgIGNvbnN0IGF1dGhvcml6ZWRNb2RlbHMgPSBhd2FpdCB0aGlzLmZyb250ZW5kTW9kZWxGaWx0ZXJBdXRob3JpemVkTW9kZWxzKHthY3Rpb246IFwiY3JlYXRlXCIsIG1vZGVsczogW21vZGVsXX0pXG5cbiAgICBpZiAoYXV0aG9yaXplZE1vZGVscy5sZW5ndGggPiAwKSB7XG4gICAgICByZXR1cm4gYXV0aG9yaXplZE1vZGVsc1swXVxuICAgIH1cblxuICAgIGF3YWl0IHJlc291cmNlLmhhbmRsZVVuYXV0aG9yaXplZENyZWF0ZWRNb2RlbChtb2RlbClcblxuICAgIHJldHVybiBudWxsXG4gIH1cblxuICAvKipcbiAgICogUnVucyBmcm9udGVuZCBtb2RlbCByZWNvcmRzLlxuICAgKiBAcmV0dXJucyB7UHJvbWlzZTxpbXBvcnQoXCIuL2RhdGFiYXNlL3JlY29yZC9pbmRleC5qc1wiKS5kZWZhdWx0W10+fSAtIEZyb250ZW5kIG1vZGVsIHJlY29yZHMuXG4gICAqL1xuICBhc3luYyBmcm9udGVuZE1vZGVsUmVjb3JkcygpIHtcbiAgICBjb25zdCBtb2RlbHMgPSBhd2FpdCB0aGlzLmZyb250ZW5kTW9kZWxSZXNvdXJjZUluc3RhbmNlKCkucmVjb3JkcygpXG5cbiAgICByZXR1cm4gYXdhaXQgdGhpcy5mcm9udGVuZE1vZGVsRmlsdGVyQXV0aG9yaXplZE1vZGVscyh7YWN0aW9uOiBcImluZGV4XCIsIG1vZGVsc30pXG4gIH1cblxuICAvKipcbiAgICogUnVucyBmcm9udGVuZCBtb2RlbCBwcmVsb2FkLlxuICAgKiBAcmV0dXJucyB7aW1wb3J0KFwiLi9kYXRhYmFzZS9xdWVyeS9pbmRleC5qc1wiKS5OZXN0ZWRQcmVsb2FkUmVjb3JkIHwgbnVsbH0gLSBGcm9udGVuZCBwcmVsb2FkIGRhdGEuXG4gICAqL1xuICBmcm9udGVuZE1vZGVsUHJlbG9hZCgpIHtcbiAgICByZXR1cm4gbm9ybWFsaXplRnJvbnRlbmRNb2RlbFByZWxvYWQodGhpcy5mcm9udGVuZE1vZGVsUGFyYW1zKCkucHJlbG9hZClcbiAgfVxuXG4gIC8qKlxuICAgKiBSdW5zIGZyb250ZW5kIG1vZGVsIHNlbGVjdC5cbiAgICogQHJldHVybnMge1JlY29yZDxzdHJpbmcsIHN0cmluZ1tdPiB8IG51bGx9IC0gRnJvbnRlbmQgc2VsZWN0IGRhdGEuXG4gICAqL1xuICBmcm9udGVuZE1vZGVsU2VsZWN0KCkge1xuICAgIHJldHVybiBub3JtYWxpemVGcm9udGVuZE1vZGVsU2VsZWN0KHRoaXMuZnJvbnRlbmRNb2RlbFBhcmFtcygpLnNlbGVjdCwgdGhpcy5mcm9udGVuZE1vZGVsQ2xhc3MoKS5nZXRNb2RlbE5hbWUoKSlcbiAgfVxuXG4gIC8qKlxuICAgKiBSdW5zIGZyb250ZW5kIG1vZGVsIHNlbGVjdHMgZXh0cmEuXG4gICAqIEByZXR1cm5zIHtSZWNvcmQ8c3RyaW5nLCBzdHJpbmdbXT4gfCBudWxsfSAtIEZyb250ZW5kIGV4dHJhLXNlbGVjdCBkYXRhIChkZWZhdWx0cyBwbHVzIHRoZXNlKSwga2V5ZWQgYnkgbW9kZWwgbmFtZS5cbiAgICovXG4gIGZyb250ZW5kTW9kZWxTZWxlY3RzRXh0cmEoKSB7XG4gICAgcmV0dXJuIG5vcm1hbGl6ZUZyb250ZW5kTW9kZWxTZWxlY3QodGhpcy5mcm9udGVuZE1vZGVsUGFyYW1zKCkuc2VsZWN0c0V4dHJhLCB0aGlzLmZyb250ZW5kTW9kZWxDbGFzcygpLmdldE1vZGVsTmFtZSgpKVxuICB9XG5cbiAgLyoqXG4gICAqIFJ1bnMgZnJvbnRlbmQgbW9kZWwgc2VhcmNoZXMuXG4gICAqIEByZXR1cm5zIHtGcm9udGVuZE1vZGVsU2VhcmNoW119IC0gRnJvbnRlbmQgc2VhcmNoIGZpbHRlcnMuXG4gICAqL1xuICBmcm9udGVuZE1vZGVsU2VhcmNoZXMoKSB7XG4gICAgcmV0dXJuIG5vcm1hbGl6ZUZyb250ZW5kTW9kZWxTZWFyY2hlcyh0aGlzLmZyb250ZW5kTW9kZWxQYXJhbXMoKS5zZWFyY2hlcylcbiAgfVxuXG4gIC8qKlxuICAgKiBSdW5zIGZyb250ZW5kIG1vZGVsIHdoZXJlLlxuICAgKiBAcmV0dXJucyB7UmVjb3JkPHN0cmluZywgPz4gfCBudWxsfSAtIEZyb250ZW5kIHdoZXJlIGZpbHRlcnMuXG4gICAqL1xuICBmcm9udGVuZE1vZGVsV2hlcmUoKSB7XG4gICAgcmV0dXJuIG5vcm1hbGl6ZUZyb250ZW5kTW9kZWxXaGVyZSh0aGlzLmZyb250ZW5kTW9kZWxQYXJhbXMoKS53aGVyZSlcbiAgfVxuXG4gIC8qKlxuICAgKiBSdW5zIGZyb250ZW5kIG1vZGVsIHJhbnNhY2suXG4gICAqIEByZXR1cm5zIHtSZWNvcmQ8c3RyaW5nLCA/PiB8IG51bGx9IC0gRnJvbnRlbmQgUmFuc2FjayBmaWx0ZXJzLlxuICAgKi9cbiAgZnJvbnRlbmRNb2RlbFJhbnNhY2soKSB7XG4gICAgcmV0dXJuIG5vcm1hbGl6ZUZyb250ZW5kTW9kZWxSYW5zYWNrKHRoaXMuZnJvbnRlbmRNb2RlbFBhcmFtcygpLnJhbnNhY2spXG4gIH1cblxuICAvKipcbiAgICogUnVucyBmcm9udGVuZCBtb2RlbCBqb2lucy5cbiAgICogQHJldHVybnMge1JlY29yZDxzdHJpbmcsID8+IHwgbnVsbH0gLSBGcm9udGVuZCBqb2lucyBkZXNjcmlwdG9ycy5cbiAgICovXG4gIGZyb250ZW5kTW9kZWxKb2lucygpIHtcbiAgICByZXR1cm4gbm9ybWFsaXplRnJvbnRlbmRNb2RlbEpvaW5zKHRoaXMuZnJvbnRlbmRNb2RlbFBhcmFtcygpLmpvaW5zKVxuICB9XG5cbiAgLyoqXG4gICAqIFJ1bnMgZnJvbnRlbmQgbW9kZWwgc29ydC5cbiAgICogQHJldHVybnMge0Zyb250ZW5kTW9kZWxTb3J0W119IC0gRnJvbnRlbmQgc29ydCBkZWZpbml0aW9ucy5cbiAgICovXG4gIGZyb250ZW5kTW9kZWxTb3J0KCkge1xuICAgIHJldHVybiBub3JtYWxpemVRdWVyeVNvcnQodGhpcy5mcm9udGVuZE1vZGVsUGFyYW1zKCkuc29ydClcbiAgfVxuXG4gIC8qKlxuICAgKiBSdW5zIGZyb250ZW5kIG1vZGVsIGdyb3VwLlxuICAgKiBAcmV0dXJucyB7RnJvbnRlbmRNb2RlbEdyb3VwW119IC0gRnJvbnRlbmQgZ3JvdXAgZGVmaW5pdGlvbnMuXG4gICAqL1xuICBmcm9udGVuZE1vZGVsR3JvdXAoKSB7XG4gICAgdHJ5IHtcbiAgICAgIHJldHVybiBub3JtYWxpemVRdWVyeUdyb3VwKHRoaXMuZnJvbnRlbmRNb2RlbFBhcmFtcygpLmdyb3VwKVxuICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICB0aHJvdyBmcm9udGVuZE1vZGVsVmFsaWRhdGlvbkVycm9yRm9yRXJyb3IoZXJyb3IpXG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIFJ1bnMgZnJvbnRlbmQgbW9kZWwgcGFnaW5hdGlvbi5cbiAgICogQHJldHVybnMge0Zyb250ZW5kTW9kZWxQYWdpbmF0aW9ufSAtIEZyb250ZW5kIHBhZ2luYXRpb24gcGFyYW1zLlxuICAgKi9cbiAgZnJvbnRlbmRNb2RlbFBhZ2luYXRpb24oKSB7XG4gICAgY29uc3QgcGFyYW1zID0gdGhpcy5mcm9udGVuZE1vZGVsUGFyYW1zKClcblxuICAgIHJldHVybiBub3JtYWxpemVGcm9udGVuZE1vZGVsUGFnaW5hdGlvbih7XG4gICAgICBsaW1pdDogcGFyYW1zLmxpbWl0LFxuICAgICAgb2Zmc2V0OiBwYXJhbXMub2Zmc2V0LFxuICAgICAgcGFnZTogcGFyYW1zLnBhZ2UsXG4gICAgICBwZXJQYWdlOiBwYXJhbXMucGVyUGFnZVxuICAgIH0pXG4gIH1cblxuICAvKipcbiAgICogUnVucyBmcm9udGVuZCBtb2RlbCBkaXN0aW5jdC5cbiAgICogQHJldHVybnMge2Jvb2xlYW4gfCBudWxsfSAtIEZyb250ZW5kIGRpc3RpbmN0IGZsYWcgd2hlbiBwcm92aWRlZC5cbiAgICovXG4gIGZyb250ZW5kTW9kZWxEaXN0aW5jdCgpIHtcbiAgICByZXR1cm4gbm9ybWFsaXplRnJvbnRlbmRNb2RlbERpc3RpbmN0KHRoaXMuZnJvbnRlbmRNb2RlbFBhcmFtcygpLmRpc3RpbmN0KVxuICB9XG5cbiAgLyoqXG4gICAqIFJ1bnMgZnJvbnRlbmQgbW9kZWwgcGx1Y2suXG4gICAqIEByZXR1cm5zIHtGcm9udGVuZE1vZGVsUGx1Y2tbXX0gLSBGcm9udGVuZCBwbHVjayBkZWZpbml0aW9ucy5cbiAgICovXG4gIGZyb250ZW5kTW9kZWxQbHVjaygpIHtcbiAgICB0cnkge1xuICAgICAgcmV0dXJuIG5vcm1hbGl6ZVF1ZXJ5UGx1Y2sodGhpcy5mcm9udGVuZE1vZGVsUGFyYW1zKCkucGx1Y2spXG4gICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgIHRocm93IGZyb250ZW5kTW9kZWxWYWxpZGF0aW9uRXJyb3JGb3JFcnJvcihlcnJvcilcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogUnVucyBmcm9udGVuZCBtb2RlbCBjb3VudCByZXF1ZXN0ZWQuXG4gICAqIEByZXR1cm5zIHtib29sZWFufSAtIFdoZXRoZXIgdGhlIHJlcXVlc3QgYXNrcyBmb3IgYW4gYWdncmVnYXRlIGNvdW50LlxuICAgKi9cbiAgZnJvbnRlbmRNb2RlbENvdW50UmVxdWVzdGVkKCkge1xuICAgIHJldHVybiB0aGlzLmZyb250ZW5kTW9kZWxQYXJhbXMoKS5jb3VudCA9PT0gdHJ1ZVxuICB9XG5cbiAgLyoqXG4gICAqIFJ1bnMgZnJvbnRlbmQgbW9kZWwgd2l0aCBjb3VudC5cbiAgICogQHJldHVybnMge0FycmF5PHthdHRyaWJ1dGVOYW1lOiBzdHJpbmcsIHJlbGF0aW9uc2hpcE5hbWU6IHN0cmluZywgd2hlcmU/OiBSZWNvcmQ8c3RyaW5nLCA/Pn0+fVxuICAgKiAgIEZyb250ZW5kIHdpdGhDb3VudCBlbnRyaWVzLiBFbXB0eSBhcnJheSB3aGVuIG5vdCByZXF1ZXN0ZWQuXG4gICAqL1xuICBmcm9udGVuZE1vZGVsV2l0aENvdW50KCkge1xuICAgIGNvbnN0IHJhdyA9IHRoaXMuZnJvbnRlbmRNb2RlbFBhcmFtcygpLndpdGhDb3VudFxuXG4gICAgaWYgKCFBcnJheS5pc0FycmF5KHJhdykpIHJldHVybiBbXVxuXG4gICAgLyoqXG4gICAgICogRW50cmllcy5cbiAgICAgIEB0eXBlIHtBcnJheTx7YXR0cmlidXRlTmFtZTogc3RyaW5nLCByZWxhdGlvbnNoaXBOYW1lOiBzdHJpbmcsIHdoZXJlPzogUmVjb3JkPHN0cmluZywgPz59Pn0gKi9cbiAgICBjb25zdCBlbnRyaWVzID0gW11cblxuICAgIGZvciAoY29uc3QgZW50cnkgb2YgcmF3KSB7XG4gICAgICBpZiAoIWVudHJ5IHx8IHR5cGVvZiBlbnRyeSAhPT0gXCJvYmplY3RcIikgY29udGludWVcbiAgICAgIGlmICh0eXBlb2YgZW50cnkuYXR0cmlidXRlTmFtZSAhPT0gXCJzdHJpbmdcIiB8fCBlbnRyeS5hdHRyaWJ1dGVOYW1lLmxlbmd0aCA9PT0gMCkgY29udGludWVcbiAgICAgIGlmICh0eXBlb2YgZW50cnkucmVsYXRpb25zaGlwTmFtZSAhPT0gXCJzdHJpbmdcIiB8fCBlbnRyeS5yZWxhdGlvbnNoaXBOYW1lLmxlbmd0aCA9PT0gMCkgY29udGludWVcblxuICAgICAgZW50cmllcy5wdXNoKHtcbiAgICAgICAgYXR0cmlidXRlTmFtZTogZW50cnkuYXR0cmlidXRlTmFtZSxcbiAgICAgICAgcmVsYXRpb25zaGlwTmFtZTogZW50cnkucmVsYXRpb25zaGlwTmFtZSxcbiAgICAgICAgd2hlcmU6IGVudHJ5LndoZXJlICYmIHR5cGVvZiBlbnRyeS53aGVyZSA9PT0gXCJvYmplY3RcIiA/IGVudHJ5LndoZXJlIDogdW5kZWZpbmVkXG4gICAgICB9KVxuICAgIH1cblxuICAgIHJldHVybiBlbnRyaWVzXG4gIH1cblxuICAvKipcbiAgICogUmVzb2x2ZSBhbiBlbnRyeSBmcm9tIHRoZSBmcm9udGVuZC1tb2RlbCBgYWJpbGl0aWVzYCBwYXlsb2FkIHRvXG4gICAqIGl0cyBiYWNrZW5kIG1vZGVsIGNsYXNzIGJ5IGxvb2tpbmcgdXAgdGhlIHJlc291cmNlIGJ5IG1vZGVsTmFtZVxuICAgKiBhY3Jvc3MgYWxsIGNvbmZpZ3VyZWQgYmFja2VuZCBwcm9qZWN0cy4gUmV0dXJucyBudWxsIHdoZW4gbm9cbiAgICogcmVzb3VyY2UgbWF0Y2hlcyDigJQgdGhlIHNwZWMgZW50cnkgaXMgdGhlbiBzaWxlbnRseSBpZ25vcmVkIHNvIGFcbiAgICogY2FsbGVyIHJlcXVlc3RpbmcgYWJpbGl0aWVzIGZvciBhIG1vZGVsIHRoZXkgY2Fubm90IHJlc29sdmUgZG9lc1xuICAgKiBub3QgY3Jhc2ggdGhlIHJlcXVlc3QuXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBtb2RlbE5hbWVcbiAgICogQHJldHVybnMge3R5cGVvZiBpbXBvcnQoXCIuL2RhdGFiYXNlL3JlY29yZC9pbmRleC5qc1wiKS5kZWZhdWx0IHwgbnVsbH1cbiAgICovXG4gIF9mcm9udGVuZE1vZGVsQ2xhc3NGb3JBYmlsaXRpZXMobW9kZWxOYW1lKSB7XG4gICAgaWYgKHR5cGVvZiBtb2RlbE5hbWUgIT09IFwic3RyaW5nXCIgfHwgbW9kZWxOYW1lLmxlbmd0aCA9PT0gMCkgcmV0dXJuIG51bGxcblxuICAgIGNvbnN0IGNvbmZpZ3VyYXRpb24gPSB0aGlzLmdldENvbmZpZ3VyYXRpb24oKVxuICAgIGNvbnN0IGJhY2tlbmRQcm9qZWN0cyA9IGNvbmZpZ3VyYXRpb24/LmdldEJhY2tlbmRQcm9qZWN0cz8uKCkgPz8gW11cblxuICAgIGZvciAoY29uc3QgYmFja2VuZFByb2plY3Qgb2YgYmFja2VuZFByb2plY3RzKSB7XG4gICAgICBjb25zdCBmcm9udGVuZE1vZGVscyA9IGJhY2tlbmRQcm9qZWN0Py5mcm9udGVuZE1vZGVsc1xuICAgICAgaWYgKCFmcm9udGVuZE1vZGVscyB8fCB0eXBlb2YgZnJvbnRlbmRNb2RlbHMgIT09IFwib2JqZWN0XCIpIGNvbnRpbnVlXG5cbiAgICAgIGNvbnN0IHJlc291cmNlRGVmaW5pdGlvbiA9IGZyb250ZW5kTW9kZWxzW21vZGVsTmFtZV1cbiAgICAgIGlmICghcmVzb3VyY2VEZWZpbml0aW9uKSBjb250aW51ZVxuXG4gICAgICBjb25zdCByZXNvdXJjZUNsYXNzID0gZnJvbnRlbmRNb2RlbFJlc291cmNlQ2xhc3NGcm9tRGVmaW5pdGlvbihyZXNvdXJjZURlZmluaXRpb24pXG4gICAgICBpZiAoIXJlc291cmNlQ2xhc3MpIGNvbnRpbnVlXG5cbiAgICAgIGNvbnN0IG1vZGVsQ2xhc3MgPSB0eXBlb2YgcmVzb3VyY2VDbGFzcy5tb2RlbENsYXNzID09PSBcImZ1bmN0aW9uXCJcbiAgICAgICAgPyByZXNvdXJjZUNsYXNzLm1vZGVsQ2xhc3MoKVxuICAgICAgICA6IHJlc291cmNlQ2xhc3MuTW9kZWxDbGFzc1xuXG4gICAgICBpZiAodHlwZW9mIG1vZGVsQ2xhc3MgPT09IFwiZnVuY3Rpb25cIikgcmV0dXJuIG1vZGVsQ2xhc3NcbiAgICB9XG5cbiAgICByZXR1cm4gbnVsbFxuICB9XG5cbiAgLyoqXG4gICAqIENvbGxlY3QgZXZlcnkgbG9hZGVkIHJlY29yZCB3aG9zZSBgZ2V0TW9kZWxOYW1lKClgIG1hdGNoZXMgdGhlXG4gICAqIHJlcXVlc3RlZCBuYW1lLCB3YWxraW5nIGFjcm9zcyB0aGUgcm9vdC1sZXZlbCBzbGljZSBwbHVzIGFueVxuICAgKiBwcmVsb2FkZWQgcmVsYXRpb25zaGlwcyBhdCBhbnkgZGVwdGguIFVzZWQgdG8gZXZhbHVhdGUgcGVyLXJlY29yZFxuICAgKiBhYmlsaXRpZXMgYWdhaW5zdCBuZXN0ZWQgcHJlbG9hZGVkIGNoaWxkcmVuIHdpdGggYSBzaW5nbGUgYmF0Y2hlZFxuICAgKiBxdWVyeSBwZXIgKG1vZGVsQ2xhc3MsIGFjdGlvbikgcGFpci5cbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuL2RhdGFiYXNlL3JlY29yZC9pbmRleC5qc1wiKS5kZWZhdWx0W119IHJvb3RNb2RlbHNcbiAgICogQHBhcmFtIHtzdHJpbmd9IG1vZGVsTmFtZVxuICAgKiBAcmV0dXJucyB7aW1wb3J0KFwiLi9kYXRhYmFzZS9yZWNvcmQvaW5kZXguanNcIikuZGVmYXVsdFtdfVxuICAgKi9cbiAgX2Zyb250ZW5kTW9kZWxDb2xsZWN0UmVjb3Jkc0Zvck5hbWUocm9vdE1vZGVscywgbW9kZWxOYW1lKSB7XG4gICAgLyoqXG4gICAgICogT3V0LlxuICAgICAgQHR5cGUge2ltcG9ydChcIi4vZGF0YWJhc2UvcmVjb3JkL2luZGV4LmpzXCIpLmRlZmF1bHRbXX0gKi9cbiAgICBjb25zdCBvdXQgPSBbXVxuICAgIC8qKlxuICAgICAqIFNlZW4uXG4gICAgICBAdHlwZSB7U2V0PGltcG9ydChcIi4vZGF0YWJhc2UvcmVjb3JkL2luZGV4LmpzXCIpLmRlZmF1bHQ+fSAqL1xuICAgIGNvbnN0IHNlZW4gPSBuZXcgU2V0KClcblxuICAgIC8qKlxuICAgICAqIFdhbGsuXG4gICAgICBAcGFyYW0ge2ltcG9ydChcIi4vZGF0YWJhc2UvcmVjb3JkL2luZGV4LmpzXCIpLmRlZmF1bHQgfCBudWxsIHwgdW5kZWZpbmVkfSByZWNvcmQgKi9cbiAgICBjb25zdCB3YWxrID0gKHJlY29yZCkgPT4ge1xuICAgICAgaWYgKCFyZWNvcmQgfHwgdHlwZW9mIHJlY29yZCAhPT0gXCJvYmplY3RcIikgcmV0dXJuXG4gICAgICBpZiAoc2Vlbi5oYXMocmVjb3JkKSkgcmV0dXJuXG4gICAgICBzZWVuLmFkZChyZWNvcmQpXG5cbiAgICAgIGNvbnN0IE1vZGVsQ2xhc3MgPSB0eXBlb2YgcmVjb3JkLmdldE1vZGVsQ2xhc3MgPT09IFwiZnVuY3Rpb25cIlxuICAgICAgICA/IHJlY29yZC5nZXRNb2RlbENsYXNzKClcbiAgICAgICAgOiBudWxsXG4gICAgICBpZiAoTW9kZWxDbGFzcyAmJiB0eXBlb2YgTW9kZWxDbGFzcy5nZXRNb2RlbE5hbWUgPT09IFwiZnVuY3Rpb25cIiAmJiBNb2RlbENsYXNzLmdldE1vZGVsTmFtZSgpID09PSBtb2RlbE5hbWUpIHtcbiAgICAgICAgb3V0LnB1c2gocmVjb3JkKVxuICAgICAgfVxuXG4gICAgICBjb25zdCByZWxhdGlvbnNoaXBzTWFwID0gdHlwZW9mIE1vZGVsQ2xhc3M/LmdldFJlbGF0aW9uc2hpcHNNYXAgPT09IFwiZnVuY3Rpb25cIlxuICAgICAgICA/IE1vZGVsQ2xhc3MuZ2V0UmVsYXRpb25zaGlwc01hcCgpXG4gICAgICAgIDogbnVsbFxuICAgICAgaWYgKCFyZWxhdGlvbnNoaXBzTWFwKSByZXR1cm5cblxuICAgICAgZm9yIChjb25zdCByZWxhdGlvbnNoaXBOYW1lIG9mIE9iamVjdC5rZXlzKHJlbGF0aW9uc2hpcHNNYXApKSB7XG4gICAgICAgIGNvbnN0IHJlbGF0aW9uc2hpcCA9IHR5cGVvZiByZWNvcmQuZ2V0UmVsYXRpb25zaGlwQnlOYW1lID09PSBcImZ1bmN0aW9uXCJcbiAgICAgICAgICA/IHJlY29yZC5nZXRSZWxhdGlvbnNoaXBCeU5hbWUocmVsYXRpb25zaGlwTmFtZSlcbiAgICAgICAgICA6IG51bGxcbiAgICAgICAgaWYgKCFyZWxhdGlvbnNoaXAgfHwgdHlwZW9mIHJlbGF0aW9uc2hpcC5nZXRMb2FkZWRPclVuZGVmaW5lZCAhPT0gXCJmdW5jdGlvblwiKSBjb250aW51ZVxuXG4gICAgICAgIGNvbnN0IGxvYWRlZCA9IHJlbGF0aW9uc2hpcC5nZXRMb2FkZWRPclVuZGVmaW5lZCgpXG4gICAgICAgIGlmIChsb2FkZWQgPT09IHVuZGVmaW5lZCkgY29udGludWVcblxuICAgICAgICBpZiAoQXJyYXkuaXNBcnJheShsb2FkZWQpKSB7XG4gICAgICAgICAgZm9yIChjb25zdCBjaGlsZCBvZiBsb2FkZWQpIHdhbGsoY2hpbGQpXG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgd2Fsayhsb2FkZWQpXG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG5cbiAgICBmb3IgKGNvbnN0IHJvb3Qgb2Ygcm9vdE1vZGVscykgd2Fsayhyb290KVxuXG4gICAgcmV0dXJuIG91dFxuICB9XG5cbiAgLyoqXG4gICAqIEV2YWx1YXRlIGV2ZXJ5IGFiaWxpdHkgcmVxdWVzdGVkIHZpYSB0aGUgZnJvbnRlbmQgYGFiaWxpdGllc2BcbiAgICogcGFyYW0gYWdhaW5zdCB0aGUgbG9hZGVkIG1vZGVsIGNvaG9ydCAocGx1cyBhbnkgcHJlbG9hZGVkXG4gICAqIGNoaWxkcmVuKSwgYXR0YWNoaW5nIHRoZSByZXN1bHRzIHRvIGVhY2ggcmVjb3JkIHZpYVxuICAgKiBgX3NldENvbXB1dGVkQWJpbGl0eWAuIFJ1bnMgb25lIGJhdGNoZWQgYGF1dGhvcml6ZWQgcXVlcnkgKyBwbHVja2BcbiAgICogcGVyIChtb2RlbENsYXNzLCBhY3Rpb24pIHBhaXIsIHJlZ2FyZGxlc3Mgb2YgaG93IG1hbnkgcmVjb3Jkc1xuICAgKiB3ZXJlIGxvYWRlZC5cbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuL2RhdGFiYXNlL3JlY29yZC9pbmRleC5qc1wiKS5kZWZhdWx0W119IHJvb3RNb2RlbHNcbiAgICogQHJldHVybnMge1Byb21pc2U8dm9pZD59XG4gICAqL1xuICBhc3luYyBmcm9udGVuZE1vZGVsQ29tcHV0ZUFiaWxpdGllcyhyb290TW9kZWxzKSB7XG4gICAgY29uc3QgZW50cmllcyA9IHRoaXMuZnJvbnRlbmRNb2RlbEFiaWxpdGllcygpXG4gICAgaWYgKGVudHJpZXMubGVuZ3RoID09PSAwKSByZXR1cm5cbiAgICBpZiAoIUFycmF5LmlzQXJyYXkocm9vdE1vZGVscykgfHwgcm9vdE1vZGVscy5sZW5ndGggPT09IDApIHJldHVyblxuXG4gICAgY29uc3QgYWJpbGl0eSA9IHRoaXMuY3VycmVudEFiaWxpdHkoKVxuICAgIGlmICghYWJpbGl0eSkgcmV0dXJuXG5cbiAgICBmb3IgKGNvbnN0IGVudHJ5IG9mIGVudHJpZXMpIHtcbiAgICAgIGNvbnN0IG1vZGVsQ2xhc3MgPSB0aGlzLl9mcm9udGVuZE1vZGVsQ2xhc3NGb3JBYmlsaXRpZXMoZW50cnkubW9kZWxOYW1lKVxuICAgICAgaWYgKCFtb2RlbENsYXNzKSBjb250aW51ZVxuXG4gICAgICBjb25zdCBjYW5kaWRhdGVzID0gdGhpcy5fZnJvbnRlbmRNb2RlbENvbGxlY3RSZWNvcmRzRm9yTmFtZShyb290TW9kZWxzLCBlbnRyeS5tb2RlbE5hbWUpXG4gICAgICBpZiAoY2FuZGlkYXRlcy5sZW5ndGggPT09IDApIGNvbnRpbnVlXG5cbiAgICAgIGNvbnN0IHByaW1hcnlLZXkgPSBtb2RlbENsYXNzLnByaW1hcnlLZXkoKVxuICAgICAgY29uc3QgaWRzID0gY2FuZGlkYXRlc1xuICAgICAgICAubWFwKChyZWNvcmQpID0+IHJlY29yZC5yZWFkQXR0cmlidXRlKHByaW1hcnlLZXkpKVxuICAgICAgICAuZmlsdGVyKCh2YWx1ZSkgPT4gdmFsdWUgIT09IG51bGwgJiYgdmFsdWUgIT09IHVuZGVmaW5lZClcbiAgICAgIGlmIChpZHMubGVuZ3RoID09PSAwKSBjb250aW51ZVxuXG4gICAgICBmb3IgKGNvbnN0IGFjdGlvbiBvZiBlbnRyeS5hY3Rpb25zKSB7XG4gICAgICAgIGxldCBhbGxvd2VkSWRzXG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgY29uc3QgYXV0aG9yaXplZFF1ZXJ5ID0gbW9kZWxDbGFzcy5hY2Nlc3NpYmxlRm9yKGFjdGlvbiwgYWJpbGl0eSkud2hlcmUoe1twcmltYXJ5S2V5XTogaWRzfSlcbiAgICAgICAgICBjb25zdCBwbHVja2VkID0gYXdhaXQgYXV0aG9yaXplZFF1ZXJ5LnBsdWNrKHByaW1hcnlLZXkpXG4gICAgICAgICAgYWxsb3dlZElkcyA9IG5ldyBTZXQocGx1Y2tlZC5tYXAoKHZhbHVlKSA9PiBTdHJpbmcodmFsdWUpKSlcbiAgICAgICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgICAgICAvLyBBbiBhYmlsaXR5IHdpdGggbm8gYWxsb3cgcnVsZXMgZm9yIHRoZSBhY3Rpb24gdGhyb3dzIHZpYVxuICAgICAgICAgIC8vIGBhY2Nlc3NpYmxlRm9yYDsgdHJlYXQgYXMgYSB1bml2ZXJzYWwgZGVueSBzbyB0aGUgZnJvbnRlbmRcbiAgICAgICAgICAvLyBnZXRzIGBjYW4oYWN0aW9uKSA9PT0gZmFsc2VgIGZvciBldmVyeSBjYW5kaWRhdGUsIGluc3RlYWRcbiAgICAgICAgICAvLyBvZiBzdXJmYWNpbmcgYW4gZXJyb3IgdGhhdCB0aGUgVUkgY2FuJ3QgYWN0IG9uLlxuICAgICAgICAgIHZvaWQgZXJyb3JcbiAgICAgICAgICBhbGxvd2VkSWRzID0gbmV3IFNldCgpXG4gICAgICAgIH1cblxuICAgICAgICBmb3IgKGNvbnN0IHJlY29yZCBvZiBjYW5kaWRhdGVzKSB7XG4gICAgICAgICAgY29uc3QgaWRWYWx1ZSA9IHJlY29yZC5yZWFkQXR0cmlidXRlKHByaW1hcnlLZXkpXG4gICAgICAgICAgY29uc3QgYWxsb3dlZCA9IGlkVmFsdWUgIT09IG51bGwgJiYgaWRWYWx1ZSAhPT0gdW5kZWZpbmVkICYmIGFsbG93ZWRJZHMuaGFzKFN0cmluZyhpZFZhbHVlKSlcbiAgICAgICAgICByZWNvcmQuX3NldENvbXB1dGVkQWJpbGl0eShhY3Rpb24sIGFsbG93ZWQpXG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogUGFyc2UgdGhlIGZyb250ZW5kLW1vZGVsIGBhYmlsaXRpZXNgIHBhcmFtIGludG8gYSBsaXN0IG9mXG4gICAqIGB7bW9kZWxOYW1lLCBhY3Rpb25zfWAgZW50cmllcyB0byBldmFsdWF0ZSBhZ2FpbnN0IGxvYWRlZCByZWNvcmRzLlxuICAgKiBVbmtub3duIGVudHJpZXMgYXJlIHNpbGVudGx5IHNraXBwZWQg4oCUIGRvd25zdHJlYW0gY29kZSByZXNvbHZlc1xuICAgKiBtb2RlbCBuYW1lcyB0byBjbGFzc2VzIHdoZW4gYXBwbHlpbmcgdGhlIGNoZWNrLCBzbyB1bnJlc29sdmVkXG4gICAqIG5hbWVzIG5hdHVyYWxseSBiZWNvbWUgbm8tb3BzLlxuICAgKiBAcmV0dXJucyB7QXJyYXk8e21vZGVsTmFtZTogc3RyaW5nLCBhY3Rpb25zOiBzdHJpbmdbXX0+fVxuICAgKi9cbiAgZnJvbnRlbmRNb2RlbEFiaWxpdGllcygpIHtcbiAgICBjb25zdCByYXcgPSB0aGlzLmZyb250ZW5kTW9kZWxQYXJhbXMoKS5hYmlsaXRpZXNcblxuICAgIGlmICghQXJyYXkuaXNBcnJheShyYXcpKSByZXR1cm4gW11cblxuICAgIC8qKlxuICAgICAqIEVudHJpZXMuXG4gICAgICBAdHlwZSB7QXJyYXk8e21vZGVsTmFtZTogc3RyaW5nLCBhY3Rpb25zOiBzdHJpbmdbXX0+fSAqL1xuICAgIGNvbnN0IGVudHJpZXMgPSBbXVxuXG4gICAgZm9yIChjb25zdCBlbnRyeSBvZiByYXcpIHtcbiAgICAgIGlmICghZW50cnkgfHwgdHlwZW9mIGVudHJ5ICE9PSBcIm9iamVjdFwiKSBjb250aW51ZVxuICAgICAgaWYgKHR5cGVvZiBlbnRyeS5tb2RlbE5hbWUgIT09IFwic3RyaW5nXCIgfHwgZW50cnkubW9kZWxOYW1lLmxlbmd0aCA9PT0gMCkgY29udGludWVcbiAgICAgIGlmICghQXJyYXkuaXNBcnJheShlbnRyeS5hY3Rpb25zKSkgY29udGludWVcblxuICAgICAgY29uc3QgYWN0aW9ucyA9IGVudHJ5LmFjdGlvbnMuZmlsdGVyKFxuICAgICAgICAoLyoqXG4gICAgICAgICAgKiBUeXBlcyB0aGUgZm9sbG93aW5nIHZhbHVlLlxuICAgICAgICAgICBAdHlwZSB7P30gKi8gYWN0aW9uKSA9PiB0eXBlb2YgYWN0aW9uID09PSBcInN0cmluZ1wiICYmIGFjdGlvbi5sZW5ndGggPiAwXG4gICAgICApXG5cbiAgICAgIGlmIChhY3Rpb25zLmxlbmd0aCA9PT0gMCkgY29udGludWVcblxuICAgICAgZW50cmllcy5wdXNoKHthY3Rpb25zLCBtb2RlbE5hbWU6IGVudHJ5Lm1vZGVsTmFtZX0pXG4gICAgfVxuXG4gICAgcmV0dXJuIGVudHJpZXNcbiAgfVxuXG4gIC8qKlxuICAgKiBSZWFkIHRoZSBmcm9udGVuZC1tb2RlbCBgcXVlcnlEYXRhYCBwYXJhbS4gVGhlIHdpcmUgZm9ybWF0IGNhcnJpZXNcbiAgICogb25seSAqKm5hbWVzKiogKHRoZSBrZXlzIHRoZSBmcm9udGVuZCB3YW50cyBhdHRhY2hlZCkgcGx1cyB0aGVcbiAgICogb3B0aW9uYWwgbmVzdGVkLXJlbGF0aW9uc2hpcCBjaGFpbiBsZWFkaW5nIHRvIHRoZW0g4oCUIHRoZSBhY3R1YWwgU1FMXG4gICAqIGZyYWdtZW50cyBsaXZlIG9uIHRoZSBiYWNrZW5kIG1vZGVsIGFzIGBNb2RlbC5xdWVyeURhdGEobmFtZSwgZm4pYFxuICAgKiByZWdpc3RyYXRpb25zLiBDYWxsZXJzIGNhbm5vdCBwdXNoIFNRTCB0aHJvdWdoIHRoaXMgZW5kcG9pbnQuXG4gICAqXG4gICAqIFJldHVybnMgdGhlIHJhdyBuZXN0ZWQtcmVjb3JkIHNwZWMgKHNoYXBlIHZhbGlkYXRlZCBieSB0aGVcbiAgICogbm9ybWFsaXplciBpbnNpZGUgYFF1ZXJ5LnF1ZXJ5RGF0YWApIG9yIGBudWxsYCB3aGVuIG5vdCByZXF1ZXN0ZWQuXG4gICAqIEByZXR1cm5zIHtpbXBvcnQoXCIuL2RhdGFiYXNlL3F1ZXJ5L3F1ZXJ5LWRhdGEuanNcIikuUXVlcnlEYXRhU3BlYyB8IG51bGx9XG4gICAqL1xuICBmcm9udGVuZE1vZGVsUXVlcnlEYXRhKCkge1xuICAgIGNvbnN0IHJhdyA9IHRoaXMuZnJvbnRlbmRNb2RlbFBhcmFtcygpLnF1ZXJ5RGF0YVxuXG4gICAgaWYgKHJhdyA9PSBudWxsKSByZXR1cm4gbnVsbFxuXG4gICAgaWYgKHR5cGVvZiByYXcgPT09IFwic3RyaW5nXCIpIHJldHVybiByYXdcbiAgICBpZiAoQXJyYXkuaXNBcnJheShyYXcpKSByZXR1cm4gcmF3XG4gICAgaWYgKHR5cGVvZiByYXcgPT09IFwib2JqZWN0XCIpIHJldHVybiByYXdcblxuICAgIHJldHVybiBudWxsXG4gIH1cblxuICAvKipcbiAgICogUnVucyBmcm9udGVuZCBtb2RlbCBpbmRleCBxdWVyeS5cbiAgICogQHJldHVybnMge2ltcG9ydChcIi4vZGF0YWJhc2UvcXVlcnkvbW9kZWwtY2xhc3MtcXVlcnkuanNcIikuZGVmYXVsdH0gLSBGcm9udGVuZCBpbmRleCBxdWVyeSB3aXRoIG5vcm1hbGl6ZWQgcGFyYW1zIGFwcGxpZWQuXG4gICAqL1xuICBmcm9udGVuZE1vZGVsSW5kZXhRdWVyeSgpIHtcbiAgICBsZXQgcXVlcnkgPSB0aGlzLmZyb250ZW5kTW9kZWxBdXRob3JpemVkUXVlcnkoXCJpbmRleFwiKVxuICAgIGNvbnN0IHByZWxvYWQgPSB0aGlzLmZyb250ZW5kTW9kZWxQcmVsb2FkKClcblxuICAgIGlmIChwcmVsb2FkKSB7XG4gICAgICBxdWVyeSA9IHF1ZXJ5LnByZWxvYWQocHJlbG9hZClcbiAgICB9XG5cbiAgICBjb25zdCBqb2lucyA9IHRoaXMuZnJvbnRlbmRNb2RlbEpvaW5zKClcbiAgICBjb25zdCB3aGVyZSA9IHRoaXMuZnJvbnRlbmRNb2RlbFdoZXJlKClcbiAgICBjb25zdCBwYWdpbmF0aW9uID0gdGhpcy5mcm9udGVuZE1vZGVsUGFnaW5hdGlvbigpXG4gICAgY29uc3QgZGlzdGluY3QgPSB0aGlzLmZyb250ZW5kTW9kZWxEaXN0aW5jdCgpXG5cbiAgICB0aGlzLmFwcGx5RnJvbnRlbmRNb2RlbFBhZ2luYXRpb24oe3BhZ2luYXRpb24sIHF1ZXJ5fSlcblxuICAgIGlmIChkaXN0aW5jdCAhPT0gbnVsbCkge1xuICAgICAgcXVlcnkuZGlzdGluY3QoZGlzdGluY3QpXG4gICAgfVxuXG4gICAgaWYgKHdoZXJlKSB7XG4gICAgICB0aGlzLmFwcGx5RnJvbnRlbmRNb2RlbFdoZXJlKHtxdWVyeSwgd2hlcmV9KVxuICAgIH1cblxuICAgIGNvbnN0IHJhbnNhY2sgPSB0aGlzLmZyb250ZW5kTW9kZWxSYW5zYWNrKClcblxuICAgIGlmIChyYW5zYWNrKSB7XG4gICAgICBxdWVyeS5yYW5zYWNrKHJhbnNhY2spXG4gICAgfVxuXG4gICAgaWYgKGpvaW5zKSB7XG4gICAgICB0aGlzLmFwcGx5RnJvbnRlbmRNb2RlbEpvaW5zKHtqb2lucywgcXVlcnl9KVxuICAgIH1cblxuICAgIGNvbnN0IHNlYXJjaGVzID0gdGhpcy5mcm9udGVuZE1vZGVsU2VhcmNoZXMoKVxuXG4gICAgZm9yIChjb25zdCBzZWFyY2ggb2Ygc2VhcmNoZXMpIHtcbiAgICAgIHRoaXMuYXBwbHlGcm9udGVuZE1vZGVsU2VhcmNoKHtxdWVyeSwgc2VhcmNofSlcbiAgICB9XG5cbiAgICBjb25zdCBncm91cHMgPSB0aGlzLmZyb250ZW5kTW9kZWxHcm91cCgpXG5cbiAgICBpZiAoZ3JvdXBzLmxlbmd0aCA+IDApIHtcbiAgICAgIHRoaXMuYXBwbHlGcm9udGVuZE1vZGVsUm9vdEdyb3VwQ29sdW1ucyh7cXVlcnl9KVxuICAgIH1cblxuICAgIGZvciAoY29uc3QgZ3JvdXAgb2YgZ3JvdXBzKSB7XG4gICAgICB0aGlzLmFwcGx5RnJvbnRlbmRNb2RlbEdyb3VwKHtncm91cCwgcXVlcnl9KVxuICAgIH1cblxuICAgIGNvbnN0IHNvcnRzID0gdGhpcy5mcm9udGVuZE1vZGVsU29ydCgpXG5cbiAgICBpZiAoc29ydHMubGVuZ3RoID4gMCkge1xuICAgICAgZm9yIChjb25zdCBzb3J0IG9mIHNvcnRzKSB7XG4gICAgICAgIHRoaXMuYXBwbHlGcm9udGVuZE1vZGVsU29ydCh7cXVlcnksIHNvcnR9KVxuICAgICAgfVxuICAgIH1cblxuICAgIGNvbnN0IHdpdGhDb3VudCA9IHRoaXMuZnJvbnRlbmRNb2RlbFdpdGhDb3VudCgpXG5cbiAgICBmb3IgKGNvbnN0IGVudHJ5IG9mIHdpdGhDb3VudCkge1xuICAgICAgLyoqXG4gICAgICAgKiBTcGVjLlxuICAgICAgICBAdHlwZSB7UmVjb3JkPHN0cmluZywgYm9vbGVhbiB8IHtyZWxhdGlvbnNoaXA/OiBzdHJpbmcsIHdoZXJlPzogUmVjb3JkPHN0cmluZywgPz59Pn0gKi9cbiAgICAgIGNvbnN0IHNwZWMgPSB7fVxuICAgICAgc3BlY1tlbnRyeS5hdHRyaWJ1dGVOYW1lXSA9IHtyZWxhdGlvbnNoaXA6IGVudHJ5LnJlbGF0aW9uc2hpcE5hbWUsIHdoZXJlOiBlbnRyeS53aGVyZX1cbiAgICAgIHF1ZXJ5LndpdGhDb3VudChzcGVjKVxuICAgIH1cblxuICAgIGNvbnN0IHF1ZXJ5RGF0YSA9IHRoaXMuZnJvbnRlbmRNb2RlbFF1ZXJ5RGF0YSgpXG5cbiAgICBpZiAocXVlcnlEYXRhICE9IG51bGwpIHtcbiAgICAgIHF1ZXJ5LnF1ZXJ5RGF0YShxdWVyeURhdGEpXG4gICAgfVxuXG4gICAgcXVlcnkgPSB0aGlzLmFwcGx5RnJvbnRlbmRNb2RlbFRyYW5zbGF0ZWRBdHRyaWJ1dGVQcmVsb2Fkcyh7cXVlcnl9KVxuXG4gICAgaWYgKHF1ZXJ5Ll9kaXN0aW5jdCAmJiBxdWVyeS5kcml2ZXIuZ2V0VHlwZSgpID09PSBcIm1zc3FsXCIpIHtcbiAgICAgIHJldHVybiB0aGlzLmZyb250ZW5kTW9kZWxNc3NxbERpc3RpbmN0QnlQcmltYXJ5S2V5UXVlcnkoe3F1ZXJ5fSlcbiAgICB9XG5cbiAgICByZXR1cm4gcXVlcnlcbiAgfVxuXG4gIC8qKlxuICAgKiBNU1NRTCBjYW5ub3QgYXBwbHkgRElTVElOQ1Qgb3ZlciBub24tY29tcGFyYWJsZSB0ZXh0IGNvbHVtbnMgaW4gdGFibGUuKiBzZWxlY3RzLlxuICAgKiBUaGlzIHJld3JpdGVzIGRpc3RpbmN0IGZyb250ZW5kLW1vZGVsIHF1ZXJpZXMgdG8gc2VsZWN0IHJvb3QgcmVjb3JkcyBieSBkaXN0aW5jdCBQSyBzdWJxdWVyeS5cbiAgICogQHBhcmFtIHtvYmplY3R9IGFyZ3MgLSBBcmdzLlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4vZGF0YWJhc2UvcXVlcnkvbW9kZWwtY2xhc3MtcXVlcnkuanNcIikuZGVmYXVsdH0gYXJncy5xdWVyeSAtIFF1ZXJ5IHdpdGggZGlzdGluY3QgYW5kIGZpbHRlcnMuXG4gICAqIEByZXR1cm5zIHtpbXBvcnQoXCIuL2RhdGFiYXNlL3F1ZXJ5L21vZGVsLWNsYXNzLXF1ZXJ5LmpzXCIpLmRlZmF1bHR9IC0gTVNTUUwtc2FmZSBkaXN0aW5jdCBxdWVyeS5cbiAgICovXG4gIGZyb250ZW5kTW9kZWxNc3NxbERpc3RpbmN0QnlQcmltYXJ5S2V5UXVlcnkoe3F1ZXJ5fSkge1xuICAgIGNvbnN0IG1vZGVsQ2xhc3MgPSB0aGlzLmZyb250ZW5kTW9kZWxDbGFzcygpXG4gICAgY29uc3QgcHJpbWFyeUtleSA9IG1vZGVsQ2xhc3MucHJpbWFyeUtleSgpXG4gICAgY29uc3Qgcm9vdFRhYmxlU3FsID0gcXVlcnkuZHJpdmVyLnF1b3RlVGFibGUobW9kZWxDbGFzcy50YWJsZU5hbWUoKSlcbiAgICBjb25zdCBwcmltYXJ5S2V5U3FsID0gYCR7cm9vdFRhYmxlU3FsfS4ke3F1ZXJ5LmRyaXZlci5xdW90ZUNvbHVtbihwcmltYXJ5S2V5KX1gXG4gICAgY29uc3QgZGlzdGluY3RJZHNRdWVyeSA9IHF1ZXJ5LmNsb25lKClcblxuICAgIGRpc3RpbmN0SWRzUXVlcnkuX3ByZWxvYWQgPSB7fVxuICAgIGRpc3RpbmN0SWRzUXVlcnkuX3NlbGVjdHMgPSBbXVxuICAgIGRpc3RpbmN0SWRzUXVlcnkuc2VsZWN0KHByaW1hcnlLZXlTcWwpXG4gICAgZGlzdGluY3RJZHNRdWVyeS5kaXN0aW5jdCh0cnVlKVxuXG4gICAgY29uc3QgZGlzdGluY3RSb290UXVlcnkgPSBtb2RlbENsYXNzLl9uZXdRdWVyeSgpXG5cbiAgICBkaXN0aW5jdFJvb3RRdWVyeS53aGVyZShgJHtwcmltYXJ5S2V5U3FsfSBJTiAoJHtkaXN0aW5jdElkc1F1ZXJ5LnRvU3FsKCl9KWApXG4gICAgZGlzdGluY3RSb290UXVlcnkuX3ByZWxvYWQgPSB7Li4ucXVlcnkuX3ByZWxvYWR9XG5cbiAgICByZXR1cm4gZGlzdGluY3RSb290UXVlcnlcbiAgfVxuXG4gIC8qKlxuICAgKiBSdW5zIGZyb250ZW5kIG1vZGVsIHBsdWNrIHZhbHVlcy5cbiAgICogQHBhcmFtIHtvYmplY3R9IGFyZ3MgLSBQbHVjayBhcmdzLlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4vZGF0YWJhc2UvcXVlcnkvbW9kZWwtY2xhc3MtcXVlcnkuanNcIikuZGVmYXVsdH0gYXJncy5xdWVyeSAtIFF1ZXJ5IGluc3RhbmNlLlxuICAgKiBAcGFyYW0ge0Zyb250ZW5kTW9kZWxQbHVja1tdfSBhcmdzLnBsdWNrIC0gUGx1Y2sgZGVzY3JpcHRvcnMuXG4gICAqIEByZXR1cm5zIHtQcm9taXNlPEFycmF5PD8+Pn0gLSBQbHVja2VkIHZhbHVlcy5cbiAgICovXG4gIGFzeW5jIGZyb250ZW5kTW9kZWxQbHVja1ZhbHVlcyh7cXVlcnksIHBsdWNrfSkge1xuICAgIGlmIChwbHVjay5sZW5ndGggPCAxKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoXCJObyBjb2x1bW5zIGdpdmVuIHRvIHBsdWNrXCIpXG4gICAgfVxuXG4gICAgY29uc3QgbW9kZWxDbGFzcyA9IHRoaXMuZnJvbnRlbmRNb2RlbENsYXNzKClcbiAgICBjb25zdCBwbHVja1F1ZXJ5ID0gcXVlcnkuY2xvbmUoKVxuICAgIC8qKlxuICAgICAqIEFsaWFzZXMuXG4gICAgICBAdHlwZSB7c3RyaW5nW119ICovXG4gICAgY29uc3QgYWxpYXNlcyA9IFtdXG4gICAgY29uc3QgcXVlcnlNZXRhZGF0YSA9IGZyb250ZW5kTW9kZWxRdWVyeU1ldGFkYXRhKHF1ZXJ5KVxuICAgIGNvbnN0IHBsdWNrUXVlcnlNZXRhZGF0YSA9IGZyb250ZW5kTW9kZWxRdWVyeU1ldGFkYXRhKHBsdWNrUXVlcnkpXG4gICAgY29uc3Qgam9pbmVkUGF0aHMgPSBxdWVyeU1ldGFkYXRhW2Zyb250ZW5kTW9kZWxKb2luZWRQYXRoc1N5bWJvbF1cblxuICAgIHBsdWNrUXVlcnkuX3ByZWxvYWQgPSB7fVxuICAgIHBsdWNrUXVlcnkuX3NlbGVjdHMgPSBbXVxuICAgIHBsdWNrUXVlcnlNZXRhZGF0YVtmcm9udGVuZE1vZGVsSm9pbmVkUGF0aHNTeW1ib2xdID0gam9pbmVkUGF0aHMgPyBuZXcgU2V0KGpvaW5lZFBhdGhzKSA6IG5ldyBTZXQoKVxuXG4gICAgZm9yIChjb25zdCBbcGx1Y2tJbmRleCwgcGx1Y2tFbnRyeV0gb2YgcGx1Y2suZW50cmllcygpKSB7XG4gICAgICBjb25zdCB0YXJnZXRNb2RlbENsYXNzID0gdGhpcy5mcm9udGVuZE1vZGVsU2VhcmNoVGFyZ2V0TW9kZWxDbGFzcyh7XG4gICAgICAgIG1vZGVsQ2xhc3MsXG4gICAgICAgIHBhdGg6IHBsdWNrRW50cnkucGF0aFxuICAgICAgfSlcbiAgICAgIGNvbnN0IGNvbHVtbk5hbWUgPSB0aGlzLnJlc29sdmVGcm9udGVuZE1vZGVsQ29sdW1uTmFtZSh0YXJnZXRNb2RlbENsYXNzLCBwbHVja0VudHJ5LmNvbHVtbilcblxuICAgICAgaWYgKCFjb2x1bW5OYW1lKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihgVW5rbm93biBwbHVjayBjb2x1bW4gXCIke3BsdWNrRW50cnkuY29sdW1ufVwiIGZvciAke3RhcmdldE1vZGVsQ2xhc3MubmFtZX1gKVxuICAgICAgfVxuXG4gICAgICBpZiAocGx1Y2tFbnRyeS5wYXRoLmxlbmd0aCA+IDApIHtcbiAgICAgICAgdGhpcy5lbnN1cmVGcm9udGVuZE1vZGVsSm9pblBhdGgoe3BhdGg6IHBsdWNrRW50cnkucGF0aCwgcXVlcnk6IHBsdWNrUXVlcnl9KVxuICAgICAgfVxuXG4gICAgICBjb25zdCB0YWJsZVJlZmVyZW5jZSA9IHBsdWNrUXVlcnkuZ2V0VGFibGVSZWZlcmVuY2VGb3JKb2luKC4uLnBsdWNrRW50cnkucGF0aClcbiAgICAgIGNvbnN0IGNvbHVtblNxbCA9IGAke3BsdWNrUXVlcnkuZHJpdmVyLnF1b3RlVGFibGUodGFibGVSZWZlcmVuY2UpfS4ke3BsdWNrUXVlcnkuZHJpdmVyLnF1b3RlQ29sdW1uKGNvbHVtbk5hbWUpfWBcbiAgICAgIGNvbnN0IGFsaWFzID0gYGZyb250ZW5kX21vZGVsX3BsdWNrXyR7cGx1Y2tJbmRleH1gXG5cbiAgICAgIHBsdWNrUXVlcnkuc2VsZWN0KGAke2NvbHVtblNxbH0gQVMgJHtwbHVja1F1ZXJ5LmRyaXZlci5xdW90ZUNvbHVtbihhbGlhcyl9YClcbiAgICAgIGFsaWFzZXMucHVzaChhbGlhcylcbiAgICB9XG5cbiAgICBjb25zdCByb3dzID0gYXdhaXQgcGx1Y2tRdWVyeS5yZXN1bHRzKClcblxuICAgIGlmIChhbGlhc2VzLmxlbmd0aCA9PT0gMSkge1xuICAgICAgY29uc3QgW2FsaWFzXSA9IGFsaWFzZXNcblxuICAgICAgcmV0dXJuIHJvd3MubWFwKChyb3cpID0+IC8qKlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqIFR5cGVzIHRoZSBmb2xsb3dpbmcgdmFsdWUuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBAdHlwZSB7UmVjb3JkPHN0cmluZywgPz59ICovIChyb3cpW2FsaWFzXSlcbiAgICB9XG5cbiAgICByZXR1cm4gcm93cy5tYXAoKHJvdykgPT4ge1xuICAgICAgY29uc3Qgcm93SGFzaCA9IC8qKlxuICAgICAgICAgICAgICAgICAgICAgICAqIFR5cGVzIHRoZSBmb2xsb3dpbmcgdmFsdWUuXG4gICAgICAgICAgICAgICAgICAgICAgICBAdHlwZSB7UmVjb3JkPHN0cmluZywgPz59ICovIChyb3cpXG5cbiAgICAgIHJldHVybiBhbGlhc2VzLm1hcCgoYWxpYXMpID0+IHJvd0hhc2hbYWxpYXNdKVxuICAgIH0pXG4gIH1cblxuICAvKipcbiAgICogUnVucyBmcm9udGVuZCBtb2RlbCBzZWFyY2ggdGFyZ2V0IG1vZGVsIGNsYXNzLlxuICAgKiBAcGFyYW0ge29iamVjdH0gYXJncyAtIFNlYXJjaCBhcmdzLlxuICAgKiBAcGFyYW0ge3R5cGVvZiBpbXBvcnQoXCIuL2RhdGFiYXNlL3JlY29yZC9pbmRleC5qc1wiKS5kZWZhdWx0fSBhcmdzLm1vZGVsQ2xhc3MgLSBSb290IG1vZGVsIGNsYXNzLlxuICAgKiBAcGFyYW0ge3N0cmluZ1tdfSBhcmdzLnBhdGggLSBSZWxhdGlvbnNoaXAgcGF0aC5cbiAgICogQHJldHVybnMge3R5cGVvZiBpbXBvcnQoXCIuL2RhdGFiYXNlL3JlY29yZC9pbmRleC5qc1wiKS5kZWZhdWx0fSAtIFRhcmdldCBtb2RlbCBjbGFzcy5cbiAgICovXG4gIGZyb250ZW5kTW9kZWxTZWFyY2hUYXJnZXRNb2RlbENsYXNzKHttb2RlbENsYXNzLCBwYXRofSkge1xuICAgIGxldCB0YXJnZXRNb2RlbENsYXNzID0gbW9kZWxDbGFzc1xuXG4gICAgZm9yIChjb25zdCByZWxhdGlvbnNoaXBOYW1lIG9mIHBhdGgpIHtcbiAgICAgIGNvbnN0IHJlbGF0aW9uc2hpcCA9IHRhcmdldE1vZGVsQ2xhc3MuZ2V0UmVsYXRpb25zaGlwc01hcCgpW3JlbGF0aW9uc2hpcE5hbWVdXG5cbiAgICAgIGlmICghcmVsYXRpb25zaGlwKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihgVW5rbm93biBzZWFyY2ggcmVsYXRpb25zaGlwIFwiJHtyZWxhdGlvbnNoaXBOYW1lfVwiIGZvciAke3RhcmdldE1vZGVsQ2xhc3MubmFtZX1gKVxuICAgICAgfVxuXG4gICAgICBjb25zdCByZWxhdGlvbnNoaXBUYXJnZXRNb2RlbENsYXNzID0gcmVsYXRpb25zaGlwLmdldFRhcmdldE1vZGVsQ2xhc3MoKVxuXG4gICAgICBpZiAoIXJlbGF0aW9uc2hpcFRhcmdldE1vZGVsQ2xhc3MpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBObyB0YXJnZXQgbW9kZWwgY2xhc3MgZm9yICR7dGFyZ2V0TW9kZWxDbGFzcy5uYW1lfSMke3JlbGF0aW9uc2hpcE5hbWV9YClcbiAgICAgIH1cblxuICAgICAgdGFyZ2V0TW9kZWxDbGFzcyA9IHJlbGF0aW9uc2hpcFRhcmdldE1vZGVsQ2xhc3NcbiAgICB9XG5cbiAgICByZXR1cm4gdGFyZ2V0TW9kZWxDbGFzc1xuICB9XG5cbiAgLyoqXG4gICAqIFJ1bnMgYXBwbHkgZnJvbnRlbmQgbW9kZWwgc2VhcmNoLlxuICAgKiBAcGFyYW0ge29iamVjdH0gYXJncyAtIFNlYXJjaCBhcmdzLlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4vZGF0YWJhc2UvcXVlcnkvbW9kZWwtY2xhc3MtcXVlcnkuanNcIikuZGVmYXVsdH0gYXJncy5xdWVyeSAtIFF1ZXJ5IGluc3RhbmNlLlxuICAgKiBAcGFyYW0ge0Zyb250ZW5kTW9kZWxTZWFyY2h9IGFyZ3Muc2VhcmNoIC0gU2VhcmNoIGZpbHRlci5cbiAgICogQHJldHVybnMge3ZvaWR9XG4gICAqL1xuICBhcHBseUZyb250ZW5kTW9kZWxTZWFyY2goe3F1ZXJ5LCBzZWFyY2h9KSB7XG4gICAgY29uc3QgbW9kZWxDbGFzcyA9IHRoaXMuZnJvbnRlbmRNb2RlbENsYXNzKClcbiAgICBjb25zdCB0YXJnZXRNb2RlbENsYXNzID0gdGhpcy5mcm9udGVuZE1vZGVsU2VhcmNoVGFyZ2V0TW9kZWxDbGFzcyh7XG4gICAgICBtb2RlbENsYXNzLFxuICAgICAgcGF0aDogc2VhcmNoLnBhdGhcbiAgICB9KVxuICAgIGNvbnN0IGNvbHVtbk5hbWUgPSB0aGlzLnJlc29sdmVGcm9udGVuZE1vZGVsQ29sdW1uTmFtZSh0YXJnZXRNb2RlbENsYXNzLCBzZWFyY2guY29sdW1uKVxuXG4gICAgaWYgKCFjb2x1bW5OYW1lKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoYFVua25vd24gc2VhcmNoIGNvbHVtbiBcIiR7c2VhcmNoLmNvbHVtbn1cIiBmb3IgJHt0YXJnZXRNb2RlbENsYXNzLm5hbWV9YClcbiAgICB9XG5cbiAgICBpZiAoc2VhcmNoLnBhdGgubGVuZ3RoID4gMCkge1xuICAgICAgdGhpcy5lbnN1cmVGcm9udGVuZE1vZGVsSm9pblBhdGgoe3BhdGg6IHNlYXJjaC5wYXRoLCBxdWVyeX0pXG4gICAgfVxuXG4gICAgY29uc3QgdGFibGVSZWZlcmVuY2UgPSBxdWVyeS5nZXRUYWJsZVJlZmVyZW5jZUZvckpvaW4oLi4uc2VhcmNoLnBhdGgpXG4gICAgY29uc3QgY29sdW1uU3FsID0gYCR7cXVlcnkuZHJpdmVyLnF1b3RlVGFibGUodGFibGVSZWZlcmVuY2UpfS4ke3F1ZXJ5LmRyaXZlci5xdW90ZUNvbHVtbihjb2x1bW5OYW1lKX1gXG4gICAgY29uc3Qgb3BlcmF0b3JNYXAgPSB7XG4gICAgICBlcTogXCI9XCIsXG4gICAgICBndDogXCI+XCIsXG4gICAgICBndGVxOiBcIj49XCIsXG4gICAgICBsaWtlOiBcIkxJS0VcIixcbiAgICAgIGx0OiBcIjxcIixcbiAgICAgIGx0ZXE6IFwiPD1cIixcbiAgICAgIG5vdEVxOiBcIiE9XCJcbiAgICB9XG4gICAgY29uc3Qgc3FsT3BlcmF0b3IgPSBvcGVyYXRvck1hcFtzZWFyY2gub3BlcmF0b3JdXG5cbiAgICBpZiAoc2VhcmNoLm9wZXJhdG9yID09PSBcImVxXCIpIHtcbiAgICAgIGlmICh0aGlzLmFwcGx5RnJvbnRlbmRNb2RlbEFycmF5U2VhcmNoKHtlbXB0eVNxbDogXCIxPTBcIiwgb3BlcmF0b3JTcWw6IFwiSU5cIiwgcXVlcnksIHNlYXJjaCwgY29sdW1uU3FsfSkpIHJldHVyblxuXG4gICAgICBpZiAoc2VhcmNoLnZhbHVlID09PSBudWxsKSB7XG4gICAgICAgIHF1ZXJ5LndoZXJlKGAke2NvbHVtblNxbH0gSVMgTlVMTGApXG4gICAgICAgIHJldHVyblxuICAgICAgfVxuICAgIH1cblxuICAgIGlmIChzZWFyY2gub3BlcmF0b3IgPT09IFwibm90RXFcIikge1xuICAgICAgaWYgKHRoaXMuYXBwbHlGcm9udGVuZE1vZGVsQXJyYXlTZWFyY2goe2VtcHR5U3FsOiBcIjE9MVwiLCBvcGVyYXRvclNxbDogXCJOT1QgSU5cIiwgcXVlcnksIHNlYXJjaCwgY29sdW1uU3FsfSkpIHJldHVyblxuXG4gICAgICBpZiAoc2VhcmNoLnZhbHVlID09PSBudWxsKSB7XG4gICAgICAgIHF1ZXJ5LndoZXJlKGAke2NvbHVtblNxbH0gSVMgTk9UIE5VTExgKVxuICAgICAgICByZXR1cm5cbiAgICAgIH1cbiAgICB9XG5cbiAgICBxdWVyeS53aGVyZShgJHtjb2x1bW5TcWx9ICR7c3FsT3BlcmF0b3J9ICR7cXVlcnkuZHJpdmVyLnF1b3RlKHNlYXJjaC52YWx1ZSl9YClcbiAgfVxuXG4gIC8qKlxuICAgKiBBcHBseSBhcnJheS12YWx1ZWQgZXF1YWxpdHkgc2VhcmNoIGZpbHRlcnMuXG4gICAqIEBwYXJhbSB7b2JqZWN0fSBhcmdzIC0gU2VhcmNoIGFyZ3VtZW50cy5cbiAgICogQHBhcmFtIHtzdHJpbmd9IGFyZ3MuY29sdW1uU3FsIC0gU1FMIGZvciB0aGUgc2VhcmNoZWQgY29sdW1uLlxuICAgKiBAcGFyYW0ge3N0cmluZ30gYXJncy5lbXB0eVNxbCAtIFNRTCBwcmVkaWNhdGUgdXNlZCB3aGVuIHRoZSBhcnJheSBpcyBlbXB0eS5cbiAgICogQHBhcmFtIHtcIklOXCIgfCBcIk5PVCBJTlwifSBhcmdzLm9wZXJhdG9yU3FsIC0gU1FMIGFycmF5IG9wZXJhdG9yLlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4vZGF0YWJhc2UvcXVlcnkvbW9kZWwtY2xhc3MtcXVlcnkuanNcIikuZGVmYXVsdH0gYXJncy5xdWVyeSAtIFF1ZXJ5IGluc3RhbmNlLlxuICAgKiBAcGFyYW0ge0Zyb250ZW5kTW9kZWxTZWFyY2h9IGFyZ3Muc2VhcmNoIC0gU2VhcmNoIGRlc2NyaXB0b3IuXG4gICAqIEByZXR1cm5zIHtib29sZWFufSAtIFdoZXRoZXIgYW4gYXJyYXkgcHJlZGljYXRlIHdhcyBhcHBsaWVkLlxuICAgKi9cbiAgYXBwbHlGcm9udGVuZE1vZGVsQXJyYXlTZWFyY2goe2NvbHVtblNxbCwgZW1wdHlTcWwsIG9wZXJhdG9yU3FsLCBxdWVyeSwgc2VhcmNofSkge1xuICAgIGlmICghQXJyYXkuaXNBcnJheShzZWFyY2gudmFsdWUpKSByZXR1cm4gZmFsc2VcblxuICAgIGlmIChzZWFyY2gudmFsdWUubGVuZ3RoID09PSAwKSB7XG4gICAgICBxdWVyeS53aGVyZShlbXB0eVNxbClcbiAgICB9IGVsc2Uge1xuICAgICAgcXVlcnkud2hlcmUoYCR7Y29sdW1uU3FsfSAke29wZXJhdG9yU3FsfSAoJHtzZWFyY2gudmFsdWUubWFwKChlbnRyeSkgPT4gcXVlcnkuZHJpdmVyLnF1b3RlKGVudHJ5KSkuam9pbihcIiwgXCIpfSlgKVxuICAgIH1cblxuICAgIHJldHVybiB0cnVlXG4gIH1cblxuICAvKipcbiAgICogUnVucyBhcHBseSBmcm9udGVuZCBtb2RlbCBwYWdpbmF0aW9uLlxuICAgKiBAcGFyYW0ge29iamVjdH0gYXJncyAtIFBhZ2luYXRpb24gYXJncy5cbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuL2RhdGFiYXNlL3F1ZXJ5L21vZGVsLWNsYXNzLXF1ZXJ5LmpzXCIpLmRlZmF1bHR9IGFyZ3MucXVlcnkgLSBRdWVyeSBpbnN0YW5jZS5cbiAgICogQHBhcmFtIHtGcm9udGVuZE1vZGVsUGFnaW5hdGlvbn0gYXJncy5wYWdpbmF0aW9uIC0gUGFnaW5hdGlvbiB2YWx1ZXMuXG4gICAqIEByZXR1cm5zIHt2b2lkfVxuICAgKi9cbiAgYXBwbHlGcm9udGVuZE1vZGVsUGFnaW5hdGlvbih7cXVlcnksIHBhZ2luYXRpb259KSB7XG4gICAgaWYgKHBhZ2luYXRpb24ubGltaXQgIT09IG51bGwpIHtcbiAgICAgIHF1ZXJ5LmxpbWl0KHBhZ2luYXRpb24ubGltaXQpXG4gICAgfVxuXG4gICAgaWYgKHBhZ2luYXRpb24ub2Zmc2V0ICE9PSBudWxsKSB7XG4gICAgICBxdWVyeS5vZmZzZXQocGFnaW5hdGlvbi5vZmZzZXQpXG4gICAgfVxuXG4gICAgaWYgKHBhZ2luYXRpb24ucGVyUGFnZSAhPT0gbnVsbCkge1xuICAgICAgcXVlcnkucGVyUGFnZShwYWdpbmF0aW9uLnBlclBhZ2UpXG4gICAgfVxuXG4gICAgaWYgKHBhZ2luYXRpb24ucGFnZSAhPT0gbnVsbCkge1xuICAgICAgcXVlcnkucGFnZShwYWdpbmF0aW9uLnBhZ2UpXG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIFJ1bnMgYXBwbHkgZnJvbnRlbmQgbW9kZWwgd2hlcmUuXG4gICAqIEBwYXJhbSB7b2JqZWN0fSBhcmdzIC0gV2hlcmUgYXJncy5cbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuL2RhdGFiYXNlL3F1ZXJ5L21vZGVsLWNsYXNzLXF1ZXJ5LmpzXCIpLmRlZmF1bHR9IGFyZ3MucXVlcnkgLSBRdWVyeSBpbnN0YW5jZS5cbiAgICogQHBhcmFtIHtSZWNvcmQ8c3RyaW5nLCA/Pn0gYXJncy53aGVyZSAtIFJvb3QtbW9kZWwgd2hlcmUgY29uZGl0aW9ucy5cbiAgICogQHJldHVybnMge3ZvaWR9XG4gICAqL1xuICBhcHBseUZyb250ZW5kTW9kZWxXaGVyZSh7cXVlcnksIHdoZXJlfSkge1xuICAgIHRoaXMuYXBwbHlGcm9udGVuZE1vZGVsV2hlcmVGb3JQYXRoKHtcbiAgICAgIG1vZGVsQ2xhc3M6IHRoaXMuZnJvbnRlbmRNb2RlbENsYXNzKCksXG4gICAgICBwYXRoOiBbXSxcbiAgICAgIHF1ZXJ5LFxuICAgICAgd2hlcmVcbiAgICB9KVxuICB9XG5cbiAgLyoqXG4gICAqIFJ1bnMgYXBwbHkgZnJvbnRlbmQgbW9kZWwgam9pbnMuXG4gICAqIEBwYXJhbSB7b2JqZWN0fSBhcmdzIC0gSm9pbnMgYXJncy5cbiAgICogQHBhcmFtIHtSZWNvcmQ8c3RyaW5nLCA/Pn0gYXJncy5qb2lucyAtIFJlbGF0aW9uc2hpcC1vYmplY3Qgam9pbnMuXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi9kYXRhYmFzZS9xdWVyeS9tb2RlbC1jbGFzcy1xdWVyeS5qc1wiKS5kZWZhdWx0fSBhcmdzLnF1ZXJ5IC0gUXVlcnkgaW5zdGFuY2UuXG4gICAqIEByZXR1cm5zIHt2b2lkfVxuICAgKi9cbiAgYXBwbHlGcm9udGVuZE1vZGVsSm9pbnMoe2pvaW5zLCBxdWVyeX0pIHtcbiAgICBjb25zdCBqb2luUGF0aEtleXMgPSBuZXcgU2V0KClcblxuICAgIHRoaXMuYXBwbHlGcm9udGVuZE1vZGVsSm9pbnNGb3JQYXRoKHtcbiAgICAgIGpvaW5zLFxuICAgICAgam9pblBhdGhLZXlzLFxuICAgICAgbW9kZWxDbGFzczogdGhpcy5mcm9udGVuZE1vZGVsQ2xhc3MoKSxcbiAgICAgIHBhdGg6IFtdLFxuICAgICAgcXVlcnlcbiAgICB9KVxuXG4gICAgcXVlcnkuam9pbnMoam9pbnMpXG5cbiAgICBjb25zdCBxdWVyeU1ldGFkYXRhID0gZnJvbnRlbmRNb2RlbFF1ZXJ5TWV0YWRhdGEocXVlcnkpXG4gICAgY29uc3Qgam9pbmVkUGF0aHMgPSBxdWVyeU1ldGFkYXRhW2Zyb250ZW5kTW9kZWxKb2luZWRQYXRoc1N5bWJvbF0gfHwgbmV3IFNldCgpXG5cbiAgICBmb3IgKGNvbnN0IGpvaW5QYXRoS2V5IG9mIGpvaW5QYXRoS2V5cykge1xuICAgICAgam9pbmVkUGF0aHMuYWRkKGpvaW5QYXRoS2V5KVxuICAgIH1cblxuICAgIHF1ZXJ5TWV0YWRhdGFbZnJvbnRlbmRNb2RlbEpvaW5lZFBhdGhzU3ltYm9sXSA9IGpvaW5lZFBhdGhzXG4gIH1cblxuICAvKipcbiAgICogUnVucyBhcHBseSBmcm9udGVuZCBtb2RlbCBqb2lucyBmb3IgcGF0aC5cbiAgICogQHBhcmFtIHtvYmplY3R9IGFyZ3MgLSBKb2lucyBhcmdzLlxuICAgKiBAcGFyYW0ge1JlY29yZDxzdHJpbmcsID8+fSBhcmdzLmpvaW5zIC0gSm9pbnMgZm9yIGN1cnJlbnQgcGF0aC5cbiAgICogQHBhcmFtIHtTZXQ8c3RyaW5nPn0gYXJncy5qb2luUGF0aEtleXMgLSBKb2luZWQgcGF0aCBrZXlzLlxuICAgKiBAcGFyYW0ge3R5cGVvZiBpbXBvcnQoXCIuL2RhdGFiYXNlL3JlY29yZC9pbmRleC5qc1wiKS5kZWZhdWx0fSBhcmdzLm1vZGVsQ2xhc3MgLSBNb2RlbCBjbGFzcyBmb3IgY3VycmVudCBwYXRoLlxuICAgKiBAcGFyYW0ge3N0cmluZ1tdfSBhcmdzLnBhdGggLSBSZWxhdGlvbnNoaXAgcGF0aC5cbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuL2RhdGFiYXNlL3F1ZXJ5L21vZGVsLWNsYXNzLXF1ZXJ5LmpzXCIpLmRlZmF1bHR9IGFyZ3MucXVlcnkgLSBRdWVyeSBpbnN0YW5jZS5cbiAgICogQHJldHVybnMge3ZvaWR9XG4gICAqL1xuICBhcHBseUZyb250ZW5kTW9kZWxKb2luc0ZvclBhdGgoe2pvaW5zLCBqb2luUGF0aEtleXMsIG1vZGVsQ2xhc3MsIHBhdGgsIHF1ZXJ5fSkge1xuICAgIHZvaWQgcXVlcnlcblxuICAgIGZvciAoY29uc3QgW3JlbGF0aW9uc2hpcE5hbWUsIHJlbGF0aW9uc2hpcEpvaW5dIG9mIE9iamVjdC5lbnRyaWVzKGpvaW5zKSkge1xuICAgICAgY29uc3QgcmVsYXRpb25zaGlwID0gbW9kZWxDbGFzcy5nZXRSZWxhdGlvbnNoaXBzTWFwKClbcmVsYXRpb25zaGlwTmFtZV1cblxuICAgICAgaWYgKCFyZWxhdGlvbnNoaXApIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBVbmtub3duIGpvaW4gcmVsYXRpb25zaGlwIFwiJHtyZWxhdGlvbnNoaXBOYW1lfVwiIGZvciAke21vZGVsQ2xhc3MubmFtZX1gKVxuICAgICAgfVxuXG4gICAgICBjb25zdCB0YXJnZXRNb2RlbENsYXNzID0gcmVsYXRpb25zaGlwLmdldFRhcmdldE1vZGVsQ2xhc3MoKVxuXG4gICAgICBpZiAoIXRhcmdldE1vZGVsQ2xhc3MpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBObyB0YXJnZXQgbW9kZWwgY2xhc3MgZm9yIGpvaW4gcmVsYXRpb25zaGlwIFwiJHtyZWxhdGlvbnNoaXBOYW1lfVwiIG9uICR7bW9kZWxDbGFzcy5uYW1lfWApXG4gICAgICB9XG5cbiAgICAgIGNvbnN0IHJlbGF0aW9uc2hpcFBhdGggPSBbLi4ucGF0aCwgcmVsYXRpb25zaGlwTmFtZV1cbiAgICAgIGpvaW5QYXRoS2V5cy5hZGQocmVsYXRpb25zaGlwUGF0aC5qb2luKFwiLlwiKSlcblxuICAgICAgaWYgKHJlbGF0aW9uc2hpcEpvaW4gPT09IHRydWUpIGNvbnRpbnVlXG5cbiAgICAgIHRoaXMuYXBwbHlGcm9udGVuZE1vZGVsSm9pbnNGb3JQYXRoKHtcbiAgICAgICAgam9pbnM6IHJlbGF0aW9uc2hpcEpvaW4sXG4gICAgICAgIGpvaW5QYXRoS2V5cyxcbiAgICAgICAgbW9kZWxDbGFzczogdGFyZ2V0TW9kZWxDbGFzcyxcbiAgICAgICAgcGF0aDogcmVsYXRpb25zaGlwUGF0aCxcbiAgICAgICAgcXVlcnlcbiAgICAgIH0pXG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIFJlc29sdmVzIGEga2V5IHRoYXQgbWF5IGJlIGVpdGhlciBhIGNhbWVsQ2FzZSBhdHRyaWJ1dGUgbmFtZSBvciBhIHJhdyBEQlxuICAgKiBjb2x1bW4gbmFtZSB0byBpdHMgY2Fub25pY2FsIGNvbHVtbiBuYW1lLiAgUmV0dXJucyBgdW5kZWZpbmVkYCB3aGVuIHRoZVxuICAgKiBrZXkgbWF0Y2hlcyBuZWl0aGVyIG1hcC5cbiAgICogQHBhcmFtIHt0eXBlb2YgaW1wb3J0KFwiLi9kYXRhYmFzZS9yZWNvcmQvaW5kZXguanNcIikuZGVmYXVsdH0gbW9kZWxDbGFzcyAtIE1vZGVsIGNsYXNzLlxuICAgKiBAcGFyYW0ge3N0cmluZ30ga2V5IC0gQXR0cmlidXRlIG5hbWUgb3IgY29sdW1uIG5hbWUgdG8gcmVzb2x2ZS5cbiAgICogQHJldHVybnMge3N0cmluZyB8IHVuZGVmaW5lZH0gLSBSZXNvbHZlZCBEQiBjb2x1bW4gbmFtZSwgb3IgYHVuZGVmaW5lZGAuXG4gICAqL1xuICByZXNvbHZlRnJvbnRlbmRNb2RlbENvbHVtbk5hbWUobW9kZWxDbGFzcywga2V5KSB7XG4gICAgY29uc3QgYXR0cmlidXRlTmFtZVRvQ29sdW1uTmFtZU1hcCA9IG1vZGVsQ2xhc3MuZ2V0QXR0cmlidXRlTmFtZVRvQ29sdW1uTmFtZU1hcCgpXG4gICAgY29uc3QgY29sdW1uTmFtZSA9IGF0dHJpYnV0ZU5hbWVUb0NvbHVtbk5hbWVNYXBba2V5XVxuXG4gICAgaWYgKGNvbHVtbk5hbWUpIHJldHVybiBjb2x1bW5OYW1lXG5cbiAgICAvLyBGYWxsIGJhY2s6IGNoZWNrIHdoZXRoZXIgdGhlIGtleSBpcyBhbHJlYWR5IGEgcmF3IERCIGNvbHVtbiBuYW1lLlxuICAgIGNvbnN0IGNvbHVtbk5hbWVUb0F0dHJpYnV0ZU5hbWVNYXAgPSBtb2RlbENsYXNzLmdldENvbHVtbk5hbWVUb0F0dHJpYnV0ZU5hbWVNYXAoKVxuXG4gICAgaWYgKGNvbHVtbk5hbWVUb0F0dHJpYnV0ZU5hbWVNYXBba2V5XSkgcmV0dXJuIGtleVxuXG4gICAgcmV0dXJuIHVuZGVmaW5lZFxuICB9XG5cbiAgLyoqXG4gICAqIFJ1bnMgYXBwbHkgZnJvbnRlbmQgbW9kZWwgd2hlcmUgZm9yIHBhdGguXG4gICAqIEBwYXJhbSB7b2JqZWN0fSBhcmdzIC0gV2hlcmUgYXJncy5cbiAgICogQHBhcmFtIHt0eXBlb2YgaW1wb3J0KFwiLi9kYXRhYmFzZS9yZWNvcmQvaW5kZXguanNcIikuZGVmYXVsdH0gYXJncy5tb2RlbENsYXNzIC0gTW9kZWwgY2xhc3MgZm9yIGN1cnJlbnQgd2hlcmUgc2NvcGUuXG4gICAqIEBwYXJhbSB7c3RyaW5nW119IGFyZ3MucGF0aCAtIFJlbGF0aW9uc2hpcCBwYXRoIGZyb20gcm9vdC5cbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuL2RhdGFiYXNlL3F1ZXJ5L21vZGVsLWNsYXNzLXF1ZXJ5LmpzXCIpLmRlZmF1bHR9IGFyZ3MucXVlcnkgLSBRdWVyeSBpbnN0YW5jZS5cbiAgICogQHBhcmFtIHtSZWNvcmQ8c3RyaW5nLCA/Pn0gYXJncy53aGVyZSAtIFdoZXJlIGNvbmRpdGlvbnMgZm9yIGN1cnJlbnQgc2NvcGUuXG4gICAqIEByZXR1cm5zIHt2b2lkfVxuICAgKi9cbiAgYXBwbHlGcm9udGVuZE1vZGVsV2hlcmVGb3JQYXRoKHttb2RlbENsYXNzLCBwYXRoLCBxdWVyeSwgd2hlcmV9KSB7XG4gICAgZm9yIChjb25zdCBbYXR0cmlidXRlTmFtZSwgdmFsdWVdIG9mIE9iamVjdC5lbnRyaWVzKHdoZXJlKSkge1xuICAgICAgY29uc3QgY29sdW1uTmFtZSA9IHRoaXMucmVzb2x2ZUZyb250ZW5kTW9kZWxDb2x1bW5OYW1lKG1vZGVsQ2xhc3MsIGF0dHJpYnV0ZU5hbWUpXG5cbiAgICAgIGlmIChjb2x1bW5OYW1lKSB7XG4gICAgICAgIHRoaXMuZW5zdXJlRnJvbnRlbmRNb2RlbEpvaW5QYXRoKHtwYXRoLCBxdWVyeX0pXG5cbiAgICAgICAgY29uc3QgdGFibGVSZWZlcmVuY2UgPSBxdWVyeS5nZXRUYWJsZVJlZmVyZW5jZUZvckpvaW4oLi4ucGF0aClcbiAgICAgICAgY29uc3QgY29sdW1uU3FsID0gYCR7cXVlcnkuZHJpdmVyLnF1b3RlVGFibGUodGFibGVSZWZlcmVuY2UpfS4ke3F1ZXJ5LmRyaXZlci5xdW90ZUNvbHVtbihjb2x1bW5OYW1lKX1gXG5cbiAgICAgICAgaWYgKEFycmF5LmlzQXJyYXkodmFsdWUpKSB7XG4gICAgICAgICAgaWYgKHZhbHVlLmxlbmd0aCA9PT0gMCkge1xuICAgICAgICAgICAgcXVlcnkud2hlcmUoXCIxPTBcIilcbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgY29uc3Qgbm9ybWFsaXplZFZhbHVlcyA9IHZhbHVlLm1hcCgoZW50cnkpID0+IHRoaXMubm9ybWFsaXplRnJvbnRlbmRNb2RlbFdoZXJlQ29sdW1uVmFsdWUoe2NvbHVtbk5hbWUsIG1vZGVsQ2xhc3MsIHZhbHVlOiBlbnRyeX0pKVxuXG4gICAgICAgICAgICBpZiAobm9ybWFsaXplZFZhbHVlcy5pbmNsdWRlcyhmcm9udGVuZE1vZGVsV2hlcmVOb01hdGNoU3ltYm9sKSkge1xuICAgICAgICAgICAgICBxdWVyeS53aGVyZShcIjE9MFwiKVxuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgcXVlcnkud2hlcmUoYCR7Y29sdW1uU3FsfSBJTiAoJHtub3JtYWxpemVkVmFsdWVzLm1hcCgoZW50cnkpID0+IHF1ZXJ5LmRyaXZlci5xdW90ZShlbnRyeSkpLmpvaW4oXCIsIFwiKX0pYClcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG5cbiAgICAgICAgICBjb250aW51ZVxuICAgICAgICB9XG5cbiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHtcbiAgICAgICAgICBxdWVyeS53aGVyZShgJHtjb2x1bW5TcWx9IElTIE5VTExgKVxuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIGNvbnN0IG5vcm1hbGl6ZWRWYWx1ZSA9IHRoaXMubm9ybWFsaXplRnJvbnRlbmRNb2RlbFdoZXJlQ29sdW1uVmFsdWUoe2NvbHVtbk5hbWUsIG1vZGVsQ2xhc3MsIHZhbHVlfSlcblxuICAgICAgICAgIGlmIChub3JtYWxpemVkVmFsdWUgPT09IGZyb250ZW5kTW9kZWxXaGVyZU5vTWF0Y2hTeW1ib2wpIHtcbiAgICAgICAgICAgIHF1ZXJ5LndoZXJlKFwiMT0wXCIpXG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHF1ZXJ5LndoZXJlKGAke2NvbHVtblNxbH0gPSAke3F1ZXJ5LmRyaXZlci5xdW90ZShub3JtYWxpemVkVmFsdWUpfWApXG4gICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgY29udGludWVcbiAgICAgIH1cblxuICAgICAgaWYgKGlzUGxhaW5PYmplY3QodmFsdWUpKSB7XG4gICAgICAgIGNvbnN0IHJlbGF0aW9uc2hpcCA9IG1vZGVsQ2xhc3MuZ2V0UmVsYXRpb25zaGlwc01hcCgpW2F0dHJpYnV0ZU5hbWVdXG5cbiAgICAgICAgaWYgKCFyZWxhdGlvbnNoaXApIHtcbiAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYFVua25vd24gd2hlcmUgcmVsYXRpb25zaGlwIFwiJHthdHRyaWJ1dGVOYW1lfVwiIGZvciAke21vZGVsQ2xhc3MubmFtZX1gKVxuICAgICAgICB9XG5cbiAgICAgICAgY29uc3QgdGFyZ2V0TW9kZWxDbGFzcyA9IHJlbGF0aW9uc2hpcC5nZXRUYXJnZXRNb2RlbENsYXNzKClcblxuICAgICAgICBpZiAoIXRhcmdldE1vZGVsQ2xhc3MpIHtcbiAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYE5vIHRhcmdldCBtb2RlbCBjbGFzcyBmb3Igd2hlcmUgcmVsYXRpb25zaGlwIFwiJHthdHRyaWJ1dGVOYW1lfVwiIG9uICR7bW9kZWxDbGFzcy5uYW1lfWApXG4gICAgICAgIH1cblxuICAgICAgICBjb25zdCByZWxhdGlvbnNoaXBQYXRoID0gWy4uLnBhdGgsIGF0dHJpYnV0ZU5hbWVdXG5cbiAgICAgICAgdGhpcy5hcHBseUZyb250ZW5kTW9kZWxXaGVyZUZvclBhdGgoe1xuICAgICAgICAgIG1vZGVsQ2xhc3M6IHRhcmdldE1vZGVsQ2xhc3MsXG4gICAgICAgICAgcGF0aDogcmVsYXRpb25zaGlwUGF0aCxcbiAgICAgICAgICBxdWVyeSxcbiAgICAgICAgICB3aGVyZTogdmFsdWVcbiAgICAgICAgfSlcblxuICAgICAgICBjb250aW51ZVxuICAgICAgfVxuXG4gICAgICB0aHJvdyBuZXcgRXJyb3IoYFVua25vd24gd2hlcmUgY29sdW1uIFwiJHthdHRyaWJ1dGVOYW1lfVwiIGZvciAke21vZGVsQ2xhc3MubmFtZX1gKVxuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBSdW5zIG5vcm1hbGl6ZSBmcm9udGVuZCBtb2RlbCB3aGVyZSBjb2x1bW4gdmFsdWUuXG4gICAqIEBwYXJhbSB7b2JqZWN0fSBhcmdzIC0gQXJncy5cbiAgICogQHBhcmFtIHt0eXBlb2YgaW1wb3J0KFwiLi9kYXRhYmFzZS9yZWNvcmQvaW5kZXguanNcIikuZGVmYXVsdH0gYXJncy5tb2RlbENsYXNzIC0gTW9kZWwgY2xhc3MuXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBhcmdzLmNvbHVtbk5hbWUgLSBDb2x1bW4gbmFtZS5cbiAgICogQHBhcmFtIHs/fSBhcmdzLnZhbHVlIC0gV2hlcmUgdmFsdWUuXG4gICAqIEByZXR1cm5zIHs/IHwgc3ltYm9sfSAtIFNRTC1zYWZlIHdoZXJlIHZhbHVlLlxuICAgKi9cbiAgbm9ybWFsaXplRnJvbnRlbmRNb2RlbFdoZXJlQ29sdW1uVmFsdWUoe2NvbHVtbk5hbWUsIG1vZGVsQ2xhc3MsIHZhbHVlfSkge1xuICAgIGlmICh0eXBlb2YgdmFsdWUgPT09IFwic3RyaW5nXCIpIHtcbiAgICAgIGNvbnN0IGNvbHVtblR5cGUgPSBtb2RlbENsYXNzLmdldENvbHVtblR5cGVCeU5hbWUoY29sdW1uTmFtZSk/LnRvTG93ZXJDYXNlKClcbiAgICAgIGNvbnN0IGlzRGF0ZVRpbWVDb2x1bW4gPSB0eXBlb2YgY29sdW1uVHlwZSA9PT0gXCJzdHJpbmdcIiAmJiBbXCJkYXRlXCIsIFwiZGF0ZXRpbWVcIiwgXCJ0aW1lc3RhbXBcIl0uc29tZSgodHlwZSkgPT4gY29sdW1uVHlwZS5pbmNsdWRlcyh0eXBlKSlcblxuICAgICAgaWYgKGlzRGF0ZVRpbWVDb2x1bW4pIHtcbiAgICAgICAgY29uc3QgcGFyc2VkRGF0ZSA9IG5ldyBEYXRlKHZhbHVlKVxuXG4gICAgICAgIGlmICghTnVtYmVyLmlzTmFOKHBhcnNlZERhdGUuZ2V0VGltZSgpKSkge1xuICAgICAgICAgIHJldHVybiBwYXJzZWREYXRlXG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG5cbiAgICBpZiAoaXNQbGFpbk9iamVjdCh2YWx1ZSkpIHtcbiAgICAgIGNvbnN0IGNvbHVtblR5cGUgPSBtb2RlbENsYXNzLmdldENvbHVtblR5cGVCeU5hbWUoY29sdW1uTmFtZSlcblxuICAgICAgaWYgKHR5cGVvZiBjb2x1bW5UeXBlICE9PSBcInN0cmluZ1wiKSB7XG4gICAgICAgIHJldHVybiBmcm9udGVuZE1vZGVsV2hlcmVOb01hdGNoU3ltYm9sXG4gICAgICB9XG5cbiAgICAgIGNvbnN0IG5vcm1hbGl6ZWRUeXBlID0gY29sdW1uVHlwZS50b0xvd2VyQ2FzZSgpXG4gICAgICBjb25zdCBvYmplY3RWYWx1ZVR5cGVzID0gbmV3IFNldChbXCJjaGFyXCIsIFwidmFyY2hhclwiLCBcIm52YXJjaGFyXCIsIFwic3RyaW5nXCIsIFwiZW51bVwiLCBcImpzb25cIiwgXCJqc29uYlwiLCBcImNpdGV4dFwiLCBcImJpbmFyeVwiLCBcInZhcmJpbmFyeVwiXSlcbiAgICAgIGNvbnN0IHN1cHBvcnRzT2JqZWN0VmFsdWVzID0gbm9ybWFsaXplZFR5cGUuaW5jbHVkZXMoXCJ0ZXh0XCIpIHx8IG9iamVjdFZhbHVlVHlwZXMuaGFzKG5vcm1hbGl6ZWRUeXBlKVxuXG4gICAgICBpZiAoIXN1cHBvcnRzT2JqZWN0VmFsdWVzKSB7XG4gICAgICAgIHJldHVybiBmcm9udGVuZE1vZGVsV2hlcmVOb01hdGNoU3ltYm9sXG4gICAgICB9XG5cbiAgICAgIHJldHVybiBKU09OLnN0cmluZ2lmeSh2YWx1ZSlcbiAgICB9XG5cbiAgICByZXR1cm4gdmFsdWVcbiAgfVxuXG4gIC8qKlxuICAgKiBSdW5zIGFwcGx5IGZyb250ZW5kIG1vZGVsIGdyb3VwLlxuICAgKiBAcGFyYW0ge29iamVjdH0gYXJncyAtIEdyb3VwIGFyZ3MuXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi9kYXRhYmFzZS9xdWVyeS9tb2RlbC1jbGFzcy1xdWVyeS5qc1wiKS5kZWZhdWx0fSBhcmdzLnF1ZXJ5IC0gUXVlcnkgaW5zdGFuY2UuXG4gICAqIEBwYXJhbSB7RnJvbnRlbmRNb2RlbEdyb3VwfSBhcmdzLmdyb3VwIC0gR3JvdXAgZGVmaW5pdGlvbi5cbiAgICogQHJldHVybnMge3ZvaWR9XG4gICAqL1xuICBhcHBseUZyb250ZW5kTW9kZWxHcm91cCh7cXVlcnksIGdyb3VwfSkge1xuICAgIGNvbnN0IG1vZGVsQ2xhc3MgPSB0aGlzLmZyb250ZW5kTW9kZWxDbGFzcygpXG4gICAgY29uc3QgdGFyZ2V0TW9kZWxDbGFzcyA9IHRoaXMuZnJvbnRlbmRNb2RlbFNlYXJjaFRhcmdldE1vZGVsQ2xhc3Moe1xuICAgICAgbW9kZWxDbGFzcyxcbiAgICAgIHBhdGg6IGdyb3VwLnBhdGhcbiAgICB9KVxuICAgIGNvbnN0IGNvbHVtbk5hbWUgPSB0aGlzLnJlc29sdmVGcm9udGVuZE1vZGVsQ29sdW1uTmFtZSh0YXJnZXRNb2RlbENsYXNzLCBncm91cC5jb2x1bW4pXG5cbiAgICBpZiAoIWNvbHVtbk5hbWUpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihgVW5rbm93biBncm91cCBjb2x1bW4gXCIke2dyb3VwLmNvbHVtbn1cIiBmb3IgJHt0YXJnZXRNb2RlbENsYXNzLm5hbWV9YClcbiAgICB9XG5cbiAgICB0aGlzLmVuc3VyZUZyb250ZW5kTW9kZWxKb2luUGF0aCh7cGF0aDogZ3JvdXAucGF0aCwgcXVlcnl9KVxuXG4gICAgY29uc3QgdGFibGVSZWZlcmVuY2UgPSBxdWVyeS5nZXRUYWJsZVJlZmVyZW5jZUZvckpvaW4oLi4uZ3JvdXAucGF0aClcbiAgICBjb25zdCBjb2x1bW5TcWwgPSBgJHtxdWVyeS5kcml2ZXIucXVvdGVUYWJsZSh0YWJsZVJlZmVyZW5jZSl9LiR7cXVlcnkuZHJpdmVyLnF1b3RlQ29sdW1uKGNvbHVtbk5hbWUpfWBcblxuICAgIHRoaXMuZW5zdXJlRnJvbnRlbmRNb2RlbEdyb3VwQ29sdW1uKHtjb2x1bW5TcWwsIHF1ZXJ5fSlcbiAgfVxuXG4gIC8qKlxuICAgKiBBZGRzIHJvb3QtbW9kZWwgY29sdW1ucyB0byBHUk9VUCBCWSBzbyBzdHJpY3QgU1FMIGVuZ2luZXMgYWNjZXB0IGRlZmF1bHQgcm9vdC10YWJsZSBzZWxlY3RzLlxuICAgKiBAcGFyYW0ge29iamVjdH0gYXJncyAtIEFyZ3MuXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi9kYXRhYmFzZS9xdWVyeS9tb2RlbC1jbGFzcy1xdWVyeS5qc1wiKS5kZWZhdWx0fSBhcmdzLnF1ZXJ5IC0gUXVlcnkgaW5zdGFuY2UuXG4gICAqIEByZXR1cm5zIHt2b2lkfVxuICAgKi9cbiAgYXBwbHlGcm9udGVuZE1vZGVsUm9vdEdyb3VwQ29sdW1ucyh7cXVlcnl9KSB7XG4gICAgY29uc3QgbW9kZWxDbGFzcyA9IHRoaXMuZnJvbnRlbmRNb2RlbENsYXNzKClcbiAgICBjb25zdCBhdHRyaWJ1dGVOYW1lVG9Db2x1bW5OYW1lTWFwID0gbW9kZWxDbGFzcy5nZXRBdHRyaWJ1dGVOYW1lVG9Db2x1bW5OYW1lTWFwKClcbiAgICBjb25zdCByb290VGFibGVSZWZlcmVuY2UgPSBxdWVyeS5nZXRUYWJsZVJlZmVyZW5jZUZvckpvaW4oKVxuXG4gICAgZm9yIChjb25zdCBjb2x1bW5OYW1lIG9mIE9iamVjdC52YWx1ZXMoYXR0cmlidXRlTmFtZVRvQ29sdW1uTmFtZU1hcCkpIHtcbiAgICAgIGNvbnN0IGNvbHVtblNxbCA9IGAke3F1ZXJ5LmRyaXZlci5xdW90ZVRhYmxlKHJvb3RUYWJsZVJlZmVyZW5jZSl9LiR7cXVlcnkuZHJpdmVyLnF1b3RlQ29sdW1uKGNvbHVtbk5hbWUpfWBcblxuICAgICAgdGhpcy5lbnN1cmVGcm9udGVuZE1vZGVsR3JvdXBDb2x1bW4oe2NvbHVtblNxbCwgcXVlcnl9KVxuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBFbnN1cmVzIGEgZ3JvdXAtYnkgU1FMIGNvbHVtbiBpcyBvbmx5IGFwcGVuZGVkIG9uY2UuXG4gICAqIEBwYXJhbSB7b2JqZWN0fSBhcmdzIC0gQXJncy5cbiAgICogQHBhcmFtIHtzdHJpbmd9IGFyZ3MuY29sdW1uU3FsIC0gRnVsbHktcXVhbGlmaWVkIGNvbHVtbiBTUUwuXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi9kYXRhYmFzZS9xdWVyeS9tb2RlbC1jbGFzcy1xdWVyeS5qc1wiKS5kZWZhdWx0fSBhcmdzLnF1ZXJ5IC0gUXVlcnkgaW5zdGFuY2UuXG4gICAqIEByZXR1cm5zIHt2b2lkfVxuICAgKi9cbiAgZW5zdXJlRnJvbnRlbmRNb2RlbEdyb3VwQ29sdW1uKHtjb2x1bW5TcWwsIHF1ZXJ5fSkge1xuICAgIGNvbnN0IHF1ZXJ5TWV0YWRhdGEgPSBmcm9udGVuZE1vZGVsUXVlcnlNZXRhZGF0YShxdWVyeSlcbiAgICBjb25zdCBncm91cGVkQ29sdW1ucyA9IHF1ZXJ5TWV0YWRhdGFbZnJvbnRlbmRNb2RlbEdyb3VwZWRDb2x1bW5zU3ltYm9sXSB8fCBuZXcgU2V0KClcblxuICAgIGlmIChncm91cGVkQ29sdW1ucy5oYXMoY29sdW1uU3FsKSkgcmV0dXJuXG5cbiAgICBxdWVyeS5ncm91cChjb2x1bW5TcWwpXG4gICAgZ3JvdXBlZENvbHVtbnMuYWRkKGNvbHVtblNxbClcbiAgICBxdWVyeU1ldGFkYXRhW2Zyb250ZW5kTW9kZWxHcm91cGVkQ29sdW1uc1N5bWJvbF0gPSBncm91cGVkQ29sdW1uc1xuICB9XG5cbiAgLyoqXG4gICAqIFJ1bnMgYXBwbHkgZnJvbnRlbmQgbW9kZWwgdHJhbnNsYXRlZCBhdHRyaWJ1dGUgcHJlbG9hZHMuXG4gICAqIEBwYXJhbSB7b2JqZWN0fSBhcmdzIC0gQXJncy5cbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuL2RhdGFiYXNlL3F1ZXJ5L21vZGVsLWNsYXNzLXF1ZXJ5LmpzXCIpLmRlZmF1bHQ8Pz59IGFyZ3MucXVlcnkgLSBRdWVyeSBpbnN0YW5jZS5cbiAgICogQHJldHVybnMge2ltcG9ydChcIi4vZGF0YWJhc2UvcXVlcnkvbW9kZWwtY2xhc3MtcXVlcnkuanNcIikuZGVmYXVsdDw/Pn0gLSBRdWVyeSB3aXRoIHRyYW5zbGF0aW9ucyBwcmVsb2FkZWQgaWYgbmVlZGVkLlxuICAgKi9cbiAgYXBwbHlGcm9udGVuZE1vZGVsVHJhbnNsYXRlZEF0dHJpYnV0ZVByZWxvYWRzKHtxdWVyeX0pIHtcbiAgICBjb25zdCBtb2RlbENsYXNzID0gdGhpcy5mcm9udGVuZE1vZGVsQ2xhc3MoKVxuICAgIGNvbnN0IHNlbGVjdGVkQXR0cmlidXRlcyA9IHRoaXMuZnJvbnRlbmRNb2RlbEVmZmVjdGl2ZVNlbGVjdGVkQXR0cmlidXRlc0Zvck1vZGVsQ2xhc3MobW9kZWxDbGFzcywgdGhpcy5mcm9udGVuZE1vZGVsRGVmYXVsdEF0dHJpYnV0ZXNGb3JNb2RlbENsYXNzKG1vZGVsQ2xhc3MpIHx8IFtdKVxuICAgICAgfHwgdGhpcy5mcm9udGVuZE1vZGVsRGVmYXVsdEF0dHJpYnV0ZXNGb3JNb2RlbENsYXNzKG1vZGVsQ2xhc3MpXG5cbiAgICBpZiAoIXNlbGVjdGVkQXR0cmlidXRlcykgcmV0dXJuIHF1ZXJ5XG5cbiAgICBjb25zdCByZXNvdXJjZSA9IHRoaXMuZnJvbnRlbmRNb2RlbFJlc291cmNlSW5zdGFuY2UoKVxuICAgIGNvbnN0IHJlc291cmNlQ2xhc3MgPSAvKipcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICogVHlwZXMgdGhlIGZvbGxvd2luZyB2YWx1ZS5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBAdHlwZSB7dHlwZW9mIGltcG9ydChcIi4vZnJvbnRlbmQtbW9kZWwtcmVzb3VyY2UvYmFzZS1yZXNvdXJjZS5qc1wiKS5kZWZhdWx0fSAqLyAocmVzb3VyY2UuY29uc3RydWN0b3IpXG4gICAgY29uc3QgdHJhbnNsYXRlZFNldCA9IG5ldyBTZXQocmVzb3VyY2VDbGFzcy50cmFuc2xhdGVkQXR0cmlidXRlcyB8fCBbXSlcbiAgICBsZXQgbmVlZHNUcmFuc2xhdGlvbnMgPSBmYWxzZVxuXG4gICAgZm9yIChjb25zdCBhdHRyaWJ1dGVOYW1lIG9mIHNlbGVjdGVkQXR0cmlidXRlcykge1xuICAgICAgY29uc3QgaG9va05hbWUgPSBgJHthdHRyaWJ1dGVOYW1lfUF0dHJpYnV0ZVNlbGVjdGVkYFxuICAgICAgY29uc3QgZHluYW1pY1Jlc291cmNlID0gLyoqXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKiBUeXBlcyB0aGUgZm9sbG93aW5nIHZhbHVlLlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBAdHlwZSB7UmVjb3JkPHN0cmluZywgPz59ICovICgvKipcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICogVHlwZXMgdGhlIGZvbGxvd2luZyB2YWx1ZS5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBAdHlwZSB7P30gKi8gKHJlc291cmNlKSlcblxuICAgICAgaWYgKHR5cGVvZiBkeW5hbWljUmVzb3VyY2VbaG9va05hbWVdID09PSBcImZ1bmN0aW9uXCIpIHtcbiAgICAgICAgY29uc3QgcmVzdWx0ID0gZHluYW1pY1Jlc291cmNlW2hvb2tOYW1lXSh7cXVlcnl9KVxuXG4gICAgICAgIGlmIChyZXN1bHQpIHtcbiAgICAgICAgICBxdWVyeSA9IHJlc3VsdFxuICAgICAgICB9XG4gICAgICB9IGVsc2UgaWYgKHRyYW5zbGF0ZWRTZXQuaGFzKGF0dHJpYnV0ZU5hbWUpKSB7XG4gICAgICAgIG5lZWRzVHJhbnNsYXRpb25zID0gdHJ1ZVxuICAgICAgfVxuICAgIH1cblxuICAgIGlmIChuZWVkc1RyYW5zbGF0aW9ucykge1xuICAgICAgcXVlcnkgPSBxdWVyeS5wcmVsb2FkKHt0cmFuc2xhdGlvbnM6IHt9fSlcbiAgICB9XG5cbiAgICByZXR1cm4gcXVlcnlcbiAgfVxuXG4gIC8qKlxuICAgKiBSdW5zIGFwcGx5IGZyb250ZW5kIG1vZGVsIHNvcnQuXG4gICAqIEBwYXJhbSB7b2JqZWN0fSBhcmdzIC0gU29ydCBhcmdzLlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4vZGF0YWJhc2UvcXVlcnkvbW9kZWwtY2xhc3MtcXVlcnkuanNcIikuZGVmYXVsdH0gYXJncy5xdWVyeSAtIFF1ZXJ5IGluc3RhbmNlLlxuICAgKiBAcGFyYW0ge0Zyb250ZW5kTW9kZWxTb3J0fSBhcmdzLnNvcnQgLSBTb3J0IGRlZmluaXRpb24uXG4gICAqIEByZXR1cm5zIHt2b2lkfVxuICAgKi9cbiAgYXBwbHlGcm9udGVuZE1vZGVsU29ydCh7cXVlcnksIHNvcnR9KSB7XG4gICAgY29uc3QgbW9kZWxDbGFzcyA9IHRoaXMuZnJvbnRlbmRNb2RlbENsYXNzKClcbiAgICBjb25zdCB0YXJnZXRNb2RlbENsYXNzID0gdGhpcy5mcm9udGVuZE1vZGVsU2VhcmNoVGFyZ2V0TW9kZWxDbGFzcyh7XG4gICAgICBtb2RlbENsYXNzLFxuICAgICAgcGF0aDogc29ydC5wYXRoXG4gICAgfSlcbiAgICBjb25zdCB0cmFuc2xhdGVkQXR0cmlidXRlc01hcCA9IHRhcmdldE1vZGVsQ2xhc3MuZ2V0VHJhbnNsYXRpb25zTWFwKClcbiAgICBjb25zdCB0cmFuc2xhdGVkQXR0cmlidXRlTmFtZXMgPSBPYmplY3Qua2V5cyh0cmFuc2xhdGVkQXR0cmlidXRlc01hcClcbiAgICBjb25zdCBpc1RyYW5zbGF0ZWRTb3J0QXR0cmlidXRlID0gdHJhbnNsYXRlZEF0dHJpYnV0ZU5hbWVzLmluY2x1ZGVzKHNvcnQuY29sdW1uKVxuXG4gICAgY29uc3QgY29sdW1uTmFtZSA9IHRoaXMucmVzb2x2ZUZyb250ZW5kTW9kZWxDb2x1bW5OYW1lKHRhcmdldE1vZGVsQ2xhc3MsIHNvcnQuY29sdW1uKVxuICAgIGNvbnN0IGRpcmVjdGlvbiA9IHNvcnQuZGlyZWN0aW9uLnRvVXBwZXJDYXNlKClcblxuICAgIGlmIChpc1RyYW5zbGF0ZWRTb3J0QXR0cmlidXRlKSB7XG4gICAgICBjb25zdCB0cmFuc2xhdGlvbk1vZGVsQ2xhc3MgPSB0YXJnZXRNb2RlbENsYXNzLmdldFRyYW5zbGF0aW9uQ2xhc3MoKVxuICAgICAgY29uc3QgdHJhbnNsYXRpb25BdHRyaWJ1dGVOYW1lVG9Db2x1bW5OYW1lTWFwID0gdHJhbnNsYXRpb25Nb2RlbENsYXNzLmdldEF0dHJpYnV0ZU5hbWVUb0NvbHVtbk5hbWVNYXAoKVxuICAgICAgY29uc3QgdHJhbnNsYXRpb25Db2x1bW5OYW1lID0gdHJhbnNsYXRpb25BdHRyaWJ1dGVOYW1lVG9Db2x1bW5OYW1lTWFwW3NvcnQuY29sdW1uXVxuICAgICAgY29uc3QgdHJhbnNsYXRpb25QYXRoID0gc29ydC5wYXRoLmNvbmNhdChbXCJjdXJyZW50VHJhbnNsYXRpb25cIl0pXG5cbiAgICAgIGlmICghdHJhbnNsYXRpb25Db2x1bW5OYW1lKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihgVW5rbm93biB0cmFuc2xhdGVkIHNvcnQgY29sdW1uIFwiJHtzb3J0LmNvbHVtbn1cIiBmb3IgJHt0YXJnZXRNb2RlbENsYXNzLm5hbWV9YClcbiAgICAgIH1cblxuICAgICAgdGhpcy5lbnN1cmVGcm9udGVuZE1vZGVsU29ydEpvaW5QYXRoKHtwYXRoOiB0cmFuc2xhdGlvblBhdGgsIHF1ZXJ5fSlcblxuICAgICAgY29uc3QgdHJhbnNsYXRpb25UYWJsZVJlZmVyZW5jZSA9IHF1ZXJ5LmdldFRhYmxlUmVmZXJlbmNlRm9ySm9pbiguLi50cmFuc2xhdGlvblBhdGgpXG4gICAgICBjb25zdCB0cmFuc2xhdGlvbkNvbHVtblNxbCA9IGAke3F1ZXJ5LmRyaXZlci5xdW90ZVRhYmxlKHRyYW5zbGF0aW9uVGFibGVSZWZlcmVuY2UpfS4ke3F1ZXJ5LmRyaXZlci5xdW90ZUNvbHVtbih0cmFuc2xhdGlvbkNvbHVtbk5hbWUpfWBcblxuICAgICAgcXVlcnkub3JkZXIoYCR7dHJhbnNsYXRpb25Db2x1bW5TcWx9ICR7ZGlyZWN0aW9ufWApXG5cbiAgICAgIHJldHVyblxuICAgIH1cblxuICAgIGlmICghY29sdW1uTmFtZSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKGBVbmtub3duIHNvcnQgY29sdW1uIFwiJHtzb3J0LmNvbHVtbn1cIiBmb3IgJHt0YXJnZXRNb2RlbENsYXNzLm5hbWV9YClcbiAgICB9XG5cbiAgICB0aGlzLmVuc3VyZUZyb250ZW5kTW9kZWxTb3J0Sm9pblBhdGgoe3BhdGg6IHNvcnQucGF0aCwgcXVlcnl9KVxuXG4gICAgY29uc3QgdGFibGVSZWZlcmVuY2UgPSBxdWVyeS5nZXRUYWJsZVJlZmVyZW5jZUZvckpvaW4oLi4uc29ydC5wYXRoKVxuICAgIGNvbnN0IGNvbHVtblNxbCA9IGAke3F1ZXJ5LmRyaXZlci5xdW90ZVRhYmxlKHRhYmxlUmVmZXJlbmNlKX0uJHtxdWVyeS5kcml2ZXIucXVvdGVDb2x1bW4oY29sdW1uTmFtZSl9YFxuXG4gICAgcXVlcnkub3JkZXIoYCR7Y29sdW1uU3FsfSAke2RpcmVjdGlvbn1gKVxuICB9XG5cbiAgLyoqXG4gICAqIEVuc3VyZXMgYSBzb3J0IGpvaW4gcGF0aCBoYXMgYmVlbiBqb2luZWQgb24gcXVlcnkuXG4gICAqIEBwYXJhbSB7b2JqZWN0fSBhcmdzIC0gSm9pbiBhcmdzLlxuICAgKiBAcGFyYW0ge3N0cmluZ1tdfSBhcmdzLnBhdGggLSBSZWxhdGlvbnNoaXAgam9pbiBwYXRoLlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4vZGF0YWJhc2UvcXVlcnkvbW9kZWwtY2xhc3MtcXVlcnkuanNcIikuZGVmYXVsdH0gYXJncy5xdWVyeSAtIFF1ZXJ5IGluc3RhbmNlLlxuICAgKiBAcmV0dXJucyB7dm9pZH1cbiAgICovXG4gIGVuc3VyZUZyb250ZW5kTW9kZWxTb3J0Sm9pblBhdGgoe3BhdGgsIHF1ZXJ5fSkge1xuICAgIHRoaXMuZW5zdXJlRnJvbnRlbmRNb2RlbEpvaW5QYXRoKHtwYXRoLCBxdWVyeX0pXG4gIH1cblxuICAvKipcbiAgICogRW5zdXJlcyBhIHJlbGF0aW9uc2hpcCBwYXRoIGhhcyBleGFjdGx5IG9uZSBTUUwgam9pbi5cbiAgICogQHBhcmFtIHtvYmplY3R9IGFyZ3MgLSBKb2luIGFyZ3MuXG4gICAqIEBwYXJhbSB7c3RyaW5nW119IGFyZ3MucGF0aCAtIFJlbGF0aW9uc2hpcCBqb2luIHBhdGguXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi9kYXRhYmFzZS9xdWVyeS9tb2RlbC1jbGFzcy1xdWVyeS5qc1wiKS5kZWZhdWx0fSBhcmdzLnF1ZXJ5IC0gUXVlcnkgaW5zdGFuY2UuXG4gICAqIEByZXR1cm5zIHt2b2lkfVxuICAgKi9cbiAgZW5zdXJlRnJvbnRlbmRNb2RlbEpvaW5QYXRoKHtwYXRoLCBxdWVyeX0pIHtcbiAgICBpZiAocGF0aC5sZW5ndGggPCAxKSByZXR1cm5cblxuICAgIGNvbnN0IHF1ZXJ5TWV0YWRhdGEgPSBmcm9udGVuZE1vZGVsUXVlcnlNZXRhZGF0YShxdWVyeSlcbiAgICBjb25zdCBqb2luZWRQYXRocyA9IHF1ZXJ5TWV0YWRhdGFbZnJvbnRlbmRNb2RlbEpvaW5lZFBhdGhzU3ltYm9sXSB8fCBuZXcgU2V0KClcbiAgICBjb25zdCBwYXRoS2V5ID0gcGF0aC5qb2luKFwiLlwiKVxuXG4gICAgaWYgKGpvaW5lZFBhdGhzLmhhcyhwYXRoS2V5KSkgcmV0dXJuXG5cbiAgICBxdWVyeS5qb2lucyhidWlsZEZyb250ZW5kTW9kZWxKb2luT2JqZWN0RnJvbVBhdGgocGF0aCkpXG4gICAgam9pbmVkUGF0aHMuYWRkKHBhdGhLZXkpXG4gICAgcXVlcnlNZXRhZGF0YVtmcm9udGVuZE1vZGVsSm9pbmVkUGF0aHNTeW1ib2xdID0gam9pbmVkUGF0aHNcbiAgfVxuXG4gIC8qKlxuICAgKiBSdW5zIGZyb250ZW5kIG1vZGVsIHNlbGVjdGVkIGF0dHJpYnV0ZXMgZm9yIG1vZGVsIGNsYXNzLlxuICAgKiBAcGFyYW0ge3R5cGVvZiBpbXBvcnQoXCIuL2RhdGFiYXNlL3JlY29yZC9pbmRleC5qc1wiKS5kZWZhdWx0fSBtb2RlbENsYXNzIC0gTW9kZWwgY2xhc3MuXG4gICAqIEByZXR1cm5zIHtzdHJpbmdbXSB8IG51bGx9IC0gU2VsZWN0ZWQgYXR0cmlidXRlcyBmb3IgbW9kZWwgY2xhc3MuXG4gICAqL1xuICBmcm9udGVuZE1vZGVsU2VsZWN0ZWRBdHRyaWJ1dGVzRm9yTW9kZWxDbGFzcyhtb2RlbENsYXNzKSB7XG4gICAgY29uc3Qgc2VsZWN0ID0gdGhpcy5mcm9udGVuZE1vZGVsU2VsZWN0KClcblxuICAgIGlmICghc2VsZWN0KSByZXR1cm4gbnVsbFxuXG4gICAgcmV0dXJuIHNlbGVjdFttb2RlbENsYXNzLmdldE1vZGVsTmFtZSgpXSB8fCBudWxsXG4gIH1cblxuICAvKipcbiAgICogUnVucyBmcm9udGVuZCBtb2RlbCBzZWxlY3RzIGV4dHJhIGZvciBtb2RlbCBjbGFzcy5cbiAgICogQHBhcmFtIHt0eXBlb2YgaW1wb3J0KFwiLi9kYXRhYmFzZS9yZWNvcmQvaW5kZXguanNcIikuZGVmYXVsdH0gbW9kZWxDbGFzcyAtIE1vZGVsIGNsYXNzLlxuICAgKiBAcmV0dXJucyB7c3RyaW5nW10gfCBudWxsfSAtIEV4dHJhIGF0dHJpYnV0ZXMgKGxvYWRlZCBpbiBhZGRpdGlvbiB0byB0aGUgZGVmYXVsdHMpIGZvciB0aGUgbW9kZWwgY2xhc3MuXG4gICAqL1xuICBmcm9udGVuZE1vZGVsU2VsZWN0c0V4dHJhRm9yTW9kZWxDbGFzcyhtb2RlbENsYXNzKSB7XG4gICAgY29uc3Qgc2VsZWN0c0V4dHJhID0gdGhpcy5mcm9udGVuZE1vZGVsU2VsZWN0c0V4dHJhKClcblxuICAgIGlmICghc2VsZWN0c0V4dHJhKSByZXR1cm4gbnVsbFxuXG4gICAgcmV0dXJuIHNlbGVjdHNFeHRyYVttb2RlbENsYXNzLmdldE1vZGVsTmFtZSgpXSB8fCBudWxsXG4gIH1cblxuICAvKipcbiAgICogUmVzb2x2ZXMgdGhlIGZpbmFsIHNldCBvZiBhdHRyaWJ1dGUgbmFtZXMgdG8gc2VyaWFsaXplIGZvciBhIG1vZGVsIGNsYXNzOlxuICAgKiBhbiBleHBsaWNpdCBuYXJyb3dpbmcgYHNlbGVjdGAgd2luczsgb3RoZXJ3aXNlLCB3aGVuIGBzZWxlY3RzRXh0cmFgIGlzIGdpdmVuLFxuICAgKiB0aGUgZGVmYXVsdCBhdHRyaWJ1dGVzIHBsdXMgdGhlIGV4dHJhczsgb3RoZXJ3aXNlIG51bGwgKGRlZmF1bHQgYmVoYXZpb3IpLlxuICAgKiBAcGFyYW0ge3R5cGVvZiBpbXBvcnQoXCIuL2RhdGFiYXNlL3JlY29yZC9pbmRleC5qc1wiKS5kZWZhdWx0fSBtb2RlbENsYXNzIC0gTW9kZWwgY2xhc3MuXG4gICAqIEBwYXJhbSB7c3RyaW5nW119IGZhbGxiYWNrQXR0cmlidXRlTmFtZXMgLSBBdHRyaWJ1dGUgbmFtZXMgdG8gdHJlYXQgYXMgdGhlIGRlZmF1bHRzIHdoZW4gdGhlIHJlc291cmNlIGRlY2xhcmVzIG5vbmUuXG4gICAqIEByZXR1cm5zIHtzdHJpbmdbXSB8IG51bGx9IC0gRWZmZWN0aXZlIHNlbGVjdGVkIGF0dHJpYnV0ZSBuYW1lcywgb3IgbnVsbCBmb3IgZGVmYXVsdCBzZXJpYWxpemF0aW9uLlxuICAgKi9cbiAgZnJvbnRlbmRNb2RlbEVmZmVjdGl2ZVNlbGVjdGVkQXR0cmlidXRlc0Zvck1vZGVsQ2xhc3MobW9kZWxDbGFzcywgZmFsbGJhY2tBdHRyaWJ1dGVOYW1lcykge1xuICAgIGNvbnN0IHNlbGVjdGVkQXR0cmlidXRlcyA9IHRoaXMuZnJvbnRlbmRNb2RlbFNlbGVjdGVkQXR0cmlidXRlc0Zvck1vZGVsQ2xhc3MobW9kZWxDbGFzcylcblxuICAgIGlmIChzZWxlY3RlZEF0dHJpYnV0ZXMpIHJldHVybiBzZWxlY3RlZEF0dHJpYnV0ZXNcblxuICAgIGNvbnN0IGV4dHJhQXR0cmlidXRlcyA9IHRoaXMuZnJvbnRlbmRNb2RlbFNlbGVjdHNFeHRyYUZvck1vZGVsQ2xhc3MobW9kZWxDbGFzcylcblxuICAgIGlmICghZXh0cmFBdHRyaWJ1dGVzKSByZXR1cm4gbnVsbFxuXG4gICAgY29uc3QgZGVmYXVsdEF0dHJpYnV0ZXMgPSB0aGlzLmZyb250ZW5kTW9kZWxEZWZhdWx0QXR0cmlidXRlc0Zvck1vZGVsQ2xhc3MobW9kZWxDbGFzcykgfHwgZmFsbGJhY2tBdHRyaWJ1dGVOYW1lc1xuXG4gICAgcmV0dXJuIEFycmF5LmZyb20obmV3IFNldChbLi4uZGVmYXVsdEF0dHJpYnV0ZXMsIC4uLmV4dHJhQXR0cmlidXRlc10pKVxuICB9XG5cbiAgLyoqXG4gICAqIFJ1bnMgZnJvbnRlbmQgbW9kZWwgZGVmYXVsdCBhdHRyaWJ1dGVzIGZvciBtb2RlbCBjbGFzcy5cbiAgICogQHBhcmFtIHt0eXBlb2YgaW1wb3J0KFwiLi9kYXRhYmFzZS9yZWNvcmQvaW5kZXguanNcIikuZGVmYXVsdH0gbW9kZWxDbGFzcyAtIE1vZGVsIGNsYXNzLlxuICAgKiBAcmV0dXJucyB7c3RyaW5nW10gfCBudWxsfSAtIERlZmF1bHQgZnJvbnRlbmQtbW9kZWwgYXR0cmlidXRlcyBkZWNsYXJlZCBvbiB0aGUgcmVzb3VyY2UuXG4gICAqL1xuICBmcm9udGVuZE1vZGVsRGVmYXVsdEF0dHJpYnV0ZXNGb3JNb2RlbENsYXNzKG1vZGVsQ2xhc3MpIHtcbiAgICBjb25zdCBmcm9udGVuZE1vZGVsUmVzb3VyY2UgPSB0aGlzLmZyb250ZW5kTW9kZWxSZXNvdXJjZUNvbmZpZ3VyYXRpb25Gb3JNb2RlbENsYXNzKG1vZGVsQ2xhc3MpXG4gICAgY29uc3QgYXR0cmlidXRlcyA9IGZyb250ZW5kTW9kZWxSZXNvdXJjZT8ucmVzb3VyY2VDb25maWd1cmF0aW9uLmF0dHJpYnV0ZXNcblxuICAgIGlmICghYXR0cmlidXRlcykgcmV0dXJuIG51bGxcblxuICAgIGlmIChBcnJheS5pc0FycmF5KGF0dHJpYnV0ZXMpKSB7XG4gICAgICByZXR1cm4gYXR0cmlidXRlc1xuICAgICAgICAuZmlsdGVyKChlbnRyeSkgPT4ge1xuICAgICAgICAgIGlmICh0eXBlb2YgZW50cnkgPT09IFwic3RyaW5nXCIpIHJldHVybiB0cnVlXG5cbiAgICAgICAgICBjb25zdCBjb25maWcgPSAvKipcbiAgICAgICAgICAgICAgICAgICAgICAgICAgKiBUeXBlcyB0aGUgZm9sbG93aW5nIHZhbHVlLlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgQHR5cGUge1JlY29yZDxzdHJpbmcsID8+fSAqLyAoZW50cnkpXG5cbiAgICAgICAgICBpZiAoY29uZmlnICYmIGNvbmZpZy5zZWxlY3RlZEJ5RGVmYXVsdCA9PT0gZmFsc2UpIHJldHVybiBmYWxzZVxuXG4gICAgICAgICAgcmV0dXJuIHRydWVcbiAgICAgICAgfSlcbiAgICAgICAgLm1hcCgoZW50cnkpID0+IHR5cGVvZiBlbnRyeSA9PT0gXCJzdHJpbmdcIiA/IGVudHJ5IDogLyoqXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKiBUeXBlcyB0aGUgZm9sbG93aW5nIHZhbHVlLlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBAdHlwZSB7UmVjb3JkPHN0cmluZywgPz59ICovIChlbnRyeSkubmFtZSlcbiAgICB9XG5cbiAgICBpZiAodHlwZW9mIGF0dHJpYnV0ZXMgPT09IFwib2JqZWN0XCIpIHtcbiAgICAgIHJldHVybiBPYmplY3QuZW50cmllcyhhdHRyaWJ1dGVzKVxuICAgICAgICAuZmlsdGVyKChbLCBjb25maWddKSA9PiB7XG4gICAgICAgICAgaWYgKCFjb25maWcgfHwgdHlwZW9mIGNvbmZpZyAhPT0gXCJvYmplY3RcIikgcmV0dXJuIHRydWVcblxuICAgICAgICAgIHJldHVybiAvKiogTmFycm93cyB0aGUgcnVudGltZSB2YWx1ZSB0byB0aGUgZG9jdW1lbnRlZCB0eXBlLiBAdHlwZSB7UmVjb3JkPHN0cmluZywgPz59ICovIChjb25maWcpLnNlbGVjdGVkQnlEZWZhdWx0ICE9PSBmYWxzZVxuICAgICAgICB9KVxuICAgICAgICAubWFwKChbbmFtZV0pID0+IG5hbWUpXG4gICAgfVxuXG4gICAgcmV0dXJuIG51bGxcbiAgfVxuXG4gIC8qKlxuICAgKiBSdW5zIGZyb250ZW5kIG1vZGVsIG5vbiBkZWZhdWx0IGF0dHJpYnV0ZXMgZm9yIG1vZGVsIGNsYXNzLlxuICAgKiBAcGFyYW0ge3R5cGVvZiBpbXBvcnQoXCIuL2RhdGFiYXNlL3JlY29yZC9pbmRleC5qc1wiKS5kZWZhdWx0fSBtb2RlbENsYXNzIC0gTW9kZWwgY2xhc3MuXG4gICAqIEByZXR1cm5zIHtzdHJpbmdbXX0gLSBBdHRyaWJ1dGUgbmFtZXMgZXhwbGljaXRseSBtYXJrZWQgc2VsZWN0ZWRCeURlZmF1bHQ6IGZhbHNlLlxuICAgKi9cbiAgZnJvbnRlbmRNb2RlbE5vbkRlZmF1bHRBdHRyaWJ1dGVzRm9yTW9kZWxDbGFzcyhtb2RlbENsYXNzKSB7XG4gICAgY29uc3QgZnJvbnRlbmRNb2RlbFJlc291cmNlID0gdGhpcy5mcm9udGVuZE1vZGVsUmVzb3VyY2VDb25maWd1cmF0aW9uRm9yTW9kZWxDbGFzcyhtb2RlbENsYXNzKVxuICAgIGNvbnN0IGF0dHJpYnV0ZXMgPSBmcm9udGVuZE1vZGVsUmVzb3VyY2U/LnJlc291cmNlQ29uZmlndXJhdGlvbi5hdHRyaWJ1dGVzXG5cbiAgICBpZiAoIWF0dHJpYnV0ZXMpIHJldHVybiBbXVxuXG4gICAgaWYgKEFycmF5LmlzQXJyYXkoYXR0cmlidXRlcykpIHtcbiAgICAgIHJldHVybiBhdHRyaWJ1dGVzXG4gICAgICAgIC5maWx0ZXIoKGVudHJ5KSA9PiB7XG4gICAgICAgICAgaWYgKHR5cGVvZiBlbnRyeSAhPT0gXCJvYmplY3RcIiB8fCAhZW50cnkpIHJldHVybiBmYWxzZVxuXG4gICAgICAgICAgcmV0dXJuIC8qKiBOYXJyb3dzIHRoZSBydW50aW1lIHZhbHVlIHRvIHRoZSBkb2N1bWVudGVkIHR5cGUuIEB0eXBlIHtSZWNvcmQ8c3RyaW5nLCA/Pn0gKi8gKGVudHJ5KS5zZWxlY3RlZEJ5RGVmYXVsdCA9PT0gZmFsc2VcbiAgICAgICAgfSlcbiAgICAgICAgLm1hcCgoZW50cnkpID0+IC8qKlxuICAgICAgICAgICAgICAgICAgICAgICAgICogVHlwZXMgdGhlIGZvbGxvd2luZyB2YWx1ZS5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgQHR5cGUge1JlY29yZDxzdHJpbmcsID8+fSAqLyAoLyoqXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqIFR5cGVzIHRoZSBmb2xsb3dpbmcgdmFsdWUuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQHR5cGUgez99ICovIChlbnRyeSkpLm5hbWUpXG4gICAgfVxuXG4gICAgaWYgKHR5cGVvZiBhdHRyaWJ1dGVzID09PSBcIm9iamVjdFwiKSB7XG4gICAgICByZXR1cm4gT2JqZWN0LmVudHJpZXMoYXR0cmlidXRlcylcbiAgICAgICAgLmZpbHRlcigoWywgY29uZmlnXSkgPT4gdHlwZW9mIGNvbmZpZyA9PT0gXCJvYmplY3RcIiAmJiBjb25maWcgJiYgLyoqXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKiBUeXBlcyB0aGUgZm9sbG93aW5nIHZhbHVlLlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBAdHlwZSB7UmVjb3JkPHN0cmluZywgPz59ICovIChjb25maWcpLnNlbGVjdGVkQnlEZWZhdWx0ID09PSBmYWxzZSlcbiAgICAgICAgLm1hcCgoW25hbWVdKSA9PiBuYW1lKVxuICAgIH1cblxuICAgIHJldHVybiBbXVxuICB9XG5cbiAgLyoqXG4gICAqIFJ1bnMgc2VyaWFsaXplIGZyb250ZW5kIG1vZGVsIGF0dHJpYnV0ZXMuXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi9kYXRhYmFzZS9yZWNvcmQvaW5kZXguanNcIikuZGVmYXVsdH0gbW9kZWwgLSBNb2RlbCBpbnN0YW5jZS5cbiAgICogQHJldHVybnMge1Byb21pc2U8UmVjb3JkPHN0cmluZywgPz4+fSAtIFNlcmlhbGl6ZWQgYXR0cmlidXRlcyBmaWx0ZXJlZCBieSBzZWxlY3QgbWFwLlxuICAgKi9cbiAgYXN5bmMgc2VyaWFsaXplRnJvbnRlbmRNb2RlbEF0dHJpYnV0ZXMobW9kZWwpIHtcbiAgICBjb25zdCBtb2RlbENsYXNzID0gLyoqXG4gICAgICAgICAgICAgICAgICAgICAgICAqIFR5cGVzIHRoZSBmb2xsb3dpbmcgdmFsdWUuXG4gICAgICAgICAgICAgICAgICAgICAgICAgQHR5cGUge3R5cGVvZiBpbXBvcnQoXCIuL2RhdGFiYXNlL3JlY29yZC9pbmRleC5qc1wiKS5kZWZhdWx0fSAqLyAobW9kZWwuY29uc3RydWN0b3IpXG4gICAgY29uc3QgbW9kZWxBdHRyaWJ1dGVzID0gbW9kZWwuYXR0cmlidXRlcygpXG4gICAgY29uc3Qgc2VsZWN0ZWRBdHRyaWJ1dGVzID0gdGhpcy5mcm9udGVuZE1vZGVsRWZmZWN0aXZlU2VsZWN0ZWRBdHRyaWJ1dGVzRm9yTW9kZWxDbGFzcyhtb2RlbENsYXNzLCBPYmplY3Qua2V5cyhtb2RlbEF0dHJpYnV0ZXMpKVxuICAgIGNvbnN0IGRlZmF1bHRBdHRyaWJ1dGVzID0gdGhpcy5mcm9udGVuZE1vZGVsRGVmYXVsdEF0dHJpYnV0ZXNGb3JNb2RlbENsYXNzKG1vZGVsQ2xhc3MpXG4gICAgY29uc3QgcmVzb3VyY2VJbnN0YW5jZSA9IHRoaXMuX3NlcmlhbGl6YXRpb25SZXNvdXJjZUluc3RhbmNlRm9yTW9kZWwobW9kZWwpXG5cbiAgICAvKipcbiAgICAgKiBSZXNvdXJjZSBhdHRyaWJ1dGUgbWV0aG9kIG5hbWUuXG4gICAgICogQHBhcmFtIHtzdHJpbmd9IGF0dHJpYnV0ZU5hbWUgLSBBdHRyaWJ1dGUgbmFtZS5cbiAgICAgKi9cbiAgICBjb25zdCByZXNvdXJjZUF0dHJpYnV0ZU1ldGhvZE5hbWUgPSAoYXR0cmlidXRlTmFtZSkgPT4gYCR7YXR0cmlidXRlTmFtZX1BdHRyaWJ1dGVgXG5cbiAgICAvKipcbiAgICAgKiBSZXNvdXJjZSBoYXMgYXR0cmlidXRlLlxuICAgICAqIEBwYXJhbSB7c3RyaW5nfSBhdHRyaWJ1dGVOYW1lIC0gQXR0cmlidXRlIG5hbWUuXG4gICAgICovXG4gICAgY29uc3QgcmVzb3VyY2VIYXNBdHRyaWJ1dGUgPSAoYXR0cmlidXRlTmFtZSkgPT4ge1xuICAgICAgY29uc3QgbWV0aG9kTmFtZSA9IHJlc291cmNlQXR0cmlidXRlTWV0aG9kTmFtZShhdHRyaWJ1dGVOYW1lKVxuXG4gICAgICByZXR1cm4gcmVzb3VyY2VJbnN0YW5jZSAmJiB0eXBlb2YgLyoqXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICogVHlwZXMgdGhlIGZvbGxvd2luZyB2YWx1ZS5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEB0eXBlIHtSZWNvcmQ8c3RyaW5nLCA/Pn0gKi8gKC8qKlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICogVHlwZXMgdGhlIGZvbGxvd2luZyB2YWx1ZS5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQHR5cGUgez99ICovIChyZXNvdXJjZUluc3RhbmNlKSlbbWV0aG9kTmFtZV0gPT09IFwiZnVuY3Rpb25cIlxuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFByb3RvdHlwZSBhdHRyaWJ1dGUgbWV0aG9kLlxuICAgICAqIEBwYXJhbSB7c3RyaW5nfSBhdHRyaWJ1dGVOYW1lIC0gQXR0cmlidXRlIG5hbWUuXG4gICAgICovXG4gICAgY29uc3QgcHJvdG90eXBlQXR0cmlidXRlTWV0aG9kID0gKGF0dHJpYnV0ZU5hbWUpID0+IHtcbiAgICAgIGxldCBjdXJyZW50UHJvdG90eXBlID0gT2JqZWN0LmdldFByb3RvdHlwZU9mKG1vZGVsKVxuXG4gICAgICB3aGlsZSAoY3VycmVudFByb3RvdHlwZSAmJiBjdXJyZW50UHJvdG90eXBlICE9PSBPYmplY3QucHJvdG90eXBlKSB7XG4gICAgICAgIGNvbnN0IGNhbmRpZGF0ZSA9IE9iamVjdC5nZXRPd25Qcm9wZXJ0eURlc2NyaXB0b3IoY3VycmVudFByb3RvdHlwZSwgYXR0cmlidXRlTmFtZSk/LnZhbHVlXG5cbiAgICAgICAgaWYgKHR5cGVvZiBjYW5kaWRhdGUgPT09IFwiZnVuY3Rpb25cIikge1xuICAgICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICBtZXRob2Q6IGNhbmRpZGF0ZSxcbiAgICAgICAgICAgIG93bmVyTmFtZTogY3VycmVudFByb3RvdHlwZS5jb25zdHJ1Y3Rvcj8ubmFtZVxuICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIGN1cnJlbnRQcm90b3R5cGUgPSBPYmplY3QuZ2V0UHJvdG90eXBlT2YoY3VycmVudFByb3RvdHlwZSlcbiAgICAgIH1cbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBTZXJpYWxpemVkIGF0dHJpYnV0ZSB2YWx1ZS5cbiAgICAgKiBAcGFyYW0ge3N0cmluZ30gYXR0cmlidXRlTmFtZSAtIEF0dHJpYnV0ZSBuYW1lLlxuICAgICAqL1xuICAgIGNvbnN0IHNlcmlhbGl6ZWRBdHRyaWJ1dGVWYWx1ZSA9IGFzeW5jIChhdHRyaWJ1dGVOYW1lKSA9PiB7XG4gICAgICAvLyBDaGVjayByZXNvdXJjZSBpbnN0YW5jZSBmaXJzdCAodmlydHVhbC9jb21wdXRlZCBhdHRyaWJ1dGVzIHZpYSAke25hbWV9QXR0cmlidXRlIGNvbnZlbnRpb24pXG4gICAgICBpZiAocmVzb3VyY2VIYXNBdHRyaWJ1dGUoYXR0cmlidXRlTmFtZSkpIHtcbiAgICAgICAgY29uc3QgbWV0aG9kTmFtZSA9IHJlc291cmNlQXR0cmlidXRlTWV0aG9kTmFtZShhdHRyaWJ1dGVOYW1lKVxuXG4gICAgICAgIHJldHVybiBhd2FpdCAvKipcbiAgICAgICAgICAgICAgICAgICAgICAqIFR5cGVzIHRoZSBmb2xsb3dpbmcgdmFsdWUuXG4gICAgICAgICAgICAgICAgICAgICAgIEB0eXBlIHtSZWNvcmQ8c3RyaW5nLCBGdW5jdGlvbj59ICovICgvKipcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqIFR5cGVzIHRoZSBmb2xsb3dpbmcgdmFsdWUuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEB0eXBlIHs/fSAqLyAocmVzb3VyY2VJbnN0YW5jZSkpW21ldGhvZE5hbWVdKG1vZGVsKVxuICAgICAgfVxuXG4gICAgICAvLyBGYWxsIGJhY2sgdG8gbW9kZWwgbWV0aG9kXG4gICAgICBjb25zdCBhdHRyaWJ1dGVNZXRob2RMb29rdXAgPSBwcm90b3R5cGVBdHRyaWJ1dGVNZXRob2QoYXR0cmlidXRlTmFtZSlcbiAgICAgIGNvbnN0IGF0dHJpYnV0ZU1ldGhvZCA9IGF0dHJpYnV0ZU1ldGhvZExvb2t1cD8ubWV0aG9kXG5cbiAgICAgIGlmICh0eXBlb2YgYXR0cmlidXRlTWV0aG9kID09PSBcImZ1bmN0aW9uXCIpIHtcbiAgICAgICAgcmV0dXJuIGF3YWl0IGF0dHJpYnV0ZU1ldGhvZC5jYWxsKG1vZGVsKVxuICAgICAgfVxuXG4gICAgICByZXR1cm4gbW9kZWxBdHRyaWJ1dGVzW2F0dHJpYnV0ZU5hbWVdXG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQXR0cmlidXRlIGV4aXN0cy5cbiAgICAgKiBAcGFyYW0ge3N0cmluZ30gYXR0cmlidXRlTmFtZSAtIEF0dHJpYnV0ZSBuYW1lLlxuICAgICAqL1xuICAgIGNvbnN0IGF0dHJpYnV0ZUV4aXN0cyA9IChhdHRyaWJ1dGVOYW1lKSA9PiB7XG4gICAgICByZXR1cm4gKGF0dHJpYnV0ZU5hbWUgaW4gbW9kZWxBdHRyaWJ1dGVzKSB8fCAoYXR0cmlidXRlTmFtZSBpbiAvKipcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqIFR5cGVzIHRoZSBmb2xsb3dpbmcgdmFsdWUuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEB0eXBlIHtSZWNvcmQ8c3RyaW5nLCA/Pn0gKi8gKG1vZGVsKSkgfHwgcmVzb3VyY2VIYXNBdHRyaWJ1dGUoYXR0cmlidXRlTmFtZSlcbiAgICB9XG5cbiAgICBpZiAoIXNlbGVjdGVkQXR0cmlidXRlcykge1xuICAgICAgaWYgKCFkZWZhdWx0QXR0cmlidXRlcyB8fCBkZWZhdWx0QXR0cmlidXRlcy5sZW5ndGggPCAxKSB7XG4gICAgICAgIHJldHVybiBtb2RlbEF0dHJpYnV0ZXNcbiAgICAgIH1cblxuICAgICAgY29uc3QgZXhjbHVkZWRBdHRyaWJ1dGVzID0gdGhpcy5mcm9udGVuZE1vZGVsTm9uRGVmYXVsdEF0dHJpYnV0ZXNGb3JNb2RlbENsYXNzKG1vZGVsQ2xhc3MpXG4gICAgICBjb25zdCBzZXJpYWxpemVkQXR0cmlidXRlcyA9IHsuLi5tb2RlbEF0dHJpYnV0ZXN9XG5cbiAgICAgIGZvciAoY29uc3QgZXhjbHVkZWROYW1lIG9mIGV4Y2x1ZGVkQXR0cmlidXRlcykge1xuICAgICAgICBkZWxldGUgc2VyaWFsaXplZEF0dHJpYnV0ZXNbZXhjbHVkZWROYW1lXVxuICAgICAgfVxuXG4gICAgICBmb3IgKGNvbnN0IGF0dHJpYnV0ZU5hbWUgb2YgZGVmYXVsdEF0dHJpYnV0ZXMpIHtcbiAgICAgICAgaWYgKCFhdHRyaWJ1dGVFeGlzdHMoYXR0cmlidXRlTmFtZSkpIGNvbnRpbnVlXG4gICAgICAgIHNlcmlhbGl6ZWRBdHRyaWJ1dGVzW2F0dHJpYnV0ZU5hbWVdID0gYXdhaXQgc2VyaWFsaXplZEF0dHJpYnV0ZVZhbHVlKGF0dHJpYnV0ZU5hbWUpXG4gICAgICB9XG5cbiAgICAgIHJldHVybiBzZXJpYWxpemVkQXR0cmlidXRlc1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFNlcmlhbGl6ZWQgYXR0cmlidXRlcy5cbiAgICAgIEB0eXBlIHtSZWNvcmQ8c3RyaW5nLCA/Pn0gKi9cbiAgICBjb25zdCBzZXJpYWxpemVkQXR0cmlidXRlcyA9IHt9XG5cbiAgICBmb3IgKGNvbnN0IGF0dHJpYnV0ZU5hbWUgb2Ygc2VsZWN0ZWRBdHRyaWJ1dGVzKSB7XG4gICAgICBpZiAoIWF0dHJpYnV0ZUV4aXN0cyhhdHRyaWJ1dGVOYW1lKSkgY29udGludWVcbiAgICAgIHNlcmlhbGl6ZWRBdHRyaWJ1dGVzW2F0dHJpYnV0ZU5hbWVdID0gYXdhaXQgc2VyaWFsaXplZEF0dHJpYnV0ZVZhbHVlKGF0dHJpYnV0ZU5hbWUpXG4gICAgfVxuXG4gICAgcmV0dXJuIHNlcmlhbGl6ZWRBdHRyaWJ1dGVzXG4gIH1cblxuICAvKipcbiAgICogUnVucyBzZXJpYWxpemF0aW9uIHJlc291cmNlIGluc3RhbmNlIGZvciBtb2RlbC5cbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuL2RhdGFiYXNlL3JlY29yZC9pbmRleC5qc1wiKS5kZWZhdWx0fSBtb2RlbCAtIE1vZGVsIGluc3RhbmNlLlxuICAgKiBAcmV0dXJucyB7aW1wb3J0KFwiLi9mcm9udGVuZC1tb2RlbC1yZXNvdXJjZS9iYXNlLXJlc291cmNlLmpzXCIpLmRlZmF1bHQgfCBudWxsfSAtIFJlc291cmNlIGluc3RhbmNlIG9yIG51bGwuXG4gICAqL1xuICBfc2VyaWFsaXphdGlvblJlc291cmNlSW5zdGFuY2VGb3JNb2RlbChtb2RlbCkge1xuICAgIGNvbnN0IHJlc291cmNlID0gdGhpcy5mcm9udGVuZE1vZGVsUmVzb3VyY2VJbnN0YW5jZSgpXG5cbiAgICBpZiAocmVzb3VyY2UubW9kZWxDbGFzcygpID09PSBtb2RlbC5jb25zdHJ1Y3Rvcikge1xuICAgICAgcmV0dXJuIHJlc291cmNlXG4gICAgfVxuXG4gICAgY29uc3QgY29uZmlndXJhdGlvbiA9IHRoaXMuZ2V0Q29uZmlndXJhdGlvbigpXG4gICAgY29uc3QgYmFja2VuZFByb2plY3RzID0gY29uZmlndXJhdGlvbi5nZXRCYWNrZW5kUHJvamVjdHM/LigpIHx8IFtdXG4gICAgY29uc3QgbW9kZWxDbGFzc05hbWUgPSAvKipcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAqIFR5cGVzIHRoZSBmb2xsb3dpbmcgdmFsdWUuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgIEB0eXBlIHt0eXBlb2YgaW1wb3J0KFwiLi9kYXRhYmFzZS9yZWNvcmQvaW5kZXguanNcIikuZGVmYXVsdH0gKi8gKG1vZGVsLmNvbnN0cnVjdG9yKS5nZXRNb2RlbE5hbWUoKVxuXG4gICAgZm9yIChjb25zdCBiYWNrZW5kUHJvamVjdCBvZiBiYWNrZW5kUHJvamVjdHMpIHtcbiAgICAgIGNvbnN0IHJlc291cmNlcyA9IGZyb250ZW5kTW9kZWxSZXNvdXJjZXNGb3JCYWNrZW5kUHJvamVjdChiYWNrZW5kUHJvamVjdClcbiAgICAgIGNvbnN0IHJlc291cmNlRGVmaW5pdGlvbiA9IHJlc291cmNlc1ttb2RlbENsYXNzTmFtZV1cbiAgICAgIGNvbnN0IHJlc291cmNlQ2xhc3MgPSByZXNvdXJjZURlZmluaXRpb24gPyBmcm9udGVuZE1vZGVsUmVzb3VyY2VDbGFzc0Zyb21EZWZpbml0aW9uKHJlc291cmNlRGVmaW5pdGlvbikgOiBudWxsXG5cbiAgICAgIGlmIChyZXNvdXJjZUNsYXNzKSB7XG4gICAgICAgIHJldHVybiBuZXcgcmVzb3VyY2VDbGFzcyh7XG4gICAgICAgICAgYWJpbGl0eTogdGhpcy5jdXJyZW50QWJpbGl0eSgpLFxuICAgICAgICAgIGNvbnRleHQ6IHRoaXMuY3VycmVudEFiaWxpdHkoKT8uZ2V0Q29udGV4dCgpIHx8IHt9LFxuICAgICAgICAgIGxvY2FsczogdGhpcy5jdXJyZW50QWJpbGl0eSgpPy5nZXRMb2NhbHMoKSB8fCB7fSxcbiAgICAgICAgICBtb2RlbENsYXNzOiAvKipcbiAgICAgICAgICAgICAgICAgICAgICAgKiBUeXBlcyB0aGUgZm9sbG93aW5nIHZhbHVlLlxuICAgICAgICAgICAgICAgICAgICAgICAgQHR5cGUge3R5cGVvZiBpbXBvcnQoXCIuL2RhdGFiYXNlL3JlY29yZC9pbmRleC5qc1wiKS5kZWZhdWx0fSAqLyAobW9kZWwuY29uc3RydWN0b3IpLFxuICAgICAgICAgIG1vZGVsTmFtZTogbW9kZWxDbGFzc05hbWUsXG4gICAgICAgICAgcGFyYW1zOiB7fSxcbiAgICAgICAgICByZXNvdXJjZUNvbmZpZ3VyYXRpb246IC8qKlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICogVHlwZXMgdGhlIGZvbGxvd2luZyB2YWx1ZS5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQHR5cGUge2ltcG9ydChcIi4vY29uZmlndXJhdGlvbi10eXBlcy5qc1wiKS5Gcm9udGVuZE1vZGVsUmVzb3VyY2VDb25maWd1cmF0aW9uIHwgdW5kZWZpbmVkfSAqLyAodHlwZW9mIHJlc291cmNlQ2xhc3MucmVzb3VyY2VDb25maWcgPT09IFwiZnVuY3Rpb25cIiA/IHJlc291cmNlQ2xhc3MucmVzb3VyY2VDb25maWcoKSA6IHVuZGVmaW5lZClcbiAgICAgICAgfSlcbiAgICAgIH1cbiAgICB9XG5cbiAgICByZXR1cm4gbnVsbFxuICB9XG5cbiAgLyoqXG4gICAqIFJ1bnMgZnJvbnRlbmQgbW9kZWwgZmlsdGVyIHNlcmlhbGl6YWJsZSByZWxhdGVkIG1vZGVscy5cbiAgICogQHBhcmFtIHtvYmplY3R9IGFyZ3MgLSBBcmd1bWVudHMuXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi9kYXRhYmFzZS9yZWNvcmQvaW5kZXguanNcIikuZGVmYXVsdFtdfSBhcmdzLm1vZGVscyAtIEZyb250ZW5kIG1vZGVsIHJlY29yZHMuXG4gICAqIEBwYXJhbSB7Ym9vbGVhbn0gYXJncy5yZWxhdGlvbnNoaXBJc0NvbGxlY3Rpb24gLSBXaGV0aGVyIHJlbGF0aW9uIGlzIGhhcy1tYW55LlxuICAgKiBAcmV0dXJucyB7UHJvbWlzZTxpbXBvcnQoXCIuL2RhdGFiYXNlL3JlY29yZC9pbmRleC5qc1wiKS5kZWZhdWx0W10+fSAtIFNlcmlhbGl6YWJsZSByZWxhdGVkIG1vZGVscy5cbiAgICovXG4gIGFzeW5jIGZyb250ZW5kTW9kZWxGaWx0ZXJTZXJpYWxpemFibGVSZWxhdGVkTW9kZWxzKHttb2RlbHMsIHJlbGF0aW9uc2hpcElzQ29sbGVjdGlvbn0pIHtcbiAgICBpZiAoIXRoaXMuY3VycmVudEFiaWxpdHkoKSkgcmV0dXJuIG1vZGVsc1xuICAgIGlmIChtb2RlbHMubGVuZ3RoID09PSAwKSByZXR1cm4gbW9kZWxzXG5cbiAgICAvKipcbiAgICAgKiBNb2RlbHMgYnkgY2xhc3MuXG4gICAgICBAdHlwZSB7TWFwPHR5cGVvZiBpbXBvcnQoXCIuL2RhdGFiYXNlL3JlY29yZC9pbmRleC5qc1wiKS5kZWZhdWx0LCBpbXBvcnQoXCIuL2RhdGFiYXNlL3JlY29yZC9pbmRleC5qc1wiKS5kZWZhdWx0W10+fSAqL1xuICAgIGNvbnN0IG1vZGVsc0J5Q2xhc3MgPSBuZXcgTWFwKClcblxuICAgIGZvciAoY29uc3QgbW9kZWwgb2YgbW9kZWxzKSB7XG4gICAgICBjb25zdCByZWxhdGVkTW9kZWxDbGFzcyA9IC8qKlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKiBUeXBlcyB0aGUgZm9sbG93aW5nIHZhbHVlLlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEB0eXBlIHt0eXBlb2YgaW1wb3J0KFwiLi9kYXRhYmFzZS9yZWNvcmQvaW5kZXguanNcIikuZGVmYXVsdH0gKi8gKG1vZGVsLmNvbnN0cnVjdG9yKVxuICAgICAgY29uc3QgZXhpc3RpbmdNb2RlbHNGb3JDbGFzcyA9IG1vZGVsc0J5Q2xhc3MuZ2V0KHJlbGF0ZWRNb2RlbENsYXNzKSB8fCBbXVxuXG4gICAgICBleGlzdGluZ01vZGVsc0ZvckNsYXNzLnB1c2gobW9kZWwpXG4gICAgICBtb2RlbHNCeUNsYXNzLnNldChyZWxhdGVkTW9kZWxDbGFzcywgZXhpc3RpbmdNb2RlbHNGb3JDbGFzcylcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBBdXRob3JpemVkIGlkcyBieSBjbGFzcy5cbiAgICAgIEB0eXBlIHtNYXA8dHlwZW9mIGltcG9ydChcIi4vZGF0YWJhc2UvcmVjb3JkL2luZGV4LmpzXCIpLmRlZmF1bHQsIFNldDxzdHJpbmc+Pn0gKi9cbiAgICBjb25zdCBhdXRob3JpemVkSWRzQnlDbGFzcyA9IG5ldyBNYXAoKVxuICAgIC8qKlxuICAgICAqIFByaW1hcnkga2V5cyBieSBjbGFzcy5cbiAgICAgIEB0eXBlIHtNYXA8dHlwZW9mIGltcG9ydChcIi4vZGF0YWJhc2UvcmVjb3JkL2luZGV4LmpzXCIpLmRlZmF1bHQsIHN0cmluZz59ICovXG4gICAgY29uc3QgcHJpbWFyeUtleXNCeUNsYXNzID0gbmV3IE1hcCgpXG5cbiAgICBmb3IgKGNvbnN0IFtyZWxhdGVkTW9kZWxDbGFzcywgcmVsYXRlZE1vZGVsc10gb2YgbW9kZWxzQnlDbGFzcy5lbnRyaWVzKCkpIHtcbiAgICAgIGNvbnN0IHJlbGF0ZWRSZXNvdXJjZSA9IHRoaXMuZnJvbnRlbmRNb2RlbFJlc291cmNlQ29uZmlndXJhdGlvbkZvck1vZGVsQ2xhc3MocmVsYXRlZE1vZGVsQ2xhc3MpXG5cbiAgICAgIGlmICghcmVsYXRlZFJlc291cmNlKSB7XG4gICAgICAgIGF1dGhvcml6ZWRJZHNCeUNsYXNzLnNldChyZWxhdGVkTW9kZWxDbGFzcywgbmV3IFNldCgpKVxuICAgICAgICBjb250aW51ZVxuICAgICAgfVxuXG4gICAgICBjb25zdCBhYmlsaXR5QWN0aW9uID0gcmVsYXRpb25zaGlwSXNDb2xsZWN0aW9uXG4gICAgICAgID8gcmVsYXRlZFJlc291cmNlLnJlc291cmNlQ29uZmlndXJhdGlvbi5hYmlsaXRpZXM/LmluZGV4XG4gICAgICAgIDogcmVsYXRlZFJlc291cmNlLnJlc291cmNlQ29uZmlndXJhdGlvbi5hYmlsaXRpZXM/LmZpbmRcblxuICAgICAgaWYgKHR5cGVvZiBhYmlsaXR5QWN0aW9uICE9PSBcInN0cmluZ1wiIHx8IGFiaWxpdHlBY3Rpb24ubGVuZ3RoIDwgMSkge1xuICAgICAgICBhdXRob3JpemVkSWRzQnlDbGFzcy5zZXQocmVsYXRlZE1vZGVsQ2xhc3MsIG5ldyBTZXQoKSlcbiAgICAgICAgY29udGludWVcbiAgICAgIH1cblxuICAgICAgY29uc3QgcHJpbWFyeUtleSA9IHJlbGF0ZWRNb2RlbENsYXNzLnByaW1hcnlLZXkoKVxuICAgICAgY29uc3QgaWRzID0gcmVsYXRlZE1vZGVsc1xuICAgICAgICAubWFwKChtb2RlbCkgPT4gbW9kZWwuYXR0cmlidXRlcygpW3ByaW1hcnlLZXldKVxuICAgICAgICAuZmlsdGVyKChpZCkgPT4gaWQgIT09IHVuZGVmaW5lZCAmJiBpZCAhPT0gbnVsbClcblxuICAgICAgaWYgKGlkcy5sZW5ndGggPCAxKSB7XG4gICAgICAgIGF1dGhvcml6ZWRJZHNCeUNsYXNzLnNldChyZWxhdGVkTW9kZWxDbGFzcywgbmV3IFNldCgpKVxuICAgICAgICBjb250aW51ZVxuICAgICAgfVxuXG4gICAgICBjb25zdCBhdXRob3JpemVkSWRzUmF3ID0gYXdhaXQgcmVsYXRlZE1vZGVsQ2xhc3NcbiAgICAgICAgLmFjY2Vzc2libGVGb3IoYWJpbGl0eUFjdGlvbilcbiAgICAgICAgLndoZXJlKHtbcHJpbWFyeUtleV06IGlkc30pXG4gICAgICAgIC5wbHVjayhwcmltYXJ5S2V5KVxuXG4gICAgICBwcmltYXJ5S2V5c0J5Q2xhc3Muc2V0KHJlbGF0ZWRNb2RlbENsYXNzLCBwcmltYXJ5S2V5KVxuICAgICAgYXV0aG9yaXplZElkc0J5Q2xhc3Muc2V0KHJlbGF0ZWRNb2RlbENsYXNzLCBuZXcgU2V0KGF1dGhvcml6ZWRJZHNSYXcubWFwKChpZCkgPT4gU3RyaW5nKGlkKSkpKVxuICAgIH1cblxuICAgIHJldHVybiBtb2RlbHMuZmlsdGVyKChtb2RlbCkgPT4ge1xuICAgICAgY29uc3QgcmVsYXRlZE1vZGVsQ2xhc3MgPSAvKipcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICogVHlwZXMgdGhlIGZvbGxvd2luZyB2YWx1ZS5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBAdHlwZSB7dHlwZW9mIGltcG9ydChcIi4vZGF0YWJhc2UvcmVjb3JkL2luZGV4LmpzXCIpLmRlZmF1bHR9ICovIChtb2RlbC5jb25zdHJ1Y3RvcilcbiAgICAgIGNvbnN0IGF1dGhvcml6ZWRJZHMgPSBhdXRob3JpemVkSWRzQnlDbGFzcy5nZXQocmVsYXRlZE1vZGVsQ2xhc3MpXG4gICAgICBjb25zdCBwcmltYXJ5S2V5ID0gcHJpbWFyeUtleXNCeUNsYXNzLmdldChyZWxhdGVkTW9kZWxDbGFzcylcblxuICAgICAgaWYgKCFhdXRob3JpemVkSWRzIHx8ICFwcmltYXJ5S2V5KSByZXR1cm4gZmFsc2VcblxuICAgICAgY29uc3QgcHJpbWFyeUtleVZhbHVlID0gbW9kZWwuYXR0cmlidXRlcygpW3ByaW1hcnlLZXldXG5cbiAgICAgIGlmIChwcmltYXJ5S2V5VmFsdWUgPT09IHVuZGVmaW5lZCB8fCBwcmltYXJ5S2V5VmFsdWUgPT09IG51bGwpIHJldHVybiBmYWxzZVxuXG4gICAgICByZXR1cm4gYXV0aG9yaXplZElkcy5oYXMoU3RyaW5nKHByaW1hcnlLZXlWYWx1ZSkpXG4gICAgfSlcbiAgfVxuXG4gIC8qKlxuICAgKiBSdW5zIGlzIHNlcmlhbGl6YWJsZSBmcm9udGVuZCBtb2RlbC5cbiAgICogQHBhcmFtIHs/fSB2YWx1ZSAtIENhbmRpZGF0ZSBwcmVsb2FkZWQgdmFsdWUuXG4gICAqIEByZXR1cm5zIHt2YWx1ZSBpcyBpbXBvcnQoXCIuL2RhdGFiYXNlL3JlY29yZC9pbmRleC5qc1wiKS5kZWZhdWx0fSAtIFdoZXRoZXIgdmFsdWUgYmVoYXZlcyBsaWtlIGEgbW9kZWwuXG4gICAqL1xuICBpc1NlcmlhbGl6YWJsZUZyb250ZW5kTW9kZWwodmFsdWUpIHtcbiAgICByZXR1cm4gQm9vbGVhbih2YWx1ZSAmJiB0eXBlb2YgdmFsdWUgPT09IFwib2JqZWN0XCIgJiYgdHlwZW9mIC8qKlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqIFR5cGVzIHRoZSBmb2xsb3dpbmcgdmFsdWUuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBAdHlwZSB7P30gKi8gKHZhbHVlKS5hdHRyaWJ1dGVzID09PSBcImZ1bmN0aW9uXCIpXG4gIH1cblxuICAvKipcbiAgICogUnVucyBzZXJpYWxpemUgZnJvbnRlbmQgbW9kZWxzLlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4vZGF0YWJhc2UvcmVjb3JkL2luZGV4LmpzXCIpLmRlZmF1bHRbXX0gbW9kZWxzIC0gTW9kZWxzIHRvIHNlcmlhbGl6ZS5cbiAgICogQHJldHVybnMge1Byb21pc2U8UmVjb3JkPHN0cmluZywgPz5bXT59IC0gU2VyaWFsaXplZCBtb2RlbCBwYXlsb2Fkcy5cbiAgICovXG4gIGFzeW5jIHNlcmlhbGl6ZUZyb250ZW5kTW9kZWxzKG1vZGVscykge1xuICAgIGlmIChtb2RlbHMubGVuZ3RoIDwgMSkgcmV0dXJuIFtdXG5cbiAgICAvKipcbiAgICAgKiBQcmVsb2FkZWQgcmVsYXRpb25zaGlwcyBwZXIgbW9kZWwuXG4gICAgICBAdHlwZSB7QXJyYXk8UmVjb3JkPHN0cmluZywgPz4+fSAqL1xuICAgIGNvbnN0IHByZWxvYWRlZFJlbGF0aW9uc2hpcHNQZXJNb2RlbCA9IEFycmF5LmZyb20oe2xlbmd0aDogbW9kZWxzLmxlbmd0aH0sICgpID0+ICh7fSkpXG5cbiAgICAvKipcbiAgICAgKiBDb2xsZWN0aW9uIHJlbGF0aW9uc2hpcCBlbnRyaWVzLlxuICAgICAgQHR5cGUge0FycmF5PHtsb2FkZWRNb2RlbHM6IGltcG9ydChcIi4vZGF0YWJhc2UvcmVjb3JkL2luZGV4LmpzXCIpLmRlZmF1bHRbXSwgbW9kZWxJbmRleDogbnVtYmVyLCByZWxhdGlvbnNoaXBOYW1lOiBzdHJpbmd9Pn0gKi9cbiAgICBjb25zdCBjb2xsZWN0aW9uUmVsYXRpb25zaGlwRW50cmllcyA9IFtdXG4gICAgLyoqXG4gICAgICogU2luZ3VsYXIgcmVsYXRpb25zaGlwIGVudHJpZXMuXG4gICAgICBAdHlwZSB7QXJyYXk8e2xvYWRlZE1vZGVsOiBpbXBvcnQoXCIuL2RhdGFiYXNlL3JlY29yZC9pbmRleC5qc1wiKS5kZWZhdWx0LCBtb2RlbEluZGV4OiBudW1iZXIsIHJlbGF0aW9uc2hpcE5hbWU6IHN0cmluZ30+fSAqL1xuICAgIGNvbnN0IHNpbmd1bGFyUmVsYXRpb25zaGlwRW50cmllcyA9IFtdXG5cbiAgICBtb2RlbHMuZm9yRWFjaCgobW9kZWwsIG1vZGVsSW5kZXgpID0+IHtcbiAgICAgIGNvbnN0IG1vZGVsQ2xhc3MgPSAvKipcbiAgICAgICAgICAgICAgICAgICAgICAgICAgKiBUeXBlcyB0aGUgZm9sbG93aW5nIHZhbHVlLlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgQHR5cGUge3R5cGVvZiBpbXBvcnQoXCIuL2RhdGFiYXNlL3JlY29yZC9pbmRleC5qc1wiKS5kZWZhdWx0fSAqLyAobW9kZWwuY29uc3RydWN0b3IpXG4gICAgICBjb25zdCByZWxhdGlvbnNoaXBzTWFwID0gbW9kZWxDbGFzcy5nZXRSZWxhdGlvbnNoaXBzTWFwKClcblxuICAgICAgZm9yIChjb25zdCByZWxhdGlvbnNoaXBOYW1lIGluIHJlbGF0aW9uc2hpcHNNYXApIHtcbiAgICAgICAgY29uc3QgcmVsYXRpb25zaGlwID0gbW9kZWwuZ2V0UmVsYXRpb25zaGlwQnlOYW1lKHJlbGF0aW9uc2hpcE5hbWUpXG5cbiAgICAgICAgaWYgKCFyZWxhdGlvbnNoaXAuZ2V0UHJlbG9hZGVkKCkpIGNvbnRpbnVlXG5cbiAgICAgICAgY29uc3QgbG9hZGVkUmVsYXRpb25zaGlwID0gcmVsYXRpb25zaGlwLmxvYWRlZCgpXG5cbiAgICAgICAgaWYgKEFycmF5LmlzQXJyYXkobG9hZGVkUmVsYXRpb25zaGlwKSkge1xuICAgICAgICAgIGNvbGxlY3Rpb25SZWxhdGlvbnNoaXBFbnRyaWVzLnB1c2goe2xvYWRlZE1vZGVsczogbG9hZGVkUmVsYXRpb25zaGlwLCBtb2RlbEluZGV4LCByZWxhdGlvbnNoaXBOYW1lfSlcbiAgICAgICAgICBjb250aW51ZVxuICAgICAgICB9XG5cbiAgICAgICAgaWYgKHRoaXMuaXNTZXJpYWxpemFibGVGcm9udGVuZE1vZGVsKGxvYWRlZFJlbGF0aW9uc2hpcCkpIHtcbiAgICAgICAgICBzaW5ndWxhclJlbGF0aW9uc2hpcEVudHJpZXMucHVzaCh7bG9hZGVkTW9kZWw6IGxvYWRlZFJlbGF0aW9uc2hpcCwgbW9kZWxJbmRleCwgcmVsYXRpb25zaGlwTmFtZX0pXG4gICAgICAgICAgY29udGludWVcbiAgICAgICAgfVxuXG4gICAgICAgIHByZWxvYWRlZFJlbGF0aW9uc2hpcHNQZXJNb2RlbFttb2RlbEluZGV4XVtyZWxhdGlvbnNoaXBOYW1lXSA9IGxvYWRlZFJlbGF0aW9uc2hpcCA9PSB1bmRlZmluZWQgPyBudWxsIDogbG9hZGVkUmVsYXRpb25zaGlwXG4gICAgICB9XG4gICAgfSlcblxuICAgIGlmIChjb2xsZWN0aW9uUmVsYXRpb25zaGlwRW50cmllcy5sZW5ndGggPiAwKSB7XG4gICAgICBjb25zdCBhbGxDb2xsZWN0aW9uTW9kZWxzID0gY29sbGVjdGlvblJlbGF0aW9uc2hpcEVudHJpZXMuZmxhdE1hcCgoZW50cnkpID0+IGVudHJ5LmxvYWRlZE1vZGVscylcbiAgICAgIGNvbnN0IHNlcmlhbGl6YWJsZUNvbGxlY3Rpb25Nb2RlbHMgPSBhd2FpdCB0aGlzLmZyb250ZW5kTW9kZWxGaWx0ZXJTZXJpYWxpemFibGVSZWxhdGVkTW9kZWxzKHtcbiAgICAgICAgbW9kZWxzOiBhbGxDb2xsZWN0aW9uTW9kZWxzLFxuICAgICAgICByZWxhdGlvbnNoaXBJc0NvbGxlY3Rpb246IHRydWVcbiAgICAgIH0pXG4gICAgICBjb25zdCBzZXJpYWxpemFibGVDb2xsZWN0aW9uTW9kZWxzU2V0ID0gbmV3IFNldChzZXJpYWxpemFibGVDb2xsZWN0aW9uTW9kZWxzKVxuXG4gICAgICBmb3IgKGNvbnN0IHJlbGF0aW9uc2hpcEVudHJ5IG9mIGNvbGxlY3Rpb25SZWxhdGlvbnNoaXBFbnRyaWVzKSB7XG4gICAgICAgIGNvbnN0IGFsbG93ZWRNb2RlbHMgPSByZWxhdGlvbnNoaXBFbnRyeS5sb2FkZWRNb2RlbHMuZmlsdGVyKChyZWxhdGVkTW9kZWwpID0+IHNlcmlhbGl6YWJsZUNvbGxlY3Rpb25Nb2RlbHNTZXQuaGFzKHJlbGF0ZWRNb2RlbCkpXG4gICAgICAgIGNvbnN0IHNlcmlhbGl6ZWRSZWxhdGVkTW9kZWxzID0gYXdhaXQgdGhpcy5zZXJpYWxpemVGcm9udGVuZE1vZGVscyhhbGxvd2VkTW9kZWxzKVxuXG4gICAgICAgIHByZWxvYWRlZFJlbGF0aW9uc2hpcHNQZXJNb2RlbFtyZWxhdGlvbnNoaXBFbnRyeS5tb2RlbEluZGV4XVtyZWxhdGlvbnNoaXBFbnRyeS5yZWxhdGlvbnNoaXBOYW1lXSA9IHNlcmlhbGl6ZWRSZWxhdGVkTW9kZWxzXG4gICAgICB9XG4gICAgfVxuXG4gICAgaWYgKHNpbmd1bGFyUmVsYXRpb25zaGlwRW50cmllcy5sZW5ndGggPiAwKSB7XG4gICAgICBjb25zdCBhbGxTaW5ndWxhck1vZGVscyA9IHNpbmd1bGFyUmVsYXRpb25zaGlwRW50cmllcy5tYXAoKGVudHJ5KSA9PiBlbnRyeS5sb2FkZWRNb2RlbClcbiAgICAgIGNvbnN0IHNlcmlhbGl6YWJsZVNpbmd1bGFyTW9kZWxzID0gYXdhaXQgdGhpcy5mcm9udGVuZE1vZGVsRmlsdGVyU2VyaWFsaXphYmxlUmVsYXRlZE1vZGVscyh7XG4gICAgICAgIG1vZGVsczogYWxsU2luZ3VsYXJNb2RlbHMsXG4gICAgICAgIHJlbGF0aW9uc2hpcElzQ29sbGVjdGlvbjogZmFsc2VcbiAgICAgIH0pXG4gICAgICBjb25zdCBzZXJpYWxpemFibGVTaW5ndWxhck1vZGVsc1NldCA9IG5ldyBTZXQoc2VyaWFsaXphYmxlU2luZ3VsYXJNb2RlbHMpXG5cbiAgICAgIGZvciAoY29uc3QgcmVsYXRpb25zaGlwRW50cnkgb2Ygc2luZ3VsYXJSZWxhdGlvbnNoaXBFbnRyaWVzKSB7XG4gICAgICAgIGlmICghc2VyaWFsaXphYmxlU2luZ3VsYXJNb2RlbHNTZXQuaGFzKHJlbGF0aW9uc2hpcEVudHJ5LmxvYWRlZE1vZGVsKSkge1xuICAgICAgICAgIHByZWxvYWRlZFJlbGF0aW9uc2hpcHNQZXJNb2RlbFtyZWxhdGlvbnNoaXBFbnRyeS5tb2RlbEluZGV4XVtyZWxhdGlvbnNoaXBFbnRyeS5yZWxhdGlvbnNoaXBOYW1lXSA9IG51bGxcbiAgICAgICAgICBjb250aW51ZVxuICAgICAgICB9XG5cbiAgICAgICAgY29uc3Qgc2VyaWFsaXplZE1vZGVsID0gKGF3YWl0IHRoaXMuc2VyaWFsaXplRnJvbnRlbmRNb2RlbHMoW3JlbGF0aW9uc2hpcEVudHJ5LmxvYWRlZE1vZGVsXSkpWzBdXG4gICAgICAgIHByZWxvYWRlZFJlbGF0aW9uc2hpcHNQZXJNb2RlbFtyZWxhdGlvbnNoaXBFbnRyeS5tb2RlbEluZGV4XVtyZWxhdGlvbnNoaXBFbnRyeS5yZWxhdGlvbnNoaXBOYW1lXSA9IHNlcmlhbGl6ZWRNb2RlbFxuICAgICAgfVxuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFNlcmlhbGl6ZWQgbW9kZWxzLlxuICAgICAgQHR5cGUge1JlY29yZDxzdHJpbmcsID8+W119ICovXG4gICAgY29uc3Qgc2VyaWFsaXplZE1vZGVscyA9IFtdXG5cbiAgICBmb3IgKGNvbnN0IFttb2RlbEluZGV4LCBtb2RlbF0gb2YgbW9kZWxzLmVudHJpZXMoKSkge1xuICAgICAgY29uc3Qgc2VyaWFsaXplZEF0dHJpYnV0ZXMgPSBhd2FpdCB0aGlzLnNlcmlhbGl6ZUZyb250ZW5kTW9kZWxBdHRyaWJ1dGVzKG1vZGVsKVxuICAgICAgY29uc3QgcHJlbG9hZGVkUmVsYXRpb25zaGlwcyA9IHByZWxvYWRlZFJlbGF0aW9uc2hpcHNQZXJNb2RlbFttb2RlbEluZGV4XVxuICAgICAgY29uc3QgYXNzb2NpYXRpb25Db3VudHMgPSB0eXBlb2YgbW9kZWwuYXNzb2NpYXRpb25Db3VudHMgPT09IFwiZnVuY3Rpb25cIlxuICAgICAgICA/IG1vZGVsLmFzc29jaWF0aW9uQ291bnRzKClcbiAgICAgICAgOiB7fVxuICAgICAgY29uc3QgcXVlcnlEYXRhVmFsdWVzID0gdHlwZW9mIG1vZGVsLnF1ZXJ5RGF0YVZhbHVlcyA9PT0gXCJmdW5jdGlvblwiXG4gICAgICAgID8gbW9kZWwucXVlcnlEYXRhVmFsdWVzKClcbiAgICAgICAgOiB7fVxuICAgICAgY29uc3QgY29tcHV0ZWRBYmlsaXRpZXMgPSB0eXBlb2YgbW9kZWwuY29tcHV0ZWRBYmlsaXRpZXMgPT09IFwiZnVuY3Rpb25cIlxuICAgICAgICA/IG1vZGVsLmNvbXB1dGVkQWJpbGl0aWVzKClcbiAgICAgICAgOiB7fVxuICAgICAgY29uc3QgaGFzQ291bnRzID0gT2JqZWN0LmtleXMoYXNzb2NpYXRpb25Db3VudHMpLmxlbmd0aCA+IDBcbiAgICAgIGNvbnN0IGhhc1F1ZXJ5RGF0YSA9IE9iamVjdC5rZXlzKHF1ZXJ5RGF0YVZhbHVlcykubGVuZ3RoID4gMFxuICAgICAgY29uc3QgaGFzQWJpbGl0aWVzID0gT2JqZWN0LmtleXMoY29tcHV0ZWRBYmlsaXRpZXMpLmxlbmd0aCA+IDBcbiAgICAgIGNvbnN0IGhhc1ByZWxvYWRlZCA9IE9iamVjdC5rZXlzKHByZWxvYWRlZFJlbGF0aW9uc2hpcHMpLmxlbmd0aCA+IDBcblxuICAgICAgaWYgKCFoYXNQcmVsb2FkZWQgJiYgIWhhc0NvdW50cyAmJiAhaGFzUXVlcnlEYXRhICYmICFoYXNBYmlsaXRpZXMpIHtcbiAgICAgICAgc2VyaWFsaXplZE1vZGVscy5wdXNoKHNlcmlhbGl6ZWRBdHRyaWJ1dGVzKVxuICAgICAgICBjb250aW51ZVxuICAgICAgfVxuXG4gICAgICAvKipcbiAgICAgICAqIFNlcmlhbGl6ZWQuXG4gICAgICAgIEB0eXBlIHtSZWNvcmQ8c3RyaW5nLCA/Pn0gKi9cbiAgICAgIGNvbnN0IHNlcmlhbGl6ZWQgPSB7Li4uc2VyaWFsaXplZEF0dHJpYnV0ZXN9XG5cbiAgICAgIGlmIChoYXNQcmVsb2FkZWQpIHNlcmlhbGl6ZWQuX19wcmVsb2FkZWRSZWxhdGlvbnNoaXBzID0gcHJlbG9hZGVkUmVsYXRpb25zaGlwc1xuICAgICAgaWYgKGhhc0NvdW50cykgc2VyaWFsaXplZC5fX2Fzc29jaWF0aW9uQ291bnRzID0gYXNzb2NpYXRpb25Db3VudHNcbiAgICAgIGlmIChoYXNRdWVyeURhdGEpIHNlcmlhbGl6ZWQuX19xdWVyeURhdGEgPSBxdWVyeURhdGFWYWx1ZXNcbiAgICAgIGlmIChoYXNBYmlsaXRpZXMpIHNlcmlhbGl6ZWQuX19hYmlsaXRpZXMgPSBjb21wdXRlZEFiaWxpdGllc1xuXG4gICAgICBzZXJpYWxpemVkTW9kZWxzLnB1c2goc2VyaWFsaXplZClcbiAgICB9XG5cbiAgICByZXR1cm4gc2VyaWFsaXplZE1vZGVsc1xuICB9XG5cbiAgLyoqXG4gICAqIFJ1bnMgc2VyaWFsaXplIGZyb250ZW5kIG1vZGVsLlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4vZGF0YWJhc2UvcmVjb3JkL2luZGV4LmpzXCIpLmRlZmF1bHR9IG1vZGVsIC0gRnJvbnRlbmQgbW9kZWwgcmVjb3JkLlxuICAgKiBAcmV0dXJucyB7UHJvbWlzZTxSZWNvcmQ8c3RyaW5nLCA/Pj59IC0gU2VyaWFsaXplZCBmcm9udGVuZCBtb2RlbCBwYXlsb2FkLlxuICAgKi9cbiAgYXN5bmMgc2VyaWFsaXplRnJvbnRlbmRNb2RlbChtb2RlbCkge1xuICAgIGNvbnN0IHNlcmlhbGl6ZWRNb2RlbHMgPSBhd2FpdCB0aGlzLnNlcmlhbGl6ZUZyb250ZW5kTW9kZWxzKFttb2RlbF0pXG5cbiAgICByZXR1cm4gc2VyaWFsaXplZE1vZGVsc1swXVxuICB9XG5cbiAgLyoqXG4gICAqIFJ1bnMgZnJvbnRlbmQgbW9kZWwgcmVuZGVyIGVycm9yLlxuICAgKiBAcGFyYW0ge3N0cmluZ30gZXJyb3JNZXNzYWdlIC0gRXJyb3IgbWVzc2FnZS5cbiAgICogQHJldHVybnMge1Byb21pc2U8dm9pZD59IC0gUmVzb2x2ZXMgd2hlbiBlcnJvciBoYXMgYmVlbiByZW5kZXJlZC5cbiAgICovXG4gIGFzeW5jIGZyb250ZW5kTW9kZWxSZW5kZXJFcnJvcihlcnJvck1lc3NhZ2UpIHtcbiAgICBhd2FpdCB0aGlzLmxvZ2dlci5lcnJvcihgRnJvbnRlbmQgbW9kZWwgcmVxdWVzdCBmYWlsZWQ6ICR7ZXJyb3JNZXNzYWdlfWApXG5cbiAgICBjb25zdCByZW5kZXJFcnJvciA9IC8qKlxuICAgICAgICAgICAgICAgICAgICAgICAgICogVHlwZXMgdGhlIGZvbGxvd2luZyB2YWx1ZS5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgQHR5cGUgeygoZXJyb3JNZXNzYWdlOiBzdHJpbmcpID0+IFByb21pc2U8dm9pZD4pIHwgdW5kZWZpbmVkfSAqLyAoXG4gICAgICAvKipcbiAgICAgICAqIFR5cGVzIHRoZSBmb2xsb3dpbmcgdmFsdWUuXG4gICAgICAgIEB0eXBlIHs/fSAqLyAodGhpcykucmVuZGVyRXJyb3JcbiAgICApXG5cbiAgICBpZiAodHlwZW9mIHJlbmRlckVycm9yID09PSBcImZ1bmN0aW9uXCIpIHtcbiAgICAgIGF3YWl0IHJlbmRlckVycm9yLmNhbGwodGhpcywgZnJvbnRlbmRNb2RlbENsaWVudFNhZmVFcnJvck1lc3NhZ2UpXG4gICAgICByZXR1cm5cbiAgICB9XG5cbiAgICBhd2FpdCB0aGlzLnJlbmRlcih7XG4gICAgICBqc29uOiAvKipcbiAgICAgICAgICAgICAqIFR5cGVzIHRoZSBmb2xsb3dpbmcgdmFsdWUuXG4gICAgICAgICAgICAgIEB0eXBlIHtSZWNvcmQ8c3RyaW5nLCA/Pn0gKi8gKHNlcmlhbGl6ZUZyb250ZW5kTW9kZWxUcmFuc3BvcnRWYWx1ZSh7XG4gICAgICAgIGVycm9yTWVzc2FnZTogZnJvbnRlbmRNb2RlbENsaWVudFNhZmVFcnJvck1lc3NhZ2UsXG4gICAgICAgIHN0YXR1czogXCJlcnJvclwiXG4gICAgICB9KSlcbiAgICB9KVxuICB9XG5cbiAgLyoqXG4gICAqIFJ1bnMgZnJvbnRlbmQgbW9kZWwgZXJyb3IgcGF5bG9hZC5cbiAgICogQHBhcmFtIHtzdHJpbmd9IGVycm9yTWVzc2FnZSAtIEVycm9yIG1lc3NhZ2UuXG4gICAqIEByZXR1cm5zIHtSZWNvcmQ8c3RyaW5nLCA/Pn0gLSBFcnJvciBwYXlsb2FkLlxuICAgKi9cbiAgZnJvbnRlbmRNb2RlbEVycm9yUGF5bG9hZChlcnJvck1lc3NhZ2UpIHtcbiAgICByZXR1cm4ge1xuICAgICAgZXJyb3JNZXNzYWdlLFxuICAgICAgc3RhdHVzOiBcImVycm9yXCJcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogUnVucyBmcm9udGVuZCBtb2RlbCBjbGllbnQgc2FmZSBlcnJvciBwYXlsb2FkLlxuICAgKiBAcmV0dXJucyB7UmVjb3JkPHN0cmluZywgPz59IC0gQ2xpZW50LXNhZmUgZXJyb3IgcGF5bG9hZC5cbiAgICovXG4gIGZyb250ZW5kTW9kZWxDbGllbnRTYWZlRXJyb3JQYXlsb2FkKCkge1xuICAgIHJldHVybiB0aGlzLmZyb250ZW5kTW9kZWxFcnJvclBheWxvYWQoZnJvbnRlbmRNb2RlbENsaWVudFNhZmVFcnJvck1lc3NhZ2UpXG4gIH1cblxuICAvKipcbiAgICogUnVucyBmcm9udGVuZCBtb2RlbCBjbGllbnQgZXJyb3IgcGF5bG9hZCBmb3IgZXJyb3IuXG4gICAqIEBwYXJhbSB7P30gZXJyb3IgLSBDYXVnaHQgZXJyb3IuXG4gICAqIEByZXR1cm5zIHtSZWNvcmQ8c3RyaW5nLCA/Pn0gLSBDbGllbnQgcGF5bG9hZCBmb3IgdGhlIGN1cnJlbnQgZW52aXJvbm1lbnQuXG4gICAqL1xuICBmcm9udGVuZE1vZGVsQ2xpZW50RXJyb3JQYXlsb2FkRm9yRXJyb3IoZXJyb3IpIHtcbiAgICBjb25zdCB2ZWxvY2lvdXNNZXRhZGF0YSA9IGZyb250ZW5kTW9kZWxWZWxvY2lvdXNNZXRhZGF0YUZvckVycm9yKGVycm9yKVxuXG4gICAgbGV0IHZhbGlkYXRpb25FcnJvcnNQYXlsb2FkID0ge31cblxuICAgIGlmIChlcnJvciBpbnN0YW5jZW9mIFZhbGlkYXRpb25FcnJvcikge1xuICAgICAgY29uc3QgdmFsaWRhdGlvbkVycm9ycyA9IGVycm9yLmdldFZhbGlkYXRpb25FcnJvcnMoKVxuICAgICAgY29uc3QgbW9kZWwgPSBlcnJvci5nZXRNb2RlbCgpXG4gICAgICAvKipcbiAgICAgICAqIFN0cnVjdHVyZWQgZXJyb3JzLlxuICAgICAgICBAdHlwZSB7UmVjb3JkPHN0cmluZywge3R5cGU6IHN0cmluZywgbWVzc2FnZTogc3RyaW5nLCBmdWxsTWVzc2FnZTogc3RyaW5nfVtdPn0gKi9cbiAgICAgIGNvbnN0IHN0cnVjdHVyZWRFcnJvcnMgPSB7fVxuXG4gICAgICBmb3IgKGNvbnN0IGF0dHJpYnV0ZU5hbWUgaW4gdmFsaWRhdGlvbkVycm9ycykge1xuICAgICAgICBzdHJ1Y3R1cmVkRXJyb3JzW2F0dHJpYnV0ZU5hbWVdID0gdmFsaWRhdGlvbkVycm9yc1thdHRyaWJ1dGVOYW1lXS5tYXAoZXJyID0+ICh7XG4gICAgICAgICAgdHlwZTogZXJyLnR5cGUsXG4gICAgICAgICAgbWVzc2FnZTogZXJyLm1lc3NhZ2UsXG4gICAgICAgICAgZnVsbE1lc3NhZ2U6IGAke21vZGVsLmdldE1vZGVsQ2xhc3MoKS5odW1hbkF0dHJpYnV0ZU5hbWUoYXR0cmlidXRlTmFtZSl9ICR7ZXJyLm1lc3NhZ2V9YFxuICAgICAgICB9KSlcbiAgICAgIH1cblxuICAgICAgdmFsaWRhdGlvbkVycm9yc1BheWxvYWQgPSB7XG4gICAgICAgIGVycm9yVHlwZTogXCJ2YWxpZGF0aW9uX2Vycm9yXCIsXG4gICAgICAgIHZhbGlkYXRpb25FcnJvcnM6IHN0cnVjdHVyZWRFcnJvcnNcbiAgICAgIH1cbiAgICB9XG5cbiAgICByZXR1cm4ge1xuICAgICAgLi4udGhpcy5mcm9udGVuZE1vZGVsRXJyb3JQYXlsb2FkKGZyb250ZW5kTW9kZWxDbGllbnRNZXNzYWdlRm9yRXJyb3IoZXJyb3IpKSxcbiAgICAgIC4uLmZyb250ZW5kTW9kZWxEZWJ1Z1BheWxvYWRGb3JFcnJvcih7XG4gICAgICAgIGNvbmZpZ3VyYXRpb246IHRoaXMuZ2V0Q29uZmlndXJhdGlvbigpLFxuICAgICAgICBlbnZpcm9ubWVudDogdGhpcy5nZXRDb25maWd1cmF0aW9uKCkuZ2V0RW52aXJvbm1lbnQoKSxcbiAgICAgICAgZXJyb3JcbiAgICAgIH0pLFxuICAgICAgLi4uKHZlbG9jaW91c01ldGFkYXRhID8ge3ZlbG9jaW91czogdmVsb2Npb3VzTWV0YWRhdGF9IDoge30pLFxuICAgICAgLi4udmFsaWRhdGlvbkVycm9yc1BheWxvYWRcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogUnVucyBmcm9udGVuZCBtb2RlbCBsb2cgZW5kcG9pbnQgZXJyb3IuXG4gICAqIEBwYXJhbSB7b2JqZWN0fSBhcmdzIC0gRXJyb3IgbG9nIGFyZ3MuXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBhcmdzLmFjdGlvbiAtIEVuZHBvaW50L2FjdGlvbiBsYWJlbC5cbiAgICogQHBhcmFtIHs/fSBhcmdzLmVycm9yIC0gQ2F1Z2h0IGVycm9yLlxuICAgKiBAcGFyYW0ge1wiaW5kZXhcIiB8IFwiZmluZFwiIHwgXCJjcmVhdGVcIiB8IFwidXBkYXRlXCIgfCBcImRlc3Ryb3lcIiB8IFwiYXR0YWNoXCIgfCBcImRvd25sb2FkXCIgfCBcInVybFwiIHwgXCJjdXN0b20tY29tbWFuZFwifSBbYXJncy5jb21tYW5kVHlwZV0gLSBGcm9udGVuZC1tb2RlbCBjb21tYW5kIHR5cGUuXG4gICAqIEBwYXJhbSB7c3RyaW5nIHwgdW5kZWZpbmVkfSBbYXJncy5tb2RlbF0gLSBSZXF1ZXN0IG1vZGVsIG5hbWUgd2hlbiBhdmFpbGFibGUuXG4gICAqIEBwYXJhbSB7c3RyaW5nIHwgdW5kZWZpbmVkfSBbYXJncy5yZXF1ZXN0SWRdIC0gQmF0Y2ggcmVxdWVzdCBpZCB3aGVuIGF2YWlsYWJsZS5cbiAgICogQHJldHVybnMge1Byb21pc2U8dm9pZD59IC0gUmVzb2x2ZXMgYWZ0ZXIgbG9nZ2luZy5cbiAgICovXG4gIGFzeW5jIGZyb250ZW5kTW9kZWxMb2dFbmRwb2ludEVycm9yKHthY3Rpb24sIGVycm9yLCBjb21tYW5kVHlwZSwgbW9kZWwsIHJlcXVlc3RJZH0pIHtcbiAgICAvLyBFcnJvcnMgYW5ub3RhdGVkIHdpdGggYGVycm9yLnZlbG9jaW91cyA9IHsuLi59YCBhcmUgdXNlci1mbG93XG4gICAgLy8gZmFpbHVyZXMgdGhlIGRldmVsb3BlciBoYXMgbWFya2VkIGFzIGV4cGVjdGVkIChiYWQgcGFzc3dvcmQsXG4gICAgLy8gdmFsaWRhdGlvbiBtZXNzYWdlLCBldGMuKS4gU3VyZmFjZSB0aGUgbWVzc2FnZSArIG1ldGFkYXRhIHRvXG4gICAgLy8gdGhlIGNsaWVudCAoaGFuZGxlZCBieSBmcm9udGVuZE1vZGVsQ2xpZW50RXJyb3JQYXlsb2FkRm9yRXJyb3IpLFxuICAgIC8vIGJ1dCBza2lwIHRoZSBlcnJvciBsb2cgc28gbW9uaXRvcmluZyBzdGF5cyBmb2N1c2VkIG9uIHJlYWxcbiAgICAvLyBiYWNrZW5kIGZhaWx1cmVzLlxuICAgIGlmIChmcm9udGVuZE1vZGVsRXJyb3JIYXNWZWxvY2lvdXNNZXRhZGF0YShlcnJvcikpIHJldHVyblxuXG4gICAgbGV0IHJlc29sdmVkTW9kZWwgPSBtb2RlbFxuXG4gICAgaWYgKCFyZXNvbHZlZE1vZGVsKSB7XG4gICAgICB0cnkge1xuICAgICAgICByZXNvbHZlZE1vZGVsID0gdGhpcy5mcm9udGVuZE1vZGVsUGFyYW1zKCkubW9kZWxcbiAgICAgIH0gY2F0Y2gge1xuICAgICAgICByZXNvbHZlZE1vZGVsID0gdW5kZWZpbmVkXG4gICAgICB9XG4gICAgfVxuXG4gICAgY29uc3QgZXJyb3JNZXNzYWdlID0gZXJyb3IgaW5zdGFuY2VvZiBFcnJvclxuICAgICAgPyBgJHtlcnJvci5tZXNzYWdlfVxcbiR7ZXJyb3Iuc3RhY2sgfHwgXCJcIn1gXG4gICAgICA6IFN0cmluZyhlcnJvcilcblxuICAgIGF3YWl0IHRoaXMubG9nZ2VyLmVycm9yKCgpID0+IFtcIkZyb250ZW5kIG1vZGVsIGVuZHBvaW50IHJlcXVlc3QgZmFpbGVkXCIsIHtcbiAgICAgIGFjdGlvbixcbiAgICAgIGNvbW1hbmRUeXBlLFxuICAgICAgZXJyb3I6IGVycm9yTWVzc2FnZSxcbiAgICAgIG1vZGVsOiByZXNvbHZlZE1vZGVsLFxuICAgICAgcmVxdWVzdElkXG4gICAgfV0pXG4gIH1cblxuICAvKipcbiAgICogUnVucyBmcm9udGVuZCBtb2RlbCByZW5kZXIgY29tbWFuZCByZXNwb25zZS5cbiAgICogQHBhcmFtIHtcImluZGV4XCIgfCBcImZpbmRcIiB8IFwiY3JlYXRlXCIgfCBcInVwZGF0ZVwiIHwgXCJkZXN0cm95XCIgfCBcImF0dGFjaFwiIHwgXCJkb3dubG9hZFwiIHwgXCJ1cmxcIn0gYWN0aW9uIC0gRnJvbnRlbmQgYWN0aW9uLlxuICAgKiBAcmV0dXJucyB7UHJvbWlzZTx2b2lkPn0gLSBSZXNvbHZlcyB3aGVuIHJlc3BvbnNlIGhhcyBiZWVuIHJlbmRlcmVkLlxuICAgKi9cbiAgYXN5bmMgZnJvbnRlbmRNb2RlbFJlbmRlckNvbW1hbmRSZXNwb25zZShhY3Rpb24pIHtcbiAgICB0cnkge1xuICAgICAgY29uc3QgcmVzcG9uc2VQYXlsb2FkID0gYXdhaXQgdGhpcy5mcm9udGVuZE1vZGVsQ29tbWFuZFBheWxvYWQoYWN0aW9uKVxuICAgICAgaWYgKCFyZXNwb25zZVBheWxvYWQpIHJldHVyblxuXG4gICAgICBhd2FpdCB0aGlzLnJlbmRlcih7XG4gICAgICAgIGpzb246IC8qKlxuICAgICAgICAgICAgICAgKiBUeXBlcyB0aGUgZm9sbG93aW5nIHZhbHVlLlxuICAgICAgICAgICAgICAgIEB0eXBlIHtSZWNvcmQ8c3RyaW5nLCA/Pn0gKi8gKHNlcmlhbGl6ZUZyb250ZW5kTW9kZWxUcmFuc3BvcnRWYWx1ZShyZXNwb25zZVBheWxvYWQpKVxuICAgICAgfSlcbiAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgYXdhaXQgdGhpcy5mcm9udGVuZE1vZGVsTG9nRW5kcG9pbnRFcnJvcih7YWN0aW9uLCBjb21tYW5kVHlwZTogYWN0aW9uLCBlcnJvcn0pXG5cbiAgICAgIGF3YWl0IHRoaXMucmVuZGVyKHtcbiAgICAgICAganNvbjogLyoqXG4gICAgICAgICAgICAgICAqIFR5cGVzIHRoZSBmb2xsb3dpbmcgdmFsdWUuXG4gICAgICAgICAgICAgICAgQHR5cGUge1JlY29yZDxzdHJpbmcsID8+fSAqLyAoc2VyaWFsaXplRnJvbnRlbmRNb2RlbFRyYW5zcG9ydFZhbHVlKHRoaXMuZnJvbnRlbmRNb2RlbENsaWVudEVycm9yUGF5bG9hZEZvckVycm9yKGVycm9yKSkpXG4gICAgICB9KVxuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBSdW5zIGZyb250ZW5kIG1vZGVsIGNvbW1hbmQgcGF5bG9hZC5cbiAgICogQHBhcmFtIHtcImluZGV4XCIgfCBcImZpbmRcIiB8IFwiY3JlYXRlXCIgfCBcInVwZGF0ZVwiIHwgXCJkZXN0cm95XCIgfCBcImF0dGFjaFwiIHwgXCJkb3dubG9hZFwiIHwgXCJ1cmxcIn0gYWN0aW9uIC0gRnJvbnRlbmQgYWN0aW9uLlxuICAgKiBAcmV0dXJucyB7UHJvbWlzZTxSZWNvcmQ8c3RyaW5nLCA/PiB8IG51bGw+fSAtIFJlc3BvbnNlIHBheWxvYWQuXG4gICAqL1xuICBhc3luYyBmcm9udGVuZE1vZGVsQ29tbWFuZFBheWxvYWQoYWN0aW9uKSB7XG4gICAgYXdhaXQgdGhpcy5lbnN1cmVGcm9udGVuZE1vZGVsQ2xhc3NJbml0aWFsaXplZCgpXG5cbiAgICBpZiAoIShhd2FpdCB0aGlzLnJ1bkZyb250ZW5kTW9kZWxCZWZvcmVBY3Rpb24oYWN0aW9uKSkpIHtcbiAgICAgIHJldHVybiBudWxsXG4gICAgfVxuXG4gICAgY29uc3QgcmVzb3VyY2UgPSB0aGlzLmZyb250ZW5kTW9kZWxSZXNvdXJjZUluc3RhbmNlKClcblxuICAgIGlmIChhY3Rpb24gPT09IFwiaW5kZXhcIikge1xuICAgICAgaWYgKHRoaXMuZnJvbnRlbmRNb2RlbENvdW50UmVxdWVzdGVkKCkpIHtcbiAgICAgICAgaWYgKCEoYXdhaXQgcmVzb3VyY2Uuc3VwcG9ydHNDb3VudChcImluZGV4XCIpKSkge1xuICAgICAgICAgIHRocm93IG5ldyBFcnJvcihcImNvdW50IGlzIG5vdCBzdXBwb3J0ZWQgd2hlbiByZXNvdXJjZSByZWNvcmRzIGFyZSBjdXN0b21pemVkXCIpXG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgIGNvdW50OiBhd2FpdCByZXNvdXJjZS5jb3VudCgpLFxuICAgICAgICAgIHN0YXR1czogXCJzdWNjZXNzXCJcbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICBjb25zdCBwbHVjayA9IHRoaXMuZnJvbnRlbmRNb2RlbFBsdWNrKClcblxuICAgICAgaWYgKHBsdWNrLmxlbmd0aCA+IDApIHtcbiAgICAgICAgaWYgKCEoYXdhaXQgcmVzb3VyY2Uuc3VwcG9ydHNQbHVjayhcImluZGV4XCIpKSkge1xuICAgICAgICAgIHRocm93IG5ldyBFcnJvcihcInBsdWNrIGlzIG5vdCBzdXBwb3J0ZWQgd2hlbiByZXNvdXJjZSByZWNvcmRzIGFyZSBjdXN0b21pemVkXCIpXG4gICAgICAgIH1cblxuICAgICAgICBjb25zdCB2YWx1ZXMgPSBhd2FpdCB0aGlzLmZyb250ZW5kTW9kZWxQbHVja1ZhbHVlcyh7XG4gICAgICAgICAgcGx1Y2ssXG4gICAgICAgICAgcXVlcnk6IHRoaXMuZnJvbnRlbmRNb2RlbEluZGV4UXVlcnkoKVxuICAgICAgICB9KVxuXG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgc3RhdHVzOiBcInN1Y2Nlc3NcIixcbiAgICAgICAgICB2YWx1ZXNcbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICBjb25zdCBtb2RlbHMgPSBhd2FpdCB0aGlzLmZyb250ZW5kTW9kZWxSZWNvcmRzKClcbiAgICAgIGF3YWl0IHRoaXMuZnJvbnRlbmRNb2RlbENvbXB1dGVBYmlsaXRpZXMobW9kZWxzKVxuICAgICAgY29uc3Qgc2VyaWFsaXplZE1vZGVscyA9IGF3YWl0IFByb21pc2UuYWxsKG1vZGVscy5tYXAoYXN5bmMgKG1vZGVsKSA9PiBhd2FpdCByZXNvdXJjZS5zZXJpYWxpemUobW9kZWwsIFwiaW5kZXhcIikpKVxuXG4gICAgICByZXR1cm4ge1xuICAgICAgICBtb2RlbHM6IHNlcmlhbGl6ZWRNb2RlbHMsXG4gICAgICAgIHN0YXR1czogXCJzdWNjZXNzXCJcbiAgICAgIH1cbiAgICB9XG5cbiAgICBjb25zdCBwYXJhbXMgPSB0aGlzLmZyb250ZW5kTW9kZWxQYXJhbXMoKVxuICAgIGNvbnN0IG1vZGVsQ2xhc3MgPSB0aGlzLmZyb250ZW5kTW9kZWxDbGFzcygpXG4gICAgY29uc3QgaWQgPSBwYXJhbXMuaWRcblxuICAgIGlmIChhY3Rpb24gPT09IFwiY3JlYXRlXCIpIHtcbiAgICAgIGNvbnN0IG11dGF0aW9uQXR0cmlidXRlcyA9IGZyb250ZW5kTW9kZWxNdXRhdGlvbkF0dHJpYnV0ZXMocGFyYW1zKVxuICAgICAgaWYgKHR5cGVvZiBtdXRhdGlvbkF0dHJpYnV0ZXMgPT09IFwic3RyaW5nXCIpIHJldHVybiB0aGlzLmZyb250ZW5kTW9kZWxFcnJvclBheWxvYWQobXV0YXRpb25BdHRyaWJ1dGVzKVxuXG4gICAgICBjb25zdCBtb2RlbCA9IGF3YWl0IHRoaXMuZnJvbnRlbmRNb2RlbENyZWF0ZVJlY29yZChtdXRhdGlvbkF0dHJpYnV0ZXMuYXR0cmlidXRlcywgbXV0YXRpb25BdHRyaWJ1dGVzLm5lc3RlZEF0dHJpYnV0ZXMpXG5cbiAgICAgIGlmICghbW9kZWwpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZnJvbnRlbmRNb2RlbEVycm9yUGF5bG9hZChgJHttb2RlbENsYXNzLm5hbWV9IG5vdCBmb3VuZC5gKVxuICAgICAgfVxuXG4gICAgICBjb25zdCBzZXJpYWxpemVkTW9kZWwgPSBhd2FpdCByZXNvdXJjZS5zZXJpYWxpemUobW9kZWwsIFwiY3JlYXRlXCIpXG5cbiAgICAgIHJldHVybiBmcm9udGVuZE1vZGVsU2VyaWFsaXplZE1vZGVsU3VjY2VzcyhzZXJpYWxpemVkTW9kZWwpXG4gICAgfVxuXG4gICAgaWYgKCh0eXBlb2YgaWQgIT09IFwic3RyaW5nXCIgJiYgdHlwZW9mIGlkICE9PSBcIm51bWJlclwiKSB8fCBgJHtpZH1gLmxlbmd0aCA8IDEpIHtcbiAgICAgIHJldHVybiB0aGlzLmZyb250ZW5kTW9kZWxFcnJvclBheWxvYWQoXCJFeHBlY3RlZCBtb2RlbCBpZC5cIilcbiAgICB9XG5cbiAgICBpZiAoYWN0aW9uID09PSBcImF0dGFjaFwiKSB7XG4gICAgICBjb25zdCBhdHRhY2htZW50TmFtZSA9IHBhcmFtcy5hdHRhY2htZW50TmFtZVxuICAgICAgY29uc3QgYXR0YWNobWVudElucHV0ID0gcGFyYW1zLmF0dGFjaG1lbnRcblxuICAgICAgaWYgKHR5cGVvZiBhdHRhY2htZW50TmFtZSAhPT0gXCJzdHJpbmdcIiB8fCBhdHRhY2htZW50TmFtZS5sZW5ndGggPCAxKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmZyb250ZW5kTW9kZWxFcnJvclBheWxvYWQoXCJFeHBlY3RlZCBhdHRhY2htZW50TmFtZS5cIilcbiAgICAgIH1cblxuICAgICAgaWYgKHR5cGVvZiBhdHRhY2htZW50SW5wdXQgPT09IFwidW5kZWZpbmVkXCIpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZnJvbnRlbmRNb2RlbEVycm9yUGF5bG9hZChcIkV4cGVjdGVkIGF0dGFjaG1lbnQgaW5wdXQuXCIpXG4gICAgICB9XG5cbiAgICAgIGNvbnN0IG1vZGVsID0gYXdhaXQgdGhpcy5mcm9udGVuZE1vZGVsRmluZFJlY29yZChcImF0dGFjaFwiLCBpZClcblxuICAgICAgaWYgKCFtb2RlbCkge1xuICAgICAgICByZXR1cm4gdGhpcy5mcm9udGVuZE1vZGVsRXJyb3JQYXlsb2FkKGAke21vZGVsQ2xhc3MubmFtZX0gbm90IGZvdW5kLmApXG4gICAgICB9XG5cbiAgICAgIGF3YWl0IG1vZGVsLmdldEF0dGFjaG1lbnRCeU5hbWUoYXR0YWNobWVudE5hbWUpLmF0dGFjaChhdHRhY2htZW50SW5wdXQpXG4gICAgICBjb25zdCBzZXJpYWxpemVkTW9kZWwgPSBhd2FpdCB0aGlzLnNlcmlhbGl6ZUZyb250ZW5kTW9kZWwobW9kZWwpXG5cbiAgICAgIHJldHVybiBmcm9udGVuZE1vZGVsU2VyaWFsaXplZE1vZGVsU3VjY2VzcyhzZXJpYWxpemVkTW9kZWwpXG4gICAgfVxuXG4gICAgaWYgKGFjdGlvbiA9PT0gXCJkb3dubG9hZFwiKSB7XG4gICAgICBjb25zdCBhdHRhY2htZW50UGFyYW1zID0gZnJvbnRlbmRNb2RlbEF0dGFjaG1lbnRQYXJhbXMocGFyYW1zKVxuICAgICAgaWYgKHR5cGVvZiBhdHRhY2htZW50UGFyYW1zID09PSBcInN0cmluZ1wiKSByZXR1cm4gdGhpcy5mcm9udGVuZE1vZGVsRXJyb3JQYXlsb2FkKGF0dGFjaG1lbnRQYXJhbXMpXG5cbiAgICAgIGNvbnN0IG1vZGVsID0gYXdhaXQgdGhpcy5mcm9udGVuZE1vZGVsRmluZFJlY29yZChcImRvd25sb2FkXCIsIGlkKVxuXG4gICAgICBpZiAoIW1vZGVsKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmZyb250ZW5kTW9kZWxFcnJvclBheWxvYWQoYCR7bW9kZWxDbGFzcy5uYW1lfSBub3QgZm91bmQuYClcbiAgICAgIH1cblxuICAgICAgY29uc3QgZG93bmxvYWRlZEF0dGFjaG1lbnQgPSBhd2FpdCBtb2RlbC5nZXRBdHRhY2htZW50QnlOYW1lKGF0dGFjaG1lbnRQYXJhbXMuYXR0YWNobWVudE5hbWUpLmRvd25sb2FkKGF0dGFjaG1lbnRQYXJhbXMuYXR0YWNobWVudElkKVxuXG4gICAgICBpZiAoIWRvd25sb2FkZWRBdHRhY2htZW50KSB7XG4gICAgICAgIHJldHVybiB0aGlzLmZyb250ZW5kTW9kZWxFcnJvclBheWxvYWQoXCJBdHRhY2htZW50IG5vdCBmb3VuZC5cIilcbiAgICAgIH1cblxuICAgICAgcmV0dXJuIHtcbiAgICAgICAgYXR0YWNobWVudDoge1xuICAgICAgICAgIGJ5dGVTaXplOiBkb3dubG9hZGVkQXR0YWNobWVudC5ieXRlU2l6ZSgpLFxuICAgICAgICAgIGNvbnRlbnRCYXNlNjQ6IGRvd25sb2FkZWRBdHRhY2htZW50LmNvbnRlbnQoKS50b1N0cmluZyhcImJhc2U2NFwiKSxcbiAgICAgICAgICBjb250ZW50VHlwZTogZG93bmxvYWRlZEF0dGFjaG1lbnQuY29udGVudFR5cGUoKSxcbiAgICAgICAgICBmaWxlbmFtZTogZG93bmxvYWRlZEF0dGFjaG1lbnQuZmlsZW5hbWUoKSxcbiAgICAgICAgICBpZDogZG93bmxvYWRlZEF0dGFjaG1lbnQuaWQoKSxcbiAgICAgICAgICB1cmw6IGRvd25sb2FkZWRBdHRhY2htZW50LnVybCgpXG4gICAgICAgIH0sXG4gICAgICAgIHN0YXR1czogXCJzdWNjZXNzXCJcbiAgICAgIH1cbiAgICB9XG5cbiAgICBpZiAoYWN0aW9uID09PSBcInVybFwiKSB7XG4gICAgICBjb25zdCBhdHRhY2htZW50UGFyYW1zID0gZnJvbnRlbmRNb2RlbEF0dGFjaG1lbnRQYXJhbXMocGFyYW1zKVxuICAgICAgaWYgKHR5cGVvZiBhdHRhY2htZW50UGFyYW1zID09PSBcInN0cmluZ1wiKSByZXR1cm4gdGhpcy5mcm9udGVuZE1vZGVsRXJyb3JQYXlsb2FkKGF0dGFjaG1lbnRQYXJhbXMpXG5cbiAgICAgIGNvbnN0IG1vZGVsID0gYXdhaXQgdGhpcy5mcm9udGVuZE1vZGVsRmluZFJlY29yZChcInVybFwiLCBpZClcblxuICAgICAgaWYgKCFtb2RlbCkge1xuICAgICAgICByZXR1cm4gdGhpcy5mcm9udGVuZE1vZGVsRXJyb3JQYXlsb2FkKGAke21vZGVsQ2xhc3MubmFtZX0gbm90IGZvdW5kLmApXG4gICAgICB9XG5cbiAgICAgIGNvbnN0IHVybCA9IGF3YWl0IG1vZGVsLmdldEF0dGFjaG1lbnRCeU5hbWUoYXR0YWNobWVudFBhcmFtcy5hdHRhY2htZW50TmFtZSkudXJsKGF0dGFjaG1lbnRQYXJhbXMuYXR0YWNobWVudElkKVxuXG4gICAgICBpZiAoIXVybCkge1xuICAgICAgICByZXR1cm4gdGhpcy5mcm9udGVuZE1vZGVsRXJyb3JQYXlsb2FkKFwiQXR0YWNobWVudCBVUkwgbm90IGF2YWlsYWJsZS5cIilcbiAgICAgIH1cblxuICAgICAgcmV0dXJuIHtcbiAgICAgICAgc3RhdHVzOiBcInN1Y2Nlc3NcIixcbiAgICAgICAgdXJsXG4gICAgICB9XG4gICAgfVxuXG4gICAgaWYgKGFjdGlvbiA9PT0gXCJmaW5kXCIpIHtcbiAgICAgIGNvbnN0IG1vZGVsID0gYXdhaXQgdGhpcy5mcm9udGVuZE1vZGVsRmluZFJlY29yZChcImZpbmRcIiwgaWQpXG5cbiAgICAgIGlmICghbW9kZWwpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZnJvbnRlbmRNb2RlbEVycm9yUGF5bG9hZChgJHttb2RlbENsYXNzLm5hbWV9IG5vdCBmb3VuZC5gKVxuICAgICAgfVxuXG4gICAgICBhd2FpdCB0aGlzLmZyb250ZW5kTW9kZWxDb21wdXRlQWJpbGl0aWVzKFttb2RlbF0pXG4gICAgICBjb25zdCBzZXJpYWxpemVkTW9kZWwgPSBhd2FpdCByZXNvdXJjZS5zZXJpYWxpemUobW9kZWwsIFwiZmluZFwiKVxuXG4gICAgICByZXR1cm4gZnJvbnRlbmRNb2RlbFNlcmlhbGl6ZWRNb2RlbFN1Y2Nlc3Moc2VyaWFsaXplZE1vZGVsKVxuICAgIH1cblxuICAgIGlmIChhY3Rpb24gPT09IFwidXBkYXRlXCIpIHtcbiAgICAgIGNvbnN0IG11dGF0aW9uQXR0cmlidXRlcyA9IGZyb250ZW5kTW9kZWxNdXRhdGlvbkF0dHJpYnV0ZXMocGFyYW1zKVxuICAgICAgaWYgKHR5cGVvZiBtdXRhdGlvbkF0dHJpYnV0ZXMgPT09IFwic3RyaW5nXCIpIHJldHVybiB0aGlzLmZyb250ZW5kTW9kZWxFcnJvclBheWxvYWQobXV0YXRpb25BdHRyaWJ1dGVzKVxuXG4gICAgICBjb25zdCBtb2RlbCA9IGF3YWl0IHRoaXMuZnJvbnRlbmRNb2RlbEZpbmRSZWNvcmQoXCJ1cGRhdGVcIiwgaWQpXG5cbiAgICAgIGlmICghbW9kZWwpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZnJvbnRlbmRNb2RlbEVycm9yUGF5bG9hZChgJHttb2RlbENsYXNzLm5hbWV9IG5vdCBmb3VuZC5gKVxuICAgICAgfVxuXG4gICAgICBjb25zdCB1cGRhdGVkTW9kZWwgPSBhd2FpdCByZXNvdXJjZS51cGRhdGUobW9kZWwsIG11dGF0aW9uQXR0cmlidXRlcy5hdHRyaWJ1dGVzLCB7bmVzdGVkQXR0cmlidXRlczogbXV0YXRpb25BdHRyaWJ1dGVzLm5lc3RlZEF0dHJpYnV0ZXMsIGNvbnRyb2xsZXI6IHRoaXN9KVxuICAgICAgY29uc3Qgc2VyaWFsaXplZE1vZGVsID0gYXdhaXQgcmVzb3VyY2Uuc2VyaWFsaXplKHVwZGF0ZWRNb2RlbCwgXCJ1cGRhdGVcIilcblxuICAgICAgcmV0dXJuIGZyb250ZW5kTW9kZWxTZXJpYWxpemVkTW9kZWxTdWNjZXNzKHNlcmlhbGl6ZWRNb2RlbClcbiAgICB9XG5cbiAgICBjb25zdCBtb2RlbCA9IGF3YWl0IHRoaXMuZnJvbnRlbmRNb2RlbEZpbmRSZWNvcmQoXCJkZXN0cm95XCIsIGlkKVxuXG4gICAgaWYgKCFtb2RlbCkge1xuICAgICAgcmV0dXJuIHRoaXMuZnJvbnRlbmRNb2RlbEVycm9yUGF5bG9hZChgJHttb2RlbENsYXNzLm5hbWV9IG5vdCBmb3VuZC5gKVxuICAgIH1cblxuICAgIGF3YWl0IHJlc291cmNlLmRlc3Ryb3kobW9kZWwpXG5cbiAgICByZXR1cm4ge3N0YXR1czogXCJzdWNjZXNzXCJ9XG4gIH1cblxuICAvKipcbiAgICogUnVucyBmcm9udGVuZCBhcGkuXG4gICAqIEByZXR1cm5zIHtQcm9taXNlPHZvaWQ+fSAtIFNoYXJlZCBmcm9udGVuZCBtb2RlbCBBUEkgYWN0aW9uIHdpdGggYmF0Y2ggc3VwcG9ydC5cbiAgICovXG4gIGFzeW5jIGZyb250ZW5kQXBpKCkge1xuICAgIGlmICh0aGlzLnJlcXVlc3QoKS5odHRwTWV0aG9kKCkgPT09IFwiT1BUSU9OU1wiKSB7XG4gICAgICBhd2FpdCB0aGlzLnJlbmRlcih7c3RhdHVzOiAyMDQsIGpzb246IHt9fSlcbiAgICAgIHJldHVyblxuICAgIH1cblxuICAgIGNvbnN0IHBhcmFtcyA9IC8qKlxuICAgICAgICAgICAgICAgICAgICAqIFR5cGVzIHRoZSBmb2xsb3dpbmcgdmFsdWUuXG4gICAgICAgICAgICAgICAgICAgICBAdHlwZSB7UmVjb3JkPHN0cmluZywgPz59ICovIChkZXNlcmlhbGl6ZUZyb250ZW5kTW9kZWxUcmFuc3BvcnRWYWx1ZSh0aGlzLnBhcmFtcygpKSlcbiAgICBjb25zdCByZXF1ZXN0cyA9IEFycmF5LmlzQXJyYXkocGFyYW1zLnJlcXVlc3RzKSA/IHBhcmFtcy5yZXF1ZXN0cyA6IFtwYXJhbXNdXG4gICAgLyoqXG4gICAgICogUmVzcG9uc2VzLlxuICAgICAgQHR5cGUge0FycmF5PFJlY29yZDxzdHJpbmcsID8+Pn0gKi9cbiAgICBjb25zdCByZXNwb25zZXMgPSBbXVxuXG4gICAgZm9yIChjb25zdCByZXF1ZXN0RW50cnkgb2YgcmVxdWVzdHMpIHtcbiAgICAgIGNvbnN0IGNvbW1hbmRUeXBlID0gcmVxdWVzdEVudHJ5Py5jb21tYW5kVHlwZVxuICAgICAgY29uc3QgY3VzdG9tUGF0aCA9IHJlcXVlc3RFbnRyeT8uY3VzdG9tUGF0aFxuICAgICAgY29uc3QgbW9kZWwgPSByZXF1ZXN0RW50cnk/Lm1vZGVsXG4gICAgICBjb25zdCBwYXlsb2FkID0gcmVxdWVzdEVudHJ5Py5wYXlsb2FkXG4gICAgICBjb25zdCByZXF1ZXN0SWQgPSByZXF1ZXN0RW50cnk/LnJlcXVlc3RJZFxuXG4gICAgICBpZiAodHlwZW9mIG1vZGVsICE9PSBcInN0cmluZ1wiIHx8IG1vZGVsLmxlbmd0aCA8IDEpIHtcbiAgICAgICAgcmVzcG9uc2VzLnB1c2goe1xuICAgICAgICAgIHJlcXVlc3RJZCxcbiAgICAgICAgICByZXNwb25zZTogdGhpcy5mcm9udGVuZE1vZGVsRXJyb3JQYXlsb2FkKFwiRXhwZWN0ZWQgcmVxdWVzdCBtb2RlbC5cIilcbiAgICAgICAgfSlcbiAgICAgICAgY29udGludWVcbiAgICAgIH1cblxuICAgICAgY29uc3QgaXNCdWlsdEluQ29tbWFuZCA9IFtcImluZGV4XCIsIFwiZmluZFwiLCBcImNyZWF0ZVwiLCBcInVwZGF0ZVwiLCBcImRlc3Ryb3lcIiwgXCJhdHRhY2hcIiwgXCJkb3dubG9hZFwiLCBcInVybFwiXS5pbmNsdWRlcyhjb21tYW5kVHlwZSlcblxuICAgICAgaWYgKCFpc0J1aWx0SW5Db21tYW5kICYmICh0eXBlb2YgY3VzdG9tUGF0aCAhPT0gXCJzdHJpbmdcIiB8fCAhY3VzdG9tUGF0aC5zdGFydHNXaXRoKFwiL1wiKSkpIHtcbiAgICAgICAgcmVzcG9uc2VzLnB1c2goe1xuICAgICAgICAgIHJlcXVlc3RJZCxcbiAgICAgICAgICByZXNwb25zZTogdGhpcy5mcm9udGVuZE1vZGVsRXJyb3JQYXlsb2FkKFwiRXhwZWN0ZWQgcmVxdWVzdCBjdXN0b21QYXRoLlwiKVxuICAgICAgICB9KVxuICAgICAgICBjb250aW51ZVxuICAgICAgfVxuXG4gICAgICB0cnkge1xuICAgICAgICBsZXQgcmVzcG9uc2VQYXlsb2FkXG5cbiAgICAgICAgaWYgKGlzQnVpbHRJbkNvbW1hbmQpIHtcbiAgICAgICAgICBjb25zdCBjb21tYW5kUGFyYW1zID0ge1xuICAgICAgICAgICAgLi4uKHBheWxvYWQgJiYgdHlwZW9mIHBheWxvYWQgPT09IFwib2JqZWN0XCIgPyBwYXlsb2FkIDoge30pLFxuICAgICAgICAgICAgbW9kZWxcbiAgICAgICAgICB9XG5cbiAgICAgICAgICByZXNwb25zZVBheWxvYWQgPSBhd2FpdCB0aGlzLndpdGhGcm9udGVuZE1vZGVsUGFyYW1zKGNvbW1hbmRQYXJhbXMsIGFzeW5jICgpID0+IHtcbiAgICAgICAgICAgIHJldHVybiBhd2FpdCB0aGlzLndpdGhGcm9udGVuZE1vZGVsUmVxdWVzdENvbnRleHQoY29tbWFuZFBhcmFtcywgdGhpcy5yZXNwb25zZSgpLCBhc3luYyAoKSA9PiB7XG4gICAgICAgICAgICAgIHJldHVybiBhd2FpdCB0aGlzLmZyb250ZW5kTW9kZWxDb21tYW5kUGF5bG9hZChjb21tYW5kVHlwZSlcbiAgICAgICAgICAgIH0pXG4gICAgICAgICAgfSlcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICByZXNwb25zZVBheWxvYWQgPSBhd2FpdCB0aGlzLmZyb250ZW5kQXBpQ3VzdG9tQ29tbWFuZFBheWxvYWQoe1xuICAgICAgICAgICAgY3VzdG9tUGF0aCxcbiAgICAgICAgICAgIHBheWxvYWRcbiAgICAgICAgICB9KVxuICAgICAgICB9XG5cbiAgICAgICAgcmVzcG9uc2VzLnB1c2goe1xuICAgICAgICAgIHJlcXVlc3RJZCxcbiAgICAgICAgICByZXNwb25zZTogcmVzcG9uc2VQYXlsb2FkIHx8IHRoaXMuZnJvbnRlbmRNb2RlbEVycm9yUGF5bG9hZChcIkFjdGlvbiBoYWx0ZWQgYnkgYmVmb3JlQWN0aW9uLlwiKVxuICAgICAgICB9KVxuICAgICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgICAgYXdhaXQgdGhpcy5mcm9udGVuZE1vZGVsTG9nRW5kcG9pbnRFcnJvcih7XG4gICAgICAgICAgYWN0aW9uOiBcImZyb250ZW5kQXBpXCIsXG4gICAgICAgICAgY29tbWFuZFR5cGUsXG4gICAgICAgICAgZXJyb3IsXG4gICAgICAgICAgbW9kZWwsXG4gICAgICAgICAgcmVxdWVzdElkXG4gICAgICAgIH0pXG5cbiAgICAgICAgcmVzcG9uc2VzLnB1c2goe1xuICAgICAgICAgIHJlcXVlc3RJZCxcbiAgICAgICAgICByZXNwb25zZTogdGhpcy5mcm9udGVuZE1vZGVsQ2xpZW50RXJyb3JQYXlsb2FkRm9yRXJyb3IoZXJyb3IpXG4gICAgICAgIH0pXG4gICAgICB9XG4gICAgfVxuXG4gICAgYXdhaXQgdGhpcy5yZW5kZXIoe1xuICAgICAganNvbjogLyoqXG4gICAgICAgICAgICAgKiBUeXBlcyB0aGUgZm9sbG93aW5nIHZhbHVlLlxuICAgICAgICAgICAgICBAdHlwZSB7UmVjb3JkPHN0cmluZywgPz59ICovIChzZXJpYWxpemVGcm9udGVuZE1vZGVsVHJhbnNwb3J0VmFsdWUoe1xuICAgICAgICByZXNwb25zZXMsXG4gICAgICAgIHN0YXR1czogXCJzdWNjZXNzXCJcbiAgICAgIH0pKVxuICAgIH0pXG4gIH1cblxuICAvKipcbiAgICogRGlzcGF0Y2hlcyBhIGN1c3RvbSBmcm9udGVuZC1tb2RlbCBjb21tYW5kIHRocm91Z2ggdGhlIHNoYXJlZCBmcm9udGVuZC1tb2RlbCBBUEkgZW5kcG9pbnQuXG4gICAqIEBwYXJhbSB7b2JqZWN0fSBhcmdzIC0gQXJndW1lbnRzLlxuICAgKiBAcGFyYW0ge3N0cmluZ30gYXJncy5jdXN0b21QYXRoIC0gQ3VzdG9tIGJhY2tlbmQgcm91dGUgcGF0aC5cbiAgICogQHBhcmFtIHs/fSBhcmdzLnBheWxvYWQgLSBSZXF1ZXN0IHBheWxvYWQuXG4gICAqIEByZXR1cm5zIHtQcm9taXNlPFJlY29yZDxzdHJpbmcsID8+Pn0gLSBQYXJzZWQgSlNPTiByZXNwb25zZSBwYXlsb2FkLlxuICAgKi9cbiAgYXN5bmMgZnJvbnRlbmRBcGlDdXN0b21Db21tYW5kUGF5bG9hZCh7Y3VzdG9tUGF0aCwgcGF5bG9hZH0pIHtcbiAgICBjb25zdCBjb25maWd1cmF0aW9uID0gdGhpcy5nZXRDb25maWd1cmF0aW9uKClcbiAgICBjb25zdCByZXNwb25zZSA9IG5ldyBSZXNwb25zZSh7Y29uZmlndXJhdGlvbn0pXG4gICAgY29uc3QgcmVzb2x2ZXIgPSBuZXcgUm91dGVzUmVzb2x2ZXIoe1xuICAgICAgY29uZmlndXJhdGlvbixcbiAgICAgIHJlcXVlc3Q6IHRoaXMuZ2V0UmVxdWVzdCgpLFxuICAgICAgcmVzcG9uc2VcbiAgICB9KVxuICAgIHJlc29sdmVyLnBhcmFtcyA9IHt9XG4gICAgY29uc3Qgcm91dGVIb29rTWF0Y2ggPSBhd2FpdCByZXNvbHZlci5yZXNvbHZlUm91dGVSZXNvbHZlckhvb2tzKGN1c3RvbVBhdGgpXG4gICAgY29uc3QgY29uZmlndXJhdGlvblJvdXRlcyA9IGNvbmZpZ3VyYXRpb24uZ2V0Um91dGVzKClcbiAgICBjb25zdCByb3V0ZU1hdGNoID0gcm91dGVIb29rTWF0Y2ggfHwgIWNvbmZpZ3VyYXRpb25Sb3V0ZXM/LnJvb3RSb3V0ZSA/IHVuZGVmaW5lZCA6IHJlc29sdmVyLm1hdGNoUGF0aFdpdGhSb3V0ZXMoY29uZmlndXJhdGlvblJvdXRlcy5yb290Um91dGUsIGN1c3RvbVBhdGgpXG5cbiAgICBpZiAoIXJvdXRlSG9va01hdGNoICYmICFyb3V0ZU1hdGNoKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoYE5vIGN1c3RvbSBmcm9udGVuZCBtb2RlbCByb3V0ZSBtYXRjaGVkICcke2N1c3RvbVBhdGh9J2ApXG4gICAgfVxuXG4gICAgY29uc3QgYWN0aW9uUGFyYW0gPSByb3V0ZUhvb2tNYXRjaD8uYWN0aW9uIHx8IHJlc29sdmVyLnBhcmFtcy5hY3Rpb25cbiAgICBjb25zdCBjb250cm9sbGVyUGFyYW0gPSByb3V0ZUhvb2tNYXRjaD8uY29udHJvbGxlciB8fCByZXNvbHZlci5wYXJhbXMuY29udHJvbGxlclxuICAgIGNvbnN0IGFjdGlvblZhbHVlID0gdHlwZW9mIGFjdGlvblBhcmFtID09PSBcInN0cmluZ1wiID8gYWN0aW9uUGFyYW0gOiAoQXJyYXkuaXNBcnJheShhY3Rpb25QYXJhbSkgPyBhY3Rpb25QYXJhbVswXSA6IHVuZGVmaW5lZClcbiAgICBjb25zdCBjb250cm9sbGVyVmFsdWUgPSB0eXBlb2YgY29udHJvbGxlclBhcmFtID09PSBcInN0cmluZ1wiID8gY29udHJvbGxlclBhcmFtIDogKEFycmF5LmlzQXJyYXkoY29udHJvbGxlclBhcmFtKSA/IGNvbnRyb2xsZXJQYXJhbVswXSA6IHVuZGVmaW5lZClcblxuICAgIGlmICh0eXBlb2YgYWN0aW9uVmFsdWUgIT09IFwic3RyaW5nXCIgfHwgYWN0aW9uVmFsdWUubGVuZ3RoIDwgMSB8fCB0eXBlb2YgY29udHJvbGxlclZhbHVlICE9PSBcInN0cmluZ1wiIHx8IGNvbnRyb2xsZXJWYWx1ZS5sZW5ndGggPCAxKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoYEN1c3RvbSBmcm9udGVuZCBtb2RlbCByb3V0ZSBtYXRjaGVkICcke2N1c3RvbVBhdGh9JyB3aXRob3V0IGNvbnRyb2xsZXIvYWN0aW9uIHBhcmFtc2ApXG4gICAgfVxuXG4gICAgY29uc3QgYWN0aW9uID0gaW5mbGVjdGlvbi5jYW1lbGl6ZShhY3Rpb25WYWx1ZS5yZXBsYWNlQWxsKFwiLVwiLCBcIl9cIikucmVwbGFjZUFsbChcIi9cIiwgXCJfXCIpLCB0cnVlKVxuICAgIGNvbnN0IGNvbnRyb2xsZXIgPSBjb250cm9sbGVyVmFsdWVcbiAgICBjb25zdCBjb250cm9sbGVyUGF0aCA9IHJvdXRlSG9va01hdGNoPy5jb250cm9sbGVyUGF0aCB8fCBgJHtjb25maWd1cmF0aW9uLmdldERpcmVjdG9yeSgpfS9zcmMvcm91dGVzLyR7Y29udHJvbGxlcn0vY29udHJvbGxlci5qc2BcbiAgICBjb25zdCB2aWV3UGF0aCA9IHJvdXRlSG9va01hdGNoPy52aWV3UGF0aCB8fCBgJHtjb25maWd1cmF0aW9uLmdldERpcmVjdG9yeSgpfS9zcmMvcm91dGVzLyR7Y29udHJvbGxlcn1gXG4gICAgcmVzb2x2ZXIucm91dGVIb29rQ29udHJvbGxlckNsYXNzID0gcm91dGVIb29rTWF0Y2g/LmNvbnRyb2xsZXJDbGFzc1xuICAgIGNvbnN0IGNvbnRyb2xsZXJDbGFzcyA9IGF3YWl0IHJlc29sdmVyLnJlc29sdmVDb250cm9sbGVyQ2xhc3Moe2NvbnRyb2xsZXJQYXRofSlcbiAgICBjb25zdCBjb250cm9sbGVyUGFyYW1zID0ge1xuICAgICAgLi4uKChwYXlsb2FkICYmIHR5cGVvZiBwYXlsb2FkID09PSBcIm9iamVjdFwiKSA/IHBheWxvYWQgOiB7fSksXG4gICAgICAuLi5yZXNvbHZlci5wYXJhbXNcbiAgICB9XG4gICAgY29uc3QgY29udHJvbGxlckluc3RhbmNlID0gbmV3IGNvbnRyb2xsZXJDbGFzcyh7XG4gICAgICBhY3Rpb24sXG4gICAgICBjb25maWd1cmF0aW9uLFxuICAgICAgY29udHJvbGxlcixcbiAgICAgIHBhcmFtczogY29udHJvbGxlclBhcmFtcyxcbiAgICAgIHJlcXVlc3Q6IC8qKlxuICAgICAgICAgICAgICAgICogVHlwZXMgdGhlIGZvbGxvd2luZyB2YWx1ZS5cbiAgICAgICAgICAgICAgICAgQHR5cGUge2ltcG9ydChcIi4vaHR0cC1zZXJ2ZXIvY2xpZW50L3JlcXVlc3QuanNcIikuZGVmYXVsdH0gKi8gKHRoaXMuZ2V0UmVxdWVzdCgpKSxcbiAgICAgIHJlc3BvbnNlLFxuICAgICAgdmlld1BhdGhcbiAgICB9KVxuXG4gICAgYXdhaXQgdGhpcy53aXRoRnJvbnRlbmRNb2RlbFJlcXVlc3RDb250ZXh0KGNvbnRyb2xsZXJQYXJhbXMsIHJlc3BvbnNlLCBhc3luYyAoKSA9PiB7XG4gICAgICBhd2FpdCBjb250cm9sbGVySW5zdGFuY2UuX3J1bkJlZm9yZUNhbGxiYWNrcygpXG4gICAgICBjb25zdCBjb250cm9sbGVyTWV0aG9kcyA9IC8qKlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKiBUeXBlcyB0aGUgZm9sbG93aW5nIHZhbHVlLlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEB0eXBlIHtSZWNvcmQ8c3RyaW5nLCAoKSA9PiBQcm9taXNlPHZvaWQ+IHwgdm9pZD59ICovICgvKipcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICogVHlwZXMgdGhlIGZvbGxvd2luZyB2YWx1ZS5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBAdHlwZSB7P30gKi8gKGNvbnRyb2xsZXJJbnN0YW5jZSkpXG5cbiAgICAgIGF3YWl0IGNvbnRyb2xsZXJNZXRob2RzW2FjdGlvbl0oKVxuICAgIH0pXG5cbiAgICBjb25zdCBzZXRDb29raWVIZWFkZXJzID0gcmVzcG9uc2UuaGVhZGVyc1tcIlNldC1Db29raWVcIl0gfHwgW11cblxuICAgIGZvciAoY29uc3Qgc2V0Q29va2llSGVhZGVyIG9mIHNldENvb2tpZUhlYWRlcnMpIHtcbiAgICAgIHRoaXMucmVzcG9uc2UoKS5hZGRIZWFkZXIoXCJTZXQtQ29va2llXCIsIHNldENvb2tpZUhlYWRlcilcbiAgICB9XG5cbiAgICBjb25zdCByZXNwb25zZUJvZHkgPSByZXNwb25zZS5nZXRCb2R5KClcblxuICAgIGlmICh0eXBlb2YgcmVzcG9uc2VCb2R5ICE9PSBcInN0cmluZ1wiIHx8IHJlc3BvbnNlQm9keS5sZW5ndGggPCAxKSB7XG4gICAgICByZXR1cm4ge31cbiAgICB9XG5cbiAgICAvLyBQcmVzZXJ2ZSBuZXN0ZWQgdHJhbnNwb3J0IG1hcmtlcnMgc28gdGhlIG91dGVyIHNoYXJlZCBmcm9udGVuZC1tb2RlbCBBUElcbiAgICAvLyBjYW4gcmV0dXJuIHRoZW0gdW5jaGFuZ2VkIGFuZCBsZXQgdGhlIGNsaWVudCBoeWRyYXRlIG9uY2UgYXQgdGhlIGVkZ2UuXG4gICAgcmV0dXJuIC8qKiBOYXJyb3dzIHRoZSBydW50aW1lIHZhbHVlIHRvIHRoZSBkb2N1bWVudGVkIHR5cGUuIEB0eXBlIHtSZWNvcmQ8c3RyaW5nLCA/Pn0gKi8gKEpTT04ucGFyc2UocmVzcG9uc2VCb2R5KSlcbiAgfVxuXG4gIC8qKlxuICAgKiBSdW5zIGZyb250ZW5kIGluZGV4LlxuICAgKiBAcmV0dXJucyB7UHJvbWlzZTx2b2lkPn0gLSBDb2xsZWN0aW9uIGFjdGlvbiBmb3IgZnJvbnRlbmQgbW9kZWwgcmVzb3VyY2VzLlxuICAgKi9cbiAgYXN5bmMgZnJvbnRlbmRJbmRleCgpIHtcbiAgICBpZiAodGhpcy5yZXF1ZXN0KCkuaHR0cE1ldGhvZCgpID09PSBcIk9QVElPTlNcIikge1xuICAgICAgYXdhaXQgdGhpcy5yZW5kZXIoe3N0YXR1czogMjA0LCBqc29uOiB7fX0pXG4gICAgICByZXR1cm5cbiAgICB9XG5cbiAgICBhd2FpdCB0aGlzLmZyb250ZW5kTW9kZWxSZW5kZXJDb21tYW5kUmVzcG9uc2UoXCJpbmRleFwiKVxuICB9XG5cbiAgLyoqXG4gICAqIFJ1bnMgZnJvbnRlbmQgZmluZC5cbiAgICogQHJldHVybnMge1Byb21pc2U8dm9pZD59IC0gTWVtYmVyIGZpbmQgYWN0aW9uIGZvciBmcm9udGVuZCBtb2RlbCByZXNvdXJjZXMuXG4gICAqL1xuICBhc3luYyBmcm9udGVuZEZpbmQoKSB7XG4gICAgaWYgKHRoaXMucmVxdWVzdCgpLmh0dHBNZXRob2QoKSA9PT0gXCJPUFRJT05TXCIpIHtcbiAgICAgIGF3YWl0IHRoaXMucmVuZGVyKHtzdGF0dXM6IDIwNCwganNvbjoge319KVxuICAgICAgcmV0dXJuXG4gICAgfVxuXG4gICAgYXdhaXQgdGhpcy5mcm9udGVuZE1vZGVsUmVuZGVyQ29tbWFuZFJlc3BvbnNlKFwiZmluZFwiKVxuICB9XG5cbiAgLyoqXG4gICAqIFJ1bnMgZnJvbnRlbmQgdXBkYXRlLlxuICAgKiBAcmV0dXJucyB7UHJvbWlzZTx2b2lkPn0gLSBNZW1iZXIgdXBkYXRlIGFjdGlvbiBmb3IgZnJvbnRlbmQgbW9kZWwgcmVzb3VyY2VzLlxuICAgKi9cbiAgYXN5bmMgZnJvbnRlbmRVcGRhdGUoKSB7XG4gICAgaWYgKHRoaXMucmVxdWVzdCgpLmh0dHBNZXRob2QoKSA9PT0gXCJPUFRJT05TXCIpIHtcbiAgICAgIGF3YWl0IHRoaXMucmVuZGVyKHtzdGF0dXM6IDIwNCwganNvbjoge319KVxuICAgICAgcmV0dXJuXG4gICAgfVxuXG4gICAgYXdhaXQgdGhpcy5mcm9udGVuZE1vZGVsUmVuZGVyQ29tbWFuZFJlc3BvbnNlKFwidXBkYXRlXCIpXG4gIH1cblxuICAvKipcbiAgICogUnVucyBmcm9udGVuZCBhdHRhY2guXG4gICAqIEByZXR1cm5zIHtQcm9taXNlPHZvaWQ+fSAtIE1lbWJlciBhdHRhY2ggYWN0aW9uIGZvciBmcm9udGVuZCBtb2RlbCByZXNvdXJjZXMuXG4gICAqL1xuICBhc3luYyBmcm9udGVuZEF0dGFjaCgpIHtcbiAgICBpZiAodGhpcy5yZXF1ZXN0KCkuaHR0cE1ldGhvZCgpID09PSBcIk9QVElPTlNcIikge1xuICAgICAgYXdhaXQgdGhpcy5yZW5kZXIoe3N0YXR1czogMjA0LCBqc29uOiB7fX0pXG4gICAgICByZXR1cm5cbiAgICB9XG5cbiAgICBhd2FpdCB0aGlzLmZyb250ZW5kTW9kZWxSZW5kZXJDb21tYW5kUmVzcG9uc2UoXCJhdHRhY2hcIilcbiAgfVxuXG4gIC8qKlxuICAgKiBSdW5zIGZyb250ZW5kIGRvd25sb2FkLlxuICAgKiBAcmV0dXJucyB7UHJvbWlzZTx2b2lkPn0gLSBNZW1iZXIgZG93bmxvYWQgYWN0aW9uIGZvciBmcm9udGVuZCBtb2RlbCByZXNvdXJjZXMuXG4gICAqL1xuICBhc3luYyBmcm9udGVuZERvd25sb2FkKCkge1xuICAgIGlmICh0aGlzLnJlcXVlc3QoKS5odHRwTWV0aG9kKCkgPT09IFwiT1BUSU9OU1wiKSB7XG4gICAgICBhd2FpdCB0aGlzLnJlbmRlcih7c3RhdHVzOiAyMDQsIGpzb246IHt9fSlcbiAgICAgIHJldHVyblxuICAgIH1cblxuICAgIGF3YWl0IHRoaXMuZnJvbnRlbmRNb2RlbFJlbmRlckNvbW1hbmRSZXNwb25zZShcImRvd25sb2FkXCIpXG4gIH1cblxuICAvKipcbiAgICogUnVucyBmcm9udGVuZCB1cmwuXG4gICAqIEByZXR1cm5zIHtQcm9taXNlPHZvaWQ+fSAtIE1lbWJlciBVUkwgYWN0aW9uIGZvciBmcm9udGVuZCBtb2RlbCByZXNvdXJjZXMuXG4gICAqL1xuICBhc3luYyBmcm9udGVuZFVybCgpIHtcbiAgICBpZiAodGhpcy5yZXF1ZXN0KCkuaHR0cE1ldGhvZCgpID09PSBcIk9QVElPTlNcIikge1xuICAgICAgYXdhaXQgdGhpcy5yZW5kZXIoe3N0YXR1czogMjA0LCBqc29uOiB7fX0pXG4gICAgICByZXR1cm5cbiAgICB9XG5cbiAgICBhd2FpdCB0aGlzLmZyb250ZW5kTW9kZWxSZW5kZXJDb21tYW5kUmVzcG9uc2UoXCJ1cmxcIilcbiAgfVxuXG4gIC8qKlxuICAgKiBSdW5zIGZyb250ZW5kIGNyZWF0ZS5cbiAgICogQHJldHVybnMge1Byb21pc2U8dm9pZD59IC0gTWVtYmVyIGNyZWF0ZSBhY3Rpb24gZm9yIGZyb250ZW5kIG1vZGVsIHJlc291cmNlcy5cbiAgICovXG4gIGFzeW5jIGZyb250ZW5kQ3JlYXRlKCkge1xuICAgIGlmICh0aGlzLnJlcXVlc3QoKS5odHRwTWV0aG9kKCkgPT09IFwiT1BUSU9OU1wiKSB7XG4gICAgICBhd2FpdCB0aGlzLnJlbmRlcih7c3RhdHVzOiAyMDQsIGpzb246IHt9fSlcbiAgICAgIHJldHVyblxuICAgIH1cblxuICAgIGF3YWl0IHRoaXMuZnJvbnRlbmRNb2RlbFJlbmRlckNvbW1hbmRSZXNwb25zZShcImNyZWF0ZVwiKVxuICB9XG5cbiAgLyoqXG4gICAqIFJ1bnMgZnJvbnRlbmQgZGVzdHJveS5cbiAgICogQHJldHVybnMge1Byb21pc2U8dm9pZD59IC0gTWVtYmVyIGRlc3Ryb3kgYWN0aW9uIGZvciBmcm9udGVuZCBtb2RlbCByZXNvdXJjZXMuXG4gICAqL1xuICBhc3luYyBmcm9udGVuZERlc3Ryb3koKSB7XG4gICAgaWYgKHRoaXMucmVxdWVzdCgpLmh0dHBNZXRob2QoKSA9PT0gXCJPUFRJT05TXCIpIHtcbiAgICAgIGF3YWl0IHRoaXMucmVuZGVyKHtzdGF0dXM6IDIwNCwganNvbjoge319KVxuICAgICAgcmV0dXJuXG4gICAgfVxuXG4gICAgYXdhaXQgdGhpcy5mcm9udGVuZE1vZGVsUmVuZGVyQ29tbWFuZFJlc3BvbnNlKFwiZGVzdHJveVwiKVxuICB9XG5cbiAgLyoqXG4gICAqIFJ1bnMgZnJvbnRlbmQgY3VzdG9tIGNvbW1hbmQuXG4gICAqIEByZXR1cm5zIHtQcm9taXNlPHZvaWQ+fSAtIEN1c3RvbSBjb2xsZWN0aW9uL21lbWJlciBjb21tYW5kIGFjdGlvbiBmb3IgZnJvbnRlbmQtbW9kZWwgcmVzb3VyY2VzLlxuICAgKi9cbiAgYXN5bmMgZnJvbnRlbmRDdXN0b21Db21tYW5kKCkge1xuICAgIGlmICh0aGlzLnJlcXVlc3QoKS5odHRwTWV0aG9kKCkgPT09IFwiT1BUSU9OU1wiKSB7XG4gICAgICBhd2FpdCB0aGlzLnJlbmRlcih7c3RhdHVzOiAyMDQsIGpzb246IHt9fSlcbiAgICAgIHJldHVyblxuICAgIH1cblxuICAgIHRyeSB7XG4gICAgICBjb25zdCByZXNwb25zZVBheWxvYWQgPSBhd2FpdCB0aGlzLmZyb250ZW5kTW9kZWxDdXN0b21Db21tYW5kUGF5bG9hZCgpXG5cbiAgICAgIGF3YWl0IHRoaXMucmVuZGVyKHtcbiAgICAgICAganNvbjogLyoqXG4gICAgICAgICAgICAgICAqIFR5cGVzIHRoZSBmb2xsb3dpbmcgdmFsdWUuXG4gICAgICAgICAgICAgICAgQHR5cGUge1JlY29yZDxzdHJpbmcsID8+fSAqLyAoc2VyaWFsaXplRnJvbnRlbmRNb2RlbFRyYW5zcG9ydFZhbHVlKHJlc3BvbnNlUGF5bG9hZCkpXG4gICAgICB9KVxuICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICBhd2FpdCB0aGlzLmZyb250ZW5kTW9kZWxMb2dFbmRwb2ludEVycm9yKHthY3Rpb246IFwiZnJvbnRlbmRDdXN0b21Db21tYW5kXCIsIGNvbW1hbmRUeXBlOiBcImN1c3RvbS1jb21tYW5kXCIsIGVycm9yfSlcblxuICAgICAgYXdhaXQgdGhpcy5yZW5kZXIoe1xuICAgICAgICBqc29uOiAvKipcbiAgICAgICAgICAgICAgICogVHlwZXMgdGhlIGZvbGxvd2luZyB2YWx1ZS5cbiAgICAgICAgICAgICAgICBAdHlwZSB7UmVjb3JkPHN0cmluZywgPz59ICovIChzZXJpYWxpemVGcm9udGVuZE1vZGVsVHJhbnNwb3J0VmFsdWUodGhpcy5mcm9udGVuZE1vZGVsQ2xpZW50RXJyb3JQYXlsb2FkRm9yRXJyb3IoZXJyb3IpKSlcbiAgICAgIH0pXG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIFJ1bnMgZnJvbnRlbmQgbW9kZWwgY3VzdG9tIGNvbW1hbmQgcGF5bG9hZC5cbiAgICogQHJldHVybnMge1Byb21pc2U8UmVjb3JkPHN0cmluZywgPz4+fSAtIFJlc3BvbnNlIHBheWxvYWQuXG4gICAqL1xuICBhc3luYyBmcm9udGVuZE1vZGVsQ3VzdG9tQ29tbWFuZFBheWxvYWQoKSB7XG4gICAgY29uc3QgcGFyYW1zID0gdGhpcy5mcm9udGVuZE1vZGVsUGFyYW1zKClcbiAgICBjb25zdCBtZXRob2ROYW1lID0gcGFyYW1zLmZyb250ZW5kTW9kZWxDdXN0b21Db21tYW5kTWV0aG9kTmFtZVxuICAgIGNvbnN0IHNjb3BlID0gcGFyYW1zLmZyb250ZW5kTW9kZWxDdXN0b21Db21tYW5kU2NvcGVcblxuICAgIGlmICh0eXBlb2YgbWV0aG9kTmFtZSAhPT0gXCJzdHJpbmdcIiB8fCBtZXRob2ROYW1lLmxlbmd0aCA8IDEpIHtcbiAgICAgIHJldHVybiB0aGlzLmZyb250ZW5kTW9kZWxFcnJvclBheWxvYWQoXCJFeHBlY3RlZCBmcm9udGVuZC1tb2RlbCBjdXN0b20gY29tbWFuZCBtZXRob2QgbmFtZS5cIilcbiAgICB9XG5cbiAgICBpZiAoc2NvcGUgIT09IFwiY29sbGVjdGlvblwiICYmIHNjb3BlICE9PSBcIm1lbWJlclwiKSB7XG4gICAgICByZXR1cm4gdGhpcy5mcm9udGVuZE1vZGVsRXJyb3JQYXlsb2FkKFwiRXhwZWN0ZWQgZnJvbnRlbmQtbW9kZWwgY3VzdG9tIGNvbW1hbmQgc2NvcGUuXCIpXG4gICAgfVxuXG4gICAgY29uc3QgcmVzb3VyY2UgPSAvKipcbiAgICAgICAgICAgICAgICAgICAgICAqIFR5cGVzIHRoZSBmb2xsb3dpbmcgdmFsdWUuXG4gICAgICAgICAgICAgICAgICAgICAgIEB0eXBlIHtSZWNvcmQ8c3RyaW5nLCA/Pn0gKi8gKHRoaXMuZnJvbnRlbmRNb2RlbFJlc291cmNlSW5zdGFuY2UoKSlcbiAgICBjb25zdCBjb21tYW5kTWV0aG9kID0gcmVzb3VyY2VbbWV0aG9kTmFtZV1cblxuICAgIGlmICh0eXBlb2YgY29tbWFuZE1ldGhvZCAhPT0gXCJmdW5jdGlvblwiKSB7XG4gICAgICByZXR1cm4gdGhpcy5mcm9udGVuZE1vZGVsRXJyb3JQYXlsb2FkKGBNaXNzaW5nIGZyb250ZW5kLW1vZGVsIGN1c3RvbSBjb21tYW5kICcke21ldGhvZE5hbWV9Jy5gKVxuICAgIH1cblxuICAgIGNvbnN0IHJlc3BvbnNlUGF5bG9hZCA9IGF3YWl0IGNvbW1hbmRNZXRob2QuY2FsbChyZXNvdXJjZSlcblxuICAgIGlmICghcmVzcG9uc2VQYXlsb2FkIHx8IHR5cGVvZiByZXNwb25zZVBheWxvYWQgIT09IFwib2JqZWN0XCIpIHtcbiAgICAgIHJldHVybiB7c3RhdHVzOiBcInN1Y2Nlc3NcIn1cbiAgICB9XG5cbiAgICByZXR1cm4gLyoqIE5hcnJvd3MgdGhlIHJ1bnRpbWUgdmFsdWUgdG8gdGhlIGRvY3VtZW50ZWQgdHlwZS4gQHR5cGUge1JlY29yZDxzdHJpbmcsID8+fSAqLyAoXG4gICAgICBhd2FpdCB0aGlzLmF1dG9TZXJpYWxpemVGcm9udGVuZE1vZGVsc0luUGF5bG9hZChcbiAgICAgICAgcmVzcG9uc2VQYXlsb2FkLFxuICAgICAgICAvKipcbiAgICAgICAgICogVHlwZXMgdGhlIGZvbGxvd2luZyB2YWx1ZS5cbiAgICAgICAgICBAdHlwZSB7e3NlcmlhbGl6ZTogKG1vZGVsOiA/LCBhY3Rpb246IHN0cmluZykgPT4gUHJvbWlzZTxSZWNvcmQ8c3RyaW5nLCA/Pj59fSAqLyAocmVzb3VyY2UpLFxuICAgICAgICBtZXRob2ROYW1lXG4gICAgICApXG4gICAgKVxuICB9XG5cbiAgLyoqXG4gICAqIFdhbGtzIGEgY3VzdG9tLWNvbW1hbmQgcmVzcG9uc2UgcGF5bG9hZCBhbmQgcmVwbGFjZXMgYW55IGJhY2tlbmQgYFJlY29yZGBcbiAgICogaW5zdGFuY2Ugd2l0aCB0aGUgcmVzb3VyY2UncyBwZXItYWN0aW9uIHNlcmlhbGl6ZWQgZm9ybSBzbyBoYW5kbGVycyBjYW5cbiAgICogcmV0dXJuIGB7cmVjb3JkLCBzdGF0dXM6IFwib2tcIn1gIGluc3RlYWQgb2YgZXhwbGljaXRseSBjYWxsaW5nXG4gICAqIGBhd2FpdCB0aGlzLnNlcmlhbGl6ZShyZWNvcmQsIGFjdGlvbilgLiBQbGFpbiBvYmplY3RzLCBhcnJheXMsIGFuZFxuICAgKiBwcmltaXRpdmUgdmFsdWVzIHBhc3MgdGhyb3VnaCBhbmQgYXJlIGxhdGVyIGVuY29kZWQgYnlcbiAgICogYHNlcmlhbGl6ZUZyb250ZW5kTW9kZWxUcmFuc3BvcnRWYWx1ZWAuXG4gICAqIEBwYXJhbSB7P30gdmFsdWUgLSBQYXlsb2FkIHZhbHVlLlxuICAgKiBAcGFyYW0ge3tzZXJpYWxpemU6IChtb2RlbDogPywgYWN0aW9uOiBzdHJpbmcpID0+IFByb21pc2U8UmVjb3JkPHN0cmluZywgPz4+fX0gcmVzb3VyY2UgLSBSZXNvdXJjZSBpbnN0YW5jZSBwcm92aWRpbmcgYHNlcmlhbGl6ZWAuXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBhY3Rpb24gLSBDdXN0b20gY29tbWFuZCBtZXRob2QgbmFtZSBwYXNzZWQgdG8gYHJlc291cmNlLnNlcmlhbGl6ZWAgZm9yIHBlci1hY3Rpb24gYXV0aG9yaXphdGlvbiBmaWx0ZXJpbmcuXG4gICAqIEBwYXJhbSB7V2Vha1NldDxvYmplY3Q+fSBbc2Vlbl0gLSBSZWN1cnNpb24gc3RhY2sgb2YgcGxhaW4tb2JqZWN0IGNvbnRhaW5lcnMgY3VycmVudGx5IGJlaW5nIHdhbGtlZC4gTWVtYmVyc2hpcCBpcyBhZGRlZCBvbiBlbnRyeSBhbmQgcmVtb3ZlZCBvbiBleGl0IHNvIGEgY29udGFpbmVyIHNoYXJlZCBiZXR3ZWVuIHNpYmxpbmdzIChpLmUuIHJlZmVyZW5jZWQgdHdpY2UgYnV0IG5vdCBjeWNsaWNhbGx5KSBpcyB3YWxrZWQgb24gZWFjaCByZWZlcmVuY2UgaW5zdGVhZCBvZiBiZWluZyBzaG9ydC1jaXJjdWl0ZWQgdGhlIHNlY29uZCB0aW1lLCB3aGljaCB3b3VsZCBsZXQgYmFja2VuZCBgUmVjb3JkYCBpbnN0YW5jZXMgaW5zaWRlIGl0IGJ5cGFzcyBgcmVzb3VyY2Uuc2VyaWFsaXplYC5cbiAgICogQHJldHVybnMge1Byb21pc2U8Pz59IC0gUGF5bG9hZCB3aXRoIGJhY2tlbmQgYFJlY29yZGAgaW5zdGFuY2VzIHJlcGxhY2VkIGJ5IHNlcmlhbGl6ZWQgbWFya2Vycy5cbiAgICovXG4gIGFzeW5jIGF1dG9TZXJpYWxpemVGcm9udGVuZE1vZGVsc0luUGF5bG9hZCh2YWx1ZSwgcmVzb3VyY2UsIGFjdGlvbiwgc2VlbiA9IG5ldyBXZWFrU2V0KCkpIHtcbiAgICBpZiAodmFsdWUgPT09IG51bGwgfHwgdmFsdWUgPT09IHVuZGVmaW5lZCkge1xuICAgICAgcmV0dXJuIHZhbHVlXG4gICAgfVxuXG4gICAgaWYgKGlzQmFja2VuZE1vZGVsSW5zdGFuY2UodmFsdWUpKSB7XG4gICAgICBjb25zdCByaWNoU2VyaWFsaXplZCA9IGF3YWl0IHJlc291cmNlLnNlcmlhbGl6ZSh2YWx1ZSwgYWN0aW9uKVxuICAgICAgY29uc3QgbW9kZWxDbGFzcyA9IC8qKlxuICAgICAgICAgICAgICAgICAgICAgICAgICAqIFR5cGVzIHRoZSBmb2xsb3dpbmcgdmFsdWUuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICBAdHlwZSB7e2NvbnN0cnVjdG9yOiB7Z2V0TW9kZWxOYW1lPzogKCkgPT4gc3RyaW5nLCBuYW1lPzogc3RyaW5nfX19ICovICh2YWx1ZSkuY29uc3RydWN0b3JcbiAgICAgIGNvbnN0IG1vZGVsTmFtZSA9IHR5cGVvZiBtb2RlbENsYXNzLmdldE1vZGVsTmFtZSA9PT0gXCJmdW5jdGlvblwiID8gbW9kZWxDbGFzcy5nZXRNb2RlbE5hbWUoKSA6IChtb2RlbENsYXNzLm5hbWUgfHwgXCJcIilcblxuICAgICAgLy8gV3JhcCB0aGUgcmVzb3VyY2Utc2VyaWFsaXplZCBwYXlsb2FkIGluIHRoZSBmcm9udGVuZF9tb2RlbCB0cmFuc3BvcnRcbiAgICAgIC8vIG1hcmtlci4gTWFya2VyLWJhc2VkIGRlY29kaW5nIHJvdXRlcyB0aHJvdWdoIGBpbnN0YW50aWF0ZUZyb21SZXNwb25zZWAsXG4gICAgICAvLyBzbyBhYmlsaXRpZXMgLyBxdWVyeURhdGEgLyBhc3NvY2lhdGlvbkNvdW50cyAvIHByZWxvYWRlZFJlbGF0aW9uc2hpcHNcbiAgICAgIC8vIGJha2VkIGludG8gdGhlIHJpY2ggYXR0cmlidXRlcyBieSBgcmVzb3VyY2Uuc2VyaWFsaXplYCBhcmUgcmVzdG9yZWQgb25cbiAgICAgIC8vIHRoZSBjbGllbnQgd2l0aG91dCBjYWxsZXJzIG5lZWRpbmcgdG8gd3JhcCBtb2RlbHMgbWFudWFsbHkuXG4gICAgICByZXR1cm4ge1xuICAgICAgICBfX3ZlbG9jaW91c190eXBlOiBcImZyb250ZW5kX21vZGVsXCIsXG4gICAgICAgIGF0dHJpYnV0ZXM6IHJpY2hTZXJpYWxpemVkLFxuICAgICAgICBtb2RlbE5hbWVcbiAgICAgIH1cbiAgICB9XG5cbiAgICBpZiAoQXJyYXkuaXNBcnJheSh2YWx1ZSkpIHtcbiAgICAgIC8qKlxuICAgICAgICogUmVzdWx0LlxuICAgICAgICBAdHlwZSB7QXJyYXk8Pz59ICovXG4gICAgICBjb25zdCByZXN1bHQgPSBbXVxuXG4gICAgICBmb3IgKGNvbnN0IGVudHJ5IG9mIHZhbHVlKSB7XG4gICAgICAgIHJlc3VsdC5wdXNoKGF3YWl0IHRoaXMuYXV0b1NlcmlhbGl6ZUZyb250ZW5kTW9kZWxzSW5QYXlsb2FkKGVudHJ5LCByZXNvdXJjZSwgYWN0aW9uLCBzZWVuKSlcbiAgICAgIH1cblxuICAgICAgcmV0dXJuIHJlc3VsdFxuICAgIH1cblxuICAgIGlmICh0eXBlb2YgdmFsdWUgPT09IFwib2JqZWN0XCIgJiYgT2JqZWN0LmdldFByb3RvdHlwZU9mKHZhbHVlKSA9PT0gT2JqZWN0LnByb3RvdHlwZSkge1xuICAgICAgY29uc3QgY29udGFpbmVyID0gLyoqXG4gICAgICAgICAgICAgICAgICAgICAgICAgKiBUeXBlcyB0aGUgZm9sbG93aW5nIHZhbHVlLlxuICAgICAgICAgICAgICAgICAgICAgICAgICBAdHlwZSB7UmVjb3JkPHN0cmluZywgPz59ICovICh2YWx1ZSlcblxuICAgICAgaWYgKHNlZW4uaGFzKGNvbnRhaW5lcikpIHtcbiAgICAgICAgLy8gQ3ljbGljIGJhY2stcmVmZXJlbmNlIGFsb25nIHRoZSBjdXJyZW50IHJlY3Vyc2lvbiBwYXRoOyB0aGVcbiAgICAgICAgLy8gYW5jZXN0b3IgZnJhbWUgaXMgc3RpbGwgd2Fsa2luZyB0aGlzIGNvbnRhaW5lciBhbmQgd2lsbCBwcm9kdWNlXG4gICAgICAgIC8vIGl0cyBzZXJpYWxpemVkIGZvcm0uIFJldHVybmluZyB0aGUgb3JpZ2luYWwgY29udGFpbmVyIGhlcmVcbiAgICAgICAgLy8gYnJlYWtzIHRoZSBjeWNsZSB3aXRob3V0IGJ5cGFzc2luZyB0aGUgd2Fsa2VyIGZvciBzaWJsaW5ncyB0aGF0XG4gICAgICAgIC8vIHNoYXJlIGEgbm9uLWN5Y2xpYyByZWZlcmVuY2UgKHRob3NlIHJlLWVudGVyIHRoZSBicmFuY2ggYmVsb3dcbiAgICAgICAgLy8gYmVjYXVzZSB0aGUgY29udGFpbmVyIGlzIHJlbW92ZWQgZnJvbSBgc2VlbmAgb24gc3RhY2sgZXhpdCkuXG4gICAgICAgIHJldHVybiBjb250YWluZXJcbiAgICAgIH1cblxuICAgICAgc2Vlbi5hZGQoY29udGFpbmVyKVxuXG4gICAgICB0cnkge1xuICAgICAgICAvKipcbiAgICAgICAgICogUmVzdWx0LlxuICAgICAgICAgIEB0eXBlIHtSZWNvcmQ8c3RyaW5nLCA/Pn0gKi9cbiAgICAgICAgY29uc3QgcmVzdWx0ID0ge31cblxuICAgICAgICBmb3IgKGNvbnN0IFtrZXksIG5lc3RlZF0gb2YgT2JqZWN0LmVudHJpZXMoY29udGFpbmVyKSkge1xuICAgICAgICAgIC8vIGBhc3NpZ25TYWZlUHJvcGVydHlgIHN0b3JlcyBrZXlzIGxpa2UgYF9fcHJvdG9fX2AgYXMgb3duXG4gICAgICAgICAgLy8gZGF0YSBwcm9wZXJ0aWVzIGluc3RlYWQgb2YgaW52b2tpbmcgdGhlIHByb3RvdHlwZSBzZXR0ZXIsXG4gICAgICAgICAgLy8gc28gYSBjdXN0b20tY29tbWFuZCByZXNwb25zZSB0aGF0IGVjaG9lcyBwYXJzZWQgY2xpZW50XG4gICAgICAgICAgLy8gaW5wdXQgY2Fubm90IHBvbGx1dGUgYE9iamVjdC5wcm90b3R5cGVgIGhlcmUuIFRoZSB0cmFuc3BvcnRcbiAgICAgICAgICAvLyBzZXJpYWxpemVyIGFwcGxpZXMgdGhlIHNhbWUgcHJvdGVjdGlvbiBvbiBpdHMgb3duIHBhc3M7IHdlXG4gICAgICAgICAgLy8ganVzdCBwcmVzZXJ2ZSBpdCBhY3Jvc3MgdGhlIGF1dG8tc2VyaWFsaXplIHdhbGsuXG4gICAgICAgICAgYXNzaWduU2FmZVByb3BlcnR5KHJlc3VsdCwga2V5LCBhd2FpdCB0aGlzLmF1dG9TZXJpYWxpemVGcm9udGVuZE1vZGVsc0luUGF5bG9hZChuZXN0ZWQsIHJlc291cmNlLCBhY3Rpb24sIHNlZW4pKVxuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIHJlc3VsdFxuICAgICAgfSBmaW5hbGx5IHtcbiAgICAgICAgc2Vlbi5kZWxldGUoY29udGFpbmVyKVxuICAgICAgfVxuICAgIH1cblxuICAgIHJldHVybiB2YWx1ZVxuICB9XG5cbn1cbiJdfQ==