@sumaris-net/ngx-components 3.0.0-rc1 → 4.0.0-rc10

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 (677) hide show
  1. package/esm2022/public_api.mjs +340 -0
  2. package/{esm2020 → esm2022}/src/app/admin/admin-routing.module.mjs +8 -8
  3. package/{esm2020 → esm2022}/src/app/admin/admin.module.mjs +12 -12
  4. package/esm2022/src/app/admin/services/filter/person.filter.mjs +69 -0
  5. package/esm2022/src/app/admin/services/person.service.mjs +174 -0
  6. package/esm2022/src/app/admin/services/validator/person.validator.mjs +72 -0
  7. package/esm2022/src/app/admin/users/users.mjs +264 -0
  8. package/esm2022/src/app/admin/users/users.module.mjs +58 -0
  9. package/esm2022/src/app/core/about/about.modal.mjs +84 -0
  10. package/{esm2020 → esm2022}/src/app/core/about/about.module.mjs +9 -9
  11. package/{esm2020 → esm2022}/src/app/core/account/account.module.mjs +22 -22
  12. package/esm2022/src/app/core/account/account.page.mjs +337 -0
  13. package/esm2022/src/app/core/account/new-token.modal.mjs +130 -0
  14. package/esm2022/src/app/core/account/token.table.mjs +146 -0
  15. package/esm2022/src/app/core/auth/auth.form.mjs +140 -0
  16. package/esm2022/src/app/core/auth/auth.modal.mjs +76 -0
  17. package/{esm2020 → esm2022}/src/app/core/auth/auth.module.mjs +16 -16
  18. package/{esm2020 → esm2022}/src/app/core/core.module.mjs +87 -87
  19. package/{esm2020 → esm2022}/src/app/core/core.testing.module.mjs +23 -23
  20. package/esm2022/src/app/core/form/buttons/form-buttons-bar.component.mjs +109 -0
  21. package/{esm2020 → esm2022}/src/app/core/form/buttons/form-buttons-bar.module.mjs +10 -10
  22. package/esm2022/src/app/core/form/entity/editor.class.mjs +718 -0
  23. package/esm2022/src/app/core/form/entity/entity-editor-modal.class.mjs +436 -0
  24. package/esm2022/src/app/core/form/entity/entity-editor.class.mjs +730 -0
  25. package/esm2022/src/app/core/form/entity/entity-metadata.component.mjs +24 -0
  26. package/{esm2020 → esm2022}/src/app/core/form/entity/entity.module.mjs +11 -11
  27. package/esm2022/src/app/core/form/form.class.mjs +353 -0
  28. package/{esm2020 → esm2022}/src/app/core/form/form.module.mjs +30 -30
  29. package/{esm2020 → esm2022}/src/app/core/form/form.utils.mjs +69 -60
  30. package/esm2022/src/app/core/form/list/list.form.mjs +233 -0
  31. package/{esm2020 → esm2022}/src/app/core/form/list/list.module.mjs +10 -10
  32. package/esm2022/src/app/core/form/properties/properties.form.mjs +143 -0
  33. package/{esm2020 → esm2022}/src/app/core/form/properties/properties.module.mjs +13 -13
  34. package/esm2022/src/app/core/form/properties/properties.table.mjs +269 -0
  35. package/esm2022/src/app/core/form/properties/property.validator.mjs +24 -0
  36. package/esm2022/src/app/core/form/properties/testing/properties-form.test.mjs +95 -0
  37. package/{esm2020 → esm2022}/src/app/core/form/properties/testing/properties-form.testing.module.mjs +11 -11
  38. package/esm2022/src/app/core/form/text-popover/testing/text-popover.testing.mjs +73 -0
  39. package/{esm2020 → esm2022}/src/app/core/form/text-popover/testing/text-popover.testing.module.mjs +10 -10
  40. package/esm2022/src/app/core/form/text-popover/text-popover.component.mjs +152 -0
  41. package/esm2022/src/app/core/form/text-popover/text-popover.module.mjs +35 -0
  42. package/{esm2020 → esm2022}/src/app/core/graphql/graphql.module.mjs +6 -6
  43. package/esm2022/src/app/core/graphql/graphql.service.mjs +788 -0
  44. package/{esm2020 → esm2022}/src/app/core/graphql/graphql.utils.mjs +2 -1
  45. package/esm2022/src/app/core/home/home.mjs +282 -0
  46. package/esm2022/src/app/core/home/home.module.mjs +51 -0
  47. package/esm2022/src/app/core/icon/icon.component.mjs +40 -0
  48. package/{esm2020 → esm2022}/src/app/core/icon/icon.module.mjs +7 -7
  49. package/esm2022/src/app/core/install/install-upgrade-card.component.mjs +358 -0
  50. package/{esm2020 → esm2022}/src/app/core/install/install-upgrade-card.module.mjs +10 -10
  51. package/esm2022/src/app/core/menu/menu.component.mjs +264 -0
  52. package/esm2022/src/app/core/menu/menu.model.mjs +269 -0
  53. package/esm2022/src/app/core/menu/menu.module.mjs +52 -0
  54. package/esm2022/src/app/core/menu/menu.service.mjs +671 -0
  55. package/esm2022/src/app/core/menu/sub-menu-tab.directive.mjs +109 -0
  56. package/{esm2020 → esm2022}/src/app/core/menu/testing/menu-other.testing.mjs +5 -5
  57. package/esm2022/src/app/core/menu/testing/menu.testing.mjs +122 -0
  58. package/{esm2020 → esm2022}/src/app/core/menu/testing/menu.testing.module.mjs +12 -12
  59. package/esm2022/src/app/core/offline/update-offline-mode-card.component.mjs +29 -0
  60. package/{esm2020 → esm2022}/src/app/core/offline/update-offline-mode-card.module.mjs +10 -10
  61. package/esm2022/src/app/core/peer/select-peer.modal.mjs +193 -0
  62. package/{esm2020 → esm2022}/src/app/core/peer/select-peer.module.mjs +13 -13
  63. package/esm2022/src/app/core/register/register-confirm.page.mjs +88 -0
  64. package/esm2022/src/app/core/register/register.form.mjs +194 -0
  65. package/esm2022/src/app/core/register/register.modal.mjs +55 -0
  66. package/{esm2020 → esm2022}/src/app/core/register/register.module.mjs +13 -13
  67. package/esm2022/src/app/core/services/account.service.mjs +1243 -0
  68. package/esm2022/src/app/core/services/auth-guard.service.mjs +76 -0
  69. package/esm2022/src/app/core/services/base-entity-service.class.mjs +482 -0
  70. package/esm2022/src/app/core/services/base-graphql-service.class.mjs +224 -0
  71. package/esm2022/src/app/core/services/base58.mjs +79 -0
  72. package/{esm2020 → esm2022}/src/app/core/services/config/core.config.mjs +7 -7
  73. package/esm2022/src/app/core/services/config.service.mjs +367 -0
  74. package/esm2022/src/app/core/services/crypto.service.mjs +107 -0
  75. package/esm2022/src/app/core/services/local-settings.service.mjs +468 -0
  76. package/esm2022/src/app/core/services/model/account.model.mjs +155 -0
  77. package/esm2022/src/app/core/services/model/config.model.mjs +107 -0
  78. package/esm2022/src/app/core/services/model/department.model.mjs +34 -0
  79. package/esm2022/src/app/core/services/model/entity.decorators.mjs +97 -0
  80. package/esm2022/src/app/core/services/model/entity.model.mjs +228 -0
  81. package/esm2022/src/app/core/services/model/peer.model.mjs +83 -0
  82. package/esm2022/src/app/core/services/model/person.model.mjs +110 -0
  83. package/esm2022/src/app/core/services/model/referential.model.mjs +189 -0
  84. package/esm2022/src/app/core/services/model/token.model.mjs +57 -0
  85. package/esm2022/src/app/core/services/network.service.mjs +626 -0
  86. package/{esm2020 → esm2022}/src/app/core/services/network.types.mjs +1 -1
  87. package/{esm2020 → esm2022}/src/app/core/services/pipes/account.pipes.mjs +9 -9
  88. package/{esm2020 → esm2022}/src/app/core/services/pipes/department-to-string.pipe.mjs +5 -5
  89. package/{esm2020 → esm2022}/src/app/core/services/pipes/person-to-string.pipe.mjs +5 -5
  90. package/{esm2020 → esm2022}/src/app/core/services/pipes/usage-mode.pipes.mjs +9 -9
  91. package/esm2022/src/app/core/services/platform.service.mjs +557 -0
  92. package/esm2022/src/app/core/services/storage/entities-storage.service.mjs +434 -0
  93. package/esm2022/src/app/core/services/storage/entity-store.class.mjs +458 -0
  94. package/esm2022/src/app/core/services/testing/referential-filter.model.mjs +25 -0
  95. package/esm2022/src/app/core/services/testing/referential.validator.mjs +46 -0
  96. package/esm2022/src/app/core/services/validator/account.validator.mjs +45 -0
  97. package/esm2022/src/app/core/services/validator/base.validator.class.mjs +49 -0
  98. package/esm2022/src/app/core/services/validator/local-settings.validator.mjs +67 -0
  99. package/{esm2020 → esm2022}/src/app/core/services/validator/user-settings.validator.mjs +5 -5
  100. package/{esm2020 → esm2022}/src/app/core/services/validator/user-token.validator.mjs +5 -5
  101. package/{esm2020 → esm2022}/src/app/core/settings/settings.module.mjs +9 -9
  102. package/esm2022/src/app/core/settings/settings.page.mjs +328 -0
  103. package/esm2022/src/app/core/table/actions-column.component.mjs +115 -0
  104. package/esm2022/src/app/core/table/async-table.class.mjs +1735 -0
  105. package/esm2022/src/app/core/table/entities-async-table-datasource.class.mjs +386 -0
  106. package/esm2022/src/app/core/table/entities-table-datasource.class.mjs +401 -0
  107. package/esm2022/src/app/core/table/memory-table.class.mjs +57 -0
  108. package/esm2022/src/app/core/table/table-select-columns.component.mjs +46 -0
  109. package/esm2022/src/app/core/table/table.class.mjs +1775 -0
  110. package/esm2022/src/app/core/table/table.model.mjs +16 -0
  111. package/{esm2020 → esm2022}/src/app/core/table/table.module.mjs +12 -12
  112. package/esm2022/src/app/core/table/testing/table-validator.service.mjs +28 -0
  113. package/esm2022/src/app/core/table/testing/table.testing.mjs +291 -0
  114. package/{esm2020 → esm2022}/src/app/core/table/testing/table.testing.module.mjs +16 -16
  115. package/esm2022/src/app/core/table/testing/table2-validator.service.mjs +25 -0
  116. package/esm2022/src/app/core/table/testing/table2.testing.mjs +250 -0
  117. package/esm2022/src/app/shared/audio/audio.mjs +251 -0
  118. package/esm2022/src/app/shared/audio/audio.testing.mjs +32 -0
  119. package/{esm2020 → esm2022}/src/app/shared/audio/audio.testing.module.mjs +10 -10
  120. package/esm2022/src/app/shared/capacitor/keyboard.mjs +42 -0
  121. package/esm2022/src/app/shared/capacitor/plugins.mjs +9 -0
  122. package/esm2022/src/app/shared/dates.mjs +149 -0
  123. package/esm2022/src/app/shared/debug/debug.component.mjs +40 -0
  124. package/{esm2020 → esm2022}/src/app/shared/debug/debug.module.mjs +14 -14
  125. package/esm2022/src/app/shared/directives/autofocus.directive.mjs +98 -0
  126. package/esm2022/src/app/shared/directives/autotitle.directive.mjs +32 -0
  127. package/{esm2020 → esm2022}/src/app/shared/directives/directives.module.mjs +13 -13
  128. package/esm2022/src/app/shared/directives/drag-and-drop.directive.mjs +52 -0
  129. package/esm2022/src/app/shared/directives/ng-var.directive.mjs +33 -0
  130. package/esm2022/src/app/shared/directives/resizable/resizable.component.mjs +62 -0
  131. package/esm2022/src/app/shared/directives/resizable/resizable.directive.mjs +45 -0
  132. package/{esm2020 → esm2022}/src/app/shared/directives/resizable/resizable.module.mjs +5 -5
  133. package/esm2022/src/app/shared/file/file.service.mjs +122 -0
  134. package/{esm2020 → esm2022}/src/app/shared/file/file.utils.mjs +2 -2
  135. package/esm2022/src/app/shared/form/field.component.mjs +353 -0
  136. package/esm2022/src/app/shared/form/loading-spinner.mjs +35 -0
  137. package/{esm2020 → esm2022}/src/app/shared/functions.mjs +2 -2
  138. package/esm2022/src/app/shared/geolocation/geolocation.utils.mjs +82 -0
  139. package/esm2022/src/app/shared/gesture/gesture-config.mjs +46 -0
  140. package/esm2022/src/app/shared/graph/graph-colors.mjs +219 -0
  141. package/esm2022/src/app/shared/guard/component-dirty.guard.mjs +59 -0
  142. package/esm2022/src/app/shared/help/help.modal.mjs +63 -0
  143. package/esm2022/src/app/shared/hotkeys/dialog/hotkeys-dialog.component.mjs +23 -0
  144. package/esm2022/src/app/shared/hotkeys/hotkeys.service.mjs +85 -0
  145. package/{esm2020 → esm2022}/src/app/shared/hotkeys/shared-hotkeys.module.mjs +12 -12
  146. package/esm2022/src/app/shared/http/http.utils.mjs +56 -0
  147. package/esm2022/src/app/shared/image/gallery/image-gallery.component.mjs +388 -0
  148. package/{esm2020 → esm2022}/src/app/shared/image/gallery/image-gallery.module.mjs +22 -22
  149. package/esm2022/src/app/shared/image/gallery/testing/gallegry.model.testing.mjs +26 -0
  150. package/esm2022/src/app/shared/image/gallery/testing/gallery.service.testing.mjs +90 -0
  151. package/esm2022/src/app/shared/image/gallery/testing/gallery.testing.mjs +41 -0
  152. package/{esm2020 → esm2022}/src/app/shared/image/gallery/testing/gallery.testing.module.mjs +16 -16
  153. package/{esm2020 → esm2022}/src/app/shared/image/image.module.mjs +11 -11
  154. package/esm2022/src/app/shared/image/image.service.mjs +104 -0
  155. package/esm2022/src/app/shared/inputs.mjs +231 -0
  156. package/esm2022/src/app/shared/interceptors/progess.interceptor.mjs +28 -0
  157. package/esm2022/src/app/shared/logging/logging-service.class.mjs +128 -0
  158. package/{esm2020 → esm2022}/src/app/shared/logging/logging-service.module.mjs +8 -8
  159. package/esm2022/src/app/shared/material/autocomplete/material.autocomplete.config.mjs +49 -0
  160. package/esm2022/src/app/shared/material/autocomplete/material.autocomplete.mjs +961 -0
  161. package/esm2022/src/app/shared/material/autocomplete/material.autocomplete.module.mjs +82 -0
  162. package/esm2022/src/app/shared/material/autocomplete/testing/autocomplete.test.mjs +217 -0
  163. package/esm2022/src/app/shared/material/badge/badge.directive.mjs +209 -0
  164. package/{esm2020 → esm2022}/src/app/shared/material/badge/badge.module.mjs +9 -9
  165. package/esm2022/src/app/shared/material/badge/badge.test.mjs +42 -0
  166. package/esm2022/src/app/shared/material/boolean/boolean.module.mjs +72 -0
  167. package/esm2022/src/app/shared/material/boolean/material-boolean2.mjs +266 -0
  168. package/esm2022/src/app/shared/material/boolean/material.boolean.mjs +271 -0
  169. package/esm2022/src/app/shared/material/boolean/testing/boolean.test.page.mjs +54 -0
  170. package/{esm2020 → esm2022}/src/app/shared/material/chips/chips.module.mjs +30 -30
  171. package/esm2022/src/app/shared/material/chips/material.chips.mjs +719 -0
  172. package/esm2022/src/app/shared/material/chips/testing/chips.test.mjs +148 -0
  173. package/{esm2020 → esm2022}/src/app/shared/material/datetime/datetime.module.mjs +38 -38
  174. package/esm2022/src/app/shared/material/datetime/material.date.mjs +396 -0
  175. package/esm2022/src/app/shared/material/datetime/material.dateshort.mjs +406 -0
  176. package/esm2022/src/app/shared/material/datetime/material.datetime.mjs +549 -0
  177. package/esm2022/src/app/shared/material/datetime/testing/mat-date-time.test.mjs +132 -0
  178. package/esm2022/src/app/shared/material/datetime/testing/mat-date.test.mjs +123 -0
  179. package/esm2022/src/app/shared/material/datetime/testing/mat-dateshort.test.mjs +115 -0
  180. package/esm2022/src/app/shared/material/duration/duration.module.mjs +70 -0
  181. package/{esm2020 → esm2022}/src/app/shared/material/duration/duration.utils.mjs +2 -2
  182. package/esm2022/src/app/shared/material/duration/material.duration.mjs +273 -0
  183. package/esm2022/src/app/shared/material/duration/testing/mat-duration.test.mjs +79 -0
  184. package/{esm2020 → esm2022}/src/app/shared/material/latlong/latlong.utils.mjs +3 -3
  185. package/esm2022/src/app/shared/material/latlong/material.latlong.mjs +440 -0
  186. package/esm2022/src/app/shared/material/latlong/material.latlong.module.mjs +72 -0
  187. package/esm2022/src/app/shared/material/latlong/testing/latlong.test.mjs +113 -0
  188. package/esm2022/src/app/shared/material/material.module.mjs +229 -0
  189. package/esm2022/src/app/shared/material/material.testing.module.mjs +221 -0
  190. package/esm2022/src/app/shared/material/numpad/numpad.append-to-input.directive.mjs +104 -0
  191. package/esm2022/src/app/shared/material/numpad/numpad.component.mjs +83 -0
  192. package/esm2022/src/app/shared/material/numpad/numpad.container.mjs +203 -0
  193. package/esm2022/src/app/shared/material/numpad/numpad.content.mjs +19 -0
  194. package/esm2022/src/app/shared/material/numpad/numpad.directive.mjs +168 -0
  195. package/esm2022/src/app/shared/material/numpad/numpad.dom-service.mjs +36 -0
  196. package/esm2022/src/app/shared/material/numpad/numpad.model.mjs +16 -0
  197. package/{esm2020 → esm2022}/src/app/shared/material/numpad/numpad.module.mjs +20 -20
  198. package/esm2022/src/app/shared/material/numpad/testing/numpad.test.mjs +48 -0
  199. package/esm2022/src/app/shared/material/paginator/material.paginator-i18n.mjs +48 -0
  200. package/esm2022/src/app/shared/material/stepper/material.stepper-i18n.mjs +23 -0
  201. package/esm2022/src/app/shared/material/swipe/material.swipe.mjs +368 -0
  202. package/{esm2020 → esm2022}/src/app/shared/material/swipe/swipe.module.mjs +19 -19
  203. package/esm2022/src/app/shared/material/swipe/testing/swipe.test.mjs +67 -0
  204. package/esm2022/src/app/shared/material/testing/common.test.mjs +105 -0
  205. package/esm2022/src/app/shared/material/text/testing/text-form.testing.mjs +31 -0
  206. package/esm2022/src/app/shared/material/text/text-form.component.mjs +97 -0
  207. package/esm2022/src/app/shared/material/text/text-form.module.mjs +63 -0
  208. package/esm2022/src/app/shared/named-filter/named-filter-selector.component.mjs +236 -0
  209. package/esm2022/src/app/shared/named-filter/named-filter.model.mjs +49 -0
  210. package/{esm2020 → esm2022}/src/app/shared/named-filter/named-filter.module.mjs +5 -5
  211. package/esm2022/src/app/shared/named-filter/named-filter.service.mjs +69 -0
  212. package/{esm2020 → esm2022}/src/app/shared/pipes/arrays.pipe.mjs +25 -25
  213. package/{esm2020 → esm2022}/src/app/shared/pipes/colors.pipe.mjs +4 -4
  214. package/esm2022/src/app/shared/pipes/date-diff-duration.pipe.mjs +51 -0
  215. package/esm2022/src/app/shared/pipes/date-format.pipe.mjs +72 -0
  216. package/esm2022/src/app/shared/pipes/date-from-now.pipe.mjs +28 -0
  217. package/esm2022/src/app/shared/pipes/duration.pipe.mjs +36 -0
  218. package/esm2022/src/app/shared/pipes/file-size.pipe.mjs +60 -0
  219. package/esm2022/src/app/shared/pipes/form.pipes.mjs +194 -0
  220. package/{esm2020 → esm2022}/src/app/shared/pipes/highlight.pipe.mjs +5 -5
  221. package/esm2022/src/app/shared/pipes/latlong-format.pipe.mjs +42 -0
  222. package/{esm2020 → esm2022}/src/app/shared/pipes/maps.pipe.mjs +13 -13
  223. package/esm2022/src/app/shared/pipes/maskito.pipe.mjs +118 -0
  224. package/{esm2020 → esm2022}/src/app/shared/pipes/math.pipes.mjs +13 -13
  225. package/esm2022/src/app/shared/pipes/ng-init.pipe.mjs +19 -0
  226. package/{esm2020 → esm2022}/src/app/shared/pipes/number-format.pipe.mjs +5 -5
  227. package/esm2022/src/app/shared/pipes/pipes.module.mjs +256 -0
  228. package/esm2022/src/app/shared/pipes/property.pipes.mjs +97 -0
  229. package/{esm2020 → esm2022}/src/app/shared/pipes/string.pipes.mjs +31 -31
  230. package/esm2022/src/app/shared/pipes/translate-context.pipe.mjs +44 -0
  231. package/{esm2020 → esm2022}/src/app/shared/pipes/types.pipes.mjs +14 -14
  232. package/esm2022/src/app/shared/rx-state.module.mjs +23 -0
  233. package/esm2022/src/app/shared/services/entity-service.class.mjs +7 -0
  234. package/esm2022/src/app/shared/services/memory-entity-service.class.mjs +347 -0
  235. package/esm2022/src/app/shared/services/progress-bar.service.mjs +31 -0
  236. package/esm2022/src/app/shared/services/startable-observable-service.class.mjs +121 -0
  237. package/esm2022/src/app/shared/services/startable-service.class.mjs +113 -0
  238. package/esm2022/src/app/shared/services/translate-context.service.mjs +104 -0
  239. package/esm2022/src/app/shared/services.mjs +62 -0
  240. package/{esm2020 → esm2022}/src/app/shared/shared-routing.module.mjs +12 -12
  241. package/esm2022/src/app/shared/shared.module.mjs +231 -0
  242. package/{esm2020 → esm2022}/src/app/shared/shared.testing.module.mjs +40 -40
  243. package/esm2022/src/app/shared/storage/storage-explorer.component.mjs +286 -0
  244. package/esm2022/src/app/shared/storage/storage-explorer.module.mjs +46 -0
  245. package/{esm2020 → esm2022}/src/app/shared/storage/storage-explorer.testing-routing.module.mjs +7 -7
  246. package/{esm2020 → esm2022}/src/app/shared/storage/storage-explorer.testing.module.mjs +6 -6
  247. package/esm2022/src/app/shared/storage/storage.service.mjs +134 -0
  248. package/{esm2020 → esm2022}/src/app/shared/storage/storage.utils.mjs +1 -1
  249. package/esm2022/src/app/shared/testing/observable.test.mjs +96 -0
  250. package/esm2022/src/app/shared/testing/tests.page.mjs +37 -0
  251. package/esm2022/src/app/shared/toast/toast.testing.mjs +52 -0
  252. package/{esm2020 → esm2022}/src/app/shared/toast/toast.testing.module.mjs +10 -10
  253. package/esm2022/src/app/shared/toast/toasts.mjs +144 -0
  254. package/esm2022/src/app/shared/toolbar/modal-toolbar.mjs +60 -0
  255. package/esm2022/src/app/shared/toolbar/toolbar.mjs +264 -0
  256. package/esm2022/src/app/shared/toolbar/toolbar.module.mjs +57 -0
  257. package/esm2022/src/app/shared/upload-file/testing/upload-file.testing.mjs +59 -0
  258. package/{esm2020 → esm2022}/src/app/shared/upload-file/testing/upload-file.testing.module.mjs +10 -10
  259. package/esm2022/src/app/shared/upload-file/upload-file-popover.component.mjs +107 -0
  260. package/esm2022/src/app/shared/upload-file/upload-file.component.mjs +211 -0
  261. package/esm2022/src/app/shared/upload-file/upload-file.model.mjs +27 -0
  262. package/esm2022/src/app/shared/validator/form-error-adapter.class.mjs +106 -0
  263. package/esm2022/src/app/shared/validator/validators.mjs +580 -0
  264. package/esm2022/src/app/shared/version/versions.mjs +81 -0
  265. package/{esm2020 → esm2022}/src/app/social/job/job.module.mjs +12 -12
  266. package/esm2022/src/app/social/job/progression/job-progression.component.mjs +35 -0
  267. package/esm2022/src/app/social/job/progression/job-progression.icon.mjs +232 -0
  268. package/esm2022/src/app/social/job/progression/job-progression.list.mjs +50 -0
  269. package/esm2022/src/app/social/job/progression/job-progression.model.mjs +29 -0
  270. package/esm2022/src/app/social/job/progression/job-progression.service.mjs +73 -0
  271. package/esm2022/src/app/social/job/testing/job-progression.testing.mjs +43 -0
  272. package/esm2022/src/app/social/job/testing/job-progression.testing.service.mjs +53 -0
  273. package/{esm2020 → esm2022}/src/app/social/job/testing/job.testing.module.mjs +9 -9
  274. package/esm2022/src/app/social/message/message.form.mjs +140 -0
  275. package/esm2022/src/app/social/message/message.modal.mjs +110 -0
  276. package/esm2022/src/app/social/message/message.model.mjs +75 -0
  277. package/esm2022/src/app/social/message/message.module.mjs +22 -0
  278. package/esm2022/src/app/social/message/message.service.mjs +110 -0
  279. package/{esm2020 → esm2022}/src/app/social/social.module.mjs +19 -19
  280. package/{esm2020 → esm2022}/src/app/social/social.testing.module.mjs +10 -10
  281. package/esm2022/src/app/social/user-event/notification/user-event-notification.icon.mjs +123 -0
  282. package/esm2022/src/app/social/user-event/notification/user-event-notification.list.mjs +263 -0
  283. package/esm2022/src/app/social/user-event/testing/user-event.testing.mjs +233 -0
  284. package/esm2022/src/app/social/user-event/testing/user-event.testing.model.mjs +129 -0
  285. package/{esm2020 → esm2022}/src/app/social/user-event/testing/user-event.testing.module.mjs +9 -9
  286. package/esm2022/src/app/social/user-event/testing/user-event.testing.service.mjs +116 -0
  287. package/esm2022/src/app/social/user-event/user-event.module.mjs +43 -0
  288. package/esm2022/src/app/social/user-event/user-event.service.mjs +512 -0
  289. package/esm2022/src/environments/environment.class.mjs +50 -0
  290. package/esm2022/src/environments/environment.loader.mjs +83 -0
  291. package/esm2022/src/environments/environment.mjs +97 -0
  292. package/{fesm2020 → fesm2022}/sumaris-net.ngx-components.mjs +11115 -9134
  293. package/fesm2022/sumaris-net.ngx-components.mjs.map +1 -0
  294. package/package.json +38 -19
  295. package/public_api.d.ts +5 -1
  296. package/src/app/admin/users/users.d.ts +1 -1
  297. package/src/app/admin/users/users.module.d.ts +2 -1
  298. package/src/app/core/account/account.page.d.ts +3 -2
  299. package/src/app/core/account/new-token.modal.d.ts +2 -4
  300. package/src/app/core/account/token.table.d.ts +6 -4
  301. package/src/app/core/form/buttons/form-buttons-bar.component.d.ts +2 -2
  302. package/src/app/core/form/entity/editor.class.d.ts +2 -2
  303. package/src/app/core/form/entity/entity-editor-modal.class.d.ts +1 -1
  304. package/src/app/core/form/entity/entity-editor.class.d.ts +10 -6
  305. package/src/app/core/form/entity/entity-metadata.component.d.ts +1 -1
  306. package/src/app/core/form/form.class.d.ts +1 -1
  307. package/src/app/core/form/list/list.form.d.ts +1 -1
  308. package/src/app/core/form/properties/properties.form.d.ts +1 -1
  309. package/src/app/core/form/properties/properties.table.d.ts +1 -1
  310. package/src/app/core/form/text-popover/text-popover.component.d.ts +2 -2
  311. package/src/app/core/form/text-popover/text-popover.module.d.ts +4 -5
  312. package/src/app/core/graphql/graphql.service.d.ts +2 -4
  313. package/src/app/core/graphql/graphql.utils.d.ts +1 -1
  314. package/src/app/core/home/home.module.d.ts +4 -3
  315. package/src/app/core/icon/icon.component.d.ts +1 -1
  316. package/src/app/core/install/install-upgrade-card.component.d.ts +1 -1
  317. package/src/app/core/menu/menu.component.d.ts +7 -3
  318. package/src/app/core/menu/menu.module.d.ts +3 -5
  319. package/src/app/core/menu/menu.service.d.ts +3 -1
  320. package/src/app/core/menu/sub-menu-tab.directive.d.ts +1 -1
  321. package/src/app/core/offline/update-offline-mode-card.component.d.ts +1 -1
  322. package/src/app/core/peer/select-peer.modal.d.ts +1 -1
  323. package/src/app/core/services/account.service.d.ts +4 -0
  324. package/src/app/core/services/base-entity-service.class.d.ts +1 -1
  325. package/src/app/core/services/config/core.config.d.ts +2 -2
  326. package/src/app/core/services/model/person.model.d.ts +1 -1
  327. package/src/app/core/services/model/referential.model.d.ts +2 -1
  328. package/src/app/core/services/model/settings.model.d.ts +1 -1
  329. package/src/app/core/services/model/token.model.d.ts +1 -0
  330. package/src/app/core/services/network.service.d.ts +11 -7
  331. package/src/app/core/services/network.types.d.ts +2 -2
  332. package/src/app/core/services/storage/entity-store.class.d.ts +1 -1
  333. package/src/app/core/table/actions-column.component.d.ts +1 -1
  334. package/src/app/core/table/async-table.class.d.ts +1 -1
  335. package/src/app/core/table/memory-table.class.d.ts +1 -1
  336. package/src/app/core/table/table-select-columns.component.d.ts +1 -1
  337. package/src/app/core/table/table.class.d.ts +2 -1
  338. package/src/app/core/table/table.model.d.ts +1 -1
  339. package/src/app/core/table/testing/table.testing.d.ts +1 -1
  340. package/src/app/shared/audio/audio.d.ts +1 -1
  341. package/src/app/shared/debug/debug.component.d.ts +1 -1
  342. package/src/app/shared/directives/autofocus.directive.d.ts +1 -1
  343. package/src/app/shared/directives/ng-var.directive.d.ts +1 -1
  344. package/src/app/shared/directives/resizable/resizable.component.d.ts +1 -1
  345. package/src/app/shared/events.d.ts +1 -1
  346. package/src/app/shared/form/field.component.d.ts +1 -1
  347. package/src/app/shared/form/loading-spinner.d.ts +1 -1
  348. package/src/app/shared/help/help.modal.d.ts +1 -1
  349. package/src/app/shared/hotkeys/dialog/hotkeys-dialog.component.d.ts +2 -4
  350. package/src/app/shared/http/http.utils.d.ts +1 -0
  351. package/src/app/shared/image/gallery/image-gallery.component.d.ts +1 -1
  352. package/src/app/shared/inputs.d.ts +1 -1
  353. package/src/app/shared/material/autocomplete/material.autocomplete.d.ts +2 -2
  354. package/src/app/shared/material/autocomplete/material.autocomplete.module.d.ts +10 -9
  355. package/src/app/shared/material/badge/badge.directive.d.ts +1 -1
  356. package/src/app/shared/material/boolean/boolean.module.d.ts +4 -5
  357. package/src/app/shared/material/boolean/material-boolean2.d.ts +1 -1
  358. package/src/app/shared/material/boolean/material.boolean.d.ts +1 -1
  359. package/src/app/shared/material/chips/material.chips.d.ts +1 -1
  360. package/src/app/shared/material/datetime/datetime.module.d.ts +2 -2
  361. package/src/app/shared/material/datetime/material.date.d.ts +2 -2
  362. package/src/app/shared/material/datetime/material.dateshort.d.ts +3 -3
  363. package/src/app/shared/material/datetime/material.datetime.d.ts +14 -7
  364. package/src/app/shared/material/duration/duration.module.d.ts +6 -5
  365. package/src/app/shared/material/duration/material.duration.d.ts +2 -2
  366. package/src/app/shared/material/latlong/material.latlong.d.ts +14 -8
  367. package/src/app/shared/material/latlong/material.latlong.module.d.ts +9 -8
  368. package/src/app/shared/material/latlong/testing/latlong.test.d.ts +2 -0
  369. package/src/app/shared/material/material.module.d.ts +2 -1
  370. package/src/app/shared/material/material.testing.module.d.ts +14 -13
  371. package/src/app/shared/material/numpad/numpad.append-to-input.directive.d.ts +1 -1
  372. package/src/app/shared/material/numpad/numpad.component.d.ts +1 -1
  373. package/src/app/shared/material/numpad/numpad.content.d.ts +1 -1
  374. package/src/app/shared/material/numpad/numpad.directive.d.ts +1 -1
  375. package/src/app/shared/material/swipe/material.swipe.d.ts +1 -1
  376. package/src/app/shared/material/testing/common.test.d.ts +4 -2
  377. package/src/app/shared/material/text/testing/text-form.testing.d.ts +13 -0
  378. package/src/app/{core/form/text-popover → shared/material/text}/text-form.component.d.ts +2 -2
  379. package/src/app/shared/material/text/text-form.module.d.ts +16 -0
  380. package/src/app/shared/named-filter/named-filter-selector.component.d.ts +9 -3
  381. package/src/app/shared/pipes/maskito.pipe.d.ts +16 -0
  382. package/src/app/shared/pipes/pipes.module.d.ts +5 -4
  383. package/src/app/shared/pipes/types.pipes.d.ts +3 -3
  384. package/src/app/shared/rx-state.module.d.ts +1 -1
  385. package/src/app/shared/services/entity-service.class.d.ts +1 -1
  386. package/src/app/shared/services/job.utils.d.ts +1 -1
  387. package/src/app/shared/services/memory-entity-service.class.d.ts +7 -3
  388. package/src/app/shared/services.d.ts +1 -0
  389. package/src/app/shared/shared.module.d.ts +16 -15
  390. package/src/app/shared/storage/storage-explorer.component.d.ts +1 -1
  391. package/src/app/shared/storage/storage-explorer.module.d.ts +3 -3
  392. package/src/app/shared/storage/storage.service.d.ts +1 -1
  393. package/src/app/shared/storage/storage.utils.d.ts +1 -1
  394. package/src/app/shared/toolbar/modal-toolbar.d.ts +1 -1
  395. package/src/app/shared/toolbar/toolbar.d.ts +1 -1
  396. package/src/app/shared/toolbar/toolbar.module.d.ts +4 -3
  397. package/src/app/shared/upload-file/upload-file-popover.component.d.ts +1 -1
  398. package/src/app/shared/upload-file/upload-file.component.d.ts +1 -1
  399. package/src/app/shared/upload-file/upload-file.model.d.ts +2 -2
  400. package/src/app/social/job/progression/job-progression.component.d.ts +1 -1
  401. package/src/app/social/job/progression/job-progression.icon.d.ts +1 -1
  402. package/src/app/social/job/progression/job-progression.list.d.ts +1 -1
  403. package/src/app/social/message/message.form.d.ts +8 -2
  404. package/src/app/social/message/message.modal.d.ts +5 -1
  405. package/src/app/social/message/message.model.d.ts +2 -0
  406. package/src/app/social/message/message.module.d.ts +2 -1
  407. package/src/app/social/message/message.service.d.ts +8 -3
  408. package/src/app/social/user-event/notification/user-event-notification.icon.d.ts +4 -3
  409. package/src/app/social/user-event/notification/user-event-notification.list.d.ts +1 -1
  410. package/src/app/social/user-event/user-event.model.d.ts +2 -2
  411. package/src/app/social/user-event/user-event.module.d.ts +3 -2
  412. package/src/app/social/user-event/user-event.service.d.ts +5 -0
  413. package/src/assets/environments/environment-test.json +6 -0
  414. package/src/assets/i18n/en-US.json +25 -23
  415. package/src/assets/i18n/en.json +25 -23
  416. package/src/assets/i18n/fr.json +10 -7
  417. package/src/assets/manifest.json +1 -1
  418. package/src/environments/environment.class.d.ts +2 -0
  419. package/src/environments/environment.loader.d.ts +26 -0
  420. package/src/theme/_material.globals.scss +2 -2
  421. package/src/theme/_material.scss +34 -5
  422. package/src/theme/_mixins.scss +2 -2
  423. package/src/theme/_ngx-components.globals.scss +2 -2
  424. package/src/theme/_ngx-components.scss +8 -9
  425. package/src/theme/_ngx-components.table.scss +20 -8
  426. package/esm2020/public_api.mjs +0 -336
  427. package/esm2020/src/app/admin/services/filter/person.filter.mjs +0 -59
  428. package/esm2020/src/app/admin/services/person.service.mjs +0 -170
  429. package/esm2020/src/app/admin/services/validator/person.validator.mjs +0 -71
  430. package/esm2020/src/app/admin/users/users.mjs +0 -259
  431. package/esm2020/src/app/admin/users/users.module.mjs +0 -54
  432. package/esm2020/src/app/core/about/about.modal.mjs +0 -71
  433. package/esm2020/src/app/core/account/account.page.mjs +0 -317
  434. package/esm2020/src/app/core/account/new-token.modal.mjs +0 -115
  435. package/esm2020/src/app/core/account/token.table.mjs +0 -137
  436. package/esm2020/src/app/core/auth/auth.form.mjs +0 -132
  437. package/esm2020/src/app/core/auth/auth.modal.mjs +0 -72
  438. package/esm2020/src/app/core/form/buttons/form-buttons-bar.component.mjs +0 -107
  439. package/esm2020/src/app/core/form/entity/editor.class.mjs +0 -679
  440. package/esm2020/src/app/core/form/entity/entity-editor-modal.class.mjs +0 -422
  441. package/esm2020/src/app/core/form/entity/entity-editor.class.mjs +0 -690
  442. package/esm2020/src/app/core/form/entity/entity-metadata.component.mjs +0 -25
  443. package/esm2020/src/app/core/form/form.class.mjs +0 -345
  444. package/esm2020/src/app/core/form/list/list.form.mjs +0 -222
  445. package/esm2020/src/app/core/form/properties/properties.form.mjs +0 -132
  446. package/esm2020/src/app/core/form/properties/properties.table.mjs +0 -265
  447. package/esm2020/src/app/core/form/properties/property.validator.mjs +0 -23
  448. package/esm2020/src/app/core/form/properties/testing/properties-form.test.mjs +0 -90
  449. package/esm2020/src/app/core/form/text-popover/testing/text-popover.testing.mjs +0 -70
  450. package/esm2020/src/app/core/form/text-popover/text-form.component.mjs +0 -89
  451. package/esm2020/src/app/core/form/text-popover/text-popover.component.mjs +0 -146
  452. package/esm2020/src/app/core/form/text-popover/text-popover.module.mjs +0 -40
  453. package/esm2020/src/app/core/graphql/graphql.service.mjs +0 -774
  454. package/esm2020/src/app/core/home/home.mjs +0 -258
  455. package/esm2020/src/app/core/home/home.module.mjs +0 -48
  456. package/esm2020/src/app/core/icon/icon.component.mjs +0 -41
  457. package/esm2020/src/app/core/install/install-upgrade-card.component.mjs +0 -344
  458. package/esm2020/src/app/core/menu/menu.component.mjs +0 -239
  459. package/esm2020/src/app/core/menu/menu.model.mjs +0 -247
  460. package/esm2020/src/app/core/menu/menu.module.mjs +0 -57
  461. package/esm2020/src/app/core/menu/menu.service.mjs +0 -654
  462. package/esm2020/src/app/core/menu/sub-menu-tab.directive.mjs +0 -98
  463. package/esm2020/src/app/core/menu/testing/menu.testing.mjs +0 -121
  464. package/esm2020/src/app/core/offline/update-offline-mode-card.component.mjs +0 -27
  465. package/esm2020/src/app/core/peer/select-peer.modal.mjs +0 -183
  466. package/esm2020/src/app/core/register/register-confirm.page.mjs +0 -81
  467. package/esm2020/src/app/core/register/register.form.mjs +0 -183
  468. package/esm2020/src/app/core/register/register.modal.mjs +0 -52
  469. package/esm2020/src/app/core/services/account.service.mjs +0 -1206
  470. package/esm2020/src/app/core/services/auth-guard.service.mjs +0 -71
  471. package/esm2020/src/app/core/services/base-entity-service.class.mjs +0 -468
  472. package/esm2020/src/app/core/services/base-graphql-service.class.mjs +0 -221
  473. package/esm2020/src/app/core/services/base58.mjs +0 -78
  474. package/esm2020/src/app/core/services/config.service.mjs +0 -355
  475. package/esm2020/src/app/core/services/crypto.service.mjs +0 -107
  476. package/esm2020/src/app/core/services/local-settings.service.mjs +0 -460
  477. package/esm2020/src/app/core/services/model/account.model.mjs +0 -147
  478. package/esm2020/src/app/core/services/model/config.model.mjs +0 -92
  479. package/esm2020/src/app/core/services/model/department.model.mjs +0 -30
  480. package/esm2020/src/app/core/services/model/entity.decorators.mjs +0 -97
  481. package/esm2020/src/app/core/services/model/entity.model.mjs +0 -225
  482. package/esm2020/src/app/core/services/model/peer.model.mjs +0 -68
  483. package/esm2020/src/app/core/services/model/person.model.mjs +0 -97
  484. package/esm2020/src/app/core/services/model/referential.model.mjs +0 -164
  485. package/esm2020/src/app/core/services/model/token.model.mjs +0 -48
  486. package/esm2020/src/app/core/services/network.service.mjs +0 -590
  487. package/esm2020/src/app/core/services/platform.service.mjs +0 -524
  488. package/esm2020/src/app/core/services/storage/entities-storage.service.mjs +0 -428
  489. package/esm2020/src/app/core/services/storage/entity-store.class.mjs +0 -449
  490. package/esm2020/src/app/core/services/testing/referential-filter.model.mjs +0 -23
  491. package/esm2020/src/app/core/services/testing/referential.validator.mjs +0 -45
  492. package/esm2020/src/app/core/services/validator/account.validator.mjs +0 -41
  493. package/esm2020/src/app/core/services/validator/base.validator.class.mjs +0 -47
  494. package/esm2020/src/app/core/services/validator/local-settings.validator.mjs +0 -66
  495. package/esm2020/src/app/core/settings/settings.page.mjs +0 -312
  496. package/esm2020/src/app/core/table/actions-column.component.mjs +0 -102
  497. package/esm2020/src/app/core/table/async-table.class.mjs +0 -1698
  498. package/esm2020/src/app/core/table/entities-async-table-datasource.class.mjs +0 -384
  499. package/esm2020/src/app/core/table/entities-table-datasource.class.mjs +0 -399
  500. package/esm2020/src/app/core/table/memory-table.class.mjs +0 -53
  501. package/esm2020/src/app/core/table/table-select-columns.component.mjs +0 -43
  502. package/esm2020/src/app/core/table/table.class.mjs +0 -1733
  503. package/esm2020/src/app/core/table/table.model.mjs +0 -12
  504. package/esm2020/src/app/core/table/testing/table-validator.service.mjs +0 -27
  505. package/esm2020/src/app/core/table/testing/table.testing.mjs +0 -281
  506. package/esm2020/src/app/core/table/testing/table2-validator.service.mjs +0 -24
  507. package/esm2020/src/app/core/table/testing/table2.testing.mjs +0 -242
  508. package/esm2020/src/app/shared/audio/audio.mjs +0 -248
  509. package/esm2020/src/app/shared/audio/audio.testing.mjs +0 -31
  510. package/esm2020/src/app/shared/capacitor/keyboard.mjs +0 -40
  511. package/esm2020/src/app/shared/capacitor/plugins.mjs +0 -9
  512. package/esm2020/src/app/shared/dates.mjs +0 -149
  513. package/esm2020/src/app/shared/debug/debug.component.mjs +0 -39
  514. package/esm2020/src/app/shared/directives/autofocus.directive.mjs +0 -93
  515. package/esm2020/src/app/shared/directives/autotitle.directive.mjs +0 -30
  516. package/esm2020/src/app/shared/directives/drag-and-drop.directive.mjs +0 -53
  517. package/esm2020/src/app/shared/directives/ng-var.directive.mjs +0 -31
  518. package/esm2020/src/app/shared/directives/resizable/resizable.component.mjs +0 -60
  519. package/esm2020/src/app/shared/directives/resizable/resizable.directive.mjs +0 -40
  520. package/esm2020/src/app/shared/file/file.service.mjs +0 -117
  521. package/esm2020/src/app/shared/form/field.component.mjs +0 -334
  522. package/esm2020/src/app/shared/form/loading-spinner.mjs +0 -36
  523. package/esm2020/src/app/shared/geolocation/geolocation.utils.mjs +0 -80
  524. package/esm2020/src/app/shared/gesture/gesture-config.mjs +0 -49
  525. package/esm2020/src/app/shared/graph/graph-colors.mjs +0 -212
  526. package/esm2020/src/app/shared/guard/component-dirty.guard.mjs +0 -57
  527. package/esm2020/src/app/shared/help/help.modal.mjs +0 -53
  528. package/esm2020/src/app/shared/hotkeys/dialog/hotkeys-dialog.component.mjs +0 -23
  529. package/esm2020/src/app/shared/hotkeys/hotkeys.service.mjs +0 -81
  530. package/esm2020/src/app/shared/http/http.utils.mjs +0 -52
  531. package/esm2020/src/app/shared/image/gallery/image-gallery.component.mjs +0 -368
  532. package/esm2020/src/app/shared/image/gallery/testing/gallegry.model.testing.mjs +0 -27
  533. package/esm2020/src/app/shared/image/gallery/testing/gallery.service.testing.mjs +0 -90
  534. package/esm2020/src/app/shared/image/gallery/testing/gallery.testing.mjs +0 -39
  535. package/esm2020/src/app/shared/image/image.service.mjs +0 -98
  536. package/esm2020/src/app/shared/inputs.mjs +0 -231
  537. package/esm2020/src/app/shared/interceptors/progess.interceptor.mjs +0 -27
  538. package/esm2020/src/app/shared/logging/logging-service.class.mjs +0 -121
  539. package/esm2020/src/app/shared/material/autocomplete/material.autocomplete.config.mjs +0 -47
  540. package/esm2020/src/app/shared/material/autocomplete/material.autocomplete.mjs +0 -925
  541. package/esm2020/src/app/shared/material/autocomplete/material.autocomplete.module.mjs +0 -78
  542. package/esm2020/src/app/shared/material/autocomplete/testing/autocomplete.test.mjs +0 -209
  543. package/esm2020/src/app/shared/material/badge/badge.directive.mjs +0 -199
  544. package/esm2020/src/app/shared/material/badge/badge.test.mjs +0 -41
  545. package/esm2020/src/app/shared/material/boolean/boolean.module.mjs +0 -76
  546. package/esm2020/src/app/shared/material/boolean/material-boolean2.mjs +0 -248
  547. package/esm2020/src/app/shared/material/boolean/material.boolean.mjs +0 -254
  548. package/esm2020/src/app/shared/material/boolean/testing/boolean.test.page.mjs +0 -51
  549. package/esm2020/src/app/shared/material/chips/material.chips.mjs +0 -688
  550. package/esm2020/src/app/shared/material/chips/testing/chips.test.mjs +0 -143
  551. package/esm2020/src/app/shared/material/datetime/material.date.mjs +0 -378
  552. package/esm2020/src/app/shared/material/datetime/material.dateshort.mjs +0 -387
  553. package/esm2020/src/app/shared/material/datetime/material.datetime.mjs +0 -501
  554. package/esm2020/src/app/shared/material/datetime/testing/mat-date-time.test.mjs +0 -120
  555. package/esm2020/src/app/shared/material/datetime/testing/mat-date.test.mjs +0 -118
  556. package/esm2020/src/app/shared/material/datetime/testing/mat-dateshort.test.mjs +0 -111
  557. package/esm2020/src/app/shared/material/duration/duration.module.mjs +0 -67
  558. package/esm2020/src/app/shared/material/duration/material.duration.mjs +0 -258
  559. package/esm2020/src/app/shared/material/duration/testing/mat-duration.test.mjs +0 -76
  560. package/esm2020/src/app/shared/material/latlong/material.latlong.mjs +0 -383
  561. package/esm2020/src/app/shared/material/latlong/material.latlong.module.mjs +0 -67
  562. package/esm2020/src/app/shared/material/latlong/testing/latlong.test.mjs +0 -102
  563. package/esm2020/src/app/shared/material/material.module.mjs +0 -224
  564. package/esm2020/src/app/shared/material/material.testing.module.mjs +0 -210
  565. package/esm2020/src/app/shared/material/numpad/numpad.append-to-input.directive.mjs +0 -98
  566. package/esm2020/src/app/shared/material/numpad/numpad.component.mjs +0 -80
  567. package/esm2020/src/app/shared/material/numpad/numpad.container.mjs +0 -190
  568. package/esm2020/src/app/shared/material/numpad/numpad.content.mjs +0 -17
  569. package/esm2020/src/app/shared/material/numpad/numpad.directive.mjs +0 -162
  570. package/esm2020/src/app/shared/material/numpad/numpad.dom-service.mjs +0 -32
  571. package/esm2020/src/app/shared/material/numpad/numpad.model.mjs +0 -15
  572. package/esm2020/src/app/shared/material/numpad/testing/numpad.test.mjs +0 -46
  573. package/esm2020/src/app/shared/material/paginator/material.paginator-i18n.mjs +0 -46
  574. package/esm2020/src/app/shared/material/stepper/material.stepper-i18n.mjs +0 -22
  575. package/esm2020/src/app/shared/material/swipe/material.swipe.mjs +0 -345
  576. package/esm2020/src/app/shared/material/swipe/testing/swipe.test.mjs +0 -64
  577. package/esm2020/src/app/shared/material/testing/common.test.mjs +0 -95
  578. package/esm2020/src/app/shared/named-filter/named-filter-selector.component.mjs +0 -202
  579. package/esm2020/src/app/shared/named-filter/named-filter.model.mjs +0 -45
  580. package/esm2020/src/app/shared/named-filter/named-filter.service.mjs +0 -63
  581. package/esm2020/src/app/shared/pipes/date-diff-duration.pipe.mjs +0 -48
  582. package/esm2020/src/app/shared/pipes/date-format.pipe.mjs +0 -66
  583. package/esm2020/src/app/shared/pipes/date-from-now.pipe.mjs +0 -27
  584. package/esm2020/src/app/shared/pipes/duration.pipe.mjs +0 -34
  585. package/esm2020/src/app/shared/pipes/file-size.pipe.mjs +0 -62
  586. package/esm2020/src/app/shared/pipes/form.pipes.mjs +0 -187
  587. package/esm2020/src/app/shared/pipes/latlong-format.pipe.mjs +0 -46
  588. package/esm2020/src/app/shared/pipes/ng-init.pipe.mjs +0 -21
  589. package/esm2020/src/app/shared/pipes/pipes.module.mjs +0 -247
  590. package/esm2020/src/app/shared/pipes/property.pipes.mjs +0 -93
  591. package/esm2020/src/app/shared/pipes/translate-context.pipe.mjs +0 -43
  592. package/esm2020/src/app/shared/rx-state.module.mjs +0 -23
  593. package/esm2020/src/app/shared/services/entity-service.class.mjs +0 -7
  594. package/esm2020/src/app/shared/services/memory-entity-service.class.mjs +0 -339
  595. package/esm2020/src/app/shared/services/progress-bar.service.mjs +0 -33
  596. package/esm2020/src/app/shared/services/startable-observable-service.class.mjs +0 -121
  597. package/esm2020/src/app/shared/services/startable-service.class.mjs +0 -113
  598. package/esm2020/src/app/shared/services/translate-context.service.mjs +0 -103
  599. package/esm2020/src/app/shared/services.mjs +0 -62
  600. package/esm2020/src/app/shared/shared.module.mjs +0 -224
  601. package/esm2020/src/app/shared/storage/storage-explorer.component.mjs +0 -268
  602. package/esm2020/src/app/shared/storage/storage-explorer.module.mjs +0 -47
  603. package/esm2020/src/app/shared/storage/storage.service.mjs +0 -132
  604. package/esm2020/src/app/shared/testing/observable.test.mjs +0 -95
  605. package/esm2020/src/app/shared/testing/tests.page.mjs +0 -33
  606. package/esm2020/src/app/shared/toast/toast.testing.mjs +0 -51
  607. package/esm2020/src/app/shared/toast/toasts.mjs +0 -144
  608. package/esm2020/src/app/shared/toolbar/modal-toolbar.mjs +0 -58
  609. package/esm2020/src/app/shared/toolbar/toolbar.mjs +0 -251
  610. package/esm2020/src/app/shared/toolbar/toolbar.module.mjs +0 -53
  611. package/esm2020/src/app/shared/upload-file/testing/upload-file.testing.mjs +0 -58
  612. package/esm2020/src/app/shared/upload-file/upload-file-popover.component.mjs +0 -97
  613. package/esm2020/src/app/shared/upload-file/upload-file.component.mjs +0 -204
  614. package/esm2020/src/app/shared/upload-file/upload-file.model.mjs +0 -20
  615. package/esm2020/src/app/shared/validator/form-error-adapter.class.mjs +0 -104
  616. package/esm2020/src/app/shared/validator/validators.mjs +0 -580
  617. package/esm2020/src/app/shared/version/versions.mjs +0 -81
  618. package/esm2020/src/app/social/job/progression/job-progression.component.mjs +0 -34
  619. package/esm2020/src/app/social/job/progression/job-progression.icon.mjs +0 -223
  620. package/esm2020/src/app/social/job/progression/job-progression.list.mjs +0 -46
  621. package/esm2020/src/app/social/job/progression/job-progression.model.mjs +0 -23
  622. package/esm2020/src/app/social/job/progression/job-progression.service.mjs +0 -71
  623. package/esm2020/src/app/social/job/testing/job-progression.testing.mjs +0 -41
  624. package/esm2020/src/app/social/job/testing/job-progression.testing.service.mjs +0 -55
  625. package/esm2020/src/app/social/message/message.form.mjs +0 -84
  626. package/esm2020/src/app/social/message/message.modal.mjs +0 -93
  627. package/esm2020/src/app/social/message/message.model.mjs +0 -64
  628. package/esm2020/src/app/social/message/message.module.mjs +0 -35
  629. package/esm2020/src/app/social/message/message.service.mjs +0 -84
  630. package/esm2020/src/app/social/user-event/notification/user-event-notification.icon.mjs +0 -114
  631. package/esm2020/src/app/social/user-event/notification/user-event-notification.list.mjs +0 -246
  632. package/esm2020/src/app/social/user-event/testing/user-event.testing.mjs +0 -227
  633. package/esm2020/src/app/social/user-event/testing/user-event.testing.model.mjs +0 -112
  634. package/esm2020/src/app/social/user-event/testing/user-event.testing.service.mjs +0 -111
  635. package/esm2020/src/app/social/user-event/user-event.module.mjs +0 -39
  636. package/esm2020/src/app/social/user-event/user-event.service.mjs +0 -488
  637. package/esm2020/src/environments/environment.class.mjs +0 -5
  638. package/esm2020/src/environments/environment.mjs +0 -94
  639. package/fesm2015/sumaris-net.ngx-components.mjs +0 -41541
  640. package/fesm2015/sumaris-net.ngx-components.mjs.map +0 -1
  641. package/fesm2020/sumaris-net.ngx-components.mjs.map +0 -1
  642. /package/{esm2020 → esm2022}/src/app/core/services/errors.mjs +0 -0
  643. /package/{esm2020 → esm2022}/src/app/core/services/model/filter.model.mjs +0 -0
  644. /package/{esm2020 → esm2022}/src/app/core/services/model/history.model.mjs +0 -0
  645. /package/{esm2020 → esm2022}/src/app/core/services/model/model.enum.mjs +0 -0
  646. /package/{esm2020 → esm2022}/src/app/core/services/model/settings.model.mjs +0 -0
  647. /package/{esm2020 → esm2022}/src/app/core/services/model/tree-item-entity.model.mjs +0 -0
  648. /package/{esm2020 → esm2022}/src/app/core/services/network.utils.mjs +0 -0
  649. /package/{esm2020 → esm2022}/src/app/core/table/table.utils.mjs +0 -0
  650. /package/{esm2020 → esm2022}/src/app/shared/alerts.mjs +0 -0
  651. /package/{esm2020 → esm2022}/src/app/shared/constants.mjs +0 -0
  652. /package/{esm2020 → esm2022}/src/app/shared/debug/debug-service.class.mjs +0 -0
  653. /package/{esm2020 → esm2022}/src/app/shared/events.mjs +0 -0
  654. /package/{esm2020 → esm2022}/src/app/shared/file/csv.utils.mjs +0 -0
  655. /package/{esm2020 → esm2022}/src/app/shared/file/images.utils.mjs +0 -0
  656. /package/{esm2020 → esm2022}/src/app/shared/file/json.utils.mjs +0 -0
  657. /package/{esm2020 → esm2022}/src/app/shared/file/uri.utils.mjs +0 -0
  658. /package/{esm2020 → esm2022}/src/app/shared/focusable.mjs +0 -0
  659. /package/{esm2020 → esm2022}/src/app/shared/form/field.model.mjs +0 -0
  660. /package/{esm2020 → esm2022}/src/app/shared/forms.mjs +0 -0
  661. /package/{esm2020 → esm2022}/src/app/shared/gesture/hammer.utils.mjs +0 -0
  662. /package/{esm2020 → esm2022}/src/app/shared/graph/colors.utils.mjs +0 -0
  663. /package/{esm2020 → esm2022}/src/app/shared/image/image.model.mjs +0 -0
  664. /package/{esm2020 → esm2022}/src/app/shared/logging/log-level.model.mjs +0 -0
  665. /package/{esm2020 → esm2022}/src/app/shared/logging/logger.model.mjs +0 -0
  666. /package/{esm2020 → esm2022}/src/app/shared/logging/logging-service.config.mjs +0 -0
  667. /package/{esm2020 → esm2022}/src/app/shared/material/autocomplete/material.autocomplete.utils.mjs +0 -0
  668. /package/{esm2020 → esm2022}/src/app/shared/material/material.animations.mjs +0 -0
  669. /package/{esm2020 → esm2022}/src/app/shared/modules.mjs +0 -0
  670. /package/{esm2020 → esm2022}/src/app/shared/observables.mjs +0 -0
  671. /package/{esm2020 → esm2022}/src/app/shared/platforms.mjs +0 -0
  672. /package/{esm2020 → esm2022}/src/app/shared/services/job.utils.mjs +0 -0
  673. /package/{esm2020 → esm2022}/src/app/shared/services/validator-service.class.mjs +0 -0
  674. /package/{esm2020 → esm2022}/src/app/shared/types.mjs +0 -0
  675. /package/{esm2020 → esm2022}/src/app/social/social.errors.mjs +0 -0
  676. /package/{esm2020 → esm2022}/src/app/social/user-event/user-event.model.mjs +0 -0
  677. /package/{esm2020 → esm2022}/sumaris-net.ngx-components.mjs +0 -0
@@ -0,0 +1,788 @@
1
+ import { firstValueFrom, of, Subject } from 'rxjs';
2
+ import { ApolloClient, ApolloLink, InMemoryCache, NetworkStatus, } from '@apollo/client/core';
3
+ import { ErrorCodes, ServerErrorCodes } from '../services/errors';
4
+ import { catchError, distinctUntilChanged, filter, first, map, mergeMap, takeUntil, throttleTime } from 'rxjs/operators';
5
+ import { Inject, Injectable, InjectionToken, Optional } from '@angular/core';
6
+ import { AppWebSocket, createTrackerLink, isMutationOperation, isSubscriptionOperation, restoreTrackedQueries, StorageServiceWrapper, } from './graphql.utils';
7
+ import { RetryLink } from '@apollo/client/link/retry';
8
+ import queueLinkImported from 'apollo-link-queue';
9
+ import serializingLinkImported from 'apollo-link-serialize';
10
+ import loggerLinkImported from 'apollo-link-logger';
11
+ import { EntityUtils } from '../services/model/entity.model';
12
+ import { isNil, isNotEmptyArray, isNotNil, toNumber } from '../../shared/functions';
13
+ import { HttpHeaders } from '@angular/common/http';
14
+ import { persistCache } from 'apollo3-cache-persist';
15
+ import { ENVIRONMENT } from '../../../environments/environment.class';
16
+ import { StartableService } from '../../shared/services/startable-service.class';
17
+ import { isMobile } from '../../shared/platforms';
18
+ import { GraphQLWsLink } from '@apollo/client/link/subscriptions';
19
+ import { createClient } from 'graphql-ws';
20
+ import { unwrapESModule } from '../../shared/modules';
21
+ import { createFragmentRegistry } from '@apollo/client/cache/inmemory/fragmentRegistry';
22
+ import * as i0 from "@angular/core";
23
+ import * as i1 from "@ionic/angular";
24
+ import * as i2 from "apollo-angular";
25
+ import * as i3 from "apollo-angular/http";
26
+ import * as i4 from "../services/network.service";
27
+ import * as i5 from "../../shared/storage/storage.service";
28
+ import * as i6 from "../../../environments/environment.class";
29
+ // Workaround for issue https://github.com/ng-packagr/ng-packagr/issues/2215
30
+ const QueueLink = unwrapESModule(queueLinkImported);
31
+ const SerializingLink = unwrapESModule(serializingLinkImported);
32
+ const loggerLink = unwrapESModule(loggerLinkImported);
33
+ export const APP_GRAPHQL_TYPE_POLICIES = new InjectionToken('graphqlTypePolicies');
34
+ export const APP_GRAPHQL_FRAGMENTS = new InjectionToken('graphqlFragments');
35
+ export class GraphqlService extends StartableService {
36
+ platform;
37
+ apollo;
38
+ httpLink;
39
+ network;
40
+ storage;
41
+ environment;
42
+ typePolicies;
43
+ fragments;
44
+ _networkStatusChanged$;
45
+ httpParams;
46
+ wsParams;
47
+ connectionParams = {};
48
+ _defaultFetchPolicy;
49
+ onNetworkError = new Subject();
50
+ customErrors = {};
51
+ onResetAuth = new Subject();
52
+ get client() {
53
+ return this._data;
54
+ }
55
+ get cache() {
56
+ return this.apollo.client.cache;
57
+ }
58
+ get defaultFetchPolicy() {
59
+ return this._defaultFetchPolicy;
60
+ }
61
+ constructor(platform, apollo, httpLink, network, storage, environment, typePolicies, fragments) {
62
+ super(platform); // Wait platform
63
+ this.platform = platform;
64
+ this.apollo = apollo;
65
+ this.httpLink = httpLink;
66
+ this.network = network;
67
+ this.storage = storage;
68
+ this.environment = environment;
69
+ this.typePolicies = typePolicies;
70
+ this.fragments = fragments;
71
+ this._debug = !environment.production;
72
+ this._defaultFetchPolicy = environment.apolloFetchPolicy;
73
+ // Listen network status
74
+ this._networkStatusChanged$ = network.onNetworkStatusChanges
75
+ .pipe(filter(isNotNil), distinctUntilChanged());
76
+ // When getting network error: try to ping peer, and toggle to offline
77
+ this.onNetworkError
78
+ .pipe(throttleTime(300), filter(() => this.network.online), mergeMap(() => this.network.checkPeerAlive()), filter(alive => !alive))
79
+ .subscribe(() => this.network.setForceOffline(true, { showToast: true }));
80
+ }
81
+ async setAuthToken(token) {
82
+ if (token) {
83
+ console.debug('[graphql] Apply token authentication to headers');
84
+ this.connectionParams.authToken = token;
85
+ }
86
+ // Clean auth token
87
+ else if (this.connectionParams.authToken) {
88
+ console.debug('[graphql] Remove token authentication from headers');
89
+ delete this.connectionParams.authToken;
90
+ await this.clearCache();
91
+ }
92
+ }
93
+ async setAuthBasic(basic) {
94
+ if (basic) {
95
+ console.debug('[graphql] Apply basic authentication to headers');
96
+ this.connectionParams.authBasic = basic;
97
+ }
98
+ // Clean auth basic
99
+ else if (this.connectionParams.authBasic) {
100
+ console.debug('[graphql] Remove basic authentication from headers');
101
+ delete this.connectionParams.authBasic;
102
+ await this.clearCache();
103
+ }
104
+ }
105
+ /**
106
+ * Allow to add a field resolver
107
+ * (see doc: https://www.apollographql.com/docs/react/data/local-state/#handling-client-fields-with-resolvers)
108
+ *
109
+ * @param resolvers
110
+ */
111
+ async addResolver(resolvers) {
112
+ if (!this.started)
113
+ await this.ready();
114
+ this.apollo.client.addResolvers(resolvers);
115
+ }
116
+ async query(opts) {
117
+ if (!this.started)
118
+ await this.ready();
119
+ let res;
120
+ try {
121
+ res = await this.client.query({
122
+ query: opts.query,
123
+ variables: opts.variables,
124
+ fetchPolicy: opts.fetchPolicy || this._defaultFetchPolicy || undefined
125
+ });
126
+ }
127
+ catch (err) {
128
+ res = this.toApolloError(err, opts.error);
129
+ }
130
+ if (res.errors) {
131
+ throw res.errors[0];
132
+ }
133
+ return res.data;
134
+ }
135
+ watchQueryRef(opts) {
136
+ return this.apollo.watchQuery({
137
+ query: opts.query,
138
+ variables: opts.variables,
139
+ fetchPolicy: opts.fetchPolicy || this._defaultFetchPolicy || undefined,
140
+ notifyOnNetworkStatusChange: true
141
+ });
142
+ }
143
+ queryRefValuesChanges(queryRef, opts) {
144
+ return queryRef
145
+ .valueChanges
146
+ .pipe(catchError(error => this.onApolloError(error, opts.error)), filter(value => value.networkStatus === NetworkStatus.ready || value.networkStatus === NetworkStatus.error), map(({ data, errors }) => {
147
+ if (errors) {
148
+ throw errors[0];
149
+ }
150
+ return data;
151
+ }));
152
+ }
153
+ watchQuery(opts) {
154
+ const queryRef = this.watchQueryRef(opts);
155
+ return this.queryRefValuesChanges(queryRef, opts);
156
+ }
157
+ async mutate(opts) {
158
+ // If offline, compute an optimistic response for tracked queries
159
+ if ((opts.forceOffline || this.network.offline) && opts.offlineResponse) {
160
+ if (typeof opts.offlineResponse === 'function') {
161
+ opts.context = opts.context || {};
162
+ const optimisticResponseFn = opts.offlineResponse;
163
+ opts.optimisticResponse = await optimisticResponseFn(opts.context);
164
+ if (this._debug)
165
+ console.debug('[graphql] [offline] Using an optimistic response: ', opts.optimisticResponse);
166
+ }
167
+ else {
168
+ opts.optimisticResponse = opts.offlineResponse;
169
+ }
170
+ if (opts.forceOffline) {
171
+ const res = { data: opts.optimisticResponse };
172
+ if (opts.update) {
173
+ opts.update(this.apollo.client.cache, res);
174
+ }
175
+ return res.data;
176
+ }
177
+ }
178
+ const res = await firstValueFrom(this.apollo.mutate({
179
+ mutation: opts.mutation,
180
+ variables: opts.variables,
181
+ context: opts.context,
182
+ optimisticResponse: opts.optimisticResponse,
183
+ update: opts.update
184
+ })
185
+ .pipe(catchError(error => this.onApolloError(error, opts.error)), first()));
186
+ if (Array.isArray(res.errors)) {
187
+ throw res.errors[0];
188
+ }
189
+ return res.data;
190
+ }
191
+ subscribe(opts, extra) {
192
+ return this.apollo.subscribe({
193
+ query: opts.query,
194
+ fetchPolicy: opts && opts.fetchPolicy || 'network-only',
195
+ errorPolicy: opts && opts.errorPolicy || undefined,
196
+ variables: opts.variables
197
+ }, {
198
+ useZone: true,
199
+ ...extra
200
+ })
201
+ .pipe(catchError(error => this.onApolloError(error, opts.error)), map(({ data, errors }) => {
202
+ if (errors) {
203
+ throw errors[0];
204
+ }
205
+ return data;
206
+ }));
207
+ }
208
+ insertIntoQueryCache(cache, opts) {
209
+ cache = cache || this.apollo.client.cache;
210
+ opts.arrayFieldName = opts.arrayFieldName || 'data';
211
+ try {
212
+ let data = cache.readQuery({ query: opts.query, variables: opts.variables });
213
+ if (!data)
214
+ return; // Skip: nothing in cache
215
+ if (data[opts.arrayFieldName]) {
216
+ // Copy because immutable
217
+ data = { ...data };
218
+ // Append to result array
219
+ data[opts.arrayFieldName] = [...data[opts.arrayFieldName], { ...opts.data }];
220
+ // Resort, if need
221
+ if (opts.sortFn) {
222
+ data[opts.arrayFieldName].sort(opts.sortFn);
223
+ }
224
+ // Exclude if exceed max size
225
+ const size = toNumber(opts.variables && opts.variables['size'], -1);
226
+ if (size > 0 && data[opts.arrayFieldName].length > size) {
227
+ data[opts.arrayFieldName].splice(size, data[opts.arrayFieldName].length - size);
228
+ }
229
+ // Increment total
230
+ if (isNotNil(opts.totalFieldName)) {
231
+ if (isNotNil(data[opts.totalFieldName])) {
232
+ data[opts.totalFieldName] += 1;
233
+ }
234
+ else {
235
+ console.warn('[graphql] Unable to update cached query. Unknown result part: ' + opts.totalFieldName);
236
+ }
237
+ }
238
+ cache.writeQuery({
239
+ query: opts.query,
240
+ variables: opts.variables,
241
+ data
242
+ });
243
+ }
244
+ else {
245
+ console.warn('[graphql] Unable to update cached query. Unknown result part: ' + opts.arrayFieldName);
246
+ }
247
+ }
248
+ catch (err) {
249
+ // continue
250
+ // read in cache is not guaranteed to return a result. see https://github.com/apollographql/react-apollo/issues/1776#issuecomment-372237940
251
+ if (this._debug)
252
+ console.error('[graphql] Error while updating cache: ', err);
253
+ }
254
+ }
255
+ addManyToQueryCache(cache, opts) {
256
+ if (!opts.data || !opts.data.length)
257
+ return; // nothing to process
258
+ cache = cache || this.apollo.client.cache;
259
+ opts.arrayFieldName = opts.arrayFieldName || 'data';
260
+ try {
261
+ let data = cache.readQuery({ query: opts.query, variables: opts.variables });
262
+ if (!data)
263
+ return 0; // skip
264
+ if (data[opts.arrayFieldName]) {
265
+ // Copy because immutable
266
+ data = { ...data };
267
+ // Keep only not existing res
268
+ const equalsFn = opts.equalsFn || ((d1, d2) => d1['id'] === d2['id'] && d1['entityName'] === d2['entityName']);
269
+ const newItems = opts.data.filter(inputValue => data[opts.arrayFieldName].findIndex(existingValue => equalsFn(inputValue, existingValue)) === -1);
270
+ if (!newItems.length)
271
+ return; // No new value
272
+ // Append to array
273
+ data[opts.arrayFieldName] = [...data[opts.arrayFieldName], ...newItems];
274
+ // Resort, if need
275
+ if (opts.sortFn) {
276
+ data[opts.arrayFieldName].sort(opts.sortFn);
277
+ }
278
+ // Exclude if exceed max size
279
+ const size = toNumber(opts.variables && opts.variables['size'], -1);
280
+ if (size > 0 && data[opts.arrayFieldName].length > size) {
281
+ data[opts.arrayFieldName].splice(size, data[opts.arrayFieldName].length - size);
282
+ }
283
+ // Increment the total
284
+ if (isNotNil(opts.totalFieldName)) {
285
+ if (isNotNil(data[opts.totalFieldName])) {
286
+ data[opts.arrayFieldName] += newItems.length;
287
+ }
288
+ else {
289
+ console.warn('[graphql] Unable to update cached query. Unknown result part: ' + opts.totalFieldName);
290
+ }
291
+ }
292
+ // Write to cache
293
+ cache.writeQuery({
294
+ query: opts.query,
295
+ variables: opts.variables,
296
+ data
297
+ });
298
+ }
299
+ else {
300
+ console.warn('[graphql] Unable to update cached query. Unknown result part: ' + opts.arrayFieldName);
301
+ }
302
+ }
303
+ catch (err) {
304
+ // continue
305
+ // read in cache is not guaranteed to return a result. see https://github.com/apollographql/react-apollo/issues/1776#issuecomment-372237940
306
+ if (this._debug)
307
+ console.warn('[graphql] Error while updating cache: ', err);
308
+ }
309
+ }
310
+ /**
311
+ * Remove from cache, and return if removed or not
312
+ *
313
+ * @param cache
314
+ * @param opts
315
+ */
316
+ removeFromCachedQueryById(cache, opts) {
317
+ cache = cache || this.apollo.client.cache;
318
+ opts.arrayFieldName = opts.arrayFieldName || 'data';
319
+ try {
320
+ let data = cache.readQuery({ query: opts.query, variables: opts.variables });
321
+ if (data && data[opts.arrayFieldName]) {
322
+ // Copy because immutable
323
+ data = { ...data };
324
+ const index = data[opts.arrayFieldName].findIndex(item => item['id'] === opts.ids);
325
+ if (index === -1)
326
+ return false; // Skip (nothing removed)
327
+ // Copy, then remove deleted item
328
+ data[opts.arrayFieldName] = data[opts.arrayFieldName].slice();
329
+ const deletedItem = data[opts.arrayFieldName].splice(index, 1)[0];
330
+ cache.evict({ id: cache.identify(deletedItem) });
331
+ // Decrement the total
332
+ if (isNotNil(opts.totalFieldName)) {
333
+ if (isNotNil(data[opts.totalFieldName])) {
334
+ data[opts.totalFieldName] -= 1;
335
+ }
336
+ else {
337
+ console.warn('[graphql] Unable to update cached query. Unknown result part: ' + opts.totalFieldName);
338
+ }
339
+ }
340
+ // Write to cache
341
+ cache.writeQuery({
342
+ query: opts.query,
343
+ variables: opts.variables,
344
+ data
345
+ });
346
+ return true;
347
+ }
348
+ else {
349
+ console.warn('[graphql] Unable to update cached query. Unknown result part: ' + opts.arrayFieldName);
350
+ return false;
351
+ }
352
+ }
353
+ catch (err) {
354
+ // continue
355
+ // read in cache is not guaranteed to return a result. see https://github.com/apollographql/react-apollo/issues/1776#issuecomment-372237940
356
+ if (this._debug)
357
+ console.warn('[graphql] Error while removing from cache: ', err);
358
+ return false;
359
+ }
360
+ }
361
+ /**
362
+ * Remove ids from cache, and return the number of items removed
363
+ *
364
+ * @param cache
365
+ * @param opts
366
+ */
367
+ removeFromCachedQueryByIds(cache, opts) {
368
+ cache = cache || this.apollo.client.cache;
369
+ opts.arrayFieldName = opts.arrayFieldName || 'data';
370
+ try {
371
+ let data = cache.readQuery(opts);
372
+ if (data && data[opts.arrayFieldName]) {
373
+ // Copy because immutable
374
+ data = { ...data };
375
+ const deletedIndexes = data[opts.arrayFieldName].reduce((res, item, index) => opts.ids.includes(item['id']) ? res.concat(index) : res, []);
376
+ if (deletedIndexes.length <= 0)
377
+ return 0; // Skip (nothing removed)
378
+ // Query has NO total
379
+ if (isNil(opts.totalFieldName)) {
380
+ // Evict each object
381
+ deletedIndexes
382
+ .map(index => data[opts.arrayFieldName][index])
383
+ .map(item => cache.identify(item))
384
+ .forEach(id => cache.evict({ id }));
385
+ }
386
+ // Query has a total
387
+ else {
388
+ // Copy the array
389
+ data[opts.arrayFieldName] = data[opts.arrayFieldName].slice();
390
+ // remove from array, then evict
391
+ deletedIndexes
392
+ // Reverse: to keep valid index
393
+ .reverse()
394
+ // Remove from the array
395
+ .map(index => data[opts.arrayFieldName].splice(index, 1)[0])
396
+ // Evict from cache
397
+ .map(item => cache.identify(item))
398
+ .forEach(id => cache.evict({ id }));
399
+ if (isNotNil(data[opts.totalFieldName])) {
400
+ data[opts.totalFieldName] -= deletedIndexes.length; // Remove deletion count
401
+ }
402
+ else {
403
+ console.warn('[graphql] Unable to update the total in cached query. Unknown result part: ' + opts.totalFieldName);
404
+ }
405
+ cache.writeQuery({
406
+ query: opts.query,
407
+ variables: opts.variables,
408
+ data
409
+ });
410
+ return deletedIndexes.length;
411
+ }
412
+ }
413
+ else {
414
+ console.warn('[graphql] Unable to update cached query. Unknown result part: ' + opts.arrayFieldName);
415
+ return 0;
416
+ }
417
+ }
418
+ catch (err) {
419
+ // continue
420
+ // read in cache is not guaranteed to return a result. see https://github.com/apollographql/react-apollo/issues/1776#issuecomment-372237940
421
+ if (this._debug)
422
+ console.warn('[graphql] Error while removing from cache: ', err);
423
+ return 0;
424
+ }
425
+ }
426
+ updateToQueryCache(cache, opts) {
427
+ cache = cache || this.apollo.client.cache;
428
+ opts.arrayFieldName = opts.arrayFieldName || 'data';
429
+ try {
430
+ let data = cache.readQuery(opts);
431
+ if (data && data[opts.arrayFieldName]) {
432
+ // Copy because immutable
433
+ data = { ...data };
434
+ const equalsFn = opts.equalsFn || ((d1, d2) => EntityUtils.equals(d1, d2, 'id'));
435
+ // Update if exists, or insert
436
+ const index = data[opts.arrayFieldName].findIndex(v => equalsFn(opts.data, v));
437
+ if (index !== -1) {
438
+ data[opts.arrayFieldName] = data[opts.arrayFieldName].slice().splice(index, 1, opts.data);
439
+ }
440
+ else {
441
+ data[opts.arrayFieldName] = [...data[opts.arrayFieldName], opts.data];
442
+ }
443
+ // Increment total (if changed)
444
+ if (isNotNil(opts.totalFieldName) && index === -1) {
445
+ if (isNotNil(data[opts.totalFieldName])) {
446
+ data[opts.totalFieldName] += 1;
447
+ }
448
+ else {
449
+ console.warn('[graphql] Unable to update cached query. Unknown result part: ' + opts.totalFieldName);
450
+ }
451
+ }
452
+ cache.writeQuery({
453
+ query: opts.query,
454
+ variables: opts.variables,
455
+ data
456
+ });
457
+ return; // OK: stop here
458
+ }
459
+ }
460
+ catch (err) {
461
+ // continue
462
+ // read in cache is not guaranteed to return a result. see https://github.com/apollographql/react-apollo/issues/1776#issuecomment-372237940
463
+ if (this._debug)
464
+ console.warn('[graphql] Error while updating cache: ', err);
465
+ }
466
+ }
467
+ async clearCache(client) {
468
+ client = (client || this.client);
469
+ if (client) {
470
+ console.info('[graphql] Cleaning cache... ');
471
+ const now = this._debug && Date.now();
472
+ // Clearing the cache
473
+ await client.cache.reset();
474
+ if (this._debug)
475
+ console.debug(`[graphql] Cleaning cache [OK] in ${Date.now() - now}ms`);
476
+ }
477
+ }
478
+ registerCustomError(error) {
479
+ this.customErrors = { ...this.customErrors, ...error };
480
+ }
481
+ /* -- protected methods -- */
482
+ async ngOnStart() {
483
+ // Wait network and storage
484
+ await Promise.all([
485
+ this.storage.ready(),
486
+ this.network.ready()
487
+ ]);
488
+ console.info('[graphql] Starting graphql...');
489
+ const mobile = isMobile(window);
490
+ const enableTrackMutationQueries = !mobile;
491
+ const peer = this.network.peer;
492
+ if (!peer)
493
+ throw Error('[graphql] Missing peer. Unable to start graphql service');
494
+ const uri = peer.url + '/graphql';
495
+ const wsUrl = uri.replace(/^http(s)?:/, 'ws$1:') + '/websocket';
496
+ console.info('[graphql] Base uri: ' + uri);
497
+ console.info('[graphql] Subscription uri: ' + wsUrl);
498
+ this.httpParams = this.httpParams || {};
499
+ this.httpParams.uri = uri;
500
+ this.wsParams = {
501
+ ...this.wsParams,
502
+ lazy: true,
503
+ connectionParams: this.connectionParams,
504
+ webSocketImpl: AppWebSocket,
505
+ url: wsUrl,
506
+ shouldRetry: (errOrCloseEvent) => {
507
+ // If WS URL changed, then do not retry
508
+ if (wsUrl !== this.wsParams.url) {
509
+ return false;
510
+ }
511
+ console.warn('[graphql-service] [WS] Trying to reconnect...', errOrCloseEvent);
512
+ return true;
513
+ },
514
+ retryAttempts: 10
515
+ };
516
+ // Create a storage configuration
517
+ const storage = new StorageServiceWrapper(this.storage);
518
+ let client = this.apollo.client;
519
+ if (!client) {
520
+ console.debug('[graphql] Creating Apollo GraphQL client...');
521
+ // Websocket link
522
+ const wsLink = new GraphQLWsLink(createClient(this.wsParams));
523
+ this.onResetAuth
524
+ .pipe(takeUntil(this.stopSubject))
525
+ .subscribe(() => {
526
+ console.info('[graphql] Closing websocket client, to force unauth');
527
+ wsLink.client.dispose();
528
+ });
529
+ // Retry when failed link
530
+ const retryLink = new RetryLink();
531
+ const authLink = new ApolloLink((operation, forward) => {
532
+ const authorization = [];
533
+ if (this.connectionParams.authToken) {
534
+ authorization.push(`token ${this.connectionParams.authToken}`);
535
+ }
536
+ if (this.connectionParams.authBasic) {
537
+ authorization.push(`Basic ${this.connectionParams.authBasic}`);
538
+ }
539
+ const headers = new HttpHeaders()
540
+ .append('Authorization', authorization);
541
+ // Use the setContext method to set the HTTP headers.
542
+ operation.setContext({
543
+ ...operation.getContext(),
544
+ ...{ headers }
545
+ });
546
+ // Call the next link in the middleware chain.
547
+ return forward(operation);
548
+ });
549
+ // Http link
550
+ const httpLink = this.httpLink.create(this.httpParams);
551
+ // Cache
552
+ const cache = new InMemoryCache({
553
+ typePolicies: this.typePolicies,
554
+ fragments: isNotEmptyArray(this.fragments) ? createFragmentRegistry(...this.fragments) : undefined
555
+ });
556
+ // Add cache persistence
557
+ if (this.environment.persistCache) {
558
+ console.debug('[graphql] Starting persistence cache...');
559
+ await persistCache({
560
+ cache,
561
+ storage,
562
+ trigger: this.platform.is('android') ? 'background' : 'write',
563
+ debounce: 1000,
564
+ debug: true
565
+ });
566
+ }
567
+ let mutationLinks;
568
+ // Add queue to store tracked queries, when offline
569
+ if (enableTrackMutationQueries) {
570
+ const serializingLink = new SerializingLink();
571
+ const trackerLink = createTrackerLink({
572
+ storage,
573
+ onNetworkStatusChange: this._networkStatusChanged$,
574
+ debounce: 1000,
575
+ debug: true
576
+ });
577
+ // Creating a mutation queue
578
+ const queueLink = new QueueLink();
579
+ this.registerSubscription(this._networkStatusChanged$
580
+ .subscribe(type => {
581
+ // Network is offline: start buffering into queue
582
+ if (type === 'none') {
583
+ console.info('[graphql] offline mode: enable mutations buffer');
584
+ queueLink.close();
585
+ }
586
+ // Network is online
587
+ else {
588
+ console.info('[graphql] online mode: disable mutations buffer');
589
+ queueLink.open();
590
+ }
591
+ }));
592
+ mutationLinks = [
593
+ loggerLink,
594
+ queueLink,
595
+ trackerLink,
596
+ queueLink,
597
+ serializingLink,
598
+ retryLink,
599
+ authLink,
600
+ httpLink
601
+ ];
602
+ }
603
+ else {
604
+ mutationLinks = [
605
+ retryLink,
606
+ authLink,
607
+ httpLink
608
+ ];
609
+ }
610
+ // create Apollo
611
+ client = new ApolloClient({
612
+ cache,
613
+ link: ApolloLink.split(
614
+ // Handle mutations
615
+ isMutationOperation, ApolloLink.from(mutationLinks), ApolloLink.split(
616
+ // Handle subscriptions
617
+ isSubscriptionOperation, wsLink,
618
+ // Handle queries
619
+ ApolloLink.from([
620
+ retryLink,
621
+ authLink,
622
+ httpLink
623
+ ]))),
624
+ connectToDevTools: !this.environment.production
625
+ });
626
+ this.apollo.client = client;
627
+ }
628
+ // Enable tracked queries persistence
629
+ if (enableTrackMutationQueries && this.environment.persistCache) {
630
+ try {
631
+ await restoreTrackedQueries({
632
+ apolloClient: client,
633
+ storage,
634
+ debug: true
635
+ });
636
+ }
637
+ catch (err) {
638
+ console.error('[graphql] Failed to restore tracked queries from storage: ' + (err && err.message || err), err);
639
+ }
640
+ }
641
+ // Listen for network restart
642
+ this.registerSubscription(this.network.on('start', () => this.restart()));
643
+ // Listen for clear cache request, from network
644
+ this.registerSubscription(this.network.on('resetCache', () => this.clearCache()));
645
+ console.info('[graphql] Starting graphql [OK]');
646
+ return client;
647
+ }
648
+ async ngOnStop() {
649
+ console.info('[graphql] Stopping graphql service...');
650
+ await this.resetClient();
651
+ }
652
+ async resetClient(client) {
653
+ client = (client || this.apollo.client);
654
+ if (!client)
655
+ return;
656
+ console.info('[graphql] Resetting Apollo client...');
657
+ client.stop();
658
+ this.onResetAuth.next();
659
+ await Promise.all([
660
+ client.clearStore(),
661
+ this.clearCache(client)
662
+ ]);
663
+ }
664
+ onApolloError(err, defaultError) {
665
+ return of(this.toApolloError(err, defaultError));
666
+ }
667
+ toApolloError(err, defaultError) {
668
+ let error =
669
+ // If network error: try to convert to App (read as JSON), or create an UNKNOWN_NETWORK_ERROR
670
+ (err.networkError && ((err.networkError.error && this.toAppError(err.networkError.error))
671
+ || this.toAppError(err.networkError)
672
+ || (err.networkError.error && this.createAppErrorByCode(err.networkError.error.status))
673
+ || this.createAppErrorByCode(ErrorCodes.UNKNOWN_NETWORK_ERROR)))
674
+ // If graphQL: try to convert the first error found
675
+ || (err.graphQLErrors && err.graphQLErrors.length && this.toAppError(err.graphQLErrors[0]))
676
+ || this.toAppError(err)
677
+ || this.toAppError(err.originalError)
678
+ || (err.graphQLErrors && err.graphQLErrors[0])
679
+ || err;
680
+ console.error('[graphql] ' + (error && error.message || error), error.stack || '');
681
+ if (error?.code === ErrorCodes.UNKNOWN_NETWORK_ERROR && err.networkError?.message) {
682
+ console.error('[graphql] original error: ' + err.networkError.message);
683
+ this.onNetworkError.next(error);
684
+ }
685
+ // Apply default error, and store original error into error's details
686
+ if ((!error || !error.code || error.code === ErrorCodes.INTERNAL_SERVER_ERROR) && defaultError) {
687
+ error = { ...defaultError, details: error, stack: err.stack };
688
+ if (defaultError.message) {
689
+ error.message = defaultError.message;
690
+ }
691
+ }
692
+ return {
693
+ data: null,
694
+ errors: [error],
695
+ loading: false,
696
+ networkStatus: NetworkStatus.error
697
+ };
698
+ }
699
+ createAppErrorByCode(errorCode) {
700
+ const message = this.getI18nErrorMessageByCode(errorCode);
701
+ if (message) {
702
+ return {
703
+ code: errorCode,
704
+ message
705
+ };
706
+ }
707
+ return undefined;
708
+ }
709
+ getI18nErrorMessageByCode(errorCode) {
710
+ // look in registered error codes
711
+ const customErrorMessage = this.customErrors[errorCode];
712
+ if (customErrorMessage) {
713
+ return customErrorMessage;
714
+ }
715
+ // Default, switch on error code
716
+ switch (errorCode) {
717
+ case ServerErrorCodes.UNAUTHORIZED:
718
+ return 'ERROR.UNAUTHORIZED';
719
+ case ServerErrorCodes.FORBIDDEN:
720
+ return 'ERROR.FORBIDDEN';
721
+ case ErrorCodes.UNKNOWN_NETWORK_ERROR:
722
+ return 'ERROR.UNKNOWN_NETWORK_ERROR';
723
+ case ServerErrorCodes.BAD_UPDATE_DATE:
724
+ return 'ERROR.BAD_UPDATE_DATE';
725
+ case ServerErrorCodes.DATA_LOCKED:
726
+ return 'ERROR.DATA_LOCKED';
727
+ case ServerErrorCodes.BAD_APP_VERSION:
728
+ return 'ERROR.BAD_APP_VERSION';
729
+ case ServerErrorCodes.DATA_NOT_UNIQUE:
730
+ return 'ERROR.DATA_NOT_UNIQUE';
731
+ }
732
+ return undefined;
733
+ }
734
+ toAppError(err) {
735
+ let error = err;
736
+ let message = err && err.message || err;
737
+ // parse message if JSON
738
+ if (typeof message === 'string' && message.trim().indexOf('{"code":') === 0) {
739
+ try {
740
+ error = JSON.parse(message
741
+ // Remove special characters before parsing (e.g. SQL errors from an Oracle database)
742
+ .replace('\n', ' ')
743
+ .replace('\r', ''));
744
+ message = error.message || message;
745
+ }
746
+ catch (parseError) {
747
+ console.error('Unable to parse error as JSON: ', parseError);
748
+ }
749
+ }
750
+ if (error && error.code) {
751
+ const appError = {
752
+ code: error.code,
753
+ message: (typeof message === 'string') ? message : error.message,
754
+ ...this.createAppErrorByCode(error.code)
755
+ };
756
+ if (appError.code !== error.code || appError.message !== error.message) {
757
+ // Store original error in details
758
+ appError.details = error;
759
+ return appError;
760
+ }
761
+ // Keep error (with details, if any)
762
+ return error;
763
+ }
764
+ return undefined;
765
+ }
766
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.0.6", ngImport: i0, type: GraphqlService, deps: [{ token: i1.Platform }, { token: i2.Apollo }, { token: i3.HttpLink }, { token: i4.NetworkService }, { token: i5.StorageService }, { token: ENVIRONMENT }, { token: APP_GRAPHQL_TYPE_POLICIES, optional: true }, { token: APP_GRAPHQL_FRAGMENTS, optional: true }], target: i0.ɵɵFactoryTarget.Injectable });
767
+ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "17.0.6", ngImport: i0, type: GraphqlService, providedIn: 'root' });
768
+ }
769
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.0.6", ngImport: i0, type: GraphqlService, decorators: [{
770
+ type: Injectable,
771
+ args: [{
772
+ providedIn: 'root'
773
+ }]
774
+ }], ctorParameters: () => [{ type: i1.Platform }, { type: i2.Apollo }, { type: i3.HttpLink }, { type: i4.NetworkService }, { type: i5.StorageService }, { type: i6.Environment, decorators: [{
775
+ type: Inject,
776
+ args: [ENVIRONMENT]
777
+ }] }, { type: undefined, decorators: [{
778
+ type: Optional
779
+ }, {
780
+ type: Inject,
781
+ args: [APP_GRAPHQL_TYPE_POLICIES]
782
+ }] }, { type: undefined, decorators: [{
783
+ type: Optional
784
+ }, {
785
+ type: Inject,
786
+ args: [APP_GRAPHQL_FRAGMENTS]
787
+ }] }] });
788
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZ3JhcGhxbC5zZXJ2aWNlLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vLi4vc3JjL2FwcC9jb3JlL2dyYXBocWwvZ3JhcGhxbC5zZXJ2aWNlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxjQUFjLEVBQWMsRUFBRSxFQUFFLE9BQU8sRUFBRSxNQUFNLE1BQU0sQ0FBQztBQUUvRCxPQUFPLEVBRUwsWUFBWSxFQUNaLFVBQVUsRUFHVixhQUFhLEVBRWIsYUFBYSxHQUlkLE1BQU0scUJBQXFCLENBQUM7QUFDN0IsT0FBTyxFQUFFLFVBQVUsRUFBRSxnQkFBZ0IsRUFBZ0IsTUFBTSxvQkFBb0IsQ0FBQztBQUNoRixPQUFPLEVBQUUsVUFBVSxFQUFFLG9CQUFvQixFQUFFLE1BQU0sRUFBRSxLQUFLLEVBQUUsR0FBRyxFQUFFLFFBQVEsRUFBRSxTQUFTLEVBQUUsWUFBWSxFQUFFLE1BQU0sZ0JBQWdCLENBQUM7QUFFekgsT0FBTyxFQUFFLE1BQU0sRUFBRSxVQUFVLEVBQUUsY0FBYyxFQUFFLFFBQVEsRUFBRSxNQUFNLGVBQWUsQ0FBQztBQUc3RSxPQUFPLEVBQ0wsWUFBWSxFQUNaLGlCQUFpQixFQUVqQixtQkFBbUIsRUFDbkIsdUJBQXVCLEVBQ3ZCLHFCQUFxQixFQUNyQixxQkFBcUIsR0FDdEIsTUFBTSxpQkFBaUIsQ0FBQztBQUN6QixPQUFPLEVBQUUsU0FBUyxFQUFFLE1BQU0sMkJBQTJCLENBQUM7QUFDdEQsT0FBTyxpQkFBaUIsTUFBTSxtQkFBbUIsQ0FBQztBQUNsRCxPQUFPLHVCQUF1QixNQUFNLHVCQUF1QixDQUFDO0FBQzVELE9BQU8sa0JBQWtCLE1BQU0sb0JBQW9CLENBQUM7QUFFcEQsT0FBTyxFQUFFLFdBQVcsRUFBVyxNQUFNLGdDQUFnQyxDQUFDO0FBQ3RFLE9BQU8sRUFBRSxLQUFLLEVBQUUsZUFBZSxFQUFFLFFBQVEsRUFBRSxRQUFRLEVBQUUsTUFBTSx3QkFBd0IsQ0FBQztB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Q0FBb0M7WUFDcEMsT0FBTyxLQUFLLENBQUM7U0FDZDtRQUNELE9BQU8sU0FBUyxDQUFDO0lBQ25CLENBQUM7dUdBaDRCVSxjQUFjLG9KQThCZixXQUFXLGFBQ0MseUJBQXlCLDZCQUN6QixxQkFBcUI7MkdBaENoQyxjQUFjLGNBRmIsTUFBTTs7MkZBRVAsY0FBYztrQkFIMUIsVUFBVTttQkFBQztvQkFDVixVQUFVLEVBQUUsTUFBTTtpQkFDbkI7OzBCQStCSSxNQUFNOzJCQUFDLFdBQVc7OzBCQUNsQixRQUFROzswQkFBSSxNQUFNOzJCQUFDLHlCQUF5Qjs7MEJBQzVDLFFBQVE7OzBCQUFJLE1BQU07MkJBQUMscUJBQXFCIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgZmlyc3RWYWx1ZUZyb20sIE9ic2VydmFibGUsIG9mLCBTdWJqZWN0IH0gZnJvbSAncnhqcyc7XG5pbXBvcnQgeyBBcG9sbG8sIEV4dHJhU3Vic2NyaXB0aW9uT3B0aW9ucywgUXVlcnlSZWYgfSBmcm9tICdhcG9sbG8tYW5ndWxhcic7XG5pbXBvcnQge1xuICBBcG9sbG9DYWNoZSxcbiAgQXBvbGxvQ2xpZW50LFxuICBBcG9sbG9MaW5rLFxuICBBcG9sbG9RdWVyeVJlc3VsdCxcbiAgRmV0Y2hQb2xpY3ksXG4gIEluTWVtb3J5Q2FjaGUsXG4gIE11dGF0aW9uVXBkYXRlckZuLFxuICBOZXR3b3JrU3RhdHVzLFxuICBPcGVyYXRpb25WYXJpYWJsZXMsXG4gIFR5cGVQb2xpY2llcyxcbiAgV2F0Y2hRdWVyeUZldGNoUG9saWN5LFxufSBmcm9tICdAYXBvbGxvL2NsaWVudC9jb3JlJztcbmltcG9ydCB7IEVycm9yQ29kZXMsIFNlcnZlckVycm9yQ29kZXMsIFNlcnZpY2VFcnJvciB9IGZyb20gJy4uL3NlcnZpY2VzL2Vycm9ycyc7XG5pbXBvcnQgeyBjYXRjaEVycm9yLCBkaXN0aW5jdFVudGlsQ2hhbmdlZCwgZmlsdGVyLCBmaXJzdCwgbWFwLCBtZXJnZU1hcCwgdGFrZVVudGlsLCB0aHJvdHRsZVRpbWUgfSBmcm9tICdyeGpzL29wZXJhdG9ycyc7XG5cbmltcG9ydCB7IEluamVjdCwgSW5qZWN0YWJsZSwgSW5qZWN0aW9uVG9rZW4sIE9wdGlvbmFsIH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQgeyBOZXR3b3JrU2VydmljZSB9IGZyb20gJy4uL3NlcnZpY2VzL25ldHdvcmsuc2VydmljZSc7XG5pbXBvcnQgeyBDb25uZWN0aW9uVHlwZSB9IGZyb20gJy4uL3NlcnZpY2VzL25ldHdvcmsudHlwZXMnO1xuaW1wb3J0IHtcbiAgQXBwV2ViU29ja2V0LFxuICBjcmVhdGVUcmFja2VyTGluayxcbiAgRW1wdHlPYmplY3QsXG4gIGlzTXV0YXRpb25PcGVyYXRpb24sXG4gIGlzU3Vic2NyaXB0aW9uT3BlcmF0aW9uLFxuICByZXN0b3JlVHJhY2tlZFF1ZXJpZXMsXG4gIFN0b3JhZ2VTZXJ2aWNlV3JhcHBlcixcbn0gZnJvbSAnLi9ncmFwaHFsLnV0aWxzJztcbmltcG9ydCB7IFJldHJ5TGluayB9IGZyb20gJ0BhcG9sbG8vY2xpZW50L2xpbmsvcmV0cnknO1xuaW1wb3J0IHF1ZXVlTGlua0ltcG9ydGVkIGZyb20gJ2Fwb2xsby1saW5rLXF1ZXVlJztcbmltcG9ydCBzZXJpYWxpemluZ0xpbmtJbXBvcnRlZCBmcm9tICdhcG9sbG8tbGluay1zZXJpYWxpemUnO1xuaW1wb3J0IGxvZ2dlckxpbmtJbXBvcnRlZCBmcm9tICdhcG9sbG8tbGluay1sb2dnZXInO1xuaW1wb3J0IHsgUGxhdGZvcm0gfSBmcm9tICdAaW9uaWMvYW5ndWxhcic7XG5pbXBvcnQgeyBFbnRpdHlVdGlscywgSUVudGl0eSB9IGZyb20gJy4uL3NlcnZpY2VzL21vZGVsL2VudGl0eS5tb2RlbCc7XG5pbXBvcnQgeyBpc05pbCwgaXNOb3RFbXB0eUFycmF5LCBpc05vdE5pbCwgdG9OdW1iZXIgfSBmcm9tICcuLi8uLi9zaGFyZWQvZnVuY3Rpb25zJztcbmltcG9ydCB7IFJlc29sdmVycyB9IGZyb20gJ0BhcG9sbG8vY2xpZW50L2NvcmUvdHlwZXMnO1xuaW1wb3J0IHsgSHR0cEhlYWRlcnMgfSBmcm9tICdAYW5ndWxhci9jb21tb24vaHR0cCc7XG5pbXBvcnQgeyBIdHRwTGluaywgT3B0aW9ucyB9IGZyb20gJ2Fwb2xsby1hbmd1bGFyL2h0dHAnO1xuaW1wb3J0IHsgcGVyc2lzdENhY2hlLCBQZXJzaXN0ZW50U3RvcmFnZSB9IGZyb20gJ2Fwb2xsbzMtY2FjaGUtcGVyc2lzdCc7XG5pbXBvcnQgeyBFcnJvclBvbGljeSwgTXV0YXRpb25CYXNlT3B0aW9ucyB9IGZyb20gJ0BhcG9sbG8vY2xpZW50L2NvcmUvd2F0Y2hRdWVyeU9wdGlvbnMnO1xuaW1wb3J0IHsgQ2FjaGUgfSBmcm9tICdAYXBvbGxvL2NsaWVudC9jYWNoZS9jb3JlL3R5cGVzL0NhY2hlJztcbmltcG9ydCB7IEVudmlyb25tZW50LCBFTlZJUk9OTUVOVCB9IGZyb20gJy4uLy4uLy4uL2Vudmlyb25tZW50cy9lbnZpcm9ubWVudC5jbGFzcyc7XG5pbXBvcnQgeyBQcm9wZXJ0aWVzTWFwIH0gZnJvbSAnLi4vLi4vc2hhcmVkL3R5cGVzJztcbmltcG9ydCB7IFN0YXJ0YWJsZVNlcnZpY2UgfSBmcm9tICcuLi8uLi9zaGFyZWQvc2VydmljZXMvc3RhcnRhYmxlLXNlcnZpY2UuY2xhc3MnO1xuaW1wb3J0IHsgaXNNb2JpbGUgfSBmcm9tICcuLi8uLi9zaGFyZWQvcGxhdGZvcm1zJztcbmltcG9ydCB7IFN0b3JhZ2VTZXJ2aWNlIH0gZnJvbSAnLi4vLi4vc2hhcmVkL3N0b3JhZ2Uvc3RvcmFnZS5zZXJ2aWNlJztcbmltcG9ydCB7IEdyYXBoUUxXc0xpbmsgfSBmcm9tICdAYXBvbGxvL2NsaWVudC9saW5rL3N1YnNjcmlwdGlvbnMnO1xuaW1wb3J0IHsgQ2xpZW50T3B0aW9ucywgY3JlYXRlQ2xpZW50IH0gZnJvbSAnZ3JhcGhxbC13cyc7XG5pbXBvcnQgeyB1bndyYXBFU01vZHVsZSB9IGZyb20gJy4uLy4uL3NoYXJlZC9tb2R1bGVzJztcbmltcG9ydCB7IGNyZWF0ZUZyYWdtZW50UmVnaXN0cnkgfSBmcm9tICdAYXBvbGxvL2NsaWVudC9jYWNoZS9pbm1lbW9yeS9mcmFnbWVudFJlZ2lzdHJ5JztcbmltcG9ydCB7IERvY3VtZW50Tm9kZSB9IGZyb20gJ2dyYXBocWwnO1xuXG4vLyBXb3JrYXJvdW5kIGZvciBpc3N1ZSBodHRwczovL2dpdGh1Yi5jb20vbmctcGFja2Fnci9uZy1wYWNrYWdyL2lzc3Vlcy8yMjE1XG5jb25zdCBRdWV1ZUxpbmsgPSB1bndyYXBFU01vZHVsZShxdWV1ZUxpbmtJbXBvcnRlZCk7XG5jb25zdCBTZXJpYWxpemluZ0xpbmsgPSB1bndyYXBFU01vZHVsZShzZXJpYWxpemluZ0xpbmtJbXBvcnRlZCk7XG5jb25zdCBsb2dnZXJMaW5rID0gdW53cmFwRVNNb2R1bGUobG9nZ2VyTGlua0ltcG9ydGVkKTtcblxuZXhwb3J0IGludGVyZmFjZSBXYXRjaFF1ZXJ5T3B0aW9uczxWPiB7XG4gIHF1ZXJ5OiBhbnk7XG4gIHZhcmlhYmxlcz86IFY7XG4gIGVycm9yPzogU2VydmljZUVycm9yO1xuICBmZXRjaFBvbGljeT86IFdhdGNoUXVlcnlGZXRjaFBvbGljeTtcbn1cblxuZXhwb3J0IGludGVyZmFjZSBNdXRhdGVRdWVyeU9wdGlvbnM8VCwgViA9IE9wZXJhdGlvblZhcmlhYmxlcz4gZXh0ZW5kcyBNdXRhdGlvbkJhc2VPcHRpb25zPFQsIFY+IHtcbiAgbXV0YXRpb246IGFueTtcbiAgdmFyaWFibGVzPzogVjtcbiAgZXJyb3I/OiBTZXJ2aWNlRXJyb3I7XG4gIGNvbnRleHQ/OiB7XG4gICAgc2VyaWFsaXphdGlvbktleT86IHN0cmluZztcbiAgICB0cmFja2VkPzogYm9vbGVhbjtcbiAgICB0aW1lb3V0PzogbnVtYmVyO1xuICB9O1xuICBvcHRpbWlzdGljUmVzcG9uc2U/OiBUO1xuICBvZmZsaW5lUmVzcG9uc2U/OiBUIHwgKChjb250ZXh0OiBhbnkpID0+IFByb21pc2U8VD4pO1xuICB1cGRhdGU/OiBNdXRhdGlvblVwZGF0ZXJGbjxUPjtcbiAgZm9yY2VPZmZsaW5lPzogYm9vbGVhbjtcbn1cblxuZXhwb3J0IGNvbnN0IEFQUF9HUkFQSFFMX1RZUEVfUE9MSUNJRVMgPSBuZXcgSW5qZWN0aW9uVG9rZW48VHlwZVBvbGljaWVzPignZ3JhcGhxbFR5cGVQb2xpY2llcycpO1xuXG5leHBvcnQgY29uc3QgQVBQX0dSQVBIUUxfRlJBR01FTlRTID0gbmV3IEluamVjdGlvblRva2VuPERvY3VtZW50Tm9kZVtdPignZ3JhcGhxbEZyYWdtZW50cycpO1xuXG5cbmV4cG9ydCBpbnRlcmZhY2UgQ29ubmVjdGlvblBhcmFtcyBleHRlbmRzIFJlY29yZDxzdHJpbmcsIHN0cmluZz4ge1xuICBhdXRoVG9rZW4/OiBzdHJpbmc7XG4gIGF1dGhCYXNpYz86IHN0cmluZztcbn1cblxuQEluamVjdGFibGUoe1xuICBwcm92aWRlZEluOiAncm9vdCdcbn0pXG5leHBvcnQgY2xhc3MgR3JhcGhxbFNlcnZpY2UgZXh0ZW5kcyBTdGFydGFibGVTZXJ2aWNlPEFwb2xsb0NsaWVudDxhbnk+PiB7XG5cbiAgcHJpdmF0ZSByZWFkb25seSBfbmV0d29ya1N0YXR1c0NoYW5nZWQkOiBPYnNlcnZhYmxlPENvbm5lY3Rpb25UeXBlPjtcblxuICBwcml2YXRlIGh0dHBQYXJhbXM6IE9wdGlvbnM7XG4gIHByaXZhdGUgd3NQYXJhbXM6IENsaWVudE9wdGlvbnM8Q29ubmVjdGlvblBhcmFtcz47XG4gIHByaXZhdGUgY29ubmVjdGlvblBhcmFtczogQ29ubmVjdGlvblBhcmFtcyA9IHt9O1xuICBwcml2YXRlIHJlYWRvbmx5IF9kZWZhdWx0RmV0Y2hQb2xpY3k6IFdhdGNoUXVlcnlGZXRjaFBvbGljeTtcbiAgcHJpdmF0ZSBvbk5ldHdvcmtFcnJvciA9IG5ldyBTdWJqZWN0PGFueT4oKTtcbiAgcHJpdmF0ZSBjdXN0b21FcnJvcnM6IFByb3BlcnRpZXNNYXAgPSB7fTtcbiAgcHJpdmF0ZSBvblJlc2V0QXV0aCAgPSBuZXcgU3ViamVjdDx2b2lkPigpO1xuXG4gIGdldCBjbGllbnQoKTogQXBvbGxvQ2xpZW50PGFueT4ge1xuICAgIHJldHVybiB0aGlzLl9kYXRhO1xuICB9XG5cbiAgZ2V0IGNhY2hlKCk6IEFwb2xsb0NhY2hlPGFueT4ge1xuICAgIHJldHVybiB0aGlzLmFwb2xsby5jbGllbnQuY2FjaGU7XG4gIH1cblxuICBnZXQgZGVmYXVsdEZldGNoUG9saWN5KCk6IFdhdGNoUXVlcnlGZXRjaFBvbGljeSB7XG4gICAgcmV0dXJuIHRoaXMuX2RlZmF1bHRGZXRjaFBvbGljeTtcbiAgfVxuXG4gIGNvbnN0cnVjdG9yKFxuICAgIHByaXZhdGUgcGxhdGZvcm06IFBsYXRmb3JtLFxuICAgIHByaXZhdGUgYXBvbGxvOiBBcG9sbG8sXG4gICAgcHJpdmF0ZSBodHRwTGluazogSHR0cExpbmssXG4gICAgcHJpdmF0ZSBuZXR3b3JrOiBOZXR3b3JrU2VydmljZSxcbiAgICBwcml2YXRlIHN0b3JhZ2U6IFN0b3JhZ2VTZXJ2aWNlLFxuICAgIEBJbmplY3QoRU5WSVJPTk1FTlQpIHByb3RlY3RlZCBlbnZpcm9ubWVudDogRW52aXJvbm1lbnQsXG4gICAgQE9wdGlvbmFsKCkgQEluamVjdChBUFBfR1JBUEhRTF9UWVBFX1BPTElDSUVTKSBwcml2YXRlIHR5cGVQb2xpY2llczogVHlwZVBvbGljaWVzLFxuICAgIEBPcHRpb25hbCgpIEBJbmplY3QoQVBQX0dSQVBIUUxfRlJBR01FTlRTKSBwcml2YXRlIGZyYWdtZW50czogRG9jdW1lbnROb2RlW11cbiAgKSB7XG4gICAgc3VwZXIocGxhdGZvcm0pOyAvLyBXYWl0IHBsYXRmb3JtXG5cbiAgICB0aGlzLl9kZWJ1ZyA9ICFlbnZpcm9ubWVudC5wcm9kdWN0aW9uO1xuICAgIHRoaXMuX2RlZmF1bHRGZXRjaFBvbGljeSA9IGVudmlyb25tZW50LmFwb2xsb0ZldGNoUG9saWN5O1xuXG4gICAgLy8gTGlzdGVuIG5ldHdvcmsgc3RhdHVzXG4gICAgdGhpcy5fbmV0d29ya1N0YXR1c0NoYW5nZWQkID0gbmV0d29yay5vbk5ldHdvcmtTdGF0dXNDaGFuZ2VzXG4gICAgICAucGlwZShcbiAgICAgICAgZmlsdGVyKGlzTm90TmlsKSxcbiAgICAgICAgZGlzdGluY3RVbnRpbENoYW5nZWQoKVxuICAgICAgKTtcblxuICAgIC8vIFdoZW4gZ2V0dGluZyBuZXR3b3JrIGVycm9yOiB0cnkgdG8gcGluZyBwZWVyLCBhbmQgdG9nZ2xlIHRvIG9mZmxpbmVcbiAgICB0aGlzLm9uTmV0d29ya0Vycm9yXG4gICAgICAucGlwZShcbiAgICAgICAgdGhyb3R0bGVUaW1lKDMwMCksXG4gICAgICAgIGZpbHRlcigoKSA9PiB0aGlzLm5ldHdvcmsub25saW5lKSxcbiAgICAgICAgbWVyZ2VNYXAoKCkgPT4gdGhpcy5uZXR3b3JrLmNoZWNrUGVlckFsaXZlKCkpLFxuICAgICAgICBmaWx0ZXIoYWxpdmUgPT4gIWFsaXZlKVxuICAgICAgKVxuICAgICAgLnN1YnNjcmliZSgoKSA9PiB0aGlzLm5ldHdvcmsuc2V0Rm9yY2VPZmZsaW5lKHRydWUsIHtzaG93VG9hc3Q6IHRydWV9KSk7XG5cbiAgfVxuXG4gIGFzeW5jIHNldEF1dGhUb2tlbih0b2tlbjogc3RyaW5nKSB7XG4gICAgaWYgKHRva2VuKSB7XG4gICAgICBjb25zb2xlLmRlYnVnKCdbZ3JhcGhxbF0gQXBwbHkgdG9rZW4gYXV0aGVudGljYXRpb24gdG8gaGVhZGVycycpO1xuICAgICAgdGhpcy5jb25uZWN0aW9uUGFyYW1zLmF1dGhUb2tlbiA9IHRva2VuO1xuICAgIH1cbiAgICAvLyBDbGVhbiBhdXRoIHRva2VuXG4gICAgZWxzZSBpZiAodGhpcy5jb25uZWN0aW9uUGFyYW1zLmF1dGhUb2tlbikge1xuICAgICAgY29uc29sZS5kZWJ1ZygnW2dyYXBocWxdIFJlbW92ZSB0b2tlbiBhdXRoZW50aWNhdGlvbiBmcm9tIGhlYWRlcnMnKTtcbiAgICAgIGRlbGV0ZSB0aGlzLmNvbm5lY3Rpb25QYXJhbXMuYXV0aFRva2VuO1xuXG4gICAgICBhd2FpdCB0aGlzLmNsZWFyQ2FjaGUoKTtcbiAgICB9XG4gIH1cblxuICBhc3luYyBzZXRBdXRoQmFzaWMoYmFzaWM6IHN0cmluZykge1xuICAgIGlmIChiYXNpYykge1xuICAgICAgY29uc29sZS5kZWJ1ZygnW2dyYXBocWxdIEFwcGx5IGJhc2ljIGF1dGhlbnRpY2F0aW9uIHRvIGhlYWRlcnMnKTtcbiAgICAgIHRoaXMuY29ubmVjdGlvblBhcmFtcy5hdXRoQmFzaWMgPSBiYXNpYztcbiAgICB9XG4gICAgLy8gQ2xlYW4gYXV0aCBiYXNpY1xuICAgIGVsc2UgaWYgKHRoaXMuY29ubmVjdGlvblBhcmFtcy5hdXRoQmFzaWMpIHtcbiAgICAgIGNvbnNvbGUuZGVidWcoJ1tncmFwaHFsXSBSZW1vdmUgYmFzaWMgYXV0aGVudGljYXRpb24gZnJvbSBoZWFkZXJzJyk7XG4gICAgICBkZWxldGUgdGhpcy5jb25uZWN0aW9uUGFyYW1zLmF1dGhCYXNpYztcblxuICAgICAgYXdhaXQgdGhpcy5jbGVhckNhY2hlKCk7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIEFsbG93IHRvIGFkZCBhIGZpZWxkIHJlc29sdmVyXG4gICAqICAoc2VlIGRvYzogaHR0cHM6Ly93d3cuYXBvbGxvZ3JhcGhxbC5jb20vZG9jcy9yZWFjdC9kYXRhL2xvY2FsLXN0YXRlLyNoYW5kbGluZy1jbGllbnQtZmllbGRzLXdpdGgtcmVzb2x2ZXJzKVxuICAgKlxuICAgKiBAcGFyYW0gcmVzb2x2ZXJzXG4gICAqL1xuICBhc3luYyBhZGRSZXNvbHZlcihyZXNvbHZlcnM6IFJlc29sdmVycyB8IFJlc29sdmVyc1tdKSB7XG4gICAgaWYgKCF0aGlzLnN0YXJ0ZWQpIGF3YWl0IHRoaXMucmVhZHkoKTtcbiAgICB0aGlzLmFwb2xsby5jbGllbnQuYWRkUmVzb2x2ZXJzKHJlc29sdmVycyk7XG4gIH1cblxuICBhc3luYyBxdWVyeTxULCBWID0gRW1wdHlPYmplY3Q+KG9wdHM6IHtcbiAgICBxdWVyeTogYW55O1xuICAgIHZhcmlhYmxlcz86IFY7XG4gICAgZXJyb3I/OiBTZXJ2aWNlRXJyb3I7XG4gICAgZmV0Y2hQb2xpY3k/OiBGZXRjaFBvbGljeTtcbiAgfSk6IFByb21pc2U8VD4ge1xuICAgIGlmICghdGhpcy5zdGFydGVkKSBhd2FpdCB0aGlzLnJlYWR5KCk7XG4gICAgbGV0IHJlczogQXBvbGxvUXVlcnlSZXN1bHQ8VD47XG4gICAgdHJ5IHtcbiAgICAgIHJlcyA9IGF3YWl0IHRoaXMuY2xpZW50LnF1ZXJ5PFQsIFY+KHtcbiAgICAgICAgcXVlcnk6IG9wdHMucXVlcnksXG4gICAgICAgIHZhcmlhYmxlczogb3B0cy52YXJpYWJsZXMsXG4gICAgICAgIGZldGNoUG9saWN5OiBvcHRzLmZldGNoUG9saWN5IHx8ICh0aGlzLl9kZWZhdWx0RmV0Y2hQb2xpY3kgYXMgRmV0Y2hQb2xpY3kpIHx8IHVuZGVmaW5lZFxuICAgICAgfSk7XG4gICAgfSBjYXRjaCAoZXJyKSB7XG4gICAgICByZXMgPSB0aGlzLnRvQXBvbGxvRXJyb3I8VD4oZXJyLCBvcHRzLmVycm9yKTtcbiAgICB9XG4gICAgaWYgKHJlcy5lcnJvcnMpIHtcbiAgICAgIHRocm93IHJlcy5lcnJvcnNbMF07XG4gICAgfVxuICAgIHJldHVybiByZXMuZGF0YTtcbiAgfVxuXG4gIHdhdGNoUXVlcnlSZWY8VCwgViA9IEVtcHR5T2JqZWN0PihvcHRzOiBXYXRjaFF1ZXJ5T3B0aW9uczxWPik6IFF1ZXJ5UmVmPFQsIFY+IHtcbiAgICByZXR1cm4gdGhpcy5hcG9sbG8ud2F0Y2hRdWVyeTxULCBWPih7XG4gICAgICBxdWVyeTogb3B0cy5xdWVyeSxcbiAgICAgIHZhcmlhYmxlczogb3B0cy52YXJpYWJsZXMsXG4gICAgICBmZXRjaFBvbGljeTogb3B0cy5mZXRjaFBvbGljeSB8fCAodGhpcy5fZGVmYXVsdEZldGNoUG9saWN5IGFzIEZldGNoUG9saWN5KSB8fCB1bmRlZmluZWQsXG4gICAgICBub3RpZnlPbk5ldHdvcmtTdGF0dXNDaGFuZ2U6IHRydWVcbiAgICB9KTtcbiAgfVxuXG4gIHF1ZXJ5UmVmVmFsdWVzQ2hhbmdlczxULCBWID0gRW1wdHlPYmplY3Q+KHF1ZXJ5UmVmOiBRdWVyeVJlZjxULCBWPiwgb3B0czogV2F0Y2hRdWVyeU9wdGlvbnM8Vj4pOiBPYnNlcnZhYmxlPFQ+IHtcbiAgICByZXR1cm4gcXVlcnlSZWZcbiAgICAgIC52YWx1ZUNoYW5nZXNcbiAgICAgIC5waXBlKFxuICAgICAgICBjYXRjaEVycm9yKGVycm9yID0+IHRoaXMub25BcG9sbG9FcnJvcjxUPihlcnJvciwgb3B0cy5lcnJvcikpLFxuICAgICAgICBmaWx0ZXIodmFsdWUgPT4gdmFsdWUubmV0d29ya1N0YXR1cyA9PT0gTmV0d29ya1N0YXR1cy5yZWFkeSB8fCB2YWx1ZS5uZXR3b3JrU3RhdHVzID09PSBOZXR3b3JrU3RhdHVzLmVycm9yKSxcbiAgICAgICAgbWFwKCh7ZGF0YSwgZXJyb3JzfSkgPT4ge1xuICAgICAgICAgIGlmIChlcnJvcnMpIHtcbiAgICAgICAgICAgIHRocm93IGVycm9yc1swXTtcbiAgICAgICAgICB9XG4gICAgICAgICAgcmV0dXJuIGRhdGE7XG4gICAgICAgIH0pXG4gICAgICApO1xuICB9XG5cbiAgd2F0Y2hRdWVyeTxULCBWID0gRW1wdHlPYmplY3Q+KG9wdHM6IFdhdGNoUXVlcnlPcHRpb25zPFY+KTogT2JzZXJ2YWJsZTxUPiB7XG4gICAgY29uc3QgcXVlcnlSZWY6IFF1ZXJ5UmVmPFQsIFY+ID0gdGhpcy53YXRjaFF1ZXJ5UmVmKG9wdHMpO1xuICAgIHJldHVybiB0aGlzLnF1ZXJ5UmVmVmFsdWVzQ2hhbmdlcyhxdWVyeVJlZiwgb3B0cyk7XG4gIH1cblxuICBhc3luYyBtdXRhdGU8VCwgViA9IEVtcHR5T2JqZWN0PihvcHRzOiBNdXRhdGVRdWVyeU9wdGlvbnM8VCwgVj4pOiBQcm9taXNlPFQ+IHtcblxuICAgIC8vIElmIG9mZmxpbmUsIGNvbXB1dGUgYW4gb3B0aW1pc3RpYyByZXNwb25zZSBmb3IgdHJhY2tlZCBxdWVyaWVzXG4gICAgaWYgKChvcHRzLmZvcmNlT2ZmbGluZSB8fCB0aGlzLm5ldHdvcmsub2ZmbGluZSkgJiYgb3B0cy5vZmZsaW5lUmVzcG9uc2UpIHtcbiAgICAgIGlmICh0eXBlb2Ygb3B0cy5vZmZsaW5lUmVzcG9uc2UgPT09ICdmdW5jdGlvbicpIHtcbiAgICAgICAgb3B0cy5jb250ZXh0ID0gb3B0cy5jb250ZXh0IHx8IHt9O1xuICAgICAgICBjb25zdCBvcHRpbWlzdGljUmVzcG9uc2VGbiA9IChvcHRzLm9mZmxpbmVSZXNwb25zZSBhcyAoKGNvbnRleHQ6IGFueSkgPT4gUHJvbWlzZTxUPikpO1xuICAgICAgICBvcHRzLm9wdGltaXN0aWNSZXNwb25zZSA9IGF3YWl0IG9wdGltaXN0aWNSZXNwb25zZUZuKG9wdHMuY29udGV4dCk7XG4gICAgICAgIGlmICh0aGlzLl9kZWJ1ZykgY29uc29sZS5kZWJ1ZygnW2dyYXBocWxdIFtvZmZsaW5lXSBVc2luZyBhbiBvcHRpbWlzdGljIHJlc3BvbnNlOiAnLCBvcHRzLm9wdGltaXN0aWNSZXNwb25zZSk7XG4gICAgICB9XG4gICAgICBlbHNlIHtcbiAgICAgICAgb3B0cy5vcHRpbWlzdGljUmVzcG9uc2UgPSBvcHRzLm9mZmxpbmVSZXNwb25zZSBhcyBUO1xuICAgICAgfVxuICAgICAgaWYgKG9wdHMuZm9yY2VPZmZsaW5lKSB7XG4gICAgICAgIGNvbnN0IHJlcyA9IHtkYXRhOiBvcHRzLm9wdGltaXN0aWNSZXNwb25zZX07XG4gICAgICAgIGlmIChvcHRzLnVwZGF0ZSkge1xuICAgICAgICAgIG9wdHMudXBkYXRlKHRoaXMuYXBvbGxvLmNsaWVudC5jYWNoZSwgcmVzKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gcmVzLmRhdGE7XG4gICAgICB9XG4gICAgfVxuXG4gICAgY29uc3QgcmVzID0gYXdhaXQgZmlyc3RWYWx1ZUZyb20odGhpcy5hcG9sbG8ubXV0YXRlPEFwb2xsb1F1ZXJ5UmVzdWx0PFQ+LCBWPih7XG4gICAgICBtdXRhdGlvbjogb3B0cy5tdXRhdGlvbixcbiAgICAgIHZhcmlhYmxlczogb3B0cy52YXJpYWJsZXMsXG4gICAgICBjb250ZXh0OiBvcHRzLmNvbnRleHQsXG4gICAgICBvcHRpbWlzdGljUmVzcG9uc2U6IG9wdHMub3B0aW1pc3RpY1Jlc3BvbnNlIGFzIGFueSxcbiAgICAgIHVwZGF0ZTogb3B0cy51cGRhdGUgYXMgYW55XG4gICAgfSlcbiAgICAgIC5waXBlKFxuICAgICAgICBjYXRjaEVycm9yKGVycm9yID0+IHRoaXMub25BcG9sbG9FcnJvcjxUPihlcnJvciwgb3B0cy5lcnJvcikpLFxuICAgICAgICBmaXJzdCgpLFxuICAgICAgICAvLyBUbyBkZWJ1ZywgaWYgbmVlZDpcbiAgICAgICAgLy90YXAoKHJlcykgPT4gKCFyZXMpICYmIGNvbnNvbGUuZXJyb3IoJ1tncmFwaHFsXSBVbmtub3duIGVycm9yIGR1cmluZyBtdXRhdGlvbi4gQ2hlY2sgZXJyb3JzIGluIGNvbnNvbGUgKG1heSBiZSBhbiBpbnZhbGlkIGdlbmVyYXRlZCBjYWNoZSBpZCA/KScpKVxuICAgICAgKSk7XG4gICAgaWYgKEFycmF5LmlzQXJyYXkocmVzLmVycm9ycykpIHtcbiAgICAgIHRocm93IHJlcy5lcnJvcnNbMF07XG4gICAgfVxuICAgIHJldHVybiByZXMuZGF0YSBhcyBUO1xuICB9XG5cbiAgc3Vic2NyaWJlPFQsIFYgPSBFbXB0eU9iamVjdD4ob3B0czoge1xuICAgIHF1ZXJ5OiBhbnk7XG4gICAgdmFyaWFibGVzOiBWO1xuICAgIGZldGNoUG9saWN5PzogRmV0Y2hQb2xpY3k7XG4gICAgZXJyb3JQb2xpY3k/OiBFcnJvclBvbGljeTtcbiAgICBlcnJvcj86IFNlcnZpY2VFcnJvcjtcbiAgfSwgZXh0cmE/OiBFeHRyYVN1YnNjcmlwdGlvbk9wdGlvbnMpOiBPYnNlcnZhYmxlPFQ+IHtcblxuICAgIHJldHVybiB0aGlzLmFwb2xsby5zdWJzY3JpYmU8VD4oe1xuICAgICAgcXVlcnk6IG9wdHMucXVlcnksXG4gICAgICBmZXRjaFBvbGljeTogb3B0cyAmJiBvcHRzLmZldGNoUG9saWN5IHx8ICduZXR3b3JrLW9ubHknLFxuICAgICAgZXJyb3JQb2xpY3k6IG9wdHMgJiYgb3B0cy5lcnJvclBvbGljeSB8fCB1bmRlZmluZWQsXG4gICAgICB2YXJpYWJsZXM6IG9wdHMudmFyaWFibGVzXG4gICAgfSwge1xuICAgICAgdXNlWm9uZTogdHJ1ZSxcbiAgICAgIC4uLmV4dHJhXG4gICAgfSlcbiAgICAgIC5waXBlKFxuICAgICAgICBjYXRjaEVycm9yKGVycm9yID0+IHRoaXMub25BcG9sbG9FcnJvcjxUPihlcnJvciwgb3B0cy5lcnJvcikpLFxuICAgICAgICBtYXAoKHtkYXRhLCBlcnJvcnN9KSA9PiB7XG4gICAgICAgICAgaWYgKGVycm9ycykge1xuICAgICAgICAgICAgdGhyb3cgZXJyb3JzWzBdO1xuICAgICAgICAgIH1cbiAgICAgICAgICByZXR1cm4gZGF0YTtcbiAgICAgICAgfSlcbiAgICAgICk7XG4gIH1cblxuICBpbnNlcnRJbnRvUXVlcnlDYWNoZTxULCBWID0gRW1wdHlPYmplY3Q+KGNhY2hlOiBBcG9sbG9DYWNoZTxhbnk+LFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG9wdHM6IENhY2hlLlJlYWRRdWVyeU9wdGlvbnM8ViwgYW55PiAmIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFycmF5RmllbGROYW1lOiBzdHJpbmc7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0b3RhbEZpZWxkTmFtZT86IHN0cmluZztcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRhdGE6IFQ7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzb3J0Rm4/OiAoZDE6IFQsIGQyOiBUKSA9PiBudW1iZXI7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzaXplPzogbnVtYmVyO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0pIHtcblxuICAgIGNhY2hlID0gY2FjaGUgfHwgdGhpcy5hcG9sbG8uY2xpZW50LmNhY2hlO1xuICAgIG9wdHMuYXJyYXlGaWVsZE5hbWUgPSBvcHRzLmFycmF5RmllbGROYW1lIHx8ICdkYXRhJztcblxuICAgIHRyeSB7XG4gICAgICBsZXQgZGF0YSA9IGNhY2hlLnJlYWRRdWVyeTxhbnksIFY+KHtxdWVyeTogb3B0cy5xdWVyeSwgdmFyaWFibGVzOiBvcHRzLnZhcmlhYmxlc30pO1xuXG4gICAgICBpZiAoIWRhdGEpIHJldHVybjsgLy8gU2tpcDogbm90aGluZyBpbiBjYWNoZVxuXG4gICAgICBpZiAoZGF0YVtvcHRzLmFycmF5RmllbGROYW1lXSkge1xuICAgICAgICAvLyBDb3B5IGJlY2F1c2UgaW1tdXRhYmxlXG4gICAgICAgIGRhdGEgPSB7IC4uLmRhdGEgfTtcblxuICAgICAgICAvLyBBcHBlbmQgdG8gcmVzdWx0IGFycmF5XG4gICAgICAgIGRhdGFbb3B0cy5hcnJheUZpZWxkTmFtZV0gPSBbIC4uLmRhdGFbb3B0cy5hcnJheUZpZWxkTmFtZV0sIHsuLi5vcHRzLmRhdGF9XTtcblxuICAgICAgICAvLyBSZXNvcnQsIGlmIG5lZWRcbiAgICAgICAgaWYgKG9wdHMuc29ydEZuKSB7XG4gICAgICAgICAgZGF0YVtvcHRzLmFycmF5RmllbGROYW1lXS5zb3J0KG9wdHMuc29ydEZuKTtcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIEV4Y2x1ZGUgaWYgZXhjZWVkIG1heCBzaXplXG4gICAgICAgIGNvbnN0IHNpemUgPSB0b051bWJlcihvcHRzLnZhcmlhYmxlcyAmJiBvcHRzLnZhcmlhYmxlc1snc2l6ZSddLCAtMSk7XG4gICAgICAgIGlmIChzaXplID4gMCAmJiBkYXRhW29wdHMuYXJyYXlGaWVsZE5hbWVdLmxlbmd0aCA+IHNpemUpIHtcbiAgICAgICAgICBkYXRhW29wdHMuYXJyYXlGaWVsZE5hbWVdLnNwbGljZShzaXplLCBkYXRhW29wdHMuYXJyYXlGaWVsZE5hbWVdLmxlbmd0aCAtIHNpemUpO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gSW5jcmVtZW50IHRvdGFsXG4gICAgICAgIGlmIChpc05vdE5pbChvcHRzLnRvdGFsRmllbGROYW1lKSkge1xuICAgICAgICAgIGlmIChpc05vdE5pbChkYXRhW29wdHMudG90YWxGaWVsZE5hbWVdKSkge1xuICAgICAgICAgICAgZGF0YVtvcHRzLnRvdGFsRmllbGROYW1lXSArPSAxO1xuICAgICAgICAgIH1cbiAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIGNvbnNvbGUud2FybignW2dyYXBocWxdIFVuYWJsZSB0byB1cGRhdGUgY2FjaGVkIHF1ZXJ5LiBVbmtub3duIHJlc3VsdCBwYXJ0OiAnICsgb3B0cy50b3RhbEZpZWxkTmFtZSk7XG4gICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgY2FjaGUud3JpdGVRdWVyeSh7XG4gICAgICAgICAgcXVlcnk6IG9wdHMucXVlcnksXG4gICAgICAgICAgdmFyaWFibGVzOiBvcHRzLnZhcmlhYmxlcyxcbiAgICAgICAgICBkYXRhXG4gICAgICAgIH0pO1xuICAgICAgfVxuICAgICAgZWxzZSB7XG4gICAgICAgIGNvbnNvbGUud2FybignW2dyYXBocWxdIFVuYWJsZSB0byB1cGRhdGUgY2FjaGVkIHF1ZXJ5LiBVbmtub3duIHJlc3VsdCBwYXJ0OiAnICsgb3B0cy5hcnJheUZpZWxkTmFtZSk7XG4gICAgICB9XG4gICAgfSBjYXRjaCAoZXJyKSB7XG4gICAgICAvLyBjb250aW51ZVxuICAgICAgLy8gcmVhZCBpbiBjYWNoZSBpcyBub3QgZ3VhcmFudGVlZCB0byByZXR1cm4gYSByZXN1bHQuIHNlZSBodHRwczovL2dpdGh1Yi5jb20vYXBvbGxvZ3JhcGhxbC9yZWFjdC1hcG9sbG8vaXNzdWVzLzE3NzYjaXNzdWVjb21tZW50LTM3MjIzNzk0MFxuICAgICAgaWYgKHRoaXMuX2RlYnVnKSBjb25zb2xlLmVycm9yKCdbZ3JhcGhxbF0gRXJyb3Igd2hpbGUgdXBkYXRpbmcgY2FjaGU6ICcsIGVycik7XG4gICAgfVxuICB9XG5cbiAgYWRkTWFueVRvUXVlcnlDYWNoZTxUID0gYW55LCBWID0gRW1wdHlPYmplY3Q+KGNhY2hlOiBBcG9sbG9DYWNoZTxhbnk+LFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgb3B0czogQ2FjaGUuUmVhZFF1ZXJ5T3B0aW9uczxWLCBhbnk+ICYge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhcnJheUZpZWxkTmFtZTogc3RyaW5nO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0b3RhbEZpZWxkTmFtZT86IHN0cmluZztcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZGF0YTogVFtdO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlcXVhbHNGbj86IChkMTogVCwgZDI6IFQpID0+IGJvb2xlYW47XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNvcnRGbj86IChkMTogVCwgZDI6IFQpID0+IG51bWJlcjtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0pIHtcblxuICAgIGlmICghb3B0cy5kYXRhIHx8ICFvcHRzLmRhdGEubGVuZ3RoKSByZXR1cm47IC8vIG5vdGhpbmcgdG8gcHJvY2Vzc1xuXG4gICAgY2FjaGUgPSBjYWNoZSB8fCB0aGlzLmFwb2xsby5jbGllbnQuY2FjaGU7XG4gICAgb3B0cy5hcnJheUZpZWxkTmFtZSA9IG9wdHMuYXJyYXlGaWVsZE5hbWUgfHwgJ2RhdGEnO1xuXG4gICAgdHJ5IHtcbiAgICAgIGxldCBkYXRhID0gY2FjaGUucmVhZFF1ZXJ5PGFueSwgVj4oe3F1ZXJ5OiBvcHRzLnF1ZXJ5LCB2YXJpYWJsZXM6IG9wdHMudmFyaWFibGVzfSk7XG4gICAgICBpZiAoIWRhdGEpIHJldHVybiAwOyAvLyBza2lwXG5cbiAgICAgIGlmIChkYXRhW29wdHMuYXJyYXlGaWVsZE5hbWVdKSB7XG4gICAgICAgIC8vIENvcHkgYmVjYXVzZSBpbW11dGFibGVcbiAgICAgICAgZGF0YSA9IHsgLi4uZGF0YSB9O1xuXG4gICAgICAgIC8vIEtlZXAgb25seSBub3QgZXhpc3RpbmcgcmVzXG4gICAgICAgIGNvbnN0IGVxdWFsc0ZuID0gb3B0cy5lcXVhbHNGbiB8fCAoKGQxLCBkMikgPT4gZDFbJ2lkJ10gPT09IGQyWydpZCddICYmIGQxWydlbnRpdHlOYW1lJ10gPT09IGQyWydlbnRpdHlOYW1lJ10pO1xuICAgICAgICBjb25zdCBuZXdJdGVtcyA9IG9wdHMuZGF0YS5maWx0ZXIoaW5wdXRWYWx1ZSA9PiBkYXRhW29wdHMuYXJyYXlGaWVsZE5hbWVdLmZpbmRJbmRleChleGlzdGluZ1ZhbHVlID0+IGVxdWFsc0ZuKGlucHV0VmFsdWUsIGV4aXN0aW5nVmFsdWUpKSA9PT0gLTEpO1xuXG4gICAgICAgIGlmICghbmV3SXRlbXMubGVuZ3RoKSByZXR1cm47IC8vIE5vIG5ldyB2YWx1ZVxuXG4gICAgICAgIC8vIEFwcGVuZCB0byBhcnJheVxuICAgICAgICBkYXRhW29wdHMuYXJyYXlGaWVsZE5hbWVdID0gWyAuLi5kYXRhW29wdHMuYXJyYXlGaWVsZE5hbWVdLCAuLi5uZXdJdGVtc107XG5cbiAgICAgICAgLy8gUmVzb3J0LCBpZiBuZWVkXG4gICAgICAgIGlmIChvcHRzLnNvcnRGbikge1xuICAgICAgICAgIGRhdGFbb3B0cy5hcnJheUZpZWxkTmFtZV0uc29ydChvcHRzLnNvcnRGbik7XG4gICAgICAgIH1cblxuICAgICAgICAvLyBFeGNsdWRlIGlmIGV4Y2VlZCBtYXggc2l6ZVxuICAgICAgICBjb25zdCBzaXplID0gdG9OdW1iZXIob3B0cy52YXJpYWJsZXMgJiYgb3B0cy52YXJpYWJsZXNbJ3NpemUnXSwgLTEpO1xuICAgICAgICBpZiAoc2l6ZSA+IDAgJiYgZGF0YVtvcHRzLmFycmF5RmllbGROYW1lXS5sZW5ndGggPiBzaXplKSB7XG4gICAgICAgICAgZGF0YVtvcHRzLmFycmF5RmllbGROYW1lXS5zcGxpY2Uoc2l6ZSwgZGF0YVtvcHRzLmFycmF5RmllbGROYW1lXS5sZW5ndGggLSBzaXplKTtcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIEluY3JlbWVudCB0aGUgdG90YWxcbiAgICAgICAgaWYgKGlzTm90TmlsKG9wdHMudG90YWxGaWVsZE5hbWUpKSB7XG4gICAgICAgICAgaWYgKGlzTm90TmlsKGRhdGFbb3B0cy50b3RhbEZpZWxkTmFtZV0pKSB7XG4gICAgICAgICAgICBkYXRhW29wdHMuYXJyYXlGaWVsZE5hbWVdICs9IG5ld0l0ZW1zLmxlbmd0aDtcbiAgICAgICAgICB9XG4gICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICBjb25zb2xlLndhcm4oJ1tncmFwaHFsXSBVbmFibGUgdG8gdXBkYXRlIGNhY2hlZCBxdWVyeS4gVW5rbm93biByZXN1bHQgcGFydDogJyArIG9wdHMudG90YWxGaWVsZE5hbWUpO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIC8vIFdyaXRlIHRvIGNhY2hlXG4gICAgICAgIGNhY2hlLndyaXRlUXVlcnkoe1xuICAgICAgICAgIHF1ZXJ5OiBvcHRzLnF1ZXJ5LFxuICAgICAgICAgIHZhcmlhYmxlczogb3B0cy52YXJpYWJsZXMsXG4gICAgICAgICAgZGF0YVxuICAgICAgICB9KTtcbiAgICAgIH1cbiAgICAgIGVsc2Uge1xuICAgICAgICBjb25zb2xlLndhcm4oJ1tncmFwaHFsXSBVbmFibGUgdG8gdXBkYXRlIGNhY2hlZCBxdWVyeS4gVW5rbm93biByZXN1bHQgcGFydDogJyArIG9wdHMuYXJyYXlGaWVsZE5hbWUpO1xuICAgICAgfVxuICAgIH0gY2F0Y2ggKGVycikge1xuICAgICAgLy8gY29udGludWVcbiAgICAgIC8vIHJlYWQgaW4gY2FjaGUgaXMgbm90IGd1YXJhbnRlZWQgdG8gcmV0dXJuIGEgcmVzdWx0LiBzZWUgaHR0cHM6Ly9naXRodWIuY29tL2Fwb2xsb2dyYXBocWwvcmVhY3QtYXBvbGxvL2lzc3Vlcy8xNzc2I2lzc3VlY29tbWVudC0zNzIyMzc5NDBcbiAgICAgIGlmICh0aGlzLl9kZWJ1ZykgY29uc29sZS53YXJuKCdbZ3JhcGhxbF0gRXJyb3Igd2hpbGUgdXBkYXRpbmcgY2FjaGU6ICcsIGVycik7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIFJlbW92ZSBmcm9tIGNhY2hlLCBhbmQgcmV0dXJuIGlmIHJlbW92ZWQgb3Igbm90XG4gICAqXG4gICAqIEBwYXJhbSBjYWNoZVxuICAgKiBAcGFyYW0gb3B0c1xuICAgKi9cbiAgcmVtb3ZlRnJvbUNhY2hlZFF1ZXJ5QnlJZDxWID0gRW1wdHlPYmplY3QsIElEID0gbnVtYmVyPihjYWNoZTogQXBvbGxvQ2FjaGU8YW55PixcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBvcHRzOiBDYWNoZS5SZWFkUXVlcnlPcHRpb25zPFYsIGFueT4gJiB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhcnJheUZpZWxkTmFtZTogc3RyaW5nO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdG90YWxGaWVsZE5hbWU/OiBzdHJpbmc7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZHM6IElEOyAvLyBEbyBOT1QgdXNlICdpZCcsIGFzIGFscmVhZHkgdXNlZCBieSB0aGUgQXBvbGxvIEFQSVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0pOiBib29sZWFuIHtcblxuICAgIGNhY2hlID0gY2FjaGUgfHwgdGhpcy5hcG9sbG8uY2xpZW50LmNhY2hlO1xuICAgIG9wdHMuYXJyYXlGaWVsZE5hbWUgPSBvcHRzLmFycmF5RmllbGROYW1lIHx8ICdkYXRhJztcblxuICAgIHRyeSB7XG4gICAgICBsZXQgZGF0YSA9IGNhY2hlLnJlYWRRdWVyeTxhbnksIFY+KHtxdWVyeTogb3B0cy5xdWVyeSwgdmFyaWFibGVzOiBvcHRzLnZhcmlhYmxlc30pO1xuXG4gICAgICBpZiAoZGF0YSAmJiBkYXRhW29wdHMuYXJyYXlGaWVsZE5hbWVdKSB7XG4gICAgICAgIC8vIENvcHkgYmVjYXVzZSBpbW11dGFibGVcbiAgICAgICAgZGF0YSA9IHsgLi4uZGF0YSB9O1xuXG4gICAgICAgIGNvbnN0IGluZGV4ID0gZGF0YVtvcHRzLmFycmF5RmllbGROYW1lXS5maW5kSW5kZXgoaXRlbSA9PiBpdGVtWydpZCddID09PSBvcHRzLmlkcyk7XG4gICAgICAgIGlmIChpbmRleCA9PT0gLTEpIHJldHVybiBmYWxzZTsgLy8gU2tpcCAobm90aGluZyByZW1vdmVkKVxuXG4gICAgICAgIC8vIENvcHksIHRoZW4gcmVtb3ZlIGRlbGV0ZWQgaXRlbVxuICAgICAgICBkYXRhW29wdHMuYXJyYXlGaWVsZE5hbWVdID0gZGF0YVtvcHRzLmFycmF5RmllbGROYW1lXS5zbGljZSgpO1xuICAgICAgICBjb25zdCBkZWxldGVkSXRlbSA9IGRhdGFbb3B0cy5hcnJheUZpZWxkTmFtZV0uc3BsaWNlKGluZGV4LCAxKVswXTtcbiAgICAgICAgY2FjaGUuZXZpY3Qoe2lkOiBjYWNoZS5pZGVudGlmeShkZWxldGVkSXRlbSl9KTtcblxuICAgICAgICAvLyBEZWNyZW1lbnQgdGhlIHRvdGFsXG4gICAgICAgIGlmIChpc05vdE5pbChvcHRzLnRvdGFsRmllbGROYW1lKSkge1xuICAgICAgICAgIGlmIChpc05vdE5pbChkYXRhW29wdHMudG90YWxGaWVsZE5hbWVdKSkge1xuICAgICAgICAgICAgZGF0YVtvcHRzLnRvdGFsRmllbGROYW1lXSAtPSAxO1xuICAgICAgICAgIH1cbiAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIGNvbnNvbGUud2FybignW2dyYXBocWxdIFVuYWJsZSB0byB1cGRhdGUgY2FjaGVkIHF1ZXJ5LiBVbmtub3duIHJlc3VsdCBwYXJ0OiAnICsgb3B0cy50b3RhbEZpZWxkTmFtZSk7XG4gICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgLy8gV3JpdGUgdG8gY2FjaGVcbiAgICAgICAgY2FjaGUud3JpdGVRdWVyeSh7XG4gICAgICAgICAgcXVlcnk6IG9wdHMucXVlcnksXG4gICAgICAgICAgdmFyaWFibGVzOiBvcHRzLnZhcmlhYmxlcyxcbiAgICAgICAgICBkYXRhXG4gICAgICAgIH0pO1xuICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgIH1cbiAgICAgIGVsc2Uge1xuICAgICAgICBjb25zb2xlLndhcm4oJ1tncmFwaHFsXSBVbmFibGUgdG8gdXBkYXRlIGNhY2hlZCBxdWVyeS4gVW5rbm93biByZXN1bHQgcGFydDogJyArIG9wdHMuYXJyYXlGaWVsZE5hbWUpO1xuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICB9XG4gICAgfSBjYXRjaCAoZXJyKSB7XG4gICAgICAvLyBjb250aW51ZVxuICAgICAgLy8gcmVhZCBpbiBjYWNoZSBpcyBub3QgZ3VhcmFudGVlZCB0byByZXR1cm4gYSByZXN1bHQuIHNlZSBodHRwczovL2dpdGh1Yi5jb20vYXBvbGxvZ3JhcGhxbC9yZWFjdC1hcG9sbG8vaXNzdWVzLzE3NzYjaXNzdWVjb21tZW50LTM3MjIzNzk0MFxuICAgICAgaWYgKHRoaXMuX2RlYnVnKSBjb25zb2xlLndhcm4oJ1tncmFwaHFsXSBFcnJvciB3aGlsZSByZW1vdmluZyBmcm9tIGNhY2hlOiAnLCBlcnIpO1xuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBSZW1vdmUgaWRzIGZyb20gY2FjaGUsIGFuZCByZXR1cm4gdGhlIG51bWJlciBvZiBpdGVtcyByZW1vdmVkXG4gICAqXG4gICAqIEBwYXJhbSBjYWNoZVxuICAgKiBAcGFyYW0gb3B0c1xuICAgKi9cbiAgcmVtb3ZlRnJvbUNhY2hlZFF1ZXJ5QnlJZHM8ViA9IEVtcHR5T2JqZWN0LCBJRCA9IG51bWJlcj4oY2FjaGU6IEFwb2xsb0NhY2hlPGFueT4sXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG9wdHM6IENhY2hlLlJlYWRRdWVyeU9wdGlvbnM8ViwgYW55PiAmIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhcnJheUZpZWxkTmFtZTogc3RyaW5nO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRvdGFsRmllbGROYW1lPzogc3RyaW5nO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlkczogSURbXTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfSk6IG51bWJlciB7XG5cbiAgICBjYWNoZSA9IGNhY2hlIHx8IHRoaXMuYXBvbGxvLmNsaWVudC5jYWNoZTtcbiAgICBvcHRzLmFycmF5RmllbGROYW1lID0gb3B0cy5hcnJheUZpZWxkTmFtZSB8fCAnZGF0YSc7XG5cbiAgICB0cnkge1xuICAgICAgbGV0IGRhdGEgPSBjYWNoZS5yZWFkUXVlcnkob3B0cyk7XG5cbiAgICAgIGlmIChkYXRhICYmIGRhdGFbb3B0cy5hcnJheUZpZWxkTmFtZV0pIHtcbiAgICAgICAgLy8gQ29weSBiZWNhdXNlIGltbXV0YWJsZVxuICAgICAgICBkYXRhID0geyAuLi5kYXRhIH07XG5cbiAgICAgICAgY29uc3QgZGVsZXRlZEluZGV4ZXMgPSBkYXRhW29wdHMuYXJyYXlGaWVsZE5hbWVdLnJlZHVjZSgocmVzLCBpdGVtLCBpbmRleCkgPT4gb3B0cy5pZHMuaW5jbHVkZXMoaXRlbVsnaWQnXSkgPyByZXMuY29uY2F0KGluZGV4KSA6IHJlcywgW10pO1xuXG4gICAgICAgIGlmIChkZWxldGVkSW5kZXhlcy5sZW5ndGggPD0gMCkgcmV0dXJuIDA7IC8vIFNraXAgKG5vdGhpbmcgcmVtb3ZlZClcblxuICAgICAgICAvLyBRdWVyeSBoYXMgTk8gdG90YWxcbiAgICAgICAgaWYgKGlzTmlsKG9wdHMudG90YWxGaWVsZE5hbWUpKSB7XG5cbiAgICAgICAgICAvLyBFdmljdCBlYWNoIG9iamVjdFxuICAgICAgICAgIGRlbGV0ZWRJbmRleGVzXG4gICAgICAgICAgICAubWFwKGluZGV4ID0+IGRhdGFbb3B0cy5hcnJheUZpZWxkTmFtZV1baW5kZXhdKVxuICAgICAgICAgICAgLm1hcChpdGVtID0+IGNhY2hlLmlkZW50aWZ5KGl0ZW0pKVxuICAgICAgICAgICAgLmZvckVhY2goaWQgPT4gY2FjaGUuZXZpY3Qoe2lkfSkpO1xuXG4gICAgICAgIH1cbiAgICAgICAgLy8gUXVlcnkgaGFzIGEgdG90YWxcbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgLy8gQ29weSB0aGUgYXJyYXlcbiAgICAgICAgICBkYXRhW29wdHMuYXJyYXlGaWVsZE5hbWVdID0gZGF0YVtvcHRzLmFycmF5RmllbGROYW1lXS5zbGljZSgpO1xuXG4gICAgICAgICAgLy8gcmVtb3ZlIGZyb20gYXJyYXksIHRoZW4gZXZpY3RcbiAgICAgICAgICBkZWxldGVkSW5kZXhlc1xuICAgICAgICAgICAgLy8gUmV2ZXJzZTogdG8ga2VlcCB2YWxpZCBpbmRleFxuICAgICAgICAgICAgLnJldmVyc2UoKVxuICAgICAgICAgICAgLy8gUmVtb3ZlIGZyb20gdGhlIGFycmF5XG4gICAgICAgICAgICAubWFwKGluZGV4ID0+IGRhdGFbb3B0cy5hcnJheUZpZWxkTmFtZV0uc3BsaWNlKGluZGV4LCAxKVswXSlcbiAgICAgICAgICAgIC8vIEV2aWN0IGZyb20gY2FjaGVcbiAgICAgICAgICAgIC5tYXAoaXRlbSA9PiBjYWNoZS5pZGVudGlmeShpdGVtKSlcbiAgICAgICAgICAgIC5mb3JFYWNoKGlkID0+IGNhY2hlLmV2aWN0KHtpZH0pKTtcblxuICAgICAgICAgIGlmIChpc05vdE5pbChkYXRhW29wdHMudG90YWxGaWVsZE5hbWVdKSkge1xuICAgICAgICAgICAgZGF0YVtvcHRzLnRvdGFsRmllbGROYW1lXSAtPSBkZWxldGVkSW5kZXhlcy5sZW5ndGg7IC8vIFJlbW92ZSBkZWxldGlvbiBjb3VudFxuICAgICAgICAgIH1cbiAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIGNvbnNvbGUud2FybignW2dyYXBocWxdIFVuYWJsZSB0byB1cGRhdGUgdGhlIHRvdGFsIGluIGNhY2hlZCBxdWVyeS4gVW5rbm93biByZXN1bHQgcGFydDogJyArIG9wdHMudG90YWxGaWVsZE5hbWUpO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIGNhY2hlLndyaXRlUXVlcnkoe1xuICAgICAgICAgICAgcXVlcnk6IG9wdHMucXVlcnksXG4gICAgICAgICAgICB2YXJpYWJsZXM6IG9wdHMudmFyaWFibGVzLFxuICAgICAgICAgICAgZGF0YVxuICAgICAgICAgIH0pO1xuXG4gICAgICAgICAgcmV0dXJuIGRlbGV0ZWRJbmRleGVzLmxlbmd0aDtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgZWxzZSB7XG4gICAgICAgIGNvbnNvbGUud2FybignW2dyYXBocWxdIFVuYWJsZSB0byB1cGRhdGUgY2FjaGVkIHF1ZXJ5LiBVbmtub3duIHJlc3VsdCBwYXJ0OiAnICsgb3B0cy5hcnJheUZpZWxkTmFtZSk7XG4gICAgICAgIHJldHVybiAwO1xuICAgICAgfVxuICAgIH0gY2F0Y2ggKGVycikge1xuICAgICAgLy8gY29udGludWVcbiAgICAgIC8vIHJlYWQgaW4gY2FjaGUgaXMgbm90IGd1YXJhbnRlZWQgdG8gcmV0dXJuIGEgcmVzdWx0LiBzZWUgaHR0cHM6Ly9naXRodWIuY29tL2Fwb2xsb2dyYXBocWwvcmVhY3QtYXBvbGxvL2lzc3Vlcy8xNzc2I2lzc3VlY29tbWVudC0zNzIyMzc5NDBcbiAgICAgIGlmICh0aGlzLl9kZWJ1ZykgY29uc29sZS53YXJuKCdbZ3JhcGhxbF0gRXJyb3Igd2hpbGUgcmVtb3ZpbmcgZnJvbSBjYWNoZTogJywgZXJyKTtcbiAgICAgIHJldHVybiAwO1xuICAgIH1cbiAgfVxuXG4gIHVwZGF0ZVRvUXVlcnlDYWNoZTxUIGV4dGVuZHMgSUVudGl0eTxhbnk+LFxuICAgIFYgPSBFbXB0eU9iamVjdD4oY2FjaGU6IEFwb2xsb0NhY2hlPGFueT4sXG4gICAgICAgICAgICAgICAgICAgICBvcHRzOiBDYWNoZS5SZWFkUXVlcnlPcHRpb25zPFYsIGFueT4gJiB7XG4gICAgICAgICAgICAgICAgICAgICAgIGFycmF5RmllbGROYW1lOiBzdHJpbmc7XG4gICAgICAgICAgICAgICAgICAgICAgIHRvdGFsRmllbGROYW1lPzogc3RyaW5nO1xuICAgICAgICAgICAgICAgICAgICAgICBkYXRhOiBUO1xuICAgICAgICAgICAgICAgICAgICAgICBlcXVhbHNGbj86IChkMTogVCwgZDI6IFQpID0+IGJvb2xlYW47XG4gICAgICAgICAgICAgICAgICAgICB9KSB7XG4gICAgY2FjaGUgPSBjYWNoZSB8fCB0aGlzLmFwb2xsby5jbGllbnQuY2FjaGU7XG4gICAgb3B0cy5hcnJheUZpZWxkTmFtZSA9IG9wdHMuYXJyYXlGaWVsZE5hbWUgfHwgJ2RhdGEnO1xuXG4gICAgdHJ5IHtcbiAgICAgIGxldCBkYXRhOiBhbnkgPSBjYWNoZS5yZWFkUXVlcnkob3B0cyk7XG5cbiAgICAgIGlmIChkYXRhICYmIGRhdGFbb3B0cy5hcnJheUZpZWxkTmFtZV0pIHtcbiAgICAgICAgLy8gQ29weSBiZWNhdXNlIGltbXV0YWJsZVxuICAgICAgICBkYXRhID0geyAuLi5kYXRhIH07XG5cbiAgICAgICAgY29uc3QgZXF1YWxzRm4gPSBvcHRzLmVxdWFsc0ZuIHx8ICgoZDEsIGQyKSA9PiBFbnRpdHlVdGlscy5lcXVhbHMoZDEsIGQyLCAnaWQnKSk7XG5cbiAgICAgICAgLy8gVXBkYXRlIGlmIGV4aXN0cywgb3IgaW5zZXJ0XG4gICAgICAgIGNvbnN0IGluZGV4ID0gZGF0YVtvcHRzLmFycmF5RmllbGROYW1lXS5maW5kSW5kZXgodiA9PiBlcXVhbHNGbihvcHRzLmRhdGEsIHYpKTtcbiAgICAgICAgaWYgKGluZGV4ICE9PSAtMSkge1xuICAgICAgICAgIGRhdGFbb3B0cy5hcnJheUZpZWxkTmFtZV0gPSBkYXRhW29wdHMuYXJyYXlGaWVsZE5hbWVdLnNsaWNlKCkuc3BsaWNlKGluZGV4LCAxLCBvcHRzLmRhdGEpO1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgIGRhdGFbb3B0cy5hcnJheUZpZWxkTmFtZV0gPSBbIC4uLmRhdGFbb3B0cy5hcnJheUZpZWxkTmFtZV0sIG9wdHMuZGF0YV07XG4gICAgICAgIH1cblxuICAgICAgICAvLyBJbmNyZW1lbnQgdG90YWwgKGlmIGNoYW5nZWQpXG4gICAgICAgIGlmIChpc05vdE5pbChvcHRzLnRvdGFsRmllbGROYW1lKSAmJiBpbmRleCA9PT0gLTEpIHtcbiAgICAgICAgICBpZiAoaXNOb3ROaWwoZGF0YVtvcHRzLnRvdGFsRmllbGROYW1lXSkpIHtcbiAgICAgICAgICAgIGRhdGFbb3B0cy50b3RhbEZpZWxkTmFtZV0gKz0gMTtcbiAgICAgICAgICB9XG4gICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICBjb25zb2xlLndhcm4oJ1tncmFwaHFsXSBVbmFibGUgdG8gdXBkYXRlIGNhY2hlZCBxdWVyeS4gVW5rbm93biByZXN1bHQgcGFydDogJyArIG9wdHMudG90YWxGaWVsZE5hbWUpO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIGNhY2hlLndyaXRlUXVlcnkoe1xuICAgICAgICAgIHF1ZXJ5OiBvcHRzLnF1ZXJ5LFxuICAgICAgICAgIHZhcmlhYmxlczogb3B0cy52YXJpYWJsZXMsXG4gICAgICAgICAgZGF0YVxuICAgICAgICB9KTtcbiAgICAgICAgcmV0dXJuOyAvLyBPSzogc3RvcCBoZXJlXG4gICAgICB9XG4gICAgfSBjYXRjaCAoZXJyKSB7XG4gICAgICAvLyBjb250aW51ZVxuICAgICAgLy8gcmVhZCBpbiBjYWNoZSBpcyBub3QgZ3VhcmFudGVlZCB0byByZXR1cm4gYSByZXN1bHQuIHNlZSBodHRwczovL2dpdGh1Yi5jb20vYXBvbGxvZ3JhcGhxbC9yZWFjdC1hcG9sbG8vaXNzdWVzLzE3NzYjaXNzdWVjb21tZW50LTM3MjIzNzk0MFxuICAgICAgaWYgKHRoaXMuX2RlYnVnKSBjb25zb2xlLndhcm4oJ1tncmFwaHFsXSBFcnJvciB3aGlsZSB1cGRhdGluZyBjYWNoZTogJywgZXJyKTtcbiAgICB9XG4gIH1cblxuICBhc3luYyBjbGVhckNhY2hlKGNsaWVudD86IEFwb2xsb0NsaWVudDxhbnk+KTogUHJvbWlzZTx2b2lkPiB7XG4gICAgY2xpZW50ID0gKGNsaWVudCB8fCB0aGlzLmNsaWVudCkgYXMgQXBvbGxvQ2xpZW50PGFueT47XG4gICAgaWYgKGNsaWVudCkge1xuICAgICAgY29uc29sZS5pbmZvKCdbZ3JhcGhxbF0gQ2xlYW5pbmcgY2FjaGUuLi4gJyk7XG4gICAgICBjb25zdCBub3cgPSB0aGlzLl9kZWJ1ZyAmJiBEYXRlLm5vdygpO1xuXG4gICAgICAvLyBDbGVhcmluZyB0aGUgY2FjaGVcbiAgICAgIGF3YWl0IGNsaWVudC5jYWNoZS5yZXNldCgpO1xuXG4gICAgICBpZiAodGhpcy5fZGVidWcpIGNvbnNvbGUuZGVidWcoYFtncmFwaHFsXSBDbGVhbmluZyBjYWNoZSBbT0tdIGluICR7RGF0ZS5ub3coKSAtIG5vd31tc2ApO1xuICAgIH1cbiAgfVxuXG4gIHJlZ2lzdGVyQ3VzdG9tRXJyb3IoZXJyb3I6IFByb3BlcnRpZXNNYXApIHtcbiAgICB0aGlzLmN1c3RvbUVycm9ycyA9IHsuLi50aGlzLmN1c3RvbUVycm9ycywgLi4uZXJyb3J9O1xuICB9XG5cbiAgLyogLS0gcHJvdGVjdGVkIG1ldGhvZHMgLS0gKi9cblxuICBwcm90ZWN0ZWQgYXN5bmMgbmdPblN0YXJ0KCk6IFByb21pc2U8QXBvbGxvQ2xpZW50PGFueT4+IHtcblxuICAgIC8vIFdhaXQgbmV0d29yayBhbmQgc3RvcmFnZVxuICAgIGF3YWl0IFByb21pc2UuYWxsKFtcbiAgICAgIHRoaXMuc3RvcmFnZS5yZWFkeSgpLFxuICAgICAgdGhpcy5uZXR3b3JrLnJlYWR5KClcbiAgICBdKTtcblxuICAgIGNvbnNvbGUuaW5mbygnW2dyYXBocWxdIFN0YXJ0aW5nIGdyYXBocWwuLi4nKTtcbiAgICBjb25zdCBtb2JpbGUgPSBpc01vYmlsZSh3aW5kb3cpO1xuICAgIGNvbnN0IGVuYWJsZVRyYWNrTXV0YXRpb25RdWVyaWVzID0gIW1vYmlsZTtcblxuICAgIGNvbnN0IHBlZXIgPSB0aGlzLm5ldHdvcmsucGVlcjtcbiAgICBpZiAoIXBlZXIpIHRocm93IEVycm9yKCdbZ3JhcGhxbF0gTWlzc2luZyBwZWVyLiBVbmFibGUgdG8gc3RhcnQgZ3JhcGhxbCBzZXJ2aWNlJyk7XG5cbiAgICBjb25zdCB1cmkgPSBwZWVyLnVybCArICcvZ3JhcGhxbCc7XG4gICAgY29uc3Qgd3NVcmwgPSB1cmkucmVwbGFjZSgvXmh0dHAocyk/Oi8sICd3cyQxOicpICsgJy93ZWJzb2NrZXQnO1xuICAgIGNvbnNvbGUuaW5mbygnW2dyYXBocWxdIEJhc2UgdXJpOiAnICsgdXJpKTtcbiAgICBjb25zb2xlLmluZm8oJ1tncmFwaHFsXSBTdWJzY3JpcHRpb24gdXJpOiAnICsgd3NVcmwpO1xuXG4gICAgdGhpcy5odHRwUGFyYW1zID0gdGhpcy5odHRwUGFyYW1zIHx8IHt9O1xuICAgIHRoaXMuaHR0cFBhcmFtcy51cmkgPSB1cmk7XG5cbiAgICB0aGlzLndzUGFyYW1zID0ge1xuICAgICAgLi4udGhpcy53c1BhcmFtcyxcbiAgICAgIGxhenk6IHRydWUsXG4gICAgICBjb25uZWN0aW9uUGFyYW1zOiB0aGlzLmNvbm5lY3Rpb25QYXJhbXMsXG4gICAgICB3ZWJTb2NrZXRJbXBsOiBBcHBXZWJTb2NrZXQsXG4gICAgICB1cmw6IHdzVXJsLFxuICAgICAgc2hvdWxkUmV0cnk6IChlcnJPckNsb3NlRXZlbnQpID0+IHtcbiAgICAgICAgLy8gSWYgV1MgVVJMIGNoYW5nZWQsIHRoZW4gZG8gbm90IHJldHJ5XG4gICAgICAgIGlmICh3c1VybCAhPT0gdGhpcy53c1BhcmFtcy51cmwpIHtcbiAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgIH1cbiAgICAgICAgY29uc29sZS53YXJuKCdbZ3JhcGhxbC1zZXJ2aWNlXSBbV1NdIFRyeWluZyB0byByZWNvbm5lY3QuLi4nLCBlcnJPckNsb3NlRXZlbnQpO1xuICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgIH0sXG4gICAgICByZXRyeUF0dGVtcHRzOiAxMFxuICAgIH07XG5cbiAgICAvLyBDcmVhdGUgYSBzdG9yYWdlIGNvbmZpZ3VyYXRpb25cbiAgICBjb25zdCBzdG9yYWdlOiBQZXJzaXN0ZW50U3RvcmFnZTxzdHJpbmc+ID0gbmV3IFN0b3JhZ2VTZXJ2aWNlV3JhcHBlcih0aGlzLnN0b3JhZ2UpO1xuXG4gICAgbGV0IGNsaWVudCA9IHRoaXMuYXBvbGxvLmNsaWVudDtcbiAgICBpZiAoIWNsaWVudCkge1xuICAgICAgY29uc29sZS5kZWJ1ZygnW2dyYXBocWxdIENyZWF0aW5nIEFwb2xsbyBHcmFwaFFMIGNsaWVudC4uLicpO1xuXG4gICAgICAvLyBXZWJzb2NrZXQgbGlua1xuICAgICAgY29uc3Qgd3NMaW5rID0gbmV3IEdyYXBoUUxXc0xpbmsoY3JlYXRlQ2xpZW50KHRoaXMud3NQYXJhbXMpKTtcbiAgICAgIHRoaXMub25SZXNldEF1dGhcbiAgICAgICAgLnBpcGUodGFrZVVudGlsKHRoaXMuc3RvcFN1YmplY3QpKVxuICAgICAgICAuc3Vic2NyaWJlKCgpID0+IHtcbiAgICAgICAgICBjb25zb2xlLmluZm8oJ1tncmFwaHFsXSBDbG9zaW5nIHdlYnNvY2tldCBjbGllbnQsIHRvIGZvcmNlIHVuYXV0aCcpO1xuICAgICAgICAgIHdzTGluay5jbGllbnQuZGlzcG9zZSgpO1xuICAgICAgICB9KTtcblxuICAgICAgLy8gUmV0cnkgd2hlbiBmYWlsZWQgbGlua1xuICAgICAgY29uc3QgcmV0cnlMaW5rID0gbmV3IFJldHJ5TGluaygpO1xuICAgICAgY29uc3QgYXV0aExpbmsgPSBuZXcgQXBvbGxvTGluaygob3BlcmF0aW9uLCBmb3J3YXJkKSA9PiB7XG5cbiAgICAgICAgY29uc3QgYXV0aG9yaXphdGlvbiA9IFtdO1xuICAgICAgICBpZiAodGhpcy5jb25uZWN0aW9uUGFyYW1zLmF1dGhUb2tlbikge1xuICAgICAgICAgIGF1dGhvcml6YXRpb24ucHVzaChgdG9rZW4gJHt0aGlzLmNvbm5lY3Rpb25QYXJhbXMuYXV0aFRva2VufWApO1xuICAgICAgICB9XG4gICAgICAgIGlmICh0aGlzLmNvbm5lY3Rpb25QYXJhbXMuYXV0aEJhc2ljKSB7XG4gICAgICAgICAgYXV0aG9yaXphdGlvbi5wdXNoKGBCYXNpYyAke3RoaXMuY29ubmVjdGlvblBhcmFtcy5hdXRoQmFzaWN9YCk7XG4gICAgICAgIH1cbiAgICAgICAgY29uc3QgaGVhZGVycyA9IG5ldyBIdHRwSGVhZGVycygpXG4gICAgICAgICAgLmFwcGVuZCgnQXV0aG9yaXphdGlvbicsIGF1dGhvcml6YXRpb24pO1xuXG4gICAgICAgIC8vIFVzZSB0aGUgc2V0Q29udGV4dCBtZXRob2QgdG8gc2V0IHRoZSBIVFRQIGhlYWRlcnMuXG4gICAgICAgIG9wZXJhdGlvbi5zZXRDb250ZXh0KHtcbiAgICAgICAgICAuLi5vcGVyYXRpb24uZ2V0Q29udGV4dCgpLFxuICAgICAgICAgIC4uLntoZWFkZXJzfVxuICAgICAgICB9KTtcblxuICAgICAgICAvLyBDYWxsIHRoZSBuZXh0IGxpbmsgaW4gdGhlIG1pZGRsZXdhcmUgY2hhaW4uXG4gICAgICAgIHJldHVybiBmb3J3YXJkKG9wZXJhdGlvbik7XG4gICAgICB9KTtcblxuICAgICAgLy8gSHR0cCBsaW5rXG4gICAgICBjb25zdCBodHRwTGluayA9IHRoaXMuaHR0cExpbmsuY3JlYXRlKHRoaXMuaHR0cFBhcmFtcyk7XG5cbiAgICAgIC8vIENhY2hlXG4gICAgICBjb25zdCBjYWNoZSA9IG5ldyBJbk1lbW9yeUNhY2hlKHtcbiAgICAgICAgdHlwZVBvbGljaWVzOiB0aGlzLnR5cGVQb2xpY2llcyxcbiAgICAgICAgZnJhZ21lbnRzOiBpc05vdEVtcHR5QXJyYXkodGhpcy5mcmFnbWVudHMpID8gY3JlYXRlRnJhZ21lbnRSZWdpc3RyeSguLi50aGlzLmZyYWdtZW50cykgOiB1bmRlZmluZWRcbiAgICAgIH0pO1xuXG4gICAgICAvLyBBZGQgY2FjaGUgcGVyc2lzdGVuY2VcbiAgICAgIGlmICh0aGlzLmVudmlyb25tZW50LnBlcnNpc3RDYWNoZSkge1xuICAgICAgICBjb25zb2xlLmRlYnVnKCdbZ3JhcGhxbF0gU3RhcnRpbmcgcGVyc2lzdGVuY2UgY2FjaGUuLi4nKTtcbiAgICAgICAgYXdhaXQgcGVyc2lzdENhY2hlKHtcbiAgICAgICAgICBjYWNoZSxcbiAgICAgICAgICBzdG9yYWdlLFxuICAgICAgICAgIHRyaWdnZXI6IHRoaXMucGxhdGZvcm0uaXMoJ2FuZHJvaWQnKSA/ICdiYWNrZ3JvdW5kJyA6ICd3cml0ZScsXG4gICAgICAgICAgZGVib3VuY2U6IDEwMDAsXG4gICAgICAgICAgZGVidWc6IHRydWVcbiAgICAgICAgfSk7XG4gICAgICB9XG5cbiAgICAgIGxldCBtdXRhdGlvbkxpbmtzOiBBcnJheTxBcG9sbG9MaW5rPjtcblxuICAgICAgLy8gQWRkIHF1ZXVlIHRvIHN0b3JlIHRyYWNrZWQgcXVlcmllcywgd2hlbiBvZmZsaW5lXG4gICAgICBpZiAoZW5hYmxlVHJhY2tNdXRhdGlvblF1ZXJpZXMpIHtcbiAgICAgICAgY29uc3Qgc2VyaWFsaXppbmdMaW5rID0gbmV3IFNlcmlhbGl6aW5nTGluaygpO1xuICAgICAgICBjb25zdCB0cmFja2VyTGluayA9IGNyZWF0ZVRyYWNrZXJMaW5rKHtcbiAgICAgICAgICBzdG9yYWdlLFxuICAgICAgICAgIG9uTmV0d29ya1N0YXR1c0NoYW5nZTogdGhpcy5fbmV0d29ya1N0YXR1c0NoYW5nZWQkLFxuICAgICAgICAgIGRlYm91bmNlOiAxMDAwLFxuICAgICAgICAgIGRlYnVnOiB0cnVlXG4gICAgICAgIH0pO1xuICAgICAgICAvLyBDcmVhdGluZyBhIG11dGF0aW9uIHF1ZXVlXG4gICAgICAgIGNvbnN0IHF1ZXVlTGluayA9IG5ldyBRdWV1ZUxpbmsoKTtcbiAgICAgICAgdGhpcy5yZWdpc3RlclN1YnNjcmlwdGlvbih0aGlzLl9uZXR3b3JrU3RhdHVzQ2hhbmdlZCRcbiAgICAgICAgICAuc3Vic2NyaWJlKHR5cGUgPT4ge1xuICAgICAgICAgICAgLy8gTmV0d29yayBpcyBvZmZsaW5lOiBzdGFydCBidWZmZXJpbmcgaW50byBxdWV1ZVxuICAgICAgICAgICAgaWYgKHR5cGUgPT09ICdub25lJykge1xuICAgICAgICAgICAgICBjb25zb2xlLmluZm8oJ1tncmFwaHFsXSBvZmZsaW5lIG1vZGU6IGVuYWJsZSBtdXRhdGlvbnMgYnVmZmVyJyk7XG4gICAgICAgICAgICAgIHF1ZXVlTGluay5jbG9zZSgpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgLy8gTmV0d29yayBpcyBvbmxpbmVcbiAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICBjb25zb2xlLmluZm8oJ1tncmFwaHFsXSBvbmxpbmUgbW9kZTogZGlzYWJsZSBtdXRhdGlvbnMgYnVmZmVyJyk7XG4gICAgICAgICAgICAgIHF1ZXVlTGluay5vcGVuKCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfSkpO1xuICAgICAgICBtdXRhdGlvbkxpbmtzID0gW1xuICAgICAgICAgIGxvZ2dlckxpbmssXG4gICAgICAgICAgcXVldWVMaW5rLFxuICAgICAgICAgIHRyYWNrZXJMaW5rLFxuICAgICAgICAgIHF1ZXVlTGluayxcbiAgICAgICAgICBzZXJpYWxpemluZ0xpbmssXG4gICAgICAgICAgcmV0cnlMaW5rLFxuICAgICAgICAgIGF1dGhMaW5rLFxuICAgICAgICAgIGh0dHBMaW5rXG4gICAgICAgIF07XG4gICAgICB9XG4gICAgICBlbHNlIHtcbiAgICAgICAgbXV0YXRpb25MaW5rcyA9IFtcbiAgICAgICAgICByZXRyeUxpbmssXG4gICAgICAgICAgYXV0aExpbmssXG4gICAgICAgICAgaHR0cExpbmtcbiAgICAgICAgXTtcbiAgICAgIH1cblxuICAgICAgLy8gY3JlYXRlIEFwb2xsb1xuICAgICAgY2xpZW50ID0gbmV3IEFwb2xsb0NsaWVudCh7XG4gICAgICAgIGNhY2hlLFxuICAgICAgICBsaW5rOlxuICAgICAgICAgIEFwb2xsb0xpbmsuc3BsaXQoXG4gICAgICAgICAgICAvLyBIYW5kbGUgbXV0YXRpb25zXG4gICAgICAgICAgICBpc011dGF0aW9uT3BlcmF0aW9uLFxuICAgICAgICAgICAgQXBvbGxvTGluay5mcm9tKG11dGF0aW9uTGlua3MpLFxuXG4gICAgICAgICAgICBBcG9sbG9MaW5rLnNwbGl0KFxuICAgICAgICAgICAgICAvLyBIYW5kbGUgc3Vic2NyaXB0aW9uc1xuICAgICAgICAgICAgICBpc1N1YnNjcmlwdGlvbk9wZXJhdGlvbixcbiAgICAgICAgICAgICAgd3NMaW5rLFxuXG4gICAgICAgICAgICAgIC8vIEhhbmRsZSBxdWVyaWVzXG4gICAgICAgICAgICAgIEFwb2xsb0xpbmsuZnJvbShbXG4gICAgICAgICAgICAgICAgcmV0cnlMaW5rLFxuICAgICAgICAgICAgICAgIGF1dGhMaW5rLFxuICAgICAgICAgICAgICAgIGh0dHBMaW5rXG4gICAgICAgICAgICAgIF0pXG4gICAgICAgICAgICApXG4gICAgICAgICAgKSxcbiAgICAgICAgY29ubmVjdFRvRGV2VG9vbHM6ICF0aGlzLmVudmlyb25tZW50LnByb2R1Y3Rpb25cbiAgICAgIH0pO1xuXG4gICAgICB0aGlzLmFwb2xsby5jbGllbnQgPSBjbGllbnQ7XG4gICAgfVxuXG4gICAgLy8gRW5hYmxlIHRyYWNrZWQgcXVlcmllcyBwZXJzaXN0ZW5jZVxuICAgIGlmIChlbmFibGVUcmFja011dGF0aW9uUXVlcmllcyAmJiB0aGlzLmVudmlyb25tZW50LnBlcnNpc3RDYWNoZSkge1xuXG4gICAgICB0cnkge1xuICAgICAgICBhd2FpdCByZXN0b3JlVHJhY2tlZFF1ZXJpZXMoe1xuICAgICAgICAgIGFwb2xsb0NsaWVudDogY2xpZW50LFxuICAgICAgICAgIHN0b3JhZ2UsXG4gICAgICAgICAgZGVidWc6IHRydWVcbiAgICAgICAgfSk7XG4gICAgICB9IGNhdGNoIChlcnIpIHtcbiAgICAgICAgY29uc29sZS5lcnJvcignW2dyYXBocWxdIEZhaWxlZCB0byByZXN0b3JlIHRyYWNrZWQgcXVlcmllcyBmcm9tIHN0b3JhZ2U6ICcgKyAoZXJyICYmIGVyci5tZXNzYWdlIHx8IGVyciksIGVycik7XG4gICAgICB9XG4gICAgfVxuXG4gICAgLy8gTGlzdGVuIGZvciBuZXR3b3JrIHJlc3RhcnRcbiAgICB0aGlzLnJlZ2lzdGVyU3Vic2NyaXB0aW9uKFxuICAgICAgdGhpcy5uZXR3b3JrLm9uKCdzdGFydCcsICgpID0+IHRoaXMucmVzdGFydCgpKVxuICAgICk7XG5cbiAgICAvLyBMaXN0ZW4gZm9yIGNsZWFyIGNhY2hlIHJlcXVlc3QsIGZyb20gbmV0d29ya1xuICAgIHRoaXMucmVnaXN0ZXJTdWJzY3JpcHRpb24oXG4gICAgICB0aGlzLm5ldHdvcmsub24oJ3Jlc2V0Q2FjaGUnLCAoKSA9PiB0aGlzLmNsZWFyQ2FjaGUoKSlcbiAgICApO1xuXG4gICAgY29uc29sZS5pbmZvKCdbZ3JhcGhxbF0gU3RhcnRpbmcgZ3JhcGhxbCBbT0tdJyk7XG4gICAgcmV0dXJuIGNsaWVudDtcbiAgfVxuXG4gIHByb3RlY3RlZCBhc3luYyBuZ09uU3RvcCgpIHtcbiAgICBjb25zb2xlLmluZm8oJ1tncmFwaHFsXSBTdG9wcGluZyBncmFwaHFsIHNlcnZpY2UuLi4nKTtcbiAgICBhd2FpdCB0aGlzLnJlc2V0Q2xpZW50KCk7XG4gIH1cblxuICBwcm90ZWN0ZWQgYXN5bmMgcmVzZXRDbGllbnQoY2xpZW50PzogQXBvbGxvQ2xpZW50PGFueT4pIHtcbiAgICBjbGllbnQgPSAoY2xpZW50IHx8IHRoaXMuYXBvbGxvLmNsaWVudCkgYXMgQXBvbGxvQ2xpZW50PGFueT47XG4gICAgaWYgKCFjbGllbnQpIHJldHVybjtcblxuICAgIGNvbnNvbGUuaW5mbygnW2dyYXBocWxdIFJlc2V0dGluZyBBcG9sbG8gY2xpZW50Li4uJyk7XG4gICAgY2xpZW50LnN0b3AoKTtcblxuICAgIHRoaXMub25SZXNldEF1dGgubmV4dCgpO1xuXG4gICAgYXdhaXQgUHJvbWlzZS5hbGwoW1xuICAgICAgY2xpZW50LmNsZWFyU3RvcmUoKSxcbiAgICAgIHRoaXMuY2xlYXJDYWNoZShjbGllbnQpXG4gICAgXSk7XG4gIH1cblxuICBwcml2YXRlIG9uQXBvbGxvRXJyb3I8VD4oZXJyOiBhbnksIGRlZmF1bHRFcnJvcj86IGFueSk6IE9ic2VydmFibGU8QXBvbGxvUXVlcnlSZXN1bHQ8VD4+IHtcbiAgICByZXR1cm4gb2YodGhpcy50b0Fwb2xsb0Vycm9yPFQ+KGVyciwgZGVmYXVsdEVycm9yKSk7XG4gIH1cblxuICBwcml2YXRlIHRvQXBvbGxvRXJyb3I8VD4oZXJyOiBhbnksIGRlZmF1bHRFcnJvcj86IGFueSk6IEFwb2xsb1F1ZXJ5UmVzdWx0PFQ+IHtcbiAgICBsZXQgZXJyb3IgPVxuICAgICAgLy8gSWYgbmV0d29yayBlcnJvcjogdHJ5IHRvIGNvbnZlcnQgdG8gQXBwIChyZWFkIGFzIEpTT04pLCBvciBjcmVhdGUgYW4gVU5LTk9XTl9ORVRXT1JLX0VSUk9SXG4gICAgICAoZXJyLm5ldHdvcmtFcnJvciAmJiAoXG4gICAgICAgICAgKGVyci5uZXR3b3JrRXJyb3IuZXJyb3IgJiYgdGhpcy50b0FwcEVycm9yKGVyci5uZXR3b3JrRXJyb3IuZXJyb3IpKVxuICAgICAgICAgIHx8IHRoaXMudG9BcHBFcnJvcihlcnIubmV0d29ya0Vycm9yKVxuICAgICAgICAgIHx8IChlcnIubmV0d29ya0Vycm9yLmVycm9yICYmIHRoaXMuY3JlYXRlQXBwRXJyb3JCeUNvZGUoZXJyLm5ldHdvcmtFcnJvci5lcnJvci5zdGF0dXMpKVxuICAgICAgICAgIHx8IHRoaXMuY3JlYXRlQXBwRXJyb3JCeUNvZGUoRXJyb3JDb2Rlcy5VTktOT1dOX05FVFdPUktfRVJST1IpXG4gICAgICAgIClcbiAgICAgIClcbiAgICAgIC8vIElmIGdyYXBoUUw6IHRyeSB0byBjb252ZXJ0IHRoZSBmaXJzdCBlcnJvciBmb3VuZFxuICAgICAgfHwgKGVyci5ncmFwaFFMRXJyb3JzICYmIGVyci5ncmFwaFFMRXJyb3JzLmxlbmd0aCAmJiB0aGlzLnRvQXBwRXJyb3IoZXJyLmdyYXBoUUxFcnJvcnNbMF0pKVxuICAgICAgfHwgdGhpcy50b0FwcEVycm9yKGVycilcbiAgICAgIHx8IHRoaXMudG9BcHBFcnJvcihlcnIub3JpZ2luYWxFcnJvcilcbiAgICAgIHx8IChlcnIuZ3JhcGhRTEVycm9ycyAmJiBlcnIuZ3JhcGhRTEVycm9yc1swXSlcbiAgICAgIHx8IGVycjtcbiAgICBjb25zb2xlLmVycm9yKCdbZ3JhcGhxbF0gJyArIChlcnJvciAmJiBlcnJvci5tZXNzYWdlIHx8IGVycm9yKSwgZXJyb3Iuc3RhY2sgfHwgJycpO1xuICAgIGlmIChlcnJvcj8uY29kZSA9PT0gRXJyb3JDb2Rlcy5VTktOT1dOX05FVFdPUktfRVJST1IgJiYgZXJyLm5ldHdvcmtFcnJvcj8ubWVzc2FnZSkge1xuICAgICAgY29uc29sZS5lcnJvcignW2dyYXBocWxdIG9yaWdpbmFsIGVycm9yOiAnICsgZXJyLm5ldHdvcmtFcnJvci5tZXNzYWdlKTtcbiAgICAgIHRoaXMub25OZXR3b3JrRXJyb3IubmV4dChlcnJvcik7XG4gICAgfVxuXG4gICAgLy8gQXBwbHkgZGVmYXVsdCBlcnJvciwgYW5kIHN0b3JlIG9yaWdpbmFsIGVycm9yIGludG8gZXJyb3IncyBkZXRhaWxzXG4gICAgaWYgKCghZXJyb3IgfHwgIWVycm9yLmNvZGUgfHwgZXJyb3IuY29kZSA9PT0gRXJyb3JDb2Rlcy5JTlRFUk5BTF9TRVJWRVJfRVJST1IpICYmIGRlZmF1bHRFcnJvcikge1xuICAgICAgZXJyb3IgPSB7Li4uZGVmYXVsdEVycm9yLCBkZXRhaWxzOiBlcnJvciwgc3RhY2s6IGVyci5zdGFja307XG4gICAgICBpZiAoZGVmYXVsdEVycm9yLm1lc3NhZ2UpIHtcbiAgICAgICAgZXJyb3IubWVzc2FnZSA9IGRlZmF1bHRFcnJvci5tZXNzYWdlO1xuICAgICAgfVxuICAgIH1cblxuICAgIHJldHVybiB7XG4gICAgICBkYXRhOiBudWxsLFxuICAgICAgZXJyb3JzOiBbZXJyb3JdLFxuICAgICAgbG9hZGluZzogZmFsc2UsXG4gICAgICBuZXR3b3JrU3RhdHVzOiBOZXR3b3JrU3RhdHVzLmVycm9yXG4gICAgfTtcbiAgfVxuXG4gIHByaXZhdGUgY3JlYXRlQXBwRXJyb3JCeUNvZGUoZXJyb3JDb2RlOiBudW1iZXIpOiBhbnkgfCB1bmRlZmluZWQge1xuICAgIGNvbnN0IG1lc3NhZ2UgPSB0aGlzLmdldEkxOG5FcnJvck1lc3NhZ2VCeUNvZGUoZXJyb3JDb2RlKTtcbiAgICBpZiAobWVzc2FnZSkge1xuICAgICAgcmV0dXJuIHtcbiAgICAgICAgY29kZTogZXJyb3JDb2RlLFxuICAgICAgICBtZXNzYWdlXG4gICAgICB9O1xuICAgIH1cbiAgICByZXR1cm4gdW5kZWZpbmVkO1xuICB9XG5cbiAgcHJpdmF0ZSBnZXRJMThuRXJyb3JNZXNzYWdlQnlDb2RlKGVycm9yQ29kZTogbnVtYmVyKTogc3RyaW5nIHwgdW5kZWZpbmVkIHtcblxuICAgIC8vIGxvb2sgaW4gcmVnaXN0ZXJlZCBlcnJvciBjb2Rlc1xuICAgIGNvbnN0IGN1c3RvbUVycm9yTWVzc2FnZSA9IHRoaXMuY3VzdG9tRXJyb3JzW2Vycm9yQ29kZV07XG4gICAgaWYgKGN1c3RvbUVycm9yTWVzc2FnZSkge1xuICAgICAgcmV0dXJuIGN1c3RvbUVycm9yTWVzc2FnZTtcbiAgICB9XG5cbiAgICAvLyBEZWZhdWx0LCBzd2l0Y2ggb24gZXJyb3IgY29kZVxuICAgIHN3aXRjaCAoZXJyb3JDb2RlKSB7XG4gICAgICBjYXNlIFNlcnZlckVycm9yQ29kZXMuVU5BVVRIT1JJWkVEOlxuICAgICAgICByZXR1cm4gJ0VSUk9SLlVOQVVUSE9SSVpFRCc7XG4gICAgICBjYXNlIFNlcnZlckVycm9yQ29kZXMuRk9SQklEREVOOlxuICAgICAgICByZXR1cm4gJ0VSUk9SLkZPUkJJRERFTic7XG4gICAgICBjYXNlIEVycm9yQ29kZXMuVU5LTk9XTl9ORVRXT1JLX0VSUk9SOlxuICAgICAgICByZXR1cm4gJ0VSUk9SLlVOS05PV05fTkVUV09SS19FUlJPUic7XG4gICAgICBjYXNlIFNlcnZlckVycm9yQ29kZXMuQkFEX1VQREFURV9EQVRFOlxuICAgICAgICByZXR1cm4gJ0VSUk9SLkJBRF9VUERBVEVfREFURSc7XG4gICAgICBjYXNlIFNlcnZlckVycm9yQ29kZXMuREFUQV9MT0NLRUQ6XG4gICAgICAgIHJldHVybiAnRVJST1IuREFUQV9MT0NLRUQnO1xuICAgICAgY2FzZSBTZXJ2ZXJFcnJvckNvZGVzLkJBRF9BUFBfVkVSU0lPTjpcbiAgICAgICAgcmV0dXJuICdFUlJPUi5CQURfQVBQX1ZFUlNJT04nO1xuICAgICAgY2FzZSBTZXJ2ZXJFcnJvckNvZGVzLkRBVEFfTk9UX1VOSVFVRTpcbiAgICAgICAgcmV0dXJuICdFUlJPUi5EQVRBX05PVF9VTklRVUUnO1xuICAgIH1cblxuICAgIHJldHVybiB1bmRlZmluZWQ7XG4gIH1cblxuICBwcml2YXRlIHRvQXBwRXJyb3IoZXJyOiBhbnkpOiBhbnkgfCB1bmRlZmluZWQge1xuICAgIGxldCBlcnJvciA9IGVycjtcbiAgICBsZXQgbWVzc2FnZSA9IGVyciAmJiBlcnIubWVzc2FnZSB8fCBlcnI7XG4gICAgLy8gcGFyc2UgbWVzc2FnZSBpZiBKU09OXG4gICAgaWYgKHR5cGVvZiBtZXNzYWdlID09PSAnc3RyaW5nJyAmJiBtZXNzYWdlLnRyaW0oKS5pbmRleE9mKCd7XCJjb2RlXCI6JykgPT09IDApIHtcbiAgICAgIHRyeSB7XG4gICAgICAgIGVycm9yID0gSlNPTi5wYXJzZShtZXNzYWdlXG4gICAgICAgICAgLy8gUmVtb3ZlIHNwZWNpYWwgY2hhcmFjdGVycyBiZWZvcmUgcGFyc2luZyAoZS5nLiBTUUwgZXJyb3JzIGZyb20gYW4gT3JhY2xlIGRhdGFiYXNlKVxuICAgICAgICAgIC5yZXBsYWNlKCdcXG4nLCAnICcpXG4gICAgICAgICAgLnJlcGxhY2UoJ1xccicsICcnKSk7XG4gICAgICAgIG1lc3NhZ2UgPSBlcnJvci5tZXNzYWdlIHx8IG1lc3NhZ2U7XG4gICAgICB9XG4gICAgICBjYXRjaCAocGFyc2VFcnJvcikge1xuICAgICAgICBjb25zb2xlLmVycm9yKCdVbmFibGUgdG8gcGFyc2UgZXJyb3IgYXMgSlNPTjogJywgcGFyc2VFcnJvcik7XG4gICAgICB9XG4gICAgfVxuICAgIGlmIChlcnJvciAmJiBlcnJvci5jb2RlKSB7XG4gICAgICBjb25zdCBhcHBFcnJvciA9IHtcbiAgICAgICAgY29kZTogZXJyb3IuY29kZSxcbiAgICAgICAgbWVzc2FnZTogKHR5cGVvZiBtZXNzYWdlID09PSAnc3RyaW5nJykgPyBtZXNzYWdlIDogZXJyb3IubWVzc2FnZSxcbiAgICAgICAgLi4udGhpcy5jcmVhdGVBcHBFcnJvckJ5Q29kZShlcnJvci5jb2RlKVxuICAgICAgfTtcbiAgICAgIGlmIChhcHBFcnJvci5jb2RlICE9PSBlcnJvci5jb2RlIHx8IGFwcEVycm9yLm1lc3NhZ2UgIT09IGVycm9yLm1lc3NhZ2UpIHtcbiAgICAgICAgLy8gU3RvcmUgb3JpZ2luYWwgZXJyb3IgaW4gZGV0YWlsc1xuICAgICAgICBhcHBFcnJvci5kZXRhaWxzID0gZXJyb3I7XG4gICAgICAgIHJldHVybiBhcHBFcnJvcjtcbiAgICAgIH1cbiAgICAgIC8vIEtlZXAgZXJyb3IgKHdpdGggZGV0YWlscywgaWYgYW55KVxuICAgICAgcmV0dXJuIGVycm9yO1xuICAgIH1cbiAgICByZXR1cm4gdW5kZWZpbmVkO1xuICB9XG5cbn1cbiJdfQ==