@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.
- package/esm2022/lib/array-sort-pipe.mjs +30 -0
- package/esm2022/lib/designer.component.mjs +605 -0
- package/esm2022/lib/designer.module.mjs +183 -0
- package/esm2022/lib/designer.service.mjs +14 -0
- package/esm2022/lib/effect/effect-curve/effect-curve.component.mjs +569 -0
- package/esm2022/lib/effect/effect-pan-tilt/effect-pan-tilt.component.mjs +36 -0
- package/esm2022/lib/effect/effect.component.mjs +174 -0
- package/esm2022/lib/error-dialog/error-dialog.component.mjs +75 -0
- package/esm2022/lib/fixture/fixture-capability/fixture-capability-channel/fixture-capability-channel.component.mjs +222 -0
- package/esm2022/lib/fixture/fixture-capability/fixture-capability-color/fixture-capability-color.component.mjs +147 -0
- package/esm2022/lib/fixture/fixture-capability/fixture-capability-color-wheel/fixture-capability-color-wheel.component.mjs +213 -0
- package/esm2022/lib/fixture/fixture-capability/fixture-capability-dimmer/fixture-capability-dimmer.component.mjs +78 -0
- package/esm2022/lib/fixture/fixture-capability/fixture-capability-pan-tilt/fixture-capability-pan-tilt.component.mjs +119 -0
- package/esm2022/lib/fixture/fixture-capability/fixture-capability.component.mjs +169 -0
- package/esm2022/lib/fixture/fixture-channel/fixture-channel.component.mjs +160 -0
- package/esm2022/lib/fixture/fixture-settings/fixture-settings-position/fixture-settings-position.component.mjs +365 -0
- package/esm2022/lib/fixture/fixture-settings/fixture-settings-stage/fixture-settings-stage.component.mjs +151 -0
- package/esm2022/lib/fixture/fixture-settings/fixture-settings.component.mjs +46 -0
- package/esm2022/lib/fixture/fixture.component.mjs +138 -0
- package/esm2022/lib/fixture-pool/fixture-pool-create-from-file/fixture-pool-create-from-file.component.mjs +145 -0
- package/esm2022/lib/fixture-pool/fixture-pool.component.mjs +589 -0
- package/esm2022/lib/intro/intro.component.mjs +95 -0
- package/esm2022/lib/master-dimmer/master-dimmer.component.mjs +66 -0
- package/esm2022/lib/models/cached-fixture-capability.mjs +9 -0
- package/esm2022/lib/models/cached-fixture-channel.mjs +7 -0
- package/esm2022/lib/models/cached-fixture.mjs +6 -0
- package/esm2022/lib/models/color.mjs +8 -0
- package/esm2022/lib/models/composition.mjs +46 -0
- package/esm2022/lib/models/effect-curve-profile-channel.mjs +15 -0
- package/esm2022/lib/models/effect-curve.mjs +69 -0
- package/esm2022/lib/models/effect-pan-tilt.mjs +19 -0
- package/esm2022/lib/models/effect.mjs +12 -0
- package/esm2022/lib/models/fixture-capability-value.mjs +15 -0
- package/esm2022/lib/models/fixture-capability.mjs +84 -0
- package/esm2022/lib/models/fixture-channel-value.mjs +11 -0
- package/esm2022/lib/models/fixture-channel.mjs +24 -0
- package/esm2022/lib/models/fixture-mode.mjs +14 -0
- package/esm2022/lib/models/fixture-profile.mjs +70 -0
- package/esm2022/lib/models/fixture-wheel-slot.mjs +26 -0
- package/esm2022/lib/models/fixture-wheel.mjs +15 -0
- package/esm2022/lib/models/fixture.mjs +40 -0
- package/esm2022/lib/models/preset-region-scene.mjs +8 -0
- package/esm2022/lib/models/preset.mjs +56 -0
- package/esm2022/lib/models/project.mjs +68 -0
- package/esm2022/lib/models/scene-playback-region.mjs +11 -0
- package/esm2022/lib/models/scene.mjs +27 -0
- package/esm2022/lib/models/universe.mjs +11 -0
- package/esm2022/lib/preset/preset-settings/preset-settings.component.mjs +194 -0
- package/esm2022/lib/preset/preset.component.mjs +131 -0
- package/esm2022/lib/preview/models/color-changer-3d.mjs +167 -0
- package/esm2022/lib/preview/models/fixture-3d.mjs +150 -0
- package/esm2022/lib/preview/models/moving-head-3d.mjs +243 -0
- package/esm2022/lib/preview/preview.component.mjs +212 -0
- package/esm2022/lib/project/project-browser/project-browser.component.mjs +143 -0
- package/esm2022/lib/project/project-import/project-import.component.mjs +107 -0
- package/esm2022/lib/project/project-save/project-save.component.mjs +178 -0
- package/esm2022/lib/project/project-share/project-share.component.mjs +71 -0
- package/esm2022/lib/scene/scene-settings/scene-settings.component.mjs +146 -0
- package/esm2022/lib/scene/scene.component.mjs +110 -0
- package/esm2022/lib/services/animation.service.mjs +16 -0
- package/esm2022/lib/services/config.service.mjs +27 -0
- package/esm2022/lib/services/effect.service.mjs +14 -0
- package/esm2022/lib/services/error-dialog.service.mjs +39 -0
- package/esm2022/lib/services/fixture-pool.service.mjs +30 -0
- package/esm2022/lib/services/fixture.service.mjs +431 -0
- package/esm2022/lib/services/hotkey-target-exclude.service.mjs +24 -0
- package/esm2022/lib/services/intro.service.mjs +140 -0
- package/esm2022/lib/services/preset.service.mjs +400 -0
- package/esm2022/lib/services/preview-mesh.service.mjs +57 -0
- package/esm2022/lib/services/preview.service.mjs +496 -0
- package/esm2022/lib/services/project-load.service.mjs +149 -0
- package/esm2022/lib/services/project.service.mjs +97 -0
- package/esm2022/lib/services/scene.service.mjs +164 -0
- package/esm2022/lib/services/timeline.service.mjs +726 -0
- package/esm2022/lib/services/universe.service.mjs +23 -0
- package/esm2022/lib/services/user-ensure-login.service.mjs +38 -0
- package/esm2022/lib/services/user.service.mjs +89 -0
- package/esm2022/lib/services/uuid.service.mjs +23 -0
- package/esm2022/lib/services/warning-dialog.service.mjs +38 -0
- package/esm2022/lib/timeline/composition-settings/composition-settings.component.mjs +334 -0
- package/esm2022/lib/timeline/timeline-grid/timeline-grid.component.mjs +216 -0
- package/esm2022/lib/timeline/timeline.component.mjs +418 -0
- package/esm2022/lib/user/user-login/user-login.component.mjs +144 -0
- package/esm2022/lib/user/user-register/user-register.component.mjs +220 -0
- package/esm2022/lib/wait-dialog/wait-dialog.component.mjs +26 -0
- package/esm2022/lib/warning-dialog/warning-dialog.component.mjs +68 -0
- package/esm2022/public_api.mjs +7 -0
- package/esm2022/rocketshow-designer.mjs +5 -0
- package/fesm2022/rocketshow-designer.mjs +10626 -0
- package/fesm2022/rocketshow-designer.mjs.map +1 -0
- package/index.d.ts +5 -0
- package/lib/array-sort-pipe.d.ts +3 -0
- package/lib/designer.component.d.ts +15 -12
- package/lib/designer.module.d.ts +54 -0
- package/lib/designer.service.d.ts +3 -0
- package/lib/effect/effect-curve/effect-curve.component.d.ts +4 -1
- package/lib/effect/effect-pan-tilt/effect-pan-tilt.component.d.ts +3 -0
- package/lib/effect/effect.component.d.ts +3 -0
- package/lib/error-dialog/error-dialog.component.d.ts +3 -0
- package/lib/fixture/fixture-capability/fixture-capability-channel/fixture-capability-channel.component.d.ts +4 -1
- package/lib/fixture/fixture-capability/fixture-capability-color/fixture-capability-color.component.d.ts +3 -0
- package/lib/fixture/fixture-capability/fixture-capability-color-wheel/fixture-capability-color-wheel.component.d.ts +5 -2
- package/lib/fixture/fixture-capability/fixture-capability-dimmer/fixture-capability-dimmer.component.d.ts +3 -0
- package/lib/fixture/fixture-capability/fixture-capability-pan-tilt/fixture-capability-pan-tilt.component.d.ts +3 -0
- package/lib/fixture/fixture-capability/fixture-capability.component.d.ts +3 -0
- package/lib/fixture/fixture-channel/fixture-channel.component.d.ts +3 -0
- package/lib/fixture/fixture-settings/fixture-settings-position/fixture-settings-position.component.d.ts +3 -0
- package/lib/fixture/fixture-settings/fixture-settings-stage/fixture-settings-stage.component.d.ts +3 -0
- package/lib/fixture/fixture-settings/fixture-settings.component.d.ts +3 -0
- package/lib/fixture/fixture.component.d.ts +3 -0
- package/lib/fixture-pool/fixture-pool-create-from-file/fixture-pool-create-from-file.component.d.ts +3 -0
- package/lib/fixture-pool/fixture-pool.component.d.ts +3 -0
- package/lib/intro/intro.component.d.ts +3 -0
- package/lib/master-dimmer/master-dimmer.component.d.ts +3 -0
- package/lib/preset/preset-settings/preset-settings.component.d.ts +3 -0
- package/lib/preset/preset.component.d.ts +3 -0
- package/lib/preview/preview.component.d.ts +4 -4
- package/lib/project/project-browser/project-browser.component.d.ts +3 -0
- package/lib/project/project-import/project-import.component.d.ts +3 -0
- package/lib/project/project-save/project-save.component.d.ts +3 -0
- package/lib/project/project-share/project-share.component.d.ts +3 -0
- package/lib/scene/scene-settings/scene-settings.component.d.ts +3 -0
- package/lib/scene/scene.component.d.ts +3 -0
- package/lib/services/animation.service.d.ts +3 -0
- package/lib/services/config.service.d.ts +3 -0
- package/lib/services/effect.service.d.ts +3 -0
- package/lib/services/error-dialog.service.d.ts +3 -0
- package/lib/services/fixture-pool.service.d.ts +3 -0
- package/lib/services/fixture.service.d.ts +3 -0
- package/lib/services/hotkey-target-exclude.service.d.ts +3 -0
- package/lib/services/intro.service.d.ts +3 -0
- package/lib/services/preset.service.d.ts +3 -0
- package/lib/services/preview-mesh.service.d.ts +3 -0
- package/lib/services/preview.service.d.ts +4 -0
- package/lib/services/project-load.service.d.ts +3 -0
- package/lib/services/project.service.d.ts +3 -0
- package/lib/services/scene.service.d.ts +3 -0
- package/lib/services/timeline.service.d.ts +4 -1
- package/lib/services/universe.service.d.ts +3 -0
- package/lib/services/user-ensure-login.service.d.ts +3 -0
- package/lib/services/user.service.d.ts +3 -0
- package/lib/services/uuid.service.d.ts +3 -0
- package/lib/services/warning-dialog.service.d.ts +3 -0
- package/lib/timeline/composition-settings/composition-settings.component.d.ts +3 -0
- package/lib/timeline/timeline-grid/timeline-grid.component.d.ts +3 -0
- package/lib/timeline/timeline.component.d.ts +3 -0
- package/lib/user/user-login/user-login.component.d.ts +3 -0
- package/lib/user/user-register/user-register.component.d.ts +3 -0
- package/lib/wait-dialog/wait-dialog.component.d.ts +3 -0
- package/lib/warning-dialog/warning-dialog.component.d.ts +3 -0
- package/package.json +20 -22
- package/rocketshow-designer-1.33.0.tgz +0 -0
- package/bundles/rocketshow-designer.umd.js +0 -9966
- package/bundles/rocketshow-designer.umd.js.map +0 -1
- package/bundles/rocketshow-designer.umd.min.js +0 -17
- package/bundles/rocketshow-designer.umd.min.js.map +0 -1
- package/esm2015/lib/array-sort-pipe.js +0 -28
- package/esm2015/lib/designer.component.js +0 -411
- package/esm2015/lib/designer.module.js +0 -117
- package/esm2015/lib/designer.service.js +0 -16
- package/esm2015/lib/effect/effect-curve/effect-curve.component.js +0 -325
- package/esm2015/lib/effect/effect-pan-tilt/effect-pan-tilt.component.js +0 -30
- package/esm2015/lib/effect/effect.component.js +0 -73
- package/esm2015/lib/error-dialog/error-dialog.component.js +0 -42
- package/esm2015/lib/fixture/fixture-capability/fixture-capability-channel/fixture-capability-channel.component.js +0 -141
- package/esm2015/lib/fixture/fixture-capability/fixture-capability-color/fixture-capability-color.component.js +0 -128
- package/esm2015/lib/fixture/fixture-capability/fixture-capability-color-wheel/fixture-capability-color-wheel.component.js +0 -163
- package/esm2015/lib/fixture/fixture-capability/fixture-capability-dimmer/fixture-capability-dimmer.component.js +0 -60
- package/esm2015/lib/fixture/fixture-capability/fixture-capability-pan-tilt/fixture-capability-pan-tilt.component.js +0 -87
- package/esm2015/lib/fixture/fixture-capability/fixture-capability.component.js +0 -97
- package/esm2015/lib/fixture/fixture-channel/fixture-channel.component.js +0 -66
- package/esm2015/lib/fixture/fixture-settings/fixture-settings-position/fixture-settings-position.component.js +0 -200
- package/esm2015/lib/fixture/fixture-settings/fixture-settings-stage/fixture-settings-stage.component.js +0 -31
- package/esm2015/lib/fixture/fixture-settings/fixture-settings.component.js +0 -35
- package/esm2015/lib/fixture/fixture.component.js +0 -70
- package/esm2015/lib/fixture-pool/fixture-pool-create-from-file/fixture-pool-create-from-file.component.js +0 -128
- package/esm2015/lib/fixture-pool/fixture-pool.component.js +0 -331
- package/esm2015/lib/intro/intro.component.js +0 -25
- package/esm2015/lib/master-dimmer/master-dimmer.component.js +0 -41
- package/esm2015/lib/models/cached-fixture-capability.js +0 -9
- package/esm2015/lib/models/cached-fixture-channel.js +0 -7
- package/esm2015/lib/models/cached-fixture.js +0 -6
- package/esm2015/lib/models/color.js +0 -8
- package/esm2015/lib/models/composition.js +0 -46
- package/esm2015/lib/models/effect-curve-profile-channel.js +0 -15
- package/esm2015/lib/models/effect-curve.js +0 -69
- package/esm2015/lib/models/effect-pan-tilt.js +0 -19
- package/esm2015/lib/models/effect.js +0 -12
- package/esm2015/lib/models/fixture-capability-value.js +0 -15
- package/esm2015/lib/models/fixture-capability.js +0 -84
- package/esm2015/lib/models/fixture-channel-value.js +0 -11
- package/esm2015/lib/models/fixture-channel.js +0 -24
- package/esm2015/lib/models/fixture-mode.js +0 -14
- package/esm2015/lib/models/fixture-profile.js +0 -70
- package/esm2015/lib/models/fixture-wheel-slot.js +0 -26
- package/esm2015/lib/models/fixture-wheel.js +0 -15
- package/esm2015/lib/models/fixture.js +0 -40
- package/esm2015/lib/models/preset-region-scene.js +0 -8
- package/esm2015/lib/models/preset.js +0 -56
- package/esm2015/lib/models/project.js +0 -68
- package/esm2015/lib/models/scene-playback-region.js +0 -11
- package/esm2015/lib/models/scene.js +0 -27
- package/esm2015/lib/models/universe.js +0 -11
- package/esm2015/lib/preset/preset-settings/preset-settings.component.js +0 -66
- package/esm2015/lib/preset/preset.component.js +0 -85
- package/esm2015/lib/preview/models/color-changer-3d.js +0 -167
- package/esm2015/lib/preview/models/fixture-3d.js +0 -150
- package/esm2015/lib/preview/models/moving-head-3d.js +0 -233
- package/esm2015/lib/preview/preview.component.js +0 -242
- package/esm2015/lib/project/project-browser/project-browser.component.js +0 -73
- package/esm2015/lib/project/project-import/project-import.component.js +0 -89
- package/esm2015/lib/project/project-save/project-save.component.js +0 -105
- package/esm2015/lib/project/project-share/project-share.component.js +0 -43
- package/esm2015/lib/scene/scene-settings/scene-settings.component.js +0 -52
- package/esm2015/lib/scene/scene.component.js +0 -56
- package/esm2015/lib/services/animation.service.js +0 -17
- package/esm2015/lib/services/config.service.js +0 -28
- package/esm2015/lib/services/effect.service.js +0 -16
- package/esm2015/lib/services/error-dialog.service.js +0 -44
- package/esm2015/lib/services/fixture-pool.service.js +0 -34
- package/esm2015/lib/services/fixture.service.js +0 -443
- package/esm2015/lib/services/hotkey-target-exclude.service.js +0 -26
- package/esm2015/lib/services/intro.service.js +0 -144
- package/esm2015/lib/services/preset.service.js +0 -416
- package/esm2015/lib/services/preview-mesh.service.js +0 -58
- package/esm2015/lib/services/preview.service.js +0 -500
- package/esm2015/lib/services/project-load.service.js +0 -171
- package/esm2015/lib/services/project.service.js +0 -113
- package/esm2015/lib/services/scene.service.js +0 -174
- package/esm2015/lib/services/timeline.service.js +0 -738
- package/esm2015/lib/services/universe.service.js +0 -24
- package/esm2015/lib/services/user-ensure-login.service.js +0 -44
- package/esm2015/lib/services/user.service.js +0 -93
- package/esm2015/lib/services/uuid.service.js +0 -25
- package/esm2015/lib/services/warning-dialog.service.js +0 -43
- package/esm2015/lib/timeline/composition-settings/composition-settings.component.js +0 -197
- package/esm2015/lib/timeline/timeline-grid/timeline-grid.component.js +0 -55
- package/esm2015/lib/timeline/timeline.component.js +0 -239
- package/esm2015/lib/user/user-login/user-login.component.js +0 -64
- package/esm2015/lib/user/user-register/user-register.component.js +0 -89
- package/esm2015/lib/wait-dialog/wait-dialog.component.js +0 -16
- package/esm2015/lib/warning-dialog/warning-dialog.component.js +0 -42
- package/esm2015/public_api.js +0 -7
- package/esm2015/rocketshow-designer.js +0 -61
- package/esm5/lib/array-sort-pipe.js +0 -31
- package/esm5/lib/designer.component.js +0 -468
- package/esm5/lib/designer.module.js +0 -120
- package/esm5/lib/designer.service.js +0 -17
- package/esm5/lib/effect/effect-curve/effect-curve.component.js +0 -386
- package/esm5/lib/effect/effect-pan-tilt/effect-pan-tilt.component.js +0 -31
- package/esm5/lib/effect/effect.component.js +0 -75
- package/esm5/lib/error-dialog/error-dialog.component.js +0 -43
- package/esm5/lib/fixture/fixture-capability/fixture-capability-channel/fixture-capability-channel.component.js +0 -159
- package/esm5/lib/fixture/fixture-capability/fixture-capability-color/fixture-capability-color.component.js +0 -130
- package/esm5/lib/fixture/fixture-capability/fixture-capability-color-wheel/fixture-capability-color-wheel.component.js +0 -215
- package/esm5/lib/fixture/fixture-capability/fixture-capability-dimmer/fixture-capability-dimmer.component.js +0 -61
- package/esm5/lib/fixture/fixture-capability/fixture-capability-pan-tilt/fixture-capability-pan-tilt.component.js +0 -88
- package/esm5/lib/fixture/fixture-capability/fixture-capability.component.js +0 -130
- package/esm5/lib/fixture/fixture-channel/fixture-channel.component.js +0 -68
- package/esm5/lib/fixture/fixture-settings/fixture-settings-position/fixture-settings-position.component.js +0 -306
- package/esm5/lib/fixture/fixture-settings/fixture-settings-stage/fixture-settings-stage.component.js +0 -32
- package/esm5/lib/fixture/fixture-settings/fixture-settings.component.js +0 -36
- package/esm5/lib/fixture/fixture.component.js +0 -71
- package/esm5/lib/fixture-pool/fixture-pool-create-from-file/fixture-pool-create-from-file.component.js +0 -127
- package/esm5/lib/fixture-pool/fixture-pool.component.js +0 -430
- package/esm5/lib/intro/intro.component.js +0 -26
- package/esm5/lib/master-dimmer/master-dimmer.component.js +0 -42
- package/esm5/lib/models/cached-fixture-capability.js +0 -11
- package/esm5/lib/models/cached-fixture-channel.js +0 -9
- package/esm5/lib/models/cached-fixture.js +0 -8
- package/esm5/lib/models/color.js +0 -10
- package/esm5/lib/models/composition.js +0 -60
- package/esm5/lib/models/effect-curve-profile-channel.js +0 -29
- package/esm5/lib/models/effect-curve.js +0 -95
- package/esm5/lib/models/effect-pan-tilt.js +0 -24
- package/esm5/lib/models/effect.js +0 -14
- package/esm5/lib/models/fixture-capability-value.js +0 -17
- package/esm5/lib/models/fixture-capability.js +0 -86
- package/esm5/lib/models/fixture-channel-value.js +0 -13
- package/esm5/lib/models/fixture-channel.js +0 -38
- package/esm5/lib/models/fixture-mode.js +0 -16
- package/esm5/lib/models/fixture-profile.js +0 -114
- package/esm5/lib/models/fixture-wheel-slot.js +0 -28
- package/esm5/lib/models/fixture-wheel.js +0 -29
- package/esm5/lib/models/fixture.js +0 -42
- package/esm5/lib/models/preset-region-scene.js +0 -10
- package/esm5/lib/models/preset.js +0 -90
- package/esm5/lib/models/project.js +0 -122
- package/esm5/lib/models/scene-playback-region.js +0 -13
- package/esm5/lib/models/scene.js +0 -29
- package/esm5/lib/models/universe.js +0 -13
- package/esm5/lib/preset/preset-settings/preset-settings.component.js +0 -67
- package/esm5/lib/preset/preset.component.js +0 -86
- package/esm5/lib/preview/models/color-changer-3d.js +0 -194
- package/esm5/lib/preview/models/fixture-3d.js +0 -196
- package/esm5/lib/preview/models/moving-head-3d.js +0 -250
- package/esm5/lib/preview/preview.component.js +0 -280
- package/esm5/lib/project/project-browser/project-browser.component.js +0 -77
- package/esm5/lib/project/project-import/project-import.component.js +0 -88
- package/esm5/lib/project/project-save/project-save.component.js +0 -120
- package/esm5/lib/project/project-share/project-share.component.js +0 -44
- package/esm5/lib/scene/scene-settings/scene-settings.component.js +0 -53
- package/esm5/lib/scene/scene.component.js +0 -57
- package/esm5/lib/services/animation.service.js +0 -18
- package/esm5/lib/services/config.service.js +0 -29
- package/esm5/lib/services/effect.service.js +0 -17
- package/esm5/lib/services/error-dialog.service.js +0 -46
- package/esm5/lib/services/fixture-pool.service.js +0 -36
- package/esm5/lib/services/fixture.service.js +0 -643
- package/esm5/lib/services/hotkey-target-exclude.service.js +0 -27
- package/esm5/lib/services/intro.service.js +0 -145
- package/esm5/lib/services/preset.service.js +0 -637
- package/esm5/lib/services/preview-mesh.service.js +0 -61
- package/esm5/lib/services/preview.service.js +0 -754
- package/esm5/lib/services/project-load.service.js +0 -185
- package/esm5/lib/services/project.service.js +0 -127
- package/esm5/lib/services/scene.service.js +0 -251
- package/esm5/lib/services/timeline.service.js +0 -845
- package/esm5/lib/services/universe.service.js +0 -36
- package/esm5/lib/services/user-ensure-login.service.js +0 -45
- package/esm5/lib/services/user.service.js +0 -95
- package/esm5/lib/services/uuid.service.js +0 -26
- package/esm5/lib/services/warning-dialog.service.js +0 -45
- package/esm5/lib/timeline/composition-settings/composition-settings.component.js +0 -206
- package/esm5/lib/timeline/timeline-grid/timeline-grid.component.js +0 -56
- package/esm5/lib/timeline/timeline.component.js +0 -243
- package/esm5/lib/user/user-login/user-login.component.js +0 -66
- package/esm5/lib/user/user-register/user-register.component.js +0 -91
- package/esm5/lib/wait-dialog/wait-dialog.component.js +0 -18
- package/esm5/lib/warning-dialog/warning-dialog.component.js +0 -43
- package/esm5/public_api.js +0 -7
- package/esm5/rocketshow-designer.js +0 -61
- package/fesm2015/rocketshow-designer.js +0 -7945
- package/fesm2015/rocketshow-designer.js.map +0 -1
- package/fesm5/rocketshow-designer.js +0 -9690
- package/fesm5/rocketshow-designer.js.map +0 -1
- package/rocketshow-designer-1.32.0.tgz +0 -0
- package/rocketshow-designer.d.ts +0 -60
- 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==
|