@mediusinc/mng-commons 0.17.6 → 0.18.0-rc.1

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 (376) hide show
  1. package/esm2020/lib/api/models/builders/query-param.builder.mjs +58 -58
  2. package/esm2020/lib/api/models/filter-match-type.model.mjs +24 -24
  3. package/esm2020/lib/api/models/filter-param.model.mjs +32 -32
  4. package/esm2020/lib/api/models/index.mjs +8 -8
  5. package/esm2020/lib/api/models/mappers.mjs +12 -12
  6. package/esm2020/lib/api/models/query-mode.model.mjs +17 -17
  7. package/esm2020/lib/api/models/query-param.model.mjs +67 -67
  8. package/esm2020/lib/api/models/query-result.model.mjs +23 -23
  9. package/esm2020/lib/api/models/serialization.model.mjs +1 -1
  10. package/esm2020/lib/api/services/api.abstract.service.mjs +55 -55
  11. package/esm2020/lib/api/services/crud-api.abstract.service.mjs +67 -67
  12. package/esm2020/lib/api/services/get-all-api.abstract.service.mjs +22 -22
  13. package/esm2020/lib/api/services/index.mjs +3 -3
  14. package/esm2020/lib/api/utils/index.mjs +2 -2
  15. package/esm2020/lib/api/utils/medius-rest.util.mjs +212 -212
  16. package/esm2020/lib/api/utils/object-serializer.util.mjs +247 -247
  17. package/esm2020/lib/components/action/action.component.mjs +213 -213
  18. package/esm2020/lib/components/action/editor/action-editor.component.mjs +271 -271
  19. package/esm2020/lib/components/action/index.mjs +3 -3
  20. package/esm2020/lib/components/action/models/action-confirmation-service.model.mjs +1 -1
  21. package/esm2020/lib/components/action/models/action-execution.model.mjs +240 -240
  22. package/esm2020/lib/components/action/models/index.mjs +3 -3
  23. package/esm2020/lib/components/action/models/tableview-action-default-categories.model.mjs +10 -10
  24. package/esm2020/lib/components/action/route/action-route.component.mjs +124 -124
  25. package/esm2020/lib/components/form/autocomplete/autocomplete.component.mjs +299 -299
  26. package/esm2020/lib/components/form/date-range/date-range.component.mjs +108 -108
  27. package/esm2020/lib/components/form/dropdown/dropdown.component.mjs +193 -193
  28. package/esm2020/lib/components/form/editor/form-editor.component.mjs +219 -213
  29. package/esm2020/lib/components/form/formly/fields/formly-field-action/formly-field-action.component.mjs +39 -0
  30. package/esm2020/lib/components/form/formly/fields/formly-field-autocomplete/formly-field-autocomplete.component.mjs +50 -49
  31. package/esm2020/lib/components/form/formly/fields/formly-field-dropdown/formly-field-dropdown.component.mjs +45 -44
  32. package/esm2020/lib/components/form/formly/fields/formly-field-fieldset/formly-field-fieldset.component.mjs +26 -25
  33. package/esm2020/lib/components/form/formly/fields/formly-field-input/formly-field-input.component.mjs +103 -102
  34. package/esm2020/lib/components/form/formly/fields/formly-field-label/formly-field-label.component.mjs +24 -23
  35. package/esm2020/lib/components/form/formly/fields/formly-field-lookup-dialog/formly-field-lookup-dialog.component.mjs +181 -180
  36. package/esm2020/lib/components/form/formly/fields/formly-field-table-dialog-form/formly-field-table-dialog-form.component.mjs +168 -167
  37. package/esm2020/lib/components/form/formly/fields/formly-field-table-dialog-multiselect/formly-field-table-dialog-multiselect.component.mjs +149 -148
  38. package/esm2020/lib/components/form/formly/fields/formly-field-tabs/formly-field-tabs.component.mjs +17 -17
  39. package/esm2020/lib/components/form/formly/fields/index.mjs +11 -10
  40. package/esm2020/lib/components/form/formly/wrappers/formly-field-no-label-wrapper/formly-field-no-label-wrapper.component.mjs +15 -0
  41. package/esm2020/lib/components/form/formly/wrappers/formly-field-wrapper/formly-field-wrapper.component.mjs +15 -15
  42. package/esm2020/lib/components/form/formly/wrappers/index.mjs +3 -3
  43. package/esm2020/lib/components/form/index.mjs +4 -4
  44. package/esm2020/lib/components/form/models/field-action-context.model.mjs +2 -0
  45. package/esm2020/lib/components/form/models/form-editor.event.mjs +33 -33
  46. package/esm2020/lib/components/form/models/form-editor.interface.mjs +2 -0
  47. package/esm2020/lib/components/form/models/index.mjs +3 -2
  48. package/esm2020/lib/components/layout/breadcrumb.component.mjs +16 -16
  49. package/esm2020/lib/components/layout/footer.component.mjs +16 -16
  50. package/esm2020/lib/components/layout/index.mjs +7 -7
  51. package/esm2020/lib/components/layout/main-layout.component.mjs +51 -51
  52. package/esm2020/lib/components/layout/menu-item.component.mjs +267 -267
  53. package/esm2020/lib/components/layout/menu.component.mjs +20 -20
  54. package/esm2020/lib/components/layout/services/index.mjs +1 -1
  55. package/esm2020/lib/components/layout/services/main-layout.component.service.mjs +192 -192
  56. package/esm2020/lib/components/layout/topbar.component.mjs +64 -64
  57. package/esm2020/lib/components/layout/version.component.mjs +57 -57
  58. package/esm2020/lib/components/tableview/index.mjs +6 -6
  59. package/esm2020/lib/components/tableview/models/index.mjs +1 -1
  60. package/esm2020/lib/components/tableview/models/table.event.mjs +15 -15
  61. package/esm2020/lib/components/tableview/route/tableview-route.abstract.component.mjs +81 -81
  62. package/esm2020/lib/components/tableview/route/tableview-route.component.mjs +52 -52
  63. package/esm2020/lib/components/tableview/table/column-filter/column-filter.component.mjs +119 -119
  64. package/esm2020/lib/components/tableview/table/column-value/column-value.component.mjs +73 -73
  65. package/esm2020/lib/components/tableview/table/table.component.mjs +559 -559
  66. package/esm2020/lib/components/tableview/tableview.component.mjs +112 -112
  67. package/esm2020/lib/config/formly.config.mjs +186 -181
  68. package/esm2020/lib/config/index.mjs +1 -1
  69. package/esm2020/lib/config/models/config.model.mjs +2 -0
  70. package/esm2020/lib/config/models/formly-config.model.mjs +2 -0
  71. package/esm2020/lib/config/models/index.mjs +3 -3
  72. package/esm2020/lib/data-providers/base.data-provider.mjs +16 -16
  73. package/esm2020/lib/data-providers/editor.data-provider.mjs +36 -36
  74. package/esm2020/lib/data-providers/index.mjs +6 -6
  75. package/esm2020/lib/data-providers/lookup.data-provider.mjs +15 -15
  76. package/esm2020/lib/data-providers/table.data-provider.mjs +37 -37
  77. package/esm2020/lib/data-providers/tableview-crud.data-provider.mjs +23 -23
  78. package/esm2020/lib/data-providers/tableview.data-provider.mjs +58 -58
  79. package/esm2020/lib/descriptors/action/action-confirmation.descriptor.mjs +76 -76
  80. package/esm2020/lib/descriptors/action-button.descriptor.mjs +59 -59
  81. package/esm2020/lib/descriptors/action.descriptor.mjs +548 -548
  82. package/esm2020/lib/descriptors/column.descriptor.mjs +380 -380
  83. package/esm2020/lib/descriptors/editor.descriptor.mjs +251 -246
  84. package/esm2020/lib/descriptors/field-validation.descriptor.mjs +20 -20
  85. package/esm2020/lib/descriptors/field.descriptor.mjs +902 -864
  86. package/esm2020/lib/descriptors/filter.descriptor.mjs +320 -320
  87. package/esm2020/lib/descriptors/index.mjs +11 -11
  88. package/esm2020/lib/descriptors/interfaces/field-config.interface.mjs +1 -1
  89. package/esm2020/lib/descriptors/interfaces/index.mjs +2 -2
  90. package/esm2020/lib/descriptors/interfaces/lookup-descriptor.interface.mjs +1 -1
  91. package/esm2020/lib/descriptors/model.descriptor.mjs +44 -44
  92. package/esm2020/lib/descriptors/table.descriptor.mjs +463 -463
  93. package/esm2020/lib/descriptors/tableview.descriptor.mjs +323 -323
  94. package/esm2020/lib/descriptors/types/action.type.mjs +25 -25
  95. package/esm2020/lib/descriptors/types/column.type.mjs +11 -11
  96. package/esm2020/lib/descriptors/types/editor.type.mjs +7 -7
  97. package/esm2020/lib/descriptors/types/field.type.mjs +52 -52
  98. package/esm2020/lib/descriptors/types/filter.type.mjs +30 -30
  99. package/esm2020/lib/descriptors/types/index.mjs +6 -6
  100. package/esm2020/lib/descriptors/types/table.type.mjs +26 -26
  101. package/esm2020/lib/directives/component.directive.mjs +43 -43
  102. package/esm2020/lib/directives/index.mjs +2 -2
  103. package/esm2020/lib/directives/template.directive.mjs +27 -27
  104. package/esm2020/lib/mng-commons.module.mjs +466 -463
  105. package/esm2020/lib/models/column-value.model.mjs +1 -1
  106. package/esm2020/lib/models/enum.model.mjs +1 -1
  107. package/esm2020/lib/models/error.model.mjs +1 -1
  108. package/esm2020/lib/models/formly-field.model.mjs +2 -2
  109. package/esm2020/lib/models/index.mjs +9 -9
  110. package/esm2020/lib/models/menu.model.mjs +1 -1
  111. package/esm2020/lib/models/tableview-attr.model.mjs +1 -1
  112. package/esm2020/lib/models/user.model.mjs +1 -1
  113. package/esm2020/lib/models/version.model.mjs +1 -1
  114. package/esm2020/lib/models/view-container.model.mjs +1 -1
  115. package/esm2020/lib/pipes/boolean.pipe.mjs +26 -26
  116. package/esm2020/lib/pipes/class-map.pipe.mjs +21 -21
  117. package/esm2020/lib/pipes/enum.pipe.mjs +24 -24
  118. package/esm2020/lib/pipes/enumerate-async.pipe.mjs +37 -37
  119. package/esm2020/lib/pipes/enumerate.pipe.mjs +54 -54
  120. package/esm2020/lib/pipes/getter.pipe.mjs +19 -19
  121. package/esm2020/lib/pipes/i18n-property.pipe.mjs +17 -17
  122. package/esm2020/lib/pipes/index.mjs +10 -10
  123. package/esm2020/lib/pipes/json-path.pipe.mjs +78 -78
  124. package/esm2020/lib/pipes/models/internal/enumrate-pipe-i18n.model.mjs +1 -1
  125. package/esm2020/lib/pipes/models/internal/index.mjs +1 -1
  126. package/esm2020/lib/pipes/parametrize.pipe.mjs +84 -84
  127. package/esm2020/lib/pipes/template.pipe.mjs +23 -23
  128. package/esm2020/lib/router/index.mjs +2 -2
  129. package/esm2020/lib/router/models/index.mjs +1 -1
  130. package/esm2020/lib/router/models/router.model.mjs +1 -1
  131. package/esm2020/lib/router/route-builder.mjs +425 -425
  132. package/esm2020/lib/router/tableview-route-builder.mjs +183 -183
  133. package/esm2020/lib/security/authorization.guard.mjs +25 -25
  134. package/esm2020/lib/security/authorization.service.mjs +46 -46
  135. package/esm2020/lib/security/authorization.util.mjs +15 -15
  136. package/esm2020/lib/security/index.mjs +3 -3
  137. package/esm2020/lib/security/model/authorization.type.mjs +7 -7
  138. package/esm2020/lib/security/model/index.mjs +3 -3
  139. package/esm2020/lib/security/model/permission-service.interface.mjs +1 -1
  140. package/esm2020/lib/security/model/permissions.model.mjs +86 -86
  141. package/esm2020/lib/services/action-executor.service.mjs +547 -547
  142. package/esm2020/lib/services/commons.service.mjs +354 -354
  143. package/esm2020/lib/services/configuration.service.mjs +119 -119
  144. package/esm2020/lib/services/error-mapper.service.mjs +13 -13
  145. package/esm2020/lib/services/index.mjs +6 -6
  146. package/esm2020/lib/services/internal/commons-init.provider.mjs +3 -3
  147. package/esm2020/lib/services/internal/commons-init.service.mjs +43 -43
  148. package/esm2020/lib/services/internal/index.mjs +2 -2
  149. package/esm2020/lib/services/navigation.service.mjs +47 -47
  150. package/esm2020/lib/services/providers/config-service.provider.mjs +29 -29
  151. package/esm2020/lib/services/providers/formly-config.provider.mjs +30 -30
  152. package/esm2020/lib/services/providers/index.mjs +2 -2
  153. package/esm2020/lib/services/tokens/browser-storage.token.mjs +5 -5
  154. package/esm2020/lib/services/tokens/commons-init.token.mjs +2 -2
  155. package/esm2020/lib/services/tokens/default-setting.token.mjs +2 -2
  156. package/esm2020/lib/services/tokens/index.mjs +4 -4
  157. package/esm2020/lib/services/tokens/module-config.token.mjs +2 -2
  158. package/esm2020/lib/services/version.service.mjs +38 -38
  159. package/esm2020/lib/services/view-container.component.service.mjs +47 -47
  160. package/esm2020/lib/styles/button-style.builder.mjs +164 -164
  161. package/esm2020/lib/styles/index.mjs +2 -2
  162. package/esm2020/lib/styles/models/index.mjs +2 -2
  163. package/esm2020/lib/styles/models/style-level.enum.mjs +11 -11
  164. package/esm2020/lib/styles/models/style-size.enum.mjs +8 -8
  165. package/esm2020/lib/styles/styles.util.mjs +41 -41
  166. package/esm2020/lib/types/index.mjs +2 -2
  167. package/esm2020/lib/types/type.decorator.mjs +21 -21
  168. package/esm2020/lib/types/type.model.mjs +1 -1
  169. package/esm2020/lib/utils/action-data-provider.util.mjs +144 -144
  170. package/esm2020/lib/utils/date.util.mjs +117 -117
  171. package/esm2020/lib/utils/editor-formly.util.mjs +263 -251
  172. package/esm2020/lib/utils/enum.util.mjs +81 -81
  173. package/esm2020/lib/utils/i18n.util.mjs +232 -232
  174. package/esm2020/lib/utils/index.mjs +9 -9
  175. package/esm2020/lib/utils/model.util.mjs +68 -68
  176. package/esm2020/lib/utils/notification.util.mjs +45 -45
  177. package/esm2020/lib/utils/route.util.mjs +23 -23
  178. package/esm2020/lib/utils/string.util.mjs +26 -26
  179. package/esm2020/lib/utils/tableview.util.mjs +143 -143
  180. package/esm2020/lib/utils/type.util.mjs +92 -92
  181. package/esm2020/mediusinc-mng-commons.mjs +4 -4
  182. package/esm2020/public-api.mjs +54 -54
  183. package/fesm2015/mediusinc-mng-commons.mjs +12803 -12694
  184. package/fesm2015/mediusinc-mng-commons.mjs.map +1 -1
  185. package/fesm2020/mediusinc-mng-commons.mjs +12647 -12540
  186. package/fesm2020/mediusinc-mng-commons.mjs.map +1 -1
  187. package/index.d.ts +5 -5
  188. package/lib/api/models/builders/query-param.builder.d.ts +13 -13
  189. package/lib/api/models/filter-match-type.model.d.ts +23 -23
  190. package/lib/api/models/filter-param.model.d.ts +23 -23
  191. package/lib/api/models/index.d.ts +8 -8
  192. package/lib/api/models/mappers.d.ts +6 -6
  193. package/lib/api/models/query-mode.model.d.ts +16 -16
  194. package/lib/api/models/query-param.model.d.ts +31 -31
  195. package/lib/api/models/query-result.model.d.ts +24 -24
  196. package/lib/api/models/serialization.model.d.ts +8 -8
  197. package/lib/api/services/api.abstract.service.d.ts +24 -24
  198. package/lib/api/services/crud-api.abstract.service.d.ts +22 -22
  199. package/lib/api/services/get-all-api.abstract.service.d.ts +14 -14
  200. package/lib/api/services/index.d.ts +3 -3
  201. package/lib/api/utils/index.d.ts +2 -2
  202. package/lib/api/utils/medius-rest.util.d.ts +16 -16
  203. package/lib/api/utils/object-serializer.util.d.ts +33 -33
  204. package/lib/components/action/action.component.d.ts +69 -69
  205. package/lib/components/action/editor/action-editor.component.d.ts +63 -63
  206. package/lib/components/action/index.d.ts +3 -3
  207. package/lib/components/action/models/action-confirmation-service.model.d.ts +6 -6
  208. package/lib/components/action/models/action-execution.model.d.ts +131 -131
  209. package/lib/components/action/models/index.d.ts +3 -3
  210. package/lib/components/action/models/tableview-action-default-categories.model.d.ts +10 -10
  211. package/lib/components/action/route/action-route.component.d.ts +31 -31
  212. package/lib/components/form/autocomplete/autocomplete.component.d.ts +61 -61
  213. package/lib/components/form/date-range/date-range.component.d.ts +28 -28
  214. package/lib/components/form/dropdown/dropdown.component.d.ts +52 -52
  215. package/lib/components/form/editor/form-editor.component.d.ts +45 -45
  216. package/lib/components/form/formly/fields/formly-field-action/formly-field-action.component.d.ts +13 -0
  217. package/lib/components/form/formly/fields/formly-field-autocomplete/formly-field-autocomplete.component.d.ts +16 -15
  218. package/lib/components/form/formly/fields/formly-field-dropdown/formly-field-dropdown.component.d.ts +15 -14
  219. package/lib/components/form/formly/fields/formly-field-fieldset/formly-field-fieldset.component.d.ts +14 -13
  220. package/lib/components/form/formly/fields/formly-field-input/formly-field-input.component.d.ts +24 -23
  221. package/lib/components/form/formly/fields/formly-field-label/formly-field-label.component.d.ts +11 -10
  222. package/lib/components/form/formly/fields/formly-field-lookup-dialog/formly-field-lookup-dialog.component.d.ts +46 -45
  223. package/lib/components/form/formly/fields/formly-field-table-dialog-form/formly-field-table-dialog-form.component.d.ts +21 -20
  224. package/lib/components/form/formly/fields/formly-field-table-dialog-multiselect/formly-field-table-dialog-multiselect.component.d.ts +37 -36
  225. package/lib/components/form/formly/fields/formly-field-tabs/formly-field-tabs.component.d.ts +7 -6
  226. package/lib/components/form/formly/fields/index.d.ts +10 -9
  227. package/lib/components/form/formly/wrappers/formly-field-no-label-wrapper/formly-field-no-label-wrapper.component.d.ts +6 -0
  228. package/lib/components/form/formly/wrappers/formly-field-wrapper/formly-field-wrapper.component.d.ts +6 -6
  229. package/lib/components/form/formly/wrappers/index.d.ts +2 -2
  230. package/lib/components/form/index.d.ts +4 -4
  231. package/lib/components/form/models/field-action-context.model.d.ts +17 -0
  232. package/lib/components/form/models/form-editor.event.d.ts +37 -37
  233. package/lib/components/form/models/form-editor.interface.d.ts +10 -0
  234. package/lib/components/form/models/index.d.ts +2 -1
  235. package/lib/components/layout/breadcrumb.component.d.ts +8 -8
  236. package/lib/components/layout/footer.component.d.ts +9 -9
  237. package/lib/components/layout/index.d.ts +7 -7
  238. package/lib/components/layout/main-layout.component.d.ts +20 -20
  239. package/lib/components/layout/menu-item.component.d.ts +52 -52
  240. package/lib/components/layout/menu.component.d.ts +10 -10
  241. package/lib/components/layout/services/index.d.ts +1 -1
  242. package/lib/components/layout/services/main-layout.component.service.d.ts +65 -65
  243. package/lib/components/layout/topbar.component.d.ts +28 -28
  244. package/lib/components/layout/version.component.d.ts +19 -19
  245. package/lib/components/tableview/index.d.ts +6 -6
  246. package/lib/components/tableview/models/index.d.ts +1 -1
  247. package/lib/components/tableview/models/table.event.d.ts +17 -17
  248. package/lib/components/tableview/route/tableview-route.abstract.component.d.ts +26 -26
  249. package/lib/components/tableview/route/tableview-route.component.d.ts +18 -18
  250. package/lib/components/tableview/table/column-filter/column-filter.component.d.ts +38 -38
  251. package/lib/components/tableview/table/column-value/column-value.component.d.ts +30 -30
  252. package/lib/components/tableview/table/table.component.d.ts +113 -113
  253. package/lib/components/tableview/tableview.component.d.ts +48 -48
  254. package/lib/config/formly.config.d.ts +16 -16
  255. package/lib/config/index.d.ts +1 -1
  256. package/lib/config/models/{mng-config.model.d.ts → config.model.d.ts} +36 -36
  257. package/lib/config/models/formly-config.model.d.ts +11 -0
  258. package/lib/config/models/index.d.ts +2 -2
  259. package/lib/data-providers/base.data-provider.d.ts +14 -14
  260. package/lib/data-providers/editor.data-provider.d.ts +25 -25
  261. package/lib/data-providers/index.d.ts +6 -6
  262. package/lib/data-providers/lookup.data-provider.d.ts +14 -14
  263. package/lib/data-providers/table.data-provider.d.ts +27 -27
  264. package/lib/data-providers/tableview-crud.data-provider.d.ts +8 -8
  265. package/lib/data-providers/tableview.data-provider.d.ts +37 -37
  266. package/lib/descriptors/action/action-confirmation.descriptor.d.ts +36 -36
  267. package/lib/descriptors/action-button.descriptor.d.ts +22 -22
  268. package/lib/descriptors/action.descriptor.d.ts +212 -212
  269. package/lib/descriptors/column.descriptor.d.ts +123 -123
  270. package/lib/descriptors/editor.descriptor.d.ts +95 -94
  271. package/lib/descriptors/field-validation.descriptor.d.ts +18 -18
  272. package/lib/descriptors/field.descriptor.d.ts +324 -309
  273. package/lib/descriptors/filter.descriptor.d.ts +112 -112
  274. package/lib/descriptors/index.d.ts +11 -11
  275. package/lib/descriptors/interfaces/field-config.interface.d.ts +9 -9
  276. package/lib/descriptors/interfaces/index.d.ts +2 -2
  277. package/lib/descriptors/interfaces/lookup-descriptor.interface.d.ts +17 -17
  278. package/lib/descriptors/model.descriptor.d.ts +18 -18
  279. package/lib/descriptors/table.descriptor.d.ts +182 -182
  280. package/lib/descriptors/tableview.descriptor.d.ts +122 -122
  281. package/lib/descriptors/types/action.type.d.ts +21 -21
  282. package/lib/descriptors/types/column.type.d.ts +10 -10
  283. package/lib/descriptors/types/editor.type.d.ts +6 -6
  284. package/lib/descriptors/types/field.type.d.ts +44 -44
  285. package/lib/descriptors/types/filter.type.d.ts +27 -27
  286. package/lib/descriptors/types/index.d.ts +6 -6
  287. package/lib/descriptors/types/table.type.d.ts +22 -22
  288. package/lib/directives/component.directive.d.ts +16 -16
  289. package/lib/directives/index.d.ts +2 -2
  290. package/lib/directives/template.directive.d.ts +13 -13
  291. package/lib/mng-commons.module.d.ts +94 -93
  292. package/lib/models/column-value.model.d.ts +4 -4
  293. package/lib/models/enum.model.d.ts +6 -6
  294. package/lib/models/error.model.d.ts +14 -14
  295. package/lib/models/formly-field.model.d.ts +16 -16
  296. package/lib/models/index.d.ts +9 -9
  297. package/lib/models/menu.model.d.ts +27 -27
  298. package/lib/models/tableview-attr.model.d.ts +9 -9
  299. package/lib/models/user.model.d.ts +8 -8
  300. package/lib/models/version.model.d.ts +18 -18
  301. package/lib/models/view-container.model.d.ts +37 -37
  302. package/lib/pipes/boolean.pipe.d.ts +7 -7
  303. package/lib/pipes/class-map.pipe.d.ts +7 -7
  304. package/lib/pipes/enum.pipe.d.ts +8 -8
  305. package/lib/pipes/enumerate-async.pipe.d.ts +14 -14
  306. package/lib/pipes/enumerate.pipe.d.ts +21 -21
  307. package/lib/pipes/getter.pipe.d.ts +7 -7
  308. package/lib/pipes/i18n-property.pipe.d.ts +8 -8
  309. package/lib/pipes/index.d.ts +10 -10
  310. package/lib/pipes/json-path.pipe.d.ts +13 -13
  311. package/lib/pipes/models/internal/enumrate-pipe-i18n.model.d.ts +5 -5
  312. package/lib/pipes/models/internal/index.d.ts +1 -1
  313. package/lib/pipes/parametrize.pipe.d.ts +13 -13
  314. package/lib/pipes/template.pipe.d.ts +10 -10
  315. package/lib/router/index.d.ts +2 -2
  316. package/lib/router/models/index.d.ts +1 -1
  317. package/lib/router/models/router.model.d.ts +33 -33
  318. package/lib/router/route-builder.d.ts +98 -98
  319. package/lib/router/tableview-route-builder.d.ts +37 -37
  320. package/lib/security/authorization.guard.d.ts +11 -11
  321. package/lib/security/authorization.service.d.ts +19 -19
  322. package/lib/security/authorization.util.d.ts +5 -5
  323. package/lib/security/index.d.ts +3 -3
  324. package/lib/security/model/authorization.type.d.ts +6 -6
  325. package/lib/security/model/index.d.ts +3 -3
  326. package/lib/security/model/permission-service.interface.d.ts +6 -6
  327. package/lib/security/model/permissions.model.d.ts +37 -37
  328. package/lib/services/action-executor.service.d.ts +149 -149
  329. package/lib/services/commons.service.d.ts +81 -81
  330. package/lib/services/configuration.service.d.ts +45 -45
  331. package/lib/services/error-mapper.service.d.ts +7 -7
  332. package/lib/services/index.d.ts +6 -6
  333. package/lib/services/internal/commons-init.provider.d.ts +3 -3
  334. package/lib/services/internal/commons-init.service.d.ts +16 -16
  335. package/lib/services/internal/index.d.ts +2 -2
  336. package/lib/services/navigation.service.d.ts +14 -14
  337. package/lib/services/providers/config-service.provider.d.ts +6 -6
  338. package/lib/services/providers/formly-config.provider.d.ts +4 -4
  339. package/lib/services/providers/index.d.ts +2 -2
  340. package/lib/services/tokens/browser-storage.token.d.ts +2 -2
  341. package/lib/services/tokens/commons-init.token.d.ts +3 -3
  342. package/lib/services/tokens/default-setting.token.d.ts +2 -2
  343. package/lib/services/tokens/index.d.ts +4 -4
  344. package/lib/services/tokens/module-config.token.d.ts +3 -3
  345. package/lib/services/version.service.d.ts +13 -13
  346. package/lib/services/view-container.component.service.d.ts +28 -28
  347. package/lib/styles/button-style.builder.d.ts +67 -67
  348. package/lib/styles/index.d.ts +2 -2
  349. package/lib/styles/models/index.d.ts +2 -2
  350. package/lib/styles/models/style-level.enum.d.ts +10 -10
  351. package/lib/styles/models/style-size.enum.d.ts +7 -7
  352. package/lib/styles/styles.util.d.ts +14 -14
  353. package/lib/types/index.d.ts +2 -2
  354. package/lib/types/type.decorator.d.ts +4 -4
  355. package/lib/types/type.model.d.ts +23 -23
  356. package/lib/utils/action-data-provider.util.d.ts +20 -20
  357. package/lib/utils/date.util.d.ts +7 -7
  358. package/lib/utils/editor-formly.util.d.ts +12 -11
  359. package/lib/utils/enum.util.d.ts +50 -50
  360. package/lib/utils/i18n.util.d.ts +56 -56
  361. package/lib/utils/index.d.ts +9 -9
  362. package/lib/utils/model.util.d.ts +8 -8
  363. package/lib/utils/notification.util.d.ts +11 -11
  364. package/lib/utils/route.util.d.ts +4 -4
  365. package/lib/utils/string.util.d.ts +4 -4
  366. package/lib/utils/tableview.util.d.ts +39 -39
  367. package/lib/utils/type.util.d.ts +57 -57
  368. package/mediusinc-mng-commons-0.18.0-rc.1.tgz +0 -0
  369. package/package.json +1 -1
  370. package/public-api.d.ts +34 -34
  371. package/version-info.json +6 -6
  372. package/esm2020/lib/components/form/formly/wrappers/formly-table-wrapper/formly-table-wrapper.component.mjs +0 -15
  373. package/esm2020/lib/config/models/mng-config.model.mjs +0 -2
  374. package/esm2020/lib/config/models/mng-formly-config-model.mjs +0 -2
  375. package/lib/components/form/formly/wrappers/formly-table-wrapper/formly-table-wrapper.component.d.ts +0 -6
  376. package/lib/config/models/mng-formly-config-model.d.ts +0 -17
@@ -1,560 +1,560 @@
1
- import { ChangeDetectionStrategy, Component, ContentChildren, EventEmitter, Input, Optional, Output, ViewChild, ViewChildren } from '@angular/core';
2
- import { FilterMatchMode } from 'primeng/api';
3
- import { Table } from 'primeng/table';
4
- import { BehaviorSubject, Observable, ReplaySubject, isObservable, of } from 'rxjs';
5
- import { map } from 'rxjs/operators';
6
- import { MediusFilterMatchType, MediusQueryParam, MediusQueryParamBuilder, MediusQueryResult } from '../../../api/models';
7
- import { MediusRestUtil } from '../../../api/utils';
8
- import { TableDynamicDescriptor } from '../../../descriptors';
9
- import { ActionPositionEnum, FilterTypeEnum, TableFilterDisplayEnum, TablePaginationModeEnum, TableSizeEnum } from '../../../descriptors/types';
10
- import { MngComponentDirective, MngTemplateDirective } from '../../../directives';
11
- import { StylesUtil } from '../../../styles';
12
- import { NotificationUtil } from '../../../utils';
13
- import { MngTableCellClickEvent, MngTableLoadEvent } from '../models';
14
- import * as i0 from "@angular/core";
15
- import * as i1 from "@angular/router";
16
- import * as i2 from "@ngx-translate/core";
17
- import * as i3 from "../../../services";
18
- import * as i4 from "@angular/common";
19
- import * as i5 from "primeng/api";
20
- import * as i6 from "primeng/table";
21
- import * as i7 from "primeng/skeleton";
22
- import * as i8 from "../../../directives/component.directive";
23
- import * as i9 from "./column-value/column-value.component";
24
- import * as i10 from "./column-filter/column-filter.component";
25
- import * as i11 from "../../action/action.component";
26
- import * as i12 from "../../../pipes/i18n-property.pipe";
27
- import * as i13 from "../../../pipes/class-map.pipe";
28
- export class MngTableComponent {
29
- constructor(injector, router, route, translate, actionExecutor, viewContainerService) {
30
- this.injector = injector;
31
- this.router = router;
32
- this.route = route;
33
- this.translate = translate;
34
- this.actionExecutor = actionExecutor;
35
- this.viewContainerService = viewContainerService;
36
- this.filterDisplayRow = TableFilterDisplayEnum.Row;
37
- this.filterDisplayMenu = TableFilterDisplayEnum.Menu;
38
- this.useQueryParams = false;
39
- // extra features input
40
- this.selectionMode = 'multiple';
41
- this.selectionEnabled = false;
42
- // actions
43
- this.actions = [];
44
- this.columnActionMinWidth = null;
45
- // event outputs
46
- this.loadEventEmitter = new EventEmitter();
47
- this.cellClickEventEmitter = new EventEmitter();
48
- this.selectionChangeEventEmitter = new EventEmitter();
49
- this.captionCmpInstEventEmitter = new EventEmitter();
50
- this.columnActionCmpInstEventEmitter = new EventEmitter();
51
- // data provider and items
52
- this.isLazy = false;
53
- this.isPagination = false;
54
- this.useDataProvider = false;
55
- this.useQueryParamsInitializedSubejct = new BehaviorSubject(false);
56
- this.useQueryParamsInitialized$ = this.useQueryParamsInitializedSubejct.asObservable();
57
- this.dataProviderInfiniteScrollItems = [];
58
- this.itemsSubject = new ReplaySubject(1);
59
- this.offset = 0;
60
- this.multiSortMeta = null;
61
- this.filterMetadata = {};
62
- // infinite scroll
63
- this.infiniteScroll = false;
64
- this.tableFullHeightOffset = null;
65
- this.rowHeight = null;
66
- // selection
67
- this.selection = [];
68
- // data provider
69
- this.dataProviderService = null;
70
- this.dataProviderQueryResultSubject = new ReplaySubject(1);
71
- this.dataProviderLoadingSubject = new ReplaySubject(1);
72
- this.dataProviderLatestLazyLoadEventVersion = 0;
73
- this.dataProviderLatestQueryParamVersion = 0;
74
- // filter, sort
75
- this.hasColumnFilters = false;
76
- this.isFilterChanged = false;
77
- this.isSortChanged = false;
78
- this.filterDescriptors = [];
79
- // actions
80
- this.showInlineActionsColumn = false;
81
- this.rowClickActions = [];
82
- this.rowInlineActions = [];
83
- this.subscriptions = [];
84
- }
85
- ngOnInit() {
86
- this.viewContainer = this.viewContainerInit ?? this.viewContainerService ?? undefined;
87
- if (!(this.initialDescriptor instanceof TableDynamicDescriptor)) {
88
- this.descriptor = this.initialDescriptor;
89
- }
90
- // map row settings
91
- this.filterDescriptors = this.descriptor?.columns.filter(c => typeof c.filterDescriptor !== 'undefined').map(c => c.filterDescriptor) ?? [];
92
- this.hasColumnFilters = this.filterDescriptors.length > 0;
93
- this.rows = this.descriptor?.defaultNumRows ?? 25;
94
- this.rowsPerPageOptions = this.descriptor?.rowsPerPageOptions ?? [25, 50, 100];
95
- // process actions
96
- for (const action of this.actions) {
97
- switch (action.position) {
98
- case ActionPositionEnum.RowClick:
99
- this.rowClickActions.push(action);
100
- break;
101
- case ActionPositionEnum.RowInline:
102
- this.rowInlineActions.push(action);
103
- break;
104
- }
105
- }
106
- this.showInlineActionsColumn = typeof this.columnActionComponent !== 'undefined' || this.rowInlineActions.length > 0;
107
- // define all styles
108
- this.className = this.descriptor?.className ?? '';
109
- this.tableFullHeightOffset = this.descriptor?.tableFullHeightOffset ?? null;
110
- this.rowHeight = this.descriptor?.rowHeight ?? null;
111
- if (typeof this.isColumnClickable === 'undefined') {
112
- // define if cell click is being observed via output
113
- this.isColumnClickable = this.rowClickActions.length > 0 || this.cellClickEventEmitter.observed;
114
- }
115
- switch (this.descriptor?.size) {
116
- case TableSizeEnum.Small:
117
- this.className += ' p-datatable-sm';
118
- break;
119
- case TableSizeEnum.Large:
120
- this.className += ' p-datatable-lg';
121
- break;
122
- }
123
- if (this.descriptor?.hasGridlines) {
124
- this.className += ' p-datatable-gridlines';
125
- }
126
- if (this.descriptor && !this.columnActionMinWidth) {
127
- this.columnActionMinWidth = StylesUtil.calculateTableColumnActionWidth(this.descriptor, this.rowInlineActions);
128
- }
129
- // check if infinite scroll
130
- if (this.descriptor?.paginationMode === TablePaginationModeEnum.InfiniteScroll) {
131
- this.infiniteScroll = true;
132
- this.tableFullHeightOffset = this.descriptor.tableFullHeightOffset ?? 315;
133
- this.rowHeight = this.descriptor.rowHeight ?? 45;
134
- this.useQueryParams = false;
135
- }
136
- else if (this.descriptor?.paginationMode === TablePaginationModeEnum.Pagination) {
137
- this.isPagination = true;
138
- }
139
- // check if data provider is supplied, if is, use it primarily
140
- if (this.dataProvider) {
141
- // map subjects to observables and initiate data
142
- this.useDataProvider = true;
143
- this.isLazy = this.dataProvider.isLazy;
144
- this.queryResult$ = this.dataProviderQueryResultSubject.asObservable();
145
- this.loading$ = this.dataProviderLoadingSubject.asObservable();
146
- const emptyQueryResult = new MediusQueryResult();
147
- emptyQueryResult.pageData = [];
148
- emptyQueryResult.allDataCount = 0;
149
- this.dataProviderLoadingSubject.next(false);
150
- this.dataProviderQueryResultSubject.next(emptyQueryResult);
151
- // inject service
152
- if (this.dataProvider.serviceType) {
153
- this.dataProviderService = this.injector.get(this.dataProvider.serviceType);
154
- }
155
- const reloadSubscription = this.dataProvider.getAllReload$.subscribe({
156
- next: () => {
157
- this.reload();
158
- }
159
- });
160
- this.subscriptions.push(reloadSubscription);
161
- }
162
- else {
163
- // if query result is provided, use it as secondary source or else try to use items
164
- if (this.queryResult) {
165
- this.queryResult$ = this.queryResult instanceof Observable ? this.queryResult : of(this.queryResult);
166
- }
167
- else {
168
- this.queryResult$ = (isObservable(this.items) ? this.items : this.itemsSubject.asObservable()).pipe(
169
- // distinctUntilChanged((v1, v2) => v1.length === v2.length &&
170
- // v1.every((v1i, idx) => v1i[this.descriptor.dataKeyProperty] === v2[idx][this.descriptor.dataKeyProperty])),
171
- map(items => {
172
- const queryResult = new MediusQueryResult();
173
- queryResult.pageData = items;
174
- queryResult.allDataCount = items.length;
175
- return queryResult;
176
- }));
177
- if (!isObservable(this.items)) {
178
- this.itemsSubject.next(this.items ?? []);
179
- }
180
- }
181
- if (typeof this.loading !== 'undefined') {
182
- this.loading$ = this.loading instanceof Observable ? this.loading : of(this.loading);
183
- }
184
- }
185
- const initialQueryParamMap = this.route.snapshot.queryParamMap;
186
- if (this.useQueryParams &&
187
- ((!initialQueryParamMap.has('sort') && this.descriptor?.hasDefaultSort) ||
188
- (!initialQueryParamMap.has('filter') && this.filterDescriptors.some(fd => fd.hasDefaultValue)))) {
189
- // default sort/filters are applied, no additional filtering/sorting is specified in query param
190
- // redirect must be done at first step
191
- const mediusQueryParam = MediusRestUtil.fromAngularQueryParamsToMediusQueryParams(this.route.snapshot.queryParams, this.filterDescriptors, this.rowsPerPageOptions[0]);
192
- const event = {};
193
- event.multiSortMeta = this.createSortMeta(mediusQueryParam);
194
- event.filters = this.createFilterMeta(mediusQueryParam);
195
- // first navigate to correct url with default filters/sorts
196
- this.router
197
- .navigate([], {
198
- relativeTo: this.route,
199
- replaceUrl: true,
200
- queryParams: MediusRestUtil.fromPrimeLazyLoadEventToAngularQueryParams(event, this.rowsPerPageOptions[0])
201
- })
202
- .then(() => {
203
- this.initializeDataLoadingTriggers();
204
- });
205
- }
206
- else {
207
- this.initializeDataLoadingTriggers();
208
- }
209
- this.queryResultSubscription = this.queryResult$.subscribe(e => (this.queryResult = e));
210
- }
211
- ngAfterContentInit() {
212
- this.templates.forEach(template => {
213
- switch (template.getType()) {
214
- case 'caption':
215
- this.captionTemplate = template.template;
216
- break;
217
- case 'columnAction':
218
- this.columnActionTemplate = template.template;
219
- if (!this.showInlineActionsColumn) {
220
- this.showInlineActionsColumn = true;
221
- }
222
- break;
223
- case 'footer':
224
- this.footerTemplate = template.template;
225
- break;
226
- }
227
- });
228
- }
229
- ngOnChanges(changes) {
230
- if (changes['items'] && !changes['items'].firstChange && Array.isArray(changes['items'].currentValue)) {
231
- this.itemsSubject.next(changes['items'].currentValue);
232
- }
233
- }
234
- ngOnDestroy() {
235
- this.dataProviderSubscription?.unsubscribe();
236
- this.queryResultSubscription?.unsubscribe();
237
- this.subscriptions.forEach(s => s.unsubscribe());
238
- }
239
- reload(emitEvent = false, resetParams = false) {
240
- const queryParamsBuilder = resetParams
241
- ? MediusQueryParamBuilder.create(this.rowsPerPageOptions[0], 0)
242
- : MediusQueryParamBuilder.createFromExisting(this.dataProviderLatestQueryParam ?? new MediusQueryParam())
243
- .withItemsPerPage(this.rows)
244
- .withItemsOffset(this.offset);
245
- this.loadTableWithDataProvider(queryParamsBuilder.build(), emitEvent);
246
- }
247
- onTableLazyLoad(event) {
248
- this.dataProviderLatestLazyLoadEvent = event;
249
- this.dataProviderLatestLazyLoadEventVersion++;
250
- if (this.useQueryParams) {
251
- if (!event.multiSortMeta || event.multiSortMeta.length === 0) {
252
- // add default sort meta to event if not multisort meta is present
253
- event.multiSortMeta = this.createSortMeta();
254
- }
255
- if (!event.filters) {
256
- event.filters = this.createFilterMeta();
257
- }
258
- this.router.navigate([], {
259
- relativeTo: this.route,
260
- replaceUrl: true,
261
- queryParams: MediusRestUtil.fromPrimeLazyLoadEventToAngularQueryParams(event, this.rowsPerPageOptions[0])
262
- });
263
- }
264
- else {
265
- const mediusQueryParams = event ? MediusRestUtil.fromPrimeLazyLoadEventToMediusQueryParams(event) : new MediusQueryParam();
266
- this.loadTableWithDataProvider(mediusQueryParams);
267
- }
268
- }
269
- // eslint-disable-next-line @typescript-eslint/no-unused-vars
270
- onTableSort(event) {
271
- this.isSortChanged = true;
272
- }
273
- // eslint-disable-next-line @typescript-eslint/no-unused-vars
274
- onTableFilter(event) {
275
- this.isFilterChanged = true;
276
- }
277
- onCellClick(event, col, item, idx) {
278
- const mngEvent = new MngTableCellClickEvent(col, item, idx);
279
- this.cellClickEventEmitter.next(mngEvent);
280
- if (this.rowClickActions.length) {
281
- for (const action of this.rowClickActions) {
282
- this.actionExecutor.triggerRowClickAction(action, mngEvent, this.route, this.descriptor);
283
- }
284
- }
285
- }
286
- onSelectionChange(event) {
287
- this.selectionChangeEventEmitter.emit(event);
288
- }
289
- onCaptionCmpInst(instance) {
290
- this.captionCmpInstEventEmitter.next(instance);
291
- }
292
- onColumnActionCmpInst(instance) {
293
- this.columnActionCmpInstEventEmitter.next(instance);
294
- }
295
- onActionFinish(runResult) {
296
- if (!runResult.error) {
297
- this.reload();
298
- }
299
- }
300
- loadTableWithDataProvider(queryParam = null, emitEvent = true) {
301
- if (!this.useDataProvider) {
302
- return;
303
- }
304
- this.dataProviderSubscription?.unsubscribe();
305
- this.dataProviderLoadingSubject.next(true);
306
- if (!queryParam) {
307
- queryParam = MediusQueryParamBuilder.create(this.rowsPerPageOptions[0]).build();
308
- }
309
- this.dataProviderLatestQueryParam = queryParam;
310
- this.dataProviderLatestQueryParamVersion++;
311
- MediusRestUtil.modifyFilterProperties(queryParam, this.filterDescriptors);
312
- this.dataProviderSubscription = this.dataProvider?.getAll(queryParam, this.dataProviderService).subscribe({
313
- next: res => {
314
- if (this.initialDescriptor instanceof TableDynamicDescriptor) {
315
- this.descriptor = this.initialDescriptor.toTableDescriptorFromData(res);
316
- this.filterDescriptors = this.descriptor.columns.filter(c => typeof c.filterDescriptor !== 'undefined').map(c => c.filterDescriptor);
317
- this.hasColumnFilters = this.filterDescriptors.length > 0;
318
- // } else {
319
- // this.descriptor = this.initialDescriptor.onDataReceivedTypeBuilding(res);
320
- }
321
- if (this.infiniteScroll) {
322
- if (this.isFilterChanged || this.isSortChanged) {
323
- this.dataProviderInfiniteScrollItems = [];
324
- }
325
- this.dataProviderInfiniteScrollItems.splice(queryParam.itemsOffset ?? 0, queryParam.itemsPerPage ?? this.rows, ...(res.pageData ?? []));
326
- this.dataProviderInfiniteScrollItems = [...this.dataProviderInfiniteScrollItems];
327
- }
328
- else {
329
- this.dataProviderQueryResultSubject.next(res);
330
- }
331
- this.isFilterChanged = false;
332
- this.isSortChanged = false;
333
- this.dataProviderLoadingSubject.next(false);
334
- },
335
- error: err => {
336
- // TODO: check what happens on error with no model iniside descriptor
337
- NotificationUtil.tableNotificationError(this.translate, this.descriptor, err, this.viewContainer);
338
- const emptyQueryResult = new MediusQueryResult();
339
- emptyQueryResult.pageData = [];
340
- emptyQueryResult.allDataCount = 0;
341
- this.dataProviderQueryResultSubject.next(emptyQueryResult);
342
- this.dataProviderLoadingSubject.next(false);
343
- }
344
- });
345
- if (emitEvent) {
346
- const mngEvent = new MngTableLoadEvent();
347
- mngEvent.originalEvent = this.dataProviderLatestLazyLoadEvent ?? undefined;
348
- mngEvent.queryParam = queryParam;
349
- this.loadEventEmitter.next(mngEvent);
350
- }
351
- }
352
- loadTableFromRouteUpdate(params) {
353
- const mediusQueryParam = MediusRestUtil.fromAngularQueryParamsToMediusQueryParams(params, this.filterDescriptors, this.rowsPerPageOptions[0]);
354
- if (this.dataProviderLatestLazyLoadEventVersion < this.dataProviderLatestQueryParamVersion + 1) {
355
- // update only if new version from query params will be higher
356
- this.updatePrimeSortAndFilter(mediusQueryParam);
357
- }
358
- this.useQueryParamsInitializedSubejct.next(true);
359
- this.loadTableWithDataProvider(mediusQueryParam);
360
- }
361
- updatePrimeSortAndFilter(mediusQueryParam) {
362
- this.multiSortMeta = this.createSortMeta(mediusQueryParam);
363
- this.filterMetadata = this.createFilterMeta(mediusQueryParam);
364
- this.rows = mediusQueryParam?.itemsPerPage ?? this.rowsPerPageOptions[0];
365
- this.offset = mediusQueryParam?.itemsOffset ?? 0;
366
- }
367
- createFilterMeta(mediusQueryParam) {
368
- let params;
369
- if (!mediusQueryParam) {
370
- params = new MediusQueryParam();
371
- }
372
- else {
373
- params = mediusQueryParam;
374
- }
375
- const primeFilterMeta = {};
376
- // if any filter is present, no default filters should be applied!
377
- const applyDefaultFilters = (params.filterParams?.length ?? 0) === 0;
378
- this.filterDescriptors.forEach(f => {
379
- let matchMode;
380
- if (f.defaultFilterMatchMode) {
381
- matchMode = f.defaultFilterMatchMode;
382
- }
383
- else {
384
- switch (f.filterType) {
385
- case FilterTypeEnum.String:
386
- matchMode = FilterMatchMode.CONTAINS;
387
- break;
388
- case FilterTypeEnum.Date:
389
- matchMode = FilterMatchMode.DATE_IS;
390
- break;
391
- case FilterTypeEnum.Lookup:
392
- case FilterTypeEnum.LookupEnum: {
393
- const lookupFilter = f;
394
- if (lookupFilter.multiselect) {
395
- matchMode = FilterMatchMode.IN;
396
- }
397
- else {
398
- matchMode = FilterMatchMode.EQUALS;
399
- }
400
- break;
401
- }
402
- default:
403
- matchMode = FilterMatchMode.EQUALS;
404
- break;
405
- }
406
- }
407
- let value = null;
408
- if (applyDefaultFilters) {
409
- if (f.defaultValueTo && f.defaultValue) {
410
- value = [f.defaultValue, f.defaultValueTo];
411
- }
412
- else if (f.defaultValue) {
413
- value = f.defaultValue;
414
- }
415
- }
416
- primeFilterMeta[f.property] = {
417
- value: value,
418
- matchMode: matchMode
419
- };
420
- });
421
- params.filterParams?.forEach(f => {
422
- const descriptor = this.filterDescriptors.find(fd => fd.filterProperty === f.property || fd.property === f.property);
423
- const matchMode = f.filterMatchType && descriptor ? MediusRestUtil.getMapping(f.filterMatchType, descriptor.filterType, 2)?.[0] : MediusFilterMatchType.Equals;
424
- if (descriptor && matchMode) {
425
- let filterValue = f.filterValue;
426
- if (descriptor.filterType === FilterTypeEnum.Date && typeof filterValue !== 'undefined') {
427
- if (typeof filterValue === 'string' || typeof filterValue === 'number') {
428
- filterValue = new Date(filterValue);
429
- }
430
- // if range is provided, take that into account
431
- if (typeof f.filterValueTo === 'string' || typeof f.filterValueTo === 'number') {
432
- const filterValueTo = new Date(f.filterValueTo);
433
- filterValue = [filterValue, filterValueTo];
434
- }
435
- }
436
- primeFilterMeta[descriptor.property] = {
437
- value: filterValue,
438
- matchMode: matchMode
439
- };
440
- }
441
- });
442
- return primeFilterMeta;
443
- }
444
- createSortMeta(mediusQueryParam) {
445
- let params;
446
- if (!mediusQueryParam) {
447
- params = new MediusQueryParam();
448
- }
449
- else {
450
- params = mediusQueryParam;
451
- }
452
- let sortMeta;
453
- const applyDefaultSorts = (params.sortProperty?.length ?? 0) === 0;
454
- if (applyDefaultSorts && this.descriptor?.hasDefaultSort) {
455
- sortMeta = this.descriptor.defaultSortProperty.map((p, idx) => ({
456
- field: p,
457
- order: this.descriptor.defaultSortAsc[idx] ? 1 : -1
458
- }));
459
- }
460
- else {
461
- sortMeta = [];
462
- }
463
- params.sortProperty?.forEach((s, idx) => {
464
- const existingIndex = sortMeta.findIndex(value => value.field === s);
465
- if (existingIndex > -1) {
466
- sortMeta[existingIndex].order = params.sortAsc?.[idx] ?? true ? 1 : -1;
467
- }
468
- else {
469
- sortMeta.push({
470
- field: s,
471
- order: params.sortAsc?.[idx] ?? true ? 1 : -1
472
- });
473
- }
474
- });
475
- return sortMeta;
476
- }
477
- initializeDataLoadingTriggers() {
478
- if (this.useQueryParams) {
479
- // trigger table loads from route updates
480
- const subscription = this.route.queryParams.subscribe(qp => {
481
- this.loadTableFromRouteUpdate(qp);
482
- });
483
- this.subscriptions.push(subscription);
484
- }
485
- else {
486
- // load data immediately by creating default sorts and filters (primeng will trigger onLazyLoad event on sort&filter metadata change)
487
- const defaultSort = this.createSortMeta();
488
- if (defaultSort.length > 0) {
489
- this.multiSortMeta = defaultSort;
490
- }
491
- const defaultFilter = this.createFilterMeta();
492
- if (defaultFilter) {
493
- this.filterMetadata = defaultFilter;
494
- }
495
- }
496
- }
497
- }
498
- MngTableComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.1.0", ngImport: i0, type: MngTableComponent, deps: [{ token: i0.Injector }, { token: i1.Router }, { token: i1.ActivatedRoute }, { token: i2.TranslateService }, { token: i3.MngActionExecutorService }, { token: i3.MngViewContainerComponentService, optional: true }], target: i0.ɵɵFactoryTarget.Component });
499
- MngTableComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.1.0", type: MngTableComponent, selector: "mng-table", inputs: { initialDescriptor: ["descriptor", "initialDescriptor"], items: "items", queryResult: "queryResult", loading: "loading", dataProvider: "dataProvider", useQueryParams: "useQueryParams", selectionMode: "selectionMode", selectionEnabled: "selectionEnabled", actions: "actions", isColumnClickable: "isColumnClickable", viewContainerInit: ["viewContainer", "viewContainerInit"], captionComponent: "captionComponent", columnActionComponent: "columnActionComponent", columnActionMinWidth: "columnActionMinWidth" }, outputs: { loadEventEmitter: "tableLoad", cellClickEventEmitter: "cellClick", selectionChangeEventEmitter: "selectionChange", captionCmpInstEventEmitter: "captionComponentInstance", columnActionCmpInstEventEmitter: "columnActionComponentInstance" }, queries: [{ propertyName: "templates", predicate: MngTemplateDirective }], viewQueries: [{ propertyName: "primeTable", first: true, predicate: Table, descendants: true }, { propertyName: "components", predicate: MngComponentDirective, descendants: true }], usesOnChanges: true, ngImport: i0, template: "<div [style.height]=\"tableFullHeightOffset ? 'calc(100vh - ' + tableFullHeightOffset + 'px)' : null\">\n <!-- MUST NOT use observable for value when using virtual scroll - does not work for some reason -->\n <p-table\n *ngIf=\"!useQueryParams || (useQueryParamsInitialized$ | async)\"\n [value]=\"infiniteScroll ? dataProviderInfiniteScrollItems : (queryResult$ | async)?.pageData ?? []\"\n [dataKey]=\"$any(descriptor?.dataKeyProperty ?? null)\"\n [lazy]=\"isLazy\"\n [loading]=\"(loading$ | async) ?? false\"\n [paginator]=\"isPagination && !infiniteScroll\"\n [rows]=\"$any(infiniteScroll ? 20 : rows)\"\n [first]=\"$any(infiniteScroll ? 0 : offset)\"\n [totalRecords]=\"$any(infiniteScroll ? null : (queryResult$ | async)?.allDataCount ?? 0)\"\n [rowsPerPageOptions]=\"$any(infiniteScroll ? null : rowsPerPageOptions)\"\n [showCurrentPageReport]=\"!infiniteScroll\"\n [currentPageReportTemplate]=\"'mngTable.paginationMsg' | translate\"\n [multiSortMeta]=\"$any(multiSortMeta)\"\n [filters]=\"filterMetadata\"\n sortMode=\"multiple\"\n [(selection)]=\"selection\"\n (selectionChange)=\"onSelectionChange($event)\"\n [selectionMode]=\"$any(selectionEnabled ? selectionMode : null)\"\n [scrollable]=\"true\"\n [virtualScroll]=\"infiniteScroll\"\n [virtualScrollItemSize]=\"$any(rowHeight)\"\n scrollHeight=\"flex\"\n [rowHover]=\"descriptor?.hasHover ?? true\"\n [styleClass]=\"className\"\n (onLazyLoad)=\"onTableLazyLoad($event)\"\n (onSort)=\"onTableSort($event)\"\n (onFilter)=\"onTableFilter($event)\">\n <ng-template *ngIf=\"captionTemplate || captionComponent || descriptor?.title\" pTemplate=\"caption\">\n <ng-container *ngIf=\"captionTemplate; else componentOrDefaultCaption\">\n <ng-container *ngTemplateOutlet=\"captionTemplate\"></ng-container>\n </ng-container>\n <ng-template #componentOrDefaultCaption>\n <div *ngIf=\"captionComponent; else defaultCaption\" [mngComponent]=\"captionComponent\" (instanceCreated)=\"onCaptionCmpInst($event)\"></div>\n <ng-template #defaultCaption>\n <h5 class=\"p-0 m-0\">{{ descriptor?.title }}</h5>\n </ng-template>\n </ng-template>\n </ng-template>\n\n <ng-template pTemplate=\"header\">\n <tr *ngIf=\"!descriptor?.hideHeader\" class=\"mng-table-header\" [class]=\"descriptor?.headerClassName\">\n <th *ngIf=\"selectionEnabled && selectionMode === 'multiple'\" style=\"min-width: 36px\" pFrozenColumn>\n <p-tableHeaderCheckbox></p-tableHeaderCheckbox>\n </th>\n <!-- We need the line below, because otherwise p-tableRadioButton shifts the rest of the columns in table -->\n <th *ngIf=\"selectionEnabled && selectionMode === 'single'\" style=\"min-width: 36px\" pFrozenColumn></th>\n <ng-container *ngFor=\"let col of descriptor?.columns\">\n <th\n *ngIf=\"col.isSortEnabled\"\n [pSortableColumn]=\"col.property\"\n [style.width.%]=\"col.width\"\n [style.min-width.px]=\"col.minWidth\"\n [style.max-width.px]=\"col.maxWidth\"\n [class]=\"\n col.headerClassName +\n (descriptor?.filterDisplay === filterDisplayRow && hasColumnFilters && col.filterDescriptor\n ? ' mng-column-filter-' + col.filterDescriptor.filterType\n : '')\n \">\n <div class=\"flex justify-content-between align-items-center\">\n {{ col.title ?? (col.property | i18nProperty: descriptor!.model) | translate }}\n <p-sortIcon [field]=\"col.property\"></p-sortIcon>\n <mng-table-column-filter\n *ngIf=\"col.filterDescriptor && descriptor!.filterDisplay === filterDisplayMenu\"\n class=\"ml-auto\"\n [display]=\"descriptor!.filterDisplay\"\n [descriptor]=\"col.filterDescriptor\">\n </mng-table-column-filter>\n </div>\n </th>\n <th\n *ngIf=\"!col.isSortEnabled\"\n [style.width.%]=\"col.width\"\n [style.min-width.px]=\"col.minWidth\"\n [style.max-width.px]=\"col.maxWidth\"\n [class]=\"\n col.headerClassName +\n (descriptor?.filterDisplay === filterDisplayRow && hasColumnFilters && col.filterDescriptor\n ? ' mng-column-filter-' + col.filterDescriptor.filterType\n : '')\n \">\n {{ col.title ?? (col.property | i18nProperty: descriptor!.model) | translate }}\n <ng-container>\n <mng-table-column-filter\n *ngIf=\"col.filterDescriptor && descriptor!.filterDisplay === filterDisplayMenu\"\n class=\"ml-auto\"\n [display]=\"descriptor!.filterDisplay\"\n [descriptor]=\"col.filterDescriptor\">\n </mng-table-column-filter>\n </ng-container>\n </th>\n </ng-container>\n <th *ngIf=\"showInlineActionsColumn\" [style.min-width.px]=\"columnActionMinWidth\" pFrozenColumn></th>\n </tr>\n <tr *ngIf=\"descriptor?.filterDisplay === filterDisplayRow && hasColumnFilters\" class=\"mng-column-filter-row\">\n <!-- We need the line below, because otherwise p-tableRadioButton shifts the rest of the columns in table -->\n <th *ngIf=\"selectionEnabled && selectionMode === 'single'\" style=\"min-width: 36px\" pFrozenColumn></th>\n <th\n *ngFor=\"let col of descriptor?.columns\"\n [class]=\"(col.filterDescriptor ? 'mng-column-filter-' + col.filterDescriptor.filterType + ' ' : ' ') + col.filterDescriptor?.columnClassName\"\n [style.width.%]=\"col.filterDescriptor?.columnWidth ?? col.width\"\n [style.min-width.px]=\"col.filterDescriptor?.columnMinWidth ?? col.minWidth\"\n [style.max-width.px]=\"col.maxWidth\">\n <div class=\"flex\" *ngIf=\"col.filterDescriptor\">\n <mng-table-column-filter [display]=\"descriptor!.filterDisplay\" [descriptor]=\"col.filterDescriptor\"></mng-table-column-filter>\n </div>\n </th>\n <th *ngIf=\"showInlineActionsColumn\" [style.min-width.px]=\"columnActionMinWidth\" pFrozenColumn></th>\n </tr>\n </ng-template>\n\n <ng-template pTemplate=\"body\" let-item let-idx=\"rowIndex\">\n <tr [style.height.px]=\"rowHeight\" [class]=\"descriptor?.rowClassName | mngClassMapPipe: descriptor?.rowClassNameMapFn:item\">\n <td *ngIf=\"selectionEnabled && selectionMode === 'multiple'\" style=\"min-width: 36px\" pFrozenColumn>\n <p-tableCheckbox [value]=\"item\"></p-tableCheckbox>\n </td>\n <td *ngIf=\"selectionEnabled && selectionMode === 'single'\" style=\"min-width: 36px\" pFrozenColumn>\n <p-tableRadioButton [value]=\"item\"></p-tableRadioButton>\n </td>\n <td\n *ngFor=\"let col of descriptor?.columns\"\n (click)=\"onCellClick($event, col, item, idx)\"\n [class]=\"\n col.className +\n (descriptor?.filterDisplay === filterDisplayRow && hasColumnFilters && col.filterDescriptor ? ' mng-column-filter-' + col.filterDescriptor.filterType : '')\n \"\n [class.clickable]=\"isColumnClickable\"\n [style.width.%]=\"col.width\"\n [style.min-width.px]=\"col.minWidth\"\n [style.max-width.px]=\"col.maxWidth\">\n <span class=\"p-column-title\">{{ col.title ?? (col.property | i18nProperty: descriptor!.model) | translate }}</span>\n <mng-table-column-value [descriptor]=\"col\" [item]=\"item\"></mng-table-column-value>\n </td>\n <td\n *ngIf=\"showInlineActionsColumn\"\n class=\"column-action justify-content-end text-right\"\n [style.min-width.px]=\"columnActionMinWidth\"\n pFrozenColumn\n alignFrozen=\"right\">\n <ng-container *ngIf=\"columnActionTemplate; else showColumnActionComponentOrDefault\">\n <ng-container *ngTemplateOutlet=\"columnActionTemplate; context: {rowItem: item, rowIndex: idx}\"></ng-container>\n </ng-container>\n <ng-template #showColumnActionComponentOrDefault>\n <span\n *ngIf=\"columnActionComponent; else defaultColumnActions\"\n [mngComponent]=\"columnActionComponent!\"\n (instanceCreated)=\"onColumnActionCmpInst($event)\"></span>\n </ng-template>\n <ng-template #defaultColumnActions>\n <mng-action\n *ngFor=\"let action of rowInlineActions\"\n [action]=\"action\"\n [item]=\"item\"\n [itemId]=\"descriptor?.model?.idPropertyName ? item[descriptor!.model!.idPropertyName!] : null\"\n [actionData]=\"{itemIndex: idx}\"\n (finish)=\"onActionFinish($event)\">\n </mng-action>\n </ng-template>\n </td>\n </tr>\n </ng-template>\n\n <ng-template pTemplate=\"loadingbody\">\n <tr [style.height.px]=\"rowHeight\">\n <td [attr.colspan]=\"(descriptor?.columns?.length ?? 0) + (showInlineActionsColumn ? 1 : 0) + (selectionEnabled ? 1 : 0)\">\n <div class=\"loading-text\"></div>\n <p-skeleton [ngStyle]=\"{width: '100%'}\"></p-skeleton>\n </td>\n </tr>\n </ng-template>\n\n <ng-template pTemplate=\"emptymessage\">\n <tr [style.height.px]=\"rowHeight\">\n <td [attr.colspan]=\"(descriptor?.columns?.length ?? 0) + (showInlineActionsColumn ? 1 : 0) + (selectionEnabled ? 1 : 0)\">\n {{ 'mngTable.noItems' | translate }}\n </td>\n </tr>\n </ng-template>\n\n <ng-template *ngIf=\"footerTemplate\" pTemplate=\"summary\">\n <ng-container [ngTemplateOutlet]=\"footerTemplate\" [ngTemplateOutletContext]=\"{queryResult: queryResult}\"></ng-container>\n </ng-template>\n </p-table>\n</div>\n", dependencies: [{ kind: "directive", type: i4.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i4.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i4.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "directive", type: i4.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "directive", type: i5.PrimeTemplate, selector: "[pTemplate]", inputs: ["type", "pTemplate"] }, { kind: "component", type: i6.Table, selector: "p-table", inputs: ["frozenColumns", "frozenValue", "style", "styleClass", "tableStyle", "tableStyleClass", "paginator", "pageLinks", "rowsPerPageOptions", "alwaysShowPaginator", "paginatorPosition", "paginatorDropdownAppendTo", "paginatorDropdownScrollHeight", "currentPageReportTemplate", "showCurrentPageReport", "showJumpToPageDropdown", "showJumpToPageInput", "showFirstLastIcon", "showPageLinks", "defaultSortOrder", "sortMode", "resetPageOnSort", "selectionMode", "selectionPageOnly", "contextMenuSelection", "contextMenuSelectionMode", "dataKey", "metaKeySelection", "rowSelectable", "rowTrackBy", "lazy", "lazyLoadOnInit", "compareSelectionBy", "csvSeparator", "exportFilename", "filters", "globalFilterFields", "filterDelay", "filterLocale", "expandedRowKeys", "editingRowKeys", "rowExpandMode", "scrollable", "scrollDirection", "rowGroupMode", "scrollHeight", "virtualScroll", "virtualScrollItemSize", "virtualScrollOptions", "virtualScrollDelay", "frozenWidth", "responsive", "contextMenu", "resizableColumns", "columnResizeMode", "reorderableColumns", "loading", "loadingIcon", "showLoader", "rowHover", "customSort", "showInitialSortBadge", "autoLayout", "exportFunction", "exportHeader", "stateKey", "stateStorage", "editMode", "groupRowsBy", "groupRowsByOrder", "responsiveLayout", "breakpoint", "virtualRowHeight", "value", "columns", "first", "rows", "totalRecords", "sortField", "sortOrder", "multiSortMeta", "selection", "selectAll"], outputs: ["selectAllChange", "selectionChange", "contextMenuSelectionChange", "onRowSelect", "onRowUnselect", "onPage", "onSort", "onFilter", "onLazyLoad", "onRowExpand", "onRowCollapse", "onContextMenuSelect", "onColResize", "onColReorder", "onRowReorder", "onEditInit", "onEditComplete", "onEditCancel", "onHeaderCheckboxToggle", "sortFunction", "firstChange", "rowsChange", "onStateSave", "onStateRestore"] }, { kind: "directive", type: i6.SortableColumn, selector: "[pSortableColumn]", inputs: ["pSortableColumn", "pSortableColumnDisabled"] }, { kind: "directive", type: i6.FrozenColumn, selector: "[pFrozenColumn]", inputs: ["frozen", "alignFrozen"] }, { kind: "component", type: i6.SortIcon, selector: "p-sortIcon", inputs: ["field"] }, { kind: "component", type: i6.TableRadioButton, selector: "p-tableRadioButton", inputs: ["disabled", "value", "index", "inputId", "name", "ariaLabel"] }, { kind: "component", type: i6.TableCheckbox, selector: "p-tableCheckbox", inputs: ["disabled", "value", "index", "inputId", "name", "required", "ariaLabel"] }, { kind: "component", type: i6.TableHeaderCheckbox, selector: "p-tableHeaderCheckbox", inputs: ["disabled", "inputId", "name", "ariaLabel"] }, { kind: "component", type: i7.Skeleton, selector: "p-skeleton", inputs: ["styleClass", "style", "shape", "animation", "borderRadius", "size", "width", "height"] }, { kind: "directive", type: i8.MngComponentDirective, selector: "[mngComponent]", inputs: ["mngComponent", "inputs"], outputs: ["instanceCreated"] }, { kind: "component", type: i9.MngTableColumnValueComponent, selector: "mng-table-column-value", inputs: ["descriptor", "item"] }, { kind: "component", type: i10.MngTableColumnFilterComponent, selector: "mng-table-column-filter", inputs: ["descriptor", "display"] }, { kind: "component", type: i11.MngActionComponent, selector: "mng-action", inputs: ["action", "item", "itemId", "actionData", "queryParam", "dataProvider", "disabled", "loading", "viewContainer", "selectedItems"], outputs: ["finish"] }, { kind: "pipe", type: i4.AsyncPipe, name: "async" }, { kind: "pipe", type: i2.TranslatePipe, name: "translate" }, { kind: "pipe", type: i12.MngI18nPropertyPipe, name: "i18nProperty" }, { kind: "pipe", type: i13.MngClassMapPipe, name: "mngClassMapPipe" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
500
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.1.0", ngImport: i0, type: MngTableComponent, decorators: [{
501
- type: Component,
502
- args: [{ selector: 'mng-table', changeDetection: ChangeDetectionStrategy.OnPush, template: "<div [style.height]=\"tableFullHeightOffset ? 'calc(100vh - ' + tableFullHeightOffset + 'px)' : null\">\n <!-- MUST NOT use observable for value when using virtual scroll - does not work for some reason -->\n <p-table\n *ngIf=\"!useQueryParams || (useQueryParamsInitialized$ | async)\"\n [value]=\"infiniteScroll ? dataProviderInfiniteScrollItems : (queryResult$ | async)?.pageData ?? []\"\n [dataKey]=\"$any(descriptor?.dataKeyProperty ?? null)\"\n [lazy]=\"isLazy\"\n [loading]=\"(loading$ | async) ?? false\"\n [paginator]=\"isPagination && !infiniteScroll\"\n [rows]=\"$any(infiniteScroll ? 20 : rows)\"\n [first]=\"$any(infiniteScroll ? 0 : offset)\"\n [totalRecords]=\"$any(infiniteScroll ? null : (queryResult$ | async)?.allDataCount ?? 0)\"\n [rowsPerPageOptions]=\"$any(infiniteScroll ? null : rowsPerPageOptions)\"\n [showCurrentPageReport]=\"!infiniteScroll\"\n [currentPageReportTemplate]=\"'mngTable.paginationMsg' | translate\"\n [multiSortMeta]=\"$any(multiSortMeta)\"\n [filters]=\"filterMetadata\"\n sortMode=\"multiple\"\n [(selection)]=\"selection\"\n (selectionChange)=\"onSelectionChange($event)\"\n [selectionMode]=\"$any(selectionEnabled ? selectionMode : null)\"\n [scrollable]=\"true\"\n [virtualScroll]=\"infiniteScroll\"\n [virtualScrollItemSize]=\"$any(rowHeight)\"\n scrollHeight=\"flex\"\n [rowHover]=\"descriptor?.hasHover ?? true\"\n [styleClass]=\"className\"\n (onLazyLoad)=\"onTableLazyLoad($event)\"\n (onSort)=\"onTableSort($event)\"\n (onFilter)=\"onTableFilter($event)\">\n <ng-template *ngIf=\"captionTemplate || captionComponent || descriptor?.title\" pTemplate=\"caption\">\n <ng-container *ngIf=\"captionTemplate; else componentOrDefaultCaption\">\n <ng-container *ngTemplateOutlet=\"captionTemplate\"></ng-container>\n </ng-container>\n <ng-template #componentOrDefaultCaption>\n <div *ngIf=\"captionComponent; else defaultCaption\" [mngComponent]=\"captionComponent\" (instanceCreated)=\"onCaptionCmpInst($event)\"></div>\n <ng-template #defaultCaption>\n <h5 class=\"p-0 m-0\">{{ descriptor?.title }}</h5>\n </ng-template>\n </ng-template>\n </ng-template>\n\n <ng-template pTemplate=\"header\">\n <tr *ngIf=\"!descriptor?.hideHeader\" class=\"mng-table-header\" [class]=\"descriptor?.headerClassName\">\n <th *ngIf=\"selectionEnabled && selectionMode === 'multiple'\" style=\"min-width: 36px\" pFrozenColumn>\n <p-tableHeaderCheckbox></p-tableHeaderCheckbox>\n </th>\n <!-- We need the line below, because otherwise p-tableRadioButton shifts the rest of the columns in table -->\n <th *ngIf=\"selectionEnabled && selectionMode === 'single'\" style=\"min-width: 36px\" pFrozenColumn></th>\n <ng-container *ngFor=\"let col of descriptor?.columns\">\n <th\n *ngIf=\"col.isSortEnabled\"\n [pSortableColumn]=\"col.property\"\n [style.width.%]=\"col.width\"\n [style.min-width.px]=\"col.minWidth\"\n [style.max-width.px]=\"col.maxWidth\"\n [class]=\"\n col.headerClassName +\n (descriptor?.filterDisplay === filterDisplayRow && hasColumnFilters && col.filterDescriptor\n ? ' mng-column-filter-' + col.filterDescriptor.filterType\n : '')\n \">\n <div class=\"flex justify-content-between align-items-center\">\n {{ col.title ?? (col.property | i18nProperty: descriptor!.model) | translate }}\n <p-sortIcon [field]=\"col.property\"></p-sortIcon>\n <mng-table-column-filter\n *ngIf=\"col.filterDescriptor && descriptor!.filterDisplay === filterDisplayMenu\"\n class=\"ml-auto\"\n [display]=\"descriptor!.filterDisplay\"\n [descriptor]=\"col.filterDescriptor\">\n </mng-table-column-filter>\n </div>\n </th>\n <th\n *ngIf=\"!col.isSortEnabled\"\n [style.width.%]=\"col.width\"\n [style.min-width.px]=\"col.minWidth\"\n [style.max-width.px]=\"col.maxWidth\"\n [class]=\"\n col.headerClassName +\n (descriptor?.filterDisplay === filterDisplayRow && hasColumnFilters && col.filterDescriptor\n ? ' mng-column-filter-' + col.filterDescriptor.filterType\n : '')\n \">\n {{ col.title ?? (col.property | i18nProperty: descriptor!.model) | translate }}\n <ng-container>\n <mng-table-column-filter\n *ngIf=\"col.filterDescriptor && descriptor!.filterDisplay === filterDisplayMenu\"\n class=\"ml-auto\"\n [display]=\"descriptor!.filterDisplay\"\n [descriptor]=\"col.filterDescriptor\">\n </mng-table-column-filter>\n </ng-container>\n </th>\n </ng-container>\n <th *ngIf=\"showInlineActionsColumn\" [style.min-width.px]=\"columnActionMinWidth\" pFrozenColumn></th>\n </tr>\n <tr *ngIf=\"descriptor?.filterDisplay === filterDisplayRow && hasColumnFilters\" class=\"mng-column-filter-row\">\n <!-- We need the line below, because otherwise p-tableRadioButton shifts the rest of the columns in table -->\n <th *ngIf=\"selectionEnabled && selectionMode === 'single'\" style=\"min-width: 36px\" pFrozenColumn></th>\n <th\n *ngFor=\"let col of descriptor?.columns\"\n [class]=\"(col.filterDescriptor ? 'mng-column-filter-' + col.filterDescriptor.filterType + ' ' : ' ') + col.filterDescriptor?.columnClassName\"\n [style.width.%]=\"col.filterDescriptor?.columnWidth ?? col.width\"\n [style.min-width.px]=\"col.filterDescriptor?.columnMinWidth ?? col.minWidth\"\n [style.max-width.px]=\"col.maxWidth\">\n <div class=\"flex\" *ngIf=\"col.filterDescriptor\">\n <mng-table-column-filter [display]=\"descriptor!.filterDisplay\" [descriptor]=\"col.filterDescriptor\"></mng-table-column-filter>\n </div>\n </th>\n <th *ngIf=\"showInlineActionsColumn\" [style.min-width.px]=\"columnActionMinWidth\" pFrozenColumn></th>\n </tr>\n </ng-template>\n\n <ng-template pTemplate=\"body\" let-item let-idx=\"rowIndex\">\n <tr [style.height.px]=\"rowHeight\" [class]=\"descriptor?.rowClassName | mngClassMapPipe: descriptor?.rowClassNameMapFn:item\">\n <td *ngIf=\"selectionEnabled && selectionMode === 'multiple'\" style=\"min-width: 36px\" pFrozenColumn>\n <p-tableCheckbox [value]=\"item\"></p-tableCheckbox>\n </td>\n <td *ngIf=\"selectionEnabled && selectionMode === 'single'\" style=\"min-width: 36px\" pFrozenColumn>\n <p-tableRadioButton [value]=\"item\"></p-tableRadioButton>\n </td>\n <td\n *ngFor=\"let col of descriptor?.columns\"\n (click)=\"onCellClick($event, col, item, idx)\"\n [class]=\"\n col.className +\n (descriptor?.filterDisplay === filterDisplayRow && hasColumnFilters && col.filterDescriptor ? ' mng-column-filter-' + col.filterDescriptor.filterType : '')\n \"\n [class.clickable]=\"isColumnClickable\"\n [style.width.%]=\"col.width\"\n [style.min-width.px]=\"col.minWidth\"\n [style.max-width.px]=\"col.maxWidth\">\n <span class=\"p-column-title\">{{ col.title ?? (col.property | i18nProperty: descriptor!.model) | translate }}</span>\n <mng-table-column-value [descriptor]=\"col\" [item]=\"item\"></mng-table-column-value>\n </td>\n <td\n *ngIf=\"showInlineActionsColumn\"\n class=\"column-action justify-content-end text-right\"\n [style.min-width.px]=\"columnActionMinWidth\"\n pFrozenColumn\n alignFrozen=\"right\">\n <ng-container *ngIf=\"columnActionTemplate; else showColumnActionComponentOrDefault\">\n <ng-container *ngTemplateOutlet=\"columnActionTemplate; context: {rowItem: item, rowIndex: idx}\"></ng-container>\n </ng-container>\n <ng-template #showColumnActionComponentOrDefault>\n <span\n *ngIf=\"columnActionComponent; else defaultColumnActions\"\n [mngComponent]=\"columnActionComponent!\"\n (instanceCreated)=\"onColumnActionCmpInst($event)\"></span>\n </ng-template>\n <ng-template #defaultColumnActions>\n <mng-action\n *ngFor=\"let action of rowInlineActions\"\n [action]=\"action\"\n [item]=\"item\"\n [itemId]=\"descriptor?.model?.idPropertyName ? item[descriptor!.model!.idPropertyName!] : null\"\n [actionData]=\"{itemIndex: idx}\"\n (finish)=\"onActionFinish($event)\">\n </mng-action>\n </ng-template>\n </td>\n </tr>\n </ng-template>\n\n <ng-template pTemplate=\"loadingbody\">\n <tr [style.height.px]=\"rowHeight\">\n <td [attr.colspan]=\"(descriptor?.columns?.length ?? 0) + (showInlineActionsColumn ? 1 : 0) + (selectionEnabled ? 1 : 0)\">\n <div class=\"loading-text\"></div>\n <p-skeleton [ngStyle]=\"{width: '100%'}\"></p-skeleton>\n </td>\n </tr>\n </ng-template>\n\n <ng-template pTemplate=\"emptymessage\">\n <tr [style.height.px]=\"rowHeight\">\n <td [attr.colspan]=\"(descriptor?.columns?.length ?? 0) + (showInlineActionsColumn ? 1 : 0) + (selectionEnabled ? 1 : 0)\">\n {{ 'mngTable.noItems' | translate }}\n </td>\n </tr>\n </ng-template>\n\n <ng-template *ngIf=\"footerTemplate\" pTemplate=\"summary\">\n <ng-container [ngTemplateOutlet]=\"footerTemplate\" [ngTemplateOutletContext]=\"{queryResult: queryResult}\"></ng-container>\n </ng-template>\n </p-table>\n</div>\n" }]
503
- }], ctorParameters: function () { return [{ type: i0.Injector }, { type: i1.Router }, { type: i1.ActivatedRoute }, { type: i2.TranslateService }, { type: i3.MngActionExecutorService }, { type: i3.MngViewContainerComponentService, decorators: [{
504
- type: Optional
505
- }] }]; }, propDecorators: { initialDescriptor: [{
506
- type: Input,
507
- args: ['descriptor']
508
- }], items: [{
509
- type: Input
510
- }], queryResult: [{
511
- type: Input
512
- }], loading: [{
513
- type: Input
514
- }], dataProvider: [{
515
- type: Input
516
- }], useQueryParams: [{
517
- type: Input
518
- }], selectionMode: [{
519
- type: Input
520
- }], selectionEnabled: [{
521
- type: Input
522
- }], actions: [{
523
- type: Input
524
- }], isColumnClickable: [{
525
- type: Input
526
- }], viewContainerInit: [{
527
- type: Input,
528
- args: ['viewContainer']
529
- }], captionComponent: [{
530
- type: Input
531
- }], columnActionComponent: [{
532
- type: Input
533
- }], columnActionMinWidth: [{
534
- type: Input
535
- }], loadEventEmitter: [{
536
- type: Output,
537
- args: ['tableLoad']
538
- }], cellClickEventEmitter: [{
539
- type: Output,
540
- args: ['cellClick']
541
- }], selectionChangeEventEmitter: [{
542
- type: Output,
543
- args: ['selectionChange']
544
- }], captionCmpInstEventEmitter: [{
545
- type: Output,
546
- args: ['captionComponentInstance']
547
- }], columnActionCmpInstEventEmitter: [{
548
- type: Output,
549
- args: ['columnActionComponentInstance']
550
- }], templates: [{
551
- type: ContentChildren,
552
- args: [MngTemplateDirective]
553
- }], components: [{
554
- type: ViewChildren,
555
- args: [MngComponentDirective]
556
- }], primeTable: [{
557
- type: ViewChild,
558
- args: [Table]
559
- }] } });
1
+ import { ChangeDetectionStrategy, Component, ContentChildren, EventEmitter, Input, Optional, Output, ViewChild, ViewChildren } from '@angular/core';
2
+ import { FilterMatchMode } from 'primeng/api';
3
+ import { Table } from 'primeng/table';
4
+ import { BehaviorSubject, Observable, ReplaySubject, isObservable, of } from 'rxjs';
5
+ import { map } from 'rxjs/operators';
6
+ import { MediusFilterMatchType, MediusQueryParam, MediusQueryParamBuilder, MediusQueryResult } from '../../../api/models';
7
+ import { MediusRestUtil } from '../../../api/utils';
8
+ import { TableDynamicDescriptor } from '../../../descriptors';
9
+ import { ActionPositionEnum, FilterTypeEnum, TableFilterDisplayEnum, TablePaginationModeEnum, TableSizeEnum } from '../../../descriptors/types';
10
+ import { MngComponentDirective, MngTemplateDirective } from '../../../directives';
11
+ import { StylesUtil } from '../../../styles';
12
+ import { NotificationUtil } from '../../../utils';
13
+ import { MngTableCellClickEvent, MngTableLoadEvent } from '../models';
14
+ import * as i0 from "@angular/core";
15
+ import * as i1 from "@angular/router";
16
+ import * as i2 from "@ngx-translate/core";
17
+ import * as i3 from "../../../services";
18
+ import * as i4 from "@angular/common";
19
+ import * as i5 from "primeng/api";
20
+ import * as i6 from "primeng/table";
21
+ import * as i7 from "primeng/skeleton";
22
+ import * as i8 from "../../../directives/component.directive";
23
+ import * as i9 from "./column-value/column-value.component";
24
+ import * as i10 from "./column-filter/column-filter.component";
25
+ import * as i11 from "../../action/action.component";
26
+ import * as i12 from "../../../pipes/i18n-property.pipe";
27
+ import * as i13 from "../../../pipes/class-map.pipe";
28
+ export class MngTableComponent {
29
+ constructor(injector, router, route, translate, actionExecutor, viewContainerService) {
30
+ this.injector = injector;
31
+ this.router = router;
32
+ this.route = route;
33
+ this.translate = translate;
34
+ this.actionExecutor = actionExecutor;
35
+ this.viewContainerService = viewContainerService;
36
+ this.filterDisplayRow = TableFilterDisplayEnum.Row;
37
+ this.filterDisplayMenu = TableFilterDisplayEnum.Menu;
38
+ this.useQueryParams = false;
39
+ // extra features input
40
+ this.selectionMode = 'multiple';
41
+ this.selectionEnabled = false;
42
+ // actions
43
+ this.actions = [];
44
+ this.columnActionMinWidth = null;
45
+ // event outputs
46
+ this.loadEventEmitter = new EventEmitter();
47
+ this.cellClickEventEmitter = new EventEmitter();
48
+ this.selectionChangeEventEmitter = new EventEmitter();
49
+ this.captionCmpInstEventEmitter = new EventEmitter();
50
+ this.columnActionCmpInstEventEmitter = new EventEmitter();
51
+ // data provider and items
52
+ this.isLazy = false;
53
+ this.isPagination = false;
54
+ this.useDataProvider = false;
55
+ this.useQueryParamsInitializedSubejct = new BehaviorSubject(false);
56
+ this.useQueryParamsInitialized$ = this.useQueryParamsInitializedSubejct.asObservable();
57
+ this.dataProviderInfiniteScrollItems = [];
58
+ this.itemsSubject = new ReplaySubject(1);
59
+ this.offset = 0;
60
+ this.multiSortMeta = null;
61
+ this.filterMetadata = {};
62
+ // infinite scroll
63
+ this.infiniteScroll = false;
64
+ this.tableFullHeightOffset = null;
65
+ this.rowHeight = null;
66
+ // selection
67
+ this.selection = [];
68
+ // data provider
69
+ this.dataProviderService = null;
70
+ this.dataProviderQueryResultSubject = new ReplaySubject(1);
71
+ this.dataProviderLoadingSubject = new ReplaySubject(1);
72
+ this.dataProviderLatestLazyLoadEventVersion = 0;
73
+ this.dataProviderLatestQueryParamVersion = 0;
74
+ // filter, sort
75
+ this.hasColumnFilters = false;
76
+ this.isFilterChanged = false;
77
+ this.isSortChanged = false;
78
+ this.filterDescriptors = [];
79
+ // actions
80
+ this.showInlineActionsColumn = false;
81
+ this.rowClickActions = [];
82
+ this.rowInlineActions = [];
83
+ this.subscriptions = [];
84
+ }
85
+ ngOnInit() {
86
+ this.viewContainer = this.viewContainerInit ?? this.viewContainerService ?? undefined;
87
+ if (!(this.initialDescriptor instanceof TableDynamicDescriptor)) {
88
+ this.descriptor = this.initialDescriptor;
89
+ }
90
+ // map row settings
91
+ this.filterDescriptors = this.descriptor?.columns.filter(c => typeof c.filterDescriptor !== 'undefined').map(c => c.filterDescriptor) ?? [];
92
+ this.hasColumnFilters = this.filterDescriptors.length > 0;
93
+ this.rows = this.descriptor?.defaultNumRows ?? 25;
94
+ this.rowsPerPageOptions = this.descriptor?.rowsPerPageOptions ?? [25, 50, 100];
95
+ // process actions
96
+ for (const action of this.actions) {
97
+ switch (action.position) {
98
+ case ActionPositionEnum.RowClick:
99
+ this.rowClickActions.push(action);
100
+ break;
101
+ case ActionPositionEnum.RowInline:
102
+ this.rowInlineActions.push(action);
103
+ break;
104
+ }
105
+ }
106
+ this.showInlineActionsColumn = typeof this.columnActionComponent !== 'undefined' || this.rowInlineActions.length > 0;
107
+ // define all styles
108
+ this.className = this.descriptor?.className ?? '';
109
+ this.tableFullHeightOffset = this.descriptor?.tableFullHeightOffset ?? null;
110
+ this.rowHeight = this.descriptor?.rowHeight ?? null;
111
+ if (typeof this.isColumnClickable === 'undefined') {
112
+ // define if cell click is being observed via output
113
+ this.isColumnClickable = this.rowClickActions.length > 0 || this.cellClickEventEmitter.observed;
114
+ }
115
+ switch (this.descriptor?.size) {
116
+ case TableSizeEnum.Small:
117
+ this.className += ' p-datatable-sm';
118
+ break;
119
+ case TableSizeEnum.Large:
120
+ this.className += ' p-datatable-lg';
121
+ break;
122
+ }
123
+ if (this.descriptor?.hasGridlines) {
124
+ this.className += ' p-datatable-gridlines';
125
+ }
126
+ if (this.descriptor && !this.columnActionMinWidth) {
127
+ this.columnActionMinWidth = StylesUtil.calculateTableColumnActionWidth(this.descriptor, this.rowInlineActions);
128
+ }
129
+ // check if infinite scroll
130
+ if (this.descriptor?.paginationMode === TablePaginationModeEnum.InfiniteScroll) {
131
+ this.infiniteScroll = true;
132
+ this.tableFullHeightOffset = this.descriptor.tableFullHeightOffset ?? 315;
133
+ this.rowHeight = this.descriptor.rowHeight ?? 45;
134
+ this.useQueryParams = false;
135
+ }
136
+ else if (this.descriptor?.paginationMode === TablePaginationModeEnum.Pagination) {
137
+ this.isPagination = true;
138
+ }
139
+ // check if data provider is supplied, if is, use it primarily
140
+ if (this.dataProvider) {
141
+ // map subjects to observables and initiate data
142
+ this.useDataProvider = true;
143
+ this.isLazy = this.dataProvider.isLazy;
144
+ this.queryResult$ = this.dataProviderQueryResultSubject.asObservable();
145
+ this.loading$ = this.dataProviderLoadingSubject.asObservable();
146
+ const emptyQueryResult = new MediusQueryResult();
147
+ emptyQueryResult.pageData = [];
148
+ emptyQueryResult.allDataCount = 0;
149
+ this.dataProviderLoadingSubject.next(false);
150
+ this.dataProviderQueryResultSubject.next(emptyQueryResult);
151
+ // inject service
152
+ if (this.dataProvider.serviceType) {
153
+ this.dataProviderService = this.injector.get(this.dataProvider.serviceType);
154
+ }
155
+ const reloadSubscription = this.dataProvider.getAllReload$.subscribe({
156
+ next: () => {
157
+ this.reload();
158
+ }
159
+ });
160
+ this.subscriptions.push(reloadSubscription);
161
+ }
162
+ else {
163
+ // if query result is provided, use it as secondary source or else try to use items
164
+ if (this.queryResult) {
165
+ this.queryResult$ = this.queryResult instanceof Observable ? this.queryResult : of(this.queryResult);
166
+ }
167
+ else {
168
+ this.queryResult$ = (isObservable(this.items) ? this.items : this.itemsSubject.asObservable()).pipe(
169
+ // distinctUntilChanged((v1, v2) => v1.length === v2.length &&
170
+ // v1.every((v1i, idx) => v1i[this.descriptor.dataKeyProperty] === v2[idx][this.descriptor.dataKeyProperty])),
171
+ map(items => {
172
+ const queryResult = new MediusQueryResult();
173
+ queryResult.pageData = items;
174
+ queryResult.allDataCount = items.length;
175
+ return queryResult;
176
+ }));
177
+ if (!isObservable(this.items)) {
178
+ this.itemsSubject.next(this.items ?? []);
179
+ }
180
+ }
181
+ if (typeof this.loading !== 'undefined') {
182
+ this.loading$ = this.loading instanceof Observable ? this.loading : of(this.loading);
183
+ }
184
+ }
185
+ const initialQueryParamMap = this.route.snapshot.queryParamMap;
186
+ if (this.useQueryParams &&
187
+ ((!initialQueryParamMap.has('sort') && this.descriptor?.hasDefaultSort) ||
188
+ (!initialQueryParamMap.has('filter') && this.filterDescriptors.some(fd => fd.hasDefaultValue)))) {
189
+ // default sort/filters are applied, no additional filtering/sorting is specified in query param
190
+ // redirect must be done at first step
191
+ const mediusQueryParam = MediusRestUtil.fromAngularQueryParamsToMediusQueryParams(this.route.snapshot.queryParams, this.filterDescriptors, this.rowsPerPageOptions[0]);
192
+ const event = {};
193
+ event.multiSortMeta = this.createSortMeta(mediusQueryParam);
194
+ event.filters = this.createFilterMeta(mediusQueryParam);
195
+ // first navigate to correct url with default filters/sorts
196
+ this.router
197
+ .navigate([], {
198
+ relativeTo: this.route,
199
+ replaceUrl: true,
200
+ queryParams: MediusRestUtil.fromPrimeLazyLoadEventToAngularQueryParams(event, this.rowsPerPageOptions[0])
201
+ })
202
+ .then(() => {
203
+ this.initializeDataLoadingTriggers();
204
+ });
205
+ }
206
+ else {
207
+ this.initializeDataLoadingTriggers();
208
+ }
209
+ this.queryResultSubscription = this.queryResult$.subscribe(e => (this.queryResult = e));
210
+ }
211
+ ngAfterContentInit() {
212
+ this.templates.forEach(template => {
213
+ switch (template.getType()) {
214
+ case 'caption':
215
+ this.captionTemplate = template.template;
216
+ break;
217
+ case 'columnAction':
218
+ this.columnActionTemplate = template.template;
219
+ if (!this.showInlineActionsColumn) {
220
+ this.showInlineActionsColumn = true;
221
+ }
222
+ break;
223
+ case 'footer':
224
+ this.footerTemplate = template.template;
225
+ break;
226
+ }
227
+ });
228
+ }
229
+ ngOnChanges(changes) {
230
+ if (changes['items'] && !changes['items'].firstChange && Array.isArray(changes['items'].currentValue)) {
231
+ this.itemsSubject.next(changes['items'].currentValue);
232
+ }
233
+ }
234
+ ngOnDestroy() {
235
+ this.dataProviderSubscription?.unsubscribe();
236
+ this.queryResultSubscription?.unsubscribe();
237
+ this.subscriptions.forEach(s => s.unsubscribe());
238
+ }
239
+ reload(emitEvent = false, resetParams = false) {
240
+ const queryParamsBuilder = resetParams
241
+ ? MediusQueryParamBuilder.create(this.rowsPerPageOptions[0], 0)
242
+ : MediusQueryParamBuilder.createFromExisting(this.dataProviderLatestQueryParam ?? new MediusQueryParam())
243
+ .withItemsPerPage(this.rows)
244
+ .withItemsOffset(this.offset);
245
+ this.loadTableWithDataProvider(queryParamsBuilder.build(), emitEvent);
246
+ }
247
+ onTableLazyLoad(event) {
248
+ this.dataProviderLatestLazyLoadEvent = event;
249
+ this.dataProviderLatestLazyLoadEventVersion++;
250
+ if (this.useQueryParams) {
251
+ if (!event.multiSortMeta || event.multiSortMeta.length === 0) {
252
+ // add default sort meta to event if not multisort meta is present
253
+ event.multiSortMeta = this.createSortMeta();
254
+ }
255
+ if (!event.filters) {
256
+ event.filters = this.createFilterMeta();
257
+ }
258
+ this.router.navigate([], {
259
+ relativeTo: this.route,
260
+ replaceUrl: true,
261
+ queryParams: MediusRestUtil.fromPrimeLazyLoadEventToAngularQueryParams(event, this.rowsPerPageOptions[0])
262
+ });
263
+ }
264
+ else {
265
+ const mediusQueryParams = event ? MediusRestUtil.fromPrimeLazyLoadEventToMediusQueryParams(event) : new MediusQueryParam();
266
+ this.loadTableWithDataProvider(mediusQueryParams);
267
+ }
268
+ }
269
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
270
+ onTableSort(event) {
271
+ this.isSortChanged = true;
272
+ }
273
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
274
+ onTableFilter(event) {
275
+ this.isFilterChanged = true;
276
+ }
277
+ onCellClick(event, col, item, idx) {
278
+ const mngEvent = new MngTableCellClickEvent(col, item, idx);
279
+ this.cellClickEventEmitter.next(mngEvent);
280
+ if (this.rowClickActions.length) {
281
+ for (const action of this.rowClickActions) {
282
+ this.actionExecutor.triggerRowClickAction(action, mngEvent, this.route, this.descriptor);
283
+ }
284
+ }
285
+ }
286
+ onSelectionChange(event) {
287
+ this.selectionChangeEventEmitter.emit(event);
288
+ }
289
+ onCaptionCmpInst(instance) {
290
+ this.captionCmpInstEventEmitter.next(instance);
291
+ }
292
+ onColumnActionCmpInst(instance) {
293
+ this.columnActionCmpInstEventEmitter.next(instance);
294
+ }
295
+ onActionFinish(runResult) {
296
+ if (!runResult.error) {
297
+ this.reload();
298
+ }
299
+ }
300
+ loadTableWithDataProvider(queryParam = null, emitEvent = true) {
301
+ if (!this.useDataProvider) {
302
+ return;
303
+ }
304
+ this.dataProviderSubscription?.unsubscribe();
305
+ this.dataProviderLoadingSubject.next(true);
306
+ if (!queryParam) {
307
+ queryParam = MediusQueryParamBuilder.create(this.rowsPerPageOptions[0]).build();
308
+ }
309
+ this.dataProviderLatestQueryParam = queryParam;
310
+ this.dataProviderLatestQueryParamVersion++;
311
+ MediusRestUtil.modifyFilterProperties(queryParam, this.filterDescriptors);
312
+ this.dataProviderSubscription = this.dataProvider?.getAll(queryParam, this.dataProviderService).subscribe({
313
+ next: res => {
314
+ if (this.initialDescriptor instanceof TableDynamicDescriptor) {
315
+ this.descriptor = this.initialDescriptor.toTableDescriptorFromData(res);
316
+ this.filterDescriptors = this.descriptor.columns.filter(c => typeof c.filterDescriptor !== 'undefined').map(c => c.filterDescriptor);
317
+ this.hasColumnFilters = this.filterDescriptors.length > 0;
318
+ // } else {
319
+ // this.descriptor = this.initialDescriptor.onDataReceivedTypeBuilding(res);
320
+ }
321
+ if (this.infiniteScroll) {
322
+ if (this.isFilterChanged || this.isSortChanged) {
323
+ this.dataProviderInfiniteScrollItems = [];
324
+ }
325
+ this.dataProviderInfiniteScrollItems.splice(queryParam.itemsOffset ?? 0, queryParam.itemsPerPage ?? this.rows, ...(res.pageData ?? []));
326
+ this.dataProviderInfiniteScrollItems = [...this.dataProviderInfiniteScrollItems];
327
+ }
328
+ else {
329
+ this.dataProviderQueryResultSubject.next(res);
330
+ }
331
+ this.isFilterChanged = false;
332
+ this.isSortChanged = false;
333
+ this.dataProviderLoadingSubject.next(false);
334
+ },
335
+ error: err => {
336
+ // TODO: check what happens on error with no model iniside descriptor
337
+ NotificationUtil.tableNotificationError(this.translate, this.descriptor, err, this.viewContainer);
338
+ const emptyQueryResult = new MediusQueryResult();
339
+ emptyQueryResult.pageData = [];
340
+ emptyQueryResult.allDataCount = 0;
341
+ this.dataProviderQueryResultSubject.next(emptyQueryResult);
342
+ this.dataProviderLoadingSubject.next(false);
343
+ }
344
+ });
345
+ if (emitEvent) {
346
+ const mngEvent = new MngTableLoadEvent();
347
+ mngEvent.originalEvent = this.dataProviderLatestLazyLoadEvent ?? undefined;
348
+ mngEvent.queryParam = queryParam;
349
+ this.loadEventEmitter.next(mngEvent);
350
+ }
351
+ }
352
+ loadTableFromRouteUpdate(params) {
353
+ const mediusQueryParam = MediusRestUtil.fromAngularQueryParamsToMediusQueryParams(params, this.filterDescriptors, this.rowsPerPageOptions[0]);
354
+ if (this.dataProviderLatestLazyLoadEventVersion < this.dataProviderLatestQueryParamVersion + 1) {
355
+ // update only if new version from query params will be higher
356
+ this.updatePrimeSortAndFilter(mediusQueryParam);
357
+ }
358
+ this.useQueryParamsInitializedSubejct.next(true);
359
+ this.loadTableWithDataProvider(mediusQueryParam);
360
+ }
361
+ updatePrimeSortAndFilter(mediusQueryParam) {
362
+ this.multiSortMeta = this.createSortMeta(mediusQueryParam);
363
+ this.filterMetadata = this.createFilterMeta(mediusQueryParam);
364
+ this.rows = mediusQueryParam?.itemsPerPage ?? this.rowsPerPageOptions[0];
365
+ this.offset = mediusQueryParam?.itemsOffset ?? 0;
366
+ }
367
+ createFilterMeta(mediusQueryParam) {
368
+ let params;
369
+ if (!mediusQueryParam) {
370
+ params = new MediusQueryParam();
371
+ }
372
+ else {
373
+ params = mediusQueryParam;
374
+ }
375
+ const primeFilterMeta = {};
376
+ // if any filter is present, no default filters should be applied!
377
+ const applyDefaultFilters = (params.filterParams?.length ?? 0) === 0;
378
+ this.filterDescriptors.forEach(f => {
379
+ let matchMode;
380
+ if (f.defaultFilterMatchMode) {
381
+ matchMode = f.defaultFilterMatchMode;
382
+ }
383
+ else {
384
+ switch (f.filterType) {
385
+ case FilterTypeEnum.String:
386
+ matchMode = FilterMatchMode.CONTAINS;
387
+ break;
388
+ case FilterTypeEnum.Date:
389
+ matchMode = FilterMatchMode.DATE_IS;
390
+ break;
391
+ case FilterTypeEnum.Lookup:
392
+ case FilterTypeEnum.LookupEnum: {
393
+ const lookupFilter = f;
394
+ if (lookupFilter.multiselect) {
395
+ matchMode = FilterMatchMode.IN;
396
+ }
397
+ else {
398
+ matchMode = FilterMatchMode.EQUALS;
399
+ }
400
+ break;
401
+ }
402
+ default:
403
+ matchMode = FilterMatchMode.EQUALS;
404
+ break;
405
+ }
406
+ }
407
+ let value = null;
408
+ if (applyDefaultFilters) {
409
+ if (f.defaultValueTo && f.defaultValue) {
410
+ value = [f.defaultValue, f.defaultValueTo];
411
+ }
412
+ else if (f.defaultValue) {
413
+ value = f.defaultValue;
414
+ }
415
+ }
416
+ primeFilterMeta[f.property] = {
417
+ value: value,
418
+ matchMode: matchMode
419
+ };
420
+ });
421
+ params.filterParams?.forEach(f => {
422
+ const descriptor = this.filterDescriptors.find(fd => fd.filterProperty === f.property || fd.property === f.property);
423
+ const matchMode = f.filterMatchType && descriptor ? MediusRestUtil.getMapping(f.filterMatchType, descriptor.filterType, 2)?.[0] : MediusFilterMatchType.Equals;
424
+ if (descriptor && matchMode) {
425
+ let filterValue = f.filterValue;
426
+ if (descriptor.filterType === FilterTypeEnum.Date && typeof filterValue !== 'undefined') {
427
+ if (typeof filterValue === 'string' || typeof filterValue === 'number') {
428
+ filterValue = new Date(filterValue);
429
+ }
430
+ // if range is provided, take that into account
431
+ if (typeof f.filterValueTo === 'string' || typeof f.filterValueTo === 'number') {
432
+ const filterValueTo = new Date(f.filterValueTo);
433
+ filterValue = [filterValue, filterValueTo];
434
+ }
435
+ }
436
+ primeFilterMeta[descriptor.property] = {
437
+ value: filterValue,
438
+ matchMode: matchMode
439
+ };
440
+ }
441
+ });
442
+ return primeFilterMeta;
443
+ }
444
+ createSortMeta(mediusQueryParam) {
445
+ let params;
446
+ if (!mediusQueryParam) {
447
+ params = new MediusQueryParam();
448
+ }
449
+ else {
450
+ params = mediusQueryParam;
451
+ }
452
+ let sortMeta;
453
+ const applyDefaultSorts = (params.sortProperty?.length ?? 0) === 0;
454
+ if (applyDefaultSorts && this.descriptor?.hasDefaultSort) {
455
+ sortMeta = this.descriptor.defaultSortProperty.map((p, idx) => ({
456
+ field: p,
457
+ order: this.descriptor.defaultSortAsc[idx] ? 1 : -1
458
+ }));
459
+ }
460
+ else {
461
+ sortMeta = [];
462
+ }
463
+ params.sortProperty?.forEach((s, idx) => {
464
+ const existingIndex = sortMeta.findIndex(value => value.field === s);
465
+ if (existingIndex > -1) {
466
+ sortMeta[existingIndex].order = params.sortAsc?.[idx] ?? true ? 1 : -1;
467
+ }
468
+ else {
469
+ sortMeta.push({
470
+ field: s,
471
+ order: params.sortAsc?.[idx] ?? true ? 1 : -1
472
+ });
473
+ }
474
+ });
475
+ return sortMeta;
476
+ }
477
+ initializeDataLoadingTriggers() {
478
+ if (this.useQueryParams) {
479
+ // trigger table loads from route updates
480
+ const subscription = this.route.queryParams.subscribe(qp => {
481
+ this.loadTableFromRouteUpdate(qp);
482
+ });
483
+ this.subscriptions.push(subscription);
484
+ }
485
+ else {
486
+ // load data immediately by creating default sorts and filters (primeng will trigger onLazyLoad event on sort&filter metadata change)
487
+ const defaultSort = this.createSortMeta();
488
+ if (defaultSort.length > 0) {
489
+ this.multiSortMeta = defaultSort;
490
+ }
491
+ const defaultFilter = this.createFilterMeta();
492
+ if (defaultFilter) {
493
+ this.filterMetadata = defaultFilter;
494
+ }
495
+ }
496
+ }
497
+ }
498
+ MngTableComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.1.0", ngImport: i0, type: MngTableComponent, deps: [{ token: i0.Injector }, { token: i1.Router }, { token: i1.ActivatedRoute }, { token: i2.TranslateService }, { token: i3.MngActionExecutorService }, { token: i3.MngViewContainerComponentService, optional: true }], target: i0.ɵɵFactoryTarget.Component });
499
+ MngTableComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.1.0", type: MngTableComponent, selector: "mng-table", inputs: { initialDescriptor: ["descriptor", "initialDescriptor"], items: "items", queryResult: "queryResult", loading: "loading", dataProvider: "dataProvider", useQueryParams: "useQueryParams", selectionMode: "selectionMode", selectionEnabled: "selectionEnabled", actions: "actions", isColumnClickable: "isColumnClickable", viewContainerInit: ["viewContainer", "viewContainerInit"], captionComponent: "captionComponent", columnActionComponent: "columnActionComponent", columnActionMinWidth: "columnActionMinWidth" }, outputs: { loadEventEmitter: "tableLoad", cellClickEventEmitter: "cellClick", selectionChangeEventEmitter: "selectionChange", captionCmpInstEventEmitter: "captionComponentInstance", columnActionCmpInstEventEmitter: "columnActionComponentInstance" }, queries: [{ propertyName: "templates", predicate: MngTemplateDirective }], viewQueries: [{ propertyName: "primeTable", first: true, predicate: Table, descendants: true }, { propertyName: "components", predicate: MngComponentDirective, descendants: true }], usesOnChanges: true, ngImport: i0, template: "<div [style.height]=\"tableFullHeightOffset ? 'calc(100vh - ' + tableFullHeightOffset + 'px)' : null\">\n <!-- MUST NOT use observable for value when using virtual scroll - does not work for some reason -->\n <p-table\n *ngIf=\"!useQueryParams || (useQueryParamsInitialized$ | async)\"\n [value]=\"infiniteScroll ? dataProviderInfiniteScrollItems : (queryResult$ | async)?.pageData ?? []\"\n [dataKey]=\"$any(descriptor?.dataKeyProperty ?? null)\"\n [lazy]=\"isLazy\"\n [loading]=\"(loading$ | async) ?? false\"\n [paginator]=\"isPagination && !infiniteScroll\"\n [rows]=\"$any(infiniteScroll ? 20 : rows)\"\n [first]=\"$any(infiniteScroll ? 0 : offset)\"\n [totalRecords]=\"$any(infiniteScroll ? null : (queryResult$ | async)?.allDataCount ?? 0)\"\n [rowsPerPageOptions]=\"$any(infiniteScroll ? null : rowsPerPageOptions)\"\n [showCurrentPageReport]=\"!infiniteScroll\"\n [currentPageReportTemplate]=\"'mngTable.paginationMsg' | translate\"\n [multiSortMeta]=\"$any(multiSortMeta)\"\n [filters]=\"filterMetadata\"\n sortMode=\"multiple\"\n [(selection)]=\"selection\"\n (selectionChange)=\"onSelectionChange($event)\"\n [selectionMode]=\"$any(selectionEnabled ? selectionMode : null)\"\n [scrollable]=\"true\"\n [virtualScroll]=\"infiniteScroll\"\n [virtualScrollItemSize]=\"$any(rowHeight)\"\n scrollHeight=\"flex\"\n [rowHover]=\"descriptor?.hasHover ?? true\"\n [styleClass]=\"className\"\n (onLazyLoad)=\"onTableLazyLoad($event)\"\n (onSort)=\"onTableSort($event)\"\n (onFilter)=\"onTableFilter($event)\">\n <ng-template *ngIf=\"captionTemplate || captionComponent || descriptor?.title\" pTemplate=\"caption\">\n <ng-container *ngIf=\"captionTemplate; else componentOrDefaultCaption\">\n <ng-container *ngTemplateOutlet=\"captionTemplate\"></ng-container>\n </ng-container>\n <ng-template #componentOrDefaultCaption>\n <div *ngIf=\"captionComponent; else defaultCaption\" [mngComponent]=\"captionComponent\" (instanceCreated)=\"onCaptionCmpInst($event)\"></div>\n <ng-template #defaultCaption>\n <h5 class=\"p-0 m-0\">{{ descriptor?.title }}</h5>\n </ng-template>\n </ng-template>\n </ng-template>\n\n <ng-template pTemplate=\"header\">\n <tr *ngIf=\"!descriptor?.hideHeader\" class=\"mng-table-header\" [class]=\"descriptor?.headerClassName\">\n <th *ngIf=\"selectionEnabled && selectionMode === 'multiple'\" style=\"min-width: 36px\" pFrozenColumn>\n <p-tableHeaderCheckbox></p-tableHeaderCheckbox>\n </th>\n <!-- We need the line below, because otherwise p-tableRadioButton shifts the rest of the columns in table -->\n <th *ngIf=\"selectionEnabled && selectionMode === 'single'\" style=\"min-width: 36px\" pFrozenColumn></th>\n <ng-container *ngFor=\"let col of descriptor?.columns\">\n <th\n *ngIf=\"col.isSortEnabled\"\n [pSortableColumn]=\"col.property\"\n [style.width.%]=\"col.width\"\n [style.min-width.px]=\"col.minWidth\"\n [style.max-width.px]=\"col.maxWidth\"\n [class]=\"\n col.headerClassName +\n (descriptor?.filterDisplay === filterDisplayRow && hasColumnFilters && col.filterDescriptor\n ? ' mng-column-filter-' + col.filterDescriptor.filterType\n : '')\n \">\n <div class=\"flex justify-content-between align-items-center\">\n {{ col.title ?? (col.property | i18nProperty: descriptor!.model) | translate }}\n <p-sortIcon [field]=\"col.property\"></p-sortIcon>\n <mng-table-column-filter\n *ngIf=\"col.filterDescriptor && descriptor!.filterDisplay === filterDisplayMenu\"\n class=\"ml-auto\"\n [display]=\"descriptor!.filterDisplay\"\n [descriptor]=\"col.filterDescriptor\">\n </mng-table-column-filter>\n </div>\n </th>\n <th\n *ngIf=\"!col.isSortEnabled\"\n [style.width.%]=\"col.width\"\n [style.min-width.px]=\"col.minWidth\"\n [style.max-width.px]=\"col.maxWidth\"\n [class]=\"\n col.headerClassName +\n (descriptor?.filterDisplay === filterDisplayRow && hasColumnFilters && col.filterDescriptor\n ? ' mng-column-filter-' + col.filterDescriptor.filterType\n : '')\n \">\n {{ col.title ?? (col.property | i18nProperty: descriptor!.model) | translate }}\n <ng-container>\n <mng-table-column-filter\n *ngIf=\"col.filterDescriptor && descriptor!.filterDisplay === filterDisplayMenu\"\n class=\"ml-auto\"\n [display]=\"descriptor!.filterDisplay\"\n [descriptor]=\"col.filterDescriptor\">\n </mng-table-column-filter>\n </ng-container>\n </th>\n </ng-container>\n <th *ngIf=\"showInlineActionsColumn\" [style.min-width.px]=\"columnActionMinWidth\" pFrozenColumn></th>\n </tr>\n <tr *ngIf=\"descriptor?.filterDisplay === filterDisplayRow && hasColumnFilters\" class=\"mng-column-filter-row\">\n <!-- We need the line below, because otherwise p-tableRadioButton shifts the rest of the columns in table -->\n <th *ngIf=\"selectionEnabled && selectionMode === 'single'\" style=\"min-width: 36px\" pFrozenColumn></th>\n <th\n *ngFor=\"let col of descriptor?.columns\"\n [class]=\"(col.filterDescriptor ? 'mng-column-filter-' + col.filterDescriptor.filterType + ' ' : ' ') + col.filterDescriptor?.columnClassName\"\n [style.width.%]=\"col.filterDescriptor?.columnWidth ?? col.width\"\n [style.min-width.px]=\"col.filterDescriptor?.columnMinWidth ?? col.minWidth\"\n [style.max-width.px]=\"col.maxWidth\">\n <div class=\"flex\" *ngIf=\"col.filterDescriptor\">\n <mng-table-column-filter [display]=\"descriptor!.filterDisplay\" [descriptor]=\"col.filterDescriptor\"></mng-table-column-filter>\n </div>\n </th>\n <th *ngIf=\"showInlineActionsColumn\" [style.min-width.px]=\"columnActionMinWidth\" pFrozenColumn></th>\n </tr>\n </ng-template>\n\n <ng-template pTemplate=\"body\" let-item let-idx=\"rowIndex\">\n <tr [style.height.px]=\"rowHeight\" [class]=\"descriptor?.rowClassName | mngClassMapPipe: descriptor?.rowClassNameMapFn:item\">\n <td *ngIf=\"selectionEnabled && selectionMode === 'multiple'\" style=\"min-width: 36px\" pFrozenColumn>\n <p-tableCheckbox [value]=\"item\"></p-tableCheckbox>\n </td>\n <td *ngIf=\"selectionEnabled && selectionMode === 'single'\" style=\"min-width: 36px\" pFrozenColumn>\n <p-tableRadioButton [value]=\"item\"></p-tableRadioButton>\n </td>\n <td\n *ngFor=\"let col of descriptor?.columns\"\n (click)=\"onCellClick($event, col, item, idx)\"\n [class]=\"\n col.className +\n (descriptor?.filterDisplay === filterDisplayRow && hasColumnFilters && col.filterDescriptor ? ' mng-column-filter-' + col.filterDescriptor.filterType : '')\n \"\n [class.clickable]=\"isColumnClickable\"\n [style.width.%]=\"col.width\"\n [style.min-width.px]=\"col.minWidth\"\n [style.max-width.px]=\"col.maxWidth\">\n <span class=\"p-column-title\">{{ col.title ?? (col.property | i18nProperty: descriptor!.model) | translate }}</span>\n <mng-table-column-value [descriptor]=\"col\" [item]=\"item\"></mng-table-column-value>\n </td>\n <td\n *ngIf=\"showInlineActionsColumn\"\n class=\"column-action justify-content-end text-right\"\n [style.min-width.px]=\"columnActionMinWidth\"\n pFrozenColumn\n alignFrozen=\"right\">\n <ng-container *ngIf=\"columnActionTemplate; else showColumnActionComponentOrDefault\">\n <ng-container *ngTemplateOutlet=\"columnActionTemplate; context: {rowItem: item, rowIndex: idx}\"></ng-container>\n </ng-container>\n <ng-template #showColumnActionComponentOrDefault>\n <span\n *ngIf=\"columnActionComponent; else defaultColumnActions\"\n [mngComponent]=\"columnActionComponent!\"\n (instanceCreated)=\"onColumnActionCmpInst($event)\"></span>\n </ng-template>\n <ng-template #defaultColumnActions>\n <mng-action\n *ngFor=\"let action of rowInlineActions\"\n [action]=\"action\"\n [item]=\"item\"\n [itemId]=\"descriptor?.model?.idPropertyName ? item[descriptor!.model!.idPropertyName!] : null\"\n [actionData]=\"{itemIndex: idx}\"\n (finish)=\"onActionFinish($event)\">\n </mng-action>\n </ng-template>\n </td>\n </tr>\n </ng-template>\n\n <ng-template pTemplate=\"loadingbody\">\n <tr [style.height.px]=\"rowHeight\">\n <td [attr.colspan]=\"(descriptor?.columns?.length ?? 0) + (showInlineActionsColumn ? 1 : 0) + (selectionEnabled ? 1 : 0)\">\n <div class=\"loading-text\"></div>\n <p-skeleton [ngStyle]=\"{width: '100%'}\"></p-skeleton>\n </td>\n </tr>\n </ng-template>\n\n <ng-template pTemplate=\"emptymessage\">\n <tr [style.height.px]=\"rowHeight\">\n <td [attr.colspan]=\"(descriptor?.columns?.length ?? 0) + (showInlineActionsColumn ? 1 : 0) + (selectionEnabled ? 1 : 0)\">\n {{ 'mngTable.noItems' | translate }}\n </td>\n </tr>\n </ng-template>\n\n <ng-template *ngIf=\"footerTemplate\" pTemplate=\"summary\">\n <ng-container [ngTemplateOutlet]=\"footerTemplate\" [ngTemplateOutletContext]=\"{queryResult: queryResult}\"></ng-container>\n </ng-template>\n </p-table>\n</div>\n", dependencies: [{ kind: "directive", type: i4.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i4.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i4.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "directive", type: i4.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "directive", type: i5.PrimeTemplate, selector: "[pTemplate]", inputs: ["type", "pTemplate"] }, { kind: "component", type: i6.Table, selector: "p-table", inputs: ["frozenColumns", "frozenValue", "style", "styleClass", "tableStyle", "tableStyleClass", "paginator", "pageLinks", "rowsPerPageOptions", "alwaysShowPaginator", "paginatorPosition", "paginatorDropdownAppendTo", "paginatorDropdownScrollHeight", "currentPageReportTemplate", "showCurrentPageReport", "showJumpToPageDropdown", "showJumpToPageInput", "showFirstLastIcon", "showPageLinks", "defaultSortOrder", "sortMode", "resetPageOnSort", "selectionMode", "selectionPageOnly", "contextMenuSelection", "contextMenuSelectionMode", "dataKey", "metaKeySelection", "rowSelectable", "rowTrackBy", "lazy", "lazyLoadOnInit", "compareSelectionBy", "csvSeparator", "exportFilename", "filters", "globalFilterFields", "filterDelay", "filterLocale", "expandedRowKeys", "editingRowKeys", "rowExpandMode", "scrollable", "scrollDirection", "rowGroupMode", "scrollHeight", "virtualScroll", "virtualScrollItemSize", "virtualScrollOptions", "virtualScrollDelay", "frozenWidth", "responsive", "contextMenu", "resizableColumns", "columnResizeMode", "reorderableColumns", "loading", "loadingIcon", "showLoader", "rowHover", "customSort", "showInitialSortBadge", "autoLayout", "exportFunction", "exportHeader", "stateKey", "stateStorage", "editMode", "groupRowsBy", "groupRowsByOrder", "responsiveLayout", "breakpoint", "virtualRowHeight", "value", "columns", "first", "rows", "totalRecords", "sortField", "sortOrder", "multiSortMeta", "selection", "selectAll"], outputs: ["selectAllChange", "selectionChange", "contextMenuSelectionChange", "onRowSelect", "onRowUnselect", "onPage", "onSort", "onFilter", "onLazyLoad", "onRowExpand", "onRowCollapse", "onContextMenuSelect", "onColResize", "onColReorder", "onRowReorder", "onEditInit", "onEditComplete", "onEditCancel", "onHeaderCheckboxToggle", "sortFunction", "firstChange", "rowsChange", "onStateSave", "onStateRestore"] }, { kind: "directive", type: i6.SortableColumn, selector: "[pSortableColumn]", inputs: ["pSortableColumn", "pSortableColumnDisabled"] }, { kind: "directive", type: i6.FrozenColumn, selector: "[pFrozenColumn]", inputs: ["frozen", "alignFrozen"] }, { kind: "component", type: i6.SortIcon, selector: "p-sortIcon", inputs: ["field"] }, { kind: "component", type: i6.TableRadioButton, selector: "p-tableRadioButton", inputs: ["disabled", "value", "index", "inputId", "name", "ariaLabel"] }, { kind: "component", type: i6.TableCheckbox, selector: "p-tableCheckbox", inputs: ["disabled", "value", "index", "inputId", "name", "required", "ariaLabel"] }, { kind: "component", type: i6.TableHeaderCheckbox, selector: "p-tableHeaderCheckbox", inputs: ["disabled", "inputId", "name", "ariaLabel"] }, { kind: "component", type: i7.Skeleton, selector: "p-skeleton", inputs: ["styleClass", "style", "shape", "animation", "borderRadius", "size", "width", "height"] }, { kind: "directive", type: i8.MngComponentDirective, selector: "[mngComponent]", inputs: ["mngComponent", "inputs"], outputs: ["instanceCreated"] }, { kind: "component", type: i9.MngTableColumnValueComponent, selector: "mng-table-column-value", inputs: ["descriptor", "item"] }, { kind: "component", type: i10.MngTableColumnFilterComponent, selector: "mng-table-column-filter", inputs: ["descriptor", "display"] }, { kind: "component", type: i11.MngActionComponent, selector: "mng-action", inputs: ["action", "item", "itemId", "actionData", "queryParam", "dataProvider", "disabled", "loading", "viewContainer", "selectedItems"], outputs: ["finish"] }, { kind: "pipe", type: i4.AsyncPipe, name: "async" }, { kind: "pipe", type: i2.TranslatePipe, name: "translate" }, { kind: "pipe", type: i12.MngI18nPropertyPipe, name: "i18nProperty" }, { kind: "pipe", type: i13.MngClassMapPipe, name: "mngClassMapPipe" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
500
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.1.0", ngImport: i0, type: MngTableComponent, decorators: [{
501
+ type: Component,
502
+ args: [{ selector: 'mng-table', changeDetection: ChangeDetectionStrategy.OnPush, template: "<div [style.height]=\"tableFullHeightOffset ? 'calc(100vh - ' + tableFullHeightOffset + 'px)' : null\">\n <!-- MUST NOT use observable for value when using virtual scroll - does not work for some reason -->\n <p-table\n *ngIf=\"!useQueryParams || (useQueryParamsInitialized$ | async)\"\n [value]=\"infiniteScroll ? dataProviderInfiniteScrollItems : (queryResult$ | async)?.pageData ?? []\"\n [dataKey]=\"$any(descriptor?.dataKeyProperty ?? null)\"\n [lazy]=\"isLazy\"\n [loading]=\"(loading$ | async) ?? false\"\n [paginator]=\"isPagination && !infiniteScroll\"\n [rows]=\"$any(infiniteScroll ? 20 : rows)\"\n [first]=\"$any(infiniteScroll ? 0 : offset)\"\n [totalRecords]=\"$any(infiniteScroll ? null : (queryResult$ | async)?.allDataCount ?? 0)\"\n [rowsPerPageOptions]=\"$any(infiniteScroll ? null : rowsPerPageOptions)\"\n [showCurrentPageReport]=\"!infiniteScroll\"\n [currentPageReportTemplate]=\"'mngTable.paginationMsg' | translate\"\n [multiSortMeta]=\"$any(multiSortMeta)\"\n [filters]=\"filterMetadata\"\n sortMode=\"multiple\"\n [(selection)]=\"selection\"\n (selectionChange)=\"onSelectionChange($event)\"\n [selectionMode]=\"$any(selectionEnabled ? selectionMode : null)\"\n [scrollable]=\"true\"\n [virtualScroll]=\"infiniteScroll\"\n [virtualScrollItemSize]=\"$any(rowHeight)\"\n scrollHeight=\"flex\"\n [rowHover]=\"descriptor?.hasHover ?? true\"\n [styleClass]=\"className\"\n (onLazyLoad)=\"onTableLazyLoad($event)\"\n (onSort)=\"onTableSort($event)\"\n (onFilter)=\"onTableFilter($event)\">\n <ng-template *ngIf=\"captionTemplate || captionComponent || descriptor?.title\" pTemplate=\"caption\">\n <ng-container *ngIf=\"captionTemplate; else componentOrDefaultCaption\">\n <ng-container *ngTemplateOutlet=\"captionTemplate\"></ng-container>\n </ng-container>\n <ng-template #componentOrDefaultCaption>\n <div *ngIf=\"captionComponent; else defaultCaption\" [mngComponent]=\"captionComponent\" (instanceCreated)=\"onCaptionCmpInst($event)\"></div>\n <ng-template #defaultCaption>\n <h5 class=\"p-0 m-0\">{{ descriptor?.title }}</h5>\n </ng-template>\n </ng-template>\n </ng-template>\n\n <ng-template pTemplate=\"header\">\n <tr *ngIf=\"!descriptor?.hideHeader\" class=\"mng-table-header\" [class]=\"descriptor?.headerClassName\">\n <th *ngIf=\"selectionEnabled && selectionMode === 'multiple'\" style=\"min-width: 36px\" pFrozenColumn>\n <p-tableHeaderCheckbox></p-tableHeaderCheckbox>\n </th>\n <!-- We need the line below, because otherwise p-tableRadioButton shifts the rest of the columns in table -->\n <th *ngIf=\"selectionEnabled && selectionMode === 'single'\" style=\"min-width: 36px\" pFrozenColumn></th>\n <ng-container *ngFor=\"let col of descriptor?.columns\">\n <th\n *ngIf=\"col.isSortEnabled\"\n [pSortableColumn]=\"col.property\"\n [style.width.%]=\"col.width\"\n [style.min-width.px]=\"col.minWidth\"\n [style.max-width.px]=\"col.maxWidth\"\n [class]=\"\n col.headerClassName +\n (descriptor?.filterDisplay === filterDisplayRow && hasColumnFilters && col.filterDescriptor\n ? ' mng-column-filter-' + col.filterDescriptor.filterType\n : '')\n \">\n <div class=\"flex justify-content-between align-items-center\">\n {{ col.title ?? (col.property | i18nProperty: descriptor!.model) | translate }}\n <p-sortIcon [field]=\"col.property\"></p-sortIcon>\n <mng-table-column-filter\n *ngIf=\"col.filterDescriptor && descriptor!.filterDisplay === filterDisplayMenu\"\n class=\"ml-auto\"\n [display]=\"descriptor!.filterDisplay\"\n [descriptor]=\"col.filterDescriptor\">\n </mng-table-column-filter>\n </div>\n </th>\n <th\n *ngIf=\"!col.isSortEnabled\"\n [style.width.%]=\"col.width\"\n [style.min-width.px]=\"col.minWidth\"\n [style.max-width.px]=\"col.maxWidth\"\n [class]=\"\n col.headerClassName +\n (descriptor?.filterDisplay === filterDisplayRow && hasColumnFilters && col.filterDescriptor\n ? ' mng-column-filter-' + col.filterDescriptor.filterType\n : '')\n \">\n {{ col.title ?? (col.property | i18nProperty: descriptor!.model) | translate }}\n <ng-container>\n <mng-table-column-filter\n *ngIf=\"col.filterDescriptor && descriptor!.filterDisplay === filterDisplayMenu\"\n class=\"ml-auto\"\n [display]=\"descriptor!.filterDisplay\"\n [descriptor]=\"col.filterDescriptor\">\n </mng-table-column-filter>\n </ng-container>\n </th>\n </ng-container>\n <th *ngIf=\"showInlineActionsColumn\" [style.min-width.px]=\"columnActionMinWidth\" pFrozenColumn></th>\n </tr>\n <tr *ngIf=\"descriptor?.filterDisplay === filterDisplayRow && hasColumnFilters\" class=\"mng-column-filter-row\">\n <!-- We need the line below, because otherwise p-tableRadioButton shifts the rest of the columns in table -->\n <th *ngIf=\"selectionEnabled && selectionMode === 'single'\" style=\"min-width: 36px\" pFrozenColumn></th>\n <th\n *ngFor=\"let col of descriptor?.columns\"\n [class]=\"(col.filterDescriptor ? 'mng-column-filter-' + col.filterDescriptor.filterType + ' ' : ' ') + col.filterDescriptor?.columnClassName\"\n [style.width.%]=\"col.filterDescriptor?.columnWidth ?? col.width\"\n [style.min-width.px]=\"col.filterDescriptor?.columnMinWidth ?? col.minWidth\"\n [style.max-width.px]=\"col.maxWidth\">\n <div class=\"flex\" *ngIf=\"col.filterDescriptor\">\n <mng-table-column-filter [display]=\"descriptor!.filterDisplay\" [descriptor]=\"col.filterDescriptor\"></mng-table-column-filter>\n </div>\n </th>\n <th *ngIf=\"showInlineActionsColumn\" [style.min-width.px]=\"columnActionMinWidth\" pFrozenColumn></th>\n </tr>\n </ng-template>\n\n <ng-template pTemplate=\"body\" let-item let-idx=\"rowIndex\">\n <tr [style.height.px]=\"rowHeight\" [class]=\"descriptor?.rowClassName | mngClassMapPipe: descriptor?.rowClassNameMapFn:item\">\n <td *ngIf=\"selectionEnabled && selectionMode === 'multiple'\" style=\"min-width: 36px\" pFrozenColumn>\n <p-tableCheckbox [value]=\"item\"></p-tableCheckbox>\n </td>\n <td *ngIf=\"selectionEnabled && selectionMode === 'single'\" style=\"min-width: 36px\" pFrozenColumn>\n <p-tableRadioButton [value]=\"item\"></p-tableRadioButton>\n </td>\n <td\n *ngFor=\"let col of descriptor?.columns\"\n (click)=\"onCellClick($event, col, item, idx)\"\n [class]=\"\n col.className +\n (descriptor?.filterDisplay === filterDisplayRow && hasColumnFilters && col.filterDescriptor ? ' mng-column-filter-' + col.filterDescriptor.filterType : '')\n \"\n [class.clickable]=\"isColumnClickable\"\n [style.width.%]=\"col.width\"\n [style.min-width.px]=\"col.minWidth\"\n [style.max-width.px]=\"col.maxWidth\">\n <span class=\"p-column-title\">{{ col.title ?? (col.property | i18nProperty: descriptor!.model) | translate }}</span>\n <mng-table-column-value [descriptor]=\"col\" [item]=\"item\"></mng-table-column-value>\n </td>\n <td\n *ngIf=\"showInlineActionsColumn\"\n class=\"column-action justify-content-end text-right\"\n [style.min-width.px]=\"columnActionMinWidth\"\n pFrozenColumn\n alignFrozen=\"right\">\n <ng-container *ngIf=\"columnActionTemplate; else showColumnActionComponentOrDefault\">\n <ng-container *ngTemplateOutlet=\"columnActionTemplate; context: {rowItem: item, rowIndex: idx}\"></ng-container>\n </ng-container>\n <ng-template #showColumnActionComponentOrDefault>\n <span\n *ngIf=\"columnActionComponent; else defaultColumnActions\"\n [mngComponent]=\"columnActionComponent!\"\n (instanceCreated)=\"onColumnActionCmpInst($event)\"></span>\n </ng-template>\n <ng-template #defaultColumnActions>\n <mng-action\n *ngFor=\"let action of rowInlineActions\"\n [action]=\"action\"\n [item]=\"item\"\n [itemId]=\"descriptor?.model?.idPropertyName ? item[descriptor!.model!.idPropertyName!] : null\"\n [actionData]=\"{itemIndex: idx}\"\n (finish)=\"onActionFinish($event)\">\n </mng-action>\n </ng-template>\n </td>\n </tr>\n </ng-template>\n\n <ng-template pTemplate=\"loadingbody\">\n <tr [style.height.px]=\"rowHeight\">\n <td [attr.colspan]=\"(descriptor?.columns?.length ?? 0) + (showInlineActionsColumn ? 1 : 0) + (selectionEnabled ? 1 : 0)\">\n <div class=\"loading-text\"></div>\n <p-skeleton [ngStyle]=\"{width: '100%'}\"></p-skeleton>\n </td>\n </tr>\n </ng-template>\n\n <ng-template pTemplate=\"emptymessage\">\n <tr [style.height.px]=\"rowHeight\">\n <td [attr.colspan]=\"(descriptor?.columns?.length ?? 0) + (showInlineActionsColumn ? 1 : 0) + (selectionEnabled ? 1 : 0)\">\n {{ 'mngTable.noItems' | translate }}\n </td>\n </tr>\n </ng-template>\n\n <ng-template *ngIf=\"footerTemplate\" pTemplate=\"summary\">\n <ng-container [ngTemplateOutlet]=\"footerTemplate\" [ngTemplateOutletContext]=\"{queryResult: queryResult}\"></ng-container>\n </ng-template>\n </p-table>\n</div>\n" }]
503
+ }], ctorParameters: function () { return [{ type: i0.Injector }, { type: i1.Router }, { type: i1.ActivatedRoute }, { type: i2.TranslateService }, { type: i3.MngActionExecutorService }, { type: i3.MngViewContainerComponentService, decorators: [{
504
+ type: Optional
505
+ }] }]; }, propDecorators: { initialDescriptor: [{
506
+ type: Input,
507
+ args: ['descriptor']
508
+ }], items: [{
509
+ type: Input
510
+ }], queryResult: [{
511
+ type: Input
512
+ }], loading: [{
513
+ type: Input
514
+ }], dataProvider: [{
515
+ type: Input
516
+ }], useQueryParams: [{
517
+ type: Input
518
+ }], selectionMode: [{
519
+ type: Input
520
+ }], selectionEnabled: [{
521
+ type: Input
522
+ }], actions: [{
523
+ type: Input
524
+ }], isColumnClickable: [{
525
+ type: Input
526
+ }], viewContainerInit: [{
527
+ type: Input,
528
+ args: ['viewContainer']
529
+ }], captionComponent: [{
530
+ type: Input
531
+ }], columnActionComponent: [{
532
+ type: Input
533
+ }], columnActionMinWidth: [{
534
+ type: Input
535
+ }], loadEventEmitter: [{
536
+ type: Output,
537
+ args: ['tableLoad']
538
+ }], cellClickEventEmitter: [{
539
+ type: Output,
540
+ args: ['cellClick']
541
+ }], selectionChangeEventEmitter: [{
542
+ type: Output,
543
+ args: ['selectionChange']
544
+ }], captionCmpInstEventEmitter: [{
545
+ type: Output,
546
+ args: ['captionComponentInstance']
547
+ }], columnActionCmpInstEventEmitter: [{
548
+ type: Output,
549
+ args: ['columnActionComponentInstance']
550
+ }], templates: [{
551
+ type: ContentChildren,
552
+ args: [MngTemplateDirective]
553
+ }], components: [{
554
+ type: ViewChildren,
555
+ args: [MngComponentDirective]
556
+ }], primeTable: [{
557
+ type: ViewChild,
558
+ args: [Table]
559
+ }] } });
560
560
  //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidGFibGUuY29tcG9uZW50LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vLi4vc3JjL2xpYi9jb21wb25lbnRzL3RhYmxldmlldy90YWJsZS90YWJsZS5jb21wb25lbnQudHMiLCIuLi8uLi8uLi8uLi8uLi8uLi9zcmMvbGliL2NvbXBvbmVudHMvdGFibGV2aWV3L3RhYmxlL3RhYmxlLmNvbXBvbmVudC5odG1sIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFFSCx1QkFBdUIsRUFDdkIsU0FBUyxFQUNULGVBQWUsRUFDZixZQUFZLEVBRVosS0FBSyxFQUlMLFFBQVEsRUFDUixNQUFNLEVBS04sU0FBUyxFQUNULFlBQVksRUFDZixNQUFNLGVBQWUsQ0FBQztBQUl2QixPQUFPLEVBQUMsZUFBZSxFQUEwQyxNQUFNLGFBQWEsQ0FBQztBQUNyRixPQUFPLEVBQUMsS0FBSyxFQUFDLE1BQU0sZUFBZSxDQUFDO0FBQ3BDLE9BQU8sRUFBQyxlQUFlLEVBQUUsVUFBVSxFQUFFLGFBQWEsRUFBZ0IsWUFBWSxFQUFFLEVBQUUsRUFBQyxNQUFNLE1BQU0sQ0FBQztBQUNoRyxPQUFPLEVBQUMsR0FBRyxFQUFDLE1BQU0sZ0JBQWdCLENBQUM7QUFFbkMsT0FBTyxFQUFDLHFCQUFxQixFQUFFLGdCQUFnQixFQUFFLHVCQUF1QixFQUFFLGlCQUFpQixFQUFDLE1BQU0scUJBQXFCLENBQUM7QUFDeEgsT0FBTyxFQUFDLGNBQWMsRUFBQyxNQUFNLG9CQUFvQixDQUFDO0FBRWxELE9BQU8sRUFBZ0csc0JBQXNCLEVBQUMsTUFBTSxzQkFBc0IsQ0FBQztBQUMzSixPQUFPLEVBQUMsa0JBQWtCLEVBQUUsY0FBYyxFQUFFLHNCQUFzQixFQUFFLHVCQUF1QixFQUFFLGFBQWEsRUFBQyxNQUFNLDRCQUE0QixDQUFDO0FBQzlJLE9BQU8sRUFBQyxxQkFBcUIsRUFBRSxvQkFBb0IsRUFBQyxNQUFNLHFCQUFxQixDQUFDO0FBR2hGLE9BQU8s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O3NCQUE3QixLQUFLO2dCQUdVLGFBQWE7c0JBQTVCLEtBQUs7Z0JBQ1UsZ0JBQWdCO3NCQUEvQixLQUFLO2dCQUdVLE9BQU87c0JBQXRCLEtBQUs7Z0JBR1UsaUJBQWlCO3NCQUFoQyxLQUFLO2dCQUd5QixpQkFBaUI7c0JBQS9DLEtBQUs7dUJBQUMsZUFBZTtnQkFDTixnQkFBZ0I7c0JBQS9CLEtBQUs7Z0JBQ1UscUJBQXFCO3NCQUFwQyxLQUFLO2dCQUNVLG9CQUFvQjtzQkFBbkMsS0FBSztnQkFHc0IsZ0JBQWdCO3NCQUEzQyxNQUFNO3VCQUFDLFdBQVc7Z0JBQ1MscUJBQXFCO3NCQUFoRCxNQUFNO3VCQUFDLFdBQVc7Z0JBQ2UsMkJBQTJCO3NCQUE1RCxNQUFNO3VCQUFDLGlCQUFpQjtnQkFDa0IsMEJBQTBCO3NCQUFwRSxNQUFNO3VCQUFDLDBCQUEwQjtnQkFDYywrQkFBK0I7c0JBQTlFLE1BQU07dUJBQUMsK0JBQStCO2dCQUdPLFNBQVM7c0JBQXRELGVBQWU7dUJBQUMsb0JBQW9CO2dCQUNPLFVBQVU7c0JBQXJELFlBQVk7dUJBQUMscUJBQXFCO2dCQUNWLFVBQVU7c0JBQWxDLFNBQVM7dUJBQUMsS0FBSyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7XG4gICAgQWZ0ZXJDb250ZW50SW5pdCxcbiAgICBDaGFuZ2VEZXRlY3Rpb25TdHJhdGVneSxcbiAgICBDb21wb25lbnQsXG4gICAgQ29udGVudENoaWxkcmVuLFxuICAgIEV2ZW50RW1pdHRlcixcbiAgICBJbmplY3RvcixcbiAgICBJbnB1dCxcbiAgICBPbkNoYW5nZXMsXG4gICAgT25EZXN0cm95LFxuICAgIE9uSW5pdCxcbiAgICBPcHRpb25hbCxcbiAgICBPdXRwdXQsXG4gICAgUXVlcnlMaXN0LFxuICAgIFNpbXBsZUNoYW5nZXMsXG4gICAgVGVtcGxhdGVSZWYsXG4gICAgVHlwZSxcbiAgICBWaWV3Q2hpbGQsXG4gICAgVmlld0NoaWxkcmVuXG59IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHtBY3RpdmF0ZWRSb3V0ZSwgUGFyYW1zLCBSb3V0ZXJ9IGZyb20gJ0Bhbmd1bGFyL3JvdXRlcic7XG5cbmltcG9ydCB7VHJhbnNsYXRlU2VydmljZX0gZnJvbSAnQG5neC10cmFuc2xhdGUvY29yZSc7XG5pbXBvcnQge0ZpbHRlck1hdGNoTW9kZSwgRmlsdGVyTWV0YWRhdGEsIExhenlMb2FkRXZlbnQsIFNvcnRNZXRhfSBmcm9tICdwcmltZW5nL2FwaSc7XG5pbXBvcnQge1RhYmxlfSBmcm9tICdwcmltZW5nL3RhYmxlJztcbmltcG9ydCB7QmVoYXZpb3JTdWJqZWN0LCBPYnNlcnZhYmxlLCBSZXBsYXlTdWJqZWN0LCBTdWJzY3JpcHRpb24sIGlzT2JzZXJ2YWJsZSwgb2Z9IGZyb20gJ3J4anMnO1xuaW1wb3J0IHttYXB9IGZyb20gJ3J4anMvb3BlcmF0b3JzJztcblxuaW1wb3J0IHtNZWRpdXNGaWx0ZXJNYXRjaFR5cGUsIE1lZGl1c1F1ZXJ5UGFyYW0sIE1lZGl1c1F1ZXJ5UGFyYW1CdWlsZGVyLCBNZWRpdXNRdWVyeVJlc3VsdH0gZnJvbSAnLi4vLi4vLi4vYXBpL21vZGVscyc7XG5pbXBvcnQge01lZGl1c1Jlc3RVdGlsfSBmcm9tICcuLi8uLi8uLi9hcGkvdXRpbHMnO1xuaW1wb3J0IHtJVGFibGVEYXRhUHJvdmlkZXJ9IGZyb20gJy4uLy4uLy4uL2RhdGEtcHJvdmlkZXJzJztcbmltcG9ydCB7QWN0aW9uRGVzY3JpcHRvciwgQ29sdW1uRGVzY3JpcHRvciwgRmlsdGVyRGVzY3JpcHRvciwgRmlsdGVyTG9va3VwRGVzY3JpcHRvciwgVGFibGVEZXNjcmlwdG9yLCBUYWJsZUR5bmFtaWNEZXNjcmlwdG9yfSBmcm9tICcuLi8uLi8uLi9kZXNjcmlwdG9ycyc7XG5pbXBvcnQge0FjdGlvblBvc2l0aW9uRW51bSwgRmlsdGVyVHlwZUVudW0sIFRhYmxlRmlsdGVyRGlzcGxheUVudW0sIFRhYmxlUGFnaW5hdGlvbk1vZGVFbnVtLCBUYWJsZVNpemVFbnVtfSBmcm9tICcuLi8uLi8uLi9kZXNjcmlwdG9ycy90eXBlcyc7XG5pbXBvcnQge01uZ0NvbXBvbmVudERpcmVjdGl2ZSwgTW5nVGVtcGxhdGVEaXJlY3RpdmV9IGZyb20gJy4uLy4uLy4uL2RpcmVjdGl2ZXMnO1xuaW1wb3J0IHtJVmlld0NvbnRhaW5lcn0gZnJvbSAnLi4vLi4vLi4vbW9kZWxzJztcbmltcG9ydCB7TW5nQWN0aW9uRXhlY3V0b3JTZXJ2aWNlLCBNbmdWaWV3Q29udGFpbmVyQ29tcG9uZW50U2VydmljZX0gZnJvbSAnLi4vLi4vLi4vc2VydmljZXMnO1xuaW1wb3J0IHtTdHlsZXNVdGlsfSBmcm9tICcuLi8uLi8uLi9zdHlsZXMnO1xuaW1wb3J0IHtOb3RpZmljYXRpb25VdGlsfSBmcm9tICcuLi8uLi8uLi91dGlscyc7XG5pbXBvcnQge0FjdGlvbkluc3RhbmNlfSBmcm9tICcuLi8uLi9hY3Rpb24vbW9kZWxzJztcbmltcG9ydCB7TW5nVGFibGVDZWxsQ2xpY2tFdmVudCwgTW5nVGFibGVMb2FkRXZlbnR9IGZyb20gJy4uL21vZGVscyc7XG5cbkBDb21wb25lbnQoe1xuICAgIHNlbGVjdG9yOiAnbW5nLXRhYmxlJyxcbiAgICB0ZW1wbGF0ZVVybDogJy4vdGFibGUuY29tcG9uZW50Lmh0bWwnLFxuICAgIGNoYW5nZURldGVjdGlvbjogQ2hhbmdlRGV0ZWN0aW9uU3RyYXRlZ3kuT25QdXNoXG59KVxuZXhwb3J0IGNsYXNzIE1uZ1RhYmxlQ29tcG9uZW50PFQsIFM+IGltcGxlbWVudHMgT25Jbml0LCBPbkNoYW5nZXMsIEFmdGVyQ29udGVudEluaXQsIE9uRGVzdHJveSB7XG4gICAgcHVibGljIHJlYWRvbmx5IGZpbHRlckRpc3BsYXlSb3c6IFRhYmxlRmlsdGVyRGlzcGxheUVudW0gPSBUYWJsZUZpbHRlckRpc3BsYXlFbnVtLlJvdztcbiAgICBwdWJsaWMgcmVhZG9ubHkgZmlsdGVyRGlzcGxheU1lbnU6IFRhYmxlRmlsdGVyRGlzcGxheUVudW0gPSBUYWJsZUZpbHRlckRpc3BsYXlFbnVtLk1lbnU7XG5cbiAgICAvLyBtZXRhZGF0YSBpbnB1dFxuICAgIEBJbnB1dCgnZGVzY3JpcHRvcicpIHB1YmxpYyBpbml0aWFsRGVzY3JpcHRvciE6IFRhYmxlRGVzY3JpcHRvcjxUPjtcbiAgICBwdWJsaWMgZGVzY3JpcHRvcj86IFRhYmxlRGVzY3JpcHRvcjxUPjtcblxuICAgIC8vIGRhdGEgc291cmNlIGlucHV0c1xuICAgIEBJbnB1dCgpIHB1YmxpYyBpdGVtcz86IE9ic2VydmFibGU8QXJyYXk8VD4+IHwgQXJyYXk8VD47XG4gICAgQElucHV0KCkgcHVibGljIHF1ZXJ5UmVzdWx0PzogT2JzZXJ2YWJsZTxNZWRpdXNRdWVyeVJlc3VsdDxUPj4gfCBNZWRpdXNRdWVyeVJlc3VsdDxUPjtcbiAgICBASW5wdXQoKSBwdWJsaWMgbG9hZGluZz86IE9ic2VydmFibGU8Ym9vbGVhbj4gfCBib29sZWFuO1xuICAgIEBJbnB1dCgpIHB1YmxpYyBkYXRhUHJvdmlkZXI/OiBJVGFibGVEYXRhUHJvdmlkZXI8VCwgYW55PjtcbiAgICBASW5wdXQoKSBwdWJsaWMgdXNlUXVlcnlQYXJhbXMgPSBmYWxzZTtcblxuICAgIC8vIGV4dHJhIGZlYXR1cmVzIGlucHV0XG4gICAgQElucHV0KCkgcHVibGljIHNlbGVjdGlvbk1vZGUgPSAnbXVsdGlwbGUnO1xuICAgIEBJbnB1dCgpIHB1YmxpYyBzZWxlY3Rpb25FbmFibGVkID0gZmFsc2U7XG5cbiAgICAvLyBhY3Rpb25zXG4gICAgQElucHV0KCkgcHVibGljIGFjdGlvbnM6IEFycmF5PEFjdGlvbkRlc2NyaXB0b3I8VD4+ID0gW107XG5cbiAgICAvLyB2aXN1YWxcbiAgICBASW5wdXQoKSBwdWJsaWMgaXNDb2x1bW5DbGlja2FibGU/OiBib29sZWFuO1xuXG4gICAgLy8gY29tcG9uZW50IGlucHV0c1xuICAgIEBJbnB1dCgndmlld0NvbnRhaW5lcicpIHB1YmxpYyB2aWV3Q29udGFpbmVySW5pdD86IElWaWV3Q29udGFpbmVyPFQsIFM+O1xuICAgIEBJbnB1dCgpIHB1YmxpYyBjYXB0aW9uQ29tcG9uZW50PzogVHlwZTxhbnk+O1xuICAgIEBJbnB1dCgpIHB1YmxpYyBjb2x1bW5BY3Rpb25Db21wb25lbnQ/OiBUeXBlPGFueT47XG4gICAgQElucHV0KCkgcHVibGljIGNvbHVtbkFjdGlvbk1pbldpZHRoOiBudW1iZXIgfCBudWxsID0gbnVsbDtcblxuICAgIC8vIGV2ZW50IG91dHB1dHNcbiAgICBAT3V0cHV0KCd0YWJsZUxvYWQnKSBwdWJsaWMgbG9hZEV2ZW50RW1pdHRlciA9IG5ldyBFdmVudEVtaXR0ZXI8TW5nVGFibGVMb2FkRXZlbnQ+KCk7XG4gICAgQE91dHB1dCgnY2VsbENsaWNrJykgcHVibGljIGNlbGxDbGlja0V2ZW50RW1pdHRlciA9IG5ldyBFdmVudEVtaXR0ZXI8TW5nVGFibGVDZWxsQ2xpY2tFdmVudDxUPj4oKTtcbiAgICBAT3V0cHV0KCdzZWxlY3Rpb25DaGFuZ2UnKSBwdWJsaWMgc2VsZWN0aW9uQ2hhbmdlRXZlbnRFbWl0dGVyID0gbmV3IEV2ZW50RW1pdHRlcjxBcnJheTxUPj4oKTtcbiAgICBAT3V0cHV0KCdjYXB0aW9uQ29tcG9uZW50SW5zdGFuY2UnKSBwdWJsaWMgY2FwdGlvbkNtcEluc3RFdmVudEVtaXR0ZXIgPSBuZXcgRXZlbnRFbWl0dGVyPGFueT4oKTtcbiAgICBAT3V0cHV0KCdjb2x1bW5BY3Rpb25Db21wb25lbnRJbnN0YW5jZScpIHB1YmxpYyBjb2x1bW5BY3Rpb25DbXBJbnN0RXZlbnRFbWl0dGVyID0gbmV3IEV2ZW50RW1pdHRlcjxhbnk+KCk7XG5cbiAgICAvLyBjb250ZW50IGFuZCB2aWV3IHF1ZXJpZXNcbiAgICBAQ29udGVudENoaWxkcmVuKE1uZ1RlbXBsYXRlRGlyZWN0aXZlKSBwdWJsaWMgdGVtcGxhdGVzITogUXVlcnlMaXN0PE1uZ1RlbXBsYXRlRGlyZWN0aXZlPjtcbiAgICBAVmlld0NoaWxkcmVuKE1uZ0NvbXBvbmVudERpcmVjdGl2ZSkgcHVibGljIGNvbXBvbmVudHMhOiBRdWVyeUxpc3Q8TW5nQ29tcG9uZW50RGlyZWN0aXZlPGFueT4+O1xuICAgIEBWaWV3Q2hpbGQoVGFibGUpIHB1YmxpYyBwcmltZVRhYmxlITogVGFibGU7XG5cbiAgICAvLyB0ZW1wbGF0ZXNcbiAgICBwdWJsaWMgY2FwdGlvblRlbXBsYXRlPzogVGVtcGxhdGVSZWY8YW55PjtcbiAgICBwdWJsaWMgY29sdW1uQWN0aW9uVGVtcGxhdGU/OiBUZW1wbGF0ZVJlZjxhbnk+O1xuICAgIHB1YmxpYyBmb290ZXJUZW1wbGF0ZT86IFRlbXBsYXRlUmVmPGFueT47XG5cbiAgICAvLyBkYXRhIHByb3ZpZGVyIGFuZCBpdGVtc1xuICAgIHB1YmxpYyBpc0xhenkgPSBmYWxzZTtcbiAgICBwdWJsaWMgaXNQYWdpbmF0aW9uID0gZmFsc2U7XG4gICAgcHJpdmF0ZSB1c2VEYXRhUHJvdmlkZXIgPSBmYWxzZTtcbiAgICBwcml2YXRlIHVzZVF1ZXJ5UGFyYW1zSW5pdGlhbGl6ZWRTdWJlamN0ID0gbmV3IEJlaGF2aW9yU3ViamVjdChmYWxzZSk7XG4gICAgcHVibGljIHVzZVF1ZXJ5UGFyYW1zSW5pdGlhbGl6ZWQkID0gdGhpcy51c2VRdWVyeVBhcmFtc0luaXRpYWxpemVkU3ViZWpjdC5hc09ic2VydmFibGUoKTtcbiAgICBwdWJsaWMgcXVlcnlSZXN1bHQkPzogT2JzZXJ2YWJsZTxNZWRpdXNRdWVyeVJlc3VsdDxUPj47XG4gICAgcHVibGljIGxvYWRpbmckPzogT2JzZXJ2YWJsZTxib29sZWFuPjtcbiAgICBwdWJsaWMgZGF0YVByb3ZpZGVySW5maW5pdGVTY3JvbGxJdGVtczogQXJyYXk8VD4gPSBbXTtcbiAgICBwcml2YXRlIGl0ZW1zU3ViamVjdCA9IG5ldyBSZXBsYXlTdWJqZWN0PEFycmF5PFQ+PigxKTtcblxuICAgIHByaXZhdGUgcXVlcnlSZXN1bHRTdWJzY3JpcHRpb24/OiBTdWJzY3JpcHRpb247XG5cbiAgICAvLyBwYWdpbmF0aW9uLCBzb3J0IGFuZCBmaWx0ZXJzXG4gICAgcHVibGljIHJvd3NQZXJQYWdlT3B0aW9ucyE6IEFycmF5PG51bWJlcj47XG4gICAgcHVibGljIHJvd3MhOiBudW1iZXI7XG4gICAgcHVibGljIG9mZnNldCA9IDA7XG4gICAgcHVibGljIG11bHRpU29ydE1ldGE6IFNvcnRNZXRhW10gfCBudWxsID0gbnVsbDtcbiAgICBwdWJsaWMgZmlsdGVyTWV0YWRhdGE6IHtbczogc3RyaW5nXTogRmlsdGVyTWV0YWRhdGF9ID0ge307XG5cbiAgICAvLyBpbmZpbml0ZSBzY3JvbGxcbiAgICBwdWJsaWMgaW5maW5pdGVTY3JvbGwgPSBmYWxzZTtcblxuICAgIC8vIHZpc3VhbFxuICAgIHB1YmxpYyBjbGFzc05hbWUhOiBzdHJpbmc7XG4gICAgcHVibGljIHRhYmxlRnVsbEhlaWdodE9mZnNldDogbnVtYmVyIHwgbnVsbCA9IG51bGw7XG4gICAgcHVibGljIHJvd0hlaWdodDogbnVtYmVyIHwgbnVsbCA9IG51bGw7XG5cbiAgICAvLyBzZWxlY3Rpb25cbiAgICBwdWJsaWMgc2VsZWN0aW9uOiBBcnJheTxUPiA9IFtdO1xuXG4gICAgLy8gZGF0YSBwcm92aWRlclxuICAgIHByaXZhdGUgZGF0YVByb3ZpZGVyU2VydmljZTogYW55ID0gbnVsbDtcbiAgICBwcml2YXRlIGRhdGFQcm92aWRlclF1ZXJ5UmVzdWx0U3ViamVjdCA9IG5ldyBSZXBsYXlTdWJqZWN0PE1lZGl1c1F1ZXJ5UmVzdWx0PFQ+PigxKTtcbiAgICBwcml2YXRlIGRhdGFQcm92aWRlckxvYWRpbmdTdWJqZWN0ID0gbmV3IFJlcGxheVN1YmplY3Q8Ym9vbGVhbj4oMSk7XG4gICAgcHJpdmF0ZSBkYXRhUHJvdmlkZXJMYXRlc3RMYXp5TG9hZEV2ZW50PzogTGF6eUxvYWRFdmVudDtcbiAgICBwcml2YXRlIGRhdGFQcm92aWRlckxhdGVzdExhenlMb2FkRXZlbnRWZXJzaW9uID0gMDtcbiAgICBwcml2YXRlIGRhdGFQcm92aWRlckxhdGVzdFF1ZXJ5UGFyYW0/OiBNZWRpdXNRdWVyeVBhcmFtO1xuICAgIHByaXZhdGUgZGF0YVByb3ZpZGVyTGF0ZXN0UXVlcnlQYXJhbVZlcnNpb24gPSAwO1xuICAgIHByaXZhdGUgZGF0YVByb3ZpZGVyU3Vic2NyaXB0aW9uPzogU3Vic2NyaXB0aW9uO1xuXG4gICAgLy8gZmlsdGVyLCBzb3J0XG4gICAgcHVibGljIGhhc0NvbHVtbkZpbHRlcnMgPSBmYWxzZTtcbiAgICBwcml2YXRlIGlzRmlsdGVyQ2hhbmdlZCA9IGZhbHNlO1xuICAgIHByaXZhdGUgaXNTb3J0Q2hhbmdlZCA9IGZhbHNlO1xuICAgIHByaXZhdGUgZmlsdGVyRGVzY3JpcHRvcnM6IEFycmF5PEZpbHRlckRlc2NyaXB0b3I8YW55Pj4gPSBbXTtcblxuICAgIC8vIGFjdGlvbnNcbiAgICBwdWJsaWMgc2hvd0lubGluZUFjdGlvbnNDb2x1bW4gPSBmYWxzZTtcbiAgICBwdWJsaWMgcm93Q2xpY2tBY3Rpb25zOiBBY3Rpb25EZXNjcmlwdG9yPFQ+W10gPSBbXTtcbiAgICBwdWJsaWMgcm93SW5saW5lQWN0aW9uczogQWN0aW9uRGVzY3JpcHRvcjxUPltdID0gW107XG5cbiAgICAvLyBvdGhlclxuICAgIHByaXZhdGUgdmlld0NvbnRhaW5lcj86IElWaWV3Q29udGFpbmVyPFQsIFM+O1xuICAgIHByaXZhdGUgc3Vic2NyaXB0aW9uczogU3Vic2NyaXB0aW9uW10gPSBbXTtcblxuICAgIGNvbnN0cnVjdG9yKFxuICAgICAgICBwcml2YXRlIGluamVjdG9yOiBJbmplY3RvcixcbiAgICAgICAgcHJpdmF0ZSByb3V0ZXI6IFJvdXRlcixcbiAgICAgICAgcHJpdmF0ZSByb3V0ZTogQWN0aXZhdGVkUm91dGUsXG4gICAgICAgIHByaXZhdGUgdHJhbnNsYXRlOiBUcmFuc2xhdGVTZXJ2aWNlLFxuICAgICAgICBwcml2YXRlIGFjdGlvbkV4ZWN1dG9yOiBNbmdBY3Rpb25FeGVjdXRvclNlcnZpY2UsXG4gICAgICAgIEBPcHRpb25hbCgpIHByaXZhdGUgdmlld0NvbnRhaW5lclNlcnZpY2U6IE1uZ1ZpZXdDb250YWluZXJDb21wb25lbnRTZXJ2aWNlPFQsIFM+IHwgbnVsbFxuICAgICkge31cblxuICAgIHB1YmxpYyBuZ09uSW5pdCgpIHtcbiAgICAgICAgdGhpcy52aWV3Q29udGFpbmVyID0gdGhpcy52aWV3Q29udGFpbmVySW5pdCA/PyB0aGlzLnZpZXdDb250YWluZXJTZXJ2aWNlID8/IHVuZGVmaW5lZDtcblxuICAgICAgICBpZiAoISh0aGlzLmluaXRpYWxEZXNjcmlwdG9yIGluc3RhbmNlb2YgVGFibGVEeW5hbWljRGVzY3JpcHRvcikpIHtcbiAgICAgICAgICAgIHRoaXMuZGVzY3JpcHRvciA9IHRoaXMuaW5pdGlhbERlc2NyaXB0b3I7XG4gICAgICAgIH1cblxuICAgICAgICAvLyBtYXAgcm93IHNldHRpbmdzXG4gICAgICAgIHRoaXMuZmlsdGVyRGVzY3JpcHRvcnMgPSB0aGlzLmRlc2NyaXB0b3I/LmNvbHVtbnMuZmlsdGVyKGMgPT4gdHlwZW9mIGMuZmlsdGVyRGVzY3JpcHRvciAhPT0gJ3VuZGVmaW5lZCcpLm1hcChjID0+IGMuZmlsdGVyRGVzY3JpcHRvciEpID8/IFtdO1xuICAgICAgICB0aGlzLmhhc0NvbHVtbkZpbHRlcnMgPSB0aGlzLmZpbHRlckRlc2NyaXB0b3JzLmxlbmd0aCA+IDA7XG4gICAgICAgIHRoaXMucm93cyA9IHRoaXMuZGVzY3JpcHRvcj8uZGVmYXVsdE51bVJvd3MgPz8gMjU7XG4gICAgICAgIHRoaXMucm93c1BlclBhZ2VPcHRpb25zID0gdGhpcy5kZXNjcmlwdG9yPy5yb3dzUGVyUGFnZU9wdGlvbnMgPz8gWzI1LCA1MCwgMTAwXTtcblxuICAgICAgICAvLyBwcm9jZXNzIGFjdGlvbnNcbiAgICAgICAgZm9yIChjb25zdCBhY3Rpb24gb2YgdGhpcy5hY3Rpb25zKSB7XG4gICAgICAgICAgICBzd2l0Y2ggKGFjdGlvbi5wb3NpdGlvbikge1xuICAgICAgICAgICAgICAgIGNhc2UgQWN0aW9uUG9zaXRpb25FbnVtLlJvd0NsaWNrOlxuICAgICAgICAgICAgICAgICAgICB0aGlzLnJvd0NsaWNrQWN0aW9ucy5wdXNoKGFjdGlvbik7XG4gICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgIGNhc2UgQWN0aW9uUG9zaXRpb25FbnVtLlJvd0lubGluZTpcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5yb3dJbmxpbmVBY3Rpb25zLnB1c2goYWN0aW9uKTtcbiAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5zaG93SW5saW5lQWN0aW9uc0NvbHVtbiA9IHR5cGVvZiB0aGlzLmNvbHVtbkFjdGlvbkNvbXBvbmVudCAhPT0gJ3VuZGVmaW5lZCcgfHwgdGhpcy5yb3dJbmxpbmVBY3Rpb25zLmxlbmd0aCA+IDA7XG5cbiAgICAgICAgLy8gZGVmaW5lIGFsbCBzdHlsZXNcbiAgICAgICAgdGhpcy5jbGFzc05hbWUgPSB0aGlzLmRlc2NyaXB0b3I/LmNsYXNzTmFtZSA/PyAnJztcbiAgICAgICAgdGhpcy50YWJsZUZ1bGxIZWlnaHRPZmZzZXQgPSB0aGlzLmRlc2NyaXB0b3I/LnRhYmxlRnVsbEhlaWdodE9mZnNldCA/PyBudWxsO1xuICAgICAgICB0aGlzLnJvd0hlaWdodCA9IHRoaXMuZGVzY3JpcHRvcj8ucm93SGVpZ2h0ID8/IG51bGw7XG4gICAgICAgIGlmICh0eXBlb2YgdGhpcy5pc0NvbHVtbkNsaWNrYWJsZSA9PT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgICAgICAgIC8vIGRlZmluZSBpZiBjZWxsIGNsaWNrIGlzIGJlaW5nIG9ic2VydmVkIHZpYSBvdXRwdXRcbiAgICAgICAgICAgIHRoaXMuaXNDb2x1bW5DbGlja2FibGUgPSB0aGlzLnJvd0NsaWNrQWN0aW9ucy5sZW5ndGggPiAwIHx8IHRoaXMuY2VsbENsaWNrRXZlbnRFbWl0dGVyLm9ic2VydmVkO1xuICAgICAgICB9XG4gICAgICAgIHN3aXRjaCAodGhpcy5kZXNjcmlwdG9yPy5zaXplKSB7XG4gICAgICAgICAgICBjYXNlIFRhYmxlU2l6ZUVudW0uU21hbGw6XG4gICAgICAgICAgICAgICAgdGhpcy5jbGFzc05hbWUgKz0gJyBwLWRhdGF0YWJsZS1zbSc7XG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICBjYXNlIFRhYmxlU2l6ZUVudW0uTGFyZ2U6XG4gICAgICAgICAgICAgICAgdGhpcy5jbGFzc05hbWUgKz0gJyBwLWRhdGF0YWJsZS1sZyc7XG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHRoaXMuZGVzY3JpcHRvcj8uaGFzR3JpZGxpbmVzKSB7XG4gICAgICAgICAgICB0aGlzLmNsYXNzTmFtZSArPSAnIHAtZGF0YXRhYmxlLWdyaWRsaW5lcyc7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHRoaXMuZGVzY3JpcHRvciAmJiAhdGhpcy5jb2x1bW5BY3Rpb25NaW5XaWR0aCkge1xuICAgICAgICAgICAgdGhpcy5jb2x1bW5BY3Rpb25NaW5XaWR0aCA9IFN0eWxlc1V0aWwuY2FsY3VsYXRlVGFibGVDb2x1bW5BY3Rpb25XaWR0aChcbiAgICAgICAgICAgICAgICB0aGlzLmRlc2NyaXB0b3IgYXMgVGFibGVEZXNjcmlwdG9yPHVua25vd24+LFxuICAgICAgICAgICAgICAgIHRoaXMucm93SW5saW5lQWN0aW9ucyBhcyBBcnJheTxBY3Rpb25EZXNjcmlwdG9yPHVua25vd24+PlxuICAgICAgICAgICAgKTtcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIGNoZWNrIGlmIGluZmluaXRlIHNjcm9sbFxuICAgICAgICBpZiAodGhpcy5kZXNjcmlwdG9yPy5wYWdpbmF0aW9uTW9kZSA9PT0gVGFibGVQYWdpbmF0aW9uTW9kZUVudW0uSW5maW5pdGVTY3JvbGwpIHtcbiAgICAgICAgICAgIHRoaXMuaW5maW5pdGVTY3JvbGwgPSB0cnVlO1xuICAgICAgICAgICAgdGhpcy50YWJsZUZ1bGxIZWlnaHRPZmZzZXQgPSB0aGlzLmRlc2NyaXB0b3IudGFibGVGdWxsSGVpZ2h0T2Zmc2V0ID8/IDMxNTtcbiAgICAgICAgICAgIHRoaXMucm93SGVpZ2h0ID0gdGhpcy5kZXNjcmlwdG9yLnJvd0hlaWdodCA/PyA0NTtcbiAgICAgICAgICAgIHRoaXMudXNlUXVlcnlQYXJhbXMgPSBmYWxzZTtcbiAgICAgICAgfSBlbHNlIGlmICh0aGlzLmRlc2NyaXB0b3I/LnBhZ2luYXRpb25Nb2RlID09PSBUYWJsZVBhZ2luYXRpb25Nb2RlRW51bS5QYWdpbmF0aW9uKSB7XG4gICAgICAgICAgICB0aGlzLmlzUGFnaW5hdGlvbiA9IHRydWU7XG4gICAgICAgIH1cblxuICAgICAgICAvLyBjaGVjayBpZiBkYXRhIHByb3ZpZGVyIGlzIHN1cHBsaWVkLCBpZiBpcywgdXNlIGl0IHByaW1hcmlseVxuICAgICAgICBpZiAodGhpcy5kYXRhUHJvdmlkZXIpIHtcbiAgICAgICAgICAgIC8vIG1hcCBzdWJqZWN0cyB0byBvYnNlcnZhYmxlcyBhbmQgaW5pdGlhdGUgZGF0YVxuICAgICAgICAgICAgdGhpcy51c2VEYXRhUHJvdmlkZXIgPSB0cnVlO1xuICAgICAgICAgICAgdGhpcy5pc0xhenkgPSB0aGlzLmRhdGFQcm92aWRlci5pc0xhenk7XG4gICAgICAgICAgICB0aGlzLnF1ZXJ5UmVzdWx0JCA9IHRoaXMuZGF0YVByb3ZpZGVyUXVlcnlSZXN1bHRTdWJqZWN0LmFzT2JzZXJ2YWJsZSgpO1xuICAgICAgICAgICAgdGhpcy5sb2FkaW5nJCA9IHRoaXMuZGF0YVByb3ZpZGVyTG9hZGluZ1N1YmplY3QuYXNPYnNlcnZhYmxlKCk7XG4gICAgICAgICAgICBjb25zdCBlbXB0eVF1ZXJ5UmVzdWx0ID0gbmV3IE1lZGl1c1F1ZXJ5UmVzdWx0PFQ+KCk7XG4gICAgICAgICAgICBlbXB0eVF1ZXJ5UmVzdWx0LnBhZ2VEYXRhID0gW107XG4gICAgICAgICAgICBlbXB0eVF1ZXJ5UmVzdWx0LmFsbERhdGFDb3VudCA9IDA7XG4gICAgICAgICAgICB0aGlzLmRhdGFQcm92aWRlckxvYWRpbmdTdWJqZWN0Lm5leHQoZmFsc2UpO1xuICAgICAgICAgICAgdGhpcy5kYXRhUHJvdmlkZXJRdWVyeVJlc3VsdFN1YmplY3QubmV4dChlbXB0eVF1ZXJ5UmVzdWx0KTtcblxuICAgICAgICAgICAgLy8gaW5qZWN0IHNlcnZpY2VcbiAgICAgICAgICAgIGlmICh0aGlzLmRhdGFQcm92aWRlci5zZXJ2aWNlVHlwZSkge1xuICAgICAgICAgICAgICAgIHRoaXMuZGF0YVByb3ZpZGVyU2VydmljZSA9IHRoaXMuaW5qZWN0b3IuZ2V0PGFueT4odGhpcy5kYXRhUHJvdmlkZXIuc2VydmljZVR5cGUpO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBjb25zdCByZWxvYWRTdWJzY3JpcHRpb24gPSB0aGlzLmRhdGFQcm92aWRlci5nZXRBbGxSZWxvYWQkLnN1YnNjcmliZSh7XG4gICAgICAgICAgICAgICAgbmV4dDogKCkgPT4ge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLnJlbG9hZCgpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgdGhpcy5zdWJzY3JpcHRpb25zLnB1c2gocmVsb2FkU3Vic2NyaXB0aW9uKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIC8vIGlmIHF1ZXJ5IHJlc3VsdCBpcyBwcm92aWRlZCwgdXNlIGl0IGFzIHNlY29uZGFyeSBzb3VyY2Ugb3IgZWxzZSB0cnkgdG8gdXNlIGl0ZW1zXG4gICAgICAgICAgICBpZiAodGhpcy5xdWVyeVJlc3VsdCkge1xuICAgICAgICAgICAgICAgIHRoaXMucXVlcnlSZXN1bHQkID0gdGhpcy5xdWVyeVJlc3VsdCBpbnN0YW5jZW9mIE9ic2VydmFibGUgPyB0aGlzLnF1ZXJ5UmVzdWx0IDogb2YodGhpcy5xdWVyeVJlc3VsdCk7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIHRoaXMucXVlcnlSZXN1bHQkID0gKGlzT2JzZXJ2YWJsZSh0aGlzLml0ZW1zKSA/IHRoaXMuaXRlbXMgOiB0aGlzLml0ZW1zU3ViamVjdC5hc09ic2VydmFibGUoKSkucGlwZShcbiAgICAgICAgICAgICAgICAgICAgLy8gZGlzdGluY3RVbnRpbENoYW5nZWQoKHYxLCB2MikgPT4gdjEubGVuZ3RoID09PSB2Mi5sZW5ndGggJiZcbiAgICAgICAgICAgICAgICAgICAgLy8gICAgIHYxLmV2ZXJ5KCh2MWksIGlkeCkgPT4gdjFpW3RoaXMuZGVzY3JpcHRvci5kYXRhS2V5UHJvcGVydHldID09PSB2MltpZHhdW3RoaXMuZGVzY3JpcHRvci5kYXRhS2V5UHJvcGVydHldKSksXG4gICAgICAgICAgICAgICAgICAgIG1hcChpdGVtcyA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBxdWVyeVJlc3VsdCA9IG5ldyBNZWRpdXNRdWVyeVJlc3VsdDxUPigpO1xuICAgICAgICAgICAgICAgICAgICAgICAgcXVlcnlSZXN1bHQucGFnZURhdGEgPSBpdGVtcztcbiAgICAgICAgICAgICAgICAgICAgICAgIHF1ZXJ5UmVzdWx0LmFsbERhdGFDb3VudCA9IGl0ZW1zLmxlbmd0aDtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBxdWVyeVJlc3VsdDtcbiAgICAgICAgICAgICAgICAgICAgfSlcbiAgICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgICAgIGlmICghaXNPYnNlcnZhYmxlKHRoaXMuaXRlbXMpKSB7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuaXRlbXNTdWJqZWN0Lm5leHQodGhpcy5pdGVtcyA/PyBbXSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKHR5cGVvZiB0aGlzLmxvYWRpbmcgIT09ICd1bmRlZmluZWQnKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5sb2FkaW5nJCA9IHRoaXMubG9hZGluZyBpbnN0YW5jZW9mIE9ic2VydmFibGUgPyB0aGlzLmxvYWRpbmcgOiBvZih0aGlzLmxvYWRpbmcpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgY29uc3QgaW5pdGlhbFF1ZXJ5UGFyYW1NYXAgPSB0aGlzLnJvdXRlLnNuYXBzaG90LnF1ZXJ5UGFyYW1NYXA7XG4gICAgICAgIGlmIChcbiAgICAgICAgICAgIHRoaXMudXNlUXVlcnlQYXJhbXMgJiZcbiAgICAgICAgICAgICgoIWluaXRpYWxRdWVyeVBhcmFtTWFwLmhhcygnc29ydCcpICYmIHRoaXMuZGVzY3JpcHRvcj8uaGFzRGVmYXVsdFNvcnQpIHx8XG4gICAgICAgICAgICAgICAgKCFpbml0aWFsUXVlcnlQYXJhbU1hcC5oYXMoJ2ZpbHRlcicpICYmIHRoaXMuZmlsdGVyRGVzY3JpcHRvcnMuc29tZShmZCA9PiBmZC5oYXNEZWZhdWx0VmFsdWUpKSlcbiAgICAgICAgKSB7XG4gICAgICAgICAgICAvLyBkZWZhdWx0IHNvcnQvZmlsdGVycyBhcmUgYXBwbGllZCwgbm8gYWRkaXRpb25hbCBmaWx0ZXJpbmcvc29ydGluZyBpcyBzcGVjaWZpZWQgaW4gcXVlcnkgcGFyYW1cbiAgICAgICAgICAgIC8vIHJlZGlyZWN0IG11c3QgYmUgZG9uZSBhdCBmaXJzdCBzdGVwXG4gICAgICAgICAgICBjb25zdCBtZWRpdXNRdWVyeVBhcmFtID0gTWVkaXVzUmVzdFV0aWwuZnJvbUFuZ3VsYXJRdWVyeVBhcmFtc1RvTWVkaXVzUXVlcnlQYXJhbXModGhpcy5yb3V0ZS5zbmFwc2hvdC5xdWVyeVBhcmFtcywgdGhpcy5maWx0ZXJEZXNjcmlwdG9ycywgdGhpcy5yb3dzUGVyUGFnZU9wdGlvbnNbMF0pO1xuXG4gICAgICAgICAgICBjb25zdCBldmVudDogTGF6eUxvYWRFdmVudCA9IHt9O1xuICAgICAgICAgICAgZXZlbnQubXVsdGlTb3J0TWV0YSA9IHRoaXMuY3JlYXRlU29ydE1ldGEobWVkaXVzUXVlcnlQYXJhbSk7XG4gICAgICAgICAgICBldmVudC5maWx0ZXJzID0gdGhpcy5jcmVhdGVGaWx0ZXJNZXRhKG1lZGl1c1F1ZXJ5UGFyYW0pO1xuXG4gICAgICAgICAgICAvLyBmaXJzdCBuYXZpZ2F0ZSB0byBjb3JyZWN0IHVybCB3aXRoIGRlZmF1bHQgZmlsdGVycy9zb3J0c1xuICAgICAgICAgICAgdGhpcy5yb3V0ZXJcbiAgICAgICAgICAgICAgICAubmF2aWdhdGUoW10sIHtcbiAgICAgICAgICAgICAgICAgICAgcmVsYXRpdmVUbzogdGhpcy5yb3V0ZSxcbiAgICAgICAgICAgICAgICAgICAgcmVwbGFjZVVybDogdHJ1ZSxcbiAgICAgICAgICAgICAgICAgICAgcXVlcnlQYXJhbXM6IE1lZGl1c1Jlc3RVdGlsLmZyb21QcmltZUxhenlMb2FkRXZlbnRUb0FuZ3VsYXJRdWVyeVBhcmFtcyhldmVudCwgdGhpcy5yb3dzUGVyUGFnZU9wdGlvbnNbMF0pXG4gICAgICAgICAgICAgICAgfSlcbiAgICAgICAgICAgICAgICAudGhlbigoKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuaW5pdGlhbGl6ZURhdGFMb2FkaW5nVHJpZ2dlcnMoKTtcbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHRoaXMuaW5pdGlhbGl6ZURhdGFMb2FkaW5nVHJpZ2dlcnMoKTtcbiAgICAgICAgfVxuXG4gICAgICAgIHRoaXMucXVlcnlSZXN1bHRTdWJzY3JpcHRpb24gPSB0aGlzLnF1ZXJ5UmVzdWx0JC5zdWJzY3JpYmUoZSA9PiAodGhpcy5xdWVyeVJlc3VsdCA9IGUpKTtcbiAgICB9XG5cbiAgICBwdWJsaWMgbmdBZnRlckNvbnRlbnRJbml0KCkge1xuICAgICAgICB0aGlzLnRlbXBsYXRlcy5mb3JFYWNoKHRlbXBsYXRlID0+IHtcbiAgICAgICAgICAgIHN3aXRjaCAodGVtcGxhdGUuZ2V0VHlwZSgpKSB7XG4gICAgICAgICAgICAgICAgY2FzZSAnY2FwdGlvbic6XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuY2FwdGlvblRlbXBsYXRlID0gdGVtcGxhdGUudGVtcGxhdGU7XG4gICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgIGNhc2UgJ2NvbHVtbkFjdGlvbic6XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuY29sdW1uQWN0aW9uVGVtcGxhdGUgPSB0ZW1wbGF0ZS50ZW1wbGF0ZTtcbiAgICAgICAgICAgICAgICAgICAgaWYgKCF0aGlzLnNob3dJbmxpbmVBY3Rpb25zQ29sdW1uKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnNob3dJbmxpbmVBY3Rpb25zQ29sdW1uID0gdHJ1ZTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICBjYXNlICdmb290ZXInOlxuICAgICAgICAgICAgICAgICAgICB0aGlzLmZvb3RlclRlbXBsYXRlID0gdGVtcGxhdGUudGVtcGxhdGU7XG4gICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICB9XG5cbiAgICBuZ09uQ2hhbmdlcyhjaGFuZ2VzOiBTaW1wbGVDaGFuZ2VzKTogdm9pZCB7XG4gICAgICAgIGlmIChjaGFuZ2VzWydpdGVtcyddICYmICFjaGFuZ2VzWydpdGVtcyddLmZpcnN0Q2hhbmdlICYmIEFycmF5LmlzQXJyYXkoY2hhbmdlc1snaXRlbXMnXS5jdXJyZW50VmFsdWUpKSB7XG4gICAgICAgICAgICB0aGlzLml0ZW1zU3ViamVjdC5uZXh0KGNoYW5nZXNbJ2l0ZW1zJ10uY3VycmVudFZhbHVlKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIHB1YmxpYyBuZ09uRGVzdHJveSgpIHtcbiAgICAgICAgdGhpcy5kYXRhUHJvdmlkZXJTdWJzY3JpcHRpb24/LnVuc3Vic2NyaWJlKCk7XG4gICAgICAgIHRoaXMucXVlcnlSZXN1bHRTdWJzY3JpcHRpb24/LnVuc3Vic2NyaWJlKCk7XG4gICAgICAgIHRoaXMuc3Vic2NyaXB0aW9ucy5mb3JFYWNoKHMgPT4gcy51bnN1YnNjcmliZSgpKTtcbiAgICB9XG5cbiAgICBwdWJsaWMgcmVsb2FkKGVtaXRFdmVudCA9IGZhbHNlLCByZXNldFBhcmFtcyA9IGZhbHNlKSB7XG4gICAgICAgIGNvbnN0IHF1ZXJ5UGFyYW1zQnVpbGRlciA9IHJlc2V0UGFyYW1zXG4gICAgICAgICAgICA/IE1lZGl1c1F1ZXJ5UGFyYW1CdWlsZGVyLmNyZWF0ZSh0aGlzLnJvd3NQZXJQYWdlT3B0aW9uc1swXSwgMClcbiAgICAgICAgICAgIDogTWVkaXVzUXVlcnlQYXJhbUJ1aWxkZXIuY3JlYXRlRnJvbUV4aXN0aW5nKHRoaXMuZGF0YVByb3ZpZGVyTGF0ZXN0UXVlcnlQYXJhbSA/PyBuZXcgTWVkaXVzUXVlcnlQYXJhbSgpKVxuICAgICAgICAgICAgICAgICAgLndpdGhJdGVtc1BlclBhZ2UodGhpcy5yb3dzKVxuICAgICAgICAgICAgICAgICAgLndpdGhJdGVtc09mZnNldCh0aGlzLm9mZnNldCk7XG5cbiAgICAgICAgdGhpcy5sb2FkVGFibGVXaXRoRGF0YVByb3ZpZGVyKHF1ZXJ5UGFyYW1zQnVpbGRlci5idWlsZCgpLCBlbWl0RXZlbnQpO1xuICAgIH1cblxuICAgIHB1YmxpYyBvblRhYmxlTGF6eUxvYWQoZXZlbnQ6IExhenlMb2FkRXZlbnQpIHtcbiAgICAgICAgdGhpcy5kYXRhUHJvdmlkZXJMYXRlc3RMYXp5TG9hZEV2ZW50ID0gZXZlbnQ7XG4gICAgICAgIHRoaXMuZGF0YVByb3ZpZGVyTGF0ZXN0TGF6eUxvYWRFdmVudFZlcnNpb24rKztcblxuICAgICAgICBpZiAodGhpcy51c2VRdWVyeVBhcmFtcykge1xuICAgICAgICAgICAgaWYgKCFldmVudC5tdWx0aVNvcnRNZXRhIHx8IGV2ZW50Lm11bHRpU29ydE1ldGEubGVuZ3RoID09PSAwKSB7XG4gICAgICAgICAgICAgICAgLy8gYWRkIGRlZmF1bHQgc29ydCBtZXRhIHRvIGV2ZW50IGlmIG5vdCBtdWx0aXNvcnQgbWV0YSBpcyBwcmVzZW50XG4gICAgICAgICAgICAgICAgZXZlbnQubXVsdGlTb3J0TWV0YSA9IHRoaXMuY3JlYXRlU29ydE1ldGEoKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmICghZXZlbnQuZmlsdGVycykge1xuICAgICAgICAgICAgICAgIGV2ZW50LmZpbHRlcnMgPSB0aGlzLmNyZWF0ZUZpbHRlck1ldGEoKTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgdGhpcy5yb3V0ZXIubmF2aWdhdGUoW10sIHtcbiAgICAgICAgICAgICAgICByZWxhdGl2ZVRvOiB0aGlzLnJvdXRlLFxuICAgICAgICAgICAgICAgIHJlcGxhY2VVcmw6IHRydWUsXG4gICAgICAgICAgICAgICAgcXVlcnlQYXJhbXM6IE1lZGl1c1Jlc3RVdGlsLmZyb21QcmltZUxhenlMb2FkRXZlbnRUb0FuZ3VsYXJRdWVyeVBhcmFtcyhldmVudCwgdGhpcy5yb3dzUGVyUGFnZU9wdGlvbnNbMF0pXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGNvbnN0IG1lZGl1c1F1ZXJ5UGFyYW1zID0gZXZlbnQgPyBNZWRpdXNSZXN0VXRpbC5mcm9tUHJpbWVMYXp5TG9hZEV2ZW50VG9NZWRpdXNRdWVyeVBhcmFtcyhldmVudCkgOiBuZXcgTWVkaXVzUXVlcnlQYXJhbSgpO1xuICAgICAgICAgICAgdGhpcy5sb2FkVGFibGVXaXRoRGF0YVByb3ZpZGVyKG1lZGl1c1F1ZXJ5UGFyYW1zKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tdW51c2VkLXZhcnNcbiAgICBwdWJsaWMgb25UYWJsZVNvcnQoZXZlbnQ6IGFueSkge1xuICAgICAgICB0aGlzLmlzU29ydENoYW5nZWQgPSB0cnVlO1xuICAgIH1cblxuICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tdW51c2VkLXZhcnNcbiAgICBwdWJsaWMgb25UYWJsZUZpbHRlcihldmVudDogYW55KSB7XG4gICAgICAgIHRoaXMuaXNGaWx0ZXJDaGFuZ2VkID0gdHJ1ZTtcbiAgICB9XG5cbiAgICBwdWJsaWMgb25DZWxsQ2xpY2soZXZlbnQ6IEV2ZW50LCBjb2w6IENvbHVtbkRlc2NyaXB0b3I8YW55LCBUPiwgaXRlbTogVCwgaWR4OiBudW1iZXIpIHtcbiAgICAgICAgY29uc3QgbW5nRXZlbnQgPSBuZXcgTW5nVGFibGVDZWxsQ2xpY2tFdmVudDxUPihjb2wsIGl0ZW0sIGlkeCk7XG4gICAgICAgIHRoaXMuY2VsbENsaWNrRXZlbnRFbWl0dGVyLm5leHQobW5nRXZlbnQpO1xuICAgICAgICBpZiAodGhpcy5yb3dDbGlja0FjdGlvbnMubGVuZ3RoKSB7XG4gICAgICAgICAgICBmb3IgKGNvbnN0IGFjdGlvbiBvZiB0aGlzLnJvd0NsaWNrQWN0aW9ucykge1xuICAgICAgICAgICAgICAgIHRoaXMuYWN0aW9uRXhlY3V0b3IudHJpZ2dlclJvd0NsaWNrQWN0aW9uKGFjdGlvbiwgbW5nRXZlbnQsIHRoaXMucm91dGUsIHRoaXMuZGVzY3JpcHRvcik7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBwdWJsaWMgb25TZWxlY3Rpb25DaGFuZ2UoZXZlbnQ6IEFycmF5PFQ+KSB7XG4gICAgICAgIHRoaXMuc2VsZWN0aW9uQ2hhbmdlRXZlbnRFbWl0dGVyLmVtaXQoZXZlbnQpO1xuICAgIH1cblxuICAgIHB1YmxpYyBvbkNhcHRpb25DbXBJbnN0PEM+KGluc3RhbmNlOiBDKSB7XG4gICAgICAgIHRoaXMuY2FwdGlvbkNtcEluc3RFdmVudEVtaXR0ZXIubmV4dChpbnN0YW5jZSk7XG4gICAgfVxuXG4gICAgcHVibGljIG9uQ29sdW1uQWN0aW9uQ21wSW5zdDxDPihpbnN0YW5jZTogQykge1xuICAgICAgICB0aGlzLmNvbHVtbkFjdGlvbkNtcEluc3RFdmVudEVtaXR0ZXIubmV4dChpbnN0YW5jZSk7XG4gICAgfVxuXG4gICAgcHVibGljIG9uQWN0aW9uRmluaXNoKHJ1blJlc3VsdDogQWN0aW9uSW5zdGFuY2U8VCwgdW5rbm93bj4pIHtcbiAgICAgICAgaWYgKCFydW5SZXN1bHQuZXJyb3IpIHtcbiAgICAgICAgICAgIHRoaXMucmVsb2FkKCk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBwcml2YXRlIGxvYWRUYWJsZVdpdGhEYXRhUHJvdmlkZXIocXVlcnlQYXJhbTogTWVkaXVzUXVlcnlQYXJhbSB8IG51bGwgPSBudWxsLCBlbWl0RXZlbnQgPSB0cnVlKSB7XG4gICAgICAgIGlmICghdGhpcy51c2VEYXRhUHJvdmlkZXIpIHtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuXG4gICAgICAgIHRoaXMuZGF0YVByb3ZpZGVyU3Vic2NyaXB0aW9uPy51bnN1YnNjcmliZSgpO1xuICAgICAgICB0aGlzLmRhdGFQcm92aWRlckxvYWRpbmdTdWJqZWN0Lm5leHQodHJ1ZSk7XG5cbiAgICAgICAgaWYgKCFxdWVyeVBhcmFtKSB7XG4gICAgICAgICAgICBxdWVyeVBhcmFtID0gTWVkaXVzUXVlcnlQYXJhbUJ1aWxkZXIuY3JlYXRlKHRoaXMucm93c1BlclBhZ2VPcHRpb25zWzBdKS5idWlsZCgpO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMuZGF0YVByb3ZpZGVyTGF0ZXN0UXVlcnlQYXJhbSA9IHF1ZXJ5UGFyYW07XG4gICAgICAgIHRoaXMuZGF0YVByb3ZpZGVyTGF0ZXN0UXVlcnlQYXJhbVZlcnNpb24rKztcblxuICAgICAgICBNZWRpdXNSZXN0VXRpbC5tb2RpZnlGaWx0ZXJQcm9wZXJ0aWVzKHF1ZXJ5UGFyYW0sIHRoaXMuZmlsdGVyRGVzY3JpcHRvcnMpO1xuXG4gICAgICAgIHRoaXMuZGF0YVByb3ZpZGVyU3Vic2NyaXB0aW9uID0gdGhpcy5kYXRhUHJvdmlkZXI/LmdldEFsbChxdWVyeVBhcmFtLCB0aGlzLmRhdGFQcm92aWRlclNlcnZpY2UpLnN1YnNjcmliZSh7XG4gICAgICAgICAgICBuZXh0OiByZXMgPT4ge1xuICAgICAgICAgICAgICAgIGlmICh0aGlzLmluaXRpYWxEZXNjcmlwdG9yIGluc3RhbmNlb2YgVGFibGVEeW5hbWljRGVzY3JpcHRvcikge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLmRlc2NyaXB0b3IgPSB0aGlzLmluaXRpYWxEZXNjcmlwdG9yLnRvVGFibGVEZXNjcmlwdG9yRnJvbURhdGEocmVzKTtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5maWx0ZXJEZXNjcmlwdG9ycyA9IHRoaXMuZGVzY3JpcHRvci5jb2x1bW5zLmZpbHRlcihjID0+IHR5cGVvZiBjLmZpbHRlckRlc2NyaXB0b3IgIT09ICd1bmRlZmluZWQnKS5tYXAoYyA9PiBjLmZpbHRlckRlc2NyaXB0b3IhKTtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5oYXNDb2x1bW5GaWx0ZXJzID0gdGhpcy5maWx0ZXJEZXNjcmlwdG9ycy5sZW5ndGggPiAwO1xuICAgICAgICAgICAgICAgICAgICAvLyB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAvLyAgICAgdGhpcy5kZXNjcmlwdG9yID0gdGhpcy5pbml0aWFsRGVzY3JpcHRvci5vbkRhdGFSZWNlaXZlZFR5cGVCdWlsZGluZyhyZXMpO1xuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIGlmICh0aGlzLmluZmluaXRlU2Nyb2xsKSB7XG4gICAgICAgICAgICAgICAgICAgIGlmICh0aGlzLmlzRmlsdGVyQ2hhbmdlZCB8fCB0aGlzLmlzU29ydENoYW5nZWQpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuZGF0YVByb3ZpZGVySW5maW5pdGVTY3JvbGxJdGVtcyA9IFtdO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuZGF0YVByb3ZpZGVySW5maW5pdGVTY3JvbGxJdGVtcy5zcGxpY2UocXVlcnlQYXJhbSEuaXRlbXNPZmZzZXQgPz8gMCwgcXVlcnlQYXJhbSEuaXRlbXNQZXJQYWdlID8/IHRoaXMucm93cywgLi4uKHJlcy5wYWdlRGF0YSA/PyBbXSkpO1xuICAgICAgICAgICAgICAgICAgICB0aGlzLmRhdGFQcm92aWRlckluZmluaXRlU2Nyb2xsSXRlbXMgPSBbLi4udGhpcy5kYXRhUHJvdmlkZXJJbmZpbml0ZVNjcm9sbEl0ZW1zXTtcbiAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLmRhdGFQcm92aWRlclF1ZXJ5UmVzdWx0U3ViamVjdC5uZXh0KHJlcyk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHRoaXMuaXNGaWx0ZXJDaGFuZ2VkID0gZmFsc2U7XG4gICAgICAgICAgICAgICAgdGhpcy5pc1NvcnRDaGFuZ2VkID0gZmFsc2U7XG4gICAgICAgICAgICAgICAgdGhpcy5kYXRhUHJvdmlkZXJMb2FkaW5nU3ViamVjdC5uZXh0KGZhbHNlKTtcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBlcnJvcjogZXJyID0+IHtcbiAgICAgICAgICAgICAgICAvLyBUT0RPOiBjaGVjayB3aGF0IGhhcHBlbnMgb24gZXJyb3Igd2l0aCBubyBtb2RlbCBpbmlzaWRlIGRlc2NyaXB0b3JcbiAgICAgICAgICAgICAgICBOb3RpZmljYXRpb25VdGlsLnRhYmxlTm90aWZpY2F0aW9uRXJyb3IodGhpcy50cmFuc2xhdGUsIHRoaXMuZGVzY3JpcHRvciEsIGVyciwgdGhpcy52aWV3Q29udGFpbmVyKTtcbiAgICAgICAgICAgICAgICBjb25zdCBlbXB0eVF1ZXJ5UmVzdWx0ID0gbmV3IE1lZGl1c1F1ZXJ5UmVzdWx0PFQ+KCk7XG4gICAgICAgICAgICAgICAgZW1wdHlRdWVyeVJlc3VsdC5wYWdlRGF0YSA9IFtdO1xuICAgICAgICAgICAgICAgIGVtcHR5UXVlcnlSZXN1bHQuYWxsRGF0YUNvdW50ID0gMDtcbiAgICAgICAgICAgICAgICB0aGlzLmRhdGFQcm92aWRlclF1ZXJ5UmVzdWx0U3ViamVjdC5uZXh0KGVtcHR5UXVlcnlSZXN1bHQpO1xuICAgICAgICAgICAgICAgIHRoaXMuZGF0YVByb3ZpZGVyTG9hZGluZ1N1YmplY3QubmV4dChmYWxzZSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuXG4gICAgICAgIGlmIChlbWl0RXZlbnQpIHtcbiAgICAgICAgICAgIGNvbnN0IG1uZ0V2ZW50ID0gbmV3IE1uZ1RhYmxlTG9hZEV2ZW50KCk7XG4gICAgICAgICAgICBtbmdFdmVudC5vcmlnaW5hbEV2ZW50ID0gdGhpcy5kYXRhUHJvdmlkZXJMYXRlc3RMYXp5TG9hZEV2ZW50ID8/IHVuZGVmaW5lZDtcbiAgICAgICAgICAgIG1uZ0V2ZW50LnF1ZXJ5UGFyYW0gPSBxdWVyeVBhcmFtO1xuICAgICAgICAgICAgdGhpcy5sb2FkRXZlbnRFbWl0dGVyLm5leHQobW5nRXZlbnQpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBsb2FkVGFibGVGcm9tUm91dGVVcGRhdGUocGFyYW1zOiBQYXJhbXMpIHtcbiAgICAgICAgY29uc3QgbWVkaXVzUXVlcnlQYXJhbSA9IE1lZGl1c1Jlc3RVdGlsLmZyb21Bbmd1bGFyUXVlcnlQYXJhbXNUb01lZGl1c1F1ZXJ5UGFyYW1zKHBhcmFtcywgdGhpcy5maWx0ZXJEZXNjcmlwdG9ycywgdGhpcy5yb3dzUGVyUGFnZU9wdGlvbnNbMF0pO1xuICAgICAgICBpZiAodGhpcy5kYXRhUHJvdmlkZXJMYXRlc3RMYXp5TG9hZEV2ZW50VmVyc2lvbiA8IHRoaXMuZGF0YVByb3ZpZGVyTGF0ZXN0UXVlcnlQYXJhbVZlcnNpb24gKyAxKSB7XG4gICAgICAgICAgICAvLyB1cGRhdGUgb25seSBpZiBuZXcgdmVyc2lvbiBmcm9tIHF1ZXJ5IHBhcmFtcyB3aWxsIGJlIGhpZ2hlclxuICAgICAgICAgICAgdGhpcy51cGRhdGVQcmltZVNvcnRBbmRGaWx0ZXIobWVkaXVzUXVlcnlQYXJhbSk7XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy51c2VRdWVyeVBhcmFtc0luaXRpYWxpemVkU3ViZWpjdC5uZXh0KHRydWUpO1xuICAgICAgICB0aGlzLmxvYWRUYWJsZVdpdGhEYXRhUHJvdmlkZXIobWVkaXVzUXVlcnlQYXJhbSk7XG4gICAgfVxuXG4gICAgcHJpdmF0ZSB1cGRhdGVQcmltZVNvcnRBbmRGaWx0ZXIobWVkaXVzUXVlcnlQYXJhbTogTWVkaXVzUXVlcnlQYXJhbSkge1xuICAgICAgICB0aGlzLm11bHRpU29ydE1ldGEgPSB0aGlzLmNyZWF0ZVNvcnRNZXRhKG1lZGl1c1F1ZXJ5UGFyYW0pO1xuICAgICAgICB0aGlzLmZpbHRlck1ldGFkYXRhID0gdGhpcy5jcmVhdGVGaWx0ZXJNZXRhKG1lZGl1c1F1ZXJ5UGFyYW0pO1xuICAgICAgICB0aGlzLnJvd3MgPSBtZWRpdXNRdWVyeVBhcmFtPy5pdGVtc1BlclBhZ2UgPz8gdGhpcy5yb3dzUGVyUGFnZU9wdGlvbnNbMF07XG4gICAgICAgIHRoaXMub2Zmc2V0ID0gbWVkaXVzUXVlcnlQYXJhbT8uaXRlbXNPZmZzZXQgPz8gMDtcbiAgICB9XG5cbiAgICBwcml2YXRlIGNyZWF0ZUZpbHRlck1ldGEobWVkaXVzUXVlcnlQYXJhbT86IE1lZGl1c1F1ZXJ5UGFyYW0pIHtcbiAgICAgICAgbGV0IHBhcmFtczogTWVkaXVzUXVlcnlQYXJhbTtcbiAgICAgICAgaWYgKCFtZWRpdXNRdWVyeVBhcmFtKSB7XG4gICAgICAgICAgICBwYXJhbXMgPSBuZXcgTWVkaXVzUXVlcnlQYXJhbSgpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgcGFyYW1zID0gbWVkaXVzUXVlcnlQYXJhbTtcbiAgICAgICAgfVxuXG4gICAgICAgIGNvbnN0IHByaW1lRmlsdGVyTWV0YToge1tzOiBzdHJpbmddOiBGaWx0ZXJNZXRhZGF0YX0gPSB7fTtcbiAgICAgICAgLy8gaWYgYW55IGZpbHRlciBpcyBwcmVzZW50LCBubyBkZWZhdWx0IGZpbHRlcnMgc2hvdWxkIGJlIGFwcGxpZWQhXG4gICAgICAgIGNvbnN0IGFwcGx5RGVmYXVsdEZpbHRlcnMgPSAocGFyYW1zLmZpbHRlclBhcmFtcz8ubGVuZ3RoID8/IDApID09PSAwO1xuXG4gICAgICAgIHRoaXMuZmlsdGVyRGVzY3JpcHRvcnMuZm9yRWFjaChmID0+IHtcbiAgICAgICAgICAgIGxldCBtYXRjaE1vZGU7XG4gICAgICAgICAgICBpZiAoZi5kZWZhdWx0RmlsdGVyTWF0Y2hNb2RlKSB7XG4gICAgICAgICAgICAgICAgbWF0Y2hNb2RlID0gZi5kZWZhdWx0RmlsdGVyTWF0Y2hNb2RlO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICBzd2l0Y2ggKGYuZmlsdGVyVHlwZSkge1xuICAgICAgICAgICAgICAgICAgICBjYXNlIEZpbHRlclR5cGVFbnVtLlN0cmluZzpcbiAgICAgICAgICAgICAgICAgICAgICAgIG1hdGNoTW9kZSA9IEZpbHRlck1hdGNoTW9kZS5DT05UQUlOUztcbiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgICAgICBjYXNlIEZpbHRlclR5cGVFbnVtLkRhdGU6XG4gICAgICAgICAgICAgICAgICAgICAgICBtYXRjaE1vZGUgPSBGaWx0ZXJNYXRjaE1vZGUuREFURV9JUztcbiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgICAgICBjYXNlIEZpbHRlclR5cGVFbnVtLkxvb2t1cDpcbiAgICAgICAgICAgICAgICAgICAgY2FzZSBGaWx0ZXJUeXBlRW51bS5Mb29rdXBFbnVtOiB7XG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBsb29rdXBGaWx0ZXIgPSBmIGFzIEZpbHRlckxvb2t1cERlc2NyaXB0b3I8YW55PjtcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChsb29rdXBGaWx0ZXIubXVsdGlzZWxlY3QpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBtYXRjaE1vZGUgPSBGaWx0ZXJNYXRjaE1vZGUuSU47XG4gICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1hdGNoTW9kZSA9IEZpbHRlck1hdGNoTW9kZS5FUVVBTFM7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBkZWZhdWx0OlxuICAgICAgICAgICAgICAgICAgICAgICAgbWF0Y2hNb2RlID0gRmlsdGVyTWF0Y2hNb2RlLkVRVUFMUztcbiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgbGV0IHZhbHVlID0gbnVsbDtcbiAgICAgICAgICAgIGlmIChhcHBseURlZmF1bHRGaWx0ZXJzKSB7XG4gICAgICAgICAgICAgICAgaWYgKGYuZGVmYXVsdFZhbHVlVG8gJiYgZi5kZWZhdWx0VmFsdWUpIHtcbiAgICAgICAgICAgICAgICAgICAgdmFsdWUgPSBbZi5kZWZhdWx0VmFsdWUsIGYuZGVmYXVsdFZhbHVlVG9dO1xuICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAoZi5kZWZhdWx0VmFsdWUpIHtcbiAgICAgICAgICAgICAgICAgICAgdmFsdWUgPSBmLmRlZmF1bHRWYWx1ZTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIHByaW1lRmlsdGVyTWV0YVtmLnByb3BlcnR5XSA9IHtcbiAgICAgICAgICAgICAgICB2YWx1ZTogdmFsdWUsXG4gICAgICAgICAgICAgICAgbWF0Y2hNb2RlOiBtYXRjaE1vZGVcbiAgICAgICAgICAgIH07XG4gICAgICAgIH0pO1xuXG4gICAgICAgIHBhcmFtcy5maWx0ZXJQYXJhbXM/LmZvckVhY2goZiA9PiB7XG4gICAgICAgICAgICBjb25zdCBkZXNjcmlwdG9yID0gdGhpcy5maWx0ZXJEZXNjcmlwdG9ycy5maW5kKGZkID0+IGZkLmZpbHRlclByb3BlcnR5ID09PSBmLnByb3BlcnR5IHx8IGZkLnByb3BlcnR5ID09PSBmLnByb3BlcnR5KTtcbiAgICAgICAgICAgIGNvbnN0IG1hdGNoTW9kZSA9IGYuZmlsdGVyTWF0Y2hUeXBlICYmIGRlc2NyaXB0b3IgPyBNZWRpdXNSZXN0VXRpbC5nZXRNYXBwaW5nKGYuZmlsdGVyTWF0Y2hUeXBlLCBkZXNjcmlwdG9yLmZpbHRlclR5cGUsIDIpPy5bMF0gOiBNZWRpdXNGaWx0ZXJNYXRjaFR5cGUuRXF1YWxzO1xuICAgICAgICAgICAgaWYgKGRlc2NyaXB0b3IgJiYgbWF0Y2hNb2RlKSB7XG4gICAgICAgICAgICAgICAgbGV0IGZpbHRlclZhbHVlID0gZi5maWx0ZXJWYWx1ZTtcbiAgICAgICAgICAgICAgICBpZiAoZGVzY3JpcHRvci5maWx0ZXJUeXBlID09PSBGaWx0ZXJUeXBlRW51bS5EYXRlICYmIHR5cGVvZiBmaWx0ZXJWYWx1ZSAhPT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKHR5cGVvZiBmaWx0ZXJWYWx1ZSA9PT0gJ3N0cmluZycgfHwgdHlwZW9mIGZpbHRlclZhbHVlID09PSAnbnVtYmVyJykge1xuICAgICAgICAgICAgICAgICAgICAgICAgZmlsdGVyVmFsdWUgPSBuZXcgRGF0ZShmaWx0ZXJWYWx1ZSk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgLy8gaWYgcmFuZ2UgaXMgcHJvdmlkZWQsIHRha2UgdGhhdCBpbnRvIGFjY291bnRcbiAgICAgICAgICAgICAgICAgICAgaWYgKHR5cGVvZiBmLmZpbHRlclZhbHVlVG8gPT09ICdzdHJpbmcnIHx8IHR5cGVvZiBmLmZpbHRlclZhbHVlVG8gPT09ICdudW1iZXInKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBmaWx0ZXJWYWx1ZVRvID0gbmV3IERhdGUoZi5maWx0ZXJWYWx1ZVRvKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGZpbHRlclZhbHVlID0gW2ZpbHRlclZhbHVlLCBmaWx0ZXJWYWx1ZVRvXTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBwcmltZUZpbHRlck1ldGFbZGVzY3JpcHRvci5wcm9wZXJ0eV0gPSB7XG4gICAgICAgICAgICAgICAgICAgIHZhbHVlOiBmaWx0ZXJWYWx1ZSxcbiAgICAgICAgICAgICAgICAgICAgbWF0Y2hNb2RlOiBtYXRjaE1vZGVcbiAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICAgICAgcmV0dXJuIHByaW1lRmlsdGVyTWV0YTtcbiAgICB9XG5cbiAgICBwcml2YXRlIGNyZWF0ZVNvcnRNZXRhKG1lZGl1c1F1ZXJ5UGFyYW0/OiBNZWRpdXNRdWVyeVBhcmFtKTogU29ydE1ldGFbXSB7XG4gICAgICAgIGxldCBwYXJhbXM6IE1lZGl1c1F1ZXJ5UGFyYW07XG4gICAgICAgIGlmICghbWVkaXVzUXVlcnlQYXJhbSkge1xuICAgICAgICAgICAgcGFyYW1zID0gbmV3IE1lZGl1c1F1ZXJ5UGFyYW0oKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHBhcmFtcyA9IG1lZGl1c1F1ZXJ5UGFyYW07XG4gICAgICAgIH1cblxuICAgICAgICBsZXQgc29ydE1ldGE6IFNvcnRNZXRhW107XG4gICAgICAgIGNvbnN0IGFwcGx5RGVmYXVsdFNvcnRzID0gKHBhcmFtcy5zb3J0UHJvcGVydHk/Lmxlbmd0aCA/PyAwKSA9PT0gMDtcblxuICAgICAgICBpZiAoYXBwbHlEZWZhdWx0U29ydHMgJiYgdGhpcy5kZXNjcmlwdG9yPy5oYXNEZWZhdWx0U29ydCkge1xuICAgICAgICAgICAgc29ydE1ldGEgPSB0aGlzLmRlc2NyaXB0b3IuZGVmYXVsdFNvcnRQcm9wZXJ0eS5tYXAoXG4gICAgICAgICAgICAgICAgKHAsIGlkeCkgPT5cbiAgICAgICAgICAgICAgICAgICAgPFNvcnRNZXRhPntcbiAgICAgICAgICAgICAgICAgICAgICAgIGZpZWxkOiBwLFxuICAgICAgICAgICAgICAgICAgICAgICAgb3JkZXI6IHRoaXMuZGVzY3JpcHRvciEuZGVmYXVsdFNvcnRBc2NbaWR4XSA/IDEgOiAtMVxuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICApO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgc29ydE1ldGEgPSBbXTtcbiAgICAgICAgfVxuXG4gICAgICAgIHBhcmFtcy5zb3J0UHJvcGVydHk/LmZvckVhY2goKHMsIGlkeCkgPT4ge1xuICAgICAgICAgICAgY29uc3QgZXhpc3RpbmdJbmRleCA9IHNvcnRNZXRhLmZpbmRJbmRleCh2YWx1ZSA9PiB2YWx1ZS5maWVsZCA9PT0gcyk7XG4gICAgICAgICAgICBpZiAoZXhpc3RpbmdJbmRleCA+IC0xKSB7XG4gICAgICAgICAgICAgICAgc29ydE1ldGFbZXhpc3RpbmdJbmRleF0ub3JkZXIgPSBwYXJhbXMuc29ydEFzYz8uW2lkeF0gPz8gdHJ1ZSA/IDEgOiAtMTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgc29ydE1ldGEucHVzaCh7XG4gICAgICAgICAgICAgICAgICAgIGZpZWxkOiBzLFxuICAgICAgICAgICAgICAgICAgICBvcmRlcjogcGFyYW1zLnNvcnRBc2M/LltpZHhdID8/IHRydWUgPyAxIDogLTFcbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG5cbiAgICAgICAgcmV0dXJuIHNvcnRNZXRhO1xuICAgIH1cblxuICAgIHByaXZhdGUgaW5pdGlhbGl6ZURhdGFMb2FkaW5nVHJpZ2dlcnMoKSB7XG4gICAgICAgIGlmICh0aGlzLnVzZVF1ZXJ5UGFyYW1zKSB7XG4gICAgICAgICAgICAvLyB0cmlnZ2VyIHRhYmxlIGxvYWRzIGZyb20gcm91dGUgdXBkYXRlc1xuICAgICAgICAgICAgY29uc3Qgc3Vic2NyaXB0aW9uID0gdGhpcy5yb3V0ZS5xdWVyeVBhcmFtcy5zdWJzY3JpYmUocXAgPT4ge1xuICAgICAgICAgICAgICAgIHRoaXMubG9hZFRhYmxlRnJvbVJvdXRlVXBkYXRlKHFwKTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgdGhpcy5zdWJzY3JpcHRpb25zLnB1c2goc3Vic2NyaXB0aW9uKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIC8vIGxvYWQgZGF0YSBpbW1lZGlhdGVseSBieSBjcmVhdGluZyBkZWZhdWx0IHNvcnRzIGFuZCBmaWx0ZXJzIChwcmltZW5nIHdpbGwgdHJpZ2dlciBvbkxhenlMb2FkIGV2ZW50IG9uIHNvcnQmZmlsdGVyIG1ldGFkYXRhIGNoYW5nZSlcbiAgICAgICAgICAgIGNvbnN0IGRlZmF1bHRTb3J0ID0gdGhpcy5jcmVhdGVTb3J0TWV0YSgpO1xuICAgICAgICAgICAgaWYgKGRlZmF1bHRTb3J0Lmxlbmd0aCA+IDApIHtcbiAgICAgICAgICAgICAgICB0aGlzLm11bHRpU29ydE1ldGEgPSBkZWZhdWx0U29ydDtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgY29uc3QgZGVmYXVsdEZpbHRlciA9IHRoaXMuY3JlYXRlRmlsdGVyTWV0YSgpO1xuICAgICAgICAgICAgaWYgKGRlZmF1bHRGaWx0ZXIpIHtcbiAgICAgICAgICAgICAgICB0aGlzLmZpbHRlck1ldGFkYXRhID0gZGVmYXVsdEZpbHRlcjtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH1cbn1cbiIsIjxkaXYgW3N0eWxlLmhlaWdodF09XCJ0YWJsZUZ1bGxIZWlnaHRPZmZzZXQgPyAnY2FsYygxMDB2aCAtICcgKyB0YWJsZUZ1bGxIZWlnaHRPZmZzZXQgKyAncHgpJyA6IG51bGxcIj5cbiAgICA8IS0tIE1VU1QgTk9UIHVzZSBvYnNlcnZhYmxlIGZvciB2YWx1ZSB3aGVuIHVzaW5nIHZpcnR1YWwgc2Nyb2xsIC0gZG9lcyBub3Qgd29yayBmb3Igc29tZSByZWFzb24gLS0+XG4gICAgPHAtdGFibGVcbiAgICAgICAgKm5nSWY9XCIhdXNlUXVlcnlQYXJhbXMgfHwgKHVzZVF1ZXJ5UGFyYW1zSW5pdGlhbGl6ZWQkIHwgYXN5bmMpXCJcbiAgICAgICAgW3ZhbHVlXT1cImluZmluaXRlU2Nyb2xsID8gZGF0YVByb3ZpZGVySW5maW5pdGVTY3JvbGxJdGVtcyA6IChxdWVyeVJlc3VsdCQgfCBhc3luYyk/LnBhZ2VEYXRhID8/IFtdXCJcbiAgICAgICAgW2RhdGFLZXldPVwiJGFueShkZXNjcmlwdG9yPy5kYXRhS2V5UHJvcGVydHkgPz8gbnVsbClcIlxuICAgICAgICBbbGF6eV09XCJpc0xhenlcIlxuICAgICAgICBbbG9hZGluZ109XCIobG9hZGluZyQgfCBhc3luYykgPz8gZmFsc2VcIlxuICAgICAgICBbcGFnaW5hdG9yXT1cImlzUGFnaW5hdGlvbiAmJiAhaW5maW5pdGVTY3JvbGxcIlxuICAgICAgICBbcm93c109XCIkYW55KGluZmluaXRlU2Nyb2xsID8gMjAgOiByb3dzKVwiXG4gICAgICAgIFtmaXJzdF09XCIkYW55KGluZmluaXRlU2Nyb2xsID8gMCA6IG9mZnNldClcIlxuICAgICAgICBbdG90YWxSZWNvcmRzXT1cIiRhbnkoaW5maW5pdGVTY3JvbGwgPyBudWxsIDogKHF1ZXJ5UmVzdWx0JCB8IGFzeW5jKT8uYWxsRGF0YUNvdW50ID8/IDApXCJcbiAgICAgICAgW3Jvd3NQZXJQYWdlT3B0aW9uc109XCIkYW55KGluZmluaXRlU2Nyb2xsID8gbnVsbCA6IHJvd3NQZXJQYWdlT3B0aW9ucylcIlxuICAgICAgICBbc2hvd0N1cnJlbnRQYWdlUmVwb3J0XT1cIiFpbmZpbml0ZVNjcm9sbFwiXG4gICAgICAgIFtjdXJyZW50UGFnZVJlcG9ydFRlbXBsYXRlXT1cIidtbmdUYWJsZS5wYWdpbmF0aW9uTXNnJyB8IHRyYW5zbGF0ZVwiXG4gICAgICAgIFttdWx0aVNvcnRNZXRhXT1cIiRhbnkobXVsdGlTb3J0TWV0YSlcIlxuICAgICAgICBbZmlsdGVyc109XCJmaWx0ZXJNZXRhZGF0YVwiXG4gICAgICAgIHNvcnRNb2RlPVwibXVsdGlwbGVcIlxuICAgICAgICBbKHNlbGVjdGlvbildPVwic2VsZWN0aW9uXCJcbiAgICAgICAgKHNlbGVjdGlvbkNoYW5nZSk9XCJvblNlbGVjdGlvbkNoYW5nZSgkZXZlbnQpXCJcbiAgICAgICAgW3NlbGVjdGlvbk1vZGVdPVwiJGFueShzZWxlY3Rpb25FbmFibGVkID8gc2VsZWN0aW9uTW9kZSA6IG51bGwpXCJcbiAgICAgICAgW3Njcm9sbGFibGVdPVwidHJ1ZVwiXG4gICAgICAgIFt2aXJ0dWFsU2Nyb2xsXT1cImluZmluaXRlU2Nyb2xsXCJcbiAgICAgICAgW3ZpcnR1YWxTY3JvbGxJdGVtU2l6ZV09XCIkYW55KHJvd0hlaWdodClcIlxuICAgICAgICBzY3JvbGxIZWlnaHQ9XCJmbGV4XCJcbiAgICAgICAgW3Jvd0hvdmVyXT1cImRlc2NyaXB0b3I/Lmhhc0hvdmVyID8/IHRydWVcIlxuICAgICAgICBbc3R5bGVDbGFzc109XCJjbGFzc05hbWVcIlxuICAgICAgICAob25MYXp5TG9hZCk9XCJvblRhYmxlTGF6eUxvYWQoJGV2ZW50KVwiXG4gICAgICAgIChvblNvcnQpPVwib25UYWJsZVNvcnQoJGV2ZW50KVwiXG4gICAgICAgIChvbkZpbHRlcik9XCJvblRhYmxlRmlsdGVyKCRldmVudClcIj5cbiAgICAgICAgPG5nLXRlbXBsYXRlICpuZ0lmPVwiY2FwdGlvblRlbXBsYXRlIHx8IGNhcHRpb25Db21wb25lbnQgfHwgZGVzY3JpcHRvcj8udGl0bGVcIiBwVGVtcGxhdGU9XCJjYXB0aW9uXCI+XG4gICAgICAgICAgICA8bmctY29udGFpbmVyICpuZ0lmPVwiY2FwdGlvblRlbXBsYXRlOyBlbHNlIGNvbXBvbmVudE9yRGVmYXVsdENhcHRpb25cIj5cbiAgICAgICAgICAgICAgICA8bmctY29udGFpbmVyICpuZ1RlbXBsYXRlT3V0bGV0PVwiY2FwdGlvblRlbXBsYXRlXCI+PC9uZy1jb250YWluZXI+XG4gICAgICAgICAgICA8L25nLWNvbnRhaW5lcj5cbiAgICAgICAgICAgIDxuZy10ZW1wbGF0ZSAjY29tcG9uZW50T3JEZWZhdWx0Q2FwdGlvbj5cbiAgICAgICAgICAgICAgICA8ZGl2ICpuZ0lmPVwiY2FwdGlvbkNvbXBvbmVudDsgZWxzZSBkZWZhdWx0Q2FwdGlvblwiIFttbmdDb21wb25lbnRdPVwiY2FwdGlvbkNvbXBvbmVudFwiIChpbnN0YW5jZUNyZWF0ZWQpPVwib25DYXB0aW9uQ21wSW5zdCgkZXZlbnQpXCI+PC9kaXY+XG4gICAgICAgICAgICAgICAgPG5nLXRlbXBsYXRlICNkZWZhdWx0Q2FwdGlvbj5cbiAgICAgICAgICAgICAgICAgICAgPGg1IGNsYXNzPVwicC0wIG0tMFwiPnt7IGRlc2NyaXB0b3I/LnRpdGxlIH19PC9oNT5cbiAgICAgICAgICAgICAgICA8L25nLXRlbXBsYXRlPlxuICAgICAgICAgICAgPC9uZy10ZW1wbGF0ZT5cbiAgICAgICAgPC9uZy10ZW1wbGF0ZT5cblxuICAgICAgICA8bmctdGVtcGxhdGUgcFRlbXBsYXRlPVwiaGVhZGVyXCI+XG4gICAgICAgICAgICA8dHIgKm5nSWY9XCIhZGVzY3JpcHRvcj8uaGlkZUhlYWRlclwiIGNsYXNzPVwibW5nLXRhYmxlLWhlYWRlclwiIFtjbGFzc109XCJkZXNjcmlwdG9yPy5oZWFkZXJDbGFzc05hbWVcIj5cbiAgICAgICAgICAgICAgICA8dGggKm5nSWY9XCJzZWxlY3Rpb25FbmFibGVkICYmIHNlbGVjdGlvbk1vZGUgPT09ICdtdWx0aXBsZSdcIiBzdHlsZT1cIm1pbi13aWR0aDogMzZweFwiIHBGcm96ZW5Db2x1bW4+XG4gICAgICAgICAgICAgICAgICAgIDxwLXRhYmxlSGVhZGVyQ2hlY2tib3g+PC9wLXRhYmxlSGVhZGVyQ2hlY2tib3g+XG4gICAgICAgICAgICAgICAgPC90aD5cbiAgICAgICAgICAgICAgICA8IS0tIFdlIG5lZWQgdGhlIGxpbmUgYmVsb3csIGJlY2F1c2Ugb3RoZXJ3aXNlIHAtdGFibGVSYWRpb0J1dHRvbiBzaGlmdHMgdGhlIHJlc3Qgb2YgdGhlIGNvbHVtbnMgaW4gdGFibGUgLS0+XG4gICAgICAgICAgICAgICAgPHRoICpuZ0lmPVwic2VsZWN0aW9uRW5hYmxlZCAmJiBzZWxlY3Rpb25Nb2RlID09PSAnc2luZ2xlJ1wiIHN0eWxlPVwibWluLXdpZHRoOiAzNnB4XCIgcEZyb3plbkNvbHVtbj48L3RoPlxuICAgICAgICAgICAgICAgIDxuZy1jb250YWluZXIgKm5nRm9yPVwibGV0IGNvbCBvZiBkZXNjcmlwdG9yPy5jb2x1bW5zXCI+XG4gICAgICAgICAgICAgICAgICAgIDx0aFxuICAgICAgICAgICAgICAgICAgICAgICAgKm5nSWY9XCJjb2wuaXNTb3J0RW5hYmxlZFwiXG4gICAgICAgICAgICAgICAgICAgICAgICBbcFNvcnRhYmxlQ29sdW1uXT1cImNvbC5wcm9wZXJ0eVwiXG4gICAgICAgICAgICAgICAgICAgICAgICBbc3R5bGUud2lkdGguJV09XCJjb2wud2lkdGhcIlxuICAgICAgICAgICAgICAgICAgICAgICAgW3N0eWxlLm1pbi13aWR0aC5weF09XCJjb2wubWluV2lkdGhcIlxuICAgICAgICAgICAgICAgICAgICAgICAgW3N0eWxlLm1heC13aWR0aC5weF09XCJjb2wubWF4V2lkdGhcIlxuICAgICAgICAgICAgICAgICAgICAgICAgW2NsYXNzXT1cIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbC5oZWFkZXJDbGFzc05hbWUgK1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIChkZXNjcmlwdG9yPy5maWx0ZXJEaXNwbGF5ID09PSBmaWx0ZXJEaXNwbGF5Um93ICYmIGhhc0NvbHVtbkZpbHRlcnMgJiYgY29sLmZpbHRlckRlc2NyaXB0b3JcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPyAnIG1uZy1jb2x1bW4tZmlsdGVyLScgKyBjb2wuZmlsdGVyRGVzY3JpcHRvci5maWx0ZXJUeXBlXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDogJycpXG4gICAgICAgICAgICAgICAgICAgICAgICBcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJmbGV4IGp1c3RpZnktY29udGVudC1iZXR3ZWVuIGFsaWduLWl0ZW1zLWNlbnRlclwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHt7IGNvbC50aXRsZSA/PyAoY29sLnByb3BlcnR5IHwgaTE4blByb3BlcnR5OiBkZXNjcmlwdG9yIS5tb2RlbCkgfCB0cmFuc2xhdGUgfX1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8cC1zb3J0SWNvbiBbZmllbGRdPVwiY29sLnByb3BlcnR5XCI+PC9wLXNvcnRJY29uPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxtbmctdGFibGUtY29sdW1uLWZpbHRlclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqbmdJZj1cImNvbC5maWx0ZXJEZXNjcmlwdG9yICYmIGRlc2NyaXB0b3IhLmZpbHRlckRpc3BsYXkgPT09IGZpbHRlckRpc3BsYXlNZW51XCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2xhc3M9XCJtbC1hdXRvXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW2Rpc3BsYXldPVwiZGVzY3JpcHRvciEuZmlsdGVyRGlzcGxheVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtkZXNjcmlwdG9yXT1cImNvbC5maWx0ZXJEZXNjcmlwdG9yXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9tbmctdGFibGUtY29sdW1uLWZpbHRlcj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICAgICA8L3RoPlxuICAgICAgICAgICAgICAgICAgICA8dGhcbiAgICAgICAgICAgICAgICAgICAgICAgICpuZ0lmPVwiIWNvbC5pc1NvcnRFbmFibGVkXCJcbiAgICAgICAgICAgICAgICAgICAgICAgIFtzdHlsZS53aWR0aC4lXT1cImNvbC53aWR0aFwiXG4gICAgICAgICAgICAgICAgICAgICAgICBbc3R5bGUubWluLXdpZHRoLnB4XT1cImNvbC5taW5XaWR0aFwiXG4gICAgICAgICAgICAgICAgICAgICAgICBbc3R5bGUubWF4LXdpZHRoLnB4XT1cImNvbC5tYXhXaWR0aFwiXG4gICAgICAgICAgICAgICAgICAgICAgICBbY2xhc3NdPVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY29sLmhlYWRlckNsYXNzTmFtZSArXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgKGRlc2NyaXB0b3I/LmZpbHRlckRpc3BsYXkgPT09IGZpbHRlckRpc3BsYXlSb3cgJiYgaGFzQ29sdW1uRmlsdGVycyAmJiBjb2wuZmlsdGVyRGVzY3JpcHRvclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA/ICcgbW5nLWNvbHVtbi1maWx0ZXItJyArIGNvbC5maWx0ZXJEZXNjcmlwdG9yLmZpbHRlclR5cGVcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgOiAnJylcbiAgICAgICAgICAgICAgICAgICAgICAgIFwiPlxuICAgICAgICAgICAgICAgICAgICAgICAge3sgY29sLnRpdGxlID8/IChjb2wucHJvcGVydHkgfCBpMThuUHJvcGVydHk6IGRlc2NyaXB0b3IhLm1vZGVsKSB8IHRyYW5zbGF0ZSB9fVxuICAgICAgICAgICAgICAgICAgICAgICAgPG5nLWNvbnRhaW5lcj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8bW5nLXRhYmxlLWNvbHVtbi1maWx0ZXJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKm5nSWY9XCJjb2wuZmlsdGVyRGVzY3JpcHRvciAmJiBkZXNjcmlwdG9yIS5maWx0ZXJEaXNwbGF5ID09PSBmaWx0ZXJEaXNwbGF5TWVudVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNsYXNzPVwibWwtYXV0b1wiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtkaXNwbGF5XT1cImRlc2NyaXB0b3IhLmZpbHRlckRpc3BsYXlcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbZGVzY3JpcHRvcl09XCJjb2wuZmlsdGVyRGVzY3JpcHRvclwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvbW5nLXRhYmxlLWNvbHVtbi1maWx0ZXI+XG4gICAgICAgICAgICAgICAgICAgICAgICA8L25nLWNvbnRhaW5lcj5cbiAgICAgICAgICAgICAgICAgICAgPC90aD5cbiAgICAgICAgICAgICAgICA8L25nLWNvbnRhaW5lcj5cbiAgICAgICAgICAgICAgICA8dGggKm5nSWY9XCJzaG93SW5saW5lQWN0aW9uc0NvbHVtblwiIFtzdHlsZS5taW4td2lkdGgucHhdPVwiY29sdW1uQWN0aW9uTWluV2lkdGhcIiBwRnJvemVuQ29sdW1uPjwvdGg+XG4gICAgICAgICAgICA8L3RyPlxuICAgICAgICAgICAgPHRyICpuZ0lmPVwiZGVzY3JpcHRvcj8uZmlsdGVyRGlzcGxheSA9PT0gZmlsdGVyRGlzcGxheVJvdyAmJiBoYXNDb2x1bW5GaWx0ZXJzXCIgY2xhc3M9XCJtbmctY29sdW1uLWZpbHRlci1yb3dcIj5cbiAgICAgICAgICAgICAgICA8IS0tIFdlIG5lZWQgdGhlIGxpbmUgYmVsb3csIGJlY2F1c2Ugb3RoZXJ3aXNlIHAtdGFibGVSYWRpb0J1dHRvbiBzaGlmdHMgdGhlIHJlc3Qgb2YgdGhlIGNvbHVtbnMgaW4gdGFibGUgLS0+XG4gICAgICAgICAgICAgICAgPHRoICpuZ0lmPVwic2VsZWN0aW9uRW5hYmxlZCAmJiBzZWxlY3Rpb25Nb2RlID09PSAnc2luZ2xlJ1wiIHN0eWxlPVwibWluLXdpZHRoOiAzNnB4XCIgcEZyb3plbkNvbHVtbj48L3RoPlxuICAgICAgICAgICAgICAgIDx0aFxuICAgICAgICAgICAgICAgICAgICAqbmdGb3I9XCJsZXQgY29sIG9mIGRlc2NyaXB0b3I/LmNvbHVtbnNcIlxuICAgICAgICAgICAgICAgICAgICBbY2xhc3NdPVwiKGNvbC5maWx0ZXJEZXNjcmlwdG9yID8gJ21uZy1jb2x1bW4tZmlsdGVyLScgKyBjb2wuZmlsdGVyRGVzY3JpcHRvci5maWx0ZXJUeXBlICsgJyAnIDogJyAnKSArIGNvbC5maWx0ZXJEZXNjcmlwdG9yPy5jb2x1bW5DbGFzc05hbWVcIlxuICAgICAgICAgICAgICAgICAgICBbc3R5bGUud2lkdGguJV09XCJjb2wuZmlsdGVyRGVzY3JpcHRvcj8uY29sdW1uV2lkdGggPz8gY29sLndpZHRoXCJcbiAgICAgICAgICAgICAgICAgICAgW3N0eWxlLm1pbi13aWR0aC5weF09XCJjb2wuZmlsdGVyRGVzY3JpcHRvcj8uY29sdW1uTWluV2lkdGggPz8gY29sLm1pbldpZHRoXCJcbiAgICAgICAgICAgICAgICAgICAgW3N0eWxlLm1heC13aWR0aC5weF09XCJjb2wubWF4V2lkdGhcIj5cbiAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImZsZXhcIiAqbmdJZj1cImNvbC5maWx0ZXJEZXNjcmlwdG9yXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICA8bW5nLXRhYmxlLWNvbHVtbi1maWx0ZXIgW2Rpc3BsYXldPVwiZGVzY3JpcHRvciEuZmlsdGVyRGlzcGxheVwiIFtkZXNjcmlwdG9yXT1cImNvbC5maWx0ZXJEZXNjcmlwdG9yXCI+PC9tbmctdGFibGUtY29sdW1uLWZpbHRlcj5cbiAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgPC90aD5cbiAgICAgICAgICAgICAgICA8dGggKm5nSWY9XCJzaG93SW5saW5lQWN0aW9uc0NvbHVtblwiIFtzdHlsZS5taW4td2lkdGgucHhdPVwiY29sdW1uQWN0aW9uTWluV2lkdGhcIiBwRnJvemVuQ29sdW1uPjwvdGg+XG4gICAgICAgICAgICA8L3RyPlxuICAgICAgICA8L25nLXRlbXBsYXRlPlxuXG4gICAgICAgIDxuZy10ZW1wbGF0ZSBwVGVtcGxhdGU9XCJib2R5XCIgbGV0LWl0ZW0gbGV0LWlkeD1cInJvd0luZGV4XCI+XG4gICAgICAgICAgICA8dHIgW3N0eWxlLmhlaWdodC5weF09XCJyb3dIZWlnaHRcIiBbY2xhc3NdPVwiZGVzY3JpcHRvcj8ucm93Q2xhc3NOYW1lIHwgbW5nQ2xhc3NNYXBQaXBlOiBkZXNjcmlwdG9yPy5yb3dDbGFzc05hbWVNYXBGbjppdGVtXCI+XG4gICAgICAgICAgICAgICAgPHRkICpuZ0lmPVwic2VsZWN0aW9uRW5hYmxlZCAmJiBzZWxlY3Rpb25Nb2RlID09PSAnbXVsdGlwbGUnXCIgc3R5bGU9XCJtaW4td2lkdGg6IDM2cHhcIiBwRnJvemVuQ29sdW1uPlxuICAgICAgICAgICAgICAgICAgICA8cC10YWJsZUNoZWNrYm94IFt2YWx1ZV09XCJpdGVtXCI+PC9wLXRhYmxlQ2hlY2tib3g+XG4gICAgICAgICAgICAgICAgPC90ZD5cbiAgICAgICAgICAgICAgICA8dGQgKm5nSWY9XCJzZWxlY3Rpb25FbmFibGVkICYmIHNlbGVjdGlvbk1vZGUgPT09ICdzaW5nbGUnXCIgc3R5bGU9XCJtaW4td2lkdGg6IDM2cHhcIiBwRnJvemVuQ29sdW1uPlxuICAgICAgICAgICAgICAgICAgICA8cC10YWJsZVJhZGlvQnV0dG9uIFt2YWx1ZV09XCJpdGVtXCI+PC9wLXRhYmxlUmFkaW9CdXR0b24+XG4gICAgICAgICAgICAgICAgPC90ZD5cbiAgICAgICAgICAgICAgICA8dGRcbiAgICAgICAgICAgICAgICAgICAgKm5nRm9yPVwibGV0IGNvbCBvZiBkZXNjcmlwdG9yPy5jb2x1bW5zXCJcbiAgICAgICAgICAgICAgICAgICAgKGNsaWNrKT1cIm9uQ2VsbENsaWNrKCRldmVudCwgY29sLCBpdGVtLCBpZHgpXCJcbiAgICAgICAgICAgICAgICAgICAgW2NsYXNzXT1cIlxuICAgICAgICAgICAgICAgICAgICAgICAgY29sLmNsYXNzTmFtZSArXG4gICAgICAgICAgICAgICAgICAgICAgICAoZGVzY3JpcHRvcj8uZmlsdGVyRGlzcGxheSA9PT0gZmlsdGVyRGlzcGxheVJvdyAmJiBoYXNDb2x1bW5GaWx0ZXJzICYmIGNvbC5maWx0ZXJEZXNjcmlwdG9yID8gJyBtbmctY29sdW1uLWZpbHRlci0nICsgY29sLmZpbHRlckRlc2NyaXB0b3IuZmlsdGVyVHlwZSA6ICcnKVxuICAgICAgICAgICAgICAgICAgICBcIlxuICAgICAgICAgICAgICAgICAgICBbY2xhc3MuY2xpY2thYmxlXT1cImlzQ29sdW1uQ2xpY2thYmxlXCJcbiAgICAgICAgICAgICAgICAgICAgW3N0eWxlLndpZHRoLiVdPVwiY29sLndpZHRoXCJcbiAgICAgICAgICAgICAgICAgICAgW3N0eWxlLm1pbi13aWR0aC5weF09XCJjb2wubWluV2lkdGhcIlxuICAgICAgICAgICAgICAgICAgICBbc3R5bGUubWF4LXdpZHRoLnB4XT1cImNvbC5tYXhXaWR0aFwiPlxuICAgICAgICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cInAtY29sdW1uLXRpdGxlXCI+e3sgY29sLnRpdGxlID8/IChjb2wucHJvcGVydHkgfCBpMThuUHJvcGVydHk6IGRlc2NyaXB0b3IhLm1vZGVsKSB8IHRyYW5zbGF0ZSB9fTwvc3Bhbj5cbiAgICAgICAgICAgICAgICAgICAgPG1uZy10YWJsZS1jb2x1bW4tdmFsdWUgW2Rlc2NyaXB0b3JdPVwiY29sXCIgW2l0ZW1dPVwiaXRlbVwiPjwvbW5nLXRhYmxlLWNvbHVtbi12YWx1ZT5cbiAgICAgICAgICAgICAgICA8L3RkPlxuICAgICAgICAgICAgICAgIDx0ZFxuICAgICAgICAgICAgICAgICAgICAqbmdJZj1cInNob3dJbmxpbmVBY3Rpb25zQ29sdW1uXCJcbiAgICAgICAgICAgICAgICAgICAgY2xhc3M9XCJjb2x1bW4tYWN0aW9uIGp1c3RpZnktY29udGVudC1lbmQgdGV4dC1yaWdodFwiXG4gICAgICAgICAgICAgICAgICAgIFtzdHlsZS5taW4td2lkdGgucHhdPVwiY29sdW1uQWN0aW9uTWluV2lkdGhcIlxuICAgICAgICAgICAgICAgICAgICBwRnJvemVuQ29sdW1uXG4gICAgICAgICAgICAgICAgICAgIGFsaWduRnJvemVuPVwicmlnaHRcIj5cbiAgICAgICAgICAgICAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdJZj1cImNvbHVtbkFjdGlvblRlbXBsYXRlOyBlbHNlIHNob3dDb2x1bW5BY3Rpb25Db21wb25lbnRPckRlZmF1bHRcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDxuZy1jb250YWluZXIgKm5nVGVtcGxhdGVPdXRsZXQ9XCJjb2x1bW5BY3Rpb25UZW1wbGF0ZTsgY29udGV4dDoge3Jvd0l0ZW06IGl0ZW0sIHJvd0luZGV4OiBpZHh9XCI+PC9uZy1jb250YWluZXI+XG4gICAgICAgICAgICAgICAgICAgIDwvbmctY29udGFpbmVyPlxuICAgICAgICAgICAgICAgICAgICA8bmctdGVtcGxhdGUgI3Nob3dDb2x1bW5BY3Rpb25Db21wb25lbnRPckRlZmF1bHQ+XG4gICAgICAgICAgICAgICAgICAgICAgICA8c3BhblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICpuZ0lmPVwiY29sdW1uQWN0aW9uQ29tcG9uZW50OyBlbHNlIGRlZmF1bHRDb2x1bW5BY3Rpb25zXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBbbW5nQ29tcG9uZW50XT1cImNvbHVtbkFjdGlvbkNvbXBvbmVudCFcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIChpbnN0YW5jZUNyZWF0ZWQpPVwib25Db2x1bW5BY3Rpb25DbXBJbnN0KCRldmVudClcIj48L3NwYW4+XG4gICAgICAgICAgICAgICAgICAgIDwvbmctdGVtcGxhdGU+XG4gICAgICAgICAgICAgICAgICAgIDxuZy10ZW1wbGF0ZSAjZGVmYXVsdENvbHVtbkFjdGlvbnM+XG4gICAgICAgICAgICAgICAgICAgICAgICA8bW5nLWFjdGlvblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICpuZ0Zvcj1cImxldCBhY3Rpb24gb2Ygcm93SW5saW5lQWN0aW9uc1wiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgW2FjdGlvbl09XCJhY3Rpb25cIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtpdGVtXT1cIml0ZW1cIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtpdGVtSWRdPVwiZGVzY3JpcHRvcj8ubW9kZWw/LmlkUHJvcGVydHlOYW1lID8gaXRlbVtkZXNjcmlwdG9yIS5tb2RlbCEuaWRQcm9wZXJ0eU5hbWUhXSA6IG51bGxcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIFthY3Rpb25EYXRhXT1cIntpdGVtSW5kZXg6IGlkeH1cIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIChmaW5pc2gpPVwib25BY3Rpb25GaW5pc2goJGV2ZW50KVwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgPC9tbmctYWN0aW9uPlxuICAgICAgICAgICAgICAgICAgICA8L25nLXRlbXBsYXRlPlxuICAgICAgICAgICAgICAgIDwvdGQ+XG4gICAgICAgICAgICA8L3RyPlxuICAgICAgICA8L25nLXRlbXBsYXRlPlxuXG4gICAgICAgIDxuZy10ZW1wbGF0ZSBwVGVtcGxhdGU9XCJsb2FkaW5nYm9keVwiPlxuICAgICAgICAgICAgPHRyIFtzdHlsZS5oZWlnaHQucHhdPVwicm93SGVpZ2h0XCI+XG4gICAgICAgICAgICAgICAgPHRkIFthdHRyLmNvbHNwYW5dPVwiKGRlc2NyaXB0b3I/LmNvbHVtbnM/Lmxlbmd0aCA/PyAwKSArIChzaG93SW5saW5lQWN0aW9uc0NvbHVtbiA/IDEgOiAwKSArIChzZWxlY3Rpb25FbmFibGVkID8gMSA6IDApXCI+XG4gICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJsb2FkaW5nLXRleHRcIj48L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgPHAtc2tlbGV0b24gW25nU3R5bGVdPVwie3dpZHRoOiAnMTAwJSd9XCI+PC9wLXNrZWxldG9uPlxuICAgICAgICAgICAgICAgIDwvdGQ+XG4gICAgICAgICAgICA8L3RyPlxuICAgICAgICA8L25nLXRlbXBsYXRlPlxuXG4gICAgICAgIDxuZy10ZW1wbGF0ZSBwVGVtcGxhdGU9XCJlbXB0eW1lc3NhZ2VcIj5cbiAgICAgICAgICAgIDx0ciBbc3R5bGUuaGVpZ2h0LnB4XT1cInJvd0hlaWdodFwiPlxuICAgICAgICAgICAgICAgIDx0ZCBbYXR0ci5jb2xzcGFuXT1cIihkZXNjcmlwdG9yPy5jb2x1bW5zPy5sZW5ndGggPz8gMCkgKyAoc2hvd0lubGluZUFjdGlvbnNDb2x1bW4gPyAxIDogMCkgKyAoc2VsZWN0aW9uRW5hYmxlZCA/IDEgOiAwKVwiPlxuICAgICAgICAgICAgICAgICAgICB7eyAnbW5nVGFibGUubm9JdGVtcycgfCB0cmFuc2xhdGUgfX1cbiAgICAgICAgICAgICAgICA8L3RkPlxuICAgICAgICAgICAgPC90cj5cbiAgICAgICAgPC9uZy10ZW1wbGF0ZT5cblxuICAgICAgICA8bmctdGVtcGxhdGUgKm5nSWY9XCJmb290ZXJUZW1wbGF0ZVwiIHBUZW1wbGF0ZT1cInN1bW1hcnlcIj5cbiAgICAgICAgICAgIDxuZy1jb250YWluZXIgW25nVGVtcGxhdGVPdXRsZXRdPVwiZm9vdGVyVGVtcGxhdGVcIiBbbmdUZW1wbGF0ZU91dGxldENvbnRleHRdPVwie3F1ZXJ5UmVzdWx0OiBxdWVyeVJlc3VsdH1cIj48L25nLWNvbnRhaW5lcj5cbiAgICAgICAgPC9uZy10ZW1wbGF0ZT5cbiAgICA8L3AtdGFibGU+XG48L2Rpdj5cbiJdfQ==