@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
|
@@ -0,0 +1,496 @@
|
|
|
1
|
+
import { Injectable } from '@angular/core';
|
|
2
|
+
import { Subject } from 'rxjs';
|
|
3
|
+
import * as THREE from 'three';
|
|
4
|
+
import { EffectCurve } from '../models/effect-curve';
|
|
5
|
+
import { FixtureCapabilityType } from '../models/fixture-capability';
|
|
6
|
+
import { FixtureChannelValue } from '../models/fixture-channel-value';
|
|
7
|
+
import { PresetRegionScene } from '../models/preset-region-scene';
|
|
8
|
+
import { FixtureService } from './fixture.service';
|
|
9
|
+
import { PresetService } from './preset.service';
|
|
10
|
+
import { ProjectService } from './project.service';
|
|
11
|
+
import { SceneService } from './scene.service';
|
|
12
|
+
import { TimelineService } from './timeline.service';
|
|
13
|
+
import { UniverseService } from './universe.service';
|
|
14
|
+
import * as i0 from "@angular/core";
|
|
15
|
+
import * as i1 from "./preset.service";
|
|
16
|
+
import * as i2 from "./fixture.service";
|
|
17
|
+
import * as i3 from "./scene.service";
|
|
18
|
+
import * as i4 from "./timeline.service";
|
|
19
|
+
import * as i5 from "./universe.service";
|
|
20
|
+
import * as i6 from "./project.service";
|
|
21
|
+
export class PreviewService {
|
|
22
|
+
constructor(presetService, fixtureService, sceneService, timelineService, universeService, projectService) {
|
|
23
|
+
this.presetService = presetService;
|
|
24
|
+
this.fixtureService = fixtureService;
|
|
25
|
+
this.sceneService = sceneService;
|
|
26
|
+
this.timelineService = timelineService;
|
|
27
|
+
this.universeService = universeService;
|
|
28
|
+
this.projectService = projectService;
|
|
29
|
+
this.doUpdateFixtureSetup = new Subject();
|
|
30
|
+
this.stageMeshes = [];
|
|
31
|
+
this.stageMaterial = new THREE.MeshStandardMaterial({
|
|
32
|
+
color: 0x0d0d0d,
|
|
33
|
+
// roughness: 0.5,
|
|
34
|
+
// metalness: 0.5,
|
|
35
|
+
});
|
|
36
|
+
}
|
|
37
|
+
getAlreadyCalculatedFixture(fixtures, fixtureIndex) {
|
|
38
|
+
// Has this fixture already been calculated (same universe and dmx start address as a fixture before)
|
|
39
|
+
// --> return it
|
|
40
|
+
for (let i = 0; i < fixtureIndex; i++) {
|
|
41
|
+
const calculatedFixture = fixtures[i];
|
|
42
|
+
if (calculatedFixture.fixture.dmxUniverseUuid === fixtures[fixtureIndex].fixture.dmxUniverseUuid &&
|
|
43
|
+
calculatedFixture.fixture.dmxFirstChannel === fixtures[fixtureIndex].fixture.dmxFirstChannel) {
|
|
44
|
+
return calculatedFixture;
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
return undefined;
|
|
48
|
+
}
|
|
49
|
+
getPresets(timeMillis) {
|
|
50
|
+
// Get relevant presets in correct order to process with their corresponding scene, if available
|
|
51
|
+
let presets = [];
|
|
52
|
+
if (this.timelineService.playState === 'playing') {
|
|
53
|
+
// Only use active presets in current regions
|
|
54
|
+
presets = this.timelineService.getPresetsInTime(timeMillis);
|
|
55
|
+
}
|
|
56
|
+
else {
|
|
57
|
+
if (this.projectService.project.previewPreset) {
|
|
58
|
+
// Only preview the selected preset
|
|
59
|
+
if (this.presetService.selectedPreset) {
|
|
60
|
+
presets.push(new PresetRegionScene(this.presetService.selectedPreset, undefined, undefined));
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
else {
|
|
64
|
+
// Preview the selected scenes
|
|
65
|
+
for (let sceneIndex = this.projectService.project.scenes.length - 1; sceneIndex >= 0; sceneIndex--) {
|
|
66
|
+
for (const scene of this.sceneService.selectedScenes) {
|
|
67
|
+
if (scene.uuid === this.projectService.project.scenes[sceneIndex].uuid) {
|
|
68
|
+
for (let presetIndex = this.projectService.project.presets.length - 1; presetIndex >= 0; presetIndex--) {
|
|
69
|
+
for (const presetUuid of scene.presetUuids) {
|
|
70
|
+
// Loop over the presets in the preset service to retain the preset order
|
|
71
|
+
if (presetUuid === this.projectService.project.presets[presetIndex].uuid) {
|
|
72
|
+
presets.push(new PresetRegionScene(this.projectService.project.presets[presetIndex], undefined, scene));
|
|
73
|
+
break;
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
return presets;
|
|
83
|
+
}
|
|
84
|
+
mixChannelValue(existingChannelValues, channelValue, intensityPercentage, defaultValue = 0) {
|
|
85
|
+
let newValue = channelValue.value;
|
|
86
|
+
let existingValue = defaultValue;
|
|
87
|
+
if (intensityPercentage < 1) {
|
|
88
|
+
// We need to mix a possibly existing value (or the default value 0) with the new value (fading)
|
|
89
|
+
// Get the existent value for this property
|
|
90
|
+
for (const existingChannelValue of existingChannelValues) {
|
|
91
|
+
if (existingChannelValue.channelName === channelValue.channelName &&
|
|
92
|
+
existingChannelValue.profileUuid === channelValue.profileUuid) {
|
|
93
|
+
existingValue = existingChannelValue.value;
|
|
94
|
+
break;
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
// Mix the existing value with the new value
|
|
98
|
+
newValue = existingValue * (1 - intensityPercentage) + newValue * intensityPercentage;
|
|
99
|
+
}
|
|
100
|
+
// Remove the existent value, if available
|
|
101
|
+
for (let i = 0; i < existingChannelValues.length; i++) {
|
|
102
|
+
if (existingChannelValues[i].channelName === channelValue.channelName &&
|
|
103
|
+
existingChannelValues[i].profileUuid === channelValue.profileUuid) {
|
|
104
|
+
existingChannelValues.splice(i, 1);
|
|
105
|
+
break;
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
// Add the new value
|
|
109
|
+
const fixtureChannelValue = new FixtureChannelValue();
|
|
110
|
+
fixtureChannelValue.channelName = channelValue.channelName;
|
|
111
|
+
fixtureChannelValue.profileUuid = channelValue.profileUuid;
|
|
112
|
+
fixtureChannelValue.value = newValue;
|
|
113
|
+
existingChannelValues.push(fixtureChannelValue);
|
|
114
|
+
}
|
|
115
|
+
// Get the fixture index inside the passed preset (used for chasing)
|
|
116
|
+
getFixtureIndex(preset, fixtureUuid) {
|
|
117
|
+
let index = 0;
|
|
118
|
+
const countedDmxChannels = [];
|
|
119
|
+
// Loop over the global fixtures to retain the order
|
|
120
|
+
for (const fixture of this.projectService.project.fixtures) {
|
|
121
|
+
for (const presetFixtureUuid of preset.fixtureUuids) {
|
|
122
|
+
if (presetFixtureUuid === fixture.uuid) {
|
|
123
|
+
if (fixture.uuid === fixtureUuid) {
|
|
124
|
+
return index;
|
|
125
|
+
}
|
|
126
|
+
// don't count fixtures on the same channel as already counted ones
|
|
127
|
+
if (!countedDmxChannels.includes(fixture.dmxFirstChannel)) {
|
|
128
|
+
countedDmxChannels.push(fixture.dmxFirstChannel);
|
|
129
|
+
index++;
|
|
130
|
+
}
|
|
131
|
+
break;
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
// Not found in the preset
|
|
136
|
+
return undefined;
|
|
137
|
+
}
|
|
138
|
+
getPresetIntensity(preset, timeMillis) {
|
|
139
|
+
// When fading is in progress (on preset or scene-level), the current preset does not
|
|
140
|
+
// fully cover underlying values.
|
|
141
|
+
// -> 0 = no covering at all, 1 = fully cover (no fading)
|
|
142
|
+
let intensityPercentageScene = 1;
|
|
143
|
+
let intensityPercentagePreset = 1;
|
|
144
|
+
let intensityPercentage = 1;
|
|
145
|
+
if (preset.region && preset.scene) {
|
|
146
|
+
// Fade out is stronger than fade in (if they overlap)
|
|
147
|
+
// Take away intensity for scene fading
|
|
148
|
+
const sceneStartMillis = preset.scene.fadeInPre ? preset.region.startMillis - preset.scene.fadeInMillis : preset.region.startMillis;
|
|
149
|
+
const sceneEndMillis = preset.scene.fadeOutPost ? preset.region.endMillis + preset.scene.fadeOutMillis : preset.region.endMillis;
|
|
150
|
+
if (timeMillis > sceneEndMillis - preset.scene.fadeOutMillis && timeMillis < sceneEndMillis) {
|
|
151
|
+
// Scene fades out
|
|
152
|
+
intensityPercentageScene = (sceneEndMillis - timeMillis) / preset.scene.fadeOutMillis;
|
|
153
|
+
}
|
|
154
|
+
else if (timeMillis < sceneStartMillis + preset.scene.fadeInMillis && timeMillis > sceneStartMillis) {
|
|
155
|
+
// Scene fades in
|
|
156
|
+
intensityPercentageScene = (timeMillis - sceneStartMillis) / preset.scene.fadeInMillis;
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
if (preset.region && preset.preset) {
|
|
160
|
+
// Take away intensity for preset fading
|
|
161
|
+
let presetStartMillis = preset.preset.startMillis === undefined ? preset.region.startMillis : preset.region.startMillis + preset.preset.startMillis;
|
|
162
|
+
let presetEndMillis = preset.preset.endMillis === undefined ? preset.region.endMillis : preset.region.startMillis + preset.preset.endMillis;
|
|
163
|
+
// extend the running time, if fading is done outside the boundaries
|
|
164
|
+
presetStartMillis -= preset.preset.fadeInPre ? preset.preset.fadeInMillis : 0;
|
|
165
|
+
presetEndMillis += preset.preset.fadeOutPost ? preset.preset.fadeOutMillis : 0;
|
|
166
|
+
if (timeMillis > presetEndMillis - preset.preset.fadeOutMillis && timeMillis < presetEndMillis) {
|
|
167
|
+
// Preset fades out
|
|
168
|
+
intensityPercentagePreset = (presetEndMillis - timeMillis) / preset.preset.fadeOutMillis;
|
|
169
|
+
}
|
|
170
|
+
else if (timeMillis < presetStartMillis + preset.preset.fadeInMillis && timeMillis > presetStartMillis) {
|
|
171
|
+
// Preset fades in
|
|
172
|
+
intensityPercentagePreset = (timeMillis - presetStartMillis) / preset.preset.fadeInMillis;
|
|
173
|
+
}
|
|
174
|
+
intensityPercentage = intensityPercentageScene * intensityPercentagePreset;
|
|
175
|
+
}
|
|
176
|
+
return intensityPercentage;
|
|
177
|
+
}
|
|
178
|
+
mixCapabilityValues(preset, cachedFixture, values, intensityPercentage) {
|
|
179
|
+
let hasColor = false;
|
|
180
|
+
// mix the preset capability values
|
|
181
|
+
for (const presetCapabilityValue of preset.preset.fixtureCapabilityValues) {
|
|
182
|
+
for (const cachedChannel of cachedFixture.channels) {
|
|
183
|
+
if (cachedChannel.channel) {
|
|
184
|
+
for (const channelCapability of cachedChannel.capabilities) {
|
|
185
|
+
if (this.fixtureService.capabilitiesMatch(presetCapabilityValue.type, channelCapability.capability.type, presetCapabilityValue.color, channelCapability.capability.color, presetCapabilityValue.wheel, channelCapability.wheelName, presetCapabilityValue.profileUuid, cachedFixture.profile.uuid)) {
|
|
186
|
+
// the capabilities match -> apply the value, if possible
|
|
187
|
+
if ((presetCapabilityValue.type === FixtureCapabilityType.Intensity ||
|
|
188
|
+
presetCapabilityValue.type === FixtureCapabilityType.ColorIntensity) &&
|
|
189
|
+
presetCapabilityValue.valuePercentage >= 0) {
|
|
190
|
+
// intensity and colorIntensity (dimmer and color)
|
|
191
|
+
const valuePercentage = presetCapabilityValue.valuePercentage;
|
|
192
|
+
const defaultValue = 0;
|
|
193
|
+
// brightness property
|
|
194
|
+
if (cachedChannel.capabilities.length === 1) {
|
|
195
|
+
// the only capability in this channel
|
|
196
|
+
const fixtureChannelValue = new FixtureChannelValue();
|
|
197
|
+
fixtureChannelValue.channelName = cachedChannel.name;
|
|
198
|
+
fixtureChannelValue.profileUuid = cachedFixture.profile.uuid;
|
|
199
|
+
fixtureChannelValue.value = cachedChannel.maxValue * valuePercentage;
|
|
200
|
+
this.mixChannelValue(values, fixtureChannelValue, intensityPercentage, defaultValue);
|
|
201
|
+
if (presetCapabilityValue.type === FixtureCapabilityType.ColorIntensity) {
|
|
202
|
+
hasColor = true;
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
else {
|
|
206
|
+
// more than one capability in the channel
|
|
207
|
+
if (channelCapability.capability.brightness === 'off' && valuePercentage === 0) {
|
|
208
|
+
const fixtureChannelValue = new FixtureChannelValue();
|
|
209
|
+
fixtureChannelValue.channelName = cachedChannel.name;
|
|
210
|
+
fixtureChannelValue.profileUuid = cachedFixture.profile.uuid;
|
|
211
|
+
fixtureChannelValue.value = channelCapability.centerValue;
|
|
212
|
+
this.mixChannelValue(values, fixtureChannelValue, intensityPercentage, defaultValue);
|
|
213
|
+
if (presetCapabilityValue.type === FixtureCapabilityType.ColorIntensity) {
|
|
214
|
+
hasColor = true;
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
else if ((channelCapability.capability.brightnessStart === 'dark' || channelCapability.capability.brightnessStart === 'off') &&
|
|
218
|
+
channelCapability.capability.brightnessEnd === 'bright') {
|
|
219
|
+
const value = (channelCapability.capability.dmxRange[1] - channelCapability.capability.dmxRange[0]) * valuePercentage +
|
|
220
|
+
channelCapability.capability.dmxRange[0];
|
|
221
|
+
const fixtureChannelValue = new FixtureChannelValue();
|
|
222
|
+
fixtureChannelValue.channelName = cachedChannel.name;
|
|
223
|
+
fixtureChannelValue.profileUuid = cachedFixture.profile.uuid;
|
|
224
|
+
fixtureChannelValue.value = value;
|
|
225
|
+
this.mixChannelValue(values, fixtureChannelValue, intensityPercentage, defaultValue);
|
|
226
|
+
if (presetCapabilityValue.type === FixtureCapabilityType.ColorIntensity) {
|
|
227
|
+
hasColor = true;
|
|
228
|
+
}
|
|
229
|
+
}
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
else if ((presetCapabilityValue.type === FixtureCapabilityType.Pan || presetCapabilityValue.type === FixtureCapabilityType.Tilt) &&
|
|
233
|
+
presetCapabilityValue.valuePercentage >= 0) {
|
|
234
|
+
const fixtureChannelValue = new FixtureChannelValue();
|
|
235
|
+
fixtureChannelValue.channelName = cachedChannel.name;
|
|
236
|
+
fixtureChannelValue.profileUuid = cachedFixture.profile.uuid;
|
|
237
|
+
fixtureChannelValue.value = cachedChannel.maxValue * presetCapabilityValue.valuePercentage;
|
|
238
|
+
this.mixChannelValue(values, fixtureChannelValue, 1);
|
|
239
|
+
}
|
|
240
|
+
else if (presetCapabilityValue.type === FixtureCapabilityType.WheelSlot &&
|
|
241
|
+
channelCapability.capability.slotNumber === presetCapabilityValue.slotNumber) {
|
|
242
|
+
// wheel slot (color, gobo, etc.)
|
|
243
|
+
const fixtureChannelValue = new FixtureChannelValue();
|
|
244
|
+
fixtureChannelValue.channelName = cachedChannel.name;
|
|
245
|
+
fixtureChannelValue.profileUuid = cachedFixture.profile.uuid;
|
|
246
|
+
fixtureChannelValue.value = channelCapability.centerValue;
|
|
247
|
+
this.mixChannelValue(values, fixtureChannelValue, 1);
|
|
248
|
+
// check, whether we just set a color wheel value
|
|
249
|
+
if (channelCapability.wheelIsColor) {
|
|
250
|
+
hasColor = true;
|
|
251
|
+
}
|
|
252
|
+
}
|
|
253
|
+
}
|
|
254
|
+
}
|
|
255
|
+
}
|
|
256
|
+
// approximate the color from a color or a different color wheel, if necessary
|
|
257
|
+
if (!hasColor && cachedChannel.colorWheel) {
|
|
258
|
+
const capability = this.presetService.getApproximatedColorWheelCapability(preset.preset, cachedChannel);
|
|
259
|
+
if (capability) {
|
|
260
|
+
// we found an approximated color in the available wheel channel
|
|
261
|
+
const fixtureChannelValue = new FixtureChannelValue();
|
|
262
|
+
fixtureChannelValue.channelName = cachedChannel.name;
|
|
263
|
+
fixtureChannelValue.profileUuid = cachedFixture.profile.uuid;
|
|
264
|
+
fixtureChannelValue.value = capability.centerValue;
|
|
265
|
+
this.mixChannelValue(values, fixtureChannelValue, 1);
|
|
266
|
+
}
|
|
267
|
+
}
|
|
268
|
+
}
|
|
269
|
+
}
|
|
270
|
+
}
|
|
271
|
+
mixChannelValues(preset, cachedFixture, values, intensityPercentage) {
|
|
272
|
+
// mix the preset channel values
|
|
273
|
+
for (const cachedChannel of cachedFixture.channels) {
|
|
274
|
+
if (cachedChannel.channel) {
|
|
275
|
+
for (const channelValue of preset.preset.fixtureChannelValues) {
|
|
276
|
+
if (cachedFixture.profile.uuid === channelValue.profileUuid && cachedChannel.name === channelValue.channelName) {
|
|
277
|
+
this.mixChannelValue(values, channelValue, intensityPercentage);
|
|
278
|
+
}
|
|
279
|
+
}
|
|
280
|
+
}
|
|
281
|
+
}
|
|
282
|
+
}
|
|
283
|
+
mixEffects(timeMillis, fixtureIndex, preset, cachedFixture, values, intensityPercentage) {
|
|
284
|
+
for (const effect of preset.preset.effects) {
|
|
285
|
+
if (effect.visible) {
|
|
286
|
+
// EffectCurve
|
|
287
|
+
if (effect instanceof EffectCurve) {
|
|
288
|
+
const effectCurve = effect;
|
|
289
|
+
// capabilities
|
|
290
|
+
for (const capability of effectCurve.capabilities) {
|
|
291
|
+
for (const cachedChannel of cachedFixture.channels) {
|
|
292
|
+
for (const channelCapability of cachedChannel.capabilities) {
|
|
293
|
+
if (this.fixtureService.capabilitiesMatch(capability.type, channelCapability.capability.type, capability.color, channelCapability.capability.color, null, null, null, null)) {
|
|
294
|
+
const fixtureChannelValue = new FixtureChannelValue();
|
|
295
|
+
fixtureChannelValue.channelName = cachedChannel.name;
|
|
296
|
+
fixtureChannelValue.profileUuid = cachedFixture.profile.uuid;
|
|
297
|
+
fixtureChannelValue.value = cachedChannel.maxValue * effectCurve.getValueAtMillis(timeMillis, fixtureIndex);
|
|
298
|
+
this.mixChannelValue(values, fixtureChannelValue, intensityPercentage);
|
|
299
|
+
}
|
|
300
|
+
}
|
|
301
|
+
}
|
|
302
|
+
}
|
|
303
|
+
// channels
|
|
304
|
+
for (const channelProfile of effectCurve.channels) {
|
|
305
|
+
if (channelProfile.profileUuid === cachedFixture.profile.uuid) {
|
|
306
|
+
for (const channel of channelProfile.channels) {
|
|
307
|
+
for (const cachedChannel of cachedFixture.channels) {
|
|
308
|
+
if (cachedChannel.name === channel) {
|
|
309
|
+
const fixtureChannelValue = new FixtureChannelValue();
|
|
310
|
+
fixtureChannelValue.channelName = cachedChannel.name;
|
|
311
|
+
fixtureChannelValue.profileUuid = cachedFixture.profile.uuid;
|
|
312
|
+
fixtureChannelValue.value = cachedChannel.maxValue * effectCurve.getValueAtMillis(timeMillis, fixtureIndex);
|
|
313
|
+
this.mixChannelValue(values, fixtureChannelValue, intensityPercentage);
|
|
314
|
+
}
|
|
315
|
+
}
|
|
316
|
+
}
|
|
317
|
+
break;
|
|
318
|
+
}
|
|
319
|
+
}
|
|
320
|
+
}
|
|
321
|
+
// TODO other effects (PanTilt, etc.)
|
|
322
|
+
}
|
|
323
|
+
}
|
|
324
|
+
}
|
|
325
|
+
// return all fixture uuids with their corresponding channel values
|
|
326
|
+
getChannelValues(timeMillis, presets) {
|
|
327
|
+
// Loop over all relevant presets and calc the property values from the presets (capabilities and effects)
|
|
328
|
+
const calculatedFixtures = new Map();
|
|
329
|
+
for (let i = 0; i < this.fixtureService.cachedFixtures.length; i++) {
|
|
330
|
+
const cachedFixture = this.fixtureService.cachedFixtures[i];
|
|
331
|
+
// all values of the current fixture channels
|
|
332
|
+
let values = [];
|
|
333
|
+
const alreadyCalculatedFixture = this.getAlreadyCalculatedFixture(this.fixtureService.cachedFixtures, i);
|
|
334
|
+
if (alreadyCalculatedFixture) {
|
|
335
|
+
// only relevant for the preview --> reuse all calculated values
|
|
336
|
+
values = Object.assign([], calculatedFixtures.get(alreadyCalculatedFixture));
|
|
337
|
+
}
|
|
338
|
+
else {
|
|
339
|
+
// apply the default values
|
|
340
|
+
for (const cachedChannel of cachedFixture.channels) {
|
|
341
|
+
if (cachedChannel.channel) {
|
|
342
|
+
if (cachedChannel.channel.defaultValue) {
|
|
343
|
+
const fixtureChannelValue = new FixtureChannelValue();
|
|
344
|
+
fixtureChannelValue.channelName = cachedChannel.name;
|
|
345
|
+
fixtureChannelValue.profileUuid = cachedFixture.profile.uuid;
|
|
346
|
+
fixtureChannelValue.value = cachedChannel.defaultValue;
|
|
347
|
+
this.mixChannelValue(values, fixtureChannelValue, 1);
|
|
348
|
+
}
|
|
349
|
+
}
|
|
350
|
+
}
|
|
351
|
+
for (const preset of presets) {
|
|
352
|
+
// search for this fixture in the preset and get it's preset-specific index (for chasing effects)
|
|
353
|
+
const fixtureIndex = this.getFixtureIndex(preset.preset, cachedFixture.fixture.uuid);
|
|
354
|
+
if (fixtureIndex >= 0) {
|
|
355
|
+
// this fixture is also in the preset -> mix the required values (overwrite existing values,
|
|
356
|
+
// if set multiple times)
|
|
357
|
+
const intensityPercentage = this.getPresetIntensity(preset, timeMillis);
|
|
358
|
+
this.mixCapabilityValues(preset, cachedFixture, values, intensityPercentage);
|
|
359
|
+
this.mixChannelValues(preset, cachedFixture, values, intensityPercentage);
|
|
360
|
+
this.mixEffects(timeMillis, fixtureIndex, preset, cachedFixture, values, intensityPercentage);
|
|
361
|
+
}
|
|
362
|
+
}
|
|
363
|
+
}
|
|
364
|
+
// Store the calculated values for subsequent fixtures on the same DMX address
|
|
365
|
+
calculatedFixtures.set(cachedFixture, values);
|
|
366
|
+
}
|
|
367
|
+
return calculatedFixtures;
|
|
368
|
+
}
|
|
369
|
+
setUniverseValues(fixtures, masterDimmerValue) {
|
|
370
|
+
// TODO only, if monitoring is enabled
|
|
371
|
+
return;
|
|
372
|
+
// Reset all DMX universes
|
|
373
|
+
for (const universe of this.universeService.universes) {
|
|
374
|
+
universe.channelValues = [];
|
|
375
|
+
for (let i = 0; i < 512; i++) {
|
|
376
|
+
universe.channelValues.push(0);
|
|
377
|
+
}
|
|
378
|
+
}
|
|
379
|
+
// loop over each fixture
|
|
380
|
+
fixtures.forEach((channelValues, cachedFixture) => {
|
|
381
|
+
// TODO Get the correct universe for this fixture
|
|
382
|
+
const universe = this.universeService.getUniverseByUuid(cachedFixture.fixture.dmxUniverseUuid);
|
|
383
|
+
// loop over each channel for this fixture
|
|
384
|
+
for (let channelIndex = 0; channelIndex < cachedFixture.mode.channels.length; channelIndex++) {
|
|
385
|
+
const channelObj = cachedFixture.mode.channels[channelIndex];
|
|
386
|
+
if (typeof channelObj === 'string') {
|
|
387
|
+
const channelName = channelObj;
|
|
388
|
+
// match this mode channel with a channel value
|
|
389
|
+
for (const channelValue of channelValues) {
|
|
390
|
+
const channel = this.fixtureService.getChannelByName(cachedFixture, channelName);
|
|
391
|
+
if (channel && channel.channel) {
|
|
392
|
+
const fineIndex = channel.channel.fineChannelAliases.indexOf(channelName);
|
|
393
|
+
if (channel.name === channelValue.channelName || fineIndex > -1) {
|
|
394
|
+
const universeChannel = cachedFixture.fixture.dmxFirstChannel + channelIndex;
|
|
395
|
+
const dmxValue = Math.floor(channelValue.value / Math.pow(256, channel.channel.fineChannelAliases.length - (fineIndex + 1))) % 256;
|
|
396
|
+
// TODO
|
|
397
|
+
break;
|
|
398
|
+
}
|
|
399
|
+
}
|
|
400
|
+
}
|
|
401
|
+
}
|
|
402
|
+
}
|
|
403
|
+
});
|
|
404
|
+
}
|
|
405
|
+
fixtureIsSelected(uuid, presets) {
|
|
406
|
+
for (const preset of presets) {
|
|
407
|
+
for (const fixtureUuid of preset.preset.fixtureUuids) {
|
|
408
|
+
if (fixtureUuid === uuid) {
|
|
409
|
+
return true;
|
|
410
|
+
}
|
|
411
|
+
}
|
|
412
|
+
}
|
|
413
|
+
return false;
|
|
414
|
+
}
|
|
415
|
+
updateFixtureSetup() {
|
|
416
|
+
this.doUpdateFixtureSetup.next();
|
|
417
|
+
}
|
|
418
|
+
prepareStageMesh(mesh) {
|
|
419
|
+
mesh.receiveShadow = false;
|
|
420
|
+
mesh.castShadow = false;
|
|
421
|
+
}
|
|
422
|
+
updateStage() {
|
|
423
|
+
if (!this.scene) {
|
|
424
|
+
return;
|
|
425
|
+
}
|
|
426
|
+
let geometry;
|
|
427
|
+
let mesh;
|
|
428
|
+
// Remove old meshes from the scene
|
|
429
|
+
for (const existingMesh of this.stageMeshes) {
|
|
430
|
+
this.scene.remove(existingMesh);
|
|
431
|
+
existingMesh.geometry.dispose();
|
|
432
|
+
}
|
|
433
|
+
this.stageMeshes = [];
|
|
434
|
+
// Ground
|
|
435
|
+
geometry = new THREE.PlaneGeometry(5000, 5000);
|
|
436
|
+
mesh = new THREE.Mesh(geometry, this.stageMaterial);
|
|
437
|
+
this.prepareStageMesh(mesh);
|
|
438
|
+
mesh.position.set(0, 0, 0);
|
|
439
|
+
mesh.rotateX((Math.PI / 180) * -90);
|
|
440
|
+
this.scene.add(mesh);
|
|
441
|
+
this.stageMeshes.push(mesh);
|
|
442
|
+
// Floor
|
|
443
|
+
geometry = new THREE.BoxGeometry(this.projectService.project.stageWidthCm, this.projectService.project.stageFloorHeightCm, this.projectService.project.stageDepthCm);
|
|
444
|
+
mesh = new THREE.Mesh(geometry, this.stageMaterial);
|
|
445
|
+
this.prepareStageMesh(mesh);
|
|
446
|
+
mesh.position.set(0, this.projectService.project.stageFloorHeightCm / 2, 0);
|
|
447
|
+
this.scene.add(mesh);
|
|
448
|
+
this.stageMeshes.push(mesh);
|
|
449
|
+
// Pillar front left
|
|
450
|
+
geometry = new THREE.BoxGeometry(this.projectService.project.stagePillarWidthCm, this.projectService.project.stageHeightCm, this.projectService.project.stagePillarWidthCm);
|
|
451
|
+
mesh = new THREE.Mesh(geometry, this.stageMaterial);
|
|
452
|
+
this.prepareStageMesh(mesh);
|
|
453
|
+
mesh.position.set(-this.projectService.project.stageWidthCm / 2 + this.projectService.project.stagePillarWidthCm / 2, this.projectService.project.stageHeightCm / 2 + this.projectService.project.stageFloorHeightCm, this.projectService.project.stageDepthCm / 2 - this.projectService.project.stagePillarWidthCm / 2);
|
|
454
|
+
this.scene.add(mesh);
|
|
455
|
+
this.stageMeshes.push(mesh);
|
|
456
|
+
// Pillar front right
|
|
457
|
+
geometry = new THREE.BoxGeometry(this.projectService.project.stagePillarWidthCm, this.projectService.project.stageHeightCm, this.projectService.project.stagePillarWidthCm);
|
|
458
|
+
mesh = new THREE.Mesh(geometry, this.stageMaterial);
|
|
459
|
+
this.prepareStageMesh(mesh);
|
|
460
|
+
mesh.position.set(this.projectService.project.stageWidthCm / 2 - this.projectService.project.stagePillarWidthCm / 2, this.projectService.project.stageHeightCm / 2 + this.projectService.project.stageFloorHeightCm, this.projectService.project.stageDepthCm / 2 - this.projectService.project.stagePillarWidthCm / 2);
|
|
461
|
+
this.scene.add(mesh);
|
|
462
|
+
this.stageMeshes.push(mesh);
|
|
463
|
+
// Pillar back left
|
|
464
|
+
geometry = new THREE.BoxGeometry(this.projectService.project.stagePillarWidthCm, this.projectService.project.stageHeightCm, this.projectService.project.stagePillarWidthCm);
|
|
465
|
+
mesh = new THREE.Mesh(geometry, this.stageMaterial);
|
|
466
|
+
this.prepareStageMesh(mesh);
|
|
467
|
+
mesh.position.set(-this.projectService.project.stageWidthCm / 2 + this.projectService.project.stagePillarWidthCm / 2, this.projectService.project.stageHeightCm / 2 + this.projectService.project.stageFloorHeightCm, -this.projectService.project.stageDepthCm / 2 + this.projectService.project.stagePillarWidthCm / 2);
|
|
468
|
+
this.scene.add(mesh);
|
|
469
|
+
this.stageMeshes.push(mesh);
|
|
470
|
+
// Pillar back right
|
|
471
|
+
geometry = new THREE.BoxGeometry(this.projectService.project.stagePillarWidthCm, this.projectService.project.stageHeightCm, this.projectService.project.stagePillarWidthCm);
|
|
472
|
+
mesh = new THREE.Mesh(geometry, this.stageMaterial);
|
|
473
|
+
this.prepareStageMesh(mesh);
|
|
474
|
+
mesh.position.set(this.projectService.project.stageWidthCm / 2 - this.projectService.project.stagePillarWidthCm / 2, this.projectService.project.stageHeightCm / 2 + this.projectService.project.stageFloorHeightCm, -this.projectService.project.stageDepthCm / 2 + this.projectService.project.stagePillarWidthCm / 2);
|
|
475
|
+
this.scene.add(mesh);
|
|
476
|
+
this.stageMeshes.push(mesh);
|
|
477
|
+
// Ceiling
|
|
478
|
+
geometry = new THREE.BoxGeometry(this.projectService.project.stageWidthCm, this.projectService.project.stageCeilingHeightCm, this.projectService.project.stageDepthCm);
|
|
479
|
+
mesh = new THREE.Mesh(geometry, this.stageMaterial);
|
|
480
|
+
this.prepareStageMesh(mesh);
|
|
481
|
+
mesh.position.set(0, this.projectService.project.stageHeightCm +
|
|
482
|
+
this.projectService.project.stageCeilingHeightCm / 2 +
|
|
483
|
+
this.projectService.project.stageFloorHeightCm, 0);
|
|
484
|
+
this.scene.add(mesh);
|
|
485
|
+
this.stageMeshes.push(mesh);
|
|
486
|
+
}
|
|
487
|
+
static { this.ɵfac = function PreviewService_Factory(t) { return new (t || PreviewService)(i0.ɵɵinject(i1.PresetService), i0.ɵɵinject(i2.FixtureService), i0.ɵɵinject(i3.SceneService), i0.ɵɵinject(i4.TimelineService), i0.ɵɵinject(i5.UniverseService), i0.ɵɵinject(i6.ProjectService)); }; }
|
|
488
|
+
static { this.ɵprov = /*@__PURE__*/ i0.ɵɵdefineInjectable({ token: PreviewService, factory: PreviewService.ɵfac, providedIn: 'root' }); }
|
|
489
|
+
}
|
|
490
|
+
(() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(PreviewService, [{
|
|
491
|
+
type: Injectable,
|
|
492
|
+
args: [{
|
|
493
|
+
providedIn: 'root',
|
|
494
|
+
}]
|
|
495
|
+
}], () => [{ type: i1.PresetService }, { type: i2.FixtureService }, { type: i3.SceneService }, { type: i4.TimelineService }, { type: i5.UniverseService }, { type: i6.ProjectService }], null); })();
|
|
496
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicHJldmlldy5zZXJ2aWNlLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vcHJvamVjdHMvZGVzaWduZXIvc3JjL2xpYi9zZXJ2aWNlcy9wcmV2aWV3LnNlcnZpY2UudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLFVBQVUsRUFBRSxNQUFNLGVBQWUsQ0FBQztBQUMzQyxPQUFPLEVBQUUsT0FBTyxFQUFFLE1BQU0sTUFBTSxDQUFDO0FBQy9CLE9BQU8sS0FBSyxLQUFLLE1BQU0sT0FBTyxDQUFDO0FBRS9CLE9BQU8sRUFBRSxXQUFXLEVBQUUsTUFBTSx3QkFBd0IsQ0FBQztBQUNyRCxPQUFPLEVBQUUscUJBQXFCLEVBQUUsTUFBTSw4QkFBOEIsQ0FBQztBQUNyRSxPQUFPLEVBQUUsbUJBQW1CLEVBQUUsTUFBTSxpQ0FBaUMsQ0FBQztBQUV0RSxPQUFPLEVBQUUsaUJBQWlCLEVBQUUsTUFBTSwrQkFBK0IsQ0FBQztBQUVsRSxPQUFPLEVBQUUsY0FBYyxFQUFFLE1BQU0sbUJBQW1CLENBQUM7QUFDbkQsT0FBTyxFQUFFLGFBQWEsRUFBRSxNQUFNLGtCQUFrQixDQUFDO0FBQ2pELE9BQU8sRUFBRSxjQUFjLEVBQUUsTUFBTSxtQkFBbUIsQ0FBQztBQUNuRCxPQUFPLEVBQUUsWUFBWSxFQUFFLE1BQU0saUJBQWlCLENBQUM7QUFDL0MsT0FBTyxFQUFFLGVBQWUsRUFBRSxNQUFNLG9CQUFvQixDQUFDO0FBQ3JELE9BQU8sRUFBRSxlQUFlLEVBQUUsTUFBTSxvQkFBb0IsQ0FBQzs7Ozs7Ozs7QUFLckQsTUFBTSxPQUFPLGNBQWM7SUFZekIsWUFDVSxhQUE0QixFQUM1QixjQUE4QixFQUM5QixZQUEwQixFQUMxQixlQUFnQyxFQUNoQyxlQUFnQyxFQUNoQyxjQUE4QjtRQUw5QixrQkFBYSxHQUFiLGFBQWEsQ0FBZTtRQUM1QixtQkFBYyxHQUFkLGNBQWMsQ0FBZ0I7UUFDOUIsaUJBQVksR0FBWixZQUFZLENB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S0FBSyxDQUFDLEdBQUcsQ0FBQyxJQUFJLENBQUMsQ0FBQztRQUNyQixJQUFJLENBQUMsV0FBVyxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsQ0FBQztRQUU1QixVQUFVO1FBQ1YsUUFBUSxHQUFHLElBQUksS0FBSyxDQUFDLFdBQVcsQ0FDOUIsSUFBSSxDQUFDLGNBQWMsQ0FBQyxPQUFPLENBQUMsWUFBWSxFQUN4QyxJQUFJLENBQUMsY0FBYyxDQUFDLE9BQU8sQ0FBQyxvQkFBb0IsRUFDaEQsSUFBSSxDQUFDLGNBQWMsQ0FBQyxPQUFPLENBQUMsWUFBWSxDQUN6QyxDQUFDO1FBQ0YsSUFBSSxHQUFHLElBQUksS0FBSyxDQUFDLElBQUksQ0FBQyxRQUFRLEVBQUUsSUFBSSxDQUFDLGFBQWEsQ0FBQyxDQUFDO1FBQ3BELElBQUksQ0FBQyxnQkFBZ0IsQ0FBQyxJQUFJLENBQUMsQ0FBQztRQUM1QixJQUFJLENBQUMsUUFBUSxDQUFDLEdBQUcsQ0FDZixDQUFDLEVBQ0QsSUFBSSxDQUFDLGNBQWMsQ0FBQyxPQUFPLENBQUMsYUFBYTtZQUN2QyxJQUFJLENBQUMsY0FBYyxDQUFDLE9BQU8sQ0FBQyxvQkFBb0IsR0FBRyxDQUFDO1lBQ3BELElBQUksQ0FBQyxjQUFjLENBQUMsT0FBTyxDQUFDLGtCQUFrQixFQUNoRCxDQUFDLENBQ0YsQ0FBQztRQUNGLElBQUksQ0FBQyxLQUFLLENBQUMsR0FBRyxDQUFDLElBQUksQ0FBQyxDQUFDO1FBQ3JCLElBQUksQ0FBQyxXQUFXLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxDQUFDO0lBQzlCLENBQUM7K0VBNW5CVSxjQUFjO3VFQUFkLGNBQWMsV0FBZCxjQUFjLG1CQUZiLE1BQU07O2lGQUVQLGNBQWM7Y0FIMUIsVUFBVTtlQUFDO2dCQUNWLFVBQVUsRUFBRSxNQUFNO2FBQ25CIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgSW5qZWN0YWJsZSB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHsgU3ViamVjdCB9IGZyb20gJ3J4anMnO1xuaW1wb3J0ICogYXMgVEhSRUUgZnJvbSAndGhyZWUnO1xuaW1wb3J0IHsgQ2FjaGVkRml4dHVyZSB9IGZyb20gJy4uL21vZGVscy9jYWNoZWQtZml4dHVyZSc7XG5pbXBvcnQgeyBFZmZlY3RDdXJ2ZSB9IGZyb20gJy4uL21vZGVscy9lZmZlY3QtY3VydmUnO1xuaW1wb3J0IHsgRml4dHVyZUNhcGFiaWxpdHlUeXBlIH0gZnJvbSAnLi4vbW9kZWxzL2ZpeHR1cmUtY2FwYWJpbGl0eSc7XG5pbXBvcnQgeyBGaXh0dXJlQ2hhbm5lbFZhbHVlIH0gZnJvbSAnLi4vbW9kZWxzL2ZpeHR1cmUtY2hhbm5lbC12YWx1ZSc7XG5pbXBvcnQgeyBQcmVzZXQgfSBmcm9tICcuLi9tb2RlbHMvcHJlc2V0JztcbmltcG9ydCB7IFByZXNldFJlZ2lvblNjZW5lIH0gZnJvbSAnLi4vbW9kZWxzL3ByZXNldC1yZWdpb24tc2NlbmUnO1xuaW1wb3J0IHsgVW5pdmVyc2UgfSBmcm9tICcuLi9tb2RlbHMvdW5pdmVyc2UnO1xuaW1wb3J0IHsgRml4dHVyZVNlcnZpY2UgfSBmcm9tICcuL2ZpeHR1cmUuc2VydmljZSc7XG5pbXBvcnQgeyBQcmVzZXRTZXJ2aWNlIH0gZnJvbSAnLi9wcmVzZXQuc2VydmljZSc7XG5pbXBvcnQgeyBQcm9qZWN0U2VydmljZSB9IGZyb20gJy4vcHJvamVjdC5zZXJ2aWNlJztcbmltcG9ydCB7IFNjZW5lU2VydmljZSB9IGZyb20gJy4vc2NlbmUuc2VydmljZSc7XG5pbXBvcnQgeyBUaW1lbGluZVNlcnZpY2UgfSBmcm9tICcuL3RpbWVsaW5lLnNlcnZpY2UnO1xuaW1wb3J0IHsgVW5pdmVyc2VTZXJ2aWNlIH0gZnJvbSAnLi91bml2ZXJzZS5zZXJ2aWNlJztcblxuQEluamVjdGFibGUoe1xuICBwcm92aWRlZEluOiAncm9vdCcsXG59KVxuZXhwb3J0IGNsYXNzIFByZXZpZXdTZXJ2aWNlIHtcbiAgcHVibGljIGRvVXBkYXRlRml4dHVyZVNldHVwOiBTdWJqZWN0PHZvaWQ+ID0gbmV3IFN1YmplY3QoKTtcblxuICBwdWJsaWMgc2NlbmU6IFRIUkVFLlNjZW5lO1xuXG4gIHByaXZhdGUgc3RhZ2VNZXNoZXM6IFRIUkVFLk1lc2hbXSA9IFtdO1xuICBwcml2YXRlIHN0YWdlTWF0ZXJpYWwgPSBuZXcgVEhSRUUuTWVzaFN0YW5kYXJkTWF0ZXJpYWwoe1xuICAgIGNvbG9yOiAweDBkMGQwZCxcbiAgICAvLyByb3VnaG5lc3M6IDAuNSxcbiAgICAvLyBtZXRhbG5lc3M6IDAuNSxcbiAgfSk7XG5cbiAgY29uc3RydWN0b3IoXG4gICAgcHJpdmF0ZSBwcmVzZXRTZXJ2aWNlOiBQcmVzZXRTZXJ2aWNlLFxuICAgIHByaXZhdGUgZml4dHVyZVNlcnZpY2U6IEZpeHR1cmVTZXJ2aWNlLFxuICAgIHByaXZhdGUgc2NlbmVTZXJ2aWNlOiBTY2VuZVNlcnZpY2UsXG4gICAgcHJpdmF0ZSB0aW1lbGluZVNlcnZpY2U6IFRpbWVsaW5lU2VydmljZSxcbiAgICBwcml2YXRlIHVuaXZlcnNlU2VydmljZTogVW5pdmVyc2VTZXJ2aWNlLFxuICAgIHByaXZhdGUgcHJvamVjdFNlcnZpY2U6IFByb2plY3RTZXJ2aWNlXG4gICkge31cblxuICBwcml2YXRlIGdldEFscmVhZHlDYWxjdWxhdGVkRml4dHVyZShmaXh0dXJlczogQ2FjaGVkRml4dHVyZVtdLCBmaXh0dXJlSW5kZXg6IG51bWJlcik6IENhY2hlZEZpeHR1cmUge1xuICAgIC8vIEhhcyB0aGlzIGZpeHR1cmUgYWxyZWFkeSBiZWVuIGNhbGN1bGF0ZWQgKHNhbWUgdW5pdmVyc2UgYW5kIGRteCBzdGFydCBhZGRyZXNzIGFzIGEgZml4dHVyZSBiZWZvcmUpXG4gICAgLy8gLS0+IHJldHVybiBpdFxuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgZml4dHVyZUluZGV4OyBpKyspIHtcbiAgICAgIGNvbnN0IGNhbGN1bGF0ZWRGaXh0dXJlID0gZml4dHVyZXNbaV07XG5cbiAgICAgIGlmIChcbiAgICAgICAgY2FsY3VsYXRlZEZpeHR1cmUuZml4dHVyZS5kbXhVbml2ZXJzZVV1aWQgPT09IGZpeHR1cmVzW2ZpeHR1cmVJbmRleF0uZml4dHVyZS5kbXhVbml2ZXJzZVV1aWQgJiZcbiAgICAgICAgY2FsY3VsYXRlZEZpeHR1cmUuZml4dHVyZS5kbXhGaXJzdENoYW5uZWwgPT09IGZpeHR1cmVzW2ZpeHR1cmVJbmRleF0uZml4dHVyZS5kbXhGaXJzdENoYW5uZWxcbiAgICAgICkge1xuICAgICAgICByZXR1cm4gY2FsY3VsYXRlZEZpeHR1cmU7XG4gICAgICB9XG4gICAgfVxuXG4gICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgfVxuXG4gIHB1YmxpYyBnZXRQcmVzZXRzKHRpbWVNaWxsaXM6IG51bWJlcik6IFByZXNldFJlZ2lvblNjZW5lW10ge1xuICAgIC8vIEdldCByZWxldmFudCBwcmVzZXRzIGluIGNvcnJlY3Qgb3JkZXIgdG8gcHJvY2VzcyB3aXRoIHRoZWlyIGNvcnJlc3BvbmRpbmcgc2NlbmUsIGlmIGF2YWlsYWJsZVxuICAgIGxldCBwcmVzZXRzOiBQcmVzZXRSZWdpb25TY2VuZVtdID0gW107XG5cbiAgICBpZiAodGhpcy50aW1lbGluZVNlcnZpY2UucGxheVN0YXRlID09PSAncGxheWluZycpIHtcbiAgICAgIC8vIE9ubHkgdXNlIGFjdGl2ZSBwcmVzZXRzIGluIGN1cnJlbnQgcmVnaW9uc1xuICAgICAgcHJlc2V0cyA9IHRoaXMudGltZWxpbmVTZXJ2aWNlLmdldFByZXNldHNJblRpbWUodGltZU1pbGxpcyk7XG4gICAgfSBlbHNlIHtcbiAgICAgIGlmICh0aGlzLnByb2plY3RTZXJ2aWNlLnByb2plY3QucHJldmlld1ByZXNldCkge1xuICAgICAgICAvLyBPbmx5IHByZXZpZXcgdGhlIHNlbGVjdGVkIHByZXNldFxuICAgICAgICBpZiAodGhpcy5wcmVzZXRTZXJ2aWNlLnNlbGVjdGVkUHJlc2V0KSB7XG4gICAgICAgICAgcHJlc2V0cy5wdXNoKG5ldyBQcmVzZXRSZWdpb25TY2VuZSh0aGlzLnByZXNldFNlcnZpY2Uuc2VsZWN0ZWRQcmVzZXQsIHVuZGVmaW5lZCwgdW5kZWZpbmVkKSk7XG4gICAgICAgIH1cbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIC8vIFByZXZpZXcgdGhlIHNlbGVjdGVkIHNjZW5lc1xuICAgICAgICBmb3IgKGxldCBzY2VuZUluZGV4ID0gdGhpcy5wcm9qZWN0U2VydmljZS5wcm9qZWN0LnNjZW5lcy5sZW5ndGggLSAxOyBzY2VuZUluZGV4ID49IDA7IHNjZW5lSW5kZXgtLSkge1xuICAgICAgICAgIGZvciAoY29uc3Qgc2NlbmUgb2YgdGhpcy5zY2VuZVNlcnZpY2Uuc2VsZWN0ZWRTY2VuZXMpIHtcbiAgICAgICAgICAgIGlmIChzY2VuZS51dWlkID09PSB0aGlzLnByb2plY3RTZXJ2aWNlLnByb2plY3Quc2NlbmVzW3NjZW5lSW5kZXhdLnV1aWQpIHtcbiAgICAgICAgICAgICAgZm9yIChsZXQgcHJlc2V0SW5kZXggPSB0aGlzLnByb2plY3RTZXJ2aWNlLnByb2plY3QucHJlc2V0cy5sZW5ndGggLSAxOyBwcmVzZXRJbmRleCA+PSAwOyBwcmVzZXRJbmRleC0tKSB7XG4gICAgICAgICAgICAgICAgZm9yIChjb25zdCBwcmVzZXRVdWlkIG9mIHNjZW5lLnByZXNldFV1aWRzKSB7XG4gICAgICAgICAgICAgICAgICAvLyBMb29wIG92ZXIgdGhlIHByZXNldHMgaW4gdGhlIHByZXNldCBzZXJ2aWNlIHRvIHJldGFpbiB0aGUgcHJlc2V0IG9yZGVyXG4gICAgICAgICAgICAgICAgICBpZiAocHJlc2V0VXVpZCA9PT0gdGhpcy5wcm9qZWN0U2VydmljZS5wcm9qZWN0LnByZXNldHNbcHJlc2V0SW5kZXhdLnV1aWQpIHtcbiAgICAgICAgICAgICAgICAgICAgcHJlc2V0cy5wdXNoKG5ldyBQcmVzZXRSZWdpb25TY2VuZSh0aGlzLnByb2plY3RTZXJ2aWNlLnByb2plY3QucHJlc2V0c1twcmVzZXRJbmRleF0sIHVuZGVmaW5lZCwgc2NlbmUpKTtcbiAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuXG4gICAgcmV0dXJuIHByZXNldHM7XG4gIH1cblxuICBwcml2YXRlIG1peENoYW5uZWxWYWx1ZShcbiAgICBleGlzdGluZ0NoYW5uZWxWYWx1ZXM6IEZpeHR1cmVDaGFubmVsVmFsdWVbXSxcbiAgICBjaGFubmVsVmFsdWU6IEZpeHR1cmVDaGFubmVsVmFsdWUsXG4gICAgaW50ZW5zaXR5UGVyY2VudGFnZTogbnVtYmVyLFxuICAgIGRlZmF1bHRWYWx1ZTogbnVtYmVyID0gMFxuICApIHtcbiAgICBsZXQgbmV3VmFsdWU6IG51bWJlciA9IGNoYW5uZWxWYWx1ZS52YWx1ZTtcbiAgICBsZXQgZXhpc3RpbmdWYWx1ZTogbnVtYmVyID0gZGVmYXVsdFZhbHVlO1xuXG4gICAgaWYgKGludGVuc2l0eVBlcmNlbnRhZ2UgPCAxKSB7XG4gICAgICAvLyBXZSBuZWVkIHRvIG1peCBhIHBvc3NpYmx5IGV4aXN0aW5nIHZhbHVlIChvciB0aGUgZGVmYXVsdCB2YWx1ZSAwKSB3aXRoIHRoZSBuZXcgdmFsdWUgKGZhZGluZylcblxuICAgICAgLy8gR2V0IHRoZSBleGlzdGVudCB2YWx1ZSBmb3IgdGhpcyBwcm9wZXJ0eVxuICAgICAgZm9yIChjb25zdCBleGlzdGluZ0NoYW5uZWxWYWx1ZSBvZiBleGlzdGluZ0NoYW5uZWxWYWx1ZXMpIHtcbiAgICAgICAgaWYgKFxuICAgICAgICAgIGV4aXN0aW5nQ2hhbm5lbFZhbHVlLmNoYW5uZWxOYW1lID09PSBjaGFubmVsVmFsdWUuY2hhbm5lbE5hbWUgJiZcbiAgICAgICAgICBleGlzdGluZ0NoYW5uZWxWYWx1ZS5wcm9maWxlVXVpZCA9PT0gY2hhbm5lbFZhbHVlLnByb2ZpbGVVdWlkXG4gICAgICAgICkge1xuICAgICAgICAgIGV4aXN0aW5nVmFsdWUgPSBleGlzdGluZ0NoYW5uZWxWYWx1ZS52YWx1ZTtcbiAgICAgICAgICBicmVhaztcbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICAvLyBNaXggdGhlIGV4aXN0aW5nIHZhbHVlIHdpdGggdGhlIG5ldyB2YWx1ZVxuICAgICAgbmV3VmFsdWUgPSBleGlzdGluZ1ZhbHVlICogKDEgLSBpbnRlbnNpdHlQZXJjZW50YWdlKSArIG5ld1ZhbHVlICogaW50ZW5zaXR5UGVyY2VudGFnZTtcbiAgICB9XG5cbiAgICAvLyBSZW1vdmUgdGhlIGV4aXN0ZW50IHZhbHVlLCBpZiBhdmFpbGFibGVcbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IGV4aXN0aW5nQ2hhbm5lbFZhbHVlcy5sZW5ndGg7IGkrKykge1xuICAgICAgaWYgKFxuICAgICAgICBleGlzdGluZ0NoYW5uZWxWYWx1ZXNbaV0uY2hhbm5lbE5hbWUgPT09IGNoYW5uZWxWYWx1ZS5jaGFubmVsTmFtZSAmJlxuICAgICAgICBleGlzdGluZ0NoYW5uZWxWYWx1ZXNbaV0ucHJvZmlsZVV1aWQgPT09IGNoYW5uZWxWYWx1ZS5wcm9maWxlVXVpZFxuICAgICAgKSB7XG4gICAgICAgIGV4aXN0aW5nQ2hhbm5lbFZhbHVlcy5zcGxpY2UoaSwgMSk7XG4gICAgICAgIGJyZWFrO1xuICAgICAgfVxuICAgIH1cblxuICAgIC8vIEFkZCB0aGUgbmV3IHZhbHVlXG4gICAgY29uc3QgZml4dHVyZUNoYW5uZWxWYWx1ZSA9IG5ldyBGaXh0dXJlQ2hhbm5lbFZhbHVlKCk7XG4gICAgZml4dHVyZUNoYW5uZWxWYWx1ZS5jaGFubmVsTmFtZSA9IGNoYW5uZWxWYWx1ZS5jaGFubmVsTmFtZTtcbiAgICBmaXh0dXJlQ2hhbm5lbFZhbHVlLnByb2ZpbGVVdWlkID0gY2hhbm5lbFZhbHVlLnByb2ZpbGVVdWlkO1xuICAgIGZpeHR1cmVDaGFubmVsVmFsdWUudmFsdWUgPSBuZXdWYWx1ZTtcbiAgICBleGlzdGluZ0NoYW5uZWxWYWx1ZXMucHVzaChmaXh0dXJlQ2hhbm5lbFZhbHVlKTtcbiAgfVxuXG4gIC8vIEdldCB0aGUgZml4dHVyZSBpbmRleCBpbnNpZGUgdGhlIHBhc3NlZCBwcmVzZXQgKHVzZWQgZm9yIGNoYXNpbmcpXG4gIHByaXZhdGUgZ2V0Rml4dHVyZUluZGV4KHByZXNldDogUHJlc2V0LCBmaXh0dXJlVXVpZDogc3RyaW5nKTogbnVtYmVyIHtcbiAgICBsZXQgaW5kZXggPSAwO1xuICAgIGNvbnN0IGNvdW50ZWREbXhDaGFubmVsczogbnVtYmVyW10gPSBbXTtcblxuICAgIC8vIExvb3Agb3ZlciB0aGUgZ2xvYmFsIGZpeHR1cmVzIHRvIHJldGFpbiB0aGUgb3JkZXJcbiAgICBmb3IgKGNvbnN0IGZpeHR1cmUgb2YgdGhpcy5wcm9qZWN0U2VydmljZS5wcm9qZWN0LmZpeHR1cmVzKSB7XG4gICAgICBmb3IgKGNvbnN0IHByZXNldEZpeHR1cmVVdWlkIG9mIHByZXNldC5maXh0dXJlVXVpZHMpIHtcbiAgICAgICAgaWYgKHByZXNldEZpeHR1cmVVdWlkID09PSBmaXh0dXJlLnV1aWQpIHtcbiAgICAgICAgICBpZiAoZml4dHVyZS51dWlkID09PSBmaXh0dXJlVXVpZCkge1xuICAgICAgICAgICAgcmV0dXJuIGluZGV4O1xuICAgICAgICAgIH1cblxuICAgICAgICAgIC8vIGRvbid0IGNvdW50IGZpeHR1cmVzIG9uIHRoZSBzYW1lIGNoYW5uZWwgYXMgYWxyZWFkeSBjb3VudGVkIG9uZXNcbiAgICAgICAgICBpZiAoIWNvdW50ZWREbXhDaGFubmVscy5pbmNsdWRlcyhmaXh0dXJlLmRteEZpcnN0Q2hhbm5lbCkpIHtcbiAgICAgICAgICAgIGNvdW50ZWREbXhDaGFubmVscy5wdXNoKGZpeHR1cmUuZG14Rmlyc3RDaGFubmVsKTtcbiAgICAgICAgICAgIGluZGV4Kys7XG4gICAgICAgICAgfVxuICAgICAgICAgIGJyZWFrO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuXG4gICAgLy8gTm90IGZvdW5kIGluIHRoZSBwcmVzZXRcbiAgICByZXR1cm4gdW5kZWZpbmVkO1xuICB9XG5cbiAgcHJpdmF0ZSBnZXRQcmVzZXRJbnRlbnNpdHkocHJlc2V0OiBQcmVzZXRSZWdpb25TY2VuZSwgdGltZU1pbGxpczogbnVtYmVyKTogbnVtYmVyIHtcbiAgICAvLyBXaGVuIGZhZGluZyBpcyBpbiBwcm9ncmVzcyAob24gcHJlc2V0IG9yIHNjZW5lLWxldmVsKSwgdGhlIGN1cnJlbnQgcHJlc2V0IGRvZXMgbm90XG4gICAgLy8gZnVsbHkgY292ZXIgdW5kZXJseWluZyB2YWx1ZXMuXG4gICAgLy8gLT4gMCA9IG5vIGNvdmVyaW5nIGF0IGFsbCwgMSA9IGZ1bGx5IGNvdmVyIChubyBmYWRpbmcpXG4gICAgbGV0IGludGVuc2l0eVBlcmNlbnRhZ2VTY2VuZSA9IDE7XG4gICAgbGV0IGludGVuc2l0eVBlcmNlbnRhZ2VQcmVzZXQgPSAxO1xuICAgIGxldCBpbnRlbnNpdHlQZXJjZW50YWdlID0gMTtcblxuICAgIGlmIChwcmVzZXQucmVnaW9uICYmIHByZXNldC5zY2VuZSkge1xuICAgICAgLy8gRmFkZSBvdXQgaXMgc3Ryb25nZXIgdGhhbiBmYWRlIGluIChpZiB0aGV5IG92ZXJsYXApXG5cbiAgICAgIC8vIFRha2UgYXdheSBpbnRlbnNpdHkgZm9yIHNjZW5lIGZhZGluZ1xuICAgICAgY29uc3Qgc2NlbmVTdGFydE1pbGxpcyA9IHByZXNldC5zY2VuZS5mYWRlSW5QcmUgPyBwcmVzZXQucmVnaW9uLnN0YXJ0TWlsbGlzIC0gcHJlc2V0LnNjZW5lLmZhZGVJbk1pbGxpcyA6IHByZXNldC5yZWdpb24uc3RhcnRNaWxsaXM7XG4gICAgICBjb25zdCBzY2VuZUVuZE1pbGxpcyA9IHByZXNldC5zY2VuZS5mYWRlT3V0UG9zdCA/IHByZXNldC5yZWdpb24uZW5kTWlsbGlzICsgcHJlc2V0LnNjZW5lLmZhZGVPdXRNaWxsaXMgOiBwcmVzZXQucmVnaW9uLmVuZE1pbGxpcztcblxuICAgICAgaWYgKHRpbWVNaWxsaXMgPiBzY2VuZUVuZE1pbGxpcyAtIHByZXNldC5zY2VuZS5mYWRlT3V0TWlsbGlzICYmIHRpbWVNaWxsaXMgPCBzY2VuZUVuZE1pbGxpcykge1xuICAgICAgICAvLyBTY2VuZSBmYWRlcyBvdXRcbiAgICAgICAgaW50ZW5zaXR5UGVyY2VudGFnZVNjZW5lID0gKHNjZW5lRW5kTWlsbGlzIC0gdGltZU1pbGxpcykgLyBwcmVzZXQuc2NlbmUuZmFkZU91dE1pbGxpcztcbiAgICAgIH0gZWxzZSBpZiAodGltZU1pbGxpcyA8IHNjZW5lU3RhcnRNaWxsaXMgKyBwcmVzZXQuc2NlbmUuZmFkZUluTWlsbGlzICYmIHRpbWVNaWxsaXMgPiBzY2VuZVN0YXJ0TWlsbGlzKSB7XG4gICAgICAgIC8vIFNjZW5lIGZhZGVzIGluXG4gICAgICAgIGludGVuc2l0eVBlcmNlbnRhZ2VTY2VuZSA9ICh0aW1lTWlsbGlzIC0gc2NlbmVTdGFydE1pbGxpcykgLyBwcmVzZXQuc2NlbmUuZmFkZUluTWlsbGlzO1xuICAgICAgfVxuICAgIH1cblxuICAgIGlmIChwcmVzZXQucmVnaW9uICYmIHByZXNldC5wcmVzZXQpIHtcbiAgICAgIC8vIFRha2UgYXdheSBpbnRlbnNpdHkgZm9yIHByZXNldCBmYWRpbmdcbiAgICAgIGxldCBwcmVzZXRTdGFydE1pbGxpcyA9XG4gICAgICAgIHByZXNldC5wcmVzZXQuc3RhcnRNaWxsaXMgPT09IHVuZGVmaW5lZCA/IHByZXNldC5yZWdpb24uc3RhcnRNaWxsaXMgOiBwcmVzZXQucmVnaW9uLnN0YXJ0TWlsbGlzICsgcHJlc2V0LnByZXNldC5zdGFydE1pbGxpcztcblxuICAgICAgbGV0IHByZXNldEVuZE1pbGxpcyA9XG4gICAgICAgIHByZXNldC5wcmVzZXQuZW5kTWlsbGlzID09PSB1bmRlZmluZWQgPyBwcmVzZXQucmVnaW9uLmVuZE1pbGxpcyA6IHByZXNldC5yZWdpb24uc3RhcnRNaWxsaXMgKyBwcmVzZXQucHJlc2V0LmVuZE1pbGxpcztcblxuICAgICAgLy8gZXh0ZW5kIHRoZSBydW5uaW5nIHRpbWUsIGlmIGZhZGluZyBpcyBkb25lIG91dHNpZGUgdGhlIGJvdW5kYXJpZXNcbiAgICAgIHByZXNldFN0YXJ0TWlsbGlzIC09IHByZXNldC5wcmVzZXQuZmFkZUluUHJlID8gcHJlc2V0LnByZXNldC5mYWRlSW5NaWxsaXMgOiAwO1xuICAgICAgcHJlc2V0RW5kTWlsbGlzICs9IHByZXNldC5wcmVzZXQuZmFkZU91dFBvc3QgPyBwcmVzZXQucHJlc2V0LmZhZGVPdXRNaWxsaXMgOiAwO1xuXG4gICAgICBpZiAodGltZU1pbGxpcyA+IHByZXNldEVuZE1pbGxpcyAtIHByZXNldC5wcmVzZXQuZmFkZU91dE1pbGxpcyAmJiB0aW1lTWlsbGlzIDwgcHJlc2V0RW5kTWlsbGlzKSB7XG4gICAgICAgIC8vIFByZXNldCBmYWRlcyBvdXRcbiAgICAgICAgaW50ZW5zaXR5UGVyY2VudGFnZVByZXNldCA9IChwcmVzZXRFbmRNaWxsaXMgLSB0aW1lTWlsbGlzKSAvIHByZXNldC5wcmVzZXQuZmFkZU91dE1pbGxpcztcbiAgICAgIH0gZWxzZSBpZiAodGltZU1pbGxpcyA8IHByZXNldFN0YXJ0TWlsbGlzICsgcHJlc2V0LnByZXNldC5mYWRlSW5NaWxsaXMgJiYgdGltZU1pbGxpcyA+IHByZXNldFN0YXJ0TWlsbGlzKSB7XG4gICAgICAgIC8vIFByZXNldCBmYWRlcyBpblxuICAgICAgICBpbnRlbnNpdHlQZXJjZW50YWdlUHJlc2V0ID0gKHRpbWVNaWxsaXMgLSBwcmVzZXRTdGFydE1pbGxpcykgLyBwcmVzZXQucHJlc2V0LmZhZGVJbk1pbGxpcztcbiAgICAgIH1cblxuICAgICAgaW50ZW5zaXR5UGVyY2VudGFnZSA9IGludGVuc2l0eVBlcmNlbnRhZ2VTY2VuZSAqIGludGVuc2l0eVBlcmNlbnRhZ2VQcmVzZXQ7XG4gICAgfVxuXG4gICAgcmV0dXJuIGludGVuc2l0eVBlcmNlbnRhZ2U7XG4gIH1cblxuICBwcml2YXRlIG1peENhcGFiaWxpdHlWYWx1ZXMoXG4gICAgcHJlc2V0OiBQcmVzZXRSZWdpb25TY2VuZSxcbiAgICBjYWNoZWRGaXh0dXJlOiBDYWNoZWRGaXh0dXJlLFxuICAgIHZhbHVlczogRml4dHVyZUNoYW5uZWxWYWx1ZVtdLFxuICAgIGludGVuc2l0eVBlcmNlbnRhZ2U6IG51bWJlclxuICApIHtcbiAgICBsZXQgaGFzQ29sb3IgPSBmYWxzZTtcblxuICAgIC8vIG1peCB0aGUgcHJlc2V0IGNhcGFiaWxpdHkgdmFsdWVzXG4gICAgZm9yIChjb25zdCBwcmVzZXRDYXBhYmlsaXR5VmFsdWUgb2YgcHJlc2V0LnByZXNldC5maXh0dXJlQ2FwYWJpbGl0eVZhbHVlcykge1xuICAgICAgZm9yIChjb25zdCBjYWNoZWRDaGFubmVsIG9mIGNhY2hlZEZpeHR1cmUuY2hhbm5lbHMpIHtcbiAgICAgICAgaWYgKGNhY2hlZENoYW5uZWwuY2hhbm5lbCkge1xuICAgICAgICAgIGZvciAoY29uc3QgY2hhbm5lbENhcGFiaWxpdHkgb2YgY2FjaGVkQ2hhbm5lbC5jYXBhYmlsaXRpZXMpIHtcbiAgICAgICAgICAgIGlmIChcbiAgICAgICAgICAgICAgdGhpcy5maXh0dXJlU2VydmljZS5jYXBhYmlsaXRpZXNNYXRjaChcbiAgICAgICAgICAgICAgICBwcmVzZXRDYXBhYmlsaXR5VmFsdWUudHlwZSxcbiAgICAgICAgICAgICAgICBjaGFubmVsQ2FwYWJpbGl0eS5jYXBhYmlsaXR5LnR5cGUsXG4gICAgICAgICAgICAgICAgcHJlc2V0Q2FwYWJpbGl0eVZhbHVlLmNvbG9yLFxuICAgICAgICAgICAgICAgIGNoYW5uZWxDYXBhYmlsaXR5LmNhcGFiaWxpdHkuY29sb3IsXG4gICAgICAgICAgICAgICAgcHJlc2V0Q2FwYWJpbGl0eVZhbHVlLndoZWVsLFxuICAgICAgICAgICAgICAgIGNoYW5uZWxDYXBhYmlsaXR5LndoZWVsTmFtZSxcbiAgICAgICAgICAgICAgICBwcmVzZXRDYXBhYmlsaXR5VmFsdWUucHJvZmlsZVV1aWQsXG4gICAgICAgICAgICAgICAgY2FjaGVkRml4dHVyZS5wcm9maWxlLnV1aWRcbiAgICAgICAgICAgICAgKVxuICAgICAgICAgICAgKSB7XG4gICAgICAgICAgICAgIC8vIHRoZSBjYXBhYmlsaXRpZXMgbWF0Y2ggLT4gYXBwbHkgdGhlIHZhbHVlLCBpZiBwb3NzaWJsZVxuICAgICAgICAgICAgICBpZiAoXG4gICAgICAgICAgICAgICAgKHByZXNldENhcGFiaWxpdHlWYWx1ZS50eXBlID09PSBGaXh0dXJlQ2FwYWJpbGl0eVR5cGUuSW50ZW5zaXR5IHx8XG4gICAgICAgICAgICAgICAgICBwcmVzZXRDYXBhYmlsaXR5VmFsdWUudHlwZSA9PT0gRml4dHVyZUNhcGFiaWxpdHlUeXBlLkNvbG9ySW50ZW5zaXR5KSAmJlxuICAgICAgICAgICAgICAgIHByZXNldENhcGFiaWxpdHlWYWx1ZS52YWx1ZVBlcmNlbnRhZ2UgPj0gMFxuICAgICAgICAgICAgICApIHtcbiAgICAgICAgICAgICAgICAvLyBpbnRlbnNpdHkgYW5kIGNvbG9ySW50ZW5zaXR5IChkaW1tZXIgYW5kIGNvbG9yKVxuICAgICAgICAgICAgICAgIGNvbnN0IHZhbHVlUGVyY2VudGFnZSA9IHByZXNldENhcGFiaWxpdHlWYWx1ZS52YWx1ZVBlcmNlbnRhZ2U7XG4gICAgICAgICAgICAgICAgY29uc3QgZGVmYXVsdFZhbHVlID0gMDtcblxuICAgICAgICAgICAgICAgIC8vIGJyaWdodG5lc3MgcHJvcGVydHlcbiAgICAgICAgICAgICAgICBpZiAoY2FjaGVkQ2hhbm5lbC5jYXBhYmlsaXRpZXMubGVuZ3RoID09PSAxKSB7XG4gICAgICAgICAgICAgICAgICAvLyB0aGUgb25seSBjYXBhYmlsaXR5IGluIHRoaXMgY2hhbm5lbFxuICAgICAgICAgICAgICAgICAgY29uc3QgZml4dHVyZUNoYW5uZWxWYWx1ZSA9IG5ldyBGaXh0dXJlQ2hhbm5lbFZhbHVlKCk7XG4gICAgICAgICAgICAgICAgICBmaXh0dXJlQ2hhbm5lbFZhbHVlLmNoYW5uZWxOYW1lID0gY2FjaGVkQ2hhbm5lbC5uYW1lO1xuICAgICAgICAgICAgICAgICAgZml4dHVyZUNoYW5uZWxWYWx1ZS5wcm9maWxlVXVpZCA9IGNhY2hlZEZpeHR1cmUucHJvZmlsZS51dWlkO1xuICAgICAgICAgICAgICAgICAgZml4dHVyZUNoYW5uZWxWYWx1ZS52YWx1ZSA9IGNhY2hlZENoYW5uZWwubWF4VmFsdWUgKiB2YWx1ZVBlcmNlbnRhZ2U7XG4gICAgICAgICAgICAgICAgICB0aGlzLm1peENoYW5uZWxWYWx1ZSh2YWx1ZXMsIGZpeHR1cmVDaGFubmVsVmFsdWUsIGludGVuc2l0eVBlcmNlbnRhZ2UsIGRlZmF1bHRWYWx1ZSk7XG5cbiAgICAgICAgICAgICAgICAgIGlmIChwcmVzZXRDYXBhYmlsaXR5VmFsdWUudHlwZSA9PT0gRml4dHVyZUNhcGFiaWxpdHlUeXBlLkNvbG9ySW50ZW5zaXR5KSB7XG4gICAgICAgICAgICAgICAgICAgIGhhc0NvbG9yID0gdHJ1ZTtcbiAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgLy8gbW9yZSB0aGFuIG9uZSBjYXBhYmlsaXR5IGluIHRoZSBjaGFubmVsXG4gICAgICAgICAgICAgICAgICBpZiAoY2hhbm5lbENhcGFiaWxpdHkuY2FwYWJpbGl0eS5icmlnaHRuZXNzID09PSAnb2ZmJyAmJiB2YWx1ZVBlcmNlbnRhZ2UgPT09IDApIHtcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgZml4dHVyZUNoYW5uZWxWYWx1ZSA9IG5ldyBGaXh0dXJlQ2hhbm5lbFZhbHVlKCk7XG4gICAgICAgICAgICAgICAgICAgIGZpeHR1cmVDaGFubmVsVmFsdWUuY2hhbm5lbE5hbWUgPSBjYWNoZWRDaGFubmVsLm5hbWU7XG4gICAgICAgICAgICAgICAgICAgIGZpeHR1cmVDaGFubmVsVmFsdWUucHJvZmlsZVV1aWQgPSBjYWNoZWRGaXh0dXJlLnByb2ZpbGUudXVpZDtcbiAgICAgICAgICAgICAgICAgICAgZml4dHVyZUNoYW5uZWxWYWx1ZS52YWx1ZSA9IGNoYW5uZWxDYXBhYmlsaXR5LmNlbnRlclZhbHVlO1xuICAgICAgICAgICAgICAgICAgICB0aGlzLm1peENoYW5uZWxWYWx1ZSh2YWx1ZXMsIGZpeHR1cmVDaGFubmVsVmFsdWUsIGludGVuc2l0eVBlcmNlbnRhZ2UsIGRlZmF1bHRWYWx1ZSk7XG5cbiAgICAgICAgICAgICAgICAgICAgaWYgKHByZXNldENhcGFiaWxpdHlWYWx1ZS50eXBlID09PSBGaXh0dXJlQ2FwYWJpbGl0eVR5cGUuQ29sb3JJbnRlbnNpdHkpIHtcbiAgICAgICAgICAgICAgICAgICAgICBoYXNDb2xvciA9IHRydWU7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAoXG4gICAgICAgICAgICAgICAgICAgIChjaGFubmVsQ2FwYWJpbGl0eS5jYXBhYmlsaXR5LmJyaWdodG5lc3NTdGFydCA9PT0gJ2RhcmsnIHx8IGNoYW5uZWxDYXBhYmlsaXR5LmNhcGFiaWxpdHkuYnJpZ2h0bmVzc1N0YXJ0ID09PSAnb2ZmJykgJiZcbiAgICAgICAgICAgICAgICAgICAgY2hhbm5lbENhcGFiaWxpdHkuY2FwYWJpbGl0eS5icmlnaHRuZXNzRW5kID09PSAnYnJpZ2h0J1xuICAgICAgICAgICAgICAgICAgKSB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IHZhbHVlID1cbiAgICAgICAgICAgICAgICAgICAgICAoY2hhbm5lbENhcGFiaWxpdHkuY2FwYWJpbGl0eS5kbXhSYW5nZVsxXSAtIGNoYW5uZWxDYXBhYmlsaXR5LmNhcGFiaWxpdHkuZG14UmFuZ2VbMF0pICogdmFsdWVQZXJjZW50YWdlICtcbiAgICAgICAgICAgICAgICAgICAgICBjaGFubmVsQ2FwYWJpbGl0eS5jYXBhYmlsaXR5LmRteFJhbmdlWzBdO1xuXG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IGZpeHR1cmVDaGFubmVsVmFsdWUgPSBuZXcgRml4dHVyZUNoYW5uZWxWYWx1ZSgpO1xuICAgICAgICAgICAgICAgICAgICBmaXh0dXJlQ2hhbm5lbFZhbHVlLmNoYW5uZWxOYW1lID0gY2FjaGVkQ2hhbm5lbC5uYW1lO1xuICAgICAgICAgICAgICAgICAgICBmaXh0dXJlQ2hhbm5lbFZhbHVlLnByb2ZpbGVVdWlkID0gY2FjaGVkRml4dHVyZS5wcm9maWxlLnV1aWQ7XG4gICAgICAgICAgICAgICAgICAgIGZpeHR1cmVDaGFubmVsVmFsdWUudmFsdWUgPSB2YWx1ZTtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5taXhDaGFubmVsVmFsdWUodmFsdWVzLCBmaXh0dXJlQ2hhbm5lbFZhbHVlLCBpbnRlbnNpdHlQZXJjZW50YWdlLCBkZWZhdWx0VmFsdWUpO1xuXG4gICAgICAgICAgICAgICAgICAgIGlmIChwcmVzZXRDYXBhYmlsaXR5VmFsdWUudHlwZSA9PT0gRml4dHVyZUNhcGFiaWxpdHlUeXBlLkNvbG9ySW50ZW5zaXR5KSB7XG4gICAgICAgICAgICAgICAgICAgICAgaGFzQ29sb3IgPSB0cnVlO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICB9IGVsc2UgaWYgKFxuICAgICAgICAgICAgICAgIChwcmVzZXRDYXBhYmlsaXR5VmFsdWUudHlwZSA9PT0gRml4dHVyZUNhcGFiaWxpdHlUeXBlLlBhbiB8fCBwcmVzZXRDYXBhYmlsaXR5VmFsdWUudHlwZSA9PT0gRml4dHVyZUNhcGFiaWxpdHlUeXBlLlRpbHQpICYmXG4gICAgICAgICAgICAgICAgcHJlc2V0Q2FwYWJpbGl0eVZhbHVlLnZhbHVlUGVyY2VudGFnZSA+PSAwXG4gICAgICAgICAgICAgICkge1xuICAgICAgICAgICAgICAgIGNvbnN0IGZpeHR1cmVDaGFubmVsVmFsdWUgPSBuZXcgRml4dHVyZUNoYW5uZWxWYWx1ZSgpO1xuICAgICAgICAgICAgICAgIGZpeHR1cmVDaGFubmVsVmFsdWUuY2hhbm5lbE5hbWUgPSBjYWNoZWRDaGFubmVsLm5hbWU7XG4gICAgICAgICAgICAgICAgZml4dHVyZUNoYW5uZWxWYWx1ZS5wcm9maWxlVXVpZCA9IGNhY2hlZEZpeHR1cmUucHJvZmlsZS51dWlkO1xuICAgICAgICAgICAgICAgIGZpeHR1cmVDaGFubmVsVmFsdWUudmFsdWUgPSBjYWNoZWRDaGFubmVsLm1heFZhbHVlICogcHJlc2V0Q2FwYWJpbGl0eVZhbHVlLnZhbHVlUGVyY2VudGFnZTtcbiAgICAgICAgICAgICAgICB0aGlzLm1peENoYW5uZWxWYWx1ZSh2YWx1ZXMsIGZpeHR1cmVDaGFubmVsVmFsdWUsIDEpO1xuICAgICAgICAgICAgICB9IGVsc2UgaWYgKFxuICAgICAgICAgICAgICAgIHByZXNldENhcGFiaWxpdHlWYWx1ZS50eXBlID09PSBGaXh0dXJlQ2FwYWJpbGl0eVR5cGUuV2hlZWxTbG90ICYmXG4gICAgICAgICAgICAgICAgY2hhbm5lbENhcGFiaWxpdHkuY2FwYWJpbGl0eS5zbG90TnVtYmVyID09PSBwcmVzZXRDYXBhYmlsaXR5VmFsdWUuc2xvdE51bWJlclxuICAgICAgICAgICAgICApIHtcbiAgICAgICAgICAgICAgICAvLyB3aGVlbCBzbG90IChjb2xvciwgZ29ibywgZXRjLilcbiAgICAgICAgICAgICAgICBjb25zdCBmaXh0dXJlQ2hhbm5lbFZhbHVlID0gbmV3IEZpeHR1cmVDaGFubmVsVmFsdWUoKTtcbiAgICAgICAgICAgICAgICBmaXh0dXJlQ2hhbm5lbFZhbHVlLmNoYW5uZWxOYW1lID0gY2FjaGVkQ2hhbm5lbC5uYW1lO1xuICAgICAgICAgICAgICAgIGZpeHR1cmVDaGFubmVsVmFsdWUucHJvZmlsZVV1aWQgPSBjYWNoZWRGaXh0dXJlLnByb2ZpbGUudXVpZDtcbiAgICAgICAgICAgICAgICBmaXh0dXJlQ2hhbm5lbFZhbHVlLnZhbHVlID0gY2hhbm5lbENhcGFiaWxpdHkuY2VudGVyVmFsdWU7XG4gICAgICAgICAgICAgICAgdGhpcy5taXhDaGFubmVsVmFsdWUodmFsdWVzLCBmaXh0dXJlQ2hhbm5lbFZhbHVlLCAxKTtcblxuICAgICAgICAgICAgICAgIC8vIGNoZWNrLCB3aGV0aGVyIHdlIGp1c3Qgc2V0IGEgY29sb3Igd2hlZWwgdmFsdWVcbiAgICAgICAgICAgICAgICBpZiAoY2hhbm5lbENhcGFiaWxpdHkud2hlZWxJc0NvbG9yKSB7XG4gICAgICAgICAgICAgICAgICBoYXNDb2xvciA9IHRydWU7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgLy8gYXBwcm94aW1hdGUgdGhlIGNvbG9yIGZyb20gYSBjb2xvciBvciBhIGRpZmZlcmVudCBjb2xvciB3aGVlbCwgaWYgbmVjZXNzYXJ5XG4gICAgICAgIGlmICghaGFzQ29sb3IgJiYgY2FjaGVkQ2hhbm5lbC5jb2xvcldoZWVsKSB7XG4gICAgICAgICAgY29uc3QgY2FwYWJpbGl0eSA9IHRoaXMucHJlc2V0U2VydmljZS5nZXRBcHByb3hpbWF0ZWRDb2xvcldoZWVsQ2FwYWJpbGl0eShwcmVzZXQucHJlc2V0LCBjYWNoZWRDaGFubmVsKTtcblxuICAgICAgICAgIGlmIChjYXBhYmlsaXR5KSB7XG4gICAgICAgICAgICAvLyB3ZSBmb3VuZCBhbiBhcHByb3hpbWF0ZWQgY29sb3IgaW4gdGhlIGF2YWlsYWJsZSB3aGVlbCBjaGFubmVsXG4gICAgICAgICAgICBjb25zdCBmaXh0dXJlQ2hhbm5lbFZhbHVlID0gbmV3IEZpeHR1cmVDaGFubmVsVmFsdWUoKTtcbiAgICAgICAgICAgIGZpeHR1cmVDaGFubmVsVmFsdWUuY2hhbm5lbE5hbWUgPSBjYWNoZWRDaGFubmVsLm5hbWU7XG4gICAgICAgICAgICBmaXh0dXJlQ2hhbm5lbFZhbHVlLnByb2ZpbGVVdWlkID0gY2FjaGVkRml4dHVyZS5wcm9maWxlLnV1aWQ7XG4gICAgICAgICAgICBmaXh0dXJlQ2hhbm5lbFZhbHVlLnZhbHVlID0gY2FwYWJpbGl0eS5jZW50ZXJWYWx1ZTtcbiAgICAgICAgICAgIHRoaXMubWl4Q2hhbm5lbFZhbHVlKHZhbHVlcywgZml4dHVyZUNoYW5uZWxWYWx1ZSwgMSk7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSBtaXhDaGFubmVsVmFsdWVzKFxuICAgIHByZXNldDogUHJlc2V0UmVnaW9uU2NlbmUsXG4gICAgY2FjaGVkRml4dHVyZTogQ2FjaGVkRml4dHVyZSxcbiAgICB2YWx1ZXM6IEZpeHR1cmVDaGFubmVsVmFsdWVbXSxcbiAgICBpbnRlbnNpdHlQZXJjZW50YWdlOiBudW1iZXJcbiAgKSB7XG4gICAgLy8gbWl4IHRoZSBwcmVzZXQgY2hhbm5lbCB2YWx1ZXNcbiAgICBmb3IgKGNvbnN0IGNhY2hlZENoYW5uZWwgb2YgY2FjaGVkRml4dHVyZS5jaGFubmVscykge1xuICAgICAgaWYgKGNhY2hlZENoYW5uZWwuY2hhbm5lbCkge1xuICAgICAgICBmb3IgKGNvbnN0IGNoYW5uZWxWYWx1ZSBvZiBwcmVzZXQucHJlc2V0LmZpeHR1cmVDaGFubmVsVmFsdWVzKSB7XG4gICAgICAgICAgaWYgKGNhY2hlZEZpeHR1cmUucHJvZmlsZS51dWlkID09PSBjaGFubmVsVmFsdWUucHJvZmlsZVV1aWQgJiYgY2FjaGVkQ2hhbm5lbC5uYW1lID09PSBjaGFubmVsVmFsdWUuY2hhbm5lbE5hbWUpIHtcbiAgICAgICAgICAgIHRoaXMubWl4Q2hhbm5lbFZhbHVlKHZhbHVlcywgY2hhbm5lbFZhbHVlLCBpbnRlbnNpdHlQZXJjZW50YWdlKTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICBwcml2YXRlIG1peEVmZmVjdHMoXG4gICAgdGltZU1pbGxpczogbnVtYmVyLFxuICAgIGZpeHR1cmVJbmRleDogbnVtYmVyLFxuICAgIHByZXNldDogUHJlc2V0UmVnaW9uU2NlbmUsXG4gICAgY2FjaGVkRml4dHVyZTogQ2FjaGVkRml4dHVyZSxcbiAgICB2YWx1ZXM6IEZpeHR1cmVDaGFubmVsVmFsdWVbXSxcbiAgICBpbnRlbnNpdHlQZXJjZW50YWdlOiBudW1iZXJcbiAgKSB7XG4gICAgZm9yIChjb25zdCBlZmZlY3Qgb2YgcHJlc2V0LnByZXNldC5lZmZlY3RzKSB7XG4gICAgICBpZiAoZWZmZWN0LnZpc2libGUpIHtcbiAgICAgICAgLy8gRWZmZWN0Q3VydmVcbiAgICAgICAgaWYgKGVmZmVjdCBpbnN0YW5jZW9mIEVmZmVjdEN1cnZlKSB7XG4gICAgICAgICAgY29uc3QgZWZmZWN0Q3VydmUgPSBlZmZlY3QgYXMgRWZmZWN0Q3VydmU7XG5cbiAgICAgICAgICAvLyBjYXBhYmlsaXRpZXNcbiAgICAgICAgICBmb3IgKGNvbnN0IGNhcGFiaWxpdHkgb2YgZWZmZWN0Q3VydmUuY2FwYWJpbGl0aWVzKSB7XG4gICAgICAgICAgICBmb3IgKGNvbnN0IGNhY2hlZENoYW5uZWwgb2YgY2FjaGVkRml4dHVyZS5jaGFubmVscykge1xuICAgICAgICAgICAgICBmb3IgKGNvbnN0IGNoYW5uZWxDYXBhYmlsaXR5IG9mIGNhY2hlZENoYW5uZWwuY2FwYWJpbGl0aWVzKSB7XG4gICAgICAgICAgICAgICAgaWYgKFxuICAgICAgICAgICAgICAgICAgdGhpcy5maXh0dXJlU2VydmljZS5jYXBhYmlsaXRpZXNNYXRjaChcbiAgICAgICAgICAgICAgICAgICAgY2FwYWJpbGl0eS50eXBlLFxuICAgICAgICAgICAgICAgICAgICBjaGFubmVsQ2FwYWJpbGl0eS5jYXBhYmlsaXR5LnR5cGUsXG4gICAgICAgICAgICAgICAgICAgIGNhcGFiaWxpdHkuY29sb3IsXG4gICAgICAgICAgICAgICAgICAgIGNoYW5uZWxDYXBhYmlsaXR5LmNhcGFiaWxpdHkuY29sb3IsXG4gICAgICAgICAgICAgICAgICAgIG51bGwsXG4gICAgICAgICAgICAgICAgICAgIG51bGwsXG4gICAgICAgICAgICAgICAgICAgIG51bGwsXG4gICAgICAgICAgICAgICAgICAgIG51bGxcbiAgICAgICAgICAgICAgICAgIClcbiAgICAgICAgICAgICAgICApIHtcbiAgICAgICAgICAgICAgICAgIGNvbnN0IGZpeHR1cmVDaGFubmVsVmFsdWUgPSBuZXcgRml4dHVyZUNoYW5uZWxWYWx1ZSgpO1xuICAgICAgICAgICAgICAgICAgZml4dHVyZUNoYW5uZWxWYWx1ZS5jaGFubmVsTmFtZSA9IGNhY2hlZENoYW5uZWwubmFtZTtcbiAgICAgICAgICAgICAgICAgIGZpeHR1cmVDaGFubmVsVmFsdWUucHJvZmlsZVV1aWQgPSBjYWNoZWRGaXh0dXJlLnByb2ZpbGUudXVpZDtcbiAgICAgICAgICAgICAgICAgIGZpeHR1cmVDaGFubmVsVmFsdWUudmFsdWUgPSBjYWNoZWRDaGFubmVsLm1heFZhbHVlICogZWZmZWN0Q3VydmUuZ2V0VmFsdWVBdE1pbGxpcyh0aW1lTWlsbGlzLCBmaXh0dXJlSW5kZXgpO1xuICAgICAgICAgICAgICAgICAgdGhpcy5taXhDaGFubmVsVmFsdWUodmFsdWVzLCBmaXh0dXJlQ2hhbm5lbFZhbHVlLCBpbnRlbnNpdHlQZXJjZW50YWdlKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG5cbiAgICAgICAgICAvLyBjaGFubmVsc1xuICAgICAgICAgIGZvciAoY29uc3QgY2hhbm5lbFByb2ZpbGUgb2YgZWZmZWN0Q3VydmUuY2hhbm5lbHMpIHtcbiAgICAgICAgICAgIGlmIChjaGFubmVsUHJvZmlsZS5wcm9maWxlVXVpZCA9PT0gY2FjaGVkRml4dHVyZS5wcm9maWxlLnV1aWQpIHtcbiAgICAgICAgICAgICAgZm9yIChjb25zdCBjaGFubmVsIG9mIGNoYW5uZWxQcm9maWxlLmNoYW5uZWxzKSB7XG4gICAgICAgICAgICAgICAgZm9yIChjb25zdCBjYWNoZWRDaGFubmVsIG9mIGNhY2hlZEZpeHR1cmUuY2hhbm5lbHMpIHtcbiAgICAgICAgICAgICAgICAgIGlmIChjYWNoZWRDaGFubmVsLm5hbWUgPT09IGNoYW5uZWwpIHtcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgZml4dHVyZUNoYW5uZWxWYWx1ZSA9IG5ldyBGaXh0dXJlQ2hhbm5lbFZhbHVlKCk7XG4gICAgICAgICAgICAgICAgICAgIGZpeHR1cmVDaGFubmVsVmFsdWUuY2hhbm5lbE5hbWUgPSBjYWNoZWRDaGFubmVsLm5hbWU7XG4gICAgICAgICAgICAgICAgICAgIGZpeHR1cmVDaGFubmVsVmFsdWUucHJvZmlsZVV1aWQgPSBjYWNoZWRGaXh0dXJlLnByb2ZpbGUudXVpZDtcbiAgICAgICAgICAgICAgICAgICAgZml4dHVyZUNoYW5uZWxWYWx1ZS52YWx1ZSA9IGNhY2hlZENoYW5uZWwubWF4VmFsdWUgKiBlZmZlY3RDdXJ2ZS5nZXRWYWx1ZUF0TWlsbGlzKHRpbWVNaWxsaXMsIGZpeHR1cmVJbmRleCk7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMubWl4Q2hhbm5lbFZhbHVlKHZhbHVlcywgZml4dHVyZUNoYW5uZWxWYWx1ZSwgaW50ZW5zaXR5UGVyY2VudGFnZSk7XG4gICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgLy8gVE9ETyBvdGhlciBlZmZlY3RzIChQYW5UaWx0LCBldGMuKVxuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIC8vIHJldHVybiBhbGwgZml4dHVyZSB1dWlkcyB3aXRoIHRoZWlyIGNvcnJlc3BvbmRpbmcgY2hhbm5lbCB2YWx1ZXNcbiAgcHVibGljIGdldENoYW5uZWxWYWx1ZXModGltZU1pbGxpczogbnVtYmVyLCBwcmVzZXRzOiBQcmVzZXRSZWdpb25TY2VuZVtdKTogTWFwPENhY2hlZEZpeHR1cmUsIEZpeHR1cmVDaGFubmVsVmFsdWVbXT4ge1xuICAgIC8vIExvb3Agb3ZlciBhbGwgcmVsZXZhbnQgcHJlc2V0cyBhbmQgY2FsYyB0aGUgcHJvcGVydHkgdmFsdWVzIGZyb20gdGhlIHByZXNldHMgKGNhcGFiaWxpdGllcyBhbmQgZWZmZWN0cylcbiAgICBjb25zdCBjYWxjdWxhdGVkRml4dHVyZXMgPSBuZXcgTWFwPENhY2hlZEZpeHR1cmUsIEZpeHR1cmVDaGFubmVsVmFsdWVbXT4oKTtcblxuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgdGhpcy5maXh0dXJlU2VydmljZS5jYWNoZWRGaXh0dXJlcy5sZW5ndGg7IGkrKykge1xuICAgICAgY29uc3QgY2FjaGVkRml4dHVyZSA9IHRoaXMuZml4dHVyZVNlcnZpY2UuY2FjaGVkRml4dHVyZXNbaV07XG5cbiAgICAgIC8vIGFsbCB2YWx1ZXMgb2YgdGhlIGN1cnJlbnQgZml4dHVyZSBjaGFubmVsc1xuICAgICAgbGV0IHZhbHVlczogRml4dHVyZUNoYW5uZWxWYWx1ZVtdID0gW107XG5cbiAgICAgIGNvbnN0IGFscmVhZHlDYWxjdWxhdGVkRml4dHVyZSA9IHRoaXMuZ2V0QWxyZWFkeUNhbGN1bGF0ZWRGaXh0dXJlKHRoaXMuZml4dHVyZVNlcnZpY2UuY2FjaGVkRml4dHVyZXMsIGkpO1xuXG4gICAgICBpZiAoYWxyZWFkeUNhbGN1bGF0ZWRGaXh0dXJlKSB7XG4gICAgICAgIC8vIG9ubHkgcmVsZXZhbnQgZm9yIHRoZSBwcmV2aWV3IC0tPiByZXVzZSBhbGwgY2FsY3VsYXRlZCB2YWx1ZXNcbiAgICAgICAgdmFsdWVzID0gT2JqZWN0LmFzc2lnbihbXSwgY2FsY3VsYXRlZEZpeHR1cmVzLmdldChhbHJlYWR5Q2FsY3VsYXRlZEZpeHR1cmUpKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIC8vIGFwcGx5IHRoZSBkZWZhdWx0IHZhbHVlc1xuICAgICAgICBmb3IgKGNvbnN0IGNhY2hlZENoYW5uZWwgb2YgY2FjaGVkRml4dHVyZS5jaGFubmVscykge1xuICAgICAgICAgIGlmIChjYWNoZWRDaGFubmVsLmNoYW5uZWwpIHtcbiAgICAgICAgICAgIGlmIChjYWNoZWRDaGFubmVsLmNoYW5uZWwuZGVmYXVsdFZhbHVlKSB7XG4gICAgICAgICAgICAgIGNvbnN0IGZpeHR1cmVDaGFubmVsVmFsdWUgPSBuZXcgRml4dHVyZUNoYW5uZWxWYWx1ZSgpO1xuICAgICAgICAgICAgICBmaXh0dXJlQ2hhbm5lbFZhbHVlLmNoYW5uZWxOYW1lID0gY2FjaGVkQ2hhbm5lbC5uYW1lO1xuICAgICAgICAgICAgICBmaXh0dXJlQ2hhbm5lbFZhbHVlLnByb2ZpbGVVdWlkID0gY2FjaGVkRml4dHVyZS5wcm9maWxlLnV1aWQ7XG4gICAgICAgICAgICAgIGZpeHR1cmVDaGFubmVsVmFsdWUudmFsdWUgPSBjYWNoZWRDaGFubmVsLmRlZmF1bHRWYWx1ZTtcbiAgICAgICAgICAgICAgdGhpcy5taXhDaGFubmVsVmFsdWUodmFsdWVzLCBmaXh0dXJlQ2hhbm5lbFZhbHVlLCAxKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICBmb3IgKGNvbnN0IHByZXNldCBvZiBwcmVzZXRzKSB7XG4gICAgICAgICAgLy8gc2VhcmNoIGZvciB0aGlzIGZpeHR1cmUgaW4gdGhlIHByZXNldCBhbmQgZ2V0IGl0J3MgcHJlc2V0LXNwZWNpZmljIGluZGV4IChmb3IgY2hhc2luZyBlZmZlY3RzKVxuICAgICAgICAgIGNvbnN0IGZpeHR1cmVJbmRleCA9IHRoaXMuZ2V0Rml4dHVyZUluZGV4KHByZXNldC5wcmVzZXQsIGNhY2hlZEZpeHR1cmUuZml4dHVyZS51dWlkKTtcblxuICAgICAgICAgIGlmIChmaXh0dXJlSW5kZXggPj0gMCkge1xuICAgICAgICAgICAgLy8gdGhpcyBmaXh0dXJlIGlzIGFsc28gaW4gdGhlIHByZXNldCAtPiBtaXggdGhlIHJlcXVpcmVkIHZhbHVlcyAob3ZlcndyaXRlIGV4aXN0aW5nIHZhbHVlcyxcbiAgICAgICAgICAgIC8vIGlmIHNldCBtdWx0aXBsZSB0aW1lcylcbiAgICAgICAgICAgIGNvbnN0IGludGVuc2l0eVBlcmNlbnRhZ2UgPSB0aGlzLmdldFByZXNldEludGVuc2l0eShwcmVzZXQsIHRpbWVNaWxsaXMpO1xuXG4gICAgICAgICAgICB0aGlzLm1peENhcGFiaWxpdHlWYWx1ZXMocHJlc2V0LCBjYWNoZWRGaXh0dXJlLCB2YWx1ZXMsIGludGVuc2l0eVBlcmNlbnRhZ2UpO1xuICAgICAgICAgICAgdGhpcy5taXhDaGFubmVsVmFsdWVzKHByZXNldCwgY2FjaGVkRml4dHVyZSwgdmFsdWVzLCBpbnRlbnNpdHlQZXJjZW50YWdlKTtcbiAgICAgICAgICAgIHRoaXMubWl4RWZmZWN0cyh0aW1lTWlsbGlzLCBmaXh0dXJlSW5kZXgsIHByZXNldCwgY2FjaGVkRml4dHVyZSwgdmFsdWVzLCBpbnRlbnNpdHlQZXJjZW50YWdlKTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgLy8gU3RvcmUgdGhlIGNhbGN1bGF0ZWQgdmFsdWVzIGZvciBzdWJzZXF1ZW50IGZpeHR1cmVzIG9uIHRoZSBzYW1lIERNWCBhZGRyZXNzXG4gICAgICBjYWxjdWxhdGVkRml4dHVyZXMuc2V0KGNhY2hlZEZpeHR1cmUsIHZhbHVlcyk7XG4gICAgfVxuXG4gICAgcmV0dXJuIGNhbGN1bGF0ZWRGaXh0dXJlcztcbiAgfVxuXG4gIHB1YmxpYyBzZXRVbml2ZXJzZVZhbHVlcyhmaXh0dXJlczogTWFwPENhY2hlZEZpeHR1cmUsIEZpeHR1cmVDaGFubmVsVmFsdWVbXT4sIG1hc3RlckRpbW1lclZhbHVlOiBudW1iZXIpIHtcbiAgICAvLyBUT0RPIG9ubHksIGlmIG1vbml0b3JpbmcgaXMgZW5hYmxlZFxuICAgIHJldHVybjtcblxuICAgIC8vIFJlc2V0IGFsbCBETVggdW5pdmVyc2VzXG4gICAgZm9yIChjb25zdCB1bml2ZXJzZSBvZiB0aGlzLnVuaXZlcnNlU2VydmljZS51bml2ZXJzZXMpIHtcbiAgICAgIHVuaXZlcnNlLmNoYW5uZWxWYWx1ZXMgPSBbXTtcbiAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgNTEyOyBpKyspIHtcbiAgICAgICAgdW5pdmVyc2UuY2hhbm5lbFZhbHVlcy5wdXNoKDApO1xuICAgICAgfVxuICAgIH1cblxuICAgIC8vIGxvb3Agb3ZlciBlYWNoIGZpeHR1cmVcbiAgICBmaXh0dXJlcy5mb3JFYWNoKChjaGFubmVsVmFsdWVzOiBGaXh0dXJlQ2hhbm5lbFZhbHVlW10sIGNhY2hlZEZpeHR1cmU6IENhY2hlZEZpeHR1cmUpID0+IHtcbiAgICAgIC8vIFRPRE8gR2V0IHRoZSBjb3JyZWN0IHVuaXZlcnNlIGZvciB0aGlzIGZpeHR1cmVcbiAgICAgIGNvbnN0IHVuaXZlcnNlOiBVbml2ZXJzZSA9IHRoaXMudW5pdmVyc2VTZXJ2aWNlLmdldFVuaXZlcnNlQnlVdWlkKGNhY2hlZEZpeHR1cmUuZml4dHVyZS5kbXhVbml2ZXJzZVV1aWQpO1xuXG4gICAgICAvLyBsb29wIG92ZXIgZWFjaCBjaGFubmVsIGZvciB0aGlzIGZpeHR1cmVcbiAgICAgIGZvciAobGV0IGNoYW5uZWxJbmRleCA9IDA7IGNoYW5uZWxJbmRleCA8IGNhY2hlZEZpeHR1cmUubW9kZS5jaGFubmVscy5sZW5ndGg7IGNoYW5uZWxJbmRleCsrKSB7XG4gICAgICAgIGNvbnN0IGNoYW5uZWxPYmogPSBjYWNoZWRGaXh0dXJlLm1vZGUuY2hhbm5lbHNbY2hhbm5lbEluZGV4XTtcbiAgICAgICAgaWYgKHR5cGVvZiBjaGFubmVsT2JqID09PSAnc3RyaW5nJykge1xuICAgICAgICAgIGNvbnN0IGNoYW5uZWxOYW1lID0gY2hhbm5lbE9iajtcbiAgICAgICAgICAvLyBtYXRjaCB0aGlzIG1vZGUgY2hhbm5lbCB3aXRoIGEgY2hhbm5lbCB2YWx1ZVxuICAgICAgICAgIGZvciAoY29uc3QgY2hhbm5lbFZhbHVlIG9mIGNoYW5uZWxWYWx1ZXMpIHtcbiAgICAgICAgICAgIGNvbnN0IGNoYW5uZWwgPSB0aGlzLmZpeHR1cmVTZXJ2aWNlLmdldENoYW5uZWxCeU5hbWUoY2FjaGVkRml4dHVyZSwgY2hhbm5lbE5hbWUpO1xuICAgICAgICAgICAgaWYgKGNoYW5uZWwgJiYgY2hhbm5lbC5jaGFubmVsKSB7XG4gICAgICAgICAgICAgIGNvbnN0IGZpbmVJbmRleCA9IGNoYW5uZWwuY2hhbm5lbC5maW5lQ2hhbm5lbEFsaWFzZXMuaW5kZXhPZihjaGFubmVsTmFtZSk7XG4gICAgICAgICAgICAgIGlmIChjaGFubmVsLm5hbWUgPT09IGNoYW5uZWxWYWx1ZS5jaGFubmVsTmFtZSB8fCBmaW5lSW5kZXggPiAtMSkge1xuICAgICAgICAgICAgICAgIGNvbnN0IHVuaXZlcnNlQ2hhbm5lbCA9IGNhY2hlZEZpeHR1cmUuZml4dHVyZS5kbXhGaXJzdENoYW5uZWwgKyBjaGFubmVsSW5kZXg7XG4gICAgICAgICAgICAgICAgY29uc3QgZG14VmFsdWUgPVxuICAgICAgICAgICAgICAgICAgTWF0aC5mbG9vcihjaGFubmVsVmFsdWUudmFsdWUgLyBNYXRoLnBvdygyNTYsIGNoYW5uZWwuY2hhbm5lbC5maW5lQ2hhbm5lbEFsaWFzZXMubGVuZ3RoIC0gKGZpbmVJbmRleCArIDEpKSkgJSAyNTY7XG4gICAgICAgICAgICAgICAgLy8gVE9ET1xuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9XG4gICAgfSk7XG4gIH1cblxuICBwdWJsaWMgZml4dHVyZUlzU2VsZWN0ZWQodXVpZDogc3RyaW5nLCBwcmVzZXRzOiBQcmVzZXRSZWdpb25TY2VuZVtdKTogYm9vbGVhbiB7XG4gICAgZm9yIChjb25zdCBwcmVzZXQgb2YgcHJlc2V0cykge1xuICAgICAgZm9yIChjb25zdCBmaXh0dXJlVXVpZCBvZiBwcmVzZXQucHJlc2V0LmZpeHR1cmVVdWlkcykge1xuICAgICAgICBpZiAoZml4dHVyZVV1aWQgPT09IHV1aWQpIHtcbiAgICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cblxuICAgIHJldHVybiBmYWxzZTtcbiAgfVxuXG4gIHB1YmxpYyB1cGRhdGVGaXh0dXJlU2V0dXAoKSB7XG4gICAgdGhpcy5kb1VwZGF0ZUZpeHR1cmVTZXR1cC5uZXh0KCk7XG4gIH1cblxuICBwcml2YXRlIHByZXBhcmVTdGFnZU1lc2gobWVzaDogVEhSRUUuTWVzaCkge1xuICAgIG1lc2gucmVjZWl2ZVNoYWRvdyA9IGZhbHNlO1xuICAgIG1lc2guY2FzdFNoYWRvdyA9IGZhbHNlO1xuICB9XG5cbiAgcHVibGljIHVwZGF0ZVN0YWdlKCkge1xuICAgIGlmICghdGhpcy5zY2VuZSkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGxldCBnZW9tZXRyeTogYW55O1xuICAgIGxldCBtZXNoOiBhbnk7XG5cbiAgICAvLyBSZW1vdmUgb2xkIG1lc2hlcyBmcm9tIHRoZSBzY2VuZVxuICAgIGZvciAoY29uc3QgZXhpc3RpbmdNZXNoIG9mIHRoaXMuc3RhZ2VNZXNoZXMpIHtcbiAgICAgIHRoaXMuc2NlbmUucmVtb3ZlKGV4aXN0aW5nTWVzaCk7XG4gICAgICBleGlzdGluZ01lc2guZ2VvbWV0cnkuZGlzcG9zZSgpO1xuICAgIH1cbiAgICB0aGlzLnN0YWdlTWVzaGVzID0gW107XG5cbiAgICAvLyBHcm91bmRcbiAgICBnZW9tZXRyeSA9IG5ldyBUSFJFRS5QbGFuZUdlb21ldHJ5KDUwMDAsIDUwMDApO1xuICAgIG1lc2ggPSBuZXcgVEhSRUUuTWVzaChnZW9tZXRyeSwgdGhpcy5zdGFnZU1hdGVyaWFsKTtcbiAgICB0aGlzLnByZXBhcmVTdGFnZU1lc2gobWVzaCk7XG4gICAgbWVzaC5wb3NpdGlvbi5zZXQoMCwgMCwgMCk7XG4gICAgbWVzaC5yb3RhdGVYKChNYXRoLlBJIC8gMTgwKSAqIC05MCk7XG4gICAgdGhpcy5zY2VuZS5hZGQobWVzaCk7XG4gICAgdGhpcy5zdGFnZU1lc2hlcy5wdXNoKG1lc2gpO1xuXG4gICAgLy8gRmxvb3JcbiAgICBnZW9tZXRyeSA9IG5ldyBUSFJFRS5Cb3hHZW9tZXRyeShcbiAgICAgIHRoaXMucHJvamVjdFNlcnZpY2UucHJvamVjdC5zdGFnZVdpZHRoQ20sXG4gICAgICB0aGlzLnByb2plY3RTZXJ2aWNlLnByb2plY3Quc3RhZ2VGbG9vckhlaWdodENtLFxuICAgICAgdGhpcy5wcm9qZWN0U2VydmljZS5wcm9qZWN0LnN0YWdlRGVwdGhDbVxuICAgICk7XG4gICAgbWVzaCA9IG5ldyBUSFJFRS5NZXNoKGdlb21ldHJ5LCB0aGlzLnN0YWdlTWF0ZXJpYWwpO1xuICAgIHRoaXMucHJlcGFyZVN0YWdlTWVzaChtZXNoKTtcbiAgICBtZXNoLnBvc2l0aW9uLnNldCgwLCB0aGlzLnByb2plY3RTZXJ2aWNlLnByb2plY3Quc3RhZ2VGbG9vckhlaWdodENtIC8gMiwgMCk7XG4gICAgdGhpcy5zY2VuZS5hZGQobWVzaCk7XG4gICAgdGhpcy5zdGFnZU1lc2hlcy5wdXNoKG1lc2gpO1xuXG4gICAgLy8gUGlsbGFyIGZyb250IGxlZnRcbiAgICBnZW9tZXRyeSA9IG5ldyBUSFJFRS5Cb3hHZW9tZXRyeShcbiAgICAgIHRoaXMucHJvamVjdFNlcnZpY2UucHJvamVjdC5zdGFnZVBpbGxhcldpZHRoQ20sXG4gICAgICB0aGlzLnByb2plY3RTZXJ2aWNlLnByb2plY3Quc3RhZ2VIZWlnaHRDbSxcbiAgICAgIHRoaXMucHJvamVjdFNlcnZpY2UucHJvamVjdC5zdGFnZVBpbGxhcldpZHRoQ21cbiAgICApO1xuICAgIG1lc2ggPSBuZXcgVEhSRUUuTWVzaChnZW9tZXRyeSwgdGhpcy5zdGFnZU1hdGVyaWFsKTtcbiAgICB0aGlzLnByZXBhcmVTdGFnZU1lc2gobWVzaCk7XG4gICAgbWVzaC5wb3NpdGlvbi5zZXQoXG4gICAgICAtdGhpcy5wcm9qZWN0U2VydmljZS5wcm9qZWN0LnN0YWdlV2lkdGhDbSAvIDIgKyB0aGlzLnByb2plY3RTZXJ2aWNlLnByb2plY3Quc3RhZ2VQaWxsYXJXaWR0aENtIC8gMixcbiAgICAgIHRoaXMucHJvamVjdFNlcnZpY2UucHJvamVjdC5zdGFnZUhlaWdodENtIC8gMiArIHRoaXMucHJvamVjdFNlcnZpY2UucHJvamVjdC5zdGFnZUZsb29ySGVpZ2h0Q20sXG4gICAgICB0aGlzLnByb2plY3RTZXJ2aWNlLnByb2plY3Quc3RhZ2VEZXB0aENtIC8gMiAtIHRoaXMucHJvamVjdFNlcnZpY2UucHJvamVjdC5zdGFnZVBpbGxhcldpZHRoQ20gLyAyXG4gICAgKTtcbiAgICB0aGlzLnNjZW5lLmFkZChtZXNoKTtcbiAgICB0aGlzLnN0YWdlTWVzaGVzLnB1c2gobWVzaCk7XG5cbiAgICAvLyBQaWxsYXIgZnJvbnQgcmlnaHRcbiAgICBnZW9tZXRyeSA9IG5ldyBUSFJFRS5Cb3hHZW9tZXRyeShcbiAgICAgIHRoaXMucHJvamVjdFNlcnZpY2UucHJvamVjdC5zdGFnZVBpbGxhcldpZHRoQ20sXG4gICAgICB0aGlzLnByb2plY3RTZXJ2aWNlLnByb2plY3Quc3RhZ2VIZWlnaHRDbSxcbiAgICAgIHRoaXMucHJvamVjdFNlcnZpY2UucHJvamVjdC5zdGFnZVBpbGxhcldpZHRoQ21cbiAgICApO1xuICAgIG1lc2ggPSBuZXcgVEhSRUUuTWVzaChnZW9tZXRyeSwgdGhpcy5zdGFnZU1hdGVyaWFsKTtcbiAgICB0aGlzLnByZXBhcmVTdGFnZU1lc2gobWVzaCk7XG4gICAgbWVzaC5wb3NpdGlvbi5zZXQoXG4gICAgICB0aGlzLnByb2plY3RTZXJ2aWNlLnByb2plY3Quc3RhZ2VXaWR0aENtIC8gMiAtIHRoaXMucHJvamVjdFNlcnZpY2UucHJvamVjdC5zdGFnZVBpbGxhcldpZHRoQ20gLyAyLFxuICAgICAgdGhpcy5wcm9qZWN0U2VydmljZS5wcm9qZWN0LnN0YWdlSGVpZ2h0Q20gLyAyICsgdGhpcy5wcm9qZWN0U2VydmljZS5wcm9qZWN0LnN0YWdlRmxvb3JIZWlnaHRDbSxcbiAgICAgIHRoaXMucHJvamVjdFNlcnZpY2UucHJvamVjdC5zdGFnZURlcHRoQ20gLyAyIC0gdGhpcy5wcm9qZWN0U2VydmljZS5wcm9qZWN0LnN0YWdlUGlsbGFyV2lkdGhDbSAvIDJcbiAgICApO1xuICAgIHRoaXMuc2NlbmUuYWRkKG1lc2gpO1xuICAgIHRoaXMuc3RhZ2VNZXNoZXMucHVzaChtZXNoKTtcblxuICAgIC8vIFBpbGxhciBiYWNrIGxlZnRcbiAgICBnZW9tZXRyeSA9IG5ldyBUSFJFRS5Cb3hHZW9tZXRyeShcbiAgICAgIHRoaXMucHJvamVjdFNlcnZpY2UucHJvamVjdC5zdGFnZVBpbGxhcldpZHRoQ20sXG4gICAgICB0aGlzLnByb2plY3RTZXJ2aWNlLnByb2plY3Quc3RhZ2VIZWlnaHRDbSxcbiAgICAgIHRoaXMucHJvamVjdFNlcnZpY2UucHJvamVjdC5zdGFnZVBpbGxhcldpZHRoQ21cbiAgICApO1xuICAgIG1lc2ggPSBuZXcgVEhSRUUuTWVzaChnZW9tZXRyeSwgdGhpcy5zdGFnZU1hdGVyaWFsKTtcbiAgICB0aGlzLnByZXBhcmVTdGFnZU1lc2gobWVzaCk7XG4gICAgbWVzaC5wb3NpdGlvbi5zZXQoXG4gICAgICAtdGhpcy5wcm9qZWN0U2VydmljZS5wcm9qZWN0LnN0YWdlV2lkdGhDbSAvIDIgKyB0aGlzLnByb2plY3RTZXJ2aWNlLnByb2plY3Quc3RhZ2VQaWxsYXJXaWR0aENtIC8gMixcbiAgICAgIHRoaXMucHJvamVjdFNlcnZpY2UucHJvamVjdC5zdGFnZUhlaWdodENtIC8gMiArIHRoaXMucHJvamVjdFNlcnZpY2UucHJvamVjdC5zdGFnZUZsb29ySGVpZ2h0Q20sXG4gICAgICAtdGhpcy5wcm9qZWN0U2VydmljZS5wcm9qZWN0LnN0YWdlRGVwdGhDbSAvIDIgKyB0aGlzLnByb2plY3RTZXJ2aWNlLnByb2plY3Quc3RhZ2VQaWxsYXJXaWR0aENtIC8gMlxuICAgICk7XG4gICAgdGhpcy5zY2VuZS5hZGQobWVzaCk7XG4gICAgdGhpcy5zdGFnZU1lc2hlcy5wdXNoKG1lc2gpO1xuXG4gICAgLy8gUGlsbGFyIGJhY2sgcmlnaHRcbiAgICBnZW9tZXRyeSA9IG5ldyBUSFJFRS5Cb3hHZW9tZXRyeShcbiAgICAgIHRoaXMucHJvamVjdFNlcnZpY2UucHJvamVjdC5zdGFnZVBpbGxhcldpZHRoQ20sXG4gICAgICB0aGlzLnByb2plY3RTZXJ2aWNlLnByb2plY3Quc3RhZ2VIZWlnaHRDbSxcbiAgICAgIHRoaXMucHJvamVjdFNlcnZpY2UucHJvamVjdC5zdGFnZVBpbGxhcldpZHRoQ21cbiAgICApO1xuICAgIG1lc2ggPSBuZXcgVEhSRUUuTWVzaChnZW9tZXRyeSwgdGhpcy5zdGFnZU1hdGVyaWFsKTtcbiAgICB0aGlzLnByZXBhcmVTdGFnZU1lc2gobWVzaCk7XG4gICAgbWVzaC5wb3NpdGlvbi5zZXQoXG4gICAgICB0aGlzLnByb2plY3RTZXJ2aWNlLnByb2plY3Quc3RhZ2VXaWR0aENtIC8gMiAtIHRoaXMucHJvamVjdFNlcnZpY2UucHJvamVjdC5zdGFnZVBpbGxhcldpZHRoQ20gLyAyLFxuICAgICAgdGhpcy5wcm9qZWN0U2VydmljZS5wcm9qZWN0LnN0YWdlSGVpZ2h0Q20gLyAyICsgdGhpcy5wcm9qZWN0U2VydmljZS5wcm9qZWN0LnN0YWdlRmxvb3JIZWlnaHRDbSxcbiAgICAgIC10aGlzLnByb2plY3RTZXJ2aWNlLnByb2plY3Quc3RhZ2VEZXB0aENtIC8gMiArIHRoaXMucHJvamVjdFNlcnZpY2UucHJvamVjdC5zdGFnZVBpbGxhcldpZHRoQ20gLyAyXG4gICAgKTtcbiAgICB0aGlzLnNjZW5lLmFkZChtZXNoKTtcbiAgICB0aGlzLnN0YWdlTWVzaGVzLnB1c2gobWVzaCk7XG5cbiAgICAvLyBDZWlsaW5nXG4gICAgZ2VvbWV0cnkgPSBuZXcgVEhSRUUuQm94R2VvbWV0cnkoXG4gICAgICB0aGlzLnByb2plY3RTZXJ2aWNlLnByb2plY3Quc3RhZ2VXaWR0aENtLFxuICAgICAgdGhpcy5wcm9qZWN0U2VydmljZS5wcm9qZWN0LnN0YWdlQ2VpbGluZ0hlaWdodENtLFxuICAgICAgdGhpcy5wcm9qZWN0U2VydmljZS5wcm9qZWN0LnN0YWdlRGVwdGhDbVxuICAgICk7XG4gICAgbWVzaCA9IG5ldyBUSFJFRS5NZXNoKGdlb21ldHJ5LCB0aGlzLnN0YWdlTWF0ZXJpYWwpO1xuICAgIHRoaXMucHJlcGFyZVN0YWdlTWVzaChtZXNoKTtcbiAgICBtZXNoLnBvc2l0aW9uLnNldChcbiAgICAgIDAsXG4gICAgICB0aGlzLnByb2plY3RTZXJ2aWNlLnByb2plY3Quc3RhZ2VIZWlnaHRDbSArXG4gICAgICAgIHRoaXMucHJvamVjdFNlcnZpY2UucHJvamVjdC5zdGFnZUNlaWxpbmdIZWlnaHRDbSAvIDIgK1xuICAgICAgICB0aGlzLnByb2plY3RTZXJ2aWNlLnByb2plY3Quc3RhZ2VGbG9vckhlaWdodENtLFxuICAgICAgMFxuICAgICk7XG4gICAgdGhpcy5zY2VuZS5hZGQobWVzaCk7XG4gICAgdGhpcy5zdGFnZU1lc2hlcy5wdXNoKG1lc2gpO1xuICB9XG59XG4iXX0=
|