speechrecorderng 2.21.4 → 2.22.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/{esm2015/lib/action/action.js → esm2020/lib/action/action.mjs} +0 -0
- package/{esm2015/lib/audio/audio_display.js → esm2020/lib/audio/audio_display.mjs} +5 -5
- package/esm2020/lib/audio/audio_player.mjs +276 -0
- package/esm2020/lib/audio/capture/capture.mjs +547 -0
- package/{esm2015/lib/audio/context.js → esm2020/lib/audio/context.mjs} +0 -0
- package/esm2020/lib/audio/dsp/level_measure.mjs +351 -0
- package/{esm2015/lib/audio/format.js → esm2020/lib/audio/format.mjs} +0 -0
- package/{esm2015/lib/audio/impl/wavformat.js → esm2020/lib/audio/impl/wavformat.mjs} +0 -0
- package/{esm2015/lib/audio/impl/wavwriter.js → esm2020/lib/audio/impl/wavwriter.mjs} +0 -0
- package/{esm2015/lib/audio/io/stream.js → esm2020/lib/audio/io/stream.mjs} +0 -0
- package/{esm2015/lib/audio/persistor.js → esm2020/lib/audio/persistor.mjs} +0 -0
- package/{esm2015/lib/audio/playback/player.js → esm2020/lib/audio/playback/player.mjs} +0 -0
- package/esm2020/lib/audio/ui/audio_canvas_layer_comp.mjs +376 -0
- package/{esm2015/lib/audio/ui/audio_display_control.js → esm2020/lib/audio/ui/audio_display_control.mjs} +5 -5
- package/{esm2015/lib/audio/ui/audio_display_scroll_pane.js → esm2020/lib/audio/ui/audio_display_scroll_pane.mjs} +5 -5
- package/{esm2015/lib/audio/ui/audiosignal.js → esm2020/lib/audio/ui/audiosignal.mjs} +5 -5
- package/{esm2015/lib/audio/ui/common.js → esm2020/lib/audio/ui/common.mjs} +0 -0
- package/esm2020/lib/audio/ui/container.mjs +431 -0
- package/{esm2015/lib/audio/ui/livelevel.js → esm2020/lib/audio/ui/livelevel.mjs} +5 -5
- package/{esm2015/lib/audio/ui/scroll_pane_horizontal.js → esm2020/lib/audio/ui/scroll_pane_horizontal.mjs} +4 -4
- package/{esm2015/lib/audio/ui/sonagram.js → esm2020/lib/audio/ui/sonagram.mjs} +5 -5
- package/{esm2015/lib/dsp/utils.js → esm2020/lib/dsp/utils.mjs} +0 -0
- package/{esm2015/lib/io/BinaryWriter.js → esm2020/lib/io/BinaryWriter.mjs} +0 -0
- package/{esm2015/lib/io/stream.js → esm2020/lib/io/stream.mjs} +0 -0
- package/{esm2015/lib/math/2d/geometry.js → esm2020/lib/math/2d/geometry.mjs} +0 -0
- package/{esm2015/lib/math/complex.js → esm2020/lib/math/complex.mjs} +0 -0
- package/{esm2015/lib/math/dft.js → esm2020/lib/math/dft.mjs} +0 -0
- package/{esm2015/lib/math/utils.js → esm2020/lib/math/utils.mjs} +0 -0
- package/esm2020/lib/media/utils.mjs +14 -0
- package/esm2020/lib/net/uploader.mjs +246 -0
- package/{esm2015/lib/speechrecorder/project/project.js → esm2020/lib/speechrecorder/project/project.mjs} +0 -0
- package/{esm2015/lib/speechrecorder/project/project.service.js → esm2020/lib/speechrecorder/project/project.service.mjs} +4 -4
- package/esm2020/lib/speechrecorder/recording.mjs +54 -0
- package/esm2020/lib/speechrecorder/recordings/recordings.service.mjs +246 -0
- package/{esm2015/lib/speechrecorder/script/script.js → esm2020/lib/speechrecorder/script/script.mjs} +2 -2
- package/{esm2015/lib/speechrecorder/script/script.service.js → esm2020/lib/speechrecorder/script/script.service.mjs} +4 -4
- package/esm2020/lib/speechrecorder/session/audiorecorder.mjs +1144 -0
- package/esm2020/lib/speechrecorder/session/controlpanel.mjs +449 -0
- package/{esm2015/lib/speechrecorder/session/item.js → esm2020/lib/speechrecorder/session/item.mjs} +1 -1
- package/{esm2015/lib/speechrecorder/session/progress.js → esm2020/lib/speechrecorder/session/progress.mjs} +5 -5
- package/{esm2015/lib/speechrecorder/session/prompting.js → esm2020/lib/speechrecorder/session/prompting.mjs} +21 -21
- package/esm2020/lib/speechrecorder/session/recorder_combi_pane.mjs +75 -0
- package/esm2020/lib/speechrecorder/session/recording_list.mjs +109 -0
- package/esm2020/lib/speechrecorder/session/recordingfile/recording-file-meta.component.mjs +126 -0
- package/{esm2015/lib/speechrecorder/session/recordingfile/recording-file-navi.component.js → esm2020/lib/speechrecorder/session/recordingfile/recording-file-navi.component.mjs} +5 -5
- package/esm2020/lib/speechrecorder/session/recordingfile/recording-file-u-i.component.mjs +168 -0
- package/esm2020/lib/speechrecorder/session/recordingfile/recording-file-view.component.mjs +415 -0
- package/{esm2015/lib/speechrecorder/session/recordingfile/recording-file.js → esm2020/lib/speechrecorder/session/recordingfile/recording-file.mjs} +1 -1
- package/esm2020/lib/speechrecorder/session/recordingfile/recordingfile-service.mjs +251 -0
- package/{esm2015/lib/speechrecorder/session/session.js → esm2020/lib/speechrecorder/session/session.mjs} +0 -0
- package/{esm2015/lib/speechrecorder/session/session.service.js → esm2020/lib/speechrecorder/session/session.service.mjs} +4 -4
- package/{esm2015/lib/speechrecorder/session/session_finished_dialog.js → esm2020/lib/speechrecorder/session/session_finished_dialog.mjs} +4 -4
- package/esm2020/lib/speechrecorder/session/sessionmanager.mjs +1274 -0
- package/{esm2015/lib/speechrecorder/session/warning_bar.js → esm2020/lib/speechrecorder/session/warning_bar.mjs} +5 -5
- package/{esm2015/lib/speechrecorder/spruploader.js → esm2020/lib/speechrecorder/spruploader.mjs} +4 -4
- package/{esm2015/lib/speechrecorder/startstopsignal/startstopsignal.js → esm2020/lib/speechrecorder/startstopsignal/startstopsignal.mjs} +0 -0
- package/{esm2015/lib/speechrecorder/startstopsignal/ui/simpletrafficlight.js → esm2020/lib/speechrecorder/startstopsignal/ui/simpletrafficlight.mjs} +5 -5
- package/esm2020/lib/speechrecorderng.component.mjs +427 -0
- package/{esm2015/lib/speechrecorderng.module.js → esm2020/lib/speechrecorderng.module.mjs} +12 -11
- package/{esm2015/lib/spr.config.js → esm2020/lib/spr.config.mjs} +4 -4
- package/{esm2015/lib/spr.module.version.js → esm2020/lib/spr.module.version.mjs} +2 -2
- package/{esm2015/lib/ui/canvas_layer_comp.js → esm2020/lib/ui/canvas_layer_comp.mjs} +4 -4
- package/{esm2015/lib/ui/message_dialog.js → esm2020/lib/ui/message_dialog.mjs} +4 -4
- package/{esm2015/lib/ui/recordingitem_display.js → esm2020/lib/ui/recordingitem_display.mjs} +9 -9
- package/{esm2015/lib/utils/css_utils.js → esm2020/lib/utils/css_utils.mjs} +0 -0
- package/{esm2015/lib/utils/scrollIntoViewToBottom.js → esm2020/lib/utils/scrollIntoViewToBottom.mjs} +4 -4
- package/{esm2015/lib/utils/ua-parser.js → esm2020/lib/utils/ua-parser.mjs} +0 -0
- package/{esm2015/lib/utils/utils.js → esm2020/lib/utils/utils.mjs} +0 -0
- package/esm2020/public-api.mjs +31 -0
- package/{esm2015/speechrecorderng.js → esm2020/speechrecorderng.mjs} +0 -0
- package/fesm2015/speechrecorderng.mjs +11991 -0
- package/fesm2015/speechrecorderng.mjs.map +1 -0
- package/{fesm2015/speechrecorderng.js → fesm2020/speechrecorderng.mjs} +1863 -285
- package/fesm2020/speechrecorderng.mjs.map +1 -0
- package/lib/media/utils.d.ts +3 -0
- package/lib/net/uploader.d.ts +4 -2
- package/lib/speechrecorder/recording.d.ts +14 -3
- package/lib/speechrecorder/recordings/recordings.service.d.ts +12 -5
- package/lib/speechrecorder/session/audiorecorder.d.ts +150 -0
- package/lib/speechrecorder/session/controlpanel.d.ts +2 -1
- package/lib/speechrecorder/session/item.d.ts +2 -2
- package/lib/speechrecorder/session/recorder_combi_pane.d.ts +26 -0
- package/lib/speechrecorder/session/recording_list.d.ts +19 -0
- package/lib/speechrecorder/session/recordingfile/recording-file-meta.component.d.ts +6 -2
- package/lib/speechrecorder/session/recordingfile/recording-file-view.component.d.ts +5 -4
- package/lib/speechrecorder/session/recordingfile/recording-file.d.ts +2 -2
- package/lib/speechrecorder/session/recordingfile/recordingfile-service.d.ts +5 -3
- package/lib/speechrecorder/session/sessionmanager.d.ts +5 -5
- package/lib/speechrecorderng.module.d.ts +31 -28
- package/lib/spr.module.version.d.ts +1 -1
- package/package.json +33 -20
- package/public-api.d.ts +2 -1
- package/bundles/speechrecorderng.umd.js +0 -10146
- package/bundles/speechrecorderng.umd.js.map +0 -1
- package/esm2015/lib/audio/audio_player.js +0 -274
- package/esm2015/lib/audio/capture/capture.js +0 -544
- package/esm2015/lib/audio/dsp/level_measure.js +0 -356
- package/esm2015/lib/audio/ui/audio_canvas_layer_comp.js +0 -364
- package/esm2015/lib/audio/ui/container.js +0 -412
- package/esm2015/lib/net/uploader.js +0 -220
- package/esm2015/lib/speechrecorder/recording.js +0 -38
- package/esm2015/lib/speechrecorder/recordings/recordings.service.js +0 -173
- package/esm2015/lib/speechrecorder/session/controlpanel.js +0 -446
- package/esm2015/lib/speechrecorder/session/recordingfile/recording-file-meta.component.js +0 -83
- package/esm2015/lib/speechrecorder/session/recordingfile/recording-file-u-i.component.js +0 -163
- package/esm2015/lib/speechrecorder/session/recordingfile/recording-file-view.component.js +0 -386
- package/esm2015/lib/speechrecorder/session/recordingfile/recordingfile-service.js +0 -191
- package/esm2015/lib/speechrecorder/session/sessionmanager.js +0 -1271
- package/esm2015/lib/speechrecorderng.component.js +0 -423
- package/esm2015/public-api.js +0 -30
- package/fesm2015/speechrecorderng.js.map +0 -1
|
@@ -0,0 +1,351 @@
|
|
|
1
|
+
import { DSPUtils } from "../../dsp/utils";
|
|
2
|
+
import { Arrays, WorkerHelper } from "../../utils/utils";
|
|
3
|
+
export const MIN_DB_LEVEL = -40.0;
|
|
4
|
+
export class LevelInfo {
|
|
5
|
+
constructor(channelCount, startFrame = 0, frameLength = 0, minLinLevels, maxLinLevels) {
|
|
6
|
+
this.channelCount = channelCount;
|
|
7
|
+
this.startFrame = startFrame;
|
|
8
|
+
this.frameLength = frameLength;
|
|
9
|
+
this._minLinLevels = this.checkOrInitArray(minLinLevels);
|
|
10
|
+
this._maxLinLevels = this.checkOrInitArray(maxLinLevels);
|
|
11
|
+
}
|
|
12
|
+
get minLinLevels() {
|
|
13
|
+
return this._minLinLevels;
|
|
14
|
+
}
|
|
15
|
+
get maxLinLevels() {
|
|
16
|
+
return this._maxLinLevels;
|
|
17
|
+
}
|
|
18
|
+
checkOrInitArray(arr) {
|
|
19
|
+
if (arr) {
|
|
20
|
+
if (arr.length !== this.channelCount)
|
|
21
|
+
throw new Error("Level arrays must be equal to channel count " + this.channelCount);
|
|
22
|
+
return arr;
|
|
23
|
+
}
|
|
24
|
+
else {
|
|
25
|
+
return new Array(this.channelCount);
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
merge(levelInfo) {
|
|
29
|
+
if (levelInfo === null) {
|
|
30
|
+
return;
|
|
31
|
+
}
|
|
32
|
+
if (this.channelCount !== levelInfo.channelCount) {
|
|
33
|
+
throw new Error("Channel count of level info to merge must be equal. (" + this.channelCount + " != " + levelInfo.channelCount + ")");
|
|
34
|
+
}
|
|
35
|
+
let endFrame = this.startFrame + this.frameLength;
|
|
36
|
+
let mergeEndFrame = levelInfo.startFrame + levelInfo.frameLength;
|
|
37
|
+
if (levelInfo.startFrame < this.startFrame) {
|
|
38
|
+
this.startFrame = levelInfo.startFrame;
|
|
39
|
+
}
|
|
40
|
+
if (mergeEndFrame > endFrame) {
|
|
41
|
+
this.frameLength = mergeEndFrame - this.startFrame;
|
|
42
|
+
}
|
|
43
|
+
for (let ch = 0; ch < this.channelCount; ch++) {
|
|
44
|
+
if (levelInfo.minLinLevels[ch] < this.minLinLevels[ch]) {
|
|
45
|
+
this.minLinLevels[ch] = levelInfo.minLinLevels[ch];
|
|
46
|
+
}
|
|
47
|
+
if (levelInfo.maxLinLevels[ch] > this.maxLinLevels[ch]) {
|
|
48
|
+
this.maxLinLevels[ch] = levelInfo.maxLinLevels[ch];
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
levelsLin() {
|
|
53
|
+
let lvlsLin = new Array(this.channelCount);
|
|
54
|
+
for (let ch = 0; ch < this.channelCount; ch++) {
|
|
55
|
+
lvlsLin[ch] = Math.max(Math.abs(this.minLinLevels[ch]), Math.abs(this.maxLinLevels[ch]));
|
|
56
|
+
}
|
|
57
|
+
return lvlsLin;
|
|
58
|
+
}
|
|
59
|
+
powerLevelsDB() {
|
|
60
|
+
let lvlsDb = new Array(this.channelCount);
|
|
61
|
+
for (let ch = 0; ch < this.channelCount; ch++) {
|
|
62
|
+
lvlsDb[ch] = DSPUtils.toPowerLevelInDB(this.levelsLin()[ch]);
|
|
63
|
+
}
|
|
64
|
+
return lvlsDb;
|
|
65
|
+
}
|
|
66
|
+
powerLevelDB() {
|
|
67
|
+
let pLvlsDb = this.powerLevelsDB();
|
|
68
|
+
return Math.max(...pLvlsDb);
|
|
69
|
+
}
|
|
70
|
+
clone() {
|
|
71
|
+
return new LevelInfo(this.channelCount, this.startFrame, this.frameLength, Arrays.cloneNumberArray(this.minLinLevels), Arrays.cloneNumberArray(this.maxLinLevels));
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
export class LevelInfos {
|
|
75
|
+
constructor(bufferLevelInfos, peakLevelInfo) {
|
|
76
|
+
this.bufferLevelInfos = bufferLevelInfos;
|
|
77
|
+
this.peakLevelInfo = peakLevelInfo;
|
|
78
|
+
}
|
|
79
|
+
framesPerBuffer() {
|
|
80
|
+
if (this.bufferLevelInfos.length > 0) {
|
|
81
|
+
return this.bufferLevelInfos[0].frameLength;
|
|
82
|
+
}
|
|
83
|
+
return this.peakLevelInfo.frameLength / this.bufferLevelInfos.length;
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
export class PeakLevelInterceptor {
|
|
87
|
+
constructor(levelListener) {
|
|
88
|
+
this.levelListener = levelListener;
|
|
89
|
+
this._channelCount = 0;
|
|
90
|
+
this._peakDbLvl = MIN_DB_LEVEL;
|
|
91
|
+
}
|
|
92
|
+
get peakDbLvl() {
|
|
93
|
+
return this._peakDbLvl;
|
|
94
|
+
}
|
|
95
|
+
get channelCount() {
|
|
96
|
+
return this._channelCount;
|
|
97
|
+
}
|
|
98
|
+
set channelCount(value) {
|
|
99
|
+
this._channelCount = value;
|
|
100
|
+
if (this.levelListener) {
|
|
101
|
+
this.levelListener.channelCount = value;
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
update(levelInfo, peakLevelInfo) {
|
|
105
|
+
let peakDBVal = levelInfo.powerLevelDB();
|
|
106
|
+
if (this.peakDbLvl < peakDBVal) {
|
|
107
|
+
this._peakDbLvl = peakDBVal;
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
streamFinished() {
|
|
111
|
+
if (this.levelListener) {
|
|
112
|
+
this.levelListener.streamFinished();
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
reset() {
|
|
116
|
+
this._peakDbLvl = MIN_DB_LEVEL;
|
|
117
|
+
if (this.levelListener) {
|
|
118
|
+
this.levelListener.reset();
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
export class LevelMeasure {
|
|
123
|
+
constructor() {
|
|
124
|
+
this.worker = null;
|
|
125
|
+
this.workerURL = WorkerHelper.buildWorkerBlobURL(this.workerFunction);
|
|
126
|
+
}
|
|
127
|
+
calcBufferLevelInfos(audioBuffer, bufferTimeLength) {
|
|
128
|
+
return new Promise((resolve) => {
|
|
129
|
+
let chs = audioBuffer.numberOfChannels;
|
|
130
|
+
let bufferFrameLength = Math.round(audioBuffer.sampleRate * bufferTimeLength);
|
|
131
|
+
let buffers = new Array(chs);
|
|
132
|
+
for (let ch = 0; ch < chs; ch++) {
|
|
133
|
+
let adCh = audioBuffer.getChannelData(ch);
|
|
134
|
+
let adChCopy = new Float32Array(adCh.length);
|
|
135
|
+
adChCopy.set(adCh);
|
|
136
|
+
buffers[ch] = adChCopy.buffer;
|
|
137
|
+
}
|
|
138
|
+
this.worker = new Worker(this.workerURL);
|
|
139
|
+
this.worker.onmessage = (me) => {
|
|
140
|
+
let linLevelArrs = new Array(chs);
|
|
141
|
+
for (let ch = 0; ch < chs; ch++) {
|
|
142
|
+
linLevelArrs[ch] = new Float32Array(me.data.linLevelBuffers[ch]);
|
|
143
|
+
}
|
|
144
|
+
let bufferCount = Math.ceil(me.data.frameLength / me.data.bufferFrameLength);
|
|
145
|
+
let framePos = 0;
|
|
146
|
+
let bufferLevelInfos = new Array();
|
|
147
|
+
let peakLevelInfo = new LevelInfo(chs);
|
|
148
|
+
for (let bi = 0; bi < bufferCount; bi++) {
|
|
149
|
+
let minLevels = new Array(chs);
|
|
150
|
+
let maxLevels = new Array(chs);
|
|
151
|
+
for (let ch = 0; ch < chs; ch++) {
|
|
152
|
+
let linLvlArrPos = bi * 2;
|
|
153
|
+
minLevels[ch] = linLevelArrs[ch][linLvlArrPos];
|
|
154
|
+
maxLevels[ch] = linLevelArrs[ch][linLvlArrPos + 1];
|
|
155
|
+
}
|
|
156
|
+
let bli = new LevelInfo(chs, framePos, me.data.bufferFrameLength, minLevels, maxLevels);
|
|
157
|
+
bufferLevelInfos.push(bli);
|
|
158
|
+
peakLevelInfo.merge(bli);
|
|
159
|
+
}
|
|
160
|
+
this.terminateWorker();
|
|
161
|
+
resolve(new LevelInfos(bufferLevelInfos, peakLevelInfo));
|
|
162
|
+
};
|
|
163
|
+
this.worker.postMessage({ bufferFrameLength: bufferFrameLength, audioData: buffers, chs: chs }, buffers);
|
|
164
|
+
});
|
|
165
|
+
}
|
|
166
|
+
terminateWorker() {
|
|
167
|
+
this.worker?.terminate();
|
|
168
|
+
}
|
|
169
|
+
/*
|
|
170
|
+
* Method used as worker code.
|
|
171
|
+
*/
|
|
172
|
+
workerFunction() {
|
|
173
|
+
self.onmessage = function (msg) {
|
|
174
|
+
let chs = msg.data.chs;
|
|
175
|
+
let bufferFrameLength = msg.data.bufferFrameLength;
|
|
176
|
+
let audioData = new Array(chs);
|
|
177
|
+
let linLevels = new Array(chs);
|
|
178
|
+
for (let ch = 0; ch < chs; ch++) {
|
|
179
|
+
audioData[ch] = new Float32Array(msg.data.audioData[ch]);
|
|
180
|
+
}
|
|
181
|
+
let frameLength = audioData[0].length;
|
|
182
|
+
let bufferCount = Math.ceil(frameLength / bufferFrameLength);
|
|
183
|
+
for (let ch = 0; ch < chs; ch++) {
|
|
184
|
+
linLevels[ch] = new Float32Array(bufferCount * 2);
|
|
185
|
+
}
|
|
186
|
+
if (audioData && chs > 0) {
|
|
187
|
+
for (let ch = 0; ch < chs; ch++) {
|
|
188
|
+
let chData = audioData[ch];
|
|
189
|
+
for (let s = 0; s < frameLength; s++) {
|
|
190
|
+
let bi = Math.floor(s / bufferFrameLength);
|
|
191
|
+
let lvlArrPos = bi * 2;
|
|
192
|
+
//let bs = s % bufferFrameLength;
|
|
193
|
+
let chSample = chData[s];
|
|
194
|
+
if (chSample < linLevels[ch][lvlArrPos]) {
|
|
195
|
+
linLevels[ch][lvlArrPos] = chSample;
|
|
196
|
+
}
|
|
197
|
+
lvlArrPos++;
|
|
198
|
+
if (chSample > linLevels[ch][lvlArrPos]) {
|
|
199
|
+
linLevels[ch][lvlArrPos] = chSample;
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
const linLevelBufs = new Array(chs);
|
|
204
|
+
for (let ch = 0; ch < chs; ch++) {
|
|
205
|
+
linLevelBufs[ch] = linLevels[ch].buffer;
|
|
206
|
+
}
|
|
207
|
+
postMessage({ bufferFrameLength: bufferFrameLength, frameLength: frameLength, linLevelBuffers: linLevelBufs }, linLevelBufs);
|
|
208
|
+
}
|
|
209
|
+
};
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
export class StreamLevelMeasure {
|
|
213
|
+
constructor() {
|
|
214
|
+
this.currentLevelInfos = null;
|
|
215
|
+
this.peakLevelInfo = null;
|
|
216
|
+
this.worker = null;
|
|
217
|
+
this.channelCount = 0;
|
|
218
|
+
this.bufferIndex = 0;
|
|
219
|
+
this.frameCount = 0;
|
|
220
|
+
this.levelListener = null;
|
|
221
|
+
this.peakLevelListener = null;
|
|
222
|
+
this.peakLevelInDb = MIN_DB_LEVEL;
|
|
223
|
+
this.workerURL = WorkerHelper.buildWorkerBlobURL(this.workerFunction);
|
|
224
|
+
}
|
|
225
|
+
setFormat(channels, sampleRate) {
|
|
226
|
+
this.channelCount = channels;
|
|
227
|
+
this.currentLevelInfos = new LevelInfo(this.channelCount);
|
|
228
|
+
this.peakLevelInfo = new LevelInfo(this.channelCount);
|
|
229
|
+
this.worker = new Worker(this.workerURL);
|
|
230
|
+
this.worker.onmessage = (me) => {
|
|
231
|
+
let streamFinished = me.data.streamFinished;
|
|
232
|
+
if (streamFinished) {
|
|
233
|
+
if (this.levelListener) {
|
|
234
|
+
this.levelListener.streamFinished();
|
|
235
|
+
}
|
|
236
|
+
}
|
|
237
|
+
else {
|
|
238
|
+
let minLevels = new Array(this.channelCount);
|
|
239
|
+
let maxLevels = new Array(this.channelCount);
|
|
240
|
+
for (let ch = 0; ch < this.channelCount; ch++) {
|
|
241
|
+
let fls = new Float32Array(me.data.linLevelBuffers[ch]);
|
|
242
|
+
minLevels[ch] = fls[0];
|
|
243
|
+
maxLevels[ch] = fls[1];
|
|
244
|
+
}
|
|
245
|
+
let bi = new LevelInfo(this.channelCount, this.frameCount, me.data.fraemLength, minLevels, maxLevels);
|
|
246
|
+
this.updateLevels(bi);
|
|
247
|
+
}
|
|
248
|
+
};
|
|
249
|
+
}
|
|
250
|
+
nextStream() {
|
|
251
|
+
this.reset();
|
|
252
|
+
}
|
|
253
|
+
reset() {
|
|
254
|
+
this.currentLevelInfos = new LevelInfo(this.channelCount);
|
|
255
|
+
this.peakLevelInfo = new LevelInfo(this.channelCount);
|
|
256
|
+
if (this.levelListener) {
|
|
257
|
+
this.levelListener.reset();
|
|
258
|
+
this.levelListener.channelCount = this.channelCount;
|
|
259
|
+
}
|
|
260
|
+
if (this.peakLevelListener) {
|
|
261
|
+
this.peakLevelInDb = MIN_DB_LEVEL;
|
|
262
|
+
this.peakLevelListener(this.peakLevelInDb);
|
|
263
|
+
}
|
|
264
|
+
}
|
|
265
|
+
write(bufferData) {
|
|
266
|
+
let bufArrCopies = new Array(bufferData.length);
|
|
267
|
+
let buffers = new Array(bufferData.length);
|
|
268
|
+
for (let ch = 0; ch < bufferData.length; ch++) {
|
|
269
|
+
bufArrCopies[ch] = bufferData[ch].slice();
|
|
270
|
+
buffers[ch] = bufArrCopies[ch].buffer;
|
|
271
|
+
}
|
|
272
|
+
this.worker?.postMessage({
|
|
273
|
+
streamFinished: false,
|
|
274
|
+
audioData: buffers,
|
|
275
|
+
chs: this.channelCount,
|
|
276
|
+
bufferIndex: this.bufferIndex
|
|
277
|
+
}, buffers);
|
|
278
|
+
this.bufferIndex++;
|
|
279
|
+
return bufArrCopies[0].length;
|
|
280
|
+
}
|
|
281
|
+
flush() {
|
|
282
|
+
this.worker?.postMessage({ streamFinished: true });
|
|
283
|
+
}
|
|
284
|
+
close() {
|
|
285
|
+
this.worker?.terminate();
|
|
286
|
+
}
|
|
287
|
+
/*
|
|
288
|
+
* Method used as worker code.
|
|
289
|
+
*/
|
|
290
|
+
workerFunction() {
|
|
291
|
+
self.onmessage = function (msg) {
|
|
292
|
+
let streamFinished = msg.data.streamFinished;
|
|
293
|
+
if (streamFinished) {
|
|
294
|
+
postMessage({ streamFinished: true });
|
|
295
|
+
}
|
|
296
|
+
else {
|
|
297
|
+
let chs = msg.data.chs;
|
|
298
|
+
let frameLength = null;
|
|
299
|
+
let audioData = new Array(chs);
|
|
300
|
+
let linLevels = new Array(chs);
|
|
301
|
+
for (let ch = 0; ch < chs; ch++) {
|
|
302
|
+
linLevels[ch] = new Float32Array(2);
|
|
303
|
+
audioData[ch] = new Float32Array(msg.data.audioData[ch]);
|
|
304
|
+
}
|
|
305
|
+
if (audioData) {
|
|
306
|
+
for (let ch = 0; ch < chs; ch++) {
|
|
307
|
+
let chData = audioData[ch];
|
|
308
|
+
if (frameLength === null) {
|
|
309
|
+
frameLength = chData.length;
|
|
310
|
+
}
|
|
311
|
+
for (let s = 0; s < frameLength; s++) {
|
|
312
|
+
let chSample = chData[s];
|
|
313
|
+
if (chSample < linLevels[ch][0]) {
|
|
314
|
+
linLevels[ch][0] = chSample;
|
|
315
|
+
}
|
|
316
|
+
if (chSample > linLevels[ch][1]) {
|
|
317
|
+
linLevels[ch][1] = chSample;
|
|
318
|
+
}
|
|
319
|
+
}
|
|
320
|
+
}
|
|
321
|
+
}
|
|
322
|
+
let linLevelBufs = new Array(chs);
|
|
323
|
+
for (let ch = 0; ch < chs; ch++) {
|
|
324
|
+
linLevelBufs[ch] = linLevels[ch].buffer;
|
|
325
|
+
}
|
|
326
|
+
postMessage({ streamFinished: false, frameLength: frameLength, linLevelBuffers: linLevelBufs }, linLevelBufs);
|
|
327
|
+
}
|
|
328
|
+
};
|
|
329
|
+
}
|
|
330
|
+
updateLevels(bufferLevelInfo) {
|
|
331
|
+
this.currentLevelInfos = bufferLevelInfo;
|
|
332
|
+
if (this.peakLevelInfo) {
|
|
333
|
+
this.peakLevelInfo.merge(bufferLevelInfo);
|
|
334
|
+
if (this.levelListener) {
|
|
335
|
+
this.levelListener.update(this.currentLevelInfos, this.peakLevelInfo.clone());
|
|
336
|
+
}
|
|
337
|
+
if (this.peakLevelListener) {
|
|
338
|
+
let peakDBVal = bufferLevelInfo.powerLevelDB();
|
|
339
|
+
if (this.peakLevelInDb < peakDBVal) {
|
|
340
|
+
this.peakLevelInDb = peakDBVal;
|
|
341
|
+
// the event comes from outside of an Angular zone
|
|
342
|
+
this.peakLevelListener(this.peakLevelInDb);
|
|
343
|
+
}
|
|
344
|
+
}
|
|
345
|
+
}
|
|
346
|
+
}
|
|
347
|
+
stop() {
|
|
348
|
+
this.worker?.terminate();
|
|
349
|
+
}
|
|
350
|
+
}
|
|
351
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibGV2ZWxfbWVhc3VyZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uLy4uL3Byb2plY3RzL3NwZWVjaHJlY29yZGVybmcvc3JjL2xpYi9hdWRpby9kc3AvbGV2ZWxfbWVhc3VyZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUMsUUFBUSxFQUFDLE1BQU0saUJBQWlCLENBQUM7QUFFekMsT0FBTyxFQUFDLE1BQU0sRUFBRSxZQUFZLEVBQUMsTUFBTSxtQkFBbUIsQ0FBQztBQUV2RCxNQUFNLENBQUMsTUFBTSxZQUFZLEdBQUcsQ0FBQyxJQUFJLENBQUM7QUFJbEMsTUFBTSxPQUFPLFNBQVM7SUFLcEIsWUFBNEIsWUFBb0IsRUFDN0IsYUFBcUIsQ0FBQyxFQUN0QixjQUFzQixDQUFDLEVBQzlCLFlBQTRCLEVBQzVCLFlBQTRCO1FBSlosaUJBQVksR0FBWixZQUFZLENBQVE7UUFDN0IsZUFBVSxHQUFWLFVBQVUsQ0FBWTtRQUN0QixnQkFBVyxHQUFYLFdBQVcsQ0FBWTtRQUd4QyxJQUFJLENBQUMsYUFBYSxHQUFHLElBQUksQ0FBQyxnQkFBZ0IsQ0FBQyxZQUFZLENBQUMsQ0FBQztRQUN6RCxJQUFJLENBQUMsYUFBYSxHQUFHLElBQUksQ0FBQyxnQkFBZ0IsQ0FBQyxZQUFZLENBQUMsQ0FBQztJQUMzRCxDQUFDO0lBRUQsSUFBSSxZQUFZO1FBQ2QsT0FBTyxJQUFJLENBQUMsYUFBYSxDQUFDO0lBQzVCLENBQUM7SUFFRCxJQUFJLFlBQVk7UUFDZCxPQUFPLElBQUksQ0FBQyxhQUFhLENBQUM7SUFDNUIsQ0FBQztJQUVPLGdCQUFnQixDQUFDLEdBQThCO1FBQ3JELElBQUksR0FBRyxFQUFFO1lBQ1AsSUFBSSxHQUFHLENBQUMsTUFBTSxLQUFLLElBQUksQ0FBQyxZQUFZO2dCQUNsQyxNQUFPLElBQUksS0FBSyxDQUFDLDhDQUE4QyxHQUFHLElBQUksQ0FBQyxZQUFZLENBQUMsQ0FBQztZQUN2RixPQUFP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LGlCQUFpQixFQUFDO2dCQUN4QixJQUFJLFNBQVMsR0FBRyxlQUFlLENBQUMsWUFBWSxFQUFFLENBQUM7Z0JBQy9DLElBQUksSUFBSSxDQUFDLGFBQWEsR0FBRyxTQUFTLEVBQUU7b0JBQ2xDLElBQUksQ0FBQyxhQUFhLEdBQUcsU0FBUyxDQUFDO29CQUMvQixrREFBa0Q7b0JBQ2xELElBQUksQ0FBQyxpQkFBaUIsQ0FBQyxJQUFJLENBQUMsYUFBYSxDQUFDLENBQUM7aUJBQzVDO2FBQ0Y7U0FDRjtJQUNILENBQUM7SUFHRCxJQUFJO1FBQ0YsSUFBSSxDQUFDLE1BQU0sRUFBRSxTQUFTLEVBQUUsQ0FBQztJQUMzQixDQUFDO0NBR0YiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQge0RTUFV0aWxzfSBmcm9tIFwiLi4vLi4vZHNwL3V0aWxzXCI7XHJcbmltcG9ydCB7U2VxdWVuY2VBdWRpb0Zsb2F0MzJPdXRTdHJlYW19IGZyb20gXCIuLi9pby9zdHJlYW1cIjtcclxuaW1wb3J0IHtBcnJheXMsIFdvcmtlckhlbHBlcn0gZnJvbSBcIi4uLy4uL3V0aWxzL3V0aWxzXCI7XHJcblxyXG5leHBvcnQgY29uc3QgTUlOX0RCX0xFVkVMID0gLTQwLjA7XHJcblxyXG5cclxuXHJcbmV4cG9ydCBjbGFzcyBMZXZlbEluZm8ge1xyXG5cclxuICBwcml2YXRlIHJlYWRvbmx5IF9taW5MaW5MZXZlbHM6IEFycmF5PG51bWJlcj47XHJcbiAgcHJpdmF0ZSByZWFkb25seSBfbWF4TGluTGV2ZWxzOiBBcnJheTxudW1iZXI+O1xyXG5cclxuICBjb25zdHJ1Y3RvcihwdWJsaWMgcmVhZG9ubHkgY2hhbm5lbENvdW50OiBudW1iZXIsXHJcbiAgICAgICAgICAgICAgcHVibGljIHN0YXJ0RnJhbWU6IG51bWJlciA9IDAsXHJcbiAgICAgICAgICAgICAgcHVibGljIGZyYW1lTGVuZ3RoOiBudW1iZXIgPSAwLFxyXG4gICAgICAgICAgICAgIG1pbkxpbkxldmVscz86IEFycmF5PG51bWJlcj4sXHJcbiAgICAgICAgICAgICAgbWF4TGluTGV2ZWxzPzogQXJyYXk8bnVtYmVyPikge1xyXG4gICAgdGhpcy5fbWluTGluTGV2ZWxzID0gdGhpcy5jaGVja09ySW5pdEFycmF5KG1pbkxpbkxldmVscyk7XHJcbiAgICB0aGlzLl9tYXhMaW5MZXZlbHMgPSB0aGlzLmNoZWNrT3JJbml0QXJyYXkobWF4TGluTGV2ZWxzKTtcclxuICB9XHJcblxyXG4gIGdldCBtaW5MaW5MZXZlbHMoKSB7XHJcbiAgICByZXR1cm4gdGhpcy5fbWluTGluTGV2ZWxzO1xyXG4gIH1cclxuXHJcbiAgZ2V0IG1heExpbkxldmVscygpIHtcclxuICAgIHJldHVybiB0aGlzLl9tYXhMaW5MZXZlbHM7XHJcbiAgfVxyXG5cclxuICBwcml2YXRlIGNoZWNrT3JJbml0QXJyYXkoYXJyOiBBcnJheTxudW1iZXI+IHwgdW5kZWZpbmVkKTogQXJyYXk8bnVtYmVyPiB7XHJcbiAgICBpZiAoYXJyKSB7XHJcbiAgICAgIGlmIChhcnIubGVuZ3RoICE9PSB0aGlzLmNoYW5uZWxDb3VudClcclxuICAgICAgICB0aHJvdyAgbmV3IEVycm9yKFwiTGV2ZWwgYXJyYXlzIG11c3QgYmUgZXF1YWwgdG8gY2hhbm5lbCBjb3VudCBcIiArIHRoaXMuY2hhbm5lbENvdW50KTtcclxuICAgICAgcmV0dXJuIGFycjtcclxuICAgIH0gZWxzZSB7XHJcbiAgICAgIHJldHVybiBuZXcgQXJyYXk8bnVtYmVyPih0aGlzLmNoYW5uZWxDb3VudClcclxuICAgIH1cclxuICB9XHJcblxyXG4gIG1lcmdlKGxldmVsSW5mbzogTGV2ZWxJbmZvKSB7XHJcbiAgICBpZiAobGV2ZWxJbmZvID09PSBudWxsKSB7XHJcbiAgICAgIHJldHVybjtcclxuICAgIH1cclxuICAgIGlmICh0aGlzLmNoYW5uZWxDb3VudCAhPT0gbGV2ZWxJbmZvLmNoYW5uZWxDb3VudCkge1xyXG4gICAgICB0aHJvdyBuZXcgRXJyb3IoXCJDaGFubmVsIGNvdW50IG9mIGxldmVsIGluZm8gdG8gbWVyZ2UgbXVzdCBiZSBlcXVhbC4gKFwiICsgdGhpcy5jaGFubmVsQ291bnQgKyBcIiAhPSBcIiArIGxldmVsSW5mby5jaGFubmVsQ291bnQgKyBcIilcIik7XHJcbiAgICB9XHJcblxyXG4gICAgbGV0IGVuZEZyYW1lID0gdGhpcy5zdGFydEZyYW1lICsgdGhpcy5mcmFtZUxlbmd0aDtcclxuICAgIGxldCBtZXJnZUVuZEZyYW1lID0gbGV2ZWxJbmZvLnN0YXJ0RnJhbWUgKyBsZXZlbEluZm8uZnJhbWVMZW5ndGg7XHJcblxyXG4gICAgaWYgKGxldmVsSW5mby5zdGFydEZyYW1lIDwgdGhpcy5zdGFydEZyYW1lKSB7XHJcbiAgICAgIHRoaXMuc3RhcnRGcmFtZSA9IGxldmVsSW5mby5zdGFydEZyYW1lO1xyXG4gICAgfVxyXG5cclxuICAgIGlmIChtZXJnZUVuZEZyYW1lID4gZW5kRnJhbWUpIHtcclxuICAgICAgdGhpcy5mcmFtZUxlbmd0aCA9IG1lcmdlRW5kRnJhbWUgLSB0aGlzLnN0YXJ0RnJhbWU7XHJcbiAgICB9XHJcblxyXG4gICAgZm9yIChsZXQgY2ggPSAwOyBjaCA8IHRoaXMuY2hhbm5lbENvdW50OyBjaCsrKSB7XHJcblxyXG4gICAgICBpZiAobGV2ZWxJbmZvLm1pbkxpbkxldmVsc1tjaF0gPCB0aGlzLm1pbkxpbkxldmVsc1tjaF0pIHtcclxuICAgICAgICB0aGlzLm1pbkxpbkxldmVsc1tjaF0gPSBsZXZlbEluZm8ubWluTGluTGV2ZWxzW2NoXTtcclxuICAgICAgfVxyXG4gICAgICBpZiAobGV2ZWxJbmZvLm1heExpbkxldmVsc1tjaF0gPiB0aGlzLm1heExpbkxldmVsc1tjaF0pIHtcclxuICAgICAgICB0aGlzLm1heExpbkxldmVsc1tjaF0gPSBsZXZlbEluZm8ubWF4TGluTGV2ZWxzW2NoXTtcclxuICAgICAgfVxyXG4gICAgfVxyXG4gIH1cclxuXHJcbiAgbGV2ZWxzTGluKCk6IEFycmF5PG51bWJlcj4ge1xyXG4gICAgbGV0IGx2bHNMaW4gPSBuZXcgQXJyYXk8bnVtYmVyPih0aGlzLmNoYW5uZWxDb3VudCk7XHJcbiAgICBmb3IgKGxldCBjaCA9IDA7IGNoIDwgdGhpcy5jaGFubmVsQ291bnQ7IGNoKyspIHtcclxuICAgICAgbHZsc0xpbltjaF0gPSBNYXRoLm1heChNYXRoLmFicyh0aGlzLm1pbkxpbkxldmVsc1tjaF0pLCBNYXRoLmFicyh0aGlzLm1heExpbkxldmVsc1tjaF0pKTtcclxuICAgIH1cclxuICAgIHJldHVybiBsdmxzTGluO1xyXG4gIH1cclxuXHJcbiAgcG93ZXJMZXZlbHNEQigpOiBBcnJheTxudW1iZXI+IHtcclxuICAgIGxldCBsdmxzRGIgPSBuZXcgQXJyYXk8bnVtYmVyPih0aGlzLmNoYW5uZWxDb3VudCk7XHJcbiAgICBmb3IgKGxldCBjaCA9IDA7IGNoIDwgdGhpcy5jaGFubmVsQ291bnQ7IGNoKyspIHtcclxuICAgICAgbHZsc0RiW2NoXSA9IERTUFV0aWxzLnRvUG93ZXJMZXZlbEluREIodGhpcy5sZXZlbHNMaW4oKVtjaF0pO1xyXG4gICAgfVxyXG4gICAgcmV0dXJuIGx2bHNEYjtcclxuICB9XHJcblxyXG4gIHBvd2VyTGV2ZWxEQigpOiBudW1iZXIge1xyXG4gICAgbGV0IHBMdmxzRGIgPSB0aGlzLnBvd2VyTGV2ZWxzREIoKTtcclxuICAgIHJldHVybiBNYXRoLm1heCguLi5wTHZsc0RiKTtcclxuICB9XHJcblxyXG4gIGNsb25lKCk6IExldmVsSW5mbyB7XHJcbiAgICByZXR1cm4gbmV3IExldmVsSW5mbyh0aGlzLmNoYW5uZWxDb3VudCwgdGhpcy5zdGFydEZyYW1lLCB0aGlzLmZyYW1lTGVuZ3RoLCBBcnJheXMuY2xvbmVOdW1iZXJBcnJheSh0aGlzLm1pbkxpbkxldmVscyksXHJcbiAgICAgIEFycmF5cy5jbG9uZU51bWJlckFycmF5KHRoaXMubWF4TGluTGV2ZWxzKSk7XHJcbiAgfVxyXG59XHJcblxyXG5leHBvcnQgY2xhc3MgTGV2ZWxJbmZvcyB7XHJcbiAgY29uc3RydWN0b3IocHVibGljIHJlYWRvbmx5IGJ1ZmZlckxldmVsSW5mb3M6IEFycmF5PExldmVsSW5mbz4sIHB1YmxpYyByZWFkb25seSBwZWFrTGV2ZWxJbmZvOiBMZXZlbEluZm8pIHtcclxuICB9XHJcblxyXG4gIGZyYW1lc1BlckJ1ZmZlcigpOm51bWJlcntcclxuICAgIGlmKHRoaXMuYnVmZmVyTGV2ZWxJbmZvcy5sZW5ndGg+MCl7XHJcbiAgICAgIHJldHVybiB0aGlzLmJ1ZmZlckxldmVsSW5mb3NbMF0uZnJhbWVMZW5ndGg7XHJcbiAgICB9XHJcbiAgICByZXR1cm4gdGhpcy5wZWFrTGV2ZWxJbmZvLmZyYW1lTGVuZ3RoL3RoaXMuYnVmZmVyTGV2ZWxJbmZvcy5sZW5ndGg7XHJcbiAgfVxyXG59XHJcblxyXG5cclxuZXhwb3J0IGludGVyZmFjZSBMZXZlbExpc3RlbmVyIHtcclxuICBjaGFubmVsQ291bnQ6IG51bWJlcjtcclxuXHJcbiAgdXBkYXRlKGxldmVsSW5mbzogTGV2ZWxJbmZvLCBwZWFrTGV2ZWxJbmZvOiBMZXZlbEluZm8pOiB2b2lkO1xyXG5cclxuICBzdHJlYW1GaW5pc2hlZCgpOiB2b2lkO1xyXG5cclxuICByZXNldCgpOiB2b2lkO1xyXG59XHJcblxyXG5leHBvcnQgaW50ZXJmYWNlIFBlYWtMZXZlbExpc3RlbmVyIHtcclxuICB1cGRhdGUocGVha0xldmVsOm51bWJlcik6IHZvaWQ7XHJcbn1cclxuXHJcbmV4cG9ydCBpbnRlcmZhY2UgUGVha0xldmVsTGlzdGVuZXIge1xyXG5cclxuICB1cGRhdGUobGV2ZWxJbmZvOiBMZXZlbEluZm8sIHBlYWtMZXZlbEluZm86IExldmVsSW5mbyk6IHZvaWQ7XHJcblxyXG4gIHN0cmVhbUZpbmlzaGVkKCk6IHZvaWQ7XHJcblxyXG4gIHJlc2V0KCk6IHZvaWQ7XHJcbn1cclxuXHJcbmV4cG9ydCBjbGFzcyBQZWFrTGV2ZWxJbnRlcmNlcHRvciBpbXBsZW1lbnRzIExldmVsTGlzdGVuZXJ7XHJcbiAgZ2V0IHBlYWtEYkx2bCgpOiBudW1iZXIge1xyXG4gICAgcmV0dXJuIHRoaXMuX3BlYWtEYkx2bDtcclxuICB9XHJcbiAgZ2V0IGNoYW5uZWxDb3VudCgpOiBudW1iZXIge1xyXG4gICAgcmV0dXJuIHRoaXMuX2NoYW5uZWxDb3VudDtcclxuICB9XHJcblxyXG4gIHNldCBjaGFubmVsQ291bnQodmFsdWU6IG51bWJlcikge1xyXG4gICAgdGhpcy5fY2hhbm5lbENvdW50ID0gdmFsdWU7XHJcbiAgICBpZih0aGlzLmxldmVsTGlzdGVuZXIpe1xyXG4gICAgICB0aGlzLmxldmVsTGlzdGVuZXIuY2hhbm5lbENvdW50PXZhbHVlO1xyXG4gICAgfVxyXG4gIH1cclxuXHJcbiAgcHJpdmF0ZSBfY2hhbm5lbENvdW50OiBudW1iZXI9MDtcclxuXHJcbiAgcHJpdmF0ZSBfcGVha0RiTHZsID0gTUlOX0RCX0xFVkVMO1xyXG5cclxuXHJcblxyXG4gIGNvbnN0cnVjdG9yKHByaXZhdGUgbGV2ZWxMaXN0ZW5lcj86TGV2ZWxMaXN0ZW5lcikge31cclxuXHJcbiAgdXBkYXRlKGxldmVsSW5mbzogTGV2ZWxJbmZvLCBwZWFrTGV2ZWxJbmZvOiBMZXZlbEluZm8pOiB2b2lke1xyXG4gICAgbGV0IHBlYWtEQlZhbCA9IGxldmVsSW5mby5wb3dlckxldmVsREIoKTtcclxuICAgIGlmICh0aGlzLnBlYWtEYkx2bCA8IHBlYWtEQlZhbCkge1xyXG4gICAgICB0aGlzLl9wZWFrRGJMdmwgPSBwZWFrREJWYWw7XHJcbiAgICB9XHJcbiAgfVxyXG5cclxuICBzdHJlYW1GaW5pc2hlZCgpOiB2b2lke1xyXG4gICAgaWYodGhpcy5sZXZlbExpc3RlbmVyKXtcclxuICAgICAgdGhpcy5sZXZlbExpc3RlbmVyLnN0cmVhbUZpbmlzaGVkKCk7XHJcbiAgICB9XHJcbiAgfVxyXG5cclxuICByZXNldCgpOiB2b2lke1xyXG4gICAgdGhpcy5fcGVha0RiTHZsID0gTUlOX0RCX0xFVkVMO1xyXG4gICAgaWYodGhpcy5sZXZlbExpc3RlbmVyKXtcclxuICAgICAgdGhpcy5sZXZlbExpc3RlbmVyLnJlc2V0KCk7XHJcbiAgICB9XHJcbiAgfVxyXG59XHJcblxyXG5kZWNsYXJlIGZ1bmN0aW9uIHBvc3RNZXNzYWdlKG1lc3NhZ2U6IGFueSwgdHJhbnNmZXI/OiBBcnJheTxhbnk+KTogdm9pZDtcclxuXHJcblxyXG5leHBvcnQgY2xhc3MgTGV2ZWxNZWFzdXJlIHtcclxuXHJcbiAgcHJpdmF0ZSByZWFkb25seSB3b3JrZXJVUkw6IHN0cmluZztcclxuICBwcml2YXRlIHdvcmtlcjogV29ya2VyfG51bGw9bnVsbDtcclxuXHJcbiAgY29uc3RydWN0b3IoKSB7XHJcbiAgICB0aGlzLndvcmtlclVSTCA9IFdvcmtlckhlbHBlci5idWlsZFdvcmtlckJsb2JVUkwodGhpcy53b3JrZXJGdW5jdGlvbilcclxuICB9XHJcblxyXG4gIGNhbGNCdWZmZXJMZXZlbEluZm9zKGF1ZGlvQnVmZmVyOiBBdWRpb0J1ZmZlciwgYnVmZmVyVGltZUxlbmd0aDogbnVtYmVyKTogUHJvbWlzZTxMZXZlbEluZm9zPiB7XHJcbiAgICByZXR1cm4gbmV3IFByb21pc2U8TGV2ZWxJbmZvcz4oKHJlc29sdmUpPT57XHJcbiAgICAgIGxldCBjaHMgPSBhdWRpb0J1ZmZlci5udW1iZXJPZkNoYW5uZWxzO1xyXG4gICAgICBsZXQgYnVmZmVyRnJhbWVMZW5ndGg9TWF0aC5yb3VuZChhdWRpb0J1ZmZlci5zYW1wbGVSYXRlKmJ1ZmZlclRpbWVMZW5ndGgpO1xyXG4gICAgICBsZXQgYnVmZmVycyA9IG5ldyBBcnJheTxhbnk+KGNocyk7XHJcbiAgICAgIGZvciAobGV0IGNoID0gMDsgY2ggPCBjaHM7IGNoKyspIHtcclxuICAgICAgICBsZXQgYWRDaD1hdWRpb0J1ZmZlci5nZXRDaGFubmVsRGF0YShjaCk7XHJcbiAgICAgICAgbGV0IGFkQ2hDb3B5PW5ldyBGbG9hdDMyQXJyYXkoYWRDaC5sZW5ndGgpO1xyXG4gICAgICAgIGFkQ2hDb3B5LnNldChhZENoKTtcclxuICAgICAgICBidWZmZXJzW2NoXSA9IGFkQ2hDb3B5LmJ1ZmZlcjtcclxuICAgICAgfVxyXG5cclxuICAgICAgdGhpcy53b3JrZXIgPSBuZXcgV29ya2VyKHRoaXMud29ya2VyVVJMKTtcclxuICAgICAgdGhpcy53b3JrZXIub25tZXNzYWdlID0gKG1lKSA9PiB7XHJcblxyXG4gICAgICAgIGxldCBsaW5MZXZlbEFycnM9bmV3IEFycmF5PEZsb2F0MzJBcnJheT4oY2hzKTtcclxuICAgICAgICBmb3IgKGxldCBjaCA9IDA7IGNoIDwgY2hzOyBjaCsrKSB7XHJcbiAgICAgICAgICBsaW5MZXZlbEFycnNbY2hdID0gbmV3IEZsb2F0MzJBcnJheShtZS5kYXRhLmxpbkxldmVsQnVmZmVyc1tjaF0pO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgbGV0IGJ1ZmZlckNvdW50PU1hdGguY2VpbChtZS5kYXRhLmZyYW1lTGVuZ3RoL21lLmRhdGEuYnVmZmVyRnJhbWVMZW5ndGgpO1xyXG4gICAgICAgIGxldCBmcmFtZVBvcz0wO1xyXG4gICAgICAgIGxldCBidWZmZXJMZXZlbEluZm9zPW5ldyBBcnJheTxMZXZlbEluZm8+KCk7XHJcbiAgICAgICAgbGV0IHBlYWtMZXZlbEluZm89bmV3IExldmVsSW5mbyhjaHMpO1xyXG4gICAgICAgIGZvcihsZXQgYmk9MDtiaTxidWZmZXJDb3VudDtiaSsrKSB7XHJcbiAgICAgICAgICBsZXQgbWluTGV2ZWxzID0gbmV3IEFycmF5PG51bWJlcj4oY2hzKTtcclxuICAgICAgICAgIGxldCBtYXhMZXZlbHMgPSBuZXcgQXJyYXk8bnVtYmVyPihjaHMpO1xyXG4gICAgICAgICAgZm9yIChsZXQgY2ggPSAwOyBjaCA8IGNoczsgY2grKykge1xyXG4gICAgICAgICAgICBsZXQgbGluTHZsQXJyUG9zPWJpKjI7XHJcbiAgICAgICAgICAgIG1pbkxldmVsc1tjaF09bGluTGV2ZWxBcnJzW2NoXVtsaW5MdmxBcnJQb3NdO1xyXG4gICAgICAgICAgICBtYXhMZXZlbHNbY2hdPWxpbkxldmVsQXJyc1tjaF1bbGluTHZsQXJyUG9zKzFdO1xyXG4gICAgICAgICAgfVxyXG4gICAgICAgICAgbGV0IGJsaSA9IG5ldyBMZXZlbEluZm8oY2hzLCBmcmFtZVBvcywgbWUuZGF0YS5idWZmZXJGcmFtZUxlbmd0aCwgbWluTGV2ZWxzLCBtYXhMZXZlbHMpO1xyXG4gICAgICAgICAgYnVmZmVyTGV2ZWxJbmZvcy5wdXNoKGJsaSk7XHJcbiAgICAgICAgICBwZWFrTGV2ZWxJbmZvLm1lcmdlKGJsaSk7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIHRoaXMudGVybWluYXRlV29ya2VyKCk7XHJcbiAgICAgICAgcmVzb2x2ZShuZXcgTGV2ZWxJbmZvcyhidWZmZXJMZXZlbEluZm9zLCBwZWFrTGV2ZWxJbmZvKSk7XHJcbiAgICAgIH07XHJcblxyXG4gICAgICB0aGlzLndvcmtlci5wb3N0TWVzc2FnZSh7YnVmZmVyRnJhbWVMZW5ndGg6YnVmZmVyRnJhbWVMZW5ndGgsYXVkaW9EYXRhOiBidWZmZXJzLCBjaHM6IGNoc30sIGJ1ZmZlcnMpO1xyXG5cclxuICAgIH0pO1xyXG5cclxuICB9XHJcblxyXG5cclxuICBwcml2YXRlIHRlcm1pbmF0ZVdvcmtlcigpIHtcclxuICAgIHRoaXMud29ya2VyPy50ZXJtaW5hdGUoKTtcclxuXHJcbiAgfVxyXG5cclxuICAvKlxyXG4gICAqICBNZXRob2QgdXNlZCBhcyB3b3JrZXIgY29kZS5cclxuICAgKi9cclxuICB3b3JrZXJGdW5jdGlvbigpIHtcclxuICAgIHNlbGYub25tZXNzYWdlID0gZnVuY3Rpb24gKG1zZzpNZXNzYWdlRXZlbnQpIHtcclxuXHJcbiAgICAgIGxldCBjaHMgPSBtc2cuZGF0YS5jaHM7XHJcbiAgICAgIGxldCBidWZmZXJGcmFtZUxlbmd0aCA9IG1zZy5kYXRhLmJ1ZmZlckZyYW1lTGVuZ3RoO1xyXG5cclxuICAgICAgbGV0IGF1ZGlvRGF0YSA9IG5ldyBBcnJheTxGbG9hdDMyQXJyYXk+KGNocyk7XHJcbiAgICAgIGxldCBsaW5MZXZlbHMgPSBuZXcgQXJyYXk8RmxvYXQzMkFycmF5PihjaHMpO1xyXG5cclxuICAgICAgZm9yIChsZXQgY2ggPSAwOyBjaCA8IGNoczsgY2grKykge1xyXG4gICAgICAgIGF1ZGlvRGF0YVtjaF0gPSBuZXcgRmxvYXQzMkFycmF5KG1zZy5kYXRhLmF1ZGlvRGF0YVtjaF0pO1xyXG4gICAgICB9XHJcbiAgICAgIGxldCBmcmFtZUxlbmd0aCA9IGF1ZGlvRGF0YVswXS5sZW5ndGg7XHJcbiAgICAgIGxldCBidWZmZXJDb3VudD1NYXRoLmNlaWwoZnJhbWVMZW5ndGgvYnVmZmVyRnJhbWVMZW5ndGgpO1xyXG4gICAgICBmb3IgKGxldCBjaCA9IDA7IGNoIDwgY2hzOyBjaCsrKSB7XHJcbiAgICAgICAgbGluTGV2ZWxzW2NoXSA9IG5ldyBGbG9hdDMyQXJyYXkoYnVmZmVyQ291bnQqMik7XHJcbiAgICAgIH1cclxuICAgICAgaWYgKGF1ZGlvRGF0YSAmJiBjaHMgPiAwKSB7XHJcbiAgICAgICAgZm9yIChsZXQgY2ggPSAwOyBjaCA8IGNoczsgY2grKykge1xyXG4gICAgICAgICAgbGV0IGNoRGF0YSA9IGF1ZGlvRGF0YVtjaF07XHJcblxyXG4gICAgICAgICAgZm9yIChsZXQgcyA9IDA7IHMgPCBmcmFtZUxlbmd0aDsgcysrKSB7XHJcbiAgICAgICAgICAgIGxldCBiaSA9IE1hdGguZmxvb3IocyAvIGJ1ZmZlckZyYW1lTGVuZ3RoKTtcclxuICAgICAgICAgICAgbGV0IGx2bEFyclBvcyA9IGJpICogMjtcclxuICAgICAgICAgICAgLy9sZXQgYnMgPSBzICUgYnVmZmVyRnJhbWVMZW5ndGg7XHJcbiAgICAgICAgICAgIGxldCBjaFNhbXBsZT1jaERhdGFbc107XHJcbiAgICAgICAgICAgIGlmIChjaFNhbXBsZSA8IGxpbkxldmVsc1tjaF1bbHZsQXJyUG9zXSkge1xyXG4gICAgICAgICAgICAgIGxpbkxldmVsc1tjaF1bbHZsQXJyUG9zXSA9IGNoU2FtcGxlO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIGx2bEFyclBvcysrO1xyXG4gICAgICAgICAgICBpZiAoY2hTYW1wbGUgPiBsaW5MZXZlbHNbY2hdW2x2bEFyclBvc10pIHtcclxuICAgICAgICAgICAgICBsaW5MZXZlbHNbY2hdW2x2bEFyclBvc10gPSBjaFNhbXBsZTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuICAgICAgICBjb25zdCBsaW5MZXZlbEJ1ZnMgPSBuZXcgQXJyYXk8YW55PihjaHMpO1xyXG4gICAgICAgIGZvciAobGV0IGNoID0gMDsgY2ggPCBjaHM7IGNoKyspIHtcclxuICAgICAgICAgIGxpbkxldmVsQnVmc1tjaF0gPSBsaW5MZXZlbHNbY2hdLmJ1ZmZlcjtcclxuICAgICAgICB9XHJcbiAgICAgICAgcG9zdE1lc3NhZ2Uoe2J1ZmZlckZyYW1lTGVuZ3RoOmJ1ZmZlckZyYW1lTGVuZ3RoLGZyYW1lTGVuZ3RoOmZyYW1lTGVuZ3RoLGxpbkxldmVsQnVmZmVyczogbGluTGV2ZWxCdWZzfSwgbGluTGV2ZWxCdWZzKTtcclxuICAgICAgfVxyXG4gICAgfVxyXG4gIH1cclxufVxyXG5cclxuXHJcbmV4cG9ydCBjbGFzcyBTdHJlYW1MZXZlbE1lYXN1cmUgaW1wbGVtZW50cyBTZXF1ZW5jZUF1ZGlvRmxvYXQzMk91dFN0cmVhbSB7XHJcblxyXG4gIGN1cnJlbnRMZXZlbEluZm9zOiBMZXZlbEluZm98bnVsbD1udWxsO1xyXG4gIHBlYWtMZXZlbEluZm86IExldmVsSW5mb3xudWxsPW51bGw7XHJcblxyXG4gIHByaXZhdGUgcmVhZG9ubHkgd29ya2VyVVJMOiBzdHJpbmc7XHJcbiAgcHJpdmF0ZSB3b3JrZXI6IFdvcmtlcnxudWxsPW51bGw7XHJcbiAgcHJpdmF0ZSBjaGFubmVsQ291bnQ6IG51bWJlcj0wO1xyXG4gIHByaXZhdGUgYnVmZmVySW5kZXg6IG51bWJlciA9IDA7XHJcbiAgcHJpdmF0ZSBmcmFtZUNvdW50OiBudW1iZXIgPSAwO1xyXG5cclxuICBsZXZlbExpc3RlbmVyOiBMZXZlbExpc3RlbmVyfG51bGw9bnVsbDtcclxuICBwZWFrTGV2ZWxMaXN0ZW5lcjogKChwZWFrTHZsSW5EYjpudW1iZXIpPT52b2lkKXxudWxsPW51bGw7XHJcbiAgcHJpdmF0ZSBwZWFrTGV2ZWxJbkRiOm51bWJlcj1NSU5fREJfTEVWRUw7XHJcblxyXG4gIGNvbnN0cnVjdG9yKCkge1xyXG4gICAgdGhpcy53b3JrZXJVUkwgPSBXb3JrZXJIZWxwZXIuYnVpbGRXb3JrZXJCbG9iVVJMKHRoaXMud29ya2VyRnVuY3Rpb24pXHJcbiAgfVxyXG5cclxuICBzZXRGb3JtYXQoY2hhbm5lbHM6IG51bWJlciwgc2FtcGxlUmF0ZTogbnVtYmVyKSB7XHJcbiAgICB0aGlzLmNoYW5uZWxDb3VudCA9IGNoYW5uZWxzO1xyXG4gICAgdGhpcy5jdXJyZW50TGV2ZWxJbmZvcyA9IG5ldyBMZXZlbEluZm8odGhpcy5jaGFubmVsQ291bnQpO1xyXG4gICAgdGhpcy5wZWFrTGV2ZWxJbmZvID0gbmV3IExldmVsSW5mbyh0aGlzLmNoYW5uZWxDb3VudCk7XHJcbiAgICB0aGlzLndvcmtlciA9IG5ldyBXb3JrZXIodGhpcy53b3JrZXJVUkwpO1xyXG4gICAgdGhpcy53b3JrZXIub25tZXNzYWdlID0gKG1lKSA9PiB7XHJcbiAgICAgIGxldCBzdHJlYW1GaW5pc2hlZCA9IG1lLmRhdGEuc3RyZWFtRmluaXNoZWQ7XHJcbiAgICAgIGlmIChzdHJlYW1GaW5pc2hlZCkge1xyXG4gICAgICAgIGlmICh0aGlzLmxldmVsTGlzdGVuZXIpIHtcclxuICAgICAgICAgIHRoaXMubGV2ZWxMaXN0ZW5lci5zdHJlYW1GaW5pc2hlZCgpXHJcbiAgICAgICAgfVxyXG4gICAgICB9IGVsc2Uge1xyXG5cclxuICAgICAgICBsZXQgbWluTGV2ZWxzID0gbmV3IEFycmF5PG51bWJlcj4odGhpcy5jaGFubmVsQ291bnQpO1xyXG4gICAgICAgIGxldCBtYXhMZXZlbHMgPSBuZXcgQXJyYXk8bnVtYmVyPih0aGlzLmNoYW5uZWxDb3VudCk7XHJcbiAgICAgICAgZm9yIChsZXQgY2ggPSAwOyBjaCA8IHRoaXMuY2hhbm5lbENvdW50OyBjaCsrKSB7XHJcbiAgICAgICAgICBsZXQgZmxzID0gbmV3IEZsb2F0MzJBcnJheShtZS5kYXRhLmxpbkxldmVsQnVmZmVyc1tjaF0pO1xyXG4gICAgICAgICAgbWluTGV2ZWxzW2NoXSA9IGZsc1swXTtcclxuICAgICAgICAgIG1heExldmVsc1tjaF0gPSBmbHNbMV07XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGxldCBiaSA9IG5ldyBMZXZlbEluZm8odGhpcy5jaGFubmVsQ291bnQsIHRoaXMuZnJhbWVDb3VudCwgbWUuZGF0YS5mcmFlbUxlbmd0aCwgbWluTGV2ZWxzLCBtYXhMZXZlbHMpO1xyXG4gICAgICAgIHRoaXMudXBkYXRlTGV2ZWxzKGJpKTtcclxuICAgICAgfVxyXG4gICAgfVxyXG4gIH1cclxuXHJcblxyXG4gIG5leHRTdHJlYW0oKSB7XHJcbiAgICB0aGlzLnJlc2V0KCk7XHJcbiAgfVxyXG5cclxuICBwcml2YXRlIHJlc2V0KCkge1xyXG4gICAgdGhpcy5jdXJyZW50TGV2ZWxJbmZvcyA9IG5ldyBMZXZlbEluZm8odGhpcy5jaGFubmVsQ291bnQpO1xyXG4gICAgdGhpcy5wZWFrTGV2ZWxJbmZvID0gbmV3IExldmVsSW5mbyh0aGlzLmNoYW5uZWxDb3VudCk7XHJcbiAgICBpZiAodGhpcy5sZXZlbExpc3RlbmVyKSB7XHJcbiAgICAgIHRoaXMubGV2ZWxMaXN0ZW5lci5yZXNldCgpO1xyXG4gICAgICB0aGlzLmxldmVsTGlzdGVuZXIuY2hhbm5lbENvdW50ID0gdGhpcy5jaGFubmVsQ291bnQ7XHJcbiAgICB9XHJcbiAgICBpZiAodGhpcy5wZWFrTGV2ZWxMaXN0ZW5lcikge1xyXG4gICAgICB0aGlzLnBlYWtMZXZlbEluRGI9TUlOX0RCX0xFVkVMO1xyXG4gICAgICB0aGlzLnBlYWtMZXZlbExpc3RlbmVyKHRoaXMucGVha0xldmVsSW5EYik7XHJcbiAgICB9XHJcbiAgfVxyXG5cclxuICB3cml0ZShidWZmZXJEYXRhOiBBcnJheTxGbG9hdDMyQXJyYXk+KTogbnVtYmVyIHtcclxuICAgIGxldCBidWZBcnJDb3BpZXMgPSBuZXcgQXJyYXk8RmxvYXQzMkFycmF5PihidWZmZXJEYXRhLmxlbmd0aCk7XHJcbiAgICBsZXQgYnVmZmVycyA9IG5ldyBBcnJheTxhbnk+KGJ1ZmZlckRhdGEubGVuZ3RoKTtcclxuICAgIGZvciAobGV0IGNoID0gMDsgY2ggPCBidWZmZXJEYXRhLmxlbmd0aDsgY2grKykge1xyXG4gICAgICBidWZBcnJDb3BpZXNbY2hdID0gYnVmZmVyRGF0YVtjaF0uc2xpY2UoKTtcclxuICAgICAgYnVmZmVyc1tjaF0gPSBidWZBcnJDb3BpZXNbY2hdLmJ1ZmZlcjtcclxuICAgIH1cclxuICAgIHRoaXMud29ya2VyPy5wb3N0TWVzc2FnZSh7XHJcbiAgICAgIHN0cmVhbUZpbmlzaGVkOiBmYWxzZSxcclxuICAgICAgYXVkaW9EYXRhOiBidWZmZXJzLFxyXG4gICAgICBjaHM6IHRoaXMuY2hhbm5lbENvdW50LFxyXG4gICAgICBidWZmZXJJbmRleDogdGhpcy5idWZmZXJJbmRleFxyXG4gICAgfSwgYnVmZmVycyk7XHJcbiAgICB0aGlzLmJ1ZmZlckluZGV4Kys7XHJcbiAgICByZXR1cm4gYnVmQXJyQ29waWVzWzBdLmxlbmd0aDtcclxuICB9XHJcblxyXG4gIGZsdXNoKCkge1xyXG4gICAgdGhpcy53b3JrZXI/LnBvc3RNZXNzYWdlKHtzdHJlYW1GaW5pc2hlZDogdHJ1ZX0pO1xyXG5cclxuICB9XHJcblxyXG4gIGNsb3NlKCkge1xyXG4gICAgICB0aGlzLndvcmtlcj8udGVybWluYXRlKCk7XHJcbiAgfVxyXG5cclxuICAvKlxyXG4gICAqICBNZXRob2QgdXNlZCBhcyB3b3JrZXIgY29kZS5cclxuICAgKi9cclxuICB3b3JrZXJGdW5jdGlvbigpIHtcclxuICAgIHNlbGYub25tZXNzYWdlID0gZnVuY3Rpb24gKG1zZzpNZXNzYWdlRXZlbnQpIHtcclxuICAgICAgbGV0IHN0cmVhbUZpbmlzaGVkID0gbXNnLmRhdGEuc3RyZWFtRmluaXNoZWQ7XHJcbiAgICAgIGlmIChzdHJlYW1GaW5pc2hlZCkge1xyXG4gICAgICAgIHBvc3RNZXNzYWdlKHtzdHJlYW1GaW5pc2hlZDogdHJ1ZX0pO1xyXG4gICAgICB9IGVsc2Uge1xyXG4gICAgICAgIGxldCBjaHMgPSBtc2cuZGF0YS5jaHM7XHJcbiAgICAgICAgbGV0IGZyYW1lTGVuZ3RoID0gbnVsbDtcclxuICAgICAgICBsZXQgYXVkaW9EYXRhID0gbmV3IEFycmF5PEZsb2F0MzJBcnJheT4oY2hzKTtcclxuICAgICAgICBsZXQgbGluTGV2ZWxzID0gbmV3IEFycmF5PEZsb2F0MzJBcnJheT4oY2hzKTtcclxuICAgICAgICBmb3IgKGxldCBjaCA9IDA7IGNoIDwgY2hzOyBjaCsrKSB7XHJcbiAgICAgICAgICBsaW5MZXZlbHNbY2hdID0gbmV3IEZsb2F0MzJBcnJheSgyKTtcclxuICAgICAgICAgIGF1ZGlvRGF0YVtjaF0gPSBuZXcgRmxvYXQzMkFycmF5KG1zZy5kYXRhLmF1ZGlvRGF0YVtjaF0pO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgaWYgKGF1ZGlvRGF0YSkge1xyXG4gICAgICAgICAgZm9yIChsZXQgY2ggPSAwOyBjaCA8IGNoczsgY2grKykge1xyXG4gICAgICAgICAgICBsZXQgY2hEYXRhID0gYXVkaW9EYXRhW2NoXTtcclxuICAgICAgICAgICAgaWYgKGZyYW1lTGVuZ3RoID09PSBudWxsKSB7XHJcbiAgICAgICAgICAgICAgZnJhbWVMZW5ndGggPSBjaERhdGEubGVuZ3RoO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIGZvciAobGV0IHMgPSAwOyBzIDwgZnJhbWVMZW5ndGg7IHMrKykge1xyXG4gICAgICAgICAgICAgIGxldCBjaFNhbXBsZT1jaERhdGFbc107XHJcbiAgICAgICAgICAgICAgaWYgKGNoU2FtcGxlIDwgbGluTGV2ZWxzW2NoXVswXSkge1xyXG4gICAgICAgICAgICAgICAgbGluTGV2ZWxzW2NoXVswXSA9IGNoU2FtcGxlO1xyXG4gICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICBpZiAoY2hTYW1wbGUgPiBsaW5MZXZlbHNbY2hdWzFdKSB7XHJcbiAgICAgICAgICAgICAgICBsaW5MZXZlbHNbY2hdWzFdID0gY2hTYW1wbGU7XHJcbiAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGxldCBsaW5MZXZlbEJ1ZnMgPSBuZXcgQXJyYXk8YW55PihjaHMpO1xyXG4gICAgICAgIGZvciAobGV0IGNoID0gMDsgY2ggPCBjaHM7IGNoKyspIHtcclxuICAgICAgICAgIGxpbkxldmVsQnVmc1tjaF0gPSBsaW5MZXZlbHNbY2hdLmJ1ZmZlcjtcclxuICAgICAgICB9XHJcbiAgICAgICAgcG9zdE1lc3NhZ2Uoe3N0cmVhbUZpbmlzaGVkOiBmYWxzZSwgZnJhbWVMZW5ndGg6IGZyYW1lTGVuZ3RoLCBsaW5MZXZlbEJ1ZmZlcnM6IGxpbkxldmVsQnVmc30sIGxpbkxldmVsQnVmcyk7XHJcbiAgICAgIH1cclxuICAgIH1cclxuICB9XHJcblxyXG4gIHVwZGF0ZUxldmVscyhidWZmZXJMZXZlbEluZm86IExldmVsSW5mbykge1xyXG5cclxuICAgIHRoaXMuY3VycmVudExldmVsSW5mb3MgPSBidWZmZXJMZXZlbEluZm87XHJcbiAgICBpZih0aGlzLnBlYWtMZXZlbEluZm8pIHtcclxuICAgICAgdGhpcy5wZWFrTGV2ZWxJbmZvLm1lcmdlKGJ1ZmZlckxldmVsSW5mbyk7XHJcbiAgICAgIGlmICh0aGlzLmxldmVsTGlzdGVuZXIpIHtcclxuICAgICAgICB0aGlzLmxldmVsTGlzdGVuZXIudXBkYXRlKHRoaXMuY3VycmVudExldmVsSW5mb3MsIHRoaXMucGVha0xldmVsSW5mby5jbG9uZSgpKTtcclxuICAgICAgfVxyXG4gICAgICBpZih0aGlzLnBlYWtMZXZlbExpc3RlbmVyKXtcclxuICAgICAgICBsZXQgcGVha0RCVmFsID0gYnVmZmVyTGV2ZWxJbmZvLnBvd2VyTGV2ZWxEQigpO1xyXG4gICAgICAgIGlmICh0aGlzLnBlYWtMZXZlbEluRGIgPCBwZWFrREJWYWwpIHtcclxuICAgICAgICAgIHRoaXMucGVha0xldmVsSW5EYiA9IHBlYWtEQlZhbDtcclxuICAgICAgICAgIC8vIHRoZSBldmVudCBjb21lcyBmcm9tIG91dHNpZGUgb2YgYW4gQW5ndWxhciB6b25lXHJcbiAgICAgICAgICB0aGlzLnBlYWtMZXZlbExpc3RlbmVyKHRoaXMucGVha0xldmVsSW5EYik7XHJcbiAgICAgICAgfVxyXG4gICAgICB9XHJcbiAgICB9XHJcbiAgfVxyXG5cclxuXHJcbiAgc3RvcCgpIHtcclxuICAgIHRoaXMud29ya2VyPy50ZXJtaW5hdGUoKTtcclxuICB9XHJcblxyXG5cclxufVxyXG4iXX0=
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|