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,68 +1,68 @@
1
- import { PromptitemUtil } from "../../script/script";
2
- // export class RecordingFile {
3
- //
4
- // get recordingFileId(): string | number {
5
- // return this._recordingFileId;
6
- // }
7
- //
8
- // frames:number=null
9
- // editStartFrame:number=null
10
- // editEndFrame:number=null
11
- //
12
- // recording:PromptItem;
13
- //
14
- // session:number|string;
15
- //
16
- // get audioBuffer(): AudioBuffer {
17
- // return this._audioBuffer;
18
- // }
19
- //
20
- // set audioBuffer(value: AudioBuffer) {
21
- // this._audioBuffer = value;
22
- // }
23
- // private _recordingFileId:string | number;
24
- // private _audioBuffer:AudioBuffer;
25
- //
26
- // constructor(recordingFileId: string| number, audioBuffer:AudioBuffer){
27
- // this._recordingFileId=recordingFileId;
28
- // this._audioBuffer=audioBuffer;
29
- // }
30
- //
31
- //
32
- // }
33
- export class RecordingFileUtil {
34
- static recordingAsPlainText(recordingFile) {
35
- if (recordingFile) {
36
- let r = recordingFile.recording;
37
- if (r) {
38
- return PromptitemUtil.toPlainTextString(r);
39
- }
40
- }
41
- return "n/a";
42
- }
43
- static framePosForSampleRate(framePosSampleRate, framePos, sampleRate) {
44
- let fpFSr = null;
45
- // TODO transitional until editSampleRates are set in the database
46
- if (framePosSampleRate == null) {
47
- framePosSampleRate = sampleRate;
48
- }
49
- if (framePosSampleRate != null && framePos != null) {
50
- if (framePosSampleRate === sampleRate) {
51
- fpFSr = framePos;
52
- }
53
- else {
54
- fpFSr = Math.round((framePos * sampleRate) / framePosSampleRate);
55
- }
56
- }
57
- return fpFSr;
58
- }
59
- static editStartFrameForSampleRate(recordingFile, sampleRate) {
60
- let esffSr = RecordingFileUtil.framePosForSampleRate(recordingFile.editSampleRate, recordingFile.editStartFrame, sampleRate);
61
- return esffSr;
62
- }
63
- static editEndFrameForSampleRate(recordingFile, sampleRate) {
64
- let eeffSr = RecordingFileUtil.framePosForSampleRate(recordingFile.editSampleRate, recordingFile.editEndFrame, sampleRate);
65
- return eeffSr;
66
- }
67
- }
1
+ import { PromptitemUtil } from "../../script/script";
2
+ // export class RecordingFile {
3
+ //
4
+ // get recordingFileId(): string | number {
5
+ // return this._recordingFileId;
6
+ // }
7
+ //
8
+ // frames:number=null
9
+ // editStartFrame:number=null
10
+ // editEndFrame:number=null
11
+ //
12
+ // recording:PromptItem;
13
+ //
14
+ // session:number|string;
15
+ //
16
+ // get audioBuffer(): AudioBuffer {
17
+ // return this._audioBuffer;
18
+ // }
19
+ //
20
+ // set audioBuffer(value: AudioBuffer) {
21
+ // this._audioBuffer = value;
22
+ // }
23
+ // private _recordingFileId:string | number;
24
+ // private _audioBuffer:AudioBuffer;
25
+ //
26
+ // constructor(recordingFileId: string| number, audioBuffer:AudioBuffer){
27
+ // this._recordingFileId=recordingFileId;
28
+ // this._audioBuffer=audioBuffer;
29
+ // }
30
+ //
31
+ //
32
+ // }
33
+ export class RecordingFileUtil {
34
+ static recordingAsPlainText(recordingFile) {
35
+ if (recordingFile) {
36
+ let r = recordingFile.recording;
37
+ if (r) {
38
+ return PromptitemUtil.toPlainTextString(r);
39
+ }
40
+ }
41
+ return "n/a";
42
+ }
43
+ static framePosForSampleRate(framePosSampleRate, framePos, sampleRate) {
44
+ let fpFSr = null;
45
+ // TODO transitional until editSampleRates are set in the database
46
+ if (framePosSampleRate == null) {
47
+ framePosSampleRate = sampleRate;
48
+ }
49
+ if (framePosSampleRate != null && framePos != null) {
50
+ if (framePosSampleRate === sampleRate) {
51
+ fpFSr = framePos;
52
+ }
53
+ else {
54
+ fpFSr = Math.round((framePos * sampleRate) / framePosSampleRate);
55
+ }
56
+ }
57
+ return fpFSr;
58
+ }
59
+ static editStartFrameForSampleRate(recordingFile, sampleRate) {
60
+ let esffSr = RecordingFileUtil.framePosForSampleRate(recordingFile.editSampleRate, recordingFile.editStartFrame, sampleRate);
61
+ return esffSr;
62
+ }
63
+ static editEndFrameForSampleRate(recordingFile, sampleRate) {
64
+ let eeffSr = RecordingFileUtil.framePosForSampleRate(recordingFile.editSampleRate, recordingFile.editEndFrame, sampleRate);
65
+ return eeffSr;
66
+ }
67
+ }
68
68
  //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicmVjb3JkaW5nLWZpbGUuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi8uLi9wcm9qZWN0cy9zcGVlY2hyZWNvcmRlcm5nL3NyYy9saWIvc3BlZWNocmVjb3JkZXIvc2Vzc2lvbi9yZWNvcmRpbmdmaWxlL3JlY29yZGluZy1maWxlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBQyxjQUFjLEVBQUMsTUFBTSxxQkFBcUIsQ0FBQztBQUluRCwrQkFBK0I7QUFDL0IsRUFBRTtBQUNGLDZDQUE2QztBQUM3QyxvQ0FBb0M7QUFDcEMsTUFBTTtBQUNOLEVBQUU7QUFDRix1QkFBdUI7QUFDdkIsK0JBQStCO0FBQy9CLDZCQUE2QjtBQUM3QixFQUFFO0FBQ0YsMEJBQTBCO0FBQzFCLEVBQUU7QUFDRiwyQkFBMkI7QUFDM0IsRUFBRTtBQUNGLHFDQUFxQztBQUNyQyxnQ0FBZ0M7QUFDaEMsTUFBTTtBQUNOLEVBQUU7QUFDRiwwQ0FBMEM7QUFDMUMsaUNBQWlDO0FBQ2pDLE1BQU07QUFDTiw4Q0FBOEM7QUFDOUMsc0NBQXNDO0FBQ3RDLEVBQUU7QUFDRiwyRUFBMkU7QUFDM0UsNkNBQTZDO0FBQzdDLHFDQUFxQztBQUNyQyxNQUFNO0FBQ04sRUFBRTtBQUNGLEVBQUU7QUFDRixJQUFJO0FBRUosTUFBTSxPQUFPLGlCQUFpQjtJQUNyQixNQUFNLENBQUMsb0JBQW9CLENBQUMsYUFBOEI7UUFDL0QsSUFBSSxhQUFhLEVBQUU7WUFDakIsSUFBSSxDQUFDLEdBQUcsYUFBYSxDQUFDLFNBQVMsQ0FBQztZQUNoQyxJQUFJLENBQUMsRUFBRTtnQkFDTCxPQUFPLGNBQWMsQ0FBQyxpQkFBaUIsQ0FBQyxDQUFDLENBQUMsQ0FBQzthQUM1QztTQUNGO1FBQ0QsT0FBTyxLQUFLLENBQUM7SUFDZixDQUFDO0lBRU0sTUFBTSxDQUFDLHFCQUFxQixDQUFDLGtCQUE4QixFQUFDLFFBQW9CLEVBQUMsVUFBaUI7UUFDdkcsSUFBSSxLQUFLLEdBQUMsSUFBSSxDQUFDO1FBRWYsa0VBQWtFO1FBQ2xFLElBQUcsa0JBQWtCLElBQUUsSUFBSSxFQUFDO1lBQzFCLGtCQUFrQixHQUFDLFVBQVUsQ0FBQztTQUMvQjtRQUNELElBQUcsa0JBQWtCLElBQUUsSUFBSSxJQUFJLFFBQVEsSUFBRSxJQUFJLEVBQUU7WUFDN0MsSUFBSSxrQkFBa0IsS0FBSyxVQUFVLEVBQUU7Z0JBQ3JDLEtBQUssR0FBQyxRQUFRLENBQUM7YUFDaEI7aUJBQU07Z0JBQ0wsS0FBSyxHQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQyxRQUFRLEdBQUcsVUFBVSxDQUFDLEdBQUcsa0JBQWtCLENBQUMsQ0FBQzthQUNoRTtTQUNGO1FBQ0QsT0FBTyxLQUFLLENBQUM7SUFDZixDQUFDO0lBRU0sTUFBTSxDQUFDLDJCQUEyQixDQUFDLGFBQTJCLEVBQUUsVUFBaUI7UUFDdEYsSUFBSSxNQUFNLEdBQUMsaUJBQWlCLENBQUMscUJBQXFCLENBQUMsYUFBYSxDQUFDLGNBQWMsRUFBQyxhQUFhLENBQUMsY0FBYyxFQUFDLFVBQVUsQ0FBQyxDQUFDO1FBQ3pILE9BQU8sTUFBTSxDQUFDO0lBQ2hCLENBQUM7SUFFTSxNQUFNLENBQUMseUJBQXlCLENBQUMsYUFBMkIsRUFBRSxVQUFpQjtRQUNwRixJQUFJLE1BQU0sR0FBQyxpQkFBaUIsQ0FBQyxxQkFBcUIsQ0FBQyxhQUFhLENBQUMsY0FBYyxFQUFDLGFBQWEsQ0FBQyxZQUFZLEVBQUMsVUFBVSxDQUFDLENBQUM7UUFDdkgsT0FBTyxNQUFNLENBQUM7SUFDaEIsQ0FBQztDQUNGIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHtQcm9tcHRpdGVtVXRpbH0gZnJvbSBcIi4uLy4uL3NjcmlwdC9zY3JpcHRcIjtcclxuaW1wb3J0IHtSZWNvcmRpbmdGaWxlLCBTcHJSZWNvcmRpbmdGaWxlfSBmcm9tIFwiLi4vLi4vcmVjb3JkaW5nXCI7XHJcblxyXG5cclxuLy8gZXhwb3J0IGNsYXNzIFJlY29yZGluZ0ZpbGUge1xyXG4vL1xyXG4vLyAgIGdldCByZWNvcmRpbmdGaWxlSWQoKTogc3RyaW5nIHwgbnVtYmVyIHtcclxuLy8gICAgIHJldHVybiB0aGlzLl9yZWNvcmRpbmdGaWxlSWQ7XHJcbi8vICAgfVxyXG4vL1xyXG4vLyAgIGZyYW1lczpudW1iZXI9bnVsbFxyXG4vLyAgIGVkaXRTdGFydEZyYW1lOm51bWJlcj1udWxsXHJcbi8vICAgZWRpdEVuZEZyYW1lOm51bWJlcj1udWxsXHJcbi8vXHJcbi8vICAgcmVjb3JkaW5nOlByb21wdEl0ZW07XHJcbi8vXHJcbi8vICAgc2Vzc2lvbjpudW1iZXJ8c3RyaW5nO1xyXG4vL1xyXG4vLyAgIGdldCBhdWRpb0J1ZmZlcigpOiBBdWRpb0J1ZmZlciB7XHJcbi8vICAgICByZXR1cm4gdGhpcy5fYXVkaW9CdWZmZXI7XHJcbi8vICAgfVxyXG4vL1xyXG4vLyAgIHNldCBhdWRpb0J1ZmZlcih2YWx1ZTogQXVkaW9CdWZmZXIpIHtcclxuLy8gICAgIHRoaXMuX2F1ZGlvQnVmZmVyID0gdmFsdWU7XHJcbi8vICAgfVxyXG4vLyAgIHByaXZhdGUgX3JlY29yZGluZ0ZpbGVJZDpzdHJpbmcgfCBudW1iZXI7XHJcbi8vICAgcHJpdmF0ZSBfYXVkaW9CdWZmZXI6QXVkaW9CdWZmZXI7XHJcbi8vXHJcbi8vICAgY29uc3RydWN0b3IocmVjb3JkaW5nRmlsZUlkOiBzdHJpbmd8IG51bWJlciwgYXVkaW9CdWZmZXI6QXVkaW9CdWZmZXIpe1xyXG4vLyAgICAgdGhpcy5fcmVjb3JkaW5nRmlsZUlkPXJlY29yZGluZ0ZpbGVJZDtcclxuLy8gICAgIHRoaXMuX2F1ZGlvQnVmZmVyPWF1ZGlvQnVmZmVyO1xyXG4vLyAgIH1cclxuLy9cclxuLy9cclxuLy8gfVxyXG5cclxuZXhwb3J0IGNsYXNzIFJlY29yZGluZ0ZpbGVVdGlsIHtcclxuICBwdWJsaWMgc3RhdGljIHJlY29yZGluZ0FzUGxhaW5UZXh0KHJlY29yZGluZ0ZpbGU6U3ByUmVjb3JkaW5nRmlsZSkge1xyXG4gICAgaWYgKHJlY29yZGluZ0ZpbGUpIHtcclxuICAgICAgbGV0IHIgPSByZWNvcmRpbmdGaWxlLnJlY29yZGluZztcclxuICAgICAgaWYgKHIpIHtcclxuICAgICAgICByZXR1cm4gUHJvbXB0aXRlbVV0aWwudG9QbGFpblRleHRTdHJpbmcocik7XHJcbiAgICAgIH1cclxuICAgIH1cclxuICAgIHJldHVybiBcIm4vYVwiO1xyXG4gIH1cclxuXHJcbiAgcHVibGljIHN0YXRpYyBmcmFtZVBvc0ZvclNhbXBsZVJhdGUoZnJhbWVQb3NTYW1wbGVSYXRlOm51bWJlcnxudWxsLGZyYW1lUG9zOm51bWJlcnxudWxsLHNhbXBsZVJhdGU6bnVtYmVyKTpudW1iZXJ8bnVsbHtcclxuICAgIGxldCBmcEZTcj1udWxsO1xyXG5cclxuICAgIC8vIFRPRE8gdHJhbnNpdGlvbmFsIHVudGlsIGVkaXRTYW1wbGVSYXRlcyBhcmUgc2V0IGluIHRoZSBkYXRhYmFzZVxyXG4gICAgaWYoZnJhbWVQb3NTYW1wbGVSYXRlPT1udWxsKXtcclxuICAgICAgZnJhbWVQb3NTYW1wbGVSYXRlPXNhbXBsZVJhdGU7XHJcbiAgICB9XHJcbiAgICBpZihmcmFtZVBvc1NhbXBsZVJhdGUhPW51bGwgJiYgZnJhbWVQb3MhPW51bGwpIHtcclxuICAgICAgaWYgKGZyYW1lUG9zU2FtcGxlUmF0ZSA9PT0gc2FtcGxlUmF0ZSkge1xyXG4gICAgICAgIGZwRlNyPWZyYW1lUG9zO1xyXG4gICAgICB9IGVsc2Uge1xyXG4gICAgICAgIGZwRlNyPU1hdGgucm91bmQoKGZyYW1lUG9zICogc2FtcGxlUmF0ZSkgLyBmcmFtZVBvc1NhbXBsZVJhdGUpO1xyXG4gICAgICB9XHJcbiAgICB9XHJcbiAgICByZXR1cm4gZnBGU3I7XHJcbiAgfVxyXG5cclxuICBwdWJsaWMgc3RhdGljIGVkaXRTdGFydEZyYW1lRm9yU2FtcGxlUmF0ZShyZWNvcmRpbmdGaWxlOlJlY29yZGluZ0ZpbGUsIHNhbXBsZVJhdGU6bnVtYmVyKTpudW1iZXIgfCBudWxse1xyXG4gICAgbGV0IGVzZmZTcj1SZWNvcmRpbmdGaWxlVXRpbC5mcmFtZVBvc0ZvclNhbXBsZVJhdGUocmVjb3JkaW5nRmlsZS5lZGl0U2FtcGxlUmF0ZSxyZWNvcmRpbmdGaWxlLmVkaXRTdGFydEZyYW1lLHNhbXBsZVJhdGUpO1xyXG4gICAgcmV0dXJuIGVzZmZTcjtcclxuICB9XHJcblxyXG4gIHB1YmxpYyBzdGF0aWMgZWRpdEVuZEZyYW1lRm9yU2FtcGxlUmF0ZShyZWNvcmRpbmdGaWxlOlJlY29yZGluZ0ZpbGUsIHNhbXBsZVJhdGU6bnVtYmVyKTpudW1iZXIgfCBudWxse1xyXG4gICAgbGV0IGVlZmZTcj1SZWNvcmRpbmdGaWxlVXRpbC5mcmFtZVBvc0ZvclNhbXBsZVJhdGUocmVjb3JkaW5nRmlsZS5lZGl0U2FtcGxlUmF0ZSxyZWNvcmRpbmdGaWxlLmVkaXRFbmRGcmFtZSxzYW1wbGVSYXRlKTtcclxuICAgIHJldHVybiBlZWZmU3I7XHJcbiAgfVxyXG59XHJcbiJdfQ==
@@ -0,0 +1,288 @@
1
+ import { Inject, Injectable } from '@angular/core';
2
+ import { HttpHeaders } from "@angular/common/http";
3
+ import { Observable } from "rxjs";
4
+ import { ApiType, SPEECHRECORDER_CONFIG } from "../../../spr.config";
5
+ import { UUID } from "../../../utils/utils";
6
+ import { RecordingFileUtils } from "../../recording";
7
+ import { AudioBufferSource, AudioDataHolder } from "../../../audio/audio_data_holder";
8
+ import { BasicRecordingService } from "../../recordings/basic_recording.service";
9
+ import { AudioContextProvider } from "../../../audio/context";
10
+ import * as i0 from "@angular/core";
11
+ import * as i1 from "@angular/common/http";
12
+ import * as i2 from "../../../spr.config";
13
+ export class RecordingFileService extends BasicRecordingService {
14
+ static { this.RECOFILE_API_CTX = 'recordingfile'; }
15
+ constructor(http, config) {
16
+ super(http, config);
17
+ this.http = http;
18
+ this.config = config;
19
+ //private debugDelay:number=10000;
20
+ this.debugDelay = 0;
21
+ }
22
+ recoFileUrl(recordingFileId) {
23
+ let encRecfileId = encodeURIComponent(recordingFileId);
24
+ let recUrl = this.apiEndPoint + RecordingFileService.RECOFILE_API_CTX + '/' + encRecfileId;
25
+ return recUrl;
26
+ }
27
+ fetchAudiofile(recordingFileId) {
28
+ let recUrl = this.recoFileUrl(recordingFileId);
29
+ if (this.config && this.config.apiType === ApiType.FILES) {
30
+ // for development and demo
31
+ // append UUID to make request URL unique to avoid localhost server caching
32
+ recUrl = recUrl + '.wav';
33
+ }
34
+ let headers = new HttpHeaders({
35
+ 'Accept': 'audio/wav'
36
+ });
37
+ return this.http.get(recUrl, {
38
+ observe: 'response',
39
+ headers: headers,
40
+ responseType: 'arraybuffer',
41
+ withCredentials: this.withCredentials
42
+ });
43
+ }
44
+ recordingFileDescrObserver(recordingFileId) {
45
+ let recUrl = this.recoFileUrl(recordingFileId);
46
+ if (this.config && this.config.apiType === ApiType.FILES) {
47
+ // for development and demo
48
+ // append UUID to make request URL unique to avoid localhost server caching
49
+ recUrl = recUrl + '.json?requestUUID=' + UUID.generate();
50
+ }
51
+ return this.http.get(recUrl, { withCredentials: this.withCredentials });
52
+ }
53
+ sprRecordingFileDescrObserver(recordingFileId) {
54
+ let recUrl = this.recoFileUrl(recordingFileId);
55
+ if (this.config && this.config.apiType === ApiType.FILES) {
56
+ // for development and demo
57
+ // append UUID to make request URL unique to avoid localhost server caching
58
+ recUrl = recUrl + '.json?requestUUID=' + UUID.generate();
59
+ }
60
+ return this.http.get(recUrl, { withCredentials: this.withCredentials });
61
+ }
62
+ fetchSessionAudiofileById(projectName, sessId, recordingFileId) {
63
+ let recUrl = this.recoFileUrl(recordingFileId);
64
+ // if (this.config && this.config.apiType === ApiType.FILES) {
65
+ // // for development and demo
66
+ // // append UUID to make request URL unique to avoid localhost server caching
67
+ // recUrl = recUrl + '.wav?requestUUID=' + UUID.generate();
68
+ // }
69
+ return this.http.get(recUrl, {
70
+ observe: 'response',
71
+ responseType: 'arraybuffer',
72
+ withCredentials: this.withCredentials
73
+ });
74
+ }
75
+ // TODO test
76
+ fetchAndApplyRecordingFile(recordingFile) {
77
+ let wobs = new Observable(observer => {
78
+ if (recordingFile.recordingFileId) {
79
+ let obs = this.fetchAudiofile(recordingFile.recordingFileId);
80
+ obs.subscribe({ next: resp => {
81
+ if (resp.body) {
82
+ AudioContextProvider.decodeAudioData(resp.body).then(ab => {
83
+ let as = new AudioBufferSource(ab);
84
+ RecordingFileUtils.setAudioData(recordingFile, new AudioDataHolder(as));
85
+ if (this.debugDelay > 0) {
86
+ window.setTimeout(() => {
87
+ observer.next(recordingFile);
88
+ observer.complete();
89
+ }, this.debugDelay);
90
+ }
91
+ else {
92
+ observer.next(recordingFile);
93
+ observer.complete();
94
+ }
95
+ }).catch(reason => { observer.error(reason); });
96
+ }
97
+ else {
98
+ observer.error('Received no audio data!');
99
+ }
100
+ },
101
+ error: (error) => {
102
+ if (error.status == 404) {
103
+ // Interpret not as an error, the file ist not recorded yet
104
+ observer.next(null);
105
+ observer.complete();
106
+ }
107
+ else {
108
+ // all other states are errors
109
+ observer.error(error);
110
+ observer.complete();
111
+ }
112
+ }
113
+ });
114
+ }
115
+ else {
116
+ observer.error();
117
+ }
118
+ });
119
+ return wobs;
120
+ }
121
+ fetchRecordingFile(aCtx, recordingFileId) {
122
+ let wobs = new Observable(observer => {
123
+ let rf = null;
124
+ let rfDescrObs = this.recordingFileDescrObserver(recordingFileId);
125
+ rfDescrObs.subscribe({ next: value => {
126
+ rf = value;
127
+ }, error: (error) => {
128
+ observer.error(error);
129
+ }, complete: () => {
130
+ let rfAudioObs = this.fetchAudiofile(recordingFileId);
131
+ rfAudioObs.subscribe({
132
+ next: resp => {
133
+ // Do not use Promise version, which does not work with Safari 13
134
+ if (resp.body) {
135
+ AudioContextProvider.decodeAudioData(resp.body).then(ab => {
136
+ if (rf) {
137
+ let as = new AudioBufferSource(ab);
138
+ RecordingFileUtils.setAudioData(rf, new AudioDataHolder(as));
139
+ }
140
+ else {
141
+ observer.error('Recording file object null');
142
+ }
143
+ if (this.debugDelay > 0) {
144
+ window.setTimeout(() => {
145
+ observer.next(rf);
146
+ observer.complete();
147
+ }, this.debugDelay);
148
+ }
149
+ else {
150
+ observer.next(rf);
151
+ observer.complete();
152
+ }
153
+ }).catch(reason => { observer.error(reason); });
154
+ }
155
+ else {
156
+ observer.error('Received no audio data');
157
+ }
158
+ },
159
+ error: (error) => {
160
+ if (error.status == 404) {
161
+ // Interpret not as an error, the file ist not recorded yet
162
+ observer.next(null);
163
+ observer.complete();
164
+ }
165
+ else {
166
+ // all other states are errors
167
+ observer.error(error);
168
+ observer.complete();
169
+ }
170
+ }
171
+ });
172
+ }
173
+ });
174
+ });
175
+ return wobs;
176
+ }
177
+ fetchSprRecordingFile(recordingFileId) {
178
+ let wobs = new Observable(observer => {
179
+ let rf = null;
180
+ let rfDescrObs = this.sprRecordingFileDescrObserver(recordingFileId);
181
+ rfDescrObs.subscribe({ next: value => {
182
+ rf = value;
183
+ },
184
+ error: (error) => {
185
+ observer.error(error);
186
+ }, complete: () => {
187
+ let sampleCnt = null;
188
+ if (rf && rf.channels && rf.frames) {
189
+ sampleCnt = rf.channels * rf.frames;
190
+ }
191
+ // TODO use download storage type depending on sample count of file
192
+ if (rf && rf.samplerate && sampleCnt != null && sampleCnt > this._maxAutoNetMemStoreSamples) {
193
+ const baseUrl = this.recoFileUrl(recordingFileId);
194
+ const obNetAb = this.chunkAudioRequestToNetAudioBuffer(baseUrl, 0, rf?.samplerate, BasicRecordingService.DEFAULT_CHUNKED_DOWNLOAD_SECONDS, rf.frames);
195
+ obNetAb.subscribe({
196
+ next: (nab) => {
197
+ let adh = new AudioDataHolder(nab);
198
+ if (rf) {
199
+ RecordingFileUtils.setAudioData(rf, adh);
200
+ observer.next(rf);
201
+ }
202
+ },
203
+ complete: () => {
204
+ observer.complete();
205
+ },
206
+ error: (error) => {
207
+ if (error.status == 404) {
208
+ // Interpret not as an error, the file ist not recorded yet
209
+ observer.next(null);
210
+ observer.complete();
211
+ }
212
+ else {
213
+ // all other states are errors
214
+ observer.error(error);
215
+ observer.complete();
216
+ }
217
+ }
218
+ });
219
+ }
220
+ else {
221
+ let rfAudioObs = this.fetchAudiofile(recordingFileId);
222
+ rfAudioObs.subscribe({ next: resp => {
223
+ // Do not use Promise version, which does not work with Safari 13
224
+ if (resp.body) {
225
+ AudioContextProvider.decodeAudioData(resp.body).then(ab => {
226
+ if (rf) {
227
+ let as = new AudioBufferSource(ab);
228
+ let adh = new AudioDataHolder(as);
229
+ RecordingFileUtils.setAudioData(rf, adh);
230
+ }
231
+ else {
232
+ observer.error('Recording file object null');
233
+ }
234
+ if (this.debugDelay > 0) {
235
+ window.setTimeout(() => {
236
+ observer.next(rf);
237
+ observer.complete();
238
+ }, this.debugDelay);
239
+ }
240
+ else {
241
+ observer.next(rf);
242
+ observer.complete();
243
+ }
244
+ }).catch(reason => { observer.error(reason); });
245
+ }
246
+ else {
247
+ observer.error('Received no audio data');
248
+ }
249
+ },
250
+ error: (error) => {
251
+ if (error.status == 404) {
252
+ // Interpret not as an error, the file ist not recorded yet
253
+ observer.next(null);
254
+ observer.complete();
255
+ }
256
+ else {
257
+ // all other states are errors
258
+ observer.error(error);
259
+ observer.complete();
260
+ }
261
+ }
262
+ });
263
+ }
264
+ }
265
+ });
266
+ });
267
+ return wobs;
268
+ }
269
+ saveEditSelection(recordingFileId, editSampleRate, editStartFrame, editEndFrame) {
270
+ let recUrl = this.apiEndPoint + RecordingFileService.RECOFILE_API_CTX + '/' + recordingFileId;
271
+ if (this.config && this.config.apiType === ApiType.FILES) {
272
+ // for development and demo
273
+ // append UUID to make request URL unique to avoid localhost server caching
274
+ recUrl = recUrl + '.json?requestUUID=' + UUID.generate();
275
+ }
276
+ //console.log("Path request URL: "+recUrl)
277
+ return this.http.patch(recUrl, { editSampleRate: editSampleRate, editStartFrame: editStartFrame, editEndFrame: editEndFrame }, { withCredentials: this.withCredentials });
278
+ }
279
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.0.6", ngImport: i0, type: RecordingFileService, deps: [{ token: i1.HttpClient }, { token: SPEECHRECORDER_CONFIG }], target: i0.ɵɵFactoryTarget.Injectable }); }
280
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "17.0.6", ngImport: i0, type: RecordingFileService }); }
281
+ }
282
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.0.6", ngImport: i0, type: RecordingFileService, decorators: [{
283
+ type: Injectable
284
+ }], ctorParameters: () => [{ type: i1.HttpClient }, { type: i2.SpeechRecorderConfig, decorators: [{
285
+ type: Inject,
286
+ args: [SPEECHRECORDER_CONFIG]
287
+ }] }] });
288
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicmVjb3JkaW5nZmlsZS1zZXJ2aWNlLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vLi4vLi4vcHJvamVjdHMvc3BlZWNocmVjb3JkZXJuZy9zcmMvbGliL3NwZWVjaHJlY29yZGVyL3Nlc3Npb24vcmVjb3JkaW5nZmlsZS9yZWNvcmRpbmdmaWxlLXNlcnZpY2UudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFDLE1BQU0sRUFBRSxVQUFVLEVBQUMsTUFBTSxlQUFlLENBQUM7QUFDakQsT0FBTyxFQUFnQyxXQUFXLEVBQWUsTUFBTSxzQkFBc0IsQ0FBQztBQUc5RixPQUFPLEVBQUMsVUFBVSxFQUFDLE1BQU0sTUFBTSxDQUFDO0FBR2hDLE9BQU8sRUFBQyxPQUFPLEVBQUUscUJBQXFCLEVBQXVCLE1BQU0scUJBQXFCLENBQUM7QUFDekYsT0FBTyxFQUFDLElBQUksRUFBQyxNQUFNLHNCQUFzQixDQUFDO0FBQzFDLE9BQU8sRUFBZ0Isa0JBQWtCLEVBQW1CLE1BQU0saUJBQWlCLENBQUM7QUFDcEYsT0FBTyxFQUFDLGlCQUFpQixFQUFFLGVBQWUsRUFBQyxNQUFNLGtDQUFrQyxDQUFDO0FBQ3BGLE9BQU8sRUFBQyxxQkFBcUIsRUFBQyxNQUFNLDBDQUEwQyxDQUFDO0FBQy9FLE9BQU8sRUFBQyxvQkFBb0IsRUFBQyxNQUFNLHdCQUF3QixDQUFDOzs7O0FBSTVELE1BQU0sT0FBTyxvQkFBcUIsU0FBUSxxQkFBcUI7YUFFdEMscUJBQWdCLEdBQUcsZUFBZSxBQUFsQixDQUFrQjtJQUt6RCxZQUFzQixJQUFnQixFQUEyQyxNQUE2QjtRQUMxRyxLQUFLLENBQUMsSUFBSSxFQUFDLE1BQU0sQ0FBQyxDQUFDO1FBREQsU0FBSSxHQUFKLElBQUksQ0FBWTtRQUEyQyxXQUFNLEdBQU4sTUFBTSxDQUF1QjtRQUg5RyxrQ0FBa0M7UUFDMUIsZUFBVSxHQUFRLENBQUMsQ0FBQztJQUk1QixDQUFDO0lBRU8sV0FBVyxD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ZXNDb250ZW50IjpbImltcG9ydCB7SW5qZWN0LCBJbmplY3RhYmxlfSBmcm9tICdAYW5ndWxhci9jb3JlJztcclxuaW1wb3J0IHtIdHRwQ2xpZW50LCBIdHRwRXJyb3JSZXNwb25zZSwgSHR0cEhlYWRlcnMsIEh0dHBSZXNwb25zZX0gZnJvbSBcIkBhbmd1bGFyL2NvbW1vbi9odHRwXCI7XHJcblxyXG5cclxuaW1wb3J0IHtPYnNlcnZhYmxlfSBmcm9tIFwicnhqc1wiO1xyXG5cclxuXHJcbmltcG9ydCB7QXBpVHlwZSwgU1BFRUNIUkVDT1JERVJfQ09ORklHLCBTcGVlY2hSZWNvcmRlckNvbmZpZ30gZnJvbSBcIi4uLy4uLy4uL3Nwci5jb25maWdcIjtcclxuaW1wb3J0IHtVVUlEfSBmcm9tIFwiLi4vLi4vLi4vdXRpbHMvdXRpbHNcIjtcclxuaW1wb3J0IHtSZWNvcmRpbmdGaWxlLCBSZWNvcmRpbmdGaWxlVXRpbHMsIFNwclJlY29yZGluZ0ZpbGV9IGZyb20gXCIuLi8uLi9yZWNvcmRpbmdcIjtcclxuaW1wb3J0IHtBdWRpb0J1ZmZlclNvdXJjZSwgQXVkaW9EYXRhSG9sZGVyfSBmcm9tIFwiLi4vLi4vLi4vYXVkaW8vYXVkaW9fZGF0YV9ob2xkZXJcIjtcclxuaW1wb3J0IHtCYXNpY1JlY29yZGluZ1NlcnZpY2V9IGZyb20gXCIuLi8uLi9yZWNvcmRpbmdzL2Jhc2ljX3JlY29yZGluZy5zZXJ2aWNlXCI7XHJcbmltcG9ydCB7QXVkaW9Db250ZXh0UHJvdmlkZXJ9IGZyb20gXCIuLi8uLi8uLi9hdWRpby9jb250ZXh0XCI7XHJcblxyXG5cclxuQEluamVjdGFibGUoKVxyXG5leHBvcnQgY2xhc3MgUmVjb3JkaW5nRmlsZVNlcnZpY2UgZXh0ZW5kcyBCYXNpY1JlY29yZGluZ1NlcnZpY2V7XHJcblxyXG4gIHB1YmxpYyBzdGF0aWMgcmVhZG9ubHkgUkVDT0ZJTEVfQVBJX0NUWCA9ICdyZWNvcmRpbmdmaWxlJ1xyXG5cclxuICAvL3ByaXZhdGUgZGVidWdEZWxheTpudW1iZXI9MTAwMDA7XHJcbiAgcHJpdmF0ZSBkZWJ1Z0RlbGF5Om51bWJlcj0wO1xyXG5cclxuICBjb25zdHJ1Y3Rvcihwcm90ZWN0ZWQgaHR0cDogSHR0cENsaWVudCwgQEluamVjdChTUEVFQ0hSRUNPUkRFUl9DT05GSUcpIHByb3RlY3RlZCBjb25maWc/OiBTcGVlY2hSZWNvcmRlckNvbmZpZykge1xyXG4gICAgICBzdXBlcihodHRwLGNvbmZpZyk7XHJcbiAgfVxyXG5cclxuICBwcml2YXRlIHJlY29GaWxlVXJsKHJlY29yZGluZ0ZpbGVJZDogc3RyaW5nIHwgbnVtYmVyKTpzdHJpbmd7XHJcbiAgICBsZXQgZW5jUmVjZmlsZUlkPWVuY29kZVVSSUNvbXBvbmVudChyZWNvcmRpbmdGaWxlSWQpO1xyXG4gICAgbGV0IHJlY1VybCA9IHRoaXMuYXBpRW5kUG9pbnQgKyBSZWNvcmRpbmdGaWxlU2VydmljZS5SRUNPRklMRV9BUElfQ1RYICsgJy8nICsgZW5jUmVjZmlsZUlkO1xyXG5cclxuICAgIHJldHVybiByZWNVcmw7XHJcbiAgfVxyXG5cclxuICBwcml2YXRlIGZldGNoQXVkaW9maWxlKHJlY29yZGluZ0ZpbGVJZDogc3RyaW5nIHwgbnVtYmVyKTogT2JzZXJ2YWJsZTxIdHRwUmVzcG9uc2U8QXJyYXlCdWZmZXI+PiB7XHJcbiAgICBsZXQgcmVjVXJsID0gdGhpcy5yZWNvRmlsZVVybChyZWNvcmRpbmdGaWxlSWQpO1xyXG4gICAgaWYgKHRoaXMuY29uZmlnICYmIHRoaXMuY29uZmlnLmFwaVR5cGUgPT09IEFwaVR5cGUuRklMRVMpIHtcclxuICAgICAgLy8gZm9yIGRldmVsb3BtZW50IGFuZCBkZW1vXHJcbiAgICAgIC8vIGFwcGVuZCBVVUlEIHRvIG1ha2UgcmVxdWVzdCBVUkwgdW5pcXVlIHRvIGF2b2lkIGxvY2FsaG9zdCBzZXJ2ZXIgY2FjaGluZ1xyXG4gICAgICByZWNVcmwgPSByZWNVcmwgKyAnLndhdic7XHJcbiAgICB9XHJcbiAgICBsZXQgaGVhZGVycyA9IG5ldyBIdHRwSGVhZGVycyh7XHJcbiAgICAgICdBY2NlcHQnOiAnYXVkaW8vd2F2J1xyXG4gICAgfSk7XHJcblxyXG4gICAgcmV0dXJuIHRoaXMuaHR0cC5nZXQocmVjVXJsLCB7XHJcbiAgICAgIG9ic2VydmU6ICdyZXNwb25zZScsXHJcbiAgICAgIGhlYWRlcnM6IGhlYWRlcnMsXHJcbiAgICAgIHJlc3BvbnNlVHlwZTogJ2FycmF5YnVmZmVyJyxcclxuICAgICAgd2l0aENyZWRlbnRpYWxzOiB0aGlzLndpdGhDcmVkZW50aWFsc1xyXG4gICAgfSk7XHJcbiAgfVxyXG5cclxuICBwcml2YXRlIHJlY29yZGluZ0ZpbGVEZXNjck9ic2VydmVyKHJlY29yZGluZ0ZpbGVJZDogc3RyaW5nIHwgbnVtYmVyKTogT2JzZXJ2YWJsZTxSZWNvcmRpbmdGaWxlPiB7XHJcblxyXG4gICAgbGV0IHJlY1VybCA9IHRoaXMucmVjb0ZpbGVVcmwocmVjb3JkaW5nRmlsZUlkKTtcclxuICAgIGlmICh0aGlzLmNvbmZpZyAmJiB0aGlzLmNvbmZpZy5hcGlUeXBlID09PSBBcGlUeXBlLkZJTEVTKSB7XHJcbiAgICAgIC8vIGZvciBkZXZlbG9wbWVudCBhbmQgZGVtb1xyXG4gICAgICAvLyBhcHBlbmQgVVVJRCB0byBtYWtlIHJlcXVlc3QgVVJMIHVuaXF1ZSB0byBhdm9pZCBsb2NhbGhvc3Qgc2VydmVyIGNhY2hpbmdcclxuICAgICAgcmVjVXJsID0gcmVjVXJsICsgJy5qc29uP3JlcXVlc3RVVUlEPScrVVVJRC5nZW5lcmF0ZSgpO1xyXG4gICAgfVxyXG4gICAgcmV0dXJuIHRoaXMuaHR0cC5nZXQ8UmVjb3JkaW5nRmlsZT4ocmVjVXJsLHsgd2l0aENyZWRlbnRpYWxzOiB0aGlzLndpdGhDcmVkZW50aWFscyB9KTtcclxuICB9XHJcblxyXG4gIHByaXZhdGUgc3ByUmVjb3JkaW5nRmlsZURlc2NyT2JzZXJ2ZXIocmVjb3JkaW5nRmlsZUlkOiBzdHJpbmcgfCBudW1iZXIpOiBPYnNlcnZhYmxlPFNwclJlY29yZGluZ0ZpbGU+IHtcclxuXHJcbiAgICBsZXQgcmVjVXJsID0gdGhpcy5yZWNvRmlsZVVybChyZWNvcmRpbmdGaWxlSWQpO1xyXG4gICAgaWYgKHRoaXMuY29uZmlnICYmIHRoaXMuY29uZmlnLmFwaVR5cGUgPT09IEFwaVR5cGUuRklMRVMpIHtcclxuICAgICAgLy8gZm9yIGRldmVsb3BtZW50IGFuZCBkZW1vXHJcbiAgICAgIC8vIGFwcGVuZCBVVUlEIHRvIG1ha2UgcmVxdWVzdCBVUkwgdW5pcXVlIHRvIGF2b2lkIGxvY2FsaG9zdCBzZXJ2ZXIgY2FjaGluZ1xyXG4gICAgICByZWNVcmwgPSByZWNVcmwgKyAnLmpzb24/cmVxdWVzdFVVSUQ9JytVVUlELmdlbmVyYXRlKCk7XHJcbiAgICB9XHJcbiAgICByZXR1cm4gdGhpcy5odHRwLmdldDxTcHJSZWNvcmRpbmdGaWxlPihyZWNVcmwseyB3aXRoQ3JlZGVudGlhbHM6IHRoaXMud2l0aENyZWRlbnRpYWxzIH0pO1xyXG4gIH1cclxuXHJcblxyXG4gIHByaXZhdGUgZmV0Y2hTZXNzaW9uQXVkaW9maWxlQnlJZChwcm9qZWN0TmFtZTogc3RyaW5nLCBzZXNzSWQ6IHN0cmluZyB8IG51bWJlciwgcmVjb3JkaW5nRmlsZUlkOiBzdHJpbmcgfCBudW1iZXIpOiBPYnNlcnZhYmxlPEh0dHBSZXNwb25zZTxBcnJheUJ1ZmZlcj4+IHtcclxuXHJcbiAgICBsZXQgcmVjVXJsID0gdGhpcy5yZWNvRmlsZVVybChyZWNvcmRpbmdGaWxlSWQpO1xyXG4gICAgLy8gaWYgKHRoaXMuY29uZmlnICYmIHRoaXMuY29uZmlnLmFwaVR5cGUgPT09IEFwaVR5cGUuRklMRVMpIHtcclxuICAgIC8vICAgLy8gZm9yIGRldmVsb3BtZW50IGFuZCBkZW1vXHJcbiAgICAvLyAgIC8vIGFwcGVuZCBVVUlEIHRvIG1ha2UgcmVxdWVzdCBVUkwgdW5pcXVlIHRvIGF2b2lkIGxvY2FsaG9zdCBzZXJ2ZXIgY2FjaGluZ1xyXG4gICAgLy8gICByZWNVcmwgPSByZWNVcmwgKyAnLndhdj9yZXF1ZXN0VVVJRD0nICsgVVVJRC5nZW5lcmF0ZSgpO1xyXG4gICAgLy8gfVxyXG4gICAgcmV0dXJuIHRoaXMuaHR0cC5nZXQocmVjVXJsLCB7XHJcbiAgICAgIG9ic2VydmU6ICdyZXNwb25zZScsXHJcbiAgICAgIHJlc3BvbnNlVHlwZTogJ2FycmF5YnVmZmVyJyxcclxuICAgICAgd2l0aENyZWRlbnRpYWxzOiB0aGlzLndpdGhDcmVkZW50aWFsc1xyXG4gICAgfSk7XHJcbiAgfVxyXG5cclxuXHJcbiAgLy8gVE9ETyB0ZXN0XHJcblxyXG4gIGZldGNoQW5kQXBwbHlSZWNvcmRpbmdGaWxlKHJlY29yZGluZ0ZpbGU6U3ByUmVjb3JkaW5nRmlsZSk6T2JzZXJ2YWJsZTxTcHJSZWNvcmRpbmdGaWxlfG51bGw+IHtcclxuXHJcbiAgICBsZXQgd29icyA9IG5ldyBPYnNlcnZhYmxlPFNwclJlY29yZGluZ0ZpbGV8bnVsbD4ob2JzZXJ2ZXI9PntcclxuICAgICAgaWYocmVjb3JkaW5nRmlsZS5yZWNvcmRpbmdGaWxlSWQpIHtcclxuICAgICAgICBsZXQgb2JzID0gdGhpcy5mZXRjaEF1ZGlvZmlsZShyZWNvcmRpbmdGaWxlLnJlY29yZGluZ0ZpbGVJZCk7XHJcblxyXG4gICAgICAgIG9icy5zdWJzY3JpYmUoXHJcbiAgICAgICAgICAgIHtuZXh0OnJlc3AgPT4ge1xyXG4gICAgICAgICAgICAgIGlmKHJlc3AuYm9keSkge1xyXG4gICAgICAgICAgICAgICAgQXVkaW9Db250ZXh0UHJvdmlkZXIuZGVjb2RlQXVkaW9EYXRhKHJlc3AuYm9keSkudGhlbihhYiA9PiB7XHJcbiAgICAgICAgICAgICAgICAgIGxldCBhcz1uZXcgQXVkaW9CdWZmZXJTb3VyY2UoYWIpO1xyXG4gICAgICAgICAgICAgICAgICBSZWNvcmRpbmdGaWxlVXRpbHMuc2V0QXVkaW9EYXRhKHJlY29yZGluZ0ZpbGUsbmV3IEF1ZGlvRGF0YUhvbGRlcihhcykpO1xyXG4gICAgICAgICAgICAgICAgICBpZiAodGhpcy5kZWJ1Z0RlbGF5ID4gMCkge1xyXG4gICAgICAgICAgICAgICAgICAgIHdpbmRvdy5zZXRUaW1lb3V0KCgpID0+IHtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICBvYnNlcnZlci5uZXh0KHJlY29yZGluZ0ZpbGUpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgb2JzZXJ2ZXIuY29tcGxldGUoKTtcclxuICAgICAgICAgICAgICAgICAgICB9LCB0aGlzLmRlYnVnRGVsYXkpO1xyXG4gICAgICAgICAgICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgICAgIG9ic2VydmVyLm5leHQocmVjb3JkaW5nRmlsZSk7XHJcbiAgICAgICAgICAgICAgICAgICAgb2JzZXJ2ZXIuY29tcGxldGUoKTtcclxuICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgfSkuY2F0Y2gocmVhc29uPT57b2JzZXJ2ZXIuZXJyb3IocmVhc29uKX0pO1xyXG4gICAgICAgICAgICAgIH1lbHNle1xyXG4gICAgICAgICAgICAgICAgb2JzZXJ2ZXIuZXJyb3IoJ1JlY2VpdmVkIG5vIGF1ZGlvIGRhdGEhJyk7XHJcbiAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB9LFxyXG4gICAgICAgICAgICBlcnJvcjooZXJyb3I6IEh0dHBFcnJvclJlc3BvbnNlKSA9PiB7XHJcbiAgICAgICAgICAgICAgaWYgKGVycm9yLnN0YXR1cyA9PSA0MDQpIHtcclxuICAgICAgICAgICAgICAgIC8vIEludGVycHJldCBub3QgYXMgYW4gZXJyb3IsIHRoZSBmaWxlIGlzdCBub3QgcmVjb3JkZWQgeWV0XHJcbiAgICAgICAgICAgICAgICBvYnNlcnZlci5uZXh0KG51bGwpO1xyXG4gICAgICAgICAgICAgICAgb2JzZXJ2ZXIuY29tcGxldGUoKVxyXG4gICAgICAgICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgICAgICAvLyBhbGwgb3RoZXIgc3RhdGVzIGFyZSBlcnJvcnNcclxuICAgICAgICAgICAgICAgIG9ic2VydmVyLmVycm9yKGVycm9yKTtcclxuICAgICAgICAgICAgICAgIG9ic2VydmVyLmNvbXBsZXRlKCk7XHJcbiAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB9XHJcbiAgICAgIH0pO1xyXG4gICAgICB9ZWxzZXtcclxuICAgICAgICBvYnNlcnZlci5lcnJvcigpO1xyXG4gICAgICB9XHJcbiAgICB9KTtcclxuXHJcbiAgICByZXR1cm4gd29icztcclxuICB9XHJcblxyXG4gIGZldGNoUmVjb3JkaW5nRmlsZShhQ3R4OiBBdWRpb0NvbnRleHQsIHJlY29yZGluZ0ZpbGVJZDogc3RyaW5nIHwgbnVtYmVyKTogT2JzZXJ2YWJsZTxSZWNvcmRpbmdGaWxlIHwgbnVsbD4ge1xyXG5cclxuICAgIGxldCB3b2JzID0gbmV3IE9ic2VydmFibGU8UmVjb3JkaW5nRmlsZSB8IG51bGw+KG9ic2VydmVyID0+IHtcclxuICAgICAgbGV0IHJmOiBSZWNvcmRpbmdGaWxlfG51bGwgPSBudWxsO1xyXG4gICAgICBsZXQgcmZEZXNjck9icyA9IHRoaXMucmVjb3JkaW5nRmlsZURlc2NyT2JzZXJ2ZXIocmVjb3JkaW5nRmlsZUlkKTtcclxuICAgICAgcmZEZXNjck9icy5zdWJzY3JpYmUoXHJcbiAgICAgICAgICB7bmV4dDp2YWx1ZSA9PiB7XHJcbiAgICAgICAgcmYgPSB2YWx1ZTtcclxuICAgICAgfSwgZXJyb3I6KGVycm9yKSA9PiB7XHJcbiAgICAgICAgb2JzZXJ2ZXIuZXJyb3IoZXJyb3IpO1xyXG4gICAgICB9LCBjb21wbGV0ZTooKSA9PiB7XHJcbiAgICAgICAgbGV0IHJmQXVkaW9PYnMgPSB0aGlzLmZldGNoQXVkaW9maWxlKHJlY29yZGluZ0ZpbGVJZCk7XHJcbiAgICAgICAgcmZBdWRpb09icy5zdWJzY3JpYmUoe1xyXG4gICAgICAgICAgbmV4dDogcmVzcCA9PiB7XHJcbiAgICAgICAgICAgIC8vIERvIG5vdCB1c2UgUHJvbWlzZSB2ZXJzaW9uLCB3aGljaCBkb2VzIG5vdCB3b3JrIHdpdGggU2FmYXJpIDEzXHJcbiAgICAgICAgICAgIGlmIChyZXNwLmJvZHkpIHtcclxuICAgICAgICAgICAgICBBdWRpb0NvbnRleHRQcm92aWRlci5kZWNvZGVBdWRpb0RhdGEocmVzcC5ib2R5KS50aGVuKCBhYiA9PiB7XHJcbiAgICAgICAgICAgICAgICBpZiAocmYpIHtcclxuICAgICAgICAgICAgICAgICAgbGV0IGFzID0gbmV3IEF1ZGlvQnVmZmVyU291cmNlKGFiKTtcclxuICAgICAgICAgICAgICAgICAgUmVjb3JkaW5nRmlsZVV0aWxzLnNldEF1ZGlvRGF0YShyZiwgbmV3IEF1ZGlvRGF0YUhvbGRlcihhcykpO1xyXG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgICAgICAgb2JzZXJ2ZXIuZXJyb3IoJ1JlY29yZGluZyBmaWxlIG9iamVjdCBudWxsJyk7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICBpZiAodGhpcy5kZWJ1Z0RlbGF5ID4gMCkge1xyXG4gICAgICAgICAgICAgICAgICB3aW5kb3cuc2V0VGltZW91dCgoKSA9PiB7XHJcbiAgICAgICAgICAgICAgICAgICAgb2JzZXJ2ZXIubmV4dChyZik7XHJcbiAgICAgICAgICAgICAgICAgICAgb2JzZXJ2ZXIuY29tcGxldGUoKTtcclxuICAgICAgICAgICAgICAgICAgfSwgdGhpcy5kZWJ1Z0RlbGF5KTtcclxuICAgICAgICAgICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgICAgICAgIG9ic2VydmVyLm5leHQocmYpO1xyXG4gICAgICAgICAgICAgICAgICBvYnNlcnZlci5jb21wbGV0ZSgpO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgIH0pLmNhdGNoKHJlYXNvbiA9PiB7b2JzZXJ2ZXIuZXJyb3IocmVhc29uKX0pO1xyXG4gICAgICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICAgIG9ic2VydmVyLmVycm9yKCdSZWNlaXZlZCBubyBhdWRpbyBkYXRhJyk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgIH0sXHJcbiAgICAgICAgICBlcnJvcjogKGVycm9yOiBIdHRwRXJyb3JSZXNwb25zZSkgPT4ge1xyXG4gICAgICAgICAgICBpZiAoZXJyb3Iuc3RhdHVzID09IDQwNCkge1xyXG4gICAgICAgICAgICAgIC8vIEludGVycHJldCBub3QgYXMgYW4gZXJyb3IsIHRoZSBmaWxlIGlzdCBub3QgcmVjb3JkZWQgeWV0XHJcbiAgICAgICAgICAgICAgb2JzZXJ2ZXIubmV4dChudWxsKTtcclxuICAgICAgICAgICAgICBvYnNlcnZlci5jb21wbGV0ZSgpXHJcbiAgICAgICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgICAgLy8gYWxsIG90aGVyIHN0YXRlcyBhcmUgZXJyb3JzXHJcbiAgICAgICAgICAgICAgb2JzZXJ2ZXIuZXJyb3IoZXJyb3IpO1xyXG4gICAgICAgICAgICAgIG9ic2VydmVyLmNvbXBsZXRlKCk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgIH1cclxuICAgICAgICB9KTtcclxuICAgICAgICB9XHJcbiAgICAgIH0pO1xyXG4gICAgfSk7XHJcblxyXG4gICAgcmV0dXJuIHdvYnM7XHJcbiAgfVxyXG5cclxuICBmZXRjaFNwclJlY29yZGluZ0ZpbGUoIHJlY29yZGluZ0ZpbGVJZDogc3RyaW5nIHwgbnVtYmVyKTogT2JzZXJ2YWJsZTxTcHJSZWNvcmRpbmdGaWxlIHwgbnVsbD4ge1xyXG5cclxuICAgIGxldCB3b2JzID0gbmV3IE9ic2VydmFibGU8U3ByUmVjb3JkaW5nRmlsZSB8IG51bGw+KG9ic2VydmVyID0+IHtcclxuICAgICAgbGV0IHJmOiBTcHJSZWNvcmRpbmdGaWxlfG51bGwgPSBudWxsO1xyXG4gICAgICBsZXQgcmZEZXNjck9icyA9IHRoaXMuc3ByUmVjb3JkaW5nRmlsZURlc2NyT2JzZXJ2ZXIocmVjb3JkaW5nRmlsZUlkKTtcclxuICAgICAgcmZEZXNjck9icy5zdWJzY3JpYmUoe25leHQ6dmFsdWUgPT4ge1xyXG4gICAgICAgIHJmID0gdmFsdWU7XHJcbiAgICAgIH1cclxuICAgICwgZXJyb3I6KGVycm9yKSA9PiB7XHJcbiAgICAgICAgb2JzZXJ2ZXIuZXJyb3IoZXJyb3IpO1xyXG4gICAgICB9LCBjb21wbGV0ZTooKSA9PiB7XHJcbiAgICAgICAgbGV0IHNhbXBsZUNudDogbnVtYmVyIHwgbnVsbCA9IG51bGw7XHJcbiAgICAgICAgaWYgKHJmICYmIHJmLmNoYW5uZWxzICYmIHJmLmZyYW1lcykge1xyXG4gICAgICAgICAgc2FtcGxlQ250ID0gcmYuY2hhbm5lbHMgKiByZi5mcmFtZXM7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIC8vIFRPRE8gdXNlIGRvd25sb2FkIHN0b3JhZ2UgdHlwZSBkZXBlbmRpbmcgb24gc2FtcGxlIGNvdW50IG9mIGZpbGVcclxuICAgICAgICBpZiAocmYgJiYgcmYuc2FtcGxlcmF0ZSAmJiBzYW1wbGVDbnQgIT0gbnVsbCAmJiBzYW1wbGVDbnQgPiB0aGlzLl9tYXhBdXRvTmV0TWVtU3RvcmVTYW1wbGVzKSB7XHJcbiAgICAgICAgICBjb25zdCBiYXNlVXJsID0gdGhpcy5yZWNvRmlsZVVybChyZWNvcmRpbmdGaWxlSWQpO1xyXG4gICAgICAgICAgY29uc3Qgb2JOZXRBYiA9IHRoaXMuY2h1bmtBdWRpb1JlcXVlc3RUb05ldEF1ZGlvQnVmZmVyKGJhc2VVcmwsIDAsIHJmPy5zYW1wbGVyYXRlLCBCYXNpY1JlY29yZGluZ1NlcnZpY2UuREVGQVVMVF9DSFVOS0VEX0RPV05MT0FEX1NFQ09ORFMsIHJmLmZyYW1lcyk7XHJcbiAgICAgICAgICBvYk5ldEFiLnN1YnNjcmliZShcclxuICAgICAgICAgICAgICB7XHJcbiAgICAgICAgICAgICAgICBuZXh0OiAobmFiKSA9PiB7XHJcbiAgICAgICAgICAgICAgICAgIGxldCBhZGggPSBuZXcgQXVkaW9EYXRhSG9sZGVyKG5hYik7XHJcbiAgICAgICAgICAgICAgICAgIGlmIChyZikge1xyXG4gICAgICAgICAgICAgICAgICAgIFJlY29yZGluZ0ZpbGVVdGlscy5zZXRBdWRpb0RhdGEocmYsIGFkaCk7XHJcbiAgICAgICAgICAgICAgICAgICAgb2JzZXJ2ZXIubmV4dChyZik7XHJcbiAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIH0sXHJcbiAgICAgICAgICAgICAgICBjb21wbGV0ZTogKCkgPT4ge1xyXG4gICAgICAgICAgICAgICAgICBvYnNlcnZlci5jb21wbGV0ZSgpO1xyXG4gICAgICAgICAgICAgICAgfSxcclxuICAgICAgICAgICAgICAgIGVycm9yOiAoZXJyb3IpID0+IHtcclxuICAgICAgICAgICAgICAgICAgaWYgKGVycm9yLnN0YXR1cyA9PSA0MDQpIHtcclxuICAgICAgICAgICAgICAgICAgICAvLyBJbnRlcnByZXQgbm90IGFzIGFuIGVycm9yLCB0aGUgZmlsZSBpc3Qgbm90IHJlY29yZGVkIHlldFxyXG4gICAgICAgICAgICAgICAgICAgIG9ic2VydmVyLm5leHQobnVsbCk7XHJcbiAgICAgICAgICAgICAgICAgICAgb2JzZXJ2ZXIuY29tcGxldGUoKVxyXG4gICAgICAgICAgICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgICAgIC8vIGFsbCBvdGhlciBzdGF0ZXMgYXJlIGVycm9yc1xyXG4gICAgICAgICAgICAgICAgICAgIG9ic2VydmVyLmVycm9yKGVycm9yKTtcclxuICAgICAgICAgICAgICAgICAgICBvYnNlcnZlci5jb21wbGV0ZSgpO1xyXG4gICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgKTtcclxuICAgICAgICB9IGVsc2Uge1xyXG5cclxuICAgICAgICAgIGxldCByZkF1ZGlvT2JzID0gdGhpcy5mZXRjaEF1ZGlvZmlsZShyZWNvcmRpbmdGaWxlSWQpO1xyXG4gICAgICAgICAgcmZBdWRpb09icy5zdWJzY3JpYmUoXHJcbiAgICAgICAgICAgICAge25leHQ6cmVzcCA9PlxyXG4gICAgICAgICAge1xyXG4gICAgICAgICAgICAvLyBEbyBub3QgdXNlIFByb21pc2UgdmVyc2lvbiwgd2hpY2ggZG9lcyBub3Qgd29yayB3aXRoIFNhZmFyaSAxM1xyXG4gICAgICAgICAgICBpZiAocmVzcC5ib2R5KSB7XHJcbiAgICAgICAgICAgICAgQXVkaW9Db250ZXh0UHJvdmlkZXIuZGVjb2RlQXVkaW9EYXRhKHJlc3AuYm9keSkudGhlbiggYWIgPT4ge1xyXG4gICAgICAgICAgICAgICAgaWYgKHJmKSB7XHJcbiAgICAgICAgICAgICAgICAgIGxldCBhcyA9IG5ldyBBdWRpb0J1ZmZlclNvdXJjZShhYik7XHJcbiAgICAgICAgICAgICAgICAgIGxldCBhZGggPSBuZXcgQXVkaW9EYXRhSG9sZGVyKGFzKTtcclxuICAgICAgICAgICAgICAgICAgUmVjb3JkaW5nRmlsZVV0aWxzLnNldEF1ZGlvRGF0YShyZiwgYWRoKTtcclxuICAgICAgICAgICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgICAgICAgIG9ic2VydmVyLmVycm9yKCdSZWNvcmRpbmcgZmlsZSBvYmplY3QgbnVsbCcpO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgaWYgKHRoaXMuZGVidWdEZWxheSA+IDApIHtcclxuICAgICAgICAgICAgICAgICAgd2luZG93LnNldFRpbWVvdXQoKCkgPT4ge1xyXG4gICAgICAgICAgICAgICAgICAgIG9ic2VydmVyLm5leHQocmYpO1xyXG4gICAgICAgICAgICAgICAgICAgIG9ic2VydmVyLmNvbXBsZXRlKCk7XHJcbiAgICAgICAgICAgICAgICAgIH0sIHRoaXMuZGVidWdEZWxheSk7XHJcbiAgICAgICAgICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgICBvYnNlcnZlci5uZXh0KHJmKTtcclxuICAgICAgICAgICAgICAgICAgb2JzZXJ2ZXIuY29tcGxldGUoKTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICB9KS5jYXRjaChyZWFzb24gPT4ge29ic2VydmVyLmVycm9yKHJlYXNvbil9KTtcclxuICAgICAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgICBvYnNlcnZlci5lcnJvcignUmVjZWl2ZWQgbm8gYXVkaW8gZGF0YScpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICB9XHJcbiAgICAgICAgLCBlcnJvcjooZXJyb3I6IEh0dHBFcnJvclJlc3BvbnNlKSA9PiB7XHJcbiAgICAgICAgICAgIGlmIChlcnJvci5zdGF0dXMgPT0gNDA0KSB7XHJcbiAgICAgICAgICAgICAgLy8gSW50ZXJwcmV0IG5vdCBhcyBhbiBlcnJvciwgdGhlIGZpbGUgaXN0IG5vdCByZWNvcmRlZCB5ZXRcclxuICAgICAgICAgICAgICBvYnNlcnZlci5uZXh0KG51bGwpO1xyXG4gICAgICAgICAgICAgIG9ic2VydmVyLmNvbXBsZXRlKClcclxuICAgICAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgICAvLyBhbGwgb3RoZXIgc3RhdGVzIGFyZSBlcnJvcnNcclxuICAgICAgICAgICAgICBvYnNlcnZlci5lcnJvcihlcnJvcik7XHJcbiAgICAgICAgICAgICAgb2JzZXJ2ZXIuY29tcGxldGUoKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgfVxyXG4gICAgICAgIH0pO1xyXG4gICAgICAgIH1cclxuICAgICAgfVxyXG4gICAgfSk7XHJcbiAgICB9KTtcclxuXHJcbiAgICByZXR1cm4gd29icztcclxuICB9XHJcblxyXG4gIHNhdmVFZGl0U2VsZWN0aW9uKHJlY29yZGluZ0ZpbGVJZDogc3RyaW5nIHwgbnVtYmVyLGVkaXRTYW1wbGVSYXRlOm51bWJlcnxudWxsLGVkaXRTdGFydEZyYW1lOm51bWJlcnxudWxsLGVkaXRFbmRGcmFtZTpudW1iZXJ8bnVsbCk6IE9ic2VydmFibGU8U3ByUmVjb3JkaW5nRmlsZSB8IG51bGw+IHtcclxuICAgIGxldCByZWNVcmwgPSB0aGlzLmFwaUVuZFBvaW50ICsgUmVjb3JkaW5nRmlsZVNlcnZpY2UuUkVDT0ZJTEVfQVBJX0NUWCArICcvJyArIHJlY29yZGluZ0ZpbGVJZDtcclxuICAgIGlmICh0aGlzLmNvbmZpZyAmJiB0aGlzLmNvbmZpZy5hcGlUeXBlID09PSBBcGlUeXBlLkZJTEVTKSB7XHJcbiAgICAgIC8vIGZvciBkZXZlbG9wbWVudCBhbmQgZGVtb1xyXG4gICAgICAvLyBhcHBlbmQgVVVJRCB0byBtYWtlIHJlcXVlc3QgVVJMIHVuaXF1ZSB0byBhdm9pZCBsb2NhbGhvc3Qgc2VydmVyIGNhY2hpbmdcclxuICAgICAgcmVjVXJsID0gcmVjVXJsICsgJy5qc29uP3JlcXVlc3RVVUlEPScrVVVJRC5nZW5lcmF0ZSgpO1xyXG4gICAgfVxyXG4gICAgLy9jb25zb2xlLmxvZyhcIlBhdGggcmVxdWVzdCBVUkw6IFwiK3JlY1VybClcclxuICAgIHJldHVybiB0aGlzLmh0dHAucGF0Y2g8U3ByUmVjb3JkaW5nRmlsZT4ocmVjVXJsLHtlZGl0U2FtcGxlUmF0ZTplZGl0U2FtcGxlUmF0ZSxlZGl0U3RhcnRGcmFtZTplZGl0U3RhcnRGcmFtZSxlZGl0RW5kRnJhbWU6ZWRpdEVuZEZyYW1lfSx7IHdpdGhDcmVkZW50aWFsczogdGhpcy53aXRoQ3JlZGVudGlhbHMgfSk7XHJcbiAgfVxyXG5cclxufVxyXG5cclxuXHJcbiJdfQ==
@@ -1,2 +1,2 @@
1
- export {};
1
+ export {};
2
2
  //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2Vzc2lvbi5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uLy4uL3Byb2plY3RzL3NwZWVjaHJlY29yZGVybmcvc3JjL2xpYi9zcGVlY2hyZWNvcmRlci9zZXNzaW9uL3Nlc3Npb24udHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IiIsInNvdXJjZXNDb250ZW50IjpbIlxyXG5leHBvcnQgdHlwZSBTdGF0dXM9IFwiQ1JFQVRFRFwiIHwgXCJMT0FERURcIiB8IFwiU1RBUlRFRF9UUkFJTklOR1wiIHwgXCJTVEFSVEVEXCIgfCBcIkNPTVBMRVRFRFwiO1xyXG5cclxuZXhwb3J0IHR5cGUgVHlwZT0gJ05PUk0nIHwgJ1RFU1QnIHwgJ1RFU1RfREVGX0EnIHwgJ1NJTlVTX1RFU1QnO1xyXG5cclxuZXhwb3J0IGludGVyZmFjZSBTZXNzaW9ue1xyXG5cclxuICBzZXNzaW9uSWQ6IHN0cmluZyB8IG51bWJlcixcclxuICBzdGF0dXM6IFN0YXR1cyxcclxuICBzZWFsZWQ/OmJvb2xlYW4sXHJcbiAgdHlwZTogVHlwZSxcclxuICBsb2FkZWREYXRlPzpEYXRlLFxyXG4gIHN0YXJ0ZWRUcmFpbmluZ0RhdGU/OkRhdGUsXHJcbiAgc3RhcnRlZERhdGU/OkRhdGUsXHJcbiAgY29tcGxldGVkRGF0ZT86RGF0ZSxcclxuICByZXN0YXJ0ZWREYXRlPzpEYXRlLFxyXG4gIHByb2plY3Q6IHN0cmluZyxcclxuICBzY3JpcHQ6IHN0cmluZyB8IG51bWJlclxyXG5cclxufVxyXG4iXX0=
@@ -0,0 +1,69 @@
1
+ import { Inject, Injectable } from '@angular/core';
2
+ import { ApiType, SPEECHRECORDER_CONFIG } from "../../spr.config";
3
+ import { UUID } from "../../utils/utils";
4
+ import { Observable } from "rxjs";
5
+ import { ProjectService } from "../project/project.service";
6
+ import * as i0 from "@angular/core";
7
+ import * as i1 from "@angular/common/http";
8
+ import * as i2 from "../../spr.config";
9
+ export class SessionService {
10
+ get uploadCount() {
11
+ return this._uploadCount;
12
+ }
13
+ static { this.SESSION_API_CTX = 'session'; }
14
+ constructor(http, config) {
15
+ this.http = http;
16
+ this.config = config;
17
+ this.apiEndPoint = '';
18
+ this.withCredentials = false;
19
+ this._uploadCount = 0;
20
+ if (config && config.apiEndPoint) {
21
+ this.apiEndPoint = config.apiEndPoint;
22
+ }
23
+ if (this.apiEndPoint !== '') {
24
+ this.apiEndPoint = this.apiEndPoint + '/';
25
+ }
26
+ if (config != null && config.withCredentials != null) {
27
+ this.withCredentials = config.withCredentials;
28
+ }
29
+ this.sessionsUrl = this.apiEndPoint + SessionService.SESSION_API_CTX;
30
+ }
31
+ sessionObserver(id) {
32
+ let sessUrl = this.sessionsUrl + '/' + id;
33
+ if (this.config && this.config.apiType === ApiType.FILES) {
34
+ // for development and demo
35
+ // append UUID to make request URL unique to avoid localhost server caching
36
+ sessUrl = sessUrl + '.json?requestUUID=' + UUID.generate();
37
+ }
38
+ return this.http.get(sessUrl, { withCredentials: this.withCredentials });
39
+ }
40
+ patchSessionObserver(session, body) {
41
+ let sesssUrl = this.apiEndPoint + ProjectService.PROJECT_API_CTX + '/' + session.project + '/' + SessionService.SESSION_API_CTX + '/' + session.sessionId;
42
+ let wrapObs = new Observable(subscriber => {
43
+ this._uploadCount++;
44
+ let obs = this.http.patch(sesssUrl, body, { withCredentials: this.withCredentials });
45
+ obs.subscribe({
46
+ next: (value) => {
47
+ subscriber.next(value);
48
+ },
49
+ error: error => {
50
+ this._uploadCount--;
51
+ subscriber.error(error);
52
+ }, complete: () => {
53
+ this._uploadCount--;
54
+ subscriber.complete();
55
+ }
56
+ });
57
+ });
58
+ return wrapObs;
59
+ }
60
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.0.6", ngImport: i0, type: SessionService, deps: [{ token: i1.HttpClient }, { token: SPEECHRECORDER_CONFIG }], target: i0.ɵɵFactoryTarget.Injectable }); }
61
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "17.0.6", ngImport: i0, type: SessionService }); }
62
+ }
63
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.0.6", ngImport: i0, type: SessionService, decorators: [{
64
+ type: Injectable
65
+ }], ctorParameters: () => [{ type: i1.HttpClient }, { type: i2.SpeechRecorderConfig, decorators: [{
66
+ type: Inject,
67
+ args: [SPEECHRECORDER_CONFIG]
68
+ }] }] });
69
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2Vzc2lvbi5zZXJ2aWNlLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vLi4vcHJvamVjdHMvc3BlZWNocmVjb3JkZXJuZy9zcmMvbGliL3NwZWVjaHJlY29yZGVyL3Nlc3Npb24vc2Vzc2lvbi5zZXJ2aWNlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBQyxNQUFNLEVBQUUsVUFBVSxFQUFDLE1BQU0sZUFBZSxDQUFDO0FBRWpELE9BQU8sRUFBQyxPQUFPLEVBQUUscUJBQXFCLEVBQXVCLE1BQU0sa0JBQWtCLENBQUM7QUFFdEYsT0FBTyxFQUFDLElBQUksRUFBQyxNQUFNLG1CQUFtQixDQUFDO0FBQ3ZDLE9BQU8sRUFBQyxVQUFVLEVBQUMsTUFBTSxNQUFNLENBQUM7QUFDaEMsT0FBTyxFQUFDLGNBQWMsRUFBQyxNQUFNLDRCQUE0QixDQUFDOzs7O0FBSzFELE1BQU0sT0FBTyxjQUFjO0lBQ3pCLElBQUksV0FBVztRQUNiLE9BQU8sSUFBSSxDQUFDLFlBQVksQ0FBQztJQUMzQixDQUFDO2FBQ3NCLG9CQUFlLEdBQUMsU0FBUyxBQUFWLENBQVc7SUFNakQsWUFBb0IsSUFBZSxFQUF3QyxNQUE0QjtRQUFuRixTQUFJLEdBQUosSUFBSSxDQUFXO1FBQXdDLFdBQU0sR0FBTixNQUFNLENBQXNCO1FBTC9GLGdCQUFXLEdBQUMsRUFBRSxDQUFDO1FBRU4sb0JBQWUsR0FBUyxLQUFLLENBQUM7UUFDdkMsaUJBQVksR0FBQyxDQUFDLENBQUM7UUFJckIsSUFBRyxNQUFNLElBQUksTUFBTSxDQUFDLFdBQVcsRUFBRTtZQUMvQixJQUFJLENBQUMsV0FBVyxHQUFDLE1BQU0sQ0FBQyxXQUFXLENBQUM7U0FDckM7UUFDRCxJQUFHLElBQUksQ0FBQyxXQUFXLEtBQUssRUFBRSxFQUFDO1lBQ3pCLElBQUksQ0FBQyxXQUFXLEdBQUMsSUFBSSxDQUFDLFdBQVcsR0FBQyxHQUFHLENBQUE7U0FDdEM7UUFDRCxJQUFHLE1BQU0sSUFBRSxJQUFJLElBQUksTUFBTSxDQUFDLGVBQWUsSUFBRSxJQUFJLEVBQUM7WUFDOUMsSUFBSSxDQUFDLGVBQWUsR0FBQyxNQUFNLENBQUMsZUFBZSxDQUFDO1NBQzdDO1FBQ0QsSUFBSSxDQUFDLFdBQVcsR0FBRyxJQUFJLENBQUMsV0FBVyxHQUFHLGNBQWMsQ0FBQyxlQUFlLENBQUM7SUFDdkUsQ0FBQztJQUVELGVBQWUsQ0FBQyxFQUFVO1FBRXhCLElBQUksT0FBTyxHQUFHLElBQUksQ0FBQyxXQUFXLEdBQUcsR0FBRyxHQUFHLEVBQUUsQ0FBQztRQUMxQyxJQUFJLElBQUksQ0FBQyxNQUFNLElBQUksSUFBSSxDQUFDLE1BQU0sQ0FBQyxPQUFPLEtBQUssT0FBTyxDQUFDLEtBQUssRUFBRTtZQUN4RCwyQkFBMkI7WUFDM0IsMkVBQTJFO1lBQzNFLE9BQU8sR0FBRyxPQUFPLEdBQUcsb0JBQW9CLEdBQUMsSUFBSSxDQUFDLFFBQVEsRUFBRSxDQUFDO1NBQzFEO1FBQ0QsT0FBTyxJQUFJLENBQUMsSUFBSSxDQUFDLEdBQUcsQ0FBVSxPQUFPLEVBQUMsRUFBRSxlQUFlLEVBQUUsSUFBSSxDQUFDLGVBQWUsRUFBRSxDQUFDLENBQUM7SUFFbkYsQ0FBQztJQUVELG9CQUFvQixDQUFDLE9BQWUsRUFBQyxJQUFRO1FBRTNDLElBQUksUUFBUSxHQUFHLElBQUksQ0FBQyxXQUFXLEdBQUcsY0FBYyxDQUFDLGVBQWUsR0FBRyxHQUFHLEdBQUcsT0FBTyxDQUFDLE9BQU8sR0FBRyxHQUFHLEdBQUcsY0FBYyxDQUFDLGVBQWUsR0FBRyxHQUFHLEdBQUcsT0FBTyxDQUFDLFNBQVMsQ0FBQTtRQUV6SixJQUFJLE9BQU8sR0FBRyxJQUFJLFVBQVUsQ0FBVSxVQUFVLENBQUMsRUFBRTtZQUNqRCxJQUFJLENBQUMsWUFBWSxFQUFFLENBQUM7WUFDcEIsSUFBSSxHQUFHLEdBQUcsSUFBSSxDQUFDLElBQUksQ0FBQyxLQUFLLENBQVUsUUFBUSxFQUFFLElBQUksRUFBRSxFQUFDLGVBQWUsRUFBRSxJQUFJLENBQUMsZUFBZSxFQUFDLENBQUMsQ0FBQztZQUM1RixHQUFHLENBQUMsU0FBUyxDQUFDO2dCQUNkLElBQUksRUFBQyxDQUFDLEtBQUssRUFBRSxFQUFFO29CQUViLFVBQVUsQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLENBQUM7Z0JBQ3pCLENBQUM7Z0JBQ0EsS0FBSyxFQUFFLEtBQUssQ0FBQyxFQUFFO29CQUNkLElBQUksQ0FBQyxZQUFZLEVBQUUsQ0FBQztvQkFDcEIsVUFBVSxDQUFDLEtBQUssQ0FBQyxLQUFLLENBQUMsQ0FBQztnQkFDMUIsQ0FBQyxFQUFFLFFBQVEsRUFBQyxHQUFHLEVBQUU7b0JBQ2YsSUFBSSxDQUFDLFlBQVksRUFBRSxDQUFDO29CQUNwQixVQUFVLENBQUMsUUFBUSxFQUFFLENBQUM7Z0JBQ3hCLENBQUM7YUFDRixDQUFDLENBQUM7UUFDSCxDQUFDLENBQUMsQ0FBQztRQUNILE9BQU8sT0FBTyxDQUFDO0lBQ2pCLENBQUM7OEdBMURVLGNBQWMsNENBVW1CLHFCQUFxQjtrSEFWdEQsY0FBYzs7MkZBQWQsY0FBYztrQkFEMUIsVUFBVTs7MEJBVzRCLE1BQU07MkJBQUMscUJBQXFCIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHtJbmplY3QsIEluamVjdGFibGV9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xyXG5pbXBvcnQge0h0dHBDbGllbnR9IGZyb20gXCJAYW5ndWxhci9jb21tb24vaHR0cFwiO1xyXG5pbXBvcnQge0FwaVR5cGUsIFNQRUVDSFJFQ09SREVSX0NPTkZJRywgU3BlZWNoUmVjb3JkZXJDb25maWd9IGZyb20gXCIuLi8uLi9zcHIuY29uZmlnXCI7XHJcbmltcG9ydCB7U2Vzc2lvbn0gZnJvbSBcIi4vc2Vzc2lvblwiO1xyXG5pbXBvcnQge1VVSUR9IGZyb20gXCIuLi8uLi91dGlscy91dGlsc1wiO1xyXG5pbXBvcnQge09ic2VydmFibGV9IGZyb20gXCJyeGpzXCI7XHJcbmltcG9ydCB7UHJvamVjdFNlcnZpY2V9IGZyb20gXCIuLi9wcm9qZWN0L3Byb2plY3Quc2VydmljZVwiO1xyXG5cclxuXHJcblxyXG5ASW5qZWN0YWJsZSgpXHJcbmV4cG9ydCBjbGFzcyBTZXNzaW9uU2VydmljZSB7XHJcbiAgZ2V0IHVwbG9hZENvdW50KCk6IG51bWJlciB7XHJcbiAgICByZXR1cm4gdGhpcy5fdXBsb2FkQ291bnQ7XHJcbiAgfVxyXG4gIHB1YmxpYyBzdGF0aWMgcmVhZG9ubHkgU0VTU0lPTl9BUElfQ1RYPSdzZXNzaW9uJztcclxuICBwcml2YXRlIGFwaUVuZFBvaW50PScnO1xyXG4gIHByaXZhdGUgcmVhZG9ubHkgc2Vzc2lvbnNVcmw6c3RyaW5nO1xyXG4gIHByaXZhdGUgcmVhZG9ubHkgd2l0aENyZWRlbnRpYWxzOmJvb2xlYW49ZmFsc2U7XHJcbiAgcHJpdmF0ZSBfdXBsb2FkQ291bnQ9MDtcclxuXHJcbiAgY29uc3RydWN0b3IocHJpdmF0ZSBodHRwOkh0dHBDbGllbnQsQEluamVjdChTUEVFQ0hSRUNPUkRFUl9DT05GSUcpIHByaXZhdGUgY29uZmlnPzpTcGVlY2hSZWNvcmRlckNvbmZpZykge1xyXG5cclxuICAgIGlmKGNvbmZpZyAmJiBjb25maWcuYXBpRW5kUG9pbnQpIHtcclxuICAgICAgdGhpcy5hcGlFbmRQb2ludD1jb25maWcuYXBpRW5kUG9pbnQ7XHJcbiAgICB9XHJcbiAgICBpZih0aGlzLmFwaUVuZFBvaW50ICE9PSAnJyl7XHJcbiAgICAgIHRoaXMuYXBpRW5kUG9pbnQ9dGhpcy5hcGlFbmRQb2ludCsnLydcclxuICAgIH1cclxuICAgIGlmKGNvbmZpZyE9bnVsbCAmJiBjb25maWcud2l0aENyZWRlbnRpYWxzIT1udWxsKXtcclxuICAgICAgdGhpcy53aXRoQ3JlZGVudGlhbHM9Y29uZmlnLndpdGhDcmVkZW50aWFscztcclxuICAgIH1cclxuICAgIHRoaXMuc2Vzc2lvbnNVcmwgPSB0aGlzLmFwaUVuZFBvaW50ICsgU2Vzc2lvblNlcnZpY2UuU0VTU0lPTl9BUElfQ1RYO1xyXG4gIH1cclxuXHJcbiAgc2Vzc2lvbk9ic2VydmVyKGlkOiBzdHJpbmcpOiBPYnNlcnZhYmxlPFNlc3Npb24+IHtcclxuXHJcbiAgICBsZXQgc2Vzc1VybCA9IHRoaXMuc2Vzc2lvbnNVcmwgKyAnLycgKyBpZDtcclxuICAgIGlmICh0aGlzLmNvbmZpZyAmJiB0aGlzLmNvbmZpZy5hcGlUeXBlID09PSBBcGlUeXBlLkZJTEVTKSB7XHJcbiAgICAgIC8vIGZvciBkZXZlbG9wbWVudCBhbmQgZGVtb1xyXG4gICAgICAvLyBhcHBlbmQgVVVJRCB0byBtYWtlIHJlcXVlc3QgVVJMIHVuaXF1ZSB0byBhdm9pZCBsb2NhbGhvc3Qgc2VydmVyIGNhY2hpbmdcclxuICAgICAgc2Vzc1VybCA9IHNlc3NVcmwgKyAnLmpzb24/cmVxdWVzdFVVSUQ9JytVVUlELmdlbmVyYXRlKCk7XHJcbiAgICB9XHJcbiAgICByZXR1cm4gdGhpcy5odHRwLmdldDxTZXNzaW9uPihzZXNzVXJsLHsgd2l0aENyZWRlbnRpYWxzOiB0aGlzLndpdGhDcmVkZW50aWFscyB9KTtcclxuXHJcbiAgfVxyXG5cclxuICBwYXRjaFNlc3Npb25PYnNlcnZlcihzZXNzaW9uOlNlc3Npb24sYm9keTphbnkpOiBPYnNlcnZhYmxlPFNlc3Npb24+IHtcclxuXHJcbiAgICBsZXQgc2Vzc3NVcmwgPSB0aGlzLmFwaUVuZFBvaW50ICsgUHJvamVjdFNlcnZpY2UuUFJPSkVDVF9BUElfQ1RYICsgJy8nICsgc2Vzc2lvbi5wcm9qZWN0ICsgJy8nICsgU2Vzc2lvblNlcnZpY2UuU0VTU0lPTl9BUElfQ1RYICsgJy8nICsgc2Vzc2lvbi5zZXNzaW9uSWRcclxuXHJcbiAgICBsZXQgd3JhcE9icyA9IG5ldyBPYnNlcnZhYmxlPFNlc3Npb24+KHN1YnNjcmliZXIgPT4ge1xyXG4gICAgICB0aGlzLl91cGxvYWRDb3VudCsrO1xyXG4gICAgICBsZXQgb2JzID0gdGhpcy5odHRwLnBhdGNoPFNlc3Npb24+KHNlc3NzVXJsLCBib2R5LCB7d2l0aENyZWRlbnRpYWxzOiB0aGlzLndpdGhDcmVkZW50aWFsc30pO1xyXG4gICAgICBvYnMuc3Vic2NyaWJlKHtcclxuICAgICAgbmV4dDoodmFsdWUpID0+XHJcbiAgICAgIHtcclxuICAgICAgICBzdWJzY3JpYmVyLm5leHQodmFsdWUpO1xyXG4gICAgICB9XHJcbiAgICAgICxlcnJvcjogZXJyb3IgPT4ge1xyXG4gICAgICAgIHRoaXMuX3VwbG9hZENvdW50LS07XHJcbiAgICAgICAgc3Vic2NyaWJlci5lcnJvcihlcnJvcik7XHJcbiAgICAgIH0sIGNvbXBsZXRlOigpID0+IHtcclxuICAgICAgICB0aGlzLl91cGxvYWRDb3VudC0tO1xyXG4gICAgICAgIHN1YnNjcmliZXIuY29tcGxldGUoKTtcclxuICAgICAgfVxyXG4gICAgfSk7XHJcbiAgICB9KTtcclxuICAgIHJldHVybiB3cmFwT2JzO1xyXG4gIH1cclxuXHJcbiAgLy8gcHV0U2Vzc2lvbk9ic2VydmVyKHNlc3Npb246IFNlc3Npb24pOiBPYnNlcnZhYmxlPFNlc3Npb24+IHtcclxuICAvL1xyXG4gIC8vICAgbGV0IHNlc3NzVXJsID0gdGhpcy5hcGlFbmRQb2ludCArIFByb2plY3RTZXJ2aWNlLlBST0pFQ1RfQVBJX0NUWCArICcvJyArIHNlc3Npb24ucHJvamVjdCArICcvJyArIFNlc3Npb25TZXJ2aWNlLlNFU1NJT05fQVBJX0NUWCArICcvJyArIHNlc3Npb24uc2Vzc2lvblxyXG4gIC8vXHJcbiAgLy8gICBsZXQgd3JhcE9icyA9IG5ldyBPYnNlcnZhYmxlPFNlc3Npb24+KHN1YnNjcmliZXIgPT4ge1xyXG4gIC8vICAgICB0aGlzLl91cGxvYWRDb3VudCsrO1xyXG4gIC8vICAgICBsZXQgb2JzID0gdGhpcy5odHRwLnB1dDxTZXNzaW9uPihzZXNzc1VybCwgc2Vzc2lvbiwge3dpdGhDcmVkZW50aWFsczogdGhpcy53aXRoQ3JlZGVudGlhbHN9KTtcclxuICAvLyAgICAgb2JzLnN1YnNjcmliZSgodmFsdWUpID0+IHtcclxuICAvLyAgICAgICBzdWJzY3JpYmVyLm5leHQodmFsdWUpO1xyXG4gIC8vICAgICB9LCBlcnJvciA9PiB7XHJcbiAgLy8gICAgICAgdGhpcy5fdXBsb2FkQ291bnQtLTtcclxuICAvLyAgICAgICBzdWJzY3JpYmVyLmVycm9yKGVycm9yKTtcclxuICAvLyAgICAgfSwgKCkgPT4ge1xyXG4gIC8vICAgICAgIHRoaXMuX3VwbG9hZENvdW50LS07XHJcbiAgLy8gICAgICAgc3Vic2NyaWJlci5jb21wbGV0ZSgpO1xyXG4gIC8vICAgICB9KTtcclxuICAvLyAgIH0pO1xyXG4gIC8vICAgcmV0dXJuIHdyYXBPYnM7XHJcbiAgLy8gfVxyXG4gIC8vXHJcblxyXG5cclxufVxyXG5cclxuXHJcblxyXG4iXX0=