mediasfu-angular 1.0.2 → 2.0.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/README.md +678 -578
- package/dist/README.md +677 -578
- package/dist/fesm2022/mediasfu-angular.mjs +5551 -2944
- package/dist/fesm2022/mediasfu-angular.mjs.map +1 -1
- package/dist/lib/@types/types.d.ts +22 -1
- package/dist/lib/components/breakout-components/breakout-rooms-modal.component.d.ts +1 -0
- package/dist/lib/components/mediasfu-components/mediasfu-broadcast.component.d.ts +153 -61
- package/dist/lib/components/mediasfu-components/mediasfu-chat.component.d.ts +154 -66
- package/dist/lib/components/mediasfu-components/mediasfu-conference.component.d.ts +190 -76
- package/dist/lib/components/mediasfu-components/mediasfu-generic.component.d.ts +184 -70
- package/dist/lib/components/mediasfu-components/mediasfu-webinar.component.d.ts +192 -78
- package/dist/lib/components/menu-components/menu-modal/menu-modal.component.d.ts +6 -1
- package/dist/lib/components/menu-components/share-buttons-component/share-buttons-component.component.d.ts +5 -2
- package/dist/lib/components/misc-components/confirm-here-modal/confirm-here-modal.component.d.ts +4 -2
- package/dist/lib/components/misc-components/pre-join-page/pre-join-page.component.d.ts +71 -66
- package/dist/lib/components/misc-components/share-event-modal/share-event-modal.component.d.ts +5 -1
- package/dist/lib/consumers/connect-local-ips.service.d.ts +81 -0
- package/dist/lib/consumers/connect-send-transport-audio.service.d.ts +43 -11
- package/dist/lib/consumers/connect-send-transport-screen.service.d.ts +87 -46
- package/dist/lib/consumers/connect-send-transport-video.service.d.ts +89 -43
- package/dist/lib/consumers/connect-send-transport.service.d.ts +5 -1
- package/dist/lib/consumers/create-send-transport.service.d.ts +130 -40
- package/dist/lib/consumers/disconnect-send-transport-audio.service.d.ts +77 -40
- package/dist/lib/consumers/disconnect-send-transport-screen.service.d.ts +48 -14
- package/dist/lib/consumers/disconnect-send-transport-video.service.d.ts +81 -44
- package/dist/lib/consumers/get-piped-producers-alt.service.d.ts +5 -1
- package/dist/lib/consumers/receive-all-piped-transports.service.d.ts +5 -1
- package/dist/lib/consumers/resume-send-transport-audio.service.d.ts +54 -21
- package/dist/lib/consumers/stream-success-audio-switch.service.d.ts +124 -40
- package/dist/lib/consumers/trigger.service.d.ts +3 -0
- package/dist/lib/methods/exit-methods/confirm-exit.service.d.ts +5 -1
- package/dist/lib/methods/recording-methods/start-recording.service.d.ts +3 -0
- package/dist/lib/methods/recording-methods/stop-recording.service.d.ts +4 -1
- package/dist/lib/methods/recording-methods/update-recording.service.d.ts +3 -0
- package/dist/lib/methods/stream-methods/click-audio.service.d.ts +3 -0
- package/dist/lib/methods/utils/check-limits-and-make-request.service.d.ts +23 -0
- package/dist/lib/methods/utils/create-response-join-room.util.d.ts +33 -0
- package/dist/lib/methods/utils/create-room-on-media-sfu.service.d.ts +25 -0
- package/dist/lib/methods/utils/initial-values.util.d.ts +6 -0
- package/dist/lib/methods/utils/join-room-on-media-sfu.service.d.ts +52 -0
- package/dist/lib/methods/whiteboard-methods/capture-canvas-stream.service.d.ts +37 -20
- package/dist/lib/producers/producer-emits/join-local-room.service.d.ts +125 -0
- package/dist/lib/producers/socket-receive-methods/all-members-rest.service.d.ts +7 -2
- package/dist/lib/producers/socket-receive-methods/all-members.service.d.ts +7 -2
- package/dist/lib/producers/socket-receive-methods/disconnect-user-self.service.d.ts +5 -1
- package/dist/lib/sockets/socket-manager.service.d.ts +90 -0
- package/dist/public-api.d.ts +11 -1
- package/package.json +17 -20
- package/dist/esm2022/lib/@types/types.mjs +0 -2
- package/dist/esm2022/lib/components/background-components/background-modal/background-modal.component.mjs +0 -799
- package/dist/esm2022/lib/components/breakout-components/breakout-rooms-modal.component.mjs +0 -366
- package/dist/esm2022/lib/components/breakout-components/edit-room-modal/edit-room-modal.component.mjs +0 -143
- package/dist/esm2022/lib/components/breakout-components/room-list/room-list.component.mjs +0 -40
- package/dist/esm2022/lib/components/co-host-components/co-host-modal/co-host-modal.component.mjs +0 -245
- package/dist/esm2022/lib/components/display-components/alert-component/alert.component.component.mjs +0 -79
- package/dist/esm2022/lib/components/display-components/audio-card/audio-card.component.mjs +0 -356
- package/dist/esm2022/lib/components/display-components/audio-grid/audio-grid.component.mjs +0 -80
- package/dist/esm2022/lib/components/display-components/card-video-display/card-video-display.component.mjs +0 -129
- package/dist/esm2022/lib/components/display-components/control-buttons-alt-component/control-buttons-alt-component.component.mjs +0 -138
- package/dist/esm2022/lib/components/display-components/control-buttons-component/control-buttons-component.component.mjs +0 -231
- package/dist/esm2022/lib/components/display-components/control-buttons-component-touch/control-buttons-component-touch.component.mjs +0 -282
- package/dist/esm2022/lib/components/display-components/control-widgets/menu-participants-widget.component.mjs +0 -82
- package/dist/esm2022/lib/components/display-components/control-widgets/menu-record-widget.component.mjs +0 -65
- package/dist/esm2022/lib/components/display-components/control-widgets/menu-widget.component.mjs +0 -137
- package/dist/esm2022/lib/components/display-components/control-widgets/message-widget.component.mjs +0 -137
- package/dist/esm2022/lib/components/display-components/control-widgets/record-timer-widget.component.mjs +0 -51
- package/dist/esm2022/lib/components/display-components/control-widgets/screenshare-widget.component.mjs +0 -101
- package/dist/esm2022/lib/components/display-components/flexible-grid/flexible-grid.component.mjs +0 -151
- package/dist/esm2022/lib/components/display-components/flexible-video/flexible-video.component.mjs +0 -250
- package/dist/esm2022/lib/components/display-components/loading-modal/loading-modal.component.mjs +0 -102
- package/dist/esm2022/lib/components/display-components/main-aspect-component/main-aspect-component.component.mjs +0 -140
- package/dist/esm2022/lib/components/display-components/main-container-component/main-container-component.component.mjs +0 -131
- package/dist/esm2022/lib/components/display-components/main-grid-component/main-grid-component.component.mjs +0 -120
- package/dist/esm2022/lib/components/display-components/main-screen-component/main-screen-component.component.mjs +0 -201
- package/dist/esm2022/lib/components/display-components/meeting-progress-timer/meeting-progress-timer.component.mjs +0 -115
- package/dist/esm2022/lib/components/display-components/mini-audio/mini-audio.component.mjs +0 -319
- package/dist/esm2022/lib/components/display-components/mini-card/mini-card.component.mjs +0 -161
- package/dist/esm2022/lib/components/display-components/mini-card-audio/mini-card-audio.component.mjs +0 -230
- package/dist/esm2022/lib/components/display-components/other-grid-component/other-grid-component.component.mjs +0 -126
- package/dist/esm2022/lib/components/display-components/pagination/pagination.component.mjs +0 -334
- package/dist/esm2022/lib/components/display-components/sub-aspect-component/sub-aspect-component.component.mjs +0 -112
- package/dist/esm2022/lib/components/display-components/video-card/video-card.component.mjs +0 -392
- package/dist/esm2022/lib/components/display-settings-components/display-settings-modal.component.mjs +0 -106
- package/dist/esm2022/lib/components/event-settings-components/event-settings-modal/event-settings-modal.component.mjs +0 -199
- package/dist/esm2022/lib/components/exit-components/confirm-exit-modal/confirm-exit-modal.component.mjs +0 -132
- package/dist/esm2022/lib/components/media-settings-components/media-settings-modal/media-settings-modal.component.mjs +0 -220
- package/dist/esm2022/lib/components/mediasfu-components/mediasfu-broadcast.component.mjs +0 -4238
- package/dist/esm2022/lib/components/mediasfu-components/mediasfu-chat.component.mjs +0 -3754
- package/dist/esm2022/lib/components/mediasfu-components/mediasfu-conference.component.mjs +0 -5071
- package/dist/esm2022/lib/components/mediasfu-components/mediasfu-generic.component.mjs +0 -5380
- package/dist/esm2022/lib/components/mediasfu-components/mediasfu-webinar.component.mjs +0 -5068
- package/dist/esm2022/lib/components/menu-components/custom-buttons/custom-buttons.component.mjs +0 -83
- package/dist/esm2022/lib/components/menu-components/meeting-id-component/meeting-id-component.component.mjs +0 -27
- package/dist/esm2022/lib/components/menu-components/meeting-passcode-component/meeting-passcode-component.component.mjs +0 -27
- package/dist/esm2022/lib/components/menu-components/menu-modal/menu-modal.component.mjs +0 -125
- package/dist/esm2022/lib/components/menu-components/share-buttons-component/share-buttons-component.component.mjs +0 -106
- package/dist/esm2022/lib/components/message-components/message-panel/message-panel.component.mjs +0 -228
- package/dist/esm2022/lib/components/message-components/messages-modal/messages-modal.component.mjs +0 -277
- package/dist/esm2022/lib/components/misc-components/confirm-here-modal/confirm-here-modal.component.mjs +0 -130
- package/dist/esm2022/lib/components/misc-components/pre-join-page/pre-join-page.component.mjs +0 -343
- package/dist/esm2022/lib/components/misc-components/share-event-modal/share-event-modal.component.mjs +0 -127
- package/dist/esm2022/lib/components/misc-components/welcome-page/welcome-page.component.mjs +0 -241
- package/dist/esm2022/lib/components/participants-components/participant-list/participant-list.component.mjs +0 -82
- package/dist/esm2022/lib/components/participants-components/participant-list-item/participant-list-item.component.mjs +0 -139
- package/dist/esm2022/lib/components/participants-components/participant-list-others/participant-list-others.component.mjs +0 -40
- package/dist/esm2022/lib/components/participants-components/participant-list-others-item/participant-list-others-item.component.mjs +0 -60
- package/dist/esm2022/lib/components/participants-components/participants-modal/participants-modal.component.mjs +0 -124
- package/dist/esm2022/lib/components/polls-components/poll-modal/poll-modal.component.mjs +0 -201
- package/dist/esm2022/lib/components/recording-components/advanced-panel-component/advanced-panel-components.component.mjs +0 -92
- package/dist/esm2022/lib/components/recording-components/recording-modal/recording-modal.component.mjs +0 -133
- package/dist/esm2022/lib/components/recording-components/standard-panel-component/standard-panel-component.component.mjs +0 -90
- package/dist/esm2022/lib/components/requests-components/render-request-component/render-request-component.component.mjs +0 -81
- package/dist/esm2022/lib/components/requests-components/requests-modal/requests-modal.component.mjs +0 -147
- package/dist/esm2022/lib/components/screenboard-components/screenboard/screenboard.component.mjs +0 -627
- package/dist/esm2022/lib/components/screenboard-components/screenboard-modal/screenboard-modal.component.mjs +0 -391
- package/dist/esm2022/lib/components/waiting-components/waiting-room-modal.component.mjs +0 -201
- package/dist/esm2022/lib/components/whiteboard-components/configure-whiteboard-modal/configure-whiteboard-modal.component.mjs +0 -286
- package/dist/esm2022/lib/components/whiteboard-components/whiteboard/whiteboard.component.mjs +0 -1833
- package/dist/esm2022/lib/consumers/add-videos-grid.service.mjs +0 -345
- package/dist/esm2022/lib/consumers/auto-adjust.service.mjs +0 -109
- package/dist/esm2022/lib/consumers/calculate-rows-and-columns.service.mjs +0 -60
- package/dist/esm2022/lib/consumers/change-vids.service.mjs +0 -551
- package/dist/esm2022/lib/consumers/check-grid.service.mjs +0 -93
- package/dist/esm2022/lib/consumers/check-permission.service.mjs +0 -105
- package/dist/esm2022/lib/consumers/check-screen-share.service.mjs +0 -106
- package/dist/esm2022/lib/consumers/close-and-resize.service.mjs +0 -331
- package/dist/esm2022/lib/consumers/compare-active-names.service.mjs +0 -106
- package/dist/esm2022/lib/consumers/compare-screen-states.service.mjs +0 -98
- package/dist/esm2022/lib/consumers/connect-ips.service.mjs +0 -154
- package/dist/esm2022/lib/consumers/connect-recv-transport.service.mjs +0 -146
- package/dist/esm2022/lib/consumers/connect-send-transport-audio.service.mjs +0 -84
- package/dist/esm2022/lib/consumers/connect-send-transport-screen.service.mjs +0 -102
- package/dist/esm2022/lib/consumers/connect-send-transport-video.service.mjs +0 -99
- package/dist/esm2022/lib/consumers/connect-send-transport.service.mjs +0 -140
- package/dist/esm2022/lib/consumers/consumer-resume.service.mjs +0 -368
- package/dist/esm2022/lib/consumers/control-media.service.mjs +0 -113
- package/dist/esm2022/lib/consumers/create-send-transport.service.mjs +0 -172
- package/dist/esm2022/lib/consumers/disconnect-send-transport-audio.service.mjs +0 -108
- package/dist/esm2022/lib/consumers/disconnect-send-transport-screen.service.mjs +0 -84
- package/dist/esm2022/lib/consumers/disconnect-send-transport-video.service.mjs +0 -101
- package/dist/esm2022/lib/consumers/disp-streams.service.mjs +0 -513
- package/dist/esm2022/lib/consumers/generate-page-content.service.mjs +0 -106
- package/dist/esm2022/lib/consumers/get-estimate.service.mjs +0 -120
- package/dist/esm2022/lib/consumers/get-piped-producers-alt.service.mjs +0 -82
- package/dist/esm2022/lib/consumers/get-producers-piped.service.mjs +0 -79
- package/dist/esm2022/lib/consumers/get-videos.service.mjs +0 -91
- package/dist/esm2022/lib/consumers/mix-streams.service.mjs +0 -95
- package/dist/esm2022/lib/consumers/on-screen-changes.service.mjs +0 -103
- package/dist/esm2022/lib/consumers/prepopulate-user-media.service.mjs +0 -541
- package/dist/esm2022/lib/consumers/process-consumer-transports-audio.service.mjs +0 -101
- package/dist/esm2022/lib/consumers/process-consumer-transports.service.mjs +0 -128
- package/dist/esm2022/lib/consumers/re-port.service.mjs +0 -114
- package/dist/esm2022/lib/consumers/re-update-inter.service.mjs +0 -239
- package/dist/esm2022/lib/consumers/readjust.service.mjs +0 -173
- package/dist/esm2022/lib/consumers/receive-all-piped-transports.service.mjs +0 -87
- package/dist/esm2022/lib/consumers/receive-room-messages.service.mjs +0 -69
- package/dist/esm2022/lib/consumers/reorder-streams.service.mjs +0 -239
- package/dist/esm2022/lib/consumers/request-screen-share.service.mjs +0 -101
- package/dist/esm2022/lib/consumers/resume-pause-audio-streams.service.mjs +0 -150
- package/dist/esm2022/lib/consumers/resume-pause-streams.service.mjs +0 -103
- package/dist/esm2022/lib/consumers/resume-send-transport-audio.service.mjs +0 -91
- package/dist/esm2022/lib/consumers/signal-new-consumer-transport.service.mjs +0 -136
- package/dist/esm2022/lib/consumers/socket-receive-methods/join-consume-room.service.mjs +0 -96
- package/dist/esm2022/lib/consumers/socket-receive-methods/new-pipe-producer.service.mjs +0 -100
- package/dist/esm2022/lib/consumers/socket-receive-methods/producer-closed.service.mjs +0 -78
- package/dist/esm2022/lib/consumers/start-share-screen.service.mjs +0 -120
- package/dist/esm2022/lib/consumers/stop-share-screen.service.mjs +0 -175
- package/dist/esm2022/lib/consumers/stream-success-audio-switch.service.mjs +0 -185
- package/dist/esm2022/lib/consumers/stream-success-audio.service.mjs +0 -210
- package/dist/esm2022/lib/consumers/stream-success-screen.service.mjs +0 -193
- package/dist/esm2022/lib/consumers/stream-success-video.service.mjs +0 -260
- package/dist/esm2022/lib/consumers/switch-user-audio.service.mjs +0 -120
- package/dist/esm2022/lib/consumers/switch-user-video-alt.service.mjs +0 -260
- package/dist/esm2022/lib/consumers/switch-user-video.service.mjs +0 -172
- package/dist/esm2022/lib/consumers/trigger.service.mjs +0 -210
- package/dist/esm2022/lib/consumers/update-mini-cards-grid.service.mjs +0 -135
- package/dist/esm2022/lib/consumers/update-participant-audio-decibels.service.mjs +0 -84
- package/dist/esm2022/lib/methods/background-methods/launch-background.service.mjs +0 -48
- package/dist/esm2022/lib/methods/breakout-room-methods/breakout-room-updated.service.mjs +0 -183
- package/dist/esm2022/lib/methods/breakout-room-methods/launch-breakout-rooms.service.mjs +0 -46
- package/dist/esm2022/lib/methods/co-host-methods/launch-co-host.service.mjs +0 -46
- package/dist/esm2022/lib/methods/co-host-methods/modify-co-host-settings.service.mjs +0 -104
- package/dist/esm2022/lib/methods/display-settings-methods/launch-display-settings.service.mjs +0 -46
- package/dist/esm2022/lib/methods/display-settings-methods/modify-display-settings.service.mjs +0 -194
- package/dist/esm2022/lib/methods/exit-methods/confirm-exit.service.mjs +0 -52
- package/dist/esm2022/lib/methods/exit-methods/launch-confirm-exit.service.mjs +0 -42
- package/dist/esm2022/lib/methods/media-settings-methods/launch-media-settings.service.mjs +0 -85
- package/dist/esm2022/lib/methods/menu-methods/launch-menu-modal.service.mjs +0 -44
- package/dist/esm2022/lib/methods/message-methods/launch-messages.service.mjs +0 -45
- package/dist/esm2022/lib/methods/message-methods/send-message.service.mjs +0 -143
- package/dist/esm2022/lib/methods/participants-methods/launch-participants.service.mjs +0 -47
- package/dist/esm2022/lib/methods/participants-methods/message-participants.service.mjs +0 -98
- package/dist/esm2022/lib/methods/participants-methods/mute-participants.service.mjs +0 -96
- package/dist/esm2022/lib/methods/participants-methods/remove-participants.service.mjs +0 -107
- package/dist/esm2022/lib/methods/polls-methods/handle-create-poll.service.mjs +0 -75
- package/dist/esm2022/lib/methods/polls-methods/handle-end-poll.service.mjs +0 -72
- package/dist/esm2022/lib/methods/polls-methods/handle-vote-poll.service.mjs +0 -83
- package/dist/esm2022/lib/methods/polls-methods/launch-poll.service.mjs +0 -43
- package/dist/esm2022/lib/methods/polls-methods/poll-updated.service.mjs +0 -95
- package/dist/esm2022/lib/methods/recording-methods/check-pause-state.service.mjs +0 -69
- package/dist/esm2022/lib/methods/recording-methods/check-resume-state.service.mjs +0 -56
- package/dist/esm2022/lib/methods/recording-methods/confirm-recording.service.mjs +0 -278
- package/dist/esm2022/lib/methods/recording-methods/launch-recording.service.mjs +0 -125
- package/dist/esm2022/lib/methods/recording-methods/record-pause-timer.service.mjs +0 -67
- package/dist/esm2022/lib/methods/recording-methods/record-resume-timer.service.mjs +0 -130
- package/dist/esm2022/lib/methods/recording-methods/record-start-timer.service.mjs +0 -134
- package/dist/esm2022/lib/methods/recording-methods/record-update-timer.service.mjs +0 -80
- package/dist/esm2022/lib/methods/recording-methods/start-recording.service.mjs +0 -197
- package/dist/esm2022/lib/methods/recording-methods/stop-recording.service.mjs +0 -112
- package/dist/esm2022/lib/methods/recording-methods/update-recording.service.mjs +0 -272
- package/dist/esm2022/lib/methods/requests-methods/launch-requests.service.mjs +0 -51
- package/dist/esm2022/lib/methods/requests-methods/respond-to-requests.service.mjs +0 -84
- package/dist/esm2022/lib/methods/settings-methods/launch-settings.service.mjs +0 -51
- package/dist/esm2022/lib/methods/settings-methods/modify-settings.service.mjs +0 -109
- package/dist/esm2022/lib/methods/stream-methods/click-audio.service.mjs +0 -275
- package/dist/esm2022/lib/methods/stream-methods/click-chat.service.mjs +0 -75
- package/dist/esm2022/lib/methods/stream-methods/click-screen-share.service.mjs +0 -178
- package/dist/esm2022/lib/methods/stream-methods/click-video.service.mjs +0 -271
- package/dist/esm2022/lib/methods/stream-methods/switch-audio.service.mjs +0 -80
- package/dist/esm2022/lib/methods/stream-methods/switch-video-alt.service.mjs +0 -116
- package/dist/esm2022/lib/methods/stream-methods/switch-video.service.mjs +0 -132
- package/dist/esm2022/lib/methods/utils/format-number.service.mjs +0 -57
- package/dist/esm2022/lib/methods/utils/generate-random-messages.service.mjs +0 -120
- package/dist/esm2022/lib/methods/utils/generate-random-participants.service.mjs +0 -126
- package/dist/esm2022/lib/methods/utils/generate-random-polls.service.mjs +0 -78
- package/dist/esm2022/lib/methods/utils/generate-random-request-list.service.mjs +0 -90
- package/dist/esm2022/lib/methods/utils/generate-random-waiting-room-list.service.mjs +0 -59
- package/dist/esm2022/lib/methods/utils/get-modal-position.util.mjs +0 -32
- package/dist/esm2022/lib/methods/utils/get-overlay-position.util.mjs +0 -31
- package/dist/esm2022/lib/methods/utils/initial-values.util.mjs +0 -379
- package/dist/esm2022/lib/methods/utils/meeting-timer/start-meeting-progress-timer.service.mjs +0 -96
- package/dist/esm2022/lib/methods/utils/mini-audio-player/mini-audio-player.component.mjs +0 -315
- package/dist/esm2022/lib/methods/utils/producer/a-params.service.mjs +0 -58
- package/dist/esm2022/lib/methods/utils/producer/h-params.service.mjs +0 -87
- package/dist/esm2022/lib/methods/utils/producer/screen-params.service.mjs +0 -61
- package/dist/esm2022/lib/methods/utils/producer/v-params.service.mjs +0 -87
- package/dist/esm2022/lib/methods/utils/producer/video-capture-constraints.service.mjs +0 -84
- package/dist/esm2022/lib/methods/utils/sleep.util.mjs +0 -17
- package/dist/esm2022/lib/methods/utils/sound-player.service.mjs +0 -63
- package/dist/esm2022/lib/methods/utils/validate-alphanumeric.service.mjs +0 -49
- package/dist/esm2022/lib/methods/waiting-methods/launch-waiting.service.mjs +0 -41
- package/dist/esm2022/lib/methods/waiting-methods/respond-to-waiting.service.mjs +0 -69
- package/dist/esm2022/lib/methods/whiteboard-methods/capture-canvas-stream.service.mjs +0 -98
- package/dist/esm2022/lib/methods/whiteboard-methods/launch-configure-whiteboard.service.mjs +0 -44
- package/dist/esm2022/lib/producer-client/producer-client-emits/create-device-client.service.mjs +0 -74
- package/dist/esm2022/lib/producer-client/producer-client-emits/join-room-client.service.mjs +0 -96
- package/dist/esm2022/lib/producer-client/producer-client-emits/update-room-parameters-client.service.mjs +0 -276
- package/dist/esm2022/lib/producers/producer-emits/join-con-room.service.mjs +0 -152
- package/dist/esm2022/lib/producers/producer-emits/join-room.service.mjs +0 -152
- package/dist/esm2022/lib/producers/socket-receive-methods/all-members-rest.service.mjs +0 -228
- package/dist/esm2022/lib/producers/socket-receive-methods/all-members.service.mjs +0 -218
- package/dist/esm2022/lib/producers/socket-receive-methods/all-waiting-room-members.service.mjs +0 -57
- package/dist/esm2022/lib/producers/socket-receive-methods/ban-participant.service.mjs +0 -76
- package/dist/esm2022/lib/producers/socket-receive-methods/control-media-host.service.mjs +0 -183
- package/dist/esm2022/lib/producers/socket-receive-methods/disconnect-user-self.service.mjs +0 -50
- package/dist/esm2022/lib/producers/socket-receive-methods/disconnect.service.mjs +0 -64
- package/dist/esm2022/lib/producers/socket-receive-methods/get-domains.service.mjs +0 -78
- package/dist/esm2022/lib/producers/socket-receive-methods/host-request-response.service.mjs +0 -150
- package/dist/esm2022/lib/producers/socket-receive-methods/meeting-ended.service.mjs +0 -73
- package/dist/esm2022/lib/producers/socket-receive-methods/meeting-still-there.service.mjs +0 -47
- package/dist/esm2022/lib/producers/socket-receive-methods/meeting-time-remaining.service.mjs +0 -63
- package/dist/esm2022/lib/producers/socket-receive-methods/participant-requested.service.mjs +0 -63
- package/dist/esm2022/lib/producers/socket-receive-methods/person-joined.service.mjs +0 -54
- package/dist/esm2022/lib/producers/socket-receive-methods/producer-media-closed.service.mjs +0 -129
- package/dist/esm2022/lib/producers/socket-receive-methods/producer-media-paused.service.mjs +0 -152
- package/dist/esm2022/lib/producers/socket-receive-methods/producer-media-resumed.service.mjs +0 -99
- package/dist/esm2022/lib/producers/socket-receive-methods/re-initiate-recording.service.mjs +0 -67
- package/dist/esm2022/lib/producers/socket-receive-methods/receive-message.service.mjs +0 -134
- package/dist/esm2022/lib/producers/socket-receive-methods/recording-notice.service.mjs +0 -233
- package/dist/esm2022/lib/producers/socket-receive-methods/room-record-params.service.mjs +0 -121
- package/dist/esm2022/lib/producers/socket-receive-methods/screen-producer-id.service.mjs +0 -86
- package/dist/esm2022/lib/producers/socket-receive-methods/start-records.service.mjs +0 -60
- package/dist/esm2022/lib/producers/socket-receive-methods/stopped-recording.service.mjs +0 -62
- package/dist/esm2022/lib/producers/socket-receive-methods/time-left-recording.service.mjs +0 -57
- package/dist/esm2022/lib/producers/socket-receive-methods/update-consuming-domains.service.mjs +0 -105
- package/dist/esm2022/lib/producers/socket-receive-methods/update-media-settings.service.mjs +0 -66
- package/dist/esm2022/lib/producers/socket-receive-methods/updated-co-host.service.mjs +0 -96
- package/dist/esm2022/lib/producers/socket-receive-methods/user-waiting.service.mjs +0 -52
- package/dist/esm2022/lib/sockets/socket-manager.service.mjs +0 -113
- package/dist/esm2022/mediasfu-angular.mjs +0 -5
- package/dist/esm2022/public-api.mjs +0 -187
|
@@ -1,799 +0,0 @@
|
|
|
1
|
-
/* eslint-disable @typescript-eslint/no-non-null-assertion */
|
|
2
|
-
import { Component, Input, ViewChild, } from '@angular/core';
|
|
3
|
-
import { CommonModule } from '@angular/common';
|
|
4
|
-
import { FontAwesomeModule } from '@fortawesome/angular-fontawesome';
|
|
5
|
-
import { faTimes } from '@fortawesome/free-solid-svg-icons';
|
|
6
|
-
import { SelfieSegmentation } from '@mediapipe/selfie_segmentation';
|
|
7
|
-
import * as i0 from "@angular/core";
|
|
8
|
-
import * as i1 from "@angular/common";
|
|
9
|
-
import * as i2 from "@fortawesome/angular-fontawesome";
|
|
10
|
-
/**
|
|
11
|
-
* BackgroundModal - Component to manage background selection and manipulation in media streams.
|
|
12
|
-
*
|
|
13
|
-
* This component allows users to choose, apply, and manipulate virtual backgrounds for media streams, leveraging MediaPipe’s Selfie Segmentation and MediaSoup functionalities.
|
|
14
|
-
*
|
|
15
|
-
* @component
|
|
16
|
-
* @name BackgroundModal
|
|
17
|
-
* @example
|
|
18
|
-
* ```typescript
|
|
19
|
-
* <app-background-modal
|
|
20
|
-
* [isVisible]="isModalVisible"
|
|
21
|
-
* [parameters]="modalParameters"
|
|
22
|
-
* position="topLeft"
|
|
23
|
-
* backgroundColor="#f5f5f5"
|
|
24
|
-
* (onClose)="handleModalClose()"
|
|
25
|
-
* ></app-background-modal>
|
|
26
|
-
* ```
|
|
27
|
-
*
|
|
28
|
-
* @param {boolean} isVisible - Visibility state of the modal.
|
|
29
|
-
* @param {BackgroundModalParameters} parameters - Parameters including settings and methods for media and background management.
|
|
30
|
-
* @param {string} position - The position of the modal, e.g., 'topLeft'.
|
|
31
|
-
* @param {string} backgroundColor - Background color of the modal.
|
|
32
|
-
* @param {Function} onClose - Callback function when the modal is closed.
|
|
33
|
-
*
|
|
34
|
-
* @property {faTimes} faTimes - Icon used for closing the modal.
|
|
35
|
-
* @property {string} customImage - Custom image URL for background.
|
|
36
|
-
* @property {string} selectedImage - Selected image URL for background.
|
|
37
|
-
* @property {MediaStream | null} segmentVideo - Media stream for video segmentation.
|
|
38
|
-
* @property {SelfieSegmentation | null} selfieSegmentation - SelfieSegmentation instance.
|
|
39
|
-
* @property {boolean} pauseSegmentation - Pause state for segmentation.
|
|
40
|
-
* @property {MediaStream | null} processedStream - Processed media stream with applied background.
|
|
41
|
-
* @property {boolean} keepBackground - State to keep or reset background.
|
|
42
|
-
*
|
|
43
|
-
* @method
|
|
44
|
-
* ngOnInit - Initializes the modal component by updating properties based on parameters.
|
|
45
|
-
*/
|
|
46
|
-
export class BackgroundModal {
|
|
47
|
-
isVisible = false;
|
|
48
|
-
parameters = {};
|
|
49
|
-
position = 'topLeft';
|
|
50
|
-
backgroundColor = '#f5f5f5';
|
|
51
|
-
onClose = () => {
|
|
52
|
-
console.log('onClose');
|
|
53
|
-
};
|
|
54
|
-
defaultImagesContainerRef;
|
|
55
|
-
uploadImageInputRef;
|
|
56
|
-
backgroundCanvasRef;
|
|
57
|
-
videoPreviewRef;
|
|
58
|
-
captureVideoRef;
|
|
59
|
-
loadingOverlayRef;
|
|
60
|
-
applyBackgroundButtonRef;
|
|
61
|
-
saveBackgroundButtonRef;
|
|
62
|
-
faTimes = faTimes;
|
|
63
|
-
customImage = '';
|
|
64
|
-
selectedImage = '';
|
|
65
|
-
segmentVideo = null;
|
|
66
|
-
selfieSegmentation = null;
|
|
67
|
-
pauseSegmentation = false;
|
|
68
|
-
processedStream = null;
|
|
69
|
-
keepBackground = false;
|
|
70
|
-
backgroundHasChanged = false;
|
|
71
|
-
virtualStream = null;
|
|
72
|
-
mainCanvas;
|
|
73
|
-
prevKeepBackground = false;
|
|
74
|
-
appliedBackground = false;
|
|
75
|
-
videoAlreadyOn = false;
|
|
76
|
-
audioOnlyRoom = false;
|
|
77
|
-
islevel = '0';
|
|
78
|
-
recordStarted = false;
|
|
79
|
-
recordResumed = false;
|
|
80
|
-
recordPaused = false;
|
|
81
|
-
recordStopped = false;
|
|
82
|
-
recordingMediaOptions = '';
|
|
83
|
-
vidCons = {};
|
|
84
|
-
frameRate = 5;
|
|
85
|
-
targetResolution = '1280x720';
|
|
86
|
-
videoParams = {};
|
|
87
|
-
autoClickBackground = false;
|
|
88
|
-
localStreamVideo = null;
|
|
89
|
-
clonedStream = null;
|
|
90
|
-
clonedTrack = null;
|
|
91
|
-
updateCustomImage;
|
|
92
|
-
updateSelectedImage;
|
|
93
|
-
updateSegmentVideo;
|
|
94
|
-
updateSelfieSegmentation;
|
|
95
|
-
updatePauseSegmentation;
|
|
96
|
-
updateProcessedStream;
|
|
97
|
-
updateKeepBackground;
|
|
98
|
-
updateBackgroundHasChanged;
|
|
99
|
-
updateVirtualStream;
|
|
100
|
-
updateMainCanvas;
|
|
101
|
-
updatePrevKeepBackground;
|
|
102
|
-
updateAppliedBackground;
|
|
103
|
-
updateVideoParams;
|
|
104
|
-
updateAutoClickBackground;
|
|
105
|
-
// Media functions
|
|
106
|
-
createSendTransport;
|
|
107
|
-
connectSendTransportVideo;
|
|
108
|
-
disconnectSendTransportVideo;
|
|
109
|
-
onScreenChanges;
|
|
110
|
-
sleep;
|
|
111
|
-
ngOnInit() {
|
|
112
|
-
// Initialize local properties from the parameters
|
|
113
|
-
if (this.parameters) {
|
|
114
|
-
try {
|
|
115
|
-
this.updateVariables();
|
|
116
|
-
}
|
|
117
|
-
catch {
|
|
118
|
-
/* handle error */
|
|
119
|
-
}
|
|
120
|
-
}
|
|
121
|
-
}
|
|
122
|
-
ngOnChanges(changes) {
|
|
123
|
-
if (changes['isVisible']) {
|
|
124
|
-
this.onVisibilityChange();
|
|
125
|
-
}
|
|
126
|
-
if (changes['autoClickBackground']) {
|
|
127
|
-
console.log('Auto click background changed:', this.autoClickBackground, changes['autoClickBackground']);
|
|
128
|
-
}
|
|
129
|
-
}
|
|
130
|
-
updateVariables() {
|
|
131
|
-
this.customImage = this.parameters.customImage || '';
|
|
132
|
-
this.selectedImage = this.parameters.selectedImage || '';
|
|
133
|
-
this.segmentVideo = this.parameters.segmentVideo || null;
|
|
134
|
-
this.selfieSegmentation = this.parameters.selfieSegmentation || null;
|
|
135
|
-
this.pauseSegmentation = this.parameters.pauseSegmentation || false;
|
|
136
|
-
this.processedStream = this.parameters.processedStream || null;
|
|
137
|
-
this.keepBackground = this.parameters.keepBackground || false;
|
|
138
|
-
this.backgroundHasChanged = this.parameters.backgroundHasChanged || false;
|
|
139
|
-
this.virtualStream = this.parameters.virtualStream || null;
|
|
140
|
-
this.mainCanvas = this.parameters.mainCanvas || this.backgroundCanvasRef?.nativeElement || null;
|
|
141
|
-
this.prevKeepBackground = this.parameters.prevKeepBackground || false;
|
|
142
|
-
this.appliedBackground = this.parameters.appliedBackground || false;
|
|
143
|
-
this.videoAlreadyOn = this.parameters.videoAlreadyOn || false;
|
|
144
|
-
this.audioOnlyRoom = this.parameters.audioOnlyRoom || false;
|
|
145
|
-
this.islevel = this.parameters.islevel || '0';
|
|
146
|
-
this.recordStarted = this.parameters.recordStarted || false;
|
|
147
|
-
this.recordResumed = this.parameters.recordResumed || false;
|
|
148
|
-
this.recordPaused = this.parameters.recordPaused || false;
|
|
149
|
-
this.recordStopped = this.parameters.recordStopped || false;
|
|
150
|
-
this.recordingMediaOptions = this.parameters.recordingMediaOptions || '';
|
|
151
|
-
this.vidCons = this.parameters.vidCons || {};
|
|
152
|
-
this.frameRate = this.parameters.frameRate || 5;
|
|
153
|
-
this.videoParams = this.parameters.videoParams || null;
|
|
154
|
-
this.autoClickBackground = this.parameters.autoClickBackground || false;
|
|
155
|
-
this.localStreamVideo = this.parameters.localStreamVideo || null;
|
|
156
|
-
// Assign method references
|
|
157
|
-
this.updateCustomImage = this.parameters.updateCustomImage;
|
|
158
|
-
this.updateSelectedImage = this.parameters.updateSelectedImage;
|
|
159
|
-
this.updateSegmentVideo = this.parameters.updateSegmentVideo;
|
|
160
|
-
this.updateSelfieSegmentation = this.parameters.updateSelfieSegmentation;
|
|
161
|
-
this.updatePauseSegmentation = this.parameters.updatePauseSegmentation;
|
|
162
|
-
this.updateProcessedStream = this.parameters.updateProcessedStream;
|
|
163
|
-
this.updateKeepBackground = this.parameters.updateKeepBackground;
|
|
164
|
-
this.updateBackgroundHasChanged = this.parameters.updateBackgroundHasChanged;
|
|
165
|
-
this.updateVirtualStream = this.parameters.updateVirtualStream;
|
|
166
|
-
this.updateMainCanvas = this.parameters.updateMainCanvas;
|
|
167
|
-
this.updatePrevKeepBackground = this.parameters.updatePrevKeepBackground;
|
|
168
|
-
this.updateAppliedBackground = this.parameters.updateAppliedBackground;
|
|
169
|
-
this.updateVideoParams = this.parameters.updateVideoParams;
|
|
170
|
-
this.updateAutoClickBackground = this.parameters.updateAutoClickBackground;
|
|
171
|
-
this.createSendTransport = this.parameters.createSendTransport;
|
|
172
|
-
this.connectSendTransportVideo = this.parameters.connectSendTransportVideo;
|
|
173
|
-
this.disconnectSendTransportVideo = this.parameters.disconnectSendTransportVideo;
|
|
174
|
-
this.onScreenChanges = this.parameters.onScreenChanges;
|
|
175
|
-
this.sleep = this.parameters.sleep;
|
|
176
|
-
}
|
|
177
|
-
onVisibilityChange = async () => {
|
|
178
|
-
if (this.parameters) {
|
|
179
|
-
this.parameters = this.parameters.getUpdatedAllParams();
|
|
180
|
-
this.updateVariables();
|
|
181
|
-
}
|
|
182
|
-
if (this.isVisible) {
|
|
183
|
-
if (!this.selfieSegmentation) {
|
|
184
|
-
await this.preloadModel().catch(() => console.log('Error preloading model:'));
|
|
185
|
-
}
|
|
186
|
-
this.renderDefaultImages();
|
|
187
|
-
if (this.selectedImage) {
|
|
188
|
-
await this.loadImageToCanvas(this.selectedImage, this.selectedImage);
|
|
189
|
-
}
|
|
190
|
-
else {
|
|
191
|
-
this.clearCanvas();
|
|
192
|
-
this.backgroundCanvasRef.nativeElement.classList.remove('d-none');
|
|
193
|
-
}
|
|
194
|
-
this.saveBackgroundButtonRef.nativeElement.classList.add('d-none');
|
|
195
|
-
this.saveBackgroundButtonRef.nativeElement.disabled = true;
|
|
196
|
-
this.applyBackgroundButtonRef.nativeElement.classList.remove('d-none');
|
|
197
|
-
this.applyBackgroundButtonRef.nativeElement.disabled = false;
|
|
198
|
-
if (this.processedStream &&
|
|
199
|
-
this.prevKeepBackground == this.keepBackground &&
|
|
200
|
-
this.keepBackground &&
|
|
201
|
-
this.appliedBackground) {
|
|
202
|
-
this.applyBackgroundButtonRef.nativeElement.innerText = 'Apply Background';
|
|
203
|
-
}
|
|
204
|
-
else {
|
|
205
|
-
this.applyBackgroundButtonRef.nativeElement.innerText = 'Preview Background';
|
|
206
|
-
}
|
|
207
|
-
if (this.autoClickBackground) {
|
|
208
|
-
await this.applyBackground();
|
|
209
|
-
await this.saveBackground();
|
|
210
|
-
this.autoClickBackground = false;
|
|
211
|
-
this.updateAutoClickBackground(this.autoClickBackground);
|
|
212
|
-
}
|
|
213
|
-
}
|
|
214
|
-
else {
|
|
215
|
-
try {
|
|
216
|
-
// If no background is applied or the applied background should not be kept
|
|
217
|
-
if (!this.appliedBackground ||
|
|
218
|
-
(this.appliedBackground && !this.keepBackground) ||
|
|
219
|
-
(this.appliedBackground && !this.videoAlreadyOn)) {
|
|
220
|
-
const refVideo = this.captureVideoRef.nativeElement;
|
|
221
|
-
this.pauseSegmentation = true;
|
|
222
|
-
this.updatePauseSegmentation(this.pauseSegmentation);
|
|
223
|
-
if (!this.videoAlreadyOn) {
|
|
224
|
-
// Stop video tracks and clear the video element's srcObject
|
|
225
|
-
if (refVideo && refVideo.srcObject) {
|
|
226
|
-
refVideo.srcObject.getTracks().forEach((track) => track.stop());
|
|
227
|
-
refVideo.srcObject = null;
|
|
228
|
-
}
|
|
229
|
-
// Stop segmentVideo tracks
|
|
230
|
-
if (this.segmentVideo) {
|
|
231
|
-
this.segmentVideo.getTracks().forEach((track) => track.stop());
|
|
232
|
-
this.segmentVideo = null;
|
|
233
|
-
this.updateSegmentVideo(this.segmentVideo);
|
|
234
|
-
}
|
|
235
|
-
// Stop virtualStream tracks
|
|
236
|
-
if (this.virtualStream) {
|
|
237
|
-
this.virtualStream.getTracks().forEach((track) => track.stop());
|
|
238
|
-
this.virtualStream = null;
|
|
239
|
-
this.updateVirtualStream(this.virtualStream);
|
|
240
|
-
}
|
|
241
|
-
}
|
|
242
|
-
}
|
|
243
|
-
// Hide the video preview and show the canvas
|
|
244
|
-
this.videoPreviewRef.nativeElement.classList.add('d-none');
|
|
245
|
-
this.backgroundCanvasRef.nativeElement.classList.remove('d-none');
|
|
246
|
-
}
|
|
247
|
-
catch {
|
|
248
|
-
/* handle error */
|
|
249
|
-
}
|
|
250
|
-
}
|
|
251
|
-
};
|
|
252
|
-
async preloadModel() {
|
|
253
|
-
this.selfieSegmentation = new SelfieSegmentation({
|
|
254
|
-
locateFile: (file) => `https://cdn.jsdelivr.net/npm/@mediapipe/selfie_segmentation/${file}`,
|
|
255
|
-
});
|
|
256
|
-
this.selfieSegmentation.setOptions({
|
|
257
|
-
modelSelection: 1,
|
|
258
|
-
selfieMode: false,
|
|
259
|
-
});
|
|
260
|
-
await this.selfieSegmentation.initialize();
|
|
261
|
-
this.updateSelfieSegmentation(this.selfieSegmentation);
|
|
262
|
-
}
|
|
263
|
-
renderDefaultImages() {
|
|
264
|
-
const defaultImages = ['wall', 'wall2', 'shelf', 'clock', 'desert', 'flower'];
|
|
265
|
-
const defaultImagesContainer = this.defaultImagesContainerRef.nativeElement;
|
|
266
|
-
defaultImagesContainer.innerHTML = '';
|
|
267
|
-
defaultImages.forEach((baseName) => {
|
|
268
|
-
const thumb = `https://mediasfu.com/images/backgrounds/${baseName}_thumbnail.jpg`;
|
|
269
|
-
const small = `https://mediasfu.com/images/backgrounds/${baseName}_small.jpg`;
|
|
270
|
-
const large = `https://mediasfu.com/images/backgrounds/${baseName}_large.jpg`;
|
|
271
|
-
const full = `https://mediasfu.com/images/backgrounds/${baseName}.jpg`;
|
|
272
|
-
const img = document.createElement('img');
|
|
273
|
-
img.src = thumb;
|
|
274
|
-
img.classList.add('img-thumbnail', 'm-1');
|
|
275
|
-
img.style.width = '80px';
|
|
276
|
-
img.style.cursor = 'pointer';
|
|
277
|
-
img.addEventListener('click', async () => {
|
|
278
|
-
if (this.targetResolution == 'fhd' || this.targetResolution == 'qhd') {
|
|
279
|
-
await this.loadImageToCanvas(small, large);
|
|
280
|
-
}
|
|
281
|
-
else {
|
|
282
|
-
await this.loadImageToCanvas(small, full);
|
|
283
|
-
}
|
|
284
|
-
});
|
|
285
|
-
defaultImagesContainer.appendChild(img);
|
|
286
|
-
});
|
|
287
|
-
const noBackgroundImg = document.createElement('div');
|
|
288
|
-
noBackgroundImg.classList.add('img-thumbnail', 'm-1', 'd-flex', 'align-items-center', 'justify-content-center');
|
|
289
|
-
noBackgroundImg.style.width = '76px';
|
|
290
|
-
noBackgroundImg.style.minHeight = '60px';
|
|
291
|
-
noBackgroundImg.style.cursor = 'pointer';
|
|
292
|
-
noBackgroundImg.style.backgroundColor = '#f8f9fa';
|
|
293
|
-
noBackgroundImg.style.border = '1px solid #dee2e6';
|
|
294
|
-
noBackgroundImg.style.position = 'relative';
|
|
295
|
-
noBackgroundImg.innerHTML =
|
|
296
|
-
'<span style="position:absolute; top:50%; left:50%; transform:translate(-50%, -50%); color:#000;">None</span>';
|
|
297
|
-
noBackgroundImg.addEventListener('click', async () => {
|
|
298
|
-
this.selectedImage = '';
|
|
299
|
-
this.updateSelectedImage(this.selectedImage);
|
|
300
|
-
this.updateCustomImage('');
|
|
301
|
-
this.showLoading();
|
|
302
|
-
this.videoPreviewRef.nativeElement.classList.add('d-none');
|
|
303
|
-
this.backgroundCanvasRef.nativeElement.classList.remove('d-none');
|
|
304
|
-
this.clearCanvas();
|
|
305
|
-
this.hideLoading();
|
|
306
|
-
});
|
|
307
|
-
defaultImagesContainer.appendChild(noBackgroundImg);
|
|
308
|
-
if (this.customImage) {
|
|
309
|
-
const img = document.createElement('img');
|
|
310
|
-
img.src = this.customImage;
|
|
311
|
-
img.classList.add('img-thumbnail', 'm-1');
|
|
312
|
-
img.style.width = '80px';
|
|
313
|
-
img.style.cursor = 'pointer';
|
|
314
|
-
img.addEventListener('click', async () => {
|
|
315
|
-
await this.loadImageToCanvas(this.customImage, this.customImage);
|
|
316
|
-
});
|
|
317
|
-
defaultImagesContainer.appendChild(img);
|
|
318
|
-
}
|
|
319
|
-
}
|
|
320
|
-
async handleImageUpload(event) {
|
|
321
|
-
let minWidth = 1280;
|
|
322
|
-
let minHeight = 1280;
|
|
323
|
-
let maxWidth = 2560;
|
|
324
|
-
let maxHeight = 2560;
|
|
325
|
-
if (this.targetResolution == 'fhd') {
|
|
326
|
-
minWidth = 1920;
|
|
327
|
-
minHeight = 1920;
|
|
328
|
-
}
|
|
329
|
-
else if (this.targetResolution == 'qhd') {
|
|
330
|
-
minWidth = 2560;
|
|
331
|
-
minHeight = 2560;
|
|
332
|
-
} // For other resolutions, stick to the default 1280x1280
|
|
333
|
-
const input = event.target;
|
|
334
|
-
if (input.files && input.files.length > 0) {
|
|
335
|
-
const file = input.files[0];
|
|
336
|
-
const img = new Image();
|
|
337
|
-
img.crossOrigin = 'anonymous';
|
|
338
|
-
img.onload = async () => {
|
|
339
|
-
if (img.width < minWidth ||
|
|
340
|
-
img.height < minHeight ||
|
|
341
|
-
img.width > maxWidth ||
|
|
342
|
-
img.height > maxHeight) {
|
|
343
|
-
this.customImage = img.src;
|
|
344
|
-
this.updateCustomImage(this.customImage);
|
|
345
|
-
await this.loadImageToCanvas(img.src, img.src);
|
|
346
|
-
}
|
|
347
|
-
};
|
|
348
|
-
const reader = new FileReader();
|
|
349
|
-
reader.onload = (e) => {
|
|
350
|
-
if (e.target) {
|
|
351
|
-
img.src = e.target.result;
|
|
352
|
-
}
|
|
353
|
-
};
|
|
354
|
-
reader.readAsDataURL(file);
|
|
355
|
-
}
|
|
356
|
-
}
|
|
357
|
-
clearCanvas() {
|
|
358
|
-
const ctx = this.backgroundCanvasRef.nativeElement.getContext('2d');
|
|
359
|
-
ctx.clearRect(0, 0, this.backgroundCanvasRef.nativeElement.width, this.backgroundCanvasRef.nativeElement.height);
|
|
360
|
-
ctx.font = '30px Arial';
|
|
361
|
-
ctx.fillStyle = '#000';
|
|
362
|
-
ctx.textAlign = 'center';
|
|
363
|
-
ctx.textBaseline = 'middle';
|
|
364
|
-
ctx.fillText('No Background', this.backgroundCanvasRef.nativeElement.width / 2, this.backgroundCanvasRef.nativeElement.height / 2);
|
|
365
|
-
this.applyBackgroundButtonRef.nativeElement.classList.remove('d-none');
|
|
366
|
-
this.applyBackgroundButtonRef.nativeElement.disabled = false;
|
|
367
|
-
if (this.processedStream &&
|
|
368
|
-
this.prevKeepBackground == this.keepBackground &&
|
|
369
|
-
this.keepBackground &&
|
|
370
|
-
this.appliedBackground) {
|
|
371
|
-
this.applyBackgroundButtonRef.nativeElement.innerText = 'Apply Background';
|
|
372
|
-
}
|
|
373
|
-
else {
|
|
374
|
-
this.applyBackgroundButtonRef.nativeElement.innerText = 'Preview Background';
|
|
375
|
-
}
|
|
376
|
-
}
|
|
377
|
-
async loadImageToCanvas(src, fullSrc) {
|
|
378
|
-
this.showLoading();
|
|
379
|
-
await this.backgroundCanvasRef.nativeElement.classList.remove('d-none');
|
|
380
|
-
await this.videoPreviewRef.nativeElement.classList.add('d-none');
|
|
381
|
-
const img = new Image();
|
|
382
|
-
img.crossOrigin = 'anonymous';
|
|
383
|
-
img.onload = async () => {
|
|
384
|
-
const ctx = await this.backgroundCanvasRef.nativeElement.getContext('2d');
|
|
385
|
-
this.backgroundCanvasRef.nativeElement.width = img.width;
|
|
386
|
-
this.backgroundCanvasRef.nativeElement.height = img.height;
|
|
387
|
-
await ctx.drawImage(img, 0, 0);
|
|
388
|
-
this.removeBackground(img);
|
|
389
|
-
this.hideLoading();
|
|
390
|
-
};
|
|
391
|
-
img.src = src;
|
|
392
|
-
this.selectedImage = fullSrc;
|
|
393
|
-
this.updateSelectedImage(this.selectedImage);
|
|
394
|
-
this.saveBackgroundButtonRef.nativeElement.classList.add('d-none');
|
|
395
|
-
this.saveBackgroundButtonRef.nativeElement.disabled = true;
|
|
396
|
-
this.applyBackgroundButtonRef.nativeElement.classList.remove('d-none');
|
|
397
|
-
this.applyBackgroundButtonRef.nativeElement.disabled = false;
|
|
398
|
-
if (this.processedStream &&
|
|
399
|
-
this.prevKeepBackground == this.keepBackground &&
|
|
400
|
-
this.keepBackground &&
|
|
401
|
-
this.appliedBackground) {
|
|
402
|
-
this.applyBackgroundButtonRef.nativeElement.innerText = 'Apply Background';
|
|
403
|
-
}
|
|
404
|
-
else {
|
|
405
|
-
this.applyBackgroundButtonRef.nativeElement.innerText = 'Preview Background';
|
|
406
|
-
}
|
|
407
|
-
}
|
|
408
|
-
removeBackground(img) {
|
|
409
|
-
const ctx = this.backgroundCanvasRef.nativeElement.getContext('2d');
|
|
410
|
-
ctx.clearRect(0, 0, this.backgroundCanvasRef.nativeElement.width, this.backgroundCanvasRef.nativeElement.height);
|
|
411
|
-
ctx.drawImage(img, 0, 0);
|
|
412
|
-
}
|
|
413
|
-
async applyBackground() {
|
|
414
|
-
try {
|
|
415
|
-
if (this.audioOnlyRoom) {
|
|
416
|
-
this.parameters.showAlert?.({
|
|
417
|
-
message: 'You cannot use a background in an audio only event.',
|
|
418
|
-
type: 'danger',
|
|
419
|
-
});
|
|
420
|
-
return;
|
|
421
|
-
}
|
|
422
|
-
this.showLoading();
|
|
423
|
-
this.videoPreviewRef.nativeElement.classList.remove('d-none');
|
|
424
|
-
this.backgroundCanvasRef.nativeElement.classList.add('d-none');
|
|
425
|
-
const doSegmentation = this.selectedImage ? true : false;
|
|
426
|
-
this.pauseSegmentation = false;
|
|
427
|
-
this.updatePauseSegmentation(this.pauseSegmentation);
|
|
428
|
-
await this.selfieSegmentationPreview(doSegmentation);
|
|
429
|
-
this.hideLoading();
|
|
430
|
-
this.applyBackgroundButtonRef.nativeElement.classList.add('d-none');
|
|
431
|
-
this.applyBackgroundButtonRef.nativeElement.disabled = true;
|
|
432
|
-
if (this.processedStream &&
|
|
433
|
-
this.prevKeepBackground == this.keepBackground &&
|
|
434
|
-
this.keepBackground &&
|
|
435
|
-
this.appliedBackground) {
|
|
436
|
-
this.saveBackgroundButtonRef.nativeElement.classList.add('d-none');
|
|
437
|
-
this.saveBackgroundButtonRef.nativeElement.disabled = true;
|
|
438
|
-
}
|
|
439
|
-
else {
|
|
440
|
-
this.saveBackgroundButtonRef.nativeElement.classList.remove('d-none');
|
|
441
|
-
this.saveBackgroundButtonRef.nativeElement.disabled = false;
|
|
442
|
-
}
|
|
443
|
-
}
|
|
444
|
-
catch (error) {
|
|
445
|
-
console.log(error);
|
|
446
|
-
}
|
|
447
|
-
}
|
|
448
|
-
async selfieSegmentationPreview(doSegmentation) {
|
|
449
|
-
const refVideo = this.captureVideoRef.nativeElement;
|
|
450
|
-
const previewVideo = this.videoPreviewRef.nativeElement;
|
|
451
|
-
const virtualImage = new Image();
|
|
452
|
-
virtualImage.crossOrigin = 'anonymous';
|
|
453
|
-
virtualImage.src = this.selectedImage;
|
|
454
|
-
if (!this.mainCanvas) {
|
|
455
|
-
this.mainCanvas = await this.backgroundCanvasRef.nativeElement;
|
|
456
|
-
}
|
|
457
|
-
let mediaCanvas = this.mainCanvas;
|
|
458
|
-
mediaCanvas.width = refVideo.videoWidth;
|
|
459
|
-
mediaCanvas.height = refVideo.videoHeight;
|
|
460
|
-
let ctx = mediaCanvas.getContext('2d');
|
|
461
|
-
this.backgroundHasChanged = true;
|
|
462
|
-
this.updateBackgroundHasChanged(this.backgroundHasChanged);
|
|
463
|
-
this.prevKeepBackground = this.keepBackground;
|
|
464
|
-
this.updatePrevKeepBackground(this.keepBackground);
|
|
465
|
-
if (!doSegmentation) {
|
|
466
|
-
const tracks = this.processedStream?.getVideoTracks();
|
|
467
|
-
if (tracks) {
|
|
468
|
-
tracks.forEach((track) => track.stop());
|
|
469
|
-
}
|
|
470
|
-
this.processedStream = null;
|
|
471
|
-
this.keepBackground = false;
|
|
472
|
-
this.updateProcessedStream(null);
|
|
473
|
-
this.updateKeepBackground(false);
|
|
474
|
-
previewVideo.classList.remove('d-none');
|
|
475
|
-
}
|
|
476
|
-
const segmentImage = async (videoElement) => {
|
|
477
|
-
const processFrame = () => {
|
|
478
|
-
if (!this.selfieSegmentation ||
|
|
479
|
-
this.pauseSegmentation ||
|
|
480
|
-
!videoElement ||
|
|
481
|
-
videoElement.videoWidth == 0 ||
|
|
482
|
-
videoElement.videoHeight == 0) {
|
|
483
|
-
return;
|
|
484
|
-
}
|
|
485
|
-
this.selfieSegmentation.send({ image: videoElement });
|
|
486
|
-
requestAnimationFrame(processFrame);
|
|
487
|
-
};
|
|
488
|
-
videoElement.onloadeddata = () => {
|
|
489
|
-
processFrame();
|
|
490
|
-
};
|
|
491
|
-
setTimeout(async () => {
|
|
492
|
-
console.log('Capturing stream:', this.frameRate || 5);
|
|
493
|
-
this.processedStream = mediaCanvas.captureStream(this.frameRate || 5);
|
|
494
|
-
this.updateProcessedStream(this.processedStream);
|
|
495
|
-
previewVideo.srcObject = this.processedStream;
|
|
496
|
-
previewVideo.classList.remove('d-none');
|
|
497
|
-
this.keepBackground = true;
|
|
498
|
-
this.updateKeepBackground(this.keepBackground);
|
|
499
|
-
if (previewVideo.paused) {
|
|
500
|
-
try {
|
|
501
|
-
// play the video
|
|
502
|
-
previewVideo.play().then(() => {
|
|
503
|
-
/* handle success */
|
|
504
|
-
});
|
|
505
|
-
}
|
|
506
|
-
catch {
|
|
507
|
-
/* handle error */
|
|
508
|
-
}
|
|
509
|
-
}
|
|
510
|
-
}, 100);
|
|
511
|
-
};
|
|
512
|
-
if (this.videoAlreadyOn) {
|
|
513
|
-
if (this.clonedTrack &&
|
|
514
|
-
this.clonedTrack.readyState == 'live' &&
|
|
515
|
-
this.localStreamVideo?.getVideoTracks()[0].label == this.clonedTrack.label) {
|
|
516
|
-
// Use existing clonedTrack
|
|
517
|
-
}
|
|
518
|
-
else {
|
|
519
|
-
const localTracks = this.localStreamVideo?.getVideoTracks()[0];
|
|
520
|
-
this.clonedTrack = localTracks.clone();
|
|
521
|
-
this.clonedStream = new MediaStream([this.clonedTrack]);
|
|
522
|
-
this.segmentVideo = this.clonedStream;
|
|
523
|
-
}
|
|
524
|
-
this.updateSegmentVideo(this.segmentVideo);
|
|
525
|
-
refVideo.srcObject = this.segmentVideo;
|
|
526
|
-
if (refVideo.paused) {
|
|
527
|
-
refVideo.play();
|
|
528
|
-
}
|
|
529
|
-
refVideo.width = this.segmentVideo.getVideoTracks()[0].getSettings().width;
|
|
530
|
-
refVideo.height = this.segmentVideo.getVideoTracks()[0].getSettings().height;
|
|
531
|
-
mediaCanvas.width = refVideo.width;
|
|
532
|
-
mediaCanvas.height = refVideo.height;
|
|
533
|
-
ctx = mediaCanvas.getContext('2d');
|
|
534
|
-
try {
|
|
535
|
-
doSegmentation
|
|
536
|
-
? await segmentImage(refVideo)
|
|
537
|
-
: (previewVideo.srcObject = this.clonedStream
|
|
538
|
-
? this.clonedStream
|
|
539
|
-
: this.localStreamVideo);
|
|
540
|
-
}
|
|
541
|
-
catch (error) {
|
|
542
|
-
console.log('Error segmenting image:', error);
|
|
543
|
-
}
|
|
544
|
-
}
|
|
545
|
-
else {
|
|
546
|
-
if (this.segmentVideo && this.segmentVideo.getVideoTracks()[0].readyState == 'live') {
|
|
547
|
-
// Use existing segmentVideo
|
|
548
|
-
}
|
|
549
|
-
else {
|
|
550
|
-
try {
|
|
551
|
-
const stream = await navigator.mediaDevices.getUserMedia({
|
|
552
|
-
video: { ...this.vidCons, frameRate: { ideal: this.frameRate || 5 } },
|
|
553
|
-
audio: false,
|
|
554
|
-
});
|
|
555
|
-
this.segmentVideo = stream;
|
|
556
|
-
this.updateSegmentVideo(this.segmentVideo);
|
|
557
|
-
refVideo.srcObject = this.segmentVideo;
|
|
558
|
-
if (refVideo.paused) {
|
|
559
|
-
refVideo.play();
|
|
560
|
-
}
|
|
561
|
-
}
|
|
562
|
-
catch (error) {
|
|
563
|
-
console.log('Error getting user media:', error);
|
|
564
|
-
}
|
|
565
|
-
refVideo.width = this.segmentVideo.getVideoTracks()[0].getSettings().width;
|
|
566
|
-
refVideo.height = this.segmentVideo.getVideoTracks()[0].getSettings().height;
|
|
567
|
-
mediaCanvas.width = refVideo.width;
|
|
568
|
-
mediaCanvas.height = refVideo.height;
|
|
569
|
-
ctx = mediaCanvas.getContext('2d');
|
|
570
|
-
}
|
|
571
|
-
try {
|
|
572
|
-
doSegmentation
|
|
573
|
-
? await segmentImage(refVideo)
|
|
574
|
-
: (previewVideo.srcObject = refVideo.srcObject);
|
|
575
|
-
}
|
|
576
|
-
catch (error) {
|
|
577
|
-
console.log(error);
|
|
578
|
-
}
|
|
579
|
-
}
|
|
580
|
-
let repeatPattern = 'no-repeat';
|
|
581
|
-
try {
|
|
582
|
-
if (virtualImage.width < mediaCanvas.width || virtualImage.height < mediaCanvas.height) {
|
|
583
|
-
repeatPattern = 'repeat';
|
|
584
|
-
}
|
|
585
|
-
}
|
|
586
|
-
catch {
|
|
587
|
-
/* handle error */
|
|
588
|
-
}
|
|
589
|
-
const onResults = (results) => {
|
|
590
|
-
try {
|
|
591
|
-
if (!this.pauseSegmentation &&
|
|
592
|
-
mediaCanvas &&
|
|
593
|
-
mediaCanvas.width > 0 &&
|
|
594
|
-
mediaCanvas.height > 0 &&
|
|
595
|
-
virtualImage.width > 0 &&
|
|
596
|
-
virtualImage.height > 0) {
|
|
597
|
-
ctx.clearRect(0, 0, mediaCanvas.width, mediaCanvas.height);
|
|
598
|
-
ctx.drawImage(results.segmentationMask, 0, 0, mediaCanvas.width, mediaCanvas.height);
|
|
599
|
-
ctx.globalCompositeOperation = 'source-out';
|
|
600
|
-
const pat = ctx.createPattern(virtualImage, repeatPattern);
|
|
601
|
-
ctx.fillStyle = pat;
|
|
602
|
-
ctx.fillRect(0, 0, mediaCanvas.width, mediaCanvas.height);
|
|
603
|
-
ctx.globalCompositeOperation = 'destination-atop';
|
|
604
|
-
ctx.drawImage(results.image, 0, 0, mediaCanvas.width, mediaCanvas.height);
|
|
605
|
-
}
|
|
606
|
-
}
|
|
607
|
-
catch (error) {
|
|
608
|
-
console.log('Error processing results:', error);
|
|
609
|
-
}
|
|
610
|
-
};
|
|
611
|
-
if (!this.selfieSegmentation) {
|
|
612
|
-
await this.preloadModel().catch(() => console.log('Error preloading model:'));
|
|
613
|
-
}
|
|
614
|
-
try {
|
|
615
|
-
this.selfieSegmentation.onResults(onResults);
|
|
616
|
-
}
|
|
617
|
-
catch (error) {
|
|
618
|
-
console.log(error);
|
|
619
|
-
}
|
|
620
|
-
}
|
|
621
|
-
saveBackground = async () => {
|
|
622
|
-
if (this.audioOnlyRoom) {
|
|
623
|
-
this.parameters.showAlert?.({
|
|
624
|
-
message: 'You cannot use a background in an audio-only event.',
|
|
625
|
-
type: 'danger',
|
|
626
|
-
});
|
|
627
|
-
return;
|
|
628
|
-
}
|
|
629
|
-
if (this.backgroundHasChanged) {
|
|
630
|
-
if (this.videoAlreadyOn) {
|
|
631
|
-
if (this.islevel == '2' && (this.recordStarted || this.recordResumed)) {
|
|
632
|
-
if (!(this.recordPaused || this.recordStopped)) {
|
|
633
|
-
if (this.recordingMediaOptions == 'video') {
|
|
634
|
-
this.parameters.showAlert?.({
|
|
635
|
-
message: 'Please pause the recording before changing the background.',
|
|
636
|
-
type: 'danger',
|
|
637
|
-
});
|
|
638
|
-
return;
|
|
639
|
-
}
|
|
640
|
-
}
|
|
641
|
-
}
|
|
642
|
-
if (this.keepBackground && this.selectedImage && this.processedStream) {
|
|
643
|
-
this.virtualStream = this.processedStream;
|
|
644
|
-
this.updateVirtualStream(this.virtualStream);
|
|
645
|
-
this.videoParams = { track: this.virtualStream.getVideoTracks()[0] };
|
|
646
|
-
this.updateVideoParams(this.videoParams);
|
|
647
|
-
}
|
|
648
|
-
else {
|
|
649
|
-
if (this.localStreamVideo?.getVideoTracks()[0].readyState == 'live') {
|
|
650
|
-
this.videoParams = { track: this.localStreamVideo.getVideoTracks()[0] };
|
|
651
|
-
this.updateVideoParams(this.videoParams);
|
|
652
|
-
}
|
|
653
|
-
else {
|
|
654
|
-
try {
|
|
655
|
-
if (this.localStreamVideo?.getVideoTracks()[0].readyState !== 'live') {
|
|
656
|
-
this.localStreamVideo?.removeTrack(this.localStreamVideo.getVideoTracks()[0]);
|
|
657
|
-
this.localStreamVideo?.addTrack(this.segmentVideo.getVideoTracks()[0].clone());
|
|
658
|
-
}
|
|
659
|
-
}
|
|
660
|
-
catch (error) {
|
|
661
|
-
console.log('Error handling local stream video:', error);
|
|
662
|
-
}
|
|
663
|
-
this.videoParams = { track: this.segmentVideo.getVideoTracks()[0] };
|
|
664
|
-
this.updateVideoParams(this.videoParams);
|
|
665
|
-
}
|
|
666
|
-
}
|
|
667
|
-
if (this.keepBackground) {
|
|
668
|
-
this.appliedBackground = true;
|
|
669
|
-
this.updateAppliedBackground(this.appliedBackground);
|
|
670
|
-
}
|
|
671
|
-
else {
|
|
672
|
-
this.appliedBackground = false;
|
|
673
|
-
this.updateAppliedBackground(this.appliedBackground);
|
|
674
|
-
}
|
|
675
|
-
if (!this.parameters.transportCreated) {
|
|
676
|
-
await this.createSendTransport({
|
|
677
|
-
option: 'video',
|
|
678
|
-
parameters: { ...this.parameters, videoParams: this.videoParams },
|
|
679
|
-
});
|
|
680
|
-
}
|
|
681
|
-
else {
|
|
682
|
-
try {
|
|
683
|
-
if (this.parameters.videoProducer?.id &&
|
|
684
|
-
this.parameters.videoProducer.track?.id !== this.videoParams?.track?.id) {
|
|
685
|
-
await this.disconnectSendTransportVideo({ parameters: this.parameters });
|
|
686
|
-
await this.sleep({ ms: 500 });
|
|
687
|
-
}
|
|
688
|
-
await this.connectSendTransportVideo({
|
|
689
|
-
videoParams: this.videoParams,
|
|
690
|
-
parameters: this.parameters,
|
|
691
|
-
});
|
|
692
|
-
}
|
|
693
|
-
catch (error) {
|
|
694
|
-
console.log(error);
|
|
695
|
-
}
|
|
696
|
-
}
|
|
697
|
-
await this.onScreenChanges({ changed: true, parameters: this.parameters });
|
|
698
|
-
}
|
|
699
|
-
}
|
|
700
|
-
if (this.keepBackground) {
|
|
701
|
-
this.appliedBackground = true;
|
|
702
|
-
this.updateAppliedBackground(this.appliedBackground);
|
|
703
|
-
}
|
|
704
|
-
else {
|
|
705
|
-
this.appliedBackground = false;
|
|
706
|
-
this.updateAppliedBackground(this.appliedBackground);
|
|
707
|
-
}
|
|
708
|
-
this.saveBackgroundButtonRef.nativeElement.classList.add('d-none');
|
|
709
|
-
this.saveBackgroundButtonRef.nativeElement.disabled = true;
|
|
710
|
-
};
|
|
711
|
-
handleModalClose = () => {
|
|
712
|
-
try {
|
|
713
|
-
// If no background is applied or the applied background should not be kept
|
|
714
|
-
if (!this.appliedBackground ||
|
|
715
|
-
(this.appliedBackground && !this.keepBackground) ||
|
|
716
|
-
(this.appliedBackground && !this.videoAlreadyOn)) {
|
|
717
|
-
console.log('No background applied or applied background should not be kept');
|
|
718
|
-
const refVideo = this.captureVideoRef.nativeElement;
|
|
719
|
-
this.pauseSegmentation = true;
|
|
720
|
-
this.updatePauseSegmentation(this.pauseSegmentation);
|
|
721
|
-
if (!this.videoAlreadyOn) {
|
|
722
|
-
// Stop video tracks and clear the video element's srcObject
|
|
723
|
-
if (refVideo && refVideo.srcObject) {
|
|
724
|
-
refVideo.srcObject.getTracks().forEach((track) => track.stop());
|
|
725
|
-
refVideo.srcObject = null;
|
|
726
|
-
}
|
|
727
|
-
// Stop segmentVideo tracks
|
|
728
|
-
if (this.segmentVideo) {
|
|
729
|
-
this.segmentVideo.getTracks().forEach((track) => track.stop());
|
|
730
|
-
this.segmentVideo = null;
|
|
731
|
-
this.updateSegmentVideo(this.segmentVideo);
|
|
732
|
-
}
|
|
733
|
-
// Stop virtualStream tracks
|
|
734
|
-
if (this.virtualStream) {
|
|
735
|
-
this.virtualStream.getTracks().forEach((track) => track.stop());
|
|
736
|
-
this.virtualStream = null;
|
|
737
|
-
this.updateVirtualStream(this.virtualStream);
|
|
738
|
-
}
|
|
739
|
-
}
|
|
740
|
-
}
|
|
741
|
-
// Hide the video preview and show the canvas
|
|
742
|
-
this.videoPreviewRef.nativeElement.classList.add('d-none');
|
|
743
|
-
this.backgroundCanvasRef.nativeElement.classList.remove('d-none');
|
|
744
|
-
// Hide the modal
|
|
745
|
-
// this.isVisible = false;
|
|
746
|
-
this.onClose();
|
|
747
|
-
}
|
|
748
|
-
catch (error) {
|
|
749
|
-
console.log('Error during modal close:', error);
|
|
750
|
-
}
|
|
751
|
-
};
|
|
752
|
-
showLoading() {
|
|
753
|
-
this.loadingOverlayRef.nativeElement.classList.remove('d-none');
|
|
754
|
-
}
|
|
755
|
-
hideLoading() {
|
|
756
|
-
this.loadingOverlayRef.nativeElement.classList.add('d-none');
|
|
757
|
-
}
|
|
758
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.8", ngImport: i0, type: BackgroundModal, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
759
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.8", type: BackgroundModal, isStandalone: true, selector: "app-background-modal", inputs: { isVisible: "isVisible", parameters: "parameters", position: "position", backgroundColor: "backgroundColor", onClose: "onClose" }, viewQueries: [{ propertyName: "defaultImagesContainerRef", first: true, predicate: ["defaultImagesContainer"], descendants: true }, { propertyName: "uploadImageInputRef", first: true, predicate: ["uploadImageInput"], descendants: true }, { propertyName: "backgroundCanvasRef", first: true, predicate: ["backgroundCanvas"], descendants: true }, { propertyName: "videoPreviewRef", first: true, predicate: ["videoPreview"], descendants: true }, { propertyName: "captureVideoRef", first: true, predicate: ["captureVideo"], descendants: true }, { propertyName: "loadingOverlayRef", first: true, predicate: ["loadingOverlay"], descendants: true }, { propertyName: "applyBackgroundButtonRef", first: true, predicate: ["applyBackgroundButton"], descendants: true }, { propertyName: "saveBackgroundButtonRef", first: true, predicate: ["saveBackgroundButton"], descendants: true }], usesOnChanges: true, ngImport: i0, template: "<div [ngStyle]=\"{ position: 'fixed', top: 0, left: 0, width: '100%', height: '100%', backgroundColor: 'rgba(0, 0, 0, 0.5)', display: isVisible ? 'block' : 'none', zIndex: 999 }\">\r\n <div [ngStyle]=\"{ position: 'fixed', backgroundColor: backgroundColor, borderRadius: '10px', padding: '10px', width: '80%', maxWidth: '500px', maxHeight: '75%', overflowY: 'auto', overflowX: 'hidden', top: position.includes('top') ? '10px' : 'auto', bottom: position.includes('bottom') ? '10px' : 'auto', left: position.includes('Left') ? '10px' : 'auto', right: position.includes('Right') ? '10px' : 'auto' }\">\r\n <div style=\"display: flex; justify-content: space-between; align-items: center; margin-bottom: 15px;\">\r\n <h2 style=\"font-size: x-large; font-weight: bold; color: black;\">Background Settings</h2>\r\n <button (click)=\"onClose()\" style=\"border: none; background: none; cursor: pointer;\">\r\n <fa-icon [icon]=\"faTimes\" size=\"xl\" style=\"font-size: 20px; color: black;\"></fa-icon>\r\n </button>\r\n </div>\r\n <hr style=\"height: 1px; background-color: black; margin-top: 5px; margin-bottom: 5px;\" />\r\n <div style=\"max-width: 95%; overflow-x: auto;\">\r\n <div id=\"defaultImages\" #defaultImagesContainer></div>\r\n <div class=\"form-group\" style=\"max-width: 70%; overflow-x: auto;\">\r\n <label for=\"uploadImage\">Upload Custom Image</label>\r\n <input type=\"file\" class=\"form-control\" id=\"uploadImage\" #uploadImageInput (change)=\"handleImageUpload($event)\" />\r\n </div>\r\n <canvas id=\"mainCanvas\" #mainCanvas class=\"d-none\"></canvas>\r\n <canvas id=\"backgroundCanvas\" #backgroundCanvas class=\"d-none\" style=\"width: 100%; max-width: 400px; height: auto; background-color: transparent; border: 1px solid black;\"></canvas>\r\n <video id=\"captureVideo\" #captureVideo class=\"d-none\" muted autoplay playsinline></video>\r\n <video id=\"previewVideo\" #videoPreview class=\"d-none\" muted autoplay playsinline style=\"width: 100%; max-width: 400px; height: auto; background-color: transparent; border: 1px solid black;\"></video>\r\n <div id=\"loadingOverlay\" #loadingOverlay class=\"d-none\" [ngStyle]=\"{ position: 'absolute', top: 0, left: 0, width: '100%', height: '100%', backgroundColor: 'rgba(0, 0, 0, 0.5)', display: 'flex', 'justify-content': 'center', 'align-items': 'center', zIndex: 1000 }\">\r\n <div [ngStyle]=\"{ width: '50px', height: '50px', border: '5px solid rgba(255, 255, 255, 0.3)', borderRadius: '50%', borderTop: '5px solid white', animation: 'spin 1s linear infinite' }\"></div>\r\n </div>\r\n <br />\r\n <button id=\"applyBackgroundButton\" #applyBackgroundButton class=\"btn btn-primary\" (click)=\"applyBackground()\">Preview Background</button>\r\n <button id=\"saveBackgroundButton\" #saveBackgroundButton class=\"btn btn-success d-none\" (click)=\"saveBackground()\">Save Background</button>\r\n </div>\r\n </div>\r\n </div>\r\n", styles: ["@keyframes spin{0%{transform:rotate(0)}to{transform:rotate(360deg)}}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "ngmodule", type: FontAwesomeModule }, { kind: "component", type: i2.FaIconComponent, selector: "fa-icon", inputs: ["icon", "title", "animation", "mask", "flip", "size", "pull", "border", "inverse", "symbol", "rotate", "fixedWidth", "transform", "a11yRole"] }] });
|
|
760
|
-
}
|
|
761
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.8", ngImport: i0, type: BackgroundModal, decorators: [{
|
|
762
|
-
type: Component,
|
|
763
|
-
args: [{ selector: 'app-background-modal', standalone: true, imports: [CommonModule, FontAwesomeModule], template: "<div [ngStyle]=\"{ position: 'fixed', top: 0, left: 0, width: '100%', height: '100%', backgroundColor: 'rgba(0, 0, 0, 0.5)', display: isVisible ? 'block' : 'none', zIndex: 999 }\">\r\n <div [ngStyle]=\"{ position: 'fixed', backgroundColor: backgroundColor, borderRadius: '10px', padding: '10px', width: '80%', maxWidth: '500px', maxHeight: '75%', overflowY: 'auto', overflowX: 'hidden', top: position.includes('top') ? '10px' : 'auto', bottom: position.includes('bottom') ? '10px' : 'auto', left: position.includes('Left') ? '10px' : 'auto', right: position.includes('Right') ? '10px' : 'auto' }\">\r\n <div style=\"display: flex; justify-content: space-between; align-items: center; margin-bottom: 15px;\">\r\n <h2 style=\"font-size: x-large; font-weight: bold; color: black;\">Background Settings</h2>\r\n <button (click)=\"onClose()\" style=\"border: none; background: none; cursor: pointer;\">\r\n <fa-icon [icon]=\"faTimes\" size=\"xl\" style=\"font-size: 20px; color: black;\"></fa-icon>\r\n </button>\r\n </div>\r\n <hr style=\"height: 1px; background-color: black; margin-top: 5px; margin-bottom: 5px;\" />\r\n <div style=\"max-width: 95%; overflow-x: auto;\">\r\n <div id=\"defaultImages\" #defaultImagesContainer></div>\r\n <div class=\"form-group\" style=\"max-width: 70%; overflow-x: auto;\">\r\n <label for=\"uploadImage\">Upload Custom Image</label>\r\n <input type=\"file\" class=\"form-control\" id=\"uploadImage\" #uploadImageInput (change)=\"handleImageUpload($event)\" />\r\n </div>\r\n <canvas id=\"mainCanvas\" #mainCanvas class=\"d-none\"></canvas>\r\n <canvas id=\"backgroundCanvas\" #backgroundCanvas class=\"d-none\" style=\"width: 100%; max-width: 400px; height: auto; background-color: transparent; border: 1px solid black;\"></canvas>\r\n <video id=\"captureVideo\" #captureVideo class=\"d-none\" muted autoplay playsinline></video>\r\n <video id=\"previewVideo\" #videoPreview class=\"d-none\" muted autoplay playsinline style=\"width: 100%; max-width: 400px; height: auto; background-color: transparent; border: 1px solid black;\"></video>\r\n <div id=\"loadingOverlay\" #loadingOverlay class=\"d-none\" [ngStyle]=\"{ position: 'absolute', top: 0, left: 0, width: '100%', height: '100%', backgroundColor: 'rgba(0, 0, 0, 0.5)', display: 'flex', 'justify-content': 'center', 'align-items': 'center', zIndex: 1000 }\">\r\n <div [ngStyle]=\"{ width: '50px', height: '50px', border: '5px solid rgba(255, 255, 255, 0.3)', borderRadius: '50%', borderTop: '5px solid white', animation: 'spin 1s linear infinite' }\"></div>\r\n </div>\r\n <br />\r\n <button id=\"applyBackgroundButton\" #applyBackgroundButton class=\"btn btn-primary\" (click)=\"applyBackground()\">Preview Background</button>\r\n <button id=\"saveBackgroundButton\" #saveBackgroundButton class=\"btn btn-success d-none\" (click)=\"saveBackground()\">Save Background</button>\r\n </div>\r\n </div>\r\n </div>\r\n", styles: ["@keyframes spin{0%{transform:rotate(0)}to{transform:rotate(360deg)}}\n"] }]
|
|
764
|
-
}], propDecorators: { isVisible: [{
|
|
765
|
-
type: Input
|
|
766
|
-
}], parameters: [{
|
|
767
|
-
type: Input
|
|
768
|
-
}], position: [{
|
|
769
|
-
type: Input
|
|
770
|
-
}], backgroundColor: [{
|
|
771
|
-
type: Input
|
|
772
|
-
}], onClose: [{
|
|
773
|
-
type: Input
|
|
774
|
-
}], defaultImagesContainerRef: [{
|
|
775
|
-
type: ViewChild,
|
|
776
|
-
args: ['defaultImagesContainer']
|
|
777
|
-
}], uploadImageInputRef: [{
|
|
778
|
-
type: ViewChild,
|
|
779
|
-
args: ['uploadImageInput']
|
|
780
|
-
}], backgroundCanvasRef: [{
|
|
781
|
-
type: ViewChild,
|
|
782
|
-
args: ['backgroundCanvas']
|
|
783
|
-
}], videoPreviewRef: [{
|
|
784
|
-
type: ViewChild,
|
|
785
|
-
args: ['videoPreview']
|
|
786
|
-
}], captureVideoRef: [{
|
|
787
|
-
type: ViewChild,
|
|
788
|
-
args: ['captureVideo']
|
|
789
|
-
}], loadingOverlayRef: [{
|
|
790
|
-
type: ViewChild,
|
|
791
|
-
args: ['loadingOverlay']
|
|
792
|
-
}], applyBackgroundButtonRef: [{
|
|
793
|
-
type: ViewChild,
|
|
794
|
-
args: ['applyBackgroundButton']
|
|
795
|
-
}], saveBackgroundButtonRef: [{
|
|
796
|
-
type: ViewChild,
|
|
797
|
-
args: ['saveBackgroundButton']
|
|
798
|
-
}] } });
|
|
799
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYmFja2dyb3VuZC1tb2RhbC5jb21wb25lbnQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi8uLi9wcm9qZWN0cy9tZWRpYXNmdS1hbmd1bGFyL3NyYy9saWIvY29tcG9uZW50cy9iYWNrZ3JvdW5kLWNvbXBvbmVudHMvYmFja2dyb3VuZC1tb2RhbC9iYWNrZ3JvdW5kLW1vZGFsLmNvbXBvbmVudC50cyIsIi4uLy4uLy4uLy4uLy4uLy4uLy4uL3Byb2plY3RzL21lZGlhc2Z1LWFuZ3VsYXIvc3JjL2xpYi9jb21wb25lbnRzL2JhY2tncm91bmQtY29tcG9uZW50cy9iYWNrZ3JvdW5kLW1vZGFsL2JhY2tncm91bmQtbW9kYWwuY29tcG9uZW50Lmh0bWwiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsNkRBQTZEO0FBQzdELE9BQU8sRUFDTCxTQUFTLEVBQ1QsS0FBSyxFQUdMLFNBQVMsR0FHVixNQUFNLGVBQWUsQ0FBQztBQUN2QixPQUFPLEVBQUUsWUFBWSxFQUFFLE1BQU0saUJBQWlCLENBQUM7QUFDL0MsT0FBTyxFQUFFLGlCQUFpQixFQUFFLE1BQU0sa0NBQWtDLENBQUM7QUFDckUsT0FBTyxFQUFFLE9BQU8sRUFBRSxNQUFNLG1DQUFtQyxDQUFDO0FBQzVELE9BQU8sRUFBRSxrQkFBa0IsRUFBRSxNQUFNLGdDQUFnQyxDQUFDOzs7O0FBdUZwRTs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7R0FtQ0c7QUFVSCxNQUFNLE9BQU8sZUFBZTtJQUNqQixTQUFTLEdBQUcsS0FBSyxDQUFDO0lBQ2xCLFVBQVUsR0FBOEIsRUFBK0IsQ0FBQztJQUN4RSxRQUFRLEdBQUcsU0FBUyxDQUFDO0lBQ3JCLGVBQWUsR0FBRyxTQUFTLENBQUM7SUFDNUIsT0FBTyxHQUFlLEdBQUcsRUFBRTtRQUNsQyxPQUFPLENBQUMsR0FBRyxDQUFDLFNBQVMsQ0FBQyxDQUFDO0lBQ3pCLENBQUMsQ0FBQztJQUVtQyx5QkFBeUIs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LFlBQVksbUhBQUUsaUJBQWlCOzsyRkFJOUIsZUFBZTtrQkFQM0IsU0FBUzsrQkFDRSxzQkFBc0IsY0FDcEIsSUFBSSxXQUNQLENBQUMsWUFBWSxFQUFFLGlCQUFpQixDQUFDOzhCQUtqQyxTQUFTO3NCQUFqQixLQUFLO2dCQUNHLFVBQVU7c0JBQWxCLEtBQUs7Z0JBQ0csUUFBUTtzQkFBaEIsS0FBSztnQkFDRyxlQUFlO3NCQUF2QixLQUFLO2dCQUNHLE9BQU87c0JBQWYsS0FBSztnQkFJK0IseUJBQXlCO3NCQUE3RCxTQUFTO3VCQUFDLHdCQUF3QjtnQkFDSixtQkFBbUI7c0JBQWpELFNBQVM7dUJBQUMsa0JBQWtCO2dCQUNFLG1CQUFtQjtzQkFBakQsU0FBUzt1QkFBQyxrQkFBa0I7Z0JBQ0YsZUFBZTtzQkFBekMsU0FBUzt1QkFBQyxjQUFjO2dCQUNFLGVBQWU7c0JBQXpDLFNBQVM7dUJBQUMsY0FBYztnQkFDSSxpQkFBaUI7c0JBQTdDLFNBQVM7dUJBQUMsZ0JBQWdCO2dCQUNTLHdCQUF3QjtzQkFBM0QsU0FBUzt1QkFBQyx1QkFBdUI7Z0JBQ0MsdUJBQXVCO3NCQUF6RCxTQUFTO3VCQUFDLHNCQUFzQiIsInNvdXJjZXNDb250ZW50IjpbIi8qIGVzbGludC1kaXNhYmxlIEB0eXBlc2NyaXB0LWVzbGludC9uby1ub24tbnVsbC1hc3NlcnRpb24gKi9cbmltcG9ydCB7XG4gIENvbXBvbmVudCxcbiAgSW5wdXQsXG4gIE9uQ2hhbmdlcyxcbiAgU2ltcGxlQ2hhbmdlcyxcbiAgVmlld0NoaWxkLFxuICBFbGVtZW50UmVmLFxuICBPbkluaXQsXG59IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHsgQ29tbW9uTW9kdWxlIH0gZnJvbSAnQGFuZ3VsYXIvY29tbW9uJztcbmltcG9ydCB7IEZvbnRBd2Vzb21lTW9kdWxlIH0gZnJvbSAnQGZvcnRhd2Vzb21lL2FuZ3VsYXItZm9udGF3ZXNvbWUnO1xuaW1wb3J0IHsgZmFUaW1lcyB9IGZyb20gJ0Bmb3J0YXdlc29tZS9mcmVlLXNvbGlkLXN2Zy1pY29ucyc7XG5pbXBvcnQgeyBTZWxmaWVTZWdtZW50YXRpb24gfSBmcm9tICdAbWVkaWFwaXBlL3NlbGZpZV9zZWdtZW50YXRpb24nO1xuaW1wb3J0IHtcbiAgQ29ubmVjdFNlbmRUcmFuc3BvcnRWaWRlb1BhcmFtZXRlcnMsXG4gIENvbm5lY3RTZW5kVHJhbnNwb3J0VmlkZW9UeXBlLFxuICBDcmVhdGVTZW5kVHJhbnNwb3J0UGFyYW1ldGVycyxcbiAgQ3JlYXRlU2VuZFRyYW5zcG9ydFR5cGUsXG4gIERpc2Nvbm5lY3RTZW5kVHJhbnNwb3J0VmlkZW9QYXJhbWV0ZXJzLFxuICBEaXNjb25uZWN0U2VuZFRyYW5zcG9ydFZpZGVvVHlwZSxcbiAgT25TY3JlZW5DaGFuZ2VzUGFyYW1ldGVycyxcbiAgT25TY3JlZW5DaGFuZ2VzVHlwZSxcbiAgU2hvd0FsZXJ0LFxuICBTbGVlcFR5cGUsXG4gIFZpZENvbnMsXG59IGZyb20gJy4uLy4uLy4uL0B0eXBlcy90eXBlcyc7XG5pbXBvcnQgeyBQcm9kdWNlciwgUHJvZHVjZXJPcHRpb25zIH0gZnJvbSAnbWVkaWFzb3VwLWNsaWVudC9saWIvdHlwZXMnO1xuXG5leHBvcnQgaW50ZXJmYWNlIEJhY2tncm91bmRNb2RhbFBhcmFtZXRlcnNcbiAgZXh0ZW5kcyBDcmVhdGVTZW5kVHJhbnNwb3J0UGFyYW1ldGVycyxcbiAgICBDb25uZWN0U2VuZFRyYW5zcG9ydFZpZGVvUGFyYW1ldGVycyxcbiAgICBEaXNjb25uZWN0U2VuZFRyYW5zcG9ydFZpZGVvUGFyYW1ldGVycyxcbiAgICBPblNjcmVlbkNoYW5nZXNQYXJhbWV0ZXJzIHtcbiAgY3VzdG9tSW1hZ2U6IHN0cmluZztcbiAgc2VsZWN0ZWRJbWFnZTogc3RyaW5nO1xuICBzZWdtZW50VmlkZW86IE1lZGlhU3RyZWFtIHwgbnVsbDtcbiAgc2VsZmllU2VnbWVudGF0aW9uOiBTZWxmaWVTZWdtZW50YXRpb24gfCBudWxsO1xuICBwYXVzZVNlZ21lbnRhdGlvbjogYm9vbGVhbjtcbiAgcHJvY2Vzc2VkU3RyZWFtOiBNZWRpYVN0cmVhbSB8IG51bGw7XG4gIGtlZXBCYWNrZ3JvdW5kOiBib29sZWFuO1xuICBiYWNrZ3JvdW5kSGFzQ2hhbmdlZDogYm9vbGVhbjtcbiAgdmlydHVhbFN0cmVhbTogTWVkaWFTdHJlYW0gfCBudWxsO1xuICBtYWluQ2FudmFzOiBIVE1MQ2FudmFzRWxlbWVudCB8IG51bGw7XG4gIHByZXZLZWVwQmFja2dyb3VuZDogYm9vbGVhbjtcbiAgYXBwbGllZEJhY2tncm91bmQ6IGJvb2xlYW47XG4gIHZpZGVvQWxyZWFkeU9uOiBib29sZWFuO1xuICBhdWRpb09ubHlSb29tOiBib29sZWFuO1xuICBpc2xldmVsOiBzdHJpbmc7XG4gIHJlY29yZFN0YXJ0ZWQ6IGJvb2xlYW47XG4gIHJlY29yZFJlc3VtZWQ6IGJvb2xlYW47XG4gIHJlY29yZFBhdXNlZDogYm9vbGVhbjtcbiAgcmVjb3JkU3RvcHBlZDogYm9vbGVhbjtcbiAgcmVjb3JkaW5nTWVkaWFPcHRpb25zOiBzdHJpbmc7XG4gIHNob3dBbGVydD86IFNob3dBbGVydDtcbiAgbG9jYWxTdHJlYW1WaWRlbzogTWVkaWFTdHJlYW0gfCBudWxsO1xuICB2aWRDb25zOiBWaWRDb25zO1xuICBmcmFtZVJhdGU6IG51bWJlcjtcbiAgdGFyZ2V0UmVzb2x1dGlvbjogc3RyaW5nO1xuICB1cGRhdGVDdXN0b21JbWFnZTogKGltYWdlOiBzdHJpbmcpID0+IHZvaWQ7XG4gIHVwZGF0ZVNlbGVjdGVkSW1hZ2U6IChpbWFnZTogc3RyaW5nKSA9PiB2b2lkO1xuICB1cGRhdGVTZWdtZW50VmlkZW86IChzdHJlYW06IE1lZGlhU3RyZWFtIHwgbnVsbCkgPT4gdm9pZDtcbiAgdXBkYXRlU2VsZmllU2VnbWVudGF0aW9uOiAoc2VnbWVudGF0aW9uOiBTZWxmaWVTZWdtZW50YXRpb24gfCBudWxsKSA9PiB2b2lkO1xuICB1cGRhdGVQYXVzZVNlZ21lbnRhdGlvbjogKHBhdXNlOiBib29sZWFuKSA9PiB2b2lkO1xuICB1cGRhdGVQcm9jZXNzZWRTdHJlYW06IChzdHJlYW06IE1lZGlhU3RyZWFtIHwgbnVsbCkgPT4gdm9pZDtcbiAgdXBkYXRlS2VlcEJhY2tncm91bmQ6IChrZWVwOiBib29sZWFuKSA9PiB2b2lkO1xuICB1cGRhdGVCYWNrZ3JvdW5kSGFzQ2hhbmdlZDogKGNoYW5nZWQ6IGJvb2xlYW4pID0+IHZvaWQ7XG4gIHVwZGF0ZVZpcnR1YWxTdHJlYW06IChzdHJlYW06IE1lZGlhU3RyZWFtIHwgbnVsbCkgPT4gdm9pZDtcbiAgdXBkYXRlUHJldktlZXBCYWNrZ3JvdW5kOiAocHJldjogYm9vbGVhbikgPT4gdm9pZDtcbiAgdXBkYXRlQXBwbGllZEJhY2tncm91bmQ6IChhcHBsaWVkOiBib29sZWFuKSA9PiB2b2lkO1xuICB2aWRlb1Byb2R1Y2VyOiBQcm9kdWNlciB8IG51bGw7XG4gIHRyYW5zcG9ydENyZWF0ZWQ6IGJvb2xlYW47XG4gIHZpZGVvUGFyYW1zOiBQcm9kdWNlck9wdGlvbnM7XG4gIHVwZGF0ZVZpZGVvUGFyYW1zOiAocGFyYW1zOiBQcm9kdWNlck9wdGlvbnMpID0+IHZvaWQ7XG4gIGF1dG9DbGlja0JhY2tncm91bmQ6IGJvb2xlYW47XG4gIHVwZGF0ZUF1dG9DbGlja0JhY2tncm91bmQ6IChhdXRvQ2xpY2s6IGJvb2xlYW4pID0+IHZvaWQ7XG4gIHVwZGF0ZU1haW5DYW52YXM6IChjYW52YXM6IEhUTUxDYW52YXNFbGVtZW50KSA9PiB2b2lkO1xuXG4gIC8vIG1lZGlhc2Z1IGZ1bmN0aW9uc1xuICBjcmVhdGVTZW5kVHJhbnNwb3J0OiBDcmVhdGVTZW5kVHJhbnNwb3J0VHlwZTtcbiAgY29ubmVjdFNlbmRUcmFuc3BvcnRWaWRlbzogQ29ubmVjdFNlbmRUcmFuc3BvcnRWaWRlb1R5cGU7XG4gIGRpc2Nvbm5lY3RTZW5kVHJhbnNwb3J0VmlkZW86IERpc2Nvbm5lY3RTZW5kVHJhbnNwb3J0VmlkZW9UeXBlO1xuICBvblNjcmVlbkNoYW5nZXM6IE9uU2NyZWVuQ2hhbmdlc1R5cGU7XG4gIHNsZWVwOiBTbGVlcFR5cGU7XG5cbiAgZ2V0VXBkYXRlZEFsbFBhcmFtczogKCkgPT4gQmFja2dyb3VuZE1vZGFsUGFyYW1ldGVycztcbiAgW2tleTogc3RyaW5nXTogYW55O1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIEJhY2tncm91bmRNb2RhbE9wdGlvbnMge1xuICBpc1Zpc2libGU6IGJvb2xlYW47XG4gIHBhcmFtZXRlcnM6IEJhY2tncm91bmRNb2RhbFBhcmFtZXRlcnM7XG4gIHBvc2l0aW9uOiBzdHJpbmc7XG4gIGJhY2tncm91bmRDb2xvcjogc3RyaW5nO1xuICBvbkNsb3NlOiAoKSA9PiB2b2lkO1xufVxuXG4vLyBleHBvcnQgdGhlIHR5cGUgZGVmaW5pdGlvbiBmb3IgdGhlIGNvbXBvbmVudFxuZXhwb3J0IHR5cGUgQmFja2dyb3VuZE1vZGFsVHlwZSA9IChvcHRpb25zOiBCYWNrZ3JvdW5kTW9kYWxPcHRpb25zKSA9PiBIVE1MRWxlbWVudDtcblxuLyoqXG4gKiBCYWNrZ3JvdW5kTW9kYWwgLSBDb21wb25lbnQgdG8gbWFuYWdlIGJhY2tncm91bmQgc2VsZWN0aW9uIGFuZCBtYW5pcHVsYXRpb24gaW4gbWVkaWEgc3RyZWFtcy5cbiAqXG4gKiBUaGlzIGNvbXBvbmVudCBhbGxvd3MgdXNlcnMgdG8gY2hvb3NlLCBhcHBseSwgYW5kIG1hbmlwdWxhdGUgdmlydHVhbCBiYWNrZ3JvdW5kcyBmb3IgbWVkaWEgc3RyZWFtcywgbGV2ZXJhZ2luZyBNZWRpYVBpcGXigJlzIFNlbGZpZSBTZWdtZW50YXRpb24gYW5kIE1lZGlhU291cCBmdW5jdGlvbmFsaXRpZXMuXG4gKlxuICogQGNvbXBvbmVudFxuICogQG5hbWUgQmFja2dyb3VuZE1vZGFsXG4gKiBAZXhhbXBsZVxuICogYGBgdHlwZXNjcmlwdFxuICogPGFwcC1iYWNrZ3JvdW5kLW1vZGFsXG4gKiAgIFtpc1Zpc2libGVdPVwiaXNNb2RhbFZpc2libGVcIlxuICogICBbcGFyYW1ldGVyc109XCJtb2RhbFBhcmFtZXRlcnNcIlxuICogICBwb3NpdGlvbj1cInRvcExlZnRcIlxuICogICBiYWNrZ3JvdW5kQ29sb3I9XCIjZjVmNWY1XCJcbiAqICAgKG9uQ2xvc2UpPVwiaGFuZGxlTW9kYWxDbG9zZSgpXCJcbiAqID48L2FwcC1iYWNrZ3JvdW5kLW1vZGFsPlxuICogYGBgXG4gKlxuICogQHBhcmFtIHtib29sZWFufSBpc1Zpc2libGUgLSBWaXNpYmlsaXR5IHN0YXRlIG9mIHRoZSBtb2RhbC5cbiAqIEBwYXJhbSB7QmFja2dyb3VuZE1vZGFsUGFyYW1ldGVyc30gcGFyYW1ldGVycyAtIFBhcmFtZXRlcnMgaW5jbHVkaW5nIHNldHRpbmdzIGFuZCBtZXRob2RzIGZvciBtZWRpYSBhbmQgYmFja2dyb3VuZCBtYW5hZ2VtZW50LlxuICogQHBhcmFtIHtzdHJpbmd9IHBvc2l0aW9uIC0gVGhlIHBvc2l0aW9uIG9mIHRoZSBtb2RhbCwgZS5nLiwgJ3RvcExlZnQnLlxuICogQHBhcmFtIHtzdHJpbmd9IGJhY2tncm91bmRDb2xvciAtIEJhY2tncm91bmQgY29sb3Igb2YgdGhlIG1vZGFsLlxuICogQHBhcmFtIHtGdW5jdGlvbn0gb25DbG9zZSAtIENhbGxiYWNrIGZ1bmN0aW9uIHdoZW4gdGhlIG1vZGFsIGlzIGNsb3NlZC5cbiAqXG4gKiBAcHJvcGVydHkge2ZhVGltZXN9IGZhVGltZXMgLSBJY29uIHVzZWQgZm9yIGNsb3NpbmcgdGhlIG1vZGFsLlxuICogQHByb3BlcnR5IHtzdHJpbmd9IGN1c3RvbUltYWdlIC0gQ3VzdG9tIGltYWdlIFVSTCBmb3IgYmFja2dyb3VuZC5cbiAqIEBwcm9wZXJ0eSB7c3RyaW5nfSBzZWxlY3RlZEltYWdlIC0gU2VsZWN0ZWQgaW1hZ2UgVVJMIGZvciBiYWNrZ3JvdW5kLlxuICogQHByb3BlcnR5IHtNZWRpYVN0cmVhbSB8IG51bGx9IHNlZ21lbnRWaWRlbyAtIE1lZGlhIHN0cmVhbSBmb3IgdmlkZW8gc2VnbWVudGF0aW9uLlxuICogQHByb3BlcnR5IHtTZWxmaWVTZWdtZW50YXRpb24gfCBudWxsfSBzZWxmaWVTZWdtZW50YXRpb24gLSBTZWxmaWVTZWdtZW50YXRpb24gaW5zdGFuY2UuXG4gKiBAcHJvcGVydHkge2Jvb2xlYW59IHBhdXNlU2VnbWVudGF0aW9uIC0gUGF1c2Ugc3RhdGUgZm9yIHNlZ21lbnRhdGlvbi5cbiAqIEBwcm9wZXJ0eSB7TWVkaWFTdHJlYW0gfCBudWxsfSBwcm9jZXNzZWRTdHJlYW0gLSBQcm9jZXNzZWQgbWVkaWEgc3RyZWFtIHdpdGggYXBwbGllZCBiYWNrZ3JvdW5kLlxuICogQHByb3BlcnR5IHtib29sZWFufSBrZWVwQmFja2dyb3VuZCAtIFN0YXRlIHRvIGtlZXAgb3IgcmVzZXQgYmFja2dyb3VuZC5cbiAqXG4gKiBAbWV0aG9kXG4gKiBuZ09uSW5pdCAtIEluaXRpYWxpemVzIHRoZSBtb2RhbCBjb21wb25lbnQgYnkgdXBkYXRpbmcgcHJvcGVydGllcyBiYXNlZCBvbiBwYXJhbWV0ZXJzLlxuICovXG5cblxuQENvbXBvbmVudCh7XG4gIHNlbGVjdG9yOiAnYXBwLWJhY2tncm91bmQtbW9kYWwnLFxuICBzdGFuZGFsb25lOiB0cnVlLFxuICBpbXBvcnRzOiBbQ29tbW9uTW9kdWxlLCBGb250QXdlc29tZU1vZHVsZV0sXG4gIHRlbXBsYXRlVXJsOiAnLi9iYWNrZ3JvdW5kLW1vZGFsLmNvbXBvbmVudC5odG1sJyxcbiAgc3R5bGVVcmxzOiBbJy4vYmFja2dyb3VuZC1tb2RhbC5jb21wb25lbnQuY3NzJ10sXG59KVxuZXhwb3J0IGNsYXNzIEJhY2tncm91bmRNb2RhbCBpbXBsZW1lbnRzIE9uQ2hhbmdlcywgT25Jbml0IHtcbiAgQElucHV0KCkgaXNWaXNpYmxlID0gZmFsc2U7XG4gIEBJbnB1dCgpIHBhcmFtZXRlcnM6IEJhY2tncm91bmRNb2RhbFBhcmFtZXRlcnMgPSB7fSBhcyBCYWNrZ3JvdW5kTW9kYWxQYXJhbWV0ZXJzO1xuICBASW5wdXQoKSBwb3NpdGlvbiA9ICd0b3BMZWZ0JztcbiAgQElucHV0KCkgYmFja2dyb3VuZENvbG9yID0gJyNmNWY1ZjUnO1xuICBASW5wdXQoKSBvbkNsb3NlOiAoKSA9PiB2b2lkID0gKCkgPT4ge1xuICAgIGNvbnNvbGUubG9nKCdvbkNsb3NlJyk7XG4gIH07XG5cbiAgQFZpZXdDaGlsZCgnZGVmYXVsdEltYWdlc0NvbnRhaW5lcicpIGRlZmF1bHRJbWFnZXNDb250YWluZXJSZWYhOiBFbGVtZW50UmVmO1xuICBAVmlld0NoaWxkKCd1cGxvYWRJbWFnZUlucHV0JykgdXBsb2FkSW1hZ2VJbnB1dFJlZiE6IEVsZW1lbnRSZWY7XG4gIEBWaWV3Q2hpbGQoJ2JhY2tncm91bmRDYW52YXMnKSBiYWNrZ3JvdW5kQ2FudmFzUmVmITogRWxlbWVudFJlZjtcbiAgQFZpZXdDaGlsZCgndmlkZW9QcmV2aWV3JykgdmlkZW9QcmV2aWV3UmVmITogRWxlbWVudFJlZjtcbiAgQFZpZXdDaGlsZCgnY2FwdHVyZVZpZGVvJykgY2FwdHVyZVZpZGVvUmVmITogRWxlbWVudFJlZjtcbiAgQFZpZXdDaGlsZCgnbG9hZGluZ092ZXJsYXknKSBsb2FkaW5nT3ZlcmxheVJlZiE6IEVsZW1lbnRSZWY7XG4gIEBWaWV3Q2hpbGQoJ2FwcGx5QmFja2dyb3VuZEJ1dHRvbicpIGFwcGx5QmFja2dyb3VuZEJ1dHRvblJlZiE6IEVsZW1lbnRSZWY7XG4gIEBWaWV3Q2hpbGQoJ3NhdmVCYWNrZ3JvdW5kQnV0dG9uJykgc2F2ZUJhY2tncm91bmRCdXR0b25SZWYhOiBFbGVtZW50UmVmO1xuXG4gIGZhVGltZXMgPSBmYVRpbWVzO1xuXG4gIGN1c3RvbUltYWdlID0gJyc7XG4gIHNlbGVjdGVkSW1hZ2UgPSAnJztcbiAgc2VnbWVudFZpZGVvOiBNZWRpYVN0cmVhbSB8IG51bGwgPSBudWxsO1xuICBzZWxmaWVTZWdtZW50YXRpb246IFNlbGZpZVNlZ21lbnRhdGlvbiB8IG51bGwgPSBudWxsO1xuICBwYXVzZVNlZ21lbnRhdGlvbiA9IGZhbHNlO1xuICBwcm9jZXNzZWRTdHJlYW06IE1lZGlhU3RyZWFtIHwgbnVsbCA9IG51bGw7XG4gIGtlZXBCYWNrZ3JvdW5kID0gZmFsc2U7XG4gIGJhY2tncm91bmRIYXNDaGFuZ2VkID0gZmFsc2U7XG4gIHZpcnR1YWxTdHJlYW06IE1lZGlhU3RyZWFtIHwgbnVsbCA9IG51bGw7XG4gIG1haW5DYW52YXMhOiBIVE1MQ2FudmFzRWxlbWVudDtcbiAgcHJldktlZXBCYWNrZ3JvdW5kID0gZmFsc2U7XG4gIGFwcGxpZWRCYWNrZ3JvdW5kID0gZmFsc2U7XG4gIHZpZGVvQWxyZWFkeU9uID0gZmFsc2U7XG4gIGF1ZGlvT25seVJvb20gPSBmYWxzZTtcbiAgaXNsZXZlbCA9ICcwJztcbiAgcmVjb3JkU3RhcnRlZCA9IGZhbHNlO1xuICByZWNvcmRSZXN1bWVkID0gZmFsc2U7XG4gIHJlY29yZFBhdXNlZCA9IGZhbHNlO1xuICByZWNvcmRTdG9wcGVkID0gZmFsc2U7XG4gIHJlY29yZGluZ01lZGlhT3B0aW9ucyA9ICcnO1xuICB2aWRDb25zOiBhbnkgPSB7fTtcbiAgZnJhbWVSYXRlID0gNTtcbiAgdGFyZ2V0UmVzb2x1dGlvbiA9ICcxMjgweDcyMCc7XG4gIHZpZGVvUGFyYW1zOiBQcm9kdWNlck9wdGlvbnMgPSB7fTtcbiAgYXV0b0NsaWNrQmFja2dyb3VuZCA9IGZhbHNlO1xuICBsb2NhbFN0cmVhbVZpZGVvOiBNZWRpYVN0cmVhbSB8IG51bGwgPSBudWxsO1xuXG4gIGNsb25lZFN0cmVhbTogTWVkaWFTdHJlYW0gfCBudWxsID0gbnVsbDtcbiAgY2xvbmVkVHJhY2s6IE1lZGlhU3RyZWFtVHJhY2sgfCBudWxsID0gbnVsbDtcblxuICB1cGRhdGVDdXN0b21JbWFnZSE6ICh2YWx1ZTogc3RyaW5nKSA9PiB2b2lkO1xuICB1cGRhdGVTZWxlY3RlZEltYWdlITogKHZhbHVlOiBzdHJpbmcpID0+IHZvaWQ7XG4gIHVwZGF0ZVNlZ21lbnRWaWRlbyE6ICh2YWx1ZTogTWVkaWFTdHJlYW0gfCBudWxsKSA9PiB2b2lkO1xuICB1cGRhdGVTZWxmaWVTZWdtZW50YXRpb24hOiAodmFsdWU6IFNlbGZpZVNlZ21lbnRhdGlvbiB8IG51bGwpID0+IHZvaWQ7XG4gIHVwZGF0ZVBhdXNlU2VnbWVudGF0aW9uITogKHZhbHVlOiBib29sZWFuKSA9PiB2b2lkO1xuICB1cGRhdGVQcm9jZXNzZWRTdHJlYW0hOiAodmFsdWU6IE1lZGlhU3RyZWFtIHwgbnVsbCkgPT4gdm9pZDtcbiAgdXBkYXRlS2VlcEJhY2tncm91bmQhOiAodmFsdWU6IGJvb2xlYW4pID0+IHZvaWQ7XG4gIHVwZGF0ZUJhY2tncm91bmRIYXNDaGFuZ2VkITogKHZhbHVlOiBib29sZWFuKSA9PiB2b2lkO1xuICB1cGRhdGVWaXJ0dWFsU3RyZWFtITogKHZhbHVlOiBNZWRpYVN0cmVhbSB8IG51bGwpID0+IHZvaWQ7XG4gIHVwZGF0ZU1haW5DYW52YXMhOiAodmFsdWU6IEhUTUxDYW52YXNFbGVtZW50KSA9PiB2b2lkO1xuICB1cGRhdGVQcmV2S2VlcEJhY2tncm91bmQhOiAodmFsdWU6IGJvb2xlYW4pID0+IHZvaWQ7XG4gIHVwZGF0ZUFwcGxpZWRCYWNrZ3JvdW5kITogKHZhbHVlOiBib29sZWFuKSA9PiB2b2lkO1xuICB1cGRhdGVWaWRlb1BhcmFtcyE6ICh2YWx1ZTogUHJvZHVjZXJPcHRpb25zKSA9PiB2b2lkO1xuICB1cGRhdGVBdXRvQ2xpY2tCYWNrZ3JvdW5kITogKHZhbHVlOiBib29sZWFuKSA9PiB2b2lkO1xuXG4gIC8vIE1lZGlhIGZ1bmN0aW9uc1xuICBjcmVhdGVTZW5kVHJhbnNwb3J0ITogQ3JlYXRlU2VuZFRyYW5zcG9ydFR5cGU7XG4gIGNvbm5lY3RTZW5kVHJhbnNwb3J0VmlkZW8hOiBDb25uZWN0U2VuZFRyYW5zcG9ydFZpZGVvVHlwZTtcbiAgZGlzY29ubmVjdFNlbmRUcmFuc3BvcnRWaWRlbyE6IERpc2Nvbm5lY3RTZW5kVHJhbnNwb3J0VmlkZW9UeXBlO1xuICBvblNjcmVlbkNoYW5nZXMhOiBPblNjcmVlbkNoYW5nZXNUeXBlO1xuICBzbGVlcCE6IFNsZWVwVHlwZTtcblxuICBuZ09uSW5pdCgpIHtcbiAgICAvLyBJbml0aWFsaXplIGxvY2FsIHByb3BlcnRpZXMgZnJvbSB0aGUgcGFyYW1ldGVyc1xuICAgIGlmICh0aGlzLnBhcmFtZXRlcnMpIHtcbiAgICAgIHRyeSB7XG4gICAgICAgIHRoaXMudXBkYXRlVmFyaWFibGVzKCk7XG4gICAgICB9IGNhdGNoIHtcbiAgICAgICAgLyogaGFuZGxlIGVycm9yICovXG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgbmdPbkNoYW5nZXMoY2hhbmdlczogU2ltcGxlQ2hhbmdlcykge1xuICAgIGlmIChjaGFuZ2VzWydpc1Zpc2libGUnXSkge1xuICAgICAgdGhpcy5vblZpc2liaWxpdHlDaGFuZ2UoKTtcbiAgICB9XG5cbiAgICBpZiAoY2hhbmdlc1snYXV0b0NsaWNrQmFja2dyb3VuZCddKSB7XG4gICAgICBjb25zb2xlLmxvZyhcbiAgICAgICAgJ0F1dG8gY2xpY2sgYmFja2dyb3VuZCBjaGFuZ2VkOicsXG4gICAgICAgIHRoaXMuYXV0b0NsaWNrQmFja2dyb3VuZCxcbiAgICAgICAgY2hhbmdlc1snYXV0b0NsaWNrQmFja2dyb3VuZCddLFxuICAgICAgKTtcbiAgICB9XG4gIH1cblxuICB1cGRhdGVWYXJpYWJsZXMoKSB7XG4gICAgdGhpcy5jdXN0b21JbWFnZSA9IHRoaXMucGFyYW1ldGVycy5jdXN0b21JbWFnZSB8fCAnJztcbiAgICB0aGlzLnNlbGVjdGVkSW1hZ2UgPSB0aGlzLnBhcmFtZXRlcnMuc2VsZWN0ZWRJbWFnZSB8fCAnJztcbiAgICB0aGlzLnNlZ21lbnRWaWRlbyA9IHRoaXMucGFyYW1ldGVycy5zZWdtZW50VmlkZW8gfHwgbnVsbDtcbiAgICB0aGlzLnNlbGZpZVNlZ21lbnRhdGlvbiA9IHRoaXMucGFyYW1ldGVycy5zZWxmaWVTZWdtZW50YXRpb24gfHwgbnVsbDtcbiAgICB0aGlzLnBhdXNlU2VnbWVudGF0aW9uID0gdGhpcy5wYXJhbWV0ZXJzLnBhdXNlU2VnbWVudGF0aW9uIHx8IGZhbHNlO1xuICAgIHRoaXMucHJvY2Vzc2VkU3RyZWFtID0gdGhpcy5wYXJhbWV0ZXJzLnByb2Nlc3NlZFN0cmVhbSB8fCBudWxsO1xuICAgIHRoaXMua2VlcEJhY2tncm91bmQgPSB0aGlzLnBhcmFtZXRlcnMua2VlcEJhY2tncm91bmQgfHwgZmFsc2U7XG4gICAgdGhpcy5iYWNrZ3JvdW5kSGFzQ2hhbmdlZCA9IHRoaXMucGFyYW1ldGVycy5iYWNrZ3JvdW5kSGFzQ2hhbmdlZCB8fCBmYWxzZTtcbiAgICB0aGlzLnZpcnR1YWxTdHJlYW0gPSB0aGlzLnBhcmFtZXRlcnMudmlydHVhbFN0cmVhbSB8fCBudWxsO1xuICAgIHRoaXMubWFpbkNhbnZhcyA9IHRoaXMucGFyYW1ldGVycy5tYWluQ2FudmFzIHx8IHRoaXMuYmFja2dyb3VuZENhbnZhc1JlZj8ubmF0aXZlRWxlbWVudCB8fCBudWxsO1xuICAgIHRoaXMucHJldktlZXBCYWNrZ3JvdW5kID0gdGhpcy5wYXJhbWV0ZXJzLnByZXZLZWVwQmFja2dyb3VuZCB8fCBmYWxzZTtcbiAgICB0aGlzLmFwcGxpZWRCYWNrZ3JvdW5kID0gdGhpcy5wYXJhbWV0ZXJzLmFwcGxpZWRCYWNrZ3JvdW5kIHx8IGZhbHNlO1xuICAgIHRoaXMudmlkZW9BbHJlYWR5T24gPSB0aGlzLnBhcmFtZXRlcnMudmlkZW9BbHJlYWR5T24gfHwgZmFsc2U7XG4gICAgdGhpcy5hdWRpb09ubHlSb29tID0gdGhpcy5wYXJhbWV0ZXJzLmF1ZGlvT25seVJvb20gfHwgZmFsc2U7XG4gICAgdGhpcy5pc2xldmVsID0gdGhpcy5wYXJhbWV0ZXJzLmlzbGV2ZWwgfHwgJzAnO1xuICAgIHRoaXMucmVjb3JkU3RhcnRlZCA9IHRoaXMucGFyYW1ldGVycy5yZWNvcmRTdGFydGVkIHx8IGZhbHNlO1xuICAgIHRoaXMucmVjb3JkUmVzdW1lZCA9IHRoaXMucGFyYW1ldGVycy5yZWNvcmRSZXN1bWVkIHx8IGZhbHNlO1xuICAgIHRoaXMucmVjb3JkUGF1c2VkID0gdGhpcy5wYXJhbWV0ZXJzLnJlY29yZFBhdXNlZCB8fCBmYWxzZTtcbiAgICB0aGlzLnJlY29yZFN0b3BwZWQgPSB0aGlzLnBhcmFtZXRlcnMucmVjb3JkU3RvcHBlZCB8fCBmYWxzZTtcbiAgICB0aGlzLnJlY29yZGluZ01lZGlhT3B0aW9ucyA9IHRoaXMucGFyYW1ldGVycy5yZWNvcmRpbmdNZWRpYU9wdGlvbnMgfHwgJyc7XG4gICAgdGhpcy52aWRDb25zID0gdGhpcy5wYXJhbWV0ZXJzLnZpZENvbnMgfHwge307XG4gICAgdGhpcy5mcmFtZVJhdGUgPSB0aGlzLnBhcmFtZXRlcnMuZnJhbWVSYXRlIHx8IDU7XG4gICAgdGhpcy52aWRlb1BhcmFtcyA9IHRoaXMucGFyYW1ldGVycy52aWRlb1BhcmFtcyB8fCBudWxsO1xuICAgIHRoaXMuYXV0b0NsaWNrQmFja2dyb3VuZCA9IHRoaXMucGFyYW1ldGVycy5hdXRvQ2xpY2tCYWNrZ3JvdW5kIHx8IGZhbHNlO1xuICAgIHRoaXMubG9jYWxTdHJlYW1WaWRlbyA9IHRoaXMucGFyYW1ldGVycy5sb2NhbFN0cmVhbVZpZGVvIHx8IG51bGw7XG5cbiAgICAvLyBBc3NpZ24gbWV0aG9kIHJlZmVyZW5jZXNcbiAgICB0aGlzLnVwZGF0ZUN1c3RvbUltYWdlID0gdGhpcy5wYXJhbWV0ZXJzLnVwZGF0ZUN1c3RvbUltYWdlO1xuICAgIHRoaXMudXBkYXRlU2VsZWN0ZWRJbWFnZSA9IHRoaXMucGFyYW1ldGVycy51cGRhdGVTZWxlY3RlZEltYWdlO1xuICAgIHRoaXMudXBkYXRlU2VnbWVudFZpZGVvID0gdGhpcy5wYXJhbWV0ZXJzLnVwZGF0ZVNlZ21lbnRWaWRlbztcbiAgICB0aGlzLnVwZGF0ZVNlbGZpZVNlZ21lbnRhdGlvbiA9IHRoaXMucGFyYW1ldGVycy51cGRhdGVTZWxmaWVTZWdtZW50YXRpb247XG4gICAgdGhpcy51cGRhdGVQYXVzZVNlZ21lbnRhdGlvbiA9IHRoaXMucGFyYW1ldGVycy51cGRhdGVQYXVzZVNlZ21lbnRhdGlvbjtcbiAgICB0aGlzLnVwZGF0ZVByb2Nlc3NlZFN0cmVhbSA9IHRoaXMucGFyYW1ldGVycy51cGRhdGVQcm9jZXNzZWRTdHJlYW07XG4gICAgdGhpcy51cGRhdGVLZWVwQmFja2dyb3VuZCA9IHRoaXMucGFyYW1ldGVycy51cGRhdGVLZWVwQmFja2dyb3VuZDtcbiAgICB0aGlzLnVwZGF0ZUJhY2tncm91bmRIYXNDaGFuZ2VkID0gdGhpcy5wYXJhbWV0ZXJzLnVwZGF0ZUJhY2tncm91bmRIYXNDaGFuZ2VkO1xuICAgIHRoaXMudXBkYXRlVmlydHVhbFN0cmVhbSA9IHRoaXMucGFyYW1ldGVycy51cGRhdGVWaXJ0dWFsU3RyZWFtO1xuICAgIHRoaXMudXBkYXRlTWFpbkNhbnZhcyA9IHRoaXMucGFyYW1ldGVycy51cGRhdGVNYWluQ2FudmFzO1xuICAgIHRoaXMudXBkYXRlUHJldktlZXBCYWNrZ3JvdW5kID0gdGhpcy5wYXJhbWV0ZXJzLnVwZGF0ZVByZXZLZWVwQmFja2dyb3VuZDtcbiAgICB0aGlzLnVwZGF0ZUFwcGxpZWRCYWNrZ3JvdW5kID0gdGhpcy5wYXJhbWV0ZXJzLnVwZGF0ZUFwcGxpZWRCYWNrZ3JvdW5kO1xuICAgIHRoaXMudXBkYXRlVmlkZW9QYXJhbXMgPSB0aGlzLnBhcmFtZXRlcnMudXBkYXRlVmlkZW9QYXJhbXM7XG4gICAgdGhpcy51cGRhdGVBdXRvQ2xpY2tCYWNrZ3JvdW5kID0gdGhpcy5wYXJhbWV0ZXJzLnVwZGF0ZUF1dG9DbGlja0JhY2tncm91bmQ7XG5cbiAgICB0aGlzLmNyZWF0ZVNlbmRUcmFuc3BvcnQgPSB0aGlzLnBhcmFtZXRlcnMuY3JlYXRlU2VuZFRyYW5zcG9ydDtcbiAgICB0aGlzLmNvbm5lY3RTZW5kVHJhbnNwb3J0VmlkZW8gPSB0aGlzLnBhcmFtZXRlcnMuY29ubmVjdFNlbmRUcmFuc3BvcnRWaWRlbztcbiAgICB0aGlzLmRpc2Nvbm5lY3RTZW5kVHJhbnNwb3J0VmlkZW8gPSB0aGlzLnBhcmFtZXRlcnMuZGlzY29ubmVjdFNlbmRUcmFuc3BvcnRWaWRlbztcbiAgICB0aGlzLm9uU2NyZWVuQ2hhbmdlcyA9IHRoaXMucGFyYW1ldGVycy5vblNjcmVlbkNoYW5nZXM7XG4gICAgdGhpcy5zbGVlcCA9IHRoaXMucGFyYW1ldGVycy5zbGVlcDtcbiAgfVxuXG4gIG9uVmlzaWJpbGl0eUNoYW5nZSA9IGFzeW5jICgpID0+IHtcbiAgICBpZiAodGhpcy5wYXJhbWV0ZXJzKSB7XG4gICAgICB0aGlzLnBhcmFtZXRlcnMgPSB0aGlzLnBhcmFtZXRlcnMuZ2V0VXBkYXRlZEFsbFBhcmFtcygpO1xuICAgICAgdGhpcy51cGRhdGVWYXJpYWJsZXMoKTtcbiAgICB9XG5cbiAgICBpZiAodGhpcy5pc1Zpc2libGUpIHtcbiAgICAgIGlmICghdGhpcy5zZWxmaWVTZWdtZW50YXRpb24pIHtcbiAgICAgICAgYXdhaXQgdGhpcy5wcmVsb2FkTW9kZWwoKS5jYXRjaCgoKSA9PiBjb25zb2xlLmxvZygnRXJyb3IgcHJlbG9hZGluZyBtb2RlbDonKSk7XG4gICAgICB9XG4gICAgICB0aGlzLnJlbmRlckRlZmF1bHRJbWFnZXMoKTtcblxuICAgICAgaWYgKHRoaXMuc2VsZWN0ZWRJbWFnZSkge1xuICAgICAgICBhd2FpdCB0aGlzLmxvYWRJbWFnZVRvQ2FudmFzKHRoaXMuc2VsZWN0ZWRJbWFnZSwgdGhpcy5zZWxlY3RlZEltYWdlKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHRoaXMuY2xlYXJDYW52YXMoKTtcbiAgICAgICAgdGhpcy5iYWNrZ3JvdW5kQ2FudmFzUmVmLm5hdGl2ZUVsZW1lbnQuY2xhc3NMaXN0LnJlbW92ZSgnZC1ub25lJyk7XG4gICAgICB9XG5cbiAgICAgIHRoaXMuc2F2ZUJhY2tncm91bmRCdXR0b25SZWYubmF0aXZlRWxlbWVudC5jbGFzc0xpc3QuYWRkKCdkLW5vbmUnKTtcbiAgICAgIHRoaXMuc2F2ZUJhY2tncm91bmRCdXR0b25SZWYubmF0aXZlRWxlbWVudC5kaXNhYmxlZCA9IHRydWU7XG4gICAgICB0aGlzLmFwcGx5QmFja2dyb3VuZEJ1dHRvblJlZi5uYXRpdmVFbGVtZW50LmNsYXNzTGlzdC5yZW1vdmUoJ2Qtbm9uZScpO1xuICAgICAgdGhpcy5hcHBseUJhY2tncm91bmRCdXR0b25SZWYubmF0aXZlRWxlbWVudC5kaXNhYmxlZCA9IGZhbHNlO1xuXG4gICAgICBpZiAoXG4gICAgICAgIHRoaXMucHJvY2Vzc2VkU3RyZWFtICYmXG4gICAgICAgIHRoaXMucHJldktlZXBCYWNrZ3JvdW5kID09IHRoaXMua2VlcEJhY2tncm91bmQgJiZcbiAgICAgICAgdGhpcy5rZWVwQmFja2dyb3VuZCAmJlxuICAgICAgICB0aGlzLmFwcGxpZWRCYWNrZ3JvdW5kXG4gICAgICApIHtcbiAgICAgICAgdGhpcy5hcHBseUJhY2tncm91bmRCdXR0b25SZWYubmF0aXZlRWxlbWVudC5pbm5lclRleHQgPSAnQXBwbHkgQmFja2dyb3VuZCc7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB0aGlzLmFwcGx5QmFja2dyb3VuZEJ1dHRvblJlZi5uYXRpdmVFbGVtZW50LmlubmVyVGV4dCA9ICdQcmV2aWV3IEJhY2tncm91bmQnO1xuICAgICAgfVxuXG4gICAgICBpZiAodGhpcy5hdXRvQ2xpY2tCYWNrZ3JvdW5kKSB7XG4gICAgICAgIGF3YWl0IHRoaXMuYXBwbHlCYWNrZ3JvdW5kKCk7XG4gICAgICAgIGF3YWl0IHRoaXMuc2F2ZUJhY2tncm91bmQoKTtcbiAgICAgICAgdGhpcy5hdXRvQ2xpY2tCYWNrZ3JvdW5kID0gZmFsc2U7XG4gICAgICAgIHRoaXMudXBkYXRlQXV0b0NsaWNrQmFja2dyb3VuZCh0aGlzLmF1dG9DbGlja0JhY2tncm91bmQpO1xuICAgICAgfVxuICAgIH0gZWxzZSB7XG4gICAgICB0cnkge1xuICAgICAgICAvLyBJZiBubyBiYWNrZ3JvdW5kIGlzIGFwcGxpZWQgb3IgdGhlIGFwcGxpZWQgYmFja2dyb3VuZCBzaG91bGQgbm90IGJlIGtlcHRcbiAgICAgICAgaWYgKFxuICAgICAgICAgICF0aGlzLmFwcGxpZWRCYWNrZ3JvdW5kIHx8XG4gICAgICAgICAgKHRoaXMuYXBwbGllZEJhY2tncm91bmQgJiYgIXRoaXMua2VlcEJhY2tncm91bmQpIHx8XG4gICAgICAgICAgKHRoaXMuYXBwbGllZEJhY2tncm91bmQgJiYgIXRoaXMudmlkZW9BbHJlYWR5T24pXG4gICAgICAgICkge1xuICAgICAgICAgIGNvbnN0IHJlZlZpZGVvID0gdGhpcy5jYXB0dXJlVmlkZW9SZWYubmF0aXZlRWxlbWVudDtcbiAgICAgICAgICB0aGlzLnBhdXNlU2VnbWVudGF0aW9uID0gdHJ1ZTtcbiAgICAgICAgICB0aGlzLnVwZGF0ZVBhdXNlU2VnbWVudGF0aW9uKHRoaXMucGF1c2VTZWdtZW50YXRpb24pO1xuXG4gICAgICAgICAgaWYgKCF0aGlzLnZpZGVvQWxyZWFkeU9uKSB7XG4gICAgICAgICAgICAvLyBTdG9wIHZpZGVvIHRyYWNrcyBhbmQgY2xlYXIgdGhlIHZpZGVvIGVsZW1lbnQncyBzcmNPYmplY3RcbiAgICAgICAgICAgIGlmIChyZWZWaWRlbyAmJiByZWZWaWRlby5zcmNPYmplY3QpIHtcbiAgICAgICAgICAgICAgcmVmVmlkZW8uc3JjT2JqZWN0LmdldFRyYWNrcygpLmZvckVhY2goKHRyYWNrOiBhbnkpID0+IHRyYWNrLnN0b3AoKSk7XG4gICAgICAgICAgICAgIHJlZlZpZGVvLnNyY09iamVjdCA9IG51bGw7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIC8vIFN0b3Agc2VnbWVudFZpZGVvIHRyYWNrc1xuICAgICAgICAgICAgaWYgKHRoaXMuc2VnbWVudFZpZGVvKSB7XG4gICAgICAgICAgICAgIHRoaXMuc2VnbWVudFZpZGVvLmdldFRyYWNrcygpLmZvckVhY2goKHRyYWNrOiBhbnkpID0+IHRyYWNrLnN0b3AoKSk7XG4gICAgICAgICAgICAgIHRoaXMuc2VnbWVudFZpZGVvID0gbnVsbDtcbiAgICAgICAgICAgICAgdGhpcy51cGRhdGVTZWdtZW50VmlkZW8odGhpcy5zZWdtZW50VmlkZW8pO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAvLyBTdG9wIHZpcnR1YWxTdHJlYW0gdHJhY2tzXG4gICAgICAgICAgICBpZiAodGhpcy52aXJ0dWFsU3RyZWFtKSB7XG4gICAgICAgICAgICAgIHRoaXMudmlydHVhbFN0cmVhbS5nZXRUcmFja3MoKS5mb3JFYWNoKCh0cmFjazogYW55KSA9PiB0cmFjay5zdG9wKCkpO1xuICAgICAgICAgICAgICB0aGlzLnZpcnR1YWxTdHJlYW0gPSBudWxsO1xuICAgICAgICAgICAgICB0aGlzLnVwZGF0ZVZpcnR1YWxTdHJlYW0odGhpcy52aXJ0dWFsU3RyZWFtKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICAvLyBIaWRlIHRoZSB2aWRlbyBwcmV2aWV3IGFuZCBzaG93IHRoZSBjYW52YXNcbiAgICAgICAgdGhpcy52aWRlb1ByZXZpZXdSZWYubmF0aXZlRWxlbWVudC5jbGFzc0xpc3QuYWRkKCdkLW5vbmUnKTtcbiAgICAgICAgdGhpcy5iYWNrZ3JvdW5kQ2FudmFzUmVmLm5hdGl2ZUVsZW1lbnQuY2xhc3NMaXN0LnJlbW92ZSgnZC1ub25lJyk7XG4gICAgICB9IGNhdGNoIHtcbiAgICAgICAgLyogaGFuZGxlIGVycm9yICovXG4gICAgICB9XG4gICAgfVxuICB9O1xuXG4gIGFzeW5jIHByZWxvYWRNb2RlbCgpIHtcbiAgICB0aGlzLnNlbGZpZVNlZ21lbnRhdGlvbiA9IG5ldyBTZWxmaWVTZWdtZW50YXRpb24oe1xuICAgICAgbG9jYXRlRmlsZTogKGZpbGUpID0+IGBodHRwczovL2Nkbi5qc2RlbGl2ci5uZXQvbnBtL0BtZWRpYXBpcGUvc2VsZmllX3NlZ21lbnRhdGlvbi8ke2ZpbGV9YCxcbiAgICB9KTtcbiAgICB0aGlzLnNlbGZpZVNlZ21lbnRhdGlvbi5zZXRPcHRpb25zKHtcbiAgICAgIG1vZGVsU2VsZWN0aW9uOiAxLFxuICAgICAgc2VsZmllTW9kZTogZmFsc2UsXG4gICAgfSk7XG4gICAgYXdhaXQgdGhpcy5zZWxmaWVTZWdtZW50YXRpb24uaW5pdGlhbGl6ZSgpO1xuICAgIHRoaXMudXBkYXRlU2VsZmllU2VnbWVudGF0aW9uKHRoaXMuc2VsZmllU2VnbWVudGF0aW9uKTtcbiAgfVxuXG4gIHJlbmRlckRlZmF1bHRJbWFnZXMoKSB7XG4gICAgY29uc3QgZGVmYXVsdEltYWdlcyA9IFsnd2FsbCcsICd3YWxsMicsICdzaGVsZicsICdjbG9jaycsICdkZXNlcnQnLCAnZmxvd2VyJ107XG4gICAgY29uc3QgZGVmYXVsdEltYWdlc0NvbnRhaW5lciA9IHRoaXMuZGVmYXVsdEltYWdlc0NvbnRhaW5lclJlZi5uYXRpdmVFbGVtZW50O1xuICAgIGRlZmF1bHRJbWFnZXNDb250YWluZXIuaW5uZXJIVE1MID0gJyc7XG5cbiAgICBkZWZhdWx0SW1hZ2VzLmZvckVhY2goKGJhc2VOYW1lKSA9PiB7XG4gICAgICBjb25zdCB0aHVtYiA9IGBodHRwczovL21lZGlhc2Z1LmNvbS9pbWFnZXMvYmFja2dyb3VuZHMvJHtiYXNlTmFtZX1fdGh1bWJuYWlsLmpwZ2A7XG4gICAgICBjb25zdCBzbWFsbCA9IGBodHRwczovL21lZGlhc2Z1LmNvbS9pbWFnZXMvYmFja2dyb3VuZHMvJHtiYXNlTmFtZX1fc21hbGwuanBnYDtcbiAgICAgIGNvbnN0IGxhcmdlID0gYGh0dHBzOi8vbWVkaWFzZnUuY29tL2ltYWdlcy9iYWNrZ3JvdW5kcy8ke2Jhc2VOYW1lfV9sYXJnZS5qcGdgO1xuICAgICAgY29uc3QgZnVsbCA9IGBodHRwczovL21lZGlhc2Z1LmNvbS9pbWFnZXMvYmFja2dyb3VuZHMvJHtiYXNlTmFtZX0uanBnYDtcbiAgICAgIGNvbnN0IGltZyA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2ltZycpO1xuICAgICAgaW1nLnNyYyA9IHRodW1iO1xuICAgICAgaW1nLmNsYXNzTGlzdC5hZGQoJ2ltZy10aHVtYm5haWwnLCAnbS0xJyk7XG4gICAgICBpbWcuc3R5bGUud2lkdGggPSAnODBweCc7XG4gICAgICBpbWcuc3R5bGUuY3Vyc29yID0gJ3BvaW50ZXInO1xuICAgICAgaW1nLmFkZEV2ZW50TGlzdGVuZXIoJ2NsaWNrJywgYXN5bmMgKCkgPT4ge1xuICAgICAgICBpZiAodGhpcy50YXJnZXRSZXNvbHV0aW9uID09ICdmaGQnIHx8IHRoaXMudGFyZ2V0UmVzb2x1dGlvbiA9PSAncWhkJykge1xuICAgICAgICAgIGF3YWl0IHRoaXMubG9hZEltYWdlVG9DYW52YXMoc21hbGwsIGxhcmdlKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBhd2FpdCB0aGlzLmxvYWRJbWFnZVRvQ2FudmFzKHNtYWxsLCBmdWxsKTtcbiAgICAgICAgfVxuICAgICAgfSk7XG4gICAgICBkZWZhdWx0SW1hZ2VzQ29udGFpbmVyLmFwcGVuZENoaWxkKGltZyk7XG4gICAgfSk7XG5cbiAgICBjb25zdCBub0JhY2tncm91bmRJbWcgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdkaXYnKTtcbiAgICBub0JhY2tncm91bmRJbWcuY2xhc3NMaXN0LmFkZChcbiAgICAgICdpbWctdGh1bWJuYWlsJyxcbiAgICAgICdtLTEnLFxuICAgICAgJ2QtZmxleCcsXG4gICAgICAnYWxpZ24taXRlbXMtY2VudGVyJyxcbiAgICAgICdqdXN0aWZ5LWNvbnRlbnQtY2VudGVyJyxcbiAgICApO1xuICAgIG5vQmFja2dyb3VuZEltZy5zdHlsZS53aWR0aCA9ICc3NnB4JztcbiAgICBub0JhY2tncm91bmRJbWcuc3R5bGUubWluSGVpZ2h0ID0gJzYwcHgnO1xuICAgIG5vQmFja2dyb3VuZEltZy5zdHlsZS5jdXJzb3IgPSAncG9pbnRlcic7XG4gICAgbm9CYWNrZ3JvdW5kSW1nLnN0eWxlLmJhY2tncm91bmRDb2xvciA9ICcjZjhmOWZhJztcbiAgICBub0JhY2tncm91bmRJbWcuc3R5bGUuYm9yZGVyID0gJzFweCBzb2xpZCAjZGVlMmU2JztcbiAgICBub0JhY2tncm91bmRJbWcuc3R5bGUucG9zaXRpb24gPSAncmVsYXRpdmUnO1xuICAgIG5vQmFja2dyb3VuZEltZy5pbm5lckhUTUwgPVxuICAgICAgJzxzcGFuIHN0eWxlPVwicG9zaXRpb246YWJzb2x1dGU7IHRvcDo1MCU7IGxlZnQ6NTAlOyB0cmFuc2Zvcm06dHJhbnNsYXRlKC01MCUsIC01MCUpOyBjb2xvcjojMDAwO1wiPk5vbmU8L3NwYW4+JztcbiAgICBub0JhY2tncm91bmRJbWcuYWRkRXZlbnRMaXN0ZW5lcignY2xpY2snLCBhc3luYyAoKSA9PiB7XG4gICAgICB0aGlzLnNlbGVjdGVkSW1hZ2UgPSAnJztcbiAgICAgIHRoaXMudXBkYXRlU2VsZWN0ZWRJbWFnZSh0aGlzLnNlbGVjdGVkSW1hZ2UpO1xuICAgICAgdGhpcy51cGRhdGVDdXN0b21JbWFnZSgnJyk7XG4gICAgICB0aGlzLnNob3dMb2FkaW5nKCk7XG4gICAgICB0aGlzLnZpZGVvUHJldmlld1JlZi5uYXRpdmVFbGVtZW50LmNsYXNzTGlzdC5hZGQoJ2Qtbm9uZScpO1xuICAgICAgdGhpcy5iYWNrZ3JvdW5kQ2FudmFzUmVmLm5hdGl2ZUVsZW1lbnQuY2xhc3NMaXN0LnJlbW92ZSgnZC1ub25lJyk7XG4gICAgICB0aGlzLmNsZWFyQ2FudmFzKCk7XG4gICAgICB0aGlzLmhpZGVMb2FkaW5nKCk7XG4gICAgfSk7XG4gICAgZGVmYXVsdEltYWdlc0NvbnRhaW5lci5hcHBlbmRDaGlsZChub0JhY2tncm91bmRJbWcpO1xuXG4gICAgaWYgKHRoaXMuY3VzdG9tSW1hZ2UpIHtcbiAgICAgIGNvbnN0IGltZyA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2ltZycpO1xuICAgICAgaW1nLnNyYyA9IHRoaXMuY3VzdG9tSW1hZ2U7XG4gICAgICBpbWcuY2xhc3NMaXN0LmFkZCgnaW1nLXRodW1ibmFpbCcsICdtLTEnKTtcbiAgICAgIGltZy5zdHlsZS53aWR0aCA9ICc4MHB4JztcbiAgICAgIGltZy5zdHlsZS5jdXJzb3IgPSAncG9pbnRlcic7XG4gICAgICBpbWcuYWRkRXZlbnRMaXN0ZW5lcignY2xpY2snLCBhc3luYyAoKSA9PiB7XG4gICAgICAgIGF3YWl0IHRoaXMubG9hZEltYWdlVG9DYW52YXModGhpcy5jdXN0b21JbWFnZSwgdGhpcy5jdXN0b21JbWFnZSk7XG4gICAgICB9KTtcbiAgICAgIGRlZmF1bHRJbWFnZXNDb250YWluZXIuYXBwZW5kQ2hpbGQoaW1nKTtcbiAgICB9XG4gIH1cblxuICBhc3luYyBoYW5kbGVJbWFnZVVwbG9hZChldmVudDogRXZlbnQpIHtcbiAgICBsZXQgbWluV2lkdGggPSAxMjgwO1xuICAgIGxldCBtaW5IZWlnaHQgPSAxMjgwO1xuICAgIGxldCBtYXhXaWR0aCA9IDI1NjA7XG4gICAgbGV0IG1heEhlaWdodCA9IDI1NjA7XG5cbiAgICBpZiAodGhpcy50YXJnZXRSZXNvbHV0aW9uID09ICdmaGQnKSB7XG4gICAgICBtaW5XaWR0aCA9IDE5MjA7XG4gICAgICBtaW5IZWlnaHQgPSAxOTIwO1xuICAgIH0gZWxzZSBpZiAodGhpcy50YXJnZXRSZXNvbHV0aW9uID09ICdxaGQnKSB7XG4gICAgICBtaW5XaWR0aCA9IDI1NjA7XG4gICAgICBtaW5IZWlnaHQgPSAyNTYwO1xuICAgIH0gLy8gRm9yIG90aGVyIHJlc29sdXRpb25zLCBzdGljayB0byB0aGUgZGVmYXVsdCAxMjgweDEyODBcblxuICAgIGNvbnN0IGlucHV0ID0gZXZlbnQudGFyZ2V0IGFzIEhUTUxJbnB1dEVsZW1lbnQ7XG4gICAgaWYgKGlucHV0LmZpbGVzICYmIGlucHV0LmZpbGVzLmxlbmd0aCA+IDApIHtcbiAgICAgIGNvbnN0IGZpbGUgPSBpbnB1dC5maWxlc1swXTtcbiAgICAgIGNvbnN0IGltZyA9IG5ldyBJbWFnZSgpO1xuICAgICAgaW1nLmNyb3NzT3JpZ2luID0gJ2Fub255bW91cyc7XG4gICAgICBpbWcub25sb2FkID0gYXN5bmMgKCkgPT4ge1xuICAgICAgICBpZiAoXG4gICAgICAgICAgaW1nLndpZHRoIDwgbWluV2lkdGggfHxcbiAgICAgICAgICBpbWcuaGVpZ2h0IDwgbWluSGVpZ2h0IHx8XG4gICAgICAgICAgaW1nLndpZHRoID4gbWF4V2lkdGggfHxcbiAgICAgICAgICBpbWcuaGVpZ2h0ID4gbWF4SGVpZ2h0XG4gICAgICAgICkge1xuICAgICAgICAgIHRoaXMuY3VzdG9tSW1hZ2UgPSBpbWcuc3JjO1xuICAgICAgICAgIHRoaXMudXBkYXRlQ3VzdG9tSW1hZ2UodGhpcy5jdXN0b21JbWFnZSk7XG4gICAgICAgICAgYXdhaXQgdGhpcy5sb2FkSW1hZ2VUb0NhbnZhcyhpbWcuc3JjLCBpbWcuc3JjKTtcbiAgICAgICAgfVxuICAgICAgfTtcbiAgICAgIGNvbnN0IHJlYWRlciA9IG5ldyBGaWxlUmVhZGVyKCk7XG4gICAgICByZWFkZXIub25sb2FkID0gKGU6IFByb2dyZXNzRXZlbnQ8RmlsZVJlYWRlcj4pID0+IHtcbiAgICAgICAgaWYgKGUudGFyZ2V0KSB7XG4gICAgICAgICAgaW1nLnNyYyA9IGUudGFyZ2V0LnJlc3VsdCBhcyBzdHJpbmc7XG4gICAgICAgIH1cbiAgICAgIH07XG4gICAgICByZWFkZXIucmVhZEFzRGF0YVVSTChmaWxlKTtcbiAgICB9XG4gIH1cblxuICBjbGVhckNhbnZhcygpIHtcbiAgICBjb25zdCBjdHggPSB0aGlzLmJhY2tncm91bmRDYW52YXNSZWYubmF0aXZlRWxlbWVudC5nZXRDb250ZXh0KCcyZCcpO1xuICAgIGN0eC5jbGVhclJlY3QoXG4gICAgICAwLFxuICAgICAgMCxcbiAgICAgIHRoaXMuYmFja2dyb3VuZENhbnZhc1JlZi5uYXRpdmVFbGVtZW50LndpZHRoLFxuICAgICAgdGhpcy5iYWNrZ3JvdW5kQ2FudmFzUmVmLm5hdGl2ZUVsZW1lbnQuaGVpZ2h0LFxuICAgICk7XG4gICAgY3R4LmZvbnQgPSAnMzBweCBBcmlhbCc7XG4gICAgY3R4LmZpbGxTdHlsZSA9ICcjMDAwJztcbiAgICBjdHgudGV4dEFsaWduID0gJ2NlbnRlcic7XG4gICAgY3R4LnRleHRCYXNlbGluZSA9ICdtaWRkbGUnO1xuICAgIGN0eC5maWxsVGV4dChcbiAgICAgICdObyBCYWNrZ3JvdW5kJyxcbiAgICAgIHRoaXMuYmFja2dyb3VuZENhbnZhc1JlZi5uYXRpdmVFbGVtZW50LndpZHRoIC8gMixcbiAgICAgIHRoaXMuYmFja2dyb3VuZENhbnZhc1JlZi5uYXRpdmVFbGVtZW50LmhlaWdodCAvIDIsXG4gICAgKTtcblxuICAgIHRoaXMuYXBwbHlCYWNrZ3JvdW5kQnV0dG9uUmVmLm5hdGl2ZUVsZW1lbnQuY2xhc3NMaXN0LnJlbW92ZSgnZC1ub25lJyk7XG4gICAgdGhpcy5hcHBseUJhY2tncm91bmRCdXR0b25SZWYubmF0aXZlRWxlbWVudC5kaXNhYmxlZCA9IGZhbHNlO1xuXG4gICAgaWYgKFxuICAgICAgdGhpcy5wcm9jZXNzZWRTdHJlYW0gJiZcbiAgICAgIHRoaXMucHJldktlZXBCYWNrZ3JvdW5kID09IHRoaXMua2VlcEJhY2tncm91bmQgJiZcbiAgICAgIHRoaXMua2VlcEJhY2tncm91bmQgJiZcbiAgICAgIHRoaXMuYXBwbGllZEJhY2tncm91bmRcbiAgICApIHtcbiAgICAgIHRoaXMuYXBwbHlCYWNrZ3JvdW5kQnV0dG9uUmVmLm5hdGl2ZUVsZW1lbnQuaW5uZXJUZXh0ID0gJ0FwcGx5IEJhY2tncm91bmQnO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLmFwcGx5QmFja2dyb3VuZEJ1dHRvblJlZi5uYXRpdmVFbGVtZW50LmlubmVyVGV4dCA9ICdQcmV2aWV3IEJhY2tncm91bmQnO1xuICAgIH1cbiAgfVxuXG4gIGFzeW5jIGxvYWRJbWFnZVRvQ2FudmFzKHNyYzogc3RyaW5nLCBmdWxsU3JjOiBzdHJpbmcpIHtcbiAgICB0aGlzLnNob3dMb2FkaW5nKCk7XG4gICAgYXdhaXQgdGhpcy5iYWNrZ3JvdW5kQ2FudmFzUmVmLm5hdGl2ZUVsZW1lbnQuY2xhc3NMaXN0LnJlbW92ZSgnZC1ub25lJyk7XG4gICAgYXdhaXQgdGhpcy52aWRlb1ByZXZpZXdSZWYubmF0aXZlRWxlbWVudC5jbGFzc0xpc3QuYWRkKCdkLW5vbmUnKTtcblxuICAgIGNvbnN0IGltZyA9IG5ldyBJbWFnZSgpO1xuICAgIGltZy5jcm9zc09yaWdpbiA9ICdhbm9ueW1vdXMnO1xuICAgIGltZy5vbmxvYWQgPSBhc3luYyAoKSA9PiB7XG4gICAgICBjb25zdCBjdHggPSBhd2FpdCB0aGlzLmJhY2tncm91bmRDYW52YXNSZWYubmF0aXZlRWxlbWVudC5nZXRDb250ZXh0KCcyZCcpO1xuICAgICAgdGhpcy5iYWNrZ3JvdW5kQ2FudmFzUmVmLm5hdGl2ZUVsZW1lbnQud2lkdGggPSBpbWcud2lkdGg7XG4gICAgICB0aGlzLmJhY2tncm91bmRDYW52YXNSZWYubmF0aXZlRWxlbWVudC5oZWlnaHQgPSBpbWcuaGVpZ2h0O1xuICAgICAgYXdhaXQgY3R4LmRyYXdJbWFnZShpbWcsIDAsIDApO1xuICAgICAgdGhpcy5yZW1vdmVCYWNrZ3JvdW5kKGltZyk7XG4gICAgICB0aGlzLmhpZGVMb2FkaW5nKCk7XG4gICAgfTtcbiAgICBpbWcuc3JjID0gc3JjO1xuICAgIHRoaXMuc2VsZWN0ZWRJbWFnZSA9IGZ1bGxTcmM7XG4gICAgdGhpcy51cGRhdGVTZWxlY3RlZEltYWdlKHRoaXMuc2VsZWN0ZWRJbWFnZSk7XG5cbiAgICB0aGlzLnNhdmVCYWNrZ3JvdW5kQnV0dG9uUmVmLm5hdGl2ZUVsZW1lbnQuY2xhc3NMaXN0LmFkZCgnZC1ub25lJyk7XG4gICAgdGhpcy5zYXZlQmFja2dyb3VuZEJ1dHRvblJlZi5uYXRpdmVFbGVtZW50LmRpc2FibGVkID0gdHJ1ZTtcbiAgICB0aGlzLmFwcGx5QmFja2dyb3VuZEJ1dHRvblJlZi5uYXRpdmVFbGVtZW50LmNsYXNzTGlzdC5yZW1vdmUoJ2Qtbm9uZScpO1xuICAgIHRoaXMuYXBwbHlCYWNrZ3JvdW5kQnV0dG9uUmVmLm5hdGl2ZUVsZW1lbnQuZGlzYWJsZWQgPSBmYWxzZTtcblxuICAgIGlmIChcbiAgICAgIHRoaXMucHJvY2Vzc2VkU3RyZWFtICYmXG4gICAgICB0aGlzLnByZXZLZWVwQmFja2dyb3VuZCA9PSB0aGlzLmtlZXBCYWNrZ3JvdW5kICYmXG4gICAgICB0aGlzLmtlZXBCYWNrZ3JvdW5kICYmXG4gICAgICB0aGlzLmFwcGxpZWRCYWNrZ3JvdW5kXG4gICAgKSB7XG4gICAgICB0aGlzLmFwcGx5QmFja2dyb3VuZEJ1dHRvblJlZi5uYXRpdmVFbGVtZW50LmlubmVyVGV4dCA9ICdBcHBseSBCYWNrZ3JvdW5kJztcbiAgICB9IGVsc2Uge1xuICAgICAgdGhpcy5hcHBseUJhY2tncm91bmRCdXR0b25SZWYubmF0aXZlRWxlbWVudC5pbm5lclRleHQgPSAnUHJldmlldyBCYWNrZ3JvdW5kJztcbiAgICB9XG4gIH1cblxuICByZW1vdmVCYWNrZ3JvdW5kKGltZzogSFRNTEltYWdlRWxlbWVudCkge1xuICAgIGNvbnN0IGN0eCA9IHRoaXMuYmFja2dyb3VuZENhbnZhc1JlZi5uYXRpdmVFbGVtZW50LmdldENvbnRleHQoJzJkJyk7XG4gICAgY3R4LmNsZWFyUmVjdChcbiAgICAgIDAsXG4gICAgICAwLFxuICAgICAgdGhpcy5iYWNrZ3JvdW5kQ2FudmFzUmVmLm5hdGl2ZUVsZW1lbnQud2lkdGgsXG4gICAgICB0aGlzLmJhY2tncm91bmRDYW52YXNSZWYubmF0aXZlRWxlbWVudC5oZWlnaHQsXG4gICAgKTtcbiAgICBjdHguZHJhd0ltYWdlKGltZywgMCwgMCk7XG4gIH1cblxuICBhc3luYyBhcHBseUJhY2tncm91bmQoKSB7XG4gICAgdHJ5IHtcbiAgICAgIGlmICh0aGlzLmF1ZGlvT25seVJvb20pIHtcbiAgICAgICAgdGhpcy5wYXJhbWV0ZXJzLnNob3dBbGVydD8uKHtcbiAgICAgICAgICBtZXNzYWdlOiAnWW91IGNhbm5vdCB1c2UgYSBiYWNrZ3JvdW5kIGluIGFuIGF1ZGlvIG9ubHkgZXZlbnQuJyxcbiAgICAgICAgICB0eXBlOiAnZGFuZ2VyJyxcbiAgICAgICAgfSk7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cblxuICAgICAgdGhpcy5zaG93TG9hZGluZygpO1xuXG4gICAgICB0aGlzLnZpZGVvUHJldmlld1JlZi5uYXRpdmVFbGVtZW50LmNsYXNzTGlzdC5yZW1vdmUoJ2Qtbm9uZScpO1xuICAgICAgdGhpcy5iYWNrZ3JvdW5kQ2FudmFzUmVmLm5hdGl2ZUVsZW1lbnQuY2xhc3NMaXN0LmFkZCgnZC1ub25lJyk7XG5cbiAgICAgIGNvbnN0IGRvU2VnbWVudGF0aW9uID0gdGhpcy5zZWxlY3RlZEltYWdlID8gdHJ1ZSA6IGZhbHNlO1xuICAgICAgdGhpcy5wYXVzZVNlZ21lbnRhdGlvbiA9IGZhbHNlO1xuICAgICAgdGhpcy51cGRhdGVQYXVzZVNlZ21lbnRhdGlvbih0aGlzLnBhdXNlU2VnbWVudGF0aW9uKTtcbiAgICAgIGF3YWl0IHRoaXMuc2VsZmllU2VnbWVudGF0aW9uUHJldmlldyhkb1NlZ21lbnRhdGlvbik7XG5cbiAgICAgIHRoaXMuaGlkZUxvYWRpbmcoKTtcblxuICAgICAgdGhpcy5hcHBseUJhY2tncm91bmRCdXR0b25SZWYubmF0aXZlRWxlbWVudC5jbGFzc0xpc3QuYWRkKCdkLW5vbmUnKTtcbiAgICAgIHRoaXMuYXBwbHlCYWNrZ3JvdW5kQnV0dG9uUmVmLm5hdGl2ZUVsZW1lbnQuZGlzYWJsZWQgPSB0cnVlO1xuXG4gICAgICBpZiAoXG4gICAgICAgIHRoaXMucHJvY2Vzc2VkU3RyZWFtICYmXG4gICAgICAgIHRoaXMucHJldktlZXBCYWNrZ3JvdW5kID09IHRoaXMua2VlcEJhY2tncm91bmQgJiZcbiAgICAgICAgdGhpcy5rZWVwQmFja2dyb3VuZCAmJlxuICAgICAgICB0aGlzLmFwcGxpZWRCYWNrZ3JvdW5kXG4gICAgICApIHtcbiAgICAgICAgdGhpcy5zYXZlQmFja2dyb3VuZEJ1dHRvblJlZi5uYXRpdmVFbGVtZW50LmNsYXNzTGlzdC5hZGQoJ2Qtbm9uZScpO1xuICAgICAgICB0aGlzLnNhdmVCYWNrZ3JvdW5kQnV0dG9uUmVmLm5hdGl2ZUVsZW1lbnQuZGlzYWJsZWQgPSB0cnVlO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgdGhpcy5zYXZlQmFja2dyb3VuZEJ1dHRvblJlZi5uYXRpdmVFbGVtZW50LmNsYXNzTGlzdC5yZW1vdmUoJ2Qtbm9uZScpO1xuICAgICAgICB0aGlzLnNhdmVCYWNrZ3JvdW5kQnV0dG9uUmVmLm5hdGl2ZUVsZW1lbnQuZGlzYWJsZWQgPSBmYWxzZTtcbiAgICAgIH1cbiAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgY29uc29sZS5sb2coZXJyb3IpO1xuICAgIH1cbiAgfVxuXG4gIGFzeW5jIHNlbGZpZVNlZ21lbnRhdGlvblByZXZpZXcoZG9TZWdtZW50YXRpb246IGJvb2xlYW4pIHtcbiAgICBjb25zdCByZWZWaWRlbyA9IHRoaXMuY2FwdHVyZVZpZGVvUmVmLm5hdGl2ZUVsZW1lbnQ7XG4gICAgY29uc3QgcHJldmlld1ZpZGVvID0gdGhpcy52aWRlb1ByZXZpZXdSZWYubmF0aXZlRWxlbWVudDtcbiAgICBjb25zdCB2aXJ0dWFsSW1hZ2UgPSBuZXcgSW1hZ2UoKTtcbiAgICB2aXJ0dWFsSW1hZ2UuY3Jvc3NPcmlnaW4gPSAnYW5vbnltb3VzJztcbiAgICB2aXJ0dWFsSW1hZ2Uuc3JjID0gdGhpcy5zZWxlY3RlZEltYWdlO1xuXG4gICAgaWYgKCF0aGlzLm1haW5DYW52YXMpIHtcbiAgICAgIHRoaXMubWFpbkNhbnZhcyA9IGF3YWl0IHRoaXMuYmFja2dyb3VuZENhbnZhc1JlZi5uYXRpdmVFbGVtZW50O1xuICAgIH1cblxuICAgIGxldCBtZWRpYUNhbnZhcyA9IHRoaXMubWFpbkNhbnZhcztcbiAgICBtZWRpYUNhbnZhcy53aWR0aCA9IHJlZlZpZGVvLnZpZGVvV2lkdGg7XG4gICAgbWVkaWFDYW52YXMuaGVpZ2h0ID0gcmVmVmlkZW8udmlkZW9IZWlnaHQ7XG4gICAgbGV0IGN0eCA9IG1lZGlhQ2FudmFzLmdldENvbnRleHQoJzJkJyk7XG5cbiAgICB0aGlzLmJhY2tncm91bmRIYXNDaGFuZ2VkID0gdHJ1ZTtcbiAgICB0aGlzLnVwZGF0ZUJhY2tncm91bmRIYXNDaGFuZ2VkKHRoaXMuYmFja2dyb3VuZEhhc0NoYW5nZWQpO1xuICAgIHRoaXMucHJldktlZXBCYWNrZ3JvdW5kID0gdGhpcy5rZWVwQmFja2dyb3VuZDtcbiAgICB0aGlzLnVwZGF0ZVByZXZLZWVwQmFja2dyb3VuZCh0aGlzLmtlZXBCYWNrZ3JvdW5kKTtcblxuICAgIGlmICghZG9TZWdtZW50YXRpb24pIHtcbiAgICAgIGNvbnN0IHRyYWNrcyA9IHRoaXMucHJvY2Vzc2VkU3RyZWFtPy5nZXRWaWRlb1RyYWNrcygpO1xuICAgICAgaWYgKHRyYWNrcykge1xuICAgICAgICB0cmFja3MuZm9yRWFjaCgodHJhY2s6IE1lZGlhU3RyZWFtVHJhY2spID0+IHRyYWNrLnN0b3AoKSk7XG4gICAgICB9XG4gICAgICB0aGlzLnByb2Nlc3NlZFN0cmVhbSA9IG51bGw7XG4gICAgICB0aGlzLmtlZXBCYWNrZ3JvdW5kID0gZmFsc2U7XG4gICAgICB0aGlzLnVwZGF0ZVByb2Nlc3NlZFN0cmVhbShudWxsKTtcbiAgICAgIHRoaXMudXBkYXRlS2VlcEJhY2tncm91bmQoZmFsc2UpO1xuICAgICAgcHJldmlld1ZpZGVvLmNsYXNzTGlzdC5yZW1vdmUoJ2Qtbm9uZScpO1xuICAgIH1cblxuICAgIGNvbnN0IHNlZ21lbnRJbWFnZSA9IGFzeW5jICh2aWRlb0VsZW1lbnQ6IEhUTUxWaWRlb0VsZW1lbnQpID0+IHtcbiAgICAgIGNvbnN0IHByb2Nlc3NGcmFtZSA9ICgpID0+IHtcbiAgICAgICAgaWYgKFxuICAgICAgICAgICF0aGlzLnNlbGZpZVNlZ21lbnRhdGlvbiB8fFxuICAgICAgICAgIHRoaXMucGF1c2VTZWdtZW50YXRpb24gfHxcbiAgICAgICAgICAhdmlkZW9FbGVtZW50IHx8XG4gICAgICAgICAgdmlkZW9FbGVtZW50LnZpZGVvV2lkdGggPT0gMCB8fFxuICAgICAgICAgIHZpZGVvRWxlbWVudC52aWRlb0hlaWdodCA9PSAwXG4gICAgICAgICkge1xuICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLnNlbGZpZVNlZ21lbnRhdGlvbi5zZW5kKHsgaW1hZ2U6IHZpZGVvRWxlbWVudCB9KTtcbiAgICAgICAgcmVxdWVzdEFuaW1hdGlvbkZyYW1lKHByb2Nlc3NGcmFtZSk7XG4gICAgICB9O1xuXG4gICAgICB2aWRlb0VsZW1lbnQub25sb2FkZWRkYXRhID0gKCkgPT4ge1xuICAgICAgICBwcm9jZXNzRnJhbWUoKTtcbiAgICAgIH07XG5cbiAgICAgIHNldFRpbWVvdXQoYXN5bmMgKCkgPT4ge1xuICAgICAgICBjb25zb2xlLmxvZygnQ2FwdHVyaW5nIHN0cmVhbTonLCB0aGlzLmZyYW1lUmF0ZSB8fCA1KTtcbiAgICAgICAgdGhpcy5wcm9jZXNzZWRTdHJlYW0gPSBtZWRpYUNhbnZhcy5jYXB0dXJlU3RyZWFtKHRoaXMuZnJhbWVSYXRlIHx8IDUpO1xuICAgICAgICB0aGlzLnVwZGF0ZVByb2Nlc3NlZFN0cmVhbSh0aGlzLnByb2Nlc3NlZFN0cmVhbSk7XG4gICAgICAgIHByZXZpZXdWaWRlby5zcmNPYmplY3QgPSB0aGlzLnByb2Nlc3NlZFN0cmVhbTtcbiAgICAgICAgcHJldmlld1ZpZGVvLmNsYXNzTGlzdC5yZW1vdmUoJ2Qtbm9uZScpO1xuICAgICAgICB0aGlzLmtlZXBCYWNrZ3JvdW5kID0gdHJ1ZTtcbiAgICAgICAgdGhpcy51cGRhdGVLZWVwQmFja2dyb3VuZCh0aGlzLmtlZXBCYWNrZ3JvdW5kKTtcblxuICAgICAgICBpZiAocHJldmlld1ZpZGVvLnBhdXNlZCkge1xuICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICAvLyBwbGF5IHRoZSB2aWRlb1xuICAgICAgICAgICAgcHJldmlld1ZpZGVvLnBsYXkoKS50aGVuKCgpID0+IHtcbiAgICAgICAgICAgICAgLyogaGFuZGxlIHN1Y2Nlc3MgKi9cbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgIH0gY2F0Y2gge1xuICAgICAgICAgICAgLyogaGFuZGxlIGVycm9yICovXG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9LCAxMDApO1xuICAgIH07XG5cbiAgICBpZiAodGhpcy52aWRlb0FscmVhZHlPbikge1xuICAgICAgaWYgKFxuICAgICAgICB0aGlzLmNsb25lZFRyYWNrICYmXG4gICAgICAgIHRoaXMuY2xvbmVkVHJhY2sucmVhZHlTdGF0ZSA9PSAnbGl2ZScgJiZcbiAgICAgICAgdGhpcy5sb2NhbFN0cmVhbVZpZGVvPy5nZXRWaWRlb1RyYWNrcygpWzBdLmxhYmVsID09IHRoaXMuY2xvbmVkVHJhY2subGFiZWxcbiAgICAgICkge1xuICAgICAgICAvLyBVc2UgZXhpc3RpbmcgY2xvbmVkVHJhY2tcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGNvbnN0IGxvY2FsVHJhY2tzID0gdGhpcy5sb2NhbFN0cmVhbVZpZGVvPy5nZXRWaWRlb1RyYWNrcygpWzBdO1xuICAgICAgICB0aGlzLmNsb25lZFRyYWNrID0gbG9jYWxUcmFja3MhLmNsb25lKCk7XG4gICAgICAgIHRoaXMuY2xvbmVkU3RyZWFtID0gbmV3IE1lZGlhU3RyZWFtKFt0aGlzLmNsb25lZFRyYWNrIV0pO1xuICAgICAgICB0aGlzLnNlZ21lbnRWaWRlbyA9IHRoaXMuY2xvbmVkU3RyZWFtO1xuICAgICAgfVxuICAgICAgdGhpcy51cGRhdGVTZWdtZW50VmlkZW8odGhpcy5zZWdtZW50VmlkZW8pO1xuICAgICAgcmVmVmlkZW8uc3JjT2JqZWN0ID0gdGhpcy5zZWdtZW50VmlkZW87XG4gICAgICBpZiAocmVmVmlkZW8ucGF1c2VkKSB7XG4gICAgICAgIHJlZlZpZGVvLnBsYXkoKTtcbiAgICAgIH1cblxuICAgICAgcmVmVmlkZW8ud2lkdGggPSB0aGlzLnNlZ21lbnRWaWRlbyEuZ2V0VmlkZW9UcmFja3MoKVswXS5nZXRTZXR0aW5ncygpLndpZHRoITtcbiAgICAgIHJlZlZpZGVvLmhlaWdodCA9IHRoaXMuc2VnbWVudFZpZGVvIS5nZXRWaWRlb1RyYWNrcygpWzBdLmdldFNldHRpbmdzKCkuaGVpZ2h0ITtcbiAgICAgIG1lZGlhQ2FudmFzLndpZHRoID0gcmVmVmlkZW8ud2lkdGg7XG4gICAgICBtZWRpYUNhbnZhcy5oZWlnaHQgPSByZWZWaWRlby5oZWlnaHQ7XG4gICAgICBjdHggPSBtZWRpYUNhbnZhcy5nZXRDb250ZXh0KCcyZCcpO1xuXG4gICAgICB0cnkge1xuICAgICAgICBkb1NlZ21lbnRhdGlvblxuICAgICAgICAgID8gYXdhaXQgc2VnbWVudEltYWdlKHJlZlZpZGVvKVxuICAgICAgICAgIDogKHByZXZpZXdWaWRlby5zcmNPYmplY3QgPSB0aGlzLmNsb25lZFN0cmVhbVxuICAgICAgICAgICAgICA/IHRoaXMuY2xvbmVkU3RyZWFtXG4gICAgICAgICAgICAgIDogdGhpcy5sb2NhbFN0cmVhbVZpZGVvISk7XG4gICAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgICBjb25zb2xlLmxvZygnRXJyb3Igc2VnbWVudGluZyBpbWFnZTonLCBlcnJvcik7XG4gICAgICB9XG4gICAgfSBlbHNlIHtcbiAgICAgIGlmICh0aGlzLnNlZ21lbnRWaWRlbyAmJiB0aGlzLnNlZ21lbnRWaWRlby5nZXRWaWRlb1RyYWNrcygpWzBdLnJlYWR5U3RhdGUgPT0gJ2xpdmUnKSB7XG4gICAgICAgIC8vIFVzZSBleGlzdGluZyBzZWdtZW50VmlkZW9cbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgY29uc3Qgc3RyZWFtID0gYXdhaXQgbmF2aWdhdG9yLm1lZGlhRGV2aWNlcy5nZXRVc2VyTWVkaWEoe1xuICAgICAgICAgICAgdmlkZW86IHsgLi4udGhpcy52aWRDb25zLCBmcmFtZVJhdGU6IHsgaWRlYWw6IHRoaXMuZnJhbWVSYXRlIHx8IDUgfSB9LFxuICAgICAgICAgICAgYXVkaW86IGZhbHNlLFxuICAgICAgICAgIH0pO1xuICAgICAgICAgIHRoaXMuc2VnbWVudFZpZGVvID0gc3RyZWFtO1xuICAgICAgICAgIHRoaXMudXBkYXRlU2VnbWVudFZpZGVvKHRoaXMuc2VnbWVudFZpZGVvKTtcbiAgICAgICAgICByZWZWaWRlby5zcmNPYmplY3QgPSB0aGlzLnNlZ21lbnRWaWRlbztcbiAgICAgICAgICBpZiAocmVmVmlkZW8ucGF1c2VkKSB7XG4gICAgICAgICAgICByZWZWaWRlby5wbGF5KCk7XG4gICAgICAgICAgfVxuICAgICAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgICAgIGNvbnNvbGUubG9nKCdFcnJvciBnZXR0aW5nIHVzZXIgbWVkaWE6JywgZXJyb3IpO1xuICAgICAgICB9XG5cbiAgICAgICAgcmVmVmlkZW8ud2lkdGggPSB0aGlzLnNlZ21lbnRWaWRlbyEuZ2V0VmlkZW9UcmFja3MoKVswXS5nZXRTZXR0aW5ncygpLndpZHRoITtcbiAgICAgICAgcmVmVmlkZW8uaGVpZ2h0ID0gdGhpcy5zZWdtZW50VmlkZW8hLmdldFZpZGVvVHJhY2tzKClbMF0uZ2V0U2V0dGluZ3MoKS5oZWlnaHQhO1xuICAgICAgICBtZWRpYUNhbnZhcy53aWR0aCA9IHJlZlZpZGVvLndpZHRoO1xuICAgICAgICBtZWRpYUNhbnZhcy5oZWlnaHQgPSByZWZWaWRlby5oZWlnaHQ7XG4gICAgICAgIGN0eCA9IG1lZGlhQ2FudmFzLmdldENvbnRleHQoJzJkJyk7XG4gICAgICB9XG5cbiAgICAgIHRyeSB7XG4gICAgICAgIGRvU2VnbWVudGF0aW9uXG4gICAgICAgICAgPyBhd2FpdCBzZWdtZW50SW1hZ2UocmVmVmlkZW8pXG4gICAgICAgICAgOiAocHJldmlld1ZpZGVvLnNyY09iamVjdCA9IHJlZlZpZGVvLnNyY09iamVjdCk7XG4gICAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgICBjb25zb2xlLmxvZyhlcnJvcik7XG4gICAgICB9XG4gICAgfVxuXG4gICAgbGV0IHJlcGVhdFBhdHRlcm4gPSAnbm8tcmVwZWF0JztcbiAgICB0cnkge1xuICAgICAgaWYgKHZpcnR1YWxJbWFnZS53aWR0aCA8IG1lZGlhQ2FudmFzLndpZHRoIHx8IHZpcnR1YWxJbWFnZS5oZWlnaHQgPCBtZWRpYUNhbnZhcy5oZWlnaHQpIHtcbiAgICAgICAgcmVwZWF0UGF0dGVybiA9ICdyZXBlYXQnO1xuICAgICAgfVxuICAgIH0gY2F0Y2gge1xuICAgICAgLyogaGFuZGxlIGVycm9yICovXG4gICAgfVxuXG4gICAgY29uc3Qgb25SZXN1bHRzID0gKHJlc3VsdHM6IGFueSkgPT4ge1xuICAgICAgdHJ5IHtcbiAgICAgICAgaWYgKFxuICAgICAgICAgICF0aGlzLnBhdXNlU2VnbWVudGF0aW9uICYmXG4gICAgICAgICAgbWVkaWFDYW52YXMgJiZcbiAgICAgICAgICBtZWRpYUNhbnZhcy53aWR0aCA+IDAgJiZcbiAgICAgICAgICBtZWRpYUNhbnZhcy5oZWlnaHQgPiAwICYmXG4gICAgICAgICAgdmlydHVhbEltYWdlLndpZHRoID4gMCAmJlxuICAgICAgICAgIHZpcnR1YWxJbWFnZS5oZWlnaHQgPiAwXG4gICAgICAgICkge1xuICAgICAgICAgIGN0eCEuY2xlYXJSZWN0KDAsIDAsIG1lZGlhQ2FudmFzLndpZHRoLCBtZWRpYUNhbnZhcy5oZWlnaHQpO1xuICAgICAgICAgIGN0eCEuZHJhd0ltYWdlKHJlc3VsdHMuc2VnbWVudGF0aW9uTWFzaywgMCwgMCwgbWVkaWFDYW52YXMud2lkdGgsIG1lZGlhQ2FudmFzLmhlaWdodCk7XG5cbiAgICAgICAgICBjdHghLmdsb2JhbENvbXBvc2l0ZU9wZXJhdGlvbiA9ICdzb3VyY2Utb3V0JztcbiAgICAgICAgICBjb25zdCBwYXQgPSBjdHghLmNyZWF0ZVBhdHRlcm4odmlydHVhbEltYWdlLCByZXBlYXRQYXR0ZXJuKTtcbiAgICAgICAgICBjdHghLmZpbGxTdHlsZSA9IHBhdCE7XG4gICAgICAgICAgY3R4IS5maWxsUmVjdCgwLCAwLCBtZWRpYUNhbnZhcy53aWR0aCwgbWVkaWFDYW52YXMuaGVpZ2h0KTtcblxuICAgICAgICAgIGN0eCEuZ2xvYmFsQ29tcG9zaXRlT3BlcmF0aW9uID0gJ2Rlc3RpbmF0aW9uLWF0b3AnO1xuICAgICAgICAgIGN0eCEuZHJhd0ltYWdlKHJlc3VsdHMuaW1hZ2UsIDAsIDAsIG1lZGlhQ2FudmFzLndpZHRoLCBtZWRpYUNhbnZhcy5oZWlnaHQpO1xuICAgICAgICB9XG4gICAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgICBjb25zb2xlLmxvZygnRXJyb3IgcHJvY2Vzc2luZyByZXN1bHRzOicsIGVycm9yKTtcbiAgICAgIH1cbiAgICB9O1xuXG4gICAgaWYgKCF0aGlzLnNlbGZpZVNlZ21lbnRhdGlvbikge1xuICAgICAgYXdhaXQgdGhpcy5wcmVsb2FkTW9kZWwoKS5jYXRjaCgoKSA9PiBjb25zb2xlLmxvZygnRXJyb3IgcHJlbG9hZGluZyBtb2RlbDonKSk7XG4gICAgfVxuXG4gICAgdHJ5IHtcbiAgICAgIHRoaXMuc2VsZmllU2VnbWVudGF0aW9uIS5vblJlc3VsdHMob25SZXN1bHRzKTtcbiAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgY29uc29sZS5sb2coZXJyb3IpO1xuICAgIH1cbiAgfVxuXG4gIHNhdmVCYWNrZ3JvdW5kID0gYXN5bmMgKCkgPT4ge1xuICAgIGlmICh0aGlzLmF1ZGlvT25seVJvb20pIHtcbiAgICAgIHRoaXMucGFyYW1ldGVycy5zaG93QWxlcnQ/Lih7XG4gICAgICAgIG1lc3NhZ2U6ICdZb3UgY2Fubm90IHVzZSBhIGJhY2tncm91bmQgaW4gYW4gYXVkaW8tb25seSBldmVudC4nLFxuICAgICAgICB0eXBlOiAnZGFuZ2VyJyxcbiAgICAgIH0pO1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGlmICh0aGlzLmJhY2tncm91bmRIYXNDaGFuZ2VkKSB7XG4gICAgICBpZiAodGhpcy52aWRlb0FscmVhZHlPbikge1xuICAgICAgICBpZiAodGhpcy5pc2xldmVsID09ICcyJyAmJiAodGhpcy5yZWNvcmRTdGFydGVkIHx8IHRoaXMucmVjb3JkUmVzdW1lZCkpIHtcbiAgICAgICAgICBpZiAoISh0aGlzLnJlY29yZFBhdXNlZCB8fCB0aGlzLnJlY29yZFN0b3BwZWQpKSB7XG4gICAgICAgICAgICBpZiAodGhpcy5yZWNvcmRpbmdNZWRpYU9wdGlvbnMgPT0gJ3ZpZGVvJykge1xuICAgICAgICAgICAgICB0aGlzLnBhcmFtZXRlcnMuc2hvd0FsZXJ0Py4oe1xuICAgICAgICAgICAgICAgIG1lc3NhZ2U6ICdQbGVhc2UgcGF1c2UgdGhlIHJlY29yZGluZyBiZWZvcmUgY2hhbmdpbmcgdGhlIGJhY2tncm91bmQuJyxcbiAgICAgICAgICAgICAgICB0eXBlOiAnZGFuZ2VyJyxcbiAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICBpZiAodGhpcy5rZWVwQmFja2dyb3VuZCAmJiB0aGlzLnNlbGVjdGVkSW1hZ2UgJiYgdGhpcy5wcm9jZXNzZWRTdHJlYW0pIHtcbiAgICAgICAgICB0aGlzLnZpcnR1YWxTdHJlYW0gPSB0aGlzLnByb2Nlc3NlZFN0cmVhbTtcbiAgICAgICAgICB0aGlzLnVwZGF0ZVZpcnR1YWxTdHJlYW0odGhpcy52aXJ0dWFsU3RyZWFtKTtcbiAgICAgICAgICB0aGlzLnZpZGVvUGFyYW1zID0geyB0cmFjazogdGhpcy52aXJ0dWFsU3RyZWFtLmdldFZpZGVvVHJhY2tzKClbMF0gfTtcbiAgICAgICAgICB0aGlzLnVwZGF0ZVZpZGVvUGFyYW1zKHRoaXMudmlkZW9QYXJhbXMpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIGlmICh0aGlzLmxvY2FsU3RyZWFtVmlkZW8/LmdldFZpZGVvVHJhY2tzKClbMF0ucmVhZHlTdGF0ZSA9PSAnbGl2ZScpIHtcbiAgICAgICAgICAgIHRoaXMudmlkZW9QYXJhbXMgPSB7IHRyYWNrOiB0aGlzLmxvY2FsU3RyZWFtVmlkZW8uZ2V0VmlkZW9UcmFja3MoKVswXSB9O1xuICAgICAgICAgICAgdGhpcy51cGRhdGVWaWRlb1BhcmFtcyh0aGlzLnZpZGVvUGFyYW1zKTtcbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgICAgaWYgKHRoaXMubG9jYWxTdHJlYW1WaWRlbz8uZ2V0VmlkZW9UcmFja3MoKVswXS5yZWFkeVN0YXRlICE9PSAnbGl2ZScpIHtcbiAgICAgICAgICAgICAgICB0aGlzLmxvY2FsU3RyZWFtVmlkZW8/LnJlbW92ZVRyYWNrKHRoaXMubG9jYWxTdHJlYW1WaWRlby5nZXRWaWRlb1RyYWNrcygpWzBdKTtcbiAgICAgICAgICAgICAgICB0aGlzLmxvY2FsU3RyZWFtVmlkZW8/LmFkZFRyYWNrKHRoaXMuc2VnbWVudFZpZGVvIS5nZXRWaWRlb1RyYWNrcygpWzBdLmNsb25lKCkpO1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgICAgICAgICBjb25zb2xlLmxvZygnRXJyb3IgaGFuZGxpbmcgbG9jYWwgc3RyZWFtIHZpZGVvOicsIGVycm9yKTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgdGhpcy52aWRlb1BhcmFtcyA9IHsgdHJhY2s6IHRoaXMuc2VnbWVudFZpZGVvIS5nZXRWaWRlb1RyYWNrcygpWzBdIH07XG4gICAgICAgICAgICB0aGlzLnVwZGF0ZVZpZGVvUGFyYW1zKHRoaXMudmlkZW9QYXJhbXMpO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIGlmICh0aGlzLmtlZXBCYWNrZ3JvdW5kKSB7XG4gICAgICAgICAgdGhpcy5hcHBsaWVkQmFja2dyb3VuZCA9IHRydWU7XG4gICAgICAgICAgdGhpcy51cGRhdGVBcHBsaWVkQmFja2dyb3VuZCh0aGlzLmFwcGxpZWRCYWNrZ3JvdW5kKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICB0aGlzLmFwcGxpZWRCYWNrZ3JvdW5kID0gZmFsc2U7XG4gICAgICAgICAgdGhpcy51cGRhdGVBcHBsaWVkQmFja2dyb3VuZCh0aGlzLmFwcGxpZWRCYWNrZ3JvdW5kKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmICghdGhpcy5wYXJhbWV0ZXJzLnRyYW5zcG9ydENyZWF0ZWQpIHtcbiAgICAgICAgICBhd2FpdCB0aGlzLmNyZWF0ZVNlbmRUcmFuc3BvcnQoe1xuICAgICAgICAgICAgb3B0aW9uOiAndmlkZW8nLFxuICAgICAgICAgICAgcGFyYW1ldGVyczogeyAuLi50aGlzLnBhcmFtZXRlcnMsIHZpZGVvUGFyYW1zOiB0aGlzLnZpZGVvUGFyYW1zIH0sXG4gICAgICAgICAgfSk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgIGlmIChcbiAgICAgICAgICAgICAgdGhpcy5wYXJhbWV0ZXJzLnZpZGVvUHJvZHVjZXI/LmlkICYmXG4gICAgICAgICAgICAgIHRoaXMucGFyYW1ldGVycy52aWRlb1Byb2R1Y2VyLnRyYWNrPy5pZCAhPT0gdGhpcy52aWRlb1BhcmFtcz8udHJhY2s/LmlkXG4gICAgICAgICAgICApIHtcbiAgICAgICAgICAgICAgYXdhaXQgdGhpcy5kaXNjb25uZWN0U2VuZFRyYW5zcG9ydFZpZGVvKHsgcGFyYW1ldGVyczogdGhpcy5wYXJhbWV0ZXJzIH0pO1xuICAgICAgICAgICAgICBhd2FpdCB0aGlzLnNsZWVwKHsgbXM6IDUwMCB9KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGF3YWl0IHRoaXMuY29ubmVjdFNlbmRUcmFuc3BvcnRWaWRlbyh7XG4gICAgICAgICAgICAgIHZpZGVvUGFyYW1zOiB0aGlzLnZpZGVvUGFyYW1zLFxuICAgICAgICAgICAgICBwYXJhbWV0ZXJzOiB0aGlzLnBhcmFtZXRlcnMsXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgICAgICAgY29uc29sZS5sb2coZXJyb3IpO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBhd2FpdCB0aGlzLm9uU2NyZWVuQ2hhbmdlcyh7IGNoYW5nZWQ6IHRydWUsIHBhcmFtZXRlcnM6IHRoaXMucGFyYW1ldGVycyB9KTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICBpZiAodGhpcy5rZWVwQmFja2dyb3VuZCkge1xuICAgICAgdGhpcy5hcHBsaWVkQmFja2dyb3VuZCA9IHRydWU7XG4gICAgICB0aGlzLnVwZGF0ZUFwcGxpZWRCYWNrZ3JvdW5kKHRoaXMuYXBwbGllZEJhY2tncm91bmQpO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLmFwcGxpZWRCYWNrZ3JvdW5kID0gZmFsc2U7XG4gICAgICB0aGlzLnVwZGF0ZUFwcGxpZWRCYWNrZ3JvdW5kKHRoaXMuYXBwbGllZEJhY2tncm91bmQpO1xuICAgIH1cblxuICAgIHRoaXMuc2F2ZUJhY2tncm91bmRCdXR0b25SZWYubmF0aXZlRWxlbWVudC5jbGFzc0xpc3QuYWRkKCdkLW5vbmUnKTtcbiAgICB0aGlzLnNhdmVCYWNrZ3JvdW5kQnV0dG9uUmVmLm5hdGl2ZUVsZW1lbnQuZGlzYWJsZWQgPSB0cnVlO1xuICB9O1xuXG4gIGhhbmRsZU1vZGFsQ2xvc2UgPSAoKSA9PiB7XG4gICAgdHJ5IHtcbiAgICAgIC8vIElmIG5vIGJhY2tncm91bmQgaXMgYXBwbGllZCBvciB0aGUgYXBwbGllZCBiYWNrZ3JvdW5kIHNob3VsZCBub3QgYmUga2VwdFxuICAgICAgaWYgKFxuICAgICAgICAhdGhpcy5hcHBsaWVkQmFja2dyb3VuZCB8fFxuICAgICAgICAodGhpcy5hcHBsaWVkQmFja2dyb3VuZCAmJiAhdGhpcy5rZWVwQmFja2dyb3VuZCkgfHxcbiAgICAgICAgKHRoaXMuYXBwbGllZEJhY2tncm91bmQgJiYgIXRoaXMudmlkZW9BbHJlYWR5T24pXG4gICAgICApIHtcbiAgICAgICAgY29uc29sZS5sb2coJ05vIGJhY2tncm91bmQgYXBwbGllZCBvciBhcHBsaWVkIGJhY2tncm91bmQgc2hvdWxkIG5vdCBiZSBrZXB0Jyk7XG4gICAgICAgIGNvbnN0IHJlZlZpZGVvID0gdGhpcy5jYXB0dXJlVmlkZW9SZWYubmF0aXZlRWxlbWVudDtcbiAgICAgICAgdGhpcy5wYXVzZVNlZ21lbnRhdGlvbiA9IHRydWU7XG4gICAgICAgIHRoaXMudXBkYXRlUGF1c2VTZWdtZW50YXRpb24odGhpcy5wYXVzZVNlZ21lbnRhdGlvbik7XG5cbiAgICAgICAgaWYgKCF0aGlzLnZpZGVvQWxyZWFkeU9uKSB7XG4gICAgICAgICAgLy8gU3RvcCB2aWRlbyB0cmFja3MgYW5kIGNsZWFyIHRoZSB2aWRlbyBlbGVtZW50J3Mgc3JjT2JqZWN0XG4gICAgICAgICAgaWYgKHJlZlZpZGVvICYmIHJlZlZpZGVvLnNyY09iamVjdCkge1xuICAgICAgICAgICAgcmVmVmlkZW8uc3JjT2JqZWN0LmdldFRyYWNrcygpLmZvckVhY2goKHRyYWNrOiBhbnkpID0+IHRyYWNrLnN0b3AoKSk7XG4gICAgICAgICAgICByZWZWaWRlby5zcmNPYmplY3QgPSBudWxsO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIC8vIFN0b3Agc2VnbWVudFZpZGVvIHRyYWNrc1xuICAgICAgICAgIGlmICh0aGlzLnNlZ21lbnRWaWRlbykge1xuICAgICAgICAgICAgdGhpcy5zZWdtZW50VmlkZW8uZ2V0VHJhY2tzKCkuZm9yRWFjaCgodHJhY2s6IGFueSkgPT4gdHJhY2suc3RvcCgpKTtcbiAgICAgICAgICAgIHRoaXMuc2VnbWVudFZpZGVvID0gbnVsbDtcbiAgICAgICAgICAgIHRoaXMudXBkYXRlU2VnbWVudFZpZGVvKHRoaXMuc2VnbWVudFZpZGVvKTtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICAvLyBTdG9wIHZpcnR1YWxTdHJlYW0gdHJhY2tzXG4gICAgICAgICAgaWYgKHRoaXMudmlydHVhbFN0cmVhbSkge1xuICAgICAgICAgICAgdGhpcy52aXJ0dWFsU3RyZWFtLmdldFRyYWNrcygpLmZvckVhY2goKHRyYWNrOiBhbnkpID0+IHRyYWNrLnN0b3AoKSk7XG4gICAgICAgICAgICB0aGlzLnZpcnR1YWxTdHJlYW0gPSBudWxsO1xuICAgICAgICAgICAgdGhpcy51cGRhdGVWaXJ0dWFsU3RyZWFtKHRoaXMudmlydHVhbFN0cmVhbSk7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIC8vIEhpZGUgdGhlIHZpZGVvIHByZXZpZXcgYW5kIHNob3cgdGhlIGNhbnZhc1xuICAgICAgdGhpcy52aWRlb1ByZXZpZXdSZWYubmF0aXZlRWxlbWVudC5jbGFzc0xpc3QuYWRkKCdkLW5vbmUnKTtcbiAgICAgIHRoaXMuYmFja2dyb3VuZENhbnZhc1JlZi5uYXRpdmVFbGVtZW50LmNsYXNzTGlzdC5yZW1vdmUoJ2Qtbm9uZScpO1xuXG4gICAgICAvLyBIaWRlIHRoZSBtb2RhbFxuICAgICAgLy8gdGhpcy5pc1Zpc2libGUgPSBmYWxzZTtcbiAgICAgIHRoaXMub25DbG9zZSgpO1xuICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICBjb25zb2xlLmxvZygnRXJyb3IgZHVyaW5nIG1vZGFsIGNsb3NlOicsIGVycm9yKTtcbiAgICB9XG4gIH07XG5cbiAgc2hvd0xvYWRpbmcoKSB7XG4gICAgdGhpcy5sb2FkaW5nT3ZlcmxheVJlZi5uYXRpdmVFbGVtZW50LmNsYXNzTGlzdC5yZW1vdmUoJ2Qtbm9uZScpO1xuICB9XG5cbiAgaGlkZUxvYWRpbmcoKSB7XG4gICAgdGhpcy5sb2FkaW5nT3ZlcmxheVJlZi5uYXRpdmVFbGVtZW50LmNsYXNzTGlzdC5hZGQoJ2Qtbm9uZScpO1xuICB9XG59XG4iLCI8ZGl2IFtuZ1N0eWxlXT1cInsgcG9zaXRpb246ICdmaXhlZCcsIHRvcDogMCwgbGVmdDogMCwgd2lkdGg6ICcxMDAlJywgaGVpZ2h0OiAnMTAwJScsIGJhY2tncm91bmRDb2xvcjogJ3JnYmEoMCwgMCwgMCwgMC41KScsIGRpc3BsYXk6IGlzVmlzaWJsZSA/ICdibG9jaycgOiAnbm9uZScsIHpJbmRleDogOTk5IH1cIj5cclxuICAgIDxkaXYgW25nU3R5bGVdPVwieyBwb3NpdGlvbjogJ2ZpeGVkJywgYmFja2dyb3VuZENvbG9yOiBiYWNrZ3JvdW5kQ29sb3IsIGJvcmRlclJhZGl1czogJzEwcHgnLCBwYWRkaW5nOiAnMTBweCcsIHdpZHRoOiAnODAlJywgbWF4V2lkdGg6ICc1MDBweCcsIG1heEhlaWdodDogJzc1JScsIG92ZXJmbG93WTogJ2F1dG8nLCBvdmVyZmxvd1g6ICdoaWRkZW4nLCB0b3A6IHBvc2l0aW9uLmluY2x1ZGVzKCd0b3AnKSA/ICcxMHB4JyA6ICdhdXRvJywgYm90dG9tOiBwb3NpdGlvbi5pbmNsdWRlcygnYm90dG9tJykgPyAnMTBweCcgOiAnYXV0bycsIGxlZnQ6IHBvc2l0aW9uLmluY2x1ZGVzKCdMZWZ0JykgPyAnMTBweCcgOiAnYXV0bycsIHJpZ2h0OiBwb3NpdGlvbi5pbmNsdWRlcygnUmlnaHQnKSA/ICcxMHB4JyA6ICdhdXRvJyB9XCI+XHJcbiAgICAgIDxkaXYgc3R5bGU9XCJkaXNwbGF5OiBmbGV4OyBqdXN0aWZ5LWNvbnRlbnQ6IHNwYWNlLWJldHdlZW47IGFsaWduLWl0ZW1zOiBjZW50ZXI7IG1hcmdpbi1ib3R0b206IDE1cHg7XCI+XHJcbiAgICAgICAgPGgyIHN0eWxlPVwiZm9udC1zaXplOiB4LWxhcmdlOyBmb250LXdlaWdodDogYm9sZDsgY29sb3I6IGJsYWNrO1wiPkJhY2tncm91bmQgU2V0dGluZ3M8L2gyPlxyXG4gICAgICAgIDxidXR0b24gKGNsaWNrKT1cIm9uQ2xvc2UoKVwiIHN0eWxlPVwiYm9yZGVyOiBub25lOyBiYWNrZ3JvdW5kOiBub25lOyBjdXJzb3I6IHBvaW50ZXI7XCI+XHJcbiAgICAgICAgICA8ZmEtaWNvbiBbaWNvbl09XCJmYVRpbWVzXCIgc2l6ZT1cInhsXCIgc3R5bGU9XCJmb250LXNpemU6IDIwcHg7IGNvbG9yOiBibGFjaztcIj48L2ZhLWljb24+XHJcbiAgICAgICAgPC9idXR0b24+XHJcbiAgICAgIDwvZGl2PlxyXG4gICAgICA8aHIgc3R5bGU9XCJoZWlnaHQ6IDFweDsgYmFja2dyb3VuZC1jb2xvcjogYmxhY2s7IG1hcmdpbi10b3A6IDVweDsgbWFyZ2luLWJvdHRvbTogNXB4O1wiIC8+XHJcbiAgICAgIDxkaXYgc3R5bGU9XCJtYXgtd2lkdGg6IDk1JTsgb3ZlcmZsb3cteDogYXV0bztcIj5cclxuICAgICAgICA8ZGl2IGlkPVwiZGVmYXVsdEltYWdlc1wiICNkZWZhdWx0SW1hZ2VzQ29udGFpbmVyPjwvZGl2PlxyXG4gICAgICAgIDxkaXYgY2xhc3M9XCJmb3JtLWdyb3VwXCIgc3R5bGU9XCJtYXgtd2lkdGg6IDcwJTsgb3ZlcmZsb3cteDogYXV0bztcIj5cclxuICAgICAgICAgIDxsYWJlbCBmb3I9XCJ1cGxvYWRJbWFnZVwiPlVwbG9hZCBDdXN0b20gSW1hZ2U8L2xhYmVsPlxyXG4gICAgICAgICAgPGlucHV0IHR5cGU9XCJmaWxlXCIgY2xhc3M9XCJmb3JtLWNvbnRyb2xcIiBpZD1cInVwbG9hZEltYWdlXCIgI3VwbG9hZEltYWdlSW5wdXQgKGNoYW5nZSk9XCJoYW5kbGVJbWFnZVVwbG9hZCgkZXZlbnQpXCIgLz5cclxuICAgICAgICA8L2Rpdj5cclxuICAgICAgICA8Y2FudmFzIGlkPVwibWFpbkNhbnZhc1wiICNtYWluQ2FudmFzIGNsYXNzPVwiZC1ub25lXCI+PC9jYW52YXM+XHJcbiAgICAgICAgPGNhbnZhcyBpZD1cImJhY2tncm91bmRDYW52YXNcIiAjYmFja2dyb3VuZENhbnZhcyBjbGFzcz1cImQtbm9uZVwiIHN0eWxlPVwid2lkdGg6IDEwMCU7IG1heC13aWR0aDogNDAwcHg7IGhlaWdodDogYXV0bzsgYmFja2dyb3VuZC1jb2xvcjogdHJhbnNwYXJlbnQ7IGJvcmRlcjogMXB4IHNvbGlkIGJsYWNrO1wiPjwvY2FudmFzPlxyXG4gICAgICAgIDx2aWRlbyBpZD1cImNhcHR1cmVWaWRlb1wiICNjYXB0dXJlVmlkZW8gY2xhc3M9XCJkLW5vbmVcIiBtdXRlZCBhdXRvcGxheSBwbGF5c2lubGluZT48L3ZpZGVvPlxyXG4gICAgICAgIDx2aWRlbyBpZD1cInByZXZpZXdWaWRlb1wiICN2aWRlb1ByZXZpZXcgY2xhc3M9XCJkLW5vbmVcIiBtdXRlZCBhdXRvcGxheSBwbGF5c2lubGluZSBzdHlsZT1cIndpZHRoOiAxMDAlOyBtYXgtd2lkdGg6IDQwMHB4OyBoZWlnaHQ6IGF1dG87IGJhY2tncm91bmQtY29sb3I6IHRyYW5zcGFyZW50OyBib3JkZXI6IDFweCBzb2xpZCBibGFjaztcIj48L3ZpZGVvPlxyXG4gICAgICAgIDxkaXYgaWQ9XCJsb2FkaW5nT3ZlcmxheVwiICNsb2FkaW5nT3ZlcmxheSBjbGFzcz1cImQtbm9uZVwiIFtuZ1N0eWxlXT1cInsgcG9zaXRpb246ICdhYnNvbHV0ZScsIHRvcDogMCwgbGVmdDogMCwgd2lkdGg6ICcxMDAlJywgaGVpZ2h0OiAnMTAwJScsIGJhY2tncm91bmRDb2xvcjogJ3JnYmEoMCwgMCwgMCwgMC41KScsIGRpc3BsYXk6ICdmbGV4JywgJ2p1c3RpZnktY29udGVudCc6ICdjZW50ZXInLCAnYWxpZ24taXRlbXMnOiAnY2VudGVyJywgekluZGV4OiAxMDAwIH1cIj5cclxuICAgICAgICAgIDxkaXYgW25nU3R5bGVdPVwieyB3aWR0aDogJzUwcHgnLCBoZWlnaHQ6ICc1MHB4JywgYm9yZGVyOiAnNXB4IHNvbGlkIHJnYmEoMjU1LCAyNTUsIDI1NSwgMC4zKScsIGJvcmRlclJhZGl1czogJzUwJScsIGJvcmRlclRvcDogJzVweCBzb2xpZCB3aGl0ZScsIGFuaW1hdGlvbjogJ3NwaW4gMXMgbGluZWFyIGluZmluaXRlJyB9XCI+PC9kaXY+XHJcbiAgICAgICAgPC9kaXY+XHJcbiAgICAgICAgPGJyIC8+XHJcbiAgICAgICAgPGJ1dHRvbiBpZD1cImFwcGx5QmFja2dyb3VuZEJ1dHRvblwiICNhcHBseUJhY2tncm91bmRCdXR0b24gY2xhc3M9XCJidG4gYnRuLXByaW1hcnlcIiAoY2xpY2spPVwiYXBwbHlCYWNrZ3JvdW5kKClcIj5QcmV2aWV3IEJhY2tncm91bmQ8L2J1dHRvbj5cclxuICAgICAgICA8YnV0dG9uIGlkPVwic2F2ZUJhY2tncm91bmRCdXR0b25cIiAjc2F2ZUJhY2tncm91bmRCdXR0b24gY2xhc3M9XCJidG4gYnRuLXN1Y2Nlc3MgZC1ub25lXCIgKGNsaWNrKT1cInNhdmVCYWNrZ3JvdW5kKClcIj5TYXZlIEJhY2tncm91bmQ8L2J1dHRvbj5cclxuICAgICAgPC9kaXY+XHJcbiAgICA8L2Rpdj5cclxuICA8L2Rpdj5cclxuIl19
|