@rocketshow/designer 1.32.0 → 1.35.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (362) hide show
  1. package/assets/i18n/de.json +2 -1
  2. package/assets/i18n/en.json +2 -1
  3. package/esm2022/lib/array-sort-pipe.mjs +30 -0
  4. package/esm2022/lib/designer.component.mjs +672 -0
  5. package/esm2022/lib/designer.module.mjs +186 -0
  6. package/esm2022/lib/designer.service.mjs +14 -0
  7. package/esm2022/lib/dropzone/dropzone.component.mjs +93 -0
  8. package/esm2022/lib/effect/effect-curve/effect-curve.component.mjs +577 -0
  9. package/esm2022/lib/effect/effect-pan-tilt/effect-pan-tilt.component.mjs +36 -0
  10. package/esm2022/lib/effect/effect.component.mjs +174 -0
  11. package/esm2022/lib/error-dialog/error-dialog.component.mjs +75 -0
  12. package/esm2022/lib/fixture/fixture-capability/fixture-capability-channel/fixture-capability-channel.component.mjs +222 -0
  13. package/esm2022/lib/fixture/fixture-capability/fixture-capability-color/fixture-capability-color.component.mjs +147 -0
  14. package/esm2022/lib/fixture/fixture-capability/fixture-capability-color-wheel/fixture-capability-color-wheel.component.mjs +213 -0
  15. package/esm2022/lib/fixture/fixture-capability/fixture-capability-dimmer/fixture-capability-dimmer.component.mjs +78 -0
  16. package/esm2022/lib/fixture/fixture-capability/fixture-capability-pan-tilt/fixture-capability-pan-tilt.component.mjs +119 -0
  17. package/esm2022/lib/fixture/fixture-capability/fixture-capability.component.mjs +169 -0
  18. package/esm2022/lib/fixture/fixture-channel/fixture-channel.component.mjs +162 -0
  19. package/esm2022/lib/fixture/fixture-settings/fixture-settings-position/fixture-settings-position.component.mjs +365 -0
  20. package/esm2022/lib/fixture/fixture-settings/fixture-settings-stage/fixture-settings-stage.component.mjs +151 -0
  21. package/esm2022/lib/fixture/fixture-settings/fixture-settings.component.mjs +46 -0
  22. package/esm2022/lib/fixture/fixture.component.mjs +148 -0
  23. package/esm2022/lib/fixture-pool/fixture-pool-create-from-file/fixture-pool-create-from-file.component.mjs +145 -0
  24. package/esm2022/lib/fixture-pool/fixture-pool.component.mjs +643 -0
  25. package/esm2022/lib/intro/intro.component.mjs +95 -0
  26. package/esm2022/lib/master-dimmer/master-dimmer.component.mjs +66 -0
  27. package/esm2022/lib/models/cached-fixture-capability.mjs +9 -0
  28. package/esm2022/lib/models/cached-fixture-channel.mjs +7 -0
  29. package/esm2022/lib/models/cached-fixture.mjs +6 -0
  30. package/esm2022/lib/models/color.mjs +8 -0
  31. package/esm2022/lib/models/composition.mjs +46 -0
  32. package/esm2022/lib/models/effect-curve-profile-channel.mjs +15 -0
  33. package/esm2022/lib/models/effect-curve.mjs +69 -0
  34. package/esm2022/lib/models/effect-pan-tilt.mjs +19 -0
  35. package/esm2022/lib/models/effect.mjs +12 -0
  36. package/esm2022/lib/models/fixture-capability-value.mjs +15 -0
  37. package/esm2022/lib/models/fixture-capability.mjs +84 -0
  38. package/esm2022/lib/models/fixture-channel-value.mjs +11 -0
  39. package/esm2022/lib/models/fixture-channel.mjs +24 -0
  40. package/esm2022/lib/models/fixture-matrix-pixel-group-constraints.mjs +27 -0
  41. package/esm2022/lib/models/fixture-matrix-pixel-group.mjs +12 -0
  42. package/esm2022/lib/models/fixture-matrix.mjs +25 -0
  43. package/esm2022/lib/models/fixture-mode-channel.mjs +26 -0
  44. package/esm2022/lib/models/fixture-mode.mjs +17 -0
  45. package/esm2022/lib/models/fixture-physical.mjs +14 -0
  46. package/esm2022/lib/models/fixture-profile.mjs +85 -0
  47. package/esm2022/lib/models/fixture-wheel-slot.mjs +26 -0
  48. package/esm2022/lib/models/fixture-wheel.mjs +15 -0
  49. package/esm2022/lib/models/fixture.mjs +40 -0
  50. package/esm2022/lib/models/preset-fixture.mjs +10 -0
  51. package/esm2022/lib/models/preset-region-scene.mjs +8 -0
  52. package/esm2022/lib/models/preset.mjs +65 -0
  53. package/esm2022/lib/models/project.mjs +78 -0
  54. package/esm2022/lib/models/scene-playback-region.mjs +11 -0
  55. package/esm2022/lib/models/scene.mjs +27 -0
  56. package/esm2022/lib/preset/preset-settings/preset-settings.component.mjs +194 -0
  57. package/esm2022/lib/preset/preset.component.mjs +131 -0
  58. package/esm2022/lib/preview/models/color-changer-3d.mjs +64 -0
  59. package/esm2022/lib/preview/models/fixture-3d.mjs +274 -0
  60. package/esm2022/lib/preview/models/moving-head-3d.mjs +124 -0
  61. package/esm2022/lib/preview/preview.component.mjs +219 -0
  62. package/esm2022/lib/project/project-browser/project-browser.component.mjs +143 -0
  63. package/esm2022/lib/project/project-import/project-import.component.mjs +107 -0
  64. package/esm2022/lib/project/project-save/project-save.component.mjs +178 -0
  65. package/esm2022/lib/project/project-share/project-share.component.mjs +71 -0
  66. package/esm2022/lib/scene/scene-settings/scene-settings.component.mjs +146 -0
  67. package/esm2022/lib/scene/scene.component.mjs +110 -0
  68. package/esm2022/lib/services/animation.service.mjs +16 -0
  69. package/esm2022/lib/services/config.service.mjs +28 -0
  70. package/esm2022/lib/services/effect.service.mjs +14 -0
  71. package/esm2022/lib/services/error-dialog.service.mjs +39 -0
  72. package/esm2022/lib/services/fixture-pool.service.mjs +30 -0
  73. package/esm2022/lib/services/fixture.service.mjs +639 -0
  74. package/esm2022/lib/services/hotkey-target-exclude.service.mjs +24 -0
  75. package/esm2022/lib/services/intro.service.mjs +140 -0
  76. package/esm2022/lib/services/preset.service.mjs +449 -0
  77. package/esm2022/lib/services/preview-mesh.service.mjs +57 -0
  78. package/esm2022/lib/services/preview.service.mjs +497 -0
  79. package/esm2022/lib/services/project-load.service.mjs +209 -0
  80. package/esm2022/lib/services/project.service.mjs +93 -0
  81. package/esm2022/lib/services/scene.service.mjs +164 -0
  82. package/esm2022/lib/services/timeline.service.mjs +726 -0
  83. package/esm2022/lib/services/user-ensure-login.service.mjs +38 -0
  84. package/esm2022/lib/services/user.service.mjs +89 -0
  85. package/esm2022/lib/services/uuid.service.mjs +23 -0
  86. package/esm2022/lib/services/warning-dialog.service.mjs +38 -0
  87. package/esm2022/lib/timeline/composition-settings/composition-settings.component.mjs +304 -0
  88. package/esm2022/lib/timeline/timeline-grid/timeline-grid.component.mjs +216 -0
  89. package/esm2022/lib/timeline/timeline.component.mjs +418 -0
  90. package/esm2022/lib/user/user-login/user-login.component.mjs +144 -0
  91. package/esm2022/lib/user/user-register/user-register.component.mjs +220 -0
  92. package/esm2022/lib/wait-dialog/wait-dialog.component.mjs +26 -0
  93. package/esm2022/lib/warning-dialog/warning-dialog.component.mjs +68 -0
  94. package/esm2022/public_api.mjs +7 -0
  95. package/esm2022/rocketshow-designer.mjs +5 -0
  96. package/fesm2022/rocketshow-designer.mjs +11171 -0
  97. package/fesm2022/rocketshow-designer.mjs.map +1 -0
  98. package/index.d.ts +5 -0
  99. package/lib/array-sort-pipe.d.ts +3 -0
  100. package/lib/designer.component.d.ts +19 -16
  101. package/lib/designer.module.d.ts +55 -0
  102. package/lib/designer.service.d.ts +3 -0
  103. package/lib/dropzone/dropzone.component.d.ts +24 -0
  104. package/lib/effect/effect-curve/effect-curve.component.d.ts +4 -1
  105. package/lib/effect/effect-pan-tilt/effect-pan-tilt.component.d.ts +3 -0
  106. package/lib/effect/effect.component.d.ts +3 -0
  107. package/lib/error-dialog/error-dialog.component.d.ts +3 -0
  108. package/lib/fixture/fixture-capability/fixture-capability-channel/fixture-capability-channel.component.d.ts +4 -1
  109. package/lib/fixture/fixture-capability/fixture-capability-color/fixture-capability-color.component.d.ts +3 -0
  110. package/lib/fixture/fixture-capability/fixture-capability-color-wheel/fixture-capability-color-wheel.component.d.ts +5 -2
  111. package/lib/fixture/fixture-capability/fixture-capability-dimmer/fixture-capability-dimmer.component.d.ts +3 -0
  112. package/lib/fixture/fixture-capability/fixture-capability-pan-tilt/fixture-capability-pan-tilt.component.d.ts +3 -0
  113. package/lib/fixture/fixture-capability/fixture-capability.component.d.ts +3 -0
  114. package/lib/fixture/fixture-channel/fixture-channel.component.d.ts +3 -0
  115. package/lib/fixture/fixture-settings/fixture-settings-position/fixture-settings-position.component.d.ts +3 -0
  116. package/lib/fixture/fixture-settings/fixture-settings-stage/fixture-settings-stage.component.d.ts +3 -0
  117. package/lib/fixture/fixture-settings/fixture-settings.component.d.ts +3 -0
  118. package/lib/fixture/fixture.component.d.ts +7 -3
  119. package/lib/fixture-pool/fixture-pool-create-from-file/fixture-pool-create-from-file.component.d.ts +3 -0
  120. package/lib/fixture-pool/fixture-pool.component.d.ts +3 -0
  121. package/lib/intro/intro.component.d.ts +3 -0
  122. package/lib/master-dimmer/master-dimmer.component.d.ts +3 -0
  123. package/lib/models/cached-fixture.d.ts +1 -0
  124. package/lib/models/fixture-matrix-pixel-group-constraints.d.ts +8 -0
  125. package/lib/models/fixture-matrix-pixel-group.d.ts +6 -0
  126. package/lib/models/fixture-matrix.d.ts +6 -0
  127. package/lib/models/fixture-mode-channel.d.ts +8 -0
  128. package/lib/models/fixture-mode.d.ts +3 -1
  129. package/lib/models/fixture-physical.d.ts +4 -0
  130. package/lib/models/fixture-profile.d.ts +5 -0
  131. package/lib/models/preset-fixture.d.ts +5 -0
  132. package/lib/models/preset.d.ts +2 -0
  133. package/lib/models/project.d.ts +3 -0
  134. package/lib/preset/preset-settings/preset-settings.component.d.ts +3 -0
  135. package/lib/preset/preset.component.d.ts +3 -0
  136. package/lib/preview/models/color-changer-3d.d.ts +1 -11
  137. package/lib/preview/models/fixture-3d.d.ts +11 -0
  138. package/lib/preview/models/moving-head-3d.d.ts +1 -11
  139. package/lib/preview/preview.component.d.ts +4 -4
  140. package/lib/project/project-browser/project-browser.component.d.ts +3 -0
  141. package/lib/project/project-import/project-import.component.d.ts +3 -0
  142. package/lib/project/project-save/project-save.component.d.ts +3 -0
  143. package/lib/project/project-share/project-share.component.d.ts +3 -0
  144. package/lib/scene/scene-settings/scene-settings.component.d.ts +3 -0
  145. package/lib/scene/scene.component.d.ts +3 -0
  146. package/lib/services/animation.service.d.ts +3 -0
  147. package/lib/services/config.service.d.ts +4 -0
  148. package/lib/services/effect.service.d.ts +3 -0
  149. package/lib/services/error-dialog.service.d.ts +3 -0
  150. package/lib/services/fixture-pool.service.d.ts +3 -0
  151. package/lib/services/fixture.service.d.ts +10 -2
  152. package/lib/services/hotkey-target-exclude.service.d.ts +3 -0
  153. package/lib/services/intro.service.d.ts +3 -0
  154. package/lib/services/preset.service.d.ts +7 -2
  155. package/lib/services/preview-mesh.service.d.ts +3 -0
  156. package/lib/services/preview.service.d.ts +6 -4
  157. package/lib/services/project-load.service.d.ts +8 -1
  158. package/lib/services/project.service.d.ts +5 -3
  159. package/lib/services/scene.service.d.ts +3 -0
  160. package/lib/services/timeline.service.d.ts +3 -0
  161. package/lib/services/user-ensure-login.service.d.ts +3 -0
  162. package/lib/services/user.service.d.ts +3 -0
  163. package/lib/services/uuid.service.d.ts +3 -0
  164. package/lib/services/warning-dialog.service.d.ts +3 -0
  165. package/lib/timeline/composition-settings/composition-settings.component.d.ts +5 -1
  166. package/lib/timeline/timeline-grid/timeline-grid.component.d.ts +3 -0
  167. package/lib/timeline/timeline.component.d.ts +3 -0
  168. package/lib/user/user-login/user-login.component.d.ts +3 -0
  169. package/lib/user/user-register/user-register.component.d.ts +3 -0
  170. package/lib/wait-dialog/wait-dialog.component.d.ts +3 -0
  171. package/lib/warning-dialog/warning-dialog.component.d.ts +3 -0
  172. package/package.json +20 -22
  173. package/rocketshow-designer-1.35.0.tgz +0 -0
  174. package/bundles/rocketshow-designer.umd.js +0 -9966
  175. package/bundles/rocketshow-designer.umd.js.map +0 -1
  176. package/bundles/rocketshow-designer.umd.min.js +0 -17
  177. package/bundles/rocketshow-designer.umd.min.js.map +0 -1
  178. package/esm2015/lib/array-sort-pipe.js +0 -28
  179. package/esm2015/lib/designer.component.js +0 -411
  180. package/esm2015/lib/designer.module.js +0 -117
  181. package/esm2015/lib/designer.service.js +0 -16
  182. package/esm2015/lib/effect/effect-curve/effect-curve.component.js +0 -325
  183. package/esm2015/lib/effect/effect-pan-tilt/effect-pan-tilt.component.js +0 -30
  184. package/esm2015/lib/effect/effect.component.js +0 -73
  185. package/esm2015/lib/error-dialog/error-dialog.component.js +0 -42
  186. package/esm2015/lib/fixture/fixture-capability/fixture-capability-channel/fixture-capability-channel.component.js +0 -141
  187. package/esm2015/lib/fixture/fixture-capability/fixture-capability-color/fixture-capability-color.component.js +0 -128
  188. package/esm2015/lib/fixture/fixture-capability/fixture-capability-color-wheel/fixture-capability-color-wheel.component.js +0 -163
  189. package/esm2015/lib/fixture/fixture-capability/fixture-capability-dimmer/fixture-capability-dimmer.component.js +0 -60
  190. package/esm2015/lib/fixture/fixture-capability/fixture-capability-pan-tilt/fixture-capability-pan-tilt.component.js +0 -87
  191. package/esm2015/lib/fixture/fixture-capability/fixture-capability.component.js +0 -97
  192. package/esm2015/lib/fixture/fixture-channel/fixture-channel.component.js +0 -66
  193. package/esm2015/lib/fixture/fixture-settings/fixture-settings-position/fixture-settings-position.component.js +0 -200
  194. package/esm2015/lib/fixture/fixture-settings/fixture-settings-stage/fixture-settings-stage.component.js +0 -31
  195. package/esm2015/lib/fixture/fixture-settings/fixture-settings.component.js +0 -35
  196. package/esm2015/lib/fixture/fixture.component.js +0 -70
  197. package/esm2015/lib/fixture-pool/fixture-pool-create-from-file/fixture-pool-create-from-file.component.js +0 -128
  198. package/esm2015/lib/fixture-pool/fixture-pool.component.js +0 -331
  199. package/esm2015/lib/intro/intro.component.js +0 -25
  200. package/esm2015/lib/master-dimmer/master-dimmer.component.js +0 -41
  201. package/esm2015/lib/models/cached-fixture-capability.js +0 -9
  202. package/esm2015/lib/models/cached-fixture-channel.js +0 -7
  203. package/esm2015/lib/models/cached-fixture.js +0 -6
  204. package/esm2015/lib/models/color.js +0 -8
  205. package/esm2015/lib/models/composition.js +0 -46
  206. package/esm2015/lib/models/effect-curve-profile-channel.js +0 -15
  207. package/esm2015/lib/models/effect-curve.js +0 -69
  208. package/esm2015/lib/models/effect-pan-tilt.js +0 -19
  209. package/esm2015/lib/models/effect.js +0 -12
  210. package/esm2015/lib/models/fixture-capability-value.js +0 -15
  211. package/esm2015/lib/models/fixture-capability.js +0 -84
  212. package/esm2015/lib/models/fixture-channel-value.js +0 -11
  213. package/esm2015/lib/models/fixture-channel.js +0 -24
  214. package/esm2015/lib/models/fixture-mode.js +0 -14
  215. package/esm2015/lib/models/fixture-profile.js +0 -70
  216. package/esm2015/lib/models/fixture-wheel-slot.js +0 -26
  217. package/esm2015/lib/models/fixture-wheel.js +0 -15
  218. package/esm2015/lib/models/fixture.js +0 -40
  219. package/esm2015/lib/models/preset-region-scene.js +0 -8
  220. package/esm2015/lib/models/preset.js +0 -56
  221. package/esm2015/lib/models/project.js +0 -68
  222. package/esm2015/lib/models/scene-playback-region.js +0 -11
  223. package/esm2015/lib/models/scene.js +0 -27
  224. package/esm2015/lib/models/universe.js +0 -11
  225. package/esm2015/lib/preset/preset-settings/preset-settings.component.js +0 -66
  226. package/esm2015/lib/preset/preset.component.js +0 -85
  227. package/esm2015/lib/preview/models/color-changer-3d.js +0 -167
  228. package/esm2015/lib/preview/models/fixture-3d.js +0 -150
  229. package/esm2015/lib/preview/models/moving-head-3d.js +0 -233
  230. package/esm2015/lib/preview/preview.component.js +0 -242
  231. package/esm2015/lib/project/project-browser/project-browser.component.js +0 -73
  232. package/esm2015/lib/project/project-import/project-import.component.js +0 -89
  233. package/esm2015/lib/project/project-save/project-save.component.js +0 -105
  234. package/esm2015/lib/project/project-share/project-share.component.js +0 -43
  235. package/esm2015/lib/scene/scene-settings/scene-settings.component.js +0 -52
  236. package/esm2015/lib/scene/scene.component.js +0 -56
  237. package/esm2015/lib/services/animation.service.js +0 -17
  238. package/esm2015/lib/services/config.service.js +0 -28
  239. package/esm2015/lib/services/effect.service.js +0 -16
  240. package/esm2015/lib/services/error-dialog.service.js +0 -44
  241. package/esm2015/lib/services/fixture-pool.service.js +0 -34
  242. package/esm2015/lib/services/fixture.service.js +0 -443
  243. package/esm2015/lib/services/hotkey-target-exclude.service.js +0 -26
  244. package/esm2015/lib/services/intro.service.js +0 -144
  245. package/esm2015/lib/services/preset.service.js +0 -416
  246. package/esm2015/lib/services/preview-mesh.service.js +0 -58
  247. package/esm2015/lib/services/preview.service.js +0 -500
  248. package/esm2015/lib/services/project-load.service.js +0 -171
  249. package/esm2015/lib/services/project.service.js +0 -113
  250. package/esm2015/lib/services/scene.service.js +0 -174
  251. package/esm2015/lib/services/timeline.service.js +0 -738
  252. package/esm2015/lib/services/universe.service.js +0 -24
  253. package/esm2015/lib/services/user-ensure-login.service.js +0 -44
  254. package/esm2015/lib/services/user.service.js +0 -93
  255. package/esm2015/lib/services/uuid.service.js +0 -25
  256. package/esm2015/lib/services/warning-dialog.service.js +0 -43
  257. package/esm2015/lib/timeline/composition-settings/composition-settings.component.js +0 -197
  258. package/esm2015/lib/timeline/timeline-grid/timeline-grid.component.js +0 -55
  259. package/esm2015/lib/timeline/timeline.component.js +0 -239
  260. package/esm2015/lib/user/user-login/user-login.component.js +0 -64
  261. package/esm2015/lib/user/user-register/user-register.component.js +0 -89
  262. package/esm2015/lib/wait-dialog/wait-dialog.component.js +0 -16
  263. package/esm2015/lib/warning-dialog/warning-dialog.component.js +0 -42
  264. package/esm2015/public_api.js +0 -7
  265. package/esm2015/rocketshow-designer.js +0 -61
  266. package/esm5/lib/array-sort-pipe.js +0 -31
  267. package/esm5/lib/designer.component.js +0 -468
  268. package/esm5/lib/designer.module.js +0 -120
  269. package/esm5/lib/designer.service.js +0 -17
  270. package/esm5/lib/effect/effect-curve/effect-curve.component.js +0 -386
  271. package/esm5/lib/effect/effect-pan-tilt/effect-pan-tilt.component.js +0 -31
  272. package/esm5/lib/effect/effect.component.js +0 -75
  273. package/esm5/lib/error-dialog/error-dialog.component.js +0 -43
  274. package/esm5/lib/fixture/fixture-capability/fixture-capability-channel/fixture-capability-channel.component.js +0 -159
  275. package/esm5/lib/fixture/fixture-capability/fixture-capability-color/fixture-capability-color.component.js +0 -130
  276. package/esm5/lib/fixture/fixture-capability/fixture-capability-color-wheel/fixture-capability-color-wheel.component.js +0 -215
  277. package/esm5/lib/fixture/fixture-capability/fixture-capability-dimmer/fixture-capability-dimmer.component.js +0 -61
  278. package/esm5/lib/fixture/fixture-capability/fixture-capability-pan-tilt/fixture-capability-pan-tilt.component.js +0 -88
  279. package/esm5/lib/fixture/fixture-capability/fixture-capability.component.js +0 -130
  280. package/esm5/lib/fixture/fixture-channel/fixture-channel.component.js +0 -68
  281. package/esm5/lib/fixture/fixture-settings/fixture-settings-position/fixture-settings-position.component.js +0 -306
  282. package/esm5/lib/fixture/fixture-settings/fixture-settings-stage/fixture-settings-stage.component.js +0 -32
  283. package/esm5/lib/fixture/fixture-settings/fixture-settings.component.js +0 -36
  284. package/esm5/lib/fixture/fixture.component.js +0 -71
  285. package/esm5/lib/fixture-pool/fixture-pool-create-from-file/fixture-pool-create-from-file.component.js +0 -127
  286. package/esm5/lib/fixture-pool/fixture-pool.component.js +0 -430
  287. package/esm5/lib/intro/intro.component.js +0 -26
  288. package/esm5/lib/master-dimmer/master-dimmer.component.js +0 -42
  289. package/esm5/lib/models/cached-fixture-capability.js +0 -11
  290. package/esm5/lib/models/cached-fixture-channel.js +0 -9
  291. package/esm5/lib/models/cached-fixture.js +0 -8
  292. package/esm5/lib/models/color.js +0 -10
  293. package/esm5/lib/models/composition.js +0 -60
  294. package/esm5/lib/models/effect-curve-profile-channel.js +0 -29
  295. package/esm5/lib/models/effect-curve.js +0 -95
  296. package/esm5/lib/models/effect-pan-tilt.js +0 -24
  297. package/esm5/lib/models/effect.js +0 -14
  298. package/esm5/lib/models/fixture-capability-value.js +0 -17
  299. package/esm5/lib/models/fixture-capability.js +0 -86
  300. package/esm5/lib/models/fixture-channel-value.js +0 -13
  301. package/esm5/lib/models/fixture-channel.js +0 -38
  302. package/esm5/lib/models/fixture-mode.js +0 -16
  303. package/esm5/lib/models/fixture-profile.js +0 -114
  304. package/esm5/lib/models/fixture-wheel-slot.js +0 -28
  305. package/esm5/lib/models/fixture-wheel.js +0 -29
  306. package/esm5/lib/models/fixture.js +0 -42
  307. package/esm5/lib/models/preset-region-scene.js +0 -10
  308. package/esm5/lib/models/preset.js +0 -90
  309. package/esm5/lib/models/project.js +0 -122
  310. package/esm5/lib/models/scene-playback-region.js +0 -13
  311. package/esm5/lib/models/scene.js +0 -29
  312. package/esm5/lib/models/universe.js +0 -13
  313. package/esm5/lib/preset/preset-settings/preset-settings.component.js +0 -67
  314. package/esm5/lib/preset/preset.component.js +0 -86
  315. package/esm5/lib/preview/models/color-changer-3d.js +0 -194
  316. package/esm5/lib/preview/models/fixture-3d.js +0 -196
  317. package/esm5/lib/preview/models/moving-head-3d.js +0 -250
  318. package/esm5/lib/preview/preview.component.js +0 -280
  319. package/esm5/lib/project/project-browser/project-browser.component.js +0 -77
  320. package/esm5/lib/project/project-import/project-import.component.js +0 -88
  321. package/esm5/lib/project/project-save/project-save.component.js +0 -120
  322. package/esm5/lib/project/project-share/project-share.component.js +0 -44
  323. package/esm5/lib/scene/scene-settings/scene-settings.component.js +0 -53
  324. package/esm5/lib/scene/scene.component.js +0 -57
  325. package/esm5/lib/services/animation.service.js +0 -18
  326. package/esm5/lib/services/config.service.js +0 -29
  327. package/esm5/lib/services/effect.service.js +0 -17
  328. package/esm5/lib/services/error-dialog.service.js +0 -46
  329. package/esm5/lib/services/fixture-pool.service.js +0 -36
  330. package/esm5/lib/services/fixture.service.js +0 -643
  331. package/esm5/lib/services/hotkey-target-exclude.service.js +0 -27
  332. package/esm5/lib/services/intro.service.js +0 -145
  333. package/esm5/lib/services/preset.service.js +0 -637
  334. package/esm5/lib/services/preview-mesh.service.js +0 -61
  335. package/esm5/lib/services/preview.service.js +0 -754
  336. package/esm5/lib/services/project-load.service.js +0 -185
  337. package/esm5/lib/services/project.service.js +0 -127
  338. package/esm5/lib/services/scene.service.js +0 -251
  339. package/esm5/lib/services/timeline.service.js +0 -845
  340. package/esm5/lib/services/universe.service.js +0 -36
  341. package/esm5/lib/services/user-ensure-login.service.js +0 -45
  342. package/esm5/lib/services/user.service.js +0 -95
  343. package/esm5/lib/services/uuid.service.js +0 -26
  344. package/esm5/lib/services/warning-dialog.service.js +0 -45
  345. package/esm5/lib/timeline/composition-settings/composition-settings.component.js +0 -206
  346. package/esm5/lib/timeline/timeline-grid/timeline-grid.component.js +0 -56
  347. package/esm5/lib/timeline/timeline.component.js +0 -243
  348. package/esm5/lib/user/user-login/user-login.component.js +0 -66
  349. package/esm5/lib/user/user-register/user-register.component.js +0 -91
  350. package/esm5/lib/wait-dialog/wait-dialog.component.js +0 -18
  351. package/esm5/lib/warning-dialog/warning-dialog.component.js +0 -43
  352. package/esm5/public_api.js +0 -7
  353. package/esm5/rocketshow-designer.js +0 -61
  354. package/fesm2015/rocketshow-designer.js +0 -7945
  355. package/fesm2015/rocketshow-designer.js.map +0 -1
  356. package/fesm5/rocketshow-designer.js +0 -9690
  357. package/fesm5/rocketshow-designer.js.map +0 -1
  358. package/lib/models/universe.d.ts +0 -8
  359. package/lib/services/universe.service.d.ts +0 -6
  360. package/rocketshow-designer-1.32.0.tgz +0 -0
  361. package/rocketshow-designer.d.ts +0 -60
  362. package/rocketshow-designer.metadata.json +0 -1
@@ -0,0 +1,726 @@
1
+ import { HttpClient } from '@angular/common/http';
2
+ import { Injectable } from '@angular/core';
3
+ import { Subject, timer } from 'rxjs';
4
+ import { map } from 'rxjs/operators';
5
+ import WaveSurfer from 'wavesurfer.js';
6
+ import CursorPlugin from 'wavesurfer.js/dist/plugin/wavesurfer.cursor.min.js';
7
+ import RegionsPlugin from 'wavesurfer.js/dist/plugin/wavesurfer.regions.min.js';
8
+ import TimeLinePlugin from 'wavesurfer.js/dist/plugin/wavesurfer.timeline.min.js';
9
+ import { guess } from 'web-audio-beat-detector';
10
+ import { PresetRegionScene } from '../models/preset-region-scene';
11
+ import { ScenePlaybackRegion } from '../models/scene-playback-region';
12
+ import { ConfigService } from './config.service';
13
+ import { PresetService } from './preset.service';
14
+ import { ProjectService } from './project.service';
15
+ import { SceneService } from './scene.service';
16
+ import * as i0 from "@angular/core";
17
+ import * as i1 from "./scene.service";
18
+ import * as i2 from "./preset.service";
19
+ import * as i3 from "./project.service";
20
+ import * as i4 from "@angular/common/http";
21
+ import * as i5 from "./config.service";
22
+ export class TimelineService {
23
+ constructor(sceneService, presetService, projectService, http, configService) {
24
+ this.sceneService = sceneService;
25
+ this.presetService = presetService;
26
+ this.projectService = projectService;
27
+ this.http = http;
28
+ this.configService = configService;
29
+ this.playState = 'paused';
30
+ this.zoom = 0;
31
+ this.timelineClicking = false;
32
+ this.intensity = 0.2;
33
+ this.intensitySelectedScene = 0.4;
34
+ this.intensityHighlighted = 0.8;
35
+ this.waveSurferReady = new Subject();
36
+ this.detectChanges = new Subject();
37
+ // can we add new compositions based on an external pool and
38
+ // should new compositions not available in this pool be added there?
39
+ this.externalCompositionsAvailable = false;
40
+ this.loadingAudioFile = false;
41
+ this.presetService.previewSelectionChanged.subscribe(() => {
42
+ this.selectedPlaybackRegion = undefined;
43
+ this.updateRegionSelection();
44
+ });
45
+ this.sceneService.sceneDeleted.subscribe(() => {
46
+ this.redrawAllRegions();
47
+ });
48
+ this.sceneService.sceneSelected.subscribe(() => {
49
+ this.redrawAllRegions();
50
+ });
51
+ }
52
+ redrawAllRegions() {
53
+ // remove all regions from wavesurver
54
+ if (this.waveSurfer) {
55
+ for (const key of Object.keys(this.waveSurfer.regions.list)) {
56
+ const region = this.waveSurfer.regions.list[key];
57
+ region.remove();
58
+ }
59
+ }
60
+ // draw all regions
61
+ this.drawAllRegions();
62
+ }
63
+ pad(num, size) {
64
+ if (!num) {
65
+ num = 0;
66
+ }
67
+ let padded = num.toString();
68
+ while (padded.length < size) {
69
+ padded = '0' + padded;
70
+ }
71
+ return padded;
72
+ }
73
+ msToTime(millis, includeMillis = true) {
74
+ const ms = Math.round(millis % 1000);
75
+ const seconds = Math.floor(((millis % 360000) % 60000) / 1000);
76
+ const minutes = Math.floor((millis % 3600000) / 60000);
77
+ if (includeMillis) {
78
+ return this.pad(minutes, 2) + ':' + this.pad(seconds, 2) + '.' + this.pad(ms, 3);
79
+ }
80
+ else {
81
+ return this.pad(minutes, 2) + ':' + this.pad(seconds, 2);
82
+ }
83
+ }
84
+ updateCurrentTime() {
85
+ if (!this.waveSurfer) {
86
+ return;
87
+ }
88
+ // display the current time
89
+ this.currentTime = this.msToTime(this.waveSurfer.getCurrentTime() * 1000);
90
+ if (!this.waveSurfer.timeline.drawer) {
91
+ return;
92
+ }
93
+ // draw the current cursor on the timeline
94
+ // TODO redrawing the timeline each update is way to expensive.
95
+ // maybe as a better solution use an element, like the cursor inside Wavesurfer to
96
+ // display the progress?
97
+ let x = 0;
98
+ const duration = this.waveSurfer.backend.getDuration();
99
+ const width = this.waveSurfer.params.fillParent && !this.waveSurfer.params.scrollParent
100
+ ? this.waveSurfer.timeline.drawer.getWidth()
101
+ : this.waveSurfer.timeline.drawer.wrapper.scrollWidth * this.waveSurfer.params.pixelRatio;
102
+ x = (width / duration) * this.waveSurfer.getCurrentTime() - 2;
103
+ // update the timeline canvas
104
+ this.waveSurfer.timeline.render();
105
+ // draw the cursor on the timeline
106
+ this.waveSurfer.timeline.canvases.forEach((canvas, i) => {
107
+ const leftOffset = i * this.waveSurfer.timeline.maxCanvasWidth;
108
+ const ctx = canvas.getContext('2d');
109
+ ctx.fillStyle = '#fd7e14';
110
+ ctx.beginPath();
111
+ ctx.moveTo(x - 12 - leftOffset, 20);
112
+ ctx.lineTo(x + 12 - leftOffset, 20);
113
+ ctx.lineTo(x - leftOffset, 45);
114
+ ctx.fill();
115
+ });
116
+ }
117
+ startTimeUpdater() {
118
+ this.stopTimeUpdater();
119
+ const timeUpdater = timer(0, 40);
120
+ this.timeUpdateSubscription = timeUpdater.subscribe(() => {
121
+ this.updateCurrentTime();
122
+ });
123
+ }
124
+ stopTimeUpdater() {
125
+ if (this.timeUpdateSubscription) {
126
+ this.timeUpdateSubscription.unsubscribe();
127
+ }
128
+ }
129
+ formatTimeCallback(seconds, pxPerSec) {
130
+ if (this.selectedComposition.gridType === 'musical') {
131
+ return Math.round(seconds / this.selectedComposition.timeSignatureUpper / (60 / this.selectedComposition.beatsPerMinute));
132
+ }
133
+ else {
134
+ // calculate minutes and seconds from seconds count
135
+ const minutes = parseInt((seconds / 60), 10);
136
+ seconds = parseInt((seconds % 60), 10);
137
+ // fill up seconds with zeroes
138
+ const secondsStr = seconds < 10 ? '0' + seconds : seconds;
139
+ return `${minutes}:${secondsStr}`;
140
+ }
141
+ }
142
+ timeInterval(pxPerSec) {
143
+ if (this.selectedComposition.gridType === 'musical') {
144
+ const interval = 60 / this.selectedComposition.beatsPerMinute / this.selectedComposition.gridResolution;
145
+ if (pxPerSec < 40) {
146
+ return interval * 4;
147
+ }
148
+ else if (pxPerSec < 80) {
149
+ return interval * 2;
150
+ }
151
+ return interval;
152
+ }
153
+ else {
154
+ if (pxPerSec >= 25) {
155
+ return 1;
156
+ }
157
+ else if (pxPerSec * 5 >= 25) {
158
+ return 5;
159
+ }
160
+ else if (pxPerSec * 15 >= 25) {
161
+ return 15;
162
+ }
163
+ return Math.ceil(0.5 / pxPerSec) * 60;
164
+ }
165
+ }
166
+ primaryLabelInterval(pxPerSec) {
167
+ if (this.selectedComposition.gridType === 'musical') {
168
+ const interval = this.selectedComposition.timeSignatureUpper * this.selectedComposition.gridResolution;
169
+ return interval;
170
+ }
171
+ else {
172
+ if (pxPerSec >= 25) {
173
+ return 10;
174
+ }
175
+ else if (pxPerSec * 5 >= 25) {
176
+ return 6;
177
+ }
178
+ else if (pxPerSec * 15 >= 25) {
179
+ return 4;
180
+ }
181
+ return 4;
182
+ }
183
+ }
184
+ secondaryLabelInterval(pxPerSec) {
185
+ if (this.selectedComposition.gridType === 'musical') {
186
+ return 0;
187
+ }
188
+ else {
189
+ if (pxPerSec >= 25) {
190
+ return 5;
191
+ }
192
+ else if (pxPerSec * 5 >= 25) {
193
+ return 2;
194
+ }
195
+ else if (pxPerSec * 15 >= 25) {
196
+ return 2;
197
+ }
198
+ return 2;
199
+ }
200
+ }
201
+ seeekWithTimeline(e) {
202
+ // taken from wavesurfer -> drawer -> handleEvent
203
+ const clientX = e.targetTouches ? e.targetTouches[0].clientX : e.clientX;
204
+ const bbox = this.waveSurfer.timeline.wrapper.getBoundingClientRect();
205
+ const nominalWidth = this.waveSurfer.timeline.drawer.width;
206
+ const parentWidth = this.waveSurfer.timeline.drawer.getWidth();
207
+ let progress;
208
+ if (!this.waveSurfer.timeline.drawer.params.fillParent && nominalWidth < parentWidth) {
209
+ progress =
210
+ (this.waveSurfer.timeline.drawer.params.rtl ? bbox.right - clientX : clientX - bbox.left) *
211
+ (this.waveSurfer.timeline.drawer.params.pixelRatio / nominalWidth) || 0;
212
+ if (progress > 1) {
213
+ progress = 1;
214
+ }
215
+ }
216
+ else {
217
+ progress =
218
+ ((this.waveSurfer.timeline.drawer.params.rtl ? bbox.right - clientX : clientX - bbox.left) +
219
+ this.waveSurfer.timeline.wrapper.scrollLeft) /
220
+ this.waveSurfer.timeline.wrapper.scrollWidth || 0;
221
+ }
222
+ progress = Math.max(progress, 0);
223
+ setTimeout(() => {
224
+ this.waveSurfer.seekTo(progress);
225
+ this.detectChanges.next();
226
+ this.presetService.previewLive(this.selectedComposition.name, Math.round(this.waveSurfer.getCurrentTime() * 1000));
227
+ }, 0);
228
+ }
229
+ applyZoom(zoom) {
230
+ if (zoom < 0 || zoom > 200) {
231
+ return;
232
+ }
233
+ this.zoom = zoom;
234
+ if (this.waveSurfer) {
235
+ setTimeout(() => {
236
+ this.waveSurfer.zoom(this.zoom);
237
+ this.updateCurrentTime();
238
+ }, 0);
239
+ }
240
+ }
241
+ isWaveSurferReady() {
242
+ if (!this.waveSurfer) {
243
+ return false;
244
+ }
245
+ if (!this.waveSurfer.isReady) {
246
+ return false;
247
+ }
248
+ return true;
249
+ }
250
+ addRegion(waveSurferRegion) {
251
+ if (!this.isWaveSurferReady()) {
252
+ return;
253
+ }
254
+ if (!this.sceneService.selectedScenes || this.sceneService.selectedScenes.length !== 1) {
255
+ return;
256
+ }
257
+ if (!this.selectedComposition) {
258
+ return;
259
+ }
260
+ const scenePlaybackRegion = new ScenePlaybackRegion();
261
+ scenePlaybackRegion.sceneUuid = this.sceneService.selectedScenes[0].uuid;
262
+ if (waveSurferRegion) {
263
+ scenePlaybackRegion.startMillis = waveSurferRegion.start * 1000;
264
+ scenePlaybackRegion.endMillis = waveSurferRegion.end * 1000;
265
+ }
266
+ else {
267
+ scenePlaybackRegion.startMillis = (this.waveSurfer.getDuration() * 1000) / 3;
268
+ scenePlaybackRegion.endMillis = ((this.waveSurfer.getDuration() * 1000) / 3) * 2;
269
+ }
270
+ this.selectedComposition.scenePlaybackRegions.push(scenePlaybackRegion);
271
+ this.selectedPlaybackRegion = scenePlaybackRegion;
272
+ if (waveSurferRegion) {
273
+ waveSurferRegion.color =
274
+ 'rgba(' +
275
+ this.hexToRgb(this.sceneService.selectedScenes[0].color).r +
276
+ ', ' +
277
+ this.hexToRgb(this.sceneService.selectedScenes[0].color).g +
278
+ ', ' +
279
+ this.hexToRgb(this.sceneService.selectedScenes[0].color).b +
280
+ ', ' +
281
+ this.intensityHighlighted +
282
+ ')';
283
+ waveSurferRegion.attributes.selectable = true;
284
+ this.connectRegion(waveSurferRegion, this.sceneService.selectedScenes[0], scenePlaybackRegion);
285
+ this.updateRegionSelection();
286
+ }
287
+ else {
288
+ this.drawRegion(scenePlaybackRegion, this.sceneService.selectedScenes[0]);
289
+ }
290
+ this.presetService.previewLive();
291
+ }
292
+ getSnapToGridInterval() {
293
+ if (this.selectedComposition.snapToGrid) {
294
+ return 60 / this.selectedComposition.beatsPerMinute / this.selectedComposition.gridResolution;
295
+ }
296
+ return undefined;
297
+ }
298
+ getSnapToGridOffset() {
299
+ return this.selectedComposition.gridOffsetMillis / 1000;
300
+ }
301
+ deleteSelectedComposition() {
302
+ this.projectService.project.compositions.splice(this.selectedCompositionIndex, 1);
303
+ this.selectedComposition = undefined;
304
+ this.selectedCompositionIndex = undefined;
305
+ this.destroyWaveSurfer();
306
+ if (this.projectService.project.compositions.length > 0) {
307
+ this.selectCompositionIndex(0);
308
+ }
309
+ }
310
+ destroyWaveSurfer() {
311
+ this.duration = undefined;
312
+ this.loadingAudioFile = false;
313
+ if (this.waveSurfer) {
314
+ this.waveSurfer.destroy();
315
+ this.waveSurfer = undefined;
316
+ }
317
+ }
318
+ createWaveSurfer() {
319
+ this.destroyWaveSurfer();
320
+ if (!this.selectedComposition.audioFileName) {
321
+ return;
322
+ }
323
+ this.loadingAudioFile = true;
324
+ setTimeout(() => {
325
+ this.waveSurfer = WaveSurfer.create({
326
+ container: '#waveform',
327
+ waveColor: 'white',
328
+ progressColor: 'white',
329
+ // barWidth: 2,
330
+ height: 1,
331
+ interact: false,
332
+ // Use for timelines without sound. Wave will be displayed
333
+ // wrong, but should work for a dummy audio without any waves.
334
+ // duration: 400,
335
+ plugins: [
336
+ CursorPlugin.create({
337
+ // showTime: true,
338
+ opacity: 1,
339
+ color: '#fd7e14',
340
+ hideOnBlur: false /* don't show/hide the cursor on the wave (only on the timeline) */,
341
+ }),
342
+ RegionsPlugin.create({
343
+ dragSelection: {
344
+ slop: 5,
345
+ },
346
+ color: '#fff',
347
+ snapToGridInterval: this.getSnapToGridInterval(),
348
+ snapToGridOffset: this.getSnapToGridOffset(),
349
+ }),
350
+ TimeLinePlugin.create({
351
+ container: '#waveform-timeline',
352
+ primaryFontColor: '#fff',
353
+ secondaryFontColor: '#fff',
354
+ offset: this.getSnapToGridOffset(),
355
+ formatTimeCallback: this.formatTimeCallback.bind(this),
356
+ timeInterval: this.timeInterval.bind(this),
357
+ primaryLabelInterval: this.primaryLabelInterval.bind(this),
358
+ secondaryLabelInterval: this.secondaryLabelInterval.bind(this),
359
+ }),
360
+ ],
361
+ });
362
+ let audioFileName;
363
+ if (this.configService.enableMediaLibrary) {
364
+ // the file name is also used for the real file name
365
+ audioFileName = 'file/get?name=' + this.selectedComposition.audioFileName + '&type=AUDIO';
366
+ }
367
+ else {
368
+ // the composition uuid and extension is used as the file name
369
+ audioFileName =
370
+ 'composition-files/?file=' +
371
+ this.selectedComposition.uuid +
372
+ '.' +
373
+ this.selectedComposition.audioFileName.substr(this.selectedComposition.audioFileName.lastIndexOf('.') + 1);
374
+ }
375
+ this.waveSurfer.load(this.configService.restUrl + audioFileName);
376
+ this.waveSurfer.on('ready', () => {
377
+ setTimeout(() => {
378
+ // try guessing the bpm and offset from the file, if necessary
379
+ if (this.selectedComposition.tempoGuessed) {
380
+ // we already guessed the BPM of this file --> don't do it again
381
+ this.loadingAudioFile = false;
382
+ }
383
+ else {
384
+ // we have not yet guessed the BPM --> do it now
385
+ this.selectedComposition.tempoGuessed = true;
386
+ guess(this.waveSurfer.backend.buffer)
387
+ .then(({ bpm, offset }) => {
388
+ // the bpm and offset could be guessed
389
+ this.selectedComposition.beatsPerMinute = bpm;
390
+ this.selectedComposition.gridOffsetMillis = offset * 1000;
391
+ this.loadingAudioFile = false;
392
+ })
393
+ .catch((err) => {
394
+ // something went wrong
395
+ console.error('Could not detect the BPM from the audio file', err);
396
+ this.loadingAudioFile = false;
397
+ });
398
+ }
399
+ this.duration = this.msToTime(this.waveSurfer.getDuration() * 1000);
400
+ this.drawAllRegions();
401
+ // scroll wavesurfer in sync with the timeline
402
+ this.waveSurfer.timeline.wrapper.addEventListener('scroll', () => {
403
+ this.waveSurfer.drawer.wrapper.scrollLeft = this.waveSurfer.timeline.wrapper.scrollLeft;
404
+ // Set the scroll position of the timeline to the same position as the wavesurfer,
405
+ // because the timeline is larger than wavesurfer and might get out of sync.
406
+ // This way, if wavesurfer cannot scroll any further, we reset the position
407
+ // of the timeline as well.
408
+ this.waveSurfer.timeline.wrapper.scrollLeft = this.waveSurfer.drawer.wrapper.scrollLeft;
409
+ });
410
+ // display the cursor also on the timeline
411
+ this.waveSurfer.timeline.wrapper.addEventListener('mouseenter', () => {
412
+ this.waveSurfer.cursor.showCursor();
413
+ });
414
+ this.waveSurfer.timeline.wrapper.addEventListener('mouseleave', () => {
415
+ this.waveSurfer.cursor.hideCursor();
416
+ });
417
+ this.waveSurfer.timeline.wrapper.addEventListener('mousemove', (e) => {
418
+ const bbox = this.waveSurfer.container.getBoundingClientRect();
419
+ const x = e.clientX - bbox.left;
420
+ this.waveSurfer.cursor.updateCursorPosition(x, 0);
421
+ });
422
+ // hide the cursor on the wave initially. in combination with the param hideOnBlur = false,
423
+ // it will never be displayed on the wave now. we handle it on the timeline only.
424
+ this.waveSurfer.cursor.hideCursor();
425
+ // seek on timeline-click
426
+ this.waveSurfer.timeline.wrapper.addEventListener('mousedown', (e) => {
427
+ this.timelineClicking = true;
428
+ this.seeekWithTimeline(e);
429
+ });
430
+ this.waveSurfer.timeline.wrapper.addEventListener('mousemove', (e) => {
431
+ if (this.timelineClicking) {
432
+ this.seeekWithTimeline(e);
433
+ }
434
+ });
435
+ this.waveSurfer.timeline.wrapper.addEventListener('mouseup', (e) => {
436
+ this.timelineClicking = false;
437
+ });
438
+ this.updateCurrentTime();
439
+ this.detectChanges.next();
440
+ this.waveSurferReady.next();
441
+ }, 0);
442
+ });
443
+ this.waveSurfer.on('error', (error) => {
444
+ // could not load the composition --> delete it
445
+ // (this may occur, when the composition has been deleted but the project is not saved afterwards)
446
+ this.deleteSelectedComposition();
447
+ });
448
+ this.waveSurfer.on('seek', () => {
449
+ this.updateCurrentTime();
450
+ });
451
+ this.waveSurfer.on('play', () => {
452
+ this.startTimeUpdater();
453
+ });
454
+ this.waveSurfer.on('pause', () => {
455
+ this.stopTimeUpdater();
456
+ });
457
+ this.waveSurfer.on('region-created', (region) => {
458
+ // region created by selection or programmatically
459
+ if (this.sceneService.selectedScenes && this.sceneService.selectedScenes.length === 1) {
460
+ if (!region.data.handled) {
461
+ this.addRegion(region);
462
+ }
463
+ }
464
+ else {
465
+ if (!region.data.handled) {
466
+ region.remove();
467
+ }
468
+ }
469
+ });
470
+ this.waveSurfer.on('region-updated', (region) => {
471
+ this.detectChanges.next();
472
+ this.presetService.previewLive();
473
+ });
474
+ }, 0);
475
+ }
476
+ hexToRgb(hex) {
477
+ const result = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(hex);
478
+ return result
479
+ ? {
480
+ r: parseInt(result[1], 16),
481
+ g: parseInt(result[2], 16),
482
+ b: parseInt(result[3], 16),
483
+ }
484
+ : null;
485
+ }
486
+ updateRegionSelection() {
487
+ if (!this.waveSurfer) {
488
+ return;
489
+ }
490
+ for (const key of Object.keys(this.waveSurfer.regions.list)) {
491
+ const region = this.waveSurfer.regions.list[key];
492
+ // if no scene is set, the region is not valid (e.g. has been created, while
493
+ // no scene has been selected and remove did not work properly)
494
+ if (region.scene) {
495
+ let intensity = this.intensity;
496
+ region.drag = false;
497
+ region.resize = false;
498
+ region.attributes.selectable = false;
499
+ if (this.sceneService.sceneIsSelected(region.scene)) {
500
+ intensity = this.intensitySelectedScene;
501
+ region.drag = true;
502
+ region.resize = true;
503
+ region.attributes.selectable = true;
504
+ }
505
+ region.attributes.selected = false;
506
+ if (this.selectedPlaybackRegion && this.selectedPlaybackRegion === region.scenePlaybackRegion) {
507
+ intensity = this.intensityHighlighted;
508
+ region.attributes.selected = true;
509
+ }
510
+ region.color =
511
+ 'rgba(' +
512
+ this.hexToRgb(region.scene.color).r +
513
+ ', ' +
514
+ this.hexToRgb(region.scene.color).g +
515
+ ', ' +
516
+ this.hexToRgb(region.scene.color).b +
517
+ ', ' +
518
+ intensity +
519
+ ')';
520
+ region.updateRender();
521
+ }
522
+ }
523
+ }
524
+ updateSelectedRegion() {
525
+ if (!this.waveSurfer) {
526
+ return;
527
+ }
528
+ if (!this.selectedPlaybackRegion) {
529
+ return;
530
+ }
531
+ for (const key of Object.keys(this.waveSurfer.regions.list)) {
532
+ const region = this.waveSurfer.regions.list[key];
533
+ if (this.selectedPlaybackRegion === region.scenePlaybackRegion) {
534
+ region.start = this.selectedPlaybackRegion.startMillis / 1000;
535
+ region.end = this.selectedPlaybackRegion.endMillis / 1000;
536
+ region.updateRender();
537
+ break;
538
+ }
539
+ }
540
+ }
541
+ setSelectedRegion(scenePlaybackRegion) {
542
+ if (this.selectedPlaybackRegion && this.selectedPlaybackRegion === scenePlaybackRegion) {
543
+ // No update required
544
+ return;
545
+ }
546
+ if (scenePlaybackRegion) {
547
+ this.selectedPlaybackRegion = scenePlaybackRegion;
548
+ }
549
+ this.updateRegionSelection();
550
+ }
551
+ getRegionSnapToGridValue(value) {
552
+ // the regions should snap to a grid
553
+ const offset = this.getSnapToGridOffset() || 0;
554
+ const interval = this.getSnapToGridInterval() || 0;
555
+ return Math.round((value - offset) / interval) * interval + offset;
556
+ }
557
+ connectRegion(waveSurferRegion, scene, scenePlaybackRegion, preset) {
558
+ waveSurferRegion.scenePlaybackRegion = scenePlaybackRegion;
559
+ waveSurferRegion.scene = scene;
560
+ waveSurferRegion.preset = preset;
561
+ waveSurferRegion.on('click', (event) => {
562
+ if (this.sceneService.sceneIsSelected(scene)) {
563
+ this.setSelectedRegion(scenePlaybackRegion);
564
+ }
565
+ });
566
+ waveSurferRegion.on('update', () => {
567
+ this.setSelectedRegion(scenePlaybackRegion);
568
+ if (this.selectedComposition.snapToGrid) {
569
+ // update the regions boundaries. they may not snap to grid, if it has been
570
+ // disabled during creation of the region but activated afterwards.
571
+ waveSurferRegion.start = this.getRegionSnapToGridValue(waveSurferRegion.start);
572
+ waveSurferRegion.end = this.getRegionSnapToGridValue(waveSurferRegion.end);
573
+ }
574
+ scenePlaybackRegion.startMillis = waveSurferRegion.start * 1000;
575
+ scenePlaybackRegion.endMillis = waveSurferRegion.end * 1000;
576
+ });
577
+ }
578
+ drawRegion(scenePlaybackRegion, scene) {
579
+ // draw the regions of the currently selected scene
580
+ if (!this.isWaveSurferReady()) {
581
+ return;
582
+ }
583
+ // add the playback region
584
+ const waveSurferRegion = this.waveSurfer.addRegion({
585
+ start: scenePlaybackRegion.startMillis / 1000,
586
+ end: scenePlaybackRegion.endMillis / 1000,
587
+ color: '#fff',
588
+ data: { handled: true },
589
+ });
590
+ this.connectRegion(waveSurferRegion, scene, scenePlaybackRegion);
591
+ // TODO show the all presets
592
+ // for (let presetUuid of scene.presetUuids) {
593
+ // const preset = this.presetService.getPresetByUuid(presetUuid);
594
+ // let waveSurferRegion = this.timelineService.waveSurfer.addRegion({
595
+ // start: (scenePlaybackRegion.startMillis + (preset.startMillis ? preset.startMillis : 0)) / 1000,
596
+ // end: (scenePlaybackRegion.startMillis
597
+ // + (preset.endMillis ? preset.endMillis : scenePlaybackRegion.endMillis - scenePlaybackRegion.startMillis)) / 1000,
598
+ // color: '#fff',
599
+ // data: { handled: true },
600
+ // // TODO
601
+ // attributes: {
602
+ // preset: true,
603
+ // name: 'Preset 1'
604
+ // }
605
+ // });
606
+ // this.connectRegion(waveSurferRegion, scene, scenePlaybackRegion, preset);
607
+ // }
608
+ this.updateRegionSelection();
609
+ }
610
+ removeRegion() {
611
+ if (!this.selectedPlaybackRegion) {
612
+ return;
613
+ }
614
+ if (this.sceneService.selectedScenes.length !== 1) {
615
+ return;
616
+ }
617
+ for (let i = 0; i < this.selectedComposition.scenePlaybackRegions.length; i++) {
618
+ if (this.selectedComposition.scenePlaybackRegions[i] === this.selectedPlaybackRegion) {
619
+ // remove the region from wavesurfer
620
+ for (const key of Object.keys(this.waveSurfer.regions.list)) {
621
+ const region = this.waveSurfer.regions.list[key];
622
+ if (region.scenePlaybackRegion === this.selectedPlaybackRegion) {
623
+ region.remove();
624
+ }
625
+ }
626
+ this.selectedPlaybackRegion = undefined;
627
+ this.selectedComposition.scenePlaybackRegions.splice(i, 1);
628
+ return;
629
+ }
630
+ }
631
+ this.presetService.previewLive();
632
+ }
633
+ getPresetsInTime(timeMillis) {
634
+ // Return all presets which should be active during the specified time
635
+ const activePresets = [];
636
+ for (let sceneIndex = this.projectService.project.scenes.length - 1; sceneIndex >= 0; sceneIndex--) {
637
+ const scene = this.projectService.project.scenes[sceneIndex];
638
+ for (const region of this.selectedComposition.scenePlaybackRegions) {
639
+ if (region.sceneUuid === scene.uuid) {
640
+ for (let presetIndex = this.projectService.project.presets.length - 1; presetIndex >= 0; presetIndex--) {
641
+ for (const presetUuid of scene.presetUuids) {
642
+ if (presetUuid === this.projectService.project.presets[presetIndex].uuid) {
643
+ const preset = this.presetService.getPresetByUuid(presetUuid);
644
+ if (preset) {
645
+ let presetStartMillis = preset.startMillis === undefined ? region.startMillis : region.startMillis + preset.startMillis;
646
+ let presetEndMillis = preset.endMillis === undefined ? region.endMillis : region.startMillis + preset.endMillis;
647
+ // extend the running time, if fading is done outside the boundaries
648
+ presetStartMillis -= preset.fadeInPre ? preset.fadeInMillis : 0;
649
+ presetEndMillis += preset.fadeOutPost ? preset.fadeOutMillis : 0;
650
+ if (presetStartMillis <= timeMillis && presetEndMillis >= timeMillis) {
651
+ activePresets.push(new PresetRegionScene(preset, region, scene));
652
+ }
653
+ }
654
+ }
655
+ }
656
+ }
657
+ }
658
+ }
659
+ }
660
+ return activePresets;
661
+ }
662
+ drawAllRegions() {
663
+ if (!this.selectedComposition) {
664
+ return;
665
+ }
666
+ // draw the regions in the same order as their corresponding scenes, but draw
667
+ // the selected ones last, to make sure they're always clickable.
668
+ for (let sceneIndex = this.projectService.project.scenes.length - 1; sceneIndex >= 0; sceneIndex--) {
669
+ const scene = this.projectService.project.scenes[sceneIndex];
670
+ if (!this.sceneService.sceneIsSelected(scene)) {
671
+ for (const scenePlaybackRegion of this.selectedComposition.scenePlaybackRegions) {
672
+ if (scenePlaybackRegion.sceneUuid === scene.uuid) {
673
+ this.drawRegion(scenePlaybackRegion, scene);
674
+ }
675
+ }
676
+ }
677
+ }
678
+ // draw all selected scenes afterwards
679
+ for (let sceneIndex = this.projectService.project.scenes.length - 1; sceneIndex >= 0; sceneIndex--) {
680
+ const scene = this.projectService.project.scenes[sceneIndex];
681
+ if (this.sceneService.sceneIsSelected(scene)) {
682
+ for (const scenePlaybackRegion of this.selectedComposition.scenePlaybackRegions) {
683
+ if (scenePlaybackRegion.sceneUuid === scene.uuid) {
684
+ this.drawRegion(scenePlaybackRegion, scene);
685
+ }
686
+ }
687
+ }
688
+ }
689
+ }
690
+ updateGrid() {
691
+ if (this.waveSurferReady) {
692
+ this.waveSurfer.timeline.params.offset = this.getSnapToGridOffset();
693
+ this.waveSurfer.regions.params.snapToGridInterval = this.getSnapToGridInterval();
694
+ this.waveSurfer.regions.params.snapToGridOffset = this.getSnapToGridOffset();
695
+ }
696
+ this.updateCurrentTime();
697
+ }
698
+ getExternalCompositionNames() {
699
+ // get available compositions from an external pool (e.g. Rocket Show)
700
+ return this.http.get('composition/list').pipe(map((response) => {
701
+ const compositionNames = [];
702
+ for (const responseComposition of response) {
703
+ compositionNames.push(responseComposition.name);
704
+ }
705
+ return compositionNames;
706
+ }));
707
+ }
708
+ selectCompositionIndex(index) {
709
+ this.selectedComposition = this.projectService.project.compositions[index];
710
+ this.selectedCompositionIndex = index;
711
+ this.projectService.project.selectedCompositionUuid = this.selectedComposition.uuid;
712
+ this.createWaveSurfer();
713
+ // required to trigger timeline.component.resize()
714
+ this.waveSurferReady.next();
715
+ this.applyZoom(0);
716
+ }
717
+ static { this.ɵfac = function TimelineService_Factory(t) { return new (t || TimelineService)(i0.ɵɵinject(i1.SceneService), i0.ɵɵinject(i2.PresetService), i0.ɵɵinject(i3.ProjectService), i0.ɵɵinject(i4.HttpClient), i0.ɵɵinject(i5.ConfigService)); }; }
718
+ static { this.ɵprov = /*@__PURE__*/ i0.ɵɵdefineInjectable({ token: TimelineService, factory: TimelineService.ɵfac, providedIn: 'root' }); }
719
+ }
720
+ (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(TimelineService, [{
721
+ type: Injectable,
722
+ args: [{
723
+ providedIn: 'root',
724
+ }]
725
+ }], () => [{ type: i1.SceneService }, { type: i2.PresetService }, { type: i3.ProjectService }, { type: i4.HttpClient }, { type: i5.ConfigService }], null); })();
726
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidGltZWxpbmUuc2VydmljZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uL3Byb2plY3RzL2Rlc2lnbmVyL3NyYy9saWIvc2VydmljZXMvdGltZWxpbmUuc2VydmljZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsVUFBVSxFQUFFLE1BQU0sc0JBQXNCLENBQUM7QUFDbEQsT0FBTyxFQUFFLFVBQVUsRUFBRSxNQUFNLGVBQWUsQ0FBQztBQUMzQyxPQUFPLEVBQWMsT0FBTyxFQUFnQixLQUFLLEVBQUUsTUFBTSxNQUFNLENBQUM7QUFDaEUsT0FBTyxFQUFFLEdBQUcsRUFBRSxNQUFNLGdCQUFnQixDQUFDO0FBQ3JDLE9BQU8sVUFBVSxNQUFNLGVBQWUsQ0FBQztBQUN2QyxPQUFPLFlBQVksTUFBTSxvREFBb0QsQ0FBQztBQUM5RSxPQUFPLGFBQWEsTUFBTSxxREFBcUQsQ0FBQztBQUNoRixPQUFPLGNBQWMsTUFBTSxzREFBc0QsQ0FBQztBQUNsRixPQUFPLEVBQUUsS0FBSyxFQUFFLE1BQU0seUJBQXlCLENBQUM7QUFHaEQsT0FBTyxFQUFFLGlCQUFpQixFQUFFLE1BQU0sK0JBQStCLENBQUM7QUFFbEUsT0FBTyxFQUFFLG1CQUFtQixFQUFFLE1BQU0saUNBQWlDLENBQUM7QUFDdEUsT0FBTyxFQUFFLGFBQWEsRUFBRSxNQUFNLGtCQUFrQixDQUFDO0FBQ2pELE9BQU8sRUFBRSxhQUFhLEVBQUUsTUFBTSxrQkFBa0IsQ0FBQztBQUNqRCxPQUFPLEVBQUUsY0FBYyxFQUFFLE1BQU0sbUJBQW1CLENBQUM7QUFDbkQsT0FBTyxFQUFFLFlBQVksRUFBRSxNQUFNLGlCQUFpQixDQUFDOzs7Ozs7O0FBSy9DLE1BQU0sT0FBTyxlQUFlO0lBMEIxQixZQUNVLFlBQTBCLEVBQzFCLGFBQTRCLEVBQzVCLGNBQThCLEVBQzlCLElBQWdCLEVBQ2hCLGFBQTRCO1FBSjVCLGlCQUFZLEdBQVosWUFBWSxDQUFjO1FB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QyxLQUFLLENBQUMsQ0FBQztRQUMzRSxJQUFJLENBQUMsd0JBQXdCLEdBQUcsS0FBSyxDQUFDO1FBQ3RDLElBQUksQ0FBQyxjQUFjLENBQUMsT0FBTyxDQUFDLHVCQUF1QixHQUFHLElBQUksQ0FBQyxtQkFBbUIsQ0FBQyxJQUFJLENBQUM7UUFDcEYsSUFBSSxDQUFDLGdCQUFnQixFQUFFLENBQUM7UUFFeEIsa0RBQWtEO1FBQ2xELElBQUksQ0FBQyxlQUFlLENBQUMsSUFBSSxFQUFFLENBQUM7UUFFNUIsSUFBSSxDQUFDLFNBQVMsQ0FBQyxDQUFDLENBQUMsQ0FBQztJQUNwQixDQUFDO2dGQXh6QlUsZUFBZTt1RUFBZixlQUFlLFdBQWYsZUFBZSxtQkFGZCxNQUFNOztpRkFFUCxlQUFlO2NBSDNCLFVBQVU7ZUFBQztnQkFDVixVQUFVLEVBQUUsTUFBTTthQUNuQiIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IEh0dHBDbGllbnQgfSBmcm9tICdAYW5ndWxhci9jb21tb24vaHR0cCc7XG5pbXBvcnQgeyBJbmplY3RhYmxlIH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQgeyBPYnNlcnZhYmxlLCBTdWJqZWN0LCBTdWJzY3JpcHRpb24sIHRpbWVyIH0gZnJvbSAncnhqcyc7XG5pbXBvcnQgeyBtYXAgfSBmcm9tICdyeGpzL29wZXJhdG9ycyc7XG5pbXBvcnQgV2F2ZVN1cmZlciBmcm9tICd3YXZlc3VyZmVyLmpzJztcbmltcG9ydCBDdXJzb3JQbHVnaW4gZnJvbSAnd2F2ZXN1cmZlci5qcy9kaXN0L3BsdWdpbi93YXZlc3VyZmVyLmN1cnNvci5taW4uanMnO1xuaW1wb3J0IFJlZ2lvbnNQbHVnaW4gZnJvbSAnd2F2ZXN1cmZlci5qcy9kaXN0L3BsdWdpbi93YXZlc3VyZmVyLnJlZ2lvbnMubWluLmpzJztcbmltcG9ydCBUaW1lTGluZVBsdWdpbiBmcm9tICd3YXZlc3VyZmVyLmpzL2Rpc3QvcGx1Z2luL3dhdmVzdXJmZXIudGltZWxpbmUubWluLmpzJztcbmltcG9ydCB7IGd1ZXNzIH0gZnJvbSAnd2ViLWF1ZGlvLWJlYXQtZGV0ZWN0b3InO1xuaW1wb3J0IHsgQ29tcG9zaXRpb24gfSBmcm9tICcuLi9tb2RlbHMvY29tcG9zaXRpb24nO1xuaW1wb3J0IHsgUHJlc2V0IH0gZnJvbSAnLi4vbW9kZWxzL3ByZXNldCc7XG5pbXBvcnQgeyBQcmVzZXRSZWdpb25TY2VuZSB9IGZyb20gJy4uL21vZGVscy9wcmVzZXQtcmVnaW9uLXNjZW5lJztcbmltcG9ydCB7IFNjZW5lIH0gZnJvbSAnLi4vbW9kZWxzL3NjZW5lJztcbmltcG9ydCB7IFNjZW5lUGxheWJhY2tSZWdpb24gfSBmcm9tICcuLi9tb2RlbHMvc2NlbmUtcGxheWJhY2stcmVnaW9uJztcbmltcG9ydCB7IENvbmZpZ1NlcnZpY2UgfSBmcm9tICcuL2NvbmZpZy5zZXJ2aWNlJztcbmltcG9ydCB7IFByZXNldFNlcnZpY2UgfSBmcm9tICcuL3ByZXNldC5zZXJ2aWNlJztcbmltcG9ydCB7IFByb2plY3RTZXJ2aWNlIH0gZnJvbSAnLi9wcm9qZWN0LnNlcnZpY2UnO1xuaW1wb3J0IHsgU2NlbmVTZXJ2aWNlIH0gZnJvbSAnLi9zY2VuZS5zZXJ2aWNlJztcblxuQEluamVjdGFibGUoe1xuICBwcm92aWRlZEluOiAncm9vdCcsXG59KVxuZXhwb3J0IGNsYXNzIFRpbWVsaW5lU2VydmljZSB7XG4gIHB1YmxpYyB3YXZlU3VyZmVyOiBXYXZlU3VyZmVyO1xuICBwdWJsaWMgcGxheVN0YXRlID0gJ3BhdXNlZCc7XG5cbiAgcHVibGljIHpvb20gPSAwO1xuICBwcml2YXRlIHRpbWVVcGRhdGVTdWJzY3JpcHRpb246IFN1YnNjcmlwdGlvbjtcbiAgcHVibGljIGN1cnJlbnRUaW1lOiBzdHJpbmc7XG4gIHByaXZhdGUgdGltZWxpbmVDbGlja2luZyA9IGZhbHNlO1xuICBwdWJsaWMgc2VsZWN0ZWRQbGF5YmFja1JlZ2lvbjogU2NlbmVQbGF5YmFja1JlZ2lvbjtcbiAgcHJpdmF0ZSBpbnRlbnNpdHkgPSAwLjI7XG4gIHByaXZhdGUgaW50ZW5zaXR5U2VsZWN0ZWRTY2VuZSA9IDAuNDtcbiAgcHJpdmF0ZSBpbnRlbnNpdHlIaWdobGlnaHRlZCA9IDAuODtcbiAgcHVibGljIGR1cmF0aW9uOiBzdHJpbmc7XG4gIHB1YmxpYyB3YXZlU3VyZmVyUmVhZHk6IFN1YmplY3Q8dm9pZD4gPSBuZXcgU3ViamVjdCgpO1xuICBwdWJsaWMgZGV0ZWN0Q2hhbmdlczogU3ViamVjdDx2b2lkPiA9IG5ldyBTdWJqZWN0KCk7XG5cbiAgLy8gdGhlIGN1cnJlbnQgY29tcG9zaXRpb25cbiAgcHVibGljIHNlbGVjdGVkQ29tcG9zaXRpb246IENvbXBvc2l0aW9uO1xuICBwdWJsaWMgc2VsZWN0ZWRDb21wb3NpdGlvbkluZGV4OiBudW1iZXI7XG5cbiAgLy8gY2FuIHdlIGFkZCBuZXcgY29tcG9zaXRpb25zIGJhc2VkIG9uIGFuIGV4dGVybmFsIHBvb2wgYW5kXG4gIC8vIHNob3VsZCBuZXcgY29tcG9zaXRpb25zIG5vdCBhdmFpbGFibGUgaW4gdGhpcyBwb29sIGJlIGFkZGVkIHRoZXJlP1xuICBwdWJsaWMgZXh0ZXJuYWxDb21wb3NpdGlvbnNBdmFpbGFibGUgPSBmYWxzZTtcblxuICBwdWJsaWMgbG9hZGluZ0F1ZGlvRmlsZSA9IGZhbHNlO1xuXG4gIGNvbnN0cnVjdG9yKFxuICAgIHByaXZhdGUgc2NlbmVTZXJ2aWNlOiBTY2VuZVNlcnZpY2UsXG4gICAgcHJpdmF0ZSBwcmVzZXRTZXJ2aWNlOiBQcmVzZXRTZXJ2aWNlLFxuICAgIHByaXZhdGUgcHJvamVjdFNlcnZpY2U6IFByb2plY3RTZXJ2aWNlLFxuICAgIHByaXZhdGUgaHR0cDogSHR0cENsaWVudCxcbiAgICBwcml2YXRlIGNvbmZpZ1NlcnZpY2U6IENvbmZpZ1NlcnZpY2VcbiAgKSB7XG4gICAgdGhpcy5wcmVzZXRTZXJ2aWNlLnByZXZpZXdTZWxlY3Rpb25DaGFuZ2VkLnN1YnNjcmliZSgoKSA9PiB7XG4gICAgICB0aGlzLnNlbGVjdGVkUGxheWJhY2tSZWdpb24gPSB1bmRlZmluZWQ7XG4gICAgICB0aGlzLnVwZGF0ZVJlZ2lvblNlbGVjdGlvbigpO1xuICAgIH0pO1xuICAgIHRoaXMuc2NlbmVTZXJ2aWNlLnNjZW5lRGVsZXRlZC5zdWJzY3JpYmUoKCkgPT4ge1xuICAgICAgdGhpcy5yZWRyYXdBbGxSZWdpb25zKCk7XG4gICAgfSk7XG4gICAgdGhpcy5zY2VuZVNlcnZpY2Uuc2NlbmVTZWxlY3RlZC5zdWJzY3JpYmUoKCkgPT4ge1xuICAgICAgdGhpcy5yZWRyYXdBbGxSZWdpb25zKCk7XG4gICAgfSk7XG4gIH1cblxuICBwcml2YXRlIHJlZHJhd0FsbFJlZ2lvbnMoKSB7XG4gICAgLy8gcmVtb3ZlIGFsbCByZWdpb25zIGZyb20gd2F2ZXN1cnZlclxuICAgIGlmICh0aGlzLndhdmVTdXJmZXIpIHtcbiAgICAgIGZvciAoY29uc3Qga2V5IG9mIE9iamVjdC5rZXlzKHRoaXMud2F2ZVN1cmZlci5yZWdpb25zLmxpc3QpKSB7XG4gICAgICAgIGNvbnN0IHJlZ2lvbjogYW55ID0gdGhpcy53YXZlU3VyZmVyLnJlZ2lvbnMubGlzdFtrZXldO1xuICAgICAgICByZWdpb24ucmVtb3ZlKCk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgLy8gZHJhdyBhbGwgcmVnaW9uc1xuICAgIHRoaXMuZHJhd0FsbFJlZ2lvbnMoKTtcbiAgfVxuXG4gIHByaXZhdGUgcGFkKG51bTogbnVtYmVyLCBzaXplOiBudW1iZXIpOiBzdHJpbmcge1xuICAgIGlmICghbnVtKSB7XG4gICAgICBudW0gPSAwO1xuICAgIH1cblxuICAgIGxldCBwYWRkZWQ6IHN0cmluZyA9IG51bS50b1N0cmluZygpO1xuICAgIHdoaWxlIChwYWRkZWQubGVuZ3RoIDwgc2l6ZSkge1xuICAgICAgcGFkZGVkID0gJzAnICsgcGFkZGVkO1xuICAgIH1cblxuICAgIHJldHVybiBwYWRkZWQ7XG4gIH1cblxuICBwcml2YXRlIG1zVG9UaW1lKG1pbGxpczogbnVtYmVyLCBpbmNsdWRlTWlsbGlzOiBib29sZWFuID0gdHJ1ZSk6IHN0cmluZyB7XG4gICAgY29uc3QgbXM6IG51bWJlciA9IE1hdGgucm91bmQobWlsbGlzICUgMTAwMCk7XG4gICAgY29uc3Qgc2Vjb25kczogbnVtYmVyID0gTWF0aC5mbG9vcigoKG1pbGxpcyAlIDM2MDAwMCkgJSA2MDAwMCkgLyAxMDAwKTtcbiAgICBjb25zdCBtaW51dGVzOiBudW1iZXIgPSBNYXRoLmZsb29yKChtaWxsaXMgJSAzNjAwMDAwKSAvIDYwMDAwKTtcblxuICAgIGlmIChpbmNsdWRlTWlsbGlzKSB7XG4gICAgICByZXR1cm4gdGhpcy5wYWQobWludXRlcywgMikgKyAnOicgKyB0aGlzLnBhZChzZWNvbmRzLCAyKSArICcuJyArIHRoaXMucGFkKG1zLCAzKTtcbiAgICB9IGVsc2Uge1xuICAgICAgcmV0dXJuIHRoaXMucGFkKG1pbnV0ZXMsIDIpICsgJzonICsgdGhpcy5wYWQoc2Vjb25kcywgMik7XG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSB1cGRhdGVDdXJyZW50VGltZSgpIHtcbiAgICBpZiAoIXRoaXMud2F2ZVN1cmZlcikge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIC8vIGRpc3BsYXkgdGhlIGN1cnJlbnQgdGltZVxuICAgIHRoaXMuY3VycmVudFRpbWUgPSB0aGlzLm1zVG9UaW1lKHRoaXMud2F2ZVN1cmZlci5nZXRDdXJyZW50VGltZSgpICogMTAwMCk7XG5cbiAgICBpZiAoIXRoaXMud2F2ZVN1cmZlci50aW1lbGluZS5kcmF3ZXIpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICAvLyBkcmF3IHRoZSBjdXJyZW50IGN1cnNvciBvbiB0aGUgdGltZWxpbmVcbiAgICAvLyBUT0RPIHJlZHJhd2luZyB0aGUgdGltZWxpbmUgZWFjaCB1cGRhdGUgaXMgd2F5IHRvIGV4cGVuc2l2ZS5cbiAgICAvLyBtYXliZSBhcyBhIGJldHRlciBzb2x1dGlvbiB1c2UgYW4gZWxlbWVudCwgbGlrZSB0aGUgY3Vyc29yIGluc2lkZSBXYXZlc3VyZmVyIHRvXG4gICAgLy8gZGlzcGxheSB0aGUgcHJvZ3Jlc3M/XG4gICAgbGV0IHggPSAwO1xuICAgIGNvbnN0IGR1cmF0aW9uOiBudW1iZXIgPSB0aGlzLndhdmVTdXJmZXIuYmFja2VuZC5nZXREdXJhdGlvbigpO1xuICAgIGNvbnN0IHdpZHRoOiBudW1iZXIgPVxuICAgICAgdGhpcy53YXZlU3VyZmVyLnBhcmFtcy5maWxsUGFyZW50ICYmICF0aGlzLndhdmVTdXJmZXIucGFyYW1zLnNjcm9sbFBhcmVudFxuICAgICAgICA/IHRoaXMud2F2ZVN1cmZlci50aW1lbGluZS5kcmF3ZXIuZ2V0V2lkdGgoKVxuICAgICAgICA6IHRoaXMud2F2ZVN1cmZlci50aW1lbGluZS5kcmF3ZXIud3JhcHBlci5zY3JvbGxXaWR0aCAqIHRoaXMud2F2ZVN1cmZlci5wYXJhbXMucGl4ZWxSYXRpbztcblxuICAgIHggPSAod2lkdGggLyBkdXJhdGlvbikgKiB0aGlzLndhdmVTdXJmZXIuZ2V0Q3VycmVudFRpbWUoKSAtIDI7XG5cbiAgICAvLyB1cGRhdGUgdGhlIHRpbWVsaW5lIGNhbnZhc1xuICAgIHRoaXMud2F2ZVN1cmZlci50aW1lbGluZS5yZW5kZXIoKTtcblxuICAgIC8vIGRyYXcgdGhlIGN1cnNvciBvbiB0aGUgdGltZWxpbmVcbiAgICB0aGlzLndhdmVTdXJmZXIudGltZWxpbmUuY2FudmFzZXMuZm9yRWFjaCgoY2FudmFzLCBpKSA9PiB7XG4gICAgICBjb25zdCBsZWZ0T2Zmc2V0ID0gaSAqIHRoaXMud2F2ZVN1cmZlci50aW1lbGluZS5tYXhDYW52YXNXaWR0aDtcblxuICAgICAgY29uc3QgY3R4ID0gY2FudmFzLmdldENvbnRleHQoJzJkJyk7XG5cbiAgICAgIGN0eC5maWxsU3R5bGUgPSAnI2ZkN2UxNCc7XG4gICAgICBjdHguYmVnaW5QYXRoKCk7XG4gICAgICBjdHgubW92ZVRvKHggLSAxMiAtIGxlZnRPZmZzZXQsIDIwKTtcbiAgICAgIGN0eC5saW5lVG8oeCArIDEyIC0gbGVmdE9mZnNldCwgMjApO1xuICAgICAgY3R4LmxpbmVUbyh4IC0gbGVmdE9mZnNldCwgNDUpO1xuICAgICAgY3R4LmZpbGwoKTtcbiAgICB9KTtcbiAgfVxuXG4gIHByaXZhdGUgc3RhcnRUaW1lVXBkYXRlcigpIHtcbiAgICB0aGlzLnN0b3BUaW1lVXBkYXRlcigpO1xuXG4gICAgY29uc3QgdGltZVVwZGF0ZXIgPSB0aW1lcigwLCA0MCk7XG4gICAgdGhpcy50aW1lVXBkYXRlU3Vic2NyaXB0aW9uID0gdGltZVVwZGF0ZXIuc3Vic2NyaWJlKCgpID0+IHtcbiAgICAgIHRoaXMudXBkYXRlQ3VycmVudFRpbWUoKTtcbiAgICB9KTtcbiAgfVxuXG4gIHByaXZhdGUgc3RvcFRpbWVVcGRhdGVyKCkge1xuICAgIGlmICh0aGlzLnRpbWVVcGRhdGVTdWJzY3JpcHRpb24pIHtcbiAgICAgIHRoaXMudGltZVVwZGF0ZVN1YnNjcmlwdGlvbi51bnN1YnNjcmliZSgpO1xuICAgIH1cbiAgfVxuXG4gIGZvcm1hdFRpbWVDYWxsYmFjayhzZWNvbmRzOiBudW1iZXIsIHB4UGVyU2VjOiBudW1iZXIpIHtcbiAgICBpZiAodGhpcy5zZWxlY3RlZENvbXBvc2l0aW9uLmdyaWRUeXBlID09PSAnbXVzaWNhbCcpIHtcbiAgICAgIHJldHVybiBNYXRoLnJvdW5kKHNlY29uZHMgLyB0aGlzLnNlbGVjdGVkQ29tcG9zaXRpb24udGltZVNpZ25hdHVyZVVwcGVyIC8gKDYwIC8gdGhpcy5zZWxlY3RlZENvbXBvc2l0aW9uLmJlYXRzUGVyTWludXRlKSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIC8vIGNhbGN1bGF0ZSBtaW51dGVzIGFuZCBzZWNvbmRzIGZyb20gc2Vjb25kcyBjb3VudFxuICAgICAgY29uc3QgbWludXRlcyA9IHBhcnNlSW50KChzZWNvbmRzIC8gNjApIGFzIGFueSwgMTApO1xuICAgICAgc2Vjb25kcyA9IHBhcnNlSW50KChzZWNvbmRzICUgNjApIGFzIGFueSwgMTApO1xuXG4gICAgICAvLyBmaWxsIHVwIHNlY29uZHMgd2l0aCB6ZXJvZXNcbiAgICAgIGNvbnN0IHNlY29uZHNTdHIgPSBzZWNvbmRzIDwgMTAgPyAnMCcgKyBzZWNvbmRzIDogc2Vjb25kcztcbiAgICAgIHJldHVybiBgJHttaW51dGVzfToke3NlY29uZHNTdHJ9YDtcbiAgICB9XG4gIH1cblxuICB0aW1lSW50ZXJ2YWwocHhQZXJTZWM6IG51bWJlcikge1xuICAgIGlmICh0aGlzLnNlbGVjdGVkQ29tcG9zaXRpb24uZ3JpZFR5cGUgPT09ICdtdXNpY2FsJykge1xuICAgICAgY29uc3QgaW50ZXJ2YWwgPSA2MCAvIHRoaXMuc2VsZWN0ZWRDb21wb3NpdGlvbi5iZWF0c1Blck1pbnV0ZSAvIHRoaXMuc2VsZWN0ZWRDb21wb3NpdGlvbi5ncmlkUmVzb2x1dGlvbjtcblxuICAgICAgaWYgKHB4UGVyU2VjIDwgNDApIHtcbiAgICAgICAgcmV0dXJuIGludGVydmFsICogNDtcbiAgICAgIH0gZWxzZSBpZiAocHhQZXJTZWMgPCA4MCkge1xuICAgICAgICByZXR1cm4gaW50ZXJ2YWwgKiAyO1xuICAgICAgfVxuXG4gICAgICByZXR1cm4gaW50ZXJ2YWw7XG4gICAgfSBlbHNlIHtcbiAgICAgIGlmIChweFBlclNlYyA+PSAyNSkge1xuICAgICAgICByZXR1cm4gMTtcbiAgICAgIH0gZWxzZSBpZiAocHhQZXJTZWMgKiA1ID49IDI1KSB7XG4gICAgICAgIHJldHVybiA1O1xuICAgICAgfSBlbHNlIGlmIChweFBlclNlYyAqIDE1ID49IDI1KSB7XG4gICAgICAgIHJldHVybiAxNTtcbiAgICAgIH1cblxuICAgICAgcmV0dXJuIE1hdGguY2VpbCgwLjUgLyBweFBlclNlYykgKiA2MDtcbiAgICB9XG4gIH1cblxuICBwcmltYXJ5TGFiZWxJbnRlcnZhbChweFBlclNlYzogbnVtYmVyKSB7XG4gICAgaWYgKHRoaXMuc2VsZWN0ZWRDb21wb3NpdGlvbi5ncmlkVHlwZSA9PT0gJ211c2ljYWwnKSB7XG4gICAgICBjb25zdCBpbnRlcnZhbCA9IHRoaXMuc2VsZWN0ZWRDb21wb3NpdGlvbi50aW1lU2lnbmF0dXJlVXBwZXIgKiB0aGlzLnNlbGVjdGVkQ29tcG9zaXRpb24uZ3JpZFJlc29sdXRpb247XG5cbiAgICAgIHJldHVybiBpbnRlcnZhbDtcbiAgICB9IGVsc2Uge1xuICAgICAgaWYgKHB4UGVyU2VjID49IDI1KSB7XG4gICAgICAgIHJldHVybiAxMDtcbiAgICAgIH0gZWxzZSBpZiAocHhQZXJTZWMgKiA1ID49IDI1KSB7XG4gICAgICAgIHJldHVybiA2O1xuICAgICAgfSBlbHNlIGlmIChweFBlclNlYyAqIDE1ID49IDI1KSB7XG4gICAgICAgIHJldHVybiA0O1xuICAgICAgfVxuXG4gICAgICByZXR1cm4gNDtcbiAgICB9XG4gIH1cblxuICBzZWNvbmRhcnlMYWJlbEludGVydmFsKHB4UGVyU2VjOiBudW1iZXIpIHtcbiAgICBpZiAodGhpcy5zZWxlY3RlZENvbXBvc2l0aW9uLmdyaWRUeXBlID09PSAnbXVzaWNhbCcpIHtcbiAgICAgIHJldHVybiAwO1xuICAgIH0gZWxzZSB7XG4gICAgICBpZiAocHhQZXJTZWMgPj0gMjUpIHtcbiAgICAgICAgcmV0dXJuIDU7XG4gICAgICB9IGVsc2UgaWYgKHB4UGVyU2VjICogNSA+PSAyNSkge1xuICAgICAgICByZXR1cm4gMjtcbiAgICAgIH0gZWxzZSBpZiAocHhQZXJTZWMgKiAxNSA+PSAyNSkge1xuICAgICAgICByZXR1cm4gMjtcbiAgICAgIH1cbiAgICAgIHJldHVybiAyO1xuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgc2VlZWtXaXRoVGltZWxpbmUoZTogYW55KSB7XG4gICAgLy8gdGFrZW4gZnJvbSB3YXZlc3VyZmVyIC0+IGRyYXdlciAtPiBoYW5kbGVFdmVudFxuICAgIGNvbnN0IGNsaWVudFggPSBlLnRhcmdldFRvdWNoZXMgPyBlLnRhcmdldFRvdWNoZXNbMF0uY2xpZW50WCA6IGUuY2xpZW50WDtcbiAgICBjb25zdCBiYm94ID0gdGhpcy53YXZlU3VyZmVyLnRpbWVsaW5lLndyYXBwZXIuZ2V0Qm91bmRpbmdDbGllbnRSZWN0KCk7XG5cbiAgICBjb25zdCBub21pbmFsV2lkdGggPSB0aGlzLndhdmVTdXJmZXIudGltZWxpbmUuZHJhd2VyLndpZHRoO1xuICAgIGNvbnN0IHBhcmVudFdpZHRoID0gdGhpcy53YXZlU3VyZmVyLnRpbWVsaW5lLmRyYXdlci5nZXRXaWR0aCgpO1xuXG4gICAgbGV0IHByb2dyZXNzOiBudW1iZXI7XG5cbiAgICBpZiAoIXRoaXMud2F2ZVN1cmZlci50aW1lbGluZS5kcmF3ZXIucGFyYW1zLmZpbGxQYXJlbnQgJiYgbm9taW5hbFdpZHRoIDwgcGFyZW50V2lkdGgpIHtcbiAgICAgIHByb2dyZXNzID1cbiAgICAgICAgKHRoaXMud2F2ZVN1cmZlci50aW1lbGluZS5kcmF3ZXIucGFyYW1zLnJ0bCA/IGJib3gucmlnaHQgLSBjbGllbnRYIDogY2xpZW50WCAtIGJib3gubGVmdCkgKlxuICAgICAgICAgICh0aGlzLndhdmVTdXJmZXIudGltZWxpbmUuZHJhd2VyLnBhcmFtcy5waXhlbFJhdGlvIC8gbm9taW5hbFdpZHRoKSB8fCAwO1xuXG4gICAgICBpZiAocHJvZ3Jlc3MgPiAxKSB7XG4gICAgICAgIHByb2dyZXNzID0gMTtcbiAgICAgIH1cbiAgICB9IGVsc2Uge1xuICAgICAgcHJvZ3Jlc3MgPVxuICAgICAgICAoKHRoaXMud2F2ZVN1cmZlci50aW1lbGluZS5kcmF3ZXIucGFyYW1zLnJ0bCA/IGJib3gucmlnaHQgLSBjbGllbnRYIDogY2xpZW50WCAtIGJib3gubGVmdCkgK1xuICAgICAgICAgIHRoaXMud2F2ZVN1cmZlci50aW1lbGluZS53cmFwcGVyLnNjcm9sbExlZnQpIC9cbiAgICAgICAgICB0aGlzLndhdmVTdXJmZXIudGltZWxpbmUud3JhcHBlci5zY3JvbGxXaWR0aCB8fCAwO1xuICAgIH1cblxuICAgIHByb2dyZXNzID0gTWF0aC5tYXgocHJvZ3Jlc3MsIDApO1xuXG4gICAgc2V0VGltZW91dCgoKSA9PiB7XG4gICAgICB0aGlzLndhdmVTdXJmZXIuc2Vla1RvKHByb2dyZXNzKTtcbiAgICAgIHRoaXMuZGV0ZWN0Q2hhbmdlcy5uZXh0KCk7XG4gICAgICB0aGlzLnByZXNldFNlcnZpY2UucHJldmlld0xpdmUodGhpcy5zZWxlY3RlZENvbXBvc2l0aW9uLm5hbWUsIE1hdGgucm91bmQodGhpcy53YXZlU3VyZmVyLmdldEN1cnJlbnRUaW1lKCkgKiAxMDAwKSk7XG4gICAgfSwgMCk7XG4gIH1cblxuICBhcHBseVpvb20oem9vbTogYW55KSB7XG4gICAgaWYgKHpvb20gPCAwIHx8IHpvb20gPiAyMDApIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICB0aGlzLnpvb20gPSB6b29tO1xuICAgIGlmICh0aGlzLndhdmVTdXJmZXIpIHtcbiAgICAgIHNldFRpbWVvdXQoKCkgPT4ge1xuICAgICAgICB0aGlzLndhdmVTdXJmZXIuem9vbSh0aGlzLnpvb20pO1xuICAgICAgICB0aGlzLnVwZGF0ZUN1cnJlbnRUaW1lKCk7XG4gICAgICB9LCAwKTtcbiAgICB9XG4gIH1cblxuICBwcml2YXRlIGlzV2F2ZVN1cmZlclJlYWR5KCk6IGJvb2xlYW4ge1xuICAgIGlmICghdGhpcy53YXZlU3VyZmVyKSB7XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuXG4gICAgaWYgKCF0aGlzLndhdmVTdXJmZXIuaXNSZWFkeSkge1xuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cblxuICAgIHJldHVybiB0cnVlO1xuICB9XG5cbiAgYWRkUmVnaW9uKHdhdmVTdXJmZXJSZWdpb24/OiBhbnkpIHtcbiAgICBpZiAoIXRoaXMuaXNXYXZlU3VyZmVyUmVhZHkoKSkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGlmICghdGhpcy5zY2VuZVNlcnZpY2Uuc2VsZWN0ZWRTY2VuZXMgfHwgdGhpcy5zY2VuZVNlcnZpY2Uuc2VsZWN0ZWRTY2VuZXMubGVuZ3RoICE9PSAxKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgaWYgKCF0aGlzLnNlbGVjdGVkQ29tcG9zaXRpb24pIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBjb25zdCBzY2VuZVBsYXliYWNrUmVnaW9uOiBTY2VuZVBsYXliYWNrUmVnaW9uID0gbmV3IFNjZW5lUGxheWJhY2tSZWdpb24oKTtcbiAgICBzY2VuZVBsYXliYWNrUmVnaW9uLnNjZW5lVXVpZCA9IHRoaXMuc2NlbmVTZXJ2aWNlLnNlbGVjdGVkU2NlbmVzWzBdLnV1aWQ7XG5cbiAgICBpZiAod2F2ZVN1cmZlclJlZ2lvbikge1xuICAgICAgc2NlbmVQbGF5YmFja1JlZ2lvbi5zdGFydE1pbGxpcyA9IHdhdmVTdXJmZXJSZWdpb24uc3RhcnQgKiAxMDAwO1xuICAgICAgc2NlbmVQbGF5YmFja1JlZ2lvbi5lbmRNaWxsaXMgPSB3YXZlU3VyZmVyUmVnaW9uLmVuZCAqIDEwMDA7XG4gICAgfSBlbHNlIHtcbiAgICAgIHNjZW5lUGxheWJhY2tSZWdpb24uc3RhcnRNaWxsaXMgPSAodGhpcy53YXZlU3VyZmVyLmdldER1cmF0aW9uKCkgKiAxMDAwKSAvIDM7XG4gICAgICBzY2VuZVBsYXliYWNrUmVnaW9uLmVuZE1pbGxpcyA9ICgodGhpcy53YXZlU3VyZmVyLmdldER1cmF0aW9uKCkgKiAxMDAwKSAvIDMpICogMjtcbiAgICB9XG5cbiAgICB0aGlzLnNlbGVjdGVkQ29tcG9zaXRpb24uc2NlbmVQbGF5YmFja1JlZ2lvbnMucHVzaChzY2VuZVBsYXliYWNrUmVnaW9uKTtcblxuICAgIHRoaXMuc2VsZWN0ZWRQbGF5YmFja1JlZ2lvbiA9IHNjZW5lUGxheWJhY2tSZWdpb247XG5cbiAgICBpZiAod2F2ZVN1cmZlclJlZ2lvbikge1xuICAgICAgd2F2ZVN1cmZlclJlZ2lvbi5jb2xvciA9XG4gICAgICAgICdyZ2JhKCcgK1xuICAgICAgICB0aGlzLmhleFRvUmdiKHRoaXMuc2NlbmVTZXJ2aWNlLnNlbGVjdGVkU2NlbmVzWzBdLmNvbG9yKS5yICtcbiAgICAgICAgJywgJyArXG4gICAgICAgIHRoaXMuaGV4VG9SZ2IodGhpcy5zY2VuZVNlcnZpY2Uuc2VsZWN0ZWRTY2VuZXNbMF0uY29sb3IpLmcgK1xuICAgICAgICAnLCAnICtcbiAgICAgICAgdGhpcy5oZXhUb1JnYih0aGlzLnNjZW5lU2VydmljZS5zZWxlY3RlZFNjZW5lc1swXS5jb2xvcikuYiArXG4gICAgICAgICcsICcgK1xuICAgICAgICB0aGlzLmludGVuc2l0eUhpZ2hsaWdodGVkICtcbiAgICAgICAgJyknO1xuICAgICAgd2F2ZVN1cmZlclJlZ2lvbi5hdHRyaWJ1dGVzLnNlbGVjdGFibGUgPSB0cnVlO1xuICAgICAgdGhpcy5jb25uZWN0UmVnaW9uKHdhdmVTdXJmZXJSZWdpb24sIHRoaXMuc2NlbmVTZXJ2aWNlLnNlbGVjdGVkU2NlbmVzWzBdLCBzY2VuZVBsYXliYWNrUmVnaW9uKTtcbiAgICAgIHRoaXMudXBkYXRlUmVnaW9uU2VsZWN0aW9uKCk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMuZHJhd1JlZ2lvbihzY2VuZVBsYXliYWNrUmVnaW9uLCB0aGlzLnNjZW5lU2VydmljZS5zZWxlY3RlZFNjZW5lc1swXSk7XG4gICAgfVxuXG4gICAgdGhpcy5wcmVzZXRTZXJ2aWNlLnByZXZpZXdMaXZlKCk7XG4gIH1cblxuICBwcml2YXRlIGdldFNuYXBUb0dyaWRJbnRlcnZhbCgpOiBudW1iZXIge1xuICAgIGlmICh0aGlzLnNlbGVjdGVkQ29tcG9zaXRpb24uc25hcFRvR3JpZCkge1xuICAgICAgcmV0dXJuIDYwIC8gdGhpcy5zZWxlY3RlZENvbXBvc2l0aW9uLmJlYXRzUGVyTWludXRlIC8gdGhpcy5zZWxlY3RlZENvbXBvc2l0aW9uLmdyaWRSZXNvbHV0aW9uO1xuICAgIH1cblxuICAgIHJldHVybiB1bmRlZmluZWQ7XG4gIH1cblxuICBwcml2YXRlIGdldFNuYXBUb0dyaWRPZmZzZXQoKTogbnVtYmVyIHtcbiAgICByZXR1cm4gdGhpcy5zZWxlY3RlZENvbXBvc2l0aW9uLmdyaWRPZmZzZXRNaWxsaXMgLyAxMDAwO1xuICB9XG5cbiAgZGVsZXRlU2VsZWN0ZWRDb21wb3NpdGlvbigpIHtcbiAgICB0aGlzLnByb2plY3RTZXJ2aWNlLnByb2plY3QuY29tcG9zaXRpb25zLnNwbGljZSh0aGlzLnNlbGVjdGVkQ29tcG9zaXRpb25JbmRleCwgMSk7XG4gICAgdGhpcy5zZWxlY3RlZENvbXBvc2l0aW9uID0gdW5kZWZpbmVkO1xuICAgIHRoaXMuc2VsZWN0ZWRDb21wb3NpdGlvbkluZGV4ID0gdW5kZWZpbmVkO1xuICAgIHRoaXMuZGVzdHJveVdhdmVTdXJmZXIoKTtcbiAgICBpZiAodGhpcy5wcm9qZWN0U2VydmljZS5wcm9qZWN0LmNvbXBvc2l0aW9ucy5sZW5ndGggPiAwKSB7XG4gICAgICB0aGlzLnNlbGVjdENvbXBvc2l0aW9uSW5kZXgoMCk7XG4gICAgfVxuICB9XG5cbiAgZGVzdHJveVdhdmVTdXJmZXIoKSB7XG4gICAgdGhpcy5kdXJhdGlvbiA9IHVuZGVmaW5lZDtcbiAgICB0aGlzLmxvYWRpbmdBdWRpb0ZpbGUgPSBmYWxzZTtcblxuICAgIGlmICh0aGlzLndhdmVTdXJmZXIpIHtcbiAgICAgIHRoaXMud2F2ZVN1cmZlci5kZXN0cm95KCk7XG4gICAgICB0aGlzLndhdmVTdXJmZXIgPSB1bmRlZmluZWQ7XG4gICAgfVxuICB9XG5cbiAgY3JlYXRlV2F2ZVN1cmZlcigpIHtcbiAgICB0aGlzLmRlc3Ryb3lXYXZlU3VyZmVyKCk7XG5cbiAgICBpZiAoIXRoaXMuc2VsZWN0ZWRDb21wb3NpdGlvbi5hdWRpb0ZpbGVOYW1lKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgdGhpcy5sb2FkaW5nQXVkaW9GaWxlID0gdHJ1ZTtcblxuICAgIHNldFRpbWVvdXQoKCkgPT4ge1xuICAgICAgdGhpcy53YXZlU3VyZmVyID0gV2F2ZVN1cmZlci5jcmVhdGUoe1xuICAgICAgICBjb250YWluZXI6ICcjd2F2ZWZvcm0nLFxuICAgICAgICB3YXZlQ29sb3I6ICd3aGl0ZScsXG4gICAgICAgIHByb2dyZXNzQ29sb3I6ICd3aGl0ZScsXG4gICAgICAgIC8vIGJhcldpZHRoOiAyLFxuICAgICAgICBoZWlnaHQ6IDEsXG4gICAgICAgIGludGVyYWN0OiBmYWxzZSxcbiAgICAgICAgLy8gVXNlIGZvciB0aW1lbGluZXMgd2l0aG91dCBzb3VuZC4gV2F2ZSB3aWxsIGJlIGRpc3BsYXllZFxuICAgICAgICAvLyB3cm9uZywgYnV0IHNob3VsZCB3b3JrIGZvciBhIGR1bW15IGF1ZGlvIHdpdGhvdXQgYW55IHdhdmVzLlxuICAgICAgICAvLyBkdXJhdGlvbjogNDAwLFxuICAgICAgICBwbHVnaW5zOiBbXG4gICAgICAgICAgQ3Vyc29yUGx1Z2luLmNyZWF0ZSh7XG4gICAgICAgICAgICAvLyBzaG93VGltZTogdHJ1ZSxcbiAgICAgICAgICAgIG9wYWNpdHk6IDEsXG4gICAgICAgICAgICBjb2xvcjogJyNmZDdlMTQnLFxuICAgICAgICAgICAgaGlkZU9uQmx1cjogZmFsc2UgLyogZG9uJ3Qgc2hvdy9oaWRlIHRoZSBjdXJzb3Igb24gdGhlIHdhdmUgKG9ubHkgb24gdGhlIHRpbWVsaW5lKSAqLyxcbiAgICAgICAgICB9KSxcbiAgICAgICAgICBSZWdpb25zUGx1Z2luLmNyZWF0ZSh7XG4gICAgICAgICAgICBkcmFnU2VsZWN0aW9uOiB7XG4gICAgICAgICAgICAgIHNsb3A6IDUsXG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgY29sb3I6ICcjZmZmJyxcbiAgICAgICAgICAgIHNuYXBUb0dyaWRJbnRlcnZhbDogdGhpcy5nZXRTbmFwVG9HcmlkSW50ZXJ2YWwoKSxcbiAgICAgICAgICAgIHNuYXBUb0dyaWRPZmZzZXQ6IHRoaXMuZ2V0U25hcFRvR3JpZE9mZnNldCgpLFxuICAgICAgICAgIH0pLFxuICAgICAgICAgIFRpbWVMaW5lUGx1Z2luLmNyZWF0ZSh7XG4gICAgICAgICAgICBjb250YWluZXI6ICcjd2F2ZWZvcm0tdGltZWxpbmUnLFxuICAgICAgICAgICAgcHJpbWFyeUZvbnRDb2xvcjogJyNmZmYnLFxuICAgICAgICAgICAgc2Vjb25kYXJ5Rm9udENvbG9yOiAnI2ZmZicsXG4gICAgICAgICAgICBvZmZzZXQ6IHRoaXMuZ2V0U25hcFRvR3JpZE9mZnNldCgpLFxuICAgICAgICAgICAgZm9ybWF0VGltZUNhbGxiYWNrOiB0aGlzLmZvcm1hdFRpbWVDYWxsYmFjay5iaW5kKHRoaXMpLFxuICAgICAgICAgICAgdGltZUludGVydmFsOiB0aGlzLnRpbWVJbnRlcnZhbC5iaW5kKHRoaXMpLFxuICAgICAgICAgICAgcHJpbWFyeUxhYmVsSW50ZXJ2YWw6IHRoaXMucHJpbWFyeUxhYmVsSW50ZXJ2YWwuYmluZCh0aGlzKSxcbiAgICAgICAgICAgIHNlY29uZGFyeUxhYmVsSW50ZXJ2YWw6IHRoaXMuc2Vjb25kYXJ5TGFiZWxJbnRlcnZhbC5iaW5kKHRoaXMpLFxuICAgICAgICAgIH0pLFxuICAgICAgICBdLFxuICAgICAgfSk7XG5cbiAgICAgIGxldCBhdWRpb0ZpbGVOYW1lOiBzdHJpbmc7XG5cbiAgICAgIGlmICh0aGlzLmNvbmZpZ1NlcnZpY2UuZW5hYmxlTWVkaWFMaWJyYXJ5KSB7XG4gICAgICAgIC8vIHRoZSBmaWxlIG5hbWUgaXMgYWxzbyB1c2VkIGZvciB0aGUgcmVhbCBmaWxlIG5hbWVcbiAgICAgICAgYXVkaW9GaWxlTmFtZSA9ICdmaWxlL2dldD9uYW1lPScgKyB0aGlzLnNlbGVjdGVkQ29tcG9zaXRpb24uYXVkaW9GaWxlTmFtZSArICcmdHlwZT1BVURJTyc7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICAvLyB0aGUgY29tcG9zaXRpb24gdXVpZCBhbmQgZXh0ZW5zaW9uIGlzIHVzZWQgYXMgdGhlIGZpbGUgbmFtZVxuICAgICAgICBhdWRpb0ZpbGVOYW1lID1cbiAgICAgICAgICAnY29tcG9zaXRpb24tZmlsZXMvP2ZpbGU9JyArXG4gICAgICAgICAgdGhpcy5zZWxlY3RlZENvbXBvc2l0aW9uLnV1aWQgK1xuICAgICAgICAgICcuJyArXG4gICAgICAgICAgdGhpcy5zZWxlY3RlZENvbXBvc2l0aW9uLmF1ZGlvRmlsZU5hbWUuc3Vic3RyKHRoaXMuc2VsZWN0ZWRDb21wb3NpdGlvbi5hdWRpb0ZpbGVOYW1lLmxhc3RJbmRleE9mKCcuJykgKyAxKTtcbiAgICAgIH1cblxuICAgICAgdGhpcy53YXZlU3VyZmVyLmxvYWQodGhpcy5jb25maWdTZXJ2aWNlLnJlc3RVcmwgKyBhdWRpb0ZpbGVOYW1lKTtcblxuICAgICAgdGhpcy53YXZlU3VyZmVyLm9uKCdyZWFkeScsICgpID0+IHtcbiAgICAgICAgc2V0VGltZW91dCgoKSA9PiB7XG4gICAgICAgICAgLy8gdHJ5IGd1ZXNzaW5nIHRoZSBicG0gYW5kIG9mZnNldCBmcm9tIHRoZSBmaWxlLCBpZiBuZWNlc3NhcnlcbiAgICAgICAgICBpZiAodGhpcy5zZWxlY3RlZENvbXBvc2l0aW9uLnRlbXBvR3Vlc3NlZCkge1xuICAgICAgICAgICAgLy8gd2UgYWxyZWFkeSBndWVzc2VkIHRoZSBCUE0gb2YgdGhpcyBmaWxlIC0tPiBkb24ndCBkbyBpdCBhZ2FpblxuICAgICAgICAgICAgdGhpcy5sb2FkaW5nQXVkaW9GaWxlID0gZmFsc2U7XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIC8vIHdlIGhhdmUgbm90IHlldCBndWVzc2VkIHRoZSBCUE0gLS0+IGRvIGl0IG5vd1xuICAgICAgICAgICAgdGhpcy5zZWxlY3RlZENvbXBvc2l0aW9uLnRlbXBvR3Vlc3NlZCA9IHRydWU7XG4gICAgICAgICAgICBndWVzcyh0aGlzLndhdmVTdXJmZXIuYmFja2VuZC5idWZmZXIpXG4gICAgICAgICAgICAgIC50aGVuKCh7IGJwbSwgb2Zmc2V0IH0pID0+IHtcbiAgICAgICAgICAgICAgICAvLyB0aGUgYnBtIGFuZCBvZmZzZXQgY291bGQgYmUgZ3Vlc3NlZFxuICAgICAgICAgICAgICAgIHRoaXMuc2VsZWN0ZWRDb21wb3NpdGlvbi5iZWF0c1Blck1pbnV0ZSA9IGJwbTtcbiAgICAgICAgICAgICAgICB0aGlzLnNlbGVjdGVkQ29tcG9zaXRpb24uZ3JpZE9mZnNldE1pbGxpcyA9IG9mZnNldCAqIDEwMDA7XG4gICAgICAgICAgICAgICAgdGhpcy5sb2FkaW5nQXVkaW9GaWxlID0gZmFsc2U7XG4gICAgICAgICAgICAgIH0pXG4gICAgICAgICAgICAgIC5jYXRjaCgoZXJyKSA9PiB7XG4gICAgICAgICAgICAgICAgLy8gc29tZXRoaW5nIHdlbnQgd3JvbmdcbiAgICAgICAgICAgICAgICBjb25zb2xlLmVycm9yKCdDb3VsZCBub3QgZGV0ZWN0IHRoZSBCUE0gZnJvbSB0aGUgYXVkaW8gZmlsZScsIGVycik7XG4gICAgICAgICAgICAgICAgdGhpcy5sb2FkaW5nQXVkaW9GaWxlID0gZmFsc2U7XG4gICAgICAgICAgICAgIH0pO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIHRoaXMuZHVyYXRpb24gPSB0aGlzLm1zVG9UaW1lKHRoaXMud2F2ZVN1cmZlci5nZXREdXJhdGlvbigpICogMTAwMCk7XG4gICAgICAgICAgdGhpcy5kcmF3QWxsUmVnaW9ucygpO1xuXG4gICAgICAgICAgLy8gc2Nyb2xsIHdhdmVzdXJmZXIgaW4gc3luYyB3aXRoIHRoZSB0aW1lbGluZVxuICAgICAgICAgIHRoaXMud2F2ZVN1cmZlci50aW1lbGluZS53cmFwcGVyLmFkZEV2ZW50TGlzdGVuZXIoJ3Njcm9sbCcsICgpID0+IHtcbiAgICAgICAgICAgIHRoaXMud2F2ZVN1cmZlci5kcmF3ZXIud3JhcHBlci5zY3JvbGxMZWZ0ID0gdGhpcy53YXZlU3VyZmVyLnRpbWVsaW5lLndyYXBwZXIuc2Nyb2xsTGVmdDtcblxuICAgICAgICAgICAgLy8gU2V0IHRoZSBzY3JvbGwgcG9zaXRpb24gb2YgdGhlIHRpbWVsaW5lIHRvIHRoZSBzYW1lIHBvc2l0aW9uIGFzIHRoZSB3YXZlc3VyZmVyLFxuICAgICAgICAgICAgLy8gYmVjYXVzZSB0aGUgdGltZWxpbmUgaXMgbGFyZ2VyIHRoYW4gd2F2ZXN1cmZlciBhbmQgbWlnaHQgZ2V0IG91dCBvZiBzeW5jLlxuICAgICAgICAgICAgLy8gVGhpcyB3YXksIGlmIHdhdmVzdXJmZXIgY2Fubm90IHNjcm9sbCBhbnkgZnVydGhlciwgd2UgcmVzZXQgdGhlIHBvc2l0aW9uXG4gICAgICAgICAgICAvLyBvZiB0aGUgdGltZWxpbmUgYXMgd2VsbC5cbiAgICAgICAgICAgIHRoaXMud2F2ZVN1cmZlci50aW1lbGluZS53cmFwcGVyLnNjcm9sbExlZnQgPSB0aGlzLndhdmVTdXJmZXIuZHJhd2VyLndyYXBwZXIuc2Nyb2xsTGVmdDtcbiAgICAgICAgICB9KTtcblxuICAgICAgICAgIC8vIGRpc3BsYXkgdGhlIGN1cnNvciBhbHNvIG9uIHRoZSB0aW1lbGluZVxuICAgICAgICAgIHRoaXMud2F2ZVN1cmZlci50aW1lbGluZS53cmFwcGVyLmFkZEV2ZW50TGlzdGVuZXIoJ21vdXNlZW50ZXInLCAoKSA9PiB7XG4gICAgICAgICAgICB0aGlzLndhdmVTdXJmZXIuY3Vyc29yLnNob3dDdXJzb3IoKTtcbiAgICAgICAgICB9KTtcbiAgICAgICAgICB0aGlzLndhdmVTdXJmZXIudGltZWxpbmUud3JhcHBlci5hZGRFdmVudExpc3RlbmVyKCdtb3VzZWxlYXZlJywgKCkgPT4ge1xuICAgICAgICAgICAgdGhpcy53YXZlU3VyZmVyLmN1cnNvci5oaWRlQ3Vyc29yKCk7XG4gICAgICAgICAgfSk7XG4gICAgICAgICAgdGhpcy53YXZlU3VyZmVyLnRpbWVsaW5lLndyYXBwZXIuYWRkRXZlbnRMaXN0ZW5lcignbW91c2Vtb3ZlJywgKGU6IGFueSkgPT4ge1xuICAgICAgICAgICAgY29uc3QgYmJveCA9IHRoaXMud2F2ZVN1cmZlci5jb250YWluZXIuZ2V0Qm91bmRpbmdDbGllbnRSZWN0KCk7XG4gICAgICAgICAgICBjb25zdCB4ID0gZS5jbGllbnRYIC0gYmJveC5sZWZ0O1xuICAgICAgICAgICAgdGhpcy53YXZlU3VyZmVyLmN1cnNvci51cGRhdGVDdXJzb3JQb3NpdGlvbih4LCAwKTtcbiAgICAgICAgICB9KTtcblxuICAgICAgICAgIC8vIGhpZGUgdGhlIGN1cnNvciBvbiB0aGUgd2F2ZSBpbml0aWFsbHkuIGluIGNvbWJpbmF0aW9uIHdpdGggdGhlIHBhcmFtIGhpZGVPbkJsdXIgPSBmYWxzZSxcbiAgICAgICAgICAvLyBpdCB3aWxsIG5ldmVyIGJlIGRpc3BsYXllZCBvbiB0aGUgd2F2ZSBub3cuIHdlIGhhbmRsZSBpdCBvbiB0aGUgdGltZWxpbmUgb25seS5cbiAgICAgICAgICB0aGlzLndhdmVTdXJmZXIuY3Vyc29yLmhpZGVDdXJzb3IoKTtcblxuICAgICAgICAgIC8vIHNlZWsgb24gdGltZWxpbmUtY2xpY2tcbiAgICAgICAgICB0aGlzLndhdmVTdXJmZXIudGltZWxpbmUud3JhcHBlci5hZGRFdmVudExpc3RlbmVyKCdtb3VzZWRvd24nLCAoZTogYW55KSA9PiB7XG4gICAgICAgICAgICB0aGlzLnRpbWVsaW5lQ2xpY2tpbmcgPSB0cnVlO1xuICAgICAgICAgICAgdGhpcy5zZWVla1dpdGhUaW1lbGluZShlKTtcbiAgICAgICAgICB9KTtcblxuICAgICAgICAgIHRoaXMud2F2ZVN1cmZlci50aW1lbGluZS53cmFwcGVyLmFkZEV2ZW50TGlzdGVuZXIoJ21vdXNlbW92ZScsIChlOiBhbnkpID0+IHtcbiAgICAgICAgICAgIGlmICh0aGlzLnRpbWVsaW5lQ2xpY2tpbmcpIHtcbiAgICAgICAgICAgICAgdGhpcy5zZWVla1dpdGhUaW1lbGluZShlKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9KTtcblxuICAgICAgICAgIHRoaXMud2F2ZVN1cmZlci50aW1lbGluZS53cmFwcGVyLmFkZEV2ZW50TGlzdGVuZXIoJ21vdXNldXAnLCAoZTogYW55KSA9PiB7XG4gICAgICAgICAgICB0aGlzLnRpbWVsaW5lQ2xpY2tpbmcgPSBmYWxzZTtcbiAgICAgICAgICB9KTtcblxuICAgICAgICAgIHRoaXMudXBkYXRlQ3VycmVudFRpbWUoKTtcblxuICAgICAgICAgIHRoaXMuZGV0ZWN0Q2hhbmdlcy5uZXh0KCk7XG4gICAgICAgICAgdGhpcy53YXZlU3VyZmVyUmVhZHkubmV4dCgpO1xuICAgICAgICB9LCAwKTtcbiAgICAgIH0pO1xuXG4gICAgICB0aGlzLndhdmVTdXJmZXIub24oJ2Vycm9yJywgKGVycm9yOiBhbnkpID0+IHtcbiAgICAgICAgLy8gY291bGQgbm90IGxvYWQgdGhlIGNvbXBvc2l0aW9uIC0tPiBkZWxldGUgaXRcbiAgICAgICAgLy8gKHRoaXMgbWF5IG9jY3VyLCB3aGVuIHRoZSBjb21wb3NpdGlvbiBoYXMgYmVlbiBkZWxldGVkIGJ1dCB0aGUgcHJvamVjdCBpcyBub3Qgc2F2ZWQgYWZ0ZXJ3YXJkcylcbiAgICAgICAgdGhpcy5kZWxldGVTZWxlY3RlZENvbXBvc2l0aW9uKCk7XG4gICAgICB9KTtcblxuICAgICAgdGhpcy53YXZlU3VyZmVyLm9uKCdzZWVrJywgKCkgPT4ge1xuICAgICAgICB0aGlzLnVwZGF0ZUN1cnJlbnRUaW1lKCk7XG4gICAgICB9KTtcblxuICAgICAgdGhpcy53YXZlU3VyZmVyLm9uKCdwbGF5JywgKCkgPT4ge1xuICAgICAgICB0aGlzLnN0YXJ0VGltZVVwZGF0ZXIoKTtcbiAgICAgIH0pO1xuXG4gICAgICB0aGlzLndhdmVTdXJmZXIub24oJ3BhdXNlJywgKCkgPT4ge1xuICAgICAgICB0aGlzLnN0b3BUaW1lVXBkYXRlcigpO1xuICAgICAgfSk7XG5cbiAgICAgIHRoaXMud2F2ZVN1cmZlci5vbigncmVnaW9uLWNyZWF0ZWQnLCAocmVnaW9uKSA9PiB7XG4gICAgICAgIC8vIHJlZ2lvbiBjcmVhdGVkIGJ5IHNlbGVjdGlvbiBvciBwcm9ncmFtbWF0aWNhbGx5XG4gICAgICAgIGlmICh0aGlzLnNjZW5lU2VydmljZS5zZWxlY3RlZFNjZW5lcyAmJiB0aGlzLnNjZW5lU2VydmljZS5zZWxlY3RlZFNjZW5lcy5sZW5ndGggPT09IDEpIHtcbiAgICAgICAgICBpZiAoIXJlZ2lvbi5kYXRhLmhhbmRsZWQpIHtcbiAgICAgICAgICAgIHRoaXMuYWRkUmVnaW9uKHJlZ2lvbik7XG4gICAgICAgICAgfVxuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIGlmICghcmVnaW9uLmRhdGEuaGFuZGxlZCkge1xuICAgICAgICAgICAgcmVnaW9uLnJlbW92ZSgpO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfSk7XG5cbiAgICAgIHRoaXMud2F2ZVN1cmZlci5vbigncmVnaW9uLXVwZGF0ZWQnLCAocmVnaW9uOiBhbnkpID0+IHtcbiAgICAgICAgdGhpcy5kZXRlY3RDaGFuZ2VzLm5leHQoKTtcbiAgICAgICAgdGhpcy5wcmVzZXRTZXJ2aWNlLnByZXZpZXdMaXZlKCk7XG4gICAgICB9KTtcbiAgICB9LCAwKTtcbiAgfVxuXG4gIHByaXZhdGUgaGV4VG9SZ2IoaGV4OiBzdHJpbmcpIHtcbiAgICBjb25zdCByZXN1bHQgPSAvXiM/KFthLWZcXGRdezJ9KShbYS1mXFxkXXsyfSkoW2EtZlxcZF17Mn0pJC9pLmV4ZWMoaGV4KTtcbiAgICByZXR1cm4gcmVzdWx0XG4gICAgICA/IHtcbiAgICAgICAgICByOiBwYXJzZUludChyZXN1bHRbMV0sIDE2KSxcbiAgICAgICAgICBnOiBwYXJzZUludChyZXN1bHRbMl0sIDE2KSxcbiAgICAgICAgICBiOiBwYXJzZUludChyZXN1bHRbM10sIDE2KSxcbiAgICAgICAgfVxuICAgICAgOiBudWxsO1xuICB9XG5cbiAgcHJpdmF0ZSB1cGRhdGVSZWdpb25TZWxlY3Rpb24oKSB7XG4gICAgaWYgKCF0aGlzLndhdmVTdXJmZXIpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBmb3IgKGNvbnN0IGtleSBvZiBPYmplY3Qua2V5cyh0aGlzLndhdmVTdXJmZXIucmVnaW9ucy5saXN0KSkge1xuICAgICAgY29uc3QgcmVnaW9uOiBhbnkgPSB0aGlzLndhdmVTdXJmZXIucmVnaW9ucy5saXN0W2tleV07XG5cbiAgICAgIC8vIGlmIG5vIHNjZW5lIGlzIHNldCwgdGhlIHJlZ2lvbiBpcyBub3QgdmFsaWQgKGUuZy4gaGFzIGJlZW4gY3JlYXRlZCwgd2hpbGVcbiAgICAgIC8vIG5vIHNjZW5lIGhhcyBiZWVuIHNlbGVjdGVkIGFuZCByZW1vdmUgZGlkIG5vdCB3b3JrIHByb3Blcmx5KVxuICAgICAgaWYgKHJlZ2lvbi5zY2VuZSkge1xuICAgICAgICBsZXQgaW50ZW5zaXR5ID0gdGhpcy5pbnRlbnNpdHk7XG5cbiAgICAgICAgcmVnaW9uLmRyYWcgPSBmYWxzZTtcbiAgICAgICAgcmVnaW9uLnJlc2l6ZSA9IGZhbHNlO1xuICAgICAgICByZWdpb24uYXR0cmlidXRlcy5zZWxlY3RhYmxlID0gZmFsc2U7XG5cbiAgICAgICAgaWYgKHRoaXMuc2NlbmVTZXJ2aWNlLnNjZW5lSXNTZWxlY3RlZChyZWdpb24uc2NlbmUpKSB7XG4gICAgICAgICAgaW50ZW5zaXR5ID0gdGhpcy5pbnRlbnNpdHlTZWxlY3RlZFNjZW5lO1xuICAgICAgICAgIHJlZ2lvbi5kcmFnID0gdHJ1ZTtcbiAgICAgICAgICByZWdpb24ucmVzaXplID0gdHJ1ZTtcbiAgICAgICAgICByZWdpb24uYXR0cmlidXRlcy5zZWxlY3RhYmxlID0gdHJ1ZTtcbiAgICAgICAgfVxuXG4gICAgICAgIHJlZ2lvbi5hdHRyaWJ1dGVzLnNlbGVjdGVkID0gZmFsc2U7XG5cbiAgICAgICAgaWYgKHRoaXMuc2VsZWN0ZWRQbGF5YmFja1JlZ2lvbiAmJiB0aGlzLnNlbGVjdGVkUGxheWJhY2tSZWdpb24gPT09IHJlZ2lvbi5zY2VuZVBsYXliYWNrUmVnaW9uKSB7XG4gICAgICAgICAgaW50ZW5zaXR5ID0gdGhpcy5pbnRlbnNpdHlIaWdobGlnaHRlZDtcbiAgICAgICAgICByZWdpb24uYXR0cmlidXRlcy5zZWxlY3RlZCA9IHRydWU7XG4gICAgICAgIH1cblxuICAgICAgICByZWdpb24uY29sb3IgPVxuICAgICAgICAgICdyZ2JhKCcgK1xuICAgICAgICAgIHRoaXMuaGV4VG9SZ2IocmVnaW9uLnNjZW5lLmNvbG9yKS5yICtcbiAgICAgICAgICAnLCAnICtcbiAgICAgICAgICB0aGlzLmhleFRvUmdiKHJlZ2lvbi5zY2VuZS5jb2xvcikuZyArXG4gICAgICAgICAgJywgJyArXG4gICAgICAgICAgdGhpcy5oZXhUb1JnYihyZWdpb24uc2NlbmUuY29sb3IpLmIgK1xuICAgICAgICAgICcsICcgK1xuICAgICAgICAgIGludGVuc2l0eSArXG4gICAgICAgICAgJyknO1xuICAgICAgICByZWdpb24udXBkYXRlUmVuZGVyKCk7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgdXBkYXRlU2VsZWN0ZWRSZWdpb24oKSB7XG4gICAgaWYgKCF0aGlzLndhdmVTdXJmZXIpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBpZiAoIXRoaXMuc2VsZWN0ZWRQbGF5YmFja1JlZ2lvbikge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGZvciAoY29uc3Qga2V5IG9mIE9iamVjdC5rZXlzKHRoaXMud2F2ZVN1cmZlci5yZWdpb25zLmxpc3QpKSB7XG4gICAgICBjb25zdCByZWdpb246IGFueSA9IHRoaXMud2F2ZVN1cmZlci5yZWdpb25zLmxpc3Rba2V5XTtcblxuICAgICAgaWYgKHRoaXMuc2VsZWN0ZWRQbGF5YmFja1JlZ2lvbiA9PT0gcmVnaW9uLnNjZW5lUGxheWJhY2tSZWdpb24pIHtcbiAgICAgICAgcmVnaW9uLnN0YXJ0ID0gdGhpcy5zZWxlY3RlZFBsYXliYWNrUmVnaW9uLnN0YXJ0TWlsbGlzIC8gMTAwMDtcbiAgICAgICAgcmVnaW9uLmVuZCA9IHRoaXMuc2VsZWN0ZWRQbGF5YmFja1JlZ2lvbi5lbmRNaWxsaXMgLyAxMDAwO1xuICAgICAgICByZWdpb24udXBkYXRlUmVuZGVyKCk7XG4gICAgICAgIGJyZWFrO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgc2V0U2VsZWN0ZWRSZWdpb24oc2NlbmVQbGF5YmFja1JlZ2lvbj86IFNjZW5lUGxheWJhY2tSZWdpb24pIHtcbiAgICBpZiAodGhpcy5zZWxlY3RlZFBsYXliYWNrUmVnaW9uICYmIHRoaXMuc2VsZWN0ZWRQbGF5YmFja1JlZ2lvbiA9PT0gc2NlbmVQbGF5YmFja1JlZ2lvbikge1xuICAgICAgLy8gTm8gdXBkYXRlIHJlcXVpcmVkXG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgaWYgKHNjZW5lUGxheWJhY2tSZWdpb24pIHtcbiAgICAgIHRoaXMuc2VsZWN0ZWRQbGF5YmFja1JlZ2lvbiA9IHNjZW5lUGxheWJhY2tSZWdpb247XG4gICAgfVxuXG4gICAgdGhpcy51cGRhdGVSZWdpb25TZWxlY3Rpb24oKTtcbiAgfVxuXG4gIHByaXZhdGUgZ2V0UmVnaW9uU25hcFRvR3JpZFZhbHVlKHZhbHVlOiBudW1iZXIpOiBudW1iZXIge1xuICAgIC8vIHRoZSByZWdpb25zIHNob3VsZCBzbmFwIHRvIGEgZ3JpZFxuICAgIGNvbnN0IG9mZnNldCA9IHRoaXMuZ2V0U25hcFRvR3JpZE9mZnNldCgpIHx8IDA7XG4gICAgY29uc3QgaW50ZXJ2YWwgPSB0aGlzLmdldFNuYXBUb0dyaWRJbnRlcnZhbCgpIHx8IDA7XG4gICAgcmV0dXJuIE1hdGgucm91bmQoKHZhbHVlIC0gb2Zmc2V0KSAvIGludGVydmFsKSAqIGludGVydmFsICsgb2Zmc2V0O1xuICB9XG5cbiAgcHJpdmF0ZSBjb25uZWN0UmVnaW9uKHdhdmVTdXJmZXJSZWdpb246IGFueSwgc2NlbmU6IFNjZW5lLCBzY2VuZVBsYXliYWNrUmVnaW9uOiBTY2VuZVBsYXliYWNrUmVnaW9uLCBwcmVzZXQ/OiBQcmVzZXQpIHtcbiAgICB3YXZlU3VyZmVyUmVnaW9uLnNjZW5lUGxheWJhY2tSZWdpb24gPSBzY2VuZVBsYXliYWNrUmVnaW9uO1xuICAgIHdhdmVTdXJmZXJSZWdpb24uc2NlbmUgPSBzY2VuZTtcbiAgICB3YXZlU3VyZmVyUmVnaW9uLnByZXNldCA9IHByZXNldDtcblxuICAgIHdhdmVTdXJmZXJSZWdpb24ub24oJ2NsaWNrJywgKGV2ZW50KSA9PiB7XG4gICAgICBpZiAodGhpcy5zY2VuZVNlcnZpY2Uuc2NlbmVJc1NlbGVjdGVkKHNjZW5lKSkge1xuICAgICAgICB0aGlzLnNldFNlbGVjdGVkUmVnaW9uKHNjZW5lUGxheWJhY2tSZWdpb24pO1xuICAgICAgfVxuICAgIH0pO1xuXG4gICAgd2F2ZVN1cmZlclJlZ2lvbi5vbigndXBkYXRlJywgKCkgPT4ge1xuICAgICAgdGhpcy5zZXRTZWxlY3RlZFJlZ2lvbihzY2VuZVBsYXliYWNrUmVnaW9uKTtcbiAgICAgIGlmICh0aGlzLnNlbGVjdGVkQ29tcG9zaXRpb24uc25hcFRvR3JpZCkge1xuICAgICAgICAvLyB1cGRhdGUgdGhlIHJlZ2lvbnMgYm91bmRhcmllcy4gdGhleSBtYXkgbm90IHNuYXAgdG8gZ3JpZCwgaWYgaXQgaGFzIGJlZW5cbiAgICAgICAgLy8gZGlzYWJsZWQgZHVyaW5nIGNyZWF0aW9uIG9mIHRoZSByZWdpb24gYnV0IGFjdGl2YXRlZCBhZnRlcndhcmRzLlxuICAgICAgICB3YXZlU3VyZmVyUmVnaW9uLnN0YXJ0ID0gdGhpcy5nZXRSZWdpb25TbmFwVG9HcmlkVmFsdWUod2F2ZVN1cmZlclJlZ2lvbi5zdGFydCk7XG4gICAgICAgIHdhdmVTdXJmZXJSZWdpb24uZW5kID0gdGhpcy5nZXRSZWdpb25TbmFwVG9HcmlkVmFsdWUod2F2ZVN1cmZlclJlZ2lvbi5lbmQpO1xuICAgICAgfVxuICAgICAgc2NlbmVQbGF5YmFja1JlZ2lvbi5zdGFydE1pbGxpcyA9IHdhdmVTdXJmZXJSZWdpb24uc3RhcnQgKiAxMDAwO1xuICAgICAgc2NlbmVQbGF5YmFja1JlZ2lvbi5lbmRNaWxsaXMgPSB3YXZlU3VyZmVyUmVnaW9uLmVuZCAqIDEwMDA7XG4gICAgfSk7XG4gIH1cblxuICBwcml2YXRlIGRyYXdSZWdpb24oc2NlbmVQbGF5YmFja1JlZ2lvbjogU2NlbmVQbGF5YmFja1JlZ2lvbiwgc2NlbmU6IFNjZW5lKSB7XG4gICAgLy8gZHJhdyB0aGUgcmVnaW9ucyBvZiB0aGUgY3VycmVudGx5IHNlbGVjdGVkIHNjZW5lXG4gICAgaWYgKCF0aGlzLmlzV2F2ZVN1cmZlclJlYWR5KCkpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICAvLyBhZGQgdGhlIHBsYXliYWNrIHJlZ2lvblxuICAgIGNvbnN0IHdhdmVTdXJmZXJSZWdpb24gPSB0aGlzLndhdmVTdXJmZXIuYWRkUmVnaW9uKHtcbiAgICAgIHN0YXJ0OiBzY2VuZVBsYXliYWNrUmVnaW9uLnN0YXJ0TWlsbGlzIC8gMTAwMCxcbiAgICAgIGVuZDogc2NlbmVQbGF5YmFja1JlZ2lvbi5lbmRNaWxsaXMgLyAxMDAwLFxuICAgICAgY29sb3I6ICcjZmZmJyxcbiAgICAgIGRhdGE6IHsgaGFuZGxlZDogdHJ1ZSB9LFxuICAgIH0pO1xuICAgIHRoaXMuY29ubmVjdFJlZ2lvbih3YXZlU3VyZmVyUmVnaW9uLCBzY2VuZSwgc2NlbmVQbGF5YmFja1JlZ2lvbik7XG5cbiAgICAvLyBUT0RPIHNob3cgdGhlIGFsbCBwcmVzZXRzXG4gICAgLy8gZm9yIChsZXQgcHJlc2V0VXVpZCBvZiBzY2VuZS5wcmVzZXRVdWlkcykge1xuICAgIC8vICAgY29uc3QgcHJlc2V0ID0gdGhpcy5wcmVzZXRTZXJ2aWNlLmdldFByZXNldEJ5VXVpZChwcmVzZXRVdWlkKTtcblxuICAgIC8vICAgbGV0IHdhdmVTdXJmZXJSZWdpb24gPSB0aGlzLnRpbWVsaW5lU2VydmljZS53YXZlU3VyZmVyLmFkZFJlZ2lvbih7XG4gICAgLy8gICAgIHN0YXJ0OiAoc2NlbmVQbGF5YmFja1JlZ2lvbi5zdGFydE1pbGxpcyArIChwcmVzZXQuc3RhcnRNaWxsaXMgPyBwcmVzZXQuc3RhcnRNaWxsaXMgOiAwKSkgLyAxMDAwLFxuICAgIC8vICAgICBlbmQ6IChzY2VuZVBsYXliYWNrUmVnaW9uLnN0YXJ0TWlsbGlzXG4gICAgLy8gICAgICAgKyAocHJlc2V0LmVuZE1pbGxpcyA/IHByZXNldC5lbmRNaWxsaXMgOiBzY2VuZVBsYXliYWNrUmVnaW9uLmVuZE1pbGxpcyAtIHNjZW5lUGxheWJhY2tSZWdpb24uc3RhcnRNaWxsaXMpKSAvIDEwMDAsXG4gICAgLy8gICAgIGNvbG9yOiAnI2ZmZicsXG4gICAgLy8gICAgIGRhdGE6IHsgaGFuZGxlZDogdHJ1ZSB9LFxuICAgIC8vICAgICAvLyBUT0RPXG4gICAgLy8gICAgIGF0dHJpYnV0ZXM6IHtcbiAgICAvLyAgICAgICBwcmVzZXQ6IHRydWUsXG4gICAgLy8gICAgICAgbmFtZTogJ1ByZXNldCAxJ1xuICAgIC8vICAgICB9XG4gICAgLy8gICB9KTtcbiAgICAvLyAgIHRoaXMuY29ubmVjdFJlZ2lvbih3YXZlU3VyZmVyUmVnaW9uLCBzY2VuZSwgc2NlbmVQbGF5YmFja1JlZ2lvbiwgcHJlc2V0KTtcbiAgICAvLyB9XG5cbiAgICB0aGlzLnVwZGF0ZVJlZ2lvblNlbGVjdGlvbigpO1xuICB9XG5cbiAgcmVtb3ZlUmVnaW9uKCkge1xuICAgIGlmICghdGhpcy5zZWxlY3RlZFBsYXliYWNrUmVnaW9uKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgaWYgKHRoaXMuc2NlbmVTZXJ2aWNlLnNlbGVjdGVkU2NlbmVzLmxlbmd0aCAhPT0gMSkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgdGhpcy5zZWxlY3RlZENvbXBvc2l0aW9uLnNjZW5lUGxheWJhY2tSZWdpb25zLmxlbmd0aDsgaSsrKSB7XG4gICAgICBpZiAodGhpcy5zZWxlY3RlZENvbXBvc2l0aW9uLnNjZW5lUGxheWJhY2tSZWdpb25zW2ldID09PSB0aGlzLnNlbGVjdGVkUGxheWJhY2tSZWdpb24pIHtcbiAgICAgICAgLy8gcmVtb3ZlIHRoZSByZWdpb24gZnJvbSB3YXZlc3VyZmVyXG4gICAgICAgIGZvciAoY29uc3Qga2V5IG9mIE9iamVjdC5rZXlzKHRoaXMud2F2ZVN1cmZlci5yZWdpb25zLmxpc3QpKSB7XG4gICAgICAgICAgY29uc3QgcmVnaW9uOiBhbnkgPSB0aGlzLndhdmVTdXJmZXIucmVnaW9ucy5saXN0W2tleV07XG5cbiAgICAgICAgICBpZiAocmVnaW9uLnNjZW5lUGxheWJhY2tSZWdpb24gPT09IHRoaXMuc2VsZWN0ZWRQbGF5YmFja1JlZ2lvbikge1xuICAgICAgICAgICAgcmVnaW9uLnJlbW92ZSgpO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIHRoaXMuc2VsZWN0ZWRQbGF5YmFja1JlZ2lvbiA9IHVuZGVmaW5lZDtcbiAgICAgICAgdGhpcy5zZWxlY3RlZENvbXBvc2l0aW9uLnNjZW5lUGxheWJhY2tSZWdpb25zLnNwbGljZShpLCAxKTtcblxuICAgICAgICByZXR1cm47XG4gICAgICB9XG4gICAgfVxuXG4gICAgdGhpcy5wcmVzZXRTZXJ2aWNlLnByZXZpZXdMaXZlKCk7XG4gIH1cblxuICBnZXRQcmVzZXRzSW5UaW1lKHRpbWVNaWxsaXM6IG51bWJlcik6IFByZXNldFJlZ2lvblNjZW5lW10ge1xuICAgIC8vIFJldHVybiBhbGwgcHJlc2V0cyB3aGljaCBzaG91bGQgYmUgYWN0aXZlIGR1cmluZyB0aGUgc3BlY2lmaWVkIHRpbWVcbiAgICBjb25zdCBhY3RpdmVQcmVzZXRzOiBQcmVzZXRSZWdpb25TY2VuZVtdID0gW107XG5cbiAgICBmb3IgKGxldCBzY2VuZUluZGV4ID0gdGhpcy5wcm9qZWN0U2VydmljZS5wcm9qZWN0LnNjZW5lcy5sZW5ndGggLSAxOyBzY2VuZUluZGV4ID49IDA7IHNjZW5lSW5kZXgtLSkge1xuICAgICAgY29uc3Qgc2NlbmUgPSB0aGlzLnByb2plY3RTZXJ2aWNlLnByb2plY3Quc2NlbmVzW3NjZW5lSW5kZXhdO1xuXG4gICAgICBmb3IgKGNvbnN0IHJlZ2lvbiBvZiB0aGlzLnNlbGVjdGVkQ29tcG9zaXRpb24uc2NlbmVQbGF5YmFja1JlZ2lvbnMpIHtcbiAgICAgICAgaWYgKHJlZ2lvbi5zY2VuZVV1aWQgPT09IHNjZW5lLnV1aWQpIHtcbiAgICAgICAgICBmb3IgKGxldCBwcmVzZXRJbmRleCA9IHRoaXMucHJvamVjdFNlcnZpY2UucHJvamVjdC5wcmVzZXRzLmxlbmd0aCAtIDE7IHByZXNldEluZGV4ID49IDA7IHByZXNldEluZGV4LS0pIHtcbiAgICAgICAgICAgIGZvciAoY29uc3QgcHJlc2V0VXVpZCBvZiBzY2VuZS5wcmVzZXRVdWlkcykge1xuICAgICAgICAgICAgICBpZiAocHJlc2V0VXVpZCA9PT0gdGhpcy5wcm9qZWN0U2VydmljZS5wcm9qZWN0LnByZXNldHNbcHJlc2V0SW5kZXhdLnV1aWQpIHtcbiAgICAgICAgICAgICAgICBjb25zdCBwcmVzZXQgPSB0aGlzLnByZXNldFNlcnZpY2UuZ2V0UHJlc2V0QnlVdWlkKHByZXNldFV1aWQpO1xuXG4gICAgICAgICAgICAgICAgaWYgKHByZXNldCkge1xuICAgICAgICAgICAgICAgICAgbGV0IHByZXNldFN0YXJ0TWlsbGlzID0gcHJlc2V0LnN0YXJ0TWlsbGlzID09PSB1bmRlZmluZWQgPyByZWdpb24uc3RhcnRNaWxsaXMgOiByZWdpb24uc3RhcnRNaWxsaXMgKyBwcmVzZXQuc3RhcnRNaWxsaXM7XG4gICAgICAgICAgICAgICAgICBsZXQgcHJlc2V0RW5kTWlsbGlzID0gcHJlc2V0LmVuZE1pbGxpcyA9PT0gdW5kZWZpbmVkID8gcmVnaW9uLmVuZE1pbGxpcyA6IHJlZ2lvbi5zdGFydE1pbGxpcyArIHByZXNldC5lbmRNaWxsaXM7XG5cbiAgICAgICAgICAgICAgICAgIC8vIGV4dGVuZCB0aGUgcnVubmluZyB0aW1lLCBpZiBmYWRpbmcgaXMgZG9uZSBvdXRzaWRlIHRoZSBib3VuZGFyaWVzXG4gICAgICAgICAgICAgICAgICBwcmVzZXRTdGFydE1pbGxpcyAtPSBwcmVzZXQuZmFkZUluUHJlID8gcHJlc2V0LmZhZGVJbk1pbGxpcyA6IDA7XG4gICAgICAgICAgICAgICAgICBwcmVzZXRFbmRNaWxsaXMgKz0gcHJlc2V0LmZhZGVPdXRQb3N0ID8gcHJlc2V0LmZhZGVPdXRNaWxsaXMgOiAwO1xuXG4gICAgICAgICAgICAgICAgICBpZiAocHJlc2V0U3RhcnRNaWxsaXMgPD0gdGltZU1pbGxpcyAmJiBwcmVzZXRFbmRNaWxsaXMgPj0gdGltZU1pbGxpcykge1xuICAgICAgICAgICAgICAgICAgICBhY3RpdmVQcmVzZXRzLnB1c2gobmV3IFByZXNldFJlZ2lvblNjZW5lKHByZXNldCwgcmVnaW9uLCBzY2VuZSkpO1xuICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cblxuICAgIHJldHVybiBhY3RpdmVQcmVzZXRzO1xuICB9XG5cbiAgZHJhd0FsbFJlZ2lvbnMoKSB7XG4gICAgaWYgKCF0aGlzLnNlbGVjdGVkQ29tcG9zaXRpb24pIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICAvLyBkcmF3IHRoZSByZWdpb25zIGluIHRoZSBzYW1lIG9yZGVyIGFzIHRoZWlyIGNvcnJlc3BvbmRpbmcgc2NlbmVzLCBidXQgZHJhd1xuICAgIC8vIHRoZSBzZWxlY3RlZCBvbmVzIGxhc3QsIHRvIG1ha2Ugc3VyZSB0aGV5J3JlIGFsd2F5cyBjbGlja2FibGUuXG4gICAgZm9yIChsZXQgc2NlbmVJbmRleCA9IHRoaXMucHJvamVjdFNlcnZpY2UucHJvamVjdC5zY2VuZXMubGVuZ3RoIC0gMTsgc2NlbmVJbmRleCA+PSAwOyBzY2VuZUluZGV4LS0pIHtcbiAgICAgIGNvbnN0IHNjZW5lID0gdGhpcy5wcm9qZWN0U2VydmljZS5wcm9qZWN0LnNjZW5lc1tzY2VuZUluZGV4XTtcbiAgICAgIGlmICghdGhpcy5zY2VuZVNlcnZpY2Uuc2NlbmVJc1NlbGVjdGVkKHNjZW5lKSkge1xuICAgICAgICBmb3IgKGNvbnN0IHNjZW5lUGxheWJhY2tSZWdpb24gb2YgdGhpcy5zZWxlY3RlZENvbXBvc2l0aW9uLnNjZW5lUGxheWJhY2tSZWdpb25zKSB7XG4gICAgICAgICAgaWYgKHNjZW5lUGxheWJhY2tSZWdpb24uc2NlbmVVdWlkID09PSBzY2VuZS51dWlkKSB7XG4gICAgICAgICAgICB0aGlzLmRyYXdSZWdpb24oc2NlbmVQbGF5YmFja1JlZ2lvbiwgc2NlbmUpO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cblxuICAgIC8vIGRyYXcgYWxsIHNlbGVjdGVkIHNjZW5lcyBhZnRlcndhcmRzXG4gICAgZm9yIChsZXQgc2NlbmVJbmRleCA9IHRoaXMucHJvamVjdFNlcnZpY2UucHJvamVjdC5zY2VuZXMubGVuZ3RoIC0gMTsgc2NlbmVJbmRleCA+PSAwOyBzY2VuZUluZGV4LS0pIHtcbiAgICAgIGNvbnN0IHNjZW5lID0gdGhpcy5wcm9qZWN0U2VydmljZS5wcm9qZWN0LnNjZW5lc1tzY2VuZUluZGV4XTtcblxuICAgICAgaWYgKHRoaXMuc2NlbmVTZXJ2aWNlLnNjZW5lSXNTZWxlY3RlZChzY2VuZSkpIHtcbiAgICAgICAgZm9yIChjb25zdCBzY2VuZVBsYXliYWNrUmVnaW9uIG9mIHRoaXMuc2VsZWN0ZWRDb21wb3NpdGlvbi5zY2VuZVBsYXliYWNrUmVnaW9ucykge1xuICAgICAgICAgIGlmIChzY2VuZVBsYXliYWNrUmVnaW9uLnNjZW5lVXVpZCA9PT0gc2NlbmUudXVpZCkge1xuICAgICAgICAgICAgdGhpcy5kcmF3UmVnaW9uKHNjZW5lUGxheWJhY2tSZWdpb24sIHNjZW5lKTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICB1cGRhdGVHcmlkKCkge1xuICAgIGlmICh0aGlzLndhdmVTdXJmZXJSZWFkeSkge1xuICAgICAgdGhpcy53YXZlU3VyZmVyLnRpbWVsaW5lLnBhcmFtcy5vZmZzZXQgPSB0aGlzLmdldFNuYXBUb0dyaWRPZmZzZXQoKTtcblxuICAgICAgdGhpcy53YXZlU3VyZmVyLnJlZ2lvbnMucGFyYW1zLnNuYXBUb0dyaWRJbnRlcnZhbCA9IHRoaXMuZ2V0U25hcFRvR3JpZEludGVydmFsKCk7XG4gICAgICB0aGlzLndhdmVTdXJmZXIucmVnaW9ucy5wYXJhbXMuc25hcFRvR3JpZE9mZnNldCA9IHRoaXMuZ2V0U25hcFRvR3JpZE9mZnNldCgpO1xuICAgIH1cbiAgICB0aGlzLnVwZGF0ZUN1cnJlbnRUaW1lKCk7XG4gIH1cblxuICBnZXRFeHRlcm5hbENvbXBvc2l0aW9uTmFtZXMoKTogT2JzZXJ2YWJsZTxzdHJpbmdbXT4ge1xuICAgIC8vIGdldCBhdmFpbGFibGUgY29tcG9zaXRpb25zIGZyb20gYW4gZXh0ZXJuYWwgcG9vbCAoZS5nLiBSb2NrZXQgU2hvdylcbiAgICByZXR1cm4gdGhpcy5odHRwLmdldCgnY29tcG9zaXRpb24vbGlzdCcpLnBpcGUoXG4gICAgICBtYXAoKHJlc3BvbnNlOiBvYmplY3RbXSkgPT4ge1xuICAgICAgICBjb25zdCBjb21wb3NpdGlvbk5hbWVzOiBzdHJpbmdbXSA9IFtdO1xuXG4gICAgICAgIGZvciAoY29uc3QgcmVzcG9uc2VDb21wb3NpdGlvbiBvZiByZXNwb25zZSkge1xuICAgICAgICAgIGNvbXBvc2l0aW9uTmFtZXMucHVzaCgocmVzcG9uc2VDb21wb3NpdGlvbiBhcyBhbnkpLm5hbWUpO1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIGNvbXBvc2l0aW9uTmFtZXM7XG4gICAgICB9KVxuICAgICk7XG4gIH1cblxuICBzZWxlY3RDb21wb3NpdGlvbkluZGV4KGluZGV4OiBudW1iZXIpIHtcbiAgICB0aGlzLnNlbGVjdGVkQ29tcG9zaXRpb24gPSB0aGlzLnByb2plY3RTZXJ2aWNlLnByb2plY3QuY29tcG9zaXRpb25zW2luZGV4XTtcbiAgICB0aGlzLnNlbGVjdGVkQ29tcG9zaXRpb25JbmRleCA9IGluZGV4O1xuICAgIHRoaXMucHJvamVjdFNlcnZpY2UucHJvamVjdC5zZWxlY3RlZENvbXBvc2l0aW9uVXVpZCA9IHRoaXMuc2VsZWN0ZWRDb21wb3NpdGlvbi51dWlkO1xuICAgIHRoaXMuY3JlYXRlV2F2ZVN1cmZlcigpO1xuXG4gICAgLy8gcmVxdWlyZWQgdG8gdHJpZ2dlciB0aW1lbGluZS5jb21wb25lbnQucmVzaXplKClcbiAgICB0aGlzLndhdmVTdXJmZXJSZWFkeS5uZXh0KCk7XG5cbiAgICB0aGlzLmFwcGx5Wm9vbSgwKTtcbiAgfVxufVxuIl19