@c8y/ngx-components 1021.13.3 → 1021.22.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (432) hide show
  1. package/alarms/alarm-details.component.d.ts +1 -3
  2. package/alarms/alarm-details.component.d.ts.map +1 -1
  3. package/alarms/alarm-info.component.d.ts +9 -14
  4. package/alarms/alarm-info.component.d.ts.map +1 -1
  5. package/alarms/alarms-list.component.d.ts +2 -17
  6. package/alarms/alarms-list.component.d.ts.map +1 -1
  7. package/alarms/alarms-view.service.d.ts +1 -0
  8. package/alarms/alarms-view.service.d.ts.map +1 -1
  9. package/alarms/alarms.component.d.ts.map +1 -1
  10. package/alarms/alarms.helper.d.ts +5 -0
  11. package/alarms/alarms.helper.d.ts.map +1 -0
  12. package/alarms/alarms.model.d.ts +30 -0
  13. package/alarms/alarms.model.d.ts.map +1 -1
  14. package/alarms/alarms.module.d.ts.map +1 -1
  15. package/alarms/cockpit/index.d.ts.map +1 -1
  16. package/alarms/devicemanagement/index.d.ts.map +1 -1
  17. package/alarms/index.d.ts +5 -4
  18. package/alarms/index.d.ts.map +1 -1
  19. package/context-dashboard/context-dashboard.model.d.ts +1 -0
  20. package/context-dashboard/context-dashboard.model.d.ts.map +1 -1
  21. package/context-dashboard/context-dashboard.service.d.ts +7 -5
  22. package/context-dashboard/context-dashboard.service.d.ts.map +1 -1
  23. package/context-dashboard/dashboard-detail.component.d.ts +4 -7
  24. package/context-dashboard/dashboard-detail.component.d.ts.map +1 -1
  25. package/context-dashboard/dashboard-detail.service.d.ts +4 -4
  26. package/context-dashboard/dashboard-detail.service.d.ts.map +1 -1
  27. package/context-dashboard/dashboard-settings/dashboard-general-settings.component.d.ts +2 -2
  28. package/context-dashboard/dashboard-settings/dashboard-general-settings.component.d.ts.map +1 -1
  29. package/context-dashboard/dashboard-settings/typed-dashboard-settings.component.d.ts +19 -6
  30. package/context-dashboard/dashboard-settings/typed-dashboard-settings.component.d.ts.map +1 -1
  31. package/core/action-bar/action-bar-item.component.d.ts +1 -1
  32. package/core/action-bar/action-bar-item.component.d.ts.map +1 -1
  33. package/core/action-bar/action-bar.module.d.ts +6 -6
  34. package/core/action-bar/action-bar.module.d.ts.map +1 -1
  35. package/core/bootstrap/bootstrap.component.d.ts +3 -1
  36. package/core/bootstrap/bootstrap.component.d.ts.map +1 -1
  37. package/core/common/aggregation/aggregation.model.d.ts +39 -0
  38. package/core/common/aggregation/aggregation.model.d.ts.map +1 -0
  39. package/core/common/aggregation/aggregation.service.d.ts +17 -0
  40. package/core/common/aggregation/aggregation.service.d.ts.map +1 -0
  41. package/core/common/index.d.ts +4 -0
  42. package/core/common/index.d.ts.map +1 -1
  43. package/core/common/inter-app.service.d.ts +48 -0
  44. package/core/common/inter-app.service.d.ts.map +1 -0
  45. package/core/common/interval-based-reload.abstract.d.ts +120 -0
  46. package/core/common/interval-based-reload.abstract.d.ts.map +1 -0
  47. package/core/dashboard/dashboard.module.d.ts +24 -18
  48. package/core/dashboard/dashboard.module.d.ts.map +1 -1
  49. package/core/dashboard/index.d.ts +3 -0
  50. package/core/dashboard/index.d.ts.map +1 -1
  51. package/core/dashboard/widget-auto-refresh-context/auto-refresh-control.component.d.ts +31 -0
  52. package/core/dashboard/widget-auto-refresh-context/auto-refresh-control.component.d.ts.map +1 -0
  53. package/core/dashboard/widget-auto-refresh-context/auto-refresh-select-control.component.d.ts +17 -0
  54. package/core/dashboard/widget-auto-refresh-context/auto-refresh-select-control.component.d.ts.map +1 -0
  55. package/core/dashboard/widget-auto-refresh-context/global-refresh-loading.operator.d.ts +4 -0
  56. package/core/dashboard/widget-auto-refresh-context/global-refresh-loading.operator.d.ts.map +1 -0
  57. package/core/dashboard/widget-auto-refresh-context/index.d.ts +8 -0
  58. package/core/dashboard/widget-auto-refresh-context/index.d.ts.map +1 -0
  59. package/core/dashboard/widget-auto-refresh-context/widget-auto-refresh-context-icon-bar.component.d.ts +7 -0
  60. package/core/dashboard/widget-auto-refresh-context/widget-auto-refresh-context-icon-bar.component.d.ts.map +1 -0
  61. package/core/dashboard/widget-auto-refresh-context/widget-auto-refresh-context.component.d.ts +29 -0
  62. package/core/dashboard/widget-auto-refresh-context/widget-auto-refresh-context.component.d.ts.map +1 -0
  63. package/core/dashboard/widget-auto-refresh-context/widget-auto-refresh-context.model.d.ts +15 -0
  64. package/core/dashboard/widget-auto-refresh-context/widget-auto-refresh-context.model.d.ts.map +1 -0
  65. package/core/dashboard/widget-auto-refresh-context/widget-global-auto-refresh.service.d.ts +169 -0
  66. package/core/dashboard/widget-auto-refresh-context/widget-global-auto-refresh.service.d.ts.map +1 -0
  67. package/core/dashboard/widgets-dashboard.component.d.ts +6 -3
  68. package/core/dashboard/widgets-dashboard.component.d.ts.map +1 -1
  69. package/core/dashboard/wiget-time-context/aggregation-picker/aggregation-picker.component.d.ts +2 -2
  70. package/core/dashboard/wiget-time-context/aggregation-picker/aggregation-picker.component.d.ts.map +1 -1
  71. package/core/dashboard/wiget-time-context/widget-time-context-icon-bar/widget-time-context-icon-bar.component.d.ts +1 -1
  72. package/core/dashboard/wiget-time-context/widget-time-context-icon-bar/widget-time-context-icon-bar.component.d.ts.map +1 -1
  73. package/core/dashboard/wiget-time-context/widget-time-context-query.service.d.ts.map +1 -1
  74. package/core/dashboard/wiget-time-context/widget-time-context.component.d.ts +11 -8
  75. package/core/dashboard/wiget-time-context/widget-time-context.component.d.ts.map +1 -1
  76. package/core/dashboard/wiget-time-context/widget-time-context.model.d.ts +6 -12
  77. package/core/dashboard/wiget-time-context/widget-time-context.model.d.ts.map +1 -1
  78. package/core/header/header.module.d.ts +18 -18
  79. package/core/header/header.module.d.ts.map +1 -1
  80. package/core/header/title/title.component.d.ts +1 -1
  81. package/core/header/title/title.component.d.ts.map +1 -1
  82. package/core/i18n/cached-locale-dictionary.service.d.ts +5 -1
  83. package/core/i18n/cached-locale-dictionary.service.d.ts.map +1 -1
  84. package/core/i18n/i18n.module.d.ts +0 -4
  85. package/core/i18n/i18n.module.d.ts.map +1 -1
  86. package/core/i18n/index.d.ts +2 -1
  87. package/core/i18n/index.d.ts.map +1 -1
  88. package/core/i18n/translation-loader.service.d.ts +50 -0
  89. package/core/i18n/translation-loader.service.d.ts.map +1 -0
  90. package/core/i18n/translation-utils.d.ts +14 -0
  91. package/core/i18n/translation-utils.d.ts.map +1 -0
  92. package/core/plugins/plugins-resolve.service.d.ts +7 -10
  93. package/core/plugins/plugins-resolve.service.d.ts.map +1 -1
  94. package/core/router/context-route.component.d.ts +8 -3
  95. package/core/router/context-route.component.d.ts.map +1 -1
  96. package/core/router/context-route.service.d.ts +29 -3
  97. package/core/router/context-route.service.d.ts.map +1 -1
  98. package/core/router/router-tabs.resolver.d.ts +4 -1
  99. package/core/router/router-tabs.resolver.d.ts.map +1 -1
  100. package/core/router/router.model.d.ts +40 -3
  101. package/core/router/router.model.d.ts.map +1 -1
  102. package/core/router/router.module.d.ts +2 -1
  103. package/core/router/router.module.d.ts.map +1 -1
  104. package/core/router/router.service.d.ts +5 -4
  105. package/core/router/router.service.d.ts.map +1 -1
  106. package/core/router/scoped-context-route.service.d.ts +57 -0
  107. package/core/router/scoped-context-route.service.d.ts.map +1 -0
  108. package/core/router/view-context.service.d.ts +8 -18
  109. package/core/router/view-context.service.d.ts.map +1 -1
  110. package/datapoint-selector/datapoint-attributes-form/datapoint-attributes-form-validation.service.d.ts +2 -1
  111. package/datapoint-selector/datapoint-attributes-form/datapoint-attributes-form-validation.service.d.ts.map +1 -1
  112. package/datapoint-selector/datapoint-attributes-form/datapoint-attributes-form.component.d.ts +11 -2
  113. package/datapoint-selector/datapoint-attributes-form/datapoint-attributes-form.component.d.ts.map +1 -1
  114. package/datapoint-selector/datapoint-selection.model.d.ts +6 -0
  115. package/datapoint-selector/datapoint-selection.model.d.ts.map +1 -1
  116. package/datapoints-export-selector/c8y-ngx-components-datapoints-export-selector.d.ts.map +1 -0
  117. package/datapoints-export-selector/datapoints-export-selector-modal/datapoints-export-selector-file-exporter/data-fetching.service.d.ts +117 -0
  118. package/datapoints-export-selector/datapoints-export-selector-modal/datapoints-export-selector-file-exporter/data-fetching.service.d.ts.map +1 -0
  119. package/datapoints-export-selector/datapoints-export-selector-modal/datapoints-export-selector-file-exporter/data-processing.service.d.ts +90 -0
  120. package/datapoints-export-selector/datapoints-export-selector-modal/datapoints-export-selector-file-exporter/data-processing.service.d.ts.map +1 -0
  121. package/datapoints-export-selector/datapoints-export-selector-modal/datapoints-export-selector-file-exporter/datapoints-export-selector-file-exporter.component.d.ts +160 -0
  122. package/datapoints-export-selector/datapoints-export-selector-modal/datapoints-export-selector-file-exporter/datapoints-export-selector-file-exporter.component.d.ts.map +1 -0
  123. package/datapoints-export-selector/datapoints-export-selector-modal/datapoints-export-selector-file-exporter/datapoints-export-selector-file-exporter.service.d.ts +89 -0
  124. package/datapoints-export-selector/datapoints-export-selector-modal/datapoints-export-selector-file-exporter/datapoints-export-selector-file-exporter.service.d.ts.map +1 -0
  125. package/datapoints-export-selector/datapoints-export-selector-modal/datapoints-export-selector-file-exporter/datapoints-export-selector-preview/datapoints-export-selector-preview.component.d.ts +11 -0
  126. package/datapoints-export-selector/datapoints-export-selector-modal/datapoints-export-selector-file-exporter/datapoints-export-selector-preview/datapoints-export-selector-preview.component.d.ts.map +1 -0
  127. package/datapoints-export-selector/datapoints-export-selector-modal/datapoints-export-selector-file-exporter/datapoints-exports-selector-data-scope/datapoints-exports-selector-data-scope.component.d.ts +27 -0
  128. package/datapoints-export-selector/datapoints-export-selector-modal/datapoints-export-selector-file-exporter/datapoints-exports-selector-data-scope/datapoints-exports-selector-data-scope.component.d.ts.map +1 -0
  129. package/datapoints-export-selector/datapoints-export-selector-modal/datapoints-export-selector-file-exporter/datapoints-exports-selector-file-types/datapoints-exports-selector-file-types.component.d.ts +12 -0
  130. package/datapoints-export-selector/datapoints-export-selector-modal/datapoints-export-selector-file-exporter/datapoints-exports-selector-file-types/datapoints-exports-selector-file-types.component.d.ts.map +1 -0
  131. package/datapoints-export-selector/datapoints-export-selector-modal/datapoints-export-selector-file-exporter/datapoints-exports-selector-time-range/datapoints-exports-selector-time-range.component.d.ts +22 -0
  132. package/datapoints-export-selector/datapoints-export-selector-modal/datapoints-export-selector-file-exporter/datapoints-exports-selector-time-range/datapoints-exports-selector-time-range.component.d.ts.map +1 -0
  133. package/datapoints-export-selector/datapoints-export-selector-modal/datapoints-export-selector-file-exporter/generators/csv-generator.d.ts +3 -0
  134. package/datapoints-export-selector/datapoints-export-selector-modal/datapoints-export-selector-file-exporter/generators/csv-generator.d.ts.map +1 -0
  135. package/datapoints-export-selector/datapoints-export-selector-modal/datapoints-export-selector-file-exporter/generators/excel-generator.d.ts +9 -0
  136. package/datapoints-export-selector/datapoints-export-selector-modal/datapoints-export-selector-file-exporter/generators/excel-generator.d.ts.map +1 -0
  137. package/datapoints-export-selector/datapoints-export-selector-modal/datapoints-export-selector-file-exporter/utils.service.d.ts +56 -0
  138. package/datapoints-export-selector/datapoints-export-selector-modal/datapoints-export-selector-file-exporter/utils.service.d.ts.map +1 -0
  139. package/datapoints-export-selector/datapoints-export-selector-modal/datapoints-export-selector-modal.component.d.ts +21 -0
  140. package/datapoints-export-selector/datapoints-export-selector-modal/datapoints-export-selector-modal.component.d.ts.map +1 -0
  141. package/datapoints-export-selector/datapoints-export-selector.component.d.ts +14 -0
  142. package/datapoints-export-selector/datapoints-export-selector.component.d.ts.map +1 -0
  143. package/datapoints-export-selector/datapoints-export-selector.model.d.ts +232 -0
  144. package/datapoints-export-selector/datapoints-export-selector.model.d.ts.map +1 -0
  145. package/datapoints-export-selector/index.d.ts +15 -0
  146. package/datapoints-export-selector/index.d.ts.map +1 -0
  147. package/device-list/device-list.module.d.ts +4 -2
  148. package/device-list/device-list.module.d.ts.map +1 -1
  149. package/esm2022/alarms/alarm-details.component.mjs +7 -9
  150. package/esm2022/alarms/alarm-info.component.mjs +23 -33
  151. package/esm2022/alarms/alarms-list.component.mjs +5 -16
  152. package/esm2022/alarms/alarms-view.service.mjs +3 -2
  153. package/esm2022/alarms/alarms.component.mjs +10 -3
  154. package/esm2022/alarms/alarms.helper.mjs +32 -0
  155. package/esm2022/alarms/alarms.model.mjs +1 -1
  156. package/esm2022/alarms/alarms.module.mjs +5 -5
  157. package/esm2022/alarms/cockpit/index.mjs +13 -17
  158. package/esm2022/alarms/devicemanagement/index.mjs +15 -18
  159. package/esm2022/alarms/index.mjs +6 -5
  160. package/esm2022/context-dashboard/context-dashboard.component.mjs +4 -4
  161. package/esm2022/context-dashboard/context-dashboard.model.mjs +1 -1
  162. package/esm2022/context-dashboard/context-dashboard.service.mjs +47 -21
  163. package/esm2022/context-dashboard/dashboard-detail.component.mjs +8 -16
  164. package/esm2022/context-dashboard/dashboard-detail.service.mjs +13 -6
  165. package/esm2022/context-dashboard/dashboard-settings/dashboard-general-settings.component.mjs +3 -3
  166. package/esm2022/context-dashboard/dashboard-settings/typed-dashboard-settings.component.mjs +32 -11
  167. package/esm2022/core/action-bar/action-bar-item.component.mjs +3 -3
  168. package/esm2022/core/action-bar/action-bar.module.mjs +16 -5
  169. package/esm2022/core/bootstrap/bootstrap.component.mjs +21 -16
  170. package/esm2022/core/common/aggregation/aggregation.model.mjs +46 -0
  171. package/esm2022/core/common/aggregation/aggregation.service.mjs +34 -0
  172. package/esm2022/core/common/humanize-app-name.model.mjs +2 -2
  173. package/esm2022/core/common/humanize-app-name.pipe.mjs +2 -2
  174. package/esm2022/core/common/index.mjs +5 -1
  175. package/esm2022/core/common/inter-app.service.mjs +76 -0
  176. package/esm2022/core/common/interval-based-reload.abstract.mjs +110 -0
  177. package/esm2022/core/countdown-interval/countdown-interval.component.mjs +3 -3
  178. package/esm2022/core/dashboard/dashboard-child.component.mjs +6 -5
  179. package/esm2022/core/dashboard/dashboard.module.mjs +18 -1
  180. package/esm2022/core/dashboard/index.mjs +4 -1
  181. package/esm2022/core/dashboard/widget-auto-refresh-context/auto-refresh-control.component.mjs +101 -0
  182. package/esm2022/core/dashboard/widget-auto-refresh-context/auto-refresh-select-control.component.mjs +50 -0
  183. package/esm2022/core/dashboard/widget-auto-refresh-context/global-refresh-loading.operator.mjs +7 -0
  184. package/esm2022/core/dashboard/widget-auto-refresh-context/index.mjs +8 -0
  185. package/esm2022/core/dashboard/widget-auto-refresh-context/widget-auto-refresh-context-icon-bar.component.mjs +18 -0
  186. package/esm2022/core/dashboard/widget-auto-refresh-context/widget-auto-refresh-context.component.mjs +127 -0
  187. package/esm2022/core/dashboard/widget-auto-refresh-context/widget-auto-refresh-context.model.mjs +5 -0
  188. package/esm2022/core/dashboard/widget-auto-refresh-context/widget-global-auto-refresh.service.mjs +233 -0
  189. package/esm2022/core/dashboard/widgets-dashboard.component.mjs +35 -30
  190. package/esm2022/core/dashboard/wiget-time-context/aggregation-picker/aggregation-picker.component.mjs +4 -4
  191. package/esm2022/core/dashboard/wiget-time-context/realtime-control/realtime-control.component.mjs +2 -2
  192. package/esm2022/core/dashboard/wiget-time-context/widget-time-context-icon-bar/widget-time-context-icon-bar.component.mjs +5 -5
  193. package/esm2022/core/dashboard/wiget-time-context/widget-time-context-query.service.mjs +7 -4
  194. package/esm2022/core/dashboard/wiget-time-context/widget-time-context.component.mjs +37 -37
  195. package/esm2022/core/dashboard/wiget-time-context/widget-time-context.model.mjs +1 -28
  196. package/esm2022/core/date-time-picker/date-time-picker.component.mjs +3 -3
  197. package/esm2022/core/header/header.module.mjs +7 -5
  198. package/esm2022/core/header/title/title.component.mjs +3 -3
  199. package/esm2022/core/i18n/cached-locale-dictionary.service.mjs +1 -1
  200. package/esm2022/core/i18n/i18n.module.mjs +7 -14
  201. package/esm2022/core/i18n/index.mjs +3 -2
  202. package/esm2022/core/i18n/translate.parser.mjs +2 -2
  203. package/esm2022/core/i18n/translation-loader.service.mjs +132 -0
  204. package/esm2022/core/i18n/translation-utils.mjs +24 -0
  205. package/esm2022/core/plugins/plugins-resolve.service.mjs +12 -37
  206. package/esm2022/core/router/context-route.component.mjs +23 -13
  207. package/esm2022/core/router/context-route.service.mjs +37 -5
  208. package/esm2022/core/router/router-tabs.resolver.mjs +46 -15
  209. package/esm2022/core/router/router.model.mjs +6 -1
  210. package/esm2022/core/router/router.module.mjs +20 -13
  211. package/esm2022/core/router/router.service.mjs +24 -10
  212. package/esm2022/core/router/scoped-context-route.service.mjs +152 -0
  213. package/esm2022/core/router/view-context.service.mjs +59 -16
  214. package/esm2022/datapoint-selector/datapoint-attributes-form/datapoint-attributes-form-validation.service.mjs +13 -6
  215. package/esm2022/datapoint-selector/datapoint-attributes-form/datapoint-attributes-form.component.mjs +22 -5
  216. package/esm2022/datapoint-selector/datapoint-selection-list/datapoint-selection-list.component.mjs +3 -3
  217. package/esm2022/datapoint-selector/datapoint-selection.model.mjs +1 -1
  218. package/esm2022/datapoint-selector/datapoint-selector-list-item/datapoint-selector-list-item.component.mjs +3 -3
  219. package/esm2022/datapoints-export-selector/c8y-ngx-components-datapoints-export-selector.mjs +5 -0
  220. package/esm2022/datapoints-export-selector/datapoints-export-selector-modal/datapoints-export-selector-file-exporter/data-fetching.service.mjs +407 -0
  221. package/esm2022/datapoints-export-selector/datapoints-export-selector-modal/datapoints-export-selector-file-exporter/data-processing.service.mjs +207 -0
  222. package/esm2022/datapoints-export-selector/datapoints-export-selector-modal/datapoints-export-selector-file-exporter/datapoints-export-selector-file-exporter.component.mjs +467 -0
  223. package/esm2022/datapoints-export-selector/datapoints-export-selector-modal/datapoints-export-selector-file-exporter/datapoints-export-selector-file-exporter.service.mjs +187 -0
  224. package/esm2022/datapoints-export-selector/datapoints-export-selector-modal/datapoints-export-selector-file-exporter/datapoints-export-selector-preview/datapoints-export-selector-preview.component.mjs +27 -0
  225. package/esm2022/datapoints-export-selector/datapoints-export-selector-modal/datapoints-export-selector-file-exporter/datapoints-exports-selector-data-scope/datapoints-exports-selector-data-scope.component.mjs +41 -0
  226. package/esm2022/datapoints-export-selector/datapoints-export-selector-modal/datapoints-export-selector-file-exporter/datapoints-exports-selector-file-types/datapoints-exports-selector-file-types.component.mjs +23 -0
  227. package/esm2022/datapoints-export-selector/datapoints-export-selector-modal/datapoints-export-selector-file-exporter/datapoints-exports-selector-time-range/datapoints-exports-selector-time-range.component.mjs +42 -0
  228. package/esm2022/datapoints-export-selector/datapoints-export-selector-modal/datapoints-export-selector-file-exporter/generators/csv-generator.mjs +120 -0
  229. package/esm2022/datapoints-export-selector/datapoints-export-selector-modal/datapoints-export-selector-file-exporter/generators/excel-generator.mjs +282 -0
  230. package/esm2022/datapoints-export-selector/datapoints-export-selector-modal/datapoints-export-selector-file-exporter/utils.service.mjs +76 -0
  231. package/esm2022/datapoints-export-selector/datapoints-export-selector-modal/datapoints-export-selector-modal.component.mjs +46 -0
  232. package/esm2022/datapoints-export-selector/datapoints-export-selector.component.mjs +42 -0
  233. package/esm2022/datapoints-export-selector/datapoints-export-selector.model.mjs +43 -0
  234. package/esm2022/datapoints-export-selector/index.mjs +15 -0
  235. package/esm2022/device-list/add-smart-group.component.mjs +4 -3
  236. package/esm2022/device-list/device-list.module.mjs +22 -4
  237. package/esm2022/map/cluster-map.component.mjs +41 -13
  238. package/esm2022/map/map-status.component.mjs +6 -5
  239. package/esm2022/map/map.component.mjs +9 -5
  240. package/esm2022/map/map.model.mjs +1 -1
  241. package/esm2022/translation-editor/c8y-ngx-components-translation-editor.mjs +5 -0
  242. package/esm2022/translation-editor/data/c8y-ngx-components-translation-editor-data.mjs +5 -0
  243. package/esm2022/translation-editor/data/index.mjs +2 -0
  244. package/esm2022/translation-editor/data/translation-store.service.mjs +175 -0
  245. package/esm2022/translation-editor/index.mjs +10 -0
  246. package/esm2022/translation-editor/lazy/add-translation-modal/add-translation-modal.component.mjs +70 -0
  247. package/esm2022/translation-editor/lazy/c8y-ngx-components-translation-editor-lazy.mjs +5 -0
  248. package/esm2022/translation-editor/lazy/index.mjs +2 -0
  249. package/esm2022/translation-editor/lazy/manage-translation-cell-renderer/manage-translation-cell-renderer.component.mjs +53 -0
  250. package/esm2022/translation-editor/lazy/translation-editor/translation-editor.component.mjs +124 -0
  251. package/esm2022/translation-editor/translation-editor-naviagtor-factory.service.mjs +31 -0
  252. package/esm2022/widgets/cockpit/index.mjs +4 -2
  253. package/esm2022/widgets/cockpit-exports/index.mjs +8 -1
  254. package/esm2022/widgets/definitions/alarms/alarm-list/index.mjs +6 -2
  255. package/esm2022/widgets/definitions/alarms/all-critical-alarms/index.mjs +6 -2
  256. package/esm2022/widgets/definitions/alarms/recent-alarms/index.mjs +6 -2
  257. package/esm2022/widgets/definitions/datapoints-table/c8y-ngx-components-widgets-definitions-datapoints-table.mjs +5 -0
  258. package/esm2022/widgets/definitions/datapoints-table/index.mjs +34 -0
  259. package/esm2022/widgets/definitions/index.mjs +2 -1
  260. package/esm2022/widgets/definitions/map/index.mjs +4 -2
  261. package/esm2022/widgets/implementations/alarms/alarm-list-widget-config/alarm-list-widget-config.component.mjs +29 -15
  262. package/esm2022/widgets/implementations/alarms/alarm-list-widget-view/alarm-list-widget.component.mjs +57 -25
  263. package/esm2022/widgets/implementations/alarms/alarm-list-widget.model.mjs +2 -1
  264. package/esm2022/widgets/implementations/alarms/alarm-widget-alarms-reload.component.mjs +19 -21
  265. package/esm2022/widgets/implementations/datapoints-table/c8y-ngx-components-widgets-implementations-datapoints-table.mjs +5 -0
  266. package/esm2022/widgets/implementations/datapoints-table/datapoints-table-config/datapoints-table-config.component.mjs +383 -0
  267. package/esm2022/widgets/implementations/datapoints-table/datapoints-table-config/datapoints-table-config.service.mjs +124 -0
  268. package/esm2022/widgets/implementations/datapoints-table/datapoints-table-view/adjust-aggregated-time-range.pipe.mjs +191 -0
  269. package/esm2022/widgets/implementations/datapoints-table/datapoints-table-view/apply-range-class.pipe.mjs +36 -0
  270. package/esm2022/widgets/implementations/datapoints-table/datapoints-table-view/column-title.pipe.mjs +45 -0
  271. package/esm2022/widgets/implementations/datapoints-table/datapoints-table-view/datapoints-reload/datapoints-reload.component.mjs +116 -0
  272. package/esm2022/widgets/implementations/datapoints-table/datapoints-table-view/datapoints-table/datapoints-table.component.mjs +116 -0
  273. package/esm2022/widgets/implementations/datapoints-table/datapoints-table-view/datapoints-table/dynamic-column.directive.mjs +43 -0
  274. package/esm2022/widgets/implementations/datapoints-table/datapoints-table-view/datapoints-table-view.component.mjs +282 -0
  275. package/esm2022/widgets/implementations/datapoints-table/datapoints-table-view/datapoints-table-view.service.mjs +430 -0
  276. package/esm2022/widgets/implementations/datapoints-table/datapoints-table-view/virtual-scroll-listener.directive.mjs +75 -0
  277. package/esm2022/widgets/implementations/datapoints-table/datapoints-table-widget.model.mjs +76 -0
  278. package/esm2022/widgets/implementations/datapoints-table/datapoints-table.service.mjs +52 -0
  279. package/esm2022/widgets/implementations/datapoints-table/date-range-picker.component.mjs +68 -0
  280. package/esm2022/widgets/implementations/datapoints-table/index.mjs +10 -0
  281. package/esm2022/widgets/implementations/map/map-widget-config.component.mjs +19 -11
  282. package/esm2022/widgets/implementations/map/map-widget.component.mjs +20 -2
  283. package/esm2022/widgets/implementations/map/map-widget.model.mjs +1 -1
  284. package/fesm2022/c8y-ngx-components-alarms-cockpit.mjs +12 -16
  285. package/fesm2022/c8y-ngx-components-alarms-cockpit.mjs.map +1 -1
  286. package/fesm2022/c8y-ngx-components-alarms-devicemanagement.mjs +14 -17
  287. package/fesm2022/c8y-ngx-components-alarms-devicemanagement.mjs.map +1 -1
  288. package/fesm2022/c8y-ngx-components-alarms.mjs +203 -185
  289. package/fesm2022/c8y-ngx-components-alarms.mjs.map +1 -1
  290. package/fesm2022/c8y-ngx-components-context-dashboard.mjs +135 -91
  291. package/fesm2022/c8y-ngx-components-context-dashboard.mjs.map +1 -1
  292. package/fesm2022/c8y-ngx-components-datapoint-selector.mjs +37 -13
  293. package/fesm2022/c8y-ngx-components-datapoint-selector.mjs.map +1 -1
  294. package/fesm2022/c8y-ngx-components-datapoints-export-selector.mjs +1928 -0
  295. package/fesm2022/c8y-ngx-components-datapoints-export-selector.mjs.map +1 -0
  296. package/fesm2022/c8y-ngx-components-device-list.mjs +24 -5
  297. package/fesm2022/c8y-ngx-components-device-list.mjs.map +1 -1
  298. package/fesm2022/c8y-ngx-components-map.mjs +52 -19
  299. package/fesm2022/c8y-ngx-components-map.mjs.map +1 -1
  300. package/fesm2022/c8y-ngx-components-translation-editor-data.mjs +181 -0
  301. package/fesm2022/c8y-ngx-components-translation-editor-data.mjs.map +1 -0
  302. package/fesm2022/c8y-ngx-components-translation-editor-lazy.mjs +236 -0
  303. package/fesm2022/c8y-ngx-components-translation-editor-lazy.mjs.map +1 -0
  304. package/fesm2022/c8y-ngx-components-translation-editor.mjs +46 -0
  305. package/fesm2022/c8y-ngx-components-translation-editor.mjs.map +1 -0
  306. package/fesm2022/c8y-ngx-components-widgets-cockpit-exports.mjs +7 -0
  307. package/fesm2022/c8y-ngx-components-widgets-cockpit-exports.mjs.map +1 -1
  308. package/fesm2022/c8y-ngx-components-widgets-cockpit.mjs +3 -1
  309. package/fesm2022/c8y-ngx-components-widgets-cockpit.mjs.map +1 -1
  310. package/fesm2022/c8y-ngx-components-widgets-definitions-alarms-alarm-list.mjs +5 -1
  311. package/fesm2022/c8y-ngx-components-widgets-definitions-alarms-alarm-list.mjs.map +1 -1
  312. package/fesm2022/c8y-ngx-components-widgets-definitions-alarms-all-critical-alarms.mjs +5 -1
  313. package/fesm2022/c8y-ngx-components-widgets-definitions-alarms-all-critical-alarms.mjs.map +1 -1
  314. package/fesm2022/c8y-ngx-components-widgets-definitions-alarms-recent-alarms.mjs +5 -1
  315. package/fesm2022/c8y-ngx-components-widgets-definitions-alarms-recent-alarms.mjs.map +1 -1
  316. package/fesm2022/c8y-ngx-components-widgets-definitions-datapoints-table.mjs +41 -0
  317. package/fesm2022/c8y-ngx-components-widgets-definitions-datapoints-table.mjs.map +1 -0
  318. package/fesm2022/c8y-ngx-components-widgets-definitions-map.mjs +3 -1
  319. package/fesm2022/c8y-ngx-components-widgets-definitions-map.mjs.map +1 -1
  320. package/fesm2022/c8y-ngx-components-widgets-definitions.mjs +1 -0
  321. package/fesm2022/c8y-ngx-components-widgets-definitions.mjs.map +1 -1
  322. package/fesm2022/c8y-ngx-components-widgets-implementations-alarms.mjs +101 -58
  323. package/fesm2022/c8y-ngx-components-widgets-implementations-alarms.mjs.map +1 -1
  324. package/fesm2022/c8y-ngx-components-widgets-implementations-datapoints-table.mjs +1967 -0
  325. package/fesm2022/c8y-ngx-components-widgets-implementations-datapoints-table.mjs.map +1 -0
  326. package/fesm2022/c8y-ngx-components-widgets-implementations-map.mjs +37 -11
  327. package/fesm2022/c8y-ngx-components-widgets-implementations-map.mjs.map +1 -1
  328. package/fesm2022/c8y-ngx-components.mjs +5476 -4396
  329. package/fesm2022/c8y-ngx-components.mjs.map +1 -1
  330. package/locales/de.po +289 -18
  331. package/locales/en.po +12 -0
  332. package/locales/en_US.po +3 -0
  333. package/locales/es.po +253 -18
  334. package/locales/fr.po +253 -18
  335. package/locales/ja_JP.po +282 -18
  336. package/locales/locales.pot +257 -18
  337. package/locales/nl.po +253 -18
  338. package/locales/pl.po +253 -18
  339. package/locales/pt_BR.po +253 -18
  340. package/map/cluster-map.component.d.ts +8 -3
  341. package/map/cluster-map.component.d.ts.map +1 -1
  342. package/map/map-status.component.d.ts +0 -3
  343. package/map/map-status.component.d.ts.map +1 -1
  344. package/map/map.component.d.ts +4 -2
  345. package/map/map.component.d.ts.map +1 -1
  346. package/map/map.model.d.ts +2 -1
  347. package/map/map.model.d.ts.map +1 -1
  348. package/package.json +1 -1
  349. package/translation-editor/c8y-ngx-components-translation-editor.d.ts.map +1 -0
  350. package/translation-editor/data/c8y-ngx-components-translation-editor-data.d.ts.map +1 -0
  351. package/translation-editor/data/index.d.ts +2 -0
  352. package/translation-editor/data/index.d.ts.map +1 -0
  353. package/translation-editor/data/translation-store.service.d.ts +61 -0
  354. package/translation-editor/data/translation-store.service.d.ts.map +1 -0
  355. package/translation-editor/index.d.ts +2 -0
  356. package/translation-editor/index.d.ts.map +1 -0
  357. package/translation-editor/lazy/add-translation-modal/add-translation-modal.component.d.ts +30 -0
  358. package/translation-editor/lazy/add-translation-modal/add-translation-modal.component.d.ts.map +1 -0
  359. package/translation-editor/lazy/c8y-ngx-components-translation-editor-lazy.d.ts.map +1 -0
  360. package/translation-editor/lazy/index.d.ts +2 -0
  361. package/translation-editor/lazy/index.d.ts.map +1 -0
  362. package/translation-editor/lazy/manage-translation-cell-renderer/manage-translation-cell-renderer.component.d.ts +22 -0
  363. package/translation-editor/lazy/manage-translation-cell-renderer/manage-translation-cell-renderer.component.d.ts.map +1 -0
  364. package/translation-editor/lazy/translation-editor/translation-editor.component.d.ts +34 -0
  365. package/translation-editor/lazy/translation-editor/translation-editor.component.d.ts.map +1 -0
  366. package/translation-editor/translation-editor-naviagtor-factory.service.d.ts +11 -0
  367. package/translation-editor/translation-editor-naviagtor-factory.service.d.ts.map +1 -0
  368. package/widgets/cockpit/index.d.ts +13 -0
  369. package/widgets/cockpit/index.d.ts.map +1 -1
  370. package/widgets/cockpit-exports/index.d.ts +6 -0
  371. package/widgets/cockpit-exports/index.d.ts.map +1 -1
  372. package/widgets/definitions/alarms/alarm-list/index.d.ts +2 -0
  373. package/widgets/definitions/alarms/alarm-list/index.d.ts.map +1 -1
  374. package/widgets/definitions/alarms/all-critical-alarms/index.d.ts +2 -0
  375. package/widgets/definitions/alarms/all-critical-alarms/index.d.ts.map +1 -1
  376. package/widgets/definitions/alarms/recent-alarms/index.d.ts +2 -0
  377. package/widgets/definitions/alarms/recent-alarms/index.d.ts.map +1 -1
  378. package/widgets/definitions/datapoints-table/c8y-ngx-components-widgets-definitions-datapoints-table.d.ts.map +1 -0
  379. package/widgets/definitions/datapoints-table/index.d.ts +14 -0
  380. package/widgets/definitions/datapoints-table/index.d.ts.map +1 -0
  381. package/widgets/definitions/index.d.ts +1 -0
  382. package/widgets/definitions/index.d.ts.map +1 -1
  383. package/widgets/definitions/map/index.d.ts +2 -1
  384. package/widgets/definitions/map/index.d.ts.map +1 -1
  385. package/widgets/implementations/alarms/alarm-list-widget-config/alarm-list-widget-config.component.d.ts +5 -9
  386. package/widgets/implementations/alarms/alarm-list-widget-config/alarm-list-widget-config.component.d.ts.map +1 -1
  387. package/widgets/implementations/alarms/alarm-list-widget-view/alarm-list-widget.component.d.ts +17 -10
  388. package/widgets/implementations/alarms/alarm-list-widget-view/alarm-list-widget.component.d.ts.map +1 -1
  389. package/widgets/implementations/alarms/alarm-list-widget.model.d.ts +5 -1
  390. package/widgets/implementations/alarms/alarm-list-widget.model.d.ts.map +1 -1
  391. package/widgets/implementations/alarms/alarm-widget-alarms-reload.component.d.ts +5 -11
  392. package/widgets/implementations/alarms/alarm-widget-alarms-reload.component.d.ts.map +1 -1
  393. package/widgets/implementations/datapoints-table/c8y-ngx-components-widgets-implementations-datapoints-table.d.ts.map +1 -0
  394. package/widgets/implementations/datapoints-table/datapoints-table-config/datapoints-table-config.component.d.ts +129 -0
  395. package/widgets/implementations/datapoints-table/datapoints-table-config/datapoints-table-config.component.d.ts.map +1 -0
  396. package/widgets/implementations/datapoints-table/datapoints-table-config/datapoints-table-config.service.d.ts +56 -0
  397. package/widgets/implementations/datapoints-table/datapoints-table-config/datapoints-table-config.service.d.ts.map +1 -0
  398. package/widgets/implementations/datapoints-table/datapoints-table-view/adjust-aggregated-time-range.pipe.d.ts +88 -0
  399. package/widgets/implementations/datapoints-table/datapoints-table-view/adjust-aggregated-time-range.pipe.d.ts.map +1 -0
  400. package/widgets/implementations/datapoints-table/datapoints-table-view/apply-range-class.pipe.d.ts +19 -0
  401. package/widgets/implementations/datapoints-table/datapoints-table-view/apply-range-class.pipe.d.ts.map +1 -0
  402. package/widgets/implementations/datapoints-table/datapoints-table-view/column-title.pipe.d.ts +26 -0
  403. package/widgets/implementations/datapoints-table/datapoints-table-view/column-title.pipe.d.ts.map +1 -0
  404. package/widgets/implementations/datapoints-table/datapoints-table-view/datapoints-reload/datapoints-reload.component.d.ts +63 -0
  405. package/widgets/implementations/datapoints-table/datapoints-table-view/datapoints-reload/datapoints-reload.component.d.ts.map +1 -0
  406. package/widgets/implementations/datapoints-table/datapoints-table-view/datapoints-table/datapoints-table.component.d.ts +38 -0
  407. package/widgets/implementations/datapoints-table/datapoints-table-view/datapoints-table/datapoints-table.component.d.ts.map +1 -0
  408. package/widgets/implementations/datapoints-table/datapoints-table-view/datapoints-table/dynamic-column.directive.d.ts +13 -0
  409. package/widgets/implementations/datapoints-table/datapoints-table-view/datapoints-table/dynamic-column.directive.d.ts.map +1 -0
  410. package/widgets/implementations/datapoints-table/datapoints-table-view/datapoints-table-view.component.d.ts +123 -0
  411. package/widgets/implementations/datapoints-table/datapoints-table-view/datapoints-table-view.component.d.ts.map +1 -0
  412. package/widgets/implementations/datapoints-table/datapoints-table-view/datapoints-table-view.service.d.ts +196 -0
  413. package/widgets/implementations/datapoints-table/datapoints-table-view/datapoints-table-view.service.d.ts.map +1 -0
  414. package/widgets/implementations/datapoints-table/datapoints-table-view/virtual-scroll-listener.directive.d.ts +41 -0
  415. package/widgets/implementations/datapoints-table/datapoints-table-view/virtual-scroll-listener.directive.d.ts.map +1 -0
  416. package/widgets/implementations/datapoints-table/datapoints-table-widget.model.d.ts +175 -0
  417. package/widgets/implementations/datapoints-table/datapoints-table-widget.model.d.ts.map +1 -0
  418. package/widgets/implementations/datapoints-table/datapoints-table.service.d.ts +12 -0
  419. package/widgets/implementations/datapoints-table/datapoints-table.service.d.ts.map +1 -0
  420. package/widgets/implementations/datapoints-table/date-range-picker.component.d.ts +34 -0
  421. package/widgets/implementations/datapoints-table/date-range-picker.component.d.ts.map +1 -0
  422. package/widgets/implementations/datapoints-table/index.d.ts +10 -0
  423. package/widgets/implementations/datapoints-table/index.d.ts.map +1 -0
  424. package/widgets/implementations/map/map-widget-config.component.d.ts +4 -4
  425. package/widgets/implementations/map/map-widget-config.component.d.ts.map +1 -1
  426. package/widgets/implementations/map/map-widget.component.d.ts +8 -3
  427. package/widgets/implementations/map/map-widget.component.d.ts.map +1 -1
  428. package/widgets/implementations/map/map-widget.model.d.ts +4 -3
  429. package/widgets/implementations/map/map-widget.model.d.ts.map +1 -1
  430. package/core/i18n/translate.loader.d.ts +0 -31
  431. package/core/i18n/translate.loader.d.ts.map +0 -1
  432. package/esm2022/core/i18n/translate.loader.mjs +0 -71
@@ -0,0 +1,430 @@
1
+ import { Injectable } from '@angular/core';
2
+ import { MeasurementService } from '@c8y/client';
3
+ import { TIME_RANGE_INTERVAL_UNITS_VALUES } from '@c8y/ngx-components/datapoints-export-selector';
4
+ import { DURATION_OPTIONS } from '../datapoints-table-widget.model';
5
+ import * as i0 from "@angular/core";
6
+ import * as i1 from "@c8y/client";
7
+ function mapToSourceValueObject([key, value]) {
8
+ return { key, value };
9
+ }
10
+ export class DatapointsTableViewService {
11
+ constructor(measurementService) {
12
+ this.measurementService = measurementService;
13
+ }
14
+ /**
15
+ * Filters out inactive data points from the given array.
16
+ *
17
+ * @param datapoints - The array of data points to filter.
18
+ * @returns An array of data points that are active.
19
+ */
20
+ filterOutInactiveDatapoints(datapoints) {
21
+ return datapoints.filter((datapoint) => datapoint.__active);
22
+ }
23
+ hasMultipleDatapoints(datapoints) {
24
+ const ids = datapoints.map(dp => dp.__target.id);
25
+ return ids.length > 1;
26
+ }
27
+ /**
28
+ * Returns a map of active data points device IDs with their corresponding series.
29
+ *
30
+ * Example output:
31
+ * ```typescript
32
+ * new Map([
33
+ * [
34
+ * "844657202",
35
+ * [
36
+ * "c8y_Temperature.T"
37
+ * ]
38
+ * ],
39
+ * [
40
+ * "32666427",
41
+ * [
42
+ * "c8y_Battery.Battery"
43
+ * ]
44
+ * ]
45
+ * ]);
46
+ * ```
47
+ * @param datapoints - An array of data points.
48
+ * @returns A map where the key is the data point ID and the value is an array of data point series.
49
+ */
50
+ groupSeriesByDeviceId(activeDatapoints) {
51
+ return activeDatapoints.reduce((map, { fragment, series, __target: { id } }) => {
52
+ const value = `${fragment}.${series}`;
53
+ const existingValue = map.get(id) ?? [];
54
+ map.set(id, [...existingValue, value]);
55
+ return map;
56
+ }, new Map());
57
+ }
58
+ /**
59
+ * Retrieves the active data points series data and returns it as a map.
60
+ *
61
+ * @param datapointsValuesDataMap - A map of data point sources with their associated series.
62
+ * @param config - The configuration of the data points table.
63
+ * @param roundSeconds - Whether to round the seconds or not.
64
+ * If true, the seconds will be rounded to 0.
65
+ * If false, the seconds will be displayed as they are.
66
+ * @returns A Promise that resolves to a Map object with data point IDs as keys and DataObject as values or undefined when all series has forbidden access.
67
+ */
68
+ async getAllActiveSeriesDataMap(datapointsValuesDataMap, config, roundSeconds) {
69
+ const promises = Array.from(datapointsValuesDataMap).map(async ([source, series]) => {
70
+ const params = {
71
+ dateFrom: config.dateFrom,
72
+ dateTo: config.dateTo,
73
+ source,
74
+ series,
75
+ aggregationType: config.aggregation
76
+ };
77
+ // TODO: consider adding a cache mechanism -> MTM-59233
78
+ const { data, res } = await this.loadSeriesData(params, roundSeconds);
79
+ return { source, data, res };
80
+ });
81
+ const results = await Promise.all(promises);
82
+ const allSeriesHasForbiddenAccess = results.every(item => item.res?.status === 403);
83
+ if (allSeriesHasForbiddenAccess) {
84
+ throw new Error('Access forbidden: All series have a 403 status code');
85
+ }
86
+ const filteredResults = this.filterOutElementsWithForbiddenResponses(results);
87
+ const resultMap = new Map();
88
+ filteredResults.forEach(result => resultMap.set(result.source, result.data));
89
+ return resultMap;
90
+ }
91
+ /**
92
+ * Asynchronously loads series data based on the provided parameters.
93
+ *
94
+ * This method constructs a filter for retrieving series data within a specified date range,
95
+ * from a specific source, and optionally applying an aggregation type.
96
+ *
97
+ * @param params - The parameters for loading series data, including date range, source, series names, and aggregation type.
98
+ * @param roundSeconds - Indicates whether to round the seconds in the date range to the nearest whole number.
99
+ * @returns A promise that resolves to series data wrapped in result object.
100
+ */
101
+ // TODO: same method as in the datapoints-export-selector service, when integrating with it (MTM-59689), remove this method and use the one from the service
102
+ async loadSeriesData(params, roundSeconds) {
103
+ const { dateFrom, dateTo, source, series, aggregationType } = params;
104
+ const from = this.adjustDate(dateFrom, 0, roundSeconds);
105
+ const to = this.adjustDate(dateTo, 0, roundSeconds);
106
+ const filter = {
107
+ dateFrom: from,
108
+ dateTo: to,
109
+ source: source,
110
+ revert: true
111
+ };
112
+ if (aggregationType) {
113
+ filter.aggregationType = aggregationType;
114
+ }
115
+ // TODO: it is a temporal workaround for a bug in the backend,
116
+ // where the series with more than one dot are impossible to retrieve:
117
+ // https://cumulocity.atlassian.net/browse/MTM-59277
118
+ const hasMoreThanOneDot = series.some(s => s.split('.').length > 2);
119
+ if (!hasMoreThanOneDot) {
120
+ filter.series = series;
121
+ }
122
+ return await this.measurementService.listSeries(filter);
123
+ }
124
+ // TODO: same method as in the datapoints-export-selector service, when integrating with it (MTM-59689), remove this method and use the one from the service
125
+ // Integration task: MTM-60221
126
+ // TODO: Compare implementations.
127
+ /**
128
+ * Adjusts the given date by adding the specified number of minutes and setting seconds to 0.
129
+ *
130
+ * @param date - The date to be adjusted in string format.
131
+ * @param minutes - The number of minutes to add to the date.
132
+ * @param roundSeconds - Whether to round the seconds or not.
133
+ * If true, the seconds will be rounded to 0.
134
+ * If false, the seconds will be displayed as they are.
135
+ * @returns The adjusted date in ISO string format.
136
+ */
137
+ adjustDate(date, minutes, roundSeconds = true) {
138
+ const dateTime = new Date(date);
139
+ if (isNaN(dateTime.getTime())) {
140
+ throw new Error('Invalid date');
141
+ }
142
+ dateTime.setUTCMinutes(dateTime.getUTCMinutes() + minutes);
143
+ if (roundSeconds) {
144
+ dateTime.setUTCSeconds(0, 0);
145
+ }
146
+ return dateTime.toISOString();
147
+ }
148
+ /**
149
+ * Creates an array of DatapointsWithValues based on the provided datapoints and datapointsSeriesDataMap.
150
+ *
151
+ * Finds an index of a current data point within series object and based on that index filters values array.
152
+ *
153
+ * @param datapoints - An array of data points.
154
+ * @param datapointsSeriesDataMap - A map containing series data for data points.
155
+ * @returns An array of DatapointsWithValues.
156
+ */
157
+ getDatapointsWithValues(datapoints, datapointsSeriesDataMap) {
158
+ return datapoints.map((dp) => {
159
+ const seriesData = datapointsSeriesDataMap.get(dp.__target.id);
160
+ if (!seriesData) {
161
+ return { ...dp, values: {} };
162
+ }
163
+ // Find an index of a corresponding datapoint data, within series object.
164
+ const datapointSeriesArrayIndex = seriesData.series.findIndex(s => s.name === dp.series && s.type === dp.fragment);
165
+ const valuesFilteredByDatapointSeriesArrayIndex = Object.fromEntries(Object.entries(seriesData.values).map(([key, arr]) => [
166
+ key,
167
+ arr.filter((_, index) => index === datapointSeriesArrayIndex)
168
+ ]));
169
+ return {
170
+ ...dp,
171
+ seriesUnit: seriesData.series[datapointSeriesArrayIndex]?.unit,
172
+ values: valuesFilteredByDatapointSeriesArrayIndex
173
+ };
174
+ });
175
+ }
176
+ /**
177
+ * Creates the column headers for the devices in the data points table.
178
+ *
179
+ * @param datapointsWithValues - An array of data points.
180
+ * @returns An array of column headers for the devices.
181
+ */
182
+ getColumnHeaders(datapointsWithValues) {
183
+ return datapointsWithValues.map(({ __target: { name }, label, renderType, unit }) => {
184
+ return { deviceName: name, label, renderType, unit };
185
+ });
186
+ }
187
+ mapDatapointsWithValuesToList(datapointsWithValues) {
188
+ return datapointsWithValues.flatMap(dp => {
189
+ if (!dp.values) {
190
+ return [];
191
+ }
192
+ return Object.entries(dp.values).flatMap(([date, valuesArray]) => {
193
+ const value = this.findMinMaxValues(valuesArray);
194
+ if (value == null) {
195
+ return [];
196
+ }
197
+ return [
198
+ {
199
+ dateAndTime: date,
200
+ deviceName: dp.__target.name,
201
+ fragment: dp.fragment,
202
+ label: dp.label,
203
+ redRangeMax: dp.redRangeMax,
204
+ redRangeMin: dp.redRangeMin,
205
+ renderType: dp.renderType,
206
+ series: dp.series,
207
+ value: value,
208
+ yellowRangeMax: dp.yellowRangeMax,
209
+ yellowRangeMin: dp.yellowRangeMin
210
+ }
211
+ ];
212
+ });
213
+ });
214
+ }
215
+ /**
216
+ * Finds the overall minimum and maximum values from an array of objects containing 'min' and 'max' properties.
217
+ *
218
+ * If the array contains only one object, that object's 'min' and 'max' values will be returned.
219
+ *
220
+ * @param valuesArray - An array with objects, where each contains 'min' and 'max' properties.
221
+ * @returns An object with the smallest 'min' and largest 'max' values found in the array.
222
+ *
223
+ * @example
224
+ * const values = [
225
+ * { min: 1, max: 10 }
226
+ * ];
227
+ *
228
+ * const result = findMinMaxValues(values);
229
+ * // result is { min: 1, max: 10 }
230
+ */
231
+ findMinMaxValues(valuesArray) {
232
+ const validItems = valuesArray.filter((item) => item && item.min != null && item.max != null);
233
+ if (validItems.length === 0) {
234
+ return null;
235
+ }
236
+ const initialValue = { min: validItems[0].min, max: validItems[0].max };
237
+ return validItems.reduce((acc, item) => ({
238
+ min: Math.min(acc.min, item.min),
239
+ max: Math.max(acc.max, item.max)
240
+ }), initialValue);
241
+ }
242
+ /**
243
+ * Groups a list of data points by date and device, based on given references.
244
+ *
245
+ * @param dataList - The list of data points to be grouped.
246
+ * @param references - The column headers that serve as references for grouping.
247
+ * @returns An array of grouped data points, where each group corresponds to a unique date and device.
248
+ */
249
+ groupByDateAndDevice(dataList, references) {
250
+ const map = this.generateDataPointMap(dataList, references);
251
+ return this.mergeDatapoints(map);
252
+ }
253
+ /**
254
+ * Generates and populates a map with data points.
255
+ *
256
+ * This function processes the provided data points and organizes them into a map structure
257
+ * where each key is a unique combination of date and device identifiers, and the value is an
258
+ * array of data points (or null values) associated with that key. This structured data is then
259
+ * used in the data point table to render the data appropriately.
260
+ *
261
+ * @param dataList - The list of data point table items to be processed.
262
+ * @param columnsHeadersReferences - The list of column headers used to determine the order and structure of the map values.
263
+ * @returns A map where the key is a datapoint identifier containing the date and device name, and the value is an array of data point table items or null.
264
+ */
265
+ generateDataPointMap(dataList, columnsHeadersReferences) {
266
+ // Map to store the data points indexed by a unique identifier.
267
+ const map = new Map();
268
+ dataList.forEach(obj => {
269
+ // Generate a unique identifier for each data point using the date and device name.
270
+ const dateKey = this.toISOFormat(obj.dateAndTime);
271
+ const datapointIdentifier = `${dateKey}_${obj.deviceName}`;
272
+ // Initialize the map entry if it does not exist with a unique identifier.
273
+ if (!map.has(datapointIdentifier)) {
274
+ map.set(datapointIdentifier, Array(columnsHeadersReferences.length).fill(null));
275
+ }
276
+ // Find the index of the reference that matches the current data point.
277
+ const matchingColumnIndex = columnsHeadersReferences.findIndex(ref => ref.deviceName === obj.deviceName && ref.label === obj.label);
278
+ // Update the map entry with the data point.
279
+ const tableItem = map.get(datapointIdentifier);
280
+ if (tableItem) {
281
+ tableItem[matchingColumnIndex] = { ...obj };
282
+ }
283
+ });
284
+ return map;
285
+ }
286
+ /**
287
+ * Merges the data points from the given map into an array of grouped data point table items.
288
+ *
289
+ * @param map - The map containing the data points to be merged.
290
+ * @returns An array of grouped data point table items.
291
+ */
292
+ mergeDatapoints(map) {
293
+ const mergedData = [];
294
+ map.forEach((values, datapointIdentifier) => {
295
+ const [dateKey, deviceName] = datapointIdentifier.split('_');
296
+ const validDataPoint = values.some(item => item && Object.keys(item.value).length > 0);
297
+ if (validDataPoint) {
298
+ mergedData.push({
299
+ dateAndTime: dateKey,
300
+ deviceName: deviceName,
301
+ rowItems: values.map(item => (item ? { ...item } : null))
302
+ });
303
+ }
304
+ });
305
+ return mergedData;
306
+ }
307
+ sortDataByDateDescending(data) {
308
+ return data.sort((a, b) => new Date(b.dateAndTime).getTime() - new Date(a.dateAndTime).getTime());
309
+ }
310
+ /**
311
+ * Prepares the updated time range based on the selected interval.
312
+ *
313
+ * In case of a 'custom' interval or no quantity, the original date range is returned.
314
+ *
315
+ * @param interval - The selected interval type.
316
+ * @returns An object containing the `dateFrom` and `dateTo` in ISO string format.
317
+ */
318
+ prepareTimeRange(interval, dateFromInput, dateToInput) {
319
+ if (!interval || interval === TIME_RANGE_INTERVAL_UNITS_VALUES.custom) {
320
+ return { dateFrom: dateFromInput, dateTo: dateToInput };
321
+ }
322
+ const selected = DURATION_OPTIONS.find(selectedDuration => selectedDuration.id === interval);
323
+ if (!selected?.amount) {
324
+ return { dateFrom: dateFromInput, dateTo: dateToInput };
325
+ }
326
+ const now = new Date();
327
+ return {
328
+ dateFrom: this.subtractTime(now, selected.amount, selected.unit).toISOString(),
329
+ dateTo: now.toISOString()
330
+ };
331
+ }
332
+ /**
333
+ * Subtracts an amount of time from a given date.
334
+ *
335
+ * @param date - The original date.
336
+ * @param amount - The amount of time units to subtract.
337
+ * @param unit - The unit of time to subtract (e.g., minutes, hours, days, weeks, months).
338
+ * @returns A new date with the specified time subtracted.
339
+ */
340
+ subtractTime(date, amount, unit) {
341
+ const newDate = new Date(date);
342
+ switch (unit) {
343
+ case TIME_RANGE_INTERVAL_UNITS_VALUES.minutes:
344
+ newDate.setUTCMinutes(newDate.getUTCMinutes() - amount);
345
+ break;
346
+ case TIME_RANGE_INTERVAL_UNITS_VALUES.hours:
347
+ newDate.setUTCHours(newDate.getUTCHours() - amount);
348
+ break;
349
+ case TIME_RANGE_INTERVAL_UNITS_VALUES.days:
350
+ newDate.setUTCDate(newDate.getUTCDate() - amount);
351
+ break;
352
+ case TIME_RANGE_INTERVAL_UNITS_VALUES.weeks:
353
+ newDate.setUTCDate(newDate.getUTCDate() - amount * 7);
354
+ break;
355
+ case TIME_RANGE_INTERVAL_UNITS_VALUES.months:
356
+ this.subtractMonthsAndAdjustDay(newDate, amount);
357
+ break;
358
+ }
359
+ return newDate;
360
+ }
361
+ getSeriesWithoutPermissionToRead(activeDatapointsSeriesData, activeDatapointsIdsWithSeries) {
362
+ if (!activeDatapointsSeriesData) {
363
+ // Returns all activeDatapointsIdsWithSeries entries if activeDatapointsSeriesData is undefined.
364
+ // It means that the user does not have permission to see any of the selected datapoints data.
365
+ return Array.from(activeDatapointsIdsWithSeries, mapToSourceValueObject);
366
+ }
367
+ const availableSources = new Set(activeDatapointsSeriesData.keys());
368
+ return Array.from(activeDatapointsIdsWithSeries)
369
+ .filter(([source]) => !availableSources.has(source))
370
+ .map(mapToSourceValueObject);
371
+ }
372
+ /**
373
+ * Converts a date string to ISO format.
374
+ *
375
+ * @param dateStr - The date string to convert.
376
+ * @returns The ISO format of the given date string.
377
+ */
378
+ toISOFormat(dateStr) {
379
+ return new Date(dateStr).toISOString();
380
+ }
381
+ filterOutElementsWithForbiddenResponses(seriesDataWithResponse) {
382
+ return seriesDataWithResponse.filter(item => {
383
+ return !(item.res?.status === 403);
384
+ });
385
+ }
386
+ subtractMonthsAndAdjustDay(date, monthsToSubtract) {
387
+ const currentMonth = date.getUTCMonth();
388
+ const expectedTargetMonth = this.calculateTargetMonth(currentMonth, monthsToSubtract);
389
+ date.setUTCMonth(currentMonth - monthsToSubtract);
390
+ const actualMonth = date.getUTCMonth();
391
+ const dayDoesNotExistInTargetMonth = actualMonth !== expectedTargetMonth;
392
+ if (dayDoesNotExistInTargetMonth) {
393
+ this.setToLastDayOfPreviousMonth(date);
394
+ }
395
+ }
396
+ /**
397
+ * Calculates the target month number (0-11) after subtracting months from the current month.
398
+ * Handles negative month numbers by normalizing them to the valid 0-11 range.
399
+ *
400
+ * Examples:
401
+ * - January(0) - 1 month = December(11)
402
+ * - March(2) - 4 months = November(10)
403
+ * - December(11) - 1 month = November(10)
404
+ *
405
+ * @param currentMonth - Current month (0-11, where 0 is January)
406
+ * @param monthsToSubtract - Number of months to subtract
407
+ * @returns Normalized month number in range 0-11
408
+ */
409
+ calculateTargetMonth(currentMonth, monthsToSubtract) {
410
+ return (currentMonth - monthsToSubtract + 12) % 12;
411
+ }
412
+ /**
413
+ * Sets the date to the last day of the previous month.
414
+ * Using 0 as dateValue makes JavaScript automatically calculate
415
+ * last day of previous month, per JavaScript Date API behavior.
416
+ * @param date - Date to modify
417
+ */
418
+ setToLastDayOfPreviousMonth(date) {
419
+ date.setUTCDate(0);
420
+ }
421
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.9", ngImport: i0, type: DatapointsTableViewService, deps: [{ token: i1.MeasurementService }], target: i0.ɵɵFactoryTarget.Injectable }); }
422
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "18.2.9", ngImport: i0, type: DatapointsTableViewService, providedIn: 'root' }); }
423
+ }
424
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.9", ngImport: i0, type: DatapointsTableViewService, decorators: [{
425
+ type: Injectable,
426
+ args: [{
427
+ providedIn: 'root'
428
+ }]
429
+ }], ctorParameters: () => [{ type: i1.MeasurementService }] });
430
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZGF0YXBvaW50cy10YWJsZS12aWV3LnNlcnZpY2UuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi93aWRnZXRzL2ltcGxlbWVudGF0aW9ucy9kYXRhcG9pbnRzLXRhYmxlL2RhdGFwb2ludHMtdGFibGUtdmlldy9kYXRhcG9pbnRzLXRhYmxlLXZpZXcuc2VydmljZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsVUFBVSxFQUFFLE1BQU0sZUFBZSxDQUFDO0FBQzNDLE9BQU8sRUFBbUMsa0JBQWtCLEVBQW1CLE1BQU0sYUFBYSxDQUFDO0FBRW5HLE9BQU8sRUFJTCxnQ0FBZ0MsRUFFakMsTUFBTSxnREFBZ0QsQ0FBQztBQUN4RCxPQUFPLEVBQ0wsZ0JBQWdCLEVBYWpCLE1BQU0sa0NBQWtDLENBQUM7OztBQUUxQyxTQUFTLHNCQUFzQixDQUFDLENBQUMsR0FBRyxFQUFFLEtBQUssQ0FBdUI7SUFJaEUsT0FBTyxFQUFFLEdBQUcsRUFBRSxLQUFLLEVBQUUsQ0FBQztBQUN4QixDQUFDO0FBS0QsTUFBTSxPQUFPLDBCQUEwQjtJQUNyQyxZQUFvQixrQkFBc0M7UUFBdEMsdUJBQWtCLEdBQWxCLGtCQUFrQixDQUFvQjtJQUFHLENBQUM7SUFFOUQ7Ozs7O09BS0c7SUFDSCwyQkFBMkIsQ0FBQyxVQUF3QjtRQUNsRCxPQUFPLFVBQVUsQ0FBQyxNQUFNLENBQUMsQ0FBQyxTQUFxQixFQUFFLEVBQUUsQ0FBQyxTQUFTLENBQUMsUUFBUSxDQUFDLENBQUM7SUFDMUUsQ0FBQztJQUVELHFCQUFxQixDQUFDLFVBQXdCO1FBQzVDLE1BQU0sR0FBRyxHQUFHLFVBQVUsQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsUUFBUSxDQUFDLEVBQUUsQ0FBQyxDQUFDO1FBQ2pELE9BQU8sR0FBRyxDQUFDLE1BQU0sR0FBRyxDQUFDLENBQUM7SUFDeEIsQ0FBQztJQUVEOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O09Bc0JHO0lBQ0gscUJBQXFCLENBQUMsZ0JBQThCO1FBQ2xELE9BQU8sZ0JBQWdCLENBQUMsTUFBTSxDQUM1QixDQUFDLEdBQTRCLEVBQUUsRUFBRSxRQUFRLEVBQUUsTUFBTSxFQUFFLFFBQVEsRUFBRSxFQUFFLEVBQUUsRUFBRSxFQUFjLEVBQUUsRUFBRTtZQUNuRixNQUFNLEtBQUssR0FBRyxHQUFHLFFBQVEsSUFBSSxNQUFNLEVBQUUsQ0FBQztZQUN0QyxNQUFNLGFBQWEsR0FBRyxHQUFHLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxJQUFJLEVBQUUsQ0FBQztZQUN4QyxHQUFHLENBQUMsR0FBRyxDQUFDLEVBQUUsRUFBRSxDQUFDLEdBQUcsYUFBYSxFQUFFLEtBQUssQ0FBQyxDQUFDLENBQUM7WUFDdkMsT0FBTyxHQUFHLENBQUM7UUFDYixDQUFDLEVBQ0QsSUFBSSxHQUFHLEVBQXNCLENBQzlCLENBQUM7SUFDSixDQUFDO0lBRUQ7Ozs7Ozs7OztPQVNHO0lBQ0gsS0FBSyxDQUFDLHlCQUF5QixDQUM3Qix1QkFBZ0QsRUFDaEQsTUFBNkIsRUFDN0IsWUFBcUI7UUFFckIsTUFBTSxRQUFRLEdBQUcsS0FBSyxDQUFDLElBQUksQ0FBQyx1QkFBdUIsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxLQUFLLEVBQUUsQ0FBQyxNQUFNLEVBQUUsTUFBTSxDQUFDLEVBQUUsRUFBRTtZQUNsRixNQUFNLE1BQU0sR0FBa0I7Z0JBQzVCLFFBQVEsRUFBRSxNQUFNLENBQUMsUUFBUTtnQkFDekIsTUFBTSxFQUFFLE1BQU0sQ0FBQyxNQUFNO2dCQUNyQixNQUFNO2dCQUNOLE1BQU07Z0JBQ04sZUFBZSxFQUFFLE1BQU0sQ0FBQyxXQUE4QjthQUN2RCxDQUFDO1lBQ0YsdURBQXVEO1lBQ3ZELE1BQU0sRUFBRSxJQUFJLEVBQUUsR0FBRyxFQUFFLEdBQXFCLE1BQU0sSUFBSSxDQUFDLGNBQWMsQ0FBQyxNQUFNLEVBQUUsWUFBWSxDQUFDLENBQUM7WUFFeEYsT0FBTyxFQUFFLE1BQU0sRUFBRSxJQUFJLEVBQUUsR0FBRyxFQUFFLENBQUM7UUFDL0IsQ0FBQyxDQUFDLENBQUM7UUFFSCxNQUFNLE9BQU8sR0FBNkIsTUFBTSxPQUFPLENBQUMsR0FBRyxDQUFDLFFBQVEsQ0FBQyxDQUFDO1FBRXRFLE1BQU0sMkJBQTJCLEdBQUcsT0FBTyxDQUFDLEtBQUssQ0FBQyxJQUFJLENBQUMsRUFBRSxDQUFDLElBQUksQ0FBQyxHQUFHLEVBQUUsTUFBTSxLQUFLLEdBQUcsQ0FBQyxDQUFDO1FBQ3BGLElBQUksMkJBQTJCLEVBQUUsQ0FBQztZQUNoQyxNQUFNLElBQUksS0FBSyxDQUFDLHFEQUFxRCxDQUFDLENBQUM7UUFDekUsQ0FBQztRQUVELE1BQU0sZUFBZSxHQUNuQixJQUFJLENBQUMsdUNBQXVDLENBQUMsT0FBTyxDQUFDLENBQUM7UUFFeEQsTUFBTSxTQUFTLEdBQTRCLElBQUksR0FBRyxFQUE0QixDQUFDO1FBQy9FLGVBQWUsQ0FBQyxPQUFPLENBQUMsTUFBTSxDQUFDLEVBQUUsQ0FBQyxTQUFTLENBQUMsR0FBRyxDQUFDLE1BQU0sQ0FBQyxNQUFNLEVBQUUsTUFBTSxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUM7UUFFN0UsT0FBTyxTQUFTLENBQUM7SUFDbkIsQ0FBQztJQUVEOzs7Ozs7Ozs7T0FTRztJQUNILDRKQUE0SjtJQUM1SixLQUFLLENBQUMsY0FBYyxDQUFDLE1BQXFCLEVBQUUsWUFBcUI7UUFDL0QsTUFBTSxFQUFFLFFBQVEsRUFBRSxNQUFNLEVBQUUsTUFBTSxFQUFFLE1BQU0sRUFBRSxlQUFlLEVBQUUsR0FBRyxNQUFNLENBQUM7UUFDckUsTUFBTSxJQUFJLEdBQUcsSUFBSSxDQUFDLFVBQVUsQ0FBQyxRQUFRLEVBQUUsQ0FBQyxFQUFFLFlBQVksQ0FBQyxDQUFDO1FBQ3hELE1BQU0sRUFBRSxHQUFHLElBQUksQ0FBQyxVQUFVLENBQUMsTUFBTSxFQUFFLENBQUMsRUFBRSxZQUFZLENBQUMsQ0FBQztRQUVwRCxNQUFNLE1BQU0sR0FBa0I7WUFDNUIsUUFBUSxFQUFFLElBQUk7WUFDZCxNQUFNLEVBQUUsRUFBRTtZQUNWLE1BQU0sRUFBRSxNQUFNO1lBQ2QsTUFBTSxFQUFFLElBQUk7U0FDYixDQUFDO1FBRUYsSUFBSSxlQUFlLEVBQUUsQ0FBQztZQUNwQixNQUFNLENBQUMsZUFBZSxHQUFHLGVBQWUsQ0FBQztRQUMzQyxDQUFDO1FBRUQsOERBQThEO1FBQzlELHNFQUFzRTtRQUN0RSxvREFBb0Q7UUFDcEQsTUFBTSxpQkFBaUIsR0FBSSxNQUFtQixDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQyxLQUFLLENBQUMsR0FBRyxDQUFDLENBQUMsTUFBTSxHQUFHLENBQUMsQ0FBQyxDQUFDO1FBQ2xGLElBQUksQ0FBQyxpQkFBaUIsRUFBRSxDQUFDO1lBQ3ZCLE1BQU0sQ0FBQyxNQUFNLEdBQUcsTUFBTSxDQUFDO1FBQ3pCLENBQUM7UUFFRCxPQUFPLE1BQU0sSUFBSSxDQUFDLGtCQUFrQixDQUFDLFVBQVUsQ0FBQyxNQUFNLENBQUMsQ0FBQztJQUMxRCxDQUFDO0lBRUQsNEpBQTRKO0lBQzVKLDhCQUE4QjtJQUM5QixpQ0FBaUM7SUFDakM7Ozs7Ozs7OztPQVNHO0lBQ0gsVUFBVSxDQUFDLElBQW1CLEVBQUUsT0FBZSxFQUFFLFlBQVksR0FBRyxJQUFJO1FBQ2xFLE1BQU0sUUFBUSxHQUFHLElBQUksSUFBSSxDQUFDLElBQUksQ0FBQyxDQUFDO1FBQ2hDLElBQUksS0FBSyxDQUFDLFFBQVEsQ0FBQyxPQUFPLEVBQUUsQ0FBQyxFQUFFLENBQUM7WUFDOUIsTUFBTSxJQUFJLEtBQUssQ0FBQyxjQUFjLENBQUMsQ0FBQztRQUNsQyxDQUFDO1FBRUQsUUFBUSxDQUFDLGFBQWEsQ0FBQyxRQUFRLENBQUMsYUFBYSxFQUFFLEdBQUcsT0FBTyxDQUFDLENBQUM7UUFDM0QsSUFBSSxZQUFZLEVBQUUsQ0FBQztZQUNqQixRQUFRLENBQUMsYUFBYSxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQztRQUMvQixDQUFDO1FBRUQsT0FBTyxRQUFRLENBQUMsV0FBVyxFQUFFLENBQUM7SUFDaEMsQ0FBQztJQUVEOzs7Ozs7OztPQVFHO0lBQ0gsdUJBQXVCLENBQ3JCLFVBQXdCLEVBQ3hCLHVCQUFnRDtRQUVoRCxPQUFPLFVBQVUsQ0FBQyxHQUFHLENBQUMsQ0FBQyxFQUFjLEVBQUUsRUFBRTtZQUN2QyxNQUFNLFVBQVUsR0FBWSx1QkFBdUIsQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDLFFBQVEsQ0FBQyxFQUFFLENBQUMsQ0FBQztZQUV4RSxJQUFJLENBQUMsVUFBVSxFQUFFLENBQUM7Z0JBQ2hCLE9BQU8sRUFBRSxHQUFHLEVBQUUsRUFBRSxNQUFNLEVBQUUsRUFBRSxFQUFFLENBQUM7WUFDL0IsQ0FBQztZQUVELHlFQUF5RTtZQUN6RSxNQUFNLHlCQUF5QixHQUFHLFVBQVUsQ0FBQyxNQUFNLENBQUMsU0FBUyxDQUMzRCxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQyxJQUFJLEtBQUssRUFBRSxDQUFDLE1BQU0sSUFBSSxDQUFDLENBQUMsSUFBSSxLQUFLLEVBQUUsQ0FBQyxRQUFRLENBQ3BELENBQUM7WUFFRixNQUFNLHlDQUF5QyxHQUFzQixNQUFNLENBQUMsV0FBVyxDQUNyRixNQUFNLENBQUMsT0FBTyxDQUFDLFVBQVUsQ0FBQyxNQUFNLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLEdBQUcsRUFBRSxHQUFHLENBQUMsRUFBRSxFQUFFLENBQUM7Z0JBQ3BELEdBQUc7Z0JBQ0gsR0FBRyxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsRUFBRSxLQUFLLEVBQUUsRUFBRSxDQUFDLEtBQUssS0FBSyx5QkFBeUIsQ0FBQzthQUM5RCxDQUFDLENBQ0gsQ0FBQztZQUVGLE9BQU87Z0JBQ0wsR0FBRyxFQUFFO2dCQUNMLFVBQVUsRUFBRSxVQUFVLENBQUMsTUFBTSxDQUFDLHlCQUF5QixDQUFDLEVBQUUsSUFBSTtnQkFDOUQsTUFBTSxFQUFFLHlDQUF5QzthQUNsRCxDQUFDO1FBQ0osQ0FBQyxDQUFDLENBQUM7SUFDTCxDQUFDO0lBRUQ7Ozs7O09BS0c7SUFDSCxnQkFBZ0IsQ0FBQyxvQkFBa0M7UUFDakQsT0FBTyxvQkFBb0IsQ0FBQyxHQUFHLENBQzdCLENBQUMsRUFBRSxRQUFRLEVBQUUsRUFBRSxJQUFJLEVBQUUsRUFBRSxLQUFLLEVBQUUsVUFBVSxFQUFFLElBQUksRUFBRSxFQUFxQixFQUFFO1lBQ3JFLE9BQU8sRUFBRSxVQUFVLEVBQUUsSUFBSSxFQUFFLEtBQUssRUFBRSxVQUFVLEVBQUUsSUFBSSxFQUFFLENBQUM7UUFDdkQsQ0FBQyxDQUNGLENBQUM7SUFDSixDQUFDO0lBRUQsNkJBQTZCLENBQUMsb0JBQTJDO1FBQ3ZFLE9BQU8sb0JBQW9CLENBQUMsT0FBTyxDQUFDLEVBQUUsQ0FBQyxFQUFFO1lBQ3ZDLElBQUksQ0FBQyxFQUFFLENBQUMsTUFBTSxFQUFFLENBQUM7Z0JBQ2YsT0FBTyxFQUFFLENBQUM7WUFDWixDQUFDO1lBQ0QsT0FBTyxNQUFNLENBQUMsT0FBTyxDQUFDLEVBQUUsQ0FBQyxNQUFNLENBQUMsQ0FBQyxPQUFPLENBQUMsQ0FBQyxDQUFDLElBQUksRUFBRSxXQUFXLENBQUMsRUFBRSxFQUFFO2dCQUMvRCxNQUFNLEtBQUssR0FBRyxJQUFJLENBQUMsZ0JBQWdCLENBQUMsV0FBVyxDQUFDLENBQUM7Z0JBQ2pELElBQUksS0FBSyxJQUFJLElBQUksRUFBRSxDQUFDO29CQUNsQixPQUFPLEVBQUUsQ0FBQztnQkFDWixDQUFDO2dCQUNELE9BQU87b0JBQ0w7d0JBQ0UsV0FBVyxFQUFFLElBQUk7d0JBQ2pCLFVBQVUsRUFBRSxFQUFFLENBQUMsUUFBUSxDQUFDLElBQUk7d0JBQzVCLFFBQVEsRUFBRSxFQUFFLENBQUMsUUFBUTt3QkFDckIsS0FBSyxFQUFFLEVBQUUsQ0FBQyxLQUFLO3dCQUNmLFdBQVcsRUFBRSxFQUFFLENBQUMsV0FBVzt3QkFDM0IsV0FBVyxFQUFFLEVBQUUsQ0FBQyxXQUFXO3dCQUMzQixVQUFVLEVBQUUsRUFBRSxDQUFDLFVBQVU7d0JBQ3pCLE1BQU0sRUFBRSxFQUFFLENBQUMsTUFBTTt3QkFDakIsS0FBSyxFQUFFLEtBQUs7d0JBQ1osY0FBYyxFQUFFLEVBQUUsQ0FBQyxjQUFjO3dCQUNqQyxjQUFjLEVBQUUsRUFBRSxDQUFDLGNBQWM7cUJBQ2xDO2lCQUNGLENBQUM7WUFDSixDQUFDLENBQUMsQ0FBQztRQUNMLENBQUMsQ0FBQyxDQUFDO0lBQ0wsQ0FBQztJQUVEOzs7Ozs7Ozs7Ozs7Ozs7T0FlRztJQUNILGdCQUFnQixDQUFDLFdBQTJCO1FBQzFDLE1BQU0sVUFBVSxHQUFHLFdBQVcsQ0FBQyxNQUFNLENBQ25DLENBQUMsSUFBSSxFQUFpQixFQUFFLENBQUMsSUFBSSxJQUFJLElBQUksQ0FBQyxHQUFHLElBQUksSUFBSSxJQUFJLElBQUksQ0FBQyxHQUFHLElBQUksSUFBSSxDQUN0RSxDQUFDO1FBRUYsSUFBSSxVQUFVLENBQUMsTUFBTSxLQUFLLENBQUMsRUFBRSxDQUFDO1lBQzVCLE9BQU8sSUFBSSxDQUFDO1FBQ2QsQ0FBQztRQUVELE1BQU0sWUFBWSxHQUFVLEVBQUUsR0FBRyxFQUFFLFVBQVUsQ0FBQyxDQUFDLENBQUMsQ0FBQyxHQUFHLEVBQUUsR0FBRyxFQUFFLFVBQVUsQ0FBQyxDQUFDLENBQUMsQ0FBQyxHQUFHLEVBQUUsQ0FBQztRQUUvRSxPQUFPLFVBQVUsQ0FBQyxNQUFNLENBQ3RCLENBQUMsR0FBRyxFQUFFLElBQUksRUFBRSxFQUFFLENBQUMsQ0FBQztZQUNkLEdBQUcsRUFBRSxJQUFJLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxHQUFHLEVBQUUsSUFBSSxDQUFDLEdBQUcsQ0FBQztZQUNoQyxHQUFHLEVBQUUsSUFBSSxDQUFDLEdBQUcsQ0FBQyxHQUFHLENBQUMsR0FBRyxFQUFFLElBQUksQ0FBQyxHQUFHLENBQUM7U0FDakMsQ0FBQyxFQUNGLFlBQVksQ0FDYixDQUFDO0lBQ0osQ0FBQztJQUVEOzs7Ozs7T0FNRztJQUNILG9CQUFvQixDQUNsQixRQUE4QixFQUM5QixVQUErQjtRQUUvQixNQUFNLEdBQUcsR0FBRyxJQUFJLENBQUMsb0JBQW9CLENBQUMsUUFBUSxFQUFFLFVBQVUsQ0FBQyxDQUFDO1FBQzVELE9BQU8sSUFBSSxDQUFDLGVBQWUsQ0FBQyxHQUFHLENBQUMsQ0FBQztJQUNuQyxDQUFDO0lBRUQ7Ozs7Ozs7Ozs7O09BV0c7SUFDSCxvQkFBb0IsQ0FDbEIsUUFBOEIsRUFDOUIsd0JBQTZDO1FBRTdDLCtEQUErRDtRQUMvRCxNQUFNLEdBQUcsR0FBdUIsSUFBSSxHQUFHLEVBQXVELENBQUM7UUFFL0YsUUFBUSxDQUFDLE9BQU8sQ0FBQyxHQUFHLENBQUMsRUFBRTtZQUNyQixtRkFBbUY7WUFDbkYsTUFBTSxPQUFPLEdBQUcsSUFBSSxDQUFDLFdBQVcsQ0FBQyxHQUFHLENBQUMsV0FBVyxDQUFDLENBQUM7WUFDbEQsTUFBTSxtQkFBbUIsR0FBeUIsR0FBRyxPQUFPLElBQUksR0FBRyxDQUFDLFVBQVUsRUFBRSxDQUFDO1lBRWpGLDBFQUEwRTtZQUMxRSxJQUFJLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxtQkFBbUIsQ0FBQyxFQUFFLENBQUM7Z0JBQ2xDLEdBQUcsQ0FBQyxHQUFHLENBQUMsbUJBQW1CLEVBQUUsS0FBSyxDQUFDLHdCQUF3QixDQUFDLE1BQU0sQ0FBQyxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDO1lBQ2xGLENBQUM7WUFFRCx1RUFBdUU7WUFDdkUsTUFBTSxtQkFBbUIsR0FBRyx3QkFBd0IsQ0FBQyxTQUFTLENBQzVELEdBQUcsQ0FBQyxFQUFFLENBQUMsR0FBRyxDQUFDLFVBQVUsS0FBSyxHQUFHLENBQUMsVUFBVSxJQUFJLEdBQUcsQ0FBQyxLQUFLLEtBQUssR0FBRyxDQUFDLEtBQUssQ0FDcEUsQ0FBQztZQUVGLDRDQUE0QztZQUM1QyxNQUFNLFNBQVMsR0FBeUIsR0FBRyxDQUFDLEdBQUcsQ0FBQyxtQkFBbUIsQ0FBQyxDQUFDO1lBQ3JFLElBQUksU0FBUyxFQUFFLENBQUM7Z0JBQ2QsU0FBUyxDQUFDLG1CQUFtQixDQUFDLEdBQUcsRUFBRSxHQUFHLEdBQUcsRUFBRSxDQUFDO1lBQzlDLENBQUM7UUFDSCxDQUFDLENBQUMsQ0FBQztRQUVILE9BQU8sR0FBRyxDQUFDO0lBQ2IsQ0FBQztJQUVEOzs7OztPQUtHO0lBQ0gsZUFBZSxDQUFDLEdBQXVCO1FBQ3JDLE1BQU0sVUFBVSxHQUFnQyxFQUFFLENBQUM7UUFFbkQsR0FBRyxDQUFDLE9BQU8sQ0FBQyxDQUFDLE1BQU0sRUFBRSxtQkFBbUIsRUFBRSxFQUFFO1lBQzFDLE1BQU0sQ0FBQyxPQUFPLEVBQUUsVUFBVSxDQUFDLEdBQUcsbUJBQW1CLENBQUMsS0FBSyxDQUFDLEdBQUcsQ0FBQyxDQUFDO1lBQzdELE1BQU0sY0FBYyxHQUFHLE1BQU0sQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLEVBQUUsQ0FBQyxJQUFJLElBQUksTUFBTSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLENBQUMsTUFBTSxHQUFHLENBQUMsQ0FBQyxDQUFDO1lBRXZGLElBQUksY0FBYyxFQUFFLENBQUM7Z0JBQ25CLFVBQVUsQ0FBQyxJQUFJLENBQUM7b0JBQ2QsV0FBVyxFQUFFLE9BQU87b0JBQ3BCLFVBQVUsRUFBRSxVQUFVO29CQUN0QixRQUFRLEVBQUUsTUFBTSxDQUFDLEdBQUcsQ0FBQyxJQUFJLENBQUMsRUFBRSxDQUFDLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxFQUFFLEdBQUcsSUFBSSxFQUFFLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxDQUFDO2lCQUMxRCxDQUFDLENBQUM7WUFDTCxDQUFDO1FBQ0gsQ0FBQyxDQUFDLENBQUM7UUFFSCxPQUFPLFVBQVUsQ0FBQztJQUNwQixDQUFDO0lBRUQsd0JBQXdCLENBQUMsSUFBaUM7UUFDeEQsT0FBTyxJQUFJLENBQUMsSUFBSSxDQUNkLENBQUMsQ0FBQyxFQUFFLENBQUMsRUFBRSxFQUFFLENBQUMsSUFBSSxJQUFJLENBQUMsQ0FBQyxDQUFDLFdBQVcsQ0FBQyxDQUFDLE9BQU8sRUFBRSxHQUFHLElBQUksSUFBSSxDQUFDLENBQUMsQ0FBQyxXQUFXLENBQUMsQ0FBQyxPQUFPLEVBQUUsQ0FDaEYsQ0FBQztJQUNKLENBQUM7SUFFRDs7Ozs7OztPQU9HO0lBQ0gsZ0JBQWdCLENBQ2QsUUFBMkIsRUFDM0IsYUFBcUIsRUFDckIsV0FBbUI7UUFFbkIsSUFBSSxDQUFDLFFBQVEsSUFBSSxRQUFRLEtBQUssZ0NBQWdDLENBQUMsTUFBTSxFQUFFLENBQUM7WUFDdEUsT0FBTyxFQUFFLFFBQVEsRUFBRSxhQUFhLEVBQUUsTUFBTSxFQUFFLFdBQVcsRUFBRSxDQUFDO1FBQzFELENBQUM7UUFFRCxNQUFNLFFBQVEsR0FBYSxnQkFBZ0IsQ0FBQyxJQUFJLENBQzlDLGdCQUFnQixDQUFDLEVBQUUsQ0FBQyxnQkFBZ0IsQ0FBQyxFQUFFLEtBQUssUUFBUSxDQUNyRCxDQUFDO1FBRUYsSUFBSSxDQUFDLFFBQVEsRUFBRSxNQUFNLEVBQUUsQ0FBQztZQUN0QixPQUFPLEVBQUUsUUFBUSxFQUFFLGFBQWEsRUFBRSxNQUFNLEVBQUUsV0FBVyxFQUFFLENBQUM7UUFDMUQsQ0FBQztRQUVELE1BQU0sR0FBRyxHQUFHLElBQUksSUFBSSxFQUFFLENBQUM7UUFFdkIsT0FBTztZQUNMLFFBQVEsRUFBRSxJQUFJLENBQUMsWUFBWSxDQUFDLEdBQUcsRUFBRSxRQUFRLENBQUMsTUFBTSxFQUFFLFFBQVEsQ0FBQyxJQUFJLENBQUMsQ0FBQyxXQUFXLEVBQUU7WUFDOUUsTUFBTSxFQUFFLEdBQUcsQ0FBQyxXQUFXLEVBQUU7U0FDMUIsQ0FBQztJQUNKLENBQUM7SUFFRDs7Ozs7OztPQU9HO0lBQ0gsWUFBWSxDQUFDLElBQVUsRUFBRSxNQUFjLEVBQUUsSUFBWTtRQUNuRCxNQUFNLE9BQU8sR0FBRyxJQUFJLElBQUksQ0FBQyxJQUFJLENBQUMsQ0FBQztRQUUvQixRQUFRLElBQUksRUFBRSxDQUFDO1lBQ2IsS0FBSyxnQ0FBZ0MsQ0FBQyxPQUFPO2dCQUMzQyxPQUFPLENBQUMsYUFBYSxDQUFDLE9BQU8sQ0FBQyxhQUFhLEVBQUUsR0FBRyxNQUFNLENBQUMsQ0FBQztnQkFDeEQsTUFBTTtZQUNSLEtBQUssZ0NBQWdDLENBQUMsS0FBSztnQkFDekMsT0FBTyxDQUFDLFdBQVcsQ0FBQyxPQUFPLENBQUMsV0FBVyxFQUFFLEdBQUcsTUFBTSxDQUFDLENBQUM7Z0JBQ3BELE1BQU07WUFDUixLQUFLLGdDQUFnQyxDQUFDLElBQUk7Z0JBQ3hDLE9BQU8sQ0FBQyxVQUFVLENBQUMsT0FBTyxDQUFDLFVBQVUsRUFBRSxHQUFHLE1BQU0sQ0FBQyxDQUFDO2dCQUNsRCxNQUFNO1lBQ1IsS0FBSyxnQ0FBZ0MsQ0FBQyxLQUFLO2dCQUN6QyxPQUFPLENBQUMsVUFBVSxDQUFDLE9BQU8sQ0FBQyxVQUFVLEVBQUUsR0FBRyxNQUFNLEdBQUcsQ0FBQyxDQUFDLENBQUM7Z0JBQ3RELE1BQU07WUFDUixLQUFLLGdDQUFnQyxDQUFDLE1BQU07Z0JBQzFDLElBQUksQ0FBQywwQkFBMEIsQ0FBQyxPQUFPLEVBQUUsTUFBTSxDQUFDLENBQUM7Z0JBQ2pELE1BQU07UUFDVixDQUFDO1FBQ0QsT0FBTyxPQUFPLENBQUM7SUFDakIsQ0FBQztJQUVELGdDQUFnQyxDQUM5QiwwQkFBcUUsRUFDckUsNkJBQXNEO1FBRXRELElBQUksQ0FBQywwQkFBMEIsRUFBRSxDQUFDO1lBQ2hDLGdHQUFnRztZQUNoRyw4RkFBOEY7WUFDOUYsT0FBTyxLQUFLLENBQUMsSUFBSSxDQUFDLDZCQUE2QixFQUFFLHNCQUFzQixDQUFDLENBQUM7UUFDM0UsQ0FBQztRQUVELE1BQU0sZ0JBQWdCLEdBQUcsSUFBSSxHQUFHLENBQUMsMEJBQTBCLENBQUMsSUFBSSxFQUFFLENBQUMsQ0FBQztRQUVwRSxPQUFPLEtBQUssQ0FBQyxJQUFJLENBQUMsNkJBQTZCLENBQUM7YUFDN0MsTUFBTSxDQUFDLENBQUMsQ0FBQyxNQUFNLENBQUMsRUFBRSxFQUFFLENBQUMsQ0FBQyxnQkFBZ0IsQ0FBQyxHQUFHLENBQUMsTUFBTSxDQUFDLENBQUM7YUFDbkQsR0FBRyxDQUFDLHNCQUFzQixDQUFDLENBQUM7SUFDakMsQ0FBQztJQUVEOzs7OztPQUtHO0lBQ0ssV0FBVyxDQUFDLE9BQWU7UUFDakMsT0FBTyxJQUFJLElBQUksQ0FBQyxPQUFPLENBQUMsQ0FBQyxXQUFXLEVBQUUsQ0FBQztJQUN6QyxDQUFDO0lBRU8sdUNBQXVDLENBQzdDLHNCQUFnRDtRQUVoRCxPQUFPLHNCQUFzQixDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsRUFBRTtZQUMxQyxPQUFPLENBQUMsQ0FBQyxJQUFJLENBQUMsR0FBRyxFQUFFLE1BQU0sS0FBSyxHQUFHLENBQUMsQ0FBQztRQUNyQyxDQUFDLENBQUMsQ0FBQztJQUNMLENBQUM7SUFFTywwQkFBMEIsQ0FBQyxJQUFVLEVBQUUsZ0JBQXdCO1FBQ3JFLE1BQU0sWUFBWSxHQUFHLElBQUksQ0FBQyxXQUFXLEVBQUUsQ0FBQztRQUN4QyxNQUFNLG1CQUFtQixHQUFHLElBQUksQ0FBQyxvQkFBb0IsQ0FBQyxZQUFZLEVBQUUsZ0JBQWdCLENBQUMsQ0FBQztRQUV0RixJQUFJLENBQUMsV0FBVyxDQUFDLFlBQVksR0FBRyxnQkFBZ0IsQ0FBQyxDQUFDO1FBRWxELE1BQU0sV0FBVyxHQUFHLElBQUksQ0FBQyxXQUFXLEVBQUUsQ0FBQztRQUN2QyxNQUFNLDRCQUE0QixHQUFHLFdBQVcsS0FBSyxtQkFBbUIsQ0FBQztRQUV6RSxJQUFJLDRCQUE0QixFQUFFLENBQUM7WUFDakMsSUFBSSxDQUFDLDJCQUEyQixDQUFDLElBQUksQ0FBQyxDQUFDO1FBQ3pDLENBQUM7SUFDSCxDQUFDO0lBRUQ7Ozs7Ozs7Ozs7OztPQVlHO0lBQ0ssb0JBQW9CLENBQUMsWUFBb0IsRUFBRSxnQkFBd0I7UUFDekUsT0FBTyxDQUFDLFlBQVksR0FBRyxnQkFBZ0IsR0FBRyxFQUFFLENBQUMsR0FBRyxFQUFFLENBQUM7SUFDckQsQ0FBQztJQUVEOzs7OztPQUtHO0lBQ0ssMkJBQTJCLENBQUMsSUFBVTtRQUM1QyxJQUFJLENBQUMsVUFBVSxDQUFDLENBQUMsQ0FBQyxDQUFDO0lBQ3JCLENBQUM7OEdBOWZVLDBCQUEwQjtrSEFBMUIsMEJBQTBCLGNBRnpCLE1BQU07OzJGQUVQLDBCQUEwQjtrQkFIdEMsVUFBVTttQkFBQztvQkFDVixVQUFVLEVBQUUsTUFBTTtpQkFDbkIiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBJbmplY3RhYmxlIH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQgeyBJUmVzdWx0LCBJU2VyaWVzLCBJU2VyaWVzRmlsdGVyLCBNZWFzdXJlbWVudFNlcnZpY2UsIGFnZ3JlZ2F0aW9uVHlwZSB9IGZyb20gJ0BjOHkvY2xpZW50JztcbmltcG9ydCB7IEtQSURldGFpbHMgfSBmcm9tICdAYzh5L25neC1jb21wb25lbnRzL2RhdGFwb2ludC1zZWxlY3Rvcic7XG5pbXBvcnQge1xuICBEYXRhcG9pbnRzVmFsdWVzRGF0YU1hcCxcbiAgTWluTWF4VmFsdWVzLFxuICBTb3VyY2VJZCxcbiAgVElNRV9SQU5HRV9JTlRFUlZBTF9VTklUU19WQUxVRVMsXG4gIFRpbWVSYW5nZUludGVydmFsXG59IGZyb20gJ0BjOHkvbmd4LWNvbXBvbmVudHMvZGF0YXBvaW50cy1leHBvcnQtc2VsZWN0b3InO1xuaW1wb3J0IHtcbiAgRFVSQVRJT05fT1BUSU9OUyxcbiAgRGF0YVBvaW50c1RhYmxlTWFwLFxuICBEYXRhcG9pbnRUYWJsZUl0ZW0sXG4gIERhdGFwb2ludFRhYmxlTWFwS2V5LFxuICBEYXRhcG9pbnRXaXRoVmFsdWVzLFxuICBEYXRhcG9pbnRzU2VyaWVzRGF0YU1hcCxcbiAgRGF0YXBvaW50c1RhYmxlQ29uZmlnLFxuICBEdXJhdGlvbixcbiAgR3JvdXBlZERhdGFwb2ludFRhYmxlSXRlbSxcbiAgTWVhc3VyZW1lbnRSYW5nZXMsXG4gIFNlcmllc0RhdGFXaXRoUmVzcG9uc2UsXG4gIFRhYmxlQ29sdW1uSGVhZGVyLFxuICBWYWx1ZVxufSBmcm9tICcuLi9kYXRhcG9pbnRzLXRhYmxlLXdpZGdldC5tb2RlbCc7XG5cbmZ1bmN0aW9uIG1hcFRvU291cmNlVmFsdWVPYmplY3QoW2tleSwgdmFsdWVdOiBbU291cmNlSWQsIHN0cmluZ1tdXSk6IHtcbiAga2V5OiBTb3VyY2VJZDtcbiAgdmFsdWU6IHN0cmluZ1tdO1xufSB7XG4gIHJldHVybiB7IGtleSwgdmFsdWUgfTtcbn1cblxuQEluamVjdGFibGUoe1xuICBwcm92aWRlZEluOiAncm9vdCdcbn0pXG5leHBvcnQgY2xhc3MgRGF0YXBvaW50c1RhYmxlVmlld1NlcnZpY2Uge1xuICBjb25zdHJ1Y3Rvcihwcml2YXRlIG1lYXN1cmVtZW50U2VydmljZTogTWVhc3VyZW1lbnRTZXJ2aWNlKSB7fVxuXG4gIC8qKlxuICAgKiBGaWx0ZXJzIG91dCBpbmFjdGl2ZSBkYXRhIHBvaW50cyBmcm9tIHRoZSBnaXZlbiBhcnJheS5cbiAgICpcbiAgICogQHBhcmFtIGRhdGFwb2ludHMgLSBUaGUgYXJyYXkgb2YgZGF0YSBwb2ludHMgdG8gZmlsdGVyLlxuICAgKiBAcmV0dXJucyBBbiBhcnJheSBvZiBkYXRhIHBvaW50cyB0aGF0IGFyZSBhY3RpdmUuXG4gICAqL1xuICBmaWx0ZXJPdXRJbmFjdGl2ZURhdGFwb2ludHMoZGF0YXBvaW50czogS1BJRGV0YWlsc1tdKTogS1BJRGV0YWlsc1tdIHtcbiAgICByZXR1cm4gZGF0YXBvaW50cy5maWx0ZXIoKGRhdGFwb2ludDogS1BJRGV0YWlscykgPT4gZGF0YXBvaW50Ll9fYWN0aXZlKTtcbiAgfVxuXG4gIGhhc011bHRpcGxlRGF0YXBvaW50cyhkYXRhcG9pbnRzOiBLUElEZXRhaWxzW10pOiBib29sZWFuIHtcbiAgICBjb25zdCBpZHMgPSBkYXRhcG9pbnRzLm1hcChkcCA9PiBkcC5fX3RhcmdldC5pZCk7XG4gICAgcmV0dXJuIGlkcy5sZW5ndGggPiAxO1xuICB9XG5cbiAgLyoqXG4gICAqIFJldHVybnMgYSBtYXAgb2YgYWN0aXZlIGRhdGEgcG9pbnRzIGRldmljZSBJRHMgd2l0aCB0aGVpciBjb3JyZXNwb25kaW5nIHNlcmllcy5cbiAgICpcbiAgICogRXhhbXBsZSBvdXRwdXQ6XG4gICAqIGBgYHR5cGVzY3JpcHRcbiAgICogbmV3IE1hcChbXG4gICAqICAgW1xuICAgKiAgICAgXCI4NDQ2NTcyMDJcIixcbiAgICogICAgIFtcbiAgICogICAgICAgXCJjOHlfVGVtcGVyYXR1cmUuVFwiXG4gICAqICAgICBdXG4gICAqICAgXSxcbiAgICogICBbXG4gICAqICAgICBcIjMyNjY2NDI3XCIsXG4gICAqICAgICBbXG4gICAqICAgICAgIFwiYzh5X0JhdHRlcnkuQmF0dGVyeVwiXG4gICAqICAgICBdXG4gICAqICAgXVxuICAgKiBdKTtcbiAgICogYGBgXG4gICAqIEBwYXJhbSBkYXRhcG9pbnRzIC0gQW4gYXJyYXkgb2YgZGF0YSBwb2ludHMuXG4gICAqIEByZXR1cm5zIEEgbWFwIHdoZXJlIHRoZSBrZXkgaXMgdGhlIGRhdGEgcG9pbnQgSUQgYW5kIHRoZSB2YWx1ZSBpcyBhbiBhcnJheSBvZiBkYXRhIHBvaW50IHNlcmllcy5cbiAgICovXG4gIGdyb3VwU2VyaWVzQnlEZXZpY2VJZChhY3RpdmVEYXRhcG9pbnRzOiBLUElEZXRhaWxzW10pOiBEYXRhcG9pbnRzVmFsdWVzRGF0YU1hcCB7XG4gICAgcmV0dXJuIGFjdGl2ZURhdGFwb2ludHMucmVkdWNlKFxuICAgICAgKG1hcDogRGF0YXBvaW50c1ZhbHVlc0RhdGFNYXAsIHsgZnJhZ21lbnQsIHNlcmllcywgX190YXJnZXQ6IHsgaWQgfSB9OiBLUElEZXRhaWxzKSA9PiB7XG4gICAgICAgIGNvbnN0IHZhbHVlID0gYCR7ZnJhZ21lbnR9LiR7c2VyaWVzfWA7XG4gICAgICAgIGNvbnN0IGV4aXN0aW5nVmFsdWUgPSBtYXAuZ2V0KGlkKSA/PyBbXTtcbiAgICAgICAgbWFwLnNldChpZCwgWy4uLmV4aXN0aW5nVmFsdWUsIHZhbHVlXSk7XG4gICAgICAgIHJldHVybiBtYXA7XG4gICAgICB9LFxuICAgICAgbmV3IE1hcDxTb3VyY2VJZCwgc3RyaW5nW10+KClcbiAgICApO1xuICB9XG5cbiAgLyoqXG4gICAqIFJldHJpZXZlcyB0aGUgYWN0aXZlIGRhdGEgcG9pbnRzIHNlcmllcyBkYXRhIGFuZCByZXR1cm5zIGl0IGFzIGEgbWFwLlxuICAgKlxuICAgKiBAcGFyYW0gZGF0YXBvaW50c1ZhbHVlc0RhdGFNYXAgLSBBIG1hcCBvZiBkYXRhIHBvaW50IHNvdXJjZXMgd2l0aCB0aGVpciBhc3NvY2lhdGVkIHNlcmllcy5cbiAgICogQHBhcmFtIGNvbmZpZyAtIFRoZSBjb25maWd1cmF0aW9uIG9mIHRoZSBkYXRhIHBvaW50cyB0YWJsZS5cbiAgICogQHBhcmFtIHJvdW5kU2Vjb25kcyAtIFdoZXRoZXIgdG8gcm91bmQgdGhlIHNlY29uZHMgb3Igbm90LlxuICAgKiAgICAgICAgICAgICAgICAgICAgICAgSWYgdHJ1ZSwgdGhlIHNlY29uZHMgd2lsbCBiZSByb3VuZGVkIHRvIDAuXG4gICAqICAgICAgICAgICAgICAgICAgICAgICBJZiBmYWxzZSwgdGhlIHNlY29uZHMgd2lsbCBiZSBkaXNwbGF5ZWQgYXMgdGhleSBhcmUuXG4gICAqIEByZXR1cm5zIEEgUHJvbWlzZSB0aGF0IHJlc29sdmVzIHRvIGEgTWFwIG9iamVjdCB3aXRoIGRhdGEgcG9pbnQgSURzIGFzIGtleXMgYW5kIERhdGFPYmplY3QgYXMgdmFsdWVzIG9yIHVuZGVmaW5lZCB3aGVuIGFsbCBzZXJpZXMgaGFzIGZvcmJpZGRlbiBhY2Nlc3MuXG4gICAqL1xuICBhc3luYyBnZXRBbGxBY3RpdmVTZXJpZXNEYXRhTWFwKFxuICAgIGRhdGFwb2ludHNWYWx1ZXNEYXRhTWFwOiBEYXRhcG9pbnRzVmFsdWVzRGF0YU1hcCxcbiAgICBjb25maWc6IERhdGFwb2ludHNUYWJsZUNvbmZpZyxcbiAgICByb3VuZFNlY29uZHM6IGJvb2xlYW5cbiAgKTogUHJvbWlzZTxNYXA8c3RyaW5nIHwgbnVtYmVyLCBJU2VyaWVzPj4ge1xuICAgIGNvbnN0IHByb21pc2VzID0gQXJyYXkuZnJvbShkYXRhcG9pbnRzVmFsdWVzRGF0YU1hcCkubWFwKGFzeW5jIChbc291cmNlLCBzZXJpZXNdKSA9PiB7XG4gICAgICBjb25zdCBwYXJhbXM6IElTZXJpZXNGaWx0ZXIgPSB7XG4gICAgICAgIGRhdGVGcm9tOiBjb25maWcuZGF0ZUZyb20sXG4gICAgICAgIGRhdGVUbzogY29uZmlnLmRhdGVUbyxcbiAgICAgICAgc291cmNlLFxuICAgICAgICBzZXJpZXMsXG4gICAgICAgIGFnZ3JlZ2F0aW9uVHlwZTogY29uZmlnLmFnZ3JlZ2F0aW9uIGFzIGFnZ3JlZ2F0aW9uVHlwZVxuICAgICAgfTtcbiAgICAgIC8vIFRPRE86IGNvbnNpZGVyIGFkZGluZyBhIGNhY2hlIG1lY2hhbmlzbSAtPiBNVE0tNTkyMzNcbiAgICAgIGNvbnN0IHsgZGF0YSwgcmVzIH06IElSZXN1bHQ8SVNlcmllcz4gPSBhd2FpdCB0aGlzLmxvYWRTZXJpZXNEYXRhKHBhcmFtcywgcm91bmRTZWNvbmRzKTtcblxuICAgICAgcmV0dXJuIHsgc291cmNlLCBkYXRhLCByZXMgfTtcbiAgICB9KTtcblxuICAgIGNvbnN0IHJlc3VsdHM6IFNlcmllc0RhdGFXaXRoUmVzcG9uc2VbXSA9IGF3YWl0IFByb21pc2UuYWxsKHByb21pc2VzKTtcblxuICAgIGNvbnN0IGFsbFNlcmllc0hhc0ZvcmJpZGRlbkFjY2VzcyA9IHJlc3VsdHMuZXZlcnkoaXRlbSA9PiBpdGVtLnJlcz8uc3RhdHVzID09PSA0MDMpO1xuICAgIGlmIChhbGxTZXJpZXNIYXNGb3JiaWRkZW5BY2Nlc3MpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignQWNjZXNzIGZvcmJpZGRlbjogQWxsIHNlcmllcyBoYXZlIGEgNDAzIHN0YXR1cyBjb2RlJyk7XG4gICAgfVxuXG4gICAgY29uc3QgZmlsdGVyZWRSZXN1bHRzOiBTZXJpZXNEYXRhV2l0aFJlc3BvbnNlW10gPVxuICAgICAgdGhpcy5maWx0ZXJPdXRFbGVtZW50c1dpdGhGb3JiaWRkZW5SZXNwb25zZXMocmVzdWx0cyk7XG5cbiAgICBjb25zdCByZXN1bHRNYXA6IERhdGFwb2ludHNTZXJpZXNEYXRhTWFwID0gbmV3IE1hcDxzdHJpbmcgfCBudW1iZXIsIElTZXJpZXM+KCk7XG4gICAgZmlsdGVyZWRSZXN1bHRzLmZvckVhY2gocmVzdWx0ID0+IHJlc3VsdE1hcC5zZXQocmVzdWx0LnNvdXJjZSwgcmVzdWx0LmRhdGEpKTtcblxuICAgIHJldHVybiByZXN1bHRNYXA7XG4gIH1cblxuICAvKipcbiAgICogQXN5bmNocm9ub3VzbHkgbG9hZHMgc2VyaWVzIGRhdGEgYmFzZWQgb24gdGhlIHByb3ZpZGVkIHBhcmFtZXRlcnMuXG4gICAqXG4gICAqIFRoaXMgbWV0aG9kIGNvbnN0cnVjdHMgYSBmaWx0ZXIgZm9yIHJldHJpZXZpbmcgc2VyaWVzIGRhdGEgd2l0aGluIGEgc3BlY2lmaWVkIGRhdGUgcmFuZ2UsXG4gICAqIGZyb20gYSBzcGVjaWZpYyBzb3VyY2UsIGFuZCBvcHRpb25hbGx5IGFwcGx5aW5nIGFuIGFnZ3JlZ2F0aW9uIHR5cGUuXG4gICAqXG4gICAqIEBwYXJhbSBwYXJhbXMgLSBUaGUgcGFyYW1ldGVycyBmb3IgbG9hZGluZyBzZXJpZXMgZGF0YSwgaW5jbHVkaW5nIGRhdGUgcmFuZ2UsIHNvdXJjZSwgc2VyaWVzIG5hbWVzLCBhbmQgYWdncmVnYXRpb24gdHlwZS5cbiAgICogQHBhcmFtIHJvdW5kU2Vjb25kcyAtIEluZGljYXRlcyB3aGV0aGVyIHRvIHJvdW5kIHRoZSBzZWNvbmRzIGluIHRoZSBkYXRlIHJhbmdlIHRvIHRoZSBuZWFyZXN0IHdob2xlIG51bWJlci5cbiAgICogQHJldHVybnMgQSBwcm9taXNlIHRoYXQgcmVzb2x2ZXMgdG8gc2VyaWVzIGRhdGEgd3JhcHBlZCBpbiByZXN1bHQgb2JqZWN0LlxuICAgKi9cbiAgLy8gVE9ETzogc2FtZSBtZXRob2QgYXMgaW4gdGhlIGRhdGFwb2ludHMtZXhwb3J0LXNlbGVjdG9yIHNlcnZpY2UsIHdoZW4gaW50ZWdyYXRpbmcgd2l0aCBpdCAoTVRNLTU5Njg5KSwgcmVtb3ZlIHRoaXMgbWV0aG9kIGFuZCB1c2UgdGhlIG9uZSBmcm9tIHRoZSBzZXJ2aWNlXG4gIGFzeW5jIGxvYWRTZXJpZXNEYXRhKHBhcmFtczogSVNlcmllc0ZpbHRlciwgcm91bmRTZWNvbmRzOiBib29sZWFuKTogUHJvbWlzZTxJUmVzdWx0PElTZXJpZXM+PiB7XG4gICAgY29uc3QgeyBkYXRlRnJvbSwgZGF0ZVRvLCBzb3VyY2UsIHNlcmllcywgYWdncmVnYXRpb25UeXBlIH0gPSBwYXJhbXM7XG4gICAgY29uc3QgZnJvbSA9IHRoaXMuYWRqdXN0RGF0ZShkYXRlRnJvbSwgMCwgcm91bmRTZWNvbmRzKTtcbiAgICBjb25zdCB0byA9IHRoaXMuYWRqdXN0RGF0ZShkYXRlVG8sIDAsIHJvdW5kU2Vjb25kcyk7XG5cbiAgICBjb25zdCBmaWx0ZXI6IElTZXJpZXNGaWx0ZXIgPSB7XG4gICAgICBkYXRlRnJvbTogZnJvbSxcbiAgICAgIGRhdGVUbzogdG8sXG4gICAgICBzb3VyY2U6IHNvdXJjZSxcbiAgICAgIHJldmVydDogdHJ1ZVxuICAgIH07XG5cbiAgICBpZiAoYWdncmVnYXRpb25UeXBlKSB7XG4gICAgICBmaWx0ZXIuYWdncmVnYXRpb25UeXBlID0gYWdncmVnYXRpb25UeXBlO1xuICAgIH1cblxuICAgIC8vIFRPRE86IGl0IGlzIGEgdGVtcG9yYWwgd29ya2Fyb3VuZCBmb3IgYSBidWcgaW4gdGhlIGJhY2tlbmQsXG4gICAgLy8gd2hlcmUgdGhlIHNlcmllcyB3aXRoIG1vcmUgdGhhbiBvbmUgZG90IGFyZSBpbXBvc3NpYmxlIHRvIHJldHJpZXZlOlxuICAgIC8vIGh0dHBzOi8vY3VtdWxvY2l0eS5hdGxhc3NpYW4ubmV0L2Jyb3dzZS9NVE0tNTkyNzdcbiAgICBjb25zdCBoYXNNb3JlVGhhbk9uZURvdCA9IChzZXJpZXMgYXMgc3RyaW5nW10pLnNvbWUocyA9PiBzLnNwbGl0KCcuJykubGVuZ3RoID4gMik7XG4gICAgaWYgKCFoYXNNb3JlVGhhbk9uZURvdCkge1xuICAgICAgZmlsdGVyLnNlcmllcyA9IHNlcmllcztcbiAgICB9XG5cbiAgICByZXR1cm4gYXdhaXQgdGhpcy5tZWFzdXJlbWVudFNlcnZpY2UubGlzdFNlcmllcyhmaWx0ZXIpO1xuICB9XG5cbiAgLy8gVE9ETzogc2FtZSBtZXRob2QgYXMgaW4gdGhlIGRhdGFwb2ludHMtZXhwb3J0LXNlbGVjdG9yIHNlcnZpY2UsIHdoZW4gaW50ZWdyYXRpbmcgd2l0aCBpdCAoTVRNLTU5Njg5KSwgcmVtb3ZlIHRoaXMgbWV0aG9kIGFuZCB1c2UgdGhlIG9uZSBmcm9tIHRoZSBzZXJ2aWNlXG4gIC8vIEludGVncmF0aW9uIHRhc2s6IE1UTS02MDIyMVxuICAvLyBUT0RPOiBDb21wYXJlIGltcGxlbWVudGF0aW9ucy5cbiAgLyoqXG4gICAqIEFkanVzdHMgdGhlIGdpdmVuIGRhdGUgYnkgYWRkaW5nIHRoZSBzcGVjaWZpZWQgbnVtYmVyIG9mIG1pbnV0ZXMgYW5kIHNldHRpbmcgc2Vjb25kcyB0byAwLlxuICAgKlxuICAgKiBAcGFyYW0gZGF0ZSAtIFRoZSBkYXRlIHRvIGJlIGFkanVzdGVkIGluIHN0cmluZyBmb3JtYXQuXG4gICAqIEBwYXJhbSBtaW51dGVzIC0gVGhlIG51bWJlciBvZiBtaW51dGVzIHRvIGFkZCB0byB0aGUgZGF0ZS5cbiAgICogQHBhcmFtIHJvdW5kU2Vjb25kcyAtIFdoZXRoZXIgdG8gcm91bmQgdGhlIHNlY29uZHMgb3Igbm90LlxuICAgKiAgICAgICAgICAgICAgICAgICAgICAgSWYgdHJ1ZSwgdGhlIHNlY29uZHMgd2lsbCBiZSByb3VuZGVkIHRvIDAuXG4gICAqICAgICAgICAgICAgICAgICAgICAgICBJZiBmYWxzZSwgdGhlIHNlY29uZHMgd2lsbCBiZSBkaXNwbGF5ZWQgYXMgdGhleSBhcmUuXG4gICAqIEByZXR1cm5zIFRoZSBhZGp1c3RlZCBkYXRlIGluIElTTyBzdHJpbmcgZm9ybWF0LlxuICAgKi9cbiAgYWRqdXN0RGF0ZShkYXRlOiBzdHJpbmcgfCBEYXRlLCBtaW51dGVzOiBudW1iZXIsIHJvdW5kU2Vjb25kcyA9IHRydWUpOiBzdHJpbmcge1xuICAgIGNvbnN0IGRhdGVUaW1lID0gbmV3IERhdGUoZGF0ZSk7XG4gICAgaWYgKGlzTmFOKGRhdGVUaW1lLmdldFRpbWUoKSkpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignSW52YWxpZCBkYXRlJyk7XG4gICAgfVxuXG4gICAgZGF0ZVRpbWUuc2V0VVRDTWludXRlcyhkYXRlVGltZS5nZXRVVENNaW51dGVzKCkgKyBtaW51dGVzKTtcbiAgICBpZiAocm91bmRTZWNvbmRzKSB7XG4gICAgICBkYXRlVGltZS5zZXRVVENTZWNvbmRzKDAsIDApO1xuICAgIH1cblxuICAgIHJldHVybiBkYXRlVGltZS50b0lTT1N0cmluZygpO1xuICB9XG5cbiAgLyoqXG4gICAqIENyZWF0ZXMgYW4gYXJyYXkgb2YgRGF0YXBvaW50c1dpdGhWYWx1ZXMgYmFzZWQgb24gdGhlIHByb3ZpZGVkIGRhdGFwb2ludHMgYW5kIGRhdGFwb2ludHNTZXJpZXNEYXRhTWFwLlxuICAgKlxuICAgKiBGaW5kcyBhbiBpbmRleCBvZiBhIGN1cnJlbnQgZGF0YSBwb2ludCB3aXRoaW4gc2VyaWVzIG9iamVjdCBhbmQgYmFzZWQgb24gdGhhdCBpbmRleCBmaWx0ZXJzIHZhbHVlcyBhcnJheS5cbiAgICpcbiAgICogQHBhcmFtIGRhdGFwb2ludHMgLSBBbiBhcnJheSBvZiBkYXRhIHBvaW50cy5cbiAgICogQHBhcmFtIGRhdGFwb2ludHNTZXJpZXNEYXRhTWFwIC0gQSBtYXAgY29udGFpbmluZyBzZXJpZXMgZGF0YSBmb3IgZGF0YSBwb2ludHMuXG4gICAqIEByZXR1cm5zIEFuIGFycmF5IG9mIERhdGFwb2ludHNXaXRoVmFsdWVzLlxuICAgKi9cbiAgZ2V0RGF0YXBvaW50c1dpdGhWYWx1ZXMoXG4gICAgZGF0YXBvaW50czogS1BJRGV0YWlsc1tdLFxuICAgIGRhdGFwb2ludHNTZXJpZXNEYXRhTWFwOiBEYXRhcG9pbnRzU2VyaWVzRGF0YU1hcFxuICApOiBEYXRhcG9pbnRXaXRoVmFsdWVzW10ge1xuICAgIHJldHVybiBkYXRhcG9pbnRzLm1hcCgoZHA6IEtQSURldGFpbHMpID0+IHtcbiAgICAgIGNvbnN0IHNlcmllc0RhdGE6IElTZXJpZXMgPSBkYXRhcG9pbnRzU2VyaWVzRGF0YU1hcC5nZXQoZHAuX190YXJnZXQuaWQpO1xuXG4gICAgICBpZiAoIXNlcmllc0RhdGEpIHtcbiAgICAgICAgcmV0dXJuIHsgLi4uZHAsIHZhbHVlczoge30gfTtcbiAgICAgIH1cblxuICAgICAgLy8gRmluZCBhbiBpbmRleCBvZiBhIGNvcnJlc3BvbmRpbmcgZGF0YXBvaW50IGRhdGEsIHdpdGhpbiBzZXJpZXMgb2JqZWN0LlxuICAgICAgY29uc3QgZGF0YXBvaW50U2VyaWVzQXJyYXlJbmRleCA9IHNlcmllc0RhdGEuc2VyaWVzLmZpbmRJbmRleChcbiAgICAgICAgcyA9PiBzLm5hbWUgPT09IGRwLnNlcmllcyAmJiBzLnR5cGUgPT09IGRwLmZyYWdtZW50XG4gICAgICApO1xuXG4gICAgICBjb25zdCB2YWx1ZXNGaWx0ZXJlZEJ5RGF0YXBvaW50U2VyaWVzQXJyYXlJbmRleDogTWVhc3VyZW1lbnRSYW5nZXMgPSBPYmplY3QuZnJvbUVudHJpZXMoXG4gICAgICAgIE9iamVjdC5lbnRyaWVzKHNlcmllc0RhdGEudmFsdWVzKS5tYXAoKFtrZXksIGFycl0pID0+IFtcbiAgICAgICAgICBrZXksXG4gICAgICAgICAgYXJyLmZpbHRlcigoXywgaW5kZXgpID0+IGluZGV4ID09PSBkYXRhcG9pbnRTZXJpZXNBcnJheUluZGV4KVxuICAgICAgICBdKVxuICAgICAgKTtcblxuICAgICAgcmV0dXJuIHtcbiAgICAgICAgLi4uZHAsXG4gICAgICAgIHNlcmllc1VuaXQ6IHNlcmllc0RhdGEuc2VyaWVzW2RhdGFwb2ludFNlcmllc0FycmF5SW5kZXhdPy51bml0LFxuICAgICAgICB2YWx1ZXM6IHZhbHVlc0ZpbHRlcmVkQnlEYXRhcG9pbnRTZXJpZXNBcnJheUluZGV4XG4gICAgICB9O1xuICAgIH0pO1xuICB9XG5cbiAgLyoqXG4gICAqIENyZWF0ZXMgdGhlIGNvbHVtbiBoZWFkZXJzIGZvciB0aGUgZGV2aWNlcyBpbiB0aGUgZGF0YSBwb2ludHMgdGFibGUuXG4gICAqXG4gICAqIEBwYXJhbSBkYXRhcG9pbnRzV2l0aFZhbHVlcyAtIEFuIGFycmF5IG9mIGRhdGEgcG9pbnRzLlxuICAgKiBAcmV0dXJucyBBbiBhcnJheSBvZiBjb2x1bW4gaGVhZGVycyBmb3IgdGhlIGRldmljZXMuXG4gICAqL1xuICBnZXRDb2x1bW5IZWFkZXJzKGRhdGFwb2ludHNXaXRoVmFsdWVzOiBLUElEZXRhaWxzW10pOiBUYWJsZUNvbHVtbkhlYWRlcltdIHtcbiAgICByZXR1cm4gZGF0YXBvaW50c1dpdGhWYWx1ZXMubWFwKFxuICAgICAgKHsgX190YXJnZXQ6IHsgbmFtZSB9LCBsYWJlbCwgcmVuZGVyVHlwZSwgdW5pdCB9KTogVGFibGVDb2x1bW5IZWFkZXIgPT4ge1xuICAgICAgICByZXR1cm4geyBkZXZpY2VOYW1lOiBuYW1lLCBsYWJlbCwgcmVuZGVyVHlwZSwgdW5pdCB9O1xuICAgICAgfVxuICAgICk7XG4gIH1cblxuICBtYXBEYXRhcG9pbnRzV2l0aFZhbHVlc1RvTGlzdChkYXRhcG9pbnRzV2l0aFZhbHVlczogRGF0YXBvaW50V2l0aFZhbHVlc1tdKTogRGF0YXBvaW50VGFibGVJdGVtW10ge1xuICAgIHJldHVybiBkYXRhcG9pbnRzV2l0aFZhbHVlcy5mbGF0TWFwKGRwID0+IHtcbiAgICAgIGlmICghZHAudmFsdWVzKSB7XG4gICAgICAgIHJldHVybiBbXTtcbiAgICAgIH1cbiAgICAgIHJldHVybiBPYmplY3QuZW50cmllcyhkcC52YWx1ZXMpLmZsYXRNYXAoKFtkYXRlLCB2YWx1ZXNBcnJheV0pID0+IHtcbiAgICAgICAgY29uc3QgdmFsdWUgPSB0aGlzLmZpbmRNaW5NYXhWYWx1ZXModmFsdWVzQXJyYXkpO1xuICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkge1xuICAgICAgICAgIHJldHVybiBbXTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gW1xuICAgICAgICAgIHtcbiAgICAgICAgICAgIGRhdGVBbmRUaW1lOiBkYXRlLFxuICAgICAgICAgICAgZGV2aWNlTmFtZTogZHAuX190YXJnZXQubmFtZSxcbiAgICAgICAgICAgIGZyYWdtZW50OiBkcC5mcmFnbWVudCxcbiAgICAgICAgICAgIGxhYmVsOiBkcC5sYWJlbCxcbiAgICAgICAgICAgIHJlZFJhbmdlTWF4OiBkcC5yZWRSYW5nZU1heCxcbiAgICAgICAgICAgIHJlZFJhbmdlTWluOiBkcC5yZWRSYW5nZU1pbixcbiAgICAgICAgICAgIHJlbmRlclR5cGU6IGRwLnJlbmRlclR5cGUsXG4gICAgICAgICAgICBzZXJpZXM6IGRwLnNlcmllcyxcbiAgICAgICAgICAgIHZhbHVlOiB2YWx1ZSxcbiAgICAgICAgICAgIHllbGxvd1JhbmdlTWF4OiBkcC55ZWxsb3dSYW5nZU1heCxcbiAgICAgICAgICAgIHllbGxvd1JhbmdlTWluOiBkcC55ZWxsb3dSYW5nZU1pblxuICAgICAgICAgIH1cbiAgICAgICAgXTtcbiAgICAgIH0pO1xuICAgIH0pO1xuICB9XG5cbiAgLyoqXG4gICAqIEZpbmRzIHRoZSBvdmVyYWxsIG1pbmltdW0gYW5kIG1heGltdW0gdmFsdWVzIGZyb20gYW4gYXJyYXkgb2Ygb2JqZWN0cyBjb250YWluaW5nICdtaW4nIGFuZCAnbWF4JyBwcm9wZXJ0aWVzLlxuICAgKlxuICAgKiBJZiB0aGUgYXJyYXkgY29udGFpbnMgb25seSBvbmUgb2JqZWN0LCB0aGF0IG9iamVjdCdzICdtaW4nIGFuZCAnbWF4JyB2YWx1ZXMgd2lsbCBiZSByZXR1cm5lZC5cbiAgICpcbiAgICogQHBhcmFtIHZhbHVlc0FycmF5IC0gQW4gYXJyYXkgd2l0aCBvYmplY3RzLCB3aGVyZSBlYWNoIGNvbnRhaW5zICdtaW4nIGFuZCAnbWF4JyBwcm9wZXJ0aWVzLlxuICAgKiBAcmV0dXJucyBBbiBvYmplY3Qgd2l0aCB0aGUgc21hbGxlc3QgJ21pbicgYW5kIGxhcmdlc3QgJ21heCcgdmFsdWVzIGZvdW5kIGluIHRoZSBhcnJheS5cbiAgICpcbiAgICogQGV4YW1wbGVcbiAgICogY29uc3QgdmFsdWVzID0gW1xuICAgKiAgIHsgbWluOiAxLCBtYXg6IDEwIH1cbiAgICogXTtcbiAgICpcbiAgICogY29uc3QgcmVzdWx0ID0gZmluZE1pbk1heFZhbHVlcyh2YWx1ZXMpO1xuICAgKiAvLyByZXN1bHQgaXMgeyBtaW46IDEsIG1heDogMTAgfVxuICAgKi9cbiAgZmluZE1pbk1heFZhbHVlcyh2YWx1ZXNBcnJheTogTWluTWF4VmFsdWVzW10pOiBWYWx1ZSB8IG51bGwge1xuICAgIGNvbnN0IHZhbGlkSXRlbXMgPSB2YWx1ZXNBcnJheS5maWx0ZXIoXG4gICAgICAoaXRlbSk6IGl0ZW0gaXMgVmFsdWUgPT4gaXRlbSAmJiBpdGVtLm1pbiAhPSBudWxsICYmIGl0ZW0ubWF4ICE9IG51bGxcbiAgICApO1xuXG4gICAgaWYgKHZhbGlkSXRlbXMubGVuZ3RoID09PSAwKSB7XG4gICAgICByZXR1cm4gbnVsbDtcbiAgICB9XG5cbiAgICBjb25zdCBpbml0aWFsVmFsdWU6IFZhbHVlID0geyBtaW46IHZhbGlkSXRlbXNbMF0ubWluLCBtYXg6IHZhbGlkSXRlbXNbMF0ubWF4IH07XG5cbiAgICByZXR1cm4gdmFsaWRJdGVtcy5yZWR1Y2U8VmFsdWU+KFxuICAgICAgKGFjYywgaXRlbSkgPT4gKHtcbiAgICAgICAgbWluOiBNYXRoLm1pbihhY2MubWluLCBpdGVtLm1pbiksXG4gICAgICAgIG1heDogTWF0aC5tYXgoYWNjLm1heCwgaXRlbS5tYXgpXG4gICAgICB9KSxcbiAgICAgIGluaXRpYWxWYWx1ZVxuICAgICk7XG4gIH1cblxuICAvKipcbiAgICogR3JvdXBzIGEgbGlzdCBvZiBkYXRhIHBvaW50cyBieSBkYXRlIGFuZCBkZXZpY2UsIGJhc2VkIG9uIGdpdmVuIHJlZmVyZW5jZXMuXG4gICAqXG4gICAqIEBwYXJhbSBkYXRhTGlzdCAtIFRoZSBsaXN0IG9mIGRhdGEgcG9pbnRzIHRvIGJlIGdyb3VwZWQuXG4gICAqIEBwYXJhbSByZWZlcmVuY2VzIC0gVGhlIGNvbHVtbiBoZWFkZXJzIHRoYXQgc2VydmUgYXMgcmVmZXJlbmNlcyBmb3IgZ3JvdXBpbmcuXG4gICAqIEByZXR1cm5zIEFuIGFycmF5IG9mIGdyb3VwZWQgZGF0YSBwb2ludHMsIHdoZXJlIGVhY2ggZ3JvdXAgY29ycmVzcG9uZHMgdG8gYSB1bmlxdWUgZGF0ZSBhbmQgZGV2aWNlLlxuICAgKi9cbiAgZ3JvdXBCeURhdGVBbmREZXZpY2UoXG4gICAgZGF0YUxpc3Q6IERhdGFwb2ludFRhYmxlSXRlbVtdLFxuICAgIHJlZmVyZW5jZXM6IFRhYmxlQ29sdW1uSGVhZGVyW11cbiAgKTogR3JvdXBlZERhdGFwb2ludFRhYmxlSXRlbVtdIHtcbiAgICBjb25zdCBtYXAgPSB0aGlzLmdlbmVyYXRlRGF0YVBvaW50TWFwKGRhdGFMaXN0LCByZWZlcmVuY2VzKTtcbiAgICByZXR1cm4gdGhpcy5tZXJnZURhdGFwb2ludHMobWFwKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBHZW5lcmF0ZXMgYW5kIHBvcHVsYXRlcyBhIG1hcCB3aXRoIGRhdGEgcG9pbnRzLlxuICAgKlxuICAgKiBUaGlzIGZ1bmN0aW9uIHByb2Nlc3NlcyB0aGUgcHJvdmlkZWQgZGF0YSBwb2ludHMgYW5kIG9yZ2FuaXplcyB0aGVtIGludG8gYSBtYXAgc3RydWN0dXJlXG4gICAqIHdoZXJlIGVhY2gga2V5IGlzIGEgdW5pcXVlIGNvbWJpbmF0aW9uIG9mIGRhdGUgYW5kIGRldmljZSBpZGVudGlmaWVycywgYW5kIHRoZSB2YWx1ZSBpcyBhblxuICAgKiBhcnJheSBvZiBkYXRhIHBvaW50cyAob3IgbnVsbCB2YWx1ZXMpIGFzc29jaWF0ZWQgd2l0aCB0aGF0IGtleS4gVGhpcyBzdHJ1Y3R1cmVkIGRhdGEgaXMgdGhlblxuICAgKiB1c2VkIGluIHRoZSBkYXRhIHBvaW50IHRhYmxlIHRvIHJlbmRlciB0aGUgZGF0YSBhcHByb3ByaWF0ZWx5LlxuICAgKlxuICAgKiBAcGFyYW0gZGF0YUxpc3QgLSBUaGUgbGlzdCBvZiBkYXRhIHBvaW50IHRhYmxlIGl0ZW1zIHRvIGJlIHByb2Nlc3NlZC5cbiAgICogQHBhcmFtIGNvbHVtbnNIZWFkZXJzUmVmZXJlbmNlcyAtIFRoZSBsaXN0IG9mIGNvbHVtbiBoZWFkZXJzIHVzZWQgdG8gZGV0ZXJtaW5lIHRoZSBvcmRlciBhbmQgc3RydWN0dXJlIG9mIHRoZSBtYXAgdmFsdWVzLlxuICAgKiBAcmV0dXJucyBBIG1hcCB3aGVyZSB0aGUga2V5IGlzIGEgZGF0YXBvaW50IGlkZW50aWZpZXIgY29udGFpbmluZyB0aGUgZGF0ZSBhbmQgZGV2aWNlIG5hbWUsIGFuZCB0aGUgdmFsdWUgaXMgYW4gYXJyYXkgb2YgZGF0YSBwb2ludCB0YWJsZSBpdGVtcyBvciBudWxsLlxuICAgKi9cbiAgZ2VuZXJhdGVEYXRhUG9pbnRNYXAoXG4gICAgZGF0YUxpc3Q6IERhdGFwb2ludFRhYmxlSXRlbVtdLFxuICAgIGNvbHVtbnNIZWFkZXJzUmVmZXJlbmNlczogVGFibGVDb2x1bW5IZWFkZXJbXVxuICApOiBEYXRhUG9pbnRzVGFibGVNYXAge1xuICAgIC8vIE1hcCB0byBzdG9yZSB0aGUgZGF0YSBwb2ludHMgaW5kZXhlZCBieSBhIHVuaXF1ZSBpZGVudGlmaWVyLlxuICAgIGNvbnN0IG1hcDogRGF0YVBvaW50c1RhYmxlTWFwID0gbmV3IE1hcDxEYXRhcG9pbnRUYWJsZU1hcEtleSwgKERhdGFwb2ludFRhYmxlSXRlbSB8IG51bGwpW10+KCk7XG5cbiAgICBkYXRhTGlzdC5mb3JFYWNoKG9iaiA9PiB7XG4gICAgICAvLyBHZW5lcmF0ZSBhIHVuaXF1ZSBpZGVudGlmaWVyIGZvciBlYWNoIGRhdGEgcG9pbnQgdXNpbmcgdGhlIGRhdGUgYW5kIGRldmljZSBuYW1lLlxuICAgICAgY29uc3QgZGF0ZUtleSA9IHRoaXMudG9JU09Gb3JtYXQob2JqLmRhdGVBbmRUaW1lKTtcbiAgICAgIGNvbnN0IGRhdGFwb2ludElkZW50aWZpZXI6IERhdGFwb2ludFRhYmxlTWFwS2V5ID0gYCR7ZGF0ZUtleX1fJHtvYmouZGV2aWNlTmFtZX1gO1xuXG4gICAgICAvLyBJbml0aWFsaXplIHRoZSBtYXAgZW50cnkgaWYgaXQgZG9lcyBub3QgZXhpc3Qgd2l0aCBhIHVuaXF1ZSBpZGVudGlmaWVyLlxuICAgICAgaWYgKCFtYXAuaGFzKGRhdGFwb2ludElkZW50aWZpZXIpKSB7XG4gICAgICAgIG1hcC5zZXQoZGF0YXBvaW50SWRlbnRpZmllciwgQXJyYXkoY29sdW1uc0hlYWRlcnNSZWZlcmVuY2VzLmxlbmd0aCkuZmlsbChudWxsKSk7XG4gICAgICB9XG5cbiAgICAgIC8vIEZpbmQgdGhlIGluZGV4IG9mIHRoZSByZWZlcmVuY2UgdGhhdCBtYXRjaGVzIHRoZSBjdXJyZW50IGRhdGEgcG9pbnQuXG4gICAgICBjb25zdCBtYXRjaGluZ0NvbHVtbkluZGV4ID0gY29sdW1uc0hlYWRlcnNSZWZlcmVuY2VzLmZpbmRJbmRleChcbiAgICAgICAgcmVmID0+IHJlZi5kZXZpY2VOYW1lID09PSBvYmouZGV2aWNlTmFtZSAmJiByZWYubGFiZWwgPT09IG9iai5sYWJlbFxuICAgICAgKTtcblxuICAgICAgLy8gVXBkYXRlIHRoZSBtYXAgZW50cnkgd2l0aCB0aGUgZGF0YSBwb2ludC5cbiAgICAgIGNvbnN0IHRhYmxlSXRlbTogRGF0YXBvaW50VGFibGVJdGVtW10gPSBtYXAuZ2V0KGRhdGFwb2ludElkZW50aWZpZXIpO1xuICAgICAgaWYgKHRhYmxlSXRlbSkge1xuICAgICAgICB0YWJsZUl0ZW1bbWF0Y2hpbmdDb2x1bW5JbmRleF0gPSB7IC4uLm9iaiB9O1xuICAgICAgfVxuICAgIH0pO1xuXG4gICAgcmV0dXJuIG1hcDtcbiAgfVxuXG4gIC8qKlxuICAgKiBNZXJnZXMgdGhlIGRhdGEgcG9pbnRzIGZyb20gdGhlIGdpdmVuIG1hcCBpbnRvIGFuIGFycmF5IG9mIGdyb3VwZWQgZGF0YSBwb2ludCB0YWJsZSBpdGVtcy5cbiAgICpcbiAgICogQHBhcmFtIG1hcCAtIFRoZSBtYXAgY29udGFpbmluZyB0aGUgZGF0YSBwb2ludHMgdG8gYmUgbWVyZ2VkLlxuICAgKiBAcmV0dXJucyBBbiBhcnJheSBvZiBncm91cGVkIGRhdGEgcG9pbnQgdGFibGUgaXRlbXMuXG4gICAqL1xuICBtZXJnZURhdGFwb2ludHMobWFwOiBEYXRhUG9pbnRzVGFibGVNYXApOiBHcm91cGVkRGF0YXBvaW50VGFibGVJdGVtW10ge1xuICAgIGNvbnN0IG1lcmdlZERhdGE6IEdyb3VwZWREYXRhcG9pbnRUYWJsZUl0ZW1bXSA9IFtdO1xuXG4gICAgbWFwLmZvckVhY2goKHZhbHVlcywgZGF0YXBvaW50SWRlbnRpZmllcikgPT4ge1xuICAgICAgY29uc3QgW2RhdGVLZXksIGRldmljZU5hbWVdID0gZGF0YXBvaW50SWRlbnRpZmllci5zcGxpdCgnXycpO1xuICAgICAgY29uc3QgdmFsaWREYXRhUG9pbnQgPSB2YWx1ZXMuc29tZShpdGVtID0+IGl0ZW0gJiYgT2JqZWN0LmtleXMoaXRlbS52YWx1ZSkubGVuZ3RoID4gMCk7XG5cbiAgICAgIGlmICh2YWxpZERhdGFQb2ludCkge1xuICAgICAgICBtZXJnZWREYXRhLnB1c2goe1xuICAgICAgICAgIGRhdGVBbmRUaW1lOiBkYXRlS2V5LFxuICAgICAgICAgIGRldmljZU5hbWU6IGRldmljZU5hbWUsXG4gICAgICAgICAgcm93SXRlbXM6IHZhbHVlcy5tYXAoaXRlbSA9PiAoaXRlbSA/IHsgLi4uaXRlbSB9IDogbnVsbCkpXG4gICAgICAgIH0pO1xuICAgICAgfVxuICAgIH0pO1xuXG4gICAgcmV0dXJuIG1lcmdlZERhdGE7XG4gIH1cblxuICBzb3J0RGF0YUJ5RGF0ZURlc2NlbmRpbmcoZGF0YTogR3JvdXBlZERhdGFwb2ludFRhYmxlSXRlbVtdKTogR3JvdXBlZERhdGFwb2ludFRhYmxlSXRlbVtdIHtcbiAgICByZXR1cm4gZGF0YS5zb3J0KFxuICAgICAgKGEsIGIpID0+IG5ldyBEYXRlKGIuZGF0ZUFuZFRpbWUpLmdldFRpbWUoKSAtIG5ldyBEYXRlKGEuZGF0ZUFuZFRpbWUpLmdldFRpbWUoKVxuICAgICk7XG4gIH1cblxuICAvKipcbiAgICogUHJlcGFyZXMgdGhlIHVwZGF0ZWQgdGltZSByYW5nZSBiYXNlZCBvbiB0aGUgc2VsZWN0ZWQgaW50ZXJ2YWwuXG4gICAqXG4gICAqIEluIGNhc2Ugb2YgYSAnY3VzdG9tJyBpbnRlcnZhbCBvciBubyBxdWFudGl0eSwgdGhlIG9yaWdpbmFsIGRhdGUgcmFuZ2UgaXMgcmV0dXJuZWQuXG4gICAqXG4gICAqIEBwYXJhbSBpbnRlcnZhbCAtIFRoZSBzZWxlY3RlZCBpbnRlcnZhbCB0eXBlLlxuICAgKiBAcmV0dXJucyBBbiBvYmplY3QgY29udGFpbmluZyB0aGUgYGRhdGVGcm9tYCBhbmQgYGRhdGVUb2AgaW4gSVNPIHN0cmluZyBmb3JtYXQuXG4gICAqL1xuICBwcmVwYXJlVGltZVJhbmdlKFxuICAgIGludGVydmFsOiBUaW1lUmFuZ2VJbnRlcnZhbCxcbiAgICBkYXRlRnJvbUlucHV0OiBzdHJpbmcsXG4gICAgZGF0ZVRvSW5wdXQ6IHN0cmluZ1xuICApOiB7IGRhdGVGcm9tOiBzdHJpbmc7IGRhdGVUbzogc3RyaW5nIH0ge1xuICAgIGlmICghaW50ZXJ2YWwgfHwgaW50ZXJ2YWwgPT09IFRJTUVfUkFOR0VfSU5URVJWQUxfVU5JVFNfVkFMVUVTLmN1c3RvbSkge1xuICAgICAgcmV0dXJuIHsgZGF0ZUZyb206IGRhdGVGcm9tSW5wdXQsIGRhdGVUbzogZGF0ZVRvSW5wdXQgfTtcbiAgICB9XG5cbiAgICBjb25zdCBzZWxlY3RlZDogRHVyYXRpb24gPSBEVVJBVElPTl9PUFRJT05TLmZpbmQoXG4gICAgICBzZWxlY3RlZER1cmF0aW9uID0+IHNlbGVjdGVkRHVyYXRpb24uaWQgPT09IGludGVydmFsXG4gICAgKTtcblxuICAgIGlmICghc2VsZWN0ZWQ/LmFtb3VudCkge1xuICAgICAgcmV0dXJuIHsgZGF0ZUZyb206IGRhdGVGcm9tSW5wdXQsIGRhdGVUbzogZGF0ZVRvSW5wdXQgfTtcbiAgICB9XG5cbiAgICBjb25zdCBub3cgPSBuZXcgRGF0ZSgpO1xuXG4gICAgcmV0dXJuIHtcbiAgICAgIGRhdGVGcm9tOiB0aGlzLnN1YnRyYWN0VGltZShub3csIHNlbGVjdGVkLmFtb3VudCwgc2VsZWN0ZWQudW5pdCkudG9JU09TdHJpbmcoKSxcbiAgICAgIGRhdGVUbzogbm93LnRvSVNPU3RyaW5nKClcbiAgICB9O1xuICB9XG5cbiAgLyoqXG4gICAqIFN1YnRyYWN0cyBhbiBhbW91bnQgb2YgdGltZSBmcm9tIGEgZ2l2ZW4gZGF0ZS5cbiAgICpcbiAgICogQHBhcmFtIGRhdGUgLSBUaGUgb3JpZ2luYWwgZGF0ZS5cbiAgICogQHBhcmFtIGFtb3VudCAtIFRoZSBhbW91bnQgb2YgdGltZSB1bml0cyB0byBzdWJ0cmFjdC5cbiAgICogQHBhcmFtIHVuaXQgLSBUaGUgdW5pdCBvZiB0aW1lIHRvIHN1YnRyYWN0IChlLmcuLCBtaW51dGVzLCBob3VycywgZGF5cywgd2Vla3MsIG1vbnRocykuXG4gICAqIEByZXR1cm5zIEEgbmV3IGRhdGUgd2l0aCB0aGUgc3BlY2lmaWVkIHRpbWUgc3VidHJhY3RlZC5cbiAgICovXG4gIHN1YnRyYWN0VGltZShkYXRlOiBEYXRlLCBhbW91bnQ6IG51bWJlciwgdW5pdDogc3RyaW5nKTogRGF0ZSB7XG4gICAgY29uc3QgbmV3RGF0ZSA9IG5ldyBEYXRlKGRhdGUpO1xuXG4gICAgc3dpdGNoICh1bml0KSB7XG4gICAgICBjYXNlIFRJTUVfUkFOR0VfSU5URVJWQUxfVU5JVFNfVkFMVUVTLm1pbnV0ZXM6XG4gICAgICAgIG5ld0RhdGUuc2V0VVRDTWludXRlcyhuZXdEYXRlLmdldFVUQ01pbnV0ZXMoKSAtIGFtb3VudCk7XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSBUSU1FX1JBTkdFX0lOVEVSVkFMX1VOSVRTX1ZBTFVFUy5ob3VyczpcbiAgICAgICAgbmV3RGF0ZS5zZXRVVENIb3VycyhuZXdEYXRlLmdldFVUQ0hvdXJzKCkgLSBhbW91bnQpO1xuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgVElNRV9SQU5HRV9JTlRFUlZBTF9VTklUU19WQUxVRVMuZGF5czpcbiAgICAgICAgbmV3RGF0ZS5zZXRVVENEYXRlKG5ld0RhdGUuZ2V0VVRDRGF0ZSgpIC0gYW1vdW50KTtcbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlIFRJTUVfUkFOR0VfSU5URVJWQUxfVU5JVFNfVkFMVUVTLndlZWtzOlxuICAgICAgICBuZXdEYXRlLnNldFVUQ0RhdGUobmV3RGF0ZS5nZXRVVENEYXRlKCkgLSBhbW91bnQgKiA3KTtcbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlIFRJTUVfUkFOR0VfSU5URVJWQUxfVU5JVFNfVkFMVUVTLm1vbnRoczpcbiAgICAgICAgdGhpcy5zdWJ0cmFjdE1vbnRoc0FuZEFkanVzdERheShuZXdEYXRlLCBhbW91bnQpO1xuICAgICAgICBicmVhaztcbiAgICB9XG4gICAgcmV0dXJuIG5ld0RhdGU7XG4gIH1cblxuICBnZXRTZXJpZXNXaXRob3V0UGVybWlzc2lvblRvUmVhZChcbiAgICBhY3RpdmVEYXRhcG9pbnRzU2VyaWVzRGF0YTogTWFwPHN0cmluZyB8IG51bWJlciwgSVNlcmllcz4gfCB1bmRlZmluZWQsXG4gICAgYWN0aXZlRGF0YXBvaW50c0lkc1dpdGhTZXJpZXM6IERhdGFwb2ludHNWYWx1ZXNEYXRhTWFwXG4gICk6IHsga2V5OiBTb3VyY2VJZDsgdmFsdWU6IHN0cmluZ1tdIH1bXSB7XG4gICAgaWYgKCFhY3RpdmVEYXRhcG9pbnRzU2VyaWVzRGF0YSkge1xuICAgICAgLy8gUmV0dXJucyBhbGwgYWN0aXZlRGF0YXBvaW50c0lkc1dpdGhTZXJpZXMgZW50cmllcyBpZiBhY3RpdmVEYXRhcG9pbnRzU2VyaWVzRGF0YSBpcyB1bmRlZmluZWQuXG4gICAgICAvLyBJdCBtZWFucyB0aGF0IHRoZSB1c2VyIGRvZXMgbm90IGhhdmUgcGVybWlzc2lvbiB0byBzZWUgYW55IG9mIHRoZSBzZWxlY3RlZCBkYXRhcG9pbnRzIGRhdGEuXG4gICAgICByZXR1cm4gQXJyYXkuZnJvbShhY3RpdmVEYXRhcG9pbnRzSWRzV2l0aFNlcmllcywgbWFwVG9Tb3VyY2VWYWx1ZU9iamVjdCk7XG4gICAgfVxuXG4gICAgY29uc3QgYXZhaWxhYmxlU291cmNlcyA9IG5ldyBTZXQoYWN0aXZlRGF0YXBvaW50c1Nlcmllc0RhdGEua2V5cygpKTtcblxuICAgIHJldHVybiBBcnJheS5mcm9tKGFjdGl2ZURhdGFwb2ludHNJZHNXaXRoU2VyaWVzKVxuICAgICAgLmZpbHRlcigoW3NvdXJjZV0pID0+ICFhdmFpbGFibGVTb3VyY2VzLmhhcyhzb3VyY2UpKVxuICAgICAgLm1hcChtYXBUb1NvdXJjZVZhbHVlT2JqZWN0KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBDb252ZXJ0cyBhIGRhdGUgc3RyaW5nIHRvIElTTyBmb3JtYXQuXG4gICAqXG4gICAqIEBwYXJhbSBkYXRlU3RyIC0gVGhlIGRhdGUgc3RyaW5nIHRvIGNvbnZlcnQuXG4gICAqIEByZXR1cm5zIFRoZSBJU08gZm9ybWF0IG9mIHRoZSBnaXZlbiBkYXRlIHN0cmluZy5cbiAgICovXG4gIHByaXZhdGUgdG9JU09Gb3JtYXQoZGF0ZVN0cjogc3RyaW5nKTogc3RyaW5nIHtcbiAgICByZXR1cm4gbmV3IERhdGUoZGF0ZVN0cikudG9JU09TdHJpbmcoKTtcbiAgfVxuXG4gIHByaXZhdGUgZmlsdGVyT3V0RWxlbWVudHNXaXRoRm9yYmlkZGVuUmVzcG9uc2VzKFxuICAgIHNlcmllc0RhdGFXaXRoUmVzcG9uc2U6IFNlcmllc0RhdGFXaXRoUmVzcG9uc2VbXVxuICApOiBTZXJpZXNEYXRhV2l0aFJlc3BvbnNlW10ge1xuICAgIHJldHVybiBzZXJpZXNEYXRhV2l0aFJlc3BvbnNlLmZpbHRlcihpdGVtID0+IHtcbiAgICAgIHJldHVybiAhKGl0ZW0ucmVzPy5zdGF0dXMgPT09IDQwMyk7XG4gICAgfSk7XG4gIH1cblxuICBwcml2YXRlIHN1YnRyYWN0TW9udGhzQW5kQWRqdXN0RGF5KGRhdGU6IERhdGUsIG1vbnRoc1RvU3VidHJhY3Q6IG51bWJlcik6IHZvaWQge1xuICAgIGNvbnN0IGN1cnJlbnRNb250aCA9IGRhdGUuZ2V0VVRDTW9udGgoKTtcbiAgICBjb25zdCBleHBlY3RlZFRhcmdldE1vbnRoID0gdGhpcy5jYWxjdWxhdGVUYXJnZXRNb250aChjdXJyZW50TW9udGgsIG1vbnRoc1RvU3VidHJhY3QpO1xuXG4gICAgZGF0ZS5zZXRVVENNb250aChjdXJyZW50TW9udGggLSBtb250aHNUb1N1YnRyYWN0KTtcblxuICAgIGNvbnN0IGFjdHVhbE1vbnRoID0gZGF0ZS5nZXRVVENNb250aCgpO1xuICAgIGNvbnN0IGRheURvZXNOb3RFeGlzdEluVGFyZ2V0TW9udGggPSBhY3R1YWxNb250aCAhPT0gZXhwZWN0ZWRUYXJnZXRNb250aDtcblxuICAgIGlmIChkYXlEb2VzTm90RXhpc3RJblRhcmdldE1vbnRoKSB7XG4gICAgICB0aGlzLnNldFRvTGFzdERheU9mUHJldmlvdXNNb250aChkYXRlKTtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogQ2FsY3VsYXRlcyB0aGUgdGFyZ2V0IG1vbnRoIG51bWJlciAoMC0xMSkgYWZ0ZXIgc3VidHJhY3RpbmcgbW9udGhzIGZyb20gdGhlIGN1cnJlbnQgbW9udGguXG4gICAqIEhhbmRsZXMgbmVnYXRpdmUgbW9udGggbnVtYmVycyBieSBub3JtYWxpemluZyB0aGVtIHRvIHRoZSB2YWxpZCAwLTExIHJhbmdlLlxuICAgKlxuICAgKiBFeGFtcGxlczpcbiAgICogLSBKYW51YXJ5KDApIC0gMSBtb250aCA9IERlY2VtYmVyKDExKVxuICAgKiAtIE1hcmNoKDIpIC0gNCBtb250aHMgPSBOb3ZlbWJlcigxMClcbiAgICogLSBEZWNlbWJlcigxMSkgLSAxIG1vbnRoID0gTm92ZW1iZXIoMTApXG4gICAqXG4gICAqIEBwYXJhbSBjdXJyZW50TW9udGggLSBDdXJyZW50IG1vbnRoICgwLTExLCB3aGVyZSAwIGlzIEphbnVhcnkpXG4gICAqIEBwYXJhbSBtb250aHNUb1N1YnRyYWN0IC0gTnVtYmVyIG9mIG1vbnRocyB0byBzdWJ0cmFjdFxuICAgKiBAcmV0dXJucyBOb3JtYWxpemVkIG1vbnRoIG51bWJlciBpbiByYW5nZSAwLTExXG4gICAqL1xuICBwcml2YXRlIGNhbGN1bGF0ZVRhcmdldE1vbnRoKGN1cnJlbnRNb250aDogbnVtYmVyLCBtb250aHNUb1N1YnRyYWN0OiBudW1iZXIpOiBudW1iZXIge1xuICAgIHJldHVybiAoY3VycmVudE1vbnRoIC0gbW9udGhzVG9TdWJ0cmFjdCArIDEyKSAlIDEyO1xuICB9XG5cbiAgLyoqXG4gICAqIFNldHMgdGhlIGRhdGUgdG8gdGhlIGxhc3QgZGF5IG9mIHRoZSBwcmV2aW91cyBtb250aC5cbiAgICogVXNpbmcgMCBhcyBkYXRlVmFsdWUgbWFrZXMgSmF2YVNjcmlwdCBhdXRvbWF0aWNhbGx5IGNhbGN1bGF0ZVxuICAgKiBsYXN0IGRheSBvZiBwcmV2aW91cyBtb250aCwgcGVyIEphdmFTY3JpcHQgRGF0ZSBBUEkgYmVoYXZpb3IuXG4gICAqIEBwYXJhbSBkYXRlIC0gRGF0ZSB0byBtb2RpZnlcbiAgICovXG4gIHByaXZhdGUgc2V0VG9MYXN0RGF5T2ZQcmV2aW91c01vbnRoKGRhdGU6IERhdGUpOiB2b2lkIHtcbiAgICBkYXRlLnNldFVUQ0RhdGUoMCk7XG4gIH1cbn1cbiJdfQ==
@@ -0,0 +1,75 @@
1
+ import { Directive, ElementRef, EventEmitter, Input, NgZone, Output } from '@angular/core';
2
+ import * as i0 from "@angular/core";
3
+ /**
4
+ * Directive to listen for scroll events on a virtual scroll container.
5
+ * Emits `scrolled` and `scrolledToTop` events.
6
+ *
7
+ * The directive listens for scroll events on a virtual scroll container.
8
+ * - When the container is scrolled by at least 50 pixels (or a custom threshold), the `scrolled` event is emitted.
9
+ * - When the container is scrolled to the top, the `scrolledToTop` event is emitted.
10
+ *
11
+ */
12
+ export class VirtualScrollListenerDirective {
13
+ constructor(el, ngZone) {
14
+ this.el = el;
15
+ this.ngZone = ngZone;
16
+ /**
17
+ * Pixel threshold for emitting the scrolled event.
18
+ */
19
+ this.scrollThreshold = 50;
20
+ /**
21
+ * Event emitted when the virtual scroll container is scrolled by at least 50 pixels.
22
+ */
23
+ this.scrolled = new EventEmitter();
24
+ /**
25
+ * Event emitted when the virtual scroll container is scrolled to the top.
26
+ */
27
+ this.scrolledToTop = new EventEmitter();
28
+ this.lastScrollTop = 0;
29
+ }
30
+ ngAfterViewInit() {
31
+ this.virtualScrollContainer = this.el.nativeElement.querySelector('.cdk-virtual-scroll-viewport');
32
+ if (this.virtualScrollContainer) {
33
+ this.ngZone.runOutsideAngular(() => {
34
+ this.virtualScrollContainer.addEventListener('scroll', this.onScroll.bind(this));
35
+ });
36
+ }
37
+ }
38
+ ngOnDestroy() {
39
+ if (this.virtualScrollContainer) {
40
+ this.virtualScrollContainer.removeEventListener('scroll', this.onScroll.bind(this));
41
+ }
42
+ }
43
+ /**
44
+ * Handles the scroll event. Emits `scrolled` event if scrolled by at least `scrollThreshold` pixels
45
+ * and `scrolledToTop` event if scrolled to the top.
46
+ * @param event - The scroll event.
47
+ */
48
+ onScroll(event) {
49
+ const target = event.target;
50
+ const scrollTop = target.scrollTop;
51
+ if (Math.abs(scrollTop - this.lastScrollTop) > this.scrollThreshold) {
52
+ this.lastScrollTop = scrollTop;
53
+ this.ngZone.run(() => this.scrolled.emit());
54
+ }
55
+ if (scrollTop === 0) {
56
+ this.ngZone.run(() => this.scrolledToTop.emit());
57
+ }
58
+ }
59
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.9", ngImport: i0, type: VirtualScrollListenerDirective, deps: [{ token: i0.ElementRef }, { token: i0.NgZone }], target: i0.ɵɵFactoryTarget.Directive }); }
60
+ static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "18.2.9", type: VirtualScrollListenerDirective, isStandalone: true, selector: "[c8yVirtualScrollListener]", inputs: { scrollThreshold: "scrollThreshold" }, outputs: { scrolled: "scrolled", scrolledToTop: "scrolledToTop" }, ngImport: i0 }); }
61
+ }
62
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.9", ngImport: i0, type: VirtualScrollListenerDirective, decorators: [{
63
+ type: Directive,
64
+ args: [{
65
+ selector: '[c8yVirtualScrollListener]',
66
+ standalone: true
67
+ }]
68
+ }], ctorParameters: () => [{ type: i0.ElementRef }, { type: i0.NgZone }], propDecorators: { scrollThreshold: [{
69
+ type: Input
70
+ }], scrolled: [{
71
+ type: Output
72
+ }], scrolledToTop: [{
73
+ type: Output
74
+ }] } });
75
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidmlydHVhbC1zY3JvbGwtbGlzdGVuZXIuZGlyZWN0aXZlLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vLi4vd2lkZ2V0cy9pbXBsZW1lbnRhdGlvbnMvZGF0YXBvaW50cy10YWJsZS9kYXRhcG9pbnRzLXRhYmxlLXZpZXcvdmlydHVhbC1zY3JvbGwtbGlzdGVuZXIuZGlyZWN0aXZlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFFTCxTQUFTLEVBQ1QsVUFBVSxFQUNWLFlBQVksRUFDWixLQUFLLEVBQ0wsTUFBTSxFQUVOLE1BQU0sRUFDUCxNQUFNLGVBQWUsQ0FBQzs7QUFFdkI7Ozs7Ozs7O0dBUUc7QUFLSCxNQUFNLE9BQU8sOEJBQThCO0lBaUJ6QyxZQUNVLEVBQWMsRUFDZCxNQUFjO1FBRGQsT0FBRSxHQUFGLEVBQUUsQ0FBWTtRQUNkLFdBQU0sR0FBTixNQUFNLENBQVE7UUFsQnhCOztXQUVHO1FBQ00sb0JBQWUsR0FBRyxFQUFFLENBQUM7UUFDOUI7O1dBRUc7UUFDTyxhQUFRLEdBQUcsSUFBSSxZQUFZLEVBQVEsQ0FBQztRQUM5Qzs7V0FFRztRQUNPLGtCQUFhLEdBQUcsSUFBSSxZQUFZLEVBQVEsQ0FBQztRQUczQyxrQkFBYSxHQUFHLENBQUMsQ0FBQztJQUt2QixDQUFDO0lBRUosZUFBZTtRQUNiLElBQUksQ0FBQyxzQkFBc0IsR0FBRyxJQUFJLENBQUMsRUFBRSxDQUFDLGFBQWEsQ0FBQyxhQUFhLENBQy9ELDhCQUE4QixDQUMvQixDQUFDO1FBRUYsSUFBSSxJQUFJLENBQUMsc0JBQXNCLEVBQUUsQ0FBQztZQUNoQyxJQUFJLENBQUMsTUFBTSxDQUFDLGlCQUFpQixDQUFDLEdBQUcsRUFBRTtnQkFDakMsSUFBSSxDQUFDLHNCQUFzQixDQUFDLGdCQUFnQixDQUFDLFFBQVEsRUFBRSxJQUFJLENBQUMsUUFBUSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDO1lBQ25GLENBQUMsQ0FBQyxDQUFDO1FBQ0wsQ0FBQztJQUNILENBQUM7SUFFRCxXQUFXO1FBQ1QsSUFBSSxJQUFJLENBQUMsc0JBQXNCLEVBQUUsQ0FBQztZQUNoQyxJQUFJLENBQUMsc0JBQXNCLENBQUMsbUJBQW1CLENBQUMsUUFBUSxFQUFFLElBQUksQ0FBQyxRQUFRLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUM7UUFDdEYsQ0FBQztJQUNILENBQUM7SUFFRDs7OztPQUlHO0lBQ0ssUUFBUSxDQUFDLEtBQVk7UUFDM0IsTUFBTSxNQUFNLEdBQUcsS0FBSyxDQUFDLE1BQXFCLENBQUM7UUFDM0MsTUFBTSxTQUFTLEdBQUcsTUFBTSxDQUFDLFNBQVMsQ0FBQztRQUVuQyxJQUFJLElBQUksQ0FBQyxHQUFHLENBQUMsU0FBUyxHQUFHLElBQUksQ0FBQyxhQUFhLENBQUMsR0FBRyxJQUFJLENBQUMsZUFBZSxFQUFFLENBQUM7WUFDcEUsSUFBSSxDQUFDLGFBQWEsR0FBRyxTQUFTLENBQUM7WUFDL0IsSUFBSSxDQUFDLE1BQU0sQ0FBQyxHQUFHLENBQUMsR0FBRyxFQUFFLENBQUMsSUFBSSxDQUFDLFFBQVEsQ0FBQyxJQUFJLEVBQUUsQ0FBQyxDQUFDO1FBQzlDLENBQUM7UUFFRCxJQUFJLFNBQVMsS0FBSyxDQUFDLEVBQUUsQ0FBQztZQUNwQixJQUFJLENBQUMsTUFBTSxDQUFDLEdBQUcsQ0FBQyxHQUFHLEVBQUUsQ0FBQyxJQUFJLENBQUMsYUFBYSxDQUFDLElBQUksRUFBRSxDQUFDLENBQUM7UUFDbkQsQ0FBQztJQUNILENBQUM7OEdBekRVLDhCQUE4QjtrR0FBOUIsOEJBQThCOzsyRkFBOUIsOEJBQThCO2tCQUoxQyxTQUFTO21CQUFDO29CQUNULFFBQVEsRUFBRSw0QkFBNEI7b0JBQ3RDLFVBQVUsRUFBRSxJQUFJO2lCQUNqQjtvR0FLVSxlQUFlO3NCQUF2QixLQUFLO2dCQUlJLFFBQVE7c0JBQWpCLE1BQU07Z0JBSUcsYUFBYTtzQkFBdEIsTUFBTSIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7XG4gIEFmdGVyVmlld0luaXQsXG4gIERpcmVjdGl2ZSxcbiAgRWxlbWVudFJlZixcbiAgRXZlbnRFbWl0dGVyLFxuICBJbnB1dCxcbiAgTmdab25lLFxuICBPbkRlc3Ryb3ksXG4gIE91dHB1dFxufSBmcm9tICdAYW5ndWxhci9jb3JlJztcblxuLyoqXG4gKiBEaXJlY3RpdmUgdG8gbGlzdGVuIGZvciBzY3JvbGwgZXZlbnRzIG9uIGEgdmlydHVhbCBzY3JvbGwgY29udGFpbmVyLlxuICogRW1pdHMgYHNjcm9sbGVkYCBhbmQgYHNjcm9sbGVkVG9Ub3BgIGV2ZW50cy5cbiAqXG4gKiBUaGUgZGlyZWN0aXZlIGxpc3RlbnMgZm9yIHNjcm9sbCBldmVudHMgb24gYSB2aXJ0dWFsIHNjcm9sbCBjb250YWluZXIuXG4gKiAtIFdoZW4gdGhlIGNvbnRhaW5lciBpcyBzY3JvbGxlZCBieSBhdCBsZWFzdCA1MCBwaXhlbHMgKG9yIGEgY3VzdG9tIHRocmVzaG9sZCksIHRoZSBgc2Nyb2xsZWRgIGV2ZW50IGlzIGVtaXR0ZWQuXG4gKiAtIFdoZW4gdGhlIGNvbnRhaW5lciBpcyBzY3JvbGxlZCB0byB0aGUgdG9wLCB0aGUgYHNjcm9sbGVkVG9Ub3BgIGV2ZW50IGlzIGVtaXR0ZWQuXG4gKlxuICovXG5ARGlyZWN0aXZlKHtcbiAgc2VsZWN0b3I6ICdbYzh5VmlydHVhbFNjcm9sbExpc3RlbmVyXScsXG4gIHN0YW5kYWxvbmU6IHRydWVcbn0pXG5leHBvcnQgY2xhc3MgVmlydHVhbFNjcm9sbExpc3RlbmVyRGlyZWN0aXZlIGltcGxlbWVudHMgQWZ0ZXJWaWV3SW5pdCwgT25EZXN0cm95IHtcbiAgLyoqXG4gICAqIFBpeGVsIHRocmVzaG9sZCBmb3IgZW1pdHRpbmcgdGhlIHNjcm9sbGVkIGV2ZW50LlxuICAgKi9cbiAgQElucHV0KCkgc2Nyb2xsVGhyZXNob2xkID0gNTA7XG4gIC8qKlxuICAgKiBFdmVudCBlbWl0dGVkIHdoZW4gdGhlIHZpcnR1YWwgc2Nyb2xsIGNvbnRhaW5lciBpcyBzY3JvbGxlZCBieSBhdCBsZWFzdCA1MCBwaXhlbHMuXG4gICAqL1xuICBAT3V0cHV0KCkgc2Nyb2xsZWQgPSBuZXcgRXZlbnRFbWl0dGVyPHZvaWQ+KCk7XG4gIC8qKlxuICAgKiBFdmVudCBlbWl0dGVkIHdoZW4gdGhlIHZpcnR1YWwgc2Nyb2xsIGNvbnRhaW5lciBpcyBzY3JvbGxlZCB0byB0aGUgdG9wLlxuICAgKi9cbiAgQE91dHB1dCgpIHNjcm9sbGVkVG9Ub3AgPSBuZXcgRXZlbnRFbWl0dGVyPHZvaWQ+KCk7XG5cbiAgcHJpdmF0ZSB2aXJ0dWFsU2Nyb2xsQ29udGFpbmVyOiBIVE1MRWxlbWVudDtcbiAgcHJpdmF0ZSBsYXN0U2Nyb2xsVG9wID0gMDtcblxuICBjb25zdHJ1Y3RvcihcbiAgICBwcml2YXRlIGVsOiBFbGVtZW50UmVmLFxuICAgIHByaXZhdGUgbmdab25lOiBOZ1pvbmVcbiAgKSB7fVxuXG4gIG5nQWZ0ZXJWaWV3SW5pdCgpOiB2b2lkIHtcbiAgICB0aGlzLnZpcnR1YWxTY3JvbGxDb250YWluZXIgPSB0aGlzLmVsLm5hdGl2ZUVsZW1lbnQucXVlcnlTZWxlY3RvcihcbiAgICAgICcuY2RrLXZpcnR1YWwtc2Nyb2xsLXZpZXdwb3J0J1xuICAgICk7XG5cbiAgICBpZiAodGhpcy52aXJ0dWFsU2Nyb2xsQ29udGFpbmVyKSB7XG4gICAgICB0aGlzLm5nWm9uZS5ydW5PdXRzaWRlQW5ndWxhcigoKSA9PiB7XG4gICAgICAgIHRoaXMudmlydHVhbFNjcm9sbENvbnRhaW5lci5hZGRFdmVudExpc3RlbmVyKCdzY3JvbGwnLCB0aGlzLm9uU2Nyb2xsLmJpbmQodGhpcykpO1xuICAgICAgfSk7XG4gICAgfVxuICB9XG5cbiAgbmdPbkRlc3Ryb3koKTogdm9pZCB7XG4gICAgaWYgKHRoaXMudmlydHVhbFNjcm9sbENvbnRhaW5lcikge1xuICAgICAgdGhpcy52aXJ0dWFsU2Nyb2xsQ29udGFpbmVyLnJlbW92ZUV2ZW50TGlzdGVuZXIoJ3Njcm9sbCcsIHRoaXMub25TY3JvbGwuYmluZCh0aGlzKSk7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIEhhbmRsZXMgdGhlIHNjcm9sbCBldmVudC4gRW1pdHMgYHNjcm9sbGVkYCBldmVudCBpZiBzY3JvbGxlZCBieSBhdCBsZWFzdCBgc2Nyb2xsVGhyZXNob2xkYCBwaXhlbHNcbiAgICogYW5kIGBzY3JvbGxlZFRvVG9wYCBldmVudCBpZiBzY3JvbGxlZCB0byB0aGUgdG9wLlxuICAgKiBAcGFyYW0gZXZlbnQgLSBUaGUgc2Nyb2xsIGV2ZW50LlxuICAgKi9cbiAgcHJpdmF0ZSBvblNjcm9sbChldmVudDogRXZlbnQpOiB2b2lkIHtcbiAgICBjb25zdCB0YXJnZXQgPSBldmVudC50YXJnZXQgYXMgSFRNTEVsZW1lbnQ7XG4gICAgY29uc3Qgc2Nyb2xsVG9wID0gdGFyZ2V0LnNjcm9sbFRvcDtcblxuICAgIGlmIChNYXRoLmFicyhzY3JvbGxUb3AgLSB0aGlzLmxhc3RTY3JvbGxUb3ApID4gdGhpcy5zY3JvbGxUaHJlc2hvbGQpIHtcbiAgICAgIHRoaXMubGFzdFNjcm9sbFRvcCA9IHNjcm9sbFRvcDtcbiAgICAgIHRoaXMubmdab25lLnJ1bigoKSA9PiB0aGlzLnNjcm9sbGVkLmVtaXQoKSk7XG4gICAgfVxuXG4gICAgaWYgKHNjcm9sbFRvcCA9PT0gMCkge1xuICAgICAgdGhpcy5uZ1pvbmUucnVuKCgpID0+IHRoaXMuc2Nyb2xsZWRUb1RvcC5lbWl0KCkpO1xuICAgIH1cbiAgfVxufVxuIl19