@sumaris-net/ngx-components 4.0.0-rc1 → 4.0.0-rc11

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 (324) hide show
  1. package/esm2022/public_api.mjs +5 -2
  2. package/esm2022/src/app/admin/admin-routing.module.mjs +5 -5
  3. package/esm2022/src/app/admin/admin.module.mjs +6 -6
  4. package/esm2022/src/app/admin/services/filter/person.filter.mjs +3 -2
  5. package/esm2022/src/app/admin/services/person.service.mjs +5 -5
  6. package/esm2022/src/app/admin/services/validator/person.validator.mjs +5 -5
  7. package/esm2022/src/app/admin/users/users.mjs +19 -28
  8. package/esm2022/src/app/admin/users/users.module.mjs +5 -5
  9. package/esm2022/src/app/core/about/about.modal.mjs +6 -6
  10. package/esm2022/src/app/core/about/about.module.mjs +5 -5
  11. package/esm2022/src/app/core/account/account.module.mjs +5 -5
  12. package/esm2022/src/app/core/account/account.page.mjs +23 -21
  13. package/esm2022/src/app/core/account/new-token.modal.mjs +20 -15
  14. package/esm2022/src/app/core/account/token.table.mjs +25 -20
  15. package/esm2022/src/app/core/auth/auth.form.mjs +6 -6
  16. package/esm2022/src/app/core/auth/auth.modal.mjs +5 -5
  17. package/esm2022/src/app/core/auth/auth.module.mjs +5 -5
  18. package/esm2022/src/app/core/core.module.mjs +5 -5
  19. package/esm2022/src/app/core/core.testing.module.mjs +5 -5
  20. package/esm2022/src/app/core/form/buttons/form-buttons-bar.component.mjs +6 -6
  21. package/esm2022/src/app/core/form/buttons/form-buttons-bar.module.mjs +5 -5
  22. package/esm2022/src/app/core/form/entity/editor.class.mjs +18 -13
  23. package/esm2022/src/app/core/form/entity/entity-editor-modal.class.mjs +6 -6
  24. package/esm2022/src/app/core/form/entity/entity-editor.class.mjs +17 -11
  25. package/esm2022/src/app/core/form/entity/entity-metadata.component.mjs +5 -5
  26. package/esm2022/src/app/core/form/entity/entity.module.mjs +5 -5
  27. package/esm2022/src/app/core/form/form.class.mjs +5 -5
  28. package/esm2022/src/app/core/form/form.module.mjs +5 -5
  29. package/esm2022/src/app/core/form/list/list.form.mjs +6 -6
  30. package/esm2022/src/app/core/form/list/list.module.mjs +5 -5
  31. package/esm2022/src/app/core/form/properties/properties.form.mjs +7 -7
  32. package/esm2022/src/app/core/form/properties/properties.module.mjs +5 -5
  33. package/esm2022/src/app/core/form/properties/properties.table.mjs +12 -12
  34. package/esm2022/src/app/core/form/properties/property.validator.mjs +5 -5
  35. package/esm2022/src/app/core/form/properties/testing/properties-form.test.mjs +5 -5
  36. package/esm2022/src/app/core/form/properties/testing/properties-form.testing.module.mjs +5 -5
  37. package/esm2022/src/app/core/form/text-popover/testing/text-popover.testing.mjs +5 -5
  38. package/esm2022/src/app/core/form/text-popover/testing/text-popover.testing.module.mjs +5 -5
  39. package/esm2022/src/app/core/form/text-popover/text-popover.component.mjs +7 -7
  40. package/esm2022/src/app/core/form/text-popover/text-popover.module.mjs +6 -11
  41. package/esm2022/src/app/core/graphql/graphql.module.mjs +6 -6
  42. package/esm2022/src/app/core/graphql/graphql.service.mjs +19 -18
  43. package/esm2022/src/app/core/home/home.mjs +7 -8
  44. package/esm2022/src/app/core/home/home.module.mjs +5 -5
  45. package/esm2022/src/app/core/icon/icon.component.mjs +4 -4
  46. package/esm2022/src/app/core/icon/icon.module.mjs +5 -5
  47. package/esm2022/src/app/core/install/install-upgrade-card.component.mjs +6 -6
  48. package/esm2022/src/app/core/install/install-upgrade-card.module.mjs +5 -5
  49. package/esm2022/src/app/core/menu/menu.component.mjs +16 -12
  50. package/esm2022/src/app/core/menu/menu.model.mjs +3 -2
  51. package/esm2022/src/app/core/menu/menu.module.mjs +5 -5
  52. package/esm2022/src/app/core/menu/menu.service.mjs +13 -7
  53. package/esm2022/src/app/core/menu/sub-menu-tab.directive.mjs +5 -5
  54. package/esm2022/src/app/core/menu/testing/menu-other.testing.mjs +5 -5
  55. package/esm2022/src/app/core/menu/testing/menu.testing.mjs +5 -5
  56. package/esm2022/src/app/core/menu/testing/menu.testing.module.mjs +5 -5
  57. package/esm2022/src/app/core/offline/update-offline-mode-card.component.mjs +5 -5
  58. package/esm2022/src/app/core/offline/update-offline-mode-card.module.mjs +5 -5
  59. package/esm2022/src/app/core/peer/select-peer.modal.mjs +8 -7
  60. package/esm2022/src/app/core/peer/select-peer.module.mjs +5 -5
  61. package/esm2022/src/app/core/register/register-confirm.page.mjs +5 -5
  62. package/esm2022/src/app/core/register/register.form.mjs +6 -6
  63. package/esm2022/src/app/core/register/register.modal.mjs +5 -5
  64. package/esm2022/src/app/core/register/register.module.mjs +5 -5
  65. package/esm2022/src/app/core/services/account.service.mjs +52 -26
  66. package/esm2022/src/app/core/services/auth-guard.service.mjs +6 -6
  67. package/esm2022/src/app/core/services/base-entity-service.class.mjs +5 -5
  68. package/esm2022/src/app/core/services/base-graphql-service.class.mjs +6 -6
  69. package/esm2022/src/app/core/services/config/core.config.mjs +7 -7
  70. package/esm2022/src/app/core/services/config.service.mjs +15 -13
  71. package/esm2022/src/app/core/services/crypto.service.mjs +4 -4
  72. package/esm2022/src/app/core/services/local-settings.service.mjs +6 -6
  73. package/esm2022/src/app/core/services/model/account.model.mjs +5 -3
  74. package/esm2022/src/app/core/services/model/config.model.mjs +8 -6
  75. package/esm2022/src/app/core/services/model/department.model.mjs +3 -2
  76. package/esm2022/src/app/core/services/model/peer.model.mjs +3 -2
  77. package/esm2022/src/app/core/services/model/person.model.mjs +3 -2
  78. package/esm2022/src/app/core/services/model/referential.model.mjs +7 -3
  79. package/esm2022/src/app/core/services/model/token.model.mjs +8 -3
  80. package/esm2022/src/app/core/services/network.service.mjs +60 -42
  81. package/esm2022/src/app/core/services/network.types.mjs +1 -1
  82. package/esm2022/src/app/core/services/pipes/account.pipes.mjs +9 -9
  83. package/esm2022/src/app/core/services/pipes/department-to-string.pipe.mjs +5 -5
  84. package/esm2022/src/app/core/services/pipes/person-to-string.pipe.mjs +5 -5
  85. package/esm2022/src/app/core/services/pipes/usage-mode.pipes.mjs +9 -9
  86. package/esm2022/src/app/core/services/platform.service.mjs +23 -12
  87. package/esm2022/src/app/core/services/storage/entities-storage.service.mjs +6 -6
  88. package/esm2022/src/app/core/services/testing/referential-filter.model.mjs +1 -1
  89. package/esm2022/src/app/core/services/testing/referential.validator.mjs +5 -5
  90. package/esm2022/src/app/core/services/validator/account.validator.mjs +5 -5
  91. package/esm2022/src/app/core/services/validator/base.validator.class.mjs +5 -5
  92. package/esm2022/src/app/core/services/validator/local-settings.validator.mjs +5 -5
  93. package/esm2022/src/app/core/services/validator/user-settings.validator.mjs +5 -5
  94. package/esm2022/src/app/core/services/validator/user-token.validator.mjs +5 -5
  95. package/esm2022/src/app/core/settings/settings.module.mjs +5 -5
  96. package/esm2022/src/app/core/settings/settings.page.mjs +7 -7
  97. package/esm2022/src/app/core/table/actions-column.component.mjs +5 -5
  98. package/esm2022/src/app/core/table/async-table.class.mjs +5 -5
  99. package/esm2022/src/app/core/table/entities-async-table-datasource.class.mjs +5 -5
  100. package/esm2022/src/app/core/table/entities-table-datasource.class.mjs +5 -5
  101. package/esm2022/src/app/core/table/memory-table.class.mjs +5 -5
  102. package/esm2022/src/app/core/table/table-select-columns.component.mjs +5 -5
  103. package/esm2022/src/app/core/table/table.class.mjs +9 -5
  104. package/esm2022/src/app/core/table/table.module.mjs +5 -5
  105. package/esm2022/src/app/core/table/testing/table-validator.service.mjs +5 -5
  106. package/esm2022/src/app/core/table/testing/table.testing.mjs +7 -7
  107. package/esm2022/src/app/core/table/testing/table.testing.module.mjs +5 -5
  108. package/esm2022/src/app/core/table/testing/table2-validator.service.mjs +5 -5
  109. package/esm2022/src/app/core/table/testing/table2.testing.mjs +7 -7
  110. package/esm2022/src/app/shared/audio/audio.mjs +6 -6
  111. package/esm2022/src/app/shared/audio/audio.testing.mjs +5 -5
  112. package/esm2022/src/app/shared/audio/audio.testing.module.mjs +5 -5
  113. package/esm2022/src/app/shared/capacitor/keyboard.mjs +5 -5
  114. package/esm2022/src/app/shared/debug/debug.component.mjs +6 -6
  115. package/esm2022/src/app/shared/debug/debug.module.mjs +5 -5
  116. package/esm2022/src/app/shared/directives/autofocus.directive.mjs +5 -5
  117. package/esm2022/src/app/shared/directives/autotitle.directive.mjs +6 -6
  118. package/esm2022/src/app/shared/directives/directives.module.mjs +5 -5
  119. package/esm2022/src/app/shared/directives/drag-and-drop.directive.mjs +4 -4
  120. package/esm2022/src/app/shared/directives/ng-var.directive.mjs +5 -5
  121. package/esm2022/src/app/shared/directives/resizable/resizable.component.mjs +6 -6
  122. package/esm2022/src/app/shared/directives/resizable/resizable.directive.mjs +6 -6
  123. package/esm2022/src/app/shared/directives/resizable/resizable.module.mjs +5 -5
  124. package/esm2022/src/app/shared/file/file.service.mjs +6 -6
  125. package/esm2022/src/app/shared/form/field.component.mjs +7 -7
  126. package/esm2022/src/app/shared/form/loading-spinner.mjs +4 -4
  127. package/esm2022/src/app/shared/gesture/gesture-config.mjs +4 -4
  128. package/esm2022/src/app/shared/guard/component-dirty.guard.mjs +5 -5
  129. package/esm2022/src/app/shared/help/help.modal.mjs +5 -5
  130. package/esm2022/src/app/shared/hotkeys/dialog/hotkeys-dialog.component.mjs +8 -9
  131. package/esm2022/src/app/shared/hotkeys/hotkeys.service.mjs +5 -5
  132. package/esm2022/src/app/shared/hotkeys/shared-hotkeys.module.mjs +5 -5
  133. package/esm2022/src/app/shared/http/http.utils.mjs +15 -11
  134. package/esm2022/src/app/shared/image/gallery/image-gallery.component.mjs +6 -6
  135. package/esm2022/src/app/shared/image/gallery/image-gallery.module.mjs +5 -5
  136. package/esm2022/src/app/shared/image/gallery/testing/gallegry.model.testing.mjs +1 -1
  137. package/esm2022/src/app/shared/image/gallery/testing/gallery.service.testing.mjs +5 -5
  138. package/esm2022/src/app/shared/image/gallery/testing/gallery.testing.mjs +5 -5
  139. package/esm2022/src/app/shared/image/gallery/testing/gallery.testing.module.mjs +5 -5
  140. package/esm2022/src/app/shared/image/image.module.mjs +5 -5
  141. package/esm2022/src/app/shared/image/image.service.mjs +6 -6
  142. package/esm2022/src/app/shared/interceptors/progess.interceptor.mjs +1 -1
  143. package/esm2022/src/app/shared/logging/logging-service.class.mjs +6 -6
  144. package/esm2022/src/app/shared/logging/logging-service.module.mjs +5 -5
  145. package/esm2022/src/app/shared/material/autocomplete/material.autocomplete.mjs +9 -9
  146. package/esm2022/src/app/shared/material/autocomplete/material.autocomplete.module.mjs +5 -5
  147. package/esm2022/src/app/shared/material/autocomplete/testing/autocomplete.test.mjs +6 -6
  148. package/esm2022/src/app/shared/material/badge/badge.directive.mjs +6 -6
  149. package/esm2022/src/app/shared/material/badge/badge.module.mjs +5 -5
  150. package/esm2022/src/app/shared/material/badge/badge.test.mjs +5 -5
  151. package/esm2022/src/app/shared/material/boolean/boolean.module.mjs +5 -5
  152. package/esm2022/src/app/shared/material/boolean/material-boolean2.mjs +6 -6
  153. package/esm2022/src/app/shared/material/boolean/material.boolean.mjs +7 -7
  154. package/esm2022/src/app/shared/material/boolean/testing/boolean.test.page.mjs +5 -5
  155. package/esm2022/src/app/shared/material/chips/chips.module.mjs +5 -5
  156. package/esm2022/src/app/shared/material/chips/material.chips.mjs +7 -7
  157. package/esm2022/src/app/shared/material/chips/testing/chips.test.mjs +5 -5
  158. package/esm2022/src/app/shared/material/datetime/datetime.module.mjs +5 -5
  159. package/esm2022/src/app/shared/material/datetime/material.date.mjs +8 -8
  160. package/esm2022/src/app/shared/material/datetime/material.dateshort.mjs +7 -7
  161. package/esm2022/src/app/shared/material/datetime/material.datetime.mjs +36 -10
  162. package/esm2022/src/app/shared/material/datetime/testing/mat-date-time.test.mjs +15 -8
  163. package/esm2022/src/app/shared/material/datetime/testing/mat-date.test.mjs +8 -7
  164. package/esm2022/src/app/shared/material/datetime/testing/mat-dateshort.test.mjs +5 -5
  165. package/esm2022/src/app/shared/material/duration/duration.module.mjs +5 -5
  166. package/esm2022/src/app/shared/material/duration/material.duration.mjs +6 -6
  167. package/esm2022/src/app/shared/material/duration/testing/mat-duration.test.mjs +5 -5
  168. package/esm2022/src/app/shared/material/latlong/material.latlong.mjs +35 -10
  169. package/esm2022/src/app/shared/material/latlong/material.latlong.module.mjs +5 -5
  170. package/esm2022/src/app/shared/material/latlong/testing/latlong.test.mjs +5 -5
  171. package/esm2022/src/app/shared/material/material.module.mjs +14 -9
  172. package/esm2022/src/app/shared/material/material.testing.module.mjs +16 -5
  173. package/esm2022/src/app/shared/material/numpad/numpad.append-to-input.directive.mjs +5 -5
  174. package/esm2022/src/app/shared/material/numpad/numpad.component.mjs +5 -5
  175. package/esm2022/src/app/shared/material/numpad/numpad.container.mjs +5 -5
  176. package/esm2022/src/app/shared/material/numpad/numpad.content.mjs +4 -4
  177. package/esm2022/src/app/shared/material/numpad/numpad.directive.mjs +5 -5
  178. package/esm2022/src/app/shared/material/numpad/numpad.dom-service.mjs +5 -5
  179. package/esm2022/src/app/shared/material/numpad/numpad.module.mjs +5 -5
  180. package/esm2022/src/app/shared/material/numpad/testing/numpad.test.mjs +5 -5
  181. package/esm2022/src/app/shared/material/paginator/material.paginator-i18n.mjs +5 -5
  182. package/esm2022/src/app/shared/material/stepper/material.stepper-i18n.mjs +5 -5
  183. package/esm2022/src/app/shared/material/swipe/material.swipe.mjs +6 -6
  184. package/esm2022/src/app/shared/material/swipe/swipe.module.mjs +5 -5
  185. package/esm2022/src/app/shared/material/swipe/testing/swipe.test.mjs +5 -5
  186. package/esm2022/src/app/shared/material/testing/common.test.mjs +5 -5
  187. package/esm2022/src/app/shared/material/text/testing/text-form.testing.mjs +31 -0
  188. package/esm2022/src/app/shared/material/text/text-form.component.mjs +97 -0
  189. package/esm2022/src/app/shared/material/text/text-form.module.mjs +63 -0
  190. package/esm2022/src/app/shared/named-filter/named-filter-selector.component.mjs +41 -17
  191. package/esm2022/src/app/shared/named-filter/named-filter.model.mjs +1 -1
  192. package/esm2022/src/app/shared/named-filter/named-filter.module.mjs +5 -5
  193. package/esm2022/src/app/shared/named-filter/named-filter.service.mjs +5 -5
  194. package/esm2022/src/app/shared/pipes/arrays.pipe.mjs +25 -25
  195. package/esm2022/src/app/shared/pipes/colors.pipe.mjs +4 -4
  196. package/esm2022/src/app/shared/pipes/date-diff-duration.pipe.mjs +6 -6
  197. package/esm2022/src/app/shared/pipes/date-format.pipe.mjs +9 -9
  198. package/esm2022/src/app/shared/pipes/date-from-now.pipe.mjs +6 -6
  199. package/esm2022/src/app/shared/pipes/duration.pipe.mjs +6 -6
  200. package/esm2022/src/app/shared/pipes/file-size.pipe.mjs +4 -4
  201. package/esm2022/src/app/shared/pipes/form.pipes.mjs +21 -21
  202. package/esm2022/src/app/shared/pipes/highlight.pipe.mjs +5 -5
  203. package/esm2022/src/app/shared/pipes/latlong-format.pipe.mjs +10 -10
  204. package/esm2022/src/app/shared/pipes/maps.pipe.mjs +13 -13
  205. package/esm2022/src/app/shared/pipes/maskito.pipe.mjs +7 -7
  206. package/esm2022/src/app/shared/pipes/math.pipes.mjs +13 -13
  207. package/esm2022/src/app/shared/pipes/ng-init.pipe.mjs +4 -4
  208. package/esm2022/src/app/shared/pipes/number-format.pipe.mjs +5 -5
  209. package/esm2022/src/app/shared/pipes/pipes.module.mjs +5 -5
  210. package/esm2022/src/app/shared/pipes/property.pipes.mjs +9 -9
  211. package/esm2022/src/app/shared/pipes/string.pipes.mjs +31 -31
  212. package/esm2022/src/app/shared/pipes/translate-context.pipe.mjs +10 -10
  213. package/esm2022/src/app/shared/pipes/types.pipes.mjs +13 -13
  214. package/esm2022/src/app/shared/rx-state.module.mjs +5 -5
  215. package/esm2022/src/app/shared/services/entity-service.class.mjs +1 -1
  216. package/esm2022/src/app/shared/services/memory-entity-service.class.mjs +13 -13
  217. package/esm2022/src/app/shared/services/progress-bar.service.mjs +4 -4
  218. package/esm2022/src/app/shared/services/startable-observable-service.class.mjs +6 -6
  219. package/esm2022/src/app/shared/services/startable-service.class.mjs +7 -7
  220. package/esm2022/src/app/shared/services/translate-context.service.mjs +5 -5
  221. package/esm2022/src/app/shared/services.mjs +2 -2
  222. package/esm2022/src/app/shared/shared-routing.module.mjs +9 -9
  223. package/esm2022/src/app/shared/shared.module.mjs +27 -13
  224. package/esm2022/src/app/shared/shared.testing.module.mjs +5 -5
  225. package/esm2022/src/app/shared/storage/storage-explorer.component.mjs +6 -6
  226. package/esm2022/src/app/shared/storage/storage-explorer.module.mjs +5 -5
  227. package/esm2022/src/app/shared/storage/storage-explorer.testing-routing.module.mjs +5 -5
  228. package/esm2022/src/app/shared/storage/storage-explorer.testing.module.mjs +5 -5
  229. package/esm2022/src/app/shared/storage/storage.service.mjs +6 -6
  230. package/esm2022/src/app/shared/testing/observable.test.mjs +5 -5
  231. package/esm2022/src/app/shared/testing/tests.page.mjs +6 -6
  232. package/esm2022/src/app/shared/toast/toast.testing.mjs +5 -5
  233. package/esm2022/src/app/shared/toast/toast.testing.module.mjs +5 -5
  234. package/esm2022/src/app/shared/toolbar/modal-toolbar.mjs +5 -5
  235. package/esm2022/src/app/shared/toolbar/toolbar.mjs +7 -7
  236. package/esm2022/src/app/shared/toolbar/toolbar.module.mjs +5 -5
  237. package/esm2022/src/app/shared/upload-file/testing/upload-file.testing.mjs +5 -5
  238. package/esm2022/src/app/shared/upload-file/testing/upload-file.testing.module.mjs +5 -5
  239. package/esm2022/src/app/shared/upload-file/upload-file-popover.component.mjs +5 -5
  240. package/esm2022/src/app/shared/upload-file/upload-file.component.mjs +5 -5
  241. package/esm2022/src/app/shared/validator/form-error-adapter.class.mjs +6 -6
  242. package/esm2022/src/app/social/job/job.module.mjs +5 -5
  243. package/esm2022/src/app/social/job/progression/job-progression.component.mjs +5 -5
  244. package/esm2022/src/app/social/job/progression/job-progression.icon.mjs +6 -6
  245. package/esm2022/src/app/social/job/progression/job-progression.list.mjs +5 -5
  246. package/esm2022/src/app/social/job/progression/job-progression.model.mjs +3 -2
  247. package/esm2022/src/app/social/job/progression/job-progression.service.mjs +6 -6
  248. package/esm2022/src/app/social/job/testing/job-progression.testing.mjs +6 -6
  249. package/esm2022/src/app/social/job/testing/job-progression.testing.service.mjs +4 -4
  250. package/esm2022/src/app/social/job/testing/job.testing.module.mjs +5 -5
  251. package/esm2022/src/app/social/message/message.form.mjs +59 -7
  252. package/esm2022/src/app/social/message/message.modal.mjs +21 -13
  253. package/esm2022/src/app/social/message/message.model.mjs +5 -1
  254. package/esm2022/src/app/social/message/message.module.mjs +9 -22
  255. package/esm2022/src/app/social/message/message.service.mjs +33 -11
  256. package/esm2022/src/app/social/social.module.mjs +5 -5
  257. package/esm2022/src/app/social/social.testing.module.mjs +5 -5
  258. package/esm2022/src/app/social/user-event/notification/user-event-notification.icon.mjs +6 -6
  259. package/esm2022/src/app/social/user-event/notification/user-event-notification.list.mjs +6 -6
  260. package/esm2022/src/app/social/user-event/testing/user-event.testing.mjs +6 -6
  261. package/esm2022/src/app/social/user-event/testing/user-event.testing.model.mjs +3 -2
  262. package/esm2022/src/app/social/user-event/testing/user-event.testing.module.mjs +5 -5
  263. package/esm2022/src/app/social/user-event/testing/user-event.testing.service.mjs +6 -6
  264. package/esm2022/src/app/social/user-event/user-event.module.mjs +5 -5
  265. package/esm2022/src/app/social/user-event/user-event.service.mjs +40 -26
  266. package/esm2022/src/environments/environment.class.mjs +4 -1
  267. package/esm2022/src/environments/environment.loader.mjs +83 -0
  268. package/esm2022/src/environments/environment.mjs +18 -15
  269. package/fesm2022/sumaris-net.ngx-components.mjs +4422 -3975
  270. package/fesm2022/sumaris-net.ngx-components.mjs.map +1 -1
  271. package/package.json +31 -6
  272. package/public_api.d.ts +4 -1
  273. package/src/app/core/account/account.page.d.ts +3 -2
  274. package/src/app/core/account/new-token.modal.d.ts +1 -3
  275. package/src/app/core/account/token.table.d.ts +5 -3
  276. package/src/app/core/form/buttons/form-buttons-bar.component.d.ts +1 -1
  277. package/src/app/core/form/entity/editor.class.d.ts +1 -1
  278. package/src/app/core/form/entity/entity-editor.class.d.ts +10 -6
  279. package/src/app/core/form/entity/entity-metadata.component.d.ts +1 -1
  280. package/src/app/core/form/text-popover/text-popover.component.d.ts +1 -1
  281. package/src/app/core/form/text-popover/text-popover.module.d.ts +4 -5
  282. package/src/app/core/graphql/graphql.service.d.ts +2 -4
  283. package/src/app/core/graphql/graphql.utils.d.ts +1 -1
  284. package/src/app/core/menu/menu.component.d.ts +6 -2
  285. package/src/app/core/menu/menu.service.d.ts +2 -0
  286. package/src/app/core/services/account.service.d.ts +4 -0
  287. package/src/app/core/services/config/core.config.d.ts +2 -2
  288. package/src/app/core/services/model/referential.model.d.ts +2 -1
  289. package/src/app/core/services/model/token.model.d.ts +1 -0
  290. package/src/app/core/services/network.service.d.ts +11 -7
  291. package/src/app/core/table/table.class.d.ts +1 -0
  292. package/src/app/shared/hotkeys/dialog/hotkeys-dialog.component.d.ts +2 -4
  293. package/src/app/shared/http/http.utils.d.ts +1 -0
  294. package/src/app/shared/inputs.d.ts +1 -1
  295. package/src/app/shared/material/autocomplete/material.autocomplete.d.ts +1 -1
  296. package/src/app/shared/material/datetime/material.datetime.d.ts +10 -4
  297. package/src/app/shared/material/latlong/material.latlong.d.ts +10 -4
  298. package/src/app/shared/material/material.module.d.ts +2 -1
  299. package/src/app/shared/material/material.testing.module.d.ts +14 -13
  300. package/src/app/shared/material/text/testing/text-form.testing.d.ts +13 -0
  301. package/src/app/{core/form/text-popover → shared/material/text}/text-form.component.d.ts +2 -2
  302. package/src/app/shared/material/text/text-form.module.d.ts +16 -0
  303. package/src/app/shared/named-filter/named-filter-selector.component.d.ts +9 -3
  304. package/src/app/shared/services/entity-service.class.d.ts +1 -1
  305. package/src/app/shared/services/memory-entity-service.class.d.ts +7 -3
  306. package/src/app/shared/services.d.ts +1 -0
  307. package/src/app/shared/shared.module.d.ts +5 -3
  308. package/src/app/social/message/message.form.d.ts +8 -2
  309. package/src/app/social/message/message.modal.d.ts +5 -1
  310. package/src/app/social/message/message.model.d.ts +2 -0
  311. package/src/app/social/message/message.module.d.ts +2 -1
  312. package/src/app/social/message/message.service.d.ts +8 -3
  313. package/src/app/social/user-event/user-event.service.d.ts +5 -0
  314. package/src/assets/environments/environment-test.json +6 -0
  315. package/src/assets/i18n/en-US.json +25 -23
  316. package/src/assets/i18n/en.json +25 -23
  317. package/src/assets/i18n/fr.json +8 -5
  318. package/src/assets/manifest.json +1 -1
  319. package/src/environments/environment.class.d.ts +2 -0
  320. package/src/environments/environment.loader.d.ts +26 -0
  321. package/src/theme/_material.scss +20 -4
  322. package/src/theme/_ngx-components.scss +1 -1
  323. package/src/theme/_ngx-components.table.scss +24 -17
  324. package/esm2022/src/app/core/form/text-popover/text-form.component.mjs +0 -97
@@ -255,8 +255,8 @@ export class TableTestPage extends AppTable {
255
255
  markForCheck() {
256
256
  this.cd.markForCheck();
257
257
  }
258
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: TableTestPage, deps: [{ token: i0.Injector }, { token: i1.AppValidatorService }, { token: i2.UntypedFormBuilder }, { token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component });
259
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.2.12", type: TableTestPage, selector: "app-table-testing", inputs: { enableInfiniteScroll: "enableInfiniteScroll", useSticky: "useSticky" }, providers: [
258
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.0.6", ngImport: i0, type: TableTestPage, deps: [{ token: i0.Injector }, { token: i1.AppValidatorService }, { token: i2.UntypedFormBuilder }, { token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component });
259
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "17.0.6", type: TableTestPage, selector: "app-table-testing", inputs: { enableInfiniteScroll: "enableInfiniteScroll", useSticky: "useSticky" }, providers: [
260
260
  {
261
261
  provide: AppValidatorService,
262
262
  useClass: TableValidatorService
@@ -264,9 +264,9 @@ export class TableTestPage extends AppTable {
264
264
  {
265
265
  provide: AppTable, useExisting: forwardRef(() => TableTestPage),
266
266
  }
267
- ], viewQueries: [{ propertyName: "filterExpansionPanel", first: true, predicate: MatExpansionPanel, descendants: true, static: true }, { propertyName: "infiniteScroll", first: true, predicate: IonInfiniteScroll, descendants: true }], usesInheritance: true, ngImport: i0, template: "<app-toolbar color=\"primary\" [canGoBack]=\"true\"\n [hasValidate]=\"!(loadingSubject|async) && dirty\"\n (onValidate)=\"save()\"\n [backHref]=\"'/testing'\">\n <ion-title>Table (click to edit)</ion-title>\n <ion-buttons slot=\"end\">\n\n\n <ng-container *ngIf=\"!selection.hasValue(); else hasSelection\">\n\n <input matInput type=\"number\" step=\"1\" style=\"color:black; width: 50px;\" [(ngModel)]=\"rowHeight\">\n\n <!-- Add -->\n <button mat-icon-button\n *ngIf=\"canEdit && !mobile\"\n [title]=\"'COMMON.BTN_ADD'|translate\"\n (click)=\"addRow()\">\n <mat-icon>add</mat-icon>\n </button>\n\n <!-- reset filter -->\n <button mat-icon-button (click)=\"resetFilter()\"\n *ngIf=\"filterCriteriaCount\">\n <mat-icon color=\"accent\">filter_list_alt</mat-icon>\n <mat-icon class=\"icon-secondary\" style=\"left: 16px; top: 5px; font-weight: bold;\">close</mat-icon>\n </button>\n\n <!-- show filter -->\n <button mat-icon-button (click)=\"filterExpansionPanel.toggle()\">\n <mat-icon *ngIf=\"filterCriteriaCount; else emptyFilter\"\n [matBadge]=\"filterCriteriaCount\"\n matBadgeColor=\"accent\"\n matBadgeSize=\"small\"\n matBadgePosition=\"above after\">filter_list_alt\n </mat-icon>\n <ng-template #emptyFilter>\n <mat-icon>filter_list_alt</mat-icon>\n </ng-template>\n </button>\n\n <!-- save -->\n <button mat-icon-button *ngIf=\"mobile\"\n [disabled]=\"!(dirtySubject|async)\"\n (click)=\"save()\">\n <mat-icon>save</mat-icon>\n </button>\n\n <!-- start/stop timer to auto-load data -->\n <ion-button *ngIf=\"!timer\" (click)=\"startTimer()\">Start reload</ion-button>\n <ion-button *ngIf=\"timer\" (click)=\"stopTimer()\" color=\"accent\">Stop reload</ion-button>\n </ng-container>\n\n <!-- if row selection -->\n <ng-template #hasSelection>\n\n <!-- delete -->\n <button mat-icon-button\n *ngIf=\"canEdit\" [title]=\"'COMMON.BTN_DELETE'|translate\"\n (click)=\"deleteSelection($event)\">\n <mat-icon>delete</mat-icon>\n </button>\n\n <!-- duplicate -->\n <button mat-icon-button\n *ngIf=\"canEdit && selection.selected | isArrayLength: {equals: 1}\"\n [title]=\"'COMMON.BTN_DUPLICATE'|translate\"\n (click)=\"duplicateRow($event, selection.selected[0])\">\n <mat-icon>file_copy</mat-icon>\n </button>\n </ng-template>\n </ion-buttons>\n</app-toolbar>\n<ion-content class=\"ion-no-padding\">\n\n <ion-refresher slot=\"fixed\" *ngIf=\"mobile\" (ionRefresh)=\"doRefresh($event)\">\n <ion-refresher-content></ion-refresher-content>\n </ion-refresher>\n\n <!-- error -->\n <ion-item *ngIf=\"mobile && error\" lines=\"none\" @slideUpDownAnimation>\n <ion-icon color=\"danger\" slot=\"start\" name=\"alert-circle\"></ion-icon>\n <ion-label color=\"danger\" class=\"error\" [innerHTML]=\"error|translate\"></ion-label>\n </ion-item>\n\n <!-- search -->\n <mat-expansion-panel #filterExpansionPanel class=\"filter-panel filter-panel-floating\">\n <form class=\"form-container ion-padding-top\" [formGroup]=\"filterForm\" (ngSubmit)=\"applyFilterAndClosePanel($event)\">\n\n <ion-grid>\n <ion-row>\n <ion-col>\n <!-- search text -->\n <mat-form-field>\n <mat-label>{{'TABLE.TESTING.SEARCH_TEXT'|translate}}</mat-label>\n <ion-icon matPrefix name=\"search\"></ion-icon>\n <input matInput\n formControlName=\"searchText\"\n autocomplete=\"off\">\n <button mat-icon-button matSuffix tabindex=\"-1\"\n type=\"button\"\n (click)=\"clearControlValue($event, filterForm.controls.searchText)\"\n [hidden]=\"filterForm.controls.searchText.disabled || !filterForm.controls.searchText.value\">\n <mat-icon>close</mat-icon>\n </button>\n </mat-form-field>\n </ion-col>\n </ion-row>\n </ion-grid>\n </form>\n\n <mat-action-row>\n <!-- Counter -->\n <ion-label [hidden]=\"(loadingSubject|async) || filterForm.dirty\"\n [color]=\"empty && 'danger'\"\n class=\"ion-padding\">\n {{ (totalRowCount ? 'COMMON.RESULT_COUNT' : 'COMMON.NO_RESULT') | translate: {\n count: (totalRowCount |\n numberFormat)\n } }}\n </ion-label>\n\n <div class=\"toolbar-spacer\"></div>\n\n <!-- Close panel -->\n <ion-button mat-button fill=\"clear\" color=\"dark\"\n (click)=\"filterExpansionPanel.close()\"\n [disabled]=\"loadingSubject|async\">\n <ion-text translate>COMMON.BTN_CLOSE</ion-text>\n </ion-button>\n\n <!-- Search button -->\n <ion-button mat-button\n [color]=\"filterForm.dirty ? 'tertiary' : 'dark'\"\n [fill]=\"filterForm.dirty ? 'solid' : 'clear'\"\n (click)=\"applyFilterAndClosePanel($event)\">\n <ion-text translate>COMMON.BTN_APPLY</ion-text>\n </ion-button>\n </mat-action-row>\n </mat-expansion-panel>\n\n <!-- table -->\n <div [class.table-container]=\"!enableInfiniteScroll\">\n <table #table mat-table matSort matSortDisableClear\n [dataSource]=\"dataSource\"\n [matSortActive]=\"defaultSortBy\"\n [matSortDirection]=\"defaultSortDirection\"\n [trackBy]=\"trackByFn\"\n [style.--mat-row-height]=\"rowHeight + 'px'\">\n >\n\n <!-- group header cells -->\n\n <ng-container matColumnDef=\"top-start\" [sticky]=\"useSticky\">\n <th mat-header-cell *matHeaderCellDef [class.cdk-visually-hidden]=\"!canEdit\" [attr.colspan]=\"2\">\n <!-- start spacer -->\n </th>\n </ng-container>\n\n <ng-container matColumnDef=\"group-1\">\n <th mat-header-cell *matHeaderCellDef [attr.colspan]=\"3\" style=\"background-color: whitesmoke; margin-bottom: -1px;\">\n <ion-label translate>{{i18nColumnPrefix + 'GROUP_1'}}</ion-label>\n </th>\n </ng-container>\n\n <ng-container matColumnDef=\"group-2\">\n <th mat-header-cell *matHeaderCellDef [attr.colspan]=\"3\">\n <ion-label translate>{{i18nColumnPrefix + 'GROUP_2'}}</ion-label>\n </th>\n </ng-container>\n\n <ng-container matColumnDef=\"top-end\" >\n <th mat-header-cell *matHeaderCellDef>\n <!-- end spacer -->\n </th>\n </ng-container>\n\n <ng-container matColumnDef=\"select\" [sticky]=\"useSticky\" [class.mat-column-sticky]=\"useSticky\">\n <th mat-header-cell *matHeaderCellDef [class.cdk-visually-hidden]=\"!canEdit\">\n <mat-checkbox (change)=\"$event ? masterToggle() : null\" [checked]=\"selection.hasValue() && isAllSelected()\"\n [indeterminate]=\"selection.hasValue() && !isAllSelected()\">\n </mat-checkbox>\n </th>\n <td mat-cell *matCellDef=\"let row\" [class.cdk-visually-hidden]=\"!canEdit\">\n <mat-checkbox (change)=\"$event ? selection.toggle(row) : null\" [checked]=\"selection.isSelected(row)\">\n </mat-checkbox>\n </td>\n </ng-container>\n\n <!-- Id column -->\n <ng-container matColumnDef=\"id\" [sticky]=\"useSticky\" [class.mat-column-sticky]=\"useSticky\">\n <th mat-header-cell *matHeaderCellDef mat-sort-header>\n <ion-label>#</ion-label>\n </th>\n <td mat-cell *matCellDef=\"let row\">{{ row.currentData?.id }}</td>\n </ng-container>\n\n <!-- Label column -->\n <ng-container matColumnDef=\"label\">\n <th mat-header-cell *matHeaderCellDef mat-sort-header>\n <ion-label translate>TABLE.TESTING.LABEL</ion-label>\n </th>\n <td mat-cell *matCellDef=\"let row\" (click)=\"focusColumn='label'\">\n <mat-form-field *ngIf=\"row.editing; else readonlyCell\" [hideRequiredMarker]=\"false\" [floatLabel]=\"'always'\">\n <input matInput autocomplete=\"off\"\n [formControl]=\"row.validator.controls['label']\"\n [placeholder]=\"'TABLE.TESTING.LABEL'|translate\"\n [appAutofocus]=\"row.editing && focusColumn === 'label'\"\n [readonly]=\"!row.editing\">\n <mat-error *ngIf=\"row.validator.controls['label'].hasError('required')\" translate>ERROR.FIELD_REQUIRED</mat-error>\n </mat-form-field>\n <ng-template #readonlyCell>\n <ion-label appAutoTitle>\n {{ (row.validator | formGetValue : 'label')}}\n </ion-label>\n </ng-template>\n </td>\n </ng-container>\n\n <!-- Name column -->\n <ng-container matColumnDef=\"name\">\n <th mat-header-cell *matHeaderCellDef mat-sort-header>\n <ion-label translate>TABLE.TESTING.NAME</ion-label>\n </th>\n <td mat-cell *matCellDef=\"let row\"\n (click)=\"focusColumn='name'\">\n <mat-form-field *ngIf=\"row.editing; else readonlyCell\">\n <input matInput\n [formControl]=\"row.validator?.controls.name\" [placeholder]=\"'TABLE.TESTING.NAME'|translate\"\n [appAutofocus]=\"row.editing && focusColumn === 'name'\"\n >\n <mat-error *ngIf=\"row.validator?.controls.name.hasError('required')\" translate>ERROR.FIELD_REQUIRED</mat-error>\n </mat-form-field>\n <ng-template #readonlyCell>\n <ion-label appAutoTitle>\n {{ (row.validator | formGetValue : 'name')}}\n </ion-label>\n </ng-template>\n </td>\n </ng-container>\n\n <!-- Level column -->\n <ng-container matColumnDef=\"levelId\">\n <th mat-header-cell *matHeaderCellDef mat-sort-header>\n <ion-label translate>TABLE.TESTING.LEVEL_ID</ion-label>\n </th>\n <td mat-cell *matCellDef=\"let row\" (click)=\"focusColumn='levelId'\">\n <mat-autocomplete-field *ngIf=\"row.editing; else readonlyCell\"\n [formControl]=\"row.validator.controls.levelId\"\n [placeholder]=\"'TABLE.TESTING.LEVEL_ID'|translate\"\n floatLabel=\"never\"\n [config]=\"autocompleteFields.level\"\n [readonly]=\"!row.editing\"\n [autofocus]=\"row.editing && focusColumn === 'levelId'\"\n [required]=\"true\">\n </mat-autocomplete-field>\n <ng-template #readonlyCell>\n <ion-label appAutoTitle>\n {{ (row.validator | formGetValue : 'levelId'|referentialToString: autocompleteFields.level.attributes)}}\n </ion-label>\n </ng-template>\n </td>\n </ng-container>\n\n <!-- Status column -->\n <ng-container matColumnDef=\"statusId\">\n <th mat-header-cell *matHeaderCellDef>\n <span translate>USER.STATUS</span>\n </th>\n <td mat-cell *matCellDef=\"let row\" [class.mat-form-field-disabled]=\"!row.editing\">\n <mat-form-field>\n <mat-select [formControl]=\"row.validator.controls['statusId']\" [placeholder]=\"i18nColumnPrefix + 'STATUS_ID'|translate\">\n <mat-option *ngFor=\"let item of statusList\" [value]=\"item.id\">\n <mat-icon><ion-icon [name]=\"item.icon\"></ion-icon></mat-icon>\n <mat-label>{{ item.label |translate }}</mat-label>\n </mat-option>\n </mat-select>\n <mat-error *ngIf=\"row.validator.controls['statusId'].hasError('required')\" translate>ERROR.FIELD_REQUIRED</mat-error>\n </mat-form-field>\n </td>\n </ng-container>\n\n <!-- Enum column -->\n <!-- NOTE : Never used in table -->\n<!-- <ng-container matColumnDef=\"values\">-->\n<!-- <th mat-header-cell *matHeaderCellDef>-->\n<!-- <span translate>Enums</span>-->\n<!-- </th>-->\n<!-- <td mat-cell *matCellDef=\"let row\" [class.mat-form-field-disabled]=\"!row.editing\">-->\n<!-- <app-form-field-->\n<!-- [formControl]=\"row.validator|formGetControl:'properties.values'\"-->\n<!-- [definition]=\"columnDefinitions['values']\"-->\n<!-- ></app-form-field>-->\n<!-- </td>-->\n<!-- </ng-container>-->\n\n <!-- Creation date column -->\n <ng-container matColumnDef=\"updateDate\">\n <th mat-header-cell *matHeaderCellDef mat-sort-header>\n <ion-label translate>TABLE.TESTING.UPDATE_DATE</ion-label>\n </th>\n <td mat-cell *matCellDef=\"let row\" class=\"mat-form-field-disabled\">\n <ion-text color=\"medium\" *ngIf=\"row.id!==-1\">\n <small>\n {{ row.validator| formGetValue: 'creationDate' | dateFormat: {time: true} }}\n </small>\n </ion-text>\n </td>\n </ng-container>\n\n <!-- Comment column -->\n <ng-container matColumnDef=\"comments\">\n <th mat-header-cell *matHeaderCellDef>\n <ion-label translate>TABLE.TESTING.COMMENTS</ion-label>\n </th>\n <td mat-cell *matCellDef=\"let row\">\n <mat-form-field *ngIf=\"row.editing; else iconComment\">\n <!--<textarea matInput [formControl]=\"row.validator?.controls.comments\"\n [placeholder]=\"'TABLE.TESTING.COMMENTS'|translate\"\n [readonly]=\"!row.editing\"></textarea>-->\n\n <input type=\"text\" matInput [formControl]=\"row.validator?.controls.comments\"\n [placeholder]=\"'TABLE.TESTING.COMMENTS'|translate\"\n [readonly]=\"!row.editing\">\n </mat-form-field>\n\n <ng-template #iconComment>\n <mat-icon class=\"comment\"\n *ngIf=\"row.validator?.controls.comments.value\"\n [title]=\"row.validator?.controls.comments.value\"></mat-icon>\n </ng-template>\n </td>\n </ng-container>\n\n <!-- Actions buttons column -->\n <app-actions-column [stickyEnd]=\"true\" [canCancel]=\"false\"\n (optionsClick)=\"openSelectColumnsModal($event)\"\n (cancelOrDeleteClick)=\"cancelOrDelete($event.event, $event.row)\"\n (confirmAndAddClick)=\"confirmAndAdd($event.event, $event.row)\"\n (backward)=\"confirmAndBackward($event.event, $event.row)\"\n (forward)=\"confirmAndForward($event.event, $event.row)\"\n [cellTemplate]=\"cellInjection\">\n\n <!-- cell injection-->\n <ng-template #cellInjection let-row>\n <span *ngIf=\"row.editing && !row.validator.dirty\">-</span>\n </ng-template>\n\n </app-actions-column>\n\n <tr mat-header-row *matHeaderRowDef=\"groupColumns;\" class=\"mat-toolbar\"></tr>\n <tr mat-header-row *matHeaderRowDef=\"displayedColumns; sticky: true\"></tr>\n <tr mat-row *matRowDef=\"let row; columns: displayedColumns;\"\n [class.mat-row-selected]=\"row.editing\"\n [class.mat-row-error]=\"row.validator?.invalid\"\n [class.mat-row-disabled]=\"!row.editing\"\n [class.mat-row-dirty]=\"row.validator?.dirty\"\n (click)=\"clickRow($event, row)\"\n (keydown.escape)=\"escapeEditingRow($event)\"\n [cdkTrapFocus]=\"row.validator?.invalid\"></tr>\n </table>\n\n <ng-container *ngIf=\"loadingSubject|async; else noResult\">\n <ion-item>\n <ion-skeleton-text animated></ion-skeleton-text>\n </ion-item>\n </ng-container>\n\n <ng-template #noResult>\n <ion-item *ngIf=\"totalRowCount === 0\">\n <ion-text color=\"danger\" class=\"text-italic\" translate>COMMON.NO_RESULT</ion-text>\n </ion-item>\n </ng-template>\n\n <ion-infinite-scroll *ngIf=\"enableInfiniteScroll\"\n [threshold]=\"mobile ? '10%' : '2%'\" position=\"bottom\"\n (ionInfinite)=\"fetchMore($event)\">\n <ion-infinite-scroll-content\n loadingSpinner=\"circles\"\n [loadingText]=\"'COMMON.LOADING_DOTS'|translate\">\n </ion-infinite-scroll-content>\n </ion-infinite-scroll>\n </div>\n</ion-content>\n\n<ion-footer>\n <!-- Paginator -->\n <mat-paginator *ngIf=\"!enableInfiniteScroll\"\n [length]=\"totalRowCount\" [pageSize]=\"defaultPageSize\" [pageSizeOptions]=\"defaultPageSizeOptions\"\n class=\"mat-paginator-footer\"\n showFirstLastButtons>\n </mat-paginator>\n\n <app-form-buttons-bar *ngIf=\"canEdit && !mobile\"\n (onCancel)=\"load()\"\n (onSave)=\"save()\"\n [disabled]=\"(loadingSubject|async) || !dirty\">\n <!-- error -->\n <ion-item *ngIf=\"error$|async\" lines=\"none\">\n <ion-icon color=\"danger\" slot=\"start\" name=\"alert-circle\"></ion-icon>\n <ion-label color=\"danger\" [innerHTML]=\"error|translate\"></ion-label>\n </ion-item>\n </app-form-buttons-bar>\n</ion-footer>\n\n<ion-fab slot=\"fixed\" vertical=\"bottom\" horizontal=\"end\"\n *ngIf=\"canEdit && mobile\">\n <ion-fab-button color=\"tertiary\" (click)=\"addRow($event)\">\n <ion-icon name=\"add\"></ion-icon>\n </ion-fab-button>\n</ion-fab>\n", styles: [".table-container .mat-mdc-table{--mat-column-actions-min-width: 62px;--mat-column-actions-max-width: 62px}.table-container .mat-mdc-table .mat-row-selected{padding:3px}.table-container .mat-mdc-table .mat-column-select{min-width:30px}.table-container .mat-mdc-table .mat-column-id{min-width:30px;max-width:30px}.table-container .mat-mdc-table .mat-column-label,.table-container .mat-mdc-table .mat-column-name,.table-container .mat-mdc-table .mat-column-levelId,.table-container .mat-mdc-table .mat-column-statusId{min-width:150px}.table-container .mat-mdc-table .mat-column-comments{min-width:100px;max-width:100px}.table-container .mat-mdc-table .mat-column-updateDate{min-width:110px;max-width:110px}\n"], dependencies: [{ kind: "directive", type: i3.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i3.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: i4.IonButton, selector: "ion-button", inputs: ["buttonType", "color", "disabled", "download", "expand", "fill", "form", "href", "mode", "rel", "routerAnimation", "routerDirection", "shape", "size", "strong", "target", "type"] }, { kind: "component", type: i4.IonButtons, selector: "ion-buttons", inputs: ["collapse"] }, { kind: "component", type: i4.IonCol, selector: "ion-col", inputs: ["offset", "offsetLg", "offsetMd", "offsetSm", "offsetXl", "offsetXs", "pull", "pullLg", "pullMd", "pullSm", "pullXl", "pullXs", "push", "pushLg", "pushMd", "pushSm", "pushXl", "pushXs", "size", "sizeLg", "sizeMd", "sizeSm", "sizeXl", "sizeXs"] }, { kind: "component", type: i4.IonContent, selector: "ion-content", inputs: ["color", "forceOverscroll", "fullscreen", "scrollEvents", "scrollX", "scrollY"] }, { kind: "component", type: i4.IonFab, selector: "ion-fab", inputs: ["activated", "edge", "horizontal", "vertical"] }, { kind: "component", type: i4.IonFabButton, selector: "ion-fab-button", inputs: ["activated", "closeIcon", "color", "disabled", "download", "href", "mode", "rel", "routerAnimation", "routerDirection", "show", "size", "target", "translucent", "type"] }, { kind: "component", type: i4.IonFooter, selector: "ion-footer", inputs: ["collapse", "mode", "translucent"] }, { kind: "component", type: i4.IonGrid, selector: "ion-grid", inputs: ["fixed"] }, { kind: "component", type: i4.IonIcon, selector: "ion-icon", inputs: ["color", "flipRtl", "icon", "ios", "lazy", "md", "mode", "name", "sanitize", "size", "src"] }, { kind: "component", type: i4.IonInfiniteScroll, selector: "ion-infinite-scroll", inputs: ["disabled", "position", "threshold"] }, { kind: "component", type: i4.IonInfiniteScrollContent, selector: "ion-infinite-scroll-content", inputs: ["loadingSpinner", "loadingText"] }, { kind: "component", type: i4.IonItem, selector: "ion-item", inputs: ["button", "color", "counter", "counterFormatter", "detail", "detailIcon", "disabled", "download", "fill", "href", "lines", "mode", "rel", "routerAnimation", "routerDirection", "shape", "target", "type"] }, { kind: "component", type: i4.IonLabel, selector: "ion-label", inputs: ["color", "mode", "position"] }, { kind: "component", type: i4.IonRefresher, selector: "ion-refresher", inputs: ["closeDuration", "disabled", "pullFactor", "pullMax", "pullMin", "snapbackDuration"] }, { kind: "component", type: i4.IonRefresherContent, selector: "ion-refresher-content", inputs: ["pullingIcon", "pullingText", "refreshingSpinner", "refreshingText"] }, { kind: "component", type: i4.IonRow, selector: "ion-row" }, { kind: "component", type: i4.IonSkeletonText, selector: "ion-skeleton-text", inputs: ["animated"] }, { kind: "component", type: i4.IonText, selector: "ion-text", inputs: ["color", "mode"] }, { kind: "component", type: i4.IonTitle, selector: "ion-title", inputs: ["color", "size"] }, { kind: "directive", type: i5.TranslateDirective, selector: "[translate],[ngx-translate]", inputs: ["translate", "translateParams"] }, { kind: "directive", type: i2.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i2.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i2.NumberValueAccessor, selector: "input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]" }, { kind: "directive", type: i2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i2.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i2.RequiredValidator, selector: ":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]", inputs: ["required"] }, { kind: "directive", type: i2.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { kind: "directive", type: i2.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i2.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "component", type: i6.MatTable, selector: "mat-table, table[mat-table]", exportAs: ["matTable"] }, { kind: "directive", type: i6.MatHeaderCellDef, selector: "[matHeaderCellDef]" }, { kind: "directive", type: i6.MatHeaderRowDef, selector: "[matHeaderRowDef]", inputs: ["matHeaderRowDef", "matHeaderRowDefSticky"] }, { kind: "directive", type: i6.MatColumnDef, selector: "[matColumnDef]", inputs: ["sticky", "matColumnDef"] }, { kind: "directive", type: i6.MatCellDef, selector: "[matCellDef]" }, { kind: "directive", type: i6.MatRowDef, selector: "[matRowDef]", inputs: ["matRowDefColumns", "matRowDefWhen"] }, { kind: "directive", type: i6.MatHeaderCell, selector: "mat-header-cell, th[mat-header-cell]" }, { kind: "directive", type: i6.MatCell, selector: "mat-cell, td[mat-cell]" }, { kind: "component", type: i6.MatHeaderRow, selector: "mat-header-row, tr[mat-header-row]", exportAs: ["matHeaderRow"] }, { kind: "component", type: i6.MatRow, selector: "mat-row, tr[mat-row]", exportAs: ["matRow"] }, { kind: "directive", type: i7.MatSort, selector: "[matSort]", inputs: ["matSortDisabled", "matSortActive", "matSortStart", "matSortDirection", "matSortDisableClear"], outputs: ["matSortChange"], exportAs: ["matSort"] }, { kind: "component", type: i7.MatSortHeader, selector: "[mat-sort-header]", inputs: ["disabled", "mat-sort-header", "arrowPosition", "start", "sortActionDescription", "disableClear"], exportAs: ["matSortHeader"] }, { kind: "component", type: i8.MatPaginator, selector: "mat-paginator", inputs: ["disabled"], exportAs: ["matPaginator"] }, { kind: "component", type: i9.MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i9.MatLabel, selector: "mat-label" }, { kind: "directive", type: i9.MatError, selector: "mat-error, [matError]", inputs: ["id"] }, { kind: "directive", type: i9.MatPrefix, selector: "[matPrefix], [matIconPrefix], [matTextPrefix]", inputs: ["matTextPrefix"] }, { kind: "directive", type: i9.MatSuffix, selector: "[matSuffix], [matIconSuffix], [matTextSuffix]", inputs: ["matTextSuffix"] }, { kind: "directive", type: i10.MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly"], exportAs: ["matInput"] }, { kind: "component", type: i11.MatCheckbox, selector: "mat-checkbox", inputs: ["disableRipple", "color", "tabIndex"], exportAs: ["matCheckbox"] }, { kind: "component", type: i12.MatExpansionPanel, selector: "mat-expansion-panel", inputs: ["disabled", "expanded", "hideToggle", "togglePosition"], outputs: ["opened", "closed", "expandedChange", "afterExpand", "afterCollapse"], exportAs: ["matExpansionPanel"] }, { kind: "directive", type: i12.MatExpansionPanelActionRow, selector: "mat-action-row" }, { kind: "component", type: i13.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "component", type: i14.MatIconButton, selector: "button[mat-icon-button]", inputs: ["disabled", "disableRipple", "color"], exportAs: ["matButton"] }, { kind: "component", type: i15.MatSelect, selector: "mat-select", inputs: ["disabled", "disableRipple", "tabIndex", "panelWidth", "hideSingleSelectionIndicator"], exportAs: ["matSelect"] }, { kind: "component", type: i16.MatOption, selector: "mat-option", exportAs: ["matOption"] }, { kind: "directive", type: i17.MatBadge, selector: "[matBadge]", inputs: ["matBadgeDisabled", "matBadgeColor", "matBadgeOverlap", "matBadgePosition", "matBadge", "matBadgeDescription", "matBadgeSize", "matBadgeHidden"] }, { kind: "directive", type: i18.CdkTrapFocus, selector: "[cdkTrapFocus]", inputs: ["cdkTrapFocus", "cdkTrapFocusAutoCapture"], exportAs: ["cdkTrapFocus"] }, { kind: "component", type: i19.MatAutocompleteField, selector: "mat-autocomplete-field", inputs: ["equals", "logPrefix", "formControl", "formControlName", "floatLabel", "appearance", "placeholder", "suggestFn", "required", "mobile", "clearable", "debounceTime", "displayWith", "displayAttributes", "displayColumnSizes", "displayColumnNames", "highlightAccent", "showAllOnFocus", "showPanelOnFocus", "autofocus", "config", "i18nPrefix", "noResultMessage", "class", "panelWidth", "matAutocompletePosition", "multiple", "fetchMoreThreshold", "suggestLengthThreshold", "showLoadingSpinner", "debug", "showSearchBar", "stickySearchBar", "applyImplicitValue", "filter", "readonly", "tabindex", "items"], outputs: ["click", "blur", "focus", "dropButtonClick", "keydown.escape", "keyup.enter"] }, { kind: "directive", type: i20.AutofocusDirective, selector: "[autofocus], input[appAutofocus]", inputs: ["appAutofocus", "autofocusDelay"] }, { kind: "directive", type: i21.AutoTitleDirective, selector: "[appAutoTitle]" }, { kind: "component", type: i22.ToolbarComponent, selector: "app-toolbar", inputs: ["progressBarMode", "title", "color", "class", "backHref", "defaultBackHref", "hasValidate", "hasClose", "hasSearch", "canGoBack", "canShowMenu"], outputs: ["onValidate", "onClose", "onValidateAndClose", "onBackClick", "onSearch"] }, { kind: "component", type: i23.FormButtonsBarComponent, selector: "app-form-buttons-bar", inputs: ["disabled", "disabledCancel", "classList", "saveButtonColor", "backText", "cancelText", "nextText", "showBack", "showCancel", "showNext", "showSave", "showSaveAndClose", "showSaveAndNext"], outputs: ["onCancel", "onSave", "onNext", "onBack", "onSaveAndClose", "onSaveAndNext"] }, { kind: "component", type: i24.ActionsColumnComponent, selector: "app-actions-column", inputs: ["stickyEnd", "canCancel", "canConfirm", "canDelete", "canBackward", "canForward", "canConfirmAndAdd", "dirtyIcon", "optionsTitle", "class", "cellTemplate"], outputs: ["optionsClick", "cancelOrDeleteClick", "confirmEditCreateClick", "confirmAndAddClick", "backward", "forward"] }, { kind: "directive", type: i2.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "pipe", type: i3.AsyncPipe, name: "async" }, { kind: "pipe", type: i5.TranslatePipe, name: "translate" }, { kind: "pipe", type: i25.DateFormatPipe, name: "dateFormat" }, { kind: "pipe", type: i26.NumberFormatPipe, name: "numberFormat" }, { kind: "pipe", type: i27.ArrayLengthPipe, name: "isArrayLength" }, { kind: "pipe", type: i28.ReferentialToStringPipe, name: "referentialToString" }, { kind: "pipe", type: i29.FormGetValuePipe, name: "formGetValue" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
267
+ ], viewQueries: [{ propertyName: "filterExpansionPanel", first: true, predicate: MatExpansionPanel, descendants: true, static: true }, { propertyName: "infiniteScroll", first: true, predicate: IonInfiniteScroll, descendants: true }], usesInheritance: true, ngImport: i0, template: "<app-toolbar color=\"primary\" [canGoBack]=\"true\"\n [hasValidate]=\"!(loadingSubject|async) && dirty\"\n (onValidate)=\"save()\"\n [backHref]=\"'/testing'\">\n <ion-title>Table (click to edit)</ion-title>\n <ion-buttons slot=\"end\">\n\n\n <ng-container *ngIf=\"!selection.hasValue(); else hasSelection\">\n\n <input matInput type=\"number\" step=\"1\" style=\"color:black; width: 50px;\" [(ngModel)]=\"rowHeight\">\n\n <!-- Add -->\n <button mat-icon-button\n *ngIf=\"canEdit && !mobile\"\n [title]=\"'COMMON.BTN_ADD'|translate\"\n (click)=\"addRow()\">\n <mat-icon>add</mat-icon>\n </button>\n\n <!-- reset filter -->\n <button mat-icon-button (click)=\"resetFilter()\"\n *ngIf=\"filterCriteriaCount\">\n <mat-icon color=\"accent\">filter_list_alt</mat-icon>\n <mat-icon class=\"icon-secondary\" style=\"left: 16px; top: 5px; font-weight: bold;\">close</mat-icon>\n </button>\n\n <!-- show filter -->\n <button mat-icon-button (click)=\"filterExpansionPanel.toggle()\">\n <mat-icon *ngIf=\"filterCriteriaCount; else emptyFilter\"\n [matBadge]=\"filterCriteriaCount\"\n matBadgeColor=\"accent\"\n matBadgeSize=\"small\"\n matBadgePosition=\"above after\">filter_list_alt\n </mat-icon>\n <ng-template #emptyFilter>\n <mat-icon>filter_list_alt</mat-icon>\n </ng-template>\n </button>\n\n <!-- save -->\n <button mat-icon-button *ngIf=\"mobile\"\n [disabled]=\"!(dirtySubject|async)\"\n (click)=\"save()\">\n <mat-icon>save</mat-icon>\n </button>\n\n <!-- start/stop timer to auto-load data -->\n <ion-button *ngIf=\"!timer\" (click)=\"startTimer()\">Start reload</ion-button>\n <ion-button *ngIf=\"timer\" (click)=\"stopTimer()\" color=\"accent\">Stop reload</ion-button>\n </ng-container>\n\n <!-- if row selection -->\n <ng-template #hasSelection>\n\n <!-- delete -->\n <button mat-icon-button\n *ngIf=\"canEdit\" [title]=\"'COMMON.BTN_DELETE'|translate\"\n (click)=\"deleteSelection($event)\">\n <mat-icon>delete</mat-icon>\n </button>\n\n <!-- duplicate -->\n <button mat-icon-button\n *ngIf=\"canEdit && selection.selected | isArrayLength: {equals: 1}\"\n [title]=\"'COMMON.BTN_DUPLICATE'|translate\"\n (click)=\"duplicateRow($event, selection.selected[0])\">\n <mat-icon>file_copy</mat-icon>\n </button>\n </ng-template>\n </ion-buttons>\n</app-toolbar>\n<ion-content class=\"ion-no-padding\">\n\n <ion-refresher slot=\"fixed\" *ngIf=\"mobile\" (ionRefresh)=\"doRefresh($event)\">\n <ion-refresher-content></ion-refresher-content>\n </ion-refresher>\n\n <!-- error -->\n <ion-item *ngIf=\"mobile && error\" lines=\"none\" @slideUpDownAnimation>\n <ion-icon color=\"danger\" slot=\"start\" name=\"alert-circle\"></ion-icon>\n <ion-label color=\"danger\" class=\"error\" [innerHTML]=\"error|translate\"></ion-label>\n </ion-item>\n\n <!-- search -->\n <mat-expansion-panel #filterExpansionPanel class=\"filter-panel filter-panel-floating\">\n <form class=\"form-container ion-padding-top\" [formGroup]=\"filterForm\" (ngSubmit)=\"applyFilterAndClosePanel($event)\">\n\n <ion-grid>\n <ion-row>\n <ion-col>\n <!-- search text -->\n <mat-form-field>\n <mat-label>{{'TABLE.TESTING.SEARCH_TEXT'|translate}}</mat-label>\n <ion-icon matPrefix name=\"search\"></ion-icon>\n <input matInput\n formControlName=\"searchText\"\n autocomplete=\"off\">\n <button mat-icon-button matSuffix tabindex=\"-1\"\n type=\"button\"\n (click)=\"clearControlValue($event, filterForm.controls.searchText)\"\n [hidden]=\"filterForm.controls.searchText.disabled || !filterForm.controls.searchText.value\">\n <mat-icon>close</mat-icon>\n </button>\n </mat-form-field>\n </ion-col>\n </ion-row>\n </ion-grid>\n </form>\n\n <mat-action-row>\n <!-- Counter -->\n <ion-label [hidden]=\"(loadingSubject|async) || filterForm.dirty\"\n [color]=\"empty && 'danger'\"\n class=\"ion-padding\">\n {{ (totalRowCount ? 'COMMON.RESULT_COUNT' : 'COMMON.NO_RESULT') | translate: {\n count: (totalRowCount |\n numberFormat)\n } }}\n </ion-label>\n\n <div class=\"toolbar-spacer\"></div>\n\n <!-- Close panel -->\n <ion-button mat-button fill=\"clear\" color=\"dark\"\n (click)=\"filterExpansionPanel.close()\"\n [disabled]=\"loadingSubject|async\">\n <ion-text translate>COMMON.BTN_CLOSE</ion-text>\n </ion-button>\n\n <!-- Search button -->\n <ion-button mat-button\n [color]=\"filterForm.dirty ? 'tertiary' : 'dark'\"\n [fill]=\"filterForm.dirty ? 'solid' : 'clear'\"\n (click)=\"applyFilterAndClosePanel($event)\">\n <ion-text translate>COMMON.BTN_APPLY</ion-text>\n </ion-button>\n </mat-action-row>\n </mat-expansion-panel>\n\n <!-- table -->\n <div [class.table-container]=\"!enableInfiniteScroll\">\n <table #table mat-table matSort matSortDisableClear\n [dataSource]=\"dataSource\"\n [matSortActive]=\"defaultSortBy\"\n [matSortDirection]=\"defaultSortDirection\"\n [trackBy]=\"trackByFn\"\n [style.--mat-row-height]=\"rowHeight + 'px'\">\n >\n\n <!-- group header cells -->\n\n <ng-container matColumnDef=\"top-start\" [sticky]=\"useSticky\">\n <th mat-header-cell *matHeaderCellDef [class.cdk-visually-hidden]=\"!canEdit\" [attr.colspan]=\"2\">\n <!-- start spacer -->\n </th>\n </ng-container>\n\n <ng-container matColumnDef=\"group-1\">\n <th mat-header-cell *matHeaderCellDef [attr.colspan]=\"3\" style=\"background-color: whitesmoke; margin-bottom: -1px;\">\n <ion-label translate>{{i18nColumnPrefix + 'GROUP_1'}}</ion-label>\n </th>\n </ng-container>\n\n <ng-container matColumnDef=\"group-2\">\n <th mat-header-cell *matHeaderCellDef [attr.colspan]=\"3\">\n <ion-label translate>{{i18nColumnPrefix + 'GROUP_2'}}</ion-label>\n </th>\n </ng-container>\n\n <ng-container matColumnDef=\"top-end\" >\n <th mat-header-cell *matHeaderCellDef>\n <!-- end spacer -->\n </th>\n </ng-container>\n\n <ng-container matColumnDef=\"select\" [sticky]=\"useSticky\" [class.mat-column-sticky]=\"useSticky\">\n <th mat-header-cell *matHeaderCellDef [class.cdk-visually-hidden]=\"!canEdit\">\n <mat-checkbox (change)=\"$event ? masterToggle() : null\" [checked]=\"selection.hasValue() && isAllSelected()\"\n [indeterminate]=\"selection.hasValue() && !isAllSelected()\">\n </mat-checkbox>\n </th>\n <td mat-cell *matCellDef=\"let row\" [class.cdk-visually-hidden]=\"!canEdit\">\n <mat-checkbox (click)=\"toggleSelectRow($event, row)\" [checked]=\"selection.isSelected(row)\">\n </mat-checkbox>\n </td>\n </ng-container>\n\n <!-- Id column -->\n <ng-container matColumnDef=\"id\" [sticky]=\"useSticky\" [class.mat-column-sticky]=\"useSticky\">\n <th mat-header-cell *matHeaderCellDef mat-sort-header>\n <ion-label>#</ion-label>\n </th>\n <td mat-cell *matCellDef=\"let row\">{{ row.currentData?.id }}</td>\n </ng-container>\n\n <!-- Label column -->\n <ng-container matColumnDef=\"label\">\n <th mat-header-cell *matHeaderCellDef mat-sort-header>\n <ion-label translate>TABLE.TESTING.LABEL</ion-label>\n </th>\n <td mat-cell *matCellDef=\"let row\" (click)=\"focusColumn='label'\">\n <mat-form-field *ngIf=\"row.editing; else readonlyCell\" [hideRequiredMarker]=\"false\">\n <input matInput autocomplete=\"off\"\n [formControl]=\"row.validator.controls['label']\"\n [placeholder]=\"'TABLE.TESTING.LABEL'|translate\"\n [appAutofocus]=\"row.editing && focusColumn === 'label'\"\n [readonly]=\"!row.editing\">\n <mat-error *ngIf=\"row.validator.controls['label'].hasError('required')\" translate>ERROR.FIELD_REQUIRED</mat-error>\n </mat-form-field>\n <ng-template #readonlyCell>\n <ion-label appAutoTitle>\n {{ (row.validator | formGetValue : 'label')}}\n </ion-label>\n </ng-template>\n </td>\n </ng-container>\n\n <!-- Name column -->\n <ng-container matColumnDef=\"name\">\n <th mat-header-cell *matHeaderCellDef mat-sort-header>\n <ion-label translate>TABLE.TESTING.NAME</ion-label>\n </th>\n <td mat-cell *matCellDef=\"let row\"\n (click)=\"focusColumn='name'\">\n <mat-form-field *ngIf=\"row.editing; else readonlyCell\">\n <input matInput\n [formControl]=\"row.validator?.controls.name\" [placeholder]=\"'TABLE.TESTING.NAME'|translate\"\n [appAutofocus]=\"row.editing && focusColumn === 'name'\"\n >\n <mat-error *ngIf=\"row.validator?.controls.name.hasError('required')\" translate>ERROR.FIELD_REQUIRED</mat-error>\n </mat-form-field>\n <ng-template #readonlyCell>\n <ion-label appAutoTitle>\n {{ (row.validator | formGetValue : 'name')}}\n </ion-label>\n </ng-template>\n </td>\n </ng-container>\n\n <!-- Level column -->\n <ng-container matColumnDef=\"levelId\">\n <th mat-header-cell *matHeaderCellDef mat-sort-header>\n <ion-label translate>TABLE.TESTING.LEVEL_ID</ion-label>\n </th>\n <td mat-cell *matCellDef=\"let row\" (click)=\"focusColumn='levelId'\">\n <mat-autocomplete-field *ngIf=\"row.editing; else readonlyCell\"\n [formControl]=\"row.validator.controls.levelId\"\n [placeholder]=\"'TABLE.TESTING.LEVEL_ID'|translate\"\n floatLabel=\"never\"\n [config]=\"autocompleteFields.level\"\n [readonly]=\"!row.editing\"\n [autofocus]=\"row.editing && focusColumn === 'levelId'\"\n [required]=\"true\">\n </mat-autocomplete-field>\n <ng-template #readonlyCell>\n <ion-label appAutoTitle>\n {{ (row.validator | formGetValue : 'levelId'|referentialToString: autocompleteFields.level.attributes)}}\n </ion-label>\n </ng-template>\n </td>\n </ng-container>\n\n <!-- Status column -->\n <ng-container matColumnDef=\"statusId\">\n <th mat-header-cell *matHeaderCellDef>\n <span translate>USER.STATUS</span>\n </th>\n <td mat-cell *matCellDef=\"let row\" [class.mat-form-field-disabled]=\"!row.editing\">\n <mat-form-field>\n <mat-select [formControl]=\"row.validator.controls['statusId']\" [placeholder]=\"i18nColumnPrefix + 'STATUS_ID'|translate\">\n <mat-option *ngFor=\"let item of statusList\" [value]=\"item.id\">\n <mat-icon><ion-icon [name]=\"item.icon\"></ion-icon></mat-icon>\n <mat-label>{{ item.label |translate }}</mat-label>\n </mat-option>\n </mat-select>\n <mat-error *ngIf=\"row.validator.controls['statusId'].hasError('required')\" translate>ERROR.FIELD_REQUIRED</mat-error>\n </mat-form-field>\n </td>\n </ng-container>\n\n <!-- Enum column -->\n <!-- NOTE : Never used in table -->\n<!-- <ng-container matColumnDef=\"values\">-->\n<!-- <th mat-header-cell *matHeaderCellDef>-->\n<!-- <span translate>Enums</span>-->\n<!-- </th>-->\n<!-- <td mat-cell *matCellDef=\"let row\" [class.mat-form-field-disabled]=\"!row.editing\">-->\n<!-- <app-form-field-->\n<!-- [formControl]=\"row.validator|formGetControl:'properties.values'\"-->\n<!-- [definition]=\"columnDefinitions['values']\"-->\n<!-- ></app-form-field>-->\n<!-- </td>-->\n<!-- </ng-container>-->\n\n <!-- Creation date column -->\n <ng-container matColumnDef=\"updateDate\">\n <th mat-header-cell *matHeaderCellDef mat-sort-header>\n <ion-label translate>TABLE.TESTING.UPDATE_DATE</ion-label>\n </th>\n <td mat-cell *matCellDef=\"let row\" class=\"mat-form-field-disabled\">\n <ion-text color=\"medium\" *ngIf=\"row.id!==-1\">\n <small>\n {{ row.validator| formGetValue: 'creationDate' | dateFormat: {time: true} }}\n </small>\n </ion-text>\n </td>\n </ng-container>\n\n <!-- Comment column -->\n <ng-container matColumnDef=\"comments\">\n <th mat-header-cell *matHeaderCellDef>\n <ion-label translate>TABLE.TESTING.COMMENTS</ion-label>\n </th>\n <td mat-cell *matCellDef=\"let row\">\n <mat-form-field *ngIf=\"row.editing; else iconComment\">\n <!--<textarea matInput [formControl]=\"row.validator?.controls.comments\"\n [placeholder]=\"'TABLE.TESTING.COMMENTS'|translate\"\n [readonly]=\"!row.editing\"></textarea>-->\n\n <input type=\"text\" matInput [formControl]=\"row.validator?.controls.comments\"\n [placeholder]=\"'TABLE.TESTING.COMMENTS'|translate\"\n [readonly]=\"!row.editing\">\n </mat-form-field>\n\n <ng-template #iconComment>\n <mat-icon class=\"comment\"\n *ngIf=\"row.validator?.controls.comments.value\"\n [title]=\"row.validator?.controls.comments.value\"></mat-icon>\n </ng-template>\n </td>\n </ng-container>\n\n <!-- Actions buttons column -->\n <app-actions-column [stickyEnd]=\"true\" [canCancel]=\"false\"\n (optionsClick)=\"openSelectColumnsModal($event)\"\n (cancelOrDeleteClick)=\"cancelOrDelete($event.event, $event.row)\"\n (confirmAndAddClick)=\"confirmAndAdd($event.event, $event.row)\"\n (backward)=\"confirmAndBackward($event.event, $event.row)\"\n (forward)=\"confirmAndForward($event.event, $event.row)\"\n [cellTemplate]=\"cellInjection\">\n\n <!-- cell injection-->\n <ng-template #cellInjection let-row>\n <span *ngIf=\"row.editing && !row.validator.dirty\">-</span>\n </ng-template>\n\n </app-actions-column>\n\n <tr mat-header-row *matHeaderRowDef=\"groupColumns;\" class=\"mat-toolbar\"></tr>\n <tr mat-header-row *matHeaderRowDef=\"displayedColumns; sticky: true\"></tr>\n <tr mat-row *matRowDef=\"let row; columns: displayedColumns;\"\n [class.mat-row-selected]=\"row.editing\"\n [class.mat-row-error]=\"row.validator?.invalid\"\n [class.mat-row-disabled]=\"!row.editing\"\n [class.mat-row-dirty]=\"row.validator?.dirty\"\n (click)=\"clickRow($event, row)\"\n (keydown.escape)=\"escapeEditingRow($event)\"\n [cdkTrapFocus]=\"row.validator?.invalid\"></tr>\n </table>\n\n <ng-container *ngIf=\"loadingSubject|async; else noResult\">\n <ion-item>\n <ion-skeleton-text animated></ion-skeleton-text>\n </ion-item>\n </ng-container>\n\n <ng-template #noResult>\n <ion-item *ngIf=\"totalRowCount === 0\">\n <ion-text color=\"danger\" class=\"text-italic\" translate>COMMON.NO_RESULT</ion-text>\n </ion-item>\n </ng-template>\n\n <ion-infinite-scroll *ngIf=\"enableInfiniteScroll\"\n [threshold]=\"mobile ? '10%' : '2%'\" position=\"bottom\"\n (ionInfinite)=\"fetchMore($event)\">\n <ion-infinite-scroll-content\n loadingSpinner=\"circles\"\n [loadingText]=\"'COMMON.LOADING_DOTS'|translate\">\n </ion-infinite-scroll-content>\n </ion-infinite-scroll>\n </div>\n</ion-content>\n\n<ion-footer>\n <!-- Paginator -->\n <mat-paginator *ngIf=\"!enableInfiniteScroll\"\n [length]=\"totalRowCount\" [pageSize]=\"defaultPageSize\" [pageSizeOptions]=\"defaultPageSizeOptions\"\n class=\"mat-paginator-footer\"\n showFirstLastButtons>\n </mat-paginator>\n\n <app-form-buttons-bar *ngIf=\"canEdit && !mobile\"\n (onCancel)=\"load()\"\n (onSave)=\"save()\"\n [disabled]=\"(loadingSubject|async) || !dirty\">\n <!-- error -->\n <ion-item *ngIf=\"error$|async\" lines=\"none\">\n <ion-icon color=\"danger\" slot=\"start\" name=\"alert-circle\"></ion-icon>\n <ion-label color=\"danger\" [innerHTML]=\"error|translate\"></ion-label>\n </ion-item>\n </app-form-buttons-bar>\n</ion-footer>\n\n<ion-fab slot=\"fixed\" vertical=\"bottom\" horizontal=\"end\"\n *ngIf=\"canEdit && mobile\">\n <ion-fab-button color=\"tertiary\" (click)=\"addRow($event)\">\n <ion-icon name=\"add\"></ion-icon>\n </ion-fab-button>\n</ion-fab>\n", styles: [".table-container .mat-mdc-table{--mat-column-actions-min-width: 62px;--mat-column-actions-max-width: 62px}.table-container .mat-mdc-table .mat-row-selected{padding:3px}.table-container .mat-mdc-table .mat-column-select{min-width:30px}.table-container .mat-mdc-table .mat-column-id{min-width:30px;max-width:30px}.table-container .mat-mdc-table .mat-column-label,.table-container .mat-mdc-table .mat-column-name,.table-container .mat-mdc-table .mat-column-levelId,.table-container .mat-mdc-table .mat-column-statusId{min-width:150px}.table-container .mat-mdc-table .mat-column-comments{min-width:100px;max-width:100px}.table-container .mat-mdc-table .mat-column-updateDate{min-width:110px;max-width:110px}\n"], dependencies: [{ kind: "directive", type: i3.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i3.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: i4.IonButton, selector: "ion-button", inputs: ["buttonType", "color", "disabled", "download", "expand", "fill", "form", "href", "mode", "rel", "routerAnimation", "routerDirection", "shape", "size", "strong", "target", "type"] }, { kind: "component", type: i4.IonButtons, selector: "ion-buttons", inputs: ["collapse"] }, { kind: "component", type: i4.IonCol, selector: "ion-col", inputs: ["offset", "offsetLg", "offsetMd", "offsetSm", "offsetXl", "offsetXs", "pull", "pullLg", "pullMd", "pullSm", "pullXl", "pullXs", "push", "pushLg", "pushMd", "pushSm", "pushXl", "pushXs", "size", "sizeLg", "sizeMd", "sizeSm", "sizeXl", "sizeXs"] }, { kind: "component", type: i4.IonContent, selector: "ion-content", inputs: ["color", "forceOverscroll", "fullscreen", "scrollEvents", "scrollX", "scrollY"] }, { kind: "component", type: i4.IonFab, selector: "ion-fab", inputs: ["activated", "edge", "horizontal", "vertical"] }, { kind: "component", type: i4.IonFabButton, selector: "ion-fab-button", inputs: ["activated", "closeIcon", "color", "disabled", "download", "href", "mode", "rel", "routerAnimation", "routerDirection", "show", "size", "target", "translucent", "type"] }, { kind: "component", type: i4.IonFooter, selector: "ion-footer", inputs: ["collapse", "mode", "translucent"] }, { kind: "component", type: i4.IonGrid, selector: "ion-grid", inputs: ["fixed"] }, { kind: "component", type: i4.IonIcon, selector: "ion-icon", inputs: ["color", "flipRtl", "icon", "ios", "lazy", "md", "mode", "name", "sanitize", "size", "src"] }, { kind: "component", type: i4.IonInfiniteScroll, selector: "ion-infinite-scroll", inputs: ["disabled", "position", "threshold"] }, { kind: "component", type: i4.IonInfiniteScrollContent, selector: "ion-infinite-scroll-content", inputs: ["loadingSpinner", "loadingText"] }, { kind: "component", type: i4.IonItem, selector: "ion-item", inputs: ["button", "color", "counter", "counterFormatter", "detail", "detailIcon", "disabled", "download", "fill", "href", "lines", "mode", "rel", "routerAnimation", "routerDirection", "shape", "target", "type"] }, { kind: "component", type: i4.IonLabel, selector: "ion-label", inputs: ["color", "mode", "position"] }, { kind: "component", type: i4.IonRefresher, selector: "ion-refresher", inputs: ["closeDuration", "disabled", "pullFactor", "pullMax", "pullMin", "snapbackDuration"] }, { kind: "component", type: i4.IonRefresherContent, selector: "ion-refresher-content", inputs: ["pullingIcon", "pullingText", "refreshingSpinner", "refreshingText"] }, { kind: "component", type: i4.IonRow, selector: "ion-row" }, { kind: "component", type: i4.IonSkeletonText, selector: "ion-skeleton-text", inputs: ["animated"] }, { kind: "component", type: i4.IonText, selector: "ion-text", inputs: ["color", "mode"] }, { kind: "component", type: i4.IonTitle, selector: "ion-title", inputs: ["color", "size"] }, { kind: "directive", type: i5.TranslateDirective, selector: "[translate],[ngx-translate]", inputs: ["translate", "translateParams"] }, { kind: "directive", type: i2.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i2.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i2.NumberValueAccessor, selector: "input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]" }, { kind: "directive", type: i2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i2.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i2.RequiredValidator, selector: ":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]", inputs: ["required"] }, { kind: "directive", type: i2.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { kind: "directive", type: i2.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i2.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "component", type: i6.MatTable, selector: "mat-table, table[mat-table]", exportAs: ["matTable"] }, { kind: "directive", type: i6.MatHeaderCellDef, selector: "[matHeaderCellDef]" }, { kind: "directive", type: i6.MatHeaderRowDef, selector: "[matHeaderRowDef]", inputs: ["matHeaderRowDef", "matHeaderRowDefSticky"] }, { kind: "directive", type: i6.MatColumnDef, selector: "[matColumnDef]", inputs: ["sticky", "matColumnDef"] }, { kind: "directive", type: i6.MatCellDef, selector: "[matCellDef]" }, { kind: "directive", type: i6.MatRowDef, selector: "[matRowDef]", inputs: ["matRowDefColumns", "matRowDefWhen"] }, { kind: "directive", type: i6.MatHeaderCell, selector: "mat-header-cell, th[mat-header-cell]" }, { kind: "directive", type: i6.MatCell, selector: "mat-cell, td[mat-cell]" }, { kind: "component", type: i6.MatHeaderRow, selector: "mat-header-row, tr[mat-header-row]", exportAs: ["matHeaderRow"] }, { kind: "component", type: i6.MatRow, selector: "mat-row, tr[mat-row]", exportAs: ["matRow"] }, { kind: "directive", type: i7.MatSort, selector: "[matSort]", inputs: ["matSortDisabled", "matSortActive", "matSortStart", "matSortDirection", "matSortDisableClear"], outputs: ["matSortChange"], exportAs: ["matSort"] }, { kind: "component", type: i7.MatSortHeader, selector: "[mat-sort-header]", inputs: ["disabled", "mat-sort-header", "arrowPosition", "start", "sortActionDescription", "disableClear"], exportAs: ["matSortHeader"] }, { kind: "component", type: i8.MatPaginator, selector: "mat-paginator", inputs: ["disabled", "color", "pageIndex", "length", "pageSize", "pageSizeOptions", "hidePageSize", "showFirstLastButtons", "selectConfig"], outputs: ["page"], exportAs: ["matPaginator"] }, { kind: "component", type: i9.MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i9.MatLabel, selector: "mat-label" }, { kind: "directive", type: i9.MatError, selector: "mat-error, [matError]", inputs: ["id"] }, { kind: "directive", type: i9.MatPrefix, selector: "[matPrefix], [matIconPrefix], [matTextPrefix]", inputs: ["matTextPrefix"] }, { kind: "directive", type: i9.MatSuffix, selector: "[matSuffix], [matIconSuffix], [matTextSuffix]", inputs: ["matTextSuffix"] }, { kind: "directive", type: i10.MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly"], exportAs: ["matInput"] }, { kind: "component", type: i11.MatCheckbox, selector: "mat-checkbox", inputs: ["aria-label", "aria-labelledby", "aria-describedby", "id", "required", "labelPosition", "name", "value", "disableRipple", "tabIndex", "color", "checked", "disabled", "indeterminate"], outputs: ["change", "indeterminateChange"], exportAs: ["matCheckbox"] }, { kind: "component", type: i12.MatExpansionPanel, selector: "mat-expansion-panel", inputs: ["disabled", "expanded", "hideToggle", "togglePosition"], outputs: ["opened", "closed", "expandedChange", "afterExpand", "afterCollapse"], exportAs: ["matExpansionPanel"] }, { kind: "directive", type: i12.MatExpansionPanelActionRow, selector: "mat-action-row" }, { kind: "component", type: i13.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "component", type: i14.MatIconButton, selector: "button[mat-icon-button]", exportAs: ["matButton"] }, { kind: "component", type: i15.MatSelect, selector: "mat-select", inputs: ["disabled", "disableRipple", "tabIndex", "aria-describedby", "panelClass", "hideSingleSelectionIndicator", "placeholder", "required", "multiple", "disableOptionCentering", "compareWith", "value", "aria-label", "aria-labelledby", "errorStateMatcher", "typeaheadDebounceInterval", "sortComparator", "id", "panelWidth"], outputs: ["openedChange", "opened", "closed", "selectionChange", "valueChange"], exportAs: ["matSelect"] }, { kind: "component", type: i16.MatOption, selector: "mat-option", inputs: ["value", "id", "disabled"], outputs: ["onSelectionChange"], exportAs: ["matOption"] }, { kind: "directive", type: i17.MatBadge, selector: "[matBadge]", inputs: ["matBadgeColor", "matBadgeOverlap", "matBadgeDisabled", "matBadgePosition", "matBadge", "matBadgeDescription", "matBadgeSize", "matBadgeHidden"] }, { kind: "directive", type: i18.CdkTrapFocus, selector: "[cdkTrapFocus]", inputs: ["cdkTrapFocus", "cdkTrapFocusAutoCapture"], exportAs: ["cdkTrapFocus"] }, { kind: "component", type: i19.MatAutocompleteField, selector: "mat-autocomplete-field", inputs: ["equals", "logPrefix", "formControl", "formControlName", "floatLabel", "appearance", "placeholder", "suggestFn", "required", "mobile", "clearable", "debounceTime", "displayWith", "displayAttributes", "displayColumnSizes", "displayColumnNames", "highlightAccent", "showAllOnFocus", "showPanelOnFocus", "autofocus", "config", "i18nPrefix", "noResultMessage", "class", "panelWidth", "matAutocompletePosition", "multiple", "fetchMoreThreshold", "suggestLengthThreshold", "showLoadingSpinner", "debug", "showSearchBar", "stickySearchBar", "applyImplicitValue", "filter", "readonly", "tabindex", "items"], outputs: ["click", "blur", "focus", "dropButtonClick", "keydown.escape", "keyup.enter"] }, { kind: "directive", type: i20.AutofocusDirective, selector: "[autofocus], input[appAutofocus]", inputs: ["appAutofocus", "autofocusDelay"] }, { kind: "directive", type: i21.AutoTitleDirective, selector: "[appAutoTitle]" }, { kind: "component", type: i22.ToolbarComponent, selector: "app-toolbar", inputs: ["progressBarMode", "title", "color", "class", "backHref", "defaultBackHref", "hasValidate", "hasClose", "hasSearch", "canGoBack", "canShowMenu"], outputs: ["onValidate", "onClose", "onValidateAndClose", "onBackClick", "onSearch"] }, { kind: "component", type: i23.FormButtonsBarComponent, selector: "app-form-buttons-bar", inputs: ["disabled", "disabledCancel", "classList", "saveButtonColor", "backText", "cancelText", "nextText", "showBack", "showCancel", "showNext", "showSave", "showSaveAndClose", "showSaveAndNext"], outputs: ["onCancel", "onSave", "onNext", "onBack", "onSaveAndClose", "onSaveAndNext"] }, { kind: "component", type: i24.ActionsColumnComponent, selector: "app-actions-column", inputs: ["stickyEnd", "canCancel", "canConfirm", "canDelete", "canBackward", "canForward", "canConfirmAndAdd", "dirtyIcon", "optionsTitle", "class", "cellTemplate"], outputs: ["optionsClick", "cancelOrDeleteClick", "confirmEditCreateClick", "confirmAndAddClick", "backward", "forward"] }, { kind: "directive", type: i2.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "pipe", type: i3.AsyncPipe, name: "async" }, { kind: "pipe", type: i5.TranslatePipe, name: "translate" }, { kind: "pipe", type: i25.DateFormatPipe, name: "dateFormat" }, { kind: "pipe", type: i26.NumberFormatPipe, name: "numberFormat" }, { kind: "pipe", type: i27.ArrayLengthPipe, name: "isArrayLength" }, { kind: "pipe", type: i28.ReferentialToStringPipe, name: "referentialToString" }, { kind: "pipe", type: i29.FormGetValuePipe, name: "formGetValue" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
268
268
  }
269
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: TableTestPage, decorators: [{
269
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.0.6", ngImport: i0, type: TableTestPage, decorators: [{
270
270
  type: Component,
271
271
  args: [{ selector: 'app-table-testing', providers: [
272
272
  {
@@ -276,8 +276,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImpo
276
276
  {
277
277
  provide: AppTable, useExisting: forwardRef(() => TableTestPage),
278
278
  }
279
- ], changeDetection: ChangeDetectionStrategy.OnPush, template: "<app-toolbar color=\"primary\" [canGoBack]=\"true\"\n [hasValidate]=\"!(loadingSubject|async) && dirty\"\n (onValidate)=\"save()\"\n [backHref]=\"'/testing'\">\n <ion-title>Table (click to edit)</ion-title>\n <ion-buttons slot=\"end\">\n\n\n <ng-container *ngIf=\"!selection.hasValue(); else hasSelection\">\n\n <input matInput type=\"number\" step=\"1\" style=\"color:black; width: 50px;\" [(ngModel)]=\"rowHeight\">\n\n <!-- Add -->\n <button mat-icon-button\n *ngIf=\"canEdit && !mobile\"\n [title]=\"'COMMON.BTN_ADD'|translate\"\n (click)=\"addRow()\">\n <mat-icon>add</mat-icon>\n </button>\n\n <!-- reset filter -->\n <button mat-icon-button (click)=\"resetFilter()\"\n *ngIf=\"filterCriteriaCount\">\n <mat-icon color=\"accent\">filter_list_alt</mat-icon>\n <mat-icon class=\"icon-secondary\" style=\"left: 16px; top: 5px; font-weight: bold;\">close</mat-icon>\n </button>\n\n <!-- show filter -->\n <button mat-icon-button (click)=\"filterExpansionPanel.toggle()\">\n <mat-icon *ngIf=\"filterCriteriaCount; else emptyFilter\"\n [matBadge]=\"filterCriteriaCount\"\n matBadgeColor=\"accent\"\n matBadgeSize=\"small\"\n matBadgePosition=\"above after\">filter_list_alt\n </mat-icon>\n <ng-template #emptyFilter>\n <mat-icon>filter_list_alt</mat-icon>\n </ng-template>\n </button>\n\n <!-- save -->\n <button mat-icon-button *ngIf=\"mobile\"\n [disabled]=\"!(dirtySubject|async)\"\n (click)=\"save()\">\n <mat-icon>save</mat-icon>\n </button>\n\n <!-- start/stop timer to auto-load data -->\n <ion-button *ngIf=\"!timer\" (click)=\"startTimer()\">Start reload</ion-button>\n <ion-button *ngIf=\"timer\" (click)=\"stopTimer()\" color=\"accent\">Stop reload</ion-button>\n </ng-container>\n\n <!-- if row selection -->\n <ng-template #hasSelection>\n\n <!-- delete -->\n <button mat-icon-button\n *ngIf=\"canEdit\" [title]=\"'COMMON.BTN_DELETE'|translate\"\n (click)=\"deleteSelection($event)\">\n <mat-icon>delete</mat-icon>\n </button>\n\n <!-- duplicate -->\n <button mat-icon-button\n *ngIf=\"canEdit && selection.selected | isArrayLength: {equals: 1}\"\n [title]=\"'COMMON.BTN_DUPLICATE'|translate\"\n (click)=\"duplicateRow($event, selection.selected[0])\">\n <mat-icon>file_copy</mat-icon>\n </button>\n </ng-template>\n </ion-buttons>\n</app-toolbar>\n<ion-content class=\"ion-no-padding\">\n\n <ion-refresher slot=\"fixed\" *ngIf=\"mobile\" (ionRefresh)=\"doRefresh($event)\">\n <ion-refresher-content></ion-refresher-content>\n </ion-refresher>\n\n <!-- error -->\n <ion-item *ngIf=\"mobile && error\" lines=\"none\" @slideUpDownAnimation>\n <ion-icon color=\"danger\" slot=\"start\" name=\"alert-circle\"></ion-icon>\n <ion-label color=\"danger\" class=\"error\" [innerHTML]=\"error|translate\"></ion-label>\n </ion-item>\n\n <!-- search -->\n <mat-expansion-panel #filterExpansionPanel class=\"filter-panel filter-panel-floating\">\n <form class=\"form-container ion-padding-top\" [formGroup]=\"filterForm\" (ngSubmit)=\"applyFilterAndClosePanel($event)\">\n\n <ion-grid>\n <ion-row>\n <ion-col>\n <!-- search text -->\n <mat-form-field>\n <mat-label>{{'TABLE.TESTING.SEARCH_TEXT'|translate}}</mat-label>\n <ion-icon matPrefix name=\"search\"></ion-icon>\n <input matInput\n formControlName=\"searchText\"\n autocomplete=\"off\">\n <button mat-icon-button matSuffix tabindex=\"-1\"\n type=\"button\"\n (click)=\"clearControlValue($event, filterForm.controls.searchText)\"\n [hidden]=\"filterForm.controls.searchText.disabled || !filterForm.controls.searchText.value\">\n <mat-icon>close</mat-icon>\n </button>\n </mat-form-field>\n </ion-col>\n </ion-row>\n </ion-grid>\n </form>\n\n <mat-action-row>\n <!-- Counter -->\n <ion-label [hidden]=\"(loadingSubject|async) || filterForm.dirty\"\n [color]=\"empty && 'danger'\"\n class=\"ion-padding\">\n {{ (totalRowCount ? 'COMMON.RESULT_COUNT' : 'COMMON.NO_RESULT') | translate: {\n count: (totalRowCount |\n numberFormat)\n } }}\n </ion-label>\n\n <div class=\"toolbar-spacer\"></div>\n\n <!-- Close panel -->\n <ion-button mat-button fill=\"clear\" color=\"dark\"\n (click)=\"filterExpansionPanel.close()\"\n [disabled]=\"loadingSubject|async\">\n <ion-text translate>COMMON.BTN_CLOSE</ion-text>\n </ion-button>\n\n <!-- Search button -->\n <ion-button mat-button\n [color]=\"filterForm.dirty ? 'tertiary' : 'dark'\"\n [fill]=\"filterForm.dirty ? 'solid' : 'clear'\"\n (click)=\"applyFilterAndClosePanel($event)\">\n <ion-text translate>COMMON.BTN_APPLY</ion-text>\n </ion-button>\n </mat-action-row>\n </mat-expansion-panel>\n\n <!-- table -->\n <div [class.table-container]=\"!enableInfiniteScroll\">\n <table #table mat-table matSort matSortDisableClear\n [dataSource]=\"dataSource\"\n [matSortActive]=\"defaultSortBy\"\n [matSortDirection]=\"defaultSortDirection\"\n [trackBy]=\"trackByFn\"\n [style.--mat-row-height]=\"rowHeight + 'px'\">\n >\n\n <!-- group header cells -->\n\n <ng-container matColumnDef=\"top-start\" [sticky]=\"useSticky\">\n <th mat-header-cell *matHeaderCellDef [class.cdk-visually-hidden]=\"!canEdit\" [attr.colspan]=\"2\">\n <!-- start spacer -->\n </th>\n </ng-container>\n\n <ng-container matColumnDef=\"group-1\">\n <th mat-header-cell *matHeaderCellDef [attr.colspan]=\"3\" style=\"background-color: whitesmoke; margin-bottom: -1px;\">\n <ion-label translate>{{i18nColumnPrefix + 'GROUP_1'}}</ion-label>\n </th>\n </ng-container>\n\n <ng-container matColumnDef=\"group-2\">\n <th mat-header-cell *matHeaderCellDef [attr.colspan]=\"3\">\n <ion-label translate>{{i18nColumnPrefix + 'GROUP_2'}}</ion-label>\n </th>\n </ng-container>\n\n <ng-container matColumnDef=\"top-end\" >\n <th mat-header-cell *matHeaderCellDef>\n <!-- end spacer -->\n </th>\n </ng-container>\n\n <ng-container matColumnDef=\"select\" [sticky]=\"useSticky\" [class.mat-column-sticky]=\"useSticky\">\n <th mat-header-cell *matHeaderCellDef [class.cdk-visually-hidden]=\"!canEdit\">\n <mat-checkbox (change)=\"$event ? masterToggle() : null\" [checked]=\"selection.hasValue() && isAllSelected()\"\n [indeterminate]=\"selection.hasValue() && !isAllSelected()\">\n </mat-checkbox>\n </th>\n <td mat-cell *matCellDef=\"let row\" [class.cdk-visually-hidden]=\"!canEdit\">\n <mat-checkbox (change)=\"$event ? selection.toggle(row) : null\" [checked]=\"selection.isSelected(row)\">\n </mat-checkbox>\n </td>\n </ng-container>\n\n <!-- Id column -->\n <ng-container matColumnDef=\"id\" [sticky]=\"useSticky\" [class.mat-column-sticky]=\"useSticky\">\n <th mat-header-cell *matHeaderCellDef mat-sort-header>\n <ion-label>#</ion-label>\n </th>\n <td mat-cell *matCellDef=\"let row\">{{ row.currentData?.id }}</td>\n </ng-container>\n\n <!-- Label column -->\n <ng-container matColumnDef=\"label\">\n <th mat-header-cell *matHeaderCellDef mat-sort-header>\n <ion-label translate>TABLE.TESTING.LABEL</ion-label>\n </th>\n <td mat-cell *matCellDef=\"let row\" (click)=\"focusColumn='label'\">\n <mat-form-field *ngIf=\"row.editing; else readonlyCell\" [hideRequiredMarker]=\"false\" [floatLabel]=\"'always'\">\n <input matInput autocomplete=\"off\"\n [formControl]=\"row.validator.controls['label']\"\n [placeholder]=\"'TABLE.TESTING.LABEL'|translate\"\n [appAutofocus]=\"row.editing && focusColumn === 'label'\"\n [readonly]=\"!row.editing\">\n <mat-error *ngIf=\"row.validator.controls['label'].hasError('required')\" translate>ERROR.FIELD_REQUIRED</mat-error>\n </mat-form-field>\n <ng-template #readonlyCell>\n <ion-label appAutoTitle>\n {{ (row.validator | formGetValue : 'label')}}\n </ion-label>\n </ng-template>\n </td>\n </ng-container>\n\n <!-- Name column -->\n <ng-container matColumnDef=\"name\">\n <th mat-header-cell *matHeaderCellDef mat-sort-header>\n <ion-label translate>TABLE.TESTING.NAME</ion-label>\n </th>\n <td mat-cell *matCellDef=\"let row\"\n (click)=\"focusColumn='name'\">\n <mat-form-field *ngIf=\"row.editing; else readonlyCell\">\n <input matInput\n [formControl]=\"row.validator?.controls.name\" [placeholder]=\"'TABLE.TESTING.NAME'|translate\"\n [appAutofocus]=\"row.editing && focusColumn === 'name'\"\n >\n <mat-error *ngIf=\"row.validator?.controls.name.hasError('required')\" translate>ERROR.FIELD_REQUIRED</mat-error>\n </mat-form-field>\n <ng-template #readonlyCell>\n <ion-label appAutoTitle>\n {{ (row.validator | formGetValue : 'name')}}\n </ion-label>\n </ng-template>\n </td>\n </ng-container>\n\n <!-- Level column -->\n <ng-container matColumnDef=\"levelId\">\n <th mat-header-cell *matHeaderCellDef mat-sort-header>\n <ion-label translate>TABLE.TESTING.LEVEL_ID</ion-label>\n </th>\n <td mat-cell *matCellDef=\"let row\" (click)=\"focusColumn='levelId'\">\n <mat-autocomplete-field *ngIf=\"row.editing; else readonlyCell\"\n [formControl]=\"row.validator.controls.levelId\"\n [placeholder]=\"'TABLE.TESTING.LEVEL_ID'|translate\"\n floatLabel=\"never\"\n [config]=\"autocompleteFields.level\"\n [readonly]=\"!row.editing\"\n [autofocus]=\"row.editing && focusColumn === 'levelId'\"\n [required]=\"true\">\n </mat-autocomplete-field>\n <ng-template #readonlyCell>\n <ion-label appAutoTitle>\n {{ (row.validator | formGetValue : 'levelId'|referentialToString: autocompleteFields.level.attributes)}}\n </ion-label>\n </ng-template>\n </td>\n </ng-container>\n\n <!-- Status column -->\n <ng-container matColumnDef=\"statusId\">\n <th mat-header-cell *matHeaderCellDef>\n <span translate>USER.STATUS</span>\n </th>\n <td mat-cell *matCellDef=\"let row\" [class.mat-form-field-disabled]=\"!row.editing\">\n <mat-form-field>\n <mat-select [formControl]=\"row.validator.controls['statusId']\" [placeholder]=\"i18nColumnPrefix + 'STATUS_ID'|translate\">\n <mat-option *ngFor=\"let item of statusList\" [value]=\"item.id\">\n <mat-icon><ion-icon [name]=\"item.icon\"></ion-icon></mat-icon>\n <mat-label>{{ item.label |translate }}</mat-label>\n </mat-option>\n </mat-select>\n <mat-error *ngIf=\"row.validator.controls['statusId'].hasError('required')\" translate>ERROR.FIELD_REQUIRED</mat-error>\n </mat-form-field>\n </td>\n </ng-container>\n\n <!-- Enum column -->\n <!-- NOTE : Never used in table -->\n<!-- <ng-container matColumnDef=\"values\">-->\n<!-- <th mat-header-cell *matHeaderCellDef>-->\n<!-- <span translate>Enums</span>-->\n<!-- </th>-->\n<!-- <td mat-cell *matCellDef=\"let row\" [class.mat-form-field-disabled]=\"!row.editing\">-->\n<!-- <app-form-field-->\n<!-- [formControl]=\"row.validator|formGetControl:'properties.values'\"-->\n<!-- [definition]=\"columnDefinitions['values']\"-->\n<!-- ></app-form-field>-->\n<!-- </td>-->\n<!-- </ng-container>-->\n\n <!-- Creation date column -->\n <ng-container matColumnDef=\"updateDate\">\n <th mat-header-cell *matHeaderCellDef mat-sort-header>\n <ion-label translate>TABLE.TESTING.UPDATE_DATE</ion-label>\n </th>\n <td mat-cell *matCellDef=\"let row\" class=\"mat-form-field-disabled\">\n <ion-text color=\"medium\" *ngIf=\"row.id!==-1\">\n <small>\n {{ row.validator| formGetValue: 'creationDate' | dateFormat: {time: true} }}\n </small>\n </ion-text>\n </td>\n </ng-container>\n\n <!-- Comment column -->\n <ng-container matColumnDef=\"comments\">\n <th mat-header-cell *matHeaderCellDef>\n <ion-label translate>TABLE.TESTING.COMMENTS</ion-label>\n </th>\n <td mat-cell *matCellDef=\"let row\">\n <mat-form-field *ngIf=\"row.editing; else iconComment\">\n <!--<textarea matInput [formControl]=\"row.validator?.controls.comments\"\n [placeholder]=\"'TABLE.TESTING.COMMENTS'|translate\"\n [readonly]=\"!row.editing\"></textarea>-->\n\n <input type=\"text\" matInput [formControl]=\"row.validator?.controls.comments\"\n [placeholder]=\"'TABLE.TESTING.COMMENTS'|translate\"\n [readonly]=\"!row.editing\">\n </mat-form-field>\n\n <ng-template #iconComment>\n <mat-icon class=\"comment\"\n *ngIf=\"row.validator?.controls.comments.value\"\n [title]=\"row.validator?.controls.comments.value\"></mat-icon>\n </ng-template>\n </td>\n </ng-container>\n\n <!-- Actions buttons column -->\n <app-actions-column [stickyEnd]=\"true\" [canCancel]=\"false\"\n (optionsClick)=\"openSelectColumnsModal($event)\"\n (cancelOrDeleteClick)=\"cancelOrDelete($event.event, $event.row)\"\n (confirmAndAddClick)=\"confirmAndAdd($event.event, $event.row)\"\n (backward)=\"confirmAndBackward($event.event, $event.row)\"\n (forward)=\"confirmAndForward($event.event, $event.row)\"\n [cellTemplate]=\"cellInjection\">\n\n <!-- cell injection-->\n <ng-template #cellInjection let-row>\n <span *ngIf=\"row.editing && !row.validator.dirty\">-</span>\n </ng-template>\n\n </app-actions-column>\n\n <tr mat-header-row *matHeaderRowDef=\"groupColumns;\" class=\"mat-toolbar\"></tr>\n <tr mat-header-row *matHeaderRowDef=\"displayedColumns; sticky: true\"></tr>\n <tr mat-row *matRowDef=\"let row; columns: displayedColumns;\"\n [class.mat-row-selected]=\"row.editing\"\n [class.mat-row-error]=\"row.validator?.invalid\"\n [class.mat-row-disabled]=\"!row.editing\"\n [class.mat-row-dirty]=\"row.validator?.dirty\"\n (click)=\"clickRow($event, row)\"\n (keydown.escape)=\"escapeEditingRow($event)\"\n [cdkTrapFocus]=\"row.validator?.invalid\"></tr>\n </table>\n\n <ng-container *ngIf=\"loadingSubject|async; else noResult\">\n <ion-item>\n <ion-skeleton-text animated></ion-skeleton-text>\n </ion-item>\n </ng-container>\n\n <ng-template #noResult>\n <ion-item *ngIf=\"totalRowCount === 0\">\n <ion-text color=\"danger\" class=\"text-italic\" translate>COMMON.NO_RESULT</ion-text>\n </ion-item>\n </ng-template>\n\n <ion-infinite-scroll *ngIf=\"enableInfiniteScroll\"\n [threshold]=\"mobile ? '10%' : '2%'\" position=\"bottom\"\n (ionInfinite)=\"fetchMore($event)\">\n <ion-infinite-scroll-content\n loadingSpinner=\"circles\"\n [loadingText]=\"'COMMON.LOADING_DOTS'|translate\">\n </ion-infinite-scroll-content>\n </ion-infinite-scroll>\n </div>\n</ion-content>\n\n<ion-footer>\n <!-- Paginator -->\n <mat-paginator *ngIf=\"!enableInfiniteScroll\"\n [length]=\"totalRowCount\" [pageSize]=\"defaultPageSize\" [pageSizeOptions]=\"defaultPageSizeOptions\"\n class=\"mat-paginator-footer\"\n showFirstLastButtons>\n </mat-paginator>\n\n <app-form-buttons-bar *ngIf=\"canEdit && !mobile\"\n (onCancel)=\"load()\"\n (onSave)=\"save()\"\n [disabled]=\"(loadingSubject|async) || !dirty\">\n <!-- error -->\n <ion-item *ngIf=\"error$|async\" lines=\"none\">\n <ion-icon color=\"danger\" slot=\"start\" name=\"alert-circle\"></ion-icon>\n <ion-label color=\"danger\" [innerHTML]=\"error|translate\"></ion-label>\n </ion-item>\n </app-form-buttons-bar>\n</ion-footer>\n\n<ion-fab slot=\"fixed\" vertical=\"bottom\" horizontal=\"end\"\n *ngIf=\"canEdit && mobile\">\n <ion-fab-button color=\"tertiary\" (click)=\"addRow($event)\">\n <ion-icon name=\"add\"></ion-icon>\n </ion-fab-button>\n</ion-fab>\n", styles: [".table-container .mat-mdc-table{--mat-column-actions-min-width: 62px;--mat-column-actions-max-width: 62px}.table-container .mat-mdc-table .mat-row-selected{padding:3px}.table-container .mat-mdc-table .mat-column-select{min-width:30px}.table-container .mat-mdc-table .mat-column-id{min-width:30px;max-width:30px}.table-container .mat-mdc-table .mat-column-label,.table-container .mat-mdc-table .mat-column-name,.table-container .mat-mdc-table .mat-column-levelId,.table-container .mat-mdc-table .mat-column-statusId{min-width:150px}.table-container .mat-mdc-table .mat-column-comments{min-width:100px;max-width:100px}.table-container .mat-mdc-table .mat-column-updateDate{min-width:110px;max-width:110px}\n"] }]
280
- }], ctorParameters: function () { return [{ type: i0.Injector }, { type: i1.AppValidatorService }, { type: i2.UntypedFormBuilder }, { type: i0.ChangeDetectorRef }]; }, propDecorators: { enableInfiniteScroll: [{
279
+ ], changeDetection: ChangeDetectionStrategy.OnPush, template: "<app-toolbar color=\"primary\" [canGoBack]=\"true\"\n [hasValidate]=\"!(loadingSubject|async) && dirty\"\n (onValidate)=\"save()\"\n [backHref]=\"'/testing'\">\n <ion-title>Table (click to edit)</ion-title>\n <ion-buttons slot=\"end\">\n\n\n <ng-container *ngIf=\"!selection.hasValue(); else hasSelection\">\n\n <input matInput type=\"number\" step=\"1\" style=\"color:black; width: 50px;\" [(ngModel)]=\"rowHeight\">\n\n <!-- Add -->\n <button mat-icon-button\n *ngIf=\"canEdit && !mobile\"\n [title]=\"'COMMON.BTN_ADD'|translate\"\n (click)=\"addRow()\">\n <mat-icon>add</mat-icon>\n </button>\n\n <!-- reset filter -->\n <button mat-icon-button (click)=\"resetFilter()\"\n *ngIf=\"filterCriteriaCount\">\n <mat-icon color=\"accent\">filter_list_alt</mat-icon>\n <mat-icon class=\"icon-secondary\" style=\"left: 16px; top: 5px; font-weight: bold;\">close</mat-icon>\n </button>\n\n <!-- show filter -->\n <button mat-icon-button (click)=\"filterExpansionPanel.toggle()\">\n <mat-icon *ngIf=\"filterCriteriaCount; else emptyFilter\"\n [matBadge]=\"filterCriteriaCount\"\n matBadgeColor=\"accent\"\n matBadgeSize=\"small\"\n matBadgePosition=\"above after\">filter_list_alt\n </mat-icon>\n <ng-template #emptyFilter>\n <mat-icon>filter_list_alt</mat-icon>\n </ng-template>\n </button>\n\n <!-- save -->\n <button mat-icon-button *ngIf=\"mobile\"\n [disabled]=\"!(dirtySubject|async)\"\n (click)=\"save()\">\n <mat-icon>save</mat-icon>\n </button>\n\n <!-- start/stop timer to auto-load data -->\n <ion-button *ngIf=\"!timer\" (click)=\"startTimer()\">Start reload</ion-button>\n <ion-button *ngIf=\"timer\" (click)=\"stopTimer()\" color=\"accent\">Stop reload</ion-button>\n </ng-container>\n\n <!-- if row selection -->\n <ng-template #hasSelection>\n\n <!-- delete -->\n <button mat-icon-button\n *ngIf=\"canEdit\" [title]=\"'COMMON.BTN_DELETE'|translate\"\n (click)=\"deleteSelection($event)\">\n <mat-icon>delete</mat-icon>\n </button>\n\n <!-- duplicate -->\n <button mat-icon-button\n *ngIf=\"canEdit && selection.selected | isArrayLength: {equals: 1}\"\n [title]=\"'COMMON.BTN_DUPLICATE'|translate\"\n (click)=\"duplicateRow($event, selection.selected[0])\">\n <mat-icon>file_copy</mat-icon>\n </button>\n </ng-template>\n </ion-buttons>\n</app-toolbar>\n<ion-content class=\"ion-no-padding\">\n\n <ion-refresher slot=\"fixed\" *ngIf=\"mobile\" (ionRefresh)=\"doRefresh($event)\">\n <ion-refresher-content></ion-refresher-content>\n </ion-refresher>\n\n <!-- error -->\n <ion-item *ngIf=\"mobile && error\" lines=\"none\" @slideUpDownAnimation>\n <ion-icon color=\"danger\" slot=\"start\" name=\"alert-circle\"></ion-icon>\n <ion-label color=\"danger\" class=\"error\" [innerHTML]=\"error|translate\"></ion-label>\n </ion-item>\n\n <!-- search -->\n <mat-expansion-panel #filterExpansionPanel class=\"filter-panel filter-panel-floating\">\n <form class=\"form-container ion-padding-top\" [formGroup]=\"filterForm\" (ngSubmit)=\"applyFilterAndClosePanel($event)\">\n\n <ion-grid>\n <ion-row>\n <ion-col>\n <!-- search text -->\n <mat-form-field>\n <mat-label>{{'TABLE.TESTING.SEARCH_TEXT'|translate}}</mat-label>\n <ion-icon matPrefix name=\"search\"></ion-icon>\n <input matInput\n formControlName=\"searchText\"\n autocomplete=\"off\">\n <button mat-icon-button matSuffix tabindex=\"-1\"\n type=\"button\"\n (click)=\"clearControlValue($event, filterForm.controls.searchText)\"\n [hidden]=\"filterForm.controls.searchText.disabled || !filterForm.controls.searchText.value\">\n <mat-icon>close</mat-icon>\n </button>\n </mat-form-field>\n </ion-col>\n </ion-row>\n </ion-grid>\n </form>\n\n <mat-action-row>\n <!-- Counter -->\n <ion-label [hidden]=\"(loadingSubject|async) || filterForm.dirty\"\n [color]=\"empty && 'danger'\"\n class=\"ion-padding\">\n {{ (totalRowCount ? 'COMMON.RESULT_COUNT' : 'COMMON.NO_RESULT') | translate: {\n count: (totalRowCount |\n numberFormat)\n } }}\n </ion-label>\n\n <div class=\"toolbar-spacer\"></div>\n\n <!-- Close panel -->\n <ion-button mat-button fill=\"clear\" color=\"dark\"\n (click)=\"filterExpansionPanel.close()\"\n [disabled]=\"loadingSubject|async\">\n <ion-text translate>COMMON.BTN_CLOSE</ion-text>\n </ion-button>\n\n <!-- Search button -->\n <ion-button mat-button\n [color]=\"filterForm.dirty ? 'tertiary' : 'dark'\"\n [fill]=\"filterForm.dirty ? 'solid' : 'clear'\"\n (click)=\"applyFilterAndClosePanel($event)\">\n <ion-text translate>COMMON.BTN_APPLY</ion-text>\n </ion-button>\n </mat-action-row>\n </mat-expansion-panel>\n\n <!-- table -->\n <div [class.table-container]=\"!enableInfiniteScroll\">\n <table #table mat-table matSort matSortDisableClear\n [dataSource]=\"dataSource\"\n [matSortActive]=\"defaultSortBy\"\n [matSortDirection]=\"defaultSortDirection\"\n [trackBy]=\"trackByFn\"\n [style.--mat-row-height]=\"rowHeight + 'px'\">\n >\n\n <!-- group header cells -->\n\n <ng-container matColumnDef=\"top-start\" [sticky]=\"useSticky\">\n <th mat-header-cell *matHeaderCellDef [class.cdk-visually-hidden]=\"!canEdit\" [attr.colspan]=\"2\">\n <!-- start spacer -->\n </th>\n </ng-container>\n\n <ng-container matColumnDef=\"group-1\">\n <th mat-header-cell *matHeaderCellDef [attr.colspan]=\"3\" style=\"background-color: whitesmoke; margin-bottom: -1px;\">\n <ion-label translate>{{i18nColumnPrefix + 'GROUP_1'}}</ion-label>\n </th>\n </ng-container>\n\n <ng-container matColumnDef=\"group-2\">\n <th mat-header-cell *matHeaderCellDef [attr.colspan]=\"3\">\n <ion-label translate>{{i18nColumnPrefix + 'GROUP_2'}}</ion-label>\n </th>\n </ng-container>\n\n <ng-container matColumnDef=\"top-end\" >\n <th mat-header-cell *matHeaderCellDef>\n <!-- end spacer -->\n </th>\n </ng-container>\n\n <ng-container matColumnDef=\"select\" [sticky]=\"useSticky\" [class.mat-column-sticky]=\"useSticky\">\n <th mat-header-cell *matHeaderCellDef [class.cdk-visually-hidden]=\"!canEdit\">\n <mat-checkbox (change)=\"$event ? masterToggle() : null\" [checked]=\"selection.hasValue() && isAllSelected()\"\n [indeterminate]=\"selection.hasValue() && !isAllSelected()\">\n </mat-checkbox>\n </th>\n <td mat-cell *matCellDef=\"let row\" [class.cdk-visually-hidden]=\"!canEdit\">\n <mat-checkbox (click)=\"toggleSelectRow($event, row)\" [checked]=\"selection.isSelected(row)\">\n </mat-checkbox>\n </td>\n </ng-container>\n\n <!-- Id column -->\n <ng-container matColumnDef=\"id\" [sticky]=\"useSticky\" [class.mat-column-sticky]=\"useSticky\">\n <th mat-header-cell *matHeaderCellDef mat-sort-header>\n <ion-label>#</ion-label>\n </th>\n <td mat-cell *matCellDef=\"let row\">{{ row.currentData?.id }}</td>\n </ng-container>\n\n <!-- Label column -->\n <ng-container matColumnDef=\"label\">\n <th mat-header-cell *matHeaderCellDef mat-sort-header>\n <ion-label translate>TABLE.TESTING.LABEL</ion-label>\n </th>\n <td mat-cell *matCellDef=\"let row\" (click)=\"focusColumn='label'\">\n <mat-form-field *ngIf=\"row.editing; else readonlyCell\" [hideRequiredMarker]=\"false\">\n <input matInput autocomplete=\"off\"\n [formControl]=\"row.validator.controls['label']\"\n [placeholder]=\"'TABLE.TESTING.LABEL'|translate\"\n [appAutofocus]=\"row.editing && focusColumn === 'label'\"\n [readonly]=\"!row.editing\">\n <mat-error *ngIf=\"row.validator.controls['label'].hasError('required')\" translate>ERROR.FIELD_REQUIRED</mat-error>\n </mat-form-field>\n <ng-template #readonlyCell>\n <ion-label appAutoTitle>\n {{ (row.validator | formGetValue : 'label')}}\n </ion-label>\n </ng-template>\n </td>\n </ng-container>\n\n <!-- Name column -->\n <ng-container matColumnDef=\"name\">\n <th mat-header-cell *matHeaderCellDef mat-sort-header>\n <ion-label translate>TABLE.TESTING.NAME</ion-label>\n </th>\n <td mat-cell *matCellDef=\"let row\"\n (click)=\"focusColumn='name'\">\n <mat-form-field *ngIf=\"row.editing; else readonlyCell\">\n <input matInput\n [formControl]=\"row.validator?.controls.name\" [placeholder]=\"'TABLE.TESTING.NAME'|translate\"\n [appAutofocus]=\"row.editing && focusColumn === 'name'\"\n >\n <mat-error *ngIf=\"row.validator?.controls.name.hasError('required')\" translate>ERROR.FIELD_REQUIRED</mat-error>\n </mat-form-field>\n <ng-template #readonlyCell>\n <ion-label appAutoTitle>\n {{ (row.validator | formGetValue : 'name')}}\n </ion-label>\n </ng-template>\n </td>\n </ng-container>\n\n <!-- Level column -->\n <ng-container matColumnDef=\"levelId\">\n <th mat-header-cell *matHeaderCellDef mat-sort-header>\n <ion-label translate>TABLE.TESTING.LEVEL_ID</ion-label>\n </th>\n <td mat-cell *matCellDef=\"let row\" (click)=\"focusColumn='levelId'\">\n <mat-autocomplete-field *ngIf=\"row.editing; else readonlyCell\"\n [formControl]=\"row.validator.controls.levelId\"\n [placeholder]=\"'TABLE.TESTING.LEVEL_ID'|translate\"\n floatLabel=\"never\"\n [config]=\"autocompleteFields.level\"\n [readonly]=\"!row.editing\"\n [autofocus]=\"row.editing && focusColumn === 'levelId'\"\n [required]=\"true\">\n </mat-autocomplete-field>\n <ng-template #readonlyCell>\n <ion-label appAutoTitle>\n {{ (row.validator | formGetValue : 'levelId'|referentialToString: autocompleteFields.level.attributes)}}\n </ion-label>\n </ng-template>\n </td>\n </ng-container>\n\n <!-- Status column -->\n <ng-container matColumnDef=\"statusId\">\n <th mat-header-cell *matHeaderCellDef>\n <span translate>USER.STATUS</span>\n </th>\n <td mat-cell *matCellDef=\"let row\" [class.mat-form-field-disabled]=\"!row.editing\">\n <mat-form-field>\n <mat-select [formControl]=\"row.validator.controls['statusId']\" [placeholder]=\"i18nColumnPrefix + 'STATUS_ID'|translate\">\n <mat-option *ngFor=\"let item of statusList\" [value]=\"item.id\">\n <mat-icon><ion-icon [name]=\"item.icon\"></ion-icon></mat-icon>\n <mat-label>{{ item.label |translate }}</mat-label>\n </mat-option>\n </mat-select>\n <mat-error *ngIf=\"row.validator.controls['statusId'].hasError('required')\" translate>ERROR.FIELD_REQUIRED</mat-error>\n </mat-form-field>\n </td>\n </ng-container>\n\n <!-- Enum column -->\n <!-- NOTE : Never used in table -->\n<!-- <ng-container matColumnDef=\"values\">-->\n<!-- <th mat-header-cell *matHeaderCellDef>-->\n<!-- <span translate>Enums</span>-->\n<!-- </th>-->\n<!-- <td mat-cell *matCellDef=\"let row\" [class.mat-form-field-disabled]=\"!row.editing\">-->\n<!-- <app-form-field-->\n<!-- [formControl]=\"row.validator|formGetControl:'properties.values'\"-->\n<!-- [definition]=\"columnDefinitions['values']\"-->\n<!-- ></app-form-field>-->\n<!-- </td>-->\n<!-- </ng-container>-->\n\n <!-- Creation date column -->\n <ng-container matColumnDef=\"updateDate\">\n <th mat-header-cell *matHeaderCellDef mat-sort-header>\n <ion-label translate>TABLE.TESTING.UPDATE_DATE</ion-label>\n </th>\n <td mat-cell *matCellDef=\"let row\" class=\"mat-form-field-disabled\">\n <ion-text color=\"medium\" *ngIf=\"row.id!==-1\">\n <small>\n {{ row.validator| formGetValue: 'creationDate' | dateFormat: {time: true} }}\n </small>\n </ion-text>\n </td>\n </ng-container>\n\n <!-- Comment column -->\n <ng-container matColumnDef=\"comments\">\n <th mat-header-cell *matHeaderCellDef>\n <ion-label translate>TABLE.TESTING.COMMENTS</ion-label>\n </th>\n <td mat-cell *matCellDef=\"let row\">\n <mat-form-field *ngIf=\"row.editing; else iconComment\">\n <!--<textarea matInput [formControl]=\"row.validator?.controls.comments\"\n [placeholder]=\"'TABLE.TESTING.COMMENTS'|translate\"\n [readonly]=\"!row.editing\"></textarea>-->\n\n <input type=\"text\" matInput [formControl]=\"row.validator?.controls.comments\"\n [placeholder]=\"'TABLE.TESTING.COMMENTS'|translate\"\n [readonly]=\"!row.editing\">\n </mat-form-field>\n\n <ng-template #iconComment>\n <mat-icon class=\"comment\"\n *ngIf=\"row.validator?.controls.comments.value\"\n [title]=\"row.validator?.controls.comments.value\"></mat-icon>\n </ng-template>\n </td>\n </ng-container>\n\n <!-- Actions buttons column -->\n <app-actions-column [stickyEnd]=\"true\" [canCancel]=\"false\"\n (optionsClick)=\"openSelectColumnsModal($event)\"\n (cancelOrDeleteClick)=\"cancelOrDelete($event.event, $event.row)\"\n (confirmAndAddClick)=\"confirmAndAdd($event.event, $event.row)\"\n (backward)=\"confirmAndBackward($event.event, $event.row)\"\n (forward)=\"confirmAndForward($event.event, $event.row)\"\n [cellTemplate]=\"cellInjection\">\n\n <!-- cell injection-->\n <ng-template #cellInjection let-row>\n <span *ngIf=\"row.editing && !row.validator.dirty\">-</span>\n </ng-template>\n\n </app-actions-column>\n\n <tr mat-header-row *matHeaderRowDef=\"groupColumns;\" class=\"mat-toolbar\"></tr>\n <tr mat-header-row *matHeaderRowDef=\"displayedColumns; sticky: true\"></tr>\n <tr mat-row *matRowDef=\"let row; columns: displayedColumns;\"\n [class.mat-row-selected]=\"row.editing\"\n [class.mat-row-error]=\"row.validator?.invalid\"\n [class.mat-row-disabled]=\"!row.editing\"\n [class.mat-row-dirty]=\"row.validator?.dirty\"\n (click)=\"clickRow($event, row)\"\n (keydown.escape)=\"escapeEditingRow($event)\"\n [cdkTrapFocus]=\"row.validator?.invalid\"></tr>\n </table>\n\n <ng-container *ngIf=\"loadingSubject|async; else noResult\">\n <ion-item>\n <ion-skeleton-text animated></ion-skeleton-text>\n </ion-item>\n </ng-container>\n\n <ng-template #noResult>\n <ion-item *ngIf=\"totalRowCount === 0\">\n <ion-text color=\"danger\" class=\"text-italic\" translate>COMMON.NO_RESULT</ion-text>\n </ion-item>\n </ng-template>\n\n <ion-infinite-scroll *ngIf=\"enableInfiniteScroll\"\n [threshold]=\"mobile ? '10%' : '2%'\" position=\"bottom\"\n (ionInfinite)=\"fetchMore($event)\">\n <ion-infinite-scroll-content\n loadingSpinner=\"circles\"\n [loadingText]=\"'COMMON.LOADING_DOTS'|translate\">\n </ion-infinite-scroll-content>\n </ion-infinite-scroll>\n </div>\n</ion-content>\n\n<ion-footer>\n <!-- Paginator -->\n <mat-paginator *ngIf=\"!enableInfiniteScroll\"\n [length]=\"totalRowCount\" [pageSize]=\"defaultPageSize\" [pageSizeOptions]=\"defaultPageSizeOptions\"\n class=\"mat-paginator-footer\"\n showFirstLastButtons>\n </mat-paginator>\n\n <app-form-buttons-bar *ngIf=\"canEdit && !mobile\"\n (onCancel)=\"load()\"\n (onSave)=\"save()\"\n [disabled]=\"(loadingSubject|async) || !dirty\">\n <!-- error -->\n <ion-item *ngIf=\"error$|async\" lines=\"none\">\n <ion-icon color=\"danger\" slot=\"start\" name=\"alert-circle\"></ion-icon>\n <ion-label color=\"danger\" [innerHTML]=\"error|translate\"></ion-label>\n </ion-item>\n </app-form-buttons-bar>\n</ion-footer>\n\n<ion-fab slot=\"fixed\" vertical=\"bottom\" horizontal=\"end\"\n *ngIf=\"canEdit && mobile\">\n <ion-fab-button color=\"tertiary\" (click)=\"addRow($event)\">\n <ion-icon name=\"add\"></ion-icon>\n </ion-fab-button>\n</ion-fab>\n", styles: [".table-container .mat-mdc-table{--mat-column-actions-min-width: 62px;--mat-column-actions-max-width: 62px}.table-container .mat-mdc-table .mat-row-selected{padding:3px}.table-container .mat-mdc-table .mat-column-select{min-width:30px}.table-container .mat-mdc-table .mat-column-id{min-width:30px;max-width:30px}.table-container .mat-mdc-table .mat-column-label,.table-container .mat-mdc-table .mat-column-name,.table-container .mat-mdc-table .mat-column-levelId,.table-container .mat-mdc-table .mat-column-statusId{min-width:150px}.table-container .mat-mdc-table .mat-column-comments{min-width:100px;max-width:100px}.table-container .mat-mdc-table .mat-column-updateDate{min-width:110px;max-width:110px}\n"] }]
280
+ }], ctorParameters: () => [{ type: i0.Injector }, { type: i1.AppValidatorService }, { type: i2.UntypedFormBuilder }, { type: i0.ChangeDetectorRef }], propDecorators: { enableInfiniteScroll: [{
281
281
  type: Input
282
282
  }], useSticky: [{
283
283
  type: Input
@@ -288,4 +288,4 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImpo
288
288
  type: ViewChild,
289
289
  args: [IonInfiniteScroll]
290
290
  }] } });
291
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidGFibGUudGVzdGluZy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uLy4uLy4uL3NyYy9hcHAvY29yZS90YWJsZS90ZXN0aW5nL3RhYmxlLnRlc3RpbmcudHMiLCIuLi8uLi8uLi8uLi8uLi8uLi8uLi9zcmMvYXBwL2NvcmUvdGFibGUvdGVzdGluZy90YWJsZS50ZXN0aW5nLmh0bWwiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUVMLHVCQUF1QixFQUV2QixTQUFTLEVBQ1QsVUFBVSxFQUVWLEtBQUssRUFHTCxTQUFTLEVBQ1YsTUFBTSxlQUFlLENBQUM7QUFDdkIsT0FBTyxFQUFDLFFBQVEsRUFBQyxNQUFNLGdCQUFnQixDQUFDO0FBQ3hDLE9BQU8sRUFBQyxXQUFXLEVBQUUsVUFBVSxFQUFFLFVBQVUsRUFBQyxNQUFNLHdDQUF3QyxDQUFDO0FBQzNGLE9BQU8sRUFBQyxpQkFBaUIsRUFBQyxNQUFNLGdCQUFnQixDQUFDO0FBQ2pELE9BQU8sRUFBQyx1QkFBdUIsRUFBQyxNQUFNLG9DQUFvQyxDQUFDO0FBQzNFLE9BQU8sRUFBQyx1QkFBdUIsRUFBQyxNQUFNLHNEQUFzRCxDQUFDO0FBQzdGLE9BQU8sRUFBQyxtQkFBbUIsRUFBQyxNQUFNLCtDQUErQyxDQUFDO0FBRWxGLE9BQU8sRUFBQyxLQUFLLEVBQUUsUUFBUSxFQUFDLE1BQU0sMkJBQTJCLENBQUM7QUFDMUQsT0FBTyxFQUFDLG1CQUFtQixFQUFDLE1BQU0sdUJBQXVCLENBQUM7QUFDMUQsT0FBTyxFQUFDLGlCQUFpQixFQUFDLE1BQU0saURBQWlELENBQUM7QUFDbEYsT0FBTyxFQUFDLFlBQVksRUFBRSxNQUFNLEVBQUUsR0FBRyxFQUFDLE1BQU0sZ0JBQWdCLENBQUM7QUFDekQsT0FBTyxFQUFDLGlCQUFpQixFQUFDLE1BQU0sNkJBQTZCLENBQUM7QUFDOUQsT0FBTyxFQUFDLFNBQVMsRUFBQyxNQUFNLGlDQUFpQyxDQUFDO0FBQzFELE9BQU8s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QkFDaEU7cUJBQ0YsbUJBQ2dCLHVCQUF1QixDQUFDLE1BQU07a01Bb0J0QyxvQkFBb0I7c0JBQTVCLEtBQUs7Z0JBQ0csU0FBUztzQkFBakIsS0FBSztnQkFNd0Msb0JBQW9CO3NCQUFqRSxTQUFTO3VCQUFDLGlCQUFpQixFQUFFLEVBQUMsTUFBTSxFQUFFLElBQUksRUFBQztnQkFDZCxjQUFjO3NCQUEzQyxTQUFTO3VCQUFDLGlCQUFpQiIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7XG4gIEFmdGVyVmlld0luaXQsXG4gIENoYW5nZURldGVjdGlvblN0cmF0ZWd5LFxuICBDaGFuZ2VEZXRlY3RvclJlZixcbiAgQ29tcG9uZW50LFxuICBmb3J3YXJkUmVmLFxuICBJbmplY3RvcixcbiAgSW5wdXQsXG4gIE9uRGVzdHJveSxcbiAgT25Jbml0LFxuICBWaWV3Q2hpbGRcbn0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQge0FwcFRhYmxlfSBmcm9tICcuLi90YWJsZS5jbGFzcyc7XG5pbXBvcnQge1JlZmVyZW50aWFsLCBTdGF0dXNCeUlkLCBTdGF0dXNMaXN0fSBmcm9tICcuLi8uLi9zZXJ2aWNlcy9tb2RlbC9yZWZlcmVudGlhbC5tb2RlbCc7XG5pbXBvcnQge0lvbkluZmluaXRlU2Nyb2xsfSBmcm9tICdAaW9uaWMvYW5ndWxhcic7XG5pbXBvcnQge0VudGl0aWVzVGFibGVEYXRhU291cmNlfSBmcm9tICcuLi9lbnRpdGllcy10YWJsZS1kYXRhc291cmNlLmNsYXNzJztcbmltcG9ydCB7SW5NZW1vcnlFbnRpdGllc1NlcnZpY2V9IGZyb20gJy4uLy4uLy4uL3NoYXJlZC9zZXJ2aWNlcy9tZW1vcnktZW50aXR5LXNlcnZpY2UuY2xhc3MnO1xuaW1wb3J0IHtBcHBWYWxpZGF0b3JTZXJ2aWNlfSBmcm9tICcuLi8uLi9zZXJ2aWNlcy92YWxpZGF0b3IvYmFzZS52YWxpZGF0b3IuY2xhc3MnO1xuaW1wb3J0IHtBYnN0cmFjdENvbnRyb2wsIFVudHlwZWRGb3JtQnVpbGRlciwgVW50eXBlZEZvcm1Hcm91cH0gZnJvbSAnQGFuZ3VsYXIvZm9ybXMnO1xuaW1wb3J0IHtpc05pbCwgaXNOb3ROaWx9IGZyb20gJy4uLy4uLy4uL3NoYXJlZC9mdW5jdGlvbnMnO1xuaW1wb3J0IHtmcm9tVW5peE1zVGltZXN0YW1wfSBmcm9tICcuLi8uLi8uLi9zaGFyZWQvZGF0ZXMnO1xuaW1wb3J0IHtSZWZlcmVudGlhbEZpbHRlcn0gZnJvbSAnLi4vLi4vc2VydmljZXMvdGVzdGluZy9yZWZlcmVudGlhbC1maWx0ZXIubW9kZWwnO1xuaW1wb3J0IHtkZWJvdW5jZVRpbWUsIGZpbHRlciwgdGFwfSBmcm9tICdyeGpzL29wZXJhdG9ycyc7XG5pbXBvcnQge01hdEV4cGFuc2lvblBhbmVsfSBmcm9tICdAYW5ndWxhci9tYXRlcmlhbC9leHBhbnNpb24nO1xuaW1wb3J0IHtTdGF0dXNJZHN9IGZyb20gJy4uLy4uL3NlcnZpY2VzL21vZGVsL21vZGVsLmVudW0nO1xuaW1wb3J0IHtTdWJzY3JpcHRpb24sIHRpbWVyfSBmcm9tICdyeGpzJztcbmltcG9ydCB7REVGQVVMVF9QQUdFX1NJWkUsIFJFU0VSVkVEX0VORF9DT0xVTU5TLCBSRVNFUlZFRF9TVEFSVF9DT0xVTU5TfSBmcm9tICcuLi90YWJsZS5tb2RlbCc7XG5pbXBvcnQge0Zvcm1GaWVsZERlZmluaXRpb25NYXB9IGZyb20gJy4uLy4uLy4uL3NoYXJlZC9mb3JtL2ZpZWxkLm1vZGVsJztcbmltcG9ydCB7VGFibGVWYWxpZGF0b3JTZXJ2aWNlfSBmcm9tICcuL3RhYmxlLXZhbGlkYXRvci5zZXJ2aWNlJztcblxuQENvbXBvbmVudCh7XG4gIHNlbGVjdG9yOiAnYXBwLXRhYmxlLXRlc3RpbmcnLFxuICBzdHlsZVVybHM6IFsndGFibGUudGVzdGluZy5zY3NzJ10sXG4gIHRlbXBsYXRlVXJsOiAndGFibGUudGVzdGluZy5odG1sJyxcbiAgcHJvdmlkZXJzOiBbXG4gICAge1xuICAgICAgcHJvdmlkZTogQXBwVmFsaWRhdG9yU2VydmljZSxcbiAgICAgIHVzZUNsYXNzOiBUYWJsZVZhbGlkYXRvclNlcnZpY2VcbiAgICB9LFxuICAgIHtcbiAgICAgIHByb3ZpZGU6IEFwcFRhYmxlLCB1c2VFeGlzdGluZzogZm9yd2FyZFJlZigoKSA9PiBUYWJsZVRlc3RQYWdlKSxcbiAgICB9XG4gIF0sXG4gIGNoYW5nZURldGVjdGlvbjogQ2hhbmdlRGV0ZWN0aW9uU3RyYXRlZ3kuT25QdXNoXG59KVxuZXhwb3J0IGNsYXNzIFRhYmxlVGVzdFBhZ2UgZXh0ZW5kcyBBcHBUYWJsZTxSZWZlcmVudGlhbCwgUmVmZXJlbnRpYWxGaWx0ZXI+XG4gIGltcGxlbWVudHMgT25Jbml0LCBPbkRlc3Ryb3ksIEFmdGVyVmlld0luaXQge1xuXG4gIHJlYWRvbmx5IG1heFJvd0NvdW50ID0gMTAwO1xuXG4gIHRpbWVyOiBTdWJzY3JpcHRpb247XG4gIGNhbkVkaXQgPSB0cnVlO1xuICBkYXRhOiBSZWZlcmVudGlhbFtdO1xuICBmaWx0ZXJGb3JtOiBVbnR5cGVkRm9ybUdyb3VwO1xuICBmaWx0ZXJDcml0ZXJpYUNvdW50ID0gMDtcbiAgZ3JvdXBDb2x1bW5zID0gWyd0b3Atc3RhcnQnLCAnZ3JvdXAtMScsICdncm91cC0yJywgJ3RvcC1lbmQnXTtcbiAgcm93SGVpZ2h0ID0gNDg7XG4gIHBlcm1hbmVudFNlbGVjdGlvbkFsbG93ZWQgPSB0cnVlO1xuXG4gIHJlYWRvbmx5IHN0YXR1c0xpc3QgPSBTdGF0dXNMaXN0O1xuICByZWFkb25seSBzdGF0dXNCeUlkID0gU3RhdHVzQnlJZDtcbiAgcmVhZG9ubHkgY29sdW1uRGVmaW5pdGlvbnM6IEZvcm1GaWVsZERlZmluaXRpb25NYXAgPSB7fTtcblxuICBASW5wdXQoKSBlbmFibGVJbmZpbml0ZVNjcm9sbDogYm9vbGVhbjtcbiAgQElucHV0KCkgdXNlU3RpY2t5ID0gdHJ1ZTtcblxuICBnZXQgaGFzTW9yZURhdGEoKTogYm9vbGVhbiB7XG4gICAgcmV0dXJuIHRoaXMuZGF0YS5sZW5ndGggPCAxMDA7XG4gIH1cblxuICBAVmlld0NoaWxkKE1hdEV4cGFuc2lvblBhbmVsLCB7c3RhdGljOiB0cnVlfSkgZmlsdGVyRXhwYW5zaW9uUGFuZWw6IE1hdEV4cGFuc2lvblBhbmVsO1xuICBAVmlld0NoaWxkKElvbkluZmluaXRlU2Nyb2xsKSBpbmZpbml0ZVNjcm9sbDogSW9uSW5maW5pdGVTY3JvbGw7XG5cbiAgZ2V0IGRhdGFTZXJ2aWNlKCk6IEluTWVtb3J5RW50aXRpZXNTZXJ2aWNlPFJlZmVyZW50aWFsPntcbiAgICByZXR1cm4gdGhpcy5fZGF0YVNvdXJjZS5kYXRhU2VydmljZSBhcyBJbk1lbW9yeUVudGl0aWVzU2VydmljZTxSZWZlcmVudGlhbD47XG4gIH1cblxuICBjb25zdHJ1Y3RvcihpbmplY3RvcjogSW5qZWN0b3IsXG4gICAgICAgICAgICAgIHByb3RlY3RlZCB2YWxpZGF0b3JTZXJ2aWNlOiBBcHBWYWxpZGF0b3JTZXJ2aWNlLFxuICAgICAgICAgICAgICBwcm90ZWN0ZWQgZm9ybUJ1aWxkZXI6IFVudHlwZWRGb3JtQnVpbGRlcixcbiAgICAgICAgICAgICAgcHJvdGVjdGVkIGNkOiBDaGFuZ2VEZXRlY3RvclJlZlxuICAgICAgICAgICAgICApIHtcbiAgICBzdXBlcihpbmplY3RvciwgW1xuICAgICAgLi4uUkVTRVJWRURfU1RBUlRfQ09MVU1OUyxcbiAgICAgICdsYWJlbCcsXG4gICAgICAnbmFtZScsXG4gICAgICAnbGV2ZWxJZCcsXG4gICAgICAnc3RhdHVzSWQnLFxuICAgICAgLy8gJ3ZhbHVlcycsXG4gICAgICAndXBkYXRlRGF0ZScsXG4gICAgICAnY29tbWVudHMnLFxuICAgICAgLi4uUkVTRVJWRURfRU5EX0NPTFVNTlNcbiAgICBdLFxuICAgICAgbmV3IEVudGl0aWVzVGFibGVEYXRhU291cmNlKFJlZmVyZW50aWFsLCBuZXcgSW5NZW1vcnlFbnRpdGllc1NlcnZpY2UoUmVmZXJlbnRpYWwsIFJlZmVyZW50aWFsRmlsdGVyLCB7XG4gICAgICAgIHNvcnRCeVJlcGxhY2VtZW50OiB7aWQ6ICdpZCd9XG4gICAgICB9KSwgdmFsaWRhdG9yU2VydmljZSwge1xuICAgICAgICBzdXBwcmVzc0Vycm9yczogZmFsc2VcbiAgICAgIH0pLFxuICAgICAgbnVsbCk7XG5cbiAgICAvLyBXb3JrcyB3aXRoIHRydWUgYW5kIGZhbHNlXG4gICAgdGhpcy5lbmFibGVJbmZpbml0ZVNjcm9sbCA9IHRoaXMubW9iaWxlO1xuXG4gICAgdGhpcy5hdXRvTG9hZCA9IGZhbHNlO1xuICAgIHRoaXMuaW5saW5lRWRpdGlvbiA9IHRydWU7XG4gICAgdGhpcy5pMThuQ29sdW1uUHJlZml4ID0gJ1RBQkxFLlRFU1RJTkcuJztcblxuICAgIHRoaXMuY29uZmlybUJlZm9yZURlbGV0ZSA9IHRydWU7XG4gICAgdGhpcy5jb25maXJtQmVmb3JlQ2FuY2VsID0gZmFsc2U7XG4gICAgdGhpcy51bmRvYWJsZURlbGV0aW9uID0gZmFsc2U7XG4gICAgdGhpcy5zYXZlQmVmb3JlRGVsZXRlID0gZmFsc2U7XG5cbiAgICB0aGlzLnNhdmVCZWZvcmVTb3J0ID0gdHJ1ZTtcbiAgICB0aGlzLnNhdmVCZWZvcmVGaWx0ZXIgPSB0cnVlO1xuICAgIHRoaXMucHJvcGFnYXRlUm93RXJyb3IgPSB0cnVlO1xuXG4gICAgdGhpcy5maWx0ZXJGb3JtID0gZm9ybUJ1aWxkZXIuZ3JvdXAoe1xuICAgICAgc2VhcmNoVGV4dDogW251bGxdXG4gICAgfSk7XG5cbiAgICAvLyB0aGlzLmNvbHVtbkRlZmluaXRpb25zWyd2YWx1ZXMnXSA9IDxGb3JtRmllbGREZWZpbml0aW9uPntcbiAgICAvLyAgIGtleTogJ3ZhbHVlcycsXG4gICAgLy8gICB0eXBlOiAnZW51bXMnLFxuICAgIC8vICAgdmFsdWVzOiBbXG4gICAgLy8gICAgIHtrZXk6ICdBJywgdmFsdWU6ICdWYWx1ZSBBJ30sXG4gICAgLy8gICAgIHtrZXk6ICdCJywgdmFsdWU6ICdWYWx1ZSBCJ31cbiAgICAvLyAgIF1cbiAgICAvLyB9O1xuXG4gICAgdGhpcy5vblN0YXJ0RWRpdGluZ1Jvdy5zdWJzY3JpYmUocm93ID0+IHtcbiAgICAgIHJvdy52YWxpZGF0b3IucGF0Y2hWYWx1ZSh7ZW50aXR5TmFtZTogJ1Rlc3RWTyd9LCB7ZW1pdEV2ZW50OiBmYWxzZX0pO1xuICAgIH0pO1xuICB9XG5cbiAgbmdPbkluaXQoKSB7XG4gICAgc3VwZXIubmdPbkluaXQoKTtcblxuICAgIC8vIFVwZGF0ZSBmaWx0ZXIgd2hlbiBjaGFuZ2VzXG4gICAgdGhpcy5yZWdpc3RlclN1YnNjcmlwdGlvbihcbiAgICAgIHRoaXMuZmlsdGVyRm9ybS52YWx1ZUNoYW5nZXNcbiAgICAgICAgLnBpcGUoXG4gICAgICAgICAgZGVib3VuY2VUaW1lKDI1MCksXG4gICAgICAgICAgZmlsdGVyKCgpID0+IHRoaXMuZmlsdGVyRm9ybS52YWxpZCksXG4gICAgICAgICAgdGFwKHZhbHVlID0+IHtcbiAgICAgICAgICAgIGNvbnN0IGZpbHRlciA9IFJlZmVyZW50aWFsRmlsdGVyLmZyb21PYmplY3QodmFsdWUpO1xuICAgICAgICAgICAgdGhpcy5maWx0ZXJDcml0ZXJpYUNvdW50ID0gZmlsdGVyLmNvdW50Tm90RW1wdHlDcml0ZXJpYSgpO1xuICAgICAgICAgICAgdGhpcy5tYXJrRm9yQ2hlY2soKTtcbiAgICAgICAgICAgIC8vIEFwcGx5aW5nIHRoZSBmaWx0ZXJcbiAgICAgICAgICAgIHRoaXMuc2V0RmlsdGVyKGZpbHRlciwge2VtaXRFdmVudDogZmFsc2V9KTtcbiAgICAgICAgICB9KSxcbiAgICAgICAgICAvLyBTYXZlIGZpbHRlciBpbiBzZXR0aW5ncyAoYWZ0ZXIgYSBkZWJvdW5jZSB0aW1lKVxuICAgICAgICAgIGRlYm91bmNlVGltZSg1MDApLFxuICAgICAgICAgIHRhcChqc29uID0+IHRoaXMuc2V0dGluZ3Muc2F2ZVBhZ2VTZXR0aW5nKHRoaXMuc2V0dGluZ3NJZCwganNvbiwgJ2ZpbHRlcicpKVxuICAgICAgICApXG4gICAgICAgIC5zdWJzY3JpYmUoKVxuICAgICk7XG5cbiAgICB0aGlzLnJlZ2lzdGVyQXV0b2NvbXBsZXRlRmllbGQoJ2xldmVsJywge1xuICAgICAgICBpdGVtczogW1xuICAgICAgICAgIHtpZDogMSwgbGFiZWw6ICdBJywgbmFtZTogJ2l0ZW0gQSd9LFxuICAgICAgICAgIHtpZDogMSwgbGFiZWw6ICdCJywgbmFtZTogJ2l0ZW0gQid9XG4gICAgICAgIF0sXG4gICAgICAgIG1vYmlsZTogdGhpcy5tb2JpbGVcbiAgICAgIH0pO1xuXG4gICAgdGhpcy5yZWdpc3RlclN1YnNjcmlwdGlvbihcbiAgICAgIHRoaXMub25SZWZyZXNoLnN1YnNjcmliZSgoKSA9PiB7XG4gICAgICAgIHRoaXMuZmlsdGVyRm9ybS5tYXJrQXNVbnRvdWNoZWQoKTtcbiAgICAgICAgdGhpcy5maWx0ZXJGb3JtLm1hcmtBc1ByaXN0aW5lKCk7XG4gICAgICB9KSk7XG5cbiAgICB0aGlzLm1hcmtBc1JlYWR5KCk7XG4gIH1cblxuICBuZ0FmdGVyVmlld0luaXQoKSB7XG4gICAgc3VwZXIubmdBZnRlclZpZXdJbml0KCk7XG5cbiAgICAvLyBSZXN0b3JlIGZpbHRlciBmcm9tIHNldHRpbmdzXG4gICAgdGhpcy5yZXN0b3JlRmlsdGVyKCk7XG5cbiAgICAvLyBMb2FkIGRhdGFcbiAgICB0aGlzLmxvYWQoKTtcbiAgfVxuXG4gIG5nT25EZXN0cm95KCkge1xuICAgIGNvbnNvbGUuZGVidWcoJ1t0ZXN0LXRhYmxlXSBEZXN0cm95aW5nIHRhYmxlLi4uJyk7XG4gICAgc3VwZXIubmdPbkRlc3Ryb3koKTtcbiAgICB0aGlzLnN0b3BUaW1lcigpO1xuICAgIC8vdGhpcy5kYXRhU2VydmljZS5zdG9wKCk7XG4gIH1cblxuICBwcm90ZWN0ZWQgcmVzdG9yZUZpbHRlcigpIHtcbiAgICBjb25zdCBqc29uID0gdGhpcy5zZXR0aW5ncy5nZXRQYWdlU2V0dGluZ3ModGhpcy5zZXR0aW5nc0lkLCAnZmlsdGVyJyk7XG4gICAgY29uc29sZS5kZWJ1ZygnW3RhYmxlLXRlc3RdIFJlc3RvcmluZyBmaWx0ZXIgZnJvbSBzZXR0aW5ncy4uLicsIGpzb24pO1xuXG4gICAgaWYgKGpzb24pIHtcbiAgICAgIGNvbnN0IGZpbHRlciA9IFJlZmVyZW50aWFsRmlsdGVyLmZyb21PYmplY3QoanNvbik7XG4gICAgICB0aGlzLmZpbHRlckZvcm0ucGF0Y2hWYWx1ZShqc29uLCB7ZW1pdEV2ZW50OiBmYWxzZX0pO1xuICAgICAgdGhpcy5maWx0ZXJDcml0ZXJpYUNvdW50ID0gZmlsdGVyLmNvdW50Tm90RW1wdHlDcml0ZXJpYSgpO1xuICAgICAgdGhpcy5zZXRGaWx0ZXIoZmlsdGVyLCB7ZW1pdEV2ZW50OiBmYWxzZX0pO1xuICAgICAgdGhpcy5tYXJrRm9yQ2hlY2soKTtcbiAgICB9XG4gIH1cblxuICB0b2dnbGVUaW1lcigpIHtcbiAgICBpZiAoaXNOb3ROaWwodGhpcy50aW1lcikpIHRoaXMuc3RvcFRpbWVyKCk7XG4gICAgZWxzZSB0aGlzLnN0YXJ0VGltZXIoKTtcbiAgfVxuXG4gIGxvYWQoKSB7XG4gICAgY29uc29sZS5kZWJ1ZygnW3Rlc3QtdGFibGVdIFVwZGF0aW5nIGRhdGEuLi4nKTtcbiAgICB0aGlzLm1hcmtBc0xvYWRpbmcoKTtcblxuICAgIGlmIChpc05pbCh0aGlzLmRhdGEpKSB7XG4gICAgICB0aGlzLmRhdGEgPSB0aGlzLmdlbmVyYXRlRGF0YSgwLCB0aGlzLm1heFJvd0NvdW50KTtcbiAgICB9XG4gICAgdGhpcy5kYXRhU2VydmljZS52YWx1ZSA9IHRoaXMuZGF0YTtcblxuICAgIHRoaXMub25SZWZyZXNoLmVtaXQoKTtcbiAgfVxuXG4gIGFzeW5jIGZldGNoTW9yZShldmVudCkge1xuICAgIGNvbnNvbGUuZGVidWcoJ1t0YWJsZS10ZXN0XSBMb2FkaW5nIG1vcmUuLi4nLCBldmVudCk7XG4gICAgY29uc3QgZmV0Y2hlZCA9IGF3YWl0IHRoaXMuX2RhdGFTb3VyY2UuZmV0Y2hNb3JlKCk7XG5cbiAgICBpZiAoZmV0Y2hlZCAmJiBldmVudD8udGFyZ2V0ICYmIGV2ZW50LnRhcmdldC5jb21wbGV0ZSkge1xuICAgICAgLy8gV2FpdCBlbmQgb2YgbG9hZFxuICAgICAgYXdhaXQgdGhpcy53YWl0SWRsZSgpO1xuICAgICAgLy8gTWFyayB0YXJnZXQgZXZlbnQgYXMgY29tcGxldGVkIChlLmcuIElvblJlZnJlc2hlcilcbiAgICAgIGV2ZW50LnRhcmdldC5jb21wbGV0ZSgpO1xuICAgIH1cbiAgfVxuXG4gIGFzeW5jIHNhdmUob3B0cz86IHsga2VlcEVkaXRpbmc/OiBib29sZWFuIH0pOiBQcm9taXNlPGJvb2xlYW4+IHtcbiAgICBjb25zdCBzYXZlZCA9IGF3YWl0IHN1cGVyLnNhdmUob3B0cyk7XG4gICAgaWYgKHNhdmVkKSB7XG4gICAgICAvLyBVcGRhdGUgc291cmNlIGRhdGFcbiAgICAgIHRoaXMuZGF0YSA9IHRoaXMuZGF0YVNlcnZpY2UudmFsdWU7XG4gICAgfVxuICAgIHJldHVybiBzYXZlZDtcbiAgfVxuXG4gIGNsZWFyQ29udHJvbFZhbHVlKGV2ZW50OiBFdmVudCwgZm9ybUNvbnRyb2w6IEFic3RyYWN0Q29udHJvbCk6IGJvb2xlYW4ge1xuICAgIGlmIChldmVudCkgZXZlbnQuc3RvcFByb3BhZ2F0aW9uKCk7IC8vIEF2b2lkIHRvIGVudGVyIGlucHV0IHRoZSBmaWVsZFxuICAgIGZvcm1Db250cm9sLnNldFZhbHVlKG51bGwpO1xuICAgIHJldHVybiBmYWxzZTtcbiAgfVxuXG4gIGFwcGx5RmlsdGVyQW5kQ2xvc2VQYW5lbChldmVudD86IEV2ZW50KSB7XG4gICAgdGhpcy5kZWZhdWx0UGFnZVNpemUgPSBERUZBVUxUX1BBR0VfU0laRTtcbiAgICB0aGlzLm9uUmVmcmVzaC5lbWl0KGV2ZW50KTtcbiAgICB0aGlzLmZpbHRlckV4cGFuc2lvblBhbmVsLmNsb3NlKCk7XG4gIH1cblxuICByZXNldEZpbHRlcihfPzogRXZlbnQpIHtcbiAgICB0aGlzLmZpbHRlckZvcm0ucmVzZXQoe30sIHtlbWl0RXZlbnQ6IHRydWV9KTtcbiAgICB0aGlzLnNldEZpbHRlcihSZWZlcmVudGlhbEZpbHRlci5mcm9tT2JqZWN0KHt9KSwge2VtaXRFdmVudDogdHJ1ZX0pO1xuICAgIHRoaXMuZmlsdGVyRXhwYW5zaW9uUGFuZWwuY2xvc2UoKTtcbiAgfVxuXG4gIHN0YXJ0VGltZXIoKSB7XG4gICAgdGhpcy5zdG9wVGltZXIoKTtcbiAgICB0aGlzLnRpbWVyID0gdGltZXIoNTAwKVxuICAgICAgLnN1YnNjcmliZSgoKSA9PiB7XG4gICAgICAgIHRoaXMuZGF0YSA9IG51bGw7IC8vIFJlc2V0XG4gICAgICAgIHRoaXMubG9hZCgpO1xuICAgICAgfSk7XG4gIH1cblxuICBzdG9wVGltZXIoKSB7XG4gICAgdGhpcy50aW1lcj8udW5zdWJzY3JpYmUoKTtcbiAgICB0aGlzLnRpbWVyID0gbnVsbDtcbiAgfVxuXG4gIHByb3RlY3RlZCBnZW5lcmF0ZURhdGEob2Zmc2V0PzogbnVtYmVyLCBzaXplPzogbnVtYmVyLCApOiBSZWZlcmVudGlhbFtdIHtcbiAgICBvZmZzZXQgPSBvZmZzZXQgfHwgMDtcbiAgICBzaXplID0gc2l6ZSB8fCAxMDA7XG5cbiAgICBjb25zdCByZXN1bHQgPSBuZXcgQXJyYXk8UmVmZXJlbnRpYWw+KCk7XG4gICAgZm9yIChsZXQgaSA9IDA7IGkgPCBzaXplOyBpKyspIHtcbiAgICAgIGNvbnN0IGlkID0gaSArIDEgKyBvZmZzZXQ7XG4gICAgICBjb25zdCBpdGVtID0gUmVmZXJlbnRpYWwuZnJvbU9iamVjdCh7XG4gICAgICAgIGlkLFxuICAgICAgICBsYWJlbDogJ0NPREUtJyArIGlkLFxuICAgICAgICBuYW1lOiAnTmFtZSAjJyArIGlkLFxuICAgICAgICBsZXZlbElkOiB7aWQ6IDEsIGxhYmVsOiAnQScsIG5hbWU6ICdJdGVtIEEnfSxcbiAgICAgICAgc3RhdHVzSWQ6IFN0YXR1c0lkcy5FTkFCTEUsXG4gICAgICAgIGNvbW1lbnRzOiAnTXkgY29tbWVudCAjJyArIGlkLFxuICAgICAgICBwcm9wZXJ0aWVzOiB7XG4gICAgICAgICAgdmFsdWVzOiBpICUgMiA9PT0gMCA/ICdBJyA6ICdBLEInXG4gICAgICAgIH0sXG4gICAgICAgIGNyZWF0aW9uRGF0ZTogZnJvbVVuaXhNc1RpbWVzdGFtcChEYXRlLm5vdygpIC0gaSAqIDYwICogMTAwMCksXG4gICAgICAgIHVwZGF0ZURhdGU6IGZyb21Vbml4TXNUaW1lc3RhbXAoRGF0ZS5ub3coKSAtIGkgKiA2MCAqIDEwMDApLFxuICAgICAgICBlbnRpdHlOYW1lOiAnVGVzdFZPJ1xuICAgICAgfSk7XG4gICAgICByZXN1bHQucHVzaChpdGVtKTtcbiAgICB9XG5cbiAgICByZXR1cm4gcmVzdWx0O1xuICB9XG5cbiAgcHJvdGVjdGVkIG1hcmtGb3JDaGVjaygpIHtcbiAgICB0aGlzLmNkLm1hcmtGb3JDaGVjaygpO1xuICB9XG59XG4iLCI8YXBwLXRvb2xiYXIgY29sb3I9XCJwcmltYXJ5XCIgW2NhbkdvQmFja109XCJ0cnVlXCJcbiAgICAgICAgICAgICBbaGFzVmFsaWRhdGVdPVwiIShsb2FkaW5nU3ViamVjdHxhc3luYykgJiYgZGlydHlcIlxuICAgICAgICAgICAgIChvblZhbGlkYXRlKT1cInNhdmUoKVwiXG4gICAgICAgICAgICAgW2JhY2tIcmVmXT1cIicvdGVzdGluZydcIj5cbiAgPGlvbi10aXRsZT5UYWJsZSAoY2xpY2sgdG8gZWRpdCk8L2lvbi10aXRsZT5cbiAgPGlvbi1idXR0b25zIHNsb3Q9XCJlbmRcIj5cblxuXG4gICAgPG5nLWNvbnRhaW5lciAqbmdJZj1cIiFzZWxlY3Rpb24uaGFzVmFsdWUoKTsgZWxzZSBoYXNTZWxlY3Rpb25cIj5cblxuICAgICAgPGlucHV0IG1hdElucHV0IHR5cGU9XCJudW1iZXJcIiBzdGVwPVwiMVwiIHN0eWxlPVwiY29sb3I6YmxhY2s7IHdpZHRoOiA1MHB4O1wiIFsobmdNb2RlbCldPVwicm93SGVpZ2h0XCI+XG5cbiAgICAgIDwhLS0gQWRkIC0tPlxuICAgICAgPGJ1dHRvbiBtYXQtaWNvbi1idXR0b25cbiAgICAgICAgICAgICAgKm5nSWY9XCJjYW5FZGl0ICYmICFtb2JpbGVcIlxuICAgICAgICAgICAgICBbdGl0bGVdPVwiJ0NPTU1PTi5CVE5fQUREJ3x0cmFuc2xhdGVcIlxuICAgICAgICAgICAgICAoY2xpY2spPVwiYWRkUm93KClcIj5cbiAgICAgICAgPG1hdC1pY29uPmFkZDwvbWF0LWljb24+XG4gICAgICA8L2J1dHRvbj5cblxuICAgICAgPCEtLSByZXNldCBmaWx0ZXIgLS0+XG4gICAgICA8YnV0dG9uIG1hdC1pY29uLWJ1dHRvbiAoY2xpY2spPVwicmVzZXRGaWx0ZXIoKVwiXG4gICAgICAgICAgICAgICpuZ0lmPVwiZmlsdGVyQ3JpdGVyaWFDb3VudFwiPlxuICAgICAgICA8bWF0LWljb24gY29sb3I9XCJhY2NlbnRcIj5maWx0ZXJfbGlzdF9hbHQ8L21hdC1pY29uPlxuICAgICAgICA8bWF0LWljb24gY2xhc3M9XCJpY29uLXNlY29uZGFyeVwiIHN0eWxlPVwibGVmdDogMTZweDsgdG9wOiA1cHg7IGZvbnQtd2VpZ2h0OiBib2xkO1wiPmNsb3NlPC9tYXQtaWNvbj5cbiAgICAgIDwvYnV0dG9uPlxuXG4gICAgICA8IS0tIHNob3cgZmlsdGVyIC0tPlxuICAgICAgPGJ1dHRvbiBtYXQtaWNvbi1idXR0b24gKGNsaWNrKT1cImZpbHRlckV4cGFuc2lvblBhbmVsLnRvZ2dsZSgpXCI+XG4gICAgICAgIDxtYXQtaWNvbiAqbmdJZj1cImZpbHRlckNyaXRlcmlhQ291bnQ7IGVsc2UgZW1wdHlGaWx0ZXJcIlxuICAgICAgICAgICAgICAgICAgW21hdEJhZGdlXT1cImZpbHRlckNyaXRlcmlhQ291bnRcIlxuICAgICAgICAgICAgICAgICAgbWF0QmFkZ2VDb2xvcj1cImFjY2VudFwiXG4gICAgICAgICAgICAgICAgICBtYXRCYWRnZVNpemU9XCJzbWFsbFwiXG4gICAgICAgICAgICAgICAgICBtYXRCYWRnZVBvc2l0aW9uPVwiYWJvdmUgYWZ0ZXJcIj5maWx0ZXJfbGlzdF9hbHRcbiAgICAgICAgPC9tYXQtaWNvbj5cbiAgICAgICAgPG5nLXRlbXBsYXRlICNlbXB0eUZpbHRlcj5cbiAgICAgICAgICA8bWF0LWljb24+ZmlsdGVyX2xpc3RfYWx0PC9tYXQtaWNvbj5cbiAgICAgICAgPC9uZy10ZW1wbGF0ZT5cbiAgICAgIDwvYnV0dG9uPlxuXG4gICAgICA8IS0tIHNhdmUgLS0+XG4gICAgICA8YnV0dG9uIG1hdC1pY29uLWJ1dHRvbiAqbmdJZj1cIm1vYmlsZVwiXG4gICAgICAgICAgICAgIFtkaXNhYmxlZF09XCIhKGRpcnR5U3ViamVjdHxhc3luYylcIlxuICAgICAgICAgICAgICAoY2xpY2spPVwic2F2ZSgpXCI+XG4gICAgICAgIDxtYXQtaWNvbj5zYXZlPC9tYXQtaWNvbj5cbiAgICAgIDwvYnV0dG9uPlxuXG4gICAgICA8IS0tIHN0YXJ0L3N0b3AgdGltZXIgdG8gYXV0by1sb2FkIGRhdGEgLS0+XG4gICAgICA8aW9uLWJ1dHRvbiAqbmdJZj1cIiF0aW1lclwiIChjbGljayk9XCJzdGFydFRpbWVyKClcIj5TdGFydCByZWxvYWQ8L2lvbi1idXR0b24+XG4gICAgICA8aW9uLWJ1dHRvbiAqbmdJZj1cInRpbWVyXCIgKGNsaWNrKT1cInN0b3BUaW1lcigpXCIgY29sb3I9XCJhY2NlbnRcIj5TdG9wIHJlbG9hZDwvaW9uLWJ1dHRvbj5cbiAgICA8L25nLWNvbnRhaW5lcj5cblxuICAgIDwhLS0gaWYgcm93IHNlbGVjdGlvbiAtLT5cbiAgICA8bmctdGVtcGxhdGUgI2hhc1NlbGVjdGlvbj5cblxuICAgICAgPCEtLSBkZWxldGUgLS0+XG4gICAgICA8YnV0dG9uIG1hdC1pY29uLWJ1dHRvblxuICAgICAgICAgICAgICAqbmdJZj1cImNhbkVkaXRcIiBbdGl0bGVdPVwiJ0NPTU1PTi5CVE5fREVMRVRFJ3x0cmFuc2xhdGVcIlxuICAgICAgICAgICAgICAoY2xpY2spPVwiZGVsZXRlU2VsZWN0aW9uKCRldmVudClcIj5cbiAgICAgICAgPG1hdC1pY29uPmRlbGV0ZTwvbWF0LWljb24+XG4gICAgICA8L2J1dHRvbj5cblxuICAgICAgPCEtLSBkdXBsaWNhdGUgLS0+XG4gICAgICA8YnV0dG9uIG1hdC1pY29uLWJ1dHRvblxuICAgICAgICAgICAgICAqbmdJZj1cImNhbkVkaXQgJiYgc2VsZWN0aW9uLnNlbGVjdGVkIHwgaXNBcnJheUxlbmd0aDoge2VxdWFsczogMX1cIlxuICAgICAgICAgICAgICBbdGl0bGVdPVwiJ0NPTU1PTi5CVE5fRFVQTElDQVRFJ3x0cmFuc2xhdGVcIlxuICAgICAgICAgICAgICAoY2xpY2spPVwiZHVwbGljYXRlUm93KCRldmVudCwgc2VsZWN0aW9uLnNlbGVjdGVkWzBdKVwiPlxuICAgICAgICA8bWF0LWljb24+ZmlsZV9jb3B5PC9tYXQtaWNvbj5cbiAgICAgIDwvYnV0dG9uPlxuICAgIDwvbmctdGVtcGxhdGU+XG4gIDwvaW9uLWJ1dHRvbnM+XG48L2FwcC10b29sYmFyPlxuPGlvbi1jb250ZW50IGNsYXNzPVwiaW9uLW5vLXBhZGRpbmdcIj5cblxuICA8aW9uLXJlZnJlc2hlciBzbG90PVwiZml4ZWRcIiAqbmdJZj1cIm1vYmlsZVwiIChpb25SZWZyZXNoKT1cImRvUmVmcmVzaCgkZXZlbnQpXCI+XG4gICAgPGlvbi1yZWZyZXNoZXItY29udGVudD48L2lvbi1yZWZyZXNoZXItY29udGVudD5cbiAgPC9pb24tcmVmcmVzaGVyPlxuXG4gIDwhLS0gZXJyb3IgLS0+XG4gIDxpb24taXRlbSAqbmdJZj1cIm1vYmlsZSAmJiBlcnJvclwiIGxpbmVzPVwibm9uZVwiIEBzbGlkZVVwRG93bkFuaW1hdGlvbj5cbiAgICA8aW9uLWljb24gY29sb3I9XCJkYW5nZXJcIiBzbG90PVwic3RhcnRcIiBuYW1lPVwiYWxlcnQtY2lyY2xlXCI+PC9pb24taWNvbj5cbiAgICA8aW9uLWxhYmVsIGNvbG9yPVwiZGFuZ2VyXCIgY2xhc3M9XCJlcnJvclwiIFtpbm5lckhUTUxdPVwiZXJyb3J8dHJhbnNsYXRlXCI+PC9pb24tbGFiZWw+XG4gIDwvaW9uLWl0ZW0+XG5cbiAgPCEtLSBzZWFyY2ggLS0+XG4gIDxtYXQtZXhwYW5zaW9uLXBhbmVsICNmaWx0ZXJFeHBhbnNpb25QYW5lbCBjbGFzcz1cImZpbHRlci1wYW5lbCBmaWx0ZXItcGFuZWwtZmxvYXRpbmdcIj5cbiAgICA8Zm9ybSBjbGFzcz1cImZvcm0tY29udGFpbmVyIGlvbi1wYWRkaW5nLXRvcFwiIFtmb3JtR3JvdXBdPVwiZmlsdGVyRm9ybVwiIChuZ1N1Ym1pdCk9XCJhcHBseUZpbHRlckFuZENsb3NlUGFuZWwoJGV2ZW50KVwiPlxuXG4gICAgICA8aW9uLWdyaWQ+XG4gICAgICAgIDxpb24tcm93PlxuICAgICAgICAgIDxpb24tY29sPlxuICAgICAgICAgICAgPCEtLSBzZWFyY2ggdGV4dCAtLT5cbiAgICAgICAgICAgIDxtYXQtZm9ybS1maWVsZD5cbiAgICAgICAgICAgICAgPG1hdC1sYWJlbD57eydUQUJMRS5URVNUSU5HLlNFQVJDSF9URVhUJ3x0cmFuc2xhdGV9fTwvbWF0LWxhYmVsPlxuICAgICAgICAgICAgICA8aW9uLWljb24gbWF0UHJlZml4IG5hbWU9XCJzZWFyY2hcIj48L2lvbi1pY29uPlxuICAgICAgICAgICAgICA8aW5wdXQgbWF0SW5wdXRcbiAgICAgICAgICAgICAgICAgICAgIGZvcm1Db250cm9sTmFtZT1cInNlYXJjaFRleHRcIlxuICAgICAgICAgICAgICAgICAgICAgYXV0b2NvbXBsZXRlPVwib2ZmXCI+XG4gICAgICAgICAgICAgIDxidXR0b24gbWF0LWljb24tYnV0dG9uIG1hdFN1ZmZpeCB0YWJpbmRleD1cIi0xXCJcbiAgICAgICAgICAgICAgICAgICAgICB0eXBlPVwiYnV0dG9uXCJcbiAgICAgICAgICAgICAgICAgICAgICAoY2xpY2spPVwiY2xlYXJDb250cm9sVmFsdWUoJGV2ZW50LCBmaWx0ZXJGb3JtLmNvbnRyb2xzLnNlYXJjaFRleHQpXCJcbiAgICAgICAgICAgICAgICAgICAgICBbaGlkZGVuXT1cImZpbHRlckZvcm0uY29udHJvbHMuc2VhcmNoVGV4dC5kaXNhYmxlZCB8fCAhZmlsdGVyRm9ybS5jb250cm9scy5zZWFyY2hUZXh0LnZhbHVlXCI+XG4gICAgICAgICAgICAgICAgPG1hdC1pY29uPmNsb3NlPC9tYXQtaWNvbj5cbiAgICAgICAgICAgICAgPC9idXR0b24+XG4gICAgICAgICAgICA8L21hdC1mb3JtLWZpZWxkPlxuICAgICAgICAgIDwvaW9uLWNvbD5cbiAgICAgICAgPC9pb24tcm93PlxuICAgICAgPC9pb24tZ3JpZD5cbiAgICA8L2Zvcm0+XG5cbiAgICA8bWF0LWFjdGlvbi1yb3c+XG4gICAgICA8IS0tIENvdW50ZXIgIC0tPlxuICAgICAgPGlvbi1sYWJlbCBbaGlkZGVuXT1cIihsb2FkaW5nU3ViamVjdHxhc3luYykgfHwgZmlsdGVyRm9ybS5kaXJ0eVwiXG4gICAgICAgICAgICAgICAgIFtjb2xvcl09XCJlbXB0eSAmJiAnZGFuZ2VyJ1wiXG4gICAgICAgICAgICAgICAgIGNsYXNzPVwiaW9uLXBhZGRpbmdcIj5cbiAgICAgICAge3sgKHRvdGFsUm93Q291bnQgPyAnQ09NTU9OLlJFU1VMVF9DT1VOVCcgOiAnQ09NTU9OLk5PX1JFU1VMVCcpIHwgdHJhbnNsYXRlOiB7XG4gICAgICAgIGNvdW50OiAodG90YWxSb3dDb3VudCB8XG4gICAgICAgICAgbnVtYmVyRm9ybWF0KVxuICAgICAgfSB9fVxuICAgICAgPC9pb24tbGFiZWw+XG5cbiAgICAgIDxkaXYgY2xhc3M9XCJ0b29sYmFyLXNwYWNlclwiPjwvZGl2PlxuXG4gICAgICA8IS0tIENsb3NlIHBhbmVsIC0tPlxuICAgICAgPGlvbi1idXR0b24gbWF0LWJ1dHRvbiBmaWxsPVwiY2xlYXJcIiBjb2xvcj1cImRhcmtcIlxuICAgICAgICAgICAgICAgICAgKGNsaWNrKT1cImZpbHRlckV4cGFuc2lvblBhbmVsLmNsb3NlKClcIlxuICAgICAgICAgICAgICAgICAgW2Rpc2FibGVkXT1cImxvYWRpbmdTdWJqZWN0fGFzeW5jXCI+XG4gICAgICAgIDxpb24tdGV4dCB0cmFuc2xhdGU+Q09NTU9OLkJUTl9DTE9TRTwvaW9uLXRleHQ+XG4gICAgICA8L2lvbi1idXR0b24+XG5cbiAgICAgIDwhLS0gU2VhcmNoIGJ1dHRvbiAtLT5cbiAgICAgIDxpb24tYnV0dG9uIG1hdC1idXR0b25cbiAgICAgICAgICAgICAgICAgIFtjb2xvcl09XCJmaWx0ZXJGb3JtLmRpcnR5ID8gJ3RlcnRpYXJ5JyA6ICdkYXJrJ1wiXG4gICAgICAgICAgICAgICAgICBbZmlsbF09XCJmaWx0ZXJGb3JtLmRpcnR5ID8gJ3NvbGlkJyA6ICdjbGVhcidcIlxuICAgICAgICAgICAgICAgICAgKGNsaWNrKT1cImFwcGx5RmlsdGVyQW5kQ2xvc2VQYW5lbCgkZXZlbnQpXCI+XG4gICAgICAgIDxpb24tdGV4dCB0cmFuc2xhdGU+Q09NTU9OLkJUTl9BUFBMWTwvaW9uLXRleHQ+XG4gICAgICA8L2lvbi1idXR0b24+XG4gICAgPC9tYXQtYWN0aW9uLXJvdz5cbiAgPC9tYXQtZXhwYW5zaW9uLXBhbmVsPlxuXG4gIDwhLS0gdGFibGUgLS0+XG4gIDxkaXYgW2NsYXNzLnRhYmxlLWNvbnRhaW5lcl09XCIhZW5hYmxlSW5maW5pdGVTY3JvbGxcIj5cbiAgICA8dGFibGUgI3RhYmxlIG1hdC10YWJsZSBtYXRTb3J0IG1hdFNvcnREaXNhYmxlQ2xlYXJcbiAgICAgICAgICAgW2RhdGFTb3VyY2VdPVwiZGF0YVNvdXJjZVwiXG4gICAgICAgICAgIFttYXRTb3J0QWN0aXZlXT1cImRlZmF1bHRTb3J0QnlcIlxuICAgICAgICAgICBbbWF0U29ydERpcmVjdGlvbl09XCJkZWZhdWx0U29ydERpcmVjdGlvblwiXG4gICAgICAgICAgIFt0cmFja0J5XT1cInRyYWNrQnlGblwiXG4gICAgICAgICAgIFtzdHlsZS4tLW1hdC1yb3ctaGVpZ2h0XT1cInJvd0hlaWdodCArICdweCdcIj5cbiAgICA+XG5cbiAgICAgIDwhLS0gZ3JvdXAgaGVhZGVyIGNlbGxzIC0tPlxuXG4gICAgICA8bmctY29udGFpbmVyIG1hdENvbHVtbkRlZj1cInRvcC1zdGFydFwiIFtzdGlja3ldPVwidXNlU3RpY2t5XCI+XG4gICAgICAgIDx0aCBtYXQtaGVhZGVyLWNlbGwgKm1hdEhlYWRlckNlbGxEZWYgW2NsYXNzLmNkay12aXN1YWxseS1oaWRkZW5dPVwiIWNhbkVkaXRcIiBbYXR0ci5jb2xzcGFuXT1cIjJcIj5cbiAgICAgICAgICA8IS0tIHN0YXJ0IHNwYWNlciAtLT5cbiAgICAgICAgPC90aD5cbiAgICAgIDwvbmctY29udGFpbmVyPlxuXG4gICAgICA8bmctY29udGFpbmVyIG1hdENvbHVtbkRlZj1cImdyb3VwLTFcIj5cbiAgICAgICAgPHRoIG1hdC1oZWFkZXItY2VsbCAqbWF0SGVhZGVyQ2VsbERlZiBbYXR0ci5jb2xzcGFuXT1cIjNcIiBzdHlsZT1cImJhY2tncm91bmQtY29sb3I6IHdoaXRlc21va2U7IG1hcmdpbi1ib3R0b206IC0xcHg7XCI+XG4gICAgICAgICAgPGlvbi1sYWJlbCB0cmFuc2xhdGU+e3tpMThuQ29sdW1uUHJlZml4ICsgJ0dST1VQXzEnfX08L2lvbi1sYWJlbD5cbiAgICAgICAgPC90aD5cbiAgICAgIDwvbmctY29udGFpbmVyPlxuXG4gICAgICA8bmctY29udGFpbmVyIG1hdENvbHVtbkRlZj1cImdyb3VwLTJcIj5cbiAgICAgICAgPHRoIG1hdC1oZWFkZXItY2VsbCAqbWF0SGVhZGVyQ2VsbERlZiBbYXR0ci5jb2xzcGFuXT1cIjNcIj5cbiAgICAgICAgICA8aW9uLWxhYmVsIHRyYW5zbGF0ZT57e2kxOG5Db2x1bW5QcmVmaXggKyAnR1JPVVBfMid9fTwvaW9uLWxhYmVsPlxuICAgICAgICA8L3RoPlxuICAgICAgPC9uZy1jb250YWluZXI+XG5cbiAgICAgIDxuZy1jb250YWluZXIgbWF0Q29sdW1uRGVmPVwidG9wLWVuZFwiID5cbiAgICAgICAgPHRoIG1hdC1oZWFkZXItY2VsbCAqbWF0SGVhZGVyQ2VsbERlZj5cbiAgICAgICAgICA8IS0tIGVuZCBzcGFjZXIgLS0+XG4gICAgICAgIDwvdGg+XG4gICAgICA8L25nLWNvbnRhaW5lcj5cblxuICAgICAgPG5nLWNvbnRhaW5lciBtYXRDb2x1bW5EZWY9XCJzZWxlY3RcIiBbc3RpY2t5XT1cInVzZVN0aWNreVwiIFtjbGFzcy5tYXQtY29sdW1uLXN0aWNreV09XCJ1c2VTdGlja3lcIj5cbiAgICAgICAgPHRoIG1hdC1oZWFkZXItY2VsbCAqbWF0SGVhZGVyQ2VsbERlZiBbY2xhc3MuY2RrLXZpc3VhbGx5LWhpZGRlbl09XCIhY2FuRWRpdFwiPlxuICAgICAgICAgIDxtYXQtY2hlY2tib3ggKGNoYW5nZSk9XCIkZXZlbnQgPyBtYXN0ZXJUb2dnbGUoKSA6IG51bGxcIiBbY2hlY2tlZF09XCJzZWxlY3Rpb24uaGFzVmFsdWUoKSAmJiBpc0FsbFNlbGVjdGVkKClcIlxuICAgICAgICAgICAgICAgICAgICAgICAgW2luZGV0ZXJtaW5hdGVdPVwic2VsZWN0aW9uLmhhc1ZhbHVlKCkgJiYgIWlzQWxsU2VsZWN0ZWQoKVwiPlxuICAgICAgICAgIDwvbWF0LWNoZWNrYm94PlxuICAgICAgICA8L3RoPlxuICAgICAgICA8dGQgbWF0LWNlbGwgKm1hdENlbGxEZWY9XCJsZXQgcm93XCIgW2NsYXNzLmNkay12aXN1YWxseS1oaWRkZW5dPVwiIWNhbkVkaXRcIj5cbiAgICAgICAgICA8bWF0LWNoZWNrYm94ICAoY2hhbmdlKT1cIiRldmVudCA/IHNlbGVjdGlvbi50b2dnbGUocm93KSA6IG51bGxcIiBbY2hlY2tlZF09XCJzZWxlY3Rpb24uaXNTZWxlY3RlZChyb3cpXCI+XG4gICAgICAgICAgPC9tYXQtY2hlY2tib3g+XG4gICAgICAgIDwvdGQ+XG4gICAgICA8L25nLWNvbnRhaW5lcj5cblxuICAgICAgPCEtLSBJZCBjb2x1bW4gLS0+XG4gICAgICA8bmctY29udGFpbmVyIG1hdENvbHVtbkRlZj1cImlkXCIgW3N0aWNreV09XCJ1c2VTdGlja3lcIiBbY2xhc3MubWF0LWNvbHVtbi1zdGlja3ldPVwidXNlU3RpY2t5XCI+XG4gICAgICAgIDx0aCBtYXQtaGVhZGVyLWNlbGwgKm1hdEhlYWRlckNlbGxEZWYgbWF0LXNvcnQtaGVhZGVyPlxuICAgICAgICAgIDxpb24tbGFiZWw+IzwvaW9uLWxhYmVsPlxuICAgICAgICA8L3RoPlxuICAgICAgICA8dGQgbWF0LWNlbGwgKm1hdENlbGxEZWY9XCJsZXQgcm93XCI+e3sgcm93LmN1cnJlbnREYXRhPy5pZCB9fTwvdGQ+XG4gICAgICA8L25nLWNvbnRhaW5lcj5cblxuICAgICAgPCEtLSBMYWJlbCBjb2x1bW4gLS0+XG4gICAgICA8bmctY29udGFpbmVyIG1hdENvbHVtbkRlZj1cImxhYmVsXCI+XG4gICAgICAgIDx0aCBtYXQtaGVhZGVyLWNlbGwgKm1hdEhlYWRlckNlbGxEZWYgbWF0LXNvcnQtaGVhZGVyPlxuICAgICAgICAgIDxpb24tbGFiZWwgdHJhbnNsYXRlPlRBQkxFLlRFU1RJTkcuTEFCRUw8L2lvbi1sYWJlbD5cbiAgICAgICAgPC90aD5cbiAgICAgICAgPHRkIG1hdC1jZWxsICptYXRDZWxsRGVmPVwibGV0IHJvd1wiIChjbGljayk9XCJmb2N1c0NvbHVtbj0nbGFiZWwnXCI+XG4gICAgICAgICAgPG1hdC1mb3JtLWZpZWxkICpuZ0lmPVwicm93LmVkaXRpbmc7IGVsc2UgcmVhZG9ubHlDZWxsXCIgW2hpZGVSZXF1aXJlZE1hcmtlcl09XCJmYWxzZVwiIFtmbG9hdExhYmVsXT1cIidhbHdheXMnXCI+XG4gICAgICAgICAgICA8aW5wdXQgbWF0SW5wdXQgYXV0b2NvbXBsZXRlPVwib2ZmXCJcbiAgICAgICAgICAgICAgICAgICBbZm9ybUNvbnRyb2xdPVwicm93LnZhbGlkYXRvci5jb250cm9sc1snbGFiZWwnXVwiXG4gICAgICAgICAgICAgICAgICAgW3BsYWNlaG9sZGVyXT1cIidUQUJMRS5URVNUSU5HLkxBQkVMJ3x0cmFuc2xhdGVcIlxuICAgICAgICAgICAgICAgICAgIFthcHBBdXRvZm9jdXNdPVwicm93LmVkaXRpbmcgJiYgZm9jdXNDb2x1bW4gPT09ICdsYWJlbCdcIlxuICAgICAgICAgICAgICAgICAgIFtyZWFkb25seV09XCIhcm93LmVkaXRpbmdcIj5cbiAgICAgICAgICAgIDxtYXQtZXJyb3IgKm5nSWY9XCJyb3cudmFsaWRhdG9yLmNvbnRyb2xzWydsYWJlbCddLmhhc0Vycm9yKCdyZXF1aXJlZCcpXCIgdHJhbnNsYXRlPkVSUk9SLkZJRUxEX1JFUVVJUkVEPC9tYXQtZXJyb3I+XG4gICAgICAgICAgPC9tYXQtZm9ybS1maWVsZD5cbiAgICAgICAgICA8bmctdGVtcGxhdGUgI3JlYWRvbmx5Q2VsbD5cbiAgICAgICAgICAgIDxpb24tbGFiZWwgYXBwQXV0b1RpdGxlPlxuICAgICAgICAgICAgICB7eyAocm93LnZhbGlkYXRvciB8IGZvcm1HZXRWYWx1ZSA6ICdsYWJlbCcpfX1cbiAgICAgICAgICAgIDwvaW9uLWxhYmVsPlxuICAgICAgICAgIDwvbmctdGVtcGxhdGU+XG4gICAgICAgIDwvdGQ+XG4gICAgICA8L25nLWNvbnRhaW5lcj5cblxuICAgICAgPCEtLSBOYW1lIGNvbHVtbiAtLT5cbiAgICAgIDxuZy1jb250YWluZXIgbWF0Q29sdW1uRGVmPVwibmFtZVwiPlxuICAgICAgICA8dGggbWF0LWhlYWRlci1jZWxsICptYXRIZWFkZXJDZWxsRGVmIG1hdC1zb3J0LWhlYWRlcj5cbiAgICAgICAgICA8aW9uLWxhYmVsIHRyYW5zbGF0ZT5UQUJMRS5URVNUSU5HLk5BTUU8L2lvbi1sYWJlbD5cbiAgICAgICAgPC90aD5cbiAgICAgICAgPHRkIG1hdC1jZWxsICptYXRDZWxsRGVmPVwibGV0IHJvd1wiXG4gICAgICAgICAgICAoY2xpY2spPVwiZm9jdXNDb2x1bW49J25hbWUnXCI+XG4gICAgICAgICAgPG1hdC1mb3JtLWZpZWxkICpuZ0lmPVwicm93LmVkaXRpbmc7IGVsc2UgcmVhZG9ubHlDZWxsXCI+XG4gICAgICAgICAgICA8aW5wdXQgbWF0SW5wdXRcbiAgICAgICAgICAgICAgICAgICBbZm9ybUNvbnRyb2xdPVwicm93LnZhbGlkYXRvcj8uY29udHJvbHMubmFtZVwiIFtwbGFjZWhvbGRlcl09XCInVEFCTEUuVEVTVElORy5OQU1FJ3x0cmFuc2xhdGVcIlxuICAgICAgICAgICAgICAgICAgIFthcHBBdXRvZm9jdXNdPVwicm93LmVkaXRpbmcgJiYgZm9jdXNDb2x1bW4gPT09ICduYW1lJ1wiXG4gICAgICAgICAgICAgICAgICAgPlxuICAgICAgICAgICAgPG1hdC1lcnJvciAqbmdJZj1cInJvdy52YWxpZGF0b3I/LmNvbnRyb2xzLm5hbWUuaGFzRXJyb3IoJ3JlcXVpcmVkJylcIiB0cmFuc2xhdGU+RVJST1IuRklFTERfUkVRVUlSRUQ8L21hdC1lcnJvcj5cbiAgICAgICAgICA8L21hdC1mb3JtLWZpZWxkPlxuICAgICAgICAgIDxuZy10ZW1wbGF0ZSAjcmVhZG9ubHlDZWxsPlxuICAgICAgICAgICAgPGlvbi1sYWJlbCBhcHBBdXRvVGl0bGU+XG4gICAgICAgICAgICAgIHt7IChyb3cudmFsaWRhdG9yIHwgZm9ybUdldFZhbHVlIDogJ25hbWUnKX19XG4gICAgICAgICAgICA8L2lvbi1sYWJlbD5cbiAgICAgICAgICA8L25nLXRlbXBsYXRlPlxuICAgICAgICA8L3RkPlxuICAgICAgPC9uZy1jb250YWluZXI+XG5cbiAgICAgIDwhLS0gTGV2ZWwgY29sdW1uIC0tPlxuICAgICAgPG5nLWNvbnRhaW5lciBtYXRDb2x1bW5EZWY9XCJsZXZlbElkXCI+XG4gICAgICAgIDx0aCBtYXQtaGVhZGVyLWNlbGwgKm1hdEhlYWRlckNlbGxEZWYgbWF0LXNvcnQtaGVhZGVyPlxuICAgICAgICAgIDxpb24tbGFiZWwgdHJhbnNsYXRlPlRBQkxFLlRFU1RJTkcuTEVWRUxfSUQ8L2lvbi1sYWJlbD5cbiAgICAgICAgPC90aD5cbiAgICAgICAgPHRkIG1hdC1jZWxsICptYXRDZWxsRGVmPVwibGV0IHJvd1wiIChjbGljayk9XCJmb2N1c0NvbHVtbj0nbGV2ZWxJZCdcIj5cbiAgICAgICAgICA8bWF0LWF1dG9jb21wbGV0ZS1maWVsZCAqbmdJZj1cInJvdy5lZGl0aW5nOyBlbHNlIHJlYWRvbmx5Q2VsbFwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW2Zvcm1Db250cm9sXT1cInJvdy52YWxpZGF0b3IuY29udHJvbHMubGV2ZWxJZFwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW3BsYWNlaG9sZGVyXT1cIidUQUJMRS5URVNUSU5HLkxFVkVMX0lEJ3x0cmFuc2xhdGVcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZsb2F0TGFiZWw9XCJuZXZlclwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW2NvbmZpZ109XCJhdXRvY29tcGxldGVGaWVsZHMubGV2ZWxcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtyZWFkb25seV09XCIhcm93LmVkaXRpbmdcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW2F1dG9mb2N1c109XCJyb3cuZWRpdGluZyAmJiBmb2N1c0NvbHVtbiA9PT0gJ2xldmVsSWQnXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbcmVxdWlyZWRdPVwidHJ1ZVwiPlxuICAgICAgICAgIDwvbWF0LWF1dG9jb21wbGV0ZS1maWVsZD5cbiAgICAgICAgICA8bmctdGVtcGxhdGUgI3JlYWRvbmx5Q2VsbD5cbiAgICAgICAgICAgIDxpb24tbGFiZWwgYXBwQXV0b1RpdGxlPlxuICAgICAgICAgICAgICB7eyAocm93LnZhbGlkYXRvciB8IGZvcm1HZXRWYWx1ZSA6ICdsZXZlbElkJ3xyZWZlcmVudGlhbFRvU3RyaW5nOiBhdXRvY29tcGxldGVGaWVsZHMubGV2ZWwuYXR0cmlidXRlcyl9fVxuICAgICAgICAgICAgPC9pb24tbGFiZWw+XG4gICAgICAgICAgPC9uZy10ZW1wbGF0ZT5cbiAgICAgICAgPC90ZD5cbiAgICAgIDwvbmctY29udGFpbmVyPlxuXG4gICAgICA8IS0tIFN0YXR1cyBjb2x1bW4gIC0tPlxuICAgICAgPG5nLWNvbnRhaW5lciBtYXRDb2x1bW5EZWY9XCJzdGF0dXNJZFwiPlxuICAgICAgICA8dGggbWF0LWhlYWRlci1jZWxsICptYXRIZWFkZXJDZWxsRGVmPlxuICAgICAgICAgIDxzcGFuIHRyYW5zbGF0ZT5VU0VSLlNUQVRVUzwvc3Bhbj5cbiAgICAgICAgPC90aD5cbiAgICAgICAgPHRkIG1hdC1jZWxsICptYXRDZWxsRGVmPVwibGV0IHJvd1wiIFtjbGFzcy5tYXQtZm9ybS1maWVsZC1kaXNhYmxlZF09XCIhcm93LmVkaXRpbmdcIj5cbiAgICAgICAgICAgIDxtYXQtZm9ybS1maWVsZD5cbiAgICAgICAgICAgIDxtYXQtc2VsZWN0IFtmb3JtQ29udHJvbF09XCJyb3cudmFsaWRhdG9yLmNvbnRyb2xzWydzdGF0dXNJZCddXCIgW3BsYWNlaG9sZGVyXT1cImkxOG5Db2x1bW5QcmVmaXggKyAnU1RBVFVTX0lEJ3x0cmFuc2xhdGVcIj5cbiAgICAgICAgICAgICAgPG1hdC1vcHRpb24gKm5nRm9yPVwibGV0IGl0ZW0gb2Ygc3RhdHVzTGlzdFwiIFt2YWx1ZV09XCJpdGVtLmlkXCI+XG4gICAgICAgICAgICAgICAgPG1hdC1pY29uPjxpb24taWNvbiBbbmFtZV09XCJpdGVtLmljb25cIj48L2lvbi1pY29uPjwvbWF0LWljb24+XG4gICAgICAgICAgICAgICAgPG1hdC1sYWJlbD57eyBpdGVtLmxhYmVsIHx0cmFuc2xhdGUgfX08L21hdC1sYWJlbD5cbiAgICAgICAgICAgICAgPC9tYXQtb3B0aW9uPlxuICAgICAgICAgICAgPC9tYXQtc2VsZWN0PlxuICAgICAgICAgICAgPG1hdC1lcnJvciAqbmdJZj1cInJvdy52YWxpZGF0b3IuY29udHJvbHNbJ3N0YXR1c0lkJ10uaGFzRXJyb3IoJ3JlcXVpcmVkJylcIiB0cmFuc2xhdGU+RVJST1IuRklFTERfUkVRVUlSRUQ8L21hdC1lcnJvcj5cbiAgICAgICAgICA8L21hdC1mb3JtLWZpZWxkPlxuICAgICAgICA8L3RkPlxuICAgICAgPC9uZy1jb250YWluZXI+XG5cbiAgICAgIDwhLS0gRW51bSBjb2x1bW4gIC0tPlxuICAgICAgPCEtLSBOT1RFIDogTmV2ZXIgdXNlZCBpbiB0YWJsZSAgLS0+XG48IS0tICAgICAgPG5nLWNvbnRhaW5lciBtYXRDb2x1bW5EZWY9XCJ2YWx1ZXNcIj4tLT5cbjwhLS0gICAgICAgIDx0aCBtYXQtaGVhZGVyLWNlbGwgKm1hdEhlYWRlckNlbGxEZWY+LS0+XG48IS0tICAgICAgICAgIDxzcGFuIHRyYW5zbGF0ZT5FbnVtczwvc3Bhbj4tLT5cbjwhLS0gICAgICAgIDwvdGg+LS0+XG48IS0tICAgICAgICA8dGQgbWF0LWNlbGwgKm1hdENlbGxEZWY9XCJsZXQgcm93XCIgW2NsYXNzLm1hdC1mb3JtLWZpZWxkLWRpc2FibGVkXT1cIiFyb3cuZWRpdGluZ1wiPi0tPlxuPCEtLSAgICAgICAgICA8YXBwLWZvcm0tZmllbGQtLT5cbjwhLS0gICAgICAgICAgICBbZm9ybUNvbnRyb2xdPVwicm93LnZhbGlkYXRvcnxmb3JtR2V0Q29udHJvbDoncHJvcGVydGllcy52YWx1ZXMnXCItLT5cbjwhLS0gICAgICAgICAgICBbZGVmaW5pdGlvbl09XCJjb2x1bW5EZWZpbml0aW9uc1sndmFsdWVzJ11cIi0tPlxuPCEtLSAgICAgICAgICA+PC9hcHAtZm9ybS1maWVsZD4tLT5cbjwhLS0gICAgICAgIDwvdGQ+LS0+XG48IS0tICAgICAgPC9uZy1jb250YWluZXI+LS0+XG5cbiAgICAgIDwhLS0gQ3JlYXRpb24gZGF0ZSBjb2x1bW4gLS0+XG4gICAgICA8bmctY29udGFpbmVyIG1hdENvbHVtbkRlZj1cInVwZGF0ZURhdGVcIj5cbiAgICAgICAgPHRoIG1hdC1oZWFkZXItY2VsbCAqbWF0SGVhZGVyQ2VsbERlZiBtYXQtc29ydC1oZWFkZXI+XG4gICAgICAgICAgPGlvbi1sYWJlbCB0cmFuc2xhdGU+VEFCTEUuVEVTVElORy5VUERBVEVfREFURTwvaW9uLWxhYmVsPlxuICAgICAgICA8L3RoPlxuICAgICAgICA8dGQgbWF0LWNlbGwgKm1hdENlbGxEZWY9XCJsZXQgcm93XCIgY2xhc3M9XCJtYXQtZm9ybS1maWVsZC1kaXNhYmxlZFwiPlxuICAgICAgICAgIDxpb24tdGV4dCBjb2xvcj1cIm1lZGl1bVwiICpuZ0lmPVwicm93LmlkIT09LTFcIj5cbiAgICAgICAgICAgIDxzbWFsbD5cbiAgICAgICAgICAgICAge3sgcm93LnZhbGlkYXRvcnwgZm9ybUdldFZhbHVlOiAnY3JlYXRpb25EYXRlJyB8IGRhdGVGb3JtYXQ6IHt0aW1lOiB0cnVlfSB9fVxuICAgICAgICAgICAgPC9zbWFsbD5cbiAgICAgICAgICA8L2lvbi10ZXh0PlxuICAgICAgICA8L3RkPlxuICAgICAgPC9uZy1jb250YWluZXI+XG5cbiAgICAgIDwhLS0gQ29tbWVudCBjb2x1bW4gLS0+XG4gICAgICA8bmctY29udGFpbmVyIG1hdENvbHVtbkRlZj1cImNvbW1lbnRzXCI+XG4gICAgICAgIDx0aCBtYXQtaGVhZGVyLWNlbGwgKm1hdEhlYWRlckNlbGxEZWY+XG4gICAgICAgICAgPGlvbi1sYWJlbCB0cmFuc2xhdGU+VEFCTEUuVEVTVElORy5DT01NRU5UUzwvaW9uLWxhYmVsPlxuICAgICAgICA8L3RoPlxuICAgICAgICA8dGQgbWF0LWNlbGwgKm1hdENlbGxEZWY9XCJsZXQgcm93XCI+XG4gICAgICAgICAgPG1hdC1mb3JtLWZpZWxkICpuZ0lmPVwicm93LmVkaXRpbmc7IGVsc2UgaWNvbkNvbW1lbnRcIj5cbiAgICAgICAgICAgIDwhLS08dGV4dGFyZWEgbWF0SW5wdXQgW2Zvcm1Db250cm9sXT1cInJvdy52YWxpZGF0b3I/LmNvbnRyb2xzLmNvbW1lbnRzXCJcbiAgICAgICAgICAgICAgICAgICAgICBbcGxhY2Vob2xkZXJdPVwiJ1RBQkxFLlRFU1RJTkcuQ09NTUVOVFMnfHRyYW5zbGF0ZVwiXG4gICAgICAgICAgICAgICAgICAgICAgW3JlYWRvbmx5XT1cIiFyb3cuZWRpdGluZ1wiPjwvdGV4dGFyZWE+LS0+XG5cbiAgICAgICAgICAgIDxpbnB1dCB0eXBlPVwidGV4dFwiIG1hdElucHV0IFtmb3JtQ29udHJvbF09XCJyb3cudmFsaWRhdG9yPy5jb250cm9scy5jb21tZW50c1wiXG4gICAgICAgICAgICAgICAgICAgW3BsYWNlaG9sZGVyXT1cIidUQUJMRS5URVNUSU5HLkNPTU1FTlRTJ3x0cmFuc2xhdGVcIlxuICAgICAgICAgICAgICAgICAgIFtyZWFkb25seV09XCIhcm93LmVkaXRpbmdcIj5cbiAgICAgICAgICA8L21hdC1mb3JtLWZpZWxkPlxuXG4gICAgICAgICAgPG5nLXRlbXBsYXRlICNpY29uQ29tbWVudD5cbiAgICAgICAgICAgIDxtYXQtaWNvbiBjbGFzcz1cImNvbW1lbnRcIlxuICAgICAgICAgICAgICAgICAgICAgICpuZ0lmPVwicm93LnZhbGlkYXRvcj8uY29udHJvbHMuY29tbWVudHMudmFsdWVcIlxuICAgICAgICAgICAgICAgICAgICAgIFt0aXRsZV09XCJyb3cudmFsaWRhdG9yPy5jb250cm9scy5jb21tZW50cy52YWx1ZVwiPjwvbWF0LWljb24+XG4gICAgICAgICAgPC9uZy10ZW1wbGF0ZT5cbiAgICAgICAgPC90ZD5cbiAgICAgIDwvbmctY29udGFpbmVyPlxuXG4gICAgICA8IS0tIEFjdGlvbnMgYnV0dG9ucyBjb2x1bW4gLS0+XG4gICAgICA8YXBwLWFjdGlvbnMtY29sdW1uIFtzdGlja3lFbmRdPVwidHJ1ZVwiIFtjYW5DYW5jZWxdPVwiZmFsc2VcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAob3B0aW9uc0NsaWNrKT1cIm9wZW5TZWxlY3RDb2x1bW5zTW9kYWwoJGV2ZW50KVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgIChjYW5jZWxPckRlbGV0ZUNsaWNrKT1cImNhbmNlbE9yRGVsZXRlKCRldmVudC5ldmVudCwgJGV2ZW50LnJvdylcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAoY29uZmlybUFuZEFkZENsaWNrKT1cImNvbmZpcm1BbmRBZGQoJGV2ZW50LmV2ZW50LCAkZXZlbnQucm93KVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgIChiYWNrd2FyZCk9XCJjb25maXJtQW5kQmFja3dhcmQoJGV2ZW50LmV2ZW50LCAkZXZlbnQucm93KVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgIChmb3J3YXJkKT1cImNvbmZpcm1BbmRGb3J3YXJkKCRldmVudC5ldmVudCwgJGV2ZW50LnJvdylcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICBbY2VsbFRlbXBsYXRlXT1cImNlbGxJbmplY3Rpb25cIj5cblxuICAgICAgICA8IS0tIGNlbGwgaW5qZWN0aW9uLS0+XG4gICAgICAgIDxuZy10ZW1wbGF0ZSAjY2VsbEluamVjdGlvbiBsZXQtcm93PlxuICAgICAgICAgIDxzcGFuICpuZ0lmPVwicm93LmVkaXRpbmcgJiYgIXJvdy52YWxpZGF0b3IuZGlydHlcIj4tPC9zcGFuPlxuICAgICAgICA8L25nLXRlbXBsYXRlPlxuXG4gICAgICA8L2FwcC1hY3Rpb25zLWNvbHVtbj5cblxuICAgICAgPHRyIG1hdC1oZWFkZXItcm93ICptYXRIZWFkZXJSb3dEZWY9XCJncm91cENvbHVtbnM7XCIgY2xhc3M9XCJtYXQtdG9vbGJhclwiPjwvdHI+XG4gICAgICA8dHIgbWF0LWhlYWRlci1yb3cgKm1hdEhlYWRlclJvd0RlZj1cImRpc3BsYXllZENvbHVtbnM7IHN0aWNreTogdHJ1ZVwiPjwvdHI+XG4gICAgICA8dHIgbWF0LXJvdyAqbWF0Um93RGVmPVwibGV0IHJvdzsgY29sdW1uczogZGlzcGxheWVkQ29sdW1ucztcIlxuICAgICAgICAgIFtjbGFzcy5tYXQtcm93LXNlbGVjdGVkXT1cInJvdy5lZGl0aW5nXCJcbiAgICAgICAgICBbY2xhc3MubWF0LXJvdy1lcnJvcl09XCJyb3cudmFsaWRhdG9yPy5pbnZhbGlkXCJcbiAgICAgICAgICBbY2xhc3MubWF0LXJvdy1kaXNhYmxlZF09XCIhcm93LmVkaXRpbmdcIlxuICAgICAgICAgIFtjbGFzcy5tYXQtcm93LWRpcnR5XT1cInJvdy52YWxpZGF0b3I/LmRpcnR5XCJcbiAgICAgICAgICAoY2xpY2spPVwiY2xpY2tSb3coJGV2ZW50LCByb3cpXCJcbiAgICAgICAgICAoa2V5ZG93bi5lc2NhcGUpPVwiZXNjYXBlRWRpdGluZ1JvdygkZXZlbnQpXCJcbiAgICAgICAgICBbY2RrVHJhcEZvY3VzXT1cInJvdy52YWxpZGF0b3I/LmludmFsaWRcIj48L3RyPlxuICAgIDwvdGFibGU+XG5cbiAgICA8bmctY29udGFpbmVyICpuZ0lmPVwibG9hZGluZ1N1YmplY3R8YXN5bmM7IGVsc2Ugbm9SZXN1bHRcIj5cbiAgICAgIDxpb24taXRlbT5cbiAgICAgICAgPGlvbi1za2VsZXRvbi10ZXh0IGFuaW1hdGVkPjwvaW9uLXNrZWxldG9uLXRleHQ+XG4gICAgICA8L2lvbi1pdGVtPlxuICAgIDwvbmctY29udGFpbmVyPlxuXG4gICAgPG5nLXRlbXBsYXRlICNub1Jlc3VsdD5cbiAgICAgIDxpb24taXRlbSAqbmdJZj1cInRvdGFsUm93Q291bnQgPT09IDBcIj5cbiAgICAgICAgPGlvbi10ZXh0IGNvbG9yPVwiZGFuZ2VyXCIgY2xhc3M9XCJ0ZXh0LWl0YWxpY1wiIHRyYW5zbGF0ZT5DT01NT04uTk9fUkVTVUxUPC9pb24tdGV4dD5cbiAgICAgIDwvaW9uLWl0ZW0+XG4gICAgPC9uZy10ZW1wbGF0ZT5cblxuICAgIDxpb24taW5maW5pdGUtc2Nyb2xsICpuZ0lmPVwiZW5hYmxlSW5maW5pdGVTY3JvbGxcIlxuICAgICAgICAgICAgICAgICAgICAgICAgIFt0aHJlc2hvbGRdPVwibW9iaWxlID8gJzEwJScgOiAnMiUnXCIgcG9zaXRpb249XCJib3R0b21cIlxuICAgICAgICAgICAgICAgICAgICAgICAgIChpb25JbmZpbml0ZSk9XCJmZXRjaE1vcmUoJGV2ZW50KVwiPlxuICAgICAgPGlvbi1pbmZpbml0ZS1zY3JvbGwtY29udGVudFxuICAgICAgICBsb2FkaW5nU3Bpbm5lcj1cImNpcmNsZXNcIlxuICAgICAgICBbbG9hZGluZ1RleHRdPVwiJ0NPTU1PTi5MT0FESU5HX0RPVFMnfHRyYW5zbGF0ZVwiPlxuICAgICAgPC9pb24taW5maW5pdGUtc2Nyb2xsLWNvbnRlbnQ+XG4gICAgPC9pb24taW5maW5pdGUtc2Nyb2xsPlxuICA8L2Rpdj5cbjwvaW9uLWNvbnRlbnQ+XG5cbjxpb24tZm9vdGVyPlxuICA8IS0tIFBhZ2luYXRvciAgLS0+XG4gIDxtYXQtcGFnaW5hdG9yICpuZ0lmPVwiIWVuYWJsZUluZmluaXRlU2Nyb2xsXCJcbiAgICAgICAgICAgICAgICAgW2xlbmd0aF09XCJ0b3RhbFJvd0NvdW50XCIgW3BhZ2VTaXplXT1cImRlZmF1bHRQYWdlU2l6ZVwiIFtwYWdlU2l6ZU9wdGlvbnNdPVwiZGVmYXVsdFBhZ2VTaXplT3B0aW9uc1wiXG4gICAgICAgICAgICAgICAgIGNsYXNzPVwibWF0LXBhZ2luYXRvci1mb290ZXJcIlxuICAgICAgICAgICAgICAgICBzaG93Rmlyc3RMYXN0QnV0dG9ucz5cbiAgPC9tYXQtcGFnaW5hdG9yPlxuXG4gIDxhcHAtZm9ybS1idXR0b25zLWJhciAqbmdJZj1cImNhbkVkaXQgJiYgIW1vYmlsZVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAob25DYW5jZWwpPVwibG9hZCgpXCJcbiAgICAgICAgICAgICAgICAgICAgICAgIChvblNhdmUpPVwic2F2ZSgpXCJcbiAgICAgICAgICAgICAgICAgICAgICAgIFtkaXNhYmxlZF09XCIobG9hZGluZ1N1YmplY3R8YXN5bmMpIHx8ICFkaXJ0eVwiPlxuICAgIDwhLS0gZXJyb3IgLS0+XG4gICAgPGlvbi1pdGVtICpuZ0lmPVwiZXJyb3IkfGFzeW5jXCIgbGluZXM9XCJub25lXCI+XG4gICAgICA8aW9uLWljb24gY29sb3I9XCJkYW5nZXJcIiBzbG90PVwic3RhcnRcIiBuYW1lPVwiYWxlcnQtY2lyY2xlXCI+PC9pb24taWNvbj5cbiAgICAgIDxpb24tbGFiZWwgY29sb3I9XCJkYW5nZXJcIiBbaW5uZXJIVE1MXT1cImVycm9yfHRyYW5zbGF0ZVwiPjwvaW9uLWxhYmVsPlxuICAgIDwvaW9uLWl0ZW0+XG4gIDwvYXBwLWZvcm0tYnV0dG9ucy1iYXI+XG48L2lvbi1mb290ZXI+XG5cbjxpb24tZmFiIHNsb3Q9XCJmaXhlZFwiIHZlcnRpY2FsPVwiYm90dG9tXCIgaG9yaXpvbnRhbD1cImVuZFwiXG4gICAgICAgICAqbmdJZj1cImNhbkVkaXQgJiYgbW9iaWxlXCI+XG4gIDxpb24tZmFiLWJ1dHRvbiBjb2xvcj1cInRlcnRpYXJ5XCIgKGNsaWNrKT1cImFkZFJvdygkZXZlbnQpXCI+XG4gICAgPGlvbi1pY29uIG5hbWU9XCJhZGRcIj48L2lvbi1pY29uPlxuICA8L2lvbi1mYWItYnV0dG9uPlxuPC9pb24tZmFiPlxuIl19
291
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidGFibGUudGVzdGluZy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uLy4uLy4uL3NyYy9hcHAvY29yZS90YWJsZS90ZXN0aW5nL3RhYmxlLnRlc3RpbmcudHMiLCIuLi8uLi8uLi8uLi8uLi8uLi8uLi9zcmMvYXBwL2NvcmUvdGFibGUvdGVzdGluZy90YWJsZS50ZXN0aW5nLmh0bWwiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUVMLHVCQUF1QixFQUV2QixTQUFTLEVBQ1QsVUFBVSxFQUVWLEtBQUssRUFHTCxTQUFTLEVBQ1YsTUFBTSxlQUFlLENBQUM7QUFDdkIsT0FBTyxFQUFDLFFBQVEsRUFBQyxNQUFNLGdCQUFnQixDQUFDO0FBQ3hDLE9BQU8sRUFBQyxXQUFXLEVBQUUsVUFBVSxFQUFFLFVBQVUsRUFBQyxNQUFNLHdDQUF3QyxDQUFDO0FBQzNGLE9BQU8sRUFBQyxpQkFBaUIsRUFBQyxNQUFNLGdCQUFnQixDQUFDO0FBQ2pELE9BQU8sRUFBQyx1QkFBdUIsRUFBQyxNQUFNLG9DQUFvQyxDQUFDO0FBQzNFLE9BQU8sRUFBQyx1QkFBdUIsRUFBQyxNQUFNLHNEQUFzRCxDQUFDO0FBQzdGLE9BQU8sRUFBQyxtQkFBbUIsRUFBQyxNQUFNLCtDQUErQyxDQUFDO0FBRWxGLE9BQU8sRUFBQyxLQUFLLEVBQUUsUUFBUSxFQUFDLE1BQU0sMkJBQTJCLENBQUM7QUFDMUQsT0FBTyxFQUFDLG1CQUFtQixFQUFDLE1BQU0sdUJBQXVCLENBQUM7QUFDMUQsT0FBTyxFQUFDLGlCQUFpQixFQUFDLE1BQU0saURBQWlELENBQUM7QUFDbEYsT0FBTyxFQUFDLFlBQVksRUFBRSxNQUFNLEVBQUUsR0FBRyxFQUFDLE1BQU0sZ0JBQWdCLENBQUM7QUFDekQsT0FBTyxFQUFDLGlCQUFpQixFQUFDLE1BQU0sNkJBQTZCLENBQUM7QUFDOUQsT0FBTyxFQUFDLFNBQVMsRUFBQyxNQUFNLGlDQUFpQyxDQUFDO0FBQzFELE9BQU8s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QkFDaEU7cUJBQ0YsbUJBQ2dCLHVCQUF1QixDQUFDLE1BQU07Z0xBb0J0QyxvQkFBb0I7c0JBQTVCLEtBQUs7Z0JBQ0csU0FBUztzQkFBakIsS0FBSztnQkFNd0Msb0JBQW9CO3NCQUFqRSxTQUFTO3VCQUFDLGlCQUFpQixFQUFFLEVBQUMsTUFBTSxFQUFFLElBQUksRUFBQztnQkFDZCxjQUFjO3NCQUEzQyxTQUFTO3VCQUFDLGlCQUFpQiIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7XG4gIEFmdGVyVmlld0luaXQsXG4gIENoYW5nZURldGVjdGlvblN0cmF0ZWd5LFxuICBDaGFuZ2VEZXRlY3RvclJlZixcbiAgQ29tcG9uZW50LFxuICBmb3J3YXJkUmVmLFxuICBJbmplY3RvcixcbiAgSW5wdXQsXG4gIE9uRGVzdHJveSxcbiAgT25Jbml0LFxuICBWaWV3Q2hpbGRcbn0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQge0FwcFRhYmxlfSBmcm9tICcuLi90YWJsZS5jbGFzcyc7XG5pbXBvcnQge1JlZmVyZW50aWFsLCBTdGF0dXNCeUlkLCBTdGF0dXNMaXN0fSBmcm9tICcuLi8uLi9zZXJ2aWNlcy9tb2RlbC9yZWZlcmVudGlhbC5tb2RlbCc7XG5pbXBvcnQge0lvbkluZmluaXRlU2Nyb2xsfSBmcm9tICdAaW9uaWMvYW5ndWxhcic7XG5pbXBvcnQge0VudGl0aWVzVGFibGVEYXRhU291cmNlfSBmcm9tICcuLi9lbnRpdGllcy10YWJsZS1kYXRhc291cmNlLmNsYXNzJztcbmltcG9ydCB7SW5NZW1vcnlFbnRpdGllc1NlcnZpY2V9IGZyb20gJy4uLy4uLy4uL3NoYXJlZC9zZXJ2aWNlcy9tZW1vcnktZW50aXR5LXNlcnZpY2UuY2xhc3MnO1xuaW1wb3J0IHtBcHBWYWxpZGF0b3JTZXJ2aWNlfSBmcm9tICcuLi8uLi9zZXJ2aWNlcy92YWxpZGF0b3IvYmFzZS52YWxpZGF0b3IuY2xhc3MnO1xuaW1wb3J0IHtBYnN0cmFjdENvbnRyb2wsIFVudHlwZWRGb3JtQnVpbGRlciwgVW50eXBlZEZvcm1Hcm91cH0gZnJvbSAnQGFuZ3VsYXIvZm9ybXMnO1xuaW1wb3J0IHtpc05pbCwgaXNOb3ROaWx9IGZyb20gJy4uLy4uLy4uL3NoYXJlZC9mdW5jdGlvbnMnO1xuaW1wb3J0IHtmcm9tVW5peE1zVGltZXN0YW1wfSBmcm9tICcuLi8uLi8uLi9zaGFyZWQvZGF0ZXMnO1xuaW1wb3J0IHtSZWZlcmVudGlhbEZpbHRlcn0gZnJvbSAnLi4vLi4vc2VydmljZXMvdGVzdGluZy9yZWZlcmVudGlhbC1maWx0ZXIubW9kZWwnO1xuaW1wb3J0IHtkZWJvdW5jZVRpbWUsIGZpbHRlciwgdGFwfSBmcm9tICdyeGpzL29wZXJhdG9ycyc7XG5pbXBvcnQge01hdEV4cGFuc2lvblBhbmVsfSBmcm9tICdAYW5ndWxhci9tYXRlcmlhbC9leHBhbnNpb24nO1xuaW1wb3J0IHtTdGF0dXNJZHN9IGZyb20gJy4uLy4uL3NlcnZpY2VzL21vZGVsL21vZGVsLmVudW0nO1xuaW1wb3J0IHtTdWJzY3JpcHRpb24sIHRpbWVyfSBmcm9tICdyeGpzJztcbmltcG9ydCB7REVGQVVMVF9QQUdFX1NJWkUsIFJFU0VSVkVEX0VORF9DT0xVTU5TLCBSRVNFUlZFRF9TVEFSVF9DT0xVTU5TfSBmcm9tICcuLi90YWJsZS5tb2RlbCc7XG5pbXBvcnQge0Zvcm1GaWVsZERlZmluaXRpb25NYXB9IGZyb20gJy4uLy4uLy4uL3NoYXJlZC9mb3JtL2ZpZWxkLm1vZGVsJztcbmltcG9ydCB7VGFibGVWYWxpZGF0b3JTZXJ2aWNlfSBmcm9tICcuL3RhYmxlLXZhbGlkYXRvci5zZXJ2aWNlJztcblxuQENvbXBvbmVudCh7XG4gIHNlbGVjdG9yOiAnYXBwLXRhYmxlLXRlc3RpbmcnLFxuICBzdHlsZVVybHM6IFsndGFibGUudGVzdGluZy5zY3NzJ10sXG4gIHRlbXBsYXRlVXJsOiAndGFibGUudGVzdGluZy5odG1sJyxcbiAgcHJvdmlkZXJzOiBbXG4gICAge1xuICAgICAgcHJvdmlkZTogQXBwVmFsaWRhdG9yU2VydmljZSxcbiAgICAgIHVzZUNsYXNzOiBUYWJsZVZhbGlkYXRvclNlcnZpY2VcbiAgICB9LFxuICAgIHtcbiAgICAgIHByb3ZpZGU6IEFwcFRhYmxlLCB1c2VFeGlzdGluZzogZm9yd2FyZFJlZigoKSA9PiBUYWJsZVRlc3RQYWdlKSxcbiAgICB9XG4gIF0sXG4gIGNoYW5nZURldGVjdGlvbjogQ2hhbmdlRGV0ZWN0aW9uU3RyYXRlZ3kuT25QdXNoXG59KVxuZXhwb3J0IGNsYXNzIFRhYmxlVGVzdFBhZ2UgZXh0ZW5kcyBBcHBUYWJsZTxSZWZlcmVudGlhbCwgUmVmZXJlbnRpYWxGaWx0ZXI+XG4gIGltcGxlbWVudHMgT25Jbml0LCBPbkRlc3Ryb3ksIEFmdGVyVmlld0luaXQge1xuXG4gIHJlYWRvbmx5IG1heFJvd0NvdW50ID0gMTAwO1xuXG4gIHRpbWVyOiBTdWJzY3JpcHRpb247XG4gIGNhbkVkaXQgPSB0cnVlO1xuICBkYXRhOiBSZWZlcmVudGlhbFtdO1xuICBmaWx0ZXJGb3JtOiBVbnR5cGVkRm9ybUdyb3VwO1xuICBmaWx0ZXJDcml0ZXJpYUNvdW50ID0gMDtcbiAgZ3JvdXBDb2x1bW5zID0gWyd0b3Atc3RhcnQnLCAnZ3JvdXAtMScsICdncm91cC0yJywgJ3RvcC1lbmQnXTtcbiAgcm93SGVpZ2h0ID0gNDg7XG4gIHBlcm1hbmVudFNlbGVjdGlvbkFsbG93ZWQgPSB0cnVlO1xuXG4gIHJlYWRvbmx5IHN0YXR1c0xpc3QgPSBTdGF0dXNMaXN0O1xuICByZWFkb25seSBzdGF0dXNCeUlkID0gU3RhdHVzQnlJZDtcbiAgcmVhZG9ubHkgY29sdW1uRGVmaW5pdGlvbnM6IEZvcm1GaWVsZERlZmluaXRpb25NYXAgPSB7fTtcblxuICBASW5wdXQoKSBlbmFibGVJbmZpbml0ZVNjcm9sbDogYm9vbGVhbjtcbiAgQElucHV0KCkgdXNlU3RpY2t5ID0gdHJ1ZTtcblxuICBnZXQgaGFzTW9yZURhdGEoKTogYm9vbGVhbiB7XG4gICAgcmV0dXJuIHRoaXMuZGF0YS5sZW5ndGggPCAxMDA7XG4gIH1cblxuICBAVmlld0NoaWxkKE1hdEV4cGFuc2lvblBhbmVsLCB7c3RhdGljOiB0cnVlfSkgZmlsdGVyRXhwYW5zaW9uUGFuZWw6IE1hdEV4cGFuc2lvblBhbmVsO1xuICBAVmlld0NoaWxkKElvbkluZmluaXRlU2Nyb2xsKSBpbmZpbml0ZVNjcm9sbDogSW9uSW5maW5pdGVTY3JvbGw7XG5cbiAgZ2V0IGRhdGFTZXJ2aWNlKCk6IEluTWVtb3J5RW50aXRpZXNTZXJ2aWNlPFJlZmVyZW50aWFsPntcbiAgICByZXR1cm4gdGhpcy5fZGF0YVNvdXJjZS5kYXRhU2VydmljZSBhcyBJbk1lbW9yeUVudGl0aWVzU2VydmljZTxSZWZlcmVudGlhbD47XG4gIH1cblxuICBjb25zdHJ1Y3RvcihpbmplY3RvcjogSW5qZWN0b3IsXG4gICAgICAgICAgICAgIHByb3RlY3RlZCB2YWxpZGF0b3JTZXJ2aWNlOiBBcHBWYWxpZGF0b3JTZXJ2aWNlLFxuICAgICAgICAgICAgICBwcm90ZWN0ZWQgZm9ybUJ1aWxkZXI6IFVudHlwZWRGb3JtQnVpbGRlcixcbiAgICAgICAgICAgICAgcHJvdGVjdGVkIGNkOiBDaGFuZ2VEZXRlY3RvclJlZlxuICAgICAgICAgICAgICApIHtcbiAgICBzdXBlcihpbmplY3RvciwgW1xuICAgICAgLi4uUkVTRVJWRURfU1RBUlRfQ09MVU1OUyxcbiAgICAgICdsYWJlbCcsXG4gICAgICAnbmFtZScsXG4gICAgICAnbGV2ZWxJZCcsXG4gICAgICAnc3RhdHVzSWQnLFxuICAgICAgLy8gJ3ZhbHVlcycsXG4gICAgICAndXBkYXRlRGF0ZScsXG4gICAgICAnY29tbWVudHMnLFxuICAgICAgLi4uUkVTRVJWRURfRU5EX0NPTFVNTlNcbiAgICBdLFxuICAgICAgbmV3IEVudGl0aWVzVGFibGVEYXRhU291cmNlKFJlZmVyZW50aWFsLCBuZXcgSW5NZW1vcnlFbnRpdGllc1NlcnZpY2UoUmVmZXJlbnRpYWwsIFJlZmVyZW50aWFsRmlsdGVyLCB7XG4gICAgICAgIHNvcnRCeVJlcGxhY2VtZW50OiB7aWQ6ICdpZCd9XG4gICAgICB9KSwgdmFsaWRhdG9yU2VydmljZSwge1xuICAgICAgICBzdXBwcmVzc0Vycm9yczogZmFsc2VcbiAgICAgIH0pLFxuICAgICAgbnVsbCk7XG5cbiAgICAvLyBXb3JrcyB3aXRoIHRydWUgYW5kIGZhbHNlXG4gICAgdGhpcy5lbmFibGVJbmZpbml0ZVNjcm9sbCA9IHRoaXMubW9iaWxlO1xuXG4gICAgdGhpcy5hdXRvTG9hZCA9IGZhbHNlO1xuICAgIHRoaXMuaW5saW5lRWRpdGlvbiA9IHRydWU7XG4gICAgdGhpcy5pMThuQ29sdW1uUHJlZml4ID0gJ1RBQkxFLlRFU1RJTkcuJztcblxuICAgIHRoaXMuY29uZmlybUJlZm9yZURlbGV0ZSA9IHRydWU7XG4gICAgdGhpcy5jb25maXJtQmVmb3JlQ2FuY2VsID0gZmFsc2U7XG4gICAgdGhpcy51bmRvYWJsZURlbGV0aW9uID0gZmFsc2U7XG4gICAgdGhpcy5zYXZlQmVmb3JlRGVsZXRlID0gZmFsc2U7XG5cbiAgICB0aGlzLnNhdmVCZWZvcmVTb3J0ID0gdHJ1ZTtcbiAgICB0aGlzLnNhdmVCZWZvcmVGaWx0ZXIgPSB0cnVlO1xuICAgIHRoaXMucHJvcGFnYXRlUm93RXJyb3IgPSB0cnVlO1xuXG4gICAgdGhpcy5maWx0ZXJGb3JtID0gZm9ybUJ1aWxkZXIuZ3JvdXAoe1xuICAgICAgc2VhcmNoVGV4dDogW251bGxdXG4gICAgfSk7XG5cbiAgICAvLyB0aGlzLmNvbHVtbkRlZmluaXRpb25zWyd2YWx1ZXMnXSA9IDxGb3JtRmllbGREZWZpbml0aW9uPntcbiAgICAvLyAgIGtleTogJ3ZhbHVlcycsXG4gICAgLy8gICB0eXBlOiAnZW51bXMnLFxuICAgIC8vICAgdmFsdWVzOiBbXG4gICAgLy8gICAgIHtrZXk6ICdBJywgdmFsdWU6ICdWYWx1ZSBBJ30sXG4gICAgLy8gICAgIHtrZXk6ICdCJywgdmFsdWU6ICdWYWx1ZSBCJ31cbiAgICAvLyAgIF1cbiAgICAvLyB9O1xuXG4gICAgdGhpcy5vblN0YXJ0RWRpdGluZ1Jvdy5zdWJzY3JpYmUocm93ID0+IHtcbiAgICAgIHJvdy52YWxpZGF0b3IucGF0Y2hWYWx1ZSh7ZW50aXR5TmFtZTogJ1Rlc3RWTyd9LCB7ZW1pdEV2ZW50OiBmYWxzZX0pO1xuICAgIH0pO1xuICB9XG5cbiAgbmdPbkluaXQoKSB7XG4gICAgc3VwZXIubmdPbkluaXQoKTtcblxuICAgIC8vIFVwZGF0ZSBmaWx0ZXIgd2hlbiBjaGFuZ2VzXG4gICAgdGhpcy5yZWdpc3RlclN1YnNjcmlwdGlvbihcbiAgICAgIHRoaXMuZmlsdGVyRm9ybS52YWx1ZUNoYW5nZXNcbiAgICAgICAgLnBpcGUoXG4gICAgICAgICAgZGVib3VuY2VUaW1lKDI1MCksXG4gICAgICAgICAgZmlsdGVyKCgpID0+IHRoaXMuZmlsdGVyRm9ybS52YWxpZCksXG4gICAgICAgICAgdGFwKHZhbHVlID0+IHtcbiAgICAgICAgICAgIGNvbnN0IGZpbHRlciA9IFJlZmVyZW50aWFsRmlsdGVyLmZyb21PYmplY3QodmFsdWUpO1xuICAgICAgICAgICAgdGhpcy5maWx0ZXJDcml0ZXJpYUNvdW50ID0gZmlsdGVyLmNvdW50Tm90RW1wdHlDcml0ZXJpYSgpO1xuICAgICAgICAgICAgdGhpcy5tYXJrRm9yQ2hlY2soKTtcbiAgICAgICAgICAgIC8vIEFwcGx5aW5nIHRoZSBmaWx0ZXJcbiAgICAgICAgICAgIHRoaXMuc2V0RmlsdGVyKGZpbHRlciwge2VtaXRFdmVudDogZmFsc2V9KTtcbiAgICAgICAgICB9KSxcbiAgICAgICAgICAvLyBTYXZlIGZpbHRlciBpbiBzZXR0aW5ncyAoYWZ0ZXIgYSBkZWJvdW5jZSB0aW1lKVxuICAgICAgICAgIGRlYm91bmNlVGltZSg1MDApLFxuICAgICAgICAgIHRhcChqc29uID0+IHRoaXMuc2V0dGluZ3Muc2F2ZVBhZ2VTZXR0aW5nKHRoaXMuc2V0dGluZ3NJZCwganNvbiwgJ2ZpbHRlcicpKVxuICAgICAgICApXG4gICAgICAgIC5zdWJzY3JpYmUoKVxuICAgICk7XG5cbiAgICB0aGlzLnJlZ2lzdGVyQXV0b2NvbXBsZXRlRmllbGQoJ2xldmVsJywge1xuICAgICAgICBpdGVtczogW1xuICAgICAgICAgIHtpZDogMSwgbGFiZWw6ICdBJywgbmFtZTogJ2l0ZW0gQSd9LFxuICAgICAgICAgIHtpZDogMSwgbGFiZWw6ICdCJywgbmFtZTogJ2l0ZW0gQid9XG4gICAgICAgIF0sXG4gICAgICAgIG1vYmlsZTogdGhpcy5tb2JpbGVcbiAgICAgIH0pO1xuXG4gICAgdGhpcy5yZWdpc3RlclN1YnNjcmlwdGlvbihcbiAgICAgIHRoaXMub25SZWZyZXNoLnN1YnNjcmliZSgoKSA9PiB7XG4gICAgICAgIHRoaXMuZmlsdGVyRm9ybS5tYXJrQXNVbnRvdWNoZWQoKTtcbiAgICAgICAgdGhpcy5maWx0ZXJGb3JtLm1hcmtBc1ByaXN0aW5lKCk7XG4gICAgICB9KSk7XG5cbiAgICB0aGlzLm1hcmtBc1JlYWR5KCk7XG4gIH1cblxuICBuZ0FmdGVyVmlld0luaXQoKSB7XG4gICAgc3VwZXIubmdBZnRlclZpZXdJbml0KCk7XG5cbiAgICAvLyBSZXN0b3JlIGZpbHRlciBmcm9tIHNldHRpbmdzXG4gICAgdGhpcy5yZXN0b3JlRmlsdGVyKCk7XG5cbiAgICAvLyBMb2FkIGRhdGFcbiAgICB0aGlzLmxvYWQoKTtcbiAgfVxuXG4gIG5nT25EZXN0cm95KCkge1xuICAgIGNvbnNvbGUuZGVidWcoJ1t0ZXN0LXRhYmxlXSBEZXN0cm95aW5nIHRhYmxlLi4uJyk7XG4gICAgc3VwZXIubmdPbkRlc3Ryb3koKTtcbiAgICB0aGlzLnN0b3BUaW1lcigpO1xuICAgIC8vdGhpcy5kYXRhU2VydmljZS5zdG9wKCk7XG4gIH1cblxuICBwcm90ZWN0ZWQgcmVzdG9yZUZpbHRlcigpIHtcbiAgICBjb25zdCBqc29uID0gdGhpcy5zZXR0aW5ncy5nZXRQYWdlU2V0dGluZ3ModGhpcy5zZXR0aW5nc0lkLCAnZmlsdGVyJyk7XG4gICAgY29uc29sZS5kZWJ1ZygnW3RhYmxlLXRlc3RdIFJlc3RvcmluZyBmaWx0ZXIgZnJvbSBzZXR0aW5ncy4uLicsIGpzb24pO1xuXG4gICAgaWYgKGpzb24pIHtcbiAgICAgIGNvbnN0IGZpbHRlciA9IFJlZmVyZW50aWFsRmlsdGVyLmZyb21PYmplY3QoanNvbik7XG4gICAgICB0aGlzLmZpbHRlckZvcm0ucGF0Y2hWYWx1ZShqc29uLCB7ZW1pdEV2ZW50OiBmYWxzZX0pO1xuICAgICAgdGhpcy5maWx0ZXJDcml0ZXJpYUNvdW50ID0gZmlsdGVyLmNvdW50Tm90RW1wdHlDcml0ZXJpYSgpO1xuICAgICAgdGhpcy5zZXRGaWx0ZXIoZmlsdGVyLCB7ZW1pdEV2ZW50OiBmYWxzZX0pO1xuICAgICAgdGhpcy5tYXJrRm9yQ2hlY2soKTtcbiAgICB9XG4gIH1cblxuICB0b2dnbGVUaW1lcigpIHtcbiAgICBpZiAoaXNOb3ROaWwodGhpcy50aW1lcikpIHRoaXMuc3RvcFRpbWVyKCk7XG4gICAgZWxzZSB0aGlzLnN0YXJ0VGltZXIoKTtcbiAgfVxuXG4gIGxvYWQoKSB7XG4gICAgY29uc29sZS5kZWJ1ZygnW3Rlc3QtdGFibGVdIFVwZGF0aW5nIGRhdGEuLi4nKTtcbiAgICB0aGlzLm1hcmtBc0xvYWRpbmcoKTtcblxuICAgIGlmIChpc05pbCh0aGlzLmRhdGEpKSB7XG4gICAgICB0aGlzLmRhdGEgPSB0aGlzLmdlbmVyYXRlRGF0YSgwLCB0aGlzLm1heFJvd0NvdW50KTtcbiAgICB9XG4gICAgdGhpcy5kYXRhU2VydmljZS52YWx1ZSA9IHRoaXMuZGF0YTtcblxuICAgIHRoaXMub25SZWZyZXNoLmVtaXQoKTtcbiAgfVxuXG4gIGFzeW5jIGZldGNoTW9yZShldmVudCkge1xuICAgIGNvbnNvbGUuZGVidWcoJ1t0YWJsZS10ZXN0XSBMb2FkaW5nIG1vcmUuLi4nLCBldmVudCk7XG4gICAgY29uc3QgZmV0Y2hlZCA9IGF3YWl0IHRoaXMuX2RhdGFTb3VyY2UuZmV0Y2hNb3JlKCk7XG5cbiAgICBpZiAoZmV0Y2hlZCAmJiBldmVudD8udGFyZ2V0ICYmIGV2ZW50LnRhcmdldC5jb21wbGV0ZSkge1xuICAgICAgLy8gV2FpdCBlbmQgb2YgbG9hZFxuICAgICAgYXdhaXQgdGhpcy53YWl0SWRsZSgpO1xuICAgICAgLy8gTWFyayB0YXJnZXQgZXZlbnQgYXMgY29tcGxldGVkIChlLmcuIElvblJlZnJlc2hlcilcbiAgICAgIGV2ZW50LnRhcmdldC5jb21wbGV0ZSgpO1xuICAgIH1cbiAgfVxuXG4gIGFzeW5jIHNhdmUob3B0cz86IHsga2VlcEVkaXRpbmc/OiBib29sZWFuIH0pOiBQcm9taXNlPGJvb2xlYW4+IHtcbiAgICBjb25zdCBzYXZlZCA9IGF3YWl0IHN1cGVyLnNhdmUob3B0cyk7XG4gICAgaWYgKHNhdmVkKSB7XG4gICAgICAvLyBVcGRhdGUgc291cmNlIGRhdGFcbiAgICAgIHRoaXMuZGF0YSA9IHRoaXMuZGF0YVNlcnZpY2UudmFsdWU7XG4gICAgfVxuICAgIHJldHVybiBzYXZlZDtcbiAgfVxuXG4gIGNsZWFyQ29udHJvbFZhbHVlKGV2ZW50OiBFdmVudCwgZm9ybUNvbnRyb2w6IEFic3RyYWN0Q29udHJvbCk6IGJvb2xlYW4ge1xuICAgIGlmIChldmVudCkgZXZlbnQuc3RvcFByb3BhZ2F0aW9uKCk7IC8vIEF2b2lkIHRvIGVudGVyIGlucHV0IHRoZSBmaWVsZFxuICAgIGZvcm1Db250cm9sLnNldFZhbHVlKG51bGwpO1xuICAgIHJldHVybiBmYWxzZTtcbiAgfVxuXG4gIGFwcGx5RmlsdGVyQW5kQ2xvc2VQYW5lbChldmVudD86IEV2ZW50KSB7XG4gICAgdGhpcy5kZWZhdWx0UGFnZVNpemUgPSBERUZBVUxUX1BBR0VfU0laRTtcbiAgICB0aGlzLm9uUmVmcmVzaC5lbWl0KGV2ZW50KTtcbiAgICB0aGlzLmZpbHRlckV4cGFuc2lvblBhbmVsLmNsb3NlKCk7XG4gIH1cblxuICByZXNldEZpbHRlcihfPzogRXZlbnQpIHtcbiAgICB0aGlzLmZpbHRlckZvcm0ucmVzZXQoe30sIHtlbWl0RXZlbnQ6IHRydWV9KTtcbiAgICB0aGlzLnNldEZpbHRlcihSZWZlcmVudGlhbEZpbHRlci5mcm9tT2JqZWN0KHt9KSwge2VtaXRFdmVudDogdHJ1ZX0pO1xuICAgIHRoaXMuZmlsdGVyRXhwYW5zaW9uUGFuZWwuY2xvc2UoKTtcbiAgfVxuXG4gIHN0YXJ0VGltZXIoKSB7XG4gICAgdGhpcy5zdG9wVGltZXIoKTtcbiAgICB0aGlzLnRpbWVyID0gdGltZXIoNTAwKVxuICAgICAgLnN1YnNjcmliZSgoKSA9PiB7XG4gICAgICAgIHRoaXMuZGF0YSA9IG51bGw7IC8vIFJlc2V0XG4gICAgICAgIHRoaXMubG9hZCgpO1xuICAgICAgfSk7XG4gIH1cblxuICBzdG9wVGltZXIoKSB7XG4gICAgdGhpcy50aW1lcj8udW5zdWJzY3JpYmUoKTtcbiAgICB0aGlzLnRpbWVyID0gbnVsbDtcbiAgfVxuXG4gIHByb3RlY3RlZCBnZW5lcmF0ZURhdGEob2Zmc2V0PzogbnVtYmVyLCBzaXplPzogbnVtYmVyLCApOiBSZWZlcmVudGlhbFtdIHtcbiAgICBvZmZzZXQgPSBvZmZzZXQgfHwgMDtcbiAgICBzaXplID0gc2l6ZSB8fCAxMDA7XG5cbiAgICBjb25zdCByZXN1bHQgPSBuZXcgQXJyYXk8UmVmZXJlbnRpYWw+KCk7XG4gICAgZm9yIChsZXQgaSA9IDA7IGkgPCBzaXplOyBpKyspIHtcbiAgICAgIGNvbnN0IGlkID0gaSArIDEgKyBvZmZzZXQ7XG4gICAgICBjb25zdCBpdGVtID0gUmVmZXJlbnRpYWwuZnJvbU9iamVjdCh7XG4gICAgICAgIGlkLFxuICAgICAgICBsYWJlbDogJ0NPREUtJyArIGlkLFxuICAgICAgICBuYW1lOiAnTmFtZSAjJyArIGlkLFxuICAgICAgICBsZXZlbElkOiB7aWQ6IDEsIGxhYmVsOiAnQScsIG5hbWU6ICdJdGVtIEEnfSxcbiAgICAgICAgc3RhdHVzSWQ6IFN0YXR1c0lkcy5FTkFCTEUsXG4gICAgICAgIGNvbW1lbnRzOiAnTXkgY29tbWVudCAjJyArIGlkLFxuICAgICAgICBwcm9wZXJ0aWVzOiB7XG4gICAgICAgICAgdmFsdWVzOiBpICUgMiA9PT0gMCA/ICdBJyA6ICdBLEInXG4gICAgICAgIH0sXG4gICAgICAgIGNyZWF0aW9uRGF0ZTogZnJvbVVuaXhNc1RpbWVzdGFtcChEYXRlLm5vdygpIC0gaSAqIDYwICogMTAwMCksXG4gICAgICAgIHVwZGF0ZURhdGU6IGZyb21Vbml4TXNUaW1lc3RhbXAoRGF0ZS5ub3coKSAtIGkgKiA2MCAqIDEwMDApLFxuICAgICAgICBlbnRpdHlOYW1lOiAnVGVzdFZPJ1xuICAgICAgfSk7XG4gICAgICByZXN1bHQucHVzaChpdGVtKTtcbiAgICB9XG5cbiAgICByZXR1cm4gcmVzdWx0O1xuICB9XG5cbiAgcHJvdGVjdGVkIG1hcmtGb3JDaGVjaygpIHtcbiAgICB0aGlzLmNkLm1hcmtGb3JDaGVjaygpO1xuICB9XG59XG4iLCI8YXBwLXRvb2xiYXIgY29sb3I9XCJwcmltYXJ5XCIgW2NhbkdvQmFja109XCJ0cnVlXCJcbiAgICAgICAgICAgICBbaGFzVmFsaWRhdGVdPVwiIShsb2FkaW5nU3ViamVjdHxhc3luYykgJiYgZGlydHlcIlxuICAgICAgICAgICAgIChvblZhbGlkYXRlKT1cInNhdmUoKVwiXG4gICAgICAgICAgICAgW2JhY2tIcmVmXT1cIicvdGVzdGluZydcIj5cbiAgPGlvbi10aXRsZT5UYWJsZSAoY2xpY2sgdG8gZWRpdCk8L2lvbi10aXRsZT5cbiAgPGlvbi1idXR0b25zIHNsb3Q9XCJlbmRcIj5cblxuXG4gICAgPG5nLWNvbnRhaW5lciAqbmdJZj1cIiFzZWxlY3Rpb24uaGFzVmFsdWUoKTsgZWxzZSBoYXNTZWxlY3Rpb25cIj5cblxuICAgICAgPGlucHV0IG1hdElucHV0IHR5cGU9XCJudW1iZXJcIiBzdGVwPVwiMVwiIHN0eWxlPVwiY29sb3I6YmxhY2s7IHdpZHRoOiA1MHB4O1wiIFsobmdNb2RlbCldPVwicm93SGVpZ2h0XCI+XG5cbiAgICAgIDwhLS0gQWRkIC0tPlxuICAgICAgPGJ1dHRvbiBtYXQtaWNvbi1idXR0b25cbiAgICAgICAgICAgICAgKm5nSWY9XCJjYW5FZGl0ICYmICFtb2JpbGVcIlxuICAgICAgICAgICAgICBbdGl0bGVdPVwiJ0NPTU1PTi5CVE5fQUREJ3x0cmFuc2xhdGVcIlxuICAgICAgICAgICAgICAoY2xpY2spPVwiYWRkUm93KClcIj5cbiAgICAgICAgPG1hdC1pY29uPmFkZDwvbWF0LWljb24+XG4gICAgICA8L2J1dHRvbj5cblxuICAgICAgPCEtLSByZXNldCBmaWx0ZXIgLS0+XG4gICAgICA8YnV0dG9uIG1hdC1pY29uLWJ1dHRvbiAoY2xpY2spPVwicmVzZXRGaWx0ZXIoKVwiXG4gICAgICAgICAgICAgICpuZ0lmPVwiZmlsdGVyQ3JpdGVyaWFDb3VudFwiPlxuICAgICAgICA8bWF0LWljb24gY29sb3I9XCJhY2NlbnRcIj5maWx0ZXJfbGlzdF9hbHQ8L21hdC1pY29uPlxuICAgICAgICA8bWF0LWljb24gY2xhc3M9XCJpY29uLXNlY29uZGFyeVwiIHN0eWxlPVwibGVmdDogMTZweDsgdG9wOiA1cHg7IGZvbnQtd2VpZ2h0OiBib2xkO1wiPmNsb3NlPC9tYXQtaWNvbj5cbiAgICAgIDwvYnV0dG9uPlxuXG4gICAgICA8IS0tIHNob3cgZmlsdGVyIC0tPlxuICAgICAgPGJ1dHRvbiBtYXQtaWNvbi1idXR0b24gKGNsaWNrKT1cImZpbHRlckV4cGFuc2lvblBhbmVsLnRvZ2dsZSgpXCI+XG4gICAgICAgIDxtYXQtaWNvbiAqbmdJZj1cImZpbHRlckNyaXRlcmlhQ291bnQ7IGVsc2UgZW1wdHlGaWx0ZXJcIlxuICAgICAgICAgICAgICAgICAgW21hdEJhZGdlXT1cImZpbHRlckNyaXRlcmlhQ291bnRcIlxuICAgICAgICAgICAgICAgICAgbWF0QmFkZ2VDb2xvcj1cImFjY2VudFwiXG4gICAgICAgICAgICAgICAgICBtYXRCYWRnZVNpemU9XCJzbWFsbFwiXG4gICAgICAgICAgICAgICAgICBtYXRCYWRnZVBvc2l0aW9uPVwiYWJvdmUgYWZ0ZXJcIj5maWx0ZXJfbGlzdF9hbHRcbiAgICAgICAgPC9tYXQtaWNvbj5cbiAgICAgICAgPG5nLXRlbXBsYXRlICNlbXB0eUZpbHRlcj5cbiAgICAgICAgICA8bWF0LWljb24+ZmlsdGVyX2xpc3RfYWx0PC9tYXQtaWNvbj5cbiAgICAgICAgPC9uZy10ZW1wbGF0ZT5cbiAgICAgIDwvYnV0dG9uPlxuXG4gICAgICA8IS0tIHNhdmUgLS0+XG4gICAgICA8YnV0dG9uIG1hdC1pY29uLWJ1dHRvbiAqbmdJZj1cIm1vYmlsZVwiXG4gICAgICAgICAgICAgIFtkaXNhYmxlZF09XCIhKGRpcnR5U3ViamVjdHxhc3luYylcIlxuICAgICAgICAgICAgICAoY2xpY2spPVwic2F2ZSgpXCI+XG4gICAgICAgIDxtYXQtaWNvbj5zYXZlPC9tYXQtaWNvbj5cbiAgICAgIDwvYnV0dG9uPlxuXG4gICAgICA8IS0tIHN0YXJ0L3N0b3AgdGltZXIgdG8gYXV0by1sb2FkIGRhdGEgLS0+XG4gICAgICA8aW9uLWJ1dHRvbiAqbmdJZj1cIiF0aW1lclwiIChjbGljayk9XCJzdGFydFRpbWVyKClcIj5TdGFydCByZWxvYWQ8L2lvbi1idXR0b24+XG4gICAgICA8aW9uLWJ1dHRvbiAqbmdJZj1cInRpbWVyXCIgKGNsaWNrKT1cInN0b3BUaW1lcigpXCIgY29sb3I9XCJhY2NlbnRcIj5TdG9wIHJlbG9hZDwvaW9uLWJ1dHRvbj5cbiAgICA8L25nLWNvbnRhaW5lcj5cblxuICAgIDwhLS0gaWYgcm93IHNlbGVjdGlvbiAtLT5cbiAgICA8bmctdGVtcGxhdGUgI2hhc1NlbGVjdGlvbj5cblxuICAgICAgPCEtLSBkZWxldGUgLS0+XG4gICAgICA8YnV0dG9uIG1hdC1pY29uLWJ1dHRvblxuICAgICAgICAgICAgICAqbmdJZj1cImNhbkVkaXRcIiBbdGl0bGVdPVwiJ0NPTU1PTi5CVE5fREVMRVRFJ3x0cmFuc2xhdGVcIlxuICAgICAgICAgICAgICAoY2xpY2spPVwiZGVsZXRlU2VsZWN0aW9uKCRldmVudClcIj5cbiAgICAgICAgPG1hdC1pY29uPmRlbGV0ZTwvbWF0LWljb24+XG4gICAgICA8L2J1dHRvbj5cblxuICAgICAgPCEtLSBkdXBsaWNhdGUgLS0+XG4gICAgICA8YnV0dG9uIG1hdC1pY29uLWJ1dHRvblxuICAgICAgICAgICAgICAqbmdJZj1cImNhbkVkaXQgJiYgc2VsZWN0aW9uLnNlbGVjdGVkIHwgaXNBcnJheUxlbmd0aDoge2VxdWFsczogMX1cIlxuICAgICAgICAgICAgICBbdGl0bGVdPVwiJ0NPTU1PTi5CVE5fRFVQTElDQVRFJ3x0cmFuc2xhdGVcIlxuICAgICAgICAgICAgICAoY2xpY2spPVwiZHVwbGljYXRlUm93KCRldmVudCwgc2VsZWN0aW9uLnNlbGVjdGVkWzBdKVwiPlxuICAgICAgICA8bWF0LWljb24+ZmlsZV9jb3B5PC9tYXQtaWNvbj5cbiAgICAgIDwvYnV0dG9uPlxuICAgIDwvbmctdGVtcGxhdGU+XG4gIDwvaW9uLWJ1dHRvbnM+XG48L2FwcC10b29sYmFyPlxuPGlvbi1jb250ZW50IGNsYXNzPVwiaW9uLW5vLXBhZGRpbmdcIj5cblxuICA8aW9uLXJlZnJlc2hlciBzbG90PVwiZml4ZWRcIiAqbmdJZj1cIm1vYmlsZVwiIChpb25SZWZyZXNoKT1cImRvUmVmcmVzaCgkZXZlbnQpXCI+XG4gICAgPGlvbi1yZWZyZXNoZXItY29udGVudD48L2lvbi1yZWZyZXNoZXItY29udGVudD5cbiAgPC9pb24tcmVmcmVzaGVyPlxuXG4gIDwhLS0gZXJyb3IgLS0+XG4gIDxpb24taXRlbSAqbmdJZj1cIm1vYmlsZSAmJiBlcnJvclwiIGxpbmVzPVwibm9uZVwiIEBzbGlkZVVwRG93bkFuaW1hdGlvbj5cbiAgICA8aW9uLWljb24gY29sb3I9XCJkYW5nZXJcIiBzbG90PVwic3RhcnRcIiBuYW1lPVwiYWxlcnQtY2lyY2xlXCI+PC9pb24taWNvbj5cbiAgICA8aW9uLWxhYmVsIGNvbG9yPVwiZGFuZ2VyXCIgY2xhc3M9XCJlcnJvclwiIFtpbm5lckhUTUxdPVwiZXJyb3J8dHJhbnNsYXRlXCI+PC9pb24tbGFiZWw+XG4gIDwvaW9uLWl0ZW0+XG5cbiAgPCEtLSBzZWFyY2ggLS0+XG4gIDxtYXQtZXhwYW5zaW9uLXBhbmVsICNmaWx0ZXJFeHBhbnNpb25QYW5lbCBjbGFzcz1cImZpbHRlci1wYW5lbCBmaWx0ZXItcGFuZWwtZmxvYXRpbmdcIj5cbiAgICA8Zm9ybSBjbGFzcz1cImZvcm0tY29udGFpbmVyIGlvbi1wYWRkaW5nLXRvcFwiIFtmb3JtR3JvdXBdPVwiZmlsdGVyRm9ybVwiIChuZ1N1Ym1pdCk9XCJhcHBseUZpbHRlckFuZENsb3NlUGFuZWwoJGV2ZW50KVwiPlxuXG4gICAgICA8aW9uLWdyaWQ+XG4gICAgICAgIDxpb24tcm93PlxuICAgICAgICAgIDxpb24tY29sPlxuICAgICAgICAgICAgPCEtLSBzZWFyY2ggdGV4dCAtLT5cbiAgICAgICAgICAgIDxtYXQtZm9ybS1maWVsZD5cbiAgICAgICAgICAgICAgPG1hdC1sYWJlbD57eydUQUJMRS5URVNUSU5HLlNFQVJDSF9URVhUJ3x0cmFuc2xhdGV9fTwvbWF0LWxhYmVsPlxuICAgICAgICAgICAgICA8aW9uLWljb24gbWF0UHJlZml4IG5hbWU9XCJzZWFyY2hcIj48L2lvbi1pY29uPlxuICAgICAgICAgICAgICA8aW5wdXQgbWF0SW5wdXRcbiAgICAgICAgICAgICAgICAgICAgIGZvcm1Db250cm9sTmFtZT1cInNlYXJjaFRleHRcIlxuICAgICAgICAgICAgICAgICAgICAgYXV0b2NvbXBsZXRlPVwib2ZmXCI+XG4gICAgICAgICAgICAgIDxidXR0b24gbWF0LWljb24tYnV0dG9uIG1hdFN1ZmZpeCB0YWJpbmRleD1cIi0xXCJcbiAgICAgICAgICAgICAgICAgICAgICB0eXBlPVwiYnV0dG9uXCJcbiAgICAgICAgICAgICAgICAgICAgICAoY2xpY2spPVwiY2xlYXJDb250cm9sVmFsdWUoJGV2ZW50LCBmaWx0ZXJGb3JtLmNvbnRyb2xzLnNlYXJjaFRleHQpXCJcbiAgICAgICAgICAgICAgICAgICAgICBbaGlkZGVuXT1cImZpbHRlckZvcm0uY29udHJvbHMuc2VhcmNoVGV4dC5kaXNhYmxlZCB8fCAhZmlsdGVyRm9ybS5jb250cm9scy5zZWFyY2hUZXh0LnZhbHVlXCI+XG4gICAgICAgICAgICAgICAgPG1hdC1pY29uPmNsb3NlPC9tYXQtaWNvbj5cbiAgICAgICAgICAgICAgPC9idXR0b24+XG4gICAgICAgICAgICA8L21hdC1mb3JtLWZpZWxkPlxuICAgICAgICAgIDwvaW9uLWNvbD5cbiAgICAgICAgPC9pb24tcm93PlxuICAgICAgPC9pb24tZ3JpZD5cbiAgICA8L2Zvcm0+XG5cbiAgICA8bWF0LWFjdGlvbi1yb3c+XG4gICAgICA8IS0tIENvdW50ZXIgIC0tPlxuICAgICAgPGlvbi1sYWJlbCBbaGlkZGVuXT1cIihsb2FkaW5nU3ViamVjdHxhc3luYykgfHwgZmlsdGVyRm9ybS5kaXJ0eVwiXG4gICAgICAgICAgICAgICAgIFtjb2xvcl09XCJlbXB0eSAmJiAnZGFuZ2VyJ1wiXG4gICAgICAgICAgICAgICAgIGNsYXNzPVwiaW9uLXBhZGRpbmdcIj5cbiAgICAgICAge3sgKHRvdGFsUm93Q291bnQgPyAnQ09NTU9OLlJFU1VMVF9DT1VOVCcgOiAnQ09NTU9OLk5PX1JFU1VMVCcpIHwgdHJhbnNsYXRlOiB7XG4gICAgICAgIGNvdW50OiAodG90YWxSb3dDb3VudCB8XG4gICAgICAgICAgbnVtYmVyRm9ybWF0KVxuICAgICAgfSB9fVxuICAgICAgPC9pb24tbGFiZWw+XG5cbiAgICAgIDxkaXYgY2xhc3M9XCJ0b29sYmFyLXNwYWNlclwiPjwvZGl2PlxuXG4gICAgICA8IS0tIENsb3NlIHBhbmVsIC0tPlxuICAgICAgPGlvbi1idXR0b24gbWF0LWJ1dHRvbiBmaWxsPVwiY2xlYXJcIiBjb2xvcj1cImRhcmtcIlxuICAgICAgICAgICAgICAgICAgKGNsaWNrKT1cImZpbHRlckV4cGFuc2lvblBhbmVsLmNsb3NlKClcIlxuICAgICAgICAgICAgICAgICAgW2Rpc2FibGVkXT1cImxvYWRpbmdTdWJqZWN0fGFzeW5jXCI+XG4gICAgICAgIDxpb24tdGV4dCB0cmFuc2xhdGU+Q09NTU9OLkJUTl9DTE9TRTwvaW9uLXRleHQ+XG4gICAgICA8L2lvbi1idXR0b24+XG5cbiAgICAgIDwhLS0gU2VhcmNoIGJ1dHRvbiAtLT5cbiAgICAgIDxpb24tYnV0dG9uIG1hdC1idXR0b25cbiAgICAgICAgICAgICAgICAgIFtjb2xvcl09XCJmaWx0ZXJGb3JtLmRpcnR5ID8gJ3RlcnRpYXJ5JyA6ICdkYXJrJ1wiXG4gICAgICAgICAgICAgICAgICBbZmlsbF09XCJmaWx0ZXJGb3JtLmRpcnR5ID8gJ3NvbGlkJyA6ICdjbGVhcidcIlxuICAgICAgICAgICAgICAgICAgKGNsaWNrKT1cImFwcGx5RmlsdGVyQW5kQ2xvc2VQYW5lbCgkZXZlbnQpXCI+XG4gICAgICAgIDxpb24tdGV4dCB0cmFuc2xhdGU+Q09NTU9OLkJUTl9BUFBMWTwvaW9uLXRleHQ+XG4gICAgICA8L2lvbi1idXR0b24+XG4gICAgPC9tYXQtYWN0aW9uLXJvdz5cbiAgPC9tYXQtZXhwYW5zaW9uLXBhbmVsPlxuXG4gIDwhLS0gdGFibGUgLS0+XG4gIDxkaXYgW2NsYXNzLnRhYmxlLWNvbnRhaW5lcl09XCIhZW5hYmxlSW5maW5pdGVTY3JvbGxcIj5cbiAgICA8dGFibGUgI3RhYmxlIG1hdC10YWJsZSBtYXRTb3J0IG1hdFNvcnREaXNhYmxlQ2xlYXJcbiAgICAgICAgICAgW2RhdGFTb3VyY2VdPVwiZGF0YVNvdXJjZVwiXG4gICAgICAgICAgIFttYXRTb3J0QWN0aXZlXT1cImRlZmF1bHRTb3J0QnlcIlxuICAgICAgICAgICBbbWF0U29ydERpcmVjdGlvbl09XCJkZWZhdWx0U29ydERpcmVjdGlvblwiXG4gICAgICAgICAgIFt0cmFja0J5XT1cInRyYWNrQnlGblwiXG4gICAgICAgICAgIFtzdHlsZS4tLW1hdC1yb3ctaGVpZ2h0XT1cInJvd0hlaWdodCArICdweCdcIj5cbiAgICA+XG5cbiAgICAgIDwhLS0gZ3JvdXAgaGVhZGVyIGNlbGxzIC0tPlxuXG4gICAgICA8bmctY29udGFpbmVyIG1hdENvbHVtbkRlZj1cInRvcC1zdGFydFwiIFtzdGlja3ldPVwidXNlU3RpY2t5XCI+XG4gICAgICAgIDx0aCBtYXQtaGVhZGVyLWNlbGwgKm1hdEhlYWRlckNlbGxEZWYgW2NsYXNzLmNkay12aXN1YWxseS1oaWRkZW5dPVwiIWNhbkVkaXRcIiBbYXR0ci5jb2xzcGFuXT1cIjJcIj5cbiAgICAgICAgICA8IS0tIHN0YXJ0IHNwYWNlciAtLT5cbiAgICAgICAgPC90aD5cbiAgICAgIDwvbmctY29udGFpbmVyPlxuXG4gICAgICA8bmctY29udGFpbmVyIG1hdENvbHVtbkRlZj1cImdyb3VwLTFcIj5cbiAgICAgICAgPHRoIG1hdC1oZWFkZXItY2VsbCAqbWF0SGVhZGVyQ2VsbERlZiBbYXR0ci5jb2xzcGFuXT1cIjNcIiBzdHlsZT1cImJhY2tncm91bmQtY29sb3I6IHdoaXRlc21va2U7IG1hcmdpbi1ib3R0b206IC0xcHg7XCI+XG4gICAgICAgICAgPGlvbi1sYWJlbCB0cmFuc2xhdGU+e3tpMThuQ29sdW1uUHJlZml4ICsgJ0dST1VQXzEnfX08L2lvbi1sYWJlbD5cbiAgICAgICAgPC90aD5cbiAgICAgIDwvbmctY29udGFpbmVyPlxuXG4gICAgICA8bmctY29udGFpbmVyIG1hdENvbHVtbkRlZj1cImdyb3VwLTJcIj5cbiAgICAgICAgPHRoIG1hdC1oZWFkZXItY2VsbCAqbWF0SGVhZGVyQ2VsbERlZiBbYXR0ci5jb2xzcGFuXT1cIjNcIj5cbiAgICAgICAgICA8aW9uLWxhYmVsIHRyYW5zbGF0ZT57e2kxOG5Db2x1bW5QcmVmaXggKyAnR1JPVVBfMid9fTwvaW9uLWxhYmVsPlxuICAgICAgICA8L3RoPlxuICAgICAgPC9uZy1jb250YWluZXI+XG5cbiAgICAgIDxuZy1jb250YWluZXIgbWF0Q29sdW1uRGVmPVwidG9wLWVuZFwiID5cbiAgICAgICAgPHRoIG1hdC1oZWFkZXItY2VsbCAqbWF0SGVhZGVyQ2VsbERlZj5cbiAgICAgICAgICA8IS0tIGVuZCBzcGFjZXIgLS0+XG4gICAgICAgIDwvdGg+XG4gICAgICA8L25nLWNvbnRhaW5lcj5cblxuICAgICAgPG5nLWNvbnRhaW5lciBtYXRDb2x1bW5EZWY9XCJzZWxlY3RcIiBbc3RpY2t5XT1cInVzZVN0aWNreVwiIFtjbGFzcy5tYXQtY29sdW1uLXN0aWNreV09XCJ1c2VTdGlja3lcIj5cbiAgICAgICAgPHRoIG1hdC1oZWFkZXItY2VsbCAqbWF0SGVhZGVyQ2VsbERlZiBbY2xhc3MuY2RrLXZpc3VhbGx5LWhpZGRlbl09XCIhY2FuRWRpdFwiPlxuICAgICAgICAgIDxtYXQtY2hlY2tib3ggKGNoYW5nZSk9XCIkZXZlbnQgPyBtYXN0ZXJUb2dnbGUoKSA6IG51bGxcIiBbY2hlY2tlZF09XCJzZWxlY3Rpb24uaGFzVmFsdWUoKSAmJiBpc0FsbFNlbGVjdGVkKClcIlxuICAgICAgICAgICAgICAgICAgICAgICAgW2luZGV0ZXJtaW5hdGVdPVwic2VsZWN0aW9uLmhhc1ZhbHVlKCkgJiYgIWlzQWxsU2VsZWN0ZWQoKVwiPlxuICAgICAgICAgIDwvbWF0LWNoZWNrYm94PlxuICAgICAgICA8L3RoPlxuICAgICAgICA8dGQgbWF0LWNlbGwgKm1hdENlbGxEZWY9XCJsZXQgcm93XCIgW2NsYXNzLmNkay12aXN1YWxseS1oaWRkZW5dPVwiIWNhbkVkaXRcIj5cbiAgICAgICAgICA8bWF0LWNoZWNrYm94IChjbGljayk9XCJ0b2dnbGVTZWxlY3RSb3coJGV2ZW50LCByb3cpXCIgW2NoZWNrZWRdPVwic2VsZWN0aW9uLmlzU2VsZWN0ZWQocm93KVwiPlxuICAgICAgICAgIDwvbWF0LWNoZWNrYm94PlxuICAgICAgICA8L3RkPlxuICAgICAgPC9uZy1jb250YWluZXI+XG5cbiAgICAgIDwhLS0gSWQgY29sdW1uIC0tPlxuICAgICAgPG5nLWNvbnRhaW5lciBtYXRDb2x1bW5EZWY9XCJpZFwiIFtzdGlja3ldPVwidXNlU3RpY2t5XCIgW2NsYXNzLm1hdC1jb2x1bW4tc3RpY2t5XT1cInVzZVN0aWNreVwiPlxuICAgICAgICA8dGggbWF0LWhlYWRlci1jZWxsICptYXRIZWFkZXJDZWxsRGVmIG1hdC1zb3J0LWhlYWRlcj5cbiAgICAgICAgICA8aW9uLWxhYmVsPiM8L2lvbi1sYWJlbD5cbiAgICAgICAgPC90aD5cbiAgICAgICAgPHRkIG1hdC1jZWxsICptYXRDZWxsRGVmPVwibGV0IHJvd1wiPnt7IHJvdy5jdXJyZW50RGF0YT8uaWQgfX08L3RkPlxuICAgICAgPC9uZy1jb250YWluZXI+XG5cbiAgICAgIDwhLS0gTGFiZWwgY29sdW1uIC0tPlxuICAgICAgPG5nLWNvbnRhaW5lciBtYXRDb2x1bW5EZWY9XCJsYWJlbFwiPlxuICAgICAgICA8dGggbWF0LWhlYWRlci1jZWxsICptYXRIZWFkZXJDZWxsRGVmIG1hdC1zb3J0LWhlYWRlcj5cbiAgICAgICAgICA8aW9uLWxhYmVsIHRyYW5zbGF0ZT5UQUJMRS5URVNUSU5HLkxBQkVMPC9pb24tbGFiZWw+XG4gICAgICAgIDwvdGg+XG4gICAgICAgIDx0ZCBtYXQtY2VsbCAqbWF0Q2VsbERlZj1cImxldCByb3dcIiAoY2xpY2spPVwiZm9jdXNDb2x1bW49J2xhYmVsJ1wiPlxuICAgICAgICAgIDxtYXQtZm9ybS1maWVsZCAqbmdJZj1cInJvdy5lZGl0aW5nOyBlbHNlIHJlYWRvbmx5Q2VsbFwiIFtoaWRlUmVxdWlyZWRNYXJrZXJdPVwiZmFsc2VcIj5cbiAgICAgICAgICAgIDxpbnB1dCBtYXRJbnB1dCBhdXRvY29tcGxldGU9XCJvZmZcIlxuICAgICAgICAgICAgICAgICAgIFtmb3JtQ29udHJvbF09XCJyb3cudmFsaWRhdG9yLmNvbnRyb2xzWydsYWJlbCddXCJcbiAgICAgICAgICAgICAgICAgICBbcGxhY2Vob2xkZXJdPVwiJ1RBQkxFLlRFU1RJTkcuTEFCRUwnfHRyYW5zbGF0ZVwiXG4gICAgICAgICAgICAgICAgICAgW2FwcEF1dG9mb2N1c109XCJyb3cuZWRpdGluZyAmJiBmb2N1c0NvbHVtbiA9PT0gJ2xhYmVsJ1wiXG4gICAgICAgICAgICAgICAgICAgW3JlYWRvbmx5XT1cIiFyb3cuZWRpdGluZ1wiPlxuICAgICAgICAgICAgPG1hdC1lcnJvciAqbmdJZj1cInJvdy52YWxpZGF0b3IuY29udHJvbHNbJ2xhYmVsJ10uaGFzRXJyb3IoJ3JlcXVpcmVkJylcIiB0cmFuc2xhdGU+RVJST1IuRklFTERfUkVRVUlSRUQ8L21hdC1lcnJvcj5cbiAgICAgICAgICA8L21hdC1mb3JtLWZpZWxkPlxuICAgICAgICAgIDxuZy10ZW1wbGF0ZSAjcmVhZG9ubHlDZWxsPlxuICAgICAgICAgICAgPGlvbi1sYWJlbCBhcHBBdXRvVGl0bGU+XG4gICAgICAgICAgICAgIHt7IChyb3cudmFsaWRhdG9yIHwgZm9ybUdldFZhbHVlIDogJ2xhYmVsJyl9fVxuICAgICAgICAgICAgPC9pb24tbGFiZWw+XG4gICAgICAgICAgPC9uZy10ZW1wbGF0ZT5cbiAgICAgICAgPC90ZD5cbiAgICAgIDwvbmctY29udGFpbmVyPlxuXG4gICAgICA8IS0tIE5hbWUgY29sdW1uIC0tPlxuICAgICAgPG5nLWNvbnRhaW5lciBtYXRDb2x1bW5EZWY9XCJuYW1lXCI+XG4gICAgICAgIDx0aCBtYXQtaGVhZGVyLWNlbGwgKm1hdEhlYWRlckNlbGxEZWYgbWF0LXNvcnQtaGVhZGVyPlxuICAgICAgICAgIDxpb24tbGFiZWwgdHJhbnNsYXRlPlRBQkxFLlRFU1RJTkcuTkFNRTwvaW9uLWxhYmVsPlxuICAgICAgICA8L3RoPlxuICAgICAgICA8dGQgbWF0LWNlbGwgKm1hdENlbGxEZWY9XCJsZXQgcm93XCJcbiAgICAgICAgICAgIChjbGljayk9XCJmb2N1c0NvbHVtbj0nbmFtZSdcIj5cbiAgICAgICAgICA8bWF0LWZvcm0tZmllbGQgKm5nSWY9XCJyb3cuZWRpdGluZzsgZWxzZSByZWFkb25seUNlbGxcIj5cbiAgICAgICAgICAgIDxpbnB1dCBtYXRJbnB1dFxuICAgICAgICAgICAgICAgICAgIFtmb3JtQ29udHJvbF09XCJyb3cudmFsaWRhdG9yPy5jb250cm9scy5uYW1lXCIgW3BsYWNlaG9sZGVyXT1cIidUQUJMRS5URVNUSU5HLk5BTUUnfHRyYW5zbGF0ZVwiXG4gICAgICAgICAgICAgICAgICAgW2FwcEF1dG9mb2N1c109XCJyb3cuZWRpdGluZyAmJiBmb2N1c0NvbHVtbiA9PT0gJ25hbWUnXCJcbiAgICAgICAgICAgICAgICAgICA+XG4gICAgICAgICAgICA8bWF0LWVycm9yICpuZ0lmPVwicm93LnZhbGlkYXRvcj8uY29udHJvbHMubmFtZS5oYXNFcnJvcigncmVxdWlyZWQnKVwiIHRyYW5zbGF0ZT5FUlJPUi5GSUVMRF9SRVFVSVJFRDwvbWF0LWVycm9yPlxuICAgICAgICAgIDwvbWF0LWZvcm0tZmllbGQ+XG4gICAgICAgICAgPG5nLXRlbXBsYXRlICNyZWFkb25seUNlbGw+XG4gICAgICAgICAgICA8aW9uLWxhYmVsIGFwcEF1dG9UaXRsZT5cbiAgICAgICAgICAgICAge3sgKHJvdy52YWxpZGF0b3IgfCBmb3JtR2V0VmFsdWUgOiAnbmFtZScpfX1cbiAgICAgICAgICAgIDwvaW9uLWxhYmVsPlxuICAgICAgICAgIDwvbmctdGVtcGxhdGU+XG4gICAgICAgIDwvdGQ+XG4gICAgICA8L25nLWNvbnRhaW5lcj5cblxuICAgICAgPCEtLSBMZXZlbCBjb2x1bW4gLS0+XG4gICAgICA8bmctY29udGFpbmVyIG1hdENvbHVtbkRlZj1cImxldmVsSWRcIj5cbiAgICAgICAgPHRoIG1hdC1oZWFkZXItY2VsbCAqbWF0SGVhZGVyQ2VsbERlZiBtYXQtc29ydC1oZWFkZXI+XG4gICAgICAgICAgPGlvbi1sYWJlbCB0cmFuc2xhdGU+VEFCTEUuVEVTVElORy5MRVZFTF9JRDwvaW9uLWxhYmVsPlxuICAgICAgICA8L3RoPlxuICAgICAgICA8dGQgbWF0LWNlbGwgKm1hdENlbGxEZWY9XCJsZXQgcm93XCIgKGNsaWNrKT1cImZvY3VzQ29sdW1uPSdsZXZlbElkJ1wiPlxuICAgICAgICAgIDxtYXQtYXV0b2NvbXBsZXRlLWZpZWxkICpuZ0lmPVwicm93LmVkaXRpbmc7IGVsc2UgcmVhZG9ubHlDZWxsXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbZm9ybUNvbnRyb2xdPVwicm93LnZhbGlkYXRvci5jb250cm9scy5sZXZlbElkXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbcGxhY2Vob2xkZXJdPVwiJ1RBQkxFLlRFU1RJTkcuTEVWRUxfSUQnfHRyYW5zbGF0ZVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmxvYXRMYWJlbD1cIm5ldmVyXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbY29uZmlnXT1cImF1dG9jb21wbGV0ZUZpZWxkcy5sZXZlbFwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW3JlYWRvbmx5XT1cIiFyb3cuZWRpdGluZ1wiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbYXV0b2ZvY3VzXT1cInJvdy5lZGl0aW5nICYmIGZvY3VzQ29sdW1uID09PSAnbGV2ZWxJZCdcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtyZXF1aXJlZF09XCJ0cnVlXCI+XG4gICAgICAgICAgPC9tYXQtYXV0b2NvbXBsZXRlLWZpZWxkPlxuICAgICAgICAgIDxuZy10ZW1wbGF0ZSAjcmVhZG9ubHlDZWxsPlxuICAgICAgICAgICAgPGlvbi1sYWJlbCBhcHBBdXRvVGl0bGU+XG4gICAgICAgICAgICAgIHt7IChyb3cudmFsaWRhdG9yIHwgZm9ybUdldFZhbHVlIDogJ2xldmVsSWQnfHJlZmVyZW50aWFsVG9TdHJpbmc6IGF1dG9jb21wbGV0ZUZpZWxkcy5sZXZlbC5hdHRyaWJ1dGVzKX19XG4gICAgICAgICAgICA8L2lvbi1sYWJlbD5cbiAgICAgICAgICA8L25nLXRlbXBsYXRlPlxuICAgICAgICA8L3RkPlxuICAgICAgPC9uZy1jb250YWluZXI+XG5cbiAgICAgIDwhLS0gU3RhdHVzIGNvbHVtbiAgLS0+XG4gICAgICA8bmctY29udGFpbmVyIG1hdENvbHVtbkRlZj1cInN0YXR1c0lkXCI+XG4gICAgICAgIDx0aCBtYXQtaGVhZGVyLWNlbGwgKm1hdEhlYWRlckNlbGxEZWY+XG4gICAgICAgICAgPHNwYW4gdHJhbnNsYXRlPlVTRVIuU1RBVFVTPC9zcGFuPlxuICAgICAgICA8L3RoPlxuICAgICAgICA8dGQgbWF0LWNlbGwgKm1hdENlbGxEZWY9XCJsZXQgcm93XCIgW2NsYXNzLm1hdC1mb3JtLWZpZWxkLWRpc2FibGVkXT1cIiFyb3cuZWRpdGluZ1wiPlxuICAgICAgICAgICAgPG1hdC1mb3JtLWZpZWxkPlxuICAgICAgICAgICAgPG1hdC1zZWxlY3QgW2Zvcm1Db250cm9sXT1cInJvdy52YWxpZGF0b3IuY29udHJvbHNbJ3N0YXR1c0lkJ11cIiBbcGxhY2Vob2xkZXJdPVwiaTE4bkNvbHVtblByZWZpeCArICdTVEFUVVNfSUQnfHRyYW5zbGF0ZVwiPlxuICAgICAgICAgICAgICA8bWF0LW9wdGlvbiAqbmdGb3I9XCJsZXQgaXRlbSBvZiBzdGF0dXNMaXN0XCIgW3ZhbHVlXT1cIml0ZW0uaWRcIj5cbiAgICAgICAgICAgICAgICA8bWF0LWljb24+PGlvbi1pY29uIFtuYW1lXT1cIml0ZW0uaWNvblwiPjwvaW9uLWljb24+PC9tYXQtaWNvbj5cbiAgICAgICAgICAgICAgICA8bWF0LWxhYmVsPnt7IGl0ZW0ubGFiZWwgfHRyYW5zbGF0ZSB9fTwvbWF0LWxhYmVsPlxuICAgICAgICAgICAgICA8L21hdC1vcHRpb24+XG4gICAgICAgICAgICA8L21hdC1zZWxlY3Q+XG4gICAgICAgICAgICA8bWF0LWVycm9yICpuZ0lmPVwicm93LnZhbGlkYXRvci5jb250cm9sc1snc3RhdHVzSWQnXS5oYXNFcnJvcigncmVxdWlyZWQnKVwiIHRyYW5zbGF0ZT5FUlJPUi5GSUVMRF9SRVFVSVJFRDwvbWF0LWVycm9yPlxuICAgICAgICAgIDwvbWF0LWZvcm0tZmllbGQ+XG4gICAgICAgIDwvdGQ+XG4gICAgICA8L25nLWNvbnRhaW5lcj5cblxuICAgICAgPCEtLSBFbnVtIGNvbHVtbiAgLS0+XG4gICAgICA8IS0tIE5PVEUgOiBOZXZlciB1c2VkIGluIHRhYmxlICAtLT5cbjwhLS0gICAgICA8bmctY29udGFpbmVyIG1hdENvbHVtbkRlZj1cInZhbHVlc1wiPi0tPlxuPCEtLSAgICAgICAgPHRoIG1hdC1oZWFkZXItY2VsbCAqbWF0SGVhZGVyQ2VsbERlZj4tLT5cbjwhLS0gICAgICAgICAgPHNwYW4gdHJhbnNsYXRlPkVudW1zPC9zcGFuPi0tPlxuPCEtLSAgICAgICAgPC90aD4tLT5cbjwhLS0gICAgICAgIDx0ZCBtYXQtY2VsbCAqbWF0Q2VsbERlZj1cImxldCByb3dcIiBbY2xhc3MubWF0LWZvcm0tZmllbGQtZGlzYWJsZWRdPVwiIXJvdy5lZGl0aW5nXCI+LS0+XG48IS0tICAgICAgICAgIDxhcHAtZm9ybS1maWVsZC0tPlxuPCEtLSAgICAgICAgICAgIFtmb3JtQ29udHJvbF09XCJyb3cudmFsaWRhdG9yfGZvcm1HZXRDb250cm9sOidwcm9wZXJ0aWVzLnZhbHVlcydcIi0tPlxuPCEtLSAgICAgICAgICAgIFtkZWZpbml0aW9uXT1cImNvbHVtbkRlZmluaXRpb25zWyd2YWx1ZXMnXVwiLS0+XG48IS0tICAgICAgICAgID48L2FwcC1mb3JtLWZpZWxkPi0tPlxuPCEtLSAgICAgICAgPC90ZD4tLT5cbjwhLS0gICAgICA8L25nLWNvbnRhaW5lcj4tLT5cblxuICAgICAgPCEtLSBDcmVhdGlvbiBkYXRlIGNvbHVtbiAtLT5cbiAgICAgIDxuZy1jb250YWluZXIgbWF0Q29sdW1uRGVmPVwidXBkYXRlRGF0ZVwiPlxuICAgICAgICA8dGggbWF0LWhlYWRlci1jZWxsICptYXRIZWFkZXJDZWxsRGVmIG1hdC1zb3J0LWhlYWRlcj5cbiAgICAgICAgICA8aW9uLWxhYmVsIHRyYW5zbGF0ZT5UQUJMRS5URVNUSU5HLlVQREFURV9EQVRFPC9pb24tbGFiZWw+XG4gICAgICAgIDwvdGg+XG4gICAgICAgIDx0ZCBtYXQtY2VsbCAqbWF0Q2VsbERlZj1cImxldCByb3dcIiBjbGFzcz1cIm1hdC1mb3JtLWZpZWxkLWRpc2FibGVkXCI+XG4gICAgICAgICAgPGlvbi10ZXh0IGNvbG9yPVwibWVkaXVtXCIgKm5nSWY9XCJyb3cuaWQhPT0tMVwiPlxuICAgICAgICAgICAgPHNtYWxsPlxuICAgICAgICAgICAgICB7eyByb3cudmFsaWRhdG9yfCBmb3JtR2V0VmFsdWU6ICdjcmVhdGlvbkRhdGUnIHwgZGF0ZUZvcm1hdDoge3RpbWU6IHRydWV9IH19XG4gICAgICAgICAgICA8L3NtYWxsPlxuICAgICAgICAgIDwvaW9uLXRleHQ+XG4gICAgICAgIDwvdGQ+XG4gICAgICA8L25nLWNvbnRhaW5lcj5cblxuICAgICAgPCEtLSBDb21tZW50IGNvbHVtbiAtLT5cbiAgICAgIDxuZy1jb250YWluZXIgbWF0Q29sdW1uRGVmPVwiY29tbWVudHNcIj5cbiAgICAgICAgPHRoIG1hdC1oZWFkZXItY2VsbCAqbWF0SGVhZGVyQ2VsbERlZj5cbiAgICAgICAgICA8aW9uLWxhYmVsIHRyYW5zbGF0ZT5UQUJMRS5URVNUSU5HLkNPTU1FTlRTPC9pb24tbGFiZWw+XG4gICAgICAgIDwvdGg+XG4gICAgICAgIDx0ZCBtYXQtY2VsbCAqbWF0Q2VsbERlZj1cImxldCByb3dcIj5cbiAgICAgICAgICA8bWF0LWZvcm0tZmllbGQgKm5nSWY9XCJyb3cuZWRpdGluZzsgZWxzZSBpY29uQ29tbWVudFwiPlxuICAgICAgICAgICAgPCEtLTx0ZXh0YXJlYSBtYXRJbnB1dCBbZm9ybUNvbnRyb2xdPVwicm93LnZhbGlkYXRvcj8uY29udHJvbHMuY29tbWVudHNcIlxuICAgICAgICAgICAgICAgICAgICAgIFtwbGFjZWhvbGRlcl09XCInVEFCTEUuVEVTVElORy5DT01NRU5UUyd8dHJhbnNsYXRlXCJcbiAgICAgICAgICAgICAgICAgICAgICBbcmVhZG9ubHldPVwiIXJvdy5lZGl0aW5nXCI+PC90ZXh0YXJlYT4tLT5cblxuICAgICAgICAgICAgPGlucHV0IHR5cGU9XCJ0ZXh0XCIgbWF0SW5wdXQgW2Zvcm1Db250cm9sXT1cInJvdy52YWxpZGF0b3I/LmNvbnRyb2xzLmNvbW1lbnRzXCJcbiAgICAgICAgICAgICAgICAgICBbcGxhY2Vob2xkZXJdPVwiJ1RBQkxFLlRFU1RJTkcuQ09NTUVOVFMnfHRyYW5zbGF0ZVwiXG4gICAgICAgICAgICAgICAgICAgW3JlYWRvbmx5XT1cIiFyb3cuZWRpdGluZ1wiPlxuICAgICAgICAgIDwvbWF0LWZvcm0tZmllbGQ+XG5cbiAgICAgICAgICA8bmctdGVtcGxhdGUgI2ljb25Db21tZW50PlxuICAgICAgICAgICAgPG1hdC1pY29uIGNsYXNzPVwiY29tbWVudFwiXG4gICAgICAgICAgICAgICAgICAgICAgKm5nSWY9XCJyb3cudmFsaWRhdG9yPy5jb250cm9scy5jb21tZW50cy52YWx1ZVwiXG4gICAgICAgICAgICAgICAgICAgICAgW3RpdGxlXT1cInJvdy52YWxpZGF0b3I/LmNvbnRyb2xzLmNvbW1lbnRzLnZhbHVlXCI+PC9tYXQtaWNvbj5cbiAgICAgICAgICA8L25nLXRlbXBsYXRlPlxuICAgICAgICA8L3RkPlxuICAgICAgPC9uZy1jb250YWluZXI+XG5cbiAgICAgIDwhLS0gQWN0aW9ucyBidXR0b25zIGNvbHVtbiAtLT5cbiAgICAgIDxhcHAtYWN0aW9ucy1jb2x1bW4gW3N0aWNreUVuZF09XCJ0cnVlXCIgW2NhbkNhbmNlbF09XCJmYWxzZVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgIChvcHRpb25zQ2xpY2spPVwib3BlblNlbGVjdENvbHVtbnNNb2RhbCgkZXZlbnQpXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgKGNhbmNlbE9yRGVsZXRlQ2xpY2spPVwiY2FuY2VsT3JEZWxldGUoJGV2ZW50LmV2ZW50LCAkZXZlbnQucm93KVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgIChjb25maXJtQW5kQWRkQ2xpY2spPVwiY29uZmlybUFuZEFkZCgkZXZlbnQuZXZlbnQsICRldmVudC5yb3cpXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgKGJhY2t3YXJkKT1cImNvbmZpcm1BbmRCYWNrd2FyZCgkZXZlbnQuZXZlbnQsICRldmVudC5yb3cpXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgKGZvcndhcmQpPVwiY29uZmlybUFuZEZvcndhcmQoJGV2ZW50LmV2ZW50LCAkZXZlbnQucm93KVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgIFtjZWxsVGVtcGxhdGVdPVwiY2VsbEluamVjdGlvblwiPlxuXG4gICAgICAgIDwhLS0gY2VsbCBpbmplY3Rpb24tLT5cbiAgICAgICAgPG5nLXRlbXBsYXRlICNjZWxsSW5qZWN0aW9uIGxldC1yb3c+XG4gICAgICAgICAgPHNwYW4gKm5nSWY9XCJyb3cuZWRpdGluZyAmJiAhcm93LnZhbGlkYXRvci5kaXJ0eVwiPi08L3NwYW4+XG4gICAgICAgIDwvbmctdGVtcGxhdGU+XG5cbiAgICAgIDwvYXBwLWFjdGlvbnMtY29sdW1uPlxuXG4gICAgICA8dHIgbWF0LWhlYWRlci1yb3cgKm1hdEhlYWRlclJvd0RlZj1cImdyb3VwQ29sdW1ucztcIiBjbGFzcz1cIm1hdC10b29sYmFyXCI+PC90cj5cbiAgICAgIDx0ciBtYXQtaGVhZGVyLXJvdyAqbWF0SGVhZGVyUm93RGVmPVwiZGlzcGxheWVkQ29sdW1uczsgc3RpY2t5OiB0cnVlXCI+PC90cj5cbiAgICAgIDx0ciBtYXQtcm93ICptYXRSb3dEZWY9XCJsZXQgcm93OyBjb2x1bW5zOiBkaXNwbGF5ZWRDb2x1bW5zO1wiXG4gICAgICAgICAgW2NsYXNzLm1hdC1yb3ctc2VsZWN0ZWRdPVwicm93LmVkaXRpbmdcIlxuICAgICAgICAgIFtjbGFzcy5tYXQtcm93LWVycm9yXT1cInJvdy52YWxpZGF0b3I/LmludmFsaWRcIlxuICAgICAgICAgIFtjbGFzcy5tYXQtcm93LWRpc2FibGVkXT1cIiFyb3cuZWRpdGluZ1wiXG4gICAgICAgICAgW2NsYXNzLm1hdC1yb3ctZGlydHldPVwicm93LnZhbGlkYXRvcj8uZGlydHlcIlxuICAgICAgICAgIChjbGljayk9XCJjbGlja1JvdygkZXZlbnQsIHJvdylcIlxuICAgICAgICAgIChrZXlkb3duLmVzY2FwZSk9XCJlc2NhcGVFZGl0aW5nUm93KCRldmVudClcIlxuICAgICAgICAgIFtjZGtUcmFwRm9jdXNdPVwicm93LnZhbGlkYXRvcj8uaW52YWxpZFwiPjwvdHI+XG4gICAgPC90YWJsZT5cblxuICAgIDxuZy1jb250YWluZXIgKm5nSWY9XCJsb2FkaW5nU3ViamVjdHxhc3luYzsgZWxzZSBub1Jlc3VsdFwiPlxuICAgICAgPGlvbi1pdGVtPlxuICAgICAgICA8aW9uLXNrZWxldG9uLXRleHQgYW5pbWF0ZWQ+PC9pb24tc2tlbGV0b24tdGV4dD5cbiAgICAgIDwvaW9uLWl0ZW0+XG4gICAgPC9uZy1jb250YWluZXI+XG5cbiAgICA8bmctdGVtcGxhdGUgI25vUmVzdWx0PlxuICAgICAgPGlvbi1pdGVtICpuZ0lmPVwidG90YWxSb3dDb3VudCA9PT0gMFwiPlxuICAgICAgICA8aW9uLXRleHQgY29sb3I9XCJkYW5nZXJcIiBjbGFzcz1cInRleHQtaXRhbGljXCIgdHJhbnNsYXRlPkNPTU1PTi5OT19SRVNVTFQ8L2lvbi10ZXh0PlxuICAgICAgPC9pb24taXRlbT5cbiAgICA8L25nLXRlbXBsYXRlPlxuXG4gICAgPGlvbi1pbmZpbml0ZS1zY3JvbGwgKm5nSWY9XCJlbmFibGVJbmZpbml0ZVNjcm9sbFwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgW3RocmVzaG9sZF09XCJtb2JpbGUgPyAnMTAlJyA6ICcyJSdcIiBwb3NpdGlvbj1cImJvdHRvbVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgKGlvbkluZmluaXRlKT1cImZldGNoTW9yZSgkZXZlbnQpXCI+XG4gICAgICA8aW9uLWluZmluaXRlLXNjcm9sbC1jb250ZW50XG4gICAgICAgIGxvYWRpbmdTcGlubmVyPVwiY2lyY2xlc1wiXG4gICAgICAgIFtsb2FkaW5nVGV4dF09XCInQ09NTU9OLkxPQURJTkdfRE9UUyd8dHJhbnNsYXRlXCI+XG4gICAgICA8L2lvbi1pbmZpbml0ZS1zY3JvbGwtY29udGVudD5cbiAgICA8L2lvbi1pbmZpbml0ZS1zY3JvbGw+XG4gIDwvZGl2PlxuPC9pb24tY29udGVudD5cblxuPGlvbi1mb290ZXI+XG4gIDwhLS0gUGFnaW5hdG9yICAtLT5cbiAgPG1hdC1wYWdpbmF0b3IgKm5nSWY9XCIhZW5hYmxlSW5maW5pdGVTY3JvbGxcIlxuICAgICAgICAgICAgICAgICBbbGVuZ3RoXT1cInRvdGFsUm93Q291bnRcIiBbcGFnZVNpemVdPVwiZGVmYXVsdFBhZ2VTaXplXCIgW3BhZ2VTaXplT3B0aW9uc109XCJkZWZhdWx0UGFnZVNpemVPcHRpb25zXCJcbiAgICAgICAgICAgICAgICAgY2xhc3M9XCJtYXQtcGFnaW5hdG9yLWZvb3RlclwiXG4gICAgICAgICAgICAgICAgIHNob3dGaXJzdExhc3RCdXR0b25zPlxuICA8L21hdC1wYWdpbmF0b3I+XG5cbiAgPGFwcC1mb3JtLWJ1dHRvbnMtYmFyICpuZ0lmPVwiY2FuRWRpdCAmJiAhbW9iaWxlXCJcbiAgICAgICAgICAgICAgICAgICAgICAgIChvbkNhbmNlbCk9XCJsb2FkKClcIlxuICAgICAgICAgICAgICAgICAgICAgICAgKG9uU2F2ZSk9XCJzYXZlKClcIlxuICAgICAgICAgICAgICAgICAgICAgICAgW2Rpc2FibGVkXT1cIihsb2FkaW5nU3ViamVjdHxhc3luYykgfHwgIWRpcnR5XCI+XG4gICAgPCEtLSBlcnJvciAtLT5cbiAgICA8aW9uLWl0ZW0gKm5nSWY9XCJlcnJvciR8YXN5bmNcIiBsaW5lcz1cIm5vbmVcIj5cbiAgICAgIDxpb24taWNvbiBjb2xvcj1cImRhbmdlclwiIHNsb3Q9XCJzdGFydFwiIG5hbWU9XCJhbGVydC1jaXJjbGVcIj48L2lvbi1pY29uPlxuICAgICAgPGlvbi1sYWJlbCBjb2xvcj1cImRhbmdlclwiIFtpbm5lckhUTUxdPVwiZXJyb3J8dHJhbnNsYXRlXCI+PC9pb24tbGFiZWw+XG4gICAgPC9pb24taXRlbT5cbiAgPC9hcHAtZm9ybS1idXR0b25zLWJhcj5cbjwvaW9uLWZvb3Rlcj5cblxuPGlvbi1mYWIgc2xvdD1cImZpeGVkXCIgdmVydGljYWw9XCJib3R0b21cIiBob3Jpem9udGFsPVwiZW5kXCJcbiAgICAgICAgICpuZ0lmPVwiY2FuRWRpdCAmJiBtb2JpbGVcIj5cbiAgPGlvbi1mYWItYnV0dG9uIGNvbG9yPVwidGVydGlhcnlcIiAoY2xpY2spPVwiYWRkUm93KCRldmVudClcIj5cbiAgICA8aW9uLWljb24gbmFtZT1cImFkZFwiPjwvaW9uLWljb24+XG4gIDwvaW9uLWZhYi1idXR0b24+XG48L2lvbi1mYWI+XG4iXX0=
@@ -10,22 +10,22 @@ import { ResizableModule } from '../../../shared/directives/resizable/resizable.
10
10
  import * as i0 from "@angular/core";
11
11
  import * as i1 from "@ngx-translate/core";
12
12
  export class TableTestingModule {
13
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: TableTestingModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
14
- static ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "16.2.12", ngImport: i0, type: TableTestingModule, declarations: [TableTestPage,
13
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.0.6", ngImport: i0, type: TableTestingModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
14
+ static ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "17.0.6", ngImport: i0, type: TableTestingModule, declarations: [TableTestPage,
15
15
  Table2TestPage], imports: [CommonModule,
16
16
  SharedModule,
17
17
  CoreModule, i1.TranslateModule, FormsModule,
18
18
  ResizableModule], exports: [TableTestPage,
19
19
  Table2TestPage,
20
20
  TranslateModule] });
21
- static ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: TableTestingModule, imports: [CommonModule,
21
+ static ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "17.0.6", ngImport: i0, type: TableTestingModule, imports: [CommonModule,
22
22
  SharedModule,
23
23
  CoreModule,
24
24
  TranslateModule.forChild(),
25
25
  FormsModule,
26
26
  ResizableModule, TranslateModule] });
27
27
  }
28
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: TableTestingModule, decorators: [{
28
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.0.6", ngImport: i0, type: TableTestingModule, decorators: [{
29
29
  type: NgModule,
30
30
  args: [{
31
31
  imports: [
@@ -47,4 +47,4 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImpo
47
47
  ]
48
48
  }]
49
49
  }] });
50
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidGFibGUudGVzdGluZy5tb2R1bGUuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi8uLi9zcmMvYXBwL2NvcmUvdGFibGUvdGVzdGluZy90YWJsZS50ZXN0aW5nLm1vZHVsZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUMsUUFBUSxFQUFDLE1BQU0sZUFBZSxDQUFDO0FBQ3ZDLE9BQU8sRUFBQyxZQUFZLEVBQUMsTUFBTSxpQkFBaUIsQ0FBQztBQUM3QyxPQUFPLEVBQUMsZUFBZSxFQUFDLE1BQU0scUJBQXFCLENBQUM7QUFDcEQsT0FBTyxFQUFDLFVBQVUsRUFBQyxNQUFNLG1CQUFtQixDQUFDO0FBQzdDLE9BQU8sRUFBQyxhQUFhLEVBQUMsTUFBTSxpQkFBaUIsQ0FBQztBQUM5QyxPQUFPLEVBQUMsWUFBWSxFQUFDLE1BQU0sK0JBQStCLENBQUM7QUFDM0QsT0FBTyxFQUFDLFdBQVcsRUFBQyxNQUFNLGdCQUFnQixDQUFDO0FBQzNDLE9BQU8sRUFBQyxjQUFjLEVBQUMsTUFBTSxrQkFBa0IsQ0FBQztBQUNoRCxPQUFPLEVBQUMsZUFBZSxFQUFDLE1BQU0sdURBQXVELENBQUM7OztBQXNCdEYsTUFBTSxPQUFPLGtCQUFrQjt3R0FBbEIsa0JBQWtCO3lHQUFsQixrQkFBa0IsaUJBVDNCLGFBQWE7WUFDYixjQUFjLGFBVGQsWUFBWTtZQUNaLFlBQVk7WUFDWixVQUFVLHNCQUVWLFdBQVc7WUFDWCxlQUFlLGFBT2YsYUFBYTtZQUNiLGNBQWM7WUFDZCxlQUFlO3lHQUdOLGtCQUFrQixZQWpCM0IsWUFBWTtZQUNaLFlBQVk7WUFDWixVQUFVO1lBQ1YsZUFBZSxDQUFDLFFBQVEsRUFBRTtZQUMxQixXQUFXO1lBQ1gsZUFBZSxFQVNmLGVBQWU7OzRGQUdOLGtCQUFrQjtrQkFuQjlCLFFBQVE7bUJBQUM7b0JBQ1IsT0FBTyxFQUFFO3dCQUNQLFlBQVk7d0JBQ1osWUFBWTt3QkFDWixVQUFVO3dCQUNWLGVBQWUsQ0FBQyxRQUFRLEVBQUU7d0JBQzFCLFdBQVc7d0JBQ1gsZUFBZTtxQkFDaEI7b0JBQ0QsWUFBWSxFQUFFO3dCQUNaLGFBQWE7d0JBQ2IsY0FBYztxQkFDZjtvQkFDRCxPQUFPLEVBQUU7d0JBQ1AsYUFBYTt3QkFDYixjQUFjO3dCQUNkLGVBQWU7cUJBQ2hCO2lCQUNGIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHtOZ01vZHVsZX0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQge0NvbW1vbk1vZHVsZX0gZnJvbSAnQGFuZ3VsYXIvY29tbW9uJztcbmltcG9ydCB7VHJhbnNsYXRlTW9kdWxlfSBmcm9tICdAbmd4LXRyYW5zbGF0ZS9jb3JlJztcbmltcG9ydCB7Q29yZU1vZHVsZX0gZnJvbSAnLi4vLi4vY29yZS5tb2R1bGUnO1xuaW1wb3J0IHtUYWJsZVRlc3RQYWdlfSBmcm9tICcuL3RhYmxlLnRlc3RpbmcnO1xuaW1wb3J0IHtTaGFyZWRNb2R1bGV9IGZyb20gJy4uLy4uLy4uL3NoYXJlZC9zaGFyZWQubW9kdWxlJztcbmltcG9ydCB7Rm9ybXNNb2R1bGV9IGZyb20gJ0Bhbmd1bGFyL2Zvcm1zJztcbmltcG9ydCB7VGFibGUyVGVzdFBhZ2V9IGZyb20gJy4vdGFibGUyLnRlc3RpbmcnO1xuaW1wb3J0IHtSZXNpemFibGVNb2R1bGV9IGZyb20gJy4uLy4uLy4uL3NoYXJlZC9kaXJlY3RpdmVzL3Jlc2l6YWJsZS9yZXNpemFibGUubW9kdWxlJztcblxuXG5ATmdNb2R1bGUoe1xuICBpbXBvcnRzOiBbXG4gICAgQ29tbW9uTW9kdWxlLFxuICAgIFNoYXJlZE1vZHVsZSxcbiAgICBDb3JlTW9kdWxlLFxuICAgIFRyYW5zbGF0ZU1vZHVsZS5mb3JDaGlsZCgpLFxuICAgIEZvcm1zTW9kdWxlLFxuICAgIFJlc2l6YWJsZU1vZHVsZVxuICBdLFxuICBkZWNsYXJhdGlvbnM6IFtcbiAgICBUYWJsZVRlc3RQYWdlLFxuICAgIFRhYmxlMlRlc3RQYWdlXG4gIF0sXG4gIGV4cG9ydHM6IFtcbiAgICBUYWJsZVRlc3RQYWdlLFxuICAgIFRhYmxlMlRlc3RQYWdlLFxuICAgIFRyYW5zbGF0ZU1vZHVsZVxuICBdXG59KVxuZXhwb3J0IGNsYXNzIFRhYmxlVGVzdGluZ01vZHVsZSB7XG59XG4iXX0=
50
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidGFibGUudGVzdGluZy5tb2R1bGUuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi8uLi9zcmMvYXBwL2NvcmUvdGFibGUvdGVzdGluZy90YWJsZS50ZXN0aW5nLm1vZHVsZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUMsUUFBUSxFQUFDLE1BQU0sZUFBZSxDQUFDO0FBQ3ZDLE9BQU8sRUFBQyxZQUFZLEVBQUMsTUFBTSxpQkFBaUIsQ0FBQztBQUM3QyxPQUFPLEVBQUMsZUFBZSxFQUFDLE1BQU0scUJBQXFCLENBQUM7QUFDcEQsT0FBTyxFQUFDLFVBQVUsRUFBQyxNQUFNLG1CQUFtQixDQUFDO0FBQzdDLE9BQU8sRUFBQyxhQUFhLEVBQUMsTUFBTSxpQkFBaUIsQ0FBQztBQUM5QyxPQUFPLEVBQUMsWUFBWSxFQUFDLE1BQU0sK0JBQStCLENBQUM7QUFDM0QsT0FBTyxFQUFDLFdBQVcsRUFBQyxNQUFNLGdCQUFnQixDQUFDO0FBQzNDLE9BQU8sRUFBQyxjQUFjLEVBQUMsTUFBTSxrQkFBa0IsQ0FBQztBQUNoRCxPQUFPLEVBQUMsZUFBZSxFQUFDLE1BQU0sdURBQXVELENBQUM7OztBQXNCdEYsTUFBTSxPQUFPLGtCQUFrQjt1R0FBbEIsa0JBQWtCO3dHQUFsQixrQkFBa0IsaUJBVDNCLGFBQWE7WUFDYixjQUFjLGFBVGQsWUFBWTtZQUNaLFlBQVk7WUFDWixVQUFVLHNCQUVWLFdBQVc7WUFDWCxlQUFlLGFBT2YsYUFBYTtZQUNiLGNBQWM7WUFDZCxlQUFlO3dHQUdOLGtCQUFrQixZQWpCM0IsWUFBWTtZQUNaLFlBQVk7WUFDWixVQUFVO1lBQ1YsZUFBZSxDQUFDLFFBQVEsRUFBRTtZQUMxQixXQUFXO1lBQ1gsZUFBZSxFQVNmLGVBQWU7OzJGQUdOLGtCQUFrQjtrQkFuQjlCLFFBQVE7bUJBQUM7b0JBQ1IsT0FBTyxFQUFFO3dCQUNQLFlBQVk7d0JBQ1osWUFBWTt3QkFDWixVQUFVO3dCQUNWLGVBQWUsQ0FBQyxRQUFRLEVBQUU7d0JBQzFCLFdBQVc7d0JBQ1gsZUFBZTtxQkFDaEI7b0JBQ0QsWUFBWSxFQUFFO3dCQUNaLGFBQWE7d0JBQ2IsY0FBYztxQkFDZjtvQkFDRCxPQUFPLEVBQUU7d0JBQ1AsYUFBYTt3QkFDYixjQUFjO3dCQUNkLGVBQWU7cUJBQ2hCO2lCQUNGIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHtOZ01vZHVsZX0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQge0NvbW1vbk1vZHVsZX0gZnJvbSAnQGFuZ3VsYXIvY29tbW9uJztcbmltcG9ydCB7VHJhbnNsYXRlTW9kdWxlfSBmcm9tICdAbmd4LXRyYW5zbGF0ZS9jb3JlJztcbmltcG9ydCB7Q29yZU1vZHVsZX0gZnJvbSAnLi4vLi4vY29yZS5tb2R1bGUnO1xuaW1wb3J0IHtUYWJsZVRlc3RQYWdlfSBmcm9tICcuL3RhYmxlLnRlc3RpbmcnO1xuaW1wb3J0IHtTaGFyZWRNb2R1bGV9IGZyb20gJy4uLy4uLy4uL3NoYXJlZC9zaGFyZWQubW9kdWxlJztcbmltcG9ydCB7Rm9ybXNNb2R1bGV9IGZyb20gJ0Bhbmd1bGFyL2Zvcm1zJztcbmltcG9ydCB7VGFibGUyVGVzdFBhZ2V9IGZyb20gJy4vdGFibGUyLnRlc3RpbmcnO1xuaW1wb3J0IHtSZXNpemFibGVNb2R1bGV9IGZyb20gJy4uLy4uLy4uL3NoYXJlZC9kaXJlY3RpdmVzL3Jlc2l6YWJsZS9yZXNpemFibGUubW9kdWxlJztcblxuXG5ATmdNb2R1bGUoe1xuICBpbXBvcnRzOiBbXG4gICAgQ29tbW9uTW9kdWxlLFxuICAgIFNoYXJlZE1vZHVsZSxcbiAgICBDb3JlTW9kdWxlLFxuICAgIFRyYW5zbGF0ZU1vZHVsZS5mb3JDaGlsZCgpLFxuICAgIEZvcm1zTW9kdWxlLFxuICAgIFJlc2l6YWJsZU1vZHVsZVxuICBdLFxuICBkZWNsYXJhdGlvbnM6IFtcbiAgICBUYWJsZVRlc3RQYWdlLFxuICAgIFRhYmxlMlRlc3RQYWdlXG4gIF0sXG4gIGV4cG9ydHM6IFtcbiAgICBUYWJsZVRlc3RQYWdlLFxuICAgIFRhYmxlMlRlc3RQYWdlLFxuICAgIFRyYW5zbGF0ZU1vZHVsZVxuICBdXG59KVxuZXhwb3J0IGNsYXNzIFRhYmxlVGVzdGluZ01vZHVsZSB7XG59XG4iXX0=