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,79 +0,0 @@
1
- export class AudioContextProvider {
2
- static audioContextInstance() {
3
- if (!this._audioContext) {
4
- let debugFail = false;
5
- if (!window.AudioContext || typeof window.AudioContext !== 'function' || debugFail) {
6
- this._audioContext = null;
7
- throw new Error('Browser does not support Web Audio API!');
8
- }
9
- else {
10
- console.debug("Get new audio context...");
11
- this._audioContext = new window.AudioContext();
12
- console.debug("Created new audio context.");
13
- this._audioContext.addEventListener('statechange', () => {
14
- console.debug("Audio context state changed: " + this._audioContext?.state);
15
- });
16
- console.debug("Created new audio context with state: " + this._audioContext?.state);
17
- }
18
- }
19
- return this._audioContext;
20
- }
21
- // public static audioContextInstanceRunning(audioContext?:AudioContext):Promise<AudioContext>{
22
- //
23
- // return new Promise<AudioContext>((resolve,reject)=>{
24
- // let aCtx=audioContext?audioContext:AudioContextProvider.audioContextInstance();
25
- // if(aCtx) {
26
- // if(aCtx.state==='closed') {
27
- // reject(new Error('Audio context already closed.'));
28
- // }else if(aCtx.state==='running') {
29
- // resolve(aCtx);
30
- // }else{
31
- // aCtx.resume().then(() => {
32
- // if(aCtx) {
33
- // resolve(aCtx);
34
- // }else{
35
- // reject(new Error('Could not get audio context'));
36
- // }
37
- // }).catch(() => {
38
- // reject(new Error('Could not resume audio context'));
39
- // })
40
- // }
41
- // }else{
42
- // reject(new Error('Could not get audio context from browser'));
43
- // }
44
- // });
45
- // }
46
- // public static decodeAudioData(data:ArrayBuffer,audioContext?:AudioContext):Promise<AudioBuffer>{
47
- // return new Promise<AudioBuffer>((resolve,reject)=>{
48
- // // decodeAudioData requires an audio context in running state
49
- // AudioContextProvider.audioContextInstanceRunning(audioContext).then(
50
- // (aCtx)=>{
51
- // // Do not use Promise version, which does not work with Safari 13
52
- // aCtx.decodeAudioData(data,decodedData => {
53
- // resolve(decodedData);
54
- // },(reason) => {
55
- // reject(reason);
56
- // });
57
- // }
58
- // ).catch((reason)=>{
59
- // reject(reason);
60
- // })
61
- // })
62
- // }
63
- static decodeAudioData(data) {
64
- return new Promise((resolve, reject) => {
65
- if (!this._offlineAudioContext) {
66
- this._offlineAudioContext = new OfflineAudioContext(1, 44100, 44100);
67
- }
68
- // Do not use Promise version, which does not work with Safari 13
69
- this._offlineAudioContext.decodeAudioData(data, decodedData => {
70
- resolve(decodedData);
71
- }, (reason) => {
72
- reject(reason);
73
- });
74
- });
75
- }
76
- }
77
- AudioContextProvider._audioContext = null;
78
- AudioContextProvider._offlineAudioContext = null;
79
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY29udGV4dC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uL3Byb2plY3RzL3NwZWVjaHJlY29yZGVybmcvc3JjL2xpYi9hdWRpby9jb250ZXh0LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUNBLE1BQU0sT0FBTyxvQkFBb0I7SUFLeEIsTUFBTSxDQUFDLG9CQUFvQjtRQUVoQyxJQUFJLENBQUMsSUFBSSxDQUFDLGFBQWEsRUFBRTtZQUN2QixJQUFJLFNBQVMsR0FBRyxLQUFLLENBQUM7WUFDdEIsSUFBSSxDQUFDLE1BQU0sQ0FBQyxZQUFZLElBQUksT0FBTyxNQUFNLENBQUMsWUFBWSxLQUFLLFVBQVUsSUFBSSxTQUFTLEVBQUU7Z0JBQ2xGLElBQUksQ0FBQyxhQUFhLEdBQUMsSUFBSSxDQUFDO2dCQUN4QixNQUFNLElBQUksS0FBSyxDQUFDLHlDQUF5QyxDQUFDLENBQUM7YUFDNUQ7aUJBQU07Z0JBQ0wsT0FBTyxDQUFDLEtBQUssQ0FBQywwQkFBMEIsQ0FBQyxDQUFDO2dCQUMxQyxJQUFJLENBQUMsYUFBYSxHQUFFLElBQUksTUFBTSxDQUFDLFlBQVksRUFBRSxDQUFDO2dCQUM5QyxPQUFPLENBQUMsS0FBSyxDQUFDLDRCQUE0QixDQUFDLENBQUM7Z0JBQzVDLElBQUksQ0FBQyxhQUFhLENBQUMsZ0JBQWdCLENBQUMsYUFBYSxFQUFFLEdBQUcsRUFBRTtvQkFDdEQsT0FBTyxDQUFDLEtBQUssQ0FBQywrQkFBK0IsR0FBQyxJQUFJLENBQUMsYUFBYSxFQUFFLEtBQUssQ0FBQyxDQUFDO2dCQUMzRSxDQUFDLENBQUMsQ0FBQztnQkFDSCxPQUFPLENBQUMsS0FBSyxDQUFDLHdDQUF3QyxHQUFDLElBQUksQ0FBQyxhQUFhLEVBQUUsS0FBSyxDQUFDLENBQUM7YUFDbkY7U0FDRjtRQUNELE9BQU8sSUFBSSxDQUFDLGFBQWEsQ0FBQztJQUM1QixDQUFDO0lBRUQsK0ZBQStGO0lBQy9GLEVBQUU7SUFDRiwyREFBMkQ7SUFDM0Qsd0ZBQXdGO0lBQ3hGLG1CQUFtQjtJQUNuQixzQ0FBc0M7SUFDdEMsZ0VBQWdFO0lBQ2hFLDZDQUE2QztJQUM3QywyQkFBMkI7SUFDM0IsaUJBQWlCO0lBQ2pCLHVDQUF1QztJQUN2Qyx5QkFBeUI7SUFDekIsK0JBQStCO0lBQy9CLHFCQUFxQjtJQUNyQixrRUFBa0U7SUFDbEUsZ0JBQWdCO0lBQ2hCLDZCQUE2QjtJQUM3QixtRUFBbUU7SUFDbkUsZUFBZTtJQUNmLFlBQVk7SUFDWixlQUFlO0lBQ2YseUVBQXlFO0lBQ3pFLFVBQVU7SUFDVixRQUFRO0lBQ1IsSUFBSTtJQUVKLG1HQUFtRztJQUNuRyx3REFBd0Q7SUFDeEQsb0VBQW9FO0lBQ3BFLDJFQUEyRTtJQUMzRSxrQkFBa0I7SUFDbEIsNEVBQTRFO0lBQzVFLHFEQUFxRDtJQUNyRCxrQ0FBa0M7SUFDbEMsMEJBQTBCO0lBQzFCLDRCQUE0QjtJQUM1QixjQUFjO0lBQ2QsVUFBVTtJQUNWLDBCQUEwQjtJQUMxQix3QkFBd0I7SUFDeEIsU0FBUztJQUNULE9BQU87SUFDUCxJQUFJO0lBR0csTUFBTSxDQUFDLGVBQWUsQ0FBQyxJQUFnQjtRQUMxQyxPQUFPLElBQUksT0FBTyxDQUFjLENBQUMsT0FBTyxFQUFDLE1BQU0sRUFBQyxFQUFFO1lBQ2hELElBQUcsQ0FBQyxJQUFJLENBQUMsb0JBQW9CLEVBQUU7Z0JBQzNCLElBQUksQ0FBQyxvQkFBb0IsR0FBRyxJQUFJLG1CQUFtQixDQUFDLENBQUMsRUFBRSxLQUFLLEVBQUUsS0FBSyxDQUFDLENBQUM7YUFDeEU7WUFDQyxpRUFBaUU7WUFDakUsSUFBSSxDQUFDLG9CQUFvQixDQUFDLGVBQWUsQ0FBQyxJQUFJLEVBQUMsV0FBVyxDQUFDLEVBQUU7Z0JBQzNELE9BQU8sQ0FBQyxXQUFXLENBQUMsQ0FBQztZQUN2QixDQUFDLEVBQUMsQ0FBQyxNQUFNLEVBQUUsRUFBRTtnQkFDWCxNQUFNLENBQUMsTUFBTSxDQUFDLENBQUM7WUFDakIsQ0FBQyxDQUFDLENBQUM7UUFDTCxDQUFDLENBQ0YsQ0FBQTtJQUVMLENBQUM7O0FBbEZjLGtDQUFhLEdBQW9CLElBQUksQ0FBQztBQUN0Qyx5Q0FBb0IsR0FBMEIsSUFBSSxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiXHJcbmV4cG9ydCBjbGFzcyBBdWRpb0NvbnRleHRQcm92aWRlclxyXG57XHJcbiAgcHJpdmF0ZSBzdGF0aWMgX2F1ZGlvQ29udGV4dDpBdWRpb0NvbnRleHR8IG51bGw9bnVsbDtcclxuICBwcml2YXRlIHN0YXRpYyBfb2ZmbGluZUF1ZGlvQ29udGV4dDpPZmZsaW5lQXVkaW9Db250ZXh0fG51bGw9bnVsbDtcclxuXHJcbiAgcHVibGljIHN0YXRpYyBhdWRpb0NvbnRleHRJbnN0YW5jZSgpOkF1ZGlvQ29udGV4dHxudWxsXHJcbiAge1xyXG4gICAgaWYgKCF0aGlzLl9hdWRpb0NvbnRleHQpIHtcclxuICAgICAgbGV0IGRlYnVnRmFpbCA9IGZhbHNlO1xyXG4gICAgICBpZiAoIXdpbmRvdy5BdWRpb0NvbnRleHQgfHwgdHlwZW9mIHdpbmRvdy5BdWRpb0NvbnRleHQgIT09ICdmdW5jdGlvbicgfHwgZGVidWdGYWlsKSB7XHJcbiAgICAgICAgdGhpcy5fYXVkaW9Db250ZXh0PW51bGw7XHJcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdCcm93c2VyIGRvZXMgbm90IHN1cHBvcnQgV2ViIEF1ZGlvIEFQSSEnKTtcclxuICAgICAgfSBlbHNlIHtcclxuICAgICAgICBjb25zb2xlLmRlYnVnKFwiR2V0IG5ldyBhdWRpbyBjb250ZXh0Li4uXCIpO1xyXG4gICAgICAgIHRoaXMuX2F1ZGlvQ29udGV4dD0gbmV3IHdpbmRvdy5BdWRpb0NvbnRleHQoKTtcclxuICAgICAgICBjb25zb2xlLmRlYnVnKFwiQ3JlYXRlZCBuZXcgYXVkaW8gY29udGV4dC5cIik7XHJcbiAgICAgICAgdGhpcy5fYXVkaW9Db250ZXh0LmFkZEV2ZW50TGlzdGVuZXIoJ3N0YXRlY2hhbmdlJywgKCkgPT4ge1xyXG4gICAgICAgICAgY29uc29sZS5kZWJ1ZyhcIkF1ZGlvIGNvbnRleHQgc3RhdGUgY2hhbmdlZDogXCIrdGhpcy5fYXVkaW9Db250ZXh0Py5zdGF0ZSk7XHJcbiAgICAgICAgfSk7XHJcbiAgICAgICAgY29uc29sZS5kZWJ1ZyhcIkNyZWF0ZWQgbmV3IGF1ZGlvIGNvbnRleHQgd2l0aCBzdGF0ZTogXCIrdGhpcy5fYXVkaW9Db250ZXh0Py5zdGF0ZSk7XHJcbiAgICAgIH1cclxuICAgIH1cclxuICAgIHJldHVybiB0aGlzLl9hdWRpb0NvbnRleHQ7XHJcbiAgfVxyXG5cclxuICAvLyBwdWJsaWMgc3RhdGljIGF1ZGlvQ29udGV4dEluc3RhbmNlUnVubmluZyhhdWRpb0NvbnRleHQ/OkF1ZGlvQ29udGV4dCk6UHJvbWlzZTxBdWRpb0NvbnRleHQ+e1xyXG4gIC8vXHJcbiAgLy8gICAgIHJldHVybiBuZXcgUHJvbWlzZTxBdWRpb0NvbnRleHQ+KChyZXNvbHZlLHJlamVjdCk9PntcclxuICAvLyAgICAgICBsZXQgYUN0eD1hdWRpb0NvbnRleHQ/YXVkaW9Db250ZXh0OkF1ZGlvQ29udGV4dFByb3ZpZGVyLmF1ZGlvQ29udGV4dEluc3RhbmNlKCk7XHJcbiAgLy8gICAgICAgaWYoYUN0eCkge1xyXG4gIC8vICAgICAgICAgaWYoYUN0eC5zdGF0ZT09PSdjbG9zZWQnKSB7XHJcbiAgLy8gICAgICAgICAgIHJlamVjdChuZXcgRXJyb3IoJ0F1ZGlvIGNvbnRleHQgYWxyZWFkeSBjbG9zZWQuJykpO1xyXG4gIC8vICAgICAgICAgfWVsc2UgaWYoYUN0eC5zdGF0ZT09PSdydW5uaW5nJykge1xyXG4gIC8vICAgICAgICAgICByZXNvbHZlKGFDdHgpO1xyXG4gIC8vICAgICAgICAgfWVsc2V7XHJcbiAgLy8gICAgICAgICAgIGFDdHgucmVzdW1lKCkudGhlbigoKSA9PiB7XHJcbiAgLy8gICAgICAgICAgICAgaWYoYUN0eCkge1xyXG4gIC8vICAgICAgICAgICAgICAgcmVzb2x2ZShhQ3R4KTtcclxuICAvLyAgICAgICAgICAgICB9ZWxzZXtcclxuICAvLyAgICAgICAgICAgICAgIHJlamVjdChuZXcgRXJyb3IoJ0NvdWxkIG5vdCBnZXQgYXVkaW8gY29udGV4dCcpKTtcclxuICAvLyAgICAgICAgICAgICB9XHJcbiAgLy8gICAgICAgICAgIH0pLmNhdGNoKCgpID0+IHtcclxuICAvLyAgICAgICAgICAgICByZWplY3QobmV3IEVycm9yKCdDb3VsZCBub3QgcmVzdW1lIGF1ZGlvIGNvbnRleHQnKSk7XHJcbiAgLy8gICAgICAgICAgIH0pXHJcbiAgLy8gICAgICAgICB9XHJcbiAgLy8gICAgICAgfWVsc2V7XHJcbiAgLy8gICAgICAgICByZWplY3QobmV3IEVycm9yKCdDb3VsZCBub3QgZ2V0IGF1ZGlvIGNvbnRleHQgZnJvbSBicm93c2VyJykpO1xyXG4gIC8vICAgICAgIH1cclxuICAvLyAgIH0pO1xyXG4gIC8vIH1cclxuXHJcbiAgLy8gcHVibGljIHN0YXRpYyBkZWNvZGVBdWRpb0RhdGEoZGF0YTpBcnJheUJ1ZmZlcixhdWRpb0NvbnRleHQ/OkF1ZGlvQ29udGV4dCk6UHJvbWlzZTxBdWRpb0J1ZmZlcj57XHJcbiAgLy8gICByZXR1cm4gbmV3IFByb21pc2U8QXVkaW9CdWZmZXI+KChyZXNvbHZlLHJlamVjdCk9PntcclxuICAvLyAgICAgLy8gZGVjb2RlQXVkaW9EYXRhIHJlcXVpcmVzIGFuIGF1ZGlvIGNvbnRleHQgaW4gcnVubmluZyBzdGF0ZVxyXG4gIC8vICAgICBBdWRpb0NvbnRleHRQcm92aWRlci5hdWRpb0NvbnRleHRJbnN0YW5jZVJ1bm5pbmcoYXVkaW9Db250ZXh0KS50aGVuKFxyXG4gIC8vICAgICAgIChhQ3R4KT0+e1xyXG4gIC8vICAgICAgICAgLy8gRG8gbm90IHVzZSBQcm9taXNlIHZlcnNpb24sIHdoaWNoIGRvZXMgbm90IHdvcmsgd2l0aCBTYWZhcmkgMTNcclxuICAvLyAgICAgICAgIGFDdHguZGVjb2RlQXVkaW9EYXRhKGRhdGEsZGVjb2RlZERhdGEgPT4ge1xyXG4gIC8vICAgICAgICAgICByZXNvbHZlKGRlY29kZWREYXRhKTtcclxuICAvLyAgICAgICAgIH0sKHJlYXNvbikgPT4ge1xyXG4gIC8vICAgICAgICAgICByZWplY3QocmVhc29uKTtcclxuICAvLyAgICAgICAgIH0pO1xyXG4gIC8vICAgICAgIH1cclxuICAvLyAgICAgKS5jYXRjaCgocmVhc29uKT0+e1xyXG4gIC8vICAgICAgIHJlamVjdChyZWFzb24pO1xyXG4gIC8vICAgICB9KVxyXG4gIC8vICAgfSlcclxuICAvLyB9XHJcblxyXG5cclxuICBwdWJsaWMgc3RhdGljIGRlY29kZUF1ZGlvRGF0YShkYXRhOkFycmF5QnVmZmVyKTpQcm9taXNlPEF1ZGlvQnVmZmVyPntcclxuICAgICAgcmV0dXJuIG5ldyBQcm9taXNlPEF1ZGlvQnVmZmVyPigocmVzb2x2ZSxyZWplY3QpPT57XHJcbiAgICAgICAgaWYoIXRoaXMuX29mZmxpbmVBdWRpb0NvbnRleHQpIHtcclxuICAgICAgICAgICAgdGhpcy5fb2ZmbGluZUF1ZGlvQ29udGV4dCA9IG5ldyBPZmZsaW5lQXVkaW9Db250ZXh0KDEsIDQ0MTAwLCA0NDEwMCk7XHJcbiAgICAgICAgfVxyXG4gICAgICAgICAgLy8gRG8gbm90IHVzZSBQcm9taXNlIHZlcnNpb24sIHdoaWNoIGRvZXMgbm90IHdvcmsgd2l0aCBTYWZhcmkgMTNcclxuICAgICAgICAgIHRoaXMuX29mZmxpbmVBdWRpb0NvbnRleHQuZGVjb2RlQXVkaW9EYXRhKGRhdGEsZGVjb2RlZERhdGEgPT4ge1xyXG4gICAgICAgICAgICByZXNvbHZlKGRlY29kZWREYXRhKTtcclxuICAgICAgICAgIH0sKHJlYXNvbikgPT4ge1xyXG4gICAgICAgICAgICByZWplY3QocmVhc29uKTtcclxuICAgICAgICAgIH0pO1xyXG4gICAgICAgIH1cclxuICAgICAgKVxyXG5cclxuICB9XHJcblxyXG59XHJcbiJdfQ==
@@ -1,6 +0,0 @@
1
- export class WavFileFormat {
2
- }
3
- WavFileFormat.RIFF_KEY = 'RIFF';
4
- WavFileFormat.WAV_KEY = 'WAVE';
5
- WavFileFormat.PCM = 0x0001;
6
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoid2F2Zm9ybWF0LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vLi4vcHJvamVjdHMvc3BlZWNocmVjb3JkZXJuZy9zcmMvbGliL2F1ZGlvL2ltcGwvd2F2Zm9ybWF0LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUVFLE1BQU0sT0FBTyxhQUFhOztBQUNOLHNCQUFRLEdBQVUsTUFBTSxDQUFDO0FBQ3pCLHFCQUFPLEdBQVUsTUFBTSxDQUFDO0FBQ3hCLGlCQUFHLEdBQVcsTUFBTSxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiXHJcblxyXG4gIGV4cG9ydCBjbGFzcyBXYXZGaWxlRm9ybWF0IHtcclxuICAgICAgc3RhdGljIHJlYWRvbmx5IFJJRkZfS0VZOnN0cmluZyA9ICdSSUZGJztcclxuICAgICAgc3RhdGljIHJlYWRvbmx5IFdBVl9LRVk6c3RyaW5nID0gJ1dBVkUnO1xyXG4gICAgICBzdGF0aWMgcmVhZG9ubHkgUENNOm51bWJlciA9ICAweDAwMDE7XHJcbiAgICB9XHJcblxyXG5cclxuXHJcblxyXG4iXX0=
@@ -1,105 +0,0 @@
1
- import { WavFileFormat } from './wavformat';
2
- import { BinaryByteWriter } from '../../io/BinaryWriter';
3
- import { WorkerHelper } from "../../utils/utils";
4
- export class WavWriter {
5
- constructor() {
6
- this.workerURL = null;
7
- this.bw = new BinaryByteWriter();
8
- }
9
- /*
10
- * Method used as worker code.
11
- */
12
- workerFunction() {
13
- self.onmessage = function (msg) {
14
- const valView = new DataView(msg.data.buf, msg.data.bufPos);
15
- let bufPos = 0;
16
- let hDynIntRange = 1 << (msg.data.sampleSizeInBits - 1);
17
- for (let s = 0; s < msg.data.frameLength; s++) {
18
- // interleaved channel data
19
- for (let ch = 0; ch < msg.data.chs; ch++) {
20
- let srcPos = (ch * msg.data.frameLength) + s;
21
- let valFlt = msg.data.audioData[srcPos];
22
- let valInt = Math.round(valFlt * hDynIntRange);
23
- valView.setInt16(bufPos, valInt, true);
24
- bufPos += 2;
25
- }
26
- }
27
- postMessage({ buf: msg.data.buf }, [msg.data.buf]);
28
- //self.close()
29
- };
30
- }
31
- writeFmtChunk(audioBuffer) {
32
- this.bw.writeUint16(WavFileFormat.PCM, true);
33
- let frameSize = WavWriter.DEFAULT_SAMPLE_SIZE_BYTES * audioBuffer.numberOfChannels; // fixed 16-bit for now
34
- this.bw.writeUint16(audioBuffer.numberOfChannels, true);
35
- this.bw.writeUint32(audioBuffer.sampleRate, true);
36
- // dwAvgBytesPerSec
37
- this.bw.writeUint32(frameSize * audioBuffer.sampleRate, true);
38
- this.bw.writeUint16(frameSize, true);
39
- // sample size in bits (PCM format only)
40
- this.bw.writeUint16(WavWriter.DEFAULT_SAMPLE_SIZE_BYTES * 8, true);
41
- }
42
- writeDataChunk(audioBuffer) {
43
- let chData0 = audioBuffer.getChannelData(0);
44
- let dataLen = chData0.length;
45
- let hDynIntRange = 1 << ((WavWriter.DEFAULT_SAMPLE_SIZE_BYTES * 8) - 1);
46
- for (let s = 0; s < dataLen; s++) {
47
- // interleaved channel data
48
- for (let ch = 0; ch < audioBuffer.numberOfChannels; ch++) {
49
- let chData = audioBuffer.getChannelData(ch);
50
- let valFlt = chData[s];
51
- let valInt = Math.round(valFlt * hDynIntRange);
52
- this.bw.writeInt16(valInt, true);
53
- }
54
- }
55
- }
56
- writeChunkHeader(name, chkLen) {
57
- this.bw.writeAscii(name);
58
- this.bw.writeUint32(chkLen, true);
59
- }
60
- writeAsync(audioBuffer, callback) {
61
- let dataChkByteLen = this.writeHeader(audioBuffer);
62
- if (!this.workerURL) {
63
- this.workerURL = WorkerHelper.buildWorkerBlobURL(this.workerFunction);
64
- }
65
- let wo = new Worker(this.workerURL);
66
- let chs = audioBuffer.numberOfChannels;
67
- let frameLength = audioBuffer.getChannelData(0).length;
68
- let ad = new Float32Array(chs * frameLength);
69
- for (let ch = 0; ch < chs; ch++) {
70
- ad.set(audioBuffer.getChannelData(ch), ch * frameLength);
71
- }
72
- // ensureCapacity blocks !!!
73
- this.bw.ensureCapacity(dataChkByteLen);
74
- wo.onmessage = (me) => {
75
- callback(me.data.buf);
76
- wo.terminate();
77
- };
78
- //TODO Fixed sample size of 16 bits
79
- wo.postMessage({ sampleSizeInBits: 16, chs: chs, frameLength: frameLength, audioData: ad, buf: this.bw.buf, bufPos: this.bw.pos }, [ad.buffer, this.bw.buf]);
80
- }
81
- write(audioBuffer) {
82
- this.writeHeader(audioBuffer);
83
- this.writeDataChunk(audioBuffer);
84
- return this.bw.finish();
85
- }
86
- writeHeader(audioBuffer) {
87
- this.bw.writeAscii(WavFileFormat.RIFF_KEY);
88
- let dataChkByteLen = 0;
89
- //const dataChkByteLen=audioBuffer.getChannelData(0).length*WavWriter.DEFAULT_SAMPLE_SIZE_BYTES*audioBuffer.numberOfChannels;
90
- const abChs = audioBuffer.numberOfChannels;
91
- if (abChs > 0) {
92
- const abCh0 = audioBuffer.getChannelData(0);
93
- dataChkByteLen = abCh0.length * WavWriter.DEFAULT_SAMPLE_SIZE_BYTES * abChs;
94
- }
95
- const wavChunkByteLen = (4 + 4) * 3 + 16 + dataChkByteLen;
96
- this.bw.writeUint32(wavChunkByteLen, true); // must be set to file length-8 later
97
- this.bw.writeAscii(WavFileFormat.WAV_KEY);
98
- this.writeChunkHeader('fmt ', 16);
99
- this.writeFmtChunk(audioBuffer);
100
- this.writeChunkHeader('data', dataChkByteLen);
101
- return dataChkByteLen;
102
- }
103
- }
104
- WavWriter.DEFAULT_SAMPLE_SIZE_BYTES = 2;
105
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoid2F2d3JpdGVyLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vLi4vcHJvamVjdHMvc3BlZWNocmVjb3JkZXJuZy9zcmMvbGliL2F1ZGlvL2ltcGwvd2F2d3JpdGVyLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxhQUFhLEVBQUUsTUFBTSxhQUFhLENBQUE7QUFDM0MsT0FBTyxFQUFFLGdCQUFnQixFQUFFLE1BQU0sdUJBQXVCLENBQUE7QUFDeEQsT0FBTyxFQUFDLFlBQVksRUFBQyxNQUFNLG1CQUFtQixDQUFDO0FBSTVDLE1BQU0sT0FBTyxTQUFTO0lBS3BCO1FBRFEsY0FBUyxHQUFjLElBQUksQ0FBQztRQUVsQyxJQUFJLENBQUMsRUFBRSxHQUFHLElBQUksZ0JBQWdCLEVBQUUsQ0FBQztJQUNuQyxDQUFDO0lBRUQ7O09BRUc7SUFDSCxjQUFjO1FBQ1osSUFBSSxDQUFDLFNBQVMsR0FBRyxVQUFVLEdBQWdCO1lBRXpDLE1BQU0sT0FBTyxHQUFHLElBQUksUUFBUSxDQUFDLEdBQUcsQ0FBQyxJQUFJLENBQUMsR0FBRyxFQUFDLEdBQUcsQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDLENBQUM7WUFFM0QsSUFBSSxNQUFNLEdBQUcsQ0FBQyxDQUFDO1lBQ2YsSUFBSSxZQUFZLEdBQUcsQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDLElBQUksQ0FBQyxnQkFBZ0IsR0FBRyxDQUFDLENBQUMsQ0FBQztZQUN4RCxLQUFLLElBQUksQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDLEdBQUcsR0FBRyxDQUFDLElBQUksQ0FBQyxXQUFXLEVBQUUsQ0FBQyxFQUFFLEVBQUU7Z0JBQzdDLDJCQUEyQjtnQkFFM0IsS0FBSyxJQUFJLEVBQUUsR0FBRyxDQUFDLEVBQUUsRUFBRSxHQUFHLEdBQUcsQ0FBQyxJQUFJLENBQUMsR0FBRyxFQUFFLEVBQUUsRUFBRSxFQUFFO29CQUN4QyxJQUFJLE1BQU0sR0FBQyxDQUFDLEVBQUUsR0FBQyxHQUFHLENBQUMsSUFBSSxDQUFDLFdBQVcsQ0FBQyxHQUFDLENBQUMsQ0FBQztvQkFDdkMsSUFBSSxNQUFNLEdBQUcsR0FBRyxDQUFDLElBQUksQ0FBQyxTQUFTLENBQUMsTUFBTSxDQUFDLENBQUM7b0JBQ3hDLElBQUksTUFBTSxHQUFHLElBQUksQ0FBQyxLQUFLLENBQUMsTUFBTSxHQUFHLFlBQVksQ0FBQyxDQUFDO29CQUMvQyxPQUFPLENBQUMsUUFBUSxDQUFDLE1BQU0sRUFBRSxNQUFNLEVBQUUsSUFBSSxDQUFDLENBQUM7b0JBQ3ZDLE1BQU0sSUFBRSxDQUFDLENBQUM7aUJBQ1g7YUFDRjtZQUNELFdBQVcsQ0FBQyxFQUFDLEdBQUcsRUFBQyxHQUFHLENBQUMsSUFBSSxDQUFDLEdBQUcsRUFBQyxFQUFFLENBQUMsR0FBRyxDQUFDLElBQUksQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDO1lBQ2hELGNBQWM7UUFDaEIsQ0FBQyxDQUFBO0lBQ0gsQ0FBQztJQUdELGFBQWEsQ0FBQyxXQUF1QjtRQUVuQyxJQUFJLENBQUMsRUFBRSxDQUFDLFdBQVcsQ0FBQyxhQUFhLENBQUMsR0FBRyxFQUFDLElBQUksQ0FBQyxDQUFDO1FBQzVDLElBQUksU0FBUyxHQUFDLFNBQVMsQ0FBQyx5QkFBeUIsR0FBQyxXQUFXLENBQUMsZ0JBQWdCLENBQUMsQ0FBQyx1QkFBdUI7UUFDdkcsSUFBSSxDQUFDLEVBQUUsQ0FBQyxXQUFXLENBQUMsV0FBVyxDQUFDLGdCQUFnQixFQUFDLElBQUksQ0FBQyxDQUFDO1FBQ3ZELElBQUksQ0FBQyxFQUFFLENBQUMsV0FBVyxDQUFDLFdBQVcsQ0FBQyxVQUFVLEVBQUMsSUFBSSxDQUFDLENBQUM7UUFDL0MsbUJBQW1CO1FBQ3JCLElBQUksQ0FBQyxFQUFFLENBQUMsV0FBVyxDQUFDLFNBQVMsR0FBQyxXQUFXLENBQUMsVUFBVSxFQUFDLElBQUksQ0FBQyxDQUFDO1FBQzNELElBQUksQ0FBQyxFQUFFLENBQUMsV0FBVyxDQUFDLFNBQVMsRUFBQyxJQUFJLENBQUMsQ0FBQztRQUNwQyx3Q0FBd0M7UUFDeEMsSUFBSSxDQUFDLEVBQUUsQ0FBQyxXQUFXLENBQUMsU0FBUyxDQUFDLHlCQUF5QixHQUFDLENBQUMsRUFBQyxJQUFJLENBQUMsQ0FBQztJQUNsRSxDQUFDO0lBRUQsY0FBYyxDQUFDLFdBQXVCO1FBRXBDLElBQUksT0FBTyxHQUFDLFdBQVcsQ0FBQyxjQUFjLENBQUMsQ0FBQyxDQUFDLENBQUM7UUFDMUMsSUFBSSxPQUFPLEdBQUMsT0FBTyxDQUFDLE1BQU0sQ0FBQztRQUMxQixJQUFJLFlBQVksR0FBQyxDQUFDLElBQUksQ0FBQyxDQUFDLFNBQVMsQ0FBQyx5QkFBeUIsR0FBQyxDQUFDLENBQUMsR0FBQyxDQUFDLENBQUMsQ0FBQztRQUNuRSxLQUFJLElBQUksQ0FBQyxHQUFDLENBQUMsRUFBQyxDQUFDLEdBQUMsT0FBTyxFQUFDLENBQUMsRUFBRSxFQUFFO1lBQ3pCLDJCQUEyQjtZQUMzQixLQUFLLElBQUksRUFBRSxHQUFHLENBQUMsRUFBRSxFQUFFLEdBQUcsV0FBVyxDQUFDLGdCQUFnQixFQUFFLEVBQUUsRUFBRSxFQUFFO2dCQUN4RCxJQUFJLE1BQU0sR0FBRyxXQUFXLENBQUMsY0FBYyxDQUFDLEVBQUUsQ0FBQyxDQUFDO2dCQUM1QyxJQUFJLE1BQU0sR0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDLENBQUM7Z0JBQ3JCLElBQUksTUFBTSxHQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsTUFBTSxHQUFDLFlBQVksQ0FBQyxDQUFDO2dCQUMzQyxJQUFJLENBQUMsRUFBRSxDQUFDLFVBQVUsQ0FBQyxNQUFNLEVBQUMsSUFBSSxDQUFDLENBQUM7YUFDakM7U0FDRjtJQUVILENBQUM7SUFFRCxnQkFBZ0IsQ0FBQyxJQUFXLEVBQUMsTUFBYTtRQUN4QyxJQUFJLENBQUMsRUFBRSxDQUFDLFVBQVUsQ0FBQyxJQUFJLENBQUMsQ0FBQztRQUN6QixJQUFJLENBQUMsRUFBRSxDQUFDLFdBQVcsQ0FBQyxNQUFNLEVBQUMsSUFBSSxDQUFDLENBQUM7SUFDbkMsQ0FBQztJQUVELFVBQVUsQ0FBQyxXQUF1QixFQUFDLFFBQXdDO1FBRXpFLElBQUksY0FBYyxHQUFDLElBQUksQ0FBQyxXQUFXLENBQUMsV0FBVyxDQUFDLENBQUM7UUFDakQsSUFBSSxDQUFDLElBQUksQ0FBQyxTQUFTLEVBQUU7WUFDbkIsSUFBSSxDQUFDLFNBQVMsR0FBRyxZQUFZLENBQUMsa0JBQWtCLENBQUMsSUFBSSxDQUFDLGNBQWMsQ0FBQyxDQUFBO1NBQ3JFO1FBQ0YsSUFBSSxFQUFFLEdBQUcsSUFBSSxNQUFNLENBQUMsSUFBSSxDQUFDLFNBQVMsQ0FBQyxDQUFDO1FBRXBDLElBQUksR0FBRyxHQUFHLFdBQVcsQ0FBQyxnQkFBZ0IsQ0FBQztRQUV2QyxJQUFJLFdBQVcsR0FBRyxXQUFXLENBQUMsY0FBYyxDQUFDLENBQUMsQ0FBQyxDQUFDLE1BQU0sQ0FBQztRQUN2RCxJQUFJLEVBQUUsR0FBRyxJQUFJLFlBQVksQ0FBQyxHQUFHLEdBQUcsV0FBVyxDQUFDLENBQUM7UUFDN0MsS0FBSyxJQUFJLEVBQUUsR0FBRyxDQUFDLEVBQUUsRUFBRSxHQUFHLEdBQUcsRUFBRSxFQUFFLEVBQUUsRUFBRTtZQUMvQixFQUFFLENBQUMsR0FBRyxDQUFDLFdBQVcsQ0FBQyxjQUFjLENBQUMsRUFBRSxDQUFDLEVBQUUsRUFBRSxHQUFHLFdBQVcsQ0FBQyxDQUFDO1NBQzFEO1FBQ0MsNEJBQTRCO1FBQzlCLElBQUksQ0FBQyxFQUFFLENBQUMsY0FBYyxDQUFDLGNBQWMsQ0FBQyxDQUFDO1FBQ3ZDLEVBQUUsQ0FBQyxTQUFTLEdBQUcsQ0FBQyxFQUFFLEVBQUUsRUFBRTtZQUNwQixRQUFRLENBQUMsRUFBRSxDQUFDLElBQUksQ0FBQyxHQUFHLENBQUMsQ0FBQztZQUN0QixFQUFFLENBQUMsU0FBUyxFQUFFLENBQUM7UUFDakIsQ0FBQyxDQUFBO1FBQ0QsbUNBQW1DO1FBQ25DLEVBQUUsQ0FBQyxXQUFXLENBQUMsRUFBQyxnQkFBZ0IsRUFBQyxFQUFFLEVBQUUsR0FBRyxFQUFFLEdBQUcsRUFBRSxXQUFXLEVBQUUsV0FBVyxFQUFFLFNBQVMsRUFBRSxFQUFFLEVBQUMsR0FBRyxFQUFDLElBQUksQ0FBQyxFQUFFLENBQUMsR0FBRyxFQUFDLE1BQU0sRUFBQyxJQUFJLENBQUMsRUFBRSxDQUFDLEdBQUcsRUFBQyxFQUFFLENBQUMsRUFBRSxDQUFDLE1BQU0sRUFBQyxJQUFJLENBQUMsRUFBRSxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUM7SUFFdkosQ0FBQztJQUVELEtBQUssQ0FBQyxXQUF1QjtRQUMzQixJQUFJLENBQUMsV0FBVyxDQUFDLFdBQVcsQ0FBQyxDQUFDO1FBQzlCLElBQUksQ0FBQyxjQUFjLENBQUMsV0FBVyxDQUFDLENBQUM7UUFDakMsT0FBTyxJQUFJLENBQUMsRUFBRSxDQUFDLE1BQU0sRUFBRSxDQUFDO0lBQzFCLENBQUM7SUFHQSxXQUFXLENBQUMsV0FBdUI7UUFDakMsSUFBSSxDQUFDLEVBQUUsQ0FBQyxVQUFVLENBQUMsYUFBYSxDQUFDLFFBQVEsQ0FBQyxDQUFDO1FBQzNDLElBQUksY0FBYyxHQUFDLENBQUMsQ0FBQztRQUNyQiw2SEFBNkg7UUFDN0gsTUFBTSxLQUFLLEdBQUMsV0FBVyxDQUFDLGdCQUFnQixDQUFDO1FBQ3pDLElBQUcsS0FBSyxHQUFDLENBQUMsRUFBQztZQUNULE1BQU0sS0FBSyxHQUFDLFdBQVcsQ0FBQyxjQUFjLENBQUMsQ0FBQyxDQUFDLENBQUM7WUFDMUMsY0FBYyxHQUFDLEtBQUssQ0FBQyxNQUFNLEdBQUMsU0FBUyxDQUFDLHlCQUF5QixHQUFDLEtBQUssQ0FBQztTQUN2RTtRQUNELE1BQU0sZUFBZSxHQUFDLENBQUMsQ0FBQyxHQUFDLENBQUMsQ0FBQyxHQUFDLENBQUMsR0FBQyxFQUFFLEdBQUMsY0FBYyxDQUFDO1FBQ2hELElBQUksQ0FBQyxFQUFFLENBQUMsV0FBVyxDQUFDLGVBQWUsRUFBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLHFDQUFxQztRQUNoRixJQUFJLENBQUMsRUFBRSxDQUFDLFVBQVUsQ0FBQyxhQUFhLENBQUMsT0FBTyxDQUFDLENBQUM7UUFDMUMsSUFBSSxDQUFDLGdCQUFnQixDQUFDLE1BQU0sRUFBQyxFQUFFLENBQUMsQ0FBQztRQUNqQyxJQUFJLENBQUMsYUFBYSxDQUFDLFdBQVcsQ0FBQyxDQUFDO1FBQ2hDLElBQUksQ0FBQyxnQkFBZ0IsQ0FBQyxNQUFNLEVBQUMsY0FBYyxDQUFDLENBQUM7UUFDN0MsT0FBTyxjQUFjLENBQUM7SUFDeEIsQ0FBQzs7QUF0SGMsbUNBQXlCLEdBQVUsQ0FBQyxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgV2F2RmlsZUZvcm1hdCB9IGZyb20gJy4vd2F2Zm9ybWF0J1xyXG5pbXBvcnQgeyBCaW5hcnlCeXRlV3JpdGVyIH0gZnJvbSAnLi4vLi4vaW8vQmluYXJ5V3JpdGVyJ1xyXG5pbXBvcnQge1dvcmtlckhlbHBlcn0gZnJvbSBcIi4uLy4uL3V0aWxzL3V0aWxzXCI7XHJcbmRlY2xhcmUgZnVuY3Rpb24gcG9zdE1lc3NhZ2UgKG1lc3NhZ2U6YW55LCB0cmFuc2ZlcjpBcnJheTxhbnk+KTp2b2lkO1xyXG5cclxuXHJcbiAgIGV4cG9ydCBjbGFzcyBXYXZXcml0ZXIge1xyXG5cclxuICAgICBzdGF0aWMgcmVhZG9ubHkgREVGQVVMVF9TQU1QTEVfU0laRV9CWVRFUzpudW1iZXIgPSAyO1xyXG4gICAgIHByaXZhdGUgYnc6QmluYXJ5Qnl0ZVdyaXRlcjtcclxuICAgICBwcml2YXRlIHdvcmtlclVSTDogc3RyaW5nfG51bGw9bnVsbDtcclxuICAgICBjb25zdHJ1Y3RvcigpIHtcclxuICAgICAgIHRoaXMuYncgPSBuZXcgQmluYXJ5Qnl0ZVdyaXRlcigpO1xyXG4gICAgIH1cclxuXHJcbiAgICAgLypcclxuICAgICAgKiAgTWV0aG9kIHVzZWQgYXMgd29ya2VyIGNvZGUuXHJcbiAgICAgICovXHJcbiAgICAgd29ya2VyRnVuY3Rpb24oKSB7XHJcbiAgICAgICBzZWxmLm9ubWVzc2FnZSA9IGZ1bmN0aW9uIChtc2c6TWVzc2FnZUV2ZW50KSB7XHJcblxyXG4gICAgICAgICBjb25zdCB2YWxWaWV3ID0gbmV3IERhdGFWaWV3KG1zZy5kYXRhLmJ1Zixtc2cuZGF0YS5idWZQb3MpO1xyXG5cclxuICAgICAgICAgbGV0IGJ1ZlBvcyA9IDA7XHJcbiAgICAgICAgIGxldCBoRHluSW50UmFuZ2UgPSAxIDw8IChtc2cuZGF0YS5zYW1wbGVTaXplSW5CaXRzIC0gMSk7XHJcbiAgICAgICAgIGZvciAobGV0IHMgPSAwOyBzIDwgbXNnLmRhdGEuZnJhbWVMZW5ndGg7IHMrKykge1xyXG4gICAgICAgICAgIC8vIGludGVybGVhdmVkIGNoYW5uZWwgZGF0YVxyXG5cclxuICAgICAgICAgICBmb3IgKGxldCBjaCA9IDA7IGNoIDwgbXNnLmRhdGEuY2hzOyBjaCsrKSB7XHJcbiAgICAgICAgICAgICBsZXQgc3JjUG9zPShjaCptc2cuZGF0YS5mcmFtZUxlbmd0aCkrcztcclxuICAgICAgICAgICAgIGxldCB2YWxGbHQgPSBtc2cuZGF0YS5hdWRpb0RhdGFbc3JjUG9zXTtcclxuICAgICAgICAgICAgIGxldCB2YWxJbnQgPSBNYXRoLnJvdW5kKHZhbEZsdCAqIGhEeW5JbnRSYW5nZSk7XHJcbiAgICAgICAgICAgICB2YWxWaWV3LnNldEludDE2KGJ1ZlBvcywgdmFsSW50LCB0cnVlKTtcclxuICAgICAgICAgICAgIGJ1ZlBvcys9MjtcclxuICAgICAgICAgICB9XHJcbiAgICAgICAgIH1cclxuICAgICAgICAgcG9zdE1lc3NhZ2Uoe2J1Zjptc2cuZGF0YS5idWZ9LCBbbXNnLmRhdGEuYnVmXSk7XHJcbiAgICAgICAgIC8vc2VsZi5jbG9zZSgpXHJcbiAgICAgICB9XHJcbiAgICAgfVxyXG5cclxuXHJcbiAgICAgd3JpdGVGbXRDaHVuayhhdWRpb0J1ZmZlcjpBdWRpb0J1ZmZlcil7XHJcblxyXG4gICAgICAgdGhpcy5idy53cml0ZVVpbnQxNihXYXZGaWxlRm9ybWF0LlBDTSx0cnVlKTtcclxuICAgICAgIGxldCBmcmFtZVNpemU9V2F2V3JpdGVyLkRFRkFVTFRfU0FNUExFX1NJWkVfQllURVMqYXVkaW9CdWZmZXIubnVtYmVyT2ZDaGFubmVsczsgLy8gZml4ZWQgMTYtYml0IGZvciBub3dcclxuICAgICAgIHRoaXMuYncud3JpdGVVaW50MTYoYXVkaW9CdWZmZXIubnVtYmVyT2ZDaGFubmVscyx0cnVlKTtcclxuICAgICAgIHRoaXMuYncud3JpdGVVaW50MzIoYXVkaW9CdWZmZXIuc2FtcGxlUmF0ZSx0cnVlKTtcclxuICAgICAgICAgLy8gZHdBdmdCeXRlc1BlclNlY1xyXG4gICAgICAgdGhpcy5idy53cml0ZVVpbnQzMihmcmFtZVNpemUqYXVkaW9CdWZmZXIuc2FtcGxlUmF0ZSx0cnVlKTtcclxuICAgICAgIHRoaXMuYncud3JpdGVVaW50MTYoZnJhbWVTaXplLHRydWUpO1xyXG4gICAgICAgLy8gc2FtcGxlIHNpemUgaW4gYml0cyAoUENNIGZvcm1hdCBvbmx5KVxyXG4gICAgICAgdGhpcy5idy53cml0ZVVpbnQxNihXYXZXcml0ZXIuREVGQVVMVF9TQU1QTEVfU0laRV9CWVRFUyo4LHRydWUpO1xyXG4gICAgIH1cclxuXHJcbiAgICAgd3JpdGVEYXRhQ2h1bmsoYXVkaW9CdWZmZXI6QXVkaW9CdWZmZXIpe1xyXG5cclxuICAgICAgIGxldCBjaERhdGEwPWF1ZGlvQnVmZmVyLmdldENoYW5uZWxEYXRhKDApO1xyXG4gICAgICAgbGV0IGRhdGFMZW49Y2hEYXRhMC5sZW5ndGg7XHJcbiAgICAgICAgbGV0IGhEeW5JbnRSYW5nZT0xIDw8ICgoV2F2V3JpdGVyLkRFRkFVTFRfU0FNUExFX1NJWkVfQllURVMqOCktMSk7XHJcbiAgICAgICBmb3IobGV0IHM9MDtzPGRhdGFMZW47cysrKSB7XHJcbiAgICAgICAgIC8vIGludGVybGVhdmVkIGNoYW5uZWwgZGF0YVxyXG4gICAgICAgICBmb3IgKGxldCBjaCA9IDA7IGNoIDwgYXVkaW9CdWZmZXIubnVtYmVyT2ZDaGFubmVsczsgY2grKykge1xyXG4gICAgICAgICAgIGxldCBjaERhdGEgPSBhdWRpb0J1ZmZlci5nZXRDaGFubmVsRGF0YShjaCk7XHJcbiAgICAgICAgICAgbGV0IHZhbEZsdD1jaERhdGFbc107XHJcbiAgICAgICAgICAgbGV0IHZhbEludD1NYXRoLnJvdW5kKHZhbEZsdCpoRHluSW50UmFuZ2UpO1xyXG4gICAgICAgICAgIHRoaXMuYncud3JpdGVJbnQxNih2YWxJbnQsdHJ1ZSk7XHJcbiAgICAgICAgIH1cclxuICAgICAgIH1cclxuXHJcbiAgICAgfVxyXG5cclxuICAgICB3cml0ZUNodW5rSGVhZGVyKG5hbWU6c3RyaW5nLGNoa0xlbjpudW1iZXIpe1xyXG4gICAgICAgdGhpcy5idy53cml0ZUFzY2lpKG5hbWUpO1xyXG4gICAgICAgdGhpcy5idy53cml0ZVVpbnQzMihjaGtMZW4sdHJ1ZSk7XHJcbiAgICAgfVxyXG5cclxuICAgICB3cml0ZUFzeW5jKGF1ZGlvQnVmZmVyOkF1ZGlvQnVmZmVyLGNhbGxiYWNrOiAod2F2RmlsZURhdGE6VWludDhBcnJheSk9PiBhbnkpe1xyXG5cclxuICAgICAgIGxldCBkYXRhQ2hrQnl0ZUxlbj10aGlzLndyaXRlSGVhZGVyKGF1ZGlvQnVmZmVyKTtcclxuICAgICAgIGlmICghdGhpcy53b3JrZXJVUkwpIHtcclxuICAgICAgICAgdGhpcy53b3JrZXJVUkwgPSBXb3JrZXJIZWxwZXIuYnVpbGRXb3JrZXJCbG9iVVJMKHRoaXMud29ya2VyRnVuY3Rpb24pXHJcbiAgICAgICAgfVxyXG4gICAgICAgbGV0IHdvID0gbmV3IFdvcmtlcih0aGlzLndvcmtlclVSTCk7XHJcblxyXG4gICAgICAgbGV0IGNocyA9IGF1ZGlvQnVmZmVyLm51bWJlck9mQ2hhbm5lbHM7XHJcblxyXG4gICAgICAgbGV0IGZyYW1lTGVuZ3RoID0gYXVkaW9CdWZmZXIuZ2V0Q2hhbm5lbERhdGEoMCkubGVuZ3RoO1xyXG4gICAgICAgbGV0IGFkID0gbmV3IEZsb2F0MzJBcnJheShjaHMgKiBmcmFtZUxlbmd0aCk7XHJcbiAgICAgICBmb3IgKGxldCBjaCA9IDA7IGNoIDwgY2hzOyBjaCsrKSB7XHJcbiAgICAgICAgIGFkLnNldChhdWRpb0J1ZmZlci5nZXRDaGFubmVsRGF0YShjaCksIGNoICogZnJhbWVMZW5ndGgpO1xyXG4gICAgICAgfVxyXG4gICAgICAgICAvLyBlbnN1cmVDYXBhY2l0eSBibG9ja3MgISEhXHJcbiAgICAgICB0aGlzLmJ3LmVuc3VyZUNhcGFjaXR5KGRhdGFDaGtCeXRlTGVuKTtcclxuICAgICAgIHdvLm9ubWVzc2FnZSA9IChtZSkgPT4ge1xyXG4gICAgICAgICBjYWxsYmFjayhtZS5kYXRhLmJ1Zik7XHJcbiAgICAgICAgIHdvLnRlcm1pbmF0ZSgpO1xyXG4gICAgICAgfVxyXG4gICAgICAgLy9UT0RPIEZpeGVkIHNhbXBsZSBzaXplIG9mIDE2IGJpdHNcclxuICAgICAgIHdvLnBvc3RNZXNzYWdlKHtzYW1wbGVTaXplSW5CaXRzOjE2LCBjaHM6IGNocywgZnJhbWVMZW5ndGg6IGZyYW1lTGVuZ3RoLCBhdWRpb0RhdGE6IGFkLGJ1Zjp0aGlzLmJ3LmJ1ZixidWZQb3M6dGhpcy5idy5wb3N9LCBbYWQuYnVmZmVyLHRoaXMuYncuYnVmXSk7XHJcblxyXG4gICAgIH1cclxuXHJcbiAgICAgd3JpdGUoYXVkaW9CdWZmZXI6QXVkaW9CdWZmZXIpOlVpbnQ4QXJyYXl7XHJcbiAgICAgICB0aGlzLndyaXRlSGVhZGVyKGF1ZGlvQnVmZmVyKTtcclxuICAgICAgIHRoaXMud3JpdGVEYXRhQ2h1bmsoYXVkaW9CdWZmZXIpO1xyXG4gICAgICAgcmV0dXJuIHRoaXMuYncuZmluaXNoKCk7XHJcbiAgICAgfVxyXG5cclxuXHJcbiAgICAgIHdyaXRlSGVhZGVyKGF1ZGlvQnVmZmVyOkF1ZGlvQnVmZmVyKTpudW1iZXJ7XHJcbiAgICAgICAgdGhpcy5idy53cml0ZUFzY2lpKFdhdkZpbGVGb3JtYXQuUklGRl9LRVkpO1xyXG4gICAgICAgIGxldCBkYXRhQ2hrQnl0ZUxlbj0wO1xyXG4gICAgICAgIC8vY29uc3QgZGF0YUNoa0J5dGVMZW49YXVkaW9CdWZmZXIuZ2V0Q2hhbm5lbERhdGEoMCkubGVuZ3RoKldhdldyaXRlci5ERUZBVUxUX1NBTVBMRV9TSVpFX0JZVEVTKmF1ZGlvQnVmZmVyLm51bWJlck9mQ2hhbm5lbHM7XHJcbiAgICAgICAgY29uc3QgYWJDaHM9YXVkaW9CdWZmZXIubnVtYmVyT2ZDaGFubmVscztcclxuICAgICAgICBpZihhYkNocz4wKXtcclxuICAgICAgICAgIGNvbnN0IGFiQ2gwPWF1ZGlvQnVmZmVyLmdldENoYW5uZWxEYXRhKDApO1xyXG4gICAgICAgICAgZGF0YUNoa0J5dGVMZW49YWJDaDAubGVuZ3RoKldhdldyaXRlci5ERUZBVUxUX1NBTVBMRV9TSVpFX0JZVEVTKmFiQ2hzO1xyXG4gICAgICAgIH1cclxuICAgICAgICBjb25zdCB3YXZDaHVua0J5dGVMZW49KDQrNCkqMysxNitkYXRhQ2hrQnl0ZUxlbjtcclxuICAgICAgICB0aGlzLmJ3LndyaXRlVWludDMyKHdhdkNodW5rQnl0ZUxlbix0cnVlKTsgLy8gbXVzdCBiZSBzZXQgdG8gZmlsZSBsZW5ndGgtOCBsYXRlclxyXG4gICAgICAgIHRoaXMuYncud3JpdGVBc2NpaShXYXZGaWxlRm9ybWF0LldBVl9LRVkpO1xyXG4gICAgICAgIHRoaXMud3JpdGVDaHVua0hlYWRlcignZm10ICcsMTYpO1xyXG4gICAgICAgIHRoaXMud3JpdGVGbXRDaHVuayhhdWRpb0J1ZmZlcik7XHJcbiAgICAgICAgdGhpcy53cml0ZUNodW5rSGVhZGVyKCdkYXRhJyxkYXRhQ2hrQnl0ZUxlbik7XHJcbiAgICAgICAgcmV0dXJuIGRhdGFDaGtCeXRlTGVuO1xyXG4gICAgICB9XHJcblxyXG4gICB9XHJcblxyXG5cclxuXHJcbiJdfQ==