speechrecorderng 3.6.0 → 3.8.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (220) hide show
  1. package/esm2022/lib/action/action.mjs +73 -0
  2. package/{esm2020 → esm2022}/lib/audio/array_audio_buffer.mjs +163 -163
  3. package/{esm2020 → esm2022}/lib/audio/array_audio_buffer_input_stream.mjs +85 -85
  4. package/{esm2020 → esm2022}/lib/audio/array_audio_buffer_random_access_stream.mjs +15 -15
  5. package/esm2022/lib/audio/audio_data_holder.mjs +264 -0
  6. package/{esm2020 → esm2022}/lib/audio/audio_display.mjs +93 -93
  7. package/{esm2020 → esm2022}/lib/audio/audio_player.mjs +213 -213
  8. package/esm2022/lib/audio/capture/capture.mjs +855 -0
  9. package/esm2022/lib/audio/context.mjs +79 -0
  10. package/{esm2020 → esm2022}/lib/audio/dsp/level_measure.mjs +515 -515
  11. package/{esm2020 → esm2022}/lib/audio/format.mjs +16 -16
  12. package/esm2022/lib/audio/impl/wavformat.mjs +6 -0
  13. package/{esm2020 → esm2022}/lib/audio/impl/wavreader.mjs +133 -133
  14. package/esm2022/lib/audio/impl/wavwriter.mjs +105 -0
  15. package/esm2022/lib/audio/inddb_audio_buffer.mjs +508 -0
  16. package/{esm2020 → esm2022}/lib/audio/io/stream.mjs +58 -58
  17. package/esm2022/lib/audio/net_audio_buffer.mjs +293 -0
  18. package/{esm2020 → esm2022}/lib/audio/persistor.mjs +80 -80
  19. package/{esm2020 → esm2022}/lib/audio/playback/array_audio_buffer_source_node.mjs +125 -125
  20. package/esm2022/lib/audio/playback/audio_source_node.mjs +18 -0
  21. package/esm2022/lib/audio/playback/audio_source_worklet_module_loader.mjs +167 -0
  22. package/{esm2020 → esm2022}/lib/audio/playback/inddb_audio_buffer_source_node.mjs +166 -166
  23. package/{esm2020 → esm2022}/lib/audio/playback/net_audio_buffer_source_node.mjs +217 -217
  24. package/esm2022/lib/audio/playback/player.mjs +402 -0
  25. package/esm2022/lib/audio/ui/audio_canvas_layer_comp.mjs +347 -0
  26. package/{esm2020 → esm2022}/lib/audio/ui/audio_display_control.mjs +65 -65
  27. package/{esm2020 → esm2022}/lib/audio/ui/audio_display_scroll_pane.mjs +139 -139
  28. package/{esm2020 → esm2022}/lib/audio/ui/audiosignal.mjs +524 -524
  29. package/{esm2020 → esm2022}/lib/audio/ui/common.mjs +18 -18
  30. package/esm2022/lib/audio/ui/container.mjs +414 -0
  31. package/{esm2020 → esm2022}/lib/audio/ui/livelevel.mjs +352 -352
  32. package/esm2022/lib/audio/ui/scroll_pane_horizontal.mjs +11 -0
  33. package/esm2022/lib/audio/ui/sonagram.mjs +900 -0
  34. package/esm2022/lib/db/inddb.mjs +120 -0
  35. package/esm2022/lib/dsp/utils.mjs +48 -0
  36. package/{esm2020 → esm2022}/lib/io/BinaryReader.mjs +84 -84
  37. package/esm2022/lib/io/BinaryWriter.mjs +74 -0
  38. package/{esm2020 → esm2022}/lib/io/stream.mjs +258 -258
  39. package/{esm2020 → esm2022}/lib/math/2d/geometry.mjs +27 -27
  40. package/esm2022/lib/math/complex.mjs +58 -0
  41. package/{esm2020 → esm2022}/lib/math/dft.mjs +195 -195
  42. package/{esm2020 → esm2022}/lib/media/utils.mjs +13 -13
  43. package/esm2022/lib/net/uploader.mjs +367 -0
  44. package/{esm2020 → esm2022}/lib/recorder_component.mjs +64 -64
  45. package/esm2022/lib/speechrecorder/project/project.mjs +49 -0
  46. package/esm2022/lib/speechrecorder/project/project.service.mjs +64 -0
  47. package/{esm2020 → esm2022}/lib/speechrecorder/recording.mjs +123 -123
  48. package/esm2022/lib/speechrecorder/recordings/basic_recording.service.mjs +218 -0
  49. package/esm2022/lib/speechrecorder/recordings/recordings.service.mjs +1014 -0
  50. package/{esm2020 → esm2022}/lib/speechrecorder/script/script.mjs +114 -114
  51. package/{esm2020 → esm2022}/lib/speechrecorder/script/script.service.mjs +47 -47
  52. package/esm2022/lib/speechrecorder/session/audiorecorder.mjs +1179 -0
  53. package/esm2022/lib/speechrecorder/session/basicrecorder.mjs +668 -0
  54. package/esm2022/lib/speechrecorder/session/controlpanel.mjs +416 -0
  55. package/{esm2020 → esm2022}/lib/speechrecorder/session/item.mjs +29 -29
  56. package/{esm2020 → esm2022}/lib/speechrecorder/session/progress.mjs +69 -69
  57. package/{esm2020 → esm2022}/lib/speechrecorder/session/prompting.mjs +571 -571
  58. package/{esm2020 → esm2022}/lib/speechrecorder/session/recorder_combi_pane.mjs +65 -65
  59. package/esm2022/lib/speechrecorder/session/recording_file_cache.mjs +195 -0
  60. package/{esm2020 → esm2022}/lib/speechrecorder/session/recording_list.mjs +103 -103
  61. package/{esm2020 → esm2022}/lib/speechrecorder/session/recordingfile/recording-file-meta.component.mjs +63 -63
  62. package/{esm2020 → esm2022}/lib/speechrecorder/session/recordingfile/recording-file-navi.component.mjs +51 -51
  63. package/{esm2020 → esm2022}/lib/speechrecorder/session/recordingfile/recording-file-u-i.component.mjs +104 -104
  64. package/{esm2020 → esm2022}/lib/speechrecorder/session/recordingfile/recording-file-view.component.mjs +381 -381
  65. package/{esm2020 → esm2022}/lib/speechrecorder/session/recordingfile/recording-file.mjs +67 -67
  66. package/esm2022/lib/speechrecorder/session/recordingfile/recordingfile-service.mjs +288 -0
  67. package/{esm2020 → esm2022}/lib/speechrecorder/session/session.mjs +1 -1
  68. package/esm2022/lib/speechrecorder/session/session.service.mjs +69 -0
  69. package/{esm2020 → esm2022}/lib/speechrecorder/session/session_finished_dialog.mjs +29 -29
  70. package/esm2022/lib/speechrecorder/session/sessionmanager.mjs +1386 -0
  71. package/{esm2020 → esm2022}/lib/speechrecorder/session/warning_bar.mjs +28 -28
  72. package/{esm2020 → esm2022}/lib/speechrecorder/spruploader.mjs +22 -22
  73. package/{esm2020 → esm2022}/lib/speechrecorder/startstopsignal/startstopsignal.mjs +1 -1
  74. package/esm2022/lib/speechrecorder/startstopsignal/ui/simpletrafficlight.mjs +57 -0
  75. package/{esm2020 → esm2022}/lib/speechrecorderng.component.mjs +388 -388
  76. package/{esm2020 → esm2022}/lib/speechrecorderng.module.mjs +100 -100
  77. package/{esm2020 → esm2022}/lib/spr.config.mjs +26 -26
  78. package/{esm2020 → esm2022}/lib/spr.module.version.mjs +2 -2
  79. package/{esm2020 → esm2022}/lib/ui/canvas_layer_comp.mjs +38 -38
  80. package/{esm2020 → esm2022}/lib/ui/message_dialog.mjs +30 -30
  81. package/esm2022/lib/ui/recordingitem_display.mjs +253 -0
  82. package/{esm2020 → esm2022}/lib/ui/responsive_component.mjs +24 -24
  83. package/{esm2020 → esm2022}/lib/utils/scrollIntoViewToBottom.mjs +23 -23
  84. package/esm2022/lib/utils/ua-parser.mjs +190 -0
  85. package/esm2022/lib/utils/utils.mjs +105 -0
  86. package/esm2022/lib/utils/wake_lock.mjs +114 -0
  87. package/{esm2020 → esm2022}/lib/utils/wake_lock_media.mjs +1 -1
  88. package/{esm2020 → esm2022}/public-api.mjs +33 -33
  89. package/{esm2020 → esm2022}/speechrecorderng.mjs +4 -4
  90. package/{fesm2020 → fesm2022}/speechrecorderng.mjs +16518 -16454
  91. package/fesm2022/speechrecorderng.mjs.map +1 -0
  92. package/index.d.ts +5 -5
  93. package/lib/action/action.d.ts +27 -27
  94. package/lib/audio/array_audio_buffer.d.ts +31 -31
  95. package/lib/audio/array_audio_buffer_input_stream.d.ts +14 -14
  96. package/lib/audio/array_audio_buffer_random_access_stream.d.ts +9 -9
  97. package/lib/audio/audio_data_holder.d.ts +84 -84
  98. package/lib/audio/audio_display.d.ts +36 -36
  99. package/lib/audio/audio_player.d.ts +47 -47
  100. package/lib/audio/capture/capture.d.ts +67 -67
  101. package/lib/audio/context.d.ts +6 -6
  102. package/lib/audio/dsp/level_measure.d.ts +60 -60
  103. package/lib/audio/format.d.ts +11 -11
  104. package/lib/audio/impl/wavformat.d.ts +5 -5
  105. package/lib/audio/impl/wavreader.d.ts +16 -16
  106. package/lib/audio/impl/wavwriter.d.ts +13 -13
  107. package/lib/audio/inddb_audio_buffer.d.ts +68 -68
  108. package/lib/audio/io/stream.d.ts +28 -28
  109. package/lib/audio/net_audio_buffer.d.ts +57 -57
  110. package/lib/audio/persistor.d.ts +29 -29
  111. package/lib/audio/playback/array_audio_buffer_source_node.d.ts +18 -18
  112. package/lib/audio/playback/audio_source_node.d.ts +10 -10
  113. package/lib/audio/playback/audio_source_worklet_module_loader.d.ts +4 -4
  114. package/lib/audio/playback/inddb_audio_buffer_source_node.d.ts +21 -21
  115. package/lib/audio/playback/net_audio_buffer_source_node.d.ts +27 -27
  116. package/lib/audio/playback/player.d.ts +65 -65
  117. package/lib/audio/ui/audio_canvas_layer_comp.d.ts +68 -68
  118. package/lib/audio/ui/audio_display_control.d.ts +25 -25
  119. package/lib/audio/ui/audio_display_scroll_pane.d.ts +26 -26
  120. package/lib/audio/ui/audiosignal.d.ts +30 -30
  121. package/lib/audio/ui/common.d.ts +11 -11
  122. package/lib/audio/ui/container.d.ts +63 -63
  123. package/lib/audio/ui/livelevel.d.ts +60 -60
  124. package/lib/audio/ui/scroll_pane_horizontal.d.ts +5 -5
  125. package/lib/audio/ui/sonagram.d.ts +37 -37
  126. package/lib/db/inddb.d.ts +21 -21
  127. package/lib/dsp/utils.d.ts +19 -19
  128. package/lib/io/BinaryReader.d.ts +18 -18
  129. package/lib/io/BinaryWriter.d.ts +15 -15
  130. package/lib/io/stream.d.ts +59 -59
  131. package/lib/math/2d/geometry.d.ts +18 -18
  132. package/lib/math/complex.d.ts +17 -17
  133. package/lib/math/dft.d.ts +22 -22
  134. package/lib/media/utils.d.ts +3 -3
  135. package/lib/net/uploader.d.ts +81 -81
  136. package/lib/recorder_component.d.ts +16 -16
  137. package/lib/speechrecorder/project/project.d.ts +59 -59
  138. package/lib/speechrecorder/project/project.service.d.ts +21 -21
  139. package/lib/speechrecorder/recording.d.ts +51 -51
  140. package/lib/speechrecorder/recordings/basic_recording.service.d.ts +27 -27
  141. package/lib/speechrecorder/recordings/recordings.service.d.ts +48 -48
  142. package/lib/speechrecorder/script/script.d.ts +80 -79
  143. package/lib/speechrecorder/script/script.service.d.ts +16 -16
  144. package/lib/speechrecorder/session/audiorecorder.d.ts +122 -122
  145. package/lib/speechrecorder/session/basicrecorder.d.ts +139 -139
  146. package/lib/speechrecorder/session/controlpanel.d.ts +109 -107
  147. package/lib/speechrecorder/session/item.d.ts +12 -12
  148. package/lib/speechrecorder/session/progress.d.ts +17 -17
  149. package/lib/speechrecorder/session/prompting.d.ts +121 -121
  150. package/lib/speechrecorder/session/recorder_combi_pane.d.ts +32 -32
  151. package/lib/speechrecorder/session/recording_file_cache.d.ts +33 -33
  152. package/lib/speechrecorder/session/recording_list.d.ts +24 -24
  153. package/lib/speechrecorder/session/recordingfile/recording-file-meta.component.d.ts +15 -15
  154. package/lib/speechrecorder/session/recordingfile/recording-file-navi.component.d.ts +20 -20
  155. package/lib/speechrecorder/session/recordingfile/recording-file-u-i.component.d.ts +31 -31
  156. package/lib/speechrecorder/session/recordingfile/recording-file-view.component.d.ts +55 -55
  157. package/lib/speechrecorder/session/recordingfile/recording-file.d.ts +7 -7
  158. package/lib/speechrecorder/session/recordingfile/recordingfile-service.d.ts +24 -24
  159. package/lib/speechrecorder/session/session.d.ts +15 -15
  160. package/lib/speechrecorder/session/session.service.d.ts +20 -20
  161. package/lib/speechrecorder/session/session_finished_dialog.d.ts +10 -10
  162. package/lib/speechrecorder/session/sessionmanager.d.ts +129 -123
  163. package/lib/speechrecorder/session/warning_bar.d.ts +8 -8
  164. package/lib/speechrecorder/spruploader.d.ts +11 -11
  165. package/lib/speechrecorder/startstopsignal/startstopsignal.d.ts +10 -10
  166. package/lib/speechrecorder/startstopsignal/ui/simpletrafficlight.d.ts +11 -11
  167. package/lib/speechrecorderng.component.d.ts +61 -61
  168. package/lib/speechrecorderng.module.d.ts +56 -56
  169. package/lib/spr.config.d.ts +17 -17
  170. package/lib/spr.module.version.d.ts +1 -1
  171. package/lib/ui/canvas_layer_comp.d.ts +13 -13
  172. package/lib/ui/message_dialog.d.ts +10 -10
  173. package/lib/ui/recordingitem_display.d.ts +84 -84
  174. package/lib/ui/responsive_component.d.ts +9 -9
  175. package/lib/utils/scrollIntoViewToBottom.d.ts +9 -9
  176. package/lib/utils/ua-parser.d.ts +43 -43
  177. package/lib/utils/utils.d.ts +19 -19
  178. package/lib/utils/wake_lock.d.ts +23 -23
  179. package/lib/utils/wake_lock_media.d.ts +1 -1
  180. package/package.json +17 -23
  181. package/public-api.d.ts +33 -33
  182. package/esm2020/lib/action/action.mjs +0 -73
  183. package/esm2020/lib/audio/audio_data_holder.mjs +0 -264
  184. package/esm2020/lib/audio/capture/capture.mjs +0 -855
  185. package/esm2020/lib/audio/context.mjs +0 -79
  186. package/esm2020/lib/audio/impl/wavformat.mjs +0 -6
  187. package/esm2020/lib/audio/impl/wavwriter.mjs +0 -105
  188. package/esm2020/lib/audio/inddb_audio_buffer.mjs +0 -508
  189. package/esm2020/lib/audio/net_audio_buffer.mjs +0 -293
  190. package/esm2020/lib/audio/playback/audio_source_node.mjs +0 -18
  191. package/esm2020/lib/audio/playback/audio_source_worklet_module_loader.mjs +0 -167
  192. package/esm2020/lib/audio/playback/player.mjs +0 -402
  193. package/esm2020/lib/audio/ui/audio_canvas_layer_comp.mjs +0 -347
  194. package/esm2020/lib/audio/ui/container.mjs +0 -414
  195. package/esm2020/lib/audio/ui/scroll_pane_horizontal.mjs +0 -11
  196. package/esm2020/lib/audio/ui/sonagram.mjs +0 -900
  197. package/esm2020/lib/db/inddb.mjs +0 -120
  198. package/esm2020/lib/dsp/utils.mjs +0 -48
  199. package/esm2020/lib/io/BinaryWriter.mjs +0 -74
  200. package/esm2020/lib/math/complex.mjs +0 -58
  201. package/esm2020/lib/net/uploader.mjs +0 -367
  202. package/esm2020/lib/speechrecorder/project/project.mjs +0 -49
  203. package/esm2020/lib/speechrecorder/project/project.service.mjs +0 -64
  204. package/esm2020/lib/speechrecorder/recordings/basic_recording.service.mjs +0 -216
  205. package/esm2020/lib/speechrecorder/recordings/recordings.service.mjs +0 -1014
  206. package/esm2020/lib/speechrecorder/session/audiorecorder.mjs +0 -1179
  207. package/esm2020/lib/speechrecorder/session/basicrecorder.mjs +0 -666
  208. package/esm2020/lib/speechrecorder/session/controlpanel.mjs +0 -409
  209. package/esm2020/lib/speechrecorder/session/recording_file_cache.mjs +0 -195
  210. package/esm2020/lib/speechrecorder/session/recordingfile/recordingfile-service.mjs +0 -288
  211. package/esm2020/lib/speechrecorder/session/session.service.mjs +0 -69
  212. package/esm2020/lib/speechrecorder/session/sessionmanager.mjs +0 -1333
  213. package/esm2020/lib/speechrecorder/startstopsignal/ui/simpletrafficlight.mjs +0 -57
  214. package/esm2020/lib/ui/recordingitem_display.mjs +0 -253
  215. package/esm2020/lib/utils/ua-parser.mjs +0 -190
  216. package/esm2020/lib/utils/utils.mjs +0 -105
  217. package/esm2020/lib/utils/wake_lock.mjs +0 -114
  218. package/fesm2015/speechrecorderng.mjs +0 -17708
  219. package/fesm2015/speechrecorderng.mjs.map +0 -1
  220. package/fesm2020/speechrecorderng.mjs.map +0 -1
@@ -1,533 +1,533 @@
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
- }
511
- AudioSignalfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.2.12", ngImport: i0, type: AudioSignal, deps: [{ token: i0.ElementRef }], target: i0.ɵɵFactoryTarget.Component });
512
- AudioSignal.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.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: `
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: "17.0.6", ngImport: i0, type: AudioSignal, deps: [{ token: i0.ElementRef }], target: i0.ɵɵFactoryTarget.Component }); }
511
+ static { thiscmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "17.0.6", 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: `
513
512
  <canvas #bg height="10"></canvas>
514
513
  <canvas #audioSignal height="10"></canvas>
515
514
  <canvas #cursor height="10" (mousedown)="selectionStart($event)" (mouseover)="updateCursorCanvas($event)" (mousemove)="updateCursorCanvas($event)"
516
515
  (mouseleave)="updateCursorCanvas($event, false)"></canvas>
517
- <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"] });
518
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.2.12", ngImport: i0, type: AudioSignal, decorators: [{
519
- type: Component,
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: "17.0.6", ngImport: i0, type: AudioSignal, decorators: [{
519
+ type: Component,
520
520
  args: [{ selector: 'audio-signal', template: `
521
521
  <canvas #bg height="10"></canvas>
522
522
  <canvas #audioSignal height="10"></canvas>
523
523
  <canvas #cursor height="10" (mousedown)="selectionStart($event)" (mouseover)="updateCursorCanvas($event)" (mousemove)="updateCursorCanvas($event)"
524
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: function () { return [{ 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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RSxJQUFJLEVBQUU7Z0JBQ0gsZ0JBQWdCO3NCQUF0RCxTQUFTO3VCQUFDLFFBQVEsRUFBRSxFQUFFLE1BQU0sRUFBRSxJQUFJLEVBQUUiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQge0NvbXBvbmVudCwgVmlld0NoaWxkLCBFbGVtZW50UmVmfSBmcm9tICdAYW5ndWxhci9jb3JlJztcclxuaW1wb3J0IHtBdWRpb0NhbnZhc0xheWVyQ29tcG9uZW50fSBmcm9tIFwiLi9hdWRpb19jYW52YXNfbGF5ZXJfY29tcFwiO1xyXG5pbXBvcnQge1dvcmtlckhlbHBlcn0gZnJvbSBcIi4uLy4uL3V0aWxzL3V0aWxzXCI7XHJcbmltcG9ydCB7QXVkaW9CdWZmZXJTb3VyY2UsIEF1ZGlvRGF0YUhvbGRlcn0gZnJvbSBcIi4uL2F1ZGlvX2RhdGFfaG9sZGVyXCI7XHJcbmltcG9ydCB7U3Vic2NyaXB0aW9ufSBmcm9tIFwicnhqc1wiO1xyXG5cclxuZGVjbGFyZSBmdW5jdGlvbiBwb3N0TWVzc2FnZShtZXNzYWdlOiBhbnksIHRyYW5zZmVyOiBBcnJheTxhbnk+KTogdm9pZDtcclxuXHJcbkBDb21wb25lbnQoe1xyXG5cclxuICBzZWxlY3RvcjogJ2F1ZGlvLXNpZ25hbCcsXHJcbiAgdGVtcGxhdGU6IGBcclxuICAgIDxjYW52YXMgI2JnIGhlaWdodD1cIjEwXCI+PC9jYW52YXM+XHJcbiAgICA8Y2FudmFzICNhdWRpb1NpZ25hbCBoZWlnaHQ9XCIxMFwiPjwvY2FudmFzPlxyXG4gICAgPGNhbnZhcyAjY3Vyc29yIGhlaWdodD1cIjEwXCIgKG1vdXNlZG93bik9XCJzZWxlY3Rpb25TdGFydCgkZXZlbnQpXCIgKG1vdXNlb3Zlcik9XCJ1cGRhdGVDdXJzb3JDYW52YXMoJGV2ZW50KVwiIChtb3VzZW1vdmUpPVwidXBkYXRlQ3Vyc29yQ2FudmFzKCRldmVudClcIlxyXG4gICAgICAgICAgICAobW91c2VsZWF2ZSk9XCJ1cGRhdGVDdXJzb3JDYW52YXMoJGV2ZW50LCBmYWxzZSlcIj48L2NhbnZhcz5cclxuICAgIDxjYW52YXMgI21hcmtlciBoZWlnaHQ9XCIxMFwiPjwvY2FudmFzPmAsXHJcblxyXG4gIHN0eWxlczogW2A6aG9zdHtcclxuICAgICAgbWluLWhlaWdodDogMHB4O1xyXG4gICAgfWAsYGNhbnZhcyB7XHJcbiAgICB0b3A6IDA7XHJcbiAgICBsZWZ0OiAwO1xyXG4gICAgd2lkdGg6IDA7XHJcbiAgICBoZWlnaHQ6IDA7XHJcbiAgICBtaW4taGVpZ2h0OiAwcHg7XHJcbiAgICBwb3NpdGlvbjogYWJzb2x1dGU7XHJcbiAgfWBdXHJcblxyXG59KVxyXG5leHBvcnQgY2xhc3MgQXVkaW9TaWduYWwgZXh0ZW5kcyBBdWRpb0NhbnZhc0xheWVyQ29tcG9uZW50e1xyXG5cclxuICBuOiBhbnk7XHJcbiAgY2UhOiBIVE1MRGl2RWxlbWVudDtcclxuICBAVmlld0NoaWxkKCdhdWRpb1NpZ25hbCcsIHsgc3RhdGljOiB0cnVlIH0pIGF1ZGlvU2lnbmFsQ2FudmFzUmVmITogRWxlbWVudFJlZjtcclxuICBAVmlld0NoaWxkKCdtYXJrZXInLCB7IHN0YXRpYzogdHJ1ZSB9KSBwbGF5UG9zQ2FudmFzUmVmITogRWxlbWVudFJlZjtcclxuICBzaWduYWxDYW52YXMhOiBIVE1MQ2FudmFzRWxlbWVudDtcclxuXHJcbiAgbWFya2VyQ2FudmFzITogSFRNTENhbnZhc0VsZW1lbnQ7XHJcblxyXG4gIHByaXZhdGUgX3BsYXlGcmFtZVBvc2l0aW9uOiBudW1iZXJ8bnVsbD1udWxsO1xyXG5cclxuICBwcml2YXRlIHdvcmtlcjogV29ya2VyIHwgbnVsbD1udWxsO1xyXG4gIHByaXZhdGUgcmVhZG9ubHkgd29ya2VyVVJMOiBzdHJpbmc7XHJcblxyXG4gIHByaXZhdGUgcmFBc1N1YnNjOlN1YnNjcmlwdGlvbnxudWxsPW51bGw7XHJcblxyXG4gIGNvbnN0cnVjdG9yKHByaXZhdGUgcmVmOiBFbGVtZW50UmVmKSB7XHJcbiAgICBzdXBlcigpO1xyXG4gICAgdGhpcy53b3JrZXJVUkwgPSBXb3JrZXJIZWxwZXIuYnVpbGRXb3JrZXJCbG9iVVJMKHRoaXMud29ya2VyRnVuY3Rpb24pXHJcbiAgICB0aGlzLl9hdWRpb0RhdGFIb2xkZXIgPSBudWxsO1xyXG4gICAgdGhpcy5fYmdDb2xvcj0nYmxhY2snO1xyXG4gICAgdGhpcy5fc2VsZWN0Q29sb3I9J3JnYmEoMjU1LDI1NSwwLDAuOCknXHJcblxyXG4gIH1cclxuXHJcbiAgbmdBZnRlclZpZXdJbml0KCkge1xyXG5cclxuICAgIHRoaXMuY2UgPSB0aGlzLnJlZi5uYXRpdmVFbGVtZW50O1xyXG4gICAgdGhpcy5iZ0NhbnZhcyA9IHRoaXMuYmdDYW52YXNSZWYubmF0aXZlRWxlbWVudDtcclxuICAgIHRoaXMuYmdDYW52YXMuc3R5bGUuekluZGV4ID0gJzEnO1xyXG4gICAgdGhpcy5zaWduYWxDYW52YXMgPSB0aGlzLmF1ZGlvU2lnbmFsQ2FudmFzUmVmLm5hdGl2ZUVsZW1lbnQ7XHJcbiAgICB0aGlzLnNpZ25hbENhbnZhcy5zdHlsZS56SW5kZXggPSAnMic7XHJcbiAgICB0aGlzLm1hcmtlckNhbnZhcyA9IHRoaXMucGxheVBvc0NhbnZhc1JlZi5uYXRpdmVFbGVtZW50O1xyXG4gICAgdGhpcy5tYXJrZXJDYW52YXMuc3R5bGUuekluZGV4ID0gJzMnO1xyXG4gICAgdGhpcy5jdXJzb3JDYW52YXMgPSB0aGlzLmN1cnNvckNhbnZhc1JlZi5uYXRpdmVFbGVtZW50O1xyXG4gICAgdGhpcy5jdXJzb3JDYW52YXMuc3R5bGUuekluZGV4ID0gJzQnO1xyXG5cclxuICAgIHRoaXMuY2FudmFzTGF5ZXJzWzBdPXRoaXMuYmdDYW52YXM7XHJcbiAgICB0aGlzLmNhbnZhc0xheWVyc1sxXT10aGlzLnNpZ25hbENhbnZhcztcclxuICAgIHRoaXMuY2FudmFzTGF5ZXJzWzJdPXRoaXMuY3Vyc29yQ2FudmFzO1xyXG4gICAgdGhpcy5jYW52YXNMYXllcnNbM109dGhpcy5tYXJrZXJDYW52YXM7XHJcblxyXG4gIH1cclxuXHJcbiAgZ2V0IHBsYXlGcmFtZVBvc2l0aW9uKCk6IG51bWJlciB8bnVsbHtcclxuICAgIHJldHVybiB0aGlzLl9wbGF5RnJhbWVQb3NpdGlvbjtcclxuICB9XHJcblxyXG4gIHNldCBwbGF5RnJhbWVQb3NpdGlvbihwbGF5RnJhbWVQb3NpdGlvbjogbnVtYmVyfG51bGwpIHtcclxuICAgIHRoaXMuX3BsYXlGcmFtZVBvc2l0aW9uID0gcGxheUZyYW1lUG9zaXRpb247XHJcbiAgICB0aGlzLmRyYXdQbGF5UG9zaXRpb24oKTtcclxuICB9XHJcblxyXG5cclxuXHJcbiAgZHJhd1BsYXlQb3NpdGlvbigpIHtcclxuICAgIGlmICh0aGlzLm1hcmtlckNhbnZhcykge1xyXG4gICAgICBsZXQgdyA9IHRoaXMubWFya2VyQ2FudmFzLndpZHRoO1xyXG4gICAgICBsZXQgaCA9IHRoaXMubWFya2VyQ2FudmFzLmhlaWdodDtcclxuICAgICAgbGV0IGcgPSB0aGlzLm1hcmtlckNhbnZhcy5nZXRDb250ZXh0KFwiMmRcIik7XHJcbiAgICAgIGlmIChnKSB7XHJcbiAgICAgICAgZy5jbGVhclJlY3QoMCwgMCwgdywgaCk7XHJcbiAgICAgICAgaWYodGhpcy5fcGxheUZyYW1lUG9zaXRpb24pIHtcclxuICAgICAgICAgIGxldCBwaXhlbFBvcyA9IHRoaXMuZnJhbWVUb1ZpZXdQb3J0WFBpeGVsUG9zaXRpb24odGhpcy5fcGxheUZyYW1lUG9zaXRpb24pO1xyXG4gICAgICAgICAgaWYgKHBpeGVsUG9zKSB7XHJcbiAgICAgICAgICAgIGcuZmlsbFN0eWxlID0gJ3JlZCc7XHJcbiAgICAgICAgICAgIGcuc3Ryb2tlU3R5bGUgPSAncmVkJztcclxuICAgICAgICAgICAgZy5iZWdpblBhdGgoKTtcclxuICAgICAgICAgICAgZy5tb3ZlVG8ocGl4ZWxQb3MsIDApO1xyXG4gICAgICAgICAgICBnLmxpbmVUbyhwaXhlbFBvcywgaCk7XHJcbiAgICAgICAgICAgIGcuY2xvc2VQYXRoKCk7XHJcbiAgICAgICAgICAgIGcuc3Ryb2tlKCk7XHJcbiAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG4gICAgICB9XHJcbiAgICB9XHJcbiAgfVxyXG5cclxuICAvKlxyXG4gICAqICBNZXRob2QgdXNlZCBhcyB3b3JrZXIgY29kZS5cclxuICAgKi9cclxuICB3b3JrZXJGdW5jdGlvbigpIHtcclxuICAgIGFkZEV2ZW50TGlzdGVuZXIoJ21lc3NhZ2UnLCAoeyBkYXRhIH0pID0+IHtcclxuXHJcbiAgICAgIGNvbnN0IGF1ZGlvRGF0YSA9IGRhdGEuYXVkaW9EYXRhOyAvLyBhdWRpbyBkYXRhIHBhcnQgcmVxdWlyZWQgdG8gcmVuZGVyIHZpZXcgcG9ydFxyXG4gICAgICBjb25zdCBhdU9mZnNldDpudW1iZXI9ZGF0YS5hdWRpb0RhdGFPZmZzZXQ7XHJcbiAgICAgIGNvbnN0IGw9IGRhdGEubDsgLy8gbGVmdCBwaXhlbCBwb3NpdGlvbiBvZiB2aWV3IHBvcnRcclxuICAgICAgY29uc3QgdyA9IGRhdGEudzsgIC8vIHdpZHRoIG9mIHZpZXdwb3J0XHJcbiAgICAgIGNvbnN0IHZ3ID0gZGF0YS52dzsgLy8gIHRvdGFsIHdpZHRoIG9mICh2aXJ0dWFsKSBhdWRpbyB2aWV3IChub3Qgdmlld3BvcnQgd2lkdGgpXHJcbiAgICAgIGNvbnN0IGNocyA9IGRhdGEuY2hzOyAvLyBudW1iZXIgb2YgY2hhbm5lbHNcclxuICAgICAgLy9jb25zdCBkYXRhRnJhbWVMZW5ndGggPSBkYXRhLmF1ZGlvRGF0YUZyYW1lTGVuZ3RoOyAgLy8gZnJhbWUgbGVuZ3RoIG9mIGF1ZGlvIGRhdGEgcGFydCByZXF1aXJlZCBmb3IgdmlldyBwb3J0XHJcbiAgICAgIGNvbnN0IGZyYW1lTGVuZ3RoID0gZGF0YS5mcmFtZUxlbmd0aDsgIC8vIHRvdGFsIGZyYW1lIGxlbmd0aCAob2YgYXVkaW8gY2xpcClcclxuXHJcbiAgICAgIC8vY29uc29sZS5kZWJ1ZyhcIlc6IGxlZnQ6IFwiK2wrXCIsIHc6XCIrdytcIiwgdnc6IFwiK3Z3K1wiLCBjaHM6IFwiK2NocytcIiwgZnJhbWVMZW5ndGg6IFwiK2ZyYW1lTGVuZ3RoKTtcclxuXHJcbiAgICAgIGxldCBwc01pbk1heD0gbmV3IEZsb2F0MzJBcnJheSgwKTtcclxuXHJcbiAgICAgIGlmKGF1ZGlvRGF0YSAmJiBhdWRpb0RhdGEubGVuZ3RoPjAgJiYgdz49MCAmJiB2dz4wKSB7XHJcblxyXG4gICAgICAgIGNvbnN0IGZyYW1lc1BlclBpeGVsID0gZnJhbWVMZW5ndGggLyB2dztcclxuXHJcbiAgICAgICAgY29uc3QgcG9pbnRzTGVuID0gdyAqIGNocztcclxuICAgICAgICAvLyBvbmUgZm9yIG1pbiBvbmUgZm9yIG1heFxyXG4gICAgICAgIGNvbnN0IGFyckxlbiA9IHBvaW50c0xlbiAqIDI7XHJcbiAgICAgICAgcHNNaW5NYXggPSBuZXcgRmxvYXQzMkFycmF5KGFyckxlbik7XHJcbiAgICAgICAgbGV0IGNoRnJhbWVQb3MgPSAwO1xyXG4gICAgICAgIGNvbnN0IGNoRnJhbWVMZW5ndGg9YXVkaW9EYXRhLmxlbmd0aC9jaHM7XHJcbiAgICAgICAgZm9yIChsZXQgY2ggPSAwOyBjaCA8IGNoczsgY2grKykge1xyXG5cclxuICAgICAgICAgIGNoRnJhbWVQb3MgPSBjaCAqIGNoRnJhbWVMZW5ndGg7XHJcbiAgICAgICAgICBmb3IgKGxldCBwaWkgPSAwOyBwaWkgPCB3OyBwaWkrKykge1xyXG4gICAgICAgICAgICBjb25zdCB2aXJ0UGlpPWwrcGlpO1xyXG4gICAgICAgICAgICBsZXQgcE1pbiA9IEluZmluaXR5O1xyXG4gICAgICAgICAgICBsZXQgcE1heCA9IC1JbmZpbml0eTtcclxuICAgICAgICAgICAgbGV0IHBpeGVsRnJhbWVQb3MgPSBNYXRoLnJvdW5kKGNoRnJhbWVQb3MgKyAodmlydFBpaSAqIGZyYW1lc1BlclBpeGVsKSk7XHJcblxyXG4gICAgICAgICAgICAvLyBjYWxjdWxhdGUgcGl4ZWwgbWluL21heCBhbXBsaXR1ZGVcclxuICAgICAgICAgICAgZm9yIChsZXQgYWkgPSAwOyBhaSA8IGZyYW1lc1BlclBpeGVsOyBhaSsrKSB7XHJcbiAgICAgICAgICAgICAgY29uc3QgZnJhbWVQb3MgPSBwaXhlbEZyYW1lUG9zICsgYWk7XHJcbiAgICAgICAgICAgICAgbGV0IGEgPSAwO1xyXG4gICAgICAgICAgICAgIGNvbnN0IGJ1ZlBvcz1mcmFtZVBvcy1hdU9mZnNldDtcclxuICAgICAgICAgICAgICAvL2xldCBidWZQb3M9ZnJhbWVQb3M7XHJcbiAgICAgICAgICAgICAgaWYoYnVmUG9zPj0wICYmIGJ1ZlBvczxhdWRpb0RhdGEubGVuZ3RoKXtcclxuICAgICAgICAgICAgICAgIGE9YXVkaW9EYXRhW2J1ZlBvc107XHJcbiAgICAgICAgICAgICAgICAvL2NvbnNvbGUuZGVidWcoXCJXOiBjaDogXCIrY2grXCIsIHBpeGVsRnJhbWVQb3M6IFwiK3BpeGVsRnJhbWVQb3MrXCIsIGZyYW1lUG9zOiBcIitmcmFtZVBvcytcIiwgYXVPZmZzZXQ6IFwiK2F1T2Zmc2V0K1wiLCBidWZQb3M6IFwiK2J1ZlBvcytcIiwgYXVkaW9EYXRhLmxlbmd0aDogXCIrYXVkaW9EYXRhLmxlbmd0aCtcIiwgYTogXCIrYSk7XHJcbiAgICAgICAgICAgICAgICBpZiAoYSA8IHBNaW4pIHtcclxuICAgICAgICAgICAgICAgICAgcE1pbiA9IGE7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICBpZiAoYSA+IHBNYXgpIHtcclxuICAgICAgICAgICAgICAgICAgcE1heCA9IGE7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICBjb25zdCBwc01pblBvcyA9IGNoICogdyArIHBpaTtcclxuICAgICAgICAgICAgcHNNaW5NYXhbcHNNaW5Qb3NdID0gcE1pbjtcclxuICAgICAgICAgICAgY29uc3QgcHNNYXhQb3MgPSBwb2ludHNMZW4gKyBwc01pblBvcztcclxuICAgICAgICAgICAgcHNNaW5NYXhbcHNNYXhQb3NdID0gcE1heDtcclxuICAgICAgICAgICAgLy9jb25zb2xlLmRlYnVnKFwicHNNaW5NYXhbXCIrcHNNaW5Qb3MrXCJdPVwiK3BNaW4rXCIscHNNaW5NYXhbXCIrcHNNYXhQb3MrXCJdPVwiK3BNYXgpO1xyXG5cclxuICAgICAgICAgIH1cclxuICAgICAgICB9XHJcbiAgICAgIH1cclxuICAgICAgcG9zdE1lc3NhZ2Uoe3BzTWluTWF4OiBwc01pbk1heCwgbDpkYXRhLmwsdzogZGF0YS53LCBjaHM6IGRhdGEuY2hzLGVvZDpkYXRhLmVvZH0sIFtwc01pbk1heC5idWZmZXJdKTtcclxuICAgIH0pXHJcbiAgfVxyXG5cclxuXHJcblxyXG4gIHN0YXJ0RHJhdyhjbGVhciA9IHRydWUpIHtcclxuICAgIGlmIChjbGVhcikge1xyXG4gICAgICBpZih0aGlzLmJvdW5kcykge1xyXG4gICAgICAgIHRoaXMuc2lnbmFsQ2FudmFzLnN0eWxlLmxlZnQgPSBNYXRoLnJvdW5kKHRoaXMuYm91bmRzLnBvc2l0aW9uLmxlZnQpLnRvU3RyaW5nKCkgKyAncHgnO1xyXG4gICAgICAgIHRoaXMuc2lnbmFsQ2FudmFzLndpZHRoID0gTWF0aC5yb3VuZCh0aGlzLmJvdW5kcy5kaW1lbnNpb24ud2lkdGgpO1xyXG4gICAgICAgIHRoaXMuc2lnbmFsQ2FudmFzLmhlaWdodCA9IE1hdGgucm91bmQodGhpcy5ib3VuZHMuZGltZW5zaW9uLmhlaWdodCk7XHJcblxyXG4gICAgICAgIGxldCBnID0gdGhpcy5zaWduYWxDYW52YXMuZ2V0Q29udGV4dChcIjJkXCIpO1xyXG4gICAgICAgIGlmIChnKSB7XHJcbiAgICAgICAgICAvL2cuY2xlYXJSZWN0KDAsIDAsdywgaCk7XHJcbiAgICAgICAgICBnLmZpbGxTdHlsZSA9IFwiYmxhY2tcIjtcclxuICAgICAgICAgIGcuZmlsbFJlY3QoMCwgMCwgTWF0aC5yb3VuZCh0aGlzLmJvdW5kcy5kaW1lbnNpb24ud2lkdGgpLCBNYXRoLnJvdW5kKHRoaXMuYm91bmRzLmRpbWVuc2lvbi5oZWlnaHQpKTtcclxuICAgICAgICB9XHJcbiAgICAgIH1cclxuICAgIH1cclxuICAgIHRoaXMuc3RhcnRSZW5kZXIoKTtcclxuICAgIHRoaXMuZHJhd0N1cnNvckxheWVyKClcclxuICB9XHJcblxyXG5cclxuICBwcml2YXRlIHN0YXJ0UmVuZGVyKCkge1xyXG5cclxuICAgIGlmICh0aGlzLndvcmtlcikge1xyXG4gICAgICB0aGlzLndvcmtlci50ZXJtaW5hdGUoKTtcclxuICAgICAgdGhpcy53b3JrZXIgPSBudWxsO1xyXG4gICAgfVxyXG4gICAgaWYodGhpcy5yYUFzU3Vic2Mpe1xyXG4gICAgICB0aGlzLnJhQXNTdWJzYy51bnN1YnNjcmliZSgpO1xyXG4gICAgfVxyXG4gICAgICBpZiAodGhpcy5fYXVkaW9EYXRhSG9sZGVyKSB7XHJcbiAgICAgICAgdGhpcy5fYXVkaW9EYXRhSG9sZGVyLmFkZE9uUmVhZHlMaXN0ZW5lcigoKT0+e1xyXG4gICAgICAgICAgaWYodGhpcy5fYXVkaW9EYXRhSG9sZGVyICYmIHRoaXMuYm91bmRzICYmIHRoaXMuYm91bmRzLmRpbWVuc2lvbikge1xyXG4gICAgICAgICAgICBsZXQgdyA9IE1hdGgucm91bmQodGhpcy5ib3VuZHMuZGltZW5zaW9uLndpZHRoKTtcclxuICAgICAgICAgICAgbGV0IGggPSBNYXRoLnJvdW5kKHRoaXMuYm91bmRzLmRpbWVuc2lvbi5oZWlnaHQpO1xyXG4gICAgICAgICAgICBsZXQgdncgPSBNYXRoLnJvdW5kKHRoaXMudmlydHVhbERpbWVuc2lvbi53aWR0aCk7XHJcblxyXG4gICAgICAgICAgICBpZiAodyA+IDAgJiYgaCA+IDAgJiYgdncgPiAwKSB7XHJcblxyXG4gICAgICAgICAgICAgIC8vdGhpcy53byA9IG5ldyBXb3JrZXIoJy4vYXVkaW9zaWduYWwud29ya2VyLmpzJyx7dHlwZTogJ21vZHVsZSd9KTtcclxuICAgICAgICAgICAgICB0aGlzLndvcmtlciA9IG5ldyBXb3JrZXIodGhpcy53b3JrZXJVUkwpO1xyXG4gICAgICAgICAgICAgIC8vdGhpcy53byA9IG5ldyBXb3JrZXIoJ3dvcmtlci9hdWRpb3NpZ25hbC53b3JrZXIudHMnKTtcclxuXHJcbiAgICAgICAgICAgICAgLy9sZXQgV29ya2VyID0gcmVxdWlyZSgnd29ya2VyIS4uLy4uLy4uL3dvcmtlcnMvdXBsb2FkZXIvbWFpbicpO1xyXG4gICAgICAgICAgICAgIGxldCBjaHMgPSB0aGlzLl9hdWRpb0RhdGFIb2xkZXIubnVtYmVyT2ZDaGFubmVscztcclxuICAgICAgICAgICAgICBsZXQgbGVmdFBvcyA9IE1hdGgucm91bmQodGhpcy5ib3VuZHMucG9zaXRpb24ubGVmdCk7XHJcbiAgICAgICAgICAgICAgbGV0IHJlbmRlclBvcyA9IGxlZnRQb3M7XHJcblxyXG4gICAgICAgICAgICAgIGxldCBmcmFtZUxlbmd0aCA9IHRoaXMuX2F1ZGlvRGF0YUhvbGRlci5mcmFtZUxlbjtcclxuICAgICAgICAgICAgICBsZXQgZnJhbWVzUGVyUGl4ZWwgPSBNYXRoLmNlaWwoZnJhbWVMZW5ndGggLyB2dyk7XHJcbiAgICAgICAgICAgICAgLy9jb25zb2xlLmRlYnVnKFwiQ2hzOiBcIiArIGNocyArIFwiLCB2dzogXCIgKyB2dyArIFwiLCBmcmFtZUxlbmd0aDogXCIgKyBmcmFtZUxlbmd0aCArIFwiLCBmcmFtZXNQZXJQaXhlbDogXCIgKyBmcmFtZXNQZXJQaXhlbCk7XHJcbiAgICAgICAgICAgICAgbGV0IGFkOiBGbG9hdDMyQXJyYXkgPSBuZXcgRmxvYXQzMkFycmF5KGNocyAqIGZyYW1lc1BlclBpeGVsKTtcclxuICAgICAgICAgICAgICBsZXQgcmFBcyA9IHRoaXMuX2F1ZGlvRGF0YUhvbGRlci5yYW5kb21BY2Nlc3NBdWRpb1N0cmVhbSgpO1xyXG4gICAgICAgICAgICAgIGxldCBhdWRpb0J1ZmZlcjogQXVkaW9CdWZmZXIgfCBudWxsID0gbnVsbDtcclxuICAgICAgICAgICAgICBsZXQgYXVkaW9Tb3VyY2UgPSB0aGlzLl9hdWRpb0RhdGFIb2xkZXIuYXVkaW9Tb3VyY2U7XHJcbiAgICAgICAgICAgICAgaWYgKGF1ZGlvU291cmNlIGluc3RhbmNlb2YgQXVkaW9CdWZmZXJTb3VyY2UpIHtcclxuICAgICAgICAgICAgICAgIGF1ZGlvQnVmZmVyID0gYXVkaW9Tb3VyY2UuYXVkaW9CdWZmZXI7XHJcbiAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgIC8vbGV0IGFycmF5QXVkaW9CdWZmZXI9dGhpcy5fYXVkaW9EYXRhSG9sZGVyLmFycmF5QnVmZmVyO1xyXG4gICAgICAgICAgICAgIGxldCBhcnJBYkJ1ZjogRmxvYXQzMkFycmF5W10gfCBudWxsO1xyXG5cclxuICAgICAgICAgICAgICAvL2xldCBhaXM6QXJyYXlBdWRpb0J1ZmZlcklucHV0U3RyZWFtfG51bGw9bnVsbDtcclxuICAgICAgICAgICAgICAvL2xldCBhaXNCdWY6RmxvYXQzMkFycmF5W118bnVsbD1udWxsO1xyXG4gICAgICAgICAgICAgIGxldCBwc01pbk1heDogRmxvYXQzMkFycmF5IHwgbnVsbCA9IG51bGw7XHJcblxyXG4gICAgICAgICAgICAgIGlmICh0aGlzLndvcmtlcikge1xyXG4gICAgICAgICAgICAgICAgdGhpcy53b3JrZXIub25tZXNzYWdlID0gKG1lKSA9PiB7XHJcbiAgICAgICAgICAgICAgICAgIGlmIChtZS5kYXRhLmVvZCA9PT0gdHJ1ZSkge1xyXG4gICAgICAgICAgICAgICAgICAgIGxldCBwc01pbk1heFRtcDtcclxuICAgICAgICAgICAgICAgICAgICBpZiAocHNNaW5NYXgpIHtcclxuICAgICAgICAgICAgICAgICAgICAgIHBzTWluTWF4VG1wID0gcHNNaW5NYXg7XHJcbiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgICAgICAgICAgIHBzTWluTWF4VG1wID0gbWUuZGF0YS5wc01pbk1heDtcclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5kcmF3UmVuZGVyZWQobGVmdFBvcywgdywgaCwgY2hzLCBwc01pbk1heFRtcCk7XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKHRoaXMud29ya2VyKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICB0aGlzLndvcmtlci50ZXJtaW5hdGUoKTtcclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgcmFBcy5jbG9zZSgpO1xyXG4gICAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKHRoaXMuX2F1ZGlvRGF0YUhvbGRlciAmJiBhcnJBYkJ1Zikge1xyXG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IHJ3ID0gbWUuZGF0YS53O1xyXG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IHJQb2ludHNMZW4gPSBjaHMgKiBydztcclxuICAgICAgICAgICAgICAgICAgICBjb25zdCBwb2ludHNMZW4gPSBjaHMgKiB3O1xyXG4gICAgICAgICAgICAgICAgICAgIGZvciAobGV0IGNoID0gMDsgY2ggPCBjaHM7IGNoKyspIHtcclxuICAgICAgICAgICAgICAgICAgICAgIGlmIChwc01pbk1heCkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBsZXQgckJhc2VQb3MgPSBjaCAqIHJ3O1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBsZXQgYmFzZVBvcyA9IGNoICogdztcclxuICAgICAgICAgICAgICAgICAgICAgICAgbGV0IHJQb3NNaW4gPSByQmFzZVBvcztcclxuICAgICAgICAgICAgICAgICAgICAgICAgbGV0IHJQb3NNYXggPSByUG9pbnRzTGVuICsgclBvc01pbjtcclxuICAgICAgICAgICAgICAgICAgICAgICAgbGV0IHBvc01pbiA9IGJhc2VQb3MgKyAocmVuZGVyUG9zIC0gbGVmdFBvcyk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGxldCBwb3NNYXggPSBwb2ludHNMZW4gKyBwb3NNaW47XHJcblxyXG4gICAgICAgICAgICAgICAgICAgICAgICBwc01pbk1heFtwb3NNaW5dID0gbWUuZGF0YS5wc01pbk1heFtyUG9zTWluXTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgLy9jb25zb2xlLmRlYnVnKCdNaW46ICgnK3Bvc01pbisnKTogJyttZS5kYXRhLnBzTWluTWF4W3JQb3NNaW5dKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgcHNNaW5NYXhbcG9zTWF4XSA9IG1lLmRhdGEucHNNaW5NYXhbclBvc01heF07XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIC8vY29uc29sZS5kZWJ1ZygnTWF4OiAoJysocG9zTWF4KSsnKTogJyttZS5kYXRhLnBzTWluTWF4W3JQb3NNYXhdKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgLy9jb25zb2xlLmRlYnVnKFwicHNNaW5NYXhbXCIrcG9zTWluK1wiXT1cIittZS5kYXRhLnBzTWluTWF4W3JQb3NNaW5dK1wiICAoclBvc01pbj1cIityUG9zTWluK1wiKSxwc01pbk1heFtcIitwb3NNYXgrXCJdPVwiK21lLmRhdGEucHNNaW5NYXhbclBvc01heF0pO1xyXG4gICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICBsZXQgZW9kID0gZmFsc2U7XHJcbiAgICAgICAgICAgICAgICAgICAgcmVuZGVyUG9zKys7XHJcbiAgICAgICAgICAgICAgICAgICAgLy9sZXQgYWQ6RmxvYXQzMkFycmF5O1xyXG5cclxuICAgICAgICAgICAgICAgICAgICBjb25zdCBsZWZ0RnJhbWVQb3MgPSBNYXRoLmZsb29yKGZyYW1lTGVuZ3RoICogcmVuZGVyUG9zIC8gdncpO1xyXG4gICAgICAgICAgICAgICAgICAgIGlmIChyZW5kZXJQb3MgPCBsZWZ0UG9zICsgdykge1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHJhQXNPYnMgPSByYUFzLmZyYW1lc09icyhsZWZ0RnJhbWVQb3MsIGZyYW1lc1BlclBpeGVsLCBhcnJBYkJ1ZilcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICB0aGlzLnJhQXNTdWJzYyA9IHJhQXNPYnMuc3Vic2NyaWJlKFxyXG4gICAgICAgICAgICAgICAgICAgICAgICB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgbmV4dDogKHJlYWQpID0+IHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vY29uc29sZS5kZWJ1ZyhcIkZpcnN0IHJlYWQgZnJhbWU6IFwiK2FyckFiQnVmWzBdWzBdKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChhcnJBYkJ1Zikge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBhZExlbiA9IGNocyAqIGZyYW1lc1BlclBpeGVsO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoIWFkIHx8IGFkLmxlbmd0aCAhPT0gYWRMZW4pIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhZCA9IG5ldyBGbG9hdDMyQXJyYXkoYWRMZW4pO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZvciAobGV0IGNoID0gMDsgY2ggPCBjaHM7IGNoKyspIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhZC5zZXQoYXJyQWJCdWZbY2hdLCBjaCAqIGZyYW1lc1BlclBpeGVsKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgZW9kID0gKHJlYWQgPD0gMCk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBsZXQgYWRCdWYgPSBhZC5idWZmZXI7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAodGhpcy53b3JrZXIpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy53b3JrZXIucG9zdE1lc3NhZ2Uoe1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGw6IHJlbmRlclBvcyxcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB3OiBtZS5kYXRhLncsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaDogaCxcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2dzogdncsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2hzOiBjaHMsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZnJhbWVMZW5ndGg6IGZyYW1lTGVuZ3RoLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGF1ZGlvRGF0YTogYWQsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYXVkaW9EYXRhT2Zmc2V0OiBsZWZ0RnJhbWVQb3MsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZW9kOiBlb2RcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfSwgW2FkQnVmXSk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgfSxcclxuICAgICAgICAgICAgICAgICAgICAgICAgICBlcnJvcjogKGVycikgPT4ge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc29sZS5lcnJvcihcIkF1ZGlvU2lnbmFsOiBFcnJvciByZWFkaW5nIGF1ZGlvIGRhdGE6IFwiICsgZXJyKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICAgIClcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgICAgICAgICAgIGFkID0gbmV3IEZsb2F0MzJBcnJheSgpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgZW9kID0gdHJ1ZTtcclxuICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGFkQnVmID0gYWQuYnVmZmVyO1xyXG4gICAgICAgICAgICAgICAgICAgICAgaWYgKHRoaXMud29ya2VyKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMud29ya2VyLnBvc3RNZXNzYWdlKHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICBsOiByZW5kZXJQb3MsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgdzogbWUuZGF0YS53LFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgIGg6IGgsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgdnc6IHZ3LFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgIGNoczogY2hzLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgIGZyYW1lTGVuZ3RoOiBmcmFtZUxlbmd0aCxcclxuICAgICAgICAgICAgICAgICAgICAgICAgICBhdWRpb0RhdGE6IGFkLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgIGF1ZGlvRGF0YU9mZnNldDogbGVmdEZyYW1lUG9zLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgIGVvZDogZW9kXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH0sIFthZEJ1Zl0pO1xyXG4gICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgICAgaWYgKGF1ZGlvQnVmZmVyICYmIGF1ZGlvQnVmZmVyLmxlbmd0aCAqIGF1ZGlvQnVmZmVyLm51bWJlck9mQ2hhbm5lbHMgPCBBdWRpb0NhbnZhc0xheWVyQ29tcG9uZW50LkVOQUJMRV9TVFJFQU1JTkdfTlVNQkVSX09GX1NBTVBMRVNfVEhSRVNIT0xEKSB7XHJcblxyXG4gICAgICAgICAgICAgICAgLy8gUmVuZGVyIHdob2xlIGNsaXAgYXQgb25jZVxyXG4gICAgICAgICAgICAgICAgYXJyQWJCdWYgPSBudWxsO1xyXG4gICAgICAgICAgICAgICAgcHNNaW5NYXggPSBudWxsO1xyXG4gICAgICAgICAgICAgICAgY29uc3QgYWQgPSBuZXcgRmxvYXQzMkFycmF5KGNocyAqIGZyYW1lTGVuZ3RoKTtcclxuICAgICAgICAgICAgICAgIGZvciAobGV0IGNoID0gMDsgY2ggPCBjaHM7IGNoKyspIHtcclxuICAgICAgICAgICAgICAgICAgYWQuc2V0KGF1ZGlvQnVmZmVyLmdldENoYW5uZWxEYXRhKGNoKSwgY2ggKiBmcmFtZUxlbmd0aCk7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICB0aGlzLndvcmtlci5wb3N0TWVzc2FnZSh7XHJcbiAgICAgICAgICAgICAgICAgIGw6IGxlZnRQb3MsXHJcbiAgICAgICAgICAgICAgICAgIHc6IHcsXHJcbiAgICAgICAgICAgICAgICAgIHZ3OiB2dyxcclxuICAgICAgICAgICAgICAgICAgY2hzOiBjaHMsXHJcbiAgICAgICAgICAgICAgICAgIGZyYW1lTGVuZ3RoOiBmcmFtZUxlbmd0aCxcclxuICAgICAgICAgICAgICAgICAgYXVkaW9EYXRhOiBhZCxcclxuICAgICAgICAgICAgICAgICAgYXVkaW9EYXRhT2Zmc2V0OiAwLFxyXG4gICAgICAgICAgICAgICAgICBlb2Q6IHRydWVcclxuICAgICAgICAgICAgICAgIH0sIFthZC5idWZmZXJdKTtcclxuXHJcbiAgICAgICAgICAgICAgfSBlbHNlIHtcclxuXHJcbiAgICAgICAgICAgICAgICAvLyBSZW5kZXIgcGl4ZWwgYnkgcGl4ZWxcclxuICAgICAgICAgICAgICAgIGlmICh3ID4gMCkge1xyXG5cclxuICAgICAgICAgICAgICAgICAgaWYgKGZyYW1lc1BlclBpeGVsID4gMCkge1xyXG4gICAgICAgICAgICAgICAgICAgIGxldCBydyA9IDE7XHJcbiAgICAgICAgICAgICAgICAgICAgYXJyQWJCdWYgPSBuZXcgQXJyYXk8RmxvYXQzMkFycmF5PihjaHMpO1xyXG4gICAgICAgICAgICAgICAgICAgIHBzTWluTWF4ID0gbmV3IEZsb2F0MzJBcnJheShjaHMgKiB3ICogMik7XHJcbiAgICAgICAgICAgICAgICAgICAgLy9jb25zb2xlLmRlYnVnKFwiQXVkaW9zaWduYWw6IEFsbG9jYXRpbmcgYnVmZmVyczogXCIrZnJhbWVzUGVyUGl4ZWwpO1xyXG4gICAgICAgICAgICAgICAgICAgIGZvciAobGV0IGNoID0gMDsgY2ggPCBjaHM7IGNoKyspIHtcclxuICAgICAgICAgICAgICAgICAgICAgIGFyckFiQnVmW2NoXSA9IG5ldyBGbG9hdDMyQXJyYXkoZnJhbWVzUGVyUGl4ZWwpO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICBjb25zdCBsZWZ0RnJhbWVQb3MgPSBNYXRoLmZsb29yKGZyYW1lTGVuZ3RoICogcmVuZGVyUG9zIC8gdncpO1xyXG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IGF1T2Zmc2V0ID0gbGVmdEZyYW1lUG9zOyAvLyBzaG91bGQgYWx3YXlzIGJlIDBcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgcmFBc09icyA9IHJhQXMuZnJhbWVzT2JzKGxlZnRGcmFtZVBvcywgZnJhbWVzUGVyUGl4ZWwsIGFyckFiQnVmKTtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5kcmF3U3RhdGVUZXh0KFwiTG9hZGluZy9SZW5kZXJpbmcuLi5cIik7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgIHRoaXMucmFBc1N1YnNjID0gcmFBc09icy5zdWJzY3JpYmUoXHJcbiAgICAgICAgICAgICAgICAgICAgICB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIG5leHQ6IChyZWFkKSA9PiB7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChhcnJBYkJ1ZiAmJiB0aGlzLndvcmtlcikge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgYWRMZW4gPSBjaHMgKiBmcmFtZXNQZXJQaXhlbDtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICghYWQgfHwgYWQubGVuZ3RoICE9PSBhZExlbikge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhZCA9IG5ldyBGbG9hdDMyQXJyYXkoYWRMZW4pO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgZm9yIChsZXQgY2ggPSAwOyBjaCA8IGNoczsgY2grKykge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhZC5zZXQoYXJyQWJCdWZbY2hdLCBjaCAqIGZyYW1lc1BlclBpeGVsKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLndvcmtlci5wb3N0TWVzc2FnZSh7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGw6IHJlbmRlclBvcyxcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdzogcncsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZ3OiB2dyxcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2hzOiBjaHMsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZyYW1lTGVuZ3RoOiBmcmFtZUxlbmd0aCxcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYXVkaW9EYXRhOiBhZCxcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYXVkaW9EYXRhT2Zmc2V0OiBhdU9mZnNldCxcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZW9kOiAocmVhZCA8PSAwKVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfSwgW2FkLmJ1ZmZlcl0pO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICAgICAgfSxcclxuICAgICAgICAgICAgICAgICAgICAgICAgZXJyb3I6IChlcnIpID0+IHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zb2xlLmVycm9yKFwiQXVkaW9TaWduYWw6IEVycm9yIHJlYWRpbmcgYXVkaW8gZGF0YTogXCIgKyBlcnIpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgKTtcclxuICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgfVxyXG4gICAgICAgIH0pO1xyXG4gICAgICB9IGVsc2Uge1xyXG4gICAgICAgIGlmICh0aGlzLmJvdW5kcyAmJiB0aGlzLmJvdW5kcy5kaW1lbnNpb24pIHtcclxuICAgICAgICAgIGxldCB3ID0gTWF0aC5yb3VuZCh0aGlzLmJvdW5kcy5kaW1lbnNpb24ud2lkdGgpO1xyXG4gICAgICAgICAgbGV0IGggPSBNYXRoLnJvdW5kKHRoaXMuYm91bmRzLmRpbWVuc2lvbi5oZWlnaHQpO1xyXG4gICAgICAgICAgbGV0IGcgPSB0aGlzLnNpZ25hbENhbnZhcy5nZXRDb250ZXh0KFwiMmRcIik7XHJcbiAgICAgICAgICBpZiAoZykge1xyXG4gICAgICAgICAgICBnLmNsZWFyUmVjdCgwLCAwLCB3LCBoKTtcclxuICAgICAgICAgIH1cclxuICAgICAgICB9XHJcbiAgICAgIH1cclxuXHJcbiAgfVxyXG5cclxuZHJhd1N0YXRlVGV4dChzdGF0ZVRleHQ6c3RyaW5nKSB7XHJcbiAgICBpZihzdGF0ZVRleHQpIHtcclxuICAgICAgY29uc3QgZyA9IHRoaXMuc2lnbmFsQ2FudmFzLmdldENvbnRleHQoXCIyZFwiKTtcclxuICAgICAgY29uc3Qgdz10aGlzLnNpZ25hbENhbnZhcy53aWR0aDtcclxuICAgICAgY29uc3QgaD10aGlzLnNpZ25hbENhbnZhcy5oZWlnaHQ7XHJcbiAgICAgIGlmIChnICYmIHcgJiYgaCkge1xyXG4gICAgICAgIGcuc3Ryb2tlU3R5bGUgPSAnd2hpdGUnO1xyXG4gICAgICAgIGcuZmlsbFN0eWxlID0gJ3doaXRlJztcclxuICAgICAgICBnLmZvbnQgPSAnMjBweCBzYW5zLXNlcmlmJztcclxuICAgICAgICBnLmZpbGxUZXh0KHN0YXRlVGV4dCwgMTAsIDI1KTtcclxuICAgICAgfVxyXG4gICAgfVxyXG59XHJcbiAgZHJhd1JlbmRlcmVkKGxlZnQ6bnVtYmVyLHc6bnVtYmVyLGg6bnVtYmVyLGNoczpudW1iZXIscHNNaW5NYXg6RmxvYXQzMkFycmF5KSB7XHJcbiAgICB0aGlzLmRyYXdCZygpO1xyXG4gICAgdGhpcy5zaWduYWxDYW52YXMuc3R5bGUubGVmdD1sZWZ0LnRvU3RyaW5nKCkrJ3B4JztcclxuICAgIHRoaXMuc2lnbmFsQ2FudmFzLndpZHRoID0gdztcclxuICAgIHRoaXMuc2lnbmFsQ2FudmFzLmhlaWdodCA9IGg7XHJcbiAgICBsZXQgZyA9IHRoaXMuc2lnbmFsQ2FudmFzLmdldENvbnRleHQoXCIyZFwiKTtcclxuICAgIGlmIChnKSB7XHJcbiAgICAgIGcuY2xlYXJSZWN0KDAsIDAsIHcsIGgpO1xyXG4gICAgICBsZXQgcG9pbnRzTGVuID0gdyAqIGNocztcclxuICAgICAgLy8gb25lIGZvciBtaW4gb25lIGZvciBtYXhcclxuICAgICAgLy9jb25zdCBhcnJMZW4gPSBwb2ludHNMZW4gKiAyO1xyXG4gICAgICBpZiAodGhpcy5fYXVkaW9EYXRhSG9sZGVyKSB7XHJcbiAgICAgICAgLy9jb25zdCBzdGQgPSBEYXRlLm5vdygpO1xyXG5cclxuICAgICAgICBjb25zdCBjaEggPSBoIC8gY2hzO1xyXG5cclxuICAgICAgICBsZXQgeSA9IDA7XHJcbiAgICAgICAgZm9yIChsZXQgY2ggPSAwOyBjaCA8IGNoczsgY2grKykge1xyXG4gICAgICAgICAgY29uc3QgcHNNaW5Qb3MgPSBjaCAqIHc7XHJcbiAgICAgICAgICBjb25zdCBwc01heFBvcyA9IHBvaW50c0xlbiArIHBzTWluUG9zO1xyXG5cclxuICAgICAgICAgIGcuZmlsbFN0eWxlID0gJ2dyZWVuJztcclxuICAgICAgICAgIGcuc3Ryb2tlU3R5bGUgPSAnZ3JlZW4nO1xyXG5cclxuICAgICAgICAgIC8vIGRyYXcgYXVkaW8gc2lnbmFsIGFzIHNpbmdsZSBwb2x5Z29uXHJcbiAgICAgICAgICBnLmJlZ2luUGF0aCgpO1xyXG4gICAgICAgICAgZy5tb3ZlVG8oMCwgeSArIChjaEggLyAyKSArIHBzTWluTWF4W3BzTWF4UG9zXSAqIGNoSCAvIDIpO1xyXG5cclxuICAgICAgICAgIGZvciAobGV0IHBpaSA9IDA7IHBpaSA8IHc7IHBpaSsrKSB7XHJcbiAgICAgICAgICAgIGNvbnN0IHBzTWF4ID0gcHNNaW5NYXhbcHNNYXhQb3MgKyBwaWldO1xyXG4gICAgICAgICAgICBjb25zdCBwdiA9IHBzTWF4ICogY2hIIC8gMjtcclxuICAgICAgICAgICAgY29uc3QgeWQ9eSArIChjaEggLyAyKSAtIHB2O1xyXG4gICAgICAgICAgICAvL2NvbnNvbGUubG9nKFwiTGluZVRvOiA6IFwiK3BpaStcIiBcIit5ZClcclxuICAgICAgICAgICAgZy5saW5lVG8ocGlpLCB5ZCk7XHJcbiAgICAgICAgICB9XHJcbiAgICAgICAgICBjb25zdCByZXZQaXhlbFN0YXJ0PXctMTtcclxuXHJcbiAgICAgICAgICBmb3IgKGxldCBwaWkgPSByZXZQaXhlbFN0YXJ0OyBwaWkgPj0gMDsgcGlpLS0pIHtcclxuICAgICAgICAgICAgY29uc3QgcHNNaW4gPSBwc01pbk1heFtwc01pblBvcyArIHBpaV07XHJcbiAgICAgICAgICAgIGNvbnN0IHB2ID0gcHNNaW4gKiBjaEggLyAyO1xyXG4gICAgICAgICAgICBjb25zdCB5ZD15ICsgKGNoSCAvIDIpIC0gcHY7XHJcbiAgICAgICAgICAgIC8vY29uc29sZS5sb2coXCJMaW5lVG86IDogXCIrcGlpK1wiIFwiK3lkKVxyXG4gICAgICAgICAgICBnLmxpbmVUbyhwaWksIHlkKTtcclxuICAgICAgICAgIH1cclxuICAgICAgICAgIGcuY2xvc2VQYXRoKCk7XHJcblxyXG4gICAgICAgICAgZy5maWxsKCk7XHJcbiAgICAgICAgICBnLnN0cm9rZSgpO1xyXG4gICAgICAgICAgeSArPSBjaEg7XHJcbiAgICAgICAgfVxyXG4gICAgICB9XHJcbiAgICB9XHJcbiAgfVxyXG5cclxuICAvLyByZWRyYXcoKSB7XHJcbiAgLy8gICB0aGlzLmRyYXdCZygpXHJcbiAgLy8gICBsZXQgZyA9IHRoaXMuc2lnbmFsQ2FudmFzLmdldENvbnRleHQoXCIyZFwiKTtcclxuICAvLyAgIGlmIChnKSB7XHJcbiAgLy8gICAgIGxldCB3ID0gdGhpcy5zaWduYWxDYW52YXMud2lkdGg7XHJcbiAgLy8gICAgIGxldCBoID0gdGhpcy5zaWduYWxDYW52YXMuaGVpZ2h0O1xyXG4gIC8vICAgICBnLmNsZWFyUmVjdCgwLCAwLCB3LCBoKTtcclxuICAvLyAgICAgLy9nLmZpbGxTdHlsZSA9IFwiYmxhY2tcIjtcclxuICAvLyAgICAgLy9nLmZpbGxSZWN0KDAsIDAsIHcsIGgpO1xyXG4gIC8vICAgICBpZiAodGhpcy5fYXVkaW9EYXRhSG9sZGVyKSB7XHJcbiAgLy8gICAgICAgbGV0IHN0ZCA9IERhdGUubm93KCk7XHJcbiAgLy8gICAgICAgbGV0IGNocyA9IHRoaXMuX2F1ZGlvRGF0YUhvbGRlci5udW1iZXJPZkNoYW5uZWxzO1xyXG4gIC8vICAgICAgIGxldCBjaEggPSBoIC8gY2hzO1xyXG4gIC8vXHJcbiAgLy8gICAgICAgbGV0IGZyYW1lTGVuZ3RoID0gdGhpcy5fYXVkaW9EYXRhSG9sZGVyLmZyYW1lTGVuO1xyXG4gIC8vXHJcbiAgLy8gICAgICAgbGV0IGZyYW1lc1BlclBpeGVsID0gZnJhbWVMZW5ndGggLyB3O1xyXG4gIC8vICAgICAgIGxldCB5ID0gMDtcclxuICAvLyAgICAgICBsZXQgYWlzOkZsb2F0MzJBcnJheUlucHV0U3RyZWFtfG51bGw9bnVsbDtcclxuICAvLyAgICAgICBsZXQgYXVkaW9Tb3VyY2U9dGhpcy5fYXVkaW9EYXRhSG9sZGVyLmF1ZGlvU291cmNlO1xyXG4gIC8vICAgICAgIGxldCBhdWRpb0J1ZmZlcjpBdWRpb0J1ZmZlcnxudWxsPW51bGw7XHJcbiAgLy8gICAgICAgaWYoYXVkaW9Tb3VyY2UgaW5zdGFuY2VvZiBBdWRpb0J1ZmZlclNvdXJjZSl7XHJcbiAgLy8gICAgICAgICBhdWRpb0J1ZmZlcj1hdWRpb1NvdXJjZS5hdWRpb0J1ZmZlcjtcclxuICAvLyAgICAgICB9XHJcbiAgLy8gICAgICAgbGV0IGFpc0J1ZmZlcjpBcnJheTxGbG9hdDMyQXJyYXk+fG51bGw9bnVsbDtcclxuICAvLyAgICAgICBpZighYXVkaW9CdWZmZXIpIHtcclxuICAvLyAgICAgICAgIGFpcz10aGlzLl9hdWRpb0RhdGFIb2xkZXIuYXVkaW9JbnB1dFN0cmVhbSgpO1xyXG4gIC8vICAgICAgICAgYWlzQnVmZmVyPW5ldyBBcnJheTxGbG9hdDMyQXJyYXk+KGNocyk7XHJcbiAgLy8gICAgICAgICBmb3IobGV0IGNoPTA7Y2g8Y2hzO2NoKyspIHtcclxuICAvLyAgICAgICAgICAgYWlzQnVmZmVyW2NoXSA9IG5ldyBGbG9hdDMyQXJyYXkoZnJhbWVzUGVyUGl4ZWwpO1xyXG4gIC8vICAgICAgICAgfVxyXG4gIC8vICAgICAgIH1cclxuICAvLyAgICAgICAgIGZvciAobGV0IGNoID0gMDsgY2ggPCBjaHM7IGNoKyspIHtcclxuICAvLyAgICAgICAgICAgbGV0IHggPSAwO1xyXG4gIC8vICAgICAgICAgICBsZXQgcHNNaW4gPSBuZXcgRmxvYXQzMkFycmF5KHcpO1xyXG4gIC8vICAgICAgICAgICBsZXQgcHNNYXggPSBuZXcgRmxvYXQzMkFycmF5KHcpO1xyXG4gIC8vICAgICAgICAgICBsZXQgZnJhbWVQb3MgPSAwO1xyXG4gIC8vICAgICAgICAgICBmb3IgKGxldCBwaWkgPSAwOyBwaWkgPCB3OyBwaWkrKykge1xyXG4gIC8vICAgICAgICAgICAgIGxldCBwTWluID0gMDtcclxuICAvLyAgICAgICAgICAgICBsZXQgcE1heCA9IDA7XHJcbiAgLy9cclxuICAvLyAgICAgICAgICAgICBpZiAoYXVkaW9CdWZmZXIpe1xyXG4gIC8vICAgICAgICAgICAgICAgLy8gY2FsY3VsYXRlIHBpeGVsIG1pbi9tYXggYW1wbGl0dWRlXHJcbiAgLy8gICAgICAgICAgICAgICBmb3IgKGxldCBhaSA9IDA7IGFpIDwgZnJhbWVzUGVyUGl4ZWw7IGFpKyspIHtcclxuICAvLyAgICAgICAgICAgICAgICAgLy9sZXQgZnJhbWVQb3M9KHBpaSpmcmFtZXNQZXJQaXhlbCkrYWk7XHJcbiAgLy8gICAgICAgICAgICAgICAgIGxldCBhID0gYXVkaW9CdWZmZXIuZ2V0Q2hhbm5lbERhdGEoY2gpW2ZyYW1lUG9zKytdO1xyXG4gIC8vXHJcbiAgLy8gICAgICAgICAgICAgICAgIGlmIChhIDwgcE1pbikge1xyXG4gIC8vICAgICAgICAgICAgICAgICAgIHBNaW4gPSBhO1xyXG4gIC8vICAgICAgICAgICAgICAgICB9XHJcbiAgLy8gICAgICAgICAgICAgICAgIGlmIChhID4gcE1heCkge1xyXG4gIC8vICAgICAgICAgICAgICAgICAgIHBNYXggPSBhO1xyXG4gIC8vICAgICAgICAgICAgICAgICB9XHJcbiAgLy8gICAgICAgICAgICAgICB9XHJcbiAgLy8gICAgICAgICAgIH1lbHNlIGlmKGFpcyAmJiBhaXNCdWZmZXIpIHtcclxuICAvLyAgICAgICAgICAgICAgIGxldCByID0gYWlzLnJlYWQoYWlzQnVmZmVyKTtcclxuICAvLyAgICAgICAgICAgICAgIGZvciAobGV0IGFpID0gMDsgYWkgPCByOyBhaSsrKSB7XHJcbiAgLy9cclxuICAvLyAgICAgICAgICAgICAgICAgbGV0IGEgPSBhaXNCdWZmZXJbY2hdW2FpXTtcclxuICAvL1xyXG4gIC8vICAgICAgICAgICAgICAgICBpZiAoYSA8IHBNaW4pIHtcclxuICAvLyAgICAgICAgICAgICAgICAgICBwTWluID0gYTtcclxuICAvLyAgICAgICAgICAgICAgICAgfVxyXG4gIC8vICAgICAgICAgICAgICAgICBpZiAoYSA+IHBNYXgpIHtcclxuICAvLyAgICAgICAgICAgICAgICAgICBwTWF4ID0gYTtcclxuICAvLyAgICAgICAgICAgICAgICAgfVxyXG4gIC8vICAgICAgICAgICAgICAgfVxyXG4gIC8vICAgICAgICAgICAgIH1cclxuICAvLyAgICAgICAgICAgICBwc01pbltwaWldID0gcE1pbjtcclxuICAvLyAgICAgICAgICAgICBwc01heFtwaWldID0gcE1heDtcclxuICAvLyAgICAgICAgICAgfVxyXG4gIC8vICAgICAgICAgICBnLmZpbGxTdHlsZSA9ICdncmVlbic7XHJcbiAgLy8gICAgICAgICAgIGcuc3Ryb2tlU3R5bGUgPSAnZ3JlZW4nO1xyXG4gIC8vXHJcbiAgLy8gICAgICAgICAgIC8vIGRyYXcgYXVkaW8gc2lnbmFsIGFzIHNpbmdsZSBwb2x5Z29uXHJcbiAgLy8gICAgICAgICAgIGcuYmVnaW5QYXRoKCk7XHJcbiAgLy8gICAgICAgICAgIGcubW92ZVRvKDAsIHkgKyAoY2hIIC8gMikgKyBwc01pblswXSAqIGNoSCAvIDIpO1xyXG4gIC8vXHJcbiAgLy8gICAgICAgICAgIGZvciAobGV0IHBpaSA9IDA7IHBpaSA8IHc7IHBpaSsrKSB7XHJcbiAgLy8gICAgICAgICAgICAgbGV0IHB2ID0gcHNNaW5bcGlpXSAqIGNoSCAvIDI7XHJcbiAgLy8gICAgICAgICAgICAgLy9jb25zb2xlLmxvZyhcIk1pbjogXCIscHYpO1xyXG4gIC8vICAgICAgICAgICAgIGcubGluZVRvKHBpaSwgeSArIChjaEggLyAyKSArIHB2KTtcclxuICAvLyAgICAgICAgICAgfVxyXG4gIC8vICAgICAgICAgICBmb3IgKGxldCBwaWkgPSB3OyBwaWkgPj0gMDsgcGlpLS0pIHtcclxuICAvLyAgICAgICAgICAgICBsZXQgcHYgPSBwc01heFtwaWldICogY2hIIC8gMjtcclxuICAvLyAgICAgICAgICAgICAvL2NvbnNvbGUubG9nKFwiTWF4OiBcIixwdik7XHJcbiAgLy8gICAgICAgICAgICAgZy5saW5lVG8ocGlpLCB5ICsgKGNoSCAvIDIpICsgcHYpO1xyXG4gIC8vICAgICAgICAgICB9XHJcbiAgLy8gICAgICAgICAgIGcuY2xvc2VQYXRoKCk7XHJcbiAgLy8gICAgICAgICAgIC8vZy5saW5lVG8oKVxyXG4gIC8vICAgICAgICAgICBnLmZpbGwoKTtcclxuICAvLyAgICAgICAgICAgZy5zdHJva2UoKTtcclxuICAvLyAgICAgICAgICAgZy5maWxsU3R5bGUgPSBcInllbGxvd1wiO1xyXG4gIC8vICAgICAgICAgICBnLnN0cm9rZSgpO1xyXG4gIC8vICAgICAgICAgICB5ICs9IGNoSDtcclxuICAvLyAgICAgICAgIH1cclxuICAvLyAgICAgICBhaXM/LmNsb3NlKCk7XHJcbiAgLy8gICAgIH1cclxuICAvLyAgIH1cclxuICAvLyB9XHJcblxyXG4gIHNldERhdGEoYXVkaW9EYXRhOiBBdWRpb0RhdGFIb2xkZXIgfCBudWxsKSB7XHJcbiAgICB0aGlzLl9hdWRpb0RhdGFIb2xkZXIgPSBhdWRpb0RhdGE7XHJcbiAgICB0aGlzLnBsYXlGcmFtZVBvc2l0aW9uID0gMDtcclxuICB9XHJcbn1cclxuXHJcbiJdfQ==
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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RSxJQUFJLEVBQUU7Z0JBQ0gsZ0JBQWdCO3NCQUF0RCxTQUFTO3VCQUFDLFFBQVEsRUFBRSxFQUFFLE1BQU0sRUFBRSxJQUFJLEVBQUUiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQge0NvbXBvbmVudCwgVmlld0NoaWxkLCBFbGVtZW50UmVmfSBmcm9tICdAYW5ndWxhci9jb3JlJztcclxuaW1wb3J0IHtBdWRpb0NhbnZhc0xheWVyQ29tcG9uZW50fSBmcm9tIFwiLi9hdWRpb19jYW52YXNfbGF5ZXJfY29tcFwiO1xyXG5pbXBvcnQge1dvcmtlckhlbHBlcn0gZnJvbSBcIi4uLy4uL3V0aWxzL3V0aWxzXCI7XHJcbmltcG9ydCB7QXVkaW9CdWZmZXJTb3VyY2UsIEF1ZGlvRGF0YUhvbGRlcn0gZnJvbSBcIi4uL2F1ZGlvX2RhdGFfaG9sZGVyXCI7XHJcbmltcG9ydCB7U3Vic2NyaXB0aW9ufSBmcm9tIFwicnhqc1wiO1xyXG5cclxuZGVjbGFyZSBmdW5jdGlvbiBwb3N0TWVzc2FnZShtZXNzYWdlOiBhbnksIHRyYW5zZmVyOiBBcnJheTxhbnk+KTogdm9pZDtcclxuXHJcbkBDb21wb25lbnQoe1xyXG5cclxuICBzZWxlY3RvcjogJ2F1ZGlvLXNpZ25hbCcsXHJcbiAgdGVtcGxhdGU6IGBcclxuICAgIDxjYW52YXMgI2JnIGhlaWdodD1cIjEwXCI+PC9jYW52YXM+XHJcbiAgICA8Y2FudmFzICNhdWRpb1NpZ25hbCBoZWlnaHQ9XCIxMFwiPjwvY2FudmFzPlxyXG4gICAgPGNhbnZhcyAjY3Vyc29yIGhlaWdodD1cIjEwXCIgKG1vdXNlZG93bik9XCJzZWxlY3Rpb25TdGFydCgkZXZlbnQpXCIgKG1vdXNlb3Zlcik9XCJ1cGRhdGVDdXJzb3JDYW52YXMoJGV2ZW50KVwiIChtb3VzZW1vdmUpPVwidXBkYXRlQ3Vyc29yQ2FudmFzKCRldmVudClcIlxyXG4gICAgICAgICAgICAobW91c2VsZWF2ZSk9XCJ1cGRhdGVDdXJzb3JDYW52YXMoJGV2ZW50LCBmYWxzZSlcIj48L2NhbnZhcz5cclxuICAgIDxjYW52YXMgI21hcmtlciBoZWlnaHQ9XCIxMFwiPjwvY2FudmFzPmAsXHJcblxyXG4gIHN0eWxlczogW2A6aG9zdHtcclxuICAgICAgbWluLWhlaWdodDogMHB4O1xyXG4gICAgfWAsYGNhbnZhcyB7XHJcbiAgICB0b3A6IDA7XHJcbiAgICBsZWZ0OiAwO1xyXG4gICAgd2lkdGg6IDA7XHJcbiAgICBoZWlnaHQ6IDA7XHJcbiAgICBtaW4taGVpZ2h0OiAwcHg7XHJcbiAgICBwb3NpdGlvbjogYWJzb2x1dGU7XHJcbiAgfWBdXHJcblxyXG59KVxyXG5leHBvcnQgY2xhc3MgQXVkaW9TaWduYWwgZXh0ZW5kcyBBdWRpb0NhbnZhc0xheWVyQ29tcG9uZW50e1xyXG5cclxuICBuOiBhbnk7XHJcbiAgY2UhOiBIVE1MRGl2RWxlbWVudDtcclxuICBAVmlld0NoaWxkKCdhdWRpb1NpZ25hbCcsIHsgc3RhdGljOiB0cnVlIH0pIGF1ZGlvU2lnbmFsQ2FudmFzUmVmITogRWxlbWVudFJlZjtcclxuICBAVmlld0NoaWxkKCdtYXJrZXInLCB7IHN0YXRpYzogdHJ1ZSB9KSBwbGF5UG9zQ2FudmFzUmVmITogRWxlbWVudFJlZjtcclxuICBzaWduYWxDYW52YXMhOiBIVE1MQ2FudmFzRWxlbWVudDtcclxuXHJcbiAgbWFya2VyQ2FudmFzITogSFRNTENhbnZhc0VsZW1lbnQ7XHJcblxyXG4gIHByaXZhdGUgX3BsYXlGcmFtZVBvc2l0aW9uOiBudW1iZXJ8bnVsbD1udWxsO1xyXG5cclxuICBwcml2YXRlIHdvcmtlcjogV29ya2VyIHwgbnVsbD1udWxsO1xyXG4gIHByaXZhdGUgcmVhZG9ubHkgd29ya2VyVVJMOiBzdHJpbmc7XHJcblxyXG4gIHByaXZhdGUgcmFBc1N1YnNjOlN1YnNjcmlwdGlvbnxudWxsPW51bGw7XHJcblxyXG4gIGNvbnN0cnVjdG9yKHByaXZhdGUgcmVmOiBFbGVtZW50UmVmKSB7XHJcbiAgICBzdXBlcigpO1xyXG4gICAgdGhpcy53b3JrZXJVUkwgPSBXb3JrZXJIZWxwZXIuYnVpbGRXb3JrZXJCbG9iVVJMKHRoaXMud29ya2VyRnVuY3Rpb24pXHJcbiAgICB0aGlzLl9hdWRpb0RhdGFIb2xkZXIgPSBudWxsO1xyXG4gICAgdGhpcy5fYmdDb2xvcj0nYmxhY2snO1xyXG4gICAgdGhpcy5fc2VsZWN0Q29sb3I9J3JnYmEoMjU1LDI1NSwwLDAuOCknXHJcblxyXG4gIH1cclxuXHJcbiAgbmdBZnRlclZpZXdJbml0KCkge1xyXG5cclxuICAgIHRoaXMuY2UgPSB0aGlzLnJlZi5uYXRpdmVFbGVtZW50O1xyXG4gICAgdGhpcy5iZ0NhbnZhcyA9IHRoaXMuYmdDYW52YXNSZWYubmF0aXZlRWxlbWVudDtcclxuICAgIHRoaXMuYmdDYW52YXMuc3R5bGUuekluZGV4ID0gJzEnO1xyXG4gICAgdGhpcy5zaWduYWxDYW52YXMgPSB0aGlzLmF1ZGlvU2lnbmFsQ2FudmFzUmVmLm5hdGl2ZUVsZW1lbnQ7XHJcbiAgICB0aGlzLnNpZ25hbENhbnZhcy5zdHlsZS56SW5kZXggPSAnMic7XHJcbiAgICB0aGlzLm1hcmtlckNhbnZhcyA9IHRoaXMucGxheVBvc0NhbnZhc1JlZi5uYXRpdmVFbGVtZW50O1xyXG4gICAgdGhpcy5tYXJrZXJDYW52YXMuc3R5bGUuekluZGV4ID0gJzMnO1xyXG4gICAgdGhpcy5jdXJzb3JDYW52YXMgPSB0aGlzLmN1cnNvckNhbnZhc1JlZi5uYXRpdmVFbGVtZW50O1xyXG4gICAgdGhpcy5jdXJzb3JDYW52YXMuc3R5bGUuekluZGV4ID0gJzQnO1xyXG5cclxuICAgIHRoaXMuY2FudmFzTGF5ZXJzWzBdPXRoaXMuYmdDYW52YXM7XHJcbiAgICB0aGlzLmNhbnZhc0xheWVyc1sxXT10aGlzLnNpZ25hbENhbnZhcztcclxuICAgIHRoaXMuY2FudmFzTGF5ZXJzWzJdPXRoaXMuY3Vyc29yQ2FudmFzO1xyXG4gICAgdGhpcy5jYW52YXNMYXllcnNbM109dGhpcy5tYXJrZXJDYW52YXM7XHJcblxyXG4gIH1cclxuXHJcbiAgZ2V0IHBsYXlGcmFtZVBvc2l0aW9uKCk6IG51bWJlciB8bnVsbHtcclxuICAgIHJldHVybiB0aGlzLl9wbGF5RnJhbWVQb3NpdGlvbjtcclxuICB9XHJcblxyXG4gIHNldCBwbGF5RnJhbWVQb3NpdGlvbihwbGF5RnJhbWVQb3NpdGlvbjogbnVtYmVyfG51bGwpIHtcclxuICAgIHRoaXMuX3BsYXlGcmFtZVBvc2l0aW9uID0gcGxheUZyYW1lUG9zaXRpb247XHJcbiAgICB0aGlzLmRyYXdQbGF5UG9zaXRpb24oKTtcclxuICB9XHJcblxyXG5cclxuXHJcbiAgZHJhd1BsYXlQb3NpdGlvbigpIHtcclxuICAgIGlmICh0aGlzLm1hcmtlckNhbnZhcykge1xyXG4gICAgICBsZXQgdyA9IHRoaXMubWFya2VyQ2FudmFzLndpZHRoO1xyXG4gICAgICBsZXQgaCA9IHRoaXMubWFya2VyQ2FudmFzLmhlaWdodDtcclxuICAgICAgbGV0IGcgPSB0aGlzLm1hcmtlckNhbnZhcy5nZXRDb250ZXh0KFwiMmRcIik7XHJcbiAgICAgIGlmIChnKSB7XHJcbiAgICAgICAgZy5jbGVhclJlY3QoMCwgMCwgdywgaCk7XHJcbiAgICAgICAgaWYodGhpcy5fcGxheUZyYW1lUG9zaXRpb24pIHtcclxuICAgICAgICAgIGxldCBwaXhlbFBvcyA9IHRoaXMuZnJhbWVUb1ZpZXdQb3J0WFBpeGVsUG9zaXRpb24odGhpcy5fcGxheUZyYW1lUG9zaXRpb24pO1xyXG4gICAgICAgICAgaWYgKHBpeGVsUG9zKSB7XHJcbiAgICAgICAgICAgIGcuZmlsbFN0eWxlID0gJ3JlZCc7XHJcbiAgICAgICAgICAgIGcuc3Ryb2tlU3R5bGUgPSAncmVkJztcclxuICAgICAgICAgICAgZy5iZWdpblBhdGgoKTtcclxuICAgICAgICAgICAgZy5tb3ZlVG8ocGl4ZWxQb3MsIDApO1xyXG4gICAgICAgICAgICBnLmxpbmVUbyhwaXhlbFBvcywgaCk7XHJcbiAgICAgICAgICAgIGcuY2xvc2VQYXRoKCk7XHJcbiAgICAgICAgICAgIGcuc3Ryb2tlKCk7XHJcbiAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG4gICAgICB9XHJcbiAgICB9XHJcbiAgfVxyXG5cclxuICAvKlxyXG4gICAqICBNZXRob2QgdXNlZCBhcyB3b3JrZXIgY29kZS5cclxuICAgKi9cclxuICB3b3JrZXJGdW5jdGlvbigpIHtcclxuICAgIGFkZEV2ZW50TGlzdGVuZXIoJ21lc3NhZ2UnLCAoeyBkYXRhIH0pID0+IHtcclxuXHJcbiAgICAgIGNvbnN0IGF1ZGlvRGF0YSA9IGRhdGEuYXVkaW9EYXRhOyAvLyBhdWRpbyBkYXRhIHBhcnQgcmVxdWlyZWQgdG8gcmVuZGVyIHZpZXcgcG9ydFxyXG4gICAgICBjb25zdCBhdU9mZnNldDpudW1iZXI9ZGF0YS5hdWRpb0RhdGFPZmZzZXQ7XHJcbiAgICAgIGNvbnN0IGw9IGRhdGEubDsgLy8gbGVmdCBwaXhlbCBwb3NpdGlvbiBvZiB2aWV3IHBvcnRcclxuICAgICAgY29uc3QgdyA9IGRhdGEudzsgIC8vIHdpZHRoIG9mIHZpZXdwb3J0XHJcbiAgICAgIGNvbnN0IHZ3ID0gZGF0YS52dzsgLy8gIHRvdGFsIHdpZHRoIG9mICh2aXJ0dWFsKSBhdWRpbyB2aWV3IChub3Qgdmlld3BvcnQgd2lkdGgpXHJcbiAgICAgIGNvbnN0IGNocyA9IGRhdGEuY2hzOyAvLyBudW1iZXIgb2YgY2hhbm5lbHNcclxuICAgICAgLy9jb25zdCBkYXRhRnJhbWVMZW5ndGggPSBkYXRhLmF1ZGlvRGF0YUZyYW1lTGVuZ3RoOyAgLy8gZnJhbWUgbGVuZ3RoIG9mIGF1ZGlvIGRhdGEgcGFydCByZXF1aXJlZCBmb3IgdmlldyBwb3J0XHJcbiAgICAgIGNvbnN0IGZyYW1lTGVuZ3RoID0gZGF0YS5mcmFtZUxlbmd0aDsgIC8vIHRvdGFsIGZyYW1lIGxlbmd0aCAob2YgYXVkaW8gY2xpcClcclxuXHJcbiAgICAgIC8vY29uc29sZS5kZWJ1ZyhcIlc6IGxlZnQ6IFwiK2wrXCIsIHc6XCIrdytcIiwgdnc6IFwiK3Z3K1wiLCBjaHM6IFwiK2NocytcIiwgZnJhbWVMZW5ndGg6IFwiK2ZyYW1lTGVuZ3RoKTtcclxuXHJcbiAgICAgIGxldCBwc01pbk1heD0gbmV3IEZsb2F0MzJBcnJheSgwKTtcclxuXHJcbiAgICAgIGlmKGF1ZGlvRGF0YSAmJiBhdWRpb0RhdGEubGVuZ3RoPjAgJiYgdz49MCAmJiB2dz4wKSB7XHJcblxyXG4gICAgICAgIGNvbnN0IGZyYW1lc1BlclBpeGVsID0gZnJhbWVMZW5ndGggLyB2dztcclxuXHJcbiAgICAgICAgY29uc3QgcG9pbnRzTGVuID0gdyAqIGNocztcclxuICAgICAgICAvLyBvbmUgZm9yIG1pbiBvbmUgZm9yIG1heFxyXG4gICAgICAgIGNvbnN0IGFyckxlbiA9IHBvaW50c0xlbiAqIDI7XHJcbiAgICAgICAgcHNNaW5NYXggPSBuZXcgRmxvYXQzMkFycmF5KGFyckxlbik7XHJcbiAgICAgICAgbGV0IGNoRnJhbWVQb3MgPSAwO1xyXG4gICAgICAgIGNvbnN0IGNoRnJhbWVMZW5ndGg9YXVkaW9EYXRhLmxlbmd0aC9jaHM7XHJcbiAgICAgICAgZm9yIChsZXQgY2ggPSAwOyBjaCA8IGNoczsgY2grKykge1xyXG5cclxuICAgICAgICAgIGNoRnJhbWVQb3MgPSBjaCAqIGNoRnJhbWVMZW5ndGg7XHJcbiAgICAgICAgICBmb3IgKGxldCBwaWkgPSAwOyBwaWkgPCB3OyBwaWkrKykge1xyXG4gICAgICAgICAgICBjb25zdCB2aXJ0UGlpPWwrcGlpO1xyXG4gICAgICAgICAgICBsZXQgcE1pbiA9IEluZmluaXR5O1xyXG4gICAgICAgICAgICBsZXQgcE1heCA9IC1JbmZpbml0eTtcclxuICAgICAgICAgICAgbGV0IHBpeGVsRnJhbWVQb3MgPSBNYXRoLnJvdW5kKGNoRnJhbWVQb3MgKyAodmlydFBpaSAqIGZyYW1lc1BlclBpeGVsKSk7XHJcblxyXG4gICAgICAgICAgICAvLyBjYWxjdWxhdGUgcGl4ZWwgbWluL21heCBhbXBsaXR1ZGVcclxuICAgICAgICAgICAgZm9yIChsZXQgYWkgPSAwOyBhaSA8IGZyYW1lc1BlclBpeGVsOyBhaSsrKSB7XHJcbiAgICAgICAgICAgICAgY29uc3QgZnJhbWVQb3MgPSBwaXhlbEZyYW1lUG9zICsgYWk7XHJcbiAgICAgICAgICAgICAgbGV0IGEgPSAwO1xyXG4gICAgICAgICAgICAgIGNvbnN0IGJ1ZlBvcz1mcmFtZVBvcy1hdU9mZnNldDtcclxuICAgICAgICAgICAgICAvL2xldCBidWZQb3M9ZnJhbWVQb3M7XHJcbiAgICAgICAgICAgICAgaWYoYnVmUG9zPj0wICYmIGJ1ZlBvczxhdWRpb0RhdGEubGVuZ3RoKXtcclxuICAgICAgICAgICAgICAgIGE9YXVkaW9EYXRhW2J1ZlBvc107XHJcbiAgICAgICAgICAgICAgICAvL2NvbnNvbGUuZGVidWcoXCJXOiBjaDogXCIrY2grXCIsIHBpeGVsRnJhbWVQb3M6IFwiK3BpeGVsRnJhbWVQb3MrXCIsIGZyYW1lUG9zOiBcIitmcmFtZVBvcytcIiwgYXVPZmZzZXQ6IFwiK2F1T2Zmc2V0K1wiLCBidWZQb3M6IFwiK2J1ZlBvcytcIiwgYXVkaW9EYXRhLmxlbmd0aDogXCIrYXVkaW9EYXRhLmxlbmd0aCtcIiwgYTogXCIrYSk7XHJcbiAgICAgICAgICAgICAgICBpZiAoYSA8IHBNaW4pIHtcclxuICAgICAgICAgICAgICAgICAgcE1pbiA9IGE7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICBpZiAoYSA+IHBNYXgpIHtcclxuICAgICAgICAgICAgICAgICAgcE1heCA9IGE7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICBjb25zdCBwc01pblBvcyA9IGNoICogdyArIHBpaTtcclxuICAgICAgICAgICAgcHNNaW5NYXhbcHNNaW5Qb3NdID0gcE1pbjtcclxuICAgICAgICAgICAgY29uc3QgcHNNYXhQb3MgPSBwb2ludHNMZW4gKyBwc01pblBvcztcclxuICAgICAgICAgICAgcHNNaW5NYXhbcHNNYXhQb3NdID0gcE1heDtcclxuICAgICAgICAgICAgLy9jb25zb2xlLmRlYnVnKFwicHNNaW5NYXhbXCIrcHNNaW5Qb3MrXCJdPVwiK3BNaW4rXCIscHNNaW5NYXhbXCIrcHNNYXhQb3MrXCJdPVwiK3BNYXgpO1xyXG5cclxuICAgICAgICAgIH1cclxuICAgICAgICB9XHJcbiAgICAgIH1cclxuICAgICAgcG9zdE1lc3NhZ2Uoe3BzTWluTWF4OiBwc01pbk1heCwgbDpkYXRhLmwsdzogZGF0YS53LCBjaHM6IGRhdGEuY2hzLGVvZDpkYXRhLmVvZH0sIFtwc01pbk1heC5idWZmZXJdKTtcclxuICAgIH0pXHJcbiAgfVxyXG5cclxuXHJcblxyXG4gIHN0YXJ0RHJhdyhjbGVhciA9IHRydWUpIHtcclxuICAgIGlmIChjbGVhcikge1xyXG4gICAgICBpZih0aGlzLmJvdW5kcykge1xyXG4gICAgICAgIHRoaXMuc2lnbmFsQ2FudmFzLnN0eWxlLmxlZnQgPSBNYXRoLnJvdW5kKHRoaXMuYm91bmRzLnBvc2l0aW9uLmxlZnQpLnRvU3RyaW5nKCkgKyAncHgnO1xyXG4gICAgICAgIHRoaXMuc2lnbmFsQ2FudmFzLndpZHRoID0gTWF0aC5yb3VuZCh0aGlzLmJvdW5kcy5kaW1lbnNpb24ud2lkdGgpO1xyXG4gICAgICAgIHRoaXMuc2lnbmFsQ2FudmFzLmhlaWdodCA9IE1hdGgucm91bmQodGhpcy5ib3VuZHMuZGltZW5zaW9uLmhlaWdodCk7XHJcblxyXG4gICAgICAgIGxldCBnID0gdGhpcy5zaWduYWxDYW52YXMuZ2V0Q29udGV4dChcIjJkXCIpO1xyXG4gICAgICAgIGlmIChnKSB7XHJcbiAgICAgICAgICAvL2cuY2xlYXJSZWN0KDAsIDAsdywgaCk7XHJcbiAgICAgICAgICBnLmZpbGxTdHlsZSA9IFwiYmxhY2tcIjtcclxuICAgICAgICAgIGcuZmlsbFJlY3QoMCwgMCwgTWF0aC5yb3VuZCh0aGlzLmJvdW5kcy5kaW1lbnNpb24ud2lkdGgpLCBNYXRoLnJvdW5kKHRoaXMuYm91bmRzLmRpbWVuc2lvbi5oZWlnaHQpKTtcclxuICAgICAgICB9XHJcbiAgICAgIH1cclxuICAgIH1cclxuICAgIHRoaXMuc3RhcnRSZW5kZXIoKTtcclxuICAgIHRoaXMuZHJhd0N1cnNvckxheWVyKClcclxuICB9XHJcblxyXG5cclxuICBwcml2YXRlIHN0YXJ0UmVuZGVyKCkge1xyXG5cclxuICAgIGlmICh0aGlzLndvcmtlcikge1xyXG4gICAgICB0aGlzLndvcmtlci50ZXJtaW5hdGUoKTtcclxuICAgICAgdGhpcy53b3JrZXIgPSBudWxsO1xyXG4gICAgfVxyXG4gICAgaWYodGhpcy5yYUFzU3Vic2Mpe1xyXG4gICAgICB0aGlzLnJhQXNTdWJzYy51bnN1YnNjcmliZSgpO1xyXG4gICAgfVxyXG4gICAgICBpZiAodGhpcy5fYXVkaW9EYXRhSG9sZGVyKSB7XHJcbiAgICAgICAgdGhpcy5fYXVkaW9EYXRhSG9sZGVyLmFkZE9uUmVhZHlMaXN0ZW5lcigoKT0+e1xyXG4gICAgICAgICAgaWYodGhpcy5fYXVkaW9EYXRhSG9sZGVyICYmIHRoaXMuYm91bmRzICYmIHRoaXMuYm91bmRzLmRpbWVuc2lvbikge1xyXG4gICAgICAgICAgICBsZXQgdyA9IE1hdGgucm91bmQodGhpcy5ib3VuZHMuZGltZW5zaW9uLndpZHRoKTtcclxuICAgICAgICAgICAgbGV0IGggPSBNYXRoLnJvdW5kKHRoaXMuYm91bmRzLmRpbWVuc2lvbi5oZWlnaHQpO1xyXG4gICAgICAgICAgICBsZXQgdncgPSBNYXRoLnJvdW5kKHRoaXMudmlydHVhbERpbWVuc2lvbi53aWR0aCk7XHJcblxyXG4gICAgICAgICAgICBpZiAodyA+IDAgJiYgaCA+IDAgJiYgdncgPiAwKSB7XHJcblxyXG4gICAgICAgICAgICAgIC8vdGhpcy53byA9IG5ldyBXb3JrZXIoJy4vYXVkaW9zaWduYWwud29ya2VyLmpzJyx7dHlwZTogJ21vZHVsZSd9KTtcclxuICAgICAgICAgICAgICB0aGlzLndvcmtlciA9IG5ldyBXb3JrZXIodGhpcy53b3JrZXJVUkwpO1xyXG4gICAgICAgICAgICAgIC8vdGhpcy53byA9IG5ldyBXb3JrZXIoJ3dvcmtlci9hdWRpb3NpZ25hbC53b3JrZXIudHMnKTtcclxuXHJcbiAgICAgICAgICAgICAgLy9sZXQgV29ya2VyID0gcmVxdWlyZSgnd29ya2VyIS4uLy4uLy4uL3dvcmtlcnMvdXBsb2FkZXIvbWFpbicpO1xyXG4gICAgICAgICAgICAgIGxldCBjaHMgPSB0aGlzLl9hdWRpb0RhdGFIb2xkZXIubnVtYmVyT2ZDaGFubmVscztcclxuICAgICAgICAgICAgICBsZXQgbGVmdFBvcyA9IE1hdGgucm91bmQodGhpcy5ib3VuZHMucG9zaXRpb24ubGVmdCk7XHJcbiAgICAgICAgICAgICAgbGV0IHJlbmRlclBvcyA9IGxlZnRQb3M7XHJcblxyXG4gICAgICAgICAgICAgIGxldCBmcmFtZUxlbmd0aCA9IHRoaXMuX2F1ZGlvRGF0YUhvbGRlci5mcmFtZUxlbjtcclxuICAgICAgICAgICAgICBsZXQgZnJhbWVzUGVyUGl4ZWwgPSBNYXRoLmNlaWwoZnJhbWVMZW5ndGggLyB2dyk7XHJcbiAgICAgICAgICAgICAgLy9jb25zb2xlLmRlYnVnKFwiQ2hzOiBcIiArIGNocyArIFwiLCB2dzogXCIgKyB2dyArIFwiLCBmcmFtZUxlbmd0aDogXCIgKyBmcmFtZUxlbmd0aCArIFwiLCBmcmFtZXNQZXJQaXhlbDogXCIgKyBmcmFtZXNQZXJQaXhlbCk7XHJcbiAgICAgICAgICAgICAgbGV0IGFkOiBGbG9hdDMyQXJyYXkgPSBuZXcgRmxvYXQzMkFycmF5KGNocyAqIGZyYW1lc1BlclBpeGVsKTtcclxuICAgICAgICAgICAgICBsZXQgcmFBcyA9IHRoaXMuX2F1ZGlvRGF0YUhvbGRlci5yYW5kb21BY2Nlc3NBdWRpb1N0cmVhbSgpO1xyXG4gICAgICAgICAgICAgIGxldCBhdWRpb0J1ZmZlcjogQXVkaW9CdWZmZXIgfCBudWxsID0gbnVsbDtcclxuICAgICAgICAgICAgICBsZXQgYXVkaW9Tb3VyY2UgPSB0aGlzLl9hdWRpb0RhdGFIb2xkZXIuYXVkaW9Tb3VyY2U7XHJcbiAgICAgICAgICAgICAgaWYgKGF1ZGlvU291cmNlIGluc3RhbmNlb2YgQXVkaW9CdWZmZXJTb3VyY2UpIHtcclxuICAgICAgICAgICAgICAgIGF1ZGlvQnVmZmVyID0gYXVkaW9Tb3VyY2UuYXVkaW9CdWZmZXI7XHJcbiAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgIC8vbGV0IGFycmF5QXVkaW9CdWZmZXI9dGhpcy5fYXVkaW9EYXRhSG9sZGVyLmFycmF5QnVmZmVyO1xyXG4gICAgICAgICAgICAgIGxldCBhcnJBYkJ1ZjogRmxvYXQzMkFycmF5W10gfCBudWxsO1xyXG5cclxuICAgICAgICAgICAgICAvL2xldCBhaXM6QXJyYXlBdWRpb0J1ZmZlcklucHV0U3RyZWFtfG51bGw9bnVsbDtcclxuICAgICAgICAgICAgICAvL2xldCBhaXNCdWY6RmxvYXQzMkFycmF5W118bnVsbD1udWxsO1xyXG4gICAgICAgICAgICAgIGxldCBwc01pbk1heDogRmxvYXQzMkFycmF5IHwgbnVsbCA9IG51bGw7XHJcblxyXG4gICAgICAgICAgICAgIGlmICh0aGlzLndvcmtlcikge1xyXG4gICAgICAgICAgICAgICAgdGhpcy53b3JrZXIub25tZXNzYWdlID0gKG1lKSA9PiB7XHJcbiAgICAgICAgICAgICAgICAgIGlmIChtZS5kYXRhLmVvZCA9PT0gdHJ1ZSkge1xyXG4gICAgICAgICAgICAgICAgICAgIGxldCBwc01pbk1heFRtcDtcclxuICAgICAgICAgICAgICAgICAgICBpZiAocHNNaW5NYXgpIHtcclxuICAgICAgICAgICAgICAgICAgICAgIHBzTWluTWF4VG1wID0gcHNNaW5NYXg7XHJcbiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgICAgICAgICAgIHBzTWluTWF4VG1wID0gbWUuZGF0YS5wc01pbk1heDtcclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5kcmF3UmVuZGVyZWQobGVmdFBvcywgdywgaCwgY2hzLCBwc01pbk1heFRtcCk7XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKHRoaXMud29ya2VyKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICB0aGlzLndvcmtlci50ZXJtaW5hdGUoKTtcclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgcmFBcy5jbG9zZSgpO1xyXG4gICAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKHRoaXMuX2F1ZGlvRGF0YUhvbGRlciAmJiBhcnJBYkJ1Zikge1xyXG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IHJ3ID0gbWUuZGF0YS53O1xyXG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IHJQb2ludHNMZW4gPSBjaHMgKiBydztcclxuICAgICAgICAgICAgICAgICAgICBjb25zdCBwb2ludHNMZW4gPSBjaHMgKiB3O1xyXG4gICAgICAgICAgICAgICAgICAgIGZvciAobGV0IGNoID0gMDsgY2ggPCBjaHM7IGNoKyspIHtcclxuICAgICAgICAgICAgICAgICAgICAgIGlmIChwc01pbk1heCkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBsZXQgckJhc2VQb3MgPSBjaCAqIHJ3O1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBsZXQgYmFzZVBvcyA9IGNoICogdztcclxuICAgICAgICAgICAgICAgICAgICAgICAgbGV0IHJQb3NNaW4gPSByQmFzZVBvcztcclxuICAgICAgICAgICAgICAgICAgICAgICAgbGV0IHJQb3NNYXggPSByUG9pbnRzTGVuICsgclBvc01pbjtcclxuICAgICAgICAgICAgICAgICAgICAgICAgbGV0IHBvc01pbiA9IGJhc2VQb3MgKyAocmVuZGVyUG9zIC0gbGVmdFBvcyk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGxldCBwb3NNYXggPSBwb2ludHNMZW4gKyBwb3NNaW47XHJcblxyXG4gICAgICAgICAgICAgICAgICAgICAgICBwc01pbk1heFtwb3NNaW5dID0gbWUuZGF0YS5wc01pbk1heFtyUG9zTWluXTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgLy9jb25zb2xlLmRlYnVnKCdNaW46ICgnK3Bvc01pbisnKTogJyttZS5kYXRhLnBzTWluTWF4W3JQb3NNaW5dKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgcHNNaW5NYXhbcG9zTWF4XSA9IG1lLmRhdGEucHNNaW5NYXhbclBvc01heF07XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIC8vY29uc29sZS5kZWJ1ZygnTWF4OiAoJysocG9zTWF4KSsnKTogJyttZS5kYXRhLnBzTWluTWF4W3JQb3NNYXhdKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgLy9jb25zb2xlLmRlYnVnKFwicHNNaW5NYXhbXCIrcG9zTWluK1wiXT1cIittZS5kYXRhLnBzTWluTWF4W3JQb3NNaW5dK1wiICAoclBvc01pbj1cIityUG9zTWluK1wiKSxwc01pbk1heFtcIitwb3NNYXgrXCJdPVwiK21lLmRhdGEucHNNaW5NYXhbclBvc01heF0pO1xyXG4gICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICBsZXQgZW9kID0gZmFsc2U7XHJcbiAgICAgICAgICAgICAgICAgICAgcmVuZGVyUG9zKys7XHJcbiAgICAgICAgICAgICAgICAgICAgLy9sZXQgYWQ6RmxvYXQzMkFycmF5O1xyXG5cclxuICAgICAgICAgICAgICAgICAgICBjb25zdCBsZWZ0RnJhbWVQb3MgPSBNYXRoLmZsb29yKGZyYW1lTGVuZ3RoICogcmVuZGVyUG9zIC8gdncpO1xyXG4gICAgICAgICAgICAgICAgICAgIGlmIChyZW5kZXJQb3MgPCBsZWZ0UG9zICsgdykge1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHJhQXNPYnMgPSByYUFzLmZyYW1lc09icyhsZWZ0RnJhbWVQb3MsIGZyYW1lc1BlclBpeGVsLCBhcnJBYkJ1ZilcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICB0aGlzLnJhQXNTdWJzYyA9IHJhQXNPYnMuc3Vic2NyaWJlKFxyXG4gICAgICAgICAgICAgICAgICAgICAgICB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgbmV4dDogKHJlYWQpID0+IHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vY29uc29sZS5kZWJ1ZyhcIkZpcnN0IHJlYWQgZnJhbWU6IFwiK2FyckFiQnVmWzBdWzBdKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChhcnJBYkJ1Zikge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBhZExlbiA9IGNocyAqIGZyYW1lc1BlclBpeGVsO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoIWFkIHx8IGFkLmxlbmd0aCAhPT0gYWRMZW4pIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhZCA9IG5ldyBGbG9hdDMyQXJyYXkoYWRMZW4pO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZvciAobGV0IGNoID0gMDsgY2ggPCBjaHM7IGNoKyspIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhZC5zZXQoYXJyQWJCdWZbY2hdLCBjaCAqIGZyYW1lc1BlclBpeGVsKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgZW9kID0gKHJlYWQgPD0gMCk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBsZXQgYWRCdWYgPSBhZC5idWZmZXI7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAodGhpcy53b3JrZXIpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy53b3JrZXIucG9zdE1lc3NhZ2Uoe1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGw6IHJlbmRlclBvcyxcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB3OiBtZS5kYXRhLncsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaDogaCxcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2dzogdncsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2hzOiBjaHMsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZnJhbWVMZW5ndGg6IGZyYW1lTGVuZ3RoLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGF1ZGlvRGF0YTogYWQsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYXVkaW9EYXRhT2Zmc2V0OiBsZWZ0RnJhbWVQb3MsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZW9kOiBlb2RcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfSwgW2FkQnVmXSk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgfSxcclxuICAgICAgICAgICAgICAgICAgICAgICAgICBlcnJvcjogKGVycikgPT4ge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc29sZS5lcnJvcihcIkF1ZGlvU2lnbmFsOiBFcnJvciByZWFkaW5nIGF1ZGlvIGRhdGE6IFwiICsgZXJyKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICAgIClcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgICAgICAgICAgIGFkID0gbmV3IEZsb2F0MzJBcnJheSgpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgZW9kID0gdHJ1ZTtcclxuICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGFkQnVmID0gYWQuYnVmZmVyO1xyXG4gICAgICAgICAgICAgICAgICAgICAgaWYgKHRoaXMud29ya2VyKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMud29ya2VyLnBvc3RNZXNzYWdlKHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICBsOiByZW5kZXJQb3MsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgdzogbWUuZGF0YS53LFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgIGg6IGgsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgdnc6IHZ3LFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgIGNoczogY2hzLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgIGZyYW1lTGVuZ3RoOiBmcmFtZUxlbmd0aCxcclxuICAgICAgICAgICAgICAgICAgICAgICAgICBhdWRpb0RhdGE6IGFkLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgIGF1ZGlvRGF0YU9mZnNldDogbGVmdEZyYW1lUG9zLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgIGVvZDogZW9kXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH0sIFthZEJ1Zl0pO1xyXG4gICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgICAgaWYgKGF1ZGlvQnVmZmVyICYmIGF1ZGlvQnVmZmVyLmxlbmd0aCAqIGF1ZGlvQnVmZmVyLm51bWJlck9mQ2hhbm5lbHMgPCBBdWRpb0NhbnZhc0xheWVyQ29tcG9uZW50LkVOQUJMRV9TVFJFQU1JTkdfTlVNQkVSX09GX1NBTVBMRVNfVEhSRVNIT0xEKSB7XHJcblxyXG4gICAgICAgICAgICAgICAgLy8gUmVuZGVyIHdob2xlIGNsaXAgYXQgb25jZVxyXG4gICAgICAgICAgICAgICAgYXJyQWJCdWYgPSBudWxsO1xyXG4gICAgICAgICAgICAgICAgcHNNaW5NYXggPSBudWxsO1xyXG4gICAgICAgICAgICAgICAgY29uc3QgYWQgPSBuZXcgRmxvYXQzMkFycmF5KGNocyAqIGZyYW1lTGVuZ3RoKTtcclxuICAgICAgICAgICAgICAgIGZvciAobGV0IGNoID0gMDsgY2ggPCBjaHM7IGNoKyspIHtcclxuICAgICAgICAgICAgICAgICAgYWQuc2V0KGF1ZGlvQnVmZmVyLmdldENoYW5uZWxEYXRhKGNoKSwgY2ggKiBmcmFtZUxlbmd0aCk7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICB0aGlzLndvcmtlci5wb3N0TWVzc2FnZSh7XHJcbiAgICAgICAgICAgICAgICAgIGw6IGxlZnRQb3MsXHJcbiAgICAgICAgICAgICAgICAgIHc6IHcsXHJcbiAgICAgICAgICAgICAgICAgIHZ3OiB2dyxcclxuICAgICAgICAgICAgICAgICAgY2hzOiBjaHMsXHJcbiAgICAgICAgICAgICAgICAgIGZyYW1lTGVuZ3RoOiBmcmFtZUxlbmd0aCxcclxuICAgICAgICAgICAgICAgICAgYXVkaW9EYXRhOiBhZCxcclxuICAgICAgICAgICAgICAgICAgYXVkaW9EYXRhT2Zmc2V0OiAwLFxyXG4gICAgICAgICAgICAgICAgICBlb2Q6IHRydWVcclxuICAgICAgICAgICAgICAgIH0sIFthZC5idWZmZXJdKTtcclxuXHJcbiAgICAgICAgICAgICAgfSBlbHNlIHtcclxuXHJcbiAgICAgICAgICAgICAgICAvLyBSZW5kZXIgcGl4ZWwgYnkgcGl4ZWxcclxuICAgICAgICAgICAgICAgIGlmICh3ID4gMCkge1xyXG5cclxuICAgICAgICAgICAgICAgICAgaWYgKGZyYW1lc1BlclBpeGVsID4gMCkge1xyXG4gICAgICAgICAgICAgICAgICAgIGxldCBydyA9IDE7XHJcbiAgICAgICAgICAgICAgICAgICAgYXJyQWJCdWYgPSBuZXcgQXJyYXk8RmxvYXQzMkFycmF5PihjaHMpO1xyXG4gICAgICAgICAgICAgICAgICAgIHBzTWluTWF4ID0gbmV3IEZsb2F0MzJBcnJheShjaHMgKiB3ICogMik7XHJcbiAgICAgICAgICAgICAgICAgICAgLy9jb25zb2xlLmRlYnVnKFwiQXVkaW9zaWduYWw6IEFsbG9jYXRpbmcgYnVmZmVyczogXCIrZnJhbWVzUGVyUGl4ZWwpO1xyXG4gICAgICAgICAgICAgICAgICAgIGZvciAobGV0IGNoID0gMDsgY2ggPCBjaHM7IGNoKyspIHtcclxuICAgICAgICAgICAgICAgICAgICAgIGFyckFiQnVmW2NoXSA9IG5ldyBGbG9hdDMyQXJyYXkoZnJhbWVzUGVyUGl4ZWwpO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICBjb25zdCBsZWZ0RnJhbWVQb3MgPSBNYXRoLmZsb29yKGZyYW1lTGVuZ3RoICogcmVuZGVyUG9zIC8gdncpO1xyXG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IGF1T2Zmc2V0ID0gbGVmdEZyYW1lUG9zOyAvLyBzaG91bGQgYWx3YXlzIGJlIDBcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgcmFBc09icyA9IHJhQXMuZnJhbWVzT2JzKGxlZnRGcmFtZVBvcywgZnJhbWVzUGVyUGl4ZWwsIGFyckFiQnVmKTtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5kcmF3U3RhdGVUZXh0KFwiTG9hZGluZy9SZW5kZXJpbmcuLi5cIik7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgIHRoaXMucmFBc1N1YnNjID0gcmFBc09icy5zdWJzY3JpYmUoXHJcbiAgICAgICAgICAgICAgICAgICAgICB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIG5leHQ6IChyZWFkKSA9PiB7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChhcnJBYkJ1ZiAmJiB0aGlzLndvcmtlcikge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgYWRMZW4gPSBjaHMgKiBmcmFtZXNQZXJQaXhlbDtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICghYWQgfHwgYWQubGVuZ3RoICE9PSBhZExlbikge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhZCA9IG5ldyBGbG9hdDMyQXJyYXkoYWRMZW4pO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgZm9yIChsZXQgY2ggPSAwOyBjaCA8IGNoczsgY2grKykge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhZC5zZXQoYXJyQWJCdWZbY2hdLCBjaCAqIGZyYW1lc1BlclBpeGVsKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLndvcmtlci5wb3N0TWVzc2FnZSh7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGw6IHJlbmRlclBvcyxcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdzogcncsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZ3OiB2dyxcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2hzOiBjaHMsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZyYW1lTGVuZ3RoOiBmcmFtZUxlbmd0aCxcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYXVkaW9EYXRhOiBhZCxcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYXVkaW9EYXRhT2Zmc2V0OiBhdU9mZnNldCxcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZW9kOiAocmVhZCA8PSAwKVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfSwgW2FkLmJ1ZmZlcl0pO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICAgICAgfSxcclxuICAgICAgICAgICAgICAgICAgICAgICAgZXJyb3I6IChlcnIpID0+IHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zb2xlLmVycm9yKFwiQXVkaW9TaWduYWw6IEVycm9yIHJlYWRpbmcgYXVkaW8gZGF0YTogXCIgKyBlcnIpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgKTtcclxuICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgfVxyXG4gICAgICAgIH0pO1xyXG4gICAgICB9IGVsc2Uge1xyXG4gICAgICAgIGlmICh0aGlzLmJvdW5kcyAmJiB0aGlzLmJvdW5kcy5kaW1lbnNpb24pIHtcclxuICAgICAgICAgIGxldCB3ID0gTWF0aC5yb3VuZCh0aGlzLmJvdW5kcy5kaW1lbnNpb24ud2lkdGgpO1xyXG4gICAgICAgICAgbGV0IGggPSBNYXRoLnJvdW5kKHRoaXMuYm91bmRzLmRpbWVuc2lvbi5oZWlnaHQpO1xyXG4gICAgICAgICAgbGV0IGcgPSB0aGlzLnNpZ25hbENhbnZhcy5nZXRDb250ZXh0KFwiMmRcIik7XHJcbiAgICAgICAgICBpZiAoZykge1xyXG4gICAgICAgICAgICBnLmNsZWFyUmVjdCgwLCAwLCB3LCBoKTtcclxuICAgICAgICAgIH1cclxuICAgICAgICB9XHJcbiAgICAgIH1cclxuXHJcbiAgfVxyXG5cclxuZHJhd1N0YXRlVGV4dChzdGF0ZVRleHQ6c3RyaW5nKSB7XHJcbiAgICBpZihzdGF0ZVRleHQpIHtcclxuICAgICAgY29uc3QgZyA9IHRoaXMuc2lnbmFsQ2FudmFzLmdldENvbnRleHQoXCIyZFwiKTtcclxuICAgICAgY29uc3Qgdz10aGlzLnNpZ25hbENhbnZhcy53aWR0aDtcclxuICAgICAgY29uc3QgaD10aGlzLnNpZ25hbENhbnZhcy5oZWlnaHQ7XHJcbiAgICAgIGlmIChnICYmIHcgJiYgaCkge1xyXG4gICAgICAgIGcuc3Ryb2tlU3R5bGUgPSAnd2hpdGUnO1xyXG4gICAgICAgIGcuZmlsbFN0eWxlID0gJ3doaXRlJztcclxuICAgICAgICBnLmZvbnQgPSAnMjBweCBzYW5zLXNlcmlmJztcclxuICAgICAgICBnLmZpbGxUZXh0KHN0YXRlVGV4dCwgMTAsIDI1KTtcclxuICAgICAgfVxyXG4gICAgfVxyXG59XHJcbiAgZHJhd1JlbmRlcmVkKGxlZnQ6bnVtYmVyLHc6bnVtYmVyLGg6bnVtYmVyLGNoczpudW1iZXIscHNNaW5NYXg6RmxvYXQzMkFycmF5KSB7XHJcbiAgICB0aGlzLmRyYXdCZygpO1xyXG4gICAgdGhpcy5zaWduYWxDYW52YXMuc3R5bGUubGVmdD1sZWZ0LnRvU3RyaW5nKCkrJ3B4JztcclxuICAgIHRoaXMuc2lnbmFsQ2FudmFzLndpZHRoID0gdztcclxuICAgIHRoaXMuc2lnbmFsQ2FudmFzLmhlaWdodCA9IGg7XHJcbiAgICBsZXQgZyA9IHRoaXMuc2lnbmFsQ2FudmFzLmdldENvbnRleHQoXCIyZFwiKTtcclxuICAgIGlmIChnKSB7XHJcbiAgICAgIGcuY2xlYXJSZWN0KDAsIDAsIHcsIGgpO1xyXG4gICAgICBsZXQgcG9pbnRzTGVuID0gdyAqIGNocztcclxuICAgICAgLy8gb25lIGZvciBtaW4gb25lIGZvciBtYXhcclxuICAgICAgLy9jb25zdCBhcnJMZW4gPSBwb2ludHNMZW4gKiAyO1xyXG4gICAgICBpZiAodGhpcy5fYXVkaW9EYXRhSG9sZGVyKSB7XHJcbiAgICAgICAgLy9jb25zdCBzdGQgPSBEYXRlLm5vdygpO1xyXG5cclxuICAgICAgICBjb25zdCBjaEggPSBoIC8gY2hzO1xyXG5cclxuICAgICAgICBsZXQgeSA9IDA7XHJcbiAgICAgICAgZm9yIChsZXQgY2ggPSAwOyBjaCA8IGNoczsgY2grKykge1xyXG4gICAgICAgICAgY29uc3QgcHNNaW5Qb3MgPSBjaCAqIHc7XHJcbiAgICAgICAgICBjb25zdCBwc01heFBvcyA9IHBvaW50c0xlbiArIHBzTWluUG9zO1xyXG5cclxuICAgICAgICAgIGcuZmlsbFN0eWxlID0gJ2dyZWVuJztcclxuICAgICAgICAgIGcuc3Ryb2tlU3R5bGUgPSAnZ3JlZW4nO1xyXG5cclxuICAgICAgICAgIC8vIGRyYXcgYXVkaW8gc2lnbmFsIGFzIHNpbmdsZSBwb2x5Z29uXHJcbiAgICAgICAgICBnLmJlZ2luUGF0aCgpO1xyXG4gICAgICAgICAgZy5tb3ZlVG8oMCwgeSArIChjaEggLyAyKSArIHBzTWluTWF4W3BzTWF4UG9zXSAqIGNoSCAvIDIpO1xyXG5cclxuICAgICAgICAgIGZvciAobGV0IHBpaSA9IDA7IHBpaSA8IHc7IHBpaSsrKSB7XHJcbiAgICAgICAgICAgIGNvbnN0IHBzTWF4ID0gcHNNaW5NYXhbcHNNYXhQb3MgKyBwaWldO1xyXG4gICAgICAgICAgICBjb25zdCBwdiA9IHBzTWF4ICogY2hIIC8gMjtcclxuICAgICAgICAgICAgY29uc3QgeWQ9eSArIChjaEggLyAyKSAtIHB2O1xyXG4gICAgICAgICAgICAvL2NvbnNvbGUubG9nKFwiTGluZVRvOiA6IFwiK3BpaStcIiBcIit5ZClcclxuICAgICAgICAgICAgZy5saW5lVG8ocGlpLCB5ZCk7XHJcbiAgICAgICAgICB9XHJcbiAgICAgICAgICBjb25zdCByZXZQaXhlbFN0YXJ0PXctMTtcclxuXHJcbiAgICAgICAgICBmb3IgKGxldCBwaWkgPSByZXZQaXhlbFN0YXJ0OyBwaWkgPj0gMDsgcGlpLS0pIHtcclxuICAgICAgICAgICAgY29uc3QgcHNNaW4gPSBwc01pbk1heFtwc01pblBvcyArIHBpaV07XHJcbiAgICAgICAgICAgIGNvbnN0IHB2ID0gcHNNaW4gKiBjaEggLyAyO1xyXG4gICAgICAgICAgICBjb25zdCB5ZD15ICsgKGNoSCAvIDIpIC0gcHY7XHJcbiAgICAgICAgICAgIC8vY29uc29sZS5sb2coXCJMaW5lVG86IDogXCIrcGlpK1wiIFwiK3lkKVxyXG4gICAgICAgICAgICBnLmxpbmVUbyhwaWksIHlkKTtcclxuICAgICAgICAgIH1cclxuICAgICAgICAgIGcuY2xvc2VQYXRoKCk7XHJcblxyXG4gICAgICAgICAgZy5maWxsKCk7XHJcbiAgICAgICAgICBnLnN0cm9rZSgpO1xyXG4gICAgICAgICAgeSArPSBjaEg7XHJcbiAgICAgICAgfVxyXG4gICAgICB9XHJcbiAgICB9XHJcbiAgfVxyXG5cclxuICAvLyByZWRyYXcoKSB7XHJcbiAgLy8gICB0aGlzLmRyYXdCZygpXHJcbiAgLy8gICBsZXQgZyA9IHRoaXMuc2lnbmFsQ2FudmFzLmdldENvbnRleHQoXCIyZFwiKTtcclxuICAvLyAgIGlmIChnKSB7XHJcbiAgLy8gICAgIGxldCB3ID0gdGhpcy5zaWduYWxDYW52YXMud2lkdGg7XHJcbiAgLy8gICAgIGxldCBoID0gdGhpcy5zaWduYWxDYW52YXMuaGVpZ2h0O1xyXG4gIC8vICAgICBnLmNsZWFyUmVjdCgwLCAwLCB3LCBoKTtcclxuICAvLyAgICAgLy9nLmZpbGxTdHlsZSA9IFwiYmxhY2tcIjtcclxuICAvLyAgICAgLy9nLmZpbGxSZWN0KDAsIDAsIHcsIGgpO1xyXG4gIC8vICAgICBpZiAodGhpcy5fYXVkaW9EYXRhSG9sZGVyKSB7XHJcbiAgLy8gICAgICAgbGV0IHN0ZCA9IERhdGUubm93KCk7XHJcbiAgLy8gICAgICAgbGV0IGNocyA9IHRoaXMuX2F1ZGlvRGF0YUhvbGRlci5udW1iZXJPZkNoYW5uZWxzO1xyXG4gIC8vICAgICAgIGxldCBjaEggPSBoIC8gY2hzO1xyXG4gIC8vXHJcbiAgLy8gICAgICAgbGV0IGZyYW1lTGVuZ3RoID0gdGhpcy5fYXVkaW9EYXRhSG9sZGVyLmZyYW1lTGVuO1xyXG4gIC8vXHJcbiAgLy8gICAgICAgbGV0IGZyYW1lc1BlclBpeGVsID0gZnJhbWVMZW5ndGggLyB3O1xyXG4gIC8vICAgICAgIGxldCB5ID0gMDtcclxuICAvLyAgICAgICBsZXQgYWlzOkZsb2F0MzJBcnJheUlucHV0U3RyZWFtfG51bGw9bnVsbDtcclxuICAvLyAgICAgICBsZXQgYXVkaW9Tb3VyY2U9dGhpcy5fYXVkaW9EYXRhSG9sZGVyLmF1ZGlvU291cmNlO1xyXG4gIC8vICAgICAgIGxldCBhdWRpb0J1ZmZlcjpBdWRpb0J1ZmZlcnxudWxsPW51bGw7XHJcbiAgLy8gICAgICAgaWYoYXVkaW9Tb3VyY2UgaW5zdGFuY2VvZiBBdWRpb0J1ZmZlclNvdXJjZSl7XHJcbiAgLy8gICAgICAgICBhdWRpb0J1ZmZlcj1hdWRpb1NvdXJjZS5hdWRpb0J1ZmZlcjtcclxuICAvLyAgICAgICB9XHJcbiAgLy8gICAgICAgbGV0IGFpc0J1ZmZlcjpBcnJheTxGbG9hdDMyQXJyYXk+fG51bGw9bnVsbDtcclxuICAvLyAgICAgICBpZighYXVkaW9CdWZmZXIpIHtcclxuICAvLyAgICAgICAgIGFpcz10aGlzLl9hdWRpb0RhdGFIb2xkZXIuYXVkaW9JbnB1dFN0cmVhbSgpO1xyXG4gIC8vICAgICAgICAgYWlzQnVmZmVyPW5ldyBBcnJheTxGbG9hdDMyQXJyYXk+KGNocyk7XHJcbiAgLy8gICAgICAgICBmb3IobGV0IGNoPTA7Y2g8Y2hzO2NoKyspIHtcclxuICAvLyAgICAgICAgICAgYWlzQnVmZmVyW2NoXSA9IG5ldyBGbG9hdDMyQXJyYXkoZnJhbWVzUGVyUGl4ZWwpO1xyXG4gIC8vICAgICAgICAgfVxyXG4gIC8vICAgICAgIH1cclxuICAvLyAgICAgICAgIGZvciAobGV0IGNoID0gMDsgY2ggPCBjaHM7IGNoKyspIHtcclxuICAvLyAgICAgICAgICAgbGV0IHggPSAwO1xyXG4gIC8vICAgICAgICAgICBsZXQgcHNNaW4gPSBuZXcgRmxvYXQzMkFycmF5KHcpO1xyXG4gIC8vICAgICAgICAgICBsZXQgcHNNYXggPSBuZXcgRmxvYXQzMkFycmF5KHcpO1xyXG4gIC8vICAgICAgICAgICBsZXQgZnJhbWVQb3MgPSAwO1xyXG4gIC8vICAgICAgICAgICBmb3IgKGxldCBwaWkgPSAwOyBwaWkgPCB3OyBwaWkrKykge1xyXG4gIC8vICAgICAgICAgICAgIGxldCBwTWluID0gMDtcclxuICAvLyAgICAgICAgICAgICBsZXQgcE1heCA9IDA7XHJcbiAgLy9cclxuICAvLyAgICAgICAgICAgICBpZiAoYXVkaW9CdWZmZXIpe1xyXG4gIC8vICAgICAgICAgICAgICAgLy8gY2FsY3VsYXRlIHBpeGVsIG1pbi9tYXggYW1wbGl0dWRlXHJcbiAgLy8gICAgICAgICAgICAgICBmb3IgKGxldCBhaSA9IDA7IGFpIDwgZnJhbWVzUGVyUGl4ZWw7IGFpKyspIHtcclxuICAvLyAgICAgICAgICAgICAgICAgLy9sZXQgZnJhbWVQb3M9KHBpaSpmcmFtZXNQZXJQaXhlbCkrYWk7XHJcbiAgLy8gICAgICAgICAgICAgICAgIGxldCBhID0gYXVkaW9CdWZmZXIuZ2V0Q2hhbm5lbERhdGEoY2gpW2ZyYW1lUG9zKytdO1xyXG4gIC8vXHJcbiAgLy8gICAgICAgICAgICAgICAgIGlmIChhIDwgcE1pbikge1xyXG4gIC8vICAgICAgICAgICAgICAgICAgIHBNaW4gPSBhO1xyXG4gIC8vICAgICAgICAgICAgICAgICB9XHJcbiAgLy8gICAgICAgICAgICAgICAgIGlmIChhID4gcE1heCkge1xyXG4gIC8vICAgICAgICAgICAgICAgICAgIHBNYXggPSBhO1xyXG4gIC8vICAgICAgICAgICAgICAgICB9XHJcbiAgLy8gICAgICAgICAgICAgICB9XHJcbiAgLy8gICAgICAgICAgIH1lbHNlIGlmKGFpcyAmJiBhaXNCdWZmZXIpIHtcclxuICAvLyAgICAgICAgICAgICAgIGxldCByID0gYWlzLnJlYWQoYWlzQnVmZmVyKTtcclxuICAvLyAgICAgICAgICAgICAgIGZvciAobGV0IGFpID0gMDsgYWkgPCByOyBhaSsrKSB7XHJcbiAgLy9cclxuICAvLyAgICAgICAgICAgICAgICAgbGV0IGEgPSBhaXNCdWZmZXJbY2hdW2FpXTtcclxuICAvL1xyXG4gIC8vICAgICAgICAgICAgICAgICBpZiAoYSA8IHBNaW4pIHtcclxuICAvLyAgICAgICAgICAgICAgICAgICBwTWluID0gYTtcclxuICAvLyAgICAgICAgICAgICAgICAgfVxyXG4gIC8vICAgICAgICAgICAgICAgICBpZiAoYSA+IHBNYXgpIHtcclxuICAvLyAgICAgICAgICAgICAgICAgICBwTWF4ID0gYTtcclxuICAvLyAgICAgICAgICAgICAgICAgfVxyXG4gIC8vICAgICAgICAgICAgICAgfVxyXG4gIC8vICAgICAgICAgICAgIH1cclxuICAvLyAgICAgICAgICAgICBwc01pbltwaWldID0gcE1pbjtcclxuICAvLyAgICAgICAgICAgICBwc01heFtwaWldID0gcE1heDtcclxuICAvLyAgICAgICAgICAgfVxyXG4gIC8vICAgICAgICAgICBnLmZpbGxTdHlsZSA9ICdncmVlbic7XHJcbiAgLy8gICAgICAgICAgIGcuc3Ryb2tlU3R5bGUgPSAnZ3JlZW4nO1xyXG4gIC8vXHJcbiAgLy8gICAgICAgICAgIC8vIGRyYXcgYXVkaW8gc2lnbmFsIGFzIHNpbmdsZSBwb2x5Z29uXHJcbiAgLy8gICAgICAgICAgIGcuYmVnaW5QYXRoKCk7XHJcbiAgLy8gICAgICAgICAgIGcubW92ZVRvKDAsIHkgKyAoY2hIIC8gMikgKyBwc01pblswXSAqIGNoSCAvIDIpO1xyXG4gIC8vXHJcbiAgLy8gICAgICAgICAgIGZvciAobGV0IHBpaSA9IDA7IHBpaSA8IHc7IHBpaSsrKSB7XHJcbiAgLy8gICAgICAgICAgICAgbGV0IHB2ID0gcHNNaW5bcGlpXSAqIGNoSCAvIDI7XHJcbiAgLy8gICAgICAgICAgICAgLy9jb25zb2xlLmxvZyhcIk1pbjogXCIscHYpO1xyXG4gIC8vICAgICAgICAgICAgIGcubGluZVRvKHBpaSwgeSArIChjaEggLyAyKSArIHB2KTtcclxuICAvLyAgICAgICAgICAgfVxyXG4gIC8vICAgICAgICAgICBmb3IgKGxldCBwaWkgPSB3OyBwaWkgPj0gMDsgcGlpLS0pIHtcclxuICAvLyAgICAgICAgICAgICBsZXQgcHYgPSBwc01heFtwaWldICogY2hIIC8gMjtcclxuICAvLyAgICAgICAgICAgICAvL2NvbnNvbGUubG9nKFwiTWF4OiBcIixwdik7XHJcbiAgLy8gICAgICAgICAgICAgZy5saW5lVG8ocGlpLCB5ICsgKGNoSCAvIDIpICsgcHYpO1xyXG4gIC8vICAgICAgICAgICB9XHJcbiAgLy8gICAgICAgICAgIGcuY2xvc2VQYXRoKCk7XHJcbiAgLy8gICAgICAgICAgIC8vZy5saW5lVG8oKVxyXG4gIC8vICAgICAgICAgICBnLmZpbGwoKTtcclxuICAvLyAgICAgICAgICAgZy5zdHJva2UoKTtcclxuICAvLyAgICAgICAgICAgZy5maWxsU3R5bGUgPSBcInllbGxvd1wiO1xyXG4gIC8vICAgICAgICAgICBnLnN0cm9rZSgpO1xyXG4gIC8vICAgICAgICAgICB5ICs9IGNoSDtcclxuICAvLyAgICAgICAgIH1cclxuICAvLyAgICAgICBhaXM/LmNsb3NlKCk7XHJcbiAgLy8gICAgIH1cclxuICAvLyAgIH1cclxuICAvLyB9XHJcblxyXG4gIHNldERhdGEoYXVkaW9EYXRhOiBBdWRpb0RhdGFIb2xkZXIgfCBudWxsKSB7XHJcbiAgICB0aGlzLl9hdWRpb0RhdGFIb2xkZXIgPSBhdWRpb0RhdGE7XHJcbiAgICB0aGlzLnBsYXlGcmFtZVBvc2l0aW9uID0gMDtcclxuICB9XHJcbn1cclxuXHJcbiJdfQ==