speechrecorderng 3.10.13 → 3.11.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.
Files changed (99) hide show
  1. package/README.md +1 -1
  2. package/fesm2022/speechrecorderng.mjs +204 -201
  3. package/fesm2022/speechrecorderng.mjs.map +1 -1
  4. package/lib/audio/ui/audio_canvas_layer_comp.d.ts +2 -2
  5. package/lib/spr.module.version.d.ts +1 -1
  6. package/lib/ui/canvas_layer_comp.d.ts +1 -1
  7. package/lib/ui/responsive_component.d.ts +1 -1
  8. package/package.json +13 -15
  9. package/esm2022/lib/action/action.mjs +0 -73
  10. package/esm2022/lib/audio/array_audio_buffer.mjs +0 -164
  11. package/esm2022/lib/audio/array_audio_buffer_input_stream.mjs +0 -86
  12. package/esm2022/lib/audio/array_audio_buffer_random_access_stream.mjs +0 -16
  13. package/esm2022/lib/audio/audio_data_holder.mjs +0 -264
  14. package/esm2022/lib/audio/audio_display.mjs +0 -118
  15. package/esm2022/lib/audio/audio_player.mjs +0 -238
  16. package/esm2022/lib/audio/capture/capture.mjs +0 -855
  17. package/esm2022/lib/audio/context.mjs +0 -79
  18. package/esm2022/lib/audio/dsp/level_measure.mjs +0 -517
  19. package/esm2022/lib/audio/format.mjs +0 -20
  20. package/esm2022/lib/audio/impl/wavformat.mjs +0 -7
  21. package/esm2022/lib/audio/impl/wavreader.mjs +0 -144
  22. package/esm2022/lib/audio/impl/wavwriter.mjs +0 -191
  23. package/esm2022/lib/audio/inddb_audio_buffer.mjs +0 -508
  24. package/esm2022/lib/audio/io/stream.mjs +0 -59
  25. package/esm2022/lib/audio/net_audio_buffer.mjs +0 -293
  26. package/esm2022/lib/audio/persistor.mjs +0 -81
  27. package/esm2022/lib/audio/playback/array_audio_buffer_source_node.mjs +0 -126
  28. package/esm2022/lib/audio/playback/audio_source_node.mjs +0 -18
  29. package/esm2022/lib/audio/playback/audio_source_worklet_module_loader.mjs +0 -167
  30. package/esm2022/lib/audio/playback/inddb_audio_buffer_source_node.mjs +0 -167
  31. package/esm2022/lib/audio/playback/net_audio_buffer_source_node.mjs +0 -218
  32. package/esm2022/lib/audio/playback/player.mjs +0 -402
  33. package/esm2022/lib/audio/ui/audio_canvas_layer_comp.mjs +0 -347
  34. package/esm2022/lib/audio/ui/audio_display_control.mjs +0 -150
  35. package/esm2022/lib/audio/ui/audio_display_scroll_pane.mjs +0 -146
  36. package/esm2022/lib/audio/ui/audiosignal.mjs +0 -533
  37. package/esm2022/lib/audio/ui/common.mjs +0 -19
  38. package/esm2022/lib/audio/ui/container.mjs +0 -414
  39. package/esm2022/lib/audio/ui/livelevel.mjs +0 -361
  40. package/esm2022/lib/audio/ui/scroll_pane_horizontal.mjs +0 -11
  41. package/esm2022/lib/audio/ui/sonagram.mjs +0 -900
  42. package/esm2022/lib/db/inddb.mjs +0 -120
  43. package/esm2022/lib/dsp/utils.mjs +0 -48
  44. package/esm2022/lib/environment/environment.defaults.mjs +0 -9
  45. package/esm2022/lib/io/BinaryReader.mjs +0 -93
  46. package/esm2022/lib/io/BinaryWriter.mjs +0 -80
  47. package/esm2022/lib/io/stream.mjs +0 -259
  48. package/esm2022/lib/math/2d/geometry.mjs +0 -28
  49. package/esm2022/lib/math/complex.mjs +0 -58
  50. package/esm2022/lib/math/dft.mjs +0 -196
  51. package/esm2022/lib/media/utils.mjs +0 -14
  52. package/esm2022/lib/net/uploader.mjs +0 -367
  53. package/esm2022/lib/recorder_component.mjs +0 -65
  54. package/esm2022/lib/speechrecorder/project/project.mjs +0 -54
  55. package/esm2022/lib/speechrecorder/project/project.service.mjs +0 -64
  56. package/esm2022/lib/speechrecorder/recording.mjs +0 -124
  57. package/esm2022/lib/speechrecorder/recordings/basic_recording.service.mjs +0 -221
  58. package/esm2022/lib/speechrecorder/recordings/recordings.service.mjs +0 -1014
  59. package/esm2022/lib/speechrecorder/script/script.mjs +0 -114
  60. package/esm2022/lib/speechrecorder/script/script.service.mjs +0 -47
  61. package/esm2022/lib/speechrecorder/session/audiorecorder.mjs +0 -1179
  62. package/esm2022/lib/speechrecorder/session/basicrecorder.mjs +0 -676
  63. package/esm2022/lib/speechrecorder/session/controlpanel.mjs +0 -416
  64. package/esm2022/lib/speechrecorder/session/item.mjs +0 -30
  65. package/esm2022/lib/speechrecorder/session/progress.mjs +0 -135
  66. package/esm2022/lib/speechrecorder/session/prompting.mjs +0 -639
  67. package/esm2022/lib/speechrecorder/session/recorder_combi_pane.mjs +0 -88
  68. package/esm2022/lib/speechrecorder/session/recording_file_cache.mjs +0 -195
  69. package/esm2022/lib/speechrecorder/session/recording_list.mjs +0 -188
  70. package/esm2022/lib/speechrecorder/session/recordingfile/recording-file-meta.component.mjs +0 -128
  71. package/esm2022/lib/speechrecorder/session/recordingfile/recording-file-navi.component.mjs +0 -114
  72. package/esm2022/lib/speechrecorder/session/recordingfile/recording-file-u-i.component.mjs +0 -146
  73. package/esm2022/lib/speechrecorder/session/recordingfile/recording-file-view.component.mjs +0 -424
  74. package/esm2022/lib/speechrecorder/session/recordingfile/recording-file.mjs +0 -68
  75. package/esm2022/lib/speechrecorder/session/recordingfile/recordingfile-service.mjs +0 -288
  76. package/esm2022/lib/speechrecorder/session/session.mjs +0 -2
  77. package/esm2022/lib/speechrecorder/session/session.service.mjs +0 -69
  78. package/esm2022/lib/speechrecorder/session/session_finished_dialog.mjs +0 -46
  79. package/esm2022/lib/speechrecorder/session/sessionmanager.mjs +0 -1385
  80. package/esm2022/lib/speechrecorder/session/warning_bar.mjs +0 -33
  81. package/esm2022/lib/speechrecorder/spruploader.mjs +0 -22
  82. package/esm2022/lib/speechrecorder/startstopsignal/startstopsignal.mjs +0 -2
  83. package/esm2022/lib/speechrecorder/startstopsignal/ui/simpletrafficlight.mjs +0 -57
  84. package/esm2022/lib/speechrecorderng.component.mjs +0 -392
  85. package/esm2022/lib/speechrecorderng.module.mjs +0 -97
  86. package/esm2022/lib/spr.config.mjs +0 -27
  87. package/esm2022/lib/spr.module.version.mjs +0 -2
  88. package/esm2022/lib/ui/canvas_layer_comp.mjs +0 -38
  89. package/esm2022/lib/ui/intersection-observer.directive.mjs +0 -32
  90. package/esm2022/lib/ui/message_dialog.mjs +0 -51
  91. package/esm2022/lib/ui/recordingitem_display.mjs +0 -253
  92. package/esm2022/lib/ui/responsive_component.mjs +0 -24
  93. package/esm2022/lib/utils/scrollIntoViewToBottom.mjs +0 -23
  94. package/esm2022/lib/utils/ua-parser.mjs +0 -190
  95. package/esm2022/lib/utils/utils.mjs +0 -132
  96. package/esm2022/lib/utils/wake_lock.mjs +0 -114
  97. package/esm2022/lib/utils/wake_lock_media.mjs +0 -2
  98. package/esm2022/public-api.mjs +0 -35
  99. package/esm2022/speechrecorderng.mjs +0 -5
@@ -1,533 +0,0 @@
1
- import { Component, ViewChild } from '@angular/core';
2
- import { AudioCanvasLayerComponent } from "./audio_canvas_layer_comp";
3
- import { WorkerHelper } from "../../utils/utils";
4
- import { AudioBufferSource } from "../audio_data_holder";
5
- import * as i0 from "@angular/core";
6
- export class AudioSignal extends AudioCanvasLayerComponent {
7
- constructor(ref) {
8
- super();
9
- this.ref = ref;
10
- this._playFramePosition = null;
11
- this.worker = null;
12
- this.raAsSubsc = null;
13
- this.workerURL = WorkerHelper.buildWorkerBlobURL(this.workerFunction);
14
- this._audioDataHolder = null;
15
- this._bgColor = 'black';
16
- this._selectColor = 'rgba(255,255,0,0.8)';
17
- }
18
- ngAfterViewInit() {
19
- this.ce = this.ref.nativeElement;
20
- this.bgCanvas = this.bgCanvasRef.nativeElement;
21
- this.bgCanvas.style.zIndex = '1';
22
- this.signalCanvas = this.audioSignalCanvasRef.nativeElement;
23
- this.signalCanvas.style.zIndex = '2';
24
- this.markerCanvas = this.playPosCanvasRef.nativeElement;
25
- this.markerCanvas.style.zIndex = '3';
26
- this.cursorCanvas = this.cursorCanvasRef.nativeElement;
27
- this.cursorCanvas.style.zIndex = '4';
28
- this.canvasLayers[0] = this.bgCanvas;
29
- this.canvasLayers[1] = this.signalCanvas;
30
- this.canvasLayers[2] = this.cursorCanvas;
31
- this.canvasLayers[3] = this.markerCanvas;
32
- }
33
- get playFramePosition() {
34
- return this._playFramePosition;
35
- }
36
- set playFramePosition(playFramePosition) {
37
- this._playFramePosition = playFramePosition;
38
- this.drawPlayPosition();
39
- }
40
- drawPlayPosition() {
41
- if (this.markerCanvas) {
42
- let w = this.markerCanvas.width;
43
- let h = this.markerCanvas.height;
44
- let g = this.markerCanvas.getContext("2d");
45
- if (g) {
46
- g.clearRect(0, 0, w, h);
47
- if (this._playFramePosition) {
48
- let pixelPos = this.frameToViewPortXPixelPosition(this._playFramePosition);
49
- if (pixelPos) {
50
- g.fillStyle = 'red';
51
- g.strokeStyle = 'red';
52
- g.beginPath();
53
- g.moveTo(pixelPos, 0);
54
- g.lineTo(pixelPos, h);
55
- g.closePath();
56
- g.stroke();
57
- }
58
- }
59
- }
60
- }
61
- }
62
- /*
63
- * Method used as worker code.
64
- */
65
- workerFunction() {
66
- addEventListener('message', ({ data }) => {
67
- const audioData = data.audioData; // audio data part required to render view port
68
- const auOffset = data.audioDataOffset;
69
- const l = data.l; // left pixel position of view port
70
- const w = data.w; // width of viewport
71
- const vw = data.vw; // total width of (virtual) audio view (not viewport width)
72
- const chs = data.chs; // number of channels
73
- //const dataFrameLength = data.audioDataFrameLength; // frame length of audio data part required for view port
74
- const frameLength = data.frameLength; // total frame length (of audio clip)
75
- //console.debug("W: left: "+l+", w:"+w+", vw: "+vw+", chs: "+chs+", frameLength: "+frameLength);
76
- let psMinMax = new Float32Array(0);
77
- if (audioData && audioData.length > 0 && w >= 0 && vw > 0) {
78
- const framesPerPixel = frameLength / vw;
79
- const pointsLen = w * chs;
80
- // one for min one for max
81
- const arrLen = pointsLen * 2;
82
- psMinMax = new Float32Array(arrLen);
83
- let chFramePos = 0;
84
- const chFrameLength = audioData.length / chs;
85
- for (let ch = 0; ch < chs; ch++) {
86
- chFramePos = ch * chFrameLength;
87
- for (let pii = 0; pii < w; pii++) {
88
- const virtPii = l + pii;
89
- let pMin = Infinity;
90
- let pMax = -Infinity;
91
- let pixelFramePos = Math.round(chFramePos + (virtPii * framesPerPixel));
92
- // calculate pixel min/max amplitude
93
- for (let ai = 0; ai < framesPerPixel; ai++) {
94
- const framePos = pixelFramePos + ai;
95
- let a = 0;
96
- const bufPos = framePos - auOffset;
97
- //let bufPos=framePos;
98
- if (bufPos >= 0 && bufPos < audioData.length) {
99
- a = audioData[bufPos];
100
- //console.debug("W: ch: "+ch+", pixelFramePos: "+pixelFramePos+", framePos: "+framePos+", auOffset: "+auOffset+", bufPos: "+bufPos+", audioData.length: "+audioData.length+", a: "+a);
101
- if (a < pMin) {
102
- pMin = a;
103
- }
104
- if (a > pMax) {
105
- pMax = a;
106
- }
107
- }
108
- }
109
- const psMinPos = ch * w + pii;
110
- psMinMax[psMinPos] = pMin;
111
- const psMaxPos = pointsLen + psMinPos;
112
- psMinMax[psMaxPos] = pMax;
113
- //console.debug("psMinMax["+psMinPos+"]="+pMin+",psMinMax["+psMaxPos+"]="+pMax);
114
- }
115
- }
116
- }
117
- postMessage({ psMinMax: psMinMax, l: data.l, w: data.w, chs: data.chs, eod: data.eod }, [psMinMax.buffer]);
118
- });
119
- }
120
- startDraw(clear = true) {
121
- if (clear) {
122
- if (this.bounds) {
123
- this.signalCanvas.style.left = Math.round(this.bounds.position.left).toString() + 'px';
124
- this.signalCanvas.width = Math.round(this.bounds.dimension.width);
125
- this.signalCanvas.height = Math.round(this.bounds.dimension.height);
126
- let g = this.signalCanvas.getContext("2d");
127
- if (g) {
128
- //g.clearRect(0, 0,w, h);
129
- g.fillStyle = "black";
130
- g.fillRect(0, 0, Math.round(this.bounds.dimension.width), Math.round(this.bounds.dimension.height));
131
- }
132
- }
133
- }
134
- this.startRender();
135
- this.drawCursorLayer();
136
- }
137
- startRender() {
138
- if (this.worker) {
139
- this.worker.terminate();
140
- this.worker = null;
141
- }
142
- if (this.raAsSubsc) {
143
- this.raAsSubsc.unsubscribe();
144
- }
145
- if (this._audioDataHolder) {
146
- this._audioDataHolder.addOnReadyListener(() => {
147
- if (this._audioDataHolder && this.bounds && this.bounds.dimension) {
148
- let w = Math.round(this.bounds.dimension.width);
149
- let h = Math.round(this.bounds.dimension.height);
150
- let vw = Math.round(this.virtualDimension.width);
151
- if (w > 0 && h > 0 && vw > 0) {
152
- //this.wo = new Worker('./audiosignal.worker.js',{type: 'module'});
153
- this.worker = new Worker(this.workerURL);
154
- //this.wo = new Worker('worker/audiosignal.worker.ts');
155
- //let Worker = require('worker!../../../workers/uploader/main');
156
- let chs = this._audioDataHolder.numberOfChannels;
157
- let leftPos = Math.round(this.bounds.position.left);
158
- let renderPos = leftPos;
159
- let frameLength = this._audioDataHolder.frameLen;
160
- let framesPerPixel = Math.ceil(frameLength / vw);
161
- //console.debug("Chs: " + chs + ", vw: " + vw + ", frameLength: " + frameLength + ", framesPerPixel: " + framesPerPixel);
162
- let ad = new Float32Array(chs * framesPerPixel);
163
- let raAs = this._audioDataHolder.randomAccessAudioStream();
164
- let audioBuffer = null;
165
- let audioSource = this._audioDataHolder.audioSource;
166
- if (audioSource instanceof AudioBufferSource) {
167
- audioBuffer = audioSource.audioBuffer;
168
- }
169
- //let arrayAudioBuffer=this._audioDataHolder.arrayBuffer;
170
- let arrAbBuf;
171
- //let ais:ArrayAudioBufferInputStream|null=null;
172
- //let aisBuf:Float32Array[]|null=null;
173
- let psMinMax = null;
174
- if (this.worker) {
175
- this.worker.onmessage = (me) => {
176
- if (me.data.eod === true) {
177
- let psMinMaxTmp;
178
- if (psMinMax) {
179
- psMinMaxTmp = psMinMax;
180
- }
181
- else {
182
- psMinMaxTmp = me.data.psMinMax;
183
- }
184
- this.drawRendered(leftPos, w, h, chs, psMinMaxTmp);
185
- if (this.worker) {
186
- this.worker.terminate();
187
- }
188
- raAs.close();
189
- }
190
- else if (this._audioDataHolder && arrAbBuf) {
191
- const rw = me.data.w;
192
- const rPointsLen = chs * rw;
193
- const pointsLen = chs * w;
194
- for (let ch = 0; ch < chs; ch++) {
195
- if (psMinMax) {
196
- let rBasePos = ch * rw;
197
- let basePos = ch * w;
198
- let rPosMin = rBasePos;
199
- let rPosMax = rPointsLen + rPosMin;
200
- let posMin = basePos + (renderPos - leftPos);
201
- let posMax = pointsLen + posMin;
202
- psMinMax[posMin] = me.data.psMinMax[rPosMin];
203
- //console.debug('Min: ('+posMin+'): '+me.data.psMinMax[rPosMin]);
204
- psMinMax[posMax] = me.data.psMinMax[rPosMax];
205
- //console.debug('Max: ('+(posMax)+'): '+me.data.psMinMax[rPosMax]);
206
- //console.debug("psMinMax["+posMin+"]="+me.data.psMinMax[rPosMin]+" (rPosMin="+rPosMin+"),psMinMax["+posMax+"]="+me.data.psMinMax[rPosMax]);
207
- }
208
- }
209
- let eod = false;
210
- renderPos++;
211
- //let ad:Float32Array;
212
- const leftFramePos = Math.floor(frameLength * renderPos / vw);
213
- if (renderPos < leftPos + w) {
214
- const raAsObs = raAs.framesObs(leftFramePos, framesPerPixel, arrAbBuf);
215
- this.raAsSubsc = raAsObs.subscribe({
216
- next: (read) => {
217
- //console.debug("First read frame: "+arrAbBuf[0][0]);
218
- if (arrAbBuf) {
219
- const adLen = chs * framesPerPixel;
220
- if (!ad || ad.length !== adLen) {
221
- ad = new Float32Array(adLen);
222
- }
223
- for (let ch = 0; ch < chs; ch++) {
224
- ad.set(arrAbBuf[ch], ch * framesPerPixel);
225
- }
226
- }
227
- eod = (read <= 0);
228
- let adBuf = ad.buffer;
229
- if (this.worker) {
230
- this.worker.postMessage({
231
- l: renderPos,
232
- w: me.data.w,
233
- h: h,
234
- vw: vw,
235
- chs: chs,
236
- frameLength: frameLength,
237
- audioData: ad,
238
- audioDataOffset: leftFramePos,
239
- eod: eod
240
- }, [adBuf]);
241
- }
242
- },
243
- error: (err) => {
244
- console.error("AudioSignal: Error reading audio data: " + err);
245
- }
246
- });
247
- }
248
- else {
249
- ad = new Float32Array();
250
- eod = true;
251
- const adBuf = ad.buffer;
252
- if (this.worker) {
253
- this.worker.postMessage({
254
- l: renderPos,
255
- w: me.data.w,
256
- h: h,
257
- vw: vw,
258
- chs: chs,
259
- frameLength: frameLength,
260
- audioData: ad,
261
- audioDataOffset: leftFramePos,
262
- eod: eod
263
- }, [adBuf]);
264
- }
265
- }
266
- }
267
- };
268
- }
269
- if (audioBuffer && audioBuffer.length * audioBuffer.numberOfChannels < AudioCanvasLayerComponent.ENABLE_STREAMING_NUMBER_OF_SAMPLES_THRESHOLD) {
270
- // Render whole clip at once
271
- arrAbBuf = null;
272
- psMinMax = null;
273
- const ad = new Float32Array(chs * frameLength);
274
- for (let ch = 0; ch < chs; ch++) {
275
- ad.set(audioBuffer.getChannelData(ch), ch * frameLength);
276
- }
277
- this.worker.postMessage({
278
- l: leftPos,
279
- w: w,
280
- vw: vw,
281
- chs: chs,
282
- frameLength: frameLength,
283
- audioData: ad,
284
- audioDataOffset: 0,
285
- eod: true
286
- }, [ad.buffer]);
287
- }
288
- else {
289
- // Render pixel by pixel
290
- if (w > 0) {
291
- if (framesPerPixel > 0) {
292
- let rw = 1;
293
- arrAbBuf = new Array(chs);
294
- psMinMax = new Float32Array(chs * w * 2);
295
- //console.debug("Audiosignal: Allocating buffers: "+framesPerPixel);
296
- for (let ch = 0; ch < chs; ch++) {
297
- arrAbBuf[ch] = new Float32Array(framesPerPixel);
298
- }
299
- const leftFramePos = Math.floor(frameLength * renderPos / vw);
300
- const auOffset = leftFramePos; // should always be 0
301
- const raAsObs = raAs.framesObs(leftFramePos, framesPerPixel, arrAbBuf);
302
- this.drawStateText("Loading/Rendering...");
303
- this.raAsSubsc = raAsObs.subscribe({
304
- next: (read) => {
305
- if (arrAbBuf && this.worker) {
306
- const adLen = chs * framesPerPixel;
307
- if (!ad || ad.length !== adLen) {
308
- ad = new Float32Array(adLen);
309
- }
310
- for (let ch = 0; ch < chs; ch++) {
311
- ad.set(arrAbBuf[ch], ch * framesPerPixel);
312
- }
313
- this.worker.postMessage({
314
- l: renderPos,
315
- w: rw,
316
- vw: vw,
317
- chs: chs,
318
- frameLength: frameLength,
319
- audioData: ad,
320
- audioDataOffset: auOffset,
321
- eod: (read <= 0)
322
- }, [ad.buffer]);
323
- }
324
- },
325
- error: (err) => {
326
- console.error("AudioSignal: Error reading audio data: " + err);
327
- }
328
- });
329
- }
330
- }
331
- }
332
- }
333
- }
334
- });
335
- }
336
- else {
337
- if (this.bounds && this.bounds.dimension) {
338
- let w = Math.round(this.bounds.dimension.width);
339
- let h = Math.round(this.bounds.dimension.height);
340
- let g = this.signalCanvas.getContext("2d");
341
- if (g) {
342
- g.clearRect(0, 0, w, h);
343
- }
344
- }
345
- }
346
- }
347
- drawStateText(stateText) {
348
- if (stateText) {
349
- const g = this.signalCanvas.getContext("2d");
350
- const w = this.signalCanvas.width;
351
- const h = this.signalCanvas.height;
352
- if (g && w && h) {
353
- g.strokeStyle = 'white';
354
- g.fillStyle = 'white';
355
- g.font = '20px sans-serif';
356
- g.fillText(stateText, 10, 25);
357
- }
358
- }
359
- }
360
- drawRendered(left, w, h, chs, psMinMax) {
361
- this.drawBg();
362
- this.signalCanvas.style.left = left.toString() + 'px';
363
- this.signalCanvas.width = w;
364
- this.signalCanvas.height = h;
365
- let g = this.signalCanvas.getContext("2d");
366
- if (g) {
367
- g.clearRect(0, 0, w, h);
368
- let pointsLen = w * chs;
369
- // one for min one for max
370
- //const arrLen = pointsLen * 2;
371
- if (this._audioDataHolder) {
372
- //const std = Date.now();
373
- const chH = h / chs;
374
- let y = 0;
375
- for (let ch = 0; ch < chs; ch++) {
376
- const psMinPos = ch * w;
377
- const psMaxPos = pointsLen + psMinPos;
378
- g.fillStyle = 'green';
379
- g.strokeStyle = 'green';
380
- // draw audio signal as single polygon
381
- g.beginPath();
382
- g.moveTo(0, y + (chH / 2) + psMinMax[psMaxPos] * chH / 2);
383
- for (let pii = 0; pii < w; pii++) {
384
- const psMax = psMinMax[psMaxPos + pii];
385
- const pv = psMax * chH / 2;
386
- const yd = y + (chH / 2) - pv;
387
- //console.log("LineTo: : "+pii+" "+yd)
388
- g.lineTo(pii, yd);
389
- }
390
- const revPixelStart = w - 1;
391
- for (let pii = revPixelStart; pii >= 0; pii--) {
392
- const psMin = psMinMax[psMinPos + pii];
393
- const pv = psMin * chH / 2;
394
- const yd = y + (chH / 2) - pv;
395
- //console.log("LineTo: : "+pii+" "+yd)
396
- g.lineTo(pii, yd);
397
- }
398
- g.closePath();
399
- g.fill();
400
- g.stroke();
401
- y += chH;
402
- }
403
- }
404
- }
405
- }
406
- // redraw() {
407
- // this.drawBg()
408
- // let g = this.signalCanvas.getContext("2d");
409
- // if (g) {
410
- // let w = this.signalCanvas.width;
411
- // let h = this.signalCanvas.height;
412
- // g.clearRect(0, 0, w, h);
413
- // //g.fillStyle = "black";
414
- // //g.fillRect(0, 0, w, h);
415
- // if (this._audioDataHolder) {
416
- // let std = Date.now();
417
- // let chs = this._audioDataHolder.numberOfChannels;
418
- // let chH = h / chs;
419
- //
420
- // let frameLength = this._audioDataHolder.frameLen;
421
- //
422
- // let framesPerPixel = frameLength / w;
423
- // let y = 0;
424
- // let ais:Float32ArrayInputStream|null=null;
425
- // let audioSource=this._audioDataHolder.audioSource;
426
- // let audioBuffer:AudioBuffer|null=null;
427
- // if(audioSource instanceof AudioBufferSource){
428
- // audioBuffer=audioSource.audioBuffer;
429
- // }
430
- // let aisBuffer:Array<Float32Array>|null=null;
431
- // if(!audioBuffer) {
432
- // ais=this._audioDataHolder.audioInputStream();
433
- // aisBuffer=new Array<Float32Array>(chs);
434
- // for(let ch=0;ch<chs;ch++) {
435
- // aisBuffer[ch] = new Float32Array(framesPerPixel);
436
- // }
437
- // }
438
- // for (let ch = 0; ch < chs; ch++) {
439
- // let x = 0;
440
- // let psMin = new Float32Array(w);
441
- // let psMax = new Float32Array(w);
442
- // let framePos = 0;
443
- // for (let pii = 0; pii < w; pii++) {
444
- // let pMin = 0;
445
- // let pMax = 0;
446
- //
447
- // if (audioBuffer){
448
- // // calculate pixel min/max amplitude
449
- // for (let ai = 0; ai < framesPerPixel; ai++) {
450
- // //let framePos=(pii*framesPerPixel)+ai;
451
- // let a = audioBuffer.getChannelData(ch)[framePos++];
452
- //
453
- // if (a < pMin) {
454
- // pMin = a;
455
- // }
456
- // if (a > pMax) {
457
- // pMax = a;
458
- // }
459
- // }
460
- // }else if(ais && aisBuffer) {
461
- // let r = ais.read(aisBuffer);
462
- // for (let ai = 0; ai < r; ai++) {
463
- //
464
- // let a = aisBuffer[ch][ai];
465
- //
466
- // if (a < pMin) {
467
- // pMin = a;
468
- // }
469
- // if (a > pMax) {
470
- // pMax = a;
471
- // }
472
- // }
473
- // }
474
- // psMin[pii] = pMin;
475
- // psMax[pii] = pMax;
476
- // }
477
- // g.fillStyle = 'green';
478
- // g.strokeStyle = 'green';
479
- //
480
- // // draw audio signal as single polygon
481
- // g.beginPath();
482
- // g.moveTo(0, y + (chH / 2) + psMin[0] * chH / 2);
483
- //
484
- // for (let pii = 0; pii < w; pii++) {
485
- // let pv = psMin[pii] * chH / 2;
486
- // //console.log("Min: ",pv);
487
- // g.lineTo(pii, y + (chH / 2) + pv);
488
- // }
489
- // for (let pii = w; pii >= 0; pii--) {
490
- // let pv = psMax[pii] * chH / 2;
491
- // //console.log("Max: ",pv);
492
- // g.lineTo(pii, y + (chH / 2) + pv);
493
- // }
494
- // g.closePath();
495
- // //g.lineTo()
496
- // g.fill();
497
- // g.stroke();
498
- // g.fillStyle = "yellow";
499
- // g.stroke();
500
- // y += chH;
501
- // }
502
- // ais?.close();
503
- // }
504
- // }
505
- // }
506
- setData(audioData) {
507
- this._audioDataHolder = audioData;
508
- this.playFramePosition = 0;
509
- }
510
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.12", ngImport: i0, type: AudioSignal, deps: [{ token: i0.ElementRef }], target: i0.ɵɵFactoryTarget.Component }); }
511
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.12", type: AudioSignal, selector: "audio-signal", viewQueries: [{ propertyName: "audioSignalCanvasRef", first: true, predicate: ["audioSignal"], descendants: true, static: true }, { propertyName: "playPosCanvasRef", first: true, predicate: ["marker"], descendants: true, static: true }], usesInheritance: true, ngImport: i0, template: `
512
- <canvas #bg height="10"></canvas>
513
- <canvas #audioSignal height="10"></canvas>
514
- <canvas #cursor height="10" (mousedown)="selectionStart($event)" (mouseover)="updateCursorCanvas($event)" (mousemove)="updateCursorCanvas($event)"
515
- (mouseleave)="updateCursorCanvas($event, false)"></canvas>
516
- <canvas #marker height="10"></canvas>`, isInline: true, styles: [":host{min-height:0px}\n", "canvas{top:0;left:0;width:0;height:0;min-height:0px;position:absolute}\n"] }); }
517
- }
518
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.12", ngImport: i0, type: AudioSignal, decorators: [{
519
- type: Component,
520
- args: [{ selector: 'audio-signal', template: `
521
- <canvas #bg height="10"></canvas>
522
- <canvas #audioSignal height="10"></canvas>
523
- <canvas #cursor height="10" (mousedown)="selectionStart($event)" (mouseover)="updateCursorCanvas($event)" (mousemove)="updateCursorCanvas($event)"
524
- (mouseleave)="updateCursorCanvas($event, false)"></canvas>
525
- <canvas #marker height="10"></canvas>`, styles: [":host{min-height:0px}\n", "canvas{top:0;left:0;width:0;height:0;min-height:0px;position:absolute}\n"] }]
526
- }], ctorParameters: () => [{ type: i0.ElementRef }], propDecorators: { audioSignalCanvasRef: [{
527
- type: ViewChild,
528
- args: ['audioSignal', { static: true }]
529
- }], playPosCanvasRef: [{
530
- type: ViewChild,
531
- args: ['marker', { static: true }]
532
- }] } });
533
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYXVkaW9zaWduYWwuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi9wcm9qZWN0cy9zcGVlY2hyZWNvcmRlcm5nL3NyYy9saWIvYXVkaW8vdWkvYXVkaW9zaWduYWwudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFDLFNBQVMsRUFBRSxTQUFTLEVBQWEsTUFBTSxlQUFlLENBQUM7QUFDL0QsT0FBTyxFQUFDLHlCQUF5QixFQUFDLE1BQU0sMkJBQTJCLENBQUM7QUFDcEUsT0FBTyxFQUFDLFlBQVksRUFBQyxNQUFNLG1CQUFtQixDQUFDO0FBQy9DLE9BQU8sRUFBQyxpQkFBaUIsRUFBa0IsTUFBTSxzQkFBc0IsQ0FBQzs7QUEyQnhFLE1BQU0sT0FBTyxXQUFZLFNBQVEseUJBQXlCO0lBaUJ4RCxZQUFvQixHQUFlO1FBQ2pDLEtBQUssRUFBRSxDQUFDO1FBRFUsUUFBRyxHQUFILEdBQUcsQ0FBWTtRQVAzQix1QkFBa0IsR0FBYyxJQUFJLENBQUM7UUFFckMsV0FBTSxHQUFnQixJQUFJLENBQUM7UUFHM0IsY0FBUyxHQUFtQixJQUFJLENBQUM7UUFJdkMsSUFBSSxDQUFDLFNBQVMsR0FBRyxZQUFZLENBQUMsa0JBQWtCLENBQUMsSUFBSSxDQUFDLGNBQWMsQ0FBQyxDQUFBO1FBQ3JFLElBQUksQ0FBQyxnQkFBZ0IsR0FBRyxJQUFJLENBQUM7UUFDN0IsSUFBSSxDQUFDLFFBQVEsR0FBQyxPQUFPLENBQUM7UUFDdEIsSUFBSSxDQUFDLFlBQVksR0FBQyxxQkFBcUIsQ0FBQTtJQUV6QyxDQUFDO0lBRUQsZUFBZTtRQUViLElBQUksQ0FBQyxFQUFFLEdBQUcsSUFBSSxDQUFDLEdBQUcsQ0FBQyxhQUFhLENBQUM7UUFDakMsSUFBSSxDQUFDLFFBQVEsR0FBRyxJQUFJLENBQUMsV0FBVyxDQUFDLGFBQWEsQ0FBQztRQUMvQyxJQUFJLENBQUMsUUFBUSxDQUFDLEtBQUssQ0FBQyxNQUFNLEdBQUcsR0FBRyxD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Qiw2REFBNkQ7SUFDN0QsRUFBRTtJQUNGLGdEQUFnRDtJQUNoRCw2Q0FBNkM7SUFDN0MseUNBQXlDO0lBQ3pDLGlEQUFpRDtJQUNqRCxjQUFjO0lBQ2QsaURBQWlEO0lBQ2pELDZDQUE2QztJQUM3Qyx5Q0FBeUM7SUFDekMsaURBQWlEO0lBQ2pELGNBQWM7SUFDZCwyQkFBMkI7SUFDM0IseUJBQXlCO0lBQ3pCLHNCQUFzQjtJQUN0Qix3QkFBd0I7SUFDeEIsb0NBQW9DO0lBQ3BDLHdCQUF3QjtJQUN4QixzQkFBc0I7SUFDdEIsWUFBWTtJQUNaLHNCQUFzQjtJQUN0QixRQUFRO0lBQ1IsTUFBTTtJQUNOLElBQUk7SUFFSixPQUFPLENBQUMsU0FBaUM7UUFDdkMsSUFBSSxDQUFDLGdCQUFnQixHQUFHLFNBQVMsQ0FBQztRQUNsQyxJQUFJLENBQUMsaUJBQWlCLEdBQUcsQ0FBQyxDQUFDO0lBQzdCLENBQUM7K0dBOWpCVSxXQUFXO21HQUFYLFdBQVcseVRBbkJaOzs7OzswQ0FLOEI7OzRGQWM3QixXQUFXO2tCQXRCdkIsU0FBUzsrQkFFRSxjQUFjLFlBQ2Q7Ozs7OzBDQUs4QjsrRUFrQkksb0JBQW9CO3NCQUEvRCxTQUFTO3VCQUFDLGFBQWEsRUFBRSxFQUFFLE1BQU0sRUFBRSxJQUFJLEVBQUU7Z0JBQ0gsZ0JBQWdCO3NCQUF0RCxTQUFTO3VCQUFDLFFBQVEsRUFBRSxFQUFFLE1BQU0sRUFBRSxJQUFJLEVBQUUiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQge0NvbXBvbmVudCwgVmlld0NoaWxkLCBFbGVtZW50UmVmfSBmcm9tICdAYW5ndWxhci9jb3JlJztcclxuaW1wb3J0IHtBdWRpb0NhbnZhc0xheWVyQ29tcG9uZW50fSBmcm9tIFwiLi9hdWRpb19jYW52YXNfbGF5ZXJfY29tcFwiO1xyXG5pbXBvcnQge1dvcmtlckhlbHBlcn0gZnJvbSBcIi4uLy4uL3V0aWxzL3V0aWxzXCI7XHJcbmltcG9ydCB7QXVkaW9CdWZmZXJTb3VyY2UsIEF1ZGlvRGF0YUhvbGRlcn0gZnJvbSBcIi4uL2F1ZGlvX2RhdGFfaG9sZGVyXCI7XHJcbmltcG9ydCB7U3Vic2NyaXB0aW9ufSBmcm9tIFwicnhqc1wiO1xyXG5cclxuZGVjbGFyZSBmdW5jdGlvbiBwb3N0TWVzc2FnZShtZXNzYWdlOiBhbnksIHRyYW5zZmVyOiBBcnJheTxhbnk+KTogdm9pZDtcclxuXHJcbkBDb21wb25lbnQoe1xyXG5cclxuICBzZWxlY3RvcjogJ2F1ZGlvLXNpZ25hbCcsXHJcbiAgdGVtcGxhdGU6IGBcclxuICAgIDxjYW52YXMgI2JnIGhlaWdodD1cIjEwXCI+PC9jYW52YXM+XHJcbiAgICA8Y2FudmFzICNhdWRpb1NpZ25hbCBoZWlnaHQ9XCIxMFwiPjwvY2FudmFzPlxyXG4gICAgPGNhbnZhcyAjY3Vyc29yIGhlaWdodD1cIjEwXCIgKG1vdXNlZG93bik9XCJzZWxlY3Rpb25TdGFydCgkZXZlbnQpXCIgKG1vdXNlb3Zlcik9XCJ1cGRhdGVDdXJzb3JDYW52YXMoJGV2ZW50KVwiIChtb3VzZW1vdmUpPVwidXBkYXRlQ3Vyc29yQ2FudmFzKCRldmVudClcIlxyXG4gICAgICAgICAgICAobW91c2VsZWF2ZSk9XCJ1cGRhdGVDdXJzb3JDYW52YXMoJGV2ZW50LCBmYWxzZSlcIj48L2NhbnZhcz5cclxuICAgIDxjYW52YXMgI21hcmtlciBoZWlnaHQ9XCIxMFwiPjwvY2FudmFzPmAsXHJcblxyXG4gIHN0eWxlczogW2A6aG9zdHtcclxuICAgICAgbWluLWhlaWdodDogMHB4O1xyXG4gICAgfWAsYGNhbnZhcyB7XHJcbiAgICB0b3A6IDA7XHJcbiAgICBsZWZ0OiAwO1xyXG4gICAgd2lkdGg6IDA7XHJcbiAgICBoZWlnaHQ6IDA7XHJcbiAgICBtaW4taGVpZ2h0OiAwcHg7XHJcbiAgICBwb3NpdGlvbjogYWJzb2x1dGU7XHJcbiAgfWBdXHJcblxyXG59KVxyXG5leHBvcnQgY2xhc3MgQXVkaW9TaWduYWwgZXh0ZW5kcyBBdWRpb0NhbnZhc0xheWVyQ29tcG9uZW50e1xyXG5cclxuICBuOiBhbnk7XHJcbiAgY2UhOiBIVE1MRGl2RWxlbWVudDtcclxuICBAVmlld0NoaWxkKCdhdWRpb1NpZ25hbCcsIHsgc3RhdGljOiB0cnVlIH0pIGF1ZGlvU2lnbmFsQ2FudmFzUmVmITogRWxlbWVudFJlZjtcclxuICBAVmlld0NoaWxkKCdtYXJrZXInLCB7IHN0YXRpYzogdHJ1ZSB9KSBwbGF5UG9zQ2FudmFzUmVmITogRWxlbWVudFJlZjtcclxuICBzaWduYWxDYW52YXMhOiBIVE1MQ2FudmFzRWxlbWVudDtcclxuXHJcbiAgbWFya2VyQ2FudmFzITogSFRNTENhbnZhc0VsZW1lbnQ7XHJcblxyXG4gIHByaXZhdGUgX3BsYXlGcmFtZVBvc2l0aW9uOiBudW1iZXJ8bnVsbD1udWxsO1xyXG5cclxuICBwcml2YXRlIHdvcmtlcjogV29ya2VyIHwgbnVsbD1udWxsO1xyXG4gIHByaXZhdGUgcmVhZG9ubHkgd29ya2VyVVJMOiBzdHJpbmc7XHJcblxyXG4gIHByaXZhdGUgcmFBc1N1YnNjOlN1YnNjcmlwdGlvbnxudWxsPW51bGw7XHJcblxyXG4gIGNvbnN0cnVjdG9yKHByaXZhdGUgcmVmOiBFbGVtZW50UmVmKSB7XHJcbiAgICBzdXBlcigpO1xyXG4gICAgdGhpcy53b3JrZXJVUkwgPSBXb3JrZXJIZWxwZXIuYnVpbGRXb3JrZXJCbG9iVVJMKHRoaXMud29ya2VyRnVuY3Rpb24pXHJcbiAgICB0aGlzLl9hdWRpb0RhdGFIb2xkZXIgPSBudWxsO1xyXG4gICAgdGhpcy5fYmdDb2xvcj0nYmxhY2snO1xyXG4gICAgdGhpcy5fc2VsZWN0Q29sb3I9J3JnYmEoMjU1LDI1NSwwLDAuOCknXHJcblxyXG4gIH1cclxuXHJcbiAgbmdBZnRlclZpZXdJbml0KCkge1xyXG5cclxuICAgIHRoaXMuY2UgPSB0aGlzLnJlZi5uYXRpdmVFbGVtZW50O1xyXG4gICAgdGhpcy5iZ0NhbnZhcyA9IHRoaXMuYmdDYW52YXNSZWYubmF0aXZlRWxlbWVudDtcclxuICAgIHRoaXMuYmdDYW52YXMuc3R5bGUuekluZGV4ID0gJzEnO1xyXG4gICAgdGhpcy5zaWduYWxDYW52YXMgPSB0aGlzLmF1ZGlvU2lnbmFsQ2FudmFzUmVmLm5hdGl2ZUVsZW1lbnQ7XHJcbiAgICB0aGlzLnNpZ25hbENhbnZhcy5zdHlsZS56SW5kZXggPSAnMic7XHJcbiAgICB0aGlzLm1hcmtlckNhbnZhcyA9IHRoaXMucGxheVBvc0NhbnZhc1JlZi5uYXRpdmVFbGVtZW50O1xyXG4gICAgdGhpcy5tYXJrZXJDYW52YXMuc3R5bGUuekluZGV4ID0gJzMnO1xyXG4gICAgdGhpcy5jdXJzb3JDYW52YXMgPSB0aGlzLmN1cnNvckNhbnZhc1JlZi5uYXRpdmVFbGVtZW50O1xyXG4gICAgdGhpcy5jdXJzb3JDYW52YXMuc3R5bGUuekluZGV4ID0gJzQnO1xyXG5cclxuICAgIHRoaXMuY2FudmFzTGF5ZXJzWzBdPXRoaXMuYmdDYW52YXM7XHJcbiAgICB0aGlzLmNhbnZhc0xheWVyc1sxXT10aGlzLnNpZ25hbENhbnZhcztcclxuICAgIHRoaXMuY2FudmFzTGF5ZXJzWzJdPXRoaXMuY3Vyc29yQ2FudmFzO1xyXG4gICAgdGhpcy5jYW52YXNMYXllcnNbM109dGhpcy5tYXJrZXJDYW52YXM7XHJcblxyXG4gIH1cclxuXHJcbiAgZ2V0IHBsYXlGcmFtZVBvc2l0aW9uKCk6IG51bWJlciB8bnVsbHtcclxuICAgIHJldHVybiB0aGlzLl9wbGF5RnJhbWVQb3NpdGlvbjtcclxuICB9XHJcblxyXG4gIHNldCBwbGF5RnJhbWVQb3NpdGlvbihwbGF5RnJhbWVQb3NpdGlvbjogbnVtYmVyfG51bGwpIHtcclxuICAgIHRoaXMuX3BsYXlGcmFtZVBvc2l0aW9uID0gcGxheUZyYW1lUG9zaXRpb247XHJcbiAgICB0aGlzLmRyYXdQbGF5UG9zaXRpb24oKTtcclxuICB9XHJcblxyXG5cclxuXHJcbiAgZHJhd1BsYXlQb3NpdGlvbigpIHtcclxuICAgIGlmICh0aGlzLm1hcmtlckNhbnZhcykge1xyXG4gICAgICBsZXQgdyA9IHRoaXMubWFya2VyQ2FudmFzLndpZHRoO1xyXG4gICAgICBsZXQgaCA9IHRoaXMubWFya2VyQ2FudmFzLmhlaWdodDtcclxuICAgICAgbGV0IGcgPSB0aGlzLm1hcmtlckNhbnZhcy5nZXRDb250ZXh0KFwiMmRcIik7XHJcbiAgICAgIGlmIChnKSB7XHJcbiAgICAgICAgZy5jbGVhclJlY3QoMCwgMCwgdywgaCk7XHJcbiAgICAgICAgaWYodGhpcy5fcGxheUZyYW1lUG9zaXRpb24pIHtcclxuICAgICAgICAgIGxldCBwaXhlbFBvcyA9IHRoaXMuZnJhbWVUb1ZpZXdQb3J0WFBpeGVsUG9zaXRpb24odGhpcy5fcGxheUZyYW1lUG9zaXRpb24pO1xyXG4gICAgICAgICAgaWYgKHBpeGVsUG9zKSB7XHJcbiAgICAgICAgICAgIGcuZmlsbFN0eWxlID0gJ3JlZCc7XHJcbiAgICAgICAgICAgIGcuc3Ryb2tlU3R5bGUgPSAncmVkJztcclxuICAgICAgICAgICAgZy5iZWdpblBhdGgoKTtcclxuICAgICAgICAgICAgZy5tb3ZlVG8ocGl4ZWxQb3MsIDApO1xyXG4gICAgICAgICAgICBnLmxpbmVUbyhwaXhlbFBvcywgaCk7XHJcbiAgICAgICAgICAgIGcuY2xvc2VQYXRoKCk7XHJcbiAgICAgICAgICAgIGcuc3Ryb2tlKCk7XHJcbiAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG4gICAgICB9XHJcbiAgICB9XHJcbiAgfVxyXG5cclxuICAvKlxyXG4gICAqICBNZXRob2QgdXNlZCBhcyB3b3JrZXIgY29kZS5cclxuICAgKi9cclxuICB3b3JrZXJGdW5jdGlvbigpIHtcclxuICAgIGFkZEV2ZW50TGlzdGVuZXIoJ21lc3NhZ2UnLCAoeyBkYXRhIH0pID0+IHtcclxuXHJcbiAgICAgIGNvbnN0IGF1ZGlvRGF0YSA9IGRhdGEuYXVkaW9EYXRhOyAvLyBhdWRpbyBkYXRhIHBhcnQgcmVxdWlyZWQgdG8gcmVuZGVyIHZpZXcgcG9ydFxyXG4gICAgICBjb25zdCBhdU9mZnNldDpudW1iZXI9ZGF0YS5hdWRpb0RhdGFPZmZzZXQ7XHJcbiAgICAgIGNvbnN0IGw9IGRhdGEubDsgLy8gbGVmdCBwaXhlbCBwb3NpdGlvbiBvZiB2aWV3IHBvcnRcclxuICAgICAgY29uc3QgdyA9IGRhdGEudzsgIC8vIHdpZHRoIG9mIHZpZXdwb3J0XHJcbiAgICAgIGNvbnN0IHZ3ID0gZGF0YS52dzsgLy8gIHRvdGFsIHdpZHRoIG9mICh2aXJ0dWFsKSBhdWRpbyB2aWV3IChub3Qgdmlld3BvcnQgd2lkdGgpXHJcbiAgICAgIGNvbnN0IGNocyA9IGRhdGEuY2hzOyAvLyBudW1iZXIgb2YgY2hhbm5lbHNcclxuICAgICAgLy9jb25zdCBkYXRhRnJhbWVMZW5ndGggPSBkYXRhLmF1ZGlvRGF0YUZyYW1lTGVuZ3RoOyAgLy8gZnJhbWUgbGVuZ3RoIG9mIGF1ZGlvIGRhdGEgcGFydCByZXF1aXJlZCBmb3IgdmlldyBwb3J0XHJcbiAgICAgIGNvbnN0IGZyYW1lTGVuZ3RoID0gZGF0YS5mcmFtZUxlbmd0aDsgIC8vIHRvdGFsIGZyYW1lIGxlbmd0aCAob2YgYXVkaW8gY2xpcClcclxuXHJcbiAgICAgIC8vY29uc29sZS5kZWJ1ZyhcIlc6IGxlZnQ6IFwiK2wrXCIsIHc6XCIrdytcIiwgdnc6IFwiK3Z3K1wiLCBjaHM6IFwiK2NocytcIiwgZnJhbWVMZW5ndGg6IFwiK2ZyYW1lTGVuZ3RoKTtcclxuXHJcbiAgICAgIGxldCBwc01pbk1heD0gbmV3IEZsb2F0MzJBcnJheSgwKTtcclxuXHJcbiAgICAgIGlmKGF1ZGlvRGF0YSAmJiBhdWRpb0RhdGEubGVuZ3RoPjAgJiYgdz49MCAmJiB2dz4wKSB7XHJcblxyXG4gICAgICAgIGNvbnN0IGZyYW1lc1BlclBpeGVsID0gZnJhbWVMZW5ndGggLyB2dztcclxuXHJcbiAgICAgICAgY29uc3QgcG9pbnRzTGVuID0gdyAqIGNocztcclxuICAgICAgICAvLyBvbmUgZm9yIG1pbiBvbmUgZm9yIG1heFxyXG4gICAgICAgIGNvbnN0IGFyckxlbiA9IHBvaW50c0xlbiAqIDI7XHJcbiAgICAgICAgcHNNaW5NYXggPSBuZXcgRmxvYXQzMkFycmF5KGFyckxlbik7XHJcbiAgICAgICAgbGV0IGNoRnJhbWVQb3MgPSAwO1xyXG4gICAgICAgIGNvbnN0IGNoRnJhbWVMZW5ndGg9YXVkaW9EYXRhLmxlbmd0aC9jaHM7XHJcbiAgICAgICAgZm9yIChsZXQgY2ggPSAwOyBjaCA8IGNoczsgY2grKykge1xyXG5cclxuICAgICAgICAgIGNoRnJhbWVQb3MgPSBjaCAqIGNoRnJhbWVMZW5ndGg7XHJcbiAgICAgICAgICBmb3IgKGxldCBwaWkgPSAwOyBwaWkgPCB3OyBwaWkrKykge1xyXG4gICAgICAgICAgICBjb25zdCB2aXJ0UGlpPWwrcGlpO1xyXG4gICAgICAgICAgICBsZXQgcE1pbiA9IEluZmluaXR5O1xyXG4gICAgICAgICAgICBsZXQgcE1heCA9IC1JbmZpbml0eTtcclxuICAgICAgICAgICAgbGV0IHBpeGVsRnJhbWVQb3MgPSBNYXRoLnJvdW5kKGNoRnJhbWVQb3MgKyAodmlydFBpaSAqIGZyYW1lc1BlclBpeGVsKSk7XHJcblxyXG4gICAgICAgICAgICAvLyBjYWxjdWxhdGUgcGl4ZWwgbWluL21heCBhbXBsaXR1ZGVcclxuICAgICAgICAgICAgZm9yIChsZXQgYWkgPSAwOyBhaSA8IGZyYW1lc1BlclBpeGVsOyBhaSsrKSB7XHJcbiAgICAgICAgICAgICAgY29uc3QgZnJhbWVQb3MgPSBwaXhlbEZyYW1lUG9zICsgYWk7XHJcbiAgICAgICAgICAgICAgbGV0IGEgPSAwO1xyXG4gICAgICAgICAgICAgIGNvbnN0IGJ1ZlBvcz1mcmFtZVBvcy1hdU9mZnNldDtcclxuICAgICAgICAgICAgICAvL2xldCBidWZQb3M9ZnJhbWVQb3M7XHJcbiAgICAgICAgICAgICAgaWYoYnVmUG9zPj0wICYmIGJ1ZlBvczxhdWRpb0RhdGEubGVuZ3RoKXtcclxuICAgICAgICAgICAgICAgIGE9YXVkaW9EYXRhW2J1ZlBvc107XHJcbiAgICAgICAgICAgICAgICAvL2NvbnNvbGUuZGVidWcoXCJXOiBjaDogXCIrY2grXCIsIHBpeGVsRnJhbWVQb3M6IFwiK3BpeGVsRnJhbWVQb3MrXCIsIGZyYW1lUG9zOiBcIitmcmFtZVBvcytcIiwgYXVPZmZzZXQ6IFwiK2F1T2Zmc2V0K1wiLCBidWZQb3M6IFwiK2J1ZlBvcytcIiwgYXVkaW9EYXRhLmxlbmd0aDogXCIrYXVkaW9EYXRhLmxlbmd0aCtcIiwgYTogXCIrYSk7XHJcbiAgICAgICAgICAgICAgICBpZiAoYSA8IHBNaW4pIHtcclxuICAgICAgICAgICAgICAgICAgcE1pbiA9IGE7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICBpZiAoYSA+IHBNYXgpIHtcclxuICAgICAgICAgICAgICAgICAgcE1heCA9IGE7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICBjb25zdCBwc01pblBvcyA9IGNoICogdyArIHBpaTtcclxuICAgICAgICAgICAgcHNNaW5NYXhbcHNNaW5Qb3NdID0gcE1pbjtcclxuICAgICAgICAgICAgY29uc3QgcHNNYXhQb3MgPSBwb2ludHNMZW4gKyBwc01pblBvcztcclxuICAgICAgICAgICAgcHNNaW5NYXhbcHNNYXhQb3NdID0gcE1heDtcclxuICAgICAgICAgICAgLy9jb25zb2xlLmRlYnVnKFwicHNNaW5NYXhbXCIrcHNNaW5Qb3MrXCJdPVwiK3BNaW4rXCIscHNNaW5NYXhbXCIrcHNNYXhQb3MrXCJdPVwiK3BNYXgpO1xyXG5cclxuICAgICAgICAgIH1cclxuICAgICAgICB9XHJcbiAgICAgIH1cclxuICAgICAgcG9zdE1lc3NhZ2Uoe3BzTWluTWF4OiBwc01pbk1heCwgbDpkYXRhLmwsdzogZGF0YS53LCBjaHM6IGRhdGEuY2hzLGVvZDpkYXRhLmVvZH0sIFtwc01pbk1heC5idWZmZXJdKTtcclxuICAgIH0pXHJcbiAgfVxyXG5cclxuXHJcblxyXG4gIHN0YXJ0RHJhdyhjbGVhciA9IHRydWUpIHtcclxuICAgIGlmIChjbGVhcikge1xyXG4gICAgICBpZih0aGlzLmJvdW5kcykge1xyXG4gICAgICAgIHRoaXMuc2lnbmFsQ2FudmFzLnN0eWxlLmxlZnQgPSBNYXRoLnJvdW5kKHRoaXMuYm91bmRzLnBvc2l0aW9uLmxlZnQpLnRvU3RyaW5nKCkgKyAncHgnO1xyXG4gICAgICAgIHRoaXMuc2lnbmFsQ2FudmFzLndpZHRoID0gTWF0aC5yb3VuZCh0aGlzLmJvdW5kcy5kaW1lbnNpb24ud2lkdGgpO1xyXG4gICAgICAgIHRoaXMuc2lnbmFsQ2FudmFzLmhlaWdodCA9IE1hdGgucm91bmQodGhpcy5ib3VuZHMuZGltZW5zaW9uLmhlaWdodCk7XHJcblxyXG4gICAgICAgIGxldCBnID0gdGhpcy5zaWduYWxDYW52YXMuZ2V0Q29udGV4dChcIjJkXCIpO1xyXG4gICAgICAgIGlmIChnKSB7XHJcbiAgICAgICAgICAvL2cuY2xlYXJSZWN0KDAsIDAsdywgaCk7XHJcbiAgICAgICAgICBnLmZpbGxTdHlsZSA9IFwiYmxhY2tcIjtcclxuICAgICAgICAgIGcuZmlsbFJlY3QoMCwgMCwgTWF0aC5yb3VuZCh0aGlzLmJvdW5kcy5kaW1lbnNpb24ud2lkdGgpLCBNYXRoLnJvdW5kKHRoaXMuYm91bmRzLmRpbWVuc2lvbi5oZWlnaHQpKTtcclxuICAgICAgICB9XHJcbiAgICAgIH1cclxuICAgIH1cclxuICAgIHRoaXMuc3RhcnRSZW5kZXIoKTtcclxuICAgIHRoaXMuZHJhd0N1cnNvckxheWVyKClcclxuICB9XHJcblxyXG5cclxuICBwcml2YXRlIHN0YXJ0UmVuZGVyKCkge1xyXG5cclxuICAgIGlmICh0aGlzLndvcmtlcikge1xyXG4gICAgICB0aGlzLndvcmtlci50ZXJtaW5hdGUoKTtcclxuICAgICAgdGhpcy53b3JrZXIgPSBudWxsO1xyXG4gICAgfVxyXG4gICAgaWYodGhpcy5yYUFzU3Vic2Mpe1xyXG4gICAgICB0aGlzLnJhQXNTdWJzYy51bnN1YnNjcmliZSgpO1xyXG4gICAgfVxyXG4gICAgICBpZiAodGhpcy5fYXVkaW9EYXRhSG9sZGVyKSB7XHJcbiAgICAgICAgdGhpcy5fYXVkaW9EYXRhSG9sZGVyLmFkZE9uUmVhZHlMaXN0ZW5lcigoKT0+e1xyXG4gICAgICAgICAgaWYodGhpcy5fYXVkaW9EYXRhSG9sZGVyICYmIHRoaXMuYm91bmRzICYmIHRoaXMuYm91bmRzLmRpbWVuc2lvbikge1xyXG4gICAgICAgICAgICBsZXQgdyA9IE1hdGgucm91bmQodGhpcy5ib3VuZHMuZGltZW5zaW9uLndpZHRoKTtcclxuICAgICAgICAgICAgbGV0IGggPSBNYXRoLnJvdW5kKHRoaXMuYm91bmRzLmRpbWVuc2lvbi5oZWlnaHQpO1xyXG4gICAgICAgICAgICBsZXQgdncgPSBNYXRoLnJvdW5kKHRoaXMudmlydHVhbERpbWVuc2lvbi53aWR0aCk7XHJcblxyXG4gICAgICAgICAgICBpZiAodyA+IDAgJiYgaCA+IDAgJiYgdncgPiAwKSB7XHJcblxyXG4gICAgICAgICAgICAgIC8vdGhpcy53byA9IG5ldyBXb3JrZXIoJy4vYXVkaW9zaWduYWwud29ya2VyLmpzJyx7dHlwZTogJ21vZHVsZSd9KTtcclxuICAgICAgICAgICAgICB0aGlzLndvcmtlciA9IG5ldyBXb3JrZXIodGhpcy53b3JrZXJVUkwpO1xyXG4gICAgICAgICAgICAgIC8vdGhpcy53byA9IG5ldyBXb3JrZXIoJ3dvcmtlci9hdWRpb3NpZ25hbC53b3JrZXIudHMnKTtcclxuXHJcbiAgICAgICAgICAgICAgLy9sZXQgV29ya2VyID0gcmVxdWlyZSgnd29ya2VyIS4uLy4uLy4uL3dvcmtlcnMvdXBsb2FkZXIvbWFpbicpO1xyXG4gICAgICAgICAgICAgIGxldCBjaHMgPSB0aGlzLl9hdWRpb0RhdGFIb2xkZXIubnVtYmVyT2ZDaGFubmVscztcclxuICAgICAgICAgICAgICBsZXQgbGVmdFBvcyA9IE1hdGgucm91bmQodGhpcy5ib3VuZHMucG9zaXRpb24ubGVmdCk7XHJcbiAgICAgICAgICAgICAgbGV0IHJlbmRlclBvcyA9IGxlZnRQb3M7XHJcblxyXG4gICAgICAgICAgICAgIGxldCBmcmFtZUxlbmd0aCA9IHRoaXMuX2F1ZGlvRGF0YUhvbGRlci5mcmFtZUxlbjtcclxuICAgICAgICAgICAgICBsZXQgZnJhbWVzUGVyUGl4ZWwgPSBNYXRoLmNlaWwoZnJhbWVMZW5ndGggLyB2dyk7XHJcbiAgICAgICAgICAgICAgLy9jb25zb2xlLmRlYnVnKFwiQ2hzOiBcIiArIGNocyArIFwiLCB2dzogXCIgKyB2dyArIFwiLCBmcmFtZUxlbmd0aDogXCIgKyBmcmFtZUxlbmd0aCArIFwiLCBmcmFtZXNQZXJQaXhlbDogXCIgKyBmcmFtZXNQZXJQaXhlbCk7XHJcbiAgICAgICAgICAgICAgbGV0IGFkOiBGbG9hdDMyQXJyYXkgPSBuZXcgRmxvYXQzMkFycmF5KGNocyAqIGZyYW1lc1BlclBpeGVsKTtcclxuICAgICAgICAgICAgICBsZXQgcmFBcyA9IHRoaXMuX2F1ZGlvRGF0YUhvbGRlci5yYW5kb21BY2Nlc3NBdWRpb1N0cmVhbSgpO1xyXG4gICAgICAgICAgICAgIGxldCBhdWRpb0J1ZmZlcjogQXVkaW9CdWZmZXIgfCBudWxsID0gbnVsbDtcclxuICAgICAgICAgICAgICBsZXQgYXVkaW9Tb3VyY2UgPSB0aGlzLl9hdWRpb0RhdGFIb2xkZXIuYXVkaW9Tb3VyY2U7XHJcbiAgICAgICAgICAgICAgaWYgKGF1ZGlvU291cmNlIGluc3RhbmNlb2YgQXVkaW9CdWZmZXJTb3VyY2UpIHtcclxuICAgICAgICAgICAgICAgIGF1ZGlvQnVmZmVyID0gYXVkaW9Tb3VyY2UuYXVkaW9CdWZmZXI7XHJcbiAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgIC8vbGV0IGFycmF5QXVkaW9CdWZmZXI9dGhpcy5fYXVkaW9EYXRhSG9sZGVyLmFycmF5QnVmZmVyO1xyXG4gICAgICAgICAgICAgIGxldCBhcnJBYkJ1ZjogRmxvYXQzMkFycmF5W10gfCBudWxsO1xyXG5cclxuICAgICAgICAgICAgICAvL2xldCBhaXM6QXJyYXlBdWRpb0J1ZmZlcklucHV0U3RyZWFtfG51bGw9bnVsbDtcclxuICAgICAgICAgICAgICAvL2xldCBhaXNCdWY6RmxvYXQzMkFycmF5W118bnVsbD1udWxsO1xyXG4gICAgICAgICAgICAgIGxldCBwc01pbk1heDogRmxvYXQzMkFycmF5IHwgbnVsbCA9IG51bGw7XHJcblxyXG4gICAgICAgICAgICAgIGlmICh0aGlzLndvcmtlcikge1xyXG4gICAgICAgICAgICAgICAgdGhpcy53b3JrZXIub25tZXNzYWdlID0gKG1lKSA9PiB7XHJcbiAgICAgICAgICAgICAgICAgIGlmIChtZS5kYXRhLmVvZCA9PT0gdHJ1ZSkge1xyXG4gICAgICAgICAgICAgICAgICAgIGxldCBwc01pbk1heFRtcDtcclxuICAgICAgICAgICAgICAgICAgICBpZiAocHNNaW5NYXgpIHtcclxuICAgICAgICAgICAgICAgICAgICAgIHBzTWluTWF4VG1wID0gcHNNaW5NYXg7XHJcbiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgICAgICAgICAgIHBzTWluTWF4VG1wID0gbWUuZGF0YS5wc01pbk1heDtcclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5kcmF3UmVuZGVyZWQobGVmdFBvcywgdywgaCwgY2hzLCBwc01pbk1heFRtcCk7XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKHRoaXMud29ya2VyKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICB0aGlzLndvcmtlci50ZXJtaW5hdGUoKTtcclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgcmFBcy5jbG9zZSgpO1xyXG4gICAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKHRoaXMuX2F1ZGlvRGF0YUhvbGRlciAmJiBhcnJBYkJ1Zikge1xyXG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IHJ3ID0gbWUuZGF0YS53O1xyXG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IHJQb2ludHNMZW4gPSBjaHMgKiBydztcclxuICAgICAgICAgICAgICAgICAgICBjb25zdCBwb2ludHNMZW4gPSBjaHMgKiB3O1xyXG4gICAgICAgICAgICAgICAgICAgIGZvciAobGV0IGNoID0gMDsgY2ggPCBjaHM7IGNoKyspIHtcclxuICAgICAgICAgICAgICAgICAgICAgIGlmIChwc01pbk1heCkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBsZXQgckJhc2VQb3MgPSBjaCAqIHJ3O1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBsZXQgYmFzZVBvcyA9IGNoICogdztcclxuICAgICAgICAgICAgICAgICAgICAgICAgbGV0IHJQb3NNaW4gPSByQmFzZVBvcztcclxuICAgICAgICAgICAgICAgICAgICAgICAgbGV0IHJQb3NNYXggPSByUG9pbnRzTGVuICsgclBvc01pbjtcclxuICAgICAgICAgICAgICAgICAgICAgICAgbGV0IHBvc01pbiA9IGJhc2VQb3MgKyAocmVuZGVyUG9zIC0gbGVmdFBvcyk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGxldCBwb3NNYXggPSBwb2ludHNMZW4gKyBwb3NNaW47XHJcblxyXG4gICAgICAgICAgICAgICAgICAgICAgICBwc01pbk1heFtwb3NNaW5dID0gbWUuZGF0YS5wc01pbk1heFtyUG9zTWluXTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgLy9jb25zb2xlLmRlYnVnKCdNaW46ICgnK3Bvc01pbisnKTogJyttZS5kYXRhLnBzTWluTWF4W3JQb3NNaW5dKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgcHNNaW5NYXhbcG9zTWF4XSA9IG1lLmRhdGEucHNNaW5NYXhbclBvc01heF07XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIC8vY29uc29sZS5kZWJ1ZygnTWF4OiAoJysocG9zTWF4KSsnKTogJyttZS5kYXRhLnBzTWluTWF4W3JQb3NNYXhdKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgLy9jb25zb2xlLmRlYnVnKFwicHNNaW5NYXhbXCIrcG9zTWluK1wiXT1cIittZS5kYXRhLnBzTWluTWF4W3JQb3NNaW5dK1wiICAoclBvc01pbj1cIityUG9zTWluK1wiKSxwc01pbk1heFtcIitwb3NNYXgrXCJdPVwiK21lLmRhdGEucHNNaW5NYXhbclBvc01heF0pO1xyXG4gICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICBsZXQgZW9kID0gZmFsc2U7XHJcbiAgICAgICAgICAgICAgICAgICAgcmVuZGVyUG9zKys7XHJcbiAgICAgICAgICAgICAgICAgICAgLy9sZXQgYWQ6RmxvYXQzMkFycmF5O1xyXG5cclxuICAgICAgICAgICAgICAgICAgICBjb25zdCBsZWZ0RnJhbWVQb3MgPSBNYXRoLmZsb29yKGZyYW1lTGVuZ3RoICogcmVuZGVyUG9zIC8gdncpO1xyXG4gICAgICAgICAgICAgICAgICAgIGlmIChyZW5kZXJQb3MgPCBsZWZ0UG9zICsgdykge1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHJhQXNPYnMgPSByYUFzLmZyYW1lc09icyhsZWZ0RnJhbWVQb3MsIGZyYW1lc1BlclBpeGVsLCBhcnJBYkJ1ZilcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICB0aGlzLnJhQXNTdWJzYyA9IHJhQXNPYnMuc3Vic2NyaWJlKFxyXG4gICAgICAgICAgICAgICAgICAgICAgICB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgbmV4dDogKHJlYWQpID0+IHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vY29uc29sZS5kZWJ1ZyhcIkZpcnN0IHJlYWQgZnJhbWU6IFwiK2FyckFiQnVmWzBdWzBdKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChhcnJBYkJ1Zikge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBhZExlbiA9IGNocyAqIGZyYW1lc1BlclBpeGVsO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoIWFkIHx8IGFkLmxlbmd0aCAhPT0gYWRMZW4pIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhZCA9IG5ldyBGbG9hdDMyQXJyYXkoYWRMZW4pO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZvciAobGV0IGNoID0gMDsgY2ggPCBjaHM7IGNoKyspIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhZC5zZXQoYXJyQWJCdWZbY2hdLCBjaCAqIGZyYW1lc1BlclBpeGVsKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgZW9kID0gKHJlYWQgPD0gMCk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBsZXQgYWRCdWYgPSBhZC5idWZmZXI7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAodGhpcy53b3JrZXIpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy53b3JrZXIucG9zdE1lc3NhZ2Uoe1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGw6IHJlbmRlclBvcyxcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB3OiBtZS5kYXRhLncsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaDogaCxcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2dzogdncsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2hzOiBjaHMsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZnJhbWVMZW5ndGg6IGZyYW1lTGVuZ3RoLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGF1ZGlvRGF0YTogYWQsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYXVkaW9EYXRhT2Zmc2V0OiBsZWZ0RnJhbWVQb3MsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZW9kOiBlb2RcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfSwgW2FkQnVmXSk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgfSxcclxuICAgICAgICAgICAgICAgICAgICAgICAgICBlcnJvcjogKGVycikgPT4ge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc29sZS5lcnJvcihcIkF1ZGlvU2lnbmFsOiBFcnJvciByZWFkaW5nIGF1ZGlvIGRhdGE6IFwiICsgZXJyKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICAgIClcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgICAgICAgICAgIGFkID0gbmV3IEZsb2F0MzJBcnJheSgpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgZW9kID0gdHJ1ZTtcclxuICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGFkQnVmID0gYWQuYnVmZmVyO1xyXG4gICAgICAgICAgICAgICAgICAgICAgaWYgKHRoaXMud29ya2VyKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMud29ya2VyLnBvc3RNZXNzYWdlKHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICBsOiByZW5kZXJQb3MsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgdzogbWUuZGF0YS53LFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgIGg6IGgsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgdnc6IHZ3LFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgIGNoczogY2hzLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgIGZyYW1lTGVuZ3RoOiBmcmFtZUxlbmd0aCxcclxuICAgICAgICAgICAgICAgICAgICAgICAgICBhdWRpb0RhdGE6IGFkLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgIGF1ZGlvRGF0YU9mZnNldDogbGVmdEZyYW1lUG9zLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgIGVvZDogZW9kXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH0sIFthZEJ1Zl0pO1xyXG4gICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgICAgaWYgKGF1ZGlvQnVmZmVyICYmIGF1ZGlvQnVmZmVyLmxlbmd0aCAqIGF1ZGlvQnVmZmVyLm51bWJlck9mQ2hhbm5lbHMgPCBBdWRpb0NhbnZhc0xheWVyQ29tcG9uZW50LkVOQUJMRV9TVFJFQU1JTkdfTlVNQkVSX09GX1NBTVBMRVNfVEhSRVNIT0xEKSB7XHJcblxyXG4gICAgICAgICAgICAgICAgLy8gUmVuZGVyIHdob2xlIGNsaXAgYXQgb25jZVxyXG4gICAgICAgICAgICAgICAgYXJyQWJCdWYgPSBudWxsO1xyXG4gICAgICAgICAgICAgICAgcHNNaW5NYXggPSBudWxsO1xyXG4gICAgICAgICAgICAgICAgY29uc3QgYWQgPSBuZXcgRmxvYXQzMkFycmF5KGNocyAqIGZyYW1lTGVuZ3RoKTtcclxuICAgICAgICAgICAgICAgIGZvciAobGV0IGNoID0gMDsgY2ggPCBjaHM7IGNoKyspIHtcclxuICAgICAgICAgICAgICAgICAgYWQuc2V0KGF1ZGlvQnVmZmVyLmdldENoYW5uZWxEYXRhKGNoKSwgY2ggKiBmcmFtZUxlbmd0aCk7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICB0aGlzLndvcmtlci5wb3N0TWVzc2FnZSh7XHJcbiAgICAgICAgICAgICAgICAgIGw6IGxlZnRQb3MsXHJcbiAgICAgICAgICAgICAgICAgIHc6IHcsXHJcbiAgICAgICAgICAgICAgICAgIHZ3OiB2dyxcclxuICAgICAgICAgICAgICAgICAgY2hzOiBjaHMsXHJcbiAgICAgICAgICAgICAgICAgIGZyYW1lTGVuZ3RoOiBmcmFtZUxlbmd0aCxcclxuICAgICAgICAgICAgICAgICAgYXVkaW9EYXRhOiBhZCxcclxuICAgICAgICAgICAgICAgICAgYXVkaW9EYXRhT2Zmc2V0OiAwLFxyXG4gICAgICAgICAgICAgICAgICBlb2Q6IHRydWVcclxuICAgICAgICAgICAgICAgIH0sIFthZC5idWZmZXJdKTtcclxuXHJcbiAgICAgICAgICAgICAgfSBlbHNlIHtcclxuXHJcbiAgICAgICAgICAgICAgICAvLyBSZW5kZXIgcGl4ZWwgYnkgcGl4ZWxcclxuICAgICAgICAgICAgICAgIGlmICh3ID4gMCkge1xyXG5cclxuICAgICAgICAgICAgICAgICAgaWYgKGZyYW1lc1BlclBpeGVsID4gMCkge1xyXG4gICAgICAgICAgICAgICAgICAgIGxldCBydyA9IDE7XHJcbiAgICAgICAgICAgICAgICAgICAgYXJyQWJCdWYgPSBuZXcgQXJyYXk8RmxvYXQzMkFycmF5PihjaHMpO1xyXG4gICAgICAgICAgICAgICAgICAgIHBzTWluTWF4ID0gbmV3IEZsb2F0MzJBcnJheShjaHMgKiB3ICogMik7XHJcbiAgICAgICAgICAgICAgICAgICAgLy9jb25zb2xlLmRlYnVnKFwiQXVkaW9zaWduYWw6IEFsbG9jYXRpbmcgYnVmZmVyczogXCIrZnJhbWVzUGVyUGl4ZWwpO1xyXG4gICAgICAgICAgICAgICAgICAgIGZvciAobGV0IGNoID0gMDsgY2ggPCBjaHM7IGNoKyspIHtcclxuICAgICAgICAgICAgICAgICAgICAgIGFyckFiQnVmW2NoXSA9IG5ldyBGbG9hdDMyQXJyYXkoZnJhbWVzUGVyUGl4ZWwpO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICBjb25zdCBsZWZ0RnJhbWVQb3MgPSBNYXRoLmZsb29yKGZyYW1lTGVuZ3RoICogcmVuZGVyUG9zIC8gdncpO1xyXG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IGF1T2Zmc2V0ID0gbGVmdEZyYW1lUG9zOyAvLyBzaG91bGQgYWx3YXlzIGJlIDBcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgcmFBc09icyA9IHJhQXMuZnJhbWVzT2JzKGxlZnRGcmFtZVBvcywgZnJhbWVzUGVyUGl4ZWwsIGFyckFiQnVmKTtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5kcmF3U3RhdGVUZXh0KFwiTG9hZGluZy9SZW5kZXJpbmcuLi5cIik7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgIHRoaXMucmFBc1N1YnNjID0gcmFBc09icy5zdWJzY3JpYmUoXHJcbiAgICAgICAgICAgICAgICAgICAgICB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIG5leHQ6IChyZWFkKSA9PiB7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChhcnJBYkJ1ZiAmJiB0aGlzLndvcmtlcikge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgYWRMZW4gPSBjaHMgKiBmcmFtZXNQZXJQaXhlbDtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICghYWQgfHwgYWQubGVuZ3RoICE9PSBhZExlbikge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhZCA9IG5ldyBGbG9hdDMyQXJyYXkoYWRMZW4pO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgZm9yIChsZXQgY2ggPSAwOyBjaCA8IGNoczsgY2grKykge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhZC5zZXQoYXJyQWJCdWZbY2hdLCBjaCAqIGZyYW1lc1BlclBpeGVsKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLndvcmtlci5wb3N0TWVzc2FnZSh7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGw6IHJlbmRlclBvcyxcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdzogcncsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZ3OiB2dyxcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2hzOiBjaHMsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZyYW1lTGVuZ3RoOiBmcmFtZUxlbmd0aCxcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYXVkaW9EYXRhOiBhZCxcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYXVkaW9EYXRhT2Zmc2V0OiBhdU9mZnNldCxcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZW9kOiAocmVhZCA8PSAwKVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfSwgW2FkLmJ1ZmZlcl0pO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICAgICAgfSxcclxuICAgICAgICAgICAgICAgICAgICAgICAgZXJyb3I6IChlcnIpID0+IHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zb2xlLmVycm9yKFwiQXVkaW9TaWduYWw6IEVycm9yIHJlYWRpbmcgYXVkaW8gZGF0YTogXCIgKyBlcnIpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgKTtcclxuICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgfVxyXG4gICAgICAgIH0pO1xyXG4gICAgICB9IGVsc2Uge1xyXG4gICAgICAgIGlmICh0aGlzLmJvdW5kcyAmJiB0aGlzLmJvdW5kcy5kaW1lbnNpb24pIHtcclxuICAgICAgICAgIGxldCB3ID0gTWF0aC5yb3VuZCh0aGlzLmJvdW5kcy5kaW1lbnNpb24ud2lkdGgpO1xyXG4gICAgICAgICAgbGV0IGggPSBNYXRoLnJvdW5kKHRoaXMuYm91bmRzLmRpbWVuc2lvbi5oZWlnaHQpO1xyXG4gICAgICAgICAgbGV0IGcgPSB0aGlzLnNpZ25hbENhbnZhcy5nZXRDb250ZXh0KFwiMmRcIik7XHJcbiAgICAgICAgICBpZiAoZykge1xyXG4gICAgICAgICAgICBnLmNsZWFyUmVjdCgwLCAwLCB3LCBoKTtcclxuICAgICAgICAgIH1cclxuICAgICAgICB9XHJcbiAgICAgIH1cclxuXHJcbiAgfVxyXG5cclxuZHJhd1N0YXRlVGV4dChzdGF0ZVRleHQ6c3RyaW5nKSB7XHJcbiAgICBpZihzdGF0ZVRleHQpIHtcclxuICAgICAgY29uc3QgZyA9IHRoaXMuc2lnbmFsQ2FudmFzLmdldENvbnRleHQoXCIyZFwiKTtcclxuICAgICAgY29uc3Qgdz10aGlzLnNpZ25hbENhbnZhcy53aWR0aDtcclxuICAgICAgY29uc3QgaD10aGlzLnNpZ25hbENhbnZhcy5oZWlnaHQ7XHJcbiAgICAgIGlmIChnICYmIHcgJiYgaCkge1xyXG4gICAgICAgIGcuc3Ryb2tlU3R5bGUgPSAnd2hpdGUnO1xyXG4gICAgICAgIGcuZmlsbFN0eWxlID0gJ3doaXRlJztcclxuICAgICAgICBnLmZvbnQgPSAnMjBweCBzYW5zLXNlcmlmJztcclxuICAgICAgICBnLmZpbGxUZXh0KHN0YXRlVGV4dCwgMTAsIDI1KTtcclxuICAgICAgfVxyXG4gICAgfVxyXG59XHJcbiAgZHJhd1JlbmRlcmVkKGxlZnQ6bnVtYmVyLHc6bnVtYmVyLGg6bnVtYmVyLGNoczpudW1iZXIscHNNaW5NYXg6RmxvYXQzMkFycmF5KSB7XHJcbiAgICB0aGlzLmRyYXdCZygpO1xyXG4gICAgdGhpcy5zaWduYWxDYW52YXMuc3R5bGUubGVmdD1sZWZ0LnRvU3RyaW5nKCkrJ3B4JztcclxuICAgIHRoaXMuc2lnbmFsQ2FudmFzLndpZHRoID0gdztcclxuICAgIHRoaXMuc2lnbmFsQ2FudmFzLmhlaWdodCA9IGg7XHJcbiAgICBsZXQgZyA9IHRoaXMuc2lnbmFsQ2FudmFzLmdldENvbnRleHQoXCIyZFwiKTtcclxuICAgIGlmIChnKSB7XHJcbiAgICAgIGcuY2xlYXJSZWN0KDAsIDAsIHcsIGgpO1xyXG4gICAgICBsZXQgcG9pbnRzTGVuID0gdyAqIGNocztcclxuICAgICAgLy8gb25lIGZvciBtaW4gb25lIGZvciBtYXhcclxuICAgICAgLy9jb25zdCBhcnJMZW4gPSBwb2ludHNMZW4gKiAyO1xyXG4gICAgICBpZiAodGhpcy5fYXVkaW9EYXRhSG9sZGVyKSB7XHJcbiAgICAgICAgLy9jb25zdCBzdGQgPSBEYXRlLm5vdygpO1xyXG5cclxuICAgICAgICBjb25zdCBjaEggPSBoIC8gY2hzO1xyXG5cclxuICAgICAgICBsZXQgeSA9IDA7XHJcbiAgICAgICAgZm9yIChsZXQgY2ggPSAwOyBjaCA8IGNoczsgY2grKykge1xyXG4gICAgICAgICAgY29uc3QgcHNNaW5Qb3MgPSBjaCAqIHc7XHJcbiAgICAgICAgICBjb25zdCBwc01heFBvcyA9IHBvaW50c0xlbiArIHBzTWluUG9zO1xyXG5cclxuICAgICAgICAgIGcuZmlsbFN0eWxlID0gJ2dyZWVuJztcclxuICAgICAgICAgIGcuc3Ryb2tlU3R5bGUgPSAnZ3JlZW4nO1xyXG5cclxuICAgICAgICAgIC8vIGRyYXcgYXVkaW8gc2lnbmFsIGFzIHNpbmdsZSBwb2x5Z29uXHJcbiAgICAgICAgICBnLmJlZ2luUGF0aCgpO1xyXG4gICAgICAgICAgZy5tb3ZlVG8oMCwgeSArIChjaEggLyAyKSArIHBzTWluTWF4W3BzTWF4UG9zXSAqIGNoSCAvIDIpO1xyXG5cclxuICAgICAgICAgIGZvciAobGV0IHBpaSA9IDA7IHBpaSA8IHc7IHBpaSsrKSB7XHJcbiAgICAgICAgICAgIGNvbnN0IHBzTWF4ID0gcHNNaW5NYXhbcHNNYXhQb3MgKyBwaWldO1xyXG4gICAgICAgICAgICBjb25zdCBwdiA9IHBzTWF4ICogY2hIIC8gMjtcclxuICAgICAgICAgICAgY29uc3QgeWQ9eSArIChjaEggLyAyKSAtIHB2O1xyXG4gICAgICAgICAgICAvL2NvbnNvbGUubG9nKFwiTGluZVRvOiA6IFwiK3BpaStcIiBcIit5ZClcclxuICAgICAgICAgICAgZy5saW5lVG8ocGlpLCB5ZCk7XHJcbiAgICAgICAgICB9XHJcbiAgICAgICAgICBjb25zdCByZXZQaXhlbFN0YXJ0PXctMTtcclxuXHJcbiAgICAgICAgICBmb3IgKGxldCBwaWkgPSByZXZQaXhlbFN0YXJ0OyBwaWkgPj0gMDsgcGlpLS0pIHtcclxuICAgICAgICAgICAgY29uc3QgcHNNaW4gPSBwc01pbk1heFtwc01pblBvcyArIHBpaV07XHJcbiAgICAgICAgICAgIGNvbnN0IHB2ID0gcHNNaW4gKiBjaEggLyAyO1xyXG4gICAgICAgICAgICBjb25zdCB5ZD15ICsgKGNoSCAvIDIpIC0gcHY7XHJcbiAgICAgICAgICAgIC8vY29uc29sZS5sb2coXCJMaW5lVG86IDogXCIrcGlpK1wiIFwiK3lkKVxyXG4gICAgICAgICAgICBnLmxpbmVUbyhwaWksIHlkKTtcclxuICAgICAgICAgIH1cclxuICAgICAgICAgIGcuY2xvc2VQYXRoKCk7XHJcblxyXG4gICAgICAgICAgZy5maWxsKCk7XHJcbiAgICAgICAgICBnLnN0cm9rZSgpO1xyXG4gICAgICAgICAgeSArPSBjaEg7XHJcbiAgICAgICAgfVxyXG4gICAgICB9XHJcbiAgICB9XHJcbiAgfVxyXG5cclxuICAvLyByZWRyYXcoKSB7XHJcbiAgLy8gICB0aGlzLmRyYXdCZygpXHJcbiAgLy8gICBsZXQgZyA9IHRoaXMuc2lnbmFsQ2FudmFzLmdldENvbnRleHQoXCIyZFwiKTtcclxuICAvLyAgIGlmIChnKSB7XHJcbiAgLy8gICAgIGxldCB3ID0gdGhpcy5zaWduYWxDYW52YXMud2lkdGg7XHJcbiAgLy8gICAgIGxldCBoID0gdGhpcy5zaWduYWxDYW52YXMuaGVpZ2h0O1xyXG4gIC8vICAgICBnLmNsZWFyUmVjdCgwLCAwLCB3LCBoKTtcclxuICAvLyAgICAgLy9nLmZpbGxTdHlsZSA9IFwiYmxhY2tcIjtcclxuICAvLyAgICAgLy9nLmZpbGxSZWN0KDAsIDAsIHcsIGgpO1xyXG4gIC8vICAgICBpZiAodGhpcy5fYXVkaW9EYXRhSG9sZGVyKSB7XHJcbiAgLy8gICAgICAgbGV0IHN0ZCA9IERhdGUubm93KCk7XHJcbiAgLy8gICAgICAgbGV0IGNocyA9IHRoaXMuX2F1ZGlvRGF0YUhvbGRlci5udW1iZXJPZkNoYW5uZWxzO1xyXG4gIC8vICAgICAgIGxldCBjaEggPSBoIC8gY2hzO1xyXG4gIC8vXHJcbiAgLy8gICAgICAgbGV0IGZyYW1lTGVuZ3RoID0gdGhpcy5fYXVkaW9EYXRhSG9sZGVyLmZyYW1lTGVuO1xyXG4gIC8vXHJcbiAgLy8gICAgICAgbGV0IGZyYW1lc1BlclBpeGVsID0gZnJhbWVMZW5ndGggLyB3O1xyXG4gIC8vICAgICAgIGxldCB5ID0gMDtcclxuICAvLyAgICAgICBsZXQgYWlzOkZsb2F0MzJBcnJheUlucHV0U3RyZWFtfG51bGw9bnVsbDtcclxuICAvLyAgICAgICBsZXQgYXVkaW9Tb3VyY2U9dGhpcy5fYXVkaW9EYXRhSG9sZGVyLmF1ZGlvU291cmNlO1xyXG4gIC8vICAgICAgIGxldCBhdWRpb0J1ZmZlcjpBdWRpb0J1ZmZlcnxudWxsPW51bGw7XHJcbiAgLy8gICAgICAgaWYoYXVkaW9Tb3VyY2UgaW5zdGFuY2VvZiBBdWRpb0J1ZmZlclNvdXJjZSl7XHJcbiAgLy8gICAgICAgICBhdWRpb0J1ZmZlcj1hdWRpb1NvdXJjZS5hdWRpb0J1ZmZlcjtcclxuICAvLyAgICAgICB9XHJcbiAgLy8gICAgICAgbGV0IGFpc0J1ZmZlcjpBcnJheTxGbG9hdDMyQXJyYXk+fG51bGw9bnVsbDtcclxuICAvLyAgICAgICBpZighYXVkaW9CdWZmZXIpIHtcclxuICAvLyAgICAgICAgIGFpcz10aGlzLl9hdWRpb0RhdGFIb2xkZXIuYXVkaW9JbnB1dFN0cmVhbSgpO1xyXG4gIC8vICAgICAgICAgYWlzQnVmZmVyPW5ldyBBcnJheTxGbG9hdDMyQXJyYXk+KGNocyk7XHJcbiAgLy8gICAgICAgICBmb3IobGV0IGNoPTA7Y2g8Y2hzO2NoKyspIHtcclxuICAvLyAgICAgICAgICAgYWlzQnVmZmVyW2NoXSA9IG5ldyBGbG9hdDMyQXJyYXkoZnJhbWVzUGVyUGl4ZWwpO1xyXG4gIC8vICAgICAgICAgfVxyXG4gIC8vICAgICAgIH1cclxuICAvLyAgICAgICAgIGZvciAobGV0IGNoID0gMDsgY2ggPCBjaHM7IGNoKyspIHtcclxuICAvLyAgICAgICAgICAgbGV0IHggPSAwO1xyXG4gIC8vICAgICAgICAgICBsZXQgcHNNaW4gPSBuZXcgRmxvYXQzMkFycmF5KHcpO1xyXG4gIC8vICAgICAgICAgICBsZXQgcHNNYXggPSBuZXcgRmxvYXQzMkFycmF5KHcpO1xyXG4gIC8vICAgICAgICAgICBsZXQgZnJhbWVQb3MgPSAwO1xyXG4gIC8vICAgICAgICAgICBmb3IgKGxldCBwaWkgPSAwOyBwaWkgPCB3OyBwaWkrKykge1xyXG4gIC8vICAgICAgICAgICAgIGxldCBwTWluID0gMDtcclxuICAvLyAgICAgICAgICAgICBsZXQgcE1heCA9IDA7XHJcbiAgLy9cclxuICAvLyAgICAgICAgICAgICBpZiAoYXVkaW9CdWZmZXIpe1xyXG4gIC8vICAgICAgICAgICAgICAgLy8gY2FsY3VsYXRlIHBpeGVsIG1pbi9tYXggYW1wbGl0dWRlXHJcbiAgLy8gICAgICAgICAgICAgICBmb3IgKGxldCBhaSA9IDA7IGFpIDwgZnJhbWVzUGVyUGl4ZWw7IGFpKyspIHtcclxuICAvLyAgICAgICAgICAgICAgICAgLy9sZXQgZnJhbWVQb3M9KHBpaSpmcmFtZXNQZXJQaXhlbCkrYWk7XHJcbiAgLy8gICAgICAgICAgICAgICAgIGxldCBhID0gYXVkaW9CdWZmZXIuZ2V0Q2hhbm5lbERhdGEoY2gpW2ZyYW1lUG9zKytdO1xyXG4gIC8vXHJcbiAgLy8gICAgICAgICAgICAgICAgIGlmIChhIDwgcE1pbikge1xyXG4gIC8vICAgICAgICAgICAgICAgICAgIHBNaW4gPSBhO1xyXG4gIC8vICAgICAgICAgICAgICAgICB9XHJcbiAgLy8gICAgICAgICAgICAgICAgIGlmIChhID4gcE1heCkge1xyXG4gIC8vICAgICAgICAgICAgICAgICAgIHBNYXggPSBhO1xyXG4gIC8vICAgICAgICAgICAgICAgICB9XHJcbiAgLy8gICAgICAgICAgICAgICB9XHJcbiAgLy8gICAgICAgICAgIH1lbHNlIGlmKGFpcyAmJiBhaXNCdWZmZXIpIHtcclxuICAvLyAgICAgICAgICAgICAgIGxldCByID0gYWlzLnJlYWQoYWlzQnVmZmVyKTtcclxuICAvLyAgICAgICAgICAgICAgIGZvciAobGV0IGFpID0gMDsgYWkgPCByOyBhaSsrKSB7XHJcbiAgLy9cclxuICAvLyAgICAgICAgICAgICAgICAgbGV0IGEgPSBhaXNCdWZmZXJbY2hdW2FpXTtcclxuICAvL1xyXG4gIC8vICAgICAgICAgICAgICAgICBpZiAoYSA8IHBNaW4pIHtcclxuICAvLyAgICAgICAgICAgICAgICAgICBwTWluID0gYTtcclxuICAvLyAgICAgICAgICAgICAgICAgfVxyXG4gIC8vICAgICAgICAgICAgICAgICBpZiAoYSA+IHBNYXgpIHtcclxuICAvLyAgICAgICAgICAgICAgICAgICBwTWF4ID0gYTtcclxuICAvLyAgICAgICAgICAgICAgICAgfVxyXG4gIC8vICAgICAgICAgICAgICAgfVxyXG4gIC8vICAgICAgICAgICAgIH1cclxuICAvLyAgICAgICAgICAgICBwc01pbltwaWldID0gcE1pbjtcclxuICAvLyAgICAgICAgICAgICBwc01heFtwaWldID0gcE1heDtcclxuICAvLyAgICAgICAgICAgfVxyXG4gIC8vICAgICAgICAgICBnLmZpbGxTdHlsZSA9ICdncmVlbic7XHJcbiAgLy8gICAgICAgICAgIGcuc3Ryb2tlU3R5bGUgPSAnZ3JlZW4nO1xyXG4gIC8vXHJcbiAgLy8gICAgICAgICAgIC8vIGRyYXcgYXVkaW8gc2lnbmFsIGFzIHNpbmdsZSBwb2x5Z29uXHJcbiAgLy8gICAgICAgICAgIGcuYmVnaW5QYXRoKCk7XHJcbiAgLy8gICAgICAgICAgIGcubW92ZVRvKDAsIHkgKyAoY2hIIC8gMikgKyBwc01pblswXSAqIGNoSCAvIDIpO1xyXG4gIC8vXHJcbiAgLy8gICAgICAgICAgIGZvciAobGV0IHBpaSA9IDA7IHBpaSA8IHc7IHBpaSsrKSB7XHJcbiAgLy8gICAgICAgICAgICAgbGV0IHB2ID0gcHNNaW5bcGlpXSAqIGNoSCAvIDI7XHJcbiAgLy8gICAgICAgICAgICAgLy9jb25zb2xlLmxvZyhcIk1pbjogXCIscHYpO1xyXG4gIC8vICAgICAgICAgICAgIGcubGluZVRvKHBpaSwgeSArIChjaEggLyAyKSArIHB2KTtcclxuICAvLyAgICAgICAgICAgfVxyXG4gIC8vICAgICAgICAgICBmb3IgKGxldCBwaWkgPSB3OyBwaWkgPj0gMDsgcGlpLS0pIHtcclxuICAvLyAgICAgICAgICAgICBsZXQgcHYgPSBwc01heFtwaWldICogY2hIIC8gMjtcclxuICAvLyAgICAgICAgICAgICAvL2NvbnNvbGUubG9nKFwiTWF4OiBcIixwdik7XHJcbiAgLy8gICAgICAgICAgICAgZy5saW5lVG8ocGlpLCB5ICsgKGNoSCAvIDIpICsgcHYpO1xyXG4gIC8vICAgICAgICAgICB9XHJcbiAgLy8gICAgICAgICAgIGcuY2xvc2VQYXRoKCk7XHJcbiAgLy8gICAgICAgICAgIC8vZy5saW5lVG8oKVxyXG4gIC8vICAgICAgICAgICBnLmZpbGwoKTtcclxuICAvLyAgICAgICAgICAgZy5zdHJva2UoKTtcclxuICAvLyAgICAgICAgICAgZy5maWxsU3R5bGUgPSBcInllbGxvd1wiO1xyXG4gIC8vICAgICAgICAgICBnLnN0cm9rZSgpO1xyXG4gIC8vICAgICAgICAgICB5ICs9IGNoSDtcclxuICAvLyAgICAgICAgIH1cclxuICAvLyAgICAgICBhaXM/LmNsb3NlKCk7XHJcbiAgLy8gICAgIH1cclxuICAvLyAgIH1cclxuICAvLyB9XHJcblxyXG4gIHNldERhdGEoYXVkaW9EYXRhOiBBdWRpb0RhdGFIb2xkZXIgfCBudWxsKSB7XHJcbiAgICB0aGlzLl9hdWRpb0RhdGFIb2xkZXIgPSBhdWRpb0RhdGE7XHJcbiAgICB0aGlzLnBsYXlGcmFtZVBvc2l0aW9uID0gMDtcclxuICB9XHJcbn1cclxuXHJcbiJdfQ==