ngx-hana-nameserver-history-viewer 1.1.2 → 1.1.9-2.beta

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 (241) hide show
  1. package/README.md +6 -5
  2. package/esm2020/ngx-hana-nameserver-history-viewer.mjs +5 -0
  3. package/esm2020/public-api.mjs +2 -0
  4. package/esm2020/src/nameserver-history-viewer/components/alert/alert.component.mjs +68 -0
  5. package/esm2020/src/nameserver-history-viewer/components/alert/alert.module.mjs +22 -0
  6. package/esm2020/src/nameserver-history-viewer/components/alert/index.mjs +3 -0
  7. package/esm2020/src/nameserver-history-viewer/components/file-drop-input/file-drop-input.component.mjs +112 -0
  8. package/esm2020/src/nameserver-history-viewer/components/file-drop-input/index.mjs +2 -0
  9. package/esm2020/src/nameserver-history-viewer/components/index.mjs +9 -0
  10. package/esm2020/src/nameserver-history-viewer/components/instruction/index.mjs +2 -0
  11. package/esm2020/src/nameserver-history-viewer/components/instruction/instruction.component.mjs +42 -0
  12. package/esm2020/src/nameserver-history-viewer/components/nameserver-history.component.mjs +550 -0
  13. package/esm2020/src/nameserver-history-viewer/components/port-selector/index.mjs +2 -0
  14. package/esm2020/src/nameserver-history-viewer/components/port-selector/port-selector.component.mjs +69 -0
  15. package/esm2020/src/nameserver-history-viewer/components/port-selector/port-selector.service.mjs +41 -0
  16. package/esm2020/src/nameserver-history-viewer/components/progress-bar/index.mjs +2 -0
  17. package/esm2020/src/nameserver-history-viewer/components/progress-bar/progress-bar.component.mjs +40 -0
  18. package/esm2020/src/nameserver-history-viewer/components/time-range-selector/index.mjs +2 -0
  19. package/esm2020/src/nameserver-history-viewer/components/time-range-selector/time-range-selector.component.mjs +70 -0
  20. package/esm2020/src/nameserver-history-viewer/components/timezone-selector/index.mjs +2 -0
  21. package/esm2020/src/nameserver-history-viewer/components/timezone-selector/timezone-selector.component.mjs +90 -0
  22. package/esm2020/src/nameserver-history-viewer/components/timezone-selector/timezone-selector.service.mjs +49 -0
  23. package/esm2020/src/nameserver-history-viewer/index.mjs +3 -0
  24. package/esm2020/src/nameserver-history-viewer/nameserver-history.module.mjs +63 -0
  25. package/esm2020/src/nameserver-history-viewer/services/chart.service.mjs +323 -0
  26. package/esm2020/src/nameserver-history-viewer/services/file.service.mjs +390 -0
  27. package/esm2020/src/nameserver-history-viewer/services/index.mjs +4 -0
  28. package/esm2020/src/nameserver-history-viewer/services/ui.service.mjs +557 -0
  29. package/esm2020/src/nameserver-history-viewer/types/abort.types.mjs +6 -0
  30. package/esm2020/src/nameserver-history-viewer/types/alert.types.mjs +8 -0
  31. package/esm2020/src/nameserver-history-viewer/types/chart-content-data-item.types.mjs +2 -0
  32. package/esm2020/src/nameserver-history-viewer/types/chart-content-data.types.mjs +2 -0
  33. package/esm2020/src/nameserver-history-viewer/types/chart-content-header.types.mjs +2 -0
  34. package/esm2020/src/nameserver-history-viewer/types/chart-content-time.types.mjs +2 -0
  35. package/esm2020/src/nameserver-history-viewer/types/chart-content.types.mjs +2 -0
  36. package/esm2020/src/nameserver-history-viewer/types/color-rgba.types.mjs +2 -0
  37. package/esm2020/src/nameserver-history-viewer/types/html-element.type.mjs +9 -0
  38. package/esm2020/src/nameserver-history-viewer/types/index.mjs +28 -0
  39. package/esm2020/src/nameserver-history-viewer/types/item.types.mjs +14 -0
  40. package/esm2020/src/nameserver-history-viewer/types/legend-color.types.mjs +2 -0
  41. package/esm2020/src/nameserver-history-viewer/types/load-history-info-backup.types.mjs +2 -0
  42. package/esm2020/src/nameserver-history-viewer/types/load-history-info-columnstore.types.mjs +2 -0
  43. package/esm2020/src/nameserver-history-viewer/types/load-history-info-host.types.mjs +2 -0
  44. package/esm2020/src/nameserver-history-viewer/types/load-history-info-item.types.mjs +2 -0
  45. package/esm2020/src/nameserver-history-viewer/types/load-history-info-persistence.types.mjs +2 -0
  46. package/esm2020/src/nameserver-history-viewer/types/load-history-info-rowstore.types.mjs +2 -0
  47. package/esm2020/src/nameserver-history-viewer/types/load-history-info-server.types.mjs +2 -0
  48. package/esm2020/src/nameserver-history-viewer/types/load-history-info-session-admission-control.types.mjs +2 -0
  49. package/esm2020/src/nameserver-history-viewer/types/load-history-info-sql.types.mjs +2 -0
  50. package/esm2020/src/nameserver-history-viewer/types/load-history-info-sync-primitives.types.mjs +2 -0
  51. package/esm2020/src/nameserver-history-viewer/types/load-history-info-threads.types.mjs +2 -0
  52. package/esm2020/src/nameserver-history-viewer/types/load-history-info.types.mjs +2 -0
  53. package/esm2020/src/nameserver-history-viewer/types/port.types.mjs +2 -0
  54. package/esm2020/src/nameserver-history-viewer/types/scale-group.types.mjs +17 -0
  55. package/esm2020/src/nameserver-history-viewer/types/unit-category.types.mjs +10 -0
  56. package/esm2020/src/nameserver-history-viewer/types/unit.types.mjs +14 -0
  57. package/esm2020/src/nameserver-history-viewer/utils/chart-util.mjs +25 -0
  58. package/esm2020/src/nameserver-history-viewer/utils/chartjs-downsample/chartjs_ext.mjs +2 -0
  59. package/esm2020/src/nameserver-history-viewer/utils/chartjs-downsample/data_culling.mjs +57 -0
  60. package/esm2020/src/nameserver-history-viewer/utils/chartjs-downsample/data_mipmap.mjs +139 -0
  61. package/esm2020/src/nameserver-history-viewer/utils/chartjs-downsample/index.mjs +41 -0
  62. package/esm2020/src/nameserver-history-viewer/utils/chartjs-downsample/lttb_data_mipmap.mjs +106 -0
  63. package/esm2020/src/nameserver-history-viewer/utils/chartjs-downsample/responsive_downsample_plugin.mjs +168 -0
  64. package/esm2020/src/nameserver-history-viewer/utils/chartjs-downsample/utils.mjs +114 -0
  65. package/esm2020/src/nameserver-history-viewer/utils/chartjs-zoom/chart.zoom.mjs +527 -0
  66. package/esm2020/src/nameserver-history-viewer/utils/chartjs-zoom/index.mjs +2 -0
  67. package/esm2020/src/nameserver-history-viewer/utils/file-util.mjs +154 -0
  68. package/esm2020/src/nameserver-history-viewer/utils/index.mjs +5 -0
  69. package/esm2020/src/nameserver-history-viewer/utils/time-util.mjs +101 -0
  70. package/esm2020/src/nameserver-history-viewer/utils/ui-util.mjs +162 -0
  71. package/fesm2015/{ngx-hana-nameserver-history-viewer.js → ngx-hana-nameserver-history-viewer.mjs} +971 -2679
  72. package/fesm2015/ngx-hana-nameserver-history-viewer.mjs.map +1 -0
  73. package/fesm2020/ngx-hana-nameserver-history-viewer.mjs +4081 -0
  74. package/fesm2020/ngx-hana-nameserver-history-viewer.mjs.map +1 -0
  75. package/ngx-hana-nameserver-history-viewer.d.ts +1 -1
  76. package/package.json +33 -57
  77. package/src/nameserver-history-viewer/components/alert/alert.component.d.ts +4 -1
  78. package/src/nameserver-history-viewer/components/alert/alert.module.d.ts +6 -0
  79. package/src/nameserver-history-viewer/components/file-drop-input/file-drop-input.component.d.ts +3 -0
  80. package/src/nameserver-history-viewer/components/instruction/instruction.component.d.ts +3 -0
  81. package/src/nameserver-history-viewer/components/nameserver-history.component.d.ts +33 -14
  82. package/src/nameserver-history-viewer/components/port-selector/port-selector.component.d.ts +4 -1
  83. package/src/nameserver-history-viewer/components/port-selector/port-selector.service.d.ts +3 -0
  84. package/src/nameserver-history-viewer/components/progress-bar/progress-bar.component.d.ts +3 -0
  85. package/src/nameserver-history-viewer/components/time-range-selector/time-range-selector.component.d.ts +3 -0
  86. package/src/nameserver-history-viewer/components/timezone-selector/timezone-selector.component.d.ts +3 -0
  87. package/src/nameserver-history-viewer/components/timezone-selector/timezone-selector.service.d.ts +3 -0
  88. package/src/nameserver-history-viewer/index.d.ts +1 -0
  89. package/src/nameserver-history-viewer/nameserver-history.module.d.ts +17 -0
  90. package/src/nameserver-history-viewer/services/chart.service.d.ts +4 -1
  91. package/src/nameserver-history-viewer/services/file.service.d.ts +4 -0
  92. package/src/nameserver-history-viewer/services/ui.service.d.ts +5 -2
  93. package/src/nameserver-history-viewer/utils/chartjs-downsample/lttb_data_mipmap.d.ts +1 -1
  94. package/src/nameserver-history-viewer/utils/file-util.d.ts +11 -0
  95. package/bundles/ngx-hana-nameserver-history-viewer.umd.js +0 -6735
  96. package/bundles/ngx-hana-nameserver-history-viewer.umd.js.map +0 -1
  97. package/bundles/ngx-hana-nameserver-history-viewer.umd.min.js +0 -2
  98. package/bundles/ngx-hana-nameserver-history-viewer.umd.min.js.map +0 -1
  99. package/esm2015/ngx-hana-nameserver-history-viewer.js +0 -10
  100. package/esm2015/public-api.js +0 -6
  101. package/esm2015/src/nameserver-history-viewer/components/alert/alert.component.js +0 -114
  102. package/esm2015/src/nameserver-history-viewer/components/alert/alert.module.js +0 -21
  103. package/esm2015/src/nameserver-history-viewer/components/alert/index.js +0 -7
  104. package/esm2015/src/nameserver-history-viewer/components/file-drop-input/file-drop-input.component.js +0 -141
  105. package/esm2015/src/nameserver-history-viewer/components/file-drop-input/index.js +0 -6
  106. package/esm2015/src/nameserver-history-viewer/components/index.js +0 -13
  107. package/esm2015/src/nameserver-history-viewer/components/instruction/index.js +0 -6
  108. package/esm2015/src/nameserver-history-viewer/components/instruction/instruction.component.js +0 -62
  109. package/esm2015/src/nameserver-history-viewer/components/nameserver-history.component.js +0 -868
  110. package/esm2015/src/nameserver-history-viewer/components/port-selector/index.js +0 -6
  111. package/esm2015/src/nameserver-history-viewer/components/port-selector/port-selector.component.js +0 -93
  112. package/esm2015/src/nameserver-history-viewer/components/port-selector/port-selector.service.js +0 -60
  113. package/esm2015/src/nameserver-history-viewer/components/progress-bar/index.js +0 -6
  114. package/esm2015/src/nameserver-history-viewer/components/progress-bar/progress-bar.component.js +0 -35
  115. package/esm2015/src/nameserver-history-viewer/components/time-range-selector/index.js +0 -6
  116. package/esm2015/src/nameserver-history-viewer/components/time-range-selector/time-range-selector.component.js +0 -68
  117. package/esm2015/src/nameserver-history-viewer/components/timezone-selector/index.js +0 -6
  118. package/esm2015/src/nameserver-history-viewer/components/timezone-selector/timezone-selector.component.js +0 -151
  119. package/esm2015/src/nameserver-history-viewer/components/timezone-selector/timezone-selector.service.js +0 -80
  120. package/esm2015/src/nameserver-history-viewer/index.js +0 -6
  121. package/esm2015/src/nameserver-history-viewer/nameserver-history.module.js +0 -42
  122. package/esm2015/src/nameserver-history-viewer/services/chart.service.js +0 -504
  123. package/esm2015/src/nameserver-history-viewer/services/file.service.js +0 -487
  124. package/esm2015/src/nameserver-history-viewer/services/index.js +0 -8
  125. package/esm2015/src/nameserver-history-viewer/services/ui.service.js +0 -922
  126. package/esm2015/src/nameserver-history-viewer/types/abort.types.js +0 -13
  127. package/esm2015/src/nameserver-history-viewer/types/alert.types.js +0 -13
  128. package/esm2015/src/nameserver-history-viewer/types/chart-content-data-item.types.js +0 -15
  129. package/esm2015/src/nameserver-history-viewer/types/chart-content-data.types.js +0 -9
  130. package/esm2015/src/nameserver-history-viewer/types/chart-content-header.types.js +0 -15
  131. package/esm2015/src/nameserver-history-viewer/types/chart-content-time.types.js +0 -9
  132. package/esm2015/src/nameserver-history-viewer/types/chart-content.types.js +0 -21
  133. package/esm2015/src/nameserver-history-viewer/types/color-rgba.types.js +0 -19
  134. package/esm2015/src/nameserver-history-viewer/types/html-element.type.js +0 -19
  135. package/esm2015/src/nameserver-history-viewer/types/index.js +0 -32
  136. package/esm2015/src/nameserver-history-viewer/types/item.types.js +0 -19
  137. package/esm2015/src/nameserver-history-viewer/types/legend-color.types.js +0 -9
  138. package/esm2015/src/nameserver-history-viewer/types/load-history-info-backup.types.js +0 -19
  139. package/esm2015/src/nameserver-history-viewer/types/load-history-info-columnstore.types.js +0 -19
  140. package/esm2015/src/nameserver-history-viewer/types/load-history-info-host.types.js +0 -35
  141. package/esm2015/src/nameserver-history-viewer/types/load-history-info-item.types.js +0 -31
  142. package/esm2015/src/nameserver-history-viewer/types/load-history-info-persistence.types.js +0 -27
  143. package/esm2015/src/nameserver-history-viewer/types/load-history-info-rowstore.types.js +0 -15
  144. package/esm2015/src/nameserver-history-viewer/types/load-history-info-server.types.js +0 -25
  145. package/esm2015/src/nameserver-history-viewer/types/load-history-info-session-admission-control.types.js +0 -25
  146. package/esm2015/src/nameserver-history-viewer/types/load-history-info-sql.types.js +0 -37
  147. package/esm2015/src/nameserver-history-viewer/types/load-history-info-sync-primitives.types.js +0 -15
  148. package/esm2015/src/nameserver-history-viewer/types/load-history-info-threads.types.js +0 -23
  149. package/esm2015/src/nameserver-history-viewer/types/load-history-info.types.js +0 -31
  150. package/esm2015/src/nameserver-history-viewer/types/port.types.js +0 -17
  151. package/esm2015/src/nameserver-history-viewer/types/scale-group.types.js +0 -35
  152. package/esm2015/src/nameserver-history-viewer/types/unit-category.types.js +0 -21
  153. package/esm2015/src/nameserver-history-viewer/types/unit.types.js +0 -19
  154. package/esm2015/src/nameserver-history-viewer/utils/chart-util.js +0 -38
  155. package/esm2015/src/nameserver-history-viewer/utils/chartjs-downsample/chartjs_ext.js +0 -100
  156. package/esm2015/src/nameserver-history-viewer/utils/chartjs-downsample/data_culling.js +0 -88
  157. package/esm2015/src/nameserver-history-viewer/utils/chartjs-downsample/data_mipmap.js +0 -222
  158. package/esm2015/src/nameserver-history-viewer/utils/chartjs-downsample/index.js +0 -46
  159. package/esm2015/src/nameserver-history-viewer/utils/chartjs-downsample/lttb_data_mipmap.js +0 -166
  160. package/esm2015/src/nameserver-history-viewer/utils/chartjs-downsample/responsive_downsample_plugin.js +0 -311
  161. package/esm2015/src/nameserver-history-viewer/utils/chartjs-downsample/utils.js +0 -130
  162. package/esm2015/src/nameserver-history-viewer/utils/chartjs-zoom/chart.zoom.js +0 -827
  163. package/esm2015/src/nameserver-history-viewer/utils/chartjs-zoom/index.js +0 -6
  164. package/esm2015/src/nameserver-history-viewer/utils/file-util.js +0 -162
  165. package/esm2015/src/nameserver-history-viewer/utils/index.js +0 -9
  166. package/esm2015/src/nameserver-history-viewer/utils/time-util.js +0 -139
  167. package/esm2015/src/nameserver-history-viewer/utils/ui-util.js +0 -239
  168. package/esm5/ngx-hana-nameserver-history-viewer.js +0 -10
  169. package/esm5/public-api.js +0 -6
  170. package/esm5/src/nameserver-history-viewer/components/alert/alert.component.js +0 -146
  171. package/esm5/src/nameserver-history-viewer/components/alert/alert.module.js +0 -25
  172. package/esm5/src/nameserver-history-viewer/components/alert/index.js +0 -7
  173. package/esm5/src/nameserver-history-viewer/components/file-drop-input/file-drop-input.component.js +0 -155
  174. package/esm5/src/nameserver-history-viewer/components/file-drop-input/index.js +0 -6
  175. package/esm5/src/nameserver-history-viewer/components/index.js +0 -13
  176. package/esm5/src/nameserver-history-viewer/components/instruction/index.js +0 -6
  177. package/esm5/src/nameserver-history-viewer/components/instruction/instruction.component.js +0 -67
  178. package/esm5/src/nameserver-history-viewer/components/nameserver-history.component.js +0 -1116
  179. package/esm5/src/nameserver-history-viewer/components/port-selector/index.js +0 -6
  180. package/esm5/src/nameserver-history-viewer/components/port-selector/port-selector.component.js +0 -93
  181. package/esm5/src/nameserver-history-viewer/components/port-selector/port-selector.service.js +0 -85
  182. package/esm5/src/nameserver-history-viewer/components/progress-bar/index.js +0 -6
  183. package/esm5/src/nameserver-history-viewer/components/progress-bar/progress-bar.component.js +0 -26
  184. package/esm5/src/nameserver-history-viewer/components/time-range-selector/index.js +0 -6
  185. package/esm5/src/nameserver-history-viewer/components/time-range-selector/time-range-selector.component.js +0 -58
  186. package/esm5/src/nameserver-history-viewer/components/timezone-selector/index.js +0 -6
  187. package/esm5/src/nameserver-history-viewer/components/timezone-selector/timezone-selector.component.js +0 -180
  188. package/esm5/src/nameserver-history-viewer/components/timezone-selector/timezone-selector.service.js +0 -110
  189. package/esm5/src/nameserver-history-viewer/index.js +0 -6
  190. package/esm5/src/nameserver-history-viewer/nameserver-history.module.js +0 -46
  191. package/esm5/src/nameserver-history-viewer/services/chart.service.js +0 -659
  192. package/esm5/src/nameserver-history-viewer/services/file.service.js +0 -606
  193. package/esm5/src/nameserver-history-viewer/services/index.js +0 -8
  194. package/esm5/src/nameserver-history-viewer/services/ui.service.js +0 -1141
  195. package/esm5/src/nameserver-history-viewer/types/abort.types.js +0 -13
  196. package/esm5/src/nameserver-history-viewer/types/alert.types.js +0 -13
  197. package/esm5/src/nameserver-history-viewer/types/chart-content-data-item.types.js +0 -15
  198. package/esm5/src/nameserver-history-viewer/types/chart-content-data.types.js +0 -9
  199. package/esm5/src/nameserver-history-viewer/types/chart-content-header.types.js +0 -15
  200. package/esm5/src/nameserver-history-viewer/types/chart-content-time.types.js +0 -9
  201. package/esm5/src/nameserver-history-viewer/types/chart-content.types.js +0 -21
  202. package/esm5/src/nameserver-history-viewer/types/color-rgba.types.js +0 -19
  203. package/esm5/src/nameserver-history-viewer/types/html-element.type.js +0 -19
  204. package/esm5/src/nameserver-history-viewer/types/index.js +0 -32
  205. package/esm5/src/nameserver-history-viewer/types/item.types.js +0 -19
  206. package/esm5/src/nameserver-history-viewer/types/legend-color.types.js +0 -9
  207. package/esm5/src/nameserver-history-viewer/types/load-history-info-backup.types.js +0 -19
  208. package/esm5/src/nameserver-history-viewer/types/load-history-info-columnstore.types.js +0 -19
  209. package/esm5/src/nameserver-history-viewer/types/load-history-info-host.types.js +0 -35
  210. package/esm5/src/nameserver-history-viewer/types/load-history-info-item.types.js +0 -31
  211. package/esm5/src/nameserver-history-viewer/types/load-history-info-persistence.types.js +0 -27
  212. package/esm5/src/nameserver-history-viewer/types/load-history-info-rowstore.types.js +0 -15
  213. package/esm5/src/nameserver-history-viewer/types/load-history-info-server.types.js +0 -25
  214. package/esm5/src/nameserver-history-viewer/types/load-history-info-session-admission-control.types.js +0 -25
  215. package/esm5/src/nameserver-history-viewer/types/load-history-info-sql.types.js +0 -37
  216. package/esm5/src/nameserver-history-viewer/types/load-history-info-sync-primitives.types.js +0 -15
  217. package/esm5/src/nameserver-history-viewer/types/load-history-info-threads.types.js +0 -23
  218. package/esm5/src/nameserver-history-viewer/types/load-history-info.types.js +0 -31
  219. package/esm5/src/nameserver-history-viewer/types/port.types.js +0 -17
  220. package/esm5/src/nameserver-history-viewer/types/scale-group.types.js +0 -35
  221. package/esm5/src/nameserver-history-viewer/types/unit-category.types.js +0 -21
  222. package/esm5/src/nameserver-history-viewer/types/unit.types.js +0 -19
  223. package/esm5/src/nameserver-history-viewer/utils/chart-util.js +0 -39
  224. package/esm5/src/nameserver-history-viewer/utils/chartjs-downsample/chartjs_ext.js +0 -100
  225. package/esm5/src/nameserver-history-viewer/utils/chartjs-downsample/data_culling.js +0 -88
  226. package/esm5/src/nameserver-history-viewer/utils/chartjs-downsample/data_mipmap.js +0 -316
  227. package/esm5/src/nameserver-history-viewer/utils/chartjs-downsample/index.js +0 -46
  228. package/esm5/src/nameserver-history-viewer/utils/chartjs-downsample/lttb_data_mipmap.js +0 -240
  229. package/esm5/src/nameserver-history-viewer/utils/chartjs-downsample/responsive_downsample_plugin.js +0 -366
  230. package/esm5/src/nameserver-history-viewer/utils/chartjs-downsample/utils.js +0 -142
  231. package/esm5/src/nameserver-history-viewer/utils/chartjs-zoom/chart.zoom.js +0 -827
  232. package/esm5/src/nameserver-history-viewer/utils/chartjs-zoom/index.js +0 -6
  233. package/esm5/src/nameserver-history-viewer/utils/file-util.js +0 -163
  234. package/esm5/src/nameserver-history-viewer/utils/index.js +0 -9
  235. package/esm5/src/nameserver-history-viewer/utils/time-util.js +0 -139
  236. package/esm5/src/nameserver-history-viewer/utils/ui-util.js +0 -241
  237. package/fesm2015/ngx-hana-nameserver-history-viewer.js.map +0 -1
  238. package/fesm5/ngx-hana-nameserver-history-viewer.js +0 -6861
  239. package/fesm5/ngx-hana-nameserver-history-viewer.js.map +0 -1
  240. package/ngx-hana-nameserver-history-viewer-1.1.2.tgz +0 -0
  241. package/ngx-hana-nameserver-history-viewer.metadata.json +0 -1
@@ -0,0 +1,550 @@
1
+ import { Component, ElementRef, Input, ViewChild } from '@angular/core';
2
+ import { SelectionModel } from '@angular/cdk/collections';
3
+ import { setChartHeight, sleep, isEmptyData, getDisplayPort, getFileFromInput, isSameFile, getAbbreviatedFileName, getFileFromDrop, getRealPorts, getTimeString, printProcessedTime, getTimeRangeString, generatePorts, getDefaultTimezone, blobToFile } from '../utils';
4
+ import { Abort, Alert, HtmlElement, Item } from '../types';
5
+ import { FileService, ChartService, UIService } from '../services';
6
+ import 'hammerjs';
7
+ import '../utils/chartjs-downsample';
8
+ import '../utils/chartjs-zoom';
9
+ import * as i0 from "@angular/core";
10
+ import * as i1 from "../services";
11
+ import * as i2 from "./file-drop-input/file-drop-input.component";
12
+ import * as i3 from "./progress-bar/progress-bar.component";
13
+ import * as i4 from "./time-range-selector/time-range-selector.component";
14
+ import * as i5 from "./timezone-selector/timezone-selector.component";
15
+ import * as i6 from "./port-selector/port-selector.component";
16
+ import * as i7 from "./instruction/instruction.component";
17
+ import * as i8 from "ngx-selection-table";
18
+ import * as i9 from "./alert/alert.component";
19
+ import * as i10 from "@angular/common";
20
+ var SearchType;
21
+ (function (SearchType) {
22
+ SearchType["searchWithSubHeader"] = "searchWithSubHeader";
23
+ SearchType["searchAll"] = "searchAll";
24
+ SearchType["searchInChildren"] = "searchInChildren";
25
+ })(SearchType || (SearchType = {}));
26
+ export class NameServerHistoryComponent {
27
+ constructor(fileService, chartService, uiService) {
28
+ this.fileService = fileService;
29
+ this.chartService = chartService;
30
+ this.uiService = uiService;
31
+ /**
32
+ * Input (optional) bind to [showInstruction]
33
+ */
34
+ this.showInstruction = true;
35
+ /**
36
+ * time info of the name server history file
37
+ */
38
+ this.time = {};
39
+ /**
40
+ * data of the name server history file
41
+ */
42
+ this.data = {};
43
+ /**
44
+ * header of the name server history file
45
+ */
46
+ this.header = [];
47
+ /**
48
+ * host of the name server history file
49
+ */
50
+ this.host = 'nameserver history file';
51
+ /**
52
+ * the progress for reading file
53
+ */
54
+ this.readProgress = 0;
55
+ /**
56
+ * selected/dropped file name (abbreviation), full file name will be shown via the tooltips
57
+ */
58
+ this.abbreviatedFileName = 'or Drop File Here';
59
+ /**
60
+ * for the instruction step 4
61
+ */
62
+ this.stepShowChart = false;
63
+ this.searchType = SearchType.searchAll;
64
+ }
65
+ ngOnInit() {
66
+ // this.timezone = this.defaultTimezone;
67
+ this.onResize();
68
+ // init items' status
69
+ // reset chart button will be disable by default later, only be enabled after zoomed
70
+ this._toggleItems([
71
+ { id: HtmlElement.chartArea, status: false },
72
+ { id: HtmlElement.readFileProgress, status: false },
73
+ { id: HtmlElement.showChartButton, status: false },
74
+ { id: HtmlElement.loadPortsButton, status: true },
75
+ { id: HtmlElement.resetChartButton, status: false }
76
+ ]);
77
+ }
78
+ ngOnChanges(changes) {
79
+ const fbc = changes.fileBuffer;
80
+ if (fbc && fbc.currentValue && fbc.currentValue !== fbc.previousValue) {
81
+ // simulate selecting file
82
+ const simulatedEvent = { target: { files: [blobToFile(this.fileBuffer, this.streamModeFileName)] } };
83
+ this.fileSelected(simulatedEvent);
84
+ }
85
+ }
86
+ /**
87
+ * Reset Chart to initial status
88
+ * If legend is already selected/unselected from the list, it wouldn't be restored.
89
+ */
90
+ resetChart() {
91
+ this._toggleItems([{ id: HtmlElement.resetChartButton, status: false }]);
92
+ if (this.tableSource && this._selection) {
93
+ this.chartService.resetChart(this.tableSource, this._selection)
94
+ .catch(e => this._showMessage(Alert.error, e));
95
+ }
96
+ }
97
+ /**
98
+ * read the file and display the chart
99
+ */
100
+ showChart() {
101
+ // after click, this button and reset button needs to be disabled
102
+ this._toggleItems([
103
+ { id: HtmlElement.resetChartButton, status: false },
104
+ { id: HtmlElement.showChartButton, status: false }
105
+ ]);
106
+ this.stepShowChart = true;
107
+ this._initChartEnv().then(() => {
108
+ const selectedTime = this._selectedTimeRange;
109
+ if (selectedTime.startTime > selectedTime.endTime) {
110
+ this._showMessage(Alert.error, 'Time range is not correct.');
111
+ return;
112
+ }
113
+ if (this.file) {
114
+ // it's time for displaying the reading progress bar
115
+ this._toggleItems([{ id: HtmlElement.readFileProgress, status: true }]);
116
+ return this._buildChartFromDataFile(this.file, selectedTime.startTime, selectedTime.endTime, this.port);
117
+ }
118
+ }).catch(e => {
119
+ this._showMessage(Alert.error, e);
120
+ this._toggleItems([{ id: HtmlElement.readFileProgress, status: false }]);
121
+ });
122
+ }
123
+ /**
124
+ * load all ports from file
125
+ */
126
+ loadPorts() {
127
+ // do confirmation actions
128
+ if (this.file) {
129
+ // before start loading ports from file, display progress bar and disable the show chart button
130
+ this._toggleItems([
131
+ { id: HtmlElement.readFileProgress, status: true },
132
+ { id: HtmlElement.showChartButton, status: false }
133
+ ]);
134
+ this._readPortsFromFile(this.file);
135
+ }
136
+ }
137
+ /**
138
+ * select name server history file, currently only supports 1 file.
139
+ */
140
+ fileSelected(event) {
141
+ const selectedFile = getFileFromInput(event.target);
142
+ if (selectedFile) {
143
+ if (!isSameFile(this.file, selectedFile)) {
144
+ // init port selector
145
+ this._initPortSelector().catch(e => this._showMessage(Alert.error, e));
146
+ this.file = selectedFile;
147
+ this.abbreviatedFileName = getAbbreviatedFileName(this.file.name);
148
+ // after file has been selected, the show chart button needs to be enabled
149
+ this._toggleItems([{ id: HtmlElement.showChartButton, status: true }]);
150
+ }
151
+ }
152
+ }
153
+ /**
154
+ * drop name server history file, currently only supports 1 file.
155
+ */
156
+ fileDropped(event) {
157
+ getFileFromDrop(event)
158
+ .then(file => {
159
+ if (!isSameFile(this.file, file)) {
160
+ // init port selector
161
+ this.file = file;
162
+ if (this.file) {
163
+ this.abbreviatedFileName = getAbbreviatedFileName(this.file.name);
164
+ // after file has been dropped, the show chart button needs to be enabled
165
+ this._toggleItems([{ id: HtmlElement.showChartButton, status: true }]);
166
+ }
167
+ }
168
+ })
169
+ .then(() => {
170
+ return this._initPortSelector();
171
+ })
172
+ .catch(e => this._showMessage(Alert.error, e));
173
+ }
174
+ /**
175
+ * Select one item from selection table, relative dataset will be shown or hidden
176
+ */
177
+ selectItem(event) {
178
+ if (event && event.tableRow) {
179
+ const row = event.tableRow;
180
+ this._selection.toggle(row);
181
+ this.chartService.toggleDataInChart(row.KPI, !this._selection.isSelected(row))
182
+ .catch(e => this._showMessage(Alert.error, e));
183
+ }
184
+ }
185
+ /**
186
+ * recalculating chart height when resizing
187
+ */
188
+ onResize() {
189
+ const nameserverHistoryAllElement = this.nameserverHistoryAllRef ? this.nameserverHistoryAllRef.nativeElement : null;
190
+ const nameserverHistoryContentElement = this.nameserverHistoryContentRef ? this.nameserverHistoryContentRef.nativeElement : null;
191
+ setChartHeight(nameserverHistoryAllElement, nameserverHistoryContentElement);
192
+ }
193
+ /**
194
+ * Switch port and reinitialize chart, triggered by changing the port
195
+ * @param port the selected port
196
+ */
197
+ switchPortForChart(port) {
198
+ if (port === this._currentChartPort) {
199
+ // not to switch port, because the relative port is displaying, no need to render twice.
200
+ return;
201
+ }
202
+ if (!this.file || !port || port.length === 0 || port.slice(1, 3) === '**') {
203
+ return;
204
+ }
205
+ else if (Object.keys(this.time).length > 1 && !getRealPorts(Object.keys(this.time).filter(key => this.time[key])).includes(port)) {
206
+ this._showMessage(Alert.info, `Data of port:${port} is not loaded, please load the data first by clicking the "Show" button.`);
207
+ return;
208
+ }
209
+ // only do switch ports when available ports number > 1
210
+ if (Object.keys(this.time).filter(key => this.time[key]).length > 1) {
211
+ // disable the "show chart" and "reset chart" button first
212
+ this._toggleItems([
213
+ { id: HtmlElement.showChartButton, status: false },
214
+ { id: HtmlElement.resetChartButton, status: false }
215
+ ]);
216
+ // init the environment with switch flag
217
+ this._initChartEnv(true).then(() => {
218
+ return this._buildChart(port, null, true);
219
+ }).catch(e => this._showMessage(Alert.error, e));
220
+ }
221
+ }
222
+ /**
223
+ * get the columns which need to be hidden from the selection table
224
+ */
225
+ get hiddenColumns() {
226
+ return this.uiService.getHiddenColumns(this.hideMeasureColumns);
227
+ }
228
+ /**
229
+ * get default timezone
230
+ */
231
+ get defaultTimezone() {
232
+ return getDefaultTimezone();
233
+ }
234
+ /**
235
+ * get the key column (KPI)
236
+ */
237
+ get kpiColumn() {
238
+ return Item.kpi;
239
+ }
240
+ /**
241
+ * get the key column (KPI)
242
+ */
243
+ get descColumn() {
244
+ return Item.description;
245
+ }
246
+ /**
247
+ * get the selected time range, set second and millisecond part to 0
248
+ */
249
+ get _selectedTimeRange() {
250
+ let startTime = 0;
251
+ let endTime = 4102358400000; // 2099/12/31
252
+ if (this.dateTimeRange != null) {
253
+ if (this.dateTimeRange.length >= 1) {
254
+ // get start time
255
+ if (this.dateTimeRange[0]) {
256
+ startTime = this.dateTimeRange[0].setSeconds(0, 0);
257
+ }
258
+ if (this.dateTimeRange[1]) {
259
+ endTime = this.dateTimeRange[1].setSeconds(0, 0);
260
+ }
261
+ }
262
+ }
263
+ return { startTime: startTime, endTime: endTime };
264
+ }
265
+ /**
266
+ * get the time range string, eg: 2018-10-25 10:25 ~ 2018-10-26 10:26
267
+ */
268
+ get _selectedTimeRangeString() {
269
+ const selectedTimeRangeString = this._selectedTimeRange;
270
+ return `${getTimeString(selectedTimeRangeString.startTime)} ~ ${getTimeString(selectedTimeRangeString.endTime)}`;
271
+ }
272
+ /**
273
+ * get array of header key
274
+ */
275
+ get _headerKey() {
276
+ if (this.header) {
277
+ return this.header.map(headerItem => headerItem.key);
278
+ }
279
+ }
280
+ /**
281
+ * get array of header text
282
+ */
283
+ get _headerText() {
284
+ return this.header.map(headerItem => headerItem.text);
285
+ }
286
+ /**
287
+ * read ports from the selected nameserver history file
288
+ * @param file nameserver history file
289
+ */
290
+ _readPortsFromFile(file) {
291
+ this.fileService.getPortsFromFile(file, (progress) => {
292
+ this.readProgress = progress;
293
+ }).then(ports => {
294
+ return sleep(100).then(() => {
295
+ return this._initPortSelector(ports);
296
+ });
297
+ }).catch(e => this._showMessage(Alert.error, e));
298
+ }
299
+ /**
300
+ * build chart from the selected nameserver history file
301
+ * @param file the nameserver history file
302
+ * @param startTime start time
303
+ * @param endTime end time
304
+ * @param selectedPort selected port for nameserver history file (MDC system)
305
+ */
306
+ _buildChartFromDataFile(file, startTime, endTime, selectedPort) {
307
+ return this.fileService.getChartContentFromFile(file, startTime, endTime, selectedPort, this.timezone, this.maxRowsLimitation, progress => this.readProgress = progress)
308
+ .then(result => {
309
+ // parsing done
310
+ const beginTime = new Date();
311
+ const promises = [];
312
+ const ports = getRealPorts(Object.keys(result.time), true);
313
+ ports.forEach(port => {
314
+ // convert the unit and generate controlling data for all ports
315
+ promises.push(this.uiService.convertUnitAndGenerateControlData(result.data[port], result.header, port));
316
+ });
317
+ return Promise.all(promises)
318
+ .then(() => {
319
+ // get all ports from the analyzed data(time)
320
+ // get the port that will be shown in the page
321
+ const port = getDisplayPort(ports, selectedPort);
322
+ printProcessedTime(beginTime, 'converting step');
323
+ ports.forEach(portItem => this.uiService.generateYScale(portItem));
324
+ printProcessedTime(beginTime, 'generating YScale step');
325
+ this.data = result.data;
326
+ this.time = result.time;
327
+ this.header = this.uiService.getHeader(result.header, port);
328
+ this.host = result.host;
329
+ if (result.aborted === Abort.maxLineNumReached) {
330
+ this._showMessage(Alert.warning, `Maximum number of lines reached. Processed time range is: ${getTimeRangeString(this.time)}.`);
331
+ }
332
+ else {
333
+ if (isEmptyData(this.data)) {
334
+ this._showMessage(Alert.info, `Cannot find any data for the selected time period: ${this._selectedTimeRangeString}`);
335
+ }
336
+ else {
337
+ this._showMessage(Alert.success, `Processed time range is: ${getTimeRangeString(this.time)}.`);
338
+ }
339
+ }
340
+ return sleep(100).then(() => {
341
+ return this._buildChart(port, ports);
342
+ });
343
+ });
344
+ });
345
+ }
346
+ /**
347
+ * reinitialize the port selector with the ports
348
+ */
349
+ _initPortSelector(ports = null, selectedPort = null) {
350
+ return new Promise(resolve => {
351
+ // initialization for ngx-select
352
+ if (ports != null && ports.length > 1) {
353
+ // MDC, remove default '0000' port
354
+ this.ports = generatePorts(getRealPorts(ports), selectedPort);
355
+ }
356
+ else {
357
+ this.ports = generatePorts(ports);
358
+ }
359
+ if (ports != null && selectedPort === null) {
360
+ // reset status when doing:
361
+ // 1. loading ports
362
+ // 2. the file doesn't contain the selected Port
363
+ this.readProgress = 0;
364
+ // hide the progress bar and enable the "show chart" button
365
+ this._toggleItems([
366
+ { id: HtmlElement.readFileProgress, status: false },
367
+ { id: HtmlElement.showChartButton, status: true }
368
+ ]);
369
+ }
370
+ resolve();
371
+ });
372
+ }
373
+ /**
374
+ * build and display the chart on page
375
+ * @param port the selected port
376
+ * @param ports all available ports
377
+ * @param switchFlag indicates whether this function is triggered from switching ports (no init port selector needed)
378
+ */
379
+ _buildChart(port, ports, switchFlag = false) {
380
+ const beginTime = new Date();
381
+ if (port) {
382
+ return Promise.resolve(this._loadSettingsForSelectionsTable(port))
383
+ .then(() => {
384
+ // get the config
385
+ return this.chartService.buildChart(this.time[port], this.data[port], this.uiService.getYScale(this._headerKey, port), this._headerText, this._headerKey, this._selection, this.tableSource, this._getHostTitle(port), this.uiService.getDisplayItems(this._headerKey, port, this.defaultSelectedItems), this._onZoom.bind(this))
386
+ .then(() => {
387
+ this.readProgress = 0;
388
+ // after chart has been created, show the chart area, hide progress bar and enable the "show chart" button
389
+ this._toggleItems([
390
+ { id: HtmlElement.chartArea, status: true },
391
+ { id: HtmlElement.readFileProgress, status: false },
392
+ { id: HtmlElement.showChartButton, status: true }
393
+ ]);
394
+ // set port to current displaying port
395
+ this._currentChartPort = port;
396
+ printProcessedTime(beginTime, 'step_build_chart');
397
+ if (ports && ports.length > 0) {
398
+ if (!switchFlag) {
399
+ // initialize port selector. Do not need to do it when switching port.
400
+ return this._initPortSelector(ports, port);
401
+ }
402
+ }
403
+ });
404
+ });
405
+ }
406
+ else {
407
+ if (ports.length > 0) {
408
+ this._showMessage(Alert.warning, 'The selected port does not exist in the name server history file. Please choose a correct port and have a try again.');
409
+ if (!switchFlag) {
410
+ // initialize port selector. Do not need to do it when switching port.
411
+ return this._initPortSelector(ports, port);
412
+ }
413
+ }
414
+ }
415
+ }
416
+ /**
417
+ * get the string that will be displayed on the title area of the chart
418
+ * eg: host1 - 30040 (2018-09-05 15:32:32 ~ 2018-09-07 15:32:15)
419
+ * @param port selected port
420
+ */
421
+ _getHostTitle(port) {
422
+ if (this.host) {
423
+ return `${this.host} - ${port} ( ${getTimeRangeString(this.time[port])} )`;
424
+ }
425
+ }
426
+ /**
427
+ * after zoom, enable the reset button.
428
+ */
429
+ _onZoom() {
430
+ this._toggleItems([{ id: HtmlElement.resetChartButton, status: true }]);
431
+ }
432
+ /**
433
+ * initialize chart, including: destroy current chart, initialize config, initialize all relative data
434
+ */
435
+ _initChartEnv(switchFlag = false) {
436
+ return this.chartService.destroyChart().then(() => {
437
+ {
438
+ // cleanup other data
439
+ this._toggleItems([{ id: HtmlElement.chartArea, status: false }]);
440
+ if (!switchFlag) {
441
+ Object.keys(this.time).forEach(key => {
442
+ if (this.time[key]) {
443
+ this.time[key].length = 0;
444
+ }
445
+ });
446
+ this.time = {};
447
+ Object.keys(this.data).forEach(key => {
448
+ if (this.data[key]) {
449
+ this.data[key].length = 0;
450
+ }
451
+ });
452
+ this.data = {};
453
+ this.header.length = 0;
454
+ this.host = 'nameserver history file';
455
+ this.tableSource = void 0;
456
+ this.readProgress = 0;
457
+ this.uiService.clearLoadHistoryInfos();
458
+ }
459
+ }
460
+ });
461
+ }
462
+ /**
463
+ * Load settings for the selection table (the right part of the chart)
464
+ * @param port the selected port
465
+ */
466
+ _loadSettingsForSelectionsTable(port) {
467
+ this.tableSource = this.uiService.getSelectionTableRows(this._headerKey, port, this.defaultSelectedItems);
468
+ this._selection = new SelectionModel(true, []);
469
+ this.tableSource.forEach(row => {
470
+ if (this.uiService.getDisplayItems(this._headerKey, port, this.defaultSelectedItems).includes(row.KPI)) {
471
+ this._selection.select(row);
472
+ }
473
+ });
474
+ }
475
+ /**
476
+ * Show messages
477
+ * @param type type of the message
478
+ * @param message message text
479
+ */
480
+ _showMessage(type, message) {
481
+ if (type) {
482
+ switch (type) {
483
+ case Alert.success:
484
+ case Alert.info:
485
+ break;
486
+ case Alert.warning:
487
+ console.warn(message);
488
+ break;
489
+ case Alert.error:
490
+ console.error(message);
491
+ }
492
+ }
493
+ if (this.alertMessage === message) {
494
+ // try trigger the change event of the alert.
495
+ this.alertMessage = void 0;
496
+ setTimeout(() => this.alertMessage = message, 100);
497
+ }
498
+ else {
499
+ this.alertMessage = message;
500
+ }
501
+ this.alertType = type;
502
+ }
503
+ /**
504
+ * toggle items with the provided status (show or hide the relative element on the page)
505
+ * @param items items with the relative id and status.
506
+ */
507
+ _toggleItems(items) {
508
+ const getVariableNameByTypeId = (id) => {
509
+ switch (id) {
510
+ case HtmlElement.chartArea: return 'showChartFlag';
511
+ case HtmlElement.readFileProgress: return 'showReadFileProgress';
512
+ case HtmlElement.showChartButton: return 'enableShowChartButton';
513
+ case HtmlElement.loadPortsButton: return 'enableLoadPortsButton';
514
+ case HtmlElement.resetChartButton: return 'enableResetChartButton';
515
+ }
516
+ };
517
+ if (items) {
518
+ items.forEach(item => {
519
+ this[getVariableNameByTypeId(item.id)] = item.status;
520
+ });
521
+ }
522
+ }
523
+ }
524
+ NameServerHistoryComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.3.11", ngImport: i0, type: NameServerHistoryComponent, deps: [{ token: i1.FileService }, { token: i1.ChartService }, { token: i1.UIService }], target: i0.ɵɵFactoryTarget.Component });
525
+ NameServerHistoryComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.3.11", type: NameServerHistoryComponent, selector: "ngx-hana-nameserver-history-viewer", inputs: { defaultSelectedItems: "defaultSelectedItems", hideMeasureColumns: "hideMeasureColumns", maxRowsLimitation: "maxRowsLimitation", showInstruction: "showInstruction", timezone: "timezone", fileBuffer: "fileBuffer", streamModeFileName: "streamModeFileName" }, providers: [FileService, ChartService, UIService], viewQueries: [{ propertyName: "nameserverHistoryAllRef", first: true, predicate: ["nameserverHistoryAll"], descendants: true, read: ElementRef }, { propertyName: "nameserverHistoryContentRef", first: true, predicate: ["nameserverHistoryContent"], descendants: true, read: ElementRef }], usesOnChanges: true, ngImport: i0, template: "<div #nameserverHistoryAll class=\"nameserver-history-all\" (window:resize)=\"onResize()\">\r\n <div class=\"toolbar-chart\">\r\n <div class=\"upload-box-content\">\r\n <div *ngIf=\"!showReadFileProgress\">\r\n <file-drop-input (fileDrop)=\"fileDropped($event)\" (fileInput)=\"fileSelected($event)\"\r\n [dropAreaText]= \"abbreviatedFileName\"\r\n [inputAreaText]=\"'Browse'\"\r\n [title]=\"file?.name? file.name:'Select a name server history file from your local disk.'\"\r\n *ngIf=\"!fileBuffer\">\r\n </file-drop-input>\r\n <p *ngIf=\"fileBuffer\">{{streamModeFileName || 'nameserver_history.trc (stream mode)'}}</p>\r\n </div>\r\n <div *ngIf=\"showReadFileProgress\">\r\n <progress-bar [progress]=\"readProgress\"></progress-bar>\r\n </div>\r\n </div>\r\n <div class=\"input-time\">\r\n <div class=\"input-time-range\">\r\n <time-range-selector [disabled]=\"showReadFileProgress\" [(dateTimeRange)]=\"dateTimeRange\"></time-range-selector>\r\n </div>\r\n <div class=\"timezone-selector\">\r\n <timezone-selector [(timezone)]=\"timezone\" [disabled]=\"showReadFileProgress\"></timezone-selector>\r\n </div>\r\n </div>\r\n\r\n <div class=\"port-selection\">\r\n <div class=\"port-selector\">\r\n <port-selector (portChange)=\"switchPortForChart($event)\" [(port)]=\"port\" [ports]=\"ports\" [disabled]=\"showReadFileProgress\"></port-selector>\r\n </div>\r\n <div class=\"port-load-button\">\r\n <button (click)=\"loadPorts()\" title=\"Load all ports from name server history trace file.\" [disabled]=\"!enableShowChartButton || port || !enableLoadPortsButton\">{{showReadFileProgress? \"Loading...\" : \"Load\"}}</button>\r\n </div>\r\n </div>\r\n\r\n <div class=\"chart-operation\">\r\n <div class=\"left\">\r\n <button (click)=\"showChart()\" title=\"Load and display all data from name server history trace file.\" [disabled]=\"!enableShowChartButton\">{{showReadFileProgress? \"Loading...\" : \"Show\"}}</button>\r\n </div>\r\n <div class=\"right\">\r\n <button (click)=\"resetChart()\" title=\"Reset zoom of chart.\" [disabled]=\"showReadFileProgress || !enableResetChartButton\">Reset Chart</button>\r\n </div>\r\n </div>\r\n </div>\r\n <div #nameserverHistoryContent class=\"nameserver-history-content\">\r\n <div class=\"nameserver-history-content-chart\">\r\n <instruction [(show)]=\"showInstruction\" *ngIf=\"!showChartFlag && showInstruction\"\r\n [step1Finished]=\"!!file\"\r\n [step2Finished]=\"dateTimeRange && (!!dateTimeRange[0] || !!dateTimeRange[1]) || timezone != defaultTimezone\"\r\n [step3Finished]=\"!!port\"\r\n [step4Finished]=\"stepShowChart && !enableShowChartButton\"\r\n [step5Finished]=\"false\">\r\n </instruction>\r\n <canvas id=\"chartNameServerHistory\" ></canvas>\r\n </div>\r\n <div class=\"nameserver-history-content-controller\" >\r\n <ngx-selection-table (change)=\"selectItem($event)\" *ngIf=\"showChartFlag\"\r\n [filter]=\"true\"\r\n [checkbox]=\"true\"\r\n [tableSource]=\"tableSource\"\r\n [keyColumn]=\"kpiColumn\"\r\n [hiddenColumns]=\"hiddenColumns\"\r\n [tooltipColumn]=\"descColumn\"\r\n [searchStyle]=\"searchType\"\r\n [searchColumn]=\"kpiColumn\"\r\n [multiSelection]=\"true\">\r\n </ngx-selection-table>\r\n </div>\r\n </div>\r\n</div>\r\n<div class=\"message-container\" *ngIf=\"alertMessage\">\r\n <alert [(alertMessage)]=\"alertMessage\" [alertType]=\"alertType\" [alertTimeout]=\"30000\"></alert>\r\n</div>\r\n", styles: [":host *,:host *:before,:host *:after{box-sizing:inherit;display:inherit;font-size:inherit;font-weight:inherit;font-family:inherit}:host .hover-box,:host .nameserver-history-all .toolbar-chart .port-selection .port-load-button button:hover{outline:0;box-shadow:0 0 6px #23adff}:host .dashed-box,:host .nameserver-history-all .toolbar-chart .chart-operation button,:host .nameserver-history-all .toolbar-chart .port-selection,:host .nameserver-history-all .toolbar-chart .input-time,:host .nameserver-history-all .toolbar-chart .upload-box-content{background:#f8f8f8;box-shadow:inset 0 20px 20px -20px #0009;border:1px dashed #0782d0}:host .solid-box,:host .nameserver-history-all .toolbar-chart .port-selection .port-load-button button{background:#fff none;border:1px solid #ccc;border-radius:4px;line-height:1.42857143}:host .nameserver-history-all{width:98%;min-width:1314px;height:auto;border:1px none #0782d0;border-bottom-style:dashed;margin:3px 1%;box-sizing:border-box;display:inline-block;font-size:14px;font-weight:400;font-family:Helvetica,Arial,sans-serif}:host .nameserver-history-all .toolbar-chart{width:100%;height:48px}:host .nameserver-history-all .toolbar-chart button{text-align:center;white-space:nowrap;vertical-align:middle}:host .nameserver-history-all .toolbar-chart button:hover{text-shadow:1px 1px 3px royalblue;cursor:pointer;font-weight:600}:host .nameserver-history-all .toolbar-chart button:disabled{text-shadow:none;opacity:.65;cursor:default;color:#a9a9a9;font-weight:400}:host .nameserver-history-all .toolbar-chart .upload-box-content{width:20%;height:100%;float:left;text-align:center;color:#00008b}:host .nameserver-history-all .toolbar-chart .input-time{margin-left:1%;margin-right:1%;width:43%;height:100%}:host .nameserver-history-all .toolbar-chart .input-time .input-time-range{height:100%;width:57%;float:left}:host .nameserver-history-all .toolbar-chart .input-time .timezone-selector{margin-top:6px;height:100%;width:42.5%;margin-right:.5%;float:right}:host .nameserver-history-all .toolbar-chart .port-selection{width:14%;margin-right:1%;height:48px}:host .nameserver-history-all .toolbar-chart .port-selection .port-selector{margin-top:6px;margin-left:2%;margin-right:1%;width:47%;float:left}:host .nameserver-history-all .toolbar-chart .port-selection .port-load-button{margin-top:6px;margin-left:1%;margin-right:2%;width:47%;float:right}:host .nameserver-history-all .toolbar-chart .port-selection .port-load-button button{color:#333;width:100%;padding:6px 12px;margin-bottom:0}:host .nameserver-history-all .toolbar-chart .port-selection .port-load-button button:hover{text-shadow:None;font-weight:400}:host .nameserver-history-all .toolbar-chart .port-selection .port-load-button button:disabled{box-shadow:none}:host .nameserver-history-all .toolbar-chart .chart-operation{width:20%;height:48px;float:right}:host .nameserver-history-all .toolbar-chart .chart-operation .left{margin-right:1%;width:49%;height:100%;float:left}:host .nameserver-history-all .toolbar-chart .chart-operation .right{width:50%;height:100%;float:right}:host .nameserver-history-all .toolbar-chart .chart-operation button{width:100%;height:100%;color:#00008b}:host .nameserver-history-all .nameserver-history-content{width:100%;height:730px;margin:5px 5px 5px 0}:host .nameserver-history-all .nameserver-history-content .nameserver-history-content-chart{width:75%;height:100%;position:relative;float:left}:host .nameserver-history-all .nameserver-history-content .nameserver-history-content-controller{width:25%;height:100%;float:right;overflow:auto}:host .message-container{width:98%;margin:0 1%;box-sizing:border-box;display:inline-block}\n"], components: [{ type: i2.FileDropInputComponent, selector: "file-drop-input", inputs: ["dropAreaText", "inputAreaText"], outputs: ["fileDrop", "fileInput"] }, { type: i3.ProgressBarComponent, selector: "progress-bar", inputs: ["progress"] }, { type: i4.TimeRangeSelectorComponent, selector: "time-range-selector", inputs: ["disabled", "dateTimeRange"], outputs: ["dateTimeRangeChange"] }, { type: i5.TimezoneSelectorComponent, selector: "timezone-selector", inputs: ["disabled", "timezone"], outputs: ["timezoneChange"] }, { type: i6.PortSelectorComponent, selector: "port-selector", inputs: ["disabled", "port", "ports"], outputs: ["portChange"] }, { type: i7.InstructionComponent, selector: "instruction", inputs: ["step1Finished", "step2Finished", "step3Finished", "step4Finished", "step5Finished", "show"], outputs: ["showChange"] }, { type: i8.SelectionTableComponent, selector: "ngx-selection-table", inputs: ["filter", "keyColumn", "tableSource", "checkbox", "multiSelection", "clickToSelect", "hiddenColumns", "tooltipColumn", "searchStyle", "searchColumn"], outputs: ["change"] }, { type: i9.AlertComponent, selector: "alert", inputs: ["alertMessage", "alertType", "alertTimeout"], outputs: ["alertMessageChange"] }], directives: [{ type: i10.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }] });
526
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.11", ngImport: i0, type: NameServerHistoryComponent, decorators: [{
527
+ type: Component,
528
+ args: [{ selector: 'ngx-hana-nameserver-history-viewer', providers: [FileService, ChartService, UIService], template: "<div #nameserverHistoryAll class=\"nameserver-history-all\" (window:resize)=\"onResize()\">\r\n <div class=\"toolbar-chart\">\r\n <div class=\"upload-box-content\">\r\n <div *ngIf=\"!showReadFileProgress\">\r\n <file-drop-input (fileDrop)=\"fileDropped($event)\" (fileInput)=\"fileSelected($event)\"\r\n [dropAreaText]= \"abbreviatedFileName\"\r\n [inputAreaText]=\"'Browse'\"\r\n [title]=\"file?.name? file.name:'Select a name server history file from your local disk.'\"\r\n *ngIf=\"!fileBuffer\">\r\n </file-drop-input>\r\n <p *ngIf=\"fileBuffer\">{{streamModeFileName || 'nameserver_history.trc (stream mode)'}}</p>\r\n </div>\r\n <div *ngIf=\"showReadFileProgress\">\r\n <progress-bar [progress]=\"readProgress\"></progress-bar>\r\n </div>\r\n </div>\r\n <div class=\"input-time\">\r\n <div class=\"input-time-range\">\r\n <time-range-selector [disabled]=\"showReadFileProgress\" [(dateTimeRange)]=\"dateTimeRange\"></time-range-selector>\r\n </div>\r\n <div class=\"timezone-selector\">\r\n <timezone-selector [(timezone)]=\"timezone\" [disabled]=\"showReadFileProgress\"></timezone-selector>\r\n </div>\r\n </div>\r\n\r\n <div class=\"port-selection\">\r\n <div class=\"port-selector\">\r\n <port-selector (portChange)=\"switchPortForChart($event)\" [(port)]=\"port\" [ports]=\"ports\" [disabled]=\"showReadFileProgress\"></port-selector>\r\n </div>\r\n <div class=\"port-load-button\">\r\n <button (click)=\"loadPorts()\" title=\"Load all ports from name server history trace file.\" [disabled]=\"!enableShowChartButton || port || !enableLoadPortsButton\">{{showReadFileProgress? \"Loading...\" : \"Load\"}}</button>\r\n </div>\r\n </div>\r\n\r\n <div class=\"chart-operation\">\r\n <div class=\"left\">\r\n <button (click)=\"showChart()\" title=\"Load and display all data from name server history trace file.\" [disabled]=\"!enableShowChartButton\">{{showReadFileProgress? \"Loading...\" : \"Show\"}}</button>\r\n </div>\r\n <div class=\"right\">\r\n <button (click)=\"resetChart()\" title=\"Reset zoom of chart.\" [disabled]=\"showReadFileProgress || !enableResetChartButton\">Reset Chart</button>\r\n </div>\r\n </div>\r\n </div>\r\n <div #nameserverHistoryContent class=\"nameserver-history-content\">\r\n <div class=\"nameserver-history-content-chart\">\r\n <instruction [(show)]=\"showInstruction\" *ngIf=\"!showChartFlag && showInstruction\"\r\n [step1Finished]=\"!!file\"\r\n [step2Finished]=\"dateTimeRange && (!!dateTimeRange[0] || !!dateTimeRange[1]) || timezone != defaultTimezone\"\r\n [step3Finished]=\"!!port\"\r\n [step4Finished]=\"stepShowChart && !enableShowChartButton\"\r\n [step5Finished]=\"false\">\r\n </instruction>\r\n <canvas id=\"chartNameServerHistory\" ></canvas>\r\n </div>\r\n <div class=\"nameserver-history-content-controller\" >\r\n <ngx-selection-table (change)=\"selectItem($event)\" *ngIf=\"showChartFlag\"\r\n [filter]=\"true\"\r\n [checkbox]=\"true\"\r\n [tableSource]=\"tableSource\"\r\n [keyColumn]=\"kpiColumn\"\r\n [hiddenColumns]=\"hiddenColumns\"\r\n [tooltipColumn]=\"descColumn\"\r\n [searchStyle]=\"searchType\"\r\n [searchColumn]=\"kpiColumn\"\r\n [multiSelection]=\"true\">\r\n </ngx-selection-table>\r\n </div>\r\n </div>\r\n</div>\r\n<div class=\"message-container\" *ngIf=\"alertMessage\">\r\n <alert [(alertMessage)]=\"alertMessage\" [alertType]=\"alertType\" [alertTimeout]=\"30000\"></alert>\r\n</div>\r\n", styles: [":host *,:host *:before,:host *:after{box-sizing:inherit;display:inherit;font-size:inherit;font-weight:inherit;font-family:inherit}:host .hover-box,:host .nameserver-history-all .toolbar-chart .port-selection .port-load-button button:hover{outline:0;box-shadow:0 0 6px #23adff}:host .dashed-box,:host .nameserver-history-all .toolbar-chart .chart-operation button,:host .nameserver-history-all .toolbar-chart .port-selection,:host .nameserver-history-all .toolbar-chart .input-time,:host .nameserver-history-all .toolbar-chart .upload-box-content{background:#f8f8f8;box-shadow:inset 0 20px 20px -20px #0009;border:1px dashed #0782d0}:host .solid-box,:host .nameserver-history-all .toolbar-chart .port-selection .port-load-button button{background:#fff none;border:1px solid #ccc;border-radius:4px;line-height:1.42857143}:host .nameserver-history-all{width:98%;min-width:1314px;height:auto;border:1px none #0782d0;border-bottom-style:dashed;margin:3px 1%;box-sizing:border-box;display:inline-block;font-size:14px;font-weight:400;font-family:Helvetica,Arial,sans-serif}:host .nameserver-history-all .toolbar-chart{width:100%;height:48px}:host .nameserver-history-all .toolbar-chart button{text-align:center;white-space:nowrap;vertical-align:middle}:host .nameserver-history-all .toolbar-chart button:hover{text-shadow:1px 1px 3px royalblue;cursor:pointer;font-weight:600}:host .nameserver-history-all .toolbar-chart button:disabled{text-shadow:none;opacity:.65;cursor:default;color:#a9a9a9;font-weight:400}:host .nameserver-history-all .toolbar-chart .upload-box-content{width:20%;height:100%;float:left;text-align:center;color:#00008b}:host .nameserver-history-all .toolbar-chart .input-time{margin-left:1%;margin-right:1%;width:43%;height:100%}:host .nameserver-history-all .toolbar-chart .input-time .input-time-range{height:100%;width:57%;float:left}:host .nameserver-history-all .toolbar-chart .input-time .timezone-selector{margin-top:6px;height:100%;width:42.5%;margin-right:.5%;float:right}:host .nameserver-history-all .toolbar-chart .port-selection{width:14%;margin-right:1%;height:48px}:host .nameserver-history-all .toolbar-chart .port-selection .port-selector{margin-top:6px;margin-left:2%;margin-right:1%;width:47%;float:left}:host .nameserver-history-all .toolbar-chart .port-selection .port-load-button{margin-top:6px;margin-left:1%;margin-right:2%;width:47%;float:right}:host .nameserver-history-all .toolbar-chart .port-selection .port-load-button button{color:#333;width:100%;padding:6px 12px;margin-bottom:0}:host .nameserver-history-all .toolbar-chart .port-selection .port-load-button button:hover{text-shadow:None;font-weight:400}:host .nameserver-history-all .toolbar-chart .port-selection .port-load-button button:disabled{box-shadow:none}:host .nameserver-history-all .toolbar-chart .chart-operation{width:20%;height:48px;float:right}:host .nameserver-history-all .toolbar-chart .chart-operation .left{margin-right:1%;width:49%;height:100%;float:left}:host .nameserver-history-all .toolbar-chart .chart-operation .right{width:50%;height:100%;float:right}:host .nameserver-history-all .toolbar-chart .chart-operation button{width:100%;height:100%;color:#00008b}:host .nameserver-history-all .nameserver-history-content{width:100%;height:730px;margin:5px 5px 5px 0}:host .nameserver-history-all .nameserver-history-content .nameserver-history-content-chart{width:75%;height:100%;position:relative;float:left}:host .nameserver-history-all .nameserver-history-content .nameserver-history-content-controller{width:25%;height:100%;float:right;overflow:auto}:host .message-container{width:98%;margin:0 1%;box-sizing:border-box;display:inline-block}\n"] }]
529
+ }], ctorParameters: function () { return [{ type: i1.FileService }, { type: i1.ChartService }, { type: i1.UIService }]; }, propDecorators: { nameserverHistoryAllRef: [{
530
+ type: ViewChild,
531
+ args: ['nameserverHistoryAll', { read: ElementRef }]
532
+ }], nameserverHistoryContentRef: [{
533
+ type: ViewChild,
534
+ args: ['nameserverHistoryContent', { read: ElementRef }]
535
+ }], defaultSelectedItems: [{
536
+ type: Input
537
+ }], hideMeasureColumns: [{
538
+ type: Input
539
+ }], maxRowsLimitation: [{
540
+ type: Input
541
+ }], showInstruction: [{
542
+ type: Input
543
+ }], timezone: [{
544
+ type: Input
545
+ }], fileBuffer: [{
546
+ type: Input
547
+ }], streamModeFileName: [{
548
+ type: Input
549
+ }] } });
550
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibmFtZXNlcnZlci1oaXN0b3J5LmNvbXBvbmVudC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uL3NyYy9uYW1lc2VydmVyLWhpc3Rvcnktdmlld2VyL2NvbXBvbmVudHMvbmFtZXNlcnZlci1oaXN0b3J5LmNvbXBvbmVudC50cyIsIi4uLy4uLy4uLy4uLy4uL3NyYy9uYW1lc2VydmVyLWhpc3Rvcnktdmlld2VyL2NvbXBvbmVudHMvbmFtZXNlcnZlci1oaXN0b3J5LmNvbXBvbmVudC5odG1sIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBQyxTQUFTLEVBQUUsVUFBVSxFQUFFLEtBQUssRUFBb0MsU0FBUyxFQUFDLE1BQU0sZUFBZSxDQUFDO0FBQ3hHLE9BQU8sRUFBRSxjQUFjLEVBQUUsTUFBTSwwQkFBMEIsQ0FBQztBQUMxRCxPQUFPLEVBQ0wsY0FBYyxFQUNkLEtBQUssRUFDTCxXQUFXLEVBQ1gsY0FBYyxFQUNkLGdCQUFnQixFQUNoQixVQUFVLEVBQ1Ysc0JBQXNCLEVBQ3RCLGVBQWUsRUFDZixZQUFZLEVBQ1osYUFBYSxFQUNiLGtCQUFrQixFQUNsQixrQkFBa0IsRUFDbEIsYUFBYSxFQUNiLGtCQUFrQixFQUNsQixVQUFVLEVBQ1gsTUFBTSxVQUFVLENBQUM7QUFDbEIsT0FBTyxFQUFFLEtBQUssRUFBRSxLQUFLLEVBQUUsV0FBVyxFQUFFLElBQUksRUFBZ0UsTUFBTSxVQUFVLENBQUM7QUFDekgsT0FBTyxFQUFFLFdBQVcsRUFBRSxZQUFZLEVBQUUsU0FBUyxFQUFFLE1BQU0sYUFBYSxDQUFDO0FBRW5FLE9BQU8sVUFBVSxDQUFDO0FBQ2xCLE9BQU8sNkJBQTZCLENBQUM7QUFDckMsT0FBTyx1QkFBdUIsQ0FBQzs7Ozs7Ozs7Ozs7O0FBRS9CLElBQUssVUFJSjtBQUpELFdBQUssVUFBVTtJQUNiLHlEQUEyQyxDQUFBO0lBQzNDLHFDQUF1QixDQUFBO0lBQ3ZCLG1EQUFxQyxDQUFBO0FBQ3ZDLENB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dCB7Q29tcG9uZW50LCBFbGVtZW50UmVmLCBJbnB1dCwgT25DaGFuZ2VzLCBPbkluaXQsIFNpbXBsZUNoYW5nZXMsIFZpZXdDaGlsZH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XHJcbmltcG9ydCB7IFNlbGVjdGlvbk1vZGVsIH0gZnJvbSAnQGFuZ3VsYXIvY2RrL2NvbGxlY3Rpb25zJztcclxuaW1wb3J0IHtcclxuICBzZXRDaGFydEhlaWdodCxcclxuICBzbGVlcCxcclxuICBpc0VtcHR5RGF0YSxcclxuICBnZXREaXNwbGF5UG9ydCxcclxuICBnZXRGaWxlRnJvbUlucHV0LFxyXG4gIGlzU2FtZUZpbGUsXHJcbiAgZ2V0QWJicmV2aWF0ZWRGaWxlTmFtZSxcclxuICBnZXRGaWxlRnJvbURyb3AsXHJcbiAgZ2V0UmVhbFBvcnRzLFxyXG4gIGdldFRpbWVTdHJpbmcsXHJcbiAgcHJpbnRQcm9jZXNzZWRUaW1lLFxyXG4gIGdldFRpbWVSYW5nZVN0cmluZyxcclxuICBnZW5lcmF0ZVBvcnRzLFxyXG4gIGdldERlZmF1bHRUaW1lem9uZSxcclxuICBibG9iVG9GaWxlXHJcbn0gZnJvbSAnLi4vdXRpbHMnO1xyXG5pbXBvcnQgeyBBYm9ydCwgQWxlcnQsIEh0bWxFbGVtZW50LCBJdGVtLCBDaGFydENvbnRlbnREYXRhLCBDaGFydENvbnRlbnRIZWFkZXIsIENoYXJ0Q29udGVudFRpbWUsIFBvcnQgfSBmcm9tICcuLi90eXBlcyc7XHJcbmltcG9ydCB7IEZpbGVTZXJ2aWNlLCBDaGFydFNlcnZpY2UsIFVJU2VydmljZSB9IGZyb20gJy4uL3NlcnZpY2VzJztcclxuXHJcbmltcG9ydCAnaGFtbWVyanMnO1xyXG5pbXBvcnQgJy4uL3V0aWxzL2NoYXJ0anMtZG93bnNhbXBsZSc7XHJcbmltcG9ydCAnLi4vdXRpbHMvY2hhcnRqcy16b29tJztcclxuXHJcbmVudW0gU2VhcmNoVHlwZSB7XHJcbiAgc2VhcmNoV2l0aFN1YkhlYWRlciA9ICdzZWFyY2hXaXRoU3ViSGVhZGVyJyxcclxuICBzZWFyY2hBbGwgPSAnc2VhcmNoQWxsJyxcclxuICBzZWFyY2hJbkNoaWxkcmVuID0gJ3NlYXJjaEluQ2hpbGRyZW4nXHJcbn1cclxuXHJcbkBDb21wb25lbnQoe1xyXG4gIHNlbGVjdG9yOiAnbmd4LWhhbmEtbmFtZXNlcnZlci1oaXN0b3J5LXZpZXdlcicsXHJcbiAgdGVtcGxhdGVVcmw6ICcuL25hbWVzZXJ2ZXItaGlzdG9yeS5jb21wb25lbnQuaHRtbCcsXHJcbiAgc3R5bGVVcmxzOiBbICcuL25hbWVzZXJ2ZXItaGlzdG9yeS5jb21wb25lbnQuc2NzcycgXSxcclxuICBwcm92aWRlcnM6IFsgRmlsZVNlcnZpY2UsIENoYXJ0U2VydmljZSwgVUlTZXJ2aWNlIF1cclxufSlcclxuZXhwb3J0IGNsYXNzIE5hbWVTZXJ2ZXJIaXN0b3J5Q29tcG9uZW50IGltcGxlbWVudHMgT25DaGFuZ2VzLCBPbkluaXQge1xyXG4gIEBWaWV3Q2hpbGQoJ25hbWVzZXJ2ZXJIaXN0b3J5QWxsJywgeyByZWFkOiBFbGVtZW50UmVmIH0pIG5hbWVzZXJ2ZXJIaXN0b3J5QWxsUmVmOiBFbGVtZW50UmVmO1xyXG4gIEBWaWV3Q2hpbGQoJ25hbWVzZXJ2ZXJIaXN0b3J5Q29udGVudCcsIHsgcmVhZDogRWxlbWVudFJlZiB9KSBuYW1lc2VydmVySGlzdG9yeUNvbnRlbnRSZWY6IEVsZW1lbnRSZWY7XHJcblxyXG4gIC8qKlxyXG4gICAqIElucHV0IChvcHRpb25hbCkgYmluZCB0byBbZGVmYXVsdFNlbGVjdGVkSXRlbXNdXHJcbiAgICovXHJcbiAgQElucHV0KCkgZGVmYXVsdFNlbGVjdGVkSXRlbXM6IHN0cmluZ1tdO1xyXG5cclxuICAvKipcclxuICAgKiBJbnB1dCAob3B0aW9uYWwpIGJpbmQgdG8gW2hpZGVNZWFzdXJlQ29sdW1uc11cclxuICAgKi9cclxuICBASW5wdXQoKSBoaWRlTWVhc3VyZUNvbHVtbnM6IHN0cmluZ1tdO1xyXG5cclxuICAvKipcclxuICAgKiBJbnB1dCAob3B0aW9uYWwpIGJpbmQgdG8gW21heFJvd3NMaW1pdGF0aW9uXVxyXG4gICAqL1xyXG4gIEBJbnB1dCgpIG1heFJvd3NMaW1pdGF0aW9uOiBudW1iZXI7XHJcblxyXG4gIC8qKlxyXG4gICAqIElucHV0IChvcHRpb25hbCkgYmluZCB0byBbc2hvd0luc3RydWN0aW9uXVxyXG4gICAqL1xyXG4gIEBJbnB1dCgpIHNob3dJbnN0cnVjdGlvbiA9IHRydWU7XHJcblxyXG4gIC8qKlxyXG4gICAqIElucHV0IChvcHRpb25hbCkgYmluZCB0byBbdGltZXpvbmVdXHJcbiAgICovXHJcbiAgQElucHV0KCkgdGltZXpvbmU6IHN0cmluZztcclxuXHJcbiAgLyoqXHJcbiAgICogZmlsZSBidWZmZXIsIHVzZSB0aGlzIGZvciBzdHJlYW0gbW9kZVxyXG4gICAqL1xyXG4gIEBJbnB1dCgpIGZpbGVCdWZmZXI6IEJsb2I7XHJcblxyXG4gIC8qKlxyXG4gICAqIGZpbGUgbmFtZSBmb3Igc3RyZWFtIG1vZGVcclxuICAgKi9cclxuICBASW5wdXQoKSBzdHJlYW1Nb2RlRmlsZU5hbWU6IHN0cmluZztcclxuXHJcblxyXG4gIC8qKlxyXG4gICAqIHNlbGVjdGVkIG5hbWUgc2VydmVyIGhpc3RvcnkgZmlsZVxyXG4gICAqL1xyXG4gIGZpbGU6IEZpbGU7XHJcblxyXG4gIC8qKlxyXG4gICAqIHRpbWUgaW5mbyBvZiB0aGUgbmFtZSBzZXJ2ZXIgaGlzdG9yeSBmaWxlXHJcbiAgICovXHJcbiAgdGltZTogQ2hhcnRDb250ZW50VGltZSA9IHt9O1xyXG5cclxuICAvKipcclxuICAgKiBkYXRhIG9mIHRoZSBuYW1lIHNlcnZlciBoaXN0b3J5IGZpbGVcclxuICAgKi9cclxuICBkYXRhOiBDaGFydENvbnRlbnREYXRhID0ge307XHJcblxyXG4gIC8qKlxyXG4gICAqIGhlYWRlciBvZiB0aGUgbmFtZSBzZXJ2ZXIgaGlzdG9yeSBmaWxlXHJcbiAgICovXHJcbiAgaGVhZGVyOiBDaGFydENvbnRlbnRIZWFkZXJbXSA9IFtdO1xyXG5cclxuICAvKipcclxuICAgKiBob3N0IG9mIHRoZSBuYW1lIHNlcnZlciBoaXN0b3J5IGZpbGVcclxuICAgKi9cclxuICBob3N0ID0gJ25hbWVzZXJ2ZXIgaGlzdG9yeSBmaWxlJztcclxuXHJcbiAgLyoqXHJcbiAgICogYWxlcnQgbWVzc2FnZSBjb250ZW50XHJcbiAgICovXHJcbiAgYWxlcnRNZXNzYWdlOiBzdHJpbmc7XHJcblxyXG4gIC8qKlxyXG4gICAqIGFsZXJ0IG1lc3NhZ2UgdHlwZVxyXG4gICAqL1xyXG4gIGFsZXJ0VHlwZTogQWxlcnQ7XHJcblxyXG4gIC8qKlxyXG4gICAqIHNlbGVjdGVkIHBvcnRcclxuICAgKi9cclxuICBwb3J0OiBzdHJpbmc7XHJcblxyXG4gIC8qKlxyXG4gICAqIGFsbCB0aGUgcG9ydHMgZnJvbSB0aGUgbmFtZXNlcnZlciBoaXN0b3J5IGZpbGVcclxuICAgKi9cclxuICBwb3J0czogUG9ydFtdO1xyXG5cclxuICAvKipcclxuICAgKiBzZWxlY3RlZCB0aW1lIHJhbmdlXHJcbiAgICovXHJcbiAgZGF0ZVRpbWVSYW5nZTogRGF0ZVtdO1xyXG5cclxuICAvKipcclxuICAgKiBkYXRhIHNvdXJjZSBmb3IgdGhlIHNlbGVjdGlvbiB0YWJsZSAocmlnaHQgcGFydCBvZiB0aGUgY2hhcnQpXHJcbiAgICovXHJcbiAgdGFibGVTb3VyY2U6IGFueVtdO1xyXG5cclxuICAvKipcclxuICAgKiB0aGUgcHJvZ3Jlc3MgZm9yIHJlYWRpbmcgZmlsZVxyXG4gICAqL1xyXG4gIHJlYWRQcm9ncmVzcyA9IDA7XHJcblxyXG4gIC8qKlxyXG4gICAqIHNlbGVjdGVkL2Ryb3BwZWQgZmlsZSBuYW1lIChhYmJyZXZpYXRpb24pLCBmdWxsIGZpbGUgbmFtZSB3aWxsIGJlIHNob3duIHZpYSB0aGUgdG9vbHRpcHNcclxuICAgKi9cclxuICBhYmJyZXZpYXRlZEZpbGVOYW1lID0gJ29yIERyb3AgRmlsZSBIZXJlJztcclxuXHJcbiAgLyoqXHJcbiAgICogZm9yIHRoZSBpbnN0cnVjdGlvbiBzdGVwIDRcclxuICAgKi9cclxuICBzdGVwU2hvd0NoYXJ0ID0gZmFsc2U7XHJcblxyXG4gIC8qKlxyXG4gICAqIGNvbnRyb2wgZmxhZyBmb3Igc2hvd2luZyB0aGUgbmFtZSBzZXJ2ZXIgaGlzdG9yeSBjaGFydFxyXG4gICAqL1xyXG4gIHNob3dDaGFydEZsYWc6IGJvb2xlYW47XHJcblxyXG4gIC8qKlxyXG4gICAqIGNvbnRyb2wgZmxhZyBmb3Igc2hvd2luZyB0aGUgZmlsZSByZWFkaW5nIHByb2dyZXNzXHJcbiAgICovXHJcbiAgc2hvd1JlYWRGaWxlUHJvZ3Jlc3M6IGJvb2xlYW47XHJcblxyXG4gIC8qKlxyXG4gICAqIGNvbnRyb2wgZmxhZyBmb3IgXCJMb2FkXCIgcG9ydHMgYnV0dG9uXHJcbiAgICovXHJcbiAgZW5hYmxlTG9hZFBvcnRzQnV0dG9uOiBib29sZWFuO1xyXG5cclxuICAvKipcclxuICAgKiBjb250cm9sIGZsYWcgZm9yIGVuYWJsaW5nIFwiU2hvd1wiIGNoYXJ0IGJ1dHRvblxyXG4gICAqL1xyXG4gIGVuYWJsZVNob3dDaGFydEJ1dHRvbjogYm9vbGVhbjtcclxuXHJcbiAgLyoqXHJcbiAgICogY29udHJvbCBmbGFnIGZvciBcIlJlc2V0XCIgY2hhcnQgYnV0dG9uXHJcbiAgICovXHJcbiAgZW5hYmxlUmVzZXRDaGFydEJ1dHRvbjogYm9vbGVhbjtcclxuXHJcbiAgc2VhcmNoVHlwZSA9IFNlYXJjaFR5cGUuc2VhcmNoQWxsO1xyXG5cclxuICAvKipcclxuICAgKiBzZWxlY3Rpb24gaW5mb3JtYXRpb24gZm9yIHRoZSBzZWxlY3Rpb24gdGFibGVcclxuICAgKi9cclxuICBwcml2YXRlIF9zZWxlY3Rpb246IFNlbGVjdGlvbk1vZGVsPGFueT47XHJcblxyXG4gIC8qKlxyXG4gICAqIGN1cnJlbnQgZGlzcGxheWluZyBwb3J0XHJcbiAgICovXHJcbiAgcHJpdmF0ZSBfY3VycmVudENoYXJ0UG9ydDogc3RyaW5nO1xyXG5cclxuICBjb25zdHJ1Y3Rvcihwcml2YXRlIGZpbGVTZXJ2aWNlOiBGaWxlU2VydmljZSxcclxuICAgICAgICAgICAgICBwcml2YXRlIGNoYXJ0U2VydmljZTogQ2hhcnRTZXJ2aWNlLFxyXG4gICAgICAgICAgICAgIHByaXZhdGUgdWlTZXJ2aWNlOiBVSVNlcnZpY2UpIHt9XHJcblxyXG4gIG5nT25Jbml0KCkge1xyXG4gICAgLy8gdGhpcy50aW1lem9uZSA9IHRoaXMuZGVmYXVsdFRpbWV6b25lO1xyXG4gICAgdGhpcy5vblJlc2l6ZSgpO1xyXG5cclxuICAgIC8vIGluaXQgaXRlbXMnIHN0YXR1c1xyXG4gICAgLy8gcmVzZXQgY2hhcnQgYnV0dG9uIHdpbGwgYmUgZGlzYWJsZSBieSBkZWZhdWx0IGxhdGVyLCBvbmx5IGJlIGVuYWJsZWQgYWZ0ZXIgem9vbWVkXHJcbiAgICB0aGlzLl90b2dnbGVJdGVtcyhbXHJcbiAgICAgIHtpZDogSHRtbEVsZW1lbnQuY2hhcnRBcmVhLCBzdGF0dXM6IGZhbHNlfSxcclxuICAgICAge2lkOiBIdG1sRWxlbWVudC5yZWFkRmlsZVByb2dyZXNzLCBzdGF0dXM6IGZhbHNlfSxcclxuICAgICAge2lkOiBIdG1sRWxlbWVudC5zaG93Q2hhcnRCdXR0b24sIHN0YXR1czogZmFsc2V9LFxyXG4gICAgICB7aWQ6IEh0bWxFbGVtZW50LmxvYWRQb3J0c0J1dHRvbiwgc3RhdHVzOiB0cnVlfSxcclxuICAgICAge2lkOiBIdG1sRWxlbWVudC5yZXNldENoYXJ0QnV0dG9uLCBzdGF0dXM6IGZhbHNlfV0pO1xyXG5cclxuICB9XHJcblxyXG4gIG5nT25DaGFuZ2VzKGNoYW5nZXM6IFNpbXBsZUNoYW5nZXMpIHtcclxuICAgIGNvbnN0IGZiYyA9IGNoYW5nZXMuZmlsZUJ1ZmZlcjtcclxuICAgIGlmIChmYmMgJiYgZmJjLmN1cnJlbnRWYWx1ZSAmJiBmYmMuY3VycmVudFZhbHVlICE9PSBmYmMucHJldmlvdXNWYWx1ZSkge1xyXG4gICAgICAvLyBzaW11bGF0ZSBzZWxlY3RpbmcgZmlsZVxyXG4gICAgICBjb25zdCBzaW11bGF0ZWRFdmVudCA9IHt0YXJnZXQ6IHtmaWxlczogW2Jsb2JUb0ZpbGUodGhpcy5maWxlQnVmZmVyLCB0aGlzLnN0cmVhbU1vZGVGaWxlTmFtZSldfX07XHJcbiAgICAgIHRoaXMuZmlsZVNlbGVjdGVkKHNpbXVsYXRlZEV2ZW50KTtcclxuICAgIH1cclxuICB9XHJcblxyXG4gICAgLyoqXHJcbiAgICogUmVzZXQgQ2hhcnQgdG8gaW5pdGlhbCBzdGF0dXNcclxuICAgKiBJZiBsZWdlbmQgaXMgYWxyZWFkeSBzZWxlY3RlZC91bnNlbGVjdGVkIGZyb20gdGhlIGxpc3QsIGl0IHdvdWxkbid0IGJlIHJlc3RvcmVkLlxyXG4gICAqL1xyXG4gIHJlc2V0Q2hhcnQoKTogdm9pZCB7XHJcbiAgICB0aGlzLl90b2dnbGVJdGVtcyhbe2lkOiBIdG1sRWxlbWVudC5yZXNldENoYXJ0QnV0dG9uLCBzdGF0dXM6IGZhbHNlfV0pO1xyXG5cclxuICAgIGlmICh0aGlzLnRhYmxlU291cmNlICYmIHRoaXMuX3NlbGVjdGlvbikge1xyXG4gICAgICB0aGlzLmNoYXJ0U2VydmljZS5yZXNldENoYXJ0KHRoaXMudGFibGVTb3VyY2UsIHRoaXMuX3NlbGVjdGlvbilcclxuICAgICAgICAuY2F0Y2goZSA9PiB0aGlzLl9zaG93TWVzc2FnZShBbGVydC5lcnJvciwgZSkpO1xyXG4gICAgfVxyXG4gIH1cclxuXHJcbiAgLyoqXHJcbiAgICogcmVhZCB0aGUgZmlsZSBhbmQgZGlzcGxheSB0aGUgY2hhcnRcclxuICAgKi9cclxuICBzaG93Q2hhcnQoKTogdm9pZCB7XHJcbiAgICAvLyBhZnRlciBjbGljaywgdGhpcyBidXR0b24gYW5kIHJlc2V0IGJ1dHRvbiBuZWVkcyB0byBiZSBkaXNhYmxlZFxyXG4gICAgdGhpcy5fdG9nZ2xlSXRlbXMoW1xyXG4gICAgICB7aWQ6IEh0bWxFbGVtZW50LnJlc2V0Q2hhcnRCdXR0b24sIHN0YXR1czogZmFsc2V9LFxyXG4gICAgICB7aWQ6IEh0bWxFbGVtZW50LnNob3dDaGFydEJ1dHRvbiwgc3RhdHVzOiBmYWxzZX1dKTtcclxuXHJcbiAgICB0aGlzLnN0ZXBTaG93Q2hhcnQgPSB0cnVlO1xyXG5cclxuICAgIHRoaXMuX2luaXRDaGFydEVudigpLnRoZW4oKCkgPT4ge1xyXG4gICAgICBjb25zdCBzZWxlY3RlZFRpbWUgPSB0aGlzLl9zZWxlY3RlZFRpbWVSYW5nZTtcclxuICAgICAgaWYgKHNlbGVjdGVkVGltZS5zdGFydFRpbWUgPiBzZWxlY3RlZFRpbWUuZW5kVGltZSkge1xyXG4gICAgICAgIHRoaXMuX3Nob3dNZXNzYWdlKEFsZXJ0LmVycm9yLCAnVGltZSByYW5nZSBpcyBub3QgY29ycmVjdC4nKTtcclxuICAgICAgICByZXR1cm47XHJcbiAgICAgIH1cclxuICAgICAgaWYgKHRoaXMuZmlsZSkge1xyXG4gICAgICAgIC8vIGl0J3MgdGltZSBmb3IgZGlzcGxheWluZyB0aGUgcmVhZGluZyBwcm9ncmVzcyBiYXJcclxuICAgICAgICB0aGlzLl90b2dnbGVJdGVtcyhbe2lkOiBIdG1sRWxlbWVudC5yZWFkRmlsZVByb2dyZXNzLCBzdGF0dXM6IHRydWV9XSk7XHJcbiAgICAgICAgcmV0dXJuIHRoaXMuX2J1aWxkQ2hhcnRGcm9tRGF0YUZpbGUodGhpcy5maWxlLCBzZWxlY3RlZFRpbWUuc3RhcnRUaW1lLCBzZWxlY3RlZFRpbWUuZW5kVGltZSwgdGhpcy5wb3J0KTtcclxuICAgICAgfVxyXG4gICAgfSkuY2F0Y2goZSA9PiB7XHJcbiAgICAgIHRoaXMuX3Nob3dNZXNzYWdlKEFsZXJ0LmVycm9yLCBlKTtcclxuICAgICAgdGhpcy5fdG9nZ2xlSXRlbXMoW3tpZDogSHRtbEVsZW1lbnQucmVhZEZpbGVQcm9ncmVzcywgc3RhdHVzOiBmYWxzZX1dKTtcclxuICAgIH0pO1xyXG4gIH1cclxuXHJcbiAgLyoqXHJcbiAgICogbG9hZCBhbGwgcG9ydHMgZnJvbSBmaWxlXHJcbiAgICovXHJcbiAgbG9hZFBvcnRzKCk6IHZvaWQge1xyXG4gICAgLy8gZG8gY29uZmlybWF0aW9uIGFjdGlvbnNcclxuICAgIGlmICh0aGlzLmZpbGUpIHtcclxuICAgICAgLy8gYmVmb3JlIHN0YXJ0IGxvYWRpbmcgcG9ydHMgZnJvbSBmaWxlLCBkaXNwbGF5IHByb2dyZXNzIGJhciBhbmQgZGlzYWJsZSB0aGUgc2hvdyBjaGFydCBidXR0b25cclxuICAgICAgdGhpcy5fdG9nZ2xlSXRlbXMoW1xyXG4gICAgICAgIHtpZDogSHRtbEVsZW1lbnQucmVhZEZpbGVQcm9ncmVzcywgc3RhdHVzOiB0cnVlfSxcclxuICAgICAgICB7aWQ6IEh0bWxFbGVtZW50LnNob3dDaGFydEJ1dHRvbiwgc3RhdHVzOiBmYWxzZX1cclxuICAgICAgXSk7XHJcbiAgICAgIHRoaXMuX3JlYWRQb3J0c0Zyb21GaWxlKHRoaXMuZmlsZSk7XHJcbiAgICB9XHJcbiAgfVxyXG5cclxuICAvKipcclxuICAgKiBzZWxlY3QgbmFtZSBzZXJ2ZXIgaGlzdG9yeSBmaWxlLCBjdXJyZW50bHkgb25seSBzdXBwb3J0cyAxIGZpbGUuXHJcbiAgICovXHJcbiAgZmlsZVNlbGVjdGVkKGV2ZW50OiBhbnkpIHtcclxuICAgIGNvbnN0IHNlbGVjdGVkRmlsZSA9IGdldEZpbGVGcm9tSW5wdXQoZXZlbnQudGFyZ2V0KTtcclxuICAgIGlmIChzZWxlY3RlZEZpbGUpIHtcclxuICAgICAgaWYgKCFpc1NhbWVGaWxlKHRoaXMuZmlsZSwgc2VsZWN0ZWRGaWxlKSkge1xyXG4gICAgICAgIC8vIGluaXQgcG9ydCBzZWxlY3RvclxyXG4gICAgICAgIHRoaXMuX2luaXRQb3J0U2VsZWN0b3IoKS5jYXRjaChlID0+IHRoaXMuX3Nob3dNZXNzYWdlKEFsZXJ0LmVycm9yLCBlKSk7XHJcblxyXG4gICAgICAgIHRoaXMuZmlsZSA9IHNlbGVjdGVkRmlsZTtcclxuICAgICAgICB0aGlzLmFiYnJldmlhdGVkRmlsZU5hbWUgPSBnZXRBYmJyZXZpYXRlZEZpbGVOYW1lKHRoaXMuZmlsZS5uYW1lKTtcclxuICAgICAgICAvLyBhZnRlciBmaWxlIGhhcyBiZWVuIHNlbGVjdGVkLCB0aGUgc2hvdyBjaGFydCBidXR0b24gbmVlZHMgdG8gYmUgZW5hYmxlZFxyXG4gICAgICAgIHRoaXMuX3RvZ2dsZUl0ZW1zKFt7aWQ6IEh0bWxFbGVtZW50LnNob3dDaGFydEJ1dHRvbiwgc3RhdHVzOiB0cnVlfV0pO1xyXG4gICAgICB9XHJcbiAgICB9XHJcbiAgfVxyXG5cclxuICAvKipcclxuICAgKiBkcm9wIG5hbWUgc2VydmVyIGhpc3RvcnkgZmlsZSwgY3VycmVudGx5IG9ubHkgc3VwcG9ydHMgMSBmaWxlLlxyXG4gICAqL1xyXG4gIGZpbGVEcm9wcGVkKGV2ZW50OiBhbnkpIHtcclxuICAgIGdldEZpbGVGcm9tRHJvcChldmVudClcclxuICAgICAgLnRoZW4oZmlsZSA9PiB7XHJcbiAgICAgICAgaWYgKCFpc1NhbWVGaWxlKHRoaXMuZmlsZSwgZmlsZSkpIHtcclxuICAgICAgICAgIC8vIGluaXQgcG9ydCBzZWxlY3RvclxyXG4gICAgICAgICAgdGhpcy5maWxlID0gZmlsZTtcclxuICAgICAgICAgIGlmICh0aGlzLmZpbGUpIHtcclxuICAgICAgICAgICAgdGhpcy5hYmJyZXZpYXRlZEZpbGVOYW1lID0gZ2V0QWJicmV2aWF0ZWRGaWxlTmFtZSh0aGlzLmZpbGUubmFtZSk7XHJcbiAgICAgICAgICAgIC8vIGFmdGVyIGZpbGUgaGFzIGJlZW4gZHJvcHBlZCwgdGhlIHNob3cgY2hhcnQgYnV0dG9uIG5lZWRzIHRvIGJlIGVuYWJsZWRcclxuICAgICAgICAgICAgdGhpcy5fdG9nZ2xlSXRlbXMoW3tpZDogSHRtbEVsZW1lbnQuc2hvd0NoYXJ0QnV0dG9uLCBzdGF0dXM6IHRydWV9XSk7XHJcbiAgICAgICAgICB9XHJcbiAgICAgICAgfX0pXHJcbiAgICAgIC50aGVuKCgpID0+ICB7XHJcbiAgICAgICAgcmV0dXJuIHRoaXMuX2luaXRQb3J0U2VsZWN0b3IoKTtcclxuICAgICAgfSlcclxuICAgICAgLmNhdGNoKGUgPT4gdGhpcy5fc2hvd01lc3NhZ2UoQWxlcnQuZXJyb3IsIGUpKTtcclxuICB9XHJcblxyXG4gIC8qKlxyXG4gICAqIFNlbGVjdCBvbmUgaXRlbSBmcm9tIHNlbGVjdGlvbiB0YWJsZSwgcmVsYXRpdmUgZGF0YXNldCB3aWxsIGJlIHNob3duIG9yIGhpZGRlblxyXG4gICAqL1xyXG4gIHNlbGVjdEl0ZW0oZXZlbnQ6IGFueSkge1xyXG4gICAgaWYgKGV2ZW50ICYmIGV2ZW50LnRhYmxlUm93KSB7XHJcbiAgICAgIGNvbnN0IHJvdyA9IGV2ZW50LnRhYmxlUm93O1xyXG4gICAgICB0aGlzLl9zZWxlY3Rpb24udG9nZ2xlKHJvdyk7XHJcbiAgICAgIHRoaXMuY2hhcnRTZXJ2aWNlLnRvZ2dsZURhdGFJbkNoYXJ0KHJvdy5LUEksICF0aGlzLl9zZWxlY3Rpb24uaXNTZWxlY3RlZChyb3cpKVxyXG4gICAgICAgIC5jYXRjaChlID0+IHRoaXMuX3Nob3dNZXNzYWdlKEFsZXJ0LmVycm9yLCBlKSk7XHJcbiAgICB9XHJcbiAgfVxyXG5cclxuICAvKipcclxuICAgKiByZWNhbGN1bGF0aW5nIGNoYXJ0IGhlaWdodCB3aGVuIHJlc2l6aW5nXHJcbiAgICovXHJcbiAgb25SZXNpemUoKSB7XHJcbiAgICBjb25zdCBuYW1lc2VydmVySGlzdG9yeUFsbEVsZW1lbnQgPSB0aGlzLm5hbWVzZXJ2ZXJIaXN0b3J5QWxsUmVmID8gdGhpcy5uYW1lc2VydmVySGlzdG9yeUFsbFJlZi5uYXRpdmVFbGVtZW50IDogbnVsbDtcclxuICAgIGNvbnN0IG5hbWVzZXJ2ZXJIaXN0b3J5Q29udGVudEVsZW1lbnQgPSB0aGlzLm5hbWVzZXJ2ZXJIaXN0b3J5Q29udGVudFJlZiA/IHRoaXMubmFtZXNlcnZlckhpc3RvcnlDb250ZW50UmVmLm5hdGl2ZUVsZW1lbnQgOiBudWxsO1xyXG4gICAgc2V0Q2hhcnRIZWlnaHQobmFtZXNlcnZlckhpc3RvcnlBbGxFbGVtZW50LCBuYW1lc2VydmVySGlzdG9yeUNvbnRlbnRFbGVtZW50KTtcclxuICB9XHJcblxyXG4gIC8qKlxyXG4gICAqIFN3aXRjaCBwb3J0IGFuZCByZWluaXRpYWxpemUgY2hhcnQsIHRyaWdnZXJlZCBieSBjaGFuZ2luZyB0aGUgcG9ydFxyXG4gICAqIEBwYXJhbSBwb3J0IHRoZSBzZWxlY3RlZCBwb3J0XHJcbiAgICovXHJcbiAgc3dpdGNoUG9ydEZvckNoYXJ0KHBvcnQ6IHN0cmluZyk6IHZvaWQge1xyXG4gICAgaWYgKHBvcnQgPT09IHRoaXMuX2N1cnJlbnRDaGFydFBvcnQpIHtcclxuICAgICAgLy8gbm90IHRvIHN3aXRjaCBwb3J0LCBiZWNhdXNlIHRoZSByZWxhdGl2ZSBwb3J0IGlzIGRpc3BsYXlpbmcsIG5vIG5lZWQgdG8gcmVuZGVyIHR3aWNlLlxyXG4gICAgICByZXR1cm47XHJcbiAgICB9XHJcbiAgICBpZiAoIXRoaXMuZmlsZSB8fCAhcG9ydCB8fCBwb3J0Lmxlbmd0aCA9PT0gMCB8fCBwb3J0LnNsaWNlKDEsIDMpID09PSAnKionKSB7XHJcbiAgICAgIHJldHVybjtcclxuICAgIH0gZWxzZSBpZiAoT2JqZWN0LmtleXModGhpcy50aW1lKS5sZW5ndGggPiAxICYmICFnZXRSZWFsUG9ydHMoT2JqZWN0LmtleXModGhpcy50aW1lKS5maWx0ZXIoa2V5ID0+IHRoaXMudGltZVtrZXldKSkuaW5jbHVkZXMocG9ydCkpIHtcclxuICAgICAgdGhpcy5fc2hvd01lc3NhZ2UoQWxlcnQuaW5mbywgYERhdGEgb2YgcG9ydDoke3BvcnR9IGlzIG5vdCBsb2FkZWQsIHBsZWFzZSBsb2FkIHRoZSBkYXRhIGZpcnN0IGJ5IGNsaWNraW5nIHRoZSBcIlNob3dcIiBidXR0b24uYCk7XHJcbiAgICAgIHJldHVybjtcclxuICAgIH1cclxuXHJcbiAgICAvLyBvbmx5IGRvIHN3aXRjaCBwb3J0cyB3aGVuIGF2YWlsYWJsZSBwb3J0cyBudW1iZXIgPiAxXHJcbiAgICBpZiAoT2JqZWN0LmtleXModGhpcy50aW1lKS5maWx0ZXIoa2V5ID0+IHRoaXMudGltZVtrZXldKS5sZW5ndGggPiAxKSB7XHJcbiAgICAgIC8vIGRpc2FibGUgdGhlIFwic2hvdyBjaGFydFwiIGFuZCBcInJlc2V0IGNoYXJ0XCIgYnV0dG9uIGZpcnN0XHJcbiAgICAgIHRoaXMuX3RvZ2dsZUl0ZW1zKFtcclxuICAgICAgICB7aWQ6IEh0bWxFbGVtZW50LnNob3dDaGFydEJ1dHRvbiwgc3RhdHVzOiBmYWxzZX0sXHJcbiAgICAgICAge2lkOiBIdG1sRWxlbWVudC5yZXNldENoYXJ0QnV0dG9uLCBzdGF0dXM6IGZhbHNlfV0pO1xyXG4gICAgICAvLyBpbml0IHRoZSBlbnZpcm9ubWVudCB3aXRoIHN3aXRjaCBmbGFnXHJcbiAgICAgIHRoaXMuX2luaXRDaGFydEVudih0cnVlKS50aGVuKCgpID0+IHtcclxuICAgICAgICByZXR1cm4gdGhpcy5fYnVpbGRDaGFydChwb3J0LCBudWxsLCB0cnVlKTtcclxuICAgICAgfSkuY2F0Y2goZSA9PiB0aGlzLl9zaG93TWVzc2FnZShBbGVydC5lcnJvciwgZSkpO1xyXG4gICAgfVxyXG4gIH1cclxuXHJcbiAgLyoqXHJcbiAgICogZ2V0IHRoZSBjb2x1bW5zIHdoaWNoIG5lZWQgdG8gYmUgaGlkZGVuIGZyb20gdGhlIHNlbGVjdGlvbiB0YWJsZVxyXG4gICAqL1xyXG4gIGdldCBoaWRkZW5Db2x1bW5zKCk6IHN0cmluZ1tdIHtcclxuICAgIHJldHVybiB0aGlzLnVpU2VydmljZS5nZXRIaWRkZW5Db2x1bW5zKHRoaXMuaGlkZU1lYXN1cmVDb2x1bW5zKTtcclxuICB9XHJcblxyXG4gIC8qKlxyXG4gICAqIGdldCBkZWZhdWx0IHRpbWV6b25lXHJcbiAgICovXHJcbiAgZ2V0IGRlZmF1bHRUaW1lem9uZSgpOiBzdHJpbmcge1xyXG4gICAgcmV0dXJuIGdldERlZmF1bHRUaW1lem9uZSgpO1xyXG4gIH1cclxuXHJcbiAgLyoqXHJcbiAgICogZ2V0IHRoZSBrZXkgY29sdW1uIChLUEkpXHJcbiAgICovXHJcbiAgZ2V0IGtwaUNvbHVtbigpOiBJdGVtIHtcclxuICAgIHJldHVybiBJdGVtLmtwaTtcclxuICB9XHJcblxyXG4gIC8qKlxyXG4gICAqIGdldCB0aGUga2V5IGNvbHVtbiAoS1BJKVxyXG4gICAqL1xyXG4gIGdldCBkZXNjQ29sdW1uKCk6IEl0ZW0ge1xyXG4gICAgcmV0dXJuIEl0ZW0uZGVzY3JpcHRpb247XHJcbiAgfVxyXG5cclxuICAvKipcclxuICAgKiBnZXQgdGhlIHNlbGVjdGVkIHRpbWUgcmFuZ2UsIHNldCBzZWNvbmQgYW5kIG1pbGxpc2Vjb25kIHBhcnQgdG8gMFxyXG4gICAqL1xyXG4gIHByaXZhdGUgZ2V0IF9zZWxlY3RlZFRpbWVSYW5nZSgpOiB7c3RhcnRUaW1lOiBudW1iZXIsIGVuZFRpbWU6IG51bWJlcn0ge1xyXG4gICAgbGV0IHN0YXJ0VGltZSA9IDA7XHJcbiAgICBsZXQgZW5kVGltZSA9IDQxMDIzNTg0MDAwMDA7IC8vIDIwOTkvMTIvMzFcclxuICAgIGlmICh0aGlzLmRhdGVUaW1lUmFuZ2UgIT0gbnVsbCkge1xyXG4gICAgICBpZiAodGhpcy5kYXRlVGltZVJhbmdlLmxlbmd0aCA+PSAxKSB7XHJcbiAgICAgICAgLy8gZ2V0IHN0YXJ0IHRpbWVcclxuICAgICAgICBpZiAodGhpcy5kYXRlVGltZVJhbmdlWzBdKSB7XHJcbiAgICAgICAgICBzdGFydFRpbWUgPSB0aGlzLmRhdGVUaW1lUmFuZ2VbMF0uc2V0U2Vjb25kcygwLCAwKTtcclxuICAgICAgICB9XHJcbiAgICAgICAgaWYgKHRoaXMuZGF0ZVRpbWVSYW5nZVsxXSkge1xyXG4gICAgICAgICAgZW5kVGltZSA9IHRoaXMuZGF0ZVRpbWVSYW5nZVsxXS5zZXRTZWNvbmRzKDAsIDApO1xyXG4gICAgICAgIH1cclxuICAgICAgfVxyXG4gICAgfVxyXG4gICAgcmV0dXJuIHtzdGFydFRpbWU6IHN0YXJ0VGltZSwgZW5kVGltZTogZW5kVGltZX07XHJcbiAgfVxyXG5cclxuICAvKipcclxuICAgKiBnZXQgdGhlIHRpbWUgcmFuZ2Ugc3RyaW5nLCBlZzogMjAxOC0xMC0yNSAxMDoyNSB+IDIwMTgtMTAtMjYgMTA6MjZcclxuICAgKi9cclxuICBwcml2YXRlIGdldCBfc2VsZWN0ZWRUaW1lUmFuZ2VTdHJpbmcoKTogc3RyaW5nIHtcclxuICAgIGNvbnN0IHNlbGVjdGVkVGltZVJhbmdlU3RyaW5nID0gdGhpcy5fc2VsZWN0ZWRUaW1lUmFuZ2U7XHJcbiAgICByZXR1cm4gYCR7Z2V0VGltZVN0cmluZyhzZWxlY3RlZFRpbWVSYW5nZVN0cmluZy5zdGFydFRpbWUpfSB+ICR7Z2V0VGltZVN0cmluZyhzZWxlY3RlZFRpbWVSYW5nZVN0cmluZy5lbmRUaW1lKX1gO1xyXG4gIH1cclxuXHJcbiAgLyoqXHJcbiAgICogZ2V0IGFycmF5IG9mIGhlYWRlciBrZXlcclxuICAgKi9cclxuICBwcml2YXRlIGdldCBfaGVhZGVyS2V5KCk6IHN0cmluZ1tdIHtcclxuICAgIGlmICh0aGlzLmhlYWRlcikge1xyXG4gICAgICByZXR1cm4gdGhpcy5oZWFkZXIubWFwKGhlYWRlckl0ZW0gPT4gaGVhZGVySXRlbS5rZXkpO1xyXG4gICAgfVxyXG4gIH1cclxuXHJcbiAgLyoqXHJcbiAgICogZ2V0IGFycmF5IG9mIGhlYWRlciB0ZXh0XHJcbiAgICovXHJcbiAgcHJpdmF0ZSBnZXQgX2hlYWRlclRleHQoKTogc3RyaW5nW10ge1xyXG4gICAgcmV0dXJuIHRoaXMuaGVhZGVyLm1hcChoZWFkZXJJdGVtID0+IGhlYWRlckl0ZW0udGV4dCk7XHJcbiAgfVxyXG5cclxuICAvKipcclxuICAgKiByZWFkIHBvcnRzIGZyb20gdGhlIHNlbGVjdGVkIG5hbWVzZXJ2ZXIgaGlzdG9yeSBmaWxlXHJcbiAgICogQHBhcmFtIGZpbGUgbmFtZXNlcnZlciBoaXN0b3J5IGZpbGVcclxuICAgKi9cclxuICBwcml2YXRlIF9yZWFkUG9ydHNGcm9tRmlsZShmaWxlOiBGaWxlKTogdm9pZCB7XHJcbiAgICB0aGlzLmZpbGVTZXJ2aWNlLmdldFBvcnRzRnJvbUZpbGUoZmlsZSwgKHByb2dyZXNzKSA9PiB7XHJcbiAgICAgIHRoaXMucmVhZFByb2dyZXNzID0gcHJvZ3Jlc3M7XHJcbiAgICB9KS50aGVuKHBvcnRzID0+IHtcclxuICAgICAgcmV0dXJuIHNsZWVwKDEwMCkudGhlbigoKSA9PiB7XHJcbiAgICAgICAgcmV0dXJuIHRoaXMuX2luaXRQb3J0U2VsZWN0b3IocG9ydHMpO1xyXG4gICAgICB9KTtcclxuICAgIH0pLmNhdGNoKGUgPT4gdGhpcy5fc2hvd01lc3NhZ2UoQWxlcnQuZXJyb3IsIGUpKTtcclxuICB9XHJcblxyXG4gIC8qKlxyXG4gICAqIGJ1aWxkIGNoYXJ0IGZyb20gdGhlIHNlbGVjdGVkIG5hbWVzZXJ2ZXIgaGlzdG9yeSBmaWxlXHJcbiAgICogQHBhcmFtIGZpbGUgdGhlIG5hbWVzZXJ2ZXIgaGlzdG9yeSBmaWxlXHJcbiAgICogQHBhcmFtIHN0YXJ0VGltZSBzdGFydCB0aW1lXHJcbiAgICogQHBhcmFtIGVuZFRpbWUgZW5kIHRpbWVcclxuICAgKiBAcGFyYW0gc2VsZWN0ZWRQb3J0IHNlbGVjdGVkIHBvcnQgZm9yIG5hbWVzZXJ2ZXIgaGlzdG9yeSBmaWxlIChNREMgc3lzdGVtKVxyXG4gICAqL1xyXG4gIHByaXZhdGUgX2J1aWxkQ2hhcnRGcm9tRGF0YUZpbGUoZmlsZTogRmlsZSwgc3RhcnRUaW1lOiBudW1iZXIsIGVuZFRpbWU6IG51bWJlciwgc2VsZWN0ZWRQb3J0OiBzdHJpbmcpOiBQcm9taXNlPGFueT4ge1xyXG4gICAgcmV0dXJuIHRoaXMuZmlsZVNlcnZpY2UuZ2V0Q2hhcnRDb250ZW50RnJvbUZpbGUoXHJcbiAgICAgIGZpbGUsXHJcbiAgICAgIHN0YXJ0VGltZSxcclxuICAgICAgZW5kVGltZSxcclxuICAgICAgc2VsZWN0ZWRQb3J0LFxyXG4gICAgICB0aGlzLnRpbWV6b25lLFxyXG4gICAgICB0aGlzLm1heFJvd3NMaW1pdGF0aW9uLCBwcm9ncmVzcyA9PiB0aGlzLnJlYWRQcm9ncmVzcyA9IHByb2dyZXNzKVxyXG4gICAgICAudGhlbihyZXN1bHQgPT4ge1xyXG4gICAgICAgIC8vIHBhcnNpbmcgZG9uZVxyXG4gICAgICAgIGNvbnN0IGJlZ2luVGltZSA9IG5ldyBEYXRlKCk7XHJcbiAgICAgICAgY29uc3QgcHJvbWlzZXMgPSBbXTtcclxuICAgICAgICBjb25zdCBwb3J0cyA9IGdldFJlYWxQb3J0cyhPYmplY3Qua2V5cyhyZXN1bHQudGltZSksIHRydWUpO1xyXG4gICAgICAgIHBvcnRzLmZvckVhY2gocG9ydCA9PiB7XHJcbiAgICAgICAgICAvLyBjb252ZXJ0IHRoZSB1bml0IGFuZCBnZW5lcmF0ZSBjb250cm9sbGluZyBkYXRhIGZvciBhbGwgcG9ydHNcclxuICAgICAgICAgIHByb21pc2VzLnB1c2godGhpcy51aVNlcnZpY2UuY29udmVydFVuaXRBbmRHZW5lcmF0ZUNvbnRyb2xEYXRhKHJlc3VsdC5kYXRhW3BvcnRdLCByZXN1bHQuaGVhZGVyLCBwb3J0KSk7XHJcbiAgICAgICAgfSk7XHJcblxyXG4gICAgICAgIHJldHVybiBQcm9taXNlLmFsbChwcm9taXNlcylcclxuICAgICAgICAgIC50aGVuKCgpID0+IHtcclxuXHJcbiAgICAgICAgICAgIC8vIGdldCBhbGwgcG9ydHMgZnJvbSB0aGUgYW5hbHl6ZWQgZGF0YSh0aW1lKVxyXG4gICAgICAgICAgICAvLyBnZXQgdGhlIHBvcnQgdGhhdCB3aWxsIGJlIHNob3duIGluIHRoZSBwYWdlXHJcbiAgICAgICAgICAgIGNvbnN0IHBvcnQgPSBnZXREaXNwbGF5UG9ydChwb3J0cywgc2VsZWN0ZWRQb3J0KTtcclxuXHJcbiAgICAgICAgICAgIHByaW50UHJvY2Vzc2VkVGltZShiZWdpblRpbWUsICdjb252ZXJ0aW5nIHN0ZXAnKTtcclxuICAgICAgICAgICAgcG9ydHMuZm9yRWFjaCggcG9ydEl0ZW0gPT4gdGhpcy51aVNlcnZpY2UuZ2VuZXJhdGVZU2NhbGUocG9ydEl0ZW0pKTtcclxuICAgICAgICAgICAgcHJpbnRQcm9jZXNzZWRUaW1lKGJlZ2luVGltZSwgJ2dlbmVyYXRpbmcgWVNjYWxlIHN0ZXAnKTtcclxuICAgICAgICAgICAgdGhpcy5kYXRhID0gcmVzdWx0LmRhdGE7XHJcbiAgICAgICAgICAgIHRoaXMudGltZSA9IHJlc3VsdC50aW1lO1xyXG4gICAgICAgICAgICB0aGlzLmhlYWRlciA9IHRoaXMudWlTZXJ2aWNlLmdldEhlYWRlcihyZXN1bHQuaGVhZGVyLCBwb3J0KTtcclxuICAgICAgICAgICAgdGhpcy5ob3N0ID0gcmVzdWx0Lmhvc3Q7XHJcbiAgICAgICAgICAgIGlmIChyZXN1bHQuYWJvcnRlZCA9PT0gQWJvcnQubWF4TGluZU51bVJlYWNoZWQpIHtcclxuICAgICAgICAgICAgICB0aGlzLl9zaG93TWVzc2FnZShcclxuICAgICAgICAgICAgICAgIEFsZXJ0Lndhcm5pbmcsIGBNYXhpbXVtIG51bWJlciBvZiBsaW5lcyByZWFjaGVkLiBQcm9jZXNzZWQgdGltZSByYW5nZSBpczogJHtnZXRUaW1lUmFuZ2VTdHJpbmcodGhpcy50aW1lKX0uYCk7XHJcbiAgICAgICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgICAgaWYgKGlzRW1wdHlEYXRhKHRoaXMuZGF0YSkpIHtcclxuICAgICAgICAgICAgICAgIHRoaXMuX3Nob3dNZXNzYWdlKEFsZXJ0LmluZm8sIGBDYW5ub3QgZmluZCBhbnkgZGF0YSBmb3IgdGhlIHNlbGVjdGVkIHRpbWUgcGVyaW9kOiAke3RoaXMuX3NlbGVjdGVkVGltZVJhbmdlU3RyaW5nfWApO1xyXG4gICAgICAgICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgICAgICB0aGlzLl9zaG93TWVzc2FnZShBbGVydC5zdWNjZXNzLCBgUHJvY2Vzc2VkIHRpbWUgcmFuZ2UgaXM6ICR7Z2V0VGltZVJhbmdlU3RyaW5nKHRoaXMudGltZSl9LmApO1xyXG4gICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICByZXR1cm4gc2xlZXAoMTAwKS50aGVuKCgpID0+IHtcclxuICAgICAgICAgICAgICByZXR1cm4gdGhpcy5fYnVpbGRDaGFydChwb3J0LCBwb3J0cyk7XHJcbiAgICAgICAgICAgIH0pO1xyXG4gICAgICAgICAgfSk7XHJcbiAgICAgIH0pO1xyXG4gIH1cclxuXHJcbiAgLyoqXHJcbiAgICogcmVpbml0aWFsaXplIHRoZSBwb3J0IHNlbGVjdG9yIHdpdGggdGhlIHBvcnRzXHJcbiAgICovXHJcbiAgcHJpdmF0ZSBfaW5pdFBvcnRTZWxlY3Rvcihwb3J0czogc3RyaW5nW10gPSBudWxsLCBzZWxlY3RlZFBvcnQ6IHN0cmluZyA9IG51bGwpOiBQcm9taXNlPHZvaWQ+IHtcclxuICAgIHJldHVybiBuZXcgUHJvbWlzZShyZXNvbHZlID0+IHtcclxuICAgICAgLy8gaW5pdGlhbGl6YXRpb24gZm9yIG5neC1zZWxlY3RcclxuICAgICAgaWYgKHBvcnRzICE9IG51bGwgJiYgcG9ydHMubGVuZ3RoID4gMSkge1xyXG4gICAgICAgIC8vIE1EQywgcmVtb3ZlIGRlZmF1bHQgJzAwMDAnIHBvcnRcclxuICAgICAgICB0aGlzLnBvcnRzID0gZ2VuZXJhdGVQb3J0cyhnZXRSZWFsUG9ydHMocG9ydHMpLCBzZWxlY3RlZFBvcnQpO1xyXG4gICAgICB9IGVsc2Uge1xyXG4gICAgICAgIHRoaXMucG9ydHMgPSBnZW5lcmF0ZVBvcnRzKHBvcnRzKTtcclxuICAgICAgfVxyXG5cclxuICAgICAgaWYgKHBvcnRzICE9IG51bGwgJiYgc2VsZWN0ZWRQb3J0ID09PSBudWxsKSB7XHJcbiAgICAgICAgLy8gcmVzZXQgc3RhdHVzIHdoZW4gZG9pbmc6XHJcbiAgICAgICAgLy8gMS4gbG9hZGluZyBwb3J0c1xyXG4gICAgICAgIC8vIDIuIHRoZSBmaWxlIGRvZXNuJ3QgY29udGFpbiB0aGUgc2VsZWN0ZWQgUG9ydFxyXG4gICAgICAgIHRoaXMucmVhZFByb2dyZXNzID0gMDtcclxuICAgICAgICAvLyBoaWRlIHRoZSBwcm9ncmVzcyBiYXIgYW5kIGVuYWJsZSB0aGUgXCJzaG93IGNoYXJ0XCIgYnV0dG9uXHJcbiAgICAgICAgdGhpcy5fdG9nZ2xlSXRlbXMoW1xyXG4gICAgICAgICAge2lkOiBIdG1sRWxlbWVudC5yZWFkRmlsZVByb2dyZXNzLCBzdGF0dXM6IGZhbHNlfSxcclxuICAgICAgICAgIHtpZDogSHRtbEVsZW1lbnQuc2hvd0NoYXJ0QnV0dG9uLCBzdGF0dXM6IHRydWV9XHJcbiAgICAgICAgXSk7XHJcbiAgICAgIH1cclxuICAgICAgcmVzb2x2ZSgpO1xyXG4gICAgfSk7XHJcbiAgfVxyXG5cclxuICAvKipcclxuICAgKiBidWlsZCBhbmQgZGlzcGxheSB0aGUgY2hhcnQgb24gcGFnZVxyXG4gICAqIEBwYXJhbSBwb3J0IHRoZSBzZWxlY3RlZCBwb3J0XHJcbiAgICogQHBhcmFtIHBvcnRzIGFsbCBhdmFpbGFibGUgcG9ydHNcclxuICAgKiBAcGFyYW0gc3dpdGNoRmxhZyBpbmRpY2F0ZXMgd2hldGhlciB0aGlzIGZ1bmN0aW9uIGlzIHRyaWdnZXJlZCBmcm9tIHN3aXRjaGluZyBwb3J0cyAobm8gaW5pdCBwb3J0IHNlbGVjdG9yIG5lZWRlZClcclxuICAgKi9cclxuICBwcml2YXRlIF9idWlsZENoYXJ0KHBvcnQ6IHN0cmluZywgcG9ydHM6IHN0cmluZ1tdLCBzd2l0Y2hGbGFnID0gZmFsc2UpOiBQcm9taXNlPGFueT4ge1xyXG4gICAgY29uc3QgYmVnaW5UaW1lID0gbmV3IERhdGUoKTtcclxuICAgIGlmIChwb3J0KSB7XHJcbiAgICAgIHJldHVybiBQcm9taXNlLnJlc29sdmUodGhpcy5fbG9hZFNldHRpbmdzRm9yU2VsZWN0aW9uc1RhYmxlKHBvcnQpKVxyXG4gICAgICAgIC50aGVuKCAoKSA9PiB7XHJcbiAgICAgICAgICAvLyBnZXQgdGhlIGNvbmZpZ1xyXG4gICAgICAgICAgcmV0dXJuIHRoaXMuY2hhcnRTZXJ2aWNlLmJ1aWxkQ2hhcnQoXHJcbiAgICAgICAgICAgIHRoaXMudGltZVtwb3J0XSxcclxuICAgICAgICAgICAgdGhpcy5kYXRhW3BvcnRdLFxyXG4gICAgICAgICAgICB0aGlzLnVpU2VydmljZS5nZXRZU2NhbGUodGhpcy5faGVhZGVyS2V5LCBwb3J0KSxcclxuICAgICAgICAgICAgdGhpcy5faGVhZGVyVGV4dCxcclxuICAgICAgICAgICAgdGhpcy5faGVhZGVyS2V5LFxyXG4gICAgICAgICAgICB0aGlzLl9zZWxlY3Rpb24sXHJcbiAgICAgICAgICAgIHRoaXMudGFibGVTb3VyY2UsXHJcbiAgICAgICAgICAgIHRoaXMuX2dldEhvc3RUaXRsZShwb3J0KSxcclxuICAgICAgICAgICAgdGhpcy51aVNlcnZpY2UuZ2V0RGlzcGxheUl0ZW1zKHRoaXMuX2hlYWRlcktleSwgcG9ydCwgdGhpcy5kZWZhdWx0U2VsZWN0ZWRJdGVtcyksXHJcbiAgICAgICAgICAgIHRoaXMuX29uWm9vbS5iaW5kKHRoaXMpKVxyXG4gICAgICAgICAgICAudGhlbigoKSA9PiB7XHJcbiAgICAgICAgICAgICAgdGhpcy5yZWFkUHJvZ3Jlc3MgPSAwO1xyXG4gICAgICAgICAgICAgIC8vIGFmdGVyIGNoYXJ0IGhhcyBiZWVuIGNyZWF0ZWQsIHNob3cgdGhlIGNoYXJ0IGFyZWEsIGhpZGUgcHJvZ3Jlc3MgYmFyIGFuZCBlbmFibGUgdGhlIFwic2hvdyBjaGFydFwiIGJ1dHRvblxyXG4gICAgICAgICAgICAgIHRoaXMuX3RvZ2dsZUl0ZW1zKFtcclxuICAgICAgICAgICAgICAgIHtpZDogSHRtbEVsZW1lbnQuY2hhcnRBcmVhLCBzdGF0dXM6IHRydWV9LFxyXG4gICAgICAgICAgICAgICAge2lkOiBIdG1sRWxlbWVudC5yZWFkRmlsZVByb2dyZXNzLCBzdGF0dXM6IGZhbHNlfSxcclxuICAgICAgICAgICAgICAgIHtpZDogSHRtbEVsZW1lbnQuc2hvd0NoYXJ0QnV0dG9uLCBzdGF0dXM6IHRydWV9XHJcbiAgICAgICAgICAgICAgXSk7XHJcbiAgICAgICAgICAgICAgLy8gc2V0IHBvcnQgdG8gY3VycmVudCBkaXNwbGF5aW5nIHBvcnRcclxuICAgICAgICAgICAgICB0aGlzLl9jdXJyZW50Q2hhcnRQb3J0ID0gcG9ydDtcclxuICAgICAgICAgICAgICBwcmludFByb2Nlc3NlZFRpbWUoYmVnaW5UaW1lLCAnc3RlcF9idWlsZF9jaGFydCcpO1xyXG4gICAgICAgICAgICAgIGlmIChwb3J0cyAmJiBwb3J0cy5sZW5ndGggPiAwKSB7XHJcbiAgICAgICAgICAgICAgICBpZiAoIXN3aXRjaEZsYWcpIHtcclxuICAgICAgICAgICAgICAgICAgLy8gaW5pdGlhbGl6ZSBwb3J0IHNlbGVjdG9yLiBEbyBub3QgbmVlZCB0byBkbyBpdCB3aGVuIHN3aXRjaGluZyBwb3J0LlxyXG4gICAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5faW5pdFBvcnRTZWxlY3Rvcihwb3J0cywgcG9ydCk7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB9KTtcclxuICAgICAgICB9KTtcclxuICAgIH0gZWxzZSB7XHJcbiAgICAgIGlmIChwb3J0cy5sZW5ndGggPiAwKSB7XHJcbiAgICAgICAgdGhpcy5fc2hvd01lc3NhZ2UoXHJcbiAgICAgICAgICBBbGVydC53YXJuaW5nLFxyXG4gICAgICAgICAgJ1RoZSBzZWxlY3RlZCBwb3J0IGRvZXMgbm90IGV4aXN0IGluIHRoZSBuYW1lIHNlcnZlciBoaXN0b3J5IGZpbGUuIFBsZWFzZSBjaG9vc2UgYSBjb3JyZWN0IHBvcnQgYW5kIGhhdmUgYSB0cnkgYWdhaW4uJyk7XHJcbiAgICAgICAgaWYgKCFzd2l0Y2hGbGFnKSB7XHJcbiAgICAgICAgICAvLyBpbml0aWFsaXplIHBvcnQgc2VsZWN0b3IuIERvIG5vdCBuZWVkIHRvIGRvIGl0IHdoZW4gc3dpdGNoaW5nIHBvcnQuXHJcbiAgICAgICAgICByZXR1cm4gdGhpcy5faW5pdFBvcnRTZWxlY3Rvcihwb3J0cywgcG9ydCk7XHJcbiAgICAgICAgfVxyXG4gICAgICB9XHJcbiAgICB9XHJcbiAgfVxyXG5cclxuICAvKipcclxuICAgKiBnZXQgdGhlIHN0cmluZyB0aGF0IHdpbGwgYmUgZGlzcGxheWVkIG9uIHRoZSB0aXRsZSBhcmVhIG9mIHRoZSBjaGFydFxyXG4gICAqIGVnOiBob3N0MSAtIDMwMDQwICgyMDE4LTA5LTA1IDE1OjMyOjMyIH4gMjAxOC0wOS0wNyAxNTozMjoxNSlcclxuICAgKiBAcGFyYW0gcG9ydCBzZWxlY3RlZCBwb3J0XHJcbiAgICovXHJcbiAgcHJpdmF0ZSBfZ2V0SG9zdFRpdGxlKHBvcnQ6IHN0cmluZyk6IHN0cmluZyB7XHJcbiAgICBpZiAodGhpcy5ob3N0KSB7XHJcbiAgICAgIHJldHVybiAgYCR7dGhpcy5ob3N0fSAtICR7cG9ydH0gKCAke2dldFRpbWVSYW5nZVN0cmluZyh0aGlzLnRpbWVbcG9ydF0pfSApYDtcclxuICAgIH1cclxuICB9XHJcblxyXG4gIC8qKlxyXG4gICAqIGFmdGVyIHpvb20sIGVuYWJsZSB0aGUgcmVzZXQgYnV0dG9uLlxyXG4gICAqL1xyXG4gIHByaXZhdGUgX29uWm9vbSgpOiB2b2lkIHtcclxuICAgIHRoaXMuX3RvZ2dsZUl0ZW1zKFt7aWQ6IEh0bWxFbGVtZW50LnJlc2V0Q2hhcnRCdXR0b24sIHN0YXR1czogdHJ1ZX1dKTtcclxuICB9XHJcblxyXG4gIC8qKlxyXG4gICAqIGluaXRpYWxpemUgY2hhcnQsIGluY2x1ZGluZzogZGVzdHJveSBjdXJyZW50IGNoYXJ0LCBpbml0aWFsaXplIGNvbmZpZywgaW5pdGlhbGl6ZSBhbGwgcmVsYXRpdmUgZGF0YVxyXG4gICAqL1xyXG4gIHByaXZhdGUgX2luaXRDaGFydEVudihzd2l0Y2hGbGFnOiBib29sZWFuID0gZmFsc2UpOiBQcm9taXNlPGFueT4ge1xyXG4gICAgcmV0dXJuIHRoaXMuY2hhcnRTZXJ2aWNlLmRlc3Ryb3lDaGFydCgpLnRoZW4oKCkgPT4ge1xyXG4gICAgICB7XHJcbiAgICAgICAgLy8gY2xlYW51cCBvdGhlciBkYXRhXHJcbiAgICAgICAgdGhpcy5fdG9nZ2xlSXRlbXMoW3tpZDogSHRtbEVsZW1lbnQuY2hhcnRBcmVhLCBzdGF0dXM6IGZhbHNlfV0pO1xyXG5cclxuICAgICAgICBpZiAoIXN3aXRjaEZsYWcpIHtcclxuICAgICAgICAgIE9iamVjdC5rZXlzKHRoaXMudGltZSkuZm9yRWFjaChrZXkgPT4ge1xyXG4gICAgICAgICAgICBpZiAodGhpcy50aW1lW2tleV0pIHtcclxuICAgICAgICAgICAgICB0aGlzLnRpbWVba2V5XS5sZW5ndGggPSAwO1xyXG4gICAgICAgICAgICB9fSk7XHJcbiAgICAgICAgICB0aGlzLnRpbWUgPSB7fTtcclxuICAgICAgICAgIE9iamVjdC5rZXlzKHRoaXMuZGF0YSkuZm9yRWFjaChrZXkgPT4ge1xyXG4gICAgICAgICAgICBpZiAodGhpcy5kYXRhW2tleV0pIHtcclxuICAgICAgICAgICAgICB0aGlzLmRhdGFba2V5XS5sZW5ndGggPSAwO1xyXG4gICAgICAgICAgICB9fSk7XHJcbiAgICAgICAgICB0aGlzLmRhdGEgPSB7fTtcclxuICAgICAgICAgIHRoaXMuaGVhZGVyLmxlbmd0aCA9IDA7XHJcbiAgICAgICAgICB0aGlzLmhvc3QgPSAnbmFtZXNlcnZlciBoaXN0b3J5IGZpbGUnO1xyXG4gICAgICAgICAgdGhpcy50YWJsZVNvdXJjZSA9IHZvaWQgMDtcclxuICAgICAgICAgIHRoaXMucmVhZFByb2dyZXNzID0gMDtcclxuICAgICAgICAgIHRoaXMudWlTZXJ2aWNlLmNsZWFyTG9hZEhpc3RvcnlJbmZvcygpO1xyXG4gICAgICAgIH1cclxuICAgICAgfVxyXG4gICAgfSk7XHJcbiAgfVxyXG5cclxuICAvKipcclxuICAgKiBMb2FkIHNldHRpbmdzIGZvciB0aGUgc2VsZWN0aW9uIHRhYmxlICh0aGUgcmlnaHQgcGFydCBvZiB0aGUgY2hhcnQpXHJcbiAgICogQHBhcmFtIHBvcnQgdGhlIHNlbGVjdGVkIHBvcnRcclxuICAgKi9cclxuICBwcml2YXRlIF9sb2FkU2V0dGluZ3NGb3JTZWxlY3Rpb25zVGFibGUocG9ydDogc3RyaW5nKTogdm9pZCB7XHJcbiAgICB0aGlzLnRhYmxlU291cmNlID0gdGhpcy51aVNlcnZpY2UuZ2V0U2VsZWN0aW9uVGFibGVSb3dzKHRoaXMuX2hlYWRlcktleSwgcG9ydCwgdGhpcy5kZWZhdWx0U2VsZWN0ZWRJdGVtcyk7XHJcbiAgICB0aGlzLl9zZWxlY3Rpb24gPSBuZXcgU2VsZWN0aW9uTW9kZWwodHJ1ZSwgW10pO1xyXG4gICAgdGhpcy50YWJsZVNvdXJjZS5mb3JFYWNoKHJvdyA9PiB7XHJcbiAgICAgIGlmICh0aGlzLnVpU2VydmljZS5nZXREaXNwbGF5SXRlbXModGhpcy5faGVhZGVyS2V5LCBwb3J0LCB0aGlzLmRlZmF1bHRTZWxlY3RlZEl0ZW1zKS5pbmNsdWRlcyhyb3cuS1BJKSkge1xyXG4gICAgICAgIHRoaXMuX3NlbGVjdGlvbi5zZWxlY3Qocm93KTtcclxuICAgICAgfVxyXG4gICAgfSk7XHJcbiAgfVxyXG5cclxuICAvKipcclxuICAgKiBTaG93IG1lc3NhZ2VzXHJcbiAgICogQHBhcmFtIHR5cGUgdHlwZSBvZiB0aGUgbWVzc2FnZVxyXG4gICAqIEBwYXJhbSBtZXNzYWdlIG1lc3NhZ2UgdGV4dFxyXG4gICAqL1xyXG4gIHByaXZhdGUgX3Nob3dNZXNzYWdlKHR5cGU6IEFsZXJ0LCBtZXNzYWdlOiBzdHJpbmcpOiB2b2lkIHtcclxuICAgIGlmICh0eXBlKSB7XHJcbiAgICAgIHN3aXRjaCAodHlwZSkge1xyXG4gICAgICAgIGNhc2UgQWxlcnQuc3VjY2VzczpcclxuICAgICAgICBjYXNlIEFsZXJ0LmluZm86XHJcbiAgICAgICAgICBicmVhaztcclxuICAgICAgICBjYXNlIEFsZXJ0Lndhcm5pbmc6XHJcbiAgICAgICAgICBjb25zb2xlLndhcm4obWVzc2FnZSk7XHJcbiAgICAgICAgICBicmVhaztcclxuICAgICAgICBjYXNlIEFsZXJ0LmVycm9yOlxyXG4gICAgICAgICAgY29uc29sZS5lcnJvcihtZXNzYWdlKTtcclxuICAgICAgfVxyXG4gICAgfVxyXG4gICAgaWYgKHRoaXMuYWxlcnRNZXNzYWdlID09PSBtZXNzYWdlKSB7XHJcbiAgICAgIC8vIHRyeSB0cmlnZ2VyIHRoZSBjaGFuZ2UgZXZlbnQgb2YgdGhlIGFsZXJ0LlxyXG4gICAgICB0aGlzLmFsZXJ0TWVzc2FnZSA9IHZvaWQgMDtcclxuICAgICAgc2V0VGltZW91dCgoKSA9PiB0aGlzLmFsZXJ0TWVzc2FnZSA9IG1lc3NhZ2UsIDEwMCk7XHJcbiAgICB9IGVsc2Uge1xyXG4gICAgICB0aGlzLmFsZXJ0TWVzc2FnZSA9IG1lc3NhZ2U7XHJcbiAgICB9XHJcbiAgICB0aGlzLmFsZXJ0VHlwZSA9IHR5cGU7XHJcbiAgfVxyXG5cclxuICAvKipcclxuICAgKiB0b2dnbGUgaXRlbXMgd2l0aCB0aGUgcHJvdmlkZWQgc3RhdHVzIChzaG93IG9yIGhpZGUgdGhlIHJlbGF0aXZlIGVsZW1lbnQgb24gdGhlIHBhZ2UpXHJcbiAgICogQHBhcmFtIGl0ZW1zIGl0ZW1zIHdpdGggdGhlIHJlbGF0aXZlIGlkIGFuZCBzdGF0dXMuXHJcbiAgICovXHJcbiAgcHJpdmF0ZSBfdG9nZ2xlSXRlbXMoaXRlbXM6IHtpZDogSHRtbEVsZW1lbnQsIHN0YXR1czogYm9vbGVhbn1bXSkge1xyXG4gICAgY29uc3QgZ2V0VmFyaWFibGVOYW1lQnlUeXBlSWQgPSAoaWQ6IEh0bWxFbGVtZW50KSA9PiB7XHJcbiAgICAgIHN3aXRjaCAoaWQpIHtcclxuICAgICAgICBjYXNlIEh0bWxFbGVtZW50LmNoYXJ0QXJlYTogcmV0dXJuICdzaG93Q2hhcnRGbGFnJztcclxuICAgICAgICBjYXNlIEh0bWxFbGVtZW50LnJlYWRGaWxlUHJvZ3Jlc3M6IHJldHVybiAnc2hvd1JlYWRGaWxlUHJvZ3Jlc3MnO1xyXG4gICAgICAgIGNhc2UgSHRtbEVsZW1lbnQuc2hvd0NoYXJ0QnV0dG9uOiByZXR1cm4gJ2VuYWJsZVNob3dDaGFydEJ1dHRvbic7XHJcbiAgICAgICAgY2FzZSBIdG1sRWxlbWVudC5sb2FkUG9ydHNCdXR0b246IHJldHVybiAnZW5hYmxlTG9hZFBvcnRzQnV0dG9uJztcclxuICAgICAgICBjYXNlIEh0bWxFbGVtZW50LnJlc2V0Q2hhcnRCdXR0b246IHJldHVybiAnZW5hYmxlUmVzZXRDaGFydEJ1dHRvbic7XHJcbiAgICAgIH1cclxuICAgIH07XHJcbiAgICBpZiAoaXRlbXMpIHtcclxuICAgICAgaXRlbXMuZm9yRWFjaChpdGVtID0+IHtcclxuICAgICAgICB0aGlzW2dldFZhcmlhYmxlTmFtZUJ5VHlwZUlkKGl0ZW0uaWQpXSA9IGl0ZW0uc3RhdHVzO1xyXG4gICAgICB9KTtcclxuICAgIH1cclxuICB9XHJcbn1cclxuIiwiPGRpdiAjbmFtZXNlcnZlckhpc3RvcnlBbGwgY2xhc3M9XCJuYW1lc2VydmVyLWhpc3RvcnktYWxsXCIgKHdpbmRvdzpyZXNpemUpPVwib25SZXNpemUoKVwiPlxyXG4gIDxkaXYgY2xhc3M9XCJ0b29sYmFyLWNoYXJ0XCI+XHJcbiAgICA8ZGl2IGNsYXNzPVwidXBsb2FkLWJveC1jb250ZW50XCI+XHJcbiAgICAgIDxkaXYgKm5nSWY9XCIhc2hvd1JlYWRGaWxlUHJvZ3Jlc3NcIj5cclxuICAgICAgICA8ZmlsZS1kcm9wLWlucHV0IChmaWxlRHJvcCk9XCJmaWxlRHJvcHBlZCgkZXZlbnQpXCIgKGZpbGVJbnB1dCk9XCJmaWxlU2VsZWN0ZWQoJGV2ZW50KVwiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICBbZHJvcEFyZWFUZXh0XT0gXCJhYmJyZXZpYXRlZEZpbGVOYW1lXCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgIFtpbnB1dEFyZWFUZXh0XT1cIidCcm93c2UnXCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgIFt0aXRsZV09XCJmaWxlPy5uYW1lPyBmaWxlLm5hbWU6J1NlbGVjdCBhIG5hbWUgc2VydmVyIGhpc3RvcnkgZmlsZSBmcm9tIHlvdXIgbG9jYWwgZGlzay4nXCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgICpuZ0lmPVwiIWZpbGVCdWZmZXJcIj5cclxuICAgICAgICA8L2ZpbGUtZHJvcC1pbnB1dD5cclxuICAgICAgICA8cCAqbmdJZj1cImZpbGVCdWZmZXJcIj57e3N0cmVhbU1vZGVGaWxlTmFtZSB8fCAnbmFtZXNlcnZlcl9oaXN0b3J5LnRyYyAoc3RyZWFtIG1vZGUpJ319PC9wPlxyXG4gICAgICA8L2Rpdj5cclxuICAgICAgPGRpdiAqbmdJZj1cInNob3dSZWFkRmlsZVByb2dyZXNzXCI+XHJcbiAgICAgICAgPHByb2dyZXNzLWJhciBbcHJvZ3Jlc3NdPVwicmVhZFByb2dyZXNzXCI+PC9wcm9ncmVzcy1iYXI+XHJcbiAgICAgIDwvZGl2PlxyXG4gICAgPC9kaXY+XHJcbiAgICA8ZGl2IGNsYXNzPVwiaW5wdXQtdGltZVwiPlxyXG4gICAgIDxkaXYgY2xhc3M9XCJpbnB1dC10aW1lLXJhbmdlXCI+XHJcbiAgICAgICA8dGltZS1yYW5nZS1zZWxlY3RvciBbZGlzYWJsZWRdPVwic2hvd1JlYWRGaWxlUHJvZ3Jlc3NcIiBbKGRhdGVUaW1lUmFuZ2UpXT1cImRhdGVUaW1lUmFuZ2VcIj48L3RpbWUtcmFuZ2Utc2VsZWN0b3I+XHJcbiAgICAgPC9kaXY+XHJcbiAgICAgIDxkaXYgY2xhc3M9XCJ0aW1lem9uZS1zZWxlY3RvclwiPlxyXG4gICAgICAgIDx0aW1lem9uZS1zZWxlY3RvciBbKHRpbWV6b25lKV09XCJ0aW1lem9uZVwiIFtkaXNhYmxlZF09XCJzaG93UmVhZEZpbGVQcm9ncmVzc1wiPjwvdGltZXpvbmUtc2VsZWN0b3I+XHJcbiAgICAgIDwvZGl2PlxyXG4gICAgPC9kaXY+XHJcblxyXG4gICAgPGRpdiBjbGFzcz1cInBvcnQtc2VsZWN0aW9uXCI+XHJcbiAgICAgIDxkaXYgY2xhc3M9XCJwb3J0LXNlbGVjdG9yXCI+XHJcbiAgICAgICAgPHBvcnQtc2VsZWN0b3IgKHBvcnRDaGFuZ2UpPVwic3dpdGNoUG9ydEZvckNoYXJ0KCRldmVudClcIiBbKHBvcnQpXT1cInBvcnRcIiBbcG9ydHNdPVwicG9ydHNcIiBbZGlzYWJsZWRdPVwic2hvd1JlYWRGaWxlUHJvZ3Jlc3NcIj48L3BvcnQtc2VsZWN0b3I+XHJcbiAgICAgIDwvZGl2PlxyXG4gICAgICA8ZGl2IGNsYXNzPVwicG9ydC1sb2FkLWJ1dHRvblwiPlxyXG4gICAgICAgIDxidXR0b24gKGNsaWNrKT1cImxvYWRQb3J0cygpXCIgdGl0bGU9XCJMb2FkIGFsbCBwb3J0cyBmcm9tIG5hbWUgc2VydmVyIGhpc3RvcnkgdHJhY2UgZmlsZS5cIiBbZGlzYWJsZWRdPVwiIWVuYWJsZVNob3dDaGFydEJ1dHRvbiB8fCBwb3J0IHx8ICFlbmFibGVMb2FkUG9ydHNCdXR0b25cIj57e3Nob3dSZWFkRmlsZVByb2dyZXNzPyBcIkxvYWRpbmcuLi5cIiA6IFwiTG9hZFwifX08L2J1dHRvbj5cclxuICAgICAgPC9kaXY+XHJcbiAgICA8L2Rpdj5cclxuXHJcbiAgICA8ZGl2IGNsYXNzPVwiY2hhcnQtb3BlcmF0aW9uXCI+XHJcbiAgICAgIDxkaXYgY2xhc3M9XCJsZWZ0XCI+XHJcbiAgICAgICAgPGJ1dHRvbiAoY2xpY2spPVwic2hvd0NoYXJ0KClcIiB0aXRsZT1cIkxvYWQgYW5kIGRpc3BsYXkgYWxsIGRhdGEgZnJvbSBuYW1lIHNlcnZlciBoaXN0b3J5IHRyYWNlIGZpbGUuXCIgW2Rpc2FibGVkXT1cIiFlbmFibGVTaG93Q2hhcnRCdXR0b25cIj57e3Nob3dSZWFkRmlsZVByb2dyZXNzPyBcIkxvYWRpbmcuLi5cIiA6IFwiU2hvd1wifX08L2J1dHRvbj5cclxuICAgICAgPC9kaXY+XHJcbiAgICAgIDxkaXYgY2xhc3M9XCJyaWdodFwiPlxyXG4gICAgICAgIDxidXR0b24gKGNsaWNrKT1cInJlc2V0Q2hhcnQoKVwiIHRpdGxlPVwiUmVzZXQgem9vbSBvZiBjaGFydC5cIiBbZGlzYWJsZWRdPVwic2hvd1JlYWRGaWxlUHJvZ3Jlc3MgfHwgIWVuYWJsZVJlc2V0Q2hhcnRCdXR0b25cIj5SZXNldCBDaGFydDwvYnV0dG9uPlxyXG4gICAgICA8L2Rpdj5cclxuICAgIDwvZGl2PlxyXG4gIDwvZGl2PlxyXG4gIDxkaXYgI25hbWVzZXJ2ZXJIaXN0b3J5Q29udGVudCBjbGFzcz1cIm5hbWVzZXJ2ZXItaGlzdG9yeS1jb250ZW50XCI+XHJcbiAgICA8ZGl2IGNsYXNzPVwibmFtZXNlcnZlci1oaXN0b3J5LWNvbnRlbnQtY2hhcnRcIj5cclxuICAgICAgPGluc3RydWN0aW9uIFsoc2hvdyldPVwic2hvd0luc3RydWN0aW9uXCIgKm5nSWY9XCIhc2hvd0NoYXJ0RmxhZyAmJiBzaG93SW5zdHJ1Y3Rpb25cIlxyXG4gICAgICAgICAgICAgICAgICAgW3N0ZXAxRmluaXNoZWRdPVwiISFmaWxlXCJcclxuICAgICAgICAgICAgICAgICAgIFtzdGVwMkZpbmlzaGVkXT1cImRhdGVUaW1lUmFuZ2UgJiYgKCEhZGF0ZVRpbWVSYW5nZVswXSB8fCAhIWRhdGVUaW1lUmFuZ2VbMV0pIHx8IHRpbWV6b25lICE9IGRlZmF1bHRUaW1lem9uZVwiXHJcbiAgICAgICAgICAgICAgICAgICBbc3RlcDNGaW5pc2hlZF09XCIhIXBvcnRcIlxyXG4gICAgICAgICAgICAgICAgICAgW3N0ZXA0RmluaXNoZWRdPVwic3RlcFNob3dDaGFydCAmJiAhZW5hYmxlU2hvd0NoYXJ0QnV0dG9uXCJcclxuICAgICAgICAgICAgICAgICAgIFtzdGVwNUZpbmlzaGVkXT1cImZhbHNlXCI+XHJcbiAgICAgIDwvaW5zdHJ1Y3Rpb24+XHJcbiAgICAgIDxjYW52YXMgaWQ9XCJjaGFydE5hbWVTZXJ2ZXJIaXN0b3J5XCIgPjwvY2FudmFzPlxyXG4gICAgPC9kaXY+XHJcbiAgICA8ZGl2IGNsYXNzPVwibmFtZXNlcnZlci1oaXN0b3J5LWNvbnRlbnQtY29udHJvbGxlclwiID5cclxuICAgICAgPG5neC1zZWxlY3Rpb24tdGFibGUgKGNoYW5nZSk9XCJzZWxlY3RJdGVtKCRldmVudClcIiAqbmdJZj1cInNob3dDaGFydEZsYWdcIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICBbZmlsdGVyXT1cInRydWVcIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICBbY2hlY2tib3hdPVwidHJ1ZVwiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgIFt0YWJsZVNvdXJjZV09XCJ0YWJsZVNvdXJjZVwiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgIFtrZXlDb2x1bW5dPVwia3BpQ29sdW1uXCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgW2hpZGRlbkNvbHVtbnNdPVwiaGlkZGVuQ29sdW1uc1wiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgIFt0b29sdGlwQ29sdW1uXT1cImRlc2NDb2x1bW5cIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICBbc2VhcmNoU3R5bGVdPVwic2VhcmNoVHlwZVwiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgIFtzZWFyY2hDb2x1bW5dPVwia3BpQ29sdW1uXCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgW211bHRpU2VsZWN0aW9uXT1cInRydWVcIj5cclxuICAgICAgPC9uZ3gtc2VsZWN0aW9uLXRhYmxlPlxyXG4gICAgPC9kaXY+XHJcbiAgPC9kaXY+XHJcbjwvZGl2PlxyXG48ZGl2IGNsYXNzPVwibWVzc2FnZS1jb250YWluZXJcIiAqbmdJZj1cImFsZXJ0TWVzc2FnZVwiPlxyXG4gIDxhbGVydCBbKGFsZXJ0TWVzc2FnZSldPVwiYWxlcnRNZXNzYWdlXCIgW2FsZXJ0VHlwZV09XCJhbGVydFR5cGVcIiBbYWxlcnRUaW1lb3V0XT1cIjMwMDAwXCI+PC9hbGVydD5cclxuPC9kaXY+XHJcbiJdfQ==