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