@sumaris-net/ngx-components 2.0.0-rc3 → 2.0.0-rc31

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 (338) hide show
  1. package/README.md +3 -1
  2. package/doc/changelog.md +13 -0
  3. package/esm2020/public_api.mjs +72 -61
  4. package/esm2020/src/app/admin/admin-routing.module.mjs +6 -6
  5. package/esm2020/src/app/admin/admin.module.mjs +6 -6
  6. package/esm2020/src/app/admin/services/person.service.mjs +3 -3
  7. package/esm2020/src/app/admin/services/validator/person.validator.mjs +3 -3
  8. package/esm2020/src/app/admin/users/users.mjs +233 -0
  9. package/esm2020/src/app/admin/users/users.module.mjs +54 -0
  10. package/esm2020/src/app/core/about/about.modal.mjs +71 -0
  11. package/esm2020/src/app/core/about/about.module.mjs +34 -0
  12. package/esm2020/src/app/core/account/account.module.mjs +43 -0
  13. package/esm2020/src/app/core/account/account.page.mjs +239 -0
  14. package/esm2020/src/app/core/auth/auth.form.mjs +131 -0
  15. package/esm2020/src/app/core/auth/auth.modal.mjs +72 -0
  16. package/esm2020/src/app/core/auth/auth.module.mjs +47 -0
  17. package/esm2020/src/app/core/core.module.mjs +86 -125
  18. package/esm2020/src/app/core/core.testing.module.mjs +7 -7
  19. package/esm2020/src/app/core/form/{form-buttons-bar.component.mjs → buttons/form-buttons-bar.component.mjs} +7 -7
  20. package/esm2020/src/app/core/form/buttons/form-buttons-bar.module.mjs +35 -0
  21. package/esm2020/src/app/core/form/entity/editor.class.mjs +675 -0
  22. package/esm2020/src/app/core/form/entity/entity-editor-modal.class.mjs +421 -0
  23. package/esm2020/src/app/core/form/entity/entity-editor.class.mjs +646 -0
  24. package/esm2020/src/app/core/form/{entity-metadata.component.mjs → entity/entity-metadata.component.mjs} +6 -6
  25. package/esm2020/src/app/core/form/entity/entity.module.mjs +38 -0
  26. package/esm2020/src/app/core/form/form.class.mjs +7 -4
  27. package/esm2020/src/app/core/form/form.module.mjs +66 -0
  28. package/esm2020/src/app/core/form/form.utils.mjs +3 -3
  29. package/esm2020/src/app/core/form/list/list.form.mjs +222 -0
  30. package/esm2020/src/app/core/form/list/list.module.mjs +35 -0
  31. package/esm2020/src/app/core/form/properties/properties.form.mjs +3 -3
  32. package/esm2020/src/app/core/form/properties/properties.module.mjs +35 -0
  33. package/esm2020/src/app/core/form/properties/property.validator.mjs +3 -3
  34. package/esm2020/src/app/core/form/properties/testing/properties-form.test.mjs +3 -3
  35. package/esm2020/src/app/core/form/properties/testing/properties-form.testing.module.mjs +4 -4
  36. package/esm2020/src/app/core/{text-popover → form/text-popover}/testing/text-popover.testing.mjs +4 -4
  37. package/esm2020/src/app/core/form/text-popover/testing/text-popover.testing.module.mjs +45 -0
  38. package/esm2020/src/app/core/{text-popover → form/text-popover}/text-form.component.mjs +8 -8
  39. package/esm2020/src/app/core/{text-popover → form/text-popover}/text-popover.component.mjs +6 -6
  40. package/esm2020/src/app/core/form/text-popover/text-popover.module.mjs +40 -0
  41. package/esm2020/src/app/core/graphql/graphql.module.mjs +4 -4
  42. package/esm2020/src/app/core/graphql/graphql.service.mjs +3 -3
  43. package/esm2020/src/app/core/graphql/graphql.utils.mjs +3 -2
  44. package/esm2020/src/app/core/home/home.mjs +8 -8
  45. package/esm2020/src/app/core/home/home.module.mjs +48 -0
  46. package/esm2020/src/app/core/icon/icon.component.mjs +5 -5
  47. package/esm2020/src/app/core/icon/icon.module.mjs +4 -4
  48. package/esm2020/src/app/core/install/install-upgrade-card.component.mjs +3 -3
  49. package/esm2020/src/app/core/install/install-upgrade-card.module.mjs +17 -15
  50. package/esm2020/src/app/core/menu/menu.component.mjs +5 -5
  51. package/esm2020/src/app/core/menu/menu.module.mjs +9 -10
  52. package/esm2020/src/app/core/menu/menu.service.mjs +3 -3
  53. package/esm2020/src/app/core/offline/update-offline-mode-card.component.mjs +4 -4
  54. package/esm2020/src/app/core/offline/update-offline-mode-card.module.mjs +35 -0
  55. package/esm2020/src/app/core/peer/select-peer.modal.mjs +4 -4
  56. package/esm2020/src/app/core/peer/select-peer.module.mjs +14 -10
  57. package/esm2020/src/app/core/register/register-confirm.page.mjs +81 -0
  58. package/esm2020/src/app/core/register/register.form.mjs +181 -0
  59. package/esm2020/src/app/core/register/register.modal.mjs +52 -0
  60. package/esm2020/src/app/core/register/register.module.mjs +17 -15
  61. package/esm2020/src/app/core/services/account.service.mjs +20 -21
  62. package/esm2020/src/app/core/services/auth-guard.service.mjs +6 -6
  63. package/esm2020/src/app/core/services/base-entity-service.class.mjs +3 -3
  64. package/esm2020/src/app/core/services/base-graphql-service.class.mjs +8 -8
  65. package/esm2020/src/app/core/services/base58.mjs +2 -2
  66. package/esm2020/src/app/core/services/config.service.mjs +3 -3
  67. package/esm2020/src/app/core/services/crypto.service.mjs +82 -97
  68. package/esm2020/src/app/core/services/local-settings.service.mjs +8 -10
  69. package/esm2020/src/app/core/services/model/referential.model.mjs +11 -3
  70. package/esm2020/src/app/core/services/network.service.mjs +4 -4
  71. package/esm2020/src/app/core/services/pipes/account.pipes.mjs +8 -8
  72. package/esm2020/src/app/core/services/pipes/department-to-string.pipe.mjs +4 -4
  73. package/esm2020/src/app/core/services/pipes/person-to-string.pipe.mjs +4 -4
  74. package/esm2020/src/app/core/services/pipes/usage-mode.pipes.mjs +8 -8
  75. package/esm2020/src/app/core/services/platform.service.mjs +9 -10
  76. package/esm2020/src/app/core/services/storage/entities-storage.service.mjs +3 -3
  77. package/esm2020/src/app/core/services/testing/referential.validator.mjs +3 -3
  78. package/esm2020/src/app/core/services/validator/account.validator.mjs +3 -3
  79. package/esm2020/src/app/core/services/validator/base.validator.class.mjs +3 -3
  80. package/esm2020/src/app/core/services/validator/local-settings.validator.mjs +3 -3
  81. package/esm2020/src/app/core/services/validator/user-settings.validator.mjs +3 -3
  82. package/esm2020/src/app/core/settings/settings.module.mjs +34 -0
  83. package/esm2020/src/app/core/settings/settings.page.mjs +4 -4
  84. package/esm2020/src/app/core/table/actions-column.component.mjs +4 -4
  85. package/esm2020/src/app/core/table/entities-table-datasource.class.mjs +4 -4
  86. package/esm2020/src/app/core/table/memory-table.class.mjs +3 -3
  87. package/esm2020/src/app/core/table/table-select-columns.component.mjs +3 -3
  88. package/esm2020/src/app/core/table/table.class.mjs +157 -162
  89. package/esm2020/src/app/core/table/table.module.mjs +40 -0
  90. package/esm2020/src/app/core/table/testing/table.testing.mjs +7 -7
  91. package/esm2020/src/app/core/table/testing/table.testing.module.mjs +4 -4
  92. package/esm2020/src/app/shared/audio/audio.mjs +3 -3
  93. package/esm2020/src/app/shared/audio/audio.testing.mjs +3 -3
  94. package/esm2020/src/app/shared/audio/audio.testing.module.mjs +4 -4
  95. package/esm2020/src/app/shared/capacitor/keyboard.mjs +3 -3
  96. package/esm2020/src/app/shared/dates.mjs +32 -14
  97. package/esm2020/src/app/shared/debug/debug.component.mjs +3 -3
  98. package/esm2020/src/app/shared/debug/debug.module.mjs +4 -4
  99. package/esm2020/src/app/shared/directives/autofocus.directive.mjs +3 -3
  100. package/esm2020/src/app/shared/directives/autotitle.directive.mjs +3 -3
  101. package/esm2020/src/app/shared/directives/directives.module.mjs +4 -4
  102. package/esm2020/src/app/shared/directives/drag-and-drop.directive.mjs +3 -3
  103. package/esm2020/src/app/shared/directives/ng-var.directive.mjs +3 -3
  104. package/esm2020/src/app/shared/directives/resizable/resizable.component.mjs +3 -3
  105. package/esm2020/src/app/shared/directives/resizable/resizable.directive.mjs +3 -3
  106. package/esm2020/src/app/shared/directives/resizable/resizable.module.mjs +4 -4
  107. package/esm2020/src/app/shared/events.mjs +2 -2
  108. package/esm2020/src/app/shared/file/file.service.mjs +6 -5
  109. package/esm2020/src/app/shared/form/field.component.mjs +3 -3
  110. package/esm2020/src/app/shared/form/loading-spinner.mjs +3 -3
  111. package/esm2020/src/app/shared/gesture/gesture-config.mjs +3 -3
  112. package/esm2020/src/app/shared/graph/graph-colors.mjs +17 -63
  113. package/esm2020/src/app/shared/guard/component-dirty.guard.mjs +3 -3
  114. package/esm2020/src/app/shared/help/help.modal.mjs +3 -3
  115. package/esm2020/src/app/shared/hotkeys/dialog/hotkeys-dialog.component.mjs +3 -3
  116. package/esm2020/src/app/shared/hotkeys/hotkeys.service.mjs +3 -3
  117. package/esm2020/src/app/shared/hotkeys/shared-hotkeys.module.mjs +4 -4
  118. package/esm2020/src/app/shared/image/gallery/image-gallery.component.mjs +4 -4
  119. package/esm2020/src/app/shared/image/gallery/image-gallery.module.mjs +4 -4
  120. package/esm2020/src/app/shared/image/gallery/testing/gallery.service.testing.mjs +3 -3
  121. package/esm2020/src/app/shared/image/gallery/testing/gallery.testing.mjs +3 -3
  122. package/esm2020/src/app/shared/image/gallery/testing/gallery.testing.module.mjs +4 -4
  123. package/esm2020/src/app/shared/image/image.module.mjs +4 -4
  124. package/esm2020/src/app/shared/image/image.service.mjs +3 -3
  125. package/esm2020/src/app/shared/material/autocomplete/material.autocomplete.config.mjs +1 -1
  126. package/esm2020/src/app/shared/material/autocomplete/material.autocomplete.mjs +6 -8
  127. package/esm2020/src/app/shared/material/autocomplete/material.autocomplete.module.mjs +4 -4
  128. package/esm2020/src/app/shared/material/autocomplete/testing/autocomplete.test.mjs +3 -3
  129. package/esm2020/src/app/shared/material/badge/badge.directive.mjs +25 -6
  130. package/esm2020/src/app/shared/material/badge/badge.module.mjs +4 -4
  131. package/esm2020/src/app/shared/material/badge/badge.test.mjs +10 -8
  132. package/esm2020/src/app/shared/material/boolean/boolean.module.mjs +4 -4
  133. package/esm2020/src/app/shared/material/boolean/material.boolean.mjs +3 -3
  134. package/esm2020/src/app/shared/material/chips/chips.module.mjs +4 -4
  135. package/esm2020/src/app/shared/material/chips/material.chips.mjs +5 -6
  136. package/esm2020/src/app/shared/material/chips/testing/chips.test.mjs +3 -3
  137. package/esm2020/src/app/shared/material/datetime/datetime.module.mjs +4 -4
  138. package/esm2020/src/app/shared/material/datetime/material.date.mjs +5 -6
  139. package/esm2020/src/app/shared/material/datetime/material.dateshort.mjs +3 -3
  140. package/esm2020/src/app/shared/material/datetime/material.datetime.mjs +5 -6
  141. package/esm2020/src/app/shared/material/datetime/testing/mat-date-time.test.mjs +5 -7
  142. package/esm2020/src/app/shared/material/datetime/testing/mat-date.test.mjs +7 -8
  143. package/esm2020/src/app/shared/material/duration/duration.module.mjs +4 -4
  144. package/esm2020/src/app/shared/material/duration/material.duration.mjs +3 -3
  145. package/esm2020/src/app/shared/material/latlong/material.latlong.mjs +3 -3
  146. package/esm2020/src/app/shared/material/latlong/material.latlong.module.mjs +4 -4
  147. package/esm2020/src/app/shared/material/latlong/testing/latlong.test.mjs +3 -3
  148. package/esm2020/src/app/shared/material/material.animations.mjs +1 -1
  149. package/esm2020/src/app/shared/material/material.module.mjs +4 -4
  150. package/esm2020/src/app/shared/material/material.testing.module.mjs +23 -11
  151. package/esm2020/src/app/shared/material/numpad/numpad.append-to-input.directive.mjs +3 -3
  152. package/esm2020/src/app/shared/material/numpad/numpad.component.mjs +3 -3
  153. package/esm2020/src/app/shared/material/numpad/numpad.container.mjs +3 -3
  154. package/esm2020/src/app/shared/material/numpad/numpad.content.mjs +3 -3
  155. package/esm2020/src/app/shared/material/numpad/numpad.directive.mjs +3 -3
  156. package/esm2020/src/app/shared/material/numpad/numpad.dom-service.mjs +3 -3
  157. package/esm2020/src/app/shared/material/numpad/numpad.module.mjs +4 -4
  158. package/esm2020/src/app/shared/material/numpad/testing/numpad.test.mjs +3 -3
  159. package/esm2020/src/app/shared/material/paginator/material.paginator-i18n.mjs +3 -3
  160. package/esm2020/src/app/shared/material/stepper/material.stepper-i18n.mjs +3 -3
  161. package/esm2020/src/app/shared/material/swipe/material.swipe.mjs +3 -3
  162. package/esm2020/src/app/shared/material/swipe/swipe.module.mjs +4 -4
  163. package/esm2020/src/app/shared/material/swipe/testing/swipe.test.mjs +7 -8
  164. package/esm2020/src/app/shared/observables.mjs +29 -22
  165. package/esm2020/src/app/shared/pipes/arrays.pipe.mjs +24 -24
  166. package/esm2020/src/app/shared/pipes/colors.pipe.mjs +3 -3
  167. package/esm2020/src/app/shared/pipes/date-diff-duration.pipe.mjs +8 -9
  168. package/esm2020/src/app/shared/pipes/date-format.pipe.mjs +4 -4
  169. package/esm2020/src/app/shared/pipes/date-from-now.pipe.mjs +4 -4
  170. package/esm2020/src/app/shared/pipes/duration.pipe.mjs +4 -4
  171. package/esm2020/src/app/shared/pipes/file-size.pipe.mjs +3 -3
  172. package/esm2020/src/app/shared/pipes/form.pipes.mjs +18 -18
  173. package/esm2020/src/app/shared/pipes/highlight.pipe.mjs +4 -4
  174. package/esm2020/src/app/shared/pipes/latlong-format.pipe.mjs +9 -9
  175. package/esm2020/src/app/shared/pipes/maps.pipe.mjs +12 -12
  176. package/esm2020/src/app/shared/pipes/math.pipes.mjs +12 -12
  177. package/esm2020/src/app/shared/pipes/ng-init.pipe.mjs +3 -3
  178. package/esm2020/src/app/shared/pipes/number-format.pipe.mjs +4 -4
  179. package/esm2020/src/app/shared/pipes/pipes.module.mjs +4 -4
  180. package/esm2020/src/app/shared/pipes/property.pipes.mjs +7 -7
  181. package/esm2020/src/app/shared/pipes/string.pipes.mjs +15 -15
  182. package/esm2020/src/app/shared/pipes/translate-context.pipe.mjs +8 -8
  183. package/esm2020/src/app/shared/services/memory-entity-service.class.mjs +15 -9
  184. package/esm2020/src/app/shared/services/progress-bar.service.mjs +3 -3
  185. package/esm2020/src/app/shared/services/storage/storage.service.mjs +3 -3
  186. package/esm2020/src/app/shared/services/translate-context.service.mjs +3 -3
  187. package/esm2020/src/app/shared/shared-routing.module.mjs +7 -7
  188. package/esm2020/src/app/shared/shared.module.mjs +9 -5
  189. package/esm2020/src/app/shared/shared.testing.module.mjs +4 -4
  190. package/esm2020/src/app/shared/testing/observable.test.mjs +95 -0
  191. package/esm2020/src/app/shared/testing/tests.page.mjs +3 -3
  192. package/esm2020/src/app/shared/toast/toast.testing.mjs +3 -3
  193. package/esm2020/src/app/shared/toast/toast.testing.module.mjs +4 -4
  194. package/esm2020/src/app/shared/toolbar/modal-toolbar.mjs +3 -3
  195. package/esm2020/src/app/shared/toolbar/toolbar.mjs +3 -3
  196. package/esm2020/src/app/shared/toolbar/toolbar.module.mjs +4 -4
  197. package/esm2020/src/app/shared/upload-file/testing/upload-file.testing.mjs +3 -3
  198. package/esm2020/src/app/shared/upload-file/testing/upload-file.testing.module.mjs +4 -4
  199. package/esm2020/src/app/shared/upload-file/upload-file-popover.component.mjs +3 -3
  200. package/esm2020/src/app/shared/upload-file/upload-file.component.mjs +3 -3
  201. package/esm2020/src/app/shared/validator/form-error-adapter.class.mjs +3 -3
  202. package/esm2020/src/app/shared/validator/validators.mjs +4 -5
  203. package/esm2020/src/app/social/job/job.module.mjs +4 -4
  204. package/esm2020/src/app/social/job/job.service.mjs +3 -3
  205. package/esm2020/src/app/social/job/progression/job-progression.icon.mjs +3 -3
  206. package/esm2020/src/app/social/job/progression/job-progression.list.mjs +3 -3
  207. package/esm2020/src/app/social/job/testing/job-progression.testing.mjs +3 -3
  208. package/esm2020/src/app/social/job/testing/job-progression.testing.service.mjs +3 -3
  209. package/esm2020/src/app/social/job/testing/job.testing.module.mjs +4 -4
  210. package/esm2020/src/app/social/message/message.form.mjs +3 -3
  211. package/esm2020/src/app/social/message/message.modal.mjs +3 -3
  212. package/esm2020/src/app/social/message/message.module.mjs +4 -4
  213. package/esm2020/src/app/social/message/message.service.mjs +3 -3
  214. package/esm2020/src/app/social/social.module.mjs +4 -4
  215. package/esm2020/src/app/social/social.testing.module.mjs +4 -4
  216. package/esm2020/src/app/social/user-event/notification/user-event-notification.icon.mjs +3 -3
  217. package/esm2020/src/app/social/user-event/notification/user-event-notification.list.mjs +6 -6
  218. package/esm2020/src/app/social/user-event/testing/user-event.testing.mjs +13 -12
  219. package/esm2020/src/app/social/user-event/testing/user-event.testing.module.mjs +4 -4
  220. package/esm2020/src/app/social/user-event/testing/user-event.testing.service.mjs +3 -3
  221. package/esm2020/src/app/social/user-event/user-event.module.mjs +4 -4
  222. package/esm2020/src/app/social/user-event/user-event.service.mjs +6 -8
  223. package/fesm2015/sumaris-net.ngx-components.mjs +4619 -4210
  224. package/fesm2015/sumaris-net.ngx-components.mjs.map +1 -1
  225. package/fesm2020/sumaris-net.ngx-components.mjs +4548 -4129
  226. package/fesm2020/sumaris-net.ngx-components.mjs.map +1 -1
  227. package/package.json +3 -2
  228. package/plugins/clovelced-plugin-audiomanagement/README.md +66 -0
  229. package/plugins/cordova-plugin-camera/README.md +703 -0
  230. package/plugins/cordova-plugin-device/README.md +309 -0
  231. package/plugins/cordova-plugin-file/README.md +848 -0
  232. package/plugins/cordova-plugin-file-transfer/README.md +598 -0
  233. package/plugins/cordova-plugin-file-transfer/doc/de/README.md +311 -0
  234. package/plugins/cordova-plugin-file-transfer/doc/es/README.md +311 -0
  235. package/plugins/cordova-plugin-file-transfer/doc/fr/README.md +270 -0
  236. package/plugins/cordova-plugin-file-transfer/doc/it/README.md +311 -0
  237. package/plugins/cordova-plugin-file-transfer/doc/ja/README.md +311 -0
  238. package/plugins/cordova-plugin-file-transfer/doc/ko/README.md +311 -0
  239. package/plugins/cordova-plugin-file-transfer/doc/pl/README.md +311 -0
  240. package/plugins/cordova-plugin-file-transfer/doc/zh/README.md +311 -0
  241. package/plugins/cordova-plugin-ionic-keyboard/README.md +220 -0
  242. package/plugins/cordova-plugin-ionic-webview/README.md +181 -0
  243. package/plugins/cordova-plugin-media-capture/README.md +626 -0
  244. package/plugins/cordova-plugin-splashscreen/README.md +387 -0
  245. package/plugins/cordova-plugin-statusbar/README.md +341 -0
  246. package/plugins/cordova-plugin-telerik-imagepicker/README.md +155 -0
  247. package/plugins/cordova-plugin-whitelist/README.md +185 -0
  248. package/plugins/cordova-sqlite-storage/README.md +1848 -0
  249. package/plugins/integrator-cordova-plugin-downloader/README.md +49 -0
  250. package/public_api.d.ts +71 -23
  251. package/src/app/admin/admin.module.d.ts +1 -1
  252. package/src/app/admin/users/{list/users.d.ts → users.d.ts} +11 -11
  253. package/src/app/admin/users/users.module.d.ts +13 -0
  254. package/src/app/core/about/{modal-about.d.ts → about.modal.d.ts} +1 -1
  255. package/src/app/core/about/about.module.d.ts +10 -0
  256. package/src/app/core/account/account.module.d.ts +11 -0
  257. package/src/app/core/account/{account.d.ts → account.page.d.ts} +5 -1
  258. package/src/app/core/auth/{form/form-auth.d.ts → auth.form.d.ts} +9 -9
  259. package/src/app/core/auth/{modal/modal-auth.d.ts → auth.modal.d.ts} +4 -4
  260. package/src/app/core/auth/auth.module.d.ts +11 -0
  261. package/src/app/core/core.module.d.ts +20 -29
  262. package/src/app/core/core.testing.module.d.ts +1 -1
  263. package/src/app/core/form/{form-buttons-bar.component.d.ts → buttons/form-buttons-bar.component.d.ts} +2 -2
  264. package/src/app/core/form/buttons/form-buttons-bar.module.d.ts +9 -0
  265. package/src/app/core/form/{editor.class.d.ts → entity/editor.class.d.ts} +11 -10
  266. package/src/app/core/form/{entity-editor-modal.class.d.ts → entity/entity-editor-modal.class.d.ts} +24 -15
  267. package/src/app/core/form/{entity-editor.class.d.ts → entity/entity-editor.class.d.ts} +10 -10
  268. package/src/app/core/form/{entity-metadata.component.d.ts → entity/entity-metadata.component.d.ts} +1 -1
  269. package/src/app/core/form/entity/entity.module.d.ts +10 -0
  270. package/src/app/core/form/form.class.d.ts +1 -0
  271. package/src/app/core/form/form.module.d.ts +13 -0
  272. package/src/app/core/form/form.utils.d.ts +2 -2
  273. package/src/app/core/form/{list.form.d.ts → list/list.form.d.ts} +4 -4
  274. package/src/app/core/form/list/list.module.d.ts +9 -0
  275. package/src/app/core/form/properties/properties.module.d.ts +9 -0
  276. package/src/app/core/{text-popover → form/text-popover}/testing/text-popover.testing.d.ts +0 -0
  277. package/src/app/core/{text-popover → form/text-popover}/testing/text-popover.testing.module.d.ts +0 -0
  278. package/src/app/core/{text-popover → form/text-popover}/text-form.component.d.ts +1 -1
  279. package/src/app/core/{text-popover → form/text-popover}/text-popover.component.d.ts +0 -0
  280. package/src/app/core/form/text-popover/text-popover.module.d.ts +10 -0
  281. package/src/app/core/home/home.module.d.ts +12 -0
  282. package/src/app/core/install/install-upgrade-card.module.d.ts +6 -7
  283. package/src/app/core/menu/menu.component.d.ts +1 -1
  284. package/src/app/core/offline/update-offline-mode-card.component.d.ts +1 -1
  285. package/src/app/core/offline/update-offline-mode-card.module.d.ts +9 -0
  286. package/src/app/core/peer/select-peer.modal.d.ts +1 -1
  287. package/src/app/core/peer/select-peer.module.d.ts +5 -4
  288. package/src/app/core/register/{confirm/confirm.d.ts → register-confirm.page.d.ts} +4 -4
  289. package/src/app/core/register/{form/form-register.d.ts → register.form.d.ts} +7 -7
  290. package/src/app/core/register/{modal/modal-register.d.ts → register.modal.d.ts} +2 -2
  291. package/src/app/core/register/register.module.d.ts +6 -6
  292. package/src/app/core/services/account.service.d.ts +5 -6
  293. package/src/app/core/services/base-graphql-service.class.d.ts +9 -8
  294. package/src/app/core/services/crypto.service.d.ts +23 -18
  295. package/src/app/core/services/model/referential.model.d.ts +6 -1
  296. package/src/app/core/settings/settings.module.d.ts +10 -0
  297. package/src/app/core/table/actions-column.component.d.ts +1 -1
  298. package/src/app/core/table/table.class.d.ts +21 -38
  299. package/src/app/core/table/table.module.d.ts +10 -0
  300. package/src/app/core/table/testing/table.testing.d.ts +1 -1
  301. package/src/app/shared/dates.d.ts +13 -3
  302. package/src/app/shared/events.d.ts +4 -4
  303. package/src/app/shared/graph/graph-colors.d.ts +8 -8
  304. package/src/app/shared/image/gallery/image-gallery.component.d.ts +1 -1
  305. package/src/app/shared/material/autocomplete/material.autocomplete.config.d.ts +1 -1
  306. package/src/app/shared/material/badge/badge.directive.d.ts +3 -1
  307. package/src/app/shared/material/badge/badge.test.d.ts +1 -0
  308. package/src/app/shared/material/datetime/material.date.d.ts +1 -1
  309. package/src/app/shared/material/datetime/material.datetime.d.ts +4 -4
  310. package/src/app/shared/material/datetime/testing/mat-date.test.d.ts +1 -0
  311. package/src/app/shared/material/material.testing.module.d.ts +9 -8
  312. package/src/app/shared/material/swipe/testing/swipe.test.d.ts +2 -3
  313. package/src/app/shared/observables.d.ts +1 -1
  314. package/src/app/shared/services/memory-entity-service.class.d.ts +5 -0
  315. package/src/app/shared/shared.module.d.ts +2 -1
  316. package/src/app/shared/testing/observable.test.d.ts +25 -0
  317. package/src/theme/_ionic.globals.scss +4 -0
  318. package/src/theme/_material.globals.scss +3 -1
  319. package/src/theme/_mixins.scss +3 -3
  320. package/esm2020/public_test_api.mjs +0 -46
  321. package/esm2020/src/app/admin/users/list/users.mjs +0 -233
  322. package/esm2020/src/app/admin/users/list/users.module.mjs +0 -58
  323. package/esm2020/src/app/core/about/modal-about.mjs +0 -71
  324. package/esm2020/src/app/core/account/account.mjs +0 -230
  325. package/esm2020/src/app/core/auth/form/form-auth.mjs +0 -131
  326. package/esm2020/src/app/core/auth/modal/modal-auth.mjs +0 -72
  327. package/esm2020/src/app/core/form/editor.class.mjs +0 -672
  328. package/esm2020/src/app/core/form/entity-editor-modal.class.mjs +0 -407
  329. package/esm2020/src/app/core/form/entity-editor.class.mjs +0 -646
  330. package/esm2020/src/app/core/form/list.form.mjs +0 -222
  331. package/esm2020/src/app/core/register/confirm/confirm.mjs +0 -81
  332. package/esm2020/src/app/core/register/form/form-register.mjs +0 -181
  333. package/esm2020/src/app/core/register/modal/modal-register.mjs +0 -52
  334. package/esm2020/src/app/core/text-popover/testing/text-popover.testing.module.mjs +0 -45
  335. package/esm2020/src/app/vendor.mjs +0 -16
  336. package/public_test_api.d.ts +0 -37
  337. package/src/app/admin/users/list/users.module.d.ts +0 -14
  338. package/src/app/vendor.d.ts +0 -11
@@ -1,672 +0,0 @@
1
- import { Directive, EventEmitter, Input, Optional, Output, ViewChild } from '@angular/core';
2
- import { IonContent } from '@ionic/angular';
3
- import { BehaviorSubject, Subject, Subscription } from 'rxjs';
4
- import { AppTable } from '../table/table.class';
5
- import { AppForm } from './form.class';
6
- import { FormButtonsBarToken } from './form-buttons-bar.component';
7
- import { AppFormProvider, AppFormUtils } from './form.utils';
8
- import { Toasts } from '../../shared/toast/toasts';
9
- import { ToolbarToken } from '../../shared/toolbar/toolbar';
10
- import { isNotNil, toNumber } from '../../shared/functions';
11
- import { AbstractControl } from '@angular/forms';
12
- import { waitForFalse, waitForTrue } from '../../shared/observables';
13
- import * as i0 from "@angular/core";
14
- import * as i1 from "@angular/router";
15
- import * as i2 from "@ionic/angular";
16
- import * as i3 from "@ngx-translate/core";
17
- export class AppTabEditorOptions {
18
- }
19
- // eslint-disable-next-line @angular-eslint/directive-class-suffix
20
- export class AppEditor {
21
- constructor(route, router, alertCtrl, translate) {
22
- this.route = route;
23
- this.router = router;
24
- this.alertCtrl = alertCtrl;
25
- this.translate = translate;
26
- this._subscription = new Subscription();
27
- this._enabled = false;
28
- this.destroySubject = new Subject();
29
- this.readySubject = new BehaviorSubject(false);
30
- this.dirtySubject = new BehaviorSubject(false);
31
- this.loadingSubject = new BehaviorSubject(true);
32
- this.errorSubject = new BehaviorSubject(undefined);
33
- this.savingSubject = new BehaviorSubject(false);
34
- this.touchedSubject = new BehaviorSubject(false);
35
- this.debug = false;
36
- this.submitted = false;
37
- this.toolbar = null;
38
- this.formButtonsBar = null;
39
- }
40
- /**
41
- * @deprecated
42
- */
43
- set _loading(value) {
44
- this.loadingSubject.next(value);
45
- }
46
- /**
47
- * @deprecated
48
- */
49
- get _loading() {
50
- return this.loadingSubject.value;
51
- }
52
- /**
53
- * @deprecated
54
- */
55
- get _$ready() {
56
- return this.readySubject;
57
- }
58
- /**
59
- * @deprecated
60
- */
61
- get _$loading() {
62
- return this.loadingSubject;
63
- }
64
- get error() {
65
- return this.errorSubject.value;
66
- }
67
- set error(error) {
68
- this.setError(error);
69
- }
70
- get saving() {
71
- return this.savingSubject.value || this.editors?.some(e => e.saving);
72
- }
73
- get tables() {
74
- return this._children && this._children.filter(c => c instanceof AppTable);
75
- }
76
- get forms() {
77
- return this._children && this._children.filter(c => c instanceof AppForm);
78
- }
79
- get editors() {
80
- return this._children && this._children.filter(c => c instanceof AppEditor);
81
- }
82
- get dirty() {
83
- return this.dirtySubject.value || (this._children && this._children.findIndex(c => c.enabled && c.dirty) !== -1) || false;
84
- }
85
- /**
86
- * Is valid (tables and forms)
87
- */
88
- get valid() {
89
- // Important: Should be not invalid AND not pending, so use '!valid' (DO NOT use 'invalid')
90
- return !this._children || this._children.findIndex(c => c.enabled && !c.valid) === -1;
91
- }
92
- get invalid() {
93
- return (this._children && this._children.findIndex(c => c.enabled && c.invalid) !== -1) || false;
94
- }
95
- get pending() {
96
- return (this._children && this._children.findIndex(c => c.enabled && c.pending) !== -1) || false;
97
- }
98
- get loading() {
99
- return this.loadingSubject.value || (this._children && this._children.findIndex(c => c.enabled && c.loading) !== -1) || false;
100
- }
101
- get loaded() {
102
- return !this.loadingSubject.value && (!this._children || this._children.findIndex(c => c.enabled && c.loading) === -1) || false;
103
- }
104
- get touched() {
105
- return this.touchedSubject.value || (this._children && this._children.findIndex(c => c.enabled && c.touched) !== -1) || false;
106
- }
107
- get untouched() {
108
- return !this.touchedSubject.value && (!this._children || this._children.findIndex(c => c.enabled && c.touched) === -1) || false;
109
- }
110
- get enabled() {
111
- return this._enabled;
112
- }
113
- get disabled() {
114
- return !this._enabled;
115
- }
116
- get children() {
117
- return this._children;
118
- }
119
- get empty() {
120
- return !this._enabled;
121
- }
122
- ngOnInit() {
123
- if (this.formButtonsBar) {
124
- this.registerSubscription(this.formButtonsBar.onBack.subscribe(event => this.goBack(event)));
125
- }
126
- }
127
- ngAfterViewInit() {
128
- // Can be overridden by subclasses
129
- }
130
- ngOnDestroy() {
131
- this._subscription.unsubscribe();
132
- this.readySubject.unsubscribe();
133
- this.loadingSubject.unsubscribe();
134
- this.errorSubject.unsubscribe();
135
- this.destroySubject.next();
136
- this.destroySubject.unsubscribe();
137
- }
138
- addChildForm(form) {
139
- if (!form)
140
- throw new Error('Trying to register an undefined child form');
141
- this._children = this._children || [];
142
- if (typeof form === 'function') {
143
- this._children.push(new AppFormProvider(form));
144
- }
145
- else {
146
- this._children.push(form);
147
- }
148
- return this;
149
- }
150
- addChildForms(forms) {
151
- (forms || []).forEach(form => this.addChildForm(form));
152
- }
153
- removeChildForm(form) {
154
- if (!form)
155
- throw new Error('Trying to remove an undefined child form');
156
- const index = (this._children || []).findIndex(c => c === form);
157
- if (index !== -1) {
158
- return this._children.splice(index, 1)[0];
159
- }
160
- return undefined;
161
- }
162
- disable(opts) {
163
- this._enabled = false;
164
- this._children?.forEach(c => c.disable(opts));
165
- if (!this.loading && (!opts || opts.emitEvent !== false))
166
- this.markForCheck();
167
- }
168
- enable(opts) {
169
- this._enabled = true;
170
- this._children?.forEach(c => c.enable(opts));
171
- if (!this.loading && (!opts || opts.emitEvent !== false))
172
- this.markForCheck();
173
- }
174
- markAsPristine(opts) {
175
- this.error = null;
176
- this.submitted = false;
177
- if (this.dirtySubject.value !== false) {
178
- this.dirtySubject.next(false);
179
- }
180
- this._children?.forEach(c => c.markAsPristine(opts));
181
- if (!this.loading && (!opts || opts.emitEvent !== false))
182
- this.markForCheck();
183
- }
184
- markAsUntouched(opts) {
185
- if (this.touchedSubject.value !== false) {
186
- this.touchedSubject.next(false);
187
- }
188
- this._children?.forEach(c => c.markAsUntouched());
189
- if (!this.loading && (!opts || opts.emitEvent !== false))
190
- this.markForCheck();
191
- }
192
- /**
193
- * @deprecated prefer to use markAllAsTouched()
194
- * @param opts
195
- */
196
- markAsTouched(opts) {
197
- if (!this.touchedSubject.value !== true) {
198
- this.touchedSubject.next(true);
199
- }
200
- this._children?.forEach(c => c.markAsTouched(opts));
201
- if (!this.loading && (!opts || opts.emitEvent !== false))
202
- this.markForCheck();
203
- }
204
- markAllAsTouched(opts) {
205
- if (this.touchedSubject.value !== true) {
206
- this.touchedSubject.next(true);
207
- }
208
- this._children?.forEach(c => c.markAllAsTouched(opts));
209
- if (!this.loading && (!opts || opts.emitEvent !== false))
210
- this.markForCheck();
211
- }
212
- markAsDirty(opts) {
213
- if (!this.dirtySubject.value) {
214
- this.dirtySubject.next(true);
215
- if (!this.loading && (!opts || opts.emitEvent !== false))
216
- this.markForCheck();
217
- }
218
- }
219
- markAsLoading(opts) {
220
- if (!this.loadingSubject.value) {
221
- this.loadingSubject.next(true);
222
- if (!opts || opts.emitEvent !== false)
223
- this.markForCheck();
224
- }
225
- }
226
- markAsLoaded(opts) {
227
- if (this.loadingSubject.value) {
228
- this.loadingSubject.next(false);
229
- if (!opts || opts.onlySelf !== true) {
230
- // Emit to children forms and editors
231
- // note: tables should be changed by parent
232
- this.forms?.forEach(f => f.markAsLoaded(opts));
233
- this.editors?.forEach(e => e.markAsLoaded(opts));
234
- }
235
- if (!opts || opts.emitEvent !== false) {
236
- this.markForCheck();
237
- }
238
- }
239
- }
240
- markAsReady(opts) {
241
- this._children?.forEach(c => c.markAsReady(opts));
242
- this.readySubject.next(true);
243
- }
244
- ready(opts) {
245
- if (this.readySubject.value)
246
- return Promise.resolve();
247
- return waitForTrue(this.readySubject, opts);
248
- }
249
- waitIdle(opts) {
250
- if (!this.loadingSubject.value)
251
- return Promise.resolve();
252
- return waitForFalse(this.loadingSubject, opts);
253
- }
254
- markAsSaving(opts) {
255
- if (this.savingSubject.value !== true) {
256
- this.savingSubject.next(true);
257
- if (!opts || opts.emitEvent !== false)
258
- this.markForCheck();
259
- }
260
- }
261
- markAsSaved(opts) {
262
- if (this.savingSubject.value !== false) {
263
- this.savingSubject.next(false);
264
- if (!opts || opts.emitEvent !== false)
265
- this.markForCheck();
266
- }
267
- }
268
- async cancel(event) {
269
- if (this.isNewData) {
270
- await this.unload(); // async reset
271
- }
272
- else if (this.dirty) {
273
- await this.reload(); // async reload
274
- }
275
- }
276
- /**
277
- * Unload the page (remove all data). Useful when reusing angular cache a cancelled page
278
- *
279
- * @param opts
280
- */
281
- async unload(opts) {
282
- console.debug('[editor] Unloading data...');
283
- this.markAsLoading();
284
- this._children?.forEach(f => {
285
- if (f instanceof AppForm) {
286
- f.reset(null, opts);
287
- }
288
- else if (f instanceof AppTable) {
289
- f.dataSource.disconnect();
290
- }
291
- else if (f instanceof AppEditor) {
292
- f.unload(opts);
293
- }
294
- });
295
- this.markAsPristine(opts);
296
- this.markAsSaved(opts);
297
- }
298
- async reloadWithConfirmation(confirm) {
299
- const needConfirm = this.dirty;
300
- // if not confirm yet: ask confirmation
301
- if (!confirm && needConfirm) {
302
- const translations = this.translate.instant(['COMMON.BTN_ABORT_CHANGES', 'COMMON.BTN_CANCEL', 'CONFIRM.CANCEL_CHANGES', 'CONFIRM.ALERT_HEADER']);
303
- const alert = await this.alertCtrl.create({
304
- header: translations['CONFIRM.ALERT_HEADER'],
305
- message: translations['CONFIRM.CANCEL_CHANGES'],
306
- buttons: [
307
- {
308
- text: translations['COMMON.BTN_ABORT_CHANGES'],
309
- cssClass: 'secondary',
310
- handler: () => {
311
- confirm = true; // update upper value
312
- }
313
- },
314
- {
315
- text: translations['COMMON.BTN_CANCEL'],
316
- role: 'cancel',
317
- handler: () => {
318
- }
319
- }
320
- ]
321
- });
322
- await alert.present();
323
- await alert.onDidDismiss();
324
- }
325
- // If confirm: execute the reload
326
- if (confirm || !needConfirm) {
327
- this.scrollToTop();
328
- this.disable();
329
- return await this.reload();
330
- }
331
- }
332
- async goBack(event) {
333
- // Go back
334
- if (this.toolbar?.canGoBack) {
335
- return this.toolbar.goBack();
336
- }
337
- else {
338
- // Back to home
339
- return this.router.navigateByUrl('/');
340
- }
341
- }
342
- logFormErrors(prefix) {
343
- if (this.debug)
344
- console.debug('[editor] Editor not valid. Checking where (forms, tables)...');
345
- this._children?.forEach(c => this.logChildrenErrors(c, prefix));
346
- }
347
- /* -- protected methods -- */
348
- async scrollToTop(duration) {
349
- duration = toNumber(duration, 500);
350
- if (!this.content) {
351
- console.warn(`[tab-editor] Cannot scroll to top. (no 'ion-content' tag found ${this.constructor.name}`);
352
- // TODO: FIXME (not working as the page is not the window)
353
- const scrollToTop = window.setInterval(() => {
354
- const pos = window.scrollY;
355
- if (pos > 0) {
356
- window.scrollTo(0, pos - 20); // how far to scroll on each step
357
- }
358
- else {
359
- window.clearInterval(scrollToTop);
360
- }
361
- }, 16);
362
- return;
363
- }
364
- return this.content.scrollToTop(duration);
365
- }
366
- registerSubscription(sub) {
367
- this._subscription.add(sub);
368
- }
369
- unregisterSubscription(sub) {
370
- this._subscription.remove(sub);
371
- }
372
- async saveIfDirtyAndConfirm(event, opts) {
373
- if (!this.dirty)
374
- return true;
375
- let confirmed = opts?.confirmed || false;
376
- if (!confirmed) {
377
- let cancel = false;
378
- const translations = this.translate.instant(['COMMON.BTN_SAVE', 'COMMON.BTN_CANCEL', 'COMMON.BTN_ABORT_CHANGES', 'CONFIRM.SAVE', 'CONFIRM.ALERT_HEADER']);
379
- const alert = await this.alertCtrl.create({
380
- header: translations['CONFIRM.ALERT_HEADER'],
381
- message: translations['CONFIRM.SAVE'],
382
- buttons: [
383
- {
384
- text: translations['COMMON.BTN_CANCEL'],
385
- role: 'cancel',
386
- cssClass: 'secondary',
387
- handler: () => {
388
- cancel = true;
389
- }
390
- },
391
- {
392
- text: translations['COMMON.BTN_ABORT_CHANGES'],
393
- cssClass: 'secondary',
394
- handler: () => {
395
- }
396
- },
397
- {
398
- text: translations['COMMON.BTN_SAVE'],
399
- handler: () => {
400
- confirmed = true; // update upper value
401
- }
402
- }
403
- ]
404
- });
405
- await alert.present();
406
- await alert.onDidDismiss();
407
- if (!confirmed) {
408
- return !cancel;
409
- }
410
- }
411
- return await this.save(event, opts);
412
- }
413
- async showToast(opts) {
414
- if (!this.toastController)
415
- throw new Error('Missing toastController in component\'s constructor');
416
- await Toasts.show(this.toastController, this.translate, opts);
417
- }
418
- logChildrenErrors(c, prefix, path) {
419
- prefix = prefix || '[app-tab-editor] ';
420
- // If editor
421
- if (c instanceof AppEditor) {
422
- c.logFormErrors();
423
- }
424
- // Angular form control
425
- else if (c instanceof AbstractControl) {
426
- AppFormUtils.logFormErrors(c, prefix, path);
427
- }
428
- // If form provider: get delegate
429
- else if (c instanceof AppFormProvider) {
430
- if (!c.empty && !c.valid) {
431
- c.waitDelegate({ timeout: 1000 }).then(delegate => this.logChildrenErrors(delegate, prefix, 'provider'));
432
- }
433
- }
434
- // If table
435
- else if (c instanceof AppTable) {
436
- if (c.invalid && c.editedRow && c.editedRow.validator) {
437
- const path = c.constructor.name.toLowerCase();
438
- AppFormUtils.logFormErrors(c.editedRow.validator, prefix, path);
439
- }
440
- }
441
- // If form
442
- else if (c instanceof AppForm) {
443
- if (!c.empty && !c.valid) {
444
- if (c.pending) {
445
- const path = c.constructor.name.toLowerCase();
446
- console.warn(`${prefix} -> ${path}: waiting while pending...`);
447
- AppFormUtils.waitWhilePending(c, { timeout: 1000 })
448
- .then(() => this.logChildrenErrors(c.form, prefix, path));
449
- }
450
- else {
451
- AppFormUtils.logFormErrors(c.form, prefix);
452
- }
453
- }
454
- }
455
- // If editor
456
- else if (c instanceof AppEditor) {
457
- if (!c.empty && !c.valid) {
458
- if (c.pending) {
459
- const path = c.constructor.name.toLowerCase();
460
- console.warn(`${prefix} -> ${path}: waiting while pending...`);
461
- AppFormUtils.waitWhilePending(c, { timeout: 1000 })
462
- .then(() => c.logFormErrors(prefix));
463
- }
464
- else {
465
- c.logFormErrors(prefix);
466
- }
467
- }
468
- }
469
- else {
470
- console.warn(`${prefix} Unknown children sub-form: `, c);
471
- }
472
- }
473
- setError(value, opts) {
474
- if (this.errorSubject.value !== value) {
475
- this.errorSubject.next(value);
476
- if (!opts || opts.emitEvent !== false)
477
- this.markForCheck();
478
- }
479
- }
480
- resetError(opts) {
481
- this.setError(undefined, opts);
482
- }
483
- markForCheck() {
484
- // Should be override by subclasses, if change detection is Push
485
- }
486
- }
487
- AppEditor.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.2.6", ngImport: i0, type: AppEditor, deps: [{ token: i1.ActivatedRoute }, { token: i1.Router }, { token: i2.AlertController }, { token: i3.TranslateService }], target: i0.ɵɵFactoryTarget.Directive });
488
- AppEditor.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "14.2.6", type: AppEditor, viewQueries: [{ propertyName: "toolbar", first: true, predicate: ToolbarToken, descendants: true }, { propertyName: "formButtonsBar", first: true, predicate: FormButtonsBarToken, descendants: true, static: true }, { propertyName: "content", first: true, predicate: IonContent, descendants: true, static: true }], ngImport: i0 });
489
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.2.6", ngImport: i0, type: AppEditor, decorators: [{
490
- type: Directive
491
- }], ctorParameters: function () { return [{ type: i1.ActivatedRoute }, { type: i1.Router }, { type: i2.AlertController }, { type: i3.TranslateService }]; }, propDecorators: { toolbar: [{
492
- type: ViewChild,
493
- args: [ToolbarToken]
494
- }], formButtonsBar: [{
495
- type: ViewChild,
496
- args: [FormButtonsBarToken, { static: true }]
497
- }], content: [{
498
- type: ViewChild,
499
- args: [IonContent, { static: true }]
500
- }] } });
501
- // eslint-disable-next-line @angular-eslint/directive-class-suffix
502
- export class AppTabEditor extends AppEditor {
503
- constructor(route, // Modal editor give 'null'
504
- router, alertCtrl, translate, options) {
505
- super(route, router, alertCtrl, translate);
506
- this.route = route;
507
- this.router = router;
508
- this.alertCtrl = alertCtrl;
509
- this.translate = translate;
510
- this._selectedTabIndex = 0;
511
- this.selectedTabIndexChange = new EventEmitter();
512
- options = {
513
- tabCount: 1,
514
- enableSwipe: true,
515
- tabGroupAnimationDuration: '200ms',
516
- ...options
517
- };
518
- this.tabCount = options.tabCount;
519
- this.enableSwipe = options.enableSwipe;
520
- this.tabGroupAnimationDuration = options.tabGroupAnimationDuration;
521
- this.queryTabIndexParamName = 'tab';
522
- }
523
- set selectedTabIndex(value) {
524
- this.setSelectedTabIndex(value);
525
- }
526
- get selectedTabIndex() {
527
- return this._selectedTabIndex;
528
- }
529
- ngOnInit() {
530
- super.ngOnInit();
531
- // Read the selected tab index, from path query params
532
- if (this.tabGroup && this.route && this.queryTabIndexParamName) {
533
- this.registerSubscription(this.route.queryParams
534
- .subscribe(queryParams => {
535
- this.queryParams = { ...queryParams };
536
- // Parse tab param
537
- if (this.tabCount > 1 && this.queryTabIndexParamName) {
538
- const tabIndex = queryParams[this.queryTabIndexParamName];
539
- this.queryParams[this.queryTabIndexParamName] = tabIndex && parseInt(tabIndex) || undefined;
540
- if (isNotNil(this.queryParams[this.queryTabIndexParamName])) {
541
- this.selectedTabIndex = this.queryParams[this.queryTabIndexParamName];
542
- }
543
- }
544
- // Realign tab, after a delay because the tab can be disabled when component is created
545
- setTimeout(() => this.tabGroup.realignInkBar(), 500);
546
- }));
547
- }
548
- }
549
- ngOnDestroy() {
550
- super.ngOnDestroy();
551
- this.selectedTabIndexChange.complete();
552
- this.loadingSubject.unsubscribe();
553
- this.errorSubject.unsubscribe();
554
- }
555
- setSelectedTabIndex(value, opts) {
556
- // Fix value
557
- if (value < 0) {
558
- value = 0;
559
- }
560
- else if (value > this.tabCount - 1) {
561
- console.warn(`[tab-editor] Invalid tab index ${value}. Max value is ${this.tabCount - 1}`);
562
- value = this._selectedTabIndex;
563
- }
564
- this._selectedTabIndex = value;
565
- this.selectedTabIndexChange.next(value);
566
- if (this.tabGroup && (!opts || opts.realignInkBar !== false)) {
567
- this.tabGroup.selectedIndex = value;
568
- this.markForCheck();
569
- // Wait tab change in UI, before realign ink tab
570
- setTimeout(() => this.tabGroup.realignInkBar(), 200);
571
- }
572
- else if (!opts || opts.emitEvent !== false) {
573
- this.markForCheck();
574
- }
575
- }
576
- realignInkBar() {
577
- this.tabGroup?.realignInkBar();
578
- }
579
- onTabChange(event, queryTabIndexParamName) {
580
- queryTabIndexParamName = queryTabIndexParamName || this.queryTabIndexParamName;
581
- if (!queryTabIndexParamName || !this.route)
582
- return true; // Skip if tab query param not set, or no route
583
- if (!this.queryParams || +this.queryParams[queryTabIndexParamName] !== event.index) {
584
- this.queryParams = this.queryParams || {};
585
- this.queryParams[queryTabIndexParamName] = event.index;
586
- if (queryTabIndexParamName === 'tab' && isNotNil(this.queryParams['subtab'])) {
587
- delete this.queryParams.subtab; // clean subtab
588
- }
589
- this.router.navigate(['.'], {
590
- relativeTo: this.route,
591
- queryParams: this.queryParams,
592
- replaceUrl: true
593
- });
594
- return true;
595
- }
596
- return false;
597
- }
598
- /**
599
- * Action triggered when user swipes
600
- */
601
- onSwipeTab(event) {
602
- // DEBUG
603
- // if (this.debug) console.debug("[tab-page] onSwipeTab()");
604
- // Skip, if not a valid swipe event
605
- if (!this.enableSwipe || !event
606
- || event.defaultPrevented || (event.srcEvent && event.srcEvent.defaultPrevented)
607
- || event.pointerType !== 'touch') {
608
- return false;
609
- }
610
- // DEBUG
611
- //if (this.debug)
612
- //console.debug("[tab-page] Detected swipe: " + event.type, event);
613
- let selectTabIndex = this.selectedTabIndex;
614
- switch (event.type) {
615
- // Open next tab
616
- case 'swipeleft':
617
- const isLast = selectTabIndex >= (this.tabCount - 1);
618
- selectTabIndex = isLast ? 0 : selectTabIndex + 1;
619
- break;
620
- // Open previous tab
621
- case 'swiperight':
622
- const isFirst = selectTabIndex <= 0;
623
- selectTabIndex = isFirst ? this.tabCount : selectTabIndex - 1;
624
- break;
625
- // Other case
626
- default:
627
- console.error('[tab-page] Unknown swipe action: ' + event.type);
628
- return false;
629
- }
630
- setTimeout(() => {
631
- this.selectedTabIndex = selectTabIndex;
632
- this.markForCheck();
633
- });
634
- return true;
635
- }
636
- onSubTabChange(event) {
637
- this.onTabChange(event, 'subtab');
638
- }
639
- async unload(opts) {
640
- this.selectedTabIndex = 0;
641
- await super.unload(opts);
642
- }
643
- async saveDirtyChildren() {
644
- // Save all dirty tables
645
- const results = await Promise.all([
646
- ...this.tables,
647
- ...this.editors
648
- ]
649
- .filter(c => c.dirty)
650
- .map(c => c.save()));
651
- return !results.some(saved => saved !== true);
652
- }
653
- }
654
- AppTabEditor.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.2.6", ngImport: i0, type: AppTabEditor, deps: [{ token: i1.ActivatedRoute, optional: true }, { token: i1.Router }, { token: i2.AlertController }, { token: i3.TranslateService }, { token: AppTabEditorOptions, optional: true }], target: i0.ɵɵFactoryTarget.Directive });
655
- AppTabEditor.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "14.2.6", type: AppTabEditor, inputs: { queryTabIndexParamName: "queryTabIndexParamName", selectedTabIndex: "selectedTabIndex" }, outputs: { selectedTabIndexChange: "selectedTabIndexChange" }, viewQueries: [{ propertyName: "tabGroup", first: true, predicate: ["tabGroup"], descendants: true, static: true }], usesInheritance: true, ngImport: i0 });
656
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.2.6", ngImport: i0, type: AppTabEditor, decorators: [{
657
- type: Directive
658
- }], ctorParameters: function () { return [{ type: i1.ActivatedRoute, decorators: [{
659
- type: Optional
660
- }] }, { type: i1.Router }, { type: i2.AlertController }, { type: i3.TranslateService }, { type: AppTabEditorOptions, decorators: [{
661
- type: Optional
662
- }] }]; }, propDecorators: { queryTabIndexParamName: [{
663
- type: Input
664
- }], selectedTabIndex: [{
665
- type: Input
666
- }], selectedTabIndexChange: [{
667
- type: Output
668
- }], tabGroup: [{
669
- type: ViewChild,
670
- args: ['tabGroup', { static: true }]
671
- }] } });
672
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZWRpdG9yLmNsYXNzLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vLi4vc3JjL2FwcC9jb3JlL2Zvcm0vZWRpdG9yLmNsYXNzLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBZ0IsU0FBUyxFQUFFLFlBQVksRUFBRSxLQUFLLEVBQXFCLFFBQVEsRUFBRSxNQUFNLEVBQUUsU0FBUyxFQUFDLE1BQU0sZUFBZSxDQUFDO0FBRzVILE9BQU8sRUFBa0IsVUFBVSxFQUFrQixNQUFNLGdCQUFnQixDQUFDO0FBRTVFLE9BQU8sRUFBQyxlQUFlLEVBQUUsT0FBTyxFQUFFLFlBQVksRUFBZ0IsTUFBTSxNQUFNLENBQUM7QUFDM0UsT0FBTyxFQUFDLFFBQVEsRUFBQyxNQUFNLHNCQUFzQixDQUFDO0FBQzlDLE9BQU8sRUFBQyxPQUFPLEVBQUMsTUFBTSxjQUFjLENBQUM7QUFDckMsT0FBTyxFQUFDLG1CQUFtQixFQUFDLE1BQU0sOEJBQThCLENBQUM7QUFDakUsT0FBTyxFQUFDLGVBQWUsRUFBRSxZQUFZLEVBQTJCLE1BQU0sY0FBYyxDQUFDO0FBQ3JGLE9BQU8sRUFBbUIsTUFBTSxFQUFDLE1BQU0sMkJBQTJCLENBQUM7QUFFbkUsT0FBTyxFQUFDLFlBQVksRUFBQyxNQUFNLDhCQUE4QixDQUFDO0FBQzFELE9BQU8sRUFBQyxRQUFRLEVBQUUsUUFBUSxFQUFDLE1BQU0sd0JBQXdCLENBQUM7QUFFMUQsT0FBTyxFQUFDLGVBQWUsRUFBQyxNQUFNLGdCQUFnQixDQUFDO0FBQy9DLE9BQU8sRUFBQyxZQUFZLEVBQWtCLFdBQVcsRUFBQyxNQUFNLDBCQUEwQixDQUFDOzs7OztBQWVuRixNQUFNLE9BQU8sbUJBQW1CO0NBZ0IvQjtBQUdELGtFQUFrRTtBQUNsRSxNQUFNLE9BQWdCLFNBQVM7SUFtSTdCLFlBQ1ksS0FBcUIsRUFDckIsTUFBYyxFQUNkLFNBQTBCLEVBQzFCLFNBQTJCO1FBSDNCLFVBQUssR0FBTCxLQUFL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T0FFRztJQUNILElBQUksS0FBSztRQUNQLDJGQUEyRjtRQUMzRixPQUFPLENBQUMsSUFBSSxDQUFDLFNBQVMsSUFBSSxJQUFJLENBQUMsU0FBUyxDQUFDLFNBQVMsQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQyxPQUFPLElBQUksQ0FBQyxDQUFDLENBQUMsS0FBSyxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUM7SUFDeEYsQ0FBQztJQUVELElBQUksT0FBTztRQUNULE9BQU8sQ0FBQyxJQUFJLENBQUMsU0FBUyxJQUFJLElBQUksQ0FBQyxTQUFTLENBQUMsU0FBUyxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDLE9BQU8sSUFBSSxDQUFDLENBQUMsT0FBTyxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsSUFBSSxLQUFLLENBQUM7SUFDbkcsQ0FBQztJQUVELElBQUksT0FBTztRQUNULE9BQU8sQ0FBQyxJQUFJLENBQUMsU0FBUyxJQUFJLElBQUksQ0FBQyxTQUFTLENBQUMsU0FBUyxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDLE9BQU8sSUFBSSxDQUFDLENBQUMsT0FBTyxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsSUFBSSxLQUFLLENBQUM7SUFDbkcsQ0FBQztJQUVELElBQUksT0FBTztRQUNULE9BQU8sSUFBSSxDQUFDLGNBQWMsQ0FBQyxLQUFLLElBQUksQ0FBQyxJQUFJLENBQUMsU0FBUyxJQUFJLElBQUksQ0FBQyxTQUFTLENBQUMsU0FBUyxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDLE9BQU8sSUFBSSxDQUFDLENBQUMsT0FBTyxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsSUFBSSxLQUFLLENBQUM7SUFDaEksQ0FBQztJQUVELElBQUksTUFBTTtRQUNSLE9BQU8sQ0FBQyxJQUFJLENBQUMsY0FBYyxDQUFDLEtBQUssSUFBSSxDQUFDLENBQUMsSUFBSSxDQUFDLFNBQVMsSUFBSSxJQUFJLENBQUMsU0FBUyxDQUFDLFNBQVMsQ0FB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LElBQUksQ0FBQyxnQkFBZ0IsR0FBRyxDQUFDLENBQUM7UUFDMUIsTUFBTSxLQUFLLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQyxDQUFDO0lBQzNCLENBQUM7SUFJUyxLQUFLLENBQUMsaUJBQWlCO1FBQy9CLHdCQUF3QjtRQUN4QixNQUFNLE9BQU8sR0FBRyxNQUFNLE9BQU8sQ0FBQyxHQUFHLENBQUM7WUFDaEMsR0FBRyxJQUFJLENBQUMsTUFBTTtZQUNkLEdBQUcsSUFBSSxDQUFDLE9BQU87U0FDaEI7YUFDRSxNQUFNLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsS0FBSyxDQUFDO2FBQ3BCLEdBQUcsQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQyxJQUFJLEVBQUUsQ0FBQyxDQUFDLENBQUM7UUFFdkIsT0FBTyxDQUFDLE9BQU8sQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLEVBQUUsQ0FBQyxLQUFLLEtBQUssSUFBSSxDQUFDLENBQUM7SUFDaEQsQ0FBQzs7eUdBcE1tQixZQUFZOzZGQUFaLFlBQVk7MkZBQVosWUFBWTtrQkFGakMsU0FBUzs7MEJBMkJMLFFBQVE7OzBCQUlSLFFBQVE7NENBbEJGLHNCQUFzQjtzQkFBOUIsS0FBSztnQkFFTyxnQkFBZ0I7c0JBQTVCLEtBQUs7Z0JBT2Esc0JBQXNCO3NCQUF4QyxNQUFNO2dCQUVrQyxRQUFRO3NCQUFoRCxTQUFTO3VCQUFDLFVBQVUsRUFBRSxFQUFFLE1BQU0sRUFBRSxJQUFJLEVBQUUiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQge0FmdGVyVmlld0luaXQsIERpcmVjdGl2ZSwgRXZlbnRFbWl0dGVyLCBJbnB1dCwgT25EZXN0cm95LCBPbkluaXQsIE9wdGlvbmFsLCBPdXRwdXQsIFZpZXdDaGlsZH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQge0FjdGl2YXRlZFJvdXRlLCBQYXJhbXMsIFJvdXRlcn0gZnJvbSAnQGFuZ3VsYXIvcm91dGVyJztcbmltcG9ydCB7TWF0VGFiQ2hhbmdlRXZlbnQsIE1hdFRhYkdyb3VwfSBmcm9tICdAYW5ndWxhci9tYXRlcmlhbC90YWJzJztcbmltcG9ydCB7QWxlcnRDb250cm9sbGVyLCBJb25Db250ZW50LCBUb2FzdENvbnRyb2xsZXJ9IGZyb20gJ0Bpb25pYy9hbmd1bGFyJztcbmltcG9ydCB7VHJhbnNsYXRlU2VydmljZX0gZnJvbSAnQG5neC10cmFuc2xhdGUvY29yZSc7XG5pbXBvcnQge0JlaGF2aW9yU3ViamVjdCwgU3ViamVjdCwgU3Vic2NyaXB0aW9uLCBUZWFyZG93bkxvZ2ljfSBmcm9tICdyeGpzJztcbmltcG9ydCB7QXBwVGFibGV9IGZyb20gJy4uL3RhYmxlL3RhYmxlLmNsYXNzJztcbmltcG9ydCB7QXBwRm9ybX0gZnJvbSAnLi9mb3JtLmNsYXNzJztcbmltcG9ydCB7Rm9ybUJ1dHRvbnNCYXJUb2tlbn0gZnJvbSAnLi9mb3JtLWJ1dHRvbnMtYmFyLmNvbXBvbmVudCc7XG5pbXBvcnQge0FwcEZvcm1Qcm92aWRlciwgQXBwRm9ybVV0aWxzLCBJQXBwRm9ybSwgSUFwcEZvcm1HZXR0ZXJ9IGZyb20gJy4vZm9ybS51dGlscyc7XG5pbXBvcnQge1Nob3dUb2FzdE9wdGlvbnMsIFRvYXN0c30gZnJvbSAnLi4vLi4vc2hhcmVkL3RvYXN0L3RvYXN0cyc7XG5pbXBvcnQge0hhbW1lclN3aXBlRXZlbnR9IGZyb20gJy4uLy4uL3NoYXJlZC9nZXN0dXJlL2hhbW1lci51dGlscyc7XG5pbXBvcnQge1Rvb2xiYXJUb2tlbn0gZnJvbSAnLi4vLi4vc2hhcmVkL3Rvb2xiYXIvdG9vbGJhcic7XG5pbXBvcnQge2lzTm90TmlsLCB0b051bWJlcn0gZnJvbSAnLi4vLi4vc2hhcmVkL2Z1bmN0aW9ucyc7XG5pbXBvcnQge0NhbkxlYXZlfSBmcm9tICcuLi8uLi9zaGFyZWQvZ3VhcmQvY29tcG9uZW50LWRpcnR5Lmd1YXJkJztcbmltcG9ydCB7QWJzdHJhY3RDb250cm9sfSBmcm9tICdAYW5ndWxhci9mb3Jtcyc7XG5pbXBvcnQge3dhaXRGb3JGYWxzZSwgV2FpdEZvck9wdGlvbnMsIHdhaXRGb3JUcnVlfSBmcm9tICcuLi8uLi9zaGFyZWQvb2JzZXJ2YWJsZXMnO1xuXG5leHBvcnQgaW50ZXJmYWNlIElBcHBFZGl0b3IgZXh0ZW5kcyBDYW5MZWF2ZSwgSUFwcEZvcm0ge1xuICBzYXZlKGV2ZW50PzogRXZlbnQsIG9wdGlvbnM/OiBhbnkpOiBQcm9taXNlPGJvb2xlYW4+O1xuICBjYW5jZWwoZXZlbnQ/OiBFdmVudCk6IFByb21pc2U8dm9pZD47XG4gIGFkZENoaWxkRm9ybShmb3JtOiBJQXBwRm9ybSB8IElBcHBGb3JtR2V0dGVyKTogdm9pZDtcbn1cblxuZXhwb3J0IGludGVyZmFjZSBJQXBwVGFiRWRpdG9yIGV4dGVuZHMgSUFwcEVkaXRvciB7XG4gIHNlbGVjdGVkVGFiSW5kZXg6IG51bWJlcjtcbiAgc2V0U2VsZWN0ZWRUYWJJbmRleCh2YWx1ZTogbnVtYmVyLCBvcHRzPzoge2VtaXRFdmVudD86IGJvb2xlYW47IHJlYWxpZ25JbmtCYXI/OiBib29sZWFuO30pOiB2b2lkO1xuICB1bmxvYWQob3B0cz86IHtlbWl0RXZlbnQ/OiBib29sZWFufSk6IFByb21pc2U8dm9pZD47XG4gIHJlYWxpZ25JbmtCYXIoKTtcbn1cblxuZXhwb3J0IGNsYXNzIEFwcFRhYkVkaXRvck9wdGlvbnMge1xuXG4gIC8qKlxuICAgKiBOdW1iZXIgb2YgdGFiLiAxIGJ5IGRlZmF1bHRcbiAgICovXG4gIHRhYkNvdW50PzogbnVtYmVyO1xuXG4gIC8qKlxuICAgKiAnMjAwbXMnIGJ5IGRlZmF1bHRcbiAgICovXG4gIHRhYkdyb3VwQW5pbWF0aW9uRHVyYXRpb24/OiBzdHJpbmc7XG5cbiAgLyoqXG4gICAqIFNob3VsZCBlbmFibGUgc3dpcGUgYmV0d2VlbiB0YWIsIG9uIHRvdWNoIHNjcmVlblxuICAgKi9cbiAgZW5hYmxlU3dpcGU/OiBib29sZWFuOyAvLyB0cnVlIGJ5IGRlZmF1bHRcbn1cblxuQERpcmVjdGl2ZSgpXG4vLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgQGFuZ3VsYXItZXNsaW50L2RpcmVjdGl2ZS1jbGFzcy1zdWZmaXhcbmV4cG9ydCBhYnN0cmFjdCBjbGFzcyBBcHBFZGl0b3I8VCA9IGFueSwgSUQgPSBudW1iZXIsIE8gPSBhbnk+XG4gIGltcGxlbWVudHMgSUFwcEVkaXRvciwgT25Jbml0LCBPbkRlc3Ryb3ksIEFmdGVyVmlld0luaXQge1xuXG4gIHByaXZhdGUgX2NoaWxkcmVuOiBJQXBwRm9ybVtdO1xuICBwcml2YXRlIF9zdWJzY3JpcHRpb24gPSBuZXcgU3Vic2NyaXB0aW9uKCk7XG5cbiAgcHJvdGVjdGVkIF9lbmFibGVkID0gZmFsc2U7XG4gIHByb3RlY3RlZCB0b2FzdENvbnRyb2xsZXI6IFRvYXN0Q29udHJvbGxlcjtcbiAgcHJvdGVjdGVkIHJlYWRvbmx5IGRlc3Ryb3lTdWJqZWN0ID0gbmV3IFN1YmplY3Q8dm9pZD4oKTtcblxuICByZWFkb25seSByZWFkeVN1YmplY3QgPSBuZXcgQmVoYXZpb3JTdWJqZWN0PGJvb2xlYW4+KGZhbHNlKTtcbiAgcmVhZG9ubHkgZGlydHlTdWJqZWN0ID0gbmV3IEJlaGF2aW9yU3ViamVjdDxib29sZWFuPihmYWxzZSk7XG4gIHJlYWRvbmx5IGxvYWRpbmdTdWJqZWN0ID0gbmV3IEJlaGF2aW9yU3ViamVjdDxib29sZWFuPih0cnVlKTtcbiAgcmVhZG9ubHkgZXJyb3JTdWJqZWN0ID0gbmV3IEJlaGF2aW9yU3ViamVjdDxzdHJpbmc+KHVuZGVmaW5lZCk7XG4gIHJlYWRvbmx5IHNhdmluZ1N1YmplY3QgPSBuZXcgQmVoYXZpb3JTdWJqZWN0PGJvb2xlYW4+KGZhbHNlKTtcbiAgcmVhZG9ubHkgdG91Y2hlZFN1YmplY3QgPSBuZXcgQmVoYXZpb3JTdWJqZWN0PGJvb2xlYW4+KGZhbHNlKTtcblxuICBkZWJ1ZyA9IGZhbHNlO1xuICBwcmV2aW91c0RhdGFJZDogSUQ7XG4gIHN1Ym1pdHRlZCA9IGZhbHNlO1xuICBxdWVyeVBhcmFtczogUGFyYW1zO1xuICBpMThuQ29udGV4dDoge1xuICAgIHByZWZpeDogc3RyaW5nO1xuICAgIHN1ZmZpeDogc3RyaW5nO1xuICB9O1xuXG4gIC8qKlxuICAgKiAgQGRlcHJlY2F0ZWRcbiAgICovXG4gIHByb3RlY3RlZCBzZXQgX2xvYWRpbmcodmFsdWU6IGJvb2xlYW4pIHtcbiAgICB0aGlzLmxvYWRpbmdTdWJqZWN0Lm5leHQodmFsdWUpO1xuICB9XG5cbiAgLyoqXG4gICAqICBAZGVwcmVjYXRlZFxuICAgKi9cbiAgcHJvdGVjdGVkIGdldCBfbG9hZGluZygpOiBib29sZWFuIHtcbiAgICByZXR1cm4gdGhpcy5sb2FkaW5nU3ViamVjdC52YWx1ZTtcbiAgfVxuICAvKipcbiAgICogIEBkZXByZWNhdGVkXG4gICAqL1xuICBwcm90ZWN0ZWQgZ2V0IF8kcmVhZHkoKTogQmVoYXZpb3JTdWJqZWN0PGJvb2xlYW4+IHtcbiAgICByZXR1cm4gdGhpcy5yZWFkeVN1YmplY3Q7XG4gIH1cbiAgLyoqXG4gICAqICBAZGVwcmVjYXRlZFxuICAgKi9cbiAgcHJvdGVjdGVkIGdldCBfJGxvYWRpbmcoKTogQmVoYXZpb3JTdWJqZWN0PGJvb2xlYW4+IHtcbiAgICByZXR1cm4gdGhpcy5sb2FkaW5nU3ViamVjdDtcbiAgfVxuXG4gIGdldCBlcnJvcigpOiBzdHJpbmcge1xuICAgIHJldHVybiB0aGlzLmVycm9yU3ViamVjdC52YWx1ZTtcbiAgfVxuXG4gIHNldCBlcnJvcihlcnJvcjogc3RyaW5nKSB7XG4gICAgdGhpcy5zZXRFcnJvcihlcnJvcik7XG4gIH1cblxuICBnZXQgc2F2aW5nKCk6IGJvb2xlYW4ge1xuICAgIHJldHVybiB0aGlzLnNhdmluZ1N1YmplY3QudmFsdWUgfHwgdGhpcy5lZGl0b3JzPy5zb21lKGUgPT4gZS5zYXZpbmcpO1xuICB9XG5cbiAgQFZpZXdDaGlsZChUb29sYmFyVG9rZW4pIHRvb2xiYXI6IFRvb2xiYXJUb2tlbnxudWxsID0gbnVsbDtcbiAgQFZpZXdDaGlsZChGb3JtQnV0dG9uc0JhclRva2VuLCB7IHN0YXRpYzogdHJ1ZSB9KSBmb3JtQnV0dG9uc0JhcjogRm9ybUJ1dHRvbnNCYXJUb2tlbnxudWxsID0gbnVsbDtcbiAgQFZpZXdDaGlsZChJb25Db250ZW50LCB7c3RhdGljOiB0cnVlfSkgY29udGVudDogSW9uQ29udGVudDtcblxuICBnZXQgdGFibGVzKCk6IEFwcFRhYmxlPGFueT5bXSB7XG4gICAgcmV0dXJuIHRoaXMuX2NoaWxkcmVuICYmICh0aGlzLl9jaGlsZHJlbi5maWx0ZXIoYyA9PiBjIGluc3RhbmNlb2YgQXBwVGFibGUpIGFzIEFwcFRhYmxlPGFueT5bXSk7XG4gIH1cbiAgZ2V0IGZvcm1zKCk6IEFwcEZvcm08YW55PltdIHtcbiAgICByZXR1cm4gdGhpcy5fY2hpbGRyZW4gJiYgKHRoaXMuX2NoaWxkcmVuLmZpbHRlcihjID0+IGMgaW5zdGFuY2VvZiBBcHBGb3JtKSBhcyBBcHBGb3JtPGFueT5bXSk7XG4gIH1cbiAgZ2V0IGVkaXRvcnMoKTogQXBwRWRpdG9yPGFueT5bXSB7XG4gICAgcmV0dXJuIHRoaXMuX2NoaWxkcmVuICYmICh0aGlzLl9jaGlsZHJlbi5maWx0ZXIoYyA9PiBjIGluc3RhbmNlb2YgQXBwRWRpdG9yKSBhcyBBcHBFZGl0b3JbXSk7XG4gIH1cbiAgZ2V0IGRpcnR5KCk6IGJvb2xlYW4ge1xuICAgIHJldHVybiB0aGlzLmRpcnR5U3ViamVjdC52YWx1ZSB8fCAodGhpcy5fY2hpbGRyZW4gJiYgdGhpcy5fY2hpbGRyZW4uZmluZEluZGV4KGMgPT4gYy5lbmFibGVkICYmIGMuZGlydHkpICE9PSAtMSkgfHwgZmFsc2U7XG4gIH1cblxuICAvKipcbiAgICogSXMgdmFsaWQgKHRhYmxlcyBhbmQgZm9ybXMpXG4gICAqL1xuICBnZXQgdmFsaWQoKTogYm9vbGVhbiB7XG4gICAgLy8gSW1wb3J0YW50OiBTaG91bGQgYmUgbm90IGludmFsaWQgQU5EIG5vdCBwZW5kaW5nLCBzbyB1c2UgJyF2YWxpZCcgKERPIE5PVCB1c2UgJ2ludmFsaWQnKVxuICAgIHJldHVybiAhdGhpcy5fY2hpbGRyZW4gfHwgdGhpcy5fY2hpbGRyZW4uZmluZEluZGV4KGMgPT4gYy5lbmFibGVkICYmICFjLnZhbGlkKSA9PT0gLTE7XG4gIH1cblxuICBnZXQgaW52YWxpZCgpOiBib29sZWFuIHtcbiAgICByZXR1cm4gKHRoaXMuX2NoaWxkcmVuICYmIHRoaXMuX2NoaWxkcmVuLmZpbmRJbmRleChjID0+IGMuZW5hYmxlZCAmJiBjLmludmFsaWQpICE9PSAtMSkgfHwgZmFsc2U7XG4gIH1cblxuICBnZXQgcGVuZGluZygpOiBib29sZWFuIHtcbiAgICByZXR1cm4gKHRoaXMuX2NoaWxkcmVuICYmIHRoaXMuX2NoaWxkcmVuLmZpbmRJbmRleChjID0+IGMuZW5hYmxlZCAmJiBjLnBlbmRpbmcpICE9PSAtMSkgfHwgZmFsc2U7XG4gIH1cblxuICBnZXQgbG9hZGluZygpOiBib29sZWFuIHtcbiAgICByZXR1cm4gdGhpcy5sb2FkaW5nU3ViamVjdC52YWx1ZSB8fCAodGhpcy5fY2hpbGRyZW4gJiYgdGhpcy5fY2hpbGRyZW4uZmluZEluZGV4KGMgPT4gYy5lbmFibGVkICYmIGMubG9hZGluZykgIT09IC0xKSB8fCBmYWxzZTtcbiAgfVxuXG4gIGdldCBsb2FkZWQoKTogYm9vbGVhbiB7XG4gICAgcmV0dXJuICF0aGlzLmxvYWRpbmdTdWJqZWN0LnZhbHVlICYmICghdGhpcy5fY2hpbGRyZW4gfHwgdGhpcy5fY2hpbGRyZW4uZmluZEluZGV4KGMgPT4gYy5lbmFibGVkICYmIGMubG9hZGluZykgPT09IC0xKSB8fCBmYWxzZTtcbiAgfVxuXG4gIGdldCB0b3VjaGVkKCk6IGJvb2xlYW4ge1xuICAgIHJldHVybiB0aGlzLnRvdWNoZWRTdWJqZWN0LnZhbHVlIHx8ICh0aGlzLl9jaGlsZHJlbiAmJiB0aGlzLl9jaGlsZHJlbi5maW5kSW5kZXgoYyA9PiBjLmVuYWJsZWQgJiYgYy50b3VjaGVkKSAhPT0gLTEpIHx8IGZhbHNlO1xuICB9XG5cbiAgZ2V0IHVudG91Y2hlZCgpOiBib29sZWFuIHtcbiAgICByZXR1cm4gIXRoaXMudG91Y2hlZFN1YmplY3QudmFsdWUgJiYgKCF0aGlzLl9jaGlsZHJlbiB8fCB0aGlzLl9jaGlsZHJlbi5maW5kSW5kZXgoYyA9PiBjLmVuYWJsZWQgJiYgYy50b3VjaGVkKSA9PT0gLTEpIHx8IGZhbHNlO1xuICB9XG5cbiAgZ2V0IGVuYWJsZWQoKTogYm9vbGVhbiB7XG4gICAgcmV0dXJuIHRoaXMuX2VuYWJsZWQ7XG4gIH1cblxuICBnZXQgZGlzYWJsZWQoKTogYm9vbGVhbiB7XG4gICAgcmV0dXJuICF0aGlzLl9lbmFibGVkO1xuICB9XG5cbiAgZ2V0IGNoaWxkcmVuKCk6IElBcHBGb3JtW10ge1xuICAgIHJldHVybiB0aGlzLl9jaGlsZHJlbjtcbiAgfVxuXG4gIGdldCBlbXB0eSgpOiBib29sZWFuIHtcbiAgICByZXR1cm4gIXRoaXMuX2VuYWJsZWQ7XG4gIH1cblxuICBhYnN0cmFjdCBnZXQgaXNOZXdEYXRhKCk6IGJvb2xlYW47XG5cbiAgcHJvdGVjdGVkIGNvbnN0cnVjdG9yKFxuICAgIHByb3RlY3RlZCByb3V0ZTogQWN0aXZhdGVkUm91dGUsXG4gICAgcHJvdGVjdGVkIHJvdXRlcjogUm91dGVyLFxuICAgIHByb3RlY3RlZCBhbGVydEN0cmw6IEFsZXJ0Q29udHJvbGxlcixcbiAgICBwcm90ZWN0ZWQgdHJhbnNsYXRlOiBUcmFuc2xhdGVTZXJ2aWNlXG4gICkge1xuICB9XG5cbiAgbmdPbkluaXQoKSB7XG5cbiAgICBpZiAodGhpcy5mb3JtQnV0dG9uc0Jhcikge1xuICAgICAgdGhpcy5yZWdpc3RlclN1YnNjcmlwdGlvbih0aGlzLmZvcm1CdXR0b25zQmFyLm9uQmFjay5zdWJzY3JpYmUoZXZlbnQgPT4gdGhpcy5nb0JhY2soZXZlbnQpKSk7XG4gICAgfVxuICB9XG5cbiAgbmdBZnRlclZpZXdJbml0KCkge1xuICAgIC8vIENhbiBiZSBvdmVycmlkZGVuIGJ5IHN1YmNsYXNzZXNcbiAgfVxuXG4gIG5nT25EZXN0cm95KCkge1xuICAgIHRoaXMuX3N1YnNjcmlwdGlvbi51bnN1YnNjcmliZSgpO1xuXG4gICAgdGhpcy5yZWFkeVN1YmplY3QudW5zdWJzY3JpYmUoKTtcbiAgICB0aGlzLmxvYWRpbmdTdWJqZWN0LnVuc3Vic2NyaWJlKCk7XG4gICAgdGhpcy5lcnJvclN1YmplY3QudW5zdWJzY3JpYmUoKTtcblxuICAgIHRoaXMuZGVzdHJveVN1YmplY3QubmV4dCgpO1xuICAgIHRoaXMuZGVzdHJveVN1YmplY3QudW5zdWJzY3JpYmUoKTtcbiAgfVxuXG4gIGFkZENoaWxkRm9ybShmb3JtOiBJQXBwRm9ybSB8IElBcHBGb3JtR2V0dGVyKSB7XG4gICAgaWYgKCFmb3JtKSB0aHJvdyBuZXcgRXJyb3IoJ1RyeWluZyB0byByZWdpc3RlciBhbiB1bmRlZmluZWQgY2hpbGQgZm9ybScpO1xuICAgIHRoaXMuX2NoaWxkcmVuID0gdGhpcy5fY2hpbGRyZW4gfHwgW107XG4gICAgaWYgKHR5cGVvZiBmb3JtID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICB0aGlzLl9jaGlsZHJlbi5wdXNoKG5ldyBBcHBGb3JtUHJvdmlkZXIoZm9ybSkpO1xuICAgIH1cbiAgICBlbHNlIHtcbiAgICAgIHRoaXMuX2NoaWxkcmVuLnB1c2goZm9ybSk7XG4gICAgfVxuICAgIHJldHVybiB0aGlzO1xuICB9XG5cbiAgYWRkQ2hpbGRGb3Jtcyhmb3JtczogKElBcHBGb3JtIHwgSUFwcEZvcm1HZXR0ZXIpW10pIHtcbiAgICAoZm9ybXMgfHwgW10pLmZvckVhY2goZm9ybSA9PiB0aGlzLmFkZENoaWxkRm9ybShmb3JtKSk7XG4gIH1cblxuICByZW1vdmVDaGlsZEZvcm0oZm9ybTogSUFwcEZvcm0gfCBJQXBwRm9ybUdldHRlcik6IElBcHBGb3JtIHwgSUFwcEZvcm1HZXR0ZXIge1xuICAgIGlmICghZm9ybSkgdGhyb3cgbmV3IEVycm9yKCdUcnlpbmcgdG8gcmVtb3ZlIGFuIHVuZGVmaW5lZCBjaGlsZCBmb3JtJyk7XG4gICAgY29uc3QgaW5kZXggPSAodGhpcy5fY2hpbGRyZW4gfHwgW10pLmZpbmRJbmRleChjID0+IGMgPT09IGZvcm0pO1xuICAgIGlmIChpbmRleCAhPT0gLTEpIHtcbiAgICAgIHJldHVybiB0aGlzLl9jaGlsZHJlbi5zcGxpY2UoaW5kZXgsIDEpWzBdO1xuICAgIH1cbiAgICByZXR1cm4gdW5kZWZpbmVkO1xuICB9XG5cbiAgZGlzYWJsZShvcHRzPzoge29ubHlTZWxmPzogYm9vbGVhbjsgZW1pdEV2ZW50PzogYm9vbGVhbiB9KSB7XG4gICAgdGhpcy5fZW5hYmxlZCA9IGZhbHNlO1xuICAgIHRoaXMuX2NoaWxkcmVuPy5mb3JFYWNoKGMgPT4gYy5kaXNhYmxlKG9wdHMpKTtcbiAgICBpZiAoIXRoaXMubG9hZGluZyAmJiAoIW9wdHMgfHwgb3B0cy5lbWl0RXZlbnQgIT09IGZhbHNlKSkgdGhpcy5tYXJrRm9yQ2hlY2soKTtcbiAgfVxuXG4gIGVuYWJsZShvcHRzPzoge29ubHlTZWxmPzogYm9vbGVhbjsgZW1pdEV2ZW50PzogYm9vbGVhbiB9KSB7XG4gICAgdGhpcy5fZW5hYmxlZCA9IHRydWU7XG4gICAgdGhpcy5fY2hpbGRyZW4/LmZvckVhY2goYyA9PiBjLmVuYWJsZShvcHRzKSk7XG4gICAgaWYgKCF0aGlzLmxvYWRpbmcgJiYgKCFvcHRzIHx8IG9wdHMuZW1pdEV2ZW50ICE9PSBmYWxzZSkpIHRoaXMubWFya0ZvckNoZWNrKCk7XG4gIH1cblxuICBtYXJrQXNQcmlzdGluZShvcHRzPzoge29ubHlTZWxmPzogYm9vbGVhbjsgZW1pdEV2ZW50PzogYm9vbGVhbiB9KSB7XG4gICAgdGhpcy5lcnJvciA9IG51bGw7XG4gICAgdGhpcy5zdWJtaXR0ZWQgPSBmYWxzZTtcbiAgICBpZiAodGhpcy5kaXJ0eVN1YmplY3QudmFsdWUgIT09IGZhbHNlKSB7XG4gICAgICB0aGlzLmRpcnR5U3ViamVjdC5uZXh0KGZhbHNlKTtcbiAgICB9XG4gICAgdGhpcy5fY2hpbGRyZW4/LmZvckVhY2goYyA9PiBjLm1hcmtBc1ByaXN0aW5lKG9wdHMpKTtcbiAgICBpZiAoIXRoaXMubG9hZGluZyAmJiAoIW9wdHMgfHwgb3B0cy5lbWl0RXZlbnQgIT09IGZhbHNlKSkgdGhpcy5tYXJrRm9yQ2hlY2soKTtcbiAgfVxuXG4gIG1hcmtBc1VudG91Y2hlZChvcHRzPzoge29ubHlTZWxmPzogYm9vbGVhbjsgZW1pdEV2ZW50PzogYm9vbGVhbiB9KSB7XG4gICAgaWYgKHRoaXMudG91Y2hlZFN1YmplY3QudmFsdWUgIT09IGZhbHNlKSB7XG4gICAgICB0aGlzLnRvdWNoZWRTdWJqZWN0Lm5leHQoZmFsc2UpO1xuICAgIH1cbiAgICB0aGlzLl9jaGlsZHJlbj8uZm9yRWFjaChjID0+IGMubWFya0FzVW50b3VjaGVkKCkpO1xuICAgIGlmICghdGhpcy5sb2FkaW5nICYmICghb3B0cyB8fCBvcHRzLmVtaXRFdmVudCAhPT0gZmFsc2UpKSB0aGlzLm1hcmtGb3JDaGVjaygpO1xuICB9XG5cbiAgLyoqXG4gICAqIEBkZXByZWNhdGVkIHByZWZlciB0byB1c2UgbWFya0FsbEFzVG91Y2hlZCgpXG4gICAqIEBwYXJhbSBvcHRzXG4gICAqL1xuICBtYXJrQXNUb3VjaGVkKG9wdHM/OiB7b25seVNlbGY/OiBib29sZWFuOyBlbWl0RXZlbnQ/OiBib29sZWFuIH0pIHtcbiAgICBpZiAoIXRoaXMudG91Y2hlZFN1YmplY3QudmFsdWUgIT09IHRydWUpIHtcbiAgICAgIHRoaXMudG91Y2hlZFN1YmplY3QubmV4dCh0cnVlKTtcbiAgICB9XG4gICAgdGhpcy5fY2hpbGRyZW4/LmZvckVhY2goYyA9PiBjLm1hcmtBc1RvdWNoZWQob3B0cykpO1xuICAgIGlmICghdGhpcy5sb2FkaW5nICYmICghb3B0cyB8fCBvcHRzLmVtaXRFdmVudCAhPT0gZmFsc2UpKSB0aGlzLm1hcmtGb3JDaGVjaygpO1xuICB9XG5cbiAgbWFya0FsbEFzVG91Y2hlZChvcHRzPzoge2VtaXRFdmVudD86IGJvb2xlYW4gfSkge1xuICAgIGlmICh0aGlzLnRvdWNoZWRTdWJqZWN0LnZhbHVlICE9PSB0cnVlKSB7XG4gICAgICB0aGlzLnRvdWNoZWRTdWJqZWN0Lm5leHQodHJ1ZSk7XG4gICAgfVxuICAgIHRoaXMuX2NoaWxkcmVuPy5mb3JFYWNoKGMgPT4gYy5tYXJrQWxsQXNUb3VjaGVkKG9wdHMpKTtcbiAgICBpZiAoIXRoaXMubG9hZGluZyAmJiAoIW9wdHMgfHwgb3B0cy5lbWl0RXZlbnQgIT09IGZhbHNlKSkgdGhpcy5tYXJrRm9yQ2hlY2soKTtcbiAgfVxuXG4gIG1hcmtBc0RpcnR5KG9wdHM/OiB7b25seVNlbGY/OiBib29sZWFuOyBlbWl0RXZlbnQ/OiBib29sZWFuO30pe1xuICAgIGlmICghdGhpcy5kaXJ0eVN1YmplY3QudmFsdWUpIHtcbiAgICAgIHRoaXMuZGlydHlTdWJqZWN0Lm5leHQodHJ1ZSk7XG4gICAgICBpZiAoIXRoaXMubG9hZGluZyAmJiAoIW9wdHMgfHwgb3B0cy5lbWl0RXZlbnQgIT09IGZhbHNlKSkgdGhpcy5tYXJrRm9yQ2hlY2soKTtcbiAgICB9XG4gIH1cblxuICBtYXJrQXNMb2FkaW5nKG9wdHM/OiB7b25seVNlbGY/OiBib29sZWFuOyBlbWl0RXZlbnQ/OiBib29sZWFuO30pe1xuICAgIGlmICghdGhpcy5sb2FkaW5nU3ViamVjdC52YWx1ZSkge1xuICAgICAgdGhpcy5sb2FkaW5nU3ViamVjdC5uZXh0KHRydWUpO1xuICAgICAgaWYgKCFvcHRzIHx8IG9wdHMuZW1pdEV2ZW50ICE9PSBmYWxzZSkgdGhpcy5tYXJrRm9yQ2hlY2soKTtcbiAgICB9XG4gIH1cblxuICBtYXJrQXNMb2FkZWQob3B0cz86IHtcbiAgICBvbmx5U2VsZj86IGJvb2xlYW47XG4gICAgZW1pdEV2ZW50PzogYm9vbGVhbjtcbiAgfSl7XG4gICAgaWYgKHRoaXMubG9hZGluZ1N1YmplY3QudmFsdWUpIHtcbiAgICAgIHRoaXMubG9hZGluZ1N1YmplY3QubmV4dChmYWxzZSk7XG4gICAgICBpZiAoIW9wdHMgfHwgb3B0cy5vbmx5U2VsZiAhPT0gdHJ1ZSkge1xuICAgICAgICAvLyBFbWl0IHRvIGNoaWxkcmVuIGZvcm1zIGFuZCBlZGl0b3JzXG4gICAgICAgIC8vIG5vdGU6IHRhYmxlcyBzaG91bGQgYmUgY2hhbmdlZCBieSBwYXJlbnRcbiAgICAgICAgdGhpcy5mb3Jtcz8uZm9yRWFjaChmID0+IGYubWFya0FzTG9hZGVkKG9wdHMpKTtcbiAgICAgICAgdGhpcy5lZGl0b3JzPy5mb3JFYWNoKGUgPT4gZS5tYXJrQXNMb2FkZWQob3B0cykpO1xuICAgICAgfVxuICAgICAgaWYgKCFvcHRzIHx8IG9wdHMuZW1pdEV2ZW50ICE9PSBmYWxzZSkge1xuICAgICAgICB0aGlzLm1hcmtGb3JDaGVjaygpO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIG1hcmtBc1JlYWR5KG9wdHM/OiB7ZW1pdEV2ZW50PzogYm9vbGVhbiB9KSB7XG4gICAgdGhpcy5fY2hpbGRyZW4/LmZvckVhY2goYyA9PiBjLm1hcmtBc1JlYWR5KG9wdHMpKTtcbiAgICB0aGlzLnJlYWR5U3ViamVjdC5uZXh0KHRydWUpO1xuICB9XG5cbiAgcmVhZHkob3B0cz86IFdhaXRGb3JPcHRpb25zKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgaWYgKHRoaXMucmVhZHlTdWJqZWN0LnZhbHVlKSByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKCk7XG4gICAgcmV0dXJuIHdhaXRGb3JUcnVlKHRoaXMucmVhZHlTdWJqZWN0LCBvcHRzKTtcbiAgfVxuXG4gIHdhaXRJZGxlKG9wdHM/OiBXYWl0Rm9yT3B0aW9ucyk6IFByb21pc2U8dm9pZD4ge1xuICAgIGlmICghdGhpcy5sb2FkaW5nU3ViamVjdC52YWx1ZSkgcmV0dXJuIFByb21pc2UucmVzb2x2ZSgpO1xuICAgIHJldHVybiB3YWl0Rm9yRmFsc2UodGhpcy5sb2FkaW5nU3ViamVjdCwgb3B0cyk7XG4gIH1cblxuICBtYXJrQXNTYXZpbmcob3B0cz86IHsgZW1pdEV2ZW50PzogYm9vbGVhbiB9KXtcbiAgICBpZiAodGhpcy5zYXZpbmdTdWJqZWN0LnZhbHVlICE9PSB0cnVlKSB7XG4gICAgICB0aGlzLnNhdmluZ1N1YmplY3QubmV4dCh0cnVlKTtcbiAgICAgIGlmICghb3B0cyB8fCBvcHRzLmVtaXRFdmVudCAhPT0gZmFsc2UpIHRoaXMubWFya0ZvckNoZWNrKCk7XG4gICAgfVxuICB9XG5cbiAgbWFya0FzU2F2ZWQob3B0cz86IHsgZW1pdEV2ZW50PzogYm9vbGVhbiB9KXtcbiAgICBpZiAodGhpcy5zYXZpbmdTdWJqZWN0LnZhbHVlICE9PSBmYWxzZSkge1xuICAgICAgdGhpcy5zYXZpbmdTdWJqZWN0Lm5leHQoZmFsc2UpO1xuICAgICAgaWYgKCFvcHRzIHx8IG9wdHMuZW1pdEV2ZW50ICE9PSBmYWxzZSkgdGhpcy5tYXJrRm9yQ2hlY2soKTtcbiAgICB9XG4gIH1cblxuICBhc3luYyBjYW5jZWwoZXZlbnQ/OiBFdmVudCk6IFByb21pc2U8dm9pZD4ge1xuICAgIGlmICh0aGlzLmlzTmV3RGF0YSkge1xuICAgICAgYXdhaXQgdGhpcy51bmxvYWQoKTsgLy8gYXN5bmMgcmVzZXRcbiAgICB9XG4gICAgZWxzZSBpZiAodGhpcy5kaXJ0eSl7XG4gICAgICBhd2FpdCB0aGlzLnJlbG9hZCgpOyAvLyBhc3luYyByZWxvYWRcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogVW5sb2FkIHRoZSBwYWdlIChyZW1vdmUgYWxsIGRhdGEpLiBVc2VmdWwgd2hlbiByZXVzaW5nIGFuZ3VsYXIgY2FjaGUgYSBjYW5jZWxsZWQgcGFnZVxuICAgKlxuICAgKiBAcGFyYW0gb3B0c1xuICAgKi9cbiAgYXN5bmMgdW5sb2FkKG9wdHM/OiB7ZW1pdEV2ZW50PzogYm9vbGVhbiB9KTogUHJvbWlzZTx2b2lkPiB7XG4gICAgY29uc29sZS5kZWJ1ZygnW2VkaXRvcl0gVW5sb2FkaW5nIGRhdGEuLi4nKTtcbiAgICB0aGlzLm1hcmtBc0xvYWRpbmcoKTtcbiAgICB0aGlzLl9jaGlsZHJlbj8uZm9yRWFjaChmID0+IHtcbiAgICAgIGlmIChmIGluc3RhbmNlb2YgQXBwRm9ybSkge1xuICAgICAgICBmLnJlc2V0KG51bGwsIG9wdHMpO1xuICAgICAgfVxuICAgICAgZWxzZSBpZiAoZiBpbnN0YW5jZW9mIEFwcFRhYmxlKSB7XG4gICAgICAgIGYuZGF0YVNvdXJjZS5kaXNjb25uZWN0KCk7XG4gICAgICB9XG4gICAgICBlbHNlIGlmIChmIGluc3RhbmNlb2YgQXBwRWRpdG9yKSB7XG4gICAgICAgIGYudW5sb2FkKG9wdHMpO1xuICAgICAgfVxuICAgIH0pO1xuXG4gICAgdGhpcy5tYXJrQXNQcmlzdGluZShvcHRzKTtcbiAgICB0aGlzLm1hcmtBc1NhdmVkKG9wdHMpO1xuICB9XG5cbiAgYXN5bmMgcmVsb2FkV2l0aENvbmZpcm1hdGlvbihjb25maXJtPzogYm9vbGVhbikge1xuICAgIGNvbnN0IG5lZWRDb25maXJtID0gdGhpcy5kaXJ0eTtcbiAgICAvLyBpZiBub3QgY29uZmlybSB5ZXQ6IGFzayBjb25maXJtYXRpb25cbiAgICBpZiAoIWNvbmZpcm0gJiYgbmVlZENvbmZpcm0pIHtcbiAgICAgIGNvbnN0IHRyYW5zbGF0aW9ucyA9IHRoaXMudHJhbnNsYXRlLmluc3RhbnQoWydDT01NT04uQlROX0FCT1JUX0NIQU5HRVMnLCAnQ09NTU9OLkJUTl9DQU5DRUwnLCAnQ09ORklSTS5DQU5DRUxfQ0hBTkdFUycsICdDT05GSVJNLkFMRVJUX0hFQURFUiddKTtcbiAgICAgIGNvbnN0IGFsZXJ0ID0gYXdhaXQgdGhpcy5hbGVydEN0cmwuY3JlYXRlKHtcbiAgICAgICAgaGVhZGVyOiB0cmFuc2xhdGlvbnNbJ0NPTkZJUk0uQUxFUlRfSEVBREVSJ10sXG4gICAgICAgIG1lc3NhZ2U6IHRyYW5zbGF0aW9uc1snQ09ORklSTS5DQU5DRUxfQ0hBTkdFUyddLFxuICAgICAgICBidXR0b25zOiBbXG4gICAgICAgICAge1xuICAgICAgICAgICAgdGV4dDogdHJhbnNsYXRpb25zWydDT01NT04uQlROX0FCT1JUX0NIQU5HRVMnXSxcbiAgICAgICAgICAgIGNzc0NsYXNzOiAnc2Vjb25kYXJ5JyxcbiAgICAgICAgICAgIGhhbmRsZXI6ICgpID0+IHtcbiAgICAgICAgICAgICAgY29uZmlybSA9IHRydWU7IC8vIHVwZGF0ZSB1cHBlciB2YWx1ZVxuICAgICAgICAgICAgfVxuICAgICAgICAgIH0sXG4gICAgICAgICAge1xuICAgICAgICAgICAgdGV4dDogdHJhbnNsYXRpb25zWydDT01NT04uQlROX0NBTkNFTCddLFxuICAgICAgICAgICAgcm9sZTogJ2NhbmNlbCcsXG4gICAgICAgICAgICBoYW5kbGVyOiAoKSA9PiB7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgICBdXG4gICAgICB9KTtcbiAgICAgIGF3YWl0IGFsZXJ0LnByZXNlbnQoKTtcbiAgICAgIGF3YWl0IGFsZXJ0Lm9uRGlkRGlzbWlzcygpO1xuICAgIH1cblxuICAgIC8vIElmIGNvbmZpcm06IGV4ZWN1dGUgdGhlIHJlbG9hZFxuICAgIGlmIChjb25maXJtIHx8ICFuZWVkQ29uZmlybSkge1xuICAgICAgdGhpcy5zY3JvbGxUb1RvcCgpO1xuICAgICAgdGhpcy5kaXNhYmxlKCk7XG4gICAgICByZXR1cm4gYXdhaXQgdGhpcy5yZWxvYWQoKTtcbiAgICB9XG4gIH1cblxuICBhc3luYyBnb0JhY2soZXZlbnQ/OiBFdmVudCk6IFByb21pc2U8dm9pZCB8IGJvb2xlYW4+IHtcbiAgICAvLyBHbyBiYWNrXG4gICAgaWYgKHRoaXMudG9vbGJhcj8uY2FuR29CYWNrKSB7XG4gICAgICByZXR1cm4gdGhpcy50b29sYmFyLmdvQmFjaygpO1xuICAgIH0gZWxzZSB7XG4gICAgICAvLyBCYWNrIHRvIGhvbWVcbiAgICAgIHJldHVybiB0aGlzLnJvdXRlci5uYXZpZ2F0ZUJ5VXJsKCcvJyk7XG4gICAgfVxuICB9XG5cblxuXG4gIGFic3RyYWN0IGxvYWQoaWQ/OiBJRCwgb3B0aW9ucz86IE8pOiBQcm9taXNlPHZvaWQ+O1xuXG4gIGFic3RyYWN0IHNhdmUoZXZlbnQ/OiBFdmVudCwgb3B0aW9ucz86IGFueSk6IFByb21pc2U8Ym9vbGVhbj47XG5cbiAgYWJzdHJhY3QgcmVsb2FkKCk6IFByb21pc2U8dm9pZD47XG5cbiAgbG9nRm9ybUVycm9ycyhwcmVmaXg/OiBzdHJpbmcpIHtcbiAgICBpZiAodGhpcy5kZWJ1ZykgY29uc29sZS5kZWJ1ZygnW2VkaXRvcl0gRWRpdG9yIG5vdCB2YWxpZC4gQ2hlY2tpbmcgd2hlcmUgKGZvcm1zLCB0YWJsZXMpLi4uJyk7XG4gICAgdGhpcy5fY2hpbGRyZW4/LmZvckVhY2goYyA9PiB0aGlzLmxvZ0NoaWxkcmVuRXJyb3JzKGMsIHByZWZpeCkpO1xuICB9XG5cbiAgLyogLS0gcHJvdGVjdGVkIG1ldGhvZHMgLS0gKi9cblxuICBwcm90ZWN0ZWQgYXN5bmMgc2Nyb2xsVG9Ub3AoZHVyYXRpb24/OiBudW1iZXIpIHtcbiAgICBkdXJhdGlvbiA9IHRvTnVtYmVyKGR1cmF0aW9uLCA1MDApO1xuXG4gICAgaWYgKCF0aGlzLmNvbnRlbnQpIHtcbiAgICAgIGNvbnNvbGUud2FybihgW3RhYi1lZGl0b3JdIENhbm5vdCBzY3JvbGwgdG8gdG9wLiAobm8gJ2lvbi1jb250ZW50JyB0YWcgZm91bmQgJHt0aGlzLmNvbnN0cnVjdG9yLm5hbWV9YCk7XG5cbiAgICAgIC8vIFRPRE86IEZJWE1FIChub3Qgd29ya2luZyBhcyB0aGUgcGFnZSBpcyBub3QgdGhlIHdpbmRvdylcbiAgICAgIGNvbnN0IHNjcm9sbFRvVG9wID0gd2luZG93LnNldEludGVydmFsKCgpID0+IHtcbiAgICAgICAgY29uc3QgcG9zID0gd2luZG93LnNjcm9sbFk7XG4gICAgICAgIGlmIChwb3MgPiAwKSB7XG4gICAgICAgICAgd2luZG93LnNjcm9sbFRvKDAsIHBvcyAtIDIwKTsgLy8gaG93IGZhciB0byBzY3JvbGwgb24gZWFjaCBzdGVwXG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgd2luZG93LmNsZWFySW50ZXJ2YWwoc2Nyb2xsVG9Ub3ApO1xuICAgICAgICB9XG4gICAgICB9LCAxNik7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgcmV0dXJuIHRoaXMuY29udGVudC5zY3JvbGxUb1RvcChkdXJhdGlvbik7XG4gIH1cblxuICBwcm90ZWN0ZWQgcmVnaXN0ZXJTdWJzY3JpcHRpb24oc3ViOiBTdWJzY3JpcHRpb258VGVhcmRvd25Mb2dpYykge1xuICAgIHRoaXMuX3N1YnNjcmlwdGlvbi5hZGQoc3ViKTtcbiAgfVxuXG4gIHByb3RlY3RlZCB1bnJlZ2lzdGVyU3Vic2NyaXB0aW9uKHN1YjogU3Vic2NyaXB0aW9uKSB7XG4gICAgdGhpcy5fc3Vic2NyaXB0aW9uLnJlbW92ZShzdWIpO1xuICB9XG5cbiAgcHJvdGVjdGVkIGFzeW5jIHNhdmVJZkRpcnR5QW5kQ29uZmlybShldmVudD86IFVJRXZlbnQsIG9wdHM/OiB7XG4gICAgZW1pdEV2ZW50PzogYm9vbGVhbjtcbiAgICBjb25maXJtZWQ/OiBib29sZWFuXG4gIH0pOiBQcm9taXNlPGJvb2xlYW4+IHtcbiAgICBpZiAoIXRoaXMuZGlydHkpIHJldHVybiB0cnVlO1xuXG4gICAgbGV0IGNvbmZpcm1lZCA9IG9wdHM/LmNvbmZpcm1lZCB8fCBmYWxzZTtcbiAgICBpZiAoIWNvbmZpcm1lZCkge1xuICAgICAgbGV0IGNhbmNlbCA9IGZhbHNlO1xuICAgICAgY29uc3QgdHJhbnNsYXRpb25zID0gdGhpcy50cmFuc2xhdGUuaW5zdGFudChbJ0NPTU1PTi5CVE5fU0FWRScsICdDT01NT04uQlROX0NBTkNFTCcsICdDT01NT04uQlROX0FCT1JUX0NIQU5HRVMnLCAnQ09ORklSTS5TQVZFJywgJ0NPTkZJUk0uQUxFUlRfSEVBREVSJ10pO1xuICAgICAgY29uc3QgYWxlcnQgPSBhd2FpdCB0aGlzLmFsZXJ0Q3RybC5jcmVhdGUoe1xuICAgICAgICBoZWFkZXI6IHRyYW5zbGF0aW9uc1snQ09ORklSTS5BTEVSVF9IRUFERVInXSxcbiAgICAgICAgbWVzc2FnZTogdHJhbnNsYXRpb25zWydDT05GSVJNLlNBVkUnXSxcbiAgICAgICAgYnV0dG9uczogW1xuICAgICAgICAgIHtcbiAgICAgICAgICAgIHRleHQ6IHRyYW5zbGF0aW9uc1snQ09NTU9OLkJUTl9DQU5DRUwnXSxcbiAgICAgICAgICAgIHJvbGU6ICdjYW5jZWwnLFxuICAgICAgICAgICAgY3NzQ2xhc3M6ICdzZWNvbmRhcnknLFxuICAgICAgICAgICAgaGFuZGxlcjogKCkgPT4ge1xuICAgICAgICAgICAgICBjYW5jZWwgPSB0cnVlO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH0sXG4gICAgICAgICAge1xuICAgICAgICAgICAgdGV4dDogdHJhbnNsYXRpb25zWydDT01NT04uQlROX0FCT1JUX0NIQU5HRVMnXSxcbiAgICAgICAgICAgIGNzc0NsYXNzOiAnc2Vjb25kYXJ5JyxcbiAgICAgICAgICAgIGhhbmRsZXI6ICgpID0+IHtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9LFxuICAgICAgICAgIHtcbiAgICAgICAgICAgIHRleHQ6IHRyYW5zbGF0aW9uc1snQ09NTU9OLkJUTl9TQVZFJ10sXG4gICAgICAgICAgICBoYW5kbGVyOiAoKSA9PiB7XG4gICAgICAgICAgICAgIGNvbmZpcm1lZCA9IHRydWU7IC8vIHVwZGF0ZSB1cHBlciB2YWx1ZVxuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgXVxuICAgICAgfSk7XG4gICAgICBhd2FpdCBhbGVydC5wcmVzZW50KCk7XG4gICAgICBhd2FpdCBhbGVydC5vbkRpZERpc21pc3MoKTtcblxuICAgICAgaWYgKCFjb25maXJtZWQpIHtcbiAgICAgICAgcmV0dXJuICFjYW5jZWw7XG4gICAgICB9XG4gICAgfVxuXG4gICAgcmV0dXJuIGF3YWl0IHRoaXMuc2F2ZShldmVudCwgb3B0cyk7XG4gIH1cblxuICBwcm90ZWN0ZWQgYXN5bmMgc2hvd1RvYXN0KG9wdHM6IFNob3dUb2FzdE9wdGlvbnMpIHtcbiAgICBpZiAoIXRoaXMudG9hc3RDb250cm9sbGVyKSB0aHJvdyBuZXcgRXJyb3IoJ01pc3NpbmcgdG9hc3RDb250cm9sbGVyIGluIGNvbXBvbmVudFxcJ3MgY29uc3RydWN0b3InKTtcbiAgICBhd2FpdCBUb2FzdHMuc2hvdyh0aGlzLnRvYXN0Q29udHJvbGxlciwgdGhpcy50cmFuc2xhdGUsIG9wdHMpO1xuICB9XG5cbiAgcHJvdGVjdGVkIGxvZ0NoaWxkcmVuRXJyb3JzKGM6IElBcHBGb3JtIHwgQWJzdHJhY3RDb250cm9sLCBwcmVmaXg/OiBzdHJpbmcsIHBhdGg/OiBzdHJpbmcpIHtcbiAgICBwcmVmaXggPSBwcmVmaXggfHwgJ1thcHAtdGFiLWVkaXRvcl0gJztcbiAgICAvLyBJZiBlZGl0b3JcbiAgICBpZiAoYyBpbnN0YW5jZW9mIEFwcEVkaXRvcikge1xuICAgICAgYy5sb2dGb3JtRXJyb3JzKCk7XG4gICAgfVxuICAgIC8vIEFuZ3VsYXIgZm9ybSBjb250cm9sXG4gICAgZWxzZSBpZiAoYyBpbnN0YW5jZW9mIEFic3RyYWN0Q29udHJvbCkge1xuICAgICAgQXBwRm9ybVV0aWxzLmxvZ0Zvcm1FcnJvcnMoYywgcHJlZml4LCBwYXRoKTtcbiAgICB9XG4gICAgLy8gSWYgZm9ybSBwcm92aWRlcjogZ2V0IGRlbGVnYXRlXG4gICAgZWxzZSBpZiAoYyBpbnN0YW5jZW9mIEFwcEZvcm1Qcm92aWRlcikge1xuICAgICAgaWYgKCFjLmVtcHR5ICYmICFjLnZhbGlkKSB7XG4gICAgICAgIGMud2FpdERlbGVnYXRlKHt0aW1lb3V0OiAxMDAwfSkudGhlbihkZWxlZ2F0ZSA9PiB0aGlzLmxvZ0NoaWxkcmVuRXJyb3JzKGRlbGVnYXRlLCBwcmVmaXgsICdwcm92aWRlcicpKTtcbiAgICAgIH1cbiAgICB9XG4gICAgLy8gSWYgdGFibGVcbiAgICBlbHNlIGlmIChjIGluc3RhbmNlb2YgQXBwVGFibGUpIHtcbiAgICAgIGlmIChjLmludmFsaWQgJiYgYy5lZGl0ZWRSb3cgJiYgYy5lZGl0ZWRSb3cudmFsaWRhdG9yKSB7XG4gICAgICAgIGNvbnN0IHBhdGggPSBjLmNvbnN0cnVjdG9yLm5hbWUudG9Mb3dlckNhc2UoKTtcbiAgICAgICAgQXBwRm9ybVV0aWxzLmxvZ0Zvcm1FcnJvcnMoYy5lZGl0ZWRSb3cudmFsaWRhdG9yLCBwcmVmaXgsIHBhdGgpO1xuICAgICAgfVxuICAgIH1cbiAgICAvLyBJZiBmb3JtXG4gICAgZWxzZSBpZiAoYyBpbnN0YW5jZW9mIEFwcEZvcm0pIHtcbiAgICAgIGlmICghYy5lbXB0eSAmJiAhYy52YWxpZCkge1xuICAgICAgICBpZiAoYy5wZW5kaW5nKSB7XG4gICAgICAgICAgY29uc3QgcGF0aCA9IGMuY29uc3RydWN0b3IubmFtZS50b0xvd2VyQ2FzZSgpO1xuICAgICAgICAgIGNvbnNvbGUud2FybiggYCR7cHJlZml4fSAtPiAke3BhdGh9OiB3YWl0aW5nIHdoaWxlIHBlbmRpbmcuLi5gKTtcbiAgICAgICAgICBBcHBGb3JtVXRpbHMud2FpdFdoaWxlUGVuZGluZyhjLCB7dGltZW91dDogMTAwMH0pXG4gICAgICAgICAgICAudGhlbigoKSA9PiB0aGlzLmxvZ0NoaWxkcmVuRXJyb3JzKGMuZm9ybSwgcHJlZml4LCBwYXRoKSk7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgQXBwRm9ybVV0aWxzLmxvZ0Zvcm1FcnJvcnMoYy5mb3JtLCBwcmVmaXgpO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuICAgIC8vIElmIGVkaXRvclxuICAgIGVsc2UgaWYgKGMgaW5zdGFuY2VvZiBBcHBFZGl0b3IpIHtcbiAgICAgIGlmICghYy5lbXB0eSAmJiAhYy52YWxpZCkge1xuICAgICAgICBpZiAoYy5wZW5kaW5nKSB7XG4gICAgICAgICAgY29uc3QgcGF0aCA9IGMuY29uc3RydWN0b3IubmFtZS50b0xvd2VyQ2FzZSgpO1xuICAgICAgICAgIGNvbnNvbGUud2FybiggYCR7cHJlZml4fSAtPiAke3BhdGh9OiB3YWl0aW5nIHdoaWxlIHBlbmRpbmcuLi5gKTtcbiAgICAgICAgICBBcHBGb3JtVXRpbHMud2FpdFdoaWxlUGVuZGluZyhjLCB7dGltZW91dDogMTAwMH0pXG4gICAgICAgICAgICAudGhlbigoKSA9PiBjLmxvZ0Zvcm1FcnJvcnMocHJlZml4KSk7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgYy5sb2dGb3JtRXJyb3JzKHByZWZpeCk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG4gICAgZWxzZSB7XG4gICAgICBjb25zb2xlLndhcm4oIGAke3ByZWZpeH0gVW5rbm93biBjaGlsZHJlbiBzdWItZm9ybTogYCwgYyk7XG4gICAgfVxuICB9XG5cbiAgcHJvdGVjdGVkIHNldEVycm9yKHZhbHVlOiBzdHJpbmcsIG9wdHM/OiB7ZW1pdEV2ZW50PzogYm9vbGVhbjt9KSB7XG4gICAgaWYgKHRoaXMuZXJyb3JTdWJqZWN0LnZhbHVlICE9PSB2YWx1ZSkge1xuICAgICAgdGhpcy5lcnJvclN1YmplY3QubmV4dCh2YWx1ZSk7XG4gICAgICBpZiAoIW9wdHMgfHwgb3B0cy5lbWl0RXZlbnQgIT09IGZhbHNlKSB0aGlzLm1hcmtGb3JDaGVjaygpO1xuICAgIH1cbiAgfVxuXG4gIHByb3RlY3RlZCByZXNldEVycm9yKG9wdHM/OiB7ZW1pdEV2ZW50PzogYm9vbGVhbn0pIHtcbiAgICB0aGlzLnNldEVycm9yKHVuZGVmaW5lZCwgb3B0cyk7XG4gIH1cblxuICBwcm90ZWN0ZWQgbWFya0ZvckNoZWNrKCkge1xuICAgIC8vIFNob3VsZCBiZSBvdmVycmlkZSBieSBzdWJjbGFzc2VzLCBpZiBjaGFuZ2UgZGV0ZWN0aW9uIGlzIFB1c2hcbiAgfVxufVxuXG5ARGlyZWN0aXZlKClcbi8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBAYW5ndWxhci1lc2xpbnQvZGlyZWN0aXZlLWNsYXNzLXN1ZmZpeFxuZXhwb3J0IGFic3RyYWN0IGNsYXNzIEFwcFRhYkVkaXRvcjxUID0gYW55LCBJRCA9IG51bWJlciwgTyA9IGFueT5cbiAgZXh0ZW5kcyBBcHBFZGl0b3I8VCwgSUQsIE8+XG4gIGltcGxlbWVudHMgSUFwcFRhYkVkaXRvciB7XG5cbiAgcHJvdGVjdGVkIF9zZWxlY3RlZFRhYkluZGV4ID0gMDtcblxuICAvLyBFZGl0b3Igb3B0aW9uc1xuICB0YWJDb3VudDogbnVtYmVyO1xuICBlbmFibGVTd2lwZTogYm9vbGVhbjtcbiAgdGFiR3JvdXBBbmltYXRpb25EdXJhdGlvbjogc3RyaW5nO1xuXG4gIEBJbnB1dCgpIHF1ZXJ5VGFiSW5kZXhQYXJhbU5hbWU6IHN0cmluZztcblxuICBASW5wdXQoKSBzZXQgc2VsZWN0ZWRUYWJJbmRleCh2YWx1ZTogbnVtYmVyKSB7XG4gICAgdGhpcy5zZXRTZWxlY3RlZFRhYkluZGV4KHZhbHVlKTtcbiAgfVxuICBnZXQgc2VsZWN0ZWRUYWJJbmRleCgpOiBudW1iZXIge1xuICAgIHJldHVybiB0aGlzLl9zZWxlY3RlZFRhYkluZGV4O1xuICB9XG5cbiAgQE91dHB1dCgpIHJlYWRvbmx5IHNlbGVjdGVkVGFiSW5kZXhDaGFuZ2UgPSBuZXcgRXZlbnRFbWl0dGVyPG51bWJlcj4oKTtcblxuICBAVmlld0NoaWxkKCd0YWJHcm91cCcsIHsgc3RhdGljOiB0cnVlIH0pIHRhYkdyb3VwOiBNYXRUYWJHcm91cDtcblxuICBwcm90ZWN0ZWQgY29uc3RydWN0b3IoXG4gICAgQE9wdGlvbmFsKCkgcHJvdGVjdGVkIHJvdXRlOiBBY3RpdmF0ZWRSb3V0ZSwgLy8gTW9kYWwgZWRpdG9yIGdpdmUgJ251bGwnXG4gICAgcHJvdGVjdGVkIHJvdXRlcjogUm91dGVyLFxuICAgIHByb3RlY3RlZCBhbGVydEN0cmw6IEFsZXJ0Q29udHJvbGxlcixcbiAgICBwcm90ZWN0ZWQgdHJhbnNsYXRlOiBUcmFuc2xhdGVTZXJ2aWNlLFxuICAgIEBPcHRpb25hbCgpIG9wdGlvbnM/OiBBcHBUYWJFZGl0b3JPcHRpb25zKSB7XG4gICAgc3VwZXIocm91dGUsIHJvdXRlciwgYWxlcnRDdHJsLCB0cmFuc2xhdGUpO1xuICAgIG9wdGlvbnMgPSB7XG4gICAgICB0YWJDb3VudDogMSxcbiAgICAgIGVuYWJsZVN3aXBlOiB0cnVlLFxuICAgICAgdGFiR3JvdXBBbmltYXRpb25EdXJhdGlvbjogJzIwMG1zJyxcbiAgICAgIC4uLm9wdGlvbnNcbiAgICB9XG4gICAgdGhpcy50YWJDb3VudCA9IG9wdGlvbnMudGFiQ291bnQ7XG4gICAgdGhpcy5lbmFibGVTd2lwZSA9IG9wdGlvbnMuZW5hYmxlU3dpcGU7XG4gICAgdGhpcy50YWJHcm91cEFuaW1hdGlvbkR1cmF0aW9uID0gb3B0aW9ucy50YWJHcm91cEFuaW1hdGlvbkR1cmF0aW9uO1xuICAgIHRoaXMucXVlcnlUYWJJbmRleFBhcmFtTmFtZSA9ICd0YWInO1xuICB9XG5cbiAgbmdPbkluaXQoKSB7XG4gICAgc3VwZXIubmdPbkluaXQoKTtcblxuICAgIC8vIFJlYWQgdGhlIHNlbGVjdGVkIHRhYiBpbmRleCwgZnJvbSBwYXRoIHF1ZXJ5IHBhcmFtc1xuICAgIGlmICh0aGlzLnRhYkdyb3VwICYmIHRoaXMucm91dGUgJiYgdGhpcy5xdWVyeVRhYkluZGV4UGFyYW1OYW1lKSB7XG4gICAgICB0aGlzLnJlZ2lzdGVyU3Vic2NyaXB0aW9uKHRoaXMucm91dGUucXVlcnlQYXJhbXNcbiAgICAgICAgLnN1YnNjcmliZShxdWVyeVBhcmFtcyA9PiB7XG4gICAgICAgICAgdGhpcy5xdWVyeVBhcmFtcyA9IHsuLi5xdWVyeVBhcmFtc307XG5cbiAgICAgICAgICAvLyBQYXJzZSB0YWIgcGFyYW1cbiAgICAgICAgICBpZiAodGhpcy50YWJDb3VudCA+IDEgJiYgdGhpcy5xdWVyeVRhYkluZGV4UGFyYW1OYW1lKSB7XG4gICAgICAgICAgICBjb25zdCB0YWJJbmRleCA9IHF1ZXJ5UGFyYW1zW3RoaXMucXVlcnlUYWJJbmRleFBhcmFtTmFtZV07XG4gICAgICAgICAgICB0aGlzLnF1ZXJ5UGFyYW1zW3RoaXMucXVlcnlUYWJJbmRleFBhcmFtTmFtZV0gPSB0YWJJbmRleCAmJiBwYXJzZUludCh0YWJJbmRleCkgfHwgdW5kZWZpbmVkO1xuICAgICAgICAgICAgaWYgKGlzTm90TmlsKHRoaXMucXVlcnlQYXJhbXNbdGhpcy5xdWVyeVRhYkluZGV4UGFyYW1OYW1lXSkpIHtcbiAgICAgICAgICAgICAgdGhpcy5zZWxlY3RlZFRhYkluZGV4ID0gdGhpcy5xdWVyeVBhcmFtc1t0aGlzLnF1ZXJ5VGFiSW5kZXhQYXJhbU5hbWVdO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cblxuICAgICAgICAgIC8vIFJlYWxpZ24gdGFiLCBhZnRlciBhIGRlbGF5IGJlY2F1c2UgdGhlIHRhYiBjYW4gYmUgZGlzYWJsZWQgd2hlbiBjb21wb25lbnQgaXMgY3JlYXRlZFxuICAgICAgICAgIHNldFRpbWVvdXQoKCkgPT4gdGhpcy50YWJHcm91cC5yZWFsaWduSW5rQmFyKCksIDUwMCk7XG4gICAgICAgIH0pKTtcbiAgICB9XG4gIH1cblxuXG4gIG5nT25EZXN0cm95KCkge1xuICAgIHN1cGVyLm5nT25EZXN0cm95KCk7XG4gICAgdGhpcy5zZWxlY3RlZFRhYkluZGV4Q2hhbmdlLmNvbXBsZXRlKCk7XG4gICAgdGhpcy5sb2FkaW5nU3ViamVjdC51bnN1YnNjcmliZSgpO1xuICAgIHRoaXMuZXJyb3JTdWJqZWN0LnVuc3Vic2NyaWJlKCk7XG4gIH1cblxuICBzZXRTZWxlY3RlZFRhYkluZGV4KHZhbHVlOiBudW1iZXIsIG9wdHM/OiB7ZW1pdEV2ZW50PzogYm9vbGVhbjsgcmVhbGlnbklua0Jhcj86IGJvb2xlYW4gfSkge1xuICAgIC8vIEZpeCB2YWx1ZVxuICAgIGlmICh2YWx1ZSA8IDApIHtcbiAgICAgIHZhbHVlID0gMDtcbiAgICB9XG4gICAgZWxzZSBpZiAodmFsdWUgPiB0aGlzLnRhYkNvdW50IC0gMSkge1xuICAgICAgY29uc29sZS53YXJuKGBbdGFiLWVkaXRvcl0gSW52YWxpZCB0YWIgaW5kZXggJHt2YWx1ZX0uIE1heCB2YWx1ZSBpcyAke3RoaXMudGFiQ291bnQtMX1gKVxuICAgICAgdmFsdWUgPSB0aGlzLl9zZWxlY3RlZFRhYkluZGV4O1xuICAgIH1cblxuICAgIHRoaXMuX3NlbGVjdGVkVGFiSW5kZXggPSB2YWx1ZTtcbiAgICB0aGlzLnNlbGVjdGVkVGFiSW5kZXhDaGFuZ2UubmV4dCh2YWx1ZSk7XG5cbiAgICBpZiAodGhpcy50YWJHcm91cCAmJiAoIW9wdHMgfHwgb3B0cy5yZWFsaWduSW5rQmFyICE9PSBmYWxzZSkpIHtcbiAgICAgIHRoaXMudGFiR3JvdXAuc2VsZWN0ZWRJbmRleCA9IHZhbHVlO1xuICAgICAgdGhpcy5tYXJrRm9yQ2hlY2soKTtcbiAgICAgIC8vIFdhaXQgdGFiIGNoYW5nZSBpbiBVSSwgYmVmb3JlIHJlYWxpZ24gaW5rIHRhYlxuICAgICAgc2V0VGltZW91dCgoKSA9PiB0aGlzLnRhYkdyb3VwLnJlYWxpZ25JbmtCYXIoKSwgMjAwKTtcbiAgICB9XG4gICAgZWxzZSBpZiAoIW9wdHMgfHwgb3B0cy5lbWl0RXZlbnQgIT09IGZhbHNlKSB7XG4gICAgICB0aGlzLm1hcmtGb3JDaGVjaygpO1xuICAgIH1cbiAgfVxuXG4gIHJlYWxpZ25JbmtCYXIoKSB7XG4gICAgdGhpcy50YWJHcm91cD8ucmVhbGlnbklua0JhcigpO1xuICB9XG5cblxuICBvblRhYkNoYW5nZShldmVudDogTWF0VGFiQ2hhbmdlRXZlbnQsIHF1ZXJ5VGFiSW5kZXhQYXJhbU5hbWU/OiBzdHJpbmcpOiBib29sZWFuIHtcbiAgICBxdWVyeVRhYkluZGV4UGFyYW1OYW1lID0gcXVlcnlUYWJJbmRleFBhcmFtTmFtZSB8fCB0aGlzLnF1ZXJ5VGFiSW5kZXhQYXJhbU5hbWU7XG5cbiAgICBpZiAoIXF1ZXJ5VGFiSW5kZXhQYXJhbU5hbWUgfHwgIXRoaXMucm91dGUpIHJldHVybiB0cnVlOyAvLyBTa2lwIGlmIHRhYiBxdWVyeSBwYXJhbSBub3Qgc2V0LCBvciBubyByb3V0ZVxuXG4gICAgaWYgKCF0aGlzLnF1ZXJ5UGFyYW1zIHx8ICt0aGlzLnF1ZXJ5UGFyYW1zW3F1ZXJ5VGFiSW5kZXhQYXJhbU5hbWVdICE9PSBldmVudC5pbmRleCkge1xuXG4gICAgICB0aGlzLnF1ZXJ5UGFyYW1zID0gdGhpcy5xdWVyeVBhcmFtcyB8fCB7fTtcbiAgICAgIHRoaXMucXVlcnlQYXJhbXNbcXVlcnlUYWJJbmRleFBhcmFtTmFtZV0gPSBldmVudC5pbmRleDtcblxuICAgICAgaWYgKHF1ZXJ5VGFiSW5kZXhQYXJhbU5hbWUgPT09ICd0YWInICYmIGlzTm90TmlsKHRoaXMucXVlcnlQYXJhbXNbJ3N1YnRhYiddKSkge1xuICAgICAgICBkZWxldGUgdGhpcy5xdWVyeVBhcmFtcy5zdWJ0YWI7IC8vIGNsZWFuIHN1YnRhYlxuICAgICAgfVxuICAgICAgdGhpcy5yb3V0ZXIubmF2aWdhdGUoWycuJ10sIHtcbiAgICAgICAgcmVsYXRpdmVUbzogdGhpcy5yb3V0ZSxcbiAgICAgICAgcXVlcnlQYXJhbXM6IHRoaXMucXVlcnlQYXJhbXMsXG4gICAgICAgIHJlcGxhY2VVcmw6IHRydWVcbiAgICAgIH0pO1xuICAgICAgcmV0dXJuIHRydWU7XG4gICAgfVxuICAgIHJldHVybiBmYWxzZTtcbiAgfVxuXG4gIC8qKlxuICAgKiBBY3Rpb24gdHJpZ2dlcmVkIHdoZW4gdXNlciBzd2lwZXNcbiAgICovXG4gIG9uU3dpcGVUYWIoZXZlbnQ6IEhhbW1lclN3aXBlRXZlbnQpOiBib29sZWFuIHtcbiAgICAvLyBERUJVR1xuICAgIC8vIGlmICh0aGlzLmRlYnVnKSBjb25zb2xlLmRlYnVnKFwiW3RhYi1wYWdlXSBvblN3aXBlVGFiKClcIik7XG5cbiAgICAvLyBTa2lwLCBpZiBub3QgYSB2YWxpZCBzd2lwZSBldmVudFxuICAgIGlmICghdGhpcy5lbmFibGVTd2lwZSB8fCAhZXZlbnRcbiAgICAgIHx8IGV2ZW50LmRlZmF1bHRQcmV2ZW50ZWQgfHwgKGV2ZW50LnNyY0V2ZW50ICYmIGV2ZW50LnNyY0V2ZW50LmRlZmF1bHRQcmV2ZW50ZWQpXG4gICAgICB8fCBldmVudC5wb2ludGVyVHlwZSAhPT0gJ3RvdWNoJ1xuICAgICkge1xuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cblxuICAgIC8vIERFQlVHXG4gICAgLy9pZiAodGhpcy5kZWJ1ZylcbiAgICAvL2NvbnNvbGUuZGVidWcoXCJbdGFiLXBhZ2VdIERldGVjdGVkIHN3aXBlOiBcIiArIGV2ZW50LnR5cGUsIGV2ZW50KTtcblxuICAgIGxldCBzZWxlY3RUYWJJbmRleCA9IHRoaXMuc2VsZWN0ZWRUYWJJbmRleDtcbiAgICBzd2l0Y2ggKGV2ZW50LnR5cGUpIHtcbiAgICAgIC8vIE9wZW4gbmV4dCB0YWJcbiAgICAgIGNhc2UgJ3N3aXBlbGVmdCc6XG4gICAgICAgIGNvbnN0IGlzTGFzdCA9IHNlbGVjdFRhYkluZGV4ID49ICh0aGlzLnRhYkNvdW50IC0gMSk7XG4gICAgICAgIHNlbGVjdFRhYkluZGV4ID0gaXNMYXN0ID8gMCA6IHNlbGVjdFRhYkluZGV4ICsgMTtcbiAgICAgICAgYnJlYWs7XG5cblxuICAgICAgLy8gT3BlbiBwcmV2aW91cyB0YWJcbiAgICAgIGNhc2UgJ3N3aXBlcmlnaHQnOlxuICAgICAgICBjb25zdCBpc0ZpcnN0ID0gc2VsZWN0VGFiSW5kZXggPD0gMDtcbiAgICAgICAgc2VsZWN0VGFiSW5kZXggPSBpc0ZpcnN0ID8gdGhpcy50YWJDb3VudCA6IHNlbGVjdFRhYkluZGV4IC0gMTtcbiAgICAgICAgYnJlYWs7XG5cbiAgICAgIC8vIE90aGVyIGNhc2VcbiAgICAgIGRlZmF1bHQ6XG4gICAgICAgIGNvbnNvbGUuZXJyb3IoJ1t0YWItcGFnZV0gVW5rbm93biBzd2lwZSBhY3Rpb246ICcgKyBldmVudC50eXBlKTtcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cblxuICAgIHNldFRpbWVvdXQoKCkgPT4ge1xuICAgICAgdGhpcy5zZWxlY3RlZFRhYkluZGV4ID0gc2VsZWN0VGFiSW5kZXg7XG4gICAgICB0aGlzLm1hcmtGb3JDaGVjaygpO1xuICAgIH0pO1xuXG4gICAgcmV0dXJuIHRydWU7XG4gIH1cblxuICBvblN1YlRhYkNoYW5nZShldmVudDogTWF0VGFiQ2hhbmdlRXZlbnQpIHtcbiAgICB0aGlzLm9uVGFiQ2hhbmdlKGV2ZW50LCAnc3VidGFiJyk7XG4gIH1cblxuICBhc3luYyB1bmxvYWQob3B0cz86IHsgZW1pdEV2ZW50PzogYm9vbGVhbiB9KTogUHJvbWlzZTx2b2lkPiB7XG4gICAgdGhpcy5zZWxlY3RlZFRhYkluZGV4ID0gMDtcbiAgICBhd2FpdCBzdXBlci51bmxvYWQob3B0cyk7XG4gIH1cblxuICBwcm90ZWN0ZWQgYWJzdHJhY3QgZ2V0Rmlyc3RJbnZhbGlkVGFiSW5kZXgoKTogbnVtYmVyO1xuXG4gIHByb3RlY3RlZCBhc3luYyBzYXZlRGlydHlDaGlsZHJlbigpOiBQcm9taXNlPGJvb2xlYW4+IHtcbiAgICAvLyBTYXZlIGFsbCBkaXJ0eSB0YWJsZXNcbiAgICBjb25zdCByZXN1bHRzID0gYXdhaXQgUHJvbWlzZS5hbGwoW1xuICAgICAgLi4udGhpcy50YWJsZXMsXG4gICAgICAuLi50aGlzLmVkaXRvcnNcbiAgICBdXG4gICAgICAuZmlsdGVyKGMgPT4gYy5kaXJ0eSlcbiAgICAgIC5tYXAoYyA9PiBjLnNhdmUoKSkpO1xuXG4gICAgcmV0dXJuICFyZXN1bHRzLnNvbWUoc2F2ZWQgPT4gc2F2ZWQgIT09IHRydWUpO1xuICB9XG59XG4iXX0=