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
@@ -0,0 +1,402 @@
1
+ import { Action } from '../../action/action';
2
+ import { ArrayAudioBuffer } from "../array_audio_buffer";
3
+ import { ArrayAudioBufferSourceNode } from "./array_audio_buffer_source_node";
4
+ import { IndexedDbAudioBuffer } from "../inddb_audio_buffer";
5
+ import { AudioSourceWorkletModuleLoader } from "./audio_source_worklet_module_loader";
6
+ import { IndexedDbAudioBufferSourceNode } from "./inddb_audio_buffer_source_node";
7
+ import { NetAudioBuffer } from "../net_audio_buffer";
8
+ import { NetAudioBufferSourceNode } from "./net_audio_buffer_source_node";
9
+ import { AudioBufferSource } from "../audio_data_holder";
10
+ import { AudioContextProvider } from "../context";
11
+ export var EventType;
12
+ (function (EventType) {
13
+ EventType[EventType["CLOSED"] = 0] = "CLOSED";
14
+ EventType[EventType["READY"] = 1] = "READY";
15
+ EventType[EventType["STARTED"] = 2] = "STARTED";
16
+ EventType[EventType["POS_UPDATE"] = 3] = "POS_UPDATE";
17
+ EventType[EventType["STOPPED"] = 4] = "STOPPED";
18
+ EventType[EventType["ENDED"] = 5] = "ENDED";
19
+ EventType[EventType["ERROR"] = 6] = "ERROR";
20
+ })(EventType || (EventType = {}));
21
+ export class AudioPlayerEvent {
22
+ constructor(type, timePosition) {
23
+ this._type = type;
24
+ this._timePosition = timePosition;
25
+ }
26
+ get type() {
27
+ return this._type;
28
+ }
29
+ get timePosition() {
30
+ return this._timePosition;
31
+ }
32
+ }
33
+ export class AudioPlayer {
34
+ get autoPlayOnSelectToggleAction() {
35
+ return this._autoPlayOnSelectToggleAction;
36
+ }
37
+ static { this.DEFAULT_BUFSIZE = 8192; }
38
+ constructor(listener) {
39
+ this.running = false;
40
+ this.context = null;
41
+ this.ready = false;
42
+ this._audioClip = null;
43
+ this._audioSource = null;
44
+ this.sourceBufferNode = null;
45
+ this.sourceAudioWorkletNode = null;
46
+ this.playStartTime = null;
47
+ this.timerVar = null;
48
+ this.listener = listener;
49
+ this.bufSize = AudioPlayer.DEFAULT_BUFSIZE;
50
+ this.n = navigator;
51
+ this.buffPos = 0;
52
+ this.zeroBufCnt = 0;
53
+ this.zb = new Float32Array(this.bufSize);
54
+ this._startAction = new Action('Start');
55
+ this._startAction.disabled = true;
56
+ this._startAction.onAction = () => this.start();
57
+ this._startSelectionAction = new Action('Start selected');
58
+ this._startSelectionAction.disabled = true;
59
+ this._startSelectionAction.onAction = () => this.startSelected();
60
+ this._autoPlayOnSelectToggleAction = new Action("Autoplay on select", false);
61
+ this._stopAction = new Action('Stop');
62
+ this._stopAction.disabled = true;
63
+ this._stopAction.onAction = () => this.stop();
64
+ }
65
+ _audioContext() {
66
+ if (!this.context) {
67
+ this.context = AudioContextProvider.audioContextInstance();
68
+ if (this.context) {
69
+ this.context.addEventListener('statechange', (ev) => {
70
+ if (this.context && this.context.state !== 'running') {
71
+ this.stop();
72
+ }
73
+ });
74
+ }
75
+ }
76
+ return this.context;
77
+ }
78
+ get startAction() {
79
+ return this._startAction;
80
+ }
81
+ get startSelectionAction() {
82
+ return this._startSelectionAction;
83
+ }
84
+ get stopAction() {
85
+ return this._stopAction;
86
+ }
87
+ set audioClip(audioClip) {
88
+ this._audioClip = audioClip;
89
+ let length = 0;
90
+ let chs = 0;
91
+ if (audioClip && audioClip.audioDataHolder) {
92
+ let audioDataHolder = audioClip.audioDataHolder;
93
+ chs = audioDataHolder.numberOfChannels;
94
+ if (chs > 0) {
95
+ length = audioDataHolder.frameLen;
96
+ //if (chs > this.context.destination.maxChannelCount) {
97
+ // // TODO exception
98
+ //}
99
+ }
100
+ this.audioSource = audioDataHolder.audioSource;
101
+ audioClip.addSelectionObserver((ac) => {
102
+ this._startSelectionAction.disabled = this.startSelectionDisabled();
103
+ if (!this.startSelectionAction.disabled && this._autoPlayOnSelectToggleAction.value) {
104
+ this.startSelected();
105
+ }
106
+ });
107
+ }
108
+ else {
109
+ this.audioSource = null;
110
+ }
111
+ }
112
+ get audioSource() {
113
+ return this._audioSource;
114
+ }
115
+ set audioSource(value) {
116
+ this.stop();
117
+ this._audioSource = value;
118
+ if (this._audioSource) {
119
+ this.ready = true;
120
+ this.updateStartActions();
121
+ if (this.listener) {
122
+ this.listener.audioPlayerUpdate(new AudioPlayerEvent(EventType.READY));
123
+ }
124
+ }
125
+ else {
126
+ this.ready = false;
127
+ this.updateStartActions();
128
+ if (this.listener) {
129
+ this.listener.audioPlayerUpdate(new AudioPlayerEvent(EventType.CLOSED));
130
+ }
131
+ }
132
+ }
133
+ _loadSourceWorkletAndInitStart() {
134
+ if (this.context) {
135
+ AudioSourceWorkletModuleLoader.loadModule(this.context).then(() => {
136
+ //console.debug("Player ready. ( by Player::_loadSourceWorkletAndInitStart()");
137
+ this.ready = true;
138
+ this.updateStartActions();
139
+ if (this.listener) {
140
+ this.listener.audioPlayerUpdate(new AudioPlayerEvent(EventType.READY));
141
+ }
142
+ }).catch((error) => {
143
+ this.ready = false;
144
+ this.updateStartActions();
145
+ if (this.listener) {
146
+ this.listener.audioPlayerUpdate(new AudioPlayerEvent(EventType.CLOSED));
147
+ }
148
+ console.error('Could not add module ' + error);
149
+ });
150
+ }
151
+ }
152
+ _startAudioSourceWorkletNode() {
153
+ this._loadSourceWorkletAndInitStart();
154
+ if (this.context && this.sourceAudioWorkletNode) {
155
+ this.sourceAudioWorkletNode.onprocessorerror = (ev) => {
156
+ let msg = 'Unknwon error';
157
+ if (ev instanceof ErrorEvent) {
158
+ msg = ev.message;
159
+ }
160
+ console.error("Audio source worklet error: " + msg);
161
+ if (this.listener) {
162
+ // TODO
163
+ // this.listener.error(msg);
164
+ // this.listener.audioPlayerUpdate(new AudioPlayerEvent());
165
+ }
166
+ };
167
+ this.sourceAudioWorkletNode.connect(this.context.destination); // this already starts playing
168
+ this.sourceAudioWorkletNode.onended = () => this.onended();
169
+ this.running = true;
170
+ this.sourceAudioWorkletNode.start();
171
+ //console.debug("Playback start action enabled. ( by Player::_startAudioSourceWorkletNode()");
172
+ this._startAction.disabled = true;
173
+ this._startSelectionAction.disabled = true;
174
+ this._stopAction.disabled = false;
175
+ if (this.listener) {
176
+ this.listener.audioPlayerUpdate(new AudioPlayerEvent(EventType.STARTED));
177
+ }
178
+ }
179
+ }
180
+ start() {
181
+ this._audioContext();
182
+ if (this.context) {
183
+ if (!this._startAction.disabled && !this.running) {
184
+ if (this.context.state === 'suspended') {
185
+ this.context.resume().then(() => {
186
+ this._start();
187
+ }).catch((reason) => {
188
+ console.error(reason.message());
189
+ throw reason;
190
+ });
191
+ }
192
+ else if (this.context.state === 'closed') {
193
+ const msg = 'Error: Cannot start playback. Audio context is already closed!';
194
+ console.error(msg);
195
+ throw new Error(msg);
196
+ }
197
+ else {
198
+ this._start();
199
+ }
200
+ }
201
+ }
202
+ }
203
+ updateStartActions() {
204
+ if (this.ready) {
205
+ if (this._audioSource instanceof AudioBufferSource || this._audioSource instanceof ArrayAudioBuffer || this._audioSource instanceof IndexedDbAudioBuffer) {
206
+ this._startAction.disabled = false;
207
+ this._startSelectionAction.disabled = this.startSelectionDisabled();
208
+ }
209
+ else {
210
+ if (this._audioSource instanceof NetAudioBuffer) {
211
+ this._audioSource.addOnReadyListener(() => {
212
+ this._startAction.disabled = false;
213
+ this._startSelectionAction.disabled = this.startSelectionDisabled();
214
+ });
215
+ }
216
+ }
217
+ }
218
+ else {
219
+ this._startAction.disabled = true;
220
+ this._startSelectionAction.disabled = true;
221
+ }
222
+ }
223
+ startSelectionDisabled() {
224
+ return !(this._audioClip && !this.startAction.disabled && this._audioClip.selection);
225
+ }
226
+ _start(playSelection = false) {
227
+ if (!this.context) {
228
+ throw new Error("Could not get audio context!");
229
+ }
230
+ if (this._audioSource instanceof AudioBufferSource) {
231
+ this.sourceBufferNode = this.context.createBufferSource();
232
+ this.sourceBufferNode.buffer = this._audioSource.audioBuffer;
233
+ this.sourceBufferNode.connect(this.context.destination);
234
+ this.sourceBufferNode.onended = () => this.onended();
235
+ this.playStartTime = this.context.currentTime;
236
+ this.running = true;
237
+ // unfortunately Web Audio API uses time values not frames
238
+ const ac = this._audioClip;
239
+ let offset = 0;
240
+ if (playSelection && ac && ac.selection) {
241
+ const s = ac.selection;
242
+ const sr = ac.audioDataHolder.sampleRate;
243
+ offset = s.leftFrame / sr;
244
+ const stopPosInsecs = s.rightFrame / sr;
245
+ const dur = stopPosInsecs - offset;
246
+ this.sourceBufferNode.start(0, offset, dur);
247
+ }
248
+ else {
249
+ this.sourceBufferNode.start();
250
+ }
251
+ this.playStartTime = this.context.currentTime - offset;
252
+ this._startAction.disabled = true;
253
+ this._startSelectionAction.disabled = true;
254
+ this._stopAction.disabled = false;
255
+ if (this.listener) {
256
+ this.listener.audioPlayerUpdate(new AudioPlayerEvent(EventType.STARTED));
257
+ }
258
+ }
259
+ else if (this._audioSource instanceof ArrayAudioBuffer || this._audioSource instanceof IndexedDbAudioBuffer || this._audioSource instanceof NetAudioBuffer) {
260
+ AudioSourceWorkletModuleLoader.loadModule(this.context).then(() => {
261
+ this.playStartTime = null;
262
+ if (this.context) {
263
+ if (this._audioSource instanceof ArrayAudioBuffer) {
264
+ const aabsn = new ArrayAudioBufferSourceNode(this.context);
265
+ aabsn.arrayAudioBuffer = this._audioSource;
266
+ this.sourceAudioWorkletNode = aabsn;
267
+ }
268
+ else if (this._audioSource instanceof IndexedDbAudioBuffer) {
269
+ const iasn = new IndexedDbAudioBufferSourceNode(this.context);
270
+ iasn.inddbAudioBuffer = this._audioSource;
271
+ this.sourceAudioWorkletNode = iasn;
272
+ }
273
+ else if (this._audioSource instanceof NetAudioBuffer) {
274
+ const nabsn = new NetAudioBufferSourceNode(this.context);
275
+ nabsn.netAudioBuffer = this._audioSource;
276
+ this.sourceAudioWorkletNode = nabsn;
277
+ }
278
+ if (this.sourceAudioWorkletNode) {
279
+ this.sourceAudioWorkletNode.onprocessorerror = (ev) => {
280
+ let msg = 'Unknwon error';
281
+ if (ev instanceof ErrorEvent) {
282
+ msg = ev.message;
283
+ }
284
+ console.error("Audio source worklet error: " + msg);
285
+ if (this.listener) {
286
+ this.listener.audioPlayerUpdate(new AudioPlayerEvent(EventType.ERROR));
287
+ }
288
+ };
289
+ this.sourceAudioWorkletNode.connect(this.context.destination); // this already starts playing
290
+ this.sourceAudioWorkletNode.onended = () => this.onended();
291
+ this.running = true;
292
+ const ac = this._audioClip;
293
+ let offset = 0;
294
+ if (playSelection && ac && ac.selection) {
295
+ const s = ac.selection;
296
+ const sr = ac.audioDataHolder.sampleRate;
297
+ offset = s.leftFrame / sr;
298
+ const stopPosInsecs = s.rightFrame / sr;
299
+ const dur = stopPosInsecs - offset;
300
+ this.sourceAudioWorkletNode.start(0, offset, dur);
301
+ }
302
+ else {
303
+ this.sourceAudioWorkletNode.start();
304
+ }
305
+ //this.playStartTime = this.context.currentTime - offset;
306
+ this._startAction.disabled = true;
307
+ this._startSelectionAction.disabled = true;
308
+ this._stopAction.disabled = false;
309
+ if (this.listener) {
310
+ this.listener.audioPlayerUpdate(new AudioPlayerEvent(EventType.STARTED));
311
+ }
312
+ }
313
+ }
314
+ }).catch((error) => {
315
+ console.error(error.message);
316
+ this.ready = false;
317
+ this.updateStartActions();
318
+ if (this.listener) {
319
+ this.listener.audioPlayerUpdate(new AudioPlayerEvent(EventType.CLOSED));
320
+ }
321
+ throw error;
322
+ });
323
+ }
324
+ }
325
+ startSelected() {
326
+ this._audioContext();
327
+ if (!this.context) {
328
+ throw new Error("Could not get audio context!");
329
+ }
330
+ if (!this._startAction.disabled && !this.running) {
331
+ if (this.context.state === 'suspended') {
332
+ this.context.resume().then(() => {
333
+ this._start(true);
334
+ }).catch((reason) => {
335
+ console.error(reason.message);
336
+ throw reason;
337
+ });
338
+ }
339
+ else if (this.context.state === 'closed') {
340
+ const msg = 'Error: Cannot start playback of selection. Audio context is already closed!';
341
+ console.error(msg);
342
+ throw new Error(msg);
343
+ }
344
+ else {
345
+ this._start(true);
346
+ }
347
+ }
348
+ }
349
+ stop() {
350
+ if (this.running) {
351
+ if (this.sourceBufferNode) {
352
+ this.sourceBufferNode.stop();
353
+ }
354
+ if (this.sourceAudioWorkletNode) {
355
+ this.sourceAudioWorkletNode.stop();
356
+ }
357
+ if (this.timerVar !== null) {
358
+ window.clearInterval(this.timerVar);
359
+ }
360
+ this.running = false;
361
+ if (this.listener) {
362
+ this.listener.audioPlayerUpdate(new AudioPlayerEvent(EventType.STOPPED));
363
+ }
364
+ }
365
+ }
366
+ onended() {
367
+ if (this.timerVar != null) {
368
+ window.clearInterval(this.timerVar);
369
+ }
370
+ this._startAction.disabled = !this._audioSource;
371
+ this._startSelectionAction.disabled = this.startSelectionDisabled();
372
+ this._stopAction.disabled = true;
373
+ this.running = false;
374
+ if (this.listener) {
375
+ this.listener.audioPlayerUpdate(new AudioPlayerEvent(EventType.ENDED));
376
+ }
377
+ }
378
+ get playPositionTime() {
379
+ let ppt = null;
380
+ if (this.context && this.playStartTime !== null) {
381
+ ppt = this.context.currentTime - this.playStartTime;
382
+ }
383
+ else if (this.sourceAudioWorkletNode) {
384
+ ppt = this.sourceAudioWorkletNode.playPositionTime;
385
+ }
386
+ return ppt;
387
+ }
388
+ get playPositionFrames() {
389
+ let ppFrs = null;
390
+ if (this._audioSource) {
391
+ let sr = this._audioSource.sampleRate;
392
+ if (sr) {
393
+ let ppTime = this.playPositionTime;
394
+ if (ppTime !== null) {
395
+ ppFrs = sr * ppTime;
396
+ }
397
+ }
398
+ }
399
+ return ppFrs;
400
+ }
401
+ }
402
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicGxheWVyLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vLi4vcHJvamVjdHMvc3BlZWNocmVjb3JkZXJuZy9zcmMvbGliL2F1ZGlvL3BsYXliYWNrL3BsYXllci50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsTUFBTSxFQUFFLE1BQU0scUJBQXFCLENBQUE7QUFFNUMsT0FBTyxFQUFDLGdCQUFnQixFQUFDLE1BQU0sdUJBQXVCLENBQUM7QUFDdkQsT0FBTyxFQUFDLDBCQUEwQixFQUFDLE1BQU0sa0NBQWtDLENBQUM7QUFDNUUsT0FBTyxFQUFDLG9CQUFvQixFQUFDLE1BQU0sdUJBQXVCLENBQUM7QUFDM0QsT0FBTyxFQUFDLDhCQUE4QixFQUFDLE1BQU0sc0NBQXNDLENBQUM7QUFDcEYsT0FBTyxFQUFDLDhCQUE4QixFQUFDLE1BQU0sa0NBQWtDLENBQUM7QUFFaEYsT0FBTyxFQUFDLGNBQWMsRUFBQyxNQUFNLHFCQUFxQixDQUFDO0FBQ25ELE9BQU8sRUFBQyx3QkFBd0IsRUFBQyxNQUFNLGdDQUFnQyxDQUFDO0FBQ3hFLE9BQU8sRUFBQyxpQkFBaUIsRUFBYyxNQUFNLHNCQUFzQixDQUFDO0FBQ3BFLE9BQU8sRUFBQyxvQkFBb0IsRUFBQyxNQUFNLFlBQVksQ0FBQztBQUk1QyxNQUFNLENBQU4sSUFBYSxTQUFpRTtBQUE5RSxXQUFhLFNBQVM7SUFBRSw2Q0FBTSxDQUFBO0lBQUMsMkNBQUssQ0FBQTtJQUFDLCtDQUFPLENBQUE7SUFBQyxxREFBVSxDQUFBO0lBQUUsK0NBQU8sQ0FBQTtJQUFFLDJDQUFLLENBQUE7SUFBQywyQ0FBSyxDQUFBO0FBQUEsQ0FBQyxFQUFqRSxTQUFTLEtBQVQsU0FBUyxRQUF3RDtBQUU5RSxNQUFNLE9BQU8sZ0JBQWdCO0lBS3pCLFlBQVksSUFBYyxFQUFFLFlBQW9CO1FBQzVDLElBQUksQ0FBQyxLQUFLLEdBQUcsSUFBSSxDQUFDO1FBQ2xCLElBQUksQ0FBQyxh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XHJcbmltcG9ydCB7IEF1ZGlvQ2xpcCB9IGZyb20gJy4uL3BlcnNpc3RvcidcclxuaW1wb3J0IHtBcnJheUF1ZGlvQnVmZmVyfSBmcm9tIFwiLi4vYXJyYXlfYXVkaW9fYnVmZmVyXCI7XHJcbmltcG9ydCB7QXJyYXlBdWRpb0J1ZmZlclNvdXJjZU5vZGV9IGZyb20gXCIuL2FycmF5X2F1ZGlvX2J1ZmZlcl9zb3VyY2Vfbm9kZVwiO1xyXG5pbXBvcnQge0luZGV4ZWREYkF1ZGlvQnVmZmVyfSBmcm9tIFwiLi4vaW5kZGJfYXVkaW9fYnVmZmVyXCI7XHJcbmltcG9ydCB7QXVkaW9Tb3VyY2VXb3JrbGV0TW9kdWxlTG9hZGVyfSBmcm9tIFwiLi9hdWRpb19zb3VyY2Vfd29ya2xldF9tb2R1bGVfbG9hZGVyXCI7XHJcbmltcG9ydCB7SW5kZXhlZERiQXVkaW9CdWZmZXJTb3VyY2VOb2RlfSBmcm9tIFwiLi9pbmRkYl9hdWRpb19idWZmZXJfc291cmNlX25vZGVcIjtcclxuaW1wb3J0IHtBdWRpb1NvdXJjZU5vZGV9IGZyb20gXCIuL2F1ZGlvX3NvdXJjZV9ub2RlXCI7XHJcbmltcG9ydCB7TmV0QXVkaW9CdWZmZXJ9IGZyb20gXCIuLi9uZXRfYXVkaW9fYnVmZmVyXCI7XHJcbmltcG9ydCB7TmV0QXVkaW9CdWZmZXJTb3VyY2VOb2RlfSBmcm9tIFwiLi9uZXRfYXVkaW9fYnVmZmVyX3NvdXJjZV9ub2RlXCI7XHJcbmltcG9ydCB7QXVkaW9CdWZmZXJTb3VyY2UsIEF1ZGlvU291cmNlfSBmcm9tIFwiLi4vYXVkaW9fZGF0YV9ob2xkZXJcIjtcclxuaW1wb3J0IHtBdWRpb0NvbnRleHRQcm92aWRlcn0gZnJvbSBcIi4uL2NvbnRleHRcIjtcclxuXHJcblxyXG5cclxuICAgIGV4cG9ydCBlbnVtICBFdmVudFR5cGUge0NMT1NFRCxSRUFEWSxTVEFSVEVELFBPU19VUERBVEUsIFNUT1BQRUQsIEVOREVELEVSUk9SfVxyXG5cclxuICAgIGV4cG9ydCBjbGFzcyBBdWRpb1BsYXllckV2ZW50e1xyXG5cclxuICAgICAgICBwcml2YXRlIHJlYWRvbmx5IF90eXBlOkV2ZW50VHlwZTtcclxuICAgICAgICBwcml2YXRlIHJlYWRvbmx5IF90aW1lUG9zaXRpb246bnVtYmVyIHwgdW5kZWZpbmVkO1xyXG5cclxuICAgICAgICBjb25zdHJ1Y3Rvcih0eXBlOkV2ZW50VHlwZSwgdGltZVBvc2l0aW9uPzpudW1iZXIpIHtcclxuICAgICAgICAgICAgdGhpcy5fdHlwZSA9IHR5cGU7XHJcbiAgICAgICAgICAgIHRoaXMuX3RpbWVQb3NpdGlvbiA9IHRpbWVQb3NpdGlvbjtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIGdldCB0eXBlKCkge1xyXG4gICAgICAgICAgICByZXR1cm4gdGhpcy5fdHlwZTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIGdldCB0aW1lUG9zaXRpb24oKSB7XHJcbiAgICAgICAgICAgIHJldHVybiB0aGlzLl90aW1lUG9zaXRpb247XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG4gICAgZXhwb3J0IGludGVyZmFjZSBBdWRpb1BsYXllckxpc3RlbmVyIHtcclxuICAgICAgICBhdWRpb1BsYXllclVwZGF0ZShlOkF1ZGlvUGxheWVyRXZlbnQpOnZvaWQ7XHJcbiAgICB9XHJcblxyXG4gICAgZXhwb3J0IGNsYXNzIEF1ZGlvUGxheWVyIHtcclxuXHJcbiAgICAgICAgZ2V0IGF1dG9QbGF5T25TZWxlY3RUb2dnbGVBY3Rpb24oKTogQWN0aW9uPGJvb2xlYW4+IHtcclxuICAgICAgICAgICAgcmV0dXJuIHRoaXMuX2F1dG9QbGF5T25TZWxlY3RUb2dnbGVBY3Rpb247XHJcbiAgICAgICAgfVxyXG4gICAgICAgIHB1YmxpYyBzdGF0aWMgREVGQVVMVF9CVUZTSVpFOm51bWJlciA9IDgxOTI7XHJcbiAgICAgICAgcHJpdmF0ZSBydW5uaW5nPWZhbHNlO1xyXG4gICAgICAgIHByaXZhdGUgcmVhZG9ubHkgX3N0YXJ0QWN0aW9uOkFjdGlvbjx2b2lkPjtcclxuICAgICAgICBwcml2YXRlIHJlYWRvbmx5IF9zdGFydFNlbGVjdGlvbkFjdGlvbjpBY3Rpb248dm9pZD47XHJcbiAgICAgICAgcHJpdmF0ZSByZWFkb25seSBfYXV0b1BsYXlPblNlbGVjdFRvZ2dsZUFjdGlvbjpBY3Rpb248Ym9vbGVhbj47XHJcbiAgICAgICAgcHJpdmF0ZSByZWFkb25seSBfc3RvcEFjdGlvbjpBY3Rpb248dm9pZD47XHJcbiAgICAgICAgYnVmU2l6ZTpudW1iZXI7XHJcbiAgICAgICAgY29udGV4dDpBdWRpb0NvbnRleHR8bnVsbD1udWxsO1xyXG4gICAgICAgIHJlYWR5PWZhbHNlO1xyXG4gICAgICAgIGxpc3RlbmVyOkF1ZGlvUGxheWVyTGlzdGVuZXI7XHJcbiAgICAgICAgX2F1ZGlvQ2xpcDpBdWRpb0NsaXB8bnVsbD1udWxsO1xyXG4gICAgICAgIHByaXZhdGUgX2F1ZGlvU291cmNlOkF1ZGlvU291cmNlfG51bGw9bnVsbDtcclxuICAgICAgICBzb3VyY2VCdWZmZXJOb2RlOkF1ZGlvQnVmZmVyU291cmNlTm9kZXxudWxsPW51bGw7XHJcbiAgICAgICAgc291cmNlQXVkaW9Xb3JrbGV0Tm9kZTpBdWRpb1NvdXJjZU5vZGV8bnVsbD1udWxsO1xyXG5cclxuICAgICAgICBidWZmUG9zOm51bWJlcjtcclxuICAgICAgICBwcml2YXRlIHplcm9CdWZDbnQ6bnVtYmVyO1xyXG4gICAgICAgIG46YW55O1xyXG4gICAgICAgIHpiOkZsb2F0MzJBcnJheTtcclxuICAgICAgICBwcml2YXRlIHBsYXlTdGFydFRpbWU6bnVtYmVyfG51bGw9bnVsbDtcclxuXHJcbiAgICAgICAgcHJpdmF0ZSB0aW1lclZhcjpudW1iZXJ8bnVsbD1udWxsO1xyXG5cclxuICAgICAgICBjb25zdHJ1Y3RvcihsaXN0ZW5lcjpBdWRpb1BsYXllckxpc3RlbmVyKSB7XHJcbiAgICAgICAgICAgIHRoaXMubGlzdGVuZXI9bGlzdGVuZXI7XHJcbiAgICAgICAgICAgIHRoaXMuYnVmU2l6ZSA9IEF1ZGlvUGxheWVyLkRFRkFVTFRfQlVGU0laRTtcclxuICAgICAgICAgICAgdGhpcy5uPW5hdmlnYXRvcjtcclxuICAgICAgICAgICAgdGhpcy5idWZmUG9zPTA7XHJcbiAgICAgICAgICAgIHRoaXMuemVyb0J1ZkNudD0wO1xyXG4gICAgICAgICAgICB0aGlzLnpiID0gbmV3IEZsb2F0MzJBcnJheSh0aGlzLmJ1ZlNpemUpO1xyXG4gICAgICAgICAgICB0aGlzLl9zdGFydEFjdGlvbiA9IG5ldyBBY3Rpb24oJ1N0YXJ0Jyk7XHJcbiAgICAgICAgICAgIHRoaXMuX3N0YXJ0QWN0aW9uLmRpc2FibGVkID0gdHJ1ZTtcclxuICAgICAgICAgICAgdGhpcy5fc3RhcnRBY3Rpb24ub25BY3Rpb24gPSAoKT0+dGhpcy5zdGFydCgpO1xyXG4gICAgICAgICAgICB0aGlzLl9zdGFydFNlbGVjdGlvbkFjdGlvbj1uZXcgQWN0aW9uKCdTdGFydCBzZWxlY3RlZCcpXHJcbiAgICAgICAgICAgIHRoaXMuX3N0YXJ0U2VsZWN0aW9uQWN0aW9uLmRpc2FibGVkPXRydWVcclxuICAgICAgICAgICAgdGhpcy5fc3RhcnRTZWxlY3Rpb25BY3Rpb24ub25BY3Rpb24gPSAoKT0+dGhpcy5zdGFydFNlbGVjdGVkKCk7XHJcbiAgICAgICAgICAgIHRoaXMuX2F1dG9QbGF5T25TZWxlY3RUb2dnbGVBY3Rpb249bmV3IEFjdGlvbjxib29sZWFuPihcIkF1dG9wbGF5IG9uIHNlbGVjdFwiLGZhbHNlKTtcclxuICAgICAgICAgICAgdGhpcy5fc3RvcEFjdGlvbiA9IG5ldyBBY3Rpb24oJ1N0b3AnKTtcclxuICAgICAgICAgICAgdGhpcy5fc3RvcEFjdGlvbi5kaXNhYmxlZCA9IHRydWU7XHJcbiAgICAgICAgICAgIHRoaXMuX3N0b3BBY3Rpb24ub25BY3Rpb24gPSAoKT0+dGhpcy5zdG9wKCk7XHJcblxyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgcHJpdmF0ZSBfYXVkaW9Db250ZXh0KCk6QXVkaW9Db250ZXh0fG51bGx7XHJcbiAgICAgICAgICAgIGlmKCF0aGlzLmNvbnRleHQpe1xyXG4gICAgICAgICAgICAgICAgdGhpcy5jb250ZXh0PUF1ZGlvQ29udGV4dFByb3ZpZGVyLmF1ZGlvQ29udGV4dEluc3RhbmNlKCk7XHJcbiAgICAgICAgICAgICAgICBpZih0aGlzLmNvbnRleHQpIHtcclxuICAgICAgICAgICAgICAgICAgICB0aGlzLmNvbnRleHQuYWRkRXZlbnRMaXN0ZW5lcignc3RhdGVjaGFuZ2UnLCAoZXYpID0+IHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmKHRoaXMuY29udGV4dCAmJiB0aGlzLmNvbnRleHQuc3RhdGUhPT0ncnVubmluZycpe1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuc3RvcCgpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgKTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICByZXR1cm4gdGhpcy5jb250ZXh0O1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgZ2V0IHN0YXJ0QWN0aW9uKCkge1xyXG4gICAgICAgICAgICByZXR1cm4gdGhpcy5fc3RhcnRBY3Rpb247XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICBnZXQgc3RhcnRTZWxlY3Rpb25BY3Rpb24oKXtcclxuICAgICAgICAgIHJldHVybiB0aGlzLl9zdGFydFNlbGVjdGlvbkFjdGlvblxyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgZ2V0IHN0b3BBY3Rpb24oKSB7XHJcbiAgICAgICAgICAgIHJldHVybiB0aGlzLl9zdG9wQWN0aW9uO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgc2V0IGF1ZGlvQ2xpcChhdWRpb0NsaXA6QXVkaW9DbGlwfCBudWxsKSB7XHJcbiAgICAgICAgICB0aGlzLl9hdWRpb0NsaXA9YXVkaW9DbGlwXHJcbiAgICAgICAgICAgIGxldCBsZW5ndGggPSAwO1xyXG4gICAgICAgICAgICBsZXQgY2hzID0gMDtcclxuICAgICAgICAgICAgaWYgKGF1ZGlvQ2xpcCAmJiBhdWRpb0NsaXAuYXVkaW9EYXRhSG9sZGVyKSB7XHJcbiAgICAgICAgICAgICAgICBsZXQgYXVkaW9EYXRhSG9sZGVyPWF1ZGlvQ2xpcC5hdWRpb0RhdGFIb2xkZXI7XHJcbiAgICAgICAgICAgICAgICBjaHMgPSBhdWRpb0RhdGFIb2xkZXIubnVtYmVyT2ZDaGFubmVsc1xyXG4gICAgICAgICAgICAgICAgaWYgKGNocyA+IDApIHtcclxuICAgICAgICAgICAgICAgICAgICBsZW5ndGggPSBhdWRpb0RhdGFIb2xkZXIuZnJhbWVMZW47XHJcbiAgICAgICAgICAgICAgICAgICAgLy9pZiAoY2hzID4gdGhpcy5jb250ZXh0LmRlc3RpbmF0aW9uLm1heENoYW5uZWxDb3VudCkge1xyXG4gICAgICAgICAgICAgICAgICAgIC8vICAgIC8vIFRPRE8gZXhjZXB0aW9uXHJcbiAgICAgICAgICAgICAgICAgICAgLy99XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICB0aGlzLmF1ZGlvU291cmNlPWF1ZGlvRGF0YUhvbGRlci5hdWRpb1NvdXJjZTtcclxuXHJcbiAgICAgICAgICAgICAgICBhdWRpb0NsaXAuYWRkU2VsZWN0aW9uT2JzZXJ2ZXIoKGFjKT0+IHtcclxuICAgICAgICAgICAgICAgICAgICB0aGlzLl9zdGFydFNlbGVjdGlvbkFjdGlvbi5kaXNhYmxlZCA9IHRoaXMuc3RhcnRTZWxlY3Rpb25EaXNhYmxlZCgpO1xyXG4gICAgICAgICAgICAgICAgICAgIGlmICghdGhpcy5zdGFydFNlbGVjdGlvbkFjdGlvbi5kaXNhYmxlZCAmJiB0aGlzLl9hdXRvUGxheU9uU2VsZWN0VG9nZ2xlQWN0aW9uLnZhbHVlKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICB0aGlzLnN0YXJ0U2VsZWN0ZWQoKTtcclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIClcclxuICAgICAgICAgICAgfWVsc2V7XHJcbiAgICAgICAgICAgICAgICB0aGlzLmF1ZGlvU291cmNlPW51bGw7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9XHJcblxyXG4gICAgICBnZXQgYXVkaW9Tb3VyY2UoKTogQXVkaW9Tb3VyY2UgfCBudWxsIHtcclxuICAgICAgICByZXR1cm4gdGhpcy5fYXVkaW9Tb3VyY2U7XHJcbiAgICAgIH1cclxuXHJcbiAgICAgIHNldCBhdWRpb1NvdXJjZSh2YWx1ZTogQXVkaW9Tb3VyY2UgfCBudWxsKSB7XHJcbiAgICAgICAgdGhpcy5zdG9wKCk7XHJcbiAgICAgICAgdGhpcy5fYXVkaW9Tb3VyY2UgPSB2YWx1ZTtcclxuICAgICAgICAgICAgaWYgKHRoaXMuX2F1ZGlvU291cmNlKSB7XHJcblxyXG4gICAgICAgICAgICAgICAgdGhpcy5yZWFkeSA9IHRydWU7XHJcbiAgICAgICAgICAgICAgICB0aGlzLnVwZGF0ZVN0YXJ0QWN0aW9ucygpO1xyXG4gICAgICAgICAgICAgICAgaWYgKHRoaXMubGlzdGVuZXIpIHtcclxuICAgICAgICAgICAgICAgICAgICB0aGlzLmxpc3RlbmVyLmF1ZGlvUGxheWVyVXBkYXRlKG5ldyBBdWRpb1BsYXllckV2ZW50KEV2ZW50VHlwZS5SRUFEWSkpO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB9ZWxzZSB7XHJcbiAgICAgICAgICAgICAgdGhpcy5yZWFkeSA9IGZhbHNlO1xyXG4gICAgICAgICAgICAgIHRoaXMudXBkYXRlU3RhcnRBY3Rpb25zKCk7XHJcbiAgICAgICAgICAgICAgaWYgKHRoaXMubGlzdGVuZXIpIHtcclxuICAgICAgICAgICAgICAgIHRoaXMubGlzdGVuZXIuYXVkaW9QbGF5ZXJVcGRhdGUobmV3IEF1ZGlvUGxheWVyRXZlbnQoRXZlbnRUeXBlLkNMT1NFRCkpO1xyXG4gICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgfVxyXG4gICAgICB9XHJcblxyXG4gICAgICAgIHByaXZhdGUgX2xvYWRTb3VyY2VXb3JrbGV0QW5kSW5pdFN0YXJ0KCl7XHJcbiAgICAgICAgICAgIGlmKHRoaXMuY29udGV4dCkge1xyXG4gICAgICAgICAgICAgICAgQXVkaW9Tb3VyY2VXb3JrbGV0TW9kdWxlTG9hZGVyLmxvYWRNb2R1bGUodGhpcy5jb250ZXh0KS50aGVuKCgpID0+IHtcclxuICAgICAgICAgICAgICAgICAgICAvL2NvbnNvbGUuZGVidWcoXCJQbGF5ZXIgcmVhZHkuICggYnkgUGxheWVyOjpfbG9hZFNvdXJjZVdvcmtsZXRBbmRJbml0U3RhcnQoKVwiKTtcclxuICAgICAgICAgICAgICAgICAgICB0aGlzLnJlYWR5ID0gdHJ1ZTtcclxuICAgICAgICAgICAgICAgICAgICB0aGlzLnVwZGF0ZVN0YXJ0QWN0aW9ucygpO1xyXG4gICAgICAgICAgICAgICAgICAgIGlmICh0aGlzLmxpc3RlbmVyKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMubGlzdGVuZXIuYXVkaW9QbGF5ZXJVcGRhdGUobmV3IEF1ZGlvUGxheWVyRXZlbnQoRXZlbnRUeXBlLlJFQURZKSk7XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgfSkuY2F0Y2goKGVycm9yOiBhbnkpID0+IHtcclxuICAgICAgICAgICAgICAgICAgICB0aGlzLnJlYWR5ID0gZmFsc2U7XHJcbiAgICAgICAgICAgICAgICAgICAgdGhpcy51cGRhdGVTdGFydEFjdGlvbnMoKTtcclxuICAgICAgICAgICAgICAgICAgICBpZiAodGhpcy5saXN0ZW5lcikge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmxpc3RlbmVyLmF1ZGlvUGxheWVyVXBkYXRlKG5ldyBBdWRpb1BsYXllckV2ZW50KEV2ZW50VHlwZS5DTE9TRUQpKTtcclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgY29uc29sZS5lcnJvcignQ291bGQgbm90IGFkZCBtb2R1bGUgJyArIGVycm9yKTtcclxuICAgICAgICAgICAgICAgIH0pO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG5cclxuXHJcbiAgcHJpdmF0ZSBfc3RhcnRBdWRpb1NvdXJjZVdvcmtsZXROb2RlKCl7XHJcbiAgICAgIHRoaXMuX2xvYWRTb3VyY2VXb3JrbGV0QW5kSW5pdFN0YXJ0KCk7XHJcbiAgICAgICAgICBpZih0aGlzLmNvbnRleHQgJiYgdGhpcy5zb3VyY2VBdWRpb1dvcmtsZXROb2RlKSB7XHJcbiAgICAgICAgICAgIHRoaXMuc291cmNlQXVkaW9Xb3JrbGV0Tm9kZS5vbnByb2Nlc3NvcmVycm9yID0gKGV2OiBFdmVudCkgPT4ge1xyXG4gICAgICAgICAgICAgIGxldCBtc2cgPSAnVW5rbndvbiBlcnJvcic7XHJcbiAgICAgICAgICAgICAgaWYgKGV2IGluc3RhbmNlb2YgRXJyb3JFdmVudCkge1xyXG4gICAgICAgICAgICAgICAgbXNnID0gZXYubWVzc2FnZTtcclxuICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgY29uc29sZS5lcnJvcihcIkF1ZGlvIHNvdXJjZSB3b3JrbGV0IGVycm9yOiBcIiArIG1zZyk7XHJcbiAgICAgICAgICAgICAgaWYgKHRoaXMubGlzdGVuZXIpIHtcclxuICAgICAgICAgICAgICAgIC8vIFRPRE9cclxuICAgICAgICAgICAgICAgIC8vIHRoaXMubGlzdGVuZXIuZXJyb3IobXNnKTtcclxuICAgICAgICAgICAgICAgIC8vIHRoaXMubGlzdGVuZXIuYXVkaW9QbGF5ZXJVcGRhdGUobmV3IEF1ZGlvUGxheWVyRXZlbnQoKSk7XHJcbiAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB9O1xyXG5cclxuICAgICAgICAgICAgdGhpcy5zb3VyY2VBdWRpb1dvcmtsZXROb2RlLmNvbm5lY3QodGhpcy5jb250ZXh0LmRlc3RpbmF0aW9uKTsgLy8gdGhpcyBhbHJlYWR5IHN0YXJ0cyBwbGF5aW5nXHJcbiAgICAgICAgICAgIHRoaXMuc291cmNlQXVkaW9Xb3JrbGV0Tm9kZS5vbmVuZGVkID0gKCkgPT4gdGhpcy5vbmVuZGVkKCk7XHJcbiAgICAgICAgICAgIHRoaXMucnVubmluZyA9IHRydWU7XHJcbiAgICAgICAgICAgIHRoaXMuc291cmNlQXVkaW9Xb3JrbGV0Tm9kZS5zdGFydCgpO1xyXG4gICAgICAgICAgICAvL2NvbnNvbGUuZGVidWcoXCJQbGF5YmFjayBzdGFydCBhY3Rpb24gZW5hYmxlZC4gKCBieSBQbGF5ZXI6Ol9zdGFydEF1ZGlvU291cmNlV29ya2xldE5vZGUoKVwiKTtcclxuICAgICAgICAgICAgdGhpcy5fc3RhcnRBY3Rpb24uZGlzYWJsZWQgPSB0cnVlO1xyXG4gICAgICAgICAgICB0aGlzLl9zdGFydFNlbGVjdGlvbkFjdGlvbi5kaXNhYmxlZCA9IHRydWVcclxuICAgICAgICAgICAgdGhpcy5fc3RvcEFjdGlvbi5kaXNhYmxlZCA9IGZhbHNlO1xyXG5cclxuICAgICAgICAgICAgaWYgKHRoaXMubGlzdGVuZXIpIHtcclxuICAgICAgICAgICAgICB0aGlzLmxpc3RlbmVyLmF1ZGlvUGxheWVyVXBkYXRlKG5ldyBBdWRpb1BsYXllckV2ZW50KEV2ZW50VHlwZS5TVEFSVEVEKSk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgIH1cclxuXHJcbiAgfVxyXG5cclxuICAgICAgICBzdGFydCgpIHtcclxuXHJcbiAgICAgICAgICAgIHRoaXMuX2F1ZGlvQ29udGV4dCgpO1xyXG5cclxuICAgICAgICAgICAgaWYodGhpcy5jb250ZXh0KSB7XHJcbiAgICAgICAgICAgICAgICBpZiAoIXRoaXMuX3N0YXJ0QWN0aW9uLmRpc2FibGVkICYmICF0aGlzLnJ1bm5pbmcpIHtcclxuICAgICAgICAgICAgICAgICAgICBpZiAodGhpcy5jb250ZXh0LnN0YXRlID09PSAnc3VzcGVuZGVkJykge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmNvbnRleHQucmVzdW1lKCkudGhlbigoKSA9PiB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLl9zdGFydCgpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB9KS5jYXRjaCgocmVhc29uKSA9PiB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zb2xlLmVycm9yKHJlYXNvbi5tZXNzYWdlKCkpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3cgcmVhc29uO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB9KVxyXG4gICAgICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAodGhpcy5jb250ZXh0LnN0YXRlID09PSAnY2xvc2VkJykge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBtc2cgPSAnRXJyb3I6IENhbm5vdCBzdGFydCBwbGF5YmFjay4gQXVkaW8gY29udGV4dCBpcyBhbHJlYWR5IGNsb3NlZCEnO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zb2xlLmVycm9yKG1zZyk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihtc2cpO1xyXG4gICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuX3N0YXJ0KCk7XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICB1cGRhdGVTdGFydEFjdGlvbnMoKXtcclxuXHJcbiAgICAgICAgICBpZih0aGlzLnJlYWR5KXtcclxuICAgICAgICAgICAgaWYodGhpcy5fYXVkaW9Tb3VyY2UgaW5zdGFuY2VvZiBBdWRpb0J1ZmZlclNvdXJjZSB8fCB0aGlzLl9hdWRpb1NvdXJjZSBpbnN0YW5jZW9mIEFycmF5QXVkaW9CdWZmZXIgfHwgdGhpcy5fYXVkaW9Tb3VyY2UgaW5zdGFuY2VvZiBJbmRleGVkRGJBdWRpb0J1ZmZlcil7XHJcbiAgICAgICAgICAgICAgdGhpcy5fc3RhcnRBY3Rpb24uZGlzYWJsZWQ9ZmFsc2U7XHJcbiAgICAgICAgICAgICAgdGhpcy5fc3RhcnRTZWxlY3Rpb25BY3Rpb24uZGlzYWJsZWQ9dGhpcy5zdGFydFNlbGVjdGlvbkRpc2FibGVkKCk7XHJcbiAgICAgICAgICAgIH1lbHNle1xyXG4gICAgICAgICAgICAgIGlmKHRoaXMuX2F1ZGlvU291cmNlIGluc3RhbmNlb2YgTmV0QXVkaW9CdWZmZXIpe1xyXG4gICAgICAgICAgICAgICAgdGhpcy5fYXVkaW9Tb3VyY2UuYWRkT25SZWFkeUxpc3RlbmVyKCgpPT57XHJcbiAgICAgICAgICAgICAgICAgIHRoaXMuX3N0YXJ0QWN0aW9uLmRpc2FibGVkPWZhbHNlO1xyXG4gICAgICAgICAgICAgICAgICB0aGlzLl9zdGFydFNlbGVjdGlvbkFjdGlvbi5kaXNhYmxlZD10aGlzLnN0YXJ0U2VsZWN0aW9uRGlzYWJsZWQoKTtcclxuICAgICAgICAgICAgICAgIH0pO1xyXG4gICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgfWVsc2V7XHJcbiAgICAgICAgICAgIHRoaXMuX3N0YXJ0QWN0aW9uLmRpc2FibGVkPXRydWU7XHJcbiAgICAgICAgICAgIHRoaXMuX3N0YXJ0U2VsZWN0aW9uQWN0aW9uLmRpc2FibGVkPXRydWU7XHJcbiAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICBzdGFydFNlbGVjdGlvbkRpc2FibGVkKCl7XHJcbiAgICAgICAgICByZXR1cm4gISh0aGlzLl9hdWRpb0NsaXAgJiYgIXRoaXMuc3RhcnRBY3Rpb24uZGlzYWJsZWQgJiYgdGhpcy5fYXVkaW9DbGlwLnNlbGVjdGlvbiApXHJcbiAgICAgICAgfVxyXG5cclxuXHJcbiAgICAgICAgcHJpdmF0ZSBfc3RhcnQocGxheVNlbGVjdGlvbj1mYWxzZSl7XHJcbiAgICAgICAgICAgICAgICBpZighdGhpcy5jb250ZXh0KXtcclxuICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJDb3VsZCBub3QgZ2V0IGF1ZGlvIGNvbnRleHQhXCIpO1xyXG4gICAgICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgIGlmICh0aGlzLl9hdWRpb1NvdXJjZSBpbnN0YW5jZW9mIEF1ZGlvQnVmZmVyU291cmNlKSB7XHJcbiAgICAgICAgICAgIHRoaXMuc291cmNlQnVmZmVyTm9kZSA9IHRoaXMuY29udGV4dC5jcmVhdGVCdWZmZXJTb3VyY2UoKTtcclxuICAgICAgICAgICAgdGhpcy5zb3VyY2VCdWZmZXJOb2RlLmJ1ZmZlciA9IHRoaXMuX2F1ZGlvU291cmNlLmF1ZGlvQnVmZmVyO1xyXG4gICAgICAgICAgICB0aGlzLnNvdXJjZUJ1ZmZlck5vZGUuY29ubmVjdCh0aGlzLmNvbnRleHQuZGVzdGluYXRpb24pO1xyXG4gICAgICAgICAgICB0aGlzLnNvdXJjZUJ1ZmZlck5vZGUub25lbmRlZCA9ICgpID0+IHRoaXMub25lbmRlZCgpO1xyXG4gICAgICAgICAgICB0aGlzLnBsYXlTdGFydFRpbWUgPSB0aGlzLmNvbnRleHQuY3VycmVudFRpbWU7XHJcbiAgICAgICAgICAgIHRoaXMucnVubmluZyA9IHRydWU7XHJcbiAgICAgICAgICAgIC8vIHVuZm9ydHVuYXRlbHkgV2ViIEF1ZGlvIEFQSSB1c2VzIHRpbWUgdmFsdWVzIG5vdCBmcmFtZXNcclxuICAgICAgICAgICAgY29uc3QgYWMgPSB0aGlzLl9hdWRpb0NsaXBcclxuICAgICAgICAgICAgbGV0IG9mZnNldCA9IDA7XHJcbiAgICAgICAgICAgIGlmIChwbGF5U2VsZWN0aW9uICYmIGFjICYmIGFjLnNlbGVjdGlvbikge1xyXG5cclxuICAgICAgICAgICAgICBjb25zdCBzID0gYWMuc2VsZWN0aW9uO1xyXG4gICAgICAgICAgICAgIGNvbnN0IHNyID0gYWMuYXVkaW9EYXRhSG9sZGVyLnNhbXBsZVJhdGU7XHJcbiAgICAgICAgICAgICAgb2Zmc2V0ID0gcy5sZWZ0RnJhbWUgLyBzcjtcclxuICAgICAgICAgICAgICBjb25zdCBzdG9wUG9zSW5zZWNzID0gcy5yaWdodEZyYW1lIC8gc3I7XHJcbiAgICAgICAgICAgICAgY29uc3QgZHVyID0gc3RvcFBvc0luc2VjcyAtIG9mZnNldDtcclxuICAgICAgICAgICAgICB0aGlzLnNvdXJjZUJ1ZmZlck5vZGUuc3RhcnQoMCwgb2Zmc2V0LCBkdXIpXHJcbiAgICAgICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgICAgdGhpcy5zb3VyY2VCdWZmZXJOb2RlLnN0YXJ0KCk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgdGhpcy5wbGF5U3RhcnRUaW1lID0gdGhpcy5jb250ZXh0LmN1cnJlbnRUaW1lIC0gb2Zmc2V0O1xyXG4gICAgICAgICAgICB0aGlzLl9zdGFydEFjdGlvbi5kaXNhYmxlZCA9IHRydWU7XHJcbiAgICAgICAgICAgIHRoaXMuX3N0YXJ0U2VsZWN0aW9uQWN0aW9uLmRpc2FibGVkID0gdHJ1ZVxyXG4gICAgICAgICAgICB0aGlzLl9zdG9wQWN0aW9uLmRpc2FibGVkID0gZmFsc2U7XHJcblxyXG4gICAgICAgICAgICBpZiAodGhpcy5saXN0ZW5lcikge1xyXG4gICAgICAgICAgICAgIHRoaXMubGlzdGVuZXIuYXVkaW9QbGF5ZXJVcGRhdGUobmV3IEF1ZGlvUGxheWVyRXZlbnQoRXZlbnRUeXBlLlNUQVJURUQpKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgfSBlbHNlIGlmICh0aGlzLl9hdWRpb1NvdXJjZSBpbnN0YW5jZW9mIEFycmF5QXVkaW9CdWZmZXIgfHwgdGhpcy5fYXVkaW9Tb3VyY2UgaW5zdGFuY2VvZiBJbmRleGVkRGJBdWRpb0J1ZmZlciB8fCB0aGlzLl9hdWRpb1NvdXJjZSBpbnN0YW5jZW9mIE5ldEF1ZGlvQnVmZmVyKSB7XHJcbiAgICAgICAgICAgICAgQXVkaW9Tb3VyY2VXb3JrbGV0TW9kdWxlTG9hZGVyLmxvYWRNb2R1bGUodGhpcy5jb250ZXh0KS50aGVuKCgpID0+IHtcclxuICAgICAgICAgICAgICAgICAgdGhpcy5wbGF5U3RhcnRUaW1lID0gbnVsbDtcclxuICAgICAgICAgICAgICAgICAgaWYgKHRoaXMuY29udGV4dCkge1xyXG4gICAgICAgICAgICAgICAgICBpZiAodGhpcy5fYXVkaW9Tb3VyY2UgaW5zdGFuY2VvZiBBcnJheUF1ZGlvQnVmZmVyKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICBjb25zdCBhYWJzbiA9IG5ldyBBcnJheUF1ZGlvQnVmZmVyU291cmNlTm9kZSh0aGlzLmNvbnRleHQpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgYWFic24uYXJyYXlBdWRpb0J1ZmZlciA9IHRoaXMuX2F1ZGlvU291cmNlO1xyXG4gICAgICAgICAgICAgICAgICAgICAgdGhpcy5zb3VyY2VBdWRpb1dvcmtsZXROb2RlID0gYWFic247XHJcbiAgICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAodGhpcy5fYXVkaW9Tb3VyY2UgaW5zdGFuY2VvZiBJbmRleGVkRGJBdWRpb0J1ZmZlcikge1xyXG4gICAgICAgICAgICAgICAgICAgICAgY29uc3QgaWFzbiA9IG5ldyBJbmRleGVkRGJBdWRpb0J1ZmZlclNvdXJjZU5vZGUodGhpcy5jb250ZXh0KTtcclxuICAgICAgICAgICAgICAgICAgICAgIGlhc24uaW5kZGJBdWRpb0J1ZmZlciA9IHRoaXMuX2F1ZGlvU291cmNlO1xyXG4gICAgICAgICAgICAgICAgICAgICAgdGhpcy5zb3VyY2VBdWRpb1dvcmtsZXROb2RlID0gaWFzbjtcclxuICAgICAgICAgICAgICAgICAgfSBlbHNlIGlmICh0aGlzLl9hdWRpb1NvdXJjZSBpbnN0YW5jZW9mIE5ldEF1ZGlvQnVmZmVyKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICBjb25zdCBuYWJzbiA9IG5ldyBOZXRBdWRpb0J1ZmZlclNvdXJjZU5vZGUodGhpcy5jb250ZXh0KTtcclxuICAgICAgICAgICAgICAgICAgICAgIG5hYnNuLm5ldEF1ZGlvQnVmZmVyID0gdGhpcy5fYXVkaW9Tb3VyY2U7XHJcbiAgICAgICAgICAgICAgICAgICAgICB0aGlzLnNvdXJjZUF1ZGlvV29ya2xldE5vZGUgPSBuYWJzbjtcclxuICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICBpZiAodGhpcy5zb3VyY2VBdWRpb1dvcmtsZXROb2RlKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICB0aGlzLnNvdXJjZUF1ZGlvV29ya2xldE5vZGUub25wcm9jZXNzb3JlcnJvciA9IChldjogRXZlbnQpID0+IHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICBsZXQgbXNnID0gJ1Vua253b24gZXJyb3InO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChldiBpbnN0YW5jZW9mIEVycm9yRXZlbnQpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbXNnID0gZXYubWVzc2FnZTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc29sZS5lcnJvcihcIkF1ZGlvIHNvdXJjZSB3b3JrbGV0IGVycm9yOiBcIiArIG1zZyk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHRoaXMubGlzdGVuZXIpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5saXN0ZW5lci5hdWRpb1BsYXllclVwZGF0ZShuZXcgQXVkaW9QbGF5ZXJFdmVudChFdmVudFR5cGUuRVJST1IpKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICB9O1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAgIHRoaXMuc291cmNlQXVkaW9Xb3JrbGV0Tm9kZS5jb25uZWN0KHRoaXMuY29udGV4dC5kZXN0aW5hdGlvbik7IC8vIHRoaXMgYWxyZWFkeSBzdGFydHMgcGxheWluZ1xyXG4gICAgICAgICAgICAgICAgICAgICAgdGhpcy5zb3VyY2VBdWRpb1dvcmtsZXROb2RlLm9uZW5kZWQgPSAoKSA9PiB0aGlzLm9uZW5kZWQoKTtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICB0aGlzLnJ1bm5pbmcgPSB0cnVlO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGFjID0gdGhpcy5fYXVkaW9DbGlwXHJcbiAgICAgICAgICAgICAgICAgICAgICBsZXQgb2Zmc2V0ID0gMFxyXG4gICAgICAgICAgICAgICAgICAgICAgaWYgKHBsYXlTZWxlY3Rpb24gJiYgYWMgJiYgYWMuc2VsZWN0aW9uKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgcyA9IGFjLnNlbGVjdGlvbjtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBzciA9IGFjLmF1ZGlvRGF0YUhvbGRlci5zYW1wbGVSYXRlO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgIG9mZnNldCA9IHMubGVmdEZyYW1lIC8gc3I7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3Qgc3RvcFBvc0luc2VjcyA9IHMucmlnaHRGcmFtZSAvIHNyO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGR1ciA9IHN0b3BQb3NJbnNlY3MgLSBvZmZzZXRcclxuICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnNvdXJjZUF1ZGlvV29ya2xldE5vZGUuc3RhcnQoMCwgb2Zmc2V0LCBkdXIpXHJcbiAgICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuc291cmNlQXVkaW9Xb3JrbGV0Tm9kZS5zdGFydCgpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgICAgICAgICAgIC8vdGhpcy5wbGF5U3RhcnRUaW1lID0gdGhpcy5jb250ZXh0LmN1cnJlbnRUaW1lIC0gb2Zmc2V0O1xyXG4gICAgICAgICAgICAgICAgICAgICAgdGhpcy5fc3RhcnRBY3Rpb24uZGlzYWJsZWQgPSB0cnVlO1xyXG4gICAgICAgICAgICAgICAgICAgICAgdGhpcy5fc3RhcnRTZWxlY3Rpb25BY3Rpb24uZGlzYWJsZWQgPSB0cnVlXHJcbiAgICAgICAgICAgICAgICAgICAgICB0aGlzLl9zdG9wQWN0aW9uLmRpc2FibGVkID0gZmFsc2U7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgICAgaWYgKHRoaXMubGlzdGVuZXIpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmxpc3RlbmVyLmF1ZGlvUGxheWVyVXBkYXRlKG5ldyBBdWRpb1BsYXllckV2ZW50KEV2ZW50VHlwZS5TVEFSVEVEKSk7XHJcbiAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgfSkuY2F0Y2goKGVycm9yOiBhbnkpID0+IHtcclxuICAgICAgICAgICAgICAgICAgY29uc29sZS5lcnJvcihlcnJvci5tZXNzYWdlKTtcclxuICAgICAgICAgICAgICAgICAgdGhpcy5yZWFkeSA9IGZhbHNlO1xyXG4gICAgICAgICAgICAgICAgICB0aGlzLnVwZGF0ZVN0YXJ0QWN0aW9ucygpO1xyXG4gICAgICAgICAgICAgICAgICBpZiAodGhpcy5saXN0ZW5lcikge1xyXG4gICAgICAgICAgICAgICAgICAgICAgdGhpcy5saXN0ZW5lci5hdWRpb1BsYXllclVwZGF0ZShuZXcgQXVkaW9QbGF5ZXJFdmVudChFdmVudFR5cGUuQ0xPU0VEKSk7XHJcbiAgICAgICAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgICAgICAgIHRocm93IGVycm9yO1xyXG4gICAgICAgICAgICAgIH0pO1xyXG5cclxuICAgICAgICAgIH1cclxuICAgICAgICB9XHJcblxyXG4gICAgICBzdGFydFNlbGVjdGVkKCkge1xyXG4gICAgICAgICAgICB0aGlzLl9hdWRpb0NvbnRleHQoKTtcclxuICAgICAgICAgIGlmKCF0aGlzLmNvbnRleHQpe1xyXG4gICAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihcIkNvdWxkIG5vdCBnZXQgYXVkaW8gY29udGV4dCFcIik7XHJcbiAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgaWYoIXRoaXMuX3N0YXJ0QWN0aW9uLmRpc2FibGVkICYmICF0aGlzLnJ1bm5pbmcpIHtcclxuICAgICAgICAgIGlmICh0aGlzLmNvbnRleHQuc3RhdGUgPT09ICdzdXNwZW5kZWQnKSB7XHJcbiAgICAgICAgICAgIHRoaXMuY29udGV4dC5yZXN1bWUoKS50aGVuKCgpID0+IHtcclxuICAgICAgICAgICAgICB0aGlzLl9zdGFydCh0cnVlKTtcclxuICAgICAgICAgICAgfSkuY2F0Y2goKHJlYXNvbikgPT4ge1xyXG4gICAgICAgICAgICAgIGNvbnNvbGUuZXJyb3IocmVhc29uLm1lc3NhZ2UpO1xyXG4gICAgICAgICAgICAgIHRocm93IHJlYXNvbjtcclxuICAgICAgICAgICAgfSlcclxuICAgICAgICAgIH1lbHNlIGlmKHRoaXMuY29udGV4dC5zdGF0ZT09PSdjbG9zZWQnKXtcclxuICAgICAgICAgICAgY29uc3QgbXNnPSdFcnJvcjogQ2Fubm90IHN0YXJ0IHBsYXliYWNrIG9mIHNlbGVjdGlvbi4gQXVkaW8gY29udGV4dCBpcyBhbHJlYWR5IGNsb3NlZCEnO1xyXG4gICAgICAgICAgICBjb25zb2xlLmVycm9yKG1zZyk7XHJcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihtc2cpO1xyXG4gICAgICAgICAgfWVsc2V7XHJcbiAgICAgICAgICAgIHRoaXMuX3N0YXJ0KHRydWUpO1xyXG4gICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuICAgICAgfVxyXG5cclxuICAgICAgICBzdG9wKCl7XHJcbiAgICAgICAgICAgIGlmKHRoaXMucnVubmluZykge1xyXG4gICAgICAgICAgICAgICAgaWYgKHRoaXMuc291cmNlQnVmZmVyTm9kZSkge1xyXG4gICAgICAgICAgICAgICAgICAgIHRoaXMuc291cmNlQnVmZmVyTm9kZS5zdG9wKCk7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICBpZih0aGlzLnNvdXJjZUF1ZGlvV29ya2xldE5vZGUpe1xyXG4gICAgICAgICAgICAgICAgICB0aGlzLnNvdXJjZUF1ZGlvV29ya2xldE5vZGUuc3RvcCgpO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICBpZiAodGhpcy50aW1lclZhciAhPT0gbnVsbCkge1xyXG4gICAgICAgICAgICAgICAgICAgIHdpbmRvdy5jbGVhckludGVydmFsKHRoaXMudGltZXJWYXIpO1xyXG4gICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgIHRoaXMucnVubmluZyA9IGZhbHNlO1xyXG4gICAgICAgICAgICAgICAgICBpZiAodGhpcy5saXN0ZW5lcikge1xyXG4gICAgICAgICAgICAgICAgICAgIHRoaXMubGlzdGVuZXIuYXVkaW9QbGF5ZXJVcGRhdGUobmV3IEF1ZGlvUGxheWVyRXZlbnQoRXZlbnRUeXBlLlNUT1BQRUQpKTtcclxuICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgb25lbmRlZCgpIHtcclxuICAgICAgICAgICAgaWYodGhpcy50aW1lclZhciE9bnVsbCkge1xyXG4gICAgICAgICAgICAgICAgd2luZG93LmNsZWFySW50ZXJ2YWwodGhpcy50aW1lclZhcik7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgdGhpcy5fc3RhcnRBY3Rpb24uZGlzYWJsZWQgPSAhdGhpcy5fYXVkaW9Tb3VyY2U7XHJcbiAgICAgICAgICAgIHRoaXMuX3N0YXJ0U2VsZWN0aW9uQWN0aW9uLmRpc2FibGVkPXRoaXMuc3RhcnRTZWxlY3Rpb25EaXNhYmxlZCgpXHJcbiAgICAgICAgICAgIHRoaXMuX3N0b3BBY3Rpb24uZGlzYWJsZWQgPSB0cnVlO1xyXG4gICAgICAgICAgICB0aGlzLnJ1bm5pbmc9ZmFsc2U7XHJcbiAgICAgICAgICAgIGlmICh0aGlzLmxpc3RlbmVyKSB7XHJcbiAgICAgICAgICAgICAgICB0aGlzLmxpc3RlbmVyLmF1ZGlvUGxheWVyVXBkYXRlKG5ldyBBdWRpb1BsYXllckV2ZW50KEV2ZW50VHlwZS5FTkRFRCkpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICBnZXQgcGxheVBvc2l0aW9uVGltZSgpOm51bWJlcnxudWxsIHtcclxuICAgICAgICAgICAgbGV0IHBwdD1udWxsO1xyXG4gICAgICAgICAgICBpZih0aGlzLmNvbnRleHQgJiYgdGhpcy5wbGF5U3RhcnRUaW1lIT09bnVsbCkge1xyXG4gICAgICAgICAgICAgICAgcHB0PSB0aGlzLmNvbnRleHQuY3VycmVudFRpbWUgLSB0aGlzLnBsYXlTdGFydFRpbWU7XHJcbiAgICAgICAgICAgIH1lbHNlIGlmKHRoaXMuc291cmNlQXVkaW9Xb3JrbGV0Tm9kZSl7XHJcbiAgICAgICAgICAgICAgcHB0PXRoaXMuc291cmNlQXVkaW9Xb3JrbGV0Tm9kZS5wbGF5UG9zaXRpb25UaW1lO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIHJldHVybiBwcHQ7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgZ2V0IHBsYXlQb3NpdGlvbkZyYW1lcygpOm51bWJlcnxudWxsIHtcclxuICAgICAgICBsZXQgcHBGcnM6bnVtYmVyfG51bGw9bnVsbDtcclxuICAgICAgIGlmKHRoaXMuX2F1ZGlvU291cmNlKSB7XHJcbiAgICAgICAgIGxldCBzcj10aGlzLl9hdWRpb1NvdXJjZS5zYW1wbGVSYXRlO1xyXG4gICAgICAgICBpZiAoc3IpIHtcclxuICAgICAgICAgICBsZXQgcHBUaW1lID0gdGhpcy5wbGF5UG9zaXRpb25UaW1lO1xyXG4gICAgICAgICAgIGlmIChwcFRpbWUgIT09IG51bGwpIHtcclxuICAgICAgICAgICAgIHBwRnJzID0gc3IgKiBwcFRpbWU7XHJcbiAgICAgICAgICAgfVxyXG4gICAgICAgICB9XHJcbiAgICAgICB9XHJcbiAgICAgICAgcmV0dXJuIHBwRnJzO1xyXG4gICAgICB9XHJcblxyXG4gICAgfVxyXG5cclxuIl19