taon 18.0.33 → 19.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (335) hide show
  1. package/assets/shared/shared_folder_info.txt +1 -1
  2. package/browser/fesm2022/taon.mjs +67 -84
  3. package/browser/fesm2022/taon.mjs.map +1 -1
  4. package/browser/lib/base-classes/base-context.d.ts +6 -6
  5. package/browser/lib/base-classes/base.d.ts +6 -6
  6. package/browser/lib/index.d.ts +6 -32
  7. package/browser/lib/ui/taon-progress-bar/taon-progress-bar.component.d.ts +1 -3
  8. package/browser/lib/ui/taon-progress-bar/taon-progress-bar.module.d.ts +1 -2
  9. package/client/fesm2022/taon.mjs +67 -84
  10. package/client/fesm2022/taon.mjs.map +1 -1
  11. package/client/lib/base-classes/base-context.d.ts +6 -6
  12. package/client/lib/base-classes/base.d.ts +6 -6
  13. package/client/lib/index.d.ts +6 -32
  14. package/client/lib/ui/taon-progress-bar/taon-progress-bar.component.d.ts +1 -3
  15. package/client/lib/ui/taon-progress-bar/taon-progress-bar.module.d.ts +1 -2
  16. package/lib/base-classes/base-context.d.ts +6 -6
  17. package/lib/base-classes/base-subscriber.d.ts +4 -0
  18. package/lib/base-classes/base-subscriber.js +25 -0
  19. package/lib/base-classes/base-subscriber.js.map +1 -0
  20. package/lib/base-classes/base.d.ts +6 -6
  21. package/lib/formly/formly-group-wrapper-component.js +1 -0
  22. package/lib/formly/formly-group-wrapper-component.js.map +1 -1
  23. package/lib/formly/formly-repeat-component.js +1 -0
  24. package/lib/formly/formly-repeat-component.js.map +1 -1
  25. package/lib/helpers/class-helpers.js +2 -2
  26. package/lib/helpers/class-helpers.js.map +1 -1
  27. package/lib/index.d.ts +6 -32
  28. package/lib/realtime/realtime-strategy/realtime-abstract-mock.d.ts +10 -0
  29. package/lib/realtime/realtime-strategy/realtime-abstract-mock.js +214 -0
  30. package/lib/realtime/realtime-strategy/realtime-abstract-mock.js.map +1 -0
  31. package/lib/realtime/realtime-strategy/realtime-strategy-ipc-models/index.d.ts +0 -0
  32. package/lib/realtime/realtime-strategy/realtime-strategy-ipc-models/index.js +5 -0
  33. package/lib/realtime/realtime-strategy/realtime-strategy-ipc-models/index.js.map +1 -0
  34. package/lib/realtime/realtime-strategy/realtime-strategy-ipc-models/realtime-strategy-ipc-main-namespace.d.ts +22 -0
  35. package/lib/realtime/realtime-strategy/realtime-strategy-ipc-models/realtime-strategy-ipc-main-namespace.js +139 -0
  36. package/lib/realtime/realtime-strategy/realtime-strategy-ipc-models/realtime-strategy-ipc-main-namespace.js.map +1 -0
  37. package/lib/realtime/realtime-strategy/realtime-strategy-ipc-models/realtime-strategy-ipc-main-wrapper.d.ts +16 -0
  38. package/lib/realtime/realtime-strategy/realtime-strategy-ipc-models/realtime-strategy-ipc-main-wrapper.js +68 -0
  39. package/lib/realtime/realtime-strategy/realtime-strategy-ipc-models/realtime-strategy-ipc-main-wrapper.js.map +1 -0
  40. package/lib/realtime/realtime-strategy/realtime-strategy-ipc-models/realtime-strategy-ipc-renderer-namespace.d.ts +10 -0
  41. package/lib/realtime/realtime-strategy/realtime-strategy-ipc-models/realtime-strategy-ipc-renderer-namespace.js +56 -0
  42. package/lib/realtime/realtime-strategy/realtime-strategy-ipc-models/realtime-strategy-ipc-renderer-namespace.js.map +1 -0
  43. package/lib/realtime/realtime-strategy/realtime-strategy-ipc-models/realtime-strategy-ipc-renderer-wrapper.d.ts +10 -0
  44. package/lib/realtime/realtime-strategy/realtime-strategy-ipc-models/realtime-strategy-ipc-renderer-wrapper.js +50 -0
  45. package/lib/realtime/realtime-strategy/realtime-strategy-ipc-models/realtime-strategy-ipc-renderer-wrapper.js.map +1 -0
  46. package/lib/realtime/realtime-strategy/realtime-strategy-ipc-models/realtime-strategy-ipc.models.d.ts +13 -0
  47. package/lib/realtime/realtime-strategy/realtime-strategy-ipc-models/realtime-strategy-ipc.models.js +3 -0
  48. package/lib/realtime/realtime-strategy/realtime-strategy-ipc-models/realtime-strategy-ipc.models.js.map +1 -0
  49. package/lib/realtime/realtime-strategy/realtime-strategy-mock-models/index.d.ts +2 -0
  50. package/lib/realtime/realtime-strategy/realtime-strategy-mock-models/index.js +6 -0
  51. package/lib/realtime/realtime-strategy/realtime-strategy-mock-models/index.js.map +1 -0
  52. package/lib/realtime/realtime-strategy/realtime-strategy-mock-models/realtime-strategy-mock-client.d.ts +16 -0
  53. package/lib/realtime/realtime-strategy/realtime-strategy-mock-models/realtime-strategy-mock-client.js +54 -0
  54. package/lib/realtime/realtime-strategy/realtime-strategy-mock-models/realtime-strategy-mock-client.js.map +1 -0
  55. package/lib/realtime/realtime-strategy/realtime-strategy-mock-models/realtime-strategy-mock-namespaces.d.ts +17 -0
  56. package/lib/realtime/realtime-strategy/realtime-strategy-mock-models/realtime-strategy-mock-namespaces.js +52 -0
  57. package/lib/realtime/realtime-strategy/realtime-strategy-mock-models/realtime-strategy-mock-namespaces.js.map +1 -0
  58. package/lib/realtime/realtime-strategy/realtime-strategy-mock-models/realtime-strategy-mock-server.d.ts +11 -0
  59. package/lib/realtime/realtime-strategy/realtime-strategy-mock-models/realtime-strategy-mock-server.js +39 -0
  60. package/lib/realtime/realtime-strategy/realtime-strategy-mock-models/realtime-strategy-mock-server.js.map +1 -0
  61. package/lib/realtime/realtime-strategy/realtime-strategy-mock-models/realtime-strategy-mock-socket.d.ts +13 -0
  62. package/lib/realtime/realtime-strategy/realtime-strategy-mock-models/realtime-strategy-mock-socket.js +46 -0
  63. package/lib/realtime/realtime-strategy/realtime-strategy-mock-models/realtime-strategy-mock-socket.js.map +1 -0
  64. package/lib/realtime/realtime-strategy/realtime-strategy-mock-models/realtime-strategy-mock.models.d.ts +11 -0
  65. package/lib/realtime/realtime-strategy/realtime-strategy-mock-models/realtime-strategy-mock.models.js +3 -0
  66. package/lib/realtime/realtime-strategy/realtime-strategy-mock-models/realtime-strategy-mock.models.js.map +1 -0
  67. package/lib/ui/directives/firedev-inject-html.directive.d.ts +6 -0
  68. package/lib/ui/directives/firedev-long-press.directive.d.ts +22 -0
  69. package/lib/ui/directives/index.js +2 -2
  70. package/lib/ui/index.js +2 -2
  71. package/lib/ui/taon-admin-mode-configuration/components/taon-admin-edit-mode/index.d.ts +2 -0
  72. package/lib/ui/taon-admin-mode-configuration/components/taon-admin-edit-mode/index.js +5 -0
  73. package/lib/ui/taon-admin-mode-configuration/components/taon-admin-edit-mode/index.js.map +1 -0
  74. package/lib/ui/taon-admin-mode-configuration/components/taon-admin-edit-mode/taon-admin-edit-mode.component.d.ts +29 -0
  75. package/lib/ui/taon-admin-mode-configuration/components/taon-admin-edit-mode/taon-admin-edit-mode.module.d.ts +2 -0
  76. package/lib/ui/taon-admin-mode-configuration/components/taon-db-admin/index.d.ts +1 -0
  77. package/lib/ui/taon-admin-mode-configuration/components/taon-db-admin/index.js +5 -0
  78. package/lib/ui/taon-admin-mode-configuration/components/taon-db-admin/index.js.map +1 -0
  79. package/lib/ui/taon-admin-mode-configuration/components/taon-db-admin/taon-db-admin.component.d.ts +8 -0
  80. package/lib/ui/taon-admin-mode-configuration/components/taon-file-general-opt/index.d.ts +2 -0
  81. package/lib/ui/taon-admin-mode-configuration/components/taon-file-general-opt/index.js +5 -0
  82. package/lib/ui/taon-admin-mode-configuration/components/taon-file-general-opt/index.js.map +1 -0
  83. package/lib/ui/taon-admin-mode-configuration/components/taon-file-general-opt/taon-file-general-opt.component.d.ts +13 -0
  84. package/lib/ui/taon-admin-mode-configuration/components/taon-file-general-opt/taon-file-general-opt.module.d.ts +2 -0
  85. package/lib/ui/taon-admin-mode-configuration/index.js +2 -2
  86. package/lib/ui/taon-admin-mode-configuration/models/taon-admin-mode-tabs.d.ts +5 -0
  87. package/lib/ui/taon-admin-mode-configuration/models/taon-admin-mode-tabs.js +3 -0
  88. package/lib/ui/taon-admin-mode-configuration/models/taon-admin-mode-tabs.js.map +1 -0
  89. package/lib/ui/taon-admin-mode-configuration/taon-admin-control.service.d.ts +14 -0
  90. package/lib/ui/taon-admin-mode-configuration/taon-admin-mode-configuration.module.d.ts +2 -0
  91. package/lib/ui/taon-github-fork-me-corner/index.js +2 -2
  92. package/lib/ui/taon-github-fork-me-ribbon/index.js +2 -2
  93. package/lib/ui/taon-notifications/taon-notifications.models.js +2 -2
  94. package/lib/ui/taon-progress-bar/index.js +2 -2
  95. package/lib/ui/taon-progress-bar/taon-progress-bar.component.d.ts +1 -3
  96. package/lib/ui/taon-session-passcode/index.js +2 -2
  97. package/lib/ui/taon-table/index.js +2 -2
  98. package/lib/ui/toan-full-material.module.d.ts +2 -0
  99. package/old-app .js +1 -0
  100. package/old-app .js.map +1 -1
  101. package/package.json +3 -3
  102. package/taon.jsonc +0 -5
  103. package/tmp-environment.json +24 -3
  104. package/websql/fesm2022/taon.mjs +67 -84
  105. package/websql/fesm2022/taon.mjs.map +1 -1
  106. package/websql/lib/base-classes/base-context.d.ts +6 -6
  107. package/websql/lib/base-classes/base.d.ts +6 -6
  108. package/websql/lib/index.d.ts +6 -32
  109. package/websql/lib/ui/taon-progress-bar/taon-progress-bar.component.d.ts +1 -3
  110. package/websql/lib/ui/taon-progress-bar/taon-progress-bar.module.d.ts +1 -2
  111. package/browser/esm2022/lib/base-classes/base-abstract-entity.mjs +0 -18
  112. package/browser/esm2022/lib/base-classes/base-class.mjs +0 -17
  113. package/browser/esm2022/lib/base-classes/base-context.mjs +0 -14
  114. package/browser/esm2022/lib/base-classes/base-controller.mjs +0 -19
  115. package/browser/esm2022/lib/base-classes/base-crud-controller.mjs +0 -279
  116. package/browser/esm2022/lib/base-classes/base-entity.mjs +0 -18
  117. package/browser/esm2022/lib/base-classes/base-injector.mjs +0 -167
  118. package/browser/esm2022/lib/base-classes/base-migration.mjs +0 -23
  119. package/browser/esm2022/lib/base-classes/base-provider.mjs +0 -6
  120. package/browser/esm2022/lib/base-classes/base-repository.mjs +0 -514
  121. package/browser/esm2022/lib/base-classes/base-subscriber-for-entity.mjs +0 -156
  122. package/browser/esm2022/lib/base-classes/base.mjs +0 -26
  123. package/browser/esm2022/lib/constants.mjs +0 -4
  124. package/browser/esm2022/lib/context-db-migrations.mjs +0 -425
  125. package/browser/esm2022/lib/create-context.mjs +0 -127
  126. package/browser/esm2022/lib/decorators/classes/controller-decorator.mjs +0 -18
  127. package/browser/esm2022/lib/decorators/classes/entity-decorator.mjs +0 -30
  128. package/browser/esm2022/lib/decorators/classes/migration-decorator.mjs +0 -18
  129. package/browser/esm2022/lib/decorators/classes/provider-decorator.mjs +0 -18
  130. package/browser/esm2022/lib/decorators/classes/repository-decorator.mjs +0 -18
  131. package/browser/esm2022/lib/decorators/classes/subscriber-decorator.mjs +0 -18
  132. package/browser/esm2022/lib/decorators/http/http-decorators.mjs +0 -24
  133. package/browser/esm2022/lib/decorators/http/http-methods-decorators.mjs +0 -78
  134. package/browser/esm2022/lib/decorators/http/http-params-decorators.mjs +0 -47
  135. package/browser/esm2022/lib/dependency-injection/di-container.mjs +0 -32
  136. package/browser/esm2022/lib/endpoint-context.mjs +0 -1705
  137. package/browser/esm2022/lib/entity-process.mjs +0 -198
  138. package/browser/esm2022/lib/env.mjs +0 -6
  139. package/browser/esm2022/lib/get-response-value.mjs +0 -27
  140. package/browser/esm2022/lib/helpers/class-helpers.mjs +0 -183
  141. package/browser/esm2022/lib/helpers/taon-helpers.mjs +0 -120
  142. package/browser/esm2022/lib/index.mjs +0 -70
  143. package/browser/esm2022/lib/inject.mjs +0 -36
  144. package/browser/esm2022/lib/models.mjs +0 -106
  145. package/browser/esm2022/lib/orm.mjs +0 -6
  146. package/browser/esm2022/lib/realtime/realtime-client.mjs +0 -141
  147. package/browser/esm2022/lib/realtime/realtime-core.mjs +0 -62
  148. package/browser/esm2022/lib/realtime/realtime-server.mjs +0 -292
  149. package/browser/esm2022/lib/realtime/realtime-strategy/index.mjs +0 -7
  150. package/browser/esm2022/lib/realtime/realtime-strategy/realtime-strategy-ipc.mjs +0 -218
  151. package/browser/esm2022/lib/realtime/realtime-strategy/realtime-strategy-mock.mjs +0 -224
  152. package/browser/esm2022/lib/realtime/realtime-strategy/realtime-strategy-socket-io.mjs +0 -29
  153. package/browser/esm2022/lib/realtime/realtime-strategy/realtime-strategy.mjs +0 -14
  154. package/browser/esm2022/lib/realtime/realtime-subs-manager.mjs +0 -81
  155. package/browser/esm2022/lib/realtime/realtime.models.mjs +0 -4
  156. package/browser/esm2022/lib/storage.mjs +0 -5
  157. package/browser/esm2022/lib/symbols.mjs +0 -97
  158. package/browser/esm2022/lib/ui/directives/index.mjs +0 -6
  159. package/browser/esm2022/lib/ui/directives/safe.pipe.mjs +0 -43
  160. package/browser/esm2022/lib/ui/directives/taon-inject-html.directive.mjs +0 -24
  161. package/browser/esm2022/lib/ui/directives/taon-long-press.directive.mjs +0 -120
  162. package/browser/esm2022/lib/ui/index.mjs +0 -12
  163. package/browser/esm2022/lib/ui/taon-admin-mode-configuration/index.mjs +0 -4
  164. package/browser/esm2022/lib/ui/taon-admin-mode-configuration/taon-admin-mode-configuration.component.mjs +0 -194
  165. package/browser/esm2022/lib/ui/taon-admin-mode-configuration/taon-admin.service.mjs +0 -55
  166. package/browser/esm2022/lib/ui/taon-full-material.module.mjs +0 -179
  167. package/browser/esm2022/lib/ui/taon-github-fork-me-corner/index.mjs +0 -5
  168. package/browser/esm2022/lib/ui/taon-github-fork-me-corner/taon-github-fork-me-corner.component.mjs +0 -18
  169. package/browser/esm2022/lib/ui/taon-github-fork-me-corner/taon-github-fork-me-corner.module.mjs +0 -21
  170. package/browser/esm2022/lib/ui/taon-notifications/index.mjs +0 -7
  171. package/browser/esm2022/lib/ui/taon-notifications/taon-notifications.component.mjs +0 -25
  172. package/browser/esm2022/lib/ui/taon-notifications/taon-notifications.models.mjs +0 -5
  173. package/browser/esm2022/lib/ui/taon-notifications/taon-notifications.module.mjs +0 -21
  174. package/browser/esm2022/lib/ui/taon-notifications/taon-notifications.service.mjs +0 -48
  175. package/browser/esm2022/lib/ui/taon-progress-bar/index.mjs +0 -5
  176. package/browser/esm2022/lib/ui/taon-progress-bar/taon-progress-bar.component.mjs +0 -98
  177. package/browser/esm2022/lib/ui/taon-progress-bar/taon-progress-bar.module.mjs +0 -22
  178. package/browser/esm2022/lib/ui/taon-session-passcode/index.mjs +0 -4
  179. package/browser/esm2022/lib/ui/taon-session-passcode/taon-session-passcode.component.mjs +0 -120
  180. package/browser/esm2022/lib/ui/taon-table/index.mjs +0 -5
  181. package/browser/esm2022/lib/ui/taon-table/taon-table.component.mjs +0 -160
  182. package/browser/esm2022/lib/ui/taon-table/taon-table.module.mjs +0 -57
  183. package/browser/esm2022/lib/validators.mjs +0 -76
  184. package/browser/esm2022/public-api.mjs +0 -2
  185. package/browser/esm2022/taon.mjs +0 -5
  186. package/client/esm2022/lib/base-classes/base-abstract-entity.mjs +0 -18
  187. package/client/esm2022/lib/base-classes/base-class.mjs +0 -17
  188. package/client/esm2022/lib/base-classes/base-context.mjs +0 -14
  189. package/client/esm2022/lib/base-classes/base-controller.mjs +0 -19
  190. package/client/esm2022/lib/base-classes/base-crud-controller.mjs +0 -279
  191. package/client/esm2022/lib/base-classes/base-entity.mjs +0 -18
  192. package/client/esm2022/lib/base-classes/base-injector.mjs +0 -167
  193. package/client/esm2022/lib/base-classes/base-migration.mjs +0 -23
  194. package/client/esm2022/lib/base-classes/base-provider.mjs +0 -6
  195. package/client/esm2022/lib/base-classes/base-repository.mjs +0 -514
  196. package/client/esm2022/lib/base-classes/base-subscriber-for-entity.mjs +0 -156
  197. package/client/esm2022/lib/base-classes/base.mjs +0 -26
  198. package/client/esm2022/lib/constants.mjs +0 -4
  199. package/client/esm2022/lib/context-db-migrations.mjs +0 -425
  200. package/client/esm2022/lib/create-context.mjs +0 -127
  201. package/client/esm2022/lib/decorators/classes/controller-decorator.mjs +0 -18
  202. package/client/esm2022/lib/decorators/classes/entity-decorator.mjs +0 -30
  203. package/client/esm2022/lib/decorators/classes/migration-decorator.mjs +0 -18
  204. package/client/esm2022/lib/decorators/classes/provider-decorator.mjs +0 -18
  205. package/client/esm2022/lib/decorators/classes/repository-decorator.mjs +0 -18
  206. package/client/esm2022/lib/decorators/classes/subscriber-decorator.mjs +0 -18
  207. package/client/esm2022/lib/decorators/http/http-decorators.mjs +0 -24
  208. package/client/esm2022/lib/decorators/http/http-methods-decorators.mjs +0 -78
  209. package/client/esm2022/lib/decorators/http/http-params-decorators.mjs +0 -47
  210. package/client/esm2022/lib/dependency-injection/di-container.mjs +0 -32
  211. package/client/esm2022/lib/endpoint-context.mjs +0 -1705
  212. package/client/esm2022/lib/entity-process.mjs +0 -198
  213. package/client/esm2022/lib/env.mjs +0 -6
  214. package/client/esm2022/lib/get-response-value.mjs +0 -27
  215. package/client/esm2022/lib/helpers/class-helpers.mjs +0 -183
  216. package/client/esm2022/lib/helpers/taon-helpers.mjs +0 -120
  217. package/client/esm2022/lib/index.mjs +0 -70
  218. package/client/esm2022/lib/inject.mjs +0 -36
  219. package/client/esm2022/lib/models.mjs +0 -106
  220. package/client/esm2022/lib/orm.mjs +0 -6
  221. package/client/esm2022/lib/realtime/realtime-client.mjs +0 -141
  222. package/client/esm2022/lib/realtime/realtime-core.mjs +0 -62
  223. package/client/esm2022/lib/realtime/realtime-server.mjs +0 -292
  224. package/client/esm2022/lib/realtime/realtime-strategy/index.mjs +0 -7
  225. package/client/esm2022/lib/realtime/realtime-strategy/realtime-strategy-ipc.mjs +0 -218
  226. package/client/esm2022/lib/realtime/realtime-strategy/realtime-strategy-mock.mjs +0 -224
  227. package/client/esm2022/lib/realtime/realtime-strategy/realtime-strategy-socket-io.mjs +0 -29
  228. package/client/esm2022/lib/realtime/realtime-strategy/realtime-strategy.mjs +0 -14
  229. package/client/esm2022/lib/realtime/realtime-subs-manager.mjs +0 -81
  230. package/client/esm2022/lib/realtime/realtime.models.mjs +0 -4
  231. package/client/esm2022/lib/storage.mjs +0 -5
  232. package/client/esm2022/lib/symbols.mjs +0 -97
  233. package/client/esm2022/lib/ui/directives/index.mjs +0 -6
  234. package/client/esm2022/lib/ui/directives/safe.pipe.mjs +0 -43
  235. package/client/esm2022/lib/ui/directives/taon-inject-html.directive.mjs +0 -24
  236. package/client/esm2022/lib/ui/directives/taon-long-press.directive.mjs +0 -120
  237. package/client/esm2022/lib/ui/index.mjs +0 -12
  238. package/client/esm2022/lib/ui/taon-admin-mode-configuration/index.mjs +0 -4
  239. package/client/esm2022/lib/ui/taon-admin-mode-configuration/taon-admin-mode-configuration.component.mjs +0 -194
  240. package/client/esm2022/lib/ui/taon-admin-mode-configuration/taon-admin.service.mjs +0 -55
  241. package/client/esm2022/lib/ui/taon-full-material.module.mjs +0 -179
  242. package/client/esm2022/lib/ui/taon-github-fork-me-corner/index.mjs +0 -5
  243. package/client/esm2022/lib/ui/taon-github-fork-me-corner/taon-github-fork-me-corner.component.mjs +0 -18
  244. package/client/esm2022/lib/ui/taon-github-fork-me-corner/taon-github-fork-me-corner.module.mjs +0 -21
  245. package/client/esm2022/lib/ui/taon-notifications/index.mjs +0 -7
  246. package/client/esm2022/lib/ui/taon-notifications/taon-notifications.component.mjs +0 -25
  247. package/client/esm2022/lib/ui/taon-notifications/taon-notifications.models.mjs +0 -5
  248. package/client/esm2022/lib/ui/taon-notifications/taon-notifications.module.mjs +0 -21
  249. package/client/esm2022/lib/ui/taon-notifications/taon-notifications.service.mjs +0 -48
  250. package/client/esm2022/lib/ui/taon-progress-bar/index.mjs +0 -5
  251. package/client/esm2022/lib/ui/taon-progress-bar/taon-progress-bar.component.mjs +0 -98
  252. package/client/esm2022/lib/ui/taon-progress-bar/taon-progress-bar.module.mjs +0 -22
  253. package/client/esm2022/lib/ui/taon-session-passcode/index.mjs +0 -4
  254. package/client/esm2022/lib/ui/taon-session-passcode/taon-session-passcode.component.mjs +0 -120
  255. package/client/esm2022/lib/ui/taon-table/index.mjs +0 -5
  256. package/client/esm2022/lib/ui/taon-table/taon-table.component.mjs +0 -160
  257. package/client/esm2022/lib/ui/taon-table/taon-table.module.mjs +0 -57
  258. package/client/esm2022/lib/validators.mjs +0 -76
  259. package/client/esm2022/public-api.mjs +0 -2
  260. package/client/esm2022/taon.mjs +0 -5
  261. package/websql/esm2022/lib/base-classes/base-abstract-entity.mjs +0 -25
  262. package/websql/esm2022/lib/base-classes/base-class.mjs +0 -17
  263. package/websql/esm2022/lib/base-classes/base-context.mjs +0 -14
  264. package/websql/esm2022/lib/base-classes/base-controller.mjs +0 -19
  265. package/websql/esm2022/lib/base-classes/base-crud-controller.mjs +0 -238
  266. package/websql/esm2022/lib/base-classes/base-entity.mjs +0 -16
  267. package/websql/esm2022/lib/base-classes/base-injector.mjs +0 -167
  268. package/websql/esm2022/lib/base-classes/base-migration.mjs +0 -23
  269. package/websql/esm2022/lib/base-classes/base-provider.mjs +0 -6
  270. package/websql/esm2022/lib/base-classes/base-repository.mjs +0 -431
  271. package/websql/esm2022/lib/base-classes/base-subscriber-for-entity.mjs +0 -156
  272. package/websql/esm2022/lib/base-classes/base.mjs +0 -26
  273. package/websql/esm2022/lib/constants.mjs +0 -4
  274. package/websql/esm2022/lib/context-db-migrations.mjs +0 -274
  275. package/websql/esm2022/lib/create-context.mjs +0 -126
  276. package/websql/esm2022/lib/decorators/classes/controller-decorator.mjs +0 -18
  277. package/websql/esm2022/lib/decorators/classes/entity-decorator.mjs +0 -28
  278. package/websql/esm2022/lib/decorators/classes/migration-decorator.mjs +0 -18
  279. package/websql/esm2022/lib/decorators/classes/provider-decorator.mjs +0 -18
  280. package/websql/esm2022/lib/decorators/classes/repository-decorator.mjs +0 -18
  281. package/websql/esm2022/lib/decorators/classes/subscriber-decorator.mjs +0 -18
  282. package/websql/esm2022/lib/decorators/http/http-decorators.mjs +0 -24
  283. package/websql/esm2022/lib/decorators/http/http-methods-decorators.mjs +0 -78
  284. package/websql/esm2022/lib/decorators/http/http-params-decorators.mjs +0 -47
  285. package/websql/esm2022/lib/dependency-injection/di-container.mjs +0 -32
  286. package/websql/esm2022/lib/endpoint-context.mjs +0 -1586
  287. package/websql/esm2022/lib/entity-process.mjs +0 -198
  288. package/websql/esm2022/lib/env.mjs +0 -6
  289. package/websql/esm2022/lib/get-response-value.mjs +0 -25
  290. package/websql/esm2022/lib/helpers/class-helpers.mjs +0 -183
  291. package/websql/esm2022/lib/helpers/taon-helpers.mjs +0 -120
  292. package/websql/esm2022/lib/index.mjs +0 -72
  293. package/websql/esm2022/lib/inject.mjs +0 -36
  294. package/websql/esm2022/lib/models.mjs +0 -97
  295. package/websql/esm2022/lib/orm.mjs +0 -65
  296. package/websql/esm2022/lib/realtime/realtime-client.mjs +0 -141
  297. package/websql/esm2022/lib/realtime/realtime-core.mjs +0 -62
  298. package/websql/esm2022/lib/realtime/realtime-server.mjs +0 -176
  299. package/websql/esm2022/lib/realtime/realtime-strategy/index.mjs +0 -7
  300. package/websql/esm2022/lib/realtime/realtime-strategy/realtime-strategy-ipc.mjs +0 -218
  301. package/websql/esm2022/lib/realtime/realtime-strategy/realtime-strategy-mock.mjs +0 -224
  302. package/websql/esm2022/lib/realtime/realtime-strategy/realtime-strategy-socket-io.mjs +0 -29
  303. package/websql/esm2022/lib/realtime/realtime-strategy/realtime-strategy.mjs +0 -14
  304. package/websql/esm2022/lib/realtime/realtime-subs-manager.mjs +0 -81
  305. package/websql/esm2022/lib/realtime/realtime.models.mjs +0 -4
  306. package/websql/esm2022/lib/storage.mjs +0 -5
  307. package/websql/esm2022/lib/symbols.mjs +0 -97
  308. package/websql/esm2022/lib/ui/directives/index.mjs +0 -6
  309. package/websql/esm2022/lib/ui/directives/safe.pipe.mjs +0 -43
  310. package/websql/esm2022/lib/ui/directives/taon-inject-html.directive.mjs +0 -24
  311. package/websql/esm2022/lib/ui/directives/taon-long-press.directive.mjs +0 -120
  312. package/websql/esm2022/lib/ui/index.mjs +0 -12
  313. package/websql/esm2022/lib/ui/taon-admin-mode-configuration/index.mjs +0 -4
  314. package/websql/esm2022/lib/ui/taon-admin-mode-configuration/taon-admin-mode-configuration.component.mjs +0 -194
  315. package/websql/esm2022/lib/ui/taon-admin-mode-configuration/taon-admin.service.mjs +0 -55
  316. package/websql/esm2022/lib/ui/taon-full-material.module.mjs +0 -179
  317. package/websql/esm2022/lib/ui/taon-github-fork-me-corner/index.mjs +0 -5
  318. package/websql/esm2022/lib/ui/taon-github-fork-me-corner/taon-github-fork-me-corner.component.mjs +0 -18
  319. package/websql/esm2022/lib/ui/taon-github-fork-me-corner/taon-github-fork-me-corner.module.mjs +0 -21
  320. package/websql/esm2022/lib/ui/taon-notifications/index.mjs +0 -7
  321. package/websql/esm2022/lib/ui/taon-notifications/taon-notifications.component.mjs +0 -25
  322. package/websql/esm2022/lib/ui/taon-notifications/taon-notifications.models.mjs +0 -5
  323. package/websql/esm2022/lib/ui/taon-notifications/taon-notifications.module.mjs +0 -21
  324. package/websql/esm2022/lib/ui/taon-notifications/taon-notifications.service.mjs +0 -48
  325. package/websql/esm2022/lib/ui/taon-progress-bar/index.mjs +0 -5
  326. package/websql/esm2022/lib/ui/taon-progress-bar/taon-progress-bar.component.mjs +0 -50
  327. package/websql/esm2022/lib/ui/taon-progress-bar/taon-progress-bar.module.mjs +0 -22
  328. package/websql/esm2022/lib/ui/taon-session-passcode/index.mjs +0 -4
  329. package/websql/esm2022/lib/ui/taon-session-passcode/taon-session-passcode.component.mjs +0 -120
  330. package/websql/esm2022/lib/ui/taon-table/index.mjs +0 -5
  331. package/websql/esm2022/lib/ui/taon-table/taon-table.component.mjs +0 -160
  332. package/websql/esm2022/lib/ui/taon-table/taon-table.module.mjs +0 -57
  333. package/websql/esm2022/lib/validators.mjs +0 -76
  334. package/websql/esm2022/public-api.mjs +0 -2
  335. package/websql/esm2022/taon.mjs +0 -5
@@ -1,1586 +0,0 @@
1
- /* eslint-disable @typescript-eslint/typedef */
2
- import { EventSubscriber } from 'taon-typeorm/websql';
3
- import { Entity as TypeormEntity } from 'taon-typeorm/websql';
4
- /* */
5
- /* */
6
- /* */
7
- /* */
8
- /* */
9
- /* */
10
- /* */
11
- /* */
12
- /* */
13
- /* */
14
- /* */
15
- import { TaonAdminService } from './ui/taon-admin-mode-configuration/taon-admin.service';
16
- import { UtilsOs, Utils } from 'tnp-core/websql';
17
- import { crossPlatformPath } from 'tnp-core/websql';
18
- import { Models } from './models';
19
- import { ClassHelpers } from './helpers/class-helpers';
20
- import { Symbols } from './symbols';
21
- import { _, Helpers } from 'tnp-core/websql';
22
- import { DITaonContainer } from './dependency-injection/di-container';
23
- import { TaonHelpers } from './helpers/taon-helpers';
24
- import { Mapping, Models as ModelsNg2Rest, Resource, RestHeaders, } from 'ng2-rest/websql'; /* */
25
- /* */
26
- /* */
27
- /* */
28
- /* */
29
- import { JSON10 } from 'json10/websql';
30
- import { from, Subject } from 'rxjs';
31
- import { getResponseValue } from './get-response-value';
32
- import axios from 'axios';
33
- import { DataSource, } from 'taon-typeorm/websql'; /* */
34
- import { ENV } from './env';
35
- import { RealtimeCore } from './realtime/realtime-core';
36
- import { ContextDbMigrations } from './context-db-migrations';
37
- export class EndpointContext {
38
- static initNgZone(ngZone) {
39
- this.ngZone = ngZone;
40
- }
41
- get isRunOrRevertOnlyMigrationAppStart() {
42
- return !!(this.onlyMigrationRun || this.onlyMigrationRevertToTimestamp);
43
- }
44
- get realtimeClient() {
45
- return this.realtime.client;
46
- }
47
- get realtimeServer() {
48
- return this.realtime.server;
49
- }
50
- get logHttp() {
51
- if (_.isObject(this.config?.logs)) {
52
- return !!this.config.logs.http;
53
- }
54
- return this.config?.logs === true;
55
- }
56
- get logRealtime() {
57
- if (_.isObject(this.config?.logs)) {
58
- return !!this.config.logs.realtime;
59
- }
60
- return this.config?.logs === true;
61
- }
62
- get logFramework() {
63
- if (_.isObject(this.config?.logs)) {
64
- return !!this.config.logs.framework;
65
- }
66
- return this.config?.logs === true;
67
- }
68
- get logDb() {
69
- if (_.isObject(this.config?.logs)) {
70
- return !!this.config.logs.db;
71
- }
72
- return this.config?.logs === true;
73
- }
74
- get logMigrations() {
75
- if (_.isObject(this.config?.logs)) {
76
- return !!this.config.logs.migrations;
77
- }
78
- return this.config?.logs === true;
79
- }
80
- constructor(originalConfig, configFn) {
81
- this.originalConfig = originalConfig;
82
- this.configFn = configFn;
83
- this.disabledRealtime = false;
84
- /**
85
- * check whether context is inited
86
- * (with init() function )
87
- */
88
- this.inited = false;
89
- this.dbMigrations = new ContextDbMigrations(this);
90
- this.localInstaceObjSymbol = Symbol('localInstaceObjSymbol');
91
- /**
92
- * all instances of classes from context
93
- * key is class name
94
- */
95
- this.allClassesInstances = {};
96
- this.classInstancesByNameObj = {};
97
- this.objWithClassesInstancesArr = {};
98
- this.activeRoutes = [];
99
- this.skipWritingServerRoutes = false;
100
- this.injectableTypesfromContexts = [
101
- Models.ClassType.CONTROLLER,
102
- Models.ClassType.PROVIDER,
103
- Models.ClassType.REPOSITORY,
104
- Models.ClassType.SUBSCRIBER,
105
- Models.ClassType.MIGRATION,
106
- ];
107
- this.allTypesfromContexts = [
108
- ...this.injectableTypesfromContexts,
109
- Models.ClassType.ENTITY,
110
- ];
111
- this.expressApp = {};
112
- this.onlyMigrationRun = false;
113
- this.onlyMigrationRevertToTimestamp = undefined;
114
- this.entitiesTriggers = {};
115
- this.cloneClassWithNewMetadata = ({ BaseClass, className, config, ctx, classType, }) => {
116
- const cloneClass = () => {
117
- var _a, _b, _c, _d, _e;
118
- if (BaseClass[Symbols.fullClassNameStaticProperty] ===
119
- `${ctx.contextName}.${className}`) {
120
- return BaseClass;
121
- }
122
- return class extends BaseClass {
123
- constructor() {
124
- super(...arguments);
125
- this[_e] = ctx;
126
- }
127
- static { _a = Symbols.orignalClass, _b = Symbols.fullClassNameStaticProperty, _c = Symbols.classNameStaticProperty, _d = Symbols.ctxInClassOrClassObj, _e = Symbols.ctxInClassOrClassObj; }
128
- // @ts-ignore
129
- static { this[_a] = BaseClass; }
130
- // @ts-ignore
131
- static { this[_b] = `${ctx.contextName}.${className}`; }
132
- // @ts-ignore
133
- static { this[_c] = className; }
134
- static { this[_d] = ctx; }
135
- static __getFullPathForClass__(arr = []) {
136
- const name = this[Symbols.fullClassNameStaticProperty];
137
- arr.push(name);
138
- // @ts-ignore
139
- if (this[Symbols.orignalClass] && // @ts-ignore
140
- this[Symbols.orignalClass].__getFullPathForClass__) {
141
- // @ts-ignore
142
- this[Symbols.orignalClass].__getFullPathForClass__(arr);
143
- }
144
- return arr.join('/');
145
- }
146
- static get fullPathForClass() {
147
- return this.__getFullPathForClass__();
148
- }
149
- };
150
- };
151
- const cloneClassFunction = cloneClass();
152
- return cloneClassFunction;
153
- };
154
- this.cloneClassesObjWithNewMetadata = ({ classesInput, config, ctx, classType, }) => {
155
- const classes = {};
156
- for (const key of Object.keys(classesInput || {})) {
157
- const BaseClass = classesInput[key];
158
- if (!BaseClass) {
159
- Helpers.error(`Class ${key} is not defined in context ${ctx.contextName}
160
-
161
- Please check if you have correct import in context file
162
-
163
- `);
164
- }
165
- var className = Reflect.getMetadata(Symbols.metadata.className, BaseClass);
166
- className = className || key;
167
- BaseClass[Symbols.classNameStaticProperty] = className;
168
- const clonedClass = this.cloneClassWithNewMetadata({
169
- BaseClass,
170
- className,
171
- config,
172
- ctx,
173
- classType,
174
- });
175
- classes[className] = clonedClass;
176
- }
177
- return classes;
178
- };
179
- }
180
- async init(options) {
181
- const { initFromRecrusiveContextResovle, overrideHost, overrideRemoteHost, onlyMigrationRun, onlyMigrationRevertToTimestamp, } = options || {}; // TODO use it ?
182
- this.inited = true;
183
- // @ts-ignore
184
- this.onlyMigrationRun = onlyMigrationRun;
185
- // @ts-ignore
186
- this.onlyMigrationRevertToTimestamp = onlyMigrationRevertToTimestamp;
187
- this.config = this.configFn(ENV);
188
- if (_.isObject(this.config.database)) {
189
- this.config.database = Models.DatabaseConfig.from(this.config.database).databaseConfigTypeORM;
190
- }
191
- if (overrideHost && overrideRemoteHost) {
192
- Helpers.throw(`[taon-config] You can't have overrideHost and overrideRemoteHost at the same time`);
193
- }
194
- this.config.host = !_.isUndefined(overrideHost)
195
- ? overrideHost
196
- : this.config.host;
197
- this.config.remoteHost = !_.isUndefined(overrideRemoteHost)
198
- ? overrideRemoteHost
199
- : this.config.remoteHost;
200
- this.config.host = this.host === null ? void 0 : this.host;
201
- this.config.remoteHost =
202
- this.remoteHost === null ? void 0 : this.remoteHost;
203
- if (this.config.host &&
204
- !this.config.host.startsWith('http://') &&
205
- !this.config.host.startsWith('https://')) {
206
- Helpers.throw(`[taon-config] Your 'host' must start with http:// or https://`);
207
- }
208
- if (_.isUndefined(this.config.useIpcWhenElectron)) {
209
- this.config.useIpcWhenElectron = true;
210
- }
211
- if (this.config.remoteHost &&
212
- !this.config.remoteHost.startsWith('http://') &&
213
- !this.config.remoteHost.startsWith('https://')) {
214
- Helpers.throw(`[taon-config] Your 'remoteHost' must start with http:// or https://`);
215
- }
216
- //@ts-expect-error overriding readonly
217
- this.skipWritingServerRoutes = _.isBoolean(this.config.skipWritingServerRoutes)
218
- ? this.config.skipWritingServerRoutes
219
- : false;
220
- if (this.config.host) {
221
- this.mode = 'backend-frontend(tcp+udp)';
222
- this.mode = 'backend-frontend(websql)';
223
- }
224
- if (this.config.remoteHost) {
225
- if (this.config.host) {
226
- Helpers.throw(`[taon] You can't have remoteHost and host at the same time`);
227
- }
228
- this.mode = 'remote-backend(tcp+udp)';
229
- }
230
- if (this.config.useIpcWhenElectron && Helpers.isElectron) {
231
- if (Helpers.isWebSQL) {
232
- this.mode = 'backend-frontend(websql-electron)';
233
- }
234
- else {
235
- this.mode = 'backend-frontend(ipc-electron)';
236
- }
237
- }
238
- if (!this.mode && !this.config.abstract) {
239
- Helpers.error(`[taon] Context "${this.contextName}": You need to provide host or remoteHost or useIpcWhenElectron`, false, true);
240
- /* */
241
- /* */
242
- }
243
- if (this.config.database === true) {
244
- this.databaseConfig = this.getAutoGeneratedConfig();
245
- }
246
- else if (_.isObject(this.config.database)) {
247
- this.databaseConfig = _.merge(this.getAutoGeneratedConfig(), _.cloneDeep(this.config.database));
248
- }
249
- if (this.config.session) {
250
- this.session = _.cloneDeep(this.config.session);
251
- const oneHour = 1000 * 60 * 60 * 1; // 24;
252
- if (!this.session.cookieMaxAge) {
253
- this.session.cookieMaxAge = oneHour;
254
- }
255
- axios.defaults.withCredentials = true;
256
- }
257
- this.config.contexts = this.config.contexts || {};
258
- this.config.entities = this.config.entities || {};
259
- this.config.controllers = this.config.controllers || {};
260
- this.config.repositories = this.config.repositories || {};
261
- this.config.providers = this.config.providers || {};
262
- this.config.subscribers = this.config.subscribers || {};
263
- this.config.migrations = this.config.migrations || {};
264
- this.config.entities = {
265
- ...(await this.getRecrusiveClassesfromContextsObj(Models.ClassType.ENTITY)),
266
- ...this.config.entities,
267
- };
268
- this.config.controllers = {
269
- ...(await this.getRecrusiveClassesfromContextsObj(Models.ClassType.CONTROLLER)),
270
- ...this.config.controllers,
271
- };
272
- this.config.providers = {
273
- ...(await this.getRecrusiveClassesfromContextsObj(Models.ClassType.PROVIDER)),
274
- ...this.config.providers,
275
- };
276
- this.config.subscribers = {
277
- ...(await this.getRecrusiveClassesfromContextsObj(Models.ClassType.SUBSCRIBER)),
278
- ...this.config.subscribers,
279
- };
280
- this.config.repositories = {
281
- ...(await this.getRecrusiveClassesfromContextsObj(Models.ClassType.REPOSITORY)),
282
- ...this.config.repositories,
283
- };
284
- this.config.migrations = {
285
- ...(await this.getRecrusiveClassesfromContextsObj(Models.ClassType.MIGRATION)),
286
- ...this.config.migrations,
287
- };
288
- this.config.controllers = this.cloneClassesObjWithNewMetadata({
289
- classesInput: this.config.controllers,
290
- config: this.config,
291
- ctx: this,
292
- classType: Models.ClassType.CONTROLLER,
293
- });
294
- this.config.repositories = this.cloneClassesObjWithNewMetadata({
295
- classesInput: this.config.repositories,
296
- config: this.config,
297
- ctx: this,
298
- classType: Models.ClassType.REPOSITORY,
299
- });
300
- this.config.providers = this.cloneClassesObjWithNewMetadata({
301
- classesInput: this.config.providers,
302
- config: this.config,
303
- ctx: this,
304
- classType: Models.ClassType.PROVIDER,
305
- });
306
- this.config.subscribers = this.cloneClassesObjWithNewMetadata({
307
- classesInput: this.config.subscribers,
308
- config: this.config,
309
- ctx: this,
310
- classType: Models.ClassType.SUBSCRIBER,
311
- });
312
- this.config.migrations = this.cloneClassesObjWithNewMetadata({
313
- classesInput: this.config.migrations,
314
- config: this.config,
315
- ctx: this,
316
- classType: Models.ClassType.MIGRATION,
317
- });
318
- for (const classTypeName of this.injectableTypesfromContexts) {
319
- this.classInstancesByNameObj[classTypeName] = {};
320
- this.objWithClassesInstancesArr[classTypeName] = [];
321
- }
322
- for (const classTypeName of this.injectableTypesfromContexts) {
323
- await this.createInstances(this.config[Models.ClassTypeKey[classTypeName]], classTypeName);
324
- }
325
- if (!this.isRunOrRevertOnlyMigrationAppStart) {
326
- if (this.mode === 'backend-frontend(tcp+udp)' && !this.config.abstract) {
327
- /* */
328
- /* */
329
- /* */
330
- /* */
331
- /* */
332
- /* */
333
- /* */
334
- /* */
335
- /* */
336
- /* */
337
- /* */
338
- /* */
339
- /* */
340
- /* */
341
- /* */
342
- /* */
343
- /* */
344
- /* */
345
- /* */
346
- }
347
- if (!this.config.abstract) {
348
- this.disabledRealtime = !!this.config.disabledRealtime;
349
- /* */
350
- /* */
351
- /* */
352
- /* */
353
- /* */
354
- this.realtime = new RealtimeCore(this);
355
- }
356
- }
357
- if (this.config.abstract) {
358
- this.logFramework &&
359
- Helpers.info(`[taon] Create abstract context: ${this.config.contextName}`);
360
- }
361
- else {
362
- if (this.config.remoteHost) {
363
- this.logFramework &&
364
- Helpers.info(`[taon] Create context for remote host: ${this.config.remoteHost}`);
365
- }
366
- else {
367
- this.logFramework &&
368
- Helpers.info(`[taon] Create context for host: ${this.config.host}`);
369
- }
370
- }
371
- Object.keys(this.config).forEach(key => {
372
- this.originalConfig[key] = this.config[key];
373
- });
374
- }
375
- getAutoGeneratedConfig() {
376
- let databaseConfig = Models.DatabaseConfig.from({});
377
- if (UtilsOs.isRunningInDocker()) {
378
- Helpers.info('Running in docker, using in mysql database');
379
- databaseConfig = Models.DatabaseConfig.from({
380
- database: `db-${this.contextName}.sqlite`,
381
- type: 'mysql',
382
- recreateMode: 'PRESERVE_DATA+MIGRATIONS',
383
- logging: this.logDb,
384
- databasePort: 3306,
385
- databaseHost: 'localhost',
386
- databaseUsername: 'root',
387
- databasePassword: 'admin',
388
- });
389
- }
390
- else {
391
- this.logFramework &&
392
- Helpers.info(`[taon][database] Automatically resolving database config for mode ${this.mode}`);
393
- switch (this.mode) {
394
- case 'backend-frontend(ipc-electron)':
395
- databaseConfig = Models.DatabaseConfig.from({
396
- location: `db-${this.contextName}.sqlite`,
397
- type: 'sqljs',
398
- recreateMode: 'DROP_DB+MIGRATIONS',
399
- logging: this.logDb,
400
- });
401
- break;
402
- case 'backend-frontend(websql-electron)':
403
- case 'backend-frontend(websql)':
404
- let keepWebsqlDbDataAfterReload = false;
405
- keepWebsqlDbDataAfterReload =
406
- TaonAdminService.Instance?.keepWebsqlDbDataAfterReload; // TODO @LAST
407
- databaseConfig = databaseConfig = Models.DatabaseConfig.from({
408
- location: `db-${this.contextName}.sqlite`,
409
- type: 'sqljs',
410
- useLocalForage: true, // !!window['localforage'], // TODO this need to be checked in runtime
411
- recreateMode: keepWebsqlDbDataAfterReload
412
- ? 'PRESERVE_DATA+MIGRATIONS'
413
- : 'DROP_DB+MIGRATIONS',
414
- logging: this.logDb,
415
- });
416
- break;
417
- case 'backend-frontend(tcp+udp)':
418
- databaseConfig = Models.DatabaseConfig.from({
419
- database: `context-db-${this.contextName}`,
420
- location: `db-${this.contextName}.sqlite`,
421
- type: 'sqljs',
422
- recreateMode: 'DROP_DB+MIGRATIONS',
423
- logging: this.logDb,
424
- });
425
- break;
426
- }
427
- }
428
- return databaseConfig.databaseConfigTypeORM;
429
- }
430
- get ngZone() {
431
- return EndpointContext.ngZone;
432
- return;
433
- }
434
- startServer() {
435
- /* */
436
- /* */
437
- /* */
438
- /* */
439
- /* */
440
- /* */
441
- /* */
442
- /* */
443
- /* */
444
- /* */
445
- /* */
446
- /* */
447
- /* */
448
- /* */
449
- /* */
450
- /* */
451
- return (void 0);
452
- }
453
- displayRoutes(app) {
454
- /* */
455
- /* */
456
- /* */
457
- /* */
458
- /* */
459
- /* */
460
- /* */
461
- /* */
462
- /* */
463
- /* */
464
- /* */
465
- /* */
466
- /* */
467
- /* */
468
- /* */
469
- /* */
470
- /* */
471
- /* */
472
- /* */
473
- /* */
474
- /* */
475
- /* */
476
- /* */
477
- /* */
478
- /* */
479
- /* */
480
- /* */
481
- /* */
482
- }
483
- get modeAllowsDatabaseCreation() {
484
- return (this.mode === 'backend-frontend(tcp+udp)' ||
485
- this.mode === 'backend-frontend(websql)' ||
486
- this.mode === 'backend-frontend(ipc-electron)');
487
- }
488
- async getRecrusiveClassesfromContextsObj(classType) {
489
- const arr = await this.getRecrusiveClassesfromContexts(classType);
490
- return arr.reduce((acc, c) => {
491
- acc[ClassHelpers.getName(c)] = c;
492
- return acc;
493
- }, {});
494
- }
495
- async getRecrusiveClassesfromContexts(classType, arr = []) {
496
- const contexts = Object.values(this.config.contexts || {});
497
- for (const ctx of contexts) {
498
- const ref = await ctx.__ref();
499
- const classesInput = ref.getClassFunBy(classType);
500
- const clonedClasses = Object.values(this.cloneClassesObjWithNewMetadata({
501
- classesInput,
502
- config: this.config,
503
- ctx: this,
504
- classType,
505
- }));
506
- clonedClasses.forEach(c => arr.push(c));
507
- await ref.getRecrusiveClassesfromContexts(classType, arr);
508
- }
509
- return arr;
510
- }
511
- getClassInstanceObjBy(classType) {
512
- return this.classInstancesByNameObj[classType];
513
- }
514
- getClassesInstancesArrBy(classType) {
515
- return this.objWithClassesInstancesArr[classType];
516
- }
517
- inject(ctor, options) {
518
- if (!options) {
519
- options = {};
520
- }
521
- const className = ClassHelpers.getName(ctor);
522
- const locaInstanceConstructorArgs = options.locaInstanceConstructorArgs || [];
523
- if (this.isCLassType(Models.ClassType.REPOSITORY, ctor)) {
524
- options.localInstance = true;
525
- }
526
- if (options?.localInstance) {
527
- const ctxClassFn = this.getClassFunByClassName(className);
528
- let entityName = '';
529
- if (className === 'BaseRepository') {
530
- const entityFn = locaInstanceConstructorArgs[0];
531
- const entity = entityFn && entityFn();
532
- entityName = entity && ClassHelpers.getName(entity);
533
- }
534
- if (!options.contextClassInstance[this.localInstaceObjSymbol]) {
535
- options.contextClassInstance[this.localInstaceObjSymbol] = {};
536
- }
537
- const instanceKey = className + (entityName ? `.${entityName}` : '');
538
- const existed = options.contextClassInstance[this.localInstaceObjSymbol][instanceKey];
539
- if (existed) {
540
- return existed;
541
- }
542
- if (!ctxClassFn) {
543
- throw new Error(`Not able to inject "${className}" inside context "${this.contextName}"
544
-
545
- Make sure they share the same context or import context where "${className}" is defined.
546
-
547
- `);
548
- }
549
- const injectedInstance = new ctxClassFn(...locaInstanceConstructorArgs);
550
- options.contextClassInstance[this.localInstaceObjSymbol][instanceKey] =
551
- injectedInstance;
552
- return injectedInstance;
553
- }
554
- const contextScopeInstance = this.allClassesInstances[className];
555
- return contextScopeInstance;
556
- }
557
- /**
558
- * alias for inject
559
- */
560
- getInstanceBy(ctor) {
561
- return this.inject(ctor, { localInstance: false });
562
- }
563
- checkIfContextInitialized() {
564
- if (_.isUndefined(this.config)) {
565
- throw new Error(`Please check if your context has been initialized.
566
-
567
-
568
- await Context.initialize();
569
-
570
-
571
-
572
- `);
573
- }
574
- }
575
- getClassFunBy(classType) {
576
- this.checkIfContextInitialized();
577
- switch (classType) {
578
- case Models.ClassType.CONTROLLER:
579
- return this.config.controllers;
580
- case Models.ClassType.ENTITY:
581
- return this.config.entities;
582
- case Models.ClassType.PROVIDER:
583
- return this.config.providers;
584
- case Models.ClassType.REPOSITORY:
585
- return this.config.repositories;
586
- case Models.ClassType.SUBSCRIBER:
587
- return this.config.subscribers;
588
- case Models.ClassType.MIGRATION:
589
- return this.config.migrations;
590
- }
591
- }
592
- isCLassType(classType, classFn) {
593
- return !!this.getClassFunBy(classType)[ClassHelpers.getName(classFn)];
594
- }
595
- /**
596
- * Only for injectable types
597
- * Only for classType: CONTROLLER, REPOSITORY, PROVIDER
598
- */
599
- getClassFunByClassName(className) {
600
- for (const classTypeName of this.allTypesfromContexts) {
601
- const classesForInjectableType = this.config[Models.ClassTypeKey[classTypeName]];
602
- if (classesForInjectableType[className]) {
603
- return classesForInjectableType[className];
604
- }
605
- }
606
- }
607
- getClassFunByClass(classFunction) {
608
- const className = ClassHelpers.getName(classFunction);
609
- return this.getClassFunByClassName(className);
610
- }
611
- getClassFunByArr(classType) {
612
- return Object.values(this.getClassFunBy(classType) || {});
613
- }
614
- async createInstances(classes, classType) {
615
- for (const classFn of [
616
- ...Object.values(classes),
617
- ]) {
618
- const instance = DITaonContainer.resolve(classFn);
619
- const classInstancesByNameObj = this.classInstancesByNameObj[classType];
620
- const className = ClassHelpers.getName(classFn);
621
- classInstancesByNameObj[className] = instance;
622
- this.config[Models.ClassTypeKey[classType]][className] = classFn;
623
- this.objWithClassesInstancesArr[classType].push(instance);
624
- this.allClassesInstances[className] = instance;
625
- }
626
- }
627
- async reinitControllers() {
628
- if (this.remoteHost || Object.keys(this.config.migrations).length > 0) {
629
- return;
630
- }
631
- const controllers = this.getClassesInstancesArrBy(Models.ClassType.CONTROLLER);
632
- for (const ctrl of controllers) {
633
- if (_.isFunction(ctrl.initExampleDbData)) {
634
- await Helpers.runSyncOrAsync({
635
- functionFn: ctrl.initExampleDbData,
636
- context: ctrl,
637
- });
638
- }
639
- }
640
- }
641
- async initClasses() {
642
- if (this.remoteHost) {
643
- return;
644
- }
645
- for (const classTypeName of [
646
- Models.ClassType.PROVIDER,
647
- Models.ClassType.REPOSITORY,
648
- Models.ClassType.CONTROLLER,
649
- Models.ClassType.ENTITY,
650
- Models.ClassType.MIGRATION,
651
- ]) {
652
- for (const classFun of this.getClassFunByArr(classTypeName)) {
653
- if (_.isFunction(classFun._)) {
654
- await Helpers.runSyncOrAsync({
655
- functionFn: classFun._,
656
- context: classFun,
657
- });
658
- }
659
- }
660
- }
661
- for (const classTypeName of [
662
- Models.ClassType.PROVIDER,
663
- Models.ClassType.REPOSITORY,
664
- Models.ClassType.CONTROLLER,
665
- Models.ClassType.MIGRATION,
666
- ]) {
667
- for (const ctrl of this.getClassesInstancesArrBy(classTypeName)) {
668
- if (_.isFunction(ctrl._)) {
669
- await Helpers.runSyncOrAsync({
670
- functionFn: ctrl._,
671
- context: ctrl,
672
- });
673
- }
674
- }
675
- }
676
- }
677
- isActiveOn(classInstance) {
678
- let contextRef = classInstance[Symbols.ctxInClassOrClassObj];
679
- return this === contextRef;
680
- }
681
- get uri() {
682
- const url = this.host
683
- ? new URL(this.host)
684
- : this.remoteHost
685
- ? new URL(this.remoteHost)
686
- : void 0;
687
- return url;
688
- }
689
- get isHttpServer() {
690
- return this.uri.protocol === 'https:';
691
- }
692
- /**
693
- * ipc/udp needs this
694
- */
695
- get contextName() {
696
- return this.config.contextName;
697
- }
698
- get publicAssets() {
699
- return this.config?.publicAssets || [];
700
- }
701
- get isProductionMode() {
702
- return this.config.productionMode;
703
- }
704
- get remoteHost() {
705
- return this.config.remoteHost;
706
- }
707
- get host() {
708
- return this.config.host;
709
- }
710
- get orgin() {
711
- return this.uri?.origin;
712
- }
713
- async initSubscribers() {
714
- if (this.remoteHost) {
715
- return;
716
- }
717
- const subscriberClasses = this.getClassFunByArr(Models.ClassType.SUBSCRIBER);
718
- for (const subscriberClassFn of subscriberClasses) {
719
- const options = Reflect.getMetadata(Symbols.metadata.options.subscriber, subscriberClassFn);
720
- EventSubscriber()(subscriberClassFn);
721
- }
722
- }
723
- async initEntities() {
724
- if (this.remoteHost) {
725
- return;
726
- }
727
- const entities = this.getClassFunByArr(Models.ClassType.ENTITY);
728
- for (const entity of entities) {
729
- const options = Reflect.getMetadata(Symbols.metadata.options.entity, entity);
730
- const createTable = _.isUndefined(options.createTable)
731
- ? true
732
- : options.createTable;
733
- const nameForEntity = ClassHelpers.getName(entity);
734
- if (_.isUndefined(options.createTable) ? true : options.createTable) {
735
- this.logDb &&
736
- console.info(`[taon][typeorm] create table for entity "${nameForEntity}" ? '${createTable}'`);
737
- TypeormEntity(nameForEntity)(entity);
738
- }
739
- else {
740
- this.logDb &&
741
- console.info(`[taon][typeorm] create table for entity "${nameForEntity}" ? '${createTable}'`);
742
- }
743
- }
744
- }
745
- async initDatabaseConnection() {
746
- if (this.remoteHost) {
747
- return;
748
- }
749
- const entities = this.getClassFunByArr(Models.ClassType.ENTITY).map(entityFn => {
750
- return ClassHelpers.getOrginalClass(entityFn);
751
- });
752
- const subscribers = this.getClassFunByArr(Models.ClassType.SUBSCRIBER);
753
- const dataSourceDbConfig = _.isObject(this.databaseConfig)
754
- ? {
755
- type: this.databaseConfig.type,
756
- port: this.databaseConfig.databasePort,
757
- host: this.databaseConfig.databaseHost,
758
- database: this.databaseConfig.database,
759
- username: this.databaseConfig.databaseUsername,
760
- password: this.databaseConfig.databasePassword,
761
- useLocalForage: this.databaseConfig.useLocalForage,
762
- entities,
763
- subscribers,
764
- synchronize: this.isRunOrRevertOnlyMigrationAppStart
765
- ? false
766
- : this.databaseConfig.synchronize,
767
- autoSave: !_.isNil(this.databaseConfig.autoSave)
768
- ? this.databaseConfig.autoSave
769
- : !UtilsOs.isRunningInDocker(), // in docker I am using mysql or posgress
770
- dropSchema: this.isRunOrRevertOnlyMigrationAppStart
771
- ? false
772
- : this.databaseConfig.dropSchema,
773
- logging: !!this.databaseConfig.logging,
774
- location: this.databaseConfig.location,
775
- }
776
- : {};
777
- this.logFramework &&
778
- console.log(`[Context: "${this.contextName}"] dataSourceDbConfig`, dataSourceDbConfig);
779
- if (this.modeAllowsDatabaseCreation && this.databaseConfig) {
780
- this.logDb &&
781
- this.logFramework &&
782
- Helpers.info('[taon][database] prepare typeorm connection...');
783
- try {
784
- const connection = new DataSource(dataSourceDbConfig);
785
- this.connection = connection;
786
- await this.connection.initialize();
787
- }
788
- catch (error) {
789
- console.error(error?.message || error);
790
- }
791
- if (!this.connection?.isInitialized) {
792
- console.log('WRONG CONFIG', dataSourceDbConfig);
793
- throw new Error(`Something wrong with connection init in ${this.mode}`);
794
- /* */
795
- /* */
796
- }
797
- if (this.logDb || this.logFramework) {
798
- console.info(`
799
-
800
- CONTECTION OK for ${this.contextName} - ${this.mode}
801
-
802
- [taon][typeorm] db prepration done.. db initialize=${this.connection?.isInitialized}
803
-
804
-
805
- `, dataSourceDbConfig, { 'this.connection': !!this.connection });
806
- console.log(`Database file location: ${this.connection.options.database}`);
807
- }
808
- }
809
- else {
810
- Helpers.info(`[taon][typeorm] Not initing db for mode ${this.mode}`);
811
- }
812
- }
813
- initControllers() {
814
- if (this.isRunOrRevertOnlyMigrationAppStart) {
815
- return;
816
- }
817
- const allControllers = this.getClassFunByArr(Models.ClassType.CONTROLLER);
818
- for (const controllerClassFn of allControllers) {
819
- controllerClassFn[Symbols.classMethodsNames] =
820
- ClassHelpers.getMethodsNames(controllerClassFn);
821
- const configs = ClassHelpers.getControllerConfigs(controllerClassFn);
822
- const classConfig = configs[0];
823
- const parentscalculatedPath = _.slice(configs, 1)
824
- .reverse()
825
- .map(bc => {
826
- if (TaonHelpers.isGoodPath(bc.path)) {
827
- return bc.path;
828
- }
829
- return bc.className;
830
- })
831
- .join('/');
832
- if (TaonHelpers.isGoodPath(classConfig.path)) {
833
- classConfig.calculatedPath = classConfig.path;
834
- }
835
- else {
836
- classConfig.calculatedPath =
837
- `${parentscalculatedPath}/${ClassHelpers.getName(controllerClassFn)}`
838
- .replace(/\/\//g, '/')
839
- .split('/')
840
- .reduce((acc, bc) => {
841
- return _.last(acc) === bc ? acc : [...acc, bc];
842
- }, [])
843
- .join('/');
844
- }
845
- _.slice(configs, 1).forEach(bc => {
846
- const alreadyIs = classConfig.methods;
847
- const toMerge = _.cloneDeep(bc.methods);
848
- for (const key in toMerge) {
849
- if (toMerge.hasOwnProperty(key) && !alreadyIs[key]) {
850
- const element = toMerge[key];
851
- alreadyIs[key] = element;
852
- }
853
- }
854
- });
855
- /* */
856
- /* */
857
- this.logHttp &&
858
- console.groupCollapsed(`[taon][express-server] routes [${classConfig.className}]`);
859
- /* */
860
- /* */
861
- Object.keys(classConfig.methods).forEach(methodName => {
862
- const methodConfig = classConfig.methods[methodName];
863
- const type = methodConfig.type;
864
- const expressPath = methodConfig.global
865
- ? `/${methodConfig.path?.replace(/\//, '')}`
866
- : TaonHelpers.getExpressPath(classConfig, methodConfig);
867
- if (Helpers.isNode || Helpers.isWebSQL) {
868
- const { routePath, method } = this.initServer(type, methodConfig, classConfig, expressPath, controllerClassFn);
869
- this.activeRoutes.push({
870
- routePath,
871
- method,
872
- });
873
- }
874
- const shouldInitClient = Helpers.isBrowser || this.remoteHost || Helpers.isWebSQL;
875
- if (shouldInitClient) {
876
- this.initClient(controllerClassFn, type, methodConfig, expressPath);
877
- }
878
- });
879
- /* */
880
- /* */
881
- this.logHttp && console.groupEnd();
882
- /* */
883
- /* */
884
- }
885
- }
886
- writeActiveRoutes() {
887
- if (this.remoteHost ||
888
- this.isRunOrRevertOnlyMigrationAppStart ||
889
- this.skipWritingServerRoutes) {
890
- return;
891
- }
892
- const contexts = [this];
893
- const troutes = Utils.uniqArray(this.activeRoutes.map(f => {
894
- return `${f.method} ${f.routePath}`;
895
- })).map(f => {
896
- const [method, routePath] = f.split(' ');
897
- return (`\n### ${_.startCase(_.last(routePath.split('/')))}\n` +
898
- TaonHelpers.fillUpTo(method.toUpperCase() + ' ', 10) +
899
- this.uri.href.replace(/\/$/, '') +
900
- routePath);
901
- });
902
- const routes = [
903
- ...['', `# ROUTES FOR HOST ${this.uri.href} `],
904
- ...troutes,
905
- ].join('\n');
906
- const fileName = crossPlatformPath([
907
- /* */
908
- /* */
909
- `routes-${this.config.contextName}.rest`,
910
- ]);
911
- this.logFramework && console.log(`[taon] routes file: ${fileName} `);
912
- /* */
913
- /* */
914
- }
915
- get middlewares() {
916
- /* */
917
- /* */
918
- return (void 0);
919
- }
920
- initMiddlewares() {
921
- /* */
922
- /* */
923
- /* */
924
- /* */
925
- /* */
926
- /* */
927
- /* */
928
- /* */
929
- /* */
930
- /* */
931
- /* */
932
- /* */
933
- /* */
934
- /* */
935
- /* */
936
- /* */
937
- /* */
938
- /* */
939
- /* */
940
- /* */
941
- /* */
942
- /* */
943
- /* */
944
- /* */
945
- /* */
946
- /* */
947
- /* */
948
- /* */
949
- /* */
950
- /* */
951
- /* */
952
- /* */
953
- /* */
954
- /* */
955
- /* */
956
- /* */
957
- /* */
958
- /* */
959
- /* */
960
- /* */
961
- /* */
962
- /* */
963
- /* */
964
- /* */
965
- /* */
966
- /* */
967
- /* */
968
- /* */
969
- /* */
970
- /* */
971
- /* */
972
- /* */
973
- /* */
974
- /* */
975
- /* */
976
- /* */
977
- /* */
978
- /* */
979
- /* */
980
- /* */
981
- /* */
982
- /* */
983
- /* */
984
- /* */
985
- /* */
986
- /* */
987
- /* */
988
- /* */
989
- /* */
990
- /* */
991
- /* */
992
- /* */
993
- /* */
994
- /* */
995
- /* */
996
- /* */
997
- /* */
998
- /* */
999
- /* */
1000
- /* */
1001
- /* */
1002
- /* */
1003
- /* */
1004
- /* */
1005
- /* */
1006
- /* */
1007
- /* */
1008
- /* */
1009
- /* */
1010
- /* */
1011
- /* */
1012
- /* */
1013
- /* */
1014
- /* */
1015
- /* */
1016
- /* */
1017
- /* */
1018
- /* */
1019
- /* */
1020
- /* */
1021
- /* */
1022
- /* */
1023
- }
1024
- initServer(type, methodConfig, classConfig, expressPath, target) {
1025
- const requestHandler = methodConfig.requestHandler &&
1026
- typeof methodConfig.requestHandler === 'function'
1027
- ? methodConfig.requestHandler
1028
- : (req, res, next) => {
1029
- next();
1030
- };
1031
- const url = this.uri;
1032
- const getResult = async (resolvedParams, req, res) => {
1033
- const response = methodConfig.descriptor.value.apply(
1034
- /**
1035
- * Context for method @GET,@PUT etc.
1036
- */
1037
- this.getInstanceBy(target),
1038
- /**
1039
- * Params for metjod @GET, @PUT etc.
1040
- */
1041
- resolvedParams);
1042
- let result = await getResponseValue(response, { req, res });
1043
- return result;
1044
- };
1045
- url.pathname = url.pathname.replace(/\/$/, '');
1046
- expressPath = url.pathname.startsWith('/')
1047
- ? `${url.pathname}${expressPath}`
1048
- : expressPath;
1049
- expressPath = expressPath.replace(/\/\//g, '/');
1050
- if (Helpers.isElectron) {
1051
- /* */
1052
- /* */
1053
- /* */
1054
- /* */
1055
- /* */
1056
- /* */
1057
- /* */
1058
- /* */
1059
- /* */
1060
- /* */
1061
- /* */
1062
- /* */
1063
- /* */
1064
- /* */
1065
- /* */
1066
- /* */
1067
- /* */
1068
- /* */
1069
- /* */
1070
- /* */
1071
- /* */
1072
- }
1073
- if (!this.remoteHost) {
1074
- if (Helpers.isWebSQL) {
1075
- if (!this.expressApp[type.toLowerCase()]) {
1076
- this.expressApp[type.toLowerCase()] = () => { };
1077
- }
1078
- }
1079
- /* */
1080
- /* */
1081
- /* */
1082
- /* */
1083
- /* */
1084
- /* */
1085
- /* */
1086
- /* */
1087
- /* */
1088
- /* */
1089
- /* */
1090
- /* */
1091
- /* */
1092
- /* */
1093
- /* */
1094
- /* */
1095
- /* */
1096
- /* */
1097
- /* */
1098
- /* */
1099
- /* */
1100
- /* */
1101
- /* */
1102
- /* */
1103
- /* */
1104
- /* */
1105
- /* */
1106
- /* */
1107
- /* */
1108
- /* */
1109
- /* */
1110
- /* */
1111
- /* */
1112
- /* */
1113
- /* */
1114
- /* */
1115
- /* */
1116
- /* */
1117
- /* */
1118
- /* */
1119
- /* */
1120
- /* */
1121
- /* */
1122
- /* */
1123
- /* */
1124
- /* */
1125
- /* */
1126
- /* */
1127
- /* */
1128
- /* */
1129
- /* */
1130
- /* */
1131
- /* */
1132
- /* */
1133
- /* */
1134
- /* */
1135
- /* */
1136
- /* */
1137
- /* */
1138
- /* */
1139
- /* */
1140
- /* */
1141
- /* */
1142
- /* */
1143
- /* */
1144
- /* */
1145
- /* */
1146
- /* */
1147
- /* */
1148
- /* */
1149
- /* */
1150
- /* */
1151
- /* */
1152
- /* */
1153
- /* */
1154
- /* */
1155
- /* */
1156
- /* */
1157
- /* */
1158
- /* */
1159
- /* */
1160
- /* */
1161
- /* */
1162
- /* */
1163
- /* */
1164
- /* */
1165
- /* */
1166
- /* */
1167
- /* */
1168
- /* */
1169
- /* */
1170
- /* */
1171
- /* */
1172
- /* */
1173
- /* */
1174
- /* */
1175
- /* */
1176
- /* */
1177
- /* */
1178
- /* */
1179
- /* */
1180
- /* */
1181
- /* */
1182
- /* */
1183
- /* */
1184
- /* */
1185
- /* */
1186
- /* */
1187
- /* */
1188
- /* */
1189
- /* */
1190
- /* */
1191
- /* */
1192
- /* */
1193
- /* */
1194
- /* */
1195
- /* */
1196
- /* */
1197
- /* */
1198
- /* */
1199
- /* */
1200
- /* */
1201
- /* */
1202
- /* */
1203
- /* */
1204
- /* */
1205
- /* */
1206
- /* */
1207
- /* */
1208
- /* */
1209
- /* */
1210
- /* */
1211
- /* */
1212
- /* */
1213
- /* */
1214
- /* */
1215
- /* */
1216
- /* */
1217
- /* */
1218
- /* */
1219
- /* */
1220
- /* */
1221
- /* */
1222
- /* */
1223
- /* */
1224
- /* */
1225
- /* */
1226
- /* */
1227
- /* */
1228
- /* */
1229
- /* */
1230
- /* */
1231
- /* */
1232
- /* */
1233
- /* */
1234
- /* */
1235
- /* */
1236
- /* */
1237
- /* */
1238
- /* */
1239
- /* */
1240
- /* */
1241
- /* */
1242
- /* */
1243
- /* */
1244
- /* */
1245
- /* */
1246
- /* */
1247
- /* */
1248
- /* */
1249
- /* */
1250
- /* */
1251
- /* */
1252
- /* */
1253
- /* */
1254
- /* */
1255
- /* */
1256
- /* */
1257
- /* */
1258
- /* */
1259
- /* */
1260
- /* */
1261
- /* */
1262
- /* */
1263
- /* */
1264
- /* */
1265
- /* */
1266
- /* */
1267
- /* */
1268
- /* */
1269
- /* */
1270
- /* */
1271
- /* */
1272
- /* */
1273
- /* */
1274
- /* */
1275
- /* */
1276
- /* */
1277
- /* */
1278
- /* */
1279
- /* */
1280
- /* */
1281
- /* */
1282
- /* */
1283
- /* */
1284
- /* */
1285
- /* */
1286
- /* */
1287
- /* */
1288
- /* */
1289
- /* */
1290
- /* */
1291
- /* */
1292
- /* */
1293
- }
1294
- return {
1295
- routePath: expressPath,
1296
- method: methodConfig.type,
1297
- };
1298
- }
1299
- /**
1300
- * client can be browser or nodejs (when remote host)
1301
- */
1302
- initClient(target, type, methodConfig, expressPath) {
1303
- const ctx = this;
1304
- this.logHttp && console.log(`${type?.toUpperCase()} ${expressPath} `);
1305
- let storage;
1306
- if (Helpers.isBrowser) {
1307
- storage = window;
1308
- }
1309
- /* */
1310
- /* */
1311
- /* */
1312
- /* */
1313
- const orgMethods = target.prototype[methodConfig.methodName];
1314
- if (Helpers.isElectron) {
1315
- target.prototype[methodConfig.methodName] = function (...args) {
1316
- const received = new Promise(async (resolve, reject) => {
1317
- const headers = {};
1318
- const { request, response } = TaonHelpers.websqlMocks(headers);
1319
- Helpers.ipcRenderer.once(TaonHelpers.ipcKeyNameResponse(target, methodConfig, expressPath), (event, responseData) => {
1320
- let res = responseData;
1321
- console.log({ responseData });
1322
- try {
1323
- const body = res;
1324
- res = new ModelsNg2Rest.HttpResponse({
1325
- body: void 0,
1326
- isArray: void 0,
1327
- method: methodConfig.type,
1328
- url: `${ctx.uri.origin}${'' // TODO express path
1329
- }${methodConfig.path} `,
1330
- }, Helpers.isBlob(body) || _.isString(body)
1331
- ? body
1332
- : JSON.stringify(body), RestHeaders.from(headers), void 0, () => body);
1333
- resolve(res);
1334
- }
1335
- catch (error) {
1336
- console.error(error);
1337
- reject(error);
1338
- }
1339
- });
1340
- Helpers.ipcRenderer.send(TaonHelpers.ipcKeyNameRequest(target, methodConfig, expressPath), args);
1341
- });
1342
- received['observable'] = from(received);
1343
- return {
1344
- received,
1345
- };
1346
- };
1347
- return;
1348
- }
1349
- const MIN_TIMEOUT = 500;
1350
- const MIN_TIMEOUT_STEP = 200;
1351
- const timeout = window[Symbols.old.WEBSQL_REST_PROGRESS_TIMEOUT] || MIN_TIMEOUT;
1352
- let updateFun = window[Symbols.old.WEBSQL_REST_PROGRESS_FUN];
1353
- if (!window[Symbols.old.WEBSQL_REST_PROGRESS_FUN]) {
1354
- window[Symbols.old.WEBSQL_REST_PROGRESS_FUN] = new Subject();
1355
- }
1356
- updateFun = window[Symbols.old.WEBSQL_REST_PROGRESS_FUN];
1357
- let startFun = window[Symbols.old.WEBSQL_REST_PROGRESS_FUN_START];
1358
- if (!window[Symbols.old.WEBSQL_REST_PROGRESS_FUN_START]) {
1359
- window[Symbols.old.WEBSQL_REST_PROGRESS_FUN_START] = new Subject();
1360
- }
1361
- startFun = window[Symbols.old.WEBSQL_REST_PROGRESS_FUN_START];
1362
- let doneFun = window[Symbols.old.WEBSQL_REST_PROGRESS_FUN_DONE];
1363
- if (!window[Symbols.old.WEBSQL_REST_PROGRESS_FUN_DONE]) {
1364
- window[Symbols.old.WEBSQL_REST_PROGRESS_FUN_DONE] = new Subject();
1365
- }
1366
- doneFun = window[Symbols.old.WEBSQL_REST_PROGRESS_FUN_DONE];
1367
- let periodsToUpdate = 0;
1368
- if (timeout >= MIN_TIMEOUT) {
1369
- periodsToUpdate = Math.floor(timeout / MIN_TIMEOUT_STEP);
1370
- }
1371
- const periods = async () => {
1372
- startFun.next();
1373
- for (let n = 1; n <= periodsToUpdate; n++) {
1374
- let upValue = Math.round(((MIN_TIMEOUT_STEP * n) / timeout) * 100);
1375
- if (upValue > 100) {
1376
- upValue = 100;
1377
- }
1378
- updateFun.next(upValue);
1379
- await new Promise((resolve, reject) => {
1380
- setTimeout(() => {
1381
- resolve(void 0);
1382
- }, MIN_TIMEOUT_STEP);
1383
- });
1384
- }
1385
- doneFun.next();
1386
- };
1387
- target.prototype[methodConfig.methodName] = function (...args) {
1388
- const received = new Promise(async (resolve, reject) => {
1389
- const headers = {};
1390
- const { request, response } = TaonHelpers.websqlMocks(headers);
1391
- let res;
1392
- try {
1393
- res = await Helpers.runSyncOrAsync({
1394
- functionFn: orgMethods,
1395
- context: this,
1396
- arrayOfParams: args,
1397
- });
1398
- if (typeof res === 'function') {
1399
- res = await Helpers.runSyncOrAsync({
1400
- functionFn: res,
1401
- context: this,
1402
- arrayOfParams: [request, response],
1403
- });
1404
- }
1405
- if (typeof res === 'function') {
1406
- res = await Helpers.runSyncOrAsync({
1407
- functionFn: res,
1408
- context: this,
1409
- arrayOfParams: [request, response],
1410
- });
1411
- }
1412
- if (typeof res === 'object' && res?.received) {
1413
- res = await res.received;
1414
- }
1415
- const body = res;
1416
- res = new ModelsNg2Rest.HttpResponse({
1417
- body: void 0,
1418
- isArray: void 0,
1419
- method: methodConfig.type,
1420
- url: `${ctx.uri.origin}${'' // TODO express path
1421
- }${methodConfig.path} `,
1422
- }, Helpers.isBlob(body) || _.isString(body)
1423
- ? body
1424
- : JSON.stringify(body), RestHeaders.from(headers), void 0, () => body);
1425
- await periods();
1426
- resolve(res);
1427
- }
1428
- catch (error) {
1429
- await periods();
1430
- console.error(error);
1431
- reject(error);
1432
- }
1433
- });
1434
- received['observable'] = from(received);
1435
- if (Helpers.isWebSQL) {
1436
- return {
1437
- received,
1438
- };
1439
- }
1440
- };
1441
- if (Helpers.isWebSQL) {
1442
- return;
1443
- }
1444
- target.prototype[methodConfig.methodName] = function (...args) {
1445
- if (!storage[Symbols.old.ENDPOINT_META_CONFIG])
1446
- storage[Symbols.old.ENDPOINT_META_CONFIG] = {};
1447
- if (!storage[Symbols.old.ENDPOINT_META_CONFIG][ctx.uri.href])
1448
- storage[Symbols.old.ENDPOINT_META_CONFIG][ctx.uri.href] = {};
1449
- const endpoints = storage[Symbols.old.ENDPOINT_META_CONFIG];
1450
- let rest;
1451
- if (!endpoints[ctx.uri.href][expressPath]) {
1452
- let headers = {};
1453
- if (methodConfig.contentType && !methodConfig.responseType) {
1454
- rest = Resource.create(ctx.uri.href, expressPath, Symbols.old.MAPPING_CONFIG_HEADER, Symbols.old.CIRCURAL_OBJECTS_MAP_BODY, RestHeaders.from({
1455
- 'Content-Type': methodConfig.contentType,
1456
- Accept: methodConfig.contentType,
1457
- }));
1458
- }
1459
- else if (methodConfig.contentType && methodConfig.responseType) {
1460
- rest = Resource.create(ctx.uri.href, expressPath, Symbols.old.MAPPING_CONFIG_HEADER, Symbols.old.CIRCURAL_OBJECTS_MAP_BODY, RestHeaders.from({
1461
- 'Content-Type': methodConfig.contentType,
1462
- Accept: methodConfig.contentType,
1463
- responsetypeaxios: methodConfig.responseType,
1464
- }));
1465
- }
1466
- else if (!methodConfig.contentType && methodConfig.responseType) {
1467
- rest = Resource.create(ctx.uri.href, expressPath, Symbols.old.MAPPING_CONFIG_HEADER, Symbols.old.CIRCURAL_OBJECTS_MAP_BODY, RestHeaders.from({
1468
- responsetypeaxios: methodConfig.responseType,
1469
- }));
1470
- }
1471
- else {
1472
- rest = Resource.create(ctx.uri.href, expressPath, Symbols.old.MAPPING_CONFIG_HEADER, Symbols.old.CIRCURAL_OBJECTS_MAP_BODY);
1473
- }
1474
- endpoints[ctx.uri.href][expressPath] = rest;
1475
- }
1476
- else {
1477
- rest = endpoints[ctx.uri.href][expressPath];
1478
- }
1479
- const method = type.toLowerCase();
1480
- const isWithBody = method === 'put' || method === 'post';
1481
- const pathPrams = {};
1482
- let queryParams = {};
1483
- let bodyObject = {};
1484
- args.forEach((param, i) => {
1485
- let currentParam = void 0;
1486
- for (let pp in methodConfig.parameters) {
1487
- let v = methodConfig.parameters[pp];
1488
- if (v.index === i) {
1489
- currentParam = v;
1490
- break;
1491
- }
1492
- }
1493
- if (currentParam.paramType === 'Path') {
1494
- pathPrams[currentParam.paramName] = param;
1495
- }
1496
- if (currentParam.paramType === 'Query') {
1497
- if (currentParam.paramName) {
1498
- const mapping = Mapping.decode(param, !ctx.isProductionMode);
1499
- if (mapping) {
1500
- rest.headers.set(`${Symbols.old.MAPPING_CONFIG_HEADER_QUERY_PARAMS}${currentParam.paramName} `, JSON.stringify(mapping));
1501
- }
1502
- queryParams[currentParam.paramName] = param;
1503
- }
1504
- else {
1505
- const mapping = Mapping.decode(param, !ctx.isProductionMode);
1506
- if (mapping) {
1507
- rest.headers.set(Symbols.old.MAPPING_CONFIG_HEADER_QUERY_PARAMS, JSON.stringify(mapping));
1508
- }
1509
- queryParams = _.cloneDeep(param);
1510
- }
1511
- }
1512
- if (currentParam.paramType === 'Header') {
1513
- if (currentParam.paramName) {
1514
- if (currentParam.paramName === Symbols.old.MDC_KEY) {
1515
- rest.headers.set(currentParam.paramName, encodeURIComponent(JSON.stringify(param)));
1516
- }
1517
- else {
1518
- rest.headers.set(currentParam.paramName, param);
1519
- }
1520
- }
1521
- else {
1522
- for (let header in param) {
1523
- rest.headers.set(header, param[header]);
1524
- }
1525
- }
1526
- }
1527
- if (currentParam.paramType === 'Cookie') {
1528
- Resource.Cookies.write(currentParam.paramName, param, currentParam.expireInSeconds);
1529
- }
1530
- if (currentParam.paramType === 'Body') {
1531
- if (currentParam.paramName) {
1532
- if (ClassHelpers.getName(bodyObject) === 'FormData') {
1533
- throw new Error(`[taon - framework] Don use param names when posting / putting FormData.
1534
- Use this:
1535
-
1536
- (@Taon.Http.Param.Body() formData: FormData) ...
1537
-
1538
-
1539
- instead
1540
-
1541
- (@Taon.Http.Param.Body('${currentParam.paramName}') formData: FormData) ...
1542
-
1543
- `);
1544
- }
1545
- const mapping = Mapping.decode(param, !ctx.isProductionMode);
1546
- if (mapping) {
1547
- rest.headers.set(`${Symbols.old.MAPPING_CONFIG_HEADER_BODY_PARAMS}${currentParam.paramName} `, JSON.stringify(mapping));
1548
- }
1549
- bodyObject[currentParam.paramName] = param;
1550
- }
1551
- else {
1552
- const mapping = Mapping.decode(param, !ctx.isProductionMode);
1553
- if (mapping) {
1554
- rest.headers.set(Symbols.old.MAPPING_CONFIG_HEADER_BODY_PARAMS, JSON.stringify(mapping));
1555
- }
1556
- bodyObject = param;
1557
- }
1558
- }
1559
- });
1560
- if (typeof bodyObject === 'object' &&
1561
- ClassHelpers.getName(bodyObject) !== 'FormData') {
1562
- let circuralFromItem = [];
1563
- bodyObject = JSON10.parse(JSON10.stringify(bodyObject, void 0, void 0, circs => {
1564
- circuralFromItem = circs;
1565
- }));
1566
- rest.headers.set(Symbols.old.CIRCURAL_OBJECTS_MAP_BODY, JSON10.stringify(circuralFromItem));
1567
- }
1568
- if (typeof queryParams === 'object') {
1569
- let circuralFromQueryParams = [];
1570
- queryParams = JSON10.parse(JSON10.stringify(queryParams, void 0, void 0, circs => {
1571
- circuralFromQueryParams = circs;
1572
- }));
1573
- rest.headers.set(Symbols.old.CIRCURAL_OBJECTS_MAP_QUERY_PARAM, JSON10.stringify(circuralFromQueryParams));
1574
- }
1575
- const httpResultObj = {
1576
- received: isWithBody
1577
- ? rest.model(pathPrams)[method](bodyObject, [queryParams])
1578
- : rest.model(pathPrams)[method]([queryParams]),
1579
- };
1580
- return httpResultObj;
1581
- };
1582
- }
1583
- }
1584
- ;
1585
- ({}); // @--end-of-file-for-module=taon lib/endpoint-context.ts
1586
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZW5kcG9pbnQtY29udGV4dC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3RtcC1saWJzLWZvci1kaXN0LXdlYnNxbC90YW9uL3Byb2plY3RzL3Rhb24vc3JjL2xpYi9lbmRwb2ludC1jb250ZXh0LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUVBLCtDQUErQztBQUcvQyxPQUFPLEVBQUUsZUFBZSxFQUFFLE1BQU0scUJBQXFCLENBQUM7QUFXdEQsT0FBTyxFQUFFLE1BQU0sSUFBSSxhQUFhLEVBQVEsTUFBTSxxQkFBcUIsQ0FBQztBQUVwRSxLQUFLO0FBQ0wsS0FBSztBQUNMLEtBQUs7QUFDTCxLQUFLO0FBQ0wsS0FBSztBQUNMLEtBQUs7QUFDTCxLQUFLO0FBQ0wsS0FBSztBQUNMLEtBQUs7QUFDTCxLQUFLO0FBQ0wsS0FBSztBQUdMLE9BQU8sRUFBRSxnQkFBZ0IsRUFBRSxNQUFNLHVEQUF1RCxDQUFDO0FBRXpGLE9BQU8sRUFBRSxPQUFPLEVBQUUsS0FBSyxFQUFFLE1BQU0saUJBQWlCLENBQUM7QUFDakQsT0FBTyxFQUFFLGlCQUFpQixFQUFFLE1BQU0saUJBQWlCLENBQUM7QUFDcEQsT0FBTyxFQUFFLE1BQU0sRUFBRSxNQUFNLFVBQVUsQ0FBQztBQUNsQyxPQUFPLEVBQUUsWUFBWSxFQUFFLE1BQU0seUJBQXlCLENBQUM7QUFDdkQsT0FBTyxFQUFFLE9BQU8sRUFBRSxNQUFNLFdBQVcsQ0FBQztBQUNwQyxPQUFPLEVBQUUsQ0FBQyxFQUFFLE9BQU8sRUFBRSxNQUFNLGlCQUFpQixDQUFDO0FBRTdDLE9BQU8sRUFBRSxlQUFlLEVBQUUsTUFBTSxxQ0FBcUMsQ0FBQztBQUV0RSxPQUFPLEVBQUUsV0FBVyxFQUFFLE1BQU0sd0JBQXdCLENBQUM7QUFDckQsT0FBTyxFQUFJLE9BQU8sRUFBSSxNQUFNLElBQUksYUFBYSxFQUFJLFFBQVEsRUFBSSxXQUFXLEdBQUcsTUFBTSxpQkFBaUIsQ0FBQyxDQUFBLEtBQUs7QUFDeEcsS0FBSztBQUNMLEtBQUs7QUFDTCxLQUFLO0FBQ0wsS0FBSztBQUVMLE9BQU8sRUFBRSxNQUFNLEVBQUUsTUFBTSxlQUFlLENBQUM7QUFFdkMsT0FBTyxFQUFFLElBQUksRUFBRSxPQUFPLEVBQUUsTUFBTSxNQUFNLENBQUM7QUFFckMsT0FBTyxFQUFFLGdCQUFnQixFQUFFLE1BQU0sc0JBQXNCLENBQUM7QUFFeEQsT0FBTyxLQUFLLE1BQU0sT0FBTyxDQUFDO0FBRTFCLE9BQU8sRUFBSSxVQUFVLEdBQWtELE1BQU0scUJBQXFCLENBQUMsQ0FBQSxLQUFLO0FBT3hHLE9BQU8sRUFBRSxHQUFHLEVBQUUsTUFBTSxPQUFPLENBQUM7QUFFNUIsT0FBTyxFQUFFLFlBQVksRUFBRSxNQUFNLDBCQUEwQixDQUFDO0FBSXhELE9BQU8sRUFBRSxtQkFBbUIsRUFBRSxNQUFNLHlCQUF5QixDQUFDO0FBRzlELE1BQU0sT0FBTyxlQUFlO0lBTTFCLE1BQU0sQ0FBQyxVQUFVLENBQUMsTUFBYztRQUU5QixJQUFJLENBQUMsTUFBTSxHQUFHLE1BQU0sQ0FBQztJQUV2QixDQUFDO0lBdUZELElBQUksa0NBQWtDO1FBQ3BDLE9BQU8sQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLGdCQUFnQixJQUFJLElBQUksQ0FBQyw4QkFBOEIsQ0FBQyxDQUFDO0lBQzFFLENBQUM7SUFpQkQsSUFBSSxjQUFjO1FBQ2hCLE9BQU8sSUFBSSxDQUFDLFFBQVEsQ0FBQyxNQUFNLENBQUM7SUFDOUIsQ0FBQztJQUNELElBQUksY0FBYztRQUNoQixPQUFPLElBQUksQ0FBQyxRQUFRLENBQUMsTUFBTSxDQUFDO0lBQzlCLENBQUM7SUFXRCxJQUFJLE9BQU87UUFDVCxJQUFJLENBQUMsQ0FBQyxRQUFRLENBQUMsSUFBSSxDQUFDLE1BQU0sRUFBRSxJQUFJLENBQUMsRUFBRSxDQUFDO1lBQ2xDLE9BQU8sQ0FBQyxDQUFFLElBQUksQ0FBQyxNQUFNLENBQUMsSUFBcUMsQ0FBQyxJQUFJLENBQUM7UUFDbkUsQ0FBQztRQUNELE9BQU8sSUFBSSxDQUFDLE1BQU0sRUFBRSxJQUFJLEtBQUssSUFBSSxDQUFDO0lBQ3BDLENBQUM7SUFFRCxJQUFJLFdBQVc7UUFDYixJQUFJLENBQUMsQ0FBQyxRQUFRLENBQUMsSUFBSSxDQUFDLE1BQU0sRUFBRSxJQUFJLENBQUMsRUFBRSxDQUFDO1lBQ2xDLE9BQU8sQ0FBQyxDQUFFLElBQUksQ0FBQyxNQUFNLENBQUMsSUFBcUMsQ0FBQyxRQUFRLENBQUM7UUFDdkUsQ0FBQztRQUNELE9BQU8sSUFBSSxDQUFDLE1BQU0sRUFBRSxJQUFJLEtBQUssSUFBSSxDQUFDO0lBQ3BDLENBQUM7SUFFRCxJQUFJLFlBQVk7UUFDZCxJQUFJLENBQUMsQ0FBQyxRQUFRLENBQUMsSUFBSSxDQUFDLE1BQU0sRUFBRSxJQUFJLENBQUMsRUFBRSxDQUFDO1lBQ2xDLE9BQU8sQ0FBQyxDQUFFLElBQUksQ0FBQyxNQUFNLENBQUMsSUFBcUMsQ0FBQyxTQUFTLENBQUM7UUFDeEUsQ0FBQztRQUNELE9BQU8sSUFBSSxDQUFDLE1BQU0sRUFBRSxJQUFJLEtBQUssSUFBSSxDQUFDO0lBQ3BDLENBQUM7SUFFRCxJQUFJLEtBQUs7UUFDUCxJQUFJLENBQUMsQ0FBQyxRQUFRLENBQUMsSUFBSSxDQUFDLE1BQU0sRUFBRSxJQUFJLENBQUMsRUFBRSxDQUFDO1lBQ2xDLE9BQU8sQ0FBQyxDQUFFLElBQUksQ0FBQyxNQUFNLENBQUMsSUFBcUMsQ0FBQyxFQUFFLENBQUM7UUFDakUsQ0FBQztRQUNELE9BQU8sSUFBSSxDQUFDLE1BQU0sRUFBRSxJQUFJLEtBQUssSUFBSSxDQUFDO0lBQ3BDLENBQUM7SUFFRCxJQUFJLGFBQWE7UUFDZixJQUFJLENBQUMsQ0FBQyxRQUFRLENBQUMsSUFBSSxDQUFDLE1BQU0sRUFBRSxJQUFJLENBQUMsRUFBRSxDQUFDO1lBQ2xDLE9BQU8sQ0FBQyxDQUFFLElBQUksQ0FBQyxNQUFNLENBQUMsSUFBcUMsQ0FBQyxVQUFVLENBQUM7UUFDekUsQ0FBQztRQUNELE9BQU8sSUFBSSxDQUFDLE1BQU0sRUFBRSxJQUFJLEtBQUss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SztRQUNMLEtBQUs7UUFDTCxLQUFLO1FBQ0wsS0FBSztRQUNMLEtBQUs7UUFDTCxLQUFLO1FBQ0wsS0FBSztRQUNMLEtBQUs7UUFDTCxLQUFLO1FBQ0wsS0FBSztRQUNMLEtBQUs7UUFDTCxLQUFLO1FBQ0wsS0FBSztRQUNMLEtBQUs7UUFDTCxLQUFLO1FBQ0wsS0FBSztRQUNMLEtBQUs7UUFDTCxLQUFLO1FBQ0wsS0FBSztRQUNMLEtBQUs7UUFDTCxLQUFLO1FBQ0wsS0FBSztRQUNMLEtBQUs7UUFDTCxLQUFLO1FBQ0wsS0FBSztRQUNMLEtBQUs7UUFDTCxLQUFLO1FBQ0wsS0FBSztRQUNMLEtBQUs7UUFDTCxLQUFLO1FBQ0wsS0FBSztRQUNMLEtBQUs7UUFDTCxLQUFLO1FBQ0wsS0FBSztRQUNMLEtBQUs7UUFDTCxLQUFLO1FBQ0wsS0FBSztRQUNMLEtBQUs7UUFDTCxLQUFLO1FBQ0wsS0FBSztRQUNMLEtBQUs7UUFDTCxLQUFLO1FBQ0wsS0FBSztRQUNMLEtBQUs7UUFDTCxLQUFLO1FBQ0wsS0FBSztRQUNMLEtBQUs7UUFDTCxLQUFLO1FBQ0wsS0FBSztRQUNMLEtBQUs7UUFDTCxLQUFLO1FBQ0wsS0FBSztRQUNMLEtBQUs7UUFDTCxLQUFLO1FBQ0wsS0FBSztRQUNMLEtBQUs7UUFDTCxLQUFLO1FBQ0wsS0FBSztRQUNMLEtBQUs7UUFDTCxLQUFLO1FBQ0wsS0FBSztRQUNMLEtBQUs7UUFDTCxLQUFLO1FBQ0wsS0FBSztRQUNMLEtBQUs7UUFDTCxLQUFLO1FBQ0wsS0FBSztRQUNMLEtBQUs7UUFDTCxLQUFLO1FBQ0wsS0FBSztRQUNMLEtBQUs7UUFDTCxLQUFLO1FBQ0wsS0FBSztRQUNMLEtBQUs7UUFDTCxLQUFLO1FBQ0wsS0FBSztRQUNMLEtBQUs7UUFDTCxLQUFLO1FBQ0wsS0FBSztRQUNMLEtBQUs7UUFDTCxLQUFLO1FBQ0wsS0FBSztRQUNMLEtBQUs7SUFFSCxDQUFDO0lBSU8sVUFBVSxDQUVoQixJQUFpQyxFQUNqQyxZQUFpQyxFQUNqQyxXQUEyQyxFQUMzQyxXQUFtQixFQUNuQixNQUFn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SztZQUNMLEtBQUs7WUFDTCxLQUFLO1lBQ0wsS0FBSztZQUNMLEtBQUs7WUFDTCxLQUFLO1lBQ0wsS0FBSztZQUNMLEtBQUs7WUFDTCxLQUFLO1lBQ0wsS0FBSztZQUNMLEtBQUs7WUFDTCxLQUFLO1lBQ0wsS0FBSztZQUNMLEtBQUs7WUFDTCxLQUFLO1lBQ0wsS0FBSztZQUNMLEtBQUs7WUFDTCxLQUFLO1lBQ0wsS0FBSztZQUNMLEtBQUs7WUFDTCxLQUFLO1lBQ0wsS0FBSztZQUNMLEtBQUs7WUFDTCxLQUFLO1lBQ0wsS0FBSztZQUNMLEtBQUs7WUFDTCxLQUFLO1lBQ0wsS0FBSztZQUNMLEtBQUs7WUFDTCxLQUFLO1lBQ0wsS0FBSztZQUNMLEtBQUs7WUFDTCxLQUFLO1lBQ0wsS0FBSztZQUNMLEtBQUs7WUFDTCxLQUFLO1lBQ0wsS0FBSztZQUNMLEtBQUs7WUFDTCxLQUFLO1lBQ0wsS0FBSztZQUNMLEtBQUs7WUFDTCxLQUFLO1lBQ0wsS0FBSztZQUNMLEtBQUs7WUFDTCxLQUFLO1lBQ0wsS0FBSztZQUNMLEtBQUs7WUFDTCxLQUFLO1lBQ0wsS0FBSztZQUNMLEtBQUs7WUFDTCxLQUFLO1lBQ0wsS0FBSztZQUNMLEtBQUs7WUFDTCxLQUFLO1lBQ0wsS0FBSztZQUNMLEtBQUs7WUFDTCxLQUFLO1lBQ0wsS0FBSztZQUNMLEtBQUs7WUFDTCxLQUFLO1lBQ0wsS0FBSztZQUNMLEtBQUs7WUFDTCxLQUFLO1lBQ0wsS0FBSztZQUNMLEtBQUs7WUFDTCxLQUFLO1lBQ0wsS0FBSztZQUNMLEtBQUs7WUFDTCxLQUFLO1lBQ0wsS0FBSztZQUNMLEtBQUs7WUFDTCxLQUFLO1lBQ0wsS0FBSztZQUNMLEtBQUs7WUFDTCxLQUFLO1lBQ0wsS0FBSztZQUNMLEtBQUs7WUFDTCxLQUFLO1lBQ0wsS0FBSztZQUNMLEtBQUs7WUFDTCxLQUFLO1lBQ0wsS0FBSztZQUNMLEtBQUs7WUFDTCxLQUFLO1lBQ0wsS0FBSztZQUNMLEtBQUs7WUFDTCxLQUFLO1lBQ0wsS0FBSztZQUNMLEtBQUs7WUFDTCxLQUFLO1lBQ0wsS0FBSztZQUNMLEtBQUs7WUFDTCxLQUFLO1lBQ0wsS0FBSztZQUNMLEtBQUs7WUFDTCxLQUFLO1lBQ0wsS0FBSztZQUNMLEtBQUs7WUFDTCxLQUFLO1lBQ0wsS0FBSztZQUNMLEtBQUs7WUFDTCxLQUFLO1lBQ0wsS0FBSztZQUNMLEtBQUs7WUFDTCxLQUFLO1lBQ0wsS0FBSztZQUNMLEtBQUs7WUFDTCxLQUFLO1lBQ0wsS0FBSztZQUNMLEtBQUs7WUFDTCxLQUFLO1lBQ0wsS0FBSztZQUNMLEtBQUs7WUFDTCxLQUFLO1lBQ0wsS0FBSztZQUNMLEtBQUs7WUFDTCxLQUFLO1lBQ0wsS0FBSztZQUNMLEtBQUs7WUFDTCxLQUFLO1lBQ0wsS0FBSztZQUNMLEtBQUs7WUFDTCxLQUFLO1lBQ0wsS0FBSztZQUNMLEtBQUs7WUFDTCxLQUFLO1lBQ0wsS0FBSztZQUNMLEtBQUs7WUFDTCxLQUFLO1lBQ0wsS0FBSztZQUNMLEtBQUs7WUFDTCxLQUFLO1lBQ0wsS0FBSztZQUNMLEtBQUs7WUFDTCxLQUFLO1lBQ0wsS0FBSztZQUNMLEtBQUs7WUFDTCxLQUFLO1lBQ0wsS0FBSztZQUNMLEtBQUs7WUFDTCxLQUFLO1lBQ0wsS0FBSztZQUNMLEtBQUs7WUFDTCxLQUFLO1lBQ0wsS0FBSztZQUNMLEtBQUs7WUFDTCxLQUFLO1lBQ0wsS0FBSztZQUNMLEtBQUs7WUFDTCxLQUFLO1lBQ0wsS0FBSztZQUNMLEtBQUs7WUFDTCxLQUFLO1lBQ0wsS0FBSztZQUNMLEtBQUs7WUFDTCxLQUFLO1lBQ0wsS0FBSztZQUNMLEtBQUs7WUFDTCxLQUFLO1lBQ0wsS0FBSztZQUNMLEtBQUs7WUFDTCxLQUFLO1lBQ0wsS0FBSztZQUNMLEtBQUs7WUFDTCxLQUFLO1lBQ0wsS0FBSztZQUNMLEtBQUs7WUFDTCxLQUFLO1lBQ0wsS0FBSztRQUVELENBQUM7UUFFRCxPQUFPO1lBQ0wsU0FBUyxFQUFFLFdBQVc7WUFDdEIsTUFBTSxFQUFFLFlBQVksQ0FBQyxJQUFJO1NBQzFCLENBQUM7SUFDSixDQUFDO0lBSUQ7O09BRUc7SUFDSyxVQUFVLENBRWhC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QUNsQyxDQUFDLENBQUMsQ0FDSCxDQUFDO2dCQUVGLElBQUksQ0FBQyxPQUFPLENBQUMsR0FBRyxDQUNkLE9BQU8sQ0FBQyxHQUFHLENBQUMsZ0NBQWdDLEVBQzVDLE1BQU0sQ0FBQyxTQUFTLENBQUMsdUJBQXVCLENBQUMsQ0FDMUMsQ0FBQztZQUNKLENBQUM7WUFHRCxNQUFNLGFBQWEsR0FBRztnQkFDcEIsUUFBUSxFQUFFLFVBQVU7b0JBQ2xCLENBQUMsQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLFNBQVMsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxDQUFDLFVBQVUsRUFBRSxDQUFDLFdBQVcsQ0FBQyxDQUFDO29CQUMxRCxDQUFDLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxTQUFTLENBQUMsQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDLFdBQVcsQ0FBQyxDQUFDO2FBQ2pELENBQUM7WUFDRixPQUFPLGFBQWEsQ0FBQztRQUN2QixDQUFDLENBQUM7SUFFSixDQUFDO0NBRUY7QUFFQSxDQUFDO0FBQUEsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDLHlEQUF5RCIsInNvdXJjZXNDb250ZW50IjpbIlxuXG4vKiBlc2xpbnQtZGlzYWJsZSBAdHlwZXNjcmlwdC1lc2xpbnQvdHlwZWRlZiAqL1xuXG5cbmltcG9ydCB7IEV2ZW50U3Vic2NyaWJlciB9IGZyb20gJ3Rhb24tdHlwZW9ybS93ZWJzcWwnO1xuaW1wb3J0IHR5cGUge1xuICBUcmFuc2FjdGlvblJvbGxiYWNrRXZlbnQsXG4gIFRyYW5zYWN0aW9uQ29tbWl0RXZlbnQsXG4gIFRyYW5zYWN0aW9uU3RhcnRFdmVudCxcbiAgUmVjb3ZlckV2ZW50LFxuICBTb2Z0UmVtb3ZlRXZlbnQsXG4gIFJlbW92ZUV2ZW50LFxuICBVcGRhdGVFdmVudCxcbiAgSW5zZXJ0RXZlbnQsXG59IGZyb20gJ3Rhb24tdHlwZW9ybSc7XG5pbXBvcnQgeyBFbnRpdHkgYXMgVHlwZW9ybUVudGl0eSwgVHJlZSB9IGZyb20gJ3Rhb24tdHlwZW9ybS93ZWJzcWwnO1xuXG4vKiAqL1xuLyogKi9cbi8qICovXG4vKiAqL1xuLyogKi9cbi8qICovXG4vKiAqL1xuLyogKi9cbi8qICovXG4vKiAqL1xuLyogKi9cbiAgXG5cbmltcG9ydCB7IFRhb25BZG1pblNlcnZpY2UgfSBmcm9tICcuL3VpL3Rhb24tYWRtaW4tbW9kZS1jb25maWd1cmF0aW9uL3Rhb24tYWRtaW4uc2VydmljZSc7XG5cbmltcG9ydCB7IFV0aWxzT3MsIFV0aWxzIH0gZnJvbSAndG5wLWNvcmUvd2Vic3FsJztcbmltcG9ydCB7IGNyb3NzUGxhdGZvcm1QYXRoIH0gZnJvbSAndG5wLWNvcmUvd2Vic3FsJztcbmltcG9ydCB7IE1vZGVscyB9IGZyb20gJy4vbW9kZWxzJztcbmltcG9ydCB7IENsYXNzSGVscGVycyB9IGZyb20gJy4vaGVscGVycy9jbGFzcy1oZWxwZXJzJztcbmltcG9ydCB7IFN5bWJvbHMgfSBmcm9tICcuL3N5bWJvbHMnO1xuaW1wb3J0IHsgXywgSGVscGVycyB9IGZyb20gJ3RucC1jb3JlL3dlYnNxbCc7XG5pbXBvcnQgdHlwZSB7IGNyZWF0ZUNvbnRleHQgfSBmcm9tICcuL2NyZWF0ZS1jb250ZXh0JztcbmltcG9ydCB7IERJVGFvbkNvbnRhaW5lciB9IGZyb20gJy4vZGVwZW5kZW5jeS1pbmplY3Rpb24vZGktY29udGFpbmVyJztcbmltcG9ydCB7IFRhb25Db250cm9sbGVyT3B0aW9ucyB9IGZyb20gJy4vZGVjb3JhdG9ycy9jbGFzc2VzL2NvbnRyb2xsZXItZGVjb3JhdG9yJztcbmltcG9ydCB7IFRhb25IZWxwZXJzIH0gZnJvbSAnLi9oZWxwZXJzL3Rhb24taGVscGVycyc7XG5pbXBvcnQgeyAgIE1hcHBpbmcsICAgTW9kZWxzIGFzIE1vZGVsc05nMlJlc3QsICAgUmVzb3VyY2UsICAgUmVzdEhlYWRlcnMsIH0gZnJvbSAnbmcyLXJlc3Qvd2Vic3FsJzsvKiAqL1xuLyogKi9cbi8qICovXG4vKiAqL1xuLyogKi9cblxuaW1wb3J0IHsgSlNPTjEwIH0gZnJvbSAnanNvbjEwL3dlYnNxbCc7XG5pbXBvcnQgeyBwYXRoIH0gZnJvbSAndG5wLWNvcmUvd2Vic3FsJztcbmltcG9ydCB7IGZyb20sIFN1YmplY3QgfSBmcm9tICdyeGpzJztcbmltcG9ydCB7IEVudGl0eVByb2Nlc3MgfSBmcm9tICcuL2VudGl0eS1wcm9jZXNzJztcbmltcG9ydCB7IGdldFJlc3BvbnNlVmFsdWUgfSBmcm9tICcuL2dldC1yZXNwb25zZS12YWx1ZSc7XG5pbXBvcnQgdHlwZSB7IEFwcGxpY2F0aW9uIH0gZnJvbSAnZXhwcmVzcyc7XG5pbXBvcnQgYXhpb3MgZnJvbSAnYXhpb3MnO1xuaW1wb3J0IHR5cGUgeyBOZ1pvbmUgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7ICAgRGF0YVNvdXJjZSwgICBEYXRhU291cmNlT3B0aW9ucywgICBnZXRNZXRhZGF0YUFyZ3NTdG9yYWdlLCB9IGZyb20gJ3Rhb24tdHlwZW9ybS93ZWJzcWwnOy8qICovXG4vKiAqL1xuLyogKi9cbi8qICovXG5cbmltcG9ydCB7IFRhb25FbnRpdHlPcHRpb25zIH0gZnJvbSAnLi9kZWNvcmF0b3JzL2NsYXNzZXMvZW50aXR5LWRlY29yYXRvcic7XG5pbXBvcnQgdHlwZSB7IFNlcnZlciB9IGZyb20gJ2h0dHAnO1xuaW1wb3J0IHsgRU5WIH0gZnJvbSAnLi9lbnYnO1xuaW1wb3J0IHR5cGUgeyBCYXNlQ2xhc3MgfSBmcm9tICcuL2Jhc2UtY2xhc3Nlcy9iYXNlLWNsYXNzJztcbmltcG9ydCB7IFJlYWx0aW1lQ29yZSB9IGZyb20gJy4vcmVhbHRpbWUvcmVhbHRpbWUtY29yZSc7XG5pbXBvcnQgeyBUYW9uU3Vic2NyaWJlck9wdGlvbnMgfSBmcm9tICcuL2RlY29yYXRvcnMvY2xhc3Nlcy9zdWJzY3JpYmVyLWRlY29yYXRvcic7XG5pbXBvcnQgeyBCYXNlU3Vic2NyaWJlckZvckVudGl0eSB9IGZyb20gJy4vYmFzZS1jbGFzc2VzL2Jhc2Utc3Vic2NyaWJlci1mb3ItZW50aXR5JztcbmltcG9ydCB0eXBlIHsgQmFzZU1pZ3JhdGlvbiB9IGZyb20gJy4vYmFzZS1jbGFzc2VzL2Jhc2UtbWlncmF0aW9uJztcbmltcG9ydCB7IENvbnRleHREYk1pZ3JhdGlvbnMgfSBmcm9tICcuL2NvbnRleHQtZGItbWlncmF0aW9ucyc7XG5cblxuZXhwb3J0IGNsYXNzIEVuZHBvaW50Q29udGV4dCB7XG5cblxuXG4gIHByaXZhdGUgc3RhdGljIG5nWm9uZTogTmdab25lO1xuXG4gIHN0YXRpYyBpbml0Tmdab25lKG5nWm9uZTogTmdab25lKSB7XG5cbiAgICB0aGlzLm5nWm9uZSA9IG5nWm9uZTtcblxuICB9XG5cblxuXG5cblxuXG5cblxuXG5cblxuXG4gIGRpc2FibGVkUmVhbHRpbWU6IGJvb2xlYW4gPSBmYWxzZTtcbiAgLyoqXG4gICAqIGNoZWNrIHdoZXRoZXIgY29udGV4dCBpcyBpbml0ZWRcbiAgICogKHdpdGggaW5pdCgpIGZ1bmN0aW9uIClcbiAgICovXG4gIHB1YmxpYyBpbml0ZWQ6IGJvb2xlYW4gPSBmYWxzZTtcblxuXG4gIHJlYWRvbmx5IGRiTWlncmF0aW9ucyA9IG5ldyBDb250ZXh0RGJNaWdyYXRpb25zKHRoaXMpO1xuXG4gIHByaXZhdGUgcmVhZG9ubHkgbG9jYWxJbnN0YWNlT2JqU3ltYm9sID0gU3ltYm9sKCdsb2NhbEluc3RhY2VPYmpTeW1ib2wnKTtcblxuXG4gIC8qKlxuICAgKiBhbGwgaW5zdGFuY2VzIG9mIGNsYXNzZXMgZnJvbSBjb250ZXh0XG4gICAqIGtleSBpcyBjbGFzcyBuYW1lXG4gICAqL1xuICBwdWJsaWMgcmVhZG9ubHkgYWxsQ2xhc3Nlc0luc3RhbmNlcyA9IHt9O1xuXG5cblxuICBwcml2YXRlIHJlYWRvbmx5IGNsYXNzSW5zdGFuY2VzQnlOYW1lT2JqID0ge307XG5cblxuXG4gIHByaXZhdGUgcmVhZG9ubHkgb2JqV2l0aENsYXNzZXNJbnN0YW5jZXNBcnIgPSB7fTtcblxuXG5cbiAgcHVibGljIHJlYWRvbmx5IGFjdGl2ZVJvdXRlczoge1xuICAgIHJvdXRlUGF0aDogc3RyaW5nO1xuICAgIG1ldGhvZDogTW9kZWxzLkh0dHAuUmVzdC5IdHRwTWV0aG9kO1xuICB9W10gPSBbXTtcblxuXG4gIHB1YmxpYyByZWFkb25seSBza2lwV3JpdGluZ1NlcnZlclJvdXRlczogYm9vbGVhbiA9IGZhbHNlO1xuXG5cbiAgcHJpdmF0ZSBpbmplY3RhYmxlVHlwZXNmcm9tQ29udGV4dHMgPSBbXG4gICAgTW9kZWxzLkNsYXNzVHlwZS5DT05UUk9MTEVSLFxuICAgIE1vZGVscy5DbGFzc1R5cGUuUFJPVklERVIsXG4gICAgTW9kZWxzLkNsYXNzVHlwZS5SRVBPU0lUT1JZLFxuICAgIE1vZGVscy5DbGFzc1R5cGUuU1VCU0NSSUJFUixcbiAgICBNb2RlbHMuQ2xhc3NUeXBlLk1JR1JBVElPTixcbiAgXTtcblxuXG4gIHByaXZhdGUgYWxsVHlwZXNmcm9tQ29udGV4dHMgPSBbXG4gICAgLi4udGhpcy5pbmplY3RhYmxlVHlwZXNmcm9tQ29udGV4dHMsXG4gICAgTW9kZWxzLkNsYXNzVHlwZS5FTlRJVFksXG4gIF07XG5cblxuXG5cbiAgcHVibGljIGV4cHJlc3NBcHA6IEFwcGxpY2F0aW9uID0ge30gYXMgYW55O1xuXG5cblxuICBwdWJsaWMgc2VydmVyVGNwVWRwOiBTZXJ2ZXI7XG5cblxuXG4gIGRhdGFiYXNlQ29uZmlnPzogTW9kZWxzLkRhdGFiYXNlQ29uZmlnVHlwZU9ybTtcblxuXG5cbiAgbW9kZTogTW9kZWxzLkZyYW1ld29ya01vZGU7XG5cblxuXG4gIHJlYWRvbmx5IG9ubHlNaWdyYXRpb25SdW4/OiBib29sZWFuID0gZmFsc2U7XG4gIHJlYWRvbmx5IG9ubHlNaWdyYXRpb25SZXZlcnRUb1RpbWVzdGFtcD86IG51bWJlciA9IHVuZGVmaW5lZDtcblxuICBnZXQgaXNSdW5PclJldmVydE9ubHlNaWdyYXRpb25BcHBTdGFydCgpOiBib29sZWFuIHtcbiAgICByZXR1cm4gISEodGhpcy5vbmx5TWlncmF0aW9uUnVuIHx8IHRoaXMub25seU1pZ3JhdGlvblJldmVydFRvVGltZXN0YW1wKTtcbiAgfVxuXG5cblxuICBzZXNzaW9uPzogTW9kZWxzLklTZXNzaW9uO1xuXG5cblxuICBwdWJsaWMgY29ubmVjdGlvbjogRGF0YVNvdXJjZTtcblxuXG5cbiAgcHJpdmF0ZSBlbnRpdGllc1RyaWdnZXJzID0ge307XG5cblxuXG4gIHByaXZhdGUgcmVhbHRpbWU6IFJlYWx0aW1lQ29yZTtcbiAgZ2V0IHJlYWx0aW1lQ2xpZW50KCkge1xuICAgIHJldHVybiB0aGlzLnJlYWx0aW1lLmNsaWVudDtcbiAgfVxuICBnZXQgcmVhbHRpbWVTZXJ2ZXIoKSB7XG4gICAgcmV0dXJuIHRoaXMucmVhbHRpbWUuc2VydmVyO1xuICB9XG5cblxuXG4gIC8qKlxuICAgKiBhdmFpbGFibGUgYWZ0ZXIgaW5pdCgpXG4gICAqL1xuICBwdWJsaWMgY29uZmlnOiBNb2RlbHMuQ29udGV4dE9wdGlvbnM8YW55LCBhbnksIGFueSwgYW55LCBhbnksIGFueSwgYW55PjtcblxuXG5cbiAgZ2V0IGxvZ0h0dHAoKTogYm9vbGVhbiB7XG4gICAgaWYgKF8uaXNPYmplY3QodGhpcy5jb25maWc/LmxvZ3MpKSB7XG4gICAgICByZXR1cm4gISEodGhpcy5jb25maWcubG9ncyBhcyBNb2RlbHMuQ29ubmVjdGlvbk9wdGlvbnNMb2dzKS5odHRwO1xuICAgIH1cbiAgICByZXR1cm4gdGhpcy5jb25maWc/LmxvZ3MgPT09IHRydWU7XG4gIH1cblxuICBnZXQgbG9nUmVhbHRpbWUoKTogYm9vbGVhbiB7XG4gICAgaWYgKF8uaXNPYmplY3QodGhpcy5jb25maWc/LmxvZ3MpKSB7XG4gICAgICByZXR1cm4gISEodGhpcy5jb25maWcubG9ncyBhcyBNb2RlbHMuQ29ubmVjdGlvbk9wdGlvbnNMb2dzKS5yZWFsdGltZTtcbiAgICB9XG4gICAgcmV0dXJuIHRoaXMuY29uZmlnPy5sb2dzID09PSB0cnVlO1xuICB9XG5cbiAgZ2V0IGxvZ0ZyYW1ld29yaygpOiBib29sZWFuIHtcbiAgICBpZiAoXy5pc09iamVjdCh0aGlzLmNvbmZpZz8ubG9ncykpIHtcbiAgICAgIHJldHVybiAhISh0aGlzLmNvbmZpZy5sb2dzIGFzIE1vZGVscy5Db25uZWN0aW9uT3B0aW9uc0xvZ3MpLmZyYW1ld29yaztcbiAgICB9XG4gICAgcmV0dXJuIHRoaXMuY29uZmlnPy5sb2dzID09PSB0cnVlO1xuICB9XG5cbiAgZ2V0IGxvZ0RiKCk6IGJvb2xlYW4ge1xuICAgIGlmIChfLmlzT2JqZWN0KHRoaXMuY29uZmlnPy5sb2dzKSkge1xuICAgICAgcmV0dXJuICEhKHRoaXMuY29uZmlnLmxvZ3MgYXMgTW9kZWxzLkNvbm5lY3Rpb25PcHRpb25zTG9ncykuZGI7XG4gICAgfVxuICAgIHJldHVybiB0aGlzLmNvbmZpZz8ubG9ncyA9PT0gdHJ1ZTtcbiAgfVxuXG4gIGdldCBsb2dNaWdyYXRpb25zKCk6IGJvb2xlYW4ge1xuICAgIGlmIChfLmlzT2JqZWN0KHRoaXMuY29uZmlnPy5sb2dzKSkge1xuICAgICAgcmV0dXJuICEhKHRoaXMuY29uZmlnLmxvZ3MgYXMgTW9kZWxzLkNvbm5lY3Rpb25PcHRpb25zTG9ncykubWlncmF0aW9ucztcbiAgICB9XG4gICAgcmV0dXJuIHRoaXMuY29uZmlnPy5sb2dzID09PSB0cnVlO1xuICB9XG5cblxuXG5cblxuICBjb25zdHJ1Y3RvcihcbiAgICBwcml2YXRlIG9yaWdpbmFsQ29uZmlnOiBNb2RlbHMuQ29udGV4dE9wdGlvbnM8XG4gICAgICBhbnksXG4gICAgICBhbnksXG4gICAgICBhbnksXG4gICAgICBhbnksXG4gICAgICBhbnksXG4gICAgICBhbnksXG4gICAgICBhbnlcbiAgICA+LFxuICAgIHByaXZhdGUgY29uZmlnRm46IChcbiAgICAgIGVudjogYW55LFxuICAgICkgPT4gTW9kZWxzLkNvbnRleHRPcHRpb25zPGFueSwgYW55LCBhbnksIGFueSwgYW55LCBhbnksIGFueT4sXG4gICkge31cblxuXG5cbiAgcHVibGljIGFzeW5jIGluaXQob3B0aW9ucz86IHtcbiAgICBpbml0RnJvbVJlY3J1c2l2ZUNvbnRleHRSZXNvdmxlPzogYm9vbGVhbjtcbiAgICBvdmVycmlkZUhvc3Q/OiBzdHJpbmcgfCBudWxsO1xuICAgIG92ZXJyaWRlUmVtb3RlSG9zdD86IHN0cmluZyB8IG51bGw7XG4gICAgb25seU1pZ3JhdGlvblJ1bj86IGJvb2xlYW47XG4gICAgb25seU1pZ3JhdGlvblJldmVydFRvVGltZXN0YW1wPzogbnVtYmVyO1xuICB9KSB7XG4gICAgY29uc3Qge1xuICAgICAgaW5pdEZyb21SZWNydXNpdmVDb250ZXh0UmVzb3ZsZSxcbiAgICAgIG92ZXJyaWRlSG9zdCxcbiAgICAgIG92ZXJyaWRlUmVtb3RlSG9zdCxcbiAgICAgIG9ubHlNaWdyYXRpb25SdW4sXG4gICAgICBvbmx5TWlncmF0aW9uUmV2ZXJ0VG9UaW1lc3RhbXAsXG4gICAgfSA9IG9wdGlvbnMgfHwge307IC8vIFRPRE8gdXNlIGl0ID9cblxuICAgIHRoaXMuaW5pdGVkID0gdHJ1ZTtcbiAgICAvLyBAdHMtaWdub3JlXG4gICAgdGhpcy5vbmx5TWlncmF0aW9uUnVuID0gb25seU1pZ3JhdGlvblJ1bjtcbiAgICAvLyBAdHMtaWdub3JlXG4gICAgdGhpcy5vbmx5TWlncmF0aW9uUmV2ZXJ0VG9UaW1lc3RhbXAgPSBvbmx5TWlncmF0aW9uUmV2ZXJ0VG9UaW1lc3RhbXA7XG4gICAgdGhpcy5jb25maWcgPSB0aGlzLmNvbmZpZ0ZuKEVOVik7XG4gICAgaWYgKF8uaXNPYmplY3QodGhpcy5jb25maWcuZGF0YWJhc2UpKSB7XG4gICAgICB0aGlzLmNvbmZpZy5kYXRhYmFzZSA9IE1vZGVscy5EYXRhYmFzZUNvbmZpZy5mcm9tKFxuICAgICAgICB0aGlzLmNvbmZpZy5kYXRhYmFzZSBhcyBNb2RlbHMuRGF0YWJhc2VDb25maWcsXG4gICAgICApLmRhdGFiYXNlQ29uZmlnVHlwZU9STTtcbiAgICB9XG4gICAgaWYgKG92ZXJyaWRlSG9zdCAmJiBvdmVycmlkZVJlbW90ZUhvc3QpIHtcbiAgICAgIEhlbHBlcnMudGhyb3coXG4gICAgICAgIGBbdGFvbi1jb25maWddIFlvdSBjYW4ndCBoYXZlIG92ZXJyaWRlSG9zdCBhbmQgb3ZlcnJpZGVSZW1vdGVIb3N0IGF0IHRoZSBzYW1lIHRpbWVgLFxuICAgICAgKTtcbiAgICB9XG5cbiAgICB0aGlzLmNvbmZpZy5ob3N0ID0gIV8uaXNVbmRlZmluZWQob3ZlcnJpZGVIb3N0KVxuICAgICAgPyBvdmVycmlkZUhvc3RcbiAgICAgIDogdGhpcy5jb25maWcuaG9zdDtcbiAgICB0aGlzLmNvbmZpZy5yZW1vdGVIb3N0ID0gIV8uaXNVbmRlZmluZWQob3ZlcnJpZGVSZW1vdGVIb3N0KVxuICAgICAgPyBvdmVycmlkZVJlbW90ZUhvc3RcbiAgICAgIDogdGhpcy5jb25maWcucmVtb3RlSG9zdDtcblxuICAgIHRoaXMuY29uZmlnLmhvc3QgPSB0aGlzLmhvc3QgPT09IG51bGwgPyB2b2lkIDAgOiB0aGlzLmhvc3Q7XG4gICAgdGhpcy5jb25maWcucmVtb3RlSG9zdCA9XG4gICAgICB0aGlzLnJlbW90ZUhvc3QgPT09IG51bGwgPyB2b2lkIDAgOiB0aGlzLnJlbW90ZUhvc3Q7XG5cbiAgICBpZiAoXG4gICAgICB0aGlzLmNvbmZpZy5ob3N0ICYmXG4gICAgICAhdGhpcy5jb25maWcuaG9zdC5zdGFydHNXaXRoKCdodHRwOi8vJykgJiZcbiAgICAgICF0aGlzLmNvbmZpZy5ob3N0LnN0YXJ0c1dpdGgoJ2h0dHBzOi8vJylcbiAgICApIHtcbiAgICAgIEhlbHBlcnMudGhyb3coXG4gICAgICAgIGBbdGFvbi1jb25maWddIFlvdXIgJ2hvc3QnIG11c3Qgc3RhcnQgd2l0aCBodHRwOi8vIG9yIGh0dHBzOi8vYCxcbiAgICAgICk7XG4gICAgfVxuXG4gICAgaWYgKF8uaXNVbmRlZmluZWQodGhpcy5jb25maWcudXNlSXBjV2hlbkVsZWN0cm9uKSkge1xuICAgICAgdGhpcy5jb25maWcudXNlSXBjV2hlbkVsZWN0cm9uID0gdHJ1ZTtcbiAgICB9XG5cbiAgICBpZiAoXG4gICAgICB0aGlzLmNvbmZpZy5yZW1vdGVIb3N0ICYmXG4gICAgICAhdGhpcy5jb25maWcucmVtb3RlSG9zdC5zdGFydHNXaXRoKCdodHRwOi8vJykgJiZcbiAgICAgICF0aGlzLmNvbmZpZy5yZW1vdGVIb3N0LnN0YXJ0c1dpdGgoJ2h0dHBzOi8vJylcbiAgICApIHtcbiAgICAgIEhlbHBlcnMudGhyb3coXG4gICAgICAgIGBbdGFvbi1jb25maWddIFlvdXIgJ3JlbW90ZUhvc3QnIG11c3Qgc3RhcnQgd2l0aCBodHRwOi8vIG9yIGh0dHBzOi8vYCxcbiAgICAgICk7XG4gICAgfVxuXG5cbiAgICAvL0B0cy1leHBlY3QtZXJyb3Igb3ZlcnJpZGluZyByZWFkb25seVxuICAgIHRoaXMuc2tpcFdyaXRpbmdTZXJ2ZXJSb3V0ZXMgPSBfLmlzQm9vbGVhbihcbiAgICAgIHRoaXMuY29uZmlnLnNraXBXcml0aW5nU2VydmVyUm91dGVzLFxuICAgIClcbiAgICAgID8gdGhpcy5jb25maWcuc2tpcFdyaXRpbmdTZXJ2ZXJSb3V0ZXNcbiAgICAgIDogZmFsc2U7XG5cblxuXG4gICAgaWYgKHRoaXMuY29uZmlnLmhvc3QpIHtcbiAgICAgIHRoaXMubW9kZSA9ICdiYWNrZW5kLWZyb250ZW5kKHRjcCt1ZHApJztcblxuICAgICAgdGhpcy5tb2RlID0gJ2JhY2tlbmQtZnJvbnRlbmQod2Vic3FsKSc7XG5cbiAgICB9XG5cbiAgICBpZiAodGhpcy5jb25maWcucmVtb3RlSG9zdCkge1xuICAgICAgaWYgKHRoaXMuY29uZmlnLmhvc3QpIHtcbiAgICAgICAgSGVscGVycy50aHJvdyhcbiAgICAgICAgICBgW3Rhb25dIFlvdSBjYW4ndCBoYXZlIHJlbW90ZUhvc3QgYW5kIGhvc3QgYXQgdGhlIHNhbWUgdGltZWAsXG4gICAgICAgICk7XG4gICAgICB9XG4gICAgICB0aGlzLm1vZGUgPSAncmVtb3RlLWJhY2tlbmQodGNwK3VkcCknO1xuICAgIH1cblxuICAgIGlmICh0aGlzLmNvbmZpZy51c2VJcGNXaGVuRWxlY3Ryb24gJiYgSGVscGVycy5pc0VsZWN0cm9uKSB7XG4gICAgICBpZiAoSGVscGVycy5pc1dlYlNRTCkge1xuICAgICAgICB0aGlzLm1vZGUgPSAnYmFja2VuZC1mcm9udGVuZCh3ZWJzcWwtZWxlY3Ryb24pJztcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHRoaXMubW9kZSA9ICdiYWNrZW5kLWZyb250ZW5kKGlwYy1lbGVjdHJvbiknO1xuICAgICAgfVxuICAgIH1cblxuICAgIGlmICghdGhpcy5tb2RlICYmICF0aGlzLmNvbmZpZy5hYnN0cmFjdCkge1xuICAgICAgSGVscGVycy5lcnJvcihcbiAgICAgICAgYFt0YW9uXSBDb250ZXh0IFwiJHt0aGlzLmNvbnRleHROYW1lfVwiOiBZb3UgbmVlZCB0byBwcm92aWRlIGhvc3Qgb3IgcmVtb3RlSG9zdCBvciB1c2VJcGNXaGVuRWxlY3Ryb25gLFxuICAgICAgICBmYWxzZSxcbiAgICAgICAgdHJ1ZSxcbiAgICAgICk7XG4vKiAqL1xuLyogKi9cbiAgXG4gICAgfVxuXG5cblxuICAgIGlmICh0aGlzLmNvbmZpZy5kYXRhYmFzZSA9PT0gdHJ1ZSkge1xuICAgICAgdGhpcy5kYXRhYmFzZUNvbmZpZyA9IHRoaXMuZ2V0QXV0b0dlbmVyYXRlZENvbmZpZygpO1xuICAgIH0gZWxzZSBpZiAoXy5pc09iamVjdCh0aGlzLmNvbmZpZy5kYXRhYmFzZSkpIHtcbiAgICAgIHRoaXMuZGF0YWJhc2VDb25maWcgPSBfLm1lcmdlKFxuICAgICAgICB0aGlzLmdldEF1dG9HZW5lcmF0ZWRDb25maWcoKSxcbiAgICAgICAgXy5jbG9uZURlZXAodGhpcy5jb25maWcuZGF0YWJhc2UpLFxuICAgICAgKSBhcyBNb2RlbHMuRGF0YWJhc2VDb25maWdUeXBlT3JtO1xuICAgIH1cblxuXG5cbiAgICBpZiAodGhpcy5jb25maWcuc2Vzc2lvbikge1xuICAgICAgdGhpcy5zZXNzaW9uID0gXy5jbG9uZURlZXAodGhpcy5jb25maWcuc2Vzc2lvbik7XG4gICAgICBjb25zdCBvbmVIb3VyID0gMTAwMCAqIDYwICogNjAgKiAxOyAvLyAyNDtcbiAgICAgIGlmICghdGhpcy5zZXNzaW9uLmNvb2tpZU1heEFnZSkge1xuICAgICAgICB0aGlzLnNlc3Npb24uY29va2llTWF4QWdlID0gb25lSG91cjtcbiAgICAgIH1cblxuICAgICAgYXhpb3MuZGVmYXVsdHMud2l0aENyZWRlbnRpYWxzID0gdHJ1ZTtcbiAgICB9XG5cblxuXG4gICAgdGhpcy5jb25maWcuY29udGV4dHMgPSB0aGlzLmNvbmZpZy5jb250ZXh0cyB8fCB7fTtcbiAgICB0aGlzLmNvbmZpZy5lbnRpdGllcyA9IHRoaXMuY29uZmlnLmVudGl0aWVzIHx8IHt9O1xuICAgIHRoaXMuY29uZmlnLmNvbnRyb2xsZXJzID0gdGhpcy5jb25maWcuY29udHJvbGxlcnMgfHwge307XG4gICAgdGhpcy5jb25maWcucmVwb3NpdG9yaWVzID0gdGhpcy5jb25maWcucmVwb3NpdG9yaWVzIHx8IHt9O1xuICAgIHRoaXMuY29uZmlnLnByb3ZpZGVycyA9IHRoaXMuY29uZmlnLnByb3ZpZGVycyB8fCB7fTtcbiAgICB0aGlzLmNvbmZpZy5zdWJzY3JpYmVycyA9IHRoaXMuY29uZmlnLnN1YnNjcmliZXJzIHx8IHt9O1xuICAgIHRoaXMuY29uZmlnLm1pZ3JhdGlvbnMgPSB0aGlzLmNvbmZpZy5taWdyYXRpb25zIHx8IHt9O1xuXG4gICAgdGhpcy5jb25maWcuZW50aXRpZXMgPSB7XG4gICAgICAuLi4oYXdhaXQgdGhpcy5nZXRSZWNydXNpdmVDbGFzc2VzZnJvbUNvbnRleHRzT2JqKFxuICAgICAgICBNb2RlbHMuQ2xhc3NUeXBlLkVOVElUWSxcbiAgICAgICkpLFxuICAgICAgLi4udGhpcy5jb25maWcuZW50aXRpZXMsXG4gICAgfTtcblxuICAgIHRoaXMuY29uZmlnLmNvbnRyb2xsZXJzID0ge1xuICAgICAgLi4uKGF3YWl0IHRoaXMuZ2V0UmVjcnVzaXZlQ2xhc3Nlc2Zyb21Db250ZXh0c09iaihcbiAgICAgICAgTW9kZWxzLkNsYXNzVHlwZS5DT05UUk9MTEVSLFxuICAgICAgKSksXG4gICAgICAuLi50aGlzLmNvbmZpZy5jb250cm9sbGVycyxcbiAgICB9O1xuXG4gICAgdGhpcy5jb25maWcucHJvdmlkZXJzID0ge1xuICAgICAgLi4uKGF3YWl0IHRoaXMuZ2V0UmVjcnVzaXZlQ2xhc3Nlc2Zyb21Db250ZXh0c09iaihcbiAgICAgICAgTW9kZWxzLkNsYXNzVHlwZS5QUk9WSURFUixcbiAgICAgICkpLFxuICAgICAgLi4udGhpcy5jb25maWcucHJvdmlkZXJzLFxuICAgIH07XG5cbiAgICB0aGlzLmNvbmZpZy5zdWJzY3JpYmVycyA9IHtcbiAgICAgIC4uLihhd2FpdCB0aGlzLmdldFJlY3J1c2l2ZUNsYXNzZXNmcm9tQ29udGV4dHNPYmooXG4gICAgICAgIE1vZGVscy5DbGFzc1R5cGUuU1VCU0NSSUJFUixcbiAgICAgICkpLFxuICAgICAgLi4udGhpcy5jb25maWcuc3Vic2NyaWJlcnMsXG4gICAgfTtcblxuICAgIHRoaXMuY29uZmlnLnJlcG9zaXRvcmllcyA9IHtcbiAgICAgIC4uLihhd2FpdCB0aGlzLmdldFJlY3J1c2l2ZUNsYXNzZXNmcm9tQ29udGV4dHNPYmooXG4gICAgICAgIE1vZGVscy5DbGFzc1R5cGUuUkVQT1NJVE9SWSxcbiAgICAgICkpLFxuICAgICAgLi4udGhpcy5jb25maWcucmVwb3NpdG9yaWVzLFxuICAgIH07XG5cbiAgICB0aGlzLmNvbmZpZy5taWdyYXRpb25zID0ge1xuICAgICAgLi4uKGF3YWl0IHRoaXMuZ2V0UmVjcnVzaXZlQ2xhc3Nlc2Zyb21Db250ZXh0c09iaihcbiAgICAgICAgTW9kZWxzLkNsYXNzVHlwZS5NSUdSQVRJT04sXG4gICAgICApKSxcbiAgICAgIC4uLnRoaXMuY29uZmlnLm1pZ3JhdGlvbnMsXG4gICAgfTtcblxuXG5cblxuXG5cbiAgICB0aGlzLmNvbmZpZy5jb250cm9sbGVycyA9IHRoaXMuY2xvbmVDbGFzc2VzT2JqV2l0aE5ld01ldGFkYXRhKHtcbiAgICAgIGNsYXNzZXNJbnB1dDogdGhpcy5jb25maWcuY29udHJvbGxlcnMsXG4gICAgICBjb25maWc6IHRoaXMuY29uZmlnLFxuICAgICAgY3R4OiB0aGlzLFxuICAgICAgY2xhc3NUeXBlOiBNb2RlbHMuQ2xhc3NUeXBlLkNPTlRST0xMRVIsXG4gICAgfSk7XG4gICAgdGhpcy5jb25maWcucmVwb3NpdG9yaWVzID0gdGhpcy5jbG9uZUNsYXNzZXNPYmpXaXRoTmV3TWV0YWRhdGEoe1xuICAgICAgY2xhc3Nlc0lucHV0OiB0aGlzLmNvbmZpZy5yZXBvc2l0b3JpZXMsXG4gICAgICBjb25maWc6IHRoaXMuY29uZmlnLFxuICAgICAgY3R4OiB0aGlzLFxuICAgICAgY2xhc3NUeXBlOiBNb2RlbHMuQ2xhc3NUeXBlLlJFUE9TSVRPUlksXG4gICAgfSk7XG4gICAgdGhpcy5jb25maWcucHJvdmlkZXJzID0gdGhpcy5jbG9uZUNsYXNzZXNPYmpXaXRoTmV3TWV0YWRhdGEoe1xuICAgICAgY2xhc3Nlc0lucHV0OiB0aGlzLmNvbmZpZy5wcm92aWRlcnMsXG4gICAgICBjb25maWc6IHRoaXMuY29uZmlnLFxuICAgICAgY3R4OiB0aGlzLFxuICAgICAgY2xhc3NUeXBlOiBNb2RlbHMuQ2xhc3NUeXBlLlBST1ZJREVSLFxuICAgIH0pO1xuICAgIHRoaXMuY29uZmlnLnN1YnNjcmliZXJzID0gdGhpcy5jbG9uZUNsYXNzZXNPYmpXaXRoTmV3TWV0YWRhdGEoe1xuICAgICAgY2xhc3Nlc0lucHV0OiB0aGlzLmNvbmZpZy5zdWJzY3JpYmVycyxcbiAgICAgIGNvbmZpZzogdGhpcy5jb25maWcsXG4gICAgICBjdHg6IHRoaXMsXG4gICAgICBjbGFzc1R5cGU6IE1vZGVscy5DbGFzc1R5cGUuU1VCU0NSSUJFUixcbiAgICB9KTtcblxuICAgIHRoaXMuY29uZmlnLm1pZ3JhdGlvbnMgPSB0aGlzLmNsb25lQ2xhc3Nlc09ialdpdGhOZXdNZXRhZGF0YSh7XG4gICAgICBjbGFzc2VzSW5wdXQ6IHRoaXMuY29uZmlnLm1pZ3JhdGlvbnMsXG4gICAgICBjb25maWc6IHRoaXMuY29uZmlnLFxuICAgICAgY3R4OiB0aGlzLFxuICAgICAgY2xhc3NUeXBlOiBNb2RlbHMuQ2xhc3NUeXBlLk1JR1JBVElPTixcbiAgICB9KTtcblxuXG5cbiAgICBmb3IgKGNvbnN0IGNsYXNzVHlwZU5hbWUgb2YgdGhpcy5pbmplY3RhYmxlVHlwZXNmcm9tQ29udGV4dHMpIHtcbiAgICAgIHRoaXMuY2xhc3NJbnN0YW5jZXNCeU5hbWVPYmpbY2xhc3NUeXBlTmFtZV0gPSB7fTtcbiAgICAgIHRoaXMub2JqV2l0aENsYXNzZXNJbnN0YW5jZXNBcnJbY2xhc3NUeXBlTmFtZV0gPSBbXTtcbiAgICB9XG5cbiAgICBmb3IgKGNvbnN0IGNsYXNzVHlwZU5hbWUgb2YgdGhpcy5pbmplY3RhYmxlVHlwZXNmcm9tQ29udGV4dHMpIHtcbiAgICAgIGF3YWl0IHRoaXMuY3JlYXRlSW5zdGFuY2VzKFxuICAgICAgICB0aGlzLmNvbmZpZ1tNb2RlbHMuQ2xhc3NUeXBlS2V5W2NsYXNzVHlwZU5hbWVdXSxcbiAgICAgICAgY2xhc3NUeXBlTmFtZSxcbiAgICAgICk7XG4gICAgfVxuXG5cbiAgICBpZiAoIXRoaXMuaXNSdW5PclJldmVydE9ubHlNaWdyYXRpb25BcHBTdGFydCkge1xuXG4gICAgICBpZiAodGhpcy5tb2RlID09PSAnYmFja2VuZC1mcm9udGVuZCh0Y3ArdWRwKScgJiYgIXRoaXMuY29uZmlnLmFic3RyYWN0KSB7XG4vKiAqL1xuLyogKi9cbi8qICovXG4vKiAqL1xuLyogKi9cbi8qICovXG4vKiAqL1xuLyogKi9cbi8qICovXG4vKiAqL1xuLyogKi9cbi8qICovXG4vKiAqL1xuLyogKi9cbi8qICovXG4vKiAqL1xuLyogKi9cbi8qICovXG4vKiAqL1xuICBcbiAgICAgIH1cblxuXG5cbiAgICAgIGlmICghdGhpcy5jb25maWcuYWJzdHJhY3QpIHtcbiAgICAgICAgdGhpcy5kaXNhYmxlZFJlYWx0aW1lID0gISF0aGlzLmNvbmZpZy5kaXNhYmxlZFJlYWx0aW1lO1xuLyogKi9cbi8qICovXG4vKiAqL1xuLyogKi9cbi8qICovXG4gIFxuICAgICAgICB0aGlzLnJlYWx0aW1lID0gbmV3IFJlYWx0aW1lQ29yZSh0aGlzKTtcbiAgICAgIH1cblxuICAgIH1cblxuXG5cbiAgICBpZiAodGhpcy5jb25maWcuYWJzdHJhY3QpIHtcbiAgICAgIHRoaXMubG9nRnJhbWV3b3JrICYmXG4gICAgICAgIEhlbHBlcnMuaW5mbyhcbiAgICAgICAgICBgW3Rhb25dIENyZWF0ZSBhYnN0cmFjdCBjb250ZXh0OiAke3RoaXMuY29uZmlnLmNvbnRleHROYW1lfWAsXG4gICAgICAgICk7XG4gICAgfSBlbHNlIHtcbiAgICAgIGlmICh0aGlzLmNvbmZpZy5yZW1vdGVIb3N0KSB7XG4gICAgICAgIHRoaXMubG9nRnJhbWV3b3JrICYmXG4gICAgICAgICAgSGVscGVycy5pbmZvKFxuICAgICAgICAgICAgYFt0YW9uXSBDcmVhdGUgY29udGV4dCBmb3IgcmVtb3RlIGhvc3Q6ICR7dGhpcy5jb25maWcucmVtb3RlSG9zdH1gLFxuICAgICAgICAgICk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB0aGlzLmxvZ0ZyYW1ld29yayAmJlxuICAgICAgICAgIEhlbHBlcnMuaW5mbyhgW3Rhb25dIENyZWF0ZSBjb250ZXh0IGZvciBob3N0OiAke3RoaXMuY29uZmlnLmhvc3R9YCk7XG4gICAgICB9XG4gICAgfVxuXG5cblxuICAgIE9iamVjdC5rZXlzKHRoaXMuY29uZmlnKS5mb3JFYWNoKGtleSA9PiB7XG4gICAgICB0aGlzLm9yaWdpbmFsQ29uZmlnW2tleV0gPSB0aGlzLmNvbmZpZ1trZXldO1xuICAgIH0pO1xuICB9XG5cblxuXG4gIHByaXZhdGUgZ2V0QXV0b0dlbmVyYXRlZENvbmZpZygpOiBNb2RlbHMuRGF0YWJhc2VDb25maWdUeXBlT3JtIHtcblxuICAgIGxldCBkYXRhYmFzZUNvbmZpZzogTW9kZWxzLkRhdGFiYXNlQ29uZmlnID0gTW9kZWxzLkRhdGFiYXNlQ29uZmlnLmZyb20oe30pO1xuICAgIGlmIChVdGlsc09zLmlzUnVubmluZ0luRG9ja2VyKCkpIHtcbiAgICAgIEhlbHBlcnMuaW5mbygnUnVubmluZyBpbiBkb2NrZXIsIHVzaW5nIGluIG15c3FsIGRhdGFiYXNlJyk7XG5cbiAgICAgIGRhdGFiYXNlQ29uZmlnID0gTW9kZWxzLkRhdGFiYXNlQ29uZmlnLmZyb20oe1xuICAgICAgICBkYXRhYmFzZTogYGRiLSR7dGhpcy5jb250ZXh0TmFtZX0uc3FsaXRlYCxcbiAgICAgICAgdHlwZTogJ215c3FsJyxcbiAgICAgICAgcmVjcmVhdGVNb2RlOiAnUFJFU0VSVkVfREFUQStNSUdSQVRJT05TJyxcbiAgICAgICAgbG9nZ2luZzogdGhpcy5sb2dEYixcbiAgICAgICAgZGF0YWJhc2VQb3J0OiAzMzA2LFxuICAgICAgICBkYXRhYmFzZUhvc3Q6ICdsb2NhbGhvc3QnLFxuICAgICAgICBkYXRhYmFzZVVzZXJuYW1lOiAncm9vdCcsXG4gICAgICAgIGRhdGFiYXNlUGFzc3dvcmQ6ICdhZG1pbicsXG4gICAgICB9KTtcbiAgICB9IGVsc2Uge1xuICAgICAgdGhpcy5sb2dGcmFtZXdvcmsgJiZcbiAgICAgICAgSGVscGVycy5pbmZvKFxuICAgICAgICAgIGBbdGFvbl1bZGF0YWJhc2VdIEF1dG9tYXRpY2FsbHkgcmVzb2x2aW5nIGRhdGFiYXNlIGNvbmZpZyBmb3IgbW9kZSAke3RoaXMubW9kZX1gLFxuICAgICAgICApO1xuICAgICAgc3dpdGNoICh0aGlzLm1vZGUpIHtcblxuICAgICAgICBjYXNlICdiYWNrZW5kLWZyb250ZW5kKGlwYy1lbGVjdHJvbiknOlxuICAgICAgICAgIGRhdGFiYXNlQ29uZmlnID0gTW9kZWxzLkRhdGFiYXNlQ29uZmlnLmZyb20oe1xuICAgICAgICAgICAgbG9jYXRpb246IGBkYi0ke3RoaXMuY29udGV4dE5hbWV9LnNxbGl0ZWAsXG4gICAgICAgICAgICB0eXBlOiAnc3FsanMnLFxuICAgICAgICAgICAgcmVjcmVhdGVNb2RlOiAnRFJPUF9EQitNSUdSQVRJT05TJyxcbiAgICAgICAgICAgIGxvZ2dpbmc6IHRoaXMubG9nRGIsXG4gICAgICAgICAgfSk7XG4gICAgICAgICAgYnJlYWs7XG5cblxuXG4gICAgICAgIGNhc2UgJ2JhY2tlbmQtZnJvbnRlbmQod2Vic3FsLWVsZWN0cm9uKSc6XG4gICAgICAgIGNhc2UgJ2JhY2tlbmQtZnJvbnRlbmQod2Vic3FsKSc6XG4gICAgICAgICAgbGV0IGtlZXBXZWJzcWxEYkRhdGFBZnRlclJlbG9hZCA9IGZhbHNlO1xuXG4gICAgICAgICAga2VlcFdlYnNxbERiRGF0YUFmdGVyUmVsb2FkID1cbiAgICAgICAgICAgIFRhb25BZG1pblNlcnZpY2UuSW5zdGFuY2U/LmtlZXBXZWJzcWxEYkRhdGFBZnRlclJlbG9hZDsgLy8gVE9ETyBATEFTVFxuXG5cbiAgICAgICAgICBkYXRhYmFzZUNvbmZpZyA9IGRhdGFiYXNlQ29uZmlnID0gTW9kZWxzLkRhdGFiYXNlQ29uZmlnLmZyb20oe1xuICAgICAgICAgICAgbG9jYXRpb246IGBkYi0ke3RoaXMuY29udGV4dE5hbWV9LnNxbGl0ZWAsXG4gICAgICAgICAgICB0eXBlOiAnc3FsanMnLFxuICAgICAgICAgICAgdXNlTG9jYWxGb3JhZ2U6IHRydWUsIC8vICEhd2luZG93Wydsb2NhbGZvcmFnZSddLCAvLyBUT0RPIHRoaXMgbmVlZCB0byBiZSBjaGVja2VkIGluIHJ1bnRpbWVcbiAgICAgICAgICAgIHJlY3JlYXRlTW9kZToga2VlcFdlYnNxbERiRGF0YUFmdGVyUmVsb2FkXG4gICAgICAgICAgICAgID8gJ1BSRVNFUlZFX0RBVEErTUlHUkFUSU9OUydcbiAgICAgICAgICAgICAgOiAnRFJPUF9EQitNSUdSQVRJT05TJyxcbiAgICAgICAgICAgIGxvZ2dpbmc6IHRoaXMubG9nRGIsXG4gICAgICAgICAgfSk7XG4gICAgICAgICAgYnJlYWs7XG5cblxuXG4gICAgICAgIGNhc2UgJ2JhY2tlbmQtZnJvbnRlbmQodGNwK3VkcCknOlxuICAgICAgICAgIGRhdGFiYXNlQ29uZmlnID0gTW9kZWxzLkRhdGFiYXNlQ29uZmlnLmZyb20oe1xuICAgICAgICAgICAgZGF0YWJhc2U6IGBjb250ZXh0LWRiLSR7dGhpcy5jb250ZXh0TmFtZX1gLFxuICAgICAgICAgICAgbG9jYXRpb246IGBkYi0ke3RoaXMuY29udGV4dE5hbWV9LnNxbGl0ZWAsXG4gICAgICAgICAgICB0eXBlOiAnc3FsanMnLFxuICAgICAgICAgICAgcmVjcmVhdGVNb2RlOiAnRFJPUF9EQitNSUdSQVRJT05TJyxcbiAgICAgICAgICAgIGxvZ2dpbmc6IHRoaXMubG9nRGIsXG4gICAgICAgICAgfSk7XG4gICAgICAgICAgYnJlYWs7XG5cbiAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIGRhdGFiYXNlQ29uZmlnLmRhdGFiYXNlQ29uZmlnVHlwZU9STTtcblxuICB9XG5cblxuXG4gIGdldCBuZ1pvbmUoKTogYW55IHtcblxuICAgIHJldHVybiBFbmRwb2ludENvbnRleHQubmdab25lO1xuXG4gICAgcmV0dXJuO1xuICB9XG5cblxuXG4gIHN0YXJ0U2VydmVyKCkge1xuLyogKi9cbi8qICovXG4vKiAqL1xuLyogKi9cbi8qICovXG4vKiAqL1xuLyogKi9cbi8qICovXG4vKiAqL1xuLyogKi9cbi8qICovXG4vKiAqL1xuLyogKi9cbi8qICovXG4vKiAqL1xuLyogKi9cbiAgICByZXR1cm4gKHZvaWQgMCk7XG4gIH1cblxuXG5cbiAgZGlzcGxheVJvdXRlcyhhcHApIHtcbi8qICovXG4vKiAqL1xuLyogKi9cbi8qICovXG4vKiAqL1xuLyogKi9cbi8qICovXG4vKiAqL1xuLyogKi9cbi8qICovXG4vKiAqL1xuLyogKi9cbi8qICovXG4vKiAqL1xuLyogKi9cbi8qICovXG4vKiAqL1xuLyogKi9cbi8qICovXG4vKiAqL1xuLyogKi9cbi8qICovXG4vKiAqL1xuLyogKi9cbi8qICovXG4vKiAqL1xuLyogKi9cbi8qICovXG4gIFxuICB9XG5cblxuXG4gIGdldCBtb2RlQWxsb3dzRGF0YWJhc2VDcmVhdGlvbigpIHtcbiAgICByZXR1cm4gKFxuICAgICAgdGhpcy5tb2RlID09PSAnYmFja2VuZC1mcm9udGVuZCh0Y3ArdWRwKScgfHxcbiAgICAgIHRoaXMubW9kZSA9PT0gJ2JhY2tlbmQtZnJvbnRlbmQod2Vic3FsKScgfHxcbiAgICAgIHRoaXMubW9kZSA9PT0gJ2JhY2tlbmQtZnJvbnRlbmQoaXBjLWVsZWN0cm9uKSdcbiAgICApO1xuICB9XG5cblxuXG5cbiAgcHJpdmF0ZSBjbG9uZUNsYXNzV2l0aE5ld01ldGFkYXRhID0gPFxuICAgIFQgZXh0ZW5kcyB7IG5ldyAoLi4uYXJnczogYW55W10pOiBhbnkgfSxcbiAgPih7XG4gICAgQmFzZUNsYXNzLFxuICAgIGNsYXNzTmFtZSxcbiAgICBjb25maWcsXG4gICAgY3R4LFxuICAgIGNsYXNzVHlwZSxcbiAgfToge1xuICAgIEJhc2VDbGFzczogVDtcbiAgICBjbGFzc05hbWU6IHN0cmluZztcbiAgICBjb25maWc6IE1vZGVscy5Db250ZXh0T3B0aW9uczxhbnksIGFueSwgYW55LCBhbnksIGFueSwgYW55LCBhbnk+O1xuICAgIGN0eDogRW5kcG9pbnRDb250ZXh0O1xuICAgIGNsYXNzVHlwZTogTW9kZWxzLkNsYXNzVHlwZTtcbiAgfSk6IFQgPT4ge1xuXG4gICAgY29uc3QgY2xvbmVDbGFzcyA9ICgpID0+IHtcbiAgICAgIGlmIChcbiAgICAgICAgQmFzZUNsYXNzW1N5bWJvbHMuZnVsbENsYXNzTmFtZVN0YXRpY1Byb3BlcnR5XSA9PT1cbiAgICAgICAgYCR7Y3R4LmNvbnRleHROYW1lfS4ke2NsYXNzTmFtZX1gXG4gICAgICApIHtcbiAgICAgICAgcmV0dXJuIEJhc2VDbGFzcztcbiAgICAgIH1cbiAgICAgIHJldHVybiBjbGFzcyBleHRlbmRzIEJhc2VDbGFzcyB7XG5cblxuICAgICAgICAvLyBAdHMtaWdub3JlXG4gICAgICAgIHN0YXRpYyBbU3ltYm9scy5vcmlnbmFsQ2xhc3NdID0gQmFzZUNsYXNzO1xuXG4gICAgICAgIC8vIEB0cy1pZ25vcmVcbiAgICAgICAgc3RhdGljIFtTeW1ib2xzLmZ1bGxDbGFzc05hbWVTdGF0aWNQcm9wZXJ0eV0gPSBgJHtjdHguY29udGV4dE5hbWV9LiR7Y2xhc3NOYW1lfWA7XG5cbiAgICAgICAgLy8gQHRzLWlnbm9yZVxuICAgICAgICBzdGF0aWMgW1N5bWJvbHMuY2xhc3NOYW1lU3RhdGljUHJvcGVydHldID0gY2xhc3NOYW1lO1xuXG4gICAgICAgIHN0YXRpYyBbU3ltYm9scy5jdHhJbkNsYXNzT3JDbGFzc09ial0gPSBjdHg7XG5cbiAgICAgICAgc3RhdGljIF9fZ2V0RnVsbFBhdGhGb3JDbGFzc19fKGFyciA9IFtdKSB7XG4gICAgICAgICAgY29uc3QgbmFtZSA9IHRoaXNbU3ltYm9scy5mdWxsQ2xhc3NOYW1lU3RhdGljUHJvcGVydHldO1xuICAgICAgICAgIGFyci5wdXNoKG5hbWUpO1xuICAgICAgICAgIC8vIEB0cy1pZ25vcmVcbiAgICAgICAgICBpZiAoXG4gICAgICAgICAgICB0aGlzW1N5bWJvbHMub3JpZ25hbENsYXNzXSAmJiAvLyBAdHMtaWdub3JlXG4gICAgICAgICAgICB0aGlzW1N5bWJvbHMub3JpZ25hbENsYXNzXS5fX2dldEZ1bGxQYXRoRm9yQ2xhc3NfX1xuICAgICAgICAgICkge1xuICAgICAgICAgICAgLy8gQHRzLWlnbm9yZVxuICAgICAgICAgICAgdGhpc1tTeW1ib2xzLm9yaWduYWxDbGFzc10uX19nZXRGdWxsUGF0aEZvckNsYXNzX18oYXJyKTtcbiAgICAgICAgICB9XG4gICAgICAgICAgcmV0dXJuIGFyci5qb2luKCcvJyk7XG4gICAgICAgIH1cbiAgICAgICAgc3RhdGljIGdldCBmdWxsUGF0aEZvckNsYXNzKCk6IHN0cmluZyB7XG4gICAgICAgICAgcmV0dXJuIHRoaXMuX19nZXRGdWxsUGF0aEZvckNsYXNzX18oKTtcbiAgICAgICAgfVxuICAgICAgICBbU3ltYm9scy5jdHhJbkNsYXNzT3JDbGFzc09ial0gPSBjdHg7XG5cblxuICAgICAgfTtcbiAgICB9O1xuXG4gICAgY29uc3QgY2xvbmVDbGFzc0Z1bmN0aW9uID0gY2xvbmVDbGFzcygpO1xuXG5cblxuXG5cblxuXG5cblxuXG5cblxuXG5cblxuXG5cblxuXG4gICAgcmV0dXJuIGNsb25lQ2xhc3NGdW5jdGlvbjtcbiAgfTtcblxuXG5cblxuXG4gIHByaXZhdGUgY2xvbmVDbGFzc2VzT2JqV2l0aE5ld01ldGFkYXRhID0gKHtcbiAgICBjbGFzc2VzSW5wdXQsXG4gICAgY29uZmlnLFxuICAgIGN0eCxcbiAgICBjbGFzc1R5cGUsXG4gIH06IHtcbiAgICBjbGFzc2VzSW5wdXQ6IGFueTtcbiAgICBjb25maWc6IE1vZGVscy5Db250ZXh0T3B0aW9uczxhbnksIGFueSwgYW55LCBhbnksIGFueSwgYW55LCBhbnk+O1xuICAgIGN0eDogRW5kcG9pbnRDb250ZXh0O1xuICAgIGNsYXNzVHlwZTogTW9kZWxzLkNsYXNzVHlwZTtcbiAgfSkgPT4ge1xuICAgIGNvbnN0IGNsYXNzZXMgPSB7fTtcblxuICAgIGZvciAoY29uc3Qga2V5IG9mIE9iamVjdC5rZXlzKGNsYXNzZXNJbnB1dCB8fCB7fSkpIHtcbiAgICAgIGNvbnN0IEJhc2VDbGFzcyA9IGNsYXNzZXNJbnB1dFtrZXldO1xuXG4gICAgICBpZiAoIUJhc2VDbGFzcykge1xuICAgICAgICBIZWxwZXJzLmVycm9yKGBDbGFzcyAke2tleX0gaXMgbm90IGRlZmluZWQgaW4gY29udGV4dCAke2N0eC5jb250ZXh0TmFtZX1cblxuICAgICAgICBQbGVhc2UgY2hlY2sgaWYgeW91IGhhdmUgY29ycmVjdCBpbXBvcnQgaW4gY29udGV4dCBmaWxlXG5cbiAgICAgICAgYCk7XG4gICAgICB9XG5cbiAgICAgIHZhciBjbGFzc05hbWUgPSBSZWZsZWN0LmdldE1ldGFkYXRhKFxuICAgICAgICBTeW1ib2xzLm1ldGFkYXRhLmNsYXNzTmFtZSxcbiAgICAgICAgQmFzZUNsYXNzLFxuICAgICAgKTtcblxuXG5cblxuXG4gICAgICBjbGFzc05hbWUgPSBjbGFzc05hbWUgfHwga2V5O1xuICAgICAgQmFzZUNsYXNzW1N5bWJvbHMuY2xhc3NOYW1lU3RhdGljUHJvcGVydHldID0gY2xhc3NOYW1lO1xuXG4gICAgICBjb25zdCBjbG9uZWRDbGFzcyA9IHRoaXMuY2xvbmVDbGFzc1dpdGhOZXdNZXRhZGF0YSh7XG4gICAgICAgIEJhc2VDbGFzcyxcbiAgICAgICAgY2xhc3NOYW1lLFxuICAgICAgICBjb25maWcsXG4gICAgICAgIGN0eCxcbiAgICAgICAgY2xhc3NUeXBlLFxuICAgICAgfSk7XG4gICAgICBjbGFzc2VzW2NsYXNzTmFtZV0gPSBjbG9uZWRDbGFzcztcbiAgICB9XG4gICAgcmV0dXJuIGNsYXNzZXM7XG4gIH07XG5cblxuXG4gIHByaXZhdGUgYXN5bmMgZ2V0UmVjcnVzaXZlQ2xhc3Nlc2Zyb21Db250ZXh0c09iaihcbiAgICBjbGFzc1R5cGU6IE1vZGVscy5DbGFzc1R5cGUsXG4gICkge1xuICAgIGNvbnN0IGFyciA9IGF3YWl0IHRoaXMuZ2V0UmVjcnVzaXZlQ2xhc3Nlc2Zyb21Db250ZXh0cyhjbGFzc1R5cGUpO1xuICAgIHJldHVybiBhcnIucmVkdWNlKChhY2MsIGMpID0+IHtcbiAgICAgIGFjY1tDbGFzc0hlbHBlcnMuZ2V0TmFtZShjKV0gPSBjO1xuICAgICAgcmV0dXJuIGFjYztcbiAgICB9LCB7fSk7XG4gIH1cblxuICBwcml2YXRlIGFzeW5jIGdldFJlY3J1c2l2ZUNsYXNzZXNmcm9tQ29udGV4dHMoXG4gICAgY2xhc3NUeXBlOiBNb2RlbHMuQ2xhc3NUeXBlLFxuICAgIGFyciA9IFtdLFxuICApIHtcbiAgICBjb25zdCBjb250ZXh0cyA9IE9iamVjdC52YWx1ZXModGhpcy5jb25maWcuY29udGV4dHMgfHwge30pIGFzIFJldHVyblR5cGU8XG4gICAgICB0eXBlb2YgY3JlYXRlQ29udGV4dFxuICAgID5bXTtcblxuXG5cbiAgICBmb3IgKGNvbnN0IGN0eCBvZiBjb250ZXh0cykge1xuXG4gICAgICBjb25zdCByZWYgPSBhd2FpdCBjdHguX19yZWYoKTtcblxuICAgICAgY29uc3QgY2xhc3Nlc0lucHV0ID0gcmVmLmdldENsYXNzRnVuQnkoY2xhc3NUeXBlKTtcblxuXG4gICAgICBjb25zdCBjbG9uZWRDbGFzc2VzID0gT2JqZWN0LnZhbHVlcyhcbiAgICAgICAgdGhpcy5jbG9uZUNsYXNzZXNPYmpXaXRoTmV3TWV0YWRhdGEoe1xuICAgICAgICAgIGNsYXNzZXNJbnB1dCxcbiAgICAgICAgICBjb25maWc6IHRoaXMuY29uZmlnLFxuICAgICAgICAgIGN0eDogdGhpcyxcbiAgICAgICAgICBjbGFzc1R5cGUsXG4gICAgICAgIH0pLFxuICAgICAgKTtcblxuICAgICAgY2xvbmVkQ2xhc3Nlcy5mb3JFYWNoKGMgPT4gYXJyLnB1c2goYykpO1xuXG4gICAgICBhd2FpdCByZWYuZ2V0UmVjcnVzaXZlQ2xhc3Nlc2Zyb21Db250ZXh0cyhjbGFzc1R5cGUsIGFycik7XG4gICAgfVxuICAgIHJldHVybiBhcnIgYXMgRnVuY3Rpb25bXTtcbiAgfVxuXG5cblxuICBnZXRDbGFzc0luc3RhbmNlT2JqQnkoY2xhc3NUeXBlOiBNb2RlbHMuQ2xhc3NUeXBlKTogYW55IHtcbiAgICByZXR1cm4gdGhpcy5jbGFzc0luc3RhbmNlc0J5TmFtZU9ialtjbGFzc1R5cGVdO1xuICB9XG5cblxuXG4gIHByaXZhdGUgZ2V0Q2xhc3Nlc0luc3RhbmNlc0FyckJ5KGNsYXNzVHlwZTogTW9kZWxzLkNsYXNzVHlwZSk6IGFueVtdIHtcbiAgICByZXR1cm4gdGhpcy5vYmpXaXRoQ2xhc3Nlc0luc3RhbmNlc0FycltjbGFzc1R5cGVdO1xuICB9XG5cblxuXG4gIGluamVjdDxUPihcbiAgICBjdG9yOiBuZXcgKC4uLmFyZ3M6IGFueVtdKSA9PiBULFxuICAgIG9wdGlvbnM/OiB7XG4gICAgICBsb2NhbEluc3RhbmNlPzogYm9vbGVhbjtcbiAgICAgIGNvbnRleHRDbGFzc0luc3RhbmNlPzogQmFzZUNsYXNzO1xuICAgICAgbG9jYUluc3RhbmNlQ29uc3RydWN0b3JBcmdzPzogQ29uc3RydWN0b3JQYXJhbWV0ZXJzPHR5cGVvZiBjdG9yPjtcbiAgICB9LFxuICApOiBUIHtcbiAgICBpZiAoIW9wdGlvbnMpIHtcbiAgICAgIG9wdGlvbnMgPSB7fSBhcyBhbnk7XG4gICAgfVxuICAgIGNvbnN0IGNsYXNzTmFtZSA9IENsYXNzSGVscGVycy5nZXROYW1lKGN0b3IpO1xuXG4gICAgY29uc3QgbG9jYUluc3RhbmNlQ29uc3RydWN0b3JBcmdzID1cbiAgICAgIG9wdGlvbnMubG9jYUluc3RhbmNlQ29uc3RydWN0b3JBcmdzIHx8IFtdO1xuXG4gICAgaWYgKHRoaXMuaXNDTGFzc1R5cGUoTW9kZWxzLkNsYXNzVHlwZS5SRVBPU0lUT1JZLCBjdG9yKSkge1xuICAgICAgb3B0aW9ucy5sb2NhbEluc3RhbmNlID0gdHJ1ZTtcbiAgICB9XG5cbiAgICBpZiAob3B0aW9ucz8ubG9jYWxJbnN0YW5jZSkge1xuICAgICAgY29uc3QgY3R4Q2xhc3NGbiA9IHRoaXMuZ2V0Q2xhc3NGdW5CeUNsYXNzTmFtZShjbGFzc05hbWUpO1xuICAgICAgbGV0IGVudGl0eU5hbWU6IHN0cmluZyA9ICcnO1xuXG4gICAgICBpZiAoY2xhc3NOYW1lID09PSAnQmFzZVJlcG9zaXRvcnknKSB7XG4gICAgICAgIGNvbnN0IGVudGl0eUZuID0gbG9jYUluc3RhbmNlQ29uc3RydWN0b3JBcmdzWzBdO1xuICAgICAgICBjb25zdCBlbnRpdHkgPSBlbnRpdHlGbiAmJiBlbnRpdHlGbigpO1xuICAgICAgICBlbnRpdHlOYW1lID0gZW50aXR5ICYmIENsYXNzSGVscGVycy5nZXROYW1lKGVudGl0eSk7XG4gICAgICB9XG5cbiAgICAgIGlmICghb3B0aW9ucy5jb250ZXh0Q2xhc3NJbnN0YW5jZVt0aGlzLmxvY2FsSW5zdGFjZU9ialN5bWJvbF0pIHtcbiAgICAgICAgb3B0aW9ucy5jb250ZXh0Q2xhc3NJbnN0YW5jZVt0aGlzLmxvY2FsSW5zdGFjZU9ialN5bWJvbF0gPSB7fTtcbiAgICAgIH1cbiAgICAgIGNvbnN0IGluc3RhbmNlS2V5ID0gY2xhc3NOYW1lICsgKGVudGl0eU5hbWUgPyBgLiR7ZW50aXR5TmFtZX1gIDogJycpO1xuICAgICAgY29uc3QgZXhpc3RlZCA9XG4gICAgICAgIG9wdGlvbnMuY29udGV4dENsYXNzSW5zdGFuY2VbdGhpcy5sb2NhbEluc3RhY2VPYmpTeW1ib2xdW2luc3RhbmNlS2V5XTtcbiAgICAgIGlmIChleGlzdGVkKSB7XG5cbiAgICAgICAgcmV0dXJuIGV4aXN0ZWQ7XG4gICAgICB9XG5cbiAgICAgIGlmICghY3R4Q2xhc3NGbikge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYE5vdCBhYmxlIHRvIGluamVjdCBcIiR7Y2xhc3NOYW1lfVwiIGluc2lkZSBjb250ZXh0IFwiJHt0aGlzLmNvbnRleHROYW1lfVwiXG5cbiAgICAgICAgTWFrZSBzdXJlIHRoZXkgc2hhcmUgdGhlIHNhbWUgY29udGV4dCBvciBpbXBvcnQgY29udGV4dCB3aGVyZSBcIiR7Y2xhc3NOYW1lfVwiIGlzIGRlZmluZWQuXG5cbiAgICAgICAgYCk7XG4gICAgICB9XG5cbiAgICAgIGNvbnN0IGluamVjdGVkSW5zdGFuY2UgPSBuZXcgKGN0eENsYXNzRm4gYXMgYW55KShcbiAgICAgICAgLi4ubG9jYUluc3RhbmNlQ29uc3RydWN0b3JBcmdzLFxuICAgICAgKTtcbiAgICAgIG9wdGlvbnMuY29udGV4dENsYXNzSW5zdGFuY2VbdGhpcy5sb2NhbEluc3RhY2VPYmpTeW1ib2xdW2luc3RhbmNlS2V5XSA9XG4gICAgICAgIGluamVjdGVkSW5zdGFuY2U7XG5cbiAgICAgIHJldHVybiBpbmplY3RlZEluc3RhbmNlO1xuICAgIH1cblxuICAgIGNvbnN0IGNvbnRleHRTY29wZUluc3RhbmNlID0gdGhpcy5hbGxDbGFzc2VzSW5zdGFuY2VzW2NsYXNzTmFtZV07XG5cblxuXG4gICAgcmV0dXJuIGNvbnRleHRTY29wZUluc3RhbmNlO1xuICB9XG5cbiAgLyoqXG4gICAqIGFsaWFzIGZvciBpbmplY3RcbiAgICovXG4gIGdldEluc3RhbmNlQnk8VD4oY3RvcjogbmV3ICguLi5hcmdzOiBhbnlbXSkgPT4gVCk6IFQge1xuXG5cblxuXG5cblxuXG5cblxuXG5cblxuXG5cblxuICAgIHJldHVybiB0aGlzLmluamVjdChjdG9yLCB7IGxvY2FsSW5zdGFuY2U6IGZhbHNlIH0pO1xuICB9XG5cblxuXG4gIGNoZWNrSWZDb250ZXh0SW5pdGlhbGl6ZWQoKSB7XG4gICAgaWYgKF8uaXNVbmRlZmluZWQodGhpcy5jb25maWcpKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoYFBsZWFzZSBjaGVjayBpZiB5b3VyIGNvbnRleHQgaGFzIGJlZW4gaW5pdGlhbGl6ZWQuXG5cblxuICAgICAgYXdhaXQgQ29udGV4dC5pbml0aWFsaXplKCk7XG5cblxuXG4gICAgICBgKTtcbiAgICB9XG4gIH1cblxuXG5cbiAgZ2V0Q2xhc3NGdW5CeShjbGFzc1R5cGU6IE1vZGVscy5DbGFzc1R5cGUpIHtcbiAgICB0aGlzLmNoZWNrSWZDb250ZXh0SW5pdGlhbGl6ZWQoKTtcbiAgICBzd2l0Y2ggKGNsYXNzVHlwZSkge1xuICAgICAgY2FzZSBNb2RlbHMuQ2xhc3NUeXBlLkNPTlRST0xMRVI6XG4gICAgICAgIHJldHVybiB0aGlzLmNvbmZpZy5jb250cm9sbGVycztcbiAgICAgIGNhc2UgTW9kZWxzLkNsYXNzVHlwZS5FTlRJVFk6XG4gICAgICAgIHJldHVybiB0aGlzLmNvbmZpZy5lbnRpdGllcztcbiAgICAgIGNhc2UgTW9kZWxzLkNsYXNzVHlwZS5QUk9WSURFUjpcbiAgICAgICAgcmV0dXJuIHRoaXMuY29uZmlnLnByb3ZpZGVycztcbiAgICAgIGNhc2UgTW9kZWxzLkNsYXNzVHlwZS5SRVBPU0lUT1JZOlxuICAgICAgICByZXR1cm4gdGhpcy5jb25maWcucmVwb3NpdG9yaWVzO1xuICAgICAgY2FzZSBNb2RlbHMuQ2xhc3NUeXBlLlNVQlNDUklCRVI6XG4gICAgICAgIHJldHVybiB0aGlzLmNvbmZpZy5zdWJzY3JpYmVycztcbiAgICAgIGNhc2UgTW9kZWxzLkNsYXNzVHlwZS5NSUdSQVRJT046XG4gICAgICAgIHJldHVybiB0aGlzLmNvbmZpZy5taWdyYXRpb25zO1xuICAgIH1cbiAgfVxuXG4gIGlzQ0xhc3NUeXBlKGNsYXNzVHlwZTogTW9kZWxzLkNsYXNzVHlwZSwgY2xhc3NGbjogRnVuY3Rpb24pOiBib29sZWFuIHtcbiAgICByZXR1cm4gISF0aGlzLmdldENsYXNzRnVuQnkoY2xhc3NUeXBlKVtDbGFzc0hlbHBlcnMuZ2V0TmFtZShjbGFzc0ZuKV07XG4gIH1cblxuICAvKipcbiAgICogT25seSBmb3IgaW5qZWN0YWJsZSB0eXBlc1xuICAgKiBPbmx5IGZvciBjbGFzc1R5cGU6IENPTlRST0xMRVIsIFJFUE9TSVRPUlksIFBST1ZJREVSXG4gICAqL1xuICBnZXRDbGFzc0Z1bkJ5Q2xhc3NOYW1lKGNsYXNzTmFtZTogc3RyaW5nKTogRnVuY3Rpb24ge1xuICAgIGZvciAoY29uc3QgY2xhc3NUeXBlTmFtZSBvZiB0aGlzLmFsbFR5cGVzZnJvbUNvbnRleHRzKSB7XG4gICAgICBjb25zdCBjbGFzc2VzRm9ySW5qZWN0YWJsZVR5cGUgPVxuICAgICAgICB0aGlzLmNvbmZpZ1tNb2RlbHMuQ2xhc3NUeXBlS2V5W2NsYXNzVHlwZU5hbWVdXTtcblxuICAgICAgaWYgKGNsYXNzZXNGb3JJbmplY3RhYmxlVHlwZVtjbGFzc05hbWVdKSB7XG4gICAgICAgIHJldHVybiBjbGFzc2VzRm9ySW5qZWN0YWJsZVR5cGVbY2xhc3NOYW1lXTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICBnZXRDbGFzc0Z1bkJ5Q2xhc3MoY2xhc3NGdW5jdGlvbjogRnVuY3Rpb24pOiBGdW5jdGlvbiB7XG4gICAgY29uc3QgY2xhc3NOYW1lID0gQ2xhc3NIZWxwZXJzLmdldE5hbWUoY2xhc3NGdW5jdGlvbik7XG4gICAgcmV0dXJuIHRoaXMuZ2V0Q2xhc3NGdW5CeUNsYXNzTmFtZShjbGFzc05hbWUpO1xuICB9XG5cbiAgZ2V0Q2xhc3NGdW5CeUFycihjbGFzc1R5cGU6IE1vZGVscy5DbGFzc1R5cGUpIHtcbiAgICByZXR1cm4gT2JqZWN0LnZhbHVlcyh0aGlzLmdldENsYXNzRnVuQnkoY2xhc3NUeXBlKSB8fCB7fSkgYXMgRnVuY3Rpb25bXTtcbiAgfVxuXG5cblxuICBwcml2YXRlIGFzeW5jIGNyZWF0ZUluc3RhbmNlcyhjbGFzc2VzOiBhbnksIGNsYXNzVHlwZTogTW9kZWxzLkNsYXNzVHlwZSkge1xuXG5cblxuXG5cbiAgICBmb3IgKGNvbnN0IGNsYXNzRm4gb2YgW1xuXG4gICAgICAuLi5PYmplY3QudmFsdWVzKGNsYXNzZXMpLFxuICAgIF0pIHtcbiAgICAgIGNvbnN0IGluc3RhbmNlID0gRElUYW9uQ29udGFpbmVyLnJlc29sdmUoY2xhc3NGbiBhcyBhbnkpIGFzIGFueTtcbiAgICAgIGNvbnN0IGNsYXNzSW5zdGFuY2VzQnlOYW1lT2JqID0gdGhpcy5jbGFzc0luc3RhbmNlc0J5TmFtZU9ialtjbGFzc1R5cGVdO1xuICAgICAgY29uc3QgY2xhc3NOYW1lID0gQ2xhc3NIZWxwZXJzLmdldE5hbWUoY2xhc3NGbik7XG5cbiAgICAgIGNsYXNzSW5zdGFuY2VzQnlOYW1lT2JqW2NsYXNzTmFtZV0gPSBpbnN0YW5jZTtcblxuICAgICAgdGhpcy5jb25maWdbTW9kZWxzLkNsYXNzVHlwZUtleVtjbGFzc1R5cGVdXVtjbGFzc05hbWVdID0gY2xhc3NGbjtcbiAgICAgIHRoaXMub2JqV2l0aENsYXNzZXNJbnN0YW5jZXNBcnJbY2xhc3NUeXBlXS5wdXNoKGluc3RhbmNlKTtcbiAgICAgIHRoaXMuYWxsQ2xhc3Nlc0luc3RhbmNlc1tjbGFzc05hbWVdID0gaW5zdGFuY2U7XG4gICAgfVxuICB9XG5cblxuXG4gIGFzeW5jIHJlaW5pdENvbnRyb2xsZXJzKCkge1xuICAgIGlmICh0aGlzLnJlbW90ZUhvc3QgfHwgT2JqZWN0LmtleXModGhpcy5jb25maWcubWlncmF0aW9ucykubGVuZ3RoID4gMCkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuXG5cbiAgICBjb25zdCBjb250cm9sbGVycyA9IHRoaXMuZ2V0Q2xhc3Nlc0luc3RhbmNlc0FyckJ5KFxuICAgICAgTW9kZWxzLkNsYXNzVHlwZS5DT05UUk9MTEVSLFxuICAgICk7XG5cbiAgICBmb3IgKGNvbnN0IGN0cmwgb2YgY29udHJvbGxlcnMpIHtcbiAgICAgIGlmIChfLmlzRnVuY3Rpb24oY3RybC5pbml0RXhhbXBsZURiRGF0YSkpIHtcbiAgICAgICAgYXdhaXQgSGVscGVycy5ydW5TeW5jT3JBc3luYyh7XG4gICAgICAgICAgZnVuY3Rpb25GbjogY3RybC5pbml0RXhhbXBsZURiRGF0YSxcbiAgICAgICAgICBjb250ZXh0OiBjdHJsLFxuICAgICAgICB9KTtcbiAgICAgIH1cbiAgICB9XG5cblxuXG4gIH1cbiAgYXN5bmMgaW5pdENsYXNzZXMoKSB7XG4gICAgaWYgKHRoaXMucmVtb3RlSG9zdCkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBmb3IgKGNvbnN0IGNsYXNzVHlwZU5hbWUgb2YgW1xuICAgICAgTW9kZWxzLkNsYXNzVHlwZS5QUk9WSURFUixcbiAgICAgIE1vZGVscy5DbGFzc1R5cGUuUkVQT1NJVE9SWSxcbiAgICAgIE1vZGVscy5DbGFzc1R5cGUuQ09OVFJPTExFUixcbiAgICAgIE1vZGVscy5DbGFzc1R5cGUuRU5USVRZLFxuICAgICAgTW9kZWxzLkNsYXNzVHlwZS5NSUdSQVRJT04sXG4gICAgXSkge1xuXG5cblxuXG4gICAgICBmb3IgKGNvbnN0IGNsYXNzRnVuIG9mIHRoaXMuZ2V0Q2xhc3NGdW5CeUFycihjbGFzc1R5cGVOYW1lKSBhcyBhbnlbXSkge1xuICAgICAgICBpZiAoXy5pc0Z1bmN0aW9uKGNsYXNzRnVuLl8pKSB7XG4gICAgICAgICAgYXdhaXQgSGVscGVycy5ydW5TeW5jT3JBc3luYyh7XG4gICAgICAgICAgICBmdW5jdGlvbkZuOiBjbGFzc0Z1bi5fLFxuICAgICAgICAgICAgY29udGV4dDogY2xhc3NGdW4sXG4gICAgICAgICAgfSk7XG5cblxuXG5cblxuXG4gICAgICAgIH1cbiAgICAgIH1cblxuXG5cblxuICAgIH1cblxuICAgIGZvciAoY29uc3QgY2xhc3NUeXBlTmFtZSBvZiBbXG4gICAgICBNb2RlbHMuQ2xhc3NUeXBlLlBST1ZJREVSLFxuICAgICAgTW9kZWxzLkNsYXNzVHlwZS5SRVBPU0lUT1JZLFxuICAgICAgTW9kZWxzLkNsYXNzVHlwZS5DT05UUk9MTEVSLFxuICAgICAgTW9kZWxzLkNsYXNzVHlwZS5NSUdSQVRJT04sXG4gICAgXSkge1xuXG5cblxuXG4gICAgICBmb3IgKGNvbnN0IGN0cmwgb2YgdGhpcy5nZXRDbGFzc2VzSW5zdGFuY2VzQXJyQnkoY2xhc3NUeXBlTmFtZSkpIHtcbiAgICAgICAgaWYgKF8uaXNGdW5jdGlvbihjdHJsLl8pKSB7XG4gICAgICAgICAgYXdhaXQgSGVscGVycy5ydW5TeW5jT3JBc3luYyh7XG4gICAgICAgICAgICBmdW5jdGlvbkZuOiBjdHJsLl8sXG4gICAgICAgICAgICBjb250ZXh0OiBjdHJsLFxuICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgICB9XG5cblxuXG5cbiAgICB9XG4gIH1cblxuXG5cbiAgaXNBY3RpdmVPbihjbGFzc0luc3RhbmNlOiBvYmplY3QpOiBib29sZWFuIHtcbiAgICBsZXQgY29udGV4dFJlZjogRW5kcG9pbnRDb250ZXh0ID1cbiAgICAgIGNsYXNzSW5zdGFuY2VbU3ltYm9scy5jdHhJbkNsYXNzT3JDbGFzc09ial07XG4gICAgcmV0dXJuIHRoaXMgPT09IGNvbnRleHRSZWY7XG4gIH1cblxuXG5cbiAgZ2V0IHVyaSgpIHtcbiAgICBjb25zdCB1cmwgPSB0aGlzLmhvc3RcbiAgICAgID8gbmV3IFVSTCh0aGlzLmhvc3QpXG4gICAgICA6IHRoaXMucmVtb3RlSG9zdFxuICAgICAgICA/IG5ldyBVUkwodGhpcy5yZW1vdGVIb3N0KVxuICAgICAgICA6IHZvaWQgMDtcbiAgICByZXR1cm4gdXJsO1xuICB9XG5cblxuXG4gIGdldCBpc0h0dHBTZXJ2ZXIoKSB7XG4gICAgcmV0dXJuIHRoaXMudXJpLnByb3RvY29sID09PSAnaHR0cHM6JztcbiAgfVxuXG5cblxuICAvKipcbiAgICogaXBjL3VkcCBuZWVkcyB0aGlzXG4gICAqL1xuICBwdWJsaWMgZ2V0IGNvbnRleHROYW1lKCkge1xuICAgIHJldHVybiB0aGlzLmNvbmZpZy5jb250ZXh0TmFtZTtcbiAgfVxuXG5cblxuICBwdWJsaWMgZ2V0IHB1YmxpY0Fzc2V0cygpIHtcbiAgICByZXR1cm4gdGhpcy5jb25maWc/LnB1YmxpY0Fzc2V0cyB8fCBbXTtcbiAgfVxuXG5cblxuICBnZXQgaXNQcm9kdWN0aW9uTW9kZSgpIHtcbiAgICByZXR1cm4gdGhpcy5jb25maWcucHJvZHVjdGlvbk1vZGU7XG4gIH1cblxuXG5cbiAgZ2V0IHJlbW90ZUhvc3QoKSB7XG4gICAgcmV0dXJuIHRoaXMuY29uZmlnLnJlbW90ZUhvc3Q7XG4gIH1cblxuXG5cbiAgZ2V0IGhvc3QoKSB7XG4gICAgcmV0dXJuIHRoaXMuY29uZmlnLmhvc3Q7XG4gIH1cblxuXG5cbiAgZ2V0IG9yZ2luKCkge1xuICAgIHJldHVybiB0aGlzLnVyaT8ub3JpZ2luO1xuICB9XG5cblxuXG4gIGFzeW5jIGluaXRTdWJzY3JpYmVycygpIHtcblxuICAgIGlmICh0aGlzLnJlbW90ZUhvc3QpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgY29uc3Qgc3Vic2NyaWJlckNsYXNzZXMgPSB0aGlzLmdldENsYXNzRnVuQnlBcnIoXG4gICAgICBNb2RlbHMuQ2xhc3NUeXBlLlNVQlNDUklCRVIsXG4gICAgKTtcbiAgICBmb3IgKGNvbnN0IHN1YnNjcmliZXJDbGFzc0ZuIG9mIHN1YnNjcmliZXJDbGFzc2VzKSB7XG4gICAgICBjb25zdCBvcHRpb25zID0gUmVmbGVjdC5nZXRNZXRhZGF0YShcbiAgICAgICAgU3ltYm9scy5tZXRhZGF0YS5vcHRpb25zLnN1YnNjcmliZXIsXG4gICAgICAgIHN1YnNjcmliZXJDbGFzc0ZuLFxuICAgICAgKSBhcyBUYW9uU3Vic2NyaWJlck9wdGlvbnM7XG5cblxuICAgICAgRXZlbnRTdWJzY3JpYmVyKCkoc3Vic2NyaWJlckNsYXNzRm4pO1xuICAgIH1cblxuICB9XG5cblxuXG4gIGFzeW5jIGluaXRFbnRpdGllcygpIHtcblxuICAgIGlmICh0aGlzLnJlbW90ZUhvc3QpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgY29uc3QgZW50aXRpZXMgPSB0aGlzLmdldENsYXNzRnVuQnlBcnIoTW9kZWxzLkNsYXNzVHlwZS5FTlRJVFkpO1xuICAgIGZvciAoY29uc3QgZW50aXR5IG9mIGVudGl0aWVzKSB7XG4gICAgICBjb25zdCBvcHRpb25zID0gUmVmbGVjdC5nZXRNZXRhZGF0YShcbiAgICAgICAgU3ltYm9scy5tZXRhZGF0YS5vcHRpb25zLmVudGl0eSxcbiAgICAgICAgZW50aXR5LFxuICAgICAgKSBhcyBUYW9uRW50aXR5T3B0aW9ucztcbiAgICAgIGNvbnN0IGNyZWF0ZVRhYmxlID0gXy5pc1VuZGVmaW5lZChvcHRpb25zLmNyZWF0ZVRhYmxlKVxuICAgICAgICA/IHRydWVcbiAgICAgICAgOiBvcHRpb25zLmNyZWF0ZVRhYmxlO1xuICAgICAgY29uc3QgbmFtZUZvckVudGl0eSA9IENsYXNzSGVscGVycy5nZXROYW1lKGVudGl0eSk7XG5cbiAgICAgIGlmIChfLmlzVW5kZWZpbmVkKG9wdGlvbnMuY3JlYXRlVGFibGUpID8gdHJ1ZSA6IG9wdGlvbnMuY3JlYXRlVGFibGUpIHtcbiAgICAgICAgdGhpcy5sb2dEYiAmJlxuICAgICAgICAgIGNvbnNvbGUuaW5mbyhcbiAgICAgICAgICAgIGBbdGFvbl1bdHlwZW9ybV0gY3JlYXRlIHRhYmxlIGZvciBlbnRpdHkgXCIke25hbWVGb3JFbnRpdHl9XCIgPyAnJHtjcmVhdGVUYWJsZX0nYCxcbiAgICAgICAgICApO1xuXG4gICAgICAgIFR5cGVvcm1FbnRpdHkobmFtZUZvckVudGl0eSkoZW50aXR5KTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHRoaXMubG9nRGIgJiZcbiAgICAgICAgICBjb25zb2xlLmluZm8oXG4gICAgICAgICAgICBgW3Rhb25dW3R5cGVvcm1dIGNyZWF0ZSB0YWJsZSBmb3IgZW50aXR5IFwiJHtuYW1lRm9yRW50aXR5fVwiID8gJyR7Y3JlYXRlVGFibGV9J2AsXG4gICAgICAgICAgKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgfVxuXG5cblxuXG4gIGFzeW5jIGluaXREYXRhYmFzZUNvbm5lY3Rpb24oKSB7XG5cbiAgICBpZiAodGhpcy5yZW1vdGVIb3N0KSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIGNvbnN0IGVudGl0aWVzID0gdGhpcy5nZXRDbGFzc0Z1bkJ5QXJyKE1vZGVscy5DbGFzc1R5cGUuRU5USVRZKS5tYXAoXG4gICAgICBlbnRpdHlGbiA9PiB7XG4gICAgICAgIHJldHVybiBDbGFzc0hlbHBlcnMuZ2V0T3JnaW5hbENsYXNzKGVudGl0eUZuKTtcbiAgICAgIH0sXG4gICAgKTtcblxuICAgIGNvbnN0IHN1YnNjcmliZXJzID0gdGhpcy5nZXRDbGFzc0Z1bkJ5QXJyKE1vZGVscy5DbGFzc1R5cGUuU1VCU0NSSUJFUik7XG5cbiAgICBjb25zdCBkYXRhU291cmNlRGJDb25maWcgPSBfLmlzT2JqZWN0KHRoaXMuZGF0YWJhc2VDb25maWcpXG4gICAgICA/ICh7XG4gICAgICAgICAgdHlwZTogdGhpcy5kYXRhYmFzZUNvbmZpZy50eXBlLFxuICAgICAgICAgIHBvcnQ6IHRoaXMuZGF0YWJhc2VDb25maWcuZGF0YWJhc2VQb3J0LFxuICAgICAgICAgIGhvc3Q6IHRoaXMuZGF0YWJhc2VDb25maWcuZGF0YWJhc2VIb3N0LFxuICAgICAgICAgIGRhdGFiYXNlOiB0aGlzLmRhdGFiYXNlQ29uZmlnLmRhdGFiYXNlIGFzIGFueSxcbiAgICAgICAgICB1c2VybmFtZTogdGhpcy5kYXRhYmFzZUNvbmZpZy5kYXRhYmFzZVVzZXJuYW1lLFxuICAgICAgICAgIHBhc3N3b3JkOiB0aGlzLmRhdGFiYXNlQ29uZmlnLmRhdGFiYXNlUGFzc3dvcmQsXG4gICAgICAgICAgdXNlTG9jYWxGb3JhZ2U6IHRoaXMuZGF0YWJhc2VDb25maWcudXNlTG9jYWxGb3JhZ2UsXG5cbiAgICAgICAgICBlbnRpdGllcyxcbiAgICAgICAgICBzdWJzY3JpYmVycyxcbiAgICAgICAgICBzeW5jaHJvbml6ZTogdGhpcy5pc1J1bk9yUmV2ZXJ0T25seU1pZ3JhdGlvbkFwcFN0YXJ0XG4gICAgICAgICAgICA/IGZhbHNlXG4gICAgICAgICAgICA6IHRoaXMuZGF0YWJhc2VDb25maWcuc3luY2hyb25pemUsXG4gICAgICAgICAgYXV0b1NhdmU6ICFfLmlzTmlsKHRoaXMuZGF0YWJhc2VDb25maWcuYXV0b1NhdmUpXG4gICAgICAgICAgICA/IHRoaXMuZGF0YWJhc2VDb25maWcuYXV0b1NhdmVcbiAgICAgICAgICAgIDogIVV0aWxzT3MuaXNSdW5uaW5nSW5Eb2NrZXIoKSwgLy8gaW4gZG9ja2VyIEkgYW0gdXNpbmcgbXlzcWwgb3IgcG9zZ3Jlc3NcbiAgICAgICAgICBkcm9wU2NoZW1hOiB0aGlzLmlzUnVuT3JSZXZlcnRPbmx5TWlncmF0aW9uQXBwU3RhcnRcbiAgICAgICAgICAgID8gZmFsc2VcbiAgICAgICAgICAgIDogdGhpcy5kYXRhYmFzZUNvbmZpZy5kcm9wU2NoZW1hLFxuICAgICAgICAgIGxvZ2dpbmc6ICEhdGhpcy5kYXRhYmFzZUNvbmZpZy5sb2dnaW5nLFxuICAgICAgICAgIGxvY2F0aW9uOiB0aGlzLmRhdGFiYXNlQ29uZmlnLmxvY2F0aW9uLFxuICAgICAgICB9IGFzIERhdGFTb3VyY2VPcHRpb25zKVxuICAgICAgOiAoe30gYXMgRGF0YVNvdXJjZU9wdGlvbnMpO1xuXG5cbiAgICB0aGlzLmxvZ0ZyYW1ld29yayAmJlxuICAgICAgY29uc29sZS5sb2coXG4gICAgICAgIGBbQ29udGV4dDogXCIke3RoaXMuY29udGV4dE5hbWV9XCJdIGRhdGFTb3VyY2VEYkNvbmZpZ2AsXG4gICAgICAgIGRhdGFTb3VyY2VEYkNvbmZpZyxcbiAgICAgICk7XG5cbiAgICBpZiAodGhpcy5tb2RlQWxsb3dzRGF0YWJhc2VDcmVhdGlvbiAmJiB0aGlzLmRhdGFiYXNlQ29uZmlnKSB7XG4gICAgICB0aGlzLmxvZ0RiICYmXG4gICAgICAgIHRoaXMubG9nRnJhbWV3b3JrICYmXG4gICAgICAgIEhlbHBlcnMuaW5mbygnW3Rhb25dW2RhdGFiYXNlXSBwcmVwYXJlIHR5cGVvcm0gY29ubmVjdGlvbi4uLicpO1xuICAgICAgdHJ5IHtcbiAgICAgICAgY29uc3QgY29ubmVjdGlvbiA9IG5ldyBEYXRhU291cmNlKGRhdGFTb3VyY2VEYkNvbmZpZyk7XG4gICAgICAgIHRoaXMuY29ubmVjdGlvbiA9IGNvbm5lY3Rpb247XG4gICAgICAgIGF3YWl0IHRoaXMuY29ubmVjdGlvbi5pbml0aWFsaXplKCk7XG4gICAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgICBjb25zb2xlLmVycm9yKGVycm9yPy5tZXNzYWdlIHx8IGVycm9yKTtcbiAgICAgIH1cblxuICAgICAgaWYgKCF0aGlzLmNvbm5lY3Rpb24/LmlzSW5pdGlhbGl6ZWQpIHtcbiAgICAgICAgY29uc29sZS5sb2coJ1dST05HIENPTkZJRycsIGRhdGFTb3VyY2VEYkNvbmZpZyk7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihgU29tZXRoaW5nIHdyb25nIHdpdGggY29ubmVjdGlvbiBpbml0IGluICR7dGhpcy5tb2RlfWApO1xuLyogKi9cbi8qICovXG4gIFxuICAgICAgfVxuXG4gICAgICBpZiAodGhpcy5sb2dEYiB8fCB0aGlzLmxvZ0ZyYW1ld29yaykge1xuICAgICAgICBjb25zb2xlLmluZm8oXG4gICAgICAgICAgYFxuXG4gICAgICAgIENPTlRFQ1RJT04gT0sgZm9yICR7dGhpcy5jb250ZXh0TmFtZX0gLSAke3RoaXMubW9kZX1cblxuICAgICAgICBbdGFvbl1bdHlwZW9ybV0gZGIgcHJlcHJhdGlvbiBkb25lLi4gZGIgaW5pdGlhbGl6ZT0ke3RoaXMuY29ubmVjdGlvbj8uaXNJbml0aWFsaXplZH1cblxuXG4gICAgICAgIGAsXG4gICAgICAgICAgZGF0YVNvdXJjZURiQ29uZmlnLFxuICAgICAgICAgIHsgJ3RoaXMuY29ubmVjdGlvbic6ICEhdGhpcy5jb25uZWN0aW9uIH0sXG4gICAgICAgICk7XG4gICAgICAgIGNvbnNvbGUubG9nKFxuICAgICAgICAgIGBEYXRhYmFzZSBmaWxlIGxvY2F0aW9uOiAke3RoaXMuY29ubmVjdGlvbi5vcHRpb25zLmRhdGFiYXNlfWAsXG4gICAgICAgICk7XG4gICAgICB9XG5cblxuXG5cblxuXG5cblxuXG5cbiAgICB9IGVsc2Uge1xuICAgICAgSGVscGVycy5pbmZvKGBbdGFvbl1bdHlwZW9ybV0gTm90IGluaXRpbmcgZGIgZm9yIG1vZGUgJHt0aGlzLm1vZGV9YCk7XG4gICAgfVxuXG4gIH1cblxuXG5cblxuICBpbml0Q29udHJvbGxlcnMoKSB7XG4gICAgaWYgKHRoaXMuaXNSdW5PclJldmVydE9ubHlNaWdyYXRpb25BcHBTdGFydCkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBjb25zdCBhbGxDb250cm9sbGVycyA9IHRoaXMuZ2V0Q2xhc3NGdW5CeUFycihNb2RlbHMuQ2xhc3NUeXBlLkNPTlRST0xMRVIpO1xuXG4gICAgZm9yIChjb25zdCBjb250cm9sbGVyQ2xhc3NGbiBvZiBhbGxDb250cm9sbGVycykge1xuICAgICAgY29udHJvbGxlckNsYXNzRm5bU3ltYm9scy5jbGFzc01ldGhvZHNOYW1lc10gPVxuICAgICAgICBDbGFzc0hlbHBlcnMuZ2V0TWV0aG9kc05hbWVzKGNvbnRyb2xsZXJDbGFzc0ZuKTtcbiAgICAgIGNvbnN0IGNvbmZpZ3MgPSBDbGFzc0hlbHBlcnMuZ2V0Q29udHJvbGxlckNvbmZpZ3MoY29udHJvbGxlckNsYXNzRm4pO1xuXG4gICAgICBjb25zdCBjbGFzc0NvbmZpZzogTW9kZWxzLlJ1bnRpbWVDb250cm9sbGVyQ29uZmlnID0gY29uZmlnc1swXTtcblxuICAgICAgY29uc3QgcGFyZW50c2NhbGN1bGF0ZWRQYXRoID0gXy5zbGljZShjb25maWdzLCAxKVxuICAgICAgICAucmV2ZXJzZSgpXG4gICAgICAgIC5tYXAoYmMgPT4ge1xuICAgICAgICAgIGlmIChUYW9uSGVscGVycy5pc0dvb2RQYXRoKGJjLnBhdGgpKSB7XG4gICAgICAgICAgICByZXR1cm4gYmMucGF0aDtcbiAgICAgICAgICB9XG4gICAgICAgICAgcmV0dXJuIGJjLmNsYXNzTmFtZTtcbiAgICAgICAgfSlcbiAgICAgICAgLmpvaW4oJy8nKTtcblxuICAgICAgaWYgKFRhb25IZWxwZXJzLmlzR29vZFBhdGgoY2xhc3NDb25maWcucGF0aCkpIHtcbiAgICAgICAgY2xhc3NDb25maWcuY2FsY3VsYXRlZFBhdGggPSBjbGFzc0NvbmZpZy5wYXRoO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgY2xhc3NDb25maWcuY2FsY3VsYXRlZFBhdGggPVxuICAgICAgICAgIGAke3BhcmVudHNjYWxjdWxhdGVkUGF0aH0vJHtDbGFzc0hlbHBlcnMuZ2V0TmFtZShjb250cm9sbGVyQ2xhc3NGbil9YFxuICAgICAgICAgICAgLnJlcGxhY2UoL1xcL1xcLy9nLCAnLycpXG4gICAgICAgICAgICAuc3BsaXQoJy8nKVxuICAgICAgICAgICAgLnJlZHVjZSgoYWNjLCBiYykgPT4ge1xuICAgICAgICAgICAgICByZXR1cm4gXy5sYXN0KGFjYykgPT09IGJjID8gYWNjIDogWy4uLmFjYywgYmNdO1xuICAgICAgICAgICAgfSwgW10pXG4gICAgICAgICAgICAuam9pbignLycpO1xuICAgICAgfVxuXG4gICAgICBfLnNsaWNlKGNvbmZpZ3MsIDEpLmZvckVhY2goYmMgPT4ge1xuICAgICAgICBjb25zdCBhbHJlYWR5SXMgPSBjbGFzc0NvbmZpZy5tZXRob2RzO1xuICAgICAgICBjb25zdCB0b01lcmdlID0gXy5jbG9uZURlZXAoYmMubWV0aG9kcyk7XG4gICAgICAgIGZvciAoY29uc3Qga2V5IGluIHRvTWVyZ2UpIHtcbiAgICAgICAgICBpZiAodG9NZXJnZS5oYXNPd25Qcm9wZXJ0eShrZXkpICYmICFhbHJlYWR5SXNba2V5XSkge1xuICAgICAgICAgICAgY29uc3QgZWxlbWVudCA9IHRvTWVyZ2Vba2V5XTtcbiAgICAgICAgICAgIGFscmVhZHlJc1trZXldID0gZWxlbWVudDtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH0pO1xuXG4vKiAqL1xuLyogKi9cbiAgXG4gICAgICAgIHRoaXMubG9nSHR0cCAmJlxuICAgICAgICAgIGNvbnNvbGUuZ3JvdXBDb2xsYXBzZWQoXG4gICAgICAgICAgICBgW3Rhb25dW2V4cHJlc3Mtc2VydmVyXSByb3V0ZXMgWyR7Y2xhc3NDb25maWcuY2xhc3NOYW1lfV1gLFxuICAgICAgICAgICk7XG4vKiAqL1xuLyogKi9cbiAgXG5cblxuICAgICAgT2JqZWN0LmtleXMoY2xhc3NDb25maWcubWV0aG9kcykuZm9yRWFjaChtZXRob2ROYW1lID0+IHtcbiAgICAgICAgY29uc3QgbWV0aG9kQ29uZmlnOiBNb2RlbHMuTWV0aG9kQ29uZmlnID1cbiAgICAgICAgICBjbGFzc0NvbmZpZy5tZXRob2RzW21ldGhvZE5hbWVdO1xuXG4gICAgICAgIGNvbnN0IHR5cGU6IE1vZGVscy5IdHRwLlJlc3QuSHR0cE1ldGhvZCA9IG1ldGhvZENvbmZpZy50eXBlO1xuICAgICAgICBjb25zdCBleHByZXNzUGF0aCA9IG1ldGhvZENvbmZpZy5nbG9iYWxcbiAgICAgICAgICA/IGAvJHttZXRob2RDb25maWcucGF0aD8ucmVwbGFjZSgvXFwvLywgJycpfWBcbiAgICAgICAgICA6IFRhb25IZWxwZXJzLmdldEV4cHJlc3NQYXRoKGNsYXNzQ29uZmlnLCBtZXRob2RDb25maWcpO1xuXG5cbiAgICAgICAgaWYgKEhlbHBlcnMuaXNOb2RlIHx8IEhlbHBlcnMuaXNXZWJTUUwpIHtcblxuXG4gICAgICAgICAgY29uc3QgeyByb3V0ZVBhdGgsIG1ldGhvZCB9ID0gdGhpcy5pbml0U2VydmVyKFxuICAgICAgICAgICAgdHlwZSxcbiAgICAgICAgICAgIG1ldGhvZENvbmZpZyxcbiAgICAgICAgICAgIGNsYXNzQ29uZmlnLFxuICAgICAgICAgICAgZXhwcmVzc1BhdGgsXG4gICAgICAgICAgICBjb250cm9sbGVyQ2xhc3NGbixcbiAgICAgICAgICApO1xuXG4gICAgICAgICAgdGhpcy5hY3RpdmVSb3V0ZXMucHVzaCh7XG4gICAgICAgICAgICByb3V0ZVBhdGgsXG4gICAgICAgICAgICBtZXRob2QsXG4gICAgICAgICAgfSk7XG5cbiAgICAgICAgfVxuXG4gICAgICAgIGNvbnN0IHNob3VsZEluaXRDbGllbnQgPVxuICAgICAgICAgIEhlbHBlcnMuaXNCcm93c2VyIHx8IHRoaXMucmVtb3RlSG9zdCB8fCBIZWxwZXJzLmlzV2ViU1FMO1xuXG4gICAgICAgIGlmIChzaG91bGRJbml0Q2xpZW50KSB7XG5cblxuXG5cblxuXG5cbiAgICAgICAgICB0aGlzLmluaXRDbGllbnQoY29udHJvbGxlckNsYXNzRm4sIHR5cGUsIG1ldGhvZENvbmZpZywgZXhwcmVzc1BhdGgpO1xuICAgICAgICB9XG4gICAgICB9KTtcblxuLyogKi9cbi8qICovXG4gIFxuICAgICAgICB0aGlzLmxvZ0h0dHAgJiYgY29uc29sZS5ncm91cEVuZCgpO1xuLyogKi9cbi8qICovXG4gIFxuICAgIH1cbiAgfVxuXG5cblxuICBwdWJsaWMgd3JpdGVBY3RpdmVSb3V0ZXMoKSB7XG4gICAgaWYgKFxuICAgICAgdGhpcy5yZW1vdGVIb3N0IHx8XG4gICAgICB0aGlzLmlzUnVuT3JSZXZlcnRPbmx5TWlncmF0aW9uQXBwU3RhcnQgfHxcbiAgICAgIHRoaXMuc2tpcFdyaXRpbmdTZXJ2ZXJSb3V0ZXNcbiAgICApIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgY29uc3QgY29udGV4dHM6IEVuZHBvaW50Q29udGV4dFtdID0gW3RoaXNdO1xuXG5cbiAgICBjb25zdCB0cm91dGVzID0gVXRpbHMudW5pcUFycmF5KFxuICAgICAgdGhpcy5hY3RpdmVSb3V0ZXMubWFwKGYgPT4ge1xuICAgICAgICByZXR1cm4gYCR7Zi5tZXRob2R9ICR7Zi5yb3V0ZVBhdGh9YDtcbiAgICAgIH0pLFxuICAgICkubWFwKGYgPT4ge1xuICAgICAgY29uc3QgW21ldGhvZCwgcm91dGVQYXRoXSA9IGYuc3BsaXQoJyAnKTtcbiAgICAgIHJldHVybiAoXG4gICAgICAgIGBcXG4jIyMgJHtfLnN0YXJ0Q2FzZShfLmxhc3Qocm91dGVQYXRoLnNwbGl0KCcvJykpKX1cXG5gICtcbiAgICAgICAgVGFvbkhlbHBlcnMuZmlsbFVwVG8obWV0aG9kLnRvVXBwZXJDYXNlKCkgKyAnICcsIDEwKSArXG4gICAgICAgIHRoaXMudXJpLmhyZWYucmVwbGFjZSgvXFwvJC8sICcnKSArXG4gICAgICAgIHJvdXRlUGF0aFxuICAgICAgKTtcblxuXG5cbiAgICB9KTtcbiAgICBjb25zdCByb3V0ZXMgPSBbXG4gICAgICAuLi5bJycsIGAjICBST1VURVMgRk9SIEhPU1QgJHt0aGlzLnVyaS5ocmVmfSBgXSxcbiAgICAgIC4uLnRyb3V0ZXMsXG4gICAgXS5qb2luKCdcXG4nKTtcbiAgICBjb25zdCBmaWxlTmFtZSA9IGNyb3NzUGxhdGZvcm1QYXRoKFtcbi8qICovXG4vKiAqL1xuICBcbiAgICAgIGByb3V0ZXMtJHt0aGlzLmNvbmZpZy5jb250ZXh0TmFtZX0ucmVzdGAsXG4gICAgXSk7XG5cbiAgICB0aGlzLmxvZ0ZyYW1ld29yayAmJiBjb25zb2xlLmxvZyhgW3Rhb25dIHJvdXRlcyBmaWxlOiAke2ZpbGVOYW1lfSBgKTtcblxuLyogKi9cbi8qICovXG4gIFxuXG4gIH1cblxuXG5cbiAgcHVibGljIGdldCBtaWRkbGV3YXJlcygpOiBNb2RlbHMuTWlkZGxld2FyZVR5cGVbXSB7XG4vKiAqL1xuLyogKi9cbiAgICByZXR1cm4gKHZvaWQgMCk7XG4gIH1cblxuXG5cbiAgcHJpdmF0ZSBpbml0TWlkZGxld2FyZXMoKSB7XG4vKiAqL1xuLyogKi9cbi8qICovXG4vKiAqL1xuLyogKi9cbi8qICovXG4vKiAqL1xuLyogKi9cbi8qICovXG4vKiAqL1xuLyogKi9cbi8qICovXG4vKiAqL1xuLyogKi9cbi8qICovXG4vKiAqL1xuLyogKi9cbi8qICovXG4vKiAqL1xuLyogKi9cbi8qICovXG4vKiAqL1xuLyogKi9cbi8qICovXG4vKiAqL1xuLyogKi9cbi8qICovXG4vKiAqL1xuLyogKi9cbi8qICovXG4vKiAqL1xuLyogKi9cbi8qICovXG4vKiAqL1xuLyogKi9cbi8qICovXG4vKiAqL1xuLyogKi9cbi8qICovXG4vKiAqL1xuLyogKi9cbi8qICovXG4vKiAqL1xuLyogKi9cbi8qICovXG4vKiAqL1xuLyogKi9cbi8qICovXG4vKiAqL1xuLyogKi9cbi8qICovXG4vKiAqL1xuLyogKi9cbi8qICovXG4vKiAqL1xuLyogKi9cbi8qICovXG4vKiAqL1xuLyogKi9cbi8qICovXG4vKiAqL1xuLyogKi9cbi8qICovXG4vKiAqL1xuLyogKi9cbi8qICovXG4vKiAqL1xuLyogKi9cbi8qICovXG4vKiAqL1xuLyogKi9cbi8qICovXG4vKiAqL1xuLyogKi9cbi8qICovXG4vKiAqL1xuLyogKi9cbi8qICovXG4vKiAqL1xuLyogKi9cbi8qICovXG4vKiAqL1xuLyogKi9cbi8qICovXG4vKiAqL1xuLyogKi9cbi8qICovXG4vKiAqL1xuLyogKi9cbi8qICovXG4vKiAqL1xuLyogKi9cbi8qICovXG4vKiAqL1xuLyogKi9cbi8qICovXG4vKiAqL1xuLyogKi9cbi8qICovXG4vKiAqL1xuLyogKi9cbi8qICovXG4gIFxuICB9XG5cblxuXG4gIHByaXZhdGUgaW5pdFNlcnZlcihcblxuICAgIHR5cGU6IE1vZGVscy5IdHRwLlJlc3QuSHR0cE1ldGhvZCxcbiAgICBtZXRob2RDb25maWc6IE1vZGVscy5NZXRob2RDb25maWcsXG4gICAgY2xhc3NDb25maWc6IE1vZGVscy5SdW50aW1lQ29udHJvbGxlckNvbmZpZyxcbiAgICBleHByZXNzUGF0aDogc3RyaW5nLFxuICAgIHRhcmdldDogRnVuY3Rpb24sXG5cbiAgKTogYW55IHtcblxuXG4gICAgY29uc3QgcmVxdWVzdEhhbmRsZXIgPVxuICAgICAgbWV0aG9kQ29uZmlnLnJlcXVlc3RIYW5kbGVyICYmXG4gICAgICB0eXBlb2YgbWV0aG9kQ29uZmlnLnJlcXVlc3RIYW5kbGVyID09PSAnZnVuY3Rpb24nXG4gICAgICAgID8gbWV0aG9kQ29uZmlnLnJlcXVlc3RIYW5kbGVyXG4gICAgICAgIDogKHJlcSwgcmVzLCBuZXh0KSA9PiB7XG4gICAgICAgICAgICBuZXh0KCk7XG4gICAgICAgICAgfTtcblxuXG4gICAgY29uc3QgdXJsID0gdGhpcy51cmk7XG5cblxuICAgIGNvbnN0IGdldFJlc3VsdCA9IGFzeW5jIChyZXNvbHZlZFBhcmFtcywgcmVxLCByZXMpID0+IHtcbiAgICAgIGNvbnN0IHJlc3BvbnNlOiBNb2RlbHMuSHR0cC5SZXNwb25zZTxhbnk+ID1cbiAgICAgICAgbWV0aG9kQ29uZmlnLmRlc2NyaXB0b3IudmFsdWUuYXBwbHkoXG4gICAgICAgICAgLyoqXG4gICAgICAgICAgICogQ29udGV4dCBmb3IgbWV0aG9kIEBHRVQsQFBVVCBldGMuXG4gICAgICAgICAgICovXG4gICAgICAgICAgdGhpcy5nZXRJbnN0YW5jZUJ5KHRhcmdldCBhcyBhbnkpLFxuICAgICAgICAgIC8qKlxuICAgICAgICAgICAqIFBhcmFtcyBmb3IgbWV0am9kIEBHRVQsIEBQVVQgZXRjLlxuICAgICAgICAgICAqL1xuICAgICAgICAgIHJlc29sdmVkUGFyYW1zLFxuICAgICAgICApO1xuICAgICAgbGV0IHJlc3VsdCA9IGF3YWl0IGdldFJlc3BvbnNlVmFsdWUocmVzcG9uc2UsIHsgcmVxLCByZXMgfSk7XG4gICAgICByZXR1cm4gcmVzdWx0O1xuICAgIH07XG5cblxuICAgIHVybC5wYXRobmFtZSA9IHVybC5wYXRobmFtZS5yZXBsYWNlKC9cXC8kLywgJycpO1xuICAgIGV4cHJlc3NQYXRoID0gdXJsLnBhdGhuYW1lLnN0YXJ0c1dpdGgoJy8nKVxuICAgICAgPyBgJHt1cmwucGF0aG5hbWV9JHtleHByZXNzUGF0aH1gXG4gICAgICA6IGV4cHJlc3NQYXRoO1xuICAgIGV4cHJlc3NQYXRoID0gZXhwcmVzc1BhdGgucmVwbGFjZSgvXFwvXFwvL2csICcvJyk7XG5cblxuXG4gICAgaWYgKEhlbHBlcnMuaXNFbGVjdHJvbikge1xuLyogKi9cbi8qICovXG4vKiAqL1xuLyogKi9cbi8qICovXG4vKiAqL1xuLyogKi9cbi8qICovXG4vKiAqL1xuLyogKi9cbi8qICovXG4vKiAqL1xuLyogKi9cbi8qICovXG4vKiAqL1xuLyogKi9cbi8qICovXG4vKiAqL1xuLyogKi9cbi8qICovXG4vKiAqL1xuICBcbiAgICB9XG5cbiAgICBpZiAoIXRoaXMucmVtb3RlSG9zdCkge1xuXG5cbiAgICAgIGlmIChIZWxwZXJzLmlzV2ViU1FMKSB7XG4gICAgICAgIGlmICghdGhpcy5leHByZXNzQXBwW3R5cGUudG9Mb3dlckNhc2UoKV0pIHtcbiAgICAgICAgICB0aGlzLmV4cHJlc3NBcHBbdHlwZS50b0xvd2VyQ2FzZSgpXSA9ICgpID0+IHt9O1xuICAgICAgICB9XG4gICAgICB9XG5cblxuXG4vKiAqL1xuLyogKi9cbi8qICovXG4vKiAqL1xuLyogKi9cbi8qICovXG4vKiAqL1xuLyogKi9cbi8qICovXG4vKiAqL1xuLyogKi9cbi8qICovXG4vKiAqL1xuLyogKi9cbi8qICovXG4vKiAqL1xuLyogKi9cbi8qICovXG4vKiAqL1xuLyogKi9cbi8qICovXG4vKiAqL1xuLyogKi9cbi8qICovXG4vKiAqL1xuLyogKi9cbi8qICovXG4vKiAqL1xuLyogKi9cbi8qICovXG4vKiAqL1xuLyogKi9cbi8qICovXG4vKiAqL1xuLyogKi9cbi8qICovXG4vKiAqL1xuLyogKi9cbi8qICovXG4vKiAqL1xuLyogKi9cbi8qICovXG4vKiAqL1xuLyogKi9cbi8qICovXG4vKiAqL1xuLyogKi9cbi8qICovXG4vKiAqL1xuLyogKi9cbi8qICovXG4vKiAqL1xuLyogKi9cbi8qICovXG4vKiAqL1xuLyogKi9cbi8qICovXG4vKiAqL1xuLyogKi9cbi8qICovXG4vKiAqL1xuLyogKi9cbi8qICovXG4vKiAqL1xuLyogKi9cbi8qICovXG4vKiAqL1xuLyogKi9cbi8qICovXG4vKiAqL1xuLyogKi9cbi8qICovXG4vKiAqL1xuLyogKi9cbi8qICovXG4vKiAqL1xuLyogKi9cbi8qICovXG4vKiAqL1xuLyogKi9cbi8qICovXG4vKiAqL1xuLyogKi9cbi8qICovXG4vKiAqL1xuLyogKi9cbi8qICovXG4vKiAqL1xuLyogKi9cbi8qICovXG4vKiAqL1xuLyogKi9cbi8qICovXG4vKiAqL1xuLyogKi9cbi8qICovXG4vKiAqL1xuLyogKi9cbi8qICovXG4vKiAqL1xuLyogKi9cbi8qICovXG4vKiAqL1xuLyogKi9cbi8qICovXG4vKiAqL1xuLyogKi9cbi8qICovXG4vKiAqL1xuLyogKi9cbi8qICovXG4vKiAqL1xuLyogKi9cbi8qICovXG4vKiAqL1xuLyogKi9cbi8qICovXG4vKiAqL1xuLyogKi9cbi8qICovXG4vKiAqL1xuLyogKi9cbi8qICovXG4vKiAqL1xuLyogKi9cbi8qICovXG4vKiAqL1xuLyogKi9cbi8qICovXG4vKiAqL1xuLyogKi9cbi8qICovXG4vKiAqL1xuLyogKi9cbi8qICovXG4vKiAqL1xuLyogKi9cbi8qICovXG4vKiAqL1xuLyogKi9cbi8qICovXG4vKiAqL1xuLyogKi9cbi8qICovXG4vKiAqL1xuLyogKi9cbi8qICovXG4vKiAqL1xuLyogKi9cbi8qICovXG4vKiAqL1xuLyogKi9cbi8qICovXG4vKiAqL1xuLyogKi9cbi8qICovXG4vKiAqL1xuLyogKi9cbi8qICovXG4vKiAqL1xuLyogKi9cbi8qICovXG4vKiAqL1xuLyogKi9cbi8qICovXG4vKiAqL1xuLyogKi9cbi8qICovXG4vKiAqL1xuLyogKi9cbi8qICovXG4vKiAqL1xuLyogKi9cbi8qICovXG4vKiAqL1xuLyogKi9cbi8qICovXG4vKiAqL1xuLyogKi9cbi8qICovXG4vKiAqL1xuLyogKi9cbi8qICovXG4vKiAqL1xuLyogKi9cbi8qICovXG4vKiAqL1xuLyogKi9cbi8qICovXG4vKiAqL1xuLyogKi9cbi8qICovXG4vKiAqL1xuLyogKi9cbi8qICovXG4vKiAqL1xuLyogKi9cbi8qICovXG4vKiAqL1xuLyogKi9cbi8qICovXG4vKiAqL1xuLyogKi9cbi8qICovXG4vKiAqL1xuLyogKi9cbi8qICovXG4vKiAqL1xuLyogKi9cbi8qICovXG4vKiAqL1xuLyogKi9cbi8qICovXG4vKiAqL1xuICBcbiAgICB9XG5cbiAgICByZXR1cm4ge1xuICAgICAgcm91dGVQYXRoOiBleHByZXNzUGF0aCxcbiAgICAgIG1ldGhvZDogbWV0aG9kQ29uZmlnLnR5cGUsXG4gICAgfTtcbiAgfVxuXG5cblxuICAvKipcbiAgICogY2xpZW50IGNhbiBiZSBicm93c2VyIG9yIG5vZGVqcyAod2hlbiByZW1vdGUgaG9zdClcbiAgICovXG4gIHByaXZhdGUgaW5pdENsaWVudChcblxuICAgIHRhcmdldDogRnVuY3Rpb24sXG4gICAgdHlwZTogTW9kZWxzLkh0dHAuUmVzdC5IdHRwTWV0aG9kLFxuICAgIG1ldGhvZENvbmZpZzogTW9kZWxzLkh0dHAuUmVzdC5NZXRob2RDb25maWcsXG4gICAgZXhwcmVzc1BhdGg6IHN0cmluZyxcblxuICApOiB2b2lkIHtcbiAgICBjb25zdCBjdHggPSB0aGlzO1xuXG4gICAgdGhpcy5sb2dIdHRwICYmIGNvbnNvbGUubG9nKGAke3R5cGU/LnRvVXBwZXJDYXNlKCl9ICR7ZXhwcmVzc1BhdGh9IGApO1xuXG5cbiAgICBsZXQgc3RvcmFnZTogYW55O1xuICAgIGlmIChIZWxwZXJzLmlzQnJvd3Nlcikge1xuICAgICAgc3RvcmFnZSA9IHdpbmRvdztcbiAgICB9XG4vKiAqL1xuLyogKi9cbi8qICovXG4vKiAqL1xuICBcblxuXG4gICAgY29uc3Qgb3JnTWV0aG9kcyA9IHRhcmdldC5wcm90b3R5cGVbbWV0aG9kQ29uZmlnLm1ldGhvZE5hbWVdO1xuXG5cblxuICAgIGlmIChIZWxwZXJzLmlzRWxlY3Ryb24pIHtcbiAgICAgIHRhcmdldC5wcm90b3R5cGVbbWV0aG9kQ29uZmlnLm1ldGhvZE5hbWVdID0gZnVuY3Rpb24gKC4uLmFyZ3MpIHtcbiAgICAgICAgY29uc3QgcmVjZWl2ZWQgPSBuZXcgUHJvbWlzZShhc3luYyAocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICAgICAgY29uc3QgaGVhZGVycyA9IHt9O1xuICAgICAgICAgIGNvbnN0IHsgcmVxdWVzdCwgcmVzcG9uc2UgfSA9IFRhb25IZWxwZXJzLndlYnNxbE1vY2tzKGhlYWRlcnMpO1xuXG4gICAgICAgICAgSGVscGVycy5pcGNSZW5kZXJlci5vbmNlKFxuICAgICAgICAgICAgVGFvbkhlbHBlcnMuaXBjS2V5TmFtZVJlc3BvbnNlKHRhcmdldCwgbWV0aG9kQ29uZmlnLCBleHByZXNzUGF0aCksXG4gICAgICAgICAgICAoZXZlbnQsIHJlc3BvbnNlRGF0YSkgPT4ge1xuICAgICAgICAgICAgICBsZXQgcmVzOiBhbnkgPSByZXNwb25zZURhdGE7XG4gICAgICAgICAgICAgIGNvbnNvbGUubG9nKHsgcmVzcG9uc2VEYXRhIH0pO1xuICAgICAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgICAgIGNvbnN0IGJvZHkgPSByZXM7XG4gICAgICAgICAgICAgICAgcmVzID0gbmV3IE1vZGVsc05nMlJlc3QuSHR0cFJlc3BvbnNlKFxuICAgICAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgICAgICBib2R5OiB2b2lkIDAsXG4gICAgICAgICAgICAgICAgICAgIGlzQXJyYXk6IHZvaWQgMCBhcyBhbnksXG4gICAgICAgICAgICAgICAgICAgIG1ldGhvZDogbWV0aG9kQ29uZmlnLnR5cGUsXG4gICAgICAgICAgICAgICAgICAgIHVybDogYCR7Y3R4LnVyaS5vcmlnaW59JHtcbiAgICAgICAgICAgICAgICAgICAgICAnJyAvLyBUT0RPIGV4cHJlc3MgcGF0aFxuICAgICAgICAgICAgICAgICAgICB9JHttZXRob2RDb25maWcucGF0aH0gYCxcbiAgICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgICBIZWxwZXJzLmlzQmxvYihib2R5KSB8fCBfLmlzU3RyaW5nKGJvZHkpXG4gICAgICAgICAgICAgICAgICAgID8gYm9keVxuICAgICAgICAgICAgICAgICAgICA6IEpTT04uc3RyaW5naWZ5KGJvZHkpLFxuICAgICAgICAgICAgICAgICAgUmVzdEhlYWRlcnMuZnJvbShoZWFkZXJzKSxcbiAgICAgICAgICAgICAgICAgIHZvaWQgMCxcbiAgICAgICAgICAgICAgICAgICgpID0+IGJvZHksXG4gICAgICAgICAgICAgICAgKTtcblxuICAgICAgICAgICAgICAgIHJlc29sdmUocmVzKTtcbiAgICAgICAgICAgICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgICAgICAgICAgICBjb25zb2xlLmVycm9yKGVycm9yKTtcbiAgICAgICAgICAgICAgICByZWplY3QoZXJyb3IpO1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9LFxuICAgICAgICAgICk7XG4gICAgICAgICAgSGVscGVycy5pcGNSZW5kZXJlci5zZW5kKFxuICAgICAgICAgICAgVGFvbkhlbHBlcnMuaXBjS2V5TmFtZVJlcXVlc3QodGFyZ2V0LCBtZXRob2RDb25maWcsIGV4cHJlc3NQYXRoKSxcbiAgICAgICAgICAgIGFyZ3MsXG4gICAgICAgICAgKTtcbiAgICAgICAgfSk7XG4gICAgICAgIHJlY2VpdmVkWydvYnNlcnZhYmxlJ10gPSBmcm9tKHJlY2VpdmVkKTtcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICByZWNlaXZlZCxcbiAgICAgICAgfTtcbiAgICAgIH07XG4gICAgICByZXR1cm47XG4gICAgfVxuXG5cblxuXG5cblxuICAgIGNvbnN0IE1JTl9USU1FT1VUID0gNTAwO1xuICAgIGNvbnN0IE1JTl9USU1FT1VUX1NURVAgPSAyMDA7XG4gICAgY29uc3QgdGltZW91dCA9XG4gICAgICB3aW5kb3dbU3ltYm9scy5vbGQuV0VCU1FMX1JFU1RfUFJPR1JFU1NfVElNRU9VVF0gfHwgTUlOX1RJTUVPVVQ7XG5cbiAgICBsZXQgdXBkYXRlRnVuOiBTdWJqZWN0PG51bWJlcj4gPVxuICAgICAgd2luZG93W1N5bWJvbHMub2xkLldFQlNRTF9SRVNUX1BST0dSRVNTX0ZVTl07XG4gICAgaWYgKCF3aW5kb3dbU3ltYm9scy5vbGQuV0VCU1FMX1JFU1RfUFJPR1JFU1NfRlVOXSkge1xuICAgICAgd2luZG93W1N5bWJvbHMub2xkLldFQlNRTF9SRVNUX1BST0dSRVNTX0ZVTl0gPSBuZXcgU3ViamVjdCgpO1xuICAgIH1cbiAgICB1cGRhdGVGdW4gPSB3aW5kb3dbU3ltYm9scy5vbGQuV0VCU1FMX1JFU1RfUFJPR1JFU1NfRlVOXTtcblxuICAgIGxldCBzdGFydEZ1bjogU3ViamVjdDx2b2lkPiA9XG4gICAgICB3aW5kb3dbU3ltYm9scy5vbGQuV0VCU1FMX1JFU1RfUFJPR1JFU1NfRlVOX1NUQVJUXTtcbiAgICBpZiAoIXdpbmRvd1tTeW1ib2xzLm9sZC5XRUJTUUxfUkVTVF9QUk9HUkVTU19GVU5fU1RBUlRdKSB7XG4gICAgICB3aW5kb3dbU3ltYm9scy5vbGQuV0VCU1FMX1JFU1RfUFJPR1JFU1NfRlVOX1NUQVJUXSA9IG5ldyBTdWJqZWN0KCk7XG4gICAgfVxuICAgIHN0YXJ0RnVuID0gd2luZG93W1N5bWJvbHMub2xkLldFQlNRTF9SRVNUX1BST0dSRVNTX0ZVTl9TVEFSVF07XG5cbiAgICBsZXQgZG9uZUZ1bjogU3ViamVjdDx2b2lkPiA9XG4gICAgICB3aW5kb3dbU3ltYm9scy5vbGQuV0VCU1FMX1JFU1RfUFJPR1JFU1NfRlVOX0RPTkVdO1xuICAgIGlmICghd2luZG93W1N5bWJvbHMub2xkLldFQlNRTF9SRVNUX1BST0dSRVNTX0ZVTl9ET05FXSkge1xuICAgICAgd2luZG93W1N5bWJvbHMub2xkLldFQlNRTF9SRVNUX1BST0dSRVNTX0ZVTl9ET05FXSA9IG5ldyBTdWJqZWN0KCk7XG4gICAgfVxuICAgIGRvbmVGdW4gPSB3aW5kb3dbU3ltYm9scy5vbGQuV0VCU1FMX1JFU1RfUFJPR1JFU1NfRlVOX0RPTkVdO1xuXG4gICAgbGV0IHBlcmlvZHNUb1VwZGF0ZSA9IDA7XG4gICAgaWYgKHRpbWVvdXQgPj0gTUlOX1RJTUVPVVQpIHtcbiAgICAgIHBlcmlvZHNUb1VwZGF0ZSA9IE1hdGguZmxvb3IodGltZW91dCAvIE1JTl9USU1FT1VUX1NURVApO1xuICAgIH1cblxuXG5cbiAgICBjb25zdCBwZXJpb2RzID0gYXN5bmMgKCkgPT4ge1xuICAgICAgc3RhcnRGdW4ubmV4dCgpO1xuICAgICAgZm9yIChsZXQgbiA9IDE7IG4gPD0gcGVyaW9kc1RvVXBkYXRlOyBuKyspIHtcblxuXG5cbiAgICAgICAgbGV0IHVwVmFsdWUgPSBNYXRoLnJvdW5kKCgoTUlOX1RJTUVPVVRfU1RFUCAqIG4pIC8gdGltZW91dCkgKiAxMDApO1xuICAgICAgICBpZiAodXBWYWx1ZSA+IDEwMCkge1xuICAgICAgICAgIHVwVmFsdWUgPSAxMDA7XG4gICAgICAgIH1cblxuICAgICAgICB1cGRhdGVGdW4ubmV4dCh1cFZhbHVlKTtcblxuICAgICAgICBhd2FpdCBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICAgICAgc2V0VGltZW91dCgoKSA9PiB7XG4gICAgICAgICAgICByZXNvbHZlKHZvaWQgMCk7XG4gICAgICAgICAgfSwgTUlOX1RJTUVPVVRfU1RFUCk7XG4gICAgICAgIH0pO1xuXG4gICAgICB9XG4gICAgICBkb25lRnVuLm5leHQoKTtcbiAgICB9O1xuXG5cbiAgICB0YXJnZXQucHJvdG90eXBlW21ldGhvZENvbmZpZy5tZXRob2ROYW1lXSA9IGZ1bmN0aW9uICguLi5hcmdzKSB7XG5cblxuXG4gICAgICBjb25zdCByZWNlaXZlZCA9IG5ldyBQcm9taXNlKGFzeW5jIChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICAgICAgY29uc3QgaGVhZGVycyA9IHt9O1xuICAgICAgICBjb25zdCB7IHJlcXVlc3QsIHJlc3BvbnNlIH0gPSBUYW9uSGVscGVycy53ZWJzcWxNb2NrcyhoZWFkZXJzKTtcblxuICAgICAgICBsZXQgcmVzOiBhbnk7XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgcmVzID0gYXdhaXQgSGVscGVycy5ydW5TeW5jT3JBc3luYyh7XG4gICAgICAgICAgICBmdW5jdGlvbkZuOiBvcmdNZXRob2RzLFxuICAgICAgICAgICAgY29udGV4dDogdGhpcyxcbiAgICAgICAgICAgIGFycmF5T2ZQYXJhbXM6IGFyZ3MsXG4gICAgICAgICAgfSk7XG5cbiAgICAgICAgICBpZiAodHlwZW9mIHJlcyA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgICAgICAgcmVzID0gYXdhaXQgSGVscGVycy5ydW5TeW5jT3JBc3luYyh7XG4gICAgICAgICAgICAgIGZ1bmN0aW9uRm46IHJlcyxcbiAgICAgICAgICAgICAgY29udGV4dDogdGhpcyxcbiAgICAgICAgICAgICAgYXJyYXlPZlBhcmFtczogW3JlcXVlc3QsIHJlc3BvbnNlXSxcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIGlmICh0eXBlb2YgcmVzID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICAgICAgICByZXMgPSBhd2FpdCBIZWxwZXJzLnJ1blN5bmNPckFzeW5jKHtcbiAgICAgICAgICAgICAgZnVuY3Rpb25GbjogcmVzLFxuICAgICAgICAgICAgICBjb250ZXh0OiB0aGlzLFxuICAgICAgICAgICAgICBhcnJheU9mUGFyYW1zOiBbcmVxdWVzdCwgcmVzcG9uc2VdLFxuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgfVxuXG5cbiAgICAgICAgICBpZiAodHlwZW9mIHJlcyA9PT0gJ29iamVjdCcgJiYgcmVzPy5yZWNlaXZlZCkge1xuICAgICAgICAgICAgcmVzID0gYXdhaXQgcmVzLnJlY2VpdmVkO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIGNvbnN0IGJvZHkgPSByZXM7XG5cbiAgICAgICAgICByZXMgPSBuZXcgTW9kZWxzTmcyUmVzdC5IdHRwUmVzcG9uc2UoXG4gICAgICAgICAgICB7XG4gICAgICAgICAgICAgIGJvZHk6IHZvaWQgMCxcbiAgICAgICAgICAgICAgaXNBcnJheTogdm9pZCAwIGFzIGFueSxcbiAgICAgICAgICAgICAgbWV0aG9kOiBtZXRob2RDb25maWcudHlwZSxcbiAgICAgICAgICAgICAgdXJsOiBgJHtjdHgudXJpLm9yaWdpbn0ke1xuICAgICAgICAgICAgICAgICcnIC8vIFRPRE8gZXhwcmVzcyBwYXRoXG4gICAgICAgICAgICAgIH0ke21ldGhvZENvbmZpZy5wYXRofSBgLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIEhlbHBlcnMuaXNCbG9iKGJvZHkpIHx8IF8uaXNTdHJpbmcoYm9keSlcbiAgICAgICAgICAgICAgPyBib2R5XG4gICAgICAgICAgICAgIDogSlNPTi5zdHJpbmdpZnkoYm9keSksXG4gICAgICAgICAgICBSZXN0SGVhZGVycy5mcm9tKGhlYWRlcnMpLFxuICAgICAgICAgICAgdm9pZCAwLFxuICAgICAgICAgICAgKCkgPT4gYm9keSxcbiAgICAgICAgICApO1xuXG5cblxuXG5cbiAgICAgICAgICBhd2FpdCBwZXJpb2RzKCk7XG4gICAgICAgICAgcmVzb2x2ZShyZXMpO1xuICAgICAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgICAgIGF3YWl0IHBlcmlvZHMoKTtcbiAgICAgICAgICBjb25zb2xlLmVycm9yKGVycm9yKTtcblxuXG5cbiAgICAgICAgICByZWplY3QoZXJyb3IpO1xuICAgICAgICB9XG4gICAgICB9KTtcbiAgICAgIHJlY2VpdmVkWydvYnNlcnZhYmxlJ10gPSBmcm9tKHJlY2VpdmVkKTtcblxuICAgICAgaWYgKEhlbHBlcnMuaXNXZWJTUUwpIHtcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICByZWNlaXZlZCxcbiAgICAgICAgfTtcbiAgICAgIH1cbiAgICB9O1xuICAgIGlmIChIZWxwZXJzLmlzV2ViU1FMKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG5cblxuXG5cbiAgICB0YXJnZXQucHJvdG90eXBlW21ldGhvZENvbmZpZy5tZXRob2ROYW1lXSA9IGZ1bmN0aW9uICh0aGlzOiB7fSwgLi4uYXJncykge1xuXG5cblxuXG5cbiAgICAgIGlmICghc3RvcmFnZVtTeW1ib2xzLm9sZC5FTkRQT0lOVF9NRVRBX0NPTkZJR10pXG4gICAgICAgIHN0b3JhZ2VbU3ltYm9scy5vbGQuRU5EUE9JTlRfTUVUQV9DT05GSUddID0ge307XG4gICAgICBpZiAoIXN0b3JhZ2VbU3ltYm9scy5vbGQuRU5EUE9JTlRfTUVUQV9DT05GSUddW2N0eC51cmkuaHJlZl0pXG4gICAgICAgIHN0b3JhZ2VbU3ltYm9scy5vbGQuRU5EUE9JTlRfTUVUQV9DT05GSUddW2N0eC51cmkuaHJlZl0gPSB7fTtcbiAgICAgIGNvbnN0IGVuZHBvaW50cyA9IHN0b3JhZ2VbU3ltYm9scy5vbGQuRU5EUE9JTlRfTUVUQV9DT05GSUddO1xuICAgICAgbGV0IHJlc3Q6IE1vZGVsc05nMlJlc3QuUmVzb3VyY2VNb2RlbDxhbnksIGFueT47XG4gICAgICBpZiAoIWVuZHBvaW50c1tjdHgudXJpLmhyZWZdW2V4cHJlc3NQYXRoXSkge1xuICAgICAgICBsZXQgaGVhZGVycyA9IHt9O1xuICAgICAgICBpZiAobWV0aG9kQ29uZmlnLmNvbnRlbnRUeXBlICYmICFtZXRob2RDb25maWcucmVzcG9uc2VUeXBlKSB7XG4gICAgICAgICAgcmVzdCA9IFJlc291cmNlLmNyZWF0ZShcbiAgICAgICAgICAgIGN0eC51cmkuaHJlZixcbiAgICAgICAgICAgIGV4cHJlc3NQYXRoLFxuICAgICAgICAgICAgU3ltYm9scy5vbGQuTUFQUElOR19DT05GSUdfSEVBREVSIGFzIGFueSxcbiAgICAgICAgICAgIFN5bWJvbHMub2xkLkNJUkNVUkFMX09CSkVDVFNfTUFQX0JPRFkgYXMgYW55LFxuICAgICAgICAgICAgUmVzdEhlYWRlcnMuZnJvbSh7XG4gICAgICAgICAgICAgICdDb250ZW50LVR5cGUnOiBtZXRob2RDb25maWcuY29udGVudFR5cGUsXG4gICAgICAgICAgICAgIEFjY2VwdDogbWV0aG9kQ29uZmlnLmNvbnRlbnRUeXBlLFxuICAgICAgICAgICAgfSksXG4gICAgICAgICAgKTtcbiAgICAgICAgfSBlbHNlIGlmIChtZXRob2RDb25maWcuY29udGVudFR5cGUgJiYgbWV0aG9kQ29uZmlnLnJlc3BvbnNlVHlwZSkge1xuICAgICAgICAgIHJlc3QgPSBSZXNvdXJjZS5jcmVhdGUoXG4gICAgICAgICAgICBjdHgudXJpLmhyZWYsXG4gICAgICAgICAgICBleHByZXNzUGF0aCxcbiAgICAgICAgICAgIFN5bWJvbHMub2xkLk1BUFBJTkdfQ09ORklHX0hFQURFUiBhcyBhbnksXG4gICAgICAgICAgICBTeW1ib2xzLm9sZC5DSVJDVVJBTF9PQkpFQ1RTX01BUF9CT0RZIGFzIGFueSxcbiAgICAgICAgICAgIFJlc3RIZWFkZXJzLmZyb20oe1xuICAgICAgICAgICAgICAnQ29udGVudC1UeXBlJzogbWV0aG9kQ29uZmlnLmNvbnRlbnRUeXBlLFxuICAgICAgICAgICAgICBBY2NlcHQ6IG1ldGhvZENvbmZpZy5jb250ZW50VHlwZSxcbiAgICAgICAgICAgICAgcmVzcG9uc2V0eXBlYXhpb3M6IG1ldGhvZENvbmZpZy5yZXNwb25zZVR5cGUsXG4gICAgICAgICAgICB9KSxcbiAgICAgICAgICApO1xuICAgICAgICB9IGVsc2UgaWYgKCFtZXRob2RDb25maWcuY29udGVudFR5cGUgJiYgbWV0aG9kQ29uZmlnLnJlc3BvbnNlVHlwZSkge1xuICAgICAgICAgIHJlc3QgPSBSZXNvdXJjZS5jcmVhdGUoXG4gICAgICAgICAgICBjdHgudXJpLmhyZWYsXG4gICAgICAgICAgICBleHByZXNzUGF0aCxcbiAgICAgICAgICAgIFN5bWJvbHMub2xkLk1BUFBJTkdfQ09ORklHX0hFQURFUiBhcyBhbnksXG4gICAgICAgICAgICBTeW1ib2xzLm9sZC5DSVJDVVJBTF9PQkpFQ1RTX01BUF9CT0RZIGFzIGFueSxcbiAgICAgICAgICAgIFJlc3RIZWFkZXJzLmZyb20oe1xuICAgICAgICAgICAgICByZXNwb25zZXR5cGVheGlvczogbWV0aG9kQ29uZmlnLnJlc3BvbnNlVHlwZSxcbiAgICAgICAgICAgIH0pLFxuICAgICAgICAgICk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgcmVzdCA9IFJlc291cmNlLmNyZWF0ZShcbiAgICAgICAgICAgIGN0eC51cmkuaHJlZixcbiAgICAgICAgICAgIGV4cHJlc3NQYXRoLFxuICAgICAgICAgICAgU3ltYm9scy5vbGQuTUFQUElOR19DT05GSUdfSEVBREVSIGFzIGFueSxcbiAgICAgICAgICAgIFN5bWJvbHMub2xkLkNJUkNVUkFMX09CSkVDVFNfTUFQX0JPRFkgYXMgYW55LFxuICAgICAgICAgICk7XG4gICAgICAgIH1cblxuICAgICAgICBlbmRwb2ludHNbY3R4LnVyaS5ocmVmXVtleHByZXNzUGF0aF0gPSByZXN0O1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgcmVzdCA9IGVuZHBvaW50c1tjdHgudXJpLmhyZWZdW2V4cHJlc3NQYXRoXSBhcyBhbnk7XG4gICAgICB9XG5cbiAgICAgIGNvbnN0IG1ldGhvZCA9IHR5cGUudG9Mb3dlckNhc2UoKTtcbiAgICAgIGNvbnN0IGlzV2l0aEJvZHkgPSBtZXRob2QgPT09ICdwdXQnIHx8IG1ldGhvZCA9PT0gJ3Bvc3QnO1xuICAgICAgY29uc3QgcGF0aFByYW1zID0ge307XG4gICAgICBsZXQgcXVlcnlQYXJhbXMgPSB7fTtcbiAgICAgIGxldCBib2R5T2JqZWN0ID0ge307XG4gICAgICBhcmdzLmZvckVhY2goKHBhcmFtLCBpKSA9PiB7XG4gICAgICAgIGxldCBjdXJyZW50UGFyYW06IE1vZGVscy5IdHRwLlJlc3QuUGFyYW1Db25maWcgPSB2b2lkIDAgYXMgYW55O1xuXG4gICAgICAgIGZvciAobGV0IHBwIGluIG1ldGhvZENvbmZpZy5wYXJhbWV0ZXJzKSB7XG4gICAgICAgICAgbGV0IHYgPSBtZXRob2RDb25maWcucGFyYW1ldGVyc1twcF07XG4gICAgICAgICAgaWYgKHYuaW5kZXggPT09IGkpIHtcbiAgICAgICAgICAgIGN1cnJlbnRQYXJhbSA9IHY7XG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoY3VycmVudFBhcmFtLnBhcmFtVHlwZSA9PT0gJ1BhdGgnKSB7XG4gICAgICAgICAgcGF0aFByYW1zW2N1cnJlbnRQYXJhbS5wYXJhbU5hbWVdID0gcGFyYW07XG4gICAgICAgIH1cbiAgICAgICAgaWYgKGN1cnJlbnRQYXJhbS5wYXJhbVR5cGUgPT09ICdRdWVyeScpIHtcbiAgICAgICAgICBpZiAoY3VycmVudFBhcmFtLnBhcmFtTmFtZSkge1xuICAgICAgICAgICAgY29uc3QgbWFwcGluZyA9IE1hcHBpbmcuZGVjb2RlKHBhcmFtLCAhY3R4LmlzUHJvZHVjdGlvbk1vZGUpO1xuICAgICAgICAgICAgaWYgKG1hcHBpbmcpIHtcbiAgICAgICAgICAgICAgcmVzdC5oZWFkZXJzLnNldChcbiAgICAgICAgICAgICAgICBgJHtTeW1ib2xzLm9sZC5NQVBQSU5HX0NPTkZJR19IRUFERVJfUVVFUllfUEFSQU1TfSR7Y3VycmVudFBhcmFtLnBhcmFtTmFtZX0gYCxcbiAgICAgICAgICAgICAgICBKU09OLnN0cmluZ2lmeShtYXBwaW5nKSxcbiAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHF1ZXJ5UGFyYW1zW2N1cnJlbnRQYXJhbS5wYXJhbU5hbWVdID0gcGFyYW07XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGNvbnN0IG1hcHBpbmcgPSBNYXBwaW5nLmRlY29kZShwYXJhbSwgIWN0eC5pc1Byb2R1Y3Rpb25Nb2RlKTtcbiAgICAgICAgICAgIGlmIChtYXBwaW5nKSB7XG4gICAgICAgICAgICAgIHJlc3QuaGVhZGVycy5zZXQoXG4gICAgICAgICAgICAgICAgU3ltYm9scy5vbGQuTUFQUElOR19DT05GSUdfSEVBREVSX1FVRVJZX1BBUkFNUyxcbiAgICAgICAgICAgICAgICBKU09OLnN0cmluZ2lmeShtYXBwaW5nKSxcbiAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHF1ZXJ5UGFyYW1zID0gXy5jbG9uZURlZXAocGFyYW0pO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBpZiAoY3VycmVudFBhcmFtLnBhcmFtVHlwZSA9PT0gJ0hlYWRlcicpIHtcbiAgICAgICAgICBpZiAoY3VycmVudFBhcmFtLnBhcmFtTmFtZSkge1xuICAgICAgICAgICAgaWYgKGN1cnJlbnRQYXJhbS5wYXJhbU5hbWUgPT09IFN5bWJvbHMub2xkLk1EQ19LRVkpIHtcblxuICAgICAgICAgICAgICByZXN0LmhlYWRlcnMuc2V0KFxuICAgICAgICAgICAgICAgIGN1cnJlbnRQYXJhbS5wYXJhbU5hbWUsXG4gICAgICAgICAgICAgICAgZW5jb2RlVVJJQ29tcG9uZW50KEpTT04uc3RyaW5naWZ5KHBhcmFtKSksXG4gICAgICAgICAgICAgICk7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICByZXN0LmhlYWRlcnMuc2V0KGN1cnJlbnRQYXJhbS5wYXJhbU5hbWUsIHBhcmFtKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgZm9yIChsZXQgaGVhZGVyIGluIHBhcmFtKSB7XG4gICAgICAgICAgICAgIHJlc3QuaGVhZGVycy5zZXQoaGVhZGVyLCBwYXJhbVtoZWFkZXJdKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgaWYgKGN1cnJlbnRQYXJhbS5wYXJhbVR5cGUgPT09ICdDb29raWUnKSB7XG4gICAgICAgICAgUmVzb3VyY2UuQ29va2llcy53cml0ZShcbiAgICAgICAgICAgIGN1cnJlbnRQYXJhbS5wYXJhbU5hbWUsXG4gICAgICAgICAgICBwYXJhbSxcbiAgICAgICAgICAgIGN1cnJlbnRQYXJhbS5leHBpcmVJblNlY29uZHMsXG4gICAgICAgICAgKTtcbiAgICAgICAgfVxuICAgICAgICBpZiAoY3VycmVudFBhcmFtLnBhcmFtVHlwZSA9PT0gJ0JvZHknKSB7XG4gICAgICAgICAgaWYgKGN1cnJlbnRQYXJhbS5wYXJhbU5hbWUpIHtcbiAgICAgICAgICAgIGlmIChDbGFzc0hlbHBlcnMuZ2V0TmFtZShib2R5T2JqZWN0KSA9PT0gJ0Zvcm1EYXRhJykge1xuICAgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYFt0YW9uIC0gZnJhbWV3b3JrXSBEb24gdXNlIHBhcmFtIG5hbWVzIHdoZW4gcG9zdGluZyAvIHB1dHRpbmcgRm9ybURhdGEuXG4gICAgICAgICAgICAgIFVzZSB0aGlzOlxuXG4oQFRhb24uSHR0cC5QYXJhbS5Cb2R5KCkgZm9ybURhdGE6IEZvcm1EYXRhKSAuLi5cblxuXG5pbnN0ZWFkXG5cbiAgKEBUYW9uLkh0dHAuUGFyYW0uQm9keSgnJHtjdXJyZW50UGFyYW0ucGFyYW1OYW1lfScpIGZvcm1EYXRhOiBGb3JtRGF0YSkgLi4uXG5cbmApO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgY29uc3QgbWFwcGluZyA9IE1hcHBpbmcuZGVjb2RlKHBhcmFtLCAhY3R4LmlzUHJvZHVjdGlvbk1vZGUpO1xuICAgICAgICAgICAgaWYgKG1hcHBpbmcpIHtcbiAgICAgICAgICAgICAgcmVzdC5oZWFkZXJzLnNldChcbiAgICAgICAgICAgICAgICBgJHtTeW1ib2xzLm9sZC5NQVBQSU5HX0NPTkZJR19IRUFERVJfQk9EWV9QQVJBTVN9JHtjdXJyZW50UGFyYW0ucGFyYW1OYW1lfSBgLFxuICAgICAgICAgICAgICAgIEpTT04uc3RyaW5naWZ5KG1hcHBpbmcpLFxuICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgYm9keU9iamVjdFtjdXJyZW50UGFyYW0ucGFyYW1OYW1lXSA9IHBhcmFtO1xuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBjb25zdCBtYXBwaW5nID0gTWFwcGluZy5kZWNvZGUocGFyYW0sICFjdHguaXNQcm9kdWN0aW9uTW9kZSk7XG4gICAgICAgICAgICBpZiAobWFwcGluZykge1xuICAgICAgICAgICAgICByZXN0LmhlYWRlcnMuc2V0KFxuICAgICAgICAgICAgICAgIFN5bWJvbHMub2xkLk1BUFBJTkdfQ09ORklHX0hFQURFUl9CT0RZX1BBUkFNUyxcbiAgICAgICAgICAgICAgICBKU09OLnN0cmluZ2lmeShtYXBwaW5nKSxcbiAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGJvZHlPYmplY3QgPSBwYXJhbTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH0pO1xuXG4gICAgICBpZiAoXG4gICAgICAgIHR5cGVvZiBib2R5T2JqZWN0ID09PSAnb2JqZWN0JyAmJlxuICAgICAgICBDbGFzc0hlbHBlcnMuZ2V0TmFtZShib2R5T2JqZWN0KSAhPT0gJ0Zvcm1EYXRhJ1xuICAgICAgKSB7XG4gICAgICAgIGxldCBjaXJjdXJhbEZyb21JdGVtID0gW107XG4gICAgICAgIGJvZHlPYmplY3QgPSBKU09OMTAucGFyc2UoXG4gICAgICAgICAgSlNPTjEwLnN0cmluZ2lmeShib2R5T2JqZWN0LCB2b2lkIDAsIHZvaWQgMCwgY2lyY3MgPT4ge1xuICAgICAgICAgICAgY2lyY3VyYWxGcm9tSXRlbSA9IGNpcmNzO1xuICAgICAgICAgIH0pLFxuICAgICAgICApO1xuICAgICAgICByZXN0LmhlYWRlcnMuc2V0KFxuICAgICAgICAgIFN5bWJvbHMub2xkLkNJUkNVUkFMX09CSkVDVFNfTUFQX0JPRFksXG4gICAgICAgICAgSlNPTjEwLnN0cmluZ2lmeShjaXJjdXJhbEZyb21JdGVtKSxcbiAgICAgICAgKTtcbiAgICAgIH1cblxuICAgICAgaWYgKHR5cGVvZiBxdWVyeVBhcmFtcyA9PT0gJ29iamVjdCcpIHtcbiAgICAgICAgbGV0IGNpcmN1cmFsRnJvbVF1ZXJ5UGFyYW1zID0gW107XG4gICAgICAgIHF1ZXJ5UGFyYW1zID0gSlNPTjEwLnBhcnNlKFxuICAgICAgICAgIEpTT04xMC5zdHJpbmdpZnkocXVlcnlQYXJhbXMsIHZvaWQgMCwgdm9pZCAwLCBjaXJjcyA9PiB7XG4gICAgICAgICAgICBjaXJjdXJhbEZyb21RdWVyeVBhcmFtcyA9IGNpcmNzO1xuICAgICAgICAgIH0pLFxuICAgICAgICApO1xuXG4gICAgICAgIHJlc3QuaGVhZGVycy5zZXQoXG4gICAgICAgICAgU3ltYm9scy5vbGQuQ0lSQ1VSQUxfT0JKRUNUU19NQVBfUVVFUllfUEFSQU0sXG4gICAgICAgICAgSlNPTjEwLnN0cmluZ2lmeShjaXJjdXJhbEZyb21RdWVyeVBhcmFtcyksXG4gICAgICAgICk7XG4gICAgICB9XG5cblxuICAgICAgY29uc3QgaHR0cFJlc3VsdE9iaiA9IHtcbiAgICAgICAgcmVjZWl2ZWQ6IGlzV2l0aEJvZHlcbiAgICAgICAgICA/IHJlc3QubW9kZWwocGF0aFByYW1zKVttZXRob2RdKGJvZHlPYmplY3QsIFtxdWVyeVBhcmFtc10pXG4gICAgICAgICAgOiByZXN0Lm1vZGVsKHBhdGhQcmFtcylbbWV0aG9kXShbcXVlcnlQYXJhbXNdKSxcbiAgICAgIH07XG4gICAgICByZXR1cm4gaHR0cFJlc3VsdE9iajtcbiAgICB9O1xuXG4gIH1cblxufVxuXG4gOyh7fSk7IC8vIEAtLWVuZC1vZi1maWxlLWZvci1tb2R1bGU9dGFvbiBsaWIvZW5kcG9pbnQtY29udGV4dC50cyJdfQ==