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
|
@@ -1,402 +0,0 @@
|
|
|
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
|
-
constructor(listener) {
|
|
35
|
-
this.running = false;
|
|
36
|
-
this.context = null;
|
|
37
|
-
this.ready = false;
|
|
38
|
-
this._audioClip = null;
|
|
39
|
-
this._audioSource = null;
|
|
40
|
-
this.sourceBufferNode = null;
|
|
41
|
-
this.sourceAudioWorkletNode = null;
|
|
42
|
-
this.playStartTime = null;
|
|
43
|
-
this.timerVar = null;
|
|
44
|
-
this.listener = listener;
|
|
45
|
-
this.bufSize = AudioPlayer.DEFAULT_BUFSIZE;
|
|
46
|
-
this.n = navigator;
|
|
47
|
-
this.buffPos = 0;
|
|
48
|
-
this.zeroBufCnt = 0;
|
|
49
|
-
this.zb = new Float32Array(this.bufSize);
|
|
50
|
-
this._startAction = new Action('Start');
|
|
51
|
-
this._startAction.disabled = true;
|
|
52
|
-
this._startAction.onAction = () => this.start();
|
|
53
|
-
this._startSelectionAction = new Action('Start selected');
|
|
54
|
-
this._startSelectionAction.disabled = true;
|
|
55
|
-
this._startSelectionAction.onAction = () => this.startSelected();
|
|
56
|
-
this._autoPlayOnSelectToggleAction = new Action("Autoplay on select", false);
|
|
57
|
-
this._stopAction = new Action('Stop');
|
|
58
|
-
this._stopAction.disabled = true;
|
|
59
|
-
this._stopAction.onAction = () => this.stop();
|
|
60
|
-
}
|
|
61
|
-
get autoPlayOnSelectToggleAction() {
|
|
62
|
-
return this._autoPlayOnSelectToggleAction;
|
|
63
|
-
}
|
|
64
|
-
_audioContext() {
|
|
65
|
-
if (!this.context) {
|
|
66
|
-
this.context = AudioContextProvider.audioContextInstance();
|
|
67
|
-
if (this.context) {
|
|
68
|
-
this.context.addEventListener('statechange', (ev) => {
|
|
69
|
-
if (this.context && this.context.state !== 'running') {
|
|
70
|
-
this.stop();
|
|
71
|
-
}
|
|
72
|
-
});
|
|
73
|
-
}
|
|
74
|
-
}
|
|
75
|
-
return this.context;
|
|
76
|
-
}
|
|
77
|
-
get startAction() {
|
|
78
|
-
return this._startAction;
|
|
79
|
-
}
|
|
80
|
-
get startSelectionAction() {
|
|
81
|
-
return this._startSelectionAction;
|
|
82
|
-
}
|
|
83
|
-
get stopAction() {
|
|
84
|
-
return this._stopAction;
|
|
85
|
-
}
|
|
86
|
-
set audioClip(audioClip) {
|
|
87
|
-
this._audioClip = audioClip;
|
|
88
|
-
let length = 0;
|
|
89
|
-
let chs = 0;
|
|
90
|
-
if (audioClip && audioClip.audioDataHolder) {
|
|
91
|
-
let audioDataHolder = audioClip.audioDataHolder;
|
|
92
|
-
chs = audioDataHolder.numberOfChannels;
|
|
93
|
-
if (chs > 0) {
|
|
94
|
-
length = audioDataHolder.frameLen;
|
|
95
|
-
//if (chs > this.context.destination.maxChannelCount) {
|
|
96
|
-
// // TODO exception
|
|
97
|
-
//}
|
|
98
|
-
}
|
|
99
|
-
this.audioSource = audioDataHolder.audioSource;
|
|
100
|
-
audioClip.addSelectionObserver((ac) => {
|
|
101
|
-
this._startSelectionAction.disabled = this.startSelectionDisabled();
|
|
102
|
-
if (!this.startSelectionAction.disabled && this._autoPlayOnSelectToggleAction.value) {
|
|
103
|
-
this.startSelected();
|
|
104
|
-
}
|
|
105
|
-
});
|
|
106
|
-
}
|
|
107
|
-
else {
|
|
108
|
-
this.audioSource = null;
|
|
109
|
-
}
|
|
110
|
-
}
|
|
111
|
-
get audioSource() {
|
|
112
|
-
return this._audioSource;
|
|
113
|
-
}
|
|
114
|
-
set audioSource(value) {
|
|
115
|
-
this.stop();
|
|
116
|
-
this._audioSource = value;
|
|
117
|
-
if (this._audioSource) {
|
|
118
|
-
this.ready = true;
|
|
119
|
-
this.updateStartActions();
|
|
120
|
-
if (this.listener) {
|
|
121
|
-
this.listener.audioPlayerUpdate(new AudioPlayerEvent(EventType.READY));
|
|
122
|
-
}
|
|
123
|
-
}
|
|
124
|
-
else {
|
|
125
|
-
this.ready = false;
|
|
126
|
-
this.updateStartActions();
|
|
127
|
-
if (this.listener) {
|
|
128
|
-
this.listener.audioPlayerUpdate(new AudioPlayerEvent(EventType.CLOSED));
|
|
129
|
-
}
|
|
130
|
-
}
|
|
131
|
-
}
|
|
132
|
-
_loadSourceWorkletAndInitStart() {
|
|
133
|
-
if (this.context) {
|
|
134
|
-
AudioSourceWorkletModuleLoader.loadModule(this.context).then(() => {
|
|
135
|
-
//console.debug("Player ready. ( by Player::_loadSourceWorkletAndInitStart()");
|
|
136
|
-
this.ready = true;
|
|
137
|
-
this.updateStartActions();
|
|
138
|
-
if (this.listener) {
|
|
139
|
-
this.listener.audioPlayerUpdate(new AudioPlayerEvent(EventType.READY));
|
|
140
|
-
}
|
|
141
|
-
}).catch((error) => {
|
|
142
|
-
this.ready = false;
|
|
143
|
-
this.updateStartActions();
|
|
144
|
-
if (this.listener) {
|
|
145
|
-
this.listener.audioPlayerUpdate(new AudioPlayerEvent(EventType.CLOSED));
|
|
146
|
-
}
|
|
147
|
-
console.error('Could not add module ' + error);
|
|
148
|
-
});
|
|
149
|
-
}
|
|
150
|
-
}
|
|
151
|
-
_startAudioSourceWorkletNode() {
|
|
152
|
-
this._loadSourceWorkletAndInitStart();
|
|
153
|
-
if (this.context && this.sourceAudioWorkletNode) {
|
|
154
|
-
this.sourceAudioWorkletNode.onprocessorerror = (ev) => {
|
|
155
|
-
let msg = 'Unknwon error';
|
|
156
|
-
if (ev instanceof ErrorEvent) {
|
|
157
|
-
msg = ev.message;
|
|
158
|
-
}
|
|
159
|
-
console.error("Audio source worklet error: " + msg);
|
|
160
|
-
if (this.listener) {
|
|
161
|
-
// TODO
|
|
162
|
-
// this.listener.error(msg);
|
|
163
|
-
// this.listener.audioPlayerUpdate(new AudioPlayerEvent());
|
|
164
|
-
}
|
|
165
|
-
};
|
|
166
|
-
this.sourceAudioWorkletNode.connect(this.context.destination); // this already starts playing
|
|
167
|
-
this.sourceAudioWorkletNode.onended = () => this.onended();
|
|
168
|
-
this.running = true;
|
|
169
|
-
this.sourceAudioWorkletNode.start();
|
|
170
|
-
//console.debug("Playback start action enabled. ( by Player::_startAudioSourceWorkletNode()");
|
|
171
|
-
this._startAction.disabled = true;
|
|
172
|
-
this._startSelectionAction.disabled = true;
|
|
173
|
-
this._stopAction.disabled = false;
|
|
174
|
-
if (this.listener) {
|
|
175
|
-
this.listener.audioPlayerUpdate(new AudioPlayerEvent(EventType.STARTED));
|
|
176
|
-
}
|
|
177
|
-
}
|
|
178
|
-
}
|
|
179
|
-
start() {
|
|
180
|
-
this._audioContext();
|
|
181
|
-
if (this.context) {
|
|
182
|
-
if (!this._startAction.disabled && !this.running) {
|
|
183
|
-
if (this.context.state === 'suspended') {
|
|
184
|
-
this.context.resume().then(() => {
|
|
185
|
-
this._start();
|
|
186
|
-
}).catch((reason) => {
|
|
187
|
-
console.error(reason.message());
|
|
188
|
-
throw reason;
|
|
189
|
-
});
|
|
190
|
-
}
|
|
191
|
-
else if (this.context.state === 'closed') {
|
|
192
|
-
const msg = 'Error: Cannot start playback. Audio context is already closed!';
|
|
193
|
-
console.error(msg);
|
|
194
|
-
throw new Error(msg);
|
|
195
|
-
}
|
|
196
|
-
else {
|
|
197
|
-
this._start();
|
|
198
|
-
}
|
|
199
|
-
}
|
|
200
|
-
}
|
|
201
|
-
}
|
|
202
|
-
updateStartActions() {
|
|
203
|
-
if (this.ready) {
|
|
204
|
-
if (this._audioSource instanceof AudioBufferSource || this._audioSource instanceof ArrayAudioBuffer || this._audioSource instanceof IndexedDbAudioBuffer) {
|
|
205
|
-
this._startAction.disabled = false;
|
|
206
|
-
this._startSelectionAction.disabled = this.startSelectionDisabled();
|
|
207
|
-
}
|
|
208
|
-
else {
|
|
209
|
-
if (this._audioSource instanceof NetAudioBuffer) {
|
|
210
|
-
this._audioSource.addOnReadyListener(() => {
|
|
211
|
-
this._startAction.disabled = false;
|
|
212
|
-
this._startSelectionAction.disabled = this.startSelectionDisabled();
|
|
213
|
-
});
|
|
214
|
-
}
|
|
215
|
-
}
|
|
216
|
-
}
|
|
217
|
-
else {
|
|
218
|
-
this._startAction.disabled = true;
|
|
219
|
-
this._startSelectionAction.disabled = true;
|
|
220
|
-
}
|
|
221
|
-
}
|
|
222
|
-
startSelectionDisabled() {
|
|
223
|
-
return !(this._audioClip && !this.startAction.disabled && this._audioClip.selection);
|
|
224
|
-
}
|
|
225
|
-
_start(playSelection = false) {
|
|
226
|
-
if (!this.context) {
|
|
227
|
-
throw new Error("Could not get audio context!");
|
|
228
|
-
}
|
|
229
|
-
if (this._audioSource instanceof AudioBufferSource) {
|
|
230
|
-
this.sourceBufferNode = this.context.createBufferSource();
|
|
231
|
-
this.sourceBufferNode.buffer = this._audioSource.audioBuffer;
|
|
232
|
-
this.sourceBufferNode.connect(this.context.destination);
|
|
233
|
-
this.sourceBufferNode.onended = () => this.onended();
|
|
234
|
-
this.playStartTime = this.context.currentTime;
|
|
235
|
-
this.running = true;
|
|
236
|
-
// unfortunately Web Audio API uses time values not frames
|
|
237
|
-
const ac = this._audioClip;
|
|
238
|
-
let offset = 0;
|
|
239
|
-
if (playSelection && ac && ac.selection) {
|
|
240
|
-
const s = ac.selection;
|
|
241
|
-
const sr = ac.audioDataHolder.sampleRate;
|
|
242
|
-
offset = s.leftFrame / sr;
|
|
243
|
-
const stopPosInsecs = s.rightFrame / sr;
|
|
244
|
-
const dur = stopPosInsecs - offset;
|
|
245
|
-
this.sourceBufferNode.start(0, offset, dur);
|
|
246
|
-
}
|
|
247
|
-
else {
|
|
248
|
-
this.sourceBufferNode.start();
|
|
249
|
-
}
|
|
250
|
-
this.playStartTime = this.context.currentTime - offset;
|
|
251
|
-
this._startAction.disabled = true;
|
|
252
|
-
this._startSelectionAction.disabled = true;
|
|
253
|
-
this._stopAction.disabled = false;
|
|
254
|
-
if (this.listener) {
|
|
255
|
-
this.listener.audioPlayerUpdate(new AudioPlayerEvent(EventType.STARTED));
|
|
256
|
-
}
|
|
257
|
-
}
|
|
258
|
-
else if (this._audioSource instanceof ArrayAudioBuffer || this._audioSource instanceof IndexedDbAudioBuffer || this._audioSource instanceof NetAudioBuffer) {
|
|
259
|
-
AudioSourceWorkletModuleLoader.loadModule(this.context).then(() => {
|
|
260
|
-
this.playStartTime = null;
|
|
261
|
-
if (this.context) {
|
|
262
|
-
if (this._audioSource instanceof ArrayAudioBuffer) {
|
|
263
|
-
const aabsn = new ArrayAudioBufferSourceNode(this.context);
|
|
264
|
-
aabsn.arrayAudioBuffer = this._audioSource;
|
|
265
|
-
this.sourceAudioWorkletNode = aabsn;
|
|
266
|
-
}
|
|
267
|
-
else if (this._audioSource instanceof IndexedDbAudioBuffer) {
|
|
268
|
-
const iasn = new IndexedDbAudioBufferSourceNode(this.context);
|
|
269
|
-
iasn.inddbAudioBuffer = this._audioSource;
|
|
270
|
-
this.sourceAudioWorkletNode = iasn;
|
|
271
|
-
}
|
|
272
|
-
else if (this._audioSource instanceof NetAudioBuffer) {
|
|
273
|
-
const nabsn = new NetAudioBufferSourceNode(this.context);
|
|
274
|
-
nabsn.netAudioBuffer = this._audioSource;
|
|
275
|
-
this.sourceAudioWorkletNode = nabsn;
|
|
276
|
-
}
|
|
277
|
-
if (this.sourceAudioWorkletNode) {
|
|
278
|
-
this.sourceAudioWorkletNode.onprocessorerror = (ev) => {
|
|
279
|
-
let msg = 'Unknwon error';
|
|
280
|
-
if (ev instanceof ErrorEvent) {
|
|
281
|
-
msg = ev.message;
|
|
282
|
-
}
|
|
283
|
-
console.error("Audio source worklet error: " + msg);
|
|
284
|
-
if (this.listener) {
|
|
285
|
-
this.listener.audioPlayerUpdate(new AudioPlayerEvent(EventType.ERROR));
|
|
286
|
-
}
|
|
287
|
-
};
|
|
288
|
-
this.sourceAudioWorkletNode.connect(this.context.destination); // this already starts playing
|
|
289
|
-
this.sourceAudioWorkletNode.onended = () => this.onended();
|
|
290
|
-
this.running = true;
|
|
291
|
-
const ac = this._audioClip;
|
|
292
|
-
let offset = 0;
|
|
293
|
-
if (playSelection && ac && ac.selection) {
|
|
294
|
-
const s = ac.selection;
|
|
295
|
-
const sr = ac.audioDataHolder.sampleRate;
|
|
296
|
-
offset = s.leftFrame / sr;
|
|
297
|
-
const stopPosInsecs = s.rightFrame / sr;
|
|
298
|
-
const dur = stopPosInsecs - offset;
|
|
299
|
-
this.sourceAudioWorkletNode.start(0, offset, dur);
|
|
300
|
-
}
|
|
301
|
-
else {
|
|
302
|
-
this.sourceAudioWorkletNode.start();
|
|
303
|
-
}
|
|
304
|
-
//this.playStartTime = this.context.currentTime - offset;
|
|
305
|
-
this._startAction.disabled = true;
|
|
306
|
-
this._startSelectionAction.disabled = true;
|
|
307
|
-
this._stopAction.disabled = false;
|
|
308
|
-
if (this.listener) {
|
|
309
|
-
this.listener.audioPlayerUpdate(new AudioPlayerEvent(EventType.STARTED));
|
|
310
|
-
}
|
|
311
|
-
}
|
|
312
|
-
}
|
|
313
|
-
}).catch((error) => {
|
|
314
|
-
console.error(error.message);
|
|
315
|
-
this.ready = false;
|
|
316
|
-
this.updateStartActions();
|
|
317
|
-
if (this.listener) {
|
|
318
|
-
this.listener.audioPlayerUpdate(new AudioPlayerEvent(EventType.CLOSED));
|
|
319
|
-
}
|
|
320
|
-
throw error;
|
|
321
|
-
});
|
|
322
|
-
}
|
|
323
|
-
}
|
|
324
|
-
startSelected() {
|
|
325
|
-
this._audioContext();
|
|
326
|
-
if (!this.context) {
|
|
327
|
-
throw new Error("Could not get audio context!");
|
|
328
|
-
}
|
|
329
|
-
if (!this._startAction.disabled && !this.running) {
|
|
330
|
-
if (this.context.state === 'suspended') {
|
|
331
|
-
this.context.resume().then(() => {
|
|
332
|
-
this._start(true);
|
|
333
|
-
}).catch((reason) => {
|
|
334
|
-
console.error(reason.message);
|
|
335
|
-
throw reason;
|
|
336
|
-
});
|
|
337
|
-
}
|
|
338
|
-
else if (this.context.state === 'closed') {
|
|
339
|
-
const msg = 'Error: Cannot start playback of selection. Audio context is already closed!';
|
|
340
|
-
console.error(msg);
|
|
341
|
-
throw new Error(msg);
|
|
342
|
-
}
|
|
343
|
-
else {
|
|
344
|
-
this._start(true);
|
|
345
|
-
}
|
|
346
|
-
}
|
|
347
|
-
}
|
|
348
|
-
stop() {
|
|
349
|
-
if (this.running) {
|
|
350
|
-
if (this.sourceBufferNode) {
|
|
351
|
-
this.sourceBufferNode.stop();
|
|
352
|
-
}
|
|
353
|
-
if (this.sourceAudioWorkletNode) {
|
|
354
|
-
this.sourceAudioWorkletNode.stop();
|
|
355
|
-
}
|
|
356
|
-
if (this.timerVar !== null) {
|
|
357
|
-
window.clearInterval(this.timerVar);
|
|
358
|
-
}
|
|
359
|
-
this.running = false;
|
|
360
|
-
if (this.listener) {
|
|
361
|
-
this.listener.audioPlayerUpdate(new AudioPlayerEvent(EventType.STOPPED));
|
|
362
|
-
}
|
|
363
|
-
}
|
|
364
|
-
}
|
|
365
|
-
onended() {
|
|
366
|
-
if (this.timerVar != null) {
|
|
367
|
-
window.clearInterval(this.timerVar);
|
|
368
|
-
}
|
|
369
|
-
this._startAction.disabled = !this._audioSource;
|
|
370
|
-
this._startSelectionAction.disabled = this.startSelectionDisabled();
|
|
371
|
-
this._stopAction.disabled = true;
|
|
372
|
-
this.running = false;
|
|
373
|
-
if (this.listener) {
|
|
374
|
-
this.listener.audioPlayerUpdate(new AudioPlayerEvent(EventType.ENDED));
|
|
375
|
-
}
|
|
376
|
-
}
|
|
377
|
-
get playPositionTime() {
|
|
378
|
-
let ppt = null;
|
|
379
|
-
if (this.context && this.playStartTime !== null) {
|
|
380
|
-
ppt = this.context.currentTime - this.playStartTime;
|
|
381
|
-
}
|
|
382
|
-
else if (this.sourceAudioWorkletNode) {
|
|
383
|
-
ppt = this.sourceAudioWorkletNode.playPositionTime;
|
|
384
|
-
}
|
|
385
|
-
return ppt;
|
|
386
|
-
}
|
|
387
|
-
get playPositionFrames() {
|
|
388
|
-
let ppFrs = null;
|
|
389
|
-
if (this._audioSource) {
|
|
390
|
-
let sr = this._audioSource.sampleRate;
|
|
391
|
-
if (sr) {
|
|
392
|
-
let ppTime = this.playPositionTime;
|
|
393
|
-
if (ppTime !== null) {
|
|
394
|
-
ppFrs = sr * ppTime;
|
|
395
|
-
}
|
|
396
|
-
}
|
|
397
|
-
}
|
|
398
|
-
return ppFrs;
|
|
399
|
-
}
|
|
400
|
-
}
|
|
401
|
-
AudioPlayer.DEFAULT_BUFSIZE = 8192;
|
|
402
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicGxheWVyLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vLi4vcHJvamVjdHMvc3BlZWNocmVjb3JkZXJuZy9zcmMvbGliL2F1ZGlvL3BsYXliYWNrL3BsYXllci50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsTUFBTSxFQUFFLE1BQU0scUJBQXFCLENBQUE7QUFFNUMsT0FBTyxFQUFDLGdCQUFnQixFQUFDLE1BQU0sdUJBQXVCLENBQUM7QUFDdkQsT0FBTyxFQUFDLDBCQUEwQixFQUFDLE1BQU0sa0NBQWtDLENBQUM7QUFDNUUsT0FBTyxFQUFDLG9CQUFvQixFQUFDLE1BQU0sdUJBQXVCLENBQUM7QUFDM0QsT0FBTyxFQUFDLDhCQUE4QixFQUFDLE1BQU0sc0NBQXNDLENBQUM7QUFDcEYsT0FBTyxFQUFDLDhCQUE4QixFQUFDLE1BQU0sa0NBQWtDLENBQUM7QUFFaEYsT0FBTyxFQUFDLGNBQWMsRUFBQyxNQUFNLHFCQUFxQixDQUFDO0FBQ25ELE9BQU8sRUFBQyx3QkFBd0IsRUFBQyxNQUFNLGdDQUFnQyxDQUFDO0FBQ3hFLE9BQU8sRUFBQyxpQkFBaUIsRUFBYyxNQUFNLHNCQUFzQixDQUFDO0FBQ3BFLE9BQU8sRUFBQyxvQkFBb0IsRUFBQyxNQUFNLFlBQVksQ0FBQztBQUk1QyxNQUFNLENBQU4sSUFBYSxTQUFpRTtBQUE5RSxXQUFhLFNBQVM7SUFBRSw2Q0FBTSxDQUFBO0lBQUMsMkNBQUssQ0FBQTtJQUFDLCtDQUFPLENBQUE7SUFBQyxxREFBVSxDQUFBO0lBQUUsK0NBQU8sQ0FBQTtJQUFFLDJDQUFLLENBQUE7SUFBQywyQ0FBSyxDQUFBO0FBQUEsQ0FBQyxFQUFqRSxTQUFTLEtBQVQsU0FBUyxRQUF3RDtBQUU5RSxNQUFNLE9BQU8sZ0JBQWdCO0lBS3pCLFlBQVksSUFBYyxFQUFFLFlBQW9CO1FBQzVDLElBQUksQ0FBQyxLQUFLLEdBQUcsSUFBSSxDQUFDO1FBQ2xCLElBQUksQ0FBQyxh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XG5pbXBvcnQgeyBBdWRpb0NsaXAgfSBmcm9tICcuLi9wZXJzaXN0b3InXHJcbmltcG9ydCB7QXJyYXlBdWRpb0J1ZmZlcn0gZnJvbSBcIi4uL2FycmF5X2F1ZGlvX2J1ZmZlclwiO1xyXG5pbXBvcnQge0FycmF5QXVkaW9CdWZmZXJTb3VyY2VOb2RlfSBmcm9tIFwiLi9hcnJheV9hdWRpb19idWZmZXJfc291cmNlX25vZGVcIjtcclxuaW1wb3J0IHtJbmRleGVkRGJBdWRpb0J1ZmZlcn0gZnJvbSBcIi4uL2luZGRiX2F1ZGlvX2J1ZmZlclwiO1xyXG5pbXBvcnQge0F1ZGlvU291cmNlV29ya2xldE1vZHVsZUxvYWRlcn0gZnJvbSBcIi4vYXVkaW9fc291cmNlX3dvcmtsZXRfbW9kdWxlX2xvYWRlclwiO1xyXG5pbXBvcnQge0luZGV4ZWREYkF1ZGlvQnVmZmVyU291cmNlTm9kZX0gZnJvbSBcIi4vaW5kZGJfYXVkaW9fYnVmZmVyX3NvdXJjZV9ub2RlXCI7XHJcbmltcG9ydCB7QXVkaW9Tb3VyY2VOb2RlfSBmcm9tIFwiLi9hdWRpb19zb3VyY2Vfbm9kZVwiO1xyXG5pbXBvcnQge05ldEF1ZGlvQnVmZmVyfSBmcm9tIFwiLi4vbmV0X2F1ZGlvX2J1ZmZlclwiO1xyXG5pbXBvcnQge05ldEF1ZGlvQnVmZmVyU291cmNlTm9kZX0gZnJvbSBcIi4vbmV0X2F1ZGlvX2J1ZmZlcl9zb3VyY2Vfbm9kZVwiO1xyXG5pbXBvcnQge0F1ZGlvQnVmZmVyU291cmNlLCBBdWRpb1NvdXJjZX0gZnJvbSBcIi4uL2F1ZGlvX2RhdGFfaG9sZGVyXCI7XHJcbmltcG9ydCB7QXVkaW9Db250ZXh0UHJvdmlkZXJ9IGZyb20gXCIuLi9jb250ZXh0XCI7XHJcblxyXG5cclxuXHJcbiAgICBleHBvcnQgZW51bSAgRXZlbnRUeXBlIHtDTE9TRUQsUkVBRFksU1RBUlRFRCxQT1NfVVBEQVRFLCBTVE9QUEVELCBFTkRFRCxFUlJPUn1cclxuXHJcbiAgICBleHBvcnQgY2xhc3MgQXVkaW9QbGF5ZXJFdmVudHtcclxuXHJcbiAgICAgICAgcHJpdmF0ZSByZWFkb25seSBfdHlwZTpFdmVudFR5cGU7XHJcbiAgICAgICAgcHJpdmF0ZSByZWFkb25seSBfdGltZVBvc2l0aW9uOm51bWJlciB8IHVuZGVmaW5lZDtcclxuXHJcbiAgICAgICAgY29uc3RydWN0b3IodHlwZTpFdmVudFR5cGUsIHRpbWVQb3NpdGlvbj86bnVtYmVyKSB7XHJcbiAgICAgICAgICAgIHRoaXMuX3R5cGUgPSB0eXBlO1xyXG4gICAgICAgICAgICB0aGlzLl90aW1lUG9zaXRpb24gPSB0aW1lUG9zaXRpb247XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICBnZXQgdHlwZSgpIHtcclxuICAgICAgICAgICAgcmV0dXJuIHRoaXMuX3R5cGU7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICBnZXQgdGltZVBvc2l0aW9uKCkge1xyXG4gICAgICAgICAgICByZXR1cm4gdGhpcy5fdGltZVBvc2l0aW9uO1xyXG4gICAgICAgIH1cclxuICAgIH1cclxuICAgIGV4cG9ydCBpbnRlcmZhY2UgQXVkaW9QbGF5ZXJMaXN0ZW5lciB7XHJcbiAgICAgICAgYXVkaW9QbGF5ZXJVcGRhdGUoZTpBdWRpb1BsYXllckV2ZW50KTp2b2lkO1xyXG4gICAgfVxyXG5cclxuICAgIGV4cG9ydCBjbGFzcyBBdWRpb1BsYXllciB7XHJcblxyXG4gICAgICAgIGdldCBhdXRvUGxheU9uU2VsZWN0VG9nZ2xlQWN0aW9uKCk6IEFjdGlvbjxib29sZWFuPiB7XHJcbiAgICAgICAgICAgIHJldHVybiB0aGlzLl9hdXRvUGxheU9uU2VsZWN0VG9nZ2xlQWN0aW9uO1xyXG4gICAgICAgIH1cclxuICAgICAgICBwdWJsaWMgc3RhdGljIERFRkFVTFRfQlVGU0laRTpudW1iZXIgPSA4MTkyO1xyXG4gICAgICAgIHByaXZhdGUgcnVubmluZz1mYWxzZTtcclxuICAgICAgICBwcml2YXRlIHJlYWRvbmx5IF9zdGFydEFjdGlvbjpBY3Rpb248dm9pZD47XHJcbiAgICAgICAgcHJpdmF0ZSByZWFkb25seSBfc3RhcnRTZWxlY3Rpb25BY3Rpb246QWN0aW9uPHZvaWQ+O1xyXG4gICAgICAgIHByaXZhdGUgcmVhZG9ubHkgX2F1dG9QbGF5T25TZWxlY3RUb2dnbGVBY3Rpb246QWN0aW9uPGJvb2xlYW4+O1xyXG4gICAgICAgIHByaXZhdGUgcmVhZG9ubHkgX3N0b3BBY3Rpb246QWN0aW9uPHZvaWQ+O1xyXG4gICAgICAgIGJ1ZlNpemU6bnVtYmVyO1xyXG4gICAgICAgIGNvbnRleHQ6QXVkaW9Db250ZXh0fG51bGw9bnVsbDtcclxuICAgICAgICByZWFkeT1mYWxzZTtcclxuICAgICAgICBsaXN0ZW5lcjpBdWRpb1BsYXllckxpc3RlbmVyO1xyXG4gICAgICAgIF9hdWRpb0NsaXA6QXVkaW9DbGlwfG51bGw9bnVsbDtcclxuICAgICAgICBwcml2YXRlIF9hdWRpb1NvdXJjZTpBdWRpb1NvdXJjZXxudWxsPW51bGw7XHJcbiAgICAgICAgc291cmNlQnVmZmVyTm9kZTpBdWRpb0J1ZmZlclNvdXJjZU5vZGV8bnVsbD1udWxsO1xyXG4gICAgICAgIHNvdXJjZUF1ZGlvV29ya2xldE5vZGU6QXVkaW9Tb3VyY2VOb2RlfG51bGw9bnVsbDtcclxuXHJcbiAgICAgICAgYnVmZlBvczpudW1iZXI7XHJcbiAgICAgICAgcHJpdmF0ZSB6ZXJvQnVmQ250Om51bWJlcjtcclxuICAgICAgICBuOmFueTtcclxuICAgICAgICB6YjpGbG9hdDMyQXJyYXk7XHJcbiAgICAgICAgcHJpdmF0ZSBwbGF5U3RhcnRUaW1lOm51bWJlcnxudWxsPW51bGw7XHJcblxyXG4gICAgICAgIHByaXZhdGUgdGltZXJWYXI6bnVtYmVyfG51bGw9bnVsbDtcclxuXHJcbiAgICAgICAgY29uc3RydWN0b3IobGlzdGVuZXI6QXVkaW9QbGF5ZXJMaXN0ZW5lcikge1xyXG4gICAgICAgICAgICB0aGlzLmxpc3RlbmVyPWxpc3RlbmVyO1xyXG4gICAgICAgICAgICB0aGlzLmJ1ZlNpemUgPSBBdWRpb1BsYXllci5ERUZBVUxUX0JVRlNJWkU7XHJcbiAgICAgICAgICAgIHRoaXMubj1uYXZpZ2F0b3I7XHJcbiAgICAgICAgICAgIHRoaXMuYnVmZlBvcz0wO1xyXG4gICAgICAgICAgICB0aGlzLnplcm9CdWZDbnQ9MDtcclxuICAgICAgICAgICAgdGhpcy56YiA9IG5ldyBGbG9hdDMyQXJyYXkodGhpcy5idWZTaXplKTtcclxuICAgICAgICAgICAgdGhpcy5fc3RhcnRBY3Rpb24gPSBuZXcgQWN0aW9uKCdTdGFydCcpO1xyXG4gICAgICAgICAgICB0aGlzLl9zdGFydEFjdGlvbi5kaXNhYmxlZCA9IHRydWU7XHJcbiAgICAgICAgICAgIHRoaXMuX3N0YXJ0QWN0aW9uLm9uQWN0aW9uID0gKCk9PnRoaXMuc3RhcnQoKTtcclxuICAgICAgICAgICAgdGhpcy5fc3RhcnRTZWxlY3Rpb25BY3Rpb249bmV3IEFjdGlvbignU3RhcnQgc2VsZWN0ZWQnKVxyXG4gICAgICAgICAgICB0aGlzLl9zdGFydFNlbGVjdGlvbkFjdGlvbi5kaXNhYmxlZD10cnVlXHJcbiAgICAgICAgICAgIHRoaXMuX3N0YXJ0U2VsZWN0aW9uQWN0aW9uLm9uQWN0aW9uID0gKCk9PnRoaXMuc3RhcnRTZWxlY3RlZCgpO1xyXG4gICAgICAgICAgICB0aGlzLl9hdXRvUGxheU9uU2VsZWN0VG9nZ2xlQWN0aW9uPW5ldyBBY3Rpb248Ym9vbGVhbj4oXCJBdXRvcGxheSBvbiBzZWxlY3RcIixmYWxzZSk7XHJcbiAgICAgICAgICAgIHRoaXMuX3N0b3BBY3Rpb24gPSBuZXcgQWN0aW9uKCdTdG9wJyk7XHJcbiAgICAgICAgICAgIHRoaXMuX3N0b3BBY3Rpb24uZGlzYWJsZWQgPSB0cnVlO1xyXG4gICAgICAgICAgICB0aGlzLl9zdG9wQWN0aW9uLm9uQWN0aW9uID0gKCk9PnRoaXMuc3RvcCgpO1xyXG5cclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIHByaXZhdGUgX2F1ZGlvQ29udGV4dCgpOkF1ZGlvQ29udGV4dHxudWxse1xyXG4gICAgICAgICAgICBpZighdGhpcy5jb250ZXh0KXtcclxuICAgICAgICAgICAgICAgIHRoaXMuY29udGV4dD1BdWRpb0NvbnRleHRQcm92aWRlci5hdWRpb0NvbnRleHRJbnN0YW5jZSgpO1xyXG4gICAgICAgICAgICAgICAgaWYodGhpcy5jb250ZXh0KSB7XHJcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5jb250ZXh0LmFkZEV2ZW50TGlzdGVuZXIoJ3N0YXRlY2hhbmdlJywgKGV2KSA9PiB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZih0aGlzLmNvbnRleHQgJiYgdGhpcy5jb250ZXh0LnN0YXRlIT09J3J1bm5pbmcnKXtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnN0b3AoKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgICk7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgcmV0dXJuIHRoaXMuY29udGV4dDtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIGdldCBzdGFydEFjdGlvbigpIHtcclxuICAgICAgICAgICAgcmV0dXJuIHRoaXMuX3N0YXJ0QWN0aW9uO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgZ2V0IHN0YXJ0U2VsZWN0aW9uQWN0aW9uKCl7XHJcbiAgICAgICAgICByZXR1cm4gdGhpcy5fc3RhcnRTZWxlY3Rpb25BY3Rpb25cclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIGdldCBzdG9wQWN0aW9uKCkge1xyXG4gICAgICAgICAgICByZXR1cm4gdGhpcy5fc3RvcEFjdGlvbjtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIHNldCBhdWRpb0NsaXAoYXVkaW9DbGlwOkF1ZGlvQ2xpcHwgbnVsbCkge1xyXG4gICAgICAgICAgdGhpcy5fYXVkaW9DbGlwPWF1ZGlvQ2xpcFxyXG4gICAgICAgICAgICBsZXQgbGVuZ3RoID0gMDtcclxuICAgICAgICAgICAgbGV0IGNocyA9IDA7XHJcbiAgICAgICAgICAgIGlmIChhdWRpb0NsaXAgJiYgYXVkaW9DbGlwLmF1ZGlvRGF0YUhvbGRlcikge1xyXG4gICAgICAgICAgICAgICAgbGV0IGF1ZGlvRGF0YUhvbGRlcj1hdWRpb0NsaXAuYXVkaW9EYXRhSG9sZGVyO1xyXG4gICAgICAgICAgICAgICAgY2hzID0gYXVkaW9EYXRhSG9sZGVyLm51bWJlck9mQ2hhbm5lbHNcclxuICAgICAgICAgICAgICAgIGlmIChjaHMgPiAwKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgbGVuZ3RoID0gYXVkaW9EYXRhSG9sZGVyLmZyYW1lTGVuO1xyXG4gICAgICAgICAgICAgICAgICAgIC8vaWYgKGNocyA+IHRoaXMuY29udGV4dC5kZXN0aW5hdGlvbi5tYXhDaGFubmVsQ291bnQpIHtcclxuICAgICAgICAgICAgICAgICAgICAvLyAgICAvLyBUT0RPIGV4Y2VwdGlvblxyXG4gICAgICAgICAgICAgICAgICAgIC8vfVxyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgdGhpcy5hdWRpb1NvdXJjZT1hdWRpb0RhdGFIb2xkZXIuYXVkaW9Tb3VyY2U7XHJcblxyXG4gICAgICAgICAgICAgICAgYXVkaW9DbGlwLmFkZFNlbGVjdGlvbk9ic2VydmVyKChhYyk9PiB7XHJcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5fc3RhcnRTZWxlY3Rpb25BY3Rpb24uZGlzYWJsZWQgPSB0aGlzLnN0YXJ0U2VsZWN0aW9uRGlzYWJsZWQoKTtcclxuICAgICAgICAgICAgICAgICAgICBpZiAoIXRoaXMuc3RhcnRTZWxlY3Rpb25BY3Rpb24uZGlzYWJsZWQgJiYgdGhpcy5fYXV0b1BsYXlPblNlbGVjdFRvZ2dsZUFjdGlvbi52YWx1ZSkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgdGhpcy5zdGFydFNlbGVjdGVkKCk7XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICApXHJcbiAgICAgICAgICAgIH1lbHNle1xyXG4gICAgICAgICAgICAgICAgdGhpcy5hdWRpb1NvdXJjZT1udWxsO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgZ2V0IGF1ZGlvU291cmNlKCk6IEF1ZGlvU291cmNlIHwgbnVsbCB7XHJcbiAgICAgICAgcmV0dXJuIHRoaXMuX2F1ZGlvU291cmNlO1xyXG4gICAgICB9XHJcblxyXG4gICAgICBzZXQgYXVkaW9Tb3VyY2UodmFsdWU6IEF1ZGlvU291cmNlIHwgbnVsbCkge1xyXG4gICAgICAgIHRoaXMuc3RvcCgpO1xyXG4gICAgICAgIHRoaXMuX2F1ZGlvU291cmNlID0gdmFsdWU7XHJcbiAgICAgICAgICAgIGlmICh0aGlzLl9hdWRpb1NvdXJjZSkge1xyXG5cclxuICAgICAgICAgICAgICAgIHRoaXMucmVhZHkgPSB0cnVlO1xyXG4gICAgICAgICAgICAgICAgdGhpcy51cGRhdGVTdGFydEFjdGlvbnMoKTtcclxuICAgICAgICAgICAgICAgIGlmICh0aGlzLmxpc3RlbmVyKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5saXN0ZW5lci5hdWRpb1BsYXllclVwZGF0ZShuZXcgQXVkaW9QbGF5ZXJFdmVudChFdmVudFR5cGUuUkVBRFkpKTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgfWVsc2Uge1xyXG4gICAgICAgICAgICAgIHRoaXMucmVhZHkgPSBmYWxzZTtcclxuICAgICAgICAgICAgICB0aGlzLnVwZGF0ZVN0YXJ0QWN0aW9ucygpO1xyXG4gICAgICAgICAgICAgIGlmICh0aGlzLmxpc3RlbmVyKSB7XHJcbiAgICAgICAgICAgICAgICB0aGlzLmxpc3RlbmVyLmF1ZGlvUGxheWVyVXBkYXRlKG5ldyBBdWRpb1BsYXllckV2ZW50KEV2ZW50VHlwZS5DTE9TRUQpKTtcclxuICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgfVxyXG5cclxuICAgICAgICBwcml2YXRlIF9sb2FkU291cmNlV29ya2xldEFuZEluaXRTdGFydCgpe1xyXG4gICAgICAgICAgICBpZih0aGlzLmNvbnRleHQpIHtcclxuICAgICAgICAgICAgICAgIEF1ZGlvU291cmNlV29ya2xldE1vZHVsZUxvYWRlci5sb2FkTW9kdWxlKHRoaXMuY29udGV4dCkudGhlbigoKSA9PiB7XHJcbiAgICAgICAgICAgICAgICAgICAgLy9jb25zb2xlLmRlYnVnKFwiUGxheWVyIHJlYWR5LiAoIGJ5IFBsYXllcjo6X2xvYWRTb3VyY2VXb3JrbGV0QW5kSW5pdFN0YXJ0KClcIik7XHJcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5yZWFkeSA9IHRydWU7XHJcbiAgICAgICAgICAgICAgICAgICAgdGhpcy51cGRhdGVTdGFydEFjdGlvbnMoKTtcclxuICAgICAgICAgICAgICAgICAgICBpZiAodGhpcy5saXN0ZW5lcikge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmxpc3RlbmVyLmF1ZGlvUGxheWVyVXBkYXRlKG5ldyBBdWRpb1BsYXllckV2ZW50KEV2ZW50VHlwZS5SRUFEWSkpO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIH0pLmNhdGNoKChlcnJvcjogYW55KSA9PiB7XHJcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5yZWFkeSA9IGZhbHNlO1xyXG4gICAgICAgICAgICAgICAgICAgIHRoaXMudXBkYXRlU3RhcnRBY3Rpb25zKCk7XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKHRoaXMubGlzdGVuZXIpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5saXN0ZW5lci5hdWRpb1BsYXllclVwZGF0ZShuZXcgQXVkaW9QbGF5ZXJFdmVudChFdmVudFR5cGUuQ0xPU0VEKSk7XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgIGNvbnNvbGUuZXJyb3IoJ0NvdWxkIG5vdCBhZGQgbW9kdWxlICcgKyBlcnJvcik7XHJcbiAgICAgICAgICAgICAgICB9KTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuXHJcblxyXG4gIHByaXZhdGUgX3N0YXJ0QXVkaW9Tb3VyY2VXb3JrbGV0Tm9kZSgpe1xyXG4gICAgICB0aGlzLl9sb2FkU291cmNlV29ya2xldEFuZEluaXRTdGFydCgpO1xyXG4gICAgICAgICAgaWYodGhpcy5jb250ZXh0ICYmIHRoaXMuc291cmNlQXVkaW9Xb3JrbGV0Tm9kZSkge1xyXG4gICAgICAgICAgICB0aGlzLnNvdXJjZUF1ZGlvV29ya2xldE5vZGUub25wcm9jZXNzb3JlcnJvciA9IChldjogRXZlbnQpID0+IHtcclxuICAgICAgICAgICAgICBsZXQgbXNnID0gJ1Vua253b24gZXJyb3InO1xyXG4gICAgICAgICAgICAgIGlmIChldiBpbnN0YW5jZW9mIEVycm9yRXZlbnQpIHtcclxuICAgICAgICAgICAgICAgIG1zZyA9IGV2Lm1lc3NhZ2U7XHJcbiAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgIGNvbnNvbGUuZXJyb3IoXCJBdWRpbyBzb3VyY2Ugd29ya2xldCBlcnJvcjogXCIgKyBtc2cpO1xyXG4gICAgICAgICAgICAgIGlmICh0aGlzLmxpc3RlbmVyKSB7XHJcbiAgICAgICAgICAgICAgICAvLyBUT0RPXHJcbiAgICAgICAgICAgICAgICAvLyB0aGlzLmxpc3RlbmVyLmVycm9yKG1zZyk7XHJcbiAgICAgICAgICAgICAgICAvLyB0aGlzLmxpc3RlbmVyLmF1ZGlvUGxheWVyVXBkYXRlKG5ldyBBdWRpb1BsYXllckV2ZW50KCkpO1xyXG4gICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgfTtcclxuXHJcbiAgICAgICAgICAgIHRoaXMuc291cmNlQXVkaW9Xb3JrbGV0Tm9kZS5jb25uZWN0KHRoaXMuY29udGV4dC5kZXN0aW5hdGlvbik7IC8vIHRoaXMgYWxyZWFkeSBzdGFydHMgcGxheWluZ1xyXG4gICAgICAgICAgICB0aGlzLnNvdXJjZUF1ZGlvV29ya2xldE5vZGUub25lbmRlZCA9ICgpID0+IHRoaXMub25lbmRlZCgpO1xyXG4gICAgICAgICAgICB0aGlzLnJ1bm5pbmcgPSB0cnVlO1xyXG4gICAgICAgICAgICB0aGlzLnNvdXJjZUF1ZGlvV29ya2xldE5vZGUuc3RhcnQoKTtcclxuICAgICAgICAgICAgLy9jb25zb2xlLmRlYnVnKFwiUGxheWJhY2sgc3RhcnQgYWN0aW9uIGVuYWJsZWQuICggYnkgUGxheWVyOjpfc3RhcnRBdWRpb1NvdXJjZVdvcmtsZXROb2RlKClcIik7XHJcbiAgICAgICAgICAgIHRoaXMuX3N0YXJ0QWN0aW9uLmRpc2FibGVkID0gdHJ1ZTtcclxuICAgICAgICAgICAgdGhpcy5fc3RhcnRTZWxlY3Rpb25BY3Rpb24uZGlzYWJsZWQgPSB0cnVlXHJcbiAgICAgICAgICAgIHRoaXMuX3N0b3BBY3Rpb24uZGlzYWJsZWQgPSBmYWxzZTtcclxuXHJcbiAgICAgICAgICAgIGlmICh0aGlzLmxpc3RlbmVyKSB7XHJcbiAgICAgICAgICAgICAgdGhpcy5saXN0ZW5lci5hdWRpb1BsYXllclVwZGF0ZShuZXcgQXVkaW9QbGF5ZXJFdmVudChFdmVudFR5cGUuU1RBUlRFRCkpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICB9XHJcblxyXG4gIH1cclxuXHJcbiAgICAgICAgc3RhcnQoKSB7XHJcblxyXG4gICAgICAgICAgICB0aGlzLl9hdWRpb0NvbnRleHQoKTtcclxuXHJcbiAgICAgICAgICAgIGlmKHRoaXMuY29udGV4dCkge1xyXG4gICAgICAgICAgICAgICAgaWYgKCF0aGlzLl9zdGFydEFjdGlvbi5kaXNhYmxlZCAmJiAhdGhpcy5ydW5uaW5nKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKHRoaXMuY29udGV4dC5zdGF0ZSA9PT0gJ3N1c3BlbmRlZCcpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5jb250ZXh0LnJlc3VtZSgpLnRoZW4oKCkgPT4ge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5fc3RhcnQoKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgfSkuY2F0Y2goKHJlYXNvbikgPT4ge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc29sZS5lcnJvcihyZWFzb24ubWVzc2FnZSgpKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRocm93IHJlYXNvbjtcclxuICAgICAgICAgICAgICAgICAgICAgICAgfSlcclxuICAgICAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKHRoaXMuY29udGV4dC5zdGF0ZSA9PT0gJ2Nsb3NlZCcpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgbXNnID0gJ0Vycm9yOiBDYW5ub3Qgc3RhcnQgcGxheWJhY2suIEF1ZGlvIGNvbnRleHQgaXMgYWxyZWFkeSBjbG9zZWQhJztcclxuICAgICAgICAgICAgICAgICAgICAgICAgY29uc29sZS5lcnJvcihtc2cpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IobXNnKTtcclxuICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLl9zdGFydCgpO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgdXBkYXRlU3RhcnRBY3Rpb25zKCl7XHJcblxyXG4gICAgICAgICAgaWYodGhpcy5yZWFkeSl7XHJcbiAgICAgICAgICAgIGlmKHRoaXMuX2F1ZGlvU291cmNlIGluc3RhbmNlb2YgQXVkaW9CdWZmZXJTb3VyY2UgfHwgdGhpcy5fYXVkaW9Tb3VyY2UgaW5zdGFuY2VvZiBBcnJheUF1ZGlvQnVmZmVyIHx8IHRoaXMuX2F1ZGlvU291cmNlIGluc3RhbmNlb2YgSW5kZXhlZERiQXVkaW9CdWZmZXIpe1xyXG4gICAgICAgICAgICAgIHRoaXMuX3N0YXJ0QWN0aW9uLmRpc2FibGVkPWZhbHNlO1xyXG4gICAgICAgICAgICAgIHRoaXMuX3N0YXJ0U2VsZWN0aW9uQWN0aW9uLmRpc2FibGVkPXRoaXMuc3RhcnRTZWxlY3Rpb25EaXNhYmxlZCgpO1xyXG4gICAgICAgICAgICB9ZWxzZXtcclxuICAgICAgICAgICAgICBpZih0aGlzLl9hdWRpb1NvdXJjZSBpbnN0YW5jZW9mIE5ldEF1ZGlvQnVmZmVyKXtcclxuICAgICAgICAgICAgICAgIHRoaXMuX2F1ZGlvU291cmNlLmFkZE9uUmVhZHlMaXN0ZW5lcigoKT0+e1xyXG4gICAgICAgICAgICAgICAgICB0aGlzLl9zdGFydEFjdGlvbi5kaXNhYmxlZD1mYWxzZTtcclxuICAgICAgICAgICAgICAgICAgdGhpcy5fc3RhcnRTZWxlY3Rpb25BY3Rpb24uZGlzYWJsZWQ9dGhpcy5zdGFydFNlbGVjdGlvbkRpc2FibGVkKCk7XHJcbiAgICAgICAgICAgICAgICB9KTtcclxuICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgIH1lbHNle1xyXG4gICAgICAgICAgICB0aGlzLl9zdGFydEFjdGlvbi5kaXNhYmxlZD10cnVlO1xyXG4gICAgICAgICAgICB0aGlzLl9zdGFydFNlbGVjdGlvbkFjdGlvbi5kaXNhYmxlZD10cnVlO1xyXG4gICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgc3RhcnRTZWxlY3Rpb25EaXNhYmxlZCgpe1xyXG4gICAgICAgICAgcmV0dXJuICEodGhpcy5fYXVkaW9DbGlwICYmICF0aGlzLnN0YXJ0QWN0aW9uLmRpc2FibGVkICYmIHRoaXMuX2F1ZGlvQ2xpcC5zZWxlY3Rpb24gKVxyXG4gICAgICAgIH1cclxuXHJcblxyXG4gICAgICAgIHByaXZhdGUgX3N0YXJ0KHBsYXlTZWxlY3Rpb249ZmFsc2Upe1xyXG4gICAgICAgICAgICAgICAgaWYoIXRoaXMuY29udGV4dCl7XHJcbiAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwiQ291bGQgbm90IGdldCBhdWRpbyBjb250ZXh0IVwiKTtcclxuICAgICAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICBpZiAodGhpcy5fYXVkaW9Tb3VyY2UgaW5zdGFuY2VvZiBBdWRpb0J1ZmZlclNvdXJjZSkge1xyXG4gICAgICAgICAgICB0aGlzLnNvdXJjZUJ1ZmZlck5vZGUgPSB0aGlzLmNvbnRleHQuY3JlYXRlQnVmZmVyU291cmNlKCk7XHJcbiAgICAgICAgICAgIHRoaXMuc291cmNlQnVmZmVyTm9kZS5idWZmZXIgPSB0aGlzLl9hdWRpb1NvdXJjZS5hdWRpb0J1ZmZlcjtcclxuICAgICAgICAgICAgdGhpcy5zb3VyY2VCdWZmZXJOb2RlLmNvbm5lY3QodGhpcy5jb250ZXh0LmRlc3RpbmF0aW9uKTtcclxuICAgICAgICAgICAgdGhpcy5zb3VyY2VCdWZmZXJOb2RlLm9uZW5kZWQgPSAoKSA9PiB0aGlzLm9uZW5kZWQoKTtcclxuICAgICAgICAgICAgdGhpcy5wbGF5U3RhcnRUaW1lID0gdGhpcy5jb250ZXh0LmN1cnJlbnRUaW1lO1xyXG4gICAgICAgICAgICB0aGlzLnJ1bm5pbmcgPSB0cnVlO1xyXG4gICAgICAgICAgICAvLyB1bmZvcnR1bmF0ZWx5IFdlYiBBdWRpbyBBUEkgdXNlcyB0aW1lIHZhbHVlcyBub3QgZnJhbWVzXHJcbiAgICAgICAgICAgIGNvbnN0IGFjID0gdGhpcy5fYXVkaW9DbGlwXHJcbiAgICAgICAgICAgIGxldCBvZmZzZXQgPSAwO1xyXG4gICAgICAgICAgICBpZiAocGxheVNlbGVjdGlvbiAmJiBhYyAmJiBhYy5zZWxlY3Rpb24pIHtcclxuXHJcbiAgICAgICAgICAgICAgY29uc3QgcyA9IGFjLnNlbGVjdGlvbjtcclxuICAgICAgICAgICAgICBjb25zdCBzciA9IGFjLmF1ZGlvRGF0YUhvbGRlci5zYW1wbGVSYXRlO1xyXG4gICAgICAgICAgICAgIG9mZnNldCA9IHMubGVmdEZyYW1lIC8gc3I7XHJcbiAgICAgICAgICAgICAgY29uc3Qgc3RvcFBvc0luc2VjcyA9IHMucmlnaHRGcmFtZSAvIHNyO1xyXG4gICAgICAgICAgICAgIGNvbnN0IGR1ciA9IHN0b3BQb3NJbnNlY3MgLSBvZmZzZXQ7XHJcbiAgICAgICAgICAgICAgdGhpcy5zb3VyY2VCdWZmZXJOb2RlLnN0YXJ0KDAsIG9mZnNldCwgZHVyKVxyXG4gICAgICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICAgIHRoaXMuc291cmNlQnVmZmVyTm9kZS5zdGFydCgpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIHRoaXMucGxheVN0YXJ0VGltZSA9IHRoaXMuY29udGV4dC5jdXJyZW50VGltZSAtIG9mZnNldDtcclxuICAgICAgICAgICAgdGhpcy5fc3RhcnRBY3Rpb24uZGlzYWJsZWQgPSB0cnVlO1xyXG4gICAgICAgICAgICB0aGlzLl9zdGFydFNlbGVjdGlvbkFjdGlvbi5kaXNhYmxlZCA9IHRydWVcclxuICAgICAgICAgICAgdGhpcy5fc3RvcEFjdGlvbi5kaXNhYmxlZCA9IGZhbHNlO1xyXG5cclxuICAgICAgICAgICAgaWYgKHRoaXMubGlzdGVuZXIpIHtcclxuICAgICAgICAgICAgICB0aGlzLmxpc3RlbmVyLmF1ZGlvUGxheWVyVXBkYXRlKG5ldyBBdWRpb1BsYXllckV2ZW50KEV2ZW50VHlwZS5TVEFSVEVEKSk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgIH0gZWxzZSBpZiAodGhpcy5fYXVkaW9Tb3VyY2UgaW5zdGFuY2VvZiBBcnJheUF1ZGlvQnVmZmVyIHx8IHRoaXMuX2F1ZGlvU291cmNlIGluc3RhbmNlb2YgSW5kZXhlZERiQXVkaW9CdWZmZXIgfHwgdGhpcy5fYXVkaW9Tb3VyY2UgaW5zdGFuY2VvZiBOZXRBdWRpb0J1ZmZlcikge1xyXG4gICAgICAgICAgICAgIEF1ZGlvU291cmNlV29ya2xldE1vZHVsZUxvYWRlci5sb2FkTW9kdWxlKHRoaXMuY29udGV4dCkudGhlbigoKSA9PiB7XHJcbiAgICAgICAgICAgICAgICAgIHRoaXMucGxheVN0YXJ0VGltZSA9IG51bGw7XHJcbiAgICAgICAgICAgICAgICAgIGlmICh0aGlzLmNvbnRleHQpIHtcclxuICAgICAgICAgICAgICAgICAgaWYgKHRoaXMuX2F1ZGlvU291cmNlIGluc3RhbmNlb2YgQXJyYXlBdWRpb0J1ZmZlcikge1xyXG4gICAgICAgICAgICAgICAgICAgICAgY29uc3QgYWFic24gPSBuZXcgQXJyYXlBdWRpb0J1ZmZlclNvdXJjZU5vZGUodGhpcy5jb250ZXh0KTtcclxuICAgICAgICAgICAgICAgICAgICAgIGFhYnNuLmFycmF5QXVkaW9CdWZmZXIgPSB0aGlzLl9hdWRpb1NvdXJjZTtcclxuICAgICAgICAgICAgICAgICAgICAgIHRoaXMuc291cmNlQXVkaW9Xb3JrbGV0Tm9kZSA9IGFhYnNuO1xyXG4gICAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKHRoaXMuX2F1ZGlvU291cmNlIGluc3RhbmNlb2YgSW5kZXhlZERiQXVkaW9CdWZmZXIpIHtcclxuICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGlhc24gPSBuZXcgSW5kZXhlZERiQXVkaW9CdWZmZXJTb3VyY2VOb2RlKHRoaXMuY29udGV4dCk7XHJcbiAgICAgICAgICAgICAgICAgICAgICBpYXNuLmluZGRiQXVkaW9CdWZmZXIgPSB0aGlzLl9hdWRpb1NvdXJjZTtcclxuICAgICAgICAgICAgICAgICAgICAgIHRoaXMuc291cmNlQXVkaW9Xb3JrbGV0Tm9kZSA9IGlhc247XHJcbiAgICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAodGhpcy5fYXVkaW9Tb3VyY2UgaW5zdGFuY2VvZiBOZXRBdWRpb0J1ZmZlcikge1xyXG4gICAgICAgICAgICAgICAgICAgICAgY29uc3QgbmFic24gPSBuZXcgTmV0QXVkaW9CdWZmZXJTb3VyY2VOb2RlKHRoaXMuY29udGV4dCk7XHJcbiAgICAgICAgICAgICAgICAgICAgICBuYWJzbi5uZXRBdWRpb0J1ZmZlciA9IHRoaXMuX2F1ZGlvU291cmNlO1xyXG4gICAgICAgICAgICAgICAgICAgICAgdGhpcy5zb3VyY2VBdWRpb1dvcmtsZXROb2RlID0gbmFic247XHJcbiAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgaWYgKHRoaXMuc291cmNlQXVkaW9Xb3JrbGV0Tm9kZSkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgdGhpcy5zb3VyY2VBdWRpb1dvcmtsZXROb2RlLm9ucHJvY2Vzc29yZXJyb3IgPSAoZXY6IEV2ZW50KSA9PiB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgbGV0IG1zZyA9ICdVbmtud29uIGVycm9yJztcclxuICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoZXYgaW5zdGFuY2VvZiBFcnJvckV2ZW50KSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1zZyA9IGV2Lm1lc3NhZ2U7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnNvbGUuZXJyb3IoXCJBdWRpbyBzb3VyY2Ugd29ya2xldCBlcnJvcjogXCIgKyBtc2cpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgIGlmICh0aGlzLmxpc3RlbmVyKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMubGlzdGVuZXIuYXVkaW9QbGF5ZXJVcGRhdGUobmV3IEF1ZGlvUGxheWVyRXZlbnQoRXZlbnRUeXBlLkVSUk9SKSk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgICAgfTtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICB0aGlzLnNvdXJjZUF1ZGlvV29ya2xldE5vZGUuY29ubmVjdCh0aGlzLmNvbnRleHQuZGVzdGluYXRpb24pOyAvLyB0aGlzIGFscmVhZHkgc3RhcnRzIHBsYXlpbmdcclxuICAgICAgICAgICAgICAgICAgICAgIHRoaXMuc291cmNlQXVkaW9Xb3JrbGV0Tm9kZS5vbmVuZGVkID0gKCkgPT4gdGhpcy5vbmVuZGVkKCk7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgICAgdGhpcy5ydW5uaW5nID0gdHJ1ZTtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICBjb25zdCBhYyA9IHRoaXMuX2F1ZGlvQ2xpcFxyXG4gICAgICAgICAgICAgICAgICAgICAgbGV0IG9mZnNldCA9IDBcclxuICAgICAgICAgICAgICAgICAgICAgIGlmIChwbGF5U2VsZWN0aW9uICYmIGFjICYmIGFjLnNlbGVjdGlvbikge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHMgPSBhYy5zZWxlY3Rpb247XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3Qgc3IgPSBhYy5hdWRpb0RhdGFIb2xkZXIuc2FtcGxlUmF0ZTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICBvZmZzZXQgPSBzLmxlZnRGcmFtZSAvIHNyO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHN0b3BQb3NJbnNlY3MgPSBzLnJpZ2h0RnJhbWUgLyBzcjtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBkdXIgPSBzdG9wUG9zSW5zZWNzIC0gb2Zmc2V0XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5zb3VyY2VBdWRpb1dvcmtsZXROb2RlLnN0YXJ0KDAsIG9mZnNldCwgZHVyKVxyXG4gICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnNvdXJjZUF1ZGlvV29ya2xldE5vZGUuc3RhcnQoKTtcclxuICAgICAgICAgICAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICAvL3RoaXMucGxheVN0YXJ0VGltZSA9IHRoaXMuY29udGV4dC5jdXJyZW50VGltZSAtIG9mZnNldDtcclxuICAgICAgICAgICAgICAgICAgICAgIHRoaXMuX3N0YXJ0QWN0aW9uLmRpc2FibGVkID0gdHJ1ZTtcclxuICAgICAgICAgICAgICAgICAgICAgIHRoaXMuX3N0YXJ0U2VsZWN0aW9uQWN0aW9uLmRpc2FibGVkID0gdHJ1ZVxyXG4gICAgICAgICAgICAgICAgICAgICAgdGhpcy5fc3RvcEFjdGlvbi5kaXNhYmxlZCA9IGZhbHNlO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAgIGlmICh0aGlzLmxpc3RlbmVyKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5saXN0ZW5lci5hdWRpb1BsYXllclVwZGF0ZShuZXcgQXVkaW9QbGF5ZXJFdmVudChFdmVudFR5cGUuU1RBUlRFRCkpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgIH0pLmNhdGNoKChlcnJvcjogYW55KSA9PiB7XHJcbiAgICAgICAgICAgICAgICAgIGNvbnNvbGUuZXJyb3IoZXJyb3IubWVzc2FnZSk7XHJcbiAgICAgICAgICAgICAgICAgIHRoaXMucmVhZHkgPSBmYWxzZTtcclxuICAgICAgICAgICAgICAgICAgdGhpcy51cGRhdGVTdGFydEFjdGlvbnMoKTtcclxuICAgICAgICAgICAgICAgICAgaWYgKHRoaXMubGlzdGVuZXIpIHtcclxuICAgICAgICAgICAgICAgICAgICAgIHRoaXMubGlzdGVuZXIuYXVkaW9QbGF5ZXJVcGRhdGUobmV3IEF1ZGlvUGxheWVyRXZlbnQoRXZlbnRUeXBlLkNMT1NFRCkpO1xyXG4gICAgICAgICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAgICAgICB0aHJvdyBlcnJvcjtcclxuICAgICAgICAgICAgICB9KTtcclxuXHJcbiAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgc3RhcnRTZWxlY3RlZCgpIHtcclxuICAgICAgICAgICAgdGhpcy5fYXVkaW9Db250ZXh0KCk7XHJcbiAgICAgICAgICBpZighdGhpcy5jb250ZXh0KXtcclxuICAgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJDb3VsZCBub3QgZ2V0IGF1ZGlvIGNvbnRleHQhXCIpO1xyXG4gICAgICAgICAgfVxyXG5cclxuICAgICAgICAgIGlmKCF0aGlzLl9zdGFydEFjdGlvbi5kaXNhYmxlZCAmJiAhdGhpcy5ydW5uaW5nKSB7XHJcbiAgICAgICAgICBpZiAodGhpcy5jb250ZXh0LnN0YXRlID09PSAnc3VzcGVuZGVkJykge1xyXG4gICAgICAgICAgICB0aGlzLmNvbnRleHQucmVzdW1lKCkudGhlbigoKSA9PiB7XHJcbiAgICAgICAgICAgICAgdGhpcy5fc3RhcnQodHJ1ZSk7XHJcbiAgICAgICAgICAgIH0pLmNhdGNoKChyZWFzb24pID0+IHtcclxuICAgICAgICAgICAgICBjb25zb2xlLmVycm9yKHJlYXNvbi5tZXNzYWdlKTtcclxuICAgICAgICAgICAgICB0aHJvdyByZWFzb247XHJcbiAgICAgICAgICAgIH0pXHJcbiAgICAgICAgICB9ZWxzZSBpZih0aGlzLmNvbnRleHQuc3RhdGU9PT0nY2xvc2VkJyl7XHJcbiAgICAgICAgICAgIGNvbnN0IG1zZz0nRXJyb3I6IENhbm5vdCBzdGFydCBwbGF5YmFjayBvZiBzZWxlY3Rpb24uIEF1ZGlvIGNvbnRleHQgaXMgYWxyZWFkeSBjbG9zZWQhJztcclxuICAgICAgICAgICAgY29uc29sZS5lcnJvcihtc2cpO1xyXG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IobXNnKTtcclxuICAgICAgICAgIH1lbHNle1xyXG4gICAgICAgICAgICB0aGlzLl9zdGFydCh0cnVlKTtcclxuICAgICAgICAgIH1cclxuICAgICAgICB9XHJcbiAgICAgIH1cclxuXHJcbiAgICAgICAgc3RvcCgpe1xyXG4gICAgICAgICAgICBpZih0aGlzLnJ1bm5pbmcpIHtcclxuICAgICAgICAgICAgICAgIGlmICh0aGlzLnNvdXJjZUJ1ZmZlck5vZGUpIHtcclxuICAgICAgICAgICAgICAgICAgICB0aGlzLnNvdXJjZUJ1ZmZlck5vZGUuc3RvcCgpO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgaWYodGhpcy5zb3VyY2VBdWRpb1dvcmtsZXROb2RlKXtcclxuICAgICAgICAgICAgICAgICAgdGhpcy5zb3VyY2VBdWRpb1dvcmtsZXROb2RlLnN0b3AoKTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgaWYgKHRoaXMudGltZXJWYXIgIT09IG51bGwpIHtcclxuICAgICAgICAgICAgICAgICAgICB3aW5kb3cuY2xlYXJJbnRlcnZhbCh0aGlzLnRpbWVyVmFyKTtcclxuICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICB0aGlzLnJ1bm5pbmcgPSBmYWxzZTtcclxuICAgICAgICAgICAgICAgICAgaWYgKHRoaXMubGlzdGVuZXIpIHtcclxuICAgICAgICAgICAgICAgICAgICB0aGlzLmxpc3RlbmVyLmF1ZGlvUGxheWVyVXBkYXRlKG5ldyBBdWRpb1BsYXllckV2ZW50KEV2ZW50VHlwZS5TVE9QUEVEKSk7XHJcbiAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIG9uZW5kZWQoKSB7XHJcbiAgICAgICAgICAgIGlmKHRoaXMudGltZXJWYXIhPW51bGwpIHtcclxuICAgICAgICAgICAgICAgIHdpbmRvdy5jbGVhckludGVydmFsKHRoaXMudGltZXJWYXIpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIHRoaXMuX3N0YXJ0QWN0aW9uLmRpc2FibGVkID0gIXRoaXMuX2F1ZGlvU291cmNlO1xyXG4gICAgICAgICAgICB0aGlzLl9zdGFydFNlbGVjdGlvbkFjdGlvbi5kaXNhYmxlZD10aGlzLnN0YXJ0U2VsZWN0aW9uRGlzYWJsZWQoKVxyXG4gICAgICAgICAgICB0aGlzLl9zdG9wQWN0aW9uLmRpc2FibGVkID0gdHJ1ZTtcclxuICAgICAgICAgICAgdGhpcy5ydW5uaW5nPWZhbHNlO1xyXG4gICAgICAgICAgICBpZiAodGhpcy5saXN0ZW5lcikge1xyXG4gICAgICAgICAgICAgICAgdGhpcy5saXN0ZW5lci5hdWRpb1BsYXllclVwZGF0ZShuZXcgQXVkaW9QbGF5ZXJFdmVudChFdmVudFR5cGUuRU5ERUQpKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgZ2V0IHBsYXlQb3NpdGlvblRpbWUoKTpudW1iZXJ8bnVsbCB7XHJcbiAgICAgICAgICAgIGxldCBwcHQ9bnVsbDtcclxuICAgICAgICAgICAgaWYodGhpcy5jb250ZXh0ICYmIHRoaXMucGxheVN0YXJ0VGltZSE9PW51bGwpIHtcclxuICAgICAgICAgICAgICAgIHBwdD0gdGhpcy5jb250ZXh0LmN1cnJlbnRUaW1lIC0gdGhpcy5wbGF5U3RhcnRUaW1lO1xyXG4gICAgICAgICAgICB9ZWxzZSBpZih0aGlzLnNvdXJjZUF1ZGlvV29ya2xldE5vZGUpe1xyXG4gICAgICAgICAgICAgIHBwdD10aGlzLnNvdXJjZUF1ZGlvV29ya2xldE5vZGUucGxheVBvc2l0aW9uVGltZTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICByZXR1cm4gcHB0O1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgIGdldCBwbGF5UG9zaXRpb25GcmFtZXMoKTpudW1iZXJ8bnVsbCB7XHJcbiAgICAgICAgbGV0IHBwRnJzOm51bWJlcnxudWxsPW51bGw7XHJcbiAgICAgICBpZih0aGlzLl9hdWRpb1NvdXJjZSkge1xyXG4gICAgICAgICBsZXQgc3I9dGhpcy5fYXVkaW9Tb3VyY2Uuc2FtcGxlUmF0ZTtcclxuICAgICAgICAgaWYgKHNyKSB7XHJcbiAgICAgICAgICAgbGV0IHBwVGltZSA9IHRoaXMucGxheVBvc2l0aW9uVGltZTtcclxuICAgICAgICAgICBpZiAocHBUaW1lICE9PSBudWxsKSB7XHJcbiAgICAgICAgICAgICBwcEZycyA9IHNyICogcHBUaW1lO1xyXG4gICAgICAgICAgIH1cclxuICAgICAgICAgfVxyXG4gICAgICAgfVxyXG4gICAgICAgIHJldHVybiBwcEZycztcclxuICAgICAgfVxyXG5cclxuICAgIH1cclxuXHJcbiJdfQ==
|