speechrecorderng 3.6.0 → 3.8.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/esm2022/lib/action/action.mjs +73 -0
- package/{esm2020 → esm2022}/lib/audio/array_audio_buffer.mjs +163 -163
- package/{esm2020 → esm2022}/lib/audio/array_audio_buffer_input_stream.mjs +85 -85
- package/{esm2020 → esm2022}/lib/audio/array_audio_buffer_random_access_stream.mjs +15 -15
- package/esm2022/lib/audio/audio_data_holder.mjs +264 -0
- package/{esm2020 → esm2022}/lib/audio/audio_display.mjs +93 -93
- package/{esm2020 → esm2022}/lib/audio/audio_player.mjs +213 -213
- package/esm2022/lib/audio/capture/capture.mjs +855 -0
- package/esm2022/lib/audio/context.mjs +79 -0
- package/{esm2020 → esm2022}/lib/audio/dsp/level_measure.mjs +515 -515
- package/{esm2020 → esm2022}/lib/audio/format.mjs +16 -16
- package/esm2022/lib/audio/impl/wavformat.mjs +6 -0
- package/{esm2020 → esm2022}/lib/audio/impl/wavreader.mjs +133 -133
- package/esm2022/lib/audio/impl/wavwriter.mjs +105 -0
- package/esm2022/lib/audio/inddb_audio_buffer.mjs +508 -0
- package/{esm2020 → esm2022}/lib/audio/io/stream.mjs +58 -58
- package/esm2022/lib/audio/net_audio_buffer.mjs +293 -0
- package/{esm2020 → esm2022}/lib/audio/persistor.mjs +80 -80
- package/{esm2020 → esm2022}/lib/audio/playback/array_audio_buffer_source_node.mjs +125 -125
- package/esm2022/lib/audio/playback/audio_source_node.mjs +18 -0
- package/esm2022/lib/audio/playback/audio_source_worklet_module_loader.mjs +167 -0
- package/{esm2020 → esm2022}/lib/audio/playback/inddb_audio_buffer_source_node.mjs +166 -166
- package/{esm2020 → esm2022}/lib/audio/playback/net_audio_buffer_source_node.mjs +217 -217
- package/esm2022/lib/audio/playback/player.mjs +402 -0
- package/esm2022/lib/audio/ui/audio_canvas_layer_comp.mjs +347 -0
- package/{esm2020 → esm2022}/lib/audio/ui/audio_display_control.mjs +65 -65
- package/{esm2020 → esm2022}/lib/audio/ui/audio_display_scroll_pane.mjs +139 -139
- package/{esm2020 → esm2022}/lib/audio/ui/audiosignal.mjs +524 -524
- package/{esm2020 → esm2022}/lib/audio/ui/common.mjs +18 -18
- package/esm2022/lib/audio/ui/container.mjs +414 -0
- package/{esm2020 → esm2022}/lib/audio/ui/livelevel.mjs +352 -352
- package/esm2022/lib/audio/ui/scroll_pane_horizontal.mjs +11 -0
- package/esm2022/lib/audio/ui/sonagram.mjs +900 -0
- package/esm2022/lib/db/inddb.mjs +120 -0
- package/esm2022/lib/dsp/utils.mjs +48 -0
- package/{esm2020 → esm2022}/lib/io/BinaryReader.mjs +84 -84
- package/esm2022/lib/io/BinaryWriter.mjs +74 -0
- package/{esm2020 → esm2022}/lib/io/stream.mjs +258 -258
- package/{esm2020 → esm2022}/lib/math/2d/geometry.mjs +27 -27
- package/esm2022/lib/math/complex.mjs +58 -0
- package/{esm2020 → esm2022}/lib/math/dft.mjs +195 -195
- package/{esm2020 → esm2022}/lib/media/utils.mjs +13 -13
- package/esm2022/lib/net/uploader.mjs +367 -0
- package/{esm2020 → esm2022}/lib/recorder_component.mjs +64 -64
- package/esm2022/lib/speechrecorder/project/project.mjs +49 -0
- package/esm2022/lib/speechrecorder/project/project.service.mjs +64 -0
- package/{esm2020 → esm2022}/lib/speechrecorder/recording.mjs +123 -123
- package/esm2022/lib/speechrecorder/recordings/basic_recording.service.mjs +218 -0
- package/esm2022/lib/speechrecorder/recordings/recordings.service.mjs +1014 -0
- package/{esm2020 → esm2022}/lib/speechrecorder/script/script.mjs +114 -114
- package/{esm2020 → esm2022}/lib/speechrecorder/script/script.service.mjs +47 -47
- package/esm2022/lib/speechrecorder/session/audiorecorder.mjs +1179 -0
- package/esm2022/lib/speechrecorder/session/basicrecorder.mjs +668 -0
- package/esm2022/lib/speechrecorder/session/controlpanel.mjs +416 -0
- package/{esm2020 → esm2022}/lib/speechrecorder/session/item.mjs +29 -29
- package/{esm2020 → esm2022}/lib/speechrecorder/session/progress.mjs +69 -69
- package/{esm2020 → esm2022}/lib/speechrecorder/session/prompting.mjs +571 -571
- package/{esm2020 → esm2022}/lib/speechrecorder/session/recorder_combi_pane.mjs +65 -65
- package/esm2022/lib/speechrecorder/session/recording_file_cache.mjs +195 -0
- package/{esm2020 → esm2022}/lib/speechrecorder/session/recording_list.mjs +103 -103
- package/{esm2020 → esm2022}/lib/speechrecorder/session/recordingfile/recording-file-meta.component.mjs +63 -63
- package/{esm2020 → esm2022}/lib/speechrecorder/session/recordingfile/recording-file-navi.component.mjs +51 -51
- package/{esm2020 → esm2022}/lib/speechrecorder/session/recordingfile/recording-file-u-i.component.mjs +104 -104
- package/{esm2020 → esm2022}/lib/speechrecorder/session/recordingfile/recording-file-view.component.mjs +381 -381
- package/{esm2020 → esm2022}/lib/speechrecorder/session/recordingfile/recording-file.mjs +67 -67
- package/esm2022/lib/speechrecorder/session/recordingfile/recordingfile-service.mjs +288 -0
- package/{esm2020 → esm2022}/lib/speechrecorder/session/session.mjs +1 -1
- package/esm2022/lib/speechrecorder/session/session.service.mjs +69 -0
- package/{esm2020 → esm2022}/lib/speechrecorder/session/session_finished_dialog.mjs +29 -29
- package/esm2022/lib/speechrecorder/session/sessionmanager.mjs +1386 -0
- package/{esm2020 → esm2022}/lib/speechrecorder/session/warning_bar.mjs +28 -28
- package/{esm2020 → esm2022}/lib/speechrecorder/spruploader.mjs +22 -22
- package/{esm2020 → esm2022}/lib/speechrecorder/startstopsignal/startstopsignal.mjs +1 -1
- package/esm2022/lib/speechrecorder/startstopsignal/ui/simpletrafficlight.mjs +57 -0
- package/{esm2020 → esm2022}/lib/speechrecorderng.component.mjs +388 -388
- package/{esm2020 → esm2022}/lib/speechrecorderng.module.mjs +100 -100
- package/{esm2020 → esm2022}/lib/spr.config.mjs +26 -26
- package/{esm2020 → esm2022}/lib/spr.module.version.mjs +2 -2
- package/{esm2020 → esm2022}/lib/ui/canvas_layer_comp.mjs +38 -38
- package/{esm2020 → esm2022}/lib/ui/message_dialog.mjs +30 -30
- package/esm2022/lib/ui/recordingitem_display.mjs +253 -0
- package/{esm2020 → esm2022}/lib/ui/responsive_component.mjs +24 -24
- package/{esm2020 → esm2022}/lib/utils/scrollIntoViewToBottom.mjs +23 -23
- package/esm2022/lib/utils/ua-parser.mjs +190 -0
- package/esm2022/lib/utils/utils.mjs +105 -0
- package/esm2022/lib/utils/wake_lock.mjs +114 -0
- package/{esm2020 → esm2022}/lib/utils/wake_lock_media.mjs +1 -1
- package/{esm2020 → esm2022}/public-api.mjs +33 -33
- package/{esm2020 → esm2022}/speechrecorderng.mjs +4 -4
- package/{fesm2020 → fesm2022}/speechrecorderng.mjs +16518 -16454
- package/fesm2022/speechrecorderng.mjs.map +1 -0
- package/index.d.ts +5 -5
- package/lib/action/action.d.ts +27 -27
- package/lib/audio/array_audio_buffer.d.ts +31 -31
- package/lib/audio/array_audio_buffer_input_stream.d.ts +14 -14
- package/lib/audio/array_audio_buffer_random_access_stream.d.ts +9 -9
- package/lib/audio/audio_data_holder.d.ts +84 -84
- package/lib/audio/audio_display.d.ts +36 -36
- package/lib/audio/audio_player.d.ts +47 -47
- package/lib/audio/capture/capture.d.ts +67 -67
- package/lib/audio/context.d.ts +6 -6
- package/lib/audio/dsp/level_measure.d.ts +60 -60
- package/lib/audio/format.d.ts +11 -11
- package/lib/audio/impl/wavformat.d.ts +5 -5
- package/lib/audio/impl/wavreader.d.ts +16 -16
- package/lib/audio/impl/wavwriter.d.ts +13 -13
- package/lib/audio/inddb_audio_buffer.d.ts +68 -68
- package/lib/audio/io/stream.d.ts +28 -28
- package/lib/audio/net_audio_buffer.d.ts +57 -57
- package/lib/audio/persistor.d.ts +29 -29
- package/lib/audio/playback/array_audio_buffer_source_node.d.ts +18 -18
- package/lib/audio/playback/audio_source_node.d.ts +10 -10
- package/lib/audio/playback/audio_source_worklet_module_loader.d.ts +4 -4
- package/lib/audio/playback/inddb_audio_buffer_source_node.d.ts +21 -21
- package/lib/audio/playback/net_audio_buffer_source_node.d.ts +27 -27
- package/lib/audio/playback/player.d.ts +65 -65
- package/lib/audio/ui/audio_canvas_layer_comp.d.ts +68 -68
- package/lib/audio/ui/audio_display_control.d.ts +25 -25
- package/lib/audio/ui/audio_display_scroll_pane.d.ts +26 -26
- package/lib/audio/ui/audiosignal.d.ts +30 -30
- package/lib/audio/ui/common.d.ts +11 -11
- package/lib/audio/ui/container.d.ts +63 -63
- package/lib/audio/ui/livelevel.d.ts +60 -60
- package/lib/audio/ui/scroll_pane_horizontal.d.ts +5 -5
- package/lib/audio/ui/sonagram.d.ts +37 -37
- package/lib/db/inddb.d.ts +21 -21
- package/lib/dsp/utils.d.ts +19 -19
- package/lib/io/BinaryReader.d.ts +18 -18
- package/lib/io/BinaryWriter.d.ts +15 -15
- package/lib/io/stream.d.ts +59 -59
- package/lib/math/2d/geometry.d.ts +18 -18
- package/lib/math/complex.d.ts +17 -17
- package/lib/math/dft.d.ts +22 -22
- package/lib/media/utils.d.ts +3 -3
- package/lib/net/uploader.d.ts +81 -81
- package/lib/recorder_component.d.ts +16 -16
- package/lib/speechrecorder/project/project.d.ts +59 -59
- package/lib/speechrecorder/project/project.service.d.ts +21 -21
- package/lib/speechrecorder/recording.d.ts +51 -51
- package/lib/speechrecorder/recordings/basic_recording.service.d.ts +27 -27
- package/lib/speechrecorder/recordings/recordings.service.d.ts +48 -48
- package/lib/speechrecorder/script/script.d.ts +80 -79
- package/lib/speechrecorder/script/script.service.d.ts +16 -16
- package/lib/speechrecorder/session/audiorecorder.d.ts +122 -122
- package/lib/speechrecorder/session/basicrecorder.d.ts +139 -139
- package/lib/speechrecorder/session/controlpanel.d.ts +109 -107
- package/lib/speechrecorder/session/item.d.ts +12 -12
- package/lib/speechrecorder/session/progress.d.ts +17 -17
- package/lib/speechrecorder/session/prompting.d.ts +121 -121
- package/lib/speechrecorder/session/recorder_combi_pane.d.ts +32 -32
- package/lib/speechrecorder/session/recording_file_cache.d.ts +33 -33
- package/lib/speechrecorder/session/recording_list.d.ts +24 -24
- package/lib/speechrecorder/session/recordingfile/recording-file-meta.component.d.ts +15 -15
- package/lib/speechrecorder/session/recordingfile/recording-file-navi.component.d.ts +20 -20
- package/lib/speechrecorder/session/recordingfile/recording-file-u-i.component.d.ts +31 -31
- package/lib/speechrecorder/session/recordingfile/recording-file-view.component.d.ts +55 -55
- package/lib/speechrecorder/session/recordingfile/recording-file.d.ts +7 -7
- package/lib/speechrecorder/session/recordingfile/recordingfile-service.d.ts +24 -24
- package/lib/speechrecorder/session/session.d.ts +15 -15
- package/lib/speechrecorder/session/session.service.d.ts +20 -20
- package/lib/speechrecorder/session/session_finished_dialog.d.ts +10 -10
- package/lib/speechrecorder/session/sessionmanager.d.ts +129 -123
- package/lib/speechrecorder/session/warning_bar.d.ts +8 -8
- package/lib/speechrecorder/spruploader.d.ts +11 -11
- package/lib/speechrecorder/startstopsignal/startstopsignal.d.ts +10 -10
- package/lib/speechrecorder/startstopsignal/ui/simpletrafficlight.d.ts +11 -11
- package/lib/speechrecorderng.component.d.ts +61 -61
- package/lib/speechrecorderng.module.d.ts +56 -56
- package/lib/spr.config.d.ts +17 -17
- package/lib/spr.module.version.d.ts +1 -1
- package/lib/ui/canvas_layer_comp.d.ts +13 -13
- package/lib/ui/message_dialog.d.ts +10 -10
- package/lib/ui/recordingitem_display.d.ts +84 -84
- package/lib/ui/responsive_component.d.ts +9 -9
- package/lib/utils/scrollIntoViewToBottom.d.ts +9 -9
- package/lib/utils/ua-parser.d.ts +43 -43
- package/lib/utils/utils.d.ts +19 -19
- package/lib/utils/wake_lock.d.ts +23 -23
- package/lib/utils/wake_lock_media.d.ts +1 -1
- package/package.json +17 -23
- package/public-api.d.ts +33 -33
- package/esm2020/lib/action/action.mjs +0 -73
- package/esm2020/lib/audio/audio_data_holder.mjs +0 -264
- package/esm2020/lib/audio/capture/capture.mjs +0 -855
- package/esm2020/lib/audio/context.mjs +0 -79
- package/esm2020/lib/audio/impl/wavformat.mjs +0 -6
- package/esm2020/lib/audio/impl/wavwriter.mjs +0 -105
- package/esm2020/lib/audio/inddb_audio_buffer.mjs +0 -508
- package/esm2020/lib/audio/net_audio_buffer.mjs +0 -293
- package/esm2020/lib/audio/playback/audio_source_node.mjs +0 -18
- package/esm2020/lib/audio/playback/audio_source_worklet_module_loader.mjs +0 -167
- package/esm2020/lib/audio/playback/player.mjs +0 -402
- package/esm2020/lib/audio/ui/audio_canvas_layer_comp.mjs +0 -347
- package/esm2020/lib/audio/ui/container.mjs +0 -414
- package/esm2020/lib/audio/ui/scroll_pane_horizontal.mjs +0 -11
- package/esm2020/lib/audio/ui/sonagram.mjs +0 -900
- package/esm2020/lib/db/inddb.mjs +0 -120
- package/esm2020/lib/dsp/utils.mjs +0 -48
- package/esm2020/lib/io/BinaryWriter.mjs +0 -74
- package/esm2020/lib/math/complex.mjs +0 -58
- package/esm2020/lib/net/uploader.mjs +0 -367
- package/esm2020/lib/speechrecorder/project/project.mjs +0 -49
- package/esm2020/lib/speechrecorder/project/project.service.mjs +0 -64
- package/esm2020/lib/speechrecorder/recordings/basic_recording.service.mjs +0 -216
- package/esm2020/lib/speechrecorder/recordings/recordings.service.mjs +0 -1014
- package/esm2020/lib/speechrecorder/session/audiorecorder.mjs +0 -1179
- package/esm2020/lib/speechrecorder/session/basicrecorder.mjs +0 -666
- package/esm2020/lib/speechrecorder/session/controlpanel.mjs +0 -409
- package/esm2020/lib/speechrecorder/session/recording_file_cache.mjs +0 -195
- package/esm2020/lib/speechrecorder/session/recordingfile/recordingfile-service.mjs +0 -288
- package/esm2020/lib/speechrecorder/session/session.service.mjs +0 -69
- package/esm2020/lib/speechrecorder/session/sessionmanager.mjs +0 -1333
- package/esm2020/lib/speechrecorder/startstopsignal/ui/simpletrafficlight.mjs +0 -57
- package/esm2020/lib/ui/recordingitem_display.mjs +0 -253
- package/esm2020/lib/utils/ua-parser.mjs +0 -190
- package/esm2020/lib/utils/utils.mjs +0 -105
- package/esm2020/lib/utils/wake_lock.mjs +0 -114
- package/fesm2015/speechrecorderng.mjs +0 -17708
- package/fesm2015/speechrecorderng.mjs.map +0 -1
- package/fesm2020/speechrecorderng.mjs.map +0 -1
|
@@ -0,0 +1,402 @@
|
|
|
1
|
+
import { Action } from '../../action/action';
|
|
2
|
+
import { ArrayAudioBuffer } from "../array_audio_buffer";
|
|
3
|
+
import { ArrayAudioBufferSourceNode } from "./array_audio_buffer_source_node";
|
|
4
|
+
import { IndexedDbAudioBuffer } from "../inddb_audio_buffer";
|
|
5
|
+
import { AudioSourceWorkletModuleLoader } from "./audio_source_worklet_module_loader";
|
|
6
|
+
import { IndexedDbAudioBufferSourceNode } from "./inddb_audio_buffer_source_node";
|
|
7
|
+
import { NetAudioBuffer } from "../net_audio_buffer";
|
|
8
|
+
import { NetAudioBufferSourceNode } from "./net_audio_buffer_source_node";
|
|
9
|
+
import { AudioBufferSource } from "../audio_data_holder";
|
|
10
|
+
import { AudioContextProvider } from "../context";
|
|
11
|
+
export var EventType;
|
|
12
|
+
(function (EventType) {
|
|
13
|
+
EventType[EventType["CLOSED"] = 0] = "CLOSED";
|
|
14
|
+
EventType[EventType["READY"] = 1] = "READY";
|
|
15
|
+
EventType[EventType["STARTED"] = 2] = "STARTED";
|
|
16
|
+
EventType[EventType["POS_UPDATE"] = 3] = "POS_UPDATE";
|
|
17
|
+
EventType[EventType["STOPPED"] = 4] = "STOPPED";
|
|
18
|
+
EventType[EventType["ENDED"] = 5] = "ENDED";
|
|
19
|
+
EventType[EventType["ERROR"] = 6] = "ERROR";
|
|
20
|
+
})(EventType || (EventType = {}));
|
|
21
|
+
export class AudioPlayerEvent {
|
|
22
|
+
constructor(type, timePosition) {
|
|
23
|
+
this._type = type;
|
|
24
|
+
this._timePosition = timePosition;
|
|
25
|
+
}
|
|
26
|
+
get type() {
|
|
27
|
+
return this._type;
|
|
28
|
+
}
|
|
29
|
+
get timePosition() {
|
|
30
|
+
return this._timePosition;
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
export class AudioPlayer {
|
|
34
|
+
get autoPlayOnSelectToggleAction() {
|
|
35
|
+
return this._autoPlayOnSelectToggleAction;
|
|
36
|
+
}
|
|
37
|
+
static { this.DEFAULT_BUFSIZE = 8192; }
|
|
38
|
+
constructor(listener) {
|
|
39
|
+
this.running = false;
|
|
40
|
+
this.context = null;
|
|
41
|
+
this.ready = false;
|
|
42
|
+
this._audioClip = null;
|
|
43
|
+
this._audioSource = null;
|
|
44
|
+
this.sourceBufferNode = null;
|
|
45
|
+
this.sourceAudioWorkletNode = null;
|
|
46
|
+
this.playStartTime = null;
|
|
47
|
+
this.timerVar = null;
|
|
48
|
+
this.listener = listener;
|
|
49
|
+
this.bufSize = AudioPlayer.DEFAULT_BUFSIZE;
|
|
50
|
+
this.n = navigator;
|
|
51
|
+
this.buffPos = 0;
|
|
52
|
+
this.zeroBufCnt = 0;
|
|
53
|
+
this.zb = new Float32Array(this.bufSize);
|
|
54
|
+
this._startAction = new Action('Start');
|
|
55
|
+
this._startAction.disabled = true;
|
|
56
|
+
this._startAction.onAction = () => this.start();
|
|
57
|
+
this._startSelectionAction = new Action('Start selected');
|
|
58
|
+
this._startSelectionAction.disabled = true;
|
|
59
|
+
this._startSelectionAction.onAction = () => this.startSelected();
|
|
60
|
+
this._autoPlayOnSelectToggleAction = new Action("Autoplay on select", false);
|
|
61
|
+
this._stopAction = new Action('Stop');
|
|
62
|
+
this._stopAction.disabled = true;
|
|
63
|
+
this._stopAction.onAction = () => this.stop();
|
|
64
|
+
}
|
|
65
|
+
_audioContext() {
|
|
66
|
+
if (!this.context) {
|
|
67
|
+
this.context = AudioContextProvider.audioContextInstance();
|
|
68
|
+
if (this.context) {
|
|
69
|
+
this.context.addEventListener('statechange', (ev) => {
|
|
70
|
+
if (this.context && this.context.state !== 'running') {
|
|
71
|
+
this.stop();
|
|
72
|
+
}
|
|
73
|
+
});
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
return this.context;
|
|
77
|
+
}
|
|
78
|
+
get startAction() {
|
|
79
|
+
return this._startAction;
|
|
80
|
+
}
|
|
81
|
+
get startSelectionAction() {
|
|
82
|
+
return this._startSelectionAction;
|
|
83
|
+
}
|
|
84
|
+
get stopAction() {
|
|
85
|
+
return this._stopAction;
|
|
86
|
+
}
|
|
87
|
+
set audioClip(audioClip) {
|
|
88
|
+
this._audioClip = audioClip;
|
|
89
|
+
let length = 0;
|
|
90
|
+
let chs = 0;
|
|
91
|
+
if (audioClip && audioClip.audioDataHolder) {
|
|
92
|
+
let audioDataHolder = audioClip.audioDataHolder;
|
|
93
|
+
chs = audioDataHolder.numberOfChannels;
|
|
94
|
+
if (chs > 0) {
|
|
95
|
+
length = audioDataHolder.frameLen;
|
|
96
|
+
//if (chs > this.context.destination.maxChannelCount) {
|
|
97
|
+
// // TODO exception
|
|
98
|
+
//}
|
|
99
|
+
}
|
|
100
|
+
this.audioSource = audioDataHolder.audioSource;
|
|
101
|
+
audioClip.addSelectionObserver((ac) => {
|
|
102
|
+
this._startSelectionAction.disabled = this.startSelectionDisabled();
|
|
103
|
+
if (!this.startSelectionAction.disabled && this._autoPlayOnSelectToggleAction.value) {
|
|
104
|
+
this.startSelected();
|
|
105
|
+
}
|
|
106
|
+
});
|
|
107
|
+
}
|
|
108
|
+
else {
|
|
109
|
+
this.audioSource = null;
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
get audioSource() {
|
|
113
|
+
return this._audioSource;
|
|
114
|
+
}
|
|
115
|
+
set audioSource(value) {
|
|
116
|
+
this.stop();
|
|
117
|
+
this._audioSource = value;
|
|
118
|
+
if (this._audioSource) {
|
|
119
|
+
this.ready = true;
|
|
120
|
+
this.updateStartActions();
|
|
121
|
+
if (this.listener) {
|
|
122
|
+
this.listener.audioPlayerUpdate(new AudioPlayerEvent(EventType.READY));
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
else {
|
|
126
|
+
this.ready = false;
|
|
127
|
+
this.updateStartActions();
|
|
128
|
+
if (this.listener) {
|
|
129
|
+
this.listener.audioPlayerUpdate(new AudioPlayerEvent(EventType.CLOSED));
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
_loadSourceWorkletAndInitStart() {
|
|
134
|
+
if (this.context) {
|
|
135
|
+
AudioSourceWorkletModuleLoader.loadModule(this.context).then(() => {
|
|
136
|
+
//console.debug("Player ready. ( by Player::_loadSourceWorkletAndInitStart()");
|
|
137
|
+
this.ready = true;
|
|
138
|
+
this.updateStartActions();
|
|
139
|
+
if (this.listener) {
|
|
140
|
+
this.listener.audioPlayerUpdate(new AudioPlayerEvent(EventType.READY));
|
|
141
|
+
}
|
|
142
|
+
}).catch((error) => {
|
|
143
|
+
this.ready = false;
|
|
144
|
+
this.updateStartActions();
|
|
145
|
+
if (this.listener) {
|
|
146
|
+
this.listener.audioPlayerUpdate(new AudioPlayerEvent(EventType.CLOSED));
|
|
147
|
+
}
|
|
148
|
+
console.error('Could not add module ' + error);
|
|
149
|
+
});
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
_startAudioSourceWorkletNode() {
|
|
153
|
+
this._loadSourceWorkletAndInitStart();
|
|
154
|
+
if (this.context && this.sourceAudioWorkletNode) {
|
|
155
|
+
this.sourceAudioWorkletNode.onprocessorerror = (ev) => {
|
|
156
|
+
let msg = 'Unknwon error';
|
|
157
|
+
if (ev instanceof ErrorEvent) {
|
|
158
|
+
msg = ev.message;
|
|
159
|
+
}
|
|
160
|
+
console.error("Audio source worklet error: " + msg);
|
|
161
|
+
if (this.listener) {
|
|
162
|
+
// TODO
|
|
163
|
+
// this.listener.error(msg);
|
|
164
|
+
// this.listener.audioPlayerUpdate(new AudioPlayerEvent());
|
|
165
|
+
}
|
|
166
|
+
};
|
|
167
|
+
this.sourceAudioWorkletNode.connect(this.context.destination); // this already starts playing
|
|
168
|
+
this.sourceAudioWorkletNode.onended = () => this.onended();
|
|
169
|
+
this.running = true;
|
|
170
|
+
this.sourceAudioWorkletNode.start();
|
|
171
|
+
//console.debug("Playback start action enabled. ( by Player::_startAudioSourceWorkletNode()");
|
|
172
|
+
this._startAction.disabled = true;
|
|
173
|
+
this._startSelectionAction.disabled = true;
|
|
174
|
+
this._stopAction.disabled = false;
|
|
175
|
+
if (this.listener) {
|
|
176
|
+
this.listener.audioPlayerUpdate(new AudioPlayerEvent(EventType.STARTED));
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
start() {
|
|
181
|
+
this._audioContext();
|
|
182
|
+
if (this.context) {
|
|
183
|
+
if (!this._startAction.disabled && !this.running) {
|
|
184
|
+
if (this.context.state === 'suspended') {
|
|
185
|
+
this.context.resume().then(() => {
|
|
186
|
+
this._start();
|
|
187
|
+
}).catch((reason) => {
|
|
188
|
+
console.error(reason.message());
|
|
189
|
+
throw reason;
|
|
190
|
+
});
|
|
191
|
+
}
|
|
192
|
+
else if (this.context.state === 'closed') {
|
|
193
|
+
const msg = 'Error: Cannot start playback. Audio context is already closed!';
|
|
194
|
+
console.error(msg);
|
|
195
|
+
throw new Error(msg);
|
|
196
|
+
}
|
|
197
|
+
else {
|
|
198
|
+
this._start();
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
updateStartActions() {
|
|
204
|
+
if (this.ready) {
|
|
205
|
+
if (this._audioSource instanceof AudioBufferSource || this._audioSource instanceof ArrayAudioBuffer || this._audioSource instanceof IndexedDbAudioBuffer) {
|
|
206
|
+
this._startAction.disabled = false;
|
|
207
|
+
this._startSelectionAction.disabled = this.startSelectionDisabled();
|
|
208
|
+
}
|
|
209
|
+
else {
|
|
210
|
+
if (this._audioSource instanceof NetAudioBuffer) {
|
|
211
|
+
this._audioSource.addOnReadyListener(() => {
|
|
212
|
+
this._startAction.disabled = false;
|
|
213
|
+
this._startSelectionAction.disabled = this.startSelectionDisabled();
|
|
214
|
+
});
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
else {
|
|
219
|
+
this._startAction.disabled = true;
|
|
220
|
+
this._startSelectionAction.disabled = true;
|
|
221
|
+
}
|
|
222
|
+
}
|
|
223
|
+
startSelectionDisabled() {
|
|
224
|
+
return !(this._audioClip && !this.startAction.disabled && this._audioClip.selection);
|
|
225
|
+
}
|
|
226
|
+
_start(playSelection = false) {
|
|
227
|
+
if (!this.context) {
|
|
228
|
+
throw new Error("Could not get audio context!");
|
|
229
|
+
}
|
|
230
|
+
if (this._audioSource instanceof AudioBufferSource) {
|
|
231
|
+
this.sourceBufferNode = this.context.createBufferSource();
|
|
232
|
+
this.sourceBufferNode.buffer = this._audioSource.audioBuffer;
|
|
233
|
+
this.sourceBufferNode.connect(this.context.destination);
|
|
234
|
+
this.sourceBufferNode.onended = () => this.onended();
|
|
235
|
+
this.playStartTime = this.context.currentTime;
|
|
236
|
+
this.running = true;
|
|
237
|
+
// unfortunately Web Audio API uses time values not frames
|
|
238
|
+
const ac = this._audioClip;
|
|
239
|
+
let offset = 0;
|
|
240
|
+
if (playSelection && ac && ac.selection) {
|
|
241
|
+
const s = ac.selection;
|
|
242
|
+
const sr = ac.audioDataHolder.sampleRate;
|
|
243
|
+
offset = s.leftFrame / sr;
|
|
244
|
+
const stopPosInsecs = s.rightFrame / sr;
|
|
245
|
+
const dur = stopPosInsecs - offset;
|
|
246
|
+
this.sourceBufferNode.start(0, offset, dur);
|
|
247
|
+
}
|
|
248
|
+
else {
|
|
249
|
+
this.sourceBufferNode.start();
|
|
250
|
+
}
|
|
251
|
+
this.playStartTime = this.context.currentTime - offset;
|
|
252
|
+
this._startAction.disabled = true;
|
|
253
|
+
this._startSelectionAction.disabled = true;
|
|
254
|
+
this._stopAction.disabled = false;
|
|
255
|
+
if (this.listener) {
|
|
256
|
+
this.listener.audioPlayerUpdate(new AudioPlayerEvent(EventType.STARTED));
|
|
257
|
+
}
|
|
258
|
+
}
|
|
259
|
+
else if (this._audioSource instanceof ArrayAudioBuffer || this._audioSource instanceof IndexedDbAudioBuffer || this._audioSource instanceof NetAudioBuffer) {
|
|
260
|
+
AudioSourceWorkletModuleLoader.loadModule(this.context).then(() => {
|
|
261
|
+
this.playStartTime = null;
|
|
262
|
+
if (this.context) {
|
|
263
|
+
if (this._audioSource instanceof ArrayAudioBuffer) {
|
|
264
|
+
const aabsn = new ArrayAudioBufferSourceNode(this.context);
|
|
265
|
+
aabsn.arrayAudioBuffer = this._audioSource;
|
|
266
|
+
this.sourceAudioWorkletNode = aabsn;
|
|
267
|
+
}
|
|
268
|
+
else if (this._audioSource instanceof IndexedDbAudioBuffer) {
|
|
269
|
+
const iasn = new IndexedDbAudioBufferSourceNode(this.context);
|
|
270
|
+
iasn.inddbAudioBuffer = this._audioSource;
|
|
271
|
+
this.sourceAudioWorkletNode = iasn;
|
|
272
|
+
}
|
|
273
|
+
else if (this._audioSource instanceof NetAudioBuffer) {
|
|
274
|
+
const nabsn = new NetAudioBufferSourceNode(this.context);
|
|
275
|
+
nabsn.netAudioBuffer = this._audioSource;
|
|
276
|
+
this.sourceAudioWorkletNode = nabsn;
|
|
277
|
+
}
|
|
278
|
+
if (this.sourceAudioWorkletNode) {
|
|
279
|
+
this.sourceAudioWorkletNode.onprocessorerror = (ev) => {
|
|
280
|
+
let msg = 'Unknwon error';
|
|
281
|
+
if (ev instanceof ErrorEvent) {
|
|
282
|
+
msg = ev.message;
|
|
283
|
+
}
|
|
284
|
+
console.error("Audio source worklet error: " + msg);
|
|
285
|
+
if (this.listener) {
|
|
286
|
+
this.listener.audioPlayerUpdate(new AudioPlayerEvent(EventType.ERROR));
|
|
287
|
+
}
|
|
288
|
+
};
|
|
289
|
+
this.sourceAudioWorkletNode.connect(this.context.destination); // this already starts playing
|
|
290
|
+
this.sourceAudioWorkletNode.onended = () => this.onended();
|
|
291
|
+
this.running = true;
|
|
292
|
+
const ac = this._audioClip;
|
|
293
|
+
let offset = 0;
|
|
294
|
+
if (playSelection && ac && ac.selection) {
|
|
295
|
+
const s = ac.selection;
|
|
296
|
+
const sr = ac.audioDataHolder.sampleRate;
|
|
297
|
+
offset = s.leftFrame / sr;
|
|
298
|
+
const stopPosInsecs = s.rightFrame / sr;
|
|
299
|
+
const dur = stopPosInsecs - offset;
|
|
300
|
+
this.sourceAudioWorkletNode.start(0, offset, dur);
|
|
301
|
+
}
|
|
302
|
+
else {
|
|
303
|
+
this.sourceAudioWorkletNode.start();
|
|
304
|
+
}
|
|
305
|
+
//this.playStartTime = this.context.currentTime - offset;
|
|
306
|
+
this._startAction.disabled = true;
|
|
307
|
+
this._startSelectionAction.disabled = true;
|
|
308
|
+
this._stopAction.disabled = false;
|
|
309
|
+
if (this.listener) {
|
|
310
|
+
this.listener.audioPlayerUpdate(new AudioPlayerEvent(EventType.STARTED));
|
|
311
|
+
}
|
|
312
|
+
}
|
|
313
|
+
}
|
|
314
|
+
}).catch((error) => {
|
|
315
|
+
console.error(error.message);
|
|
316
|
+
this.ready = false;
|
|
317
|
+
this.updateStartActions();
|
|
318
|
+
if (this.listener) {
|
|
319
|
+
this.listener.audioPlayerUpdate(new AudioPlayerEvent(EventType.CLOSED));
|
|
320
|
+
}
|
|
321
|
+
throw error;
|
|
322
|
+
});
|
|
323
|
+
}
|
|
324
|
+
}
|
|
325
|
+
startSelected() {
|
|
326
|
+
this._audioContext();
|
|
327
|
+
if (!this.context) {
|
|
328
|
+
throw new Error("Could not get audio context!");
|
|
329
|
+
}
|
|
330
|
+
if (!this._startAction.disabled && !this.running) {
|
|
331
|
+
if (this.context.state === 'suspended') {
|
|
332
|
+
this.context.resume().then(() => {
|
|
333
|
+
this._start(true);
|
|
334
|
+
}).catch((reason) => {
|
|
335
|
+
console.error(reason.message);
|
|
336
|
+
throw reason;
|
|
337
|
+
});
|
|
338
|
+
}
|
|
339
|
+
else if (this.context.state === 'closed') {
|
|
340
|
+
const msg = 'Error: Cannot start playback of selection. Audio context is already closed!';
|
|
341
|
+
console.error(msg);
|
|
342
|
+
throw new Error(msg);
|
|
343
|
+
}
|
|
344
|
+
else {
|
|
345
|
+
this._start(true);
|
|
346
|
+
}
|
|
347
|
+
}
|
|
348
|
+
}
|
|
349
|
+
stop() {
|
|
350
|
+
if (this.running) {
|
|
351
|
+
if (this.sourceBufferNode) {
|
|
352
|
+
this.sourceBufferNode.stop();
|
|
353
|
+
}
|
|
354
|
+
if (this.sourceAudioWorkletNode) {
|
|
355
|
+
this.sourceAudioWorkletNode.stop();
|
|
356
|
+
}
|
|
357
|
+
if (this.timerVar !== null) {
|
|
358
|
+
window.clearInterval(this.timerVar);
|
|
359
|
+
}
|
|
360
|
+
this.running = false;
|
|
361
|
+
if (this.listener) {
|
|
362
|
+
this.listener.audioPlayerUpdate(new AudioPlayerEvent(EventType.STOPPED));
|
|
363
|
+
}
|
|
364
|
+
}
|
|
365
|
+
}
|
|
366
|
+
onended() {
|
|
367
|
+
if (this.timerVar != null) {
|
|
368
|
+
window.clearInterval(this.timerVar);
|
|
369
|
+
}
|
|
370
|
+
this._startAction.disabled = !this._audioSource;
|
|
371
|
+
this._startSelectionAction.disabled = this.startSelectionDisabled();
|
|
372
|
+
this._stopAction.disabled = true;
|
|
373
|
+
this.running = false;
|
|
374
|
+
if (this.listener) {
|
|
375
|
+
this.listener.audioPlayerUpdate(new AudioPlayerEvent(EventType.ENDED));
|
|
376
|
+
}
|
|
377
|
+
}
|
|
378
|
+
get playPositionTime() {
|
|
379
|
+
let ppt = null;
|
|
380
|
+
if (this.context && this.playStartTime !== null) {
|
|
381
|
+
ppt = this.context.currentTime - this.playStartTime;
|
|
382
|
+
}
|
|
383
|
+
else if (this.sourceAudioWorkletNode) {
|
|
384
|
+
ppt = this.sourceAudioWorkletNode.playPositionTime;
|
|
385
|
+
}
|
|
386
|
+
return ppt;
|
|
387
|
+
}
|
|
388
|
+
get playPositionFrames() {
|
|
389
|
+
let ppFrs = null;
|
|
390
|
+
if (this._audioSource) {
|
|
391
|
+
let sr = this._audioSource.sampleRate;
|
|
392
|
+
if (sr) {
|
|
393
|
+
let ppTime = this.playPositionTime;
|
|
394
|
+
if (ppTime !== null) {
|
|
395
|
+
ppFrs = sr * ppTime;
|
|
396
|
+
}
|
|
397
|
+
}
|
|
398
|
+
}
|
|
399
|
+
return ppFrs;
|
|
400
|
+
}
|
|
401
|
+
}
|
|
402
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicGxheWVyLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vLi4vcHJvamVjdHMvc3BlZWNocmVjb3JkZXJuZy9zcmMvbGliL2F1ZGlvL3BsYXliYWNrL3BsYXllci50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsTUFBTSxFQUFFLE1BQU0scUJBQXFCLENBQUE7QUFFNUMsT0FBTyxFQUFDLGdCQUFnQixFQUFDLE1BQU0sdUJBQXVCLENBQUM7QUFDdkQsT0FBTyxFQUFDLDBCQUEwQixFQUFDLE1BQU0sa0NBQWtDLENBQUM7QUFDNUUsT0FBTyxFQUFDLG9CQUFvQixFQUFDLE1BQU0sdUJBQXVCLENBQUM7QUFDM0QsT0FBTyxFQUFDLDhCQUE4QixFQUFDLE1BQU0sc0NBQXNDLENBQUM7QUFDcEYsT0FBTyxFQUFDLDhCQUE4QixFQUFDLE1BQU0sa0NBQWtDLENBQUM7QUFFaEYsT0FBTyxFQUFDLGNBQWMsRUFBQyxNQUFNLHFCQUFxQixDQUFDO0FBQ25ELE9BQU8sRUFBQyx3QkFBd0IsRUFBQyxNQUFNLGdDQUFnQyxDQUFDO0FBQ3hFLE9BQU8sRUFBQyxpQkFBaUIsRUFBYyxNQUFNLHNCQUFzQixDQUFDO0FBQ3BFLE9BQU8sRUFBQyxvQkFBb0IsRUFBQyxNQUFNLFlBQVksQ0FBQztBQUk1QyxNQUFNLENBQU4sSUFBYSxTQUFpRTtBQUE5RSxXQUFhLFNBQVM7SUFBRSw2Q0FBTSxDQUFBO0lBQUMsMkNBQUssQ0FBQTtJQUFDLCtDQUFPLENBQUE7SUFBQyxxREFBVSxDQUFBO0lBQUUsK0NBQU8sQ0FBQTtJQUFFLDJDQUFLLENBQUE7SUFBQywyQ0FBSyxDQUFBO0FBQUEsQ0FBQyxFQUFqRSxTQUFTLEtBQVQsU0FBUyxRQUF3RDtBQUU5RSxNQUFNLE9BQU8sZ0JBQWdCO0lBS3pCLFlBQVksSUFBYyxFQUFFLFlBQW9CO1FBQzVDLElBQUksQ0FBQyxLQUFLLEdBQUcsSUFBSSxDQUFDO1FBQ2xCLElBQUksQ0FBQyxh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XHJcbmltcG9ydCB7IEF1ZGlvQ2xpcCB9IGZyb20gJy4uL3BlcnNpc3RvcidcclxuaW1wb3J0IHtBcnJheUF1ZGlvQnVmZmVyfSBmcm9tIFwiLi4vYXJyYXlfYXVkaW9fYnVmZmVyXCI7XHJcbmltcG9ydCB7QXJyYXlBdWRpb0J1ZmZlclNvdXJjZU5vZGV9IGZyb20gXCIuL2FycmF5X2F1ZGlvX2J1ZmZlcl9zb3VyY2Vfbm9kZVwiO1xyXG5pbXBvcnQge0luZGV4ZWREYkF1ZGlvQnVmZmVyfSBmcm9tIFwiLi4vaW5kZGJfYXVkaW9fYnVmZmVyXCI7XHJcbmltcG9ydCB7QXVkaW9Tb3VyY2VXb3JrbGV0TW9kdWxlTG9hZGVyfSBmcm9tIFwiLi9hdWRpb19zb3VyY2Vfd29ya2xldF9tb2R1bGVfbG9hZGVyXCI7XHJcbmltcG9ydCB7SW5kZXhlZERiQXVkaW9CdWZmZXJTb3VyY2VOb2RlfSBmcm9tIFwiLi9pbmRkYl9hdWRpb19idWZmZXJfc291cmNlX25vZGVcIjtcclxuaW1wb3J0IHtBdWRpb1NvdXJjZU5vZGV9IGZyb20gXCIuL2F1ZGlvX3NvdXJjZV9ub2RlXCI7XHJcbmltcG9ydCB7TmV0QXVkaW9CdWZmZXJ9IGZyb20gXCIuLi9uZXRfYXVkaW9fYnVmZmVyXCI7XHJcbmltcG9ydCB7TmV0QXVkaW9CdWZmZXJTb3VyY2VOb2RlfSBmcm9tIFwiLi9uZXRfYXVkaW9fYnVmZmVyX3NvdXJjZV9ub2RlXCI7XHJcbmltcG9ydCB7QXVkaW9CdWZmZXJTb3VyY2UsIEF1ZGlvU291cmNlfSBmcm9tIFwiLi4vYXVkaW9fZGF0YV9ob2xkZXJcIjtcclxuaW1wb3J0IHtBdWRpb0NvbnRleHRQcm92aWRlcn0gZnJvbSBcIi4uL2NvbnRleHRcIjtcclxuXHJcblxyXG5cclxuICAgIGV4cG9ydCBlbnVtICBFdmVudFR5cGUge0NMT1NFRCxSRUFEWSxTVEFSVEVELFBPU19VUERBVEUsIFNUT1BQRUQsIEVOREVELEVSUk9SfVxyXG5cclxuICAgIGV4cG9ydCBjbGFzcyBBdWRpb1BsYXllckV2ZW50e1xyXG5cclxuICAgICAgICBwcml2YXRlIHJlYWRvbmx5IF90eXBlOkV2ZW50VHlwZTtcclxuICAgICAgICBwcml2YXRlIHJlYWRvbmx5IF90aW1lUG9zaXRpb246bnVtYmVyIHwgdW5kZWZpbmVkO1xyXG5cclxuICAgICAgICBjb25zdHJ1Y3Rvcih0eXBlOkV2ZW50VHlwZSwgdGltZVBvc2l0aW9uPzpudW1iZXIpIHtcclxuICAgICAgICAgICAgdGhpcy5fdHlwZSA9IHR5cGU7XHJcbiAgICAgICAgICAgIHRoaXMuX3RpbWVQb3NpdGlvbiA9IHRpbWVQb3NpdGlvbjtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIGdldCB0eXBlKCkge1xyXG4gICAgICAgICAgICByZXR1cm4gdGhpcy5fdHlwZTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIGdldCB0aW1lUG9zaXRpb24oKSB7XHJcbiAgICAgICAgICAgIHJldHVybiB0aGlzLl90aW1lUG9zaXRpb247XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG4gICAgZXhwb3J0IGludGVyZmFjZSBBdWRpb1BsYXllckxpc3RlbmVyIHtcclxuICAgICAgICBhdWRpb1BsYXllclVwZGF0ZShlOkF1ZGlvUGxheWVyRXZlbnQpOnZvaWQ7XHJcbiAgICB9XHJcblxyXG4gICAgZXhwb3J0IGNsYXNzIEF1ZGlvUGxheWVyIHtcclxuXHJcbiAgICAgICAgZ2V0IGF1dG9QbGF5T25TZWxlY3RUb2dnbGVBY3Rpb24oKTogQWN0aW9uPGJvb2xlYW4+IHtcclxuICAgICAgICAgICAgcmV0dXJuIHRoaXMuX2F1dG9QbGF5T25TZWxlY3RUb2dnbGVBY3Rpb247XHJcbiAgICAgICAgfVxyXG4gICAgICAgIHB1YmxpYyBzdGF0aWMgREVGQVVMVF9CVUZTSVpFOm51bWJlciA9IDgxOTI7XHJcbiAgICAgICAgcHJpdmF0ZSBydW5uaW5nPWZhbHNlO1xyXG4gICAgICAgIHByaXZhdGUgcmVhZG9ubHkgX3N0YXJ0QWN0aW9uOkFjdGlvbjx2b2lkPjtcclxuICAgICAgICBwcml2YXRlIHJlYWRvbmx5IF9zdGFydFNlbGVjdGlvbkFjdGlvbjpBY3Rpb248dm9pZD47XHJcbiAgICAgICAgcHJpdmF0ZSByZWFkb25seSBfYXV0b1BsYXlPblNlbGVjdFRvZ2dsZUFjdGlvbjpBY3Rpb248Ym9vbGVhbj47XHJcbiAgICAgICAgcHJpdmF0ZSByZWFkb25seSBfc3RvcEFjdGlvbjpBY3Rpb248dm9pZD47XHJcbiAgICAgICAgYnVmU2l6ZTpudW1iZXI7XHJcbiAgICAgICAgY29udGV4dDpBdWRpb0NvbnRleHR8bnVsbD1udWxsO1xyXG4gICAgICAgIHJlYWR5PWZhbHNlO1xyXG4gICAgICAgIGxpc3RlbmVyOkF1ZGlvUGxheWVyTGlzdGVuZXI7XHJcbiAgICAgICAgX2F1ZGlvQ2xpcDpBdWRpb0NsaXB8bnVsbD1udWxsO1xyXG4gICAgICAgIHByaXZhdGUgX2F1ZGlvU291cmNlOkF1ZGlvU291cmNlfG51bGw9bnVsbDtcclxuICAgICAgICBzb3VyY2VCdWZmZXJOb2RlOkF1ZGlvQnVmZmVyU291cmNlTm9kZXxudWxsPW51bGw7XHJcbiAgICAgICAgc291cmNlQXVkaW9Xb3JrbGV0Tm9kZTpBdWRpb1NvdXJjZU5vZGV8bnVsbD1udWxsO1xyXG5cclxuICAgICAgICBidWZmUG9zOm51bWJlcjtcclxuICAgICAgICBwcml2YXRlIHplcm9CdWZDbnQ6bnVtYmVyO1xyXG4gICAgICAgIG46YW55O1xyXG4gICAgICAgIHpiOkZsb2F0MzJBcnJheTtcclxuICAgICAgICBwcml2YXRlIHBsYXlTdGFydFRpbWU6bnVtYmVyfG51bGw9bnVsbDtcclxuXHJcbiAgICAgICAgcHJpdmF0ZSB0aW1lclZhcjpudW1iZXJ8bnVsbD1udWxsO1xyXG5cclxuICAgICAgICBjb25zdHJ1Y3RvcihsaXN0ZW5lcjpBdWRpb1BsYXllckxpc3RlbmVyKSB7XHJcbiAgICAgICAgICAgIHRoaXMubGlzdGVuZXI9bGlzdGVuZXI7XHJcbiAgICAgICAgICAgIHRoaXMuYnVmU2l6ZSA9IEF1ZGlvUGxheWVyLkRFRkFVTFRfQlVGU0laRTtcclxuICAgICAgICAgICAgdGhpcy5uPW5hdmlnYXRvcjtcclxuICAgICAgICAgICAgdGhpcy5idWZmUG9zPTA7XHJcbiAgICAgICAgICAgIHRoaXMuemVyb0J1ZkNudD0wO1xyXG4gICAgICAgICAgICB0aGlzLnpiID0gbmV3IEZsb2F0MzJBcnJheSh0aGlzLmJ1ZlNpemUpO1xyXG4gICAgICAgICAgICB0aGlzLl9zdGFydEFjdGlvbiA9IG5ldyBBY3Rpb24oJ1N0YXJ0Jyk7XHJcbiAgICAgICAgICAgIHRoaXMuX3N0YXJ0QWN0aW9uLmRpc2FibGVkID0gdHJ1ZTtcclxuICAgICAgICAgICAgdGhpcy5fc3RhcnRBY3Rpb24ub25BY3Rpb24gPSAoKT0+dGhpcy5zdGFydCgpO1xyXG4gICAgICAgICAgICB0aGlzLl9zdGFydFNlbGVjdGlvbkFjdGlvbj1uZXcgQWN0aW9uKCdTdGFydCBzZWxlY3RlZCcpXHJcbiAgICAgICAgICAgIHRoaXMuX3N0YXJ0U2VsZWN0aW9uQWN0aW9uLmRpc2FibGVkPXRydWVcclxuICAgICAgICAgICAgdGhpcy5fc3RhcnRTZWxlY3Rpb25BY3Rpb24ub25BY3Rpb24gPSAoKT0+dGhpcy5zdGFydFNlbGVjdGVkKCk7XHJcbiAgICAgICAgICAgIHRoaXMuX2F1dG9QbGF5T25TZWxlY3RUb2dnbGVBY3Rpb249bmV3IEFjdGlvbjxib29sZWFuPihcIkF1dG9wbGF5IG9uIHNlbGVjdFwiLGZhbHNlKTtcclxuICAgICAgICAgICAgdGhpcy5fc3RvcEFjdGlvbiA9IG5ldyBBY3Rpb24oJ1N0b3AnKTtcclxuICAgICAgICAgICAgdGhpcy5fc3RvcEFjdGlvbi5kaXNhYmxlZCA9IHRydWU7XHJcbiAgICAgICAgICAgIHRoaXMuX3N0b3BBY3Rpb24ub25BY3Rpb24gPSAoKT0+dGhpcy5zdG9wKCk7XHJcblxyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgcHJpdmF0ZSBfYXVkaW9Db250ZXh0KCk6QXVkaW9Db250ZXh0fG51bGx7XHJcbiAgICAgICAgICAgIGlmKCF0aGlzLmNvbnRleHQpe1xyXG4gICAgICAgICAgICAgICAgdGhpcy5jb250ZXh0PUF1ZGlvQ29udGV4dFByb3ZpZGVyLmF1ZGlvQ29udGV4dEluc3RhbmNlKCk7XHJcbiAgICAgICAgICAgICAgICBpZih0aGlzLmNvbnRleHQpIHtcclxuICAgICAgICAgICAgICAgICAgICB0aGlzLmNvbnRleHQuYWRkRXZlbnRMaXN0ZW5lcignc3RhdGVjaGFuZ2UnLCAoZXYpID0+IHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmKHRoaXMuY29udGV4dCAmJiB0aGlzLmNvbnRleHQuc3RhdGUhPT0ncnVubmluZycpe1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuc3RvcCgpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgKTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICByZXR1cm4gdGhpcy5jb250ZXh0O1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgZ2V0IHN0YXJ0QWN0aW9uKCkge1xyXG4gICAgICAgICAgICByZXR1cm4gdGhpcy5fc3RhcnRBY3Rpb247XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICBnZXQgc3RhcnRTZWxlY3Rpb25BY3Rpb24oKXtcclxuICAgICAgICAgIHJldHVybiB0aGlzLl9zdGFydFNlbGVjdGlvbkFjdGlvblxyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgZ2V0IHN0b3BBY3Rpb24oKSB7XHJcbiAgICAgICAgICAgIHJldHVybiB0aGlzLl9zdG9wQWN0aW9uO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgc2V0IGF1ZGlvQ2xpcChhdWRpb0NsaXA6QXVkaW9DbGlwfCBudWxsKSB7XHJcbiAgICAgICAgICB0aGlzLl9hdWRpb0NsaXA9YXVkaW9DbGlwXHJcbiAgICAgICAgICAgIGxldCBsZW5ndGggPSAwO1xyXG4gICAgICAgICAgICBsZXQgY2hzID0gMDtcclxuICAgICAgICAgICAgaWYgKGF1ZGlvQ2xpcCAmJiBhdWRpb0NsaXAuYXVkaW9EYXRhSG9sZGVyKSB7XHJcbiAgICAgICAgICAgICAgICBsZXQgYXVkaW9EYXRhSG9sZGVyPWF1ZGlvQ2xpcC5hdWRpb0RhdGFIb2xkZXI7XHJcbiAgICAgICAgICAgICAgICBjaHMgPSBhdWRpb0RhdGFIb2xkZXIubnVtYmVyT2ZDaGFubmVsc1xyXG4gICAgICAgICAgICAgICAgaWYgKGNocyA+IDApIHtcclxuICAgICAgICAgICAgICAgICAgICBsZW5ndGggPSBhdWRpb0RhdGFIb2xkZXIuZnJhbWVMZW47XHJcbiAgICAgICAgICAgICAgICAgICAgLy9pZiAoY2hzID4gdGhpcy5jb250ZXh0LmRlc3RpbmF0aW9uLm1heENoYW5uZWxDb3VudCkge1xyXG4gICAgICAgICAgICAgICAgICAgIC8vICAgIC8vIFRPRE8gZXhjZXB0aW9uXHJcbiAgICAgICAgICAgICAgICAgICAgLy99XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICB0aGlzLmF1ZGlvU291cmNlPWF1ZGlvRGF0YUhvbGRlci5hdWRpb1NvdXJjZTtcclxuXHJcbiAgICAgICAgICAgICAgICBhdWRpb0NsaXAuYWRkU2VsZWN0aW9uT2JzZXJ2ZXIoKGFjKT0+IHtcclxuICAgICAgICAgICAgICAgICAgICB0aGlzLl9zdGFydFNlbGVjdGlvbkFjdGlvbi5kaXNhYmxlZCA9IHRoaXMuc3RhcnRTZWxlY3Rpb25EaXNhYmxlZCgpO1xyXG4gICAgICAgICAgICAgICAgICAgIGlmICghdGhpcy5zdGFydFNlbGVjdGlvbkFjdGlvbi5kaXNhYmxlZCAmJiB0aGlzLl9hdXRvUGxheU9uU2VsZWN0VG9nZ2xlQWN0aW9uLnZhbHVlKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICB0aGlzLnN0YXJ0U2VsZWN0ZWQoKTtcclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIClcclxuICAgICAgICAgICAgfWVsc2V7XHJcbiAgICAgICAgICAgICAgICB0aGlzLmF1ZGlvU291cmNlPW51bGw7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9XHJcblxyXG4gICAgICBnZXQgYXVkaW9Tb3VyY2UoKTogQXVkaW9Tb3VyY2UgfCBudWxsIHtcclxuICAgICAgICByZXR1cm4gdGhpcy5fYXVkaW9Tb3VyY2U7XHJcbiAgICAgIH1cclxuXHJcbiAgICAgIHNldCBhdWRpb1NvdXJjZSh2YWx1ZTogQXVkaW9Tb3VyY2UgfCBudWxsKSB7XHJcbiAgICAgICAgdGhpcy5zdG9wKCk7XHJcbiAgICAgICAgdGhpcy5fYXVkaW9Tb3VyY2UgPSB2YWx1ZTtcclxuICAgICAgICAgICAgaWYgKHRoaXMuX2F1ZGlvU291cmNlKSB7XHJcblxyXG4gICAgICAgICAgICAgICAgdGhpcy5yZWFkeSA9IHRydWU7XHJcbiAgICAgICAgICAgICAgICB0aGlzLnVwZGF0ZVN0YXJ0QWN0aW9ucygpO1xyXG4gICAgICAgICAgICAgICAgaWYgKHRoaXMubGlzdGVuZXIpIHtcclxuICAgICAgICAgICAgICAgICAgICB0aGlzLmxpc3RlbmVyLmF1ZGlvUGxheWVyVXBkYXRlKG5ldyBBdWRpb1BsYXllckV2ZW50KEV2ZW50VHlwZS5SRUFEWSkpO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB9ZWxzZSB7XHJcbiAgICAgICAgICAgICAgdGhpcy5yZWFkeSA9IGZhbHNlO1xyXG4gICAgICAgICAgICAgIHRoaXMudXBkYXRlU3RhcnRBY3Rpb25zKCk7XHJcbiAgICAgICAgICAgICAgaWYgKHRoaXMubGlzdGVuZXIpIHtcclxuICAgICAgICAgICAgICAgIHRoaXMubGlzdGVuZXIuYXVkaW9QbGF5ZXJVcGRhdGUobmV3IEF1ZGlvUGxheWVyRXZlbnQoRXZlbnRUeXBlLkNMT1NFRCkpO1xyXG4gICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgfVxyXG4gICAgICB9XHJcblxyXG4gICAgICAgIHByaXZhdGUgX2xvYWRTb3VyY2VXb3JrbGV0QW5kSW5pdFN0YXJ0KCl7XHJcbiAgICAgICAgICAgIGlmKHRoaXMuY29udGV4dCkge1xyXG4gICAgICAgICAgICAgICAgQXVkaW9Tb3VyY2VXb3JrbGV0TW9kdWxlTG9hZGVyLmxvYWRNb2R1bGUodGhpcy5jb250ZXh0KS50aGVuKCgpID0+IHtcclxuICAgICAgICAgICAgICAgICAgICAvL2NvbnNvbGUuZGVidWcoXCJQbGF5ZXIgcmVhZHkuICggYnkgUGxheWVyOjpfbG9hZFNvdXJjZVdvcmtsZXRBbmRJbml0U3RhcnQoKVwiKTtcclxuICAgICAgICAgICAgICAgICAgICB0aGlzLnJlYWR5ID0gdHJ1ZTtcclxuICAgICAgICAgICAgICAgICAgICB0aGlzLnVwZGF0ZVN0YXJ0QWN0aW9ucygpO1xyXG4gICAgICAgICAgICAgICAgICAgIGlmICh0aGlzLmxpc3RlbmVyKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMubGlzdGVuZXIuYXVkaW9QbGF5ZXJVcGRhdGUobmV3IEF1ZGlvUGxheWVyRXZlbnQoRXZlbnRUeXBlLlJFQURZKSk7XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgfSkuY2F0Y2goKGVycm9yOiBhbnkpID0+IHtcclxuICAgICAgICAgICAgICAgICAgICB0aGlzLnJlYWR5ID0gZmFsc2U7XHJcbiAgICAgICAgICAgICAgICAgICAgdGhpcy51cGRhdGVTdGFydEFjdGlvbnMoKTtcclxuICAgICAgICAgICAgICAgICAgICBpZiAodGhpcy5saXN0ZW5lcikge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmxpc3RlbmVyLmF1ZGlvUGxheWVyVXBkYXRlKG5ldyBBdWRpb1BsYXllckV2ZW50KEV2ZW50VHlwZS5DTE9TRUQpKTtcclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgY29uc29sZS5lcnJvcignQ291bGQgbm90IGFkZCBtb2R1bGUgJyArIGVycm9yKTtcclxuICAgICAgICAgICAgICAgIH0pO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG5cclxuXHJcbiAgcHJpdmF0ZSBfc3RhcnRBdWRpb1NvdXJjZVdvcmtsZXROb2RlKCl7XHJcbiAgICAgIHRoaXMuX2xvYWRTb3VyY2VXb3JrbGV0QW5kSW5pdFN0YXJ0KCk7XHJcbiAgICAgICAgICBpZih0aGlzLmNvbnRleHQgJiYgdGhpcy5zb3VyY2VBdWRpb1dvcmtsZXROb2RlKSB7XHJcbiAgICAgICAgICAgIHRoaXMuc291cmNlQXVkaW9Xb3JrbGV0Tm9kZS5vbnByb2Nlc3NvcmVycm9yID0gKGV2OiBFdmVudCkgPT4ge1xyXG4gICAgICAgICAgICAgIGxldCBtc2cgPSAnVW5rbndvbiBlcnJvcic7XHJcbiAgICAgICAgICAgICAgaWYgKGV2IGluc3RhbmNlb2YgRXJyb3JFdmVudCkge1xyXG4gICAgICAgICAgICAgICAgbXNnID0gZXYubWVzc2FnZTtcclxuICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgY29uc29sZS5lcnJvcihcIkF1ZGlvIHNvdXJjZSB3b3JrbGV0IGVycm9yOiBcIiArIG1zZyk7XHJcbiAgICAgICAgICAgICAgaWYgKHRoaXMubGlzdGVuZXIpIHtcclxuICAgICAgICAgICAgICAgIC8vIFRPRE9cclxuICAgICAgICAgICAgICAgIC8vIHRoaXMubGlzdGVuZXIuZXJyb3IobXNnKTtcclxuICAgICAgICAgICAgICAgIC8vIHRoaXMubGlzdGVuZXIuYXVkaW9QbGF5ZXJVcGRhdGUobmV3IEF1ZGlvUGxheWVyRXZlbnQoKSk7XHJcbiAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB9O1xyXG5cclxuICAgICAgICAgICAgdGhpcy5zb3VyY2VBdWRpb1dvcmtsZXROb2RlLmNvbm5lY3QodGhpcy5jb250ZXh0LmRlc3RpbmF0aW9uKTsgLy8gdGhpcyBhbHJlYWR5IHN0YXJ0cyBwbGF5aW5nXHJcbiAgICAgICAgICAgIHRoaXMuc291cmNlQXVkaW9Xb3JrbGV0Tm9kZS5vbmVuZGVkID0gKCkgPT4gdGhpcy5vbmVuZGVkKCk7XHJcbiAgICAgICAgICAgIHRoaXMucnVubmluZyA9IHRydWU7XHJcbiAgICAgICAgICAgIHRoaXMuc291cmNlQXVkaW9Xb3JrbGV0Tm9kZS5zdGFydCgpO1xyXG4gICAgICAgICAgICAvL2NvbnNvbGUuZGVidWcoXCJQbGF5YmFjayBzdGFydCBhY3Rpb24gZW5hYmxlZC4gKCBieSBQbGF5ZXI6Ol9zdGFydEF1ZGlvU291cmNlV29ya2xldE5vZGUoKVwiKTtcclxuICAgICAgICAgICAgdGhpcy5fc3RhcnRBY3Rpb24uZGlzYWJsZWQgPSB0cnVlO1xyXG4gICAgICAgICAgICB0aGlzLl9zdGFydFNlbGVjdGlvbkFjdGlvbi5kaXNhYmxlZCA9IHRydWVcclxuICAgICAgICAgICAgdGhpcy5fc3RvcEFjdGlvbi5kaXNhYmxlZCA9IGZhbHNlO1xyXG5cclxuICAgICAgICAgICAgaWYgKHRoaXMubGlzdGVuZXIpIHtcclxuICAgICAgICAgICAgICB0aGlzLmxpc3RlbmVyLmF1ZGlvUGxheWVyVXBkYXRlKG5ldyBBdWRpb1BsYXllckV2ZW50KEV2ZW50VHlwZS5TVEFSVEVEKSk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgIH1cclxuXHJcbiAgfVxyXG5cclxuICAgICAgICBzdGFydCgpIHtcclxuXHJcbiAgICAgICAgICAgIHRoaXMuX2F1ZGlvQ29udGV4dCgpO1xyXG5cclxuICAgICAgICAgICAgaWYodGhpcy5jb250ZXh0KSB7XHJcbiAgICAgICAgICAgICAgICBpZiAoIXRoaXMuX3N0YXJ0QWN0aW9uLmRpc2FibGVkICYmICF0aGlzLnJ1bm5pbmcpIHtcclxuICAgICAgICAgICAgICAgICAgICBpZiAodGhpcy5jb250ZXh0LnN0YXRlID09PSAnc3VzcGVuZGVkJykge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmNvbnRleHQucmVzdW1lKCkudGhlbigoKSA9PiB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLl9zdGFydCgpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB9KS5jYXRjaCgocmVhc29uKSA9PiB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zb2xlLmVycm9yKHJlYXNvbi5tZXNzYWdlKCkpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3cgcmVhc29uO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB9KVxyXG4gICAgICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAodGhpcy5jb250ZXh0LnN0YXRlID09PSAnY2xvc2VkJykge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBtc2cgPSAnRXJyb3I6IENhbm5vdCBzdGFydCBwbGF5YmFjay4gQXVkaW8gY29udGV4dCBpcyBhbHJlYWR5IGNsb3NlZCEnO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zb2xlLmVycm9yKG1zZyk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihtc2cpO1xyXG4gICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuX3N0YXJ0KCk7XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICB1cGRhdGVTdGFydEFjdGlvbnMoKXtcclxuXHJcbiAgICAgICAgICBpZih0aGlzLnJlYWR5KXtcclxuICAgICAgICAgICAgaWYodGhpcy5fYXVkaW9Tb3VyY2UgaW5zdGFuY2VvZiBBdWRpb0J1ZmZlclNvdXJjZSB8fCB0aGlzLl9hdWRpb1NvdXJjZSBpbnN0YW5jZW9mIEFycmF5QXVkaW9CdWZmZXIgfHwgdGhpcy5fYXVkaW9Tb3VyY2UgaW5zdGFuY2VvZiBJbmRleGVkRGJBdWRpb0J1ZmZlcil7XHJcbiAgICAgICAgICAgICAgdGhpcy5fc3RhcnRBY3Rpb24uZGlzYWJsZWQ9ZmFsc2U7XHJcbiAgICAgICAgICAgICAgdGhpcy5fc3RhcnRTZWxlY3Rpb25BY3Rpb24uZGlzYWJsZWQ9dGhpcy5zdGFydFNlbGVjdGlvbkRpc2FibGVkKCk7XHJcbiAgICAgICAgICAgIH1lbHNle1xyXG4gICAgICAgICAgICAgIGlmKHRoaXMuX2F1ZGlvU291cmNlIGluc3RhbmNlb2YgTmV0QXVkaW9CdWZmZXIpe1xyXG4gICAgICAgICAgICAgICAgdGhpcy5fYXVkaW9Tb3VyY2UuYWRkT25SZWFkeUxpc3RlbmVyKCgpPT57XHJcbiAgICAgICAgICAgICAgICAgIHRoaXMuX3N0YXJ0QWN0aW9uLmRpc2FibGVkPWZhbHNlO1xyXG4gICAgICAgICAgICAgICAgICB0aGlzLl9zdGFydFNlbGVjdGlvbkFjdGlvbi5kaXNhYmxlZD10aGlzLnN0YXJ0U2VsZWN0aW9uRGlzYWJsZWQoKTtcclxuICAgICAgICAgICAgICAgIH0pO1xyXG4gICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgfWVsc2V7XHJcbiAgICAgICAgICAgIHRoaXMuX3N0YXJ0QWN0aW9uLmRpc2FibGVkPXRydWU7XHJcbiAgICAgICAgICAgIHRoaXMuX3N0YXJ0U2VsZWN0aW9uQWN0aW9uLmRpc2FibGVkPXRydWU7XHJcbiAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICBzdGFydFNlbGVjdGlvbkRpc2FibGVkKCl7XHJcbiAgICAgICAgICByZXR1cm4gISh0aGlzLl9hdWRpb0NsaXAgJiYgIXRoaXMuc3RhcnRBY3Rpb24uZGlzYWJsZWQgJiYgdGhpcy5fYXVkaW9DbGlwLnNlbGVjdGlvbiApXHJcbiAgICAgICAgfVxyXG5cclxuXHJcbiAgICAgICAgcHJpdmF0ZSBfc3RhcnQocGxheVNlbGVjdGlvbj1mYWxzZSl7XHJcbiAgICAgICAgICAgICAgICBpZighdGhpcy5jb250ZXh0KXtcclxuICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJDb3VsZCBub3QgZ2V0IGF1ZGlvIGNvbnRleHQhXCIpO1xyXG4gICAgICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgIGlmICh0aGlzLl9hdWRpb1NvdXJjZSBpbnN0YW5jZW9mIEF1ZGlvQnVmZmVyU291cmNlKSB7XHJcbiAgICAgICAgICAgIHRoaXMuc291cmNlQnVmZmVyTm9kZSA9IHRoaXMuY29udGV4dC5jcmVhdGVCdWZmZXJTb3VyY2UoKTtcclxuICAgICAgICAgICAgdGhpcy5zb3VyY2VCdWZmZXJOb2RlLmJ1ZmZlciA9IHRoaXMuX2F1ZGlvU291cmNlLmF1ZGlvQnVmZmVyO1xyXG4gICAgICAgICAgICB0aGlzLnNvdXJjZUJ1ZmZlck5vZGUuY29ubmVjdCh0aGlzLmNvbnRleHQuZGVzdGluYXRpb24pO1xyXG4gICAgICAgICAgICB0aGlzLnNvdXJjZUJ1ZmZlck5vZGUub25lbmRlZCA9ICgpID0+IHRoaXMub25lbmRlZCgpO1xyXG4gICAgICAgICAgICB0aGlzLnBsYXlTdGFydFRpbWUgPSB0aGlzLmNvbnRleHQuY3VycmVudFRpbWU7XHJcbiAgICAgICAgICAgIHRoaXMucnVubmluZyA9IHRydWU7XHJcbiAgICAgICAgICAgIC8vIHVuZm9ydHVuYXRlbHkgV2ViIEF1ZGlvIEFQSSB1c2VzIHRpbWUgdmFsdWVzIG5vdCBmcmFtZXNcclxuICAgICAgICAgICAgY29uc3QgYWMgPSB0aGlzLl9hdWRpb0NsaXBcclxuICAgICAgICAgICAgbGV0IG9mZnNldCA9IDA7XHJcbiAgICAgICAgICAgIGlmIChwbGF5U2VsZWN0aW9uICYmIGFjICYmIGFjLnNlbGVjdGlvbikge1xyXG5cclxuICAgICAgICAgICAgICBjb25zdCBzID0gYWMuc2VsZWN0aW9uO1xyXG4gICAgICAgICAgICAgIGNvbnN0IHNyID0gYWMuYXVkaW9EYXRhSG9sZGVyLnNhbXBsZVJhdGU7XHJcbiAgICAgICAgICAgICAgb2Zmc2V0ID0gcy5sZWZ0RnJhbWUgLyBzcjtcclxuICAgICAgICAgICAgICBjb25zdCBzdG9wUG9zSW5zZWNzID0gcy5yaWdodEZyYW1lIC8gc3I7XHJcbiAgICAgICAgICAgICAgY29uc3QgZHVyID0gc3RvcFBvc0luc2VjcyAtIG9mZnNldDtcclxuICAgICAgICAgICAgICB0aGlzLnNvdXJjZUJ1ZmZlck5vZGUuc3RhcnQoMCwgb2Zmc2V0LCBkdXIpXHJcbiAgICAgICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgICAgdGhpcy5zb3VyY2VCdWZmZXJOb2RlLnN0YXJ0KCk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgdGhpcy5wbGF5U3RhcnRUaW1lID0gdGhpcy5jb250ZXh0LmN1cnJlbnRUaW1lIC0gb2Zmc2V0O1xyXG4gICAgICAgICAgICB0aGlzLl9zdGFydEFjdGlvbi5kaXNhYmxlZCA9IHRydWU7XHJcbiAgICAgICAgICAgIHRoaXMuX3N0YXJ0U2VsZWN0aW9uQWN0aW9uLmRpc2FibGVkID0gdHJ1ZVxyXG4gICAgICAgICAgICB0aGlzLl9zdG9wQWN0aW9uLmRpc2FibGVkID0gZmFsc2U7XHJcblxyXG4gICAgICAgICAgICBpZiAodGhpcy5saXN0ZW5lcikge1xyXG4gICAgICAgICAgICAgIHRoaXMubGlzdGVuZXIuYXVkaW9QbGF5ZXJVcGRhdGUobmV3IEF1ZGlvUGxheWVyRXZlbnQoRXZlbnRUeXBlLlNUQVJURUQpKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgfSBlbHNlIGlmICh0aGlzLl9hdWRpb1NvdXJjZSBpbnN0YW5jZW9mIEFycmF5QXVkaW9CdWZmZXIgfHwgdGhpcy5fYXVkaW9Tb3VyY2UgaW5zdGFuY2VvZiBJbmRleGVkRGJBdWRpb0J1ZmZlciB8fCB0aGlzLl9hdWRpb1NvdXJjZSBpbnN0YW5jZW9mIE5ldEF1ZGlvQnVmZmVyKSB7XHJcbiAgICAgICAgICAgICAgQXVkaW9Tb3VyY2VXb3JrbGV0TW9kdWxlTG9hZGVyLmxvYWRNb2R1bGUodGhpcy5jb250ZXh0KS50aGVuKCgpID0+IHtcclxuICAgICAgICAgICAgICAgICAgdGhpcy5wbGF5U3RhcnRUaW1lID0gbnVsbDtcclxuICAgICAgICAgICAgICAgICAgaWYgKHRoaXMuY29udGV4dCkge1xyXG4gICAgICAgICAgICAgICAgICBpZiAodGhpcy5fYXVkaW9Tb3VyY2UgaW5zdGFuY2VvZiBBcnJheUF1ZGlvQnVmZmVyKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICBjb25zdCBhYWJzbiA9IG5ldyBBcnJheUF1ZGlvQnVmZmVyU291cmNlTm9kZSh0aGlzLmNvbnRleHQpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgYWFic24uYXJyYXlBdWRpb0J1ZmZlciA9IHRoaXMuX2F1ZGlvU291cmNlO1xyXG4gICAgICAgICAgICAgICAgICAgICAgdGhpcy5zb3VyY2VBdWRpb1dvcmtsZXROb2RlID0gYWFic247XHJcbiAgICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAodGhpcy5fYXVkaW9Tb3VyY2UgaW5zdGFuY2VvZiBJbmRleGVkRGJBdWRpb0J1ZmZlcikge1xyXG4gICAgICAgICAgICAgICAgICAgICAgY29uc3QgaWFzbiA9IG5ldyBJbmRleGVkRGJBdWRpb0J1ZmZlclNvdXJjZU5vZGUodGhpcy5jb250ZXh0KTtcclxuICAgICAgICAgICAgICAgICAgICAgIGlhc24uaW5kZGJBdWRpb0J1ZmZlciA9IHRoaXMuX2F1ZGlvU291cmNlO1xyXG4gICAgICAgICAgICAgICAgICAgICAgdGhpcy5zb3VyY2VBdWRpb1dvcmtsZXROb2RlID0gaWFzbjtcclxuICAgICAgICAgICAgICAgICAgfSBlbHNlIGlmICh0aGlzLl9hdWRpb1NvdXJjZSBpbnN0YW5jZW9mIE5ldEF1ZGlvQnVmZmVyKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICBjb25zdCBuYWJzbiA9IG5ldyBOZXRBdWRpb0J1ZmZlclNvdXJjZU5vZGUodGhpcy5jb250ZXh0KTtcclxuICAgICAgICAgICAgICAgICAgICAgIG5hYnNuLm5ldEF1ZGlvQnVmZmVyID0gdGhpcy5fYXVkaW9Tb3VyY2U7XHJcbiAgICAgICAgICAgICAgICAgICAgICB0aGlzLnNvdXJjZUF1ZGlvV29ya2xldE5vZGUgPSBuYWJzbjtcclxuICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICBpZiAodGhpcy5zb3VyY2VBdWRpb1dvcmtsZXROb2RlKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICB0aGlzLnNvdXJjZUF1ZGlvV29ya2xldE5vZGUub25wcm9jZXNzb3JlcnJvciA9IChldjogRXZlbnQpID0+IHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICBsZXQgbXNnID0gJ1Vua253b24gZXJyb3InO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChldiBpbnN0YW5jZW9mIEVycm9yRXZlbnQpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbXNnID0gZXYubWVzc2FnZTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc29sZS5lcnJvcihcIkF1ZGlvIHNvdXJjZSB3b3JrbGV0IGVycm9yOiBcIiArIG1zZyk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHRoaXMubGlzdGVuZXIpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5saXN0ZW5lci5hdWRpb1BsYXllclVwZGF0ZShuZXcgQXVkaW9QbGF5ZXJFdmVudChFdmVudFR5cGUuRVJST1IpKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICB9O1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAgIHRoaXMuc291cmNlQXVkaW9Xb3JrbGV0Tm9kZS5jb25uZWN0KHRoaXMuY29udGV4dC5kZXN0aW5hdGlvbik7IC8vIHRoaXMgYWxyZWFkeSBzdGFydHMgcGxheWluZ1xyXG4gICAgICAgICAgICAgICAgICAgICAgdGhpcy5zb3VyY2VBdWRpb1dvcmtsZXROb2RlLm9uZW5kZWQgPSAoKSA9PiB0aGlzLm9uZW5kZWQoKTtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICB0aGlzLnJ1bm5pbmcgPSB0cnVlO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGFjID0gdGhpcy5fYXVkaW9DbGlwXHJcbiAgICAgICAgICAgICAgICAgICAgICBsZXQgb2Zmc2V0ID0gMFxyXG4gICAgICAgICAgICAgICAgICAgICAgaWYgKHBsYXlTZWxlY3Rpb24gJiYgYWMgJiYgYWMuc2VsZWN0aW9uKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgcyA9IGFjLnNlbGVjdGlvbjtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBzciA9IGFjLmF1ZGlvRGF0YUhvbGRlci5zYW1wbGVSYXRlO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgIG9mZnNldCA9IHMubGVmdEZyYW1lIC8gc3I7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3Qgc3RvcFBvc0luc2VjcyA9IHMucmlnaHRGcmFtZSAvIHNyO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGR1ciA9IHN0b3BQb3NJbnNlY3MgLSBvZmZzZXRcclxuICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnNvdXJjZUF1ZGlvV29ya2xldE5vZGUuc3RhcnQoMCwgb2Zmc2V0LCBkdXIpXHJcbiAgICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuc291cmNlQXVkaW9Xb3JrbGV0Tm9kZS5zdGFydCgpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgICAgICAgICAgIC8vdGhpcy5wbGF5U3RhcnRUaW1lID0gdGhpcy5jb250ZXh0LmN1cnJlbnRUaW1lIC0gb2Zmc2V0O1xyXG4gICAgICAgICAgICAgICAgICAgICAgdGhpcy5fc3RhcnRBY3Rpb24uZGlzYWJsZWQgPSB0cnVlO1xyXG4gICAgICAgICAgICAgICAgICAgICAgdGhpcy5fc3RhcnRTZWxlY3Rpb25BY3Rpb24uZGlzYWJsZWQgPSB0cnVlXHJcbiAgICAgICAgICAgICAgICAgICAgICB0aGlzLl9zdG9wQWN0aW9uLmRpc2FibGVkID0gZmFsc2U7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgICAgaWYgKHRoaXMubGlzdGVuZXIpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmxpc3RlbmVyLmF1ZGlvUGxheWVyVXBkYXRlKG5ldyBBdWRpb1BsYXllckV2ZW50KEV2ZW50VHlwZS5TVEFSVEVEKSk7XHJcbiAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgfSkuY2F0Y2goKGVycm9yOiBhbnkpID0+IHtcclxuICAgICAgICAgICAgICAgICAgY29uc29sZS5lcnJvcihlcnJvci5tZXNzYWdlKTtcclxuICAgICAgICAgICAgICAgICAgdGhpcy5yZWFkeSA9IGZhbHNlO1xyXG4gICAgICAgICAgICAgICAgICB0aGlzLnVwZGF0ZVN0YXJ0QWN0aW9ucygpO1xyXG4gICAgICAgICAgICAgICAgICBpZiAodGhpcy5saXN0ZW5lcikge1xyXG4gICAgICAgICAgICAgICAgICAgICAgdGhpcy5saXN0ZW5lci5hdWRpb1BsYXllclVwZGF0ZShuZXcgQXVkaW9QbGF5ZXJFdmVudChFdmVudFR5cGUuQ0xPU0VEKSk7XHJcbiAgICAgICAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgICAgICAgIHRocm93IGVycm9yO1xyXG4gICAgICAgICAgICAgIH0pO1xyXG5cclxuICAgICAgICAgIH1cclxuICAgICAgICB9XHJcblxyXG4gICAgICBzdGFydFNlbGVjdGVkKCkge1xyXG4gICAgICAgICAgICB0aGlzLl9hdWRpb0NvbnRleHQoKTtcclxuICAgICAgICAgIGlmKCF0aGlzLmNvbnRleHQpe1xyXG4gICAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihcIkNvdWxkIG5vdCBnZXQgYXVkaW8gY29udGV4dCFcIik7XHJcbiAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgaWYoIXRoaXMuX3N0YXJ0QWN0aW9uLmRpc2FibGVkICYmICF0aGlzLnJ1bm5pbmcpIHtcclxuICAgICAgICAgIGlmICh0aGlzLmNvbnRleHQuc3RhdGUgPT09ICdzdXNwZW5kZWQnKSB7XHJcbiAgICAgICAgICAgIHRoaXMuY29udGV4dC5yZXN1bWUoKS50aGVuKCgpID0+IHtcclxuICAgICAgICAgICAgICB0aGlzLl9zdGFydCh0cnVlKTtcclxuICAgICAgICAgICAgfSkuY2F0Y2goKHJlYXNvbikgPT4ge1xyXG4gICAgICAgICAgICAgIGNvbnNvbGUuZXJyb3IocmVhc29uLm1lc3NhZ2UpO1xyXG4gICAgICAgICAgICAgIHRocm93IHJlYXNvbjtcclxuICAgICAgICAgICAgfSlcclxuICAgICAgICAgIH1lbHNlIGlmKHRoaXMuY29udGV4dC5zdGF0ZT09PSdjbG9zZWQnKXtcclxuICAgICAgICAgICAgY29uc3QgbXNnPSdFcnJvcjogQ2Fubm90IHN0YXJ0IHBsYXliYWNrIG9mIHNlbGVjdGlvbi4gQXVkaW8gY29udGV4dCBpcyBhbHJlYWR5IGNsb3NlZCEnO1xyXG4gICAgICAgICAgICBjb25zb2xlLmVycm9yKG1zZyk7XHJcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihtc2cpO1xyXG4gICAgICAgICAgfWVsc2V7XHJcbiAgICAgICAgICAgIHRoaXMuX3N0YXJ0KHRydWUpO1xyXG4gICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuICAgICAgfVxyXG5cclxuICAgICAgICBzdG9wKCl7XHJcbiAgICAgICAgICAgIGlmKHRoaXMucnVubmluZykge1xyXG4gICAgICAgICAgICAgICAgaWYgKHRoaXMuc291cmNlQnVmZmVyTm9kZSkge1xyXG4gICAgICAgICAgICAgICAgICAgIHRoaXMuc291cmNlQnVmZmVyTm9kZS5zdG9wKCk7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICBpZih0aGlzLnNvdXJjZUF1ZGlvV29ya2xldE5vZGUpe1xyXG4gICAgICAgICAgICAgICAgICB0aGlzLnNvdXJjZUF1ZGlvV29ya2xldE5vZGUuc3RvcCgpO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICBpZiAodGhpcy50aW1lclZhciAhPT0gbnVsbCkge1xyXG4gICAgICAgICAgICAgICAgICAgIHdpbmRvdy5jbGVhckludGVydmFsKHRoaXMudGltZXJWYXIpO1xyXG4gICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgIHRoaXMucnVubmluZyA9IGZhbHNlO1xyXG4gICAgICAgICAgICAgICAgICBpZiAodGhpcy5saXN0ZW5lcikge1xyXG4gICAgICAgICAgICAgICAgICAgIHRoaXMubGlzdGVuZXIuYXVkaW9QbGF5ZXJVcGRhdGUobmV3IEF1ZGlvUGxheWVyRXZlbnQoRXZlbnRUeXBlLlNUT1BQRUQpKTtcclxuICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgb25lbmRlZCgpIHtcclxuICAgICAgICAgICAgaWYodGhpcy50aW1lclZhciE9bnVsbCkge1xyXG4gICAgICAgICAgICAgICAgd2luZG93LmNsZWFySW50ZXJ2YWwodGhpcy50aW1lclZhcik7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgdGhpcy5fc3RhcnRBY3Rpb24uZGlzYWJsZWQgPSAhdGhpcy5fYXVkaW9Tb3VyY2U7XHJcbiAgICAgICAgICAgIHRoaXMuX3N0YXJ0U2VsZWN0aW9uQWN0aW9uLmRpc2FibGVkPXRoaXMuc3RhcnRTZWxlY3Rpb25EaXNhYmxlZCgpXHJcbiAgICAgICAgICAgIHRoaXMuX3N0b3BBY3Rpb24uZGlzYWJsZWQgPSB0cnVlO1xyXG4gICAgICAgICAgICB0aGlzLnJ1bm5pbmc9ZmFsc2U7XHJcbiAgICAgICAgICAgIGlmICh0aGlzLmxpc3RlbmVyKSB7XHJcbiAgICAgICAgICAgICAgICB0aGlzLmxpc3RlbmVyLmF1ZGlvUGxheWVyVXBkYXRlKG5ldyBBdWRpb1BsYXllckV2ZW50KEV2ZW50VHlwZS5FTkRFRCkpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICBnZXQgcGxheVBvc2l0aW9uVGltZSgpOm51bWJlcnxudWxsIHtcclxuICAgICAgICAgICAgbGV0IHBwdD1udWxsO1xyXG4gICAgICAgICAgICBpZih0aGlzLmNvbnRleHQgJiYgdGhpcy5wbGF5U3RhcnRUaW1lIT09bnVsbCkge1xyXG4gICAgICAgICAgICAgICAgcHB0PSB0aGlzLmNvbnRleHQuY3VycmVudFRpbWUgLSB0aGlzLnBsYXlTdGFydFRpbWU7XHJcbiAgICAgICAgICAgIH1lbHNlIGlmKHRoaXMuc291cmNlQXVkaW9Xb3JrbGV0Tm9kZSl7XHJcbiAgICAgICAgICAgICAgcHB0PXRoaXMuc291cmNlQXVkaW9Xb3JrbGV0Tm9kZS5wbGF5UG9zaXRpb25UaW1lO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIHJldHVybiBwcHQ7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgZ2V0IHBsYXlQb3NpdGlvbkZyYW1lcygpOm51bWJlcnxudWxsIHtcclxuICAgICAgICBsZXQgcHBGcnM6bnVtYmVyfG51bGw9bnVsbDtcclxuICAgICAgIGlmKHRoaXMuX2F1ZGlvU291cmNlKSB7XHJcbiAgICAgICAgIGxldCBzcj10aGlzLl9hdWRpb1NvdXJjZS5zYW1wbGVSYXRlO1xyXG4gICAgICAgICBpZiAoc3IpIHtcclxuICAgICAgICAgICBsZXQgcHBUaW1lID0gdGhpcy5wbGF5UG9zaXRpb25UaW1lO1xyXG4gICAgICAgICAgIGlmIChwcFRpbWUgIT09IG51bGwpIHtcclxuICAgICAgICAgICAgIHBwRnJzID0gc3IgKiBwcFRpbWU7XHJcbiAgICAgICAgICAgfVxyXG4gICAgICAgICB9XHJcbiAgICAgICB9XHJcbiAgICAgICAgcmV0dXJuIHBwRnJzO1xyXG4gICAgICB9XHJcblxyXG4gICAgfVxyXG5cclxuIl19
|