speechrecorderng 3.0.1 → 3.3.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 (141) hide show
  1. package/esm2020/lib/action/action.mjs +2 -1
  2. package/esm2020/lib/audio/array_audio_buffer.mjs +65 -2
  3. package/esm2020/lib/audio/array_audio_buffer_input_stream.mjs +2 -2
  4. package/esm2020/lib/audio/array_audio_buffer_random_access_stream.mjs +16 -0
  5. package/esm2020/lib/audio/audio_data_holder.mjs +203 -48
  6. package/esm2020/lib/audio/audio_display.mjs +10 -34
  7. package/esm2020/lib/audio/audio_player.mjs +18 -45
  8. package/esm2020/lib/audio/capture/capture.mjs +293 -69
  9. package/esm2020/lib/audio/dsp/level_measure.mjs +211 -88
  10. package/esm2020/lib/audio/impl/wavformat.mjs +1 -1
  11. package/esm2020/lib/audio/impl/wavreader.mjs +134 -0
  12. package/esm2020/lib/audio/impl/wavwriter.mjs +10 -9
  13. package/esm2020/lib/audio/inddb_audio_buffer.mjs +508 -0
  14. package/esm2020/lib/audio/net_audio_buffer.mjs +297 -0
  15. package/esm2020/lib/audio/persistor.mjs +8 -2
  16. package/esm2020/lib/audio/playback/array_audio_buffer_source_node.mjs +15 -154
  17. package/esm2020/lib/audio/playback/audio_source_node.mjs +18 -0
  18. package/esm2020/lib/audio/playback/audio_source_worklet_module_loader.mjs +167 -0
  19. package/esm2020/lib/audio/playback/inddb_audio_buffer_source_node.mjs +167 -0
  20. package/esm2020/lib/audio/playback/net_audio_buffer_source_node.mjs +218 -0
  21. package/esm2020/lib/audio/playback/player.mjs +190 -171
  22. package/esm2020/lib/audio/ui/audio_canvas_layer_comp.mjs +35 -76
  23. package/esm2020/lib/audio/ui/audio_display_control.mjs +12 -24
  24. package/esm2020/lib/audio/ui/audio_display_scroll_pane.mjs +14 -45
  25. package/esm2020/lib/audio/ui/audiosignal.mjs +333 -267
  26. package/esm2020/lib/audio/ui/container.mjs +40 -57
  27. package/esm2020/lib/audio/ui/livelevel.mjs +53 -52
  28. package/esm2020/lib/audio/ui/scroll_pane_horizontal.mjs +5 -19
  29. package/esm2020/lib/audio/ui/sonagram.mjs +386 -339
  30. package/esm2020/lib/db/inddb.mjs +120 -0
  31. package/esm2020/lib/io/BinaryReader.mjs +85 -0
  32. package/esm2020/lib/io/stream.mjs +101 -1
  33. package/esm2020/lib/net/uploader.mjs +111 -5
  34. package/esm2020/lib/recorder_component.mjs +59 -1
  35. package/esm2020/lib/speechrecorder/project/project.mjs +10 -1
  36. package/esm2020/lib/speechrecorder/project/project.service.mjs +3 -3
  37. package/esm2020/lib/speechrecorder/recording.mjs +19 -6
  38. package/esm2020/lib/speechrecorder/recordings/basic_recording.service.mjs +213 -0
  39. package/esm2020/lib/speechrecorder/recordings/recordings.service.mjs +724 -54
  40. package/esm2020/lib/speechrecorder/script/script.service.mjs +3 -3
  41. package/esm2020/lib/speechrecorder/session/audiorecorder.mjs +358 -184
  42. package/esm2020/lib/speechrecorder/session/basicrecorder.mjs +181 -28
  43. package/esm2020/lib/speechrecorder/session/controlpanel.mjs +47 -129
  44. package/esm2020/lib/speechrecorder/session/item.mjs +13 -1
  45. package/esm2020/lib/speechrecorder/session/progress.mjs +26 -55
  46. package/esm2020/lib/speechrecorder/session/prompting.mjs +33 -176
  47. package/esm2020/lib/speechrecorder/session/recorder_combi_pane.mjs +6 -6
  48. package/esm2020/lib/speechrecorder/session/recording_file_cache.mjs +10 -10
  49. package/esm2020/lib/speechrecorder/session/recording_list.mjs +92 -55
  50. package/esm2020/lib/speechrecorder/session/recordingfile/recording-file-meta.component.mjs +9 -13
  51. package/esm2020/lib/speechrecorder/session/recordingfile/recording-file-navi.component.mjs +9 -18
  52. package/esm2020/lib/speechrecorder/session/recordingfile/recording-file-u-i.component.mjs +10 -36
  53. package/esm2020/lib/speechrecorder/session/recordingfile/recording-file-view.component.mjs +10 -37
  54. package/esm2020/lib/speechrecorder/session/recordingfile/recordingfile-service.mjs +80 -56
  55. package/esm2020/lib/speechrecorder/session/session.service.mjs +3 -3
  56. package/esm2020/lib/speechrecorder/session/session_finished_dialog.mjs +4 -4
  57. package/esm2020/lib/speechrecorder/session/sessionmanager.mjs +409 -165
  58. package/esm2020/lib/speechrecorder/session/warning_bar.mjs +6 -29
  59. package/esm2020/lib/speechrecorder/spruploader.mjs +3 -3
  60. package/esm2020/lib/speechrecorder/startstopsignal/ui/simpletrafficlight.mjs +6 -41
  61. package/esm2020/lib/speechrecorderng.component.mjs +42 -31
  62. package/esm2020/lib/speechrecorderng.module.mjs +5 -5
  63. package/esm2020/lib/spr.config.mjs +3 -3
  64. package/esm2020/lib/spr.module.version.mjs +2 -2
  65. package/esm2020/lib/ui/canvas_layer_comp.mjs +3 -3
  66. package/esm2020/lib/ui/message_dialog.mjs +7 -7
  67. package/esm2020/lib/ui/recordingitem_display.mjs +26 -59
  68. package/esm2020/lib/utils/scrollIntoViewToBottom.mjs +3 -3
  69. package/esm2020/lib/utils/ua-parser.mjs +28 -4
  70. package/esm2020/lib/utils/utils.mjs +29 -1
  71. package/fesm2015/speechrecorderng.mjs +12675 -9136
  72. package/fesm2015/speechrecorderng.mjs.map +1 -1
  73. package/fesm2020/speechrecorderng.mjs +11580 -8050
  74. package/fesm2020/speechrecorderng.mjs.map +1 -1
  75. package/{speechrecorderng.d.ts → index.d.ts} +0 -0
  76. package/lib/audio/array_audio_buffer.d.ts +17 -1
  77. package/lib/audio/array_audio_buffer_random_access_stream.d.ts +9 -0
  78. package/lib/audio/audio_data_holder.d.ts +69 -14
  79. package/lib/audio/audio_display.d.ts +1 -1
  80. package/lib/audio/audio_player.d.ts +3 -7
  81. package/lib/audio/capture/capture.d.ts +24 -4
  82. package/lib/audio/dsp/level_measure.d.ts +2 -23
  83. package/lib/audio/impl/wavformat.d.ts +3 -3
  84. package/lib/audio/impl/wavreader.d.ts +16 -0
  85. package/lib/audio/impl/wavwriter.d.ts +1 -4
  86. package/lib/audio/inddb_audio_buffer.d.ts +68 -0
  87. package/lib/audio/net_audio_buffer.d.ts +59 -0
  88. package/lib/audio/persistor.d.ts +3 -9
  89. package/lib/audio/playback/array_audio_buffer_source_node.d.ts +2 -8
  90. package/lib/audio/playback/audio_source_node.d.ts +10 -0
  91. package/lib/audio/playback/audio_source_worklet_module_loader.d.ts +4 -0
  92. package/lib/audio/playback/inddb_audio_buffer_source_node.d.ts +21 -0
  93. package/lib/audio/playback/net_audio_buffer_source_node.d.ts +27 -0
  94. package/lib/audio/playback/player.d.ts +19 -16
  95. package/lib/audio/ui/audio_canvas_layer_comp.d.ts +3 -3
  96. package/lib/audio/ui/audio_display_control.d.ts +3 -6
  97. package/lib/audio/ui/audio_display_scroll_pane.d.ts +1 -1
  98. package/lib/audio/ui/audiosignal.d.ts +4 -3
  99. package/lib/audio/ui/container.d.ts +1 -1
  100. package/lib/audio/ui/livelevel.d.ts +11 -4
  101. package/lib/audio/ui/scroll_pane_horizontal.d.ts +1 -1
  102. package/lib/audio/ui/sonagram.d.ts +4 -3
  103. package/lib/db/inddb.d.ts +21 -0
  104. package/lib/io/BinaryReader.d.ts +18 -0
  105. package/lib/io/stream.d.ts +18 -0
  106. package/lib/net/uploader.d.ts +20 -2
  107. package/lib/recorder_component.d.ts +5 -0
  108. package/lib/speechrecorder/project/project.d.ts +9 -0
  109. package/lib/speechrecorder/recording.d.ts +7 -2
  110. package/lib/speechrecorder/recordings/basic_recording.service.d.ts +27 -0
  111. package/lib/speechrecorder/recordings/recordings.service.d.ts +21 -6
  112. package/lib/speechrecorder/session/audiorecorder.d.ts +7 -18
  113. package/lib/speechrecorder/session/basicrecorder.d.ts +28 -4
  114. package/lib/speechrecorder/session/controlpanel.d.ts +7 -7
  115. package/lib/speechrecorder/session/item.d.ts +1 -0
  116. package/lib/speechrecorder/session/progress.d.ts +2 -1
  117. package/lib/speechrecorder/session/prompting.d.ts +5 -5
  118. package/lib/speechrecorder/session/recorder_combi_pane.d.ts +1 -1
  119. package/lib/speechrecorder/session/recording_list.d.ts +2 -1
  120. package/lib/speechrecorder/session/recordingfile/recording-file-meta.component.d.ts +1 -1
  121. package/lib/speechrecorder/session/recordingfile/recording-file-navi.component.d.ts +1 -1
  122. package/lib/speechrecorder/session/recordingfile/recording-file-u-i.component.d.ts +1 -1
  123. package/lib/speechrecorder/session/recordingfile/recording-file-view.component.d.ts +1 -1
  124. package/lib/speechrecorder/session/recordingfile/recordingfile-service.d.ts +4 -5
  125. package/lib/speechrecorder/session/session_finished_dialog.d.ts +1 -1
  126. package/lib/speechrecorder/session/sessionmanager.d.ts +10 -10
  127. package/lib/speechrecorder/session/warning_bar.d.ts +1 -1
  128. package/lib/speechrecorder/startstopsignal/ui/simpletrafficlight.d.ts +1 -1
  129. package/lib/speechrecorderng.component.d.ts +2 -1
  130. package/lib/spr.module.version.d.ts +1 -1
  131. package/lib/ui/canvas_layer_comp.d.ts +1 -1
  132. package/lib/ui/message_dialog.d.ts +1 -1
  133. package/lib/ui/recordingitem_display.d.ts +3 -2
  134. package/lib/utils/scrollIntoViewToBottom.d.ts +1 -1
  135. package/lib/utils/ua-parser.d.ts +4 -1
  136. package/lib/utils/utils.d.ts +6 -0
  137. package/package.json +5 -4
  138. package/esm2020/lib/math/utils.mjs +0 -14
  139. package/esm2020/lib/utils/css_utils.mjs +0 -7
  140. package/lib/math/utils.d.ts +0 -3
  141. package/lib/utils/css_utils.d.ts +0 -3
@@ -1,139 +1,15 @@
1
1
  import { ArrayAudioBufferInputStream } from "../array_audio_buffer_input_stream";
2
2
  import { EditFloat32ArrayInputStream } from "../../io/stream";
3
- // Code from audio_source_worklet.js as string constant to be loaded as module
4
- // Changes in audio_source_worklet.js must be copied and pasted to this string constant
5
- const aswpStr = "\n" +
6
- "// Important note: Changes in audio_source_worklet.js must be copied and pasted to the string constant aswpStr in array_audio_buffer_source_node.ts\n" +
7
- "\n" +
8
- "\n" +
9
- "class AudioSourceProcessor extends AudioWorkletProcessor{\n" +
10
- "\n" +
11
- " filledFrames=0;\n" +
12
- " audioBuffers=new Array();\n" +
13
- " currentAudioBuffer=null;\n" +
14
- " currentAudioBufferFramePos=0;\n" +
15
- " currentAudioBufferAvail=0;\n" +
16
- " running=false;\n" +
17
- " ended=false;\n" +
18
- "\n" +
19
- " constructor() {\n" +
20
- " super({numberOfInputs:0,numberOfOutputs:1});\n" +
21
- " this.port.onmessage=(msgEv)=>{\n" +
22
- " // received audio playback data from application\n" +
23
- " //console.debug(\"Audio source worklet msg: Received.\");\n" +
24
- "\n" +
25
- " if(msgEv.data.cmd){\n" +
26
- " if('data'===msgEv.data.cmd) {\n" +
27
- " let chs = msgEv.data.chs;\n" +
28
- "\n" +
29
- " let audioData = new Array(chs);\n" +
30
- " for (let ch = 0; ch < chs; ch++) {\n" +
31
- " audioData[ch] = new Float32Array(msgEv.data.audioData[ch]);\n" +
32
- " }\n" +
33
- " let msgChBufLen=audioData[0].length;\n" +
34
- " this.audioBuffers.push(audioData);\n" +
35
- " this.filledFrames += msgChBufLen;\n" +
36
- " //console.debug(\"Audio source worklet msg: Filled \" + this.filledFrames+ \" in \"+this.audioBuffers.length+\" buffers.\");\n" +
37
- "\n" +
38
- " }else if('start'===msgEv.data.cmd){\n" +
39
- " this.running=true;\n" +
40
- " }else if('stop'===msgEv.data.cmd){\n" +
41
- " //console.debug(\"Stop...\");\n" +
42
- " this.running=false;\n" +
43
- " // clear buffers\n" +
44
- " this.filledFrames=0;\n" +
45
- " while(this.audioBuffers.length > 0) {\n" +
46
- " this.audioBuffers.pop();\n" +
47
- " }\n" +
48
- " this.currentAudioBuffer=new Float32Array(0);\n" +
49
- " }\n" +
50
- " }\n" +
51
- " }\n" +
52
- " }\n" +
53
- "\n" +
54
- " process(\n" +
55
- " inputs,\n" +
56
- " outputs,\n" +
57
- " parameters\n" +
58
- " ){\n" +
59
- " //console.debug(\"Audio source worklet: process \"+outputs.length+ \" output buffers.\");\n" +
60
- " // copy ring buffer data to outputs\n" +
61
- " if(!this.running){\n" +
62
- " return !this.ended;\n" +
63
- " }\n" +
64
- "\n" +
65
- " let output=outputs[0];\n" +
66
- " let chs=output.length;\n" +
67
- " //console.debug(\"Audio source worklet: Output channels: \"+chs);\n" +
68
- " if(chs>0) {\n" +
69
- "\n" +
70
- " let outCh0 = output[0];\n" +
71
- " let outChLen = outCh0.length;\n" +
72
- "\n" +
73
- " if(!this.currentAudioBuffer){\n" +
74
- " // get first buffer\n" +
75
- " let nxtBuff=this.audioBuffers.shift();\n" +
76
- " if(nxtBuff) {\n" +
77
- " this.currentAudioBuffer = nxtBuff;\n" +
78
- " this.currentAudioBufferFramePos=0;\n" +
79
- " this.currentAudioBufferAvail=this.currentAudioBuffer[0].length;\n" +
80
- " }else{\n" +
81
- " return true;\n" +
82
- " }\n" +
83
- " }\n" +
84
- "\n" +
85
- " let copied=0;\n" +
86
- " do{\n" +
87
- " if(this.currentAudioBufferAvail==0){\n" +
88
- " let nxtBuff=this.audioBuffers.shift();\n" +
89
- " if(nxtBuff){\n" +
90
- " this.currentAudioBuffer=nxtBuff;\n" +
91
- " this.currentAudioBufferFramePos=0;\n" +
92
- " this.currentAudioBufferAvail=this.currentAudioBuffer[0].length;\n" +
93
- " //console.debug(\"Next buffer with \"+this.currentAudioBufferAvail+ \" frames\");\n" +
94
- " this.port.postMessage({eventType:'bufferNotification',filledFrames:this.filledFrames});\n" +
95
- " }else{\n" +
96
- " this.ended=true;\n" +
97
- " this.port.postMessage({eventType:'ended'});\n" +
98
- " //console.debug(\"Stream ended\");\n" +
99
- " break;\n" +
100
- " }\n" +
101
- " }\n" +
102
- " //console.debug(\"outChLen: \"+outChLen+\", copied: \"+copied+\", current avail: \"+this.currentAudioBufferAvail);\n" +
103
- " let toCopy=outChLen-copied;\n" +
104
- " if(toCopy>this.currentAudioBufferAvail){\n" +
105
- " toCopy=this.currentAudioBufferAvail;\n" +
106
- " }\n" +
107
- " //console.debug(\"Copy \"+toCopy+\" frames...\");\n" +
108
- " for(let ch=0;ch<chs;ch++) {\n" +
109
- " let outCh=output[ch];\n" +
110
- " for (let i = 0; i < toCopy; i++) {\n" +
111
- " outCh[copied+i]=this.currentAudioBuffer[ch][this.currentAudioBufferFramePos+i];\n" +
112
- " }\n" +
113
- " }\n" +
114
- " copied+=toCopy;\n" +
115
- " this.currentAudioBufferFramePos+=toCopy;\n" +
116
- " this.currentAudioBufferAvail-=toCopy;\n" +
117
- "\n" +
118
- " }while(copied<outChLen);\n" +
119
- " this.filledFrames-=copied;\n" +
120
- " //console.debug(\"Copied \"+copied+\" frames.\");\n" +
121
- " }\n" +
122
- " return !this.ended;\n" +
123
- " }\n" +
124
- "}\n" +
125
- "\n" +
126
- "registerProcessor('audio-source-worklet',AudioSourceProcessor);\n";
127
- export class ArrayAudioBufferSourceNode extends AudioWorkletNode {
3
+ import { AudioSourceNode } from "./audio_source_node";
4
+ export class ArrayAudioBufferSourceNode extends AudioSourceNode {
128
5
  constructor(context) {
129
6
  super(context, 'audio-source-worklet');
130
- this._bufferFillSeconds = ArrayAudioBufferSourceNode.DEFAULT_BUFFER_FILL_SECONDS;
7
+ this._bufferFillSeconds = AudioSourceNode.DEFAULT_BUFFER_FILL_SECONDS;
131
8
  this.bufferFillFrames = 0;
132
9
  this._arrayAudioBuffer = null;
133
10
  this._audioInputStream = null;
134
11
  this._aisBufs = null;
135
12
  this.filledFrames = 0;
136
- this.onended = null;
137
13
  this.channelCountMode = 'explicit';
138
14
  this.port.onmessage = (msgEv) => {
139
15
  if (msgEv.data) {
@@ -183,6 +59,9 @@ export class ArrayAudioBufferSourceNode extends AudioWorkletNode {
183
59
  filled += read;
184
60
  }
185
61
  else {
62
+ this.port.postMessage({
63
+ cmd: 'endOfStream'
64
+ });
186
65
  break;
187
66
  }
188
67
  }
@@ -206,7 +85,7 @@ export class ArrayAudioBufferSourceNode extends AudioWorkletNode {
206
85
  }
207
86
  start(when, offset, duration) {
208
87
  if (when) {
209
- throw Error("when, offest,duration parameters currently not supported by ArrayAudioBufferSourceNode class");
88
+ throw Error("when parameter currently not supported by ArrayAudioBufferSourceNode class");
210
89
  }
211
90
  if (this._arrayAudioBuffer) {
212
91
  let arrAis = new ArrayAudioBufferInputStream(this._arrayAudioBuffer);
@@ -227,10 +106,16 @@ export class ArrayAudioBufferSourceNode extends AudioWorkletNode {
227
106
  let chs = this._arrayAudioBuffer.channelCount;
228
107
  this._aisBufs = new Array(chs);
229
108
  for (let ch = 0; ch < chs; ch++) {
230
- this._aisBufs[ch] = new Float32Array(1024);
109
+ this._aisBufs[ch] = new Float32Array(ArrayAudioBufferSourceNode.DEFAULT_STREAM_READ_FRAME_LEN);
231
110
  }
232
111
  this.fillBuffer();
233
112
  this.port.postMessage({ cmd: 'start' });
113
+ if (offset) {
114
+ this._playStartTime = this.context.currentTime - offset;
115
+ }
116
+ else {
117
+ this._playStartTime = this.context.currentTime;
118
+ }
234
119
  }
235
120
  }
236
121
  stop() {
@@ -238,28 +123,4 @@ export class ArrayAudioBufferSourceNode extends AudioWorkletNode {
238
123
  this.onended?.call(this);
239
124
  }
240
125
  }
241
- ArrayAudioBufferSourceNode.QUANTUM_FRAME_LEN = 128;
242
- ArrayAudioBufferSourceNode.DEFAULT_BUFFER_FILL_SECONDS = 10;
243
- export class AudioSourceWorkletModuleLoader {
244
- static loadModule(context) {
245
- return new Promise((resolve, reject) => {
246
- if (AudioSourceWorkletModuleLoader.moduleLoaded) {
247
- resolve.call(self);
248
- }
249
- else {
250
- let audioWorkletModuleBlob = new Blob([aswpStr], { type: 'text/javascript' });
251
- let audioWorkletModuleBlobUrl = window.URL.createObjectURL(audioWorkletModuleBlob);
252
- context.resume();
253
- context.audioWorklet.addModule(audioWorkletModuleBlobUrl).then(() => {
254
- AudioSourceWorkletModuleLoader.moduleLoaded = true;
255
- resolve.call(self);
256
- }).catch((reason) => {
257
- console.error(reason);
258
- reject.call(reason);
259
- });
260
- }
261
- });
262
- }
263
- }
264
- AudioSourceWorkletModuleLoader.moduleLoaded = false;
265
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYXJyYXlfYXVkaW9fYnVmZmVyX3NvdXJjZV9ub2RlLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vLi4vcHJvamVjdHMvc3BlZWNocmVjb3JkZXJuZy9zcmMvbGliL2F1ZGlvL3BsYXliYWNrL2FycmF5X2F1ZGlvX2J1ZmZlcl9zb3VyY2Vfbm9kZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFDQSxPQUFPLEVBQUMsMkJBQTJCLEVBQUMsTUFBTSxvQ0FBb0MsQ0FBQztBQUMvRSxPQUFPLEVBQUMsMkJBQTJCLEVBQTBCLE1BQU0saUJBQWlCLENBQUM7QUFFckYsOEVBQThFO0FBQzlFLHVGQUF1RjtBQUV2RixNQUFNLE9BQU8sR0FBRyxJQUFJO0lBQ2xCLHVKQUF1SjtJQUN2SixJQUFJO0lBQ0osSUFBSTtJQUNKLDZEQUE2RDtJQUM3RCxJQUFJO0lBQ0osdUJBQXVCO0lBQ3ZCLGlDQUFpQztJQUNqQyxnQ0FBZ0M7SUFDaEMscUNBQXFDO0lBQ3JDLGtDQUFrQztJQUNsQyxzQkFBc0I7SUFDdEIsb0JBQW9CO0lBQ3BCLElBQUk7SUFDSix1QkFBdUI7SUFDdkIsd0RBQXdEO0lBQ3hELDBDQUEwQztJQUMxQyw4REFBOEQ7SUFDOUQsdUVBQXVFO0lBQ3ZFLElBQUk7SUFDSixpQ0FBaUM7SUFDakMsNkNBQTZDO0lBQzdDLDJDQUEyQztJQUMzQyxJQUFJO0lBQ0osaURBQWlEO0lBQ2pELG9EQUFvRDtJQUNwRCwrRUFBK0U7SUFDL0UsbUJBQW1CO0lBQ25CLHNEQUFzRDtJQUN0RCxvREFBb0Q7SUFDcEQsbURBQW1EO0lBQ25ELDhJQUE4STtJQUM5SSxJQUFJO0lBQ0osbURBQW1EO0lBQ25ELG9DQUFvQztJQUNwQyxrREFBa0Q7SUFDbEQsK0NBQStDO0lBQy9DLHFDQUFxQztJQUNyQyxrQ0FBa0M7SUFDbEMsc0NBQXNDO0lBQ3RDLHVEQUF1RDtJQUN2RCw0Q0FBNEM7SUFDNUMsbUJBQW1CO0lBQ25CLDhEQUE4RDtJQUM5RCxpQkFB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O0lBQ0wsQ0FBQzs7QUFsQmMsMkNBQVksR0FBQyxLQUFLLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQge0FycmF5QXVkaW9CdWZmZXJ9IGZyb20gXCIuLi9hcnJheV9hdWRpb19idWZmZXJcIjtcclxuaW1wb3J0IHtBcnJheUF1ZGlvQnVmZmVySW5wdXRTdHJlYW19IGZyb20gXCIuLi9hcnJheV9hdWRpb19idWZmZXJfaW5wdXRfc3RyZWFtXCI7XHJcbmltcG9ydCB7RWRpdEZsb2F0MzJBcnJheUlucHV0U3RyZWFtLCBGbG9hdDMyQXJyYXlJbnB1dFN0cmVhbX0gZnJvbSBcIi4uLy4uL2lvL3N0cmVhbVwiO1xyXG5cclxuLy8gQ29kZSBmcm9tIGF1ZGlvX3NvdXJjZV93b3JrbGV0LmpzIGFzIHN0cmluZyBjb25zdGFudCB0byBiZSBsb2FkZWQgYXMgbW9kdWxlXHJcbi8vIENoYW5nZXMgaW4gYXVkaW9fc291cmNlX3dvcmtsZXQuanMgbXVzdCBiZSBjb3BpZWQgYW5kIHBhc3RlZCB0byB0aGlzIHN0cmluZyBjb25zdGFudFxyXG5cclxuY29uc3QgYXN3cFN0ciA9IFwiXFxuXCIgK1xyXG4gIFwiLy8gSW1wb3J0YW50IG5vdGU6IENoYW5nZXMgaW4gYXVkaW9fc291cmNlX3dvcmtsZXQuanMgbXVzdCBiZSBjb3BpZWQgYW5kIHBhc3RlZCB0byB0aGUgc3RyaW5nIGNvbnN0YW50IGFzd3BTdHIgaW4gYXJyYXlfYXVkaW9fYnVmZmVyX3NvdXJjZV9ub2RlLnRzXFxuXCIgK1xyXG4gIFwiXFxuXCIgK1xyXG4gIFwiXFxuXCIgK1xyXG4gIFwiY2xhc3MgQXVkaW9Tb3VyY2VQcm9jZXNzb3IgZXh0ZW5kcyBBdWRpb1dvcmtsZXRQcm9jZXNzb3J7XFxuXCIgK1xyXG4gIFwiXFxuXCIgK1xyXG4gIFwiICAgIGZpbGxlZEZyYW1lcz0wO1xcblwiICtcclxuICBcIiAgICBhdWRpb0J1ZmZlcnM9bmV3IEFycmF5KCk7XFxuXCIgK1xyXG4gIFwiICAgIGN1cnJlbnRBdWRpb0J1ZmZlcj1udWxsO1xcblwiICtcclxuICBcIiAgICBjdXJyZW50QXVkaW9CdWZmZXJGcmFtZVBvcz0wO1xcblwiICtcclxuICBcIiAgICBjdXJyZW50QXVkaW9CdWZmZXJBdmFpbD0wO1xcblwiICtcclxuICBcIiAgICBydW5uaW5nPWZhbHNlO1xcblwiICtcclxuICBcIiAgICBlbmRlZD1mYWxzZTtcXG5cIiArXHJcbiAgXCJcXG5cIiArXHJcbiAgXCIgICAgY29uc3RydWN0b3IoKSB7XFxuXCIgK1xyXG4gIFwiICAgICAgICBzdXBlcih7bnVtYmVyT2ZJbnB1dHM6MCxudW1iZXJPZk91dHB1dHM6MX0pO1xcblwiICtcclxuICBcIiAgICAgICAgdGhpcy5wb3J0Lm9ubWVzc2FnZT0obXNnRXYpPT57XFxuXCIgK1xyXG4gIFwiICAgICAgICAgIC8vIHJlY2VpdmVkIGF1ZGlvIHBsYXliYWNrIGRhdGEgZnJvbSBhcHBsaWNhdGlvblxcblwiICtcclxuICBcIiAgICAgICAgICAvL2NvbnNvbGUuZGVidWcoXFxcIkF1ZGlvIHNvdXJjZSB3b3JrbGV0IG1zZzogUmVjZWl2ZWQuXFxcIik7XFxuXCIgK1xyXG4gIFwiXFxuXCIgK1xyXG4gIFwiICAgICAgICAgIGlmKG1zZ0V2LmRhdGEuY21kKXtcXG5cIiArXHJcbiAgXCIgICAgICAgICAgICBpZignZGF0YSc9PT1tc2dFdi5kYXRhLmNtZCkge1xcblwiICtcclxuICBcIiAgICAgICAgICAgICAgbGV0IGNocyA9IG1zZ0V2LmRhdGEuY2hzO1xcblwiICtcclxuICBcIlxcblwiICtcclxuICBcIiAgICAgICAgICAgICAgbGV0IGF1ZGlvRGF0YSA9IG5ldyBBcnJheShjaHMpO1xcblwiICtcclxuICBcIiAgICAgICAgICAgICAgZm9yIChsZXQgY2ggPSAwOyBjaCA8IGNoczsgY2grKykge1xcblwiICtcclxuICBcIiAgICAgICAgICAgICAgICBhdWRpb0RhdGFbY2hdID0gbmV3IEZsb2F0MzJBcnJheShtc2dFdi5kYXRhLmF1ZGlvRGF0YVtjaF0pO1xcblwiICtcclxuICBcIiAgICAgICAgICAgICAgfVxcblwiICtcclxuICBcIiAgICAgICAgICAgICAgbGV0IG1zZ0NoQnVmTGVuPWF1ZGlvRGF0YVswXS5sZW5ndGg7XFxuXCIgK1xyXG4gIFwiICAgICAgICAgICAgICB0aGlzLmF1ZGlvQnVmZmVycy5wdXNoKGF1ZGlvRGF0YSk7XFxuXCIgK1xyXG4gIFwiICAgICAgICAgICAgICB0aGlzLmZpbGxlZEZyYW1lcyArPSBtc2dDaEJ1ZkxlbjtcXG5cIiArXHJcbiAgXCIgICAgICAgICAgICAgIC8vY29uc29sZS5kZWJ1ZyhcXFwiQXVkaW8gc291cmNlIHdvcmtsZXQgbXNnOiBGaWxsZWQgXFxcIiArIHRoaXMuZmlsbGVkRnJhbWVzKyBcXFwiIGluIFxcXCIrdGhpcy5hdWRpb0J1ZmZlcnMubGVuZ3RoK1xcXCIgYnVmZmVycy5cXFwiKTtcXG5cIiArXHJcbiAgXCJcXG5cIiArXHJcbiAgXCIgICAgICAgICAgICB9ZWxzZSBpZignc3RhcnQnPT09bXNnRXYuZGF0YS5jbWQpe1xcblwiICtcclxuICBcIiAgICAgICAgICAgICAgdGhpcy5ydW5uaW5nPXRydWU7XFxuXCIgK1xyXG4gIFwiICAgICAgICAgICAgfWVsc2UgaWYoJ3N0b3AnPT09bXNnRXYuZGF0YS5jbWQpe1xcblwiICtcclxuICBcIiAgICAgICAgICAgICAgLy9jb25zb2xlLmRlYnVnKFxcXCJTdG9wLi4uXFxcIik7XFxuXCIgK1xyXG4gIFwiICAgICAgICAgICAgICB0aGlzLnJ1bm5pbmc9ZmFsc2U7XFxuXCIgK1xyXG4gIFwiICAgICAgICAgICAgICAvLyBjbGVhciBidWZmZXJzXFxuXCIgK1xyXG4gIFwiICAgICAgICAgICAgICB0aGlzLmZpbGxlZEZyYW1lcz0wO1xcblwiICtcclxuICBcIiAgICAgICAgICAgICAgd2hpbGUodGhpcy5hdWRpb0J1ZmZlcnMubGVuZ3RoID4gMCkge1xcblwiICtcclxuICBcIiAgICAgICAgICAgICAgICB0aGlzLmF1ZGlvQnVmZmVycy5wb3AoKTtcXG5cIiArXHJcbiAgXCIgICAgICAgICAgICAgIH1cXG5cIiArXHJcbiAgXCIgICAgICAgICAgICAgIHRoaXMuY3VycmVudEF1ZGlvQnVmZmVyPW5ldyBGbG9hdDMyQXJyYXkoMCk7XFxuXCIgK1xyXG4gIFwiICAgICAgICAgICAgfVxcblwiICtcclxuICBcIiAgICAgICAgICB9XFxuXCIgK1xyXG4gIFwiICAgICAgICB9XFxuXCIgK1xyXG4gIFwiICAgIH1cXG5cIiArXHJcbiAgXCJcXG5cIiArXHJcbiAgXCIgcHJvY2VzcyhcXG5cIiArXHJcbiAgXCIgICAgICBpbnB1dHMsXFxuXCIgK1xyXG4gIFwiICAgICAgb3V0cHV0cyxcXG5cIiArXHJcbiAgXCIgICAgICBwYXJhbWV0ZXJzXFxuXCIgK1xyXG4gIFwiICApe1xcblwiICtcclxuICBcIiAgICAgIC8vY29uc29sZS5kZWJ1ZyhcXFwiQXVkaW8gc291cmNlIHdvcmtsZXQ6IHByb2Nlc3MgXFxcIitvdXRwdXRzLmxlbmd0aCsgXFxcIiBvdXRwdXQgYnVmZmVycy5cXFwiKTtcXG5cIiArXHJcbiAgXCIgICAgICAvLyBjb3B5IHJpbmcgYnVmZmVyIGRhdGEgdG8gb3V0cHV0c1xcblwiICtcclxuICBcIiAgICAgICAgaWYoIXRoaXMucnVubmluZyl7XFxuXCIgK1xyXG4gIFwiICAgICAgICAgIHJldHVybiAhdGhpcy5lbmRlZDtcXG5cIiArXHJcbiAgXCIgICAgICAgIH1cXG5cIiArXHJcbiAgXCJcXG5cIiArXHJcbiAgXCIgICAgICAgIGxldCBvdXRwdXQ9b3V0cHV0c1swXTtcXG5cIiArXHJcbiAgXCIgICAgICAgIGxldCBjaHM9b3V0cHV0Lmxlbmd0aDtcXG5cIiArXHJcbiAgXCIgICAgICAgIC8vY29uc29sZS5kZWJ1ZyhcXFwiQXVkaW8gc291cmNlIHdvcmtsZXQ6IE91dHB1dCBjaGFubmVsczogXFxcIitjaHMpO1xcblwiICtcclxuICBcIiAgICAgICAgaWYoY2hzPjApIHtcXG5cIiArXHJcbiAgXCJcXG5cIiArXHJcbiAgXCIgICAgICAgICAgbGV0IG91dENoMCA9IG91dHB1dFswXTtcXG5cIiArXHJcbiAgXCIgICAgICAgICAgbGV0IG91dENoTGVuID0gb3V0Q2gwLmxlbmd0aDtcXG5cIiArXHJcbiAgXCJcXG5cIiArXHJcbiAgXCIgICAgICAgICAgaWYoIXRoaXMuY3VycmVudEF1ZGlvQnVmZmVyKXtcXG5cIiArXHJcbiAgXCIgICAgICAgICAgICAvLyBnZXQgZmlyc3QgYnVmZmVyXFxuXCIgK1xyXG4gIFwiICAgICAgICAgICAgbGV0IG54dEJ1ZmY9dGhpcy5hdWRpb0J1ZmZlcnMuc2hpZnQoKTtcXG5cIiArXHJcbiAgXCIgICAgICAgICAgICBpZihueHRCdWZmKSB7XFxuXCIgK1xyXG4gIFwiICAgICAgICAgICAgICB0aGlzLmN1cnJlbnRBdWRpb0J1ZmZlciA9IG54dEJ1ZmY7XFxuXCIgK1xyXG4gIFwiICAgICAgICAgICAgICB0aGlzLmN1cnJlbnRBdWRpb0J1ZmZlckZyYW1lUG9zPTA7XFxuXCIgK1xyXG4gIFwiICAgICAgICAgICAgICB0aGlzLmN1cnJlbnRBdWRpb0J1ZmZlckF2YWlsPXRoaXMuY3VycmVudEF1ZGlvQnVmZmVyWzBdLmxlbmd0aDtcXG5cIiArXHJcbiAgXCIgICAgICAgICAgICB9ZWxzZXtcXG5cIiArXHJcbiAgXCIgICAgICAgICAgICAgIHJldHVybiB0cnVlO1xcblwiICtcclxuICBcIiAgICAgICAgICAgIH1cXG5cIiArXHJcbiAgXCIgICAgICAgICAgfVxcblwiICtcclxuICBcIlxcblwiICtcclxuICBcIiAgICAgICAgICBsZXQgY29waWVkPTA7XFxuXCIgK1xyXG4gIFwiICAgICAgICAgIGRve1xcblwiICtcclxuICBcIiAgICAgICAgICAgIGlmKHRoaXMuY3VycmVudEF1ZGlvQnVmZmVyQXZhaWw9PTApe1xcblwiICtcclxuICBcIiAgICAgICAgICAgICAgbGV0IG54dEJ1ZmY9dGhpcy5hdWRpb0J1ZmZlcnMuc2hpZnQoKTtcXG5cIiArXHJcbiAgXCIgICAgICAgICAgICAgIGlmKG54dEJ1ZmYpe1xcblwiICtcclxuICBcIiAgICAgICAgICAgICAgICB0aGlzLmN1cnJlbnRBdWRpb0J1ZmZlcj1ueHRCdWZmO1xcblwiICtcclxuICBcIiAgICAgICAgICAgICAgICB0aGlzLmN1cnJlbnRBdWRpb0J1ZmZlckZyYW1lUG9zPTA7XFxuXCIgK1xyXG4gIFwiICAgICAgICAgICAgICAgIHRoaXMuY3VycmVudEF1ZGlvQnVmZmVyQXZhaWw9dGhpcy5jdXJyZW50QXVkaW9CdWZmZXJbMF0ubGVuZ3RoO1xcblwiICtcclxuICBcIiAgICAgICAgICAgICAgICAvL2NvbnNvbGUuZGVidWcoXFxcIk5leHQgYnVmZmVyIHdpdGggXFxcIit0aGlzLmN1cnJlbnRBdWRpb0J1ZmZlckF2YWlsKyBcXFwiIGZyYW1lc1xcXCIpO1xcblwiICtcclxuICBcIiAgICAgICAgICAgICAgICB0aGlzLnBvcnQucG9zdE1lc3NhZ2Uoe2V2ZW50VHlwZTonYnVmZmVyTm90aWZpY2F0aW9uJyxmaWxsZWRGcmFtZXM6dGhpcy5maWxsZWRGcmFtZXN9KTtcXG5cIiArXHJcbiAgXCIgICAgICAgICAgICAgIH1lbHNle1xcblwiICtcclxuICBcIiAgICAgICAgICAgICAgICB0aGlzLmVuZGVkPXRydWU7XFxuXCIgK1xyXG4gIFwiICAgICAgICAgICAgICAgIHRoaXMucG9ydC5wb3N0TWVzc2FnZSh7ZXZlbnRUeXBlOidlbmRlZCd9KTtcXG5cIiArXHJcbiAgXCIgICAgICAgICAgICAgICAgLy9jb25zb2xlLmRlYnVnKFxcXCJTdHJlYW0gZW5kZWRcXFwiKTtcXG5cIiArXHJcbiAgXCIgICAgICAgICAgICAgICAgYnJlYWs7XFxuXCIgK1xyXG4gIFwiICAgICAgICAgICAgICB9XFxuXCIgK1xyXG4gIFwiICAgICAgICAgICAgfVxcblwiICtcclxuICBcIiAgICAgICAgICAgIC8vY29uc29sZS5kZWJ1ZyhcXFwib3V0Q2hMZW46IFxcXCIrb3V0Q2hMZW4rXFxcIiwgY29waWVkOiBcXFwiK2NvcGllZCtcXFwiLCBjdXJyZW50IGF2YWlsOiBcXFwiK3RoaXMuY3VycmVudEF1ZGlvQnVmZmVyQXZhaWwpO1xcblwiICtcclxuICBcIiAgICAgICAgICAgIGxldCB0b0NvcHk9b3V0Q2hMZW4tY29waWVkO1xcblwiICtcclxuICBcIiAgICAgICAgICAgIGlmKHRvQ29weT50aGlzLmN1cnJlbnRBdWRpb0J1ZmZlckF2YWlsKXtcXG5cIiArXHJcbiAgXCIgICAgICAgICAgICAgIHRvQ29weT10aGlzLmN1cnJlbnRBdWRpb0J1ZmZlckF2YWlsO1xcblwiICtcclxuICBcIiAgICAgICAgICAgIH1cXG5cIiArXHJcbiAgXCIgICAgICAgICAgICAvL2NvbnNvbGUuZGVidWcoXFxcIkNvcHkgXFxcIit0b0NvcHkrXFxcIiBmcmFtZXMuLi5cXFwiKTtcXG5cIiArXHJcbiAgXCIgICAgICAgICAgICBmb3IobGV0IGNoPTA7Y2g8Y2hzO2NoKyspIHtcXG5cIiArXHJcbiAgXCIgICAgICAgICAgICAgIGxldCBvdXRDaD1vdXRwdXRbY2hdO1xcblwiICtcclxuICBcIiAgICAgICAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCB0b0NvcHk7IGkrKykge1xcblwiICtcclxuICBcIiAgICAgICAgICAgICAgICBvdXRDaFtjb3BpZWQraV09dGhpcy5jdXJyZW50QXVkaW9CdWZmZXJbY2hdW3RoaXMuY3VycmVudEF1ZGlvQnVmZmVyRnJhbWVQb3MraV07XFxuXCIgK1xyXG4gIFwiICAgICAgICAgICAgICB9XFxuXCIgK1xyXG4gIFwiICAgICAgICAgICAgfVxcblwiICtcclxuICBcIiAgICAgICAgICAgIGNvcGllZCs9dG9Db3B5O1xcblwiICtcclxuICBcIiAgICAgICAgICAgIHRoaXMuY3VycmVudEF1ZGlvQnVmZmVyRnJhbWVQb3MrPXRvQ29weTtcXG5cIiArXHJcbiAgXCIgICAgICAgICAgICB0aGlzLmN1cnJlbnRBdWRpb0J1ZmZlckF2YWlsLT10b0NvcHk7XFxuXCIgK1xyXG4gIFwiXFxuXCIgK1xyXG4gIFwiICAgICAgICAgIH13aGlsZShjb3BpZWQ8b3V0Q2hMZW4pO1xcblwiICtcclxuICBcIiAgICAgICAgICB0aGlzLmZpbGxlZEZyYW1lcy09Y29waWVkO1xcblwiICtcclxuICBcIiAgICAgICAgICAvL2NvbnNvbGUuZGVidWcoXFxcIkNvcGllZCBcXFwiK2NvcGllZCtcXFwiIGZyYW1lcy5cXFwiKTtcXG5cIiArXHJcbiAgXCIgICAgICAgIH1cXG5cIiArXHJcbiAgXCIgICAgIHJldHVybiAhdGhpcy5lbmRlZDtcXG5cIiArXHJcbiAgXCIgIH1cXG5cIiArXHJcbiAgXCJ9XFxuXCIgK1xyXG4gIFwiXFxuXCIgK1xyXG4gIFwicmVnaXN0ZXJQcm9jZXNzb3IoJ2F1ZGlvLXNvdXJjZS13b3JrbGV0JyxBdWRpb1NvdXJjZVByb2Nlc3Nvcik7XFxuXCI7XHJcblxyXG5cclxuZXhwb3J0IGNsYXNzIEFycmF5QXVkaW9CdWZmZXJTb3VyY2VOb2RlIGV4dGVuZHMgQXVkaW9Xb3JrbGV0Tm9kZSB7XHJcblxyXG4gIHN0YXRpYyByZWFkb25seSBRVUFOVFVNX0ZSQU1FX0xFTiA9IDEyODtcclxuICBzdGF0aWMgcmVhZG9ubHkgREVGQVVMVF9CVUZGRVJfRklMTF9TRUNPTkRTID0gMTA7XHJcbiAgcHJpdmF0ZSBfYnVmZmVyRmlsbFNlY29uZHMgPSBBcnJheUF1ZGlvQnVmZmVyU291cmNlTm9kZS5ERUZBVUxUX0JVRkZFUl9GSUxMX1NFQ09ORFM7XHJcbiAgcHJpdmF0ZSBidWZmZXJGaWxsRnJhbWVzID0gMDtcclxuICBwcml2YXRlIF9hcnJheUF1ZGlvQnVmZmVyOiBBcnJheUF1ZGlvQnVmZmVyIHwgbnVsbCA9IG51bGw7XHJcbiAgcHJpdmF0ZSBfYXVkaW9JbnB1dFN0cmVhbTpGbG9hdDMyQXJyYXlJbnB1dFN0cmVhbXxudWxsPW51bGw7XHJcbiAgcHJpdmF0ZSBfYWlzQnVmczpGbG9hdDMyQXJyYXlbXXxudWxsPW51bGw7XHJcblxyXG4gIHByaXZhdGUgZmlsbGVkRnJhbWVzID0gMDtcclxuICBvbmVuZGVkOiAoKCkgPT4gdm9pZCkgfCBudWxsID0gbnVsbDtcclxuXHJcbiAgY29uc3RydWN0b3IoY29udGV4dDogQXVkaW9Db250ZXh0KSB7XHJcblxyXG4gICAgc3VwZXIoY29udGV4dCwgJ2F1ZGlvLXNvdXJjZS13b3JrbGV0Jyk7XHJcbiAgICB0aGlzLmNoYW5uZWxDb3VudE1vZGUgPSAnZXhwbGljaXQnO1xyXG4gICAgdGhpcy5wb3J0Lm9ubWVzc2FnZSA9IChtc2dFdjogTWVzc2FnZUV2ZW50KSA9PiB7XHJcbiAgICAgIGlmIChtc2dFdi5kYXRhKSB7XHJcbiAgICAgICAgbGV0IGV2VHlwZSA9IG1zZ0V2LmRhdGEuZXZlbnRUeXBlO1xyXG4gICAgICAgIGlmIChldlR5cGUpIHtcclxuICAgICAgICAgIGlmICgnYnVmZmVyTm90aWZpY2F0aW9uJyA9PT0gZXZUeXBlKSB7XHJcbiAgICAgICAgICAgIHRoaXMuZmlsbGVkRnJhbWVzID0gbXNnRXYuZGF0YS5maWxsZWRGcmFtZXM7XHJcbiAgICAgICAgICAgIC8vY29uc29sZS5kZWJ1ZyhcIkJ1ZmZlciBub3RpZmljYXRpb246IGZpbGxlZCBmcmFtZXM6IFwiICsgdGhpcy5maWxsZWRGcmFtZXMpO1xyXG4gICAgICAgICAgICB0aGlzLmZpbGxCdWZmZXIoKTtcclxuICAgICAgICAgIH0gZWxzZSBpZiAoJ2VuZGVkJyA9PT0gZXZUeXBlKSB7XHJcbiAgICAgICAgICAgIGxldCBkcmFpblRpbWUgPSAwO1xyXG4gICAgICAgICAgICBpZiAodGhpcy5fYXJyYXlBdWRpb0J1ZmZlcj8uc2FtcGxlUmF0ZSkge1xyXG4gICAgICAgICAgICAgIGRyYWluVGltZSA9IEFycmF5QXVkaW9CdWZmZXJTb3VyY2VOb2RlLlFVQU5UVU1fRlJBTUVfTEVOIC8gdGhpcy5fYXJyYXlBdWRpb0J1ZmZlci5zYW1wbGVSYXRlO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIC8vbGV0IGRzdEFueTphbnk9dGhpcy5jb250ZXh0LmRlc3RpbmF0aW9uO1xyXG4gICAgICAgICAgICAvL2NvbnNvbGUuZGVidWcoJ0Rlc3RpbmF0aW9uIG5vZGUgdGFpbC10aW1lOiAnK2RzdEFueVsndGFpbC10aW1lJ10pO1xyXG4gICAgICAgICAgICB3aW5kb3cuc2V0VGltZW91dCgoKSA9PiB7XHJcbiAgICAgICAgICAgICAgdGhpcy5vbmVuZGVkPy5jYWxsKHRoaXMpO1xyXG4gICAgICAgICAgICB9LCBkcmFpblRpbWUgKiAxMDAwKTtcclxuXHJcbiAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG4gICAgICB9XHJcbiAgICB9XHJcbiAgfVxyXG5cclxuICBwcml2YXRlIGZpbGxCdWZmZXIoZnJhbWVPZmZzZXQ/Om51bWJlcikge1xyXG4gICAgaWYgKHRoaXMuX2FycmF5QXVkaW9CdWZmZXIgJiYgdGhpcy5fYXVkaW9JbnB1dFN0cmVhbSAmJiB0aGlzLl9haXNCdWZzKSB7XHJcbiAgICAgIGxldCBmaWxsZWQgPSB0aGlzLmZpbGxlZEZyYW1lcztcclxuICAgICAgbGV0IGJ1ZkxlbiA9IDA7XHJcblxyXG4gICAgICB3aGlsZShmaWxsZWQ8IHRoaXMuYnVmZmVyRmlsbEZyYW1lcykge1xyXG4gICAgICAgIGxldCByZWFkID0gdGhpcy5fYXVkaW9JbnB1dFN0cmVhbS5yZWFkKHRoaXMuX2Fpc0J1ZnMpO1xyXG4gICAgICAgIC8vY29uc29sZS5sb2coXCJBcnJheUF1ZGlvQnVmZmVyU291cmNlTm9kZTogcmVhZDogXCIrcmVhZClcclxuICAgICAgICBpZiAocmVhZCkge1xyXG4gICAgICAgICAgbGV0IHRyQnVmZmVycyA9IG5ldyBBcnJheTxhbnk+KHRoaXMuY2hhbm5lbENvdW50KTtcclxuICAgICAgICAgIGZvciAobGV0IGNoID0gMDsgY2ggPCB0aGlzLmNoYW5uZWxDb3VudDsgY2grKykge1xyXG4gICAgICAgICAgICBsZXQgYWRDaCA9IHRoaXMuX2Fpc0J1ZnNbY2hdO1xyXG4gICAgICAgICAgICBsZXQgYWRDaENvcHkgPSBuZXcgRmxvYXQzMkFycmF5KGFkQ2gubGVuZ3RoKTtcclxuICAgICAgICAgICAgYnVmTGVuID0gYWRDaENvcHkubGVuZ3RoO1xyXG4gICAgICAgICAgICBhZENoQ29weS5zZXQoYWRDaCk7XHJcbiAgICAgICAgICAgIHRyQnVmZmVyc1tjaF0gPSBhZENoQ29weS5idWZmZXI7XHJcbiAgICAgICAgICB9XHJcbiAgICAgICAgICB0aGlzLnBvcnQucG9zdE1lc3NhZ2Uoe1xyXG4gICAgICAgICAgICBjbWQ6ICdkYXRhJyxcclxuICAgICAgICAgICAgY2hzOiB0aGlzLmNoYW5uZWxDb3VudCxcclxuICAgICAgICAgICAgYXVkaW9EYXRhOiB0ckJ1ZmZlcnNcclxuICAgICAgICAgIH0sIHRyQnVmZmVycyk7XHJcbiAgICAgICAgICBmaWxsZWQrPXJlYWQ7XHJcbiAgICAgICAgfWVsc2V7XHJcbiAgICAgICAgICBicmVhaztcclxuICAgICAgICB9XHJcbiAgICAgIH1cclxuXHJcbiAgICB9XHJcbiAgfVxyXG5cclxuICBnZXQgYXJyYXlBdWRpb0J1ZmZlcigpOiBBcnJheUF1ZGlvQnVmZmVyIHwgbnVsbCB7XHJcbiAgICByZXR1cm4gdGhpcy5fYXJyYXlBdWRpb0J1ZmZlcjtcclxuICB9XHJcblxyXG4gIHNldCBhcnJheUF1ZGlvQnVmZmVyKHZhbHVlOiBBcnJheUF1ZGlvQnVmZmVyIHwgbnVsbCkge1xyXG4gICAgdGhpcy5fYXJyYXlBdWRpb0J1ZmZlciA9IHZhbHVlO1xyXG4gICAgaWYgKHRoaXMuX2FycmF5QXVkaW9CdWZmZXI/LmNoYW5uZWxDb3VudCkge1xyXG4gICAgICB0aGlzLmNoYW5uZWxDb3VudCA9IHRoaXMuX2FycmF5QXVkaW9CdWZmZXI/LmNoYW5uZWxDb3VudDtcclxuICAgICAgdGhpcy5idWZmZXJGaWxsRnJhbWVzID0gdGhpcy5fYXJyYXlBdWRpb0J1ZmZlci5zYW1wbGVSYXRlICogdGhpcy5fYnVmZmVyRmlsbFNlY29uZHM7XHJcbiAgICB9XHJcbiAgfVxyXG5cclxuICBnZXQgYnVmZmVyRmlsbFNlY29uZHMoKTogbnVtYmVyIHtcclxuICAgIHJldHVybiB0aGlzLl9idWZmZXJGaWxsU2Vjb25kcztcclxuICB9XHJcblxyXG4gIHNldCBidWZmZXJGaWxsU2Vjb25kcyh2YWx1ZTogbnVtYmVyKSB7XHJcbiAgICB0aGlzLl9idWZmZXJGaWxsU2Vjb25kcyA9IHZhbHVlO1xyXG4gIH1cclxuXHJcbiAgc3RhcnQod2hlbj86IG51bWJlciB8IHVuZGVmaW5lZCxvZmZzZXQ/OiBudW1iZXIgfCB1bmRlZmluZWQsZHVyYXRpb24/OiBudW1iZXIgfCB1bmRlZmluZWQpOiB2b2lkIHtcclxuICAgIGlmICh3aGVuKSB7XHJcbiAgICAgIHRocm93IEVycm9yKFwid2hlbiwgb2ZmZXN0LGR1cmF0aW9uIHBhcmFtZXRlcnMgY3VycmVudGx5IG5vdCBzdXBwb3J0ZWQgYnkgQXJyYXlBdWRpb0J1ZmZlclNvdXJjZU5vZGUgY2xhc3NcIilcclxuICAgIH1cclxuXHJcbiAgICBpZiAodGhpcy5fYXJyYXlBdWRpb0J1ZmZlcikge1xyXG4gICAgICBsZXQgYXJyQWlzPW5ldyBBcnJheUF1ZGlvQnVmZmVySW5wdXRTdHJlYW0odGhpcy5fYXJyYXlBdWRpb0J1ZmZlcik7XHJcbiAgICAgIGlmKG9mZnNldD09PXVuZGVmaW5lZCAmJiBkdXJhdGlvbj09PXVuZGVmaW5lZCl7XHJcbiAgICAgICAgdGhpcy5fYXVkaW9JbnB1dFN0cmVhbSA9IGFyckFpcztcclxuICAgICAgfWVsc2V7XHJcbiAgICAgICAgbGV0IG9mZnNldEZyYW1lcz0wO1xyXG4gICAgICAgIGxldCBkdXJhdGlvbkZyYW1lcz11bmRlZmluZWQ7XHJcbiAgICAgICAgaWYob2Zmc2V0IT09dW5kZWZpbmVkKSB7XHJcbiAgICAgICAgICBvZmZzZXRGcmFtZXM9TWF0aC5mbG9vcihvZmZzZXQgKiB0aGlzLl9hcnJheUF1ZGlvQnVmZmVyLnNhbXBsZVJhdGUpO1xyXG4gICAgICAgIH1cclxuICAgICAgICBpZihkdXJhdGlvbiE9PXVuZGVmaW5lZCl7XHJcbiAgICAgICAgICBkdXJhdGlvbkZyYW1lcz1NYXRoLmZsb29yKGR1cmF0aW9uICogdGhpcy5fYXJyYXlBdWRpb0J1ZmZlci5zYW1wbGVSYXRlKTtcclxuICAgICAgICB9XHJcbiAgICAgICAgdGhpcy5fYXVkaW9JbnB1dFN0cmVhbT1uZXcgRWRpdEZsb2F0MzJBcnJheUlucHV0U3RyZWFtKGFyckFpcyxvZmZzZXRGcmFtZXMsZHVyYXRpb25GcmFtZXMpO1xyXG4gICAgICB9XHJcblxyXG4gICAgbGV0IGNocz10aGlzLl9hcnJheUF1ZGlvQnVmZmVyLmNoYW5uZWxDb3VudDtcclxuICAgIHRoaXMuX2Fpc0J1ZnM9bmV3IEFycmF5PEZsb2F0MzJBcnJheT4oY2hzKTtcclxuICAgIGZvcihsZXQgY2g9MDtjaDxjaHM7Y2grKyl7XHJcbiAgICAgIHRoaXMuX2Fpc0J1ZnNbY2hdPW5ldyBGbG9hdDMyQXJyYXkoMTAyNCk7XHJcbiAgICB9XHJcblxyXG4gICAgdGhpcy5maWxsQnVmZmVyKCk7XHJcbiAgICB0aGlzLnBvcnQucG9zdE1lc3NhZ2Uoe2NtZDogJ3N0YXJ0J30pO1xyXG4gIH1cclxuICB9XHJcblxyXG4gIHN0b3AoKSB7XHJcbiAgICB0aGlzLnBvcnQucG9zdE1lc3NhZ2Uoe2NtZDogJ3N0b3AnfSk7XHJcbiAgICB0aGlzLm9uZW5kZWQ/LmNhbGwodGhpcyk7XHJcbiAgfVxyXG5cclxufVxyXG5cclxuZXhwb3J0IGNsYXNzIEF1ZGlvU291cmNlV29ya2xldE1vZHVsZUxvYWRlcntcclxuICBwcml2YXRlIHN0YXRpYyBtb2R1bGVMb2FkZWQ9ZmFsc2U7XHJcbiAgc3RhdGljIGxvYWRNb2R1bGUoY29udGV4dDogQXVkaW9Db250ZXh0KTogUHJvbWlzZTx2b2lkPiB7XHJcbiAgICByZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xyXG4gICAgICBpZiAoQXVkaW9Tb3VyY2VXb3JrbGV0TW9kdWxlTG9hZGVyLm1vZHVsZUxvYWRlZCkge1xyXG4gICAgICAgIHJlc29sdmUuY2FsbChzZWxmKTtcclxuICAgICAgfSBlbHNlIHtcclxuICAgICAgICBsZXQgYXVkaW9Xb3JrbGV0TW9kdWxlQmxvYiA9IG5ldyBCbG9iKFthc3dwU3RyXSwge3R5cGU6ICd0ZXh0L2phdmFzY3JpcHQnfSk7XHJcbiAgICAgICAgbGV0IGF1ZGlvV29ya2xldE1vZHVsZUJsb2JVcmwgPSB3aW5kb3cuVVJMLmNyZWF0ZU9iamVjdFVSTChhdWRpb1dvcmtsZXRNb2R1bGVCbG9iKTtcclxuICAgICAgICBjb250ZXh0LnJlc3VtZSgpO1xyXG4gICAgICAgIGNvbnRleHQuYXVkaW9Xb3JrbGV0LmFkZE1vZHVsZShhdWRpb1dvcmtsZXRNb2R1bGVCbG9iVXJsKS50aGVuKCgpID0+IHtcclxuICAgICAgICAgIEF1ZGlvU291cmNlV29ya2xldE1vZHVsZUxvYWRlci5tb2R1bGVMb2FkZWQgPSB0cnVlO1xyXG4gICAgICAgICAgcmVzb2x2ZS5jYWxsKHNlbGYpO1xyXG4gICAgICAgIH0pLmNhdGNoKChyZWFzb24pID0+IHtcclxuICAgICAgICAgIGNvbnNvbGUuZXJyb3IocmVhc29uKTtcclxuICAgICAgICAgIHJlamVjdC5jYWxsKHJlYXNvbik7XHJcbiAgICAgICAgfSk7XHJcbiAgICAgIH1cclxuICAgIH0pO1xyXG4gIH1cclxufVxyXG4iXX0=
126
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYXJyYXlfYXVkaW9fYnVmZmVyX3NvdXJjZV9ub2RlLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vLi4vcHJvamVjdHMvc3BlZWNocmVjb3JkZXJuZy9zcmMvbGliL2F1ZGlvL3BsYXliYWNrL2FycmF5X2F1ZGlvX2J1ZmZlcl9zb3VyY2Vfbm9kZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFDQSxPQUFPLEVBQUMsMkJBQTJCLEVBQUMsTUFBTSxvQ0FBb0MsQ0FBQztBQUMvRSxPQUFPLEVBQUMsMkJBQTJCLEVBQTBCLE1BQU0saUJBQWlCLENBQUM7QUFDckYsT0FBTyxFQUFDLGVBQWUsRUFBQyxNQUFNLHFCQUFxQixDQUFDO0FBRXBELE1BQU0sT0FBTywwQkFBMkIsU0FBUSxlQUFlO0lBVTdELFlBQVksT0FBcUI7UUFFL0IsS0FBSyxDQUFDLE9BQU8sRUFBRSxzQkFBc0IsQ0FBQyxDQUFDO1FBVmpDLHVCQUFrQixHQUFHLGVBQWUsQ0FBQywyQkFBMkIsQ0FBQztRQUNqRSxxQkFBZ0IsR0FBRyxDQUFDLENBQUM7UUFDckIsc0JBQWlCLEdBQTRCLElBQUksQ0FBQztRQUNsRCxzQkFBaUIsR0FBOEIsSUFBSSxDQUFDO1FBQ3BELGFBQVEsR0FBcUIsSUFBSSxDQUFDO1FBRWxDLGlCQUFZLEdBQUcsQ0FBQyxDQUFDO1FBS3ZCLElBQUksQ0FBQyxnQkFBZ0IsR0FBRyxVQUFVLENBQUM7UUFDbkMsSUFBSSxDQUFDLElBQUksQ0FBQyxTQUFTLEdBQUcsQ0FBQyxLQUFtQixFQUFFLEVBQUU7WUFDNUMsSUFBSSxLQUFLLENBQUMsSUFBSSxFQUFFO2dCQUNkLElBQUksTUFBTSxHQUFHLEtBQUssQ0FBQyxJQUFJLENBQUMsU0FBUyxDQUFDO2dCQUNsQyxJQUFJLE1BQU0sRUFBRTtvQkFDVixJQUFJLG9CQUFvQixLQUFLLE1BQU0sRUFBRTt3QkFDbkMsSUFBSSxDQUFDLFlBQVksR0FBRyxLQUFLLENBQUMsSUFBSSxDQUFDLFlBQVks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SUFBSSxLQUFLLENBQWUsR0FBRyxDQUFDLENBQUM7WUFDM0MsS0FBSSxJQUFJLEVBQUUsR0FBQyxDQUFDLEVBQUMsRUFBRSxHQUFDLEdBQUcsRUFBQyxFQUFFLEVBQUUsRUFBQztnQkFDdkIsSUFBSSxDQUFDLFFBQVEsQ0FBQyxFQUFFLENBQUMsR0FBQyxJQUFJLFlBQVksQ0FBQywwQkFBMEIsQ0FBQyw2QkFBNkIsQ0FBQyxDQUFDO2FBQzlGO1lBRUQsSUFBSSxDQUFDLFVBQVUsRUFBRSxDQUFDO1lBQ2xCLElBQUksQ0FBQyxJQUFJLENBQUMsV0FBVyxDQUFDLEVBQUMsR0FBRyxFQUFFLE9BQU8sRUFBQyxDQUFDLENBQUM7WUFDcEMsSUFBRyxNQUFNLEVBQUU7Z0JBQ1QsSUFBSSxDQUFDLGNBQWMsR0FBRyxJQUFJLENBQUMsT0FBTyxDQUFDLFdBQVcsR0FBRyxNQUFNLENBQUM7YUFDekQ7aUJBQUk7Z0JBQ0gsSUFBSSxDQUFDLGNBQWMsR0FBRyxJQUFJLENBQUMsT0FBTyxDQUFDLFdBQVcsQ0FBQzthQUNoRDtTQUNKO0lBQ0QsQ0FBQztJQUVELElBQUk7UUFDRixJQUFJLENBQUMsSUFBSSxDQUFDLFdBQVcsQ0FBQyxFQUFDLEdBQUcsRUFBRSxNQUFNLEVBQUMsQ0FBQyxDQUFDO1FBQ3JDLElBQUksQ0FBQyxPQUFPLEVBQUUsSUFBSSxDQUFDLElBQUksQ0FBQyxDQUFDO0lBQzNCLENBQUM7Q0FFRiIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7QXJyYXlBdWRpb0J1ZmZlcn0gZnJvbSBcIi4uL2FycmF5X2F1ZGlvX2J1ZmZlclwiO1xyXG5pbXBvcnQge0FycmF5QXVkaW9CdWZmZXJJbnB1dFN0cmVhbX0gZnJvbSBcIi4uL2FycmF5X2F1ZGlvX2J1ZmZlcl9pbnB1dF9zdHJlYW1cIjtcclxuaW1wb3J0IHtFZGl0RmxvYXQzMkFycmF5SW5wdXRTdHJlYW0sIEZsb2F0MzJBcnJheUlucHV0U3RyZWFtfSBmcm9tIFwiLi4vLi4vaW8vc3RyZWFtXCI7XHJcbmltcG9ydCB7QXVkaW9Tb3VyY2VOb2RlfSBmcm9tIFwiLi9hdWRpb19zb3VyY2Vfbm9kZVwiO1xyXG5cclxuZXhwb3J0IGNsYXNzIEFycmF5QXVkaW9CdWZmZXJTb3VyY2VOb2RlIGV4dGVuZHMgQXVkaW9Tb3VyY2VOb2RlIHtcclxuXHJcbiAgcHJpdmF0ZSBfYnVmZmVyRmlsbFNlY29uZHMgPSBBdWRpb1NvdXJjZU5vZGUuREVGQVVMVF9CVUZGRVJfRklMTF9TRUNPTkRTO1xyXG4gIHByaXZhdGUgYnVmZmVyRmlsbEZyYW1lcyA9IDA7XHJcbiAgcHJpdmF0ZSBfYXJyYXlBdWRpb0J1ZmZlcjogQXJyYXlBdWRpb0J1ZmZlciB8IG51bGwgPSBudWxsO1xyXG4gIHByaXZhdGUgX2F1ZGlvSW5wdXRTdHJlYW06RmxvYXQzMkFycmF5SW5wdXRTdHJlYW18bnVsbD1udWxsO1xyXG4gIHByaXZhdGUgX2Fpc0J1ZnM6RmxvYXQzMkFycmF5W118bnVsbD1udWxsO1xyXG5cclxuICBwcml2YXRlIGZpbGxlZEZyYW1lcyA9IDA7XHJcblxyXG4gIGNvbnN0cnVjdG9yKGNvbnRleHQ6IEF1ZGlvQ29udGV4dCkge1xyXG5cclxuICAgIHN1cGVyKGNvbnRleHQsICdhdWRpby1zb3VyY2Utd29ya2xldCcpO1xyXG4gICAgdGhpcy5jaGFubmVsQ291bnRNb2RlID0gJ2V4cGxpY2l0JztcclxuICAgIHRoaXMucG9ydC5vbm1lc3NhZ2UgPSAobXNnRXY6IE1lc3NhZ2VFdmVudCkgPT4ge1xyXG4gICAgICBpZiAobXNnRXYuZGF0YSkge1xyXG4gICAgICAgIGxldCBldlR5cGUgPSBtc2dFdi5kYXRhLmV2ZW50VHlwZTtcclxuICAgICAgICBpZiAoZXZUeXBlKSB7XHJcbiAgICAgICAgICBpZiAoJ2J1ZmZlck5vdGlmaWNhdGlvbicgPT09IGV2VHlwZSkge1xyXG4gICAgICAgICAgICB0aGlzLmZpbGxlZEZyYW1lcyA9IG1zZ0V2LmRhdGEuZmlsbGVkRnJhbWVzO1xyXG4gICAgICAgICAgICAvL2NvbnNvbGUuZGVidWcoXCJCdWZmZXIgbm90aWZpY2F0aW9uOiBmaWxsZWQgZnJhbWVzOiBcIiArIHRoaXMuZmlsbGVkRnJhbWVzKTtcclxuICAgICAgICAgICAgdGhpcy5maWxsQnVmZmVyKCk7XHJcbiAgICAgICAgICB9IGVsc2UgaWYgKCdlbmRlZCcgPT09IGV2VHlwZSkge1xyXG4gICAgICAgICAgICBsZXQgZHJhaW5UaW1lID0gMDtcclxuICAgICAgICAgICAgaWYgKHRoaXMuX2FycmF5QXVkaW9CdWZmZXI/LnNhbXBsZVJhdGUpIHtcclxuICAgICAgICAgICAgICBkcmFpblRpbWUgPSBBcnJheUF1ZGlvQnVmZmVyU291cmNlTm9kZS5RVUFOVFVNX0ZSQU1FX0xFTiAvIHRoaXMuX2FycmF5QXVkaW9CdWZmZXIuc2FtcGxlUmF0ZTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAvL2xldCBkc3RBbnk6YW55PXRoaXMuY29udGV4dC5kZXN0aW5hdGlvbjtcclxuICAgICAgICAgICAgLy9jb25zb2xlLmRlYnVnKCdEZXN0aW5hdGlvbiBub2RlIHRhaWwtdGltZTogJytkc3RBbnlbJ3RhaWwtdGltZSddKTtcclxuICAgICAgICAgICAgd2luZG93LnNldFRpbWVvdXQoKCkgPT4ge1xyXG4gICAgICAgICAgICAgIHRoaXMub25lbmRlZD8uY2FsbCh0aGlzKTtcclxuICAgICAgICAgICAgfSwgZHJhaW5UaW1lICogMTAwMCk7XHJcblxyXG4gICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuICAgICAgfVxyXG4gICAgfVxyXG4gIH1cclxuXHJcbiAgcHJpdmF0ZSBmaWxsQnVmZmVyKGZyYW1lT2Zmc2V0PzpudW1iZXIpIHtcclxuICAgIGlmICh0aGlzLl9hcnJheUF1ZGlvQnVmZmVyICYmIHRoaXMuX2F1ZGlvSW5wdXRTdHJlYW0gJiYgdGhpcy5fYWlzQnVmcykge1xyXG4gICAgICBsZXQgZmlsbGVkID0gdGhpcy5maWxsZWRGcmFtZXM7XHJcbiAgICAgIGxldCBidWZMZW4gPSAwO1xyXG5cclxuICAgICAgd2hpbGUoZmlsbGVkPCB0aGlzLmJ1ZmZlckZpbGxGcmFtZXMpIHtcclxuICAgICAgICBsZXQgcmVhZCA9IHRoaXMuX2F1ZGlvSW5wdXRTdHJlYW0ucmVhZCh0aGlzLl9haXNCdWZzKTtcclxuICAgICAgICAvL2NvbnNvbGUubG9nKFwiQXJyYXlBdWRpb0J1ZmZlclNvdXJjZU5vZGU6IHJlYWQ6IFwiK3JlYWQpXHJcbiAgICAgICAgaWYgKHJlYWQpIHtcclxuICAgICAgICAgIGxldCB0ckJ1ZmZlcnMgPSBuZXcgQXJyYXk8YW55Pih0aGlzLmNoYW5uZWxDb3VudCk7XHJcbiAgICAgICAgICBmb3IgKGxldCBjaCA9IDA7IGNoIDwgdGhpcy5jaGFubmVsQ291bnQ7IGNoKyspIHtcclxuICAgICAgICAgICAgbGV0IGFkQ2ggPSB0aGlzLl9haXNCdWZzW2NoXTtcclxuICAgICAgICAgICAgbGV0IGFkQ2hDb3B5ID0gbmV3IEZsb2F0MzJBcnJheShhZENoLmxlbmd0aCk7XHJcbiAgICAgICAgICAgIGJ1ZkxlbiA9IGFkQ2hDb3B5Lmxlbmd0aDtcclxuICAgICAgICAgICAgYWRDaENvcHkuc2V0KGFkQ2gpO1xyXG4gICAgICAgICAgICB0ckJ1ZmZlcnNbY2hdID0gYWRDaENvcHkuYnVmZmVyO1xyXG4gICAgICAgICAgfVxyXG4gICAgICAgICAgdGhpcy5wb3J0LnBvc3RNZXNzYWdlKHtcclxuICAgICAgICAgICAgY21kOiAnZGF0YScsXHJcbiAgICAgICAgICAgIGNoczogdGhpcy5jaGFubmVsQ291bnQsXHJcbiAgICAgICAgICAgIGF1ZGlvRGF0YTogdHJCdWZmZXJzXHJcbiAgICAgICAgICB9LCB0ckJ1ZmZlcnMpO1xyXG4gICAgICAgICAgZmlsbGVkKz1yZWFkO1xyXG4gICAgICAgIH1lbHNle1xyXG4gICAgICAgICAgdGhpcy5wb3J0LnBvc3RNZXNzYWdlKHtcclxuICAgICAgICAgICAgY21kOiAnZW5kT2ZTdHJlYW0nXHJcbiAgICAgICAgICB9KTtcclxuICAgICAgICAgIGJyZWFrO1xyXG4gICAgICAgIH1cclxuICAgICAgfVxyXG5cclxuICAgIH1cclxuICB9XHJcblxyXG4gIGdldCBhcnJheUF1ZGlvQnVmZmVyKCk6IEFycmF5QXVkaW9CdWZmZXIgfCBudWxsIHtcclxuICAgIHJldHVybiB0aGlzLl9hcnJheUF1ZGlvQnVmZmVyO1xyXG4gIH1cclxuXHJcbiAgc2V0IGFycmF5QXVkaW9CdWZmZXIodmFsdWU6IEFycmF5QXVkaW9CdWZmZXIgfCBudWxsKSB7XHJcbiAgICB0aGlzLl9hcnJheUF1ZGlvQnVmZmVyID0gdmFsdWU7XHJcbiAgICBpZiAodGhpcy5fYXJyYXlBdWRpb0J1ZmZlcj8uY2hhbm5lbENvdW50KSB7XHJcbiAgICAgIHRoaXMuY2hhbm5lbENvdW50ID0gdGhpcy5fYXJyYXlBdWRpb0J1ZmZlcj8uY2hhbm5lbENvdW50O1xyXG4gICAgICB0aGlzLmJ1ZmZlckZpbGxGcmFtZXMgPSB0aGlzLl9hcnJheUF1ZGlvQnVmZmVyLnNhbXBsZVJhdGUgKiB0aGlzLl9idWZmZXJGaWxsU2Vjb25kcztcclxuICAgIH1cclxuICB9XHJcblxyXG4gIGdldCBidWZmZXJGaWxsU2Vjb25kcygpOiBudW1iZXIge1xyXG4gICAgcmV0dXJuIHRoaXMuX2J1ZmZlckZpbGxTZWNvbmRzO1xyXG4gIH1cclxuXHJcbiAgc2V0IGJ1ZmZlckZpbGxTZWNvbmRzKHZhbHVlOiBudW1iZXIpIHtcclxuICAgIHRoaXMuX2J1ZmZlckZpbGxTZWNvbmRzID0gdmFsdWU7XHJcbiAgfVxyXG5cclxuICBzdGFydCh3aGVuPzogbnVtYmVyIHwgdW5kZWZpbmVkLG9mZnNldD86IG51bWJlciB8IHVuZGVmaW5lZCxkdXJhdGlvbj86IG51bWJlciB8IHVuZGVmaW5lZCk6IHZvaWQge1xyXG4gICAgaWYgKHdoZW4pIHtcclxuICAgICAgdGhyb3cgRXJyb3IoXCJ3aGVuIHBhcmFtZXRlciBjdXJyZW50bHkgbm90IHN1cHBvcnRlZCBieSBBcnJheUF1ZGlvQnVmZmVyU291cmNlTm9kZSBjbGFzc1wiKVxyXG4gICAgfVxyXG5cclxuICAgIGlmICh0aGlzLl9hcnJheUF1ZGlvQnVmZmVyKSB7XHJcbiAgICAgIGxldCBhcnJBaXM9bmV3IEFycmF5QXVkaW9CdWZmZXJJbnB1dFN0cmVhbSh0aGlzLl9hcnJheUF1ZGlvQnVmZmVyKTtcclxuICAgICAgaWYob2Zmc2V0PT09dW5kZWZpbmVkICYmIGR1cmF0aW9uPT09dW5kZWZpbmVkKXtcclxuICAgICAgICB0aGlzLl9hdWRpb0lucHV0U3RyZWFtID0gYXJyQWlzO1xyXG4gICAgICB9ZWxzZXtcclxuICAgICAgICBsZXQgb2Zmc2V0RnJhbWVzPTA7XHJcbiAgICAgICAgbGV0IGR1cmF0aW9uRnJhbWVzPXVuZGVmaW5lZDtcclxuICAgICAgICBpZihvZmZzZXQhPT11bmRlZmluZWQpIHtcclxuICAgICAgICAgIG9mZnNldEZyYW1lcz1NYXRoLmZsb29yKG9mZnNldCAqIHRoaXMuX2FycmF5QXVkaW9CdWZmZXIuc2FtcGxlUmF0ZSk7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGlmKGR1cmF0aW9uIT09dW5kZWZpbmVkKXtcclxuICAgICAgICAgIGR1cmF0aW9uRnJhbWVzPU1hdGguZmxvb3IoZHVyYXRpb24gKiB0aGlzLl9hcnJheUF1ZGlvQnVmZmVyLnNhbXBsZVJhdGUpO1xyXG4gICAgICAgIH1cclxuICAgICAgICB0aGlzLl9hdWRpb0lucHV0U3RyZWFtPW5ldyBFZGl0RmxvYXQzMkFycmF5SW5wdXRTdHJlYW0oYXJyQWlzLG9mZnNldEZyYW1lcyxkdXJhdGlvbkZyYW1lcyk7XHJcbiAgICAgIH1cclxuXHJcbiAgICBsZXQgY2hzPXRoaXMuX2FycmF5QXVkaW9CdWZmZXIuY2hhbm5lbENvdW50O1xyXG4gICAgdGhpcy5fYWlzQnVmcz1uZXcgQXJyYXk8RmxvYXQzMkFycmF5PihjaHMpO1xyXG4gICAgZm9yKGxldCBjaD0wO2NoPGNocztjaCsrKXtcclxuICAgICAgdGhpcy5fYWlzQnVmc1tjaF09bmV3IEZsb2F0MzJBcnJheShBcnJheUF1ZGlvQnVmZmVyU291cmNlTm9kZS5ERUZBVUxUX1NUUkVBTV9SRUFEX0ZSQU1FX0xFTik7XHJcbiAgICB9XHJcblxyXG4gICAgdGhpcy5maWxsQnVmZmVyKCk7XHJcbiAgICB0aGlzLnBvcnQucG9zdE1lc3NhZ2Uoe2NtZDogJ3N0YXJ0J30pO1xyXG4gICAgICBpZihvZmZzZXQpIHtcclxuICAgICAgICB0aGlzLl9wbGF5U3RhcnRUaW1lID0gdGhpcy5jb250ZXh0LmN1cnJlbnRUaW1lIC0gb2Zmc2V0O1xyXG4gICAgICB9ZWxzZXtcclxuICAgICAgICB0aGlzLl9wbGF5U3RhcnRUaW1lID0gdGhpcy5jb250ZXh0LmN1cnJlbnRUaW1lO1xyXG4gICAgICB9XHJcbiAgfVxyXG4gIH1cclxuXHJcbiAgc3RvcCgpIHtcclxuICAgIHRoaXMucG9ydC5wb3N0TWVzc2FnZSh7Y21kOiAnc3RvcCd9KTtcclxuICAgIHRoaXMub25lbmRlZD8uY2FsbCh0aGlzKTtcclxuICB9XHJcblxyXG59XHJcbiJdfQ==
@@ -0,0 +1,18 @@
1
+ export class AudioSourceNode extends AudioWorkletNode {
2
+ constructor() {
3
+ super(...arguments);
4
+ this._playStartTime = null;
5
+ this.onended = null;
6
+ }
7
+ get playPositionTime() {
8
+ let ppt = null;
9
+ if (this._playStartTime !== null) {
10
+ ppt = this.context.currentTime - this._playStartTime;
11
+ }
12
+ return ppt;
13
+ }
14
+ }
15
+ AudioSourceNode.DEFAULT_BUFFER_FILL_SECONDS = 10;
16
+ AudioSourceNode.DEFAULT_STREAM_READ_FRAME_LEN = 1024;
17
+ AudioSourceNode.QUANTUM_FRAME_LEN = 128;
18
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYXVkaW9fc291cmNlX25vZGUuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi9wcm9qZWN0cy9zcGVlY2hyZWNvcmRlcm5nL3NyYy9saWIvYXVkaW8vcGxheWJhY2svYXVkaW9fc291cmNlX25vZGUudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsTUFBTSxPQUFnQixlQUFnQixTQUFRLGdCQUFnQjtJQUE5RDs7UUFJWSxtQkFBYyxHQUFhLElBQUksQ0FBQztRQVcxQyxZQUFPLEdBQXdCLElBQUksQ0FBQztJQUN0QyxDQUFDO0lBUkMsSUFBSSxnQkFBZ0I7UUFDbEIsSUFBSSxHQUFHLEdBQUMsSUFBSSxDQUFDO1FBQ2IsSUFBRyxJQUFJLENBQUMsY0FBYyxLQUFHLElBQUksRUFBRTtZQUM3QixHQUFHLEdBQUUsSUFBSSxDQUFDLE9BQU8sQ0FBQyxXQUFXLEdBQUcsSUFBSSxDQUFDLGNBQWMsQ0FBQztTQUNyRDtRQUNELE9BQU8sR0FBRyxDQUFDO0lBQ2IsQ0FBQzs7QUFiZSwyQ0FBMkIsR0FBRyxFQUFFLENBQUM7QUFDakMsNkNBQTZCLEdBQUMsSUFBSSxDQUFDO0FBQ25DLGlDQUFpQixHQUFHLEdBQUcsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbImV4cG9ydCBhYnN0cmFjdCBjbGFzcyBBdWRpb1NvdXJjZU5vZGUgZXh0ZW5kcyBBdWRpb1dvcmtsZXROb2RlIHtcclxuICBzdGF0aWMgcmVhZG9ubHkgREVGQVVMVF9CVUZGRVJfRklMTF9TRUNPTkRTID0gMTA7XHJcbiAgc3RhdGljIHJlYWRvbmx5IERFRkFVTFRfU1RSRUFNX1JFQURfRlJBTUVfTEVOPTEwMjQ7XHJcbiAgc3RhdGljIHJlYWRvbmx5IFFVQU5UVU1fRlJBTUVfTEVOID0gMTI4O1xyXG4gIHByb3RlY3RlZCBfcGxheVN0YXJ0VGltZTpudW1iZXJ8bnVsbD1udWxsO1xyXG4gIHB1YmxpYyBhYnN0cmFjdCBzdGFydCh3aGVuPzogbnVtYmVyIHwgdW5kZWZpbmVkLG9mZnNldD86IG51bWJlciB8IHVuZGVmaW5lZCxkdXJhdGlvbj86IG51bWJlciB8IHVuZGVmaW5lZCk6IHZvaWQ7XHJcbiAgcHVibGljIGFic3RyYWN0IHN0b3AoKTp2b2lkO1xyXG5cclxuICBnZXQgcGxheVBvc2l0aW9uVGltZSgpOm51bWJlcnxudWxsIHtcclxuICAgIGxldCBwcHQ9bnVsbDtcclxuICAgIGlmKHRoaXMuX3BsYXlTdGFydFRpbWUhPT1udWxsKSB7XHJcbiAgICAgIHBwdD0gdGhpcy5jb250ZXh0LmN1cnJlbnRUaW1lIC0gdGhpcy5fcGxheVN0YXJ0VGltZTtcclxuICAgIH1cclxuICAgIHJldHVybiBwcHQ7XHJcbiAgfVxyXG4gIG9uZW5kZWQ6ICgoKSA9PiB2b2lkKSB8IG51bGwgPSBudWxsO1xyXG59XHJcbiJdfQ==
@@ -0,0 +1,167 @@
1
+ // Code from audio_source_worklet.js as string constant to be loaded as module
2
+ // Changes in audio_source_worklet.js must be copied and pasted to this string constant
3
+ const aswpStr = "\n" +
4
+ "// Important note: Changes in audio_source_worklet.js must be copied and pasted to the string constant aswpStr in audio_source_worklet_module_loader.ts\n" +
5
+ "\n" +
6
+ "\n" +
7
+ "class AudioSourceProcessor extends AudioWorkletProcessor{\n" +
8
+ "\n" +
9
+ " filledFrames=0;\n" +
10
+ " audioBuffers=new Array();\n" +
11
+ " currentAudioBuffer=null;\n" +
12
+ " currentAudioBufferFramePos=0;\n" +
13
+ " currentAudioBufferAvail=0;\n" +
14
+ " running=false;\n" +
15
+ " stalled=false;\n" +
16
+ " stopped=false;\n" +
17
+ " endOfStream=false;\n" +
18
+ " ended=false;\n" +
19
+ "\n" +
20
+ " constructor() {\n" +
21
+ " super({numberOfInputs:0,numberOfOutputs:1});\n" +
22
+ " this.port.onmessage=(msgEv)=>{\n" +
23
+ " // received audio playback data from application\n" +
24
+ " //console.debug(\"Audio source worklet msg: Received.\");\n" +
25
+ "\n" +
26
+ " if(msgEv.data.cmd){\n" +
27
+ " if('data'===msgEv.data.cmd) {\n" +
28
+ " let chs = msgEv.data.chs;\n" +
29
+ "\n" +
30
+ " let audioData = new Array(chs);\n" +
31
+ " for (let ch = 0; ch < chs; ch++) {\n" +
32
+ " audioData[ch] = new Float32Array(msgEv.data.audioData[ch]);\n" +
33
+ " }\n" +
34
+ " let msgChBufLen=audioData[0].length;\n" +
35
+ " this.audioBuffers.push(audioData);\n" +
36
+ " this.filledFrames += msgChBufLen;\n" +
37
+ " //console.debug(\"Audio source worklet msg: Filled \" + this.filledFrames+ \" in \"+this.audioBuffers.length+\" buffers.\");\n" +
38
+ "\n" +
39
+ " }else if('start'===msgEv.data.cmd){\n" +
40
+ " this.running=true;\n" +
41
+ " }else if('stop'===msgEv.data.cmd){\n" +
42
+ " //console.debug(\"Stop...\");\n" +
43
+ " this.running=false;\n" +
44
+ " this.stopped=true;\n" +
45
+ " // clear buffers\n" +
46
+ " this.filledFrames=0;\n" +
47
+ " while(this.audioBuffers.length > 0) {\n" +
48
+ " this.audioBuffers.pop();\n" +
49
+ " }\n" +
50
+ " this.currentAudioBuffer=new Float32Array(0);\n" +
51
+ " }else if('endOfStream'===msgEv.data.cmd){\n" +
52
+ " this.endOfStream=true;\n" +
53
+ " }else if('continue'===msgEv.data.cmd){\n" +
54
+ " console.debug(\"Continue after stalled...\");\n" +
55
+ " this.stalled=false;\n" +
56
+ " this.port.postMessage({eventType: 'resumed'});\n" +
57
+ " }\n" +
58
+ " }\n" +
59
+ " }\n" +
60
+ " }\n" +
61
+ "\n" +
62
+ " process(\n" +
63
+ " inputs,\n" +
64
+ " outputs,\n" +
65
+ " parameters\n" +
66
+ " ){\n" +
67
+ " //console.debug(\"Audio source worklet: process \"+outputs.length+ \" output buffers.\");\n" +
68
+ " // copy ring buffer data to outputs\n" +
69
+ " if(!this.running || this.stalled){\n" +
70
+ " if(this.endOfStream) {\n" +
71
+ " this.ended = true;\n" +
72
+ " this.port.postMessage({eventType: 'ended'});\n" +
73
+ " }\n" +
74
+ " return !this.ended && !this.stopped;\n" +
75
+ " }\n" +
76
+ "\n" +
77
+ " let output=outputs[0];\n" +
78
+ " let chs=output.length;\n" +
79
+ " //console.debug(\"Audio source worklet: Output channels: \"+chs);\n" +
80
+ " if(chs>0) {\n" +
81
+ "\n" +
82
+ " let outCh0 = output[0];\n" +
83
+ " let outChLen = outCh0.length;\n" +
84
+ "\n" +
85
+ " if(!this.currentAudioBuffer){\n" +
86
+ " // get first buffer\n" +
87
+ " let nxtBuff=this.audioBuffers.shift();\n" +
88
+ " if(nxtBuff) {\n" +
89
+ " this.currentAudioBuffer = nxtBuff;\n" +
90
+ " this.currentAudioBufferFramePos=0;\n" +
91
+ " this.currentAudioBufferAvail=this.currentAudioBuffer[0].length;\n" +
92
+ " }else{\n" +
93
+ " return true;\n" +
94
+ " }\n" +
95
+ " }\n" +
96
+ "\n" +
97
+ " let copied=0;\n" +
98
+ " do{\n" +
99
+ " if(this.currentAudioBufferAvail==0){\n" +
100
+ " let nxtBuff=this.audioBuffers.shift();\n" +
101
+ " if(nxtBuff){\n" +
102
+ " this.currentAudioBuffer=nxtBuff;\n" +
103
+ " this.currentAudioBufferFramePos=0;\n" +
104
+ " this.currentAudioBufferAvail=this.currentAudioBuffer[0].length;\n" +
105
+ " //console.debug(\"Next buffer with \"+this.currentAudioBufferAvail+ \" frames\");\n" +
106
+ " this.port.postMessage({eventType:'bufferNotification',filledFrames:this.filledFrames});\n" +
107
+ " }else{\n" +
108
+ " if(this.endOfStream) {\n" +
109
+ " this.ended = true;\n" +
110
+ " this.port.postMessage({eventType: 'ended'});\n" +
111
+ " //console.debug(\"Stream ended\");\n" +
112
+ " }else{\n" +
113
+ " if(!this.stalled) {\n" +
114
+ " this.stalled = true;\n" +
115
+ " this.port.postMessage({eventType: 'stalled'});\n" +
116
+ " }\n" +
117
+ " }\n" +
118
+ " break;\n" +
119
+ " }\n" +
120
+ " }\n" +
121
+ " //console.debug(\"outChLen: \"+outChLen+\", copied: \"+copied+\", current avail: \"+this.currentAudioBufferAvail);\n" +
122
+ " let toCopy=outChLen-copied;\n" +
123
+ " if(toCopy>this.currentAudioBufferAvail){\n" +
124
+ " toCopy=this.currentAudioBufferAvail;\n" +
125
+ " }\n" +
126
+ " //console.debug(\"Copy \"+toCopy+\" frames...\");\n" +
127
+ " for(let ch=0;ch<chs;ch++) {\n" +
128
+ " let outCh=output[ch];\n" +
129
+ " for (let i = 0; i < toCopy; i++) {\n" +
130
+ " outCh[copied+i]=this.currentAudioBuffer[ch][this.currentAudioBufferFramePos+i];\n" +
131
+ " }\n" +
132
+ " }\n" +
133
+ " copied+=toCopy;\n" +
134
+ " this.currentAudioBufferFramePos+=toCopy;\n" +
135
+ " this.currentAudioBufferAvail-=toCopy;\n" +
136
+ "\n" +
137
+ " }while(copied<outChLen);\n" +
138
+ " this.filledFrames-=copied;\n" +
139
+ " //console.debug(\"Copied \"+copied+\" frames.\");\n" +
140
+ " }\n" +
141
+ " return !this.ended;\n" +
142
+ " }\n" +
143
+ "}\n" +
144
+ "\n" +
145
+ "registerProcessor('audio-source-worklet',AudioSourceProcessor);\n";
146
+ export class AudioSourceWorkletModuleLoader {
147
+ static loadModule(context) {
148
+ return new Promise((resolve, reject) => {
149
+ if (AudioSourceWorkletModuleLoader.moduleLoaded) {
150
+ resolve.call(self);
151
+ }
152
+ else {
153
+ const audioWorkletModuleBlob = new Blob([aswpStr], { type: 'text/javascript' });
154
+ const audioWorkletModuleBlobUrl = window.URL.createObjectURL(audioWorkletModuleBlob);
155
+ context.audioWorklet.addModule(audioWorkletModuleBlobUrl).then(() => {
156
+ AudioSourceWorkletModuleLoader.moduleLoaded = true;
157
+ resolve.call(self);
158
+ }).catch((reason) => {
159
+ console.error(reason);
160
+ reject.call(reason);
161
+ });
162
+ }
163
+ });
164
+ }
165
+ }
166
+ AudioSourceWorkletModuleLoader.moduleLoaded = false;
167
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYXVkaW9fc291cmNlX3dvcmtsZXRfbW9kdWxlX2xvYWRlci5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uLy4uL3Byb2plY3RzL3NwZWVjaHJlY29yZGVybmcvc3JjL2xpYi9hdWRpby9wbGF5YmFjay9hdWRpb19zb3VyY2Vfd29ya2xldF9tb2R1bGVfbG9hZGVyLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLDhFQUE4RTtBQUM5RSx1RkFBdUY7QUFFdkYsTUFBTSxPQUFPLEdBQUcsSUFBSTtJQUNoQiwySkFBMko7SUFDM0osSUFBSTtJQUNKLElBQUk7SUFDSiw2REFBNkQ7SUFDN0QsSUFBSTtJQUNKLHVCQUF1QjtJQUN2QixpQ0FBaUM7SUFDakMsZ0NBQWdDO0lBQ2hDLHFDQUFxQztJQUNyQyxrQ0FBa0M7SUFDbEMsc0JBQXNCO0lBQ3RCLHNCQUFzQjtJQUN0QixzQkFBc0I7SUFDdEIsMEJBQTBCO0lBQzFCLG9CQUFvQjtJQUNwQixJQUFJO0lBQ0osdUJBQXVCO0lBQ3ZCLHdEQUF3RDtJQUN4RCwwQ0FBMEM7SUFDMUMsOERBQThEO0lBQzlELHVFQUF1RTtJQUN2RSxJQUFJO0lBQ0osaUNBQWlDO0lBQ2pDLDZDQUE2QztJQUM3QywyQ0FBMkM7SUFDM0MsSUFBSTtJQUNKLGlEQUFpRDtJQUNqRCxvREFBb0Q7SUFDcEQsK0VBQStFO0lBQy9FLG1CQUFtQjtJQUNuQixzREFBc0Q7SUFDdEQsb0RBQW9EO0lBQ3BELG1EQUFtRDtJQUNuRCw4SUFBOEk7SUFDOUksSUFBSTtJQUNKLG1EQUFtRDtJQUNuRCxvQ0FBb0M7SUFDcEMsa0RBQWtEO0lBQ2xELCtDQUErQztJQUMvQyxxQ0FBcUM7SUFDckMsb0NBQW9DO0lBQ3BDLGtDQUFrQztJQUNsQyxzQ0FBc0M7SUFDdEMsdURBQXVEO0lBQ3ZELDRDQUE0QztJQUM1QyxtQkFBbUI7SUFDbkIsOERBQThEO0lBQzlELHlEQUF5RDtJQUN6RCx3Q0FBd0M7SUFDeEMsc0RBQXNEO0lB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QUM7Z0JBQ3RCLENBQUMsQ0FBQyxDQUFDO2FBRUo7UUFDSCxDQUFDLENBQUMsQ0FBQztJQUNMLENBQUM7O0FBbkJjLDJDQUFZLEdBQUMsS0FBSyxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiLy8gQ29kZSBmcm9tIGF1ZGlvX3NvdXJjZV93b3JrbGV0LmpzIGFzIHN0cmluZyBjb25zdGFudCB0byBiZSBsb2FkZWQgYXMgbW9kdWxlXHJcbi8vIENoYW5nZXMgaW4gYXVkaW9fc291cmNlX3dvcmtsZXQuanMgbXVzdCBiZSBjb3BpZWQgYW5kIHBhc3RlZCB0byB0aGlzIHN0cmluZyBjb25zdGFudFxyXG5cclxuY29uc3QgYXN3cFN0ciA9IFwiXFxuXCIgK1xyXG4gICAgXCIvLyBJbXBvcnRhbnQgbm90ZTogQ2hhbmdlcyBpbiBhdWRpb19zb3VyY2Vfd29ya2xldC5qcyBtdXN0IGJlIGNvcGllZCBhbmQgcGFzdGVkIHRvIHRoZSBzdHJpbmcgY29uc3RhbnQgYXN3cFN0ciBpbiBhdWRpb19zb3VyY2Vfd29ya2xldF9tb2R1bGVfbG9hZGVyLnRzXFxuXCIgK1xyXG4gICAgXCJcXG5cIiArXHJcbiAgICBcIlxcblwiICtcclxuICAgIFwiY2xhc3MgQXVkaW9Tb3VyY2VQcm9jZXNzb3IgZXh0ZW5kcyBBdWRpb1dvcmtsZXRQcm9jZXNzb3J7XFxuXCIgK1xyXG4gICAgXCJcXG5cIiArXHJcbiAgICBcIiAgICBmaWxsZWRGcmFtZXM9MDtcXG5cIiArXHJcbiAgICBcIiAgICBhdWRpb0J1ZmZlcnM9bmV3IEFycmF5KCk7XFxuXCIgK1xyXG4gICAgXCIgICAgY3VycmVudEF1ZGlvQnVmZmVyPW51bGw7XFxuXCIgK1xyXG4gICAgXCIgICAgY3VycmVudEF1ZGlvQnVmZmVyRnJhbWVQb3M9MDtcXG5cIiArXHJcbiAgICBcIiAgICBjdXJyZW50QXVkaW9CdWZmZXJBdmFpbD0wO1xcblwiICtcclxuICAgIFwiICAgIHJ1bm5pbmc9ZmFsc2U7XFxuXCIgK1xyXG4gICAgXCIgICAgc3RhbGxlZD1mYWxzZTtcXG5cIiArXHJcbiAgICBcIiAgICBzdG9wcGVkPWZhbHNlO1xcblwiICtcclxuICAgIFwiICAgIGVuZE9mU3RyZWFtPWZhbHNlO1xcblwiICtcclxuICAgIFwiICAgIGVuZGVkPWZhbHNlO1xcblwiICtcclxuICAgIFwiXFxuXCIgK1xyXG4gICAgXCIgICAgY29uc3RydWN0b3IoKSB7XFxuXCIgK1xyXG4gICAgXCIgICAgICAgIHN1cGVyKHtudW1iZXJPZklucHV0czowLG51bWJlck9mT3V0cHV0czoxfSk7XFxuXCIgK1xyXG4gICAgXCIgICAgICAgIHRoaXMucG9ydC5vbm1lc3NhZ2U9KG1zZ0V2KT0+e1xcblwiICtcclxuICAgIFwiICAgICAgICAgIC8vIHJlY2VpdmVkIGF1ZGlvIHBsYXliYWNrIGRhdGEgZnJvbSBhcHBsaWNhdGlvblxcblwiICtcclxuICAgIFwiICAgICAgICAgIC8vY29uc29sZS5kZWJ1ZyhcXFwiQXVkaW8gc291cmNlIHdvcmtsZXQgbXNnOiBSZWNlaXZlZC5cXFwiKTtcXG5cIiArXHJcbiAgICBcIlxcblwiICtcclxuICAgIFwiICAgICAgICAgIGlmKG1zZ0V2LmRhdGEuY21kKXtcXG5cIiArXHJcbiAgICBcIiAgICAgICAgICAgIGlmKCdkYXRhJz09PW1zZ0V2LmRhdGEuY21kKSB7XFxuXCIgK1xyXG4gICAgXCIgICAgICAgICAgICAgIGxldCBjaHMgPSBtc2dFdi5kYXRhLmNocztcXG5cIiArXHJcbiAgICBcIlxcblwiICtcclxuICAgIFwiICAgICAgICAgICAgICBsZXQgYXVkaW9EYXRhID0gbmV3IEFycmF5KGNocyk7XFxuXCIgK1xyXG4gICAgXCIgICAgICAgICAgICAgIGZvciAobGV0IGNoID0gMDsgY2ggPCBjaHM7IGNoKyspIHtcXG5cIiArXHJcbiAgICBcIiAgICAgICAgICAgICAgICBhdWRpb0RhdGFbY2hdID0gbmV3IEZsb2F0MzJBcnJheShtc2dFdi5kYXRhLmF1ZGlvRGF0YVtjaF0pO1xcblwiICtcclxuICAgIFwiICAgICAgICAgICAgICB9XFxuXCIgK1xyXG4gICAgXCIgICAgICAgICAgICAgIGxldCBtc2dDaEJ1Zkxlbj1hdWRpb0RhdGFbMF0ubGVuZ3RoO1xcblwiICtcclxuICAgIFwiICAgICAgICAgICAgICB0aGlzLmF1ZGlvQnVmZmVycy5wdXNoKGF1ZGlvRGF0YSk7XFxuXCIgK1xyXG4gICAgXCIgICAgICAgICAgICAgIHRoaXMuZmlsbGVkRnJhbWVzICs9IG1zZ0NoQnVmTGVuO1xcblwiICtcclxuICAgIFwiICAgICAgICAgICAgICAvL2NvbnNvbGUuZGVidWcoXFxcIkF1ZGlvIHNvdXJjZSB3b3JrbGV0IG1zZzogRmlsbGVkIFxcXCIgKyB0aGlzLmZpbGxlZEZyYW1lcysgXFxcIiBpbiBcXFwiK3RoaXMuYXVkaW9CdWZmZXJzLmxlbmd0aCtcXFwiIGJ1ZmZlcnMuXFxcIik7XFxuXCIgK1xyXG4gICAgXCJcXG5cIiArXHJcbiAgICBcIiAgICAgICAgICAgIH1lbHNlIGlmKCdzdGFydCc9PT1tc2dFdi5kYXRhLmNtZCl7XFxuXCIgK1xyXG4gICAgXCIgICAgICAgICAgICAgIHRoaXMucnVubmluZz10cnVlO1xcblwiICtcclxuICAgIFwiICAgICAgICAgICAgfWVsc2UgaWYoJ3N0b3AnPT09bXNnRXYuZGF0YS5jbWQpe1xcblwiICtcclxuICAgIFwiICAgICAgICAgICAgICAvL2NvbnNvbGUuZGVidWcoXFxcIlN0b3AuLi5cXFwiKTtcXG5cIiArXHJcbiAgICBcIiAgICAgICAgICAgICAgdGhpcy5ydW5uaW5nPWZhbHNlO1xcblwiICtcclxuICAgIFwiICAgICAgICAgICAgICB0aGlzLnN0b3BwZWQ9dHJ1ZTtcXG5cIiArXHJcbiAgICBcIiAgICAgICAgICAgICAgLy8gY2xlYXIgYnVmZmVyc1xcblwiICtcclxuICAgIFwiICAgICAgICAgICAgICB0aGlzLmZpbGxlZEZyYW1lcz0wO1xcblwiICtcclxuICAgIFwiICAgICAgICAgICAgICB3aGlsZSh0aGlzLmF1ZGlvQnVmZmVycy5sZW5ndGggPiAwKSB7XFxuXCIgK1xyXG4gICAgXCIgICAgICAgICAgICAgICAgdGhpcy5hdWRpb0J1ZmZlcnMucG9wKCk7XFxuXCIgK1xyXG4gICAgXCIgICAgICAgICAgICAgIH1cXG5cIiArXHJcbiAgICBcIiAgICAgICAgICAgICAgdGhpcy5jdXJyZW50QXVkaW9CdWZmZXI9bmV3IEZsb2F0MzJBcnJheSgwKTtcXG5cIiArXHJcbiAgICBcIiAgICAgICAgICAgIH1lbHNlIGlmKCdlbmRPZlN0cmVhbSc9PT1tc2dFdi5kYXRhLmNtZCl7XFxuXCIgK1xyXG4gICAgXCIgICAgICAgICAgICAgIHRoaXMuZW5kT2ZTdHJlYW09dHJ1ZTtcXG5cIiArXHJcbiAgICBcIiAgICAgICAgICAgIH1lbHNlIGlmKCdjb250aW51ZSc9PT1tc2dFdi5kYXRhLmNtZCl7XFxuXCIgK1xyXG4gICAgXCIgICAgICAgICAgICAgIGNvbnNvbGUuZGVidWcoXFxcIkNvbnRpbnVlIGFmdGVyIHN0YWxsZWQuLi5cXFwiKTtcXG5cIiArXHJcbiAgICBcIiAgICAgICAgICAgICAgdGhpcy5zdGFsbGVkPWZhbHNlO1xcblwiICtcclxuICAgIFwiICAgICAgICAgICAgICB0aGlzLnBvcnQucG9zdE1lc3NhZ2Uoe2V2ZW50VHlwZTogJ3Jlc3VtZWQnfSk7XFxuXCIgK1xyXG4gICAgXCIgICAgICAgICAgICB9XFxuXCIgK1xyXG4gICAgXCIgICAgICAgICAgfVxcblwiICtcclxuICAgIFwiICAgICAgICB9XFxuXCIgK1xyXG4gICAgXCIgICAgfVxcblwiICtcclxuICAgIFwiXFxuXCIgK1xyXG4gICAgXCIgcHJvY2VzcyhcXG5cIiArXHJcbiAgICBcIiAgICAgIGlucHV0cyxcXG5cIiArXHJcbiAgICBcIiAgICAgIG91dHB1dHMsXFxuXCIgK1xyXG4gICAgXCIgICAgICBwYXJhbWV0ZXJzXFxuXCIgK1xyXG4gICAgXCIgICl7XFxuXCIgK1xyXG4gICAgXCIgICAgICAvL2NvbnNvbGUuZGVidWcoXFxcIkF1ZGlvIHNvdXJjZSB3b3JrbGV0OiBwcm9jZXNzIFxcXCIrb3V0cHV0cy5sZW5ndGgrIFxcXCIgb3V0cHV0IGJ1ZmZlcnMuXFxcIik7XFxuXCIgK1xyXG4gICAgXCIgICAgICAvLyBjb3B5IHJpbmcgYnVmZmVyIGRhdGEgdG8gb3V0cHV0c1xcblwiICtcclxuICAgIFwiICAgICAgICBpZighdGhpcy5ydW5uaW5nIHx8IHRoaXMuc3RhbGxlZCl7XFxuXCIgK1xyXG4gICAgXCIgICAgICAgICAgICBpZih0aGlzLmVuZE9mU3RyZWFtKSB7XFxuXCIgK1xyXG4gICAgXCIgICAgICAgICAgICAgICAgdGhpcy5lbmRlZCA9IHRydWU7XFxuXCIgK1xyXG4gICAgXCIgICAgICAgICAgICAgICAgdGhpcy5wb3J0LnBvc3RNZXNzYWdlKHtldmVudFR5cGU6ICdlbmRlZCd9KTtcXG5cIiArXHJcbiAgICBcIiAgICAgICAgICAgIH1cXG5cIiArXHJcbiAgICBcIiAgICAgICAgICByZXR1cm4gIXRoaXMuZW5kZWQgJiYgIXRoaXMuc3RvcHBlZDtcXG5cIiArXHJcbiAgICBcIiAgICAgICAgfVxcblwiICtcclxuICAgIFwiXFxuXCIgK1xyXG4gICAgXCIgICAgICAgIGxldCBvdXRwdXQ9b3V0cHV0c1swXTtcXG5cIiArXHJcbiAgICBcIiAgICAgICAgbGV0IGNocz1vdXRwdXQubGVuZ3RoO1xcblwiICtcclxuICAgIFwiICAgICAgICAvL2NvbnNvbGUuZGVidWcoXFxcIkF1ZGlvIHNvdXJjZSB3b3JrbGV0OiBPdXRwdXQgY2hhbm5lbHM6IFxcXCIrY2hzKTtcXG5cIiArXHJcbiAgICBcIiAgICAgICAgaWYoY2hzPjApIHtcXG5cIiArXHJcbiAgICBcIlxcblwiICtcclxuICAgIFwiICAgICAgICAgIGxldCBvdXRDaDAgPSBvdXRwdXRbMF07XFxuXCIgK1xyXG4gICAgXCIgICAgICAgICAgbGV0IG91dENoTGVuID0gb3V0Q2gwLmxlbmd0aDtcXG5cIiArXHJcbiAgICBcIlxcblwiICtcclxuICAgIFwiICAgICAgICAgIGlmKCF0aGlzLmN1cnJlbnRBdWRpb0J1ZmZlcil7XFxuXCIgK1xyXG4gICAgXCIgICAgICAgICAgICAvLyBnZXQgZmlyc3QgYnVmZmVyXFxuXCIgK1xyXG4gICAgXCIgICAgICAgICAgICBsZXQgbnh0QnVmZj10aGlzLmF1ZGlvQnVmZmVycy5zaGlmdCgpO1xcblwiICtcclxuICAgIFwiICAgICAgICAgICAgaWYobnh0QnVmZikge1xcblwiICtcclxuICAgIFwiICAgICAgICAgICAgICB0aGlzLmN1cnJlbnRBdWRpb0J1ZmZlciA9IG54dEJ1ZmY7XFxuXCIgK1xyXG4gICAgXCIgICAgICAgICAgICAgIHRoaXMuY3VycmVudEF1ZGlvQnVmZmVyRnJhbWVQb3M9MDtcXG5cIiArXHJcbiAgICBcIiAgICAgICAgICAgICAgdGhpcy5jdXJyZW50QXVkaW9CdWZmZXJBdmFpbD10aGlzLmN1cnJlbnRBdWRpb0J1ZmZlclswXS5sZW5ndGg7XFxuXCIgK1xyXG4gICAgXCIgICAgICAgICAgICB9ZWxzZXtcXG5cIiArXHJcbiAgICBcIiAgICAgICAgICAgICAgcmV0dXJuIHRydWU7XFxuXCIgK1xyXG4gICAgXCIgICAgICAgICAgICB9XFxuXCIgK1xyXG4gICAgXCIgICAgICAgICAgfVxcblwiICtcclxuICAgIFwiXFxuXCIgK1xyXG4gICAgXCIgICAgICAgICAgbGV0IGNvcGllZD0wO1xcblwiICtcclxuICAgIFwiICAgICAgICAgIGRve1xcblwiICtcclxuICAgIFwiICAgICAgICAgICAgaWYodGhpcy5jdXJyZW50QXVkaW9CdWZmZXJBdmFpbD09MCl7XFxuXCIgK1xyXG4gICAgXCIgICAgICAgICAgICAgIGxldCBueHRCdWZmPXRoaXMuYXVkaW9CdWZmZXJzLnNoaWZ0KCk7XFxuXCIgK1xyXG4gICAgXCIgICAgICAgICAgICAgIGlmKG54dEJ1ZmYpe1xcblwiICtcclxuICAgIFwiICAgICAgICAgICAgICAgIHRoaXMuY3VycmVudEF1ZGlvQnVmZmVyPW54dEJ1ZmY7XFxuXCIgK1xyXG4gICAgXCIgICAgICAgICAgICAgICAgdGhpcy5jdXJyZW50QXVkaW9CdWZmZXJGcmFtZVBvcz0wO1xcblwiICtcclxuICAgIFwiICAgICAgICAgICAgICAgIHRoaXMuY3VycmVudEF1ZGlvQnVmZmVyQXZhaWw9dGhpcy5jdXJyZW50QXVkaW9CdWZmZXJbMF0ubGVuZ3RoO1xcblwiICtcclxuICAgIFwiICAgICAgICAgICAgICAgIC8vY29uc29sZS5kZWJ1ZyhcXFwiTmV4dCBidWZmZXIgd2l0aCBcXFwiK3RoaXMuY3VycmVudEF1ZGlvQnVmZmVyQXZhaWwrIFxcXCIgZnJhbWVzXFxcIik7XFxuXCIgK1xyXG4gICAgXCIgICAgICAgICAgICAgICAgdGhpcy5wb3J0LnBvc3RNZXNzYWdlKHtldmVudFR5cGU6J2J1ZmZlck5vdGlmaWNhdGlvbicsZmlsbGVkRnJhbWVzOnRoaXMuZmlsbGVkRnJhbWVzfSk7XFxuXCIgK1xyXG4gICAgXCIgICAgICAgICAgICAgIH1lbHNle1xcblwiICtcclxuICAgIFwiICAgICAgICAgICAgICAgIGlmKHRoaXMuZW5kT2ZTdHJlYW0pIHtcXG5cIiArXHJcbiAgICBcIiAgICAgICAgICAgICAgICAgIHRoaXMuZW5kZWQgPSB0cnVlO1xcblwiICtcclxuICAgIFwiICAgICAgICAgICAgICAgICAgdGhpcy5wb3J0LnBvc3RNZXNzYWdlKHtldmVudFR5cGU6ICdlbmRlZCd9KTtcXG5cIiArXHJcbiAgICBcIiAgICAgICAgICAgICAgICAgIC8vY29uc29sZS5kZWJ1ZyhcXFwiU3RyZWFtIGVuZGVkXFxcIik7XFxuXCIgK1xyXG4gICAgXCIgICAgICAgICAgICAgICAgfWVsc2V7XFxuXCIgK1xyXG4gICAgXCIgICAgICAgICAgICAgICAgICBpZighdGhpcy5zdGFsbGVkKSB7XFxuXCIgK1xyXG4gICAgXCIgICAgICAgICAgICAgICAgICAgIHRoaXMuc3RhbGxlZCA9IHRydWU7XFxuXCIgK1xyXG4gICAgXCIgICAgICAgICAgICAgICAgICAgIHRoaXMucG9ydC5wb3N0TWVzc2FnZSh7ZXZlbnRUeXBlOiAnc3RhbGxlZCd9KTtcXG5cIiArXHJcbiAgICBcIiAgICAgICAgICAgICAgICAgIH1cXG5cIiArXHJcbiAgICBcIiAgICAgICAgICAgICAgICB9XFxuXCIgK1xyXG4gICAgXCIgICAgICAgICAgICAgICAgYnJlYWs7XFxuXCIgK1xyXG4gICAgXCIgICAgICAgICAgICAgIH1cXG5cIiArXHJcbiAgICBcIiAgICAgICAgICAgIH1cXG5cIiArXHJcbiAgICBcIiAgICAgICAgICAgIC8vY29uc29sZS5kZWJ1ZyhcXFwib3V0Q2hMZW46IFxcXCIrb3V0Q2hMZW4rXFxcIiwgY29waWVkOiBcXFwiK2NvcGllZCtcXFwiLCBjdXJyZW50IGF2YWlsOiBcXFwiK3RoaXMuY3VycmVudEF1ZGlvQnVmZmVyQXZhaWwpO1xcblwiICtcclxuICAgIFwiICAgICAgICAgICAgbGV0IHRvQ29weT1vdXRDaExlbi1jb3BpZWQ7XFxuXCIgK1xyXG4gICAgXCIgICAgICAgICAgICBpZih0b0NvcHk+dGhpcy5jdXJyZW50QXVkaW9CdWZmZXJBdmFpbCl7XFxuXCIgK1xyXG4gICAgXCIgICAgICAgICAgICAgIHRvQ29weT10aGlzLmN1cnJlbnRBdWRpb0J1ZmZlckF2YWlsO1xcblwiICtcclxuICAgIFwiICAgICAgICAgICAgfVxcblwiICtcclxuICAgIFwiICAgICAgICAgICAgLy9jb25zb2xlLmRlYnVnKFxcXCJDb3B5IFxcXCIrdG9Db3B5K1xcXCIgZnJhbWVzLi4uXFxcIik7XFxuXCIgK1xyXG4gICAgXCIgICAgICAgICAgICBmb3IobGV0IGNoPTA7Y2g8Y2hzO2NoKyspIHtcXG5cIiArXHJcbiAgICBcIiAgICAgICAgICAgICAgbGV0IG91dENoPW91dHB1dFtjaF07XFxuXCIgK1xyXG4gICAgXCIgICAgICAgICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgdG9Db3B5OyBpKyspIHtcXG5cIiArXHJcbiAgICBcIiAgICAgICAgICAgICAgICBvdXRDaFtjb3BpZWQraV09dGhpcy5jdXJyZW50QXVkaW9CdWZmZXJbY2hdW3RoaXMuY3VycmVudEF1ZGlvQnVmZmVyRnJhbWVQb3MraV07XFxuXCIgK1xyXG4gICAgXCIgICAgICAgICAgICAgIH1cXG5cIiArXHJcbiAgICBcIiAgICAgICAgICAgIH1cXG5cIiArXHJcbiAgICBcIiAgICAgICAgICAgIGNvcGllZCs9dG9Db3B5O1xcblwiICtcclxuICAgIFwiICAgICAgICAgICAgdGhpcy5jdXJyZW50QXVkaW9CdWZmZXJGcmFtZVBvcys9dG9Db3B5O1xcblwiICtcclxuICAgIFwiICAgICAgICAgICAgdGhpcy5jdXJyZW50QXVkaW9CdWZmZXJBdmFpbC09dG9Db3B5O1xcblwiICtcclxuICAgIFwiXFxuXCIgK1xyXG4gICAgXCIgICAgICAgICAgfXdoaWxlKGNvcGllZDxvdXRDaExlbik7XFxuXCIgK1xyXG4gICAgXCIgICAgICAgICAgdGhpcy5maWxsZWRGcmFtZXMtPWNvcGllZDtcXG5cIiArXHJcbiAgICBcIiAgICAgICAgICAvL2NvbnNvbGUuZGVidWcoXFxcIkNvcGllZCBcXFwiK2NvcGllZCtcXFwiIGZyYW1lcy5cXFwiKTtcXG5cIiArXHJcbiAgICBcIiAgICAgICAgfVxcblwiICtcclxuICAgIFwiICAgICByZXR1cm4gIXRoaXMuZW5kZWQ7XFxuXCIgK1xyXG4gICAgXCIgIH1cXG5cIiArXHJcbiAgICBcIn1cXG5cIiArXHJcbiAgICBcIlxcblwiICtcclxuICAgIFwicmVnaXN0ZXJQcm9jZXNzb3IoJ2F1ZGlvLXNvdXJjZS13b3JrbGV0JyxBdWRpb1NvdXJjZVByb2Nlc3Nvcik7XFxuXCI7XHJcblxyXG5leHBvcnQgY2xhc3MgQXVkaW9Tb3VyY2VXb3JrbGV0TW9kdWxlTG9hZGVye1xyXG5cclxuICBwcml2YXRlIHN0YXRpYyBtb2R1bGVMb2FkZWQ9ZmFsc2U7XHJcblxyXG4gIHN0YXRpYyBsb2FkTW9kdWxlKGNvbnRleHQ6IEF1ZGlvQ29udGV4dCk6IFByb21pc2U8dm9pZD4ge1xyXG4gICAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcclxuICAgICAgaWYgKEF1ZGlvU291cmNlV29ya2xldE1vZHVsZUxvYWRlci5tb2R1bGVMb2FkZWQpIHtcclxuICAgICAgICByZXNvbHZlLmNhbGwoc2VsZik7XHJcbiAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgY29uc3QgYXVkaW9Xb3JrbGV0TW9kdWxlQmxvYiA9IG5ldyBCbG9iKFthc3dwU3RyXSwge3R5cGU6ICd0ZXh0L2phdmFzY3JpcHQnfSk7XHJcbiAgICAgICAgY29uc3QgYXVkaW9Xb3JrbGV0TW9kdWxlQmxvYlVybCA9IHdpbmRvdy5VUkwuY3JlYXRlT2JqZWN0VVJMKGF1ZGlvV29ya2xldE1vZHVsZUJsb2IpO1xyXG4gICAgICAgIGNvbnRleHQuYXVkaW9Xb3JrbGV0LmFkZE1vZHVsZShhdWRpb1dvcmtsZXRNb2R1bGVCbG9iVXJsKS50aGVuKCgpID0+IHtcclxuICAgICAgICAgIEF1ZGlvU291cmNlV29ya2xldE1vZHVsZUxvYWRlci5tb2R1bGVMb2FkZWQgPSB0cnVlO1xyXG4gICAgICAgICAgcmVzb2x2ZS5jYWxsKHNlbGYpO1xyXG4gICAgICAgIH0pLmNhdGNoKChyZWFzb24pID0+IHtcclxuICAgICAgICAgIGNvbnNvbGUuZXJyb3IocmVhc29uKTtcclxuICAgICAgICAgIHJlamVjdC5jYWxsKHJlYXNvbik7XHJcbiAgICAgICAgfSk7XHJcblxyXG4gICAgICB9XHJcbiAgICB9KTtcclxuICB9XHJcbn1cclxuIl19